Line 1... |
Line 1... |
-- $Id: fx2_3fifoctl_ic.vhd 453 2012-01-15 17:51:18Z mueller $
|
-- $Id: fx2_3fifoctl_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-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
|
-- 2012-01-15 453 13.3 O76x xc3s1200e-4 156 259 96 238 s 7.9/7.5
|
--
|
--
|
-- Revision History:
|
-- Revision History:
|
-- Date Rev Version Comment
|
-- Date Rev Version Comment
|
|
-- 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)
|
-- 2012-01-09 453 1.0 Initial version (derived from 2fifo_ic)
|
--
|
--
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
|
|
library ieee;
|
library ieee;
|
Line 96... |
Line 98... |
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
|
s_tx2prep0, -- s_tx2prep0: switch to tx2-fifo
|
s_tx2prep0, -- s_tx2prep0: switch to tx2-fifo
|
Line 113... |
Line 115... |
state : state_type; -- state
|
state : state_type; -- state
|
petocnt : slv(PETOWIDTH-1 downto 0); -- pktend 1 time out counter
|
petocnt : slv(PETOWIDTH-1 downto 0); -- pktend 1 time out counter
|
pe2tocnt : slv(PETOWIDTH-1 downto 0); -- pktend 2 time out counter
|
pe2tocnt : slv(PETOWIDTH-1 downto 0); -- pktend 2 time out counter
|
pepend : slbit; -- pktend 1 pending
|
pepend : slbit; -- pktend 1 pending
|
pe2pend : slbit; -- pktend 2 pending
|
pe2pend : slbit; -- pktend 2 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_ep8_sel : slbit; -- ep8 (tx2) select
|
moni_ep8_sel : slbit; -- ep8 (tx2) select
|
moni_ep4_pf : slbit; -- ep4 (rx) prog flag
|
moni_ep4_pf : slbit; -- ep4 (rx) prog flag
|
Line 130... |
Line 133... |
|
|
constant regs_init : regs_type := (
|
constant regs_init : regs_type := (
|
s_idle, -- state
|
s_idle, -- state
|
petocnt_init, -- petocnt
|
petocnt_init, -- petocnt
|
petocnt_init, -- pe2tocnt
|
petocnt_init, -- pe2tocnt
|
'0','0','0', -- pepend,pe2pend,rxpipe
|
'0','0', -- pepend,pe2pend
|
|
'0','0', -- rxpipe1, rxpipe2
|
ccnt_init, -- ccnt
|
ccnt_init, -- ccnt
|
'0','0','0', -- moni_ep(4|6|8)_sel
|
'0','0','0', -- moni_ep(4|6|8)_sel
|
'0','0','0' -- moni_ep(4|6|8)_pf
|
'0','0','0' -- moni_ep(4|6|8)_pf
|
);
|
);
|
|
|
Line 353... |
Line 357... |
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 idata_do : slv8 := (others=>'0');
|
variable idata_do : slv8 := (others=>'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 sltx2ok : slbit := '0';
|
variable sltx2ok : slbit := '0';
|
variable pipeok : slbit := '0';
|
variable pipeok : slbit := '0';
|
|
|
Line 386... |
Line 388... |
idata_cei := '0';
|
idata_cei := '0';
|
idata_ceo := '0';
|
idata_ceo := '0';
|
idata_oe := '0';
|
idata_oe := '0';
|
idata_do := TXFIFO_DO;
|
idata_do := TXFIFO_DO;
|
|
|
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!
|
sltx2ok := FX2_FLAG_N(c_flag_tx2_ff); -- full flag is act.low!
|
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!
|
pipeok := FX2_FLAG_N(c_flag_prog); -- almost flag is act.low!
|
|
|
Line 401... |
Line 401... |
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 432... |
Line 434... |
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 chunk done and tx2 or pe2 pending and possible
|
-- if chunk done and tx2 or pe2 pending and possible
|
elsif cc_done='1' and sltx2ok='1' and (TX2FIFO_VAL='1' or r.pe2pend='1')
|
elsif cc_done='1' and sltx2ok='1' and (TX2FIFO_VAL='1' or r.pe2pend='1')
|
then
|
then
|
|
if r.rxpipe1='1' or r.rxpipe2='1' then -- rx pipe busy ?
|
|
n.state := s_rxdisp; -- wait
|
|
else
|
n.state := s_tx2prep0;
|
n.state := s_tx2prep0;
|
|
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 560... |
Line 564... |
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);
|