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

Subversion Repositories turbo8051

[/] [turbo8051/] [trunk/] [verif/] [agents/] [ethernet/] [tb_eth_pktgn.v] - Blame information for rev 15

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 dinesha
/*-----------------------------------------------------------------
2
|           Ethernet Traffic Generator Testbench                    |
3
|                                                                   |
4
 ------------------------------------------------------------------*/
5
 
6
/*-----------------------------------------------------------------\
7
|  DESCRIPTION:                                                    |
8
|  tb_pktgn.v:  Packet generation tasks                            |
9
|                                                                  |
10
|  Instantiated modules: none                                      |
11
|  Included files: none                                            |
12
\-----------------------------------------------------------------*/
13
 
14
task construct_frame;
15
   integer size;
16
   integer payload_byte;
17
   reg [`MAX_PKT_SIZE*8 -1:0]  packet;
18
   integer i,j;
19
   begin
20
      size = current_pkt_size;
21
      // clear packet
22
      packet = 0;
23
      add_L2_header(packet);
24
      if (flow_type >= 3)
25
       add_L3_header(packet);
26
      if (flow_type >= 5)
27
       add_L4_header(packet);
28
      add_payload(packet);
29
 
30
      transmit_pkt = packet;
31
      transmit_pkt_size= size;
32
   end
33
endtask // construct_frame
34
 
35
task add_L2_header;
36
   inout [`MAX_PKT_SIZE*8 -1:0] packet;
37
   reg [47:0] mac_addr;
38
   reg [15:0] temp;
39
   integer length_field, next_offset, j;
40
   reg [`MAX_HEADER_SIZE*8-1:0] std_LLC_header;
41
 
42
   begin
43
      if (L2_custom_header_enable) // use user-defined header
44
       begin
45
          insert_header(packet, 0, L2_custom_header,
46
                     L2_custom_header_length);
47
          L3_header_position = L2_custom_header_length;
48
          if (flow_type < 3) // Layer-2 flow
49
           payload_position =  L2_custom_header_length;
50
       end // if (L2_custom_header_enable)
51
      else
52
       begin
53
          mac_addr = current_dstn_mac;
54
          //swap bytes in MAC address
55
          // MS byte goes first on the link
56
          packet[ 7: 0] =  mac_addr[47:40];
57
          packet[15: 8] =  mac_addr[39:32];
58
          packet[23:16] =  mac_addr[31:24];
59
          packet[31:24] =  mac_addr[23:16];
60
          packet[39:32] =  mac_addr[15: 8];
61
          packet[47:40] =  mac_addr[ 7: 0];
62
 
63
          mac_addr = current_src_mac;
64
          packet[55:48] =  mac_addr[47:40];
65
          packet[63:56] =  mac_addr[39:32];
66
          packet[71:64] =  mac_addr[31:24];
67
          packet[79:72] =  mac_addr[23:16];
68
          packet[87:80] =  mac_addr[15: 8];
69
          packet[95:88] =  mac_addr[ 7: 0];
70
 
71
          length_field = current_pkt_size - 6*2 - 2 -4; // SA, DA, length, CRC
72
          next_offset = 12;
73
          if ((L2_protocol_type == 1) ||
74
              (L2_protocol_type == 3))   // tagged frame
75
           begin // attach VLAN tag
76
              packet[103:96] = (L2_VLAN_TPID >> 8) & 8'hff;
77
              packet[111:104] = L2_VLAN_TPID & 8'hff;
78
              temp = current_VLAN_TCI;
79
              packet[119:112] = temp[15:8];
80
              packet[127:120] = temp[7:0];
81
              length_field = length_field -4;
82
              next_offset = next_offset +4;
83
           end
84
 
85
      // set type-length field 
86
          if ((L2_protocol_type == 0) ||
87
              (L2_protocol_type == 1))  // Ethernet frame
88
           begin
89
              if (flow_type < 3) // Layer-2 flow
90
               temp[15:0] = L2_type_field;
91
              else
92
               case(L3_protocol_type)
93
                 4: // IP Version 4
94
                  temp = 16'h0800;
95
                 6: // IP version 6
96
                  temp = 16'h08dd;
97
                 8: // TCP/IP ARP
98
                  temp = 16'h0806;
99
                 9: // IPX
100
                  temp = 16'h8137;
101
                 default:
102
                  temp = 16'h0800; // default is IP Version 4
103
               endcase // case(L3_protocol)
104
           end // if ((L2_protocol_type == 0) ||...
105
          else
106
           begin // 802.3 frame
107
              // Allow undersize L2 frames with padding
108
              // by setting length field based on payload length
109
              if ((flow_type <= 2)  // Layer-2 flow
110
                  && (payload_length < length_field))
111
               length_field = payload_length;
112
              temp[15:0] = length_field[15:0];
113
           end // else: !if((L2_protocol_type == 0) ||...
114
 
115
          for (i=0; i<8; i=i+1)
116
           packet[next_offset*8 +i] = temp[8+i];
117
          next_offset = next_offset+1;
118
          for (i=0; i<8; i=i+1)
119
           packet[next_offset*8 +i] = temp[i];
120
          next_offset = next_offset+1;
121
 
122
          // set LLC header for 802.3 frames
123
          if ((L2_protocol_type == 2) ||
124
              (L2_protocol_type == 3))  // 802.3 frame
125
           begin
126
              std_LLC_header[63:48] = 16'haaaa; //DSAP and SSAP
127
              std_LLC_header[47:40] = 8'd3;     // control
128
              std_LLC_header[39:16] = 24'd0;    // org code
129
              // set type field
130
              if (flow_type < 3) // Layer-2 flow
131
               std_LLC_header[15:0] = L2_type_field;
132
              else
133
               case(L3_protocol_type)
134
                 4: // IP Version 4
135
                  std_LLC_header[15:0] = 16'h0800;
136
                 6: // IP version 6
137
                  std_LLC_header[15:0] = 16'h08dd;
138
                 8: // TCP/IP ARP
139
                  std_LLC_header[15:0] = 16'h0806;
140
                 9: // IPX
141
                  std_LLC_header[15:0] = 16'h8137;
142
                 default:
143
                  std_LLC_header[15:0] = 16'h0800; // default is IPv4
144
               endcase // case(L3_protocol)
145
 
146
              if (L2_LLC_header_enable) // use user-defined header
147
               begin
148
                  insert_header(packet, next_offset, L2_LLC_header,
149
                             L2_LLC_header_length);
150
                  next_offset = next_offset + L2_LLC_header_length;
151
               end // if (L2_LLC_header_enable)
152
              else
153
               begin
154
                  insert_header(packet, next_offset, std_LLC_header, 8);
155
                  next_offset = next_offset + 8;
156
               end // else: !if(L2_LLC_header_enable)
157
           end // if ((L2_protocol_type == 2) ||...
158
 
159
          L3_header_position = next_offset;
160
          if (flow_type < 3) // Layer-2 flow
161
           payload_position =  next_offset;
162
       end // else: !if(L2_custom_header_enable)
163
   end
164
endtask // add_L2_header
165
 
166
task add_L3_header;
167
   inout [`MAX_PKT_SIZE*8 -1:0] packet;
168
 
