------------------------------------------------------------------------------ -- http://home.comcast.net/~mike_treseler/oe_demo.vhd -- this file -- http://home.comcast.net/~mike_treseler/oe_demo.pdf -- sim waves -- Testbench Example for bidirectional port. -- oe_demo.vhd -- Updated Wed Nov 2 11:07:46 2005 Mike Treseler ------------------------------------------------------------------------------ ---- Modelsim commands -- 1. TEXT ASSERTIONS: -- vsim -c test_oe_demo -do "run -all; exit" -- 2. DEBUG WAVES -- vsim test_oe_demo -do "add wave *;add wave /test_oe_demo/simulation/*;run -all" -- Note: By specifying the process name, you get the variables ^^^^ ------------------------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; package oe_demo_package is procedure print ( str1 : in string := ""; -- all args are optional str2 : in string := ""; str3 : in string := ""; str4 : in string := "" ); -- Shared constants go here: subtype reg is std_logic_vector (7 downto 0); constant dummy_reg : reg := x"3e"; constant dummy_dat : reg := x"81"; constant active : std_ulogic := '1'; constant clk_period : time := 40 ns; constant rst_period : time := 2*clk_period; constant sim_limit : time := 100 us; end package oe_demo_package; ------------------------------------------------------------------------------- use std.textio.write; package body oe_demo_package is procedure print ( str1 : in string := ""; str2 : in string := ""; str3 : in string := ""; str4 : in string := "" ) is constant newline_c : string := (1 => LF); constant tab_c : string := " "; constant message_c : string := newline_c & tab_c & str1 & str2 & str3 & str4; begin write(std.textio.output, message_c); end procedure print; end package body oe_demo_package; ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.oe_demo_package.all; -- Simplified Device Under Test entity oe_demo is port ( reset : in std_ulogic; clock : in std_ulogic; data : inout std_logic_vector (7 downto 0); ready : out std_ulogic; oe : in std_ulogic ); end oe_demo; ------------------------------------------------------------------------------- architecture synth of oe_demo is begin bidir : process (clock, reset) is begin -- process bidir clked : if reset = active then data <= (others => 'Z'); ready <= not active; elsif rising_edge(clock) then enable : if oe = active then data <= dummy_reg; ready <= active; else data <= (others => 'Z'); ready <= not active; end if enable; end if clked; end process bidir; end architecture synth; ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.oe_demo_package.all; -- Testbench entity test_oe_demo is end entity test_oe_demo; ------------------------------------------------------------------------------- architecture sim of test_oe_demo is -- Testbench wires go here signal reset_s : std_ulogic; -- [in] signal clock_s : std_ulogic; -- [in] signal data_s : std_logic_vector (7 downto 0); -- [inout] signal ready_s : std_ulogic; -- [in] signal oe_s : std_ulogic; -- [in] signal we_s : std_ulogic; shared variable done_v : boolean := false; begin -- Device under test instance oe_demo_1 : entity work.oe_demo port map (reset => reset_s, -- [in] clock => clock_s, -- [in] data => data_s, -- [inout] ready => ready_s, -- [out] oe => oe_s); -- [in] ------------------------------------------------------------------------------- -- clock and reset generator tb_clk : process is begin done : if now > sim_limit or done_v then wait; end if done; rst : if now < rst_period then reset_s <= active; else reset_s <= not active; end if rst; clock_s <= not active; wait for clk_period/2; clock_s <= active; wait for clk_period/2; end process tb_clk; ------------------------------------------------------------------------------- simulation : process (clock_s, reset_s) is type op_t is (idle, get, put); type script_t is array (1 to 9) of op_t; constant script : script_t := (1 => idle, 2 => get, 3 => idle, 4 => idle, 5 => put, others => idle); variable step : natural; variable op_now : op_t; begin -- process bidir clked : if reset_s = active then print("reset = ", std_ulogic'image(reset_s), "at ", time'image(now)); step := 1; oe_s <= not active; we_s <= not active; data_s <= (others => 'Z'); oe_s <= not active; elsif rising_edge(clock_s) then done_v := step > script'length; enable : if not done_v then op_now := script(step); print("op ", op_t'image(op_now) ); stim: case op_now is when idle => we_s <= not active; oe_s <= not active; data_s <= (reg'range => 'Z'); when get => we_s <= not active; oe_s <= active; data_s <= (reg'range => 'Z'); when put => we_s <= active; oe_s <= not active; data_s <= dummy_dat; when others => oe_s <= not active; data_s <= (reg'range => 'Z'); end case stim; ------------------------------------------------------------------------------- ck_write: if we_s = active then print(time'image(now), " Write Verification"); assert data_s = dummy_dat; end if ck_write; ck_read: if ready_s = active then print(time'image(now), " Read Verification"); assert data_s = dummy_reg; -- assert data_s = dummy_dat; -- uncomment to force error end if ck_read; ------------------------------------------------------------------------------- step := step + 1; -- step counter end if enable; end if clked; end process simulation; end architecture sim; -------------------------------------------------------------------------------