Copyright (c) 2003 by Valery Sklyarov and Iouliia Skliarova: DETUA, IEETA, Aveiro University, Portugal.

Slides:



Advertisements
Similar presentations
1/1/ / faculty of Electrical Engineering eindhoven university of technology Introduction Part 2: Data types and addressing modes dr.ir. A.C. Verschueren.
Advertisements

History TTL-logic PAL (Programmable Array Logic)
Integer Square Root.
TK 2633 Microprocessor & Interfacing Lecture 3: Introduction to 8085 Assembly Language Programming (2) 1 Prepared By: Associate Prof. Dr Masri Ayob.
Counters Discussion D5.3 Example 33. Counters 3-Bit, Divide-by-8 Counter 3-Bit Behavioral Counter in Verilog Modulo-5 Counter An N-Bit Counter.
Dr. Turki F. Al-Somani VHDL synthesis and simulation – Part 3 Microcomputer Systems Design (Embedded Systems)
Copyright © 2008 Pearson Addison-Wesley. All rights reserved. Chapter 13 Pointers and Linked Lists.
George Mason University ECE 448 – FPGA and ASIC Design with VHDL Finite State Machines State Diagrams, State Tables, Algorithmic State Machine (ASM) Charts,
Lecture #5 In this lecture we will introduce the sequential circuits.
LAB 9 Finite State Machine (FSM) Ui Luu Glendale Community College Bassam Matar Chandler-Gilbert Community College.
1 Part V: VHDL CODING. 2 Design StructureData TypesOperators and AttributesConcurrent DesignSequential DesignSignals and VariablesState Machines A VHDL.
Copyright © 2008 Pearson Addison-Wesley. All rights reserved. Chapter 13 Pointers and Linked Lists.
Copyright (c) 2003 by Valery Sklyarov and Iouliia Skliarova: DETUA, IEETA, Aveiro University, Portugal.
Copyright (c) 2003 by Valery Sklyarov and Iouliia Skliarova: DETUA, IEETA, Aveiro University, Portugal.
1 Copyright (c) 2003 by Valery Sklyarov and Iouliia Skliarova: DETUA, IEETA, Aveiro University, Portugal.
CprE / ComS 583 Reconfigurable Computing
VHDL in 1h Martin Schöberl. AK: JVMHWVHDL2 VHDL /= C, Java,… Think in hardware All constructs run concurrent Different from software programming Forget.
Language Concepts Ver 1.1, Copyright 1997 TS, Inc. VHDL L a n g u a g e C o n c e p t s Page 1.
ENG241 Digital Design Week #8 Registers and Counters.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved Stacks.
Lists Chapter 8. 2 Linked Lists As an ADT, a list is –finite sequence (possibly empty) of elements Operations commonly include: ConstructionAllocate &
1 RAM. 2 PS2_Keyboard: entity work.Keyboard generic map (AddressBits => ADDRESSLENGTH) port map (Reset => Reset, Clock => ClockVGA, PS2Clock => PS2Clock,
VHDL Discussion Finite State Machines IAY 0600 Digital Systems Design Alexander Sudnitson Tallinn University of Technology 1.
Copyright (c) 2003 by Valery Sklyarov and Iouliia Skliarova: DETUA, IEETA, Aveiro University, Portugal.
VHDL Discussion Sequential Sytems. Memory Elements. Registers. Counters IAY 0600 Digital Systems Design Alexander Sudnitson Tallinn University of Technology.
 Seattle Pacific University EE Logic System DesignCounters-1 Shift Registers DQ clk DQ DQ ShiftIn Q3Q3 Q2Q2 DQ Q1Q1 Q0Q0 A shift register shifts.
1 Part III: VHDL CODING. 2 Design StructureData TypesOperators and AttributesConcurrent DesignSequential DesignSignals and VariablesState Machines A VHDL.
Copyright (c) 2003 by Valery Sklyarov and Iouliia Skliarova: DETUA, IEETA, Aveiro University, Portugal.
Data Storage VHDL ET062G & ET063G Lecture 4 Najeem Lawal 2012.
Controllers ENGIN 341 – Advanced Digital Design University of Massachusetts Boston Department of Engineering Dr. Filip Cuckov.
Digital System Design using VHDL
Algorithmic State Machines Sorting Signed & Unsigned Data Types
Copyright (c) 2003 by Valery Sklyarov and Iouliia Skliarova: DETUA, IEETA, Aveiro University, Portugal.
ENG241 Digital Design Week #7 Sequential Circuits (Part B)
55:032 - Intro. to Digital DesignPage 1 VHDL and Processes Defining Sequential Circuit Behavior.
ECE DIGITAL LOGIC LECTURE 21: FINITE STATE MACHINE Assistant Prof. Fareena Saqib Florida Institute of Technology Fall 2015, 11/24/2015.
Computer Science Department Data Structure and Algorithms Lecture 3 Stacks.
8085 INTERNAL ARCHITECTURE.  Upon completing this topic, you should be able to: State all the register available in the 8085 microprocessor and explain.
Digital Design with SM Charts
Algorithmic State Machine (ASM) Charts: VHDL Code & Timing Diagrams
1 Introduction to Engineering Spring 2007 Lecture 19: Digital Tools 3.
1 AL and CA Lecture 13: System Design 1 2 Outline System Level Design Control Signals Controller Design.
1 Computer Architecture & Assembly Language Spring 2009 Dr. Richard Spillman Lecture 11 – ALU Design.
Sequential statements (1) process
Registers and Counters
ECE 448 Lecture 6 Finite State Machines State Diagrams, State Tables, Algorithmic State Machine (ASM) Charts, and VHDL Code.
Introduction Introduction to VHDL Entities Signals Data & Scalar Types
CHAPTER 17 VHDL FOR SEQUENTIAL LOGIC
Chap 7. Register Transfers and Datapaths
Hao Zheng Comp Sci & Eng USF
Stack Lesson xx   This module shows you the basic elements of a type of linked list called a stack.
CPE 528: Session #7 Department of Electrical and Computer Engineering University of Alabama in Huntsville.
Algorithmic State Machine (ASM) Charts: VHDL Code & Timing Diagrams
VHDL VHSIC Hardware Description Language VHSIC
Popping Items Off a Stack Lesson xx
ECE-C 302 Lecture 15 Prawat Nagvajara
Software Environment ISE 5.x Interaction with simple LCDs
VHDL (VHSIC Hardware Description Language)
ECE 448 Lecture 13 Multipliers Timing Parameters
ECE 545 Lecture 11 Design of Controllers Finite State Machines and Algorithmic State Machine (ASM) Charts.
Lecture #5 In this lecture we will introduce the sequential circuits.
Founded in Silicon Valley in 1984
Figure 8.1. The general form of a sequential circuit.
RTL Design Methodology Transition from Pseudocode & Interface
ECE 448 Lecture 6 Finite State Machines State Diagrams, State Tables, Algorithmic State Machine (ASM) Charts, and VHDL Code.
ECE 448 Lecture 6 Finite State Machines State Diagrams, State Tables, Algorithmic State Machine (ASM) Charts, and VHDL code ECE 448 – FPGA and ASIC Design.
ECE 448 Lecture 6 Finite State Machines State Diagrams vs. Algorithmic State Machine (ASM) Charts.
ECE 352 Digital System Fundamentals
Sequntial-Circuit Building Blocks
Computer Operation 6/22/2019.
Presentation transcript:

Copyright (c) 2003 by Valery Sklyarov and Iouliia Skliarova: DETUA, IEETA, Aveiro University, Portugal

1.Presenting basic ideas of recursive algorithms and hierarchical finite state machines (HFSM), which enable us to implement these algorithms 2. ISE 5.2 projects that demonstrate implementations in FPGA all individual components and entire circuits that carry out recursive constructing of a binary tree, which describes a structure of data and recursive sorting of data taking from the binary tree. 3. Projects for ISE 5.2 that might be downloaded and tested Three following things will be considered: 1.1. Description of the considered algorithms with examples 1.2. C++ program that implements a recursive sorting algorithm. The program can be run and tested 1.3. Presenting the considered algorithms in form of hierarchical graph schemes Two following things will be considered: 2.1. VHDL code for individual components, such as stack memory, a number of HFSM, a number of execution units that permit to understand the entire quite complicated example step by step, etc VHDL code for complete ISE 5.2 project, which takes (undefined number of data) constructs and extends a binary tree that keeps these data, carries out a sorting procedure on the binary tree.

C- program of the recursive sorting algorithm can be found in: 1. B.W.Kernighan and D.M.Ritchie, The C Programming Language. Englewood Cliffs, NJ: Prentice-Hall, Definition of a HFSM, hierarchical graph-schemes and their use on examples of very simple recursive sorting algorithms can be found in: 2. V. Sklyarov, Hierarchical Finite State Machines and Their Use for Digital Control, IEEE Transactions on VLSI, Vol. 7, No 2, June, 1999, pp This tutorial includes more complicated examples, more detailed description and a model of HFSM that is different from [2]

Let us assume that we are receiving integers (unsigned) from a channel (example from [2]) 1)17 2)6 3)18 4)9 5)5 6)21 7)… 17 root of a binary tree 6 left node because 6 < 17 right node because 18 > right node of the node 6, because left node of the node 6, because 5 < 17 and 5 < 6 21 right node of the node 18, because 21 > 17 and 21 > 18