169
   reg [`MAX_HEADER_SIZE*8-1:0] L3_header;
170
   integer length;
171
   reg [31:0] x;
172
 
173
   begin
174
      if (L3_custom_header_enable) // use user-defined header
175
       begin
176
          insert_header(packet, L3_header_position, L3_custom_header,
177
                     L3_custom_header_length);
178
          L4_header_position =  L3_header_position + L3_custom_header_length;
179
          if (flow_type < 5) // Layer-4 flow
180
           payload_position =  L4_header_position;
181
       end // if (L3_custom_header_enable)
182
      else
183
       begin
184
          case (L3_protocol_type)
185
            4: // IP Version 4
186
             begin
187
                L3_header[159:156] = 4'h4;// Version = 4
188
                L3_header[155:152] = 4'd5 + IP_ext_header_length/4;
189
                // size of datagram
190
 
191
                L3_header[151:144] = IP_service_type;// TOS field
192
 
193
                // Determine length of datagram
194
                length = current_pkt_size - L3_header_position -4; // leave 4 bytes for CRC
195
                // check payload length defined by user
196
                if (flow_type >= 5) // Layer-4 flow
197
                 begin
198
                    if (L4_protocol_type == 1) // UDP, header length = 8 bytes
199
                     begin
200
                        if ((payload_length + 20 + IP_ext_header_length + 8)
201
                            < length)
202
                         length = payload_length + 20 + IP_ext_header_length + 8;
203
                     end // if (L4_protocol_type == 1)
204
                    else // TCP, header length = 20 bytes
205
                     begin
206
                        if ((payload_length + 20 + IP_ext_header_length + 20) < length)
207
                         length = payload_length + 20 + IP_ext_header_length + 20;
208
                     end // else: !if(L4_protocol_type == 1)
209
                 end // if (flow_type >= 5)
210
                else // Layer-3 flow
211
                 if ((payload_length + 20 + IP_ext_header_length) < length)
212
                  length = payload_length + 20 + IP_ext_header_length;
213
 
214
                L3_header[143:128] = length[15:0];
215
                L3_header[127:112] = L3_sequence_number[15:0]; //IP sequence number
216
                L3_sequence_number = L3_sequence_number+1;
217
 
218
                L3_header[111:109] = IP_flags[2:0]; // IP flags 
219
                L3_header[108:96] =  IP_fragment_offset[12:0]; // fragment offset
220
 
221
                L3_header[95:88]  = L3_TTL[7:0]; // IP time to live
222
                L3_header[87:80]  = IP_protocol_field[7:0]; // L4 protocol
223
                // If flow is defined as Layer-4 set protocol field
224
                // according to the L4 protocol defined
225
                if (flow_type >= 5) // Layer-4 flow
226
                 case(L4_protocol_type)
227
                   0: // TCP
228
                    L3_header[87:80] = 8'h06;
229
                   1: // UDP
230
                    L3_header[87:80] = 8'h11;
231
                 endcase // case(L4_protocol_type)
232
                L3_header[79:64] = 16'h0; // reset IP checksum
233
                L3_header[63:32] = L3_src_address;
234
                L3_header[31:0] = L3_dstn_address;
235
                // calculate IP checksum
236
                L3_header[79:64] = IP_checksum(L3_header, 20);
237
 
238
                // insert IP header in packet
239
                insert_header(packet, L3_header_position, L3_header, 20);
240
 
241
                // insert IP extension header
242
                if (IP_ext_header_length != 0)
243
                 insert_header(packet, L3_header_position + 20,
244
                               IP_ext_header, IP_ext_header_length);
245
                L4_header_position =  L3_header_position + 20 +
246
                                      IP_ext_header_length;
247
                payload_position =  L4_header_position;
248
             end // case: 4
249
            default:
250
             begin
251
                L4_header_position =  L3_header_position;
252
                payload_position =  L4_header_position;
253
             end // case: default
254
          endcase // case(L3_protocol_type)
255
       end // else: !if(L3_custom_header_enable)
256
   end
257
endtask // add_L3_header
258
 
259
task add_L4_header;
260
   inout [`MAX_PKT_SIZE*8 -1:0] packet;
