mirror of
https://github.com/EttusResearch/uhd.git
synced 2026-10-25 17:36:10 +00:00
fpga: rfnoc: Add OFDM block
This commit is contained in:
parent
febf79834a
commit
788ff45345
63
fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ofdm/Makefile
Normal file
63
fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ofdm/Makefile
Normal file
@ -0,0 +1,63 @@
|
||||
#
|
||||
# Copyright 2024 Ettus Research, a National Instruments Brand
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
#
|
||||
|
||||
#-------------------------------------------------
|
||||
# Top-of-Makefile
|
||||
#-------------------------------------------------
|
||||
# Define BASE_DIR to point to the "top" dir
|
||||
BASE_DIR = $(abspath ../../../../top)
|
||||
# Include viv_sim_preample after defining BASE_DIR
|
||||
include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
|
||||
|
||||
#-------------------------------------------------
|
||||
# IP Specific
|
||||
#-------------------------------------------------
|
||||
# If simulation contains IP, define the IP_DIR and point
|
||||
# it to the base level IP directory
|
||||
LIB_IP_DIR = $(BASE_DIR)/../lib/ip
|
||||
|
||||
# Include makefiles and sources for all IP components
|
||||
# *after* defining the LIB_IP_DIR
|
||||
include $(LIB_IP_DIR)/xfft_32k_16b/Makefile.inc
|
||||
include $(LIB_IP_DIR)/xfft_8k_16b/Makefile.inc
|
||||
include $(LIB_IP_DIR)/xfft_4k_16b/Makefile.inc
|
||||
|
||||
DESIGN_SRCS += $(abspath \
|
||||
$(LIB_IP_XFFT_32K_16B_OUTS) \
|
||||
$(LIB_IP_XFFT_8K_16B_OUTS) \
|
||||
$(LIB_IP_XFFT_4K_16B_OUTS) \
|
||||
)
|
||||
|
||||
#-------------------------------------------------
|
||||
# Design Specific
|
||||
#-------------------------------------------------
|
||||
# Include makefiles and sources for the DUT and its
|
||||
# dependencies.
|
||||
include $(BASE_DIR)/../lib/rfnoc/core/Makefile.srcs
|
||||
include $(BASE_DIR)/../lib/rfnoc/utils/Makefile.srcs
|
||||
include Makefile.srcs
|
||||
|
||||
DESIGN_SRCS += $(abspath \
|
||||
$(RFNOC_CORE_SRCS) \
|
||||
$(RFNOC_OOT_SRCS) \
|
||||
$(RFNOC_NI_ORU_IP_XCI_SRCS) \
|
||||
)
|
||||
|
||||
#-------------------------------------------------
|
||||
# Testbench Specific
|
||||
#-------------------------------------------------
|
||||
SIM_TOP = rfnoc_block_ofdm_tb
|
||||
SIM_SRCS = $(abspath \
|
||||
rfnoc_block_ofdm_tb.sv \
|
||||
)
|
||||
|
||||
#-------------------------------------------------
|
||||
# Bottom-of-Makefile
|
||||
#-------------------------------------------------
|
||||
# Include all simulator specific makefiles here
|
||||
# Each should define a unique target to simulate
|
||||
# e.g. xsim, vsim, etc and a common "clean" target
|
||||
include $(BASE_DIR)/../tools/make/viv_simulator.mak
|
||||
23
fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ofdm/Makefile.srcs
Normal file
23
fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ofdm/Makefile.srcs
Normal file
@ -0,0 +1,23 @@
|
||||
#
|
||||
# Copyright 2023 Ettus Research, a National Instruments Brand
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
#
|
||||
|
||||
##################################################
|
||||
# RFNoC Block Sources
|
||||
##################################################
|
||||
# Here, list all the files that are necessary to synthesize this block. Don't
|
||||
# include testbenches!
|
||||
# Make sure that the source files are nicely detectable by a regex. Best to put
|
||||
# one on each line.
|
||||
# The first argument to addprefix is the current path to this Makefile, so the
|
||||
# path list is always absolute, regardless of from where we're including or
|
||||
# calling this file. RFNOC_OOT_SRCS needs to be a simply expanded variable
|
||||
# (not a recursively expanded variable), and we take care of that in the build
|
||||
# infrastructure.
|
||||
RFNOC_OOT_SRCS += $(addprefix $(dir $(abspath $(lastword $(MAKEFILE_LIST)))), \
|
||||
axis_ofdm_cyclic_prefix_removal.v \
|
||||
noc_shell_ofdm.v \
|
||||
rfnoc_block_ofdm.sv \
|
||||
)
|
||||
@ -0,0 +1,207 @@
|
||||
//
|
||||
// Copyright 2023 Ettus Research, a National Instruments Brand
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: axis_ofdm_cyclic_prefix_removal
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Removes cyclic prefix from OFDM symbols. Configuration FIFO allows for
|
||||
// either queuing up multiple configs with an optional loopback mode that
|
||||
// writes the current config back into the FIFO. This allows the block
|
||||
// to execute a pattern, for example if CP lengths can change symbol to symbol
|
||||
// in a repeating pattern.
|
||||
//
|
||||
// Note: There is a two clock bubble cycle after every OFDM symbol due to returning to
|
||||
// the idle state to load the next config, so this block must be clocked at least
|
||||
// slightly faster the sample rate, i.e. Clock rate > (Fs)*(1 + 2/(CP length + FFT Size)).
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// WIDTH : Data / Sample AXIS bus width
|
||||
// MAX_CP_LEN_LOG2 : Log2 of maximum cyclic prefix length
|
||||
// MAX_FFT_SIZE_LOG2 : Log2 of maximum FFT size
|
||||
// DEFAULT_CP_LEN : Number of samples in cyclic prefix
|
||||
// CP_LEN_FIFO_MODE : 0: FIFO without loopback, 1: FIFO with loopback
|
||||
// CP_LEN_FIFO_SIZE_LOG2 : Log2 depth of the FIFO
|
||||
// SET_TLAST : Always set tlast at the end of each symbol
|
||||
//
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module axis_ofdm_cyclic_prefix_removal #(
|
||||
parameter WIDTH = 32,
|
||||
parameter USER_WIDTH = 1,
|
||||
parameter MAX_CP_LEN_LOG2 = 16,
|
||||
parameter MAX_FFT_SIZE_LOG2 = 16,
|
||||
parameter DEFAULT_CP_LEN = 288,
|
||||
parameter CP_LEN_FIFO_MODE = 0,
|
||||
parameter CP_LEN_FIFO_SIZE_LOG2 = 5,
|
||||
parameter SET_TLAST = 1
|
||||
)(
|
||||
input wire clk,
|
||||
input wire reset,
|
||||
input wire clear_fifo, // Clears cyclic prefix length FIFO, but only when safe to do so
|
||||
input wire [MAX_FFT_SIZE_LOG2-1:0] fft_size,
|
||||
input wire [MAX_CP_LEN_LOG2-1:0] m_axis_cp_len_tdata,
|
||||
input wire m_axis_cp_len_tvalid,
|
||||
output wire m_axis_cp_len_tready,
|
||||
output wire [15:0] cp_len_fifo_occupied,
|
||||
input wire [WIDTH-1:0] s_axis_data_tdata,
|
||||
input wire [USER_WIDTH-1:0] s_axis_data_tuser,
|
||||
input wire s_axis_data_tlast,
|
||||
input wire s_axis_data_tvalid,
|
||||
output wire s_axis_data_tready,
|
||||
output wire [WIDTH-1:0] m_axis_data_tdata,
|
||||
output wire [USER_WIDTH-1:0] m_axis_data_tuser,
|
||||
output wire m_axis_data_tlast,
|
||||
output wire m_axis_data_tvalid,
|
||||
input wire m_axis_data_tready
|
||||
);
|
||||
|
||||
localparam S_IDLE = 3'd0;
|
||||
localparam S_CONFIG = 3'd1;
|
||||
localparam S_CYCLIC_PREFIX = 3'd2;
|
||||
localparam S_OFDM_SYMBOL = 3'd3;
|
||||
localparam S_CLEAR_FIFO = 3'd4;
|
||||
reg [2:0] state;
|
||||
|
||||
wire [MAX_CP_LEN_LOG2-1:0] cp_len_fifo_in_tdata, cp_len_fifo_out_tdata;
|
||||
wire cp_len_fifo_in_tvalid, cp_len_fifo_out_tvalid;
|
||||
wire cp_len_fifo_in_tready, cp_len_fifo_out_tready;
|
||||
|
||||
wire clear_config_fifo = (state == S_CLEAR_FIFO);
|
||||
|
||||
axi_fifo #(
|
||||
.WIDTH (MAX_CP_LEN_LOG2),
|
||||
.SIZE (CP_LEN_FIFO_SIZE_LOG2))
|
||||
axi_fifo_config_inst (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.clear (clear_config_fifo),
|
||||
.i_tdata (cp_len_fifo_in_tdata),
|
||||
.i_tvalid (cp_len_fifo_in_tvalid),
|
||||
.i_tready (cp_len_fifo_in_tready),
|
||||
.o_tdata (cp_len_fifo_out_tdata),
|
||||
.o_tvalid (cp_len_fifo_out_tvalid),
|
||||
.o_tready (cp_len_fifo_out_tready),
|
||||
.space (),
|
||||
.occupied (cp_len_fifo_occupied)
|
||||
);
|
||||
|
||||
generate
|
||||
// No config fifo loopback. New configs can be written at any time.
|
||||
if (CP_LEN_FIFO_MODE == 0) begin
|
||||
assign cp_len_fifo_in_tdata = m_axis_cp_len_tdata;
|
||||
assign cp_len_fifo_in_tvalid = (state == S_CLEAR_FIFO) ? 1'b0 : m_axis_cp_len_tvalid;
|
||||
assign m_axis_cp_len_tready = (state == S_CLEAR_FIFO) ? 1'b0 : cp_len_fifo_in_tready;
|
||||
assign cp_len_fifo_out_tready = (state == S_CONFIG);
|
||||
// Config fifo loopback enabled, writes current config back into config fifo in the S_CONFIG state.
|
||||
// New configs can be written in any state but S_CONFIG & S_CLEAR.
|
||||
end else begin
|
||||
assign cp_len_fifo_in_tdata = (state == S_CONFIG) ? cp_len_fifo_out_tdata : m_axis_cp_len_tdata;
|
||||
assign cp_len_fifo_in_tvalid = (state == S_CONFIG) ? cp_len_fifo_out_tvalid :
|
||||
(state == S_CLEAR_FIFO) ? 1'b0 :
|
||||
/* Else */ m_axis_cp_len_tvalid;
|
||||
assign m_axis_cp_len_tready = (state == S_CONFIG) ? 1'b0 :
|
||||
(state == S_CLEAR_FIFO) ? 1'b0 :
|
||||
/* Else */ cp_len_fifo_in_tready;
|
||||
assign cp_len_fifo_out_tready = (state == S_CONFIG);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// CP length should generally not be larger than the FFT size, but this calculation is just in case
|
||||
// someone tries to use this block in an unusual way
|
||||
localparam CNT_WIDTH = MAX_FFT_SIZE_LOG2 > MAX_CP_LEN_LOG2 ? MAX_FFT_SIZE_LOG2 : MAX_CP_LEN_LOG2;
|
||||
|
||||
reg [MAX_CP_LEN_LOG2-1:0] cp_len_reg = DEFAULT_CP_LEN;
|
||||
reg [MAX_FFT_SIZE_LOG2-1:0] fft_size_reg = 'd0;
|
||||
reg [CNT_WIDTH-1:0] cnt = 'd0;
|
||||
reg clear_fifo_hold = 1'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
// Latch FIFO clear
|
||||
if (clear_fifo) begin
|
||||
clear_fifo_hold <= 1'b1;
|
||||
end
|
||||
// State machine
|
||||
case (state)
|
||||
// Wait in idle state until either a configuration FIFO clear is requested
|
||||
// or
|
||||
S_IDLE: begin
|
||||
cnt <= 1;
|
||||
if (clear_fifo_hold) begin
|
||||
state <= S_CLEAR_FIFO;
|
||||
end else if (s_axis_data_tvalid) begin
|
||||
// Note: Only update cyclic prefix length and fft size if new values are available
|
||||
if (cp_len_fifo_out_tvalid) begin
|
||||
cp_len_reg <= cp_len_fifo_out_tdata;
|
||||
end
|
||||
fft_size_reg <= fft_size;
|
||||
state <= S_CONFIG;
|
||||
end
|
||||
end
|
||||
S_CONFIG: begin
|
||||
if (cp_len_reg > 0) begin
|
||||
state <= S_CYCLIC_PREFIX;
|
||||
end else if (fft_size_reg > 0) begin
|
||||
state <= S_OFDM_SYMBOL;
|
||||
end else begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
S_CYCLIC_PREFIX : begin
|
||||
if (s_axis_data_tvalid & s_axis_data_tready) begin
|
||||
cnt <= cnt + 1;
|
||||
if (cnt >= cp_len_reg) begin
|
||||
cnt <= 1;
|
||||
if (fft_size_reg > 0) begin
|
||||
state <= S_OFDM_SYMBOL;
|
||||
end else begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
S_OFDM_SYMBOL : begin
|
||||
if (s_axis_data_tvalid & s_axis_data_tready) begin
|
||||
cnt <= cnt + 1;
|
||||
if (cnt >= fft_size_reg) begin
|
||||
cnt <= 1;
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
S_CLEAR_FIFO : begin
|
||||
clear_fifo_hold <= 1'b0;
|
||||
cp_len_reg <= DEFAULT_CP_LEN;
|
||||
state <= S_IDLE;
|
||||
end
|
||||
default : state <= S_IDLE;
|
||||
endcase
|
||||
if (reset) begin
|
||||
clear_fifo_hold <= 1'b0;
|
||||
cp_len_reg <= DEFAULT_CP_LEN;
|
||||
cnt <= 1;
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
assign m_axis_data_tdata = s_axis_data_tdata;
|
||||
assign m_axis_data_tuser = s_axis_data_tuser;
|
||||
assign m_axis_data_tlast = (SET_TLAST == 0) ? s_axis_data_tlast : (state == S_OFDM_SYMBOL) & (cnt >= fft_size_reg);
|
||||
assign m_axis_data_tvalid = (state == S_IDLE) ? 1'b0 :
|
||||
(state == S_CYCLIC_PREFIX) ? 1'b0 :
|
||||
(state == S_OFDM_SYMBOL) ? s_axis_data_tvalid :
|
||||
(state == S_CLEAR_FIFO) ? 1'b0 :
|
||||
/* Else */ 1'b0;
|
||||
assign s_axis_data_tready = (state == S_IDLE) ? 1'b0 :
|
||||
(state == S_CYCLIC_PREFIX) ? 1'b1 :
|
||||
(state == S_OFDM_SYMBOL) ? m_axis_data_tready :
|
||||
(state == S_CLEAR_FIFO) ? 1'b0 :
|
||||
/* Else */ 1'b0;
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
305
fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ofdm/noc_shell_ofdm.v
Normal file
305
fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ofdm/noc_shell_ofdm.v
Normal file
@ -0,0 +1,305 @@
|
||||
//
|
||||
// Copyright 2024 Ettus Research, a National Instruments Brand
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: noc_shell_ofdm
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// This is a tool-generated NoC-shell for the OFDM block.
|
||||
// See the RFNoC specification for more information about NoC shells.
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// THIS_PORTID : Control crossbar port to which this block is connected
|
||||
// CHDR_W : AXIS-CHDR data bus width
|
||||
// MTU : Maximum transmission unit (i.e., maximum packet size in
|
||||
// CHDR words is 2**MTU).
|
||||
//
|
||||
|
||||
`default_nettype none
|
||||
|
||||
|
||||
module noc_shell_ofdm #(
|
||||
parameter [9:0] THIS_PORTID = 10'd0,
|
||||
parameter CHDR_W = 64,
|
||||
parameter [5:0] MTU = 10,
|
||||
parameter NUM_PORTS = 2
|
||||
) (
|
||||
//---------------------
|
||||
// Framework Interface
|
||||
//---------------------
|
||||
|
||||
// RFNoC Framework Clocks
|
||||
input wire rfnoc_chdr_clk,
|
||||
input wire rfnoc_ctrl_clk,
|
||||
input wire ce_clk,
|
||||
|
||||
// NoC Shell Generated Resets
|
||||
output wire rfnoc_chdr_rst,
|
||||
output wire rfnoc_ctrl_rst,
|
||||
output wire ce_rst,
|
||||
|
||||
// RFNoC Backend Interface
|
||||
input wire [511:0] rfnoc_core_config,
|
||||
output wire [511:0] rfnoc_core_status,
|
||||
|
||||
// AXIS-CHDR Input Ports (from framework)
|
||||
input wire [(0+NUM_PORTS)*CHDR_W-1:0] s_rfnoc_chdr_tdata,
|
||||
input wire [(0+NUM_PORTS)-1:0] s_rfnoc_chdr_tlast,
|
||||
input wire [(0+NUM_PORTS)-1:0] s_rfnoc_chdr_tvalid,
|
||||
output wire [(0+NUM_PORTS)-1:0] s_rfnoc_chdr_tready,
|
||||
// AXIS-CHDR Output Ports (to framework)
|
||||
output wire [(0+NUM_PORTS)*CHDR_W-1:0] m_rfnoc_chdr_tdata,
|
||||
output wire [(0+NUM_PORTS)-1:0] m_rfnoc_chdr_tlast,
|
||||
output wire [(0+NUM_PORTS)-1:0] m_rfnoc_chdr_tvalid,
|
||||
input wire [(0+NUM_PORTS)-1:0] m_rfnoc_chdr_tready,
|
||||
|
||||
// AXIS-Ctrl Control Input Port (from framework)
|
||||
input wire [31:0] s_rfnoc_ctrl_tdata,
|
||||
input wire s_rfnoc_ctrl_tlast,
|
||||
input wire s_rfnoc_ctrl_tvalid,
|
||||
output wire s_rfnoc_ctrl_tready,
|
||||
// AXIS-Ctrl Control Output Port (to framework)
|
||||
output wire [31:0] m_rfnoc_ctrl_tdata,
|
||||
output wire m_rfnoc_ctrl_tlast,
|
||||
output wire m_rfnoc_ctrl_tvalid,
|
||||
input wire m_rfnoc_ctrl_tready,
|
||||
|
||||
//---------------------
|
||||
// Client Interface
|
||||
//---------------------
|
||||
|
||||
// CtrlPort Clock and Reset
|
||||
output wire ctrlport_clk,
|
||||
output wire ctrlport_rst,
|
||||
// CtrlPort Master
|
||||
output wire m_ctrlport_req_wr,
|
||||
output wire m_ctrlport_req_rd,
|
||||
output wire [19:0] m_ctrlport_req_addr,
|
||||
output wire [31:0] m_ctrlport_req_data,
|
||||
input wire m_ctrlport_resp_ack,
|
||||
input wire [31:0] m_ctrlport_resp_data,
|
||||
|
||||
// AXI-Stream Data Clock and Reset
|
||||
output wire axis_data_clk,
|
||||
output wire axis_data_rst,
|
||||
// Data Stream to User Logic: in
|
||||
output wire [NUM_PORTS*32*1-1:0] m_in_axis_tdata,
|
||||
output wire [NUM_PORTS*1-1:0] m_in_axis_tkeep,
|
||||
output wire [NUM_PORTS-1:0] m_in_axis_tlast,
|
||||
output wire [NUM_PORTS-1:0] m_in_axis_tvalid,
|
||||
input wire [NUM_PORTS-1:0] m_in_axis_tready,
|
||||
output wire [NUM_PORTS*64-1:0] m_in_axis_ttimestamp,
|
||||
output wire [NUM_PORTS-1:0] m_in_axis_thas_time,
|
||||
output wire [NUM_PORTS*16-1:0] m_in_axis_tlength,
|
||||
output wire [NUM_PORTS-1:0] m_in_axis_teov,
|
||||
output wire [NUM_PORTS-1:0] m_in_axis_teob,
|
||||
// Data Stream from User Logic: out
|
||||
input wire [NUM_PORTS*32*1-1:0] s_out_axis_tdata,
|
||||
input wire [NUM_PORTS*1-1:0] s_out_axis_tkeep,
|
||||
input wire [NUM_PORTS-1:0] s_out_axis_tlast,
|
||||
input wire [NUM_PORTS-1:0] s_out_axis_tvalid,
|
||||
output wire [NUM_PORTS-1:0] s_out_axis_tready,
|
||||
input wire [NUM_PORTS*64-1:0] s_out_axis_ttimestamp,
|
||||
input wire [NUM_PORTS-1:0] s_out_axis_thas_time,
|
||||
input wire [NUM_PORTS*16-1:0] s_out_axis_tlength,
|
||||
input wire [NUM_PORTS-1:0] s_out_axis_teov,
|
||||
input wire [NUM_PORTS-1:0] s_out_axis_teob
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Backend Interface
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
wire data_i_flush_en;
|
||||
wire [31:0] data_i_flush_timeout;
|
||||
wire [63:0] data_i_flush_active;
|
||||
wire [63:0] data_i_flush_done;
|
||||
wire data_o_flush_en;
|
||||
wire [31:0] data_o_flush_timeout;
|
||||
wire [63:0] data_o_flush_active;
|
||||
wire [63:0] data_o_flush_done;
|
||||
|
||||
backend_iface #(
|
||||
.NOC_ID (32'h0FD30000),
|
||||
.NUM_DATA_I (0+NUM_PORTS),
|
||||
.NUM_DATA_O (0+NUM_PORTS),
|
||||
.CTRL_FIFOSIZE ($clog2(32)),
|
||||
.MTU (MTU)
|
||||
) backend_iface_i (
|
||||
.rfnoc_chdr_clk (rfnoc_chdr_clk),
|
||||
.rfnoc_chdr_rst (rfnoc_chdr_rst),
|
||||
.rfnoc_ctrl_clk (rfnoc_ctrl_clk),
|
||||
.rfnoc_ctrl_rst (rfnoc_ctrl_rst),
|
||||
.rfnoc_core_config (rfnoc_core_config),
|
||||
.rfnoc_core_status (rfnoc_core_status),
|
||||
.data_i_flush_en (data_i_flush_en),
|
||||
.data_i_flush_timeout (data_i_flush_timeout),
|
||||
.data_i_flush_active (data_i_flush_active),
|
||||
.data_i_flush_done (data_i_flush_done),
|
||||
.data_o_flush_en (data_o_flush_en),
|
||||
.data_o_flush_timeout (data_o_flush_timeout),
|
||||
.data_o_flush_active (data_o_flush_active),
|
||||
.data_o_flush_done (data_o_flush_done)
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Reset Generation
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
wire ce_rst_pulse;
|
||||
|
||||
pulse_synchronizer #(.MODE ("POSEDGE")) pulse_synchronizer_ce (
|
||||
.clk_a(rfnoc_chdr_clk), .rst_a(1'b0), .pulse_a (rfnoc_chdr_rst), .busy_a (),
|
||||
.clk_b(ce_clk), .pulse_b (ce_rst_pulse)
|
||||
);
|
||||
|
||||
pulse_stretch_min #(.LENGTH(32)) pulse_stretch_min_ce (
|
||||
.clk(ce_clk), .rst(1'b0),
|
||||
.pulse_in(ce_rst_pulse), .pulse_out(ce_rst)
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Control Path
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
assign ctrlport_clk = ce_clk;
|
||||
assign ctrlport_rst = ce_rst;
|
||||
|
||||
ctrlport_endpoint #(
|
||||
.THIS_PORTID (THIS_PORTID),
|
||||
.SYNC_CLKS (0),
|
||||
.AXIS_CTRL_MST_EN (0),
|
||||
.AXIS_CTRL_SLV_EN (1),
|
||||
.SLAVE_FIFO_SIZE ($clog2(32))
|
||||
) ctrlport_endpoint_i (
|
||||
.rfnoc_ctrl_clk (rfnoc_ctrl_clk),
|
||||
.rfnoc_ctrl_rst (rfnoc_ctrl_rst),
|
||||
.ctrlport_clk (ctrlport_clk),
|
||||
.ctrlport_rst (ctrlport_rst),
|
||||
.s_rfnoc_ctrl_tdata (s_rfnoc_ctrl_tdata),
|
||||
.s_rfnoc_ctrl_tlast (s_rfnoc_ctrl_tlast),
|
||||
.s_rfnoc_ctrl_tvalid (s_rfnoc_ctrl_tvalid),
|
||||
.s_rfnoc_ctrl_tready (s_rfnoc_ctrl_tready),
|
||||
.m_rfnoc_ctrl_tdata (m_rfnoc_ctrl_tdata),
|
||||
.m_rfnoc_ctrl_tlast (m_rfnoc_ctrl_tlast),
|
||||
.m_rfnoc_ctrl_tvalid (m_rfnoc_ctrl_tvalid),
|
||||
.m_rfnoc_ctrl_tready (m_rfnoc_ctrl_tready),
|
||||
.m_ctrlport_req_wr (m_ctrlport_req_wr),
|
||||
.m_ctrlport_req_rd (m_ctrlport_req_rd),
|
||||
.m_ctrlport_req_addr (m_ctrlport_req_addr),
|
||||
.m_ctrlport_req_data (m_ctrlport_req_data),
|
||||
.m_ctrlport_req_byte_en (),
|
||||
.m_ctrlport_req_has_time (),
|
||||
.m_ctrlport_req_time (),
|
||||
.m_ctrlport_resp_ack (m_ctrlport_resp_ack),
|
||||
.m_ctrlport_resp_status (2'b0),
|
||||
.m_ctrlport_resp_data (m_ctrlport_resp_data),
|
||||
.s_ctrlport_req_wr (1'b0),
|
||||
.s_ctrlport_req_rd (1'b0),
|
||||
.s_ctrlport_req_addr (20'b0),
|
||||
.s_ctrlport_req_portid (10'b0),
|
||||
.s_ctrlport_req_rem_epid (16'b0),
|
||||
.s_ctrlport_req_rem_portid (10'b0),
|
||||
.s_ctrlport_req_data (32'b0),
|
||||
.s_ctrlport_req_byte_en (4'hF),
|
||||
.s_ctrlport_req_has_time (1'b0),
|
||||
.s_ctrlport_req_time (64'b0),
|
||||
.s_ctrlport_resp_ack (),
|
||||
.s_ctrlport_resp_status (),
|
||||
.s_ctrlport_resp_data ()
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Data Path
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
genvar i;
|
||||
|
||||
assign axis_data_clk = ce_clk;
|
||||
assign axis_data_rst = ce_rst;
|
||||
|
||||
//---------------------
|
||||
// Input Data Paths
|
||||
//---------------------
|
||||
|
||||
for (i = 0; i < NUM_PORTS; i = i + 1) begin: gen_input_in
|
||||
chdr_to_axis_data #(
|
||||
.CHDR_W (CHDR_W),
|
||||
.ITEM_W (32),
|
||||
.NIPC (1),
|
||||
.SYNC_CLKS (0),
|
||||
.INFO_FIFO_SIZE ($clog2(32)),
|
||||
.PYLD_FIFO_SIZE ($clog2(32))
|
||||
) chdr_to_axis_data_in_in (
|
||||
.axis_chdr_clk (rfnoc_chdr_clk),
|
||||
.axis_chdr_rst (rfnoc_chdr_rst),
|
||||
.axis_data_clk (axis_data_clk),
|
||||
.axis_data_rst (axis_data_rst),
|
||||
.s_axis_chdr_tdata (s_rfnoc_chdr_tdata[((0+i)*CHDR_W)+:CHDR_W]),
|
||||
.s_axis_chdr_tlast (s_rfnoc_chdr_tlast[0+i]),
|
||||
.s_axis_chdr_tvalid (s_rfnoc_chdr_tvalid[0+i]),
|
||||
.s_axis_chdr_tready (s_rfnoc_chdr_tready[0+i]),
|
||||
.m_axis_tdata (m_in_axis_tdata[(32*1)*i+:(32*1)]),
|
||||
.m_axis_tkeep (m_in_axis_tkeep[1*i+:1]),
|
||||
.m_axis_tlast (m_in_axis_tlast[i]),
|
||||
.m_axis_tvalid (m_in_axis_tvalid[i]),
|
||||
.m_axis_tready (m_in_axis_tready[i]),
|
||||
.m_axis_ttimestamp (m_in_axis_ttimestamp[64*i+:64]),
|
||||
.m_axis_thas_time (m_in_axis_thas_time[i]),
|
||||
.m_axis_tlength (m_in_axis_tlength[16*i+:16]),
|
||||
.m_axis_teov (m_in_axis_teov[i]),
|
||||
.m_axis_teob (m_in_axis_teob[i]),
|
||||
.flush_en (data_i_flush_en),
|
||||
.flush_timeout (data_i_flush_timeout),
|
||||
.flush_active (data_i_flush_active[0+i]),
|
||||
.flush_done (data_i_flush_done[0+i])
|
||||
);
|
||||
end
|
||||
|
||||
//---------------------
|
||||
// Output Data Paths
|
||||
//---------------------
|
||||
|
||||
for (i = 0; i < NUM_PORTS; i = i + 1) begin: gen_output_out
|
||||
axis_data_to_chdr #(
|
||||
.CHDR_W (CHDR_W),
|
||||
.ITEM_W (32),
|
||||
.NIPC (1),
|
||||
.SYNC_CLKS (0),
|
||||
.INFO_FIFO_SIZE ($clog2(32)),
|
||||
.PYLD_FIFO_SIZE ($clog2(2**MTU)),
|
||||
.MTU (MTU),
|
||||
.SIDEBAND_AT_END (1)
|
||||
) axis_data_to_chdr_out_out (
|
||||
.axis_chdr_clk (rfnoc_chdr_clk),
|
||||
.axis_chdr_rst (rfnoc_chdr_rst),
|
||||
.axis_data_clk (axis_data_clk),
|
||||
.axis_data_rst (axis_data_rst),
|
||||
.m_axis_chdr_tdata (m_rfnoc_chdr_tdata[(0+i)*CHDR_W+:CHDR_W]),
|
||||
.m_axis_chdr_tlast (m_rfnoc_chdr_tlast[0+i]),
|
||||
.m_axis_chdr_tvalid (m_rfnoc_chdr_tvalid[0+i]),
|
||||
.m_axis_chdr_tready (m_rfnoc_chdr_tready[0+i]),
|
||||
.s_axis_tdata (s_out_axis_tdata[(32*1)*i+:(32*1)]),
|
||||
.s_axis_tkeep (s_out_axis_tkeep[1*i+:1]),
|
||||
.s_axis_tlast (s_out_axis_tlast[i]),
|
||||
.s_axis_tvalid (s_out_axis_tvalid[i]),
|
||||
.s_axis_tready (s_out_axis_tready[i]),
|
||||
.s_axis_ttimestamp (s_out_axis_ttimestamp[64*i+:64]),
|
||||
.s_axis_thas_time (s_out_axis_thas_time[i]),
|
||||
.s_axis_tlength (s_out_axis_tlength[16*i+:16]),
|
||||
.s_axis_teov (s_out_axis_teov[i]),
|
||||
.s_axis_teob (s_out_axis_teob[i]),
|
||||
.flush_en (data_o_flush_en),
|
||||
.flush_timeout (data_o_flush_timeout),
|
||||
.flush_active (data_o_flush_active[0+i]),
|
||||
.flush_done (data_o_flush_done[0+i])
|
||||
);
|
||||
end
|
||||
|
||||
endmodule // noc_shell_ofdm
|
||||
|
||||
|
||||
`default_nettype wire
|
||||
963
fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ofdm/rfnoc_block_ofdm.sv
Normal file
963
fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ofdm/rfnoc_block_ofdm.sv
Normal file
@ -0,0 +1,963 @@
|
||||
//
|
||||
// Copyright 2024 Ettus Research, a National Instruments Brand
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: rfnoc_block_ofdm
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// FFT/IFFT plus cyclic prefix insertion/removal.
|
||||
//
|
||||
// User Parameters:
|
||||
//
|
||||
// THIS_PORTID : Control crossbar port to which this block is connected
|
||||
// CHDR_W : AXIS-CHDR data bus width
|
||||
// MTU : Log2 of maximum transmission unit
|
||||
// NUM_PORTS : Number of channels
|
||||
// MAX_FFT_SIZE_LOG2 : Log2 of maximum configurable FFT size
|
||||
// MAX_CP_LEN_LOG2 : Log2 of maximum cyclic prefix length
|
||||
// MAX_CP_LIST_LEN_INS_LOG2 : Log2 of max length of cyclic prefix insertion list
|
||||
// MAX_CP_LIST_LEN_REM_LOG2 : Log2 of max length of cyclic prefix removal list
|
||||
// CP_INSERTION_REPEAT : Enable (1) or disable (0) CP insertion list FIFO loopback
|
||||
// CP_REMOVAL_REPEAT : Enable (1) or disable (0) CP removal list FIFO loopback
|
||||
//
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module rfnoc_block_ofdm #(
|
||||
logic [9:0] THIS_PORTID = 10'd0,
|
||||
int CHDR_W = 64,
|
||||
logic [5:0] MTU = 6'd10,
|
||||
int NUM_PORTS = 2,
|
||||
int MAX_FFT_SIZE_LOG2 = 12,
|
||||
int MAX_CP_LEN_LOG2 = 12,
|
||||
int MAX_CP_LIST_LEN_INS_LOG2 = 5,
|
||||
int MAX_CP_LIST_LEN_REM_LOG2 = 5,
|
||||
int CP_INSERTION_REPEAT = 1,
|
||||
int CP_REMOVAL_REPEAT = 1
|
||||
)(
|
||||
// RFNoC Framework Clocks and Resets
|
||||
input wire rfnoc_chdr_clk,
|
||||
input wire rfnoc_ctrl_clk,
|
||||
input wire ce_clk,
|
||||
// RFNoC Backend Interface
|
||||
input wire [511:0] rfnoc_core_config,
|
||||
output wire [511:0] rfnoc_core_status,
|
||||
// AXIS-CHDR Input Ports (from framework)
|
||||
input wire [(0+NUM_PORTS)*CHDR_W-1:0] s_rfnoc_chdr_tdata,
|
||||
input wire [(0+NUM_PORTS)-1:0] s_rfnoc_chdr_tlast,
|
||||
input wire [(0+NUM_PORTS)-1:0] s_rfnoc_chdr_tvalid,
|
||||
output wire [(0+NUM_PORTS)-1:0] s_rfnoc_chdr_tready,
|
||||
// AXIS-CHDR Output Ports (to framework)
|
||||
output wire [(0+NUM_PORTS)*CHDR_W-1:0] m_rfnoc_chdr_tdata,
|
||||
output wire [(0+NUM_PORTS)-1:0] m_rfnoc_chdr_tlast,
|
||||
output wire [(0+NUM_PORTS)-1:0] m_rfnoc_chdr_tvalid,
|
||||
input wire [(0+NUM_PORTS)-1:0] m_rfnoc_chdr_tready,
|
||||
// AXIS-Ctrl Input Port (from framework)
|
||||
input wire [31:0] s_rfnoc_ctrl_tdata,
|
||||
input wire s_rfnoc_ctrl_tlast,
|
||||
input wire s_rfnoc_ctrl_tvalid,
|
||||
output wire s_rfnoc_ctrl_tready,
|
||||
// AXIS-Ctrl Output Port (to framework)
|
||||
output wire [31:0] m_rfnoc_ctrl_tdata,
|
||||
output wire m_rfnoc_ctrl_tlast,
|
||||
output wire m_rfnoc_ctrl_tvalid,
|
||||
input wire m_rfnoc_ctrl_tready
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// FFT Configuration Interface Constants
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
localparam int MAX_FFT_SIZE = 2**MAX_FFT_SIZE_LOG2;
|
||||
|
||||
localparam int FFT_SCALE_PAD_W =
|
||||
MAX_FFT_SIZE == 4096 ? 3 :
|
||||
MAX_FFT_SIZE == 8192 ? 1 :
|
||||
MAX_FFT_SIZE == 16384 ? 1 :
|
||||
MAX_FFT_SIZE == 32768 ? 7 :
|
||||
MAX_FFT_SIZE == 65536 ? 7 : -1;
|
||||
localparam int FFT_SCALE_W =
|
||||
MAX_FFT_SIZE == 4096 ? 12 :
|
||||
MAX_FFT_SIZE == 8192 ? 14 :
|
||||
MAX_FFT_SIZE == 16384 ? 14 :
|
||||
MAX_FFT_SIZE == 32768 ? 16 :
|
||||
MAX_FFT_SIZE == 65536 ? 16 : -1;
|
||||
localparam int FFT_FWD_INV_W = 1;
|
||||
localparam int FFT_CP_LEN_PAD_W =
|
||||
MAX_FFT_SIZE == 4096 ? 4 :
|
||||
MAX_FFT_SIZE == 8192 ? 3 :
|
||||
MAX_FFT_SIZE == 16384 ? 2 :
|
||||
MAX_FFT_SIZE == 32768 ? 1 :
|
||||
MAX_FFT_SIZE == 65536 ? 0 : -1;
|
||||
localparam int FFT_CP_LEN_W =
|
||||
MAX_FFT_SIZE == 4096 ? 12 :
|
||||
MAX_FFT_SIZE == 8192 ? 13 :
|
||||
MAX_FFT_SIZE == 16384 ? 14 :
|
||||
MAX_FFT_SIZE == 32768 ? 15 :
|
||||
MAX_FFT_SIZE == 65536 ? 16 : -1;
|
||||
localparam int FFT_NFFT_PAD_W = 3;
|
||||
localparam int FFT_NFFT_W = 5;
|
||||
|
||||
localparam int FFT_CONFIG_W =
|
||||
FFT_SCALE_PAD_W + FFT_SCALE_W + FFT_FWD_INV_W +
|
||||
FFT_CP_LEN_PAD_W + FFT_CP_LEN_W +
|
||||
FFT_NFFT_PAD_W + FFT_NFFT_W;
|
||||
|
||||
// Use conservative 1/N scaling by default
|
||||
localparam [FFT_SCALE_W-1:0] DEFAULT_FFT_SCALING = {FFT_SCALE_W/2{2'b10}};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Signal Declarations
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Clocks and Resets
|
||||
wire ctrlport_clk;
|
||||
wire ctrlport_rst;
|
||||
wire ctrlport_rst_noc_shell;
|
||||
wire axis_data_clk;
|
||||
wire axis_data_rst;
|
||||
wire axis_data_rst_noc_shell;
|
||||
// CtrlPort Master
|
||||
wire m_ctrlport_req_wr;
|
||||
wire m_ctrlport_req_rd;
|
||||
wire [19:0] m_ctrlport_req_addr;
|
||||
wire [31:0] m_ctrlport_req_data;
|
||||
reg m_ctrlport_resp_ack = 1'b0;
|
||||
reg [31:0] m_ctrlport_resp_data;
|
||||
// Data Stream to User Logic: in
|
||||
wire [NUM_PORTS*32*1-1:0] m_in_axis_tdata;
|
||||
wire [NUM_PORTS*1-1:0] m_in_axis_tkeep;
|
||||
wire [NUM_PORTS-1:0] m_in_axis_tlast;
|
||||
wire [NUM_PORTS-1:0] m_in_axis_tvalid;
|
||||
wire [NUM_PORTS-1:0] m_in_axis_tready;
|
||||
wire [NUM_PORTS*64-1:0] m_in_axis_ttimestamp;
|
||||
wire [NUM_PORTS-1:0] m_in_axis_thas_time;
|
||||
wire [NUM_PORTS*16-1:0] m_in_axis_tlength;
|
||||
wire [NUM_PORTS-1:0] m_in_axis_teov;
|
||||
wire [NUM_PORTS-1:0] m_in_axis_teob;
|
||||
// Data Stream from User Logic: out
|
||||
wire [NUM_PORTS*32*1-1:0] s_out_axis_tdata;
|
||||
wire [NUM_PORTS*1-1:0] s_out_axis_tkeep;
|
||||
wire [NUM_PORTS-1:0] s_out_axis_tlast;
|
||||
wire [NUM_PORTS-1:0] s_out_axis_tvalid;
|
||||
wire [NUM_PORTS-1:0] s_out_axis_tready;
|
||||
wire [NUM_PORTS*64-1:0] s_out_axis_ttimestamp;
|
||||
wire [NUM_PORTS-1:0] s_out_axis_thas_time;
|
||||
wire [NUM_PORTS*16-1:0] s_out_axis_tlength;
|
||||
wire [NUM_PORTS-1:0] s_out_axis_teov;
|
||||
wire [NUM_PORTS-1:0] s_out_axis_teob;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// NoC Shell
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
noc_shell_ofdm #(
|
||||
.CHDR_W (CHDR_W),
|
||||
.THIS_PORTID (THIS_PORTID),
|
||||
.MTU (MTU),
|
||||
.NUM_PORTS (NUM_PORTS)
|
||||
) noc_shell_ofdm_i (
|
||||
//---------------------
|
||||
// Framework Interface
|
||||
//---------------------
|
||||
// Clock Inputs
|
||||
.rfnoc_chdr_clk (rfnoc_chdr_clk),
|
||||
.rfnoc_ctrl_clk (rfnoc_ctrl_clk),
|
||||
.ce_clk (ce_clk),
|
||||
// Reset Outputs
|
||||
.rfnoc_chdr_rst (),
|
||||
.rfnoc_ctrl_rst (),
|
||||
.ce_rst (),
|
||||
// RFNoC Backend Interface
|
||||
.rfnoc_core_config (rfnoc_core_config),
|
||||
.rfnoc_core_status (rfnoc_core_status),
|
||||
// CHDR Input Ports (from framework)
|
||||
.s_rfnoc_chdr_tdata (s_rfnoc_chdr_tdata),
|
||||
.s_rfnoc_chdr_tlast (s_rfnoc_chdr_tlast),
|
||||
.s_rfnoc_chdr_tvalid (s_rfnoc_chdr_tvalid),
|
||||
.s_rfnoc_chdr_tready (s_rfnoc_chdr_tready),
|
||||
// CHDR Output Ports (to framework)
|
||||
.m_rfnoc_chdr_tdata (m_rfnoc_chdr_tdata),
|
||||
.m_rfnoc_chdr_tlast (m_rfnoc_chdr_tlast),
|
||||
.m_rfnoc_chdr_tvalid (m_rfnoc_chdr_tvalid),
|
||||
.m_rfnoc_chdr_tready (m_rfnoc_chdr_tready),
|
||||
// AXIS-Ctrl Input Port (from framework)
|
||||
.s_rfnoc_ctrl_tdata (s_rfnoc_ctrl_tdata),
|
||||
.s_rfnoc_ctrl_tlast (s_rfnoc_ctrl_tlast),
|
||||
.s_rfnoc_ctrl_tvalid (s_rfnoc_ctrl_tvalid),
|
||||
.s_rfnoc_ctrl_tready (s_rfnoc_ctrl_tready),
|
||||
// AXIS-Ctrl Output Port (to framework)
|
||||
.m_rfnoc_ctrl_tdata (m_rfnoc_ctrl_tdata),
|
||||
.m_rfnoc_ctrl_tlast (m_rfnoc_ctrl_tlast),
|
||||
.m_rfnoc_ctrl_tvalid (m_rfnoc_ctrl_tvalid),
|
||||
.m_rfnoc_ctrl_tready (m_rfnoc_ctrl_tready),
|
||||
//---------------------
|
||||
// Client Interface
|
||||
//---------------------
|
||||
// CtrlPort Clock and Reset
|
||||
.ctrlport_clk (ctrlport_clk),
|
||||
.ctrlport_rst (ctrlport_rst_noc_shell),
|
||||
// CtrlPort Master
|
||||
.m_ctrlport_req_wr (m_ctrlport_req_wr),
|
||||
.m_ctrlport_req_rd (m_ctrlport_req_rd),
|
||||
.m_ctrlport_req_addr (m_ctrlport_req_addr),
|
||||
.m_ctrlport_req_data (m_ctrlport_req_data),
|
||||
.m_ctrlport_resp_ack (m_ctrlport_resp_ack),
|
||||
.m_ctrlport_resp_data (m_ctrlport_resp_data),
|
||||
// AXI-Stream Clock and Reset
|
||||
.axis_data_clk (axis_data_clk),
|
||||
.axis_data_rst (axis_data_rst_noc_shell),
|
||||
// Data Stream to User Logic: in
|
||||
.m_in_axis_tdata (m_in_axis_tdata),
|
||||
.m_in_axis_tkeep (m_in_axis_tkeep),
|
||||
.m_in_axis_tlast (m_in_axis_tlast),
|
||||
.m_in_axis_tvalid (m_in_axis_tvalid),
|
||||
.m_in_axis_tready (m_in_axis_tready),
|
||||
.m_in_axis_ttimestamp (m_in_axis_ttimestamp),
|
||||
.m_in_axis_thas_time (m_in_axis_thas_time),
|
||||
.m_in_axis_tlength (m_in_axis_tlength),
|
||||
.m_in_axis_teov (m_in_axis_teov),
|
||||
.m_in_axis_teob (m_in_axis_teob),
|
||||
// Data Stream from User Logic: out
|
||||
.s_out_axis_tdata (s_out_axis_tdata),
|
||||
.s_out_axis_tkeep (s_out_axis_tkeep),
|
||||
.s_out_axis_tlast (s_out_axis_tlast),
|
||||
.s_out_axis_tvalid (s_out_axis_tvalid),
|
||||
.s_out_axis_tready (s_out_axis_tready),
|
||||
.s_out_axis_ttimestamp (s_out_axis_ttimestamp),
|
||||
.s_out_axis_thas_time (s_out_axis_thas_time),
|
||||
.s_out_axis_tlength (s_out_axis_tlength),
|
||||
.s_out_axis_teov (s_out_axis_teov),
|
||||
.s_out_axis_teob (s_out_axis_teob)
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Control Registers
|
||||
//---------------------------------------------------------------------------
|
||||
// FFT Direction
|
||||
localparam [0:0] FFT_REVERSE = 0;
|
||||
localparam [0:0] FFT_FORWARD = 1;
|
||||
|
||||
localparam FFT_SIZE_WIDTH = MAX_FFT_SIZE_LOG2+1;
|
||||
localparam CP_LEN_WIDTH = MAX_CP_LEN_LOG2+1;
|
||||
|
||||
// TODO: Add compat register
|
||||
|
||||
// Register addresses, multiplied by 4 for 32-bit word alignment
|
||||
localparam REG_USER_RESET_ADDR = 0; // Any write to this reg forces a reset for 16 clock cycles.
|
||||
localparam REG_FFT_SIZE_LOG2_ADDR = 8; // Log2 of FFT size
|
||||
localparam REG_FFT_SCALING_ADDR = 9; // FFT scaling word, see Xilinx documentation
|
||||
localparam REG_FFT_DIRECTION_ADDR = 10; // FFT or IFFT
|
||||
localparam REG_FFT_COMMIT_ADDR = 11; // Commit the currently configured settings to the FFT IP
|
||||
localparam REG_CP_INSERTION_CP_LEN_ADDR = 16; // Cyclic Prefix (CP) length (insertion)
|
||||
localparam REG_CP_INSERTION_CP_LEN_FIFO_LOAD_ADDR = 17; // Any write to this reg will load a length into the cyclic prefix insertion FIFO
|
||||
localparam REG_CP_INSERTION_CP_LEN_FIFO_CLR_ADDR = 18; // Any write to this reg will clear the cyclic prefix insertion FIFO
|
||||
localparam REG_CP_INSERTION_CP_LEN_FIFO_OCC_ADDR = 19; // Read only, fullness of cyclic prefix insertion FIFO
|
||||
localparam REG_CP_REMOVAL_CP_LEN_ADDR = 32; // Cyclic Prefix (CP) length (removal)
|
||||
localparam REG_CP_REMOVAL_CP_LEN_FIFO_LOAD_ADDR = 33; // Any write to this reg will load a length into the cyclic prefix removal FIFO
|
||||
localparam REG_CP_REMOVAL_CP_LEN_FIFO_CLR_ADDR = 34; // Any write to this reg will clear the cyclic prefix removal FIFO
|
||||
localparam REG_CP_REMOVAL_CP_LEN_FIFO_OCC_ADDR = 35; // Read only, fullness of cyclic prefix removal config FIFO
|
||||
|
||||
localparam REG_USER_RESET_WIDTH = 1;
|
||||
localparam REG_FFT_SIZE_LOG2_WIDTH = FFT_NFFT_W;
|
||||
localparam REG_FFT_SCALING_WIDTH = FFT_SCALE_W;
|
||||
localparam REG_FFT_DIRECTION_WIDTH = FFT_FWD_INV_W;
|
||||
localparam REG_CP_INSERTION_CP_LEN_WIDTH = CP_LEN_WIDTH;
|
||||
localparam REG_CP_REMOVAL_CP_LEN_WIDTH = CP_LEN_WIDTH;
|
||||
localparam REG_CP_INSERTION_CP_LEN_FIFO_LOAD_WIDTH = 1;
|
||||
localparam REG_CP_INSERTION_CP_LEN_FIFO_CLR_WIDTH = 1;
|
||||
localparam REG_CP_INSERTION_CP_LEN_FIFO_OCC_WIDTH = 16;
|
||||
localparam REG_CP_REMOVAL_CP_LEN_FIFO_LOAD_WIDTH = 1;
|
||||
localparam REG_CP_REMOVAL_CP_LEN_FIFO_CLR_WIDTH = 1;
|
||||
localparam REG_CP_REMOVAL_CP_LEN_FIFO_OCC_WIDTH = 16;
|
||||
|
||||
localparam DEFAULT_FFT_SIZE_LOG2 = 12; // 2^12 = 4096
|
||||
localparam DEFAULT_FFT_DIRECTION = FFT_REVERSE; // Set for FFT
|
||||
localparam DEFAULT_CP_LEN = 0;
|
||||
|
||||
reg [REG_USER_RESET_WIDTH-1:0] reg_user_reset = 1'b0;
|
||||
reg [REG_FFT_SIZE_LOG2_WIDTH-1:0] reg_fft_size_log2 = DEFAULT_FFT_SIZE_LOG2;
|
||||
reg [REG_FFT_SCALING_WIDTH-1:0] reg_fft_scaling = DEFAULT_FFT_SCALING;
|
||||
reg [REG_FFT_DIRECTION_WIDTH-1:0] reg_fft_direction = DEFAULT_FFT_DIRECTION;
|
||||
reg reg_fft_commit = 1'b0;
|
||||
reg [REG_CP_INSERTION_CP_LEN_WIDTH-1:0] reg_cp_insertion_len = DEFAULT_CP_LEN;
|
||||
reg [REG_CP_REMOVAL_CP_LEN_WIDTH-1:0] reg_cp_removal_len = DEFAULT_CP_LEN;
|
||||
reg [REG_CP_INSERTION_CP_LEN_FIFO_LOAD_WIDTH-1:0] reg_cp_insertion_cp_len_fifo_load = 1'b0;
|
||||
reg [REG_CP_INSERTION_CP_LEN_FIFO_CLR_WIDTH -1:0] reg_cp_insertion_cp_len_fifo_clr = 1'b0;
|
||||
reg [REG_CP_REMOVAL_CP_LEN_FIFO_LOAD_WIDTH-1:0] reg_cp_removal_cp_len_fifo_load = 1'b0;
|
||||
reg [REG_CP_REMOVAL_CP_LEN_FIFO_CLR_WIDTH -1:0] reg_cp_removal_cp_len_fifo_clr = 1'b0;
|
||||
wire [REG_CP_INSERTION_CP_LEN_FIFO_OCC_WIDTH -1:0] reg_cp_insertion_cp_len_fifo_occupied;
|
||||
wire [REG_CP_REMOVAL_CP_LEN_FIFO_OCC_WIDTH -1:0] reg_cp_removal_cp_len_fifo_occupied;
|
||||
|
||||
wire reg_fft_commit_next;
|
||||
|
||||
wire [17:0] m_ctrlport_req_addr_aligned = m_ctrlport_req_addr[19:2];
|
||||
|
||||
always @(posedge ctrlport_clk) begin
|
||||
// Default assignment
|
||||
m_ctrlport_resp_ack <= 0;
|
||||
|
||||
// Always clear these regs after being set
|
||||
reg_user_reset <= 1'b0;
|
||||
reg_cp_insertion_cp_len_fifo_load <= 1'b0;
|
||||
reg_cp_insertion_cp_len_fifo_clr <= 1'b0;
|
||||
reg_cp_removal_cp_len_fifo_load <= 1'b0;
|
||||
reg_cp_removal_cp_len_fifo_clr <= 1'b0;
|
||||
|
||||
reg_fft_commit <= reg_fft_commit_next;
|
||||
|
||||
// Read user registers
|
||||
if (m_ctrlport_req_rd) begin // Read request
|
||||
m_ctrlport_resp_ack <= 1; // Always immediately ack
|
||||
m_ctrlport_resp_data <= 0; // Zero out by default
|
||||
case (m_ctrlport_req_addr_aligned)
|
||||
REG_USER_RESET_ADDR: m_ctrlport_resp_data <= reg_user_reset;
|
||||
REG_FFT_SIZE_LOG2_ADDR: m_ctrlport_resp_data <= reg_fft_size_log2;
|
||||
REG_FFT_SCALING_ADDR: m_ctrlport_resp_data <= reg_fft_scaling;
|
||||
REG_FFT_DIRECTION_ADDR: m_ctrlport_resp_data <= reg_fft_direction;
|
||||
REG_CP_INSERTION_CP_LEN_ADDR: m_ctrlport_resp_data <= reg_cp_insertion_len;
|
||||
REG_CP_REMOVAL_CP_LEN_ADDR: m_ctrlport_resp_data <= reg_cp_removal_len;
|
||||
REG_CP_INSERTION_CP_LEN_FIFO_LOAD_ADDR: m_ctrlport_resp_data <= reg_cp_insertion_cp_len_fifo_load;
|
||||
REG_CP_INSERTION_CP_LEN_FIFO_CLR_ADDR: m_ctrlport_resp_data <= reg_cp_insertion_cp_len_fifo_clr;
|
||||
REG_CP_INSERTION_CP_LEN_FIFO_OCC_ADDR: m_ctrlport_resp_data <= reg_cp_insertion_cp_len_fifo_occupied;
|
||||
REG_CP_REMOVAL_CP_LEN_FIFO_LOAD_ADDR: m_ctrlport_resp_data <= reg_cp_removal_cp_len_fifo_load;
|
||||
REG_CP_REMOVAL_CP_LEN_FIFO_CLR_ADDR: m_ctrlport_resp_data <= reg_cp_removal_cp_len_fifo_clr;
|
||||
REG_CP_REMOVAL_CP_LEN_FIFO_OCC_ADDR: m_ctrlport_resp_data <= reg_cp_removal_cp_len_fifo_occupied;
|
||||
default: m_ctrlport_resp_data <= 32'h0BAD_C0DE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// Write user registers
|
||||
if (m_ctrlport_req_wr) begin // Write request
|
||||
m_ctrlport_resp_ack <= 1; // Always immediately ack
|
||||
case (m_ctrlport_req_addr_aligned)
|
||||
REG_USER_RESET_ADDR: reg_user_reset <= 1'b1; // Strobe, i.e. will be cleared on the next clock cycle
|
||||
REG_FFT_SIZE_LOG2_ADDR: reg_fft_size_log2 <= m_ctrlport_req_data[REG_FFT_SIZE_LOG2_WIDTH-1:0];
|
||||
REG_FFT_SCALING_ADDR: reg_fft_scaling <= m_ctrlport_req_data[REG_FFT_SCALING_WIDTH-1:0];
|
||||
REG_FFT_DIRECTION_ADDR: reg_fft_direction <= m_ctrlport_req_data[REG_FFT_DIRECTION_WIDTH-1:0];
|
||||
REG_FFT_COMMIT_ADDR: reg_fft_commit <= 1'b1;
|
||||
REG_CP_INSERTION_CP_LEN_ADDR: reg_cp_insertion_len <= m_ctrlport_req_data[REG_CP_INSERTION_CP_LEN_WIDTH-1:0];
|
||||
REG_CP_REMOVAL_CP_LEN_ADDR: reg_cp_removal_len <= m_ctrlport_req_data[REG_CP_REMOVAL_CP_LEN_WIDTH-1:0];
|
||||
REG_CP_INSERTION_CP_LEN_FIFO_LOAD_ADDR: reg_cp_insertion_cp_len_fifo_load <= 1'b1; // Strobe
|
||||
REG_CP_INSERTION_CP_LEN_FIFO_CLR_ADDR: reg_cp_insertion_cp_len_fifo_clr <= 1'b1; // Strobe
|
||||
REG_CP_REMOVAL_CP_LEN_FIFO_LOAD_ADDR: reg_cp_removal_cp_len_fifo_load <= 1'b1; // Strobe
|
||||
REG_CP_REMOVAL_CP_LEN_FIFO_CLR_ADDR: reg_cp_removal_cp_len_fifo_clr <= 1'b1; // Strobe
|
||||
REG_CP_INSERTION_CP_LEN_FIFO_OCC_ADDR: ; // Read only
|
||||
endcase
|
||||
end
|
||||
if (ctrlport_rst) begin
|
||||
m_ctrlport_resp_ack <= 1'b0;
|
||||
reg_user_reset <= 1'b0;
|
||||
reg_fft_size_log2 <= DEFAULT_FFT_SIZE_LOG2;
|
||||
reg_fft_scaling <= DEFAULT_FFT_SCALING;
|
||||
reg_fft_direction <= DEFAULT_FFT_DIRECTION;
|
||||
reg_fft_commit <= 1'b0;
|
||||
reg_cp_insertion_len <= DEFAULT_CP_LEN;
|
||||
reg_cp_removal_len <= DEFAULT_CP_LEN;
|
||||
reg_cp_insertion_cp_len_fifo_load <= 1'b0;
|
||||
reg_cp_insertion_cp_len_fifo_clr <= 1'b0;
|
||||
reg_cp_removal_cp_len_fifo_load <= 1'b0;
|
||||
reg_cp_removal_cp_len_fifo_clr <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Reset Logic
|
||||
//---------------------------------------------------------------------------
|
||||
localparam RESET_PULSE_LEN = 8;
|
||||
localparam RESET_CNT_WIDTH = $clog2(RESET_PULSE_LEN);
|
||||
|
||||
localparam S_RESET_IDLE = 1'd0;
|
||||
localparam S_RESET_ASSERT = 1'd1;
|
||||
reg reset_state = S_RESET_ASSERT;
|
||||
|
||||
reg [RESET_CNT_WIDTH:0] user_reset_cnt = 'd0;
|
||||
reg user_reset = 1'b1;
|
||||
assign axis_data_rst = user_reset | axis_data_rst_noc_shell;
|
||||
assign ctrlport_rst = user_reset | ctrlport_rst_noc_shell;
|
||||
|
||||
always @(posedge axis_data_clk) begin
|
||||
case (reset_state)
|
||||
S_RESET_IDLE : begin
|
||||
user_reset_cnt <= 'd0;
|
||||
user_reset <= 1'b0;
|
||||
if (reg_user_reset) begin
|
||||
user_reset <= 1'b1;
|
||||
reset_state <= S_RESET_ASSERT;
|
||||
end
|
||||
end
|
||||
S_RESET_ASSERT : begin
|
||||
user_reset_cnt <= user_reset_cnt + 1;
|
||||
if (user_reset_cnt == RESET_PULSE_LEN-1) begin
|
||||
user_reset_cnt <= 'd0;
|
||||
user_reset <= 1'b0;
|
||||
reset_state <= S_RESET_IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
if (axis_data_rst_noc_shell) begin
|
||||
user_reset <= 1'b1;
|
||||
user_reset_cnt <= 'd0;
|
||||
reset_state <= S_RESET_ASSERT;
|
||||
end
|
||||
end
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Packetization
|
||||
//---------------------------------------------------------------------------
|
||||
wire [NUM_PORTS*32*1-1:0] m_axis_user_tdata;
|
||||
wire [NUM_PORTS-1:0] m_axis_user_teob;
|
||||
wire [NUM_PORTS-1:0] m_axis_user_tlast;
|
||||
wire [NUM_PORTS-1:0] m_axis_user_tvalid;
|
||||
wire [NUM_PORTS-1:0] m_axis_user_tready;
|
||||
wire [NUM_PORTS*32*1-1:0] s_axis_user_tdata;
|
||||
wire [NUM_PORTS-1:0] s_axis_user_teob;
|
||||
wire [NUM_PORTS-1:0] s_axis_user_teov;
|
||||
wire [NUM_PORTS-1:0] s_axis_user_tlast;
|
||||
wire [NUM_PORTS-1:0] s_axis_user_tvalid;
|
||||
wire [NUM_PORTS-1:0] s_axis_user_tready;
|
||||
|
||||
for (genvar i = 0; i < NUM_PORTS; i = i + 1) begin : gen_packetize
|
||||
axis_data_if_packetize #(
|
||||
.WIDTH (32),
|
||||
.CHDR_W (CHDR_W),
|
||||
.SIDEBAND_FWD_FIFO_SIZE_LOG2 (1)) // Increase if using many small bursts
|
||||
axis_data_if_packetize_inst (
|
||||
.clk (axis_data_clk),
|
||||
.reset (axis_data_rst),
|
||||
.spp (12'd0), // Use the input packet size
|
||||
.s_axis_tdata (m_in_axis_tdata[32*i +: 32]),
|
||||
.s_axis_tlast (m_in_axis_tlast[i]),
|
||||
.s_axis_tkeep (m_in_axis_tkeep[i]),
|
||||
.s_axis_tvalid (m_in_axis_tvalid[i]),
|
||||
.s_axis_tready (m_in_axis_tready[i]),
|
||||
.s_axis_ttimestamp (m_in_axis_ttimestamp[64*i +: 64]),
|
||||
.s_axis_thas_time (m_in_axis_thas_time[i]),
|
||||
.s_axis_tlength (m_in_axis_tlength[16*i +: 16]),
|
||||
.s_axis_teov (m_in_axis_teov[i]),
|
||||
.s_axis_teob (m_in_axis_teob[i]),
|
||||
.m_axis_tdata (s_out_axis_tdata[32*i +: 32]),
|
||||
.m_axis_tkeep (s_out_axis_tkeep[i]),
|
||||
.m_axis_tlast (s_out_axis_tlast[i]),
|
||||
.m_axis_tvalid (s_out_axis_tvalid[i]),
|
||||
.m_axis_tready (s_out_axis_tready[i]),
|
||||
.m_axis_ttimestamp (s_out_axis_ttimestamp[64*i +: 64]),
|
||||
.m_axis_thas_time (s_out_axis_thas_time[i]),
|
||||
.m_axis_tlength (s_out_axis_tlength[16*i +: 16]),
|
||||
.m_axis_teov (s_out_axis_teov[i]),
|
||||
.m_axis_teob (s_out_axis_teob[i]),
|
||||
.m_axis_user_tdata (m_axis_user_tdata[i*32 +: 32]),
|
||||
.m_axis_user_tkeep (), // Unused
|
||||
.m_axis_user_teob (m_axis_user_teob[i]),
|
||||
.m_axis_user_teov (), // Unused
|
||||
.m_axis_user_tlast (m_axis_user_tlast[i]),
|
||||
.m_axis_user_tvalid (m_axis_user_tvalid[i]),
|
||||
.m_axis_user_tready (m_axis_user_tready[i]),
|
||||
.s_axis_user_tdata (s_axis_user_tdata[i*32 +: 32]),
|
||||
.s_axis_user_tkeep (1'b1), // Keep all samples
|
||||
.s_axis_user_teob (s_axis_user_teob[i]),
|
||||
.s_axis_user_teov (s_axis_user_teov[i]),
|
||||
.s_axis_user_tlast (s_axis_user_tlast[i]),
|
||||
.s_axis_user_tvalid (s_axis_user_tvalid[i]),
|
||||
.s_axis_user_tready (s_axis_user_tready[i])
|
||||
);
|
||||
end
|
||||
|
||||
// Combine input streams into one. This lets us run the FFT instances (one per channel)
|
||||
// in lock-step by sharing valid/ready signals. Removes the need for multiple instances of
|
||||
// FFT configuration logic as well.
|
||||
wire [NUM_PORTS*32-1:0] m_axis_combine_tdata;
|
||||
wire [NUM_PORTS-1:0] m_axis_combine_teob;
|
||||
wire m_axis_combine_tlast;
|
||||
wire m_axis_combine_tvalid;
|
||||
wire m_axis_combine_tready;
|
||||
|
||||
axis_combine #(
|
||||
.SIZE (NUM_PORTS),
|
||||
.WIDTH (32),
|
||||
.USER_WIDTH (1),
|
||||
.FIFO_SIZE_LOG2 (0))
|
||||
axis_combine_inst (
|
||||
.clk (axis_data_clk),
|
||||
.reset (axis_data_rst),
|
||||
.s_axis_tdata (m_axis_user_tdata),
|
||||
.s_axis_tuser (m_axis_user_teob),
|
||||
.s_axis_tlast (m_axis_user_tlast),
|
||||
.s_axis_tvalid (m_axis_user_tvalid),
|
||||
.s_axis_tready (m_axis_user_tready),
|
||||
.m_axis_tdata (m_axis_combine_tdata),
|
||||
.m_axis_tuser (m_axis_combine_teob),
|
||||
.m_axis_tlast (m_axis_combine_tlast),
|
||||
.m_axis_tvalid (m_axis_combine_tvalid),
|
||||
.m_axis_tready (m_axis_combine_tready)
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// FFT
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
wire [NUM_PORTS*32-1:0] m_axis_cp_removal_tdata;
|
||||
wire [NUM_PORTS-1:0] m_axis_cp_removal_teob;
|
||||
wire [NUM_PORTS-1:0] m_axis_cp_removal_teov;
|
||||
wire m_axis_cp_removal_tlast;
|
||||
wire m_axis_cp_removal_tvalid;
|
||||
wire m_axis_cp_removal_tready;
|
||||
wire [FFT_CONFIG_W-1:0] s_axis_fft_config_tdata;
|
||||
wire s_axis_fft_config_tvalid;
|
||||
wire [NUM_PORTS-1:0] s_axis_fft_config_tready;
|
||||
wire [NUM_PORTS*32-1:0] s_axis_fft_data_tdata;
|
||||
wire s_axis_fft_data_tlast;
|
||||
wire s_axis_fft_data_tvalid;
|
||||
wire [NUM_PORTS-1:0] s_axis_fft_data_tready;
|
||||
wire [NUM_PORTS*32-1:0] m_axis_fft_data_tdata;
|
||||
wire [NUM_PORTS-1:0] m_axis_fft_data_tlast;
|
||||
wire [NUM_PORTS-1:0] m_axis_fft_data_tvalid;
|
||||
wire m_axis_fft_data_tready;
|
||||
wire [NUM_PORTS-1:0] event_frame_started;
|
||||
wire [NUM_PORTS-1:0] event_fft_overflow;
|
||||
wire [NUM_PORTS-1:0] event_frame_tlast_unexpected;
|
||||
wire [NUM_PORTS-1:0] event_frame_tlast_missing;
|
||||
wire [NUM_PORTS*32-1:0] s_axis_split_bus_tdata;
|
||||
wire [NUM_PORTS-1:0] s_axis_split_bus_teob;
|
||||
wire [NUM_PORTS-1:0] s_axis_split_bus_teov;
|
||||
wire s_axis_split_bus_tlast;
|
||||
wire s_axis_split_bus_tvalid;
|
||||
wire s_axis_split_bus_tready;
|
||||
|
||||
// Change packet length to FFT size
|
||||
wire [FFT_SIZE_WIDTH-1:0] fft_size = 1 << reg_fft_size_log2[$clog2(FFT_SIZE_WIDTH)-1:0];
|
||||
|
||||
// Clear the commit flag after the FFT has been configured
|
||||
assign reg_fft_commit_next = (s_axis_fft_config_tvalid && s_axis_fft_config_tready) ?
|
||||
1'b0 : reg_fft_commit;
|
||||
|
||||
integer dbg_removal_in_counter = 0, dbg_removal_out_counter = 0;
|
||||
integer dbg_removal_in_length, dbg_removal_out_length;
|
||||
reg dbg_removal_in_eop, dbg_removal_out_eop;
|
||||
always @(posedge axis_data_clk) begin
|
||||
if (m_axis_combine_tvalid && m_axis_combine_tready) begin
|
||||
if (m_axis_combine_tlast && m_axis_combine_teob) begin
|
||||
dbg_removal_in_counter <= 0;
|
||||
dbg_removal_in_eop <= 1;
|
||||
dbg_removal_in_length <= dbg_removal_in_counter+1;
|
||||
end else begin
|
||||
dbg_removal_in_eop <= 0;
|
||||
dbg_removal_in_counter <= dbg_removal_in_counter + 1;
|
||||
end
|
||||
end
|
||||
if (m_axis_cp_removal_tvalid && m_axis_cp_removal_tready) begin
|
||||
if (m_axis_cp_removal_tlast) begin
|
||||
dbg_removal_out_counter <= 0;
|
||||
dbg_removal_out_eop <= 1;
|
||||
dbg_removal_out_length <= dbg_removal_out_counter+1;
|
||||
end else begin
|
||||
dbg_removal_out_eop <= 0;
|
||||
dbg_removal_out_counter <= dbg_removal_out_counter + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Remove cyclic prefix
|
||||
// Also sets the packet size (i.e. tlast) to the FFT size
|
||||
axis_ofdm_cyclic_prefix_removal #(
|
||||
.WIDTH (NUM_PORTS*32),
|
||||
.USER_WIDTH (NUM_PORTS),
|
||||
.MAX_CP_LEN_LOG2 (CP_LEN_WIDTH),
|
||||
.MAX_FFT_SIZE_LOG2 (FFT_SIZE_WIDTH),
|
||||
.DEFAULT_CP_LEN (DEFAULT_CP_LEN),
|
||||
.CP_LEN_FIFO_MODE (CP_REMOVAL_REPEAT),
|
||||
.CP_LEN_FIFO_SIZE_LOG2 (MAX_CP_LIST_LEN_REM_LOG2),
|
||||
.SET_TLAST (1))
|
||||
axis_ofdm_cyclic_prefix_removal_inst (
|
||||
.clk (axis_data_clk),
|
||||
.reset (axis_data_rst),
|
||||
.clear_fifo (reg_cp_removal_cp_len_fifo_clr),
|
||||
.fft_size (fft_size),
|
||||
.m_axis_cp_len_tdata (reg_cp_removal_len),
|
||||
.m_axis_cp_len_tvalid (reg_cp_removal_cp_len_fifo_load),
|
||||
// No backpressure needed as the block controller checks "cp_len_fifo_occupied"
|
||||
// before writing to avoid overflowing FIFO
|
||||
.m_axis_cp_len_tready (),
|
||||
.cp_len_fifo_occupied (reg_cp_removal_cp_len_fifo_occupied),
|
||||
.s_axis_data_tdata (m_axis_combine_tdata),
|
||||
.s_axis_data_tuser (m_axis_combine_teob),
|
||||
.s_axis_data_tlast (m_axis_combine_tlast),
|
||||
.s_axis_data_tvalid (m_axis_combine_tvalid),
|
||||
.s_axis_data_tready (m_axis_combine_tready),
|
||||
.m_axis_data_tdata (m_axis_cp_removal_tdata),
|
||||
.m_axis_data_tuser (m_axis_cp_removal_teob),
|
||||
.m_axis_data_tlast (m_axis_cp_removal_tlast),
|
||||
.m_axis_data_tvalid (m_axis_cp_removal_tvalid),
|
||||
.m_axis_data_tready (m_axis_cp_removal_tready)
|
||||
);
|
||||
// We can create a teov from tlast because the packet size is the same as the FFT size
|
||||
assign m_axis_cp_removal_teov = {(NUM_PORTS){m_axis_cp_removal_tlast}};
|
||||
|
||||
// Below is a FIFO for a configurable cyclic prefix length list that cycles until
|
||||
// the FIFO is cleared. This allows the cyclic prefix length to dynamically change
|
||||
// at runtime on a FFT by FFT basis up to the depth of the FIFO.
|
||||
// For example:
|
||||
// - User writes 32, 64, 128 into the FIFO
|
||||
// - FFT cyclic prefix length will be configured in the following order:
|
||||
// 32, 64, 128, 32, 64, 128, etc until FIFO is cleared
|
||||
// Example #2:
|
||||
// - User writes 32 into FIFO
|
||||
// - FFT cyclic prefix length will be 32 until FIFO is cleared
|
||||
//
|
||||
// If the FIFO does not have any entries, cylic prefix length defaults to
|
||||
// CP_LEN_DEFAULT (see FFT configuration state machine below).
|
||||
// User should generally not load or clear the FIFO while streaming, but the logic
|
||||
// does not prevent it.
|
||||
//
|
||||
wire [CP_LEN_WIDTH-1:0] s_axis_cp_len_fifo_tdata;
|
||||
wire s_axis_cp_len_fifo_tvalid;
|
||||
wire [CP_LEN_WIDTH-1:0] m_axis_cp_len_fifo_tdata;
|
||||
wire m_axis_cp_len_fifo_tvalid;
|
||||
wire m_axis_cp_len_fifo_tready;
|
||||
wire cp_len_fifo_empty = (reg_cp_insertion_cp_len_fifo_occupied == 0);
|
||||
|
||||
axi_fifo #(
|
||||
.WIDTH (CP_LEN_WIDTH),
|
||||
.SIZE (MAX_CP_LIST_LEN_INS_LOG2))
|
||||
axi_fifo_cp_insertion_cp_len_inst (
|
||||
.clk (axis_data_clk),
|
||||
.reset (axis_data_rst),
|
||||
.clear (reg_cp_insertion_cp_len_fifo_clr),
|
||||
.i_tdata (s_axis_cp_len_fifo_tdata),
|
||||
.i_tvalid (s_axis_cp_len_fifo_tvalid),
|
||||
.i_tready (/* No backpressure needed as block controller checks cp_len_fifo_occupied to not overflow FIFO */),
|
||||
.o_tdata (m_axis_cp_len_fifo_tdata),
|
||||
.o_tvalid (m_axis_cp_len_fifo_tvalid), // Unused
|
||||
.o_tready (m_axis_cp_len_fifo_tready),
|
||||
.space (),
|
||||
.occupied (reg_cp_insertion_cp_len_fifo_occupied)
|
||||
);
|
||||
|
||||
// FFT IP configuration state machine
|
||||
// Loads a new configuration at the start of every FFT
|
||||
localparam S_FFT_CONFIG = 1'd0;
|
||||
localparam S_FFT_WAIT_FOR_TLAST = 1'd1;
|
||||
reg fft_config_state = S_FFT_CONFIG;
|
||||
|
||||
always @(posedge axis_data_clk) begin
|
||||
case (fft_config_state)
|
||||
S_FFT_CONFIG: begin
|
||||
if (s_axis_fft_data_tvalid & s_axis_fft_data_tready[0]) begin
|
||||
fft_config_state <= S_FFT_WAIT_FOR_TLAST;
|
||||
end
|
||||
end
|
||||
S_FFT_WAIT_FOR_TLAST: begin
|
||||
if (s_axis_fft_data_tvalid & s_axis_fft_data_tready[0] & s_axis_fft_data_tlast) begin
|
||||
fft_config_state <= S_FFT_CONFIG;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
if (axis_data_rst) begin
|
||||
fft_config_state <= S_FFT_CONFIG;
|
||||
end
|
||||
end
|
||||
|
||||
assign s_axis_fft_config_tdata = {
|
||||
{FFT_SCALE_PAD_W{1'b0}},
|
||||
reg_fft_scaling,
|
||||
reg_fft_direction,
|
||||
{FFT_CP_LEN_PAD_W{1'b0}},
|
||||
FFT_CP_LEN_W'(cp_len_fifo_empty ? DEFAULT_CP_LEN : m_axis_cp_len_fifo_tdata),
|
||||
{FFT_NFFT_PAD_W{1'b0}},
|
||||
reg_fft_size_log2
|
||||
};
|
||||
|
||||
//assign s_axis_fft_config_tdata[47:41] = '0;
|
||||
//assign s_axis_fft_config_tdata[40:25] = reg_fft_scaling;
|
||||
//assign s_axis_fft_config_tdata[24] = reg_fft_direction;
|
||||
//assign s_axis_fft_config_tdata[23] = '0;
|
||||
//assign s_axis_fft_config_tdata[22:8] = FFT_CP_LEN_W'(cp_len_fifo_empty ? DEFAULT_CP_LEN : m_axis_cp_len_fifo_tdata);
|
||||
//assign s_axis_fft_config_tdata[7:5] = '0;
|
||||
//assign s_axis_fft_config_tdata[4:0] = reg_fft_size_log2;
|
||||
|
||||
|
||||
//assign s_axis_fft_config_tvalid = reg_fft_commit;
|
||||
assign s_axis_fft_config_tvalid = (fft_config_state == S_FFT_CONFIG) ? s_axis_fft_data_tvalid : 1'b0;
|
||||
|
||||
// No cyclic prefix fifo loopback. New configs can be written at any time.
|
||||
if (CP_INSERTION_REPEAT == 0) begin : gen_cp_ins_repeat
|
||||
assign s_axis_cp_len_fifo_tdata = reg_cp_insertion_len;
|
||||
assign s_axis_cp_len_fifo_tvalid = reg_cp_insertion_cp_len_fifo_load;
|
||||
//assign m_axis_cp_len_fifo_tready = s_axis_fft_config_tvalid & s_axis_fft_config_tready[0];
|
||||
assign m_axis_cp_len_fifo_tready = (fft_config_state == S_FFT_CONFIG) & s_axis_fft_config_tvalid & s_axis_fft_config_tready[0];
|
||||
// Cyclic prefix fifo fifo loopback enabled, writes current cp length back into fifo in the S_FFT_CONFIG_LOAD state.
|
||||
// New cp lengths can only be written in the S_FFT_CONFIG_IDLE state.
|
||||
end else begin : gen_cp_ins_no_repeat
|
||||
assign s_axis_cp_len_fifo_tdata = reg_cp_insertion_cp_len_fifo_load ? reg_cp_insertion_len : m_axis_cp_len_fifo_tdata;
|
||||
assign s_axis_cp_len_fifo_tvalid =
|
||||
(m_axis_cp_len_fifo_tvalid & (s_axis_fft_config_tvalid & s_axis_fft_config_tready[0])) |
|
||||
reg_cp_insertion_cp_len_fifo_load;
|
||||
assign m_axis_cp_len_fifo_tready = s_axis_fft_config_tvalid & s_axis_fft_config_tready[0];
|
||||
end
|
||||
|
||||
// Xilinx FFT IP lacks a pass-through tuser signal so this adds one for our EOB signal
|
||||
axis_sideband_tuser #(
|
||||
.WIDTH (NUM_PORTS*32),
|
||||
.USER_WIDTH (2*NUM_PORTS),
|
||||
.FIFO_SIZE_LOG2 (5),
|
||||
.PACKET_MODE (2)) // tuser is EOB and static for the entire packet,
|
||||
// so we can use this more effecient packet mode
|
||||
axis_sideband_xfft_tuser (
|
||||
.clk (axis_data_clk),
|
||||
.reset (axis_data_rst),
|
||||
// Input bus with a tuser signal
|
||||
.s_axis_tdata (m_axis_cp_removal_tdata),
|
||||
.s_axis_tuser ({m_axis_cp_removal_teob, m_axis_cp_removal_teov}),
|
||||
.s_axis_tlast (m_axis_cp_removal_tlast),
|
||||
.s_axis_tvalid (m_axis_cp_removal_tvalid),
|
||||
.s_axis_tready (m_axis_cp_removal_tready),
|
||||
// To/from our module, i.e. Xilinx FFT, but without the tuser signal.
|
||||
// This modules keeps track of the tuser signal values internally
|
||||
// and will automatically add them back to the output stream.
|
||||
.m_axis_mod_tdata (s_axis_fft_data_tdata),
|
||||
.m_axis_mod_tlast (s_axis_fft_data_tlast),
|
||||
.m_axis_mod_tvalid (s_axis_fft_data_tvalid),
|
||||
.m_axis_mod_tready (s_axis_fft_data_tready[0]),
|
||||
.s_axis_mod_tdata (m_axis_fft_data_tdata),
|
||||
.s_axis_mod_tlast (m_axis_fft_data_tlast[0]),
|
||||
.s_axis_mod_tvalid (m_axis_fft_data_tvalid[0]),
|
||||
.s_axis_mod_tready (m_axis_fft_data_tready),
|
||||
// Output bus, i.e. Xilinx FFT output stream, but with the tuser from the input added on
|
||||
.m_axis_tdata (s_axis_split_bus_tdata),
|
||||
.m_axis_tuser ({s_axis_split_bus_teob, s_axis_split_bus_teov}),
|
||||
.m_axis_tlast (s_axis_split_bus_tlast),
|
||||
.m_axis_tvalid (s_axis_split_bus_tvalid),
|
||||
.m_axis_tready (s_axis_split_bus_tready)
|
||||
);
|
||||
|
||||
integer dbg_fft_in_counter = 0, dbg_fft_out_counter = 0;
|
||||
integer dbg_fft_in_length, dbg_fft_out_length;
|
||||
reg dbg_fft_in_eop, dbg_fft_out_eop;
|
||||
genvar i;
|
||||
for (i = 0; i < NUM_PORTS; i = i + 1) begin : gen_fft
|
||||
|
||||
always @(posedge axis_data_clk) begin
|
||||
if (s_axis_fft_data_tvalid && s_axis_fft_data_tready) begin
|
||||
if (s_axis_fft_data_tlast) begin
|
||||
dbg_fft_in_counter <= 0;
|
||||
dbg_fft_in_eop <= 1;
|
||||
dbg_fft_in_length <= dbg_fft_in_counter+1;
|
||||
end else begin
|
||||
dbg_fft_in_eop <= 0;
|
||||
dbg_fft_in_counter <= dbg_fft_in_counter + 1;
|
||||
end
|
||||
end
|
||||
|
||||
if (m_axis_fft_data_tvalid[i] && m_axis_fft_data_tready) begin
|
||||
if (m_axis_fft_data_tlast[i]) begin
|
||||
dbg_fft_out_counter <= 0;
|
||||
dbg_fft_out_eop <= 1;
|
||||
dbg_fft_out_length <= dbg_fft_out_counter+1;
|
||||
end else begin
|
||||
dbg_fft_out_eop <= 0;
|
||||
dbg_fft_out_counter <= dbg_fft_out_counter + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (MAX_FFT_SIZE == 4096) begin : gen_4k_FFT
|
||||
xfft_4k_16b xfft_4k_16b_i (
|
||||
.aclk (axis_data_clk),
|
||||
.aresetn (~axis_data_rst),
|
||||
.s_axis_config_tdata (s_axis_fft_config_tdata),
|
||||
.s_axis_config_tvalid (s_axis_fft_config_tvalid),
|
||||
.s_axis_config_tready (s_axis_fft_config_tready[i]),
|
||||
.s_axis_data_tdata ({ s_axis_fft_data_tdata[32*i +: 16], s_axis_fft_data_tdata[32*i+16 +: 16] }),
|
||||
.s_axis_data_tlast (s_axis_fft_data_tlast),
|
||||
.s_axis_data_tvalid (s_axis_fft_data_tvalid),
|
||||
.s_axis_data_tready (s_axis_fft_data_tready[i]),
|
||||
.m_axis_data_tdata ({ m_axis_fft_data_tdata[32*i +: 16], m_axis_fft_data_tdata[32*i+16 +: 16] }),
|
||||
.m_axis_data_tuser (),
|
||||
.m_axis_data_tlast (m_axis_fft_data_tlast[i]),
|
||||
.m_axis_data_tvalid (m_axis_fft_data_tvalid[i]),
|
||||
.m_axis_data_tready (m_axis_fft_data_tready),
|
||||
.m_axis_status_tdata (),
|
||||
.m_axis_status_tvalid (),
|
||||
.m_axis_status_tready (1'b1),
|
||||
.event_frame_started (event_frame_started[i]),
|
||||
.event_tlast_unexpected (event_frame_tlast_unexpected[i]),
|
||||
.event_tlast_missing (event_frame_tlast_missing[i]),
|
||||
.event_fft_overflow (event_fft_overflow[i]),
|
||||
.event_status_channel_halt (),
|
||||
.event_data_in_channel_halt (),
|
||||
.event_data_out_channel_halt ()
|
||||
);
|
||||
end else if (MAX_FFT_SIZE == 8192) begin : gen_8k_fft
|
||||
xfft_8k_16b xfft_8k_16b_i (
|
||||
.aclk (axis_data_clk),
|
||||
.aresetn (~axis_data_rst),
|
||||
.s_axis_config_tdata (s_axis_fft_config_tdata),
|
||||
.s_axis_config_tvalid (s_axis_fft_config_tvalid),
|
||||
.s_axis_config_tready (s_axis_fft_config_tready[i]),
|
||||
.s_axis_data_tdata ({ s_axis_fft_data_tdata[32*i +: 16], s_axis_fft_data_tdata[32*i+16 +: 16] }),
|
||||
.s_axis_data_tlast (s_axis_fft_data_tlast),
|
||||
.s_axis_data_tvalid (s_axis_fft_data_tvalid),
|
||||
.s_axis_data_tready (s_axis_fft_data_tready[i]),
|
||||
.m_axis_data_tdata ({ m_axis_fft_data_tdata[32*i +: 16], m_axis_fft_data_tdata[32*i+16 +: 16] }),
|
||||
.m_axis_data_tuser (),
|
||||
.m_axis_data_tlast (m_axis_fft_data_tlast[i]),
|
||||
.m_axis_data_tvalid (m_axis_fft_data_tvalid[i]),
|
||||
.m_axis_data_tready (m_axis_fft_data_tready),
|
||||
.m_axis_status_tdata (),
|
||||
.m_axis_status_tvalid (),
|
||||
.m_axis_status_tready (1'b1),
|
||||
.event_frame_started (event_frame_started[i]),
|
||||
.event_tlast_unexpected (event_frame_tlast_unexpected[i]),
|
||||
.event_tlast_missing (event_frame_tlast_missing[i]),
|
||||
.event_fft_overflow (event_fft_overflow[i]),
|
||||
.event_status_channel_halt (),
|
||||
.event_data_in_channel_halt (),
|
||||
.event_data_out_channel_halt ()
|
||||
);
|
||||
end else if (MAX_FFT_SIZE == 32768) begin : gen_32k_fft
|
||||
xfft_32k_16b xfft_32k_16b_i (
|
||||
.aclk (axis_data_clk),
|
||||
.aresetn (~axis_data_rst),
|
||||
.s_axis_config_tdata (s_axis_fft_config_tdata),
|
||||
.s_axis_config_tvalid (s_axis_fft_config_tvalid),
|
||||
.s_axis_config_tready (s_axis_fft_config_tready[i]),
|
||||
.s_axis_data_tdata ({ s_axis_fft_data_tdata[32*i +: 16], s_axis_fft_data_tdata[32*i+16 +: 16] }),
|
||||
.s_axis_data_tlast (s_axis_fft_data_tlast),
|
||||
.s_axis_data_tvalid (s_axis_fft_data_tvalid),
|
||||
.s_axis_data_tready (s_axis_fft_data_tready[i]),
|
||||
.m_axis_data_tdata ({ m_axis_fft_data_tdata[32*i +: 16], m_axis_fft_data_tdata[32*i+16 +: 16] }),
|
||||
.m_axis_data_tuser (),
|
||||
.m_axis_data_tlast (m_axis_fft_data_tlast[i]),
|
||||
.m_axis_data_tvalid (m_axis_fft_data_tvalid[i]),
|
||||
.m_axis_data_tready (m_axis_fft_data_tready),
|
||||
.m_axis_status_tdata (),
|
||||
.m_axis_status_tvalid (),
|
||||
.m_axis_status_tready (1'b1),
|
||||
.event_frame_started (event_frame_started[i]),
|
||||
.event_tlast_unexpected (event_frame_tlast_unexpected[i]),
|
||||
.event_tlast_missing (event_frame_tlast_missing[i]),
|
||||
.event_fft_overflow (event_fft_overflow[i]),
|
||||
.event_status_channel_halt (),
|
||||
.event_data_in_channel_halt (),
|
||||
.event_data_out_channel_halt ()
|
||||
);
|
||||
end
|
||||
end
|
||||
|
||||
// Split back into multiple streams
|
||||
axis_split_bus #(
|
||||
.WIDTH (32),
|
||||
.USER_WIDTH (2),
|
||||
.NUM_PORTS (NUM_PORTS))
|
||||
axis_split_bus_inst (
|
||||
.clk (axis_data_clk),
|
||||
.reset (axis_data_rst),
|
||||
.s_axis_tdata (s_axis_split_bus_tdata),
|
||||
.s_axis_tuser ({s_axis_split_bus_teob, s_axis_split_bus_teov}),
|
||||
.s_axis_tlast (s_axis_split_bus_tlast),
|
||||
.s_axis_tvalid (s_axis_split_bus_tvalid),
|
||||
.s_axis_tready (s_axis_split_bus_tready),
|
||||
.m_axis_tdata (s_axis_user_tdata),
|
||||
.m_axis_tuser ({s_axis_user_teob, s_axis_user_teov}),
|
||||
.m_axis_tlast (s_axis_user_tlast),
|
||||
.m_axis_tvalid (s_axis_user_tvalid),
|
||||
.m_axis_tready (s_axis_user_tready)
|
||||
);
|
||||
|
||||
/*
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS*32*1-1:0] m_in_axis_tdata_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] m_in_axis_tlast_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] m_in_axis_tvalid_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] m_in_axis_tready_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS*32*1-1:0] s_out_axis_tdata_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] s_out_axis_tlast_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] s_out_axis_tvalid_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] s_out_axis_tready_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [32-1:0] m_axis_combine_tdata_debug[0:NUM_PORTS-1];
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] m_axis_combine_teob_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg m_axis_combine_tlast_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg m_axis_combine_tvalid_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg m_axis_combine_tready_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [32-1:0] m_axis_cp_removal_tdata_debug[0:NUM_PORTS-1];
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] m_axis_cp_removal_teob_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg m_axis_cp_removal_tlast_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg m_axis_cp_removal_tvalid_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg m_axis_cp_removal_tready_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [32-1:0] s_axis_fft_data_tdata_debug[0:NUM_PORTS-1];
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg s_axis_fft_data_tlast_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg s_axis_fft_data_tvalid_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] s_axis_fft_data_tready_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [32-1:0] m_axis_fft_data_tdata_debug[0:NUM_PORTS-1];
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] m_axis_fft_data_tlast_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] m_axis_fft_data_tvalid_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg m_axis_fft_data_tready_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] event_frame_started_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] event_fft_overflow_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] event_frame_tlast_unexpected_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] event_frame_tlast_missing_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [32-1:0] s_axis_split_bus_tdata_debug[0:NUM_PORTS-1];
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] s_axis_split_bus_teob_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg s_axis_split_bus_tlast_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg s_axis_split_bus_tvalid_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg s_axis_split_bus_tready_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [CP_LEN_WIDTH-1:0] m_axis_cp_len_fifo_tdata_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg m_axis_cp_len_fifo_tvalid_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg m_axis_cp_len_fifo_tready_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [FFT_SIZE_WIDTH-1:0] fft_size_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [39:0] s_axis_fft_config_tdata_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg s_axis_fft_config_tvalid_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg [NUM_PORTS-1:0] s_axis_fft_config_tready_debug;
|
||||
(* dont_touch = "true", mark_debug = "true"*) reg fft_config_state_debug;
|
||||
|
||||
always @(posedge axis_data_clk) begin
|
||||
m_in_axis_tdata_debug <= m_in_axis_tdata;
|
||||
m_in_axis_tlast_debug <= m_in_axis_tlast;
|
||||
m_in_axis_tvalid_debug <= m_in_axis_tvalid;
|
||||
m_in_axis_tready_debug <= m_in_axis_tready;
|
||||
s_out_axis_tdata_debug <= s_out_axis_tdata;
|
||||
s_out_axis_tlast_debug <= s_out_axis_tlast;
|
||||
s_out_axis_tvalid_debug <= s_out_axis_tvalid;
|
||||
s_out_axis_tready_debug <= s_out_axis_tready;
|
||||
{m_axis_combine_tdata_debug[1],m_axis_combine_tdata_debug[0]} <= m_axis_combine_tdata;
|
||||
m_axis_combine_teob_debug <= m_axis_combine_teob;
|
||||
m_axis_combine_tlast_debug <= m_axis_combine_tlast;
|
||||
m_axis_combine_tvalid_debug <= m_axis_combine_tvalid;
|
||||
m_axis_combine_tready_debug <= m_axis_combine_tready;
|
||||
{m_axis_cp_removal_tdata_debug[1],m_axis_cp_removal_tdata_debug[0]} <= m_axis_cp_removal_tdata;
|
||||
m_axis_cp_removal_teob_debug <= m_axis_cp_removal_teob;
|
||||
m_axis_cp_removal_tlast_debug <= m_axis_cp_removal_tlast;
|
||||
m_axis_cp_removal_tvalid_debug <= m_axis_cp_removal_tvalid;
|
||||
m_axis_cp_removal_tready_debug <= m_axis_cp_removal_tready;
|
||||
{s_axis_fft_data_tdata_debug[1],s_axis_fft_data_tdata_debug[0]} <= s_axis_fft_data_tdata;
|
||||
s_axis_fft_data_tlast_debug <= s_axis_fft_data_tlast;
|
||||
s_axis_fft_data_tvalid_debug <= s_axis_fft_data_tvalid;
|
||||
s_axis_fft_data_tready_debug <= s_axis_fft_data_tready;
|
||||
{m_axis_fft_data_tdata_debug[1],m_axis_fft_data_tdata_debug[0]} <= m_axis_fft_data_tdata;
|
||||
m_axis_fft_data_tlast_debug <= m_axis_fft_data_tlast;
|
||||
m_axis_fft_data_tvalid_debug <= m_axis_fft_data_tvalid;
|
||||
m_axis_fft_data_tready_debug <= m_axis_fft_data_tready;
|
||||
event_frame_started_debug <= event_frame_started;
|
||||
event_fft_overflow_debug <= event_fft_overflow;
|
||||
event_frame_tlast_unexpected_debug <= event_frame_tlast_unexpected;
|
||||
event_frame_tlast_missing_debug <= event_frame_tlast_missing;
|
||||
{s_axis_split_bus_tdata_debug[1],s_axis_split_bus_tdata_debug[0]} <= s_axis_split_bus_tdata;
|
||||
s_axis_split_bus_teob_debug <= s_axis_split_bus_teob;
|
||||
s_axis_split_bus_tlast_debug <= s_axis_split_bus_tlast;
|
||||
s_axis_split_bus_tvalid_debug <= s_axis_split_bus_tvalid;
|
||||
s_axis_split_bus_tready_debug <= s_axis_split_bus_tready;
|
||||
m_axis_cp_len_fifo_tdata_debug <= m_axis_cp_len_fifo_tdata;
|
||||
m_axis_cp_len_fifo_tvalid_debug <= m_axis_cp_len_fifo_tvalid;
|
||||
m_axis_cp_len_fifo_tready_debug <= m_axis_cp_len_fifo_tready;
|
||||
fft_size_debug <= fft_size;
|
||||
s_axis_fft_config_tdata_debug <= s_axis_fft_config_tdata;
|
||||
s_axis_fft_config_tvalid_debug <= s_axis_fft_config_tvalid;
|
||||
s_axis_fft_config_tready_debug <= s_axis_fft_config_tready;
|
||||
fft_config_state_debug <= fft_config_state;
|
||||
end
|
||||
*/
|
||||
endmodule : rfnoc_block_ofdm
|
||||
|
||||
`default_nettype wire
|
||||
1135
fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ofdm/rfnoc_block_ofdm_tb.sv
Normal file
1135
fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ofdm/rfnoc_block_ofdm_tb.sv
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user