fpga: x4xx: Extend GPIO SPI support

Extend GPIO SPI transactions up to 64 bits and update the X4xx FPGA
register map and RTL to support the new access width.
Migrate the GPIO SPI register definitions to SystemVerilog.

Add testbench for X4xx GPIO SPI module covering both exisiting
32bit functionality and added 64bit functionality.
Separate TB Makefiles for X4xx and X410 implementation variant.

Bump the FPGA compatibility number so host and MPM software can reject
images that do not provide the required GPIO SPI register interface.
This commit is contained in:
Max Becker 2026-09-15 11:19:48 +02:00 committed by Frank Dietze
parent 772e682503
commit e6470cf8ce
15 changed files with 1524 additions and 330 deletions

View File

@ -62,7 +62,8 @@ x4xx_global_regs.v \
x4xx_versioning_regs.v \
x4xx_dio.v \
x4xx_gpio_atr.v \
x4xx_gpio_spi.v \
regmap/XmlSvPkgDIG_IFC_REGMAP.sv \
x4xx_gpio_spi.sv \
x4xx_dram.v \
ctrlport_spi_master.v \
cpld_interface.v \

View File

@ -1029,6 +1029,11 @@ p.offset_info, td.offset_info {
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|SPI_TRANSACTION_LSB">SPI_TRANSACTION_LSB</a>
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">SPI_TRANSACTION_GO</a>
</p>
@ -1039,6 +1044,11 @@ p.offset_info, td.offset_info {
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB">SPI_FULL_RESPONSE_MSB</a>
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|CONTROLLER_INFO">CONTROLLER_INFO</a>
</p>
@ -8329,9 +8339,9 @@ This port has a 40-bit address bus.</p></div>
</table>
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
<br />It uses RegType <strong>SPI_SETUP</strong> which is
defined in HDL source file x4xx_gpio_spi.v.
defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
@ -8351,7 +8361,7 @@ Set of configuration registers for the supported slaves.
<tr class="" valign="top">
<td class="bits">31..28</td>
<td class="bits">31..29</td>
<td>
<p><span class="name">Reserved</span><span class="attr">&nbsp;&nbsp;&nbsp;</span></p>
<p></p>
@ -8359,7 +8369,7 @@ Set of configuration registers for the supported slaves.
</tr>
<tr class="" valign="top">
<td class="bits">27</td>
<td class="bits">28</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;&nbsp;(initialvalue=0)</span></p>
<p>Controls the edge in which the MOSI line is updated.</br>
@ -8369,7 +8379,7 @@ Set of configuration registers for the supported slaves.
</tr>
<tr class="" valign="top">
<td class="bits">26</td>
<td class="bits">27</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;&nbsp;(initialvalue=0)</span></p>
<p>Controls the edge in which the MISO line is latched.</br>
@ -8379,10 +8389,13 @@ Set of configuration registers for the supported slaves.
</tr>
<tr class="" valign="top">
<td class="bits">25..20</td>
<td class="bits">26..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;&nbsp;(initialvalue=0)</span></p>
<p>Indicates the length of SPI transactions to this slave.</p>
<p>Indicates the length of SPI transactions to this slave.</br>
Valid transaction lengths are 1 through 64 bits. </br>
This is not checked on FPGA and other values will </br>
lead to undefined behavior.</p>
</td>
</tr>
@ -8505,7 +8518,7 @@ Set of configuration registers for the supported slaves.
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
@ -8554,11 +8567,112 @@ Set of configuration registers for the supported slaves.
<section class="register">
<a name="DIG_IFC_REGMAP|SPI_TRANSACTION_LSB"></a>
<h3 class="register">
Offset 0x0014: SPI_TRANSACTION_LSB
Register
(W)
<a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_LSB">&#x1F517;</a>
</h3>
<div class="sh">
<span class="opener sh-addrs">(<span class="sh-hidden">show</span><span class="sh-shown">hide</span> extended info)</span>
<div class="sh-content">
<table class="extended_info">
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X410_FPGA|RFNoC Radio 0">RFNoC Radio 0</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RFNOC_RADIO_REGMAP|PERIPH_WINDOW">RFNOC_RADIO_REGMAP|PERIPH_WINDOW</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x080000</td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<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="2">
<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="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">SPI_TRANSACTION_LSB</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>
<td class="offset_info">0x08E014</td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X410_FPGA|RFNoC Radio 1">RFNoC Radio 1</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E014</td>
</tr>
</table>
</td>
</tr>
</table>
<p class="reg_info">
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
For SPI transactions with <a href="#DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SPI_LENGTH">SPI_SLAVE_CONFIG.SPI_LENGTH</a> > 32, this must be written
before <a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">SPI_TRANSACTION_GO</a>.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
<tr class="header"><td class="bits">Bits</td><td>Name</td></tr>
<tr class="" valign="top">
<td class="bits">31..0w</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_TRANSACTION_LSB|SPI_DATA_LSB"></a>SPI_DATA_LSB</span><span class="attr">&nbsp;&nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Left-aligned LSB payload for SPI transaction with <a href="#DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SPI_LENGTH">SPI_SLAVE_CONFIG.SPI_LENGTH</a> > 32.<br/>
See <a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">SPI_TRANSACTION_GO</a> for more information.</p>
</td>
</tr>
</table>
</section>
<section class="register">
<a name="DIG_IFC_REGMAP|SPI_TRANSACTION_GO"></a>
<h3 class="register">
Offset 0x0014: SPI_TRANSACTION_GO
Offset 0x0018: SPI_TRANSACTION_GO
Register
(W)
<a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">&#x1F517;</a>
@ -8595,14 +8709,14 @@ Set of configuration registers for the supported slaves.
<td class="outercell" rowspan="2">
<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>
<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>
<td class="offset_info">0x08E014</td>
<td class="offset_info">0x08E018</td>
</tr>
</table>
</td>
@ -8617,7 +8731,7 @@ Set of configuration registers for the supported slaves.
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E014</td>
<td class="offset_info">0x08E018</td>
</tr>
</table>
</td>
@ -8628,12 +8742,13 @@ Set of configuration registers for the supported slaves.
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
Starts a SPI transaction
Starts a SPI transaction. Does not check whether a previous transaction is still ongoing.
If so, the running transaction may be corrupted.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
@ -8644,8 +8759,12 @@ Set of configuration registers for the supported slaves.
<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;&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>
<p>Payload to be sent for the SPI transaction.<br/>
If the payload is shorter than 32 bits, it must be left-aligned.
The first transmitted bit is the MSB and data is shifted out to the left.<br/>
If the desired payload is longer than 32 bits, the remaining LSBs
must be written to <a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_LSB|SPI_DATA_LSB">SPI_TRANSACTION_LSB.SPI_DATA_LSB</a> (left-aligned) before starting
the transaction.</p>
</td>
</tr>
</table>
@ -8658,7 +8777,7 @@ Set of configuration registers for the supported slaves.
<a name="DIG_IFC_REGMAP|SPI_STATUS"></a>
<h3 class="register">
Offset 0x0018: SPI_STATUS
Offset 0x001C: SPI_STATUS
Register
(R)
<a href="#DIG_IFC_REGMAP|SPI_STATUS">&#x1F517;</a>
@ -8695,14 +8814,14 @@ Set of configuration registers for the supported slaves.
<td class="outercell" rowspan="2">
<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>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x001C</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E018</td>
<td class="offset_info">0x08E01C</td>
</tr>
</table>
</td>
@ -8717,7 +8836,7 @@ Set of configuration registers for the supported slaves.
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E018</td>
<td class="offset_info">0x08E01C</td>
</tr>
</table>
</td>
@ -8728,12 +8847,13 @@ Set of configuration registers for the supported slaves.
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
Contains the status of the SPI engine.
Contains the status of the SPI engine and the least-significant 31 bits of the response.
Also read SPI_FULL_RESPONSE_MSB for bit 32 or for transactions longer than 32 bits.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
@ -8741,26 +8861,119 @@ Set of configuration registers for the supported slaves.
<tr class="" valign="top">
<td class="bits">31..25</td>
<td>
<p><span class="name">Reserved</span><span class="attr">&nbsp;&nbsp;&nbsp;</span></p>
<p></p>
</td>
</tr>
<tr class="" valign="top">
<td class="bits">24</td>
<td class="bits">31</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_STATUS|SPI_READY"></a>SPI_READY</span><span class="attr">&nbsp;&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>
<tr class="" valign="top">
<td class="bits">30..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;&nbsp;(initialvalue=0)</span></p>
<p>Records the response of the last completed SPI transaction.</p>
<p>Records only the least-significant 31 bits of the last completed SPI response.</p>
</td>
</tr>
</table>
</section>
<section class="register">
<a name="DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB"></a>
<h3 class="register">
Offset 0x0020: SPI_FULL_RESPONSE_MSB
Register
(R)
<a href="#DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB">&#x1F517;</a>
</h3>
<div class="sh">
<span class="opener sh-addrs">(<span class="sh-hidden">show</span><span class="sh-shown">hide</span> extended info)</span>
<div class="sh-content">
<table class="extended_info">
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X410_FPGA|RFNoC Radio 0">RFNoC Radio 0</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RFNOC_RADIO_REGMAP|PERIPH_WINDOW">RFNOC_RADIO_REGMAP|PERIPH_WINDOW</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x080000</td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<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="2">
<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="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">SPI_FULL_RESPONSE_MSB</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x0020</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E020</td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X410_FPGA|RFNoC Radio 1">RFNoC Radio 1</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E020</td>
</tr>
</table>
</td>
</tr>
</table>
<p class="reg_info">
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
Contains bits 62 through 31 of the last completed SPI response.
For transactions shorter than 31 bits, the upper bits in this register are undefined.
The regmap does not expose the most significant bit (bit 63) of the response.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
<tr class="header"><td class="bits">Bits</td><td>Name</td></tr>
<tr class="" valign="top">
<td class="bits">31..0</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB|SPI_FULL_RESPONSE_MSB_DATA"></a>SPI_FULL_RESPONSE_MSB_DATA</span><span class="attr">&nbsp;&nbsp;&nbsp;(initialvalue=0)</span></p>
<p></p>
</td>
</tr>
</table>
@ -8773,7 +8986,7 @@ Set of configuration registers for the supported slaves.
<a name="DIG_IFC_REGMAP|CONTROLLER_INFO"></a>
<h3 class="register">
Offset 0x001C: CONTROLLER_INFO
Offset 0x0024: CONTROLLER_INFO
Register
(R)
<a href="#DIG_IFC_REGMAP|CONTROLLER_INFO">&#x1F517;</a>
@ -8810,14 +9023,14 @@ Set of configuration registers for the supported slaves.
<td class="outercell" rowspan="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">CONTROLLER_INFO</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x001C</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x0024</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E01C</td>
<td class="offset_info">0x08E024</td>
</tr>
</table>
</td>
@ -8832,7 +9045,7 @@ Set of configuration registers for the supported slaves.
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E01C</td>
<td class="offset_info">0x08E024</td>
</tr>
</table>
</td>
@ -8843,7 +9056,7 @@ Set of configuration registers for the supported slaves.
Initial Value not specified
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
@ -32928,8 +33141,8 @@ used with 100Gb ethernet</p></div></p>
<tr valign="top">
<td class="value">11</td>
<td class="l">0x0000000B</td>
<td class="value">12</td>
<td class="l">0x0000000C</td>
<td class="l" style="text-align: left;">
<p class="name">
<a name="VERSIONING_REGS_REGMAP|FPGA_VERSION|FPGA_CURRENT_VERSION_MAJOR"></a>
@ -32941,8 +33154,8 @@ used with 100Gb ethernet</p></div></p>
<tr valign="top">
<td class="value">11</td>
<td class="l">0x0000000B</td>
<td class="value">12</td>
<td class="l">0x0000000C</td>
<td class="l" style="text-align: left;">
<p class="name">
<a name="VERSIONING_REGS_REGMAP|FPGA_VERSION|FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR"></a>
@ -32954,8 +33167,8 @@ used with 100Gb ethernet</p></div></p>
<tr valign="top">
<td class="value">637675285</td>
<td class="l">0x26022715</td>
<td class="value">638124305</td>
<td class="l">0x26090111</td>
<td class="l" style="text-align: left;">
<p class="name">
<a name="VERSIONING_REGS_REGMAP|FPGA_VERSION|FPGA_VERSION_LAST_MODIFIED_TIME"></a>

View File

@ -1175,6 +1175,11 @@ p.offset_info, td.offset_info {
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|SPI_TRANSACTION_LSB">SPI_TRANSACTION_LSB</a>
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">SPI_TRANSACTION_GO</a>
</p>
@ -1185,6 +1190,11 @@ p.offset_info, td.offset_info {
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB">SPI_FULL_RESPONSE_MSB</a>
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|CONTROLLER_INFO">CONTROLLER_INFO</a>
</p>
@ -11389,9 +11399,9 @@ This port has a 40-bit address bus.</p></div>
</table>
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
<br />It uses RegType <strong>SPI_SETUP</strong> which is
defined in HDL source file x4xx_gpio_spi.v.
defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
@ -11411,7 +11421,7 @@ Set of configuration registers for the supported slaves.
<tr class="" valign="top">
<td class="bits">31..28</td>
<td class="bits">31..29</td>
<td>
<p><span class="name">Reserved</span><span class="attr">&nbsp;&nbsp;&nbsp;</span></p>
<p></p>
@ -11419,7 +11429,7 @@ Set of configuration registers for the supported slaves.
</tr>
<tr class="" valign="top">
<td class="bits">27</td>
<td class="bits">28</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;&nbsp;(initialvalue=0)</span></p>
<p>Controls the edge in which the MOSI line is updated.</br>
@ -11429,7 +11439,7 @@ Set of configuration registers for the supported slaves.
</tr>
<tr class="" valign="top">
<td class="bits">26</td>
<td class="bits">27</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;&nbsp;(initialvalue=0)</span></p>
<p>Controls the edge in which the MISO line is latched.</br>
@ -11439,10 +11449,13 @@ Set of configuration registers for the supported slaves.
</tr>
<tr class="" valign="top">
<td class="bits">25..20</td>
<td class="bits">26..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;&nbsp;(initialvalue=0)</span></p>
<p>Indicates the length of SPI transactions to this slave.</p>
<p>Indicates the length of SPI transactions to this slave.</br>
Valid transaction lengths are 1 through 64 bits. </br>
This is not checked on FPGA and other values will </br>
lead to undefined behavior.</p>
</td>
</tr>
@ -11565,7 +11578,7 @@ Set of configuration registers for the supported slaves.
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
@ -11614,11 +11627,112 @@ Set of configuration registers for the supported slaves.
<section class="register">
<a name="DIG_IFC_REGMAP|SPI_TRANSACTION_LSB"></a>
<h3 class="register">
Offset 0x0014: SPI_TRANSACTION_LSB
Register
(W)
<a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_LSB">&#x1F517;</a>
</h3>
<div class="sh">
<span class="opener sh-addrs">(<span class="sh-hidden">show</span><span class="sh-shown">hide</span> extended info)</span>
<div class="sh-content">
<table class="extended_info">
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X420_FPGA|RFNoC Radio 0">RFNoC Radio 0</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RFNOC_RADIO_REGMAP|PERIPH_WINDOW">RFNOC_RADIO_REGMAP|PERIPH_WINDOW</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x080000</td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<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="2">
<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="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">SPI_TRANSACTION_LSB</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>
<td class="offset_info">0x08E014</td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X420_FPGA|RFNoC Radio 1">RFNoC Radio 1</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E014</td>
</tr>
</table>
</td>
</tr>
</table>
<p class="reg_info">
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
For SPI transactions with <a href="#DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SPI_LENGTH">SPI_SLAVE_CONFIG.SPI_LENGTH</a> > 32, this must be written
before <a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">SPI_TRANSACTION_GO</a>.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
<tr class="header"><td class="bits">Bits</td><td>Name</td></tr>
<tr class="" valign="top">
<td class="bits">31..0w</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_TRANSACTION_LSB|SPI_DATA_LSB"></a>SPI_DATA_LSB</span><span class="attr">&nbsp;&nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Left-aligned LSB payload for SPI transaction with <a href="#DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SPI_LENGTH">SPI_SLAVE_CONFIG.SPI_LENGTH</a> > 32.<br/>
See <a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">SPI_TRANSACTION_GO</a> for more information.</p>
</td>
</tr>
</table>
</section>
<section class="register">
<a name="DIG_IFC_REGMAP|SPI_TRANSACTION_GO"></a>
<h3 class="register">
Offset 0x0014: SPI_TRANSACTION_GO
Offset 0x0018: SPI_TRANSACTION_GO
Register
(W)
<a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">&#x1F517;</a>
@ -11655,14 +11769,14 @@ Set of configuration registers for the supported slaves.
<td class="outercell" rowspan="2">
<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>
<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>
<td class="offset_info">0x08E014</td>
<td class="offset_info">0x08E018</td>
</tr>
</table>
</td>
@ -11677,7 +11791,7 @@ Set of configuration registers for the supported slaves.
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E014</td>
<td class="offset_info">0x08E018</td>
</tr>
</table>
</td>
@ -11688,12 +11802,13 @@ Set of configuration registers for the supported slaves.
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
Starts a SPI transaction
Starts a SPI transaction. Does not check whether a previous transaction is still ongoing.
If so, the running transaction may be corrupted.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
@ -11704,8 +11819,12 @@ Set of configuration registers for the supported slaves.
<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;&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>
<p>Payload to be sent for the SPI transaction.<br/>
If the payload is shorter than 32 bits, it must be left-aligned.
The first transmitted bit is the MSB and data is shifted out to the left.<br/>
If the desired payload is longer than 32 bits, the remaining LSBs
must be written to <a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_LSB|SPI_DATA_LSB">SPI_TRANSACTION_LSB.SPI_DATA_LSB</a> (left-aligned) before starting
the transaction.</p>
</td>
</tr>
</table>
@ -11718,7 +11837,7 @@ Set of configuration registers for the supported slaves.
<a name="DIG_IFC_REGMAP|SPI_STATUS"></a>
<h3 class="register">
Offset 0x0018: SPI_STATUS
Offset 0x001C: SPI_STATUS
Register
(R)
<a href="#DIG_IFC_REGMAP|SPI_STATUS">&#x1F517;</a>
@ -11755,14 +11874,14 @@ Set of configuration registers for the supported slaves.
<td class="outercell" rowspan="2">
<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>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x001C</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E018</td>
<td class="offset_info">0x08E01C</td>
</tr>
</table>
</td>
@ -11777,7 +11896,7 @@ Set of configuration registers for the supported slaves.
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E018</td>
<td class="offset_info">0x08E01C</td>
</tr>
</table>
</td>
@ -11788,12 +11907,13 @@ Set of configuration registers for the supported slaves.
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
Contains the status of the SPI engine.
Contains the status of the SPI engine and the least-significant 31 bits of the response.
Also read SPI_FULL_RESPONSE_MSB for bit 32 or for transactions longer than 32 bits.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
@ -11801,26 +11921,119 @@ Set of configuration registers for the supported slaves.
<tr class="" valign="top">
<td class="bits">31..25</td>
<td>
<p><span class="name">Reserved</span><span class="attr">&nbsp;&nbsp;&nbsp;</span></p>
<p></p>
</td>
</tr>
<tr class="" valign="top">
<td class="bits">24</td>
<td class="bits">31</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_STATUS|SPI_READY"></a>SPI_READY</span><span class="attr">&nbsp;&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>
<tr class="" valign="top">
<td class="bits">30..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;&nbsp;(initialvalue=0)</span></p>
<p>Records the response of the last completed SPI transaction.</p>
<p>Records only the least-significant 31 bits of the last completed SPI response.</p>
</td>
</tr>
</table>
</section>
<section class="register">
<a name="DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB"></a>
<h3 class="register">
Offset 0x0020: SPI_FULL_RESPONSE_MSB
Register
(R)
<a href="#DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB">&#x1F517;</a>
</h3>
<div class="sh">
<span class="opener sh-addrs">(<span class="sh-hidden">show</span><span class="sh-shown">hide</span> extended info)</span>
<div class="sh-content">
<table class="extended_info">
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X420_FPGA|RFNoC Radio 0">RFNoC Radio 0</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RFNOC_RADIO_REGMAP|PERIPH_WINDOW">RFNOC_RADIO_REGMAP|PERIPH_WINDOW</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x080000</td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<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="2">
<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="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">SPI_FULL_RESPONSE_MSB</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x0020</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E020</td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X420_FPGA|RFNoC Radio 1">RFNoC Radio 1</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E020</td>
</tr>
</table>
</td>
</tr>
</table>
<p class="reg_info">
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
Contains bits 62 through 31 of the last completed SPI response.
For transactions shorter than 31 bits, the upper bits in this register are undefined.
The regmap does not expose the most significant bit (bit 63) of the response.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
<tr class="header"><td class="bits">Bits</td><td>Name</td></tr>
<tr class="" valign="top">
<td class="bits">31..0</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB|SPI_FULL_RESPONSE_MSB_DATA"></a>SPI_FULL_RESPONSE_MSB_DATA</span><span class="attr">&nbsp;&nbsp;&nbsp;(initialvalue=0)</span></p>
<p></p>
</td>
</tr>
</table>
@ -11833,7 +12046,7 @@ Set of configuration registers for the supported slaves.
<a name="DIG_IFC_REGMAP|CONTROLLER_INFO"></a>
<h3 class="register">
Offset 0x001C: CONTROLLER_INFO
Offset 0x0024: CONTROLLER_INFO
Register
(R)
<a href="#DIG_IFC_REGMAP|CONTROLLER_INFO">&#x1F517;</a>
@ -11870,14 +12083,14 @@ Set of configuration registers for the supported slaves.
<td class="outercell" rowspan="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">CONTROLLER_INFO</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x001C</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x0024</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E01C</td>
<td class="offset_info">0x08E024</td>
</tr>
</table>
</td>
@ -11892,7 +12105,7 @@ Set of configuration registers for the supported slaves.
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E01C</td>
<td class="offset_info">0x08E024</td>
</tr>
</table>
</td>
@ -11903,7 +12116,7 @@ Set of configuration registers for the supported slaves.
Initial Value not specified
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
@ -37693,8 +37906,8 @@ used with 100Gb ethernet</p></div></p>
<tr valign="top">
<td class="value">11</td>
<td class="l">0x0000000B</td>
<td class="value">12</td>
<td class="l">0x0000000C</td>
<td class="l" style="text-align: left;">
<p class="name">
<a name="VERSIONING_REGS_REGMAP|FPGA_VERSION|FPGA_CURRENT_VERSION_MAJOR"></a>
@ -37706,8 +37919,8 @@ used with 100Gb ethernet</p></div></p>
<tr valign="top">
<td class="value">11</td>
<td class="l">0x0000000B</td>
<td class="value">12</td>
<td class="l">0x0000000C</td>
<td class="l" style="text-align: left;">
<p class="name">
<a name="VERSIONING_REGS_REGMAP|FPGA_VERSION|FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR"></a>
@ -37719,8 +37932,8 @@ used with 100Gb ethernet</p></div></p>
<tr valign="top">
<td class="value">637675285</td>
<td class="l">0x26022715</td>
<td class="value">638124305</td>
<td class="l">0x26090111</td>
<td class="l" style="text-align: left;">
<p class="name">
<a name="VERSIONING_REGS_REGMAP|FPGA_VERSION|FPGA_VERSION_LAST_MODIFIED_TIME"></a>

View File

@ -895,6 +895,11 @@ p.offset_info, td.offset_info {
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|SPI_TRANSACTION_LSB">SPI_TRANSACTION_LSB</a>
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">SPI_TRANSACTION_GO</a>
</p>
@ -905,6 +910,11 @@ p.offset_info, td.offset_info {
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB">SPI_FULL_RESPONSE_MSB</a>
</p>
<p>
<a class="register" href="#DIG_IFC_REGMAP|CONTROLLER_INFO">CONTROLLER_INFO</a>
</p>
@ -5345,9 +5355,9 @@ This port has a 40-bit address bus.</p></div>
</table>
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
<br />It uses RegType <strong>SPI_SETUP</strong> which is
defined in HDL source file x4xx_gpio_spi.v.
defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
@ -5367,7 +5377,7 @@ Set of configuration registers for the supported slaves.
<tr class="" valign="top">
<td class="bits">31..28</td>
<td class="bits">31..29</td>
<td>
<p><span class="name">Reserved</span><span class="attr">&nbsp;&nbsp;&nbsp;</span></p>
<p></p>
@ -5375,7 +5385,7 @@ Set of configuration registers for the supported slaves.
</tr>
<tr class="" valign="top">
<td class="bits">27</td>
<td class="bits">28</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;&nbsp;(initialvalue=0)</span></p>
<p>Controls the edge in which the MOSI line is updated.</br>
@ -5385,7 +5395,7 @@ Set of configuration registers for the supported slaves.
</tr>
<tr class="" valign="top">
<td class="bits">26</td>
<td class="bits">27</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;&nbsp;(initialvalue=0)</span></p>
<p>Controls the edge in which the MISO line is latched.</br>
@ -5395,10 +5405,13 @@ Set of configuration registers for the supported slaves.
</tr>
<tr class="" valign="top">
<td class="bits">25..20</td>
<td class="bits">26..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;&nbsp;(initialvalue=0)</span></p>
<p>Indicates the length of SPI transactions to this slave.</p>
<p>Indicates the length of SPI transactions to this slave.</br>
Valid transaction lengths are 1 through 64 bits. </br>
This is not checked on FPGA and other values will </br>
lead to undefined behavior.</p>
</td>
</tr>
@ -5521,7 +5534,7 @@ Set of configuration registers for the supported slaves.
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
@ -5570,11 +5583,112 @@ Set of configuration registers for the supported slaves.
<section class="register">
<a name="DIG_IFC_REGMAP|SPI_TRANSACTION_LSB"></a>
<h3 class="register">
Offset 0x0014: SPI_TRANSACTION_LSB
Register
(W)
<a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_LSB">&#x1F517;</a>
</h3>
<div class="sh">
<span class="opener sh-addrs">(<span class="sh-hidden">show</span><span class="sh-shown">hide</span> extended info)</span>
<div class="sh-content">
<table class="extended_info">
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X440_FPGA|RFNoC Radio 0">RFNoC Radio 0</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RFNOC_RADIO_REGMAP|PERIPH_WINDOW">RFNOC_RADIO_REGMAP|PERIPH_WINDOW</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x080000</td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<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="2">
<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="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">SPI_TRANSACTION_LSB</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>
<td class="offset_info">0x08E014</td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X440_FPGA|RFNoC Radio 1">RFNoC Radio 1</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E014</td>
</tr>
</table>
</td>
</tr>
</table>
<p class="reg_info">
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
For SPI transactions with <a href="#DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SPI_LENGTH">SPI_SLAVE_CONFIG.SPI_LENGTH</a> > 32, this must be written
before <a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">SPI_TRANSACTION_GO</a>.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
<tr class="header"><td class="bits">Bits</td><td>Name</td></tr>
<tr class="" valign="top">
<td class="bits">31..0w</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_TRANSACTION_LSB|SPI_DATA_LSB"></a>SPI_DATA_LSB</span><span class="attr">&nbsp;&nbsp;&nbsp;(initialvalue=0)</span></p>
<p>Left-aligned LSB payload for SPI transaction with <a href="#DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SPI_LENGTH">SPI_SLAVE_CONFIG.SPI_LENGTH</a> > 32.<br/>
See <a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">SPI_TRANSACTION_GO</a> for more information.</p>
</td>
</tr>
</table>
</section>
<section class="register">
<a name="DIG_IFC_REGMAP|SPI_TRANSACTION_GO"></a>
<h3 class="register">
Offset 0x0014: SPI_TRANSACTION_GO
Offset 0x0018: SPI_TRANSACTION_GO
Register
(W)
<a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_GO">&#x1F517;</a>
@ -5611,14 +5725,14 @@ Set of configuration registers for the supported slaves.
<td class="outercell" rowspan="2">
<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>
<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>
<td class="offset_info">0x08E014</td>
<td class="offset_info">0x08E018</td>
</tr>
</table>
</td>
@ -5633,7 +5747,7 @@ Set of configuration registers for the supported slaves.
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E014</td>
<td class="offset_info">0x08E018</td>
</tr>
</table>
</td>
@ -5644,12 +5758,13 @@ Set of configuration registers for the supported slaves.
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
Starts a SPI transaction
Starts a SPI transaction. Does not check whether a previous transaction is still ongoing.
If so, the running transaction may be corrupted.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
@ -5660,8 +5775,12 @@ Set of configuration registers for the supported slaves.
<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;&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>
<p>Payload to be sent for the SPI transaction.<br/>
If the payload is shorter than 32 bits, it must be left-aligned.
The first transmitted bit is the MSB and data is shifted out to the left.<br/>
If the desired payload is longer than 32 bits, the remaining LSBs
must be written to <a href="#DIG_IFC_REGMAP|SPI_TRANSACTION_LSB|SPI_DATA_LSB">SPI_TRANSACTION_LSB.SPI_DATA_LSB</a> (left-aligned) before starting
the transaction.</p>
</td>
</tr>
</table>
@ -5674,7 +5793,7 @@ Set of configuration registers for the supported slaves.
<a name="DIG_IFC_REGMAP|SPI_STATUS"></a>
<h3 class="register">
Offset 0x0018: SPI_STATUS
Offset 0x001C: SPI_STATUS
Register
(R)
<a href="#DIG_IFC_REGMAP|SPI_STATUS">&#x1F517;</a>
@ -5711,14 +5830,14 @@ Set of configuration registers for the supported slaves.
<td class="outercell" rowspan="2">
<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>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x001C</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E018</td>
<td class="offset_info">0x08E01C</td>
</tr>
</table>
</td>
@ -5733,7 +5852,7 @@ Set of configuration registers for the supported slaves.
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E018</td>
<td class="offset_info">0x08E01C</td>
</tr>
</table>
</td>
@ -5744,12 +5863,13 @@ Set of configuration registers for the supported slaves.
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
Contains the status of the SPI engine.
Contains the status of the SPI engine and the least-significant 31 bits of the response.
Also read SPI_FULL_RESPONSE_MSB for bit 32 or for transactions longer than 32 bits.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
@ -5757,26 +5877,119 @@ Set of configuration registers for the supported slaves.
<tr class="" valign="top">
<td class="bits">31..25</td>
<td>
<p><span class="name">Reserved</span><span class="attr">&nbsp;&nbsp;&nbsp;</span></p>
<p></p>
</td>
</tr>
<tr class="" valign="top">
<td class="bits">24</td>
<td class="bits">31</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_STATUS|SPI_READY"></a>SPI_READY</span><span class="attr">&nbsp;&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>
<tr class="" valign="top">
<td class="bits">30..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;&nbsp;(initialvalue=0)</span></p>
<p>Records the response of the last completed SPI transaction.</p>
<p>Records only the least-significant 31 bits of the last completed SPI response.</p>
</td>
</tr>
</table>
</section>
<section class="register">
<a name="DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB"></a>
<h3 class="register">
Offset 0x0020: SPI_FULL_RESPONSE_MSB
Register
(R)
<a href="#DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB">&#x1F517;</a>
</h3>
<div class="sh">
<span class="opener sh-addrs">(<span class="sh-hidden">show</span><span class="sh-shown">hide</span> extended info)</span>
<div class="sh-content">
<table class="extended_info">
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X440_FPGA|RFNoC Radio 0">RFNoC Radio 0</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right"><a href="#RFNOC_RADIO_REGMAP|PERIPH_WINDOW">RFNOC_RADIO_REGMAP|PERIPH_WINDOW</a></td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;0x080000</td></tr>
</table>
</td>
<td class="outercell" rowspan="2">
<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="2">
<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="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">SPI_FULL_RESPONSE_MSB</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x0020</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E020</td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">Port <a href="#X440_FPGA|RFNoC Radio 1">RFNoC Radio 1</a></td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E020</td>
</tr>
</table>
</td>
</tr>
</table>
<p class="reg_info">
Initial Value = 0x00000000
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
<div class="info">
Contains bits 62 through 31 of the last completed SPI response.
For transactions shorter than 31 bits, the upper bits in this register are undefined.
The regmap does not expose the most significant bit (bit 63) of the response.
</div>
<table class="bitfields" border="0" cellspacing="0" cellpadding="0">
<tr class="header"><td class="bits">Bits</td><td>Name</td></tr>
<tr class="" valign="top">
<td class="bits">31..0</td>
<td>
<p><span class="name"><a name="DIG_IFC_REGMAP|SPI_FULL_RESPONSE_MSB|SPI_FULL_RESPONSE_MSB_DATA"></a>SPI_FULL_RESPONSE_MSB_DATA</span><span class="attr">&nbsp;&nbsp;&nbsp;(initialvalue=0)</span></p>
<p></p>
</td>
</tr>
</table>
@ -5789,7 +6002,7 @@ Set of configuration registers for the supported slaves.
<a name="DIG_IFC_REGMAP|CONTROLLER_INFO"></a>
<h3 class="register">
Offset 0x001C: CONTROLLER_INFO
Offset 0x0024: CONTROLLER_INFO
Register
(R)
<a href="#DIG_IFC_REGMAP|CONTROLLER_INFO">&#x1F517;</a>
@ -5826,14 +6039,14 @@ Set of configuration registers for the supported slaves.
<td class="outercell" rowspan="2">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td class="offset_info" align="right">CONTROLLER_INFO</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x001C</td></tr>
<tr><td class="offset_info" align="right">&nbsp;&nbsp;offset=0x0024</td></tr>
</table>
</td>
<td class="outercell" rowspan="1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E01C</td>
<td class="offset_info">0x08E024</td>
</tr>
</table>
</td>
@ -5848,7 +6061,7 @@ Set of configuration registers for the supported slaves.
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="offset_info">Total Offset =</td>
<td class="offset_info">0x08E01C</td>
<td class="offset_info">0x08E024</td>
</tr>
</table>
</td>
@ -5859,7 +6072,7 @@ Set of configuration registers for the supported slaves.
Initial Value not specified
</p>
<p class="reg_info">
This register is defined in HDL source file x4xx_gpio_spi.v.
This register is defined in HDL source file x4xx_gpio_spi.sv.
</p>
</div>
</div>
@ -27548,8 +27761,8 @@ used with 100Gb ethernet</p></div></p>
<tr valign="top">
<td class="value">11</td>
<td class="l">0x0000000B</td>
<td class="value">12</td>
<td class="l">0x0000000C</td>
<td class="l" style="text-align: left;">
<p class="name">
<a name="VERSIONING_REGS_REGMAP|FPGA_VERSION|FPGA_CURRENT_VERSION_MAJOR"></a>
@ -27561,8 +27774,8 @@ used with 100Gb ethernet</p></div></p>
<tr valign="top">
<td class="value">11</td>
<td class="l">0x0000000B</td>
<td class="value">12</td>
<td class="l">0x0000000C</td>
<td class="l" style="text-align: left;">
<p class="name">
<a name="VERSIONING_REGS_REGMAP|FPGA_VERSION|FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR"></a>
@ -27574,8 +27787,8 @@ used with 100Gb ethernet</p></div></p>
<tr valign="top">
<td class="value">637675285</td>
<td class="l">0x26022715</td>
<td class="value">638124305</td>
<td class="l">0x26090111</td>
<td class="l" style="text-align: left;">
<p class="name">
<a name="VERSIONING_REGS_REGMAP|FPGA_VERSION|FPGA_VERSION_LAST_MODIFIED_TIME"></a>

View File

@ -0,0 +1,163 @@
//-----------------------------------------------------------------------------
// File: XmlSvPkgDIG_IFC_REGMAP.sv
// Author: Autogenerated by XmlParse
// Original Project: --
// Date: --
//-----------------------------------------------------------------------------
// (c) 2026 National Instruments Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
// Purpose:
// The constants in this file are autogenerated by XmlParse.
//-----------------------------------------------------------------------------
package XmlSvPkgDIG_IFC_REGMAP;
//===============================================================================
// A numerically ordered list of registers and their HDL source files
//===============================================================================
// SPI_SLAVE_CONFIG : 0x0 (x4xx_gpio_spi.sv)
// SPI_TRANSACTION_CONFIG : 0x10 (x4xx_gpio_spi.sv)
// SPI_TRANSACTION_LSB : 0x14 (x4xx_gpio_spi.sv)
// SPI_TRANSACTION_GO : 0x18 (x4xx_gpio_spi.sv)
// SPI_STATUS : 0x1C (x4xx_gpio_spi.sv)
// SPI_FULL_RESPONSE_MSB : 0x20 (x4xx_gpio_spi.sv)
// CONTROLLER_INFO : 0x24 (x4xx_gpio_spi.sv)
//===============================================================================
// Register Group SPI_OVER_GPIO_REGS
//===============================================================================
// SPI_SLAVE_CONFIG Register (from x4xx_gpio_spi.sv)
localparam kSPI_SLAVE_CONFIGCount = 4; // Number of elements in array
// SPI_TRANSACTION_CONFIG Register (from x4xx_gpio_spi.sv)
localparam kSPI_TRANSACTION_CONFIG = 'h10; // Register Offset
localparam kSPI_TRANSACTION_CONFIGSize = 32; // register width in bits
localparam kSPI_TRANSACTION_CONFIGMask = 32'h3FFFF;
localparam kSPI_CLK_DIVSize = 16; //SPI_TRANSACTION_CONFIG:SPI_CLK_DIV
localparam kSPI_CLK_DIVMsb = 15; //SPI_TRANSACTION_CONFIG:SPI_CLK_DIV
localparam kSPI_CLK_DIV = 0; //SPI_TRANSACTION_CONFIG:SPI_CLK_DIV
localparam kSPI_SLAVE_SELECTSize = 2; //SPI_TRANSACTION_CONFIG:SPI_SLAVE_SELECT
localparam kSPI_SLAVE_SELECTMsb = 17; //SPI_TRANSACTION_CONFIG:SPI_SLAVE_SELECT
localparam kSPI_SLAVE_SELECT = 16; //SPI_TRANSACTION_CONFIG:SPI_SLAVE_SELECT
typedef struct packed {
logic [13:0] Rsvd31_18; // [31:18] 14 bit spacer
logic [1:0] SPI_SLAVE_SELECT; // [17:16] 2 bit bitfield
logic [15:0] SPI_CLK_DIV; // [15: 0] 16 bit bitfield
} SPI_TRANSACTION_CONFIG;
// SPI_TRANSACTION_LSB Register (from x4xx_gpio_spi.sv)
localparam kSPI_TRANSACTION_LSB = 'h14; // Register Offset
localparam kSPI_TRANSACTION_LSBSize = 32; // register width in bits
localparam kSPI_TRANSACTION_LSBMask = 32'hFFFFFFFF;
localparam kSPI_DATA_LSBSize = 32; //SPI_TRANSACTION_LSB:SPI_DATA_LSB
localparam kSPI_DATA_LSBMsb = 31; //SPI_TRANSACTION_LSB:SPI_DATA_LSB
localparam kSPI_DATA_LSB = 0; //SPI_TRANSACTION_LSB:SPI_DATA_LSB
typedef struct packed {
logic [31:0] SPI_DATA_LSB; // [31: 0] 32 bit bitfield
} SPI_TRANSACTION_LSB;
// SPI_TRANSACTION_GO Register (from x4xx_gpio_spi.sv)
localparam kSPI_TRANSACTION_GO = 'h18; // Register Offset
localparam kSPI_TRANSACTION_GOSize = 32; // register width in bits
localparam kSPI_TRANSACTION_GOMask = 32'hFFFFFFFF;
localparam kSPI_DATASize = 32; //SPI_TRANSACTION_GO:SPI_DATA
localparam kSPI_DATAMsb = 31; //SPI_TRANSACTION_GO:SPI_DATA
localparam kSPI_DATA = 0; //SPI_TRANSACTION_GO:SPI_DATA
typedef struct packed {
logic [31:0] SPI_DATA; // [31: 0] 32 bit bitfield
} SPI_TRANSACTION_GO;
// SPI_STATUS Register (from x4xx_gpio_spi.sv)
localparam kSPI_STATUS = 'h1C; // Register Offset
localparam kSPI_STATUSSize = 32; // register width in bits
localparam kSPI_STATUSMask = 32'hFFFFFFFF;
localparam kSPI_RESPONSESize = 31; //SPI_STATUS:SPI_RESPONSE
localparam kSPI_RESPONSEMsb = 30; //SPI_STATUS:SPI_RESPONSE
localparam kSPI_RESPONSE = 0; //SPI_STATUS:SPI_RESPONSE
localparam kSPI_READYSize = 1; //SPI_STATUS:SPI_READY
localparam kSPI_READYMsb = 31; //SPI_STATUS:SPI_READY
localparam kSPI_READY = 31; //SPI_STATUS:SPI_READY
typedef struct packed {
logic SPI_READY; // [31:31] 1 bit bitfield
logic [30:0] SPI_RESPONSE; // [30: 0] 31 bit bitfield
} SPI_STATUS;
// SPI_FULL_RESPONSE_MSB Register (from x4xx_gpio_spi.sv)
localparam kSPI_FULL_RESPONSE_MSB = 'h20; // Register Offset
localparam kSPI_FULL_RESPONSE_MSBSize = 32; // register width in bits
localparam kSPI_FULL_RESPONSE_MSBMask = 32'hFFFFFFFF;
localparam kSPI_FULL_RESPONSE_MSB_DATASize = 32; //SPI_FULL_RESPONSE_MSB:SPI_FULL_RESPONSE_MSB_DATA
localparam kSPI_FULL_RESPONSE_MSB_DATAMsb = 31; //SPI_FULL_RESPONSE_MSB:SPI_FULL_RESPONSE_MSB_DATA
localparam kSPI_FULL_RESPONSE_MSB_DATA = 0; //SPI_FULL_RESPONSE_MSB:SPI_FULL_RESPONSE_MSB_DATA
typedef struct packed {
logic [31:0] SPI_FULL_RESPONSE_MSB_DATA; // [31: 0] 32 bit bitfield
} SPI_FULL_RESPONSE_MSB;
// CONTROLLER_INFO Register (from x4xx_gpio_spi.sv)
localparam kCONTROLLER_INFO = 'h24; // Register Offset
localparam kCONTROLLER_INFOSize = 32; // register width in bits
localparam kCONTROLLER_INFOMask = 32'hF;
localparam kSLAVE_COUNTSize = 4; //CONTROLLER_INFO:SLAVE_COUNT
localparam kSLAVE_COUNTMsb = 3; //CONTROLLER_INFO:SLAVE_COUNT
localparam kSLAVE_COUNT = 0; //CONTROLLER_INFO:SLAVE_COUNT
typedef struct packed {
logic [27:0] Rsvd31_4; // [31: 4] 28 bit spacer
logic [3:0] SLAVE_COUNT; // [ 3: 0] 4 bit bitfield
} CONTROLLER_INFO;
//===============================================================================
// RegTypes
//===============================================================================
// SPI_SETUP Type (from x4xx_gpio_spi.sv)
localparam kSPI_SETUPSize = 32;
localparam kSPI_SETUPMask = 32'h1FFFFFFF;
localparam kSLAVE_CLKSize = 5; //SPI_SETUP:SLAVE_CLK
localparam kSLAVE_CLKMsb = 4; //SPI_SETUP:SLAVE_CLK
localparam kSLAVE_CLK = 0; //SPI_SETUP:SLAVE_CLK
localparam kSLAVE_MOSISize = 5; //SPI_SETUP:SLAVE_MOSI
localparam kSLAVE_MOSIMsb = 9; //SPI_SETUP:SLAVE_MOSI
localparam kSLAVE_MOSI = 5; //SPI_SETUP:SLAVE_MOSI
localparam kSLAVE_MISOSize = 5; //SPI_SETUP:SLAVE_MISO
localparam kSLAVE_MISOMsb = 14; //SPI_SETUP:SLAVE_MISO
localparam kSLAVE_MISO = 10; //SPI_SETUP:SLAVE_MISO
localparam kSLAVE_CSSize = 5; //SPI_SETUP:SLAVE_CS
localparam kSLAVE_CSMsb = 19; //SPI_SETUP:SLAVE_CS
localparam kSLAVE_CS = 15; //SPI_SETUP:SLAVE_CS
localparam kSPI_LENGTHSize = 7; //SPI_SETUP:SPI_LENGTH
localparam kSPI_LENGTHMsb = 26; //SPI_SETUP:SPI_LENGTH
localparam kSPI_LENGTH = 20; //SPI_SETUP:SPI_LENGTH
localparam kMISO_EDGESize = 1; //SPI_SETUP:MISO_EDGE
localparam kMISO_EDGEMsb = 27; //SPI_SETUP:MISO_EDGE
localparam kMISO_EDGE = 27; //SPI_SETUP:MISO_EDGE
localparam kMOSI_EDGESize = 1; //SPI_SETUP:MOSI_EDGE
localparam kMOSI_EDGEMsb = 28; //SPI_SETUP:MOSI_EDGE
localparam kMOSI_EDGE = 28; //SPI_SETUP:MOSI_EDGE
typedef struct packed {
logic [2:0] Rsvd31_29; // [31:29] 3 bit spacer
logic MOSI_EDGE; // [28:28] 1 bit bitfield
logic MISO_EDGE; // [27:27] 1 bit bitfield
logic [6:0] SPI_LENGTH; // [26:20] 7 bit bitfield
logic [4:0] SLAVE_CS; // [19:15] 5 bit bitfield
logic [4:0] SLAVE_MISO; // [14:10] 5 bit bitfield
logic [4:0] SLAVE_MOSI; // [ 9: 5] 5 bit bitfield
logic [4:0] SLAVE_CLK; // [ 4: 0] 5 bit bitfield
} SPI_SETUP;
// Return the offset of an element of register array kSPI_SLAVE_CONFIG
function automatic integer kSPI_SLAVE_CONFIG (input integer i);
begin
kSPI_SLAVE_CONFIG = (i * 'h4) + 'h0;
end
endfunction
endpackage : XmlSvPkgDIG_IFC_REGMAP

View File

@ -1,102 +0,0 @@
//
// Copyright 2025 Ettus Research, a National Instruments Brand
//
// 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)
// CONTROLLER_INFO : 0x1C (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
// CONTROLLER_INFO Register (from x4xx_gpio_spi.v)
localparam CONTROLLER_INFO = 'h1C; // Register Offset
localparam CONTROLLER_INFO_SIZE = 32; // register width in bits
localparam CONTROLLER_INFO_MASK = 32'hF;
localparam SLAVE_COUNT_SIZE = 4; //CONTROLLER_INFO:SLAVE_COUNT
localparam SLAVE_COUNT_MSB = 3; //CONTROLLER_INFO:SLAVE_COUNT
localparam SLAVE_COUNT = 0; //CONTROLLER_INFO:SLAVE_COUNT
// Return the offset of an element of register array SPI_SLAVE_CONFIG
function automatic integer SPI_SLAVE_CONFIG (input integer i);
begin
SPI_SLAVE_CONFIG = (i * 'h4) + 'h0;
end
endfunction

View File

@ -86,9 +86,9 @@
localparam FPGA_CURRENT_VERSION_BUILD = 'h0; // FPGA_VERSION:FPGA_CURRENT_VERSION_BUILD
localparam FPGA_OLDEST_COMPATIBLE_VERSION_MINOR = 'h0; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_MINOR
localparam FPGA_OLDEST_COMPATIBLE_VERSION_BUILD = 'h0; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_BUILD
localparam FPGA_CURRENT_VERSION_MAJOR = 'hB; // FPGA_VERSION:FPGA_CURRENT_VERSION_MAJOR
localparam FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR = 'hB; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR
localparam FPGA_VERSION_LAST_MODIFIED_TIME = 'h26022715; // FPGA_VERSION:FPGA_VERSION_LAST_MODIFIED_TIME
localparam FPGA_CURRENT_VERSION_MAJOR = 'hC; // FPGA_VERSION:FPGA_CURRENT_VERSION_MAJOR
localparam FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR = 'hC; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR
localparam FPGA_VERSION_LAST_MODIFIED_TIME = 'h26090111; // FPGA_VERSION:FPGA_VERSION_LAST_MODIFIED_TIME
// Enumerated type RF_CORE_100M_VERSION
localparam RF_CORE_100M_VERSION_SIZE = 7;

View File

@ -86,9 +86,9 @@
localparam FPGA_CURRENT_VERSION_BUILD = 'h0; // FPGA_VERSION:FPGA_CURRENT_VERSION_BUILD
localparam FPGA_OLDEST_COMPATIBLE_VERSION_MINOR = 'h0; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_MINOR
localparam FPGA_OLDEST_COMPATIBLE_VERSION_BUILD = 'h0; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_BUILD
localparam FPGA_CURRENT_VERSION_MAJOR = 'hB; // FPGA_VERSION:FPGA_CURRENT_VERSION_MAJOR
localparam FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR = 'hB; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR
localparam FPGA_VERSION_LAST_MODIFIED_TIME = 'h26022715; // FPGA_VERSION:FPGA_VERSION_LAST_MODIFIED_TIME
localparam FPGA_CURRENT_VERSION_MAJOR = 'hC; // FPGA_VERSION:FPGA_CURRENT_VERSION_MAJOR
localparam FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR = 'hC; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR
localparam FPGA_VERSION_LAST_MODIFIED_TIME = 'h26090111; // FPGA_VERSION:FPGA_VERSION_LAST_MODIFIED_TIME
// Enumerated type RF_CORE_1000M_VERSION
localparam RF_CORE_1000M_VERSION_SIZE = 7;

View File

@ -86,9 +86,9 @@
localparam FPGA_CURRENT_VERSION_BUILD = 'h0; // FPGA_VERSION:FPGA_CURRENT_VERSION_BUILD
localparam FPGA_OLDEST_COMPATIBLE_VERSION_MINOR = 'h0; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_MINOR
localparam FPGA_OLDEST_COMPATIBLE_VERSION_BUILD = 'h0; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_BUILD
localparam FPGA_CURRENT_VERSION_MAJOR = 'hB; // FPGA_VERSION:FPGA_CURRENT_VERSION_MAJOR
localparam FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR = 'hB; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR
localparam FPGA_VERSION_LAST_MODIFIED_TIME = 'h26022715; // FPGA_VERSION:FPGA_VERSION_LAST_MODIFIED_TIME
localparam FPGA_CURRENT_VERSION_MAJOR = 'hC; // FPGA_VERSION:FPGA_CURRENT_VERSION_MAJOR
localparam FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR = 'hC; // FPGA_VERSION:FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR
localparam FPGA_VERSION_LAST_MODIFIED_TIME = 'h26090111; // FPGA_VERSION:FPGA_VERSION_LAST_MODIFIED_TIME
// Enumerated type RF_CORE_200M_VERSION
localparam RF_CORE_200M_VERSION_SIZE = 7;

View File

@ -0,0 +1,23 @@
#
# Copyright 2026 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# Description: X410 variant of the X4xx GPIO SPI simulation shell.
#
VLOG_ARGS += +define+X410
SVLOG_ARGS += +define+X410
#-------------------------------------------------
# Top-of-Makefile
#-------------------------------------------------
BASE_DIR = $(abspath ../../../../../top)
include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
include ../x4xx/Makefile.common
#-------------------------------------------------
# Bottom-of-Makefile
#-------------------------------------------------
include $(BASE_DIR)/../tools/make/viv_simulator.mak

View File

@ -0,0 +1,20 @@
#
# Copyright 2026 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# Description: X4xx variant of the X4xx GPIO SPI simulation shell.
#
#-------------------------------------------------
# Top-of-Makefile
#-------------------------------------------------
BASE_DIR = $(abspath ../../../../../top)
include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
include ./Makefile.common
#-------------------------------------------------
# Bottom-of-Makefile
#-------------------------------------------------
include $(BASE_DIR)/../tools/make/viv_simulator.mak

View File

@ -0,0 +1,21 @@
#-------------------------------------------------
# Design Specific
#-------------------------------------------------
include $(BASE_DIR)/../lib/control/Makefile.srcs
include $(BASE_DIR)/../lib/rfnoc/Makefile.srcs
DESIGN_SRCS += $(abspath \
$(CONTROL_LIB_SRCS) \
$(RFNOC_FRAMEWORK_SRCS) \
../../../regmap/XmlSvPkgDIG_IFC_REGMAP.sv \
../../../x4xx_gpio_spi.sv \
)
#-------------------------------------------------
# Testbench Specific
#-------------------------------------------------
SIM_TOP = x4xx_gpio_spi_tb
SIM_SRCS = $(abspath \
../x4xx_gpio_spi_tb.sv \
)

View File

@ -0,0 +1,364 @@
//
// Copyright 2026 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: x4xx_gpio_spi_tb
//
// Description: X4xx GPIO SPI transaction testbench for four peripheral slots.
//
// Validates GPIO pin configuration, CS idle state, and SPI write/readback for
// 20-, 32-, 40-, and 64-bit transactions. Tests cover consecutive transfers,
// switching peripheral slots and clock dividers, randomized payloads, the
// status and extended response registers, and SPI timing checks.
//
// This testbench does not cover invalid register configurations, unsupported
// transaction lengths, concurrent transactions.
// The DUT does not properly handle these unsupported scenarios.
//
// For testing X410, run with VLOG_ARGS='+define+X410' SVLOG_ARGS='+define+X410'
//
`default_nettype none
module x4xx_gpio_spi_tb;
`include "test_exec.svh"
import PkgTestExec::*;
import ctrlport_pkg::*;
import ctrlport_bfm_pkg::*;
import spi_slave_bfm_pkg::*;
import XmlSvPkgDIG_IFC_REGMAP::*;
localparam int unsigned NUM_PERIPHERALS = 4;
// Compile-time BFM widths for the peripheral slots.
localparam int unsigned TRANSACTION_LENGTH_0 = 64;
localparam int unsigned TRANSACTION_LENGTH_1 = 40;
localparam int unsigned TRANSACTION_LENGTH_2 = 32;
localparam int unsigned TRANSACTION_LENGTH_3 = 20;
localparam time CLK_2X_PERIOD = 12ns;
`ifdef X410
localparam bit DOUBLE_CLOCK = 1;
`else
localparam bit DOUBLE_CLOCK = 0;
`endif
localparam int unsigned CLK_DIV_1 = 2;
localparam int unsigned CLK_DIV_2 = 6;
// SPI edge toggle: 0 updates on falling and samples on rising; 1 reverses it.
localparam bit SPI_UPDATE_ON_RISING = 1;
localparam int unsigned SDI_PIN = 1;
localparam int unsigned SDO_PIN = 2;
localparam int unsigned CLK_PIN = 3;
localparam int unsigned CS_PINS [0:NUM_PERIPHERALS-1] = '{0, 4, 5, 6};
localparam int unsigned TRANSACTION_LENGTHS [0:NUM_PERIPHERALS-1] = '{64, 40, 32, 20};
// The DUT uses a control clock and a 2x SPI engine clock.
logic clk, clkx2, reset;
sim_clock_gen #(.PERIOD(CLK_2X_PERIOD*2), .AUTOSTART(0)) clk_gen (
.clk(clk), .rst(reset));
sim_clock_gen #(.PERIOD(CLK_2X_PERIOD), .AUTOSTART(0)) clk_gen_x2 (
.clk(clkx2), .rst());
// GPIO interface signals
logic [31:0] gpio_out;
logic [31:0] gpio_ddr;
wire logic [31:0] gpio_in;
// SPI interfaces for the peripheral slots.
spi_if spi_if [0:NUM_PERIPHERALS-1] ();
// All slots share SCK, MOSI, and MISO GPIO pins; each has its own CS pin.
for (genvar spi_idx = 0; spi_idx < NUM_PERIPHERALS; spi_idx++) begin : gen_spi_wiring
assign spi_if[spi_idx].cs_n = gpio_out[CS_PINS[spi_idx]];
assign spi_if[spi_idx].sck = gpio_out[CLK_PIN];
assign spi_if[spi_idx].mosi = gpio_out[SDO_PIN];
assign gpio_in[SDI_PIN] = spi_if[spi_idx].miso;
end
// The BFMs must remain explicit because length is a class specialization parameter.
spi_slave_bfm #(.TRANSACTION_LENGTH(TRANSACTION_LENGTH_0)) spi_bfm_0 = new(spi_if[0]);
spi_slave_bfm #(.TRANSACTION_LENGTH(TRANSACTION_LENGTH_1)) spi_bfm_1 = new(spi_if[1]);
spi_slave_bfm #(.TRANSACTION_LENGTH(TRANSACTION_LENGTH_2)) spi_bfm_2 = new(spi_if[2]);
spi_slave_bfm #(.TRANSACTION_LENGTH(TRANSACTION_LENGTH_3)) spi_bfm_3 = new(spi_if[3]);
// Each slot has an independent monitor so timing expectations follow the
// selected transaction clock divider.
spi_timing_monitor_bfm spi_timing_mon [0:NUM_PERIPHERALS-1];
for (genvar spi_idx = 0; spi_idx < NUM_PERIPHERALS; spi_idx++) begin : gen_spi_timing_monitor
initial begin
spi_timing_mon[spi_idx] = new(
.iface(spi_if[spi_idx]), .half_per_time(get_half_per_time(CLK_DIV_1)),
.cs_hold_time(0), .cs_to_first_rise_time(0), .cs_guard_time(0));
end
end
// Control-port connection to the GPIO SPI DUT.
logic [1:0] spi_ctrlport_resp_status;
ctrlport_if gpio_ctrlport_if (.clk(clk), .rst(reset));
ctrlport_bfm gpio_ctrlport_bfm = new(gpio_ctrlport_if);
x4xx_gpio_spi dut (
.ctrlport_clk (clk),
.ctrlport_clk_2x (clkx2),
.ctrlport_rst (reset),
.s_ctrlport_req_wr (gpio_ctrlport_if.req.wr),
.s_ctrlport_req_rd (gpio_ctrlport_if.req.rd),
.s_ctrlport_req_addr (gpio_ctrlport_if.req.addr),
.s_ctrlport_req_data (gpio_ctrlport_if.req.data),
.s_ctrlport_resp_ack (gpio_ctrlport_if.resp.ack),
.s_ctrlport_resp_status(spi_ctrlport_resp_status),
.s_ctrlport_resp_data (gpio_ctrlport_if.resp.data),
.gpio_out (gpio_out),
.gpio_ddr (gpio_ddr),
.gpio_in (gpio_in)
);
assign gpio_ctrlport_if.resp.status = ctrlport_status_t'(spi_ctrlport_resp_status);
// Return the SPI half-period expected by the timing monitor. X410 runs the
// SPI engine at twice the clock rate used by the other X4xx variants.
function automatic time get_half_per_time(input int unsigned clk_div);
return (clk_div + 1) * CLK_2X_PERIOD * (DOUBLE_CLOCK ? 1 : 2);
endfunction
function automatic logic [63:0] get_response_mask(
input int unsigned transaction_length
);
// SPI_FULL_RESPONSE_MSB exposes bits 62:31; bit 63 is not returned.
return (64'h1 << ((transaction_length < 63) ? transaction_length : 63)) - 1;
endfunction
function automatic logic [31:0] get_status_mask(
input int unsigned transaction_length
);
// SPI_STATUS exposes at most 31 response bits below SPI_READY.
return (32'h1 << ((transaction_length < 31) ? transaction_length : 31)) - 1;
endfunction
// Program the pin mapping and fixed transaction length for one SPI slot.
task automatic configure_peripheral(input int unsigned selected_peripheral);
SPI_SETUP peripheral_config_fields;
peripheral_config_fields = '0;
peripheral_config_fields.MOSI_EDGE = SPI_UPDATE_ON_RISING;
peripheral_config_fields.MISO_EDGE = !SPI_UPDATE_ON_RISING;
peripheral_config_fields.SPI_LENGTH = TRANSACTION_LENGTHS[selected_peripheral];
peripheral_config_fields.SLAVE_CS = CS_PINS[selected_peripheral];
peripheral_config_fields.SLAVE_MISO = SDI_PIN;
peripheral_config_fields.SLAVE_MOSI = SDO_PIN;
peripheral_config_fields.SLAVE_CLK = CLK_PIN;
gpio_ctrlport_bfm.write(kSPI_SLAVE_CONFIG(selected_peripheral), peripheral_config_fields);
endtask
task automatic configure_transaction(
input int unsigned selected_peripheral,
input int unsigned clk_div
);
SPI_TRANSACTION_CONFIG transaction_config_fields;
// The selected selected_peripheral and divider apply to the next transaction.
transaction_config_fields = '0;
transaction_config_fields.SPI_CLK_DIV = clk_div;
transaction_config_fields.SPI_SLAVE_SELECT = selected_peripheral;
gpio_ctrlport_bfm.write(kSPI_TRANSACTION_CONFIG, transaction_config_fields);
spi_timing_mon[selected_peripheral].set_timing(
.half_per_time(get_half_per_time(clk_div)),
.cs_hold_time(0), .cs_to_first_rise_time(0), .cs_guard_time(0));
endtask
task automatic queue_bfm_transaction(
input int unsigned selected_peripheral,
input logic [63:0] write_data,
input logic [63:0] expected_response
);
// Keep the typed BFM dispatch in one place for simulator portability.
case (selected_peripheral)
0: spi_bfm_0.async_write_read(write_data, expected_response);
1: spi_bfm_1.async_write_read(write_data, expected_response);
2: spi_bfm_2.async_write_read(write_data, expected_response);
3: spi_bfm_3.async_write_read(write_data, expected_response);
default: $fatal(1, "Invalid SPI peripheral index: %0d", selected_peripheral);
endcase
endtask
task automatic wait_for_cs(input int unsigned selected_peripheral);
// Dynamic bit-select event controls are avoided for Vivado XSim.
case (selected_peripheral)
0: @(posedge gpio_out[CS_PINS[0]]);
1: @(posedge gpio_out[CS_PINS[1]]);
2: @(posedge gpio_out[CS_PINS[2]]);
3: @(posedge gpio_out[CS_PINS[3]]);
default: $fatal(1, "Invalid SPI peripheral index: %0d", selected_peripheral);
endcase
endtask
task automatic get_bfm_error_count(input int unsigned selected_peripheral, output int count);
case (selected_peripheral)
0: count = spi_bfm_0.get_error_count();
1: count = spi_bfm_1.get_error_count();
2: count = spi_bfm_2.get_error_count();
3: count = spi_bfm_3.get_error_count();
default: $fatal(1, "Invalid SPI peripheral index: %0d", selected_peripheral);
endcase
endtask
task automatic start_bfms();
// Start all models, including inactive slots. Inactive CS lines remain
// high and therefore do not consume queued transactions.
spi_bfm_0.run();
spi_bfm_1.run();
spi_bfm_2.run();
spi_bfm_3.run();
for (int unsigned spi_idx = 0; spi_idx < NUM_PERIPHERALS; spi_idx++) begin
spi_timing_mon[spi_idx].run();
end
endtask
task automatic start_transaction(
input int unsigned transaction_length,
input logic [63:0] write_data
);
if (transaction_length > 32) begin
gpio_ctrlport_bfm.write(
kSPI_TRANSACTION_LSB,
(write_data << (64 - transaction_length)) & kSPI_TRANSACTION_LSBMask);
gpio_ctrlport_bfm.write(
kSPI_TRANSACTION_GO,
(write_data >> (transaction_length - 32)) & kSPI_TRANSACTION_GOMask);
end else begin
gpio_ctrlport_bfm.write(
kSPI_TRANSACTION_GO,
(write_data << (32 - transaction_length)) & kSPI_TRANSACTION_GOMask);
end
endtask
task automatic execute_transaction(
input int unsigned selected_peripheral,
input logic [63:0] write_data,
input logic [63:0] expected_response
);
int unsigned spi_status_read;
int unsigned spi_response_msb;
int bfm_error_count;
int timing_error_count;
int unsigned transaction_length;
logic [62:0] full_response;
logic [63:0] response_mask;
logic [31:0] status_mask;
transaction_length = TRANSACTION_LENGTHS[selected_peripheral];
response_mask = get_response_mask(transaction_length);
status_mask = get_status_mask(transaction_length);
queue_bfm_transaction(selected_peripheral, write_data, expected_response);
start_transaction(transaction_length, write_data);
wait_for_cs(selected_peripheral);
repeat (20) @(posedge clk);
gpio_ctrlport_bfm.read(kSPI_STATUS, spi_status_read);
test.assert_error(
spi_status_read[kSPI_READY],
$sformatf("SPI%0d transaction not complete", transaction_length));
test.assert_error(
(spi_status_read & status_mask) == (expected_response & status_mask),
$sformatf("SPI%0d status response failed. Expected 0x%0h, got 0x%0h",
transaction_length, expected_response & status_mask,
spi_status_read & status_mask));
full_response = {32'b0, spi_status_read[30:0]};
if (transaction_length > 31) begin
gpio_ctrlport_bfm.read(kSPI_FULL_RESPONSE_MSB, spi_response_msb);
full_response[62:31] = spi_response_msb;
end
test.assert_error(
(full_response & response_mask) == (expected_response & response_mask),
$sformatf("SPI%0d full response failed. Expected 0x%0h, got 0x%0h, mask 0x%0h",
transaction_length, expected_response, full_response, response_mask));
get_bfm_error_count(selected_peripheral, bfm_error_count);
test.assert_error(
bfm_error_count == 0,
$sformatf("SPI%0d BFM reported %0d errors", transaction_length, bfm_error_count));
timing_error_count = spi_timing_mon[selected_peripheral].get_error_count();
test.assert_error(
timing_error_count == 0,
$sformatf("SPI%0d timing monitor reported %0d errors",
transaction_length, timing_error_count));
endtask
initial begin : main
string tb_name;
int unsigned selected_peripheral;
int unsigned previous_peripheral;
`ifdef X410
tb_name = "x410_gpio_spi_tb";
`else
tb_name = "x4xx_gpio_spi_tb";
`endif
test.start_tb(tb_name);
gpio_ctrlport_bfm.run();
clk_gen.start();
clk_gen_x2.start();
clk_gen.reset(50);
//-------------------------------------------------------------------------
test.start_test("Full configuration and transaction", 100us);
for (int unsigned selected_peripheral = 0; selected_peripheral < NUM_PERIPHERALS; selected_peripheral++) begin
configure_peripheral(selected_peripheral);
test.assert_error(
gpio_out[CS_PINS[selected_peripheral]] === 1'b1,
$sformatf("SPI%0d CS is not high after configuration", TRANSACTION_LENGTHS[selected_peripheral]));
test.assert_error(
gpio_ddr[CS_PINS[selected_peripheral]] === 1'b1,
$sformatf("SPI%0d CS is not configured as an output", TRANSACTION_LENGTHS[selected_peripheral]));
end
test.assert_error(gpio_ddr[CLK_PIN] === 1'b1, "SPI clock is not configured as an output");
test.assert_error(gpio_ddr[SDO_PIN] === 1'b1, "SPI SDO is not configured as an output");
test.assert_error(gpio_ddr[SDI_PIN] === 1'b0, "SPI SDI is not configured as an input");
// Only start SPI BFM after configuration is done (CS is high)
start_bfms();
configure_transaction(0, CLK_DIV_1);
execute_transaction(0, 64'hFAFAFAFA00000001, 64'h0123456789ABCDEF);
//Consecutive transaction with new divider
configure_transaction(0, CLK_DIV_2);
execute_transaction(0, 64'hFAFAFAFA00000001, 64'h0123456789ABCDEF);
//Transaction on different peripheral and new divider
configure_transaction(2, CLK_DIV_1);
execute_transaction(2, 64'hBA4B0EB4, 64'h98765432);
//Transaction on different peripheral and new divider
configure_transaction(1, CLK_DIV_1);
execute_transaction(1, 64'h0000000A010FA7BF, 64'h000000DCBA987654);
//Consecutive transaction without changing the clock divider
configure_transaction(3, CLK_DIV_1);
execute_transaction(3, 64'h00000000000FA7BF, 64'h0000000000054321);
execute_transaction(3, 64'h00000000000FA00F, 64'h0000000000054001);
test.end_test();
//-------------------------------------------------------------------------
test.start_test("Random transactions", 2ms);
previous_peripheral = NUM_PERIPHERALS;
for (int unsigned transaction = 0; transaction < 100; transaction++) begin
selected_peripheral = $urandom_range(NUM_PERIPHERALS - 1, 0);
if (selected_peripheral != previous_peripheral) begin
configure_transaction(selected_peripheral, CLK_DIV_2);
end
execute_transaction(selected_peripheral, {$urandom(), $urandom()}, {$urandom(), $urandom()});
previous_peripheral = selected_peripheral;
end
test.end_test();
test.end_tb();
end
endmodule
`default_nettype wire

View File

@ -3843,13 +3843,13 @@ endmodule
// <li> Oldest compatible version: @.VERSIONING_REGS_REGMAP..OLDEST_COMPATIBLE_VERSION
// <li> Version last modified: @.VERSIONING_REGS_REGMAP..VERSION_LAST_MODIFIED
// </info>
// <value name="FPGA_CURRENT_VERSION_MAJOR" integer="11"/>
// <value name="FPGA_CURRENT_VERSION_MAJOR" integer="12"/>
// <value name="FPGA_CURRENT_VERSION_MINOR" integer="0"/>
// <value name="FPGA_CURRENT_VERSION_BUILD" integer="0"/>
// <value name="FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR" integer="11"/>
// <value name="FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR" integer="12"/>
// <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="0x26022715"/>
// <value name="FPGA_VERSION_LAST_MODIFIED_TIME" integer="0x26090111"/>
// </enumeratedtype>
// </group>
//</regmap>

View File

@ -1,5 +1,5 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
// Copyright 2026 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
@ -28,7 +28,7 @@
module x4xx_gpio_spi #(
parameter NUM_SLAVES = 4,
parameter [19:0] BASE_ADDRESS = 0,
parameter [19:0] SIZE_ADDRESS = 19'h20
parameter [19:0] SIZE_ADDRESS = 19'h2C
) (
input wire ctrlport_clk,
input wire ctrlport_clk_2x,
@ -52,14 +52,14 @@ module x4xx_gpio_spi #(
);
`include "../../lib/rfnoc/core/ctrlport.vh"
`include "regmap/dig_ifc_regmap_utils.vh"
import XmlSvPkgDIG_IFC_REGMAP::*;
// 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 [63:0] readback;
wire readback_stb;
wire readback_stb_extended;
@ -80,10 +80,10 @@ module x4xx_gpio_spi #(
// 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];
reg [kSLAVE_CLKSize-1:0] sclk_mapping [3:0];
reg [kSLAVE_MOSISize-1:0] mosi_mapping [3:0];
reg [kSLAVE_MISOSize-1:0] miso_mapping [3:0];
reg [ kSLAVE_CSSize-1:0] ss_mapping [3:0];
//---------------------------------------------------------------------------
// Address calculation
@ -95,8 +95,8 @@ module x4xx_gpio_spi #(
// 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));
(s_ctrlport_req_addr >= BASE_ADDRESS + kSPI_SLAVE_CONFIG(0)) &&
(s_ctrlport_req_addr <= BASE_ADDRESS + kSPI_SLAVE_CONFIG(3));
// Decode the slave being addressed.
wire [1:0]slave_address = s_ctrlport_req_addr[3:2];
@ -108,7 +108,7 @@ module x4xx_gpio_spi #(
// 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];
reg [kSPI_LENGTHSize-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}};
@ -119,20 +119,25 @@ module x4xx_gpio_spi #(
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 WRITE_SPI_LSB = 3'd2;
localparam WRITE_SPI = 3'd3;
localparam CONFIG_TRANSFER = 3'd4;
localparam WAIT_SPI = 3'd5;
// Addresses in simple_spi_core_64bit.v
localparam DIVIDER_ADDRESS = 8'd0;
localparam CTRL_ADDRESS = 8'd1;
localparam DATA_ADDRESS = 8'd2;
localparam DATA_LSB_ADDRESS = 8'd3;
reg [ 2:0] state = IDLE;
reg [ 31:0] data_cache;
reg [SPI_CLK_DIV_SIZE-1:0] divider;
reg [kSPI_CLK_DIVSize-1:0] divider;
reg [ 1:0] cs;
reg spi_go = 1'b0;
reg spi_ready = 1'b0;
// Additional bits for optional 64 bit transaction
reg [ 31:0] data_cache_lsb;
integer slave_i;
@ -146,20 +151,21 @@ module x4xx_gpio_spi #(
s_ctrlport_resp_ack <= 1'b0;
spi_go <= 1'b0;
spi_ready <= 1'b0;
divider <= {SPI_CLK_DIV_SIZE{1'b0}};
divider <= {kSPI_CLK_DIVSize{1'b0}};
cs <= 2'b0;
data_cache <= 32'h0;
// Assigned to unassigned mapping. This avoids overwriting
// signals with those from uninitialized slaves.
// Assigned to unassigned mapping (pin 31 is unused). 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;
sclk_mapping[slave_i] <= 5'd31;
mosi_mapping[slave_i] <= 5'd31;
miso_mapping[slave_i] <= 5'd31;
ss_mapping [slave_i] <= 5'd31;
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}};
slave_spi_length[slave_i] <= {kSPI_LENGTHSize{1'b0}};
end
end else begin
@ -175,26 +181,33 @@ module x4xx_gpio_spi #(
// Address spi configuration writes
if(address_is_slave) begin
automatic SPI_SETUP spi_setup = s_ctrlport_req_data;
// 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];
sclk_mapping [slave_address] <= spi_setup.SLAVE_CLK;
mosi_mapping [slave_address] <= spi_setup.SLAVE_MOSI;
miso_mapping [slave_address] <= spi_setup.SLAVE_MISO;
ss_mapping [slave_address] <= spi_setup.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];
slave_spi_length [slave_address] <= spi_setup.SPI_LENGTH;
data_in_edge [slave_address] <= spi_setup.MISO_EDGE;
data_out_edge [slave_address] <= spi_setup.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];
BASE_ADDRESS + kSPI_TRANSACTION_CONFIG: begin
automatic SPI_TRANSACTION_CONFIG spi_transaction_config = s_ctrlport_req_data;
divider <= spi_transaction_config.SPI_CLK_DIV;
cs <= spi_transaction_config.SPI_SLAVE_SELECT;
end
BASE_ADDRESS + SPI_TRANSACTION_GO: begin
BASE_ADDRESS + kSPI_TRANSACTION_LSB: begin
data_cache_lsb <= s_ctrlport_req_data;
end
BASE_ADDRESS + kSPI_TRANSACTION_GO: begin
spi_ready <= 1'b0;
spi_go <= 1'b1;
data_cache <= s_ctrlport_req_data;
end
// No register implementation for provided address
@ -219,17 +232,29 @@ module x4xx_gpio_spi #(
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;
BASE_ADDRESS + kSPI_TRANSACTION_CONFIG: begin
automatic SPI_TRANSACTION_CONFIG spi_transaction_config = '0;
spi_transaction_config.SPI_CLK_DIV = divider;
s_ctrlport_resp_data <= spi_transaction_config;
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];
BASE_ADDRESS + kSPI_STATUS: begin
automatic SPI_STATUS spi_status = '0;
spi_status.SPI_READY = spi_ready;
spi_status.SPI_RESPONSE = readback[30:0];
s_ctrlport_resp_data <= spi_status;
end
BASE_ADDRESS + CONTROLLER_INFO: begin
s_ctrlport_resp_data[SLAVE_COUNT_MSB:SLAVE_COUNT] <= NUM_SLAVES;
BASE_ADDRESS + kSPI_FULL_RESPONSE_MSB: begin
automatic SPI_FULL_RESPONSE_MSB spi_full_response = '0;
spi_full_response.SPI_FULL_RESPONSE_MSB_DATA = readback[62:31];
s_ctrlport_resp_data <= spi_full_response;
end
BASE_ADDRESS + kCONTROLLER_INFO: begin
automatic CONTROLLER_INFO controller_info = '0;
controller_info.SLAVE_COUNT = NUM_SLAVES;
s_ctrlport_resp_data <= controller_info;
end
// No register implementation for provided address
@ -262,7 +287,6 @@ module x4xx_gpio_spi #(
if (ctrlport_rst) begin
state <= IDLE;
set_stb <= 1'b0;
data_cache <= 32'h0;
end else begin
// Default Assignments
@ -270,8 +294,6 @@ module x4xx_gpio_spi #(
case (state)
IDLE: begin
// Save data and address for further steps
data_cache <= s_ctrlport_req_data;
if (spi_go) begin
state <= CONFIG_TRANSFER;
@ -288,7 +310,7 @@ module x4xx_gpio_spi #(
set_addr <= CTRL_ADDRESS;
set_data <= { data_out_edge[cs], // 1 bit
data_in_edge[cs], // 1 bit
slave_spi_length[cs], // 6 bits
slave_spi_length[cs][5:0], // 6 bits, ignore MSB, 0 is considered as 64
{24-NUM_SLAVES{1'b0}}, // Padding for slaves
slave_select // NUM_SLAVES bits
};
@ -296,13 +318,27 @@ module x4xx_gpio_spi #(
// Write divider to SPI core
SET_DIVIDER: begin
if (slave_spi_length[cs] > 32) begin
state <= WRITE_SPI_LSB;
end else begin
state <= WRITE_SPI;
end
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_LSB: begin
state <= WRITE_SPI;
set_stb <= 1'b1;
set_addr <= DATA_LSB_ADDRESS;
set_data <= data_cache_lsb;
end
// Write data bits to SPI core (aligned to MSB)
WRITE_SPI: begin
state <= WAIT_SPI;
@ -345,11 +381,12 @@ module x4xx_gpio_spi #(
`ifndef X410
simple_spi_core #(
simple_spi_core_64bit #(
.BASE (0),
.WIDTH (NUM_SLAVES),
.CLK_IDLE (0),
.SEN_IDLE ({NUM_SLAVES{1'b1}})
.SEN_IDLE ({NUM_SLAVES{1'b1}}),
.MAX_BITS (64)
) simple_spi_core_i (
.clock (ctrlport_clk),
.reset (ctrlport_rst),
@ -414,11 +451,12 @@ module x4xx_gpio_spi #(
end
end
simple_spi_core #(
simple_spi_core_64bit #(
.BASE (0),
.WIDTH (NUM_SLAVES),
.CLK_IDLE (0),
.SEN_IDLE ({NUM_SLAVES{1'b1}})
.SEN_IDLE ({NUM_SLAVES{1'b1}}),
.MAX_BITS (64)
) simple_spi_core_i (
.clock (ctrlport_clk_2x),
.reset (ctrlport_rst),
@ -514,7 +552,7 @@ endmodule
`default_nettype wire
//XmlParse xml_on
//<regmap name="DIG_IFC_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
//<regmap name="DIG_IFC_REGMAP" readablestrobes="false">
// <group name="SPI_OVER_GPIO_REGS">
// <info>
// </info>
@ -550,19 +588,22 @@ endmodule
// 16-27: Port B GPIO
// </info>
// </bitfield>
// <bitfield name="SPI_LENGTH" range="20..25" initialvalue="0">
// <bitfield name="SPI_LENGTH" range="20..26" initialvalue="0">
// <info>
// Indicates the length of SPI transactions to this slave.
// Indicates the length of SPI transactions to this slave.</br>
// Valid transaction lengths are 1 through 64 bits. </br>
// This is not checked on FPGA and other values will </br>
// lead to undefined behavior.
// </info>
// </bitfield>
// <bitfield name="MISO_EDGE" range="26" initialvalue="0">
// <bitfield name="MISO_EDGE" range="27" 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">
// <bitfield name="MOSI_EDGE" range="28" initialvalue="0">
// <info>
// Controls the edge in which the MOSI line is updated.</br>
// 0 = falling edge of SCLK.</br>
@ -588,27 +629,51 @@ endmodule
// </bitfield>
// <bitfield name="SPI_SLAVE_SELECT" range="16..17" initialvalue="0"/>
// </register>
// <register name="SPI_TRANSACTION_GO" offset="0x14" size="32" readable="false">
// <register name="SPI_TRANSACTION_LSB" offset="0x14" size="32" readable="false">
// <info>
// Starts a SPI transaction
// For SPI transactions with @.SPI_SLAVE_CONFIG.SPI_LENGTH > 32, this must be written
// before @.SPI_TRANSACTION_GO.
// </info>
// <bitfield name="SPI_DATA_LSB" range="0..31" initialvalue="0">
// <info> Left-aligned LSB payload for SPI transaction with @.SPI_SLAVE_CONFIG.SPI_LENGTH > 32.<br/>
// See @.SPI_TRANSACTION_GO for more information.</info>
// </bitfield>
// </register>
// <register name="SPI_TRANSACTION_GO" offset="0x18" size="32" readable="false">
// <info>
// Starts a SPI transaction. Does not check whether a previous transaction is still ongoing.
// If so, the running transaction may be corrupted.
// </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>
// <info> Payload to be sent for the SPI transaction.<br/>
// If the payload is shorter than 32 bits, it must be left-aligned.
// The first transmitted bit is the MSB and data is shifted out to the left.<br/>
// If the desired payload is longer than 32 bits, the remaining LSBs
// must be written to @.SPI_TRANSACTION_LSB.SPI_DATA_LSB (left-aligned) before starting
// the transaction. </info>
// </bitfield>
// </register>
// <register name="SPI_STATUS" offset="0x18" size="32" writable="false">
// <register name="SPI_STATUS" offset="0x1C" size="32" writable="false">
// <info>
// Contains the status of the SPI engine.
// Contains the status of the SPI engine and the least-significant 31 bits of the response.
// Also read SPI_FULL_RESPONSE_MSB for bit 32 or for transactions longer than 32 bits.
// </info>
// <bitfield name="SPI_READY" range="24" initialvalue="0">
// <bitfield name="SPI_READY" range="31" 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 name="SPI_RESPONSE" range="0..30" initialvalue="0">
// <info> Records only the least-significant 31 bits of the last completed SPI response. </info>
// </bitfield>
// </register>
// <register name="CONTROLLER_INFO" offset="0x1C" size="32" writable="false">
// <register name="SPI_FULL_RESPONSE_MSB" offset="0x20" size="32" writable="false">
// <info>
// Contains bits 62 through 31 of the last completed SPI response.
// For transactions shorter than 31 bits, the upper bits in this register are undefined.
// The regmap does not expose the most significant bit (bit 63) of the response.
// </info>
// <bitfield name="SPI_FULL_RESPONSE_MSB_DATA" range="0..31" initialvalue="0"/>
// </register>
// <register name="CONTROLLER_INFO" offset="0x24" size="32" writable="false">
// <info>
// Contains information pertaining this SPI controller block.
// </info>