Commit 8452ca3a authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

swcore: multiport LL rewritten to use multiport RAM with 2 write ports

parent 68dda3e8
......@@ -3,17 +3,17 @@
-- Project : WhiteRabbit switch
-------------------------------------------------------------------------------
-- File : swc_multiport_linked_list.vhd
-- Author : Maciej Lipinski
-- Company : CERN BE-Co-HT
-- Author : Maciej Lipinski, Grzegorz Daniluk
-- Company : CERN BE-CO-HT
-- Created : 2010-10-26
-- Last update: 2012-03-18
-- Last update: 2016-08-26
-- Platform : FPGA-generic
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
--
-- Copyright (c) 2010 - 2012 CERN / BE-CO-HT
-- Copyright (c) 2010 - 2016 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
......@@ -37,12 +37,15 @@
-- 2010-10-26 1.0 mlipinsk Created
-- 2012-02-02 2.0 mlipinsk generic-azed
-- 2012-02-16 3.0 mlipinsk speeded up & adapted to cut-through & adapted to new MPM
-- 2016-08-26 4.0 greg.d rewritten to use multiport RAM with multiple IB write ports
-- also cleaned up IB write arbiter, now uses simple FSM
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use ieee.math_real.CEIL;
use ieee.math_real.log2;
......@@ -114,39 +117,89 @@ entity swc_multiport_linked_list is
end swc_multiport_linked_list;
architecture syn of swc_multiport_linked_list is
---------------------- writing process --------------------------------
-- arbitrating writing process
signal write_request_vec : std_logic_vector(g_num_ports-1 downto 0);
signal write_grant_vec : std_logic_vector(g_num_ports-1 downto 0);
signal write_grant_vec_d0 : std_logic_vector(g_num_ports-1 downto 0);
signal write_grant_vec_d1 : std_logic_vector(g_num_ports-1 downto 0);
signal write_grant_index : integer range 0 to g_num_ports-1;
signal write_grant_index_d0 : integer range 0 to g_num_ports-1;
signal write_request_noempty : std_logic;
signal write_done : std_logic_vector(g_num_ports-1 downto 0);
signal in_sel_write : integer range 0 to g_num_ports-1;
-- signals used by writing process
signal ll_write_ena : std_logic;
signal ll_write_next_ena : std_logic;
signal ll_write_addr : std_logic_vector(g_addr_width - 1 downto 0);
signal ll_write_next_addr : std_logic_vector(g_addr_width - 1 downto 0);
signal ll_write_data : std_logic_vector(g_data_width - 1 downto 0);
signal ll_write_data_valid : std_logic;
signal ll_write_end_of_list : std_logic;
signal tmp_write_end_of_list : std_logic_vector(g_num_ports-1 downto 0);
-- signal connected directly to DPRAM (driven/multiplexd by the above
signal ll_wr_addr : std_logic_vector(g_addr_width - 1 downto 0);
signal ll_wr_data : std_logic_vector(g_data_width - 1 downto 0);
signal ll_wr_ena : std_logic;
signal ll_wr_addr_reg : std_logic_vector(g_addr_width - 1 downto 0);
signal ll_wr_data_reg : std_logic_vector(g_data_width - 1 downto 0);
signal ll_wr_ena_reg : std_logic;
constant c_MPRAM_WPORTS : integer := 2;
constant c_MPRAM_RPORTS : integer := 2;
component mpram_lvt
generic (
MEMD : integer;
DATW : integer;
nRPF : integer;
nWPF : integer;
nRPS : integer;
nWPS : integer;
LVTA : string;
WAWB : integer;
RAWB : integer;
RDWB : integer);
port (
clk : in std_logic;
rdWr : in std_logic;
WEnb : in std_logic_vector(nWPF+nWPS-1 downto 0);
WAddr : in std_logic_vector(f_log2_size(MEMD)*(nWPF+nWPS)-1 downto 0);
WData : in std_logic_vector(DATW*(nWPF+nWPS)-1 downto 0);
RAddr : in std_logic_vector(f_log2_size(MEMD)*(nRPF+nRPS)-1 downto 0);
RData : out std_logic_vector(DATW*(nRPF+nRPS)-1 downto 0));
end component;
--------------------------------------
-- packing interfaces into records --
--------------------------------------
-- free_pck interface
type t_fp2ll is record
rd_req : std_logic;
adr : std_logic_vector(g_addr_width-1 downto 0);
end record;
type t_fp2ll_array is array (natural range <>) of t_fp2ll;
type t_ll2fp is record
data : std_logic_vector(g_data_width-1 downto 0);
rd_done : std_logic;
end record;
type t_ll2fp_array is array (natural range <>) of t_ll2fp;
signal free_pck_in : t_fp2ll_array(g_num_ports-1 downto 0);
signal free_pck_out: t_ll2fp_array(g_num_ports-1 downto 0);
-- IB write interface
signal x_wadr_in : t_lladr_array(g_num_ports-1 downto 0);
signal x_wnextadr_in : t_lladr_array(g_num_ports-1 downto 0);
signal x_wdat_in : t_lldat_array(g_num_ports-1 downto 0);
signal write_done_out: std_logic_vector(g_num_ports-1 downto 0);
--------------------------------------
-- MPRAM signals --
--------------------------------------
-- packing i/f into records
signal mpram_wadr : std_logic_vector(c_MPRAM_WPORTS*g_addr_width-1 downto 0);
signal mpram_wdat : std_logic_vector(c_MPRAM_WPORTS*g_data_width-1 downto 0);
signal mpram_radr : std_logic_vector(c_MPRAM_RPORTS*g_addr_width-1 downto 0);
signal mpram_rdat : std_logic_vector(c_MPRAM_RPORTS*g_data_width-1 downto 0);
signal x_mpram_wadr, x_mpram_wadr_d0 : t_lladr_array(c_MPRAM_WPORTS-1 downto 0);
signal x_mpram_wdat, x_mpram_wdat_d0 : t_lldat_array(c_MPRAM_WPORTS-1 downto 0);
signal x_mpram_radr : t_lladr_array(c_MPRAM_RPORTS-1 downto 0);
signal x_mpram_rdat : t_lldat_array(c_MPRAM_RPORTS-1 downto 0);
signal mpram_write : std_logic_vector(c_MPRAM_WPORTS-1 downto 0);
--------------------------------------
-- writing process --
--------------------------------------
type t_mll_fsm is (WRITE, WRITE_NEXT);
type t_mll_fsm_array is array (natural range <>) of t_mll_fsm;
type t_llports_array is array (natural range <>) of std_logic_vector(g_num_ports-1 downto 0);
type t_int_array is array (natural range <>) of integer range 0 to g_num_ports-1;
signal mll_state : t_mll_fsm_array(c_MPRAM_WPORTS-1 downto 0);
signal write_req : t_llports_array(c_MPRAM_WPORTS-1 downto 0);
signal write_i_split : t_llports_array(c_MPRAM_WPORTS-1 downto 0);
signal write_grant : t_llports_array(c_MPRAM_WPORTS-1 downto 0);
signal write_grant_d0 : t_llports_array(c_MPRAM_WPORTS-1 downto 0);
signal write_idx : t_int_array(c_MPRAM_WPORTS-1 downto 0);
signal write_done : std_logic_vector(c_MPRAM_WPORTS-1 downto 0);
signal wadr_sel : std_logic_vector(c_MPRAM_WPORTS-1 downto 0);
---------------------- reading process (free pck module) --------------------------------
-- arbitrating access
signal free_pck_request_vec : std_logic_vector(g_num_ports-1 downto 0);
......@@ -158,202 +211,191 @@ architecture syn of swc_multiport_linked_list is
signal free_pck_grant_index_d0 : integer range 0 to g_num_ports-1;
signal free_pck_grant_valid : std_logic;
signal free_pck_grant_valid_d0 : std_logic;
signal free_pck_read : std_logic_vector(g_num_ports -1 downto 0);
signal free_pck_read_done : std_logic_vector(g_num_ports -1 downto 0);
-- interface to DPRAM
signal ll_free_pck_ena : std_logic;
signal ll_free_pck_addr : std_logic_vector(g_addr_width - 1 downto 0);
signal ll_free_pck_data : std_logic_vector(g_data_width - 1 downto 0);
-- output
type t_ll_data_array is array (g_num_ports-1 downto 0) of std_logic_vector(g_data_width - 1 downto 0);
signal free_pck_data : t_ll_data_array;
signal free_pck_data_out : t_ll_data_array;
signal free_pck_data : t_lldat_array(g_num_ports-1 downto 0);
signal free_pck_data_out : t_lldat_array(g_num_ports-1 downto 0);
-- helper
signal zeros : std_logic_vector(g_num_ports-1 downto 0);
----------------- translate one hot to binary --------------------------
function f_one_hot_to_binary (
One_Hot : std_logic_vector
) return integer is
variable Bin_Vec_Var : integer range 0 to One_Hot'length -1;
begin
Bin_Vec_Var := 0;
signal zeros : std_logic_vector(g_num_ports-1 downto 0);
for I in 0 to (One_Hot'length - 1) loop
if One_Hot(I) = '1' then
Bin_Vec_Var := I;
end if;
end loop;
return Bin_Vec_Var;
end function;
-----------------------------------------------------------------------
begin -- syn
begin
zeros <= (others => '0');
PAGE_INDEX_LINKED_LIST_MPM: swc_rd_wr_ram
generic map (
g_data_width => g_data_width,-- one bit for validating the data
g_size => g_page_num)
port map (
clk_i => clk_i,
we_i => ll_wr_ena_reg,
wa_i => ll_wr_addr_reg,
wd_i => ll_wr_data_reg,
ra_i => mpm_rpath_addr_i,
rd_o => mpm_rpath_data_o);
---- this memory is read by the output of the MPM (called read pump)
--PAGE_INDEX_LINKED_LIST_MPM : generic_dpram
-- generic map (
-- g_data_width => g_data_width,-- one bit for validating the data
-- g_size => g_page_num,
-- g_dual_clock=> false
-- )
-- port map (
-- -- Port A -- writing
-- clka_i => clk_i,
-- bwea_i => (others => '1'),
-- wea_i => ll_wr_ena_reg,
-- aa_i => ll_wr_addr_reg,
-- da_i => ll_wr_data_reg,
-- qa_o => open,
-- -- Port B -- reading
-- clkb_i => clk_i,
-- bweb_i => (others => '1'),
-- web_i => '0',
-- ab_i => mpm_rpath_addr_i,
-- db_i => (others => '0'),
-- qb_o => mpm_rpath_data_o
-- );
PAGE_INDEX_LINKED_LIST_FREE_PCK: swc_rd_wr_ram
-- wiring input std_logic_vectors into types
GEN_WIRING: for I in 0 to g_num_ports-1 generate
x_wadr_in(I) <= write_addr_i((I+1)*g_addr_width-1 downto I*g_addr_width);
x_wnextadr_in(I) <= write_next_addr_i((I+1)*g_addr_width-1 downto I*g_addr_width);
x_wdat_in(I) <= write_data_i((I+1)*g_data_width-1 downto I*g_data_width);
free_pck_in(I).rd_req <= free_pck_rd_req_i(I);
free_pck_in(I).adr <= free_pck_addr_i((I+1)*g_addr_width-1 downto I*g_addr_width);
free_pck_read_done_o(I) <= free_pck_out(I).rd_done;
free_pck_data_o((I+1)*g_data_width-1 downto I*g_data_width) <= free_pck_out(I).data;
end generate;
SWITCHED_MPRAM: mpram_lvt
generic map (
g_data_width => g_data_width,
g_size => g_page_num)
MEMD => g_page_num,
DATW => g_data_width,
nRPF => c_MPRAM_RPORTS,
nWPF => c_MPRAM_WPORTS,
nRPS => 0,
nWPS => 0,
LVTA => "LVTREG",
WAWB => 0,
RAWB => 0,
RDWB => 1)
port map (
clk_i => clk_i,
we_i => ll_wr_ena_reg,
wa_i => ll_wr_addr_reg,
wd_i => ll_wr_data_reg,
ra_i => ll_free_pck_addr,
rd_o => ll_free_pck_data);
---- this memory is read by the process that force-frees pck on error
--PAGE_INDEX_LINKED_LIST_FREE_PCK : generic_dpram
-- generic map (
-- g_data_width => g_data_width,-- one bit for validating the data
-- g_size => g_page_num
-- )
-- port map (
-- -- Port A -- writing
-- clka_i => clk_i,
-- bwea_i => (others => '1'),
-- wea_i => ll_wr_ena_reg,
-- aa_i => ll_wr_addr_reg,
-- da_i => ll_wr_data_reg,
-- qa_o => open,
-- -- Port B -- reading
-- clkb_i => clk_i,
-- bweb_i => (others => '1'),
-- web_i => '0',
-- ab_i => ll_free_pck_addr,
-- db_i => (others => '0'),
-- qb_o => ll_free_pck_data
-- );
gen_write_request_vec : for i in 0 to g_num_ports - 1 generate
tmp_write_end_of_list(i) <= write_data_i((i + 1) * g_data_width - 2);
--write_request_vec(i) <= write_i(i) and (not ((tmp_write_end_of_list(i) and write_grant_vec_d0(i)) or write_grant_vec_d1(i)));
write_request_vec(i) <= write_i(i) and (not ((not write_next_addr_valid_i(i) and write_grant_vec_d0(i)) or write_grant_vec_d1(i)));
clk => clk_i,
rdWr => '0',
WEnb => mpram_write,
WAddr => mpram_wadr,
WData => mpram_wdat,
RAddr => mpram_radr,
RData => mpram_rdat);
-- pack MPRAM interfaces into types
mpram_wadr <= x_mpram_wadr_d0(1) & x_mpram_wadr_d0(0);
mpram_wdat <= x_mpram_wdat_d0(1) & x_mpram_wdat_d0(0);
mpram_radr <= x_mpram_radr(1) & x_mpram_radr(0);
x_mpram_rdat(0) <= mpram_rdat(g_data_width-1 downto 0);
x_mpram_rdat(1) <= mpram_rdat(2*g_data_width-1 downto g_data_width);
-- MPM read interface
x_mpram_radr(0) <= mpm_rpath_addr_i;
mpm_rpath_data_o <= x_mpram_rdat(0);
-- Free PCK read interface
x_mpram_radr(1) <= free_pck_in(free_pck_grant_index).adr;
ll_free_pck_data <= x_mpram_rdat(1);
--------------------------------------
-- Serving write requests from IBs --
--------------------------------------
-- we split IBs into two write ports
write_i_split(0) <= (zeros(g_num_ports/c_MPRAM_WPORTS downto 0) &
write_i(g_num_ports/c_MPRAM_WPORTS-1 downto 0));
write_i_split(1) <= (write_i(g_num_ports-1 downto g_num_ports/c_MPRAM_WPORTS) &
zeros(g_num_ports/c_MPRAM_WPORTS-1 downto 0));
write_done_out <= (write_grant_d0(0) or write_grant_d0(1)) when(write_done = "11") else
write_grant_d0(0) when(write_done = "01") else
write_grant_d0(1) when(write_done = "10") else
(others=>'0');
GEN_WRFSM: for I in 0 to c_MPRAM_WPORTS-1 generate
write_idx(I) <= to_integer(unsigned(f_onehot_decode(write_grant(I), g_num_ports)));
-- select address to be written to MPRAM. For requests with
-- write_next_addr_valid = 1 we prefer to write first the "next address" to
-- invalidate this page as soon as possible. Otherwise the output or freeing
-- module could fetch incorrect data for that page.
x_mpram_wadr(I) <= x_wnextadr_in(write_idx(I)) when(write_next_addr_valid_i(write_idx(I)) = '1' and wadr_sel(I)='0') else
x_wadr_in(write_idx(I));
-- the same way we select data to be written with the above address. It's
-- either data passed with the request from the IB or zeros to invalidate
-- next page (next addr from the request).
x_mpram_wdat(I) <= (others=>'0') when (write_next_addr_valid_i(write_idx(I)) = '1' and wadr_sel(I)='0') else
x_wdat_in(write_idx(I));
f_rr_arbitrate(write_req(I), write_grant_d0(I), write_grant(I));
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i='0' then
mll_state(I) <= WRITE;
wadr_sel(I) <= '0';
write_grant_d0(I) <= (others=>'0');
write_req(I) <= (others=>'0');
write_done(I) <= '0';
x_mpram_wadr_d0(I)<= (others=>'0');
x_mpram_wdat_d0(I)<= (others=>'0');
else
-- address and data delayed by 1 cycle to align with mpram_write from
-- the state machine.
x_mpram_wadr_d0(I)<= x_mpram_wadr(I);
x_mpram_wdat_d0(I)<= x_mpram_wdat(I);
case(mll_state(I)) is
when WRITE =>
if (or_reduce(write_grant(I)) = '1' and write_next_addr_valid_i(write_idx(I))='1') then
mll_state(I) <= WRITE_NEXT;
wadr_sel(I) <= '1'; -- switch the address to be written
mpram_write(I) <= '1';
write_done(I) <= '0';
elsif (or_reduce(write_grant(I)) = '1') then
wadr_sel(I) <= '0';
mpram_write(I) <= '1';
write_done(I) <= '1';
write_grant_d0(I) <= write_grant(I);
write_req(I) <= write_i_split(I) and (not write_grant(I)) and (not write_grant_d0(I));
else
wadr_sel(I) <= '0';
mpram_write(I) <= '0';
write_done(I) <= '0';
write_grant_d0(I) <= write_grant(I);
write_req(I) <= write_i_split(I) and (not write_grant(I)) and (not write_grant_d0(I));
end if;
when WRITE_NEXT =>
mpram_write(I) <= '1';
wadr_sel(I) <= '0';
write_done(I) <= '1';
write_grant_d0(I) <= write_grant(I);
write_req(I) <= write_i_split(I) and (not write_grant(I)) and (not write_grant_d0(I));
mll_state(I) <= WRITE;
when others =>
mll_state(I) <= WRITE;
end case;
end if;
end if;
end process;
end generate;
---------------------------------------
-- Scheduling free requests from the --
-- freeing module. --
---------------------------------------
gen_free_pck_request_vec : for i in 0 to g_num_ports - 1 generate
free_pck_request_vec(i) <= free_pck_read(i) and (not (free_pck_grant_vec_d0(i) or free_pck_grant_vec_d1(i)));
end generate;
-- writing
f_rr_arbitrate(req => write_request_vec,
pre_grant=> write_grant_vec_d0,
grant => write_grant_vec);
write_grant_index <= f_one_hot_to_binary(write_grant_vec_d0) ;
write_request_noempty <= '1' when (write_request_vec /= zeros) else '0';
-- reading
f_rr_arbitrate(req => free_pck_request_vec,
pre_grant=> free_pck_grant_vec_d0,
grant => free_pck_grant_vec);
free_pck_grant_index <= f_one_hot_to_binary(free_pck_grant_vec_d0) ;
free_pck_grant_index <= to_integer(unsigned(f_onehot_decode(free_pck_grant_vec_d0, g_num_ports)));
free_pck_request_noempty <= '1' when (free_pck_request_vec /= zeros) else '0';
-- ======= writing =======
-- mux input data for the port to which access is granted
ll_write_data <= write_data_i((write_grant_index + 1) * g_data_width - 1 downto write_grant_index * g_data_width);
ll_write_addr <= write_addr_i((write_grant_index + 1) * g_addr_width - 1 downto write_grant_index * g_addr_width);
ll_write_data_valid <= write_data_i((write_grant_index + 1) * g_data_width - 1); -- MSB bit
ll_write_end_of_list<= write_data_i((write_grant_index + 1) * g_data_width - 2); -- MSB -1 bit
--ll_write_next_addr <= ll_write_data(g_addr_width - 1 downto 0);
ll_write_next_addr <= write_next_addr_i((write_grant_index + 1) * g_addr_width - 1 downto write_grant_index * g_addr_width);
-- create data and address to be written to memory (both DPRAMs)
-- ll_wr_data <= (others => '0') when (ll_write_next_ena = '1' ) else ll_write_data;
--reversing the order (16/03/2012) of writing current/cleaning next page
ll_wr_data <= ll_write_data when (ll_write_next_ena = '1' and write_next_addr_valid_i(write_grant_index) = '1') else
(others => '0') when (ll_write_ena = '1' and write_next_addr_valid_i(write_grant_index) = '1') else
ll_write_data;-- when (ll_write_ena = '1' and write_next_addr_valid_i(write_grant_index) = '0') else
--(others => '0'); -- this should not happen
-- ll_wr_addr <= ll_write_next_addr when (ll_write_next_ena = '1' ) else ll_write_addr;
--reversing the order (16/03/2012) of writing current/cleaning next page
ll_wr_addr <= ll_write_addr when (ll_write_next_ena = '1' and write_next_addr_valid_i(write_grant_index) = '1') else
ll_write_next_addr when (ll_write_ena = '1' and write_next_addr_valid_i(write_grant_index) = '1') else
ll_write_addr;-- when (ll_write_ena = '1' and write_next_addr_valid_i(write_grant_index) = '0') else
--(others => '1'); -- this should not happen
ll_write_ena <= (write_grant_vec (write_grant_index) and write_grant_vec_d0(write_grant_index) and write_next_addr_valid_i(write_grant_index)) or
(write_grant_vec_d0(write_grant_index) and not write_next_addr_valid_i(write_grant_index));
ll_write_next_ena <= write_grant_vec_d0(write_grant_index) and write_grant_vec_d1(write_grant_index);
-- ======= reading (read pump) =======
-- address
ll_free_pck_addr <= free_pck_addr_i((free_pck_grant_index + 1) * g_addr_width - 1 downto free_pck_grant_index * g_addr_width);
process(clk_i, rst_n_i)
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
free_pck_grant_vec_d0 <= (others => '0' );
free_pck_grant_vec_d1 <= (others => '0' );
free_pck_grant_valid <= '0';
free_pck_grant_valid_d0 <= '0';
free_pck_grant_index_d0 <= 0;
write_grant_vec_d0 <= (others => '0' );
write_grant_vec_d1 <= (others => '0' );
write_grant_index_d0 <= 0;
else
free_pck_grant_vec_d0 <= free_pck_grant_vec;
free_pck_grant_vec_d1 <= free_pck_grant_vec_d0;
free_pck_grant_index_d0 <= free_pck_grant_index;
free_pck_grant_valid <= free_pck_request_noempty; -- we always get grant in 1-cycle
free_pck_grant_valid_d0 <= free_pck_grant_valid;
write_grant_vec_d0 <= write_grant_vec;
write_grant_vec_d1 <= write_grant_vec_d0;
write_grant_index_d0 <= write_grant_index;
end if;
end if;
end process;
......@@ -365,64 +407,36 @@ begin -- syn
read_data_valid: swc_ll_read_data_validation
generic map(
g_addr_width => g_addr_width,
g_data_width => g_data_width
g_data_width => g_data_width,
g_wports => c_MPRAM_WPORTS
)
port map(
clk_i => clk_i,
rst_n_i => rst_n_i,
read_req_i => free_pck_rd_req_i(i),
read_req_i => free_pck_in(i).rd_req,
read_req_o => free_pck_read(i),
read_addr_i => free_pck_addr_i((i+1)*g_addr_width - 1 downto i*g_addr_width ),
read_data_i => free_pck_data(i),--(g_data_width - 2 downto 0),
read_addr_i => free_pck_in(i).adr,
read_data_i => free_pck_data(i),
read_data_valid_i => free_pck_data(i)(g_data_width - 1),
read_data_ready_i => free_pck_grant_vec_d1(i),
write_addr_i => ll_wr_addr,
write_data_i => ll_wr_data,--(g_data_width - 2 downto 0),
write_data_valid_i => ll_wr_data(g_data_width - 1),
write_data_ready_i => ll_write_ena,
read_data_o => free_pck_data_o((i+1)*g_data_width - 1 downto i*g_data_width), --free_pck_data_out(i),--(g_data_width - 2 downto 0),
read_data_valid_o => free_pck_read_done_o(i) --free_pck_read_done(i)
-- eavesdropping
write_addr_i => x_mpram_wadr_d0,
write_data_i => x_mpram_wdat_d0,
write_data_ready_i => mpram_write,
-- end of eavesdropping
read_data_o => free_pck_out(i).data,
read_data_valid_o => free_pck_out(i).rd_done
);
-- free_pck_data_o ((i+1)*g_data_width - 1 downto i*g_data_width) <= free_pck_data_out(i)(g_data_width - 1 downto 0);
-- free_pck_data_o ((i+1)*g_data_width - 1) <= free_pck_read_done(i);
-- free_pck_read_done_o(i) <= free_pck_read_done(i);
end generate;
ll_free_pck_ena <= free_pck_grant_valid_d0;
ll_wr_ena <= ll_write_ena or ll_write_next_ena;
wr_ram: process(clk_i, rst_n_i)
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
ll_wr_addr_reg <= (others =>'0');
ll_wr_data_reg <= (others =>'0');
ll_wr_ena_reg <= '0';
else
ll_wr_addr_reg <= ll_wr_addr;
ll_wr_data_reg <= ll_wr_data;
ll_wr_ena_reg <= ll_wr_ena;
end if;
end if;
end process wr_ram;
-- wr_done: for i in 0 to g_num_ports -1 generate
-- write_done_o(i) <= '1' when ((write_grant_vec_d0(i) = '1' and tmp_write_end_of_list(i) = '1') or -- end-of-list, one one write, so write_done faster
-- (write_grant_vec_d0(i) = '1' and write_grant_vec_d1(i) = '1' and tmp_write_end_of_list(i) = '0')) else -- normal write, we write two words, it takes longer
-- '0';
-- end generate;
wr_done: for i in 0 to g_num_ports -1 generate
write_done_o(i) <= '1' when ((write_grant_vec_d0(i) = '1' and write_next_addr_valid_i(i) = '0') or -- end-of-list, one one write, so write_done faster
(write_grant_vec_d0(i) = '1' and write_grant_vec_d1(i) = '1' and write_next_addr_valid_i(i) = '1')) else -- normal write, we write two words, it takes longer
'0';
end generate;
write_done_o <= write_done_out;
end syn;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment