Commit ce4988d9 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

swcore: multiport LL configurable number of write ports to MPRAM

parent 8452ca3a
......@@ -143,6 +143,26 @@ architecture syn of swc_multiport_linked_list is
RData : out std_logic_vector(DATW*(nRPF+nRPS)-1 downto 0));
end component;
function ll_split_writes(write_i:std_logic_vector; g_num_ports:integer; idx_h:integer; idx_l:integer) return std_logic_vector is
variable write_split : std_logic_vector(g_num_ports-1 downto 0);
variable nidx : integer range 0 to g_num_ports;
begin
if idx_h > g_num_ports-1 then
nidx := g_num_ports;
else
nidx := idx_h;
end if;
if idx_l > g_num_ports-1 then
write_split := (others=>'0');
else
write_split(nidx downto idx_l) := write_i(nidx downto idx_l);
write_split(idx_l-1 downto 0) := (others=>'0');
write_split(g_num_ports-1 downto nidx+1) := (others=>'0');
end if;
return write_split;
end function;
--------------------------------------
-- packing interfaces into records --
--------------------------------------
......@@ -162,11 +182,12 @@ architecture syn of swc_multiport_linked_list is
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);
type t_llports_array is array (natural range <>) of std_logic_vector(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);
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_ored : t_llports_array(c_MPRAM_WPORTS-1 downto 0);
--------------------------------------
-- MPRAM signals --
......@@ -178,6 +199,7 @@ architecture syn of swc_multiport_linked_list is
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_wdone: t_llports_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);
......@@ -187,7 +209,6 @@ architecture syn of swc_multiport_linked_list is
--------------------------------------
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);
......@@ -259,11 +280,15 @@ begin
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);
GEN_MPRAM_WIF: for I in 0 to c_MPRAM_WPORTS-1 generate
mpram_wadr((I+1)*g_addr_width-1 downto I*g_addr_width) <= x_mpram_wadr_d0(I);
mpram_wdat((I+1)*g_data_width-1 downto I*g_data_width) <= x_mpram_wdat_d0(I);
end generate;
GEN_MPRAM_RIF: for I in 0 to c_MPRAM_RPORTS-1 generate
mpram_radr((I+1)*g_addr_width-1 downto I*g_addr_width) <= x_mpram_radr(I);
x_mpram_rdat(I) <= mpram_rdat((I+1)*g_data_width-1 downto I*g_data_width);
end generate;
-- MPM read interface
x_mpram_radr(0) <= mpm_rpath_addr_i;
......@@ -275,15 +300,18 @@ begin
--------------------------------------
-- 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');
-- we split IBs into write ports
-- IB port ranges for each write port are hardcoded to have similar
-- performance (IBs-per-write port) for 8 and 18 port version.
write_i_split(0) <= ll_split_writes(write_i, g_num_ports, 8, 0);
write_i_split(1) <= ll_split_writes(write_i, g_num_ports, g_num_ports-1, 9);
-- combine together write_done signals from multiple MPRAM write ports
write_done_ored(0) <= x_mpram_wdone(0);
GEN_WDONE: for I in 1 to c_MPRAM_WPORTS-1 generate
write_done_ored(I) <= write_done_ored(I-1) or x_mpram_wdone(I);
end generate;
write_done_o <= write_done_ored(c_MPRAM_WPORTS-1);
......@@ -304,6 +332,9 @@ begin
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));
x_mpram_wdone(I) <= write_grant_d0(I) when(write_done(I) = '1') else
(others=>'0');
f_rr_arbitrate(write_req(I), write_grant_d0(I), write_grant(I));
process(clk_i)
......@@ -437,6 +468,4 @@ begin
ll_free_pck_ena <= free_pck_grant_valid_d0;
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