---------------------------------------------------------------- -- Chapter 18 Test Bench and Verification Features ---------------------------------------------------------------- ---------------------------------------------------------------- -- 18.1 External Names ---------------------------------------------------------------- -- Page 560 assert <> /= "00000" report "Illegal controller state"; -- Page 561 <>(8) <= '1'; alias duv_data_bus is <>; duv_data_bus(8) <= '1'; sign <= duv_data_bus(0); alias duv_data_bus : std_ulogic_vector(0 to 15) is -- illegal! <>; alias duv_data_bus : std_ulogic_vector(15 downto 0) is -- illegal! <>; -- Example 18.1, Page 562 entity design is port ( ... ); end entity design; architecture rtl is constant width : natural := 32; ... begin ... end architecture rtl; entity test_bench is end entity test_bench; architecture directed of test_bench is signal test_in : bit_vector(0 to <> - 1); ... begin ... end architecture directed; entity top is end entity top; architecture level of top is begin assert false report "Width = " & to_string(<>); duv : entity work.design(rtl); tb : entity work.test_bench(directed); end architecture level; -- Example 18.2, Page 564 library ieee; use ieee.std_logic_1164.all; entity control is port ( clk, reset : in std_ulogic; ... ); end entity control; architecture fsm of control is subtype state_type is std_ulogic_vector(3 downto 0); constant idle : state_type := "0000"; constant pending1 : state_type := "0001"; ... signal current_state, next_state : state_type; begin state_reg : process (clk) is ... fsm_logic : process (all) is ... end architecture fsm; library IEEE; use IEEE.std_logic_1164.all; entity system is port ( clk, reset : in std_ulogic; ... ); end entity system; architecture rtl of system is component control is port ( clk, reset : in std_ulogic; ... ); end component control; begin control_unit : component control port map ( clk => clk, reset => reset, ... ); ... end architecture rtl; -- Example 18.2, Page 565 entity state_monitor is end entity state_monitor; architecture tracing of state_monitor is alias fsm_clk is <>; alias fsm_state is <>; begin monitor : process (fsm_clk) is begin if falling_edge(fsm_clk) then report to_string(now) & ": " & to_string(fsm_state); end if; end process monitor; end architecture tracing; library IEEE; use IEEE.std_logic_1164.all; entity tb is end entity tb; architecture monitoring of tb is signal system_clk, system_reset : std_ulogic; ... begin ... -- clock and reset generation system_duv : entity work.system(rtl) port map ( clk => system_clk, reset => system_reset, ... ); state_monitor : entity work.state_monitor(tracing); end architecture monitoring; -- Page 566 assert <> /= "00000" report "Illegal controller state"; -- Example 18.3, Page 567 architecture monitoring of tb is signal system_clk, system_reset : std_ulogic; alias fsm_clk is <>; ... begin ... -- clock and reset generation system_duv : entity work.system(rtl) port map ( clk => system_clk, reset => system_reset, ... ); monitor : process (fsm_clk) is use std.textio.all; file state_file : text open write_mode is state_file_name; alias fsm_state is <>; begin if falling_edge(fsm_clk) then report to_string(now) & ": " & to_string(fsm_state); end if; end process monitor; end architecture monitoring; -- Example 18.4, Page 568 entity CPU is ... end entity CPU; architecture BFM of CPU is use work.CPU_types.all; signal fetched_instruction : instruction_type; ... begin ... end architecture BFM; entity platform is generic ( num_cores : positive ); port ( ... ); end entity platform; architecture BFM_multicore of platform is ... begin cores : for core_num in 1 to num_cores generate processor : entity work.CPU(BFM) ...; ... end generate cores; ... end architecture BFM_multicore; -- Example 18.4, Page 569 entity test_bench is generic ( num_cores : positive ); end entity test_bench; architecture test_BFM of test_bench is ... begin duv : entity work.platform(BFM_multicore) generic map ( num_cored => num_cores ) port map ( ... ); monitors : for core_num in 1 to num_cores generate use work.CPU_types.all, work.CPU_trace.all; process is begin ... trace_instruction ( <>, ... ); ... end process; end generate monitors; end architecture test_BFM; -- Page 570 package p1 is ... end package p1; package body p1 is ... package p2 is signal s : bit; end package p2; ... end package body p1; <> ---------------------------------------------------------------- -- 18.2 Force and Release Assignments ---------------------------------------------------------------- -- Example 18.5, Page 571 verify_state_recovery : process is use work.control_pkg.all; alias clk is <>; alias current_state is <>; begin ... -- inject corrupt state wait until falling_edge(clk); current_state <= force illegal_state_12; wait until falling_edge(clk); current_state <= release; -- monitor recovery activity ... end process verify_state_recovery; -- Page 572 duv_bus <= force out "ZZZZZZZZ"; duv_bus <= force in "XXXXXXXX"; duv_bus <= release out; duv_bus <= release in; -- Example 18.6, Page 573 ... -- Test scenario: break in the output connection <> <= force out 'Z'; -- Monitor device operation under this fault condition ... -- Restore connection for the next scenario <> <= release out; ... -- Example 18.7, Page 574 alias dut_d_bus is <>; ... for test_count in 1 to num_tests loop dut_d_bus <= force in next_random_stim(dut_d_bus'length) when test_mode = random else directed_stim(test_count); wait for test_interval; end loop; -- Page 574 (carry_out, sum) <= ('0' & a) + ('0' & b); sum <= force out unsigned'("00000000"); carry_out <= force out '1'; ... sum <= release out; carry_out <= release out; ---------------------------------------------------------------- -- 18.3 Embedded PSL in VHDL ---------------------------------------------------------------- -- Page 576 always (a -> next[3] b) always ((a && next[3] b) -> c) -- Example 18.8, Page 576 library ieee; context ieee.ieee_std_context; entity slave is port ( clk, reset : in std_ulogic; req : in std_ulogic; ack : out std_ulogic; ... ); end entity slave; architecture pipelined of slave is signal req_cnt, ack_cnt : unsigned(3 downto 0); default clock is rising_edge(clk); property all_requests_acked is forall C in {0 to 15}: always {req and req_cnt = C} |=> {[*0 to 99]; ack and ack_cnt = C}; begin req_ack_counter : process (clk) is begin if rising_edge(clk) then if reset = '1' then req_cnt <= "0000"; ack_cnt <= "0000"; else if req = '1' then req_cnt <= req_cnt + 1; end if; if ack = '1' then ack_cnt <= ack_cnt + 1; end if; end if; end if; end process req_ack_counter; ... assert all_requests_acked; end architecture pipelined; -- Page 577 assert not (a and b) report "a and b are both true"; assert next[0] not (a and b) report "a and b are both true"; -- Example 18.9, Page 578 vunit complementary_outputs { assert always Q = not Q_n; } entity D_FF is port ( clk, reset, D : in bit; Q, Q_n : out bit ); end entity D_FF; architecture gate_level of D_FF is component and2 is ... ... begin G1 : and2 ... ... end architecture gate_level; -- Example 18.9, Page 579 configuration fast_sim of D_FF is use vunit complementary_outputs; for gate_level for all : and2 ... end for; ... end for; end configuration fast_sim; -- Example 18.10, Page 579 entity system is ... end entity system; architecture RTL of system is component shift_reg is port ( clk, reset, D : in bit_vector; Q, Q_n : out bit ); end component shift_reg; ... begin serializer : shift_reg ...; ... end architecture RTL; -- Example 18.10, Page 580 configuration verifying of system is for RTL for serializer : shift_reg use entity work.shift_reg(RTL); use vunit complementary_outputs; end for; end for; end configuration verifying; -- Example 18.11, Page 580 architecture RTL of system is component shift_reg is ... end component shift_reg; for serializer : shift_reg use entity work.shift_reg(RTL); use vunit complementary_outputs; end for; begin serializer : shift_reg ...; ... end architecture RTL; -- Page 581 function rose ( x : boolean ) return boolean is ...; sequence cover_fifo_empty is {reset_n && rose(cnt = 0)}; ---------------------------------------------------------------- -- Exercises ---------------------------------------------------------------- -- Exercise 1 architecture rtl of datapath is constant d_width : positive := 8; signal d_bus : std_ulogic_vector(d_width - 1 downto 0); begin adder : for i in 0 to d_width - 1 generate signal carry : std_ulogic; begin ... end generate adder; ... end architecture datapath; architecture data_test of test_bench is ... begin dp : entity work.datapath(rtl) port map ( ... ); verifier : process is begin ... end process verifier; end architecture data_test;