#include // C++ program, which: #include // - constructs a binary tree, using recursive function der *dr(der *kr,char *word) #include // - traverses binary tree, using recursive function struct der // template void drpr(der *kr, STACK &my_stack) char *w; int c; struct der *l; struct der *r;}; template class STACK{ T *top,*sp; int size; public: STACK(int n){ top = sp = new T[size=n]; } ~STACK(){ delete[] top; } void operator+=(T v) { if (size>sp-top) *sp++ = v; else cerr << "ERROR\n";} T operator--() { if (sp==top) { cerr << "error:\t"; return *sp; } return *--sp;} int operator~() const { cout << "size = " << (sp-top) << endl; return (int)(sp-top); } }; template void drpr(der *kr, STACK &my_stack) {if(kr!=NULL){ drpr(kr->l,my_stack); cout w c << endl; my_stack+=kr->w; drpr(kr->r,my_stack);}} template for a class STACK // STACK class constructor // STACK class destructor // += - push the value of v onto STACK // -- - carry out pop operation // ~ - return the size of the used STACK // top – pointer to the top; sp – stack pointer // size – the size of the stack size top sp increment (push) sp decrement (pop)

#include // C++ program, which: #include // - constructs a binary tree, using recursive function der *dr(der *kr,char *word) #include // - traverses binary tree, using recursive function struct der // template void drpr(der *kr, STACK &my_stack) char *w; int c; struct der *l; struct der *r;}; template class STACK{ T *top,*sp; int size; public: STACK(int n){ top = sp = new T[size=n]; } ~STACK(){ delete[] top; } void operator+=(T v) { if (size>sp-top) *sp++ = v; else cerr << "ERROR\n";} T operator--() { if (sp==top) { cerr << "error:\t"; return *sp; } return *--sp;} int operator~() const { cout << "size = " << (sp-top) << endl; return (int)(sp-top); } }; template void drpr(der *kr, STACK &my_stack) {if(kr!=NULL){ drpr(kr->l,my_stack); cout w c << endl; my_stack+=kr->w; drpr(kr->r,my_stack);}} a binary tree node number of incoming data with this value This function will be considered later in details

