URL
https://opencores.org/ocsvn/w11/w11/trunk
Subversion Repositories w11
Compare Revisions
- This comparison shows the changes necessary to convert path
/w11/tags/w11a_V0.6/rtl/bplib/fx2lib
- from Rev 19 to Rev 24
- ↔ Reverse comparison
Rev 19 → Rev 24
/Makefile
0,0 → 1,26
# $Id: Makefile 477 2013-01-27 14:07:10Z mueller $ |
# |
# Revision History: |
# Date Rev Version Comment |
# 2011-08-13 405 1.1 use includes from rtl/make |
# 2010-05-23 293 1.0 Initial version (cloned..) |
# |
VBOM_all = $(wildcard *.vbom) |
NGC_all = $(VBOM_all:.vbom=.ngc) |
# |
include $(RETROBASE)/rtl/make/xflow_default_nexys2.mk |
# |
.PHONY : all clean |
# |
all : $(NGC_all) |
# |
clean : ise_clean |
# |
#---- |
# |
include $(RETROBASE)/rtl/make/generic_xflow.mk |
# |
ifndef DONTINCDEP |
include $(VBOM_all:.vbom=.dep_xst) |
endif |
# |
/fx2_2fifoctl_ic.vhd
0,0 → 1,566
-- $Id: fx2_2fifoctl_ic.vhd 472 2013-01-06 14:39:10Z mueller $ |
-- |
-- 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 |
-- 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. |
-- |
-- This program is distributed in the hope that it will be useful, but |
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY |
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
-- for complete details. |
-- |
------------------------------------------------------------------------------ |
-- Module Name: fx2_2fifoctl_ic - syn |
-- Description: Cypress EZ-USB FX2 driver (2 fifo; int clk) |
-- |
-- Dependencies: vlib/xlib/iob_reg_o |
-- vlib/xlib/iob_reg_i_gen |
-- vlib/xlib/iob_reg_o_gen |
-- vlib/xlib/iob_reg_io_gen |
-- memlib/fifo_2c_dram |
-- |
-- Test bench: - |
-- Target Devices: generic |
-- Tool versions: xst 13.3; ghdl 0.29 |
-- |
-- Synthesized (xst): |
-- Date Rev ise Target flop lutl lutm slic t peri |
-- 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 |
-- 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 |
-- 2012-01-01 448 0.5 First draft |
-- |
------------------------------------------------------------------------------ |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.slvtypes.all; |
use work.xlib.all; |
use work.memlib.all; |
use work.fx2lib.all; |
|
entity fx2_2fifoctl_ic is -- EZ-USB FX2 driver (2 fifo; int clk) |
generic ( |
RXFAWIDTH : positive := 5; -- receive fifo address width |
TXFAWIDTH : positive := 5; -- transmit fifo address width |
PETOWIDTH : positive := 7; -- packet end time-out counter width |
CCWIDTH : positive := 5; -- chunk counter width |
RXAEMPTY_THRES : natural := 1; -- threshold for rx aempty flag |
TXAFULL_THRES : natural := 1); -- threshold for tx afull flag |
port ( |
CLK : in slbit; -- clock |
RESET : in slbit := '0'; -- reset |
RXDATA : out slv8; -- receive data out |
RXVAL : out slbit; -- receive data valid |
RXHOLD : in slbit; -- receive data hold |
RXAEMPTY : out slbit; -- receive almost empty flag |
TXDATA : in slv8; -- transmit data in |
TXENA : in slbit; -- transmit data enable |
TXBUSY : out slbit; -- transmit data busy |
TXAFULL : out slbit; -- transmit almost full flag |
MONI : out fx2ctl_moni_type; -- monitor port data |
I_FX2_IFCLK : in slbit; -- fx2: interface clock |
O_FX2_FIFO : out slv2; -- fx2: fifo address |
I_FX2_FLAG : in slv4; -- fx2: fifo flags |
O_FX2_SLRD_N : out slbit; -- fx2: read enable (act.low) |
O_FX2_SLWR_N : out slbit; -- fx2: write enable (act.low) |
O_FX2_SLOE_N : out slbit; -- fx2: output enable (act.low) |
O_FX2_PKTEND_N : out slbit; -- fx2: packet end (act.low) |
IO_FX2_DATA : inout slv8 -- fx2: data lines |
); |
end fx2_2fifoctl_ic; |
|
|
architecture syn of fx2_2fifoctl_ic is |
|
constant c_rxfifo : slv2 := c_fifo_ep4; |
constant c_txfifo : slv2 := c_fifo_ep6; |
|
constant c_flag_prog : integer := 0; |
constant c_flag_tx_ff : integer := 1; |
constant c_flag_rx_ef : integer := 2; |
constant c_flag_tx2_ff : integer := 3; |
|
type state_type is ( |
s_idle, -- s_idle: idle state |
s_rxprep0, -- s_rxprep0: switch to rx-fifo |
s_rxprep1, -- s_rxprep1: fifo addr setup |
s_rxprep2, -- s_rxprep2: wait for flags |
s_rxdisp, -- s_rxdisp: read, dispatch |
s_rxpipe, -- s_rxpipe: read, pipe wait |
s_txprep0, -- s_txprep0: switch to tx-fifo |
s_txprep1, -- s_txprep1: fifo addr setup |
s_txprep2, -- s_txprep2: wait for flags |
s_txdisp -- s_txdisp: write, dispatch |
); |
|
type regs_type is record |
state : state_type; -- state |
petocnt : slv(PETOWIDTH-1 downto 0); -- pktend time out counter |
pepend : slbit; -- pktend pending |
rxpipe1 : slbit; -- read pipe 1: iob capture stage |
rxpipe2 : slbit; -- read pipe 2: fifo write stage |
ccnt : slv(CCWIDTH-1 downto 0); -- chunk counter |
moni_ep4_sel : slbit; -- ep4 (rx) select |
moni_ep6_sel : slbit; -- ep6 (tx) select |
moni_ep4_pf : slbit; -- ep4 (rx) prog flag |
moni_ep6_pf : slbit; -- ep6 (tx) prog flag |
end record regs_type; |
|
constant petocnt_init : slv(PETOWIDTH-1 downto 0) := (others=>'0'); |
constant ccnt_init : slv(CCWIDTH-1 downto 0) := (others=>'0'); |
|
constant regs_init : regs_type := ( |
s_idle, -- state |
petocnt_init, -- petocnt |
'0', -- pepend |
'0','0', -- rxpipe1, rxpipe2 |
ccnt_init, -- ccnt |
'0','0', -- moni_ep(4|6)_sel |
'0','0' -- moni_ep(4|6)_pf |
); |
|
signal R_REGS : regs_type := regs_init; -- state registers |
signal N_REGS : regs_type := regs_init; -- next value state regs |
|
signal FX2_FIFO : slv2 := (others=>'0'); |
signal FX2_FIFO_CE : slbit := '0'; |
signal FX2_FLAG_N : slv4 := (others=>'0'); |
signal FX2_SLRD_N : slbit := '1'; |
signal FX2_SLWR_N : slbit := '1'; |
signal FX2_SLOE_N : slbit := '1'; |
signal FX2_PKTEND_N : slbit := '1'; |
signal FX2_DATA_CEI : slbit := '0'; |
signal FX2_DATA_CEO : slbit := '0'; |
signal FX2_DATA_OE : slbit := '0'; |
|
signal RXFIFO_DI : slv8 := (others=>'0'); |
signal RXFIFO_ENA : slbit := '0'; |
signal RXFIFO_BUSY : slbit := '0'; |
signal RXSIZE_FX2 : slv(RXFAWIDTH-1 downto 0) := (others=>'0'); |
signal RXSIZE_USR : slv(RXFAWIDTH-1 downto 0) := (others=>'0'); |
signal TXFIFO_DO : slv8 := (others=>'0'); |
signal TXFIFO_VAL : slbit := '0'; |
signal TXFIFO_HOLD : slbit := '0'; |
signal TXSIZE_FX2 : slv(TXFAWIDTH-1 downto 0) := (others=>'0'); |
signal TXSIZE_USR : slv(TXFAWIDTH-1 downto 0) := (others=>'0'); |
|
signal TXBUSY_L : slbit := '0'; |
|
signal R_MONI_C : fx2ctl_moni_type := fx2ctl_moni_init; |
signal R_MONI_S : fx2ctl_moni_type := fx2ctl_moni_init; |
|
begin |
|
assert RXAEMPTY_THRES<=2**RXFAWIDTH-1 and |
TXAFULL_THRES<=2**TXFAWIDTH-1 |
report "assert((RXAEMPTY|TXAFULL)_THRES <= 2**(RX|TX)FAWIDTH)-1" |
severity failure; |
|
|
IOB_FX2_FIFO : iob_reg_o_gen |
generic map ( |
DWIDTH => 2, |
INIT => '0') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => FX2_FIFO_CE, |
DO => FX2_FIFO, |
PAD => O_FX2_FIFO |
); |
|
IOB_FX2_FLAG : iob_reg_i_gen |
generic map ( |
DWIDTH => 4, |
INIT => '0') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => '1', |
DI => FX2_FLAG_N, |
PAD => I_FX2_FLAG |
); |
|
IOB_FX2_SLRD : iob_reg_o |
generic map ( |
INIT => '1') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => '1', |
DO => FX2_SLRD_N, |
PAD => O_FX2_SLRD_N |
); |
|
IOB_FX2_SLWR : iob_reg_o |
generic map ( |
INIT => '1') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => '1', |
DO => FX2_SLWR_N, |
PAD => O_FX2_SLWR_N |
); |
|
IOB_FX2_SLOE : iob_reg_o |
generic map ( |
INIT => '1') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => '1', |
DO => FX2_SLOE_N, |
PAD => O_FX2_SLOE_N |
); |
|
IOB_FX2_PKTEND : iob_reg_o |
generic map ( |
INIT => '1') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => '1', |
DO => FX2_PKTEND_N, |
PAD => O_FX2_PKTEND_N |
); |
|
IOB_FX2_DATA : iob_reg_io_gen |
generic map ( |
DWIDTH => 8, |
PULL => "KEEP") |
port map ( |
CLK => I_FX2_IFCLK, |
CEI => FX2_DATA_CEI, |
CEO => FX2_DATA_CEO, |
OE => FX2_DATA_OE, |
DI => RXFIFO_DI, -- input data (read from pad) |
DO => TXFIFO_DO, -- output data (write to pad) |
PAD => IO_FX2_DATA |
); |
|
RXFIFO : fifo_2c_dram -- input fifo, 2 clock, dram based |
generic map ( |
AWIDTH => RXFAWIDTH, |
DWIDTH => 8) |
port map ( |
CLKW => I_FX2_IFCLK, |
CLKR => CLK, |
RESETW => '0', |
RESETR => RESET, |
DI => RXFIFO_DI, |
ENA => RXFIFO_ENA, |
BUSY => RXFIFO_BUSY, |
DO => RXDATA, |
VAL => RXVAL, |
HOLD => RXHOLD, |
SIZEW => RXSIZE_FX2, |
SIZER => RXSIZE_USR |
); |
|
TXFIFO : fifo_2c_dram -- output fifo, 2 clock, dram based |
generic map ( |
AWIDTH => TXFAWIDTH, |
DWIDTH => 8) |
port map ( |
CLKW => CLK, |
CLKR => I_FX2_IFCLK, |
RESETW => RESET, |
RESETR => '0', |
DI => TXDATA, |
ENA => TXENA, |
BUSY => TXBUSY_L, |
DO => TXFIFO_DO, |
VAL => TXFIFO_VAL, |
HOLD => TXFIFO_HOLD, |
SIZEW => TXSIZE_USR, |
SIZER => TXSIZE_FX2 |
); |
|
proc_regs: process (I_FX2_IFCLK) |
begin |
|
if rising_edge(I_FX2_IFCLK) then |
if RESET = '1' then |
R_REGS <= regs_init; |
else |
R_REGS <= N_REGS; |
end if; |
end if; |
|
end process proc_regs; |
|
proc_next: process (R_REGS, |
FX2_FLAG_N, TXFIFO_VAL, RXSIZE_FX2, |
RXFIFO_BUSY, TXBUSY_L) |
|
variable r : regs_type := regs_init; |
variable n : regs_type := regs_init; |
|
variable ififo_ce : slbit := '0'; |
variable ififo : slv2 := "00"; |
|
variable irxfifo_ena : slbit := '0'; |
variable itxfifo_hold : slbit := '0'; |
|
variable islrd : slbit := '0'; |
variable islwr : slbit := '0'; |
variable isloe : slbit := '0'; |
variable ipktend : slbit := '0'; |
|
variable idata_cei : slbit := '0'; |
variable idata_ceo : slbit := '0'; |
variable idata_oe : slbit := '0'; |
|
variable slrxok : slbit := '0'; |
variable sltxok : slbit := '0'; |
variable pipeok : slbit := '0'; |
|
variable cc_clr : slbit := '0'; |
variable cc_cnt : slbit := '0'; |
variable cc_done : slbit := '0'; |
|
begin |
|
r := R_REGS; |
n := R_REGS; |
|
ififo_ce := '0'; |
ififo := "00"; |
|
irxfifo_ena := '0'; |
itxfifo_hold := '1'; |
|
islrd := '0'; |
islwr := '0'; |
isloe := '0'; |
ipktend := '0'; |
|
idata_cei := '0'; |
idata_ceo := '0'; |
idata_oe := '0'; |
|
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! |
pipeok := FX2_FLAG_N(c_flag_prog); -- almost flag is act.low! |
|
cc_clr := '0'; |
cc_cnt := '0'; |
if unsigned(r.ccnt) = 0 then |
cc_done := '1'; |
else |
cc_done := '0'; |
end if; |
|
n.rxpipe1 := '0'; |
|
case r.state is |
when s_idle => -- s_idle: |
if slrxok='1' and RXFIFO_BUSY='0' then |
ififo_ce := '1'; |
ififo := c_rxfifo; |
n.state := s_rxprep1; |
elsif sltxok='1' and (TXFIFO_VAL='1' or r.pepend='1')then |
ififo_ce := '1'; |
ififo := c_txfifo; |
n.state := s_txprep1; |
end if; |
|
when s_rxprep0 => -- s_rxprep0: switch to rx-fifo |
ififo_ce := '1'; |
ififo := c_rxfifo; |
n.state := s_rxprep1; |
|
when s_rxprep1 => -- s_rxprep1: fifo addr setup |
cc_clr := '1'; |
n.state := s_rxprep2; |
|
when s_rxprep2 => -- s_rxprep2: wait for flags |
isloe := '1'; |
n.state := s_rxdisp; |
|
when s_rxdisp => -- s_rxdisp: read, dispatch |
isloe := '1'; |
-- 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 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 |
elsif slrxok='1' and unsigned(RXSIZE_FX2)>3 then -- !thres must be >3! |
islrd := '1'; |
cc_cnt := '1'; |
n.rxpipe1 := '1'; |
if pipeok='1' then |
n.state := s_rxdisp; -- 1 cycle read |
--n.state := s_rxprep2; -- 2 cycle read |
else |
n.state := s_rxpipe; |
end if; |
-- otherwise back to idle |
else |
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; |
|
when s_rxpipe => -- s_rxpipe: read, pipe wait |
isloe := '1'; |
n.state := s_rxprep2; |
|
when s_txprep0 => -- s_txprep0: switch to tx-fifo |
ififo_ce := '1'; |
ififo := c_txfifo; |
n.state := s_txprep1; |
|
when s_txprep1 => -- s_txprep1: fifo addr setup |
cc_clr := '1'; |
n.state := s_txprep2; |
|
when s_txprep2 => -- s_txprep2: wait for flags |
n.state := s_txdisp; |
|
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 |
n.state := s_rxprep0; |
-- if pktend to do and possible |
elsif sltxok = '1' and r.pepend = '1' then |
ipktend := '1'; |
n.pepend := '0'; |
n.state := s_idle; |
-- if more tx to do and possible |
elsif sltxok = '1' and TXFIFO_VAL = '1' then |
cc_cnt := '1'; -- inc chunk count |
n.pepend := '0'; -- cancel pe (avoid back-2-back tx+pe) |
itxfifo_hold := '0'; |
idata_ceo := '1'; |
idata_oe := '1'; |
islwr := '1'; |
if pipeok = '1' then -- if not almost full |
n.state := s_txdisp; -- stream |
else |
n.state := s_txprep1; -- wait for full flag |
end if; |
-- otherwise back to idle |
else |
n.state := s_idle; |
end if; |
|
when others => null; |
end case; |
|
-- rx pipe handling |
idata_cei := r.rxpipe1; |
n.rxpipe2 := r.rxpipe1; |
irxfifo_ena := r.rxpipe2; |
|
-- chunk counter handling |
if cc_clr = '1' then |
n.ccnt := (others=>'1'); |
elsif cc_cnt='1' and unsigned(r.ccnt) > 0 then |
n.ccnt := slv(unsigned(r.ccnt) - 1); |
end if; |
|
-- pktend time-out handling: |
-- if tx fifo is non-empty, set counter to max |
-- if tx fifo is empty, count down every usec |
-- on 1->0 transition queue pktend request |
if TXFIFO_VAL = '1' then |
n.petocnt := (others=>'1'); |
else |
if unsigned(r.petocnt) /= 0 then |
n.petocnt := slv(unsigned(r.petocnt) - 1); |
if unsigned(r.petocnt) = 1 then |
n.pepend := '1'; |
end if; |
end if; |
end if; |
|
n.moni_ep4_sel := '0'; |
n.moni_ep6_sel := '0'; |
if r.state = s_rxdisp or r.state = s_rxpipe then |
n.moni_ep4_sel := '1'; |
n.moni_ep4_pf := not FX2_FLAG_N(c_flag_prog); |
elsif r.state = s_txdisp then |
n.moni_ep6_sel := '1'; |
n.moni_ep6_pf := not FX2_FLAG_N(c_flag_prog); |
end if; |
|
N_REGS <= n; |
|
FX2_FIFO_CE <= ififo_ce; |
FX2_FIFO <= ififo; |
|
FX2_SLRD_N <= not islrd; |
FX2_SLWR_N <= not islwr; |
FX2_SLOE_N <= not isloe; |
FX2_PKTEND_N <= not ipktend; |
|
FX2_DATA_CEI <= idata_cei; |
FX2_DATA_CEO <= idata_ceo; |
FX2_DATA_OE <= idata_oe; |
|
RXFIFO_ENA <= irxfifo_ena; |
TXFIFO_HOLD <= itxfifo_hold; |
|
end process proc_next; |
|
proc_moni: process (CLK) |
begin |
|
if rising_edge(CLK) then |
if RESET = '1' then |
R_MONI_C <= fx2ctl_moni_init; |
R_MONI_S <= fx2ctl_moni_init; |
else |
R_MONI_C <= fx2ctl_moni_init; |
R_MONI_C.fifo_ep4 <= R_REGS.moni_ep4_sel; |
R_MONI_C.fifo_ep6 <= R_REGS.moni_ep6_sel; |
R_MONI_C.flag_ep4_empty <= not FX2_FLAG_N(c_flag_rx_ef); |
R_MONI_C.flag_ep4_almost <= R_REGS.moni_ep4_pf; |
R_MONI_C.flag_ep6_full <= not FX2_FLAG_N(c_flag_tx_ff); |
R_MONI_C.flag_ep6_almost <= R_REGS.moni_ep6_pf; |
R_MONI_C.slrd <= not FX2_SLRD_N; |
R_MONI_C.slwr <= not FX2_SLWR_N; |
R_MONI_C.pktend <= not FX2_PKTEND_N; |
R_MONI_S <= R_MONI_C; |
end if; |
end if; |
|
end process proc_moni; |
|
proc_almost: process (RXSIZE_USR, TXSIZE_USR) |
begin |
|
-- rxsize_usr is the number of bytes to read |
-- txsize_usr is the number of bytes to write |
|
if unsigned(RXSIZE_USR) <= RXAEMPTY_THRES then |
RXAEMPTY <= '1'; |
else |
RXAEMPTY <= '0'; |
end if; |
|
if unsigned(TXSIZE_USR) <= TXAFULL_THRES then |
TXAFULL <= '1'; |
else |
TXAFULL <= '0'; |
end if; |
|
end process proc_almost; |
|
TXBUSY <= TXBUSY_L; |
|
MONI <= R_MONI_S; |
|
end syn; |
/fx2_3fifoctl_ic.vhd
0,0 → 1,699
-- $Id: fx2_3fifoctl_ic.vhd 472 2013-01-06 14:39:10Z mueller $ |
-- |
-- 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 |
-- 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. |
-- |
-- This program is distributed in the hope that it will be useful, but |
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY |
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
-- for complete details. |
-- |
------------------------------------------------------------------------------ |
-- Module Name: fx2_3fifoctl_ic - syn |
-- Description: Cypress EZ-USB FX2 driver (3 fifo; int clk) |
-- |
-- Dependencies: vlib/xlib/iob_reg_o |
-- vlib/xlib/iob_reg_i_gen |
-- vlib/xlib/iob_reg_o_gen |
-- vlib/xlib/iob_reg_io_gen |
-- memlib/fifo_2c_dram |
-- |
-- Test bench: - |
-- Target Devices: generic |
-- Tool versions: xst 13.3; ghdl 0.29 |
-- |
-- Synthesized (xst): |
-- 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 |
-- |
-- Revision History: |
-- 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) |
-- |
------------------------------------------------------------------------------ |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.slvtypes.all; |
use work.xlib.all; |
use work.memlib.all; |
use work.fx2lib.all; |
|
entity fx2_3fifoctl_ic is -- EZ-USB FX2 driver (3 fifo; int clk) |
generic ( |
RXFAWIDTH : positive := 5; -- receive fifo address width |
TXFAWIDTH : positive := 5; -- transmit fifo address width |
PETOWIDTH : positive := 7; -- packet end time-out counter width |
CCWIDTH : positive := 5; -- chunk counter width |
RXAEMPTY_THRES : natural := 1; -- threshold for rx aempty flag |
TXAFULL_THRES : natural := 1; -- threshold for tx afull flag |
TX2AFULL_THRES : natural := 1); -- threshold for tx2 afull flag |
port ( |
CLK : in slbit; -- clock |
RESET : in slbit := '0'; -- reset |
RXDATA : out slv8; -- receive data out |
RXVAL : out slbit; -- receive data valid |
RXHOLD : in slbit; -- receive data hold |
RXAEMPTY : out slbit; -- receive almost empty flag |
TXDATA : in slv8; -- transmit 1 data in |
TXENA : in slbit; -- transmit 1 data enable |
TXBUSY : out slbit; -- transmit 1 data busy |
TXAFULL : out slbit; -- transmit 1 almost full flag |
TX2DATA : in slv8; -- transmit 2 data in |
TX2ENA : in slbit; -- transmit 2 data enable |
TX2BUSY : out slbit; -- transmit 2 data busy |
TX2AFULL : out slbit; -- transmit 2 almost full flag |
MONI : out fx2ctl_moni_type; -- monitor port data |
I_FX2_IFCLK : in slbit; -- fx2: interface clock |
O_FX2_FIFO : out slv2; -- fx2: fifo address |
I_FX2_FLAG : in slv4; -- fx2: fifo flags |
O_FX2_SLRD_N : out slbit; -- fx2: read enable (act.low) |
O_FX2_SLWR_N : out slbit; -- fx2: write enable (act.low) |
O_FX2_SLOE_N : out slbit; -- fx2: output enable (act.low) |
O_FX2_PKTEND_N : out slbit; -- fx2: packet end (act.low) |
IO_FX2_DATA : inout slv8 -- fx2: data lines |
); |
end fx2_3fifoctl_ic; |
|
|
architecture syn of fx2_3fifoctl_ic is |
|
constant c_rxfifo : slv2 := c_fifo_ep4; |
constant c_txfifo : slv2 := c_fifo_ep6; |
constant c_tx2fifo: slv2 := c_fifo_ep8; |
|
constant c_flag_prog : integer := 0; |
constant c_flag_tx_ff : integer := 1; |
constant c_flag_rx_ef : integer := 2; |
constant c_flag_tx2_ff : integer := 3; |
|
type state_type is ( |
s_idle, -- s_idle: idle state |
s_rxprep0, -- s_rxprep0: switch to rx-fifo |
s_rxprep1, -- s_rxprep1: fifo addr setup |
s_rxprep2, -- s_rxprep2: wait for flags |
s_rxdisp, -- s_rxdisp: read, dispatch |
s_rxpipe, -- s_rxpipe: read, pipe wait |
s_txprep0, -- s_txprep0: switch to tx-fifo |
s_txprep1, -- s_txprep1: fifo addr setup |
s_txprep2, -- s_txprep2: wait for flags |
s_txdisp, -- s_txdisp: write, dispatch |
s_tx2prep0, -- s_tx2prep0: switch to tx2-fifo |
s_tx2prep1, -- s_tx2prep1: fifo addr setup |
s_tx2prep2, -- s_tx2prep2: wait for flags |
s_tx2disp -- s_tx2disp: write, dispatch |
); |
|
type regs_type is record |
state : state_type; -- state |
petocnt : slv(PETOWIDTH-1 downto 0); -- pktend 1 time out counter |
pe2tocnt : slv(PETOWIDTH-1 downto 0); -- pktend 2 time out counter |
pepend : slbit; -- pktend 1 pending |
pe2pend : slbit; -- pktend 2 pending |
rxpipe1 : slbit; -- read pipe 1: iob capture stage |
rxpipe2 : slbit; -- read pipe 2: fifo write stage |
ccnt : slv(CCWIDTH-1 downto 0); -- chunk counter |
moni_ep4_sel : slbit; -- ep4 (rx) select |
moni_ep6_sel : slbit; -- ep6 (tx) select |
moni_ep8_sel : slbit; -- ep8 (tx2) select |
moni_ep4_pf : slbit; -- ep4 (rx) prog flag |
moni_ep6_pf : slbit; -- ep6 (tx) prog flag |
moni_ep8_pf : slbit; -- ep8 (tx2) prog flag |
end record regs_type; |
|
constant petocnt_init : slv(PETOWIDTH-1 downto 0) := (others=>'0'); |
constant ccnt_init : slv(CCWIDTH-1 downto 0) := (others=>'0'); |
|
constant regs_init : regs_type := ( |
s_idle, -- state |
petocnt_init, -- petocnt |
petocnt_init, -- pe2tocnt |
'0','0', -- pepend,pe2pend |
'0','0', -- rxpipe1, rxpipe2 |
ccnt_init, -- ccnt |
'0','0','0', -- moni_ep(4|6|8)_sel |
'0','0','0' -- moni_ep(4|6|8)_pf |
); |
|
signal R_REGS : regs_type := regs_init; -- state registers |
signal N_REGS : regs_type := regs_init; -- next value state regs |
|
signal FX2_FIFO : slv2 := (others=>'0'); |
signal FX2_FIFO_CE : slbit := '0'; |
signal FX2_FLAG_N : slv4 := (others=>'0'); |
signal FX2_SLRD_N : slbit := '1'; |
signal FX2_SLWR_N : slbit := '1'; |
signal FX2_SLOE_N : slbit := '1'; |
signal FX2_PKTEND_N : slbit := '1'; |
signal FX2_DATA_CEI : slbit := '0'; |
signal FX2_DATA_CEO : slbit := '0'; |
signal FX2_DATA_OE : slbit := '0'; |
signal FX2_DATA_DO : slv8 := (others=>'0'); |
|
signal RXFIFO_DI : slv8 := (others=>'0'); |
signal RXFIFO_ENA : slbit := '0'; |
signal RXFIFO_BUSY : slbit := '0'; |
signal RXSIZE_FX2 : slv(RXFAWIDTH-1 downto 0) := (others=>'0'); |
signal RXSIZE_USR : slv(RXFAWIDTH-1 downto 0) := (others=>'0'); |
signal TXFIFO_DO : slv8 := (others=>'0'); |
signal TXFIFO_VAL : slbit := '0'; |
signal TXFIFO_HOLD : slbit := '0'; |
signal TXSIZE_FX2 : slv(TXFAWIDTH-1 downto 0) := (others=>'0'); |
signal TXSIZE_USR : slv(TXFAWIDTH-1 downto 0) := (others=>'0'); |
signal TX2FIFO_DO : slv8 := (others=>'0'); |
signal TX2FIFO_VAL : slbit := '0'; |
signal TX2FIFO_HOLD : slbit := '0'; |
signal TX2SIZE_FX2 : slv(TXFAWIDTH-1 downto 0) := (others=>'0'); |
signal TX2SIZE_USR : slv(TXFAWIDTH-1 downto 0) := (others=>'0'); |
|
signal TXBUSY_L : slbit := '0'; |
signal TX2BUSY_L : slbit := '0'; |
|
signal R_MONI_C : fx2ctl_moni_type := fx2ctl_moni_init; |
signal R_MONI_S : fx2ctl_moni_type := fx2ctl_moni_init; |
|
begin |
|
assert RXAEMPTY_THRES<=2**RXFAWIDTH-1 and |
TXAFULL_THRES<=2**TXFAWIDTH-1 and |
TX2AFULL_THRES<=2**TXFAWIDTH-1 |
report "assert((RXAEMPTY|TXAFULL|TX2AFULL)_THRES <= 2**(RX|TX)FAWIDTH)-1" |
severity failure; |
|
|
IOB_FX2_FIFO : iob_reg_o_gen |
generic map ( |
DWIDTH => 2, |
INIT => '0') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => FX2_FIFO_CE, |
DO => FX2_FIFO, |
PAD => O_FX2_FIFO |
); |
|
IOB_FX2_FLAG : iob_reg_i_gen |
generic map ( |
DWIDTH => 4, |
INIT => '0') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => '1', |
DI => FX2_FLAG_N, |
PAD => I_FX2_FLAG |
); |
|
IOB_FX2_SLRD : iob_reg_o |
generic map ( |
INIT => '1') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => '1', |
DO => FX2_SLRD_N, |
PAD => O_FX2_SLRD_N |
); |
|
IOB_FX2_SLWR : iob_reg_o |
generic map ( |
INIT => '1') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => '1', |
DO => FX2_SLWR_N, |
PAD => O_FX2_SLWR_N |
); |
|
IOB_FX2_SLOE : iob_reg_o |
generic map ( |
INIT => '1') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => '1', |
DO => FX2_SLOE_N, |
PAD => O_FX2_SLOE_N |
); |
|
IOB_FX2_PKTEND : iob_reg_o |
generic map ( |
INIT => '1') |
port map ( |
CLK => I_FX2_IFCLK, |
CE => '1', |
DO => FX2_PKTEND_N, |
PAD => O_FX2_PKTEND_N |
); |
|
IOB_FX2_DATA : iob_reg_io_gen |
generic map ( |
DWIDTH => 8, |
PULL => "KEEP") |
port map ( |
CLK => I_FX2_IFCLK, |
CEI => FX2_DATA_CEI, |
CEO => FX2_DATA_CEO, |
OE => FX2_DATA_OE, |
DI => RXFIFO_DI, -- input data (read from pad) |
DO => FX2_DATA_DO, -- output data (write to pad) |
PAD => IO_FX2_DATA |
); |
|
RXFIFO : fifo_2c_dram -- input fifo, 2 clock, dram based |
generic map ( |
AWIDTH => RXFAWIDTH, |
DWIDTH => 8) |
port map ( |
CLKW => I_FX2_IFCLK, |
CLKR => CLK, |
RESETW => '0', |
RESETR => RESET, |
DI => RXFIFO_DI, |
ENA => RXFIFO_ENA, |
BUSY => RXFIFO_BUSY, |
DO => RXDATA, |
VAL => RXVAL, |
HOLD => RXHOLD, |
SIZEW => RXSIZE_FX2, |
SIZER => RXSIZE_USR |
); |
|
TXFIFO : fifo_2c_dram -- output fifo, 2 clock, dram based |
generic map ( |
AWIDTH => TXFAWIDTH, |
DWIDTH => 8) |
port map ( |
CLKW => CLK, |
CLKR => I_FX2_IFCLK, |
RESETW => RESET, |
RESETR => '0', |
DI => TXDATA, |
ENA => TXENA, |
BUSY => TXBUSY_L, |
DO => TXFIFO_DO, |
VAL => TXFIFO_VAL, |
HOLD => TXFIFO_HOLD, |
SIZEW => TXSIZE_USR, |
SIZER => TXSIZE_FX2 |
); |
|
TX2FIFO : fifo_2c_dram -- output 2 fifo, 2 clock, dram based |
generic map ( |
AWIDTH => TXFAWIDTH, |
DWIDTH => 8) |
port map ( |
CLKW => CLK, |
CLKR => I_FX2_IFCLK, |
RESETW => RESET, |
RESETR => '0', |
DI => TX2DATA, |
ENA => TX2ENA, |
BUSY => TX2BUSY_L, |
DO => TX2FIFO_DO, |
VAL => TX2FIFO_VAL, |
HOLD => TX2FIFO_HOLD, |
SIZEW => TX2SIZE_USR, |
SIZER => TX2SIZE_FX2 |
); |
|
proc_regs: process (I_FX2_IFCLK) |
begin |
|
if rising_edge(I_FX2_IFCLK) then |
if RESET = '1' then |
R_REGS <= regs_init; |
else |
R_REGS <= N_REGS; |
end if; |
end if; |
|
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) |
|
variable r : regs_type := regs_init; |
variable n : regs_type := regs_init; |
|
variable ififo_ce : slbit := '0'; |
variable ififo : slv2 := "00"; |
|
variable irxfifo_ena : slbit := '0'; |
variable itxfifo_hold : slbit := '0'; |
variable itx2fifo_hold : slbit := '0'; |
|
variable islrd : slbit := '0'; |
variable islwr : slbit := '0'; |
variable isloe : slbit := '0'; |
variable ipktend : slbit := '0'; |
|
variable idata_cei : slbit := '0'; |
variable idata_ceo : slbit := '0'; |
variable idata_oe : slbit := '0'; |
variable idata_do : slv8 := (others=>'0'); |
|
variable slrxok : slbit := '0'; |
variable sltxok : slbit := '0'; |
variable sltx2ok : slbit := '0'; |
variable pipeok : slbit := '0'; |
|
variable cc_clr : slbit := '0'; |
variable cc_cnt : slbit := '0'; |
variable cc_done : slbit := '0'; |
|
begin |
|
r := R_REGS; |
n := R_REGS; |
|
ififo_ce := '0'; |
ififo := "00"; |
|
irxfifo_ena := '0'; |
itxfifo_hold := '1'; |
itx2fifo_hold := '1'; |
|
islrd := '0'; |
islwr := '0'; |
isloe := '0'; |
ipktend := '0'; |
|
idata_cei := '0'; |
idata_ceo := '0'; |
idata_oe := '0'; |
idata_do := TXFIFO_DO; |
|
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! |
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! |
|
cc_clr := '0'; |
cc_cnt := '0'; |
if unsigned(r.ccnt) = 0 then |
cc_done := '1'; |
else |
cc_done := '0'; |
end if; |
|
n.rxpipe1 := '0'; |
|
case r.state is |
when s_idle => -- s_idle: |
if slrxok='1' and RXFIFO_BUSY='0' then |
ififo_ce := '1'; |
ififo := c_rxfifo; |
n.state := s_rxprep1; |
elsif sltxok='1' and (TXFIFO_VAL='1' or r.pepend='1')then |
ififo_ce := '1'; |
ififo := c_txfifo; |
n.state := s_txprep1; |
elsif sltx2ok='1' and (TX2FIFO_VAL='1' or r.pe2pend='1')then |
ififo_ce := '1'; |
ififo := c_tx2fifo; |
n.state := s_tx2prep1; |
end if; |
|
when s_rxprep0 => -- s_rxprep0: switch to rx-fifo |
ififo_ce := '1'; |
ififo := c_rxfifo; |
n.state := s_rxprep1; |
|
when s_rxprep1 => -- s_rxprep1: fifo addr setup |
cc_clr := '1'; |
n.state := s_rxprep2; |
|
when s_rxprep2 => -- s_rxprep2: wait for flags |
isloe := '1'; |
n.state := s_rxdisp; |
|
when s_rxdisp => -- s_rxdisp: read, dispatch |
isloe := '1'; |
-- 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 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 |
elsif cc_done='1' and sltx2ok='1' and (TX2FIFO_VAL='1' or r.pe2pend='1') |
then |
if r.rxpipe1='1' or r.rxpipe2='1' then -- rx pipe busy ? |
n.state := s_rxdisp; -- wait |
else |
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! |
islrd := '1'; |
cc_cnt := '1'; |
n.rxpipe1 := '1'; |
if pipeok='1' then |
n.state := s_rxdisp; -- 1 cycle read |
--n.state := s_rxprep2; -- 2 cycle read |
else |
n.state := s_rxpipe; |
end if; |
-- otherwise back to idle |
else |
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; |
|
when s_rxpipe => -- s_rxpipe: read, pipe wait |
isloe := '1'; |
n.state := s_rxprep2; |
|
when s_txprep0 => -- s_txprep0: switch to tx-fifo |
ififo_ce := '1'; |
ififo := c_txfifo; |
n.state := s_txprep1; |
|
when s_txprep1 => -- s_txprep1: fifo addr setup |
cc_clr := '1'; |
n.state := s_txprep2; |
|
when s_txprep2 => -- s_txprep2: wait for flags |
n.state := s_txdisp; |
|
when s_txdisp => -- s_txdisp: write, dispatch |
-- if chunk done and tx2 or pe2 pending and possible |
if cc_done='1' and sltx2ok='1' and (TX2FIFO_VAL='1' or r.pe2pend='1') |
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 |
n.state := s_rxprep0; |
-- if pktend to do and possible |
elsif sltxok = '1' and r.pepend = '1' then |
ipktend := '1'; |
n.pepend := '0'; |
n.state := s_idle; |
-- if more tx to do and possible |
elsif sltxok = '1' and TXFIFO_VAL = '1' then |
cc_cnt := '1'; -- inc chunk count |
n.pepend := '0'; -- cancel pe (avoid back-2-back tx+pe) |
itxfifo_hold := '0'; |
idata_do := TXFIFO_DO; |
idata_ceo := '1'; |
idata_oe := '1'; |
islwr := '1'; |
if pipeok = '1' then -- if not almost full |
n.state := s_txdisp; -- stream |
else |
n.state := s_txprep1; -- wait for full flag |
end if; |
-- otherwise back to idle |
else |
n.state := s_idle; |
end if; |
|
when s_tx2prep0 => -- s_tx2prep0: switch to tx2-fifo |
ififo_ce := '1'; |
ififo := c_tx2fifo; |
n.state := s_tx2prep1; |
|
when s_tx2prep1 => -- s_tx2prep1: fifo addr setup |
cc_clr := '1'; |
n.state := s_tx2prep2; |
|
when s_tx2prep2 => -- s_tx2prep2: wait for flags |
n.state := s_tx2disp; |
|
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 |
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') |
then |
n.state := s_txprep0; |
-- if pktend 2 to do and possible |
elsif sltx2ok = '1' and r.pe2pend = '1' then |
ipktend := '1'; |
n.pe2pend := '0'; |
n.state := s_idle; |
-- if more tx2 to do and possible |
elsif sltx2ok = '1' and TX2FIFO_VAL = '1' then |
cc_cnt := '1'; -- inc chunk count |
n.pe2pend := '0'; -- cancel pe (avoid back-2-back tx+pe) |
itx2fifo_hold := '0'; |
idata_do := TX2FIFO_DO; |
idata_ceo := '1'; |
idata_oe := '1'; |
islwr := '1'; |
if pipeok = '1' then -- if not almost full |
n.state := s_tx2disp; -- stream |
else |
n.state := s_tx2prep1; -- wait for full flag |
end if; |
-- otherwise back to idle |
else |
n.state := s_idle; |
end if; |
|
when others => null; |
end case; |
|
-- rx pipe handling |
idata_cei := r.rxpipe1; |
n.rxpipe2 := r.rxpipe1; |
irxfifo_ena := r.rxpipe2; |
|
-- chunk counter handling |
if cc_clr = '1' then |
n.ccnt := (others=>'1'); |
elsif cc_cnt='1' and unsigned(r.ccnt) > 0 then |
n.ccnt := slv(unsigned(r.ccnt) - 1); |
end if; |
|
-- pktend time-out handling: |
-- if tx fifo is non-empty, set counter to max |
-- if tx fifo is empty, count down every usec |
-- on 1->0 transition queue pktend request |
if TXFIFO_VAL = '1' then |
n.petocnt := (others=>'1'); |
else |
if unsigned(r.petocnt) /= 0 then |
n.petocnt := slv(unsigned(r.petocnt) - 1); |
if unsigned(r.petocnt) = 1 then |
n.pepend := '1'; |
end if; |
end if; |
end if; |
if TX2FIFO_VAL = '1' then |
n.pe2tocnt := (others=>'1'); |
else |
if unsigned(r.pe2tocnt) /= 0 then |
n.pe2tocnt := slv(unsigned(r.pe2tocnt) - 1); |
if unsigned(r.pe2tocnt) = 1 then |
n.pe2pend := '1'; |
end if; |
end if; |
end if; |
|
n.moni_ep4_sel := '0'; |
n.moni_ep6_sel := '0'; |
n.moni_ep8_sel := '0'; |
if r.state = s_rxdisp or r.state = s_rxpipe then |
n.moni_ep4_sel := '1'; |
n.moni_ep4_pf := not FX2_FLAG_N(c_flag_prog); |
elsif r.state = s_txdisp then |
n.moni_ep6_sel := '1'; |
n.moni_ep6_pf := not FX2_FLAG_N(c_flag_prog); |
elsif r.state = s_tx2disp then |
n.moni_ep8_sel := '1'; |
n.moni_ep8_pf := not FX2_FLAG_N(c_flag_prog); |
end if; |
|
N_REGS <= n; |
|
FX2_FIFO_CE <= ififo_ce; |
FX2_FIFO <= ififo; |
|
FX2_SLRD_N <= not islrd; |
FX2_SLWR_N <= not islwr; |
FX2_SLOE_N <= not isloe; |
FX2_PKTEND_N <= not ipktend; |
|
FX2_DATA_CEI <= idata_cei; |
FX2_DATA_CEO <= idata_ceo; |
FX2_DATA_OE <= idata_oe; |
FX2_DATA_DO <= idata_do; |
|
RXFIFO_ENA <= irxfifo_ena; |
TXFIFO_HOLD <= itxfifo_hold; |
TX2FIFO_HOLD <= itx2fifo_hold; |
|
end process proc_next; |
|
proc_moni: process (CLK) |
begin |
|
if rising_edge(CLK) then |
if RESET = '1' then |
R_MONI_C <= fx2ctl_moni_init; |
R_MONI_S <= fx2ctl_moni_init; |
else |
R_MONI_C <= fx2ctl_moni_init; |
R_MONI_C.fifo_ep4 <= R_REGS.moni_ep4_sel; |
R_MONI_C.fifo_ep6 <= R_REGS.moni_ep6_sel; |
R_MONI_C.fifo_ep8 <= R_REGS.moni_ep8_sel; |
R_MONI_C.flag_ep4_empty <= not FX2_FLAG_N(c_flag_rx_ef); |
R_MONI_C.flag_ep4_almost <= R_REGS.moni_ep4_pf; |
R_MONI_C.flag_ep6_full <= not FX2_FLAG_N(c_flag_tx_ff); |
R_MONI_C.flag_ep6_almost <= R_REGS.moni_ep6_pf; |
R_MONI_C.flag_ep8_full <= not FX2_FLAG_N(c_flag_tx2_ff); |
R_MONI_C.flag_ep8_almost <= R_REGS.moni_ep8_pf; |
R_MONI_C.slrd <= not FX2_SLRD_N; |
R_MONI_C.slwr <= not FX2_SLWR_N; |
R_MONI_C.pktend <= not FX2_PKTEND_N; |
R_MONI_S <= R_MONI_C; |
end if; |
end if; |
|
end process proc_moni; |
|
proc_almost: process (RXSIZE_USR, TXSIZE_USR, TX2SIZE_USR) |
begin |
|
-- rxsize_usr is the number of bytes to read |
-- txsize_usr is the number of bytes to write |
|
if unsigned(RXSIZE_USR) <= RXAEMPTY_THRES then |
RXAEMPTY <= '1'; |
else |
RXAEMPTY <= '0'; |
end if; |
|
if unsigned(TXSIZE_USR) <= TXAFULL_THRES then |
TXAFULL <= '1'; |
else |
TXAFULL <= '0'; |
end if; |
|
if unsigned(TX2SIZE_USR) <= TX2AFULL_THRES then |
TX2AFULL <= '1'; |
else |
TX2AFULL <= '0'; |
end if; |
|
end process proc_almost; |
|
TXBUSY <= TXBUSY_L; |
TX2BUSY <= TX2BUSY_L; |
|
MONI <= R_MONI_S; |
|
end syn; |
/tb/fx2_2fifo_core.vhd
0,0 → 1,277
-- $Id: fx2_2fifo_core.vhd 469 2013-01-05 12:29:44Z mueller $ |
-- |
-- Copyright 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 |
-- 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. |
-- |
-- This program is distributed in the hope that it will be useful, but |
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY |
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
-- for complete details. |
-- |
------------------------------------------------------------------------------ |
-- Module Name: fx2_2fifo_core - sim |
-- Description: Cypress EZ-USB FX2 (2 fifo core model) |
-- |
-- Dependencies: memlib/fifo_2c_dram |
-- Test bench: - |
-- Target Devices: generic |
-- Tool versions: xst 13.3; ghdl 0.29 |
-- Revision History: |
-- Date Rev Version Comment |
-- 2013-01-04 469 1.0 Initial version |
------------------------------------------------------------------------------ |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use ieee.std_logic_textio.all; |
use std.textio.all; |
|
use work.slvtypes.all; |
use work.simbus.all; |
use work.fx2lib.all; |
use work.memlib.all; |
|
entity fx2_2fifo_core is -- EZ-USB FX2 (2 fifo core model) |
port ( |
CLK : in slbit; -- uplink clock |
RESET : in slbit; -- reset |
RXDATA : in slv8; -- rx data (ext->fx2) |
RXENA : in slbit; -- rx enable |
RXBUSY : out slbit; -- rx busy |
TXDATA : out slv8; -- tx data (fx2->ext) |
TXVAL : out slbit; -- tx valid |
IFCLK : out slbit; -- fx2 interface clock |
FIFO : in slv2; -- fx2 fifo address |
FLAG : out slv4; -- fx2 fifo flags |
SLRD_N : in slbit; -- fx2 read enable (act.low) |
SLWR_N : in slbit; -- fx2 write enable (act.low) |
SLOE_N : in slbit; -- fx2 output enable (act.low) |
PKTEND_N : in slbit; -- fx2 packet end (act.low) |
DATA : inout slv8 -- fx2 data lines |
); |
end fx2_2fifo_core; |
|
|
architecture sim of fx2_2fifo_core is |
|
constant c_rxfifo : slv2 := c_fifo_ep4; |
constant c_txfifo : slv2 := c_fifo_ep6; |
|
constant c_flag_prog : integer := 0; |
constant c_flag_tx_ff : integer := 1; |
constant c_flag_rx_ef : integer := 2; |
constant c_flag_tx2_ff : integer := 3; |
|
constant bufsize : positive := 1024; |
constant datzero : slv(DATA'range) := (others=>'0'); |
type buf_type is array (0 to bufsize-1) of slv(DATA'range); |
|
signal CLK30 : slbit := '0'; |
|
signal RXFIFO_DO : slv8 := (others=>'0'); |
signal RXFIFO_VAL : slbit := '0'; |
signal RXFIFO_HOLD : slbit := '0'; |
signal TXFIFO_DI : slv8 := (others=>'0'); |
signal TXFIFO_ENA : slbit := '0'; |
signal TXFIFO_BUSY : slbit := '0'; |
|
signal R_FLAG : slv4 := (others=>'0'); |
signal R_DATA : slv8 := (others=>'0'); |
|
-- added for debug purposes |
signal R_rxbuf_rind : natural := 0; |
signal R_rxbuf_wind : natural := 0; |
signal R_rxbuf_nbyt : natural := 0; |
signal R_txbuf_rind : natural := 0; |
signal R_txbuf_wind : natural := 0; |
signal R_txbuf_nbyt : natural := 0; |
|
begin |
|
RXFIFO : fifo_2c_dram |
generic map ( |
AWIDTH => 5, |
DWIDTH => 8) |
port map ( |
CLKW => CLK, |
CLKR => CLK30, |
RESETW => '0', |
RESETR => '0', |
DI => RXDATA, |
ENA => RXENA, |
BUSY => RXBUSY, |
DO => RXFIFO_DO, |
VAL => RXFIFO_VAL, |
HOLD => RXFIFO_HOLD, |
SIZEW => open, |
SIZER => open |
); |
|
TXFIFO : fifo_2c_dram |
generic map ( |
AWIDTH => 5, |
DWIDTH => 8) |
port map ( |
CLKW => CLK30, |
CLKR => CLK, |
RESETW => '0', |
RESETR => '0', |
DI => TXFIFO_DI, |
ENA => TXFIFO_ENA, |
BUSY => TXFIFO_BUSY, |
DO => TXDATA, |
VAL => TXVAL, |
HOLD => '0', |
SIZEW => open, |
SIZER => open |
); |
|
proc_ifclk: process |
constant offset : time := 200 ns; |
constant halfperiod_7 : time := 16700 ps; |
constant halfperiod_6 : time := 16600 ps; |
begin |
|
CLK30 <= '0'; |
wait for offset; |
|
clk_loop: loop |
CLK30 <= '1'; |
wait for halfperiod_7; |
CLK30 <= '0'; |
wait for halfperiod_7; |
CLK30 <= '1'; |
wait for halfperiod_6; |
CLK30 <= '0'; |
wait for halfperiod_7; |
CLK30 <= '1'; |
wait for halfperiod_7; |
CLK30 <= '0'; |
wait for halfperiod_6; |
exit clk_loop when to_x01(SB_CLKSTOP) = '1'; |
end loop; |
|
wait; -- endless wait, simulator will stop |
|
end process proc_ifclk; |
|
proc_state: process (CLK30) |
variable rxbuf : buf_type := (others=>datzero); |
variable rxbuf_rind : natural := 0; |
variable rxbuf_wind : natural := 0; |
variable rxbuf_nbyt : natural := 0; |
|
variable txbuf : buf_type := (others=>datzero); |
variable txbuf_rind : natural := 0; |
variable txbuf_wind : natural := 0; |
variable txbuf_nbyt : natural := 0; |
|
variable oline : line; |
|
begin |
|
if rising_edge(CLK30) then |
|
RXFIFO_HOLD <= '0'; |
TXFIFO_ENA <= '0'; |
|
-- rxfifo -> rxbuf |
if RXFIFO_VAL = '1' then |
if rxbuf_nbyt < bufsize then |
rxbuf(rxbuf_wind) := RXFIFO_DO; |
rxbuf_wind := (rxbuf_wind + 1) mod bufsize; |
rxbuf_nbyt := rxbuf_nbyt + 1; |
else |
RXFIFO_HOLD <= '1'; |
end if; |
end if; |
|
-- txbuf -> txfifo |
if txbuf_nbyt>0 and TXFIFO_BUSY='0' then |
TXFIFO_DI <= txbuf(txbuf_rind); |
TXFIFO_ENA <= '1'; |
txbuf_rind := (txbuf_rind + 1) mod bufsize; |
txbuf_nbyt := txbuf_nbyt - 1; |
end if; |
|
-- slrd cycle: rxbuf -> data |
if SLRD_N = '0' then |
if rxbuf_nbyt > 0 then |
rxbuf_rind := (rxbuf_rind + 1) mod bufsize; |
rxbuf_nbyt := rxbuf_nbyt - 1; |
else |
write(oline, string'("fx2_2fifo_core: SLRD_N=0 when rxbuf empty")); |
writeline(output, oline); |
end if; |
end if; |
R_DATA <= rxbuf(rxbuf_rind); |
|
-- slwr cycle: data -> txbuf |
if SLWR_N = '0' then |
if txbuf_nbyt < bufsize then |
txbuf(txbuf_wind) := DATA; |
txbuf_wind := (txbuf_wind + 1) mod bufsize; |
txbuf_nbyt := txbuf_nbyt + 1; |
else |
write(oline, string'("fx2_2fifo_core: SLWR_N=0 when txbuf full")); |
writeline(output, oline); |
end if; |
end if; |
|
-- prepare flags (note that FLAGs are act.low!) |
R_FLAG <= (others=>'1'); |
-- FLAGA = indexed, PF |
-- rx endpoint -> PF 'almost empty' at 3 bytes to go |
if FIFO = c_rxfifo then |
if rxbuf_nbyt < 4 then |
R_FLAG(0) <= '0'; |
end if; |
-- tx endpoint -> PF 'almost full' at 3 bytes to go |
elsif FIFO = c_txfifo then |
if txbuf_nbyt > bufsize-4 then |
R_FLAG(0) <= '0'; |
end if; |
end if; |
|
-- FLAGB = EP6 FF |
if txbuf_nbyt = bufsize then |
R_FLAG(1) <= '0'; |
end if; |
|
-- FLAGC = EP4 EF |
if rxbuf_nbyt = 0 then |
R_FLAG(2) <= '0'; |
end if; |
|
-- FLAGD = EP8 FF |
R_FLAG(3) <= '1'; |
|
-- added for debug purposes |
R_rxbuf_rind <= rxbuf_rind; |
R_rxbuf_wind <= rxbuf_wind; |
R_rxbuf_nbyt <= rxbuf_nbyt; |
R_txbuf_rind <= txbuf_rind; |
R_txbuf_wind <= txbuf_wind; |
R_txbuf_nbyt <= txbuf_nbyt; |
|
end if; |
|
end process proc_state; |
|
IFCLK <= CLK30; |
FLAG <= R_FLAG; |
|
proc_data: process (SLOE_N, R_DATA) |
begin |
if SLOE_N = '1' then |
DATA <= (others=>'Z'); |
else |
DATA <= R_DATA; |
end if; |
end process proc_data; |
|
end sim; |
/tb/fx2_2fifo_core.vbom
0,0 → 1,9
# libs |
../../../vlib/slvtypes.vhd |
../../../vlib/simlib/simlib.vhd |
../fx2lib.vhd |
../../../vlib/memlib/memlib.vhd |
# components |
../../../vlib/memlib/fifo_2c_dram.vbom |
# design |
fx2_2fifo_core.vhd |
tb
Property changes :
Added: svn:ignore
## -0,0 +1,32 ##
+*.dep_ghdl
+*.dep_isim
+*.dep_xst
+work-obj93.cf
+*.vcd
+*.ghw
+*.sav
+*.tmp
+*.exe
+ise
+xflow.his
+*.ngc
+*.ncd
+*.pcf
+*.bit
+*.msk
+isim
+isim.log
+isim.wdb
+fuse.log
+*_[sft]sim.vhd
+*_tsim.sdf
+*_xst.log
+*_tra.log
+*_twr.log
+*_map.log
+*_par.log
+*_pad.log
+*_bgn.log
+*_svn.log
+*_sum.log
+*_[dsft]sim.log
Index: fx2_2fifoctl_ic.vbom
===================================================================
--- fx2_2fifoctl_ic.vbom (nonexistent)
+++ fx2_2fifoctl_ic.vbom (revision 24)
@@ -0,0 +1,13 @@
+# libs
+../../vlib/slvtypes.vhd
+../../vlib/xlib/xlib.vhd
+../../vlib/memlib/memlib.vhd
+fx2lib.vhd
+# components
+../../vlib/xlib/iob_reg_o.vbom
+../../vlib/xlib/iob_reg_i_gen.vbom
+../../vlib/xlib/iob_reg_o_gen.vbom
+../../vlib/xlib/iob_reg_io_gen.vbom
+../../vlib/memlib/fifo_2c_dram.vbom
+# design
+fx2_2fifoctl_ic.vhd
Index: fx2_3fifoctl_ic.vbom
===================================================================
--- fx2_3fifoctl_ic.vbom (nonexistent)
+++ fx2_3fifoctl_ic.vbom (revision 24)
@@ -0,0 +1,13 @@
+# libs
+../../vlib/slvtypes.vhd
+../../vlib/xlib/xlib.vhd
+../../vlib/memlib/memlib.vhd
+fx2lib.vhd
+# components
+../../vlib/xlib/iob_reg_o.vbom
+../../vlib/xlib/iob_reg_i_gen.vbom
+../../vlib/xlib/iob_reg_o_gen.vbom
+../../vlib/xlib/iob_reg_io_gen.vbom
+../../vlib/memlib/fifo_2c_dram.vbom
+# design
+fx2_3fifoctl_ic.vhd
Index: fx2lib.vhd
===================================================================
--- fx2lib.vhd (nonexistent)
+++ fx2lib.vhd (revision 24)
@@ -0,0 +1,172 @@
+-- $Id: fx2lib.vhd 453 2012-01-15 17:51:18Z mueller $
+--
+-- Copyright 2011-2012 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
+-- Software Foundation, either version 2, or at your option any later version.
+--
+-- This program is distributed in the hope that it will be useful, but
+-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
+-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-- for complete details.
+--
+------------------------------------------------------------------------------
+-- Package Name: fx2lib
+-- Description: Cypress ez-usb fx2 support
+--
+-- Dependencies: -
+-- Tool versions: xst 12.1, 13.1, 13.3; ghdl 0.26-0.29
+--
+-- Revision History:
+-- Date Rev Version Comment
+-- 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
+-- 2012-01-01 448 1.2 add fx2_2fifoctl_ic
+-- 2011-12-25 445 1.1 change pktend iface in fx2_2fifoctl_as
+-- 2011-07-17 394 1.0.1 add c_fifo_epx and fx2ctl_moni_type
+-- 2011-07-07 389 1.0 Initial version
+------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+use work.slvtypes.all;
+
+package fx2lib is
+
+ constant c_fifo_ep2 : slv2 := "00"; -- fifo address: end point 2
+ constant c_fifo_ep4 : slv2 := "01"; -- fifo address: end point 4
+ constant c_fifo_ep6 : slv2 := "10"; -- fifo address: end point 6
+ constant c_fifo_ep8 : slv2 := "11"; -- fifo address: end point 8
+
+ type fx2ctl_moni_type is record -- fx2ctl monitor port
+ fifo_ep4 : slbit; -- fifo 1 (ep4) active;
+ fifo_ep6 : slbit; -- fifo 2 (ep6) active;
+ fifo_ep8 : slbit; -- fifo 3 (ep8) active;
+ flag_ep4_empty : slbit; -- ep4 empty flag (latched);
+ flag_ep4_almost : slbit; -- ep4 almost empty flag (latched);
+ flag_ep6_full : slbit; -- ep6 full flag (latched);
+ flag_ep6_almost : slbit; -- ep6 almost full flag (latched);
+ flag_ep8_full : slbit; -- ep8 full flag (latched);
+ flag_ep8_almost : slbit; -- ep8 almost full flag (latched);
+ slrd : slbit; -- read strobe
+ slwr : slbit; -- write strobe
+ pktend : slbit; -- pktend strobe
+ end record fx2ctl_moni_type;
+
+ constant fx2ctl_moni_init : fx2ctl_moni_type := (
+ '0','0','0', -- fifo_ep[468]
+ '0','0', -- flag_ep4_(empty|almost)
+ '0','0', -- flag_ep6_(full|almost)
+ '0','0', -- flag_ep8_(full|almost)
+ '0','0','0' -- slrd, slwr, pktend
+ );
+
+
+-- -------------------------------------
+component fx2_2fifoctl_as is -- EZ-USB FX2 driver (2 fifo; async)
+ generic (
+ RXFAWIDTH : positive := 5; -- receive fifo address width
+ TXFAWIDTH : positive := 5; -- transmit fifo address width
+ PETOWIDTH : positive := 7; -- packet end time-out counter width
+ CCWIDTH : positive := 5; -- chunk counter width
+ RXAEMPTY_THRES : natural := 1; -- threshold for rx aempty flag
+ TXAFULL_THRES : natural := 1; -- threshold for tx afull flag
+ RDPWLDELAY : positive := 5; -- slrd low delay in clock cycles
+ RDPWHDELAY : positive := 5; -- slrd high delay in clock cycles
+ WRPWLDELAY : positive := 5; -- slwr low delay in clock cycles
+ WRPWHDELAY : positive := 7; -- slwr high delay in clock cycles
+ FLAGDELAY : positive := 2); -- flag delay in clock cycles
+ port (
+ CLK : in slbit; -- clock
+ CE_USEC : in slbit; -- 1 usec clock enable
+ RESET : in slbit := '0'; -- reset
+ RXDATA : out slv8; -- receive data out
+ RXVAL : out slbit; -- receive data valid
+ RXHOLD : in slbit; -- receive data hold
+ RXAEMPTY : out slbit; -- receive almost empty flag
+ TXDATA : in slv8; -- transmit data in
+ TXENA : in slbit; -- transmit data enable
+ TXBUSY : out slbit; -- transmit data busy
+ TXAFULL : out slbit; -- transmit almost full flag
+ MONI : out fx2ctl_moni_type; -- monitor port data
+ I_FX2_IFCLK : in slbit; -- fx2: interface clock
+ O_FX2_FIFO : out slv2; -- fx2: fifo address
+ I_FX2_FLAG : in slv4; -- fx2: fifo flags
+ O_FX2_SLRD_N : out slbit; -- fx2: read enable (act.low)
+ O_FX2_SLWR_N : out slbit; -- fx2: write enable (act.low)
+ O_FX2_SLOE_N : out slbit; -- fx2: output enable (act.low)
+ O_FX2_PKTEND_N : out slbit; -- fx2: packet end (act.low)
+ IO_FX2_DATA : inout slv8 -- fx2: data lines
+ );
+end component;
+
+component fx2_2fifoctl_ic is -- EZ-USB FX2 driver (2 fifo; int clk)
+ generic (
+ RXFAWIDTH : positive := 5; -- receive fifo address width
+ TXFAWIDTH : positive := 5; -- transmit fifo address width
+ PETOWIDTH : positive := 7; -- packet end time-out counter width
+ CCWIDTH : positive := 5; -- chunk counter width
+ RXAEMPTY_THRES : natural := 1; -- threshold for rx aempty flag
+ TXAFULL_THRES : natural := 1); -- threshold for tx afull flag
+ port (
+ CLK : in slbit; -- clock
+ RESET : in slbit := '0'; -- reset
+ RXDATA : out slv8; -- receive data out
+ RXVAL : out slbit; -- receive data valid
+ RXHOLD : in slbit; -- receive data hold
+ RXAEMPTY : out slbit; -- receive almost empty flag
+ TXDATA : in slv8; -- transmit data in
+ TXENA : in slbit; -- transmit data enable
+ TXBUSY : out slbit; -- transmit data busy
+ TXAFULL : out slbit; -- transmit almost full flag
+ MONI : out fx2ctl_moni_type; -- monitor port data
+ I_FX2_IFCLK : in slbit; -- fx2: interface clock
+ O_FX2_FIFO : out slv2; -- fx2: fifo address
+ I_FX2_FLAG : in slv4; -- fx2: fifo flags
+ O_FX2_SLRD_N : out slbit; -- fx2: read enable (act.low)
+ O_FX2_SLWR_N : out slbit; -- fx2: write enable (act.low)
+ O_FX2_SLOE_N : out slbit; -- fx2: output enable (act.low)
+ O_FX2_PKTEND_N : out slbit; -- fx2: packet end (act.low)
+ IO_FX2_DATA : inout slv8 -- fx2: data lines
+ );
+end component;
+
+component fx2_3fifoctl_ic is -- EZ-USB FX2 driver (3 fifo; int clk)
+ generic (
+ RXFAWIDTH : positive := 5; -- receive fifo address width
+ TXFAWIDTH : positive := 5; -- transmit fifo address width
+ PETOWIDTH : positive := 7; -- packet end time-out counter width
+ CCWIDTH : positive := 5; -- chunk counter width
+ RXAEMPTY_THRES : natural := 1; -- threshold for rx aempty flag
+ TXAFULL_THRES : natural := 1; -- threshold for tx afull flag
+ TX2AFULL_THRES : natural := 1); -- threshold for tx2 afull flag
+ port (
+ CLK : in slbit; -- clock
+ RESET : in slbit := '0'; -- reset
+ RXDATA : out slv8; -- receive data out
+ RXVAL : out slbit; -- receive data valid
+ RXHOLD : in slbit; -- receive data hold
+ RXAEMPTY : out slbit; -- receive almost empty flag
+ TXDATA : in slv8; -- transmit 1 data in
+ TXENA : in slbit; -- transmit 1 data enable
+ TXBUSY : out slbit; -- transmit 1 data busy
+ TXAFULL : out slbit; -- transmit 1 almost full flag
+ TX2DATA : in slv8; -- transmit 2 data in
+ TX2ENA : in slbit; -- transmit 2 data enable
+ TX2BUSY : out slbit; -- transmit 2 data busy
+ TX2AFULL : out slbit; -- transmit 2 almost full flag
+ MONI : out fx2ctl_moni_type; -- monitor port data
+ I_FX2_IFCLK : in slbit; -- fx2: interface clock
+ O_FX2_FIFO : out slv2; -- fx2: fifo address
+ I_FX2_FLAG : in slv4; -- fx2: fifo flags
+ O_FX2_SLRD_N : out slbit; -- fx2: read enable (act.low)
+ O_FX2_SLWR_N : out slbit; -- fx2: write enable (act.low)
+ O_FX2_SLOE_N : out slbit; -- fx2: output enable (act.low)
+ O_FX2_PKTEND_N : out slbit; -- fx2: packet end (act.low)
+ IO_FX2_DATA : inout slv8 -- fx2: data lines
+ );
+end component;
+
+end package fx2lib;
Index: fx2_2fifoctl_as.vhd
===================================================================
--- fx2_2fifoctl_as.vhd (nonexistent)
+++ fx2_2fifoctl_as.vhd (revision 24)
@@ -0,0 +1,647 @@
+-- $Id: fx2_2fifoctl_as.vhd 453 2012-01-15 17:51:18Z mueller $
+--
+-- Copyright 2011-2012 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
+-- Software Foundation, either version 2, or at your option any later version.
+--
+-- This program is distributed in the hope that it will be useful, but
+-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
+-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-- for complete details.
+--
+------------------------------------------------------------------------------
+-- Module Name: fx2_2fifoctl_as - syn
+-- Description: Cypress EZ-USB FX2 driver (2 fifo; async)
+--
+-- Dependencies: vlib/xlib/iob_reg_o
+-- vlib/xlib/iob_reg_i_gen
+-- vlib/xlib/iob_reg_o_gen
+-- vlib/xlib/iob_reg_io_gen
+-- memlib/fifo_1c_dram
+--
+-- Test bench: -
+-- Target Devices: generic
+-- Tool versions: xst 12.1, 13.1, 13.3; ghdl 0.26-0.29
+--
+-- Synthesized (xst):
+-- Date Rev ise Target flop lutl lutm slic t peri
+-- 2012-01-14 453 13.3 O76x xc3s1200e-4 65 153 64 133 s 7.2
+-- 2012-01-03 449 13.3 O76x xc3s1200e-4 67 149 64 133 s 7.2
+-- 2011-12-25 445 13.3 O76x xc3s1200e-4 61 147 64 127 s 7.2
+-- 2011-12-25 444 13.3 O76x xc3s1200e-4 54 140 64 123 s 7.2
+-- 2011-07-07 389 12.1 M53d xc3s1200e-4 45 132 64 109 s 7.9
+--
+-- Revision History:
+-- Date Rev Version Comment
+-- 2012-01-14 453 1.3 common DELAY for PE and WR; use aempty/afull logic
+-- 2012-01-04 450 1.2.2 use new FLAG layout (EF,FF now fixed)
+-- 2012-01-03 449 1.2.1 use new fx2ctl_moni layout; hardcode ep's
+-- 2011-12-25 445 1.2 change pktend handling, now timer based
+-- 2011-11-25 433 1.1.1 now numeric_std clean
+-- 2011-07-30 400 1.1 capture rx data in 2nd last s_rdpwh cycle
+-- 2011-07-24 389 1.0.2 use FX2_FLAG_N to signal that flags are act.low
+-- 2011-07-17 394 1.0.1 (RX|TX)FIFOEP now generics; add MONI port
+-- 2011-07-08 390 1.0 Initial version
+--
+------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.slvtypes.all;
+use work.xlib.all;
+use work.memlib.all;
+use work.fx2lib.all;
+
+entity fx2_2fifoctl_as is -- EZ-USB FX2 driver (2 fifo; async)
+ generic (
+ RXFAWIDTH : positive := 5; -- receive fifo address width
+ TXFAWIDTH : positive := 5; -- transmit fifo address width
+ PETOWIDTH : positive := 7; -- packet end time-out counter width
+ CCWIDTH : positive := 5; -- chunk counter width
+ RXAEMPTY_THRES : natural := 1; -- threshold for rx aempty flag
+ TXAFULL_THRES : natural := 1; -- threshold for tx afull flag
+ RDPWLDELAY : positive := 5; -- slrd low delay in clock cycles
+ RDPWHDELAY : positive := 5; -- slrd high delay in clock cycles
+ WRPWLDELAY : positive := 5; -- slwr low delay in clock cycles
+ WRPWHDELAY : positive := 7; -- slwr high delay in clock cycles
+ FLAGDELAY : positive := 2); -- flag delay in clock cycles
+ port (
+ CLK : in slbit; -- clock
+ CE_USEC : in slbit; -- 1 usec clock enable
+ RESET : in slbit := '0'; -- reset
+ RXDATA : out slv8; -- receive data out
+ RXVAL : out slbit; -- receive data valid
+ RXHOLD : in slbit; -- receive data hold
+ RXAEMPTY : out slbit; -- receive almost empty flag
+ TXDATA : in slv8; -- transmit data in
+ TXENA : in slbit; -- transmit data enable
+ TXBUSY : out slbit; -- transmit data busy
+ TXAFULL : out slbit; -- transmit almost full flag
+ MONI : out fx2ctl_moni_type; -- monitor port data
+ I_FX2_IFCLK : in slbit; -- fx2: interface clock
+ O_FX2_FIFO : out slv2; -- fx2: fifo address
+ I_FX2_FLAG : in slv4; -- fx2: fifo flags
+ O_FX2_SLRD_N : out slbit; -- fx2: read enable (act.low)
+ O_FX2_SLWR_N : out slbit; -- fx2: write enable (act.low)
+ O_FX2_SLOE_N : out slbit; -- fx2: output enable (act.low)
+ O_FX2_PKTEND_N : out slbit; -- fx2: packet end (act.low)
+ IO_FX2_DATA : inout slv8 -- fx2: data lines
+ );
+end fx2_2fifoctl_as;
+
+
+architecture syn of fx2_2fifoctl_as is
+
+ constant c_rxfifo : slv2 := c_fifo_ep4;
+ constant c_txfifo : slv2 := c_fifo_ep6;
+
+ constant c_flag_prog : integer := 0;
+ constant c_flag_tx_ff : integer := 1;
+ constant c_flag_rx_ef : integer := 2;
+ constant c_flag_tx2_ff : integer := 3;
+
+ type state_type is (
+ s_init, -- s_init: init state
+ s_rdprep, -- s_rdprep: prepare read
+ s_rdwait, -- s_rdwait: wait for data
+ s_rdpwl, -- s_rdpwl: read, strobe low
+ s_rdpwh, -- s_rdpwh: read, strobe high
+ s_wrprep, -- s_wrprep: prepare write
+ s_wrpwl, -- s_wrpwl: write, strobe low
+ s_wrpwh, -- s_wrpwh: write, strobe high
+ s_peprep, -- s_peprep: prepare pktend
+ s_pepwl, -- s_pepwl: pktend, strobe low
+ s_pepwh -- s_pepwh: pktend, strobe high
+ );
+
+ type regs_type is record
+ state : state_type; -- state
+ petocnt : slv(PETOWIDTH-1 downto 0); -- pktend time out counter
+ pepend : slbit; -- pktend pending
+ dlycnt : slv4; -- wait delay counter
+ moni_ep4_sel : slbit; -- ep4 (rx) select
+ moni_ep6_sel : slbit; -- ep6 (tx) select
+ moni_ep4_pf : slbit; -- ep4 (rx) prog flag
+ moni_ep6_pf : slbit; -- ep6 (rx) prog flag
+ end record regs_type;
+
+ constant petocnt_init : slv(PETOWIDTH-1 downto 0) := (others=>'0');
+
+ constant regs_init : regs_type := (
+ s_init, -- state
+ petocnt_init, -- petocnt
+ '0', -- pepend
+ (others=>'0'), -- cntdly
+ '0','0', -- moni_ep(4|6)_sel
+ '0','0' -- moni_ep(4|6)_pf
+ );
+
+ signal R_REGS : regs_type := regs_init; -- state registers
+ signal N_REGS : regs_type := regs_init; -- next value state regs
+
+ signal FX2_FIFO : slv2 := (others=>'0');
+ signal FX2_FIFO_CE : slbit := '0';
+ signal FX2_FLAG_N : slv4 := (others=>'0');
+ signal FX2_SLRD_N : slbit := '1';
+ signal FX2_SLWR_N : slbit := '1';
+ signal FX2_SLOE_N : slbit := '1';
+ signal FX2_PKTEND_N : slbit := '1';
+ signal FX2_DATA_CEI : slbit := '0';
+ signal FX2_DATA_CEO : slbit := '0';
+ signal FX2_DATA_OE : slbit := '0';
+
+ signal RXFIFO_DI : slv8 := (others=>'0');
+ signal RXFIFO_ENA : slbit := '0';
+ signal RXFIFO_BUSY : slbit := '0';
+ signal RXSIZE : slv(RXFAWIDTH downto 0) := (others=>'0');
+ signal TXFIFO_DO : slv8 := (others=>'0');
+ signal TXFIFO_VAL : slbit := '0';
+ signal TXFIFO_HOLD : slbit := '0';
+ signal TXSIZE : slv(TXFAWIDTH downto 0) := (others=>'0');
+
+ signal TXBUSY_L : slbit := '0';
+
+begin
+
+ assert RDPWLDELAY<=2**R_REGS.dlycnt'length and
+ RDPWHDELAY<=2**R_REGS.dlycnt'length and RDPWHDELAY>=2 and
+ WRPWLDELAY<=2**R_REGS.dlycnt'length and
+ WRPWHDELAY<=2**R_REGS.dlycnt'length and
+ FLAGDELAY<=2**R_REGS.dlycnt'length
+ report "assert(*DELAY <= 2**dlycnt'length and RDPWHDELAY >=2)"
+ severity failure;
+
+ assert RXAEMPTY_THRES<=2**RXFAWIDTH and
+ TXAFULL_THRES<=2**TXFAWIDTH
+ report "assert((RXAEMPTY|TXAFULL)_THRES <= 2**(RX|TX)FAWIDTH)"
+ severity failure;
+
+ IOB_FX2_FIFO : iob_reg_o_gen
+ generic map (
+ DWIDTH => 2,
+ INIT => '0')
+ port map (
+ CLK => CLK,
+ CE => FX2_FIFO_CE,
+ DO => FX2_FIFO,
+ PAD => O_FX2_FIFO
+ );
+
+ IOB_FX2_FLAG : iob_reg_i_gen
+ generic map (
+ DWIDTH => 4,
+ INIT => '0')
+ port map (
+ CLK => CLK,
+ CE => '1',
+ DI => FX2_FLAG_N,
+ PAD => I_FX2_FLAG
+ );
+
+ IOB_FX2_SLRD : iob_reg_o
+ generic map (
+ INIT => '1')
+ port map (
+ CLK => CLK,
+ CE => '1',
+ DO => FX2_SLRD_N,
+ PAD => O_FX2_SLRD_N
+ );
+
+ IOB_FX2_SLWR : iob_reg_o
+ generic map (
+ INIT => '1')
+ port map (
+ CLK => CLK,
+ CE => '1',
+ DO => FX2_SLWR_N,
+ PAD => O_FX2_SLWR_N
+ );
+
+ IOB_FX2_SLOE : iob_reg_o
+ generic map (
+ INIT => '1')
+ port map (
+ CLK => CLK,
+ CE => '1',
+ DO => FX2_SLOE_N,
+ PAD => O_FX2_SLOE_N
+ );
+
+ IOB_FX2_PKTEND : iob_reg_o
+ generic map (
+ INIT => '1')
+ port map (
+ CLK => CLK,
+ CE => '1',
+ DO => FX2_PKTEND_N,
+ PAD => O_FX2_PKTEND_N
+ );
+
+ IOB_FX2_DATA : iob_reg_io_gen
+ generic map (
+ DWIDTH => 8,
+ PULL => "KEEP")
+ port map (
+ CLK => CLK,
+ CEI => FX2_DATA_CEI,
+ CEO => FX2_DATA_CEO,
+ OE => FX2_DATA_OE,
+ DI => RXFIFO_DI, -- input data (read from pad)
+ DO => TXFIFO_DO, -- output data (write to pad)
+ PAD => IO_FX2_DATA
+ );
+
+ RXFIFO : fifo_1c_dram -- input fifo, 1 clock, dram based
+ generic map (
+ AWIDTH => RXFAWIDTH,
+ DWIDTH => 8)
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ DI => RXFIFO_DI,
+ ENA => RXFIFO_ENA,
+ BUSY => RXFIFO_BUSY,
+ DO => RXDATA,
+ VAL => RXVAL,
+ HOLD => RXHOLD,
+ SIZE => RXSIZE
+ );
+
+ TXFIFO : fifo_1c_dram -- output fifo, 1 clock, dram based
+ generic map (
+ AWIDTH => TXFAWIDTH,
+ DWIDTH => 8)
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ DI => TXDATA,
+ ENA => TXENA,
+ BUSY => TXBUSY_L,
+ DO => TXFIFO_DO,
+ VAL => TXFIFO_VAL,
+ HOLD => TXFIFO_HOLD,
+ SIZE => TXSIZE
+ );
+
+ proc_regs: process (CLK)
+ begin
+
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ R_REGS <= regs_init;
+ else
+ R_REGS <= N_REGS;
+ end if;
+ end if;
+
+ end process proc_regs;
+
+ proc_next: process (R_REGS, CE_USEC,
+ FX2_FLAG_N, TXFIFO_VAL, RXFIFO_BUSY, TXBUSY_L)
+
+ variable r : regs_type := regs_init;
+ variable n : regs_type := regs_init;
+
+ variable idly_ld : slbit := '0';
+ variable idly_val : slv(r.dlycnt'range) := (others=>'0');
+ variable idly_end : slbit := '0';
+ variable idly_end1 : slbit := '0';
+
+ variable iflag_rdok : slbit := '0';
+ variable iflag_wrok : slbit := '0';
+
+ variable ififo_ce : slbit := '0';
+ variable ififo : slv2 := "00";
+
+ variable irxfifo_ena : slbit := '0';
+ variable itxfifo_hold : slbit := '0';
+
+ variable islrd : slbit := '0';
+ variable islwr : slbit := '0';
+ variable isloe : slbit := '0';
+ variable ipktend : slbit := '0';
+
+ variable idata_cei : slbit := '0';
+ variable idata_ceo : slbit := '0';
+ variable idata_oe : slbit := '0';
+
+ variable imoni : fx2ctl_moni_type := fx2ctl_moni_init;
+
+ procedure go_rdprep(nstate : out state_type;
+ idly_ld : out slbit;
+ idly_val : out slv4;
+ ififo_ce : out slbit;
+ ififo : out slv2) is
+ begin
+ idly_ld := '1';
+ idly_val := slv(to_unsigned(FLAGDELAY-1, idly_val'length));
+ ififo_ce := '1';
+ ififo := c_rxfifo;
+ nstate := s_rdprep;
+ end procedure go_rdprep;
+
+ procedure go_wrprep(nstate : out state_type;
+ idly_ld : out slbit;
+ idly_val : out slv4;
+ ififo_ce : out slbit;
+ ififo : out slv2) is
+ begin
+ idly_ld := '1';
+ idly_val := slv(to_unsigned(FLAGDELAY-1, idly_val'length));
+ ififo_ce := '1';
+ ififo := c_txfifo;
+ nstate := s_wrprep;
+ end procedure go_wrprep;
+
+ procedure go_peprep(nstate : out state_type;
+ idly_ld : out slbit;
+ idly_val : out slv4;
+ ififo_ce : out slbit;
+ ififo : out slv2) is
+ begin
+ idly_ld := '1';
+ idly_val := slv(to_unsigned(FLAGDELAY-1, idly_val'length));
+ ififo_ce := '1';
+ ififo := c_txfifo;
+ nstate := s_peprep;
+ end procedure go_peprep;
+
+ procedure go_rdpwl(nstate : out state_type;
+ idly_ld : out slbit;
+ idly_val : out slv4;
+ islrd : out slbit) is
+ begin
+ idly_ld := '1';
+ idly_val := slv(to_unsigned(RDPWLDELAY-1, n.dlycnt'length));
+ islrd := '1';
+ nstate := s_rdpwl;
+ end procedure go_rdpwl;
+
+ procedure go_wrpwl(nstate : out state_type;
+ idly_ld : out slbit;
+ idly_val : out slv4;
+ islwr : out slbit) is
+ begin
+ idly_ld := '1';
+ idly_val := slv(to_unsigned(WRPWLDELAY-1, n.dlycnt'length));
+ islwr := '1';
+ nstate := s_wrpwl;
+ end procedure go_wrpwl;
+
+ procedure go_pepwl(nstate : out state_type;
+ idly_ld : out slbit;
+ idly_val : out slv4;
+ ipktend : out slbit) is
+ begin
+ idly_ld := '1';
+ idly_val := slv(to_unsigned(WRPWLDELAY-1, n.dlycnt'length));
+ ipktend := '1';
+ nstate := s_pepwl;
+ end procedure go_pepwl;
+
+ begin
+
+ r := R_REGS;
+ n := R_REGS;
+
+ ififo_ce := '0';
+ ififo := "00";
+
+ irxfifo_ena := '0';
+ itxfifo_hold := '1';
+
+ islrd := '0';
+ islwr := '0';
+ isloe := '0';
+ ipktend := '0';
+
+ idata_cei := '0';
+ idata_ceo := '0';
+ idata_oe := '0';
+
+ imoni := fx2ctl_moni_init;
+
+ iflag_rdok := FX2_FLAG_N(c_flag_rx_ef); -- empty flag is act.low!
+ iflag_wrok := FX2_FLAG_N(c_flag_tx_ff); -- full flag is act.low!
+
+ idly_ld := '0';
+ idly_val := (others=>'0');
+ idly_end := '1';
+ idly_end1 := '0';
+ if unsigned(r.dlycnt) /= 0 then
+ idly_end := '0';
+ end if;
+ if unsigned(r.dlycnt) = 1 then
+ idly_end1 := '1';
+ end if;
+
+ case r.state is
+ when s_init => -- s_init:
+ go_rdprep(n.state, idly_ld, idly_val, ififo_ce, ififo);
+
+ when s_rdprep => -- s_rdprep: prepare read
+ if idly_end = '1' then
+ n.state := s_rdwait;
+ end if;
+
+ when s_rdwait => -- s_rdwait: wait for data
+ if r.pepend='1' and TXFIFO_VAL='0' then
+ go_peprep(n.state, idly_ld, idly_val, ififo_ce, ififo);
+
+ elsif iflag_rdok='1' and
+ (RXFIFO_BUSY='0' and TXBUSY_L='0') then
+ go_rdpwl(n.state, idly_ld, idly_val, islrd);
+
+ elsif TXFIFO_VAL = '1' then
+ go_wrprep(n.state, idly_ld, idly_val, ififo_ce, ififo);
+ end if;
+
+ when s_rdpwl => -- s_rdpwl: read, strobe low
+ idata_cei := '1';
+ isloe := '1';
+ if idly_end = '1' then
+ idly_ld := '1';
+ idly_val := slv(to_unsigned(RDPWHDELAY-1, n.dlycnt'length));
+ n.state := s_rdpwh;
+ else
+ islrd := '1';
+ n.state := s_rdpwl;
+ end if;
+
+ -- Note: data is sampled and written into rxfifo in 2nd last cycle in the
+ -- last cycle the rxfifo busy reflects therefore last written byte
+ -- and safely indicates whether another byte will fit.
+ when s_rdpwh => -- s_rdpwh: read, strobe high
+ idata_cei := '1';
+ isloe := '1';
+ if idly_end1 = '1' then -- 2nd last cycle
+ irxfifo_ena := '1'; -- capture rxdata
+ end if;
+ if idly_end = '1' then -- last cycle
+ if iflag_rdok='1' and
+ (RXFIFO_BUSY='0' and TXBUSY_L='0') then
+ go_rdpwl(n.state, idly_ld, idly_val, islrd);
+
+ elsif TXFIFO_VAL = '1' then
+ go_wrprep(n.state, idly_ld, idly_val, ififo_ce, ififo);
+
+ else
+ n.state := s_rdwait;
+ end if;
+ end if;
+
+ when s_wrprep => -- s_wrprep: prepare write
+ if idly_end = '1' then
+ if iflag_wrok = '1' then
+ go_wrpwl(n.state, idly_ld, idly_val, islwr);
+ else
+ go_rdprep(n.state, idly_ld, idly_val, ififo_ce, ififo);
+ end if;
+ end if;
+
+ when s_wrpwl => -- s_wrpwl: write, strobe low
+ idata_ceo := '1';
+ idata_oe := '1';
+ if idly_end = '1' then
+ idata_ceo := '0';
+ itxfifo_hold := '0';
+ idly_ld := '1';
+ idly_val := slv(to_unsigned(WRPWHDELAY-1, n.dlycnt'length));
+ n.state := s_wrpwh;
+ else
+ islwr := '1';
+ n.state := s_wrpwl;
+ end if;
+
+ when s_wrpwh => -- s_wrpwh: write, strobe high
+ idata_oe := '1';
+ if idly_end = '1' then
+ if iflag_wrok='1' and TXFIFO_VAL='1' then
+ go_wrpwl(n.state, idly_ld, idly_val, islwr);
+ elsif iflag_wrok='1' and r.pepend='1' and TXFIFO_VAL='0' then
+ go_pepwl(n.state, idly_ld, idly_val, ipktend);
+ else
+ go_rdprep(n.state, idly_ld, idly_val, ififo_ce, ififo);
+ end if;
+ end if;
+
+ when s_peprep => -- s_peprep: prepare pktend
+ if idly_end = '1' then
+ if iflag_wrok = '1' then
+ go_pepwl(n.state, idly_ld, idly_val, ipktend);
+ else
+ go_rdprep(n.state, idly_ld, idly_val, ififo_ce, ififo);
+ end if;
+ end if;
+
+ when s_pepwl => -- s_pepwl: pktend, strobe low
+ if idly_end = '1' then
+ idly_ld := '1';
+ idly_val := slv(to_unsigned(WRPWHDELAY-1, n.dlycnt'length));
+ n.state := s_pepwh;
+ else
+ ipktend := '1';
+ n.state := s_pepwl;
+ end if;
+
+ when s_pepwh => -- s_pepwh: pktend, strobe high
+ if idly_end = '1' then
+ n.pepend := '0';
+ go_rdprep(n.state, idly_ld, idly_val, ififo_ce, ififo);
+ end if;
+
+ when others => null;
+ end case;
+
+ if idly_ld = '1' then
+ n.dlycnt := idly_val;
+ elsif idly_end = '0' then
+ n.dlycnt := slv(unsigned(r.dlycnt) - 1);
+ end if;
+
+ -- pktend time-out handling:
+ -- if tx fifo is non-empty, set counter to max
+ -- if tx fifo is empty, count down every usec
+ -- on 1->0 transition queue pktend request
+ if TXFIFO_VAL = '1' then
+ n.petocnt := (others=>'1');
+ else
+ if CE_USEC = '1' and unsigned(r.petocnt) /= 0 then
+ n.petocnt := slv(unsigned(r.petocnt) - 1);
+ if unsigned(r.petocnt) = 1 then
+ n.pepend := '1';
+ end if;
+ end if;
+ end if;
+
+ n.moni_ep4_sel := '0';
+ n.moni_ep6_sel := '0';
+ if r.state = s_wrprep or r.state = s_wrpwl or r.state = s_wrpwh or
+ r.state = s_peprep or r.state = s_pepwl or r.state = s_pepwh then
+ n.moni_ep6_sel := '1';
+ n.moni_ep6_pf := not FX2_FLAG_N(c_flag_prog);
+ else
+ n.moni_ep4_sel := '1';
+ n.moni_ep4_pf := not FX2_FLAG_N(c_flag_prog);
+ end if;
+
+ imoni.fifo_ep4 := r.moni_ep4_sel;
+ imoni.fifo_ep6 := r.moni_ep6_sel;
+ imoni.flag_ep4_empty := not FX2_FLAG_N(c_flag_rx_ef);
+ imoni.flag_ep4_almost := r.moni_ep4_pf;
+ imoni.flag_ep6_full := not FX2_FLAG_N(c_flag_tx_ff);
+ imoni.flag_ep6_almost := r.moni_ep6_pf;
+ imoni.slrd := islrd;
+ imoni.slwr := islwr;
+ imoni.pktend := ipktend;
+
+ N_REGS <= n;
+
+ FX2_FIFO_CE <= ififo_ce;
+ FX2_FIFO <= ififo;
+
+ FX2_SLRD_N <= not islrd;
+ FX2_SLWR_N <= not islwr;
+ FX2_SLOE_N <= not isloe;
+ FX2_PKTEND_N <= not ipktend;
+
+ FX2_DATA_CEI <= idata_cei;
+ FX2_DATA_CEO <= idata_ceo;
+ FX2_DATA_OE <= idata_oe;
+
+ RXFIFO_ENA <= irxfifo_ena;
+ TXFIFO_HOLD <= itxfifo_hold;
+
+ MONI <= imoni;
+
+ end process proc_next;
+
+ proc_almost: process (RXSIZE, TXSIZE)
+ begin
+
+ -- (rx|tx)size is the number of bytes in fifo
+ -- --> rxsize is number of bytes which can be read
+ -- --> 2**txfawidth-txsize is is number of bytes which can be written
+
+ if unsigned(RXSIZE) <= RXAEMPTY_THRES then
+ RXAEMPTY <= '1';
+ else
+ RXAEMPTY <= '0';
+ end if;
+
+ if unsigned(TXSIZE) >= 2**TXFAWIDTH-TXAFULL_THRES then
+ TXAFULL <= '1';
+ else
+ TXAFULL <= '0';
+ end if;
+
+ end process proc_almost;
+
+ TXBUSY <= TXBUSY_L;
+
+end syn;
Index: fx2_2fifoctl_as.vbom
===================================================================
--- fx2_2fifoctl_as.vbom (nonexistent)
+++ fx2_2fifoctl_as.vbom (revision 24)
@@ -0,0 +1,13 @@
+# libs
+../../vlib/slvtypes.vhd
+../../vlib/xlib/xlib.vhd
+../../vlib/memlib/memlib.vhd
+fx2lib.vhd
+# components
+../../vlib/xlib/iob_reg_o.vbom
+../../vlib/xlib/iob_reg_i_gen.vbom
+../../vlib/xlib/iob_reg_o_gen.vbom
+../../vlib/xlib/iob_reg_io_gen.vbom
+../../vlib/memlib/fifo_1c_dram.vbom
+# design
+fx2_2fifoctl_as.vhd
Index: .
===================================================================
--- . (nonexistent)
+++ . (revision 24)
.
Property changes :
Added: svn:ignore
## -0,0 +1,32 ##
+*.dep_ghdl
+*.dep_isim
+*.dep_xst
+work-obj93.cf
+*.vcd
+*.ghw
+*.sav
+*.tmp
+*.exe
+ise
+xflow.his
+*.ngc
+*.ncd
+*.pcf
+*.bit
+*.msk
+isim
+isim.log
+isim.wdb
+fuse.log
+*_[sft]sim.vhd
+*_tsim.sdf
+*_xst.log
+*_tra.log
+*_twr.log
+*_map.log
+*_par.log
+*_pad.log
+*_bgn.log
+*_svn.log
+*_sum.log
+*_[dsft]sim.log