fpga: x400: Connect Radio Blocks to DIO

Original-commit: 87b2cf09301e90dfaf2a6554c424b62e0558e0b1
This commit is contained in:
Javier Valenzuela
2022-01-25 10:18:47 -07:00
committed by Wade Fife
parent 729d780bd4
commit 4edae39d9e
11 changed files with 627 additions and 232 deletions
+326 -13
View File
@@ -8,7 +8,8 @@
// Description:
//
// This module contains the common core infrastructure for RFNoC, such as the
// motherboard registers and timekeeper.
// motherboard registers and timekeeper, as well as distribution of the
// CtrlPort buses from each radio block.
//
// Parameters:
//
@@ -16,6 +17,7 @@
// CHDR_W : CHDR protocol width
// RFNOC_PROTOVER : RFNoC protocol version (major in most-significant byte,
// Minor is least significant byte)
// NUM_DBOARDS : Number of daughter boards to support
// PCIE_PRESENT : Indicates if PCIe is present in this image
//
@@ -26,6 +28,7 @@ module x4xx_core_common #(
parameter CHDR_CLK_RATE = 200000000,
parameter CHDR_W = 64,
parameter RFNOC_PROTOVER = {8'd1, 8'd0},
parameter NUM_DBOARDS = 2,
parameter PCIE_PRESENT = 0
) (
// Clocks and resets
@@ -73,8 +76,9 @@ module x4xx_core_common #(
input wire [ 7:0] radio_spc,
output wire [63:0] radio_time,
input wire sample_rx_stb,
input wire [ 3:0] time_ignore_bits,
// GPIO to DIO board (Domain: rfnoc_ctrl_clk)
// GPIO to DIO board (Domain: radio_clk)
output wire [11:0] gpio_en_a,
output wire [11:0] gpio_en_b,
// GPIO to DIO board (async)
@@ -83,12 +87,42 @@ module x4xx_core_common #(
output wire [11:0] gpio_out_a,
output wire [11:0] gpio_out_b,
// GPIO to application (Domain: rfnoc_ctrl_clk)
// GPIO to application (Domain: async)
output wire [11:0] gpio_in_fabric_a,
output wire [11:0] gpio_in_fabric_b,
input wire [11:0] gpio_out_fabric_a,
input wire [11:0] gpio_out_fabric_b,
// CtrlPort Slave (from RFNoC Radio Blocks; Domain: radio_clk)
input wire [ 1*NUM_DBOARDS-1:0] s_radio_ctrlport_req_wr,
input wire [ 1*NUM_DBOARDS-1:0] s_radio_ctrlport_req_rd,
input wire [ 20*NUM_DBOARDS-1:0] s_radio_ctrlport_req_addr,
input wire [ 32*NUM_DBOARDS-1:0] s_radio_ctrlport_req_data,
input wire [ 4*NUM_DBOARDS-1:0] s_radio_ctrlport_req_byte_en,
input wire [ 1*NUM_DBOARDS-1:0] s_radio_ctrlport_req_has_time,
input wire [ 64*NUM_DBOARDS-1:0] s_radio_ctrlport_req_time,
output wire [ 1*NUM_DBOARDS-1:0] s_radio_ctrlport_resp_ack,
output wire [ 2*NUM_DBOARDS-1:0] s_radio_ctrlport_resp_status,
output wire [ 32*NUM_DBOARDS-1:0] s_radio_ctrlport_resp_data,
// CtrlPort Master (to Daughter Boards, Domain: radio_clk)
output wire [ 1*NUM_DBOARDS-1:0] m_radio_ctrlport_req_wr,
output wire [ 1*NUM_DBOARDS-1:0] m_radio_ctrlport_req_rd,
output wire [ 20*NUM_DBOARDS-1:0] m_radio_ctrlport_req_addr,
output wire [ 32*NUM_DBOARDS-1:0] m_radio_ctrlport_req_data,
output wire [ 4*NUM_DBOARDS-1:0] m_radio_ctrlport_req_byte_en,
output wire [ 1*NUM_DBOARDS-1:0] m_radio_ctrlport_req_has_time,
output wire [ 64*NUM_DBOARDS-1:0] m_radio_ctrlport_req_time,
input wire [ 1*NUM_DBOARDS-1:0] m_radio_ctrlport_resp_ack,
input wire [ 2*NUM_DBOARDS-1:0] m_radio_ctrlport_resp_status,
input wire [ 32*NUM_DBOARDS-1:0] m_radio_ctrlport_resp_data,
// RF Reset Control
output wire start_nco_reset,
input wire nco_reset_done,
output wire adc_reset_pulse,
output wire dac_reset_pulse,
// Misc (Domain: rfnoc_ctrl_clk)
input wire [31:0] qsfp_port_0_0_info,
input wire [31:0] qsfp_port_0_1_info,
@@ -109,10 +143,10 @@ module x4xx_core_common #(
);
`include "regmap/radio_ctrlport_regmap_utils.vh"
`include "../../lib/rfnoc/core/ctrlport.vh"
`include "regmap/core_regs_regmap_utils.vh"
//---------------------------------------------------------------------------
// AXI4-Lite to ctrlport
//---------------------------------------------------------------------------
@@ -293,24 +327,284 @@ module x4xx_core_common #(
);
//-----------------------------------------------------------------------
// Radio CtrlPort Splitter
//-----------------------------------------------------------------------
wire [ 1*NUM_DBOARDS-1:0] rf_ctrlport_req_wr;
wire [ 1*NUM_DBOARDS-1:0] rf_ctrlport_req_rd;
wire [ 20*NUM_DBOARDS-1:0] rf_ctrlport_req_addr;
wire [ 32*NUM_DBOARDS-1:0] rf_ctrlport_req_data;
wire [ 4*NUM_DBOARDS-1:0] rf_ctrlport_req_byte_en;
wire [ 1*NUM_DBOARDS-1:0] rf_ctrlport_req_has_time;
wire [ 64*NUM_DBOARDS-1:0] rf_ctrlport_req_time;
wire [ 1*NUM_DBOARDS-1:0] rf_ctrlport_resp_ack;
wire [ 2*NUM_DBOARDS-1:0] rf_ctrlport_resp_status;
wire [ 32*NUM_DBOARDS-1:0] rf_ctrlport_resp_data;
wire [ 1*NUM_DBOARDS-1:0] dio_radio_ctrlport_req_wr;
wire [ 1*NUM_DBOARDS-1:0] dio_radio_ctrlport_req_rd;
wire [ 20*NUM_DBOARDS-1:0] dio_radio_ctrlport_req_addr;
wire [ 32*NUM_DBOARDS-1:0] dio_radio_ctrlport_req_data;
wire [ 4*NUM_DBOARDS-1:0] dio_radio_ctrlport_req_byte_en;
wire [ 1*NUM_DBOARDS-1:0] dio_radio_ctrlport_req_has_time;
wire [ 64*NUM_DBOARDS-1:0] dio_radio_ctrlport_req_time;
wire [ 1*NUM_DBOARDS-1:0] dio_radio_ctrlport_resp_ack;
wire [ 2*NUM_DBOARDS-1:0] dio_radio_ctrlport_resp_status;
wire [ 32*NUM_DBOARDS-1:0] dio_radio_ctrlport_resp_data;
genvar db;
generate
for (db = 0; db < NUM_DBOARDS; db = db+1) begin : gen_radio_ctrlport
//-----------------------------------------------------------------------
// CtrlPort Splitter
//-----------------------------------------------------------------------
// This section takes the CtrlPort master from each radio block and splits it
// into a CtrlPort bus for the associated daughter(m_radio_ctrlport_*), the
// RFDC timing control (rf_ctrlport_*) and DIO control(dio_radio_ctrlport_*).
localparam [31:0] DIO_WINDOW_SIZE_W = $clog2(DIO_WINDOW_SIZE);
localparam [31:0] RFDC_TIMING_WINDOW_SIZE_W = $clog2(RFDC_TIMING_WINDOW_SIZE);
localparam [31:0] DB_WINDOW_SIZE_W = $clog2(DB_WINDOW_SIZE);
ctrlport_decoder_param #(
.NUM_SLAVES (3),
.PORT_BASE ({ DIO_WINDOW[19:0], RFDC_TIMING_WINDOW[19:0], DB_WINDOW[19:0] }),
.PORT_ADDR_W ({ DIO_WINDOW_SIZE_W, RFDC_TIMING_WINDOW_SIZE_W, DB_WINDOW_SIZE_W })
) ctrlport_decoder_param_i (
.ctrlport_clk (radio_clk),
.ctrlport_rst (radio_rst),
.s_ctrlport_req_wr (s_radio_ctrlport_req_wr [ 1*db+: 1]),
.s_ctrlport_req_rd (s_radio_ctrlport_req_rd [ 1*db+: 1]),
.s_ctrlport_req_addr (s_radio_ctrlport_req_addr [20*db+:20]),
.s_ctrlport_req_data (s_radio_ctrlport_req_data [32*db+:32]),
.s_ctrlport_req_byte_en (s_radio_ctrlport_req_byte_en [ 4*db+: 4]),
.s_ctrlport_req_has_time (s_radio_ctrlport_req_has_time [ 1*db+: 1]),
.s_ctrlport_req_time (s_radio_ctrlport_req_time [64*db+:64]),
.s_ctrlport_resp_ack (s_radio_ctrlport_resp_ack [ 1*db+: 1]),
.s_ctrlport_resp_status (s_radio_ctrlport_resp_status [ 2*db+: 2]),
.s_ctrlport_resp_data (s_radio_ctrlport_resp_data [32*db+:32]),
.m_ctrlport_req_wr ({ dio_radio_ctrlport_req_wr [ 1*db+: 1], rf_ctrlport_req_wr [ 1*db+: 1], m_radio_ctrlport_req_wr [ 1*db+: 1] }),
.m_ctrlport_req_rd ({ dio_radio_ctrlport_req_rd [ 1*db+: 1], rf_ctrlport_req_rd [ 1*db+: 1], m_radio_ctrlport_req_rd [ 1*db+: 1] }),
.m_ctrlport_req_addr ({ dio_radio_ctrlport_req_addr [20*db+:20], rf_ctrlport_req_addr [20*db+:20], m_radio_ctrlport_req_addr [20*db+:20] }),
.m_ctrlport_req_data ({ dio_radio_ctrlport_req_data [32*db+:32], rf_ctrlport_req_data [32*db+:32], m_radio_ctrlport_req_data [32*db+:32] }),
.m_ctrlport_req_byte_en ({ dio_radio_ctrlport_req_byte_en [ 4*db+: 4], rf_ctrlport_req_byte_en [ 4*db+: 4], m_radio_ctrlport_req_byte_en [ 4*db+: 4] }),
.m_ctrlport_req_has_time ({ dio_radio_ctrlport_req_has_time [ 1*db+: 1], rf_ctrlport_req_has_time [ 1*db+: 1], m_radio_ctrlport_req_has_time [ 1*db+: 1] }),
.m_ctrlport_req_time ({ dio_radio_ctrlport_req_time [64*db+:64], rf_ctrlport_req_time [64*db+:64], m_radio_ctrlport_req_time [64*db+:64] }),
.m_ctrlport_resp_ack ({ dio_radio_ctrlport_resp_ack [ 1*db+: 1], rf_ctrlport_resp_ack [ 1*db+: 1], m_radio_ctrlport_resp_ack [ 1*db+: 1] }),
.m_ctrlport_resp_status ({ dio_radio_ctrlport_resp_status [ 2*db+: 2], rf_ctrlport_resp_status [ 2*db+: 2], m_radio_ctrlport_resp_status [ 2*db+: 2] }),
.m_ctrlport_resp_data ({ dio_radio_ctrlport_resp_data [32*db+:32], rf_ctrlport_resp_data [32*db+:32], m_radio_ctrlport_resp_data [32*db+:32] })
);
end
endgenerate
//-------------------------------------------------------------------------
// RF Timing Reset Control
//-------------------------------------------------------------------------
rfdc_timing_control #(
.NUM_DBOARDS (NUM_DBOARDS)
) rfdc_timing_control_i (
.clk (radio_clk),
.rst (radio_rst),
.time_now (radio_time),
.time_now_stb (sample_rx_stb),
.time_ignore_bits (time_ignore_bits),
.s_ctrlport_req_wr (rf_ctrlport_req_wr),
.s_ctrlport_req_rd (rf_ctrlport_req_rd),
.s_ctrlport_req_addr (rf_ctrlport_req_addr),
.s_ctrlport_req_data (rf_ctrlport_req_data),
.s_ctrlport_req_byte_en (rf_ctrlport_req_byte_en),
.s_ctrlport_req_has_time (rf_ctrlport_req_has_time),
.s_ctrlport_req_time (rf_ctrlport_req_time),
.s_ctrlport_resp_ack (rf_ctrlport_resp_ack),
.s_ctrlport_resp_status (rf_ctrlport_resp_status),
.s_ctrlport_resp_data (rf_ctrlport_resp_data),
.start_nco_reset (start_nco_reset),
.nco_reset_done (nco_reset_done),
.adc_reset_pulse (adc_reset_pulse),
.dac_reset_pulse (dac_reset_pulse)
);
//---------------------------------------------------------------------------
// DIO
//---------------------------------------------------------------------------
//
// DIO lines may be controlled via 3 different ctrlport interfaces.
// The diagram below shows how the different ctrlport interfaces are
// conditioned and combined.
//
// ________________
// ps ctrlport | |
// ----------------------| CLK crossing |-------+
// |(rfnoc_ctrl_clk)| |
// |________________| |
// radio 0 dio_ctrlport | _____________
// -------------------------------------------+ +----| |
// | | Ctrlport |
// +--------| combiner |---- x4xx_dio
// radio 1 dio_ctrlport | |
// ----------------------------------------------------|_____________|
// (radio_clk)
//
//
// MPM ctrlport signals to convert to radio_clk domain
wire mpm_dio_req_wr;
wire mpm_dio_req_rd;
wire [19:0] mpm_dio_req_addr;
wire [31:0] mpm_dio_req_data;
wire mpm_dio_resp_ack;
wire [ 1:0] mpm_dio_resp_status;
wire [31:0] mpm_dio_resp_data;
ctrlport_clk_cross ctrlport_clk_cross_dio (
.rst (rfnoc_ctrl_rst),
.s_ctrlport_clk (rfnoc_ctrl_clk),
.s_ctrlport_req_wr (dio_req_wr),
.s_ctrlport_req_rd (dio_req_rd),
.s_ctrlport_req_addr (dio_req_addr),
.s_ctrlport_req_portid (10'b0),
.s_ctrlport_req_rem_epid (16'b0),
.s_ctrlport_req_rem_portid (10'b0),
.s_ctrlport_req_data (dio_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 (dio_resp_ack),
.s_ctrlport_resp_status (dio_resp_status),
.s_ctrlport_resp_data (dio_resp_data),
.m_ctrlport_clk (radio_clk),
.m_ctrlport_req_wr (mpm_dio_req_wr),
.m_ctrlport_req_rd (mpm_dio_req_rd),
.m_ctrlport_req_addr (mpm_dio_req_addr),
.m_ctrlport_req_portid (),
.m_ctrlport_req_rem_epid (),
.m_ctrlport_req_rem_portid (),
.m_ctrlport_req_data (mpm_dio_req_data),
.m_ctrlport_req_byte_en (),
.m_ctrlport_req_has_time (),
.m_ctrlport_req_time (),
.m_ctrlport_resp_ack (mpm_dio_resp_ack),
.m_ctrlport_resp_status (mpm_dio_resp_status),
.m_ctrlport_resp_data (mpm_dio_resp_data)
);
// Since the PS ctrlport services other register endpoints
// outside the DIO register space, none of which are addressed
// through the ctrlport signals in the radio_clk domain.
// For this reason, ctrlport transactions not intended for the
// DIO register space will hang the bus if pushed into
// the ctrlport_combiner. For this reason, transactions out
// of said space will be filtered out from this clock crossed
// instance of the PS ctrlport.
// Windowed ctrlport signals
wire windowed_mpm_dio_req_wr;
wire windowed_mpm_dio_req_rd;
wire [19:0] windowed_mpm_dio_req_addr;
wire [31:0] windowed_mpm_dio_req_data;
wire windowed_mpm_dio_resp_ack;
wire [ 1:0] windowed_mpm_dio_resp_status;
wire [31:0] windowed_mpm_dio_resp_data;
ctrlport_window #(
.BASE_ADDRESS (DIO),
.WINDOW_SIZE (DIO_SIZE)
) ctrlport_window_dio (
.s_ctrlport_req_wr (mpm_dio_req_wr),
.s_ctrlport_req_rd (mpm_dio_req_rd),
.s_ctrlport_req_addr (mpm_dio_req_addr),
.s_ctrlport_req_portid (10'b0),
.s_ctrlport_req_rem_epid (16'b0),
.s_ctrlport_req_rem_portid (10'b0),
.s_ctrlport_req_data (mpm_dio_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 (mpm_dio_resp_ack),
.s_ctrlport_resp_status (mpm_dio_resp_status),
.s_ctrlport_resp_data (mpm_dio_resp_data),
.m_ctrlport_req_wr (windowed_mpm_dio_req_wr),
.m_ctrlport_req_rd (windowed_mpm_dio_req_rd),
.m_ctrlport_req_addr (windowed_mpm_dio_req_addr),
.m_ctrlport_req_portid (),
.m_ctrlport_req_rem_epid (),
.m_ctrlport_req_rem_portid (),
.m_ctrlport_req_data (windowed_mpm_dio_req_data),
.m_ctrlport_req_byte_en (),
.m_ctrlport_req_has_time (),
.m_ctrlport_req_time (),
.m_ctrlport_resp_ack (windowed_mpm_dio_resp_ack),
.m_ctrlport_resp_status (windowed_mpm_dio_resp_status),
.m_ctrlport_resp_data (windowed_mpm_dio_resp_data)
);
// Combined ctrlport signals
wire dio_ctrlport_req_wr;
wire dio_ctrlport_req_rd;
wire [19:0] dio_ctrlport_req_addr;
wire [31:0] dio_ctrlport_req_data;
wire dio_ctrlport_resp_ack;
wire [ 1:0] dio_ctrlport_resp_status;
wire [31:0] dio_ctrlport_resp_data;
// This combiner mixes the CtrlPort interfaces from each radio block with the
// filtered PS CtrlPort bus to allow these interfaces to interact with the
// DIO block.
ctrlport_combiner #(
.NUM_MASTERS (NUM_DBOARDS + 1),
.PRIORITY (1)
) ctrlport_combiner_dio (
.ctrlport_clk (radio_clk),
.ctrlport_rst (radio_rst),
.s_ctrlport_req_wr ({dio_radio_ctrlport_req_wr, windowed_mpm_dio_req_wr}),
.s_ctrlport_req_rd ({dio_radio_ctrlport_req_rd, windowed_mpm_dio_req_rd}),
.s_ctrlport_req_addr ({dio_radio_ctrlport_req_addr, windowed_mpm_dio_req_addr}),
.s_ctrlport_req_portid ({(NUM_DBOARDS+1){10'b0}}),
.s_ctrlport_req_rem_epid ({(NUM_DBOARDS+1){16'b0}}),
.s_ctrlport_req_rem_portid ({(NUM_DBOARDS+1){10'b0}}),
.s_ctrlport_req_data ({dio_radio_ctrlport_req_data, windowed_mpm_dio_req_data}),
.s_ctrlport_req_byte_en ({(NUM_DBOARDS+1){4'hF}}),
.s_ctrlport_req_has_time ({(NUM_DBOARDS+1){1'b0}}),
.s_ctrlport_req_time ({(NUM_DBOARDS+1){64'b0}}),
.s_ctrlport_resp_ack ({dio_radio_ctrlport_resp_ack, windowed_mpm_dio_resp_ack}),
.s_ctrlport_resp_status ({dio_radio_ctrlport_resp_status, windowed_mpm_dio_resp_status}),
.s_ctrlport_resp_data ({dio_radio_ctrlport_resp_data, windowed_mpm_dio_resp_data}),
.m_ctrlport_req_wr (dio_ctrlport_req_wr),
.m_ctrlport_req_rd (dio_ctrlport_req_rd),
.m_ctrlport_req_addr (dio_ctrlport_req_addr),
.m_ctrlport_req_portid (),
.m_ctrlport_req_rem_epid (),
.m_ctrlport_req_rem_portid (),
.m_ctrlport_req_data (dio_ctrlport_req_data),
.m_ctrlport_req_byte_en (),
.m_ctrlport_req_has_time (),
.m_ctrlport_req_time (),
.m_ctrlport_resp_ack (dio_ctrlport_resp_ack),
.m_ctrlport_resp_status (dio_ctrlport_resp_status),
.m_ctrlport_resp_data (dio_ctrlport_resp_data)
);
x4xx_dio #(
.REG_BASE (DIO),
.REG_SIZE (DIO_SIZE)
) x4xx_dio_i (
.ctrlport_clk (rfnoc_ctrl_clk),
.ctrlport_rst (rfnoc_ctrl_rst),
.s_ctrlport_req_wr (dio_req_wr),
.s_ctrlport_req_rd (dio_req_rd),
.s_ctrlport_req_addr (dio_req_addr),
.s_ctrlport_req_data (dio_req_data),
.s_ctrlport_resp_ack (dio_resp_ack),
.s_ctrlport_resp_status (dio_resp_status),
.s_ctrlport_resp_data (dio_resp_data),
.ctrlport_clk (radio_clk),
.ctrlport_rst (radio_rst),
.s_ctrlport_req_wr (dio_ctrlport_req_wr),
.s_ctrlport_req_rd (dio_ctrlport_req_rd),
.s_ctrlport_req_addr (dio_ctrlport_req_addr),
.s_ctrlport_req_data (dio_ctrlport_req_data),
.s_ctrlport_resp_ack (dio_ctrlport_resp_ack),
.s_ctrlport_resp_status (dio_ctrlport_resp_status),
.s_ctrlport_resp_data (dio_ctrlport_resp_data),
.gpio_in_a (gpio_in_a),
.gpio_in_b (gpio_in_b),
.gpio_out_a (gpio_out_a),
@@ -330,6 +624,25 @@ endmodule
//XmlParse xml_on
//
//<regmap name="RADIO_CTRLPORT_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
// <group name="RADIO_CTRLPORT_WINDOWS">
// <info>Each radio's CtrlPort peripheral interface is divided into the
// following memory spaces. Note that the CtrlPort peripheral interface
// starts at offset 0x80000 in the RFNoC Radio block's register space.</info>
// <window name="DB_WINDOW" offset="0x00000" size="0x08000">
// <info>Daughterboard GPIO interface. Register access within this space
// is directed to the associated daughterboard CPLD.</info>
// </window>
// <window name="RFDC_TIMING_WINDOW" offset="0x08000" size="0x04000" targetregmap="RFDC_TIMING_REGMAP">
// <info>RFDC timing control interface.</info>
// </window>
// <window name="DIO_WINDOW" offset="0x0C000" size="0x04000" targetregmap="DIO_REGMAP">
// <info>DIO control interface</info>
// </window>
// </group>
//</regmap>
//
//<regmap name="CORE_REGS_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
// <info>
// This is the map for the registers that the CORE_REGS window has access to