void main(void) {der *kr, *dr(der*,char*); STACK my_stack=10; int i; char word[40][21]; kr = NULL; i=0; for(;;) {cout << "Enter a word\n"; cin >> (char*)word[i]; if (word[i][0]=='0') break; kr = dr(kr,word[i++]);}; drpr(kr,my_stack); while (~my_stack != 0) cout << --my_stack << endl; } der *dr(der *kr,char *word) {int sr; if(kr==NULL){ kr = new der; kr->w = word; kr->c = 1; kr->r = kr->l = NULL;} else if((sr=strcmp(word,kr->w))==0) kr->c++; else if(sr l = dr(kr->l,word); else kr->r=dr(kr->r,word); return kr;} main function // kr and dr are pointers to binary graph nodes // my_stack is stack of size 10 getting data from a channel (input stream) // the function dr adds value // to the binary tree // the function drpr sorts data // from the binary tree and // displays sorted data

The results of the program input data output results

der *dr(der *kr,char *word) { int sr; if(kr==NULL) { kr = new der; kr->w = word; kr->c = 1; kr->r = kr->l = NULL;} else if((sr=strcmp(word,kr->w))==0) kr->c++; else if(sr l = dr(kr->l,word); else kr->r=dr(kr->r,word); return kr;} Begin X4X4 X2X2 X3X End (y 5 ) 0 1 a0a0 a1a1 a6a6 a2a2 a3a3 a7a7 y8y8 a4a4 a5a5 y 1,y 4,z 1 Z1Z1 y 1,y 2,z 1 y6y6 y7y7 y9y9 leftright

See details in the paper [2] (slide 3) y 1 - push data onto the local stack y 5 - pop data from the local stack y 2 - write an address of the left node y 4 - write an address of the right node y 3 - push data onto the output stack this output signal will be used in the algorithm Z 2 y 6 - copy address for the left node from the local stack to the register y 7 - copy address for the right node from the local stack to the register y 8 – create a new node in the RAM y 9 – prepare the local stack for stack unwiding y6y6 y7y7 The effect of outputs y 8, y 9 will be considered in VHDL code for datapath (see the component data_lcd.vhd) See the details in paper [2] (slide 3)

See details in the paper [2] (slide 3) See the details in paper [2] (slide 3)

template void drpr(der *kr, STACK &my_stack) { if(kr!=NULL){ drpr(kr->l,my_stack); cout w c << endl; my_stack+=kr->w; drpr(kr->r,my_stack);}} Begin x 1 y a 0 a 1 a 2 End, y 5 a 3 a 4 y 1,y 2,z 2 y 1,y 4,z 2 Z2Z2 Microoperations y 1, y 2, y 4 and y 5 perform operations that are hidden in software (C++) and have to be implemented in hardware This output operation is modeled by VHDL code that permits to display sorted (and other necessary) data on LCD This is also a recursive algorithm

See details in the paper [2] (slide 3) See the details in paper [2] (slide 3)

Begin X5X5 End z1z1 z2z2 a0a0 a1a1 a2a2 a3a3 0 1 Z0Z0 // for(;;) { cout << "Enter a word\n"; cin >> (char*)word[i]; if (word[i][0]=='0') break; kr = dr(kr,word[i++]);}; drpr(kr,my_stack); while (~my_stack != 0) cout << --my_stack << endl; // The cycle is modeled with the aid of an input X 5

Hierarchical specifications Recursive specifications

x 2 = 1 when new value is not equal to RAM value written on active address x 3 = 1 when pointer is equal to 11…11, i.e. there is no next node x 4 = 1 when new value less than RAM value written on active address address = address of the left node does not exist address of the right node does not exist there is a node 6 ≠ 17 6 < 17 y 1 - push address onto the local stack y 2 - write an address of the left node 1..1, i.e. there is no node activate the same module

x 2 = 1 when new value is not equal to RAM value written on active address x 3 = 1 when pointer is equal to 11…11, i.e. there is no next node x 4 = 1 when new value less than RAM value written on active address address = , i.e. there is no node recursive call increment write save address onto the local stack return to the node, which follows the previous z 1 call

x 2 = 1 when new value is not equal to RAM value written on active address x 3 = 1 when pointer is equal to 11…11, i.e. there is no next node x 4 = 1 when new value less than RAM value written on active address address = increment Writes the address of the RAM from the top of the local stack. Recursive calls stack unwinding 0..1 This address will be written to the RAM for the left node because the call was done through an exit 1 of the respective rhomboidal node 17 6

x 2 = 1 when new value is not equal to RAM value written on active address x 3 = 1 when pointer is equal to 11…11, i.e. there is no next node x 4 = 1 when new value less than RAM value written on active address this sequence will finally be activated RAM before RAM after

<17 14>6 14>12 14<15 14>13 14

12<17 12> = 12 stack unwinding

x 1 = 0 when there is no pointer to other nodes (i.e. the pointer is equal to 1..1) y 1 – push RAM address onto the local stack y 2 – write an address of the left node z 2 – call itself

x 1 = 0 when there is no pointer to other nodes (i.e. the pointer is equal to 1..1) y 1 – push RAM address onto the local stack y 2 – write an address of the left node z 2 – call itself Local stack address of 17 address of 6

x 1 = 0 when there is no pointer to other nodes (i.e. the pointer is equal to 1..1) Local stack address of 17 address of y 5 – pop data from the local stack to the address register y 3 – record output data

x 1 = 0 when there is no pointer to other nodes (i.e. the pointer is equal to 1..1) Local stack y 1 – push RAM address onto the local stack y 4 – – write an address of the right node z 2 – call itself

x 1 = 0 when there is no pointer to other nodes (i.e. the pointer is equal to 1..1) Local stack y 5 – pop data from the local stack to the address register y 3 – record output data

x 1 = 0 when there is no pointer to other nodes (i.e. the pointer is equal to 1..1) Local stack y 1 – push RAM address onto the local stack y 4 – – write an address of the right node z 2 – call itself

x 1 = 0 when there is no pointer to other nodes (i.e. the pointer is equal to 1..1) y 1 – push RAM address onto the local stack y 2 – write an address of the left node z 2 – call itself Local stack

x 1 = 0 when there is no pointer to other nodes (i.e. the pointer is equal to 1..1) Local stack y 5 – pop data from the local stack to the address register y 3 – record output data

x 1 = 0 when there is no pointer to other nodes (i.e. the pointer is equal to 1..1) Local stack y 1 – push RAM address onto the local stack y 4 – – write an address of the right node z 2 – call itself

x 1 = 0 when there is no pointer to other nodes (i.e. the pointer is equal to 1..1) Local stack y 5 – pop data from the local stack to the address register

Changes that are required in order to change the order: y 1,y 4,z 2 y 1,y 2,z 2 Other examples of modifiability can be found in [2] (slide 3) The algorithm has very compact VHDL description and it is very fast (see the next section)

Adding data to the tree until these data are available Sorting data and recording the sorted data onto the output

if rising_edge(clk) then if push = '1' then Combinational circuit (CC) Stack memory inputs outputs x1x1 xLxL y1y1 yNyN push pop Stack of moduls active module 13 2 set the state a 0 on the top stack_counter <= stack_counter + 1; FSM_stack(stack_counter+1) <= a0; M_stack(stack_counter+1) <= NM; For this example NM = z 1

Combinational circuit (CC) Stack memory inputs outputs x1x1 xLxL y1y1 yNyN push pop Stack of moduls active module Begin X 4 X 2 X End (y 5 ) 0 1 a 0 a 1 a 6 a 2 a 3 a 7 y 8 a 4 a 5 y 1,y 4, z 1 Z 1 y 1 2, z 1 y 7 y 6 y 9 y 1,y 4,z 1 1) y 1 and y 4 are active 2) Starting from the next rising edge of the clock module z 1 will be executed 3) After terminating the module z 1 an output for the next node (i.e. y 6 ) will be active

if rising_edge(clk) then if pop = '1' then Combinational circuit (CC) Stack memory inputs outputs x1x1 xLxL y1y1 yNyN push pop Stack of moduls active module stack_counter <= stack_counter - 1; return_flag <= '1'; Begin X 4 X 2 X End (y 5 ) 0 1 a 0 a 1 a 6 a 2 a 3 a 7 y 8 a 4 a 5 y 1,y 4, z 1 Z 1 y 1 2, z 1 y 7 y 6 y set return flag in order to avoid repeating outputs that appear in nodes that invoke other nodes for example

entity stack is generic ( L : integer := 3; N : integer := 7; depth : integer := 15); port ( clk : in std_logic; rst : in std_logic; push : in std_logic; pop : in std_logic; count : out std_logic_vector(3 downto 0); inputs : in std_logic_vector(L downto 0); outputs : out std_logic_vector(N downto 0)); end stack; architecture Behavioral of stack is type stack_memory is array(0 to depth) of std_logic_vector(L downto 0); signal stack : stack_memory; signal stack_counter : integer range 0 to depth; begin S 5 - on S 4 - on S 3 …S 0 stack counter value on LCD (top middle number) if pop is active (S 4 ) then outputs are shown in top left field of LCD clock from pushbutton 2 reset from reset button

