fpga: x400: Add GPIO control via ATR and DB state
Original-commit: 9335939b9b3ab85cee5908ff3357f9e7819e3366
This commit is contained in:
committed by
Wade Fife
parent
4edae39d9e
commit
962d01e583
@@ -73,6 +73,7 @@ x4xx_core_common.v \
|
||||
x4xx_global_regs.v \
|
||||
x4xx_versioning_regs.v \
|
||||
x4xx_dio.v \
|
||||
x4xx_gpio_atr.v \
|
||||
rf/100m/rf_core_100m.v \
|
||||
rf/200m/rf_core_200m.v \
|
||||
rf/200m/rf_down_4to2.v \
|
||||
|
||||
@@ -281,7 +281,12 @@
|
||||
<p><span class="register" id="a_DIO_REGMAP|DIO_MASTER_REGISTER" onclick="a('DIO_REGMAP|DIO_MASTER_REGISTER');">DIO_MASTER_REGISTER</span></p>
|
||||
<p><span class="register" id="a_DIO_REGMAP|DIO_DIRECTION_REGISTER" onclick="a('DIO_REGMAP|DIO_DIRECTION_REGISTER');">DIO_DIRECTION_REGISTER</span></p>
|
||||
<p><span class="register" id="a_DIO_REGMAP|DIO_INPUT_REGISTER" onclick="a('DIO_REGMAP|DIO_INPUT_REGISTER');">DIO_INPUT_REGISTER</span></p>
|
||||
<p><span class="register" id="a_DIO_REGMAP|DIO_OUTPUT_REGISTER" onclick="a('DIO_REGMAP|DIO_OUTPUT_REGISTER');">DIO_OUTPUT_REGISTER</span></p>
|
||||
<p><span class="register" id="a_DIO_REGMAP|DIO_OUTPUT_REGISTER" onclick="a('DIO_REGMAP|DIO_OUTPUT_REGISTER');">DIO_OUTPUT_REGISTER</span></p>
|
||||
<p><span class="register" id="a_DIO_REGMAP|DIO_SOURCE_REGISTER" onclick="a('DIO_REGMAP|DIO_SOURCE_REGISTER');">DIO_SOURCE_REGISTER</span></p>
|
||||
<p><span class="register" id="a_DIO_REGMAP|RADIO_SOURCE_REGISTER" onclick="a('DIO_REGMAP|RADIO_SOURCE_REGISTER');">RADIO_SOURCE_REGISTER</span></p>
|
||||
<p><span class="register" id="a_DIO_REGMAP|INTERFACE_DIO_SELECT" onclick="a('DIO_REGMAP|INTERFACE_DIO_SELECT');">INTERFACE_DIO_SELECT</span></p>
|
||||
<p><span class="register" id="a_DIO_REGMAP|DIO_OVERRIDE" onclick="a('DIO_REGMAP|DIO_OVERRIDE');">DIO_OVERRIDE</span></p>
|
||||
<p><span class="register" id="a_DIO_REGMAP|SW_DIO_CONTROL" onclick="a('DIO_REGMAP|SW_DIO_CONTROL');">SW_DIO_CONTROL</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
@@ -346,6 +351,23 @@
|
||||
<p><span class="register" id="a_GLOBAL_REGS_REGMAP|QSFP_PORT_1_3_INFO_REG" onclick="a('GLOBAL_REGS_REGMAP|QSFP_PORT_1_3_INFO_REG');">QSFP_PORT_1_3_INFO_REG</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<span class="pm" id="pm_GPIO_ATR_REGMAP" onclick="pm('GPIO_ATR_REGMAP');">+</span>
|
||||
<span class="regmap" id="a_GPIO_ATR_REGMAP" onclick="a('GPIO_ATR_REGMAP');">GPIO_ATR_REGMAP</span>
|
||||
</p> <div class="sh" id="div_GPIO_ATR_REGMAP">
|
||||
<p>
|
||||
<span class="pm" id="pm_GPIO_ATR_REGMAP|GPIO_ATR_REGS" onclick="pm('GPIO_ATR_REGMAP|GPIO_ATR_REGS');">+</span>
|
||||
<span class="group" id="a_GPIO_ATR_REGMAP|GPIO_ATR_REGS" onclick="a('GPIO_ATR_REGMAP|GPIO_ATR_REGS');">GPIO_ATR_REGS</span>
|
||||
</p>
|
||||
<div class="sh" id="div_GPIO_ATR_REGMAP|GPIO_ATR_REGS">
|
||||
<p><span class="register" id="a_GPIO_ATR_REGMAP|ATR_STATE" onclick="a('GPIO_ATR_REGMAP|ATR_STATE');">ATR_STATE</span></p>
|
||||
<p><span class="register" id="a_GPIO_ATR_REGMAP|CLASSIC_ATR_CONFIG" onclick="a('GPIO_ATR_REGMAP|CLASSIC_ATR_CONFIG');">CLASSIC_ATR_CONFIG</span></p>
|
||||
<p><span class="register" id="a_GPIO_ATR_REGMAP|ATR_OPTION_REGISTRER" onclick="a('GPIO_ATR_REGMAP|ATR_OPTION_REGISTRER');">ATR_OPTION_REGISTRER</span></p>
|
||||
<p><span class="register" id="a_GPIO_ATR_REGMAP|GPIO_DIR" onclick="a('GPIO_ATR_REGMAP|GPIO_DIR');">GPIO_DIR</span></p>
|
||||
<p><span class="register" id="a_GPIO_ATR_REGMAP|GPIO_DISABLED" onclick="a('GPIO_ATR_REGMAP|GPIO_DISABLED');">GPIO_DISABLED</span></p>
|
||||
<p><span class="register" id="a_GPIO_ATR_REGMAP|GPIO_IN" onclick="a('GPIO_ATR_REGMAP|GPIO_IN');">GPIO_IN</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<span class="pm" id="pm_JTAG_REGMAP" onclick="pm('JTAG_REGMAP');">+</span>
|
||||
<span class="regmap" id="a_JTAG_REGMAP" onclick="a('JTAG_REGMAP');">JTAG_REGMAP</span>
|
||||
@@ -547,6 +569,19 @@
|
||||
<p><span class="register" id="a_RADIO_CTRLPORT_REGMAP|DIO_WINDOW" onclick="a('RADIO_CTRLPORT_REGMAP|DIO_WINDOW');">DIO_WINDOW</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<span class="pm" id="pm_RADIO_DIO_REGMAP" onclick="pm('RADIO_DIO_REGMAP');">+</span>
|
||||
<span class="regmap" id="a_RADIO_DIO_REGMAP" onclick="a('RADIO_DIO_REGMAP');">RADIO_DIO_REGMAP</span>
|
||||
</p> <div class="sh" id="div_RADIO_DIO_REGMAP">
|
||||
<p>
|
||||
<span class="pm" id="pm_RADIO_DIO_REGMAP|DIO_SOURCES" onclick="pm('RADIO_DIO_REGMAP|DIO_SOURCES');">+</span>
|
||||
<span class="group" id="a_RADIO_DIO_REGMAP|DIO_SOURCES" onclick="a('RADIO_DIO_REGMAP|DIO_SOURCES');">DIO_SOURCES</span>
|
||||
</p>
|
||||
<div class="sh" id="div_RADIO_DIO_REGMAP|DIO_SOURCES">
|
||||
<p><span class="register" id="a_RADIO_DIO_REGMAP|RADIO_GPIO_ATR_REGS" onclick="a('RADIO_DIO_REGMAP|RADIO_GPIO_ATR_REGS');">RADIO_GPIO_ATR_REGS</span></p>
|
||||
<p><span class="register" id="a_RADIO_DIO_REGMAP|DIO_SOURCE_CONTROL" onclick="a('RADIO_DIO_REGMAP|DIO_SOURCE_CONTROL');">DIO_SOURCE_CONTROL</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<span class="pm" id="pm_RECONFIG_REGMAP" onclick="pm('RECONFIG_REGMAP');">+</span>
|
||||
<span class="regmap" id="a_RECONFIG_REGMAP" onclick="a('RECONFIG_REGMAP');">RECONFIG_REGMAP</span>
|
||||
|
||||
+1788
-38
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 37 KiB |
@@ -38,4 +38,4 @@
|
||||
|
||||
// DIO Window (from x4xx_core_common.v)
|
||||
localparam DIO = 'h2000; // Window Offset
|
||||
localparam DIO_SIZE = 'h20; // size in bytes
|
||||
localparam DIO_SIZE = 'h40; // size in bytes
|
||||
|
||||
@@ -15,11 +15,26 @@
|
||||
// DIO_DIRECTION_REGISTER : 0x4 (x4xx_dio.v)
|
||||
// DIO_INPUT_REGISTER : 0x8 (x4xx_dio.v)
|
||||
// DIO_OUTPUT_REGISTER : 0xC (x4xx_dio.v)
|
||||
// DIO_SOURCE_REGISTER : 0x10 (x4xx_dio.v)
|
||||
// RADIO_SOURCE_REGISTER : 0x14 (x4xx_dio.v)
|
||||
// INTERFACE_DIO_SELECT : 0x18 (x4xx_dio.v)
|
||||
// DIO_OVERRIDE : 0x1C (x4xx_dio.v)
|
||||
// SW_DIO_CONTROL : 0x20 (x4xx_dio.v)
|
||||
|
||||
//===============================================================================
|
||||
// RegTypes
|
||||
//===============================================================================
|
||||
|
||||
// DIO_CONTROL_REG Type (from x4xx_dio.v)
|
||||
localparam DIO_CONTROL_REG_SIZE = 32;
|
||||
localparam DIO_CONTROL_REG_MASK = 32'hFFF0FFF;
|
||||
localparam DIO_PORT_A_SIZE = 12; //DIO_CONTROL_REG:DIO_PORT_A
|
||||
localparam DIO_PORT_A_MSB = 11; //DIO_CONTROL_REG:DIO_PORT_A
|
||||
localparam DIO_PORT_A = 0; //DIO_CONTROL_REG:DIO_PORT_A
|
||||
localparam DIO_PORT_B_SIZE = 12; //DIO_CONTROL_REG:DIO_PORT_B
|
||||
localparam DIO_PORT_B_MSB = 27; //DIO_CONTROL_REG:DIO_PORT_B
|
||||
localparam DIO_PORT_B = 16; //DIO_CONTROL_REG:DIO_PORT_B
|
||||
|
||||
//===============================================================================
|
||||
// Register Group DIO_REGS
|
||||
//===============================================================================
|
||||
@@ -27,43 +42,35 @@
|
||||
// DIO_MASTER_REGISTER Register (from x4xx_dio.v)
|
||||
localparam DIO_MASTER_REGISTER = 'h0; // Register Offset
|
||||
localparam DIO_MASTER_REGISTER_SIZE = 32; // register width in bits
|
||||
localparam DIO_MASTER_REGISTER_MASK = 32'hFFF0FFF;
|
||||
localparam DIO_MASTER_A_SIZE = 12; //DIO_MASTER_REGISTER:DIO_MASTER_A
|
||||
localparam DIO_MASTER_A_MSB = 11; //DIO_MASTER_REGISTER:DIO_MASTER_A
|
||||
localparam DIO_MASTER_A = 0; //DIO_MASTER_REGISTER:DIO_MASTER_A
|
||||
localparam DIO_MASTER_B_SIZE = 12; //DIO_MASTER_REGISTER:DIO_MASTER_B
|
||||
localparam DIO_MASTER_B_MSB = 27; //DIO_MASTER_REGISTER:DIO_MASTER_B
|
||||
localparam DIO_MASTER_B = 16; //DIO_MASTER_REGISTER:DIO_MASTER_B
|
||||
|
||||
// DIO_DIRECTION_REGISTER Register (from x4xx_dio.v)
|
||||
localparam DIO_DIRECTION_REGISTER = 'h4; // Register Offset
|
||||
localparam DIO_DIRECTION_REGISTER_SIZE = 32; // register width in bits
|
||||
localparam DIO_DIRECTION_REGISTER_MASK = 32'hFFF0FFF;
|
||||
localparam DIO_DIRECTION_A_SIZE = 12; //DIO_DIRECTION_REGISTER:DIO_DIRECTION_A
|
||||
localparam DIO_DIRECTION_A_MSB = 11; //DIO_DIRECTION_REGISTER:DIO_DIRECTION_A
|
||||
localparam DIO_DIRECTION_A = 0; //DIO_DIRECTION_REGISTER:DIO_DIRECTION_A
|
||||
localparam DIO_DIRECTION_B_SIZE = 12; //DIO_DIRECTION_REGISTER:DIO_DIRECTION_B
|
||||
localparam DIO_DIRECTION_B_MSB = 27; //DIO_DIRECTION_REGISTER:DIO_DIRECTION_B
|
||||
localparam DIO_DIRECTION_B = 16; //DIO_DIRECTION_REGISTER:DIO_DIRECTION_B
|
||||
|
||||
// DIO_INPUT_REGISTER Register (from x4xx_dio.v)
|
||||
localparam DIO_INPUT_REGISTER = 'h8; // Register Offset
|
||||
localparam DIO_INPUT_REGISTER_SIZE = 32; // register width in bits
|
||||
localparam DIO_INPUT_REGISTER_MASK = 32'hFFF0FFF;
|
||||
localparam DIO_INPUT_A_SIZE = 12; //DIO_INPUT_REGISTER:DIO_INPUT_A
|
||||
localparam DIO_INPUT_A_MSB = 11; //DIO_INPUT_REGISTER:DIO_INPUT_A
|
||||
localparam DIO_INPUT_A = 0; //DIO_INPUT_REGISTER:DIO_INPUT_A
|
||||
localparam DIO_INPUT_B_SIZE = 12; //DIO_INPUT_REGISTER:DIO_INPUT_B
|
||||
localparam DIO_INPUT_B_MSB = 27; //DIO_INPUT_REGISTER:DIO_INPUT_B
|
||||
localparam DIO_INPUT_B = 16; //DIO_INPUT_REGISTER:DIO_INPUT_B
|
||||
|
||||
// DIO_OUTPUT_REGISTER Register (from x4xx_dio.v)
|
||||
localparam DIO_OUTPUT_REGISTER = 'hC; // Register Offset
|
||||
localparam DIO_OUTPUT_REGISTER_SIZE = 32; // register width in bits
|
||||
localparam DIO_OUTPUT_REGISTER_MASK = 32'hFFF0FFF;
|
||||
localparam DIO_OUTPUT_A_SIZE = 12; //DIO_OUTPUT_REGISTER:DIO_OUTPUT_A
|
||||
localparam DIO_OUTPUT_A_MSB = 11; //DIO_OUTPUT_REGISTER:DIO_OUTPUT_A
|
||||
localparam DIO_OUTPUT_A = 0; //DIO_OUTPUT_REGISTER:DIO_OUTPUT_A
|
||||
localparam DIO_OUTPUT_B_SIZE = 12; //DIO_OUTPUT_REGISTER:DIO_OUTPUT_B
|
||||
localparam DIO_OUTPUT_B_MSB = 27; //DIO_OUTPUT_REGISTER:DIO_OUTPUT_B
|
||||
localparam DIO_OUTPUT_B = 16; //DIO_OUTPUT_REGISTER:DIO_OUTPUT_B
|
||||
|
||||
// DIO_SOURCE_REGISTER Register (from x4xx_dio.v)
|
||||
localparam DIO_SOURCE_REGISTER = 'h10; // Register Offset
|
||||
localparam DIO_SOURCE_REGISTER_SIZE = 32; // register width in bits
|
||||
|
||||
// RADIO_SOURCE_REGISTER Register (from x4xx_dio.v)
|
||||
localparam RADIO_SOURCE_REGISTER = 'h14; // Register Offset
|
||||
localparam RADIO_SOURCE_REGISTER_SIZE = 32; // register width in bits
|
||||
|
||||
// INTERFACE_DIO_SELECT Register (from x4xx_dio.v)
|
||||
localparam INTERFACE_DIO_SELECT = 'h18; // Register Offset
|
||||
localparam INTERFACE_DIO_SELECT_SIZE = 32; // register width in bits
|
||||
|
||||
// DIO_OVERRIDE Register (from x4xx_dio.v)
|
||||
localparam DIO_OVERRIDE = 'h1C; // Register Offset
|
||||
localparam DIO_OVERRIDE_SIZE = 32; // register width in bits
|
||||
|
||||
// SW_DIO_CONTROL Register (from x4xx_dio.v)
|
||||
localparam SW_DIO_CONTROL = 'h20; // Register Offset
|
||||
localparam SW_DIO_CONTROL_SIZE = 32; // register width in bits
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// Copyright 2021 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: gpio_atr_regmap_utils.vh
|
||||
// Description:
|
||||
// The constants in this file are autogenerated by XmlParse.
|
||||
|
||||
//===============================================================================
|
||||
// A numerically ordered list of registers and their HDL source files
|
||||
//===============================================================================
|
||||
|
||||
// ATR_STATE : 0x0 (x4xx_gpio_atr.v)
|
||||
// CLASSIC_ATR_CONFIG : 0x40 (x4xx_gpio_atr.v)
|
||||
// ATR_OPTION_REGISTRER : 0x44 (x4xx_gpio_atr.v)
|
||||
// GPIO_DIR : 0x48 (x4xx_gpio_atr.v)
|
||||
// GPIO_DISABLED : 0x4C (x4xx_gpio_atr.v)
|
||||
// GPIO_IN : 0x50 (x4xx_gpio_atr.v)
|
||||
|
||||
//===============================================================================
|
||||
// RegTypes
|
||||
//===============================================================================
|
||||
|
||||
// GPIO_ATR_STATE Type (from x4xx_gpio_atr.v)
|
||||
localparam GPIO_ATR_STATE_SIZE = 32;
|
||||
localparam GPIO_ATR_STATE_MASK = 32'hFFF0FFF;
|
||||
localparam GPIO_STATE_A_SIZE = 12; //GPIO_ATR_STATE:GPIO_STATE_A
|
||||
localparam GPIO_STATE_A_MSB = 11; //GPIO_ATR_STATE:GPIO_STATE_A
|
||||
localparam GPIO_STATE_A = 0; //GPIO_ATR_STATE:GPIO_STATE_A
|
||||
localparam GPIO_STATE_B_SIZE = 12; //GPIO_ATR_STATE:GPIO_STATE_B
|
||||
localparam GPIO_STATE_B_MSB = 27; //GPIO_ATR_STATE:GPIO_STATE_B
|
||||
localparam GPIO_STATE_B = 16; //GPIO_ATR_STATE:GPIO_STATE_B
|
||||
|
||||
//===============================================================================
|
||||
// Register Group GPIO_ATR_REGS
|
||||
//===============================================================================
|
||||
|
||||
// ATR_STATE Register (from x4xx_gpio_atr.v)
|
||||
localparam ATR_STATE_COUNT = 16; // Number of elements in array
|
||||
|
||||
// CLASSIC_ATR_CONFIG Register (from x4xx_gpio_atr.v)
|
||||
localparam CLASSIC_ATR_CONFIG = 'h40; // Register Offset
|
||||
localparam CLASSIC_ATR_CONFIG_SIZE = 32; // register width in bits
|
||||
localparam CLASSIC_ATR_CONFIG_MASK = 32'hFFF0FFF;
|
||||
localparam RF_SELECT_A_SIZE = 12; //CLASSIC_ATR_CONFIG:RF_SELECT_A
|
||||
localparam RF_SELECT_A_MSB = 11; //CLASSIC_ATR_CONFIG:RF_SELECT_A
|
||||
localparam RF_SELECT_A = 0; //CLASSIC_ATR_CONFIG:RF_SELECT_A
|
||||
localparam RF_SELECT_B_SIZE = 12; //CLASSIC_ATR_CONFIG:RF_SELECT_B
|
||||
localparam RF_SELECT_B_MSB = 27; //CLASSIC_ATR_CONFIG:RF_SELECT_B
|
||||
localparam RF_SELECT_B = 16; //CLASSIC_ATR_CONFIG:RF_SELECT_B
|
||||
|
||||
// ATR_OPTION_REGISTRER Register (from x4xx_gpio_atr.v)
|
||||
localparam ATR_OPTION_REGISTRER = 'h44; // Register Offset
|
||||
localparam ATR_OPTION_REGISTRER_SIZE = 32; // register width in bits
|
||||
localparam ATR_OPTION_REGISTRER_MASK = 32'h1;
|
||||
localparam ATR_OPTION_SIZE = 1; //ATR_OPTION_REGISTRER:ATR_OPTION
|
||||
localparam ATR_OPTION_MSB = 0; //ATR_OPTION_REGISTRER:ATR_OPTION
|
||||
localparam ATR_OPTION = 0; //ATR_OPTION_REGISTRER:ATR_OPTION
|
||||
|
||||
// GPIO_DIR Register (from x4xx_gpio_atr.v)
|
||||
localparam GPIO_DIR = 'h48; // Register Offset
|
||||
localparam GPIO_DIR_SIZE = 32; // register width in bits
|
||||
localparam GPIO_DIR_MASK = 32'hFFF0FFF;
|
||||
localparam GPIO_DIR_A_SIZE = 12; //GPIO_DIR:GPIO_DIR_A
|
||||
localparam GPIO_DIR_A_MSB = 11; //GPIO_DIR:GPIO_DIR_A
|
||||
localparam GPIO_DIR_A = 0; //GPIO_DIR:GPIO_DIR_A
|
||||
localparam GPIO_DIR_B_SIZE = 12; //GPIO_DIR:GPIO_DIR_B
|
||||
localparam GPIO_DIR_B_MSB = 27; //GPIO_DIR:GPIO_DIR_B
|
||||
localparam GPIO_DIR_B = 16; //GPIO_DIR:GPIO_DIR_B
|
||||
|
||||
// GPIO_DISABLED Register (from x4xx_gpio_atr.v)
|
||||
localparam GPIO_DISABLED = 'h4C; // Register Offset
|
||||
localparam GPIO_DISABLED_SIZE = 32; // register width in bits
|
||||
localparam GPIO_DISABLED_MASK = 32'hFFF0FFF;
|
||||
localparam GPIO_DISABLED_A_SIZE = 12; //GPIO_DISABLED:GPIO_DISABLED_A
|
||||
localparam GPIO_DISABLED_A_MSB = 11; //GPIO_DISABLED:GPIO_DISABLED_A
|
||||
localparam GPIO_DISABLED_A = 0; //GPIO_DISABLED:GPIO_DISABLED_A
|
||||
localparam GPIO_DISABLED_B_SIZE = 12; //GPIO_DISABLED:GPIO_DISABLED_B
|
||||
localparam GPIO_DISABLED_B_MSB = 27; //GPIO_DISABLED:GPIO_DISABLED_B
|
||||
localparam GPIO_DISABLED_B = 16; //GPIO_DISABLED:GPIO_DISABLED_B
|
||||
|
||||
// GPIO_IN Register (from x4xx_gpio_atr.v)
|
||||
localparam GPIO_IN = 'h50; // Register Offset
|
||||
localparam GPIO_IN_SIZE = 32; // register width in bits
|
||||
localparam GPIO_IN_MASK = 32'hFFF0FFF;
|
||||
localparam GPIO_IN_A_SIZE = 12; //GPIO_IN:GPIO_IN_A
|
||||
localparam GPIO_IN_A_MSB = 11; //GPIO_IN:GPIO_IN_A
|
||||
localparam GPIO_IN_A = 0; //GPIO_IN:GPIO_IN_A
|
||||
localparam GPIO_IN_B_SIZE = 12; //GPIO_IN:GPIO_IN_B
|
||||
localparam GPIO_IN_B_MSB = 27; //GPIO_IN:GPIO_IN_B
|
||||
localparam GPIO_IN_B = 16; //GPIO_IN:GPIO_IN_B
|
||||
|
||||
// Return the offset of an element of register array ATR_STATE
|
||||
function integer ATR_STATE (input integer i);
|
||||
ATR_STATE = (i * 'h4) + 'h0;
|
||||
endfunction
|
||||
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Copyright 2021 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: radio_dio_regmap_utils.vh
|
||||
// Description:
|
||||
// The constants in this file are autogenerated by XmlParse.
|
||||
|
||||
//===============================================================================
|
||||
// A numerically ordered list of registers and their HDL source files
|
||||
//===============================================================================
|
||||
|
||||
// RADIO_GPIO_ATR_REGS : 0x0 (x4xx_core_common.v)
|
||||
// DIO_SOURCE_CONTROL : 0x1000 (x4xx_core_common.v)
|
||||
|
||||
//===============================================================================
|
||||
// RegTypes
|
||||
//===============================================================================
|
||||
|
||||
//===============================================================================
|
||||
// Register Group DIO_SOURCES
|
||||
//===============================================================================
|
||||
|
||||
// RADIO_GPIO_ATR_REGS Window (from x4xx_core_common.v)
|
||||
localparam RADIO_GPIO_ATR_REGS = 'h0; // Window Offset
|
||||
localparam RADIO_GPIO_ATR_REGS_SIZE = 'h1000; // size in bytes
|
||||
|
||||
// DIO_SOURCE_CONTROL Window (from x4xx_core_common.v)
|
||||
localparam DIO_SOURCE_CONTROL = 'h1000; // Window Offset
|
||||
localparam DIO_SOURCE_CONTROL_SIZE = 'h1000; // size in bytes
|
||||
@@ -85,7 +85,7 @@
|
||||
localparam FPGA_CURRENT_VERSION_MINOR = 'h4; // FPGA_VERSION:FPGA_CURRENT_VERSION_MINOR
|
||||
localparam FPGA_CURRENT_VERSION_MAJOR = 'h7; // FPGA_VERSION:FPGA_CURRENT_VERSION_MAJOR
|
||||
localparam FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR = 'h7; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR
|
||||
localparam FPGA_VERSION_LAST_MODIFIED_TIME = 'h21081116; // FPGA_VERSION:FPGA_VERSION_LAST_MODIFIED_TIME
|
||||
localparam FPGA_VERSION_LAST_MODIFIED_TIME = 'h21091513; // FPGA_VERSION:FPGA_VERSION_LAST_MODIFIED_TIME
|
||||
|
||||
// Enumerated type RF_CORE_100M_VERSION
|
||||
localparam RF_CORE_100M_VERSION_SIZE = 7;
|
||||
|
||||
+1
-1
@@ -2225,7 +2225,7 @@ endmodule
|
||||
// <value name="FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR" integer="7"/>
|
||||
// <value name="FPGA_OLDEST_COMPATIBLE_VERSION_MINOR" integer="0"/>
|
||||
// <value name="FPGA_OLDEST_COMPATIBLE_VERSION_BUILD" integer="0"/>
|
||||
// <value name="FPGA_VERSION_LAST_MODIFIED_TIME" integer="0x21081116"/>
|
||||
// <value name="FPGA_VERSION_LAST_MODIFIED_TIME" integer="0x21091513"/>
|
||||
// </enumeratedtype>
|
||||
// </group>
|
||||
//</regmap>
|
||||
|
||||
@@ -241,7 +241,6 @@ module x4xx_core #(
|
||||
wire [ 2*NUM_DBOARDS-1:0] ctrlport_radio_resp_status;
|
||||
wire [ 32*NUM_DBOARDS-1:0] ctrlport_radio_resp_data;
|
||||
|
||||
|
||||
x4xx_core_common #(
|
||||
.CHDR_CLK_RATE (CHDR_CLK_RATE),
|
||||
.CHDR_W (CHDR_W),
|
||||
@@ -318,6 +317,8 @@ module x4xx_core #(
|
||||
.nco_reset_done (nco_reset_done),
|
||||
.adc_reset_pulse (adc_reset_pulse),
|
||||
.dac_reset_pulse (dac_reset_pulse),
|
||||
.tx_running (tx_running),
|
||||
.rx_running (rx_running),
|
||||
.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),
|
||||
|
||||
+183
-76
@@ -10,6 +10,11 @@
|
||||
// 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/x4xx_core_common_buses.svg
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
@@ -93,6 +98,14 @@ module x4xx_core_common #(
|
||||
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,
|
||||
@@ -123,6 +136,10 @@ module x4xx_core_common #(
|
||||
output wire adc_reset_pulse,
|
||||
output wire dac_reset_pulse,
|
||||
|
||||
// Radio state for ATR control
|
||||
input wire [NUM_DBOARDS*2-1:0] tx_running,
|
||||
input wire [NUM_DBOARDS*2-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,
|
||||
@@ -146,6 +163,7 @@ module x4xx_core_common #(
|
||||
`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
|
||||
@@ -342,37 +360,69 @@ module x4xx_core_common #(
|
||||
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;
|
||||
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 [ 4*NUM_DBOARDS-1:0] radio_dio_req_byte_en;
|
||||
wire [ 1*NUM_DBOARDS-1:0] radio_dio_req_has_time;
|
||||
wire [ 64*NUM_DBOARDS-1:0] radio_dio_req_time;
|
||||
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 [NUM_DBOARDS*32-1:0] atr_gpio_out;
|
||||
wire [NUM_DBOARDS*32-1:0] atr_gpio_ddr;
|
||||
|
||||
genvar db;
|
||||
generate
|
||||
for (db = 0; db < NUM_DBOARDS; db = db+1) begin : gen_radio_ctrlport
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// CtrlPort Splitter
|
||||
// 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_*) and DIO control(dio_radio_ctrlport_*).
|
||||
// RFDC timing control (rf_ctrlport_*), the ATR GPIO control for the DB state
|
||||
// the current radio(db) 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.
|
||||
|
||||
localparam [31:0] DIO_WINDOW_SIZE_W = $clog2(DIO_WINDOW_SIZE);
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
|
||||
wire gpio_atr_ctrlport_req_wr;
|
||||
wire gpio_atr_ctrlport_req_rd;
|
||||
wire [19:0] gpio_atr_ctrlport_req_addr;
|
||||
wire [31:0] gpio_atr_ctrlport_req_data;
|
||||
wire [ 3:0] gpio_atr_ctrlport_req_byte_en;
|
||||
wire gpio_atr_ctrlport_req_has_time;
|
||||
wire [63:0] gpio_atr_ctrlport_req_time;
|
||||
wire gpio_atr_ctrlport_resp_ack;
|
||||
wire [ 1:0] gpio_atr_ctrlport_resp_status;
|
||||
wire [31:0] gpio_atr_ctrlport_resp_data;
|
||||
|
||||
|
||||
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 })
|
||||
.NUM_SLAVES (4),
|
||||
.PORT_BASE ({ DIO_SOURCE_CONTROL_OFFSET,
|
||||
RADIO_GPIO_ATR_OFFSET,
|
||||
RFDC_TIMING_WINDOW[19:0],
|
||||
DB_WINDOW[19:0]
|
||||
}),
|
||||
.PORT_ADDR_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),
|
||||
.ctrlport_rst (radio_rst),
|
||||
@@ -386,16 +436,40 @@ module x4xx_core_common #(
|
||||
.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] })
|
||||
.m_ctrlport_req_wr ({ radio_dio_req_wr [ 1*db+: 1], gpio_atr_ctrlport_req_wr, rf_ctrlport_req_wr [ 1*db+: 1], m_radio_ctrlport_req_wr [ 1*db+: 1] }),
|
||||
.m_ctrlport_req_rd ({ radio_dio_req_rd [ 1*db+: 1], gpio_atr_ctrlport_req_rd, rf_ctrlport_req_rd [ 1*db+: 1], m_radio_ctrlport_req_rd [ 1*db+: 1] }),
|
||||
.m_ctrlport_req_addr ({ radio_dio_req_addr [20*db+:20], gpio_atr_ctrlport_req_addr, rf_ctrlport_req_addr [20*db+:20], m_radio_ctrlport_req_addr [20*db+:20] }),
|
||||
.m_ctrlport_req_data ({ radio_dio_req_data [32*db+:32], gpio_atr_ctrlport_req_data, rf_ctrlport_req_data [32*db+:32], m_radio_ctrlport_req_data [32*db+:32] }),
|
||||
.m_ctrlport_req_byte_en ({ radio_dio_req_byte_en [ 4*db+: 4], gpio_atr_ctrlport_req_byte_en, rf_ctrlport_req_byte_en [ 4*db+: 4], m_radio_ctrlport_req_byte_en [ 4*db+: 4] }),
|
||||
.m_ctrlport_req_has_time ({ radio_dio_req_has_time [ 1*db+: 1], gpio_atr_ctrlport_req_has_time, rf_ctrlport_req_has_time [ 1*db+: 1], m_radio_ctrlport_req_has_time [ 1*db+: 1] }),
|
||||
.m_ctrlport_req_time ({ radio_dio_req_time [64*db+:64], gpio_atr_ctrlport_req_time, rf_ctrlport_req_time [64*db+:64], m_radio_ctrlport_req_time [64*db+:64] }),
|
||||
.m_ctrlport_resp_ack ({ radio_dio_resp_ack [ 1*db+: 1], gpio_atr_ctrlport_resp_ack, rf_ctrlport_resp_ack [ 1*db+: 1], m_radio_ctrlport_resp_ack [ 1*db+: 1] }),
|
||||
.m_ctrlport_resp_status ({ radio_dio_resp_status [ 2*db+: 2], gpio_atr_ctrlport_resp_status, rf_ctrlport_resp_status [ 2*db+: 2], m_radio_ctrlport_resp_status [ 2*db+: 2] }),
|
||||
.m_ctrlport_resp_data ({ radio_dio_resp_data [32*db+:32], gpio_atr_ctrlport_resp_data, rf_ctrlport_resp_data [32*db+:32], m_radio_ctrlport_resp_data [32*db+:32] })
|
||||
);
|
||||
|
||||
// Compute ATR state for this radio
|
||||
wire [ 3:0] db_state;
|
||||
|
||||
assign db_state = { tx_running[2*db + 1], rx_running[2*db + 1],
|
||||
tx_running[2*db + 0], rx_running[2*db + 0]};
|
||||
|
||||
x4xx_gpio_atr #(
|
||||
.REG_SIZE (RADIO_GPIO_ATR_REGS_SIZE)
|
||||
) x4xx_gpio_atr_i (
|
||||
.ctrlport_clk (radio_clk),
|
||||
.ctrlport_rst (radio_rst),
|
||||
.s_ctrlport_req_wr (gpio_atr_ctrlport_req_wr),
|
||||
.s_ctrlport_req_rd (gpio_atr_ctrlport_req_rd),
|
||||
.s_ctrlport_req_addr (gpio_atr_ctrlport_req_addr),
|
||||
.s_ctrlport_req_data (gpio_atr_ctrlport_req_data),
|
||||
.s_ctrlport_resp_ack (gpio_atr_ctrlport_resp_ack),
|
||||
.s_ctrlport_resp_status (gpio_atr_ctrlport_resp_status),
|
||||
.s_ctrlport_resp_data (gpio_atr_ctrlport_resp_data),
|
||||
.db_state (db_state),
|
||||
.gpio_in ({4'b0, gpio_in_b, 4'b0, gpio_in_a}),
|
||||
.gpio_out (atr_gpio_out[db*32+: 32]),
|
||||
.gpio_ddr (atr_gpio_ddr[db*32+: 32])
|
||||
);
|
||||
|
||||
end
|
||||
@@ -513,16 +587,16 @@ module x4xx_core_common #(
|
||||
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 (
|
||||
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),
|
||||
.ctrlport_rst (radio_rst),
|
||||
.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),
|
||||
@@ -530,23 +604,20 @@ module x4xx_core_common #(
|
||||
.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_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)
|
||||
.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
|
||||
// Combined dio ctrlport signals
|
||||
wire dio_ctrlport_req_wr;
|
||||
wire dio_ctrlport_req_rd;
|
||||
wire [19:0] dio_ctrlport_req_addr;
|
||||
@@ -564,19 +635,19 @@ module x4xx_core_common #(
|
||||
) 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_wr ({radio_dio_req_wr, windowed_mpm_dio_req_wr}),
|
||||
.s_ctrlport_req_rd ({radio_dio_req_rd, windowed_mpm_dio_req_rd}),
|
||||
.s_ctrlport_req_addr ({radio_dio_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_data ({radio_dio_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}),
|
||||
.s_ctrlport_resp_ack ({radio_dio_resp_ack, windowed_mpm_dio_resp_ack}),
|
||||
.s_ctrlport_resp_status ({radio_dio_resp_status, windowed_mpm_dio_resp_status}),
|
||||
.s_ctrlport_resp_data ({radio_dio_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),
|
||||
@@ -593,30 +664,41 @@ module x4xx_core_common #(
|
||||
);
|
||||
|
||||
x4xx_dio #(
|
||||
.REG_BASE (DIO),
|
||||
.REG_SIZE (DIO_SIZE)
|
||||
.REG_SIZE (DIO_SIZE),
|
||||
.NUM_DBOARDS (NUM_DBOARDS)
|
||||
) x4xx_dio_i (
|
||||
.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),
|
||||
.gpio_out_b (gpio_out_b),
|
||||
.gpio_en_a (gpio_en_a),
|
||||
.gpio_en_b (gpio_en_b),
|
||||
.gpio_in_fabric_a (gpio_in_fabric_a),
|
||||
.gpio_in_fabric_b (gpio_in_fabric_b),
|
||||
.gpio_out_fabric_a (gpio_out_fabric_a),
|
||||
.gpio_out_fabric_b (gpio_out_fabric_b)
|
||||
.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),
|
||||
.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 (32'b0),
|
||||
.digital_ifc_gpio_ddr_radio0 (32'b0),
|
||||
.digital_ifc_gpio_out_radio1 (32'b0),
|
||||
.digital_ifc_gpio_ddr_radio1 (32'b0),
|
||||
.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
|
||||
|
||||
|
||||
@@ -629,7 +711,11 @@ endmodule
|
||||
// <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>
|
||||
// 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 = "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>
|
||||
@@ -637,8 +723,9 @@ endmodule
|
||||
// <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 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>
|
||||
@@ -651,6 +738,10 @@ endmodule
|
||||
// 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 = "x4xx_core_common_buses.svg"
|
||||
// </info>
|
||||
// <group name="CORE_REGS">
|
||||
// <window name="GLOBAL_REGS" offset="0x0" size="0xC00" targetregmap="GLOBAL_REGS_REGMAP">
|
||||
@@ -662,9 +753,25 @@ endmodule
|
||||
// <window name="TIMEKEEPER" offset="0x1000" size="0x20">
|
||||
// <info>Window to access the timekeeper register map.</info>
|
||||
// </window>
|
||||
// <window name="DIO" offset="0x2000" size="0x20" targetregmap="DIO_REGMAP">
|
||||
// <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>
|
||||
// </group>
|
||||
//</regmap>
|
||||
|
||||
//XmlParse xml_off
|
||||
|
||||
+379
-54
@@ -9,10 +9,23 @@
|
||||
//
|
||||
// This module contains the motherboard registers for the DIO
|
||||
// auxiliary board and the logic to drive these GPIO signals.
|
||||
// Arbitration between different sources to control the state
|
||||
// of the GPIO lines includes support for the following sources:
|
||||
// - s_ctrlport_* (combination of CtrlPort from PS AXI and radio blocks)
|
||||
// - PS dio control from Processing System's GPIOs
|
||||
// - ATR state (up to two DBs)
|
||||
// - User Application
|
||||
// - radio-controlled digital bus interface
|
||||
// For a visual representation of how the different sources are
|
||||
// arbitrated, as well as representation on what each source control
|
||||
// register refers to, please refer to the "Front-Panel Programmable
|
||||
// GPIOs" section of the USRP Manual.
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// REG_BASE : Base address to use for registers.
|
||||
// REG_BASE : Base address to use for registers.
|
||||
// REG_SIZE : Register space size.
|
||||
// NUM_DBOARDS : Number of daughterboards to support.
|
||||
//
|
||||
|
||||
`default_nettype none
|
||||
@@ -20,7 +33,8 @@
|
||||
|
||||
module x4xx_dio #(
|
||||
parameter REG_BASE = 0,
|
||||
parameter REG_SIZE = 'h20
|
||||
parameter REG_SIZE = 'h30,
|
||||
parameter NUM_DBOARDS = 2
|
||||
) (
|
||||
// Slave ctrlport interface
|
||||
input wire ctrlport_clk,
|
||||
@@ -43,11 +57,31 @@ module x4xx_dio #(
|
||||
output wire [11:0] gpio_out_a,
|
||||
output wire [11:0] gpio_out_b,
|
||||
|
||||
// GPIO to application (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
|
||||
// ATR GPIO Control (ctrlport_clk)
|
||||
input wire [NUM_DBOARDS*32-1:0] atr_gpio_out,
|
||||
input wire [NUM_DBOARDS*32-1:0] atr_gpio_ddr,
|
||||
|
||||
// PS GPIO Control from Block Design (async)
|
||||
input wire [31:0] ps_gpio_out,
|
||||
input wire [31:0] ps_gpio_ddr,
|
||||
|
||||
// Digital Interface Control (ctrlport_clk)
|
||||
input wire [31:0] digital_ifc_gpio_out_radio0,
|
||||
input wire [31:0] digital_ifc_gpio_ddr_radio0,
|
||||
input wire [31:0] digital_ifc_gpio_out_radio1,
|
||||
input wire [31:0] digital_ifc_gpio_ddr_radio1,
|
||||
|
||||
// GPIO to user application (async)
|
||||
// User application relies on the local direction register
|
||||
// for GPIO direction control. For this reason, we skip
|
||||
// a mux to select between the user application and the
|
||||
// local register direction control in the mux chain, and
|
||||
// propagate their shared direction(from the local register)
|
||||
// to the remainder of the mux chain.
|
||||
output wire [11:0] user_app_in_a,
|
||||
output wire [11:0] user_app_in_b,
|
||||
input wire [11:0] user_app_out_a,
|
||||
input wire [11:0] user_app_out_b
|
||||
);
|
||||
|
||||
`include "../../lib/rfnoc/core/ctrlport.vh"
|
||||
@@ -70,6 +104,16 @@ module x4xx_dio #(
|
||||
reg [DIO_WIDTH-1:0] dio_master_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_output_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_output_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_source_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_source_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_radio_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_radio_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_interface_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_interface_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_override_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_override_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_sw_ctrl_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_sw_ctrl_b = {DIO_WIDTH {1'b0}};
|
||||
wire [DIO_WIDTH-1:0] dio_input_a;
|
||||
wire [DIO_WIDTH-1:0] dio_input_b;
|
||||
|
||||
@@ -93,6 +137,16 @@ module x4xx_dio #(
|
||||
dio_master_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_output_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_output_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_source_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_source_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_radio_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_radio_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_interface_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_interface_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_override_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_override_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_sw_ctrl_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_sw_ctrl_b <= {DIO_WIDTH {1'b0}};
|
||||
|
||||
end else begin
|
||||
// Write registers
|
||||
@@ -104,18 +158,43 @@ module x4xx_dio #(
|
||||
|
||||
case (s_ctrlport_req_addr)
|
||||
REG_BASE + DIO_MASTER_REGISTER: begin
|
||||
dio_master_a <= s_ctrlport_req_data[DIO_MASTER_A_MSB:DIO_MASTER_A];
|
||||
dio_master_b <= s_ctrlport_req_data[DIO_MASTER_B_MSB:DIO_MASTER_B];
|
||||
dio_master_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_master_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + DIO_DIRECTION_REGISTER: begin
|
||||
dio_direction_a <= s_ctrlport_req_data[DIO_DIRECTION_A_MSB:DIO_DIRECTION_A];
|
||||
dio_direction_b <= s_ctrlport_req_data[DIO_DIRECTION_B_MSB:DIO_DIRECTION_B];
|
||||
dio_direction_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_direction_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + DIO_OUTPUT_REGISTER: begin
|
||||
dio_output_a <= s_ctrlport_req_data[DIO_OUTPUT_A_MSB:DIO_OUTPUT_A];
|
||||
dio_output_b <= s_ctrlport_req_data[DIO_OUTPUT_B_MSB:DIO_OUTPUT_B];
|
||||
dio_output_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_output_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + DIO_SOURCE_REGISTER: begin
|
||||
dio_source_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_source_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + RADIO_SOURCE_REGISTER: begin
|
||||
dio_radio_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_radio_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + INTERFACE_DIO_SELECT: begin
|
||||
dio_interface_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_interface_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + DIO_OVERRIDE: begin
|
||||
dio_override_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_override_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + SW_DIO_CONTROL: begin
|
||||
dio_sw_ctrl_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_sw_ctrl_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
// No register implementation for provided address
|
||||
@@ -131,6 +210,7 @@ module x4xx_dio #(
|
||||
end
|
||||
endcase
|
||||
|
||||
|
||||
// Read registers
|
||||
end else if (s_ctrlport_req_rd) begin
|
||||
// Acknowledge by default
|
||||
@@ -140,23 +220,48 @@ module x4xx_dio #(
|
||||
|
||||
case (s_ctrlport_req_addr)
|
||||
REG_BASE + DIO_MASTER_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_MASTER_A_MSB:DIO_MASTER_A] <= dio_master_a;
|
||||
s_ctrlport_resp_data[DIO_MASTER_B_MSB:DIO_MASTER_B] <= dio_master_b;
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_master_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_master_b;
|
||||
end
|
||||
|
||||
REG_BASE + DIO_DIRECTION_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_DIRECTION_A_MSB:DIO_DIRECTION_A] <= dio_direction_a;
|
||||
s_ctrlport_resp_data[DIO_DIRECTION_B_MSB:DIO_DIRECTION_B] <= dio_direction_b;
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_direction_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_direction_b;
|
||||
end
|
||||
|
||||
REG_BASE + DIO_OUTPUT_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_OUTPUT_A_MSB:DIO_OUTPUT_A] <= dio_output_a;
|
||||
s_ctrlport_resp_data[DIO_OUTPUT_B_MSB:DIO_OUTPUT_B] <= dio_output_b;
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_output_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_output_b;
|
||||
end
|
||||
|
||||
REG_BASE + DIO_INPUT_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_INPUT_A_MSB:DIO_INPUT_A] <= dio_input_a;
|
||||
s_ctrlport_resp_data[DIO_INPUT_B_MSB:DIO_INPUT_B] <= dio_input_b;
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_input_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_input_b;
|
||||
end
|
||||
|
||||
REG_BASE + DIO_SOURCE_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_source_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_source_b;
|
||||
end
|
||||
|
||||
REG_BASE + RADIO_SOURCE_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_radio_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_radio_b;
|
||||
end
|
||||
|
||||
REG_BASE + INTERFACE_DIO_SELECT: begin
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_interface_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_interface_b;
|
||||
end
|
||||
|
||||
REG_BASE + DIO_OVERRIDE: begin
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_override_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_override_b;
|
||||
end
|
||||
|
||||
REG_BASE + SW_DIO_CONTROL: begin
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_sw_ctrl_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_sw_ctrl_b;
|
||||
end
|
||||
|
||||
// No register implementation for provided address
|
||||
@@ -198,31 +303,205 @@ module x4xx_dio #(
|
||||
);
|
||||
|
||||
// Forward raw input to user application
|
||||
assign gpio_in_fabric_a = gpio_in_a;
|
||||
assign gpio_in_fabric_b = gpio_in_b;
|
||||
assign user_app_in_a = gpio_in_a;
|
||||
assign user_app_in_b = gpio_in_b;
|
||||
|
||||
// Direction control
|
||||
assign gpio_en_a = dio_direction_a;
|
||||
assign gpio_en_b = dio_direction_b;
|
||||
wire [DIO_WIDTH-1:0] gpio_out_sw_a;
|
||||
wire [DIO_WIDTH-1:0] gpio_out_sw_b;
|
||||
|
||||
// Output assignment depending on master
|
||||
generate
|
||||
genvar i;
|
||||
for (i = 0; i < DIO_WIDTH; i = i + 1) begin: dio_output_gen
|
||||
glitch_free_mux glitch_free_mux_dio_a (
|
||||
|
||||
reg atr_gpio_src_out_a_reg = 1'b0;
|
||||
reg atr_gpio_src_out_b_reg = 1'b0;
|
||||
reg atr_gpio_src_ddr_a_reg = 1'b0;
|
||||
reg atr_gpio_src_ddr_b_reg = 1'b0;
|
||||
|
||||
// 1) Select which radio drives the output
|
||||
always @ (posedge ctrlport_clk) begin
|
||||
if (ctrlport_rst) begin
|
||||
atr_gpio_src_out_a_reg <= 1'b0;
|
||||
atr_gpio_src_out_b_reg <= 1'b0;
|
||||
end else begin
|
||||
atr_gpio_src_out_a_reg <= atr_gpio_out[dio_radio_a[i]*32 + DIO_PORT_A + i];
|
||||
atr_gpio_src_out_b_reg <= atr_gpio_out[dio_radio_b[i]*32 + DIO_PORT_B + i];
|
||||
end
|
||||
end
|
||||
|
||||
// 2) Select which radio drives the direction
|
||||
always @ (posedge ctrlport_clk) begin
|
||||
if (ctrlport_rst) begin
|
||||
atr_gpio_src_ddr_a_reg <= 1'b0;
|
||||
atr_gpio_src_ddr_b_reg <= 1'b0;
|
||||
end else begin
|
||||
atr_gpio_src_ddr_a_reg <= atr_gpio_ddr[dio_radio_a[i]*32 + DIO_PORT_A + i];
|
||||
atr_gpio_src_ddr_b_reg <= atr_gpio_ddr[dio_radio_b[i]*32 + DIO_PORT_B + i];
|
||||
end
|
||||
end
|
||||
|
||||
// Select between the Digital Interface in each radio(INTERFACE_DIO_SELECT)
|
||||
wire dio_interface_mux_out_a;
|
||||
wire dio_interface_mux_out_b;
|
||||
wire dio_interface_mux_ddr_a;
|
||||
wire dio_interface_mux_ddr_b;
|
||||
|
||||
glitch_free_mux glitch_free_interface_out_mux_dio_a (
|
||||
.select (dio_interface_a[i]),
|
||||
.signal0 (digital_ifc_gpio_out_radio0[DIO_PORT_A + i]),
|
||||
.signal1 (digital_ifc_gpio_out_radio1[DIO_PORT_A + i]),
|
||||
.muxed_signal (dio_interface_mux_out_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_interface_out_mux_dio_b (
|
||||
.select (dio_interface_b[i]),
|
||||
.signal0 (digital_ifc_gpio_out_radio0[DIO_PORT_B + i]),
|
||||
.signal1 (digital_ifc_gpio_out_radio1[DIO_PORT_B + i]),
|
||||
.muxed_signal (dio_interface_mux_out_b)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_interface_ddr_mux_dio_a (
|
||||
.select (dio_interface_a[i]),
|
||||
.signal0 (digital_ifc_gpio_ddr_radio0[DIO_PORT_A + i]),
|
||||
.signal1 (digital_ifc_gpio_ddr_radio1[DIO_PORT_A + i]),
|
||||
.muxed_signal (dio_interface_mux_ddr_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_interface_ddr_mux_dio_b (
|
||||
.select (dio_interface_b[i]),
|
||||
.signal0 (digital_ifc_gpio_ddr_radio0[DIO_PORT_B + i]),
|
||||
.signal1 (digital_ifc_gpio_ddr_radio1[DIO_PORT_B + i]),
|
||||
.muxed_signal (dio_interface_mux_ddr_b)
|
||||
);
|
||||
|
||||
|
||||
// Select between ATR or Digital control(DIO_OVERRIDE)
|
||||
wire dio_override_mux_out_a;
|
||||
wire dio_override_mux_out_b;
|
||||
wire dio_override_mux_ddr_a;
|
||||
wire dio_override_mux_ddr_b;
|
||||
|
||||
glitch_free_mux glitch_free_override_out_mux_dio_a (
|
||||
.select (dio_override_a[i]),
|
||||
.signal0 (atr_gpio_src_out_a_reg),
|
||||
.signal1 (dio_interface_mux_out_a),
|
||||
.muxed_signal (dio_override_mux_out_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_override_out_mux_dio_b (
|
||||
.select (dio_override_b[i]),
|
||||
.signal0 (atr_gpio_src_out_b_reg),
|
||||
.signal1 (dio_interface_mux_out_b),
|
||||
.muxed_signal (dio_override_mux_out_b)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_override_ddr_mux_dio_a (
|
||||
.select (dio_override_a[i]),
|
||||
.signal0 (atr_gpio_src_ddr_a_reg),
|
||||
.signal1 (dio_interface_mux_ddr_a),
|
||||
.muxed_signal (dio_override_mux_ddr_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_override_ddr_mux_dio_b (
|
||||
.select (dio_override_b[i]),
|
||||
.signal0 (atr_gpio_src_ddr_b_reg),
|
||||
.signal1 (dio_interface_mux_ddr_b),
|
||||
.muxed_signal (dio_override_mux_ddr_b)
|
||||
);
|
||||
|
||||
|
||||
// SW source select
|
||||
// SW_DIO_CONTROL, select between PS and local register
|
||||
|
||||
wire dio_sw_control_mux_out_a;
|
||||
wire dio_sw_control_mux_out_b;
|
||||
wire dio_sw_control_mux_ddr_a;
|
||||
wire dio_sw_control_mux_ddr_b;
|
||||
|
||||
glitch_free_mux glitch_free_sw_control_out_mux_dio_a (
|
||||
.select (dio_sw_ctrl_a[i]),
|
||||
.signal0 (dio_output_a[i]),
|
||||
.signal1 (ps_gpio_out[DIO_PORT_A + i]),
|
||||
.muxed_signal (dio_sw_control_mux_out_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_sw_control_out_mux_dio_b (
|
||||
.select (dio_sw_ctrl_b[i]),
|
||||
.signal0 (dio_output_b[i]),
|
||||
.signal1 (ps_gpio_out[DIO_PORT_B + i]),
|
||||
.muxed_signal (dio_sw_control_mux_out_b)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_sw_control_ddr_mux_dio_a (
|
||||
.select (dio_sw_ctrl_a[i]),
|
||||
.signal0 (dio_direction_a[i]),
|
||||
.signal1 (ps_gpio_ddr[DIO_PORT_A + i]),
|
||||
.muxed_signal (dio_sw_control_mux_ddr_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_sw_control_ddr_mux_dio_b (
|
||||
.select (dio_sw_ctrl_b[i]),
|
||||
.signal0 (dio_direction_b[i]),
|
||||
.signal1 (ps_gpio_ddr[DIO_PORT_B + i]),
|
||||
.muxed_signal (dio_sw_control_mux_ddr_b)
|
||||
);
|
||||
|
||||
|
||||
// DIO_MASTER_REGISTER Mux, select between SW_DIO_CONTROL
|
||||
// and user application
|
||||
// User application relies on the local direction register
|
||||
// for GPIO direction control. For this reason, we skip
|
||||
// a mux to select between the user application and the
|
||||
// local register direction control in the mux chain, and
|
||||
// propagate their shared direction(from the local register)
|
||||
// to the remainder of the mux chain.
|
||||
glitch_free_mux glitch_free_master_mux_dio_a (
|
||||
.select (dio_master_a[i]),
|
||||
.signal0 (gpio_out_fabric_a[i]),
|
||||
.signal1 (dio_output_a[i]),
|
||||
.signal0 (user_app_out_a[i]),
|
||||
.signal1 (dio_sw_control_mux_out_a),
|
||||
.muxed_signal (gpio_out_sw_a[i])
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_master_mux_dio_b (
|
||||
.select (dio_master_b[i]),
|
||||
.signal0 (user_app_out_b[i]),
|
||||
.signal1 (dio_sw_control_mux_out_b),
|
||||
.muxed_signal (gpio_out_sw_b[i])
|
||||
);
|
||||
|
||||
// DIO_SOURCE_REGISTER mux, select between (DIO_MASTER_REGISTER output) and
|
||||
// radio controlled source (DIO_OVERRIDE output).
|
||||
glitch_free_mux glitch_free_source_out_mux_dio_a (
|
||||
.select (dio_source_a[i]),
|
||||
.signal0 (gpio_out_sw_a[i]),
|
||||
.signal1 (dio_override_mux_out_a),
|
||||
.muxed_signal (gpio_out_a[i])
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_mux_dio_b (
|
||||
.select (dio_master_b[i]),
|
||||
.signal0 (gpio_out_fabric_b[i]),
|
||||
.signal1 (dio_output_b[i]),
|
||||
glitch_free_mux glitch_free_source_out_mux_dio_b (
|
||||
.select (dio_source_b[i]),
|
||||
.signal0 (gpio_out_sw_b[i]),
|
||||
.signal1 (dio_override_mux_out_b),
|
||||
.muxed_signal (gpio_out_b[i])
|
||||
);
|
||||
|
||||
// Direction control
|
||||
glitch_free_mux glitch_free_dir_mux_dio_a (
|
||||
.select (dio_source_a[i]),
|
||||
.signal0 (dio_sw_control_mux_ddr_a),
|
||||
.signal1 (dio_override_mux_ddr_a),
|
||||
.muxed_signal (gpio_en_a[i])
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_dir_mux_dio_b (
|
||||
.select (dio_source_b[i]),
|
||||
.signal0 (dio_sw_control_mux_ddr_b),
|
||||
.signal1 (dio_override_mux_ddr_b),
|
||||
.muxed_signal (gpio_en_b[i])
|
||||
);
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -232,44 +511,90 @@ endmodule
|
||||
|
||||
|
||||
//XmlParse xml_on
|
||||
//<regmap name="DIO_REGMAP" readablestrobes="false" ettusguidelines="true">
|
||||
//<regmap name="DIO_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
|
||||
// <group name="DIO_REGS">
|
||||
// <info>
|
||||
// Registers to control the GPIO buffer direction on the FPGA connected to the DIO board.
|
||||
// Further registers enable the PS to control and read the GPIO lines as master.
|
||||
// Make sure the GPIO lines between FPGA and GPIO board are not driven by two drivers.
|
||||
// Set the DIO registers in @.PS_CPLD_BASE_REGMAP appropriately.
|
||||
// Registers to control the GPIO buffer direction on the FPGA connected to
|
||||
// the DIO board. Further registers enable different sources to control and
|
||||
// read the GPIO lines as master. The following diagram shows how source
|
||||
// selection multiplexers are arranged, as well as an indicator for the
|
||||
// register that control them. </br>
|
||||
// <img src = "..\..\..\..\..\host\docs\res\x4xx_dio_source_muxes.svg"
|
||||
// alt="Front-Panel Programmable GPIOs"/></br>
|
||||
// Make sure the GPIO lines between FPGA and GPIO board are not driven by
|
||||
// two drivers. Set the DIO registers in @.PS_CPLD_BASE_REGMAP appropriately.
|
||||
// </info>
|
||||
//
|
||||
// <register name="DIO_MASTER_REGISTER" offset="0x00" size="32">
|
||||
// <regtype name="DIO_CONTROL_REG" size="32">
|
||||
// <info>
|
||||
// Sets whether the DIO signal line is driven by this register interface or the user application.{br/}
|
||||
// 0 = user application is master, 1 = PS is master
|
||||
// Holds a single bit setting for DIO lines in both ports. One bit per pin.
|
||||
// </info>
|
||||
// <bitfield name="DIO_PORT_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="DIO_PORT_B" range="16..27" initialvalue="0"/>
|
||||
// </regtype>
|
||||
//
|
||||
// <register name="DIO_MASTER_REGISTER" offset="0x00" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Sets whether the DIO signal line is driven by this register interface
|
||||
// or the user application.{br/}
|
||||
// 0 = user application is master, 1 = output of @.SW_DIO_CONTROL is master
|
||||
// </info>
|
||||
// <bitfield name="DIO_MASTER_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="DIO_MASTER_B" range="16..27" initialvalue="0"/>
|
||||
// </register>
|
||||
// <register name="DIO_DIRECTION_REGISTER" offset="0x04" size="32">
|
||||
// <register name="DIO_DIRECTION_REGISTER" offset="0x04" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Set the direction of FPGA buffer connected to DIO ports on the DIO board.{br/}
|
||||
// Each bit represents one signal line. 0 = line is an input to the FPGA, 1 = line is an output driven by the FPGA.
|
||||
// Each bit represents one signal line. 0 = line is an input to the FPGA,
|
||||
// 1 = line is an output driven by the FPGA.
|
||||
// </info>
|
||||
// <bitfield name="DIO_DIRECTION_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="DIO_DIRECTION_B" range="16..27" initialvalue="0"/>
|
||||
// </register>
|
||||
// <register name="DIO_INPUT_REGISTER" offset="0x08" size="32" writable="false">
|
||||
// <register name="DIO_INPUT_REGISTER" offset="0x08" typename="DIO_CONTROL_REG" writable="false">
|
||||
// <info>
|
||||
// Status of each bit at the FPGA input.
|
||||
// </info>
|
||||
// <bitfield name="DIO_INPUT_A" range="0..11"/>
|
||||
// <bitfield name="DIO_INPUT_B" range="16..27"/>
|
||||
// </register>
|
||||
// <register name="DIO_OUTPUT_REGISTER" offset="0x0C" size="32">
|
||||
// <register name="DIO_OUTPUT_REGISTER" offset="0x0C" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls the values on each DIO signal line in case the line master is set to PS in @.DIO_MASTER_REGISTER.
|
||||
// Controls the values on each DIO signal line in case the line master is
|
||||
// set to PS in @.DIO_MASTER_REGISTER.
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="DIO_SOURCE_REGISTER" offset="0x10" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls whether the DIO lines reflect the state of @.DIO_MASTER_REGISTER
|
||||
// or the radio blocks. 0 = @.DIO_MASTER_REGISTER,
|
||||
// 1 = Radio block output(@.DIO_OVERRIDE)
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="RADIO_SOURCE_REGISTER" offset="0x14" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls which radio block to use the ATR state from to determine the
|
||||
// state of the DIO lines.
|
||||
// 0 = Radio#0
|
||||
// 1 = Radio#1
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="INTERFACE_DIO_SELECT" offset="0x18" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls which of the two available digital interfaces controls the DIO lines.
|
||||
// 0 = Digital interface from Radio#0,
|
||||
// 1 = Digital Interface from Radio#1.
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="DIO_OVERRIDE" offset="0x1C" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls whether the radio input to the @.DIO_SOURCE_REGISTER mux
|
||||
// connects to the ATR control or a Digital interface block. The output
|
||||
// of the mux controlled by this bit goes to @.DIO_SOURCE_REGISTER.
|
||||
// 0 = Drive the ATR state(@.RADIO_SOURCE_REGISTER), 1 = Drive
|
||||
// Digital interface block(Output of @.INTERFACE_DIO_SELECT).
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="SW_DIO_CONTROL" offset="0x20" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls which source is forwarded to the @.DIO_MASTER_REGISTER mux.
|
||||
// This configuration is applied independently for each DIO line.
|
||||
// 0 = MPM Ctrlport endpoint, 1 = PS Netlist DIO signal.
|
||||
// </info>
|
||||
// <bitfield name="DIO_OUTPUT_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="DIO_OUTPUT_B" range="16..27" initialvalue="0"/>
|
||||
// </register>
|
||||
// </group>
|
||||
//</regmap>
|
||||
|
||||
@@ -0,0 +1,376 @@
|
||||
//
|
||||
// Copyright 2021 Ettus Research, A National Instruments Brand
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: x4xx_gpio_atr
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// This module controls the behavior of a GPIO bus of arbitrary width
|
||||
// based on the current ATR state. The radio state is determined by
|
||||
// combining the TX and RX states of each rf channel in the radio in
|
||||
// the following order: {tx_rf1, rx_rf1, tx_rf0, rx_rf0}
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// REG_BASE : Base address to use for registers.
|
||||
// REG_SIZE : Register space size.
|
||||
// WIDTH : Number of GPIO lines controlled by this block.
|
||||
//
|
||||
module x4xx_gpio_atr #(
|
||||
parameter REG_BASE = 0,
|
||||
parameter REG_SIZE = 'h20,
|
||||
parameter WIDTH = 32
|
||||
) (
|
||||
// Slave ctrlport interface
|
||||
input wire ctrlport_clk,
|
||||
input wire ctrlport_rst,
|
||||
input wire s_ctrlport_req_wr,
|
||||
input wire s_ctrlport_req_rd,
|
||||
input wire [19:0] s_ctrlport_req_addr,
|
||||
input wire [31:0] s_ctrlport_req_data,
|
||||
output reg s_ctrlport_resp_ack = 1'b0,
|
||||
output reg [ 1:0] s_ctrlport_resp_status = 2'b00,
|
||||
output reg [31:0] s_ctrlport_resp_data = {32 {1'bX}},
|
||||
// Run state signals that indicate tx and rx operation
|
||||
input wire [3:0] db_state,
|
||||
// GPIO control signals
|
||||
input wire [WIDTH-1:0] gpio_in, //GPIO input state
|
||||
output reg [WIDTH-1:0] gpio_out = {WIDTH {1'b0}}, //GPIO output state
|
||||
output reg [WIDTH-1:0] gpio_ddr = {WIDTH {1'b0}} //GPIO direction (0=input, 1=output)
|
||||
);
|
||||
|
||||
`include "../../lib/rfnoc/core/ctrlport.vh"
|
||||
`include "regmap/gpio_atr_regmap_utils.vh"
|
||||
|
||||
reg [WIDTH-1:0] in_atr_state [15:0];
|
||||
|
||||
initial begin
|
||||
in_atr_state[0] = {WIDTH {1'b0}};
|
||||
in_atr_state[1] = {WIDTH {1'b0}};
|
||||
in_atr_state[2] = {WIDTH {1'b0}};
|
||||
in_atr_state[3] = {WIDTH {1'b0}};
|
||||
in_atr_state[4] = {WIDTH {1'b0}};
|
||||
in_atr_state[5] = {WIDTH {1'b0}};
|
||||
in_atr_state[6] = {WIDTH {1'b0}};
|
||||
in_atr_state[7] = {WIDTH {1'b0}};
|
||||
in_atr_state[8] = {WIDTH {1'b0}};
|
||||
in_atr_state[9] = {WIDTH {1'b0}};
|
||||
in_atr_state[10] = {WIDTH {1'b0}};
|
||||
in_atr_state[11] = {WIDTH {1'b0}};
|
||||
in_atr_state[12] = {WIDTH {1'b0}};
|
||||
in_atr_state[13] = {WIDTH {1'b0}};
|
||||
in_atr_state[14] = {WIDTH {1'b0}};
|
||||
in_atr_state[15] = {WIDTH {1'b0}};
|
||||
end
|
||||
|
||||
reg [WIDTH-1:0] ddr_reg, atr_disable, gpio_sw_rb = {WIDTH {1'b0}};
|
||||
reg [WIDTH-1:0] ogpio, igpio = {WIDTH {1'b0}};
|
||||
reg [WIDTH-1:0] classic_atr_select = {WIDTH {1'b0}};
|
||||
|
||||
// DB state/Classic ATR selector
|
||||
reg atr_mode = 1'b0;
|
||||
|
||||
genvar state;
|
||||
//---------------------------------------------------------------------------
|
||||
// Control interface handling
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Check that address is within this module's range.
|
||||
wire address_in_range = (s_ctrlport_req_addr >= REG_BASE) && (s_ctrlport_req_addr < REG_BASE + REG_SIZE);
|
||||
|
||||
// Check that address is targeting an ATR state.
|
||||
wire address_is_atr = (s_ctrlport_req_addr >= REG_BASE + ATR_STATE(0)) && (s_ctrlport_req_addr <= REG_BASE + ATR_STATE(15));
|
||||
// Decode the ATR state being addressed.
|
||||
wire [3:0]atr_address = s_ctrlport_req_addr[5:2];
|
||||
|
||||
always @ (posedge ctrlport_clk) begin
|
||||
if (ctrlport_rst) begin
|
||||
s_ctrlport_resp_ack <= 1'b0;
|
||||
s_ctrlport_resp_data <= {32 {1'bX}};
|
||||
s_ctrlport_resp_status <= 2'b00;
|
||||
|
||||
ddr_reg <= {WIDTH {1'b0}};
|
||||
atr_disable <= {WIDTH {1'b0}};
|
||||
classic_atr_select <= {WIDTH {1'b0}};
|
||||
atr_mode <= 1'b0;
|
||||
|
||||
in_atr_state[0] <= {WIDTH {1'b0}};
|
||||
in_atr_state[1] <= {WIDTH {1'b0}};
|
||||
in_atr_state[2] <= {WIDTH {1'b0}};
|
||||
in_atr_state[3] <= {WIDTH {1'b0}};
|
||||
in_atr_state[4] <= {WIDTH {1'b0}};
|
||||
in_atr_state[5] <= {WIDTH {1'b0}};
|
||||
in_atr_state[6] <= {WIDTH {1'b0}};
|
||||
in_atr_state[7] <= {WIDTH {1'b0}};
|
||||
in_atr_state[8] <= {WIDTH {1'b0}};
|
||||
in_atr_state[9] <= {WIDTH {1'b0}};
|
||||
in_atr_state[10] <= {WIDTH {1'b0}};
|
||||
in_atr_state[11] <= {WIDTH {1'b0}};
|
||||
in_atr_state[12] <= {WIDTH {1'b0}};
|
||||
in_atr_state[13] <= {WIDTH {1'b0}};
|
||||
in_atr_state[14] <= {WIDTH {1'b0}};
|
||||
in_atr_state[15] <= {WIDTH {1'b0}};
|
||||
|
||||
end else begin
|
||||
// Write registers
|
||||
if (s_ctrlport_req_wr) begin
|
||||
// Acknowledge by default
|
||||
s_ctrlport_resp_ack <= 1'b1;
|
||||
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'b0}};
|
||||
s_ctrlport_resp_status <= CTRL_STS_OKAY;
|
||||
|
||||
// Address ATR state writes
|
||||
if(address_is_atr) begin
|
||||
in_atr_state[atr_address][GPIO_STATE_A_MSB:GPIO_STATE_A] <= s_ctrlport_req_data[GPIO_STATE_A_MSB:GPIO_STATE_A];
|
||||
in_atr_state[atr_address][GPIO_STATE_B_MSB:GPIO_STATE_B] <= s_ctrlport_req_data[GPIO_STATE_B_MSB:GPIO_STATE_B];
|
||||
end else begin
|
||||
|
||||
// Address writes to the rest of the register space
|
||||
case (s_ctrlport_req_addr)
|
||||
|
||||
REG_BASE + ATR_OPTION_REGISTRER: begin
|
||||
atr_mode <= s_ctrlport_req_data[ATR_OPTION];
|
||||
end
|
||||
|
||||
REG_BASE + CLASSIC_ATR_CONFIG: begin
|
||||
classic_atr_select[RF_SELECT_A_MSB:RF_SELECT_A] <= s_ctrlport_req_data[RF_SELECT_A_MSB:RF_SELECT_A];
|
||||
classic_atr_select[RF_SELECT_B_MSB:RF_SELECT_B] <= s_ctrlport_req_data[RF_SELECT_B_MSB:RF_SELECT_B];
|
||||
end
|
||||
|
||||
REG_BASE + GPIO_DIR: begin
|
||||
ddr_reg[GPIO_DIR_A_MSB:GPIO_DIR_A] <= s_ctrlport_req_data[GPIO_DIR_A_MSB:GPIO_DIR_A];
|
||||
ddr_reg[GPIO_DIR_B_MSB:GPIO_DIR_B] <= s_ctrlport_req_data[GPIO_DIR_B_MSB:GPIO_DIR_B];
|
||||
end
|
||||
|
||||
REG_BASE + GPIO_DISABLED: begin
|
||||
atr_disable[GPIO_DISABLED_A_MSB:GPIO_DISABLED_A] <= s_ctrlport_req_data[GPIO_DISABLED_A_MSB:GPIO_DISABLED_A];
|
||||
atr_disable[GPIO_DISABLED_B_MSB:GPIO_DISABLED_B] <= s_ctrlport_req_data[GPIO_DISABLED_B_MSB:GPIO_DISABLED_B];
|
||||
end
|
||||
|
||||
// No register implementation for provided address
|
||||
default: begin
|
||||
// Acknowledge and provide error status if address is in range
|
||||
if (address_in_range) begin
|
||||
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
|
||||
|
||||
// No response if out of range
|
||||
end else begin
|
||||
s_ctrlport_resp_ack <= 1'b0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// Read registers
|
||||
end else if (s_ctrlport_req_rd) begin
|
||||
// Acknowledge by default
|
||||
s_ctrlport_resp_ack <= 1'b1;
|
||||
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'b0}};
|
||||
s_ctrlport_resp_status <= CTRL_STS_OKAY;
|
||||
|
||||
// Address ATR state reads
|
||||
if(address_is_atr) begin
|
||||
s_ctrlport_resp_data[GPIO_STATE_A_MSB:GPIO_STATE_A] <= in_atr_state[atr_address][GPIO_STATE_A_MSB:GPIO_STATE_A];
|
||||
s_ctrlport_resp_data[GPIO_STATE_B_MSB:GPIO_STATE_B] <= in_atr_state[atr_address][GPIO_STATE_B_MSB:GPIO_STATE_B];
|
||||
end else begin
|
||||
|
||||
// Address reads to the rest of the register space
|
||||
case (s_ctrlport_req_addr)
|
||||
|
||||
REG_BASE + ATR_OPTION_REGISTRER: begin
|
||||
s_ctrlport_resp_data[ATR_OPTION] <= atr_mode;
|
||||
end
|
||||
|
||||
REG_BASE + CLASSIC_ATR_CONFIG: begin
|
||||
s_ctrlport_resp_data[RF_SELECT_A_MSB:RF_SELECT_A] <= classic_atr_select[RF_SELECT_A_MSB:RF_SELECT_A];
|
||||
s_ctrlport_resp_data[RF_SELECT_B_MSB:RF_SELECT_B] <= classic_atr_select[RF_SELECT_B_MSB:RF_SELECT_B];
|
||||
end
|
||||
|
||||
REG_BASE + GPIO_DIR: begin
|
||||
s_ctrlport_resp_data[GPIO_DIR_A_MSB:GPIO_DIR_A] <= ddr_reg[GPIO_DIR_A_MSB:GPIO_DIR_A];
|
||||
s_ctrlport_resp_data[GPIO_DIR_B_MSB:GPIO_DIR_B] <= ddr_reg[GPIO_DIR_B_MSB:GPIO_DIR_B];
|
||||
end
|
||||
|
||||
REG_BASE + GPIO_DISABLED: begin
|
||||
s_ctrlport_resp_data[GPIO_DISABLED_A_MSB:GPIO_DISABLED_A] <= atr_disable[GPIO_DISABLED_A_MSB:GPIO_DISABLED_A];
|
||||
s_ctrlport_resp_data[GPIO_DISABLED_B_MSB:GPIO_DISABLED_B] <= atr_disable[GPIO_DISABLED_B_MSB:GPIO_DISABLED_B];
|
||||
end
|
||||
|
||||
REG_BASE + GPIO_IN: begin
|
||||
s_ctrlport_resp_data[GPIO_IN_A_MSB:GPIO_IN_A] <= gpio_sw_rb[GPIO_IN_A_MSB:GPIO_IN_A];
|
||||
s_ctrlport_resp_data[GPIO_IN_B_MSB:GPIO_IN_B] <= gpio_sw_rb[GPIO_IN_B_MSB:GPIO_IN_B];
|
||||
end
|
||||
|
||||
// No register implementation for provided address
|
||||
default: begin
|
||||
// Acknowledge and provide error status if address is in range
|
||||
if (address_in_range) begin
|
||||
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
|
||||
|
||||
// No response if out of range
|
||||
end else begin
|
||||
s_ctrlport_resp_ack <= 1'b0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
end else begin
|
||||
s_ctrlport_resp_ack <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
genvar i;
|
||||
|
||||
//Pipeline for easier timing closure
|
||||
reg [ 3:0] db_state_d = 4'b0;
|
||||
reg atr_mode_d = 1'b0;
|
||||
reg [WIDTH-1:0] classic_atr_select_d = {WIDTH {1'b0}};
|
||||
always @(posedge ctrlport_clk) begin
|
||||
db_state_d <= db_state;
|
||||
atr_mode_d <= atr_mode;
|
||||
classic_atr_select_d <= classic_atr_select;
|
||||
end
|
||||
|
||||
generate
|
||||
for (i=0; i<WIDTH; i=i+1) begin: gpio_mux_gen
|
||||
//ATR selection MUX
|
||||
// Classic ATR
|
||||
always @(posedge ctrlport_clk) begin
|
||||
if(atr_mode_d) begin
|
||||
if (atr_disable[i]) begin
|
||||
// ATR state 0 for RF 0 and ATR state 4 for RF1
|
||||
ogpio[i] <= in_atr_state[classic_atr_select_d[i]*4][i];
|
||||
end else begin
|
||||
if (classic_atr_select_d[i]) begin // RF 1
|
||||
ogpio[i] <= in_atr_state[db_state_d[3:2] + 4][i];
|
||||
end else begin // RF 0
|
||||
ogpio[i] <= in_atr_state[db_state_d[1:0]][i];
|
||||
end
|
||||
end
|
||||
end else begin // Use DB state
|
||||
if (atr_disable[i]) begin
|
||||
ogpio[i] <= in_atr_state[0][i];
|
||||
end else begin
|
||||
ogpio[i] <= in_atr_state[db_state_d][i];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//Pipeline input, output and direction
|
||||
always @(posedge ctrlport_clk)
|
||||
gpio_out <= ogpio;
|
||||
|
||||
always @(posedge ctrlport_clk)
|
||||
igpio <= gpio_in;
|
||||
|
||||
always @(posedge ctrlport_clk)
|
||||
gpio_ddr <= ddr_reg;
|
||||
|
||||
//Generate software readback state
|
||||
generate
|
||||
for (i=0; i<WIDTH; i=i+1) begin: gpio_rb_gen
|
||||
always @(posedge ctrlport_clk)
|
||||
gpio_sw_rb[i] <= gpio_ddr[i] ? gpio_out[i] : igpio[i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
//XmlParse xml_on
|
||||
//<regmap name="GPIO_ATR_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
|
||||
// <group name="GPIO_ATR_REGS">
|
||||
// <info>
|
||||
// Describes the behavior of GPIO lines when controlled by the ATR state.
|
||||
// </info>
|
||||
//
|
||||
// <regtype name="GPIO_ATR_STATE" size="32">
|
||||
// <info>Holds a single bit setting for GPIO lines in both ports for a particular ATR sate</info>
|
||||
// <bitfield name="GPIO_STATE_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="GPIO_STATE_B" range="16..27" initialvalue="0"/>
|
||||
// </regtype>
|
||||
//
|
||||
// <register name="ATR_STATE" typename="GPIO_ATR_STATE" offset="0x00" count="16" options="--step 4">
|
||||
// <info>
|
||||
// Describes GPIO behavior for the different ATR states. When @.ATR_OPTION
|
||||
// is set to use the DB states, TX and RX states for RF0 and RF1 are
|
||||
// combined to create a single vector. This creates 16 different
|
||||
// combinations, each with its own register. When @.ATR_OPTION is set to
|
||||
// classic ATR, offsets 0x00-0x03 in this register group will be driven
|
||||
// in accordance with the state of RF0, and offsets 0x04-0x07 will be
|
||||
// driven in accordance with the state of RF1.
|
||||
// CLASSIC ATR MAPPING: Idle[RF0:0x00; RF1:0x04], RX[RF0:0x01; RF1:0x05],
|
||||
// TX[RF0:0x02; RF1:0x06], FDX[RF0:0x03; RF1:0x07]
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="ATR_OPTION_REGISTRER" offset="0x44" size="32">
|
||||
// <info>
|
||||
// Controls whether GPIO lines use the TX and RX state of an RF channel
|
||||
// (Classic ATR) or the daughterboard state the selector for the
|
||||
// @.GPIO_ATR_STATE.
|
||||
// </info>
|
||||
// <bitfield name="ATR_OPTION" range="0" initialvalue="0">
|
||||
// <info>
|
||||
// Sets the scheme in which RF states in the radio will control GPIO
|
||||
// lines. 0 = DB state is used. RF states are combined and the
|
||||
// GPIO state is driven based on all 16 @.GPIO_ATR_STATE registers.
|
||||
// 1 = Each RF channel has its separate ATR state(Classic ATR).
|
||||
// Use register @.CLASSIC_ATR_CONFIG to indicate the RF channel
|
||||
// to which each GPIO line responds to.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// </register>
|
||||
// <register name="CLASSIC_ATR_CONFIG" offset="0x40" size="32">
|
||||
// <info>
|
||||
// Controls the RF state mapping of each GPIO line when classic
|
||||
// ATR mode is active.
|
||||
// </info>
|
||||
// <bitfield name="RF_SELECT_A" range="0..11" initialvalue="0">
|
||||
// <info>
|
||||
// Set which RF channel's state to reflect in the pins for
|
||||
// HDMI connector A when @.ATR_OPTION is set to classic ATR.
|
||||
// Controlled in a per-pin basis.
|
||||
// 0 = RF0 State(GPIO_ATR_STATE 0x00-0x03)
|
||||
// 1 = RF1 State(GPIO_ATR_STATE 0x04-0x07)
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RF_SELECT_B" range="16..27" initialvalue="0">
|
||||
// <info>
|
||||
// Set which RF channel's state to reflect in the pins of
|
||||
// HDMI connector B when @.ATR_OPTION is set to classic ATR.
|
||||
// Controlled in a per-pin basis.
|
||||
// 0 = RF0 State(GPIO_ATR_STATE 0x00-0x03)
|
||||
// 1 = RF1 State(GPIO_ATR_STATE 0x04-0x07)
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// </register>
|
||||
// <register name="GPIO_DIR" offset="0x48" size="32">
|
||||
// <info>
|
||||
// Controls the direction of each GPIO signal when controlled by the radio state.
|
||||
// 0 = GPIO pin set to input. 1 = GPIO pin set to output
|
||||
// </info>
|
||||
// <bitfield name="GPIO_DIR_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="GPIO_DIR_B" range="16..27" initialvalue="0"/>
|
||||
// </register>
|
||||
// <register name="GPIO_DISABLED" offset="0x4C" size="32">
|
||||
// <info>
|
||||
// Disable ATR Control. DB state 0 will be reflected regardless of the ATR state.
|
||||
// </info>
|
||||
// <bitfield name="GPIO_DISABLED_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="GPIO_DISABLED_B" range="16..27" initialvalue="0"/>
|
||||
// </register>
|
||||
// <register name="GPIO_IN" offset="0x50" size="32">
|
||||
// <info>
|
||||
// Reflects the logic state of each GPIO input.
|
||||
// </info>
|
||||
// <bitfield name="GPIO_IN_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="GPIO_IN_B" range="16..27" initialvalue="0"/>
|
||||
// </register>
|
||||
// </group>
|
||||
//</regmap>
|
||||
//XmlParse xml_off
|
||||
Reference in New Issue
Block a user