O
Olaf Petzold
Guest
Hi,
what's wrong with the code below? I've got on data bus and my_data a
'X' Vector (Forcing Unknown) on reading (both register contents work
against). It seems to be a principle problem of me. What happend here?
The goal is a sequential read back of data written before. Attached a
screen shot (hopefully be distributed on news server).
Thanks
Olaf
---8<---
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bus_test is
end entity bus_test;
architecture behaviorial of bus_test is
signal done : boolean := false;
signal clk, reset : std_logic := '0';
signal address : unsigned(7 downto 0);
signal data : std_logic_vector(7 downto 0);
signal my_data : std_logic_vector(data'range);
signal rd, wr : std_logic;
constant MY_ADDRESS1 : unsigned(address'range) := b"1000_0000";
constant MY_ADDRESS2 : unsigned(address'range) := b"1001_0000";
constant TST_DATA1 : std_logic_vector(data'range)
:= b"10101010";
constant TST_DATA2 : std_logic_vector(data'range)
:= b"01010101";
begin
clk_proc : process is
constant PERIOD : time := 10 ns;
begin
clk <= '0';
if done then wait; end if;
wait for PERIOD/2;
clk <= '1';
wait for PERIOD/2;
end process clk_proc;
rst : reset <= '1', '0' after 15 ns;
register_set : block is
signal m_register1 : std_logic_vector(data'range);
signal m_register2 : std_logic_vector(data'range);
begin
rdwr_proc : process (clk, reset) is
begin
if (reset = '1') then
data <= (others => 'Z');
elsif rising_edge(clk) then
if (wr = '1') and (rd = '0') then
case address is
when MY_ADDRESS1 => m_register1 <= data;
when MY_ADDRESS2 => m_register2 <= data;
when others => null;
end case;
elsif (wr = '0') and (rd = '1') then
case address is
when MY_ADDRESS1 => data <= m_register1;
when MY_ADDRESS2 => data <= m_register2;
when others => null;
end case;
else
data <= (others => 'Z');
end if;
end if;
end process rdwr_proc;
end block register_set;
TB : process is
------------------------------------------
procedure tic is
begin
wait until rising_edge(clk);
end procedure tic;
------------------------------------------
procedure do_wr (
constant addr : in unsigned;
constant dat : in std_logic_vector) is
begin
wr <= '1';
address <= addr;
data <= dat;
tic;
wr <= '0';
end procedure do_wr;
------------------------------------------
procedure do_rd (
constant addr : in unsigned;
signal dat : out std_logic_vector) is
begin
rd <= '1';
address <= addr;
tic;
dat <= data;
rd <= '0';
end procedure do_rd;
------------------------------------------
begin
my_data <= (others => '0');
rd <= '0';
wr <= '0';
address <= (others => '0');
data <= (others => '0');
wait until (reset = '0');
tic; tic;
do_wr(MY_ADDRESS1, TST_DATA1);
do_wr(MY_ADDRESS2, TST_DATA2);
tic;
do_rd(MY_ADDRESS1, my_data);
do_rd(MY_ADDRESS2, my_data);
tic;
assert (my_data = TST_DATA1)
report "* missmatch 1 *" severity error;
assert (my_data = TST_DATA2)
report "* missmatch 2 *" severity error;
tic;
done <= true;
end process TB;
end architecture behaviorial;
--->8---
what's wrong with the code below? I've got on data bus and my_data a
'X' Vector (Forcing Unknown) on reading (both register contents work
against). It seems to be a principle problem of me. What happend here?
The goal is a sequential read back of data written before. Attached a
screen shot (hopefully be distributed on news server).
Thanks
Olaf
---8<---
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bus_test is
end entity bus_test;
architecture behaviorial of bus_test is
signal done : boolean := false;
signal clk, reset : std_logic := '0';
signal address : unsigned(7 downto 0);
signal data : std_logic_vector(7 downto 0);
signal my_data : std_logic_vector(data'range);
signal rd, wr : std_logic;
constant MY_ADDRESS1 : unsigned(address'range) := b"1000_0000";
constant MY_ADDRESS2 : unsigned(address'range) := b"1001_0000";
constant TST_DATA1 : std_logic_vector(data'range)
:= b"10101010";
constant TST_DATA2 : std_logic_vector(data'range)
:= b"01010101";
begin
clk_proc : process is
constant PERIOD : time := 10 ns;
begin
clk <= '0';
if done then wait; end if;
wait for PERIOD/2;
clk <= '1';
wait for PERIOD/2;
end process clk_proc;
rst : reset <= '1', '0' after 15 ns;
register_set : block is
signal m_register1 : std_logic_vector(data'range);
signal m_register2 : std_logic_vector(data'range);
begin
rdwr_proc : process (clk, reset) is
begin
if (reset = '1') then
data <= (others => 'Z');
elsif rising_edge(clk) then
if (wr = '1') and (rd = '0') then
case address is
when MY_ADDRESS1 => m_register1 <= data;
when MY_ADDRESS2 => m_register2 <= data;
when others => null;
end case;
elsif (wr = '0') and (rd = '1') then
case address is
when MY_ADDRESS1 => data <= m_register1;
when MY_ADDRESS2 => data <= m_register2;
when others => null;
end case;
else
data <= (others => 'Z');
end if;
end if;
end process rdwr_proc;
end block register_set;
TB : process is
------------------------------------------
procedure tic is
begin
wait until rising_edge(clk);
end procedure tic;
------------------------------------------
procedure do_wr (
constant addr : in unsigned;
constant dat : in std_logic_vector) is
begin
wr <= '1';
address <= addr;
data <= dat;
tic;
wr <= '0';
end procedure do_wr;
------------------------------------------
procedure do_rd (
constant addr : in unsigned;
signal dat : out std_logic_vector) is
begin
rd <= '1';
address <= addr;
tic;
dat <= data;
rd <= '0';
end procedure do_rd;
------------------------------------------
begin
my_data <= (others => '0');
rd <= '0';
wr <= '0';
address <= (others => '0');
data <= (others => '0');
wait until (reset = '0');
tic; tic;
do_wr(MY_ADDRESS1, TST_DATA1);
do_wr(MY_ADDRESS2, TST_DATA2);
tic;
do_rd(MY_ADDRESS1, my_data);
do_rd(MY_ADDRESS2, my_data);
tic;
assert (my_data = TST_DATA1)
report "* missmatch 1 *" severity error;
assert (my_data = TST_DATA2)
report "* missmatch 2 *" severity error;
tic;
done <= true;
end process TB;
end architecture behaviorial;
--->8---