我创建了这个ram:
library ieee;
use ieee.std_logic_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
entity true_dpram_sclk is
port
(
data_a : in std_logic_vector(7 downto 0);
data_b : in std_logic_vector(7 downto 0);
address_a : in std_logic_vector(7 downto 0);
address_b : in std_logic_vector(7 downto 0);
we_a : in std_logic := '1';
-- we_b : in std_logic := '1';
clk : in std_logic;
q_a : out std_logic_vector(7 downto 0);
q_b : out std_logic_vector(7 downto 0);
q : out std_logic
);
end true_dpram_sclk;
architecture rtl of true_dpram_sclk is
-- Build a 2-D array type for the RAM
subtype word_t is std_logic_vector(7 downto 0);
type memory_t is array(17 downto 0) of word_t;
-- Declare the RAM
shared variable ram : memory_t;
SIGNAL ADDR_A : INTEGER RANGE 0 TO 17;
SIGNAL ADDR_B : INTEGER RANGE 0 TO 17;
begin
-- Port A
process(clk)
begin
ADDR_A<=CONV_INTEGER(ADDRESS_A);
if(rising_edge(clk)) then
if(we_a = '1') then
ram(addr_a) := data_a;
elsif (we_a = '0') then
q_a <= ram(addr_a);
else
q_a <= "ZZZZZZZZ";
end if;
end if;
end process;
-- Port B
process(clk)
begin
ADDR_B<=CONV_INTEGER(ADDRESS_B);
if(rising_edge(clk)) then
if(we_a = '1') then
ram(addr_b) := data_b;
elsif (we_a = '0') then
q_b <= ram(addr_b);
else
q_b <= "ZZZZZZZZ";
end if;
end if;
end process;
-- --MATCHER
-- process (clk)
-- begin
-- if ((we_a = '0') and (we_b = '0') and ram(addr_a) =
--ram(addr_b)) then
-- q <= '1';
-- else
-- q <= '0';
-- end if;
-- end process;
--
end rtl;
以及上述测试基准:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY tb2 IS
END tb2;
ARCHITECTURE behavior OF tb2 IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT true_dpram_sclk
PORT(
data_a : IN std_logic_vector(7 downto 0);
data_b : IN std_logic_vector(7 downto 0);
address_a : IN std_logic_vector(7 downto 0);
address_b : IN std_logic_vector(7 downto 0);
we_a : IN std_logic;
-- we_b : IN std_logic;
clk : IN std_logic;
q_a : OUT std_logic_vector(7 downto 0);
q_b : OUT std_logic_vector(7 downto 0);
q : OUT std_logic
);
END COMPONENT;
-- COMPONENT matcher
-- PORT(
-- A : IN std_logic_vector(15 downto 0);
-- B : IN std_logic_vector(15 downto 0);
-- clk: IN std_logic;
-- Q : OUT std_logic
-- );
-- END COMPONENT;
--Inputs
signal data_a : std_logic_vector(7 downto 0) := (others => '0');
signal data_b : std_logic_vector(7 downto 0) := (others => '0');
signal address_a : std_logic_vector(7 downto 0) := (others => '0');
signal address_b : std_logic_vector(7 downto 0) := (others => '0');
signal we_a : std_logic := '1';
-- signal we_b : std_logic := '1';
signal clk : std_logic := '0';
SIGNAL ADDR_A : INTEGER RANGE 0 TO 17;
SIGNAL ADDR_B : INTEGER RANGE 0 TO 17;
--Outputs
signal q_a : std_logic_vector(7 downto 0);
signal q_b : std_logic_vector(7 downto 0);
signal q : std_logic := '0';
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: true_dpram_sclk PORT MAP (
data_a => data_a,
data_b => data_b,
address_a => address_a,
address_b => address_b,
we_a => we_a,
-- we_b => we_b,
clk => clk,
q_a => q_a,
q_b => q_b,
q => q
);
-- uut: matcher PORT MAP (
-- A => q_a,
-- B => q_b,
-- clk => clk,
-- Q => Q
-- );
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period;
clk <= '1';
wait for clk_period;
end process;
process
begin
--Write data into RAM
wait for clk_period*1;
--1
address_a <= "00000000";
address_b <= "00000000";
data_a <= "10111001";
data_b <= "10111001";
wait for clk_period*1;
--2
address_a <= "00000001";
address_b <= "00000001";
data_a <= "01101100";
data_b <= "01101100";
wait for clk_period*1;
--3
address_a <= "00000010";
address_b <= "00000010";
data_a <= "00110011";
data_b <= "00110011";
wait for clk_period*1;
--4
address_a <= "00000011";
address_b <= "00000011";
data_a <= "00001101";
data_b <= "00001101";
wait for clk_period*1;
--5
address_a <= "00000100";
address_b <= "00000100";
data_a <= "00001010";
data_b <= "00001010";
wait for clk_period*1;
--6
address_a <= "00000101";
address_b <= "00000101";
data_a <= "00110111";
data_b <= "00110111";
wait for clk_period*1;
--7
address_a <= "00000110";
address_b <= "00000110";
data_a <= "11110010";
data_b <= "10111001";
wait for clk_period*1;
--8
address_a <= "00000111";
address_b <= "00000111";
data_a <= "10101011";
data_b <= "01101100";
wait for clk_period*1;
--9
address_a <= "00001000";
address_b <= "00001000";
data_a <= "01111000";
data_b <= "00110011";
wait for clk_period*1;
--10
address_a <= "00001001";
address_b <= "00001001";
data_a <= "01011000";
data_b <= "00001101";
wait for clk_period*1;
--11
address_a <= "00001010";
address_b <= "00001010";
data_a <= "00001010";
data_b <= "00001010";
wait for clk_period*1;
--12
address_a <= "00001011";
address_b <= "00001011";
data_a <= "00111000";
data_b <= "00110111";
wait for clk_period*1;
--Read data from RAM
we_a <= '0';
-- we_b <= '0';
--1
address_a <= "00000000";
address_b <= "00000000";
wait for clk_period*1;
--2
address_a <= "00000001";
address_b <= "00000001";
wait for clk_period*1;
--3
address_a <= "00000010";
address_b <= "00000010";
wait for clk_period*1;
--4
address_a <= "00000011";
address_b <= "00000011";
wait for clk_period*1;
--5
address_a <= "00000100";
address_b <= "00000100";
wait for clk_period*1;
--6
address_a <= "00000101";
address_b <= "00000101";
wait for clk_period*1;
--7
address_a <= "00000110";
address_b <= "00000110";
wait for clk_period*1;
--8
address_a <= "00000111";
address_b <= "00000111";
wait for clk_period*1;
--9
address_a <= "00001000";
address_b <= "00001000";
wait for clk_period*1;
--10
address_a <= "00001001";
address_b <= "00001001";
wait for clk_period*1;
--11
address_a <= "00001010";
address_b <= "00001010";
wait for clk_period*1;
--12
address_a <= "00001100";
address_b <= "00001100";
wait for clk_period*1;
wait;
end process;
END behavior;
我想阅读address_a和address_b并逐一比较它们并返回q&lt; =&#39; 1&#39;当address_a = adress_b且q&lt; =&#39; 0&#39;什么时候不平等。我想要这样的事情:
--Read data from RAM
we_a <= '0';
-- we_b <= '0';
--1
address_a <= "00000000";
address_b <= "00000000";
if ( q_a = q_b ) then
q <= '1'; else
q <= '0';
end if;
wait for clk_period*1;
任何帮助都会很棒。谢谢!!
答案 0 :(得分:4)
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
失礼。那是一个非标准化的图书馆。不要使用它。替换为
USE IEEE.NUMERIC_STD.ALL;
并使用UNSIGNED
或SIGNED
数据类型进行算术运算。
特别是不要同时使用这两个库,就像你在测试台上那样......
address_a : in std_logic_vector(7 downto 0);
[...]
SIGNAL ADDR_A : INTEGER RANGE 0 TO 17;
[...]
ADDR_A<=CONV_INTEGER(ADDRESS_A);
address_a
为8位,因此范围为0到255(如果已签名则为-128到127)。你不能简单地把它放在0到17的范围内。这可能会导致错误。
-- Port A
process(clk)
begin
ADDR_A<=CONV_INTEGER(ADDRESS_A);
if (rising_edge(clk)) then
作业ADDR_A<=CONV_INTEGER(ADDRESS_A);
是一个组合声明。然而你把它放在计时过程中(但不是在时钟if语句中)。这有各种奇怪的效果,特别是当你合成时:它甚至可能产生一个锁存器。
ADDR_A<=CONV_INTEGER(ADDRESS_A);
需要在流程之外。如果您使用库numeric_std
和ADDR_A <= to_integer(unsigned((ADDRESS_A));
在实现中,逻辑值只能是'0'和'1'。
if(we_a = '1') then
[...]
elsif (we_a = '0') then
[... we_a = '0' is redundant here ...]
else
[... unreachable, as '1' and '0' are already covered ...]
end if;
足够的是:
if(we_a = '1') then
ram(addr_b) := data_b;
else
q_b <= ram(addr_b);
end if;
然而,这不是正确支持的RAM编码,因为您键入的内容是为了阻止q_b
在we_a = '1'
时更改。正确的是:
q_b <= ram(addr_b);
if(we_a = '1') then
ram(addr_b) := data_b;
end if;
即。写作时q_b
也会发生变化。
例如,请参阅Xilinx synthesis user guide。
Block RAM(就像你打算使用的那样)是一个封闭的组件。它最多只有两个访问端口,您使用它们:端口A和端口B.但是,在第三个进程中,您尝试通过第三个端口访问RAM!
if [...] ram(addr_a) = ram(addr_b) [...] then
这是不可能的。
如果你想比较地址的值,你必须先从RAM中取出它们......这实际上已经在端口A和端口B进程中发生了(如果你正确地改变这些就像我之前建议的那样) )。然后,您可以使用以下方法简单地比较内容:
process (clk)
begin
if rising_edge(clk) then
if q_a = q_b then
q <= '1';
else
q <= '0';
end if;
end if;
end process;
在您的代码中,您正在比较RAM 内容
ram(addr_a) = ram(addr_b)
但是,如果我读了你的问题,你想要比较地址。
addr_a = addr_b
这是什么?如果是后者,则无需做复杂的事情。只是做:
process (clk)
begin
if rising_edge(clk) then
if addr_a = addr_b then
q <= '1';
else
q <= '0';
end if;
end if;
end process;