OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.61/] [rtl/] [bplib/] [fx2lib/] [fx2_3fifoctl_ic.vhd] - Blame information for rev 33

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 wfjm
-- $Id: fx2_3fifoctl_ic.vhd 472 2013-01-06 14:39:10Z mueller $
2 17 wfjm
--
3 18 wfjm
-- Copyright 2012-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 17 wfjm
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
-- 
14
------------------------------------------------------------------------------
15
-- Module Name:    fx2_3fifoctl_ic - syn
16
-- Description:    Cypress EZ-USB FX2 driver (3 fifo; int clk)
17
--
18
-- Dependencies:   vlib/xlib/iob_reg_o
19
--                 vlib/xlib/iob_reg_i_gen
20
--                 vlib/xlib/iob_reg_o_gen
21
--                 vlib/xlib/iob_reg_io_gen
22
--                 memlib/fifo_2c_dram
23
--
24
-- Test bench:     -
25
-- Target Devices: generic
26
-- Tool versions:  xst 13.3; ghdl 0.29
27
--
28
-- Synthesized (xst):
29
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
30 18 wfjm
-- 2012-01-15   453  13.3   O76x xc3s1200e-4  157  265   96  243 s  7.7/7.4
31 17 wfjm
-- 2012-01-15   453  13.3   O76x xc3s1200e-4  156  259   96  238 s  7.9/7.5
32
--
33
-- Revision History: 
34
-- Date         Rev Version  Comment
35 18 wfjm
-- 2013-01-04   469   1.1    BUGFIX: redo rx logic, now properly pipelined
36 17 wfjm
-- 2012-01-09   453   1.0    Initial version (derived from 2fifo_ic)
37
--
38
------------------------------------------------------------------------------
39
 
40
library ieee;
41
use ieee.std_logic_1164.all;
42
use ieee.numeric_std.all;
43
 
44
use work.slvtypes.all;
45
use work.xlib.all;
46
use work.memlib.all;
47
use work.fx2lib.all;
48
 
49
entity fx2_3fifoctl_ic is               -- EZ-USB FX2 driver (3 fifo; int clk)
50
  generic (
51
    RXFAWIDTH : positive :=  5;         -- receive  fifo address width
52
    TXFAWIDTH : positive :=  5;         -- transmit fifo address width
53
    PETOWIDTH : positive :=  7;         -- packet end time-out counter width
54
    CCWIDTH :   positive :=  5;         -- chunk counter width
55
    RXAEMPTY_THRES : natural := 1;      -- threshold for rx aempty flag
56
    TXAFULL_THRES  : natural := 1;      -- threshold for tx afull flag
57
    TX2AFULL_THRES : natural := 1);     -- threshold for tx2 afull flag
58
  port (
59
    CLK : in slbit;                     -- clock
60
    RESET : in slbit := '0';            -- reset
61
    RXDATA : out slv8;                  -- receive data out
62
    RXVAL : out slbit;                  -- receive data valid
63
    RXHOLD : in slbit;                  -- receive data hold
64
    RXAEMPTY : out slbit;               -- receive almost empty flag
65
    TXDATA : in slv8;                   -- transmit 1 data in
66
    TXENA : in slbit;                   -- transmit 1 data enable
67
    TXBUSY : out slbit;                 -- transmit 1 data busy
68
    TXAFULL : out slbit;                -- transmit 1 almost full flag
69
    TX2DATA : in slv8;                  -- transmit 2 data in
70
    TX2ENA : in slbit;                  -- transmit 2 data enable
71
    TX2BUSY : out slbit;                -- transmit 2 data busy
72
    TX2AFULL : out slbit;               -- transmit 2 almost full flag
73
    MONI : out fx2ctl_moni_type;        -- monitor port data
74
    I_FX2_IFCLK : in slbit;             -- fx2: interface clock
75
    O_FX2_FIFO : out slv2;              -- fx2: fifo address
76
    I_FX2_FLAG : in slv4;               -- fx2: fifo flags
77
    O_FX2_SLRD_N : out slbit;           -- fx2: read enable    (act.low)
78
    O_FX2_SLWR_N : out slbit;           -- fx2: write enable   (act.low)
79
    O_FX2_SLOE_N : out slbit;           -- fx2: output enable  (act.low)
80
    O_FX2_PKTEND_N : out slbit;         -- fx2: packet end     (act.low)
81
    IO_FX2_DATA : inout slv8            -- fx2: data lines
82
  );
83
end fx2_3fifoctl_ic;
84
 
85
 
86
architecture syn of fx2_3fifoctl_ic is
87
 
88
  constant c_rxfifo : slv2 := c_fifo_ep4;
89
  constant c_txfifo : slv2 := c_fifo_ep6;
90
  constant c_tx2fifo: slv2 := c_fifo_ep8;
91
 
92
  constant c_flag_prog   : integer := 0;
93
  constant c_flag_tx_ff  : integer := 1;
94
  constant c_flag_rx_ef  : integer := 2;
95
  constant c_flag_tx2_ff : integer := 3;
96
 
97
  type state_type is (
98
    s_idle,                             -- s_idle: idle state
99
    s_rxprep0,                          -- s_rxprep0: switch to rx-fifo
100
    s_rxprep1,                          -- s_rxprep1: fifo addr setup
101
    s_rxprep2,                          -- s_rxprep2: wait for flags
102
    s_rxdisp,                           -- s_rxdisp: read, dispatch
103 18 wfjm
    s_rxpipe,                           -- s_rxpipe: read, pipe wait
104 17 wfjm
    s_txprep0,                          -- s_txprep0: switch to tx-fifo
105
    s_txprep1,                          -- s_txprep1: fifo addr setup
106
    s_txprep2,                          -- s_txprep2: wait for flags
107
    s_txdisp,                           -- s_txdisp: write, dispatch
108
    s_tx2prep0,                         -- s_tx2prep0: switch to tx2-fifo
109
    s_tx2prep1,                         -- s_tx2prep1: fifo addr setup
110
    s_tx2prep2,                         -- s_tx2prep2: wait for flags
111
    s_tx2disp                           -- s_tx2disp: write, dispatch
112
  );
113
 
114
  type regs_type is record
115
    state : state_type;                 -- state
116
    petocnt : slv(PETOWIDTH-1 downto 0);  -- pktend 1 time out counter
117
    pe2tocnt : slv(PETOWIDTH-1 downto 0); -- pktend 2 time out counter
118
    pepend : slbit;                     -- pktend 1 pending
119
    pe2pend : slbit;                    -- pktend 2 pending
120 18 wfjm
    rxpipe1 : slbit;                    -- read pipe 1: iob capture stage
121
    rxpipe2 : slbit;                    -- read pipe 2: fifo write stage
122 17 wfjm
    ccnt : slv(CCWIDTH-1 downto 0);     -- chunk counter
123
    moni_ep4_sel : slbit;               -- ep4 (rx) select
124
    moni_ep6_sel : slbit;               -- ep6 (tx) select
125
    moni_ep8_sel : slbit;               -- ep8 (tx2) select
126
    moni_ep4_pf : slbit;                -- ep4 (rx) prog flag
127
    moni_ep6_pf : slbit;                -- ep6 (tx) prog flag
128
    moni_ep8_pf : slbit;                -- ep8 (tx2) prog flag
129
  end record regs_type;
130
 
131
  constant petocnt_init : slv(PETOWIDTH-1 downto 0) := (others=>'0');
132
  constant ccnt_init : slv(CCWIDTH-1 downto 0) := (others=>'0');
133
 
134
  constant regs_init : regs_type := (
135
    s_idle,                             -- state
136
    petocnt_init,                       -- petocnt
137
    petocnt_init,                       -- pe2tocnt
138 18 wfjm
    '0','0',                            -- pepend,pe2pend
139
    '0','0',                            -- rxpipe1, rxpipe2
140 17 wfjm
    ccnt_init,                          -- ccnt
141
    '0','0','0',                        -- moni_ep(4|6|8)_sel
142
    '0','0','0'                         -- moni_ep(4|6|8)_pf
143
  );
144
 
145
  signal R_REGS : regs_type := regs_init;  -- state registers
