library ieee;
use ieee.std_logic_1164.all;
package oe_demo_package is
procedure print (
str1 : in string := ""; str2 : in string := "";
str3 : in string := "";
str4 : in string := ""
);
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;
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 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;
entity test_oe_demo is
end entity test_oe_demo;
architecture sim of test_oe_demo is
signal reset_s : std_ulogic; signal clock_s : std_ulogic; signal data_s : std_logic_vector (7 downto 0); signal ready_s : std_ulogic; signal oe_s : std_ulogic; signal we_s : std_ulogic;
shared variable done_v : boolean := false;
begin
oe_demo_1 : entity work.oe_demo
port map (reset => reset_s, clock => clock_s, data => data_s, ready => ready_s, oe => oe_s); 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 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;
end if ck_read;
step := step + 1; end if enable;
end if clked;
end process simulation;
end architecture sim;