fpga: rfnoc: Add RFNoC Replay block

Original-commit: 6d92a1828121ca4b57d496bbf522820f961244b9
This commit is contained in:
Wade Fife
2020-08-04 15:40:08 -05:00
committed by Aaron Rossetto
parent b4fed123c8
commit 104a73e623
11 changed files with 4101 additions and 875 deletions
@@ -0,0 +1,45 @@
#
# Copyright 2020 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_preamble after defining BASE_DIR
include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
#-------------------------------------------------
# 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_UTIL_SRCS) \
$(RFNOC_OOT_SRCS) \
)
#-------------------------------------------------
# Testbench Specific
#-------------------------------------------------
SIM_TOP = rfnoc_block_replay_all_tb
SIM_SRCS = \
$(abspath ../rfnoc_block_axi_ram_fifo/sim_axi_ram.sv) \
$(abspath rfnoc_block_replay_tb.sv) \
$(abspath rfnoc_block_replay_all_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
@@ -0,0 +1,24 @@
#
# Copyright 2020 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)))), \
rfnoc_block_replay_regs.vh \
axis_replay.v \
noc_shell_replay.v \
rfnoc_block_replay.v \
)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,306 @@
//
// Copyright 2020 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: noc_shell_replay
//
// Description:
//
// This is a tool-generated NoC-shell for the replay 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
//
`default_nettype none
module noc_shell_replay #(
parameter [9:0] THIS_PORTID = 10'd0,
parameter CHDR_W = 64,
parameter [5:0] MTU = 10,
parameter NUM_PORTS = 2,
parameter MEM_DATA_W = 64,
parameter MEM_ADDR_W = 30
) (
//---------------------
// Framework Interface
//---------------------
// RFNoC Framework Clocks
input wire rfnoc_chdr_clk,
input wire rfnoc_ctrl_clk,
input wire mem_clk,
// NoC Shell Generated Resets
output wire rfnoc_chdr_rst,
output wire rfnoc_ctrl_rst,
output wire mem_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*MEM_DATA_W/32-1:0] m_in_axis_tdata,
output wire [NUM_PORTS*MEM_DATA_W/32-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 to User Logic: out
input wire [NUM_PORTS*32*MEM_DATA_W/32-1:0] s_out_axis_tdata,
input wire [NUM_PORTS*MEM_DATA_W/32-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'h4E91A000),
.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 mem_rst_pulse;
pulse_synchronizer #(.MODE ("POSEDGE")) pulse_synchronizer_mem (
.clk_a(rfnoc_chdr_clk), .rst_a(1'b0), .pulse_a (rfnoc_chdr_rst), .busy_a (),
.clk_b(mem_clk), .pulse_b (mem_rst_pulse)
);
pulse_stretch_min #(.LENGTH(32)) pulse_stretch_min_mem (
.clk(mem_clk), .rst(1'b0),
.pulse_in(mem_rst_pulse), .pulse_out(mem_rst)
);
//---------------------------------------------------------------------------
// Control Path
//---------------------------------------------------------------------------
assign ctrlport_clk = mem_clk;
assign ctrlport_rst = mem_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 = mem_clk;
assign axis_data_rst = mem_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 (MEM_DATA_W/32),
.SYNC_CLKS (0),
.INFO_FIFO_SIZE ($clog2(32)),
.PYLD_FIFO_SIZE ($clog2(MTU))
) 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*MEM_DATA_W/32)*i+:(32*MEM_DATA_W/32)]),
.m_axis_tkeep (m_in_axis_tkeep[MEM_DATA_W/32*i+:MEM_DATA_W/32]),
.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 (MEM_DATA_W/32),
.SYNC_CLKS (0),
.INFO_FIFO_SIZE ($clog2(32)),
.PYLD_FIFO_SIZE ($clog2(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*MEM_DATA_W/32)*i+:(32*MEM_DATA_W/32)]),
.s_axis_tkeep (s_out_axis_tkeep[MEM_DATA_W/32*i+:MEM_DATA_W/32]),
.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_replay
`default_nettype wire
@@ -0,0 +1,518 @@
//
// Copyright 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: rfnoc_block_replay
//
// Description:
//
// RFNoC data record and playback block. This block has the ability to
// capture all of the data that is sent to it and store it into an attached
// memory using an AXI memory-mapped interface. It can then play back any
// part of the data on demand or continuously. Timed playback is also
// supported. See axis_replay.v for details of replay operation.
//
// 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).
// NUM_PORTS : Number of replay instances to instantiate. Each one will
// have its own register set and memory interface.
// MEM_DATA_W : Data width to use for the memory interface.
// MEM_ADDR_W : Byte address width to use for the memory interface.
//
`default_nettype none
module rfnoc_block_replay #(
parameter [9:0] THIS_PORTID = 10'd0,
parameter CHDR_W = 64,
parameter [5:0] MTU = 10,
parameter NUM_PORTS = 1,
parameter MEM_DATA_W = 64,
parameter MEM_ADDR_W = 30
) (
//---------------------------------------------------------------------------
// AXIS-CHDR Port
//---------------------------------------------------------------------------
// RFNoC Framework Clocks and Resets
input wire rfnoc_chdr_clk,
// 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,
// RFNoC Backend Interface
input wire [511:0] rfnoc_core_config,
output wire [511:0] rfnoc_core_status,
//---------------------------------------------------------------------------
// AXIS-Ctrl Port
//---------------------------------------------------------------------------
input wire rfnoc_ctrl_clk,
// 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,
//---------------------------------------------------------------------------
// AXI Memory Mapped Interface
//---------------------------------------------------------------------------
// AXI Interface Clock and Reset
input wire mem_clk,
input wire axi_rst,
// AXI Write address channel
output wire [ (NUM_PORTS*1)-1:0] m_axi_awid,
output wire [ (NUM_PORTS*MEM_ADDR_W)-1:0] m_axi_awaddr,
output wire [ (NUM_PORTS*8)-1:0] m_axi_awlen,
output wire [ (NUM_PORTS*3)-1:0] m_axi_awsize,
output wire [ (NUM_PORTS*2)-1:0] m_axi_awburst,
output wire [ (NUM_PORTS*1)-1:0] m_axi_awlock,
output wire [ (NUM_PORTS*4)-1:0] m_axi_awcache,
output wire [ (NUM_PORTS*3)-1:0] m_axi_awprot,
output wire [ (NUM_PORTS*4)-1:0] m_axi_awqos,
output wire [ (NUM_PORTS*4)-1:0] m_axi_awregion,
output wire [ (NUM_PORTS*1)-1:0] m_axi_awuser,
output wire [ (NUM_PORTS*1)-1:0] m_axi_awvalid,
input wire [ (NUM_PORTS*1)-1:0] m_axi_awready,
// AXI Write data channel
output wire [ (NUM_PORTS*MEM_DATA_W)-1:0] m_axi_wdata,
output wire [(NUM_PORTS*MEM_DATA_W/8)-1:0] m_axi_wstrb,
output wire [ (NUM_PORTS*1)-1:0] m_axi_wlast,
output wire [ (NUM_PORTS*1)-1:0] m_axi_wuser,
output wire [ (NUM_PORTS*1)-1:0] m_axi_wvalid,
input wire [ (NUM_PORTS*1)-1:0] m_axi_wready,
// AXI Write response channel signals
input wire [ (NUM_PORTS*1)-1:0] m_axi_bid,
input wire [ (NUM_PORTS*2)-1:0] m_axi_bresp,
input wire [ (NUM_PORTS*1)-1:0] m_axi_buser,
input wire [ (NUM_PORTS*1)-1:0] m_axi_bvalid,
output wire [ (NUM_PORTS*1)-1:0] m_axi_bready,
// AXI Read address channel
output wire [ (NUM_PORTS*1)-1:0] m_axi_arid,
output wire [ (NUM_PORTS*MEM_ADDR_W)-1:0] m_axi_araddr,
output wire [ (NUM_PORTS*8)-1:0] m_axi_arlen,
output wire [ (NUM_PORTS*3)-1:0] m_axi_arsize,
output wire [ (NUM_PORTS*2)-1:0] m_axi_arburst,
output wire [ (NUM_PORTS*1)-1:0] m_axi_arlock,
output wire [ (NUM_PORTS*4)-1:0] m_axi_arcache,
output wire [ (NUM_PORTS*3)-1:0] m_axi_arprot,
output wire [ (NUM_PORTS*4)-1:0] m_axi_arqos,
output wire [ (NUM_PORTS*4)-1:0] m_axi_arregion,
output wire [ (NUM_PORTS*1)-1:0] m_axi_aruser,
output wire [ (NUM_PORTS*1)-1:0] m_axi_arvalid,
input wire [ (NUM_PORTS*1)-1:0] m_axi_arready,
// AXI Read data channel
input wire [ (NUM_PORTS*1)-1:0] m_axi_rid,
input wire [ (NUM_PORTS*MEM_DATA_W)-1:0] m_axi_rdata,
input wire [ (NUM_PORTS*2)-1:0] m_axi_rresp,
input wire [ (NUM_PORTS*1)-1:0] m_axi_rlast,
input wire [ (NUM_PORTS*1)-1:0] m_axi_ruser,
input wire [ (NUM_PORTS*1)-1:0] m_axi_rvalid,
output wire [ (NUM_PORTS*1)-1:0] m_axi_rready
);
`include "rfnoc_block_replay_regs.vh"
//---------------------------------------------------------------------------
// Signal Declarations
//---------------------------------------------------------------------------
// CtrlPort Master
wire ctrlport_req_wr;
wire ctrlport_req_rd;
wire [19:0] ctrlport_req_addr;
wire [31:0] ctrlport_req_data;
wire ctrlport_resp_ack;
wire [31:0] ctrlport_resp_data;
// Data Stream to User Logic: in
wire [NUM_PORTS*MEM_DATA_W*1-1:0] in_axis_tdata;
wire [ NUM_PORTS-1:0] in_axis_tlast;
wire [ NUM_PORTS-1:0] in_axis_tvalid;
wire [ NUM_PORTS-1:0] in_axis_tready;
// Data Stream to User Logic: out
wire [NUM_PORTS*MEM_DATA_W*1-1:0] out_axis_tdata;
wire [ NUM_PORTS-1:0] out_axis_tlast;
wire [ NUM_PORTS-1:0] out_axis_tvalid;
wire [ NUM_PORTS-1:0] out_axis_tready;
wire [ NUM_PORTS*64-1:0] out_axis_ttimestamp;
wire [ NUM_PORTS-1:0] out_axis_thas_time;
wire [ NUM_PORTS-1:0] out_axis_teob;
//---------------------------------------------------------------------------
// NoC Shell
//---------------------------------------------------------------------------
wire mem_rst_noc_shell;
noc_shell_replay #(
.THIS_PORTID (THIS_PORTID),
.CHDR_W (CHDR_W),
.MEM_DATA_W (MEM_DATA_W),
.MTU (MTU),
.NUM_PORTS (NUM_PORTS)
) noc_shell_replay_i (
//---------------------
// Framework Interface
//---------------------
// Clock Inputs
.rfnoc_chdr_clk (rfnoc_chdr_clk),
.rfnoc_ctrl_clk (rfnoc_ctrl_clk),
.mem_clk (mem_clk),
// Reset Outputs
.rfnoc_chdr_rst (),
.rfnoc_ctrl_rst (),
.mem_rst (mem_rst_noc_shell),
// 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_rst (),
// CtrlPort Master
.m_ctrlport_req_wr (ctrlport_req_wr),
.m_ctrlport_req_rd (ctrlport_req_rd),
.m_ctrlport_req_addr (ctrlport_req_addr),
.m_ctrlport_req_data (ctrlport_req_data),
.m_ctrlport_resp_ack (ctrlport_resp_ack),
.m_ctrlport_resp_data (ctrlport_resp_data),
// AXI-Stream Payload Context Clock and Reset
.axis_data_clk (),
.axis_data_rst (),
// Data Stream to User Logic: in
.m_in_axis_tdata (in_axis_tdata),
.m_in_axis_tkeep (),
.m_in_axis_tlast (in_axis_tlast),
.m_in_axis_tvalid (in_axis_tvalid),
.m_in_axis_tready (in_axis_tready),
.m_in_axis_ttimestamp (),
.m_in_axis_thas_time (),
.m_in_axis_tlength (),
.m_in_axis_teov (),
.m_in_axis_teob (),
// Data Stream from User Logic: out
.s_out_axis_tdata (out_axis_tdata),
.s_out_axis_tkeep ({NUM_PORTS*MEM_DATA_W/32{1'b1}}),
.s_out_axis_tlast (out_axis_tlast),
.s_out_axis_tvalid (out_axis_tvalid),
.s_out_axis_tready (out_axis_tready),
.s_out_axis_ttimestamp (out_axis_ttimestamp),
.s_out_axis_thas_time (out_axis_thas_time),
.s_out_axis_tlength ({NUM_PORTS{16'b0}}), // Not used when SIDEBAND_AT_END = 1
.s_out_axis_teov ({NUM_PORTS{1'b0}}),
.s_out_axis_teob (out_axis_teob)
);
reg mem_rst;
// Combine the NoC Shell and AXI resets
always @(posedge mem_clk) begin
mem_rst <= axi_rst | mem_rst_noc_shell;
end
//---------------------------------------------------------------------------
// CtrlPort Splitter
//---------------------------------------------------------------------------
wire [ 1*NUM_PORTS-1:0] dec_ctrlport_req_wr;
wire [ 1*NUM_PORTS-1:0] dec_ctrlport_req_rd;
wire [20*NUM_PORTS-1:0] dec_ctrlport_req_addr;
wire [32*NUM_PORTS-1:0] dec_ctrlport_req_data;
wire [ 1*NUM_PORTS-1:0] dec_ctrlport_resp_ack;
wire [32*NUM_PORTS-1:0] dec_ctrlport_resp_data;
generate
if (NUM_PORTS > 1) begin : gen_ctrlport_decoder
ctrlport_decoder #(
.NUM_SLAVES (NUM_PORTS),
.BASE_ADDR (0),
.SLAVE_ADDR_W (REPLAY_ADDR_W)
) ctrlport_decoder_i (
.ctrlport_clk (mem_clk),
.ctrlport_rst (mem_rst),
.s_ctrlport_req_wr (ctrlport_req_wr),
.s_ctrlport_req_rd (ctrlport_req_rd),
.s_ctrlport_req_addr (ctrlport_req_addr),
.s_ctrlport_req_data (ctrlport_req_data),
.s_ctrlport_req_byte_en (4'hF),
.s_ctrlport_req_has_time (1'b0),
.s_ctrlport_req_time (64'b0),
.s_ctrlport_resp_ack (ctrlport_resp_ack),
.s_ctrlport_resp_status (),
.s_ctrlport_resp_data (ctrlport_resp_data),
.m_ctrlport_req_wr (dec_ctrlport_req_wr),
.m_ctrlport_req_rd (dec_ctrlport_req_rd),
.m_ctrlport_req_addr (dec_ctrlport_req_addr),
.m_ctrlport_req_data (dec_ctrlport_req_data),
.m_ctrlport_req_byte_en (),
.m_ctrlport_req_has_time (),
.m_ctrlport_req_time (),
.m_ctrlport_resp_ack (dec_ctrlport_resp_ack),
.m_ctrlport_resp_status ({NUM_PORTS{2'b0}}),
.m_ctrlport_resp_data (dec_ctrlport_resp_data)
);
end else begin : gen_no_decoder
assign dec_ctrlport_req_wr = ctrlport_req_wr;
assign dec_ctrlport_req_rd = ctrlport_req_rd;
assign dec_ctrlport_req_addr = {{20-REPLAY_ADDR_W{1'b0}},
ctrlport_req_addr[REPLAY_ADDR_W-1:0]};
assign dec_ctrlport_req_data = ctrlport_req_data;
assign ctrlport_resp_ack = dec_ctrlport_resp_ack;
assign ctrlport_resp_data = dec_ctrlport_resp_data;
end
endgenerate
//---------------------------------------------------------------------------
// Replay Block Instances
//---------------------------------------------------------------------------
// Width of memory transfer count. Always 8 for AXI4.
localparam MEM_COUNT_W = 8;
genvar i;
generate
for (i = 0; i < NUM_PORTS; i = i+1) begin : gen_replay_blocks
wire [ MEM_ADDR_W-1:0] write_addr;
wire [MEM_COUNT_W-1:0] write_count;
wire write_ctrl_valid;
wire write_ctrl_ready;
wire [ MEM_DATA_W-1:0] write_data;
wire write_data_valid;
wire write_data_ready;
wire [ MEM_ADDR_W-1:0] read_addr;
wire [MEM_COUNT_W-1:0] read_count;
wire read_ctrl_valid;
wire read_ctrl_ready;
wire [ MEM_DATA_W-1:0] read_data;
wire read_data_valid;
wire read_data_ready;
//-----------------------------------------------------------------------
// Replay Handler
//-----------------------------------------------------------------------
//
// This block implements the state machine and control logic for
// recording and playback of data.
//
//-----------------------------------------------------------------------
axis_replay #(
.MEM_DATA_W (MEM_DATA_W),
.MEM_ADDR_W (MEM_ADDR_W),
.MEM_COUNT_W (MEM_COUNT_W)
) axis_replay_i (
.clk (mem_clk),
.rst (mem_rst),
// CtrlPort Interface
.s_ctrlport_req_wr (dec_ctrlport_req_wr [ 1*i +: 1]),
.s_ctrlport_req_rd (dec_ctrlport_req_rd [ 1*i +: 1]),
.s_ctrlport_req_addr (dec_ctrlport_req_addr [20*i +: 20]),
.s_ctrlport_req_data (dec_ctrlport_req_data [32*i +: 32]),
.s_ctrlport_resp_ack (dec_ctrlport_resp_ack [ 1*i +: 1]),
.s_ctrlport_resp_data (dec_ctrlport_resp_data [32*i +: 32]),
// AXI Stream Interface
//
// Input
.i_tdata (in_axis_tdata [MEM_DATA_W*i +: MEM_DATA_W]),
.i_tvalid (in_axis_tvalid[ 1*i +: 1]),
.i_tlast (in_axis_tlast [ 1*i +: 1]),
.i_tready (in_axis_tready[ 1*i +: 1]),
//
// Output
.o_tdata (out_axis_tdata [MEM_DATA_W*i +: MEM_DATA_W]),
.o_ttimestamp (out_axis_ttimestamp[ 64*i +: 64]),
.o_thas_time (out_axis_thas_time [ 1*i +: 1]),
.o_teob (out_axis_teob [ 1*i +: 1]),
.o_tvalid (out_axis_tvalid [ 1*i +: 1]),
.o_tlast (out_axis_tlast [ 1*i +: 1]),
.o_tready (out_axis_tready [ 1*i +: 1]),
// Memory Interface
//
// Write interface
.write_addr (write_addr),
.write_count (write_count),
.write_ctrl_valid (write_ctrl_valid),
.write_ctrl_ready (write_ctrl_ready),
.write_data (write_data),
.write_data_valid (write_data_valid),
.write_data_ready (write_data_ready),
//
// Read interface
.read_addr (read_addr),
.read_count (read_count),
.read_ctrl_valid (read_ctrl_valid),
.read_ctrl_ready (read_ctrl_ready),
.read_data (read_data),
.read_data_valid (read_data_valid),
.read_data_ready (read_data_ready)
);
//-----------------------------------------------------------------------
// AXI DMA Master
//-----------------------------------------------------------------------
//
// This block translates simple read and write requests to AXI4
// memory-mapped reads and writes for the RAM interface.
//
//-----------------------------------------------------------------------
axi_dma_master #(
.AWIDTH (MEM_ADDR_W),
.DWIDTH (MEM_DATA_W)
) axi_dma_master_i (
//
// AXI4 Memory Mapped Interface to DRAM
//
.aclk (mem_clk),
.areset (mem_rst),
// Write control
.m_axi_awid (m_axi_awid [ 1*i +: 1]),
.m_axi_awaddr (m_axi_awaddr [MEM_ADDR_W*i +: MEM_ADDR_W]),
.m_axi_awlen (m_axi_awlen [ 8*i +: 8]),
.m_axi_awsize (m_axi_awsize [ 3*i +: 3]),
.m_axi_awburst (m_axi_awburst [ 2*i +: 2]),
.m_axi_awvalid (m_axi_awvalid [ 1*i +: 1]),
.m_axi_awready (m_axi_awready [ 1*i +: 1]),
.m_axi_awlock (m_axi_awlock [ 1*i +: 1]),
.m_axi_awcache (m_axi_awcache [ 4*i +: 4]),
.m_axi_awprot (m_axi_awprot [ 3*i +: 3]),
.m_axi_awqos (m_axi_awqos [ 4*i +: 4]),
.m_axi_awregion (m_axi_awregion[ 4*i +: 4]),
.m_axi_awuser (m_axi_awuser [ 1*i +: 1]),
// Write Data
.m_axi_wdata (m_axi_wdata [ MEM_DATA_W*i +: MEM_DATA_W]),
.m_axi_wstrb (m_axi_wstrb [(MEM_DATA_W/8)*i +: (MEM_DATA_W/8)]),
.m_axi_wlast (m_axi_wlast [ 1*i +: 1]),
.m_axi_wvalid (m_axi_wvalid[ 1*i +: 1]),
.m_axi_wready (m_axi_wready[ 1*i +: 1]),
.m_axi_wuser (m_axi_wuser [ 1*i +: 1]),
// Write Response
.m_axi_bid (m_axi_bid [1*i +: 1]),
.m_axi_bresp (m_axi_bresp [2*i +: 2]),
.m_axi_buser (m_axi_buser [1*i +: 1]),
.m_axi_bvalid (m_axi_bvalid[1*i +: 1]),
.m_axi_bready (m_axi_bready[1*i +: 1]),
// Read Control
.m_axi_arid (m_axi_arid [ 1*i +: 1]),
.m_axi_araddr (m_axi_araddr [MEM_ADDR_W*i +: MEM_ADDR_W]),
.m_axi_arlen (m_axi_arlen [ 8*i +: 8]),
.m_axi_arsize (m_axi_arsize [ 3*i +: 3]),
.m_axi_arburst (m_axi_arburst [ 2*i +: 2]),
.m_axi_arvalid (m_axi_arvalid [ 1*i +: 1]),
.m_axi_arready (m_axi_arready [ 1*i +: 1]),
.m_axi_arlock (m_axi_arlock [ 1*i +: 1]),
.m_axi_arcache (m_axi_arcache [ 4*i +: 4]),
.m_axi_arprot (m_axi_arprot [ 3*i +: 3]),
.m_axi_arqos (m_axi_arqos [ 4*i +: 4]),
.m_axi_arregion (m_axi_arregion[ 4*i +: 4]),
.m_axi_aruser (m_axi_aruser [ 1*i +: 1]),
// Read Data
.m_axi_rid (m_axi_rid [ 1*i +: 1]),
.m_axi_rdata (m_axi_rdata [MEM_DATA_W*i +: MEM_DATA_W]),
.m_axi_rresp (m_axi_rresp [ 2*i +: 2]),
.m_axi_rlast (m_axi_rlast [ 1*i +: 1]),
.m_axi_ruser (m_axi_ruser [ 1*i +: 1]),
.m_axi_rvalid (m_axi_rvalid[ 1*i +: 1]),
.m_axi_rready (m_axi_rready[ 1*i +: 1]),
//
// Interface for Write transactions
//
.write_addr (write_addr),
.write_count (write_count),
.write_ctrl_valid (write_ctrl_valid),
.write_ctrl_ready (write_ctrl_ready),
.write_data (write_data),
.write_data_valid (write_data_valid),
.write_data_ready (write_data_ready),
//
// Interface for Read transactions
//
.read_addr (read_addr),
.read_count (read_count),
.read_ctrl_valid (read_ctrl_valid),
.read_ctrl_ready (read_ctrl_ready),
.read_data (read_data),
.read_data_valid (read_data_valid),
.read_data_ready (read_data_ready),
//
// Debug
//
.debug ()
);
end
endgenerate
endmodule // rfnoc_block_replay
`default_nettype wire
@@ -0,0 +1,82 @@
//
// Copyright 2020 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: rfnoc_block_replay_tb
//
// Description:
//
// This testbench is the top-level testbench for the RFnoC Replay block. It
// instantiates several different variants of the Replay testbench, each
// using different parameters, to test different configurations.
//
`default_nettype none
module rfnoc_block_replay_all_tb;
`include "test_exec.svh"
import PkgTestExec::*;
//---------------------------------------------------------------------------
// Test Definitions
//---------------------------------------------------------------------------
typedef struct {
int CHDR_W;
int ITEM_W;
int NUM_PORTS;
int MEM_DATA_W;
int MEM_ADDR_W;
int TEST_REGS;
int TEST_FULL;
int STALL_PROB;
} test_config_t;
localparam NUM_TESTS = 15;
localparam test_config_t test[NUM_TESTS] = '{
// Test different CHDR and memory widths:
'{CHDR_W: 64, ITEM_W: 32, NUM_PORTS: 1, MEM_DATA_W: 32, MEM_ADDR_W: 16, TEST_REGS: 0, TEST_FULL: 1, STALL_PROB: 25},
'{CHDR_W: 128, ITEM_W: 32, NUM_PORTS: 1, MEM_DATA_W: 32, MEM_ADDR_W: 16, TEST_REGS: 0, TEST_FULL: 0, STALL_PROB: 25},
'{CHDR_W: 256, ITEM_W: 32, NUM_PORTS: 1, MEM_DATA_W: 32, MEM_ADDR_W: 16, TEST_REGS: 0, TEST_FULL: 1, STALL_PROB: 25},
'{CHDR_W: 64, ITEM_W: 32, NUM_PORTS: 2, MEM_DATA_W: 64, MEM_ADDR_W: 16, TEST_REGS: 1, TEST_FULL: 1, STALL_PROB: 25},
'{CHDR_W: 128, ITEM_W: 32, NUM_PORTS: 1, MEM_DATA_W: 64, MEM_ADDR_W: 16, TEST_REGS: 1, TEST_FULL: 0, STALL_PROB: 25},
'{CHDR_W: 256, ITEM_W: 32, NUM_PORTS: 1, MEM_DATA_W: 64, MEM_ADDR_W: 16, TEST_REGS: 0, TEST_FULL: 0, STALL_PROB: 25},
'{CHDR_W: 64, ITEM_W: 32, NUM_PORTS: 1, MEM_DATA_W: 128, MEM_ADDR_W: 16, TEST_REGS: 0, TEST_FULL: 0, STALL_PROB: 25},
'{CHDR_W: 128, ITEM_W: 32, NUM_PORTS: 1, MEM_DATA_W: 128, MEM_ADDR_W: 16, TEST_REGS: 0, TEST_FULL: 0, STALL_PROB: 25},
'{CHDR_W: 64, ITEM_W: 32, NUM_PORTS: 1, MEM_DATA_W: 256, MEM_ADDR_W: 16, TEST_REGS: 0, TEST_FULL: 1, STALL_PROB: 25},
'{CHDR_W: 64, ITEM_W: 32, NUM_PORTS: 1, MEM_DATA_W: 512, MEM_ADDR_W: 16, TEST_REGS: 0, TEST_FULL: 0, STALL_PROB: 25},
// Test different stall probabilities:
'{CHDR_W: 64, ITEM_W: 32, NUM_PORTS: 2, MEM_DATA_W: 64, MEM_ADDR_W: 16, TEST_REGS: 1, TEST_FULL: 1, STALL_PROB: 0},
'{CHDR_W: 64, ITEM_W: 32, NUM_PORTS: 2, MEM_DATA_W: 64, MEM_ADDR_W: 16, TEST_REGS: 1, TEST_FULL: 1, STALL_PROB: 75},
// Test large memory (> 32-bit) to check 64-bit registers:
'{CHDR_W: 64, ITEM_W: 32, NUM_PORTS: 2, MEM_DATA_W: 64, MEM_ADDR_W: 34, TEST_REGS: 1, TEST_FULL: 0, STALL_PROB: 0},
// Test different item widths to check time is handled correctly
'{CHDR_W: 64, ITEM_W: 16, NUM_PORTS: 1, MEM_DATA_W: 32, MEM_ADDR_W: 16, TEST_REGS: 0, TEST_FULL: 1, STALL_PROB: 25},
'{CHDR_W: 256, ITEM_W: 8, NUM_PORTS: 1, MEM_DATA_W: 32, MEM_ADDR_W: 16, TEST_REGS: 0, TEST_FULL: 1, STALL_PROB: 25}
};
//---------------------------------------------------------------------------
// DUT Instances
//---------------------------------------------------------------------------
genvar i;
for (i = 0; i < NUM_TESTS; i++) begin : gen_test_config
rfnoc_block_replay_tb #(
.CHDR_W (test[i].CHDR_W ),
.NUM_PORTS (test[i].NUM_PORTS ),
.MEM_DATA_W (test[i].MEM_DATA_W),
.MEM_ADDR_W (test[i].MEM_ADDR_W),
.TEST_FULL (test[i].TEST_FULL )
) rfnoc_block_replay_tb_i ();
end : gen_test_config
endmodule : rfnoc_block_replay_all_tb
`default_nettype wire
@@ -0,0 +1,205 @@
//
// Copyright 2020 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: rfnoc_block_replay_regs (Header)
//
// Description:
//
// This is a header file that contains the register descriptions for the
// RFNoC Replay block.
//
// Each RFNoC Replay block consists of NUM_PORTS independent replay engines.
// Each one has its own address space that is REPLAY_ADDR_W bits wide. That
// is, replay block N can be addressed starting at byte offset
// N*(2**REPLAY_ADDR_W).
//
// All 64-bit registers should be read/written least-significant word first
// to guarantee coherence.
//
//-----------------------------------------------------------------------------
// Register Space
//-----------------------------------------------------------------------------
// The amount of address space taken up by each replay engine. That is, the
// address space for port N starts at N*(2^REPLAY_ADDR_W).
localparam REPLAY_ADDR_W = 20'h00008;
//-----------------------------------------------------------------------------
// Replay Register Descriptions
//-----------------------------------------------------------------------------
// REG_COMPAT (R)
//
// Compatibility version. This read-only register is used by software to
// determine if this block's version is compatible with the running software. A
// major version change indicates the software for the previous major version
// is no longer compatible. A minor version change means the previous version
// is compatible, but some new features may be unavailable.
//
// [31:16] Major version
// [15: 0] Minor version
//
localparam REG_COMPAT = 'h00;
//
localparam REG_MAJOR_POS = 16;
localparam REG_MAJOR_LEN = 16;
//
localparam REG_MINOR_POS = 0;
localparam REG_MINOR_LEN = 16;
// REG_MEM_SIZE (R)
//
// Returns information about the size of the attached memory. The address size
// allows software to determine what buffer size and base address values are
// valid.
//
// [31:16] : Memory Data Word Size. Returns the bit width of the RAM word size.
// [15: 0] : Memory Address Size. Returns the bit width of the RAM byte
// address. That is, the memory is 2**VALUE bytes in size.
//
localparam REG_MEM_SIZE = 'h04;
//
localparam REG_DATA_SIZE_LEN = 16;
localparam REG_DATA_SIZE_POS = 16;
//
localparam REG_ADDR_SIZE_LEN = 16;
localparam REG_ADDR_SIZE_POS = 0;
// REG_REC_RESTART (W)
//
// Record Buffer Restart Register. Software must write to this register after
// updating the base address or buffer size. This will cause recording to
// restart at the indicated location. It does not matter what value you write.
//
localparam REG_REC_RESTART = 'h08;
// REG_REC_BASE_ADDR (R/W)
//
// Record Base Address Register. This is the byte address that controls where
// in the attached memory that recorded data should be stored. This must be a
// multiple of memory word size (REG_DATA_SIZE) in bytes.
//
localparam REG_REC_BASE_ADDR_LO = 'h10;
localparam REG_REC_BASE_ADDR_HI = 'h14;
// REG_REC_BUFFER_SIZE (R/W)
//
// Record Buffer Size Register. This controls the portion of the RAM allocated
// to the record buffer, in bytes. This must be a multiple of memory word size
// (REG_DATA_SIZE) in bytes.
//
localparam REG_REC_BUFFER_SIZE_LO = 'h18;
localparam REG_REC_BUFFER_SIZE_HI = 'h1C;
// REG_REC_FULLNESS (R)
//
// Record Fullness. Returns the number of bytes that have been recorded in the
// record buffer.
//
// This is is a 64-bit register in which the least-significant 32-bit word must
// be read first.
//
localparam REG_REC_FULLNESS_LO = 'h20;
localparam REG_REC_FULLNESS_HI = 'h24;
// REG_PLAY_BASE_ADDR (R/W)
//
// Playback Base Address Register. This is the byte address that controls where
// in the attached memory to read the data to be played back. This must be a
// multiple of memory word size (REG_DATA_SIZE) in bytes.
//
localparam REG_PLAY_BASE_ADDR_LO = 'h28;
localparam REG_PLAY_BASE_ADDR_HI = 'h2C;
// REG_PLAY_BUFFER_SIZE (R/W)
//
// Playback Buffer Size Register. This controls the size, in bytes, of the
// playback buffer in the attached memory. This must be a multiple of memory
// word size (REG_DATA_SIZE) in bytes.
//
localparam REG_PLAY_BUFFER_SIZE_LO = 'h30;
localparam REG_PLAY_BUFFER_SIZE_HI = 'h34;
// REG_PLAY_CMD_NUM_WORDS (R/W)
//
// Playback Command Number of Words. This register controls the number of
// memory data words to play back.
//
localparam REG_PLAY_CMD_NUM_WORDS_LO = 'h38;
localparam REG_PLAY_CMD_NUM_WORDS_HI = 'h3C;
//
localparam REG_CMD_NUM_WORDS_LEN = 64;
// REG_PLAY_CMD_TIME (R/W)
//
// Playback Command Time. This register indicates the timestamp to attach to
// the first packet that is played back, if timed playback is enabled.
// Subsequent packets will have the correctly incremented timestamp attached.
//
localparam REG_PLAY_CMD_TIME_LO = 'h40;
localparam REG_PLAY_CMD_TIME_HI = 'h44;
//
localparam REG_CMD_TIME_LEN = 64;
// REG_PLAY_CMD (W)
//
// Playback Command Register. This register mirrors the behavior of the RFNoC
// RX radio block. All commands are queued up in the replay command FIFO. The
// fields are as follows.
//
// [31] : Timed flag. Indicates if the command is timed (1) or not (0).
//
// [1:0] : Command field. The command indicates what you want the playback to
// do. It can be one of the following:
//
// 0 (PLAY_CMD_STOP) : Stop playing back data
// 1 (PLAY_CMD_FINITE) : Acquire NUM_SAMPS then stop
// 2 (PLAY_CMD_CONTINUOUS) : Play back continuously until stopped.
//
localparam REG_PLAY_CMD = 'h48;
//
localparam REG_PLAY_TIMED_POS = 31;
localparam REG_PLAY_TIMED_LEN = 1;
//
localparam REG_PLAY_CMD_POS = 0;
localparam REG_PLAY_CMD_LEN = 2;
// REG_PLAY_WORDS_PER_PKT (R/W)
//
// [15:0] Words Per Packet. This registers controls how many memory data words
// (REG_DATA_SIZE bits each) are inserted into each packet during
// playback. Effectively, it controls the samples-per-packet (SPP), but
// the replay block is sample-size agnostic.
//
// This value should never be set such that the total RFNoC packet size
// would exceed the system MTU or the maximum packet size allowed by
// RFNoC (2^16 bytes). Also note that the last packet of a command may
// be less than this size.
//
localparam REG_PLAY_WORDS_PER_PKT = 'h4C;
//
localparam REG_PLAY_WORDS_PER_PKT_LEN = 16;
//
localparam REG_PLAY_WORDS_PER_PKT_INIT = 160;
// REG_PLAY_ITEM_SIZE (R/W)
//
// [7:0] Number of bytes per item. This controls how much time is incremented
// for each memory word of data. This must be a power of 2.
//
localparam REG_PLAY_ITEM_SIZE = 'h50;
//
localparam REG_ITEM_SIZE_POS = 0;
localparam REG_ITEM_SIZE_LEN = 8;
//-----------------------------------------------------------------------------
// Playback Commands
//-----------------------------------------------------------------------------
localparam PLAY_CMD_STOP = 2'h0;
localparam PLAY_CMD_FINITE = 2'h1;
localparam PLAY_CMD_CONTINUOUS = 2'h2;
File diff suppressed because it is too large Load Diff