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

Subversion Repositories esoc

[/] [esoc/] [trunk/] [Sources/] [altera/] [esoc_port_mac/] [testbench/] [model/] [ethmon_32.vhd] - Blame information for rev 42

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 42 lmaarsen
-- -------------------------------------------------------------------------
2
-- -------------------------------------------------------------------------
3
--
4
-- Revision Control Information
5
--
6
-- $RCSfile: ethmon_32.vhd,v $
7
-- $Source: /ipbu/cvs/sio/projects/TriSpeedEthernet/src/testbench/models/vhdl/ethernet_model/mon/ethmon_32.vhd,v $
8
--
9
-- $Revision: #1 $
10
-- $Date: 2008/08/09 $
11
-- Check in by : $Author: sc-build $
12
-- Author      : SKNg/TTChong
13
--
14
-- Project     : Triple Speed Ethernet - 10/100/1000 MAC
15
--
16
-- Description : (Simulation only)
17
--
18
-- Ethernet Traffic Monitor/Decoder for 32 bit MAC Atlantic client interface
19
-- Instantiated in top_ethmonitor32 (top_ethmon32.vhd)
20
--
21
-- 
22
-- ALTERA Confidential and Proprietary
23
-- Copyright 2006 (c) Altera Corporation
24
-- All rights reserved
25
--
26
-- -------------------------------------------------------------------------
27
-- -------------------------------------------------------------------------
28
 
29
 
30
 
31
library ieee ;
32
use ieee.std_logic_1164.all ;
33
use ieee.std_logic_arith.all ;
34
use ieee.std_logic_unsigned.all ;
35
use std.textio.all ;
36
 
37
entity ETHMONITOR_32 is
38
 
39
    generic (
40
        ENABLE_SHIFT16 : integer := 0  --0 for false, 1 for true
41
    );
42
 
43
    port (
44
 
45
      reset       : in std_logic ;     -- active high
46
 
47
        -- GMII transmit interface: To be connected to MAC TX
48
 
49
      tx_clk      : in std_logic ;
50
      txd         : in std_logic_vector(7 downto 0);
51
      tx_dv       : in std_logic;
52
      tx_er       : in std_logic;
53
 
54
        -- Frame Contents definitions
55
 
56
      dst           : out std_logic_vector(47 downto 0); -- destination address
57
      src           : out std_logic_vector(47 downto 0); -- source address
58
 
59
      prmble_len    : out integer range 0 to 10000;         -- length of preamble
60
      pquant        : out std_logic_vector(15 downto 0); -- Pause Quanta value
61
      vlan_ctl      : out std_logic_vector(15 downto 0); -- VLAN control info
62
      len           : out std_logic_vector(15 downto 0); -- Length of payload
63
      frmtype       : out std_logic_vector(15 downto 0); -- if non-null: type field instead length
64
 
65
      payload       : out std_logic_vector(7 downto 0);
66
      payload_vld   : out std_logic;
67
 
68
        -- Indicators
69
 
70
      is_vlan       : out std_logic;
71
      is_stack_vlan : out std_logic;
72
      is_pause      : out std_logic;
73
      crc_err       : out std_logic;
74
      prmbl_err     : out std_logic;
75
      len_err       : out std_logic;
76
      payload_err   : out std_logic;
77
      frame_err     : out std_logic;
78
      pause_op_err  : out std_logic;
79
      pause_dst_err : out std_logic;
80
      mac_err       : out std_logic;
81
      end_err       : out std_logic;
82
 
83
       -- Control
84
 
85
      jumbo_en      : in std_logic;
86
      data_only     : in std_logic;
87
 
88
        -- Receive indicator
89
 
90
      frm_rcvd     : out std_logic );
91
 
92
end ETHMONITOR_32 ;
93
 
94
architecture behave of ETHMONITOR_32 is
95
 
96
    -- port signals internally reused
97
 
98
    signal iprmble_len    : integer range 0 to 10000;         -- length of preamble
99
    signal ifrmtype       : std_logic_vector(15 downto 0);
