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

1.设计读取逻辑

 `timescale 1ns / 1ps
`define NULL // Coder: joe
// Description:
// 将pcap文件中的数据包读出来,8bit位宽
//
//
//
//
// module PcapParser
#(
parameter pcap_filename = "none",
parameter ipg =
) (
input CLOCK,
input pause,
output reg available = ,
output reg datavalid = ,
output reg [:] data = ,
output reg [:] pktcount = ,
output reg newpkt = ,
output reg pcapfinished =
); // buffers for message
reg [:] global_header [:];
reg [:] packet_header [:]; integer swapped = ;
integer toNanos = ;
integer file = ;
integer r = ;
integer eof = ;
integer i = ;
integer pktSz = ;
integer diskSz = ;
integer countIPG = ; initial begin // open pcap file
if (pcap_filename == "none") begin
$display("pcap filename parameter not set");
$finish_and_return();
end file = $fopen(pcap_filename, "rb");
if (file == `NULL) begin
$display("can't read pcap input");
$finish_and_return();
end // read binary global_header
// r = $fread(file, global_header);
r = $fread(global_header,file); // check magic signature to determine byte ordering
if (global_header[] == 'hD4 && global_header[1] == 8'hC3 && global_header[] == 'hB2) begin
$display(" pcap endian: swapped, ms");
swapped = ;
toNanos = 'd1000000;
end else if (global_header[] == 'hA1 && global_header[1] == 8'hB2 && global_header[] == 'hC3) begin
$display(" pcap endian: native, ms");
swapped = ;
toNanos = 'd1000000;
end else if (global_header[] == 'h4D && global_header[1] == 8'h3C && global_header[] == 'hb2) begin
$display(" pcap endian: swapped, nanos");
swapped = ;
toNanos = 'd1;
end else if (global_header[] == 'hA1 && global_header[1] == 8'hB2 && global_header[] == 'h3c) begin
$display(" pcap endian: native, nanos");
swapped = ;
toNanos = 'd1;
end else begin
$display(" pcap endian: unrecognised format %02x%02x%02x%02x", global_header[], global_header[], global_header[], global_header[] );
$finish_and_return();
end
end always @(posedge CLOCK)
begin
if (eof == && diskSz == && countIPG == ) begin
// read packet header
// fields of interest are U32 so bear in mind the byte ordering when assembling
// multibyte fields
r = $fread(packet_header, file);
eof = $feof(file); if ( eof == ) begin
if (swapped == ) begin
pktSz = {packet_header[],packet_header[],packet_header[] ,packet_header[] };
diskSz = {packet_header[],packet_header[],packet_header[],packet_header[]};
end else begin
pktSz = {packet_header[ ],packet_header[ ],packet_header[],packet_header[]};
diskSz = {packet_header[],packet_header[],packet_header[],packet_header[]};
end $display(" packet %0d: incl_length %0d orig_length %0d eof %0d", pktcount, pktSz, diskSz, eof ); available <= ;
newpkt <= ;
pktcount <= pktcount + ;
countIPG <= ipg; // reload interpacket gap counter
end
end else if ( diskSz > ) begin // packet content is byte-aligned, no swapping required
if (~pause) begin
newpkt <= ;
diskSz <= diskSz - ;
data <= $fgetc(file);
eof = $feof(file);
if ( eof != || diskSz == ) begin
available <= ;
end else begin
datavalid <= ;
end
end else begin
datavalid <= ;
end
end else if (countIPG > ) begin
countIPG <= countIPG - ;
end else if (eof != ) begin
pcapfinished <= ; // terminal loop here
end end endmodule

2.编写testbench文件

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

 `timescale 1ns / 1ps
`define NULL // Coder: joe
// Description:
// 测试文件,读取数据,打入模块
//
//
//
//
// module PcapParser_test
#(
parameter DATA_WIDTH = ,
parameter CTRL_WIDTH=,
parameter STAGE_NUMBER = ,
parameter NUM_QUEUES =
); // Inputs
reg CLOCK = ;
reg paused = ;
reg rst=;
wire available;
wire [:] pktcount;
wire streamvalid;
wire [:] stream;
wire pcapfinished;
wire newpkt; wire out_wr;
wire [CTRL_WIDTH-:] out_ctl;
wire [DATA_WIDTH-:] out_data; wire out_wr1;
wire [CTRL_WIDTH-:] out_ctl1;
wire [DATA_WIDTH-:] out_data1; // Instantiate the Unit Under Test (UUT)
PcapParser #(
.pcap_filename( "tcp-4846-connect-disconnect.pcap" )
) pcap (
.CLOCK(CLOCK),
.pause(paused),
.available(available),
.datavalid(streamvalid),
.data(stream),
.pktcount(pktcount),
.newpkt(newpkt),
.pcapfinished(pcapfinished)
); always # CLOCK = ~CLOCK; //always #100 paused = ~paused; integer i; initial begin $dumpfile("pcap.lxt");
//$dumpvars(0); // Initialize Inputs
$display("Reading from pcap"); // Wait 100 ns for global reset to finish
#;
rst = ; // Add stimulus here
while (~pcapfinished ) begin
//$display("stream: %8d %x %d %x %x %c", i, paused, pktcount, streamvalid, stream, stream);
#
i = i+;
end $finish; end endmodule

3.读取仿真激励结果

verilog 计算机网络 仿真 激励 pcap-LMLPHP

verilog 计算机网络 仿真 激励 pcap-LMLPHP

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

qsy

2018-7-5 11:39:44

05-11 22:50