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

Subversion Repositories gbiteth

[/] [gbiteth/] [trunk/] [rtl/] [rgmii/] [rgmii_tx_wbm.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 axuan25268
-------------------------------------------------------------------------------
2
-- Title      : 
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : rgmii_tx_wbm.vhd
6
-- Author     : liyi  <alxiuyain@foxmail.com>
7
-- Company    : OE@HUST
8
-- Created    : 2013-05-09
9
-- Last update: 2013-05-26
10
-- Platform   : 
11
-- Standard   : VHDL'93/02
12
-------------------------------------------------------------------------------
13
-- Description: 
14
-------------------------------------------------------------------------------
15
-- Copyright (c) 2013 OE@HUST
16
-------------------------------------------------------------------------------
17
-- Revisions  :
18
-- Date        Version  Author  Description
19
-- 2013-05-09  1.0      liyi    Created
20
-------------------------------------------------------------------------------
21
LIBRARY ieee;
22
USE ieee.std_logic_1164.ALL;
23
USE ieee.numeric_std.ALL;
24
USE work.de2_pkg.ALL;
25
-------------------------------------------------------------------------------
26
ENTITY rgmii_tx_wbm IS
27
  GENERIC (
28
    IN_SIMULATION : BOOLEAN := FALSE);
29
  PORT (
30
    iWbClk : IN STD_LOGIC;
31
    iRst_n : IN STD_LOGIC;
32
 
33
    oWbM2S : OUT wbMasterToSlaveIF_t;
34
    iWbS2M : IN  wbSlaveToMasterIF_t;
35
 
36
    -- synthesis translate_off
37
    oWbM2S_addr : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
38
    oWbM2S_sel  : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
39
    oWbM2S_cyc  : OUT STD_LOGIC;
40
    oWbM2S_stb  : OUT STD_LOGIC;
41
    oWbM2S_we   : OUT STD_LOGIC;
42
    oWbM2S_cti  : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
43
    oWbM2S_bte  : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
44
    iWbS2M_ack  : IN  STD_LOGIC;
45
    iWbS2M_dat  : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
46
    -- synthesis translate_on
47
 
48
    -- tx buf
49
    iTxDone     : IN  STD_LOGIC;        -- act as an interrupt SIGNAL(if used)
50
    oTxDoneClr  : OUT STD_LOGIC;
51
    iTxDoneInfo : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
52
    oTxData     : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
53
    oTxAddr     : OUT UNSIGNED(10 DOWNTO 0);
54
    oTxDataWr   : OUT STD_LOGIC;
55
    oTxInfo     : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
56
    oTxInfoWr   : BUFFER STD_LOGIC;
57
 
58
    --wb
59
    iWbTxEnable  : IN  STD_LOGIC;
60
    oWbTxInt     : OUT STD_LOGIC;
61
    iWbTxIntClr  : IN  STD_LOGIC;
62
    iWbTxIntEn   : IN  STD_LOGIC;
63
    iWbTxAddr    : IN  STD_LOGIC_VECTOR(8 DOWNTO 2);
64
    iWbTxWE      : IN  STD_LOGIC;
65
    iWbTxData    : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
66
    oWbTxData    : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
67
    oWbTxIntInfo : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
68
 
69
    iCheckSumIPGen   : IN STD_LOGIC;
70
    iCheckSumTCPGen  : IN STD_LOGIC;
71
    iCheckSumUDPGen  : IN STD_LOGIC;
72
    iCheckSumICMPGen : IN STD_LOGIC
73
    );
74
 
75
END ENTITY rgmii_tx_wbm;
76
-------------------------------------------------------------------------------
77
ARCHITECTURE rtl OF rgmii_tx_wbm IS
78
 
79
  SIGNAL rDescWE   : STD_LOGIC;
80
  SIGNAL rDescAddr : UNSIGNED(6 DOWNTO 0);
81
  SIGNAL cDescDI   : STD_LOGIC_VECTOR(31 DOWNTO 0);
82
  SIGNAL rDescDO   : STD_LOGIC_VECTOR(31 DOWNTO 0);
83
 
84
  -- the length OF current frame descriptor
85
  SIGNAL rFrameLen     : UNSIGNED(15 DOWNTO 0):=(OTHERS => '0');
86
  SIGNAL rDescriptorLen : STD_LOGIC_VECTOR(15 DOWNTO 0);-- 当前descriptor的长度
87
  SIGNAL rStartTran    : BOOLEAN;
88
  SIGNAL rTransDone    : BOOLEAN;
89
  SIGNAL rCheckSumDone : BOOLEAN;
90
 
91
  SIGNAL cWbAck   : STD_LOGIC;
92
  SIGNAL rWbAck : STD_LOGIC;
93
  SIGNAL rLastOne : BOOLEAN;
94
  SIGNAL cWbData : STD_LOGIC_VECTOR(31 DOWNTO 0);
95
 
96
  -- 当前descriptor里面,从wishbone总线读取的32bit宽度数据中,
97
  -- 第一个和最后一个,有效字节数各为多少(大端模式)
98
  SIGNAL rFirstNibbleBytes : NATURAL RANGE 1 TO 4;
99
  SIGNAL rLastNibbleBytes  : NATURAL RANGE 1 TO 4;
100
  -- 一个以太网帧可能占用多个descriptor,例如帧的头和载荷在不同的物理区域,
101
  -- 那么下面一个信号表示这是当前帧的最后一个descriptor
102
  SIGNAL rLastDescriptor   : STD_LOGIC;
103
 
104
  -- the data read from outer buf to be send
105
  SIGNAL rDMADat  : STD_LOGIC_VECTOR(31 DOWNTO 0);
106
  SIGNAL rDMADatV : STD_LOGIC;
107
 
108
  -- 当前帧的最后一个wishbone读取
109
  SIGNAL rRellyLastOne  : BOOLEAN;
110
BEGIN  -- ARCHITECTURE rtl
111
 
112
  -- synthesis translate_off
113
  gen0 : IF IN_SIMULATION GENERATE
114
    cWbAck <= iWbS2M_ack;
115
    cWbData <= iWbS2M_dat;
116
  END GENERATE gen0;
117
  -- synthesis translate_on
118
  gen1 : IF NOT IN_SIMULATION GENERATE
119
    cWbAck <= iWbS2M.ack;
120
    cWbData <= iWbS2M.dat;
121
  END GENERATE gen1;
122
 
123
  PROCESS (iWbClk) IS
124
  BEGIN
125
    IF rising_edge(iWbClk) THEN
126
      rWbAck <= cWbAck;
127
    END IF;
128
  END PROCESS;
129
 
130
  csGen : BLOCK IS
131
    SIGNAL rTxAddr : UNSIGNED(10 DOWNTO 0);
132
    TYPE state_t IS (IDLE, TYPE_LEN, TAGED, STACK_TAG,IP4_PAYLOAD,
133
                     --ICMP, TCP, UDP,
134
                     IP4_HEAD, WAIT_FINISH, CS1, CS2, DONE, DONE2);
135
    SIGNAL rState        : state_t;
136
    SIGNAL rAddrRecord   : UNSIGNED(10 DOWNTO 0);
137
    SIGNAL rCheckSum     : UNSIGNED(31 DOWNTO 0);
138
    SIGNAL cCheckSum     : UNSIGNED(15 DOWNTO 0);
139
    SIGNAL rCheckSum2    : UNSIGNED(31 DOWNTO 0);
140
    SIGNAL cCheckSum2    : UNSIGNED(15 DOWNTO 0);
141
    SIGNAL rWordCnt      : UNSIGNED(13 DOWNTO 0):=(OTHERS => '0');
142
    SIGNAL rIPHeadLen    : UNSIGNED(3 DOWNTO 0);  -- IN 32bit
143
    SIGNAL rIPTotalLen   : UNSIGNED(15 DOWNTO 0);
144
    SIGNAL rProtocol     : STD_LOGIC_VECTOR(7 DOWNTO 0);
145
    SIGNAL cIPPayloadLen : UNSIGNED(15 DOWNTO 0);
146
    SIGNAL rCS1Addr      : UNSIGNED(10 DOWNTO 0);
147
    SIGNAL rCS2Addr      : UNSIGNED(10 DOWNTO 0);
148
    SIGNAL rCS1DatBak    : STD_LOGIC_VECTOR(15 DOWNTO 0);
149
    SIGNAL rCS2DatBak    : STD_LOGIC_VECTOR(15 DOWNTO 0);
150
    SIGNAL rDMADatVD1 : STD_LOGIC;
151
  BEGIN  -- BLOCK csGen
152
    cIPPayloadLen <= rIPTotalLen - to_integer(rIPHeadLen&B"00");
153
    cCheckSum     <= NOT (rCheckSum(31 DOWNTO 16)+rCheckSum(15 DOWNTO 0));
154
    cCheckSum2    <= NOT (rCheckSum2(31 DOWNTO 16)+rCheckSum2(15 DOWNTO 0));
155
    oTxAddr       <= rTxAddr;           -- BUFFER address
156
 
157
    PROCESS (iWbClk) IS
158
    BEGIN
159
      IF rising_edge(iWbClk) THEN
160
        rDMADatVD1 <= rDMADatV;
161
      END IF;
162
    END PROCESS;
163
 
164
    PROCESS (iWbClk, iRst_n) IS
165
      -- VARIABLE vTemp17 : UNSIGNED(16 DOWNTO 0);
166
      VARIABLE vTemp17 : NATURAL RANGE 0 TO 131071;
167
    BEGIN
168
      IF iRst_n = '0' THEN
169
        rTxAddr       <= (OTHERS => '0');
170
        rAddrRecord   <= (OTHERS => '0');
171
        rState        <= IDLE;
172
        rWordCnt      <= (OTHERS => '0');
173
        rCheckSumDone <= FALSE;
174
        rIPHeadLen    <= (OTHERS => '0');
175
        rIPTotalLen   <= (OTHERS => '0');
176
        rProtocol     <= (OTHERS => '0');
177
        rCheckSum2    <= (OTHERS => '0');
178
        rCS1Addr      <= (OTHERS => '0');
179
        rCS2Addr      <= (OTHERS => '0');
180
        rCS1DatBak    <= (OTHERS => '0');
181
        rCS2DatBak    <= (OTHERS => '0');
182
      ELSIF rising_edge(iWbClk) THEN
183
        rCheckSumDone <= FALSE;
184
        oTxDataWr     <= rDMADatV;
185
        oTxData       <= rDMADat;
186
        IF rDMADatVD1 = '1' THEN
187
          rTxAddr <= rTxAddr + 1;
188
        END IF;
189
        IF rDMADatV = '1' THEN
190
          rWordCnt <= rWordCnt + 1;
191
        END IF;
192
        IF rRellyLastOne THEN
193
          rAddrRecord <= rTxAddr + 2;
194
          rWordCnt <= (OTHERS => '0');
195
        END IF;
196
        --IF rRellyLastOne THEN
197
        --  rCheckSumDone <= TRUE;
198
        --END IF;
199
        CASE rState IS
200
          WHEN IDLE =>
201
            --rWordCnt   <= (OTHERS => '0');
202
            rCheckSum  <= (OTHERS => '0');
203
            rCheckSum2 <= (OTHERS => '0');
204
            --IF rStartTran THEN
205
            --  rState <= MAC;
206
            --END IF;
207
            IF rWordCnt(1 DOWNTO 0) = B"10" AND rDMADatV = '1' THEN
208
              rState <= TYPE_LEN;
209
            END IF;
210
          ---------------------------------------------------------------------
211
          --WHEN MAC =>
212
          --  IF rWordCnt(1 DOWNTO 0) = B"10" AND rDMADatV = '1' THEN
213
          --    rState <= TYPE_LEN;
214
          --  END IF;
215
          --  IF rRellyLastOne THEN          -- this should nerver happen
216
          --    rCheckSumDone <= TRUE;
217
          --    rState        <= IDLE;
218
          --  END IF;
219
          ---------------------------------------------------------------------
220
          WHEN TYPE_LEN =>
221
            IF rDMADatV = '1' THEN
222
              rState <= DONE;
223
              CASE rDMADat(31 DOWNTO 16) IS
224
                WHEN X"0800" =>         -- IPv4
225
                  rCheckSum            <= rCheckSum + UNSIGNED(rDMADat(15 DOWNTO 0));
226
                  rIPHeadLen           <= UNSIGNED(rDMADat(11 DOWNTO 8));
227
                  rWordCnt(3 DOWNTO 0) <= X"1";
228
                  rState               <= IP4_HEAD;
229
                WHEN X"8100" =>         -- taged,4 bytes
230
                  rState <= TAGED;
231
                WHEN X"88A8" | X"9100" =>      -- stack taged,8 bytes
232
                  rState <= STACK_TAG;
233
                WHEN OTHERS => NULL;
234
              END CASE;
235
            END IF;
236
            IF rRellyLastOne THEN          -- this should nerver happen
237
              rCheckSumDone <= TRUE;
238
              rState        <= IDLE;
239
            END IF;
240
          ---------------------------------------------------------------------
241
          WHEN TAGED =>
242
            IF rDMADatV = '1' THEN
243
              IF rDMADat(31 DOWNTO 16) = X"0800" THEN
244
                rCheckSum            <= rCheckSum + UNSIGNED(rDMADat(15 DOWNTO 0));
245
                rIPHeadLen           <= UNSIGNED(rDMADat(11 DOWNTO 8));
246
                rWordCnt(3 DOWNTO 0) <= X"1";
247
                rState               <= IP4_HEAD;
248
              ELSE
249
                rState <= DONE;
250
              END IF;
251
            END IF;
252
            IF rRellyLastOne THEN          -- this should nerver happen
253
              rCheckSumDone <= TRUE;
254
              rState        <= IDLE;
255
            END IF;
256
          ---------------------------------------------------------------------
257
          WHEN STACK_TAG =>
258
            IF rDMADatV = '1' THEN
259
              rState <= TAGED;
260
            END IF;
261
            IF rRellyLastOne THEN          -- this should nerver happen
262
              rCheckSumDone <= TRUE;
263
              rState        <= IDLE;
264
            END IF;
265
          ---------------------------------------------------------------------
266
          WHEN IP4_HEAD =>
267
            -- rCheckSum2 here used FOR pesudo head sum
268
            IF rDMADatV = '1' THEN
269
              CASE rWordCnt(3 DOWNTO 0) IS
270
                -- 16位的总长度+16位的标识
271
                WHEN X"1" =>            -- byte 3,4,5,6
272
                  rIPTotalLen <= UNSIGNED(rDMADat(31 DOWNTO 16));
273
                  vTemp17     := to_integer(UNSIGNED(rDMADat(31 DOWNTO 16)))+
274
                                 to_integer(UNSIGNED(rDMADat(15 DOWNTO 0)));
275
                  rCheckSum <= rCheckSum + vTemp17;
276
                -- 3bit标志+13bit片偏移量  + 8bit TTL + 8 bit Protocol
277
                WHEN X"2" =>            -- byte 7,8,9,10
278
                  vTemp17 := to_integer(UNSIGNED(rDMADat(31 DOWNTO 16)))+
279
                             to_integer(UNSIGNED(rDMADat(15 DOWNTO 0)));
280
                  rCheckSum  <= rCheckSum + vTemp17;
281
                  rCheckSum2 <= X"0000"&cIPPayloadLen +
282
                                to_integer((UNSIGNED(rDMADat(7 DOWNTO 0))));
283
                  rProtocol <= rDMADat(7 DOWNTO 0);
284
                -- 16bit 校验和+源IP地址的高16bit
285
                WHEN X"3" =>            -- byte 11,12,13,14
286
                  -- checksum assumed TO be zero
287
                  -- add the higher two bytes OF Source IP Address
288
                  rCheckSum  <= rCheckSum + UNSIGNED(rDMADat(15 DOWNTO 0));
289
                  rCheckSum2 <= rCheckSum2 + UNSIGNED(rDMADat(15 DOWNTO 0));
290
                  rCS1DatBak <= rDMADat(15 DOWNTO 0);
291
                  -- 记录下相对地址,一会儿checksum计算完成后要写入
292
                  IF rDMADatVD1 = '1' THEN
293
                    rCS1Addr <= rTxAddr + 1;
294
                  ELSE
295
                    rCS1Addr <= rTxAddr;
296
                  END IF;
297
                -- 源IP地址低16bit + 目的IP地址高16bit
298
                WHEN X"4" =>            -- byte 15,16,17,18
299
                  vTemp17 := to_integer(UNSIGNED(rDMADat(31 DOWNTO 16)))+
300
                             to_integer(UNSIGNED(rDMADat(15 DOWNTO 0)));
301
                  rCheckSum  <= rCheckSum + vTemp17;
302
                  rCheckSum2 <= rCheckSum2 + vTemp17;
303
                -- 目的IP地址低16bit + 选项(或数据) 16bit
304
                WHEN X"5" =>
305
                  -- rCheckSum2 表示的伪头在这里就计算结束了
306
                  rCheckSum2 <= rCheckSum2 + UNSIGNED(rDMADat(31 DOWNTO 16));
307
                  -- 但是对于IP头的校验和,还要继续计算选项部分
308
                  vTemp17 := to_integer(UNSIGNED(rDMADat(31 DOWNTO 16)))+
309
                             to_integer(UNSIGNED(rDMADat(15 DOWNTO 0)));
310
                  rCheckSum  <= rCheckSum + vTemp17;
311
                WHEN OTHERS =>
312
                  vTemp17 := to_integer(UNSIGNED(rDMADat(31 DOWNTO 16)))+
313
                             to_integer(UNSIGNED(rDMADat(15 DOWNTO 0)));
314
                  rCheckSum  <= rCheckSum + vTemp17;
315
              END CASE;
316
 
317
              IF rIPHeadLen = rWordCnt(3 DOWNTO 0) THEN  -- ip head finished
318
                rCheckSum <= rCheckSum + UNSIGNED(rDMADat(31 DOWNTO 16));
319
                rWordCnt  <= (OTHERS => '0');
320
                rState    <= WAIT_FINISH;
321
                IF cIPPayloadLen /= X"0000" THEN
322
                  CASE rProtocol IS
323
                    WHEN X"01" =>       -- icmp
324
                      rCheckSum2 <= X"0000"&UNSIGNED(rDMADat(15 DOWNTO 0));
325
                      rState <= IP4_PAYLOAD;
326
                    WHEN X"06" | X"11" =>       -- tcp
327
                      IF rIPHeadLen = X"5" THEN  -- 没有IP头选项部分
328
                        vTemp17 := to_integer(UNSIGNED(rDMADat(31 DOWNTO 16)))+
329
                                   to_integer(UNSIGNED(rDMADat(15 DOWNTO 0)));
330
                        rCheckSum2 <= rCheckSum2 + vTemp17;
331
                      ELSE
332
                        rCheckSum2 <= rCheckSum2 + UNSIGNED(rDMADat(15 DOWNTO 0));
333
                      END IF;
334
                      rState <= IP4_PAYLOAD;
335
                    WHEN OTHERS => NULL;
336
                  END CASE;
337
                END IF;
338
              END IF;
339
 
340
            END IF;
341
            IF rRellyLastOne THEN          -- this should nerver happen
342
              rCheckSumDone <= TRUE;
343
              rState        <= IDLE;
344
            END IF;
345
          ---------------------------------------------------------------------
346
          WHEN IP4_PAYLOAD =>
347
            IF rDMADatV = '1' THEN
348
              -- 最后一个32位数据,但是,4字节不都是有效的,但是已经保证其它的无效
349
              -- 的数据为0了,因此,跟平常一样加起来也无所谓
350
              vTemp17 := to_integer(UNSIGNED(rDMADat(31 DOWNTO 16)))+
351
                         to_integer(UNSIGNED(rDMADat(15 DOWNTO 0)));
352
              rCheckSum2 <= rCheckSum2 + vTemp17;
353
              CASE rProtocol IS
354
                WHEN X"01" =>           -- icmp
355
                  IF rWordCnt = X"000"&B"00" THEN
356
                    rCS2DatBak <= rDMADat(15 DOWNTO 0);
357
                    rCheckSum2 <= rCheckSum2 + UNSIGNED(rDMADat(15 DOWNTO 0));
358
                    IF rDMADatVD1 = '1' THEN
359
                      rCS2Addr <= rTxAddr + 1;
360
                    ELSE
361
                      rCS2Addr <= rTxAddr;
362
                    END IF;
363
                  END IF;
364
                ---------------------------------------------------------------
365
                WHEN X"06" =>           -- tcp
366
                  IF rWordCnt = X"000"&B"11" THEN
367
                    rCS2DatBak <= rDMADat(31 DOWNTO 16);
368
                    rCheckSum2 <= rCheckSum2 + UNSIGNED(rDMADat(31 DOWNTO 16));
369
                    IF rDMADatVD1 = '1' THEN
370
                      rCS2Addr <= rTxAddr + 1;
371
                    ELSE
372
                      rCS2Addr <= rTxAddr;
373
                    END IF;
374
                  END IF;
375
                ---------------------------------------------------------------
376
                WHEN X"11" =>           -- udp
377
                  IF rWordCnt = X"000"&B"01" THEN
378
                    rCS2DatBak <= rDMADat(15 DOWNTO 0);
379
                    rCheckSum2 <= rCheckSum2 + UNSIGNED(rDMADat(15 DOWNTO 0));
380
                    IF rDMADatVD1 = '1' THEN
381
                      rCS2Addr <= rTxAddr + 1;
382
                    ELSE
383
                      rCS2Addr <= rTxAddr;
384
                    END IF;
385
                  END IF;
386
                WHEN OTHERS => NULL;
387
              END CASE;
388
            END IF;
389
 
390
            IF rRellyLastOne THEN
391
              rState <= CS2;
392
            END IF;
393
          ---------------------------------------------------------------------
394
          WHEN WAIT_FINISH =>
395
            IF rRellyLastOne THEN
396
              rState <= CS1;
397
            END IF;
398
          ---------------------------------------------------------------------
399
          WHEN CS1 =>                   -- ip checksum
400
            rTxAddr   <= rCS1Addr;
401
            oTxData   <= STD_LOGIC_VECTOR(cCheckSum)&rCS1DatBak;
402
            oTxDataWr <= '1';
403
            rState    <= DONE2;
404
          ---------------------------------------------------------------------
405
          WHEN CS2 =>                   -- tcp udp icmp checksum
406
            IF rProtocol = X"06" THEN   -- tcp
407
              oTxData <= rCS2DatBak&STD_LOGIC_VECTOR(cCheckSum2);
408
            ELSE
409
              oTxData <= STD_LOGIC_VECTOR(cCheckSum2)&rCS2DatBak;
410
            END IF;
411
            rTxAddr     <= rCS2Addr;
412
            oTxDataWr   <= '1';
413
            rState <= CS1;
414
          ---------------------------------------------------------------------
415
          -- 不是ipv4的帧
416
          WHEN DONE =>
417
            IF rRellyLastOne THEN
418
              rCheckSumDone <= TRUE;
419
              rState <= IDLE;
420
            END IF;
421
          ---------------------------------------------------------------------
422
          WHEN DONE2 =>
423
            oTxDataWr     <= '0';
424
            rState        <= IDLE;
425
            rCheckSumDone <= TRUE;
426
            rTxAddr       <= rAddrRecord;
427
          WHEN OTHERS => NULL;
428
        END CASE;
429
      END IF;
430
    END PROCESS;
431
  END BLOCK csGen;
432
 
433
 
434
  -----------------------------------------------------------------------------
435
  -- FOR receive dma descriptors,32x128
436
  -----------------------------------------------------------------------------
437
  blkDescriptor : BLOCK IS
438
    -- Build a 2-D array type for the RAM
439
    SUBTYPE word_t IS STD_LOGIC_VECTOR(31 DOWNTO 0);
440
    TYPE memory_t IS ARRAY(127 DOWNTO 0) OF word_t;
441
    -- Declare the RAM 
442
    SHARED VARIABLE ram : memory_t := (OTHERS => (OTHERS => '0'));
443
  BEGIN  -- BLOCK blkDescriptor
444
    -- Port A,wishbone slave
445
    PROCESS(iWbClk)
446
    BEGIN
447
      IF(rising_edge(iWbClk)) THEN
448
        IF(iWbTxWE = '1') THEN
449
          ram(to_integer(UNSIGNED(iWbTxAddr))) := iWbTxData;
450
        END IF;
451
        oWbTxData <= ram(to_integer(UNSIGNED(iWbTxAddr)));
452
      END IF;
453
    END PROCESS;
454
    -- Port B ,internal use
455
    PROCESS(iWbClk)
456
    BEGIN
457
      IF(rising_edge(iWbClk)) THEN
458
        IF(rDescWE = '1') THEN
459
          ram(to_integer(rDescAddr)) := cDescDI;
460
        END IF;
461
        rDescDO <= ram(to_integer(rDescAddr));
462
      END IF;
463
    END PROCESS;
464
  END BLOCK blkDescriptor;
465
 
466
  -----------------------------------------------------------------------------
467
  -- un-unsed
468
  PROCESS (iWbClk, iRst_n) IS
469
  BEGIN
470
    IF iRst_n = '0' THEN
471
      oTxDoneClr <= '0';
472
    ELSIF rising_edge(iWbClk) THEN
473
      oTxDoneClr <= '0';
474
      IF iTxDone = '1' THEN
475
        oTxDoneClr <= '1';
476
      END IF;
477
    END IF;
478
  END PROCESS;
479
 
480
  blk0 : BLOCK IS
481
    TYPE state_t IS (IDLE, FIND_USEABLE1, WAIT2, TRANS);
482
    SIGNAL rState   : state_t;
483
    SIGNAL cEmpty   : STD_LOGIC;
484
    SIGNAL cFull    : STD_LOGIC;
485
    SIGNAL cIntDesc : STD_LOGIC_VECTOR(5 DOWNTO 0);
486
    SIGNAL rWrReq   : STD_LOGIC;
487
    SIGNAL cRdReq   : STD_LOGIC;
488
    SIGNAL rIntDesc : STD_LOGIC_VECTOR(5 DOWNTO 0);
489
  BEGIN  -- BLOCK blk0
490
    cDescDI              <= (OTHERS => '0');
491
    oTxInfo(31)          <= '0';
492
    oTxInfo(15 DOWNTO 0) <= STD_LOGIC_VECTOR(rFrameLen);
493
 
494
    oWbTxIntInfo(6 DOWNTO 0) <= cIntDesc&'0';
495
    cRdReq                   <= iWbTxIntClr AND NOT cEmpty;
496
    PROCESS (iWbClk) IS
497
    BEGIN
498
      IF rising_edge(iWbClk) THEN
499
        IF iWbTxIntClr = '1' THEN
500
          oWbTxIntInfo(7) <= cEmpty;
501
        END IF;
502
      END IF;
503
    END PROCESS;
504
 
505
    fifo_sc_6x64_1 : ENTITY work.fifo_sc_6x64
506
      PORT MAP (
507
        clock => iWbClk,
508
        data  => rIntDesc,
509
        rdreq => cRdReq,
510
        wrreq => rWrReq,
511
        empty => cEmpty,
512
        full  => cFull,
513
        q     => cIntDesc);
514
 
515
    PROCESS (iWbClk, iRst_n) IS
516
    BEGIN
517
      IF iRst_n = '0' THEN
518
        oWbTxInt <= '0';
519
      ELSIF rising_edge(iWbClk) THEN
520
        IF cEmpty = '0' THEN
521
          oWbTxInt <= iWbTxIntEn;
522
        END IF;
523
        IF cEmpty = '1' OR iWbTxIntClr = '1' THEN
524
          oWbTxInt <= '0';
525
        END IF;
526
      END IF;
527
    END PROCESS;
528
 
529
    PROCESS (iWbClk) IS
530
    BEGIN
531
      IF rising_edge(iWbClk) THEN
532
        rWrReq <= '0';
533
        IF rTransDone THEN
534
        --IF rCheckSumDone THEN
535
          rWrReq   <= iWbTxIntEn;
536
          rIntDesc <= STD_LOGIC_VECTOR(rDescAddr(6 DOWNTO 1));
537
        END IF;
538
      END IF;
539
    END PROCESS;
540
 
541
    PROCESS (iWbClk, iRst_n) IS
542
    BEGIN
543
      IF iRst_n = '0' THEN
544
        rState                <= IDLE;
545
        rDescAddr             <= (OTHERS => '0');
546
        rDescWE               <= '0';
547
        rFrameLen             <= (OTHERS => '0');
548
        rStartTran            <= FALSE;
549
        oTxInfo(30 DOWNTO 16) <= (OTHERS => '0');
550
        oTxInfoWr             <= '0';
551
        rLastDescriptor       <= '0';
552
        rDescriptorLen <= (OTHERS => '0');
553
      ELSIF rising_edge(iWbClk) THEN
554
        rDescWE    <= '0';
555
        rStartTran <= FALSE;
556
        oTxInfoWr  <= '0';
557
        IF oTxInfoWr = '1' THEN
558
          rFrameLen <= (OTHERS => '0');
559
        END IF;
560
        CASE rState IS
561
          WHEN IDLE =>
562
            IF cFull = '0' AND iWbTxEnable = '1' AND
563
              -- NOT too much frames pending...
564
              iTxDoneInfo(31) = '0' THEN
565
              IF rDescDO(16) = '1' AND rDescDO(15 DOWNTO 0) /= X"0000" THEN  -- ready to be send
566
                -- 当前帧的最后一个descriptor了
567
                rLastDescriptor <= rDescDO(17);
568
                -- and theres is plenty room for this frame
569
                IF rDescDO(15 DOWNTO 0) < iTxDoneInfo(15 DOWNTO 0) THEN
570
                  -- then start sending...
571
                  rFrameLen             <= UNSIGNED(rDescDO(15 DOWNTO 0))+rFrameLen;
572
                  rDescriptorLen        <= rDescDO(15 DOWNTO 0);
573
                  rState                <= WAIT2;
574
                  -- start addr in the tx buf
575
                  oTxInfo(30 DOWNTO 16) <= iTxDoneInfo(30 DOWNTO 16);
576
                  --this will give us the location of the current frame
577
                  rDescAddr             <= rDescAddr + 1;
578
                END IF;
579
              ELSE                      -- find NEXT one
580
                rDescAddr <= rDescAddr + 2;
581
                rState    <= FIND_USEABLE1;
582
              END IF;
583
            END IF;
584
          ---------------------------------------------------------------------
585
          WHEN FIND_USEABLE1 =>
586
            rState <= IDLE;
587
          ---------------------------------------------------------------------
588
          --WHEN WAIT1 =>
589
          --  rState    <= WAIT2;
590
          WHEN WAIT2 =>
591
            rStartTran <= TRUE;
592
            rState     <= TRANS;
593
            rDescAddr  <= rDescAddr - 1;
594
            rDescWE    <= '1';
595
          WHEN TRANS =>
596
            -- 如果当前descriptor已经读入完成,并且不是最后一个,那么就不等待
597
            -- checksum计算完成,直接进入下一个descriptor的查找
598
            IF rTransDone AND rLastDescriptor = '0' THEN
599
              rState <= IDLE;
600
            ELSIF rCheckSumDone THEN
601
              rState    <= IDLE;
602
              -- this will info the tx_buf module a valid frame has been
603
              -- successfully writen into the buf,and ready to be send out
604
              oTxInfoWr <= '1';
605
            -- IF we clear now AND jump TO IDLE,the flag IS NOT fully cleared
606
            -- rDescWE   <= '1';move TO the previous state !!!BUG
607
            END IF;
608
          WHEN OTHERS => NULL;
609
        END CASE;
610
      END IF;
611
    END PROCESS;
612
  END BLOCK blk0;
613
 
614
  blk1 : BLOCK IS
615
    SIGNAL rCnt    : UNSIGNED(15 DOWNTO 2);
616
    SIGNAL rCnt64  : UNSIGNED(5 DOWNTO 0);
617
    TYPE state_t IS (IDLE, REFILL, WAIT1, WASTE);
618
    SIGNAL rState  : state_t;
619
    SIGNAL rCycStb : STD_LOGIC;
620
    SIGNAL rWbAddr : UNSIGNED(31 DOWNTO 2);
621
    SIGNAL rWbCti  : STD_LOGIC_VECTOR(2 DOWNTO 0);
622
  BEGIN  -- BLOCK blk1
623
    oWbM2S.bte  <= LINEAR;
624
    oWbM2S.cyc  <= rCycStb;
625
    oWbM2S.stb  <= rCycStb;
626
    oWbM2S.we   <= '0';
627
    oWbM2S.addr <= STD_LOGIC_VECTOR(rWbAddr)&B"00";
628
    oWbM2S.sel  <= X"F";
629
    oWbM2S.cti  <= rWbCti;
630
    -- synthesis translate_off
631
    oWbM2S_bte  <= LINEAR;
632
    oWbM2S_cyc  <= rCycStb;
633
    oWbM2S_stb  <= rCycStb;
634
    oWbM2S_we   <= '0';
635
    oWbM2S_addr <= STD_LOGIC_VECTOR(rWbAddr)&B"00";
636
    oWbM2S_sel  <= X"F";
637
    oWbM2S_cti  <= rWbCti;
638
    -- synthesis translate_on
639
 
640
    PROCESS (iWbClk, iRst_n) IS
641
      VARIABLE vCnt    : UNSIGNED(15 DOWNTO 2);
642
      VARIABLE vTemp16 : UNSIGNED(15 DOWNTO 0);
643
    BEGIN
644
      IF iRst_n = '0' THEN
645
        rTransDone        <= FALSE;
646
        rCnt64            <= (OTHERS => '0');
647
        rCnt              <= (OTHERS => '0');
648
        rState            <= IDLE;
649
        rCycStb           <= '0';
650
        rWbCti            <= CLASSIC;
651
        rWbAddr           <= (OTHERS => '0');
652
        rLastOne          <= FALSE;
653
        rFirstNibbleBytes <= 1;
654
        rLastNibbleBytes  <= 1;
655
      ELSIF rising_edge(iWbClk) THEN
656
        rTransDone <= FALSE;
657
        IF cWbAck = '1' THEN
658
          rWbAddr <= rWbAddr + 1;
659
          rCnt    <= rCnt - 1;
660
          rCnt64  <= rCnt64 - 1;
661
        END IF;
662
        CASE rState IS
663
          WHEN IDLE =>
664
            rWbAddr  <= UNSIGNED(rDescDO(31 DOWNTO 2));
665
 
666
            -- 注意,这里rFirstNibbleBytes直接记录的首次有多少
667
            -- 有效字节数,在大端模式下,rDescDO(1 DOWNTO 0)=B"00"表示
668
            -- 4字节有效,rDescDO(1 DOWNTO 0)=B"10"表示高16bit有效
669
            rFirstNibbleBytes <= 4 - to_integer(UNSIGNED(rDescDO(1 DOWNTO 0)));
670
 
671
            -- descriptors 给出的目标数据的起始地址很可能不是4字节对齐的
672
            vTemp16 := UNSIGNED(rDescriptorLen) - 4 + to_integer(UNSIGNED(rDescDO(1 DOWNTO 0)));
673
            IF vTemp16(1 DOWNTO 0) /= B"00" THEN
674
              vCnt             := vTemp16(15 DOWNTO 2)+1;
675
              -- rLastNibbleBytes给出的是当前descriptor最后一次32位读取中,有效的
676
              -- 字节数
677
              rLastNibbleBytes <= to_integer(vTemp16(1 DOWNTO 0));
678
            ELSE
679
              vCnt             := vTemp16(15 DOWNTO 2);
680
              rLastNibbleBytes <= 4;
681
            END IF;
682
            --IF rFrameLen(1 DOWNTO 0) /= B"00" THEN
683
            --  vCnt := UNSIGNED(rFrameLen(15 DOWNTO 2));
684
            --ELSE
685
            --  vCnt := UNSIGNED(rFrameLen(15 DOWNTO 2)) - 1;
686
            --END IF;
687
            rCnt   <= vCnt;
688
            rCnt64 <= (OTHERS => '1');
689
            IF rStartTran THEN
690
              rLastOne <= FALSE;          -- last in a frame
691
              IF vCnt = 0 THEN
692
                rState   <= WAIT1;
693
                rWbCti   <= CLASSIC;
694
                rLastOne <= TRUE;
695
              ELSE
696
                rState <= REFILL;
697
                rWbCti <= INCR;
698
              END IF;
699
              rCycStb <= '1';
700
            END IF;
701
          ---------------------------------------------------------------------
702
          WHEN REFILL =>
703
            IF cWbAck = '1' THEN
704
              IF rCnt = X"000"&B"01" THEN
705
                rWbCti   <= LAST;
706
                rState   <= WAIT1;
707
                rLastOne <= TRUE;
708
              ELSIF rCnt64 = 1 THEN
709
                rWbCti <= LAST;
710
                rState <= WASTE;
711
              END IF;
712
            END IF;
713
          ---------------------------------------------------------------------
714
          WHEN WAIT1 =>
715
            IF cWbAck = '1' THEN
716
              rState     <= IDLE;
717
              rCycStb    <= '0';
718
              rTransDone <= TRUE;
719
            END IF;
720
          ---------------------------------------------------------------------
721
          WHEN WASTE =>
722
            rCnt64 <= rCnt64 + 1;
723
            IF rCnt64 = 16 THEN
724
              rCycStb <= '1';
725
              IF rCnt = 0 THEN
726
                rState   <= WAIT1;
727
                rWbCti   <= CLASSIC;
728
                rLastOne <= TRUE;
729
              ELSE
730
                rState <= REFILL;
731
                rWbCti <= INCR;
732
              END IF;
733
            END IF;
734
            IF cWbAck = '1' THEN
735
              rCycStb <= '0';
736
            END IF;
737
          WHEN OTHERS => NULL;
738
        END CASE;
739
      END IF;
740
    END PROCESS;
741
  END BLOCK blk1;
742
 
743
  blkDataMix : BLOCK IS
744
    TYPE state_t IS (ST1, ST2);
745
    SIGNAL rState         : state_t;
746
 
747
    -- 当前wishbone读取的,有效字节数
748
    SIGNAL rValidBytes    : NATURAL RANGE 1 TO 4;
749
    TYPE array8x8_t IS ARRAY (8 DOWNTO 1) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
750
    SIGNAL rArray8x8_2      : array8x8_t;
751
    SIGNAL rArray8x8_1      : array8x8_t;  -- 实际上只使用了4 DOWNTO 1
752
    SIGNAL rReveivedBytes : NATURAL RANGE 0 TO 8;
753
    SIGNAL rStateLittle   : BOOLEAN;
754
    SIGNAL rLastOneD1 : BOOLEAN;
755
  BEGIN  -- BLOCK blkDataMix
756
 
757
    PROCESS (iWbClk, iRst_n) IS
758
    BEGIN
759
      IF iRst_n = '0' THEN
760
        rState <= ST1;
761
      ELSIF rising_edge(iWbClk) THEN
762
        CASE rState IS
763
          -- 这是每一个descriptor的第一个读取的32位数,当然,不一定全部有效
764
          -- rFirstNibbleBytes 会告诉我们到底有几个字节有效
765
          WHEN ST1 =>
766
            IF cWbAck = '1' THEN
767
              rValidBytes <= rFirstNibbleBytes;
768
              rArray8x8_1(1) <= cWbData(7 DOWNTO 0);
769
              rArray8x8_1(2) <= cWbData(15 DOWNTO 8);
770
              rArray8x8_1(3) <= cWbData(23 DOWNTO 16);
771
              rArray8x8_1(4) <= cWbData(31 DOWNTO 24);
772
              -- 当前descriptor只需要读一次
773
              IF rLastOne THEN          -- 在大端下,
774
                NULL;
775
                --rArray8x8_1(1) <= cWbData(7 DOWNTO 0);
776
                --rArray8x8_1(2) <= cWbData(15 DOWNTO 8);
777
                --rArray8x8_1(3) <= cWbData(23 DOWNTO 16);
778
                --rArray8x8_1(4) <= cWbData(31 DOWNTO 24);
779
              ELSE
780
                rState <= ST2;
781
                --rArray8x8_1(1) <= cWbData(7 DOWNTO 0);
782
                --rArray8x8_1(2) <= cWbData(15 DOWNTO 8);
783
                --rArray8x8_1(3) <= cWbData(23 DOWNTO 16);
784
                --rArray8x8_1(4) <= cWbData(31 DOWNTO 24);
785
              END IF;
786
            END IF;
787
          ---------------------------------------------------------------------
788
          WHEN ST2 =>
789
            IF cWbAck = '1' THEN
790
              IF rLastOne THEN
791
                rValidBytes <= rLastNibbleBytes;
792
                rState      <= ST1;
793
                -- 大端下,残留的最后一个是靠齐。。。
794
                CASE rLastNibbleBytes IS
795
                  WHEN 1 =>
796
                    rArray8x8_1(1) <= cWbData(31 DOWNTO 24);
797
                  WHEN 2 =>
798
                    rArray8x8_1(2) <= cWbData(31 DOWNTO 24);
799
                    rArray8x8_1(1) <= cWbData(23 DOWNTO 16);
800
                  WHEN 3 =>
801
                    rArray8x8_1(3) <= cWbData(31 DOWNTO 24);
802
                    rArray8x8_1(2) <= cWbData(23 DOWNTO 16);
803
                    rArray8x8_1(1) <= cWbData(15 DOWNTO 8);
804
                  WHEN 4 =>
805
                    rArray8x8_1(4) <= cWbData(31 DOWNTO 24);
806
                    rArray8x8_1(3) <= cWbData(23 DOWNTO 16);
807
                    rArray8x8_1(2) <= cWbData(15 DOWNTO 8);
808
                    rArray8x8_1(1) <= cWbData(7 DOWNTO 0);
809
                  WHEN OTHERS => NULL;
810
                END CASE;
811
              ELSE
812
                rValidBytes <= 4;
813
                rArray8x8_1(1) <= cWbData(7 DOWNTO 0);
814
                rArray8x8_1(2) <= cWbData(15 DOWNTO 8);
815
                rArray8x8_1(3) <= cWbData(23 DOWNTO 16);
816
                rArray8x8_1(4) <= cWbData(31 DOWNTO 24);
817
              END IF;
818
            END IF;
819
          ---------------------------------------------------------------------
820
          WHEN OTHERS => NULL;
821
        END CASE;
822
      END IF;
823
    END PROCESS;
824
 
825
    PROCESS (iWbClk) IS
826
    BEGIN
827
      IF rising_edge(iWbClk) THEN
828
        rLastOneD1 <= rLastOne;
829
      END IF;
830
    END PROCESS;
831
 
832
    PROCESS (iWbClk, iRst_n) IS
833
      VARIABLE vReceivedBytes : NATURAL RANGE 1 TO 8;
834
      VARIABLE vArray8x8 : array8x8_t;
835
    BEGIN
836
      IF iRst_n = '0' THEN
837
        rDMADatV       <= '0';
838
        rDMADat        <= (OTHERS => '0');
839
        rReveivedBytes <= 0;
840
        rRellyLastOne  <= FALSE;
841
        rStateLittle   <= FALSE;
842
      ELSIF rising_edge(iWbClk) THEN
843
        rDMADatV      <= '0';
844
        rRellyLastOne <= FALSE;
845
        CASE rStateLittle IS
846
          WHEN FALSE =>
847
            IF rWbAck = '1' THEN
848
              vArray8x8(rValidBytes DOWNTO 1) := rArray8x8_1(rValidBytes DOWNTO 1);
849
              vArray8x8(8 DOWNTO rValidBytes+1) := rArray8x8_2(8-rValidBytes DOWNTO 1);
850
              --rArray8x8_2(rValidBytes DOWNTO 1) <= rArray8x8_1(rValidBytes DOWNTO 1);
851
              --rArray8x8_2(8 DOWNTO rValidBytes+1) <= rArray8x8_2(8-rValidBytes DOWNTO 1);
852
              rArray8x8_2 <= vArray8x8;
853
 
854
              vReceivedBytes := rReveivedBytes + rValidBytes;
855
              IF rLastOneD1 AND rLastDescriptor = '1' THEN
856
                IF vReceivedBytes > 4 THEN
857
                  rDMADatV              <= '1';
858
                  rStateLittle          <= TRUE;
859
                  rReveivedBytes        <= vReceivedBytes - 4;
860
                  rDMADat(31 DOWNTO 24) <= vArray8x8(vReceivedBytes);
861
                  rDMADat(23 DOWNTO 16) <= vArray8x8(vReceivedBytes-1);
862
                  rDMADat(15 DOWNTO 8)  <= vArray8x8(vReceivedBytes-2);
863
                  rDMADat(7 DOWNTO 0)   <= vArray8x8(vReceivedBytes-3);
864
                ELSE
865
                  rDMADatV       <= '1';
866
                  rRellyLastOne  <= TRUE;
867
                  rReveivedBytes <= 0;
868
                  CASE vReceivedBytes IS
869
                    WHEN 1 =>
870
                      rDMADat(31 DOWNTO 24) <= vArray8x8(1);
871
                      rDMADat(23 DOWNTO 0)  <= (OTHERS => '0');
872
                    WHEN 2 =>
873
                      rDMADat(31 DOWNTO 24) <= vArray8x8(2);
874
                      rDMADat(23 DOWNTO 16) <= vArray8x8(1);
875
                      rDMADat(15 DOWNTO 0)  <= (OTHERS => '0');
876
                    WHEN 3 =>
877
                      rDMADat(31 DOWNTO 24) <= vArray8x8(3);
878
                      rDMADat(23 DOWNTO 16) <= vArray8x8(2);
879
                      rDMADat(15 DOWNTO 8)  <= vArray8x8(1);
880
                      rDMADat(7 DOWNTO 0)   <= (OTHERS => '0');
881
                    WHEN 4 =>
882
                      rDMADat(31 DOWNTO 24) <= vArray8x8(4);
883
                      rDMADat(23 DOWNTO 16) <= vArray8x8(3);
884
                      rDMADat(15 DOWNTO 8)  <= vArray8x8(2);
885
                      rDMADat(7 DOWNTO 0)   <= vArray8x8(1);
886
                    WHEN OTHERS => NULL;
887
                  END CASE;
888
                END IF;
889
              ELSE                      -- NOT really last one
890
                IF vReceivedBytes >= 4 THEN
891
                  rDMADatV              <= '1';
892
                  rReveivedBytes        <= vReceivedBytes - 4;
893
                  rDMADat(31 DOWNTO 24) <= vArray8x8(vReceivedBytes);
894
                  rDMADat(23 DOWNTO 16) <= vArray8x8(vReceivedBytes-1);
895
                  rDMADat(15 DOWNTO 8)  <= vArray8x8(vReceivedBytes-2);
896
                  rDMADat(7 DOWNTO 0)   <= vArray8x8(vReceivedBytes-3);
897
                ELSE
898
                  rReveivedBytes <= vReceivedBytes;
899
                END IF;
900
              END IF;
901
            END IF;
902
          ---------------------------------------------------------------------
903
          WHEN TRUE =>
904
            rStateLittle   <= FALSE;
905
            rRellyLastOne  <= TRUE;
906
            rDMADatV       <= '1';
907
            rReveivedBytes <= 0;
908
            CASE rReveivedBytes IS
909
              WHEN 1 =>
910
                rDMADat(31 DOWNTO 24) <= rArray8x8_2(1);
911
                rDMADat(23 DOWNTO 0)  <= (OTHERS => '0');
912
              WHEN 2 =>
913
                rDMADat(31 DOWNTO 24) <= rArray8x8_2(2);
914
                rDMADat(23 DOWNTO 16) <= rArray8x8_2(1);
915
                rDMADat(15 DOWNTO 0)  <= (OTHERS => '0');
916
              WHEN 3 =>
917
                rDMADat(31 DOWNTO 24) <= rArray8x8_2(3);
918
                rDMADat(23 DOWNTO 16) <= rArray8x8_2(2);
919
                rDMADat(15 DOWNTO 8)  <= rArray8x8_2(1);
920
                rDMADat(7 DOWNTO 0)   <= (OTHERS => '0');
921
              -- 应该不会到4这个分支的!!
922
              WHEN 4 =>
923
                rDMADat(31 DOWNTO 24) <= rArray8x8_2(4);
924
                rDMADat(23 DOWNTO 16) <= rArray8x8_2(3);
925
                rDMADat(15 DOWNTO 8)  <= rArray8x8_2(2);
926
                rDMADat(7 DOWNTO 0)   <= rArray8x8_2(1);
927
              WHEN OTHERS => NULL;
928
            END CASE;
929
          ---------------------------------------------------------------------
930
          WHEN OTHERS => NULL;
931
        END CASE;
932
      END IF;
933
    END PROCESS;
934
 
935
  END BLOCK blkDataMix;
936
 
937
END ARCHITECTURE rtl;

powered by: WebSVN 2.1.0

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