261
   reg [`MAX_HEADER_SIZE*8-1:0] L4_header;
262
 
263
   integer length;
264
 
265
   begin
266
      if (L4_custom_header_enable) // use user-defined header
267
       begin
268
          insert_header(packet, L4_header_position, L4_custom_header,
269
                     L4_custom_header_length);
270
          payload_position =  L4_header_position + L4_custom_header_length;
271
       end // if (L4_custom_header_enable)
272
      else
273
       begin
274
          case(L4_protocol_type)
275
 
276
            1: begin // UDP, header size = 8 bytes
277
               L4_header[63:48] = L4_src_port;
278
               L4_header[47:32] = L4_dstn_port;
279
 
280
               // Determine length field
281
               length = current_pkt_size - L4_header_position -4; // leave 4 bytes for CRC
282
               // check payload length defined by user
283
               if ((payload_length + 8) < length)
284
                length = payload_length + 8;
285
 
286
               L4_header[31:16] = length[15:0];
287
               L4_header[15:0] =  0; // calculate checksum later after constructing payload
288
 
289
               insert_header(packet, L4_header_position, L4_header, 8);
290
               payload_position =  L4_header_position + 8;
291
            end
292
 
293
            default: begin // TCP, header size = 20 bytes
294
 
295
               L4_header[159:144] = L4_src_port;
296
               L4_header[143:128] = L4_dstn_port;
297
               L4_header[127:96] = L4_sequence_number;
298
               L4_header[95:64] = L4_ack_number;
299
               L4_header[63:60] = 4'd5; // length of header in 32-bit words
300
               L4_header[59:54] = 6'd0; // reserved field
301
               L4_header[53:48] = TCP_flags;
302
               L4_header[47:32] = TCP_window_size;
303
               L4_header[31:16] = 16'd0; // calculate checksum later
304
               L4_header[15:0]  = TCP_urgent_pointer; // calculate checksum later
305
               insert_header(packet, L4_header_position, L4_header, 20);
306
               payload_position =  L4_header_position + 20;
307
 
308
               // update TCP sequence number
309
               length = current_pkt_size - payload_position - 4; // leave 4 bytes for CRC
310
               if (payload_length < length)
311
                length = payload_length;
312
               L4_sequence_number = L4_sequence_number + length;
313
            end // case: default
314
          endcase // case(L4_protocol_type)
315
       end // else: !if(L4_custom_header_enable)
316
   end
317
endtask // add_L4_header
318
 
319
task add_payload;
320
   inout [`MAX_PKT_SIZE*8 -1:0] packet;
321
 
322
   integer length, checksum_position, i, j;
323
   reg [31:0] x;
324
   reg [7:0] payload_byte;
325
   reg [15:0] next_word;
326
   reg [31:0] checksum;
327
 
328
   begin
329
 
330
      length = current_pkt_size - payload_position;
