490 likes | 669 Views
Lecture 6 Chap 8: Sequential VHDL. Instructors: Fu-Chiung Cheng ( 鄭福炯 ) Associate Professor Computer Science & Engineering Tatung University. VHDL domains:. VHDL has two domains: A. concurrent domain: signal assignment (chap 3,4), component instances (chap 11),
E N D
Lecture 6Chap 8: Sequential VHDL Instructors: Fu-Chiung Cheng (鄭福炯) Associate Professor Computer Science & Engineering Tatung University
VHDL domains: • VHDL has two domains: • A. concurrent domain: signal assignment (chap 3,4), • component instances (chap 11), • processes. • B. sequential domain: the statements in a process. • Sequential VHDL is difficult to interpretation • as hardware
VHDL processes: • A process is a series of sequential statements that • must be executed in order. • Basic structure of a process: • process sensitivity-list • declaration part • begin • statement part • end process;
librar ieee; use ieee.std_logic_1164.all, ieee.number_std.all; entity adder is port(a, b: in unsigned(3 downto 0); sum: out unsigned(3 downto 0)); end; architecture behavior of adder is process (a.b) begin sum <= a + b; end process; end;
VHDL procsses: • sensitivity list: a list of signals to which the process • is sensitive • Any events on any of the signals in the sensitivity list • causes the process to be executed once. • A. all the statements in the statement part will be • executed • B. Then the process will stop and wait for further • activity
Wait statement • The sensitivity list is optional. • If sensitivity list is absent, then the process must • contain wait statements. • Sensitivity list and wait are mutual exclusive. • Basic structure: • process • declaration part • begin • statement part • wait on sensitivity-list; • end process;
librar ieee; use ieee.std_logic_1164.all, ieee.number_std.all; entity adder is port(a, b: in unsigned(3 downto 0); sum: out unsigned(3 downto 0)); end; architecture behavior of adder is process begin sum <= a + b; wait on a, b; end process; end;
Declaration and Statement parts • Declaration part of a process: allows the declaration • of types, functions, procedures, variables which are • local to the process. • Statement part of a process: contains the sequential • statements to be executed each time the process is • activated. • Sequential statements: • A. if statement. • B. case statements, • C. for loops, • D. simple signal assignments
Combinational Process • Combinational process must be sensitive to all the • signals that are read in the process. • If a process is not sensitive to all its inputs and is not • a registered process (chap 9) then it is unsynthesisable • Example: adder • A. inputs of the process: signals a and b. • B. it is a combinational logic. • C. a sensitivity list = wait statement at the end. • VHDL allows any number of wait statements in a • process with no sensitivity list. However, when used • for synthesis, only one wait statement can be present.
Wait statement positioning • why wait at the end = sensitivity list • At the elaboration phase of the simulation, all process • in a model are run once. • (elaboration = VHDL simulator at initialization) • It is not necessary to place the wait statement at the • end of the process. • The most common place for wait statement is at the • start (any of the statements will not be run at the • elaboration time.)
librar ieee; use ieee.std_logic_1164.all, ieee.number_std.all; entity adder is port(a, b: in unsigned(3 downto 0); sum: out unsigned(3 downto 0)); end; architecture behavior of adder is process begin wait on a, b; sum <= a + b; end process; end;
Wait statement positioning • Note that elaboration has no hardware equivalent. • Elaboration makes no difference to synthesized circuits. • Note that the difference between simulation and • synthesis due to elaboration can be a pitfall. • Simulation OK but Gate level implementation is not • (initialization problem)
Signal Assignment • Signals are the interface between VHDL’s concurrent • domain and the sequential domain within a process. • Signals are a means of communication between • processes • VHDL model: • a network of processes intercommunicating via signals. • All the hierarchy is effectively removed to leave a • network of processes and signals.
Signal Assignment • VHDL Simulator: • A. update signal values • B. run processes activated by the changes on the signals • listed in their sensitivity list. • While a process is running, all signals in the system • remain unchanged. (constant during process execution) • A signal assignment in a process causes a signal change • (an event) to be queued for that signal. • The simulator will not process the event until • process execution stops. • (signals are updated at the end of the process)
Signal Assignment • Three types of signal assignments: • A. simple assignment (OK in a process) • B. conditional assignment (not OK) • C. selected assignment (not OK) • if and case statements can be used in a process • to implement B and C
Variables • Variables are used to store intermediate values within • a process • Variables can only exist within sequential VHDL • (can not be declared or used directly in an architecture.) • Variable declaration: • variable a, b, c: std_logic; • Initial values: • variable a: std_logic :=‘1’; • If variables do not have explicit initial values given in • the declaration, the left values of the types will be • used as initial values.
Variables • Signals are not updated during process execution. • Thus, signals can not be used to store intermediate • values of calculation during process execution • Variables are updated immediately by variable • assignments • A. accumulate result • B. store intermediate values in a calculation within a • process. • C. variable := expr; • Example:
librar ieee; use ieee.std_logic_1164.all; entity full_adder is port(a, b: in std_logic; cout, sum: out std_logic); end; architecture behavior of full_adder is process (a,b,c) variable sum1, sum2, c1, c2: std_logic; begin sum1 := a xor b; c1:= a and b; -- HA sum2 := sum1 xor c; c2:= sum1 and c; -- HA sum <= sum2; cout <= c1 or c2; end process; end;
If statement • if statement is the sequential equivalent of the • conditional signal assignment. • Syntax: • if boolean then • true-statements-1; • [elsif boolean then • true-statements-2; | …] • [else • default-statements; ] • end if;
process (a,b) begin if a = b then result <= “00”; -- 0: equal elsif a < b then result <= “11”; -- -1: less than else result <= “01”; -- 1: greater than end if; end process;
If statement • hardware implementation: multiplexers process (a,b) begin if a = b then equal <= ‘1’; else equal <= ‘0’; end if; end process;
z <= a when sel1 = ‘1’ else b when sel2 = ‘1’ else c; If statement process (a,b,c, sel1, sel2) begin if sel1 = ‘1’ then z <= a; elsif sel2 = ‘1’ z <= b; else z <= c; end if; end process;
If statement: prioritization process (a,b,c, sel1, sel2) begin if sel1 = ‘1’ then z <= a; elsif sel1 = ‘0’ and sel2 = ‘1’ -- redundant z <= b; -- bad else z <= c; end if; end process;
Incomplete If statement: • What happens if there is a missing else part? • What happens if there is a signal that is not assigned • in some branches of the if statement? • Ans: The signals that do not received values, • the previous values is preserved. • Latches are used to keep the previous values • Such circuits are called sequential circuits. • (current states depend on previous history)
Complete If statement: process (a,b, enable) begin if enable = ‘1’ z <= b; else z <= a; end if; end process; process (a,b, enable) begin z <= a; if enable = ‘1’ z <= b; --- else part is missing end if; end process;
Incomplete If statement: process (a,b,c) begin if c = ‘1’ z <= a; --- z is not assigned --- if c = ‘0’ else y <= b; --- y is not assigned --- if c = ‘1’ end if; end process; process (a,b, enable) begin if enable = ‘1’ z <= b; // else part is missing end if; end process;
Incomplete If statement: • Incomplete if statement due to the redundant test: process (a,b,c) begin if c = ‘1’ z <= a; elsif c /=‘1’ then z <=b; end if; end process; Why? c = ‘1’ ==> c and 1 c = ‘0’ ==> c’ and 0’
Case statement • Case statement is like if statement. • The case statement does not need to be boolean. • The condition in case statement can be a signal, • variable, or expression • Example:
Case statement type light_type is (red, amber, green); … process (light) -- light has type light_type begin case light is when red => next_light <= green; when amber => next_light <= red; when green => next_light <=amber; end case; end process;
Case statement • when part: choices and branches • each branches can contain any number of statements • case statement must cover every possible value of the • type or subtype of the condition. • Keyword other: mopping up choice. • Example of legal choices: • A. when 0 to integer’high => • B. When red|amber => • C. When 0 to 1| 3 to 4 => • hardware implementation: multiplexers
Latches • If a signal is assigned only after some conditions and • not others, (incomplete if statement) then the previous • value of the signal is preserved. • In a registered process, the previous value is stored in • registers (synchronous sequential circuits) • In a combinational process the previous value is stored • in latches (asynchronous sequential circuits) • Thus, a process can contain a mixture of combinational • and latched outputs.
Latches • signal input, output : std_logic_vector(3 downto 0); • signal enable : std_logic; • … • process (enable, input) • begin • if enable = ‘1’ then • output <= input; • end if; • end process;
Latches • In principle, latch can be applied to a process of any • complexity. • In practice, analysis becomes extremely difficult when • there are many levels of nesting • Practical Synthesis tools have built-in limit. • Safe way: use only the outmost level of the conditional • A latched process is a combinational process with • latches on the outputs. • Example
A Latched Process: process (en, sel, a, b) begin if en = ‘1’ then if sel = ‘1’ then -- error ‘0’ z<= a; else z<=b; end if; end if; end process;
A Latched Process: • A latched process: • if en = ‘1’ then -- latch outputs • if sel = ‘1’ then -- begin combinational outputs • z<= a; • else -- complete if statemenet • z<=b; • end if; -- end of combination outputs • end if;
A Latched Process: • A single-level, two-branch if statement: • process (en, sel, a, b) • begin • if en = ‘1’ and sel=‘1’ then • z <=a; • elsif en=‘1’ and sel = ‘0’ then • z<=b; • end if; • end process; • The missing else clause means that the signal Z will not • always get a new value under all conditions.
Loops • A loop is a mechanism for repeating a section of VHDL • code. • Three types of loops in VHDL: • A. simple loop: loop indefinitely • B. while loop: loop until a condition become false. • C. for loop: loop a specified number of times. • Loop ==> hardware replication • Thus, only “for loop” is possible. • Example:
librar ieee; -- DA test: OK use ieee.std_logic_1164.all; entity match_bits is port(a, b: in std_logic_vector(7 downto 0); matches: out std_logic_vector(7 downto 0)); end; architecture behavior of match_bits is begin process (a,b) begin for I in 7 downto 0 loop matches(i) <= not (a(i) xor b(i) ); -- bitwise EQ end loop; end process; end;
librar ieee; use ieee.std_logic_1164.all; entity match_bits is port(a, b: in std_logic_vector(7 downto 0); match: out std_logic_ vector(7 downto 0)); end; architecture behavior of match_bits is process (a,b) begin matches(7) <= not (a(7) xor b(7) ); matches(6) <= not (a(6) xor b(6) ); …. matches(0) <= not (a(0) xor b(0) ); end process; end;
For loop • Note that the loop range is irrelevant, since there is no • connection between the replicated logic blocks. • Order is not important in this example. • Connection of replication blocks ==> variable • A variable is used to store value in one iteration of the • loop and then is read by another iteration. • Initialization is required. • Example:
librar ieee; use ieee.std_logic_1164.all, ieee.numeric_std.all; entity count_ones is port(vec: in std_logic_vector(15 downto 0); count: out unsigned(4 downto 0)); end;
architecture behavior of count_ones is process (vec) variable result: unsigned(4 downto 0); begin result := to_unsigned(0, result’length)); for i in 15 downto 0 loop if vec(i) = ‘1’ then result := result +1; end if; end loop -- DA Test: OK count <= result; -- but more complicate end process; end;
process (vec) variable result: unsigned(4 downto 0); begin result := to_unsigned(0, result’length)); if vec(15) = ‘1’ then result := result +1; end if; if vec(14) = ‘1’ then result := result +1; end if; …. if vec(0) = ‘1’ then result := result +1; end if; count <= result; end process;
For loop: • looping the elements of an array from left to right: • for i in vec’range loop • looping the elements of an array from right to left: • for i in vec’reverse_range loop • looping the elements of an array from lowest index to • highest index: • for i in vec’low to vec’high loop • looping the elements of an array from highest index to • lowest index: • for i in vec’high to vec’low loop
For loop: • hardware implementation: constant loop count • The constant loop count is a constraint that make some • circuits difficult to describe. • Example: • Count the number of of trailing zeros on a value: • count the zeros until a 1 is reached then stop. • This would be easy to describe as a while loop but • would be unsynthesisable. • Exit and next statement may be used
For loop: exit statement • The exit statement allows the execution of a for loop to • be stopped. • The loop is exited, even thought it has not completed • all its iterations. • Example: • Count the number of of trailing zeros on a value: • count the zeros until a 1 is reached then stop.
architecture behavior of count_trailing_zeros is process (vec) variable result: unsigned(4 downto 0); begin result := to_unsigned(0, result’length)); for i in vec’reverse_range loop exit when vec(i) = ‘1’; result = result +1; end loop count <= result; end process; end;
For loop: next statement • The next statement is closely to the exit statement • next statement skips any statements remaining in the • current iteration of the loop and moves straight on to • next iteration. • Example:
architecture behavior of count_ones is process (vec) variable result: unsigned(4 downto 0); begin result := to_unsigned(0, result’length)); for i in vec’range loop next when vec(i) = ‘0’; result = result +1; end loop count <= result; end process; end;