Line 1... |
Line 1... |
-- $Id: fx2_2fifoctl_ic.vhd 453 2012-01-15 17:51:18Z mueller $
|
-- $Id: fx2_2fifoctl_ic.vhd 472 2013-01-06 14:39:10Z mueller $
|
--
|
--
|
-- Copyright 2012- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
-- Copyright 2012-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
--
|
--
|
-- This program is free software; you may redistribute and/or modify it under
|
-- 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
|
-- the terms of the GNU General Public License as published by the Free
|
-- Software Foundation, either version 2, or at your option any later version.
|
-- Software Foundation, either version 2, or at your option any later version.
|
--
|
--
|
Line 25... |
Line 25... |
-- Target Devices: generic
|
-- Target Devices: generic
|
-- Tool versions: xst 13.3; ghdl 0.29
|
-- Tool versions: xst 13.3; ghdl 0.29
|
--
|
--
|
-- Synthesized (xst):
|
-- Synthesized (xst):
|
-- Date Rev ise Target flop lutl lutm slic t peri
|
-- Date Rev ise Target flop lutl lutm slic t peri
|
-- 2012-01-14 453 13.3 O76x xc3s1200e-4 101 173 64 159 s 8.3/7.4
|
-- 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
|
-- 2012-01-08 451 13.3 O76x xc3s1200e-4 110 166 64 163 s 7.5
|
--
|
--
|
-- Revision History:
|
-- Revision History:
|
-- Date Rev Version Comment
|
-- Date Rev Version Comment
|
|
-- 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-15 453 1.1 use aempty/afull logic; collapse tx and pe flows
|
-- 2012-01-09 451 1.0 Initial version
|
-- 2012-01-09 451 1.0 Initial version
|
-- 2012-01-01 448 0.5 First draft
|
-- 2012-01-01 448 0.5 First draft
|
--
|
--
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
Line 93... |
Line 95... |
s_idle, -- s_idle: idle state
|
s_idle, -- s_idle: idle state
|
s_rxprep0, -- s_rxprep0: switch to rx-fifo
|
s_rxprep0, -- s_rxprep0: switch to rx-fifo
|
s_rxprep1, -- s_rxprep1: fifo addr setup
|
s_rxprep1, -- s_rxprep1: fifo addr setup
|
s_rxprep2, -- s_rxprep2: wait for flags
|
s_rxprep2, -- s_rxprep2: wait for flags
|
s_rxdisp, -- s_rxdisp: read, dispatch
|
s_rxdisp, -- s_rxdisp: read, dispatch
|
s_rxpipe, -- s_rxpipe: read, pipe drain
|
s_rxpipe, -- s_rxpipe: read, pipe wait
|
s_txprep0, -- s_txprep0: switch to tx-fifo
|
s_txprep0, -- s_txprep0: switch to tx-fifo
|
s_txprep1, -- s_txprep1: fifo addr setup
|
s_txprep1, -- s_txprep1: fifo addr setup
|
s_txprep2, -- s_txprep2: wait for flags
|
s_txprep2, -- s_txprep2: wait for flags
|
s_txdisp -- s_txdisp: write, dispatch
|
s_txdisp -- s_txdisp: write, dispatch
|
);
|
);
|
|
|
type regs_type is record
|
type regs_type is record
|
state : state_type; -- state
|
state : state_type; -- state
|
petocnt : slv(PETOWIDTH-1 downto 0); -- pktend time out counter
|
petocnt : slv(PETOWIDTH-1 downto 0); -- pktend time out counter
|
pepend : slbit; -- pktend pending
|
pepend : slbit; -- pktend pending
|
rxpipe : slbit; -- read transaction in flight
|
rxpipe1 : slbit; -- read pipe 1: iob capture stage
|
|
rxpipe2 : slbit; -- read pipe 2: fifo write stage
|
ccnt : slv(CCWIDTH-1 downto 0); -- chunk counter
|
ccnt : slv(CCWIDTH-1 downto 0); -- chunk counter
|
moni_ep4_sel : slbit; -- ep4 (rx) select
|
moni_ep4_sel : slbit; -- ep4 (rx) select
|
moni_ep6_sel : slbit; -- ep6 (tx) select
|
moni_ep6_sel : slbit; -- ep6 (tx) select
|
moni_ep4_pf : slbit; -- ep4 (rx) prog flag
|
moni_ep4_pf : slbit; -- ep4 (rx) prog flag
|
moni_ep6_pf : slbit; -- ep6 (tx) prog flag
|
moni_ep6_pf : slbit; -- ep6 (tx) prog flag
|
Line 118... |
Line 121... |
constant ccnt_init : slv(CCWIDTH-1 downto 0) := (others=>'0');
|
constant ccnt_init : slv(CCWIDTH-1 downto 0) := (others=>'0');
|
|
|
constant regs_init : regs_type := (
|
constant regs_init : regs_type := (
|
s_idle, -- state
|
s_idle, -- state
|
petocnt_init, -- petocnt
|
petocnt_init, -- petocnt
|
'0','0', -- pepend,rxpipe
|
'0', -- pepend
|
|
'0','0', -- rxpipe1, rxpipe2
|
ccnt_init, -- ccnt
|
ccnt_init, -- ccnt
|
'0','0', -- moni_ep(4|6)_sel
|
'0','0', -- moni_ep(4|6)_sel
|
'0','0' -- moni_ep(4|6)_pf
|
'0','0' -- moni_ep(4|6)_pf
|
);
|
);
|
|
|
Line 311... |
Line 315... |
|
|
variable idata_cei : slbit := '0';
|
variable idata_cei : slbit := '0';
|
variable idata_ceo : slbit := '0';
|
variable idata_ceo : slbit := '0';
|
variable idata_oe : slbit := '0';
|
variable idata_oe : slbit := '0';
|
|
|
variable imoni : fx2ctl_moni_type := fx2ctl_moni_init;
|
|
|
|
variable slrxok : slbit := '0';
|
variable slrxok : slbit := '0';
|
variable sltxok : slbit := '0';
|
variable sltxok : slbit := '0';
|
variable pipeok : slbit := '0';
|
variable pipeok : slbit := '0';
|
|
|
variable cc_clr : slbit := '0';
|
variable cc_clr : slbit := '0';
|
Line 341... |
Line 343... |
|
|
idata_cei := '0';
|
idata_cei := '0';
|
idata_ceo := '0';
|
idata_ceo := '0';
|
idata_oe := '0';
|
idata_oe := '0';
|
|
|
imoni := fx2ctl_moni_init;
|
|
|
|
slrxok := FX2_FLAG_N(c_flag_rx_ef); -- empty flag is act.low!
|
slrxok := FX2_FLAG_N(c_flag_rx_ef); -- empty flag is act.low!
|
sltxok := FX2_FLAG_N(c_flag_tx_ff); -- full flag is act.low!
|
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!
|
pipeok := FX2_FLAG_N(c_flag_prog); -- almost flag is act.low!
|
|
|
cc_clr := '0';
|
cc_clr := '0';
|
Line 355... |
Line 355... |
cc_done := '1';
|
cc_done := '1';
|
else
|
else
|
cc_done := '0';
|
cc_done := '0';
|
end if;
|
end if;
|
|
|
|
n.rxpipe1 := '0';
|
|
|
case r.state is
|
case r.state is
|
when s_idle => -- s_idle:
|
when s_idle => -- s_idle:
|
if slrxok='1' and RXFIFO_BUSY='0' then
|
if slrxok='1' and RXFIFO_BUSY='0' then
|
ififo_ce := '1';
|
ififo_ce := '1';
|
ififo := c_rxfifo;
|
ififo := c_rxfifo;
|
Line 382... |
Line 384... |
isloe := '1';
|
isloe := '1';
|
n.state := s_rxdisp;
|
n.state := s_rxdisp;
|
|
|
when s_rxdisp => -- s_rxdisp: read, dispatch
|
when s_rxdisp => -- s_rxdisp: read, dispatch
|
isloe := '1';
|
isloe := '1';
|
if r.rxpipe = '1' then -- read in flight ?
|
|
irxfifo_ena := '1'; -- capture rxdata
|
|
n.rxpipe := '0';
|
|
end if;
|
|
|
|
-- if chunk done and tx or pe pending and possible
|
-- if chunk done and tx or pe pending and possible
|
if cc_done='1' and sltxok='1' and (TXFIFO_VAL='1' or r.pepend='1') then
|
if cc_done='1' and sltxok='1' and (TXFIFO_VAL='1' or r.pepend='1') then
|
n.state := s_txprep0;
|
if r.rxpipe1='1' or r.rxpipe2='1' then -- rx pipe busy ?
|
|
n.state := s_rxdisp; -- wait
|
|
else
|
|
n.state := s_txprep0; -- otherwise switch to tx flow
|
|
end if;
|
-- if more rx to do and possible
|
-- if more rx to do and possible
|
elsif slrxok='1' and RXFIFO_BUSY='0' then
|
elsif slrxok='1' and unsigned(RXSIZE_FX2)>3 then -- !thres must be >3!
|
cc_cnt := '1';
|
|
idata_cei := '1';
|
|
islrd := '1';
|
islrd := '1';
|
if false and pipeok='1' and unsigned(RXSIZE_FX2)>2 then
|
cc_cnt := '1';
|
n.rxpipe := '1';
|
n.rxpipe1 := '1';
|
n.state := s_rxdisp;
|
if pipeok='1' then
|
|
n.state := s_rxdisp; -- 1 cycle read
|
|
--n.state := s_rxprep2; -- 2 cycle read
|
else
|
else
|
n.state := s_rxpipe;
|
n.state := s_rxpipe;
|
end if;
|
end if;
|
-- otherwise back to idle
|
-- otherwise back to idle
|
else
|
else
|
n.state := s_idle;
|
if r.rxpipe1='1' or r.rxpipe2='1' then -- rx pipe busy ?
|
|
n.state := s_rxdisp; -- wait
|
|
else
|
|
n.state := s_idle; -- to idle
|
|
end if;
|
end if;
|
end if;
|
|
|
when s_rxpipe => -- s_rxpipe: read, pipe drain
|
when s_rxpipe => -- s_rxpipe: read, pipe wait
|
isloe := '1';
|
isloe := '1';
|
irxfifo_ena := '1'; -- capture rxdata
|
|
if pipeok='1' and unsigned(RXSIZE_FX2)>1 then
|
|
n.state := s_rxdisp;
|
|
else
|
|
n.state := s_rxprep2;
|
n.state := s_rxprep2;
|
end if;
|
|
|
|
when s_txprep0 => -- s_txprep0: switch to tx-fifo
|
when s_txprep0 => -- s_txprep0: switch to tx-fifo
|
ififo_ce := '1';
|
ififo_ce := '1';
|
ififo := c_txfifo;
|
ififo := c_txfifo;
|
n.state := s_txprep1;
|
n.state := s_txprep1;
|
Line 457... |
Line 457... |
end if;
|
end if;
|
|
|
when others => null;
|
when others => null;
|
end case;
|
end case;
|
|
|
|
-- rx pipe handling
|
|
idata_cei := r.rxpipe1;
|
|
n.rxpipe2 := r.rxpipe1;
|
|
irxfifo_ena := r.rxpipe2;
|
|
|
-- chunk counter handling
|
-- chunk counter handling
|
if cc_clr = '1' then
|
if cc_clr = '1' then
|
n.ccnt := (others=>'1');
|
n.ccnt := (others=>'1');
|
elsif cc_cnt='1' and unsigned(r.ccnt) > 0 then
|
elsif cc_cnt='1' and unsigned(r.ccnt) > 0 then
|
n.ccnt := slv(unsigned(r.ccnt) - 1);
|
n.ccnt := slv(unsigned(r.ccnt) - 1);
|