146
  signal N_REGS : regs_type := regs_init;  -- next value state regs
147
 
148
  signal FX2_FIFO     : slv2 := (others=>'0');
149
  signal FX2_FIFO_CE  : slbit := '0';
150
  signal FX2_FLAG_N   : slv4 := (others=>'0');
151
  signal FX2_SLRD_N   : slbit := '1';
152
  signal FX2_SLWR_N   : slbit := '1';
153
  signal FX2_SLOE_N   : slbit := '1';
154
  signal FX2_PKTEND_N : slbit := '1';
155
  signal FX2_DATA_CEI : slbit := '0';
156
  signal FX2_DATA_CEO : slbit := '0';
157
  signal FX2_DATA_OE  : slbit := '0';
158
  signal FX2_DATA_DO  : slv8 := (others=>'0');
159
 
160
  signal RXFIFO_DI  : slv8 := (others=>'0');
161
  signal RXFIFO_ENA  : slbit := '0';
162
  signal RXFIFO_BUSY : slbit := '0';
163
  signal RXSIZE_FX2  : slv(RXFAWIDTH-1 downto 0) := (others=>'0');
164
  signal RXSIZE_USR  : slv(RXFAWIDTH-1 downto 0) := (others=>'0');
165
  signal TXFIFO_DO   : slv8 := (others=>'0');
166
  signal TXFIFO_VAL  : slbit := '0';
167
  signal TXFIFO_HOLD : slbit := '0';
168
  signal TXSIZE_FX2  : slv(TXFAWIDTH-1 downto 0) := (others=>'0');
169
  signal TXSIZE_USR  : slv(TXFAWIDTH-1 downto 0) := (others=>'0');
170
  signal TX2FIFO_DO   : slv8 := (others=>'0');
171
  signal TX2FIFO_VAL  : slbit := '0';
172
  signal TX2FIFO_HOLD : slbit := '0';
173
  signal TX2SIZE_FX2  : slv(TXFAWIDTH-1 downto 0) := (others=>'0');
174
  signal TX2SIZE_USR  : slv(TXFAWIDTH-1 downto 0) := (others=>'0');
175
 
176
  signal TXBUSY_L : slbit := '0';
177
  signal TX2BUSY_L : slbit := '0';
178
 
179
  signal R_MONI_C : fx2ctl_moni_type := fx2ctl_moni_init;
180
  signal R_MONI_S : fx2ctl_moni_type := fx2ctl_moni_init;
181
 
182
begin
183
 
184
  assert RXAEMPTY_THRES<=2**RXFAWIDTH-1 and
185
         TXAFULL_THRES<=2**TXFAWIDTH-1 and
186
         TX2AFULL_THRES<=2**TXFAWIDTH-1
187
    report "assert((RXAEMPTY|TXAFULL|TX2AFULL)_THRES <= 2**(RX|TX)FAWIDTH)-1"
188
    severity failure;
189
 
190
 
191
  IOB_FX2_FIFO : iob_reg_o_gen
192
    generic map (
193
      DWIDTH => 2,
194
      INIT   => '0')
195
    port map (
196
      CLK => I_FX2_IFCLK,
197
      CE  => FX2_FIFO_CE,
198
      DO  => FX2_FIFO,
199
      PAD => O_FX2_FIFO
200
    );
201
 
202
  IOB_FX2_FLAG : iob_reg_i_gen
203
    generic map (
204
      DWIDTH => 4,
205
      INIT   => '0')
206
    port map (
207
      CLK => I_FX2_IFCLK,
208
      CE  => '1',
209
      DI  => FX2_FLAG_N,
210
      PAD => I_FX2_FLAG
211
    );
212
 
213
  IOB_FX2_SLRD : iob_reg_o
214
    generic map (
215
      INIT   => '1')
216
    port map (
217
      CLK => I_FX2_IFCLK,
218
      CE  => '1',
219
      DO  => FX2_SLRD_N,
220
      PAD => O_FX2_SLRD_N
221
    );
222
 
223
  IOB_FX2_SLWR : iob_reg_o
224
    generic map (
225
      INIT   => '1')
