fpga: x400: Add SPI bus support for GPIO ports

Original-commit: 38c549d1f7672e38773fc6624539cc166285a1df
This commit is contained in:
Javier Valenzuela
2022-01-25 10:18:47 -07:00
committed by Wade Fife
parent 962d01e583
commit 5237e5778c
9 changed files with 1338 additions and 60 deletions
+1
View File
@@ -74,6 +74,7 @@ x4xx_global_regs.v \
x4xx_versioning_regs.v \ x4xx_versioning_regs.v \
x4xx_dio.v \ x4xx_dio.v \
x4xx_gpio_atr.v \ x4xx_gpio_atr.v \
x4xx_gpio_spi.v \
rf/100m/rf_core_100m.v \ rf/100m/rf_core_100m.v \
rf/200m/rf_core_200m.v \ rf/200m/rf_core_200m.v \
rf/200m/rf_down_4to2.v \ rf/200m/rf_down_4to2.v \
+17 -1
View File
@@ -269,6 +269,21 @@
<p><span class="register" id="a_CPLD_INTERFACE_REGMAP|IPASS_CONTROL" onclick="a('CPLD_INTERFACE_REGMAP|IPASS_CONTROL');">IPASS_CONTROL</span></p> <p><span class="register" id="a_CPLD_INTERFACE_REGMAP|IPASS_CONTROL" onclick="a('CPLD_INTERFACE_REGMAP|IPASS_CONTROL');">IPASS_CONTROL</span></p>
</div> </div>
</div> </div>
<p>
<span class="pm" id="pm_DIG_IFC_REGMAP" onclick="pm('DIG_IFC_REGMAP');">+</span>
<span class="regmap" id="a_DIG_IFC_REGMAP" onclick="a('DIG_IFC_REGMAP');">DIG_IFC_REGMAP</span>
</p> <div class="sh" id="div_DIG_IFC_REGMAP">
<p>
<span class="pm" id="pm_DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS" onclick="pm('DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS');">+</span>
<span class="group" id="a_DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS" onclick="a('DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS');">SPI_OVER_GPIO_REGS</span>
</p>
<div class="sh" id="div_DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS">
<p><span class="register" id="a_DIG_IFC_REGMAP|SPI_SLAVE_CONFIG" onclick="a('DIG_IFC_REGMAP|SPI_SLAVE_CONFIG');">SPI_SLAVE_CONFIG</span></p>
<p><span class="register" id="a_DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG" onclick="a('DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG');">SPI_TRANSACTION_CONFIG</span></p>
<p><span class="register" id="a_DIG_IFC_REGMAP|SPI_TRANSACTION_GO" onclick="a('DIG_IFC_REGMAP|SPI_TRANSACTION_GO');">SPI_TRANSACTION_GO</span></p>
<p><span class="register" id="a_DIG_IFC_REGMAP|SPI_STATUS" onclick="a('DIG_IFC_REGMAP|SPI_STATUS');">SPI_STATUS</span></p>
</div>
</div>
<p> <p>
<span class="pm" id="pm_DIO_REGMAP" onclick="pm('DIO_REGMAP');">+</span> <span class="pm" id="pm_DIO_REGMAP" onclick="pm('DIO_REGMAP');">+</span>
<span class="regmap" id="a_DIO_REGMAP" onclick="a('DIO_REGMAP');">DIO_REGMAP</span> <span class="regmap" id="a_DIO_REGMAP" onclick="a('DIO_REGMAP');">DIO_REGMAP</span>
@@ -579,7 +594,8 @@
</p> </p>
<div class="sh" id="div_RADIO_DIO_REGMAP|DIO_SOURCES"> <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|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> <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>
<p><span class="register" id="a_RADIO_DIO_REGMAP|DIGITAL_IFC_REGS" onclick="a('RADIO_DIO_REGMAP|DIGITAL_IFC_REGS');">DIGITAL_IFC_REGS</span></p>
</div> </div>
</div> </div>
<p> <p>
+551 -2
View File
@@ -3229,6 +3229,492 @@ Total Offset =</td></tr>
</div> </div>
</div>
<div class="regmap">
<a name="DIG_IFC_REGMAP"></a>
<h1 class="regmap">DIG_IFC_REGMAP</h1>
<div class="group"><a name="DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS"></a><h2 class="group">SPI_OVER_GPIO_REGS</h2>
<div class="register">
<a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG"></a>
<h3 class="register">Offset 0x0000: SPI_SLAVE_CONFIG(3:0) Register Array (R|W)</h3>
<a class="sh_addrs" href="javascript:sa('DIG_IFC_REGMAP|SPI_SLAVE_CONFIG_in')">(<span id="show_DIG_IFC_REGMAP|SPI_SLAVE_CONFIG_in">show</span> extended info)</a>
<div class="sh_addrs" id="div_DIG_IFC_REGMAP|SPI_SLAVE_CONFIG_in">
<table class="extended_info">
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RADIO_CTRLPORT_REGMAP|DIO_WINDOW">RADIO_CTRLPORT_REGMAP|DIO_WINDOW</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x00C000</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RADIO_DIO_REGMAP|DIGITAL_IFC_REGS">RADIO_DIO_REGMAP|DIGITAL_IFC_REGS</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x002000</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">SPI_SLAVE_CONFIG</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x0000 + i*4</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info">
Cannot determine accessibility through this path</td></tr>
<tr><td class="offset_info">
Total Offset =</td></tr>
<tr><td class="offset_info">&nbsp;&nbsp;0x00E000 + i*4
</td></tr>
</table>
</td>
</tr>
</table><p/>
<p class="reg_info"><B>Initial Values</B><BR/>
<table>
<tr><td>default</td><td>=&gt;</td><td>0x00000000</td></tr>
</table>
</p>
<p class="reg_info">This register is defined in HDL source file x4xx_gpio_spi.v.<BR/>
It uses RegType <b>SPI_SETUP</b> which is defined in HDL source file x4xx_gpio_spi.v.</p>
</div>
<div class="info">
Controls SPI Transaction<BR/>
Set of configuration registers for the supported slaves.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
<tr class="header"><td class="bits">Bits</td><td>Name</td></tr>
<tr valign="top">
<td class="bits">31..28</td>
<td>
<p><span class="name">Reserved</span><span class="attr"> </span></p>
<p></p>
</td>
</tr>
<tr valign="top">
<td class="bits">27</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|MOSI_EDGE"></a>MOSI_EDGE</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Controls the edge in which the MOSI line is updated.</br>
0 = falling edge of SCLK.</br>
1 = rising edge of SCLK.</p>
</td>
</tr>
<tr valign="top">
<td class="bits">26</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|MISO_EDGE"></a>MISO_EDGE</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Controls the edge in which the MISO line is latched.</br>
0 = falling edge of SCLK.</br>
1 = rising edge of SCLK.</p>
</td>
</tr>
<tr valign="top">
<td class="bits">25..20</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SPI_LENGTH"></a>SPI_LENGTH</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Indicates the length of SPI transactions to this slave.</p>
</td>
</tr>
<tr valign="top">
<td class="bits">19..15</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SLAVE_CS"></a>SLAVE_CS</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Indicates which GPIO line to use for the CS signal.</br>
0-11 : Port A GPIO</br>
16-27: Port B GPIO</p>
</td>
</tr>
<tr valign="top">
<td class="bits">14..10</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SLAVE_MISO"></a>SLAVE_MISO</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Indicates which GPIO line to use for the MISO signal.</br>
0-11 : Port A GPIO</br>
16-27: Port B GPIO</p>
</td>
</tr>
<tr valign="top">
<td class="bits">9..5</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SLAVE_MOSI"></a>SLAVE_MOSI</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Indicates which GPIO line to use for the MOSI signal.</br>
0-11 : Port A GPIO</br>
16-27: Port B GPIO</p>
</td>
</tr>
<tr valign="top">
<td class="bits">4..0</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SLAVE_CLK"></a>SLAVE_CLK</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Indicates which GPIO line to use for the SCLK signal.</br>
0-11 : Port A GPIO</br>
16-27: Port B GPIO</p>
</td>
</tr>
</table>
</div>
<div class="register">
<a name="DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG"></a>
<h3 class="register">Offset 0x0010: SPI_TRANSACTION_CONFIG Register (R|W)</h3>
<a class="sh_addrs" href="javascript:sa('DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG_in')">(<span id="show_DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG_in">show</span> extended info)</a>
<div class="sh_addrs" id="div_DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG_in">
<table class="extended_info">
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RADIO_CTRLPORT_REGMAP|DIO_WINDOW">RADIO_CTRLPORT_REGMAP|DIO_WINDOW</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x00C000</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RADIO_DIO_REGMAP|DIGITAL_IFC_REGS">RADIO_DIO_REGMAP|DIGITAL_IFC_REGS</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x002000</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">SPI_TRANSACTION_CONFIG</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x0010</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info">
Total Offset =</td></tr>
<tr><td class="offset_info">&nbsp;&nbsp;0x00E010
</td></tr>
</table>
</td>
</tr>
</table><p/>
<p class="reg_info">Initial Value = 0x00000000
</p>
<p class="reg_info">This register is defined in HDL source file x4xx_gpio_spi.v.</p>
</div>
<div class="info">
Controls clock rate and target for subsequent SPI transactions.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
<tr class="header"><td class="bits">Bits</td><td>Name</td></tr>
<tr valign="top">
<td class="bits">31..24</td>
<td>
<p><span class="name">Reserved</span><span class="attr"> </span></p>
<p></p>
</td>
</tr>
<tr class='byte' valign="top">
<td class="bits">23..18</td>
<td>
<p><span class="name">Reserved</span><span class="attr"> </span></p>
<p></p>
</td>
</tr>
<tr valign="top">
<td class="bits">17..16</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG|SPI_SLAVE_SELECT"></a>SPI_SLAVE_SELECT</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p></p>
</td>
</tr>
<tr class='byte' valign="top">
<td class="bits">15..0</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG|SPI_CLK_DIV"></a>SPI_CLK_DIV</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Controls the rate for subsequent SPI transactions. SCLK = DataClk/[(SPI_CLK_DIV+1)]</p>
</td>
</tr>
</table>
</div>
<div class="register">
<a name="DIG_IFC_REGMAP|SPI_TRANSACTION_GO"></a>
<h3 class="register">Offset 0x0014: SPI_TRANSACTION_GO Register (W)</h3>
<a class="sh_addrs" href="javascript:sa('DIG_IFC_REGMAP|SPI_TRANSACTION_GO_in')">(<span id="show_DIG_IFC_REGMAP|SPI_TRANSACTION_GO_in">show</span> extended info)</a>
<div class="sh_addrs" id="div_DIG_IFC_REGMAP|SPI_TRANSACTION_GO_in">
<table class="extended_info">
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RADIO_CTRLPORT_REGMAP|DIO_WINDOW">RADIO_CTRLPORT_REGMAP|DIO_WINDOW</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x00C000</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RADIO_DIO_REGMAP|DIGITAL_IFC_REGS">RADIO_DIO_REGMAP|DIGITAL_IFC_REGS</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x002000</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">SPI_TRANSACTION_GO</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x0014</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info">
Total Offset =</td></tr>
<tr><td class="offset_info">&nbsp;&nbsp;0x00E014
</td></tr>
</table>
</td>
</tr>
</table><p/>
<p class="reg_info">Initial Value = 0x00000000
</p>
<p class="reg_info">This register is defined in HDL source file x4xx_gpio_spi.v.</p>
</div>
<div class="info">
Starts a SPI transaction
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
<tr class="header"><td class="bits">Bits</td><td>Name</td></tr>
<tr valign="top">
<td class="bits">31..0w</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_TRANSACTION_GO|SPI_DATA"></a>SPI_DATA</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Payload to be sent for the SPI transaction. If the payload is shorter than 32 bits,
it must be aligned to the MSbs in this field. LSbs are ignored in this scenario.</p>
</td>
</tr>
</table>
</div>
<div class="register">
<a name="DIG_IFC_REGMAP|SPI_STATUS"></a>
<h3 class="register">Offset 0x0018: SPI_STATUS Register (R)</h3>
<a class="sh_addrs" href="javascript:sa('DIG_IFC_REGMAP|SPI_STATUS_in')">(<span id="show_DIG_IFC_REGMAP|SPI_STATUS_in">show</span> extended info)</a>
<div class="sh_addrs" id="div_DIG_IFC_REGMAP|SPI_STATUS_in">
<table class="extended_info">
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RADIO_CTRLPORT_REGMAP|DIO_WINDOW">RADIO_CTRLPORT_REGMAP|DIO_WINDOW</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x00C000</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RADIO_DIO_REGMAP|DIGITAL_IFC_REGS">RADIO_DIO_REGMAP|DIGITAL_IFC_REGS</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x002000</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">SPI_STATUS</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x0018</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info">
Total Offset =</td></tr>
<tr><td class="offset_info">&nbsp;&nbsp;0x00E018
</td></tr>
</table>
</td>
</tr>
</table><p/>
<p class="reg_info">Initial Value = 0x00000000
</p>
<p class="reg_info">This register is defined in HDL source file x4xx_gpio_spi.v.</p>
</div>
<div class="info">
Contains the status of the SPI engine.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
<tr class="header"><td class="bits">Bits</td><td>Name</td></tr>
<tr valign="top">
<td class="bits">31..25</td>
<td>
<p><span class="name">Reserved</span><span class="attr"> </span></p>
<p></p>
</td>
</tr>
<tr valign="top">
<td class="bits">24</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_STATUS|SPI_READY"></a>SPI_READY</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Indicates the SPI engine is ready to start a new SPI transaction.</p>
</td>
</tr>
<tr class='byte' valign="top">
<td class="bits">23..0</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_STATUS|SPI_RESPONSE"></a>SPI_RESPONSE</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Records the response of the last completed SPI transaction.</p>
</td>
</tr>
</table>
</div>
</div>
</div> </div>
<div class="regmap"> <div class="regmap">
@@ -8020,7 +8506,7 @@ Total Offset =</td></tr>
Controls whether GPIO lines use the TX and RX state of an RF channel Controls whether GPIO lines use the TX and RX state of an RF channel
(Classic ATR) or the daughterboard state the selector for the (Classic ATR) or the daughterboard state the selector for the
@.GPIO_ATR_STATE. <a href="#GPIO_ATR_REGMAP|ATR_STATE">ATR_STATE</a>.
</div> </div>
@@ -8069,7 +8555,7 @@ Controls whether GPIO lines use the TX and RX state of an RF channel
<p><span class="name"><a name="GPIO_ATR_REGMAP|ATR_OPTION_REGISTRER|ATR_OPTION"></a>ATR_OPTION</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p> <p><span class="name"><a name="GPIO_ATR_REGMAP|ATR_OPTION_REGISTRER|ATR_OPTION"></a>ATR_OPTION</span><span class="attr"> &nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Sets the scheme in which RF states in the radio will control GPIO <p>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 lines. 0 = DB state is used. RF states are combined and the
GPIO state is driven based on all 16 @.GPIO_ATR_STATE registers. GPIO state is driven based on all 16 <a href="#GPIO_ATR_REGMAP|ATR_STATE">ATR_STATE</a> registers.
1 = Each RF channel has its separate ATR state(Classic ATR). 1 = Each RF channel has its separate ATR state(Classic ATR).
Use register <a href="#GPIO_ATR_REGMAP|CLASSIC_ATR_CONFIG">CLASSIC_ATR_CONFIG</a> to indicate the RF channel Use register <a href="#GPIO_ATR_REGMAP|CLASSIC_ATR_CONFIG">CLASSIC_ATR_CONFIG</a> to indicate the RF channel
to which each GPIO line responds to.</p> to which each GPIO line responds to.</p>
@@ -16322,6 +16808,69 @@ Window to access the DIO register map through the control port from the radio bl
</div> </div>
</div>
<div class="register">
<a name="RADIO_DIO_REGMAP|DIGITAL_IFC_REGS"></a>
<h3 class="register">Offset 0x2000: DIGITAL_IFC_REGS Window (R|W)</h3>
<p class="offset_info">&nbsp;&nbsp;Target regmap = <a href="#DIG_IFC_REGMAP">DIG_IFC_REGMAP</a></p>
<a class="sh_addrs" href="javascript:sa('RADIO_DIO_REGMAP|DIGITAL_IFC_REGS_in')">(<span id="show_RADIO_DIO_REGMAP|DIGITAL_IFC_REGS_in">show</span> extended info)</a>
<div class="sh_addrs" id="div_RADIO_DIO_REGMAP|DIGITAL_IFC_REGS_in">
<table class="extended_info">
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RADIO_CTRLPORT_REGMAP|DIO_WINDOW">RADIO_CTRLPORT_REGMAP|DIO_WINDOW</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x00C000</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">DIGITAL_IFC_REGS</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x2000</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;size=0x1000 (4 Kbytes)</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info">
Total Offset =</td></tr>
<tr><td class="offset_info">&nbsp;&nbsp;0x00E000
</td></tr>
</table>
</td>
</tr>
</table><p/>
<p class="reg_info">This window is defined in HDL source file x4xx_core_common.v.</p>
</div>
<div class="info">
Register space reserved for configuring a digital interface over the GPIO lines.
Currently, SPI is the only supported protocol.
</div>
</div> </div>
</div> </div>
+88
View File
@@ -0,0 +1,88 @@
//
// Copyright 2021 Ettus Research, A National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: dig_ifc_regmap_utils.vh
// Description:
// The constants in this file are autogenerated by XmlParse.
//===============================================================================
// A numerically ordered list of registers and their HDL source files
//===============================================================================
// SPI_SLAVE_CONFIG : 0x0 (x4xx_gpio_spi.v)
// SPI_TRANSACTION_CONFIG : 0x10 (x4xx_gpio_spi.v)
// SPI_TRANSACTION_GO : 0x14 (x4xx_gpio_spi.v)
// SPI_STATUS : 0x18 (x4xx_gpio_spi.v)
//===============================================================================
// RegTypes
//===============================================================================
// SPI_SETUP Type (from x4xx_gpio_spi.v)
localparam SPI_SETUP_SIZE = 32;
localparam SPI_SETUP_MASK = 32'hFFFFFFF;
localparam SLAVE_CLK_SIZE = 5; //SPI_SETUP:SLAVE_CLK
localparam SLAVE_CLK_MSB = 4; //SPI_SETUP:SLAVE_CLK
localparam SLAVE_CLK = 0; //SPI_SETUP:SLAVE_CLK
localparam SLAVE_MOSI_SIZE = 5; //SPI_SETUP:SLAVE_MOSI
localparam SLAVE_MOSI_MSB = 9; //SPI_SETUP:SLAVE_MOSI
localparam SLAVE_MOSI = 5; //SPI_SETUP:SLAVE_MOSI
localparam SLAVE_MISO_SIZE = 5; //SPI_SETUP:SLAVE_MISO
localparam SLAVE_MISO_MSB = 14; //SPI_SETUP:SLAVE_MISO
localparam SLAVE_MISO = 10; //SPI_SETUP:SLAVE_MISO
localparam SLAVE_CS_SIZE = 5; //SPI_SETUP:SLAVE_CS
localparam SLAVE_CS_MSB = 19; //SPI_SETUP:SLAVE_CS
localparam SLAVE_CS = 15; //SPI_SETUP:SLAVE_CS
localparam SPI_LENGTH_SIZE = 6; //SPI_SETUP:SPI_LENGTH
localparam SPI_LENGTH_MSB = 25; //SPI_SETUP:SPI_LENGTH
localparam SPI_LENGTH = 20; //SPI_SETUP:SPI_LENGTH
localparam MISO_EDGE_SIZE = 1; //SPI_SETUP:MISO_EDGE
localparam MISO_EDGE_MSB = 26; //SPI_SETUP:MISO_EDGE
localparam MISO_EDGE = 26; //SPI_SETUP:MISO_EDGE
localparam MOSI_EDGE_SIZE = 1; //SPI_SETUP:MOSI_EDGE
localparam MOSI_EDGE_MSB = 27; //SPI_SETUP:MOSI_EDGE
localparam MOSI_EDGE = 27; //SPI_SETUP:MOSI_EDGE
//===============================================================================
// Register Group SPI_OVER_GPIO_REGS
//===============================================================================
// SPI_SLAVE_CONFIG Register (from x4xx_gpio_spi.v)
localparam SPI_SLAVE_CONFIG_COUNT = 4; // Number of elements in array
// SPI_TRANSACTION_CONFIG Register (from x4xx_gpio_spi.v)
localparam SPI_TRANSACTION_CONFIG = 'h10; // Register Offset
localparam SPI_TRANSACTION_CONFIG_SIZE = 32; // register width in bits
localparam SPI_TRANSACTION_CONFIG_MASK = 32'h3FFFF;
localparam SPI_CLK_DIV_SIZE = 16; //SPI_TRANSACTION_CONFIG:SPI_CLK_DIV
localparam SPI_CLK_DIV_MSB = 15; //SPI_TRANSACTION_CONFIG:SPI_CLK_DIV
localparam SPI_CLK_DIV = 0; //SPI_TRANSACTION_CONFIG:SPI_CLK_DIV
localparam SPI_SLAVE_SELECT_SIZE = 2; //SPI_TRANSACTION_CONFIG:SPI_SLAVE_SELECT
localparam SPI_SLAVE_SELECT_MSB = 17; //SPI_TRANSACTION_CONFIG:SPI_SLAVE_SELECT
localparam SPI_SLAVE_SELECT = 16; //SPI_TRANSACTION_CONFIG:SPI_SLAVE_SELECT
// SPI_TRANSACTION_GO Register (from x4xx_gpio_spi.v)
localparam SPI_TRANSACTION_GO = 'h14; // Register Offset
localparam SPI_TRANSACTION_GO_SIZE = 32; // register width in bits
localparam SPI_TRANSACTION_GO_MASK = 32'hFFFFFFFF;
localparam SPI_DATA_SIZE = 32; //SPI_TRANSACTION_GO:SPI_DATA
localparam SPI_DATA_MSB = 31; //SPI_TRANSACTION_GO:SPI_DATA
localparam SPI_DATA = 0; //SPI_TRANSACTION_GO:SPI_DATA
// SPI_STATUS Register (from x4xx_gpio_spi.v)
localparam SPI_STATUS = 'h18; // Register Offset
localparam SPI_STATUS_SIZE = 32; // register width in bits
localparam SPI_STATUS_MASK = 32'h1FFFFFF;
localparam SPI_RESPONSE_SIZE = 24; //SPI_STATUS:SPI_RESPONSE
localparam SPI_RESPONSE_MSB = 23; //SPI_STATUS:SPI_RESPONSE
localparam SPI_RESPONSE = 0; //SPI_STATUS:SPI_RESPONSE
localparam SPI_READY_SIZE = 1; //SPI_STATUS:SPI_READY
localparam SPI_READY_MSB = 24; //SPI_STATUS:SPI_READY
localparam SPI_READY = 24; //SPI_STATUS:SPI_READY
// Return the offset of an element of register array SPI_SLAVE_CONFIG
function integer SPI_SLAVE_CONFIG (input integer i);
SPI_SLAVE_CONFIG = (i * 'h4) + 'h0;
endfunction
@@ -13,6 +13,7 @@
// RADIO_GPIO_ATR_REGS : 0x0 (x4xx_core_common.v) // RADIO_GPIO_ATR_REGS : 0x0 (x4xx_core_common.v)
// DIO_SOURCE_CONTROL : 0x1000 (x4xx_core_common.v) // DIO_SOURCE_CONTROL : 0x1000 (x4xx_core_common.v)
// DIGITAL_IFC_REGS : 0x2000 (x4xx_core_common.v)
//=============================================================================== //===============================================================================
// RegTypes // RegTypes
@@ -29,3 +30,7 @@
// DIO_SOURCE_CONTROL Window (from x4xx_core_common.v) // DIO_SOURCE_CONTROL Window (from x4xx_core_common.v)
localparam DIO_SOURCE_CONTROL = 'h1000; // Window Offset localparam DIO_SOURCE_CONTROL = 'h1000; // Window Offset
localparam DIO_SOURCE_CONTROL_SIZE = 'h1000; // size in bytes localparam DIO_SOURCE_CONTROL_SIZE = 'h1000; // size in bytes
// DIGITAL_IFC_REGS Window (from x4xx_core_common.v)
localparam DIGITAL_IFC_REGS = 'h2000; // Window Offset
localparam DIGITAL_IFC_REGS_SIZE = 'h1000; // size in bytes
+1
View File
@@ -249,6 +249,7 @@ module x4xx_core #(
.PCIE_PRESENT (0) .PCIE_PRESENT (0)
) x4xx_core_common_i ( ) x4xx_core_common_i (
.radio_clk (radio_clk), .radio_clk (radio_clk),
.radio_clk_2x (radio_clk_2x),
.radio_rst (radio_rst), .radio_rst (radio_rst),
.rfnoc_chdr_clk (rfnoc_chdr_clk), .rfnoc_chdr_clk (rfnoc_chdr_clk),
.rfnoc_chdr_rst (rfnoc_chdr_rst), .rfnoc_chdr_rst (rfnoc_chdr_rst),
+139 -55
View File
@@ -38,6 +38,7 @@ module x4xx_core_common #(
) ( ) (
// Clocks and resets // Clocks and resets
input wire radio_clk, input wire radio_clk,
input wire radio_clk_2x,
input wire radio_rst, input wire radio_rst,
input wire rfnoc_chdr_clk, input wire rfnoc_chdr_clk,
@@ -234,16 +235,16 @@ module x4xx_core_common #(
.s_ctrlport_resp_ack (m_resp_ack), .s_ctrlport_resp_ack (m_resp_ack),
.s_ctrlport_resp_status (m_resp_status), .s_ctrlport_resp_status (m_resp_status),
.s_ctrlport_resp_data (m_resp_data), .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_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_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_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_data ({timekeeper_req_data, versioning_req_data, global_regs_req_data, dio_req_data}),
.m_ctrlport_req_byte_en (), .m_ctrlport_req_byte_en (),
.m_ctrlport_req_has_time (), .m_ctrlport_req_has_time (),
.m_ctrlport_req_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_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_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}) .m_ctrlport_resp_data ({timekeeper_resp_data, versioning_resp_data, global_regs_resp_data, dio_resp_data})
); );
@@ -349,6 +350,7 @@ module x4xx_core_common #(
// Radio CtrlPort Splitter // 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_wr;
wire [ 1*NUM_DBOARDS-1:0] rf_ctrlport_req_rd; wire [ 1*NUM_DBOARDS-1:0] rf_ctrlport_req_rd;
wire [ 20*NUM_DBOARDS-1:0] rf_ctrlport_req_addr; wire [ 20*NUM_DBOARDS-1:0] rf_ctrlport_req_addr;
@@ -371,9 +373,36 @@ module x4xx_core_common #(
wire [ 2*NUM_DBOARDS-1:0] radio_dio_resp_status; wire [ 2*NUM_DBOARDS-1:0] radio_dio_resp_status;
wire [ 32*NUM_DBOARDS-1:0] radio_dio_resp_data; 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 [ 4*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_byte_en;
wire [ 1*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_has_time;
wire [ 64*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_time;
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 [ 4*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_byte_en;
wire [ 1*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_has_time;
wire [ 64*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_time;
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_out;
wire [NUM_DBOARDS*32-1:0] atr_gpio_ddr; 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; genvar db;
generate generate
for (db = 0; db < NUM_DBOARDS; db = db+1) begin : gen_radio_ctrlport for (db = 0; db < NUM_DBOARDS; db = db+1) begin : gen_radio_ctrlport
@@ -385,67 +414,100 @@ module x4xx_core_common #(
// This section takes the CtrlPort master from each radio block and splits it // 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 // 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 // RFDC timing control (rf_ctrlport_*), the ATR GPIO control for the DB state
// the current radio(db) and DIO main control block(x4xx_dio). // the current radio(db), 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 // Refer to diagram in the RADIO_CTRLPORT_REGMAP Register map for a
// visual representation on how these interfaces are distributed. // visual representation on how these interfaces are distributed.
// Register space offset calculation // Register space offset calculation
localparam [19:0] DIO_SOURCE_CONTROL_OFFSET = DIO_WINDOW + DIO_SOURCE_CONTROL; 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] 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 // Register space size calculation
localparam [31:0] RFDC_TIMING_WINDOW_SIZE_W = $clog2(RFDC_TIMING_WINDOW_SIZE); localparam [31:0] RFDC_TIMING_WINDOW_SIZE_W = $clog2(RFDC_TIMING_WINDOW_SIZE);
localparam [31:0] DB_WINDOW_SIZE_W = $clog2(DB_WINDOW_SIZE); 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] 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] RADIO_GPIO_ATR_SIZE_W = $clog2(RADIO_GPIO_ATR_REGS_SIZE);
localparam [31:0] DIGITAL_IFC_REGS_SIZE_W = $clog2(DIGITAL_IFC_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 #( ctrlport_decoder_param #(
.NUM_SLAVES (4), .NUM_SLAVES (5),
.PORT_BASE ({ DIO_SOURCE_CONTROL_OFFSET, .PORT_BASE ({ DIGITAL_IFC_OFFSET,
DIO_SOURCE_CONTROL_OFFSET,
RADIO_GPIO_ATR_OFFSET, RADIO_GPIO_ATR_OFFSET,
RFDC_TIMING_WINDOW[19:0], RFDC_TIMING_WINDOW[19:0],
DB_WINDOW[19:0] DB_WINDOW[19:0]
}), }),
.PORT_ADDR_W ({ DIO_SOURCE_CONTROL_SIZE_W, .PORT_ADDR_W ({ DIGITAL_IFC_REGS_SIZE_W,
DIO_SOURCE_CONTROL_SIZE_W,
RADIO_GPIO_ATR_SIZE_W, RADIO_GPIO_ATR_SIZE_W,
RFDC_TIMING_WINDOW_SIZE_W, RFDC_TIMING_WINDOW_SIZE_W,
DB_WINDOW_SIZE_W DB_WINDOW_SIZE_W
}) })
) ctrlport_decoder_param_i ( ) ctrlport_decoder_param_i (
.ctrlport_clk (radio_clk), .ctrlport_clk ( radio_clk ),
.ctrlport_rst (radio_rst), .ctrlport_rst ( radio_rst ),
.s_ctrlport_req_wr (s_radio_ctrlport_req_wr [ 1*db+: 1]), .s_ctrlport_req_wr ( s_radio_ctrlport_req_wr [ 1*db+: 1] ),
.s_ctrlport_req_rd (s_radio_ctrlport_req_rd [ 1*db+: 1]), .s_ctrlport_req_rd ( s_radio_ctrlport_req_rd [ 1*db+: 1] ),
.s_ctrlport_req_addr (s_radio_ctrlport_req_addr [20*db+:20]), .s_ctrlport_req_addr ( s_radio_ctrlport_req_addr [20*db+:20] ),
.s_ctrlport_req_data (s_radio_ctrlport_req_data [32*db+:32]), .s_ctrlport_req_data ( s_radio_ctrlport_req_data [32*db+:32] ),
.s_ctrlport_req_byte_en (s_radio_ctrlport_req_byte_en [ 4*db+: 4]), .s_ctrlport_req_byte_en ( s_radio_ctrlport_req_byte_en [ 4*db+: 4] ),
.s_ctrlport_req_has_time (s_radio_ctrlport_req_has_time [ 1*db+: 1]), .s_ctrlport_req_has_time ( s_radio_ctrlport_req_has_time [ 1*db+: 1] ),
.s_ctrlport_req_time (s_radio_ctrlport_req_time [64*db+:64]), .s_ctrlport_req_time ( s_radio_ctrlport_req_time [64*db+:64] ),
.s_ctrlport_resp_ack (s_radio_ctrlport_resp_ack [ 1*db+: 1]), .s_ctrlport_resp_ack ( s_radio_ctrlport_resp_ack [ 1*db+: 1] ),
.s_ctrlport_resp_status (s_radio_ctrlport_resp_status [ 2*db+: 2]), .s_ctrlport_resp_status ( s_radio_ctrlport_resp_status [ 2*db+: 2] ),
.s_ctrlport_resp_data (s_radio_ctrlport_resp_data [32*db+:32]), .s_ctrlport_resp_data ( s_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_wr ({ gpio_spi_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] }), radio_dio_req_wr [ 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] }), gpio_atr_ctrlport_req_wr [ 1*db+: 1],
.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] }), rf_ctrlport_req_wr [ 1*db+: 1],
.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_radio_ctrlport_req_wr [ 1*db+: 1] }),
.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_rd ({ gpio_spi_ctrlport_req_rd [ 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] }), radio_dio_req_rd [ 1*db+: 1],
.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] }), gpio_atr_ctrlport_req_rd [ 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] }), rf_ctrlport_req_rd [ 1*db+: 1],
.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] }) m_radio_ctrlport_req_rd [ 1*db+: 1] }),
.m_ctrlport_req_addr ({ gpio_spi_ctrlport_req_addr [20*db+:20],
radio_dio_req_addr [20*db+:20],
gpio_atr_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 ({ gpio_spi_ctrlport_req_data [32*db+:32],
radio_dio_req_data [32*db+:32],
gpio_atr_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 ({ gpio_spi_ctrlport_req_byte_en [ 4*db+: 4],
radio_dio_req_byte_en [ 4*db+: 4],
gpio_atr_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 ({ gpio_spi_ctrlport_req_has_time [ 1*db+: 1],
radio_dio_req_has_time [ 1*db+: 1],
gpio_atr_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 ({ gpio_spi_ctrlport_req_time [64*db+:64],
radio_dio_req_time [64*db+:64],
gpio_atr_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 ({ gpio_spi_ctrlport_resp_ack [ 1*db+: 1],
radio_dio_resp_ack [ 1*db+: 1],
gpio_atr_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 ({ gpio_spi_ctrlport_resp_status [ 2*db+: 2],
radio_dio_resp_status [ 2*db+: 2],
gpio_atr_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 ({ gpio_spi_ctrlport_resp_data [32*db+:32],
radio_dio_resp_data [32*db+:32],
gpio_atr_ctrlport_resp_data [32*db+:32],
rf_ctrlport_resp_data [32*db+:32],
m_radio_ctrlport_resp_data [32*db+:32] })
); );
// Compute ATR state for this radio // Compute ATR state for this radio
@@ -459,19 +521,37 @@ module x4xx_core_common #(
) x4xx_gpio_atr_i ( ) x4xx_gpio_atr_i (
.ctrlport_clk (radio_clk), .ctrlport_clk (radio_clk),
.ctrlport_rst (radio_rst), .ctrlport_rst (radio_rst),
.s_ctrlport_req_wr (gpio_atr_ctrlport_req_wr), .s_ctrlport_req_wr (gpio_atr_ctrlport_req_wr [ 1*db+: 1]),
.s_ctrlport_req_rd (gpio_atr_ctrlport_req_rd), .s_ctrlport_req_rd (gpio_atr_ctrlport_req_rd [ 1*db+: 1]),
.s_ctrlport_req_addr (gpio_atr_ctrlport_req_addr), .s_ctrlport_req_addr (gpio_atr_ctrlport_req_addr [20*db+:20]),
.s_ctrlport_req_data (gpio_atr_ctrlport_req_data), .s_ctrlport_req_data (gpio_atr_ctrlport_req_data [32*db+:32]),
.s_ctrlport_resp_ack (gpio_atr_ctrlport_resp_ack), .s_ctrlport_resp_ack (gpio_atr_ctrlport_resp_ack [ 1*db+: 1]),
.s_ctrlport_resp_status (gpio_atr_ctrlport_resp_status), .s_ctrlport_resp_status (gpio_atr_ctrlport_resp_status [ 2*db+: 2]),
.s_ctrlport_resp_data (gpio_atr_ctrlport_resp_data), .s_ctrlport_resp_data (gpio_atr_ctrlport_resp_data [32*db+:32]),
.db_state (db_state), .db_state (db_state),
.gpio_in ({4'b0, gpio_in_b, 4'b0, gpio_in_a}), .gpio_in ({4'b0, gpio_in_b, 4'b0, gpio_in_a}),
.gpio_out (atr_gpio_out[db*32+: 32]), .gpio_out (atr_gpio_out[db*32+: 32]),
.gpio_ddr (atr_gpio_ddr[db*32+: 32]) .gpio_ddr (atr_gpio_ddr[db*32+: 32])
); );
x4xx_gpio_spi #(
.NUM_SLAVES (2)
) x4xx_gpio_spi_i(
.ctrlport_clk (radio_clk),
.ctrlport_clk_2x (radio_clk_2x),
.ctrlport_rst (radio_rst),
.s_ctrlport_req_wr (gpio_spi_ctrlport_req_wr [ 1*db+: 1]),
.s_ctrlport_req_rd (gpio_spi_ctrlport_req_rd [ 1*db+: 1]),
.s_ctrlport_req_addr (gpio_spi_ctrlport_req_addr [20*db+:20]),
.s_ctrlport_req_data (gpio_spi_ctrlport_req_data [32*db+:32]),
.s_ctrlport_resp_ack (gpio_spi_ctrlport_resp_ack [ 1*db+: 1]),
.s_ctrlport_resp_status (gpio_spi_ctrlport_resp_status [ 2*db+: 2]),
.s_ctrlport_resp_data (gpio_spi_ctrlport_resp_data [32*db+:32]),
.gpio_out (spi_gpio_out[db*32+: 32]),
.gpio_ddr (spi_gpio_ddr[db*32+: 32]),
.gpio_in ({4'b0, gpio_in_b, 4'b0, gpio_in_a})
);
end end
endgenerate endgenerate
@@ -686,10 +766,10 @@ module x4xx_core_common #(
.atr_gpio_ddr (atr_gpio_ddr), .atr_gpio_ddr (atr_gpio_ddr),
.ps_gpio_out ({4'b0, ps_gpio_out_b, 4'b0, ps_gpio_out_a}), .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}), .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_out_radio0 (spi_gpio_out[31:0]),
.digital_ifc_gpio_ddr_radio0 (32'b0), .digital_ifc_gpio_ddr_radio0 (spi_gpio_ddr[31:0]),
.digital_ifc_gpio_out_radio1 (32'b0), .digital_ifc_gpio_out_radio1 (spi_gpio_out[63:32]),
.digital_ifc_gpio_ddr_radio1 (32'b0), .digital_ifc_gpio_ddr_radio1 (spi_gpio_ddr[63:32]),
.user_app_in_a (gpio_in_fabric_a), .user_app_in_a (gpio_in_fabric_a),
.user_app_in_b (gpio_in_fabric_b), .user_app_in_b (gpio_in_fabric_b),
.user_app_out_a (gpio_out_fabric_a), .user_app_out_a (gpio_out_fabric_a),
@@ -771,6 +851,10 @@ endmodule
// <window name="DIO_SOURCE_CONTROL" offset="0x1000" size="0x1000" targetregmap="DIO_REGMAP"> // <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> // <info>Window to access the DIO register map through the control port from the radio blocks.</info>
// </window> // </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> // </group>
//</regmap> //</regmap>
+2 -2
View File
@@ -312,13 +312,13 @@ endmodule
// <info> // <info>
// Controls whether GPIO lines use the TX and RX state of an RF channel // Controls whether GPIO lines use the TX and RX state of an RF channel
// (Classic ATR) or the daughterboard state the selector for the // (Classic ATR) or the daughterboard state the selector for the
// @.GPIO_ATR_STATE. // @.ATR_STATE.
// </info> // </info>
// <bitfield name="ATR_OPTION" range="0" initialvalue="0"> // <bitfield name="ATR_OPTION" range="0" initialvalue="0">
// <info> // <info>
// Sets the scheme in which RF states in the radio will control GPIO // 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 // lines. 0 = DB state is used. RF states are combined and the
// GPIO state is driven based on all 16 @.GPIO_ATR_STATE registers. // GPIO state is driven based on all 16 @.ATR_STATE registers.
// 1 = Each RF channel has its separate ATR state(Classic ATR). // 1 = Each RF channel has its separate ATR state(Classic ATR).
// Use register @.CLASSIC_ATR_CONFIG to indicate the RF channel // Use register @.CLASSIC_ATR_CONFIG to indicate the RF channel
// to which each GPIO line responds to. // to which each GPIO line responds to.
+534
View File
@@ -0,0 +1,534 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: x4xx_gpio_spi
//
// Description:
//
// This block enables control of a SPI master engine via CtrlPort
// transactions.
// It also enables customization on how signals from the SPI buses
// connected to the master are mapped to the GPIO Ports.
// This block supports configuring communication to up to 4 SPI slaves.
//
// Parameters:
//
// NUM_SLAVES : Number of SPI slaves to be supported. Values from 1 to 4
// are supported. SPI transfers can only target one slave
// at a time.
// BASE_ADDRESS : Start address for this register block.
// SIZE_ADDRESS : Size of the CtrlPort window to consider in this block.
//
`default_nettype none
module x4xx_gpio_spi #(
parameter NUM_SLAVES = 4,
parameter [19:0] BASE_ADDRESS = 0,
parameter [19:0] SIZE_ADDRESS = 19'h20
) (
input wire ctrlport_clk,
input wire ctrlport_clk_2x,
input wire ctrlport_rst,
// Request
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,
// Response
output reg s_ctrlport_resp_ack = 1'b0,
output reg [ 1:0] s_ctrlport_resp_status = 2'b0,
output reg [31:0] s_ctrlport_resp_data = 32'b0,
// GPIO control/status
output wire [31:0] gpio_out,
output wire [31:0] gpio_ddr,
input wire [31:0] gpio_in
);
`include "../../lib/rfnoc/core/ctrlport.vh"
`include "regmap/dig_ifc_regmap_utils.vh"
// Registers / wires for SPI core communication
reg [31:0] set_data = 0;
reg [ 7:0] set_addr = 0;
reg set_stb = 1'b0;
wire [31:0] readback;
wire readback_stb;
wire readback_stb_extended;
wire sclk;
wire mosi;
wire miso;
// This array is set to the maximum supported SPI slaves instead of
// the provided NUM_SLAVES to facilitate concurrent re-mapping.
// See section(GPIO Mapping) of this file.
wire [3:0] ss;
// Auxiliary signals to compute which GPIO lines are outputs
reg [31:0] gpio_is_mosi = 32'b0;
reg [31:0] gpio_is_sclk = 32'b0;
reg [31:0] gpio_is_cs = 32'b0;
// SPI-to-GPIO mapping signals.
// These arrays are set to the maximum supported SPI slaves instead of
// the provided NUM_SLAVES to facilitate concurrent re-mapping.
// See section(GPIO Mapping) of this file.
reg [ SLAVE_CLK_SIZE-1:0] sclk_mapping [3:0];
reg [SLAVE_MOSI_SIZE-1:0] mosi_mapping [3:0];
reg [SLAVE_MISO_SIZE-1:0] miso_mapping [3:0];
reg [ SLAVE_CS_SIZE-1:0] ss_mapping [3:0];
//---------------------------------------------------------------------------
// Address calculation
//---------------------------------------------------------------------------
wire address_in_range =
(s_ctrlport_req_addr >= BASE_ADDRESS) &&
(s_ctrlport_req_addr < BASE_ADDRESS + SIZE_ADDRESS);
// Check that address is targeting slave configuration.
wire address_is_slave =
(s_ctrlport_req_addr >= BASE_ADDRESS + SPI_SLAVE_CONFIG(0)) &&
(s_ctrlport_req_addr <= BASE_ADDRESS + SPI_SLAVE_CONFIG(3));
// Decode the slave being addressed.
wire [1:0]slave_address = s_ctrlport_req_addr[3:2];
//---------------------------------------------------------------------------
// Slave configuration signals
//---------------------------------------------------------------------------
// These settings are registered individually for each slave
reg [ NUM_SLAVES-1:0] data_in_edge = {NUM_SLAVES{1'b0}};
reg [ NUM_SLAVES-1:0] data_out_edge = {NUM_SLAVES{1'b0}};
reg [SPI_LENGTH_SIZE-1:0] slave_spi_length [NUM_SLAVES-1:0];
// One-hot encoding to indicate active slave
reg [NUM_SLAVES-1:0] slave_select = {NUM_SLAVES{1'b0}};
//---------------------------------------------------------------------------
// FSM to handle transfers
//---------------------------------------------------------------------------
localparam IDLE = 3'd0;
localparam SET_DIVIDER = 3'd1;
localparam WRITE_SPI = 3'd2;
localparam CONFIG_TRANSFER = 3'd3;
localparam WAIT_SPI = 3'd4;
localparam DIVIDER_ADDRESS = 8'd0;
localparam CTRL_ADDRESS = 8'd1;
localparam DATA_ADDRESS = 8'd2;
reg [ 2:0] state = IDLE;
reg [ 31:0] data_cache;
reg [SPI_CLK_DIV_SIZE-1:0] divider;
reg [ 1:0] cs;
reg spi_go = 1'b0;
reg spi_ready = 1'b0;
integer slave_i;
//---------------------------------------------------------------------------
// CtrlPort Register endpoints
//---------------------------------------------------------------------------
always @ (posedge ctrlport_clk) begin
if (ctrlport_rst) begin
s_ctrlport_resp_ack <= 1'b0;
spi_go <= 1'b0;
spi_ready <= 1'b0;
divider <= {SPI_CLK_DIV_SIZE{1'b0}};
cs <= 2'b0;
// Assigned to unassigned mapping. This avoids overwriting
// signals with those from uninitialized slaves.
for (slave_i=0; slave_i<4; slave_i=slave_i+1) begin
sclk_mapping[slave_i] <= 5'h31;
mosi_mapping[slave_i] <= 5'h31;
miso_mapping[slave_i] <= 5'h31;
ss_mapping [slave_i] <= 5'h31;
end
for (slave_i=0; slave_i<NUM_SLAVES; slave_i=slave_i+1) begin
slave_spi_length[slave_i] <= {SPI_LENGTH_SIZE{1'b0}};
end
end else begin
// Default assignments
s_ctrlport_resp_ack <= 1'b0;
spi_go <= 1'b0;
// Requests appear
if (s_ctrlport_req_wr) begin
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_data <= {32{1'bx}};
s_ctrlport_resp_status <= CTRL_STS_OKAY;
// Address spi configuration writes
if(address_is_slave) begin
// GPIO mapping
sclk_mapping [slave_address] <= s_ctrlport_req_data[SLAVE_CLK_MSB:SLAVE_CLK];
mosi_mapping [slave_address] <= s_ctrlport_req_data[SLAVE_MOSI_MSB:SLAVE_MOSI];
miso_mapping [slave_address] <= s_ctrlport_req_data[SLAVE_MISO_MSB:SLAVE_MISO];
ss_mapping [slave_address] <= s_ctrlport_req_data[SLAVE_CS_MSB:SLAVE_CS];
// Transfer Configuration
slave_spi_length [slave_address] <= s_ctrlport_req_data[SPI_LENGTH_MSB:SPI_LENGTH];
data_in_edge [slave_address] <= s_ctrlport_req_data[MISO_EDGE];
data_out_edge [slave_address] <= s_ctrlport_req_data[MOSI_EDGE];
end else begin
case (s_ctrlport_req_addr)
BASE_ADDRESS + SPI_TRANSACTION_CONFIG: begin
divider <= s_ctrlport_req_data[SPI_CLK_DIV_MSB:SPI_CLK_DIV];
cs <= s_ctrlport_req_data[SPI_SLAVE_SELECT_MSB:SPI_SLAVE_SELECT];
end
BASE_ADDRESS + SPI_TRANSACTION_GO: begin
spi_ready <= 1'b0;
spi_go <= 1'b1;
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 if(s_ctrlport_req_rd) begin
// default assumption: valid request
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_status <= CTRL_STS_OKAY;
s_ctrlport_resp_data <= {32{1'b0}};
case (s_ctrlport_req_addr)
BASE_ADDRESS + SPI_TRANSACTION_CONFIG: begin
s_ctrlport_resp_data[SPI_CLK_DIV_MSB:SPI_CLK_DIV] <= divider;
end
BASE_ADDRESS + SPI_STATUS: begin
s_ctrlport_resp_data[SPI_READY] <= spi_ready;
s_ctrlport_resp_data[SPI_RESPONSE_MSB:SPI_RESPONSE] <= readback[SPI_RESPONSE_MSB:SPI_RESPONSE];
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
if (readback_stb_extended) begin
spi_ready <= 1'b1;
end
end
end
//---------------------------------------------------------------------------
// SPI Control FSM
//---------------------------------------------------------------------------
always @ (posedge ctrlport_clk) begin
if (ctrlport_rst) begin
state <= IDLE;
set_stb <= 1'b0;
data_cache <= 32'h0;
end else begin
// Default Assignments
set_stb <= 1'b0;
case (state)
IDLE: begin
// Save data and address for further steps
data_cache <= s_ctrlport_req_data;
if (spi_go) begin
state <= CONFIG_TRANSFER;
slave_select <= {NUM_SLAVES{1'b0}};
slave_select[cs] <= 1'b1;
end
end
// Set slave select
CONFIG_TRANSFER: begin
state <= SET_DIVIDER;
set_stb <= 1'b1;
set_addr <= CTRL_ADDRESS;
set_data <= { data_out_edge[cs], // 1 bit
data_in_edge[cs], // 1 bit
slave_spi_length[cs], // 6 bits
{24-NUM_SLAVES{1'b0}}, // Padding for slaves
slave_select // NUM_SLAVES bits
};
end
// Write divider to SPI core
SET_DIVIDER: begin
state <= WRITE_SPI;
set_stb <= 1'b1;
set_addr <= DIVIDER_ADDRESS;
set_data <= {16'b0, divider};
end
// Write data bits to SPI core (aligned to MSB)
WRITE_SPI: begin
state <= WAIT_SPI;
set_stb <= 1'b1;
set_addr <= DATA_ADDRESS;
set_data <= data_cache;
end
// Wait for transaction to complete and translate to ctrlport response
WAIT_SPI: begin
if (readback_stb_extended) begin
state <= IDLE;
end
end
default: begin
state <= IDLE;
end
endcase
// Update Auxiliary signals
gpio_is_mosi <= 32'h0;
gpio_is_sclk <= 32'h0;
gpio_is_cs <= 32'h0;
for (slave_i=0; slave_i<NUM_SLAVES; slave_i=slave_i+1) begin
gpio_is_mosi [mosi_mapping[slave_i]] <= 1'b1;
gpio_is_sclk [sclk_mapping[slave_i]] <= 1'b1;
gpio_is_cs [ ss_mapping[slave_i]] <= 1'b1;
end
end
end
//---------------------------------------------------------------------------
// SPI master
//---------------------------------------------------------------------------
// Register set_stb for use in 2x domain.
reg set_stb_2x = 1'b0;
reg ctrlport_clk_phase = 1'b0;
always @ (posedge ctrlport_clk_2x) begin
// Assert strobe only during a single 2x cycle of the
// 1x pulse.
set_stb_2x <= ctrlport_clk_phase & set_stb;
ctrlport_clk_phase <= ~ctrlport_clk_phase;
end
simple_spi_core #(
.BASE (0),
.WIDTH (NUM_SLAVES),
.CLK_IDLE (0),
.SEN_IDLE ({NUM_SLAVES{1'b1}})
) simple_spi_core_i (
.clock (ctrlport_clk_2x),
.reset (ctrlport_rst),
.set_stb (set_stb_2x),
.set_addr (set_addr),
.set_data (set_data),
.readback (readback),
.readback_stb (readback_stb),
.ready (),
.sen (ss[NUM_SLAVES-1:0]),
.sclk (sclk),
.mosi (mosi),
.miso (miso),
.debug ()
);
// Delay and extend signal for use in 1x domain.
reg readback_stb_dly = 1'b0;
always @ (posedge ctrlport_clk_2x) begin
readback_stb_dly <= readback_stb;
end
assign readback_stb_extended = readback_stb_dly | readback_stb;
//---------------------------------------------------------------------------
// GPIO Mapping
//---------------------------------------------------------------------------
wire [31:0] mosi_mux_out;
reg [31:0] mosi_mux_out_dlyd;
wire [31:0] ss_mux_out;
wire [31:0] gated_sclk;
reg [31:0] gated_sclk_dlyd;
reg [31:0] gpio_is_sclk_dlyd;
genvar i;
generate
for (i = 0; i < 32; i = i + 1) begin: dio_output_gen
// Indicate which GPIO lines are outputs
assign gpio_ddr[i] = gpio_is_mosi[i] | gpio_is_sclk[i] | gpio_is_cs[i];
// CS re-mapping
assign ss_mux_out[i] = ( i == ss_mapping[0] ) ? ss[0] :
( i == ss_mapping[1] ) ? ss[1] :
( i == ss_mapping[2] ) ? ss[2] :
( i == ss_mapping[3] ) ? ss[3] :
1'b0;
assign mosi_mux_out[i] = gpio_is_mosi[i] ? mosi : ss_mux_out[i];
assign gated_sclk[i] = gpio_is_sclk[i] ? sclk : 1'b0;
// register signals once remapping logic is resolved
always @ (posedge ctrlport_clk_2x) begin
mosi_mux_out_dlyd[i] <= mosi_mux_out[i];
gpio_is_sclk_dlyd[i] <= gpio_is_sclk[i];
gated_sclk_dlyd[i] <= gated_sclk[i];
end
// Choose between SCLK and MOSI/SS mux.
glitch_free_mux glitch_free_gpio_out (
.select (gpio_is_sclk_dlyd[i]),
.signal0 (mosi_mux_out_dlyd[i]),
.signal1 (gated_sclk_dlyd[i]),
.muxed_signal (gpio_out[i])
);
end
endgenerate
assign miso = ( ~ss[0] ) ? gpio_in[miso_mapping[0]] :
( ~ss[1] ) ? gpio_in[miso_mapping[1]] :
( ~ss[2] ) ? gpio_in[miso_mapping[2]] :
( ~ss[3] ) ? gpio_in[miso_mapping[3]] :
1'b0;
endmodule
`default_nettype wire
//XmlParse xml_on
//<regmap name="DIG_IFC_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
// <group name="SPI_OVER_GPIO_REGS">
// <info>
// </info>
// <regtype name="SPI_SETUP" size="32">
// <info>
// Controls SPI Transaction
// </info>
// <bitfield name="SLAVE_CLK" range="0..4" initialvalue="0">
// <info>
// Indicates which GPIO line to use for the SCLK signal.</br>
// 0-11 : Port A GPIO</br>
// 16-27: Port B GPIO
// </info>
// </bitfield>
// <bitfield name="SLAVE_MOSI" range="5..9" initialvalue="0">
// <info>
// Indicates which GPIO line to use for the MOSI signal.</br>
// 0-11 : Port A GPIO</br>
// 16-27: Port B GPIO
// </info>
// </bitfield>
// <bitfield name="SLAVE_MISO" range="10..14" initialvalue="0">
// <info>
// Indicates which GPIO line to use for the MISO signal.</br>
// 0-11 : Port A GPIO</br>
// 16-27: Port B GPIO
// </info>
// </bitfield>
// <bitfield name="SLAVE_CS" range="15..19" initialvalue="0">
// <info>
// Indicates which GPIO line to use for the CS signal.</br>
// 0-11 : Port A GPIO</br>
// 16-27: Port B GPIO
// </info>
// </bitfield>
// <bitfield name="SPI_LENGTH" range="20..25" initialvalue="0">
// <info>
// Indicates the length of SPI transactions to this slave.
// </info>
// </bitfield>
// <bitfield name="MISO_EDGE" range="26" initialvalue="0">
// <info>
// Controls the edge in which the MISO line is latched.</br>
// 0 = falling edge of SCLK.</br>
// 1 = rising edge of SCLK.
// </info>
// </bitfield>
// <bitfield name="MOSI_EDGE" range="27" initialvalue="0">
// <info>
// Controls the edge in which the MOSI line is updated.</br>
// 0 = falling edge of SCLK.</br>
// 1 = rising edge of SCLK.
// </info>
// </bitfield>
// </regtype>
// <register name="SPI_SLAVE_CONFIG" typename="SPI_SETUP" offset="0x00" count="4" options="--step 4">
// <info> Set of configuration registers for the supported slaves. </info>
// </register>
// <register name="SPI_TRANSACTION_CONFIG" offset="0x10" size="32">
// <info>
// Controls clock rate and target for subsequent SPI transactions.
// </info>
// <bitfield name="SPI_CLK_DIV" range="0..15" initialvalue="0">
// <info> Controls the rate for subsequent SPI transactions. SCLK = DataClk/[(SPI_CLK_DIV+1)]</info>
// </bitfield>
// <bitfield name="SPI_SLAVE_SELECT" range="16..17" initialvalue="0"/>
// </register>
// <register name="SPI_TRANSACTION_GO" offset="0x14" size="32" readable="false">
// <info>
// Starts a SPI transaction
// </info>
// <bitfield name="SPI_DATA" range="0..31" initialvalue="0">
// <info> Payload to be sent for the SPI transaction. If the payload is shorter than 32 bits,
// it must be aligned to the MSbs in this field. LSbs are ignored in this scenario.</info>
// </bitfield>
// </register>
// <register name="SPI_STATUS" offset="0x18" size="32" writable="false">
// <info>
// Contains the status of the SPI engine.
// </info>
// <bitfield name="SPI_READY" range="24" initialvalue="0">
// <info> Indicates the SPI engine is ready to start a new SPI transaction. </info>
// </bitfield>
// <bitfield name="SPI_RESPONSE" range="0..23" initialvalue="0">
// <info> Records the response of the last completed SPI transaction. </info>
// </bitfield>
// </register>
// </group>
//</regmap>
//XmlParse xml_off