331
      if (flowrec_crc_option != 2'b10)
332
       length = length - 4; // leave 4 bytes for CRC
333
      if (payload_length < length)
334
       length = payload_length;
335
      case(payload_option)
336
        0: begin // increasing sequence of bytes
337
           payload_byte = payload_start;
338
           for (i = payload_position; i < (payload_position+length); i = i+1)
339
            begin
340
               for (j=0; j<8; j=j+1)
341
                packet[i*8 +j] = payload_byte[j];
342
               payload_byte = payload_byte +1;
343
            end // for (i = payload_position; i < (payload_position+length); i = i+1)
344
        end // case: 0
345
 
346
        1: begin // decreasing sequence of bytes
347
           payload_byte = payload_start;
348
           for (i = payload_position; i < (payload_position+length); i = i+1)
349
            begin
350
               for (j=0; j<8; j=j+1)
351
                packet[i*8 +j] = payload_byte[j];
352
               payload_byte = payload_byte -1;
353
            end // for (i = payload_position; i < (payload_position+length); i = i+1)
354
        end // case: 1
355
 
356
        2: begin // random payload
357
           for (i = payload_position; i < (payload_position+length); i = i+1)
358
            begin
359
               x = $random();
360
               for (j=0; j<8; j=j+1)
361
                packet[i*8 +j] = x[j];
362
            end // for (i = payload_position; i < (payload_position+length); i = i+1)
363
        end // case: 2
364
 
365
        3: begin // user-defined payload
366
           for (i=0; i < length; i = i+1)
367
            for (j=0; j < 8; j= j+1)
368
             packet[(payload_position+i)*8 +j] = user_payload[(length-i-1)*8 +j];
369
        end // case: 3
370
      endcase // case(payload_option)
371
 
372
      // for TCP and UDP flows, update L4 checksum
373
      if (flow_type >= 5)
374
       begin
375
          if (L4_protocol_type == 1) // UDP
376
           checksum_position = L4_header_position + 6; // position of checksum in pkt
377
          else // TCP
378
           checksum_position = L4_header_position + 16;
379
 
380
          // determine length of packet, including TCP/UDP header
381
          length = current_pkt_size - payload_position - 4; // leave 4 bytes for CRC
382
          if (payload_length < length)
383
           length = payload_length;
384
          if (L4_protocol_type == 1) // UDP
385
           length = length + 8;
386
          else // TCP
387
           length = length + 20;
388
 
389
          // calculate checksum
390
          checksum[31:0] = 32'd0;
391
          for (i=0; i < length; i = i+2)
392
           begin
393
              next_word[15:8] = 0;
394
              for (j=0; j < 8; j= j+1)
395
               next_word[8+j] = packet[(L4_header_position+i)*8 +j];
396
              // if length is an odd number of bytes, pad last byte with zeroes
397
              next_word[7:0] = 0;
398
              if ((i+1) < length)
399
               for (j=0; j < 8; j= j+1)
400
                next_word[j] = packet[(L4_header_position+i+1)*8 +j];
401
              checksum = checksum + {16'd0, next_word[15:0]};
402
           end // for (i=0; i < length; i = i+2)
403
          // add pseudo header
404
          checksum = checksum +
405
                     {16'd0, L3_src_address[31:16]} +
406
                     {16'd0, L3_src_address[15:0]} +
407
                     {16'd0, L3_dstn_address[31:16]} +
408
                     {16'd0, L3_dstn_address[15:0]};
409
          if (L4_protocol_type == 1) // UDP
410
           checksum = checksum + 32'h00000011   // protocol = 17
411
                                + {16'd0, length[15:0]};
412
                                  // length field from UDP header
413
          else // TCP
414
           checksum = checksum + 32'h00000006   // protocol = 6
415
                      + {16'd0, length[15:0]}; // length of payload + TCP header
416
 
417
          // add "end-around carry"
418
          checksum = checksum + {16'd0, checksum[31:16]};
419
 
420
          if (checksum[15:0] == 16'd0) // complement checksum
421
           checksum[15:0] = 16'hffff;
422
 
423
          case(L4_checksum_option)
424
            0: // calculate good checksum
425
             begin
426
                // nothing to do
427
             end // case: 0
428
 
429
            1: // generate bad checksum
430
             begin
431
                x = $random();
432
                if (x[15:0] == checksum[15:0]) // if we got correct checksum by accident
433
                 x[15] = ~x[15]; //invert MS bit;
434
                checksum[15:0] = x[15:0];
435
             end // case: 1
436
 
437
            2: // set checksum to zero
438
             checksum[15:0] = 16'd0;
439
 
440
            3: // set checksum to user-defined value
441
             checksum[15:0] = L4_user_checksum;
442
          endcase // case(L4_checksum_option)
443
 
444
          // insert checkum in L4 header
445
          for (j=0; j < 8; j= j+1)
446
           packet[checksum_position*8 +j] = checksum[8+j];
447
          for (j=0; j < 8; j= j+1)
448
           packet[(checksum_position +1)*8 +j] = checksum[j];
449
       end // if (flow_type >= 5)
450
   end
451
endtask // add_payload
452
 
453
task insert_header;
454
   inout [`MAX_PKT_SIZE*8 -1:0] packet;
455
   input  offset;
456
   input [`MAX_HEADER_SIZE*8-1:0] header;
457
   input length;
458
   integer offset, length;
459
   integer i,j;
460
  begin
461
     if (length != 0)
462
      for (i=0; i < length; i = i+1)
463
       for (j=0; j < 8; j= j+1)
464
        packet[(offset+i)*8 +j] = header[(length-i-1)*8 +j];
465
  end
466
endtask // insert_header
467
 
468
task construct_pause_frame;
469
   // Constructs an 802.3x PAUSE frame
470
   input [47:0] src_mac;
471
   input [15:0] pause_time;
472
   output [`MAX_PKT_SIZE*8 -1:0]  packet;
473
   output size;
474
   integer i,j, size;
475
 
476
   reg [47:0] mac_addr;
477
   reg [15:0] temp;
478
   begin
479
      size = 64;
480
      // clear packet
481
      packet = 0;
482
      // construct header;
483
      mac_addr = `PAUSE_DEST_MAC;
484
      //swap bytes in MAC address
485
      // MS byte goes first on the link
486
      packet[ 7: 0] =  mac_addr[47:40];
487
      packet[15: 8] =  mac_addr[39:32];
488
      packet[23:16] =  mac_addr[31:24];
489
      packet[31:24] =  mac_addr[23:16];
490
      packet[39:32] =  mac_addr[15: 8];
491
      packet[47:40] =  mac_addr[ 7: 0];
492
 
493
      mac_addr = src_mac;
494
      packet[55:48] =  mac_addr[47:40];
495
      packet[63:56] =  mac_addr[39:32];
496
      packet[71:64] =  mac_addr[31:24];
497
      packet[79:72] =  mac_addr[23:16];
498
      packet[87:80] =  mac_addr[15: 8];
499
      packet[95:88] =  mac_addr[ 7: 0];
500
 
501
      // set type-length field
502
      temp = `PAUSE_TYPE;
503
      packet[103:96] = temp[15:8];
504
      packet[111:104] = temp[7:0];
505
      // set PAUSE opcode
506
      temp = `PAUSE_OPCODE;
507
      packet[119:112] = temp[15:8];
508
      packet[127:120] = temp[7:0];
509
 
510
      // set pause parameter
511
      temp = pause_time;
512
      packet[135:128] = temp[15:8];
513
      packet[143:136] = temp[7:0];
514
   end
515
endtask // construct_pause_frame
516
 
517
function [15:0] IP_checksum;
518
   input [`MAX_PKT_SIZE*8 -1:0] header;
519
   input length;
520
   integer length;
521
   reg [31:0] checksum;
522
   reg [15:0] next_word;
523
   integer i, j;
524
   reg [31:0] x;
525
 
526
   begin
527
      // compute header checksum
528
      checksum[31:0] = 32'd0;
529
      for (i=0; i< length/2; i=i+1)
530
       begin
531
          for (j=0; j<16; j=j+1)
532
           next_word[j] = header[i*16 +j]; // get next 16 bits
533
          checksum = checksum + {16'd0, next_word[15:0]};
534
       end // for (j=0; j<16; j=j+1)
535
 
536
      // include IP extension header, if present
537
      if (IP_ext_header_length != 0)
538
       begin
539
          for (i=0; i< IP_ext_header_length/2; i=i+1)
540
           begin
541
              for (j=0; j<16; j=j+1)
542
               next_word[j] = IP_ext_header[i*16 +j]; // get next 16 bits
543
              checksum = checksum + {16'd0, next_word[15:0]};
544
           end // for (j=0; j<16; j=j+1)
545
       end // if (IP_ext_header_length != 0)
546
 
547
      // add "end-around carry"
548
      checksum = checksum + {16'd0, checksum[31:16]};
549
 
550
      case (L3_checksum_option)
551
        0: // calculate good checksum
552
         begin
553
            IP_checksum = ~checksum[15:0];
554
         end // case: 0
555
 
556
        1: // generate bad checksum
557
         begin
558
            x = $random();
559
            if (x[15:0] == ~checksum[15:0])
560
             // if the checksum is good by accident
561
             x[15:0] = x[15:0] ^ 16'h8000; // complement MS bit
562
            IP_checksum = x[15:0];
563
         end // case: 1
564
 
565
        2: // set checksum to zero
566
         IP_checksum = 16'd0;
567
 
568
        3: // set checksum to user-defined value
569
         IP_checksum = L3_user_checksum;
570
      endcase // case(L3_checksum_option[flow_id])
571
   end
572
endfunction
573
 

powered by: WebSVN 2.1.0

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