CSCI 660 EEGN-CSCI 660 Introduction to VLSI Design Lecture 3 Khurram Kazi Some of the slides were taken from K Gaj ’ s lecture slides from GMU ’ s VHDL course webpage
CSCI Anatomy of a Process [label:] process [(sensitivity list)] [VARIABLE name type [range] [:= initial_value;]] begin (sequential code) end process [label]; OPTIONAL
CSCI Process: Statement Part Contains Sequential Statements to be Executed Each Time the Process Is Activated Typically a process is activated by any activity on the signals listed in the sensitivity list Condition related to WAIT is fulfilled
CSCI A process can be given a unique name using an optional LABEL This is followed by the keyword PROCESS The keyword BEGIN is used to indicate the start of the process All statements within the process are executed SEQUENTIALLY. Hence, order of statements is important. A process must end with the keywords END PROCESS. TESTING: process begin TEST_VECTOR<=“00”; wait for 10 ns; TEST_VECTOR<=“01”; wait for 10 ns; TEST_VECTOR<=“10”; wait for 10 ns; TEST_VECTOR<=“11”; wait for 10 ns; end process; A process is a sequence of instructions referred to as sequential statements. What is a PROCESS? The Keyword PROCESS
CSCI Behavioral VHDL (subset) sequential signal assignment ( ) if-then-else statement wait until wait for Major instructions Selected sequential statements
CSCI PROCESS with a SENSITIVITY LIST List of signals to which the process is sensitive. Whenever there is an event on any of the signals in the sensitivity list, the process fires. Every time the process fires, it will run in its entirety. WAIT statements are NOT ALLOWED in a processes with SENSITIVITY LIST. label: process ( sensitivity list ) declaration part begin statement part end process;
CSCI Processes in VHDL Processes Describe Sequential Behavior Processes in VHDL Are Very Powerful Statements Allow to define an arbitrary behavior that may be difficult to represent by a real circuit Not every process can be synthesized Use Processes with Caution in the Code to Be Synthesized Use Processes Freely in Testbenches
CSCI Component Equivalent of a Process All signals which appear on the left of signal assignment statement (<=) are outputs e.g. y, z All signals which appear on the right of signal assignment statement (<=) or in logic expressions are inputs e.g. w, a, b, c All signals which appear in the sensitivity list are inputs e.g. clk Note that not all inputs need to be included in the sensitivity list priority: PROCESS (clk) BEGIN IF w(3) = '1' THEN y <= "11" ; ELSIF w(2) = '1' THEN y <= "10" ; ELSIF w(1) = c THEN y <= a and b; ELSE z <= "00" ; END IF ; END PROCESS ; w a y z priority b c clk
CSCI Registers
CSCI ClockD – Truth table Graphical symbol t 1 t 2 t 3 t 4 Time Clock D Q Timing diagram Q(t+1) Q(t) D latch D Q Clock
CSCI Clk D Truth table t 1 t 2 t 3 t 4 Time Clock D Q Timing diagram Q(t+1) Q(t) D flip-flop D Q Clock Graphical symbol 0 – Q(t) 1 –
CSCI LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY latch IS PORT ( D, Clock : IN STD_LOGIC ; Q : OUT STD_LOGIC) ; END latch ; ARCHITECTURE Behavior OF latch IS BEGIN PROCESS ( D, Clock ) BEGIN IF Clock = '1' THEN Q <= D ; END IF ; END PROCESS ; END Behavior; D latch D Q Clock
CSCI LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY flipflop IS PORT ( D, Clock: INSTD_LOGIC ; Q: OUTSTD_LOGIC) ; END flipflop ; ARCHITECTURE Behavior_1 OF flipflop IS BEGIN PROCESS ( Clock ) BEGIN IF Clock'EVENT AND Clock = '1' THEN Q <= D ; END IF ; END PROCESS ; END Behavior_1 ; D flip-flop D Q Clock
CSCI LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY flipflop IS PORT ( D, Clock: INSTD_LOGIC ; Q: OUTSTD_LOGIC) ; END flipflop ; ARCHITECTURE Behavior_2 OF flipflop IS BEGIN PROCESS BEGIN WAIT UNTIL Clock'EVENT AND Clock = '1' ; Q <= D ; END PROCESS ; END Behavior_2 ; D flip-flop D Q Clock
CSCI LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY flipflop IS PORT ( D, Resetn, Clock : IN STD_LOGIC ; Q : OUT STD_LOGIC) ; END flipflop ; ARCHITECTURE Behavior OF flipflop IS BEGIN PROCESS ( Resetn, Clock ) BEGIN IF Resetn = '0' THEN Q <= '0' ; ELSIF Clock'EVENT AND Clock = '1' THEN Q <= D ; END IF ; END PROCESS ; END Behavior ; D flip-flop with asynchronous reset D Q Clock Resetn
CSCI LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY flipflop IS PORT ( D, Resetn, Clock : IN STD_LOGIC ; Q : OUT STD_LOGIC) ; END flipflop ; ARCHITECTURE Behavior OF flipflop IS BEGIN PROCESS BEGIN WAIT UNTIL Clock'EVENT AND Clock = '1' ; IF Resetn = '0' THEN Q <= '0' ; ELSE Q <= D ; END IF ; END PROCESS ; END Behavior ; D flip-flop with synchronous reset D Q Clock Resetn
CSCI bit register with asynchronous reset LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY reg8 IS PORT ( D: IN STD_LOGIC_VECTOR(7 DOWNTO 0) ; Resetn, Clock: IN STD_LOGIC ; Q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ) ; END reg8 ; ARCHITECTURE Behavior OF reg8 IS BEGIN PROCESS ( Resetn, Clock ) BEGIN IF Resetn = '0' THEN Q <= " " ; ELSIF Clock'EVENT AND Clock = '1' THEN Q <= D ; END IF ; END PROCESS ; END Behavior ;` Resetn Clock reg8 88 DQ
CSCI N-bit register with asynchronous reset LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY regn IS GENERIC ( N : INTEGER := 16 ) ; PORT ( D: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0) ; Resetn, Clock: IN STD_LOGIC ; Q: OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0) ) ; END regn ; ARCHITECTURE Behavior OF regn IS BEGIN PROCESS ( Resetn, Clock ) BEGIN IF Resetn = '0' THEN Q '0') ; ELSIF Clock'EVENT AND Clock = '1' THEN Q <= D ; END IF ; END PROCESS ; END Behavior ; Resetn Clock regn NN DQ
CSCI LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY regn IS GENERIC ( N : INTEGER := 8 ) ; PORT (D : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0) ; Enable, Clock: IN STD_LOGIC ; Q : OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0) ) ; END regn ; ARCHITECTURE Behavior OF regn IS BEGIN PROCESS (Clock) BEGIN IF (Clock'EVENT AND Clock = '1' ) THEN IF Enable = '1' THEN Q <= D ; END IF ; END PROCESS ; END Behavior ; N-bit register with enable Q D Enable Clock regn NN
CSCI LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all ; ENTITY upcount IS PORT ( Clock, Resetn, Enable : IN STD_LOGIC ; Q: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)) ; END upcount ; 8-bit up-counter with asynchronous reset (1) Q Enable Clock upcount 8 Resetn
CSCI ARCHITECTURE Behavior OF upcount IS SIGNAL Count : integer ; BEGIN PROCESS ( Clock, Resetn ) BEGIN IF Resetn = '0' THEN Count <= 0 ; ELSIF (Clock'EVENT AND Clock = '1') THEN IF Enable = '1' THEN Count <= Count + 1 ; END IF ; END PROCESS ; Q <= conv_std_logic_vector (Count, 8) ; END Behavior ; 8-bit up-counter with asynchronous reset (2) Q Enable Clock upcount 4 Resetn
CSCI If Statement
CSCI Sequential Statements (1) If Statement else and elsif are optional if boolean expression then statements elsif boolean expression then statements else boolean expression then statements end if;
CSCI SELECTOR: process begin WAIT UNTIL Clock'EVENT AND Clock = '1' ; IF Sel = “00” THEN f <= x1; ELSIF Sel = “10” THEN f <= x2; ELSE f <= x3; END IF; end process; If Statement - Example
CSCI Shift Registers
CSCI Shift register DQ Sin Clock DQDQDQ Q(3) Q(2) Q(1)Q(0) Enable
CSCI Shift Register With Parallel Load D(3) DQ Clock Enable Sin D(2) DQ D(1) DQ D(0) DQ Q(0)Q(1)Q(2)Q(3) Load
CSCI LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY shift4 IS PORT ( D : IN STD_LOGIC_VECTOR(3 DOWNTO 0) ; Enable: IN STD_LOGIC ; Load: IN STD_LOGIC ; Sin : IN STD_LOGIC ; Clock : IN STD_LOGIC ; Q : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0) ) ; END shift4 ; 4-bit shift register with parallel load (1) Q Enable Clock shift4 4 D Load Sin 4
CSCI ARCHITECTURE Behavior_1 OF shift4 IS BEGIN PROCESS (Clock) BEGIN IF Clock'EVENT AND Clock = '1' THEN IF Load = '1' THEN Q <= D ; ELSIF Enable = ‘1’ THEN Q(0) <= Q(1) ; Q(1) <= Q(2); Q(2) <= Q(3) ; Q(3) <= Sin; END IF ; END PROCESS ; END Behavior_1 ; 4-bit shift register with parallel load (2) Q Enable Clock shift4 4 D Load Sin 4 Another way of writing the code Q(2 downto 0) <= Q(3 downto 1) Q(3) <= Sin;
CSCI LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY shiftn IS GENERIC ( N : INTEGER := 8 ) ; PORT (D : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0) ; Enable: IN STD_LOGIC ; Load: IN STD_LOGIC ; Sin : IN STD_LOGIC ; Clock : IN STD_LOGIC ; Q : BUFFER STD_LOGIC_VECTOR(N-1 DOWNTO 0) ) ; END shiftn ; N-bit shift register with parallel load (1) Q Enable Clock shiftn N D Load Sin N VHDL allows this, but not recommended when writing code for synthesis
CSCI ARCHITECTURE Behavior OF shiftn IS BEGIN PROCESS (Clock) BEGIN IF (Clock'EVENT AND Clock = '1' ) THEN IF Load = '1' THEN Q <= D ; ELSIF Enable = ‘1’ THEN Genbits: FOR i IN 0 TO N-2 LOOP Q(i) <= Q(i+1) ; END LOOP ; Q(N-1) <= Sin ; END IF; END PROCESS ; END Behavior ; N-bit shift register with parallel load (2) Q Enable Clock shiftn N D Load Sin N Keep in mind this shift register DOES NOT have reset.
CSCI bit Shift Register (1) library ieee; use ieee.std_logic_1164.all; ENTITY shiftreg is generic(N : integer := 4); port(clk: in STD_LOGIC; sin: in STD_LOGIC; enable: in STD_LOGIC; SOUT : out std_logic); end shiftreg; architecture ssr of shiftreg is begin p0: process (clk, enable) variable REG : std_logic_vector(N-1 downto 0); begin if (ENABLE = '0') then SOUT <= '0'; REG := (others => '0'); elsif rising_edge(CLK) then REG := REG(N-2 downto 0) & SIN; SOUT <= REG(N-1); end if; end process p0; end ssr;
CSCI LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all ; ENTITY upcount IS PORT (Clock,:IN STD_LOGIC; Resetn: IN STD_LOGIC; Enable : IN STD_LOGIC ; Q: OUT STD_LOGIC_VECTOR (7 DOWNTO 0); Decode_7: OUT STD_LOGIC ) ; END upcount ; ARCHITECTURE Behavior OF upcount IS SIGNAL Count : integer ; BEGIN PROCESS ( Clock, Resetn ) BEGIN IF Resetn = '0' THEN Count <= 0 ; ELSIF (Clock'EVENT AND Clock = '1') THEN IF Enable = '1' THEN Count <= Count + 1 ; END IF; END PROCESS ; Q <= conv_std_logic_vector (Count, 8) ; 8-bit up-counter with some decoded outputs RawDecode: Process (count) Begin IF (count = 7) then Decode_7 <= ‘1’; ELSE Decode_7 <= ‘0’; END IF; END Process; END Behavior ; ClockedDecode: Process (clk) Begin if (clock’event and clock = ‘1’) then IF (count = 7) then Decode_7 <= ‘1’; ELSE Decode_7 <= ‘0’; END IF; end if; END Process; What is the difference between the 2 processes?
CSCI Arrays Arrays are collection of objects of the same type. They can be one-dimensional (1D), two-dimensional (2D), or one-dimensional- by-one-dimensional (1Dx1D) Scalar1D1D x 1D D data arays
CSCI Arrays Scalars: BIT, STD_LOGIC, STD_ULOGIC and BOOLEAN Vectors: BIT_VECTOR, STD_LOGIC_VECTOR, STD_ULOGIC_VECTOR, INTEGER, SIGNED, and UNSIGNED There are no pre-defined 2D or 1D x 1D arrays Hence need to be specified by the user To do so, a TYPE must be first defined, then the new SIGNAL, VARIABLE or CONSTANT can be declared using that data type.
CSCI Arrays: Syntax of defining an array To specify a new array type: TYPE type_name IS ARRAY (specificaiton) of data_type; To make use of the new array type: SIGNAL signal_name: type_name [:= initial value]; Example: TYPE row IS ARRAY (7 downto 0) OF STD_LOGIC; -- 1D array TYPE matrix IS ARRAY (0 to 3) of row; -- 1Dx1D array SIGNAL x: matrix -- 1Dx1D signal
CSCI Arrays: Syntax of defining an array Another way of constructing the 1Dx1D array TYPE matrix IS ARRAY (0 to 4) of STD_LOGIC_VECTOR (7 DOWNTO 0) Example: 2D array The array below is truly two-dimensional. Notice that its construction is not based on vectors, but rather entirely on scalars TYPE matrix2D IS ARRAY (0 TO 3, 7 DOWNTO 0) of STD_LOGIC; --2D array
CSCI ROM (Read Only Memory) LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY rom is GENERIC ( bits: INTEGER := 8 -- # of bits per word words: INTEGER := 8 ); -- # of words in the memory PORT ( addr : IN INTEGER RANGE 0 to words - 1; data : OUT STD_LOGIC_VECTOR (bits-1 DOWNTO 0)); END rom; ARCHITECTURE rom of rom IS TYPE vector_array is ARRAY (0 to words -1) of STD_LOGIC_VECTOR (bits-1 DOWNTO 0); CONSTANT memory: vector_array := ( " ", " ", " ", " ", " ", " ", " ", " ", " ",); BEGIN data <= memory(addr); END rom;
CSCI RAM (Random Access Memory) LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY ram is GENERIC ( bits: INTEGER := 8 -- # of bits per word words: INTEGER := 8 ); -- # of words in the memory PORT ( wr_ena: IN STD_LOGIC; -- write enable clk: IN STD_LOGIC; -- clock addr: IN INTEGER RANGE 0 to words -1; data_in:: IN STD_LOGIC_VECTOR (bits - 1 DOWNTO 0); data_out : OUT STD_LOGIC_VECTOR (bits -1 DOWNTO 0)); END ram ARCHITECTURE ram of ram IS TYPE vector_array is ARRAY (0 to words -1) of STD_LOGIC_VECTOR (bits-1 DOWNTO 0); signal memory: vector_array; BEGIN PROCESS (clk, wr_ena) BEGIN IF (clk'EVENT AND clk = '1') THEN IF (wr_ena = '1') THEN memory(addr) <= data_in; END IF; END PROCESS; data_out <= memory(addr); END ram;
CSCI CASE: conditional statements CASE is another statement intended exclusively for sequential code (along with IF, LOOP, and WAIT) CASE identifier IS WHEN value => assignments; …….. END CASE; CASE control IS WHEN “00” => x <= a; y <= b; WHEN “01” => x <= b; y <= a; WHEN OTHERS => x <= “0000”; y <= “zzzz”; END CASE;
CSCI RANGE RANGE <> is used to indicate that the range is unconstrainded INTEGER range is to NATURAL RANGE <>, on the other hand, indicates that the only restriction is that the range must fall within the NATRUAL RANGE Natural range is 0 to
CSCI CASE: Two-digit Counter with Seven Segment Display
CSCI CASE: Two-digit Counter with Seven Segment Display LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY counter IS PORT (clk, reset: std_logic; digit1, digit1 : OUT STD_LOGIC_VECTOR (6 DOWNTO 0)); END counter; ARCHITECTURE counter of counter IS BEGIN PROCESS (clk, reset) VARIABLE temp1: INTEGER RANGE 0 TO 10; VARIABLE temp2: INTEGER RANGE 0 TO 10; Begin IF (reset = '1') THEN temp1 := 0; temp2 := 0; ELSIF (clk'event and clk = '1') THEN temp1 := temp1 + 1; IF (temp1 = 10) THEN temp1 := 0; temp2 := temp2 + 1; IF (temp2 := 10) THEN temp2 := 0; END IF; CASE temp1 IS WHEN 0 => digit1 <= " ";--7E WHEN 1 => digit1 <= " ";--30 WHEN 2 => digit1 <= " ";--6D WHEN 3 => digit1 <= " ";--79 WHEN 4 => digit1 <= " ";--33 WHEN 5 => digit1 <= " ";--5B WHEN 6 => digit1 <= " ";--5F WHEN 7 => digit1 <= " ";--70 WHEN 8 => digit1 <= " ";--7F WHEN 9 => digit1 <= " B WHEN OTHERS => NULL; END CASE; CASE temp2 IS WHEN 0 => digit2 <= " ";--7E WHEN 1 => digit2 <= " ";--30 WHEN 2 => digit2 <= " ";--6D WHEN 3 => digit2 <= " ";--79 WHEN 4 => digit2 <= " ";--33 WHEN 5 => digit2 <= " ";--5B WHEN 6 => digit2 <= " ";--5F WHEN 7 => digit2 <= " ";--70 WHEN 8 => digit2 <= " ";--7F WHEN 9 => digit2 <= " B WHEN OTHERS => NULL; END CASE; END PROCESS; END COUNTER;
CSCI As the name says, LOOP is useful when a piece of code must be instantiated several times. There are several ways of using LOOP FOR/LOOP: The loop is repeated for a fixed number of times [label:] FOR identifier IN range LOOP (sequential statements) END LOOP [label]; FOR i IN 0 TO 5 LOOP x(i) <= enable AND w(i+2); y(i) <= w(i); END LOOP MyLoop; In the code the loop will be repeated unconditionally until it reaches 5 (i.e. six times) LOOP
CSCI WHILE/LOOP: The loop is repeated until a condition no longer holds [label:] WHILE condition LOOP (sequential statements) END LOOP [label]; WHILE (I < 10) LOOP WAIT UNTIL clk’EVENT and clk = ‘1’; (other statements) END LOOP; In the code the loop will be repeated as long as i < 10 condition holds. LOOP
CSCI EXIT: Used for ending the loop [label:] EXIT [label] [WHEN condition]; FOR i IN data’RANGE LOOP CASE data(i) IS WHEN ‘0’ => count := count + 1; WHEN OTHERS => EXIT; END CASE; END LOOP; LOOP
CSCI NEXT: Used for skipping loop steps [label:] NEXT [label] [WHEN condition]; FOR I IN 0 TO 15 LOOP NEXT WHEN i = 10; (……..) END LOOP; In this example, NEXT causes LOOP to skip one iteration when i = 10 LOOP
CSCI The design counts the number of leading 0s in a binary vector, starting from the left end. This solutions shows the usage of LOOP/EXIT. In this example, the loop will end as soon as a ‘1’ is found in the data vector. Therefore, it is appropriate for counting the number of zeros that precede the first one. LOOP: Example: Leading Zeros
CSCI LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY LeadignZeros IS PORT (data: IN STD_LOGIC_VECTOR (7 DOWNTO 0); zeros : OUT INTEGER RANGE 0 TO 8 ); END LeadingZeros; ARCHITECTURE behavior of LeadingZeros IS BEGIN PROCESS (data VARIABLE count: INTEGER RANGE 0 TO 8; BEGIN count := 0; FOR i IN data'RANGE LOOP CASE data(i) IS WHEN '0' => count := count + 1; WHEN others => EXIT; END CASE; END LOOP; zeros <= count; END PROCESS; END behavior; Simulation results should be: With data = “ ” (decimal 0), 8 zeros are detected; when data = “ ”, seven zeros are encountered LOOP: Example: Leading Zeros
CSCI VHDL Assertion Statement assert boolean-expression report string-expression severity severity-level; If the boolean-expression is false, then the string-expression is displayed on the monitor along with the severity level. Severity-level can be note, warning, error, failure. Action taken depends on the simulator. Example - suppose VHDL model is supposed to generate data with even parity with ack_test: wait until ack_test = '1'; parity := test_data(3) XOR test_data(2) XOR test_data(1) XOR test_data(0); assert parity = '0' report "Parity Error" severity error; Example 2: assert (error_flag = '1') report "There was an error; simulation has halted." severity FAILURE;