Ich habe ein Projekt mit mehreren abgeleiteten Dual-Port-RAM-Blöcken. Der Code für dieses Dual-Port-RAM lautet wie folgt:
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;
Der obige Code wird in XST und Synplify Pro synthetisiert. Dies wird korrekt kompiliert und funktioniert perfekt auf FPGA ohne Probleme, wenn es mit XST synthetisiert und PARed wird.
In Synplify Pro erhalte ich einen Fehler für die Zeile:
port_a_dout_reg((i+1)*8-1 downto i*8) <= RAM(i)(conv_integer(port_a_addr));
Der Fehler, den ich bekomme, ist:Logic for ram_0_0_4(7 downto 0) does not match a standard flip-flop
Es sieht so aus, als ob XST mit Codierungsrichtlinien nachsichtig ist, während Synplify strenger ist. Können Sie erklären, warum der Fehler auftritt? Wie kann ich es lösen?
Ich muss Synplify verwenden, weil ich meinen Code auf ein älteres Gerät zurückportieren muss.
In Ordnung ... Ich habe vielleicht die Lösung herausgefunden. Die Lösung besteht darin, die Anzahl der verschachtelten Bedingungen zu reduzieren. Auf diese Weise denkt der Synthesizer nicht daran, dass das Flip-Flop mehrere Ebenen von Steuersignalen hat.
-- Write process
porta_write_blkgen : for i in 0 to NUM_BYTE_ARRAY-1 generate
porta_wrproc : process (port_a_be, port_a_clk, port_a_we)
begin -- process portb_proc
if port_a_clk'event and port_a_clk = '1' and port_a_we = '1' and 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 process porta_wrproc;
end generate porta_write_blkgen;
Synplify scheint in diesen Dingen umständlicher zu sein als die Xilinx-Tools.
Ich habe die Lösung auf FPGA getestet und es scheint in Ordnung zu sein.
RRS