fpga: lib: Add chdr_strip_header module

Original-commit: 4bf988aa3c9aa3885dc30e3da7ea67fcec48c97e
This commit is contained in:
Wade Fife
2022-08-29 17:01:45 -05:00
committed by skooNI
parent 16587514ba
commit dce09f8fd7
2 changed files with 156 additions and 0 deletions
+1
View File
@@ -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 \
))
+155
View File
@@ -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