当两个地址具有相同的值时,我如何读取这个 ram 和 return a q = 1
How i can read this ram and return a q = 1 when two addresses have the same value
我创建了这个 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 并一一比较 return q <= '1' 当 address_a = adress_b 和 q <= '0' 时不相等。我想要这样的东西:
--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;
任何帮助都会很棒。谢谢!!
图书馆的选择
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));
实现中的代码无法访问且 RAM 实例化不正确。
在实现逻辑值只能是“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。
正在访问 RAM 数据
块 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;
我创建了这个 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 并一一比较 return q <= '1' 当 address_a = adress_b 和 q <= '0' 时不相等。我想要这样的东西:
--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;
任何帮助都会很棒。谢谢!!
图书馆的选择
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));
实现中的代码无法访问且 RAM 实例化不正确。
在实现逻辑值只能是“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。
正在访问 RAM 数据
块 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;