226
    port map (
227
      CLK => I_FX2_IFCLK,
228
      CE  => '1',
229
      DO  => FX2_SLWR_N,
230
      PAD => O_FX2_SLWR_N
231
    );
232
 
233
  IOB_FX2_SLOE : iob_reg_o
234
    generic map (
235
      INIT   => '1')
236
    port map (
237
      CLK => I_FX2_IFCLK,
238
      CE  => '1',
239
      DO  => FX2_SLOE_N,
240
      PAD => O_FX2_SLOE_N
241
    );
242
 
243
  IOB_FX2_PKTEND : iob_reg_o
244
    generic map (
245
      INIT   => '1')
246
    port map (
247
      CLK => I_FX2_IFCLK,
248
      CE  => '1',
249
      DO  => FX2_PKTEND_N,
250
      PAD => O_FX2_PKTEND_N
251
    );
252
 
253
  IOB_FX2_DATA : iob_reg_io_gen
254
    generic map (
255
      DWIDTH => 8,
256
      PULL   => "KEEP")
257
    port map (
258
      CLK => I_FX2_IFCLK,
259
      CEI => FX2_DATA_CEI,
260
      CEO => FX2_DATA_CEO,
261
      OE  => FX2_DATA_OE,
262
      DI  => RXFIFO_DI,                 -- input data   (read from pad)
263
      DO  => FX2_DATA_DO,               -- output data  (write  to pad)
264
      PAD => IO_FX2_DATA
265
    );
266
 
267
  RXFIFO : fifo_2c_dram                -- input fifo, 2 clock, dram based
268
    generic map (
269
      AWIDTH => RXFAWIDTH,
270
      DWIDTH => 8)
271
    port map (
272
      CLKW   => I_FX2_IFCLK,
273
      CLKR   => CLK,
274
      RESETW => '0',
275
      RESETR => RESET,
276
      DI     => RXFIFO_DI,
277
      ENA    => RXFIFO_ENA,
278
      BUSY   => RXFIFO_BUSY,
279
      DO     => RXDATA,
280
      VAL    => RXVAL,
281
      HOLD   => RXHOLD,
282
      SIZEW  => RXSIZE_FX2,
283
      SIZER  => RXSIZE_USR
284
    );
285
 
286
  TXFIFO : fifo_2c_dram                -- output fifo, 2 clock, dram based
287
    generic map (
288
      AWIDTH => TXFAWIDTH,
289
      DWIDTH => 8)
290
    port map (
291
      CLKW   => CLK,
292
      CLKR   => I_FX2_IFCLK,
293
      RESETW => RESET,
294
      RESETR => '0',
295
      DI     => TXDATA,
296
      ENA    => TXENA,
297
      BUSY   => TXBUSY_L,
298
      DO     => TXFIFO_DO,
299
      VAL    => TXFIFO_VAL,
300
      HOLD   => TXFIFO_HOLD,
301
      SIZEW  => TXSIZE_USR,
302
      SIZER  => TXSIZE_FX2
303
    );
304
 
305
  TX2FIFO : fifo_2c_dram               -- output 2 fifo, 2 clock, dram based
306
    generic map (
307
      AWIDTH => TXFAWIDTH,
308
      DWIDTH => 8)
309
    port map (
310
      CLKW   => CLK,
311
      CLKR   => I_FX2_IFCLK,
312
      RESETW => RESET,
313
      RESETR => '0',
314
      DI     => TX2DATA,
315
      ENA    => TX2ENA,
316
      BUSY   => TX2BUSY_L,
317
      DO     => TX2FIFO_DO,
318
      VAL    => TX2FIFO_VAL,
319
      HOLD   => TX2FIFO_HOLD,
320
      SIZEW  => TX2SIZE_USR,
321
      SIZER  => TX2SIZE_FX2
322
    );
323
 
324
  proc_regs: process (I_FX2_IFCLK)
325
  begin
326
 
327
    if rising_edge(I_FX2_IFCLK) then
328
      if RESET = '1' then
329
        R_REGS <= regs_init;
330
      else
331
        R_REGS <= N_REGS;
332
      end if;
