zynq soc の artix-7 ファブリックに基づいてスタックを作成しています。BRAM を使用するスタックを作成するために、BRAM の読み取り出力が変化しないという問題があり、以前に BRAM を何度も使用したことがあり (7 シリーズではないため、微妙なものが欠落している可能性があります)、なぜこれを行うのかについて完全に困惑しています。
スタックに値を入力しました: 1、2、3
次に pop を連続して呼び出すと、読み取られる値は各 pop および読み取りアドレスに対して 3 だけです (1 クロックの読み取り遅延を待った後でも)。私もデュアル ポート RAM を試してみましたが、同じ問題がありました。
正しい動作を持つ配列ベースの RAM を使用して、ロジックの動作を確認しました。検証のために、次のソースのロジックもチェックしました: http://vhdlguru.blogspot.co.uk/2011/01/implementation-of-stack-in-vhdl.html。
したがって、問題は BRAM にあるように見えます。正しく読み取られていないか、何らかの理由で以前のすべてのメモリ アドレスに値 3 が書き込まれていますが、これは各データ項目が書き込み信号と正しいアドレスと同期されているため意味がありません。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use IEEE.numeric_std.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
-- Stack implementation for 32 bit data items using BRAM componenets
entity stack_32_BRAM is
generic( ADDR : integer :=32);
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
en : in STD_LOGIC;
push_pop : in STD_LOGIC;
data_in : in STD_LOGIC_VECTOR (31 downto 0);
data_out : out STD_LOGIC_VECTOR (31 downto 0));
end stack_32_BRAM;
architecture Behavioral of stack_32_BRAM is
COMPONENT BRAM_32_1K
PORT (
clka : IN STD_LOGIC;
rsta : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
douta : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
clkb : IN STD_LOGIC;
rstb : IN STD_LOGIC;
web : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
addrb : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
dinb : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT BRAM_32_1K_SP
PORT (
clka : IN STD_LOGIC;
rsta : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
douta : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
--The read ptr is a function of the write ptr
signal stack_ptr_read, stack_ptr_write : std_logic_vector(ADDR-1 downto 0) := (others =>'0');
signal full, empty : std_logic := '0';
signal WEA : std_logic_vector(3 downto 0) :=(others=>'0'); -- 4-bit input: A port write enable
signal addra, addrb, dinb, doutb, dina, douta : std_logic_vector(31 downto 0) := (others => '0');
signal rsta, rstb :std_logic := '0' ;
type ram is array (4 downto -2) of std_logic_vector(31 downto 0) ;
signal mem : ram :=(others=>(others=>'0'));
begin
---STACK LOGIC ---
PUSH : process (clk, push_pop, en, full, empty)
begin
if(clk'event and clk='1') then
WEA <= "0000";
if(en='1' and push_pop = '1' and full = '0') then
mem(to_integer(unsigned(stack_ptr_write))) <= data_in;
WEA <= "1111";
dina <= data_in ;
ADDRA <= stack_ptr_write;
stack_ptr_write <= stack_ptr_write + 1;
elsif(en='1' and push_pop = '0' and empty = '0') then
data_out <= douta ;--
doutb <= mem(to_integer(unsigned(stack_ptr_write - 1)));
ADDRA <= stack_ptr_write - 1;
stack_ptr_write <= stack_ptr_write - 1;
end if;
end if;
end process;
BRAM_SP : BRAM_32_1K_SP
PORT MAP (
clka => clk,
rsta => rsta,
wea => wea,
addra => addra,
dina => dina,
douta => douta
);
end Behavioral;
どうもありがとうサム