process(clk,rst,push,pop) begin if rst = '1' then stack_counter '0'); elsif rising_edge(clk) then if stack_counter < depth and push = '1' then stack_counter <= stack_counter + 1; stack(stack_counter) <= inputs; elsif stack_counter > 0 and pop = '1' then stack_counter <= stack_counter-1; outputs <= stack(stack_counter-1); end if; count <= conv_std_logic_vector(stack_counter,4); end process;

1 0 S S 7 State count DIC value to push onto the stack (in case of push operation) or value returned from the stack (in case of pop operation) stack counter (stack pointer) value S 0 …S 3 clock from stack counter increment S6S6 stack counter decrement S5S5

Combinational circuit (CC) Stack memory inputs outputs x1x1 xLxL y1y1 yNyN inc dec This stack for simplicity does not check overflow a 2 process(lpb(2),rst,FSM_stack,stack_counter) begin if rst = '1' then outputs '0'); stack_counter <= 0; elsif rising_edge(lpb(2)) then if inc = '1' then stack_counter <= stack_counter + 1; FSM_stack(stack_counter+1) '0'); elsif dec = '1' then stack_counter <= stack_counter - 1; else FSM_stack(stack_counter) <= inputs; end if; outputs <= FSM_stack(stack_counter); end process; a 2 y 3 For exemple: y 1,y 4,z 1 For example: End, y 5 For example:

VHDL code for the FSM stack was inserted into VHDL code for LCD Count stack DICO stack value stack pointer decrement – stack pointer increment – clock – value extracted from the stack Test sequence: I N P U T S O U T P U T S S 0 …S 5 = Press pushbutton S 0 …S 5 = Press pushbutton S 0 …S 5 = Press pushbutton S 0 …S 5 = Press pushbutton S 0 …S 5 = Press pushbutton S 0 …S 5 = Press pushbutton S 0 …S 5 = Press pushbutton S 0 …S 5 = Press pushbutton Press pushbutton Press pushbutton stack counter

y1.y5 SP DIx entity Divider is Port ( clk48 : in std_logic; rst : in std_logic; loc_clk : out std_logic); end Divider; architecture Behavioral of Divider is signal div: unsigned (26 downto 0); begin process(clk48, rst) begin if rst= '1' then div '0'); elsif rising_edge(clk48) then div<= div + 1; end if; end process; loc_clk<= div(div'left); end Behavioral; Divides clock to HFSM HFSM outputs FSM stack pointer decrement FSM stack pointer increment x1x1 FSM stack pointer

entity HFSM_test is Port ( clk : in std_logic; rst : in std_logic; count : out std_logic_vector(3 downto 0); inputs : in std_logic_vector(7 downto 0); outputs : out std_logic_vector(7 downto 0)); end HFSM_test; architecture Behavioral of HFSM_test is -- FSM module begin type STATE_TYPE is (a0, a1, a2, a3, a4); signal NS: STATE_TYPE; -- FSM module end for stack begin type stack is array(0 to 63) of STATE_TYPE; signal FSM_stack : stack; signal stack_counter : integer range 0 to 63; signal inc : std_logic; signal dec : std_logic; for stack end signal return_flag : std_logic; begin clock Hz reset from reset button inputs(7) = S 7 = x 1 FSM stack pointer x 1 inc dec y 5 y 4 y 3 y 2 y 1 HFSM states HFSM stack HFSM stack pointer HFSM stack pointer increment HFSM stack pointer decrement

for stack begin process(clk,rst,FSM_stack,stack_counter) begin if rst = '1' then stack_counter <= 0; FSM_stack(stack_counter) <= a0; return_flag <= '0'; elsif rising_edge(clk) then if stack_counter < 63 and inc = '1' then stack_counter <= stack_counter + 1; FSM_stack(stack_counter+1) <= a0; elsif stack_counter > 0 and dec = '1' then stack_counter <= stack_counter - 1; return_flag <= '1'; else FSM_stack(stack_counter) <= NS; return_flag <= '0'; end if; count <= conv_std_logic_vector(stack_counter,4); end process; for stack end

-- FSM module begin process (FSM_stack,stack_counter,inputs(7)) begin case FSM_stack(stack_counter) is when a0 => outputs '0'); inc <= '0'; dec <= '0'; if (inputs(7)='0') then NS <= a4; else NS <= a1; end if; when a1 => inc <= '0'; dec <= '0'; NS <= a2; if return_flag = '0' then inc <= '1'; outputs(4 downto 0) <= "00011"; else inc '0'); end if; when a2 => outputs(4 downto 0) <= "00100"; inc <= '0'; dec <= '0'; NS <= a3; when a3 => dec <= '0'; NS <= a4; if return_flag = '0' then inc <= '1'; outputs(4 downto 0) <= "01001"; else inc '0'); end if; when a4 => inc <= '0'; NS <= a4; if stack_counter > 0 then dec <= '1'; outputs(4 downto 0) <= "10000"; else dec '0'); end if; when others => null; end case; outputs(5) <= dec; outputs(6) <= inc; outputs(7) <= inputs(7); end process; -- FSM module end end Behavioral; Experiments with this code permit to test all state transitions and to understand hierarchical calls, recursivity and hierarchical returns

Begin End z 2 a 0 a 1 a 2 Z 0

This block is a datapath that is controlled by HFSM This circuit sorts and displays data from a given binary tree

entity HFSM is generic (stack_size : integer := 15); port ( clk : in std_logic; rst : in std_logic; error : buffer std_logic; X1_from_datapath : in std_logic; outputs_to_datapath : out std_logic_vector(5 downto 1)); end HFSM; architecture Behavioral of HFSM is -- modules begin type MODULE_TYPE is (m0, m2); signal NM: MODULE_TYPE; -- modules end -- FSM module begin type STATE_TYPE is (a0, a1, a2, a3, a4); signal NS: STATE_TYPE; -- FSM module end for stack begin type stack is array(0 to stack_size) of STATE_TYPE;-- std_logic_vector(3 downto 0); signal FSM_stack : stack; signal stack_counter : integer range 0 to stack_size; signal inc,tmp : std_logic; signal dec : std_logic; for stack end signal that indicates a possible error input from datapath outputs to datapath

for stack of modules begin type Mstack is array(0 to stack_size) of MODULE_TYPE;-- std_logic_vector(3 downto 0); signal M_stack : Mstack; for stack of modules end signal return_flag : std_logic; begin for stack begin process(clk,rst) begin if rst = '1' then stack_counter <= 0; FSM_stack(stack_counter) <= a0; M_stack(stack_counter) <= m0; return_flag <= '0'; error <= '0'; elsif rising_edge(clk) then if inc = '1' then if stack_counter = stack_size then error <= '1'; else stack_counter <= stack_counter + 1; FSM_stack(stack_counter+1) <= a0; M_stack(stack_counter+1) <= NM; end if; elsif dec = '1' then stack_counter <= stack_counter - 1; return_flag <= '1'; else FSM_stack(stack_counter) <= NS; return_flag <= '0'; end if; end process; for stack end Begin End z 2 a 0 a 1 a 2 Z 0 indicates stack overflow

