Unit-3
Behavioral Descriptions
The behavioral description is a powerful tool to describe systems for which digital logic structures are not known or are hard to generate.
The behavioral description describes the system by showing how outputs behave with the changes in inputs. In this description, details of the logic diagram of the system are not needed; what is needed is how the output behaves in response to a change in the input.
In VHDL, the major behavioral-description statement is process. In Verilog, the major behavioral-description statements are always and initial. For VHDL, the statements inside the process are sequential.
Let us take an example of Half adder VHDL Description: entity half_add is port (I1, I2 : in bit; O1, O2 : out bit); -- Since we are using type bit, no need for attaching a -- Library. -- If we use std_logic, we should attach the IEEE -- Library. end half_add; architecture behave_ex of half_add is begin process (I1, I2) begin O1 <= I1 xor I2 after 10 ns; -- statement 1 O2 <= I1 and I2 after 10 ns; -- statement 2 -- The above two statements are signal-assignment -- statements with 10 nanoseconds delays. -- --Other behavioral (sequential) statements can be added -- here end process; end behave_ex; Verilog Description: module half_add (I1, I2, O1, O2); input I1, I2; output O1, O2; reg O1, O2; / Since O1 and O2 are outputs and they are written inside “always,” they should be declared as reg / always @(I1, I2) begin #10 O1 = I1 ^ I2; // statement 1. #10 O2 = I1 & I2; // statement 2. end endmodule
|
Here HDL executes signal-assignment statements written inside process (VHDL) or inside always or initial (Verilog).
Referring to the VHDL code, the entity half add has two input ports, I1 and I2, and two output ports, O1 and O2. The ports are of type bit; this type is recognized by the VHDL package without the need to attach a library. If the type is std_logic, for example, the IEEE library must be attached.
The name of the architecture is behave_ex; it is bound to the entity half_add by the predefined word of. Process is the VHDL behavioral description keyword. Every VHDL behavioral description has to include a process. The statement process (I1, I2) is a concurrent statement, so its execution is determined by the occurrence of an event. I1 and I2 constitute a sensitivity list of the process. The process is executed (activated) only if an event occurs on any element of the sensitivity list; otherwise, the process remains inactive. If the process has no sensitivity list, the process is executed continuously.
All statements inside the body of a process are executed sequentially. The sequential execution here means sequential calculation, which means the calculation of a statement will not wait until the preceding statement is assigned; it will only wait until the calculation is done.
Referring to the Verilog code, always is the Verilog behavioral statement. In contrast to VHDL, all Verilog statements inside always are treated as concurrent, the same as in the data-flow description. Also, here any signal that is declared as an output or appears at the left-hand side of a signal-assignment statement should be declared as a register (reg) if it appears inside always.
The use of variables inside processes is a common practice in VHDL behavioral description. Consider the following two signal-assignment statements inside a process, where S1, S2, and t1 are signals:
Signl : process(t1) begin st1 : S1 <= t1; st2 : S2 <= not S1; end process; In VHDL, a statement can be labeled, and the label should be followed by a colon. In the above code, Signl, st1, and st2 are labels. Alternately, variable-assignment statements can be used instead of the above signal- assignment statement as follows: Varb : process(t1) variable temp1, temp2 : bit; -- This is a variable -- declaration statement begin st3 : temp1 := t1; -- This is a variable assignment -- statement st4 : temp2 := not temp1; -- This is a variable -- assignment statement st5 : S1 <= temp1; st6 : S2 <= temp2; end process;
VHDL Code for Behavioral Description of D-Latch Using Variable-Assignment Statements: entity DLTCH_var is port (d, E : in bit; Q, Qb : out bit); -- Since we are using type bit, no need for attaching a -- Library. If std_logic is used, IEEE library should be --attached end DLTCH_var; architecture DLCH_VAR of DLTCH_var is begin VAR : process (d, E) variable temp1, temp2 : bit; begin if E = ‘1’ then temp1 := d; -- This is a variable assignment statement. temp2 := not temp1; -- This is a variable assignment -- statement. end if; Qb <= temp2; -- Value of temp2 is passed to Qb Q <= temp1; -- Value of temp1 is passed to Q end process VAR; end DLCH_VAR; |
There are several statements associated with behavioral descriptions. These statements have to appear inside process in VHDL.
IF is a sequential statement that appears inside process in VHDL. It has several formats, some of which are as follows:
VHDL IF-Else Formats:
if (Boolean Expression) then statement 1; statement 2; statement 3; ....... else statement a; statement b; statement c; ....... end if; The execution of IF statement is controlled by the Boolean expression. If the Boolean expression is true, then statements 1, 2, and 3 are executed. If the expression is false, statements a, b, and c are executed. Boolean expression and execution of if: VHDL: if (clk = ‘1’) then temp := s1; else temp := s2; end if;
In above example if clk is high (1), the value of s1 is assigned to the variable temp. Otherwise, s2 is assigned to the variable temp. Execution of if as a latch VHDL if clk = ‘1’ then temp := s1; end if; If clk is high, the value of s1 is assigned to temp. If clk is not high, temp retains its current value, thus simulating a latch. Execution of if as else-if: VHDL: if (Boolean Expression1) then statement1; statement2;... elsif (Boolean expression2) then statement i; statement ii;... else statement a; statement b;... end if;
Implementing else-if: VHDL if signal1 =‘1’ then temp := s1; elsif signal2 = ‘1’ then temp := s2; else temp := s3; end if;
HDL Description of a 2x1 Multiplexer Using IF-Else: VHDL Description: library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity MUX_if is port (A, B, SEL, Gbar : in std_logic; Y : out std_logic); end MUX_if; architecture MUX_bh of MUX_if is begin process (A, B, SEL, Gbar) -- A, B, SEL, and Gbar are the sensitivity list of the process. variable temp : std_logic; -- Above statement is declaring temp as a variable; it -- will be calculated as if it is the output of the -- multiplexer. begin if Gbar = ‘0’ then if SEL = ‘1’ then temp := B; else temp := A; end if; --Now assign the variable temp to the output Y <= temp; else Y <= ‘Z’; end if; end process; end MUX_bh;
HDL Description of a 2x1 Multiplexer Using Else-IF: VHDL Description: library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity MUXBH is BEHAVIORAL DESCRIPTION • 95 port (A, B, SEL, Gbar : in std_logic; Y : out std_logic); end MUXBH; architecture MUX_bh of MUXBH is begin process (SEL, A, B, Gbar) variable temp : std_logic; begin if (Gbar = ‘0’) and (SEL = ‘1’) then temp := B; elsif (Gbar = ‘0’) and (SEL = ‘0’)then temp := A; else temp := ‘Z’; -- Z is high impedance. end if; Y <= temp; end process; end MUX_bh;
2. The case statement
The case statement is a sequential control statement. It has the following format:
VHDL Case Format:
case (control-expression) is when test value or expression1 => statements1; when test value or expression2 => statements2; when test value or expression3 => statements3; when others => statements4; end case;
If, for example, test value1 is true (i.e., it is equal to the value of the control expression), statements1 is executed. The case statement must include all possible conditions (values) of the control-expression. The statement when others can be used to guarantee that all conditions are covered.
The Case Statement
VHDL: case sel is when “00” => temp := I1; when “01” => temp := I2; when “10” => temp := I3; when others => temp := I4; end case;
In above Example, the control is sel. If sel = 00, then temp = I1, if sel = 01, then temp = I2, if sel = 10, then temp = I3, if sel = 11 (others or default), then temp = I4. All four test values have the same priority; it means that if sel = 10, for example, then the third (VHDL) statement (temp := I3) is executed directly without checking the first and second expressions (00 and 01).
Behavioral description of Positive Edge J K Flipflop using case: Edge-triggered flip-flops are sequential circuits. Flip-flops are triggered by the edge of the clock, in contrast to latches where the level of the clock (enable) is the trigger. Positive (negative) edge-triggered flip-flops sample the input only at the positive (negative) edges of the clock; any change in the input that does not occur at the edges is not sampled by the output.
State diagram
VHDL: library ieee; use ieee.std_logic_1164.all; entity JK_FF is port(JK : in bit_vector (1 downto 0); clk : in std_logic; q, qb : out bit); end JK_FF; architecture JK_BEH of JK_FF is begin P1 : process (clk) variable temp1, temp2 : bit; begin if rising_edge (clk) then case JK is when “01” => temp1 := ‘0’; when “10” => temp1 := ‘1’; when “00” => temp1 := temp1; when “11” => temp1 := not temp1; end case; q <= temp1; temp2 := not temp1; qb <= temp2; end if; end process P1; end JK_BEH;
Behavioral description of a three-bit binary Counter with active high synchronous clear: Counters are sequential circuits. For count-up counters (or simply up counters), the next state is the increment of the present state. For down-count counters (or simply down counters), the next state is the decrement of the present state.
VHDL Description library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity CT_CASE is port (clk, clr : in std_logic; q : buffer std_logic_vector (2 downto 0)); end CT_CASE; architecture ctr_case of CT_CASE is begin ctr : process(clk) variable temp : std_logic_vector (2 downto 0) := “101”; --101 is the initial value, so the counter starts from -- 110 begin if rising_edge (clk) then if clr = ‘0’ then case temp is when “000” => temp := “001”; when “001” => temp := “010”; when “010” => temp := “011”; when “011” => temp := “100”; when “100” => temp := “101”; when “101” => temp := “110”; when “110” => temp := “111”; when “111” => temp := “000”; when others => temp := “000”; end case; else temp := “000”; end if; end if; q <= temp; end process ctr; end ctr_case;
3. The wait-for statement:
The wait statement has several formats; in this section, only wait for a time period is discussed. For example:
VHDL: wait for 10 ns;
The wait statement can be implemented to generate clocks, as it is usually common in bench marks.
Implementation of the wait-for Statement to Generate Clocks
VHDL:
Library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity waittestVHDL is port ( a,b,c : out std_logic); end waittestVHDL; architecture Behavioral of waittestVHDL is begin p1 :process variable a1: std_logic := ‘0’; begin a <= a1; wait for 10 ns; a1 := not a1; end process; p2 :process variable b1: std_logic := ‘0’; begin b <= b1; wait for 20 ns; b1 := not b1; end process; p3 :process variable c1: std_logic := ‘0’; begin c <= c1; wait for 40 ns; c1 := not c1; end process; END;
4. The Loop Statement: Loop is a sequential statement that has to appear inside process in VHDL Loop is used to repeat the execution of statements written inside its body. The number of repetitions is controlled by the range of an index parameter. The loop allows the code to be compressed; instead of writing a block of code as individual statements, it can be written as one general statement that, if repeated, reproduces all statements in the block.
The HDL general format for a For-Loop is:
for <lower index value> <upper index value> <step> statements1; statement2; statement3; …. end loop
If the value of index is between lower and upper, all statements written inside the body of the loop are executed. For each cycle, the index is modified at the end loop according to the step. If the value of index is not between the lower and upper values, the loop is terminated.
VHDL For-Loop:
for i in 0 to 2 loop if temp(i) = ‘1’ then result := result + 2**i; end if; end loop; statement1; statement2; ....
The index is i, the lower value is 0, the upper value is 2, and the step is 1. All statements between the for statement and end loop are executed until the index i goes out of range. At the very beginning of the loop, i takes the value of 0
b. While-Loop:
The general format of the While-Loop is: while (condition) Statement1; Statement2; ………… end
As long as the condition is true, all statements written before the end of the loop are executed. Otherwise, the program exits the loop.
VHDL While-Loop:
while (i < x)loop i := i + 1; z := i z; end loop;
c. VHDL next and exit:
In VHDL, next and exit are two sequential statements associated with loop; exit causes the program to exit the loop, and next causes the program to jump to the end of the loop, skipping all statements written between next and end loop. The index is incremented, and if its value is still within the loop’s range, the loop is repeated. Otherwise, the program exits the loop. VHDL NEXT-EXIT: for i in 0 to 2 loop ...... ..... next When z = ’1’; statements1; end loop; statements2;
In the above example, at the very beginning of the loop’s execution, i takes the value 0; at the statement next When z = ’1’, the program checks the value of z. If z = 1, then statements1 is skipped and i is incremented to 1. The loop is then repeated with i = 1. If z is not equal to 1, then statements1 is executed, i is incremented to 1, and the loop is repeated.
HDL Code for a Four-Bit Counter with Synchronous Hold:
To write the code for the counter, binary-integer conversion is used
VHDL Description:
library ieee; use ieee.std_logic_1164.all; entity CNTR_Hold is port (clk, hold : in std_logic; q : buffer std_logic_vector (3 downto 0)); end CNTR_Hold; architecture CNTR_Hld of CNTR_Hold is begin ct : process (clk) variable temp : std_logic_vector (3 downto 0) := “0000”; -- temp is initialized to 0 so count starts at 0 variable result : integer := 0; begin if rising_edge (clk) then result := 0; -- change binary to integer lop1 : for i in 0 to 3 loop if temp(i) = ‘1’ then result := result + 2i; end if; end loop; -- increment result to describe a counter result := result + 1; -- change integer to binary lop2 : for i in 0 to 3 loop -- exit the loop if hold = 1 exit when hold = ‘1’; -- “when” is a predefined word if (result MOD 2 = 1) then temp (i) := ‘1’; else temp (i) := ‘0’; end if; --Successive division by 2 result := result/2; end loop; q <= temp; end if; end process ct; end CNTR_Hld;
HDL Code for Calculating the Factorial of Positive Integers:
VHDL Description
library IEEE; use IEEE.STD_LOGIC_1164.ALL; --The above library statements can be omitted; --however no error if it is not omitted. --The basic VHDL has type “natural.” entity factr is port(N : in natural; z : out natural); end factr; architecture factorl of factr is begin process (N) variable y, i : natural; begin y := 1; i := 0; while (i < N) loop i := i + 1; y := y i; end loop; z <= y; end process; end factorl;
|
References:
- HDL Programming (VHDL and Verilog)- Nazeih M.Botros- John Weily India Pvt. Ltd. 2008.
- Fundamentals of HDL – Cyril P.R. Pearson/Sanguin 2010.
- VHDL -Douglas perry-Tata McGraw-Hill
- A Verilog HDL Primer- J.Bhaskar – BS Publications
- Circuit Design with VHDL-Volnei A.Pedroni-PHI