100
    signal ilen           : std_logic_vector(15 downto 0);
101
    signal idst           : std_logic_vector(47 downto 0);
102
 
103
    signal iis_vlan       : std_logic;
104
    signal iis_stack_vlan : std_logic;
105
    signal iis_pause      : std_logic;
106
 
107
    -- internal
108
 
109
    type  state_typ is (S_IDLE, S_PRMBL,
110
                                S_DST , S_SRC, S_TYPELEN, S_PAUSE, S_TAG, S_LEN,
111
                                S_DATA, S_PAD, S_CRC, S_ABORT, S_UTYPE, S_DWORD32ALIGNED);
112
 
113
    signal state      : state_typ;
114
    signal last_state : state_typ;
115
 
116
 
117
    signal last_tx_dv : std_logic;     -- follows tx_dv with one cycle delay
118
 
119
 
120
    signal crc32 : std_logic_vector(31 downto 0);
121
 
122
    signal count : integer range 0 to 65535;
123
    signal poscnt: integer range 0 to 65535;       -- position in frame starts at first dst byte
124
 
125
    signal datacnt: integer range 0 to 255;   -- counter to verify payload
126
    signal datainc: integer range 0 to 255;   -- counter increment
127
 
128
    signal tx_sof  :  std_logic;   -- start of frame indicator for 1 clk cycle with 1st byte
129
    signal tx_dst  :  std_logic;   -- start of frame indicator for 1 clk cycle with 1st byte
130
 
131
 
132
begin
133
 
134
    -- connect permanent port signals
135
    -- ------------------------------
136
 
137
    prmble_len    <= iprmble_len;
138
    frmtype       <= ifrmtype;
139
    len           <= ilen;
140
    dst           <= idst;
141
    is_vlan       <= iis_vlan;
142
    is_stack_vlan <= iis_stack_vlan;
143
    is_pause      <= iis_pause;
144
 
145
 
146
    -- generate tx start pulse
147
    -- ----------------------
148
 
149
    tx_sof <= not(last_tx_dv) and tx_dv;     -- pulse with first byte 0 to 1 change
150
 
151
 
152
    -- generate pulse start of destination address
153
    -- --------------------
154
 
155
    process( last_state, state )
156
    begin
157
 
158
        if( (last_state/=S_DST) and (state=S_DST)) then
159
 
160
            tx_dst <= '1';
161
 
162
        else
163
 
164
            tx_dst <= '0';
165
 
166
        end if;
167
   end process;
168
 
169
 
170
    -- ------------------------------------------
171
    -- capture tx_er indicator
172
    -- ------------------------------------------
173
 
174
    process( tx_clk, reset )
175
    begin
176
 
177
        if( reset='1') then
178
 
179
            mac_err    <= '0';
180
            last_tx_dv <= '0';
181
 
