954 lines
44 KiB
Verilog
954 lines
44 KiB
Verilog
//
|
|
// Copyright 2021 Ettus Research, A National Instruments Brand
|
|
//
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
//
|
|
// Module: x4xx_core_common
|
|
//
|
|
// Description:
|
|
//
|
|
// This module contains the common core infrastructure for RFNoC, such as the
|
|
// motherboard registers and timekeeper, as well as distribution of the
|
|
// CtrlPort buses from each radio block.
|
|
// This module contains blocks that respond to the AXI ctrlport interface,
|
|
// the ctrlport interfaces in the radios, or a mix of both. A visual
|
|
// representation of how the AXI Ctrlport interface and the
|
|
// Ctrlport of each radio interact with the different blocks in this module
|
|
// can be found in ./doc/common/x4xx_core_common_buses.svg
|
|
//
|
|
// Parameters:
|
|
//
|
|
// CHDR_CLK_RATE : Rate of rfnoc_chdr_clk in Hz
|
|
// 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
|
|
// NUM_CH_PER_DB : Number of RF Channels per daughterboard
|
|
// NUM_TIMEKEEPERS : Number of timekeepers
|
|
// PCIE_PRESENT : Indicates if PCIe is present in this image
|
|
//
|
|
|
|
`default_nettype none
|
|
|
|
|
|
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 NUM_CH_PER_DB = 2,
|
|
parameter NUM_TIMEKEEPERS = NUM_DBOARDS,
|
|
parameter PCIE_PRESENT = 0
|
|
) (
|
|
// Clocks and resets
|
|
input wire [NUM_DBOARDS-1:0] radio_clk,
|
|
input wire [NUM_DBOARDS-1:0] radio_clk_2x,
|
|
input wire [NUM_DBOARDS-1:0] radio_rst,
|
|
|
|
input wire rfnoc_chdr_clk,
|
|
input wire rfnoc_chdr_rst,
|
|
|
|
input wire rfnoc_ctrl_clk,
|
|
input wire rfnoc_ctrl_rst,
|
|
|
|
// Ctrlport master interface from AXI
|
|
input wire ctrlport_rst,
|
|
input wire ctrlport_clk,
|
|
input wire s_ctrlport_req_wr,
|
|
input wire s_ctrlport_req_rd,
|
|
input wire [19:0] s_ctrlport_req_addr,
|
|
input wire [ 9:0] s_ctrlport_req_portid,
|
|
input wire [15:0] s_ctrlport_req_rem_epid,
|
|
input wire [ 9:0] s_ctrlport_req_rem_portid,
|
|
input wire [31:0] s_ctrlport_req_data,
|
|
input wire [ 3:0] s_ctrlport_req_byte_en,
|
|
input wire s_ctrlport_req_has_time,
|
|
input wire [63:0] s_ctrlport_req_time,
|
|
output wire s_ctrlport_resp_ack,
|
|
output wire [ 1:0] s_ctrlport_resp_status,
|
|
output wire [31:0] s_ctrlport_resp_data,
|
|
|
|
// PPS (top-level inputs)
|
|
input wire [ 1:0] pps_radioclk,
|
|
|
|
// PPS and clock control (Domain: rfnoc_ctrl_clk)
|
|
output wire [ 1:0] pps_select,
|
|
output wire [ 1:0] trig_io_select,
|
|
output wire pll_sync_trigger,
|
|
output wire [ 7:0] pll_sync_delay,
|
|
input wire pll_sync_done,
|
|
output wire [ 7:0] pps_brc_delay,
|
|
output wire [25:0] pps_prc_delay,
|
|
output wire [ 4:0] prc_rc0_divider,
|
|
output wire [ 4:0] prc_rc1_divider,
|
|
output wire pps_rc_enabled,
|
|
|
|
// Timekeeper (Domain: radio_clk)
|
|
input wire [ 7:0] radio_spc,
|
|
input wire [NUM_TIMEKEEPERS-1:0] sample_rx_stb,
|
|
input wire [ 3:0] time_ignore_bits,
|
|
output wire [64*NUM_TIMEKEEPERS-1:0] radio_time,
|
|
|
|
// 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)
|
|
input wire [11:0] gpio_in_a,
|
|
input wire [11:0] gpio_in_b,
|
|
output wire [11:0] gpio_out_a,
|
|
output wire [11:0] gpio_out_b,
|
|
|
|
// 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,
|
|
|
|
// PS GPIO Control
|
|
input wire [11:0] ps_gpio_out_a,
|
|
output wire [11:0] ps_gpio_in_a,
|
|
input wire [11:0] ps_gpio_ddr_a,
|
|
input wire [11:0] ps_gpio_out_b,
|
|
output wire [11:0] ps_gpio_in_b,
|
|
input wire [11:0] ps_gpio_ddr_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,
|
|
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 [NUM_TIMEKEEPERS-1:0] adc_reset_pulse,
|
|
output wire [NUM_TIMEKEEPERS-1:0] dac_reset_pulse,
|
|
|
|
// Radio state for ATR control
|
|
input wire [NUM_DBOARDS*NUM_CH_PER_DB-1:0] tx_running,
|
|
input wire [NUM_DBOARDS*NUM_CH_PER_DB-1:0] rx_running,
|
|
|
|
// Misc (Domain: rfnoc_ctrl_clk)
|
|
input wire [31:0] qsfp_port_0_0_info,
|
|
input wire [31:0] qsfp_port_0_1_info,
|
|
input wire [31:0] qsfp_port_0_2_info,
|
|
input wire [31:0] qsfp_port_0_3_info,
|
|
input wire [31:0] qsfp_port_1_0_info,
|
|
input wire [31:0] qsfp_port_1_1_info,
|
|
input wire [31:0] qsfp_port_1_2_info,
|
|
input wire [31:0] qsfp_port_1_3_info,
|
|
output wire [15:0] device_id,
|
|
output wire mfg_test_en_fabric_clk,
|
|
output wire mfg_test_en_gty_rcv_clk,
|
|
input wire fpga_aux_ref,
|
|
|
|
// Version (Constant)
|
|
// Each component consists of a 96-bit vector (refer to versioning_utils.vh)
|
|
input wire [64*96-1:0] version_info
|
|
|
|
);
|
|
|
|
`include "regmap/radio_ctrlport_regmap_utils.vh"
|
|
`include "../../lib/rfnoc/core/ctrlport.vh"
|
|
`include "regmap/core_regs_regmap_utils.vh"
|
|
`include "regmap/radio_dio_regmap_utils.vh"
|
|
|
|
//---------------------------------------------------------------------------
|
|
// AXI4-Lite to ctrlport
|
|
//---------------------------------------------------------------------------
|
|
|
|
// Ctrlport master interface (domain: rfnoc_ctrl_clk)
|
|
wire m_req_wr;
|
|
wire m_req_rd;
|
|
wire [CTRLPORT_ADDR_W-1:0] m_req_addr;
|
|
wire [CTRLPORT_DATA_W-1:0] m_req_data;
|
|
wire m_resp_ack;
|
|
wire [ CTRLPORT_STS_W-1:0] m_resp_status;
|
|
wire [CTRLPORT_DATA_W-1:0] m_resp_data;
|
|
|
|
// Split ctrlport for multiple endpoints (domain: rfnoc_ctrl_clk)
|
|
wire versioning_req_wr, global_regs_req_wr, dio_req_wr;
|
|
wire versioning_req_rd, global_regs_req_rd, dio_req_rd;
|
|
wire [CTRLPORT_ADDR_W-1:0] versioning_req_addr, global_regs_req_addr, dio_req_addr;
|
|
wire [CTRLPORT_DATA_W-1:0] versioning_req_data, global_regs_req_data, dio_req_data;
|
|
wire versioning_resp_ack, global_regs_resp_ack, dio_resp_ack;
|
|
wire [ CTRLPORT_STS_W-1:0] versioning_resp_status, global_regs_resp_status, dio_resp_status;
|
|
wire [CTRLPORT_DATA_W-1:0] versioning_resp_data, global_regs_resp_data, dio_resp_data;
|
|
|
|
// Timekeeper ctrlports
|
|
wire [NUM_TIMEKEEPERS-1:0] timekeeper_req_wr;
|
|
wire [NUM_TIMEKEEPERS-1:0] timekeeper_req_rd;
|
|
wire [NUM_TIMEKEEPERS*CTRLPORT_ADDR_W-1:0] timekeeper_req_addr;
|
|
wire [NUM_TIMEKEEPERS*CTRLPORT_DATA_W-1:0] timekeeper_req_data;
|
|
wire [NUM_TIMEKEEPERS-1:0] timekeeper_resp_ack;
|
|
wire [NUM_TIMEKEEPERS*CTRLPORT_DATA_W-1:0] timekeeper_resp_data;
|
|
wire [NUM_TIMEKEEPERS*CTRLPORT_STS_W-1:0] timekeeper_resp_status;
|
|
|
|
ctrlport_clk_cross ctrlport_clk_cross_i (
|
|
.rst (ctrlport_rst),
|
|
.s_ctrlport_clk (ctrlport_clk),
|
|
.s_ctrlport_req_wr (s_ctrlport_req_wr),
|
|
.s_ctrlport_req_rd (s_ctrlport_req_rd),
|
|
.s_ctrlport_req_addr (s_ctrlport_req_addr),
|
|
.s_ctrlport_req_portid (s_ctrlport_req_portid),
|
|
.s_ctrlport_req_rem_epid (s_ctrlport_req_rem_epid),
|
|
.s_ctrlport_req_rem_portid (s_ctrlport_req_rem_portid),
|
|
.s_ctrlport_req_data (s_ctrlport_req_data),
|
|
.s_ctrlport_req_byte_en (s_ctrlport_req_byte_en),
|
|
.s_ctrlport_req_has_time (s_ctrlport_req_has_time),
|
|
.s_ctrlport_req_time (s_ctrlport_req_time),
|
|
.s_ctrlport_resp_ack (s_ctrlport_resp_ack),
|
|
.s_ctrlport_resp_status (s_ctrlport_resp_status),
|
|
.s_ctrlport_resp_data (s_ctrlport_resp_data),
|
|
.m_ctrlport_clk (rfnoc_ctrl_clk),
|
|
.m_ctrlport_req_wr (m_req_wr),
|
|
.m_ctrlport_req_rd (m_req_rd),
|
|
.m_ctrlport_req_addr (m_req_addr),
|
|
.m_ctrlport_req_portid (),
|
|
.m_ctrlport_req_rem_epid (),
|
|
.m_ctrlport_req_rem_portid (),
|
|
.m_ctrlport_req_data (m_req_data),
|
|
.m_ctrlport_req_byte_en (),
|
|
.m_ctrlport_req_has_time (),
|
|
.m_ctrlport_req_time (),
|
|
.m_ctrlport_resp_ack (m_resp_ack),
|
|
.m_ctrlport_resp_status (m_resp_status),
|
|
.m_ctrlport_resp_data (m_resp_data)
|
|
);
|
|
|
|
ctrlport_splitter #(
|
|
.NUM_SLAVES (3+NUM_TIMEKEEPERS)
|
|
) ctrlport_splitter_i (
|
|
.ctrlport_clk (rfnoc_ctrl_clk),
|
|
.ctrlport_rst (rfnoc_ctrl_rst),
|
|
.s_ctrlport_req_wr (m_req_wr),
|
|
.s_ctrlport_req_rd (m_req_rd),
|
|
.s_ctrlport_req_addr (m_req_addr),
|
|
.s_ctrlport_req_data (m_req_data),
|
|
.s_ctrlport_req_byte_en (4'hF),
|
|
.s_ctrlport_req_has_time (1'b0),
|
|
.s_ctrlport_req_time (64'h0),
|
|
.s_ctrlport_resp_ack (m_resp_ack),
|
|
.s_ctrlport_resp_status (m_resp_status),
|
|
.s_ctrlport_resp_data (m_resp_data),
|
|
.m_ctrlport_req_wr ({timekeeper_req_wr, versioning_req_wr, global_regs_req_wr, dio_req_wr}),
|
|
.m_ctrlport_req_rd ({timekeeper_req_rd, versioning_req_rd, global_regs_req_rd, dio_req_rd}),
|
|
.m_ctrlport_req_addr ({timekeeper_req_addr, versioning_req_addr, global_regs_req_addr, dio_req_addr}),
|
|
.m_ctrlport_req_data ({timekeeper_req_data, versioning_req_data, global_regs_req_data, dio_req_data}),
|
|
.m_ctrlport_req_byte_en (),
|
|
.m_ctrlport_req_has_time (),
|
|
.m_ctrlport_req_time (),
|
|
.m_ctrlport_resp_ack ({timekeeper_resp_ack, versioning_resp_ack, global_regs_resp_ack, dio_resp_ack}),
|
|
.m_ctrlport_resp_status ({timekeeper_resp_status, versioning_resp_status, global_regs_resp_status, dio_resp_status}),
|
|
.m_ctrlport_resp_data ({timekeeper_resp_data, versioning_resp_data, global_regs_resp_data, dio_resp_data})
|
|
);
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// Global Registers
|
|
// -------------------------------------------------------------------
|
|
|
|
x4xx_global_regs #(
|
|
.REG_BASE (GLOBAL_REGS),
|
|
.REG_SIZE (GLOBAL_REGS_SIZE),
|
|
.CHDR_CLK_RATE (CHDR_CLK_RATE),
|
|
.CHDR_W (CHDR_W),
|
|
.RFNOC_PROTOVER (RFNOC_PROTOVER),
|
|
.NUM_TIMEKEEPERS (NUM_TIMEKEEPERS),
|
|
.PCIE_PRESENT (PCIE_PRESENT)
|
|
) x4xx_global_regs_i (
|
|
.s_ctrlport_clk (rfnoc_ctrl_clk),
|
|
.s_ctrlport_rst (rfnoc_ctrl_rst),
|
|
.s_ctrlport_req_wr (global_regs_req_wr),
|
|
.s_ctrlport_req_rd (global_regs_req_rd),
|
|
.s_ctrlport_req_addr (global_regs_req_addr),
|
|
.s_ctrlport_req_data (global_regs_req_data),
|
|
.s_ctrlport_resp_ack (global_regs_resp_ack),
|
|
.s_ctrlport_resp_status (global_regs_resp_status),
|
|
.s_ctrlport_resp_data (global_regs_resp_data),
|
|
.rfnoc_chdr_clk (rfnoc_chdr_clk),
|
|
.rfnoc_chdr_rst (rfnoc_chdr_rst),
|
|
.pps_select (pps_select),
|
|
.trig_io_select (trig_io_select),
|
|
.pll_sync_trigger (pll_sync_trigger),
|
|
.pll_sync_delay (pll_sync_delay),
|
|
.pll_sync_done (pll_sync_done),
|
|
.pps_brc_delay (pps_brc_delay),
|
|
.pps_prc_delay (pps_prc_delay),
|
|
.prc_rc0_divider (prc_rc0_divider),
|
|
.prc_rc1_divider (prc_rc1_divider),
|
|
.pps_rc_enabled (pps_rc_enabled),
|
|
.qsfp_port_0_0_info (qsfp_port_0_0_info),
|
|
.qsfp_port_0_1_info (qsfp_port_0_1_info),
|
|
.qsfp_port_0_2_info (qsfp_port_0_2_info),
|
|
.qsfp_port_0_3_info (qsfp_port_0_3_info),
|
|
.qsfp_port_1_0_info (qsfp_port_1_0_info),
|
|
.qsfp_port_1_1_info (qsfp_port_1_1_info),
|
|
.qsfp_port_1_2_info (qsfp_port_1_2_info),
|
|
.qsfp_port_1_3_info (qsfp_port_1_3_info),
|
|
.mfg_test_en_fabric_clk (mfg_test_en_fabric_clk),
|
|
.mfg_test_en_gty_rcv_clk (mfg_test_en_gty_rcv_clk),
|
|
.fpga_aux_ref (fpga_aux_ref),
|
|
.device_id (device_id)
|
|
);
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// Version Registers
|
|
// -------------------------------------------------------------------
|
|
|
|
x4xx_versioning_regs #(
|
|
.REG_BASE (VERSIONING_REGS)
|
|
) x4xx_versioning_regs_i (
|
|
.s_ctrlport_clk (rfnoc_ctrl_clk),
|
|
.s_ctrlport_rst (rfnoc_ctrl_rst),
|
|
.s_ctrlport_req_wr (versioning_req_wr),
|
|
.s_ctrlport_req_rd (versioning_req_rd),
|
|
.s_ctrlport_req_addr (versioning_req_addr),
|
|
.s_ctrlport_req_data (versioning_req_data),
|
|
.s_ctrlport_resp_ack (versioning_resp_ack),
|
|
.s_ctrlport_resp_status (versioning_resp_status),
|
|
.s_ctrlport_resp_data (versioning_resp_data),
|
|
.version_info (version_info)
|
|
);
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Timekeeper
|
|
//---------------------------------------------------------------------------
|
|
|
|
assign timekeeper_resp_status = {NUM_TIMEKEEPERS{CTRL_STS_OKAY}};
|
|
localparam TIMEKEEPERS = {TIMEKEEPER_B[CTRLPORT_ADDR_W-1:0], TIMEKEEPER_A[CTRLPORT_ADDR_W-1:0]};
|
|
|
|
genvar tk_i;
|
|
generate
|
|
for (tk_i = 0; tk_i < NUM_TIMEKEEPERS; tk_i = tk_i+1) begin : gen_timekeeper
|
|
timekeeper #(
|
|
.BASE_ADDR (TIMEKEEPERS[CTRLPORT_ADDR_W*tk_i+:CTRLPORT_ADDR_W]),
|
|
.TIME_INCREMENT (0)
|
|
) timekeeper_i (
|
|
.tb_clk (radio_clk[tk_i]),
|
|
.tb_rst (radio_rst[tk_i]),
|
|
.s_ctrlport_clk (rfnoc_ctrl_clk),
|
|
.s_ctrlport_req_wr (timekeeper_req_wr[tk_i]),
|
|
.s_ctrlport_req_rd (timekeeper_req_rd[tk_i]),
|
|
.s_ctrlport_req_addr (timekeeper_req_addr[CTRLPORT_ADDR_W*tk_i+:CTRLPORT_ADDR_W]),
|
|
.s_ctrlport_req_data (timekeeper_req_data[CTRLPORT_DATA_W*tk_i+:CTRLPORT_DATA_W]),
|
|
.s_ctrlport_resp_ack (timekeeper_resp_ack[tk_i]),
|
|
.s_ctrlport_resp_data (timekeeper_resp_data[CTRLPORT_DATA_W*tk_i+:CTRLPORT_DATA_W]),
|
|
.time_increment (radio_spc),
|
|
.sample_rx_stb (sample_rx_stb[tk_i]),
|
|
.pps (pps_radioclk[tk_i]),
|
|
.tb_timestamp (radio_time[64*tk_i+:64]),
|
|
.tb_timestamp_last_pps (),
|
|
.tb_period_ns_q32 (),
|
|
.tb_changed ()
|
|
);
|
|
end
|
|
endgenerate
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Radio CtrlPort Splitter
|
|
//-----------------------------------------------------------------------
|
|
|
|
// Radio CtrlPort endpoints
|
|
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 [ 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] radio_dio_req_wr;
|
|
wire [ 1*NUM_DBOARDS-1:0] radio_dio_req_rd;
|
|
wire [ 20*NUM_DBOARDS-1:0] radio_dio_req_addr;
|
|
wire [ 32*NUM_DBOARDS-1:0] radio_dio_req_data;
|
|
wire [ 1*NUM_DBOARDS-1:0] radio_dio_resp_ack;
|
|
wire [ 2*NUM_DBOARDS-1:0] radio_dio_resp_status;
|
|
wire [ 32*NUM_DBOARDS-1:0] radio_dio_resp_data;
|
|
|
|
wire [ 1*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_wr;
|
|
wire [ 1*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_rd;
|
|
wire [ 20*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_addr;
|
|
wire [ 32*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_data;
|
|
wire [ 1*NUM_DBOARDS-1:0] gpio_atr_ctrlport_resp_ack;
|
|
wire [ 2*NUM_DBOARDS-1:0] gpio_atr_ctrlport_resp_status;
|
|
wire [ 32*NUM_DBOARDS-1:0] gpio_atr_ctrlport_resp_data;
|
|
|
|
wire [ 1*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_wr;
|
|
wire [ 1*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_rd;
|
|
wire [ 20*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_addr;
|
|
wire [ 32*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_data;
|
|
wire [ 1*NUM_DBOARDS-1:0] gpio_spi_ctrlport_resp_ack;
|
|
wire [ 2*NUM_DBOARDS-1:0] gpio_spi_ctrlport_resp_status;
|
|
wire [ 32*NUM_DBOARDS-1:0] gpio_spi_ctrlport_resp_data;
|
|
|
|
// GPIO control signals from radio ctrlport endpoints to
|
|
// x4xx_dio.
|
|
wire [NUM_DBOARDS*32-1:0] atr_gpio_out;
|
|
wire [NUM_DBOARDS*32-1:0] atr_gpio_ddr;
|
|
|
|
wire [NUM_DBOARDS*32-1:0] spi_gpio_out;
|
|
wire [NUM_DBOARDS*32-1:0] spi_gpio_ddr;
|
|
|
|
genvar db_i, ch_i;
|
|
generate
|
|
for ( db_i = 0; db_i < NUM_DBOARDS; db_i = db_i + 1) begin : gen_radio_ctrlport
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Timed command processing
|
|
//----------------------------------------------------------------------------
|
|
|
|
wire [19:0] ctrlport_timed_req_addr;
|
|
wire [31:0] ctrlport_timed_req_data;
|
|
wire ctrlport_timed_req_rd;
|
|
wire ctrlport_timed_req_wr;
|
|
wire ctrlport_timed_resp_ack;
|
|
wire [31:0] ctrlport_timed_resp_data;
|
|
wire [ 1:0] ctrlport_timed_resp_status;
|
|
|
|
ctrlport_timer #(
|
|
.EXEC_LATE_CMDS(1)
|
|
) ctrlport_timer_i (
|
|
.clk (radio_clk[db_i]),
|
|
.rst (radio_rst[db_i]),
|
|
`ifdef X440
|
|
.time_now (radio_time[64*db_i+:64]),
|
|
.time_now_stb (sample_rx_stb[db_i]),
|
|
`else
|
|
.time_now (radio_time),
|
|
.time_now_stb (sample_rx_stb),
|
|
`endif
|
|
.time_ignore_bits (time_ignore_bits),
|
|
.s_ctrlport_req_wr (s_radio_ctrlport_req_wr [ 1*db_i+: 1]),
|
|
.s_ctrlport_req_rd (s_radio_ctrlport_req_rd [ 1*db_i+: 1]),
|
|
.s_ctrlport_req_addr (s_radio_ctrlport_req_addr [20*db_i+:20]),
|
|
.s_ctrlport_req_data (s_radio_ctrlport_req_data [32*db_i+:32]),
|
|
.s_ctrlport_req_byte_en (s_radio_ctrlport_req_byte_en [ 4*db_i+: 4]),
|
|
.s_ctrlport_req_has_time (s_radio_ctrlport_req_has_time [ 1*db_i+: 1]),
|
|
.s_ctrlport_req_time (s_radio_ctrlport_req_time [64*db_i+:64]),
|
|
.s_ctrlport_resp_ack (s_radio_ctrlport_resp_ack [ 1*db_i+: 1]),
|
|
.s_ctrlport_resp_status (s_radio_ctrlport_resp_status [ 2*db_i+: 2]),
|
|
.s_ctrlport_resp_data (s_radio_ctrlport_resp_data [32*db_i+:32]),
|
|
.m_ctrlport_req_wr (ctrlport_timed_req_wr),
|
|
.m_ctrlport_req_rd (ctrlport_timed_req_rd),
|
|
.m_ctrlport_req_addr (ctrlport_timed_req_addr),
|
|
.m_ctrlport_req_data (ctrlport_timed_req_data),
|
|
.m_ctrlport_req_byte_en (),
|
|
.m_ctrlport_resp_ack (ctrlport_timed_resp_ack),
|
|
.m_ctrlport_resp_status (ctrlport_timed_resp_status),
|
|
.m_ctrlport_resp_data (ctrlport_timed_resp_data)
|
|
);
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Radio Block 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_*), the ATR GPIO control for the DB state
|
|
// the current radio(db_i), the SPI controller of the radio, and DIO main
|
|
// control block(x4xx_dio).
|
|
// Refer to diagram in the RADIO_CTRLPORT_REGMAP Register map for a
|
|
// visual representation on how these interfaces are distributed.
|
|
|
|
// Register space offset calculation
|
|
localparam [19:0] DIO_SOURCE_CONTROL_OFFSET = DIO_WINDOW + DIO_SOURCE_CONTROL;
|
|
localparam [19:0] RADIO_GPIO_ATR_OFFSET = DIO_WINDOW + RADIO_GPIO_ATR_REGS;
|
|
localparam [19:0] DIGITAL_IFC_OFFSET = DIO_WINDOW + DIGITAL_IFC_REGS;
|
|
|
|
// Register space size calculation
|
|
localparam [31:0] RFDC_TIMING_WINDOW_SIZE_W = $clog2(RFDC_TIMING_WINDOW_SIZE);
|
|
localparam [31:0] DB_WINDOW_SIZE_W = $clog2(DB_WINDOW_SIZE);
|
|
localparam [31:0] DIO_SOURCE_CONTROL_SIZE_W = $clog2(DIO_SOURCE_CONTROL_SIZE);
|
|
localparam [31:0] RADIO_GPIO_ATR_SIZE_W = $clog2(RADIO_GPIO_ATR_REGS_SIZE);
|
|
localparam [31:0] DIGITAL_IFC_REGS_SIZE_W = $clog2(DIGITAL_IFC_REGS_SIZE);
|
|
|
|
ctrlport_decoder_param #(
|
|
.NUM_SLAVES (5),
|
|
.PORT_BASE ({ DIGITAL_IFC_OFFSET,
|
|
DIO_SOURCE_CONTROL_OFFSET,
|
|
RADIO_GPIO_ATR_OFFSET,
|
|
RFDC_TIMING_WINDOW[19:0],
|
|
DB_WINDOW[19:0]
|
|
}),
|
|
.PORT_ADDR_W ({ DIGITAL_IFC_REGS_SIZE_W,
|
|
DIO_SOURCE_CONTROL_SIZE_W,
|
|
RADIO_GPIO_ATR_SIZE_W,
|
|
RFDC_TIMING_WINDOW_SIZE_W,
|
|
DB_WINDOW_SIZE_W
|
|
})
|
|
) ctrlport_decoder_param_i (
|
|
.ctrlport_clk ( radio_clk[db_i] ),
|
|
.ctrlport_rst ( radio_rst[db_i] ),
|
|
.s_ctrlport_req_wr ( ctrlport_timed_req_wr),
|
|
.s_ctrlport_req_rd ( ctrlport_timed_req_rd),
|
|
.s_ctrlport_req_addr ( ctrlport_timed_req_addr),
|
|
.s_ctrlport_req_data ( ctrlport_timed_req_data),
|
|
.s_ctrlport_req_byte_en ( 4'hF),
|
|
.s_ctrlport_req_has_time ( 1'b0),
|
|
.s_ctrlport_req_time ( 64'h0),
|
|
.s_ctrlport_resp_ack ( ctrlport_timed_resp_ack),
|
|
.s_ctrlport_resp_status ( ctrlport_timed_resp_status),
|
|
.s_ctrlport_resp_data ( ctrlport_timed_resp_data),
|
|
.m_ctrlport_req_wr ({ gpio_spi_ctrlport_req_wr [ 1*db_i+: 1],
|
|
radio_dio_req_wr [ 1*db_i+: 1],
|
|
gpio_atr_ctrlport_req_wr [ 1*db_i+: 1],
|
|
rf_ctrlport_req_wr [ 1*db_i+: 1],
|
|
m_radio_ctrlport_req_wr [ 1*db_i+: 1] }),
|
|
.m_ctrlport_req_rd ({ gpio_spi_ctrlport_req_rd [ 1*db_i+: 1],
|
|
radio_dio_req_rd [ 1*db_i+: 1],
|
|
gpio_atr_ctrlport_req_rd [ 1*db_i+: 1],
|
|
rf_ctrlport_req_rd [ 1*db_i+: 1],
|
|
m_radio_ctrlport_req_rd [ 1*db_i+: 1] }),
|
|
.m_ctrlport_req_addr ({ gpio_spi_ctrlport_req_addr [20*db_i+:20],
|
|
radio_dio_req_addr [20*db_i+:20],
|
|
gpio_atr_ctrlport_req_addr [20*db_i+:20],
|
|
rf_ctrlport_req_addr [20*db_i+:20],
|
|
m_radio_ctrlport_req_addr [20*db_i+:20] }),
|
|
.m_ctrlport_req_data ({ gpio_spi_ctrlport_req_data [32*db_i+:32],
|
|
radio_dio_req_data [32*db_i+:32],
|
|
gpio_atr_ctrlport_req_data [32*db_i+:32],
|
|
rf_ctrlport_req_data [32*db_i+:32],
|
|
m_radio_ctrlport_req_data [32*db_i+:32] }),
|
|
.m_ctrlport_req_byte_en (),
|
|
.m_ctrlport_req_has_time (),
|
|
.m_ctrlport_req_time (),
|
|
.m_ctrlport_resp_ack ({ gpio_spi_ctrlport_resp_ack [ 1*db_i+: 1],
|
|
radio_dio_resp_ack [ 1*db_i+: 1],
|
|
gpio_atr_ctrlport_resp_ack [ 1*db_i+: 1],
|
|
rf_ctrlport_resp_ack [ 1*db_i+: 1],
|
|
m_radio_ctrlport_resp_ack [ 1*db_i+: 1] }),
|
|
.m_ctrlport_resp_status ({ gpio_spi_ctrlport_resp_status [ 2*db_i+: 2],
|
|
radio_dio_resp_status [ 2*db_i+: 2],
|
|
gpio_atr_ctrlport_resp_status [ 2*db_i+: 2],
|
|
rf_ctrlport_resp_status [ 2*db_i+: 2],
|
|
m_radio_ctrlport_resp_status [ 2*db_i+: 2] }),
|
|
.m_ctrlport_resp_data ({ gpio_spi_ctrlport_resp_data [32*db_i+:32],
|
|
radio_dio_resp_data [32*db_i+:32],
|
|
gpio_atr_ctrlport_resp_data [32*db_i+:32],
|
|
rf_ctrlport_resp_data [32*db_i+:32],
|
|
m_radio_ctrlport_resp_data [32*db_i+:32] })
|
|
);
|
|
|
|
// Compute ATR state for this radio
|
|
wire [ 2*NUM_CH_PER_DB-1:0] db_state;
|
|
|
|
for ( ch_i = 0; ch_i < NUM_CH_PER_DB; ch_i = ch_i + 1) begin: gen_db_state_ch
|
|
assign db_state[ch_i*2] = rx_running[NUM_CH_PER_DB*db_i+ch_i];
|
|
assign db_state[ch_i*2+1] = tx_running[NUM_CH_PER_DB*db_i+ch_i];
|
|
end
|
|
|
|
x4xx_gpio_atr #(
|
|
.REG_SIZE (RADIO_GPIO_ATR_REGS_SIZE),
|
|
.NUM_CH_PER_DB (NUM_CH_PER_DB)
|
|
) x4xx_gpio_atr_i (
|
|
.ctrlport_clk (radio_clk[db_i]),
|
|
.ctrlport_rst (radio_rst[db_i]),
|
|
.s_ctrlport_req_wr (gpio_atr_ctrlport_req_wr [ 1*db_i+: 1]),
|
|
.s_ctrlport_req_rd (gpio_atr_ctrlport_req_rd [ 1*db_i+: 1]),
|
|
.s_ctrlport_req_addr (gpio_atr_ctrlport_req_addr [20*db_i+:20]),
|
|
.s_ctrlport_req_data (gpio_atr_ctrlport_req_data [32*db_i+:32]),
|
|
.s_ctrlport_resp_ack (gpio_atr_ctrlport_resp_ack [ 1*db_i+: 1]),
|
|
.s_ctrlport_resp_status (gpio_atr_ctrlport_resp_status [ 2*db_i+: 2]),
|
|
.s_ctrlport_resp_data (gpio_atr_ctrlport_resp_data [32*db_i+:32]),
|
|
.db_state (db_state),
|
|
.gpio_in ({4'b0, gpio_in_b, 4'b0, gpio_in_a}),
|
|
.gpio_out (atr_gpio_out[db_i*32+: 32]),
|
|
.gpio_ddr (atr_gpio_ddr[db_i*32+: 32])
|
|
);
|
|
|
|
x4xx_gpio_spi #(
|
|
.NUM_SLAVES (2)
|
|
) x4xx_gpio_spi_i(
|
|
.ctrlport_clk (radio_clk[db_i]),
|
|
.ctrlport_clk_2x (radio_clk_2x[db_i]),
|
|
.ctrlport_rst (radio_rst[db_i]),
|
|
.s_ctrlport_req_wr (gpio_spi_ctrlport_req_wr [ 1*db_i+: 1]),
|
|
.s_ctrlport_req_rd (gpio_spi_ctrlport_req_rd [ 1*db_i+: 1]),
|
|
.s_ctrlport_req_addr (gpio_spi_ctrlport_req_addr [20*db_i+:20]),
|
|
.s_ctrlport_req_data (gpio_spi_ctrlport_req_data [32*db_i+:32]),
|
|
.s_ctrlport_resp_ack (gpio_spi_ctrlport_resp_ack [ 1*db_i+: 1]),
|
|
.s_ctrlport_resp_status (gpio_spi_ctrlport_resp_status [ 2*db_i+: 2]),
|
|
.s_ctrlport_resp_data (gpio_spi_ctrlport_resp_data [32*db_i+:32]),
|
|
.gpio_out (spi_gpio_out[db_i*32+: 32]),
|
|
.gpio_ddr (spi_gpio_ddr[db_i*32+: 32]),
|
|
.gpio_in ({4'b0, gpio_in_b, 4'b0, gpio_in_a})
|
|
);
|
|
|
|
end
|
|
endgenerate
|
|
|
|
// Synchronize DB1 ctrlport to radio_clk[0] domain
|
|
wire radio1_crossed_req_wr;
|
|
wire radio1_crossed_req_rd;
|
|
wire [ 19:0] radio1_crossed_req_addr;
|
|
wire [ 31:0] radio1_crossed_req_data;
|
|
wire radio1_crossed_resp_ack;
|
|
wire [ 1:0] radio1_crossed_resp_status;
|
|
wire [ 31:0] radio1_crossed_resp_data;
|
|
|
|
generate
|
|
// Crossing only necessary if there are multiple timekeepers/radio rates.
|
|
if (NUM_TIMEKEEPERS > 1) begin : gen_ctrlport_dio_clk_cross
|
|
ctrlport_clk_cross ctrlport_clk_radio_dio (
|
|
.rst (radio_rst[1]),
|
|
.s_ctrlport_clk (radio_clk[1]),
|
|
.s_ctrlport_req_wr (radio_dio_req_wr[1*1 +: 1]),
|
|
.s_ctrlport_req_rd (radio_dio_req_rd[1*1 +: 1]),
|
|
.s_ctrlport_req_addr (radio_dio_req_addr[1*20 +: 20]),
|
|
.s_ctrlport_req_portid (10'b0),
|
|
.s_ctrlport_req_rem_epid (16'b0),
|
|
.s_ctrlport_req_rem_portid (10'b0),
|
|
.s_ctrlport_req_data (radio_dio_req_data[1*32 +: 32]),
|
|
.s_ctrlport_req_byte_en (4'hF),
|
|
.s_ctrlport_req_has_time (1'b0),
|
|
.s_ctrlport_req_time (64'b0),
|
|
.s_ctrlport_resp_ack (radio_dio_resp_ack[1*1 +: 1]),
|
|
.s_ctrlport_resp_status (radio_dio_resp_status[1*2 +: 2]),
|
|
.s_ctrlport_resp_data (radio_dio_resp_data[1*32 +: 32]),
|
|
.m_ctrlport_clk (radio_clk[0]),
|
|
.m_ctrlport_req_wr (radio1_crossed_req_wr),
|
|
.m_ctrlport_req_rd (radio1_crossed_req_rd),
|
|
.m_ctrlport_req_addr (radio1_crossed_req_addr),
|
|
.m_ctrlport_req_portid (),
|
|
.m_ctrlport_req_rem_epid (),
|
|
.m_ctrlport_req_rem_portid (),
|
|
.m_ctrlport_req_data (radio1_crossed_req_data),
|
|
.m_ctrlport_req_byte_en (),
|
|
.m_ctrlport_req_has_time (),
|
|
.m_ctrlport_req_time (),
|
|
.m_ctrlport_resp_ack (radio1_crossed_resp_ack),
|
|
.m_ctrlport_resp_status (radio1_crossed_resp_status),
|
|
.m_ctrlport_resp_data (radio1_crossed_resp_data)
|
|
);
|
|
end else begin
|
|
assign radio1_crossed_req_wr = radio_dio_req_wr[1*1 +: 1];
|
|
assign radio1_crossed_req_rd = radio_dio_req_rd[1*1 +: 1];
|
|
assign radio1_crossed_req_addr = radio_dio_req_addr[1*20 +: 20];
|
|
assign radio1_crossed_req_data = radio_dio_req_data[1*32 +: 32];
|
|
assign radio_dio_resp_ack[1*1 +: 1] = radio1_crossed_resp_ack;
|
|
assign radio_dio_resp_status[1*2 +: 2] = radio1_crossed_resp_status;
|
|
assign radio_dio_resp_data[1*32 +: 32] = radio1_crossed_resp_data;
|
|
end
|
|
endgenerate
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
// RF Timing Reset Control
|
|
//-------------------------------------------------------------------------
|
|
|
|
rfdc_timing_control #(
|
|
.NUM_DBOARDS (NUM_DBOARDS)
|
|
) rfdc_timing_control_i (
|
|
.clk (radio_clk),
|
|
.rst (radio_rst),
|
|
.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_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[0]),
|
|
.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_decoder_param #(
|
|
.NUM_SLAVES (1),
|
|
.PORT_BASE ({DIO[19:0]}),
|
|
.PORT_ADDR_W ({$clog2(DIO_SIZE)})
|
|
) ctrlport_decoder_dio_window (
|
|
.ctrlport_clk (radio_clk[0]),
|
|
.ctrlport_rst (radio_rst[0]),
|
|
.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_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_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 dio 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[0]),
|
|
.ctrlport_rst (radio_rst[0]),
|
|
.s_ctrlport_req_wr ({radio1_crossed_req_wr, radio_dio_req_wr[0*1 +: 1], windowed_mpm_dio_req_wr}),
|
|
.s_ctrlport_req_rd ({radio1_crossed_req_rd, radio_dio_req_rd[0*1 +: 1], windowed_mpm_dio_req_rd}),
|
|
.s_ctrlport_req_addr ({radio1_crossed_req_addr, radio_dio_req_addr[0*20 +: 20], 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 ({radio1_crossed_req_data, radio_dio_req_data[0*32 +: 32], 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 ({radio1_crossed_resp_ack, radio_dio_resp_ack[0*1 +: 1], windowed_mpm_dio_resp_ack}),
|
|
.s_ctrlport_resp_status ({radio1_crossed_resp_status, radio_dio_resp_status[0*2 +: 2], windowed_mpm_dio_resp_status}),
|
|
.s_ctrlport_resp_data ({radio1_crossed_resp_data, radio_dio_resp_data[0*32 +: 32], 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_SIZE (DIO_SIZE),
|
|
.NUM_DBOARDS (NUM_DBOARDS)
|
|
) x4xx_dio_i (
|
|
.ctrlport_clk (radio_clk[0]),
|
|
.ctrlport_rst (radio_rst[0]),
|
|
.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),
|
|
.gpio_out_b (gpio_out_b),
|
|
.gpio_en_a (gpio_en_a),
|
|
.gpio_en_b (gpio_en_b),
|
|
.atr_gpio_out (atr_gpio_out),
|
|
.atr_gpio_ddr (atr_gpio_ddr),
|
|
.ps_gpio_out ({4'b0, ps_gpio_out_b, 4'b0, ps_gpio_out_a}),
|
|
.ps_gpio_ddr ({4'b0, ps_gpio_ddr_b, 4'b0, ps_gpio_ddr_a}),
|
|
.digital_ifc_gpio_out_radio0 (spi_gpio_out[31:0]),
|
|
.digital_ifc_gpio_ddr_radio0 (spi_gpio_ddr[31:0]),
|
|
.digital_ifc_gpio_out_radio1 (spi_gpio_out[63:32]),
|
|
.digital_ifc_gpio_ddr_radio1 (spi_gpio_ddr[63:32]),
|
|
.user_app_in_a (gpio_in_fabric_a),
|
|
.user_app_in_b (gpio_in_fabric_b),
|
|
.user_app_out_a (gpio_out_fabric_a),
|
|
.user_app_out_b (gpio_out_fabric_b)
|
|
);
|
|
|
|
assign ps_gpio_in_a = gpio_in_fabric_a;
|
|
assign ps_gpio_in_b = gpio_in_fabric_b;
|
|
|
|
endmodule
|
|
|
|
|
|
`default_nettype wire
|
|
|
|
|
|
//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.
|
|
// The following diagram displays the distribution of the CtrlPort
|
|
// interface to the different modules it interacts with.
|
|
// <img src = "../common/x4xx_core_common_buses.svg"
|
|
// </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="RADIO_DIO_REGMAP">
|
|
// <info>DIO control interface. Interacts with the DIO source selection
|
|
// block, ATR-based DIO control and the DIO digital 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
|
|
// from the ARM_AXI_HPM0_FPD port.
|
|
//
|
|
// The registers contained here conform the mboard-regs node that MPM uses
|
|
// to manage general FPGA control/status calls, such as versioning,
|
|
// timekeeper, GPIO, etc.
|
|
//
|
|
// The following diagram shows how the communication bus interacts with the
|
|
// modules in CORE_REGS.
|
|
// <img src = "../common/x4xx_core_common_buses.svg"
|
|
// </info>
|
|
// <group name="CORE_REGS">
|
|
// <window name="GLOBAL_REGS" offset="0x0" size="0xC00" targetregmap="GLOBAL_REGS_REGMAP">
|
|
// <info>Window to access global registers in the FPGA.</info>
|
|
// </window>
|
|
// <window name="VERSIONING_REGS" offset="0xC00" size="0x400" targetregmap="VERSIONING_REGS_REGMAP">
|
|
// <info>Window to access versioning registers in the FPGA.</info>
|
|
// </window>
|
|
// <window name="TIMEKEEPER_A" offset="0x1000" size="0x20">
|
|
// <info>Window to access the timekeeper register map.</info>
|
|
// </window>
|
|
// <window name="TIMEKEEPER_B" offset="0x1100" size="0x20">
|
|
// <info>Window to access the timekeeper register map.</info>
|
|
// </window>
|
|
// <window name="DIO" offset="0x2000" size="0x40" targetregmap="DIO_REGMAP">
|
|
// <info>Window to access the DIO register map.</info>
|
|
// </window>
|
|
// </group>
|
|
//</regmap>
|
|
|
|
//<regmap name="RADIO_DIO_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
|
|
// <info>
|
|
// This map contains register windows for controlling the different sources
|
|
// that drive the state of DIO lines.
|
|
// </info>
|
|
// <group name="DIO_SOURCES">
|
|
// <window name="RADIO_GPIO_ATR_REGS" offset="0x0" size="0x1000" targetregmap="GPIO_ATR_REGMAP">
|
|
// <info>Contains controls for DIO behavior based on the ATR state of the accessed radio</info>
|
|
// </window>
|
|
// <window name="DIO_SOURCE_CONTROL" offset="0x1000" size="0x1000" targetregmap="DIO_REGMAP">
|
|
// <info>Window to access the DIO register map through the control port from the radio blocks.</info>
|
|
// </window>
|
|
// <window name="DIGITAL_IFC_REGS" offset="0x2000" size="0x1000" targetregmap="DIG_IFC_REGMAP">
|
|
// <info>Register space reserved for configuring a digital interface over the GPIO lines.
|
|
// Currently, SPI is the only supported protocol.</info>
|
|
// </window>
|
|
// </group>
|
|
//</regmap>
|
|
|
|
//XmlParse xml_off
|