333
    end if;
334
 
335
  end process proc_regs;
336
 
337
  proc_next: process (R_REGS,
338
                      FX2_FLAG_N, TXFIFO_VAL, TX2FIFO_VAL,
339
                      TXFIFO_DO, TX2FIFO_DO,
340
                      RXSIZE_FX2, RXFIFO_BUSY, TXBUSY_L, TX2BUSY_L)
341
 
342
    variable r : regs_type := regs_init;
343
    variable n : regs_type := regs_init;
344
 
345
    variable ififo_ce : slbit := '0';
346
    variable ififo    : slv2 := "00";
347
 
348
    variable irxfifo_ena   : slbit := '0';
349
    variable itxfifo_hold  : slbit := '0';
350
    variable itx2fifo_hold : slbit := '0';
351
 
352
    variable islrd   : slbit := '0';
353
    variable islwr   : slbit := '0';
354
    variable isloe   : slbit := '0';
355
    variable ipktend : slbit := '0';
356
 
357
    variable idata_cei : slbit := '0';
358
    variable idata_ceo : slbit := '0';
359
    variable idata_oe  : slbit := '0';
360
    variable idata_do  : slv8 := (others=>'0');
361
 
362
    variable slrxok  : slbit := '0';
363
    variable sltxok  : slbit := '0';
364
    variable sltx2ok : slbit := '0';
365
    variable pipeok  : slbit := '0';
366
 
367
    variable cc_clr : slbit := '0';
368
    variable cc_cnt : slbit := '0';
369
    variable cc_done : slbit := '0';
370
 
371
  begin
372
 
373
    r := R_REGS;
374
    n := R_REGS;
375
 
376
    ififo_ce := '0';
377
    ififo    := "00";
378
 
379
    irxfifo_ena   := '0';
380
    itxfifo_hold  := '1';
381
    itx2fifo_hold := '1';
382
 
383
    islrd   := '0';
384
    islwr   := '0';
385
    isloe   := '0';
386
    ipktend := '0';
387
 
388
    idata_cei := '0';
389
    idata_ceo := '0';
390
    idata_oe  := '0';
391
    idata_do  := TXFIFO_DO;
392
 
393
    slrxok  := FX2_FLAG_N(c_flag_rx_ef);  -- empty flag is act.low!
394
    sltxok  := FX2_FLAG_N(c_flag_tx_ff);  --  full flag is act.low!
395
    sltx2ok := FX2_FLAG_N(c_flag_tx2_ff); --  full flag is act.low!
396
    pipeok  := FX2_FLAG_N(c_flag_prog);   -- almost flag is act.low!
397
 
398
    cc_clr := '0';
399
    cc_cnt := '0';
400
    if unsigned(r.ccnt) = 0  then
401
      cc_done := '1';
402
    else
403
      cc_done := '0';
404
    end if;
405 18 wfjm
 
406
    n.rxpipe1  := '0';
407 17 wfjm
 
408
    case r.state is
409
      when s_idle =>                    -- s_idle:
410
        if slrxok='1' and RXFIFO_BUSY='0' then
411
          ififo_ce := '1';
412
          ififo    := c_rxfifo;
413
          n.state := s_rxprep1;
414
        elsif sltxok='1' and (TXFIFO_VAL='1' or r.pepend='1')then
415
          ififo_ce := '1';
416
          ififo    := c_txfifo;
417
          n.state := s_txprep1;
418
        elsif sltx2ok='1' and (TX2FIFO_VAL='1' or r.pe2pend='1')then
419
          ififo_ce := '1';
420
          ififo    := c_tx2fifo;
421
          n.state := s_tx2prep1;
422
        end if;
423
 
424
      when s_rxprep0 =>                 -- s_rxprep0: switch to rx-fifo
425
        ififo_ce := '1';
426
        ififo    := c_rxfifo;
427
        n.state := s_rxprep1;
428
 
429
      when s_rxprep1 =>                 -- s_rxprep1: fifo addr setup
430
        cc_clr  := '1';
431
        n.state := s_rxprep2;
432
 
433
      when s_rxprep2 =>                 -- s_rxprep2: wait for flags
434
        isloe   := '1';
435
        n.state := s_rxdisp;
436
 
437
      when s_rxdisp =>                  -- s_rxdisp: read, dispatch
438
        isloe := '1';
439
        -- if chunk done and tx or pe pending and possible
440
        if cc_done='1' and sltxok='1' and (TXFIFO_VAL='1' or r.pepend='1') then
441 18 wfjm
          if r.rxpipe1='1' or r.rxpipe2='1' then -- rx pipe busy ?
442
            n.state := s_rxdisp;            -- wait
443
          else
444
            n.state := s_txprep0;           -- otherwise switch to tx flow
445
          end if;
446 17 wfjm
        -- if chunk done and tx2 or pe2 pending and possible
447
        elsif cc_done='1' and sltx2ok='1' and (TX2FIFO_VAL='1' or r.pe2pend='1')
448
        then
449 18 wfjm
          if r.rxpipe1='1' or r.rxpipe2='1' then -- rx pipe busy ?
450
            n.state := s_rxdisp;            -- wait
451
          else
452
            n.state := s_tx2prep0;
453
          end if;
454 17 wfjm
        -- if more rx to do and possible
455 18 wfjm
        elsif slrxok='1' and unsigned(RXSIZE_FX2)>3 then  -- !thres must be >3!
456
          islrd := '1';
457 17 wfjm
          cc_cnt := '1';
458 18 wfjm
          n.rxpipe1 := '1';
459
          if pipeok='1' then
460
            n.state := s_rxdisp;             -- 1 cycle read
461
            --n.state := s_rxprep2;            -- 2 cycle read
462 17 wfjm
          else
463
            n.state := s_rxpipe;
464 18 wfjm
          end if;
465 17 wfjm
        -- otherwise back to idle
466
        else
467 18 wfjm
          if r.rxpipe1='1' or r.rxpipe2='1' then -- rx pipe busy ?
468
            n.state := s_rxdisp;            -- wait
469
          else
470
            n.state := s_idle;              -- to idle
471
          end if;
472 17 wfjm
        end if;
473
 
474 18 wfjm
      when s_rxpipe =>                  -- s_rxpipe:  read, pipe wait
475 17 wfjm
        isloe := '1';
476 18 wfjm
        n.state := s_rxprep2;
477 17 wfjm
 
478
      when s_txprep0 =>                 -- s_txprep0: switch to tx-fifo
479
        ififo_ce := '1';
480
        ififo    := c_txfifo;
481
        n.state := s_txprep1;
482
 
483
      when s_txprep1 =>                 -- s_txprep1: fifo addr setup
484
        cc_clr  := '1';
485
        n.state := s_txprep2;
486
 
487
      when s_txprep2 =>                 -- s_txprep2: wait for flags
488
        n.state := s_txdisp;
489
 
490
      when s_txdisp =>                  -- s_txdisp: write, dispatch
491
        -- if chunk done and tx2 or pe2 pending and possible
492
        if cc_done='1' and sltx2ok='1' and (TX2FIFO_VAL='1' or r.pe2pend='1')
493
        then
494
          n.state := s_tx2prep0;
495
        -- if chunk done and rx pending and possible
496
        elsif cc_done='1' and slrxok='1' and RXFIFO_BUSY='0' then
497
          n.state := s_rxprep0;
498
        -- if pktend to do and possible
499
        elsif sltxok = '1' and r.pepend = '1' then
500
          ipktend  := '1';
501
          n.pepend := '0';
502
          n.state := s_idle;
503
        -- if more tx to do and possible
504
        elsif sltxok = '1' and TXFIFO_VAL = '1' then
505
          cc_cnt := '1';                  -- inc chunk count
506
          n.pepend := '0';                -- cancel pe (avoid back-2-back tx+pe)
507
          itxfifo_hold := '0';
508
          idata_do  := TXFIFO_DO;
509
          idata_ceo := '1';
510
          idata_oe  := '1';
511
          islwr     := '1';
512
          if pipeok = '1' then           -- if not almost full
513
            n.state   := s_txdisp;          -- stream 
514
          else
515
            n.state   := s_txprep1;         -- wait for full flag
516
          end if;
517
        -- otherwise back to idle
518
        else
519
          n.state := s_idle;
520
        end if;
521
 
522
      when s_tx2prep0 =>                -- s_tx2prep0: switch to tx2-fifo
523
        ififo_ce := '1';
524
        ififo    := c_tx2fifo;
525
        n.state := s_tx2prep1;
526
 
527
      when s_tx2prep1 =>                -- s_tx2prep1: fifo addr setup
528
        cc_clr  := '1';
529
        n.state := s_tx2prep2;
530
 
531
      when s_tx2prep2 =>                -- s_tx2prep2: wait for flags
532
        n.state := s_tx2disp;
533
 
534
      when s_tx2disp =>                 -- s_tx2disp: write, dispatch
535
        -- if chunk done and rx pending and possible
536
        if cc_done='1' and slrxok='1' and RXFIFO_BUSY='0' then
537
          n.state := s_rxprep0;
538
        -- if chunk done and tx or pe pending and possible
539
        elsif cc_done='1' and sltxok='1' and (TXFIFO_VAL='1' or r.pepend='1')
540
        then
541
          n.state := s_txprep0;
542
        -- if pktend 2 to do and possible
543
        elsif sltx2ok = '1' and r.pe2pend = '1' then
544
          ipktend  := '1';
545
          n.pe2pend := '0';
546
          n.state := s_idle;
547
        -- if more tx2 to do and possible
548
        elsif sltx2ok = '1' and TX2FIFO_VAL = '1' then
549
          cc_cnt := '1';                  -- inc chunk count
550
          n.pe2pend := '0';               -- cancel pe (avoid back-2-back tx+pe)
551
          itx2fifo_hold := '0';
552
          idata_do  := TX2FIFO_DO;
553
          idata_ceo := '1';
554
          idata_oe  := '1';
555
          islwr     := '1';
556
          if pipeok = '1' then           -- if not almost full
557
            n.state   := s_tx2disp;        -- stream 
558
          else
559
            n.state   := s_tx2prep1;       -- wait for full flag
560
          end if;
561
        -- otherwise back to idle
562
        else
563
          n.state := s_idle;
564
        end if;
565
 
566
      when others => null;
567
    end case;
568
 
569 18 wfjm
    -- rx pipe handling
570
    idata_cei   := r.rxpipe1;
571
    n.rxpipe2   := r.rxpipe1;
572
    irxfifo_ena := r.rxpipe2;
573
 
574 17 wfjm
    -- chunk counter handling
575
    if cc_clr = '1' then
576
      n.ccnt := (others=>'1');
577
    elsif cc_cnt='1' and unsigned(r.ccnt) > 0 then
578
      n.ccnt := slv(unsigned(r.ccnt) - 1);
579
    end if;
580
 
581
    -- pktend time-out handling:
582
    --   if tx fifo is non-empty, set counter to max
583
    --   if tx fifo is empty, count down every usec
584
    --   on 1->0 transition queue pktend request
585
    if TXFIFO_VAL = '1' then
586
      n.petocnt := (others=>'1');
587
    else
588
      if unsigned(r.petocnt) /= 0 then
589
        n.petocnt := slv(unsigned(r.petocnt) - 1);
590
        if unsigned(r.petocnt) = 1 then
591
          n.pepend := '1';
592
        end if;
593
      end if;
594
    end if;
595
    if TX2FIFO_VAL = '1' then
596
      n.pe2tocnt := (others=>'1');
597
    else
598
      if unsigned(r.pe2tocnt) /= 0 then
599
        n.pe2tocnt := slv(unsigned(r.pe2tocnt) - 1);
600
        if unsigned(r.pe2tocnt) = 1 then
601
          n.pe2pend := '1';
602
        end if;
603
      end if;
604
    end if;
605
 
606
    n.moni_ep4_sel := '0';
607
    n.moni_ep6_sel := '0';
608
    n.moni_ep8_sel := '0';
609
    if r.state = s_rxdisp or r.state = s_rxpipe then
610
      n.moni_ep4_sel := '1';
