Commit 1de70f50 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

modules/swcore: prevent TR FSM from being stuck in DROP when new SOF comes…

modules/swcore: prevent TR FSM from being stuck in DROP when new SOF comes before LL EOF write of a previous frame

It happened that we had only one clock cycle break between EOF and SOF
for a new frame. In that case LL FSM was not detecting SOF and was not
going to SOF_ON_WR (SOF was already _low_ when LL FSM was in S_WRITE).
If the new frame was decided to be droped after writing only the first
data word to MPM, then we were never storing the new start page to the
FSM and a force_free request was masked. Transfer FSM was not getting
ffree_done and everything was stucked in DROP forever.

The fix adds in_pck_sof_d0 signal to let LL FSM go to S_SOF_ON_WR in the
situation described above. It also keeps _high_ state of
new_pck_first_page signal so that the new start page could be written to
LL when LL FSM goes to IDLE from S_SOF_ON_WR.
parent 182f3f6d
......@@ -421,6 +421,7 @@ architecture syn of xswc_input_block is
signal in_pck_dvalid : std_logic;
signal in_pck_dat : std_logic_vector(g_mpm_data_width - 1 downto 0);
signal in_pck_sof : std_logic; -- start of frame
signal in_pck_sof_d0 : std_logic;
signal in_pck_eof : std_logic; -- end of frame
signal in_pck_err : std_logic; -- error
signal in_pck_eod : std_logic; -- end of data
......@@ -824,9 +825,12 @@ begin --archS_PCKSTART_SET_AND_REQ
end if;
mpm_dvalid <= '0';
in_pck_eof_on_pause <= '0';
if(new_pck_first_page = '1' and s_ll_write = S_SOF_ON_WR) then
if(new_pck_first_page = '1' and (s_ll_write = S_SOF_ON_WR or s_ll_write = S_WRITE)) then
-- in case LL FSM is in S_SOF_ON_WR, we need to keep
-- new_pck_first_page signal longer, otherwise we lose it..
-- The same applies for LL FSM in S_WRITE, when SOF was one cycle
-- before S_WRITE and LL FSM will enter S_SOF_ON_WR as a result
-- of in_pck_sof_d0.
new_pck_first_page <= '1';
else
new_pck_first_page <= '0';
......@@ -1954,6 +1958,7 @@ begin
mpm_dlast_d0 <= '0';
mpm_pg_req_d0 <= '0';
in_pck_sof_d0 <= '0';
--s_ll_write <= S_IDLE;
--pckstart_pageaddr_clred <= (others => '1');--make it different then the first allocated addr
--========================================
......@@ -1961,6 +1966,7 @@ begin
mpm_dlast_d0 <= mpm_dlast;
mpm_pg_req_d0 <= mpm_pg_req_i;
in_pck_sof_d0 <= in_pck_sof;
case s_ll_write is
--===========================================================================================
......@@ -2108,7 +2114,9 @@ begin
if(mpm_dlast_d0 = '1') then
s_ll_write <= S_EOF_ON_WR;
elsif(in_pck_sof = '1') then
elsif(in_pck_sof = '1' or in_pck_sof_d0 = '1') then
-- in_pck_sof_d0 triggers this condition when in_pck_sof was high
-- one cycle before LL FSM got to S_WRITE.
s_ll_write <= S_SOF_ON_WR;
end if;
......
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