Liang Yang wrote:
> 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;
-------------------------------------------------------------------------------
|