-- FSM module begin process (FSM_stack,stack_counter,X1_from_datapath, M_stack) begin case M_stack(stack_counter) is when m0 => case FSM_stack(stack_counter) is when a0 => outputs_to_datapath '0'); inc <= '0'; dec <= '0'; NS <= a1; when a1 => dec '0'); if return_flag = '0' then inc <= '1'; NM <= m2; else inc <= '0'; end if; when a2 => inc '0'); if stack_counter > 0 then dec <= '1'; else dec <= '0'; end if; when others => null; end case; Begin End z 2 a 0 a 1 a 2 Z 0

when m2 => case FSM_stack(stack_counter) is when a0 => outputs_to_datapath '0'); inc <= '0'; dec <= '0'; if (X1_from_datapath='1') then NS <= a1; else NS <= a4; end if; when a1 => dec <= '0'; NS <= a2; if return_flag = '0' then inc <= '1'; outputs_to_datapath <= "00011"; NM<=m2; else inc <= '0'; outputs_to_datapath <= "00000"; end if; when a2 => outputs_to_datapath <= "00100"; inc <= '0'; dec <= '0'; NS <= a3; when a3 => dec <= '0'; NS <= a4; if return_flag = '0' then inc <= '1'; outputs_to_datapath <= "01001"; NM<=m2; else inc <= '0'; outputs_to_datapath <= "00000"; end if; when a4 => inc <= '0'; NS <= a4; if stack_counter > 0 then dec <= '1'; outputs_to_datapath <= "10000"; else dec <= '0'; outputs_to_datapath <= "00000"; end if; when others => null; end case; when others => null; end case; end process; -- FSM module end end Behavioral; Begin x 1 y a 0 a 1 a 2 End, y 5 a 3 a 4 y 1,y 2,z 2 y 1 4,z 2 Z 2

entity Data_LCD is generic ( ROM_address_size : integer := 4; ROM_words : integer := 10; ROM_data : integer := 6; Lstack_size : integer := 15); port ( HFSM_outputs : in std_logic_vector(5 downto 1); x1_to_HFSM : out std_logic; clk : in std_logic; rst : in std_logic; error : buffer std_logic ); end Data_LCD; Result expected for this binary tree sorted data RAM address at the end RAM value HFSM outputs " "," "," ",… address 0 address 1 address 2 ……….. data left node address right node address input data in ROM

architecture Behavioral of Data_LCD is type rom_type is array (0 to ROM_words-1) of std_logic_vector (ROM_data+2*ROM_address_size-1 downto 0); constant ROM : rom_type := (" "," "," ", " "," "," ", " "," "," "," "); signal ROM_address : integer; for local stack begin type Lstack_memory is array(0 to Lstack_size) of std_logic_vector(ROM_address_size-1 downto 0); signal Lstack : Lstack_memory; signal Lstack_counter : integer range 0 to Lstack_size; for local stack end for output stack begin type Ostack_memory is array(0 to ROM_words) of std_logic_vector(ROM_data-1 downto 0); signal Ostack : Ostack_memory; signal Ostack_counter : integer range 0 to ROM_words-1; for output stack end

begin process (clk,rst) begin if rst = '1' then ROM_address <= 0; Lstack_counter <= 0; Ostack_counter <= 0; x1_to_HFSM <= '1'; error <= '0'; elsif falling_edge(clk) then if ROM_address > ROM_words-1 then x1_to_HFSM <= '0'; else x1_to_HFSM <= '1'; end if; if Lstack_counter > Lstack_size-1 then error <= '1'; end if; if HFSM_outputs(1) = '1' then Lstack_counter <= Lstack_counter + 1; Lstack(Lstack_counter) <= conv_std_logic_vector(ROM_address,ROM_address_size); end if; if HFSM_outputs(2) = '1' then ROM_address <= conv_integer(ROM(ROM_address)(ROM_address_size-1 downto 0)); end if; if HFSM_outputs(3) = '1' then Ostack_counter <= Ostack_counter + 1; Ostack(Ostack_counter) <= ROM(ROM_address)(ROM_data+2*ROM_address_size-1 downto 2*ROM_address_size); end if; if HFSM_outputs(4) = '1' then ROM_address <= conv_integer(ROM(ROM_address)(2*ROM_address_size-1 downto ROM_address_size)); end if; if HFSM_outputs(5) = '1' then Lstack_counter <= Lstack_counter - 1; ROM_address <= conv_integer(Lstack(Lstack_counter - 1)); end if; end process; Begin x 1 y a 0 a 1 a 2 End, y 5 a 3 a 4 y 1,y 2,z 2 y 1 4,z 2 Z 2

The result Clock frequency for this project is set to 25 MHz. The project contains a non linked divider. The divider can be linked in order to provide such (lower) frequency that permits all intermediate steps and relevant changes in the datapath to be seen on the LCD

entity HFSM is generic (stack_size : integer := 15); port ( clk : in std_logic; rst : in std_logic; error : buffer std_logic; X1_from_datapath : in std_logic; X3_from_datapath : in std_logic; X4_from_datapath : in std_logic; outputs_to_datapath : out std_logic_vector(8 downto 1)); end HFSM; architecture Behavioral of HFSM is -- modules begin type MODULE_TYPE is (m0, m1); signal NM: MODULE_TYPE; -- modules end -- FSM module begin type STATE_TYPE is (a0, a1, a2, a3, a4, a5, a6); signal NS: STATE_TYPE; -- FSM module end The considered circuit adds a new node to the existing binary tree The circuit does not check if there is a node in the binary tree with equal value. In other words equal values will be repeated in the binary tree The next example (example 6) eliminates repeating values on the tree 20

for stack begin type stack is array(0 to stack_size) of STATE_TYPE;-- std_logic_vector(3 downto 0); signal FSM_stack : stack; signal stack_counter : integer range 0 to stack_size; signal inc,tmp : std_logic; signal dec : std_logic; for stack end for stack of modules begin type Mstack is array(0 to stack_size) of MODULE_TYPE;-- std_logic_vector(3 downto 0); signal M_stack : Mstack; for stack of modules end signal return_flag : std_logic; begin for stack begin process(clk,rst) begin if rst = '1' then stack_counter <= 0; FSM_stack(stack_counter) <= a0; M_stack(stack_counter) <= m0; return_flag <= '0'; error <= '0'; elsif rising_edge(clk) then if inc = '1' then if stack_counter = stack_size then error <= '1'; else stack_counter <= stack_counter + 1; FSM_stack(stack_counter+1) <= a0; M_stack(stack_counter+1) <= NM; end if; elsif dec = '1' then stack_counter <= stack_counter - 1; return_flag <= '1'; else FSM_stack(stack_counter) <= NS; return_flag <= '0'; end if; end process; for stack end This code has already been considered

-- FSM module begin process (FSM_stack,stack_counter,X1_from_datapath, M_stack) begin case M_stack(stack_counter) is when m0 => case FSM_stack(stack_counter) is when a0 => outputs_to_datapath '0'); inc <= '0'; dec <= '0'; NS <= a1; when a1 => dec '0'); if return_flag = '0' then inc <= '1'; NM <= m1; else inc <= '0'; end if; when a2 => inc '0'); if stack_counter > 0 then dec <= '1'; else dec <= '0'; end if; when others => null; end case; This code has already been considered Begin End z 2 a 0 a 1 a 2 Z 0 z1z1

when m1 => case FSM_stack(stack_counter) is when a0 => outputs_to_datapath '0'); inc <= '0'; dec <= '0'; if X3_from_datapath='1' then NS <= a1; elsif X4_from_datapath='0' then NS <= a2; else NS <= a3; end if; when a1 => dec <= '0'; inc <= '0'; NS <= a6; outputs_to_datapath <= " "; when a2 => dec <= '0'; NS <= a4; if return_flag = '0' then inc <= '1'; outputs_to_datapath <= " "; NM<=m1; else inc '0'); end if; when a3 => dec <= '0'; NS <= a5; if return_flag = '0' then inc <= '1'; outputs_to_datapath <= " "; NM<=m1; else inc '0'); end if; when a4 => inc <= '0'; dec <= '0'; NS <= a6; outputs_to_datapath <= " "; when a5 => inc <= '0'; dec <= '0'; NS <= a6; outputs_to_datapath <= " "; when a6 => inc <= '0'; NS <= a6; if stack_counter > 0 then dec <= '1'; outputs_to_datapath <= " "; else dec '0'); end if; when others => null; end case; when others => null; end case;end process; -- FSM module end end Behavioral; Begin X 4 X End (y 5 ) 0 1 a 0 a 1 a 2 a 3 a 7 y 8 a 4 a 5 y 1,y 4, z 1 Z 1 y 1 2, z 1 y 6 y 7

entity Data_LCD is generic ( RAM_address_size : integer := 4; RAM_words : integer := 10; RAM_data : integer := 6; Lstack_size : integer := 15); port ( HFSM_outputs : in std_logic_vector(8 downto 1); x1_to_HFSM : out std_logic; x3_to_HFSM : out std_logic; x4_to_HFSM : out std_logic; clk : in std_logic; clk48 : in std_logic; rst : in std_logic; error : buffer std_logic ); end Data_LCD; architecture Behavioral of Data_LCD is type ram_type is array (0 to RAM_words-1) of std_logic_vector (RAM_data+2*RAM_address_size-1 downto 0); type rom_type is array (0 to 10) of std_logic_vector (5 downto 0); constant ROM : rom_type := ("000111","001000","010101","000110","001001","110011", "000000","000000","000000","000000","000000"); signal ROM_address : integer; signal RAM : ram_type; signal RAM_address : integer; signal RAM_w : integer; for local stack begin type Lstack_memory is array(0 to Lstack_size) of std_logic_vector(RAM_address_size-1 downto 0); signal Lstack : Lstack_memory; signal Lstack_counter : integer range 0 to Lstack_size; for local stack end for output stack begin type Ostack_memory is array(0 to RAM_words) of std_logic_vector(RAM_data-1 downto 0); signal Ostack : Ostack_memory; signal Ostack_counter : integer range 0 to RAM_words-1; for output stack end This code has already been considered 7 This value will be added

begin process (clk,rst) variable last_address : integer; begin if rst = '1' then RAM_address <= 0; ROM_address <= 0; RAM_w <= 2; RAM(0)(13 downto 8) <= "010000"; RAM(0)(7 downto 0) <= " "; RAM(1)(13 downto 8) <= "100000"; RAM(1)(7 downto 0) '1'); RAM(2)(13 downto 8) <= "001001"; RAM(2)(7 downto 0) '1'); Lstack_counter <= 0; Ostack_counter <= 0; x1_to_HFSM <= '1'; error <= '0'; elsif falling_edge(clk) then if RAM_address > RAM_words-1 then x1_to_HFSM <= '0'; else x1_to_HFSM <= '1'; end if; if RAM_address = 15 then x3_to_HFSM <= '1'; else x3_to_HFSM <= '0'; end if; if ROM(ROM_address) < RAM(RAM_address)(13 downto 8) then x4_to_HFSM <= '1'; else x4_to_HFSM <= '0'; end if; if Lstack_counter > Lstack_size-1 then error <= '1'; end if; Forming logic conditions x 2 and x 4

if HFSM_outputs(1) = '1' then Lstack_counter <= Lstack_counter + 1; Lstack(Lstack_counter) <= conv_std_logic_vector(RAM_address,RAM_address_size); end if; if HFSM_outputs(2) = '1' then RAM_address <= conv_integer(RAM(RAM_address)(RAM_address_size-1 downto 0)); end if; if HFSM_outputs(3) = '1' then Ostack_counter <= Ostack_counter + 1; Ostack(Ostack_counter) <= RAM(RAM_address) (RAM_data+2*RAM_address_size-1 downto 2*RAM_address_size); end if; if HFSM_outputs(4) = '1' then RAM_address <= conv_integer(RAM(RAM_address)(2*RAM_address_size-1 downto RAM_address_size)); end if; if HFSM_outputs(5) = '1' then Lstack_counter <= Lstack_counter - 1; RAM_address <= conv_integer(Lstack(Lstack_counter - 1)); end if; if HFSM_outputs(6) = '1' then RAM(RAM_address)(RAM_address_size-1 downto 0) <= Lstack(Lstack_counter+1); end if; if HFSM_outputs(7) = '1' then RAM(RAM_address) (2*RAM_address_size-1 downto RAM_address_size) <= Lstack(Lstack_counter+1); end if; if HFSM_outputs(8) = '1' then RAM(RAM_w+1) (RAM_data+2*RAM_address_size-1 downto 2*RAM_address_size) <= ROM(ROM_address); RAM(RAM_w+1)(2*RAM_address_size-1 downto 0) '1'); ROM_address <= ROM_address+1; RAM_w <= RAM_w+1; Lstack(Lstack_counter) <= conv_std_logic_vector(RAM_w+1,RAM_address_size); end if; end process; Begin X 4 X End (y 5 ) 0 1 a 0 a 1 a 2 a 3 a 7 y 8 a 4 a 5 y 1,y 4, z 1 Z 1 y 1 2, z 1 y 6 y 7 y 3 is not used for this algorithm but will be used in future

?? 09?? Values Left address Right address There is no node on the right There is no node on the left ?? 09?? address 0 address 1 address 2 address 3 RAM address y 1 …y 8

