VHDL - INTRODUCTION 1. 2. 3. 4. 5. 6. 7. 8. VHDL is not case sensitive Identifier must start with a letter All statements end with a semi-colon Comments precede with (--) “<= “ - signal assignment “:=“ - variable assignment Variables are like C- type variables. Signals have a one time value set associated to it at any time. IF – THEN - ELSE General syntax is: if (condition_1) then begin … statements_1 … end; elsif (condition_2) then begin … statements_2 … end; else begin …statements _i …end; end if; STRUCTURAL MODELING 1. Consider an example of a Dual 2 by 1 multiplexer using structural modeling. 2. Components required : 2- input AND gate 2- input OR gate Inverter ENTITY OF THE INVERTER ENTITY inv IS PORT( i1: IN BIT; o1: OUT BIT ); END inv; ARCHITECTURE OF THE INVERTER ARCHITECTURE single_delay OF inv IS BEGIN o1 <= not (i1) after 5ns; END single_delay; DESIGN OF A SIMPLE 2 INPUT AND GATE WITH A DELAY ENTITY and2 IS PORT( i1, i2 :IN BIT; o1: OUT BIT); END and2; ARCHITECTURE single_delay OF and2 IS BEGIN o1 <= (i1 AND i2) after 8ns; END single_delay; DESIGN OF A SIMPLE 2 INPUT OR GATE WITH A DELAY ENTITY or2 IS PORT( i1, i2 :IN BIT; o1: OUT BIT); END or2; ARCHITECTURE single_delay OF or2 IS BEGIN o1 <= (i1 or i2) after 8ns; END single_delay; SINGLE AND DUAL 2-1 MULTIPLEXER ENTITY ENTITY single_mux IS PORT( s: IN BIT ; --select input iA, iB : INT BIT; -- iA is selected if --s=‘0’ and iB is selected if s= ‘1’ oZ: OUT BIT –output of the mux ); END single_mux; SINGLE AND DUAL 2-1 MULTIPLEXER ARCHITECTURE ARCHITECTURE gate_level OF single_mux IS COMPONENT c1 PORT ( i1 :IN BIT; o1: OUT BIT); END COMPONENT; COMPONENT c2 PORT ( i1, i2 :IN BIT; o1: OUT BIT); END COMPONENT; SINGLE AND DUAL 2-1 MULTIPLEXER ARCHITECTURE COMPONENT c3 PORT ( i1, i2 :IN BIT; o1: OUT BIT); END COMPONENT; FOR ALL: c1 USE ENTITY WORK.inv(single_delay); FOR ALL: c2 USE ENTITY WORK.and2(single_delay); FOR ALL: c3 USE ENTITY WORK.or2(single_delay); SIGNAL im1, im2, im3: BIT; SINGLE AND DUAL 2-1 MULTIPLEXER ARCHITECTURE BEGIN g0: c1 PORT MAP (s, im1); g1: c2 PORT MAP (iA, im1, im2); g2: c2 PORT MAP (iB, s, im3); g3: c3 PORT MAP (im2, im3, oZ); END gate_level; DUAL 2-1 MULTIPLEXER ENTITY ENTITY dual_mux IS PORT( s: IN BIT ; --select input iA, iB : IN BIT _VECTOR(1 DOWNTO 0); -- iA is selected if -s=‘0’ and iB is selected if s= ‘1’ outZ: OUT BIT _VECTOR(1 DOWNTO 0)--output of the mux ); END dual_mux; DUAL 2-1 MULTIPLEXER ARCHITECTURE ARCHITECTURE element_level OF dual_mux IS --we use only one component (the single 2:1 mux) COMPONENT c1 PORT (s, iA, iB: IN BIT; oZ : OUT BIT); END COMPONENT; FOR ALL : c1 USE ENTITY WORK. single_mux (gate_level); BEGIN g0 : c1 PORT MAP(sel, inA(0), inB(0), outZ(0)); --the 1st 2:1 mux is --wired. g1 : c1 PORT MAP(sel, inA(1), inB(1), outZ(1)); --the 2nd 2:! Mux is --wired END element_level; BEHAVIORAL MODLEING 1. Show examples of a dual 2:1 multiplexer designed using behavioral models. 2. Initially components built are: 2- input AND gate 2- OR gate Inverter DIFFERENT METHODS OF BEHAVIORAL MODELING 1. 2. 3. 4. 5. WHEN …ELSE statements BOOLEAN operators PROCESSES WITH … SELECT CASE statements WHEN – ELSE STATEMENT ENTITY dual_mux IS PORT( sel: IN BIT ; --select input iA, iB : INT BIT_VECTOR( 1 DOWN TO 0); -- iA is selected if --s=‘0’ and iB is selected if s= ‘1’ oZ: OUT BIT _VECTOR(1 DOWNTO 0)--output of the mux ); END dual_mux; ARCHITECTURE behaioral_when_else OF dual_mux IS BEGIN outZ <= inA WHEN(sel = ‘0’) ELSE inB; END behavioral_when_else; BOOLEAN OPERATORS ARCHITECTURE behavioral_boolean OF dual_mux IS SIGNAL temp: BIT_VECTOR(1 downto 0); BEGIN temp <= (sel, sel); --we assign sel to all the bits of the bus temp outZ <= ((NOT) temp AND inA) OR (temp AND inB); END behavioral_boolean; PROCESS 1. A process is a block that contains only sequential statements. 2. Every process has a sensitivity list. 3. The signals in the sensitivity list determine when the sequential statements within the process will be executed. PROCESS ARCHITECTURE behavioral_process OF dual_mux IS BEGIN p1: PROCESS(sel, inA, inB) is BEGIN outZ <= inB; if(sel = ‘0’) then outZ <= inA; End if; END process p1; END behavioral_process; WITH ..SELECT STATEMENT ARCHITECTURE behavioral_sel OF dual_mux IS BEGIN WITH sel SELECT outZ <= inA after 10 ns when ‘0’, inB after 10 ns when others; END behavioral_sel; CASE STATEMENT ARCHITECTURE behavioral_sel OF dual_mux IS BEGIN P1: PROCESS (sel, inA, inB) is BEGIN CASE sel is when ‘0’ => outZ <= inA after 10 ns; when others => outZ <= in B after 10 ns; END CASE; End process; END behavioral_case; TEST BENCHES 1. A VHDL block to test a design. 2. Example of a dual 2:1 multiplexer. TEST BENCH USE WORK. ALL; ENTITY dual_mux_test IS END dual_mux_test; We do not need any interfacing since we only want to use the test-bench with the simulator. TEST BENCH ARCHITECTURE io_test OF dual_mux_test IS COMPONENT c1 PORT( sel: IN BIT; inA, inB : IN BIT_VECTOR(1 downto 0); outZ: OUT BIT_VECTOR(1 downto 0); END COMPONENT; SIGNAL sel_test: BIT; SIGNAL inA_test, inB_test : BIT_VECTOR(1 downto 0); SIGNAL outZ_test : BIT_VECTOR(1 downto 0); TEST BENCH BEGIN g0: c1 PORT MAP (sel_test, inA_test,inB_test, outZ_test); t1: inA_test <= “00”, “01” after 50 ns, “10” after 150 ns, “11” after 250 ns, “00” after 350 ns, “01” after 450 ns, “10” after 550 ns, “11” after 650 ns; t2: inB_test <= “00”, “01” after 100 ns, “10” after 200 ns, “11” after 300 ns, “00” after 400 ns, “01” after 500 ns, “10” after 600 ns, “11” after 700 ns, t3:sel_test <= ‘0’, ‘1’ after 325 ns; END io_test; GENERIC CLAUSE GENERIC allows us to communicate nonhardware and non-signal information between designs, and hence between levels of hierarchy. In the example discussed later, a delay is assigned a default value of 5ns but the delay can be changed when the component is used. GENERIC CLAUSE ENTITY decoder IS GENERIC ( delay: TIME := 5ns ); PORT ( sel: IN BIT_VECTOR(2 downto 0); outZ: OUT BIT_VECTOR(7 downto 0); ); END decoder; ARCHITECTURE single_delay OF decoder IS BEGIN WITH sel SELECT outZ <= “00000001” after delay WHEN “000”, “00000010” after delay WHEN “001”, “00000100” after delay WHEN “010”, “00001000” after delay WHEN “011”, “00010000” after delay WHEN “100”, “00100000” after delay WHEN “101”, “01000000” after delay WHEN “110”, “10000000” after delay WHEN “111”, END single_delay; GENERIC CLAUSE ENTITY decoder_test IS END decoder_test; ARCHITECTURE io_test OF decoder_test IS COMPONENT c1 GENERIC (delay: TIME); PORT( sel: IN BIT_VECTOR(2 downto 0); outZ: OUT BIT_VECTOR( 7 downto 0)); END COMPONENT; FOR g0: c1 USE ENTITY WORK. Decoder(single_delay); SIGNAL sel_test : BIT_VECTOR(2 downto 0); SIGNAL outZ_test : BIT_VECTOR(7 downto 0 ); BEGIN g0 : c1 GENERIC MAP(17ns) PORT MAP(sel_test, outZ_test); t1 : sel_test <= “000” “001” after 50 ns, “010” after 100 ns, “011” after 150 ns, “100” after 200 ns, “101” after 250 ns, “110” after 300 ns, “111” after 350 ns, “000” after 400 ns; END io_test; MEALY FINITE STATE MACHINE(ASYNCHRONOUSLY) MEALY FINITE STATE MACHINE(ASYNCHRONOUSLY) ENTITY asynchr_state_mach IS PORT ( reset : IN BIT; clk : IN BIT; xin : IN BIT; zout : OUT BIT; stateout : OUT BIT_VECTOR(1 downto 0)); END asynchr_state_mach; ARCHITECTURE behavioral OF asynchr_state_mach IS TYPE state IS (state0, state1, state2, state3); SIGNAL current_state, next_state : state := state0; BEGIN Cominat_proc : PROCESS (current_state, xin) BEGIN CASE current_state IS MEALY FIFNITE STATE MACHINE(ASYNCHRONOUSLY) when state0 => stateout <= “00”; if (xin = ‘0’) then next_state <= state1; zout <= ‘1’; else next_state <= state0; zout <= ‘0’; end if; when state1 => stateout <= “01”; If ( xin = ‘0’) then next_state <= state1; zout <= ‘0’; else next_state <= state0; zout <= ‘0’; end if; When state2 => stateout <= “10”; if (xin =‘0’) then next_state <= state3; zout <= ‘1’; else next_state <= state0; zout <= ‘0’; end if; MEALY FIFNITE STATE MACHINE(ASYNCHRONOUSLY) When state3 => stateout <= “11”; if (xin = ‘0’) then next_state <= state0; zout <= ‘1’; else next_state <= state3; zout <= ‘1’; end if; end case; end process combat_proc; clk_proc : process begin wait until (clk’event and clk =‘1’); if (reset = ‘1’) then current_state <= state0; else current_state <= next_state; end if; end process clk_proc; End behavioral; MEALY FINITE STATE MACHINE(ASYNCHRONOUSLY) ENTITY USE WORK.ALL; ENTITY asynchr_state_test IS END asynchr_state_test; ARCHITECTURE io_test OF synchr_state_test IS BEGIN COMPONENT c1 PORT ( reset : IN BIT; clk : IN BIT; xin : IN BIT; Zout: IN BIT; stateout: OUT BIT_VECTOR(1 downto 0); END COMPONENT; MEALY FIFNITE STATE MACHINE(ASYNCHRONOUSLY) FOR g0 : c1 USE ENTITY WORK. asynchr_state_mach(behavioral); --we have to declare I/O signals that are used in --the test SIGNAL reset_test : BIT:=‘0’; SIGNAL clk_test : BIT:= ‘0’; SIGNAL xin_test : BIT := ‘0’; SIGNAL zout_test : BIT; SIGNAL state_out_test: BIT_VECTOR( 1 downto 0); BEGIN clock_process : PROCESS is BEGIN clk_test <= NOT(clk_test); wait for 20 ns; END PROCESS; g0 : c1 PORT MAP (reset_test, clk_test, xin_test, zout_test, stateout_test) ; --apply a rest after 30 ns to go to state 0; t1: reset_test <= ‘0’ ‘1’ after 30ns, ‘0’ after 70 ns; MEALY FIFNITE STATE MACHINE(ASYNCHRONOUSLY) t2 : xin_test <= ‘0’, ‘1’ after 50ns, --stay in state0 ‘0’ after 90ns, --goto state1 ‘1’ after 130ns, --stay in state1 ‘0’ after 170ns, --goto state2 ‘1’ after 210ns, --goto state3 ‘0’ after 250ns, -stay in state3 ‘1’ after 290ns, --goto state0 ‘0’ after 330ns, --stay in state0 ‘1’ after 370ns, --goto state1 ‘0’ after 410ns, --goto state2 ‘1’ after 450ns, --goto state3 ‘0’ after 490ns; -- stay in state0 END io_test; MOORE FINITE STATE MACHINE MOORE FINITE STATE MACHINE ENTITY synchr_state_mach IS PORT( reset : IN BIT; clk: IN BIT; xin : IN BIT; zout : OUT BIT_VECTOR( 3 downto 0) ); END synchr_state_mach; MOORE FINITE STATE MACHINE ARCHITECTURE behavioral OF synchr_state_mach IS TYPE state IS (state0, state1, state2, state3); SIGNAL current_state, next_state : state := state0; BEGIN combat_proc :PROCESS(current_state, xin) IS BEGIN case current_state is when state0 => zout <= “0001”; if ( xin = ‘0’) then next_state <= state1; else next_state <= state0; end if; MOORE FINITE STATE MACHINE when state1 => zout <= “0010”; if ( xin = ‘0’) then next_state <= state1; else next_state <= state2; end if; when state2 => zout <= “0100”; if ( xin = ‘0’) then next_state <= state3; else next_state <= state0; end if; when state3 => zout <= “1000”; if ( xin = ‘0’) then next_state <= state0; else next_state <= state3; end if; END CASE; END PROCESS combinat_proc; MOORE FINITE STATE MACHINE Clk_proc : process(reset, clk) is Begin if (reset = ‘1’) then current_state <= state0; elsif (clk’event and clk = ‘1’) then current_state <= next_state; end if; End process clk_proc; End behavioral; MOORE FINITE STATE MACHINE USE WORK.ALL; ENTITY synchr_state_mach_test IS END synchr_state_mach_test; ARCHITECTURE io_test OF synchr_state_mach_test IS COMPONENT c1 PORT ( reset : IN BIT; clk : IN BIT; xin : IN BIT; Zout: IN BIT); END COMPONENT; MOORE FINITE STATE MACHINE FOR g0 : c1 USE ENTITY WORK. asynchr_state_mach(behavioral); --we have to declare I/O signals that are used in --the test SIGNAL reset_test : BIT:=‘0’; SIGNAL clk_test : BIT:= ‘0’; SIGNAL xin_test : BIT := ‘0’; SIGNAL zout_test : BIT_VECTOR( 3 downto 0); CONSTANT half_clk_period : TIME := 20ns; CONSTANT clk_period : TIME := 40 ns; BEGIN clock_process : PROCESS BEGIN clk_test <= NOT( clk_test); wait for half_clk_period; END PROCESS clock_process; g0: c1 PORT MAP (reset_test, clk_test, xin_test, zout_test); t1: reset_test <= ‘0’, ‘1’ after (clk_period *0.75), ‘0’ after (clk_period *1.75); MOORE FINITE STATE MACHINE t2 : xin_test <= ‘0’, --start in state0 ‘1’ after (clk_period *1.25), --stay in state0 ‘0’ after (clk_period *2.25), --goto state1 ‘0’ after (clk_period *3.25), --stay in state1 ‘1’ after (clk_period *4.25), --goto state2 ‘0’ after (clk_period *5.25), -- goto state3 ‘1’ after (clk_period *6.25), --stay in state3 ‘0’ after (clk_period *7.25), -- goto state0 ‘1’ after (clk_period *8.25), --stay in state0 ‘0’ after (clk_period *9.25), -- goto state1 ‘1’ after (clk_period *10.25), -- goto state2 ‘1’ after (clk_period *11.25), -- goto state0 ‘1’ after (clk_period *12.25); --stay in state0 END io_test; TWO PHASE CLOCK • This entity generates 2 non-overlapping clocks of period 20ns. ENTITY two_phase_clk IS PORT( phi1 : OUT BIT; phi2 : OUT BIT ); END two_phase_clk; ARCHITECTURE behave OF two_phase_clk IS BEGIN P1:process begin phi1 <= ‘0’, ‘1’ after 2ns, ‘0’ after 8ns; phi2 <= ‘0’, ‘1’ after 12ns, ‘0’ after 18ns; Wait for 20ns ; --period of 2 clocks=20ns END PROCESS two _phase_clk; END behave; D FLIP-FLOP WITH ASYNCHRONOUS RESET This entity is a negative edge triggered D flipflop. ENTITY asynchr_reset_dff IS PORT( clk: IN BIT; reset: IN BIT; din : IN BIT; qout : OUT BIT; qout_bar: OUT BIT); END asynchr_reset_dff; D FLIP-FLOP WITH ASYNCHRONOUS RESET ARCHITECTURE behave OF asynchr_rest_dff IS Begin p1: process(reset, clk) is Begin if( reset = ‘1’) then qout <= ‘0’; qout_bar <= ‘1’; elsif (clk’event and clk = ‘0’) then qout <= din; qout_bar <= NOT(din); end if; end process p1; end behave; FOUR BIT COUNTER WITH CLEAR AND ENABLE PACKAGE own_types IS TYPE bit4 IS RANGE 0 to 15; TYPE four_state_logic IS (‘0’, ‘1’, ‘Z’, ‘X’); END own_types; --This entity is a 4 bit binary counter USE WORK.own_types. ALL; ENTITY counter_4bit IS PORT( clk : IN BIT; enable : IN BIT; clear : IN BIT; count4b : INOUT BIT4 ); END counter_4bit; FOUR BIT COUNTER WITH CLEAR AND ENABLE ARCHITECTURE behave OF counter_4bit IS Signal counter_val : bit4; Begin p1 : process(enable, count4b) is begin if(enable = ‘0’) then counter_val <= count4b; elsif (count4b >= 15) then counter_val <=0; else counter_val <= count4b + 1; end if; end process p1; FOUR BIT COUNTER WITH CLEAR AND ENABLE P2 : process (clear, clk) is Begin if(clear = ‘1’) then count4b <= 0; elsif (clk_event and clk = ‘1’) then count4b <= counter_val; end if; End process p2; End behave; FOUR BIT COUNTER WITH CLEAR AND ENABLE USE WORK. ALL USE WORK.own_types.ALL; Entity counter_4bit_test IS End counter_4bit_test; Architecture io_test OF counter_4bit_test IS Component c1 PORT( clk : IN BIT; enable: IN BIT; clear : IN BIT; count4b : INOUT bit4; ); End component; FOUR BIT COUNTER WITH CLEAR AND ENABLE For g0: c1 USE ENTITY WORK.counter_4bit(behave); Signal clk_test : BIT := ‘0’; Signal enable_test : BIT := ‘0’; Signal clear_test : BIT := ‘0’; Signal count4b_test :bit4; Begin clk_process: process(clk_test) is Begin clk_test <= NOT(clk_test); wait for 20ns; End process clk_process; FOUR BIT COUNTER WITH CLEAR AND ENABLE g0 : c1 port map (clk_test, enable_test, clear_test, count4b_test); --we set enable to 0 when we want to check if --the counter is correctly “frozen”. enable_test <= ‘0’ after 50ns, ‘1’ after 100ns, ‘0’ after 210ns, ‘1’ after 310ns; --we apply a clear after 30 ns t1: clear_test <= ‘0’, ‘1’ after 30ns, ‘0’ after 70ns; End io_test; 3 TYPES OF DELAYS 1. • 2. • 3. • • Transport Delay independent of input width Inertial Delay while reject small pulses Delta Minimum delay Δ- delays do not accumulate MODELING PROPOGATION DELAY • • Signal must remain constant for at least the propagation delay or greater than the reject time to be seen on the output Pulse rejection can be less than propagation - must be explicitly stated and must be less that inertial delay, e.g., Out <= reject 6ns inertial ( A or B) after 8ns; MODELING PROPOGATION DELAY • • To specify a delay between the input and the output of a conditional concurrent statement, append : after time Inertial (Propagation) delay e.g., S_out <= (S xor B xor C_in) after 10ns; INERTIAL DELAY • • Provides for specification of input pulse width, i.e. ‘inertia’ of output, and propagation delay Inertial delay is default and reject is optional TRANSPORT DELAY • • Delay must be explicitly specified by user • keyword transport must be used. Signal will assume its new value after specified delay, independent of width. INERTIAL DELAY, e.g., • Inverter with propagation delay of 10ns which suppresses pulses shorter than 5ns. output <= reject 5ns inertial not input after 10ns; NO DELTA DELAY, e.g., DELTA DELAY, e.g., FIFO CODE Library ieee; Use ieee.std_logic_1164.all; Use work.std_arith.all; entity FIFO_LOGIC is generic (N:integer := 3); port(clk, push, pop, init : in std_logic; add : out std_logic_vector(N-1 downto 0); full,empty,we,nppush,nopop : buffer std_logic); end FIFO_LOGIC; architecture RTL of FIFO_LOGIC is signal wptr, rptr: std_logic_vector(N-1 downto 0); signal lastop :std_logic; FIFO CODE Begin Sync: process(clk) is Begin if (clk’event and clk =‘1’) then if (init = ‘1’) then wptr <=(others => ‘0’); rptr <= (others => ‘0’); lastop <= ‘0’; elsif (pop = ‘1’ and empty = ‘0’) then rptr <= rptr +1; lastop <= ‘0’; elsif (push = ‘1’ and full = ‘0’) then wptr <= wptr +1; lastop <= ‘1’; end if; end if; End process sync; FIFO CODE Comb: process ( push, pop, wptr, rptr, lastop, full, empty) is begin --full and empty flags— if(rptr = wptr) then if(lastop = ‘1’) then full <= ‘1’; empty <= ‘0’; else full <= ‘0’; empty <= ‘1’; end if; else full <= ‘0’; empty <= ‘0’; end if; FIFO CODE --address, write enable and no push/ no pop logic – if(pop = ‘0’ and push = ‘0’) then -- no operation --add <= rptr; we <= ‘0’; nopush <= ‘0’; nopop <= ‘0’; elsif (pop = ‘0’ and push = ‘1’) then --push only-add <= wptr; nopop <= ‘0’; if(full = ‘0’) then we <= ‘1’; nopush <= ‘0’; else we <= ‘0’; nopush <= ‘1’; end if; FIFO CODE Elsif (pop = ‘1’ and push = ‘0’) then -- pop only -add <= rptr; nopush <= ‘0’; we <= ‘0’; if(empty = ‘0’) then --valid read condition – nopop <= ‘0’; else nopop <= ‘1’; end if; else add <= rptr; we <= ‘0’; nopush <= ‘1’; nopop <= ‘0’; end if; end process comb; end architecture RTL; ARITHMETIC LOGIC UNIT Library ieee; Use ieee.std_logic_1164.all; Use ieee.std_lgic_misc.all; Use ieee.std_logic_arith.all; Use ieee.std_logic_unsigned.all; Entity ALU is generic(N:integer :=4); port(clk, shift_dir, sl, sr : in std_logic; Ain, Bin, memdata: in std_logic_vector(N-1 downto 0); memack: in std_logic; opcode: in std_logic_vector( 3 downto 0); ACC: outstd_logic_vector(N-1 downto 0); flag: out std_logic := ‘Z’); end ALU; ARITHMETIC LOGIC UNIT Architecture BEHAVE of ALU is Signal sout, a, b : std_logic_vector(N-1 downto 0); Begin func: process(clk, opcode, memack) is Begin case opcode is when “0001” => sout <= a+b; when “0011” => sout <= a-b; when “0010” => sout <= a and b; when “0100” => sout <= a or b; when “0101” => sout <= not b; when”0101” => if (clk’event and clk =‘1’) then if( shift_dir = ‘0’) then sout <= sout(N-2 downto 0) & s1; else sout <= sr & sout(N-1 downto 1); end if; end if; ARITHMETIC LOGIC UNIT when “0111” => sout <= b; when “1001” => sout <= null; when “1000” => if(memack = ‘1’) then sout <= memdata; end if; when “1111” => if (a<=b) then flag <= ‘1’; else flag <= ‘0’; end if; when “1110”=> null; ARITHMETIC LOGIC UNIT when “1100” => sout <= b; when “0000” => null; when others => null; end case; end process; sync: process (clk) is begin if(clk,event and clk = ‘1’) then a <= Ain; b <= Bin; ACC <= sout; end if; end process sync; end BEHAVE; ARITHMETIC LOGIC UNIT – TEST BENCH Library ieee; Use ieee.std_logic_1164.all; entity TB_ALU is end TB_ALU; architecture TEST_BENCH of T B_ALU is begin constant clk_hp : TIME := 50ns; constant N : integer := 4; signal clk, shift_dir, sl, sr : std_logic := ‘0’; signal memack, flag : syd_logic := ‘0’; signal Ain, Bin, memdata, ACC : std_logic_vector( N-1 downto 0); signal opcode : std_logic_vector (3 downto 0); ARITHMETIC LOGIC UNIT – TEST BENCH component ALU generic (N: integer := 4); port (clk, shift_dir, sl, sr : in std_logic; Ain, Bin, memdata : in std_logic_vector(N-1 downto 0); opcode : in std_logic_vector( 3 downto 0); ACC : in std_logic_vector(N-1 downto 0); flag : out std_logic : ‘Z’ ); end component; begin UUT : ALU Port map (clk, shift_dir, sr, sl, Ain, Bin, memdata, memack, opcode, ACC, flag); ARITHMETIC LOGIC UNIT – TEST BENCH clockgen : process is begin clk <= ‘1’ after clk_hp, ‘0’ after 2*clk_hp; wait for 2*clk_hp; end process clockgen; SignalSource : process is begin opcode <= “0111”, “0101”, after 30ns; Bin <= “1111”, “0000” after 400ns; wait; end process SignalSource; end TESTBENCH; configuration CFG_TB_ALU of TB_ALU is for TESTBENCH for UUT : ALU end for; end; UP/DOWN COUNTER: BEHAVIORAL entity COUNTER is PORT( d: in integer range 0 to 255; clk, clear, load, up_down : in bit; qd : out integer range 0 to 255 ); end COUNTER; architecture A of COUNTER is begin process (clk) is variable cnt : integer range 0 to 255; variable direction : integer; begin if (up_down = ‘1’) then direction := 1; else direction := -1; end if; UP/DOWN COUNTER: BEHAVIORAL if (clk’event and clk = ‘1’) then if ( load := 1) then cnt := d; else cnt := cnt + direction; end if; -- the following lines will produce a synchronous clear on the --counter if( clear = ‘0’) then cnt := ‘0’; end if; end if; qd <= cnt; end process; end A; T FLIP-FLOP : STRUCTURAL library ieee; use ieee.std_logic_1164.all; entity andgate is port (A, B, C, D : in std_logic := ‘1’; Y : out std_ulogic); end andgate; architecture gate of andgate is begin Y <= A and B and C and D; end gate; T FLIP-FLOP : STRUCTURAL library ieee; use ieee.std_logic_1164.all; entity tff is port (Rst, clk, T : in ustd_logic := ‘1’; Q : out std_ulogic); end tff; architecture behave of tff is begin process (Rst, clk) is variable qtmp :std_ulogic; begin if (Rst = ‘1’) then qtmp := ‘0’; elsif rising_edge( clk) then if T = ‘1’ then qtmp := not qtmp; end if; end if; Q <= qtmp; end process; end behave; T FLIP-FLOP : STRUCTURAL library ieee; use ieee.std_logic_1164.all; entity TCOUNT is port (Rst, clk : std_ulogic; count : std_ulogic_vector ( 4 downto 0); end TCOUNT; architecture STRUCTURE of TCOUNT is component tff port ( Rst, clk, T : in std_ulogic; Q : out std_ulogic ); end component; component andgate port ( A, B, C, D : in std_ulogic; Y : out std_ulogic ); end component; constant VCC : std_logic := ‘1’; signal T, Q : std_ulogic_vector ( 4 downto 0); T FLIP-FLOP : STRUCTURAL begin T(0) <= VCC; T0 : tff port map (Rst => Rst, clk => clk, T => T(0), Q => Q(0) ); T(1) <= Q(0); T1 : tff port map (Rst => Rst, clk => clk, T => T(1), Q => Q(1) ); A1 : andgate port map (A => Q(0), B => Q(1), Y => T(2) ); T2 : tff port map (Rst => Rst, clk => clk, T => T(2), Q => Q(2) ); A2 : andgate port map (A => Q(0), B => Q(1), C => Q(2), Y => T(2) ); T3 : tff port map (Rst => Rst, clk => clk, T => T(3), Q => Q(3) ); A3 : andgate port map (A => Q(0), B => Q(1), C => Q(2), D => Q(3), Y => T(2) ); T4 : tff port map (Rst => Rst, clk => clk, T => T(4), Q => Q(4) ); count <= Q; end STRUCTURE; TRI-STATE BUS : DATAFLOW library ieee; use ieee.std_logic_1164.all; entity prebus is port ( my_in : in std_logic_vector ( 7 downto 0 ); sel : in std_logic; my_out : out std_logic_vector (7 downto 0 ); end prebus; architecture maxpid of prebus is begin my_out <= “ZZZZZZZZ”; when (sel = ‘1’ ) else my_in; end maxpid; BARREL SHIFTER : BEHAVIORAL library ieee; use ieee.std_logic_1164.all; entity shifter is port (clk, rst, load : in std_ulogic; data : in std_ulogic( 0 to 7); q : out std_ulogic ( 0 to 7) ); end shifter; architecture behavior of shifter is begin process (rst, clk ) is variable qreg : std_ulogic_vector ( 0 to 7); begin if rst = ‘1’ then qreg := “00000000”; BARREL SHIFTER : BEHAVIORAL elsif rising_edge(clk) then if load = ‘1’ then qreg := data; else qreg := qreg ( 1 to 7) & qreg(0); -- left shift qreg := qreg (7) & qreg (0 to 6); -- right shift end if; end if; q <= qreg; end process; end behavioral; MODULO 6 COUNTER library ieee; use ieee.std_logic_1164.all; use ieee.std _logic_unsigned.all; entity count5 is port ( clk, reset, enable : in std_logic; count : out std_logiv_vector(3 downto 0) ); end count5; architecture rtl of cout5 is begin cp : process (clk) is variable qnext : std_logic_vector ( 3 downto 0); begin if reset = ‘1’ then qnext := “0000” elsif (enable = ‘1’) then if (count <5 ) then qnext := qnext +1; else qnext := “0000” MODULO 6 COUNTER end if; else qnext := count; end if; if (clk’event and clk = ‘1’) then count <= qnext; end if; end process cp; end rtl; ONE HOT FSM library ieee; use ieee.std_logic_1164.all; use ieee.std _logic_unsigned.all; use ieee.std _logic_arith.all; entity fum is port (clk, reset, x, y, z : in std_logic; f : out std_logic); end fum; architecture rtl of fum is signal state_a : std_logic; signal state_b : std_logic; signal state_c : std_logic; signal state_d : std_logic; signal next_state_a : std_logic; signal next_state_b : std_logic; signal next_state_c : std_logic; signal next_state_d : std_logic; begin ONE HOT FSM output : process ( state_a, state_b, state_c, state_d) is variable f_v : std_logic; begin f_v := ‘0’; if (state_a = ‘1’) then f_v := ‘1’; end if; if (state_b = ‘1’) then f_v := ‘1’; end if; f <= f_v; end process; fsm : process (x, y, z, state_a, state_b, state_c, state_d ) is variable vnext_state_a : std_logic; variable vnext_state_b : std_logic; variable vnext_state_c : std_logic; variable vnext_state_d : std_logic; begin vnext_state_a := ‘0’; ONE HOT FSM vnext_state_b := ‘0’; vnext_state_c := ‘0’; vnext_state_d := ‘0’; if (state_a = ‘1’) then if ( x = ‘1’) then vnext_state_c := ‘1’; elsif (z = ‘1’) then vnext_state_d := ‘1’; else vnext_state_b := ‘1’; end if; end if; if (state_b = ‘1’) then vnext_state_d := ‘1’; end if; ONE HOT FSM if (state_b = ‘1’) then if ( z = ‘1’) then if ( x = ‘1’) then vnext_state_c := ‘1’; else vnext_state_b := ‘1’; end if; else vnext_state_d := ‘1’; end if; end if; if (state_d = ‘1’) then if ( x= ‘1’) then vnext_state_b := ‘1’; elsif ( y= ‘1’) then vnext_state_c := ‘1’; elsif ( z= ‘1’) then vnext_state_a := ‘1’; else vnext_state_d := ‘1’; end if; end if; ONE HOT FSM next_state_a <= vnext_state_a; next_state_b <= vnext_state_b; next_state_c <= vnext_state_c; next_state_d <= vnext_state_d; end process fum; reg_process : process (clk, reset, next_state_a, next_state_b, next_state_c, next_state_d ) is begin if (clk’event and clk = ‘1’ ) then if (reset = ‘1’) then state_a <= ‘1’; state_b <= ‘0’; state_c <= ‘0’; state_d <= ‘0’; else state_a <= next_state_a; state_b <= next_state_b; state_c <= next_state_c; state_d <= next_state_d; end if; end if; end process reg_process; end rtl; A PIPELINE library ieee; use ieee.std_logic_1164.all; use ieee.std _logic_unsigned.all; use ieee.std _logic_arith.all; entity pipeline is port ( a : in std_logic_vector (6 downto 0); clk, reset : in std_logic; f : out std_logic_vector ( 6 downto 0) ); end pipeline; architecture pipelined of pipeline is signal b, c, d, e : std_logic_vector ( 6 downto 0); begin reg1 : process (clk, reset ) is begin if reset = ‘1’ then b <= “0000000”; elsif rising_edge (clk) then b <= a; end if; end process reg1; A PIPELINE reg2 : process (clk, reset ) is begin if reset = ‘1’ then c <= “0000000”; elsif rising_edge (clk) then c <= b + “0000001”; end if; end process reg2; reg3 : process (clk, reset ) is begin if reset = ‘1’ then d <= “0000000”; elsif rising_edge (clk) then d <= c + “0000010”; end if; end process reg3; A PIPELINE reg4 : process (clk, reset ) is begin if reset = ‘1’ then e <= “0000000”; elsif rising_edge (clk) then e <= d + “0000011”; end if; end process reg4; reg5 : process (clk, reset ) is begin if reset = ‘1’ then f <= “0000000”; elsif rising_edge (clk) then f <= e + “0000100”; end if; end process reg5; end process pipelined; A GENERIC ADDER library ieee; use ieee.std_logic_1164.all; use ieee.std _logic_unsigned.all; use ieee.std _logic_arith.all; entity add_g is generic (left : natural := 31; -- top bit prop : time :=100 ps ); port ( a, b : in std_logic_vector ( left downto 0 ); cin : in std_logic_vector; sum : out std_logic_vector (left downto 0); cout : out std_logic ); end entity add_g; architecture behave of add_g is begin adder : process variable carry : std_logic; -- internal signal variable isum : std_logic_vector ( left downto 0); A GENERIC ADDER begin carry := cin; for I in 0 to left loop isum(i) := a(i) xor b(i) xor carry; carry := (a(i) and b (i) ) or (a(i) and carry ) or (b(i) and carry); end loop; sum <= isum; cout <= carry; wait for prop; -- signals updated after prop delay end process adder; end architecture behave; 16 : 1 MULTIPLEXER library ieee; use ieee.std_logic_1164.all; entity mux4 is port ( s: in std_logic_vector ( 1 downto 0 ); i : in std_logic_vector ( 3 downto 0 ); y : out std_logic ); end mux4; architecture vector of mux4 is begin with s select y <= i (0) when “00”, i (1) when “01”, i (2) when “10”, i (3) when others; end vector; 16 : 1 MULTIPLEXER library ieee; use ieee.std_logic_1164.all; entity mux16 is port ( datain: in std_logic_vector ( 15 downto 0 ); sel : in std_logic_vector ( 3 downto 0 ); dataout : out std_logic ); end mux16; architecture rtl of mux16 is component mux4 port ( s: in std_logic_vector ( 1 downto 0 ); i : in std_logic_vector ( 3 downto 0 ); y : out std_logic ); end component; for all : mux4 use entity work. mux4(vector); signal level1 : std_logic_vector (3 downto 0); -- intermediate signals begin 16 : 1 MULTIPLEXER mux0 :mux4 port map (s => sel (1 downto 0), i => datain(3 downto 0), y => level1 (0) ); mux1 :mux4 port map (s => sel (1 downto 0), i => datain(7 downto 4), y => level1 (1) ); mux2 :mux4 port map (s => sel (1 downto 0), i => datain(11 downto 8), y => level1 (2) ); mux3 :mux4 port map (s => sel (1 downto 0), i => datain(15 downto 12), y => level1 (3) ); muxall :mux4 port map (s => sel (1 downto 0), i => level1, y => dataout ); end rtl;