把数据保存成pcap格式
//Based on the original work of Jose Fernando Zazo
//https://github.com/jfzazo/pcapFromVerilog
`timescale 1ns / 1ps
module pcap_dumper #(
parameter pcap_filename = "",
parameter c_max_pkt_size = 2048,
parameter c_ns_precision = 1,
parameter CLOCK_FREQ_HZ = 156250000
)(
input wire clk,
input wire rst_n,
input wire [63:0] tdata,
input wire [2:0] tstrb,
input wire tvalid,
input wire tlast
);
reg [7:0] global_header[0:23];
reg [7:0] packet_header[0:15];
reg [7:0] pkt_buffer [0:c_max_pkt_size];
int file = 0;
int r = 0;
int i = 0;
int j ;
int pktSz = 0;
int diskSz = 0;
int timestamp_msb = 0;
int timestamp_lsb = 0;
initial begin
// open pcap file
if (pcap_filename == "") begin
$display("pcap filename parameter not set");
$stop;
end
file = $fopen(pcap_filename, "wb");
if (file == 0) begin
$display("can't open output pcap %s", pcap_filename);
$stop;
end
// Initialize Inputs
$display("PCAP: %m writing to %s", pcap_filename);
// Magic code
global_header[3] = 8'hA1;
global_header[2] = 8'hB2;
if(!c_ns_precision) begin // Precision of microseconds.
global_header[1] = 8'hC3;
global_header[0] = 8'hD4;
end else begin // Precision of nanoseconds.
global_header[1] = 8'h3C;
global_header[0] = 8'h4D;
end
// Version. Major-minor 2.4
global_header[7] = 8'h0;
global_header[6] = 8'h4; // Minor
global_header[5] = 8'h0;
global_header[4] = 8'h2; // Major
// Snaplen
global_header[16] = 8'hff;
global_header[17] = 8'hff;
global_header[18] = 8'hff;
global_header[19] = 8'hff;
// Data link type
global_header[20] = 8'h01;
// Write binary global_header
foreach(global_header[i])
$fwrite(file,"%c",global_header[i]);
end
reg [63:0] real_timestamp ;
real ns_per_cycle = 1.0/CLOCK_FREQ_HZ*1e9;
always_ff @(negedge rst_n or posedge clk) begin
if(~rst_n) begin
pktSz = 0;
diskSz = 0;
real_timestamp = 0;
end else begin
real_timestamp+=ns_per_cycle;
if(tvalid == 1'b1) begin
// for (i=tstrb;i>=0;i--) begin
// pkt_buffer[pktSz++] = tdata[i*8+:8];
// end
for (i=0;i<=tstrb;i++) begin
pkt_buffer[pktSz++] = tdata[i*8+:8];
end
if(tlast == 1'b1) begin
diskSz = pktSz;
timestamp_msb = c_ns_precision ? real_timestamp/1000000000 : timestamp_msb/1000000;
timestamp_lsb = c_ns_precision ? real_timestamp%1000000000 : timestamp_msb%1000000;
{packet_header[3], packet_header[2], packet_header[1], packet_header[0]} = timestamp_msb;
{packet_header[7], packet_header[6], packet_header[5], packet_header[4]} = timestamp_lsb;
{packet_header[11],packet_header[10],packet_header[9] ,packet_header[8] } = diskSz ;
{packet_header[15],packet_header[14],packet_header[13],packet_header[12]} = pktSz ;
foreach(packet_header[i])
$fwrite(file,"%c",packet_header[i]);
for(j=0;j<diskSz;j++) begin
$fwrite(file,"%c",pkt_buffer[j]);
end
pktSz = 0;
end
end
end
end
endmodule