?? 09?? ?? ?? 09? There is the node on the left with the address 3 There is no node on the right address 3 The frequency of clocks is low, which permits to see all changes on the HFSM outputs step by step RAM address ? indicates that there is no node after the considered node

Local stack stores arguments that are required for an active module (such as z 1 and z 2 ) at each hierarchical level. In other words the local stack works like a stack for functions (subroutines) in C/C++ languages that keeps arguments of these functions when they are being called

entity HFSM is generic (stack_size : integer := 15); port ( clk : in std_logic; rst : in std_logic; error : buffer std_logic; X1_from_datapath : in std_logic; X2_from_datapath : in std_logic; X3_from_datapath : in std_logic; X4_from_datapath : in std_logic; X5_from_datapath : in std_logic; outputs_to_datapath : out std_logic_vector(9 downto 1)); end HFSM; architecture Behavioral of HFSM is -- modules begin type MODULE_TYPE is (m0, m1, m2);signal NM: MODULE_TYPE; -- modules end -- FSM module begin type STATE_TYPE is (a0, a1, a2, a3, a4, a5, a6, a7);signal NS: STATE_TYPE; -- FSM module end inputs from datapath outputs to datapath

for HFSM stack begin type stack is array(0 to stack_size) of STATE_TYPE; signal FSM_stack : stack; signal stack_counter : integer range 0 to stack_size; signal inc,tmp : std_logic; signal dec : std_logic; for HFSM stack end for HFSM stack of modules begin type Mstack is array(0 to stack_size) of MODULE_TYPE; signal M_stack : Mstack; for HFSM stack of modules end signal return_flag : std_logic; begin for HFSM stack begin process(clk,rst) begin if rst = '1' then stack_counter <= 0; FSM_stack(stack_counter) <= a0; M_stack(stack_counter) <= m0; return_flag <= '0'; error <= '0'; elsif rising_edge(clk) then if inc = '1' then if stack_counter = stack_size then error <= '1'; else stack_counter <= stack_counter + 1; FSM_stack(stack_counter+1) <= a0; M_stack(stack_counter+1) <= NM; end if; elsif dec = '1' then stack_counter <= stack_counter - 1; return_flag <= '1'; else FSM_stack(stack_counter) <= NS; return_flag <= '0'; end if; end process; for HFSM stack end

-- HFSM module begin process (FSM_stack,stack_counter,X1_from_datapath, M_stack)begin case M_stack(stack_counter) is when m0 => case FSM_stack(stack_counter) is when a0 => outputs_to_datapath '0'); inc <= '0'; dec <= '0'; NS <= a1; when a1 => dec '0'); if X5_from_datapath='0' then NS <= a1; else NS <= a2; end if; if return_flag = '0' then inc <= '1'; NM <= m1; else inc <= '0'; end if; when a2 => dec '0'); if return_flag = '0' then inc <= '1'; NM <= m2; else inc <= '0'; end if; when a3 => inc '0'); if stack_counter > 0 then dec <= '1'; else dec <= '0'; end if; when others => null; end case; when m1 => case FSM_stack(stack_counter) is when a0 => outputs_to_datapath '0'); inc <= '0'; dec <= '0'; if X3_from_datapath='1' then NS <= a1; elsif X2_from_datapath='0' then NS <= a6; elsif X4_from_datapath='0' then NS <= a2; else NS <= a3; end if; when a1 => dec <= '0'; inc <= '0'; NS <= a7; outputs_to_datapath <= " "; when a2 => dec <= '0'; NS <= a4; if return_flag = '0' then inc <= '1'; outputs_to_datapath <= " "; NM<=m1; else inc '0'); end if; when a3 => dec <= '0'; NS <= a5; if return_flag = '0' then inc <= '1'; outputs_to_datapath <= " "; NM<=m1; else inc '0'); end if;

when a4 => inc <= '0'; dec <= '0'; NS <= a7; outputs_to_datapath <= " "; when a5 => inc <= '0'; dec <= '0'; NS <= a7; outputs_to_datapath <= " "; when a6 => inc <= '0'; dec <= '0'; NS <= a7; outputs_to_datapath <= " "; when a7 => inc <= '0'; NS <= a7; if stack_counter > 0 then dec <= '1'; outputs_to_datapath <= " "; else dec '0'); end if; when others => null; end case; when m2 => case FSM_stack(stack_counter) is when a0 => outputs_to_datapath '0'); inc <= '0'; dec <= '0'; if (X1_from_datapath='1') then NS <= a1; else NS <= a4; end if; when a1 => dec <= '0'; NS <= a2; if return_flag = '0' then inc <= '1'; outputs_to_datapath <= " "; NM<=m2; else inc '0'); end if; when a2 => outputs_to_datapath <= " "; inc <= '0'; dec <= '0'; NS <= a3; when a3 => dec <= '0'; NS <= a4; if return_flag = '0' then inc <= '1'; outputs_to_datapath <= " "; NM<=m2; else inc '0'); end if; when a4 => inc <= '0'; NS <= a4; if stack_counter > 0 then dec <= '1'; outputs_to_datapath <= " "; else dec '0'); end if; when others => null; end case; when others => null; end case; end process;-- HFSM module end end Behavioral;

entity Data_LCD is generic ( RAM_address_size : integer := 4; RAM_words : integer := 12; ROM_words: integer := 12; RAM_data : integer := 6; Lstack_size : integer := 15); port ( HFSM_outputs : in std_logic_vector(9 downto 1); x1_to_HFSM : out std_logic; x2_to_HFSM : out std_logic; x3_to_HFSM : out std_logic; x4_to_HFSM : out std_logic; x5_to_HFSM : out std_logic; clk : in std_logic; clk48 : in std_logic; rst : in std_logic; error: buffer std_logic; end Data_LCD; architecture Behavioral of Data_LCD is -- begin for ROM that keeps input data and the datapath RAM type ram_type is array (0 to RAM_words-1) of std_logic_vector (RAM_data+2*RAM_address_size-1 downto 0); type rom_type is array (0 to ROM_words-1) of std_logic_vector (5 downto 0); constant ROM : rom_type := ("110000","010100","001001", -- 30,14,9,7,13,9,37,2,7,8,17,21 "000111","010011","001001", "110111","000010","000111", -- changes in generic "001000","010111","100001"); -- ROM_words : integer := 12; outputs to HFSM inputs from HFSM The modules z 0 and z 1 will construct this binary tree

signal ROM_address : integer; signal RAM : ram_type; signal RAM_address : integer; signal RAM_w : integer; signal ROM_w : integer; -- end for ROM that keeps input data and the datapath RAM for local stack begin type Lstack_memory is array(0 to Lstack_size) of std_logic_vector(RAM_address_size-1 downto 0); signal Lstack : Lstack_memory; signal Lstack_counter : integer range 0 to Lstack_size; for local stack end for output stack begin type Ostack_memory is array(0 to RAM_words) of std_logic_vector(RAM_data-1 downto 0); signal Ostack : Ostack_memory; signal Ostack_counter : integer range 0 to RAM_words-1; for output stack end begin process (clk,rst) variable last_address : integer; begin if rst = '1' then RAM_address <= 0; ROM_address <= 1; RAM_w <= 0; ROM_w <= ROM_words; RAM(0)(13 downto 8) <= ROM(0); RAM(0)(7 downto 0) '1'); LStack(0) '0'); Lstack_counter <= 0; Ostack_counter <= 0; x1_to_HFSM <= '1'; error <= '0'; Initialization

