This adds the NIPC parameter, which configures support for processing multiple items or samples per clock cycle. With this enabled, the FFT block can process at rates higher than 250 MSPS, such as 500 MSPS and beyond. Original-commit: fc76aa940e121fe1f85a3513f6d90df4667338cf
117 lines
3.1 KiB
Systemverilog
117 lines
3.1 KiB
Systemverilog
//
|
|
// Copyright 2024 Ettus Research, a National Instruments Brand
|
|
//
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
//
|
|
// Module: cp_removal
|
|
//
|
|
// Description:
|
|
//
|
|
// Removes the cyclic prefix from OFDM symbols. This module assumes that each
|
|
// AXI-stream input packet is one symbol with a prefix and it will output one
|
|
// packet per symbol with the prefix removed. The cyclic prefix length to be
|
|
// removed is input on the cp_len AXI-Stream input port, and it must be
|
|
// present at the start of each data packet until cp_len_tready is asserted.
|
|
// There is a one-cycle bubble at the start of each symbol to register cyclic
|
|
// prefix length.
|
|
//
|
|
// Parameters:
|
|
//
|
|
// CP_LEN_W : Width of the maximum cyclic prefix length. The maximum
|
|
// supported CP length is 2**CP_LEN_W - 1.
|
|
// DATA_W : Data/sample AXI-Stream bus width
|
|
//
|
|
|
|
`default_nettype none
|
|
|
|
|
|
module cp_removal #(
|
|
int CP_LEN_W = 12,
|
|
int DATA_W = 32
|
|
) (
|
|
input wire clk,
|
|
input wire rst,
|
|
|
|
// Cyclic prefix length input port
|
|
input wire [ CP_LEN_W-1:0] cp_len_tdata,
|
|
input wire cp_len_tvalid,
|
|
output reg cp_len_tready,
|
|
|
|
// Symbol data stream input
|
|
input wire [ DATA_W-1:0] i_tdata,
|
|
input wire i_tlast,
|
|
input wire i_tvalid,
|
|
output wire i_tready,
|
|
|
|
// Symbol data stream output (one symbol per packet)
|
|
output wire [ DATA_W-1:0] o_tdata,
|
|
output wire o_tlast,
|
|
output wire o_tvalid,
|
|
input wire o_tready
|
|
);
|
|
`include "usrp_utils.svh"
|
|
|
|
logic [CP_LEN_W-1:0] cp_len_reg;
|
|
logic [CP_LEN_W-1:0] count = 1;
|
|
|
|
enum logic [1:0] { ST_IDLE, ST_PREFIX, ST_BODY } state;
|
|
|
|
always @(posedge clk) begin
|
|
cp_len_tready <= 1'b0;
|
|
|
|
case (state)
|
|
// Wait in idle state until we get a new packet and the cyclic prefix
|
|
// length.
|
|
ST_IDLE : begin
|
|
count <= 1;
|
|
cp_len_reg <= cp_len_tdata;
|
|
if (i_tvalid && cp_len_tvalid) begin
|
|
cp_len_tready <= 1'b1;
|
|
if (cp_len_tdata > 0) begin
|
|
state <= ST_PREFIX;
|
|
end else begin
|
|
state <= ST_BODY;
|
|
end
|
|
end
|
|
end
|
|
|
|
// Remove the prefix
|
|
ST_PREFIX : begin
|
|
if (i_tvalid && i_tready) begin
|
|
count <= count + 1;
|
|
if (count == cp_len_reg) begin
|
|
count <= 1;
|
|
state <= ST_BODY;
|
|
end
|
|
end
|
|
end
|
|
|
|
// Pass through the rest until the end of the packet.
|
|
ST_BODY : begin
|
|
count <= 1;
|
|
if (i_tvalid && i_tready) begin
|
|
if(i_tlast) begin
|
|
state <= ST_IDLE;
|
|
end
|
|
end
|
|
end
|
|
endcase
|
|
|
|
if (rst) begin
|
|
state <= ST_IDLE;
|
|
count <= 'X;
|
|
cp_len_reg <= 'X;
|
|
cp_len_tready <= '0;
|
|
end
|
|
end
|
|
|
|
assign o_tdata = i_tdata;
|
|
assign o_tlast = i_tlast;
|
|
assign o_tvalid = (state == ST_BODY ) ? i_tvalid : 1'b0;
|
|
assign i_tready = (state == ST_BODY ) ? o_tready :
|
|
(state == ST_PREFIX) ? 1'b1 : 1'b0;
|
|
|
|
endmodule : cp_removal
|
|
|
|
`default_nettype wire
|