[doc] Updated content for new reggen preproc
The mdbook-reggen preprocessor introduces a new way to include generated
register and interface tables as well as a more flexible regref.
Signed-off-by: Hugo McNally <hugo.mcnally@gmail.com>
diff --git a/SUMMARY.md b/SUMMARY.md
index 7030280..b82cca9 100644
--- a/SUMMARY.md
+++ b/SUMMARY.md
@@ -13,11 +13,14 @@
- [Analog Sensor Top](./hw/top_earlgrey/ip/ast/README.md)
- [Alert Handler](./hw/top_earlgrey/ip_autogen/alert_handler/README.md)
- [Design Verification](./hw/top_earlgrey/ip_autogen/alert_handler/dv/README.md)
+ - [Interface and Registers](./hw/top_earlgrey/ip_autogen/alert_handler/data/alert_handler.hjson)
- [Checklist](./hw/top_earlgrey/ip_autogen/alert_handler/doc/checklist.md)
- [Interrupt Controller](./hw/top_earlgrey/ip_autogen/rv_plic/README.md)
- [Design Verification](./hw/top_earlgrey/ip_autogen/rv_plic/doc/dv/README.md)
+ - [Interface and Registers](./hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson)
- [Checklist](./hw/top_earlgrey/ip_autogen/rv_plic/doc/checklist.md)
- [Sensor Control](./hw/top_earlgrey/ip/sensor_ctrl/README.md)
+ - [Interface and Registers](./hw/top_earlgrey/ip/sensor_ctrl/data/sensor_ctrl.hjson)
- [Checklist](./hw/top_earlgrey/ip/sensor_ctrl/doc/checklist.md)
- [TL-UL Checklist](./hw/top_earlgrey/ip/xbar/doc/checklist.md)
- [Pinmux Targets](./hw/top_earlgrey/ip/pinmux/doc/autogen/targets.md)
@@ -28,6 +31,7 @@
- [Cores](./hw/doc/cores.md)
- [Ibex RISC-V Core Wrapper](./hw/ip/rv_core_ibex/README.md)
- [Design Verification](./hw/ip/rv_core_ibex/dv/README.md)
+ - [Interface and Registers](./hw/ip/rv_core_ibex/data/rv_core_ibex.hjson)
- [Checklist](./hw/ip/rv_core_ibex/doc/checklist.md)
- [OTBN](./hw/ip/otbn/README.md)
- [Developer Guide](./hw/ip/otbn/doc/developer-guide.md)
@@ -41,99 +45,129 @@
- [Tracer](./hw/ip/otbn/dv/tracer/README.md)
- [Formal Masking Verification Using Alma](./hw/ip/otbn/pre_sca/alma/README.md)
- [Functional Coverage](./hw/ip/otbn/dv/doc/fcov.md)
+ - [Interface and Registers](./hw/ip/otbn/data/otbn.hjson)
- [Checklist](./hw/ip/otbn/doc/checklist.md)
- [Hardware IP Blocks](./hw/ip/README.md)
- [Analog to Digital Converter Control](./hw/ip/adc_ctrl/README.md)
- [Design Verification](./hw/ip/adc_ctrl/dv/README.md)
- [Checklist](./hw/ip/adc_ctrl/doc/checklist.md)
+ - [Interface and Registers](./hw/ip/adc_ctrl/data/adc_ctrl.hjson)
- [AES](./hw/ip/aes/README.md)
- [Design Verification](./hw/ip/aes/dv/README.md)
+ - [Interface and Registers](./hw/ip/aes/data/aes.hjson)
- [Checklist](./hw/ip/aes/doc/checklist.md)
- [AON Timer](./hw/ip/aon_timer/README.md)
- [Design Verification](./hw/ip/aon_timer/dv/README.md)
+ - [Interface and Registers](./hw/ip/aon_timer/data/aon_timer.hjson)
- [Checklist](./hw/ip/aon_timer/doc/checklist.md)
- [Clock Manager](./hw/ip/clkmgr/README.md)
- [Design Verification](./hw/ip/clkmgr/dv/README.md)
+ - [Interface and Registers](./hw/top_earlgrey/ip/clkmgr/data/autogen/clkmgr.hjson)
- [Checklist](./hw/ip/clkmgr/doc/checklist.md)
- [CSRNG](./hw/ip/csrng/README.md)
- [Design Verification](./hw/ip/csrng/dv/README.md)
+ - [Interface and Registers](./hw/ip/csrng/data/csrng.hjson)
- [Checklist](./hw/ip/csrng/doc/checklist.md)
- [EDN](./hw/ip/edn/README.md)
- [Design Verification](./hw/ip/edn/dv/README.md)
+ - [Interface and Registers](./hw/ip/edn/data/edn.hjson)
- [Checklist](./hw/ip/edn/doc/checklist.md)
- [Entropy Source](./hw/ip/entropy_src/README.md)
- [Design Verification](./hw/ip/entropy_src/dv/README.md)
+ - [Interface and Registers](./hw/ip/entropy_src/data/entropy_src.hjson)
- [Checklist](./hw/ip/entropy_src/doc/checklist.md)
- [Flash Controller](./hw/ip/flash_ctrl/README.md)
- [Design Verification](./hw/ip/flash_ctrl/dv/README.md)
+ - [Interface and Registers](./hw/ip/flash_ctrl/data/flash_ctrl.hjson)
- [Checklist](./hw/ip/flash_ctrl/doc/checklist.md)
- [GPIO](./hw/ip/gpio/README.md)
- [Design Verification](./hw/ip/gpio/dv/README.md)
+ - [Interface and Registers](./hw/ip/gpio/data/gpio.hjson)
- [Checklist](./hw/ip/gpio/doc/checklist.md)
- [HMAC](./hw/ip/hmac/README.md)
- [Design Verification](./hw/ip/hmac/dv/README.md)
+ - [Interface and Registers](./hw/ip/hmac/data/hmac.hjson)
- [Checklist](./hw/ip/hmac/doc/checklist.md)
- [I2C](./hw/ip/i2c/README.md)
- [Design Verification](./hw/ip/i2c/dv/README.md)
+ - [Interface and Registers](./hw/ip/i2c/data/i2c.hjson)
- [Checklist](./hw/ip/i2c/doc/checklist.md)
- [Key Manager](./hw/ip/keymgr/README.md)
- [Design Verification](./hw/ip/keymgr/dv/README.md)
+ - [Interface and Registers](./hw/ip/keymgr/data/keymgr.hjson)
- [Checklist](./hw/ip/keymgr/doc/checklist.md)
- [KMAC](./hw/ip/kmac/README.md)
- [Design Verification](./hw/ip/kmac/dv/README.md)
+ - [Interface and Registers](./hw/ip/kmac/data/kmac.hjson)
- [Checklist](./hw/ip/kmac/doc/checklist.md)
- [Life Cycle Controller](./hw/ip/lc_ctrl/README.md)
- [Design Verification](./hw/ip/lc_ctrl/dv/README.md)
+ - [Interface and Registers](./hw/ip/lc_ctrl/data/lc_ctrl.hjson)
- [Checklist](./hw/ip/lc_ctrl/doc/checklist.md)
- [OTP Controller](./hw/ip/otp_ctrl/README.md)
- [Design Verification](./hw/ip/otp_ctrl/dv/README.md)
+ - [Interface and Registers](./hw/ip/otp_ctrl/data/otp_ctrl.hjson)
- [Checklist](./hw/ip/otp_ctrl/doc/checklist.md)
- [Pattern Generator](./hw/ip/pattgen/README.md)
- [Design Verification](./hw/ip/pattgen/dv/README.md)
+ - [Interface and Registers](./hw/ip/pattgen/data/pattgen.hjson)
- [Checklist](./hw/ip/pattgen/doc/checklist.md)
- [Pinmux](./hw/ip/pinmux/README.md)
- [Design Verification](./hw/ip/pinmux/doc/dv/README.md)
+ - [Interface and Registers](./hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson)
- [Checklist](./hw/ip/pinmux/doc/checklist.md)
- [Pulse Width Modulator](./hw/ip/pwm/README.md)
- [Design Verification](./hw/ip/pwm/dv/README.md)
+ - [Interface and Registers](./hw/ip/pwm/data/pwm.hjson)
- [Checklist](./hw/ip/pwm/doc/checklist.md)
- [Power Management](./hw/ip/pwrmgr/README.md)
- [Design Verification](./hw/ip/pwrmgr/dv/README.md)
+ - [Interface and Registers](./hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson)
- [Checklist](./hw/ip/pwrmgr/doc/checklist.md)
- [ROM Control](./hw/ip/rom_ctrl/README.md)
- [Design Verification](./hw/ip/rom_ctrl/dv/README.md)
+ - [Interface and Registers](./hw/ip/rom_ctrl/data/rom_ctrl.hjson)
- [Checklist](./hw/ip/rom_ctrl/doc/checklist.md)
- [Reset Manager](./hw/ip/rstmgr/README.md)
- [Design Verification](./hw/ip/rstmgr/dv/README.md)
+ - [Interface and Registers](./hw/top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson)
- [Checklist](./hw/ip/rstmgr/doc/checklist.md)
- [RISC-V Debug Manager](./hw/ip/rv_dm/README.md)
- [Design Verification](./hw/ip/rv_dm/dv/README.md)
+ - [Interface and Registers](./hw/ip/rv_dm/data/rv_dm.hjson)
- [Checklist](./hw/ip/rv_dm/doc/checklist.md)
- [SPI Device](./hw/ip/spi_device/README.md)
- [Design Verification](./hw/ip/spi_device/dv/README.md)
+ - [Interface and Registers](./hw/ip/spi_device/data/spi_device.hjson)
- [Checklist](./hw/ip/spi_device/doc/checklist.md)
- [SPI Host](./hw/ip/spi_host/README.md)
- [Design Verification](./hw/ip/spi_host/dv/README.md)
+ - [Interface and Registers](./hw/ip/spi_host/data/spi_host.hjson)
- [Checklist](./hw/ip/spi_host/doc/checklist.md)
- [SRAM Controller](./hw/ip/sram_ctrl/README.md)
- [Design Verification](./hw/ip/sram_ctrl/dv/README.md)
+ - [Interface and Registers](./hw/ip/sram_ctrl/data/sram_ctrl.hjson)
- [Checklist](./hw/ip/sram_ctrl/doc/checklist.md)
- [System Reset Controller](./hw/ip/sysrst_ctrl/README.md)
- [Design Verification](./hw/ip/sysrst_ctrl/dv/README.md)
+ - [Interface and Registers](./hw/ip/sysrst_ctrl/data/sysrst_ctrl.hjson)
- [Checklist](./hw/ip/sysrst_ctrl/doc/checklist.md)
- [Timer](./hw/ip/rv_timer/README.md)
- [Design Verification](./hw/ip/rv_timer/dv/README.md)
+ - [Interface and Registers](./hw/ip/rv_timer/data/rv_timer.hjson)
- [Checklist](./hw/ip/rv_timer/doc/checklist.md)
- [TL-UL Bus](./hw/ip/tlul/README.md)
- [Design Verification](./hw/ip/tlul/doc/dv/README.md)
- [Protocol Checker](./hw/ip/tlul/doc/TlulProtocolChecker.md)
- [UART](./hw/ip/uart/README.md)
- [Design Verification](./hw/ip/uart/dv/README.md)
+ - [Interface and Registers](./hw/ip/uart/data/uart.hjson)
- [Checklist](./hw/ip/uart/doc/checklist.md)
- [USB 2.0](./hw/ip/usbdev/README.md)
- [Design Verification](./hw/ip/usbdev/dv/README.md)
- [Suspending and Resuming](./hw/ip/usbdev/doc/wake_resume.md)
+ - [Interface and Registers](./hw/ip/usbdev/data/usbdev.hjson)
- [Checklist](./hw/ip/usbdev/doc/checklist.md)
- [lowRISC Hardware Primitives](./hw/ip/prim/README.md)
- [Two Input Clock](./hw/ip/prim/doc/prim_clock_gp_mux2.md)
diff --git a/hw/ip/adc_ctrl/README.md b/hw/ip/adc_ctrl/README.md
index aff9d8a..4ebcd1b 100644
--- a/hw/ip/adc_ctrl/README.md
+++ b/hw/ip/adc_ctrl/README.md
@@ -38,7 +38,7 @@
## Hardware Interface
-{{< incGenFromIpDesc "../data/adc_ctrl.hjson" "hwcfg" >}}
+* [Interface Tables](data/adc_ctrl.hjson#interfaces)
### Signals
@@ -58,21 +58,21 @@
1. *Power up ADC*: The controller issues the power up command to the ADC.
-2. *Wait for ADC turn on*: The controller waits for the number of clock cycles programmed in {{< regref "adc_pd_ctl.pwrup_time" >}} which should be set to match the ADC power up delay.
+2. *Wait for ADC turn on*: The controller waits for the number of clock cycles programmed in {{#regref adc_ctrl.adc_pd_ctl.pwrup_time }} which should be set to match the ADC power up delay.
3. *Take sample Channel 0*: The ADC is requested to sample channel 0.
-When the ADC signals complete the value is stored in {{< regref "adc_chn_val[0].adc_chn_value" >}}.
+When the ADC signals complete the value is stored in {{#regref adc_ctrl.adc_chn_val[0].adc_chn_value }}.
Note that the time taken in this step depends on the properties of the ADC.
4. *Take sample Channel 1*: The ADC is requested to sample channel 1.
-When the ADC signals complete the value is stored in {{< regref "adc_chn_val[1].adc_chn_value" >}}.
+When the ADC signals complete the value is stored in {{#regref adc_ctrl.adc_chn_val[1].adc_chn_value }}.
Note that the time taken in this step depends on the properties of the ADC.
5. *Evaluate Filters*: The filters are evaluated and debounce logic applied (see [next section](#filters-and-debounce)).
-6. *Scan type check*: At this point if the {{< regref "adc_pd_ctl.lp_mode" >}} bit is clear scanning continues at step (3).
+6. *Scan type check*: At this point if the {{#regref adc_ctrl.adc_pd_ctl.lp_mode }} bit is clear scanning continues at step (3).
If the bit is set the next step depends on how many samples have hit the filters.
- If more than {{< regref "adc_lp_sample_ctl.lp_sample_cnt" >}} samples have hit then continuous scanning continues at step (3) else periodic scanning will continue at the next step (7).
+ If more than {{#regref adc_ctrl.adc_lp_sample_ctl.lp_sample_cnt }} samples have hit then continuous scanning continues at step (3) else periodic scanning will continue at the next step (7).
7. *Power off ADC*: The controller issues the power down command to the ADC.
@@ -81,21 +81,21 @@
In active operation the controller is in continuous scanning mode:
* The ADC is continually powered on.
* The sampling cycle time is the time taken for the ADC to take two samples (450us) plus internal processing time (4 clock cycles) from the ADC controller.
-* The debounce timer will trigger the {{< regref "filter_status" >}} and interrupt after a configurable number of matching ADC samples have been seen, as determined by {{< regref "adc_sample_ctl" >}}.
+* The debounce timer will trigger the {{#regref adc_ctrl.filter_status }} and interrupt after a configurable number of matching ADC samples have been seen, as determined by {{#regref adc_ctrl.adc_sample_ctl }}.
For low power operation the periodic scanning mode can be used.
In this mode samples are taken using a slower periodic sampling cycle time with the ADC powered down most of the time.
Once a small number of cycles have hit the filter with periodic scanning then the controller switches to continuous scanning in order to more accurately debounce the signal.
In low power mode:
-* The ADC is periodically powered up to take samples; this interval is determined by {{< regref "adc_pd_ctl.wakeup_time" >}}.
-* Similar to normal operation, the ADC power-up delay is controlled by {{< regref "adc_pd_ctl.pwrup_time" >}}.
+* The ADC is periodically powered up to take samples; this interval is determined by {{#regref adc_ctrl.adc_pd_ctl.wakeup_time }}.
+* Similar to normal operation, the ADC power-up delay is controlled by {{#regref adc_ctrl.adc_pd_ctl.pwrup_time }}.
* Once the ADC is powered up, two samples are taken and compared to the filter thresholds.
-* If a configurable number of matches, as determined by {{< regref "adc_lp_sample_ctl" >}}, are seen, the ADC controller transitions to normal operation for continuous sampling.
+* If a configurable number of matches, as determined by {{#regref adc_ctrl.adc_lp_sample_ctl }}, are seen, the ADC controller transitions to normal operation for continuous sampling.
Although it can be used at any time, the periodic operation mode and use of the slow clock allows the ADC controller to continue to scan when most of the chip is in sleep or power-down modes.
The controller can be configured to issue a wakeup to the rest of the chip.
-If a filter is enabled for wakeup in {{< regref "adc_wakeup_ctl" >}} and {{< regref "filter_status" >}} indicates a match, a wakeup is generated to the system power manager.
+If a filter is enabled for wakeup in {{#regref adc_ctrl.adc_wakeup_ctl }} and {{#regref adc_ctrl.filter_status }} indicates a match, a wakeup is generated to the system power manager.
## Filters and debounce
@@ -121,34 +121,34 @@
* Inside `min=0`, `max=0xFFF`: any value will hit. This may be useful to exclude one channel from the filter.
* Outside `min=0`, `max=0xFFF`: no value will hit. If set for either channel the filter is effectively disabled.
-All pairs of filters that are enabled in {{< regref "adc_chn0_filter_ctl[7:0]" >}} and {{< regref "adc_chn1_filter_ctl[7:0]" >}} are evaluated after each pair of samples has been taken.
+All pairs of filters that are enabled in {{#regref adc_ctrl.adc_chn0_filter_ctl[7:0] }} and {{#regref adc_ctrl.adc_chn1_filter_ctl[7:0] }} are evaluated after each pair of samples has been taken.
The filter result is passed to the periodic scan counter if enabled and not at its limit otherwise the result is passed to the debounce counter.
The list below describes how the counters interpret the filter results:
* If no filters are hit then the counter will reset to zero.
* If one or more filters are hit but the set hit differs from the previous evaluation the counter resets to zero.
* If one or more filters are hit and either none was hit in the previous evaluation or the same set was hit in the previous evaluation and the counter is not at its threshold then the counter will increment.
* If one or more filters are hit and the same set was hit in the previous evaluation and the counter is at its threshold then the counter stays at the threshold.
-* If the counter is the periodic scan counter and it reaches its threshold, as defined by {{< regref "adc_lp_sample_ctl.lp_sample_cnt" >}}, then continuous scanning is enabled and the debounce counter will be used for future evaluations.
-* If the counter is the debounce counter and it reaches its threshold, as defined by {{< regref "adc_sample_ctl.np_sample_cnt" >}}, then:
+* If the counter is the periodic scan counter and it reaches its threshold, as defined by {{#regref adc_ctrl.adc_lp_sample_ctl.lp_sample_cnt }}, then continuous scanning is enabled and the debounce counter will be used for future evaluations.
+* If the counter is the debounce counter and it reaches its threshold, as defined by {{#regref adc_ctrl.adc_sample_ctl.np_sample_cnt }}, then:
* An interrupt is raised if the threshold is met for the first time.
- * The current sample values are latched into {{< regref "adc_chn_val[0].adc_chn_value_intr" >}} and {{< regref "adc_chn_val[1].adc_chn_value_intr" >}}.
+ * The current sample values are latched into {{#regref adc_ctrl.adc_chn_val[0].adc_chn_value_intr }} and {{#regref adc_ctrl.adc_chn_val[1].adc_chn_value_intr }}.
* If a series of interrupts and matches are seen, these registers only record the value of the last debounced hit.
- * The {{< regref adc_intr_status >}} register is updated by setting the bits corresponding to filters that are hit (note that bits that are already set will not be cleared).
+ * The {{#regref adc_ctrl.adc_intr_status }} register is updated by setting the bits corresponding to filters that are hit (note that bits that are already set will not be cleared).
This will cause the block to raise an interrupt if it was not already doing so.
- * If a filter is a hit and is also enabled in {{< regref "adc_wakeup_ctl" >}} the corresponding filter generates a wakeup.
+ * If a filter is a hit and is also enabled in {{#regref adc_ctrl.adc_wakeup_ctl }} the corresponding filter generates a wakeup.
* Note that the debounce counter will remain at its threshold until the set of filters are changed by software to debounce a different event or if the current match changes.
- * This implies that a stable matching event continuously matches until some condition in the system (changed filter settings, changed ADC output, software issued fsm reset in {{< regref "adc_fsm_rst" >}}) alters the result.
+ * This implies that a stable matching event continuously matches until some condition in the system (changed filter settings, changed ADC output, software issued fsm reset in {{#regref adc_ctrl.adc_fsm_rst }}) alters the result.
-Because scanning continues the {{< regref "adc_intr_status" >}} register will reflect any debounced events that are detected between the controller raising an interrupt and the status bits being cleared (by having 1 written to them).
-However, the {{< regref "adc_chn_val[0].adc_chn_value_intr" >}} and {{< regref "adc_chn_val[1].adc_chn_value_intr" >}} registers record the value at the time the interrupt was first raised and thus reflect the filter state from that point.
+Because scanning continues the {{#regref adc_ctrl.adc_intr_status }} register will reflect any debounced events that are detected between the controller raising an interrupt and the status bits being cleared (by having 1 written to them).
+However, the {{#regref adc_ctrl.adc_chn_val[0].adc_chn_value_intr }} and {{#regref adc_ctrl.adc_chn_val[1].adc_chn_value_intr }} registers record the value at the time the interrupt was first raised and thus reflect the filter state from that point.
### ADC_CTRL and ADC Interface
The interface between the ADC controller and the ADC is diagrammed below.
The interface is from the perspective of the ADC controller.
Before operation can begin, the ADC controller first powers on the ADC by setting `adc_o.pd` to 0.
-The controller then waits for the ADC to fully power up, as determined by {{< regref "adc_pd_ctl.pwrup_time" >}}.
+The controller then waits for the ADC to fully power up, as determined by {{#regref adc_ctrl.adc_pd_ctl.pwrup_time }}.
Once the ADC is ready to go, the controller then selects the channel it wishes to sample by setting `adc_o.channel_sel`.
The controller holds this value until the ADC responds with `adc_i.data_valid` and `adc_i.data`.
@@ -175,33 +175,33 @@
## Initialization
The controller should be initialized with the properties of the ADC and scan times.
-* The ADC power up delay must be set in {{< regref "adc_pd_ctl.pwrup_time" >}}.
-* The time to delay between samples in a slow scan should be set in {{< regref "adc_pd_ctl.wakeup_time" >}}.
-* The number of samples to cause transition from slow to fast scan should be set in {{< regref "adc_lp_sample_ctl" >}}.
-* The number of samples for debounce should be set in {{< regref "adc_sample_ctl" >}}.
-* The filter registers {{< regref "adc_chnX_filter_ctlN" >}} should be programmed.
-* The interrupt {{< regref "adc_intr_ctl" >}} and wakeup {{< regref "adc_wakeup_ctl" >}} enables should be configured.
-* All ones should be written to {{< regref "adc_intr_status" >}} and {{< regref "filter_status" >}} to ensure there are no spurious pending triggers.
-* Optionally, the low-power mode should be set in {{< regref "adc_pd_ctl.lp_mode" >}} if the system is going to the low-power mode.
-* The state machine will only start running when {{< regref "adc_en_ctl" >}} is set.
+* The ADC power up delay must be set in {{#regref adc_ctrl.adc_pd_ctl.pwrup_time }}.
+* The time to delay between samples in a slow scan should be set in {{#regref adc_ctrl.adc_pd_ctl.wakeup_time }}.
+* The number of samples to cause transition from slow to fast scan should be set in {{#regref adc_ctrl.adc_lp_sample_ctl }}.
+* The number of samples for debounce should be set in {{#regref adc_ctrl.adc_sample_ctl }}.
+* The filter registers {{#regref adc_ctrl.adc_chnX_filter_ctlN }} should be programmed.
+* The interrupt {{#regref adc_ctrl.adc_intr_ctl }} and wakeup {{#regref adc_ctrl.adc_wakeup_ctl }} enables should be configured.
+* All ones should be written to {{#regref adc_ctrl.adc_intr_status }} and {{#regref adc_ctrl.filter_status }} to ensure there are no spurious pending triggers.
+* Optionally, the low-power mode should be set in {{#regref adc_ctrl.adc_pd_ctl.lp_mode }} if the system is going to the low-power mode.
+* The state machine will only start running when {{#regref adc_ctrl.adc_en_ctl }} is set.
## Running in normal mode
-If fast sampling is always required then the {{< regref "adc_pd_ctl.lp_mode" >}} bit should be clear.
-In this case the values in the {{< regref "adc_lp_sample_ctl" >}} are not used.
+If fast sampling is always required then the {{#regref adc_ctrl.adc_pd_ctl.lp_mode }} bit should be clear.
+In this case the values in the {{#regref adc_ctrl.adc_lp_sample_ctl }} are not used.
The ADC will always be enabled and consuming power.
-If power saving is required then the controller can be set to operate in low power mode by setting {{< regref "adc_pd_ctl.lp_mode" >}}.
-The {{< regref "adc_lp_sample_ctl" >}} must be programmed prior to setting this bit.
+If power saving is required then the controller can be set to operate in low power mode by setting {{#regref adc_ctrl.adc_pd_ctl.lp_mode }}.
+The {{#regref adc_ctrl.adc_lp_sample_ctl }} must be programmed prior to setting this bit.
## Running with the rest of the chip in sleep
Once programmed the controller and ADC can run when the rest of the chip is in low power state and the main clocks are stopped.
This allows the chip to be woken when appropriate values are detected on the two ADC channels.
The fast sampling mode can be used but will usually consume more power than desired when the chip is in sleep.
-So it is expected that {{< regref "adc_lp_sample_ctl" >}} is configured and low power mode enabled by setting {{< regref "adc_pd_ctl.lp_mode" >}} prior to the sleep being initiated.
+So it is expected that {{#regref adc_ctrl.adc_lp_sample_ctl }} is configured and low power mode enabled by setting {{#regref adc_ctrl.adc_pd_ctl.lp_mode }} prior to the sleep being initiated.
-If the ADC wakeup is not required then the controller and ADC should both be disabled by clearing {{< regref "adc_en_ctl" >}} prior to the sleep being initiated.
+If the ADC wakeup is not required then the controller and ADC should both be disabled by clearing {{#regref adc_ctrl.adc_en_ctl }} prior to the sleep being initiated.
## Use Case
@@ -229,12 +229,12 @@
* The ADC takes a single sample in 44 clocks (220 us)
The controller should be initialized with the properties of the ADC and scan times.
-* The ADC power up delay must be set in {{< regref "adc_pd_ctl.pwrup_time" >}} to `6` (30 us).
-* The time to delay between samples in a slow scan should be set in {{< regref "adc_pd_ctl.wakeup_time" >}} to `1600` (8ms).
-* The number of samples to cause transition from slow to fast scan should be set in {{< regref "adc_lp_sample_ctl" >}} to `4` (causing slow scan to be 4*8ms = 32ms of debounce time).
-* The number of samples for debounce should be set in {{< regref "adc_sample_ctl" >}} to `155` (causing the total debounce time to be 32ms (slow scan) + 220us * 2 * 155 = 100ms, at the low end of the USB-C spec window).
+* The ADC power up delay must be set in {{#regref adc_ctrl.adc_pd_ctl.pwrup_time }} to `6` (30 us).
+* The time to delay between samples in a slow scan should be set in {{#regref adc_ctrl.adc_pd_ctl.wakeup_time }} to `1600` (8ms).
+* The number of samples to cause transition from slow to fast scan should be set in {{#regref adc_ctrl.adc_lp_sample_ctl }} to `4` (causing slow scan to be 4*8ms = 32ms of debounce time).
+* The number of samples for debounce should be set in {{#regref adc_ctrl.adc_sample_ctl }} to `155` (causing the total debounce time to be 32ms (slow scan) + 220us * 2 * 155 = 100ms, at the low end of the USB-C spec window).
-* For the 10-bit ADC granularity, the filter registers {{< regref "adc_chnX_filter_ctlN" >}} should be programmed to:
+* For the 10-bit ADC granularity, the filter registers {{#regref adc_ctrl.adc_chnX_filter_ctlN }} should be programmed to:
| Filter | Ch0 Min | Ch0 Max | Ch1 Min | Ch1 Max | Device connected |
|--------|--------------|--------------|--------------|--------------|-----------------------------|
@@ -248,9 +248,9 @@
| 7 OUT | 116 (0.25V) | 954 (2.05V) | 116 (0.25V) | 954 (2.05V) | Disconnect |
-* The interrupt {{< regref "adc_intr_ctl" >}} and wakeup {{< regref "adc_wakeup_ctl" >}} enables should be configured.
-* All ones should be written to {{< regref "adc_intr_status" >}} and {{< regref "filter_status" >}} to ensure there are no spurious pending triggers.
-* The state machine will only start running when {{< regref "adc_en_ctl" >}} is set.
+* The interrupt {{#regref adc_ctrl.adc_intr_ctl }} and wakeup {{#regref adc_ctrl.adc_wakeup_ctl }} enables should be configured.
+* All ones should be written to {{#regref adc_ctrl.adc_intr_status }} and {{#regref adc_ctrl.filter_status }} to ensure there are no spurious pending triggers.
+* The state machine will only start running when {{#regref adc_ctrl.adc_en_ctl }} is set.
Note that for the debug controller (DTS in USB-C specification) as a power source the filter that is hit will indicate the orientation of the connector.
If the debug controller is acting as a power sink then the orientation cannot be known unless the debug controller supports the optional behavior of converting one of its pulldowns to an Ra (rather than Rp) to indicate CC2 (the CC that is not used for communication).
@@ -262,4 +262,4 @@
## Registers
-{{< incGenFromIpDesc "../data/adc_ctrl.hjson" "registers" >}}
+* [Register Table](data/adc_ctrl.hjson#registers)
diff --git a/hw/ip/aes/README.md b/hw/ip/aes/README.md
index 798e32e..077b910 100644
--- a/hw/ip/aes/README.md
+++ b/hw/ip/aes/README.md
@@ -78,8 +78,8 @@
The order in which the input registers are written does not matter.
Every input register must be written at least once for the AES unit to automatically start encryption/decryption.
This is the default behavior.
-It can be disabled by setting the MANUAL_OPERATION bit in {{< regref "CTRL_SHADOWED" >}} to `1`.
-In this case, the AES unit only starts the encryption/decryption once the START bit in {{< regref "TRIGGER" >}} is set to `1` (automatically cleared to `0` once the next encryption/decryption is started).
+It can be disabled by setting the MANUAL_OPERATION bit in {{#regref aes.CTRL_SHADOWED }} to `1`.
+In this case, the AES unit only starts the encryption/decryption once the START bit in {{#regref aes.TRIGGER }} is set to `1` (automatically cleared to `0` once the next encryption/decryption is started).
Similarly, the AES unit indicates via a status register when having new output data available to be read by the processor.
Also, there is a back-pressure mechanism for the output data.
@@ -89,7 +89,7 @@
The order in which the output registers are read does not matter.
Every output register must be read at least once for the AES unit to continue.
This is the default behavior.
-It can be disabled by setting the MANUAL_OPERATION bit in {{< regref "CTRL_SHADOWED" >}} to `1`.
+It can be disabled by setting the MANUAL_OPERATION bit in {{#regref aes.CTRL_SHADOWED }} to `1`.
In this case, the AES unit never stalls and just overwrites previous output data, independent of whether it has been read or not.
@@ -120,7 +120,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/aes.hjson" "hwcfg" >}}
+* [Interface Tables](data/aes.hjson#interfaces)
The table below lists other signals of the AES unit.
@@ -159,7 +159,7 @@
For a general introduction into these cipher modes, refer to [Recommendation for Block Cipher Modes of Operation](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf).
1. The configuration and initial key is provided to the AES unit via a set of control and status registers (CSRs) accessible by the processor via TL-UL bus interface.
- The processor must first provide the configuration to the {{< regref "CTRL_SHADOWED" >}} register.
+ The processor must first provide the configuration to the {{#regref aes.CTRL_SHADOWED }} register.
Then follows the initial key.
Each key register must be written at least once.
The order in which the registers are written does not matter.
@@ -186,8 +186,8 @@
The IV is ready if -- since the last IV update (either done by the processor or the AES unit itself) -- all IV registers have been written at least once or none of them.
The AES unit will not automatically start the next encryption/decryption with a partially updated IV._
- By setting the MANUAL_OPERATION bit in {{< regref "CTRL_SHADOWED" >}} to `1`, the AES unit can be operated in manual mode.
- In manual mode, the AES unit starts encryption/decryption whenever the START bit in {{< regref "TRIGGER" >}} is set to `1`, irrespective of the status of the IV and input data registers.
+ By setting the MANUAL_OPERATION bit in {{#regref aes.CTRL_SHADOWED }} to `1`, the AES unit can be operated in manual mode.
+ In manual mode, the AES unit starts encryption/decryption whenever the START bit in {{#regref aes.TRIGGER }} is set to `1`, irrespective of the status of the IV and input data registers.
1. Once the State and Full Key registers have been loaded, the AES cipher core starts the encryption/decryption by adding the first round key to the initial state (all blocks in both data paths are bypassed).
The result is stored back in the State register.
@@ -324,10 +324,10 @@
The processor writes both input data as well as the initial key to dedicated registers via the system bus interconnect.
Alternatively, the processor can configure the AES unit to use an initial key provided by the [key manager](../keymgr/README.md) via key sideload interface without exposing the key to the processor or other hosts attached to the system bus interconnect.
-To this end, the processor has to set the SIDELOAD bit in {{< regref "CTRL_SHADOWED" >}} to `1`.
-Any write operations of the processor to the Initial Key registers {{< regref "KEY_SHARE0_0" >}} - {{< regref "KEY_SHARE1_7" >}} are then ignored.
+To this end, the processor has to set the SIDELOAD bit in {{#regref aes.CTRL_SHADOWED }} to `1`.
+Any write operations of the processor to the Initial Key registers {{#regref aes.KEY_SHARE0_0 }} - {{#regref aes.KEY_SHARE1_7 }} are then ignored.
In normal/automatic mode, the AES unit only starts encryption/decryption if the sideload key is marked as valid.
-To update the sideload key, the processor has to 1) wait for the AES unit to become idle, 2) wait for the key manager to update the sideload key and assert the valid signal, and 3) write to the {{< regref "CTRL_SHADOWED" >}} register to start a new message.
+To update the sideload key, the processor has to 1) wait for the AES unit to become idle, 2) wait for the key manager to update the sideload key and assert the valid signal, and 3) write to the {{#regref aes.CTRL_SHADOWED }} register to start a new message.
After using a sideload key, the processor has to trigger the clearing of all key registers inside the AES unit (see [De-Initialization](#de-initialization) below).
@@ -364,9 +364,9 @@
These are fully combinational (one S-Box evaluation every cycle) and have lower area footprint, but they are significantly less resistant to SCA.
They are mainly included for reference but their usage is discouraged due to potential vulnerabilities to the correlation-enhanced collision attack as described by [Moradi et al.: "Correlation-Enhanced Power Analysis Collision Attack".](https://eprint.iacr.org/2010/297.pdf)
-The masking PRNG is reseeded with fresh entropy via [EDN](../edn/README.md) automatically 1) whenever a new key is provided (see {{< regref "CTRL_AUX_SHADOWED.KEY_TOUCH_FORCES_RESEED" >}}) and 2) based on a block counter.
-The rate at which this block counter initiates automatic reseed operations can be configured via {{< regref "CTRL_SHADOWED.PRNG_RESEED_RATE" >}}.
-In addition software can manually initiate a reseed operation via {{< regref "TRIGGER.PRNG_RESEED" >}}.
+The masking PRNG is reseeded with fresh entropy via [EDN](../edn/README.md) automatically 1) whenever a new key is provided (see {{#regref aes.CTRL_AUX_SHADOWED.KEY_TOUCH_FORCES_RESEED }}) and 2) based on a block counter.
+The rate at which this block counter initiates automatic reseed operations can be configured via {{#regref aes.CTRL_SHADOWED.PRNG_RESEED_RATE }}.
+In addition software can manually initiate a reseed operation via {{#regref aes.TRIGGER.PRNG_RESEED }}.
Note that the masking can be enabled/disabled via compile-time Verilog parameter.
It may be acceptable to disable the masking when using the AES cipher core for random number generation e.g. inside [CSRNG.](../csrng/README.md)
@@ -447,7 +447,7 @@
If any of these countermeasures detects a fault, a fatal alert is triggered, the internal FSMs go into a terminal error state, the AES unit does not release further data and locks up until reset.
Since the AES unit has no ability to reset itself, a system-supplied reset is required before the AES unit can become operational again.
-Such a condition is reported in {{< regref "STATUS.ALERT_FATAL_FAULT" >}}.
+Such a condition is reported in {{#regref aes.STATUS.ALERT_FATAL_FAULT }}.
Details on where the fault has been detected are not provided.
### Data Path
@@ -464,32 +464,32 @@
## Clear upon Reset
Upon reset, the AES unit will first reseed the internal PRNGs for register clearing and masking via EDN, and then clear all key, IV and data registers with pseudo-random data.
-Only after this sequence has finished, the unit becomes idle (indicated in {{< regref "STATUS.IDLE" >}}).
+Only after this sequence has finished, the unit becomes idle (indicated in {{#regref aes.STATUS.IDLE }}).
The AES unit is then ready for software initialization.
Note that at this point, the key, IV and data registers' values can no longer be expected to match the reset values.
## Initialization
-Before initialization, software must ensure that the AES unit is idle by checking {{< regref "STATUS.IDLE" >}}.
-If the AES unit is not idle, write operations to {{< regref "CTRL_SHADOWED" >}}, the Initial Key registers {{< regref "KEY_SHARE0_0" >}} - {{< regref "KEY_SHARE1_7" >}} and initialization vector (IV) registers {{< regref "IV_0" >}} - {{< regref "IV_3" >}} are ignored.
+Before initialization, software must ensure that the AES unit is idle by checking {{#regref aes.STATUS.IDLE }}.
+If the AES unit is not idle, write operations to {{#regref aes.CTRL_SHADOWED }}, the Initial Key registers {{#regref aes.KEY_SHARE0_0 }} - {{#regref aes.KEY_SHARE1_7 }} and initialization vector (IV) registers {{#regref aes.IV_0 }} - {{#regref aes.IV_3 }} are ignored.
-To initialize the AES unit, software must first provide the configuration to the {{< regref "CTRL_SHADOWED" >}} register.
+To initialize the AES unit, software must first provide the configuration to the {{#regref aes.CTRL_SHADOWED }} register.
Since writing this register may initiate the reseeding of the internal PRNGs, software must check that the AES unit is idle before providing the initial key.
-Then software must write the initial key to the Initial Key registers {{< regref "KEY_SHARE0_0" >}} - {{< regref "KEY_SHARE1_7" >}}.
+Then software must write the initial key to the Initial Key registers {{#regref aes.KEY_SHARE0_0 }} - {{#regref aes.KEY_SHARE1_7 }}.
The key is provided in two shares:
-The first share is written to {{< regref "KEY_SHARE0_0" >}} - {{< regref "KEY_SHARE0_7" >}} and the second share is written to {{< regref "KEY_SHARE1_0" >}} - {{< regref "KEY_SHARE1_7" >}}.
-The actual initial key used for encryption corresponds to the value obtained by XORing {{< regref "KEY_SHARE0_0" >}} - {{< regref "KEY_SHARE0_7" >}} with {{< regref "KEY_SHARE1_0" >}} - {{< regref "KEY_SHARE1_7" >}}.
+The first share is written to {{#regref aes.KEY_SHARE0_0 }} - {{#regref aes.KEY_SHARE0_7 }} and the second share is written to {{#regref aes.KEY_SHARE1_0 }} - {{#regref aes.KEY_SHARE1_7 }}.
+The actual initial key used for encryption corresponds to the value obtained by XORing {{#regref aes.KEY_SHARE0_0 }} - {{#regref aes.KEY_SHARE0_7 }} with {{#regref aes.KEY_SHARE1_0 }} - {{#regref aes.KEY_SHARE1_7 }}.
Note that all registers are little-endian.
-The key length is configured using the KEY_LEN field of {{< regref "CTRL_SHADOWED" >}}.
+The key length is configured using the KEY_LEN field of {{#regref aes.CTRL_SHADOWED }}.
Independent of the selected key length, software must always write all 8 32-bit registers of both shares.
Each register must be written at least once.
The order in which the key registers are written does not matter.
Anything can be written to the unused key registers of both shares, however, random data is preferred.
-For AES-128 ,the actual initial key used for encryption is formed by XORing {{< regref "KEY_SHARE0_0" >}} - {{< regref "KEY_SHARE0_3" >}} with {{< regref "KEY_SHARE1_0" >}} - {{< regref "KEY_SHARE1_3" >}}.
-For AES-192, the actual initial key used for encryption is formed by XORing {{< regref "KEY_SHARE0_0" >}} - {{< regref "KEY_SHARE0_5" >}} with {{< regref "KEY_SHARE1_0" >}} - {{< regref "KEY_SHARE1_5" >}}.
+For AES-128 ,the actual initial key used for encryption is formed by XORing {{#regref aes.KEY_SHARE0_0 }} - {{#regref aes.KEY_SHARE0_3 }} with {{#regref aes.KEY_SHARE1_0 }} - {{#regref aes.KEY_SHARE1_3 }}.
+For AES-192, the actual initial key used for encryption is formed by XORing {{#regref aes.KEY_SHARE0_0 }} - {{#regref aes.KEY_SHARE0_5 }} with {{#regref aes.KEY_SHARE1_0 }} - {{#regref aes.KEY_SHARE1_5 }}.
-If running in CBC, CFB, OFB or CTR mode, software must also write the IV registers {{< regref "IV_0" >}} - {{< regref "IV_3" >}}.
+If running in CBC, CFB, OFB or CTR mode, software must also write the IV registers {{#regref aes.IV_0 }} - {{#regref aes.IV_3 }}.
Since providing the initial key initiate the reseeding of the internal PRNGs, software must check that the AES unit is idle before writing the IV registers.
These registers are little-endian, but the increment of the IV in CTR mode is big-endian (see [Recommendation for Block Cipher Modes of Operation](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf)).
Each IV register must be written at least once.
@@ -501,30 +501,30 @@
For block operation, software must initialize the AES unit as described in the previous section.
In particular, the AES unit must be configured to run in normal/automatic mode.
-This is indicated by the MANUAL_OPERATION bit in {{< regref "CTRL_SHADOWED" >}} reading as `0`.
+This is indicated by the MANUAL_OPERATION bit in {{#regref aes.CTRL_SHADOWED }} reading as `0`.
It ensures that the AES unit:
1. Automatically starts encryption/decryption when new input data is available.
1. Does not overwrite previous output data that has not yet been read by the processor.
Then, software must:
-1. Ensure that the INPUT_READY bit in {{< regref "STATUS" >}} is `1`.
-1. Write Input Data Block `0` to the Input Data registers {{< regref "DATA_IN_0" >}} - {{< regref "DATA_IN_3" >}}.
+1. Ensure that the INPUT_READY bit in {{#regref aes.STATUS }} is `1`.
+1. Write Input Data Block `0` to the Input Data registers {{#regref aes.DATA_IN_0 }} - {{#regref aes.DATA_IN_3 }}.
Each register must be written at least once.
The order in which these registers are written does not matter.
-1. Wait for the INPUT_READY bit in {{< regref "STATUS" >}} to become `1`, i.e. wait for the AES unit to load Input Data Block `0` into the internal state register and start operation.
+1. Wait for the INPUT_READY bit in {{#regref aes.STATUS }} to become `1`, i.e. wait for the AES unit to load Input Data Block `0` into the internal state register and start operation.
1. Write Input Data Block `1` to the Input Data registers.
Then for every Data Block `I=0,..,N-3`, software must:
-1. Wait for the OUTPUT_VALID bit in {{< regref "STATUS" >}} to become `1`, i.e., wait for the AES unit to finish encryption/decryption of Block `I`.
+1. Wait for the OUTPUT_VALID bit in {{#regref aes.STATUS }} to become `1`, i.e., wait for the AES unit to finish encryption/decryption of Block `I`.
The AES unit then directly starts processing the previously input block `I+1`
-2. Read Output Data Block `I` from the Output Data registers {{< regref "DATA_OUT_0" >}} - {{< regref "DATA_OUT_3" >}}.
+2. Read Output Data Block `I` from the Output Data registers {{#regref aes.DATA_OUT_0 }} - {{#regref aes.DATA_OUT_3 }}.
Each register must be read at least once.
The order in which these registers are read does not matter.
3. Write Input Data Block `I+2` into the Input Data register.
There is no need to explicitly check INPUT_READY as in the same cycle OUTPUT_VALID becomes `1`, the current input is loaded in (meaning INPUT_READY becomes `1` one cycle later).
Once all blocks have been input, the final data blocks `I=N-2,N-1` must be read out:
-1. Wait for the OUTPUT_VALID bit in {{< regref "STATUS" >}} to become `1`, i.e., wait for the AES unit to finish encryption/decryption of Block `I`.
+1. Wait for the OUTPUT_VALID bit in {{#regref aes.STATUS }} to become `1`, i.e., wait for the AES unit to finish encryption/decryption of Block `I`.
2. Read Output Data Block `I` from the Output Data register.
Note that interrupts are not provided, the latency of the AES unit is such that they are of little utility.
@@ -592,7 +592,7 @@
## Padding
-For the AES unit to automatically start encryption/decryption of the next data block, software is required to always update all four Input Data registers {{< regref "DATA_IN_0" >}} - {{< regref "DATA_IN_3" >}} and read all four Output Data registers {{< regref "DATA_OUT_0" >}} - {{< regref "DATA_OUT_3" >}}.
+For the AES unit to automatically start encryption/decryption of the next data block, software is required to always update all four Input Data registers {{#regref aes.DATA_IN_0 }} - {{#regref aes.DATA_IN_3 }} and read all four Output Data registers {{#regref aes.DATA_OUT_0 }} - {{#regref aes.DATA_OUT_3 }}.
This is also true if the AES unit is operated in OFB or CTR mode, i.e., if the plaintext/ciphertext not necessarily needs to be a multiple of the block size (for more details refer to Appendix A of [Recommendation for Block Cipher Modes of Operation](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf)).
In the case that the plaintext/ciphertext is not a multiple of the block size and the AES unit is operated in OFB or CTR mode, software can employ any form of padding for the input data of the last message block as the padding bits do not have an effect on the actual message bits.
@@ -602,8 +602,8 @@
## De-Initialization
After finishing operation, software must:
-1. Disable the AES unit to no longer automatically start encryption/decryption by setting the MANUAL_OPERATION bit in {{< regref "CTRL_SHADOWED" >}} to `1`.
-1. Clear all key registers, IV registers as well as the Input Data and the Output Data registers with pseudo-random data by setting the KEY_IV_DATA_IN_CLEAR and DATA_OUT_CLEAR bits in {{< regref "TRIGGER" >}} to `1`.
+1. Disable the AES unit to no longer automatically start encryption/decryption by setting the MANUAL_OPERATION bit in {{#regref aes.CTRL_SHADOWED }} to `1`.
+1. Clear all key registers, IV registers as well as the Input Data and the Output Data registers with pseudo-random data by setting the KEY_IV_DATA_IN_CLEAR and DATA_OUT_CLEAR bits in {{#regref aes.TRIGGER }} to `1`.
The code snippet below shows how to perform this task.
@@ -637,4 +637,4 @@
For a detailed overview of the register tool, please refer to the [Register Tool documentation.](../../../util/reggen/README.md)
-{{< incGenFromIpDesc "../data/aes.hjson" "registers" >}}
+* [Register Table](data/aes.hjson#registers)
diff --git a/hw/ip/aon_timer/README.md b/hw/ip/aon_timer/README.md
index 5f84d17..44d4280 100644
--- a/hw/ip/aon_timer/README.md
+++ b/hw/ip/aon_timer/README.md
@@ -20,9 +20,9 @@
A count starts at 0 and slowly ticks upwards (one tick every `N + 1` clock cycles, where `N` is the pre-scaler value).
When it reaches / exceeds the wake threshold, a level wakeup signal is sent to the power manager and a level IRQ is sent to the processor.
This wakeup signal stays high until it is explicitly acknowledged by software.
-To clear the wakeup write 0 to the {{<regref "WKUP_CAUSE">}} register.
-To clear the interrupt write 1 to {{<regref "INTR_STATE.wkup_timer_expired">}}.
-Note that if {{<regref "WKUP_COUNT">}} is not zeroed and remains at or above the wake threshold and the wakeup timer isn't disabled, the wakeup and interrupt will trigger again at the next clock tick.
+To clear the wakeup write 0 to the {{#regref aon_timer.WKUP_CAUSE }} register.
+To clear the interrupt write 1 to {{#regref aon_timer.INTR_STATE.wkup_timer_expired }}.
+Note that if {{#regref aon_timer.WKUP_COUNT }} is not zeroed and remains at or above the wake threshold and the wakeup timer isn't disabled, the wakeup and interrupt will trigger again at the next clock tick.
The wakeup timer can be used like a real-time clock for long periods in a low-power mode (though it does not give any guarantees of time-accuracy). **TODO: specify accuracy**
### AON Watchdog timer
@@ -74,7 +74,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/aon_timer.hjson" "hwcfg" >}}
+* [Interface Tables](data/aon_timer.hjson#interfaces)
## Design Details
@@ -90,25 +90,25 @@
## Initialization
-1. Write the timer values {{<regref"WKUP_COUNT">}} and {{<regref"WDOG_COUNT">}} to zero.
-2. Program the desired wakeup pre-scaler value in {{<regref"WKUP_CTRL">}}.
-3. Program the desired thresholds in {{<regref"WKUP_THOLD">}}, {{<regref"WDOG_BARK_THOLD">}} and {{<regref"WDOG_BITE_THOLD">}}.
-4. Set the enable bit to 1 in the {{<regref"WKUP_CTRL">}} / {{<regref"WDOG_CTRL">}} registers.
-5. If desired, lock the watchdog configuration by writing 1 to the `regwen` bit in {{<regref"WDOG_REGWEN">}}.
+1. Write the timer values {{#regref aon_timer.WKUP_COUNT }} and {{#regref aon_timer.WDOG_COUNT }} to zero.
+2. Program the desired wakeup pre-scaler value in {{#regref aon_timer.WKUP_CTRL }}.
+3. Program the desired thresholds in {{#regref aon_timer.WKUP_THOLD }}, {{#regref aon_timer.WDOG_BARK_THOLD }} and {{#regref aon_timer.WDOG_BITE_THOLD }}.
+4. Set the enable bit to 1 in the {{#regref aon_timer.WKUP_CTRL }} / {{#regref aon_timer.WDOG_CTRL }} registers.
+5. If desired, lock the watchdog configuration by writing 1 to the `regwen` bit in {{#regref aon_timer.WDOG_REGWEN }}.
## Watchdog pet
-Pet the watchdog by writing zero to the {{<regref"WDOG_COUNT">}} register.
+Pet the watchdog by writing zero to the {{#regref aon_timer.WDOG_COUNT }} register.
## Interrupt Handling
If either timer reaches the programmed threshold, interrupts are generated from the AON_TIMER module.
-Disable or reinitialize the wakeup timer if required by clearing the enable bit in {{<regref"WKUP_CTRL">}} or clearing the timer value in {{<regref"WKUP_COUNT">}}.
-Clear the interrupt by writing 1 into the Interrupt Status Register {{<regref "INTR_STATE">}}.
+Disable or reinitialize the wakeup timer if required by clearing the enable bit in {{#regref aon_timer.WKUP_CTRL }} or clearing the timer value in {{#regref aon_timer.WKUP_COUNT }}.
+Clear the interrupt by writing 1 into the Interrupt Status Register {{#regref aon_timer.INTR_STATE }}.
-If the timer has caused a wakeup event ({{<regref"WKUP_CAUSE">}} is set) then clear the wakeup request by writing 0 to {{<regref"WKUP_CAUSE">}}.
+If the timer has caused a wakeup event ({{#regref aon_timer.WKUP_CAUSE }} is set) then clear the wakeup request by writing 0 to {{#regref aon_timer.WKUP_CAUSE }}.
-If {{<regref"WKUP_COUNT">}} remains above the threshold after clearing the interrupt or wakeup event and the timer remains enabled, the interrupt and wakeup event will trigger again at the next clock tick.
+If {{#regref aon_timer.WKUP_COUNT }} remains above the threshold after clearing the interrupt or wakeup event and the timer remains enabled, the interrupt and wakeup event will trigger again at the next clock tick.
## Device Interface Functions (DIFs)
@@ -116,4 +116,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/aon_timer.hjson" "registers" >}}
+* [Register Table](data/aon_timer.hjson#registers)
diff --git a/hw/ip/clkmgr/README.md b/hw/ip/clkmgr/README.md
index 0be9f13..a083fec 100644
--- a/hw/ip/clkmgr/README.md
+++ b/hw/ip/clkmgr/README.md
@@ -61,7 +61,7 @@
The `Idle` signal must be sourced from the transactional modules and sent to the clock manager.
For this group software can only express its intent to shut-off, and does not have full control over the final state.
-This intent is indicated with a register in the clock manager register file, see {{< regref "CLK_HINTS" >}}.
+This intent is indicated with a register in the clock manager register file, see {{#regref clkmgr.CLK_HINTS }}.
Even when the hint is set, the `Idle` does not directly manipulate the clock.
When an idle indication is received, the `clkmgr` counts for a period of 10 local clocks to ensure the idle was not a glitch.
@@ -171,7 +171,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "/hw/top_earlgrey/ip/clkmgr/data/autogen/clkmgr.hjson" "hwcfg" >}}
+* [Interface Tables](../../top_earlgrey/ip/clkmgr/data/autogen/clkmgr.hjson#interfaces)
## Design Details
@@ -224,12 +224,12 @@
Software request for external clocks is not always valid.
Software is only able to request for external clocks when hardware debug functions are [allowed](../lc_ctrl/README.md#hw_debug_en).
-When software requests the external clock switch, it also provides an indication how fast the external clock is through {{< regref "EXTCLK_CTRL.HI_SPEED_SEL" >}}.
+When software requests the external clock switch, it also provides an indication how fast the external clock is through {{#regref clkmgr.EXTCLK_CTRL.HI_SPEED_SEL }}.
There are two supported clock speeds:
* High speed - external clock is close to nominal speeds (e.g. external clock is 96MHz and nominal frequency is 96MHz-100MHz)
* Low speed - external clock is half of nominal speeds (e.g. external clock is 48MHz and nominal frequency is 96MHz-100MHz)
-When software requests external clock, the register bit {{< regref "EXTCLK_CTRL.SEL" >}} is written.
+When software requests external clock, the register bit {{#regref clkmgr.EXTCLK_CTRL.SEL }} is written.
If hardware debug functions are allowed, the `clkmgr` sends a request signal `all_clk_byp_req_o` to `ast` and is acknowledged through `all_clk_byp_ack_i`.
If software requests a low speed external clock, at the completion of the switch, internal dividers are also stepped down.
@@ -270,7 +270,7 @@
### Clock Frequency / Time-out Measurements
Clock manager can continuously measure root clock frequencies to see if any of the root clocks have deviated from the expected frequency.
-This feature can be enabled through the various measurement control registers such as {{< regref "IO_MEASURE_CTRL" >}}.
+This feature can be enabled through the various measurement control registers such as {{#regref clkmgr.IO_MEASURE_CTRL }}.
The root clocks, specifically the clocks supplied from `ast` and their divided variants, are constantly measured against the `always on clock` when this feature is enabled.
Software sets both an expected maximum and minimum for each measured clock.
@@ -299,7 +299,7 @@
Clock too slow is registered when the clock cycle count is less than the software programmed min threshold.
Clock time-out is registered when the clock stops toggling and the timeout threshold is reached.
-As these are all software supplied values, the entire measurement control can be locked from further programming through {{< regref "MEASURE_CTRL_REGWEN" >}}.
+As these are all software supplied values, the entire measurement control can be locked from further programming through {{#regref clkmgr.MEASURE_CTRL_REGWEN }}.
# Programmers Guide
@@ -308,12 +308,12 @@
## Transactional Clock Hints
-To enable a transactional clock, set the corresponding hint in {{< regref "CLK_HINTS" >}} to `1`.
-To disable a transactional clock, set the corresponding hint in {{< regref "CLK_HINTS" >}} to `0`.
-Note, a `0` does not indicate clock is actually disabled, software can thus check {{< regref "CLK_HINTS_STATUS" >}} for the actual state of the clock.
+To enable a transactional clock, set the corresponding hint in {{#regref clkmgr.CLK_HINTS }} to `1`.
+To disable a transactional clock, set the corresponding hint in {{#regref clkmgr.CLK_HINTS }} to `0`.
+Note, a `0` does not indicate clock is actually disabled, software can thus check {{#regref clkmgr.CLK_HINTS_STATUS }} for the actual state of the clock.
## Peripheral Clock Controls
-To control peripheral clocks, directly change the bits in {{< regref "CLK_ENABLES" >}}.
+To control peripheral clocks, directly change the bits in {{#regref clkmgr.CLK_ENABLES }}.
## Device Interface Functions (DIFs)
@@ -321,4 +321,4 @@
## Register Table
-{{< incGenFromIpDesc "/hw/top_earlgrey/ip/clkmgr/data/autogen/clkmgr.hjson" "registers" >}}
+* [Register Table](../../top_earlgrey/ip/clkmgr/data/autogen/clkmgr.hjson#registers)
diff --git a/hw/ip/csrng/README.md b/hw/ip/csrng/README.md
index 9574a60..981fae1 100644
--- a/hw/ip/csrng/README.md
+++ b/hw/ip/csrng/README.md
@@ -147,7 +147,7 @@
## Hardware Interfaces
- {{< incGenFromIpDesc "../data/csrng.hjson" "hwcfg" >}}
+ * [Interface Tables](data/csrng.hjson#interfaces)
The table below lists other CSRNG signals.
@@ -552,12 +552,12 @@
All CSRNG registers are little-endian.
-When providing additional data for an <tt>instantiate</tt>, <tt>reseed</tt> or <tt>update</tt> command the data words have to be written to {{< regref "CMD_REQ" >}} in the correct order.
+When providing additional data for an <tt>instantiate</tt>, <tt>reseed</tt> or <tt>update</tt> command the data words have to be written to {{#regref csrng.CMD_REQ }} in the correct order.
Consider a byte string B<sub>1</sub>, B<sub>2</sub>, ..., B<sub>n</sub> as defined in Appendix A of [NIST's SP 800-90A](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf), i.e., where B<sub>1</sub> is the most significant byte and B<sub>n</sub> the least significant byte.
-Providing this sequence as additional data to CSRNG requires software to write the following 32-bit words to {{< regref "CMD_REQ" >}} in the following order:
+Providing this sequence as additional data to CSRNG requires software to write the following 32-bit words to {{#regref csrng.CMD_REQ }} in the following order:
<table>
-<caption>Byte order when writing to {{< regref "CMD_REQ" >}}</caption>
+<caption>Byte order when writing to {{#regref csrng.CMD_REQ }}</caption>
<thead>
<tr>
<th>Word Index</th>
@@ -583,9 +583,9 @@
</tr>
</table>
-When reading the internal state from {{< regref "INT_STATE_VAL" >}}, CSRNG returns the bytes of V and Key in the following order:
+When reading the internal state from {{#regref csrng.INT_STATE_VAL }}, CSRNG returns the bytes of V and Key in the following order:
<table>
-<caption>Byte order when reading from {{< regref "INT_STATE_VAL" >}}</caption>
+<caption>Byte order when reading from {{#regref csrng.INT_STATE_VAL }}</caption>
<thead>
<tr>
<th>Word Index</th>
@@ -623,13 +623,13 @@
</tr>
</table>
-Finally, when reading a byte string of say 64 bytes (16 words) B<sub>1</sub>, B<sub>2</sub>, ..., B<sub>64</sub> from {{< regref "GENBITS" >}} as defined in Appendix A of [NIST's SP 800-90A](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf), the bytes are returned in the following order.
+Finally, when reading a byte string of say 64 bytes (16 words) B<sub>1</sub>, B<sub>2</sub>, ..., B<sub>64</sub> from {{#regref csrng.GENBITS }} as defined in Appendix A of [NIST's SP 800-90A](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf), the bytes are returned in the following order.
Note that always 4 words return 1 128-bit GENBITS block.
Within each block, the least significant bytes are returned first and the most significant bytes are returned last.
In particular, the most significant byte B<sub>1</sub> of the string is read in Word 4 and the least significant byte B<sub>64</sub> of the string is read in Word 13.
<table>
-<caption>Byte order when reading from {{< regref "GENBITS" >}}</caption>
+<caption>Byte order when reading from {{#regref csrng.GENBITS }}</caption>
<thead>
<tr>
<th>Word Index</th>
@@ -700,4 +700,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/csrng.hjson" "registers" >}}
+* [Register Table](data/csrng.hjson#registers)
diff --git a/hw/ip/edn/README.md b/hw/ip/edn/README.md
index 28efd8d..625080d 100644
--- a/hw/ip/edn/README.md
+++ b/hw/ip/edn/README.md
@@ -18,8 +18,8 @@
- CSRNG application command has completed.
- An internal FIFO error has occurred.
- There are two alerts that are implemented in is revision:
- - A fatal alert to report common security fatal errors and EDN specific fatal errors. A list of fatal errors are listed in the {{< regref "ERR_CODE" >}} register.
- - A recoverable alert to report recoverable error. A list of fatal errors are listed in the {{< regref "RECOV_ALERT_STS" >}} register.
+ - A fatal alert to report common security fatal errors and EDN specific fatal errors. A list of fatal errors are listed in the {{#regref edn.ERR_CODE }} register.
+ - A recoverable alert to report recoverable error. A list of fatal errors are listed in the {{#regref edn.RECOV_ALERT_STS }} register.
## Description
@@ -37,8 +37,8 @@
Application interface commands to the CSRNG block can be generated by either firmware or hardware.
-Firmware can issue CSRNG commands on behalf of hardware peripherals, by writing the commands to the {{< regref "SW_CMD_REQ" >}} register.
-The command status response is captured in the {{< regref "SW_CMD_STS" >}} register.
+Firmware can issue CSRNG commands on behalf of hardware peripherals, by writing the commands to the {{#regref edn.SW_CMD_REQ }} register.
+The command status response is captured in the {{#regref edn.SW_CMD_STS }} register.
Even when CRSNG `generate` commands are issued by firmware, all random values are distributed to the hardware peripherals.
If firmware applications require random values for their *own* use, they must issue the commands directly to the CSRNG, which maintains a dedicated CSRNG instance for firmware that is accessible through TL-UL.
@@ -48,13 +48,13 @@
The general operation of this mode is that the CSRNG instance is set up by firmware, then the FIFOs are preloaded with commands.
One FIFO can be programmed to send `generate` commands.
The other FIFO can be programmed to send `reseed` commands.
-The {{< regref "MAX_NUM_REQS_BETWEEN_RESEEDS" >}} register sets the number of `generate` commands allowed between `reseed` commands.
+The {{#regref edn.MAX_NUM_REQS_BETWEEN_RESEEDS }} register sets the number of `generate` commands allowed between `reseed` commands.
Once this is done, the EDN block can request data from the CSRNG once firmware has instantiated the associated instance through the EDN command forwarding interface.
When in this mode, the EDN emits `generate` commands from the first FIFO to get more data.
-Once the {{< regref "MAX_NUM_REQS_BETWEEN_RESEEDS" >}} timer expires, the EDN block emits a `reseed` command from the second FIFO.
+Once the {{#regref edn.MAX_NUM_REQS_BETWEEN_RESEEDS }} timer expires, the EDN block emits a `reseed` command from the second FIFO.
The process of sending these two commands will repeat forever until the `EDN_ENABLE` field is cleared, the `AUTO_REQ_MODE` field is cleared, or the EDN is reset.
-Any of the command FIFOs can be reset by asserting the `CMD_FIFO_RST` field in the {{< regref "CTRL" >}} register.
+Any of the command FIFOs can be reset by asserting the `CMD_FIFO_RST` field in the {{#regref edn.CTRL }} register.
The other mode is "boot-time request mode", where only the hardware generates CSRNG application interface commands.
In this mode a single `instantiate` command is sent, followed by a stream of `generate` commands.
@@ -90,17 +90,17 @@
The EDN is for distributing random number streams to hardware blocks, via peripheral ports on on the EDN.
Each block connected to a peripheral port is referred to as an endpoint.
-To enable the EDN block, set the `EDN_ENABLE` field in the {{< regref "CTRL" >}} register..
+To enable the EDN block, set the `EDN_ENABLE` field in the {{#regref edn.CTRL }} register..
## Interaction with CSRNG Application Interface Ports
The CSRNG application interface implements the "function envelopes" recommended by [NIST SP 800-90A](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf) for random number generation, and these function envelopes establish certain requirements for the order of operations.
For instance, the application interface port must receive an explicit `instantiate` command before receiving any `generate` commands.
-The sequences of commands generated by a particular EDN are either controlled by the EDN state machine or by commands forwarded from firmware through the {{< regref "SW_CMD_REQ" >}} register.
+The sequences of commands generated by a particular EDN are either controlled by the EDN state machine or by commands forwarded from firmware through the {{#regref edn.SW_CMD_REQ }} register.
-Whenever commands are directly forwarded from firmware to the CSRNG through the {{< regref "SW_CMD_REQ" >}} register, firmware must poll and clear the `CMD_ACK` bit of the {{< regref "SW_CMD_STS" >}} register before sending any further commands.
+Whenever commands are directly forwarded from firmware to the CSRNG through the {{#regref edn.SW_CMD_REQ }} register, firmware must poll and clear the `CMD_ACK` bit of the {{#regref edn.SW_CMD_STS }} register before sending any further commands.
-Note that CSRNG commands are to be written into the {{< regref "SW_CMD_REQ" >}}, {{< regref "RESEED_CMD" >}}, and {{< regref "GENERATE_CMD" >}} registers.
+Note that CSRNG commands are to be written into the {{#regref edn.SW_CMD_REQ }}, {{#regref edn.RESEED_CMD }}, and {{#regref edn.GENERATE_CMD }} registers.
CSRNG command format details can be found in [CSRNG](../csrng/README.md).
There are two broad modes for state machine control: auto request mode and boot-time request mode.
@@ -115,8 +115,8 @@
On exiting, the EDN issues an `uninstantiate` command to destroy the associated CSRNG instance.
Once firmware initialization is complete, it is important to exit this mode if the endpoints ever need FIPS-approved random values.
-This is done by either *clearing* the `EDN_ENABLE` field or *clearing* the `BOOT_REQ_MODE` field in {{< regref "CTRL" >}} to halt the boot-time request state machine.
-Firmware must then wait for successful the shutdown of the state machine by polling the `REQ_MODE_SM_STS` field of the {{< regref "SUM_STS" >}} register.
+This is done by either *clearing* the `EDN_ENABLE` field or *clearing* the `BOOT_REQ_MODE` field in {{#regref edn.CTRL }} to halt the boot-time request state machine.
+Firmware must then wait for successful the shutdown of the state machine by polling the `REQ_MODE_SM_STS` field of the {{#regref edn.SUM_STS }} register.
It should be noted that when in boot-time request mode, no status will be updated that is used for the software port operation.
If some hang condition were to occur when in this mode, the main state machine debug register should be read to determine if a hang condition is present.
@@ -139,7 +139,7 @@
If many endpoints require boot-time entropy multiple boot-time EDNs may be required, as the EDN has a fixed maximum number of peripheral ports.
Since physical entropy generation takes time, there exists a mechanism to prioritize the EDNs, to match the boot priority of each group of attached endpoints.
To establish an order to the instantiation of each EDN, enable them one at a time.
-To ensure that the most recently enabled EDN will get next priority for physical entropy, poll the `BOOT_INST_ACK` field in the {{< regref "SUM_STS" >}} register before enabling the following EDN.
+To ensure that the most recently enabled EDN will get next priority for physical entropy, poll the `BOOT_INST_ACK` field in the {{#regref edn.SUM_STS }} register before enabling the following EDN.
If using boot-time request mode, the CSRNG seed material used for the first-activated EDN is the special pre-FIPS seed, which is specifically tested quickly to improve latency.
The first random values distributed from this EDN will therefore be available roughly 2ms after reset.
@@ -149,17 +149,17 @@
### Auto Request Mode
-Before entering auto request mode, it is the responsibility of firmware to first generate an `instantiate` command for the EDN-associated instance via the {{<regref "SW_CMD_REQ">}} register.
-The required `generate` and `reseed` commands must also be custom generated by firmware and loaded into the respective command replay FIFOs via the {{< regref "GENERATE_CMD" >}} and {{< regref "RESEED_CMD" >}} registers.
+Before entering auto request mode, it is the responsibility of firmware to first generate an `instantiate` command for the EDN-associated instance via the {{#regref edn.SW_CMD_REQ }} register.
+The required `generate` and `reseed` commands must also be custom generated by firmware and loaded into the respective command replay FIFOs via the {{#regref edn.GENERATE_CMD }} and {{#regref edn.RESEED_CMD }} registers.
These `generate` commands will be issued as necessary to meet the bandwidth requirements of the endpoints.
The `reseed` commands will be issued once every `MAX_NUM_REQS_BETWEEN_RESEEDS` generate requests.
For details on the options for application interface commands please see the [CSRNG IP Documentation](../csrng/README.md).
-Once the CSRNG instance has been instantiated, and the `generate` and `reseed` commands have been loaded, auto request mode can be entered by programming the {{< regref "CTRL" >}} register with `EDN_ENABLE` and `AUTO_REQ_MODE` fields are enabled.
+Once the CSRNG instance has been instantiated, and the `generate` and `reseed` commands have been loaded, auto request mode can be entered by programming the {{#regref edn.CTRL }} register with `EDN_ENABLE` and `AUTO_REQ_MODE` fields are enabled.
Note that if BOOT_REQ_MODE is asserted the state machine will enter boot-time request mode, even if AUTO_REQ_MODE is asserted.
-To issue any new commands other than those stored in the generate or reseed FIFOs, it is important to disable auto request mode, by deasserting the `AUTO_REQ_MODE` field in the {{< regref "CTRL" >}} register.
-Firmware must then wait until the current command is completed by polling the {{< regref "MAIN_SM_STATE" >}} register.
-Once the state machine returns to the `Idle` or `SWPortMode` states, new firmware-driven commands can be passed to the CSRNG via the {{< regref "SW_CMD_REQ" >}} register.
+To issue any new commands other than those stored in the generate or reseed FIFOs, it is important to disable auto request mode, by deasserting the `AUTO_REQ_MODE` field in the {{#regref edn.CTRL }} register.
+Firmware must then wait until the current command is completed by polling the {{#regref edn.MAIN_SM_STATE }} register.
+Once the state machine returns to the `Idle` or `SWPortMode` states, new firmware-driven commands can be passed to the CSRNG via the {{#regref edn.SW_CMD_REQ }} register.
It should be noted that when in auto request mode, no status will be updated that is used for the software port operation once the `instantiate` command has completed.
If some hang condition were to occur when in this mode, the main state machine debug register should be read to determine if a hang condition is present.
@@ -196,14 +196,14 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/edn.hjson" "hwcfg" >}}
+* [Interface Tables](data/edn.hjson#interfaces)
## Design Details
### EDN Initialization
After power-up, the EDN block is disabled.
-A single TL-UL configuration write to the {{< regref "CTRL" >}} register will start random-number streams processing in boot-time request mode.
+A single TL-UL configuration write to the {{#regref edn.CTRL }} register will start random-number streams processing in boot-time request mode.
CSRNG application commands will be sent immediately.
Once these commands have completed, a status bit will be set.
At this point, firmware can later come and reconfigure the EDN block for a different mode of operation.
@@ -271,4 +271,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/edn.hjson" "registers" >}}
+* [Register Table](data/edn.hjson#registers)
diff --git a/hw/ip/entropy_src/README.md b/hw/ip/entropy_src/README.md
index bf00dbd..560b4af0 100644
--- a/hw/ip/entropy_src/README.md
+++ b/hw/ip/entropy_src/README.md
@@ -50,7 +50,7 @@
The thresholds for these tests should be chosen to achieve a low false-positive rate (α) given a conservative estimate of the manufacturing tolerances of the PTRNG noise source.
The combined choice of threshold and window size then determine the false-negative rate (β), or the probability of missing statistical defects at any particular magnitude.
-When the IP is disabled by clearing the `ENABLE` bit in {{< regref "CONF" >}}, all heath checks are disabled and all counters internal to the health checks are reset.
+When the IP is disabled by clearing the `ENABLE` bit in {{#regref entropy_src.CONF }}, all heath checks are disabled and all counters internal to the health checks are reset.
In order to compensate for the fact our tests (like *all* realistic statistical tests) have finite resolution for detecting defects, we conservatively use 2048 bits of PTRNG noise source to construct each 384 bit conditioned entropy sample.
When passed through the conditioning block, the resultant entropy stream will be full entropy unless the PTRNG noise source has encountered some statistical defect serious enough to reduce the raw min-entropy to a level below 0.375 bits of entropy per output bit.
@@ -82,7 +82,7 @@
For maximal flexibility in normal operation, the conditioning function can also be implemented by firmware.
When this firmware conditioning feature is activated, data read directly out of the noise source can be reinjected into the entropy pipeline via a TL-UL register after it has been processed by firmware.
It should be noted that this firmware algorithm must be vetted by NIST to satisfy the requirements for a full-entropy source.
-This feature can also be disabled for security purposes, either by locking the feature via the {{< regref "REGEN" >}} register at boot, or by a write to one-time programmable (OTP) memory.
+This feature can also be disabled for security purposes, either by locking the feature via the {{#regref entropy_src.REGEN }} register at boot, or by a write to one-time programmable (OTP) memory.
## Compatibility
This IP block does not have any direct hardware compatibility requirements.
@@ -102,7 +102,7 @@
This feature is designed to provide an initial seed's worth of entropy with lower latency than the normal FIPS/CC compliant health check process.
Health testing will still be performed on boot-time mode entropy, but the window of checking is, by default, 384 bits instead of 2048 bits.
When entropy is delivered to the downstream hardware block, a signal will indicate what type of entropy it is - FIPS compliant or not.
-Boot-time mode can be completely disabled in the {{< regref "CONF" >}} register.
+Boot-time mode can be completely disabled in the {{#regref entropy_src.CONF }} register.
Once the initial boot-time mode phase has completed, the ENTROPY_SRC block will switch to FIPS compliant mode.
In this mode, once the raw entropy has been health checked, it will be passed into a conditioner block.
@@ -116,32 +116,32 @@
In the case of health tests, firmware can turn off one or all of the health tests and perform the tests in firmware.
A data path is provided in the hardware such that the inbound entropy can be trapped in the pre-conditioner FIFO.
Once a pre-determined threshold of entropy has been reached in this FIFO, the firmware can then read the entropy bits out of the FIFO.
-The exact mechanism for this functionality starts with setting the `FW_OV_MODE` field in the {{< regref "FW_OV_CONTROL" >}} register.
-This will enable firmware to monitor post-health test entropy bits by reading from the {{< regref "FW_OV_RD_DATA" >}} register.
-Firmware can use the {{< regref "OBSERVE_FIFO_THRESH" >}} and {{< regref "OBSERVE_FIFO_DEPTH" >}} to determine the state of the OBSERVE FIFO.
+The exact mechanism for this functionality starts with setting the `FW_OV_MODE` field in the {{#regref entropy_src.FW_OV_CONTROL }} register.
+This will enable firmware to monitor post-health test entropy bits by reading from the {{#regref entropy_src.FW_OV_RD_DATA }} register.
+Firmware can use the {{#regref entropy_src.OBSERVE_FIFO_THRESH }} and {{#regref entropy_src.OBSERVE_FIFO_DEPTH }} to determine the state of the OBSERVE FIFO.
At this point, firmware can do additional health checks on the entropy.
Optionally, firmware can do the conditioning function, assuming the hardware is configured to bypass the conditioner block.
-Once firmware has processed the entropy, it can then write the results back into the {{< regref "FW_OV_WR_DATA" >}} register (pre-conditioner FIFO).
-The `FW_OV_ENTROPY_INSERT` in the {{< regref "FW_OV_CONTROL" >}} register will enable inserting entropy bits back into the entropy flow.
+Once firmware has processed the entropy, it can then write the results back into the {{#regref entropy_src.FW_OV_WR_DATA }} register (pre-conditioner FIFO).
+The `FW_OV_ENTROPY_INSERT` in the {{#regref entropy_src.FW_OV_CONTROL }} register will enable inserting entropy bits back into the entropy flow.
The firmware override control fields will be set such that the new entropy will resume normal flow operation.
An additional feature of the firmware override function is to insert entropy bits into the flow and still use the conditioning function in the hardware.
-Setting the `FW_OV_INSERT_START` field in the {{< regref "FW_OV_SHA3_START" >}} register will prepare the hardware for this flow.
-Once this field is set true, the {{< regref "FW_OV_WR_DATA" >}} register can be written with entropy bits.
-The {{< regref "FW_OV_WR_FIFO_FULL" >}} register should be monitored after each write to ensure data is not dropped.
+Setting the `FW_OV_INSERT_START` field in the {{#regref entropy_src.FW_OV_SHA3_START }} register will prepare the hardware for this flow.
+Once this field is set true, the {{#regref entropy_src.FW_OV_WR_DATA }} register can be written with entropy bits.
+The {{#regref entropy_src.FW_OV_WR_FIFO_FULL }} register should be monitored after each write to ensure data is not dropped.
Once all of the data has been written, the `FW_OV_INSERT_START` field should be set to false.
The normal SHA3 processing will continue and finally push the conditioned entropy through the module.
Health checks are performed on the input raw data from the PTRNG noise source when in that mode.
There are four health tests that will be performed: repetitive count, adaptive proportion, bucket, and Markov tests.
Each test has a pair of threshold values that determine that pass/fail of the test, one threshold for boot-time mode, and one for normal mode.
-By default, all tests are enabled, but can be turn off in the {{< regref "CONF" >}} register.
+By default, all tests are enabled, but can be turn off in the {{#regref entropy_src.CONF }} register.
Because of the variability of the PTRNG noise source, there are several registers that log statistics associated with the health tests.
For example, the adaptive proportion test has a high watermark register that logs the highest measured number of ones.
-The {{< regref "ADAPTP_HI_WATERMARKS" >}} register has an entry for both normal and boot-time modes.
+The {{#regref entropy_src.ADAPTP_HI_WATERMARKS }} register has an entry for both normal and boot-time modes.
This register allows for determining how close the threshold value should be set to the fail over value.
-Specific to the adaptive proportion test, there is also the {{< regref "ADAPTP_LO_WATERMARKS" >}} register, which will hold the lowest number of ones measured.
-To help understand how well the thresholds work through time, a running count of test fails is kept in the {{< regref "ADAPTP_HI_TOTAL_FAILS" >}} register.
+Specific to the adaptive proportion test, there is also the {{#regref entropy_src.ADAPTP_LO_WATERMARKS }} register, which will hold the lowest number of ones measured.
+To help understand how well the thresholds work through time, a running count of test fails is kept in the {{#regref entropy_src.ADAPTP_HI_TOTAL_FAILS }} register.
The above example for the adaptive proportion test also applies to the other health tests, with the exception of the low watermark registers.
See the timing diagrams below for more details on how the health tests work.
It should be noted that for all error counter registers, they are sized for 16 bits, which prevents any case where counters might wrap.
@@ -163,16 +163,16 @@
- test_fail_lo_pulse: indication that a low threshold comparison failed, to be read from a register.
-The {{< regref "ALERT_THRESHOLD" >}} register determines how many fails can occur before an alert is issued.
+The {{#regref entropy_src.ALERT_THRESHOLD }} register determines how many fails can occur before an alert is issued.
By default, the current threshold is set to two, such that the occurrence of two failing test cycles back-to-back would provide a very low α value.
-The {{< regref "ALERT_FAIL_COUNTS" >}} register holds the total number of fails, plus all of the individual contributing failing tests.
-Setting the {{< regref "ALERT_THRESHOLD" >}} register to zero will disable alert generation.
+The {{#regref entropy_src.ALERT_FAIL_COUNTS }} register holds the total number of fails, plus all of the individual contributing failing tests.
+Setting the {{#regref entropy_src.ALERT_THRESHOLD }} register to zero will disable alert generation.
Firmware has a path to read entropy from the ENTROPY_SRC block.
-The {{< regref "ENTROPY_CONTROL" >}} register allows firmware to set the internal multiplexers to steer entropy data to the {{< regref "ENTROPY_DATA" >}} register.
+The {{#regref entropy_src.ENTROPY_CONTROL }} register allows firmware to set the internal multiplexers to steer entropy data to the {{#regref entropy_src.ENTROPY_DATA }} register.
The control bit `ES_TYPE` sets whether the entropy will come from the conditioning block or be sourced through the bypass path.
-A status bit will be set that can either be polled or generate an interrupt when the entropy bits are available to be read from the {{< regref "ENTROPY_DATA" >}} register.
-The firmware needs to read the {{< regref "ENTROPY_DATA" >}} register twelve times in order to cleanly evacuate the 384-bit seed from the hardware path (12*32bits=384bits total).
+A status bit will be set that can either be polled or generate an interrupt when the entropy bits are available to be read from the {{#regref entropy_src.ENTROPY_DATA }} register.
+The firmware needs to read the {{#regref entropy_src.ENTROPY_DATA }} register twelve times in order to cleanly evacuate the 384-bit seed from the hardware path (12*32bits=384bits total).
The firmware will directly read out of the main entropy FIFO, and when the control bit `ES_ROUTE` is set, no entropy is being passed to the block hardware interface.
If the `esfinal` FIFO fills up, additional entropy that has been health checked will be dropped before entering the conditioner.
@@ -189,7 +189,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/entropy_src.hjson" "hwcfg" >}}
+* [Interface Tables](data/entropy_src.hjson#interfaces)
## Design Details
@@ -200,14 +200,14 @@
For simplicity of initialization, only a single register write is needed to start functional operation of the ENTROPY_SRC block.
This assumes that proper defaults are chosen for thresholds, sampling rate, and other registers.
-For security reasons, a configuration and control register locking function is performed by the {{< regref "REGEN" >}} register.
-Clearing the bit in this register will prevent future modification of the {{< regref "CONF" >}} register or other writeable registers by firmware.
+For security reasons, a configuration and control register locking function is performed by the {{#regref entropy_src.REGEN }} register.
+Clearing the bit in this register will prevent future modification of the {{#regref entropy_src.CONF }} register or other writeable registers by firmware.
### Entropy Processing
When enabled, the ENTROPY_SRC block will generate entropy bits continuously.
-The `es_entropy_valid` bit in the `ENTROPY_SRC_INTR_STATE` register will indicate to the firmware when entropy bits can read from the {{< regref "ENTROPY_DATA" >}} register.
-The firmware will do 32-bit register reads of the {{< regref "ENTROPY_DATA" >}} register to retrieve the entropy bits.
+The `es_entropy_valid` bit in the `ENTROPY_SRC_INTR_STATE` register will indicate to the firmware when entropy bits can read from the {{#regref entropy_src.ENTROPY_DATA }} register.
+The firmware will do 32-bit register reads of the {{#regref entropy_src.ENTROPY_DATA }} register to retrieve the entropy bits.
Each read will automatically pop an entry from the entropy unpacker block.
A full twelve 32-bit words need to be read at a time.
@@ -310,13 +310,13 @@
This NIST-defined test is intended to detect statistical bias in the raw entropy data.
The test counts the number of 1's in a given sample, and applies thresholds to reject samples which deviate too far from the ideal mean of 50%.
-Depending on the value of the {{< regref "CONF.THRESHOLD_SCOPE" >}} field, the thresholds can either be applied collectively to the all RNG inputs, or the thresholds can be applied on a line-by-line basis.
-Setting {{< regref "CONF.THRESHOLD_SCOPE" >}} to `kMuBi4True` will apply the thresholds to the aggregated RNG stream.
+Depending on the value of the {{#regref entropy_src.CONF.THRESHOLD_SCOPE }} field, the thresholds can either be applied collectively to the all RNG inputs, or the thresholds can be applied on a line-by-line basis.
+Setting {{#regref entropy_src.CONF.THRESHOLD_SCOPE }} to `kMuBi4True` will apply the thresholds to the aggregated RNG stream.
This can be useful for lowering the likelihood of coincidental test failures (higher α).
-Meanwhile, setting {{< regref "CONF.THRESHOLD_SCOPE" >}} to `kMuBi4False` will apply thresholds on a line-by-line basis which allows the ENTROPY_SRC to detect single line failures.
+Meanwhile, setting {{#regref entropy_src.CONF.THRESHOLD_SCOPE }} to `kMuBi4False` will apply thresholds on a line-by-line basis which allows the ENTROPY_SRC to detect single line failures.
The following waveform shows how a sampling of a data pattern will be tested by the Adaptive Proportion test.
-In this example, the sum is taken over all RNG lines (i.e., {{< regref "CONF.THRESHOLD_SCOPE" >}} is True).
+In this example, the sum is taken over all RNG lines (i.e., {{#regref entropy_src.CONF.THRESHOLD_SCOPE }} is True).
{{< wavejson >}}
{signal: [
@@ -380,7 +380,7 @@
On average, the number of switching (e.g., "01") vs. non-switching (e.g., "00") pairs should be 50% of the total, with a variance proportional to the sample size.
Like the Adaptive Proportion test, the Markov Test can be computed either cumulatively (summing the results over all RNG lines) or on a per-line basis.
-In this example, the RNG lines are scored individually (i.e., {{< regref "CONF.THRESHOLD_SCOPE" >}} is False).
+In this example, the RNG lines are scored individually (i.e., {{#regref entropy_src.CONF.THRESHOLD_SCOPE }} is False).
{{< wavejson >}}
{signal: [
@@ -422,7 +422,7 @@
A useful feature for the ENTROPY_SRC block is the ability to disable it in a graceful matter.
Since there exists another feature to avoid power spikes between ENTROPY_SRC and CSRNG, software needs to monitor the disabling process.
-Bit 16 in the {{< regref "DEBUG_STATUS" >}} should be polled after the ENTROPY_SRC enable bits are cleared in the {{< regref "CONF" >}} register.
+Bit 16 in the {{#regref entropy_src.DEBUG_STATUS }} should be polled after the ENTROPY_SRC enable bits are cleared in the {{#regref entropy_src.CONF }} register.
After the handshakes with CSRNG are finished, the above bit should be set and the ENTROPY_SRC block can be safely enabled again.
ENTROPY_SRC may only be disabled if CSRNG is disabled.
@@ -438,4 +438,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/entropy_src.hjson" "registers" >}}
+* [Register Table](data/entropy_src.hjson#registers)
diff --git a/hw/ip/flash_ctrl/README.md b/hw/ip/flash_ctrl/README.md
index 823d853..eed7aa3 100644
--- a/hw/ip/flash_ctrl/README.md
+++ b/hw/ip/flash_ctrl/README.md
@@ -94,7 +94,7 @@
See the diagram below for an illustrative example.
![Flash Example Partition](./doc/flash_partitions.svg)
-Which type of partition is accessed is controlled through the {{< regref "CONTROL.PARTITION_SEL" >}} field.
+Which type of partition is accessed is controlled through the {{#regref flash_ctrl.CONTROL.PARTITION_SEL }} field.
The current flash controller implements one type of information partition and thus is controlled by 1 bit only.
This may change in the future.
@@ -137,7 +137,7 @@
All partitions share the same addressing scheme.
For example, the page 0 address of any kind of partition is always the same.
-To distinguish which partition is accessed, use the configuration in {{< regref "CONTROL.PARTITION_SEL" >}} and {{< regref "CONTROL.INFO_SEL" >}}
+To distinguish which partition is accessed, use the configuration in {{#regref flash_ctrl.CONTROL.PARTITION_SEL }} and {{#regref flash_ctrl.CONTROL.INFO_SEL }}
Note however, the system host is only able to access the [data partitions](#host-and-protocol-controller-handling).
##### Default Address Map
@@ -210,7 +210,7 @@
The seed material is read twice to confirm the values are consistent.
They are then forwarded to the key manager for processing.
During this seed phase, software initiated activities are back-pressured until the seed reading is complete.
-It is recommended that instead of blindly issuing transactions to the flash controller, the software polls {{< regref "STATUS.INIT_WIP" >}} until it is 0.
+It is recommended that instead of blindly issuing transactions to the flash controller, the software polls {{#regref flash_ctrl.STATUS.INIT_WIP }} until it is 0.
Once the seed phase is complete, the flash controller switches to the software interface.
Software can then read / program / erase the flash as needed.
@@ -229,7 +229,7 @@
#### Initialization
-The flash protocol controller is initialized through {{< regref "INIT" >}}.
+The flash protocol controller is initialized through {{#regref flash_ctrl.INIT }}.
When initialization is invoked, the flash controller requests the address and data scrambling keys from an external entity, [otp_ctrl](../otp_ctrl/README.md#interface-to-flash-scrambler) in this case.
After the scrambling keys are requested, the flash protocol controller reads the root seeds out of the [secret partitions](#secret-information-partitions) and sends them to the key manager.
@@ -250,10 +250,10 @@
Flash memory protection is handled differently depending on what type of partition is accessed.
-For data partitions, software can configure a number of memory protection regions such as {{< regref "MP_REGION_CFG_0" >}}.
+For data partitions, software can configure a number of memory protection regions such as {{#regref flash_ctrl.MP_REGION_CFG_0 }}.
For each region, software specifies both the beginning page and the number of pages that belong to that region.
Software then configures the access privileges for that region.
-Finally, each region can be activated or de-activated from matching through {{< regref "MP_REGION_CFG_0.EN" >}}.
+Finally, each region can be activated or de-activated from matching through {{#regref flash_ctrl.MP_REGION_CFG_0.EN }}.
Subsequent accesses are then allowed or denied based on the defined rule set.
Similar to RISCV pmp, if two region overlaps, the lower region index has higher priority.
@@ -261,14 +261,14 @@
For information partitions, the protection is done per individual page.
Each page can be configured with access privileges.
As a result, software does not need to define a start and end page for information partitions.
-See {{< regref "BANK0_INFO0_PAGE_CFG_0" >}} as an example.
+See {{#regref flash_ctrl.BANK0_INFO0_PAGE_CFG_0 }} as an example.
#### Bank Erase Protection
Unlike read, program and page erase operations, the bank erase command is the only one that can be issued at a bank level.
Because of this, bank erase commands are not guarded by the typical [memory protection mechanisms](#memory-protection).
-Instead, whether bank erase is allowed is controlled by {{< regref "MP_BANK_CFG_SHADOWED" >}}, where there is a separate configuration bit per bank.
+Instead, whether bank erase is allowed is controlled by {{#regref flash_ctrl.MP_BANK_CFG_SHADOWED }}, where there is a separate configuration bit per bank.
When the corresponding bit is set, that particular bank is permitted to have bank level operations.
The specific behavior of what is erased when bank erase is issued is flash memory dependent and thus can vary by vendor and technology.
@@ -301,7 +301,7 @@
#### Erase Suspend
-The flash controller supports erase suspend through {{< regref "ERASE_SUSPEND" >}}.
+The flash controller supports erase suspend through {{#regref flash_ctrl.ERASE_SUSPEND }}.
This allows the software to interrupt an ongoing erase operation.
The behavior of what happens to flash contents when erase is suspended is vendor defined; however, generally it can be assumed that the erase would be incomplete.
@@ -309,10 +309,10 @@
#### Additional Flash Attributes
-There are certain attributes provisioned in {{< regref "MP_REGION_CFG_0" >}} that are not directly used by the open source protocol or physical controllers.
+There are certain attributes provisioned in {{#regref flash_ctrl.MP_REGION_CFG_0 }} that are not directly used by the open source protocol or physical controllers.
Instead, these attributes are fed to the vendor flash module on a per-page or defined boundary basis.
-Currently there is only one such attribute {{< regref "MP_REGION_CFG_0.HE" >}}.
+Currently there is only one such attribute {{#regref flash_ctrl.MP_REGION_CFG_0.HE }}.
#### Idle Indication to External Power Manager
@@ -324,10 +324,10 @@
#### Flash Code Execution Handling
Flash can be used to store both data and code.
-To support separate access privileges between data and code, the flash protocol controller provides {{< regref "EXEC" >}} for software control.
+To support separate access privileges between data and code, the flash protocol controller provides {{#regref flash_ctrl.EXEC }} for software control.
-If software programs {{< regref "EXEC" >}} to `0xa26a38f7`, code fetch from flash is allowed.
-If software programs {{< regref "EXEC" >}} to any other value, code fetch from flash results in an error.
+If software programs {{#regref flash_ctrl.EXEC }} to `0xa26a38f7`, code fetch from flash is allowed.
+If software programs {{#regref flash_ctrl.EXEC }} to any other value, code fetch from flash results in an error.
The flash protocol controller distinguishes code / data transactions through the [instruction type attribute](../lc_ctrl/README.md#usage-of-user-bits) of the TL-UL interface.
@@ -335,7 +335,7 @@
The flash protocol controller maintains 3 different categories of observed errors and faults.
In general, errors are considered recoverable and primarily geared towards problems that could have been caused by software or that occurred during a software initiated operation.
-Errors can be found in {{< regref "ERR_CODE" >}}.
+Errors can be found in {{#regref flash_ctrl.ERR_CODE }}.
Faults, on the other hand, represent error events that are unlikely to have been caused by software and represent a major malfunction of the system.
@@ -364,7 +364,7 @@
##### Host Direct Access to Flash Controller Register Files {#host-direct-reg}
This category of transmission integrity behaves identically to other modules.
A bus transaction, when received, is checked for command and data payload integrity.
-If an integrity error is seen, the issuing bus host receives an in-band error response and a fault is registered in {{< regref "STD_FAULT_STATUS.REG_INTG_ERR" >}}.
+If an integrity error is seen, the issuing bus host receives an in-band error response and a fault is registered in {{#regref flash_ctrl.STD_FAULT_STATUS.REG_INTG_ERR }}.
##### Host Direct Access to Flash Macro {#host-direct-macro}
Flash can only be read by the host.
@@ -377,21 +377,21 @@
For program operations, the write data and its associated integrity are stored and propagated through the flash protocol and physical controllers.
Prior to packing the data for final flash program, the data is then checked for integrity correctness.
-If the data integrity is incorrect, an in-band error response is returned to the initiating host and an error is registered in {{< regref "ERR_CODE.PROG_INTG_ERR" >}}.
-An error is also registered in {{< regref "STD_FAULT_STATUS.PROG_INTG_ERR" >}} to indicate that a fatal fault has occurred.
+If the data integrity is incorrect, an in-band error response is returned to the initiating host and an error is registered in {{#regref flash_ctrl.ERR_CODE.PROG_INTG_ERR }}.
+An error is also registered in {{#regref flash_ctrl.STD_FAULT_STATUS.PROG_INTG_ERR }} to indicate that a fatal fault has occurred.
The reasons a program error is registered in two locations are two-fold:
-- It is registered in {{< regref "ERR_CODE" >}} so software can discover during operation status that a program has failed.
-- It is registered in {{< regref "STD_FAULT_STATUS" >}} because transmission integrity failures represent a fatal failure in the standard structure of the design, something that should never happen.
+- It is registered in {{#regref flash_ctrl.ERR_CODE }} so software can discover during operation status that a program has failed.
+- It is registered in {{#regref flash_ctrl.STD_FAULT_STATUS }} because transmission integrity failures represent a fatal failure in the standard structure of the design, something that should never happen.
##### Life Cycle Management Interface / Hardware Initiated Access to Flash Macro {#hw-controller-op}
The life cycle management interface issues transactions directly to the flash controller and does not perform a command payload integrity check.
For read operations, the read data and its associated integrity are directly checked by the life cycle management interface.
-If an integrity error is seen, it is registered in {{< regref "FAULT_STATUS.LCMGR_INTG_ERR" >}}.
+If an integrity error is seen, it is registered in {{#regref flash_ctrl.FAULT_STATUS.LCMGR_INTG_ERR }}.
For program operations, the program data and its associated integrity are propagated into the flash controller.
-If an integrity error is seen, an error is registered in {{< regref "FAULT_STATUS.PROG_INTG_ERR" >}}.
+If an integrity error is seen, an error is registered in {{#regref flash_ctrl.FAULT_STATUS.PROG_INTG_ERR }}.
#### ECC and ICV Related Read Errors
@@ -400,8 +400,8 @@
Flash reliability ECC errors (multi-bit errors) and integrity check errors (integrity check errors) are both reflected as in-band errors to the entity that issued the transaction.
That means if a host direct read, controller initiated read or hardware initiated read encounters one of these errors, the error is directly reflected in the operation status.
-Further, reliability ECC / integrity check errors are also captured in {{< regref "FAULT_STATUS" >}} and can be used to generate fatal alerts.
-The reason these are not captured in {{< regref "STD_FAULT_STATUS" >}} is because 1 or 2 bit errors can occur in real usage due to environmental conditions, thus they do not belong to the standard group of structural errors.
+Further, reliability ECC / integrity check errors are also captured in {{#regref flash_ctrl.FAULT_STATUS }} and can be used to generate fatal alerts.
+The reason these are not captured in {{#regref flash_ctrl.STD_FAULT_STATUS }} is because 1 or 2 bit errors can occur in real usage due to environmental conditions, thus they do not belong to the standard group of structural errors.
If we assume 2-bit errors can occur, then software must have a mechanism to recover from the error instead of [escalation](#flash-escalation).
#### Flash Escalation
@@ -409,7 +409,7 @@
Flash has two sources of escalation - global and local.
Global escalation is triggered by the life cycle controller through `lc_escalate_en`.
-Local escalation is triggered by a standard faults of flash, seen in {{< regref "STD_FAULT_STATUS" >}}.
+Local escalation is triggered by a standard faults of flash, seen in {{#regref flash_ctrl.STD_FAULT_STATUS }}.
Local escalation is not configurable and automatically triggers when this subset of faults are seen.
For the escalation behavior, see [flash access disable](#flash-access-disable) .
@@ -418,7 +418,7 @@
Flash access can be disabled through global escalation trigger, local escalation trigger, rma process completion or software command.
The escalation triggers are described [here](#flash-escalation).
-The software command to disable flash can be found in {{< regref "DIS" >}}.
+The software command to disable flash can be found in {{#regref flash_ctrl.DIS }}.
The description for rma entry can be found [here](#rma-entry-handling).
When disabled, the flash has a two layered response:
@@ -454,7 +454,7 @@
This section describes the open source modeling of flash memory.
The actual flash memory behavior may differ, and should consult the specific vendor or technology specification.
-When a bank erase command is issued and allowed, see [bank erase protection](#bank-erase-protection), the erase behavior is dependent on {{< regref "CONTROL.PARTITION_SEL" >}}.
+When a bank erase command is issued and allowed, see [bank erase protection](#bank-erase-protection), the erase behavior is dependent on {{#regref flash_ctrl.CONTROL.PARTITION_SEL }}.
- If data partition is selected, all data in the data partition is erased.
- If info partition is selected, all data in the data partition is erased AND all data in the info partitions (including all info types) is also erased.
@@ -564,7 +564,7 @@
When a page erase / program is issued to a flash bank, only entries that fall into that address range are evicted.
When a bank erase is issued, then all entries are evicted.
-The flash buffer is only enabled after {{< regref "INIT" >}} is invoked.
+The flash buffer is only enabled after {{#regref flash_ctrl.INIT }} is invoked.
When an RMA entry sequence is received, the flash buffers are disabled.
As an example, assume a flash word is made up of 2 bus words.
@@ -586,9 +586,9 @@
The information partition uses the same address scheme as the data partition - which is directly accessible by software.
This means the address of page{N}.word{M} is the same no matter which type of partition is accessed.
-Which partition a specific transaction accesses is denoted through a separate field {{< regref "CONTROL.PARTITION_SEL" >}} in the {{< regref "CONTROL" >}} register.
-If {{< regref "CONTROL.PARTITION_SEL" >}} is set, then the information partition is accessed.
-If {{< regref "CONTROL.PARTITION_SEL" >}} is not set, then the corresponding word in the data partition is accessed.
+Which partition a specific transaction accesses is denoted through a separate field {{#regref flash_ctrl.CONTROL.PARTITION_SEL }} in the {{#regref flash_ctrl.CONTROL }} register.
+If {{#regref flash_ctrl.CONTROL.PARTITION_SEL }} is set, then the information partition is accessed.
+If {{#regref flash_ctrl.CONTROL.PARTITION_SEL }} is not set, then the corresponding word in the data partition is accessed.
Flash scrambling, if enabled, also applies to information partitions.
It may be required for manufacturers to directly inject data into specific pages flash information partitions via die contacts.
@@ -621,7 +621,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/flash_ctrl.hjson" "hwcfg" >}}
+* [Interface Tables](data/flash_ctrl.hjson#interfaces)
### Signals
@@ -752,21 +752,21 @@
* Specify the operation to be 'READ' type
* Set the 'START' bit for the operation to begin
-The above fields can be set in the {{< regref "CONTROL" >}} and {{< regref "ADDR" >}} registers.
+The above fields can be set in the {{#regref flash_ctrl.CONTROL }} and {{#regref flash_ctrl.ADDR }} registers.
See [library code](https://github.com/lowRISC/opentitan/blob/master/sw/device/lib/flash_ctrl.c) for implementation.
It is acceptable for total number of flash words to be significantly greater than the depth of the read FIFO.
In this situation, the read FIFO will fill up (or hit programmable fill value), pause the flash read and trigger an interrupt to software.
Once there is space inside the FIFO, the controller will resume reading until the appropriate number of words have been read.
-Once the total count has been reached, the flash controller will post OP_DONE in the {{< regref "OP_STATUS" >}} register.
+Once the total count has been reached, the flash controller will post OP_DONE in the {{#regref flash_ctrl.OP_STATUS }} register.
## Issuing a Controller Program
To program flash, the same procedure as read is followed.
-However, instead of setting the {{< regref "CONTROL" >}} register for read operation, a program operation is selected instead.
+However, instead of setting the {{#regref flash_ctrl.CONTROL }} register for read operation, a program operation is selected instead.
Software will then fill the program FIFO and wait for the controller to consume this data.
Similar to the read case, the controller will automatically stall when there is insufficient data in the FIFO.
-When all desired words have been programmed, the controller will post OP_DONE in the {{< regref "OP_STATUS" >}} register.
+When all desired words have been programmed, the controller will post OP_DONE in the {{#regref flash_ctrl.OP_STATUS }} register.
## Debugging a Read Error
Since flash has multiple access modes, debugging read errors can be complicated.
@@ -781,14 +781,14 @@
Once the address is discovered, further steps can be taken to triage the issue.
### Error Encountered by Software Initiated Controller Operations
-A controller operation can encounter a much greater variety of errors, see {{< regref "ERR_CODE" >}}.
-When such an error is encountered, as reflected by {{< regref "OP_STATUS" >}} when the operation is complete, software can examine the {{< regref "ERR_ADDR" >}} to determine the error location.
+A controller operation can encounter a much greater variety of errors, see {{#regref flash_ctrl.ERR_CODE }}.
+When such an error is encountered, as reflected by {{#regref flash_ctrl.OP_STATUS }} when the operation is complete, software can examine the {{#regref flash_ctrl.ERR_ADDR }} to determine the error location.
Once the address is discovered, further steps can be taken to triage the issue.
### Correctable ECC Errors
Correctable ECC errors are by nature not fatal errors and do not stop operation.
Instead, if the error is correctable, the flash controller fixes the issue and registers the last address where a single bit error was seen.
-See {{< regref "ECC_SINGLE_ERR_CNT" >}} and {{< regref "ECC_SINGLE_ERR_ADDR" >}}
+See {{#regref flash_ctrl.ECC_SINGLE_ERR_CNT }} and {{#regref flash_ctrl.ECC_SINGLE_ERR_ADDR }}
## Device Interface Functions (DIFs)
@@ -799,4 +799,4 @@
The flash protocol controller maintains two separate access windows for the FIFO.
It is implemented this way because the access window supports transaction back-pressure should the FIFO become full (in case of write) or empty (in case of read).
-{{< incGenFromIpDesc "../data/flash_ctrl.hjson" "registers" >}}
+* [Register Table](data/flash_ctrl.hjson#registers)
diff --git a/hw/ip/gpio/README.md b/hw/ip/gpio/README.md
index 5e76c22..85b13c6 100644
--- a/hw/ip/gpio/README.md
+++ b/hw/ip/gpio/README.md
@@ -61,7 +61,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/gpio.hjson" "hwcfg" >}}
+* [Interface Tables](data/gpio.hjson#interfaces)
## Design Details
@@ -70,26 +70,26 @@
![GPIO Output Diagram](./doc/gpio_output.svg)
The GPIO module maintains one 32-bit output register `DATA_OUT` with two
-ways to write to it. Direct write access uses {{< regref "DIRECT_OUT" >}}, and
-masked access uses {{< regref "MASKED_OUT_UPPER" >}} and
-{{< regref "MASKED_OUT_LOWER" >}}. Direct access provides full write and read
+ways to write to it. Direct write access uses {{#regref gpio.DIRECT_OUT }}, and
+masked access uses {{#regref gpio.MASKED_OUT_UPPER }} and
+{{#regref gpio.MASKED_OUT_LOWER }}. Direct access provides full write and read
access for all 32 bits in one register.
For masked access the bits to modify are given as a mask in the upper
-16 bits of the {{< regref "MASKED_OUT_UPPER" >}} and
-{{< regref "MASKED_OUT_LOWER" >}} register write, while the data to write is
+16 bits of the {{#regref gpio.MASKED_OUT_UPPER }} and
+{{#regref gpio.MASKED_OUT_LOWER }} register write, while the data to write is
provided in the lower 16 bits of the register write. The hardware updates
`DATA_OUT` with the mask so that the modification is done without software
requiring a Read-Modify-Write.
Reads of masked registers return the lower/upper 16 bits of the `DATA_OUT`
contents. Zeros are returned in the upper 16 bits (mask field). To read
-what is on the pins, software should read the {{< regref "DATA_IN" >}} register.
+what is on the pins, software should read the {{#regref gpio.DATA_IN }} register.
(See [GPIO Input](#gpio-input) section below).
The same concept is duplicated for the output enable register `DATA_OE`.
-Direct access uses {{< regref "DIRECT_OE" >}}, and masked access is available
-using {{< regref "MASKED_OE_UPPER" >}} and {{< regref "MASKED_OE_LOWER" >}}.
+Direct access uses {{#regref gpio.DIRECT_OE }}, and masked access is available
+using {{#regref gpio.MASKED_OE_UPPER }} and {{#regref gpio.MASKED_OE_LOWER }}.
The output enable is sent to the pad control block to determine if the
pad should drive the `DATA_OUT` value to the associated pin or not.
@@ -104,24 +104,24 @@
### GPIO Input
-The {{< regref "DATA_IN" >}} register returns the contents as seen on the
+The {{#regref gpio.DATA_IN }} register returns the contents as seen on the
peripheral input, typically from the pads connected to those inputs. In the
presence of a pin-multiplexing unit, GPIO peripheral inputs that are
not connected to a chip input will be tied to a constant zero input.
The GPIO module provides optional independent noise filter control for
each of the 32 input signals. Each input can be independently enabled with
-the {{< regref "CTRL_EN_INPUT_FILTER" >}} (one bit per input). This 16-cycle
-filter is applied to both the {{< regref "DATA_IN" >}} register and
-the interrupt detection logic. The timing for {{< regref "DATA_IN" >}} is still
-not instantaneous if {{< regref "CTRL_EN_INPUT_FILTER" >}} is false as there is
+the {{#regref gpio.CTRL_EN_INPUT_FILTER }} (one bit per input). This 16-cycle
+filter is applied to both the {{#regref gpio.DATA_IN }} register and
+the interrupt detection logic. The timing for {{#regref gpio.DATA_IN }} is still
+not instantaneous if {{#regref gpio.CTRL_EN_INPUT_FILTER }} is false as there is
top-level routing involved, but no flops are between the chip input and the
-{{< regref "DATA_IN" >}} register.
+{{#regref gpio.DATA_IN }} register.
-The contents of {{< regref "DATA_IN" >}} are always readable and reflect the
+The contents of {{#regref gpio.DATA_IN }} are always readable and reflect the
value seen at the chip input pad regardless of the output enable setting from
DATA_OE. If the output enable is true (and the GPIO is connected to a
-chip-level pad), the value read from {{< regref "DATA_IN" >}} includes the
+chip-level pad), the value read from {{#regref gpio.DATA_IN }} includes the
effect of the peripheral's driven output (so will only differ from DATA_OUT if
the output driver is unable to switch the pin or during the delay imposed
if the noise filter is enabled).
@@ -132,17 +132,17 @@
Each interrupt can be independently enabled, tested, and configured.
Following the standard interrupt guidelines in the [Comportability
Specification](../../../doc/contributing/hw/comportability/README.md),
-the 32 bits of the {{< regref "INTR_ENABLE" >}} register determines whether the
+the 32 bits of the {{#regref gpio.INTR_ENABLE }} register determines whether the
associated inputs are configured to detect interrupt events. If enabled
via the various `INTR_CTRL_EN` registers, their current state can be
-read in the {{< regref "INTR_STATE" >}} register. Clearing is done by writing a
-`1` into the associated {{< regref "INTR_STATE" >}} bit field.
+read in the {{#regref gpio.INTR_STATE }} register. Clearing is done by writing a
+`1` into the associated {{#regref gpio.INTR_STATE }} bit field.
For configuration, there are 4 types of interrupts available per bit,
-controlled with four control registers. {{< regref "INTR_CTRL_EN_RISING" >}}
+controlled with four control registers. {{#regref gpio.INTR_CTRL_EN_RISING }}
configures the associated input for rising-edge detection.
-Similarly, {{< regref "INTR_CTRL_EN_FALLING" >}} detects falling edge inputs.
-{{< regref "INTR_CTRL_EN_LVLHIGH" >}} and {{< regref "INTR_CTRL_EN_LVLLOW" >}}
+Similarly, {{#regref gpio.INTR_CTRL_EN_FALLING }} detects falling edge inputs.
+{{#regref gpio.INTR_CTRL_EN_LVLHIGH }} and {{#regref gpio.INTR_CTRL_EN_LVLLOW }}
allow the input to be level sensitive interrupts. In theory an input can be
configured to detect both a rising and falling edge, but there is no hardware
assistance to indicate which edge caused the output interrupt.
@@ -279,4 +279,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/gpio.hjson" "registers" >}}
+* [Register Table](data/gpio.hjson#registers)
diff --git a/hw/ip/hmac/README.md b/hw/ip/hmac/README.md
index 4b8f6aa..e74ba0a 100644
--- a/hw/ip/hmac/README.md
+++ b/hw/ip/hmac/README.md
@@ -27,8 +27,8 @@
It is meant purely for hashing acceleration.
If hardened MAC operations are required, users should use either [KMAC](../kmac/README.md) or a software implementation.
-The 256-bit secret key is written in {{< regref "KEY_0" >}} to {{< regref "KEY_7" >}}.
-The message to authenticate is written to {{< regref "MSG_FIFO" >}} and the HMAC generates a 256-bit digest value which can be read from {{< regref "DIGEST_0" >}} to {{< regref "DIGEST_7" >}}.
+The 256-bit secret key is written in {{#regref hmac.KEY_0 }} to {{#regref hmac.KEY_7 }}.
+The message to authenticate is written to {{#regref hmac.MSG_FIFO }} and the HMAC generates a 256-bit digest value which can be read from {{#regref hmac.DIGEST_0 }} to {{#regref hmac.DIGEST_7 }}.
The `hash_done` interrupt is raised to report to software that the final digest is available.
The HMAC IP can run in SHA-256-only mode, whose purpose is to check the
@@ -38,13 +38,13 @@
The software doesn't need to provide the message length. The HMAC IP
will calculate the length of the message received between **1** being written to
-{{< regref "CMD.hash_start" >}} and **1** being written to {{< regref "CMD.hash_process" >}}.
+{{#regref hmac.CMD.hash_start }} and **1** being written to {{#regref hmac.CMD.hash_process }}.
This version doesn't have many defense mechanisms but is able to
wipe internal variables such as the secret key, intermediate hash results
H, digest and the message FIFO. It does not wipe the software accessible 16x32b FIFO.
The software can wipe the variables by writing a 32-bit random value into
-{{< regref "WIPE_SECRET" >}} register. The internal variables will be reset to the written
+{{#regref hmac.WIPE_SECRET }} register. The internal variables will be reset to the written
value. This version of the HMAC doesn't have a internal pseudo-random number
generator to derive the random number from the written seed number.
@@ -84,24 +84,24 @@
## Hardware Interface
-{{< incGenFromIpDesc "../data/hmac.hjson" "hwcfg" >}}
+* [Interface Tables](data/hmac.hjson#interfaces)
## Design Details
### SHA-256 message feed and pad
A message is fed via a memory-mapped message FIFO. Any write access to the
-memory-mapped window {{< regref "MSG_FIFO" >}} updates the message FIFO. If the FIFO is full,
+memory-mapped window {{#regref hmac.MSG_FIFO }} updates the message FIFO. If the FIFO is full,
the HMAC block will block any writes leading to back-pressure on the
interconnect (as opposed to dropping those writes or overwriting existing FIFO
contents). It is recommended this back-pressure is avoided by not writing to the
memory-mapped message FIFO when it is full. To avoid doing so, software can
-read the {{< regref "STATUS.fifo_full" >}} register.
+read the {{#regref hmac.STATUS.fifo_full }} register.
The logic assumes the input message is little-endian.
It converts the byte order of the word right before writing to SHA2 storage as SHA2 treats the incoming message as big-endian.
-If SW wants to convert the message byte order, SW should set {{< regref "CFG.endian_swap" >}} to **1**.
-The byte order of the digest registers, from {{< regref "DIGEST_0" >}} to {{< regref "DIGEST_7" >}} can be configured with {{< regref "CFG.digest_swap" >}}.
+If SW wants to convert the message byte order, SW should set {{#regref hmac.CFG.endian_swap }} to **1**.
+The byte order of the digest registers, from {{#regref hmac.DIGEST_0 }} to {{#regref hmac.DIGEST_7 }} can be configured with {{#regref hmac.CFG.digest_swap }}.
See the table below:
@@ -116,7 +116,7 @@
Push to SHA2 #1 | 00000004h | 00000005h
-Small writes to {{< regref "MSG_FIFO" >}} are coalesced with into 32-bit words by the [packer logic](../prim/doc/prim_packer.md).
+Small writes to {{#regref hmac.MSG_FIFO }} are coalesced with into 32-bit words by the [packer logic]({{< relref "hw/ip/prim/doc/prim_packer" >}}).
These words are fed into the internal message FIFO.
While passing writes to the packer logic, the block also counts the number of bytes that are being passed.
This gives the received message length, which is used in HMAC and SHA-256 as part of the hash computation.
@@ -238,9 +238,9 @@
## Initialization
This section of the code describes initializing the HMAC-SHA256, setting up the
-interrupts, endianness, and HMAC, SHA-256 mode. {{< regref "CFG.endian_swap" >}} reverses
+interrupts, endianness, and HMAC, SHA-256 mode. {{#regref hmac.CFG.endian_swap }} reverses
the byte-order of input words when software writes into the message FIFO.
-{{< regref "CFG.digest_swap" >}} reverses the byte-order in the final HMAC or SHA hash.
+{{#regref hmac.CFG.digest_swap }} reverses the byte-order in the final HMAC or SHA hash.
```c
void hmac_init(unsigned int endianess, unsigned int digest_endian) {
@@ -267,8 +267,8 @@
The following code shows how to send a message to the HMAC, the procedure is
the same whether a full HMAC or just a SHA-256 calculation is required (choose
-between them using {{< regref "CFG.hmac_en" >}}). In both cases the SHA-256 engine must be
-enabled using {{< regref "CFG.sha_en" >}} (once all other configuration has been properly set).
+between them using {{#regref hmac.CFG.hmac_en }}). In both cases the SHA-256 engine must be
+enabled using {{#regref hmac.CFG.sha_en }} (once all other configuration has been properly set).
If the message is bigger than 512-bit, the software must wait until the FIFO
isn't full before writing further bits.
@@ -301,15 +301,15 @@
## Updating the configurations
-The HMAC IP prevents {{< regref "CFG" >}} and {{< regref "KEY" >}} registers from updating while the engine is processing messages.
+The HMAC IP prevents {{#regref hmac.CFG }} and {{#regref hmac.KEY }} registers from updating while the engine is processing messages.
Such attempts are discarded.
-The {{< regref "KEY" >}} register ignores any attempt to access the secret key in the middle of the process.
+The {{#regref hmac.KEY }} register ignores any attempt to access the secret key in the middle of the process.
If the software tries to update the KEY, the IP reports an error through the Error FIFO. The error code is `SwUpdateSecretKeyInProcess`, `0x0003`.
## Errors
-When HMAC sees errors, the IP reports the error via {{<regref "INTR_STATUS.hmac_err" >}}.
-The details of the error type is stored in {{<regref "ERR_CODE">}}.
+When HMAC sees errors, the IP reports the error via {{#regref hmac.INTR_STATUS.hmac_err }}.
+The details of the error type is stored in {{#regref hmac.ERR_CODE }}.
Error | Value | Description
-----------------------------|-------|---------------
@@ -324,8 +324,8 @@
### FIFO_EMPTY
If the FIFO_FULL interrupt occurs, it is recommended the software does not write
-more data into {{< regref "MSG_FIFO" >}} until the interrupt is cleared and the status
-{{< regref "STATUS.fifo_full" >}} is lowered. Whilst the FIFO is full the HMAC will block
+more data into {{#regref hmac.MSG_FIFO }} until the interrupt is cleared and the status
+{{#regref hmac.STATUS.fifo_full }} is lowered. Whilst the FIFO is full the HMAC will block
writes until the FIFO has space which will cause back-pressure on the
interconnect.
@@ -335,4 +335,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/hmac.hjson" "registers" >}}
+* [Register Table](data/hmac.hjson#registers)
diff --git a/hw/ip/i2c/README.md b/hw/ip/i2c/README.md
index 493b57a..7a525a6 100644
--- a/hw/ip/i2c/README.md
+++ b/hw/ip/i2c/README.md
@@ -82,7 +82,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/i2c.hjson" "hwcfg" >}}
+* [Interface Tables](data/i2c.hjson#interfaces)
## Design Details
@@ -90,7 +90,7 @@
I2C IP is a host-target combo that can function as either an I2C host or an I2C target.
Although it is conceivable that an I2C combo can optionally function as both a host and a target at the same time, we do not support this feature at this time.
-These functional modes are enabled at runtime by setting the register fields {{< regref CTRL.ENABLEHOST >}} and {{< regref CTRL.ENABLETARGET >}}.
+These functional modes are enabled at runtime by setting the register fields {{#regref i2c.CTRL.ENABLEHOST }} and {{#regref i2c.CTRL.ENABLETARGET }}.
### Virtual Open Drain
@@ -111,10 +111,10 @@
However, there is a simpler "override" mode, by which these pins can be directly manipulated by software.
This override mode is useful for troubleshooting or error-recovery.
-To enter override mode, the register field {{< regref OVRD.TXOVRDEN >}} is asserted by software.
-In this state the output drivers `scl_tx_o` and `sda_tx_o` are controlled directly by the register fields {{< regref OVRD.SCLVAL >}} and {{< regref OVRD.SDAVAL >}}.
-When {{< regref OVRD.SCLVAL >}} and {{< regref OVRD.SDAVAL >}} are set high, the virtual open drain configuration will leave the output resistively pulled high, and controllable by remote targets.
-In this state, with SCL or SDA asserted high, the register fields {{< regref VAL.SCL_RX >}} and {{< regref VAL.SDA_RX >}} can be used to receive inputs (including remote acknowledgments) from target devices.
+To enter override mode, the register field {{#regref i2c.OVRD.TXOVRDEN }} is asserted by software.
+In this state the output drivers `scl_tx_o` and `sda_tx_o` are controlled directly by the register fields {{#regref i2c.OVRD.SCLVAL }} and {{#regref i2c.OVRD.SDAVAL }}.
+When {{#regref i2c.OVRD.SCLVAL }} and {{#regref i2c.OVRD.SDAVAL }} are set high, the virtual open drain configuration will leave the output resistively pulled high, and controllable by remote targets.
+In this state, with SCL or SDA asserted high, the register fields {{#regref i2c.VAL.SCL_RX }} and {{#regref i2c.VAL.SDA_RX }} can be used to receive inputs (including remote acknowledgments) from target devices.
#### FSM control of SCL and SDA
@@ -139,27 +139,27 @@
- Which bytes should be preceded by a START symbol.
- Which bytes should be followed by a STOP symbol
The format indicator consists of 13-bits.
-That is of one single Format Byte (entered into the format FIFO through {{< regref FDATA.FBYTE >}}), and five (5) 1-bit flags (entered into the format FIFO through registers {{< regref FDATA.READ >}}, {{< regref FDATA.RCONT >}}, {{< regref FDATA.START >}}, {{< regref FDATA.STOP >}} and {{< regref FDATA.NAKOK >}})
+That is of one single Format Byte (entered into the format FIFO through {{#regref i2c.FDATA.FBYTE }}), and five (5) 1-bit flags (entered into the format FIFO through registers {{#regref i2c.FDATA.READ }}, {{#regref i2c.FDATA.RCONT }}, {{#regref i2c.FDATA.START }}, {{#regref i2c.FDATA.STOP }} and {{#regref i2c.FDATA.NAKOK }})
The I2C reads each format indicator from the head of FMT_FIFO, and processes them in turn.
If none of the flags are set for the format indicator, the I2C FSM simply transmits the Format Byte onto the SCL and SDA pins according to the specification, waits for acknowledgement, and then proceeds to the next format indicator.
The format flags modulate the behavior as follows.
-- READ (corresponds to {{< regref FDATA.READ >}}):
-Signifies the Format Byte ({{< regref FDATA.FBYTE >}}) should be treated as an unsigned number, R, and prompts the state machine to read R bytes from the target device.
+- READ (corresponds to {{#regref i2c.FDATA.READ }}):
+Signifies the Format Byte ({{#regref i2c.FDATA.FBYTE }}) should be treated as an unsigned number, R, and prompts the state machine to read R bytes from the target device.
Bytes read from the bus, are inserted into the RX FIFO where they can be accessed by software.
A value of 0 is treated as a read of 256B.
To read a larger byte stream, multiple 256B reads can be chained together using the RCONT flag.
-- RCONT (corresponds to FIFO inputs {{< regref FDATA.RCONT >}}, only used with READ):
+- RCONT (corresponds to FIFO inputs {{#regref i2c.FDATA.RCONT }}, only used with READ):
- If RCONT is set, the Format Byte represents part of a longer sequence of reads, allowing for reads to be chained indefinitely.
- The RCONT flag indicates the the final byte returned with the current read should be responded to with an ACK, allowing the target to continue sending data.
(Note that the first R-1 bytes read will still be acknowledged regardless of whether RCONT is asserted or not.)
-- START (corresponds to {{< regref FDATA.START >}}, Ignored when used with READ):
+- START (corresponds to {{#regref i2c.FDATA.START }}, Ignored when used with READ):
Issue a START condition before transmitting the Format Byte on the bus.
- This flag may also be used to issue a repeated start condition.
-- STOP (corresponds to {{< regref FDATA.STOP >}}):
+- STOP (corresponds to {{#regref i2c.FDATA.STOP }}):
Issue a STOP signal after processing this current entry in the FMT FIFO.
- Note that this flag is not compatible with (READ & RCONT), and will cause bus conflicts.
-- NAKOK (corresponds to {{< regref FDATA.NAKOK >}}, Not compatible with READ):
+- NAKOK (corresponds to {{#regref i2c.FDATA.NAKOK }}, Not compatible with READ):
Typically every byte transmitted must also receive an ACK signal, and the IP will raise an exception if no ACK is received.
However, there are some I2C commands which do not require an ACK.
In those cases this flag should be asserted with FBYTE indicating no ACK is expected and no interrupt should be raised if the ACK is not received.
@@ -172,13 +172,13 @@
Thus, with the masks set to all ones (0x7F), the target device will respond to either of the two assigned unique addresses and no other.
If the mask and the assigned address both have zeros in a particular bit position, that bit will be a match regardless of the value of that bit received from the host.
Note that if, in any bit position, the mask has zero and the assigned address has one, no transaction can match and such mask/address pair is effectively disabled.
-The assigned address and mask pairs are set in registers {{< regref TARGET_ID.ADDRESS0 >}}, {{< regref TARGET_ID.MASK0 >}}, {{< regref TARGET_ID.ADDRESS1 >}}, and {{< regref TARGET_ID.MASK1 >}}.
+The assigned address and mask pairs are set in registers {{#regref i2c.TARGET_ID.ADDRESS0 }}, {{#regref i2c.TARGET_ID.MASK0 }}, {{#regref i2c.TARGET_ID.ADDRESS1 }}, and {{#regref i2c.TARGET_ID.MASK1 }}.
### Acquired Formatted Data
This section applies to I2C in the target mode.
When the target accepts a transaction, it inserts the transaction address, read/write bit, and START signal sent by the host into ACQ FIFO where they can be accessed by software.
-ACQ FIFO output corresponds to {{< regref ACQDATA >}}.
+ACQ FIFO output corresponds to {{#regref i2c.ACQDATA }}.
If the transaction is a write operation (R/W bit = 0), the target proceeds to read bytes from the bus and insert them into ACQ FIFO until the host terminates the transaction by sending a STOP or a repeated START signal.
A STOP or repeated START indicator is inserted into ACQ FIFO as the next entry following the last byte received, in which case other bits may be junk.
The following diagram shows consecutive entries inserted into ACQ FIFO during a write operation:
@@ -188,7 +188,7 @@
If the transaction is a read operation (R/W bit = 1), the target pulls bytes out of TX FIFO and transmits them to the bus until the host signals the end of the transfer by sending a NACK signal.
If TX FIFO holds no data, or if the ACQ FIFO contains more than 1 entry, the target will hold SCL low to stretch the clock and give software time to write data bytes into TX FIFO or handle the available command.
See (#stretching-during-read) for more details.
-TX FIFO input corresponds to {{< regref TXDATA >}}.
+TX FIFO input corresponds to {{#regref i2c.TXDATA }}.
Typically, a NACK signal is followed by a STOP or repeated START signal and the IP will raise an exception if the host sends a STOP signal after an ACK.
An ACK/NACK signal is inserted into the ACQ FIFO as the first bit (bit 0), in the same entry with a STOP or repeated START signal.
For ACK and NACK signals, the value of the first bit is 0 and 1, respectively.
@@ -215,26 +215,26 @@
$$ 1/f\_{SCL}=t\_{LOW}+t\_{HIGH}+t\_{r}+t\_{f}. $$
Thus in order to ensure compliance with the spec in any particular configuration, software will program the I2C host IP with explicit values for each of the following timing parameters, as defined in Figure 38 of the specification.
-- t<sub>LOW</sub>: set in register {{< regref TIMING0.TLOW >}}.
-- t<sub>HIGH</sub>: set in register {{< regref TIMING0.THIGH >}}.
-- t<sub>r</sub>: set in register {{< regref TIMING1.T_R >}}.
+- t<sub>LOW</sub>: set in register {{#regref i2c.TIMING0.TLOW }}.
+- t<sub>HIGH</sub>: set in register {{#regref i2c.TIMING0.THIGH }}.
+- t<sub>r</sub>: set in register {{#regref i2c.TIMING1.T_R }}.
(Note: The rise time cannot be explicitly controlled by internal hardware, and will be a function of the capacitance of the bus.
Thus this parameter is largely budgetary, meaning that it tells the state machine how much time to wait for an RC rise.)
-- t<sub>f</sub>: set in register {{< regref TIMING1.T_F >}}.
+- t<sub>f</sub>: set in register {{#regref i2c.TIMING1.T_F }}.
(Note: The fall time cannot be explicitly controlled by internal hardware, and is a function of the pin driver.
Thus this parameter is also budgetary.
Given that the actual fall time cannot be controlled to stay above the minimum values set in Table 10 of the specification, and so this in this regard this module currently is not strictly compliant to the I2C spec.)
-- t<sub>SU,STA</sub>: set in register {{< regref TIMING2.TSU_STA >}}
-- t<sub>HD,STA</sub>: set in register {{< regref TIMING2.THD_STA >}}
-- t<sub>SU,DAT</sub>: set in register {{< regref TIMING3.TSU_DAT >}}.
+- t<sub>SU,STA</sub>: set in register {{#regref i2c.TIMING2.TSU_STA }}
+- t<sub>HD,STA</sub>: set in register {{#regref i2c.TIMING2.THD_STA }}
+- t<sub>SU,DAT</sub>: set in register {{#regref i2c.TIMING3.TSU_DAT }}.
Taken to be synonymous with T<sub>SU,ACK</sub>
-- t<sub>HD,DAT</sub>: set in register {{< regref TIMING3.THD_DAT >}}.
+- t<sub>HD,DAT</sub>: set in register {{#regref i2c.TIMING3.THD_DAT }}.
Taken to be synonymous with T<sub>HD,ACK</sub>.
Moreover, since the pin driver fall time is likely to be less then one clock cycle, this parameter is also taken to be synonymous with the parameters T<sub>VD,DAT</sub> and T<sub>VD,ACK</sub>
-- t<sub>SU,STO</sub>: set in register {{< regref TIMING4.TSU_STO >}}.
-- t<sub>BUF</sub>: set in register {{< regref TIMING4.T_BUF >}}
+- t<sub>SU,STO</sub>: set in register {{#regref i2c.TIMING4.TSU_STO }}.
+- t<sub>BUF</sub>: set in register {{#regref i2c.TIMING4.T_BUF }}
-The values programmed into the registers {{< regref TIMING0 >}} through {{< regref TIMING4 >}} are to be expressed in units of the bus clock period.
+The values programmed into the registers {{#regref i2c.TIMING0 }} through {{#regref i2c.TIMING4 }} are to be expressed in units of the bus clock period.
Note in order to ensure compliance with the I2C spec, firmware must program these registers with values within the ranges laid out in Table 10 of the specification.
These values can be directly computed using DIFs given the desired speed standard, the desired operating frequency, and the actual line capacitance.
These timing parameters are then fed directly to the I2C state machine to control the bus timing.
@@ -243,8 +243,8 @@
### Timeout Control
A malfunctioning (or otherwise very slow) target device can hold SCL low indefinitely, stalling the bus.
-For this reason {{< regref TIMEOUT_CTRL >}} provides a clock-stretching timeout mechanism to notify firmware of this sort of condition.
-If {{< regref TIMEOUT_CTRL.EN >}} is asserted, an interrupt will be asserted when the IP detects that another device (a target or, in possible future revisions, an alternate host) has been holding SCL low for more than {{< regref TIMEOUT_CTRL.VAL >}} clock ticks.
+For this reason {{#regref i2c.TIMEOUT_CTRL }} provides a clock-stretching timeout mechanism to notify firmware of this sort of condition.
+If {{#regref i2c.TIMEOUT_CTRL.EN }} is asserted, an interrupt will be asserted when the IP detects that another device (a target or, in possible future revisions, an alternate host) has been holding SCL low for more than {{#regref i2c.TIMEOUT_CTRL.VAL }} clock ticks.
This feature is added as a utility, though it is not required by the I2C specification.
@@ -281,11 +281,11 @@
#### Host Mode
If the RX FIFO exceeds the designated depth of entries, the interrupt `rx_threshold` is raised to inform firmware.
-Firmware can configure the threshold value via the register {{< regref FIFO_CTRL.RXILVL >}}.
+Firmware can configure the threshold value via the register {{#regref i2c.FIFO_CTRL.RXILVL }}.
Meanwhile it the FMT FIFO level falls below a designated depth of entries the `fmt_threshold` interrupt is raised.
(Note that this behavior differs from similar interrupts in other modules, such as the UART IP module.)
-Firmware can configure the threshold value via the register {{< regref FIFO_CTRL.FMTILVL >}}.
+Firmware can configure the threshold value via the register {{#regref i2c.FIFO_CTRL.FMTILVL }}.
If either FIFO receives an additional write request when its FIFO is full, the interrupt `fmt_overflow` or `rx_overflow` is asserted and the format indicator or character is dropped.
@@ -315,8 +315,8 @@
{{</wavejson>}}
-Though normal clock stretching does not count as SCL interference, if the module detects that a target device has held SCL low and stretched the any given SCL cycle for more than {{< regref TIMEOUT_CTRL.VAL >}} clock ticks this will cause the stretch timeout interrupt to be asserted.
-This interrupt is suppressed, however, if {{< regref TIMEOUT_CTRL.EN >}} is deasserted low.
+Though normal clock stretching does not count as SCL interference, if the module detects that a target device has held SCL low and stretched the any given SCL cycle for more than {{#regref i2c.TIMEOUT_CTRL.VAL }} clock ticks this will cause the stretch timeout interrupt to be asserted.
+This interrupt is suppressed, however, if {{#regref i2c.TIMEOUT_CTRL.EN }} is deasserted low.
{{<wavejson>}}
{signal: [
@@ -357,7 +357,7 @@
If a host ceases to send SCL pulses at any point during an ongoing transaction, the target waits for a specified time period and then asserts the interrupt `host_timeout`.
Host sending an address and R/W bit to all target devices, writing to the selected target, or reading from the target are examples of ongoing transactions.
The time period is counted from the last low-to-high SCL transition.
-Firmware can configure the timeout value via the register {{< regref HOST_TIMEOUT_CTRL >}}.
+Firmware can configure the timeout value via the register {{#regref i2c.HOST_TIMEOUT_CTRL }}.
### Implementation Details: Format Flag Parsing
@@ -490,4 +490,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/i2c.hjson" "registers" >}}
+* [Register Table](data/i2c.hjson#registers)
diff --git a/hw/ip/keymgr/README.md b/hw/ip/keymgr/README.md
index 6687667..9bd7bcf 100644
--- a/hw/ip/keymgr/README.md
+++ b/hw/ip/keymgr/README.md
@@ -221,8 +221,8 @@
* Synchronous fatal errors
* Asynchronous fatal errors
-All recoverable errors (synchronous and asynchronous) are captured in {{< regref ERR_CODE >}}.
-All fatal errors (synchronous and asynchronous) are captured in {{< regref FAULT_STATUS >}}.
+All recoverable errors (synchronous and asynchronous) are captured in {{#regref keymgr.ERR_CODE }}.
+All fatal errors (synchronous and asynchronous) are captured in {{#regref keymgr.FAULT_STATUS }}.
Recoverable errors cause a recoverable alert to be sent from the key manager.
Fatal errors cause a fatal alert to be sent from the key manager.
@@ -232,29 +232,29 @@
### Synchronous Recoverable Errors
These errors can only happen when a key manager operation is invoked and are typically associated with incorrect software programming.
-At the end of the operation, key manager reports whether there was an error in {{< regref ERR_CODE >}} and sends a recoverable alert.
+At the end of the operation, key manager reports whether there was an error in {{#regref keymgr.ERR_CODE }} and sends a recoverable alert.
-* {{< regref ERR_CODE.INVALID_OP >}} Software issued an invalid operation given the current key manager state.
-* {{< regref ERR_CODE.INVALID_KMAC_INPUT >}} Software supplied invalid input (for example a key greater than the max version) for a key manager operation.
+* {{#regref keymgr.ERR_CODE.INVALID_OP }} Software issued an invalid operation given the current key manager state.
+* {{#regref keymgr.ERR_CODE.INVALID_KMAC_INPUT }} Software supplied invalid input (for example a key greater than the max version) for a key manager operation.
### Asynchronous Recoverable Errors
These errors can happen at any time regardless of whether there is a key manager operation.
-The error is reported in {{< regref ERR_CODE >}} and the key manager sends a recoverable alert.
+The error is reported in {{#regref keymgr.ERR_CODE }} and the key manager sends a recoverable alert.
-* {{< regref ERR_CODE.INVALID_SHADOW_UPDATE >}} Software performed an invalid sequence while trying to update a key manager shadow register.
+* {{#regref keymgr.ERR_CODE.INVALID_SHADOW_UPDATE }} Software performed an invalid sequence while trying to update a key manager shadow register.
### Synchronous Fatal Errors
These errors can only happen when a key manager operation is invoked and receives malformed operation results that are not logically possible.
-At the end of the operation, key manager reports whether there was an error in {{< regref FAULT_STATUS >}} and continuously sends fatal alerts .
+At the end of the operation, key manager reports whether there was an error in {{#regref keymgr.FAULT_STATUS }} and continuously sends fatal alerts .
Note, these errors are synchronous from the perspective of the key manager, but they may be asynchronous from the perspective of another module.
### Asynchronous Fatal Errors
These errors can happen at any time regardless of whether there is a key manager operation.
-The error is reported in {{< regref FAULT_STATUS >}} and the key manager continuously sends fatal alerts.
+The error is reported in {{#regref keymgr.FAULT_STATUS }} and the key manager continuously sends fatal alerts.
### Faults and Operational Faults
@@ -264,18 +264,18 @@
#### Example 1: Fault During Operation
The key manager is running a generate operation and a non-onehot command was observed by the KMAC interface.
-Since the non-onehot condition is a fault, it is reflected in {{< regref FAULT_STATUS >}} and a fatal alert is generated.
-The key manager transitions to `Invalid` state, wipes internal storage and reports an invalid operation in {{< regref ERR_CODE.INVALID_OP >}}.
+Since the non-onehot condition is a fault, it is reflected in {{#regref keymgr.FAULT_STATUS }} and a fatal alert is generated.
+The key manager transitions to `Invalid` state, wipes internal storage and reports an invalid operation in {{#regref keymgr.ERR_CODE.INVALID_OP }}.
#### Example 2: Fault During Idle
The key manager is NOT running an operation and is idle.
During this time, a fault is observed on the regfile (shadow storage error) and FSM (control FSM integrity error).
-The faults are reflected in {{< regref FAULT_STATUS >}}.
+The faults are reflected in {{#regref keymgr.FAULT_STATUS }}.
The key manager transitions to `Invalid` state, wipes internal storage but does not report an invalid operation.
#### Example 3: Operation after Fault Detection
Continuing from the example above, the key manager now begins an operation.
-Since the key manager is already in `Invalid` state, it does not wipe internal storage and reports an invalid operation in {{< regref ERR_CODE.INVALID_OP >}}.
+Since the key manager is already in `Invalid` state, it does not wipe internal storage and reports an invalid operation in {{#regref keymgr.ERR_CODE.INVALID_OP }}.
#### Additional Details on Invalid Input
@@ -344,16 +344,16 @@
There is one version for attestation and one version for sealing.
The main difference between the two CDIs is the different usage of `SW_BINDING`.
-For the Sealing CDI, the {{< regref "SEALING_SW_BINDING" >}} is used, all other inputs are the same.
-For the Attestation CDI, the {{< regref "ATTEST_SW_BINDING" >}} is used, all other inputs are the same.
+For the Sealing CDI, the {{#regref keymgr."SEALING_SW_BINDING" }} is used, all other inputs are the same.
+For the Attestation CDI, the {{#regref keymgr."ATTEST_SW_BINDING" }} is used, all other inputs are the same.
When invoking an advance operation, both versions are advanced, one after the other.
There are thus two KMAC transactions.
-The first transaction uses the Sealing CDI internal key, {{< regref "SEALING_SW_BINDING" >}} and other common inputs.
-The second transaction uses the Attestation CDI internal key, {{< regref "ATTEST_SW_BINDING" >}} and other common inputs.
+The first transaction uses the Sealing CDI internal key, {{#regref keymgr."SEALING_SW_BINDING" }} and other common inputs.
+The second transaction uses the Attestation CDI internal key, {{#regref keymgr."ATTEST_SW_BINDING" }} and other common inputs.
When invoking a generate operation, the software must specify which CDI to use as the source key.
-This is done through {{< regref "CONTROL.CDI_SEL" >}}.
+This is done through {{#regref keymgr."CONTROL.CDI_SEL" }}.
Unlike the advance operation, there is only 1 KMAC transaction since we pick a specific CDI to operate.
When disabling, both versions are disabled together.
@@ -430,7 +430,7 @@
When a valid operation is called, the internal state key is sent over the KMAC key.
During all other times, the sideloaded value is presented.
Note, there may not be a valid key in the sideload register if it has been cleared or never generated.
-The sideload key can be overwritten with another generate command, or cleared with entropy through {{< regref SIDELOAD_CLEAR >}}.
+The sideload key can be overwritten with another generate command, or cleared with entropy through {{#regref keymgr.SIDELOAD_CLEAR }}.
The clearing can be done one slot at a time, or all at once.
Once a clearing bit is enabled for a particular key slot, its value is continuously re-randomized every clock cycle.
@@ -481,10 +481,10 @@
- `CreatorRootKey` to `OwnerIntermedaiteKey`
- `OwnerIntermediateKey` to `OwnerRootKey`
-In order to save on storage and not have a duplicate copy per stage, the software binding registers {{< regref SOFTWARE_BINDING >}} are shared between key manager stages.
+In order to save on storage and not have a duplicate copy per stage, the software binding registers {{#regref keymgr.SOFTWARE_BINDING }} are shared between key manager stages.
-Software sets the appropriate values and locks it by clearing {{< regref SOFT_BINDING_EN >}}.
-When later a successful `advance` call is made, the key manager then unlocks by setting {{< regref SOFT_BINDING_EN >}} to 1.
+Software sets the appropriate values and locks it by clearing {{#regref keymgr.SOFT_BINDING_EN }}.
+When later a successful `advance` call is made, the key manager then unlocks by setting {{#regref keymgr.SOFT_BINDING_EN }} to 1.
An unsuccessful advance call (errors) does not unlock the binding.
This allows the next stage of software to re-use the binding registers.
@@ -494,30 +494,30 @@
#### One-Hot Command Check
The command received by the KMAC interface must always be in one-hot form and unchanging during the life time of a KMAC transaction.
-If this check fails, an error is reflected in {{< regref FAULT_STATUS.CMD >}}.
+If this check fails, an error is reflected in {{#regref keymgr.FAULT_STATUS.CMD }}.
#### Unexpected KMAC Done
The `kmac_done` signal can only happen during the expected transaction window.
-If this check fails, an error is reflected in {{< regref FAULT_STATUS.KMAC_DONE >}}.
+If this check fails, an error is reflected in {{#regref keymgr.FAULT_STATUS.KMAC_DONE }}.
#### Control State Machine Check
This error checks for two things:
- The key manager can advance to one of the key states (e.g. RootKey, OwnerIntermediateKey) only when there is a legal advanced operation.
- The key manager can issue an advance or generate operation to the KMAC interface only if the original software request is an advanced or generate command.
-If these checks fail, an error is reflected in {{< regref FAULT_STATUS.CTRL_FSM_CHK >}}.
+If these checks fail, an error is reflected in {{#regref keymgr.FAULT_STATUS.CTRL_FSM_CHK }}.
#### Sideload Select Check
A sideload key slot is selected for update only if the original software request targeted that key slot.
-If this check fails, an error is reflected in {{< regref FAULT_STATUS.SIDE_CTRL_SEL >}}.
+If this check fails, an error is reflected in {{#regref keymgr.FAULT_STATUS.SIDE_CTRL_SEL }}.
####
####
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/keymgr.hjson" "hwcfg" >}}
+* [Interface Tables](data/keymgr.hjson#interfaces)
# Programmers Guide
@@ -536,7 +536,7 @@
The key and valid signals remain asserted to the selected destination until software explicitly disables the output via another command, or issues another `generate-output-hw` command with a different destination primitive.
## Caveats
-The keymgr {{< regref WORKING_STATE >}} register allows software to discover the current state of `keymgr`.
+The keymgr {{#regref keymgr.WORKING_STATE }} register allows software to discover the current state of `keymgr`.
However, since these values are not hardened, they can be attacked.
As such, software should be careful to not make critical system decisions based on these registers.
They are meant generally for informational or debug purposes.
@@ -547,4 +547,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/keymgr.hjson" "registers" >}}
+* [Register Table](data/keymgr.hjson#registers)
diff --git a/hw/ip/kmac/README.md b/hw/ip/kmac/README.md
index c070405..0339af0 100644
--- a/hw/ip/kmac/README.md
+++ b/hw/ip/kmac/README.md
@@ -73,7 +73,7 @@
## Hardware Interface
-{{< incGenFromIpDesc "../data/kmac.hjson" "hwcfg" >}}
+* [Interface Tables](data/kmac.hjson#interfaces)
## Design Details
@@ -128,9 +128,9 @@
![](./doc/sha3-padding.svg)
-The hashing process begins when the software issues the start command to {{< regref "CMD" >}} .
+The hashing process begins when the software issues the start command to {{#regref kmac.CMD }} .
If cSHAKE is enabled, the padding logic expands the prefix value (`N || S` above) into a block size.
-The block size is determined by the {{< regref "CFG.kstrength" >}} .
+The block size is determined by the {{#regref kmac.CFG.kstrength }} .
If the value is 128, the block size will be 168 bytes.
If it is 256, the block size will be 136 bytes.
The expanded prefix value is transmitted to the Keccak round logic.
@@ -139,16 +139,16 @@
If the mode is not cSHAKE, or cSHAKE mode and the prefix block has been processed, the padding logic accepts the incoming message bitstream and forward the data to the Keccak round logic in a block granularity.
The padding logic controls the data flow and makes the Keccak logic to run after sending a block size.
-After the software writes the message bitstream, it should issue the Process command into {{< regref "CMD" >}} register.
-The padding logic, after receiving the Process command, appends proper ending bits with respect to the {{< regref "CFG.mode" >}} value.
+After the software writes the message bitstream, it should issue the Process command into {{#regref kmac.CMD }} register.
+The padding logic, after receiving the Process command, appends proper ending bits with respect to the {{#regref kmac.CFG.mode }} value.
The logic writes 0 up to the block size to the Keccak round logic then ends with 1 at the end of the block.
![](./doc/sha3-padding-fsm.svg)
After the Keccak round completes the last block, the padding logic asserts an `absorbed` signal to notify the software.
The signal generates the `kmac_done` interrupt.
-At this point, the software is able to read the digest in {{< regref "STATE" >}} memory region.
-If the output length is greater than the Keccak block rate in SHAKE and cSHAKE mode, the software may run the Keccak round manually by issuing Run command to {{< regref "CMD" >}} register.
+At this point, the software is able to read the digest in {{#regref kmac.STATE }} memory region.
+If the output length is greater than the Keccak block rate in SHAKE and cSHAKE mode, the software may run the Keccak round manually by issuing Run command to {{#regref kmac.CMD }} register.
The software completes the operation by issuing Done command after reading the digest.
The padding logic clears internal variables and goes back to Idle state.
@@ -160,8 +160,8 @@
KMAC core prepends and appends additional bitstream on top of Keccak padding logic in SHA3 core.
The [NIST SP 800-185][] defines `KMAC[128,256](K, X, L, S)` as a cSHAKE function.
See the section 4.3 in NIST SP 800-185 for details.
-If KMAC is enabled, the software should configure {{< regref "CMD.mode" >}} to cSHAKE and the first six bytes of {{< regref "PREFIX" >}} to `0x01204B4D4143` (bigendian).
-The first six bytes of {{< regref "PREFIX" >}} represents the value of `encode_string("KMAC")`.
+If KMAC is enabled, the software should configure {{#regref kmac.CMD.mode }} to cSHAKE and the first six bytes of {{#regref kmac.PREFIX }} to `0x01204B4D4143` (bigendian).
+The first six bytes of {{#regref kmac.PREFIX }} represents the value of `encode_string("KMAC")`.
The KMAC padding logic prepends a block containing the encoded secret key to the output message.
The KMAC first sends the block of secret key then accepts the incoming message bitstream.
@@ -192,7 +192,7 @@
However, the recommended approach to write messages is:
-1. Check the FIFO depth {{<regref "STATUS.fifo_depth" >}}. This represents the number of entry slots currently occupied in the FIFO.
+1. Check the FIFO depth {{#regref kmac.STATUS.fifo_depth }}. This represents the number of entry slots currently occupied in the FIFO.
2. Calculate the remaining size as `<max number of fifo entries> - <STATUS.fifo_depth>) * <entry size>`.
3. Write data to fill the remaining size.
4. Repeat until all data is written.
@@ -247,12 +247,12 @@
The message FIFO does not generate the masked message data.
Incoming message bitstream is not sensitive to the leakage.
-If the `EnMasking` parameter is set and {{<regref "CFG_SHADOWED.msg_mask" >}} is enabled, the message is masked upon loading into the Keccak core using the internal entropy generator.
+If the `EnMasking` parameter is set and {{#regref kmac.CFG_SHADOWED.msg_mask }} is enabled, the message is masked upon loading into the Keccak core using the internal entropy generator.
The secret key, however, is stored as masked form always.
If the `EnMasking` parameter is not set, the masking is disabled.
Then, the software has to provide the key in unmasked form by default.
-Any write operations to {{<regref "KEY_SHARE1_0" >}} - {{<regref "KEY_SHARE1_15" >}} are ignored.
+Any write operations to {{#regref kmac.KEY_SHARE1_0 }} - {{#regref kmac.KEY_SHARE1_15 }} are ignored.
If the `EnMasking` parameter is not set and the `SwKeyMasked` parameter is set, software has to provide the key in masked form.
Internally, the design then unmasks the key by XORing the two key shares together when loading the key into the engine.
@@ -279,7 +279,7 @@
![](./doc/application-interface.svg)
KMAC/SHA3 HWIP has an option to receive the secret key from the KeyMgr via sideload key interface.
-The software should set {{< regref "CFG.sideload" >}} to use the KeyMgr sideloaded key for the SW-initiated KMAC operation.
+The software should set {{#regref kmac.CFG.sideload }} to use the KeyMgr sideloaded key for the SW-initiated KMAC operation.
`keymgr_pkg::hw_key_t` defines the structure of the sideloaded key.
KeyMgr provides the sideloaded key in two-share masked form regardless of the compile-time parameter `EnMasking`.
If `EnMasking` is not defined, the KMAC merges the shared key to the unmasked form before uses the key.
@@ -323,7 +323,7 @@
This section explains the entropy generator inside the KMAC HWIP.
KMAC has an entropy generator to provide the design with pseudo-random numbers while processing the secret key block.
-The entropy is used for both remasking the DOM multipliers inside the Chi function of the Keccak core as well as for masking the message if {{<regref "CFG_SHADOWED.msg_mask" >}} is enabled.
+The entropy is used for both remasking the DOM multipliers inside the Chi function of the Keccak core as well as for masking the message if {{#regref kmac.CFG_SHADOWED.msg_mask }} is enabled.
![Entropy block](./doc/kmac-entropy.svg)
@@ -332,7 +332,7 @@
To break linear shift patterns, each LFSR features a non-linear layer.
In addition an 800-bit wide permutation spanning across all LFSRs is used.
-Depending on {{<regref "CFG_SHADOWED.entropy_mode" >}}, the entropy generator fetches initial entropy from the [Entropy Distribution Network (EDN)][edn] module or software has to provide a seed by writing the {{<regref "ENTROPY_SEED_0" >}} - {{<regref "ENTROPY_SEED_4" >}} registers in ascending order.
+Depending on {{#regref kmac.CFG_SHADOWED.entropy_mode }}, the entropy generator fetches initial entropy from the [Entropy Distribution Network (EDN)][edn] module or software has to provide a seed by writing the {{#regref kmac.ENTROPY_SEED_0 }} - {{#regref kmac.ENTROPY_SEED_4 }} registers in ascending order.
The module periodically refreshes the LFSR seeds with the new entropy from EDN.
To limit the entropy consumption for reseeding, a cascaded reseeding mechanism is used.
@@ -340,7 +340,7 @@
These five 32-bit words are directly fed into LFSRs 0/5/10/15/20 for reseeding.
At the same time, the previous states of LFSRs 0/5/10/15/20 from before the reseeding operation are permuted and then forwarded to reseed LFSRs 1/6/11/16/21.
Similarly, the previous states of LFSRs 1/6/11/16/21 from before the reseeding operation are permuted and then forwarded to reseed LFSRs 2/7/12/17/22.
-Software can still request a complete reseed of all 25 LFSRs from EDN by subsequently triggering five reseeding operations through {{<regref "CMD.entropy_req" >}}.
+Software can still request a complete reseed of all 25 LFSRs from EDN by subsequently triggering five reseeding operations through {{#regref kmac.CMD.entropy_req }}.
[edn]: ../edn/README.md
@@ -349,8 +349,8 @@
This section explains the errors KMAC HWIP raises during the hashing operations, their meanings, and the error handling process.
KMAC HWIP has the error checkers in its internal datapath.
-If the checkers detect errors, whether they are triggered by the SW mis-configure, or HW malfunctions, they report the error to {{< regref "ERR_CODE" >}} and raise an `kmac_error` interrupt.
-Each error code gives debugging information at the lower 24 bits of {{< regref "ERR_CODE" >}}.
+If the checkers detect errors, whether they are triggered by the SW mis-configure, or HW malfunctions, they report the error to {{#regref kmac.ERR_CODE }} and raise an `kmac_error` interrupt.
+Each error code gives debugging information at the lower 24 bits of {{#regref kmac.ERR_CODE }}.
Value | Error Code | Description
------|------------|-------------
@@ -392,7 +392,7 @@
The received command does not affect the Application process.
The request is dropped by the KMAC_APP module.
-The lower 3 bits of {{< regref "ERR_CODE" >}} contains the received command from the SW.
+The lower 3 bits of {{#regref kmac.ERR_CODE }} contains the received command from the SW.
#### WaitTimerExpired (0x04)
The SW may set the EDN wait timer to exit from EDN request state if the response from EDN takes long.
@@ -404,18 +404,18 @@
If the module does not complete, or flush the pending operation, it creates the back pressure to the message FIFO.
Then, the SW may not be able to access the KMAC IP at all, as the crossbar is stuck.
-The SW may move the state machine to the reset state by issuing {{<regref "CFG.err_processed" >}}.
+The SW may move the state machine to the reset state by issuing {{#regref kmac.CFG.err_processed }}.
#### IncorrectEntropyMode (0x05)
If SW misconfigures the entropy mode and let the entropy module prepare the random data, the module reports `IncorrectEntropyMode` error.
The state machine moves to Wait state after reporting the error.
-The SW may move the state machine to the reset state by issuing {{<regref "CFG.err_processed" >}}.
+The SW may move the state machine to the reset state by issuing {{#regref kmac.CFG.err_processed }}.
#### UnexpectedModeStrength (0x06)
-When the SW issues `Start` command, the KMAC_ERRCHK module checks the {{< regref "CFG.mode" >}} and {{< regref "CFG.kstrength" >}}.
+When the SW issues `Start` command, the KMAC_ERRCHK module checks the {{#regref kmac.CFG.mode }} and {{#regref kmac.CFG.kstrength }}.
The KMAC HWIP assumes the combinations of two to be **SHA3-224**, **SHA3-256**, **SHA3-384**, **SHA3-512**, **SHAKE-128**, **SHAKE-256**, **cSHAKE-128**, and **cSHAKE-256**.
If the combination of the `mode` and `kstrength` does not fall into above, the module reports the `UnexpectedModeStrength` error.
@@ -424,7 +424,7 @@
#### IncorrectFunctionName (0x07)
-If {{< regref "CFG.kmac_en" >}} is set and the SW issues the `Start` command, the KMAC_ERRCHK checks if the {{< regref "PREFIX" >}} has correct function name, `encode_string("KMAC")`.
+If {{#regref kmac.CFG.kmac_en }} is set and the SW issues the `Start` command, the KMAC_ERRCHK checks if the {{#regref kmac.PREFIX }} has correct function name, `encode_string("KMAC")`.
If the value does not match to the byte form of `encode_string("KMAC")` (`0x4341_4D4B_2001`), it reports the `IncorrectFunctionName` error.
As same as `UnexpectedModeStrength` error, this error does not block the hashing operation.
@@ -434,7 +434,7 @@
The KMAC_ERRCHK module checks the SW issued commands if it follows the guideline.
If the SW issues the command that is not relevant to the current context, the module reports the `SwCmdSequence` error.
-The lower 3bits of the {{< regref "ERR_CODE" >}} contains the received command.
+The lower 3bits of the {{#regref kmac.ERR_CODE }} contains the received command.
This error, however, does not stop the KMAC HWIP.
The incorrect command is dropped at the following datapath, SHA3 core.
@@ -444,44 +444,44 @@
## Initialization
The software can update the KMAC/SHA3 configurations only when the IP is in the idle state.
-The software should check {{< regref "STATUS.sha3_idle" >}} before updating the configurations.
-The software must first program {{< regref "CFG.msg_endianness" >}} and {{< regref "CFG.state_endianness" >}} at the initialization stage.
+The software should check {{#regref kmac.STATUS.sha3_idle }} before updating the configurations.
+The software must first program {{#regref kmac.CFG.msg_endianness }} and {{#regref kmac.CFG.state_endianness }} at the initialization stage.
These determine the byte order of incoming messages (msg_endianness) and the Keccak state output (state_endianness).
## Software Initiated KMAC/SHA3 process
This section describes the expected software process to run the KMAC/SHA3 HWIP.
-At first, the software configures {{< regref "CFG.kmac_en" >}} for KMAC operation.
-If KMAC is enabled, the software should configure {{< regref "CFG.mode" >}} to cSHAKE and {{< regref "CFG.kstrength" >}} to 128 or 256 bit security strength.
-The software also updates {{< regref "PREFIX" >}} registers if cSHAKE mode is used.
-Current design does not convert cSHAKE mode to SHAKE even if {{< regref "PREFIX" >}} is empty string.
-It is the software's responsibility to change the {{< regref "CFG.mode" >}} to SHAKE in case of empty {{< regref "PREFIX" >}}.
-The KMAC/SHA3 HWIP uses {{< regref "PREFIX" >}} registers as it is.
-It means that the software should update {{< regref "PREFIX" >}} with encoded values.
+At first, the software configures {{#regref kmac.CFG.kmac_en }} for KMAC operation.
+If KMAC is enabled, the software should configure {{#regref kmac.CFG.mode }} to cSHAKE and {{#regref kmac.CFG.kstrength }} to 128 or 256 bit security strength.
+The software also updates {{#regref kmac.PREFIX }} registers if cSHAKE mode is used.
+Current design does not convert cSHAKE mode to SHAKE even if {{#regref kmac.PREFIX }} is empty string.
+It is the software's responsibility to change the {{#regref kmac.CFG.mode }} to SHAKE in case of empty {{#regref kmac.PREFIX }}.
+The KMAC/SHA3 HWIP uses {{#regref kmac.PREFIX }} registers as it is.
+It means that the software should update {{#regref kmac.PREFIX }} with encoded values.
-If {{< regref "CFG.kmac_en" >}} is set, the software should update the secret key.
-The software prepares two shares of the secret key and selects its length in {{< regref "KEY_LEN" >}} then writes the shares of the secret key to {{< regref "KEY_SHARE0" >}} and {{< regref "KEY_SHARE1" >}} .
+If {{#regref kmac.CFG.kmac_en }} is set, the software should update the secret key.
+The software prepares two shares of the secret key and selects its length in {{#regref kmac.KEY_LEN }} then writes the shares of the secret key to {{#regref kmac.KEY_SHARE0 }} and {{#regref kmac.KEY_SHARE1 }} .
The two shares of the secret key are the values that represent the secret key value when they are XORed together.
The software can XOR the unmasked secret key with entropy.
The XORed value is a share and the entropy used is the other share.
-After configuring, the software notifies the KMAC/SHA3 engine to accept incoming messages by issuing Start command into {{< regref "CMD" >}} .
+After configuring, the software notifies the KMAC/SHA3 engine to accept incoming messages by issuing Start command into {{#regref kmac.CMD }} .
If Start command is not issued, the incoming message is discarded.
If KMAC is enabled, the software pushes the `right_encode(output_length)` value at the end of the message.
For example, if the desired output length is 256 bit, the software writes `0x00020100` to MSG_FIFO.
-After the software pushes all messages, it issues Process command to {{< regref "CMD" >}} for SHA3 engine to complete the sponge absorbing process.
+After the software pushes all messages, it issues Process command to {{#regref kmac.CMD }} for SHA3 engine to complete the sponge absorbing process.
SHA3 hashing engine pads the incoming message as defined in the SHA3 specification.
After the SHA3 engine completes the sponge absorbing step, it generates `kmac_done` interrupt.
-Or the software can poll the {{< regref "STATUS.squeeze" >}} bit until it becomes 1.
+Or the software can poll the {{#regref kmac.STATUS.squeeze }} bit until it becomes 1.
In this stage, the software may run the Keccak round manually.
If the desired digest length is greater than the Keccak rate, the software issues Run command for the Keccak round logic to run one full round after the software reads the current available Keccak state.
At this stage, KMAC/SHA3 does not raise an interrupt when the Keccak round completes the software initiated manual run.
-The software should check {{< regref "STATUS.squeeze" >}} register field for the readiness of {{< regref "STATE" >}} value.
+The software should check {{#regref kmac.STATUS.squeeze }} register field for the readiness of {{#regref kmac.STATE }} value.
-After the software reads all the digest values, it issues Done command to {{< regref "CMD" >}} register to clear the internal states.
+After the software reads all the digest values, it issues Done command to {{#regref kmac.CMD }} register to clear the internal states.
Done command clears the Keccak state, FSM in SHA3 and KMAC, and a few internal variables.
Secret key and other software programmed values won't be reset.
@@ -492,7 +492,7 @@
Internal SHA3 hashing engine receives in 64-bit granularity.
The data written to SHA3 is assumed to be little endian.
-The software may write/read the data in big-endian order if {{< regref "CFG.msg_endianness" >}} or {{< regref "CFG.state_endianness" >}} is set.
+The software may write/read the data in big-endian order if {{#regref kmac.CFG.msg_endianness }} or {{#regref kmac.CFG.state_endianness }} is set.
If the endianness bit is 1, the data is assumed to be big-endian.
So, the internal logic byte-swap the data.
For example, when the software writes `0xDEADBEEF` with endianness as 1, the logic converts it to `0xEFBEADDE` then writes into MSG_FIFO.
@@ -500,7 +500,7 @@
The software managed secret key, and the prefix are always little-endian values.
For example, if the software configures the function name `N` in KMAC operation, it writes `encode_string("KMAC")`.
The `encode_string("KMAC")` represents `0x01 0x20 0x4b 0x4d 0x41 0x43` in byte order.
-The software writes `0x4d4b2001` into {{< regref "PREFIX0" >}} and `0x????4341` into {{< regref "PREFIX1" >}} .
+The software writes `0x4d4b2001` into {{#regref kmac.PREFIX0 }} and `0x????4341` into {{#regref kmac.PREFIX1 }} .
Upper 2 bytes can vary depending on the customization input string `S`.
## KMAC/SHA3 context switching
@@ -515,7 +515,7 @@
## Registers
-{{< incGenFromIpDesc "../data/kmac.hjson" "registers" >}}
+* [Register Table](data/kmac.hjson#registers)
[SHA3 specification, FIPS 202]: https://csrc.nist.gov/publications/detail/fips/202/final
[NIST SP 800-185]: https://csrc.nist.gov/publications/detail/sp/800-185/final
diff --git a/hw/ip/lc_ctrl/README.md b/hw/ip/lc_ctrl/README.md
index f9f8fb4..c90ad7f 100644
--- a/hw/ip/lc_ctrl/README.md
+++ b/hw/ip/lc_ctrl/README.md
@@ -220,9 +220,9 @@
#### CLK_BYP_REQ
-If the life cycle state is in RAW, TEST* or RMA, and if {{< regref TRANSITION_CTRL.EXT_CLOCK_EN >}} is set to one, the CLK_BYP_REQ signal is asserted in order to switch the main system clock to an external clock signal.
+If the life cycle state is in RAW, TEST* or RMA, and if {{#regref lc_ctrl.TRANSITION_CTRL.EXT_CLOCK_EN }} is set to one, the CLK_BYP_REQ signal is asserted in order to switch the main system clock to an external clock signal.
This functionality is needed in certain life cycle states where the internal clock source may not be fully calibrated yet, since the OTP macro requires a stable clock frequency in order to reliably program the fuse array.
-Note that the {{< regref TRANSITION_CTRL.EXT_CLOCK_EN >}} register can only be set to one if the transition interface has been claimed via the {{< regref "CLAIM_TRANSITION_IF" >}} mutex.
+Note that the {{#regref lc_ctrl.TRANSITION_CTRL.EXT_CLOCK_EN }} register can only be set to one if the transition interface has been claimed via the {{#regref lc_ctrl.CLAIM_TRANSITION_IF }} mutex.
This function is not available in production life cycle states.
For details on the clock switch, please see [clkmgr](../clkmgr/README.md#life-cycle-requested-external-clock).
@@ -367,7 +367,7 @@
### Signals
-{{< incGenFromIpDesc "../data/lc_ctrl.hjson" "hwcfg" >}}
+* [Interface Tables](data/lc_ctrl.hjson#interfaces)
Signal | Direction | Type | Description
-----------------------------|------------------|------------------------------------------|---------------
@@ -386,10 +386,10 @@
`otp_lc_data_i` | `input` | `otp_ctrl_pkg::otp_lc_data_t` | Life cycle state output holding the current life cycle state, the value of the transition counter and the tokens needed for life cycle transitions.
`lc_keymgr_div_o` | `output` | `lc_keymgr_div_t` | Life cycle state group diversification value.
`lc_flash_rma_seed_o` | `output` | `lc_flash_rma_seed_t` | Seed for flash RMA.
-`otp_device_id_i` | `input` | `otp_device_id_t` | HW_CFG bits from OTP ({{< regref DEVICE_ID_0 >}}).
-`otp_manuf_state_i` | `input` | `otp_manuf_state_t` | HW_CFG bits from OTP ({{< regref MANUF_STATE_0 >}}).
-`lc_otp_vendor_test_o` | `output` | `otp_ctrl_pkg::lc_otp_vendor_test_req_t` | Vendor-specific test bits to OTP ({{< regref OTP_VENDOR_TEST_CTRL >}}).
-`lc_otp_vendor_test_i` | `input` | `otp_ctrl_pkg::lc_otp_vendor_test_rsp_t` | Vendor-specific test bits to OTP ({{< regref OTP_VENDOR_TEST_STATUS >}}).
+`otp_device_id_i` | `input` | `otp_device_id_t` | HW_CFG bits from OTP ({{#regref lc_ctrl.DEVICE_ID_0 }}).
+`otp_manuf_state_i` | `input` | `otp_manuf_state_t` | HW_CFG bits from OTP ({{#regref lc_ctrl.MANUF_STATE_0 }}).
+`lc_otp_vendor_test_o` | `output` | `otp_ctrl_pkg::lc_otp_vendor_test_req_t` | Vendor-specific test bits to OTP ({{#regref lc_ctrl.OTP_VENDOR_TEST_CTRL }}).
+`lc_otp_vendor_test_i` | `input` | `otp_ctrl_pkg::lc_otp_vendor_test_rsp_t` | Vendor-specific test bits to OTP ({{#regref lc_ctrl.OTP_VENDOR_TEST_STATUS }}).
`lc_dft_en_o` | `output` | `lc_tx_t` | [Multibit control signal](#life-cycle-decoded-outputs-and-controls).
`lc_nvm_debug_en_o` | `output` | `lc_tx_t` | [Multibit control signal](#life-cycle-decoded-outputs-and-controls).
`lc_hw_debug_en_o` | `output` | `lc_tx_t` | [Multibit control signal](#life-cycle-decoded-outputs-and-controls).
@@ -523,7 +523,7 @@
Note that the RAW state is guarded by the RAW_UNLOCK process, which involves supplying a 128bit UNLOCK_TOKEN and performing a full system reset in case the token was correct. Hence moving the state into RAW does not provide any advantage to an attacker.
The encoded life cycle state is not readable by SW in any way through the OTP or life cycle interfaces.
-However a decoded version of the manufacturing life cycle is exposed in the {{< regref "LC_STATE" >}} register.
+However a decoded version of the manufacturing life cycle is exposed in the {{#regref lc_ctrl.LC_STATE }} register.
### Life Cycle Readout Consistency Checks in OTP
@@ -541,7 +541,7 @@
Upon each life cycle transition attempt, the life cycle controller **FIRST** increments the transition counter before initiating any token hashing and comparison operations.
-A decoded version of this counter is exposed in the {{< regref "LC_TRANSITION_CNT" >}} register.
+A decoded version of this counter is exposed in the {{#regref lc_ctrl.LC_TRANSITION_CNT }} register.
### Life Cycle State Controller
@@ -590,13 +590,13 @@
The request interface consists of 7 registers:
-1. {{< regref "TRANSITION_CTRL" >}}: Control register for the transition, can be used to switch to an external clock.
-2. {{< regref "TRANSITION_TARGET" >}}: Specifies the target state to which the agent wants to transition.
-3. {{< regref "TRANSITION_TOKEN_*" >}}: Any necessary token for conditional transitions.
-4. {{< regref "TRANSITION_CMD" >}}: Start the life cycle transition.
-5. {{< regref "STATUS" >}}: Indicates whether the requested transition succeeded.
-6. {{< regref OTP_VENDOR_TEST_CTRL >}}: See [Macro-specific test control bits](#vendor-specific-test-control-register).
-7. {{< regref OTP_VENDOR_TEST_STATUS >}}: See [Macro-specific test control bits](#vendor-specific-test-control-register).
+1. {{#regref lc_ctrl.TRANSITION_CTRL }}: Control register for the transition, can be used to switch to an external clock.
+2. {{#regref lc_ctrl.TRANSITION_TARGET }}: Specifies the target state to which the agent wants to transition.
+3. {{#regref lc_ctrl.TRANSITION_TOKEN_* }}: Any necessary token for conditional transitions.
+4. {{#regref lc_ctrl.TRANSITION_CMD }}: Start the life cycle transition.
+5. {{#regref lc_ctrl.STATUS }}: Indicates whether the requested transition succeeded.
+6. {{#regref lc_ctrl.OTP_VENDOR_TEST_CTRL }}: See [Macro-specific test control bits](#vendor-specific-test-control-register).
+7. {{#regref lc_ctrl.OTP_VENDOR_TEST_STATUS }}: See [Macro-specific test control bits](#vendor-specific-test-control-register).
If the transition fails, the cause will be reported in this register as well.
@@ -604,10 +604,10 @@
![LC Request Interface](./doc/lc_ctrl_request_interface.svg)
-In order to claim the hardware mutex, the value kMuBi8True must be written to the claim register ({{< regref "CLAIM_TRANSITION_IF" >}}).
+In order to claim the hardware mutex, the value kMuBi8True must be written to the claim register ({{#regref lc_ctrl.CLAIM_TRANSITION_IF }}).
If the register reads back as kMuBi8True, then the mutex is claimed, and the interface that won arbitration can continue operations.
If the value is not read back, then the requesting interface should wait and try again later.
-Note that all transition registers (with the exception of the {{< regref "STATUS" >}} register) read back all-zero if the mutex is not claimed.
+Note that all transition registers (with the exception of the {{#regref lc_ctrl.STATUS }} register) read back all-zero if the mutex is not claimed.
When an agent is done with the mutex, it releases the mutex by explicitly writing a 0 to the claim register.
This resets the mux to select no one and also holds the request interface in reset.
@@ -616,7 +616,7 @@
Certain OTP macros require special configuration bits to be set during the test phases.
Likewise, it is necessary to expose macro-specific status bits during the test phases.
-To this end, the life cycle CSRs contain the {{< regref OTP_VENDOR_TEST_CTRL >}} and {{< regref OTP_VENDOR_TEST_STATUS >}} registers, which are reserved for vendor-specific test control and status bits.
+To this end, the life cycle CSRs contain the {{#regref lc_ctrl.OTP_VENDOR_TEST_CTRL }} and {{#regref lc_ctrl.OTP_VENDOR_TEST_STATUS }} registers, which are reserved for vendor-specific test control and status bits.
These registers are only active during RAW, TEST_* and RMA life cycle states.
In all other life cycle states, the status register reads back all-zero, and the control register value will be tied to 0 before forwarding it to the OTP macro.
@@ -647,28 +647,28 @@
# Programmer's Guide
-The register layout and offsets shown in the [register table]#register-table below are identical for both the CSR and JTAG TAP interfaces.
+The register layout and offsets shown in the [register table](data/lc_ctrl.hjson#registers) below are identical for both the CSR and JTAG TAP interfaces.
Hence the following programming sequence applies to both SW running on the device and SW running on the test appliance that accesses life cycle through the TAP.
-1. In order to perform a life cycle transition, SW should first check whether the life cycle controller has successfully initialized and is ready to accept a transition command by making sure that the {{< regref "STATUS.READY" >}} bit is set to 1, and that all other status and error bits in {{< regref "STATUS" >}} are set to 0.
+1. In order to perform a life cycle transition, SW should first check whether the life cycle controller has successfully initialized and is ready to accept a transition command by making sure that the {{#regref lc_ctrl.STATUS.READY }} bit is set to 1, and that all other status and error bits in {{#regref lc_ctrl.STATUS }} are set to 0.
-2. Read the {{< regref "LC_STATE" >}} and {{< regref "LC_TRANSITION_CNT" >}} registers to determine which life cycle state the device currently is in, and how many transition attempts are still available.
+2. Read the {{#regref lc_ctrl.LC_STATE }} and {{#regref lc_ctrl.LC_TRANSITION_CNT }} registers to determine which life cycle state the device currently is in, and how many transition attempts are still available.
-3. Claim exclusive access to the transition interface by writing kMuBi8True to the {{< regref "CLAIM_TRANSITION_IF" >}} register, and reading it back. If the value read back equals to kMuBi8True, the hardware mutex has successfully been claimed and SW can proceed to step 4. If the value read back equals to 0, the mutex has already been claimed by the other interface (either CSR or TAP), and SW should try claiming the mutex again.
-Note that all transition interface registers are protected by the hardware-governed {{< regref "TRANSITION_REGWEN" >}} register, which will only be set to 1 if the mutex has been claimed successfully.
+3. Claim exclusive access to the transition interface by writing kMuBi8True to the {{#regref lc_ctrl.CLAIM_TRANSITION_IF }} register, and reading it back. If the value read back equals to kMuBi8True, the hardware mutex has successfully been claimed and SW can proceed to step 4. If the value read back equals to 0, the mutex has already been claimed by the other interface (either CSR or TAP), and SW should try claiming the mutex again.
+Note that all transition interface registers are protected by the hardware-governed {{#regref lc_ctrl.TRANSITION_REGWEN }} register, which will only be set to 1 if the mutex has been claimed successfully.
-4. If required, enable the external clock and other vendor-specific OTP settings in the {{< regref "OTP_VENDOR_TEST_CTRL" >}} register.
+4. If required, enable the external clock and other vendor-specific OTP settings in the {{#regref lc_ctrl.OTP_VENDOR_TEST_CTRL }} register.
Note that these settings only take effect in RAW, TEST* and RMA life cycle states.
They are ignored in the PROD* and DEV states.
-5. Write the desired target state to {{< regref "TRANSITION_TARGET" >}}. For conditional transitions, the corresponding token has to be written to {{< regref "TRANSITION_TOKEN_0" >}}. For all unconditional transitions, the token registers have to be set to zero.
+5. Write the desired target state to {{#regref lc_ctrl.TRANSITION_TARGET }}. For conditional transitions, the corresponding token has to be written to {{#regref lc_ctrl.TRANSITION_TOKEN_0 }}. For all unconditional transitions, the token registers have to be set to zero.
6. An optional, but recommended step is to read back and verify the values written in steps 4. and 5. before proceeding with step 7.
-7. Write 1 to the {{< regref "TRANSITION_CMD.START" >}} register to initiate the life cycle transition.
+7. Write 1 to the {{#regref lc_ctrl.TRANSITION_CMD.START }} register to initiate the life cycle transition.
-8. Poll the {{< regref "STATUS" >}} register and wait until either {{< regref "STATUS.TRANSITION_SUCCESSFUL" >}} or any of the error bits is asserted.
-The {{< regref "TRANSITION_REGWEN" >}} register will be set to 0 while a transition is in progress in order to prevent any accidental modifications of the transition interface registers during this phase.
+8. Poll the {{#regref lc_ctrl.STATUS }} register and wait until either {{#regref lc_ctrl.STATUS.TRANSITION_SUCCESSFUL }} or any of the error bits is asserted.
+The {{#regref lc_ctrl.TRANSITION_REGWEN }} register will be set to 0 while a transition is in progress in order to prevent any accidental modifications of the transition interface registers during this phase.
Note that any life cycle state transition - no matter whether successful or not - increments the LC_TRANSITION_CNT and moves the life cycle state into the temporary POST_TRANSITION state.
Hence, step 8. cannot be carried out in case device SW is used to implement the programming sequence above, since the processor is disabled in the POST_TRANSITION life cycle state.
@@ -682,4 +682,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/lc_ctrl.hjson" "registers" >}}
+* [Register Table](data/lc_ctrl.hjson#registers)
diff --git a/hw/ip/otbn/README.md b/hw/ip/otbn/README.md
index 5e923da..f68b8e2 100644
--- a/hw/ip/otbn/README.md
+++ b/hw/ip/otbn/README.md
@@ -101,7 +101,7 @@
they are not related to the GPRs.
CSRs can be accessed through dedicated instructions, {{< otbnInsnRef "CSRRS" >}} and {{< otbnInsnRef "CSRRW" >}}.
Writes to read-only (RO) registers are ignored; they do not signal an error.
-All read-write (RW) CSRs are set to 0 when OTBN starts an operation (when 1 is written to {{< regref "CMD.start" >}}).
+All read-write (RW) CSRs are set to 0 when OTBN starts an operation (when 1 is written to {{#regref otbn.CMD.start }}).
<!-- This list of CSRs is replicated in otbn_env_cov.sv, wsr.py, the
RTL and in rig/model.py. If editing one, edit the other four as well. -->
@@ -314,7 +314,7 @@
These are analogous to the 32b CSRs, but are used by big number instructions.
They can be accessed with the {{< otbnInsnRef "BN.WSRR" >}} and {{< otbnInsnRef "BN.WSRW" >}} instructions.
Writes to read-only (RO) registers are ignored; they do not signal an error.
-All read-write (RW) WSRs are set to 0 when OTBN starts an operation (when 1 is written to {{< regref "CMD.start" >}}).
+All read-write (RW) WSRs are set to 0 when OTBN starts an operation (when 1 is written to {{#regref otbn.CMD.start }}).
<!-- This list of WSRs is replicated in otbn_env_cov.sv, wsr.py, the
RTL and in rig/model.py. If editing one, edit the other four as well. -->
@@ -482,9 +482,9 @@
## Instruction Counter
-In order to detect and mitigate fault injection attacks on the OTBN, the host CPU can read the number of executed instructions from {{< regref "INSN_CNT">}} and verify whether it matches the expectation.
+In order to detect and mitigate fault injection attacks on the OTBN, the host CPU can read the number of executed instructions from {{#regref otbn.INSN_CNT }} and verify whether it matches the expectation.
The host CPU can clear the instruction counter when OTBN is not running.
-Writing any value to {{< regref "INSN_CNT">}} clears this register to zero.
+Writing any value to {{#regref otbn.INSN_CNT }} clears this register to zero.
Write attempts while OTBN is running are ignored.
## Key Sideloading
@@ -525,7 +525,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/otbn.hjson" "hwcfg" >}}
+* [Interface Tables](data/otbn.hjson#interfaces)
### Hardware Interface Requirements
@@ -563,12 +563,12 @@
In the big number instruction subset, there are {{< otbnInsnRef "BN.LID" >}} (load indirect) and {{< otbnInsnRef "BN.SID" >}} (store indirect).
These access 256b-aligned 256b words.
-Both memories can be accessed through OTBN's register interface ({{< regref "DMEM" >}} and {{< regref "IMEM" >}}).
+Both memories can be accessed through OTBN's register interface ({{#regref otbn.DMEM }} and {{#regref otbn.IMEM }}).
All memory accesses through the register interface must be word-aligned 32b word accesses.
When OTBN is in any state other than [idle](#design-details-operational-states), reads return zero and writes have no effect.
Furthermore, a memory access when OTBN is neither idle nor locked will cause OTBN to generate a fatal error with code `ILLEGAL_BUS_ACCESS`.
-A host processor can check whether OTBN is busy by reading the {{< regref "STATUS">}} register.
+A host processor can check whether OTBN is busy by reading the {{#regref otbn.STATUS }} register.
The underlying memories used to implement the IMEM and DMEM may not grant all access requests (see [Memory Scrambling](#design-details-memory-scrambling) for details).
A request won't be granted if new scrambling keys have been requested for the memory that aren't yet available.
@@ -638,24 +638,24 @@
OTBN is *busy* for as long it is performing an operation.
OTBN is *locked* if a fatal error was observed or after handling an RMA request.
-The current operational state is reflected in the {{< regref "STATUS" >}} register.
-- After reset, OTBN is busy with the internal secure wipe and the {{< regref "STATUS" >}} register is set to `BUSY_SEC_WIPE_INT`.
-- If OTBN is idle, the {{< regref "STATUS" >}} register is set to `IDLE`.
-- If OTBN is busy, the {{< regref "STATUS" >}} register is set to one of the values starting with `BUSY_`.
-- If OTBN is locked, the {{< regref "STATUS" >}} register is set to `LOCKED`.
+The current operational state is reflected in the {{#regref otbn.STATUS }} register.
+- After reset, OTBN is busy with the internal secure wipe and the {{#regref otbn.STATUS }} register is set to `BUSY_SEC_WIPE_INT`.
+- If OTBN is idle, the {{#regref otbn.STATUS }} register is set to `IDLE`.
+- If OTBN is busy, the {{#regref otbn.STATUS }} register is set to one of the values starting with `BUSY_`.
+- If OTBN is locked, the {{#regref otbn.STATUS }} register is set to `LOCKED`.
OTBN transitions into the busy state as result of host software [issuing a command](#design-details-commands); OTBN is then said to perform an operation.
OTBN transitions out of the busy state whenever the operation has completed.
-In the {{< regref "STATUS" >}} register the different `BUSY_*` values represent the operation that is currently being performed.
+In the {{#regref otbn.STATUS }} register the different `BUSY_*` values represent the operation that is currently being performed.
-A transition out of the busy state is signaled by the `done` interrupt ({{< regref "INTR_STATE.done" >}}).
+A transition out of the busy state is signaled by the `done` interrupt ({{#regref otbn.INTR_STATE.done }}).
The locked state is a terminal state; transitioning out of it requires an OTBN reset.
### Operations and Commands {#design-details-commands}
OTBN understands a set of commands to perform certain operations.
-Commands are issued by writing to the {{< regref "CMD" >}} register.
+Commands are issued by writing to the {{#regref otbn.CMD }} register.
The `EXECUTE` command starts the [execution of the application](#design-details-software-execution) contained in OTBN's instruction memory.
@@ -668,14 +668,14 @@
Software execution on OTBN is triggered by host software by [issuing the `EXECUTE` command](#design-details-commands).
The software then runs to completion, without the ability for host software to interrupt or inspect the execution.
-- OTBN transitions into the busy state, and reflects this by setting {{< regref "STATUS">}} to `BUSY_EXECUTE`.
+- OTBN transitions into the busy state, and reflects this by setting {{#regref otbn.STATUS }} to `BUSY_EXECUTE`.
- The internal randomness source, which provides random numbers to the `URND` CSR and WSR, is re-seeded from the EDN.
- The instruction at address zero is fetched and executed.
- From this point on, all subsequent instructions are executed according to their semantics until either an {{< otbnInsnRef "ECALL" >}} instruction is executed, or an error is detected.
- A [secure wipe of internal state](#design-details-secure-wipe-internal) is performed.
-- The {{< regref "ERR_BITS" >}} register is set to indicate either a successful execution (value `0`), or to indicate the error that was observed (a non-zero value).
+- The {{#regref otbn.ERR_BITS }} register is set to indicate either a successful execution (value `0`), or to indicate the error that was observed (a non-zero value).
- OTBN transitions into the [idle state](#design-details-operational-states) (in case of a successful execution, or a recoverable error) or the locked state (in case of a fatal error).
- This transition is signaled by raising the `done` interrupt ({{< regref "INTR_STATE.done" >}}), and reflected in the {{< regref "STATUS" >}} register.
+ This transition is signaled by raising the `done` interrupt ({{#regref otbn.INTR_STATE.done }}), and reflected in the {{#regref otbn.STATUS }} register.
### Errors {#design-details-errors}
@@ -689,8 +689,8 @@
OTBN generally does not try to recover from errors itself, and provides no error handling support to code that runs on it.
OTBN gives host software the option to recover from some errors by restarting the operation.
-All software errors are treated as recoverable, unless {{< regref "CTRL.software_errs_fatal" >}} is set, and are handled as described in the section [Reaction to Recoverable Errors](#design-details-recoverable-errors).
-When {{< regref "CTRL.software_errs_fatal" >}} is set, software errors become fatal errors.
+All software errors are treated as recoverable, unless {{#regref otbn.CTRL.software_errs_fatal }} is set, and are handled as described in the section [Reaction to Recoverable Errors](#design-details-recoverable-errors).
+When {{#regref otbn.CTRL.software_errs_fatal }} is set, software errors become fatal errors.
Fatal errors are treated as described in the section [Reaction to Fatal Errors](#design-details-fatal-errors).
@@ -704,9 +704,9 @@
1. The currently running operation is terminated, similar to the way an {{< otbnInsnRef "ECALL" >}} instruction [is executed](#writing-otbn-applications-ecall):
- No more instructions are fetched or executed.
- A [secure wipe of internal state](#design-details-secure-wipe-internal) is performed.
- - The {{< regref "ERR_BITS" >}} register is set to a non-zero value that describes the error.
- - The current operation is marked as complete by setting {{< regref "INTR_STATE.done" >}}.
- - The {{< regref "STATUS" >}} register is set to `IDLE`.
+ - The {{#regref otbn.ERR_BITS }} register is set to a non-zero value that describes the error.
+ - The current operation is marked as complete by setting {{#regref otbn.INTR_STATE.done }}.
+ - The {{#regref otbn.STATUS }} register is set to `IDLE`.
2. A [recoverable alert](#alerts) is raised.
The host software can start another operation on OTBN after a recoverable error was detected.
@@ -722,17 +722,17 @@
2. If OTBN [is not idle](#design-details-operational-states), then the currently running operation is terminated, similarly to how an operation ends after an {{< otbnInsnRef "ECALL" >}} instruction [is executed](#writing-otbn-applications-ecall):
- No more instructions are fetched or executed.
- A [secure wipe of internal state](#design-details-secure-wipe-internal) is performed.
- - The {{< regref "ERR_BITS" >}} register is set to a non-zero value that describes the error.
- - The current operation is marked as complete by setting {{< regref "INTR_STATE.done" >}}.
-3. The {{< regref "STATUS" >}} register is set to `LOCKED`.
+ - The {{#regref otbn.ERR_BITS }} register is set to a non-zero value that describes the error.
+ - The current operation is marked as complete by setting {{#regref otbn.INTR_STATE.done }}.
+3. The {{#regref otbn.STATUS }} register is set to `LOCKED`.
4. A [fatal alert](#alerts) is raised.
Note that OTBN can detect some errors even when it isn't running.
One example of this is an error caused by an integrity error when reading or writing OTBN's memories over the bus.
-In this case, the {{< regref "ERR_BITS" >}} register will not change.
+In this case, the {{#regref otbn.ERR_BITS }} register will not change.
This avoids race conditions with the host processor's error handling software.
However, every error that OTBN detects when it isn't running is fatal.
-This means that the cause will be reflected in {{< regref "FATAL_ALERT_CAUSE" >}}, as described below in [Alerts](#alerts).
+This means that the cause will be reflected in {{#regref otbn.FATAL_ALERT_CAUSE }}, as described below in [Alerts](#alerts).
This way, no alert is generated without setting an error code somewhere.
### List of Errors {#design-details-list-of-errors}
@@ -834,7 +834,7 @@
<tr>
<td><code>FATAL_SOFTWARE</code></td>
<td>fatal</td>
- <td>A software error was seen and {{< regref "CTRL.software_errs_fatal" >}} was set.</td>
+ <td>A software error was seen and {{#regref otbn.CTRL.software_errs_fatal }} was set.</td>
</tr>
</tbody>
</table>
@@ -845,15 +845,15 @@
OTBN has two alerts, one recoverable and one fatal.
A **recoverable alert** is a one-time triggered alert caused by [recoverable errors](#design-details-recoverable-errors).
-The error that caused the alert can be determined by reading the {{< regref "ERR_BITS" >}} register.
+The error that caused the alert can be determined by reading the {{#regref otbn.ERR_BITS }} register.
A **fatal alert** is a continuously triggered alert caused by [fatal errors](#design-details-fatal-errors).
-The error that caused the alert can be determined by reading the {{< regref "FATAL_ALERT_CAUSE" >}} register.
-If OTBN was running, this value will also be reflected in the {{< regref "ERR_BITS" >}} register.
+The error that caused the alert can be determined by reading the {{#regref otbn.FATAL_ALERT_CAUSE }} register.
+If OTBN was running, this value will also be reflected in the {{#regref otbn.ERR_BITS }} register.
A fatal alert can only be cleared by resetting OTBN through the `rst_ni` line.
-The host CPU can clear the {{< regref "ERR_BITS" >}} when OTBN is not running.
-Writing any value to {{< regref "ERR_BITS" >}} clears this register to zero.
+The host CPU can clear the {{#regref otbn.ERR_BITS }} when OTBN is not running.
+Writing any value to {{#regref otbn.ERR_BITS }} clears this register to zero.
Write attempts while OTBN is running are ignored.
### Reaction to Life Cycle Escalation Requests {#design-details-lifecycle-escalation}
@@ -978,7 +978,7 @@
### Memory Load Integrity {#mem-load-integrity}
As well as the integrity protection discussed above for the memories and bus interface, OTBN has a second layer of integrity checking to allow a host processor to ensure that a program has been loaded correctly.
-This is visible through the {{< regref "LOAD_CHECKSUM" >}} register.
+This is visible through the {{#regref otbn.LOAD_CHECKSUM }} register.
The register exposes a cumulative CRC checksum which is updated on every write to either memory.
This is intended as a light-weight way to implement a more efficient "write and read back" check.
@@ -987,7 +987,7 @@
The CRC used is the 32-bit CRC-32-IEEE checksum.
This standard choice of generating polynomial makes it compatible with other tooling and libraries, such as the [crc32 function](https://docs.python.org/3/library/binascii.html#binascii.crc32) in the python 'binascii' module and the crc instructions in the RISC-V bitmanip specification [[SYMBIOTIC21]](#ref-symbiotic21).
-The stream over which the checksum is computed is the stream of writes that have been seen since the last write to {{< regref "LOAD_CHECKSUM" >}}.
+The stream over which the checksum is computed is the stream of writes that have been seen since the last write to {{#regref otbn.LOAD_CHECKSUM }}.
Each write is treated as a 48b value, `{imem, idx, wdata}`.
Here, `imem` is a single bit flag which is one for writes to IMEM and zero for writes to DMEM.
The `idx` value is the index of the word within the memory, zero extended from 10b to 15b.
@@ -999,9 +999,9 @@
Note the internal representation of the CRC is inverted from the register visible version.
This is done to maintain compatibility with existing CRC-32-IEEE tooling and libraries.
-To use this functionality, the host processor should set {{< regref "LOAD_CHECKSUM" >}} to a known value (traditionally, `32'h00000000`).
+To use this functionality, the host processor should set {{#regref otbn.LOAD_CHECKSUM }} to a known value (traditionally, `32'h00000000`).
Next, it should write the program to be loaded to OTBN's IMEM and DMEM over the bus.
-Finally, it should read back the value of {{< regref "LOAD_CHECKSUM" >}} and compare it with an expected value.
+Finally, it should read back the value of {{#regref otbn.LOAD_CHECKSUM }} and compare it with an expected value.
### Secure Wipe {#design-details-secure-wipe}
@@ -1081,24 +1081,24 @@
The high-level sequence by which the host processor should use OTBN is as follows.
-1. Optional: Initialise {{< regref "LOAD_CHECKSUM" >}}.
-1. Write the OTBN application binary to {{< regref "IMEM" >}}, starting at address 0.
-1. Optional: Write constants and input arguments, as mandated by the calling convention of the loaded application, to the half of DMEM accessible through the {{< regref "DMEM" >}} window.
-1. Optional: Read back {{< regref "LOAD_CHECKSUM" >}} and perform an integrity check.
+1. Optional: Initialise {{#regref otbn.LOAD_CHECKSUM }}.
+1. Write the OTBN application binary to {{#regref otbn.IMEM }}, starting at address 0.
+1. Optional: Write constants and input arguments, as mandated by the calling convention of the loaded application, to the half of DMEM accessible through the {{#regref otbn.DMEM }} window.
+1. Optional: Read back {{#regref otbn.LOAD_CHECKSUM }} and perform an integrity check.
1. Start the operation on OTBN by [issuing the `EXECUTE` command](#design-details-commands).
Now neither data nor instruction memory may be accessed from the host CPU.
After it has been started the OTBN application runs to completion without further interaction with the host.
1. Wait for the operation to complete (see below).
As soon as the OTBN operation has completed the data and instruction memories can be accessed again from the host CPU.
-1. Check if the operation was successful by reading the {{< regref "ERR_BITS" >}} register.
-1. Optional: Retrieve results by reading {{< regref "DMEM" >}}, as mandated by the calling convention of the loaded application.
+1. Check if the operation was successful by reading the {{#regref otbn.ERR_BITS }} register.
+1. Optional: Retrieve results by reading {{#regref otbn.DMEM }}, as mandated by the calling convention of the loaded application.
OTBN applications are run to completion.
-The host CPU can determine if an application has completed by either polling {{< regref "STATUS">}} or listening for an interrupt.
+The host CPU can determine if an application has completed by either polling {{#regref otbn.STATUS }} or listening for an interrupt.
-* To poll for a completed operation, software should repeatedly read the {{< regref "STATUS" >}} register.
- The operation is complete if {{< regref "STATUS" >}} is `IDLE` or `LOCKED`, otherwise the operation is in progress.
- When {{< regref "STATUS" >}} has become `LOCKED` a fatal error has occurred and OTBN must be reset to perform further operations.
+* To poll for a completed operation, software should repeatedly read the {{#regref otbn.STATUS }} register.
+ The operation is complete if {{#regref otbn.STATUS }} is `IDLE` or `LOCKED`, otherwise the operation is in progress.
+ When {{#regref otbn.STATUS }} has become `LOCKED` a fatal error has occurred and OTBN must be reset to perform further operations.
* Alternatively, software can listen for the `done` interrupt to determine if the operation has completed.
The standard sequence of working with interrupts has to be followed, i.e. the interrupt has to be enabled, an interrupt service routine has to be registered, etc.
The [DIF](#dif) contains helpers to do so conveniently.
@@ -1118,7 +1118,7 @@
## Register Table
-{{< incGenFromIpDesc "../data/otbn.hjson" "registers" >}}
+* [Register Table](data/otbn.hjson#registers)
# Writing OTBN applications {#writing-otbn-applications}
@@ -1153,8 +1153,8 @@
- No more instructions are fetched or executed.
- A [secure wipe of internal state](#design-details-secure-wipe-internal) is performed.
-- The {{< regref "ERR_BITS" >}} register is set to 0, indicating a successful operation.
-- The current operation is marked as complete by setting {{< regref "INTR_STATE.done" >}} and clearing {{< regref "STATUS" >}}.
+- The {{#regref otbn.ERR_BITS }} register is set to 0, indicating a successful operation.
+- The current operation is marked as complete by setting {{#regref otbn.INTR_STATE.done }} and clearing {{#regref otbn.STATUS }}.
The first 2kiB of DMEM can be used to pass data back to the host processor, e.g. a "return value" or an "exit code".
Refer to the section [Passing of data between the host CPU and OTBN](#writing-otbn-applications-datapassing) for more information.
diff --git a/hw/ip/otp_ctrl/README.md b/hw/ip/otp_ctrl/README.md
index ed40884..87898b0 100644
--- a/hw/ip/otp_ctrl/README.md
+++ b/hw/ip/otp_ctrl/README.md
@@ -310,7 +310,7 @@
### Signals
-{{< incGenFromIpDesc "../data/otp_ctrl.hjson" "hwcfg" >}}
+* [Interface Tables](data/otp_ctrl.hjson#interfaces)
The OTP controller contains various interfaces that connect to other comportable IPs within OpenTitan, and these are briefly explained further below.
@@ -778,16 +778,16 @@
The OTP controller initializes automatically upon power-up and is fully operational by the time the processor boots.
The only initialization steps that SW should perform are:
-1. Check that the OTP controller has successfully initialized by reading {{< regref STATUS >}}. I.e., make sure that none of the ERROR bits are set, and that the DAI is idle ({{< regref STATUS.DAI_IDLE >}}).
+1. Check that the OTP controller has successfully initialized by reading {{#regref otp_ctrl.STATUS }}. I.e., make sure that none of the ERROR bits are set, and that the DAI is idle ({{#regref otp_ctrl.STATUS.DAI_IDLE }}).
2. Set up the periodic background checks:
- - Choose whether to enable periodic [background checks](#partition-checks) by programming nonzero mask values to {{< regref INTEGRITY_CHECK_PERIOD >}} and {{< regref CONSISTENCY_CHECK_PERIOD >}}.
- - Choose whether such checks shall be subject to a timeout by programming a nonzero timeout cycle count to {{< regref CHECK_TIMEOUT >}}.
- - It is recommended to lock down the background check registers via {{< regref CHECK_REGWEN >}}, once the background checks have been set up.
+ - Choose whether to enable periodic [background checks](#partition-checks) by programming nonzero mask values to {{#regref otp_ctrl.INTEGRITY_CHECK_PERIOD }} and {{#regref otp_ctrl.CONSISTENCY_CHECK_PERIOD }}.
+ - Choose whether such checks shall be subject to a timeout by programming a nonzero timeout cycle count to {{#regref otp_ctrl.CHECK_TIMEOUT }}.
+ - It is recommended to lock down the background check registers via {{#regref otp_ctrl.CHECK_REGWEN }}, once the background checks have been set up.
-If needed, one-off integrity and consistency checks can be triggered via {{< regref CHECK_TRIGGER >}}.
-If this functionality is not needed, it is recommended to lock down the trigger register via {{< regref CHECK_TRIGGER_REGWEN >}}.
+If needed, one-off integrity and consistency checks can be triggered via {{#regref otp_ctrl.CHECK_TRIGGER }}.
+If this functionality is not needed, it is recommended to lock down the trigger register via {{#regref otp_ctrl.CHECK_TRIGGER_REGWEN }}.
-Later on during the boot process, SW may also choose to block read access to the CREATOR_SW_CFG or OWNER_SW_CFG partitions at runtime via {{< regref CREATOR_SW_CFG_READ_LOCK >}} and {{< regref OWNER_SW_CFG_READ_LOCK >}}.
+Later on during the boot process, SW may also choose to block read access to the CREATOR_SW_CFG or OWNER_SW_CFG partitions at runtime via {{#regref otp_ctrl.CREATOR_SW_CFG_READ_LOCK }} and {{#regref otp_ctrl.OWNER_SW_CFG_READ_LOCK }}.
### Reset Considerations
@@ -803,7 +803,7 @@
### Potential Side-Effects on Flash via Life Cycle
-It should be noted that the locked status of the partition holding the creator root key (i.e., the value of the {{< regref "SECRET2_DIGEST_0" >}}) determines the ID_STATUS of the device, which in turn determines SW accessibility of creator seed material in flash and OTP.
+It should be noted that the locked status of the partition holding the creator root key (i.e., the value of the {{#regref otp_ctrl.SECRET2_DIGEST_0 }}) determines the ID_STATUS of the device, which in turn determines SW accessibility of creator seed material in flash and OTP.
That means that creator-seed-related collateral needs to be provisioned to Flash **before** the OTP digest lockdown mechanism is triggered, since otherwise accessibility to the corresponding flash region is lost.
See the [life cycle controller documentation](../lc_ctrl/README.md#id-state-of-the-device) for more details.
@@ -813,13 +813,13 @@
CSR Name | Description
-------------------------------------|------------------------------------
-{{< regref DIRECT_ACCESS_WDATA_0 >}} | Low 32bit word to be written.
-{{< regref DIRECT_ACCESS_WDATA_1 >}} | High 32bit word to be written.
-{{< regref DIRECT_ACCESS_RDATA_0 >}} | Low 32bit word that has been read.
-{{< regref DIRECT_ACCESS_RDATA_1 >}} | High 32bit word that has been read.
-{{< regref DIRECT_ACCESS_ADDRESS >}} | byte address for the access.
-{{< regref DIRECT_ACCESS_CMD >}} | Command register to trigger a read or a write access.
-{{< regref DIRECT_ACCESS_REGWEN >}} | Write protection register for DAI.
+{{#regref otp_ctrl.DIRECT_ACCESS_WDATA_0 }} | Low 32bit word to be written.
+{{#regref otp_ctrl.DIRECT_ACCESS_WDATA_1 }} | High 32bit word to be written.
+{{#regref otp_ctrl.DIRECT_ACCESS_RDATA_0 }} | Low 32bit word that has been read.
+{{#regref otp_ctrl.DIRECT_ACCESS_RDATA_1 }} | High 32bit word that has been read.
+{{#regref otp_ctrl.DIRECT_ACCESS_ADDRESS }} | byte address for the access.
+{{#regref otp_ctrl.DIRECT_ACCESS_CMD }} | Command register to trigger a read or a write access.
+{{#regref otp_ctrl.DIRECT_ACCESS_REGWEN }} | Write protection register for DAI.
See further below for a detailed [Memory Map](#direct-access-memory-map) of the address space accessible via the DAI.
@@ -827,35 +827,35 @@
A typical readout sequence looks as follows:
-1. Check whether the DAI is idle by reading the {{< regref STATUS >}} register.
-2. Write the byte address for the access to {{< regref DIRECT_ACCESS_ADDRESS >}}.
+1. Check whether the DAI is idle by reading the {{#regref otp_ctrl.STATUS }} register.
+2. Write the byte address for the access to {{#regref otp_ctrl.DIRECT_ACCESS_ADDRESS }}.
Note that the address is aligned with the granule, meaning that either 2 or 3 LSBs of the address are ignored, depending on whether the access granule is 32 or 64bit.
-3. Trigger a read command by writing 0x1 to {{< regref DIRECT_ACCESS_CMD >}}.
-4. Poll the {{< regref STATUS >}} until the DAI state goes back to idle.
+3. Trigger a read command by writing 0x1 to {{#regref otp_ctrl.DIRECT_ACCESS_CMD }}.
+4. Poll the {{#regref otp_ctrl.STATUS }} until the DAI state goes back to idle.
Alternatively, the `otp_operation_done` interrupt can be enabled up to notify the processor once an access has completed.
5. If the status register flags a DAI error, additional handling is required (see [Section on Error handling](#error-handling)).
-6. If the region accessed has a 32bit access granule, the 32bit chunk of read data can be read from {{< regref DIRECT_ACCESS_RDATA_0 >}}.
-If the region accessed has a 64bit access granule, the 64bit chunk of read data can be read from the {{< regref DIRECT_ACCESS_RDATA_0 >}} and {{< regref DIRECT_ACCESS_RDATA_1 >}} registers.
+6. If the region accessed has a 32bit access granule, the 32bit chunk of read data can be read from {{#regref otp_ctrl.DIRECT_ACCESS_RDATA_0 }}.
+If the region accessed has a 64bit access granule, the 64bit chunk of read data can be read from the {{#regref otp_ctrl.DIRECT_ACCESS_RDATA_0 }} and {{#regref otp_ctrl.DIRECT_ACCESS_RDATA_1 }} registers.
7. Go back to 1. and repeat until all data has been read.
-The hardware will set {{< regref DIRECT_ACCESS_REGWEN >}} to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers.
+The hardware will set {{#regref otp_ctrl.DIRECT_ACCESS_REGWEN }} to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers.
### Programming Sequence
A typical programming sequence looks as follows:
-1. Check whether the DAI is idle by reading the {{< regref STATUS >}} register.
-2. If the region to be accessed has a 32bit access granule, place a 32bit chunk of data into {{< regref DIRECT_ACCESS_WDATA_0 >}}.
-If the region to be accessed has a 64bit access granule, both the {{< regref DIRECT_ACCESS_WDATA_0 >}} and {{< regref DIRECT_ACCESS_WDATA_1 >}} registers have to be used.
-3. Write the byte address for the access to {{< regref DIRECT_ACCESS_ADDRESS >}}.
+1. Check whether the DAI is idle by reading the {{#regref otp_ctrl.STATUS }} register.
+2. If the region to be accessed has a 32bit access granule, place a 32bit chunk of data into {{#regref otp_ctrl.DIRECT_ACCESS_WDATA_0 }}.
+If the region to be accessed has a 64bit access granule, both the {{#regref otp_ctrl.DIRECT_ACCESS_WDATA_0 }} and {{#regref otp_ctrl.DIRECT_ACCESS_WDATA_1 }} registers have to be used.
+3. Write the byte address for the access to {{#regref otp_ctrl.DIRECT_ACCESS_ADDRESS }}.
Note that the address is aligned with the granule, meaning that either 2 or 3 LSBs of the address are ignored, depending on whether the access granule is 32 or 64bit.
-4. Trigger a write command by writing 0x2 to {{< regref DIRECT_ACCESS_CMD >}}.
-5. Poll the {{< regref STATUS >}} until the DAI state goes back to idle.
+4. Trigger a write command by writing 0x2 to {{#regref otp_ctrl.DIRECT_ACCESS_CMD }}.
+5. Poll the {{#regref otp_ctrl.STATUS }} until the DAI state goes back to idle.
Alternatively, the `otp_operation_done` interrupt can be enabled up to notify the processor once an access has completed.
6. If the status register flags a DAI error, additional handling is required (see [Section on Error handling](#error-handling)).
7. Go back to 1. and repeat until all data has been written.
-The hardware will set {{< regref DIRECT_ACCESS_REGWEN >}} to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers.
+The hardware will set {{#regref otp_ctrl.DIRECT_ACCESS_REGWEN }} to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers.
Note that SW is responsible for keeping track of already programmed OTP word locations during the provisioning phase.
**It is imperative that SW does not write the same word location twice**, since this can lead to ECC inconsistencies, thereby potentially rendering the device useless.
@@ -864,14 +864,14 @@
The hardware digest computation for the hardware and secret partitions can be triggered as follows:
-1. Check whether the DAI is idle by reading the {{< regref STATUS >}} register.
-3. Write the partition base address to {{< regref DIRECT_ACCESS_ADDRESS >}}.
-4. Trigger a digest calculation command by writing 0x4 to {{< regref DIRECT_ACCESS_CMD >}}.
-5. Poll the {{< regref STATUS >}} until the DAI state goes back to idle.
+1. Check whether the DAI is idle by reading the {{#regref otp_ctrl.STATUS }} register.
+3. Write the partition base address to {{#regref otp_ctrl.DIRECT_ACCESS_ADDRESS }}.
+4. Trigger a digest calculation command by writing 0x4 to {{#regref otp_ctrl.DIRECT_ACCESS_CMD }}.
+5. Poll the {{#regref otp_ctrl.STATUS }} until the DAI state goes back to idle.
Alternatively, the `otp_operation_done` interrupt can be enabled up to notify the processor once an access has completed.
6. If the status register flags a DAI error, additional handling is required (see [Section on Error handling](#error-handling)).
-The hardware will set {{< regref DIRECT_ACCESS_REGWEN >}} to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers.
+The hardware will set {{#regref otp_ctrl.DIRECT_ACCESS_REGWEN }} to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers.
It should also be noted that the effect of locking a partition via the digest only takes effect **after** the next system reset.
To prevent integrity check failures SW must therefore ensure that no more programming operations are issued to the affected partition after initiating the digest calculation sequence.
@@ -968,17 +968,17 @@
1. [Trigger](#digest-calculation-sequence) a digest calculation via the DAI.
2. [Read back](#readout-sequence) and verify the digest location via the DAI.
-3. Perform a full-system reset and verify that the corresponding CSRs exposing the 64bit digest have been populated ({{< regref "HW_CFG_DIGEST_0" >}}, {{< regref "SECRET0_DIGEST_0" >}}, {{< regref "SECRET1_DIGEST_0" >}} or {{< regref "SECRET2_DIGEST_0" >}}).
+3. Perform a full-system reset and verify that the corresponding CSRs exposing the 64bit digest have been populated ({{#regref otp_ctrl.HW_CFG_DIGEST_0 }}, {{#regref otp_ctrl.SECRET0_DIGEST_0 }}, {{#regref otp_ctrl.SECRET1_DIGEST_0 }} or {{#regref otp_ctrl.SECRET2_DIGEST_0 }}).
It should be noted that locking only takes effect after a system reset since the affected partitions first have to re-sense the digest values.
Hence, it is critical that SW ensures that no more data is written to the partition to be locked after triggering the hardware digest calculation.
Otherwise, the device will likely be rendered inoperable as this can lead to permanent digest mismatch errors after system reboot.
-For the {{< regref "CREATOR_SW_CFG" >}} and {{< regref "OWNER_SW_CFG" >}} partitions, the process is similar, but computation and programming of the digest is entirely up to software:
+For the {{#regref otp_ctrl.CREATOR_SW_CFG }} and {{#regref otp_ctrl.OWNER_SW_CFG }} partitions, the process is similar, but computation and programming of the digest is entirely up to software:
-1. Compute a 64bit digest over the relevant parts of the partition, and [program](#programming-sequence) that value to {{< regref "CREATOR_SW_CFG_DIGEST_0" >}} or {{< regref "OWNER_SW_CFG_DIGEST_0" >}} via the DAI. Note that digest accesses through the DAI have an access granule of 64bit.
+1. Compute a 64bit digest over the relevant parts of the partition, and [program](#programming-sequence) that value to {{#regref otp_ctrl.CREATOR_SW_CFG_DIGEST_0 }} or {{#regref otp_ctrl.OWNER_SW_CFG_DIGEST_0 }} via the DAI. Note that digest accesses through the DAI have an access granule of 64bit.
2. [Read back](#readout-sequence) and verify the digest location via the DAI.
-3. Perform a full-system reset and verify that the corresponding digest CSRs {{< regref "CREATOR_SW_CFG_DIGEST_0" >}} or {{< regref "OWNER_SW_CFG_DIGEST_0" >}} have been populated with the correct 64bit value.
+3. Perform a full-system reset and verify that the corresponding digest CSRs {{#regref otp_ctrl.CREATOR_SW_CFG_DIGEST_0 }} or {{#regref otp_ctrl.OWNER_SW_CFG_DIGEST_0 }} have been populated with the correct 64bit value.
Note that any unrecoverable errors during the programming steps, or mismatches during the read-back and verification steps indicate that the device might be malfunctioning (possibly due to fabrication defects) and hence the device may have to be scrapped.
This is however rare and should not happen after fabrication testing.
@@ -989,7 +989,7 @@
## Register Table
-{{< incGenFromIpDesc "../data/otp_ctrl.hjson" "registers" >}}
+* [Register Tabel](data/otp_ctrl.hjson#registers)
# Additional Notes
diff --git a/hw/ip/pattgen/README.md b/hw/ip/pattgen/README.md
index d2b9bcd..b763f03 100644
--- a/hw/ip/pattgen/README.md
+++ b/hw/ip/pattgen/README.md
@@ -30,7 +30,7 @@
# Theory of Operations
-The pattern can be started (or halted) on either channel by setting the corresponding {{< regref "CTRL.ENABLE" >}} bit to 1 (or 0) for the desired channel.
+The pattern can be started (or halted) on either channel by setting the corresponding {{#regref pattgen.CTRL.ENABLE }} bit to 1 (or 0) for the desired channel.
Once disabled, either channel can be configured independently.
The channel parameters (i.e. clock divider ratio, clock polarity, pattern length, pattern data, and repetition count) can all be programmed on a per-channel basis.
Enabling the pattern generator channel starts the pattern from the beginning.
@@ -45,7 +45,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/pattgen.hjson" "hwcfg" >}}
+* [Interface Tables](data/pattgen.hjson#interfaces)
## Design Details
@@ -90,8 +90,8 @@
### Interrupts
The pattern generator HWIP provides two interrupt pins, `done_ch0` and `done_ch1`, which indicate the completion of pattern generation on the output channels.
-These interrupts can be enabled/disabled by setting/un-setting the corresponding bits of the {{< regref "INTR_ENABLE" >}} register.
-To clear the interrupts, bit `1` must be written the corresponding bits of {{< regref "INTR_STATE" >}} register
+These interrupts can be enabled/disabled by setting/un-setting the corresponding bits of the {{#regref pattgen.INTR_ENABLE }} register.
+To clear the interrupts, bit `1` must be written the corresponding bits of {{#regref pattgen.INTR_STATE }} register
# Programmers guide
@@ -101,8 +101,8 @@
To configure Channel 1, use the registers with the "CH1" suffix, instead of the "CH0" registers.
To configure a single channel:
-1. Before configuration, disable the desired channel by clearing the enable bit, {{< regref "CTRL.ENABLE_CH0" >}}.
-1. Set the polarity bit, {{< regref "CTRL.POLARITY_CH0" >}}, to determine the desired clock phase.
+1. Before configuration, disable the desired channel by clearing the enable bit, {{#regref pattgen.CTRL.ENABLE_CH0 }}.
+1. Set the polarity bit, {{#regref pattgen.CTRL.POLARITY_CH0 }}, to determine the desired clock phase.
For either channel, a zero in the polarity bit indicates that the channel clock line (`pcl`) should start low, and the channel data line `pda` transitions on every falling edge of `pcl`.
A one in the polarity bit inverts the `pcl` clock so that it starts high and `pda` transitions on the rising edge.
The following waveform illustrates the effect of the `POLARITY` bit.
@@ -120,19 +120,19 @@
head: {text: 'Effect of the Polarity Registers',tick:0}}
{{</wavejson>}}
-1. Program the length of seed pattern using the length field, {{< regref "SIZE.LEN_CH0" >}}.
+1. Program the length of seed pattern using the length field, {{#regref pattgen.SIZE.LEN_CH0 }}.
Note that since the allowed seed length ranges from 1-64, the value of this field should be one less than the pattern length.
-For example, to generate an 16-bit pattern, a value of 15 should be written to the field {{< regref "SIZE.LEN_CH0" >}}.
-1. Program the seed pattern (between 1 and 64 bits in length) using the multi-register {{< regref "DATA_CH0_0" >}} and {{< regref "DATA_CH0_1" >}}.
-The first 32 bits to be transmitted, are programmed in the lower half of the multi-register (i.e. {{< regref "DATA_CH0_0" >}}), and the latter 32 bits are programmed in the upper half of the multi-register (i.e. {{< regref "DATA_CH0_1" >}}).
-1. Program the clock divider ratio using the register {{< regref "PREDIV_CH0.CLK_RATIO" >}}.
+For example, to generate an 16-bit pattern, a value of 15 should be written to the field {{#regref pattgen.SIZE.LEN_CH0 }}.
+1. Program the seed pattern (between 1 and 64 bits in length) using the multi-register {{#regref pattgen.DATA_CH0_0 }} and {{#regref pattgen.DATA_CH0_1 }}.
+The first 32 bits to be transmitted, are programmed in the lower half of the multi-register (i.e. {{#regref pattgen.DATA_CH0_0 }}), and the latter 32 bits are programmed in the upper half of the multi-register (i.e. {{#regref pattgen.DATA_CH0_1 }}).
+1. Program the clock divider ratio using the register {{#regref pattgen.PREDIV_CH0.CLK_RATIO }}.
The resulting clock frequency will be slower than the input I/O clock by a ratio of 2×(CLK_RATIO+1):
$$f_{pclx}=\frac{f_\textrm{I/O clk}}{2(\textrm{CLK_RATIO}+1)}$$
-1. Program the desired number of pattern repetitions using the repetition field {{< regref "SIZE.REPS_CH0" >}}.
+1. Program the desired number of pattern repetitions using the repetition field {{#regref pattgen.SIZE.REPS_CH0 }}.
Note that since the allowed number of pattern repetitions ranges from 1-1024, the value of this field should be one less than the desired repetition count.
-For example, to repeat a pattern 30, a value of 29 should written to the field {{< regref "SIZE.REPS_CH0" >}}.
-1. Finally to start the pattern, set the {{< regref "CTRL.ENABLE_CH0" >}}.
-To start both channel patterns at the same time, configure both channels then simultaneously assert both the {{< regref "CTRL.ENABLE_CH0" >}} and {{< regref "CTRL.ENABLE_CH1" >}} bits in the same register access.
+For example, to repeat a pattern 30, a value of 29 should written to the field {{#regref pattgen.SIZE.REPS_CH0 }}.
+1. Finally to start the pattern, set the {{#regref pattgen.CTRL.ENABLE_CH0 }}.
+To start both channel patterns at the same time, configure both channels then simultaneously assert both the {{#regref pattgen.CTRL.ENABLE_CH0 }} and {{#regref pattgen.CTRL.ENABLE_CH1 }} bits in the same register access.
## Device Interface Functions (DIFs)
@@ -140,4 +140,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/pattgen.hjson" "registers" >}}
+* [Register Table](data/pattgen.hjson#registers)
diff --git a/hw/ip/pinmux/README.md b/hw/ip/pinmux/README.md
index 568bfd9..91c675c 100644
--- a/hw/ip/pinmux/README.md
+++ b/hw/ip/pinmux/README.md
@@ -86,7 +86,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson" "hwcfg" >}}
+* [Interface Tables](../../top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson#interfaces)
### Parameters
@@ -151,7 +151,7 @@
The `pinmux` contains eight programmable wakeup detector modules that can listen on any of the MIO or DIO pins.
Each detector contains a debounce filter and an 8bit counter running on the AON clock domain.
-The detectors can be programmed via the {{< regref "WKUP_DETECTOR_0" >}} and {{< regref "WKUP_DETECTOR_CNT_TH_0" >}} registers to detect the following patterns:
+The detectors can be programmed via the {{#regref pinmux.WKUP_DETECTOR_0 }} and {{#regref pinmux.WKUP_DETECTOR_CNT_TH_0 }} registers to detect the following patterns:
- rising edge
- falling edge
@@ -162,9 +162,9 @@
Note that for all patterns listed above, the input signal is sampled with the AON clock.
This means that the input signal needs to remain stable for at least one AON clock cycle after a level change for the detector to recognize the event (depending on the debounce filter configuration, the signal needs to remain stable for multiple clock cycles).
-If a pattern is detected, the wakeup detector will send a wakeup request to the power manager, and the cause bit corresponding to that detector will be set in the {{< regref "WKUP_CAUSE" >}} register.
+If a pattern is detected, the wakeup detector will send a wakeup request to the power manager, and the cause bit corresponding to that detector will be set in the {{#regref pinmux.WKUP_CAUSE }} register.
-Note that the wkup detector should be disabled by setting {{< regref "WKUP_DETECTOR_EN_0" >}} before changing the detection mode.
+Note that the wkup detector should be disabled by setting {{#regref pinmux.WKUP_DETECTOR_EN_0 }} before changing the detection mode.
The reason for that is that the pulse width counter is NOT cleared upon a mode change while the detector is enabled.
## Strap Sampling and TAP Isolation
@@ -257,7 +257,7 @@
`attr_i[8:7]` | `input` | `logic` | Slew rate (0x0: slowest, 0x3: fastest)
`attr_i[12:9]` | `input` | `logic` | Drive strength (0x0: weakest, 0xf: strongest)
-Note that the corresponding pad attribute registers {{< regref "MIO_PAD_ATTR_0" >}} and {{< regref "DIO_PAD_ATTR_0" >}} have "writes-any-reads-legal" (WARL) behavior (see also [pad attributes](#pad-attributes)).
+Note that the corresponding pad attribute registers {{#regref pinmux.MIO_PAD_ATTR_0 }} and {{#regref pinmux.DIO_PAD_ATTR_0 }} have "writes-any-reads-legal" (WARL) behavior (see also [pad attributes](#pad-attributes)).
# Programmers Guide
@@ -265,10 +265,10 @@
Software should determine and program the pad attributes at startup, or reprogram the attributes when the functionality requirements change at runtime.
-This can be achieved by writing to the {{< regref "MIO_PAD_ATTR_0" >}} and {{< regref "DIO_PAD_ATTR_0" >}} registers.
+This can be achieved by writing to the {{#regref pinmux.MIO_PAD_ATTR_0 }} and {{#regref pinmux.DIO_PAD_ATTR_0 }} registers.
Note that the IO attributes should be configured before enabling muxed IOs going through the `pinmux` matrix in order to avoid undesired electrical behavior and/or contention at the pads.
-The pad attributes configuration can be locked down individually for each pad via the {{< regref "MIO_PAD_ATTR_REGWEN_0" >}} and {{< regref "DIO_PAD_ATTR_REGWEN_0" >}} registers.
+The pad attributes configuration can be locked down individually for each pad via the {{#regref pinmux.MIO_PAD_ATTR_REGWEN_0 }} and {{#regref pinmux.DIO_PAD_ATTR_REGWEN_0 }} registers.
The configuration can then not be altered anymore until the next system reset.
The following pad attributes are supported by this register layout by default:
@@ -294,7 +294,7 @@
Upon POR, the `pinmux` state is such that all MIO outputs are high-Z, and all MIO peripheral inputs are tied off to 0.
Software should determine and program the `pinmux` mapping at startup, or reprogram it when the functionality requirements change at runtime.
-This can be achieved by writing the following values to the {{< regref "PERIPH_INSEL_0" >}} and {{< regref "MIO_OUTSEL_0" >}} registers.
+This can be achieved by writing the following values to the {{#regref pinmux.PERIPH_INSEL_0 }} and {{#regref pinmux.MIO_OUTSEL_0 }} registers.
`periph_insel` Value | Selected Input Signal
----------------------|-----------------------
@@ -313,13 +313,13 @@
The global default at reset is `2`, but the default of individual signals can be overridden at design time, if needed.
-Note that the `pinmux` configuration should be sequenced after any IO attribute-specific configuration in the {{< regref "MIO_PAD_ATTR_0" >}} and {{< regref "DIO_PAD_ATTR_0" >}} registers to avoid any unwanted electric behavior and/or contention.
-If needed, each select signal can be individually locked down via {{< regref "MIO_PERIPH_INSEL_REGWEN_0" >}} or {{< regref "MIO_OUTSEL_REGWEN_0" >}}.
+Note that the `pinmux` configuration should be sequenced after any IO attribute-specific configuration in the {{#regref pinmux.MIO_PAD_ATTR_0 }} and {{#regref pinmux.DIO_PAD_ATTR_0 }} registers to avoid any unwanted electric behavior and/or contention.
+If needed, each select signal can be individually locked down via {{#regref pinmux.MIO_PERIPH_INSEL_REGWEN_0 }} or {{#regref pinmux.MIO_OUTSEL_REGWEN_0 }}.
The configuration can then not be altered anymore until the next system reset.
## Sleep Features
-The sleep behavior of each individual MIO or DIO can be defined via the ({{< regref "MIO_PAD_SLEEP_EN_0" >}}, {{< regref "DIO_PAD_SLEEP_EN_0" >}}, {{< regref "MIO_PAD_SLEEP_MODE_0" >}} and {{< regref "DIO_PAD_SLEEP_MODE_0" >}}) registers.
+The sleep behavior of each individual MIO or DIO can be defined via the ({{#regref pinmux.MIO_PAD_SLEEP_EN_0 }}, {{#regref pinmux.DIO_PAD_SLEEP_EN_0 }}, {{#regref pinmux.MIO_PAD_SLEEP_MODE_0 }} and {{#regref pinmux.DIO_PAD_SLEEP_MODE_0 }}) registers.
Available sleep behaviors are:
`dio/mio_pad_sleep_en` Value | `dio/mio_pad_sleep_mode` Value | Sleep Behavior
------------------------------|--------------------------------|-----------------------
@@ -333,12 +333,12 @@
Rather, the retention logic continues to drive the value coming from the peripheral side.
Also note that the sleep logic is located after the `pinmux` matrix, hence the sleep configuration is per MIO pad and not per MIO peripheral.
-Before sleep entry, SW should configure the appropriate sleep behavior of all MIOs/DIOs via {{< regref "MIO_PAD_SLEEP_MODE_0" >}}, {{< regref "DIO_PAD_SLEEP_MODE_0" >}}.
+Before sleep entry, SW should configure the appropriate sleep behavior of all MIOs/DIOs via {{#regref pinmux.MIO_PAD_SLEEP_MODE_0 }}, {{#regref pinmux.DIO_PAD_SLEEP_MODE_0 }}.
This configuration can be optionally locked down, in which case it cannot be modified again until POR.
-The configured behavior is then activated for all pads that have sleep mode set to enabled ({{< regref "MIO_PAD_SLEEP_EN_0" >}} and {{< regref "DIO_PAD_SLEEP_EN_0" >}}) at once by the power manager during the sleep entry sequence.
+The configured behavior is then activated for all pads that have sleep mode set to enabled ({{#regref pinmux.MIO_PAD_SLEEP_EN_0 }} and {{#regref pinmux.DIO_PAD_SLEEP_EN_0 }}) at once by the power manager during the sleep entry sequence.
When exiting sleep, the task of disabling the sleep behavior is however up to SW.
-I.e., it must clear the per-pad sleep status bits in registers {{< regref "MIO_PAD_SLEEP_STATUS_0" >}} and {{< regref "DIO_PAD_SLEEP_STATUS_0" >}} that have been set upon sleep entry.
+I.e., it must clear the per-pad sleep status bits in registers {{#regref pinmux.MIO_PAD_SLEEP_STATUS_0 }} and {{#regref pinmux.DIO_PAD_SLEEP_STATUS_0 }} that have been set upon sleep entry.
The rationale for this is that it may not be desirable to disable sleep behavior on all pads at once due to some additional book keeping / re-initialization that needs to be performed while exiting sleep.
## Wakeup Features
@@ -351,19 +351,19 @@
A typical programming sequence for the wakeup detectors looks as follows:
-1. Before initiating any sleep mode, SW should configure the wakeup detectors appropriately and enable them via the {{< regref "WKUP_DETECTOR_0" >}}, {{< regref "WKUP_DETECTOR_CNT_TH_0" >}} and {{< regref "WKUP_DETECTOR_PADSEL_0" >}} registers.
+1. Before initiating any sleep mode, SW should configure the wakeup detectors appropriately and enable them via the {{#regref pinmux.WKUP_DETECTOR_0 }}, {{#regref pinmux.WKUP_DETECTOR_CNT_TH_0 }} and {{#regref pinmux.WKUP_DETECTOR_PADSEL_0 }} registers.
-2. Optionally, lock the wakeup detector configuration via the {{< regref "WKUP_DETECTOR_REGWEN_0" >}} registers.
+2. Optionally, lock the wakeup detector configuration via the {{#regref pinmux.WKUP_DETECTOR_REGWEN_0 }} registers.
3. During sleep, the wakeup detectors will trigger a wakeup request if a matching pattern has been observed.
- A bit corresponding to the wakeup detector that has observed the pattern will be set in the {{< regref "WKUP_CAUSE" >}} register.
+ A bit corresponding to the wakeup detector that has observed the pattern will be set in the {{#regref pinmux.WKUP_CAUSE }} register.
4. When exiting sleep, SW should read the wake info register in the [power manager](../pwrmgr/README.md) to determine the reason(s) for the wakeup request.
-5. If the wakeup request was due to a pin wakeup pattern detector, SW should inspect the {{< regref "WKUP_CAUSE" >}} registers in order to determine the exact cause.
+5. If the wakeup request was due to a pin wakeup pattern detector, SW should inspect the {{#regref pinmux.WKUP_CAUSE }} registers in order to determine the exact cause.
-6. SW should in any case disable the wakeup detectors and clear the {{< regref "WKUP_CAUSE" >}} registers once it is safe to do so (in order to not miss any events).
- Note that the {{< regref "WKUP_CAUSE" >}} registers reside in the slow AON clock domain, and hence clearing them takes a few uS to take effect.
+6. SW should in any case disable the wakeup detectors and clear the {{#regref pinmux.WKUP_CAUSE }} registers once it is safe to do so (in order to not miss any events).
+ Note that the {{#regref pinmux.WKUP_CAUSE }} registers reside in the slow AON clock domain, and hence clearing them takes a few uS to take effect.
If needed, a SW readback can be performed to ensure that the clear operation has completed successfully.
## Pinout and Pinmux Mapping
@@ -385,4 +385,4 @@
Similar register descriptions can be generated with different parameterizations.
-{{< incGenFromIpDesc "/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson" "registers" >}}
+* [Register Table](../../top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson#registers)
diff --git a/hw/ip/pwm/README.md b/hw/ip/pwm/README.md
index 8cd40fe..9bc1f17 100644
--- a/hw/ip/pwm/README.md
+++ b/hw/ip/pwm/README.md
@@ -75,7 +75,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/pwm.hjson" "hwcfg" >}}
+* [Interface Tables](data/pwm.hjson#interfaces)
## Design Details
@@ -109,8 +109,8 @@
Thus the allowed duty cycle in principle ranges from 0 to 99.998% (i.e. <nobr>1-(½)<sup>16</sup></nobr>).
However, the actual phase resolution may be smaller.
-In order to support faster pulse rates, the phase resolution can be set to less than 16-bits, in which case the observed duty cycle will be rounded down to the next lowest multiple of <nobr>2<sup>-({{< regref "CFG.DC_RESN" >}}+1)</sup></nobr>.
-In other words, the {{< regref "CFG.DC_RESN" >}} register effectively limits the duty cycle resolution, such that only the <nobr>{{< regref "CFG.DC_RESN" >}}+1</nobr> most significant bits are relevant:
+In order to support faster pulse rates, the phase resolution can be set to less than 16-bits, in which case the observed duty cycle will be rounded down to the next lowest multiple of <nobr>2<sup>-({{#regref pwm.CFG.DC_RESN }}+1)</sup></nobr>.
+In other words, the {{#regref pwm.CFG.DC_RESN }} register effectively limits the duty cycle resolution, such that only the <nobr>{{#regref pwm.CFG.DC_RESN }}+1</nobr> most significant bits are relevant:
$$DC(x; \textrm{DC_RESN})=\frac{\textrm{MSB}(x; \textrm{DC_RESN}+1)}{2^{(\textrm{DC_RESN}+1)}},$$
@@ -124,7 +124,7 @@
Each PWM pulse cycle is divided into <nobr>2<sup>DC_RESN+1</sup></nobr> beats.
During each beat, the 16-bit phase counter increments by 2<sup>(16-DC_RESN-1)</sup> (modulo 65536).
-The beat period is defined by the {{< regref "CFG.CLK_DIV" >}} register:
+The beat period is defined by the {{#regref pwm.CFG.CLK_DIV }} register:
$$f_\textrm{beat}=\frac{f_\textrm{core clk}}{\textrm{CLK_DIV}+1}$$
@@ -132,9 +132,9 @@
The PWM drive frequency is therefore:
$$f_\textrm{PWM}=f_\textrm{beat}\frac{2^{16-\textrm{DC_RESN}-1}}{2^{16}}=\frac{f_\textrm{core clk}}{2^{\textrm{DC_RESN}+1}(\textrm{CLK_DIV}+1)}$$
-The PWM phase counter is reset whenever {{< regref "CFG.CNTR_EN" >}} is disabled.
+The PWM phase counter is reset whenever {{#regref pwm.CFG.CNTR_EN }} is disabled.
-The following figure illustrates the effect of the clock divider register. Note that changes to {{< regref "CFG.CLK_DIV" >}} or {{< regref "CFG.DC_RESN" >}} only take effect when {{< regref "CFG.CNTR_EN" >}} is disabled.
+The following figure illustrates the effect of the clock divider register. Note that changes to {{#regref pwm.CFG.CLK_DIV }} or {{#regref pwm.CFG.DC_RESN }} only take effect when {{#regref pwm.CFG.CNTR_EN }} is disabled.
{{< wavejson >}}{signal: [
{name: 'core_clk_i', wave: 'p..............|..........'},
@@ -159,13 +159,13 @@
For concreteness, the text discusses the operation of channel 0, using registers and fields ending with "_0".
To operate other channels, simply choose the registers with the appropriate channel suffix.
-Clearing {{< regref "PWM_EN.EN_0" >}} disables the channel, suppressing all output pulses.
+Clearing {{#regref pwm.PWM_EN.EN_0 }} disables the channel, suppressing all output pulses.
-The pulse phase delay is always programmed by firmware into the TL-UL register {{< regref "PWM_PARAM_0.PHASE_DELAY_0" >}}.
+The pulse phase delay is always programmed by firmware into the TL-UL register {{#regref pwm.PWM_PARAM_0.PHASE_DELAY_0 }}.
The duty cycle however comes from the blink control hardware (which is described in the next section).
The current duty cycle is stored in a channel-specific signal register, `duty_cycle`.
-When operating at full resolution (i.e. `DC_RESN`==15), the channel output rises when the phase counter equals {{<regref "PWM_PARAM_0.PHASE_DELAY_0">}}, and falls when the phase counter equals {{< regref "PWM_PARAM_0.PHASE_DELAY_0">}} + `duty_cycle` (mod 2<sup>(`DC_RESN`+1)</sup>).
+When operating at full resolution (i.e. `DC_RESN`==15), the channel output rises when the phase counter equals {{#regref pwm.PWM_PARAM_0.PHASE_DELAY_0 }}, and falls when the phase counter equals {{#regref pwm.PWM_PARAM_0.PHASE_DELAY_0 }} + `duty_cycle` (mod 2<sup>(`DC_RESN`+1)</sup>).
In both cases, the transition occurs at the beginning of the beat.
When operating at lower resolution the same comparison applies, but using only the most significant (`DC_RESN`+1) bits.
@@ -173,9 +173,9 @@
In this case the comparator output will be high at the beginning of each cycle, as seen in the example waveform below.
By default the pulses are all active-high, meaning the output is low if a PWM channel is disabled.
-However, to support various drive schemes, the polarity can be inverted on a channel-by-channel basis using the {{< regref "INVERT" >}} register.
+However, to support various drive schemes, the polarity can be inverted on a channel-by-channel basis using the {{#regref pwm.INVERT }} register.
-The following figure illustrates the effect of the {{< regref "PWM_PARAM_0.PHASE_DELAY_0" >}} register and `duty_cycle`.
+The following figure illustrates the effect of the {{#regref pwm.PWM_PARAM_0.PHASE_DELAY_0 }} register and `duty_cycle`.
Note that this figure shows two channels, 0 and 1, where the second channel has a significant phase delay, such that the output pulse is high when `phase_ctr` overflows to zero.
{{< wavejson >}}
@@ -200,49 +200,49 @@
}
{{< /wavejson >}}
-Changes to {{< regref "PWM_EN.EN_0" >}} bit have no effect on the *timing* of the pulses, as the `phase_ctr` is common to all channels.
-Enabling {{< regref "PWM_EN.EN_0" >}}, or changing {{< regref "PWM_PARAM_0.PHASE_DELAY_0" >}} is acceptable while the PWM channel is enabled.
-Since these registers take effect immediately, the shape of the following pulse may be unpredictable if they are changed while {{< regref "CFG.CNTR_EN" >}} is active, though this glitch in a single pulse is likely not a problem for most applications.
-Changes to the duty cycle register {{< regref "DUTY_CYCLE_0.A_0" >}} may also be effective immediately, but only *when blinking is disabled*.
+Changes to {{#regref pwm.PWM_EN.EN_0 }} bit have no effect on the *timing* of the pulses, as the `phase_ctr` is common to all channels.
+Enabling {{#regref pwm.PWM_EN.EN_0 }}, or changing {{#regref pwm.PWM_PARAM_0.PHASE_DELAY_0 }} is acceptable while the PWM channel is enabled.
+Since these registers take effect immediately, the shape of the following pulse may be unpredictable if they are changed while {{#regref pwm.CFG.CNTR_EN }} is active, though this glitch in a single pulse is likely not a problem for most applications.
+Changes to the duty cycle register {{#regref pwm.DUTY_CYCLE_0.A_0 }} may also be effective immediately, but only *when blinking is disabled*.
-In the above waveform, the first beat (labeled "0") does not start for one clock after {{< regref "CFG.CNTR_EN" >}} is asserted.
+In the above waveform, the first beat (labeled "0") does not start for one clock after {{#regref pwm.CFG.CNTR_EN }} is asserted.
This delay is typical, and reflects the fact that it takes exactly one clock cycle for the phase counter to start (as seen in the previous waveform).
There is a register `pwm_out` at the output pin, which adds an additional delay cycle before the output pin.
-Thus, in addition to delay of the clock domain crossing, there is in total a minimum two clock delay between the assertion of {{< regref "CFG.CNTR_EN">}} and the rising edge of the first output pulse.
+Thus, in addition to delay of the clock domain crossing, there is in total a minimum two clock delay between the assertion of {{#regref pwm.CFG.CNTR_EN }} and the rising edge of the first output pulse.
### Hardware-Controlled Blink Features
-By default, the duty cycle of each channel is directly controlled by firmware, by writing the desired PWM duty cycle to the {{< regref "DUTY_CYCLE_0.A_0">}} register.
+By default, the duty cycle of each channel is directly controlled by firmware, by writing the desired PWM duty cycle to the {{#regref pwm.DUTY_CYCLE_0.A_0 }} register.
There are two other modes which allow for programmably-timed duty cycle modulations, under hardware control.
-- In the standard blink mode the duty cycle toggles between two values, {{< regref "DUTY_CYCLE_0.A_0" >}} and {{<regref "DUTY_CYCLE_0.B_0" >}}.
-- In heartbeat mode, the duty cycle linearly transitions from {{< regref "DUTY_CYCLE_0.A_0" >}} to {{< regref "DUTY_CYCLE_0.B_0" >}} and back, via a regularly-timed sequence of duty cycle increments or decrements.
+- In the standard blink mode the duty cycle toggles between two values, {{#regref pwm.DUTY_CYCLE_0.A_0 }} and {{#regref pwm.DUTY_CYCLE_0.B_0 }}.
+- In heartbeat mode, the duty cycle linearly transitions from {{#regref pwm.DUTY_CYCLE_0.A_0 }} to {{#regref pwm.DUTY_CYCLE_0.B_0 }} and back, via a regularly-timed sequence of duty cycle increments or decrements.
-In both modes the timing and control of the blinking or transition is controlled by the register fields {{< regref "BLINK_PARAM_0.X_0" >}} and {{< regref "BLINK_PARAM_0.Y_0" >}}.
+In both modes the timing and control of the blinking or transition is controlled by the register fields {{#regref pwm.BLINK_PARAM_0.X_0 }} and {{#regref pwm.BLINK_PARAM_0.Y_0 }}.
However in either mode, the interpretation of these fields is different.
-Note that changes to the {{< regref "BLINK_PARAM_0" >}} register or to the register field {{< regref "PWM_PARAM_0.HTBT_EN_0" >}} only take effect when the {{< regref "PWM_PARAM_0.BLINK_EN_0" >}} is deasserted.
+Note that changes to the {{#regref pwm.BLINK_PARAM_0 }} register or to the register field {{#regref pwm.PWM_PARAM_0.HTBT_EN_0 }} only take effect when the {{#regref pwm.PWM_PARAM_0.BLINK_EN_0 }} is deasserted.
Both of the blink modes make use of a 16-bit internal blink counter (one per channel).
-This counter is reset whenever {{< regref "PWM_PARAM_0.BLINK_EN_0" >}} is cleared.
+This counter is reset whenever {{#regref pwm.PWM_PARAM_0.BLINK_EN_0 }} is cleared.
In other words, changing the blink behavior requires first halting the blink pattern, and the pattern starts from the beginning whenever the blink enable bit is reasserted.
#### Standard Blink Mode
-To enter standard blink mode, assert {{< regref "PWM_PARAM_0.BLINK_EN_0" >}}, while leaving {{< regref "PWM_PARAM_0.HTBT_EN_0" >}} deasserted.
+To enter standard blink mode, assert {{#regref pwm.PWM_PARAM_0.BLINK_EN_0 }}, while leaving {{#regref pwm.PWM_PARAM_0.HTBT_EN_0 }} deasserted.
-In standard blink mode, the duty cycle abruptly alternates between two values: {{< regref "DUTY_CYCLE_0.A_0" >}} and {{< regref "DUTY_CYCLE_0.B_0" >}}.
-The sequence starts with {{< regref "BLINK_PARAM_0.X_0" >}}+1 pulses at {{< regref "DUTY_CYCLE_0.A_0" >}}, followed by {{< regref "BLINK_PARAM_0.Y_0" >}}+1 pulses at {{< regref "DUTY_CYCLE_0.B_0" >}}, after which the cycle repeats until blink mode is disabled.
+In standard blink mode, the duty cycle abruptly alternates between two values: {{#regref pwm.DUTY_CYCLE_0.A_0 }} and {{#regref pwm.DUTY_CYCLE_0.B_0 }}.
+The sequence starts with {{#regref pwm.BLINK_PARAM_0.X_0 }}+1 pulses at {{#regref pwm.DUTY_CYCLE_0.A_0 }}, followed by {{#regref pwm.BLINK_PARAM_0.Y_0 }}+1 pulses at {{#regref pwm.DUTY_CYCLE_0.B_0 }}, after which the cycle repeats until blink mode is disabled.
Typically multiple channels need to be configured to blink synchronously, for example in the tri-color LED case.
-This can be achieved by first disabling the desired PWM outputs using the {{< regref "PWM_EN">}} multi-register.
-Once the blink parameters have been configured for these channels, they can be simultaneously re-enabled using a single write to {{< regref "PWM_EN">}}.
+This can be achieved by first disabling the desired PWM outputs using the {{#regref pwm.PWM_EN }} multi-register.
+Once the blink parameters have been configured for these channels, they can be simultaneously re-enabled using a single write to {{#regref pwm.PWM_EN }}.
#### Heartbeat Mode
-To enter heartbeat mode, assert both {{< regref "PWM_PARAM_0.BLINK_EN_0" >}} and {{< regref "PWM_PARAM_0.HTBT_EN_0" >}}.
+To enter heartbeat mode, assert both {{#regref pwm.PWM_PARAM_0.BLINK_EN_0 }} and {{#regref pwm.PWM_PARAM_0.HTBT_EN_0 }}.
-In heartbeat mode the duty cycle gradually transitions from {{< regref "DUTY_CYCLE_0.A_0" >}} to {{< regref "DUTY_CYCLE_0.B_0" >}} and back in a series of small steps.
+In heartbeat mode the duty cycle gradually transitions from {{#regref pwm.DUTY_CYCLE_0.A_0 }} to {{#regref pwm.DUTY_CYCLE_0.B_0 }} and back in a series of small steps.
An example of this process is illustrated in the following waveform.
{{< wavejson >}}
@@ -261,54 +261,54 @@
}
{{< /wavejson >}}
-The sequence starts with {{< regref "BLINK_PARAM_0.X_0" >}}+1 pulses at {{< regref "DUTY_CYCLE_0.A_0" >}}.
-The duty cycle then increases by {{< regref "BLINK_PARAM_0.Y_0" >}}+1 units, and {{< regref "BLINK_PARAM_0.X_0" >}}+1 more pulses are generated at the new duty cycle.
-The cycle repeats until the `duty cycle`≥ {{< regref "DUTY_CYCLE_0.B_0" >}}, at which point the cycle is reversed, decrementing with the same step-size and rate until the duty cycle once again returns to {{< regref "DUTY_CYCLE_0.A_0" >}} and the whole process repeats.
-(This all assumes that {{< regref "DUTY_CYCLE_0.B_0" >}} > {{< regref "DUTY_CYCLE_0.A_0" >}}.
-If {{< regref "DUTY_CYCLE_0.B_0" >}} < {{< regref "DUTY_CYCLE_0.A_0" >}}, the cycle is similar but with all the signs reversed.
-For instance, the duty cycle is repeatedly <i>decremented</i> until reaching {{< regref "DUTY_CYCLE_0.B_0" >}}.)
+The sequence starts with {{#regref pwm.BLINK_PARAM_0.X_0 }}+1 pulses at {{#regref pwm.DUTY_CYCLE_0.A_0 }}.
+The duty cycle then increases by {{#regref pwm.BLINK_PARAM_0.Y_0 }}+1 units, and {{#regref pwm.BLINK_PARAM_0.X_0 }}+1 more pulses are generated at the new duty cycle.
+The cycle repeats until the `duty cycle`≥ {{#regref pwm.DUTY_CYCLE_0.B_0 }}, at which point the cycle is reversed, decrementing with the same step-size and rate until the duty cycle once again returns to {{#regref pwm.DUTY_CYCLE_0.A_0 }} and the whole process repeats.
+(This all assumes that {{#regref pwm.DUTY_CYCLE_0.B_0 }} > {{#regref pwm.DUTY_CYCLE_0.A_0 }}.
+If {{#regref pwm.DUTY_CYCLE_0.B_0 }} < {{#regref pwm.DUTY_CYCLE_0.A_0 }}, the cycle is similar but with all the signs reversed.
+For instance, the duty cycle is repeatedly <i>decremented</i> until reaching {{#regref pwm.DUTY_CYCLE_0.B_0 }}.)
-In the heartbeat process, the duty cycle always starts at {{< regref "DUTY_CYCLE_0.A_0" >}}, but it may slightly exceed {{< regref "DUTY_CYCLE_0.B_0" >}} on the last step if the step-size does not evenly divide the difference between duty cycles.
+In the heartbeat process, the duty cycle always starts at {{#regref pwm.DUTY_CYCLE_0.A_0 }}, but it may slightly exceed {{#regref pwm.DUTY_CYCLE_0.B_0 }} on the last step if the step-size does not evenly divide the difference between duty cycles.
-The duty cycle is never allowed to overflow or underflow, even if {{< regref "DUTY_CYCLE_0.B_0" >}} is very close to the minimum or maximum 16-bit value.
+The duty cycle is never allowed to overflow or underflow, even if {{#regref pwm.DUTY_CYCLE_0.B_0 }} is very close to the minimum or maximum 16-bit value.
If needed, the most extreme value in the `duty_cycle` sequence is truncated to stay within the allowable 16-bit range.
All other points in the heartbeat sequence are unaffected by this truncation.
# Programmer's Guide
To set the PWM Frequency for the entire IP:
-1. Clear {{< regref "CFG.CNTR_EN" >}}
-2. Select {{< regref "CFG.CLK_DIV" >}}
-3. Assert {{< regref "CFG.CNTR_EN" >}}
+1. Clear {{#regref pwm.CFG.CNTR_EN }}
+2. Select {{#regref pwm.CFG.CLK_DIV }}
+3. Assert {{#regref pwm.CFG.CNTR_EN }}
To configure the fixed PWM duty cycle and for a particular output channel (for example channel 0):
-1. Disable blinking by clearing the {{< regref "PWM_PARAM_0.BLINK_EN_0" >}} bit.
-2. Set {{< regref "DUTY_CYCLE_0.A_0" >}}
-3. Optionally set {{< regref "PWM_PARAM_0.PHASE_DELAY_0" >}} to adjust the pulse phase.
-4. Optionally assert {{< regref "INVERT.INVERT_0" >}} to flip the polarity.
-5. Set {{< regref "PWM_EN.EN_0" >}} to turn the channel on.
+1. Disable blinking by clearing the {{#regref pwm.PWM_PARAM_0.BLINK_EN_0 }} bit.
+2. Set {{#regref pwm.DUTY_CYCLE_0.A_0 }}
+3. Optionally set {{#regref pwm.PWM_PARAM_0.PHASE_DELAY_0 }} to adjust the pulse phase.
+4. Optionally assert {{#regref pwm.INVERT.INVERT_0 }} to flip the polarity.
+5. Set {{#regref pwm.PWM_EN.EN_0 }} to turn the channel on.
These changes will take place immediately, regardless of whether the `phase_ctr` is currently in the middle of a pulse cycle.
To activate simple blinking for channel 0:
-1. Set {{< regref "DUTY_CYCLE_0.A_0" >}} and {{< regref "DUTY_CYCLE_0.B_0" >}} to establish the initial and target duty cycles.
-2. Clear the {{< regref "PWM_PARAM_0.BLINK_EN_0" >}} and {{< regref "PWM_PARAM_0.HTBT_EN_0" >}} bits.
+1. Set {{#regref pwm.DUTY_CYCLE_0.A_0 }} and {{#regref pwm.DUTY_CYCLE_0.B_0 }} to establish the initial and target duty cycles.
+2. Clear the {{#regref pwm.PWM_PARAM_0.BLINK_EN_0 }} and {{#regref pwm.PWM_PARAM_0.HTBT_EN_0 }} bits.
This step is necessary for changing the blink timing parameters
-3. Set {{< regref "BLINK_PARAM_0.X_0" >}} and {{< regref "BLINK_PARAM_0.Y_0" >}} to set the number of pulse cycles respectively spent at duty cycle A and duty cycle B.
-4. Re-assert {{< regref "PWM_PARAM_0.BLINK_EN_0" >}}.
+3. Set {{#regref pwm.BLINK_PARAM_0.X_0 }} and {{#regref pwm.BLINK_PARAM_0.Y_0 }} to set the number of pulse cycles respectively spent at duty cycle A and duty cycle B.
+4. Re-assert {{#regref pwm.PWM_PARAM_0.BLINK_EN_0 }}.
-For synchronous blinking of a group of channels, first disable the desired channels using the {{< regref "PWM_EN" >}} register.
-Then after configuring the blink properties of the entire group, re-enable them with a single write to {{< regref "PWM_EN" >}}.
+For synchronous blinking of a group of channels, first disable the desired channels using the {{#regref pwm.PWM_EN }} register.
+Then after configuring the blink properties of the entire group, re-enable them with a single write to {{#regref pwm.PWM_EN }}.
To activate heartbeat blinking for channel 0:
-1. Set {{< regref "DUTY_CYCLE_0.A_0" >}} and {{< regref "DUTY_CYCLE_0.B_0" >}} to establish the initial and target duty cycles.
-2. Clear the {{< regref "PWM_PARAM_0.BLINK_EN_0" >}} bit.
+1. Set {{#regref pwm.DUTY_CYCLE_0.A_0 }} and {{#regref pwm.DUTY_CYCLE_0.B_0 }} to establish the initial and target duty cycles.
+2. Clear the {{#regref pwm.PWM_PARAM_0.BLINK_EN_0 }} bit.
This step is necessary for changing the blink timing parameters
-3. Set {{< regref "BLINK_PARAM_0.X_0" >}} to the number of pulse cycles between duty cycle steps (i.e. increments or decrements).
-4. Set {{< regref "BLINK_PARAM_0.Y_0" >}} to set the size of each step.
-5. In a single write, assert both {{< regref "PWM_PARAM_0.BLINK_EN_0" >}} and {{< regref "PWM_PARAM_0.HTBT_EN_0" >}}
+3. Set {{#regref pwm.BLINK_PARAM_0.X_0 }} to the number of pulse cycles between duty cycle steps (i.e. increments or decrements).
+4. Set {{#regref pwm.BLINK_PARAM_0.Y_0 }} to set the size of each step.
+5. In a single write, assert both {{#regref pwm.PWM_PARAM_0.BLINK_EN_0 }} and {{#regref pwm.PWM_PARAM_0.HTBT_EN_0 }}
## Device Interface Functions (DIFs)
@@ -316,4 +316,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/pwm.hjson" "registers" >}}
+* [Register Table](data/pwm.hjson#registers)
diff --git a/hw/ip/pwrmgr/README.md b/hw/ip/pwrmgr/README.md
index fbb1005..b788858 100644
--- a/hw/ip/pwrmgr/README.md
+++ b/hw/ip/pwrmgr/README.md
@@ -49,7 +49,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson" "hwcfg" >}}
+* [Interface Tables](../../top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson#interfaces)
## Overall Sequencing
@@ -87,7 +87,7 @@
Once the fast FSM acknowledges the power-up completion, the slow FSM transitions to `Idle` and waits for a power down request.
When a power down request is received, the slow FSM turns off AST clocks and power as directed by software configuration.
-This means the clocks and power are not always turned off, but are rather controlled by software configurations in {{< regref "CONTROL" >}} prior to low power entry .
+This means the clocks and power are not always turned off, but are rather controlled by software configurations in {{#regref pwm.CONTROL }} prior to low power entry .
Once these steps are complete, the slow FSM transitions to a low power state and awaits a wake request, which can come either as an actual wakeup, or a reset event (for example always on watchdog expiration).
#### Sparse FSM
@@ -105,7 +105,7 @@
The fast clock domain FSM (referred to as fast FSM from here on) resets to `Low Power` state and waits for a power-up request from the slow FSM.
-Once received, the fast FSM releases the life cycle reset stage (see [reset controller](../rstmgr/README.md) for more details).
+Once received, the fast FSM releases the life cycle reset stage (see [reset controller]({{< relref "hw/ip/rstmgr/doc" >}}) for more details).
This allows the [OTP](../otp_ctrl/README.md) to begin sensing.
Once OTP sensing completes , the life cycle controller is initialized.
The initialization of the life cycle controller puts the device into its allowed operating state (see [life cycle controller](../lc_ctrl/README.md) for more details).
@@ -117,7 +117,7 @@
The fast FSM acknowledges the slow FSM (which made the original power up request) and releases the system reset stage - this enables the processor to begin operation.
Afterwards, the fast FSM transitions to `Active` state and waits for a software low power entry request.
-A low power request is initiated by software through a combination of WFI and software low power hint in {{< regref "CONTROL" >}}.
+A low power request is initiated by software through a combination of WFI and software low power hint in {{#regref pwm.CONTROL }}.
Specifically, this means if software issues only WFI, the power manager does not treat it as a power down request.
The notion of WFI is exported from the processor.
For Ibex, this is currently in the form of `core_sleeping_o`.
@@ -353,12 +353,12 @@
## Programmer Sequence for Entering Low Power
1. Disable interrupts
-2. Enable desired wakeup and reset sources in {{< regref "WAKEUP_EN" >}} and {{< regref "RESET_EN" >}}.
+2. Enable desired wakeup and reset sources in {{#regref pwm.WAKEUP_EN }} and {{#regref pwm.RESET_EN }}.
3. Perform any system-specific low power entry steps, e.g.
- Interrupt checks (if something became pending prior to disable)
-4. Configure low power mode in {{< regref "CONTROL" >}}.
-5. Set low power hint in {{< regref "LOW_POWER_HINT" >}}.
-6. Set and poll {{< regref "CFG_CDC_SYNC" >}} to ensure above settings propagate across clock domains.
+4. Configure low power mode in {{#regref pwm.CONTROL }}.
+5. Set low power hint in {{#regref pwm.LOW_POWER_HINT }}.
+6. Set and poll {{#regref pwm.CFG_CDC_SYNC }} to ensure above settings propagate across clock domains.
7. Execute wait-for-interrupt instruction on the processing host.
### Possible Exits
@@ -384,10 +384,10 @@
1. Complete normal preparation steps.
2. Check reset cause in [rstmgr](../rstmgr/README.md)
3. Re-enable modules that have powered down.
-4. Disable wakeup recording through {{< regref "WAKE_INFO_CAPTURE_DIS" >}}.
-5. Check which source woke up the system through {{< regref "WAKE_INFO" >}}.
+4. Disable wakeup recording through {{#regref pwm.WAKE_INFO_CAPTURE_DIS }}.
+5. Check which source woke up the system through {{#regref pwm.WAKE_INFO }}.
6. Take appropriate steps to handle the wake and resume normal operation.
-7. Once wake is handled, clear the wake indication in {{< regref "WAKE_INFO" >}}.
+7. Once wake is handled, clear the wake indication in {{#regref pwm.WAKE_INFO }}.
### Exiting from Normal Sleep
@@ -395,11 +395,11 @@
Since in these scenarios the system was not reset, software continues executing the instruction after the wait-for-interrupt invocation.
1. Check exit condition to determine appropriate steps.
-2. Clear low power hints and configuration in {{< regref "CONTROL" >}}.
-3. Set and poll {{< regref "CFG_CDC_SYNC" >}} to ensure setting changes have propagated across clock boundaries.
+2. Clear low power hints and configuration in {{#regref pwm.CONTROL }}.
+3. Set and poll {{#regref pwm.CFG_CDC_SYNC }} to ensure setting changes have propagated across clock boundaries.
4. Disable wakeup sources and stop recording.
5. Re-enable interrupts for normal operation and wakeup handling.
-6. Once wake is handled, clear the wake indication in {{< regref "WAKE_INFO" >}}.
+6. Once wake is handled, clear the wake indication in {{#regref pwm.WAKE_INFO }}.
For an in-depth discussion, please see [power management programmers model](https://docs.google.com/document/d/1w86rmvylJgZVmmQ6Q1YBcCp2VFctkQT3zJ408SJMLPE/edit?usp=sharing) for additional details.
@@ -409,4 +409,4 @@
## Register Table
-{{< incGenFromIpDesc "/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson" "registers" >}}
+* [Register Table](../../top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson#registers)
diff --git a/hw/ip/rom_ctrl/README.md b/hw/ip/rom_ctrl/README.md
index ed25ac2..9b36654 100644
--- a/hw/ip/rom_ctrl/README.md
+++ b/hw/ip/rom_ctrl/README.md
@@ -145,7 +145,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/rom_ctrl.hjson" "hwcfg" >}}
+* [Interface Tables](data/rom_ctrl.hjson#interfaces)
### Parameters
@@ -222,15 +222,15 @@
Software will mostly interact with the ROM controller by fetching code or loading data from ROM.
For this, the block looks like a block of memory, accessible through a TL-UL window.
However, there are a few registers that are accessible.
-Other than the standard {{< regref "ALERT_TEST" >}} register, all are read-only.
+Other than the standard {{#regref rom_ctrl.ALERT_TEST }} register, all are read-only.
-The {{< regref "FATAL_ALERT_CAUSE" >}} register might change value during operations (if an alert is signalled), but the other registers will all have fixed values by the time any software runs.
+The {{#regref rom_ctrl.FATAL_ALERT_CAUSE }} register might change value during operations (if an alert is signalled), but the other registers will all have fixed values by the time any software runs.
-To get the computed ROM digest, software can read {{< regref "DIGEST_0" >}} through {{< regref "DIGEST_7" >}}.
+To get the computed ROM digest, software can read {{#regref rom_ctrl.DIGEST_0 }} through {{#regref rom_ctrl.DIGEST_7 }}.
The ROM also contains an expected ROM digest.
Unlike the rest of the contents of ROM, this isn't scrambled.
As such, software can't read it through the standard ROM interface (which would try to unscramble it again, resulting in rubbish data that would cause a failed ECC check).
-In case software needs access to this value, it can be read at {{< regref "EXP_DIGEST_0" >}} through {{< regref "EXP_DIGEST_7" >}}.
+In case software needs access to this value, it can be read at {{#regref rom_ctrl.EXP_DIGEST_0 }} through {{#regref rom_ctrl.EXP_DIGEST_7 }}.
## Device Interface Functions (DIFs)
@@ -238,4 +238,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/rom_ctrl.hjson" "registers" >}}
+* [Register Table](data/rom_ctrl.hjson#registers)
diff --git a/hw/ip/rstmgr/README.md b/hw/ip/rstmgr/README.md
index 095d740..c3f5d3f 100644
--- a/hw/ip/rstmgr/README.md
+++ b/hw/ip/rstmgr/README.md
@@ -108,10 +108,10 @@
The reset manager handles the reset of the core domain, and also holds relevant reset information in CSR registers, such as:
-* {{< regref "RESET_INFO" >}} indicates why the system was reset.
-* {{< regref "ALERT_INFO" >}} contains the recorded alert status prior to system reset.
+* {{#regref rstmgr.RESET_INFO }} indicates why the system was reset.
+* {{#regref rstmgr.ALERT_INFO }} contains the recorded alert status prior to system reset.
* This is useful in case the reset was triggered by an alert escalation.
-* {{< regref "CPU_INFO" >}} contains recorded CPU state prior to system reset.
+* {{#regref rstmgr.CPU_INFO }} contains recorded CPU state prior to system reset.
* This is useful in case the reset was triggered by a watchdog where the host hung on a particular bus transaction.
Additionally, the reset manager, along with the power manager, accepts requests from the system and asserts resets for the appropriate clock trees.
@@ -167,7 +167,7 @@
### Signals
-{{< incGenFromIpDesc "/hw/top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson" "hwcfg" >}}
+* [Interface Tables](../../top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson#interfaces)
## Design Details
@@ -280,7 +280,7 @@
`POR` | Cold boot, the system was reset through POR circuitry.
`LOW_POWER_EXIT` | Warm boot, the system was reset through low power exit.
`NDM RESET` | Warm boot, the system was reset through `rv_dm` non-debug-module request.
-`SW_REQ` | Warm boot, the system was reset through {{< regref "RESET_REQ" >}}.
+`SW_REQ` | Warm boot, the system was reset through {{#regref rstmgr.RESET_REQ }}.
`HW_REQ` | Warm boot, the system was reset through peripheral requests. There may be multiple such requests.
@@ -322,11 +322,11 @@
The alert information register contains the value of the alert crash dump prior to a triggered reset.
Since this information differs in length between system implementation, the alert information register only displays 32-bits at a time.
-The {{< regref "ALERT_INFO_ATTR" >}} register indicates how many 32-bit data segments must be read.
+The {{#regref rstmgr.ALERT_INFO_ATTR }} register indicates how many 32-bit data segments must be read.
-To enable alert crash dump capture, set {{< regref "ALERT_INFO_CTRL.EN" >}} to 1.
-Once the system has reset, check {{< regref "ALERT_INFO_ATTR.CNT_AVAIL" >}} for how many reads need to be done.
-Set {{< regref "ALERT_INFO_CTRL.INDEX" >}} to the desired segment, and then read the output from {{< regref "ALERT_INFO" >}}.
+To enable alert crash dump capture, set {{#regref rstmgr.ALERT_INFO_CTRL.EN }} to 1.
+Once the system has reset, check {{#regref rstmgr.ALERT_INFO_ATTR.CNT_AVAIL }} for how many reads need to be done.
+Set {{#regref rstmgr.ALERT_INFO_CTRL.INDEX }} to the desired segment, and then read the output from {{#regref rstmgr.ALERT_INFO }}.
### CPU Information
@@ -335,8 +335,8 @@
For more details on the CPU dump details, please see [crash dump](../rv_core_ibex/README.md#crash-dump-collection).
-The {{< regref "CPU_INFO_ATTR" >}} register indicates how many 32-bit data segments must be read.
-Software then simply needs to write in {{< regref "CPU_INFO_CTRL.INDEX" >}} which segment it wishes and then read out the {{< regref "CPU_INFO" >}} register.
+The {{#regref rstmgr.CPU_INFO_ATTR }} register indicates how many 32-bit data segments must be read.
+Software then simply needs to write in {{#regref rstmgr.CPU_INFO_CTRL.INDEX }} which segment it wishes and then read out the {{#regref rstmgr.CPU_INFO }} register.
# Programmers Guide
@@ -346,4 +346,4 @@
## Register Table
-{{< incGenFromIpDesc "/hw/top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson" "registers" >}}
+* [Register Table](../../top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson#registers)
diff --git a/hw/ip/rv_core_ibex/README.md b/hw/ip/rv_core_ibex/README.md
index ae07b34..dc36742 100644
--- a/hw/ip/rv_core_ibex/README.md
+++ b/hw/ip/rv_core_ibex/README.md
@@ -49,7 +49,7 @@
Each control contains two programmable regions (2 for instruction and 2 for data).
If a transaction matches multiple regions, the lowest indexed region has priority.
-For details on how to program the related registers, please see {{< regref "IBUS_ADDR_MATCHING_0" >}} and {{< regref "IBUS_REMAP_ADDR_0" >}}.
+For details on how to program the related registers, please see {{#regref rv_core_ibex.IBUS_ADDR_MATCHING_0 }} and {{#regref rv_core_ibex.IBUS_REMAP_ADDR_0 }}.
### Translation and Instruction Caching
@@ -62,19 +62,19 @@
## Random Number Generation
The wrapper has a connection to the [Entropy Distribution Network (EDN)](../edn/README.md) with a register based interface.
-The {{< regref "RND_DATA" >}} register provides 32-bits directly from the EDN.
-{{< regref "RND_STATUS.RND_DATA_VALID" >}} indicates if the data in {{< regref "RND_DATA" >}} is valid or not.
+The {{#regref rv_core_ibex.RND_DATA }} register provides 32-bits directly from the EDN.
+{{#regref rv_core_ibex.RND_STATUS.RND_DATA_VALID}} indicates if the data in {{#regref rv_core_ibex.RND_DATA }} is valid or not.
A polling style interface is used to get new random data.
-Any read to {{< regref "RND_DATA" >}} when it is valid invalidates the data and triggers an EDN request for new data.
-Software should poll {{< regref "RND_STATUS.RND_DATA_VALID" >}} until it is valid and then read from {{< regref "RND_DATA" >}} to get the new random data.
+Any read to {{#regref rv_core_ibex.RND_DATA }} when it is valid invalidates the data and triggers an EDN request for new data.
+Software should poll {{#regref rv_core_ibex.RND_STATUS.RND_DATA_VALID }} until it is valid and then read from {{#regref rv_core_ibex.RND_DATA }} to get the new random data.
Either the data is valid or a request for new data is pending.
It is not possible to have a state where there is no valid data without new data being requested.
-Upon reset {{< regref "RND_DATA" >}} is invalid.
+Upon reset {{#regref rv_core_ibex.RND_DATA }} is invalid.
A request is made to the EDN immediately out of reset, this will not be answered until the EDN is enabled.
Software should take care not to enable the EDN until the entropy complex configuration is as desired.
-When the entropy complex configuration is changed reading {{< regref "RND_DATA" >}} when it is valid will suffice to flush any old random data to trigger a new request under the new configuration.
-If a EDN request is pending when the entropy complex configuration is changed ({{< regref "RND_STATUS.RND_DATA_VALID" >}} is clear), it is advisable to wait until it is complete and then flush out the data to ensure the fresh value was produced under the new configuration.
+When the entropy complex configuration is changed reading {{#regref rv_core_ibex.RND_DATA }} when it is valid will suffice to flush any old random data to trigger a new request under the new configuration.
+If a EDN request is pending when the entropy complex configuration is changed ({{#regref rv_core_ibex.RND_STATUS.RND_DATA_VALID }} is clear), it is advisable to wait until it is complete and then flush out the data to ensure the fresh value was produced under the new configuration.
## Crash Dump Collection
@@ -136,7 +136,7 @@
### Signals
-{{< incGenFromIpDesc "../data/rv_core_ibex.hjson" "hwcfg" >}}
+* [Interface Tables](data/rv_core_ibex.hjson#interfaces)
All ports and parameters of Ibex are exposed through this wrapper module, except for the instruction and data memory interfaces (signals starting with `instr_` and `data_`).
Refer to the [Ibex documentation](https://ibex-core.readthedocs.io/en/latest/02_user/integration.html) for a detailed description of these signals and parameters.
@@ -192,4 +192,4 @@
A number of memory-mapped registers are available to control Ibex-related functionality that's specific to OpenTitan.
-{{< incGenFromIpDesc "../data/rv_core_ibex.hjson" "registers" >}}
+* [Register Table](data/rv_core_ibex.hjson#registers)
diff --git a/hw/ip/rv_dm/README.md b/hw/ip/rv_dm/README.md
index 609052b..6240045 100644
--- a/hw/ip/rv_dm/README.md
+++ b/hw/ip/rv_dm/README.md
@@ -51,7 +51,7 @@
### Signals
-{{< incGenFromIpDesc "../data/rv_dm.hjson" "hwcfg" >}}
+* [Interface Tables](data/rv_dm.hjson#interfaces)
### Life Cycle Control
@@ -131,4 +131,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/rv_dm.hjson" "registers" >}}
+* [Register Table](data/rv_dm.hjson#registers)
diff --git a/hw/ip/rv_timer/README.md b/hw/ip/rv_timer/README.md
index e4d356e..3dd4ca0 100644
--- a/hw/ip/rv_timer/README.md
+++ b/hw/ip/rv_timer/README.md
@@ -41,13 +41,13 @@
The timer module is composed of tick generators, counters, and comparators.
A tick generator creates a tick every time its internal counter hits the
-{{< regref "CFG0.prescaler" >}} value. The tick is used to increment `mtime` by the {{< regref "CFG0.step" >}}
+{{#regref spi_device.CFG0.prescaler }} value. The tick is used to increment `mtime` by the {{#regref spi_device.CFG0.step }}
value. The 64-bit `mtime` value is compared with the 64-bit `mtimecmp`. If
`mtime` is greater than or equal to `mtimecmp`, the timer raises an interrupt.
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/rv_timer.hjson" "hwcfg" >}}
+* [Interface Tables](data/rv_timer.hjson#interfaces)
## Design Details
@@ -57,13 +57,13 @@
signal. This allows creation of a call-clock timer tick such as 1us or 10us
regardless of the system clock period. It is useful if the system has more than
one clock as a clock source. The firmware just needs to adjust the
-{{< regref "CFG0.prescaler" >}} value and the actual timer interrupt handling routine does not
+{{#regref spi_device.CFG0.prescaler }} value and the actual timer interrupt handling routine does not
need a variable clock period to update `mtimecmp`.
For instance, if a system switches between 48MHz and 200MHz clocks, a prescaler
value of **47** for 48MHz and **199** for 200MHz will generate a 1us tick.
In this version, the timer only supports a single fixed clock, so the firmware
-should change {{< regref "CFG0.prescaler" >}} appropriately.
+should change {{#regref spi_device.CFG0.prescaler }} appropriately.
### Configurable number of timers and harts
@@ -234,9 +234,9 @@
If `mtime` is greater than or equal to the value of `mtimecmp`, the interrupt is generated from the RV_TIMER module.
If the core enables the timer interrupt in `MIE` CSR, it jumps into the timer interrupt service routine.
-Clearing the interrupt can be done by writing 1 into the Interrupt Status register {{<regref "INTR_STATE0">}}.
+Clearing the interrupt can be done by writing 1 into the Interrupt Status register {{#regref spi_device.INTR_STATE0 }}.
The RV_TIMER module also follows RISC-V Privileged spec that requires the interrupt to be cleared by updating `mtimecmp` memory-mapped CSRs.
-In this case both {{<regref "COMPARE_LOWER0_0">}} and {{<regref "COMPARE_UPPER0_0">}} can clear the interrupt source.
+In this case both {{#regref spi_device.COMPARE_LOWER0_0 }} and {{#regref spi_device.COMPARE_UPPER0_0 }} can clear the interrupt source.
## Device Interface Functions (DIFs)
@@ -244,4 +244,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/rv_timer.hjson" "registers" >}}
+* [Register Table](data/rv_timer.hjson#registers)
diff --git a/hw/ip/spi_device/README.md b/hw/ip/spi_device/README.md
index 2aad706..a1895a6 100644
--- a/hw/ip/spi_device/README.md
+++ b/hw/ip/spi_device/README.md
@@ -75,7 +75,7 @@
This version of IP does not support Dual IO, Quad IO, QPI commands.
In Passthrough mode, SPI Device receives SPI transactions from a host system and forwards the transactions to a downstream flash device.
-SW may filter prohibited commands by configuring 256-bit {{< regref "FILTER" >}} CSR.
+SW may filter prohibited commands by configuring 256-bit {{#regref spi_device.FILTER }} CSR.
The IP cancels ongoing transaction if the received opcode matches to the filter CSR by de-asserting CSb and gating SCK to the downstream flash device.
SW may program CSRs to change the address and/or the first 4 bytes of payload on-the-fly in Passthrough mode.
@@ -144,7 +144,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/spi_device.hjson" "hwcfg" >}}
+* [Interface Tables](data/spi_device.hjson#interfaces)
The TPM submodule requires a separate input port for CS#.
The TPM submodule and other SPI Device modes are able to be active together.
@@ -164,7 +164,7 @@
bit-serialized SDI data into a valid byte, where the data bit is valid when the
chip select signal (CSB) is 0 (active low) and SCK is at positive or negative
edge (configurable, henceforth called the "active edge"). The bit order within
-the byte is determined by {{< regref "CFG.rx_order" >}} configuration register field. After a
+the byte is determined by {{#regref spi_device.CFG.rx_order }} configuration register field. After a
byte is gathered, the interface module writes the byte data into a small FIFO
("RXFIFO") using SCK. It is read out of the FIFO and written into to the
buffer SRAM ("DP_SRAM") using the system bus clock. If RXFIFO is full, this is
@@ -173,7 +173,7 @@
The interface module also serializes data from the small transmit FIFO
("TXFIFO") and shifts it out on the SDO pin when CSB is 0 and SCK is at the
active edge. The bit order within the byte can be configured with configuration
-register field {{< regref "CFG.tx_order" >}}. It is expected that software has prepared TX data
+register field {{#regref spi_device.CFG.tx_order }}. It is expected that software has prepared TX data
based on the description in the "Defining
Firmware Operation Mode" section below. Since SCK is not under the control of
software or the device (it is driven by the external SPI host), it is possible
@@ -182,7 +182,7 @@
prepared TX data or software does not care about the contents of the TX data -
then the hardware will send whatever lingering data is in the empty TXFIFO. If
this is a functional issue, then software should at least soft-reset the contents
-of the TXFIFO using the {{< regref "CONTROL.rst_txfifo" >}} register. The soft-reset signal
+of the TXFIFO using the {{#regref spi_device.CONTROL.rst_txfifo }} register. The soft-reset signal
is not synchronized to the SCK clock, so software should drive the reset
signal when the SPI interface is idle.
@@ -316,7 +316,7 @@
RXFIFO (see details below) at appropriate size boundaries. This data is
handshake-received on the core clock side, gathered into byte or word quantity,
and written into the RX circular buffer of the dual-port SRAM. On each write,
-the RXF write pointer ({{< regref "RXF_PTR.wptr" >}}) is incremented by hardware, wrapping at
+the RXF write pointer ({{#regref spi_device.RXF_PTR.wptr }}) is incremented by hardware, wrapping at
the size of the circular buffer. Software can watch (via polling or interrupts)
the incrementing of this write pointer to determine how much valid data has been
received, and determine when and what data to act upon. Once it has acted upon
@@ -329,7 +329,7 @@
normally only write to the 32-bit wide SRAM when an entire word can be written.
Since the end of the received data may not be aligned, there is a timer that
forces sub-word writes if data has been staged for too long. The timer value
-({{< regref "CFG.timer_v" >}}) represents the number of core clock cycles. For instance, if
+({{#regref spi_device.CFG.timer_v }}) represents the number of core clock cycles. For instance, if
timer value is configured in 0xFF, the RXF control logic will write gathered
sub-word data in 255 cycles if no further bit stream from SPI is received.
@@ -368,7 +368,7 @@
The SW may configure the map from the received opcode to the command process module by programming *cmd_info* list.
Current SPI_DEVICE provides 24 command information entries.
Each entry represents a command.
-Details of the fields are explained in the {{<regref "CMD_INFO_0">}}
+Details of the fields are explained in the {{#regref spi_device.CMD_INFO_0 }}
First 11 commands are assigned to specific submodules.
@@ -379,7 +379,7 @@
[4] | Read SFDP
[10:5] | Read commands
-If the IP is in flash mode or in passthrough mode with {{<regref "INTERCEPT_EN">}} set, other than *opcode* and *valid* fields in the command information entries are ignored for Read Status and Read JEDEC ID commands.
+If the IP is in flash mode or in passthrough mode with {{#regref spi_device.INTERCEPT_EN }} set, other than *opcode* and *valid* fields in the command information entries are ignored for Read Status and Read JEDEC ID commands.
The submodules directly return data on the MISO line (SD[1]).
In Passthrough mode, if Read Status and Read JEDEC ID commands are intercepted by the internal HW, the other fields in the command information entries are ignored also.
@@ -400,7 +400,7 @@
As explained in the [previous section](#command-information-list), the command parser checks the index to activate Read Status / Read JEDEC ID/ Read Command / Address 4B modules.
Other than the first 11 slots and last two slots (the last two slots are not visible to SW), the cmdparse checks the *upload* field and activates the upload module if the field is set.
-SW can configure whether a submodule should process the command while in the passthrough mode by setting the {{<regref "INTERCEPT_EN">}} CSR.
+SW can configure whether a submodule should process the command while in the passthrough mode by setting the {{#regref spi_device.INTERCEPT_EN }} CSR.
### Status Control
@@ -420,13 +420,13 @@
WEL bit can be controlled by SW and also by HW.
HW updates WEL bit when it receives WREN(06h) or WRDI(04h) commands.
-The opcode can be configured via {{<regref "CMD_INFO_WREN">}} and {{<regref "CMD_INFO_WRDI">}}.
+The opcode can be configured via {{#regref spi_device.CMD_INFO_WREN }} and {{#regref spi_device.CMD_INFO_WRDI }}.
-The SW update of the STATUS register via {{<regref "FLASH_STATUS">}} is not instantaneous.
+The SW update of the STATUS register via {{#regref spi_device.FLASH_STATUS }} is not instantaneous.
The IP stores the SW request into the asynchronous FIFO then the request is processed in the SPI clock domain.
The request updates the temporal status register, which is called as staged registers in the design.
The staged registers are latched into the committed registers when CSb is released.
-SW sees the committed registers when reading the {{<regref "FLASH_STATUS">}} CSR.
+SW sees the committed registers when reading the {{#regref spi_device.FLASH_STATUS }} CSR.
The attached host system also reads back the committed registers via Read Status commands.
This scheme is to guarantee the atomicity of the STATUS register.
@@ -437,8 +437,8 @@
### JEDEC ID Control
JEDEC module returns JEDEC Device ID and Manufacturer ID following the Continuation Code (CC).
-SW may configure {{<regref "JEDEC_CC">}} CSR for HW to return proper CC.
-The *cc* field in {{<regref "JEDEC_CC">}} defines the return value, which is `0x7F` by default.
+SW may configure {{#regref spi_device.JEDEC_CC }} CSR for HW to return proper CC.
+The *cc* field in {{#regref spi_device.JEDEC_CC }} defines the return value, which is `0x7F` by default.
*num_cc* defines how many times the HW to send CC byte before sending the JEDEC ID.
The actual JEDEC ID consists of one byte manufacturer ID and two bytes device ID.
@@ -496,7 +496,7 @@
SW is responsible for updating the read buffer contents.
The HW notifies the SW to update the buffer contents when needed.
-The HW provides a SW configurable read watermark CSR and read-only {{<regref "LAST_READ_ADDR">}} CSR.
+The HW provides a SW configurable read watermark CSR and read-only {{#regref spi_device.LAST_READ_ADDR }} CSR.
The **LAST_READ_ADDR** shows the last read address of the recent read command.
For instance, if the host system issues `0xABCD_E000` and reads 128 (or 0x80) bytes, the **LAST_READ_ADDR** after the transaction will show `0xABCD_E07F`.
It does not show the commands falling into the mailbox region or Read SFDP command's address.
@@ -513,14 +513,14 @@
### 4B Address Management (EN4B/ EX4B)
SW may configure the HW to receive EN4B and EX4B commands and change the read command address size between 3 bytes and 4 bytes.
-For the IP to recognize EN4B/ EX4B commands, SW should configure {{<regref "CMD_INFO_EN4B">}} and {{<regref "CMD_INFO_EX4B">}}.
+For the IP to recognize EN4B/ EX4B commands, SW should configure {{#regref spi_device.CMD_INFO_EN4B }} and {{#regref spi_device.CMD_INFO_EX4B }}.
The two CSRs omit unnecessary fields from the **CMD_INFO** data structure.
The HW logic creates the default **CMD_INFO** structures for the two commands.
The command parser module uses the generated structures to process and trigger the 4B management module.
When the HW receives one of the commands, the HW changes the broadcast signal *cfg_addr_4b_en*.
-Also the HW updates {{<regref "CFG.addr_4b_en">}} after passing through CDC.
+Also the HW updates {{#regref spi_device.CFG.addr_4b_en }} after passing through CDC.
It takes at most three SYS_CLK cycles to update the value in the *CFG* register after the completion of the SPI transaction (CSb de-assertion).
_Note: The HW changes the broadcasting signal and the CSR even though the SPI host system sends more than 8 beats of the SPI S[0].
@@ -542,9 +542,9 @@
If `busy` field in the command information entry is set, the upload module also sets *BUSY* bit in the *STATUS* register.
SW may clear the *BUSY* bit after processing the command.
-The upload module provides {{<regref "UPLOAD_STATUS">}} and {{<regref "UPLOAD_STATUS2">}} CSRs for SW to parse the command, address, and payload.
+The upload module provides {{#regref spi_device.UPLOAD_STATUS }} and {{#regref spi_device.UPLOAD_STATUS2 }} CSRs for SW to parse the command, address, and payload.
If a received command has payload, SW may read the payload from the Payload buffer starting from `payload_start_idx` address.
-In normal case, `payload_start_idx` in {{<regref "UPLOAD_STATUS2">}} shows **0**.
+In normal case, `payload_start_idx` in {{#regref spi_device.UPLOAD_STATUS2 }} shows **0**.
In error case of the host sending more than the maximum allowed payload size (256B in the current version), the `payload_start_idx` may not be 0.
It is expected that the `payload_depth` is maximum payload size, 256B if `payload_start_idx` is non-zero.
In this scenario, SW should read from `payload_start_idx` to the end of the payload buffer then do a second read from the beginning of the buffer to the remained bytes.
@@ -584,9 +584,9 @@
}
{{</wavejson>}}
-The passthrough logic filters the command based on the 256 bit of {{<regref "CMD_FILTER_0">}} CSR.
+The passthrough logic filters the command based on the 256 bit of {{#regref spi_device.CMD_FILTER_0 }} CSR.
Each bit corresponds to each opcode.
-For example, if bit 5 of {{<regref "CMD_FILTER_0">}} is set, the passthrough drops **CSb** when it receives `05h` SPI command.
+For example, if bit 5 of {{#regref spi_device.CMD_FILTER_0 }} is set, the passthrough drops **CSb** when it receives `05h` SPI command.
The SW does not know whether a SPI transaction is filtered or not.
If the SW wants to check, it needs to set the _upload_ field with the opcode in the command information list.
@@ -594,18 +594,18 @@
#### Address Manipulation
-SW may configure the passthrough logic to swap certain address bits to desired values by configuring {{<regref "ADDR_SWAP_MASK">}} and {{<regref "ADDR_SWAP_DATA">}} CSRs.
+SW may configure the passthrough logic to swap certain address bits to desired values by configuring {{#regref spi_device.ADDR_SWAP_MASK }} and {{#regref spi_device.ADDR_SWAP_DATA }} CSRs.
The address translation takes in effect only when the received command is in the command information list and *addr_swap_en* field in the entry is set.
-For instance, the passthrough logic sets bit 20 of the address to 1 if {{<regref "ADDR_SWAP_MASK">}} is `0x0010_0000` and {{<regref "ADDR_SWAP_DATA">}} is `0x0010_0000`.
+For instance, the passthrough logic sets bit 20 of the address to 1 if {{#regref spi_device.ADDR_SWAP_MASK }} is `0x0010_0000` and {{#regref spi_device.ADDR_SWAP_DATA }} is `0x0010_0000`.
#### Write Status Data Manipulation
The passthrough logic also provides a way to change the first 4 bytes of the payload to the downstream SPI flash device on-the-fly as same as the address.
The main use of this feature is to protect the Status register.
-SW may configure the {{<regref "PAYLOAD_SWAP_MASK">}} and {{<regref "PAYLOAD_SWAP_DATA">}} CSRs to change the specific bit of the first 4 byte of the write payload.
-For example, {{<regref "PAYLOAD_SWAP_MASK">}} as `32'h 0000_0023` and {{<regref "PAYLOAD_SWAP_DATA">}} as `32'h 0000_0022` change bit 0 to 0, bit 1 to 1, bit 5 to 1 in the first byte payload.
+SW may configure the {{#regref spi_device.PAYLOAD_SWAP_MASK }} and {{#regref spi_device.PAYLOAD_SWAP_DATA }} CSRs to change the specific bit of the first 4 byte of the write payload.
+For example, {{#regref spi_device.PAYLOAD_SWAP_MASK }} as `32'h 0000_0023` and {{#regref spi_device.PAYLOAD_SWAP_DATA }} as `32'h 0000_0022` change bit 0 to 0, bit 1 to 1, bit 5 to 1 in the first byte payload.
The CSRs are Little Endian (LE)s.
The passthrough module consumes the lower byte first as SPI flash writes byte 0 first followed by byte 1.
@@ -630,9 +630,9 @@
As described in [SPI Device Modes](#spi-device-modes-and-active-submodules), SPI_DEVICE may return the data from the IP even if the passthrough mode is set.
The HW can process Read Status, Read JEDEC ID, Read SFDP, Read commands accessing the mailbox region, and EN4B/EX4B.
-SW configures {{<regref "INTERCEPT_EN">}} CSR to enable the feature.
+SW configures {{#regref spi_device.INTERCEPT_EN }} CSR to enable the feature.
SW may selectively enable/disable commands.
-For example, HW returns only Read Status data internally if {{<regref "INTERCEPT_EN">}} is `{status: 1'b 1, default: 1'b 0}`.
+For example, HW returns only Read Status data internally if {{#regref spi_device.INTERCEPT_EN }} is `{status: 1'b 1, default: 1'b 0}`.
Other than Read command accessing mailbox space, it is recommended to filter the intercepted commands.
@@ -686,7 +686,7 @@
## Clock and Phase
-The SPI device module has two programmable register bits to control the SPI clock, {{< regref "CFG.CPOL" >}} and {{< regref "CFG.CPHA" >}}.
+The SPI device module has two programmable register bits to control the SPI clock, {{#regref spi_device.CFG.CPOL }} and {{#regref spi_device.CFG.CPHA }}.
CPOL controls clock polarity and CPHA controls the clock phase.
For further details, please refer to this diagram from Wikipedia:
[File:SPI_timing_diagram2.svg](https://en.wikipedia.org/wiki/Serial_Peripheral_Interface#/media/File:SPI_timing_diagram2.svg)
@@ -698,7 +698,7 @@
As described in the Theory of Operations above, in this mode, the SPI device
writes incoming data directly into the SRAM (through RXFIFO) and updates the SPI
-device SRAM write pointer ({{< regref "RXF_PTR.wptr" >}}). It does not parse a command byte nor
+device SRAM write pointer ({{#regref spi_device.RXF_PTR.wptr }}). It does not parse a command byte nor
address bytes, analyzing incoming data relies on firmware implementation of a
higher level protocol. Data is sent from the TXF SRAM contents via TXFIFO.
@@ -754,7 +754,7 @@
}
{{< /wavejson >}}
-Note that in the SPI mode 3 configuration ({{< regref "CFG.CPOL" >}}=1, {{< regref "CFG.CPHA" >}}=1), the
+Note that in the SPI mode 3 configuration ({{#regref spi_device.CFG.CPOL }}=1, {{#regref spi_device.CFG.CPHA }}=1), the
logic isn't able to pop the entry from the TX async FIFO after the last bit
in the last byte of a transaction. In mode 3, no further SCK edge is given
after sending the last bit before the CSB de-assertion. The design is chosen to
@@ -823,18 +823,18 @@
## Initialization
-By default, RX SRAM FIFO base and limit address (via {{< regref "RXF_ADDR" >}} register) are
+By default, RX SRAM FIFO base and limit address (via {{#regref spi_device.RXF_ADDR }} register) are
set to 0x0 and 0x1FC, 512 bytes. And TX SRAM FIFO base and limit addresses (in
-the {{< regref "TXF_ADDR" >}} register) are 0x200 and 0x3FC. If FW wants bigger spaces, it can
-change the values of the above registers {{< regref "RXF_ADDR" >}} and {{< regref "TXF_ADDR" >}}.
+the {{#regref spi_device.TXF_ADDR }} register) are 0x200 and 0x3FC. If FW wants bigger spaces, it can
+change the values of the above registers {{#regref spi_device.RXF_ADDR }} and {{#regref spi_device.TXF_ADDR }}.
-Software can configure the timer value {{< regref "CFG.timer_v" >}} to change the delay between
+Software can configure the timer value {{#regref spi_device.CFG.timer_v }} to change the delay between
partial DATA received from SPI interface being written into the SRAM. The value
of the field is the number of the core clock cycles that the logic waits for.
## Pointers
-RX / TX SRAM FIFO has read and write pointers, {{< regref "RXF_PTR" >}} and {{< regref "TXF_PTR" >}} . Those
+RX / TX SRAM FIFO has read and write pointers, {{#regref spi_device.RXF_PTR }} and {{#regref spi_device.TXF_PTR }} . Those
pointers are used to manage circular FIFOs inside the SRAM. The pointer width in
the register description is 16 bit but the number of valid bits in the pointers
depends on the size of the SRAM.
@@ -877,8 +877,8 @@
The TPM protocol supports two protocol interfaces: FIFO and CRB (Command Response Buffer).
In terms of hardware design, these two interfaces differ in how return-by-HW registers are handled.
-In FIFO mode, when {{< regref "TPM_CFG.tpm_mode" >}} is set to 0, HW registers reads must be returned after a maximum of 1 wait state.
-In CRB mode, when {{< regref "TPM_CFG.tpm_mode" >}} is set to 1, there are no such restrictions.
+In FIFO mode, when {{#regref spi_device.TPM_CFG.tpm_mode }} is set to 0, HW registers reads must be returned after a maximum of 1 wait state.
+In CRB mode, when {{#regref spi_device.TPM_CFG.tpm_mode }} is set to 1, there are no such restrictions.
The logic always uploads both the command and address to the SW and waits for the return data in CRB mode.
### Return-by-HW register update
@@ -953,4 +953,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/spi_device.hjson" "registers" >}}
+* [Register Table](data/spi_device.hjson#registers)
diff --git a/hw/ip/spi_host/README.md b/hw/ip/spi_host/README.md
index 1400346..ae9a7dc 100644
--- a/hw/ip/spi_host/README.md
+++ b/hw/ip/spi_host/README.md
@@ -163,18 +163,18 @@
Issuing a command then consists of the following steps:
1. Configure the IP to be compatible with each attached peripheral.
-The {{< regref "CONFIGOPTS" >}} multi-register holds separate sets of configuration settings, one for each CSB line.
+The {{#regref spi_host.CONFIGOPTS }} multi-register holds separate sets of configuration settings, one for each CSB line.
In principle, the configuration of these device-specific options only needs to be done/performed once at initialization.
-2. Load the TX FIFO with the instructions and data to be transmitted to the remote device by writing to the {{< regref "TXDATA" >}} memory window.
-3. Specify which device should receive the next command using the {{< regref "CSID" >}} register.
-4. Wait for {{< regref "STATUS.READY" >}} before continuing.
-5. Issue speed, direction, and length details for the next command segment using the {{< regref "COMMAND" >}} register.
-If a command consists of multiple segments, then set {{< regref "COMMAND.CSAAT" >}} (Chip-select active after transaction) to one for all segments except the last one.
-Setting {{< regref "COMMAND.CSAAT" >}} to zero indicates the end of a transaction, prompting the IP to raise CSB at the end of the segment.
+2. Load the TX FIFO with the instructions and data to be transmitted to the remote device by writing to the {{#regref spi_host.TXDATA }} memory window.
+3. Specify which device should receive the next command using the {{#regref spi_host.CSID }} register.
+4. Wait for {{#regref spi_host.STATUS.READY }} before continuing.
+5. Issue speed, direction, and length details for the next command segment using the {{#regref spi_host.COMMAND }} register.
+If a command consists of multiple segments, then set {{#regref spi_host.COMMAND.CSAAT }} (Chip-select active after transaction) to one for all segments except the last one.
+Setting {{#regref spi_host.COMMAND.CSAAT }} to zero indicates the end of a transaction, prompting the IP to raise CSB at the end of the segment.
6. Repeat steps 4 and 5 until all segments have been described.
-7. Read any peripheral response data from the RX FIFO by reading from the {{< regref "RXDATA" >}} memory window.
+7. Read any peripheral response data from the RX FIFO by reading from the {{#regref spi_host.RXDATA }} memory window.
### About Command Segments
@@ -248,7 +248,7 @@
#### Specifying Command Segments
-The SPI host supports all four possible modes for command segments, and they are controlled writing one of the following values to the 2-bit {{< regref "COMMAND.DIRECTION" >}} register:
+The SPI host supports all four possible modes for command segments, and they are controlled writing one of the following values to the 2-bit {{#regref spi_host.COMMAND.DIRECTION }} register:
- 2'b00: Dummy cycles only (neither side transmits)
- 2'b01: RX Only
- 2'b10: TX Only
@@ -256,30 +256,30 @@
### CSID Register
-The {{< regref "CSID" >}} register is used to identify the target device for the next command segment.
-Whenever a command segment descriptor is written to {{< regref "COMMAND" >}}, {{< regref "CSID" >}} is passed into the FSM along with the command segment descriptor and the corresponding configurations options (taken from the CSID'th element of the `CONFIGOPTS` multi-register).
+The {{#regref spi_host.CSID }} register is used to identify the target device for the next command segment.
+Whenever a command segment descriptor is written to {{#regref spi_host.COMMAND }}, {{#regref spi_host.CSID }} is passed into the FSM along with the command segment descriptor and the corresponding configurations options (taken from the CSID'th element of the `CONFIGOPTS` multi-register).
This register still exists when instantiated with only one CSB line (i.e. when NumCS=1).
-However in this case the {{< regref "CSID" >}} value is ignored.
+However in this case the {{#regref spi_host.CSID }} value is ignored.
-Changes in {{< regref "CSID" >}} also affect the CSB lines, because a change in CSID can also implicitly end a command, overriding {{< regref "COMMAND.CSAAT" >}}.
-If a change is detected in {{< regref "CSID" >}}, but the previous segment was submitted with the `CSAAT` bit asserted, the FSM terminates the previous command before moving on to the next segment.
-The previous CSB line is held low for *at least* `CSNTRAIL` cycles (as defined by the previous value of {{< regref "CONFIGOPTS.CSNTRAIL" >}}) and then brought high.
-All CSB lines are held high for `CSNIDLE` cycles (using the new value of {{< regref "CONFIGOPTS.CSNIDLE" >}}).
+Changes in {{#regref spi_host.CSID }} also affect the CSB lines, because a change in CSID can also implicitly end a command, overriding {{#regref spi_host.COMMAND.CSAAT }}.
+If a change is detected in {{#regref spi_host.CSID }}, but the previous segment was submitted with the `CSAAT` bit asserted, the FSM terminates the previous command before moving on to the next segment.
+The previous CSB line is held low for *at least* `CSNTRAIL` cycles (as defined by the previous value of {{#regref spi_host.CONFIGOPTS.CSNTRAIL }}) and then brought high.
+All CSB lines are held high for `CSNIDLE` cycles (using the new value of {{#regref spi_host.CONFIGOPTS.CSNIDLE }}).
The new CSB line is asserted low, and SCK begins toggling after the usual `CSNLEAD` cycle delay.
### Configuration Options
-The {{< regref "CONFIGOPTS" >}} multi-register has one entry per CSB line and holds clock configuration and timing settings which are specific to each peripheral.
-Once the {{< regref "CONFIGOPTS" >}} multi-register has been programmed for each SPI peripheral device, the values can be left unchanged.
+The {{#regref spi_host.CONFIGOPTS }} multi-register has one entry per CSB line and holds clock configuration and timing settings which are specific to each peripheral.
+Once the {{#regref spi_host.CONFIGOPTS }} multi-register has been programmed for each SPI peripheral device, the values can be left unchanged.
The following sections give details on how the SPI_HOST can be used to control a specific peripheral.
-For simplicity, this section describes how to interact one device, attached to CSB[0], and as such references are made to the multi-registers {{< regref "CONFIGOPTS" >}} and {{< regref "COMMAND" >}}.
+For simplicity, this section describes how to interact one device, attached to CSB[0], and as such references are made to the multi-registers {{#regref spi_host.CONFIGOPTS }} and {{#regref spi_host.COMMAND }}.
To configure timing and send commands to devices on other CSB lines, instead use the `CONFIGOPTS` multi-register corresponding to desired CSB line.
The most common differences between target devices are the requirements for a specific SPI clock phase or polarity, CPOL and CPHA, which were described in the previous section [SPI Protocol Basics](#spi-protocol-basics).
-These clock parameters can be set via the {{< regref "CONFIGOPTS.CPOL">}} or {{< regref "CONFIGOPTS.CPHA" >}} register fields.
-Likewise, as also described in the previous section, if device setup times require a full clock cycle before sampling the output, Full-Cycle Mode can be enabled by asserting the {{< regref "CONFIGOPTS.FULLCYC" >}} bit.
+These clock parameters can be set via the {{#regref spi_host.CONFIGOPTS.CPOL }} or {{#regref spi_host.CONFIGOPTS.CPHA }} register fields.
+Likewise, as also described in the previous section, if device setup times require a full clock cycle before sampling the output, Full-Cycle Mode can be enabled by asserting the {{#regref spi_host.CONFIGOPTS.FULLCYC }} bit.
#### Clock rate selection
@@ -297,11 +297,11 @@
#### Chip-select Timing Control
Typically the CSB line is automatically deasserted after the last edge of SCK.
-However, by asserting {{< regref "COMMAND.CSAAT" >}} when issuing a particular command, one can instruct the core to hold CSB low indefinitely after the last clock edge.
+However, by asserting {{#regref spi_host.COMMAND.CSAAT }} when issuing a particular command, one can instruct the core to hold CSB low indefinitely after the last clock edge.
This is useful for merging two adjacent command segments together, to create more complex commands, such as flash Quad read commands which require a mix of segments with different speeds and directions.
-The CSB line can then be deasserted by either issuing another command without the {{< regref "COMMAND.CSAAT" >}} field, issuing a command to a different device (after changing the {{< regref "CSID" >}} register), or simply resetting the core FSM via the {{< regref "CONTROL.RST" >}} register.
+The CSB line can then be deasserted by either issuing another command without the {{#regref spi_host.COMMAND.CSAAT }} field, issuing a command to a different device (after changing the {{#regref spi_host.CSID }} register), or simply resetting the core FSM via the {{#regref spi_host.CONTROL.RST }} register.
-To avoid spurious clock signals, changes to the {{< regref "CONFIGOPTS" >}} parameters take effect only at the end of a command segment and only when all `csb` lines are deasserted.
+To avoid spurious clock signals, changes to the {{#regref spi_host.CONFIGOPTS }} parameters take effect only at the end of a command segment and only when all `csb` lines are deasserted.
There are two cases to consider:
1. Configuration changes detected and CSAAT=0 for the previous segment:
This is when configuration changes are typically expected, and in this case, the SPI_HOST waits for the previous segment to complete before moving changing the configuration.
@@ -315,11 +315,11 @@
However, some devices may require more timing margin and so the SPI_HOST core offers some configuration registers for controlling the timing of the CSB edges when operating under automatic control.
The relevant parameters are as follows:
- T<sub>IDLE</sub>: The minimum time between each rising edge of CSB and the following falling edge.
-This time delay is a half SCK cycle by default but can be extended to as long as eight SCK cycles by setting the {{< regref "CONFIGOPTS.CSNIDLE">}} register.
+This time delay is a half SCK cycle by default but can be extended to as long as eight SCK cycles by setting the {{#regref spi_host.CONFIGOPTS.CSNIDLE }} register.
- T<sub>LEAD</sub>: The minimum time between each falling edge of CSB and the first leading edge of SCK.
-This time delay is a half SCK cycle by default but can be extended to as long as eight SCK cycles by setting the {{< regref "CONFIGOPTS.CSNLEAD">}} register.
+This time delay is a half SCK cycle by default but can be extended to as long as eight SCK cycles by setting the {{#regref spi_host.CONFIGOPTS.CSNLEAD }} register.
- T<sub>TRAIL</sub>: The minimum time between the last trailing edge of SCK and the following rising edge of CSB.
-This time delay is a half SCK cycle by default but can be extended to as long as eight SCK cycles by setting the {{< regref "CONFIGOPTS.CSNTRAIL">}} register.
+This time delay is a half SCK cycle by default but can be extended to as long as eight SCK cycles by setting the {{#regref spi_host.CONFIGOPTS.CSNTRAIL }} register.
{{< wavejson >}}
{signal: [
@@ -350,7 +350,7 @@
Furthermore, `csb` should be remain high for the minimum idle time both before and after the configuration update.
For example, consider a SPI_HOST attached to two devices each with different requirements for the clock divider, clock polarity, and idle time.
-Consider a configuration where total idle time (as determined by the {{< regref "CONFIGOPTS.CLKDIV" >}} and {{< regref "CONFIGOPTS.CSNIDLE" >}} multi-registers) works out to 9 idle clocks for the first device, and 4 clocks for the second device.
+Consider a configuration where total idle time (as determined by the {{#regref spi_host.CONFIGOPTS.CLKDIV }} and {{#regref spi_host.CONFIGOPTS.CSNIDLE }} multi-registers) works out to 9 idle clocks for the first device, and 4 clocks for the second device.
In this scenario then, when swapping from the first device to the second, the SPI_HOST IP will only swap the clock polarity once the first `csb` line, `csb[0]`, has been high for at least 9 clocks, and will continue to hold the second `csb` line, `csb[1]`, high for 4 additional clocks before starting the next transaction.
{{< wavejson >}}
@@ -382,23 +382,23 @@
{{< /wavejson >}}
This additional idle time applies not only when switching between devices but when making any changes to the configuration for most recently used device.
-For instance, even in a SPI_HOST configured for one device, changes to {{< regref "CONFIGOPTS" >}}, will trigger this extended idle time behavior to ensure that the change in configuration only occurs in the middle of a long idle period.
+For instance, even in a SPI_HOST configured for one device, changes to {{#regref spi_host.CONFIGOPTS }}, will trigger this extended idle time behavior to ensure that the change in configuration only occurs in the middle of a long idle period.
### Special Command Fields
-The {{< regref "COMMAND" >}} register must be written once for each command segment.
-Whenever a command segment is written to {{< regref "COMMAND" >}}, the contents of the {{< regref "CONFIGOPTS" >}}, {{< regref "CSID" >}}, and {{< regref "COMMAND" >}} registers are passed through the Config/Command FIFO to the SPI_HOST core FSM.
-Once the command is issued, the core will immediately deassert {{< regref "STATUS.READY" >}}, and once the command has started {{< regref "STATUS.ACTIVE" >}} will go high.
-The command is complete when {{< regref "STATUS.ACTIVE" >}} goes low.
-A `spi_event` interrupt can also be triggered to go off on completion by setting {{< regref "EVENT_ENABLE.IDLE" >}}.
+The {{#regref spi_host.COMMAND }} register must be written once for each command segment.
+Whenever a command segment is written to {{#regref spi_host.COMMAND }}, the contents of the {{#regref spi_host.CONFIGOPTS }}, {{#regref spi_host.CSID }}, and {{#regref spi_host.COMMAND }} registers are passed through the Config/Command FIFO to the SPI_HOST core FSM.
+Once the command is issued, the core will immediately deassert {{#regref spi_host.STATUS.READY }}, and once the command has started {{#regref spi_host.STATUS.ACTIVE }} will go high.
+The command is complete when {{#regref spi_host.STATUS.ACTIVE }} goes low.
+A `spi_event` interrupt can also be triggered to go off on completion by setting {{#regref spi_host.EVENT_ENABLE.IDLE }}.
### Chip Select Masks
Each instance of the SPI_HOST IP supports a parametrizable number of chip select lines (CSB[NumCS-1:0]).
Each CSB line can be routed either to a single peripheral or to a daisy-chain of peripherals.
-Whenever a segment description is written to the {{< regref "COMMAND">}} register, the {{< regref "CSID" >}} is sent along with {{< regref "COMMAND" >}} and the `CONFIGOPTS` multi-register corresponding to {{< regref "CSID" >}} to indicate which device is meant to receive the command.
-The SPI_HOST core typically then manages the details of asserting and deasserting the proper CSB line, subject to the timing parameters expressed in {{< regref "CONFIGOPTS.CSNLEAD" >}}, {{< regref "CONFIGOPTS.CSNTRAIL" >}}, and {{< regref "CONFIGOPTS.CSNIDLE" >}}.
+Whenever a segment description is written to the {{#regref spi_host.COMMAND }} register, the {{#regref spi_host.CSID }} is sent along with {{#regref spi_host.COMMAND }} and the `CONFIGOPTS` multi-register corresponding to {{#regref spi_host.CSID }} to indicate which device is meant to receive the command.
+The SPI_HOST core typically then manages the details of asserting and deasserting the proper CSB line, subject to the timing parameters expressed in {{#regref spi_host.CONFIGOPTS.CSNLEAD }}, {{#regref spi_host.CONFIGOPTS.CSNTRAIL }}, and {{#regref spi_host.CONFIGOPTS.CSNIDLE }}.
If [Pass-through mode](#pass-through-mode) is enabled then the CSB lines are controlled by *neither* the SPI_HOST hardware nor the firmware register.
In Pass-though mode, control of the CSB lines passes directly to the inter-module port, `passthrough_i.csb`.
@@ -409,8 +409,8 @@
Since most SPI Flash transactions typically consist of 3 or 4 segments, there is a small command FIFO for submitting segments to the SPI_HOST IP, so that firmware can issue the entire transaction at one time.
-Writing a segment description to {{< regref "COMMAND" >}} when {{< regref "STATUS.READY" >}} is low will trigger an error condition, which must be acknowledged by software.
-When submitting multiple segments to the the command queue, firmware can also check the {{< regref "STATUS.CMDQD" >}} register to determine how many unprocessed segments are in the FIFO.
+Writing a segment description to {{#regref spi_host.COMMAND }} when {{#regref spi_host.STATUS.READY }} is low will trigger an error condition, which must be acknowledged by software.
+When submitting multiple segments to the the command queue, firmware can also check the {{#regref spi_host.STATUS.CMDQD }} register to determine how many unprocessed segments are in the FIFO.
## Data Formatting
@@ -424,23 +424,23 @@
The programming model for the IP should meanwhile make it easy to quickly program the peripheral device, with a minimum amount of byte shuffling.
It should be intuitive to program the specific flash devices we are targeting, while following the conventions above:
-- When transferring data in from the {{< regref "RXDATA" >}} memory window or out to the {{< regref "TXDATA" >}} window, the IP should fully utilize the TL-UL bus, using 32-bit I/O instructions.
+- When transferring data in from the {{#regref spi_host.RXDATA }} memory window or out to the {{#regref spi_host.TXDATA }} window, the IP should fully utilize the TL-UL bus, using 32-bit I/O instructions.
- The SPI_HOST should make it easy to arrange transaction data in processor memory, meaning that bytes should be sequentially transmitted in order of ascending memory address.
- When using 32-bit I/O instructions, this requires some knowledge of the processor byte-order.
-Based on these requirements, data read from {{< regref "RXDATA" >}} or placed in {{< regref "TXDATA" >}} are handled as follows:
-- 32-bit words placed in {{< regref "TXDATA" >}} are transmitted in first-in-first-out order.
-Likewise, words received from the SPI data lines are made available for reading from {{< regref "RXDATA" >}} in first-in-first-out order.
-- Within a 32-bit word, the `ByteOrder` parameter controls the order in which bytes are transmitted, and also the manner in which received bytes are eventually arranged in the 32-bit {{< regref "RXDATA" >}} register.
-By default (`ByteOrder` = 1, for Little-Endian processors), the LSB of {{< regref "TXDATA" >}} (i.e bits 7 though 0) is transmitted first, and the other bytes follow in order of increasing significance.
-Similarly, the first byte received is packed into the LSB of {{< regref "RXDATA" >}}, and the subsequent bytes of each {{< regref "RXDATA" >}} word are packed in order of increasing significance.
+Based on these requirements, data read from {{#regref spi_host.RXDATA }} or placed in {{#regref spi_host.TXDATA }} are handled as follows:
+- 32-bit words placed in {{#regref spi_host.TXDATA }} are transmitted in first-in-first-out order.
+Likewise, words received from the SPI data lines are made available for reading from {{#regref spi_host.RXDATA }} in first-in-first-out order.
+- Within a 32-bit word, the `ByteOrder` parameter controls the order in which bytes are transmitted, and also the manner in which received bytes are eventually arranged in the 32-bit {{#regref spi_host.RXDATA }} register.
+By default (`ByteOrder` = 1, for Little-Endian processors), the LSB of {{#regref spi_host.TXDATA }} (i.e bits 7 though 0) is transmitted first, and the other bytes follow in order of increasing significance.
+Similarly, the first byte received is packed into the LSB of {{#regref spi_host.RXDATA }}, and the subsequent bytes of each {{#regref spi_host.RXDATA }} word are packed in order of increasing significance.
-On the other hand, if `ByteOrder` is set to 0 (for Big-Endian processors), the MSB is transmitted first from {{< regref "TXDATA" >}}, and received data is loaded first into the MSB of {{< regref "RXDATA" >}}.
+On the other hand, if `ByteOrder` is set to 0 (for Big-Endian processors), the MSB is transmitted first from {{#regref spi_host.TXDATA }}, and received data is loaded first into the MSB of {{#regref spi_host.RXDATA }}.
- The default choice of Little-Endian reflects native byte-order of the Ibex processor.
- Finally *within a given byte*, the most significant bits are transmitted and received first.
For Dual and Quad transactions the least significant bit in any instantaneous pair or nibble is transmitted or received on SD[0], and the remaining SD bits (1 though 3) are populated in order of increasing significance.
-The following figure shows how data appears on the serial data bus when the hardware reads it from {{< regref "TXDATA" >}} or writes it to {{< regref "RXDATA" >}}.
+The following figure shows how data appears on the serial data bus when the hardware reads it from {{#regref spi_host.TXDATA }} or writes it to {{#regref spi_host.RXDATA }}.
{{< wavejson >}}
{signal: [
@@ -498,14 +498,14 @@
### Command Length and Alignment in DATA
-Even though the {{< regref "TXDATA" >}} memory window typically accepts 32-bit words, command segments do not need to use all the bytes from every word.
+Even though the {{#regref spi_host.TXDATA }} memory window typically accepts 32-bit words, command segments do not need to use all the bytes from every word.
For TX (or Bidirectional) segments, unused bytes from the latest TX FIFO word are simply ignored at the end of a segment.
For RX (or Bidirectional) segments, if the last few bytes received do not fill an entire DATA word, the partial word will be zero-padded and inserted into the RX FIFO once the segment is completed.
If ByteOrder=1 (the default, Little-Endian case), this padding will fill the unused most-significant bytes of the final RX DATA word, otherwise the padding will fill the unused least-significant bytes.
The following waveform illustrates an example SPI transaction, where neither the data transmitted nor the data received in each segment fit into an even number of 32-bit words.
-In this example, the values `I[31:0]`, `A[31:0]` and `B[31:0]`, have been previously written into {{< regref "TXDATA" >}} via firmware, and afterwards one word, `X[31:0]`, is available for reading from {{< regref "RXDATA" >}}.
+In this example, the values `I[31:0]`, `A[31:0]` and `B[31:0]`, have been previously written into {{#regref spi_host.TXDATA }} via firmware, and afterwards one word, `X[31:0]`, is available for reading from {{#regref spi_host.RXDATA }}.
All data in the waveform is transferred using 32-bit instructions.
{{< wavejson >}}
@@ -539,8 +539,8 @@
}
{{< /wavejson >}}
-When packing data into the TX FIFO, there are also no restrictions on the alignment of the data written to the {{< regref "TXDATA" >}} memory window, as it supports byte-enable signals.
-This means that when copying bytes into {{< regref "TXDATA" >}} from unaligned firmware memory addresses, it is possible to use byte or half-word instructions.
+When packing data into the TX FIFO, there are also no restrictions on the alignment of the data written to the {{#regref spi_host.TXDATA }} memory window, as it supports byte-enable signals.
+This means that when copying bytes into {{#regref spi_host.TXDATA }} from unaligned firmware memory addresses, it is possible to use byte or half-word instructions.
Full-word instructions should however be used whenever possible, because each write consumes a full word of data in the TX FIFO regardless of the instruction size.
Smaller writes will thus make inefficient use of the TX FIFO.
@@ -548,14 +548,14 @@
In the worst case, such bubbles can also be interpreted as transient underflow conditions in the TX FIFO, and could trigger spurious interrupts.
The longest delays occur whenever a word is loaded into the TX FIFO with only one byte enabled.
-When writing to the {{< regref "TXDATA" >}} window, only three types of data are expected: individual bytes, half-words, and full-words.
+When writing to the {{#regref spi_host.TXDATA }} window, only three types of data are expected: individual bytes, half-words, and full-words.
Other types of write transactions (i.e., non-contiguous, zero-byte and three-byte writes) are not supported by most processors.
Therefore it is assumed that if such transactions do appear, it is likely a sign of a system integrity error, and so these other classes of writes are not supported.
-If such transactions ever occur, they trigger an "Invalid Access" error event, which suspends the processing of future commands until the error has been cleared by setting the {{< regref "ERROR_STATUS.ACCESSINVAL" >}} bit.
+If such transactions ever occur, they trigger an "Invalid Access" error event, which suspends the processing of future commands until the error has been cleared by setting the {{#regref spi_host.ERROR_STATUS.ACCESSINVAL }} bit.
The RX FIFO has no special provisions for packing received data in any unaligned fashion.
-Depending on the `ByteOrder` parameter, the first byte received is always packed into either the most- or least-significant byte read from the {{< regref "RXDATA" >}} memory window.
+Depending on the `ByteOrder` parameter, the first byte received is always packed into either the most- or least-significant byte read from the {{#regref spi_host.RXDATA }} memory window.
## Pass-through Mode
@@ -579,20 +579,20 @@
- `IDLE`: The SPI_HOST is idle.
- `READY`: The SPI_HOST is ready to accept a new command.
- `RXFULL`: The SPI_HOST has run out of room in the RXFIFO.
-- `RXWM`: The number of 32-bit words in the RXFIFO currently exceeds the value set in {{< regref "CONTROL.RX_WATERMARK" >}}.
+- `RXWM`: The number of 32-bit words in the RXFIFO currently exceeds the value set in {{#regref spi_host.CONTROL.RX_WATERMARK }}.
- `TXEMPTY`: The SPI_HOST has transmitted all the data in the TX FIFO.
-- `TXWM`: The number of 32-bit words in the TX FIFO currently is currently less than the value set in {{< regref "CONTROL.TX_WATERMARK" >}}
+- `TXWM`: The number of 32-bit words in the TX FIFO currently is currently less than the value set in {{#regref spi_host.CONTROL.TX_WATERMARK }}
-Most SPI events signal a particular condition that persists until it is fixed, and these conditions can be detected by polling the corresponding field in the {{< regref "STATUS" >}} register.
+Most SPI events signal a particular condition that persists until it is fixed, and these conditions can be detected by polling the corresponding field in the {{#regref spi_host.STATUS }} register.
-In addition to these events, there are also two additional diagnostic fields in the {{< regref "STATUS" >}} register:
+In addition to these events, there are also two additional diagnostic fields in the {{#regref spi_host.STATUS }} register:
- `RXSTALL`: The RX FIFO is full, and the SPI_HOST is stalled and waiting for firmware to remove some data.
- `TXSTALL`: The TX FIFO is not only empty, but the SPI_HOST is stalled and waiting for firmware to add more data.
These bits can provide diagnostic data for tuning the throughput of the device, but do not themselves generate event interrupts.
By default none of these SPI events trigger an interrupt.
-They need to be enabled by writing to the corresponding field in {{< regref "EVENT_ENABLE" >}}.
+They need to be enabled by writing to the corresponding field in {{#regref spi_host.EVENT_ENABLE }}.
The SPI event interrupt is signaled only when the IP enters the corresponding state.
For example if an interrupt is requested when the TX FIFO is empty, the IP will only generate one interrupt when the last data word is transmitted from the TX FIFO.
@@ -609,61 +609,61 @@
### Error Interrupt Conditions
There are six types of error events which each represent a violation of the SPI_HOST programming model:
-- If {{< regref "COMMAND" >}} is written when {{< regref "STATUS.READY">}} is zero, the IP will assert {{< regref "ERROR_STATUS.CMDERR" >}}.
-- The IP asserts {{< regref "ERROR_STATUS.OVERFLOW" >}} if it receives a write to {{< regref "TXDATA" >}} when the TX FIFO is full.
-- The IP asserts {{< regref "ERROR_STATUS.UNDERFLOW" >}} if it software attempts to read {{< regref "RXDATA" >}} when the RX FIFO is empty.
-- Specifying a command segment with an invalid width (speed), or making a request for a Bidirectional Dual- or Quad-width segment will trigger a {{< regref "ERROR_STATUS.CMDINVAL" >}} error event.
-- Submitting a command segment to an invalid CSID (one larger or equal to `NumCS`) will trigger a {{< regref "ERROR_STATUS.CSIDINVAL" >}} event.
-- {{< regref "ERROR_STATUS.ACCESSINVAL" >}} is asserted if the IP receives a write event to the {{< regref "TXDATA" >}} window that does not correspond to any known processor data type (byte, half- or full-word).
+- If {{#regref spi_host.COMMAND }} is written when {{#regref spi_host.STATUS.READY }} is zero, the IP will assert {{#regref spi_host.ERROR_STATUS.CMDERR }}.
+- The IP asserts {{#regref spi_host.ERROR_STATUS.OVERFLOW }} if it receives a write to {{#regref spi_host.TXDATA }} when the TX FIFO is full.
+- The IP asserts {{#regref spi_host.ERROR_STATUS.UNDERFLOW }} if it software attempts to read {{#regref spi_host.RXDATA }} when the RX FIFO is empty.
+- Specifying a command segment with an invalid width (speed), or making a request for a Bidirectional Dual- or Quad-width segment will trigger a {{#regref spi_host.ERROR_STATUS.CMDINVAL }} error event.
+- Submitting a command segment to an invalid CSID (one larger or equal to `NumCS`) will trigger a {{#regref spi_host.ERROR_STATUS.CSIDINVAL }} event.
+- {{#regref spi_host.ERROR_STATUS.ACCESSINVAL }} is asserted if the IP receives a write event to the {{#regref spi_host.TXDATA }} window that does not correspond to any known processor data type (byte, half- or full-word).
All of these programming violations will create an error event when they occur.
-They will also halt the IP until the corresponding bit is cleared in the {{< regref "ERROR_STATUS" >}} register.
-Whenever an error event occurs, the error must be acknowledged by clearing (write 1 to clear) the corresponding bit in {{< regref "ERROR_STATUS" >}}.
+They will also halt the IP until the corresponding bit is cleared in the {{#regref spi_host.ERROR_STATUS }} register.
+Whenever an error event occurs, the error must be acknowledged by clearing (write 1 to clear) the corresponding bit in {{#regref spi_host.ERROR_STATUS }}.
By default all error events will trigger an `error` interrupt.
-Clearing the bit corresponding bit in the {{< regref "ERROR_ENABLE" >}} register in the suppresses interrupts for that class of error event and allows the IP to proceed even if one of these errors has occurred.
-The {{< regref "ERROR_STATUS" >}} register will continue to report all violations even if a particular class of error event has been disabled.
+Clearing the bit corresponding bit in the {{#regref spi_host.ERROR_ENABLE }} register in the suppresses interrupts for that class of error event and allows the IP to proceed even if one of these errors has occurred.
+The {{#regref spi_host.ERROR_STATUS }} register will continue to report all violations even if a particular class of error event has been disabled.
Of the six error event classes, `ACCESSINVAL` error events are the only ones which cannot be disabled.
This is because `ACCESSINVAL` events are caused by anomalous TLUL byte-enable masks that do not correspond to any known software instructions, and can only occur through a fault in the hardware integration.
-When handling SPI_HOST `error` interrupts, the {{< regref "ERROR_STATUS" >}} bit should be cleared *before* clearing the error interrupt in the {{< regref "INTR_STATE" >}} register.
+When handling SPI_HOST `error` interrupts, the {{#regref spi_host.ERROR_STATUS }} bit should be cleared *before* clearing the error interrupt in the {{#regref spi_host.INTR_STATE }} register.
Failure do to so may result in a repeated interrupt.
## Status Indicators
-The {{< regref "STATUS" >}} register contains a number of fields that should be queried for successful operation or troubleshooting.
+The {{#regref spi_host.STATUS }} register contains a number of fields that should be queried for successful operation or troubleshooting.
-The register {{< regref "STATUS.ACTIVE" >}} indicates whether a command segment is currently being processed by the FSM.
-Even if {{< regref "STATUS.ACTIVE" >}} is high it is often still possible to insert another command segment into the command FIFO.
-The register {{< regref "STATUS.READY" >}} indicates that there is room in the command FIFO.
+The register {{#regref spi_host.STATUS.ACTIVE }} indicates whether a command segment is currently being processed by the FSM.
+Even if {{#regref spi_host.STATUS.ACTIVE }} is high it is often still possible to insert another command segment into the command FIFO.
+The register {{#regref spi_host.STATUS.READY }} indicates that there is room in the command FIFO.
-The {{< regref "STATUS.BYTEORDER" >}} field indicates the fixed value of the `ByteOrder` parameter, which is presented to software to confirm the byte ordering used in the {{< regref "RXDATA" >}} and {{< regref "TXDATA" >}} windows.
+The {{#regref spi_host.STATUS.BYTEORDER }} field indicates the fixed value of the `ByteOrder` parameter, which is presented to software to confirm the byte ordering used in the {{#regref spi_host.RXDATA }} and {{#regref spi_host.TXDATA }} windows.
-The 8-bit fields {{< regref "STATUS.RXQD" >}} and {{< regref "STATUS.TXQD" >}} respectively indicate the number of words currently stored in the RX and TX FIFOs.
+The 8-bit fields {{#regref spi_host.STATUS.RXQD }} and {{#regref spi_host.STATUS.TXQD }} respectively indicate the number of words currently stored in the RX and TX FIFOs.
-The remaining fields in the {{< regref "STATUS" >}} register are all flags related to the management of the TX and RX FIFOs, which are described in the [section on SPI Events](#spi-events-and-event-interrupts).
+The remaining fields in the {{#regref spi_host.STATUS }} register are all flags related to the management of the TX and RX FIFOs, which are described in the [section on SPI Events](#spi-events-and-event-interrupts).
## Other Registers
### SPI_HOST Enable
The SPI_HOST state machine is disabled on reset.
-Before any commands are processed, the block must be enabled by writing one to the {{< regref "CONTROL.SPIEN" >}} register.
+Before any commands are processed, the block must be enabled by writing one to the {{#regref spi_host.CONTROL.SPIEN }} register.
Writing a zero to this register temporarily suspends any previously submitted transactions.
-If the block is re-enabled by writing a one to {{< regref "CONTROL.SPIEN" >}}, any previously executing commands will continue from wherever they left off.
+If the block is re-enabled by writing a one to {{#regref spi_host.CONTROL.SPIEN }}, any previously executing commands will continue from wherever they left off.
An unacknowledged error event suspends the core state machine.
### SPI_HOST Output Enable
In addition to enabling the SPI_HOST FSM, the SPI_HOST outputs must also be enabled for successful operation.
-This can be achieved by also setting the {{< regref "CONTROL.OUTPUT_EN" >}} field when enabling the SPI_HOST FSM.
+This can be achieved by also setting the {{#regref spi_host.CONTROL.OUTPUT_EN }} field when enabling the SPI_HOST FSM.
### Component reset
In addition to the global hardware reset, there is a software reset option which completely resets the SPI host.
-To use this reset, assert {{< regref "CONTROL.SW_RST" >}}, and then wait for the device to reset ({{< regref "STATUS.ACTIVE" >}}, {{< regref "STATUS.TXQD" >}} and {{< regref "STATUS.RXQD" >}} to all go to zero), before releasing {{< regref "CONTROL.SW_RST" >}}.
+To use this reset, assert {{#regref spi_host.CONTROL.SW_RST }}, and then wait for the device to reset ({{#regref spi_host.STATUS.ACTIVE }}, {{#regref spi_host.STATUS.TXQD }} and {{#regref spi_host.STATUS.RXQD }} to all go to zero), before releasing {{#regref spi_host.CONTROL.SW_RST }}.
## Block Diagram
@@ -671,7 +671,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/spi_host.hjson" "hwcfg" >}}
+* [Interface Tables](data/spi_host.hjson#interfaces)
# Design Details
@@ -874,10 +874,10 @@
### Clock Divider
The SPI_HOST FSM is driven by the rising edge of the input clock, however the FSM state registers are not *enabled* during every cycle.
-There is an internal clock counter `clk_cntr_q` which repeatedly counts down from {{< regref "CONFIGOPTS.CLKDIV" >}} to 0, and the FSM is only enabled when `clk_cntr_q == 0`.
+There is an internal clock counter `clk_cntr_q` which repeatedly counts down from {{#regref spi_host.CONFIGOPTS.CLKDIV }} to 0, and the FSM is only enabled when `clk_cntr_q == 0`.
The exception is when the FSM is one of the two possible Idle states (`Idle` or `IdleCSBActive`), in which case `clk_cntr_q` is constantly held at zero, making it possible to immediately transition out of the idle state as soon as a new command appears.
-Once the FSM transitions out of the idle state, `clk_cntr_q` resets to {{< regref "CONFIGOPTS.CLKDIV" >}}, and FSM transitions are only enabled at the divided clock rate.
+Once the FSM transitions out of the idle state, `clk_cntr_q` resets to {{#regref spi_host.CONFIGOPTS.CLKDIV }}, and FSM transitions are only enabled at the divided clock rate.
As shown in the waveform below, this has the effect of limiting the FSM transitions to only occur at discrete *timeslices* of duration:
@@ -944,11 +944,11 @@
5. WaitTrail state: Similar to the WaitLead, this state serves to control the timing of the `csb` line.
The FSM uses the `wait_cntr` register to ensure that it remains in this state for `csntrail+1` timeslices, during which time the active `csb` is still held low.
-The `wait_cntr` register resets to {{< regref "CONFIGOPTS.CSNTRAIL" >}} upon entering this state, and is decremented once per timeslice.
+The `wait_cntr` register resets to {{#regref spi_host.CONFIGOPTS.CSNTRAIL }} upon entering this state, and is decremented once per timeslice.
This state transitions to `WaitIdle` when `wait_cntr` is zero.
6. WaitIdle state: In this timing control state, the FSM uses the `wait_cntr` register to ensure that all `csb` lines are held high for at least `csnidle+1` timeslices.
-The `wait_cntr` register resets to {{< regref "CONFIGOPTS.CSNIDLE" >}} upon entering this state, and is decremented once per timeslice.
+The `wait_cntr` register resets to {{#regref spi_host.CONFIGOPTS.CSNIDLE }} upon entering this state, and is decremented once per timeslice.
This state transitions to `Idle` when `wait_cntr` reaches zero.
{{< wavejson >}}
@@ -1133,7 +1133,7 @@
- 2 for Dual-mode
- 4 for Quad-mode
-The `byte_cntr_q` register is updated from the {{< regref "COMMAND.LEN" >}} register value, at the beginning of each segment, and decremented after each `byte_ending` pulse until the counter reaches zero.
+The `byte_cntr_q` register is updated from the {{#regref spi_host.COMMAND.LEN }} register value, at the beginning of each segment, and decremented after each `byte_ending` pulse until the counter reaches zero.
This relationship between the milestone signals and the bit and byte counters is also illustrated in the previous waveform.
@@ -1150,7 +1150,7 @@
A complete state diagram, including the `ConfigSwitch` state, is shown in the following section.
-The following waveform illustrates how a change in a single {{< regref "CONFIGOPTS" >}}, here {{< regref "CONFIGOPTS.CPOL" >}}, triggers an entry into the `ConfigSwitch` Idle state, and how the new configuration is applied at the transition from `WaitIdle` to `ConfigSwitch` thereby ensuring ample idle time both before and after the configuration update.
+The following waveform illustrates how a change in a single {{#regref spi_host.CONFIGOPTS }}, here {{#regref spi_host.CONFIGOPTS.CPOL }}, triggers an entry into the `ConfigSwitch` Idle state, and how the new configuration is applied at the transition from `WaitIdle` to `ConfigSwitch` thereby ensuring ample idle time both before and after the configuration update.
{{< wavejson >}}
{signal: [
@@ -1243,17 +1243,17 @@
The operation of the SPI_HOST IP proceeds in seven general steps.
To initialize the IP:
-1. Program the {{< regref "CONFIGOPTS" >}} multi-register with the appropriate timing and polarity settings for each `csb` line.
+1. Program the {{#regref spi_host.CONFIGOPTS }} multi-register with the appropriate timing and polarity settings for each `csb` line.
2. Set the desired interrupt parameters
3. Enable the IP
Then for each command:
-4. Load the data to be transmitted into the FIFO using the {{< regref "TXDATA" >}} memory window.
-5. Specify the target device by programming the {{< regref "CSID" >}}
-6. Specify the structure of the command by writing each segment into the {{< regref "COMMAND" >}} register
- - For multi-segment transactions, be sure to assert {{< regref "COMMAND.CSAAT" >}} for all but the last command segment
-7. For transactions which expect to receive a reply, the data can then be read back from the {{< regref "RXDATA" >}} window.
+4. Load the data to be transmitted into the FIFO using the {{#regref spi_host.TXDATA }} memory window.
+5. Specify the target device by programming the {{#regref spi_host.CSID }}
+6. Specify the structure of the command by writing each segment into the {{#regref spi_host.COMMAND }} register
+ - For multi-segment transactions, be sure to assert {{#regref spi_host.COMMAND.CSAAT }} for all but the last command segment
+7. For transactions which expect to receive a reply, the data can then be read back from the {{#regref spi_host.RXDATA }} window.
These latter four steps are then repeated for each command.
Each step is covered in detail in the following sections.
@@ -1265,26 +1265,26 @@
### Per-target Configuration
-The {{< regref "CONFIGOPTS" >}} multi-register must be programmed to reflect the requirements of the attached target devices.
+The {{#regref spi_host.CONFIGOPTS }} multi-register must be programmed to reflect the requirements of the attached target devices.
As such these registers can be programmed once at initialization, or whenever a new device is connected (e.g., via changes in the external pin connections, or changes in the pinmux configuration).
-The proper settings for the {{< regref "CONFIGOPTS" >}} fields (e.g., CPOL and CPHA, clock divider, ratios, and other timing or sampling requirements) will all depend on the specific device attached as well as the board level delays.
+The proper settings for the {{#regref spi_host.CONFIGOPTS }} fields (e.g., CPOL and CPHA, clock divider, ratios, and other timing or sampling requirements) will all depend on the specific device attached as well as the board level delays.
### Interrupt configuration
The next step is to configuration the interrupts for the SPI_HOST.
This should also be done at initialization using the following register fields:
-- The {{< regref "ERROR_ENABLE" >}} register should be configured to indicate what types of error conditions (if any) should be ignored to not trigger an interrupt.
+- The {{#regref spi_host.ERROR_ENABLE }} register should be configured to indicate what types of error conditions (if any) should be ignored to not trigger an interrupt.
At reset, these fields are all set indicating that all error classes trigger an interrupt.
-- For interrupt driven I/O the {{< regref "EVENT_ENABLE" >}} register must be configured to select the desired event interrupts to signal the desired conditions (e.g. "FIFO empty", "FIFO at the watermark level", or "ready for next command segment").
+- For interrupt driven I/O the {{#regref spi_host.EVENT_ENABLE }} register must be configured to select the desired event interrupts to signal the desired conditions (e.g. "FIFO empty", "FIFO at the watermark level", or "ready for next command segment").
By default, this register is all zeros, meaning all event interrupts are disabled, and thus all transactions must be managed by polling the status register.
- - When using the FIFO watermarks to send interrupts, the watermark levels must be set via the {{< regref "CONTROL.RX_WATERMARK" >}} and {{< regref "CONTROL.TX_WATERMARK" >}} fields.
+ - When using the FIFO watermarks to send interrupts, the watermark levels must be set via the {{#regref spi_host.CONTROL.RX_WATERMARK }} and {{#regref spi_host.CONTROL.TX_WATERMARK }} fields.
-- The event and error interrupts must finally be enabled using the {{< regref "INTR_ENABLE" >}} register.
+- The event and error interrupts must finally be enabled using the {{#regref spi_host.INTR_ENABLE }} register.
### Enabling the SPI_HOST
-The IP must be enabled before sending the first command by asserting the {{< regref "CONTROL.SPIEN" >}} bit.
+The IP must be enabled before sending the first command by asserting the {{#regref spi_host.CONTROL.SPIEN }} bit.
## Issuing Transactions
@@ -1300,7 +1300,7 @@
### Loading TX data
SPI transactions expect each command to start with some command sequence from the host, and so usually data will be transmitted at least in the first command segment.
-The {{< regref "TXDATA" >}} window provides a simple interface to the TX FIFO.
+The {{#regref spi_host.TXDATA }} window provides a simple interface to the TX FIFO.
Data can be written to the window using 8-, 16- or 32-bit instructions.
Some attention, however, should be paid to byte-ordering and segmenting conventions.
@@ -1309,16 +1309,16 @@
For SPI flash applications, it is generally assumed that most of the *payload* data will be directly copied from embedded SRAM to the flash device.
-If this data is to copied to the {{< regref "TXDATA" >}} window using 32-bit instructions, the SPI_HOST should be parameterized such that the `ByteOrder` parameter matches the byte order of the embedded CPU (i.e., for Ibex, `ByteOrder` should be left set to `1` to indicate a Little-Endian CPU).
+If this data is to copied to the {{#regref spi_host.TXDATA }} window using 32-bit instructions, the SPI_HOST should be parameterized such that the `ByteOrder` parameter matches the byte order of the embedded CPU (i.e., for Ibex, `ByteOrder` should be left set to `1` to indicate a Little-Endian CPU).
This will ensure that data is transmitted to the flash (and thus also stored in flash) in address-ascending order.
-For example, consider the transfer of four bytes, `D[3:0][7:0]`, to SPI via the {{< regref "TXDATA" >}} window.
+For example, consider the transfer of four bytes, `D[3:0][7:0]`, to SPI via the {{#regref spi_host.TXDATA }} window.
- It is assumed for this example that all four bytes are contiguously stored in SRAM at a word-aligned address, with `D[0]` at the lowest byte-address.
- When these bytes are loaded into the Ibex CPU they are arranged as the 32-bit word: `W[31:0] = {D[3][7:0], D[2][7:0], D[1][7:0], D[0][7:0]}`.
-- After this word are loaded into the {{< regref "TXDATA" >}} window, the LSB (i.e., `W[7:0] = D[0][7:0]`) is transmitted first, by virtue of the `ByteOrder == 1` configuration.
+- After this word are loaded into the {{#regref spi_host.TXDATA }} window, the LSB (i.e., `W[7:0] = D[0][7:0]`) is transmitted first, by virtue of the `ByteOrder == 1` configuration.
In this way, configuring `ByteOrder` to match the CPU ensures that data is transmitted in memory-address order.
-The value of the `ByteOrder` parameter can be confirmed by firmware by reading the {{< regref "STATUS.BYTEORDER" >}} register field.
+The value of the `ByteOrder` parameter can be confirmed by firmware by reading the {{#regref spi_host.STATUS.BYTEORDER }} register field.
Not all data to the SPI device will come from memory however.
In many cases the transaction command codes or headers will be constructed or packed on the fly in CPU registers.
@@ -1350,14 +1350,14 @@
foot: {text: "Addresses are transmitted MSB first, and data is returned in order of increasing peripheral byte address."}}
{{< /wavejson >}}
-Byte ordering on the bus can also be managed by writing {{< regref "TXDATA" >}} as a sequence of discrete bytes using 8-bit transactions, since partially-filled data-words are always sent in the order they are received.
+Byte ordering on the bus can also be managed by writing {{#regref spi_host.TXDATA }} as a sequence of discrete bytes using 8-bit transactions, since partially-filled data-words are always sent in the order they are received.
A few examples related to using SPI flash devices on a Little-Endian platform:
- A 4-byte address can be loaded into the TX FIFO as four individual bytes using 8-bit I/O instructions.
-- The above read command (with 4-byte address) can be loaded into the FIFO by first loading the command code into {{< regref "TXDATA" >}} as a single byte, and the address can be loaded into {{< regref "TXDATA" >}} using 32-bit instructions, provided the byte order is swapped before loading.
+- The above read command (with 4-byte address) can be loaded into the FIFO by first loading the command code into {{#regref spi_host.TXDATA }} as a single byte, and the address can be loaded into {{#regref spi_host.TXDATA }} using 32-bit instructions, provided the byte order is swapped before loading.
- Flash transactions with 3-byte addressing require some care, as there are no 24-bit I/O instructions, though there are a several options:
- After the 8-bit command code is sent, the address can either be sent in several I/O operations (e.g., the MSB is sent as an 8-bit command, and the remaining 16-bits can be sent after swapping)
- - If bandwidth efficiency is a priority, the address, `A[23:0]`, and command code, `C[7:0]`, can all be packed together into a single 4-byte quantity `W[31:0] = {A[7:0], A[15:8], A[23:16], C[7:0]}`, which when loaded into {{< regref "TXDATA" >}} will ensure that the command code is sent first, followed by the address in MSB-first order.
+ - If bandwidth efficiency is a priority, the address, `A[23:0]`, and command code, `C[7:0]`, can all be packed together into a single 4-byte quantity `W[31:0] = {A[7:0], A[15:8], A[23:16], C[7:0]}`, which when loaded into {{#regref spi_host.TXDATA }} will ensure that the command code is sent first, followed by the address in MSB-first order.
#### Segmenting Considerations
@@ -1368,36 +1368,36 @@
#### Refilling the TX FIFO
For extremely long transactions, the TX FIFO may not have enough capacity to hold all the data being transmitted.
-In this case software can either poll the {{< regref "STATUS.TXQD" >}} register to determine the number of elements in the TX FIFO, or enable the SPI_HOST IP to send an interrupt when the FIFO drains to a certain level.
-If {{< regref "INTR_ENABLE.spi_event" >}} and {{< regref "EVENT_ENABLE.TXWM" >}} are both asserted, the IP will send an interrupt whenever the number of elements in the TX FIFO falls below {{< regref "CONTROL.TX_WATERMARK" >}}.
+In this case software can either poll the {{#regref spi_host.STATUS.TXQD }} register to determine the number of elements in the TX FIFO, or enable the SPI_HOST IP to send an interrupt when the FIFO drains to a certain level.
+If {{#regref spi_host.INTR_ENABLE.spi_event }} and {{#regref spi_host.EVENT_ENABLE.TXWM }} are both asserted, the IP will send an interrupt whenever the number of elements in the TX FIFO falls below {{#regref spi_host.CONTROL.TX_WATERMARK }}.
### Specifying the Segments
-Each write to the {{< regref "COMMAND" >}} register corresponds to a single command segment.
-The length, CSAAT flag, direction and speed settings for that segment should all be packed into a single 32-bit register and written simultaneously to {{< regref "COMMAND" >}}.
+Each write to the {{#regref spi_host.COMMAND }} register corresponds to a single command segment.
+The length, CSAAT flag, direction and speed settings for that segment should all be packed into a single 32-bit register and written simultaneously to {{#regref spi_host.COMMAND }}.
-The {{< regref "COMMAND" >}} should only be written when {{< regref "STATUS.READY" >}} is asserted.
+The {{#regref spi_host.COMMAND }} should only be written when {{#regref spi_host.STATUS.READY }} is asserted.
While each command segment is being processed, the SPI_HOST has room to queue up exactly one additional segment descriptor in the Command Clock Domain Crossing.
Once a second command segment descriptor has been submitted, software must wait for the state machine to finish processing the current segment before submitting more.
-Software can poll the {{< regref "STATUS.READY" >}} field to determine when it is safe to insert another segment descriptor.
-Otherwise the {{< regref "EVENT_ENABLE.IDLE" >}} bit can be enabled (along with {{< regref "INTR_ENABLE.spi_event" >}}) to trigger an event interrupt whenever {{< regref "STATUS.READY" >}} is asserted.
+Software can poll the {{#regref spi_host.STATUS.READY }} field to determine when it is safe to insert another segment descriptor.
+Otherwise the {{#regref spi_host.EVENT_ENABLE.IDLE }} bit can be enabled (along with {{#regref spi_host.INTR_ENABLE.spi_event }}) to trigger an event interrupt whenever {{#regref spi_host.STATUS.READY }} is asserted.
### Reading Back the Device Response
Once an RX segment descriptor has been submitted to the SPI_HOST, the received data will be available in the RX FIFO after the first word has been received.
-The number of words in the FIFO can be polled by reading the {{< regref "STATUS.RXQD" >}} field.
-The SPI_HOST IP can also configured to generate watermark event interrupts whenever the number of words received reaches (or exceeds) {{< regref "CONTROL.RX_WATERMARK" >}}.
-To enable interrupts when ever the RX FIFO reaches the watermark, assert {{< regref "EVENT_ENABLE.RXWM" >}} along with {{< regref "INTR_ENABLE.spi_event" >}}.
+The number of words in the FIFO can be polled by reading the {{#regref spi_host.STATUS.RXQD }} field.
+The SPI_HOST IP can also configured to generate watermark event interrupts whenever the number of words received reaches (or exceeds) {{#regref spi_host.CONTROL.RX_WATERMARK }}.
+To enable interrupts when ever the RX FIFO reaches the watermark, assert {{#regref spi_host.EVENT_ENABLE.RXWM }} along with {{#regref spi_host.INTR_ENABLE.spi_event }}.
## Exception Handling
-The SPI_HOST will assert one of the {{< regref "ERROR_STATUS" >}} bits in the event of a firmware programming error, and will become unresponsive until firmware acknowledges the error by clearing the corresponding error bit.
+The SPI_HOST will assert one of the {{#regref spi_host.ERROR_STATUS }} bits in the event of a firmware programming error, and will become unresponsive until firmware acknowledges the error by clearing the corresponding error bit.
-The SPI_HOST interrupt handler should clear any bits in {{< regref "ERROR_STATUS" >}} bit before clearing {{< regref "INTR_STATE.error" >}}.
+The SPI_HOST interrupt handler should clear any bits in {{#regref spi_host.ERROR_STATUS }} bit before clearing {{#regref spi_host.INTR_STATE.error }}.
-In addition to clearing the {{< regref "ERROR_STATUS" >}} register, firmware can also trigger a complete software reset via the {{< regref "CONTROL.SW_RST" >}} bit, as described in the next section.
+In addition to clearing the {{#regref spi_host.ERROR_STATUS }} register, firmware can also trigger a complete software reset via the {{#regref spi_host.CONTROL.SW_RST }} bit, as described in the next section.
Other system-level errors may arise due to improper programming of the target device (e.g., due to violations in the device programming model, or improper configuration of the SPI_HOST timing registers).
Given that the SPI protocol provides no mechanism for the target device to stall the bus, the SPI_HOST will continue to function even if the remote device becomes unresponsive.
@@ -1407,11 +1407,11 @@
In the event of an error the SPI_HOST IP can be reset under software control using the following procedure:
-1. Set {{< regref "CONTROL.SW_RST" >}}.
+1. Set {{#regref spi_host.CONTROL.SW_RST }}.
2. Poll IP status registers for confirmation of successful state machine reset:
- - Wait for {{< regref "STATUS.ACTIVE" >}} to clear.
- - Wait for both FIFOs to completely drain by polling {{< regref "STATUS.TXQD" >}} and {{< regref "STATUS.RXQD" >}} until they reach zero.
-3. Clear {{ < regref "CONTROL.SW_RST" >}}.
+ - Wait for {{#regref spi_host.STATUS.ACTIVE }} to clear.
+ - Wait for both FIFOs to completely drain by polling {{#regref spi_host.STATUS.TXQD }} and {{#regref spi_host.STATUS.RXQD }} until they reach zero.
+3. Clear {{#regref spi_host.CONTROL.SW_RST }}.
## Device Interface Functions (DIFs)
@@ -1419,7 +1419,7 @@
## Register Table
-{{< incGenFromIpDesc "../data/spi_host.hjson" "registers" >}}
+* [Register Table](data/spi_host.hjson#registers)
# Appendices
diff --git a/hw/ip/sram_ctrl/README.md b/hw/ip/sram_ctrl/README.md
index f7fe727..4591a03 100644
--- a/hw/ip/sram_ctrl/README.md
+++ b/hw/ip/sram_ctrl/README.md
@@ -61,7 +61,7 @@
### Signals
-{{< incGenFromIpDesc "../data/sram_ctrl.hjson" "hwcfg" >}}
+* [Interface Tables](data/sram_ctrl.hjson#interfaces)
The table below lists other SRAM controller signals.
@@ -71,7 +71,7 @@
`lc_escalate_en_i` | `input` | `lc_ctrl_pkg::lc_tx_t` | Multibit life cycle escalation enable signal coming from life cycle controller, asserted if an escalation has occurred.
`sram_otp_key_o` | `output` | `otp_ctrl_pkg::sram_otp_key_req_t` | Key derivation request going to the key derivation interface of the OTP controller.
`sram_otp_key_i` | `input` | `otp_ctrl_pkg::sram_otp_key_rsp_t` | Ephemeral scrambling key coming back from the key derivation interface of the OTP controller.
-`otp_en_sram_ifetch_i` | `input` | `otp_ctrl_pkg::mubi8_t` | Multibit value coming from the OTP HW_CFG partition ([EN_SRAM_IFETCH](../otp_ctrl/README.md#direct-access-memory-map)), set to kMuBi8True in order to enable the {{< regref "EXEC" >}} CSR.
+`otp_en_sram_ifetch_i` | `input` | `otp_ctrl_pkg::mubi8_t` | Multibit value coming from the OTP HW_CFG partition ([EN_SRAM_IFETCH](../otp_ctrl/README.md#direct-access-memory-map)), set to kMuBi8True in order to enable the {{#regref sram_ctrl.EXEC }} CSR.
`cfg_i` | `input` | `logic [CfgWidth-1:0]` | Attributes for physical memory macro.
#### Interfaces to OTP and the SRAM Scrambling Primitive
@@ -143,7 +143,7 @@
Since the scrambling device uses a block cipher in CTR mode, it is undesirable to initialize the memory with all-zeros from a security perspective, as that would reveal the XOR keystream.
To this end, the `sram_ctrl` contains an LFSR-based initialization mechanism that overwrites the the entire memory with pseudorandom data.
-Initialization can be triggered via the {{< regref "CTRL.INIT" >}} CSR, and once triggered, the LFSR is first re-seeded with the nonce that has been fetched together with the scrambling key.
+Initialization can be triggered via the {{#regref sram_ctrl.CTRL.INIT }} CSR, and once triggered, the LFSR is first re-seeded with the nonce that has been fetched together with the scrambling key.
Then, the memory is initialized with pseudorandom data pulled from the LFSR.
For each pseudorandom 32bit word, the initialization mechanism computes the corresponding integrity bits and writes both the data and integrity bits (39bit total) through the scrambling device using the most recently obtained scrambling key.
@@ -155,7 +155,7 @@
### Code Execution from SRAM
The SRAM controller contains an access control mechanism for filtering instruction fetches from the processor.
-As illustrated below, an OTP switch EN_SRAM_IFETCH (see [OTP memory map](../otp_ctrl/README.md#direct-access-memory-map)) allows to either tie code execution from SRAM to the life cycle state via the HW_DEBUG_EN function (see [life cycle docs](../lc_ctrl/README.md#hw_debug_en)), or it can be enabled / disabled via the {{< regref "EXEC" >}} CSR.
+As illustrated below, an OTP switch EN_SRAM_IFETCH (see [OTP memory map](../otp_ctrl/README.md#direct-access-memory-map)) allows to either tie code execution from SRAM to the life cycle state via the HW_DEBUG_EN function (see [life cycle docs](../lc_ctrl/README.md#hw_debug_en)), or it can be enabled / disabled via the {{#regref sram_ctrl.EXEC }} CSR.
![SRAM Code Execution](./doc/sram_ctrl_sram_execution.svg)
@@ -205,19 +205,19 @@
The memory inside the SRAM controller can be used right away after a system reset.
However, since the scrambling key defaults to a predefined value, it is recommended that SW performs the following initialization steps as early in the boot process as possible.
-1. Request an updated ephemeral scrambling key from OTP by writing 0x1 to {{< regref "CTRL.RENEW_SCR_KEY" >}}.
- SW should spin on {{< regref "STATUS.SCR_KEY_VALID" >}} to wait until the new key has been obtained.
+1. Request an updated ephemeral scrambling key from OTP by writing 0x1 to {{#regref sram_ctrl.CTRL.RENEW_SCR_KEY }}.
+ SW should spin on {{#regref sram_ctrl.STATUS.SCR_KEY_VALID }} to wait until the new key has been obtained.
While this is not strictly needed since memory accesses to the SRAM will be stalled until the updated key has been obtained, the PC value upon a watchdog crash will be more informative when using a spin wait.
-2. (optional) Initialize the memory with pseudo random data by writing 0x1 to {{< regref "CTRL.INIT" >}}
- SW should spin on {{< regref "STATUS.INIT_DONE" >}} to wait until the memory has been initialized.
+2. (optional) Initialize the memory with pseudo random data by writing 0x1 to {{#regref sram_ctrl.CTRL.INIT }}
+ SW should spin on {{#regref sram_ctrl.STATUS.INIT_DONE }} to wait until the memory has been initialized.
While this is not strictly needed since memory accesses to the SRAM will be stalled until the initialization is done, the PC value upon a watchdog crash will be more informative when using a spin wait.
-3. (optional) Check the {{< regref "STATUS.SCR_KEY_SEED_VALID" >}} bit:
+3. (optional) Check the {{#regref sram_ctrl.STATUS.SCR_KEY_SEED_VALID }} bit:
- In case the scrambling key seeds have been fully provisioned to OTP, this bit should be set to 0x1. A value of 0x0 indicates that the OTP could be malfunctioning or has been tampered with.
- If the scrambling seeds have not yet been provisioned to OTP, this bit is set to 0x0. The scrambling key will in that case still be ephemeral, but the key seed mixed in as part of the key derivation process will be set to a predefined netlist constant.
-4. (optional) Lock down write access to {{< regref "CTRL" >}} by writing to {{< regref "CTRL_REGWEN" >}} if future key renewals and initializations should be disallowed until the next system reset.
+4. (optional) Lock down write access to {{#regref sram_ctrl.CTRL }} by writing to {{#regref sram_ctrl.CTRL_REGWEN }} if future key renewals and initializations should be disallowed until the next system reset.
Note that before (re-)requesting an updated SRAM key it is imperative to make sure that:
- The memory contents are not needed anymore. Requesting a key implicitly wipes all data in the SRAM.
@@ -231,4 +231,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/sram_ctrl.hjson" "registers" >}}
+* [Register Table](data/sram_ctrl.hjson#registers)
diff --git a/hw/ip/sysrst_ctrl/README.md b/hw/ip/sysrst_ctrl/README.md
index 03914bb..82732b9 100644
--- a/hw/ip/sysrst_ctrl/README.md
+++ b/hw/ip/sysrst_ctrl/README.md
@@ -52,7 +52,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/sysrst_ctrl.hjson" "hwcfg" >}}
+* [Interface Tables](data/sysrst_ctrl.hjson#interfaces)
## Combo detection
@@ -70,21 +70,21 @@
Let's use the "Power button + Key0 + Key1" combo with pre-condition "Key2" as an example:
-0. Software can define the key value `key2_in_i==0` as pre-condition in the {{< regref COM_PRE_SEL_CTL_0 >}} register.
-1. The key-pressed time for the pre-condition (e.g. 2 seconds) can be configured via the {{< regref COM_DET_SEL_CTL_0 >}} register.
-2. Software can define the three key values `pwrb_in_i==0`, `key0_in_i==0` and `key1_in_i==0` as trigger combination in the {{< regref COM_SEL_CTL_0 >}} register.
-3. The combo duration for which the above combo should be pressed (e.g. 10 seconds) can be configured via the {{< regref COM_DET_CTL_0 >}} register.
-4. Actions such as asserting `ec_rst_l_o` and raising an interrupt can be configured via the {{< regref COM_OUT_CTL_0 >}} register.
-5. The pulse width of the `ec_rst_l_o` pulse can be set in the {{< regref EC_RST_CTL >}} register.
-6. The software can optionally lock the `sysrst_ctrl` configuration via {{< regref REGWEN >}}
+0. Software can define the key value `key2_in_i==0` as pre-condition in the {{#regref spi_host.COM_PRE_SEL_CTL_0 }} register.
+1. The key-pressed time for the pre-condition (e.g. 2 seconds) can be configured via the {{#regref spi_host.COM_DET_SEL_CTL_0 }} register.
+2. Software can define the three key values `pwrb_in_i==0`, `key0_in_i==0` and `key1_in_i==0` as trigger combination in the {{#regref spi_host.COM_SEL_CTL_0 }} register.
+3. The combo duration for which the above combo should be pressed (e.g. 10 seconds) can be configured via the {{#regref spi_host.COM_DET_CTL_0 }} register.
+4. Actions such as asserting `ec_rst_l_o` and raising an interrupt can be configured via the {{#regref spi_host.COM_OUT_CTL_0 }} register.
+5. The pulse width of the `ec_rst_l_o` pulse can be set in the {{#regref spi_host.EC_RST_CTL }} register.
+6. The software can optionally lock the `sysrst_ctrl` configuration via {{#regref spi_host.REGWEN }}
Once the above configuration is active, `sysrst_ctrl` will start the timer when the pre-condition is valid (logic 0 level on all pre-condition signals).
If the timing condition (2 seconds) is met, `systrst_ctrl` will enable combo detection, and wait for a high (logic 1) to low (logic 0) transition of the combined trigger signal.
-If a transition is seen, and the timing condition is met (10 seconds), `sysrst_ctrl` will assert `ec_rst_l_o`, the interrupt request and set the interrupt status register {{< regref COMBO_INTR_STATUS >}} to indicate the interrupt cause.
-The software interrupt handler should then read the {{< regref COMBO_INTR_STATUS >}} register and clear the interrupt via the {{< regref INTR_STATE >}} register.
+If a transition is seen, and the timing condition is met (10 seconds), `sysrst_ctrl` will assert `ec_rst_l_o`, the interrupt request and set the interrupt status register {{#regref spi_host.COMBO_INTR_STATUS }} to indicate the interrupt cause.
+The software interrupt handler should then read the {{#regref spi_host.COMBO_INTR_STATUS }} register and clear the interrupt via the {{#regref spi_host.INTR_STATE }} register.
Note that an interrupt will also issue a wakeup request to the OpenTitan power manager via `wkup_req_o`.
-Software should therefore read and clear the {{< regref WKUP_STATUS >}} register as well.
+Software should therefore read and clear the {{#regref spi_host.WKUP_STATUS }} register as well.
### Combo actions
@@ -92,14 +92,14 @@
- Drive the `bat_disable` output high until the next reset.
- Issue an interrupt to the processor via `intr_event_detected_o`.
-- Assert `ec_rst_l_o` for the amount of cycles configured in {{< regref EC_RST_CTL >}}.
+- Assert `ec_rst_l_o` for the amount of cycles configured in {{#regref spi_host.EC_RST_CTL }}.
- Issue a reset request via `rst_req_o` to the reset manager of the OpenTitan system. Note that once a reset request is issued, it will remain asserted until the next reset.
-These actions can be configured via the {{< regref COM_OUT_CTL_0 >}} register for each of the combo blocks as described in the previous section.
+These actions can be configured via the {{#regref spi_host.COM_OUT_CTL_0 }} register for each of the combo blocks as described in the previous section.
### Hardwired reset stretching functionality
-In addition to the combo action described above, `ec_rst_l_o` is automatically asserted for the amount of cycles defined in the {{< regref EC_RST_CTL >}} register whenever the `ec_rst_l_i` input is asserted (i.e., when it transitions from high to low).
+In addition to the combo action described above, `ec_rst_l_o` is automatically asserted for the amount of cycles defined in the {{#regref spi_host.EC_RST_CTL }} register whenever the `ec_rst_l_i` input is asserted (i.e., when it transitions from high to low).
## Auto-block key outputs
@@ -107,26 +107,26 @@
Let's use the "Power button + Esc + Refresh" combo as an example.
When `pwrb_in_i` is asserted, `key1_out_o` (row) should be overridden so that `sysrst_ctrl` can detect if `key0_in_i` (column) is Refresh.
-1. The software enables the auto block feature and sets an appropriate debounce timer value in the {{< regref AUTO_BLOCK_DEBOUNCE_CTL >}} register.
-2. The software then defines the key outputs to auto override and their override values in the {{< regref AUTO_BLOCK_OUT_CTL >}} register.
+1. The software enables the auto block feature and sets an appropriate debounce timer value in the {{#regref spi_host.AUTO_BLOCK_DEBOUNCE_CTL }} register.
+2. The software then defines the key outputs to auto override and their override values in the {{#regref spi_host.AUTO_BLOCK_OUT_CTL }} register.
Once the above configuration is active, `sysrst_ctrl` will detect a high (logic 1) to low (logic 0) transition on `pwrb_in_i` and check whether the key `pwrb_in_i` stays low for the programmed duration.
-If this condition is met, `sysrst_ctrl` will drive `key1_out_o` to the value programmed in {{< regref AUTO_BLOCK_OUT_CTL >}}.
+If this condition is met, `sysrst_ctrl` will drive `key1_out_o` to the value programmed in {{#regref spi_host.AUTO_BLOCK_OUT_CTL }}.
## Keyboard and input triggered interrupt
Software can program the `sysrst_ctrl` block to detect edge transitions on the `pwrb_in_i`, `key0_in_i`, `key1_in_i`, `key2_in_i`, `ac_present_i`, `ec_rst_l_i` and `flash_wp_l_i` signals and trigger an interrupt:
-1. Software first defines the input signal and the edge transition to detect (H->L or L->H) via the {{< regref KEY_INTR_CTL >}} register.
-2. The software then programs an appropriate debounce timer value to the {{< regref KEY_INTR_DEBOUNCE_CTL >}} register.
+1. Software first defines the input signal and the edge transition to detect (H->L or L->H) via the {{#regref spi_host.KEY_INTR_CTL }} register.
+2. The software then programs an appropriate debounce timer value to the {{#regref spi_host.KEY_INTR_DEBOUNCE_CTL }} register.
For example, when the power button is pressed, `pwrb_in_i` goes from logic 1 to logic 0 which would amount to an H->L transition.
Likewise, when the power button is released, `pwrb_in_i` goes from logic 0 to logic 1 which would amount to an L->H transition.
-When `sysrst_ctrl` detects a transition (H->L or L->H) as specified in {{< regref KEY_INTR_CTL >}} and it meets the debounce requirement in {{< regref KEY_INTR_DEBOUNCE_CTL >}}, `sysrst_ctrl` sets the {{< regref KEY_INTR_STATUS >}} register to indicate the interrupt cause and send out a consolidated interrupt to the PLIC.
-The software interrupt handler should then read the {{< regref KEY_INTR_STATUS >}} register and clear the interrupt via the {{< regref INTR_STATE >}} register.
+When `sysrst_ctrl` detects a transition (H->L or L->H) as specified in {{#regref spi_host.KEY_INTR_CTL }} and it meets the debounce requirement in {{#regref spi_host.KEY_INTR_DEBOUNCE_CTL }}, `sysrst_ctrl` sets the {{#regref spi_host.KEY_INTR_STATUS }} register to indicate the interrupt cause and send out a consolidated interrupt to the PLIC.
+The software interrupt handler should then read the {{#regref spi_host.KEY_INTR_STATUS }} register and clear the interrupt via the {{#regref spi_host.INTR_STATE }} register.
Note that an interrupt will also issue a wakeup request to the OpenTitan power manager via `wkup_req_o`.
-Software should therefore read and clear the {{< regref WKUP_STATUS >}} register as well.
+Software should therefore read and clear the {{#regref spi_host.WKUP_STATUS }} register as well.
## Ultra-low-power Wakeup Feature
@@ -138,28 +138,28 @@
- A H -> L transition on the `pwrb_in_i` signal
- A L -> H transition on the `lid_open_i` signal
-Note that the signals may be potentially inverted due to the [input inversion feature](#inversion).
+Note that the signals may be potentially inverted due to the [input inversion feature]({{< relref "#inversion" >}}).
In order to activate this feature, software should do the following:
-1. Software can program the appropriate debounce times via the {{< regref ULP_AC_DEBOUNCE_CTL >}}, {{< regref ULP_LID_DEBOUNCE_CTL >}} and {{< regref ULP_PWRB_DEBOUNCE_CTL >}} registers.
-2. Then, software can activate detection by setting the {{< regref ULP_CTL >}} register to 1.
+1. Software can program the appropriate debounce times via the {{#regref spi_host.ULP_AC_DEBOUNCE_CTL }}, {{#regref spi_host.ULP_LID_DEBOUNCE_CTL }} and {{#regref spi_host.ULP_PWRB_DEBOUNCE_CTL }} registers.
+2. Then, software can activate detection by setting the {{#regref spi_host.ULP_CTL }} register to 1.
Once the above configuration is active, `sysrst_ctrl` will start the timer when a transition is detected.
-Once the timing condition is met, `sysrst_ctrl` will assert `z3_wakeup` output signal, the interrupt request and set the interrupt status register {{< regref ULP_STATUS >}} to indicate the interrupt cause.
-The software interrupt handler should then read the {{< regref ULP_STATUS >}} register and clear the interrupt via the {{< regref INTR_STATE >}} register.
+Once the timing condition is met, `sysrst_ctrl` will assert `z3_wakeup` output signal, the interrupt request and set the interrupt status register {{#regref spi_host.ULP_STATUS }} to indicate the interrupt cause.
+The software interrupt handler should then read the {{#regref spi_host.ULP_STATUS }} register and clear the interrupt via the {{#regref spi_host.INTR_STATE }} register.
Note that an interrupt will also issue a wakeup request to the OpenTitan power manager via `wkup_req_o`.
-Software should therefore read and clear the {{< regref WKUP_STATUS >}} register as well.
+Software should therefore read and clear the {{#regref spi_host.WKUP_STATUS }} register as well.
Also note that the detection status is sticky.
-I.e., software needs to explicitly disable this feature by setting {{< regref ULP_CTL >}} to 0 in order to clear the FSM state.
-If software wants to re-arm the mechanism right away, it should first read back {{< regref ULP_CTL >}} to make sure it has been cleared before setting that register to 1 again.
+I.e., software needs to explicitly disable this feature by setting {{#regref spi_host.ULP_CTL }} to 0 in order to clear the FSM state.
+If software wants to re-arm the mechanism right away, it should first read back {{#regref spi_host.ULP_CTL }} to make sure it has been cleared before setting that register to 1 again.
This is needed because this register has to be synchronized over to the AON clock domain.
## Pin input value accessibility
-`sysrst_ctrl` allows the software to read the raw input pin values via the {{< regref PIN_IN_VALUE >}} register like GPIOs.
+`sysrst_ctrl` allows the software to read the raw input pin values via the {{#regref spi_host.PIN_IN_VALUE }} register like GPIOs.
To this end, the hardware samples the raw input values of `pwrb_in_i`, `key[0,1,2]_in_i`, `ac_present_i`, `ec_rst_l_i`, `flash_wp_l_i` before they are being inverted, and synchronizes them onto the bus clock domain.
## Pin output and keyboard inversion control {#inversion}
@@ -167,29 +167,29 @@
Software can optionally override all output signals, and change the signal polarity of some of the input and output signals.
The output signal override feature always has higher priority than any of the combo pattern detection mechanisms described above.
-The selection of output signals to override, and the override values are programmable and lockable via the {{< regref PIN_ALLOWED_CTL >}} register.
-For example, {{< regref PIN_ALLOWED_CTL.EC_RST_L_0 >}} to 1 and {{< regref PIN_ALLOWED_CTL.EC_RST_L_1 >}} to 0 means that software allows `ec_rst_l_o` to be overridden with logic 0, but not with logic 1.
-If the SW locks the configuration with {{< regref REGWEN >}}, {{< regref PIN_ALLOWED_CTL >}} cannot be modified until the next OpenTitan reset.
+The selection of output signals to override, and the override values are programmable and lockable via the {{#regref spi_host.PIN_ALLOWED_CTL }} register.
+For example, {{#regref spi_host.PIN_ALLOWED_CTL.EC_RST_L_0 }} to 1 and {{#regref spi_host.PIN_ALLOWED_CTL.EC_RST_L_1 }} to 0 means that software allows `ec_rst_l_o` to be overridden with logic 0, but not with logic 1.
+If the SW locks the configuration with {{#regref spi_host.REGWEN }}, {{#regref spi_host.PIN_ALLOWED_CTL }} cannot be modified until the next OpenTitan reset.
-When the system is up and running, the software can modify {{< regref PIN_OUT_CTL >}} and {{< regref PIN_OUT_VALUE >}} to enable or disable the feature.
-For example, to release `ec_rst_l_o` after OpenTitan completes the reset, software can set {{< regref PIN_OUT_CTL >}} to 0 to stop the hardware from driving `ec_rst_l_o` to 0.
+When the system is up and running, the software can modify {{#regref spi_host.PIN_OUT_CTL }} and {{#regref spi_host.PIN_OUT_VALUE }} to enable or disable the feature.
+For example, to release `ec_rst_l_o` after OpenTitan completes the reset, software can set {{#regref spi_host.PIN_OUT_CTL }} to 0 to stop the hardware from driving `ec_rst_l_o` to 0.
-The input / output signal inversions can be programmed via the {{< regref KEY_INVERT_CTL >}} register.
+The input / output signal inversions can be programmed via the {{#regref spi_host.KEY_INVERT_CTL }} register.
Input signals will be inverted before the combo detection logic, while output signals will be inverted after the output signal override logic.
## EC and Power-on-reset
OpenTitan and EC will be reset together during power-on.
When OpenTitan is in reset, `ec_rst_l_o` will be asserted (active low).
-The power-on-reset value of {{< regref PIN_ALLOWED_CTL.EC_RST_L_1 >}} and {{< regref PIN_OUT_CTL.EC_RST_L >}} will guarantee that `ec_rst_l_o` remains asserted after OpenTitan reset is released.
-The software can release `ec_rst_l_o` explicitly by setting {{< regref PIN_OUT_CTL.EC_RST_L >}} to 0 during boot in order to complete the OpenTitan and EC power-on-reset sequence.
+The power-on-reset value of {{#regref spi_host.PIN_ALLOWED_CTL.EC_RST_L_1 }} and {{#regref spi_host.PIN_OUT_CTL.EC_RST_L }} will guarantee that `ec_rst_l_o` remains asserted after OpenTitan reset is released.
+The software can release `ec_rst_l_o` explicitly by setting {{#regref spi_host.PIN_OUT_CTL.EC_RST_L }} to 0 during boot in order to complete the OpenTitan and EC power-on-reset sequence.
Note that since the `sysrst_ctrl` does not have control over the pad open-drain settings, software should properly initialize the pad attributes of the corresponding pad in the [pinmux configuration](../pinmux/README.md) before releasing `ec_rst_l_o`.
## Flash Write Protect Output
Upon reset, the `flash_wp_l_o` signal will be asserted active low.
-The software can release `flash_wp_l_o` explicitly by setting {{< regref PIN_OUT_CTL.FLASH_WP_L >}} to 0 when needed.
+The software can release `flash_wp_l_o` explicitly by setting {{#regref spi_host.PIN_OUT_CTL.FLASH_WP_L }} to 0 when needed.
The `flash_wp_l_o` signal does have a corresponding input signal `flash_wp_l_i` - but that one is mainly intended for pad observability and does not have a bypass path to `flash_wp_l_o`.
Hence, the value of `flash_wp_l_o` defaults to logic 0 when it is not explicitly driven via the override function.
@@ -201,4 +201,4 @@
## Registers
-{{< incGenFromIpDesc "../data/sysrst_ctrl.hjson" "registers" >}}
+* [Register Table](data/sysrst_ctrl.hjson#registers)
diff --git a/hw/ip/uart/README.md b/hw/ip/uart/README.md
index b3c19bc..feadb76 100644
--- a/hw/ip/uart/README.md
+++ b/hw/ip/uart/README.md
@@ -42,7 +42,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/uart.hjson" "hwcfg" >}}
+* [Interface Tables](data/uart.hjson#interfaces)
## Design Details
@@ -85,7 +85,7 @@
### Transmission
-A write to {{< regref "WDATA" >}} enqueues a data byte into the 32 byte deep write FIFO, which
+A write to {{#regref uart.WDATA }} enqueues a data byte into the 32 byte deep write FIFO, which
triggers the transmit module to start UART TX serial data transfer. The TX
module dequeues the byte from the FIFO and shifts it bit by bit out to the UART
TX pin on positive edges of the baud clock.
@@ -108,7 +108,7 @@
incoming serial bits into a character buffer. If the STOP bit is
detected as high and the optional parity bit is correct the data byte
is pushed into a 32 byte deep RX FIFO. The data can be read out by
-reading {{< regref "RDATA" >}} register.
+reading {{#regref uart.RDATA }} register.
This behaviour of the receiver can be used to compute the approximate
baud clock frequency error that can be tolerated between the
@@ -152,7 +152,7 @@
### Setting the baud rate
-The baud rate is set by writing to the {{< regref "CTRL.NCO" >}} register field. This should be
+The baud rate is set by writing to the {{#regref uart.CTRL.NCO }} register field. This should be
set using the equation below, where `f_pclk` is the system clock frequency
provided to the UART, and `f_baud` is the desired baud rate (in bits per second).
@@ -206,8 +206,8 @@
and unexpected event interrupts.
#### tx_watermark / rx_watermark
-If the TX FIFO level becomes smaller than the TX water mark level (configurable via {{< regref "FIFO_CTRL.RXILVL" >}} and {{< regref "FIFO_CTRL.TXILVL" >}}), the `tx_watermark` interrupt is raised to inform SW.
-If the RX FIFO level becomes greater than or equal to RX water mark level (configurable via {{< regref "FIFO_CTRL.RXILVL" >}} and {{< regref "FIFO_CTRL.TXILVL" >}}), the `rx_watermark` interrupt is raised to inform SW.
+If the TX FIFO level becomes smaller than the TX water mark level (configurable via {{#regref uart.FIFO_CTRL.RXILVL }} and {{#regref uart.FIFO_CTRL.TXILVL }}), the `tx_watermark` interrupt is raised to inform SW.
+If the RX FIFO level becomes greater than or equal to RX water mark level (configurable via {{#regref uart.FIFO_CTRL.RXILVL }} and {{#regref uart.FIFO_CTRL.TXILVL }}), the `rx_watermark` interrupt is raised to inform SW.
Note that the watermark interrupts are edge triggered events.
This means the interrupt only triggers when the condition transitions from untrue->true.
@@ -231,7 +231,7 @@
The `rx_break_err` interrupt is triggered if a break condition has
been detected. A break condition is defined as the RX pin being
continuously low for more than a programmable number of
-character-times (via {{< regref "CTRL.RXBLVL" >}}, either 2, 4, 8, or 16). A
+character-times (via {{#regref uart.CTRL.RXBLVL }}, either 2, 4, 8, or 16). A
character time is 10 bit-times if parity is disabled (START + 8 data +
STOP) or 11 bit-times if parity is enabled (START + 8 data + parity +
STOP). If the UART is connected to an external connector this would
@@ -244,10 +244,10 @@
and no break is generated.) Note that only one interrupt is generated
per break -- the line must return high for at least half a bit-time
before an additional break interrupt is generated. The current break
-status can be read from the {{< regref "STATUS.BREAK" >}} bit. If STATUS.BREAK is set
-but {{< regref "INTR_STATE.BREAK" >}} is clear then the line break has already caused
+status can be read from the {{#regref uart.STATUS.BREAK }} bit. If STATUS.BREAK is set
+but {{#regref uart.INTR_STATE.BREAK }} is clear then the line break has already caused
an interrupt that has been cleared but the line break is still going
-on. If {{< regref "STATUS.BREAK" >}} is clear but {{< regref "INTR_STATE.BREAK" >}} is set then
+on. If {{#regref uart.STATUS.BREAK }} is clear but {{#regref uart.INTR_STATE.BREAK }} is set then
there has been a line break for which software has not cleared the
interrupt but the line is now back to normal.
@@ -302,7 +302,7 @@
#### rx_timeout
The `rx_timeout` interrupt is triggered when the RX FIFO has data sitting in it
without software reading it for a programmable number of bit times (using the
-baud rate clock as reference, programmable via {{< regref "TIMEOUT_CTRL" >}}). This is used to
+baud rate clock as reference, programmable via {{#regref uart.TIMEOUT_CTRL }}). This is used to
alert software that it has data still waiting in the FIFO that has not been
handled yet. The timeout counter is reset whenever the FIFO depth is changed or
an `rx_timeout` event occurs. If the RX FIFO is full and new character is
@@ -317,7 +317,7 @@
#### rx_parity_err
The `rx_parity_err` interrupt is triggered if parity is enabled and
the RX parity bit does not match the expected polarity as programmed
-in {{< regref "CTRL.PARITY_ODD" >}}.
+in {{#regref uart.CTRL.PARITY_ODD }}.
# Programmers Guide
@@ -462,7 +462,7 @@
}
```
-One use of the `rx_timeout` interrupt is when the {{< regref "FIFO_CTRL.RXILVL" >}}
+One use of the `rx_timeout` interrupt is when the {{#regref uart.FIFO_CTRL.RXILVL }}
is set greater than one, so an interrupt is only fired when the fifo
is full to a certain level. If the remote device sends fewer than the
watermark number of characters before stopping sending (for example it
@@ -483,4 +483,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/uart.hjson" "registers" >}}
+* [Register Table](data/uart.hjson#registers)
diff --git a/hw/ip/usbdev/README.md b/hw/ip/usbdev/README.md
index 03b8f18..43c153f 100644
--- a/hw/ip/usbdev/README.md
+++ b/hw/ip/usbdev/README.md
@@ -61,7 +61,7 @@
As soon as it is detected that SOF will not be received as expected (usually because the link is no longer active), `usb_ref_val_o` deasserts to zero until after the next `usb_ref_pulse_o`.
Both these signals are synchronous to the 48 MHz clock.
-They can be forced to zero by setting {{< regref "phy_config.usb_ref_disable" >}} to `1`.
+They can be forced to zero by setting {{#regref usbdev.phy_config.usb_ref_disable }} to `1`.
To successfully receive SOF packets without errors and thereby enabling clock synchronization, the initial accuracy of the 48 MHz clock source should be within 3.2% or 32,000 ppm.
This requirement comes from the fact that the SOF packet has a length of 24 bits (plus 8-bit sync field).
@@ -69,7 +69,7 @@
Internally, the USB device dynamically adjusts the sampling point based on observed line transitions.
Assuming the last bit of the SOF packet ID is sampled in the middle of the eye, the drift over the remaining 16 bits of the packet must be lower than half a bit (10^6 * (0.5/16) = 32,000 ppm).
-To externally monitor the 48 MHz clock, the USB device supports an oscillator test mode which can be enabled by setting {{< regref "phy_config.tx_osc_test_mode" >}} to `1`.
+To externally monitor the 48 MHz clock, the USB device supports an oscillator test mode which can be enabled by setting {{#regref usbdev.phy_config.tx_osc_test_mode }} to `1`.
In this mode, the device constantly transmits a J/K pattern but no longer receives SOF packets.
Consequently, it does not generate reference pulses for clock synchronization.
The clock might drift off.
@@ -94,7 +94,7 @@
The IP block supports two different encodings, driving out on separate TX interfaces.
The default encoding looks like the USB bus, with D+ and D- values driven on usb_dp_o and usb_dn_o pins.
The alternate encoding uses usb_se0_o to indicate a single-ended zero (SE0), and usb_d_o encodes K/J (when usb_se0_o is low).
-The TX mode can be selected by setting the `use_tx_d_se0` bit in {{< regref "phy_config" >}} to either 1 (alternate, using d/se0) or 0 (default, using dp/dn).
+The TX mode can be selected by setting the `use_tx_d_se0` bit in {{#regref usbdev.phy_config }} to either 1 (alternate, using d/se0) or 0 (default, using dp/dn).
The following table summarizes how the different output signals relate to the USB interface pins.
@@ -113,7 +113,7 @@
### Data Receive
The IP block supports recovery of the differential K and J symbols from the output of an external differential receiver or directly from the D+/D- pair.
-The RX mode can be selected to use a differential receiver's output by setting the `use_diff_rcvr` bit in {{< regref "phy_config" >}}.
+The RX mode can be selected to use a differential receiver's output by setting the `use_diff_rcvr` bit in {{#regref usbdev.phy_config }}.
The D+/D- pair is always used to detect the single-ended zero (SE0) state.
The following table summarizes how the different input signals relate to the USB interface pins.
@@ -131,7 +131,7 @@
| External Pins | Internal Signals | Notes |
|----------------|--------------------------|-------|
| sense (VBUS) | sense_i | The sense pin indicates the presence of VBUS from the USB host. |
-| [pullup] | dp_pullup_o, dn_pullup_o | When dp_pullup_o or dn_pullup_o asserts a 1.5k pullup resistor should be connected to D+ or D-, respectively. This can be done inside the chip or with an external pin. A permanently connected resistor could be used if the pin flip feature is not needed, but this is not recommended because there is then no way to force the device to appear to unplug. Only one of the pullup signals can be asserted at any time. The selection is based on the `pinflip` bit in {{< regref "phy_config" >}}. Because this is a Full-Speed device the resistor must be on the D+ pin, so when `pinflip` is zero, dp_pullup_o is used. |
+| [pullup] | dp_pullup_o, dn_pullup_o | When dp_pullup_o or dn_pullup_o asserts a 1.5k pullup resistor should be connected to D+ or D-, respectively. This can be done inside the chip or with an external pin. A permanently connected resistor could be used if the pin flip feature is not needed, but this is not recommended because there is then no way to force the device to appear to unplug. Only one of the pullup signals can be asserted at any time. The selection is based on the `pinflip` bit in {{#regref usbdev.phy_config }}. Because this is a Full-Speed device the resistor must be on the D+ pin, so when `pinflip` is zero, dp_pullup_o is used. |
| [suspend] | suspend_o | The suspend pin indicates to the USB transceiver that a constant idle has been detected on the link and the device is in the Suspend state (see Section 7.1.7.6 of the [USB 2.0 specification](https://www.usb.org/document-library/usb-20-specification)). |
| [rx_enable] | rx_enable_o | The rx_enable pin turns on/off a differential receiver. It is enabled via a CSR and automatically disabled when the device suspends. |
@@ -148,20 +148,20 @@
Alternatively, it can be used to enable an internal 1.5k pullup on the D+ pin.
This USB device supports the flipping of D+/D-.
-If the `pinflip` bit in {{< regref "phy_config" >}} is set, the data pins are flipped internally, meaning the 1.5k pullup resistor needs to be on the external D- line.
+If the `pinflip` bit in {{#regref usbdev.phy_config }} is set, the data pins are flipped internally, meaning the 1.5k pullup resistor needs to be on the external D- line.
To control the pullup on the D- line, this USB device features `dn_pullup_o` signal.
Of the two pullup signals `dp_pullup_o` and `dn_pullup_o`, only one can be enabled at any time.
As this is a Full-Speed device, `dp_pullup_o`, i.e., the pullup on D+ is used by default (`pinflip` equals zero).
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/usbdev.hjson" "hwcfg" >}}
+* [Interface Tables](data/usbdev.hjson#interfaces)
## USB Link State
The USB link has a number of states.
-These are detected and reported in {{< regref "usbstat.link_state" >}} and state changes are reported using interrupts.
+These are detected and reported in {{#regref usbdev.usbstat.link_state }} and state changes are reported using interrupts.
The FSM implements a subset of the USB device state diagram shown in Figure 9-1 of the [USB 2.0 specification.](https://www.usb.org/document-library/usb-20-specification)
|State| Description |
@@ -208,7 +208,7 @@
Software provides buffers for packet reception through a 4-entry Available Buffer FIFO.
(More study needed but four seems about right: one just returned to software, one being filled, one ready to be filled, and one for luck.)
-The {{< regref "rxenable_out" >}} and {{< regref "rxenable_setup" >}} registers is used to indicate which endpoints will accept data from the host using OUT or SETUP transactions, respectively.
+The {{#regref usbdev.rxenable_out }} and {{#regref usbdev.rxenable_setup }} registers is used to indicate which endpoints will accept data from the host using OUT or SETUP transactions, respectively.
When a packet is transferred from the host to the device (using an OUT or SETUP transaction) and reception of that type of transaction is enabled for the requested endpoint, the next buffer ID is pulled from the Available Buffer FIFO.
The packet data is written to the corresponding buffer in the packet buffer (the 2 kB SRAM).
If the packet is correctly received, an ACK is returned to the host.
@@ -217,33 +217,33 @@
Software should immediately provide a free buffer for future reception by writing the corresponding buffer ID to the Available Buffer FIFO.
It can then process the packet and eventually return the received buffer to the free pool.
This allows streaming on a single endpoint or across a number of endpoints.
-If the packets cannot be consumed at the rate they are received, software can implement selective flow control by clearing {{< regref "rxenable_out" >}} for a particular endpoint, which will result in a request to that endpoint being NAKed (negative acknowledgment).
+If the packets cannot be consumed at the rate they are received, software can implement selective flow control by clearing {{#regref usbdev.rxenable_out }} for a particular endpoint, which will result in a request to that endpoint being NAKed (negative acknowledgment).
In the unfortunate event that the Available Buffer FIFO is empty or the Received Buffer FIFO is full, all OUT transactions are NAKed and SETUP transactions are ignored.
In that event, the host will retry the transaction (up to some maximum attempts or time).
-There are two options for a given OUT endpoint's flow control, controlled by the {{< regref "set_nak_out" >}} register.
+There are two options for a given OUT endpoint's flow control, controlled by the {{#regref usbdev.set_nak_out }} register.
If `set_nak_out` is 0 for the endpoint, it will accept packets as long as there are buffers available in the Available Buffer FIFO and space available in the Received Buffer FIFO.
For timing, this option implies that software may not be able to affect the response to a given transaction, and buffer availability is the only needed factor.
-If `set_nak_out` is 1 for the endpoint, it will clear its corresponding bit in the {{< regref "rxenable_out" >}} register, forcing NAK responses to OUT transactions to that endpoint until software can intervene.
+If `set_nak_out` is 1 for the endpoint, it will clear its corresponding bit in the {{#regref usbdev.rxenable_out }} register, forcing NAK responses to OUT transactions to that endpoint until software can intervene.
That option uses NAK to defer the host, and this enables software to implement features that require protocol-level control at transaction boundaries, such as when implementing the functional stall.
### Transmission
To send data to the host in response to an IN transaction, software first writes the data into a free buffer.
-Then, it writes the buffer ID, data length and rdy flag to the {{< regref "configin" >}} register of the corresponding endpoint.
+Then, it writes the buffer ID, data length and rdy flag to the {{#regref usbdev.configin }} register of the corresponding endpoint.
When the host next does an IN transaction to that endpoint, the data will be sent from the buffer.
-On receipt of the ACK from the host, the rdy bit in the {{< regref "configin" >}} register will be cleared, and the bit corresponding to the endpoint ID will be set in the {{< regref "in_sent" >}} register causing a pkt_sent interrupt to be raised.
-Software can return the buffer to the free pool and write a 1 to clear the endpoint bit in the {{< regref "in_sent" >}} register.
-Note that streaming can be achieved if the next buffer has been prepared and is written to the {{< regref "configin" >}} register when the interrupt is received.
+On receipt of the ACK from the host, the rdy bit in the {{#regref usbdev.configin }} register will be cleared, and the bit corresponding to the endpoint ID will be set in the {{#regref usbdev.in_sent }} register causing a pkt_sent interrupt to be raised.
+Software can return the buffer to the free pool and write a 1 to clear the endpoint bit in the {{#regref usbdev.in_sent }} register.
+Note that streaming can be achieved if the next buffer has been prepared and is written to the {{#regref usbdev.configin }} register when the interrupt is received.
A Control transfer requires one or more IN transactions, either during the data stage or the status stage.
-Therefore, when a SETUP transaction is received for an endpoint, any buffers that are waiting to be sent out to the host from that endpoint are canceled by clearing the rdy bit in the corresponding {{< regref "configin" >}} register.
+Therefore, when a SETUP transaction is received for an endpoint, any buffers that are waiting to be sent out to the host from that endpoint are canceled by clearing the rdy bit in the corresponding {{#regref usbdev.configin }} register.
To keep track of such canceled buffers, the pend bit in the same register is set.
The transfer must be queued again after the Control transfer is completed.
-Similarly, a Link Reset cancels any waiting IN transactions by clearing the rdy bit in the {{< regref "configin" >}} register of all endpoints.
-The pend bit in the {{< regref "configin" >}} register is set for all endpoints with a pending IN transaction.
+Similarly, a Link Reset cancels any waiting IN transactions by clearing the rdy bit in the {{#regref usbdev.configin }} register of all endpoints.
+The pend bit in the {{#regref usbdev.configin }} register is set for all endpoints with a pending IN transaction.
### Buffer Count and Size
@@ -251,7 +251,7 @@
Under high load, the 32 buffers of the packet buffer (2 kB SRAM) are allocated as follows:
- 1 is being processed following reception,
- 4 are in the Available Buffer FIFO, and
-- 12 (worst case) waiting transmissions in the {{< regref "configin" >}} registers.
+- 12 (worst case) waiting transmissions in the {{#regref usbdev.configin }} registers.
This leaves 15 buffers for preparation of future transmissions (which would need 12 in the worst case of one per endpoint) and the free pool.
The size of 64 bytes per buffer satisfies the maximum USB packet size for a Full-Speed interface for Control transfers (max may be 8, 16, 32 or 64 bytes), Bulk Transfers (max is 64 bytes) and Interrupt transfers (max is 64 bytes).
@@ -267,19 +267,19 @@
## Initialization
-The basic hardware initialization is to (in any order) configure the physical interface for the implementation via the {{< regref "phy_config" >}} register, fill the Available Buffer FIFO, enable IN and OUT endpoints with ID 0 (this is the control endpoint that the host will use to configure the interface), enable reception of SETUP and OUT packets on OUT Endpoint 0, and enable any required interrupts.
-Finally, the interface is enabled by setting the enable bit in the {{< regref "usbctrl" >}} register.
+The basic hardware initialization is to (in any order) configure the physical interface for the implementation via the {{#regref usbdev.phy_config }} register, fill the Available Buffer FIFO, enable IN and OUT endpoints with ID 0 (this is the control endpoint that the host will use to configure the interface), enable reception of SETUP and OUT packets on OUT Endpoint 0, and enable any required interrupts.
+Finally, the interface is enabled by setting the enable bit in the {{#regref usbdev.usbctrl }} register.
Setting this bit causes the USB device to assert the pullup on the D+ line, which is used by the host to detect the device.
-There is no need to configure the device ID in ({{< regref "usbctrl.device_address" >}}) at this point -- the line remains in reset and the hardware forces the device ID to zero.
+There is no need to configure the device ID in ({{#regref usbdev.usbctrl.device_address }}) at this point -- the line remains in reset and the hardware forces the device ID to zero.
The second stage of initialization is done under control of the host, which will use control transfers (always beginning with SETUP transactions) to Endpoint 0.
Initially these will be sent to device ID 0.
-When a Set Address request is received, the device ID received must be stored in the {{< regref "usbctrl.device_address" >}} register.
+When a Set Address request is received, the device ID received must be stored in the {{#regref usbdev.usbctrl.device_address }} register.
Note that device 0 is used for the entire control transaction setting the new device ID, so writing the new ID to the register should not be done until the ACK for the Status stage has been received (see [USB 2.0 specification](https://www.usb.org/document-library/usb-20-specification)).
The host will then issue additional control transfers to Endpoint 0 to configure the device, now to the device's configured address.
-In response to the Set Configuration request, software should set up the rest of the endpoints for that configuration, including configuring the flow control behavior for OUT endpoints via the {{< regref "set_nak_out" >}} register, configuring the endpoint type via the {{< regref "rxenable_setup" >}} register (for a control endpoint) and the {{< regref "out_iso" >}} and {{< regref "in_iso" >}} registers (for isochronous OUT and IN endpoints, respectively).
-Finally, software should enable the configured endpoints via the {{< regref "ep_out_enable" >}} and {{< regref "ep_in_enable" >}} registers.
+In response to the Set Configuration request, software should set up the rest of the endpoints for that configuration, including configuring the flow control behavior for OUT endpoints via the {{#regref usbdev.set_nak_out }} register, configuring the endpoint type via the {{#regref usbdev.rxenable_setup }} register (for a control endpoint) and the {{#regref usbdev.out_iso }} and {{#regref usbdev.in_iso }} registers (for isochronous OUT and IN endpoints, respectively).
+Finally, software should enable the configured endpoints via the {{#regref usbdev.ep_out_enable }} and {{#regref usbdev.ep_in_enable }} registers.
The status stage of the Set Configuration request should not be allowed to complete until all endpoints are set up.
@@ -299,7 +299,7 @@
Keeping the Available Buffer FIFO full can be done with a simple loop, adding buffer IDs from the software-managed free pool until the FIFO is full.
A simpler policy of just adding a buffer ID to the Available Buffer FIFO whenever a buffer ID is removed from the Received Buffer FIFO should work on average, but performance will be slightly worse when bursts of packets are received.
-Flow control (using NAKs) may be done on a per-endpoint basis using the {{< regref "rxenable_out" >}} register.
+Flow control (using NAKs) may be done on a per-endpoint basis using the {{#regref usbdev.rxenable_out }} register.
If this does not indicate OUT packet reception is enabled, then any OUT packet will receive a NAK to request a retry later.
This should only be done for short durations or the host may timeout the transaction.
@@ -309,7 +309,7 @@
The host will send OUT or SETUP transactions when it wants to transfer data to the device.
The data packets are directed to a particular endpoint, and the maximum packet size is set per-endpoint in its Endpoint Descriptor (this must be the same or smaller than the maximum packet size supported by the device).
A pkt_received interrupt is raised whenever there are one or more packets in the Received Buffer FIFO.
-Software should pop the information from the Received Buffer FIFO by reading the {{< regref "rxfifo" >}} register, which gives (1) the buffer ID that the data was received in, (2) the data length received in bytes, (3) the endpoint to which the packet was sent, and (4) an indication if the packet was sent with an OUT or SETUP transaction.
+Software should pop the information from the Received Buffer FIFO by reading the {{#regref usbdev.rxfifo }} register, which gives (1) the buffer ID that the data was received in, (2) the data length received in bytes, (3) the endpoint to which the packet was sent, and (4) an indication if the packet was sent with an OUT or SETUP transaction.
Note that the data length could be between zero and the maximum packet size -- in some situations a zero length packet is used as an acknowledgment or end of transfer.
The data length does not include the packet CRC.
@@ -324,30 +324,30 @@
The host will only generate IN requests if the endpoint is declared as an IN endpoint in its Endpoint Descriptor (note that two descriptors are needed if the same endpoint is used for both IN and OUT transfers).
The Endpoint Descriptor also includes a description of the frequency the endpoint should be polled (for isochronous and interrupt endpoints).
-Data is queued for transmission by writing the corresponding {{< regref "configin" >}} register with the buffer ID containing the data, the length in bytes of data (0 to maximum packet length) and setting the rdy bit.
+Data is queued for transmission by writing the corresponding {{#regref usbdev.configin }} register with the buffer ID containing the data, the length in bytes of data (0 to maximum packet length) and setting the rdy bit.
This data (with the packet CRC) will be sent as a response to the next IN transaction on the corresponding endpoint.
-When the host ACKs the data, the rdy bit is cleared, the corresponding endpoint bit is set in the {{< regref "in_sent" >}} register, and a pkt_sent interrupt is raised. If the host does not ACK the data, the packet will be retried.
-When the packet transmission has been noted by software, the corresponding endpoint bit should be cleared in the {{< regref "in_sent" >}} register (by writing a 1 to this very bit).
+When the host ACKs the data, the rdy bit is cleared, the corresponding endpoint bit is set in the {{#regref usbdev.in_sent }} register, and a pkt_sent interrupt is raised. If the host does not ACK the data, the packet will be retried.
+When the packet transmission has been noted by software, the corresponding endpoint bit should be cleared in the {{#regref usbdev.in_sent }} register (by writing a 1 to this very bit).
-Note that the {{< regref "configin" >}} for an endpoint is a single register, so no new data packet should be queued until the previous packet has been ACKed.
-If a SETUP transaction is received on a control endpoint that has a transmission pending, the hardware will **clear the rdy bit** and **set the pend bit** in the {{< regref "configin" >}} register of that endpoint.
-Software must remember the pending transmission and, after the Control transaction is complete, write it back to the {{< regref "configin" >}} register with the rdy bit set.
+Note that the {{#regref usbdev.configin }} for an endpoint is a single register, so no new data packet should be queued until the previous packet has been ACKed.
+If a SETUP transaction is received on a control endpoint that has a transmission pending, the hardware will **clear the rdy bit** and **set the pend bit** in the {{#regref usbdev.configin }} register of that endpoint.
+Software must remember the pending transmission and, after the Control transaction is complete, write it back to the {{#regref usbdev.configin }} register with the rdy bit set.
## Stalling
-The {{< regref "out_stall" >}} and {{< regref "in_stall" >}} registers are used for endpoint stalling.
+The {{#regref usbdev.out_stall }} and {{#regref usbdev.in_stall }} registers are used for endpoint stalling.
There is one dedicated register per endpoint.
Stalling is used to signal that the host should not retry a particular transmission or to signal certain error conditions (functional stall).
Control endpoints also use a STALL to indicate unsupported requests (protocol stall).
-Unused endpoints can have their {{< regref "in_stall" >}} or {{< regref "out_stall" >}} register left clear, so in many cases there is no need to use the register.
+Unused endpoints can have their {{#regref usbdev.in_stall }} or {{#regref usbdev.out_stall }} register left clear, so in many cases there is no need to use the register.
If the stall register is set for an enabled endpoint then the STALL response will be provided to all IN or OUT requests on that endpoint.
In the case of a protocol stall, the device must send a STALL for all IN/OUT requests until the next SETUP token is received.
-To support this, software sets the {{< regref "in_stall" >}} and {{< regref "out_stall" >}} register for an endpoint when the host requests an unsupported transfer.
+To support this, software sets the {{#regref usbdev.in_stall }} and {{#regref usbdev.out_stall }} register for an endpoint when the host requests an unsupported transfer.
The hardware will then send a STALL response to all IN/OUT transactions until the next SETUP is received for this endpoint.
-Receiving the **SETUP token clears the {{< regref "in_stall" >}} and {{< regref "out_stall" >}} registers** for that endpoint.
-If either a control endpoint's {{< regref "set_nak_out" >}} bit is set or software has cleared the {{< regref "rxenable_out" >}} bit before this transfer began, the hardware will send NAKs to any IN/OUT requests until the software has decided what action to take for the new SETUP request.
+Receiving the **SETUP token clears the {{#regref usbdev.in_stall }} and {{#regref usbdev.out_stall }} registers** for that endpoint.
+If either a control endpoint's {{#regref usbdev.set_nak_out }} bit is set or software has cleared the {{#regref usbdev.rxenable_out }} bit before this transfer began, the hardware will send NAKs to any IN/OUT requests until the software has decided what action to take for the new SETUP request.
## Device Interface Functions (DIFs)
@@ -355,7 +355,7 @@
## Register Table
-{{< incGenFromIpDesc "../data/usbdev.hjson" "registers" >}}
+* [Register Table](data/usbdev.hjson#registers)
## Application to FPGAs
diff --git a/hw/ip/usbdev/doc/wake_resume.md b/hw/ip/usbdev/doc/wake_resume.md
index c151b59..042b1df 100644
--- a/hw/ip/usbdev/doc/wake_resume.md
+++ b/hw/ip/usbdev/doc/wake_resume.md
@@ -21,15 +21,15 @@
- The protocol engine begins ignoring transactions.
Any non-idle signaling kicks off the process to resume.
- The USB differential receiver is turned off, if it was controlled by the `rx_enable_o` pin.
- - Software receives the event for going into the suspended state in {{< regref "intr_state.link_suspend" "hw/ip/usbdev/doc/_index.md" >}}.
+ - Software receives the event for going into the suspended state in {{#regref usbdev.intr_state.link_suspend }}.
2. Software hands control to the AON module.
- - Software writes a `1` to {{< regref "wake_control.suspend_req" "hw/ip/usbdev/doc/_index.md" >}}.
+ - Software writes a `1` to {{#regref usbdev.wake_control.suspend_req }}.
- The AON module transitions to the active state and takes over the pullup enable.
It begins monitoring for events that trigger waking / resuming / resetting.
3. Software prepares for deep sleep.
- It saves the current "device state" in the AON retention RAM, including the current configuration and device address (if any).
- The `usbdev_linkstate` module is still powered and monitoring events, and it can resume at any time.
- Note that if a resume event does occur before the point of no return, software need only set {{< regref "wake_control.wake_ack" "hw/ip/usbdev/doc/_index.md" >}} to restore control to `usbdev`.
+ Note that if a resume event does occur before the point of no return, software need only set {{#regref usbdev.wake_control.wake_ack }} to restore control to `usbdev`.
- Software also does any other tasks for preparing for deep sleep, such as enabling USB events to wake the chip.
4. Software begins deep sleep.
- This is the likely the point of no return.
@@ -47,11 +47,11 @@
It is now monitoring events alongside the AON module.
4. Software releases the DIOs from sleep mode.
5. Software checks the AON events and identifies the correct state transition.
-6. Software issues {{< regref "wake_control.wake_ack" "hw/ip/usbdev/doc/_index.md" >}} to the AON module.
+6. Software issues {{#regref usbdev.wake_control.wake_ack }} to the AON module.
- The AON module stops monitoring events and controlling the pull-ups, restoring control to the full-power `usbdev` module.
- The AON module also clears the stored events.
Events that occurred between reading the stored values in the AON module and acknowledging the wake-up are captured in the `usbdev_linkstate` module.
-7. If software determined the state transition should be back to an active state, software issues {{< regref "usbctrl.resume_link_active" "hw/ip/usbdev/doc/_index.md" >}}.
+7. If software determined the state transition should be back to an active state, software issues {{#regref usbdev.usbctrl.resume_link_active }}.
- After going to low-power, it's not clear to the hardware whether it needs a bus reset to transition out of the `LinkPowered` state.
Software's saved state in the AON retention RAM should provide this information, and the CSR write provides a bypass mechanism.
- The `usbdev_linkstate` module transitions from `LinkPowered` to `LinkResuming` state.
diff --git a/hw/ip_templates/alert_handler/README.md b/hw/ip_templates/alert_handler/README.md
index b3fc596..f3dfce4 100644
--- a/hw/ip_templates/alert_handler/README.md
+++ b/hw/ip_templates/alert_handler/README.md
@@ -111,7 +111,7 @@
### Signals
-{{< incGenFromIpDesc "../data/alert_handler.hjson" "hwcfg" >}}
+* [Interface Tables](../../top_earlgrey/ip_autogen/alert_handler/data/alert_handler.hjson#interfaces)
The table below lists other alert handler module signals.
The number of alert instances is parametric and hence alert and ping diff pairs are grouped together in packed arrays.
@@ -174,7 +174,7 @@
This can be useful for extracting more information about possible failures or bugs without having to use the tile-link bus interface (which may become unresponsive under certain circumstances).
It is recommended for the top level to store this information in an always-on location.
-Note that the crashdump state is continuously output via `crashdump_o` until the latching trigger condition is true for the first time (see {{< regref CLASSA_CRASHDUMP_TRIGGER_SHADOWED >}}).
+Note that the crashdump state is continuously output via `crashdump_o` until the latching trigger condition is true for the first time (see {{#regref alert_handler.CLASSA_CRASHDUMP_TRIGGER_SHADOWED }}).
After that, the `crashdump_o` is held constant until all classes that have escalated are cleared.
This is done so that it is possible to capture the true alert cause before spurious alert events start to pop up due to escalation countermeasures with excessive side effects (like life cycle scrapping for example).
If classes that have escalated are not configured as clearable, then it is not possible to re-arm the crashdump latching mechanism at runtime and the alert handler has to be reset.
@@ -386,7 +386,7 @@
In both cases, the LFSR timer proceeds with the next ping, but in the second case it will additionally raise a "pingfail" alert.
The ping enable signal remains asserted during the time where the LFSR counter waits.
-The timeout value is a function of the ratios between the alert handler clock and peripheral clocks present in the system, and can be programmed at startup time via the register {{< regref "PING_TIMEOUT_CYC_SHADOWED" >}}.
+The timeout value is a function of the ratios between the alert handler clock and peripheral clocks present in the system, and can be programmed at startup time via the register {{#regref alert_handler.PING_TIMEOUT_CYC_SHADOWED }}.
Note that the ping timer directly flags a "pingfail" alert if a spurious "ping ok" message comes in that has not been requested.
@@ -444,20 +444,20 @@
- Accumulation max value.
This is the total number (sum of all alerts classified in this group) of alerts required to enter escalation phase (see below).
- Example register is {{< regref "CLASSA_ACCUM_THRESH_SHADOWED" >}}.
+ Example register is {{#regref alert_handler.CLASSA_ACCUM_THRESH_SHADOWED }}.
- Current accumulation register.
This clearable register indicates how many alerts have been accumulated to date.
Software should clear before it reaches the accumulation setting to avoid escalation.
- Example register is {{< regref "CLASSA_ACCUM_CNT" >}}.
+ Example register is {{#regref alert_handler.CLASSA_ACCUM_CNT }}.
2. The second way is an interrupt timeout counter which triggers escalation if an alert interrupt is not handled within the programmable timeout window.
Once the counter hits the timeout threshold, the escalation protocol is triggered.
The corresponding CSRs are:
- - Interrupt timeout value in cycles {{< regref "CLASSA_TIMEOUT_CYC_SHADOWED" >}}.
+ - Interrupt timeout value in cycles {{#regref alert_handler.CLASSA_TIMEOUT_CYC_SHADOWED }}.
The interrupt timeout is disabled if this is set to 0 (default).
- - The current interrupt timeout value can be read via {{< regref "CLASSA_ESC_CNT" >}} if {{< regref "CLASSA_STATE" >}} is in the `Timeout` state.
- Software should clear the corresponding interrupt state bit {{< regref "INTR_STATE.CLASSA" >}} before the timeout expires to avoid escalation.
+ - The current interrupt timeout value can be read via {{#regref alert_handler.CLASSA_ESC_CNT }} if {{#regref alert_handler.CLASSA_STATE }} is in the `Timeout` state.
+ Software should clear the corresponding interrupt state bit {{#regref alert_handler.INTR_STATE.CLASSA }} before the timeout expires to avoid escalation.
Technically, the interrupt timeout feature (2. above) is implemented using the same counter used to time the escalation phases.
This is possible since escalation phases or interrupt timeout periods are non-overlapping (escalation always takes precedence should it be triggered).
@@ -474,13 +474,13 @@
Each class can be programmed with its own escalation protocol.
If one of the two mechanisms described above fires, a timer for that particular class is started.
-The timer can be programmed with up to 4 delays (e.g., {{< regref "CLASSA_PHASE0_CYC" >}}), each representing a distinct escalation phase (0 - 3).
+The timer can be programmed with up to 4 delays (e.g., {{#regref alert_handler.CLASSA_PHASE0_CYC }}), each representing a distinct escalation phase (0 - 3).
Each of the four escalation severity outputs (0 - 3) are by default configured to be asserted during the corresponding phase, e.g., severity 0 in phase 0, severity 1 in phase 1, etc.
-However, this mapping can be freely reassigned by modifying the corresponding enable/phase mappings (e.g., {{< regref "CLASSA_CTRL_SHADOWED.E0_MAP" >}} for enable bit 0 of class A).
+However, this mapping can be freely reassigned by modifying the corresponding enable/phase mappings (e.g., {{#regref alert_handler.CLASSA_CTRL_SHADOWED.E0_MAP }} for enable bit 0 of class A).
This mapping will be locked in together with the alert enable configuration after initial configuration.
-SW can stop a triggered escalation protocol by clearing the corresponding escalation counter (e.g., {{< regref "CLASSA_ESC_CNT" >}}).
-Protection of this clearing is up to software, see the register control section that follows for {{< regref "CLASSA_CTRL_SHADOWED.LOCK" >}}.
+SW can stop a triggered escalation protocol by clearing the corresponding escalation counter (e.g., {{#regref alert_handler.CLASSA_ESC_CNT }}).
+Protection of this clearing is up to software, see the register control section that follows for {{#regref alert_handler.CLASSA_CTRL_SHADOWED.LOCK }}.
It should be noted that each of the escalation phases have a duration of at least 1 clock cycle, even if the cycle count of a particular phase has been
set to 0.
@@ -818,7 +818,7 @@
It is consequently possible for a group of alert senders to already be in reset or clock gated state, while the corresponding LPG logic does not yet know about this state change - and vice versa.
In practice, this means that ping requests may be pending for several cycles until the LPG logic detects a reset or clock-gated condition and disables the corresponding alert channel(s).
-Fortunately, such delay can be tolerated by setting the ping timeout to a sufficiently large value (see {{< regref "CLASSA_TIMEOUT_CYC_SHADOWED" >}}).
+Fortunately, such delay can be tolerated by setting the ping timeout to a sufficiently large value (see {{#regref alert_handler.CLASSA_TIMEOUT_CYC_SHADOWED }}).
As for alert events, this latency difference should not pose a problem.
Alert events may get stuck in the alert sender due to a reset or clock-gated condition - but this is to be expected.
@@ -876,44 +876,44 @@
1. For each alert and each local alert:
- Determine if alert is enabled (should only be false if alert is known to be faulty).
- Set {{< regref "ALERT_EN_SHADOWED_0.EN_A_0" >}} and {{< regref "LOC_ALERT_EN_SHADOWED_0.EN_LA_0" >}} accordingly.
+ Set {{#regref alert_handler.ALERT_EN_SHADOWED_0.EN_A_0 }} and {{#regref alert_handler.LOC_ALERT_EN_SHADOWED_0.EN_LA_0 }} accordingly.
- Determine which class (A..D) the alert is associated with.
- Set {{< regref "ALERT_CLASS_SHADOWED_0.CLASS_A_0" >}} and {{< regref "LOC_ALERT_CLASS_SHADOWED_0.CLASS_LA_0" >}} accordingly.
+ Set {{#regref alert_handler.ALERT_CLASS_SHADOWED_0.CLASS_A_0 }} and {{#regref alert_handler.LOC_ALERT_CLASS_SHADOWED_0.CLASS_LA_0 }} accordingly.
- - Optionally lock each alert configuration by writing 0 to {{< regref "ALERT_REGWEN_0.EN_0" >}} or {{< regref "LOC_ALERT_REGWEN_0.EN_0" >}}.
+ - Optionally lock each alert configuration by writing 0 to {{#regref alert_handler.ALERT_REGWEN_0.EN_0 }} or {{#regref alert_handler.LOC_ALERT_REGWEN_0.EN_0 }}.
Note however that only **locked and enabled** alerts are going to be pinged using the ping mechanism.
This ensures that spurious ping failures cannot occur when previously enabled alerts are being disabled again (before locking).
-2. Set the ping timeout value {{< regref "PING_TIMEOUT_CYC_SHADOWED" >}}.
+2. Set the ping timeout value {{#regref alert_handler.PING_TIMEOUT_CYC_SHADOWED }}.
This value is dependent on the clock ratios present in the system.
3. For each class (A..D):
- - Determine whether to enable escalation mechanisms (accumulation / interrupt timeout) for this particular class. Set {{< regref "CLASSA_CTRL_SHADOWED.EN" >}} accordingly.
+ - Determine whether to enable escalation mechanisms (accumulation / interrupt timeout) for this particular class. Set {{#regref alert_handler.CLASSA_CTRL_SHADOWED.EN }} accordingly.
- Determine if this class of alerts allows clearing of escalation once it has begun.
- Set {{< regref "CLASSA_CTRL_SHADOWED.LOCK" >}} to true if clearing should be disabled.
+ Set {{#regref alert_handler.CLASSA_CTRL_SHADOWED.LOCK }} to true if clearing should be disabled.
If true, once escalation protocol begins, it can not be stopped, the assumption being that it ends in a chip reset else it will be rendered useless thenceforth.
- - Determine the number of alerts required to be accumulated before escalation protocol kicks in. Set {{< regref "CLASSA_ACCUM_THRESH" >}} accordingly.
+ - Determine the number of alerts required to be accumulated before escalation protocol kicks in. Set {{#regref alert_handler.CLASSA_ACCUM_THRESH }} accordingly.
- Determine whether the interrupt associated with that class needs a timeout.
- If yes, set {{< regref "CLASSA_TIMEOUT_CYC_SHADOWED" >}} to an appropriate value greater than zero (zero corresponds to an infinite timeout and disables the mechanism).
+ If yes, set {{#regref alert_handler.CLASSA_TIMEOUT_CYC_SHADOWED }} to an appropriate value greater than zero (zero corresponds to an infinite timeout and disables the mechanism).
- For each escalation phase (0..3):
- - Determine length of each escalation phase by setting {{< regref "CLASSA_PHASE0_CYC" >}} accordingly
+ - Determine length of each escalation phase by setting {{#regref alert_handler.CLASSA_PHASE0_CYC }} accordingly
- For each escalation signal (0..3):
- - Determine whether to enable the escalation signal, and set the {{< regref "CLASSA_CTRL_SHADOWED.E0_EN" >}} bit accordingly (default is enabled).
- Note that setting all of the `E*_EN` bits to 0 within a class has the same effect of disabling the entire class by setting {{< regref "CLASSA_CTRL_SHADOWED.EN" >}} to zero.
- - Determine the phase -> escalation mapping of this class and program it via the {{< regref "CLASSA_CTRL_SHADOWED.E0_MAP" >}} values if it needs to be changed from the default mapping (0->0, 1->1, 2->2, 3->3).
+ - Determine whether to enable the escalation signal, and set the {{#regref alert_handler.CLASSA_CTRL_SHADOWED.E0_EN }} bit accordingly (default is enabled).
+ Note that setting all of the `E*_EN` bits to 0 within a class has the same effect of disabling the entire class by setting {{#regref alert_handler.CLASSA_CTRL_SHADOWED.EN }} to zero.
+ - Determine the phase -> escalation mapping of this class and program it via the {{#regref alert_handler.CLASSA_CTRL_SHADOWED.E0_MAP }} values if it needs to be changed from the default mapping (0->0, 1->1, 2->2, 3->3).
- - Optionally lock the class configuration by writing 0 to {{< regref "CLASSA_CTRL_SHADOWED.REGWEN" >}}.
+ - Optionally lock the class configuration by writing 0 to {{#regref alert_handler.CLASSA_CTRL_SHADOWED.REGWEN }}.
-4. After initial configuration at startup, enable the ping timer mechanism by writing 1 to {{< regref "PING_TIMER_EN" >}}.
-It is also recommended to lock the ping timer configuration by clearing {{< regref "PING_TIMER_REGWEN" >}}.
+4. After initial configuration at startup, enable the ping timer mechanism by writing 1 to {{#regref alert_handler.PING_TIMER_EN }}.
+It is also recommended to lock the ping timer configuration by clearing {{#regref alert_handler.PING_TIMER_REGWEN }}.
Note that only **locked and enabled** alerts are going to be pinged using the ping mechanism.
This ensures that spurious ping failures cannot occur when previously enabled alerts are being disabled again (before locking).
@@ -922,12 +922,12 @@
For every alert that is enabled, an interrupt will be triggered on class A, B, C, or D.
To handle an interrupt of a particular class, software should execute the following steps:
-1. If needed, check the escalation state of this class by reading {{< regref "CLASSA_STATE" >}}.
+1. If needed, check the escalation state of this class by reading {{#regref alert_handler.CLASSA_STATE }}.
This reveals whether escalation protocol has been triggered and in which escalation phase the class is.
In case interrupt timeouts are enabled the class will be in timeout state unless escalation has already been triggered.
- The current interrupt or escalation cycle counter can be read via {{< regref "CLASSA_ESC_CNT" >}}.
+ The current interrupt or escalation cycle counter can be read via {{#regref alert_handler.CLASSA_ESC_CNT }}.
-2. Since the interrupt does not indicate which alert triggered, SW must read the cause registers {{< regref "LOC_ALERT_CAUSE" >}} and {{< regref "ALERT_CAUSE" >}} etc.
+2. Since the interrupt does not indicate which alert triggered, SW must read the cause registers {{#regref alert_handler.LOC_ALERT_CAUSE }} and {{#regref alert_handler.ALERT_CAUSE }} etc.
The cause bits of all alerts are concatenated and chunked into 32bit words.
Hence the register file contains as many cause words as needed to cover all alerts present in the system.
Each cause register contains a sticky bit that is set by the incoming alert, and is clearable with a write by software.
@@ -938,12 +938,12 @@
3. After the event is cleared (if needed or possible), software should handle the interrupt as follows:
- - Resetting the accumulation register for the class by writing {{< regref "CLASSA_CLR" >}}.
+ - Resetting the accumulation register for the class by writing {{#regref alert_handler.CLASSA_CLR }}.
This also aborts the escalation protocol if it has been triggered.
- If for some reason it is desired to never allow the accumulator or escalation to be cleared, software can initialize the {{< regref "CLASSA_CLR_REGWEN" >}} register to zero.
- If {{< regref "CLASSA_CLR_REGWEN" >}} is already false when an alert interrupt is detected (either due to software control or hardware trigger via {{< regref "CLASSA_CTRL_SHADOWED.LOCK" >}}), then the accumulation counter can not be cleared and this step has no effect.
+ If for some reason it is desired to never allow the accumulator or escalation to be cleared, software can initialize the {{#regref alert_handler.CLASSA_CLR_REGWEN }} register to zero.
+ If {{#regref alert_handler.CLASSA_CLR_REGWEN }} is already false when an alert interrupt is detected (either due to software control or hardware trigger via {{#regref alert_handler.CLASSA_CTRL_SHADOWED.LOCK }}), then the accumulation counter can not be cleared and this step has no effect.
- - After the accumulation counter is reset (if applicable), software should clear the class A interrupt state bit {{< regref "INTR_STATE.CLASSA" >}}.
+ - After the accumulation counter is reset (if applicable), software should clear the class A interrupt state bit {{#regref alert_handler.INTR_STATE.CLASSA }}.
Clearing the class A interrupt state bit also clears and stops the interrupt timeout counter (if enabled).
Note that testing interrupts by writing to the interrupt test registers does also trigger the internal interrupt timeout (if enabled), since the interrupt state is used as enable signal for the timer.
@@ -955,7 +955,7 @@
## Register Table
-{{< incGenFromIpDesc "../data/alert_handler.hjson" "registers" >}}
+* [Register Table](../../top_earlgrey/ip_autogen/alert_handler/data/alert_handler.hjson#registers)
# Additional Notes
diff --git a/hw/ip_templates/rv_plic/README.md b/hw/ip_templates/rv_plic/README.md
index 40976b1..5d03af0 100644
--- a/hw/ip_templates/rv_plic/README.md
+++ b/hw/ip_templates/rv_plic/README.md
@@ -33,7 +33,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/rv_plic.hjson" "hwcfg" >}}
+* [Interface Tables](../../top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson#interfaces)
## Design Details
@@ -50,7 +50,7 @@
Interrupt sources have configurable priority values. The maximum value of the
priority is configurable through the localparam `MAX_PRIO` in the rv_plic
-top-level module. For each target there is a threshold value ({{< regref "THRESHOLD0" >}} for
+top-level module. For each target there is a threshold value ({{#regref rv_plic.THRESHOLD0 }} for
target 0). RV_PLIC notifies a target of an interrupt only if it's priority is
strictly greater than the target's threshold. Note this means an interrupt with
a priority is 0 is effectively prevented from causing an interrupt at any target
@@ -70,25 +70,25 @@
The choice is a system-integration decision and can be configured via the design parameter `LevelEdgeTrig` for each interrupt request.
When the gateway detects an interrupt event it raises the interrupt pending bit
-({{< regref "IP" >}}) for that interrupt source. When an interrupt is claimed by a target the
-relevant bit of {{< regref "IP" >}} is cleared. A bit in {{< regref "IP" >}} will not be reasserted until the
+({{#regref rv_plic.IP }}) for that interrupt source. When an interrupt is claimed by a target the
+relevant bit of {{#regref rv_plic.IP }} is cleared. A bit in {{#regref rv_plic.IP }} will not be reasserted until the
target signals completion of the interrupt. Any new interrupt event between a
-bit in {{< regref "IP" >}} asserting and completing that interrupt is ignored. In particular
+bit in {{#regref rv_plic.IP }} asserting and completing that interrupt is ignored. In particular
this means that for edge triggered interrupts if a new edge is seen after the
-source's {{< regref "IP" >}} bit is asserted but before completion, that edge will be ignored
+source's {{#regref rv_plic.IP }} bit is asserted but before completion, that edge will be ignored
(counting missed edges as discussed in the RISC-V PLIC specification is not
supported).
Note that there is no ability for a level triggered interrupt to be cancelled.
-If the interrupt drops after the gateway has set a bit in {{< regref "IP" >}}, the bit will
+If the interrupt drops after the gateway has set a bit in {{#regref rv_plic.IP }}, the bit will
remain set until the interrupt is completed. The SW handler should be conscious
of this and check the interrupt still requires handling in the handler if this
behaviour is possible.
### Interrupt Enables
-Each target has a set of Interrupt Enable ({{< regref "IE0" >}} for target 0) registers. Each
-bit in the {{< regref "IE0" >}} registers controls the corresponding interrupt source. If an
+Each target has a set of Interrupt Enable ({{#regref rv_plic.IE0 }} for target 0) registers. Each
+bit in the {{#regref rv_plic.IE0 }} registers controls the corresponding interrupt source. If an
interrupt source is disabled for a target, then interrupt events from that
source won't trigger an interrupt at the target. RV_PLIC doesn't have a global
interrupt disable feature.
@@ -96,23 +96,23 @@
### Interrupt Claims
"Claiming" an interrupt is done by a target reading the associated
-Claim/Completion register for the target ({{< regref "CC0" >}} for target 0). The return value
-of the {{< regref "CC0" >}} read represents the ID of the pending interrupt that has the
+Claim/Completion register for the target ({{#regref rv_plic.CC0 }} for target 0). The return value
+of the {{#regref rv_plic.CC0 }} read represents the ID of the pending interrupt that has the
highest priority. If two or more pending interrupts have the same priority,
RV_PLIC chooses the one with lowest ID. Only interrupts that that are enabled
for the target can be claimed. The target priority threshold doesn't matter
(this only factors into whether an interrupt is signalled to the target) so
-lower priority interrupt IDs can be returned on a read from {{< regref "CC0" >}}. If no
+lower priority interrupt IDs can be returned on a read from {{#regref rv_plic.CC0 }}. If no
interrupt is pending (or all pending interrupts are disabled for the target) a
-read of {{< regref "CC0" >}} returns an ID of 0.
+read of {{#regref rv_plic.CC0 }} returns an ID of 0.
### Interrupt Completion
-After an interrupt is claimed, the relevant bit of interrupt pending ({{< regref "IP" >}}) is
+After an interrupt is claimed, the relevant bit of interrupt pending ({{#regref rv_plic.IP }}) is
cleared, regardless of the status of the `intr_src_i` input value. Until a
target "completes" the interrupt, it won't be re-asserted if a new event for the
interrupt occurs. A target completes the interrupt by writing the ID of the
-interrupt to the Claim/Complete register ({{< regref "CC0" >}} for target 0). The write event
+interrupt to the Claim/Complete register ({{#regref rv_plic.CC0 }} for target 0). The write event
is forwarded to the Gateway logic, which resets the interrupt status to accept a
new interrupt event. The assumption is that the processor has cleaned up the
originating interrupt event during the time between claim and complete such that
@@ -153,7 +153,7 @@
interrupt sources are set, as all priorities and thresholds are 0 by default and
all ``IE`` values are 0. Software should configure the above three registers.
-{{< regref "PRIO0" >}} .. {{< regref "PRIO31" >}} registers are unique. So, only one of the targets
+{{#regref rv_plic.PRIO0 }} .. {{#regref rv_plic.PRIO31 }} registers are unique. So, only one of the targets
shall configure them.
```c
@@ -181,14 +181,14 @@
## Handling Interrupt Request Events
If software receives an interrupt request, it is recommended to follow the steps
-shown below (assuming target 0 which uses {{< regref "CC0" >}} for claim/complete).
+shown below (assuming target 0 which uses {{#regref rv_plic.CC0 }} for claim/complete).
1. Claim the interrupts right after entering to the interrupt service routine
- by reading the {{< regref "CC0" >}} register.
+ by reading the {{#regref rv_plic.CC0 }} register.
2. Determine which interrupt should be serviced based on the values read from
- the {{< regref "CC0" >}} register.
+ the {{#regref rv_plic.CC0 }} register.
3. Execute ISR, clearing the originating peripheral interrupt.
-4. Write Interrupt ID to {{< regref "CC0" >}}
+4. Write Interrupt ID to {{#regref rv_plic.CC0 }}
5. Repeat as necessary for other pending interrupts.
It is possible to have multiple interrupt events claimed. If software claims one
@@ -244,4 +244,4 @@
- CC: N_TARGET
Claim by read, complete by write
-{{< incGenFromIpDesc "../data/rv_plic.hjson" "registers" >}}
+* [Register Table](../../top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson#interfaces)
diff --git a/hw/top_earlgrey/ip/sensor_ctrl/README.md b/hw/top_earlgrey/ip/sensor_ctrl/README.md
index 55aa888..5809525 100644
--- a/hw/top_earlgrey/ip/sensor_ctrl/README.md
+++ b/hw/top_earlgrey/ip/sensor_ctrl/README.md
@@ -34,11 +34,11 @@
The `sensor control` can optionally generate alert acknowledgements back to the `analog sensor top`.
-For each incoming alert, it can be programmed as fatal or recoverable through {{< regref "FATAL_ALERT_EN" >}}.
-If set to recoverable, an alert will be registered in {{< regref "RECOV_ALERT" >}} and the original `analog sensor top` event acknowledged.
+For each incoming alert, it can be programmed as fatal or recoverable through {{#regref sensor_ctrl.FATAL_ALERT_EN }}.
+If set to recoverable, an alert will be registered in {{#regref sensor_ctrl.RECOV_ALERT }} and the original `analog sensor top` event acknowledged.
The acknowledgement prevents alerts from constantly being sent.
-If set to fatal, an alert will be registered in {{< regref "FATAL_ALERT" >}} but the original `analog sensor top` event will not be acknowledged.
+If set to fatal, an alert will be registered in {{#regref sensor_ctrl.FATAL_ALERT }} but the original `analog sensor top` event will not be acknowledged.
This causes the alert to constantly send until the system escalates in some form.
## Wakeup Requests
@@ -53,12 +53,12 @@
### Signals
-{{< incGenFromIpDesc "../data/sensor_ctrl.hjson" "hwcfg" >}}
+* [Interface Tables](data/sensor_ctrl.hjson#interfaces)
# Programmer's Guide
Each available alert has a corresponding fatality configuration.
-If an alert event is set to 1 in {{< regref "FATAL_ALERT_EN" >}}, `sensor control` treats it as a fatal event instead of a recoverable event.
+If an alert event is set to 1 in {{#regref sensor_ctrl.FATAL_ALERT_EN }}, `sensor control` treats it as a fatal event instead of a recoverable event.
Fatal events are not acknowledged, and continuously send alert events in the system until some kind of escalation is seen.
## Device Interface Functions (DIFs)
@@ -67,4 +67,4 @@
## Register Table
-{{< incGenFromIpDesc "../data/sensor_ctrl.hjson" "registers" >}}
+* [Register Table](data/sensor_ctrl.hjson#register)
diff --git a/hw/top_earlgrey/ip_autogen/alert_handler/README.md b/hw/top_earlgrey/ip_autogen/alert_handler/README.md
index 7384839..f26ed64 100644
--- a/hw/top_earlgrey/ip_autogen/alert_handler/README.md
+++ b/hw/top_earlgrey/ip_autogen/alert_handler/README.md
@@ -111,7 +111,7 @@
### Signals
-{{< incGenFromIpDesc "../data/alert_handler.hjson" "hwcfg" >}}
+* [Interface Tables](data/alert_handler.hjson#interfaces)
The table below lists other alert handler module signals.
The number of alert instances is parametric and hence alert and ping diff pairs are grouped together in packed arrays.
@@ -174,7 +174,7 @@
This can be useful for extracting more information about possible failures or bugs without having to use the tile-link bus interface (which may become unresponsive under certain circumstances).
It is recommended for the top level to store this information in an always-on location.
-Note that the crashdump state is continuously output via `crashdump_o` until the latching trigger condition is true for the first time (see {{< regref CLASSA_CRASHDUMP_TRIGGER_SHADOWED >}}).
+Note that the crashdump state is continuously output via `crashdump_o` until the latching trigger condition is true for the first time (see {{#regref alert_handler.CLASSA_CRASHDUMP_TRIGGER_SHADOWED }}).
After that, the `crashdump_o` is held constant until all classes that have escalated are cleared.
This is done so that it is possible to capture the true alert cause before spurious alert events start to pop up due to escalation countermeasures with excessive side effects (like life cycle scrapping for example).
If classes that have escalated are not configured as clearable, then it is not possible to re-arm the crashdump latching mechanism at runtime and the alert handler has to be reset.
@@ -386,7 +386,7 @@
In both cases, the LFSR timer proceeds with the next ping, but in the second case it will additionally raise a "pingfail" alert.
The ping enable signal remains asserted during the time where the LFSR counter waits.
-The timeout value is a function of the ratios between the alert handler clock and peripheral clocks present in the system, and can be programmed at startup time via the register {{< regref "PING_TIMEOUT_CYC_SHADOWED" >}}.
+The timeout value is a function of the ratios between the alert handler clock and peripheral clocks present in the system, and can be programmed at startup time via the register {{#regref alert_handler.PING_TIMEOUT_CYC_SHADOWED }}.
Note that the ping timer directly flags a "pingfail" alert if a spurious "ping ok" message comes in that has not been requested.
@@ -444,20 +444,20 @@
- Accumulation max value.
This is the total number (sum of all alerts classified in this group) of alerts required to enter escalation phase (see below).
- Example register is {{< regref "CLASSA_ACCUM_THRESH_SHADOWED" >}}.
+ Example register is {{#regref alert_handler.CLASSA_ACCUM_THRESH_SHADOWED }}.
- Current accumulation register.
This clearable register indicates how many alerts have been accumulated to date.
Software should clear before it reaches the accumulation setting to avoid escalation.
- Example register is {{< regref "CLASSA_ACCUM_CNT" >}}.
+ Example register is {{#regref alert_handler.CLASSA_ACCUM_CNT }}.
2. The second way is an interrupt timeout counter which triggers escalation if an alert interrupt is not handled within the programmable timeout window.
Once the counter hits the timeout threshold, the escalation protocol is triggered.
The corresponding CSRs are:
- - Interrupt timeout value in cycles {{< regref "CLASSA_TIMEOUT_CYC_SHADOWED" >}}.
+ - Interrupt timeout value in cycles {{#regref alert_handler.CLASSA_TIMEOUT_CYC_SHADOWED }}.
The interrupt timeout is disabled if this is set to 0 (default).
- - The current interrupt timeout value can be read via {{< regref "CLASSA_ESC_CNT" >}} if {{< regref "CLASSA_STATE" >}} is in the `Timeout` state.
- Software should clear the corresponding interrupt state bit {{< regref "INTR_STATE.CLASSA" >}} before the timeout expires to avoid escalation.
+ - The current interrupt timeout value can be read via {{#regref alert_handler.CLASSA_ESC_CNT }} if {{#regref alert_handler.CLASSA_STATE }} is in the `Timeout` state.
+ Software should clear the corresponding interrupt state bit {{#regref alert_handler.INTR_STATE.CLASSA }} before the timeout expires to avoid escalation.
Technically, the interrupt timeout feature (2. above) is implemented using the same counter used to time the escalation phases.
This is possible since escalation phases or interrupt timeout periods are non-overlapping (escalation always takes precedence should it be triggered).
@@ -474,13 +474,13 @@
Each class can be programmed with its own escalation protocol.
If one of the two mechanisms described above fires, a timer for that particular class is started.
-The timer can be programmed with up to 4 delays (e.g., {{< regref "CLASSA_PHASE0_CYC" >}}), each representing a distinct escalation phase (0 - 3).
+The timer can be programmed with up to 4 delays (e.g., {{#regref alert_handler.CLASSA_PHASE0_CYC }}), each representing a distinct escalation phase (0 - 3).
Each of the four escalation severity outputs (0 - 3) are by default configured to be asserted during the corresponding phase, e.g., severity 0 in phase 0, severity 1 in phase 1, etc.
-However, this mapping can be freely reassigned by modifying the corresponding enable/phase mappings (e.g., {{< regref "CLASSA_CTRL_SHADOWED.E0_MAP" >}} for enable bit 0 of class A).
+However, this mapping can be freely reassigned by modifying the corresponding enable/phase mappings (e.g., {{#regref alert_handler.CLASSA_CTRL_SHADOWED.E0_MAP }} for enable bit 0 of class A).
This mapping will be locked in together with the alert enable configuration after initial configuration.
-SW can stop a triggered escalation protocol by clearing the corresponding escalation counter (e.g., {{< regref "CLASSA_ESC_CNT" >}}).
-Protection of this clearing is up to software, see the register control section that follows for {{< regref "CLASSA_CTRL_SHADOWED.LOCK" >}}.
+SW can stop a triggered escalation protocol by clearing the corresponding escalation counter (e.g., {{#regref alert_handler.CLASSA_ESC_CNT }}).
+Protection of this clearing is up to software, see the register control section that follows for {{#regref alert_handler.CLASSA_CTRL_SHADOWED.LOCK }}.
It should be noted that each of the escalation phases have a duration of at least 1 clock cycle, even if the cycle count of a particular phase has been
set to 0.
@@ -818,7 +818,7 @@
It is consequently possible for a group of alert senders to already be in reset or clock gated state, while the corresponding LPG logic does not yet know about this state change - and vice versa.
In practice, this means that ping requests may be pending for several cycles until the LPG logic detects a reset or clock-gated condition and disables the corresponding alert channel(s).
-Fortunately, such delay can be tolerated by setting the ping timeout to a sufficiently large value (see {{< regref "CLASSA_TIMEOUT_CYC_SHADOWED" >}}).
+Fortunately, such delay can be tolerated by setting the ping timeout to a sufficiently large value (see {{#regref alert_handler.CLASSA_TIMEOUT_CYC_SHADOWED }}).
As for alert events, this latency difference should not pose a problem.
Alert events may get stuck in the alert sender due to a reset or clock-gated condition - but this is to be expected.
@@ -876,44 +876,44 @@
1. For each alert and each local alert:
- Determine if alert is enabled (should only be false if alert is known to be faulty).
- Set {{< regref "ALERT_EN_SHADOWED_0.EN_A_0" >}} and {{< regref "LOC_ALERT_EN_SHADOWED_0.EN_LA_0" >}} accordingly.
+ Set {{#regref alert_handler.ALERT_EN_SHADOWED_0.EN_A_0 }} and {{#regref alert_handler.LOC_ALERT_EN_SHADOWED_0.EN_LA_0 }} accordingly.
- Determine which class (A..D) the alert is associated with.
- Set {{< regref "ALERT_CLASS_SHADOWED_0.CLASS_A_0" >}} and {{< regref "LOC_ALERT_CLASS_SHADOWED_0.CLASS_LA_0" >}} accordingly.
+ Set {{#regref alert_handler.ALERT_CLASS_SHADOWED_0.CLASS_A_0 }} and {{#regref alert_handler.LOC_ALERT_CLASS_SHADOWED_0.CLASS_LA_0 }} accordingly.
- - Optionally lock each alert configuration by writing 0 to {{< regref "ALERT_REGWEN_0.EN_0" >}} or {{< regref "LOC_ALERT_REGWEN_0.EN_0" >}}.
+ - Optionally lock each alert configuration by writing 0 to {{#regref alert_handler.ALERT_REGWEN_0.EN_0 }} or {{#regref alert_handler.LOC_ALERT_REGWEN_0.EN_0 }}.
Note however that only **locked and enabled** alerts are going to be pinged using the ping mechanism.
This ensures that spurious ping failures cannot occur when previously enabled alerts are being disabled again (before locking).
-2. Set the ping timeout value {{< regref "PING_TIMEOUT_CYC_SHADOWED" >}}.
+2. Set the ping timeout value {{#regref alert_handler.PING_TIMEOUT_CYC_SHADOWED }}.
This value is dependent on the clock ratios present in the system.
3. For each class (A..D):
- - Determine whether to enable escalation mechanisms (accumulation / interrupt timeout) for this particular class. Set {{< regref "CLASSA_CTRL_SHADOWED.EN" >}} accordingly.
+ - Determine whether to enable escalation mechanisms (accumulation / interrupt timeout) for this particular class. Set {{#regref alert_handler.CLASSA_CTRL_SHADOWED.EN }} accordingly.
- Determine if this class of alerts allows clearing of escalation once it has begun.
- Set {{< regref "CLASSA_CTRL_SHADOWED.LOCK" >}} to true if clearing should be disabled.
+ Set {{#regref alert_handler.CLASSA_CTRL_SHADOWED.LOCK }} to true if clearing should be disabled.
If true, once escalation protocol begins, it can not be stopped, the assumption being that it ends in a chip reset else it will be rendered useless thenceforth.
- - Determine the number of alerts required to be accumulated before escalation protocol kicks in. Set {{< regref "CLASSA_ACCUM_THRESH" >}} accordingly.
+ - Determine the number of alerts required to be accumulated before escalation protocol kicks in. Set {{#regref alert_handler.CLASSA_ACCUM_THRESH }} accordingly.
- Determine whether the interrupt associated with that class needs a timeout.
- If yes, set {{< regref "CLASSA_TIMEOUT_CYC_SHADOWED" >}} to an appropriate value greater than zero (zero corresponds to an infinite timeout and disables the mechanism).
+ If yes, set {{#regref alert_handler.CLASSA_TIMEOUT_CYC_SHADOWED }} to an appropriate value greater than zero (zero corresponds to an infinite timeout and disables the mechanism).
- For each escalation phase (0..3):
- - Determine length of each escalation phase by setting {{< regref "CLASSA_PHASE0_CYC" >}} accordingly
+ - Determine length of each escalation phase by setting {{#regref alert_handler.CLASSA_PHASE0_CYC }} accordingly
- For each escalation signal (0..3):
- - Determine whether to enable the escalation signal, and set the {{< regref "CLASSA_CTRL_SHADOWED.E0_EN" >}} bit accordingly (default is enabled).
- Note that setting all of the `E*_EN` bits to 0 within a class has the same effect of disabling the entire class by setting {{< regref "CLASSA_CTRL_SHADOWED.EN" >}} to zero.
- - Determine the phase -> escalation mapping of this class and program it via the {{< regref "CLASSA_CTRL_SHADOWED.E0_MAP" >}} values if it needs to be changed from the default mapping (0->0, 1->1, 2->2, 3->3).
+ - Determine whether to enable the escalation signal, and set the {{#regref alert_handler.CLASSA_CTRL_SHADOWED.E0_EN }} bit accordingly (default is enabled).
+ Note that setting all of the `E*_EN` bits to 0 within a class has the same effect of disabling the entire class by setting {{#regref alert_handler.CLASSA_CTRL_SHADOWED.EN }} to zero.
+ - Determine the phase -> escalation mapping of this class and program it via the {{#regref alert_handler.CLASSA_CTRL_SHADOWED.E0_MAP }} values if it needs to be changed from the default mapping (0->0, 1->1, 2->2, 3->3).
- - Optionally lock the class configuration by writing 0 to {{< regref "CLASSA_CTRL_SHADOWED.REGWEN" >}}.
+ - Optionally lock the class configuration by writing 0 to {{#regref alert_handler.CLASSA_CTRL_SHADOWED.REGWEN }}.
-4. After initial configuration at startup, enable the ping timer mechanism by writing 1 to {{< regref "PING_TIMER_EN" >}}.
-It is also recommended to lock the ping timer configuration by clearing {{< regref "PING_TIMER_REGWEN" >}}.
+4. After initial configuration at startup, enable the ping timer mechanism by writing 1 to {{#regref alert_handler.PING_TIMER_EN }}.
+It is also recommended to lock the ping timer configuration by clearing {{#regref alert_handler.PING_TIMER_REGWEN }}.
Note that only **locked and enabled** alerts are going to be pinged using the ping mechanism.
This ensures that spurious ping failures cannot occur when previously enabled alerts are being disabled again (before locking).
@@ -922,12 +922,12 @@
For every alert that is enabled, an interrupt will be triggered on class A, B, C, or D.
To handle an interrupt of a particular class, software should execute the following steps:
-1. If needed, check the escalation state of this class by reading {{< regref "CLASSA_STATE" >}}.
+1. If needed, check the escalation state of this class by reading {{#regref alert_handler.CLASSA_STATE }}.
This reveals whether escalation protocol has been triggered and in which escalation phase the class is.
In case interrupt timeouts are enabled the class will be in timeout state unless escalation has already been triggered.
- The current interrupt or escalation cycle counter can be read via {{< regref "CLASSA_ESC_CNT" >}}.
+ The current interrupt or escalation cycle counter can be read via {{#regref alert_handler.CLASSA_ESC_CNT }}.
-2. Since the interrupt does not indicate which alert triggered, SW must read the cause registers {{< regref "LOC_ALERT_CAUSE" >}} and {{< regref "ALERT_CAUSE" >}} etc.
+2. Since the interrupt does not indicate which alert triggered, SW must read the cause registers {{#regref alert_handler.LOC_ALERT_CAUSE }} and {{#regref alert_handler.ALERT_CAUSE }} etc.
The cause bits of all alerts are concatenated and chunked into 32bit words.
Hence the register file contains as many cause words as needed to cover all alerts present in the system.
Each cause register contains a sticky bit that is set by the incoming alert, and is clearable with a write by software.
@@ -938,12 +938,12 @@
3. After the event is cleared (if needed or possible), software should handle the interrupt as follows:
- - Resetting the accumulation register for the class by writing {{< regref "CLASSA_CLR" >}}.
+ - Resetting the accumulation register for the class by writing {{#regref alert_handler.CLASSA_CLR }}.
This also aborts the escalation protocol if it has been triggered.
- If for some reason it is desired to never allow the accumulator or escalation to be cleared, software can initialize the {{< regref "CLASSA_CLR_REGWEN" >}} register to zero.
- If {{< regref "CLASSA_CLR_REGWEN" >}} is already false when an alert interrupt is detected (either due to software control or hardware trigger via {{< regref "CLASSA_CTRL_SHADOWED.LOCK" >}}), then the accumulation counter can not be cleared and this step has no effect.
+ If for some reason it is desired to never allow the accumulator or escalation to be cleared, software can initialize the {{#regref alert_handler.CLASSA_CLR_REGWEN }} register to zero.
+ If {{#regref alert_handler.CLASSA_CLR_REGWEN }} is already false when an alert interrupt is detected (either due to software control or hardware trigger via {{#regref alert_handler.CLASSA_CTRL_SHADOWED.LOCK }}), then the accumulation counter can not be cleared and this step has no effect.
- - After the accumulation counter is reset (if applicable), software should clear the class A interrupt state bit {{< regref "INTR_STATE.CLASSA" >}}.
+ - After the accumulation counter is reset (if applicable), software should clear the class A interrupt state bit {{#regref alert_handler.INTR_STATE.CLASSA }}.
Clearing the class A interrupt state bit also clears and stops the interrupt timeout counter (if enabled).
Note that testing interrupts by writing to the interrupt test registers does also trigger the internal interrupt timeout (if enabled), since the interrupt state is used as enable signal for the timer.
@@ -955,7 +955,7 @@
## Register Table
-{{< incGenFromIpDesc "../data/alert_handler.hjson" "registers" >}}
+* [Register Table](data/alert_handler.hjson#registers)
# Additional Notes
diff --git a/hw/top_earlgrey/ip_autogen/rv_plic/README.md b/hw/top_earlgrey/ip_autogen/rv_plic/README.md
index ab88c37..1befbfc 100644
--- a/hw/top_earlgrey/ip_autogen/rv_plic/README.md
+++ b/hw/top_earlgrey/ip_autogen/rv_plic/README.md
@@ -33,7 +33,7 @@
## Hardware Interfaces
-{{< incGenFromIpDesc "../data/rv_plic.hjson" "hwcfg" >}}
+* [Interface Tables](data/rv_plic.hjson#interfaces)
## Design Details
@@ -50,7 +50,7 @@
Interrupt sources have configurable priority values. The maximum value of the
priority is configurable through the localparam `MAX_PRIO` in the rv_plic
-top-level module. For each target there is a threshold value ({{< regref "THRESHOLD0" >}} for
+top-level module. For each target there is a threshold value ({{#regref rv_plic.THRESHOLD0 }} for
target 0). RV_PLIC notifies a target of an interrupt only if it's priority is
strictly greater than the target's threshold. Note this means an interrupt with
a priority is 0 is effectively prevented from causing an interrupt at any target
@@ -70,25 +70,25 @@
The choice is a system-integration decision and can be configured via the design parameter `LevelEdgeTrig` for each interrupt request.
When the gateway detects an interrupt event it raises the interrupt pending bit
-({{< regref "IP" >}}) for that interrupt source. When an interrupt is claimed by a target the
-relevant bit of {{< regref "IP" >}} is cleared. A bit in {{< regref "IP" >}} will not be reasserted until the
+({{#regref rv_plic.IP }}) for that interrupt source. When an interrupt is claimed by a target the
+relevant bit of {{#regref rv_plic.IP }} is cleared. A bit in {{#regref rv_plic.IP }} will not be reasserted until the
target signals completion of the interrupt. Any new interrupt event between a
-bit in {{< regref "IP" >}} asserting and completing that interrupt is ignored. In particular
+bit in {{#regref rv_plic.IP }} asserting and completing that interrupt is ignored. In particular
this means that for edge triggered interrupts if a new edge is seen after the
-source's {{< regref "IP" >}} bit is asserted but before completion, that edge will be ignored
+source's {{#regref rv_plic.IP }} bit is asserted but before completion, that edge will be ignored
(counting missed edges as discussed in the RISC-V PLIC specification is not
supported).
Note that there is no ability for a level triggered interrupt to be cancelled.
-If the interrupt drops after the gateway has set a bit in {{< regref "IP" >}}, the bit will
+If the interrupt drops after the gateway has set a bit in {{#regref rv_plic.IP }}, the bit will
remain set until the interrupt is completed. The SW handler should be conscious
of this and check the interrupt still requires handling in the handler if this
behaviour is possible.
### Interrupt Enables
-Each target has a set of Interrupt Enable ({{< regref "IE0" >}} for target 0) registers. Each
-bit in the {{< regref "IE0" >}} registers controls the corresponding interrupt source. If an
+Each target has a set of Interrupt Enable ({{#regref rv_plic.IE0 }} for target 0) registers. Each
+bit in the {{#regref rv_plic.IE0 }} registers controls the corresponding interrupt source. If an
interrupt source is disabled for a target, then interrupt events from that
source won't trigger an interrupt at the target. RV_PLIC doesn't have a global
interrupt disable feature.
@@ -96,23 +96,23 @@
### Interrupt Claims
"Claiming" an interrupt is done by a target reading the associated
-Claim/Completion register for the target ({{< regref "CC0" >}} for target 0). The return value
-of the {{< regref "CC0" >}} read represents the ID of the pending interrupt that has the
+Claim/Completion register for the target ({{#regref rv_plic.CC0 }} for target 0). The return value
+of the {{#regref rv_plic.CC0 }} read represents the ID of the pending interrupt that has the
highest priority. If two or more pending interrupts have the same priority,
RV_PLIC chooses the one with lowest ID. Only interrupts that that are enabled
for the target can be claimed. The target priority threshold doesn't matter
(this only factors into whether an interrupt is signalled to the target) so
-lower priority interrupt IDs can be returned on a read from {{< regref "CC0" >}}. If no
+lower priority interrupt IDs can be returned on a read from {{#regref rv_plic.CC0 }}. If no
interrupt is pending (or all pending interrupts are disabled for the target) a
-read of {{< regref "CC0" >}} returns an ID of 0.
+read of {{#regref rv_plic.CC0 }} returns an ID of 0.
### Interrupt Completion
-After an interrupt is claimed, the relevant bit of interrupt pending ({{< regref "IP" >}}) is
+After an interrupt is claimed, the relevant bit of interrupt pending ({{#regref rv_plic.IP }}) is
cleared, regardless of the status of the `intr_src_i` input value. Until a
target "completes" the interrupt, it won't be re-asserted if a new event for the
interrupt occurs. A target completes the interrupt by writing the ID of the
-interrupt to the Claim/Complete register ({{< regref "CC0" >}} for target 0). The write event
+interrupt to the Claim/Complete register ({{#regref rv_plic.CC0 }} for target 0). The write event
is forwarded to the Gateway logic, which resets the interrupt status to accept a
new interrupt event. The assumption is that the processor has cleaned up the
originating interrupt event during the time between claim and complete such that
@@ -153,7 +153,7 @@
interrupt sources are set, as all priorities and thresholds are 0 by default and
all ``IE`` values are 0. Software should configure the above three registers.
-{{< regref "PRIO0" >}} .. {{< regref "PRIO31" >}} registers are unique. So, only one of the targets
+{{#regref rv_plic.PRIO0 }} .. {{#regref rv_plic.PRIO31 }} registers are unique. So, only one of the targets
shall configure them.
```c
@@ -181,14 +181,14 @@
## Handling Interrupt Request Events
If software receives an interrupt request, it is recommended to follow the steps
-shown below (assuming target 0 which uses {{< regref "CC0" >}} for claim/complete).
+shown below (assuming target 0 which uses {{#regref rv_plic.CC0 }} for claim/complete).
1. Claim the interrupts right after entering to the interrupt service routine
- by reading the {{< regref "CC0" >}} register.
+ by reading the {{#regref rv_plic.CC0 }} register.
2. Determine which interrupt should be serviced based on the values read from
- the {{< regref "CC0" >}} register.
+ the {{#regref rv_plic.CC0 }} register.
3. Execute ISR, clearing the originating peripheral interrupt.
-4. Write Interrupt ID to {{< regref "CC0" >}}
+4. Write Interrupt ID to {{#regref rv_plic.CC0 }}
5. Repeat as necessary for other pending interrupts.
It is possible to have multiple interrupt events claimed. If software claims one
@@ -244,4 +244,4 @@
- CC: N_TARGET
Claim by read, complete by write
-{{< incGenFromIpDesc "../data/rv_plic.hjson" "registers" >}}
+* [Register Table](data/rv_plic.hjson#registers)