Tengo un proyecto con varios bloques de RAM de doble puerto inferidos. El código para esta memoria RAM de doble puerto es el siguiente:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
use ieee.std_logic_textio.all;
library std;
use std.textio.all;
entity dual_port_ram_w_be is
generic(
DATA_WIDTH : natural := 32;
ADDR_WIDTH : natural := 12;
INITIALIZE_TO_ZERO : boolean := true;
MEMTYPE_PAR_DIRECTIVE : string := "block"
);
port(
-- Port A
port_a_clk : in std_logic;
port_a_we : in std_logic;
port_a_be : in std_logic_vector(DATA_WIDTH/8-1 downto 0);
port_a_addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
port_a_din : in std_logic_vector(DATA_WIDTH-1 downto 0);
port_a_dout : out std_logic_vector(DATA_WIDTH-1 downto 0);
-- Port B
port_b_clk : in std_logic;
port_b_we : in std_logic;
port_b_be : in std_logic_vector(DATA_WIDTH/8-1 downto 0);
port_b_addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
port_b_din : in std_logic_vector(DATA_WIDTH-1 downto 0);
port_b_dout : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end dual_port_ram_w_be;
architecture dual_port_ram_w_be_arch of dual_port_ram_w_be is
-- Memory formation : Byte enabled RAM is formed by laying byte RAM arrays
-- side-by-side. Read and write processes are realized by for loops iterating
-- across the byte array RAMs
-- Calculate array length, number of byte arrays
constant MEM_DEPTH : natural := 2**ADDR_WIDTH;
constant NUM_BYTE_ARRAY : natural := DATA_WIDTH/8;
-- Infer memory
type byte_array is array (0 to MEM_DEPTH-1) of std_logic_vector(7 downto 0);
type ram_type is array (NUM_BYTE_ARRAY-1 downto 0) of byte_array;
-- Zero initialize function
impure function zero_initialize return ram_type is
variable mem : ram_type;
begin
if INITIALIZE_TO_ZERO = true then
for i in 0 to MEM_DEPTH-1 loop
for byte_index in 0 to NUM_BYTE_ARRAY-1 loop
mem(byte_index)(i) := (others => '0');
end loop; -- byte_index
end loop; -- i
end if;
return mem;
end zero_initialize;
-- Constrain RAM memory to use "block", warn if not possible
shared variable RAM : ram_type := zero_initialize;
attribute ram_style : string;
attribute ram_style of RAM : variable is MEMTYPE_PAR_DIRECTIVE;
-- Temp signals
signal port_a_dout_reg : std_logic_vector(DATA_WIDTH-1 downto 0) := (others => '0');
signal port_b_dout_reg : std_logic_vector(DATA_WIDTH-1 downto 0) := (others => '0');
begin
-----------------------------------------------------------------------------
-- Port A block
-----------------------------------------------------------------------------
port_a_dout <= port_a_dout_reg;
porta_rdwr_blkgen : for i in 0 to NUM_BYTE_ARRAY-1 generate
porta_proc : process (port_a_clk)
begin -- process portb_proc
if port_a_clk'event and port_a_clk = '1' then
port_a_dout_reg((i+1)*8-1 downto i*8) <= RAM(i)(conv_integer(port_a_addr));
if port_a_we = '1' then
if port_a_be(i) = '1' then
RAM(i)(conv_integer(port_a_addr)) := port_a_din((i+1)*8-1 downto i*8);
end if;
end if;
end if;
end process porta_proc;
end generate porta_rdwr_blkgen;
-------------------------------------------------------------------------------
---- Port B
-------------------------------------------------------------------------------
port_b_dout <= port_b_dout_reg;
portb_rdwr_blkgen : for i in 0 to NUM_BYTE_ARRAY-1 generate
portb_proc : process (port_b_clk)
begin -- process portb_proc
if port_b_clk'event and port_b_clk = '1' then
port_b_dout_reg((i+1)*8-1 downto i*8) <= RAM(i)(conv_integer(port_b_addr));
if port_b_we = '1' then
if port_b_be(i) = '1' then
RAM(i)(conv_integer(port_b_addr)) := port_b_din((i+1)*8-1 downto i*8);
end if;
end if;
end if;
end process portb_proc;
end generate portb_rdwr_blkgen;
end dual_port_ram_w_be_arch;
El código anterior se sintetiza en XST y Synplify Pro. Esto compila correctamente y funciona perfectamente en FPGA sin problemas cuando se sintetiza y PARed con XST.
En Synplify Pro, recibo un error para la línea:
port_a_dout_reg((i+1)*8-1 downto i*8) <= RAM(i)(conv_integer(port_a_addr));
El error que obtengo es:
Logic for ram_0_0_4(7 downto 0) does not match a standard flip-flop
Parece que XST es indulgente con las directrices de codificación, mientras que Synplify es más estricto. ¿Puedes explicar por qué está ocurriendo el error? ¿Cómo puedo solucionarlo?
Necesito usar Synplify porque necesito hacer una copia de mi código a un dispositivo más antiguo.