View difference between Paste ID: TSXEUPiQ and 1MykgQ0D
SHOW: | | - or go back to the newest paste.
1
`timescale 1ns/1ps
2
module packet_sender(
3
                     input             clk,
4
                     input             reset,
5
                     //input [7:0]       packet_size_i,
6
		     input             start,
7
                     //input [23:0]      bytes,
8
                     //input             en,
9
                     //input             HSYNC,
10
                     //input             VSYNC,
11
                     //input [10:0]      HCOUNT,
12
                     //input [10:0]      VCOUNT,
13
                     //output reg        fifo_full,
14
                     output reg [3:0]  wr_flags_o,
15
	             output reg [31:0] wr_data_o,
16
	             output reg        wr_src_rdy_o,
17
	             input             wr_dst_rdy_i
18
                     //    output reg [1300*8-1:0] rtp_pkt //made as output for monitoring purpose.
19
                     // Remove when synthesizing the core
20
                     );
21
  
22
23
  
24
25
  //states
26
  //states
27
28
  localparam [26:0]
29
    IDLE       = 2**0,
30
    CALC_IP_HDR1_CHKSUM    = 2**1,
31
    CALC_IP_HDR2_CHKSUM    = 2**2,
32
    CALC_IP_HDR3_CHKSUM    = 2**3,
33
    CALC_IP_HDR4_CHKSUM    = 2**4,
34
    CALC_IP_HDR5_CHKSUM    = 2**5,
35
    SOP                    = 2**6,
36
    TRANSMIT_HDR2           = 2**7,
37
    TRANSMIT_HDR3           = 2**8,
38
    TRANSMIT_HDR4           = 2**9,
39
    TRANSMIT_HDR5           = 2**10,
40
    TRANSMIT_HDR6           = 2**11, 
41
    TRANSMIT_HDR7           = 2**12,
42
    TRANSMIT_HDR8           = 2**13,
43
    TRANSMIT_HDR9           = 2**14,
44
    TRANSMIT_HDR10          = 2**15,
45
    TRANSMIT_HDR11          = 2**16,
46
    SEND_RTP_HDR1           = 2**17,
47
    SEND_RTP_HDR2           = 2**18,
48
    SEND_RTP_HDR3           = 2**19,
49
    SEND_RTP_HDR4           = 2**20,
50
    SEND_RTP_HDR5           = 2**21,
51
    SEND_RTP1               = 2**22,
52
    SEND_RTP2               = 2**23,
53
    SEND_RTP3               = 2**24,
54
    SEND_RTP4               = 2**25,
55
    CLEANUP                 = 2**26;
56
  
57
  
58
59
  
60
  reg [26:0]                           state, nxt_state;
61
   
62
  reg [15:0]                           pixel_cnt, pkt_cnt, line_cnt, frame_cnt,
63
                                       line_no, seqn, pkt_offset;
64
  reg [31:0]                           timest;
65
  reg [15:0]                           nxt_pixel_cnt, nxt_pkt_cnt, nxt_line_cnt, nxt_frame_cnt,
66
                                       nxt_line_no, nxt_seqn, nxt_pkt_offset;
67
  reg [31:0]                           nxt_timest;
68
  reg                                  nxt_fifo_full;
69
70
  reg [13:0]                           packet_size_count, nxt_packet_size_count;
71
72
  reg                                  nxt_wr_src_rdy_o;
73
  reg [3:0]                            nxt_wr_flags_o;
74
  reg [31:0]                           nxt_wr_data_o;
75
  
76
  
77
  //reg              sof, nxt_sof;
78
79
80
  reg [10:0]                           hcount, vcount, nxt_hcount, nxt_vcount;
81
  
82
  //temporary variables. DELETE THEM LATER
83
  reg                                  en;
84
  //reg              VSYNC;  
85
  //reg              fifo_full;           
86
87
88
  localparam IP_IDENTIFICATION = 16'haabb;
89
  localparam IP_FRAG = 13'd0;
90
91
  parameter SRC_PORT = 16'h1234;
92
  parameter DST_PORT = 16'h1234;
93
  parameter SRC_MAC = 48'h0018_3e01_53d5;
94
  parameter DST_MAC = 48'h782b_cb87_cc67;  //ubuntu mac
95
  parameter DST_IP = 32'hc0a8_0101;  //192.168.1.1
96
  parameter SRC_IP = 32'hc0a8_0102;  //192.168.1.2
97
  
98
  // Generate valid IP header checksums
99
  wire [15:0]                          header_checksum;
100
  reg [31:0]                           header_checksum_input;
101
  reg                                  header_checksum_reset, nxt_header_checksum_reset;
102
  
103
  ip_header_checksum ip_header_checksum (
104
                                         .clk(clk),
105
                                         .checksum(header_checksum),
106
                                         .header(header_checksum_input),
107
                                         .reset(header_checksum_reset)
108
                                         );
109
  
110
  
111
  // Calculate packet lengths
112
  wire [15:0] packet_length_udp1, packet_length_ip1, packet_length_rtp1;
113
  wire [15:0] packet_length_udp2, packet_length_ip2, packet_length_rtp2;
114
  
115
  // assign packet_length_rtp1 = 16'd1292 ;  //1272+20 byte header = 1292 bytes
116
  // assign packet_length_udp1 = 16'd1300 ; // 1292 +  8 byte udp hdr
117
  // assign packet_length_ip1  = 16'd1320 ; // IP header adds 20 bytes to UDP packet
118
119
  // assign packet_length_rtp2 = 16'd1316 ;  //1296+20 = 1316 bytes
120
  // assign packet_length_udp2 = 16'd1324 ; // 1316 +  8 byte hdr
121
  //  assign packet_length_ip2  = 16'd1344 ; // 1324 + 20 IP header adds 20 bytes to UDP packet
122
  
123
  assign packet_length_rtp1 = {3'b000, 8'b0010_1000, 5'b01100}; //rtp payload +  20 byte hdr = 1272 + 20 = 1292
124
  assign packet_length_udp1 = {3'b000, 8'b0010_1000, 5'b10100}; //rtp + udp hdr = 1300
125
  assign packet_length_ip1  = {3'b000, 8'b0010_1001, 5'b01000}; //rtp + udp hdr + ip hdr = 1320
126
  
127
  //
128
   assign packet_length_rtp2 = {3'b000, 8'b0010_1001, 5'b00100}; //rtp payload +  20 byte hdr = 1296+20 = 1316
129
   assign packet_length_udp2 = {3'b000, 8'b0010_1001, 5'b01100}; //rtp + udp hdr = 1316 + 8 = 1324 
130
   assign packet_length_ip2  = {3'b000, 8'b0010_1010, 5'b00000}; //rtp + udp hdr + ip hdr = 1320  = 1324 + 20 = 1344 
131
  
132
  
133
  //ip packet header (20 bytes)
134
  wire [31:0]                          header_1, header_2, header_3, header_4, header_5; //broken into 5 (4 bytes)
135
  
136
  //assign header_1 = {16'h4500, packet_length_ip};  //{version,ihl}, ip packet length including ip header
137
  assign header_2 = {IP_IDENTIFICATION[15:0], 3'b000, IP_FRAG[12:0]}; // IP identification, fragment;
138
  assign header_3 = {16'h4011, 16'h0000}; // TTL, protocol=17 for udp, header checksum
139
  assign header_4 = SRC_IP;
140
  assign header_5 = DST_IP;
141
  
142
 
143
  reg [24:0]                           pixel_mem [1279:0];
144
  
145
  
146
  initial // Read the memory contents from the file simple_rgb.txt in pixel_mem memory
147
    begin
148
      $readmemb("simple_rgb.txt", pixel_mem);
149
      $display("Pixel memory read successfully\n");
150
    end
151
152
  
153
  //Sequential logic
154
  always @(posedge clk)
155
    if(reset)
156
      begin
157
        state         <= #1 IDLE;
158
        pixel_cnt     <= #1 0;
159
        pkt_cnt       <= #1 0;
160
        line_cnt      <= #1 0;
161
        frame_cnt     <= #1 0;
162
        //fifo_full     <= #1 0;
163
        pkt_offset    <= #1 0;
164
        line_no       <= #1 26;
165
        seqn          <= #1 0;
166
        timest        <= #1 32'h0;
167
        wr_data_o     <= #1 0;
168
        wr_flags_o    <= #1 0;
169
        wr_src_rdy_o  <= #1 0;
170
        //sof           <= #1 0;
171
        hcount        <= #1 0;
172
        vcount        <= #1 0;
173
        header_checksum_reset <= #1 1;
174
	packet_size_count    <= #1 0;
175
     
176
      end // if (reset)
177
  
178
    else
179
      begin
180
        state         <= #1 nxt_state;
181
        pixel_cnt     <= #1 nxt_pixel_cnt;
182
        pkt_cnt       <= #1 nxt_pkt_cnt;
183
        line_cnt      <= #1 nxt_line_cnt;
184
        frame_cnt     <= #1 nxt_frame_cnt;
185
        //fifo_full     <= #1 nxt_fifo_full;
186
        pkt_offset    <= #1 nxt_pkt_offset;
187
        line_no       <= #1 nxt_line_no;
188
        seqn          <= #1 nxt_seqn;
189
        timest        <= #1 nxt_timest;
190
        wr_data_o     <= #1 nxt_wr_data_o;
191
        wr_src_rdy_o  <= #1 nxt_wr_src_rdy_o;
192
        wr_flags_o    <= #1 nxt_wr_flags_o;
193
        //  sof           <= #1 nxt_sof;
194
        hcount        <= #1 nxt_hcount;
195
        vcount        <= #1 nxt_vcount;
196
        header_checksum_reset <= #1 nxt_header_checksum_reset; //unassert reset
197
        packet_size_count <= #1 nxt_packet_size_count;
198
      end // else: !if(reset)
199
  
200
201
  //combinational logic
202
203
  always @*
204
    begin
205
      //assign defaults
206
      nxt_state        = state;
207
      nxt_pixel_cnt    = pixel_cnt;
208
      nxt_pkt_cnt      = pkt_cnt;
209
      nxt_line_cnt     = line_cnt;
210
      nxt_frame_cnt    = frame_cnt;
211
      //nxt_fifo_full    = fifo_full;
212
      nxt_pkt_offset   = pkt_offset;
213
      nxt_line_no      = line_no;
214
      nxt_seqn         = seqn;
215
      nxt_timest       = timest;
216
      nxt_wr_src_rdy_o   = wr_src_rdy_o;
217
      nxt_wr_flags_o     = wr_flags_o;
218
      nxt_wr_data_o      = wr_data_o;
219
      //nxt_sof            = sof;
220
      nxt_hcount         = hcount;
221
      nxt_vcount         = vcount;
222
      nxt_header_checksum_reset = header_checksum_reset;
223
      nxt_packet_size_count = packet_size_count;
224
      case(state)
225
        IDLE:
226
          begin
227
            //      nxt_fifo_full = 1'b0;
228
            
229
            //Start of traffic (should see a HSYNC transition)
230
            /* -----\/----- EXCLUDED -----\/-----
231
             if(HSYNC & ~VSYNC)  //or VCOUNT == 1
232
             nxt_sof = 1;
233
             
234
             if(en && sof)
235
             nxt_state = MAKE_PKT;
236
             -----/\----- EXCLUDED -----/\----- */
237
            en = 1; //pixel_mem[hcount][24];
238
            //VSYNC = 0;  //temporary
239
            nxt_packet_size_count = 0;
240
            
241-
            if(start) 
241+
            if(seqn < 3) 
242
	      begin
243
                nxt_state = CALC_IP_HDR1_CHKSUM;
244
		nxt_header_checksum_reset = 0; //unassert reset
245
                
246
	      end
247
          end
248
249
        
250
        CALC_IP_HDR1_CHKSUM:
251
          begin
252
            if(pkt_cnt !=2 )
253
               header_checksum_input = {16'h4500, packet_length_ip1};
254
                  else
255
             header_checksum_input = {16'h4500, packet_length_ip2};
256
             
257
            nxt_state = CALC_IP_HDR2_CHKSUM;
258
          end
259
260
        CALC_IP_HDR2_CHKSUM:
261
          begin
262
            header_checksum_input = header_2;
263
            nxt_state = CALC_IP_HDR3_CHKSUM;
264
          end
265
        
266
        CALC_IP_HDR3_CHKSUM:
267
          begin
268
            header_checksum_input = header_3;
269
            nxt_state = CALC_IP_HDR4_CHKSUM;
270
          end
271
        
272
        CALC_IP_HDR4_CHKSUM:
273
          begin
274
            header_checksum_input = header_4;
275
            nxt_state = CALC_IP_HDR5_CHKSUM;
276
          end
277
        
278
        CALC_IP_HDR5_CHKSUM:
279
          begin
280
            header_checksum_input = header_5;
281
            nxt_state = SOP;
282
          end
283
        
284
        SOP:
285
          begin
286
            start_pkt();  //start of Ethernet frame
287
            transmit_header(DST_MAC[47:16]); //start with 32 bits of dst_mac address
288
            nxt_state = TRANSMIT_HDR2;
289
          end
290
291
        TRANSMIT_HDR2:
292
          begin
293
            transmit_header({DST_MAC[15:0], SRC_MAC[47:32]}); 
294
	    clear_mac_flags();
295
            nxt_state = TRANSMIT_HDR3;
296
          end
297
        
298
        TRANSMIT_HDR3:
299
          begin
300
            transmit_header(SRC_MAC[31:0]);
301
            nxt_state = TRANSMIT_HDR4;
302
          end
303
304
        TRANSMIT_HDR4:
305
          begin
306
            transmit_header({16'h0800, 16'h4500}); // First 8 bits: hwtype ethernet (4), protocol type ipv4 (1),  header length (1) (*4), dsc (2)
307
            nxt_state = TRANSMIT_HDR5;
308
          end
309
310
        TRANSMIT_HDR5:
311
          begin
312
            if(pkt_cnt != 2)
313
	      transmit_header({packet_length_ip1, header_2[31:16]});
314
            else
315
	      transmit_header({packet_length_ip2, header_2[31:16]});
316
            nxt_state = TRANSMIT_HDR6;
317
          end
318
319
        TRANSMIT_HDR6:
320
          begin
321
            transmit_header({header_2[15:0], header_3[31:16]});
322
            nxt_state = TRANSMIT_HDR7;
323
          end
324
325
        TRANSMIT_HDR7:
326
          begin
327
            transmit_header({header_checksum, header_4[31:16]}); // Inject the calculated header checksum here
328
            nxt_state = TRANSMIT_HDR8;
329
          end
330
331
        TRANSMIT_HDR8:
332
          begin
333
            transmit_header({header_4[15:0], header_5[31:16]});
334
            nxt_state = TRANSMIT_HDR9;
335
          end
336
337
        TRANSMIT_HDR9:
338
          begin
339
            transmit_header({header_5[15:0], SRC_PORT});
340
            nxt_state = TRANSMIT_HDR10;
341
          end
342
        
343
        TRANSMIT_HDR10:
344
          begin
345
            if(pkt_cnt !=2)
346
	      transmit_header({DST_PORT, packet_length_udp1});
347
            else
348
	      transmit_header({DST_PORT, packet_length_udp2});
349
            nxt_state = TRANSMIT_HDR11;
350
          end
351
        
352
        TRANSMIT_HDR11:
353
          begin
354
            if(line_cnt != 719)
355
              transmit_header({32'h0000,8'h80,1'b0,7'd24}); // {UDP checksum (4), start of RTP header's 2 bytes}
356
            else
357
              transmit_header({32'h0000,8'h80,1'b1,7'd24}); //  1'b1 marks the end of frame
358
              
359
            nxt_state = SEND_RTP_HDR1;
360
          end
361
        
362
        SEND_RTP_HDR1:
363
          begin
364
            if (wr_dst_rdy_i) 
365
              begin
366
                nxt_wr_data_o = {seqn,timest[31:16]};
367
                nxt_state = SEND_RTP_HDR2;
368
              end
369
          end
370
        
371
        SEND_RTP_HDR2:
372
          begin
373
            if (wr_dst_rdy_i) 
374
              begin
375
                nxt_wr_data_o = {timest[15:0],16'd0}; //{timstamp,ssrc[31:16]}
376
                nxt_state = SEND_RTP_HDR3;
377
              end
378
          end
379
        
380
        
381
        SEND_RTP_HDR3:
382
          begin
383
            if (wr_dst_rdy_i) 
384
              begin
385
                nxt_wr_data_o = {16'd0,16'd0}; //{ssrc[15:0],length[31:16]}
386
                nxt_state = SEND_RTP_HDR4;
387
              end
388
          end
389
390
        
391
        SEND_RTP_HDR4:
392
          begin
393
            if (wr_dst_rdy_i) 
394
              begin
395
                if(pkt_cnt != 2)
396
		  nxt_wr_data_o = {16'd1272,line_no[15:0]}; //{length[15:0],line_no}
397
                else
398
		  nxt_wr_data_o = {16'd1296,line_no[15:0]};
399
                nxt_state = SEND_RTP_HDR5;
400
              end
401
          end
402
        
403
        SEND_RTP_HDR5:
404
          begin
405
            if(wr_dst_rdy_i)
406
              begin
407
                //nxt_wr_data_o = {pkt_offset,pixel_mem[hcount][23:8]}; //{offset,pixel}
408
                nxt_wr_data_o = {pkt_offset,16'hFF00}; //{offset,pixel}
409
                nxt_state = SEND_RTP1;
410
              end
411
          end
412
413
        SEND_RTP1:
414
          begin
415
            if (wr_dst_rdy_i) 
416
              begin
417
                //nxt_wr_data_o = {pixel_mem[hcount][7:0],pixel_mem[hcount+1][23:0]};
418
                nxt_wr_data_o = {8'h00,24'hFF_00_00};
419
                nxt_packet_size_count = packet_size_count + 1'b1;
420
	        if ( (pkt_cnt != 2 && packet_size_count == {5'b0, 8'b0010_1000, 3'b100}) ||
421
		     (pkt_cnt == 2 && packet_size_count == {5'b0, 8'b0010_1001, 3'b100}) )
422
		  begin
423
		    nxt_wr_flags_o = 4'b0010; // 4 bytes, EOF	
424
		    nxt_state = CLEANUP;
425
		  end
426
		else
427
		  nxt_state = SEND_RTP2;
428
              end
429
          end
430
        
431
        SEND_RTP2:
432
          begin
433
            if (wr_dst_rdy_i) 
434
              begin
435
                //nxt_wr_data_o = {pixel_mem[hcount+2][23:0],pixel_mem[hcount+3][23:16]};
436
                nxt_wr_data_o = {24'hFF_00_00,8'hFF};
437
                nxt_packet_size_count = packet_size_count + 1'b1;
438
	        if ( (pkt_cnt != 2 && packet_size_count == {5'b0, 8'b0010_1000, 3'b100})||
439
		     (pkt_cnt == 2 && packet_size_count == {5'b0, 8'b0010_1001, 3'b100}) )
440
		  begin
441
		    nxt_wr_flags_o = 4'b0010; // 4 bytes, EOF	
442
		    nxt_state = CLEANUP;
443
		  end
444
                else
445
		  nxt_state = SEND_RTP3;
446
              end
447
          end
448
        
449
        SEND_RTP3:
450
          begin
451
            if (wr_dst_rdy_i) 
452
              begin
453
                //nxt_wr_data_o = {pixel_mem[hcount+3][15:0],pixel_mem[hcount+4][23:8]};
454
                nxt_wr_data_o = {16'h00_00,16'hFF_00};
455
		nxt_packet_size_count = packet_size_count + 1'b1;
456
		if ( (pkt_cnt != 2 && packet_size_count == {5'b0, 8'b0010_1000, 3'b100})||
457
		     (pkt_cnt == 2 && packet_size_count == {5'b0, 8'b0010_1001, 3'b100}) )
458
		  begin
459
		    nxt_wr_flags_o = 4'b0010; // 4 bytes, EOF	
460
		    nxt_state = CLEANUP;
461
		  end
462
		else
463
                  nxt_state = SEND_RTP4;
464
              end 
465
          end // case: SEND_RTP3
466
        
467
        
468
        SEND_RTP4:
469
          begin
470
            if (wr_dst_rdy_i) 
471
              begin
472
                //nxt_wr_data_o = {pixel_mem[hcount+4][7:0],pixel_mem[hcount+5][23:0]};
473
                nxt_wr_data_o = {8'h00,24'hFF_00_00};
474
                nxt_pixel_cnt = pixel_cnt + 6;
475
                nxt_hcount    = hcount + 4;  //adjusted from 6 to 4
476
                nxt_packet_size_count = packet_size_count + 1'b1;
477
	        
478
                if ((pkt_cnt != 2 && packet_size_count == {5'b0, 8'b0010_1000, 3'b100} )||
479
		    (pkt_cnt == 2 && packet_size_count == {5'b0, 8'b0010_1001, 3'b100}) )
480
		  begin
481
		    nxt_wr_flags_o = 4'b0010; // 4 bytes, EOF	
482
		    nxt_state = CLEANUP;
483
		  end
484
                else
485
		  nxt_state = SEND_RTP2;
486
                
487
              end // if (wr_dst_rdy_i)
488
            
489
          end // case: SEND_RTP4
490
        
491
        
492
        CLEANUP:
493
          begin
494
            if (wr_dst_rdy_i) // Wait until we're sure the last word has been received.
495
              begin
496
		nxt_wr_src_rdy_o = 0;
497
		//nxt_wr_flags_o = 0;
498
               	nxt_header_checksum_reset = 1;
499
		
500
		if(  pkt_cnt != 2 )
501
		  begin
502
		    nxt_pkt_cnt = pkt_cnt +1;
503
		    nxt_pkt_offset = pkt_offset + 16'd1272;  //next packet's offset is 1281 from current
504
		  end
505
                else if  (pkt_cnt == 2)
506
		  begin
507
		    nxt_line_cnt    = line_cnt + 1;    //move to next line
508
		    nxt_line_no     = line_no + 1;     //line number is 26 + 1
509
		    nxt_pkt_offset  = 0;               // reset offset to 0
510
		    nxt_pkt_cnt     = 0;
511
		    nxt_hcount      = 0;               //reset hcount
512
		  end 
513
		
514
                if(line_cnt == 719)
515
                  begin
516
                    nxt_frame_cnt = nxt_frame_cnt + 1;
517
                    nxt_line_cnt = 0;
518
                    nxt_line_no = 26;
519
                    nxt_timest = nxt_timest + 1;
520
                  end
521
                
522
                
523
                nxt_seqn = seqn + 1;
524
                nxt_pixel_cnt = 0;
525
		nxt_state = IDLE ;
526
              end // if (wr_dst_rdy_i)
527
          end // case: CLEANUP
528
        
529
        
530
        
531
      endcase // case (state)
532
      
533
    end // always @ *
534
  
535
  
536
  task start_pkt;
537
    begin
538
      nxt_wr_src_rdy_o = 1;	
539
      nxt_wr_flags_o = 4'b0001; // Start of packet
540
    end
541
542
  endtask 
543
  
544
545
  task transmit_header;
546
    input [31:0] header;
547
    begin
548
      if (wr_dst_rdy_i)
549
       	nxt_wr_data_o = header;
550
    end
551
    
552
  endtask
553
  
554
  task clear_mac_flags;
555
    begin
556
      nxt_wr_flags_o = 4'b0000;
557
    end
558
  endtask
559
  
560
  
561
  
562
endmodule // packetizer