欢迎来到羊村

pcap.sv

上一篇 / 下一篇  2017-11-23 17:10:37 / 个人分类:FPGA_Verilog

把数据保存成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


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar