Я пытаюсь реализовать FIFO (в VHDL), но в тот момент, когда я запускаю testbench, симуляция показывает только 165 нс, когда я устанавливаю время на 800ns. Я получаю его, чтобы запустить 800ns, когда я прокомментирую строку, которая присваивает push_valid_i 1 в тестовом банке (в «Цикл 2»). Это, похоже, проблема с реализацией, верно? На всякий случай, я запускаю Xilinx ISE 14.7 на ubuntu 64. Вот реализация на тестовом стенде.ISim не работает полное время моделирования [VHDL - Xilinx ISE]
Реализация:
library IEEE;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
use WORK.my_pkg.ALL;
entity Fifo is
Port(
clk : in STD_LOGIC;
rst_n : in STD_LOGIC;
-- DATA
push_data_i : in STD_LOGIC_VECTOR (FIFO_WIDTH-1 downto 0); -- Data IN.
pop_data_o : out STD_LOGIC_VECTOR (FIFO_WIDTH-1 downto 0); -- Data out.
-- CONTROL
push_valid_i : in STD_LOGIC; -- 1 to write push_data_i into the FIFO.
pop_grant_i : in STD_LOGIC; -- 1 to read from the FIFO.
-- STATUS
push_grant_o : out STD_LOGIC; -- 0 when full. To write push_grant_o=1 and push_valid_i=1.
pop_valid_o : out STD_LOGIC; -- 1 where there is data available in the FIFO.
-- TEST/DEBUG Purpose only
PORT_write_ptr_reg : out STD_LOGIC_VECTOR (FIFO_DEPTH-1 downto 0);
PORT_write_ptr_next : out STD_LOGIC_VECTOR (FIFO_DEPTH-1 downto 0);
PORT_write_ptr_succ : out STD_LOGIC_VECTOR (FIFO_DEPTH-1 downto 0);
PORT_read_ptr_reg : out STD_LOGIC_VECTOR (FIFO_DEPTH-1 downto 0);
PORT_read_ptr_next : out STD_LOGIC_VECTOR (FIFO_DEPTH-1 downto 0);
PORT_read_ptr_succ : out STD_LOGIC_VECTOR (FIFO_DEPTH-1 downto 0);
PORT_full_reg, PORT_empty_reg, PORT_full_next, PORT_empty_next, PORT_wr_en : out STD_LOGIC;
PORT_operation : out STD_LOGIC_VECTOR (1 downto 0)
);
end Fifo;
architecture Behavioral of Fifo is
type reg_type is array (FIFO_DEPTH-1 downto 0) of STD_LOGIC_VECTOR (FIFO_WIDTH-1 downto 0); -- FIFO_WIDTH x FIFO_DEPTH 2D-array.
signal array_reg : reg_type; -- FIFO itself. Data is stored here.
signal write_ptr_reg, write_ptr_next, write_ptr_succ : STD_LOGIC_VECTOR (FIFO_DEPTH-1 downto 0); -- Write control registers.
signal read_ptr_reg, read_ptr_next, read_ptr_succ : STD_LOGIC_VECTOR (FIFO_DEPTH-1 downto 0); -- Read control registers.
signal full_reg, full_next : STD_LOGIC := '0'; -- Status registers
signal empty_reg, empty_next : STD_LOGIC := '1'; -- Status registers
signal operation : STD_LOGIC_VECTOR (1 downto 0) := "00"; -- Operation 2 bit array
signal wr_en: STD_LOGIC; -- Write possible register.
begin
-- ** PUSH & POP PORTS (data) ** --
process(clk, rst_n)
begin
if(rst_n='0') then
array_reg <= (others=>(others=>'0')); -- Sets the entire array_reg (2D-array) to 0.
write_ptr_reg <= (others=>'0'); -- Resets all write registers (to 0).
read_ptr_reg <= (others=>'0'); -- Resets all read registers (to 0).
full_reg <= '0'; -- Full register is set to 0 as FIFO is not FULL.
empty_reg <= '1'; -- Empty register is set to 1 as FIFO is empty.
elsif (clk'event and clk='1') then -- Rising edge of the clock.
if (wr_en='1') then
array_reg(to_integer(unsigned(write_ptr_reg))) <= push_data_i; -- It writes the incoming data (push_data_i) to the corresponding position in the FIFO.
-- It expects an intiger as the position in the array. Therefore the 'to_intiger' function.
write_ptr_reg <= write_ptr_next; -- Current write position becomes the next one on clock event.
read_ptr_reg <= read_ptr_next; -- Current read position becomes the next one on clock event.
full_reg <= full_next; -- Current full position becomes the next one on clock event.
empty_reg <= empty_next; -- Current empty position becomes the next one on clock event.
end if;
end if;
end process;
-- Input port:
wr_en <= push_valid_i and (not full_reg); -- If FIFO is NOT full it is possible to write.
push_grant_o <= (not full_reg); -- Outputs if the FIFO is FULL (push_grant_o=0)
-- Output port:
-- It is done differently from the input port as the output data ('first-in', pointed by read_ptr_reg)has to be available all the time.
pop_data_o <= array_reg(to_integer(unsigned(read_ptr_reg)));
-- Successive values to read and write when requested.
write_ptr_succ <= STD_LOGIC_VECTOR(unsigned(write_ptr_reg)+1);
read_ptr_succ <= STD_LOGIC_VECTOR(unsigned(read_ptr_reg)+1);
-- ** Events and register control ** --
operation <= (push_valid_i & pop_grant_i); -- Concatenates the two control inputs for the 'case, when' statement.
process(write_ptr_reg, write_ptr_succ, read_ptr_reg, read_ptr_succ,
operation, full_reg, empty_reg)
begin
write_ptr_next <= write_ptr_reg; -- This for lines are to assure that the current state does not
read_ptr_next <= read_ptr_reg; -- change in case none of the case-when statements happen.
full_next <= full_reg;
empty_next <= empty_reg;
case operation is
when "00" => -- Not write (push) or read (pop).
when "01" => -- Read.
if(empty_reg /= '1') then -- If FIFO is NOT empty, it can be read.
read_ptr_next <= read_ptr_succ; -- It points to the successive position to read.
full_next <= '0'; -- As one position is read, FIFO will NOT be full.
if(read_ptr_succ=write_ptr_reg) then -- Read 'reached' write. So the FIFO will be EMPTY.
empty_next <= '1';
end if;
end if;
when "10" => -- Write.
if(full_reg /='1') then -- If FIFO is NOT full, it can be written.
write_ptr_next <= write_ptr_succ;
empty_next <= '0'; -- The FIFO is written, so it will NOT be empty.
if(write_ptr_succ=read_ptr_reg) then -- Write 'reached' read, so the FIFO will be full.
full_next <= '1';
end if;
end if;
when others => -- Write and Read at the same time.
write_ptr_next <= write_ptr_succ;
read_ptr_next <= read_ptr_succ;
end case;
end process;
-- Output STATUS
push_grant_o <= not full_reg;
pop_valid_o <= not empty_reg;
-- TEST/DEBUG ONLY
PORT_write_ptr_reg <= write_ptr_reg;
PORT_write_ptr_next <= write_ptr_next;
PORT_write_ptr_succ <= write_ptr_succ;
PORT_read_ptr_reg <= read_ptr_reg;
PORT_read_ptr_next <= read_ptr_next;
PORT_read_ptr_succ <= read_ptr_succ;
PORT_full_reg <= full_reg;
PORT_empty_reg <= empty_reg;
PORT_full_next <= full_next;
PORT_empty_next <= empty_next;
PORT_wr_en <= wr_en;
PORT_operation <= (push_valid_i & pop_grant_i);
end Behavioral;
Пользовательская библиотека 'my_pkg':
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package my_pkg is
constant FIFO_DEPTH : positive := 4;
constant DATA_WIDTH : positive := 3;
constant FIFO_WIDTH : positive := DATA_WIDTH+1; --DATAWIDTH=WIDTH+1bitParity
constant PARITY : bit := '0'; -- EVEN or ODD.
constant PARITY_BIT : bit := '0'; -- LSB or MSB.
end my_pkg;
Я использовал постоянный тип, как это должно быть синтезируемого, и я читал, что переменная не является.
Испытательный стенд:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY Fifo_testbench IS
END Fifo_testbench;
ARCHITECTURE behavior OF Fifo_testbench IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT Fifo
PORT(
clk : IN std_logic;
rst_n : IN std_logic;
push_data_i : IN std_logic_vector(3 downto 0);
pop_data_o : OUT std_logic_vector(3 downto 0);
push_valid_i : IN std_logic;
pop_grant_i : IN std_logic;
push_grant_o : OUT std_logic;
pop_valid_o : OUT std_logic;
PORT_write_ptr_reg : OUT std_logic_vector(3 downto 0);
PORT_write_ptr_next : OUT std_logic_vector(3 downto 0);
PORT_write_ptr_succ : OUT std_logic_vector(3 downto 0);
PORT_read_ptr_reg : OUT std_logic_vector(3 downto 0);
PORT_read_ptr_next : OUT std_logic_vector(3 downto 0);
PORT_read_ptr_succ : OUT std_logic_vector(3 downto 0);
PORT_full_reg : OUT std_logic;
PORT_empty_reg : OUT std_logic;
PORT_full_next : OUT std_logic;
PORT_empty_next : OUT std_logic;
PORT_wr_en : OUT std_logic;
PORT_operation : OUT std_logic_vector(1 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal rst_n : std_logic := '0';
signal push_data_i : std_logic_vector(3 downto 0) := (others => '0');
signal push_valid_i : std_logic := '0';
signal pop_grant_i : std_logic := '0';
--Outputs
signal pop_data_o : std_logic_vector(3 downto 0);
signal push_grant_o : std_logic;
signal pop_valid_o : std_logic;
signal PORT_write_ptr_reg : std_logic_vector(3 downto 0);
signal PORT_write_ptr_next : std_logic_vector(3 downto 0);
signal PORT_write_ptr_succ : std_logic_vector(3 downto 0);
signal PORT_read_ptr_reg : std_logic_vector(3 downto 0);
signal PORT_read_ptr_next : std_logic_vector(3 downto 0);
signal PORT_read_ptr_succ : std_logic_vector(3 downto 0);
signal PORT_full_reg : std_logic;
signal PORT_empty_reg : std_logic;
signal PORT_full_next : std_logic;
signal PORT_empty_next : std_logic;
signal PORT_wr_en : std_logic;
signal PORT_operation : std_logic_vector(1 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Fifo PORT MAP (
clk => clk,
rst_n => rst_n,
push_data_i => push_data_i,
pop_data_o => pop_data_o,
push_valid_i => push_valid_i,
pop_grant_i => pop_grant_i,
push_grant_o => push_grant_o,
pop_valid_o => pop_valid_o,
PORT_write_ptr_reg => PORT_write_ptr_reg,
PORT_write_ptr_next => PORT_write_ptr_next,
PORT_write_ptr_succ => PORT_write_ptr_succ,
PORT_read_ptr_reg => PORT_read_ptr_reg,
PORT_read_ptr_next => PORT_read_ptr_next,
PORT_read_ptr_succ => PORT_read_ptr_succ,
PORT_full_reg => PORT_full_reg,
PORT_empty_reg => PORT_empty_reg,
PORT_full_next => PORT_full_next,
PORT_empty_next => PORT_empty_next,
PORT_wr_en => PORT_wr_en,
PORT_operation => PORT_operation
);
-- Clock process definitions
clk_process :process
begin
clk <= '1';
wait for clk_period/2;
clk <= '0';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 20 ns;
rst_n <= '1';
wait for clk_period;
-- Cycle 2
push_valid_i <= '1';
push_data_i <= "0001";
wait for clk_period;
wait;
end process;
END;
Вот снимок экрана, когда push_valid_i < = '1' комментирует: https://ibb.co/koy0dv
Вот снимок экрана, когда push_valid_i < = '1' не прокомментировал : https://ibb.co/mxiSQa
Спасибо за помощь.
Источник для пакета my_package не включен. FIFO_DEPTH нельзя использовать как ширину двоичного адреса ('signal write_ptr_reg, write_ptr_next, write_ptr_succ: STD_LOGIC_VECTOR (FIFO_DEPTH-1 до 0); read_ptr_reg, read_ptr_next, read_ptr_succ: STD_LOGIC_VECTOR (FIFO_DEPTH-1 downto 0);') и массив size ('type reg_type - это массив (FIFO_DEPTH - 1 до 0) STD_LOGIC_VECTOR (FIFO_WIDTH-1 до 0);'). 2, увеличенный до ширины ptr в битах, является размером массива. Поверните привязку к проверке. Исправьте размер массива или ширину ptr, и ваш тестовый тест будет работать до остановки (часы бесплатны). – user1155120
FIFO можно увеличить по глубине, чтобы соответствовать адресу: 'type reg_type - это массив (2 ** FIFO_DEPTH - 1 до 0) STD_LOGIC_VECTOR (FIFO_WIDTH - 1 downto 0);'. – user1155120
Вы можете объяснить, как симуляция останавливается при 165ns: есть ли в окне консоли какие-либо ASSERT или REPORTS, рассказывающие вам, что пошло не так? –