Commit eb4fce62 authored by Maciej Lipinski's avatar Maciej Lipinski

swcore[new mpm]: re-doing sel handling in the MPM (design flaw identified

parent 846342c9
......@@ -54,7 +54,9 @@ package mpm_pkg is
g_fifo_size : integer := 4;
g_page_addr_width : integer := 11;
g_partial_select_width : integer := 1;
g_max_packet_size : integer := 10000
g_max_oob_size : integer := 3;
g_max_packet_size : integer := 10000;
g_ll_data_width : integer := 15
);
port(
......@@ -80,7 +82,7 @@ package mpm_pkg is
rport_pg_req_o : out std_logic_vector (g_num_ports-1 downto 0);
ll_addr_o : out std_logic_vector(g_page_addr_width-1 downto 0);
ll_data_i : in std_logic_vector(g_page_addr_width+1 downto 0)
ll_data_i : in std_logic_vector(g_ll_data_width -1 downto 0)
);
end component;
......
......@@ -18,7 +18,9 @@ entity mpm_read_path is
g_fifo_size : integer;
g_page_addr_width : integer;
g_partial_select_width : integer;
g_max_packet_size : integer
g_max_oob_size : integer;
g_max_packet_size : integer;
g_ll_data_width : integer
);
port(
......@@ -42,7 +44,7 @@ entity mpm_read_path is
-- Linked List I/F (I/O clock domain)
ll_addr_o : out std_logic_vector(g_page_addr_width-1 downto 0);
ll_data_i : in std_logic_vector(g_page_addr_width+1 downto 0);
ll_data_i : in std_logic_vector(g_ll_data_width -1 downto 0);
-- F. B. Memory I/F
fbm_addr_o : out std_logic_vector(f_log2_size(g_num_pages * g_page_size / g_ratio)-1 downto 0);
......@@ -60,7 +62,9 @@ architecture rtl of mpm_read_path is
g_page_size : integer;
g_partial_select_width : integer;
g_ratio : integer;
g_max_packet_size : integer);
g_max_oob_size : integer;
g_max_packet_size : integer;
g_ll_data_width : integer);
port (
clk_io_i : in std_logic;
rst_n_io_i : in std_logic;
......@@ -76,7 +80,7 @@ architecture rtl of mpm_read_path is
ll_req_o : out std_logic;
ll_grant_i : in std_logic;
ll_addr_o : out std_logic_vector(g_page_addr_width-1 downto 0);
ll_data_i : in std_logic_vector(g_page_addr_width + 1 downto 0);
ll_data_i : in std_logic_vector(g_ll_data_width -1 downto 0);
pf_full_i : in std_logic;
pf_we_o : out std_logic;
pf_fbm_addr_o : out std_logic_vector(f_log2_size(g_num_pages * g_page_size / g_ratio) - 1 downto 0);
......@@ -364,7 +368,9 @@ begin -- rtl
g_page_size => g_page_size,
g_partial_select_width => g_partial_select_width,
g_ratio => g_ratio,
g_max_packet_size => g_max_packet_size)
g_max_oob_size => g_max_oob_size,
g_max_packet_size => g_max_packet_size,
g_ll_data_width => g_ll_data_width)
port map (
clk_io_i => clk_io_i,
rst_n_io_i => rst_n_io_i,
......
......@@ -14,6 +14,8 @@ entity mpm_rpath_io_block is
g_page_size : integer;
g_partial_select_width : integer;
g_ratio : integer;
g_ll_data_width : integer;
g_max_oob_size : integer;
g_max_packet_size : integer);
port (
......@@ -35,7 +37,7 @@ entity mpm_rpath_io_block is
ll_req_o : out std_logic;
ll_grant_i : in std_logic;
ll_addr_o : out std_logic_vector(g_page_addr_width-1 downto 0);
ll_data_i : in std_logic_vector(g_page_addr_width + 1 downto 0);
ll_data_i : in std_logic_vector(g_ll_data_width -1 downto 0);
-- Page FIFO interface
pf_full_i : in std_logic;
......@@ -54,11 +56,12 @@ end mpm_rpath_io_block;
architecture behavioral of mpm_rpath_io_block is
constant c_lines_per_page : integer := g_page_size/g_ratio;
constant c_page_lines_width : integer := f_log2_size(c_lines_per_page + 1);
constant c_page_size_width : integer := f_log2_size(g_page_size + 1);
constant c_word_count_width : integer := f_log2_size(g_max_packet_size + 1);
constant c_lines_per_page : integer := g_page_size/g_ratio;
constant c_page_lines_width : integer := f_log2_size(c_lines_per_page + 1);
constant c_page_size_width : integer := f_log2_size(g_page_size + 1);
constant c_word_count_width : integer := f_log2_size(g_max_packet_size + 1);
constant c_max_oob_size_width : integer := f_log2_size(g_max_oob_size + 1);
function f_fast_div_pagesize
(x : unsigned;
y : integer) return unsigned is
......@@ -106,6 +109,8 @@ architecture behavioral of mpm_rpath_io_block is
next_page : std_logic_vector(g_page_addr_width-1 downto 0);
dsel : std_logic_vector(g_partial_select_width-1 downto 0);
size : std_logic_vector(f_log2_size(g_page_size + 1)-1 downto 0);
oob_size : std_logic_vector(c_max_oob_size_width - 1 downto 0);
oob_dsel : std_logic_vector(g_partial_select_width - 1 downto 0);
end record;
......@@ -139,21 +144,29 @@ architecture behavioral of mpm_rpath_io_block is
-- When HI, fetcher aborts fetching the current page chain and proceeds to the
-- next packet.
signal fetch_abort : std_logic;
signal fetch_dsel_words : unsigned(f_log2_size(g_page_size+1)-1 downto 0);
signal fetch_oob_dsel : std_logic_vector(g_partial_select_width-1 downto 0);
signal saved_dsel : std_logic_vector(g_partial_select_width-1 downto 0);
signal saved_dat_dsel : std_logic_vector(g_partial_select_width-1 downto 0);
signal saved_oob_dsel : std_logic_vector(g_partial_select_width-1 downto 0);
-- Datapath signals
signal df_we_d0 : std_logic;
signal last_page : std_logic;
signal words_total : unsigned(c_word_count_width-1 downto 0);
signal dsel_words_total : unsigned(c_word_count_width-1 downto 0);
signal words_xmitted : unsigned(c_word_count_width-1 downto 0);
signal d_last_int, d_valid_int, df_rd_int : std_logic;
signal d_last_int, d_valid_int, df_rd_int, d_endOfData_int : std_logic;
signal pf_we_int : std_logic;
signal ll_req_int, ll_grant_d0, ll_grant_d1 : std_logic;
signal counters_equal : std_logic;
signal data_dsel_valid : std_logic;
signal wait_first_fetched : std_logic;
begin -- behavioral
......@@ -182,18 +195,23 @@ begin -- behavioral
--counters_equal <= '1' when (words_total = words_xmitted) else '0';
counters_equal <= '1' when (words_total = words_xmitted and rport_dreq_i = '1') else '0';
-- ML
data_dsel_valid <= '1' when (dsel_words_total = words_xmitted and rport_dreq_i = '1') else '0';
p_count_words : process(clk_io_i)
begin
if rising_edge(clk_io_i) then
if rst_n_io_i = '0' or (d_last_int = '1' and d_valid_int = '1') then
words_total <= (others => '0');
words_xmitted <= to_unsigned(1, words_xmitted'length);
d_last_int <= '0';
words_total <= (others => '0');
dsel_words_total<= (others => '0');
words_xmitted <= to_unsigned(1, words_xmitted'length);
d_last_int <= '0';
d_endOfData_int <= '0';
else
if(fetch_last = '1' and fetch_ack = '1') then
saved_dsel <= fetch_dsel;
if(data_dsel_valid = '1') then
saved_dat_dsel <= fetch_dsel;
elsif(fetch_last = '1' and fetch_ack = '1') then
saved_oob_dsel <= fetch_oob_dsel;
end if;
if(df_rd_int = '1') then
......@@ -202,21 +220,23 @@ begin -- behavioral
if(fetch_ack = '1') then
if(fetch_first = '1') then
words_total <= resize(fetch_pg_words, words_total'length);
words_total <= resize(fetch_pg_words, words_total'length);
dsel_words_total <= resize(fetch_dsel_words, dsel_words_total'length);
else
words_total <= words_total + fetch_pg_words;
words_total <= words_total + fetch_pg_words;
dsel_words_total <= dsel_words_total + fetch_dsel_words;
end if;
end if;
d_last_int <= counters_equal;
d_last_int <= counters_equal;
d_endOfData_int <= data_dsel_valid;
end if;
end if;
end process;
df_rd_int <= rport_dreq_i and not (df_empty_i or d_last_int);
df_rd_int <= rport_dreq_i and not (df_empty_i or d_last_int or wait_first_fetched);
df_rd_o <= df_rd_int;
......@@ -239,8 +259,8 @@ begin -- behavioral
rport_dlast_o <= d_last_int;
rport_d_o <= df_d_i;
rport_dsel_o <= saved_dsel when d_last_int = '1' else (others => '1');
rport_dsel_o <= saved_oob_dsel when d_last_int = '1' else
saved_dat_dsel when d_endOfData_int = '1' else (others => '1');
-------------------------------------------------------------------------------
-- Page fetcher logic
......@@ -249,14 +269,19 @@ begin -- behavioral
-- pointer to the next page (shared with page size and partial select)
cur_ll.next_page <= ll_data_i(g_page_addr_width-1 downto 0);
-- 1: last page in the chain
cur_ll.eof <= ll_data_i(g_page_addr_width);
cur_ll.eof <= ll_data_i(g_ll_data_width-2);
-- 1: page is valid
cur_ll.valid <= ll_data_i(g_page_addr_width+1);
cur_ll.valid <= ll_data_i(g_ll_data_width-1);
-- 1: number of the words in page (1 = 1 word .. g_page_size-1 = full page)
cur_ll.size <= ll_data_i(c_page_size_width-1 downto 0);
-- 1: partial select bits (number of bytes in the last word of the page. For
-- 16-bit datapath: 0 = 1 byte, 1 = 2 bytes, etc.)
cur_ll.dsel <= ll_data_i(g_page_addr_width-1 downto g_page_addr_width-g_partial_select_width);
cur_ll.dsel <= ll_data_i(g_ll_data_width-3 downto g_ll_data_width-2-g_partial_select_width);
cur_ll.oob_size <= ll_data_i(g_ll_data_width-2-g_partial_select_width-1 downto
g_ll_data_width-2-g_partial_select_width-c_max_oob_size_width);
cur_ll.oob_dsel <= ll_data_i(g_page_addr_width-1 downto g_page_addr_width-g_partial_select_width);
fetch_valid <= fvalid_int and not fetch_ack;
......@@ -271,12 +296,20 @@ begin -- behavioral
ll_req_int <= '0';
ll_grant_d0 <= '0';
ll_grant_d1 <= '0';
fetch_dsel_words<= (others =>'0');
fetch_oob_dsel <= (others =>'0');
wait_first_fetched <='1';
else
ll_grant_d0 <= ll_grant_i;
ll_grant_d1 <= ll_grant_d0;
if(cur_ll.valid = '1' and fetch_first = '1') then
wait_first_fetched <='0';
elsif(fetch_first = '1' and df_empty_i = '0') then
wait_first_fetched <='1';
end if;
case page_state is
-- request the 1st page of the packet from the Read port interface. Once got
-- the 1st address, go to FIRST_LL state
......@@ -303,17 +336,26 @@ begin -- behavioral
elsif(ll_grant_d1 = '1' and cur_ll.valid = '1') then
cur_page <= cur_ll.next_page;
ll_addr_o <= cur_ll.next_page;
if(cur_ll.eof = '1') then
page_state <= WAIT_LAST_ACK;
fetch_pg_words <= unsigned(cur_ll.size);
fetch_pg_lines <= f_fast_div_pagesize(unsigned(cur_ll.size), g_ratio);
fetch_pg_addr <= cur_page;
fetch_dsel <= cur_ll.dsel;
fetch_oob_dsel <= cur_ll.oob_dsel;
fvalid_int <= '1';
fetch_last <= '1';
fetch_dsel <= cur_ll.dsel;
fetch_dsel_words <= unsigned(cur_ll.size) - unsigned(cur_ll.oob_size);
else
page_state <= WAIT_ACK;
if(unsigned(cur_ll.oob_size) /= to_unsigned(0, c_max_oob_size_width)) then
fetch_dsel <= cur_ll.dsel;
fetch_dsel_words <= to_unsigned(g_page_size, fetch_dsel_words'length) - resize(unsigned(cur_ll.oob_size), fetch_dsel_words'length);
else
fetch_dsel_words <= to_unsigned(g_page_size, fetch_pg_words'length);
end if;
fetch_pg_words <= to_unsigned(g_page_size, fetch_pg_words'length);
fetch_pg_lines <= to_unsigned(c_lines_per_page, fetch_pg_lines'length);
......
......@@ -17,7 +17,9 @@ entity mpm_top is
g_fifo_size : integer := 4;
g_page_addr_width : integer := 11;
g_partial_select_width : integer := 1;
g_max_packet_size : integer := 10000
g_max_oob_size : integer := 3;
g_max_packet_size : integer := 10000;
g_ll_data_width : integer := 15
);
port(
......@@ -47,7 +49,7 @@ entity mpm_top is
rport_pg_req_o : out std_logic_vector (g_num_ports-1 downto 0);
ll_addr_o : out std_logic_vector(g_page_addr_width-1 downto 0);
ll_data_i : in std_logic_vector(g_page_addr_width+1 downto 0)
ll_data_i : in std_logic_vector(g_ll_data_width -1 downto 0)
);
end mpm_top;
......@@ -93,7 +95,9 @@ architecture rtl of mpm_top is
g_fifo_size : integer;
g_page_addr_width : integer;
g_partial_select_width : integer;
g_max_packet_size : integer);
g_max_oob_size : integer;
g_max_packet_size : integer;
g_ll_data_width : integer);
port (
clk_io_i : in std_logic;
clk_core_i : in std_logic;
......@@ -109,7 +113,7 @@ architecture rtl of mpm_top is
rport_pg_req_o : out std_logic_vector(g_num_ports-1 downto 0);
rport_pg_valid_i : in std_logic_vector (g_num_ports-1 downto 0);
ll_addr_o : out std_logic_vector(g_page_addr_width-1 downto 0);
ll_data_i : in std_logic_vector(g_page_addr_width+1 downto 0);
ll_data_i : in std_logic_vector(g_ll_data_width -1 downto 0);
fbm_addr_o : out std_logic_vector(f_log2_size(g_num_pages * g_page_size / g_ratio)-1 downto 0);
fbm_data_i : in std_logic_vector(g_ratio * g_data_width -1 downto 0));
end component;
......@@ -167,7 +171,9 @@ begin -- rtl
g_fifo_size => g_fifo_size,
g_page_addr_width => g_page_addr_width,
g_partial_select_width => g_partial_select_width,
g_max_packet_size => g_max_packet_size)
g_max_oob_size => g_max_oob_size,
g_max_packet_size => g_max_packet_size,
g_ll_data_width => g_ll_data_width)
port map (
clk_io_i => clk_io_i,
clk_core_i => clk_core_i,
......
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