Commit e94dffe1 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

swcore: use record-based interfaces for multiport linked list

parent babcf5c0
......@@ -83,29 +83,12 @@ entity swc_multiport_linked_list is
rst_n_i : in std_logic;
clk_i : in std_logic;
-- write request
write_i : in std_logic_vector(g_num_ports - 1 downto 0);
-- indicates that the data was written
write_done_o : out std_logic_vector(g_num_ports - 1 downto 0);
-- write address, needs to be valid till write_done_o=HIGH
write_addr_i : in std_logic_vector(g_num_ports * g_addr_width - 1 downto 0);
-- next page [ctrls,address or (size + sel)]
write_data_i : in std_logic_vector(g_num_ports * g_data_width - 1 downto 0);
-- if we already know the address (of the next page to be used), we provide it here, it
-- is invalidated.
write_next_addr_i : in std_logic_vector(g_num_ports * g_addr_width - 1 downto 0);
-- indicates that the next_addr is provided
write_next_addr_valid_i: in std_logic_vector(g_num_ports - 1 downto 0);
ib_i : in t_ib2ll_array(g_num_ports-1 downto 0);
ib_o : out t_ll2ib_array(g_num_ports-1 downto 0);
------------ reading from the Linked List by freeing module ----------
-- request reading
free_pck_rd_req_i : in std_logic_vector(g_num_ports - 1 downto 0);
-- requested address, needs to be valid till write_done_o=HIGH
free_pck_addr_i : in std_logic_vector(g_num_ports * g_addr_width - 1 downto 0);
-- data available on data_o
free_pck_read_done_o : out std_logic_vector(g_num_ports - 1 downto 0);
-- requested data
free_pck_data_o : out std_logic_vector(g_num_ports * g_data_width - 1 downto 0);
free_pck_i : in t_fp2ll_array(g_num_ports-1 downto 0);
free_pck_o : out t_ll2fp_array(g_num_ports-1 downto 0);
-------- reading by Multiport Memory (direct access) -------
-- requested address, needs to be valid till write_done_o=HIGH
......@@ -166,27 +149,8 @@ architecture syn of swc_multiport_linked_list is
--------------------------------------
-- 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);
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_ored : t_llports_array(c_MPRAM_WPORTS-1 downto 0);
--------------------------------------
......@@ -212,6 +176,8 @@ architecture syn of swc_multiport_linked_list is
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_i_vec : std_logic_vector(g_num_ports-1 downto 0);
signal write_next_vec : std_logic_vector(g_num_ports-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);
......@@ -239,26 +205,9 @@ architecture syn of swc_multiport_linked_list is
-- output
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);
begin
zeros <= (others => '0');
-- 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 (
MEMD => g_page_num,
......@@ -294,26 +243,28 @@ begin
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;
x_mpram_radr(1) <= free_pck_i(free_pck_grant_index).adr;
ll_free_pck_data <= x_mpram_rdat(1);
--------------------------------------
-- Serving write requests from IBs --
--------------------------------------
GEN_WRITE_VEC: for I in 0 to g_num_ports-1 generate
write_i_vec(I) <= ib_i(I).write;
ib_o(I).done <= write_done_ored(c_MPRAM_WPORTS-1)(I);
end generate;
-- 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, 5, 0);
write_i_split(1) <= ll_split_writes(write_i, g_num_ports, 11, 6);
write_i_split(2) <= ll_split_writes(write_i, g_num_ports, g_num_ports-1, 12);
write_i_split(0) <= ll_split_writes(write_i_vec, g_num_ports, 5, 0);
write_i_split(1) <= ll_split_writes(write_i_vec, g_num_ports, 11, 6);
write_i_split(2) <= ll_split_writes(write_i_vec, g_num_ports, g_num_ports-1, 12);
-- 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);
GEN_WRFSM: for I in 0 to c_MPRAM_WPORTS-1 generate
......@@ -324,14 +275,14 @@ begin
-- 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));
x_mpram_wadr(I) <= ib_i(write_idx(I)).adr_next when(ib_i(write_idx(I)).next_valid = '1' and wadr_sel(I)='0') else
ib_i(write_idx(I)).adr;
-- 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));
x_mpram_wdat(I) <= (others=>'0') when (ib_i(write_idx(I)).next_valid = '1' and wadr_sel(I)='0') else
ib_i(write_idx(I)).data;
x_mpram_wdone(I) <= write_grant_d0(I) when(write_done(I) = '1') else
(others=>'0');
......@@ -359,7 +310,7 @@ begin
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
if (or_reduce(write_grant(I)) = '1' and ib_i(write_idx(I)).next_valid = '1') then
mll_state(I) <= WRITE_NEXT;
wadr_sel(I) <= '1'; -- switch the address to be written
mpram_write(I) <= '1';
......@@ -411,7 +362,7 @@ begin
grant => free_pck_grant_vec);
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';
free_pck_request_noempty <= '1' when (or_reduce(free_pck_request_vec) /= '0') else '0';
process(clk_i, rst_n_i)
begin
......@@ -446,10 +397,10 @@ begin
clk_i => clk_i,
rst_n_i => rst_n_i,
read_req_i => free_pck_in(i).rd_req,
read_req_i => free_pck_i(i).rd_req,
read_req_o => free_pck_read(i),
read_addr_i => free_pck_in(i).adr,
read_addr_i => free_pck_i(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),
......@@ -460,8 +411,8 @@ begin
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
read_data_o => free_pck_o(i).data,
read_data_valid_o => free_pck_o(i).rd_done
);
end generate;
......
......@@ -69,11 +69,8 @@ entity swc_multiport_pck_pg_free_module is
ob_free_done_o : out std_logic_vector(g_num_ports-1 downto 0);
ob_free_pgaddr_i : in std_logic_vector(g_num_ports * g_page_addr_width - 1 downto 0);
ll_read_addr_o : out std_logic_vector(g_num_ports * g_page_addr_width -1 downto 0);
ll_read_data_i : in std_logic_vector(g_num_ports * g_data_width - 1 downto 0);
--ll_read_data_i : in std_logic_vector(g_page_addr_width - 1 downto 0);
ll_read_req_o : out std_logic_vector(g_num_ports-1 downto 0);
ll_read_valid_data_i : in std_logic_vector(g_num_ports-1 downto 0);
ll_i : in t_ll2fp_array(g_num_ports-1 downto 0);
ll_o : out t_fp2ll_array(g_num_ports-1 downto 0);
mmu_resource_i : in std_logic_vector(g_num_ports * g_resource_num_width -1 downto 0);
......@@ -123,10 +120,10 @@ begin -- syn
ob_free_done_o => ob_free_done_o(i),
ob_free_pgaddr_i => ob_free_pgaddr_i((i+1)*g_page_addr_width - 1 downto i * g_page_addr_width),
ll_read_addr_o => ll_read_addr_o((i+1)*g_page_addr_width - 1 downto i * g_page_addr_width),
ll_read_data_i => ll_read_data_i((i+1)*g_data_width - 1 downto i * g_data_width),
ll_read_req_o => ll_read_req_o(i),
ll_read_valid_data_i => ll_read_valid_data_i(i),
ll_read_addr_o => ll_o(i).adr,
ll_read_data_i => ll_i(i).data,
ll_read_req_o => ll_o(i).rd_req,
ll_read_valid_data_i => ll_i(i).rd_done,
mmu_resource_i => mmu_resource_i((i+1)*g_resource_num_width -1 downto i *g_resource_num_width),
......
......@@ -74,6 +74,51 @@ package swc_swcore_pkg is
type t_lladr_array is array(integer range <>) of std_logic_vector(c_ll_addr_width-1 downto 0);
type t_lldat_array is array(integer range <>) of std_logic_vector(c_ll_data_width-1 downto 0);
-- free_pck to Linked List interface
--------------------------------------
-- Free_pck to Linked List i/f --
--------------------------------------
type t_fp2ll is record
-- request reading
rd_req : std_logic;
-- requested address, needs to be valid till write_done_o=HIGH
adr : std_logic_vector(c_ll_addr_width-1 downto 0);
end record;
type t_fp2ll_array is array (natural range <>) of t_fp2ll;
type t_ll2fp is record
-- requested data
data : std_logic_vector(c_ll_data_width-1 downto 0);
-- data available on data_o
rd_done : std_logic;
end record;
type t_ll2fp_array is array (natural range <>) of t_ll2fp;
--------------------------------------
-- IB to Linked List i/f --
--------------------------------------
type t_ib2ll is record
-- write request
write : std_logic;
-- write address, needs to be valid till write_done_o=HIGH
adr : std_logic_vector(c_ll_addr_width-1 downto 0);
-- next page [ctrls,address or (size + sel)]
data : std_logic_vector(c_ll_data_width-1 downto 0);
-- if we already know the address (of the next page to be used), we provide it here, it
-- is invalidated.
adr_next : std_logic_vector(c_ll_addr_width-1 downto 0);
-- indicates that the next_addr is provided
next_valid : std_logic;
end record;
type t_ib2ll_array is array (natural range <>) of t_ib2ll;
type t_ll2ib is record
-- indicates that the data was written
done : std_logic;
end record;
type t_ll2ib_array is array (natural range <>) of t_ll2ib;
component swc_prio_encoder
generic (
g_num_inputs : integer range 2 to 80;
......@@ -188,17 +233,11 @@ package swc_swcore_pkg is
rst_n_i : in std_logic;
clk_i : in std_logic;
write_i : in std_logic_vector(g_num_ports - 1 downto 0);
write_done_o : out std_logic_vector(g_num_ports - 1 downto 0);
write_addr_i : in std_logic_vector(g_num_ports * g_addr_width - 1 downto 0);
write_data_i : in std_logic_vector(g_num_ports * g_data_width - 1 downto 0);
write_next_addr_i : in std_logic_vector(g_num_ports * g_addr_width - 1 downto 0);
write_next_addr_valid_i: in std_logic_vector(g_num_ports - 1 downto 0);
free_pck_rd_req_i : in std_logic_vector(g_num_ports - 1 downto 0);
free_pck_addr_i : in std_logic_vector(g_num_ports * g_addr_width - 1 downto 0);
free_pck_read_done_o : out std_logic_vector(g_num_ports - 1 downto 0);
free_pck_data_o : out std_logic_vector(g_num_ports * g_data_width - 1 downto 0);
ib_i : in t_ib2ll_array(g_num_ports-1 downto 0);
ib_o : out t_ll2ib_array(g_num_ports-1 downto 0);
free_pck_i : in t_fp2ll_array(g_num_ports-1 downto 0);
free_pck_o : out t_ll2fp_array(g_num_ports-1 downto 0);
mpm_rpath_addr_i : in std_logic_vector(g_addr_width - 1 downto 0);
mpm_rpath_data_o : out std_logic_vector(g_data_width - 1 downto 0)
......@@ -563,11 +602,8 @@ component swc_multiport_pck_pg_free_module is
ob_free_done_o : out std_logic_vector(g_num_ports-1 downto 0);
ob_free_pgaddr_i : in std_logic_vector(g_num_ports * g_page_addr_width - 1 downto 0);
ll_read_addr_o : out std_logic_vector(g_num_ports * g_page_addr_width -1 downto 0);
ll_read_data_i : in std_logic_vector(g_num_ports * g_data_width - 1 downto 0);
--ll_read_data_i : in std_logic_vector(g_page_addr_width - 1 downto 0);
ll_read_req_o : out std_logic_vector(g_num_ports-1 downto 0);
ll_read_valid_data_i : in std_logic_vector(g_num_ports-1 downto 0);
ll_i : in t_ll2fp_array(g_num_ports-1 downto 0);
ll_o : out t_fp2ll_array(g_num_ports-1 downto 0);
mmu_resource_i : in std_logic_vector(g_num_ports * g_resource_num_width -1 downto 0);
......
......@@ -259,14 +259,8 @@ architecture rtl of xswc_core is
----------------------------------------------------------------------------------------------------
-- signals connecting >>Input Block<< with >>Linked List<< (new)
----------------------------------------------------------------------------------------------------
signal ib2ll_addr : std_logic_vector(g_num_ports*c_ll_addr_width - 1 downto 0);
signal ib2ll_data : std_logic_vector(g_num_ports*c_ll_data_width - 1 downto 0);
signal ib2ll_next_addr : std_logic_vector(g_num_ports*c_ll_addr_width - 1 downto 0);
signal ib2ll_next_addr_valid : std_logic_vector(g_num_ports - 1 downto 0);
signal ib2ll_wr_req : std_logic_vector(g_num_ports - 1 downto 0);
signal ll2ib_wr_done : std_logic_vector(g_num_ports - 1 downto 0);
signal ib2ll : t_ib2ll_array(g_num_ports-1 downto 0);
signal ll2ib : t_ll2ib_array(g_num_ports-1 downto 0);
----------------------------------------------------------------------------------------------------
-- signals connecting >>Input Block<< with >>Pck's pages freeeing module<<
......@@ -300,10 +294,8 @@ architecture rtl of xswc_core is
signal ll_read_valid_data : std_logic_vector(g_num_ports-1 downto 0);
-- new Free Pck (FP) module <-> Linked List (LL)
signal fp2ll_rd_req : std_logic_vector(g_num_ports - 1 downto 0);
signal fp2ll_addr : std_logic_vector(g_num_ports * c_ll_addr_width - 1 downto 0);
signal ll2fp_read_done : std_logic_vector(g_num_ports - 1 downto 0);
signal ll2fp_data : std_logic_vector(g_num_ports * c_ll_data_width - 1 downto 0);
signal fp2ll : t_fp2ll_array(g_num_ports-1 downto 0);
signal ll2fp : t_ll2fp_array(g_num_ports-1 downto 0);
----------------------------------------------------------------------------------------------------
-- signals connecting >>Pck's pages freeing module (PPFM)<< with >>Page allocator (MMU)<<
......@@ -599,14 +591,12 @@ architecture rtl of xswc_core is
-- I/F with Linked List
-------------------------------------------------------------------------------
ll_addr_o => ib2ll_addr((i+1)* c_ll_addr_width - 1 downto i* c_ll_addr_width),
ll_data_o => ib2ll_data((i+1)* c_ll_data_width - 1 downto i *c_ll_data_width),
ll_next_addr_o => ib2ll_next_addr((i+1)* c_ll_addr_width - 1 downto i* c_ll_addr_width),
ll_next_addr_valid_o => ib2ll_next_addr_valid(i),
ll_wr_req_o => ib2ll_wr_req(i),
ll_wr_done_i => ll2ib_wr_done(i),
ll_addr_o => ib2ll(i).adr,
ll_data_o => ib2ll(i).data,
ll_next_addr_o => ib2ll(i).adr_next,
ll_next_addr_valid_o => ib2ll(i).next_valid,
ll_wr_req_o => ib2ll(i).write,
ll_wr_done_i => ll2ib(i).done,
-------------------------------------------------------------------------------
-- I/F with Page Transfer Arbiter (PTA)
......@@ -736,10 +726,8 @@ architecture rtl of xswc_core is
ob_free_done_o => ppfm_free_done_to_ob,
ob_free_pgaddr_i => ob_free_pgaddr,
ll_read_addr_o => fp2ll_addr, --ppfm_read_addr,
ll_read_data_i => ll2fp_data, --ll_data,
ll_read_req_o => fp2ll_rd_req, --ppfm_read_req,
ll_read_valid_data_i => ll2fp_read_done, --ll_read_valid_data,
ll_i => ll2fp,
ll_o => fp2ll,
mmu_resource_i => mmu2ppfm_resource,
......@@ -771,31 +759,20 @@ architecture rtl of xswc_core is
g_data_width => c_ll_data_width
)
port map(
rst_n_i => rst_n_i,
clk_i => clk_i,
write_i => ib2ll_wr_req,
write_done_o => ll2ib_wr_done,
write_next_addr_i => ib2ll_next_addr,
write_next_addr_valid_i => ib2ll_next_addr_valid,
rst_n_i => rst_n_i,
clk_i => clk_i,
write_addr_i => ib2ll_addr,
write_data_i => ib2ll_data,
ib_i => ib2ll,
ib_o => ll2ib,
mpm_rpath_addr_i => mpm2ll_addr,
mpm_rpath_data_o => ll2mpm_data,
mpm_rpath_addr_i => mpm2ll_addr,
mpm_rpath_data_o => ll2mpm_data,
free_pck_i => fp2ll,
free_pck_o => ll2fp
free_pck_rd_req_i => fp2ll_rd_req,
free_pck_addr_i => fp2ll_addr,
free_pck_read_done_o => ll2fp_read_done,
free_pck_data_o => ll2fp_data
);
-- tmp
--fp2ll_rd_req <= (others => '0');
--fp2ll_addr <= (others => '0');
----------------------------------------------------------------------
-- Memory Mangement Unit (MMU)
----------------------------------------------------------------------
......
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