fpga: lib: Add chdr_strip_header module
Original-commit: 4bf988aa3c9aa3885dc30e3da7ea67fcec48c97e
This commit is contained in:
@@ -30,4 +30,5 @@ ctrlport_to_settings_bus.v \
|
||||
noc_shell_generic_ctrlport_pyld_chdr.v \
|
||||
timekeeper.v \
|
||||
ctrlport_terminator.v \
|
||||
chdr_strip_header.sv \
|
||||
))
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
//
|
||||
// Copyright 2022 Ettus Research, a National Instruments Brand
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: chdr_strip_header
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Removes the CHDR header depending on the state of strip_en on the first
|
||||
// word of the packet.
|
||||
//
|
||||
|
||||
`default_nettype none
|
||||
|
||||
|
||||
module chdr_strip_header #(
|
||||
parameter CHDR_W = 64,
|
||||
localparam USER_W = 16
|
||||
) (
|
||||
// Clock and reset
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
// Strip enable, sampled when the first word of the packet is transferred
|
||||
input wire strip_en,
|
||||
|
||||
// CHDR input packet
|
||||
input wire [CHDR_W-1:0] s_chdr_tdata,
|
||||
input wire s_chdr_tlast,
|
||||
input wire s_chdr_tvalid,
|
||||
output logic s_chdr_tready,
|
||||
|
||||
// Output packet (with or without header)
|
||||
output logic [CHDR_W-1:0] m_tdata,
|
||||
output logic [USER_W-1:0] m_tuser,
|
||||
output logic m_tlast,
|
||||
output logic m_tvalid,
|
||||
input wire m_tready
|
||||
);
|
||||
|
||||
`include "../core/rfnoc_chdr_utils.vh"
|
||||
|
||||
enum {
|
||||
ST_HDR, // CHDR header
|
||||
ST_STRIP, // Strip header
|
||||
ST_PASS // Pass packet through
|
||||
} state;
|
||||
|
||||
localparam COUNT_W = (CHDR_W == 64) ?
|
||||
6 : // Max count is timestamp + metadata
|
||||
5; // Max count is metadata only (timestamp is in the first word)
|
||||
|
||||
// The number of CHDR words we need to skip to get to the payload, minus one.
|
||||
logic [COUNT_W-1:0] skip_length;
|
||||
// Counter to track where we are in the header.
|
||||
logic [COUNT_W-1:0] skip_count;
|
||||
|
||||
// Total length of the header, including timestamp and metadata, minus 1.
|
||||
logic [COUNT_W-1:0] hdr_length;
|
||||
|
||||
// Register to hold the new packet length, in bytes
|
||||
logic [15:0] packet_length;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// State Machine Registers
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
always_ff @(posedge clk) begin : sm_reg
|
||||
case (state)
|
||||
ST_HDR : begin
|
||||
skip_count <= 1;
|
||||
skip_length <= hdr_length;
|
||||
packet_length <= chdr_get_length(s_chdr_tdata) - (CHDR_W/8);
|
||||
|
||||
if (s_chdr_tvalid && s_chdr_tready) begin
|
||||
if (hdr_length > 0 && strip_en) begin
|
||||
state <= ST_STRIP;
|
||||
end else begin
|
||||
state <= ST_PASS;
|
||||
end
|
||||
end
|
||||
end
|
||||
ST_STRIP : begin
|
||||
if (s_chdr_tvalid && s_chdr_tready) begin
|
||||
packet_length <= packet_length - (CHDR_W/8);
|
||||
skip_count <= skip_count + 1;
|
||||
if (s_chdr_tlast) begin
|
||||
state <= ST_HDR;
|
||||
end else if (skip_count == skip_length) begin
|
||||
state <= ST_PASS;
|
||||
end
|
||||
end
|
||||
end
|
||||
ST_PASS : begin
|
||||
if (s_chdr_tvalid && s_chdr_tready && s_chdr_tlast) begin
|
||||
state <= ST_HDR;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
if (rst) begin
|
||||
state <= ST_HDR;
|
||||
end
|
||||
end : sm_reg
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// State Machine Combinatorial Logic
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
always_comb begin : sm_comb
|
||||
m_tdata = s_chdr_tdata;
|
||||
m_tlast = s_chdr_tlast;
|
||||
|
||||
// Calculate the length of the header, including timestamp and metadata,
|
||||
// minus 1.
|
||||
if (CHDR_W == 64 && chdr_get_pkt_type(s_chdr_tdata) == CHDR_PKT_TYPE_DATA_TS) begin
|
||||
hdr_length = chdr_get_num_mdata(s_chdr_tdata) + 1;
|
||||
end else begin
|
||||
hdr_length = chdr_get_num_mdata(s_chdr_tdata);
|
||||
end
|
||||
|
||||
// Drive m_tvalid and s_chdr_tready
|
||||
case (state)
|
||||
ST_HDR : begin
|
||||
m_tuser = chdr_get_length(s_chdr_tdata);
|
||||
if (strip_en) begin
|
||||
// Drop header word
|
||||
m_tvalid = 0;
|
||||
s_chdr_tready = 1;
|
||||
end else begin
|
||||
// Pass header through
|
||||
m_tvalid = s_chdr_tvalid;
|
||||
s_chdr_tready = m_tready;
|
||||
end
|
||||
end
|
||||
ST_STRIP : begin
|
||||
// Drop incoming words
|
||||
m_tvalid = 0;
|
||||
m_tuser = 'X;
|
||||
s_chdr_tready = 1;
|
||||
end
|
||||
ST_PASS : begin
|
||||
// Pass words through
|
||||
m_tvalid = s_chdr_tvalid;
|
||||
m_tuser = packet_length;
|
||||
s_chdr_tready = m_tready;
|
||||
end
|
||||
endcase
|
||||
end : sm_comb
|
||||
|
||||
endmodule : chdr_strip_header
|
||||
|
||||
|
||||
`default_nettype wire
|
||||
Reference in New Issue
Block a user