611
      n.moni_ep4_pf  := not FX2_FLAG_N(c_flag_prog);
612
    elsif r.state = s_txdisp then
613
      n.moni_ep6_sel := '1';
614
      n.moni_ep6_pf  := not FX2_FLAG_N(c_flag_prog);
615
    elsif r.state = s_tx2disp then
616
      n.moni_ep8_sel := '1';
617
      n.moni_ep8_pf  := not FX2_FLAG_N(c_flag_prog);
618
    end if;
619
 
620
    N_REGS <= n;
621
 
622
    FX2_FIFO_CE  <= ififo_ce;
623
    FX2_FIFO     <= ififo;
624
 
625
    FX2_SLRD_N   <= not islrd;
626
    FX2_SLWR_N   <= not islwr;
627
    FX2_SLOE_N   <= not isloe;
628
    FX2_PKTEND_N <= not ipktend;
629
 
630
    FX2_DATA_CEI <= idata_cei;
631
    FX2_DATA_CEO <= idata_ceo;
632
    FX2_DATA_OE  <= idata_oe;
633
    FX2_DATA_DO  <= idata_do;
634
 
635
    RXFIFO_ENA   <= irxfifo_ena;
636
    TXFIFO_HOLD  <= itxfifo_hold;
637
    TX2FIFO_HOLD <= itx2fifo_hold;
638
 
639
  end process proc_next;
640
 
641
  proc_moni: process (CLK)
642
  begin
643
 
644
    if rising_edge(CLK) then
645
      if RESET = '1' then
646
        R_MONI_C <= fx2ctl_moni_init;
647
        R_MONI_S <= fx2ctl_moni_init;
648
      else
649
        R_MONI_C <= fx2ctl_moni_init;
650
        R_MONI_C.fifo_ep4        <= R_REGS.moni_ep4_sel;
651
        R_MONI_C.fifo_ep6        <= R_REGS.moni_ep6_sel;
652
        R_MONI_C.fifo_ep8        <= R_REGS.moni_ep8_sel;
653
        R_MONI_C.flag_ep4_empty  <= not FX2_FLAG_N(c_flag_rx_ef);
654
        R_MONI_C.flag_ep4_almost <= R_REGS.moni_ep4_pf;
655
        R_MONI_C.flag_ep6_full   <= not FX2_FLAG_N(c_flag_tx_ff);
656
        R_MONI_C.flag_ep6_almost <= R_REGS.moni_ep6_pf;
657
        R_MONI_C.flag_ep8_full   <= not FX2_FLAG_N(c_flag_tx2_ff);
658
        R_MONI_C.flag_ep8_almost <= R_REGS.moni_ep8_pf;
659
        R_MONI_C.slrd            <= not FX2_SLRD_N;
660
        R_MONI_C.slwr            <= not FX2_SLWR_N;
661
        R_MONI_C.pktend          <= not FX2_PKTEND_N;
662
        R_MONI_S <= R_MONI_C;
663
      end if;
664
    end if;
665
 
666
  end process proc_moni;
667
 
668
  proc_almost: process (RXSIZE_USR, TXSIZE_USR, TX2SIZE_USR)
669
  begin
670
 
671
    -- rxsize_usr is the number of bytes to read
672
    -- txsize_usr is the number of bytes to write
673
 
674
    if unsigned(RXSIZE_USR) <= RXAEMPTY_THRES then
675
      RXAEMPTY <= '1';
676
    else
677
      RXAEMPTY <= '0';
678
    end if;
679
 
680
    if unsigned(TXSIZE_USR) <= TXAFULL_THRES then
681
      TXAFULL <= '1';
682
    else
683
      TXAFULL <= '0';
684
    end if;
685
 
686
    if unsigned(TX2SIZE_USR) <= TX2AFULL_THRES then
687
      TX2AFULL <= '1';
688
    else
689
      TX2AFULL <= '0';
690
    end if;
691
 
692
  end process proc_almost;
693
 
694
  TXBUSY  <= TXBUSY_L;
695
  TX2BUSY <= TX2BUSY_L;
696
 
697
  MONI <= R_MONI_S;
698
 
699
end syn;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.