182
        elsif( tx_clk='1' and tx_clk'event ) then
183
 
184
            if( tx_sof='1' ) then
185
 
186
                mac_err <= '0';            -- reset indicator at start of new receive
187
 
188
            elsif( tx_er = '1' ) then
189
 
190
                mac_err <= '1';        -- capture one or many
191
 
192
            end if;
193
 
194
            last_tx_dv <= tx_dv;
195
 
196
        end if;
197
    end process;
198
 
199
 
200
    -- ----------------------------------------------
201
    -- CRC calculation over all bytes except preamble
202
    -- ----------------------------------------------
203
 
204
    process( tx_clk, reset )
205
 
206
        variable crctmp : std_logic_vector(31 downto 0);
207
        variable i      : integer range 0 to 8;
208
 
209
    begin
210
        if( reset = '1' ) then
211
 
212
            crc32    <= (others => '1' );
213
            crc_err  <= '0';
214
 
215
        elsif( tx_clk = '1' and tx_clk'event ) then    -- need it ahead
216
 
217
            if( (tx_dst='1') or
218
                ((state /= S_IDLE) and (state /= S_PRMBL) and (state /= S_UTYPE)) or
219
                ((state = S_UTYPE) and tx_dv='1') ) then  -- push all inclusive CRC bytes
220
 
221
                    -- preset CRC or load current value
222
 
223
                    if( tx_dst='1' ) then   -- first data, preset CRC
224
 
225
                        crctmp := (others => '1' );
226
 
227
                    else
228
 
229
                        crctmp := crc32;
230
 
231
                    end if;
232
 
233
                    -- calculate next step
234
 
235
                    for i in 0 to 7 loop      -- process all bits we have here
236
 
237
                       if( (txd(i) xor crctmp(31)) = '1' ) then
238
                         crctmp := to_stdlogicvector((to_bitvector(crctmp)) sll 1);  -- shift in a 0, will be xor'ed to 1 by the polynom
239
                         crctmp := crctmp xor X"04C11DB7";
240
                       else
241
                         crctmp := to_stdlogicvector((to_bitvector(crctmp)) sll 1);  -- shift in a 0
242
                       end if;
243
 
244
                   end loop;
245
 
246
                   crc32 <= crctmp; -- remember current value
247
 
248
 
249
                   -- check if CRC is valid
250
 
251
                   if( crctmp = X"C704DD7B" ) then
252
 
253
                        crc_err <= '0';
254
 
255
                   else
256
 
257
                        crc_err <= '1';
258
 
259
                   end if;
260
 
261
            end if;
262
 
263
        end if;
264
 
265
    end process;
266
 
267
    -- ----------------------------------------------
268
    -- Extract RX Payload on payload bus and check payload errors:
269
    -- * first byte is counter initialization
270
    -- * second byte is counter increment
271
    -- * data begins from 3rd byte on 
272
    -- ----------------------------------------------
273
 
274
    process( tx_clk, reset )
275
    begin
276
        if( reset = '1' ) then
277
 
278
            payload     <= (others => '0' );
279
            payload_vld <= '0';
280
            payload_err <= '0';
281
            datacnt     <= 0;
282
 
283
        elsif( tx_clk='1' and tx_clk'event ) then
284
 
285
            if( state = S_TYPELEN ) then
286
 
287
                payload_err <= '0';        -- reset as a frame of length 0 will not get into S_DATA.
288
 
289
            end if;
290
 
291
            if( state = S_DATA) then
292
 
293
                payload     <= txd;
294
                payload_vld <= '1';
295
 
296
                if( count=0 ) then
297
 
298
                    datacnt <= conv_integer('0' & txd);   -- load counter
299
                    payload_err <= '0';
300
 
301
                elsif( count=1) then
302
 
303
                    datainc <= conv_integer('0' & txd);   -- load increment
304
 
305
                else
306
 
307
                        -- verify payload contents
308
 
309
                    datacnt <= (datacnt+datainc) mod 256;
310
 
311
                    if( datacnt /= conv_integer('0' & txd ) ) then
312
 
313
                         payload_err <= '1';
314
 
315
                    end if;
316
 
317
                end if;
318
 
319
            else
320
 
321
                payload       <= (others => '0' );
322
                payload_vld   <= '0';
323
 
324
            end if;
325
        end if;
326
    end process;
327
 
328
    -- ----------------------------------------------
329
    -- Position Counter: Starts with first octet of destination address
330
    -- ----------------------------------------------
331
 
332
    process( tx_clk, reset )
333
    begin
334
      if( reset = '1' ) then
335
 
336
            poscnt <= 0;
337
 
338
      elsif(tx_clk='1' and tx_clk'event ) then
339
 
340
            if( tx_dst='1' ) then  -- reset at start of DST 
341
 
342
                poscnt <= 1;
343
 
344
            else
345
 
346
                if( poscnt < 65535 ) then
347
 
348
                        poscnt <= poscnt +1;
349
 
350
                end if;
351
 
352
            end if;
353
     end if;
354
    end process;
355
 
356
 
357
 
358
 
359
 
360
    -- ----------------------------------------------
361
    -- End of Frame:
362
    -- change from non-idle to idle indicates something was received
363
    -- if dv is still asserted this is an end error
364
    -- ----------------------------------------------
365
    process( tx_clk, reset )
366
    begin
367
      if( reset = '1' ) then
368
 
369
            frm_rcvd <= '0';
370
            end_err  <= '0';
371
 
372
      elsif(tx_clk='1' and tx_clk'event ) then
373
 
374
            if( last_state/=S_IDLE and state=S_IDLE ) then
375
 
376
                frm_rcvd <= '1';
377
 
378
            else
379
 
380
                frm_rcvd <= '0';
381
 
382
            end if;
383
 
384
 
385
            if( tx_sof='1' ) then
386
 
387
                end_err <= '0';
388
 
389
            elsif(last_state/=S_IDLE and state=S_IDLE and tx_dv='1') then
390
 
391
                end_err <= '1';  -- dv still asserted even after nothing more expected
392
 
393
            end if;
394
 
395
      end if;
396
    end process;
397
 
398
    -- ----------------------------------------------
399
    -- Preamble check
400
    -- ----------------------------------------------
401
    process( tx_clk, reset )
402
    begin
403
      if( reset = '1' ) then
404
 
405
            prmbl_err <= '0';
406
            iprmble_len <= 0;
407
 
408
      elsif(tx_clk='1' and tx_clk'event ) then
409
 
410
            if( tx_sof='1' ) then
411
 
412
                if( txd /= X"55" ) then
413
 
414
                    prmbl_err <= '1';
415
 
416
                else
417
 
418
                    prmbl_err <= '0';      -- reset usually
419
 
420
                end if;
421
 
422
                if( data_only='1' ) then
423
 
424
                    iprmble_len <= 0;
425
 
426
                else
427
 
428
                    iprmble_len <= 1;
429
 
430
                end if;
431
 
432
 
433
            elsif( state=S_PRMBL ) then
434
 
435
                if( txd /= X"55" and txd /= X"D5" ) then
436
 
437
                    prmbl_err <= '1';
438
 
439
                end if;
440
 
441
                iprmble_len <= iprmble_len + 1;
442
 
443
            end if;
444
      end if;
445
    end process;
446
 
447
 
448
    -- ----------------------------------------------
449
    -- Extract Source and Destination addresses
450
    -- ----------------------------------------------
451
    process( tx_clk, reset )
452
 
453
        variable ix: integer;
454
 
455
    begin
456
      if( reset = '1' ) then
457
 
458
            idst <= (others => '0');
459
            src <= (others => '0');
460
 
461
      elsif(tx_clk='1' and tx_clk'event ) then
462
 
463
            ix := (count*8);
464
 
465
            if( tx_sof='1' ) then
466
                ix := 0;
467
            end if;
468
 
469
 
470
            if (tx_sof = '1' and data_only = '1' and state = S_DWORD32ALIGNED and ENABLE_SHIFT16 = 1) then
471
                          -- do nothing.
472
            end if;
473
 
474
            if (tx_sof = '1' and data_only = '1' and ENABLE_SHIFT16 = 1 and state = S_DST) then
475
 
476
                    idst(ix+7 downto ix) <= txd(7 downto 0);      -- first received is LSByte
477
 
478
                end if;
479
 
480
            if( (tx_sof='1' and data_only='1' and ENABLE_SHIFT16 = 0 ) or     -- very first byte and not preamble
481
                (state=S_DST) ) then
482
 
483
                idst(ix+7 downto ix) <= txd(7 downto 0);      -- first received is LSByte
484
 
485
            end if;
486
 
487
            if( state=S_SRC ) then
488
 
489
                src(ix+7 downto ix) <= txd(7 downto 0);      -- first received is LSByte
490
 
491
            end if;
492
 
493
      end if;
494
 
495
    end process;
496
 
497
    -- ----------------------------------------------
498
    -- Extract Length/Type field and VLAN Tag identifier
499
    -- ----------------------------------------------
500
    process( tx_clk, reset )
501
 
502
        variable ix: integer;
503
        variable ln: line;
504
 
505
    begin
506
      if( reset = '1' ) then
507
 
508
            ilen           <= (others => '0');
509
            ifrmtype       <= (others => '0');
510
            vlan_ctl       <= (others => '0');
511
            iis_vlan       <= '0';
512
            len_err        <= '0';
513
            iis_stack_vlan <= '0' ;
514
 
515
      elsif(tx_clk='1' and tx_clk'event ) then
516
 
517
            ix := 8-(count*8);
518
 
519
            --if( tx_sof_d = '1' ) then              -- clear all on start of every frame
520
            --
521
            --    ilen     <= (others => '0');
522
            --    ifrmtype <= (others => '0');
523
            --    vlan_ctl <= (others => '0');
524
            --    iis_vlan  <= '0';
525
            --    
526
            --end if;
527
 
528
            if( state=S_TYPELEN ) then            -- if in type/len set both
529
 
530
                ifrmtype(ix+7 downto ix) <= txd;
531
                ilen(ix+7 downto ix)     <= txd;
532
                vlan_ctl <= (others => '0');      -- clear at start of new frame (at SOF it is too early)
533
                iis_vlan  <= '0';
534
                len_err  <= '0';
535
 
536
            elsif( state=S_LEN ) then             -- in len again, set len independently
537
 
538
                ilen(ix+7 downto ix)     <= txd;
539
 
540
            elsif( state=S_TAG ) then
541
 
542
                iis_vlan  <= '1';
543
                vlan_ctl(ix+7 downto ix) <= txd;
544
 
545
            end if;
546
 
547
            if( state=S_TYPELEN ) then
548
 
549
                iis_stack_vlan <= '0' ;
550
 
551
            elsif (last_state=S_LEN and state=S_TAG) then
552
 
553
                iis_stack_vlan <= '1' ;
554
 
555
            end if ;
556
 
557
            -- verify length at end of frame for normal frames (length 46... max and not a type)
558
 
559
            if( (last_state=S_CRC) and (state=S_IDLE) and iis_pause='0' and
560
                ( (iis_vlan='0' and (ilen > 45)) or
561
                  (iis_vlan='1' and (ilen > 41))) ) then
562
 
563
                        -- verify integrity of length field 
564
 
565
                        if( tx_dv='1' or                                 -- state machine did not expect more
566
                            (iis_vlan='1' and (ilen /= (poscnt-22))) or
567
                            (iis_vlan='0' and (ilen /= (poscnt-18))) ) then
568
 
569
                                len_err <= '1';
570
 
571
                        else
572
 
573
                                len_err <= '0';
574
 
575
                        end if;
576
 
577
            end if;
578
 
579
      end if;
580
   end process;
581
 
582
 
583
    -- ----------------------------------------------
584
    -- Extract Pause frame indication,
585
    --               opcode error,
586
    --               destination address error,
587
    --               and Pause Quanta
588
    -- ----------------------------------------------
589
    process( tx_clk, reset )
590
 
591
        variable ix: integer;
592
 
593
    begin
594
      if( reset = '1' ) then
595
 
596
            pquant       <= (others => '0');
597
            iis_pause     <= '0';
598
            pause_op_err <= '0';
599
            pause_dst_err<= '0';
600
 
601
      elsif(tx_clk='1' and tx_clk'event ) then
602
 
603
        if( tx_sof='1' ) then
604
 
605
            iis_pause     <= '0';     -- clear at start of frame
606
            pause_op_err <= '0';
607
            pause_dst_err<= '0';
608
 
609
        end if;
610
 
611
        if( state=S_PAUSE ) then
612
 
613
            iis_pause <= '1';
614
 
615
            if( count>=2 ) then  -- pick octets after opcode
616
 
617
                ix := 8-((count-2)*8);        -- MSB comes first
618
                pquant(ix+7 downto ix) <= txd;
619
 
620
            elsif( ((count=0) and (txd/=X"00")) or       -- verify 00-01 opcode
621
                   ((count=1) and (txd/=X"01")) ) then
622
 
623
                   pause_op_err <= '1';
624
 
625
            end if;
626
 
627
            if( idst /= X"010000c28001" ) then   -- 01-80-c2-00-00-01 is standard !
628
 
629
                   pause_dst_err <= '1';
630
 
631
            end if;
632
 
633
        end if;
634
      end if;
635
    end process;
636
 
637
 
638
 
639
 
640
    -- ----------------------------------------------
641
    -- Monitor State Machine
642
    -- ----------------------------------------------
643
 
644
    process( tx_clk, reset )
645
 
646
        variable hi,lo  : integer;
647
        variable cnttmp : integer range 0 to 65536;
648
        variable i      : integer;
649
        variable flen   : integer;
650
 
651
    begin
652
      if( reset = '1' ) then
653
 
654
            state      <= S_IDLE;
655
            last_state <= S_IDLE;
656
 
657
            count      <= 0;
658
            frame_err  <= '0';   -- state machine abort indicator
659
 
660
      elsif(tx_clk='1' and tx_clk'event ) then
661
 
662
          -- remember last state and increment internal counter
663
 
664
          last_state <= state;
665
 
666
          if(count < 65535) then
667
             cnttmp := count+1;
668
          else
669
             cnttmp := count ;
670
          end if;
671
 
672
 
673
          -- Abort detection: If enable goes low in middle of frame
674
 
675
          if( (state/=S_IDLE) and (state/=S_ABORT) and (state /= S_UTYPE) and tx_dv='0' ) then
676
 
677
              state     <= S_ABORT;
678
 
679
          else
680
 
681
            case state is
682
 
683
            when S_ABORT => if( tx_dv='1' ) then
684
 
685
                                if( last_tx_dv='0' and data_only='1' ) then  -- only 1 clock cycle inbetween
686
                                   if (ENABLE_SHIFT16 = 0) then
687
                                     state <= S_DST;
688
                                   else
689
                                      state <= S_DWORD32ALIGNED;
690
                                   end if;
691
 
692
                                    cnttmp := 1;
693
                                    frame_err  <= '0';
694
 
695
                                else
696
 
697
                                    state <= S_ABORT;    -- wait til tx stops transmission
698
 
699
                                end if;
700
 
701
                            else
702
 
703
                                state <= S_IDLE;
704
 
705
                            end if;
706
 
707
                            frame_err <= '1';
708
 
709
 
710
            when S_IDLE  => if( tx_sof='1' ) then       -- we miss the very first !
711
                                cnttmp      := 1;       -- therefore need to count to 1 immediately
712
                                frame_err  <= '0';
713
 
714
                                if( data_only='1' ) then     -- no preamble checking ?
715
 
716
                                        if (ENABLE_SHIFT16 = 0) then
717
                                    state <= S_DST;
718
                                        else
719
                                           state <= S_DWORD32ALIGNED;
720
                                        end if;
721
 
722
 
723
                                else
724
 
725
                                    state <= S_PRMBL;
726
 
727
                                end if;
728
 
729
                            else
730
 
731
                                cnttmp      := 0;  -- keep it to zero always 
732
 
733
                            end if;
734
 
735
 
736
            when S_PRMBL => if( txd=X"D5" ) then
737
 
738
                                state   <= S_DST;
739
                                cnttmp  := 0;
740
                            end if;
741
 
742
 
743
            when S_DWORD32ALIGNED   =>
744
                            if( count = 1) then
745
                                state  <= S_DST;
746
                                cnttmp := 0;
747
                            end if;
748
 
749
 
750
            when S_DST   => if( count = 5) then
751
 
752
                                state  <= S_SRC;
753
                                cnttmp := 0;
754
                            end if;
755
 
756
 
757
            when S_SRC   => if( count = 5) then
758
 
759
                                state  <= S_TYPELEN;
760
                                cnttmp := 0;
761
                            end if;
762
 
763
 
764
          when S_TYPELEN => if( count/=0 ) then    -- second half of 2-octet field
765
 
766
                                cnttmp := 0;
767
 
768
                                flen := conv_integer('0' & ilen(15 downto 8) & txd );  -- need it NOW
769
 
770
                                if( (jumbo_en='1' and (flen <= 9000)) or (flen <= 1500)) then
771
 
772
                                    -- ok normal user frame. check if data or 0 length
773
 
774
                                    if( flen /= 0 ) then
775
 
776
                                        state <= S_DATA;
777
 
778
                                    else                     -- no data, PAD or finished
779
 
780
                                        if( data_only='1' ) then
781
 
782
                                            state <= S_IDLE; -- Ok, we are done dont expect anything more
783
 
784
                                        else
785
 
786
                                            state <= S_PAD;  -- zero-length frame needs padding
787
 
788
                                        end if;
789
 
790
                                    end if;
791
 
792
                                else -- not normal frame
793
 
794
                                    if( flen = 16#8808# ) then
795
 
796
                                        state <= S_PAUSE;
797
 
798
                                    elsif( flen = 16#8100# ) then
799
 
800
                                        state <= S_TAG;
801
 
802
                                    else
803
 
804
                                        state   <= S_UTYPE; -- S_ABORT;    -- unknown type
805
 
806
                                    end if;
807
                                end if;
808
                            end if;
809
 
810
 
811
            when S_PAUSE => if(   count>=3 ) then -- need to overread opcode
812
 
813
                                state <= S_PAD;
814
                                cnttmp := 0;
815
 
816
                            end if;
817
 
818
 
819
            when S_TAG  =>  if( count>=1 ) then
820
 
821
                                state <= S_LEN;
822
                                cnttmp := 0;
823
 
824
                            end if;
825
 
826
 
827
            when S_LEN  =>  if( count >= 1) then   -- Length after VLAN TAG
828
 
829
                                cnttmp := 0;
830
 
831
                                flen := conv_integer('0' & ilen(15 downto 8) & txd );  -- need it NOW
832
 
833
                                if ( flen = 16#8100# ) then
834
 
835
                                        state <= S_TAG;
836
 
837
                                --elsif( flen /= 0 ) then
838
                                    --( (jumbo_en='1' and (flen > 9000)) or (jumbo_en='0' and (flen > 1500)) ) ) then
839
 
840
                                    --state <= S_UTYPE;
841
 
842
                                elsif( flen /= 0 ) then
843
 
844
                                    state <= S_DATA;
845
 
846
                                else                     -- no data, PAD or finished
847
 
848
                                    if( data_only='1' ) then
849
 
850
                                        state <= S_IDLE; -- Ok, we are done dont expect CRC
851
 
852
                                    else
853
 
854
                                        state <= S_PAD;
855
 
856
                                    end if;
857
                                end if;
858
                            end if;
859
 
860
 
861
            when S_DATA  => if( count >= (conv_integer(ilen)-1)) then
862
 
863
                                cnttmp := 0;
864
 
865
                                if( data_only='1' ) then      -- no PAD and no CRC ?
866
 
867
                                    state <= S_IDLE;
868
 
869
                                elsif( poscnt < 60-1 ) then   -- expect padding ?
870
 
871
                                    state <= S_PAD;
872
 
873
                                else
874
 
875
                                    state <= S_CRC;
876
 
877
                                end if;
878
                             end if;
879
 
880
 
881
             when S_PAD    => if( poscnt >= (60-1) ) then
882
 
883
                                  state <= S_CRC;
884
                                  cnttmp := 0;
885
 
886
                              end if;
887
 
888
 
889
             when S_CRC    => if( count >= 3 ) then
890
 
891
                                  state <= S_IDLE;
892
                                  cnttmp := 0;
893
 
894
                              end if;
895
 
896
             when S_UTYPE  => if( tx_dv='0' ) then   -- unknown type... wait for end of frame
897
 
898
                                  state <= S_IDLE;
899
                                  cnttmp := 0;
900
 
901
                              end if;
902
 
903
             end case;
904
 
905
           end if;  -- abort                    
906
 
907
 
908
           -- load the counter with the new value                   
909
 
910
           count <= cnttmp;
911
 
912
 
913
      end if;
914
   end process;
915
 
916
end behave;
917
 
918
 

powered by: WebSVN 2.1.0

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