verilog 计算机网络 仿真 激励 pcap

做verilog网络逻辑时,需要产生正确的数据包格式激励,手写激励真烦人,现在让testbench读取pcap文件,则可以精确还原数据包的bit与时序,省去了一大批麻烦

1.设计读取逻辑

  1 `timescale 1ns / 1ps
  2 `define NULL 0
  3 
  4 // Coder:    joe
  5 // Description:
  6 //    将pcap文件中的数据包读出来,8bit位宽
  7 //  
  8 //   
  9 //
 10 //  
 11 //
 12 
 13 module PcapParser
 14     #(
 15         parameter pcap_filename = "none",
 16         parameter ipg = 32
 17     ) (
 18         input CLOCK,
 19         input pause,
 20         output reg available = 0,
 21         output reg datavalid = 0,
 22         output reg [7:0] data = 0,
 23         output reg [7:0] pktcount = 0,
 24         output reg newpkt = 0,
 25         output reg pcapfinished = 0
 26     );
 27         
 28     
 29 
 30     // buffers for message
 31     reg [7:0] global_header [0:23];
 32     reg [7:0] packet_header [0:15];
 33 
 34     integer swapped = 0;
 35     integer toNanos = 0;
 36     integer file = 0;
 37     integer r    = 0;
 38     integer eof  = 0;
 39     integer i    = 0;
 40     integer pktSz  = 0;
 41     integer diskSz = 0;
 42     integer countIPG = 0;
 43 
 44     initial begin
 45         
 46 
 47         // open pcap file
 48         if (pcap_filename == "none") begin
 49             $display("pcap filename parameter not set");
 50             $finish_and_return(1);
 51         end
 52 
 53         file = $fopen(pcap_filename, "rb");
 54         if (file == `NULL) begin
 55             $display("can't read pcap input");
 56             $finish_and_return(1);
 57         end
 58 
 59         // read binary global_header
 60         // r = $fread(file, global_header);
 61         r = $fread(global_header,file);
 62 
 63         // check magic signature to determine byte ordering
 64         if (global_header[0] == 8'hD4 && global_header[1] == 8'hC3 && global_header[2] == 8'hB2) begin
 65             $display(" pcap endian: swapped, ms");
 66             swapped = 1;
 67             toNanos = 32'd1000000;
 68         end else if (global_header[0] == 8'hA1 && global_header[1] == 8'hB2 && global_header[2] == 8'hC3) begin
 69             $display(" pcap endian: native, ms");
 70             swapped = 0;
 71             toNanos = 32'd1000000;
 72         end else if (global_header[0] == 8'h4D && global_header[1] == 8'h3C && global_header[2] == 8'hb2) begin
 73             $display(" pcap endian: swapped, nanos");
 74             swapped = 1;
 75             toNanos = 32'd1;
 76         end else if (global_header[0] == 8'hA1 && global_header[1] == 8'hB2 && global_header[2] == 8'h3c) begin
 77             $display(" pcap endian: native, nanos");
 78             swapped = 0;
 79             toNanos = 32'd1;
 80         end else begin
 81             $display(" pcap endian: unrecognised format %02x%02x%02x%02x", global_header[0], global_header[1], global_header[2], global_header[3] );
 82             $finish_and_return(1);
 83         end
 84     end
 85 
 86     always @(posedge CLOCK)
 87     begin
 88         if (eof == 0 && diskSz == 0 && countIPG == 0) begin
 89             // read packet header
 90             // fields of interest are U32 so bear in mind the byte ordering when assembling
 91             // multibyte fields
 92             r = $fread(packet_header, file);
 93             eof = $feof(file);
 94 
 95             if ( eof == 0) begin
 96                 if (swapped == 1) begin
 97                     pktSz  = {packet_header[11],packet_header[10],packet_header[9] ,packet_header[8] };
 98                     diskSz = {packet_header[15],packet_header[14],packet_header[13],packet_header[12]};
 99                 end else begin
100                     pktSz =  {packet_header[ 8],packet_header[ 9],packet_header[10],packet_header[11]};
101                     diskSz = {packet_header[12],packet_header[13],packet_header[14],packet_header[15]};
102                 end
103 
104                 $display("  packet %0d: incl_length %0d orig_length %0d eof %0d", pktcount, pktSz, diskSz, eof );
105 
106                 available <= 1;
107                 newpkt <= 1;
108                 pktcount <= pktcount + 1;
109                 countIPG <= ipg;    // reload interpacket gap counter
110             end
111         end else if ( diskSz > 0) begin
112 
113             // packet content is byte-aligned, no swapping required
114             if (~pause) begin
115                 newpkt <= 0;
116                 diskSz <= diskSz - 1;
117                 data <= $fgetc(file);
118                 eof = $feof(file);
119                 if ( eof != 0 || diskSz == 1) begin
120                     available <= 0;
121                 end else begin
122                     datavalid <= 1;
123                 end
124             end else begin
125                 datavalid <= 0;
126             end
127         end else if (countIPG > 0) begin
128             countIPG <= countIPG - 1;
129         end else if (eof != 0) begin
130             pcapfinished <= 1;    // terminal loop here
131         end
132 
133 
134     end
135 
136 endmodule

2.编写testbench文件

将 tcp-4846-connect-disconnect.pcap 文件放在工程目录下。自己随意放置一个,然后修改源码中文件的名称,才可以读到。

 1 `timescale 1ns / 1ps
 2 `define NULL 0
 3 
 4 // Coder:    joe
 5 // Description:
 6 //    测试文件,读取数据,打入模块
 7 //  
 8 //   
 9 //
10 //  
11 //
12 
13 module PcapParser_test
14 #(
15         parameter DATA_WIDTH = 480,
16         parameter CTRL_WIDTH=32,
17         parameter STAGE_NUMBER = 2,
18         parameter NUM_QUEUES = 8
19     );
20 
21     // Inputs
22     reg CLOCK = 0;
23     reg paused = 0;
24     reg rst=0;
25     wire available;
26     wire [7:0] pktcount;
27     wire streamvalid;
28     wire [7:0] stream;
29     wire pcapfinished;
30     wire newpkt;
31     
32     wire out_wr;
33     wire [CTRL_WIDTH-1:0] out_ctl;
34     wire [DATA_WIDTH-1:0] out_data;
35     
36     wire out_wr1;
37     wire [CTRL_WIDTH-1:0] out_ctl1;
38     wire [DATA_WIDTH-1:0] out_data1;
39 
40     // Instantiate the Unit Under Test (UUT)
41     PcapParser #(
42         .pcap_filename( "tcp-4846-connect-disconnect.pcap" )
43     ) pcap (
44         .CLOCK(CLOCK),
45         .pause(paused),
46         .available(available),
47         .datavalid(streamvalid),
48         .data(stream),
49         .pktcount(pktcount),
50         .newpkt(newpkt),
51         .pcapfinished(pcapfinished)
52     );
53     
54 
55     always #10 CLOCK = ~CLOCK;
56     
57     //always #100 paused = ~paused;
58 
59     integer i;
60 
61     initial begin
62 
63         $dumpfile("pcap.lxt");
64         //$dumpvars(0);
65 
66         // Initialize Inputs
67         $display("Reading from pcap");
68 
69         // Wait 100 ns for global reset to finish
70         #10; 
71         rst = 1;
72 
73         // Add stimulus here
74         while (~pcapfinished ) begin
75             //$display("stream: %8d %x %d %x %x %c", i, paused, pktcount, streamvalid, stream, stream);
76             #20
77             i = i+1;
78         end
79 
80         $finish;
81 
82     end
83 
84 endmodule

3.读取仿真激励结果

=====================

qsy

2018-7-5 11:39:44

猜你喜欢

转载自www.cnblogs.com/pandaroll/p/9267502.html