Liang said:
I even tried to initialize this inout port to all 0, but it still shows "UU"
when I start simulation. During pre-synthesis simulation,
the initial value of DATA is also "UU", but it changes to correct value
after assignment take effect in the test bench.
Initialization has no effect for synthesis code.
A bidirectional interface requires signals and controls
for access and data direction. See the example below.
I try to figure out which one is driving this DATA port when its value
is changed. But I don't know how to do this in Active HDL. The break point
is located in the lsi_10k library and I can't trace it until the program
control
Tracing code is not very effective at solving system level problems.
-- Mike Treseler
-------------------------------------------------------------------------------
-- Testbench Example for bidirectional port.
-- oe_demo.vhd
-- Wed Jul 9 12:13:53 2003 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
-- 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;
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_sim : std_ulogic; -- [in]
signal clock_sim : std_ulogic; -- [in]
signal data_sim : std_logic_vector (7 downto 0); -- [inout]
signal ready_sim : std_ulogic; -- [in]
signal oe_sim : std_ulogic; -- [in]
signal we_sim : std_ulogic;
shared variable done_sim : boolean := false;
begin
-- Device under test instance
oe_demo_1 : entity work.oe_demo
port map (reset => reset_sim, -- [in]
clock => clock_sim, -- [in]
data => data_sim, -- [inout]
ready => ready_sim, -- [out]
oe => oe_sim); -- [in]
-- clock and reset generator
tb_clk : process is
begin
done : if now > sim_limit or done_sim then
wait;
end if done;
rst : if now < rst_period then
reset_sim <= active;
else
reset_sim <= not active;
end if rst;
clock_sim <= '0';
wait for clk_period/2;
clock_sim <= '1';
wait for clk_period/2;
end process tb_clk;
simulation : process (clock_sim, reset_sim) 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_sim = active then
report("reset " & std_ulogic'image(reset_sim));
step := 1;
oe_sim <= not active;
we_sim <= not active;
data_sim <= (others => 'Z');
oe_sim <= not active;
elsif rising_edge(clock_sim) then
done_sim := step > script'length;
enable : if not done_sim then
op_now := script(step);
report("op " & op_t'image(op_now) );
stim: case op_now is
when idle =>
we_sim <= not active;
oe_sim <= not active;
data_sim <= (reg'range => 'Z');
when get =>
we_sim <= not active;
oe_sim <= active;
data_sim <= (reg'range => 'Z');
when put =>
we_sim <= active;
oe_sim <= not active;
data_sim <= dummy_dat;
when others =>
oe_sim <= not active;
data_sim <= (reg'range => 'Z');
end case stim;
ck_write: if we_sim = active then
report(time'image(now)&
" Should have no Error assertions below " &
" ###### Write test ######");
assert data_sim = dummy_dat;
end if ck_write;
ck_read: if ready_sim = active then
report(time'image(now)&
" Should have no Error assertions below " &
" ###### Read test ######");
assert data_sim = dummy_dat;
-- assert data_sim = dummy_reg; -- 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;
-------------------------------------------------------------------------------