我有这段 IP,它应该是一个 32 位字节的可寻址内存。但我不能让它推断出块公羊,它推断出大量的触发器......
它应该安装在只有双端口块 RAM 的 Spartan3e (xc3s1200e-4fg320) 上,实际上,内存被分成奇偶排列的两个阵列......
这是代码,我希望这可能有助于理解我做错了什么?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
package mem_types is
type memory_t is array (natural range <>) of std_logic_vector(7 downto 0);
end mem_types;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.mem_types.all;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ram is
generic (
INIT : memory_t(0 to 4095) := (others => (others => '0'))
);
port ( clk, rst : in std_logic;
addr : in std_logic_vector(11 downto 0);
din : in std_logic_vector(31 downto 0);
dout : out std_logic_vector(31 downto 0);
we : std_logic_vector(3 downto 0)
);
end ram;
architecture Behavioral of ram is
type ramport_t is record
addr : std_logic_vector(10 downto 0);
dout : std_logic_vector(7 downto 0);
din : std_logic_vector(7 downto 0);
wea : std_logic;
end record;
signal port0a, port0b, port1a, port1b : ramport_t;
signal addr_a, addr_b, addr_c, addr_d : std_logic_vector(11 downto 0);
signal memory0, memory1 : memory_t(0 to 2047);
begin
addr_a <= addr;
addr_b <= addr+1;
addr_c <= addr+2;
addr_d <= addr+3;
port0a.addr <= addr_a(11 downto 1) when addr_a(0) = '0' else addr_b(11 downto 1);
port1a.addr <= addr_b(11 downto 1) when addr_b(0) = '1' else addr_a(11 downto 1);
port0b.addr <= addr_c(11 downto 1) when addr_c(0) = '0' else addr_d(11 downto 1);
port1b.addr <= addr_d(11 downto 1) when addr_d(0) = '1' else addr_c(11 downto 1);
dout(07 downto 00) <= port0a.dout when addr_a(0) = '0' else port1a.dout;
dout(15 downto 08) <= port1a.dout when addr_b(0) = '1' else port0a.dout;
dout(23 downto 16) <= port0b.dout when addr_c(0) = '0' else port1b.dout;
dout(31 downto 24) <= port1b.dout when addr_d(0) = '1' else port0b.dout;
port0a.din <= din(07 downto 00) when addr_a(0) = '0' else din(15 downto 08);
port1a.din <= din(15 downto 08) when addr_b(0) = '1' else din(07 downto 00);
port0b.din <= din(23 downto 16) when addr_c(0) = '0' else din(31 downto 24);
port1b.din <= din(31 downto 24) when addr_d(0) = '1' else din(23 downto 16);
port0a.wea <= we(0) when addr_a(0) = '0' else we(1);
port1a.wea <= we(1) when addr_b(0) = '1' else we(0);
port0b.wea <= we(2) when addr_c(0) = '0' else we(3);
port1b.wea <= we(3) when addr_d(0) = '1' else we(2);
port0a.dout <= memory0(conv_integer(port0a.addr));
port0b.dout <= memory0(conv_integer(port0b.addr));
port1a.dout <= memory1(conv_integer(port1a.addr));
port1b.dout <= memory1(conv_integer(port1b.addr));
process (clk, rst)
begin
if rst = '1' then
for a in 0 to 2047 loop
memory0(a) <= INIT(a*2);
end loop;
elsif falling_edge(clk) then
if (port0a.wea = '1') then
memory0(conv_integer(port0a.addr)) <= port0a.din;
end if;
if (port0b.wea = '1') then
memory0(conv_integer(port0b.addr)) <= port0b.din;
end if;
end if;
end process;
process (clk, rst)
begin
if rst = '1' then
for a in 0 to 2047 loop
memory1(a) <= INIT((a*2)+1);
end loop;
elsif falling_edge(clk) then
if (port1a.wea = '1') then
memory1(conv_integer(port1a.addr)) <= port1a.din;
end if;
if (port1b.wea = '1') then
memory1(conv_integer(port1b.addr)) <= port1b.din;
end if;
end if;
end process;
end Behavioral;