From b937eb9a414a5d4d7bacdcecb59657105706f743 Mon Sep 17 00:00:00 2001 From: "Walter F.J. Mueller" Date: Sun, 30 Apr 2017 15:14:06 +0200 Subject: [PATCH] BUGFIX: resolve hangup of fx2 USB controller - was caused by inconsistent use of rx fifo thresholds - adding more lines to monitor output (fsm_* lines for state tracking) --- rtl/bplib/fx2lib/fx2_2fifoctl_ic.vhd | 44 ++++++++++++++++++------ rtl/bplib/fx2lib/fx2_3fifoctl_ic.vhd | 50 ++++++++++++++++++++++------ rtl/bplib/fx2lib/fx2lib.vhd | 18 +++++++--- 3 files changed, 87 insertions(+), 25 deletions(-) diff --git a/rtl/bplib/fx2lib/fx2_2fifoctl_ic.vhd b/rtl/bplib/fx2lib/fx2_2fifoctl_ic.vhd index b53bc383..686b6498 100644 --- a/rtl/bplib/fx2lib/fx2_2fifoctl_ic.vhd +++ b/rtl/bplib/fx2lib/fx2_2fifoctl_ic.vhd @@ -1,6 +1,6 @@ --- $Id: fx2_2fifoctl_ic.vhd 649 2015-02-21 21:10:16Z mueller $ +-- $Id: fx2_2fifoctl_ic.vhd 888 2017-04-30 13:06:51Z mueller $ -- --- Copyright 2012-2013 by Walter F.J. Mueller +-- Copyright 2012-2017 by Walter F.J. Mueller -- -- This program is free software; you may redistribute and/or modify it under -- the terms of the GNU General Public License as published by the Free @@ -23,16 +23,19 @@ -- -- Test bench: - -- Target Devices: generic --- Tool versions: xst 13.3-14.7; ghdl 0.29-0.31 +-- Tool versions: xst 13.3-14.7; ghdl 0.29-0.34 -- -- Synthesized (xst): -- Date Rev ise Target flop lutl lutm slic t peri +-- 2017-04-30 888 14.7 131013 xc6slx16-2 145 147 32 75 s 5.5/5.1 -- 2013-01-04 469 13.3 O76x xc3s1200e-4 112 172 64 169 s 7.4/7.4 -- 2012-01-14 453 13.3 O76x xc3s1200e-4 101? 173 64 159 s 8.3/7.4 -- 2012-01-08 451 13.3 O76x xc3s1200e-4 110 166 64 163 s 7.5 -- -- Revision History: -- Date Rev Version Comment +-- 2017-04-30 888 1.3 BUGFIX: resolve rx fifo threshold deadlock +-- add fsm_* monitor lines -- 2013-01-04 469 1.2 BUGFIX: redo rx logic, now properly pipelined -- 2012-01-15 453 1.1 use aempty/afull logic; collapse tx and pe flows -- 2012-01-09 451 1.0 Initial version @@ -129,7 +132,10 @@ architecture syn of fx2_2fifoctl_ic is '0','0', -- moni_ep(4|6)_sel '0','0' -- moni_ep(4|6)_pf ); - + + constant rxfifo_thres : natural := 3; -- required free space in rx fifo to + -- start rx pipeline + signal R_REGS : regs_type := regs_init; -- state registers signal N_REGS : regs_type := regs_init; -- next value state regs @@ -295,9 +301,7 @@ begin end process proc_regs; - proc_next: process (R_REGS, - FX2_FLAG_N, TXFIFO_VAL, RXSIZE_FX2, - RXFIFO_BUSY, TXBUSY_L) + proc_next: process (R_REGS, FX2_FLAG_N, TXFIFO_VAL, RXSIZE_FX2, TXBUSY_L) variable r : regs_type := regs_init; variable n : regs_type := regs_init; @@ -320,6 +324,7 @@ begin variable slrxok : slbit := '0'; variable sltxok : slbit := '0'; variable pipeok : slbit := '0'; + variable rxfifook : slbit := '0'; variable cc_clr : slbit := '0'; variable cc_cnt : slbit := '0'; @@ -349,6 +354,11 @@ begin sltxok := FX2_FLAG_N(c_flag_tx_ff); -- full flag is act.low! pipeok := FX2_FLAG_N(c_flag_prog); -- almost flag is act.low! + rxfifook := '0'; + if unsigned(RXSIZE_FX2)>rxfifo_thres then -- enough space in rx fifo ? + rxfifook := '1'; + end if; + cc_clr := '0'; cc_cnt := '0'; if unsigned(r.ccnt) = 0 then @@ -361,7 +371,7 @@ begin case r.state is when s_idle => -- s_idle: - if slrxok='1' and RXFIFO_BUSY='0' then + if slrxok='1' and rxfifook='1' then -- rx data and space in fifo ififo_ce := '1'; ififo := c_rxfifo; n.state := s_rxprep1; @@ -394,7 +404,7 @@ begin n.state := s_txprep0; -- otherwise switch to tx flow end if; -- if more rx to do and possible - elsif slrxok='1' and unsigned(RXSIZE_FX2)>3 then -- !thres must be >3! + elsif slrxok='1' and rxfifook='1' then islrd := '1'; cc_cnt := '1'; n.rxpipe1 := '1'; @@ -431,7 +441,7 @@ begin when s_txdisp => -- s_txdisp: write, dispatch -- if chunk done and rx pending and possible - if cc_done='1' and slrxok='1' and RXFIFO_BUSY='0' then + if cc_done='1' and slrxok='1' and rxfifook='1' then n.state := s_rxprep0; -- if pktend to do and possible elsif sltxok = '1' and r.pepend = '1' then @@ -533,6 +543,20 @@ begin R_MONI_C.slrd <= not FX2_SLRD_N; R_MONI_C.slwr <= not FX2_SLWR_N; R_MONI_C.pktend <= not FX2_PKTEND_N; + case R_REGS.state is + when s_idle => R_MONI_C.fsm_idle <= '1'; + when s_rxprep0 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_rx <= '1'; + when s_rxprep1 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_rx <= '1'; + when s_rxprep2 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_rx <= '1'; + when s_rxdisp => R_MONI_C.fsm_disp <= '1'; R_MONI_C.fsm_rx <= '1'; + when s_rxpipe => R_MONI_C.fsm_pipe <= '1'; R_MONI_C.fsm_rx <= '1'; + when s_txprep0 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_tx <= '1'; + when s_txprep1 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_tx <= '1'; + when s_txprep2 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_tx <= '1'; + when s_txdisp => R_MONI_C.fsm_disp <= '1'; R_MONI_C.fsm_tx <= '1'; + when others => null; + end case; + R_MONI_S <= R_MONI_C; end if; end if; diff --git a/rtl/bplib/fx2lib/fx2_3fifoctl_ic.vhd b/rtl/bplib/fx2lib/fx2_3fifoctl_ic.vhd index cc1b2bdf..c1819199 100644 --- a/rtl/bplib/fx2lib/fx2_3fifoctl_ic.vhd +++ b/rtl/bplib/fx2lib/fx2_3fifoctl_ic.vhd @@ -1,6 +1,6 @@ --- $Id: fx2_3fifoctl_ic.vhd 649 2015-02-21 21:10:16Z mueller $ +-- $Id: fx2_3fifoctl_ic.vhd 888 2017-04-30 13:06:51Z mueller $ -- --- Copyright 2012-2013 by Walter F.J. Mueller +-- Copyright 2012-2017 by Walter F.J. Mueller -- -- This program is free software; you may redistribute and/or modify it under -- the terms of the GNU General Public License as published by the Free @@ -23,15 +23,18 @@ -- -- Test bench: - -- Target Devices: generic --- Tool versions: xst 13.3-14.7; ghdl 0.29-0.31 +-- Tool versions: xst 13.3-14.7; ghdl 0.29-0.34 -- -- Synthesized (xst): -- Date Rev ise Target flop lutl lutm slic t peri +-- 2017-04-30 888 14.7 131013 xc6slx16-2 207 207 48 125 s 6.9/5.8 -- 2012-01-15 453 13.3 O76x xc3s1200e-4 157 265 96 243 s 7.7/7.4 -- 2012-01-15 453 13.3 O76x xc3s1200e-4 156 259 96 238 s 7.9/7.5 -- -- Revision History: -- Date Rev Version Comment +-- 2017-04-30 888 1.2 BUGFIX: resolve rx fifo threshold deadlock +-- add fsm_* monitor lines -- 2013-01-04 469 1.1 BUGFIX: redo rx logic, now properly pipelined -- 2012-01-09 453 1.0 Initial version (derived from 2fifo_ic) -- @@ -142,6 +145,9 @@ architecture syn of fx2_3fifoctl_ic is '0','0','0' -- moni_ep(4|6|8)_pf ); + constant rxfifo_thres : natural := 3; -- required free space in rx fifo to + -- start rx pipeline + signal R_REGS : regs_type := regs_init; -- state registers signal N_REGS : regs_type := regs_init; -- next value state regs @@ -334,10 +340,8 @@ begin end process proc_regs; - proc_next: process (R_REGS, - FX2_FLAG_N, TXFIFO_VAL, TX2FIFO_VAL, - TXFIFO_DO, TX2FIFO_DO, - RXSIZE_FX2, RXFIFO_BUSY, TXBUSY_L, TX2BUSY_L) + proc_next: process (R_REGS, FX2_FLAG_N, TXFIFO_VAL, TX2FIFO_VAL, + TXFIFO_DO, TX2FIFO_DO, RXSIZE_FX2, TXBUSY_L, TX2BUSY_L) variable r : regs_type := regs_init; variable n : regs_type := regs_init; @@ -363,6 +367,7 @@ begin variable sltxok : slbit := '0'; variable sltx2ok : slbit := '0'; variable pipeok : slbit := '0'; + variable rxfifook : slbit := '0'; variable cc_clr : slbit := '0'; variable cc_cnt : slbit := '0'; @@ -395,6 +400,11 @@ begin sltx2ok := FX2_FLAG_N(c_flag_tx2_ff); -- full flag is act.low! pipeok := FX2_FLAG_N(c_flag_prog); -- almost flag is act.low! + rxfifook := '0'; + if unsigned(RXSIZE_FX2)>rxfifo_thres then -- enough space in rx fifo ? + rxfifook := '1'; + end if; + cc_clr := '0'; cc_cnt := '0'; if unsigned(r.ccnt) = 0 then @@ -407,7 +417,7 @@ begin case r.state is when s_idle => -- s_idle: - if slrxok='1' and RXFIFO_BUSY='0' then + if slrxok='1' and rxfifook='1' then -- rx data and space in fifo ififo_ce := '1'; ififo := c_rxfifo; n.state := s_rxprep1; @@ -452,7 +462,7 @@ begin n.state := s_tx2prep0; end if; -- if more rx to do and possible - elsif slrxok='1' and unsigned(RXSIZE_FX2)>3 then -- !thres must be >3! + elsif slrxok='1' and rxfifook='1' then islrd := '1'; cc_cnt := '1'; n.rxpipe1 := '1'; @@ -493,7 +503,7 @@ begin then n.state := s_tx2prep0; -- if chunk done and rx pending and possible - elsif cc_done='1' and slrxok='1' and RXFIFO_BUSY='0' then + elsif cc_done='1' and slrxok='1' and rxfifook='1' then n.state := s_rxprep0; -- if pktend to do and possible elsif sltxok = '1' and r.pepend = '1' then @@ -533,7 +543,7 @@ begin when s_tx2disp => -- s_tx2disp: write, dispatch -- if chunk done and rx pending and possible - if cc_done='1' and slrxok='1' and RXFIFO_BUSY='0' then + if cc_done='1' and slrxok='1' and rxfifook='1' then n.state := s_rxprep0; -- if chunk done and tx or pe pending and possible elsif cc_done='1' and sltxok='1' and (TXFIFO_VAL='1' or r.pepend='1') @@ -659,6 +669,24 @@ begin R_MONI_C.slrd <= not FX2_SLRD_N; R_MONI_C.slwr <= not FX2_SLWR_N; R_MONI_C.pktend <= not FX2_PKTEND_N; + case R_REGS.state is + when s_idle => R_MONI_C.fsm_idle <= '1'; + when s_rxprep0 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_rx <= '1'; + when s_rxprep1 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_rx <= '1'; + when s_rxprep2 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_rx <= '1'; + when s_rxdisp => R_MONI_C.fsm_disp <= '1'; R_MONI_C.fsm_rx <= '1'; + when s_rxpipe => R_MONI_C.fsm_pipe <= '1'; R_MONI_C.fsm_rx <= '1'; + when s_txprep0 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_tx <= '1'; + when s_txprep1 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_tx <= '1'; + when s_txprep2 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_tx <= '1'; + when s_txdisp => R_MONI_C.fsm_disp <= '1'; R_MONI_C.fsm_tx <= '1'; + when s_tx2prep0 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_tx2 <= '1'; + when s_tx2prep1 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_tx2 <= '1'; + when s_tx2prep2 => R_MONI_C.fsm_prep <= '1'; R_MONI_C.fsm_tx2 <= '1'; + when s_tx2disp => R_MONI_C.fsm_disp <= '1'; R_MONI_C.fsm_tx2 <= '1'; + when others => null; + end case; + R_MONI_S <= R_MONI_C; end if; end if; diff --git a/rtl/bplib/fx2lib/fx2lib.vhd b/rtl/bplib/fx2lib/fx2lib.vhd index 9a346925..6498e01f 100644 --- a/rtl/bplib/fx2lib/fx2lib.vhd +++ b/rtl/bplib/fx2lib/fx2lib.vhd @@ -1,6 +1,6 @@ --- $Id: fx2lib.vhd 638 2015-01-25 22:01:38Z mueller $ +-- $Id: fx2lib.vhd 888 2017-04-30 13:06:51Z mueller $ -- --- Copyright 2011-2015 by Walter F.J. Mueller +-- Copyright 2011-2017 by Walter F.J. Mueller -- -- This program is free software; you may redistribute and/or modify it under -- the terms of the GNU General Public License as published by the Free @@ -16,10 +16,11 @@ -- Description: Cypress ez-usb fx2 support -- -- Dependencies: - --- Tool versions: xst 12.1-14.7; ghdl 0.26-0.31 +-- Tool versions: xst 12.1-14.7; ghdl 0.26-0.34 -- -- Revision History: -- Date Rev Version Comment +-- 2017-04-30 888 1.5 add fsm_* monitor lines -- 2015-01-25 638 1.4 retire fx2_2fifoctl_as -- 2012-01-14 453 1.3 use afull/aempty logic instead of exporting size -- 2012-01-03 449 1.2.1 reorganize fx2ctl_moni; hardcode ep's @@ -54,6 +55,13 @@ package fx2lib is slrd : slbit; -- read strobe slwr : slbit; -- write strobe pktend : slbit; -- pktend strobe + fsm_idle : slbit; -- fsm: in s_idle + fsm_prep : slbit; -- fsm: in s_*prep* + fsm_disp : slbit; -- fsm: in s_*disp* + fsm_pipe : slbit; -- fsm: in s_rxpipe + fsm_rx : slbit; -- fsm: in s_rx* + fsm_tx : slbit; -- fsm: in s_tx* + fsm_tx2 : slbit; -- fsm: in s_tx2* end record fx2ctl_moni_type; constant fx2ctl_moni_init : fx2ctl_moni_type := ( @@ -61,7 +69,9 @@ package fx2lib is '0','0', -- flag_ep4_(empty|almost) '0','0', -- flag_ep6_(full|almost) '0','0', -- flag_ep8_(full|almost) - '0','0','0' -- slrd, slwr, pktend + '0','0','0', -- slrd, slwr, pktend + '0','0','0','0', -- fsm_(idle|prep|disp|pipe) + '0','0','0' -- fsm_(rx|tx|tx2) );