elsif falling_edge(clk) then if RAM_address > RAM_words-1 then x1_to_HFSM <= '0'; else x1_to_HFSM <= '1'; end if; if ROM(ROM_address) = RAM(RAM_address) (RAM_data+2*RAM_address_size-1 downto 2*RAM_address_size) then x2_to_HFSM <= '0'; else x2_to_HFSM <= '1'; end if; if RAM_address = 15 then x3_to_HFSM <= '1'; else x3_to_HFSM <= '0'; end if; if ROM(ROM_address) < RAM(RAM_address) (RAM_data+2*RAM_address_size-1 downto 2*RAM_address_size) then x4_to_HFSM <= '1'; else x4_to_HFSM <= '0'; end if; if ROM_address = ROM_w then x5_to_HFSM <= '1'; else x5_to_HFSM <= '0'; end if; if Lstack_counter > Lstack_size-1 then error <= '1'; end if; if HFSM_outputs(1) = '1' then Lstack_counter <= Lstack_counter + 1; Lstack(Lstack_counter) <= conv_std_logic_vector(RAM_address,RAM_address_size); end if; if HFSM_outputs(2) = '1' then RAM_address <= conv_integer(RAM(RAM_address)(RAM_address_size-1 downto 0)); end if; if HFSM_outputs(3) = '1' then Ostack_counter <= Ostack_counter + 1; Ostack(Ostack_counter) <= RAM(RAM_address) (RAM_data+2*RAM_address_size-1 downto 2*RAM_address_size); end if;

if HFSM_outputs(4) = '1' then RAM_address <= conv_integer(RAM(RAM_address) (2*RAM_address_size-1 downto RAM_address_size)); end if; if HFSM_outputs(5) = '1' then if Lstack_counter > 0 then Lstack_counter <= Lstack_counter - 1; RAM_address <= conv_integer(Lstack(Lstack_counter - 1)); end if; if HFSM_outputs(6) = '1' then RAM(RAM_address) (RAM_address_size-1 downto 0) <= Lstack(Lstack_counter+1); end if; if HFSM_outputs(7) = '1' then RAM(RAM_address) (2*RAM_address_size-1 downto RAM_address_size) <= Lstack(Lstack_counter+1); end if; if HFSM_outputs(8) = '1' then RAM(RAM_w+1) (RAM_data+2*RAM_address_size-1 downto 2*RAM_address_size) <= ROM(ROM_address); RAM(RAM_w+1)(2*RAM_address_size-1 downto 0) '1'); ROM_address <= ROM_address+1; RAM_w <= RAM_w+1; Lstack(Lstack_counter) <= conv_std_logic_vector(RAM_w+1,RAM_address_size); end if; if HFSM_outputs(9) = '1' thenROM_address <= ROM_address+1; Lstack(Lstack_counter) <= conv_std_logic_vector(RAM_address,RAM_address_size); end if; end process;

--constant ROM : rom_type := --("100010","001000","111001", -- 22,8,39,6,9,6,39,3,6,8,18,21,0,28,1 -- "000110","001001","000110", -- "111001","000011","000110", -- "001000","011000","100001", -- changes in generic -- "000000","101000","000001"); -- ROM_words : integer := 15; --constant ROM : rom_type := --("100010","001000","111001", -- 22,8,39,6,9,6,39,3,6,8,18,21,0,28,1,22,33 -- "000110","001001","000110", -- "111001","000011","000110", -- "001000","011000","100001", -- changes in generic -- "000000","101000","000001", -- ROM_words : integer := 18; -- "100010","110011","110011"); --constant ROM : rom_type := --("100010","000110","010101", "111001","001001","000110", -- "000110","000011","100111", -- changes in generic -- "010010","100010","100001"); -- ROM_words : integer := 12; --constant ROM : rom_type := --("100010","001000","010101", -- 22,8,15,6,9,6,33,3,6,12,18,21 -- "000110","001001","000110", -- "111001","000011","000110", -- changes in generic -- "010010","011000","100001"); -- ROM_words : integer := 12; --constant ROM : rom_type := --("100010","001000","010101", -- 22,8,15,6,9,33,39,3,27,12,18,21 -- "000110","001001","110011", -- "111001","000011","100111", -- changes in generic -- "010010","011000","100001"); -- ROM_words : integer := 12; --constant ROM : rom_type := --("010000","110000","100000", -- 10,30,20,25,5,35,6,7,8,,29,28,27 -- "100101","000101","110101", -- "000110","000111","001000", -- changes in generic -- "101001","101000","100111"); -- ROM_words : integer := 12; These sets of input data make possible to test various examples The modules z 0, z 1 build this binary tree The module z 2 sorts the numbers and stores in the output stack the following result:

The module z 2 sorts the numbers and stores in the output stack the following result: This result will be displayed on the LCD as follows: constant ROM : rom_type := ("110000","010100","001001", -- 30,14,9,7,13,9,37,2,7,8,17,21 "000111","010011","001001", "110111","000010","000111", -- changes in generic "001000","010111","100001"); -- ROM_words : integer := 12; Another example: The modules z 0, z 1 build this binary tree This result will be displayed on the LCD as follows: The module z 2 sorts the numbers and stores in the output stack the following result:

The code, which contols LCD is inserted to the datapath (the data_lcd block). This code is separated by comments y 1,…,y 9 x 1,…,x 5

There are 7 examples available that demonstrate different steps of the tutorial 1. Visual C zipped project for C++ program considered in the part1 2. ISE 5.2 zipped project for Example 1 – stack memory (see Part 2) 3. ISE 5.2 zipped project for Example 2 – HFSM stack memory (see Part 2) 4. ISE 5.2 zipped project for Example 3 – recursive HFSM (see Part 2) 5. ISE 5.2 zipped project for Example 4 – multi module HFSM (see Part 2) 6. ISE 5.2 zipped project for Example 5 – constructing a binary tree (see Part 2) 7. ISE 5.2 zipped project for Example 6 – full example that implements all the circuits and the algorithms considered in the Part 1 (see Part 1 and Part 2) The names of the projects are: 1.HFSM_CPP.zip 2.stack.zip 3.HFSM_stack.zip 4.RHFSM.zip 5.MM_HFSM.zip 6.CBT.zip 7.Full_example.zip C++ ISE 5.2