From 726cd46d0a841adba93560c78c982c01582baa14 Mon Sep 17 00:00:00 2001 From: Alexander Williams Date: Fri, 13 Oct 2023 17:08:29 -0700 Subject: [PATCH] [spi_device] Remove generic mode Remove generic mode from spi_device. Generic mode has a very different timing model than the relatively high throughput, high latency flash and tpm modes. Generic mode requires data to be available on the MISO pin *before* the first SCK edge, whereas flash and tpm modes have a significant command phase that comes first. In addition, generic mode requires support for a number of different idle clock polarities and sampling phases, whereas flash and TPM modes have one clearly defined set. The complexity for supporting both timing models for one IP led to a compromised performance for flash and TPM. Remove generic mode here to permit optimizations that target the latter modes. Signed-off-by: Alexander Williams --- hw/ip/spi_device/data/spi_device.hjson | 299 +-- hw/ip/spi_device/doc/generic-blockdiagram.svg | 1 - hw/ip/spi_device/doc/interfaces.md | 6 - hw/ip/spi_device/doc/programmers_guide.md | 44 - hw/ip/spi_device/doc/registers.md | 563 ++--- hw/ip/spi_device/doc/rxf_ctrl_fsm.svg | 1 - hw/ip/spi_device/doc/rxf_ctrl_fsm_table.png | Bin 110916 -> 0 bytes hw/ip/spi_device/doc/theory_of_operation.md | 339 +-- hw/ip/spi_device/doc/txf_ctrl_dp.svg | 1 - hw/ip/spi_device/doc/txf_ctrl_fsm_table.png | Bin 80965 -> 0 bytes .../dv/env/seq_lib/spi_device_abort_vseq.sv | 37 - .../dv/env/seq_lib/spi_device_base_vseq.sv | 343 --- .../seq_lib/spi_device_bit_transfer_vseq.sv | 78 - .../seq_lib/spi_device_byte_transfer_vseq.sv | 18 - .../spi_device_dummy_item_extra_dly_vseq.sv | 33 - .../spi_device_extreme_fifo_size_vseq.sv | 35 - .../env/seq_lib/spi_device_fifo_full_vseq.sv | 32 - ...spi_device_fifo_underflow_overflow_vseq.sv | 55 - .../dv/env/seq_lib/spi_device_intr_vseq.sv | 190 -- .../dv/env/seq_lib/spi_device_perf_vseq.sv | 24 - .../spi_device_rx_async_fifo_reset_vseq.sv | 67 - .../env/seq_lib/spi_device_rx_timeout_vseq.sv | 76 - .../dv/env/seq_lib/spi_device_smoke_vseq.sv | 46 - .../env/seq_lib/spi_device_stress_all_vseq.sv | 8 +- .../spi_device_tx_async_fifo_reset_vseq.sv | 48 - .../dv/env/seq_lib/spi_device_txrx_vseq.sv | 252 --- .../dv/env/seq_lib/spi_device_vseq_list.sv | 14 - hw/ip/spi_device/dv/env/spi_device_env.core | 14 - hw/ip/spi_device/dv/env/spi_device_env_cfg.sv | 3 - hw/ip/spi_device/dv/env/spi_device_env_pkg.sv | 6 - .../dv/env/spi_device_scoreboard.sv | 135 +- hw/ip/spi_device/dv/spi_device_sim_cfg.hjson | 72 +- hw/ip/spi_device/dv/tb/tb.sv | 18 - hw/ip/spi_device/lint/spi_device.vlt | 7 - hw/ip/spi_device/lint/spi_device.waiver | 38 +- hw/ip/spi_device/rtl/spi_device.sv | 451 +--- hw/ip/spi_device/rtl/spi_device_pkg.sv | 19 +- hw/ip/spi_device/rtl/spi_device_reg_pkg.sv | 486 ++-- hw/ip/spi_device/rtl/spi_device_reg_top.sv | 1964 ++++------------- hw/ip/spi_device/rtl/spi_fwm_rxf_ctrl.sv | 275 --- hw/ip/spi_device/rtl/spi_fwm_txf_ctrl.sv | 241 -- hw/ip/spi_device/rtl/spi_fwmode.sv | 302 --- hw/ip/spi_device/spi_device.core | 3 - .../data/autogen/top_earlgrey.gen.hjson | 36 - .../data/ip/chip_spi_device_testplan.hjson | 35 - hw/top_earlgrey/dv/chip_sim_cfg.hjson | 8 +- hw/top_earlgrey/dv/env/chip_env.core | 1 - .../seq_lib/chip_sw_spi_device_tx_rx_vseq.sv | 79 - .../dv/env/seq_lib/chip_vseq_list.sv | 1 - .../ip_autogen/rv_plic/data/rv_plic.hjson | 50 +- .../data/top_earlgrey_rv_plic.ipconfig.hjson | 2 +- .../ip_autogen/rv_plic/rtl/rv_plic.sv | 10 +- .../ip_autogen/rv_plic/rtl/rv_plic_reg_pkg.sv | 446 ++-- .../ip_autogen/rv_plic/rtl/rv_plic_reg_top.sv | 736 +----- hw/top_earlgrey/rtl/autogen/top_earlgrey.sv | 248 +-- .../sw/autogen/chip/top_earlgrey.rs | 488 ++-- hw/top_earlgrey/sw/autogen/top_earlgrey.c | 8 +- hw/top_earlgrey/sw/autogen/top_earlgrey.h | 238 +- sw/device/examples/BUILD | 1 - sw/device/examples/demos.c | 13 - sw/device/examples/demos.h | 7 - sw/device/examples/hello_usbdev/BUILD | 1 - .../examples/hello_usbdev/hello_usbdev.c | 24 - sw/device/examples/hello_world/BUILD | 1 - sw/device/examples/hello_world/hello_world.c | 26 - .../lib/dif/autogen/dif_spi_device_autogen.c | 23 +- .../lib/dif/autogen/dif_spi_device_autogen.h | 36 +- .../dif_spi_device_autogen_unittest.cc | 59 +- sw/device/lib/dif/dif_rv_plic_unittest.cc | 6 +- sw/device/lib/dif/dif_spi_device.c | 538 +---- sw/device/lib/dif/dif_spi_device.h | 231 +- sw/device/lib/dif/dif_spi_device_unittest.cc | 928 +------- sw/device/lib/runtime/BUILD | 1 - sw/device/lib/runtime/print.c | 79 - sw/device/lib/runtime/print.h | 11 - .../lib/testing/test_framework/ottf_console.c | 13 +- .../silicon_creator/lib/drivers/spi_device.c | 1 - .../lib/drivers/spi_device_unittest.cc | 1 - .../silicon_owner/tock/tests/basic/BUILD | 4 + sw/device/tests/BUILD | 77 - sw/device/tests/autogen/plic_all_irqs_test.c | 4 +- sw/device/tests/rstmgr_sw_rst_ctrl_test.c | 11 +- sw/device/tests/sim_dv/BUILD | 19 - sw/device/tests/sim_dv/spi_passthrough_test.c | 15 +- sw/device/tests/sim_dv/spi_tx_rx_test.c | 370 ---- sw/device/tests/sival/BUILD | 1 - .../tests/spi_device_ottf_console_test.c | 22 - sw/device/tests/spi_device_smoketest.c | 403 ---- sw/device/tests/spi_device_tpm_tx_rx_test.c | 16 +- .../tests/chip/spi_device_ottf_console/BUILD | 22 - .../chip/spi_device_ottf_console/src/main.rs | 75 - sw/host/tests/chip/spi_device_smoketest/BUILD | 23 - .../chip/spi_device_smoketest/src/main.rs | 143 -- 93 files changed, 1569 insertions(+), 10666 deletions(-) delete mode 100644 hw/ip/spi_device/doc/generic-blockdiagram.svg delete mode 100644 hw/ip/spi_device/doc/rxf_ctrl_fsm.svg delete mode 100644 hw/ip/spi_device/doc/rxf_ctrl_fsm_table.png delete mode 100644 hw/ip/spi_device/doc/txf_ctrl_dp.svg delete mode 100644 hw/ip/spi_device/doc/txf_ctrl_fsm_table.png delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_abort_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_bit_transfer_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_byte_transfer_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_dummy_item_extra_dly_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_extreme_fifo_size_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_fifo_full_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_fifo_underflow_overflow_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_intr_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_perf_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_rx_async_fifo_reset_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_rx_timeout_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_smoke_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_tx_async_fifo_reset_vseq.sv delete mode 100644 hw/ip/spi_device/dv/env/seq_lib/spi_device_txrx_vseq.sv delete mode 100644 hw/ip/spi_device/rtl/spi_fwm_rxf_ctrl.sv delete mode 100644 hw/ip/spi_device/rtl/spi_fwm_txf_ctrl.sv delete mode 100644 hw/ip/spi_device/rtl/spi_fwmode.sv delete mode 100644 hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tx_rx_vseq.sv delete mode 100644 sw/device/tests/sim_dv/spi_tx_rx_test.c delete mode 100644 sw/device/tests/spi_device_ottf_console_test.c delete mode 100644 sw/device/tests/spi_device_smoketest.c delete mode 100644 sw/host/tests/chip/spi_device_ottf_console/BUILD delete mode 100644 sw/host/tests/chip/spi_device_ottf_console/src/main.rs delete mode 100644 sw/host/tests/chip/spi_device_smoketest/BUILD delete mode 100644 sw/host/tests/chip/spi_device_smoketest/src/main.rs diff --git a/hw/ip/spi_device/data/spi_device.hjson b/hw/ip/spi_device/data/spi_device.hjson index cb6b9ba2af8d9..24cab7480b6ae 100644 --- a/hw/ip/spi_device/data/spi_device.hjson +++ b/hw/ip/spi_device/data/spi_device.hjson @@ -6,8 +6,7 @@ human_name: "SPI Device", one_line_desc: "Serial peripheral interface supporting different device modes, suitable for bulk-load of data into and out of the chip", one_paragraph_desc: ''' - SPI Device is a configurable, versatile hardware block that implements a generic SPI device mode, plus three additional modes (SPI Flash emulation mode, SPI passthrough mode, and TPM over SPI mode) to support a variety of different applications. - For example, generic mode can be used in a raw data transfer protocol termed "Firmware Operation Mode", which is intended to be used to bulk-load data into and out of the chip. + SPI Device is a configurable, versatile hardware block that implements three modes (SPI Flash emulation mode, SPI passthrough mode, and TPM over SPI mode) to support a variety of different applications. TPM over SPI operates in compliance with TPM PC Client Platform, unloading this protocol from a software solution. SPI Flash emulation mode supports many JEDEC standard commands such as Read Status, Read JEDEC ID, Read SFDP, EN4B/EX4B, and multiple other read commands, allowing OpenTitan to provide, for example, verified boot firmware to other external devices. ''' @@ -35,6 +34,14 @@ commit_id: "", notes: "" } + { version: "2.0.0", + life_stage: "L1", + design_stage: "D1", + verification_stage: "V1", + dif_stage: "S1", + commit_id: "", + notes: "" + } ] clocking: [ {clock: "clk_i", reset: "rst_ni", primary: true}, @@ -59,27 +66,6 @@ } ] interrupt_list: [ - { name: "generic_rx_full" - desc: "RX SRAM FIFO Full" - } - { name: "generic_rx_watermark" - desc: "RX SRAM FIFO is above the level" - } - { name: "generic_tx_watermark" - desc: "TX SRAM FIFO is under the level" - } - { name: "generic_rx_error" - desc: "SDI in FwMode has error" - type: "event" - } - { name: "generic_rx_overflow" - desc: "RX Async FIFO overflow" - type: "event" - } - { name: "generic_tx_underflow" - desc: "TX Async FIFO underflow" - type: "event" - } { name: "upload_cmdfifo_not_empty" desc: "Upload Command FIFO is not empty" } @@ -191,12 +177,6 @@ } ], features: [ - { - name: "SPI_DEVICE.MODE.GENERIC", - desc: '''Single-lane SPI device interface implementing a raw data transfer protocol for bulk-data loading. - AKA. Firmware Operation Mode - ''' - } { name: "SPI_DEVICE.MODE.FLASH_EMULATION", desc: '''Emulates the behaviour of a Serial Flash device when connected to an upstream SPI Host. @@ -246,35 +226,6 @@ desc: '''CSR.STATUS fields show the current status of the two CSB signals (.csb/.tpm_csb). ''' } - { - name: "SPI_DEVICE.MODE.GENERIC.ASYNC_FIFOS", - desc: '''A pair of asynchronous FIFOs (RXFIFO/TXFIFO) interface with the bus in Generic mode. - - - The bus-facing side of the FIFOs is driven by the bus-CLK. - - The internal-facing side of the FIFOs is driven by the core-CLK. - - Generic-mode logic interfaces the internal-facing sides of the FIFOs with the DPSRAM. - - Generic-mode uses the entire DPSRAM space exclusively (See feature SPI_DEVICE.MODE.GENERIC.DPSRAM_TXF_RXF). - - Writing to "CSR.CONTROL.rst_txfifo" soft-resets the contents of the TXFIFO. - - Received data is normally written from the RXFIFO output to the DPSRAM receive buffer on 32b word boundaries. - - "CSR.CFG.timer_v" provides configurable control of the delay between the end of unaligned receive data and - the construction of an (abnormal) sub-word write to the DPSRAM receive buffer. - - "CSR.ASYNC_FIFO_LEVEL.txlvl" and "CSR.ASYNC_FIFO_LEVEL.rxlvl" contain the current levels of each FIFO. - ''' - } - { - name: "SPI_DEVICE.MODE.GENERIC.DPSRAM_TXF_RXF", - desc: '''A dual-port SRAM, notionally split into transmit (TXF) and receive (RXF) circular buffers, holds data in Generic Mode. - - - TXF and RXF sections are defined by CSR.RXF_ADDR and CSR.TXF_ADDR, each of which contains a base and limit value. - - The boundary between TXF and RXF sections is configurable at runtime by writing to CSR.RXF_ADDR and CSR.TXF_ADDR. - - The current contents of TXF and RXF is defined by CSR.TXF_PTR and CSR.RXF_PTR, each of which contain a rptr and wptr. - - HW interfaces the buffers with the bus through two async-fifos (See feature SPI_DEVICE.MODE.GENERIC.ASYNC_FIFOS). - - CSR.TXF_PTR.rptr and CSR.RXF_PTR.wptr are controlled by HW in response to bus operations that consume or provide data. - - SW updates the rptr/wptr values to indicate it has written-to or read-from each buffer. - - CSR.STATUS contains empty and full flags for each buffer (.txf_empty/.txf_full/.rxf_empty/.rxf_full) - - - ''' - } { name: "SPI_DEVICE.MODE.FLASH_EMULATION.COMMANDS", desc: '''Device should respond to all specified standard SPI Flash Commands. @@ -404,30 +355,17 @@ swaccess: "rw", hwaccess: "hro", fields: [ - { bits: "0", - name: "ABORT", - desc: '''Abort pending TX data in Generic mode. - - If TX_FIFO (Asynchronous) is full, the TXF waits indefinitely to - push the next byte into the asynchronous FIFO. SW may reset the - Async FIFO along with aborting the current task. SW should update - the write pointer of the TXF in order not to push the byte to - Asynchronous FIFO again by TXF logic. - ''' - resval: "0" - }, { bits: "5:4", name: "MODE", - desc: "SPI Device operation mode. Currently only FwMode is supported.", + desc: "SPI Device flash operation mode.", resval: "1" enum: [ { value: "0", - name: "fwmode", - desc: ''' - FW operation mode. + name: "disabled", + desc: '''SPI Flash operations disabled. - HW just dumps incoming data to SRAM and reads from SRAM and - sends to SDO. This mode doesn't support Dual or Quad mode + SPI device flash operations are disabled, and all transactions are ignored. + Note that SPI TPM operations are controlled by !!TPM_CFG ''' }, { value: "1" @@ -457,51 +395,6 @@ // passed between spi_dev/host due to passthrough "excl:CsrNonInitTests:CsrExclWrite"] }, - { bits: "16", - name: "rst_txfifo", - desc: ''' - Reset Async TX_FIFO. - - This only resets asynchronous fifo. If firmware wants to reset SRAM - FIFO, it should write 0 into read/write pointers. - - _Note_: This value should be controlled only when SPI interface is - in Idle state as this reset signal doesn't have reset synchronizer. - ''' - resval: "0", - }, - { bits: "17", - name: "rst_rxfifo", - desc: ''' - Reset Async RX_FIFO. - - This only resets asynchronous fifo. If firmware wants to reset SRAM - FIFO, it should write 0 into read pointer and write pointer. - - _Note_: This value should be controlled only when SPI interface is - in Idle state as this reset signal doesn't have reset synchronizer. - ''' - resval: "0", - }, - { bits: "31" - name: "sram_clk_en", - desc: '''SRAM Clock Enable. - - This controls the clock gating cell lying on DP SRAM clock. As the - nature of absent of SPI_CLK in idle state, the clock mux for SRAM - B port cannot be glitch-free MUX. So, it is up to SW to change the - clock safely. - - Programming sequence: - - 1. Check if SPI line is idle - 2. Clear sram_clk_en to 0. - 3. Change mode to FwMode for peri clk, FlashMode or PassThrough - for SPI_CLK. - 4. Set sram_clk_en to 1. - ''' - resval: "1" - } ] }, { name: "CFG", @@ -529,16 +422,6 @@ desc: "RX bit order on SDI. Module stores bitstream from MSB to LSB if value is 0.", resval: "0", }, - { bits: "15:8", - name: "timer_v", - desc: ''' - number of clocks for RXF to wait. - - To reduce traffic to SRAM, RXF control module waits given clock cycle - if it doesn't fill SRAM data width even if Async RX FIFO is empty. - ''' - resval: "0x7F", - }, { bits: "16" name: "addr_4b_en" swaccess: "rw" @@ -568,75 +451,12 @@ } // f: mailbox_en ] }, - { name: "FIFO_LEVEL", - desc: "RX/ TX FIFO levels.", - swaccess: "rw", - hwaccess: "hro", - fields: [ - { bits: "15:0", - name: "rxlvl", - resval: "0x80", - desc: ''' - RX FIFO level. - - If RX SRAM FIFO level exceeds this value, it triggers interrupt. - ''' - }, - { bits: "31:16", - name: "txlvl", - resval: "0x0", - desc: ''' - TX FIFO level. - - If TX SRAM FIFO level drops below this value, it triggers interrupt. - ''' - }, - ], - }, - { name: "ASYNC_FIFO_LEVEL", - desc: "RX/ TX Async FIFO levels between main clk and spi clock", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - fields: [ - { bits: "23:16", - name: "txlvl", - desc: ''' - TX Async FIFO level. - - This value shows the number of available entry in TX Async FIFO. - If the software writes message into SRAM FIFO and update FIFO write pointer - but no clock from the host is given, the data stuck at this async fifo waiting - host toggles SCK. This value represents the number of bytes. - ''' - }, - { bits: "7:0", - name: "rxlvl", - desc: ''' - RX Async FIFO level. - - This value shows the number of available entry in RX Async FIFO. - ''' - } - ] - }, { name: "STATUS", desc: "SPI Device status register", swaccess: "ro", hwaccess: "hwo", hwext: "true", fields: [ - { bits: "0", name: "rxf_full", desc: "RX FIFO full" }, - { bits: "1", name: "rxf_empty", desc: "RX FIFO empty", resval: "1"}, - { bits: "2", name: "txf_full", desc: "TX FIFO full"}, - { bits: "3", name: "txf_empty", desc: "TX FIFO empty", resval: "1"}, - { bits: "4", name: "abort_done", - desc: '''Abort process is completed. - - Current version does not implement abort_done logic. It is tied to - 1 always. - ''' - resval: "1" }, { bits: "5", name: "csb", desc: "Direct input of CSb signal", resval: "1" }, { bits: "6" name: "tpm_csb" @@ -650,90 +470,6 @@ } ] }, - { name: "RXF_PTR", - desc: "Receiver FIFO (SRAM) pointers", - swaccess: "rw", - hwaccess: "hrw", - fields: [ - { bits: "15:0", - name: "RPTR", - desc: "Read pointer. bit x is for phase bit. check circular fifo description", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - tags: [// Updating rptr will cause unexpected interrupts. These interrupts may take a - // while to generate and cip_base_vseq::clear_all_interrupts may not be able to - // clear them in time. Leftover interrupts will cause sim error - "excl:CsrNonInitTests:CsrExclWrite"] - }, - { bits: "31:16", - name: "WPTR", - desc: "Write pointer. Bit x is phase bit.", - swaccess: "ro", - hwaccess: "hwo", - resval: "0", - } - ] - }, - { name: "TXF_PTR", - desc: "Transmitter FIFO (SRAM) pointers", - swaccess: "rw", - hwaccess: "hrw", - fields: [ - { bits: "15:0", - name: "RPTR", - desc: "Read pointer. bit x is for phase bit. check circular fifo description", - swaccess: "ro", - hwaccess: "hwo", - resval: "0", - }, - { bits: "31:16", - name: "WPTR", - desc: "Write pointer. Bit x is phase bit.", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - tags: [// Updating rptr will cause unexpected interrupts. These interrupts may take a - // while to generate and cip_base_vseq::clear_all_interrupts may not be able to - // clear them in time. Leftover interrupts will cause sim error - "excl:CsrNonInitTests:CsrExclWrite"] - } - ] - }, - { name: "RXF_ADDR", - desc: "Receiver FIFO (SRAM) Addresses", - swaccess: "rw", - hwaccess: "hro", - fields: [ - { bits: "15:0", - name: "base", - desc: "Base offset in bytes in the SRAM. Lower 2 bits are ignored.", - resval: "0", - }, - { bits: "31:16", - name: "limit", - desc: "Limit offset in bytes in the SRAM. Lower 2 bits are ignored.", - resval: "0x1FC", - } - ], - }, - { name: "TXF_ADDR", - desc: "Transmitter FIFO (SRAM) Addresses", - swaccess: "rw", - hwaccess: "hro", - fields: [ - { bits: "15:0", - name: "base", - desc: "Base offset in bytes in the SRAM. Lower 2 bits are ignored.", - resval: "0x200", - }, - { bits: "31:16", - name: "limit", - desc: "Limit offset in bytes in the SRAM. Lower 2 bits are ignored.", - resval: "0x3FC", - } - ], - }, //========================================================================= // Flash & Passthrough CSRs { name: "INTERCEPT_EN" @@ -1590,10 +1326,9 @@ desc: ''' SPI internal buffer. - In Generic mode, this buffer is used for RX/TX buffer. In Flash & - Passthrough mode, lower 2kB is for Read content emulating eFlash. - next 1kB is for Mailbox read/write buffer. The rest is 256B SFDP - buffer, 32B of CmdFIFO, 32B of AddrFIFO, and 256B of payload FIFO. + The lower 2kB is for Read content emulating eFlash. The next 1 kB is + for Mailbox read/write buffer. The rest is 256B SFDP buffer, 32B of + CmdFIFO, 32B of AddrFIFO, and 256B of payload FIFO. ''' }, }, diff --git a/hw/ip/spi_device/doc/generic-blockdiagram.svg b/hw/ip/spi_device/doc/generic-blockdiagram.svg deleted file mode 100644 index 0f35631257aab..0000000000000 --- a/hw/ip/spi_device/doc/generic-blockdiagram.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/spi_device/doc/interfaces.md b/hw/ip/spi_device/doc/interfaces.md index 18d130a64bc22..06318fce8832f 100644 --- a/hw/ip/spi_device/doc/interfaces.md +++ b/hw/ip/spi_device/doc/interfaces.md @@ -30,12 +30,6 @@ Referring to the [Comportable guideline for peripheral device functionality](htt | Interrupt Name | Type | Description | |:-------------------------|:-------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| generic_rx_full | Event | RX SRAM FIFO Full | -| generic_rx_watermark | Event | RX SRAM FIFO is above the level | -| generic_tx_watermark | Event | TX SRAM FIFO is under the level | -| generic_rx_error | Event | SDI in FwMode has error | -| generic_rx_overflow | Event | RX Async FIFO overflow | -| generic_tx_underflow | Event | TX Async FIFO underflow | | upload_cmdfifo_not_empty | Event | Upload Command FIFO is not empty | | upload_payload_not_empty | Event | Upload payload is not empty. The event occurs after SPI transaction completed | | upload_payload_overflow | Event | Upload payload overflow event. When a SPI Host system issues a command with payload more than 256B, this event is reported. When it happens, SW should read the last written payload index CSR to figure out the starting address of the last 256B. | diff --git a/hw/ip/spi_device/doc/programmers_guide.md b/hw/ip/spi_device/doc/programmers_guide.md index 3bad1d05a447d..ab1aba62f4725 100644 --- a/hw/ip/spi_device/doc/programmers_guide.md +++ b/hw/ip/spi_device/doc/programmers_guide.md @@ -2,37 +2,9 @@ ## Initialization -By default, RX SRAM FIFO base and limit address (via [`RXF_ADDR`](registers.md#rxf_addr) register) are -set to 0x0 and 0x1FC, 512 bytes. And TX SRAM FIFO base and limit addresses (in -the [`TXF_ADDR`](registers.md#txf_addr) register) are 0x200 and 0x3FC. If FW wants bigger spaces, it can -change the values of the above registers [`RXF_ADDR`](registers.md#rxf_addr) and [`TXF_ADDR`](registers.md#txf_addr). - -Software can configure the timer value [`CFG.timer_v`](registers.md#cfg) 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, [`RXF_PTR`](registers.md#rxf_ptr) and [`TXF_PTR`](registers.md#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. - -The current SRAM size is 2kB and the pointer width is 12 bits, 11bits -representing a byte offset and 1 most-significant bit for indicating phase of -the FIFO. Since they represent bytes, the low 2 bits indicate the offset within -the 32-bit wide SRAM word. The pointers indicate the offset into the area -described by the base and limit values, so the lower bits (11 bits in this case) -of a pointer should not exceed the size in bytes (4 * (limit address - base -address)) reserved for the region (RXF or TXF) that the pointer is in. For -instance, if FW sets RXFIFO depth to 128 (default value), it should not update -the read pointer outside the range 0x000 - 0x1FF (128*4 = 512Bytes ignoring -the phase bit, bit 11). - ## Dual-port SRAM Layout The figure below shows the SRAM layout in the Flash and Passthrough modes. -In generic mode, the whole DPSRAM is used as RX/TX buffers as described in the generic mode section. The SRAM begins at `0x1000`, which in the figure is `0x000`. ![SPI Device Dual-port SRAM Layout](../doc/spid_sram_layout.svg) @@ -40,22 +12,6 @@ The SRAM begins at `0x1000`, which in the figure is `0x000`. The regions starting from `0xF00` to `0xFFF` are assigned to TPM Read/Write FIFOs. They are not used in this version of IP. -## SPI Mode Changes - -The clock for port B of the dual-port SRAM comes from different sources, depending on which SPI mode is selected. -For the generic mode, the peripheral clock is used, while for flash and passthrough mode, the SPI clock is used. -Since the SPI clock is not active when the SPI interface is idle, the design cannot make use of a glitch-free clock mux that would require a continuously running clock. -Therefore, software has to use the [`CONTROL.sram_clk_en`](registers.md#control) register to gate the clock while switching between modes with different dual-port SRAM clock sources. - -For any mode change that involves switching to a different clock source, the following programming sequence must be followed: - -1. Software should ensure that the SPI clock is inactive, e.g. by holding the upstream SPI host in reset or signal it to hold off. -2. Clear [`CONTROL.sram_clk_en`](registers.md#control) to 0. -3. Change to the new SPI mode -4. Set [`CONTROL.sram_clk_en`](registers.md#control) to 1. - -**Note: This is a limitation of the current `spi_device` that is planned to be removed in a future revision.** - ## TPM over SPI ### Initialization diff --git a/hw/ip/spi_device/doc/registers.md b/hw/ip/spi_device/doc/registers.md index 43958e26d0f30..d4ef0751d6082 100644 --- a/hw/ip/spi_device/doc/registers.md +++ b/hw/ip/spi_device/doc/registers.md @@ -3,172 +3,148 @@ ## Summary -| Name | Offset | Length | Description | -|:---------------------------------------------------------|:---------|---------:|:--------------------------------------------------------| -| spi_device.[`INTR_STATE`](#intr_state) | 0x0 | 4 | Interrupt State Register | -| spi_device.[`INTR_ENABLE`](#intr_enable) | 0x4 | 4 | Interrupt Enable Register | -| spi_device.[`INTR_TEST`](#intr_test) | 0x8 | 4 | Interrupt Test Register | -| spi_device.[`ALERT_TEST`](#alert_test) | 0xc | 4 | Alert Test Register | -| spi_device.[`CONTROL`](#control) | 0x10 | 4 | Control register | -| spi_device.[`CFG`](#cfg) | 0x14 | 4 | Configuration Register | -| spi_device.[`FIFO_LEVEL`](#fifo_level) | 0x18 | 4 | RX/ TX FIFO levels. | -| spi_device.[`ASYNC_FIFO_LEVEL`](#async_fifo_level) | 0x1c | 4 | RX/ TX Async FIFO levels between main clk and spi clock | -| spi_device.[`STATUS`](#status) | 0x20 | 4 | SPI Device status register | -| spi_device.[`RXF_PTR`](#rxf_ptr) | 0x24 | 4 | Receiver FIFO (SRAM) pointers | -| spi_device.[`TXF_PTR`](#txf_ptr) | 0x28 | 4 | Transmitter FIFO (SRAM) pointers | -| spi_device.[`RXF_ADDR`](#rxf_addr) | 0x2c | 4 | Receiver FIFO (SRAM) Addresses | -| spi_device.[`TXF_ADDR`](#txf_addr) | 0x30 | 4 | Transmitter FIFO (SRAM) Addresses | -| spi_device.[`INTERCEPT_EN`](#intercept_en) | 0x34 | 4 | Intercept Passthrough datapath. | -| spi_device.[`LAST_READ_ADDR`](#last_read_addr) | 0x38 | 4 | Last Read Address | -| spi_device.[`FLASH_STATUS`](#flash_status) | 0x3c | 4 | SPI Flash Status register. | -| spi_device.[`JEDEC_CC`](#jedec_cc) | 0x40 | 4 | JEDEC Continuation Code configuration register. | -| spi_device.[`JEDEC_ID`](#jedec_id) | 0x44 | 4 | JEDEC ID register. | -| spi_device.[`READ_THRESHOLD`](#read_threshold) | 0x48 | 4 | Read Buffer threshold register. | -| spi_device.[`MAILBOX_ADDR`](#mailbox_addr) | 0x4c | 4 | Mailbox Base address register. | -| spi_device.[`UPLOAD_STATUS`](#upload_status) | 0x50 | 4 | Upload module status register. | -| spi_device.[`UPLOAD_STATUS2`](#upload_status2) | 0x54 | 4 | Upload module status 2 register. | -| spi_device.[`UPLOAD_CMDFIFO`](#upload_cmdfifo) | 0x58 | 4 | Command Fifo Read Port. | -| spi_device.[`UPLOAD_ADDRFIFO`](#upload_addrfifo) | 0x5c | 4 | Address Fifo Read Port. | -| spi_device.[`CMD_FILTER_0`](#CMD_FILTER_0) | 0x60 | 4 | Command Filter | -| spi_device.[`CMD_FILTER_1`](#CMD_FILTER_1) | 0x64 | 4 | Command Filter | -| spi_device.[`CMD_FILTER_2`](#CMD_FILTER_2) | 0x68 | 4 | Command Filter | -| spi_device.[`CMD_FILTER_3`](#CMD_FILTER_3) | 0x6c | 4 | Command Filter | -| spi_device.[`CMD_FILTER_4`](#CMD_FILTER_4) | 0x70 | 4 | Command Filter | -| spi_device.[`CMD_FILTER_5`](#CMD_FILTER_5) | 0x74 | 4 | Command Filter | -| spi_device.[`CMD_FILTER_6`](#CMD_FILTER_6) | 0x78 | 4 | Command Filter | -| spi_device.[`CMD_FILTER_7`](#CMD_FILTER_7) | 0x7c | 4 | Command Filter | -| spi_device.[`ADDR_SWAP_MASK`](#addr_swap_mask) | 0x80 | 4 | Address Swap Mask register. | -| spi_device.[`ADDR_SWAP_DATA`](#addr_swap_data) | 0x84 | 4 | The address value for the address swap feature. | -| spi_device.[`PAYLOAD_SWAP_MASK`](#payload_swap_mask) | 0x88 | 4 | Write Data Swap in the passthrough mode. | -| spi_device.[`PAYLOAD_SWAP_DATA`](#payload_swap_data) | 0x8c | 4 | Write Data Swap in the passthrough mode. | -| spi_device.[`CMD_INFO_0`](#cmd_info) | 0x90 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_1`](#cmd_info) | 0x94 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_2`](#cmd_info) | 0x98 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_3`](#cmd_info) | 0x9c | 4 | Command Info register. | -| spi_device.[`CMD_INFO_4`](#cmd_info) | 0xa0 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_5`](#cmd_info) | 0xa4 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_6`](#cmd_info) | 0xa8 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_7`](#cmd_info) | 0xac | 4 | Command Info register. | -| spi_device.[`CMD_INFO_8`](#cmd_info) | 0xb0 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_9`](#cmd_info) | 0xb4 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_10`](#cmd_info) | 0xb8 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_11`](#cmd_info) | 0xbc | 4 | Command Info register. | -| spi_device.[`CMD_INFO_12`](#cmd_info) | 0xc0 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_13`](#cmd_info) | 0xc4 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_14`](#cmd_info) | 0xc8 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_15`](#cmd_info) | 0xcc | 4 | Command Info register. | -| spi_device.[`CMD_INFO_16`](#cmd_info) | 0xd0 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_17`](#cmd_info) | 0xd4 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_18`](#cmd_info) | 0xd8 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_19`](#cmd_info) | 0xdc | 4 | Command Info register. | -| spi_device.[`CMD_INFO_20`](#cmd_info) | 0xe0 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_21`](#cmd_info) | 0xe4 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_22`](#cmd_info) | 0xe8 | 4 | Command Info register. | -| spi_device.[`CMD_INFO_23`](#cmd_info) | 0xec | 4 | Command Info register. | -| spi_device.[`CMD_INFO_EN4B`](#cmd_info_en4b) | 0xf0 | 4 | Opcode for EN4B. | -| spi_device.[`CMD_INFO_EX4B`](#cmd_info_ex4b) | 0xf4 | 4 | Opcode for EX4B | -| spi_device.[`CMD_INFO_WREN`](#cmd_info_wren) | 0xf8 | 4 | Opcode for Write Enable (WREN) | -| spi_device.[`CMD_INFO_WRDI`](#cmd_info_wrdi) | 0xfc | 4 | Opcode for Write Disable (WRDI) | -| spi_device.[`TPM_CAP`](#tpm_cap) | 0x800 | 4 | TPM HWIP Capability register. | -| spi_device.[`TPM_CFG`](#tpm_cfg) | 0x804 | 4 | TPM Configuration register. | -| spi_device.[`TPM_STATUS`](#tpm_status) | 0x808 | 4 | TPM submodule state register. | -| spi_device.[`TPM_ACCESS_0`](#TPM_ACCESS_0) | 0x80c | 4 | TPM_ACCESS_x register. | -| spi_device.[`TPM_ACCESS_1`](#TPM_ACCESS_1) | 0x810 | 4 | TPM_ACCESS_x register. | -| spi_device.[`TPM_STS`](#tpm_sts) | 0x814 | 4 | TPM_STS_x register. | -| spi_device.[`TPM_INTF_CAPABILITY`](#tpm_intf_capability) | 0x818 | 4 | TPM_INTF_CAPABILITY | -| spi_device.[`TPM_INT_ENABLE`](#tpm_int_enable) | 0x81c | 4 | TPM_INT_ENABLE | -| spi_device.[`TPM_INT_VECTOR`](#tpm_int_vector) | 0x820 | 4 | TPM_INT_VECTOR | -| spi_device.[`TPM_INT_STATUS`](#tpm_int_status) | 0x824 | 4 | TPM_INT_STATUS | -| spi_device.[`TPM_DID_VID`](#tpm_did_vid) | 0x828 | 4 | TPM_DID/ TPM_VID register | -| spi_device.[`TPM_RID`](#tpm_rid) | 0x82c | 4 | TPM_RID | -| spi_device.[`TPM_CMD_ADDR`](#tpm_cmd_addr) | 0x830 | 4 | TPM Command and Address buffer | -| spi_device.[`TPM_READ_FIFO`](#tpm_read_fifo) | 0x834 | 4 | TPM Read command return data FIFO. | -| spi_device.[`TPM_WRITE_FIFO`](#tpm_write_fifo) | 0x838 | 4 | TPM Write command received data FIFO. | -| spi_device.[`buffer`](#buffer) | 0x1000 | 4096 | SPI internal buffer. | +| Name | Offset | Length | Description | +|:---------------------------------------------------------|:---------|---------:|:------------------------------------------------| +| spi_device.[`INTR_STATE`](#intr_state) | 0x0 | 4 | Interrupt State Register | +| spi_device.[`INTR_ENABLE`](#intr_enable) | 0x4 | 4 | Interrupt Enable Register | +| spi_device.[`INTR_TEST`](#intr_test) | 0x8 | 4 | Interrupt Test Register | +| spi_device.[`ALERT_TEST`](#alert_test) | 0xc | 4 | Alert Test Register | +| spi_device.[`CONTROL`](#control) | 0x10 | 4 | Control register | +| spi_device.[`CFG`](#cfg) | 0x14 | 4 | Configuration Register | +| spi_device.[`STATUS`](#status) | 0x18 | 4 | SPI Device status register | +| spi_device.[`INTERCEPT_EN`](#intercept_en) | 0x1c | 4 | Intercept Passthrough datapath. | +| spi_device.[`LAST_READ_ADDR`](#last_read_addr) | 0x20 | 4 | Last Read Address | +| spi_device.[`FLASH_STATUS`](#flash_status) | 0x24 | 4 | SPI Flash Status register. | +| spi_device.[`JEDEC_CC`](#jedec_cc) | 0x28 | 4 | JEDEC Continuation Code configuration register. | +| spi_device.[`JEDEC_ID`](#jedec_id) | 0x2c | 4 | JEDEC ID register. | +| spi_device.[`READ_THRESHOLD`](#read_threshold) | 0x30 | 4 | Read Buffer threshold register. | +| spi_device.[`MAILBOX_ADDR`](#mailbox_addr) | 0x34 | 4 | Mailbox Base address register. | +| spi_device.[`UPLOAD_STATUS`](#upload_status) | 0x38 | 4 | Upload module status register. | +| spi_device.[`UPLOAD_STATUS2`](#upload_status2) | 0x3c | 4 | Upload module status 2 register. | +| spi_device.[`UPLOAD_CMDFIFO`](#upload_cmdfifo) | 0x40 | 4 | Command Fifo Read Port. | +| spi_device.[`UPLOAD_ADDRFIFO`](#upload_addrfifo) | 0x44 | 4 | Address Fifo Read Port. | +| spi_device.[`CMD_FILTER_0`](#CMD_FILTER_0) | 0x48 | 4 | Command Filter | +| spi_device.[`CMD_FILTER_1`](#CMD_FILTER_1) | 0x4c | 4 | Command Filter | +| spi_device.[`CMD_FILTER_2`](#CMD_FILTER_2) | 0x50 | 4 | Command Filter | +| spi_device.[`CMD_FILTER_3`](#CMD_FILTER_3) | 0x54 | 4 | Command Filter | +| spi_device.[`CMD_FILTER_4`](#CMD_FILTER_4) | 0x58 | 4 | Command Filter | +| spi_device.[`CMD_FILTER_5`](#CMD_FILTER_5) | 0x5c | 4 | Command Filter | +| spi_device.[`CMD_FILTER_6`](#CMD_FILTER_6) | 0x60 | 4 | Command Filter | +| spi_device.[`CMD_FILTER_7`](#CMD_FILTER_7) | 0x64 | 4 | Command Filter | +| spi_device.[`ADDR_SWAP_MASK`](#addr_swap_mask) | 0x68 | 4 | Address Swap Mask register. | +| spi_device.[`ADDR_SWAP_DATA`](#addr_swap_data) | 0x6c | 4 | The address value for the address swap feature. | +| spi_device.[`PAYLOAD_SWAP_MASK`](#payload_swap_mask) | 0x70 | 4 | Write Data Swap in the passthrough mode. | +| spi_device.[`PAYLOAD_SWAP_DATA`](#payload_swap_data) | 0x74 | 4 | Write Data Swap in the passthrough mode. | +| spi_device.[`CMD_INFO_0`](#cmd_info) | 0x78 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_1`](#cmd_info) | 0x7c | 4 | Command Info register. | +| spi_device.[`CMD_INFO_2`](#cmd_info) | 0x80 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_3`](#cmd_info) | 0x84 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_4`](#cmd_info) | 0x88 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_5`](#cmd_info) | 0x8c | 4 | Command Info register. | +| spi_device.[`CMD_INFO_6`](#cmd_info) | 0x90 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_7`](#cmd_info) | 0x94 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_8`](#cmd_info) | 0x98 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_9`](#cmd_info) | 0x9c | 4 | Command Info register. | +| spi_device.[`CMD_INFO_10`](#cmd_info) | 0xa0 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_11`](#cmd_info) | 0xa4 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_12`](#cmd_info) | 0xa8 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_13`](#cmd_info) | 0xac | 4 | Command Info register. | +| spi_device.[`CMD_INFO_14`](#cmd_info) | 0xb0 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_15`](#cmd_info) | 0xb4 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_16`](#cmd_info) | 0xb8 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_17`](#cmd_info) | 0xbc | 4 | Command Info register. | +| spi_device.[`CMD_INFO_18`](#cmd_info) | 0xc0 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_19`](#cmd_info) | 0xc4 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_20`](#cmd_info) | 0xc8 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_21`](#cmd_info) | 0xcc | 4 | Command Info register. | +| spi_device.[`CMD_INFO_22`](#cmd_info) | 0xd0 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_23`](#cmd_info) | 0xd4 | 4 | Command Info register. | +| spi_device.[`CMD_INFO_EN4B`](#cmd_info_en4b) | 0xd8 | 4 | Opcode for EN4B. | +| spi_device.[`CMD_INFO_EX4B`](#cmd_info_ex4b) | 0xdc | 4 | Opcode for EX4B | +| spi_device.[`CMD_INFO_WREN`](#cmd_info_wren) | 0xe0 | 4 | Opcode for Write Enable (WREN) | +| spi_device.[`CMD_INFO_WRDI`](#cmd_info_wrdi) | 0xe4 | 4 | Opcode for Write Disable (WRDI) | +| spi_device.[`TPM_CAP`](#tpm_cap) | 0x800 | 4 | TPM HWIP Capability register. | +| spi_device.[`TPM_CFG`](#tpm_cfg) | 0x804 | 4 | TPM Configuration register. | +| spi_device.[`TPM_STATUS`](#tpm_status) | 0x808 | 4 | TPM submodule state register. | +| spi_device.[`TPM_ACCESS_0`](#TPM_ACCESS_0) | 0x80c | 4 | TPM_ACCESS_x register. | +| spi_device.[`TPM_ACCESS_1`](#TPM_ACCESS_1) | 0x810 | 4 | TPM_ACCESS_x register. | +| spi_device.[`TPM_STS`](#tpm_sts) | 0x814 | 4 | TPM_STS_x register. | +| spi_device.[`TPM_INTF_CAPABILITY`](#tpm_intf_capability) | 0x818 | 4 | TPM_INTF_CAPABILITY | +| spi_device.[`TPM_INT_ENABLE`](#tpm_int_enable) | 0x81c | 4 | TPM_INT_ENABLE | +| spi_device.[`TPM_INT_VECTOR`](#tpm_int_vector) | 0x820 | 4 | TPM_INT_VECTOR | +| spi_device.[`TPM_INT_STATUS`](#tpm_int_status) | 0x824 | 4 | TPM_INT_STATUS | +| spi_device.[`TPM_DID_VID`](#tpm_did_vid) | 0x828 | 4 | TPM_DID/ TPM_VID register | +| spi_device.[`TPM_RID`](#tpm_rid) | 0x82c | 4 | TPM_RID | +| spi_device.[`TPM_CMD_ADDR`](#tpm_cmd_addr) | 0x830 | 4 | TPM Command and Address buffer | +| spi_device.[`TPM_READ_FIFO`](#tpm_read_fifo) | 0x834 | 4 | TPM Read command return data FIFO. | +| spi_device.[`TPM_WRITE_FIFO`](#tpm_write_fifo) | 0x838 | 4 | TPM Write command received data FIFO. | +| spi_device.[`buffer`](#buffer) | 0x1000 | 4096 | SPI internal buffer. | ## INTR_STATE Interrupt State Register - Offset: `0x0` - Reset default: `0x0` -- Reset mask: `0xfff` +- Reset mask: `0x3f` ### Fields ```wavejson -{"reg": [{"name": "generic_rx_full", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "generic_rx_watermark", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "generic_tx_watermark", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "generic_rx_error", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "generic_rx_overflow", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "generic_tx_underflow", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "upload_cmdfifo_not_empty", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "upload_payload_not_empty", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "upload_payload_overflow", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "readbuf_watermark", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "readbuf_flip", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "tpm_header_not_empty", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 20}], "config": {"lanes": 1, "fontsize": 10, "vspace": 260}} +{"reg": [{"name": "upload_cmdfifo_not_empty", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "upload_payload_not_empty", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "upload_payload_overflow", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "readbuf_watermark", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "readbuf_flip", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "tpm_header_not_empty", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 260}} ``` | Bits | Type | Reset | Name | Description | |:------:|:------:|:-------:|:-------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 31:12 | | | | Reserved | -| 11 | ro | 0x0 | tpm_header_not_empty | TPM Header(Command/Address) buffer available | -| 10 | rw1c | 0x0 | readbuf_flip | Read buffer flipped event. The host system accesses other side of buffer. | -| 9 | rw1c | 0x0 | readbuf_watermark | Read Buffer Threshold event. The host system accesses greater than or equal to the threshold of a buffer. | -| 8 | rw1c | 0x0 | upload_payload_overflow | Upload payload overflow event. When a SPI Host system issues a command with payload more than 256B, this event is reported. When it happens, SW should read the last written payload index CSR to figure out the starting address of the last 256B. | -| 7 | rw1c | 0x0 | upload_payload_not_empty | Upload payload is not empty. The event occurs after SPI transaction completed | -| 6 | rw1c | 0x0 | upload_cmdfifo_not_empty | Upload Command FIFO is not empty | -| 5 | rw1c | 0x0 | generic_tx_underflow | TX Async FIFO underflow | -| 4 | rw1c | 0x0 | generic_rx_overflow | RX Async FIFO overflow | -| 3 | rw1c | 0x0 | generic_rx_error | SDI in FwMode has error | -| 2 | rw1c | 0x0 | generic_tx_watermark | TX SRAM FIFO is under the level | -| 1 | rw1c | 0x0 | generic_rx_watermark | RX SRAM FIFO is above the level | -| 0 | rw1c | 0x0 | generic_rx_full | RX SRAM FIFO Full | +| 31:6 | | | | Reserved | +| 5 | ro | 0x0 | tpm_header_not_empty | TPM Header(Command/Address) buffer available | +| 4 | rw1c | 0x0 | readbuf_flip | Read buffer flipped event. The host system accesses other side of buffer. | +| 3 | rw1c | 0x0 | readbuf_watermark | Read Buffer Threshold event. The host system accesses greater than or equal to the threshold of a buffer. | +| 2 | rw1c | 0x0 | upload_payload_overflow | Upload payload overflow event. When a SPI Host system issues a command with payload more than 256B, this event is reported. When it happens, SW should read the last written payload index CSR to figure out the starting address of the last 256B. | +| 1 | rw1c | 0x0 | upload_payload_not_empty | Upload payload is not empty. The event occurs after SPI transaction completed | +| 0 | rw1c | 0x0 | upload_cmdfifo_not_empty | Upload Command FIFO is not empty | ## INTR_ENABLE Interrupt Enable Register - Offset: `0x4` - Reset default: `0x0` -- Reset mask: `0xfff` +- Reset mask: `0x3f` ### Fields ```wavejson -{"reg": [{"name": "generic_rx_full", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "generic_rx_watermark", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "generic_tx_watermark", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "generic_rx_error", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "generic_rx_overflow", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "generic_tx_underflow", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "upload_cmdfifo_not_empty", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "upload_payload_not_empty", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "upload_payload_overflow", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "readbuf_watermark", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "readbuf_flip", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "tpm_header_not_empty", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 20}], "config": {"lanes": 1, "fontsize": 10, "vspace": 260}} +{"reg": [{"name": "upload_cmdfifo_not_empty", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "upload_payload_not_empty", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "upload_payload_overflow", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "readbuf_watermark", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "readbuf_flip", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "tpm_header_not_empty", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 260}} ``` | Bits | Type | Reset | Name | Description | |:------:|:------:|:-------:|:-------------------------|:-----------------------------------------------------------------------------------| -| 31:12 | | | | Reserved | -| 11 | rw | 0x0 | tpm_header_not_empty | Enable interrupt when [`INTR_STATE.tpm_header_not_empty`](#intr_state) is set. | -| 10 | rw | 0x0 | readbuf_flip | Enable interrupt when [`INTR_STATE.readbuf_flip`](#intr_state) is set. | -| 9 | rw | 0x0 | readbuf_watermark | Enable interrupt when [`INTR_STATE.readbuf_watermark`](#intr_state) is set. | -| 8 | rw | 0x0 | upload_payload_overflow | Enable interrupt when [`INTR_STATE.upload_payload_overflow`](#intr_state) is set. | -| 7 | rw | 0x0 | upload_payload_not_empty | Enable interrupt when [`INTR_STATE.upload_payload_not_empty`](#intr_state) is set. | -| 6 | rw | 0x0 | upload_cmdfifo_not_empty | Enable interrupt when [`INTR_STATE.upload_cmdfifo_not_empty`](#intr_state) is set. | -| 5 | rw | 0x0 | generic_tx_underflow | Enable interrupt when [`INTR_STATE.generic_tx_underflow`](#intr_state) is set. | -| 4 | rw | 0x0 | generic_rx_overflow | Enable interrupt when [`INTR_STATE.generic_rx_overflow`](#intr_state) is set. | -| 3 | rw | 0x0 | generic_rx_error | Enable interrupt when [`INTR_STATE.generic_rx_error`](#intr_state) is set. | -| 2 | rw | 0x0 | generic_tx_watermark | Enable interrupt when [`INTR_STATE.generic_tx_watermark`](#intr_state) is set. | -| 1 | rw | 0x0 | generic_rx_watermark | Enable interrupt when [`INTR_STATE.generic_rx_watermark`](#intr_state) is set. | -| 0 | rw | 0x0 | generic_rx_full | Enable interrupt when [`INTR_STATE.generic_rx_full`](#intr_state) is set. | +| 31:6 | | | | Reserved | +| 5 | rw | 0x0 | tpm_header_not_empty | Enable interrupt when [`INTR_STATE.tpm_header_not_empty`](#intr_state) is set. | +| 4 | rw | 0x0 | readbuf_flip | Enable interrupt when [`INTR_STATE.readbuf_flip`](#intr_state) is set. | +| 3 | rw | 0x0 | readbuf_watermark | Enable interrupt when [`INTR_STATE.readbuf_watermark`](#intr_state) is set. | +| 2 | rw | 0x0 | upload_payload_overflow | Enable interrupt when [`INTR_STATE.upload_payload_overflow`](#intr_state) is set. | +| 1 | rw | 0x0 | upload_payload_not_empty | Enable interrupt when [`INTR_STATE.upload_payload_not_empty`](#intr_state) is set. | +| 0 | rw | 0x0 | upload_cmdfifo_not_empty | Enable interrupt when [`INTR_STATE.upload_cmdfifo_not_empty`](#intr_state) is set. | ## INTR_TEST Interrupt Test Register - Offset: `0x8` - Reset default: `0x0` -- Reset mask: `0xfff` +- Reset mask: `0x3f` ### Fields ```wavejson -{"reg": [{"name": "generic_rx_full", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "generic_rx_watermark", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "generic_tx_watermark", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "generic_rx_error", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "generic_rx_overflow", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "generic_tx_underflow", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "upload_cmdfifo_not_empty", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "upload_payload_not_empty", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "upload_payload_overflow", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "readbuf_watermark", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "readbuf_flip", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "tpm_header_not_empty", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 20}], "config": {"lanes": 1, "fontsize": 10, "vspace": 260}} +{"reg": [{"name": "upload_cmdfifo_not_empty", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "upload_payload_not_empty", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "upload_payload_overflow", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "readbuf_watermark", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "readbuf_flip", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "tpm_header_not_empty", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 260}} ``` | Bits | Type | Reset | Name | Description | |:------:|:------:|:-------:|:-------------------------|:----------------------------------------------------------------------------| -| 31:12 | | | | Reserved | -| 11 | wo | 0x0 | tpm_header_not_empty | Write 1 to force [`INTR_STATE.tpm_header_not_empty`](#intr_state) to 1. | -| 10 | wo | 0x0 | readbuf_flip | Write 1 to force [`INTR_STATE.readbuf_flip`](#intr_state) to 1. | -| 9 | wo | 0x0 | readbuf_watermark | Write 1 to force [`INTR_STATE.readbuf_watermark`](#intr_state) to 1. | -| 8 | wo | 0x0 | upload_payload_overflow | Write 1 to force [`INTR_STATE.upload_payload_overflow`](#intr_state) to 1. | -| 7 | wo | 0x0 | upload_payload_not_empty | Write 1 to force [`INTR_STATE.upload_payload_not_empty`](#intr_state) to 1. | -| 6 | wo | 0x0 | upload_cmdfifo_not_empty | Write 1 to force [`INTR_STATE.upload_cmdfifo_not_empty`](#intr_state) to 1. | -| 5 | wo | 0x0 | generic_tx_underflow | Write 1 to force [`INTR_STATE.generic_tx_underflow`](#intr_state) to 1. | -| 4 | wo | 0x0 | generic_rx_overflow | Write 1 to force [`INTR_STATE.generic_rx_overflow`](#intr_state) to 1. | -| 3 | wo | 0x0 | generic_rx_error | Write 1 to force [`INTR_STATE.generic_rx_error`](#intr_state) to 1. | -| 2 | wo | 0x0 | generic_tx_watermark | Write 1 to force [`INTR_STATE.generic_tx_watermark`](#intr_state) to 1. | -| 1 | wo | 0x0 | generic_rx_watermark | Write 1 to force [`INTR_STATE.generic_rx_watermark`](#intr_state) to 1. | -| 0 | wo | 0x0 | generic_rx_full | Write 1 to force [`INTR_STATE.generic_rx_full`](#intr_state) to 1. | +| 31:6 | | | | Reserved | +| 5 | wo | 0x0 | tpm_header_not_empty | Write 1 to force [`INTR_STATE.tpm_header_not_empty`](#intr_state) to 1. | +| 4 | wo | 0x0 | readbuf_flip | Write 1 to force [`INTR_STATE.readbuf_flip`](#intr_state) to 1. | +| 3 | wo | 0x0 | readbuf_watermark | Write 1 to force [`INTR_STATE.readbuf_watermark`](#intr_state) to 1. | +| 2 | wo | 0x0 | upload_payload_overflow | Write 1 to force [`INTR_STATE.upload_payload_overflow`](#intr_state) to 1. | +| 1 | wo | 0x0 | upload_payload_not_empty | Write 1 to force [`INTR_STATE.upload_payload_not_empty`](#intr_state) to 1. | +| 0 | wo | 0x0 | upload_cmdfifo_not_empty | Write 1 to force [`INTR_STATE.upload_cmdfifo_not_empty`](#intr_state) to 1. | ## ALERT_TEST Alert Test Register @@ -190,90 +166,42 @@ Alert Test Register ## CONTROL Control register - Offset: `0x10` -- Reset default: `0x80000010` -- Reset mask: `0x80030031` +- Reset default: `0x10` +- Reset mask: `0x30` ### Fields ```wavejson -{"reg": [{"name": "ABORT", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 3}, {"name": "MODE", "bits": 2, "attr": ["rw"], "rotate": -90}, {"bits": 10}, {"name": "rst_txfifo", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "rst_rxfifo", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 13}, {"name": "sram_clk_en", "bits": 1, "attr": ["rw"], "rotate": -90}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +{"reg": [{"bits": 4}, {"name": "MODE", "bits": 2, "attr": ["rw"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} ``` -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:-------------------------------------| -| 31 | rw | 0x1 | [sram_clk_en](#control--sram_clk_en) | -| 30:18 | | | Reserved | -| 17 | rw | 0x0 | [rst_rxfifo](#control--rst_rxfifo) | -| 16 | rw | 0x0 | [rst_txfifo](#control--rst_txfifo) | -| 15:6 | | | Reserved | -| 5:4 | rw | 0x1 | [MODE](#control--mode) | -| 3:1 | | | Reserved | -| 0 | rw | 0x0 | [ABORT](#control--abort) | - -### CONTROL . sram_clk_en -SRAM Clock Enable. - -This controls the clock gating cell lying on DP SRAM clock. As the -nature of absent of SPI_CLK in idle state, the clock mux for SRAM -B port cannot be glitch-free MUX. So, it is up to SW to change the -clock safely. - -Programming sequence: - -1. Check if SPI line is idle -2. Clear sram_clk_en to 0. -3. Change mode to FwMode for peri clk, FlashMode or PassThrough - for SPI_CLK. -4. Set sram_clk_en to 1. - -### CONTROL . rst_rxfifo -Reset Async RX_FIFO. - -This only resets asynchronous fifo. If firmware wants to reset SRAM -FIFO, it should write 0 into read pointer and write pointer. - -_Note_: This value should be controlled only when SPI interface is -in Idle state as this reset signal doesn't have reset synchronizer. - -### CONTROL . rst_txfifo -Reset Async TX_FIFO. - -This only resets asynchronous fifo. If firmware wants to reset SRAM -FIFO, it should write 0 into read/write pointers. - -_Note_: This value should be controlled only when SPI interface is -in Idle state as this reset signal doesn't have reset synchronizer. +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-----------------------| +| 31:6 | | | Reserved | +| 5:4 | rw | 0x1 | [MODE](#control--mode) | +| 3:0 | | | Reserved | ### CONTROL . MODE -SPI Device operation mode. Currently only FwMode is supported. +SPI Device flash operation mode. | Value | Name | Description | |:--------|:------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 0x0 | fwmode | FW operation mode. HW just dumps incoming data to SRAM and reads from SRAM and sends to SDO. This mode doesn't support Dual or Quad mode | +| 0x0 | disabled | SPI Flash operations disabled. SPI device flash operations are disabled, and all transactions are ignored. Note that SPI TPM operations are controlled by !!TPM_CFG | | 0x1 | flashmode | SPI Flash Emulation mode. In flash mode, SPI Device IP accepts SPI Flash commands and processes internally, then returns data for the read commands. HW processes the Status, JEDEC ID, SFDP commands. The current version does not support Dual/Quad IO and QPI commands. | | 0x2 | passthrough | In passthrough mode, SPI Device IP forwards the incoming SPI flash traffics to the attached downstream flash device. HW may processes commands internally and returns data. SW may configure the device to drop inadmissable commands. | Other values are reserved. -### CONTROL . ABORT -Abort pending TX data in Generic mode. - -If TX_FIFO (Asynchronous) is full, the TXF waits indefinitely to -push the next byte into the asynchronous FIFO. SW may reset the -Async FIFO along with aborting the current task. SW should update -the write pointer of the TXF in order not to push the byte to -Asynchronous FIFO again by TXF logic. - ## CFG Configuration Register - Offset: `0x14` -- Reset default: `0x7f00` -- Reset mask: `0x101ff0f` +- Reset default: `0x0` +- Reset mask: `0x101000f` ### Fields ```wavejson -{"reg": [{"name": "CPOL", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "CPHA", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "tx_order", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "rx_order", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 4}, {"name": "timer_v", "bits": 8, "attr": ["rw"], "rotate": 0}, {"name": "addr_4b_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 7}, {"name": "mailbox_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 7}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}} +{"reg": [{"name": "CPOL", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "CPHA", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "tx_order", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "rx_order", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 12}, {"name": "addr_4b_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 7}, {"name": "mailbox_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 7}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}} ``` | Bits | Type | Reset | Name | @@ -282,8 +210,7 @@ Configuration Register | 24 | rw | 0x0 | [mailbox_en](#cfg--mailbox_en) | | 23:17 | | | Reserved | | 16 | rw | 0x0 | [addr_4b_en](#cfg--addr_4b_en) | -| 15:8 | rw | 0x7f | [timer_v](#cfg--timer_v) | -| 7:4 | | | Reserved | +| 15:4 | | | Reserved | | 3 | rw | 0x0 | [rx_order](#cfg--rx_order) | | 2 | rw | 0x0 | [tx_order](#cfg--tx_order) | | 1 | rw | 0x0 | [CPHA](#cfg--cpha) | @@ -310,12 +237,6 @@ Even though Read SFDP command has address fields, the SFDP command is not affected by this field. The command always parse 24 bits on the SPI line 0 following the SPI command as the address field. -### CFG . timer_v -number of clocks for RXF to wait. - -To reduce traffic to SRAM, RXF control module waits given clock cycle -if it doesn't fill SRAM data width even if Async RX FIFO is empty. - ### CFG . rx_order RX bit order on SDI. Module stores bitstream from MSB to LSB if value is 0. @@ -328,150 +249,29 @@ Data phase. 0 for negative edge change, 1 for positive edge change ### CFG . CPOL Clock polarity. 0 for normal SPI, 1 for negative edge latch -## FIFO_LEVEL -RX/ TX FIFO levels. -- Offset: `0x18` -- Reset default: `0x80` -- Reset mask: `0xffffffff` - -### Fields - -```wavejson -{"reg": [{"name": "rxlvl", "bits": 16, "attr": ["rw"], "rotate": 0}, {"name": "txlvl", "bits": 16, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:------------------------------------------------------------------------------------| -| 31:16 | rw | 0x0 | txlvl | TX FIFO level. If TX SRAM FIFO level drops below this value, it triggers interrupt. | -| 15:0 | rw | 0x80 | rxlvl | RX FIFO level. If RX SRAM FIFO level exceeds this value, it triggers interrupt. | - -## ASYNC_FIFO_LEVEL -RX/ TX Async FIFO levels between main clk and spi clock -- Offset: `0x1c` -- Reset default: `0x0` -- Reset mask: `0xff00ff` - -### Fields - -```wavejson -{"reg": [{"name": "rxlvl", "bits": 8, "attr": ["ro"], "rotate": 0}, {"bits": 8}, {"name": "txlvl", "bits": 8, "attr": ["ro"], "rotate": 0}, {"bits": 8}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:----------------------------------| -| 31:24 | | | Reserved | -| 23:16 | ro | x | [txlvl](#async_fifo_level--txlvl) | -| 15:8 | | | Reserved | -| 7:0 | ro | x | [rxlvl](#async_fifo_level--rxlvl) | - -### ASYNC_FIFO_LEVEL . txlvl -TX Async FIFO level. - -This value shows the number of available entry in TX Async FIFO. -If the software writes message into SRAM FIFO and update FIFO write pointer -but no clock from the host is given, the data stuck at this async fifo waiting -host toggles SCK. This value represents the number of bytes. - -### ASYNC_FIFO_LEVEL . rxlvl -RX Async FIFO level. - -This value shows the number of available entry in RX Async FIFO. - ## STATUS SPI Device status register -- Offset: `0x20` -- Reset default: `0x7a` -- Reset mask: `0x7f` - -### Fields - -```wavejson -{"reg": [{"name": "rxf_full", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "rxf_empty", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "txf_full", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "txf_empty", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "abort_done", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "csb", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "tpm_csb", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 25}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-----------|:---------------------------------------------------------------------------------------------------------| -| 31:7 | | | | Reserved | -| 6 | ro | 0x1 | tpm_csb | Direct input of TPM CSb | -| 5 | ro | 0x1 | csb | Direct input of CSb signal | -| 4 | ro | 0x1 | abort_done | Abort process is completed. Current version does not implement abort_done logic. It is tied to 1 always. | -| 3 | ro | 0x1 | txf_empty | TX FIFO empty | -| 2 | ro | x | txf_full | TX FIFO full | -| 1 | ro | 0x1 | rxf_empty | RX FIFO empty | -| 0 | ro | x | rxf_full | RX FIFO full | - -## RXF_PTR -Receiver FIFO (SRAM) pointers -- Offset: `0x24` -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Fields - -```wavejson -{"reg": [{"name": "RPTR", "bits": 16, "attr": ["rw"], "rotate": 0}, {"name": "WPTR", "bits": 16, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:----------------------------------------------------------------------| -| 31:16 | ro | 0x0 | WPTR | Write pointer. Bit x is phase bit. | -| 15:0 | rw | 0x0 | RPTR | Read pointer. bit x is for phase bit. check circular fifo description | - -## TXF_PTR -Transmitter FIFO (SRAM) pointers -- Offset: `0x28` -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Fields - -```wavejson -{"reg": [{"name": "RPTR", "bits": 16, "attr": ["ro"], "rotate": 0}, {"name": "WPTR", "bits": 16, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:----------------------------------------------------------------------| -| 31:16 | rw | 0x0 | WPTR | Write pointer. Bit x is phase bit. | -| 15:0 | ro | 0x0 | RPTR | Read pointer. bit x is for phase bit. check circular fifo description | - -## RXF_ADDR -Receiver FIFO (SRAM) Addresses -- Offset: `0x2c` -- Reset default: `0x1fc0000` -- Reset mask: `0xffffffff` - -### Fields - -```wavejson -{"reg": [{"name": "base", "bits": 16, "attr": ["rw"], "rotate": 0}, {"name": "limit", "bits": 16, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:-------------------------------------------------------------| -| 31:16 | rw | 0x1fc | limit | Limit offset in bytes in the SRAM. Lower 2 bits are ignored. | -| 15:0 | rw | 0x0 | base | Base offset in bytes in the SRAM. Lower 2 bits are ignored. | - -## TXF_ADDR -Transmitter FIFO (SRAM) Addresses -- Offset: `0x30` -- Reset default: `0x3fc0200` -- Reset mask: `0xffffffff` +- Offset: `0x18` +- Reset default: `0x60` +- Reset mask: `0x60` ### Fields ```wavejson -{"reg": [{"name": "base", "bits": 16, "attr": ["rw"], "rotate": 0}, {"name": "limit", "bits": 16, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +{"reg": [{"bits": 5}, {"name": "csb", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "tpm_csb", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 25}], "config": {"lanes": 1, "fontsize": 10, "vspace": 90}} ``` -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:-------------------------------------------------------------| -| 31:16 | rw | 0x3fc | limit | Limit offset in bytes in the SRAM. Lower 2 bits are ignored. | -| 15:0 | rw | 0x200 | base | Base offset in bytes in the SRAM. Lower 2 bits are ignored. | +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:--------|:---------------------------| +| 31:7 | | | | Reserved | +| 6 | ro | 0x1 | tpm_csb | Direct input of TPM CSb | +| 5 | ro | 0x1 | csb | Direct input of CSb signal | +| 4:0 | | | | Reserved | ## INTERCEPT_EN Intercept Passthrough datapath. -- Offset: `0x34` +- Offset: `0x1c` - Reset default: `0x0` - Reset mask: `0xf` @@ -494,7 +294,7 @@ Last Read Address This register shows the last address accessed by the host system. It is updated by the HW when CSb is de-asserted. -- Offset: `0x38` +- Offset: `0x20` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -519,7 +319,7 @@ maintain this register value up to date. The HW latches the value when SPI Flash transaction begins. Any updates during the transaction will be updated after the transaction is completed. -- Offset: `0x3c` +- Offset: `0x24` - Reset default: `0x0` - Reset mask: `0xffffff` @@ -573,7 +373,7 @@ JEDEC Continuation Code configuration register. Read JEDEC ID must return the continuation code if the manufacturer ID is not shown in the first page of JEDEC table. This register controls the Continuation Code. -- Offset: `0x40` +- Offset: `0x28` - Reset default: `0x7f` - Reset mask: `0xffff` @@ -591,7 +391,7 @@ the Continuation Code. ## JEDEC_ID JEDEC ID register. -- Offset: `0x44` +- Offset: `0x2c` - Reset default: `0x0` - Reset mask: `0xffffff` @@ -610,7 +410,7 @@ JEDEC ID register. ## READ_THRESHOLD Read Buffer threshold register. -- Offset: `0x48` +- Offset: `0x30` - Reset default: `0x0` - Reset mask: `0x3ff` @@ -630,7 +430,7 @@ Mailbox Base address register. The mailbox size is fixed. In this version of IP, the size is 1kB. Lower 10 bits of the Mailbox address is tied to 0. -- Offset: `0x4c` +- Offset: `0x34` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -646,7 +446,7 @@ Lower 10 bits of the Mailbox address is tied to 0. ## UPLOAD_STATUS Upload module status register. -- Offset: `0x50` +- Offset: `0x38` - Reset default: `0x0` - Reset mask: `0x9f9f` @@ -678,7 +478,7 @@ payload in a command, this field may not be 0. For example, if the system issues 258B payload, the payload_depth is 256 (as the IP only holds 256B of payload), the payload_start_idx is 2. SW should read from 2 to 255 then 0 and 1. -- Offset: `0x54` +- Offset: `0x3c` - Reset default: `0x0` - Reset mask: `0xff01ff` @@ -697,7 +497,7 @@ holds 256B of payload), the payload_start_idx is 2. SW should read from ## UPLOAD_CMDFIFO Command Fifo Read Port. -- Offset: `0x58` +- Offset: `0x40` - Reset default: `0x0` - Reset mask: `0xff` @@ -714,7 +514,7 @@ Command Fifo Read Port. ## UPLOAD_ADDRFIFO Address Fifo Read Port. -- Offset: `0x5c` +- Offset: `0x44` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -733,7 +533,7 @@ Command Filter If a bit in this CSR is 1, then corresponding SPI command w.r.t the bit position among 256 bit is dropped in SPI Passthrough mode. -- Offset: `0x60` +- Offset: `0x48` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -783,7 +583,7 @@ Command Filter If a bit in this CSR is 1, then corresponding SPI command w.r.t the bit position among 256 bit is dropped in SPI Passthrough mode. -- Offset: `0x64` +- Offset: `0x4c` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -833,7 +633,7 @@ Command Filter If a bit in this CSR is 1, then corresponding SPI command w.r.t the bit position among 256 bit is dropped in SPI Passthrough mode. -- Offset: `0x68` +- Offset: `0x50` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -883,7 +683,7 @@ Command Filter If a bit in this CSR is 1, then corresponding SPI command w.r.t the bit position among 256 bit is dropped in SPI Passthrough mode. -- Offset: `0x6c` +- Offset: `0x54` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -933,7 +733,7 @@ Command Filter If a bit in this CSR is 1, then corresponding SPI command w.r.t the bit position among 256 bit is dropped in SPI Passthrough mode. -- Offset: `0x70` +- Offset: `0x58` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -983,7 +783,7 @@ Command Filter If a bit in this CSR is 1, then corresponding SPI command w.r.t the bit position among 256 bit is dropped in SPI Passthrough mode. -- Offset: `0x74` +- Offset: `0x5c` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -1033,7 +833,7 @@ Command Filter If a bit in this CSR is 1, then corresponding SPI command w.r.t the bit position among 256 bit is dropped in SPI Passthrough mode. -- Offset: `0x78` +- Offset: `0x60` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -1083,7 +883,7 @@ Command Filter If a bit in this CSR is 1, then corresponding SPI command w.r.t the bit position among 256 bit is dropped in SPI Passthrough mode. -- Offset: `0x7c` +- Offset: `0x64` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -1136,7 +936,7 @@ this register is set, the corresponding address bit in the SPI Read commands is replaced with the data from [`ADDR_SWAP_DATA.`](#addr_swap_data) If 3B address mode is active, upper 8bit [31:24] is ignored. -- Offset: `0x80` +- Offset: `0x68` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -1152,7 +952,7 @@ If 3B address mode is active, upper 8bit [31:24] is ignored. ## ADDR_SWAP_DATA The address value for the address swap feature. -- Offset: `0x84` +- Offset: `0x6c` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -1171,7 +971,7 @@ Write Data Swap in the passthrough mode. PAYLOAD_SWAP_MASK CSR provides the SW to change certain bits in the first 4 bytes of the write payload in the passthrough mode. -- Offset: `0x88` +- Offset: `0x70` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -1195,7 +995,7 @@ passthrough mode. The register should be written in Little-Endian order. [7:0] bits are processed in the first received payload byte. [31:24] bits for the 4th byte. -- Offset: `0x8c` +- Offset: `0x74` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -1219,30 +1019,30 @@ Command Info register. | Name | Offset | |:------------|:---------| -| CMD_INFO_0 | 0x90 | -| CMD_INFO_1 | 0x94 | -| CMD_INFO_2 | 0x98 | -| CMD_INFO_3 | 0x9c | -| CMD_INFO_4 | 0xa0 | -| CMD_INFO_5 | 0xa4 | -| CMD_INFO_6 | 0xa8 | -| CMD_INFO_7 | 0xac | -| CMD_INFO_8 | 0xb0 | -| CMD_INFO_9 | 0xb4 | -| CMD_INFO_10 | 0xb8 | -| CMD_INFO_11 | 0xbc | -| CMD_INFO_12 | 0xc0 | -| CMD_INFO_13 | 0xc4 | -| CMD_INFO_14 | 0xc8 | -| CMD_INFO_15 | 0xcc | -| CMD_INFO_16 | 0xd0 | -| CMD_INFO_17 | 0xd4 | -| CMD_INFO_18 | 0xd8 | -| CMD_INFO_19 | 0xdc | -| CMD_INFO_20 | 0xe0 | -| CMD_INFO_21 | 0xe4 | -| CMD_INFO_22 | 0xe8 | -| CMD_INFO_23 | 0xec | +| CMD_INFO_0 | 0x78 | +| CMD_INFO_1 | 0x7c | +| CMD_INFO_2 | 0x80 | +| CMD_INFO_3 | 0x84 | +| CMD_INFO_4 | 0x88 | +| CMD_INFO_5 | 0x8c | +| CMD_INFO_6 | 0x90 | +| CMD_INFO_7 | 0x94 | +| CMD_INFO_8 | 0x98 | +| CMD_INFO_9 | 0x9c | +| CMD_INFO_10 | 0xa0 | +| CMD_INFO_11 | 0xa4 | +| CMD_INFO_12 | 0xa8 | +| CMD_INFO_13 | 0xac | +| CMD_INFO_14 | 0xb0 | +| CMD_INFO_15 | 0xb4 | +| CMD_INFO_16 | 0xb8 | +| CMD_INFO_17 | 0xbc | +| CMD_INFO_18 | 0xc0 | +| CMD_INFO_19 | 0xc4 | +| CMD_INFO_20 | 0xc8 | +| CMD_INFO_21 | 0xcc | +| CMD_INFO_22 | 0xd0 | +| CMD_INFO_23 | 0xd4 | ### Fields @@ -1355,7 +1155,7 @@ Command Opcode Opcode for EN4B. If the register is active, it affects in flash / passthrough modes. -- Offset: `0xf0` +- Offset: `0xd8` - Reset default: `0x0` - Reset mask: `0x800000ff` @@ -1373,7 +1173,7 @@ If the register is active, it affects in flash / passthrough modes. ## CMD_INFO_EX4B Opcode for EX4B -- Offset: `0xf4` +- Offset: `0xdc` - Reset default: `0x0` - Reset mask: `0x800000ff` @@ -1391,7 +1191,7 @@ Opcode for EX4B ## CMD_INFO_WREN Opcode for Write Enable (WREN) -- Offset: `0xf8` +- Offset: `0xe0` - Reset default: `0x0` - Reset mask: `0x800000ff` @@ -1409,7 +1209,7 @@ Opcode for Write Enable (WREN) ## CMD_INFO_WRDI Opcode for Write Disable (WRDI) -- Offset: `0xfc` +- Offset: `0xe4` - Reset default: `0x0` - Reset mask: `0x800000ff` @@ -1777,10 +1577,9 @@ TPM Write command received data FIFO. ## buffer SPI internal buffer. -In Generic mode, this buffer is used for RX/TX buffer. In Flash & -Passthrough mode, lower 2kB is for Read content emulating eFlash. -next 1kB is for Mailbox read/write buffer. The rest is 256B SFDP -buffer, 32B of CmdFIFO, 32B of AddrFIFO, and 256B of payload FIFO. +The lower 2kB is for Read content emulating eFlash. The next 1 kB is +for Mailbox read/write buffer. The rest is 256B SFDP buffer, 32B of +CmdFIFO, 32B of AddrFIFO, and 256B of payload FIFO. - Word Aligned Offset Range: `0x1000`to`0x1ffc` - Size (words): `1024` diff --git a/hw/ip/spi_device/doc/rxf_ctrl_fsm.svg b/hw/ip/spi_device/doc/rxf_ctrl_fsm.svg deleted file mode 100644 index 58761aea9dfa8..0000000000000 --- a/hw/ip/spi_device/doc/rxf_ctrl_fsm.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/spi_device/doc/rxf_ctrl_fsm_table.png b/hw/ip/spi_device/doc/rxf_ctrl_fsm_table.png deleted file mode 100644 index 7ff8f8a095ad48bed6d7effbf9b5c00df1f0eb3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110916 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
    YGJ7n*kzFK_8bZKLYy{Hr9Nv$16 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 z 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 \ No newline at end of file diff --git a/hw/ip/spi_device/doc/txf_ctrl_fsm_table.png b/hw/ip/spi_device/doc/txf_ctrl_fsm_table.png deleted file mode 100644 index daf4a7d01a35f55444af28cd8d2ce25124717567..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80965 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

    R?`_6Cnb=Ts3qwu;=!J)Ncsj%w&cR+3FJ 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 e1BB_O&6B{ diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_abort_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_abort_vseq.sv deleted file mode 100644 index 61edb4030f90d..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_abort_vseq.sv +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Abort test, make TX FIFO full without host traffic, check for idle state -class spi_device_abort_vseq extends spi_device_base_vseq; - `uvm_object_utils(spi_device_abort_vseq) - `uvm_object_new - - virtual task body(); - bit [31:0] device_data; - bit tx_fifo_full = 0; - bit abort_done = 0; - - spi_device_fw_init(); - `DV_CHECK_RANDOMIZE_FATAL(this) - `DV_CHECK_STD_RANDOMIZE_FATAL(device_data) - - while (tx_fifo_full == 0) begin - write_device_words_to_send({device_data}); - csr_rd(.ptr(ral.status.txf_full), .value(tx_fifo_full)); - end - - cfg.clk_rst_vif.wait_clks(100); - ral.control.abort.set(1'b1); - csr_update(.csr(ral.control)); - //TODO Abort done returns 1 - Issue 9823 for implementation - while (abort_done == 0) begin - csr_rd(.ptr(ral.status.abort_done), .value(abort_done)); - end - ral.control.abort.set(1'b0); - csr_update(.csr(ral.control)); - cfg.clk_rst_vif.wait_clks(100); - //TODO Checking when we get feedback on issue 9822 - endtask : body - -endclass : spi_device_abort_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv index d9f5c2c8cb3fb..10885adc98140 100644 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv +++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv @@ -18,19 +18,6 @@ class spi_device_base_vseq extends cip_base_vseq #( rand bit host_bit_dir; rand bit device_bit_dir; - rand uint sram_host_base_addr; - rand uint sram_host_limit_addr; - rand uint sram_device_base_addr; - rand uint sram_device_limit_addr; - // helper variables - rand uint num_host_sram_words; - rand uint num_device_sram_words; - rand uint sram_host_byte_size; - rand uint sram_device_byte_size; - - rand bit [15:0] tx_watermark_lvl; - rand bit [15:0] rx_watermark_lvl; - // core clk freq / spi clk freq is from 1/4 to 8. use below 2 var to represent the ratio // if spi_freq_faster, core_spi_freq_ratio = spi clk freq / core clk freq (1:4) // if !spi_freq_faster, core_spi_freq_ratio = core clk freq / spi clk freq (1:8) @@ -39,40 +26,6 @@ class spi_device_base_vseq extends cip_base_vseq #( bit kill_spi_device_flash_auto_rsp; - // override it in random seq - constraint sram_addr_c { - // host and device addr space within sram should not overlap - sram_host_base_addr == 32'h0; - sram_host_limit_addr == 32'h1ff; // 512 bytes - sram_device_base_addr == 32'h200; - sram_device_limit_addr == 32'h3ff; // 512 bytes - } - - constraint sram_size_c { - solve num_host_sram_words before sram_host_byte_size; - solve num_device_sram_words before sram_device_byte_size; - num_host_sram_words == sram_host_limit_addr[31:2] - sram_host_base_addr[31:2] + 1; - num_device_sram_words == sram_device_limit_addr[31:2] - sram_device_base_addr[31:2] + 1; - sram_host_byte_size == num_host_sram_words << 2; - sram_device_byte_size == num_device_sram_words << 2; - } - - constraint tx_watermark_lvl_c { - tx_watermark_lvl dist { - [0 : SRAM_WORD_SIZE] :/ 1, // first 2 words - [SRAM_WORD_SIZE+1 : sram_host_byte_size-1-SRAM_WORD_SIZE] :/ 7, - [sram_host_byte_size-SRAM_WORD_SIZE : sram_host_byte_size] :/ 1, // max 2 words - [sram_host_byte_size+1 : SRAM_SIZE] :/ 1};// over the max size - } - - constraint rx_watermark_lvl_c { - rx_watermark_lvl dist { - [0 : SRAM_WORD_SIZE] :/ 1, // first 2 words - [SRAM_WORD_SIZE+1 : sram_device_byte_size-1-SRAM_WORD_SIZE] :/ 7, - [sram_device_byte_size-SRAM_WORD_SIZE : sram_device_byte_size] :/ 1, // max 2 words - [sram_device_byte_size+1 : SRAM_SIZE] :/ 1};// over the max size - } - // core clk freq / spi clk freq is from 1/4 to 8 constraint freq_c { core_spi_freq_ratio inside {[1:8]}; @@ -84,7 +37,6 @@ class spi_device_base_vseq extends cip_base_vseq #( virtual task apply_reset(string kind = "HARD"); super.apply_reset(kind); cfg.do_spi_clk_configure = 1; - cfg.do_spi_device_fw_mem_cfg = 1; cfg.do_addr_4b_cfg = 1; endtask @@ -106,19 +58,6 @@ class spi_device_base_vseq extends cip_base_vseq #( cfg.clk_rst_vif.wait_clks(2); endtask - // check if any remaining data - virtual task check_for_tx_rx_idle(); - uint tx_avail_bytes, rx_avail_bytes; - read_tx_avail_bytes(SramDataAvail, tx_avail_bytes); - `DV_CHECK_EQ(tx_avail_bytes, 0); - read_rx_avail_bytes(SramDataAvail, rx_avail_bytes); - `DV_CHECK_EQ(rx_avail_bytes, 0); - csr_rd_check(.ptr(ral.status.rxf_empty), .compare_value(1)); - // level should be 0 - csr_rd_check(.ptr(ral.async_fifo_level.txlvl), .compare_value(0)); - csr_rd_check(.ptr(ral.async_fifo_level.rxlvl), .compare_value(0)); - endtask - // configure the clock frequence virtual task spi_clk_init(); if (cfg.do_spi_clk_configure) begin @@ -137,97 +76,6 @@ class spi_device_base_vseq extends cip_base_vseq #( end endtask - virtual task spi_device_fw_init(); - spi_clk_init(); - // update host agent - cfg.spi_host_agent_cfg.sck_polarity[0] = sck_polarity; - cfg.spi_host_agent_cfg.sck_phase[0] = sck_phase; - cfg.spi_host_agent_cfg.host_bit_dir = host_bit_dir; - cfg.spi_host_agent_cfg.device_bit_dir = device_bit_dir; - cfg.spi_host_agent_cfg.csid = 0; - cfg.spi_host_agent_cfg.partial_byte = 0; - cfg.spi_host_agent_cfg.decode_commands = 0; - cfg.spi_host_agent_cfg.num_bytes_per_trans_in_mon = 4; - - // update device rtl - ral.control.mode.set(GenericMode); - csr_update(.csr(ral.control)); - ral.cfg.cpol.set(sck_polarity); - ral.cfg.cpha.set(sck_phase); - ral.cfg.tx_order.set(device_bit_dir); - ral.cfg.rx_order.set(host_bit_dir); - //ral.cfg.timer_v.set(rx_timer); TODO do it later - csr_update(.csr(ral.cfg)); - - // watermark - ral.fifo_level.txlvl.set(tx_watermark_lvl); - ral.fifo_level.rxlvl.set(rx_watermark_lvl); - csr_update(.csr(ral.fifo_level)); - - // intr_enable - `DV_CHECK_RANDOMIZE_FATAL(ral.intr_enable) - csr_update(.csr(ral.intr_enable)); - - if (cfg.do_spi_device_fw_mem_cfg) begin - set_sram_host_addr_range(sram_host_base_addr, sram_host_limit_addr); - set_sram_device_addr_range(sram_device_base_addr, sram_device_limit_addr); - // only configure sram once - cfg.do_spi_device_fw_mem_cfg = 0; - sram_host_base_addr.rand_mode(0); - sram_host_limit_addr.rand_mode(0); - sram_device_base_addr.rand_mode(0); - sram_device_limit_addr.rand_mode(0); - end - endtask - - virtual task reset_fifo(bit txfifo, bit rxfifo); - ral.control.rst_txfifo.set(txfifo); - ral.control.rst_rxfifo.set(rxfifo); - csr_update(.csr(ral.control)); - endtask - - // set sram circular fifo limits for tx (spi_device) - // args are 32 bits to be generic - corresponding fields are only 16 bits - virtual task set_sram_device_addr_range(bit [31:0] base, - bit [31:0] limit); - ral.txf_addr.base.set(base); - ral.txf_addr.limit.set(limit); - csr_update(.csr(ral.txf_addr)); - endtask - - // set sram circular fifo limits for rx (host agant) - // args are 32 bits to be generic - corresponding fields are only 16 bits - virtual task set_sram_host_addr_range(bit [31:0] base, - bit [31:0] limit); - ral.rxf_addr.base.set(base); - ral.rxf_addr.limit.set(limit); - csr_update(.csr(ral.rxf_addr)); - endtask - - // set a byte of data via host agent, receive a byte of data from spi_device - virtual task spi_host_xfer_byte(bit [7:0] host_data, ref bit [7:0] device_data); - spi_host_seq m_spi_host_seq; - `uvm_create_on(m_spi_host_seq, p_sequencer.spi_sequencer_h) - `DV_CHECK_RANDOMIZE_WITH_FATAL(m_spi_host_seq, - data.size() == 1; - data[0] == host_data;) - `uvm_send(m_spi_host_seq) - device_data = m_spi_host_seq.rsp.data[0]; - endtask - - // set a word (32 bits) of data via host agent, receive a word of data from spi_device - virtual task spi_host_xfer_word(bit [31:0] host_data, ref bit [31:0] device_data); - spi_host_seq m_spi_host_seq; - byte data_bytes[SRAM_WORD_SIZE]; - {<<8{data_bytes}} = host_data; - `uvm_create_on(m_spi_host_seq, p_sequencer.spi_sequencer_h) - `DV_CHECK_RANDOMIZE_WITH_FATAL(m_spi_host_seq, - data.size() == SRAM_WORD_SIZE; - foreach (data[i]) {data[i] == data_bytes[i];}) - `uvm_send(m_spi_host_seq) - device_data = {<<8{m_spi_host_seq.rsp.data}}; - endtask - virtual task spi_host_wait_on_busy(); spi_host_flash_seq m_spi_host_seq; `uvm_create_on(m_spi_host_seq, p_sequencer.spi_sequencer_h) @@ -269,16 +117,6 @@ class spi_device_base_vseq extends cip_base_vseq #( kill_spi_device_flash_auto_rsp = 1; endtask - // set a random chunk of bytes of data via host agent and receive same number of data from device - virtual task spi_host_xfer_bytes(int num_bytes = $urandom_range(1, 512), - ref bit [7:0] device_data[$]); - spi_host_seq m_spi_host_seq; - `uvm_create_on(m_spi_host_seq, p_sequencer.spi_sequencer_h) - `DV_CHECK_RANDOMIZE_WITH_FATAL(m_spi_host_seq, data.size() == num_bytes;) - `uvm_send(m_spi_host_seq) - device_data = m_spi_host_seq.rsp.data; - endtask - // send dummy item virtual task spi_host_xfer_dummy_item(); spi_host_dummy_seq m_spi_host_seq; @@ -288,185 +126,4 @@ class spi_device_base_vseq extends cip_base_vseq #( `uvm_send(m_spi_host_seq) endtask - // write spi device data to send when incoming host traffic arrives - virtual task write_device_words_to_send(bit [31:0] device_data[$]); - bit [TL_DW-1:0] tx_wptr; - uint tx_sram_size_bytes = `GET_TX_ALLOCATED_SRAM_SIZE_BYTES; - - // write data to tx base address + curr tx wptr - tx_wptr = ral.txf_ptr.wptr.get_mirrored_value(); - foreach (device_data[i]) begin - bit [TL_DW-1:0] tx_wptr_addr; - bit [TL_DW-1:0] tx_base_addr = ral.txf_addr.base.get_mirrored_value(); - tx_base_addr[1:0] = 0; // ignore lower 2 bits - tx_wptr_addr = cfg.sram_start_addr + tx_base_addr + tx_wptr[SRAM_MSB:0]; - `uvm_info(`gfn, $sformatf({"tx_wptr[SRAM_MSB:0] = 0x%0h, tx_wptr_phase_bit = 0x%0h, ", - "tx_sram_size_bytes = 0x%0h, tx_wptr_addr = 0x%0h"}, - tx_wptr[SRAM_MSB:0], tx_wptr[SRAM_PTR_PHASE_BIT], - tx_sram_size_bytes, tx_wptr_addr), UVM_MEDIUM) - tl_access(.addr(tx_wptr_addr), .write(1'b1), .data(device_data[i])); // TODO: bkdr wr? - - // advance tx wptr by SRAM_WORD_SIZE - tx_wptr = get_sram_new_ptr(.ptr(tx_wptr), - .increment(SRAM_WORD_SIZE), - .sram_size_bytes(tx_sram_size_bytes)); - `uvm_info(`gfn, $sformatf("new tx_wptr = 0x%0h", tx_wptr), UVM_MEDIUM) - end - - // update txf_ptr.wptr - tx_wptr = get_csr_val_with_updated_field(ral.txf_ptr.wptr, ral.txf_ptr.get(), tx_wptr); - csr_wr(.ptr(ral.txf_ptr), .value(tx_wptr)); - endtask - - // read spi host data received from the host - virtual task read_host_words_rcvd(uint num_words, ref bit [31:0] host_data[$]); - bit [TL_DW-1:0] rx_rptr; - uint rx_sram_size_bytes = `GET_RX_ALLOCATED_SRAM_SIZE_BYTES; - - // read data from rx base address + curr rptr - rx_rptr = ral.rxf_ptr.rptr.get_mirrored_value(); - repeat (num_words) begin - bit [TL_DW-1:0] rx_rptr_addr; - bit [TL_DW-1:0] word_data; - bit [TL_DW-1:0] rx_base_addr = ral.rxf_addr.base.get_mirrored_value(); - rx_base_addr[1:0] = 0; // ignore lower 2 bits - rx_rptr_addr = cfg.sram_start_addr + rx_base_addr + rx_rptr[SRAM_MSB:0]; - `uvm_info(`gfn, $sformatf({"rx_rptr[SRAM_MSB:0] = 0x%0h, rx_rptr_phase_bit = 0x%0h, ", - "rx_sram_size_bytes = 0x%0h, rx_rptr_addr = 0x%0h"}, - rx_rptr[SRAM_MSB:0], rx_rptr[SRAM_PTR_PHASE_BIT], - rx_sram_size_bytes, rx_rptr_addr), UVM_MEDIUM) - tl_access(.addr(rx_rptr_addr), .write(1'b0), .data(word_data)); // TODO: bkdr rd? - host_data.push_back(word_data); - // advance rx rptr by SRAM_WORD_SIZE - rx_rptr = get_sram_new_ptr(.ptr(rx_rptr), - .increment(SRAM_WORD_SIZE), - .sram_size_bytes(rx_sram_size_bytes)); - `uvm_info(`gfn, $sformatf("new rx_rptr = 0x%0h", rx_rptr), UVM_MEDIUM) - end - - // update rxf_ptr.rptr - csr_wr(.ptr(ral.rxf_ptr), .value(rx_rptr)); - endtask - - virtual task read_tx_avail_bytes(sram_avail_type_e avail_type, ref uint avail_bytes); - bit [TL_DW-1:0] rptr; - bit [TL_DW-1:0] wptr; - uint sram_size_bytes = `GET_TX_ALLOCATED_SRAM_SIZE_BYTES; - - csr_rd(.ptr(ral.txf_ptr.rptr), .value(rptr)); - wptr = ral.txf_ptr.wptr.get_mirrored_value(); - case(avail_type) - SramDataAvail: begin - avail_bytes = get_sram_filled_bytes(wptr, rptr, sram_size_bytes, "read_tx_avail_bytes"); - // if sram has no data, check async fifo level - if (avail_bytes == 0) begin - uint fifo_lvl; - csr_rd(.ptr(ral.async_fifo_level.txlvl), .value(fifo_lvl)); - avail_bytes += fifo_lvl; - end - end - SramSpaceAvail: begin - avail_bytes = get_sram_space_bytes(wptr, rptr, sram_size_bytes, "read_tx_avail_bytes"); - end - endcase - `uvm_info(`gfn, $sformatf("TX avail_type = %0s, avail_bytes = %0d", - avail_type.name, avail_bytes), UVM_MEDIUM) - endtask - - virtual task read_rx_avail_bytes(sram_avail_type_e avail_type, ref uint avail_bytes); - bit [TL_DW-1:0] rptr; - bit [TL_DW-1:0] wptr; - uint sram_size_bytes = `GET_RX_ALLOCATED_SRAM_SIZE_BYTES; - - csr_rd(.ptr(ral.rxf_ptr.wptr), .value(wptr)); - rptr = ral.rxf_ptr.rptr.get_mirrored_value(); - case(avail_type) - SramDataAvail: begin - avail_bytes = get_sram_filled_bytes(wptr, rptr, sram_size_bytes, "read_rx_avail_bytes"); - end - SramSpaceAvail: begin - avail_bytes = get_sram_space_bytes(wptr, rptr, sram_size_bytes, "read_rx_avail_bytes"); - end - endcase - `uvm_info(`gfn, $sformatf("RX avail_type = %0s, avail_bytes = %0d", - avail_type.name, avail_bytes), UVM_MEDIUM) - endtask - - virtual task wait_for_tx_avail_bytes(uint req_bytes, sram_avail_type_e avail_type, - ref uint avail_bytes); - uint cur_bytes; - `DV_SPINWAIT( - do begin - read_tx_avail_bytes(avail_type, cur_bytes); - end while (cur_bytes < req_bytes);, - {"wait_for_tx_avail_bytes::", avail_type.name}, - default_timeout_ns * 2 - ) - avail_bytes = cur_bytes; - `uvm_info(`gfn, $sformatf("TX req_bytes = %0d, avail_type = %0s, avail_bytes = %0d", - req_bytes, avail_type.name, avail_bytes), UVM_MEDIUM) - endtask - - virtual task wait_for_rx_avail_bytes(uint req_bytes, sram_avail_type_e avail_type, - ref uint avail_bytes); - uint cur_bytes; - `DV_SPINWAIT( - do begin - read_rx_avail_bytes(avail_type, cur_bytes); - end while (cur_bytes < req_bytes);, - {"wait_for_rx_avail_bytes::", avail_type.name}, - default_timeout_ns * 2 - ) - avail_bytes = cur_bytes; - `uvm_info(`gfn, $sformatf("RX req_bytes = %0d, avail_type = %0s, avail_bytes = %0d", - req_bytes, avail_type.name, avail_bytes), UVM_MEDIUM) - endtask - - // before spi host starts transfer, wait for tx to have enough data and rx to have enough space - // to avoid overflow and underflow - virtual task wait_for_tx_filled_rx_space_bytes(uint req_bytes, ref uint avail_bytes); - uint tx_avail_bytes, rx_avail_bytes; - fork - wait_for_tx_avail_bytes(req_bytes, SramDataAvail, tx_avail_bytes); - wait_for_rx_avail_bytes(req_bytes, SramSpaceAvail, rx_avail_bytes); - join - // return the less number - avail_bytes = (tx_avail_bytes < rx_avail_bytes) ? tx_avail_bytes : rx_avail_bytes; - endtask - - // before spi host starts transfer, check if tx has enough data and rx has enough space - // if return_out_of_range = 1, return more than actual available bytes - virtual task get_num_xfer_bytes(bit return_out_of_range, ref uint avail_bytes); - uint tx_avail_bytes, rx_avail_bytes, final_data_bytes; - - read_tx_avail_bytes(SramDataAvail, tx_avail_bytes); - read_rx_avail_bytes(SramSpaceAvail, rx_avail_bytes); - // get the less number to avoid under/overflow - avail_bytes = (tx_avail_bytes < rx_avail_bytes) ? tx_avail_bytes : rx_avail_bytes; - - if (return_out_of_range) begin - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(final_data_bytes, - final_data_bytes[1:0] == 0; - final_data_bytes inside {[avail_bytes+1:SRAM_SIZE]};) - avail_bytes = final_data_bytes; - end - endtask - - virtual function void fifo_underflow_overflow_sva_control(bit enable); - if (enable) begin - $asserton(0, "tb.dut.u_txf_underflow.SrcPulseCheck_M"); - $asserton(0, "tb.dut.u_txf_underflow.DstPulseCheck_A"); - $asserton(0, "tb.dut.u_rxf_overflow.SrcPulseCheck_M"); - if (cfg.en_dv_cdc) begin - $asserton(0, "tb.dut.u_rxf_overflow.DstPulseCheck_A"); - end - end else begin - $assertoff(0, "tb.dut.u_txf_underflow.SrcPulseCheck_M"); - $assertoff(0, "tb.dut.u_txf_underflow.DstPulseCheck_A"); - $assertoff(0, "tb.dut.u_rxf_overflow.SrcPulseCheck_M"); - if (cfg.en_dv_cdc) begin - $assertoff(0, "tb.dut.u_rxf_overflow.DstPulseCheck_A"); - end - end - endfunction endclass : spi_device_base_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_bit_transfer_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_bit_transfer_vseq.sv deleted file mode 100644 index a724d628acbdd..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_bit_transfer_vseq.sv +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Bit Access test to verify proper handling of partial byte transfers -// TODO, constrain not to send 7 bits, as that byte may or may not be dropped depends on -// the phase setting, which is low risk and makes scb too complicated. -class spi_device_bit_transfer_vseq extends spi_device_base_vseq; - `uvm_object_utils(spi_device_bit_transfer_vseq) - `uvm_object_new - - constraint num_trans_c { - num_trans == 20; - } - - virtual task body(); - bit [39:0] host_data; - bit [31:0] device_data; - bit [7:0] device_data_exp[$] = {1,2,3,4,5}; // Init - uint avail_bytes; - uint avail_data; - bit [2:0] bits_num; - - for (int i = 1; i <= num_trans; i++) begin - `uvm_info(`gfn, $sformatf("starting sequence %0d/%0d", i, num_trans), UVM_LOW) - `DV_CHECK_RANDOMIZE_FATAL(this) - spi_device_fw_init(); - repeat ($urandom_range(8)) begin - bit [31:0] host_data_exp_q[$]; - `DV_CHECK_STD_RANDOMIZE_FATAL(host_data) - `DV_CHECK_STD_RANDOMIZE_FATAL(device_data) - write_device_words_to_send({device_data}); - `uvm_info(`gfn, $sformatf("Device Data = 0x%0h", device_data), UVM_LOW) - cfg.clk_rst_vif.wait_clks(16); - cfg.spi_host_agent_cfg.partial_byte = 1; - // Randomize number of bits to send before CSB deassert - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(bits_num, bits_num inside {[1:6]};) - cfg.spi_host_agent_cfg.bits_to_transfer = bits_num; - `uvm_info(`gfn, $sformatf("Bits_num = 0x%0h", bits_num), UVM_LOW) - spi_host_xfer_byte(host_data[7:0], device_data_exp[0]); - `uvm_info(`gfn, $sformatf("new device data 0 = 0x%0h", device_data_exp[0]), UVM_LOW) - cfg.clk_rst_vif.wait_clks(4); - cfg.spi_host_agent_cfg.partial_byte = 0; - spi_host_xfer_byte(host_data[15:8], device_data_exp[1]); - `uvm_info(`gfn, $sformatf("new device data 1 = 0x%0h", device_data_exp[1]), UVM_LOW) - spi_host_xfer_byte(host_data[23:16], device_data_exp[2]); - `uvm_info(`gfn, $sformatf("new device data 2 = 0x%0h", device_data_exp[2]), UVM_LOW) - spi_host_xfer_byte(host_data[31:24], device_data_exp[3]); - `uvm_info(`gfn, $sformatf("new device data 3 = 0x%0h", device_data_exp[3]), UVM_LOW) - // In case of 7 bits, first 7 bits will not be repeated - if (bits_num < 7) begin - spi_host_xfer_byte(host_data[39:32], device_data_exp[4]); - `uvm_info(`gfn, $sformatf("new device data 4 = 0x%0h", device_data_exp[4]), UVM_LOW) - end - if (bits_num < 7) begin - `DV_CHECK_CASE_EQ(device_data, - {device_data_exp[4],device_data_exp[3], device_data_exp[2], device_data_exp[1]}) - end else begin - if (cfg.spi_host_agent_cfg.device_bit_dir == 1) begin - device_data[7] = 0; - end else begin - device_data[0] = 0; - end - `DV_CHECK_CASE_EQ(device_data, - {device_data_exp[3],device_data_exp[2], device_data_exp[1], device_data_exp[0]}) - end - - wait_for_rx_avail_bytes(SRAM_WORD_SIZE, SramDataAvail, avail_bytes); - `DV_CHECK_EQ(avail_bytes, SRAM_WORD_SIZE) - read_host_words_rcvd(1, host_data_exp_q); - // first byte is dropped due to partial byte sent - host_data = host_data >> 8; - `DV_CHECK_CASE_EQ(host_data, host_data_exp_q[0]) - end - end - endtask : body - -endclass : spi_device_bit_transfer_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_byte_transfer_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_byte_transfer_vseq.sv deleted file mode 100644 index 64894b4a7605b..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_byte_transfer_vseq.sv +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Byte Access test to verify proper byte data transfer without timeout expiring -class spi_device_byte_transfer_vseq extends spi_device_rx_timeout_vseq; - `uvm_object_utils(spi_device_byte_transfer_vseq) - `uvm_object_new - - constraint timeout_place_c { - timeout_place == 0; - } - - constraint num_trans_c { - num_trans == 10; - } - -endclass : spi_device_byte_transfer_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_dummy_item_extra_dly_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_dummy_item_extra_dly_vseq.sv deleted file mode 100644 index cb7fe62cf04f0..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_dummy_item_extra_dly_vseq.sv +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// test with more dummy csk/csb and more extra delay btw csk/word -class spi_device_dummy_item_extra_dly_vseq extends spi_device_txrx_vseq; - `uvm_object_utils(spi_device_dummy_item_extra_dly_vseq) - `uvm_object_new - - constraint en_extra_dly_c { - en_extra_dly == 1; - } - - virtual task spi_device_fw_init(); - allow_dummy_trans_pct = 100; - super.spi_device_fw_init(); - // use more aggressive delay, but if higher than below values, timeout may happen - randcase - 1: begin - cfg.spi_host_agent_cfg.max_extra_dly_ns_btw_sck = 100; - cfg.spi_host_agent_cfg.extra_dly_chance_pc_btw_sck = 20; - end - 1: begin - cfg.spi_host_agent_cfg.max_extra_dly_ns_btw_sck = 50; - cfg.spi_host_agent_cfg.extra_dly_chance_pc_btw_sck = 50; - end - endcase - // no timeout concern for delay between word - cfg.spi_host_agent_cfg.max_extra_dly_ns_btw_word = 10000; - cfg.spi_host_agent_cfg.extra_dly_chance_pc_btw_word = 20; - endtask - -endclass : spi_device_dummy_item_extra_dly_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_extreme_fifo_size_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_extreme_fifo_size_vseq.sv deleted file mode 100644 index 6afc813b33dc4..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_extreme_fifo_size_vseq.sv +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// test tx/rx sram fifo with extreme setting, size 1 word and SRAM_SIZE-1 word -class spi_device_extreme_fifo_size_vseq extends spi_device_txrx_vseq; - `uvm_object_utils(spi_device_extreme_fifo_size_vseq) - `uvm_object_new - - constraint sram_size_constraints_c { - num_host_sram_words dist { - 1 :/ 1, // 1 word - SRAM_SIZE[31:2]/2 :/ 1, // half of the total mem - SRAM_SIZE[31:2]-1 :/ 1, // max size - [2:SRAM_SIZE[31:2]-2] :/ 1 - }; - num_device_sram_words dist { - 1 :/ 1, // 1 word - SRAM_SIZE[31:2]/2 :/ 1, // half of the total mem - SRAM_SIZE[31:2]-1 :/ 1, // max size - [2:SRAM_SIZE[31:2]-2] :/ 1 - }; - } - - // reduce total data to reduce sim time as fifo size is too small and it takes much longer time - // to finish - constraint tx_total_bytes_c { - tx_total_bytes inside {[SRAM_SIZE/2 : SRAM_SIZE*2]}; - tx_total_bytes[1:0] == 0; // word aligned - } - - constraint num_trans_c { - num_trans == 2; - } -endclass : spi_device_extreme_fifo_size_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_fifo_full_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_fifo_full_vseq.sv deleted file mode 100644 index ab123b0536fe0..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_fifo_full_vseq.sv +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// test tx/rx sram fifo full by controlling the distribution of delay -// use less delay for tx write, regular delay for spi and the more delay for rx read -class spi_device_fifo_full_vseq extends spi_device_txrx_vseq; - `uvm_object_utils(spi_device_fifo_full_vseq) - `uvm_object_new - - // additional constraint for tx_total_bytes to transfer more data - constraint tx_total_bytes_additional_c { - tx_total_bytes inside {[5 * SRAM_SIZE : 7 * SRAM_SIZE]}; - } - - constraint tx_delay_c { - tx_delay inside {[0 : 10]}; - } - - constraint rx_delay_c { - rx_delay dist { - 0 :/ 1, - [1 : 100] :/ 1, - [101 : 2_000] :/ 8 - }; - } - - constraint num_trans_c { - num_trans inside {[2:3]}; - } - -endclass : spi_device_fifo_full_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_fifo_underflow_overflow_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_fifo_underflow_overflow_vseq.sv deleted file mode 100644 index 4bb7888d319e6..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_fifo_underflow_overflow_vseq.sv +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// test tx sram fifo underflow and rx sram fifo overflow by overriding -// read_tx_filled_rx_space_bytes to send spi transfer when there is no space no data available -class spi_device_fifo_underflow_overflow_vseq extends spi_device_txrx_vseq; - `uvm_object_utils(spi_device_fifo_underflow_overflow_vseq) - `uvm_object_new - - constraint num_trans_c { - num_trans inside {[2:3]}; - } - - virtual task body(); - // overflow will occur in this test, disable overflow assertion in RTL - fifo_underflow_overflow_sva_control(.enable(0)); - - allow_underflow_overflow = 1; - // when underflow, sio may be unknown, disable checking it - cfg.spi_host_agent_cfg.en_monitor_checks = 0; - super.body(); - cfg.spi_host_agent_cfg.en_monitor_checks = 1; - - fifo_underflow_overflow_sva_control(.enable(1)); - endtask - - // there may be some data left due to under/overflow, need to flush out all data - virtual task check_for_tx_rx_idle(); - uint tx_avail_bytes, rx_avail_bytes; - bit [31:0] device_words_q[$]; - - // flush out all remaining tx data in fifo due to overflow - while (1) begin - read_tx_avail_bytes(SramDataAvail, tx_avail_bytes); - if (tx_avail_bytes == 0) break; - process_spi_xfer(); - end - // there are some underflow data in fifo, clean them up - // repeat twice in case some data in async_fifo when sram fifo is full - for (uint i = 0; i < 2; i++) begin - cfg.clk_rst_vif.wait_clks(2); // 2 cycle for fifo ptr to be updated - read_rx_avail_bytes(SramDataAvail, rx_avail_bytes); - if (rx_avail_bytes == 0) break; - read_host_words_rcvd(rx_avail_bytes / SRAM_WORD_SIZE, device_words_q); - // in case data is transferred from async fifo, wait until transfer is done - if (i == 0) begin - csr_spinwait(.ptr(ral.async_fifo_level.rxlvl), .exp_data(0)); - end - end - - super.check_for_tx_rx_idle(); - endtask - -endclass : spi_device_fifo_underflow_overflow_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_intr_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_intr_vseq.sv deleted file mode 100644 index 0cadb34a9faf9..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_intr_vseq.sv +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// directly test all the interrupt one by one -// also test async fifo status - empty and full -class spi_device_intr_vseq extends spi_device_txrx_vseq; - `uvm_object_utils(spi_device_intr_vseq) - `uvm_object_new - - virtual task body(); - spi_device_intr_e spi_dev_intr; - bit is_tx_async_fifo_filled; - - // overflow will occur in this test, disable overflow assertion in RTL - fifo_underflow_overflow_sva_control(.enable(0)); - for (int i = 1; i <= num_trans; i++) begin - `DV_CHECK_RANDOMIZE_FATAL(this) - spi_device_fw_init(); - - // txf_empty and rxf_full value isn't guaranteed as it needs SPI to be live to update it - csr_rd_check(.ptr(ral.status.rxf_empty), .compare_value(1)); - csr_rd_check(.ptr(ral.status.txf_full), .compare_value(0)); - - // fill tx async fifo to avoid sending out unknown data - if (!is_tx_async_fifo_filled) begin - bit [7:0] device_bytes_q[$]; - // fill the fifo and wait until data is ready - process_tx_write(ASYNC_FIFO_SIZE); - csr_spinwait(.ptr(ral.async_fifo_level.txlvl), .exp_data(ASYNC_FIFO_SIZE)); - // clean up tx fifo - spi_host_xfer_bytes(ASYNC_FIFO_SIZE, device_bytes_q); - // clean up rx fifo - process_rx_read(ASYNC_FIFO_SIZE); - // clean interrupts - csr_wr(.ptr(ral.intr_state), .value('1)); - end - - repeat (NumSpiDevIntr) begin - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(spi_dev_intr, - spi_dev_intr inside {RxFifoFull, RxFifoGeLevel, TxFifoLtLevel, - RxFwModeErr, RxFifoOverflow, TxFifoUnderflow};) - `uvm_info(`gfn, $sformatf("\nTesting %0s", spi_dev_intr.name), UVM_LOW) - drive_and_check_one_intr(spi_dev_intr); - - csr_wr(.ptr(ral.intr_state), .value('1)); - check_for_tx_rx_idle(); - end - `uvm_info(`gfn, $sformatf("finished run %0d/%0d", i, num_trans), UVM_LOW) - end - fifo_underflow_overflow_sva_control(.enable(1)); - endtask : body - - task drive_and_check_one_intr(spi_device_intr_e spi_dev_intr); - bit [7:0] device_bytes_q[$]; - uint avail_bytes; - - case (spi_dev_intr) - RxFifoFull, RxFifoOverflow: begin // test fifo full and overflow together - // just below fifo full - spi_host_xfer_bytes(sram_host_byte_size - SRAM_WORD_SIZE, device_bytes_q); - wait_for_rx_avail_bytes(sram_host_byte_size - SRAM_WORD_SIZE, SramDataAvail, avail_bytes); - cfg.clk_rst_vif.wait_clks(4); // for interrupt to triggered - check_interrupts(.interrupts(1 << RxFifoFull), .check_set(0)); - - // fifo should be full - spi_host_xfer_bytes(SRAM_WORD_SIZE, device_bytes_q); - wait_for_rx_avail_bytes(sram_host_byte_size, SramDataAvail, avail_bytes); - check_interrupts(.interrupts(1 << RxFifoFull), .check_set(1)); - csr_rd_check(.ptr(ral.status.rxf_full), .compare_value(0)); - - // wait for some delay to move out of async fifo, then check it's empty - cfg.clk_rst_vif.wait_clks(20); - csr_rd_check(.ptr(ral.status.rxf_empty), .compare_value(1)); - - // fill async fifo and check fifo doesn't overflow - spi_host_xfer_bytes(ASYNC_FIFO_SIZE, device_bytes_q); - cfg.clk_rst_vif.wait_clks(4); // for interrupt to triggered - check_interrupts(.interrupts(1 << RxFifoOverflow), .check_set(0)); - // check async fifo status - csr_rd_check(.ptr(ral.status.rxf_empty), .compare_value(0)); - - // fill 1 word and check fifo overflow - spi_host_xfer_bytes(SRAM_WORD_SIZE, device_bytes_q); - check_interrupts(.interrupts(1 << RxFifoOverflow), .check_set(1)); - check_interrupts(.interrupts(1 << RxFifoGeLevel), - .check_set(rx_watermark_lvl inside {[1:sram_host_byte_size]})); - - // need spi clock to run in order to update rxf_full - csr_rd_check(.ptr(ral.status.rxf_full), .compare_value(1)); - // clean up rx fifo - process_rx_read(sram_host_byte_size + ASYNC_FIFO_SIZE); - end - RxFifoGeLevel: begin - uint aligned_watermark = (rx_watermark_lvl >> 2) << 2; // remove lsb 2bits - uint filled_bytes; - - if (rx_watermark_lvl[1:0] > 0) aligned_watermark += SRAM_WORD_SIZE; - - if (rx_watermark_lvl > 0 && aligned_watermark < sram_host_byte_size) begin - // just below watermark - if (aligned_watermark - SRAM_WORD_SIZE > 0) begin - spi_host_xfer_bytes(aligned_watermark - SRAM_WORD_SIZE, device_bytes_q); - wait_for_rx_avail_bytes(aligned_watermark - SRAM_WORD_SIZE, SramDataAvail, avail_bytes); - check_interrupts(.interrupts(1 << RxFifoGeLevel), .check_set(0)); - end - // equal to watermark - spi_host_xfer_bytes(SRAM_WORD_SIZE, device_bytes_q); - wait_for_rx_avail_bytes(aligned_watermark, SramDataAvail, avail_bytes); - check_interrupts(.interrupts(1 << RxFifoGeLevel), .check_set(1)); - - // clean interrupts and test it's edge triggered - filled_bytes = aligned_watermark + SRAM_WORD_SIZE; - csr_wr(.ptr(ral.intr_state), .value('1)); - spi_host_xfer_bytes(SRAM_WORD_SIZE, device_bytes_q); - wait_for_rx_avail_bytes(filled_bytes, SramDataAvail, avail_bytes); - check_interrupts(.interrupts(1 << RxFifoGeLevel), .check_set(0)); - - // clean up rx fifo - process_rx_read(filled_bytes); - end - end - TxFifoLtLevel: begin - uint aligned_watermark = (tx_watermark_lvl >> 2) << 2; // remove lsb 2bits - uint filled_bytes; - - if (tx_watermark_lvl[1:0] > 0) aligned_watermark += SRAM_WORD_SIZE; - - if (tx_watermark_lvl == 0 || tx_watermark_lvl > sram_device_byte_size) begin // no intr - // fill the sram fifo and async fifo, als wait until data is ready - process_tx_write(sram_device_byte_size + SRAM_WORD_SIZE); - wait_for_tx_avail_bytes(sram_device_byte_size, SramDataAvail, avail_bytes); - - // clean up tx fifo - spi_host_xfer_bytes(sram_device_byte_size + SRAM_WORD_SIZE, device_bytes_q); - - // clean up rx fifo - process_rx_read(dv_utils_pkg::min2(sram_host_byte_size + ASYNC_FIFO_SIZE, - sram_device_byte_size + SRAM_WORD_SIZE)); - // check no interrupt since tx_watermark_lvl is 0 or over the max size - check_interrupts(.interrupts(1 << TxFifoLtLevel), .check_set(0)); - end else begin - // fill async fifo, design has 2 words depth, but only update ptr to 2nd word when 1st - // one is out - process_tx_write(SRAM_WORD_SIZE); - csr_spinwait(.ptr(ral.async_fifo_level.txlvl), .exp_data(SRAM_WORD_SIZE)); - // just at watermark - if (aligned_watermark != 0) process_tx_write(aligned_watermark); - if (aligned_watermark > ASYNC_FIFO_SIZE) begin - cfg.clk_rst_vif.wait_clks($urandom_range(1, 10)); - check_interrupts(.interrupts(1 << TxFifoLtLevel), .check_set(0)); - csr_rd_check(.ptr(ral.status.txf_full), .compare_value(1)); - end - - // send one word and fifo is less than watermark - spi_host_xfer_bytes(SRAM_WORD_SIZE, device_bytes_q); - // txf_empty relies on spi clock to update. - if (aligned_watermark != 0) begin - csr_rd_check(.ptr(ral.status.txf_empty), .compare_value(0)); - end - cfg.clk_rst_vif.wait_clks(4); // for interrupt to triggered - check_interrupts(.interrupts(1 << TxFifoLtLevel), .check_set(1)); - - // clean up tx fifo - if (aligned_watermark != 0) spi_host_xfer_bytes(aligned_watermark, device_bytes_q); - - // clean up rx fifo - process_rx_read(dv_utils_pkg::min2(sram_host_byte_size + ASYNC_FIFO_SIZE, - aligned_watermark + SRAM_WORD_SIZE)); - end - end - RxFwModeErr: begin - // TODO, do it later - end - TxFifoUnderflow: begin - // send one word when fifo is empty - spi_host_xfer_bytes(SRAM_WORD_SIZE, device_bytes_q); - cfg.clk_rst_vif.wait_clks(4); // for interrupt to triggered - check_interrupts(.interrupts(1 << TxFifoUnderflow), .check_set(1)); - - // this needs spi clock to update. When it's empty and we keep spi clock live to make - // it underflow, we can guarantee this empty is set. - csr_rd_check(.ptr(ral.status.txf_empty), .compare_value(1)); - // clean up rx fifo - process_rx_read(SRAM_WORD_SIZE); - end - default: `uvm_fatal(`gfn, $sformatf("unexpected intr %s", spi_dev_intr.name)) - endcase - endtask : drive_and_check_one_intr -endclass : spi_device_intr_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_perf_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_perf_vseq.sv deleted file mode 100644 index 8a4099bf4a1a0..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_perf_vseq.sv +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// test tx/rx sram fifo full by controlling the distribution of delay -// use less delay for tx write, regular delay for spi and the more delay for rx read -// use minimal delays for maximum performance -class spi_device_perf_vseq extends spi_device_txrx_vseq; - `uvm_object_utils(spi_device_perf_vseq) - `uvm_object_new - - constraint tx_delay_c { - tx_delay inside {[0 : 1]}; - } - - constraint rx_delay_c { - rx_delay inside {[2 : 10]}; - } - - constraint num_trans_c { - num_trans == 2; - } - -endclass : spi_device_perf_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_rx_async_fifo_reset_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_rx_async_fifo_reset_vseq.sv deleted file mode 100644 index 336fbe36e46a6..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_rx_async_fifo_reset_vseq.sv +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// RX ASYNC FIFO test with driving data resetting async rx fifo and driving new data -class spi_device_rx_async_fifo_reset_vseq extends spi_device_txrx_vseq; - `uvm_object_utils(spi_device_rx_async_fifo_reset_vseq) - `uvm_object_new - - constraint sram_size_constraints_c { - num_host_sram_words dist { - 1 :/ 1, - 2 :/ 1, - 3 :/ 1, - 4 :/ 1 - }; - } - - virtual task body(); - bit [31:0] host_data; - bit [31:0] device_data; - bit [31:0] device_data_exp; - bit [7:0] rx_level; - uint avail_bytes; - uint avail_data; - bit [31:0] host_data_exp_q[$]; - - spi_device_fw_init(); - // Disable prim_flip_2sync destination pulse assertions - fifo_underflow_overflow_sva_control(0); - `DV_CHECK_STD_RANDOMIZE_FATAL(host_data) - `DV_CHECK_STD_RANDOMIZE_FATAL(device_data) - wait_for_tx_avail_bytes(SRAM_WORD_SIZE, SramSpaceAvail, avail_bytes); - // Start SPI transfers to fill up the RX SRAM FIFO and at least part of the RX async FIFO - for (int i = 0; i < 6; i++) begin - write_device_words_to_send({device_data}); - end - cfg.clk_rst_vif.wait_clks(16); - for (int i = 0; i < 6; i++) begin - spi_host_xfer_word(host_data, device_data_exp); - end - csr_rd(.ptr(ral.async_fifo_level.rxlvl), .value(rx_level)); - `DV_CHECK_CASE_NE(rx_level, 0) - // Program `rst_rxfifo` to reset the async FIFO - csr_wr(.ptr(ral.control.rst_rxfifo), .value(1)); - cfg.clk_rst_vif.wait_clks(100); - csr_wr(.ptr(ral.control.rst_rxfifo), .value(0)); - // Check `async_fifo_level.rxlvl` is 0 - csr_rd_check(.ptr(ral.async_fifo_level.rxlvl), .compare_value(0)); - // Write sram_host_base_addr into read and write point of RX SRAM FIFO - ral.rxf_ptr.wptr.set(sram_host_base_addr); - ral.rxf_ptr.rptr.set(sram_host_base_addr); - csr_update(.csr(ral.rxf_ptr)); - // Fill TX SRAM FIFO with some other data and start another SPI transfers - for (int i = 0; i < 6; i++) begin - write_device_words_to_send({32'h12345678}); - end - cfg.clk_rst_vif.wait_clks(16); - for (int i = 0; i < 6; i++) begin - spi_host_xfer_word(32'h12345678, device_data_exp); - end - // Restore prim_flip_2sync destination pulse assertions - fifo_underflow_overflow_sva_control(1); - - endtask : body - -endclass : spi_device_rx_async_fifo_reset_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_rx_timeout_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_rx_timeout_vseq.sv deleted file mode 100644 index 6c203cc3546cf..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_rx_timeout_vseq.sv +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Byte Access test to verify proper byte data transfer with timeout expiring -class spi_device_rx_timeout_vseq extends spi_device_base_vseq; - `uvm_object_utils(spi_device_rx_timeout_vseq) - `uvm_object_new - - rand bit [7:0] timeout; // Timeout value to be configured - rand bit [2:0] timeout_place; // Dictates bytes after which timeout will take place - - constraint timeout_c { - timeout >= 100; - } - - constraint num_trans_c { - num_trans == 20; - } - - virtual task transfer_check_byte(bit [1:0] byte_n, bit [7:0] tout, - bit [2:0] tout_place, bit [7:0] host_b, ref bit [7:0] device_d); - uint available_data; - bit [7:0] transfer_byte; - spi_host_xfer_byte(host_b, device_d); - if (tout_place == 3'd0 && byte_n < 3) begin - read_rx_avail_bytes(SramDataAvail, available_data); - `DV_CHECK_CASE_EQ(available_data, 0) - end - if (tout_place[byte_n] == 1'b1) begin - cfg.clk_rst_vif.wait_clks(tout + 10); - read_rx_avail_bytes(SramDataAvail, available_data); - `DV_CHECK_CASE_EQ(available_data, byte_n + 1) - end - endtask - - virtual task body(); - bit [31:0] host_data; - bit [31:0] device_data; - bit [7:0] device_data_exp[$]; - bit [7:0] device_byte; - uint avail_bytes; - uint avail_data; - - spi_device_fw_init(); - - for (int i = 1; i <= num_trans; i++) begin - `uvm_info(`gfn, $sformatf("starting sequence %0d/%0d", i, num_trans), UVM_LOW) - `DV_CHECK_RANDOMIZE_FATAL(this) - ral.cfg.timer_v.set(timeout); - csr_update(.csr(ral.cfg)); - repeat ($urandom_range(2, 10)) begin - bit [31:0] host_data_exp_q[$]; - `DV_CHECK_STD_RANDOMIZE_FATAL(host_data) - `DV_CHECK_STD_RANDOMIZE_FATAL(device_data) - // check if tx sram full and wait for at least a word to become available - wait_for_tx_avail_bytes(SRAM_WORD_SIZE, SramSpaceAvail, avail_bytes); - write_device_words_to_send({device_data}); - wait_for_tx_filled_rx_space_bytes(SRAM_WORD_SIZE, avail_bytes); - for (int i = 0; i <= 3; i++) begin - transfer_check_byte(i, timeout, timeout_place, host_data[i * 8 + 7 -: 8], device_byte); - device_data_exp[i] = device_byte; - end - cfg.clk_rst_vif.wait_clks(10); - read_rx_avail_bytes(SramDataAvail, avail_data); - `DV_CHECK_CASE_EQ(avail_data, 4) - read_host_words_rcvd(1, host_data_exp_q); - `DV_CHECK_CASE_EQ(host_data, host_data_exp_q[0]) - `DV_CHECK_CASE_EQ(device_data, - {device_data_exp[3], device_data_exp[2], device_data_exp[1], device_data_exp[0]}) - check_for_tx_rx_idle(); - end - end - endtask : body - -endclass : spi_device_rx_timeout_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_smoke_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_smoke_vseq.sv deleted file mode 100644 index a9eca70261dd7..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_smoke_vseq.sv +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// smoke test to verify host and device spi data transfers and circular fifo wrapping -// cpol, cpha, host and device data ordering and sram fofo limits are randomized -class spi_device_smoke_vseq extends spi_device_base_vseq; - `uvm_object_utils(spi_device_smoke_vseq) - `uvm_object_new - - constraint num_trans_c { - num_trans == 2; - } - - virtual task body(); - bit [31:0] host_data; - bit [31:0] device_data; - bit [31:0] device_data_exp; - uint avail_bytes; - - for (int i = 1; i <= num_trans; i++) begin - `uvm_info(`gfn, $sformatf("starting sequence %0d/%0d", i, num_trans), UVM_LOW) - `DV_CHECK_RANDOMIZE_FATAL(this) - spi_device_fw_init(); - repeat ($urandom_range(2, 10)) begin - bit [31:0] host_data_exp_q[$]; - `DV_CHECK_STD_RANDOMIZE_FATAL(host_data) - `DV_CHECK_STD_RANDOMIZE_FATAL(device_data) - // check if tx sram full and wait for at least a word to become available - wait_for_tx_avail_bytes(SRAM_WORD_SIZE, SramSpaceAvail, avail_bytes); - write_device_words_to_send({device_data}); - wait_for_tx_filled_rx_space_bytes(SRAM_WORD_SIZE, avail_bytes); - spi_host_xfer_word(host_data, device_data_exp); - // check if rx sram is empty and wait for at least a word to arrive - wait_for_rx_avail_bytes(SRAM_WORD_SIZE, SramDataAvail, avail_bytes); - read_host_words_rcvd(1, host_data_exp_q); - // TODO: move checks to scoreboard - `DV_CHECK_CASE_EQ(host_data, host_data_exp_q[0]) - `DV_CHECK_CASE_EQ(device_data, device_data_exp) - - check_for_tx_rx_idle(); - end - end - endtask : body - -endclass : spi_device_smoke_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_stress_all_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_stress_all_vseq.sv index 596bc50c9e9e4..4844a39fa9bf3 100644 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_stress_all_vseq.sv +++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_stress_all_vseq.sv @@ -16,13 +16,7 @@ class spi_device_stress_all_vseq extends spi_device_base_vseq; task body(); int num_flash_tpm_seq; - string seq_names[$] = {"spi_device_txrx_vseq", - "spi_device_fifo_full_vseq", - "spi_device_fifo_underflow_overflow_vseq", - "spi_device_extreme_fifo_size_vseq", - "spi_device_dummy_item_extra_dly_vseq", - "spi_device_intr_vseq", - "spi_device_perf_vseq", + string seq_names[$] = { "spi_device_csb_read_vseq", "spi_device_common_vseq" // for intr_test }; diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_tx_async_fifo_reset_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_tx_async_fifo_reset_vseq.sv deleted file mode 100644 index 983ff6969c2e3..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_tx_async_fifo_reset_vseq.sv +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// TX ASYNC FIFO test with driving data, resetting async tx fifo and driving new data -class spi_device_tx_async_fifo_reset_vseq extends spi_device_base_vseq; - `uvm_object_utils(spi_device_tx_async_fifo_reset_vseq) - `uvm_object_new - - virtual task body(); - bit [31:0] host_data; - bit [31:0] device_data; - bit [31:0] device_data_exp; - bit [7:0] tx_level; - uint avail_bytes; - uint avail_data; - bit [31:0] host_data_exp_q[$]; - - spi_device_fw_init(); - // Disable prim_flip_2sync destination pulse assertions - fifo_underflow_overflow_sva_control(0); - `DV_CHECK_STD_RANDOMIZE_FATAL(host_data) - `DV_CHECK_STD_RANDOMIZE_FATAL(device_data) - // Fill TX SRAM FIFO with some data, which will be transfered to TX async FIFO - wait_for_tx_avail_bytes(SRAM_WORD_SIZE, SramSpaceAvail, avail_bytes); - write_device_words_to_send({device_data}); //TODO random amount of data - cfg.clk_rst_vif.wait_clks(16); - csr_rd(.ptr(ral.async_fifo_level.txlvl), .value(tx_level)); - `DV_CHECK_CASE_NE(tx_level, 0) - // Program `rst_txfifo` to reset the async FIFO - ral.control.rst_txfifo.set(1'b1); - csr_update(.csr(ral.control)); - cfg.clk_rst_vif.wait_clks(100); - ral.control.rst_txfifo.set(1'b0); - csr_update(.csr(ral.control)); - // Check `async_fifo_level.txlvl` is 0 - csr_rd_check(.ptr(ral.async_fifo_level.txlvl), .compare_value(0)); - //Fill TX SRAM FIFO with some other data and enable SPI transfer - write_device_words_to_send({32'h12345678}); - cfg.clk_rst_vif.wait_clks(100); - spi_host_xfer_word(host_data, device_data_exp); - `DV_CHECK_CASE_EQ(32'h12345678, device_data_exp) - // Restore prim_flip_2sync destination pulse assertions - fifo_underflow_overflow_sva_control(1); - - endtask : body - -endclass : spi_device_tx_async_fifo_reset_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_txrx_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_txrx_vseq.sv deleted file mode 100644 index adfabb63e9626..0000000000000 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_txrx_vseq.sv +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// this is the base random test, extended by most of the other spi device tests -// there are 3 parallel threads in seq body -// 1. process_tx_write -// 2. process_rx_read -// 3. process_spi_transfer -class spi_device_txrx_vseq extends spi_device_base_vseq; - `uvm_object_utils(spi_device_txrx_vseq) - `uvm_object_new - - // total bytes for tx/rx for each iteration - rand uint tx_total_bytes; - rand uint rx_total_bytes; - - // delay - rand uint tx_delay; - rand uint rx_delay; - rand uint spi_delay; - - rand bit en_extra_dly; - - // helper rand variable - rand bit is_same_host_device_sram_words; - - // semaphores to avoid updating fifo ptr when over/underflow is happening. Issue #103 - semaphore tx_ptr_sema, rx_ptr_sema; - bit allow_underflow_overflow; - - constraint tx_total_bytes_c { - tx_total_bytes inside {[SRAM_SIZE : 10 * SRAM_SIZE]}; - tx_total_bytes[1:0] == 0; // word aligned - } - - constraint rx_total_bytes_c { - rx_total_bytes == tx_total_bytes; - } - - constraint tx_delay_c { - tx_delay dist { - 0 :/ 1, - [1 : 100] :/ 3, - [101 : 10_000] :/ 1 - }; - } - - constraint rx_delay_c { - rx_delay dist { - 0 :/ 1, - [1 : 100] :/ 3, - [101 : 10_000] :/ 1 - }; - } - - constraint spi_delay_c { - spi_delay dist { - 0 :/ 1, - [1 : 100] :/ 3, - [101 : 10_000] :/ 1 - }; - } - - constraint num_trans_c { - num_trans inside {[2:3]}; - } - - // lower 2 bits are ignored, use word granularity to contrain the sram setting - constraint sram_addr_c { - // if limit is 0, it means 1 word - sram_host_limit_addr[31:2] < (SRAM_SIZE/SRAM_WORD_SIZE); - sram_device_limit_addr[31:2] < (SRAM_SIZE/SRAM_WORD_SIZE); - - sram_host_base_addr <= sram_host_limit_addr; - sram_device_base_addr <= sram_device_limit_addr; - // host and device addr space within sram should not overlap - if (sram_host_limit_addr < sram_device_base_addr) { - sram_host_limit_addr[31:2] < sram_device_base_addr[31:2]; - sram_device_limit_addr < SRAM_SIZE; - } else { - sram_device_limit_addr[31:2] < sram_host_base_addr[31:2]; - sram_host_limit_addr < SRAM_SIZE; - } - } - - // size from 25 to SRAM_SIZE/SRAM_WORD_SIZE-25 - // override it if test extreme cases - constraint sram_size_constraints_c { - num_host_sram_words inside {[25:SRAM_SIZE/SRAM_WORD_SIZE]}; - num_device_sram_words inside {[25:SRAM_SIZE/SRAM_WORD_SIZE]}; - is_same_host_device_sram_words == (num_host_sram_words == num_device_sram_words); - is_same_host_device_sram_words dist { - 1 :/ 2, - 0 :/ 1 - }; - } - virtual task spi_device_fw_init(); - super.spi_device_fw_init(); - cfg.spi_host_agent_cfg.en_extra_dly_btw_sck = en_extra_dly; - cfg.spi_host_agent_cfg.en_extra_dly_btw_word = en_extra_dly; - endtask - - virtual task body(); - tx_ptr_sema = new(1); - rx_ptr_sema = new(1); - // Disable prim_flip_2sync destination pulse assertions - fifo_underflow_overflow_sva_control(0); - for (int i = 1; i <= num_trans; i++) begin - bit done_tx_write, done_rx_read, done_xfer; - `uvm_info(`gfn, $sformatf("starting sequence %0d/%0d", i, num_trans), UVM_LOW) - `DV_CHECK_RANDOMIZE_FATAL(this) - spi_device_fw_init(); - fork - begin - process_tx_write(tx_total_bytes); - done_tx_write = 1; - end - begin - process_rx_read(rx_total_bytes); - done_rx_read = 1; - end - begin - while (!done_tx_write || !done_rx_read) process_spi_xfer(); - done_xfer = 1; - end - begin // drive dummy host item - bit en_dummy = $urandom_range(0, 99) < allow_dummy_trans_pct; - while (!done_xfer && en_dummy) begin - `DV_CHECK_MEMBER_RANDOMIZE_FATAL(tx_delay) - cfg.clk_rst_vif.wait_clks(tx_delay); - spi_host_xfer_dummy_item(); - end - end - join - check_for_tx_rx_idle(); - end // for - // Restore prim_flip_2sync destination pulse assertions - fifo_underflow_overflow_sva_control(1); - endtask : body - - virtual task process_tx_write(uint xfer_bytes); - uint sram_avail_bytes; - uint tx_write_bytes; - while (xfer_bytes > 0) begin - bit [31:0] device_words_q[$]; - `DV_CHECK_MEMBER_RANDOMIZE_FATAL(tx_delay) - cfg.clk_rst_vif.wait_clks(tx_delay); - - wait_for_tx_avail_bytes(SRAM_WORD_SIZE, SramSpaceAvail, sram_avail_bytes); - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(tx_write_bytes, - tx_write_bytes <= sram_avail_bytes; - tx_write_bytes <= xfer_bytes; - tx_write_bytes[1:0] == 0; - tx_write_bytes dist { - [1:SRAM_WORD_SIZE] :/ 1, - [SRAM_WORD_SIZE+1:20] :/ 3, - [21:SRAM_SIZE-1] :/ 1, - SRAM_SIZE :/ 1};) - repeat (tx_write_bytes / SRAM_WORD_SIZE) device_words_q.push_back($urandom); - `uvm_info(`gfn, $sformatf("tx_write_bytes = %0d, sram_avail_bytes = %0d,\ - xfer_bytes = %0d", - tx_write_bytes, sram_avail_bytes, xfer_bytes), UVM_MEDIUM) - - // make sure ptr isn't being updated while fifo underflow is happening - if (allow_underflow_overflow) tx_ptr_sema.get(); - write_device_words_to_send(device_words_q); - - // when fifo is empty, need to wait until fifo fetch data from sram before release semaphore - if (allow_underflow_overflow) begin - // it takes 4 cycles to fetch data to async fifo - cfg.clk_rst_vif.wait_clks(4); - tx_ptr_sema.put(); - end - - xfer_bytes -= tx_write_bytes; - end - `uvm_info(`gfn, "done process_tx_write", UVM_MEDIUM) - endtask : process_tx_write - - virtual task process_rx_read(uint xfer_bytes); - uint sram_avail_bytes; - uint rx_read_bytes; - while (xfer_bytes > 0) begin - bit [31:0] device_words_q[$]; - `DV_CHECK_MEMBER_RANDOMIZE_FATAL(rx_delay) - cfg.clk_rst_vif.wait_clks(rx_delay); - - wait_for_rx_avail_bytes(SRAM_WORD_SIZE, SramDataAvail, sram_avail_bytes); - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(rx_read_bytes, - rx_read_bytes <= sram_avail_bytes; - rx_read_bytes <= xfer_bytes; - rx_read_bytes[1:0] == 0; - rx_read_bytes dist { - [1:SRAM_WORD_SIZE] :/ 1, - [SRAM_WORD_SIZE+1:20] :/ 3, - [21:SRAM_SIZE-1] :/ 1, - SRAM_SIZE :/ 1};) - `uvm_info(`gfn, $sformatf("rx_read_bytes = %0d, sram_avail_bytes = %0d, xfer_bytes =%0d", - rx_read_bytes, sram_avail_bytes, xfer_bytes), UVM_MEDIUM) - - // make sure ptr isn't being updated while fifo overflow is happening - if (allow_underflow_overflow) rx_ptr_sema.get(); - read_host_words_rcvd(rx_read_bytes / SRAM_WORD_SIZE, device_words_q); - if (allow_underflow_overflow) rx_ptr_sema.put(); - - xfer_bytes -= rx_read_bytes; - end - `uvm_info(`gfn, "done process_rx_read", UVM_MEDIUM) - endtask : process_rx_read - - virtual task process_spi_xfer(); - uint sram_avail_bytes; - uint spi_bytes; - bit is_under_over_flow = 0; - bit [7:0] device_bytes_q[$]; - - `DV_CHECK_MEMBER_RANDOMIZE_FATAL(spi_delay) - cfg.clk_rst_vif.wait_clks(spi_delay); - - if (allow_underflow_overflow) is_under_over_flow = $urandom_range(0, 1); - get_num_xfer_bytes(is_under_over_flow, sram_avail_bytes); - if (sram_avail_bytes < SRAM_WORD_SIZE) begin - `uvm_info(`gfn, "no avail byte for process_spi_xfer", UVM_MEDIUM) - return; - end - - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(spi_bytes, - spi_bytes <= sram_avail_bytes; - spi_bytes[1:0] == 0; - spi_bytes dist { - [1:SRAM_WORD_SIZE] :/ 1, - [SRAM_WORD_SIZE+1:20] :/ 3, - [21:SRAM_SIZE-1] :/ 1, - SRAM_SIZE :/ 1};) - - // avoid ptr is updated while fifo under/overflow is happening - if (is_under_over_flow) begin - fork - tx_ptr_sema.get(); - rx_ptr_sema.get(); - join - end - spi_host_xfer_bytes(spi_bytes, device_bytes_q); - if (is_under_over_flow) begin - tx_ptr_sema.put(); - rx_ptr_sema.put(); - end - `uvm_info(`gfn, "done process_spi_xfer", UVM_MEDIUM) - endtask : process_spi_xfer - -endclass : spi_device_txrx_vseq diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv index 79d32adfc0ef8..2523bef2ffe16 100644 --- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv +++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv @@ -3,27 +3,13 @@ // SPDX-License-Identifier: Apache-2.0 `include "spi_device_base_vseq.sv" -`include "spi_device_smoke_vseq.sv" `include "spi_device_common_vseq.sv" -`include "spi_device_txrx_vseq.sv" -`include "spi_device_fifo_full_vseq.sv" -`include "spi_device_fifo_underflow_overflow_vseq.sv" -`include "spi_device_extreme_fifo_size_vseq.sv" -`include "spi_device_dummy_item_extra_dly_vseq.sv" -`include "spi_device_intr_vseq.sv" -`include "spi_device_perf_vseq.sv" `include "spi_device_csb_read_vseq.sv" -`include "spi_device_rx_timeout_vseq.sv" -`include "spi_device_byte_transfer_vseq.sv" `include "spi_device_mem_parity_vseq.sv" `include "spi_device_ram_cfg_vseq.sv" `include "spi_device_tpm_base_vseq.sv" `include "spi_device_tpm_read_hw_reg_vseq.sv" `include "spi_device_tpm_all_vseq.sv" -`include "spi_device_bit_transfer_vseq.sv" -`include "spi_device_tx_async_fifo_reset_vseq.sv" -`include "spi_device_rx_async_fifo_reset_vseq.sv" -`include "spi_device_abort_vseq.sv" `include "spi_device_tpm_sts_read_vseq.sv" `include "spi_device_tpm_rw_vseq.sv" `include "spi_device_pass_base_vseq.sv" diff --git a/hw/ip/spi_device/dv/env/spi_device_env.core b/hw/ip/spi_device/dv/env/spi_device_env.core index 42d4379a25212..043439ba896c5 100644 --- a/hw/ip/spi_device/dv/env/spi_device_env.core +++ b/hw/ip/spi_device/dv/env/spi_device_env.core @@ -20,26 +20,12 @@ filesets: - seq_lib/spi_device_vseq_list.sv: {is_include_file: true} - seq_lib/spi_device_base_vseq.sv: {is_include_file: true} - seq_lib/spi_device_common_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_smoke_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_fifo_underflow_overflow_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_extreme_fifo_size_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_txrx_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_fifo_full_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_dummy_item_extra_dly_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_intr_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_perf_vseq.sv: {is_include_file: true} - seq_lib/spi_device_csb_read_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_byte_transfer_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_rx_timeout_vseq.sv: {is_include_file: true} - seq_lib/spi_device_mem_parity_vseq.sv: {is_include_file: true} - seq_lib/spi_device_ram_cfg_vseq.sv: {is_include_file: true} - seq_lib/spi_device_tpm_base_vseq.sv: {is_include_file: true} - seq_lib/spi_device_tpm_read_hw_reg_vseq.sv: {is_include_file: true} - seq_lib/spi_device_tpm_all_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_bit_transfer_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_tx_async_fifo_reset_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_rx_async_fifo_reset_vseq.sv: {is_include_file: true} - - seq_lib/spi_device_abort_vseq.sv: {is_include_file: true} - seq_lib/spi_device_tpm_sts_read_vseq.sv: {is_include_file: true} - seq_lib/spi_device_tpm_rw_vseq.sv: {is_include_file: true} - seq_lib/spi_device_pass_base_vseq.sv: {is_include_file: true} diff --git a/hw/ip/spi_device/dv/env/spi_device_env_cfg.sv b/hw/ip/spi_device/dv/env/spi_device_env_cfg.sv index 392e97c911cb1..7f48bc0449dc9 100644 --- a/hw/ip/spi_device/dv/env/spi_device_env_cfg.sv +++ b/hw/ip/spi_device/dv/env/spi_device_env_cfg.sv @@ -20,9 +20,6 @@ class spi_device_env_cfg extends cip_base_env_cfg #(.RAL_T(spi_device_reg_block) // This prevents clk from being configured multiple times bit do_spi_clk_configure = 1; - // can only configure the FW mem once after reset. - bit do_spi_device_fw_mem_cfg = 1; - // test may have 2 threads to configure spi_device for flash and TPM mode. // both may access the same csr `CFG`, have this to avoid accessing it at the same time. semaphore spi_cfg_sema = new(1); diff --git a/hw/ip/spi_device/dv/env/spi_device_env_pkg.sv b/hw/ip/spi_device/dv/env/spi_device_env_pkg.sv index 012a864b83ecc..8aa6130168c1e 100644 --- a/hw/ip/spi_device/dv/env/spi_device_env_pkg.sv +++ b/hw/ip/spi_device/dv/env/spi_device_env_pkg.sv @@ -22,12 +22,6 @@ package spi_device_env_pkg; // local parameters and types typedef enum { - RxFifoFull, - RxFifoGeLevel, - TxFifoLtLevel, - RxFwModeErr, - RxFifoOverflow, - TxFifoUnderflow, CmdFifoNotEmpty, PayloadNotEmpty, PayloadOverflow, diff --git a/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv b/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv index a48f621c29177..fb658501bc5cb 100644 --- a/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv +++ b/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv @@ -117,16 +117,6 @@ class spi_device_scoreboard extends cip_base_scoreboard #(.CFG_T (spi_device_env end case (cfg.spi_host_agent_cfg.spi_func_mode) - SpiModeGeneric: begin - `DV_CHECK_EQ(`gmv(ral.control.mode), GenericMode) - receive_spi_rx_data({item.data[3], item.data[2], item.data[1], item.data[0]}); - if (cfg.en_cov) begin - cov.bit_order_clk_cfg_cg.sample(cfg.spi_host_agent_cfg.host_bit_dir, - cfg.spi_host_agent_cfg.device_bit_dir, - cfg.spi_host_agent_cfg.sck_polarity[FW_FLASH_CSB_ID], - cfg.spi_host_agent_cfg.sck_phase[FW_FLASH_CSB_ID]); - end - end SpiModeFlash: begin internal_process_cmd_e cmd_type; bit is_intercepted; @@ -964,35 +954,10 @@ class spi_device_scoreboard extends cip_base_scoreboard #(.CFG_T (spi_device_env `DV_CHECK_NE_FATAL(csr, null) end else if (csr_addr inside {[cfg.sram_start_addr:cfg.sram_end_addr]}) begin - if (`gmv(ral.control.mode) == GenericMode) begin - uint tx_base = ral.txf_addr.base.get_mirrored_value(); - uint rx_base = ral.rxf_addr.base.get_mirrored_value(); - uint tx_limit = ral.txf_addr.limit.get_mirrored_value(); - uint rx_limit = ral.rxf_addr.limit.get_mirrored_value(); - uint mem_addr = item.a_addr - cfg.sram_start_addr; - tx_base[1:0] = 0; - rx_base[1:0] = 0; - if (mem_addr inside {[tx_base : tx_base + tx_limit]}) begin // TX address - if (write && channel == AddrChannel) begin - tx_mem.write(mem_addr - tx_base, item.a_data); - `uvm_info(`gfn, $sformatf("write tx_mem addr 0x%0h, data: 0x%0h", - mem_addr - tx_base, item.a_data), UVM_MEDIUM) - end - end else if (mem_addr inside {[rx_base : rx_base + rx_limit]}) begin // RX address - if (!write && channel == DataChannel) begin //TODO UVM_ERROR unexpected write on RX mem - uint addr = mem_addr - rx_base; - bit [TL_DW-1:0] data_exp = rx_mem.read(addr); - `DV_CHECK_EQ(item.d_data, data_exp, $sformatf("Compare SPI RX data, addr: 0x%0h", addr)) - end - end else begin - // TODO hit unlocated mem, sample coverage - end - end else begin - if (!write) begin - // cip_base_scoreboard compares the mem read only when the address exists - // just need to ensure address exists here and mem check is done at process_mem_read - `DV_CHECK(spi_mem.addr_exists(csr_addr)) - end + if (!write) begin + // cip_base_scoreboard compares the mem read only when the address exists + // just need to ensure address exists here and mem check is done at process_mem_read + `DV_CHECK(spi_mem.addr_exists(csr_addr)) end return; end @@ -1029,16 +994,6 @@ class spi_device_scoreboard extends cip_base_scoreboard #(.CFG_T (spi_device_env // process the csr req case (csr.get_name()) - "txf_ptr": begin - if (write && channel == AddrChannel) begin - update_tx_fifo_and_rptr(); - end - end - "rxf_ptr": begin - if (write && channel == AddrChannel) begin - update_rx_mem_fifo_and_wptr(); - end - end "flash_status": begin if (write && channel == AddrChannel) begin // store the item in a queue as flash_status is updated at the end of spi transaction @@ -1075,7 +1030,6 @@ class spi_device_scoreboard extends cip_base_scoreboard #(.CFG_T (spi_device_env cov.intr_pins_cg.sample(intr, cfg.intr_vif.pins[intr]); end - // generic_* interrupts are tested in the direct test - spi_device_intr_vseq. if (!(i inside {ReadbufFlip, ReadbufWatermark, PayloadOverflow, CmdFifoNotEmpty, PayloadNotEmpty, TpmHeaderNotEmpty}) || (i == TpmHeaderNotEmpty && !cfg.en_check_tpm_not_empty_intr)) begin @@ -1120,9 +1074,7 @@ class spi_device_scoreboard extends cip_base_scoreboard #(.CFG_T (spi_device_env end end "control": begin - if (write && channel == AddrChannel) begin - if (!`gmv(ral.control.rst_txfifo) || `gmv(ral.control.abort)) tx_word_q.delete(); - end + ; end "upload_cmdfifo": begin if (!write && channel == DataChannel) begin @@ -1219,29 +1171,6 @@ class spi_device_scoreboard extends cip_base_scoreboard #(.CFG_T (spi_device_env end endtask - // read data from mem then update tx fifo and tx_rptr - virtual function void update_tx_fifo_and_rptr(); - uint filled_bytes = get_tx_sram_filled_bytes(); - uint tx_limit = `gmv(ral.txf_addr.limit); - - // LSB 2 bits are ignored by design - tx_limit[1:0] = 0; - // move data to fifo - while (tx_word_q.size < 2 && filled_bytes >= SRAM_WORD_SIZE) begin - tx_word_q.push_back(tx_mem.read(tx_rptr_exp[SRAM_MSB:0])); - `uvm_info(`gfn, $sformatf("write tx_word_q rptr 0x%0h, data: 0x%0h", - tx_rptr_exp, tx_mem.read(tx_rptr_exp[SRAM_MSB:0])), UVM_MEDIUM) - tx_rptr_exp = get_sram_new_ptr(.ptr(tx_rptr_exp), - .increment(SRAM_WORD_SIZE), - .sram_size_bytes(`GET_TX_ALLOCATED_SRAM_SIZE_BYTES)); - filled_bytes -= SRAM_WORD_SIZE; - end - // sample when the fifo is full - if (cfg.en_cov && filled_bytes == `GET_TX_ALLOCATED_SRAM_SIZE_BYTES) begin - cov.fw_tx_fifo_size_cg.sample(`GET_TX_ALLOCATED_SRAM_SIZE_BYTES); - end - endfunction - // send out SPI data from tx_fifo and fetch more data from sram to fifo virtual function void sendout_spi_tx_data(bit [31:0] data_act); @@ -1255,26 +1184,12 @@ class spi_device_scoreboard extends cip_base_scoreboard #(.CFG_T (spi_device_env end end `DV_CHECK_EQ(data_act, data_exp, "Compare SPI TX data") - update_tx_fifo_and_rptr(); end else begin // underflow // TODO coverage sample `uvm_info(`gfn, $sformatf("TX underflow data: 0x%0h", data_act), UVM_MEDIUM) end endfunction - // when receive a spi rx data, save it in rx_fifo and then write to rx_mem - // when rx_fifo is full (size=2) and no space in sram, drop it - virtual function void receive_spi_rx_data(bit [TL_DW-1:0] data); - if (get_rx_sram_space_bytes() >= SRAM_WORD_SIZE || rx_word_q.size < 2) begin - rx_word_q.push_back(data); - update_rx_mem_fifo_and_wptr(); - end - else begin - `uvm_info(`gfn, $sformatf("RX overflow data: 0x%0h ptr: 0x%0h", data, rx_wptr_exp), - UVM_MEDIUM) - end - endfunction - // Check if opcode is enabled and returns index of enabled opcode // Checks if there are duplicate enabled opcodes - not proper config // HW parses commands this way @@ -1314,44 +1229,6 @@ class spi_device_scoreboard extends cip_base_scoreboard #(.CFG_T (spi_device_env end endfunction - // update rx mem, fifo and wptr when receive a spi trans or when rptr is updated - virtual function void update_rx_mem_fifo_and_wptr(); - uint space_bytes = get_rx_sram_space_bytes(); - // move from fifo to mem - while (rx_word_q.size > 0 && space_bytes >= SRAM_WORD_SIZE) begin - bit [TL_DW:0] data = rx_word_q.pop_front(); - rx_mem.write(rx_wptr_exp[SRAM_MSB:0], data); - `uvm_info(`gfn, $sformatf("write rx_mem, addr 0x%0h, data: 0x%0h", - rx_wptr_exp, data), UVM_MEDIUM) - rx_wptr_exp = get_sram_new_ptr(.ptr(rx_wptr_exp), - .increment(SRAM_WORD_SIZE), - .sram_size_bytes(`GET_RX_ALLOCATED_SRAM_SIZE_BYTES)); - space_bytes -= SRAM_WORD_SIZE; - end - // sample when the fifo is full - if (cfg.en_cov && space_bytes == 0) begin - cov.fw_rx_fifo_size_cg.sample(`GET_RX_ALLOCATED_SRAM_SIZE_BYTES); - end - endfunction - - virtual function uint get_tx_sram_filled_bytes(); - uint tx_wptr = ral.txf_ptr.wptr.get_mirrored_value(); - uint filled_bytes = get_sram_filled_bytes(tx_wptr, - tx_rptr_exp, - `GET_TX_ALLOCATED_SRAM_SIZE_BYTES, - {`gfn, "::get_tx_sram_filled_bytes"}); - return filled_bytes; - endfunction - - virtual function uint get_rx_sram_space_bytes(); - uint rx_rptr = ral.rxf_ptr.rptr.get_mirrored_value(); - uint space_bytes = get_sram_space_bytes(rx_wptr_exp, - rx_rptr, - `GET_RX_ALLOCATED_SRAM_SIZE_BYTES, - {`gfn, "::get_rx_sram_space_bytes"}); - return space_bytes; - endfunction - // reinitialises the scoreboard's memory models function void clear_mems(); spi_mem.init(); @@ -1361,8 +1238,6 @@ class spi_device_scoreboard extends cip_base_scoreboard #(.CFG_T (spi_device_env virtual function void reset(string kind = "HARD"); super.reset(kind); - tx_rptr_exp = ral.txf_ptr.rptr.get_reset(); - rx_wptr_exp = ral.rxf_ptr.wptr.get_reset(); intr_trigger_pending = ral.intr_state.get_reset(); tx_word_q.delete(); diff --git a/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson b/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson index 8a06ca052e759..000e753b9d729 100644 --- a/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson +++ b/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson @@ -56,61 +56,11 @@ // List of test specifications. tests: [ - { - name: spi_device_smoke - uvm_test_seq: spi_device_smoke_vseq - } - - { - name: spi_device_txrx - uvm_test_seq: spi_device_txrx_vseq - } - - { - name: spi_device_fifo_full - uvm_test_seq: spi_device_fifo_full_vseq - } - - { - name: spi_device_fifo_underflow_overflow - uvm_test_seq: spi_device_fifo_underflow_overflow_vseq - } - - { - name: spi_device_extreme_fifo_size - uvm_test_seq: spi_device_extreme_fifo_size_vseq - run_timeout_mins: 90 - } - - { - name: spi_device_dummy_item_extra_dly - uvm_test_seq: spi_device_dummy_item_extra_dly_vseq - } - - { - name: spi_device_intr - uvm_test_seq: spi_device_intr_vseq - } - - { - name: spi_device_perf - uvm_test_seq: spi_device_perf_vseq - } - { name: spi_device_csb_read uvm_test_seq: spi_device_csb_read_vseq } - { - name: spi_device_byte_transfer - uvm_test_seq: spi_device_byte_transfer_vseq - } - - { - name: spi_device_rx_timeout - uvm_test_seq: spi_device_rx_timeout_vseq - } // This test reuses the same structure as tl_intg_err. { name: "spi_device_mem_parity" @@ -135,26 +85,6 @@ uvm_test_seq: spi_device_tpm_all_vseq } - { - name: spi_device_bit_transfer - uvm_test_seq: spi_device_bit_transfer_vseq - } - - { - name: spi_device_tx_async_fifo_reset - uvm_test_seq: spi_device_tx_async_fifo_reset_vseq - } - - { - name: spi_device_rx_async_fifo_reset - uvm_test_seq: spi_device_rx_async_fifo_reset_vseq - } - - { - name: spi_device_abort - uvm_test_seq: spi_device_abort_vseq - } - { name: spi_device_tpm_sts_read uvm_test_seq: spi_device_tpm_sts_read_vseq @@ -227,7 +157,7 @@ regressions: [ { name: smoke - tests: ["spi_device_smoke"] + tests: ["spi_device_flash_mode"] } ] } diff --git a/hw/ip/spi_device/dv/tb/tb.sv b/hw/ip/spi_device/dv/tb/tb.sv index c057d8ae1e045..232f6d4832ef2 100644 --- a/hw/ip/spi_device/dv/tb/tb.sv +++ b/hw/ip/spi_device/dv/tb/tb.sv @@ -28,12 +28,6 @@ module tb; spi_device_pkg::passthrough_req_t pass_out; spi_device_pkg::passthrough_rsp_t pass_in; - wire intr_rxf; - wire intr_rxlvl; - wire intr_txlvl; - wire intr_rxerr; - wire intr_rxoverflow; - wire intr_txunderflow; wire intr_cmdfifo_not_empty; wire intr_payload_not_empty; wire intr_payload_overflow; @@ -72,12 +66,6 @@ module tb; .passthrough_i (pass_in ), .passthrough_o (pass_out ), - .intr_generic_rx_full_o (intr_rxf ), - .intr_generic_rx_watermark_o (intr_rxlvl), - .intr_generic_tx_watermark_o (intr_txlvl), - .intr_generic_rx_error_o (intr_rxerr), - .intr_generic_rx_overflow_o (intr_rxoverflow), - .intr_generic_tx_underflow_o (intr_txunderflow), .intr_upload_cmdfifo_not_empty_o (intr_cmdfifo_not_empty), .intr_upload_payload_not_empty_o (intr_payload_not_empty), .intr_upload_payload_overflow_o (intr_payload_overflow), @@ -116,12 +104,6 @@ module tb; `CONNECT_SPI_IO_PASS(spi_if_pass, pass_in.s, pass_out.s, pass_out.s_en, 2) `CONNECT_SPI_IO_PASS(spi_if_pass, pass_in.s, pass_out.s, pass_out.s_en, 3) - assign interrupts[RxFifoFull] = intr_rxf; - assign interrupts[RxFifoGeLevel] = intr_rxlvl; - assign interrupts[TxFifoLtLevel] = intr_txlvl; - assign interrupts[RxFwModeErr] = intr_rxerr; - assign interrupts[RxFifoOverflow] = intr_rxoverflow; - assign interrupts[TxFifoUnderflow] = intr_txunderflow; assign interrupts[CmdFifoNotEmpty] = intr_cmdfifo_not_empty; assign interrupts[PayloadNotEmpty] = intr_payload_not_empty; assign interrupts[PayloadOverflow] = intr_payload_overflow; diff --git a/hw/ip/spi_device/lint/spi_device.vlt b/hw/ip/spi_device/lint/spi_device.vlt index 29c3a1b0981d6..df04d4a24c101 100644 --- a/hw/ip/spi_device/lint/spi_device.vlt +++ b/hw/ip/spi_device/lint/spi_device.vlt @@ -6,13 +6,6 @@ `verilator_config -// The mode_i input is not currently used: we only support FwMode at the moment. -lint_off -rule UNUSED -file "*/rtl/spi_fwmode.sv" -match "Signal is not used: 'mode_i'" - -// SRAM error protection is not yet implemented -lint_off -rule UNUSED -file "*/rtl/spi_fwm_rxf_ctrl.sv" -match "Signal is not used: 'sram_error'" -lint_off -rule UNUSED -file "*/rtl/spi_fwm_txf_ctrl.sv" -match "Signal is not used: 'sram_error'" - // Waive a warning caused by the fact that our "abort" register // matches a C++ common word. lint_off -rule SYMRSVDWORD -file "*/rtl/spi_device_reg_pkg.sv" -match "Symbol matches C++ common word: 'abort'" diff --git a/hw/ip/spi_device/lint/spi_device.waiver b/hw/ip/spi_device/lint/spi_device.waiver index 24ffc521b52de..2fd0f236bc03c 100644 --- a/hw/ip/spi_device/lint/spi_device.waiver +++ b/hw/ip/spi_device/lint/spi_device.waiver @@ -35,10 +35,6 @@ waive -rules NOT_READ -location {spi_device.sv} -regexp {Signal.*sram_base_addr. -comment "Sram base address is given by parameter. Didn't decided if this field is used." waive -rules NOT_READ -location {spi_device.sv} -regexp {Signal.*[rt]xf_ptr.*' is not read} \ -comment "Only lower bits are used for sram_addr but leaving the register fields flexible" -waive -rules HIER_NET_NOT_READ -location {spi_fwmode.sv} -regexp {[nN]et.*spi_mode.* is not read} \ - -comment "FwMode is used. This field is used when EEPROM is implemented" -waive -rules HIER_NET_NOT_READ -location {spi_fwmode.sv} -regexp {[nN]et.*fwm_sram_error.* is not read} \ - -comment "SRAM error correction code is not implemented" waive -rules HIER_NET_NOT_READ NOT_READ -location {spi_device.sv} -regexp {.*fifo_level\..xlvl\.q} \ -comment "RXLevel and TXLevel is used only for pointer width." waive -rules HIER_NET_NOT_READ -location {spi_device.sv} -regexp {(tl_sram_h2d|tl_i).*a_mask} \ @@ -46,24 +42,10 @@ waive -rules HIER_NET_NOT_READ -location {spi_device.sv} -regexp {(tl_sram_h2d|t waive -rules HIER_NET_NOT_READ NOT_READ -location {spi_device.sv} -regexp {mem_(a|b)_(rerror|addr)} \ -comment "Only portion of Memory address is used depending on SramAw parameter" -waive -rules NOT_READ -location {spi_fwm_rxf_ctrl.sv} -regexp {Signal 'ptr_cmp\[1:0\]' is not read} \ - -comment "Only upper bits are used to compare FIFO full condition to avoid partial write" - -waive -rules CONST_OUTPUT -location {spi_fwm_txf_ctrl.sv} -regexp {Output 'sram_w.*' is driven} \ - -comment "always read operation from TX FIFO CTRL" -waive -rules CONST_OUTPUT -location {spi_fwm_*xf_ctrl.sv} -regexp {Output 'depth.*} \ - -comment "Based on the SRAM size 2kB, it cannot hit the case" - waive -rules CONST_FF -location {spi_p2s.sv} \ -regexp {Flip-flop 'tx_state' is driven} \ -comment "Intended behavior" -waive -rules CONST_FF -location {spi_device.sv} -regexp {fwm_rerr_q} \ - -comment "Will implement the interrupt later. Waive for now" -waive -rules CONST_FF -location {spi_fwmode.sv} -regexp {'tx_state' is driven by constant one} \ - -comment "Intentionally reset to TxIdle and assign TxActive else. For CPHA=1 mode" -waive -rules TWO_STATE_TYPE -location {spi_device.sv} -regexp {'fwm_fifo_e' is of} \ - -comment "Intended declaration" waive -rules TWO_STATE_TYPE -location {spi_device.sv} \ -regexp {'sys_sram_e' is of two state type} \ -comment "Enum int unsigned is used as a index. OK to be two state" @@ -74,8 +56,6 @@ waive -rules TWO_STATE_TYPE -location {spid_status.sv} \ -regexp {'status_bit_e' is of two state type} \ -comment "Enum status_bit_e is used as an index. OK to be two state" -waive -rules ONE_BIT_MEM_WIDTH -location {spi_device.sv spi_fwmode.sv} -regexp {Memory 'fwm_sram_.*' has word} \ - -comment "Intended implementation to make it consistent with other signals" waive -rules {ONE_BIT_MEM_WIDTH} -location {spi_device.sv} \ -regexp {Memory 'sub_(sram|p2s)_.*' has word} \ -comment "Intended implemenetation to make it consistent" @@ -83,14 +63,6 @@ waive -rules {ONE_BIT_MEM_WIDTH} -location {spi_device.sv} \ waive -rules EXPLICIT_BITLEN -location {spi_*} -regexp {for constant '1'} \ -comment "Parameter subtract is fine" -waive -rules INPUT_NOT_READ -location {spi_fwm_*xf_ctrl.sv} -regexp {Input port 'sram_error' is not read} \ - -comment "Sram error protection is not yet implemented" -waive -rules INPUT_NOT_READ -location {spi_fwmode.sv} -regexp {Input port 'mode_i' is not read} \ - -comment "Only FwMode is used at this moment" - -waive -rules CONST_FF -location {spi_device.sv} -msg {Flip-flop 'fwm_rxerr_q' is driven by constant zero} \ - -comment "This is an unimplemented error signal which is currently tied to 0." - # intentional terminal states waive -rules TERMINAL_STATE -location {spi_cmdparse.sv} -regexp {Terminal state 'St(Status|Jedec|Sfdp|ReadCmd|Upload|Addr4B|WrEn)' is detected} waive -rules TERMINAL_STATE -location {spi_readcmd.sv} \ @@ -129,19 +101,11 @@ waive -rules CLOCK_MUX -location {spi_device.sv} \ -comment "ascentlint with prim generic has generated clock starting from a flop" #### INFO -waive -rules VAR_INDEX -location {spi_fwm_rxf_ctrl.sv} -regexp {'byte_enable\[pos\]'} \ - -comment "Flip-flop implemented" -waive -rules VAR_INDEX -location {spi_fwm_rxf_ctrl.sv} -regexp {'sram_[wr]data.*'} \ - -comment "Flip-flop implemented" -waive -rules VAR_INDEX -location {spi_fwm_txf_ctrl.sv} -regexp {'fifo_wdata_d.*'} \ - -comment "fifo_data_d is latched to fifo_data[7:0]" -waive -rules CASE_INC -location {spi_fwm_*xf_ctrl.sv} -regexp {Case statement tag not} \ - -comment "Enum type is used for state machine" #### NOT used #### For the convenience of the design, below signals are intentionally unused waive -rules {NOT_USED NOT_READ} -location {spi_device.sv} \ - -regexp {'sub_(sram|p2s)_.*\[1\]' is not (used|read)} \ + -regexp {'sub_(sram|p2s)_.*\[0\]' is not (used|read)} \ -comment "CmdParse does not have SRAM intf" #### Intented Terminal States diff --git a/hw/ip/spi_device/rtl/spi_device.sv b/hw/ip/spi_device/rtl/spi_device.sv index 40f8b14d7d876..292ab1b5a2d7a 100644 --- a/hw/ip/spi_device/rtl/spi_device.sv +++ b/hw/ip/spi_device/rtl/spi_device.sv @@ -37,14 +37,6 @@ module spi_device input spi_device_pkg::passthrough_rsp_t passthrough_i, // Interrupts - // INTR: Generic mode - output logic intr_generic_rx_full_o, // RX FIFO Full - output logic intr_generic_rx_watermark_o, // RX FIFO above level - output logic intr_generic_tx_watermark_o, // TX FIFO below level - output logic intr_generic_rx_error_o, // RX Frame error - output logic intr_generic_rx_overflow_o, // RX Async FIFO Overflow - output logic intr_generic_tx_underflow_o, // TX Async FIFO Underflow - // INTR: Flash mode output logic intr_upload_cmdfifo_not_empty_o, output logic intr_upload_payload_not_empty_o, @@ -70,12 +62,6 @@ module spi_device import spi_device_pkg::*; - localparam int FifoWidth = $bits(spi_byte_t); - localparam int FifoDepth = 8; // 2 DWords - localparam int SDW = $clog2(SramDw/FifoWidth); - localparam int PtrW = SramAw + 1 + SDW; - localparam int AsFifoDepthW = $clog2(FifoDepth+1); - localparam int unsigned ReadBufferDepth = spi_device_pkg::SramMsgDepth; localparam int unsigned BufferAw = $clog2(ReadBufferDepth); @@ -99,13 +85,6 @@ module spi_device tlul_pkg::tl_d2h_t tl_sram_d2h; // Dual-port SRAM Interface: Refer prim_ram_2p_wrapper.sv - logic sram_clk; - logic sram_clk_en; - logic sram_clk_ungated; - logic sram_clk_muxed; - logic sram_rst_n; - logic sram_rst_n_noscan; - logic mem_a_req; logic mem_a_write; logic [SramAw-1:0] mem_a_addr; @@ -138,9 +117,6 @@ module spi_device logic [3:0] passthrough_sd, passthrough_sd_en; // Upload related interfaces (SRAM, FIFOs) - // Initially, SysSramEnd was the end of the enum variable. But lint tool - // raises errors the value being used in the parameter. So changed to - // localparam typedef enum int unsigned { SysSramFw = 0, SysSramCmdFifo = 1, @@ -199,18 +175,9 @@ module spi_device logic txorder; // TX bitstream order: 0(bit 7 to 0), 1(bit 0 to 7) logic rxorder; // RX bitstream order: 0(bit 7 to 0), 1(bit 0 to 7) - logic abort; // Abort current operations (txf only at this time) - // Think how FW knows abort is done. - //logic abort_done; // ICEBOX(#18357): Not implemented yet - logic sys_csb_syncd; - logic rst_txfifo_n, rst_rxfifo_n; - logic rst_txfifo_reg, rst_rxfifo_reg; - - //spi_addr_size_e addr_size; // Not used in fwmode spi_mode_e spi_mode; - //spi_byte_t fw_dummy_byte; logic cfg_addr_4b_en; // Address 3B/ 4B tracker related signals @@ -228,25 +195,6 @@ module spi_device // CMD_INFO_EX4B. logic cmd_en4b_pulse, cmd_ex4b_pulse; - logic intr_sram_rxf_full, intr_fwm_rxerr; - logic intr_fwm_rxlvl, rxlvl, rxlvl_d, intr_fwm_txlvl, txlvl, txlvl_d; - logic intr_fwm_rxoverflow, intr_fwm_txunderflow; - - logic rxf_overflow, txf_underflow; - - logic [7:0] timer_v; // Wait timer inside rxf control - logic [PtrW-1:0] sram_rxf_rptr, sram_rxf_wptr; - logic [PtrW-1:0] sram_txf_rptr, sram_txf_wptr; - logic [PtrW-1:0] sram_rxf_depth, sram_txf_depth; - - logic [SramAw-1:0] sram_rxf_bindex, sram_txf_bindex; - logic [SramAw-1:0] sram_rxf_lindex, sram_txf_lindex; - - logic [AsFifoDepthW-1:0] as_txfifo_depth, as_rxfifo_depth; - - logic rxf_empty, rxf_full, txf_empty, txf_full; - logic rxf_full_syncd, txf_empty_syncd; // sync signals - // SPI S2P signals // io_mode: Determine s2p/p2s behavior. // io_mode is changed at the negedge of SPI_CLK (based on the SPI protocol). @@ -402,210 +350,13 @@ module spi_device assign txorder = reg2hw.cfg.tx_order.q; assign rxorder = reg2hw.cfg.rx_order.q; - assign rst_txfifo_reg = reg2hw.control.rst_txfifo.q; - assign rst_rxfifo_reg = reg2hw.control.rst_rxfifo.q; - - assign sram_clk_en = reg2hw.control.sram_clk_en.q; - - assign timer_v = reg2hw.cfg.timer_v.q; - //assign cfg_addr_4b_en = reg2hw.cfg.addr_4b_en.q; - assign sram_rxf_bindex = reg2hw.rxf_addr.base.q[SDW+:SramAw]; - assign sram_rxf_lindex = reg2hw.rxf_addr.limit.q[SDW+:SramAw]; - assign sram_txf_bindex = reg2hw.txf_addr.base.q[SDW+:SramAw]; - assign sram_txf_lindex = reg2hw.txf_addr.limit.q[SDW+:SramAw]; - - assign sram_rxf_rptr = reg2hw.rxf_ptr.rptr.q[PtrW-1:0]; - assign hw2reg.rxf_ptr.wptr.d = {{(16-PtrW){1'b0}}, sram_rxf_wptr}; - assign hw2reg.rxf_ptr.wptr.de = 1'b1; - - assign sram_txf_wptr = reg2hw.txf_ptr.wptr.q[PtrW-1:0]; - assign hw2reg.txf_ptr.rptr.d = {{(16-PtrW){1'b0}}, sram_txf_rptr}; - assign hw2reg.txf_ptr.rptr.de = 1'b1; - - assign abort = reg2hw.control.abort.q; - assign hw2reg.status.abort_done.d = 1'b1; - - assign hw2reg.status.rxf_empty.d = rxf_empty; - assign hw2reg.status.txf_full.d = txf_full; - - // SYNC logic required - assign hw2reg.status.rxf_full.d = rxf_full_syncd; - assign hw2reg.status.txf_empty.d = txf_empty_syncd; - // CSb : after 2stage synchronizer assign hw2reg.status.csb.d = sys_csb_syncd; assign hw2reg.status.tpm_csb.d = sys_tpm_csb_syncd; - logic rxf_full_q, txf_empty_q; - always_ff @(posedge clk_spi_in_buf or negedge rst_ni) begin - if (!rst_ni) rxf_full_q <= 1'b0; - else rxf_full_q <= rxf_full; - end - always_ff @(posedge clk_spi_out_buf or negedge rst_ni) begin - if (!rst_ni) txf_empty_q <= 1'b1; - else txf_empty_q <= txf_empty; - end - prim_flop_2sync #(.Width(1)) u_sync_rxf ( - .clk_i, - .rst_ni, - .d_i(rxf_full_q), - .q_o(rxf_full_syncd) - ); - prim_flop_2sync #(.Width(1), .ResetValue(1'b1)) u_sync_txe ( - .clk_i, - .rst_ni, - .d_i(txf_empty_q), - .q_o(txf_empty_syncd) - ); - - assign spi_mode = spi_mode_e'(reg2hw.control.mode.q); - - // Async FIFO level - // rx rdepth, tx wdepth to be in main clock domain - assign hw2reg.async_fifo_level.txlvl.d = {{(8-AsFifoDepthW){1'b0}}, as_txfifo_depth}; - assign hw2reg.async_fifo_level.rxlvl.d = {{(8-AsFifoDepthW){1'b0}}, as_rxfifo_depth}; - - // Interrupt - - // Edge - logic sram_rxf_full_q, fwm_rxerr_q; - logic sram_rxf_full , fwm_rxerr ; - - // ICEBOX(#10058): Check if CE# deasserted in the middle of bit transfer - assign fwm_rxerr = 1'b0; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - sram_rxf_full_q <= 1'b0; - fwm_rxerr_q <= 1'b0; - end else begin - sram_rxf_full_q <= sram_rxf_full; - fwm_rxerr_q <= fwm_rxerr; - end - end - - // Interrupt - assign intr_sram_rxf_full = ~sram_rxf_full_q & sram_rxf_full; - assign intr_fwm_rxerr = ~fwm_rxerr_q & fwm_rxerr; - - assign rxlvl_d = (sram_rxf_depth >= reg2hw.fifo_level.rxlvl.q[PtrW-1:0]) ; - assign txlvl_d = (sram_txf_depth < reg2hw.fifo_level.txlvl.q[PtrW-1:0]) ; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - rxlvl <= 1'b0; - txlvl <= 1'b0; - end else begin - rxlvl <= rxlvl_d; - txlvl <= txlvl_d; - end - end - assign intr_fwm_rxlvl = ~rxlvl && rxlvl_d; - assign intr_fwm_txlvl = ~txlvl && txlvl_d; - - // rxf_overflow - // Could trigger lint error for input clock. - // It's unavoidable due to the characteristics of SPI intf - prim_pulse_sync u_rxf_overflow ( - .clk_src_i (clk_spi_in_buf ), - .rst_src_ni (rst_ni ), - .src_pulse_i (rxf_overflow ), - .clk_dst_i (clk_i ), - .rst_dst_ni (rst_ni ), - .dst_pulse_o (intr_fwm_rxoverflow) - ); - - // txf_underflow - // Could trigger lint error for input clock. - // It's unavoidable due to the characteristics of SPI intf - prim_pulse_sync u_txf_underflow ( - .clk_src_i (clk_spi_out_buf ), - .rst_src_ni (rst_ni ), - .src_pulse_i (txf_underflow ), - .clk_dst_i (clk_i ), - .rst_dst_ni (rst_ni ), - .dst_pulse_o (intr_fwm_txunderflow) - ); - - prim_intr_hw #(.Width(1)) u_intr_rxf ( - .clk_i, - .rst_ni, - .event_intr_i (intr_sram_rxf_full ), - .reg2hw_intr_enable_q_i (reg2hw.intr_enable.generic_rx_full.q), - .reg2hw_intr_test_q_i (reg2hw.intr_test.generic_rx_full.q ), - .reg2hw_intr_test_qe_i (reg2hw.intr_test.generic_rx_full.qe ), - .reg2hw_intr_state_q_i (reg2hw.intr_state.generic_rx_full.q ), - .hw2reg_intr_state_de_o (hw2reg.intr_state.generic_rx_full.de), - .hw2reg_intr_state_d_o (hw2reg.intr_state.generic_rx_full.d ), - .intr_o (intr_generic_rx_full_o ) - ); - - prim_intr_hw #(.Width(1)) u_intr_rxlvl ( - .clk_i, - .rst_ni, - .event_intr_i (intr_fwm_rxlvl ), - .reg2hw_intr_enable_q_i (reg2hw.intr_enable.generic_rx_watermark.q), - .reg2hw_intr_test_q_i (reg2hw.intr_test.generic_rx_watermark.q ), - .reg2hw_intr_test_qe_i (reg2hw.intr_test.generic_rx_watermark.qe ), - .reg2hw_intr_state_q_i (reg2hw.intr_state.generic_rx_watermark.q ), - .hw2reg_intr_state_de_o (hw2reg.intr_state.generic_rx_watermark.de), - .hw2reg_intr_state_d_o (hw2reg.intr_state.generic_rx_watermark.d ), - .intr_o (intr_generic_rx_watermark_o ) - ); - - prim_intr_hw #(.Width(1)) u_intr_txlvl ( - .clk_i, - .rst_ni, - .event_intr_i (intr_fwm_txlvl ), - .reg2hw_intr_enable_q_i (reg2hw.intr_enable.generic_tx_watermark.q), - .reg2hw_intr_test_q_i (reg2hw.intr_test.generic_tx_watermark.q ), - .reg2hw_intr_test_qe_i (reg2hw.intr_test.generic_tx_watermark.qe ), - .reg2hw_intr_state_q_i (reg2hw.intr_state.generic_tx_watermark.q ), - .hw2reg_intr_state_de_o (hw2reg.intr_state.generic_tx_watermark.de), - .hw2reg_intr_state_d_o (hw2reg.intr_state.generic_tx_watermark.d ), - .intr_o (intr_generic_tx_watermark_o ) - ); - - prim_intr_hw #(.Width(1)) u_intr_rxerr ( - .clk_i, - .rst_ni, - .event_intr_i (intr_fwm_rxerr ), - .reg2hw_intr_enable_q_i (reg2hw.intr_enable.generic_rx_error.q), - .reg2hw_intr_test_q_i (reg2hw.intr_test.generic_rx_error.q ), - .reg2hw_intr_test_qe_i (reg2hw.intr_test.generic_rx_error.qe ), - .reg2hw_intr_state_q_i (reg2hw.intr_state.generic_rx_error.q ), - .hw2reg_intr_state_de_o (hw2reg.intr_state.generic_rx_error.de), - .hw2reg_intr_state_d_o (hw2reg.intr_state.generic_rx_error.d ), - .intr_o (intr_generic_rx_error_o ) - ); - - prim_intr_hw #(.Width(1)) u_intr_rxoverflow ( - .clk_i, - .rst_ni, - .event_intr_i (intr_fwm_rxoverflow ), - .reg2hw_intr_enable_q_i (reg2hw.intr_enable.generic_rx_overflow.q), - .reg2hw_intr_test_q_i (reg2hw.intr_test.generic_rx_overflow.q ), - .reg2hw_intr_test_qe_i (reg2hw.intr_test.generic_rx_overflow.qe ), - .reg2hw_intr_state_q_i (reg2hw.intr_state.generic_rx_overflow.q ), - .hw2reg_intr_state_de_o (hw2reg.intr_state.generic_rx_overflow.de), - .hw2reg_intr_state_d_o (hw2reg.intr_state.generic_rx_overflow.d ), - .intr_o (intr_generic_rx_overflow_o ) - ); - - prim_intr_hw #(.Width(1)) u_intr_txunderflow ( - .clk_i, - .rst_ni, - .event_intr_i (intr_fwm_txunderflow ), - .reg2hw_intr_enable_q_i (reg2hw.intr_enable.generic_tx_underflow.q), - .reg2hw_intr_test_q_i (reg2hw.intr_test.generic_tx_underflow.q ), - .reg2hw_intr_test_qe_i (reg2hw.intr_test.generic_tx_underflow.qe ), - .reg2hw_intr_state_q_i (reg2hw.intr_state.generic_tx_underflow.q ), - .hw2reg_intr_state_de_o (hw2reg.intr_state.generic_tx_underflow.de), - .hw2reg_intr_state_d_o (hw2reg.intr_state.generic_tx_underflow.d ), - .intr_o (intr_generic_tx_underflow_o ) - ); + assign spi_mode = spi_mode_e'(reg2hw.control.q); prim_edge_detector #( .Width (2), @@ -813,12 +564,9 @@ module spi_device end - ////////////////////////////// - // // Clock & reset control // - ////////////////////////////// - // clk_spi cannot use glitch-free clock mux as clock switching in glitch-free - // requires two clocks to propagate clock selection and enable but SPI clock - // doesn't exist until it transmits data through SDI + /////////////////////////// + // Clock & reset control // + /////////////////////////// logic sck_n; logic rst_spi_n; prim_mubi_pkg::mubi4_t [ScanModeUseLast-1:0] scanmode; @@ -842,15 +590,15 @@ module spi_device ); assign sck_monitor_o = cio_sck_i; - assign clk_spi_in = (cpha ^ cpol) ? sck_n : cio_sck_i ; - assign clk_spi_out = (cpha ^ cpol) ? cio_sck_i : sck_n ; + assign clk_spi_in = cio_sck_i; + assign clk_spi_out = sck_n; prim_clock_mux2 #( .NoFpgaBufG(1'b1) ) u_clk_spi_in_mux ( .clk0_i(clk_spi_in), .clk1_i(scan_clk_i), - .sel_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode[ClkMuxSel])), + .sel_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode[ClkMuxSel]) | mbist_en_i), .clk_o(clk_spi_in_muxed) ); @@ -903,24 +651,6 @@ module spi_device .clk_o(rst_spi_n) ); - prim_clock_mux2 #( - .NoFpgaBufG(1'b1) - ) u_tx_rst_scan_mux ( - .clk0_i(rst_ni & ~rst_txfifo_reg), - .clk1_i(scan_rst_ni), - .sel_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode[TxRstMuxSel])), - .clk_o(rst_txfifo_n) - ); - - prim_clock_mux2 #( - .NoFpgaBufG(1'b1) - ) u_rx_rst_scan_mux ( - .clk0_i(rst_ni & ~rst_rxfifo_reg), - .clk1_i(scan_rst_ni), - .sel_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode[RxRstMuxSel])), - .clk_o(rst_rxfifo_n) - ); - logic tpm_rst_n, sys_tpm_rst_n; prim_clock_mux2 #( @@ -952,70 +682,6 @@ module spi_device .scanmode_i (scanmode[TpmRstSel]) ); - // SRAM clock - // If FwMode, SRAM clock for B port uses peripheral clock (clk_i) - // If FlashMode or PassThrough, SRAM clock for B port uses SPI_CLK - // To remove glitch, CG cell is put after clock mux - // The enable signal is not synchronized to SRAM_CLK when clock is - // switched into SPI_CLK. So, change the clock only when SPI_CLK is - // not toggle. - // - // Programming sequence: - // Change to SPI_CLK - // 1. Check if SPI line is idle. - // 2. Clear sram_clk_en to 0. - // 3. Change mode to FlashMode or PassThrough - // 4. Set sram_clk_en to 1. - // Change to peripheral clk - // 1. Check if SPI_CLK is idle - // 2. Clear sram_clk_en to 0. - // 3. Change mode to FwMode - // 4. Set sram_clk_en to 1. - prim_clock_mux2 #( - .NoFpgaBufG(1'b1) - ) u_sram_clk_sel ( - .clk0_i (clk_spi_in_buf), - .clk1_i (clk_i), - .sel_i (spi_mode == FwMode), - .clk_o (sram_clk_ungated) - ); - - prim_clock_mux2 #( - .NoFpgaBufG(1'b1) - ) u_sram_clk_scan ( - .clk0_i (sram_clk_ungated), - .clk1_i (scan_clk_i), - .sel_i ((prim_mubi_pkg::mubi4_test_true_strict(scanmode[ClkSramSel]) | mbist_en_i)), - .clk_o (sram_clk_muxed) - ); - - prim_clock_gating #( - .FpgaBufGlobal(1'b0) - ) u_sram_clk_cg ( - .clk_i (sram_clk_muxed), - .en_i (sram_clk_en), - .test_en_i ((prim_mubi_pkg::mubi4_test_true_strict(scanmode[ClkSramSel]) | mbist_en_i)), - .clk_o (sram_clk) - ); - - prim_clock_mux2 #( - .NoFpgaBufG (1'b1) - ) u_sram_rst_sel ( - .clk0_i (rst_spi_n), - .clk1_i (rst_ni), - .sel_i (spi_mode == FwMode), - .clk_o (sram_rst_n_noscan) - ); - - prim_clock_mux2 #( - .NoFpgaBufG (1'b1) - ) u_sram_rst_scanmux ( - .clk0_i (sram_rst_n_noscan), - .clk1_i (scan_rst_ni), - .sel_i (prim_mubi_pkg::mubi4_test_true_strict(scanmode[RstSramSel])), - .clk_o (sram_rst_n) - ); - // CSb edge on the system clock prim_edge_detector #( .Width (1 ), @@ -1146,8 +812,6 @@ module spi_device // SPI_DEVICE mode selector // ////////////////////////////// // This logic chooses appropriate signals based on input SPI_DEVICE mode. - // e.g) If FwMode is selected. all data connected to spi_fwmode logic - // Assume spi_mode does not change dynamically // io_mode to spi_s2p io_mode should be affected at the negedge of SPI_CLK @@ -1212,12 +876,6 @@ module spi_device mem_b_l2m = '{ default: '0 }; - sub_sram_m2l[IoModeFw] = '{ - rvalid: 1'b 0, - rdata: '0, - rerror: '{uncorr: 1'b 0, corr: 1'b 0} - }; - flash_sram_m2l = '{ rvalid: 1'b 0, rdata: '0, @@ -1225,19 +883,6 @@ module spi_device }; unique case (spi_mode) - FwMode: begin - io_mode = sub_iomode[IoModeFw]; - - p2s_valid = sub_p2s_valid[IoModeFw]; - p2s_data = sub_p2s_data[IoModeFw]; - sub_p2s_sent[IoModeFw] = p2s_sent; - - // SRAM:: Remember this has glitch - // switch should happen only when clock gate is disabled. - mem_b_l2m = sub_sram_l2m[IoModeFw]; - sub_sram_m2l[IoModeFw] = mem_b_m2l; - end - FlashMode, PassThrough: begin // SRAM comb logic is in SCK clock domain mem_b_l2m = flash_sram_l2m; @@ -1309,7 +954,7 @@ module spi_device end else begin : spi_out_flash_passthrough // SPI Generic, Flash, Passthrough modes unique case (spi_mode) - FwMode, FlashMode: begin + FlashMode: begin cio_sd_o = internal_sd; cio_sd_en_o = internal_sd_en; end @@ -1379,76 +1024,6 @@ module spi_device .io_mode_i (io_mode_outclk) ); - ///////////// - // FW Mode // - ///////////// - spi_fwmode #( - .FifoWidth (FifoWidth), - .FifoDepth (FifoDepth) - ) u_fwmode ( - .clk_i (sram_clk), - .rst_ni (sram_rst_n), - - .clk_spi_in_i (clk_spi_in_buf), - .rst_rxfifo_ni (rst_rxfifo_n), - .clk_spi_out_i (clk_spi_out_buf), - .rst_txfifo_ni (rst_txfifo_n), - - // Mode - .spi_mode_i (spi_mode), - - .rxf_overflow_o (rxf_overflow), - .txf_underflow_o (txf_underflow), - - // SRAM interface - .fwm_req_o (sub_sram_l2m[IoModeFw].req ), - .fwm_write_o (sub_sram_l2m[IoModeFw].we ), - .fwm_addr_o (sub_sram_l2m[IoModeFw].addr ), - .fwm_wdata_o (sub_sram_l2m[IoModeFw].wdata ), - .fwm_wstrb_o (sub_sram_l2m[IoModeFw].wstrb ), - .fwm_rvalid_i (sub_sram_m2l[IoModeFw].rvalid ), - .fwm_rdata_i (sub_sram_m2l[IoModeFw].rdata ), - .fwm_rerror_i (sub_sram_m2l[IoModeFw].rerror ), - - // Input from S2P - .rx_data_valid_i (s2p_data_valid), - .rx_data_i (s2p_data), - - // Output to S2P (mode select) - .io_mode_o (sub_iomode[IoModeFw]), - - // P2S - .tx_wvalid_o (sub_p2s_valid [IoModeFw]), - .tx_data_o (sub_p2s_data [IoModeFw]), - .tx_wready_i (sub_p2s_sent [IoModeFw]), - - // CSRs - .timer_v_i (timer_v), - .sram_rxf_bindex_i (sram_rxf_bindex), - .sram_txf_bindex_i (sram_txf_bindex), - .sram_rxf_lindex_i (sram_rxf_lindex), - .sram_txf_lindex_i (sram_txf_lindex), - - .abort_i (abort), - - .sram_rxf_rptr_i (sram_rxf_rptr ), - .sram_rxf_wptr_o (sram_rxf_wptr ), - .sram_txf_rptr_o (sram_txf_rptr ), - .sram_txf_wptr_i (sram_txf_wptr ), - .sram_rxf_depth_o (sram_rxf_depth), - .sram_txf_depth_o (sram_txf_depth), - .sram_rxf_full_o (sram_rxf_full ), - - .as_txfifo_depth_o (as_txfifo_depth), - .as_rxfifo_depth_o (as_rxfifo_depth), - - .rxf_empty_o (rxf_empty), - .rxf_full_o (rxf_full), - .txf_empty_o (txf_empty), - .txf_full_o (txf_full) - - ); - //////////////////// // SPI Flash Mode // //////////////////// @@ -2066,8 +1641,8 @@ module spi_device .clk_a_i (clk_i), .rst_a_ni (rst_ni), - .clk_b_i (sram_clk), - .rst_b_ni (sram_rst_n), + .clk_b_i (clk_spi_in_buf), + .rst_b_ni (rst_spi_n), .a_req_i (mem_a_req), .a_write_i (mem_a_write), @@ -2135,12 +1710,6 @@ module spi_device `ASSERT_KNOWN(scanmodeKnown, scanmode_i, clk_i, 0) `ASSERT_KNOWN(CioSdoEnOKnown, cio_sd_en_o) - `ASSERT_KNOWN(IntrRxfOKnown, intr_generic_rx_full_o ) - `ASSERT_KNOWN(IntrRxlvlOKnown, intr_generic_rx_watermark_o) - `ASSERT_KNOWN(IntrTxlvlOKnown, intr_generic_tx_watermark_o) - `ASSERT_KNOWN(IntrRxerrOKnown, intr_generic_rx_error_o ) - `ASSERT_KNOWN(IntrRxoverflowOKnown, intr_generic_rx_overflow_o ) - `ASSERT_KNOWN(IntrTxunderflowOKnown, intr_generic_tx_underflow_o) `ASSERT_KNOWN(IntrUploadCmdfifoNotEmptyOKnown, intr_upload_cmdfifo_not_empty_o) `ASSERT_KNOWN(IntrUploadPayloadNotEmptyOKnown, diff --git a/hw/ip/spi_device/rtl/spi_device_pkg.sv b/hw/ip/spi_device/rtl/spi_device_pkg.sv index 90ca704278980..6735de4e4a6f6 100644 --- a/hw/ip/spi_device/rtl/spi_device_pkg.sv +++ b/hw/ip/spi_device/rtl/spi_device_pkg.sv @@ -282,13 +282,12 @@ package spi_device_pkg; } io_mode_e; typedef enum int unsigned { - IoModeFw = 0, - IoModeCmdParse = 1, - IoModeReadCmd = 2, - IoModeStatus = 3, - IoModeJedec = 4, - IoModeUpload = 5, - IoModeEnd = 6 // Indicate of Length + IoModeCmdParse = 0, + IoModeReadCmd = 1, + IoModeStatus = 2, + IoModeJedec = 3, + IoModeUpload = 4, + IoModeEnd = 5 // Indicate of Length } sub_io_mode_e; // SPI Line Mode (Mode0 <-> Mode3) @@ -484,14 +483,10 @@ package spi_device_pkg; parameter int unsigned BitCntW = $clog2(BitLength + 1); // spi device scanmode usage - typedef enum logic [3:0] { + typedef enum logic [2:0] { ClkInvSel, CsbRstMuxSel, - TxRstMuxSel, - RxRstMuxSel, ClkMuxSel, - ClkSramSel, - RstSramSel, TpmRstSel, ScanModeUseLast } scan_mode_e; diff --git a/hw/ip/spi_device/rtl/spi_device_reg_pkg.sv b/hw/ip/spi_device/rtl/spi_device_reg_pkg.sv index 8eeac81b24401..13b1c76c55bfd 100644 --- a/hw/ip/spi_device/rtl/spi_device_reg_pkg.sv +++ b/hw/ip/spi_device/rtl/spi_device_reg_pkg.sv @@ -23,24 +23,6 @@ package spi_device_reg_pkg; //////////////////////////// typedef struct packed { - struct packed { - logic q; - } generic_rx_full; - struct packed { - logic q; - } generic_rx_watermark; - struct packed { - logic q; - } generic_tx_watermark; - struct packed { - logic q; - } generic_rx_error; - struct packed { - logic q; - } generic_rx_overflow; - struct packed { - logic q; - } generic_tx_underflow; struct packed { logic q; } upload_cmdfifo_not_empty; @@ -62,24 +44,6 @@ package spi_device_reg_pkg; } spi_device_reg2hw_intr_state_reg_t; typedef struct packed { - struct packed { - logic q; - } generic_rx_full; - struct packed { - logic q; - } generic_rx_watermark; - struct packed { - logic q; - } generic_tx_watermark; - struct packed { - logic q; - } generic_rx_error; - struct packed { - logic q; - } generic_rx_overflow; - struct packed { - logic q; - } generic_tx_underflow; struct packed { logic q; } upload_cmdfifo_not_empty; @@ -101,30 +65,6 @@ package spi_device_reg_pkg; } spi_device_reg2hw_intr_enable_reg_t; typedef struct packed { - struct packed { - logic q; - logic qe; - } generic_rx_full; - struct packed { - logic q; - logic qe; - } generic_rx_watermark; - struct packed { - logic q; - logic qe; - } generic_tx_watermark; - struct packed { - logic q; - logic qe; - } generic_rx_error; - struct packed { - logic q; - logic qe; - } generic_rx_overflow; - struct packed { - logic q; - logic qe; - } generic_tx_underflow; struct packed { logic q; logic qe; @@ -157,21 +97,7 @@ package spi_device_reg_pkg; } spi_device_reg2hw_alert_test_reg_t; typedef struct packed { - struct packed { - logic q; - } abort; - struct packed { - logic [1:0] q; - } mode; - struct packed { - logic q; - } rst_txfifo; - struct packed { - logic q; - } rst_rxfifo; - struct packed { - logic q; - } sram_clk_en; + logic [1:0] q; } spi_device_reg2hw_control_reg_t; typedef struct packed { @@ -187,9 +113,6 @@ package spi_device_reg_pkg; struct packed { logic q; } rx_order; - struct packed { - logic [7:0] q; - } timer_v; struct packed { logic q; } addr_4b_en; @@ -198,45 +121,6 @@ package spi_device_reg_pkg; } mailbox_en; } spi_device_reg2hw_cfg_reg_t; - typedef struct packed { - struct packed { - logic [15:0] q; - } rxlvl; - struct packed { - logic [15:0] q; - } txlvl; - } spi_device_reg2hw_fifo_level_reg_t; - - typedef struct packed { - struct packed { - logic [15:0] q; - } rptr; - } spi_device_reg2hw_rxf_ptr_reg_t; - - typedef struct packed { - struct packed { - logic [15:0] q; - } wptr; - } spi_device_reg2hw_txf_ptr_reg_t; - - typedef struct packed { - struct packed { - logic [15:0] q; - } base; - struct packed { - logic [15:0] q; - } limit; - } spi_device_reg2hw_rxf_addr_reg_t; - - typedef struct packed { - struct packed { - logic [15:0] q; - } base; - struct packed { - logic [15:0] q; - } limit; - } spi_device_reg2hw_txf_addr_reg_t; - typedef struct packed { struct packed { logic q; @@ -474,30 +358,6 @@ package spi_device_reg_pkg; } spi_device_reg2hw_tpm_write_fifo_reg_t; typedef struct packed { - struct packed { - logic d; - logic de; - } generic_rx_full; - struct packed { - logic d; - logic de; - } generic_rx_watermark; - struct packed { - logic d; - logic de; - } generic_tx_watermark; - struct packed { - logic d; - logic de; - } generic_rx_error; - struct packed { - logic d; - logic de; - } generic_rx_overflow; - struct packed { - logic d; - logic de; - } generic_tx_underflow; struct packed { logic d; logic de; @@ -532,30 +392,6 @@ package spi_device_reg_pkg; } spi_device_hw2reg_cfg_reg_t; typedef struct packed { - struct packed { - logic [7:0] d; - } rxlvl; - struct packed { - logic [7:0] d; - } txlvl; - } spi_device_hw2reg_async_fifo_level_reg_t; - - typedef struct packed { - struct packed { - logic d; - } rxf_full; - struct packed { - logic d; - } rxf_empty; - struct packed { - logic d; - } txf_full; - struct packed { - logic d; - } txf_empty; - struct packed { - logic d; - } abort_done; struct packed { logic d; } csb; @@ -564,20 +400,6 @@ package spi_device_reg_pkg; } tpm_csb; } spi_device_hw2reg_status_reg_t; - typedef struct packed { - struct packed { - logic [15:0] d; - logic de; - } wptr; - } spi_device_hw2reg_rxf_ptr_reg_t; - - typedef struct packed { - struct packed { - logic [15:0] d; - logic de; - } rptr; - } spi_device_hw2reg_txf_ptr_reg_t; - typedef struct packed { logic [31:0] d; } spi_device_hw2reg_last_read_addr_reg_t; @@ -674,17 +496,12 @@ package spi_device_reg_pkg; // Register -> HW type typedef struct packed { - spi_device_reg2hw_intr_state_reg_t intr_state; // [1671:1660] - spi_device_reg2hw_intr_enable_reg_t intr_enable; // [1659:1648] - spi_device_reg2hw_intr_test_reg_t intr_test; // [1647:1624] - spi_device_reg2hw_alert_test_reg_t alert_test; // [1623:1622] - spi_device_reg2hw_control_reg_t control; // [1621:1616] - spi_device_reg2hw_cfg_reg_t cfg; // [1615:1602] - spi_device_reg2hw_fifo_level_reg_t fifo_level; // [1601:1570] - spi_device_reg2hw_rxf_ptr_reg_t rxf_ptr; // [1569:1554] - spi_device_reg2hw_txf_ptr_reg_t txf_ptr; // [1553:1538] - spi_device_reg2hw_rxf_addr_reg_t rxf_addr; // [1537:1506] - spi_device_reg2hw_txf_addr_reg_t txf_addr; // [1505:1474] + spi_device_reg2hw_intr_state_reg_t intr_state; // [1507:1502] + spi_device_reg2hw_intr_enable_reg_t intr_enable; // [1501:1496] + spi_device_reg2hw_intr_test_reg_t intr_test; // [1495:1484] + spi_device_reg2hw_alert_test_reg_t alert_test; // [1483:1482] + spi_device_reg2hw_control_reg_t control; // [1481:1480] + spi_device_reg2hw_cfg_reg_t cfg; // [1479:1474] spi_device_reg2hw_intercept_en_reg_t intercept_en; // [1473:1470] spi_device_reg2hw_flash_status_reg_t flash_status; // [1469:1444] spi_device_reg2hw_jedec_cc_reg_t jedec_cc; // [1443:1428] @@ -719,12 +536,9 @@ package spi_device_reg_pkg; // HW -> register type typedef struct packed { - spi_device_hw2reg_intr_state_reg_t intr_state; // [282:259] - spi_device_hw2reg_cfg_reg_t cfg; // [258:257] - spi_device_hw2reg_async_fifo_level_reg_t async_fifo_level; // [256:241] - spi_device_hw2reg_status_reg_t status; // [240:234] - spi_device_hw2reg_rxf_ptr_reg_t rxf_ptr; // [233:217] - spi_device_hw2reg_txf_ptr_reg_t txf_ptr; // [216:200] + spi_device_hw2reg_intr_state_reg_t intr_state; // [215:204] + spi_device_hw2reg_cfg_reg_t cfg; // [203:202] + spi_device_hw2reg_status_reg_t status; // [201:200] spi_device_hw2reg_last_read_addr_reg_t last_read_addr; // [199:168] spi_device_hw2reg_flash_status_reg_t flash_status; // [167:144] spi_device_hw2reg_upload_status_reg_t upload_status; // [143:128] @@ -744,64 +558,58 @@ package spi_device_reg_pkg; parameter logic [BlockAw-1:0] SPI_DEVICE_ALERT_TEST_OFFSET = 13'h c; parameter logic [BlockAw-1:0] SPI_DEVICE_CONTROL_OFFSET = 13'h 10; parameter logic [BlockAw-1:0] SPI_DEVICE_CFG_OFFSET = 13'h 14; - parameter logic [BlockAw-1:0] SPI_DEVICE_FIFO_LEVEL_OFFSET = 13'h 18; - parameter logic [BlockAw-1:0] SPI_DEVICE_ASYNC_FIFO_LEVEL_OFFSET = 13'h 1c; - parameter logic [BlockAw-1:0] SPI_DEVICE_STATUS_OFFSET = 13'h 20; - parameter logic [BlockAw-1:0] SPI_DEVICE_RXF_PTR_OFFSET = 13'h 24; - parameter logic [BlockAw-1:0] SPI_DEVICE_TXF_PTR_OFFSET = 13'h 28; - parameter logic [BlockAw-1:0] SPI_DEVICE_RXF_ADDR_OFFSET = 13'h 2c; - parameter logic [BlockAw-1:0] SPI_DEVICE_TXF_ADDR_OFFSET = 13'h 30; - parameter logic [BlockAw-1:0] SPI_DEVICE_INTERCEPT_EN_OFFSET = 13'h 34; - parameter logic [BlockAw-1:0] SPI_DEVICE_LAST_READ_ADDR_OFFSET = 13'h 38; - parameter logic [BlockAw-1:0] SPI_DEVICE_FLASH_STATUS_OFFSET = 13'h 3c; - parameter logic [BlockAw-1:0] SPI_DEVICE_JEDEC_CC_OFFSET = 13'h 40; - parameter logic [BlockAw-1:0] SPI_DEVICE_JEDEC_ID_OFFSET = 13'h 44; - parameter logic [BlockAw-1:0] SPI_DEVICE_READ_THRESHOLD_OFFSET = 13'h 48; - parameter logic [BlockAw-1:0] SPI_DEVICE_MAILBOX_ADDR_OFFSET = 13'h 4c; - parameter logic [BlockAw-1:0] SPI_DEVICE_UPLOAD_STATUS_OFFSET = 13'h 50; - parameter logic [BlockAw-1:0] SPI_DEVICE_UPLOAD_STATUS2_OFFSET = 13'h 54; - parameter logic [BlockAw-1:0] SPI_DEVICE_UPLOAD_CMDFIFO_OFFSET = 13'h 58; - parameter logic [BlockAw-1:0] SPI_DEVICE_UPLOAD_ADDRFIFO_OFFSET = 13'h 5c; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_0_OFFSET = 13'h 60; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_1_OFFSET = 13'h 64; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_2_OFFSET = 13'h 68; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_3_OFFSET = 13'h 6c; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_4_OFFSET = 13'h 70; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_5_OFFSET = 13'h 74; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_6_OFFSET = 13'h 78; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_7_OFFSET = 13'h 7c; - parameter logic [BlockAw-1:0] SPI_DEVICE_ADDR_SWAP_MASK_OFFSET = 13'h 80; - parameter logic [BlockAw-1:0] SPI_DEVICE_ADDR_SWAP_DATA_OFFSET = 13'h 84; - parameter logic [BlockAw-1:0] SPI_DEVICE_PAYLOAD_SWAP_MASK_OFFSET = 13'h 88; - parameter logic [BlockAw-1:0] SPI_DEVICE_PAYLOAD_SWAP_DATA_OFFSET = 13'h 8c; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_0_OFFSET = 13'h 90; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_1_OFFSET = 13'h 94; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_2_OFFSET = 13'h 98; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_3_OFFSET = 13'h 9c; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_4_OFFSET = 13'h a0; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_5_OFFSET = 13'h a4; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_6_OFFSET = 13'h a8; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_7_OFFSET = 13'h ac; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_8_OFFSET = 13'h b0; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_9_OFFSET = 13'h b4; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_10_OFFSET = 13'h b8; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_11_OFFSET = 13'h bc; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_12_OFFSET = 13'h c0; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_13_OFFSET = 13'h c4; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_14_OFFSET = 13'h c8; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_15_OFFSET = 13'h cc; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_16_OFFSET = 13'h d0; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_17_OFFSET = 13'h d4; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_18_OFFSET = 13'h d8; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_19_OFFSET = 13'h dc; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_20_OFFSET = 13'h e0; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_21_OFFSET = 13'h e4; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_22_OFFSET = 13'h e8; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_23_OFFSET = 13'h ec; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_EN4B_OFFSET = 13'h f0; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_EX4B_OFFSET = 13'h f4; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_WREN_OFFSET = 13'h f8; - parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_WRDI_OFFSET = 13'h fc; + parameter logic [BlockAw-1:0] SPI_DEVICE_STATUS_OFFSET = 13'h 18; + parameter logic [BlockAw-1:0] SPI_DEVICE_INTERCEPT_EN_OFFSET = 13'h 1c; + parameter logic [BlockAw-1:0] SPI_DEVICE_LAST_READ_ADDR_OFFSET = 13'h 20; + parameter logic [BlockAw-1:0] SPI_DEVICE_FLASH_STATUS_OFFSET = 13'h 24; + parameter logic [BlockAw-1:0] SPI_DEVICE_JEDEC_CC_OFFSET = 13'h 28; + parameter logic [BlockAw-1:0] SPI_DEVICE_JEDEC_ID_OFFSET = 13'h 2c; + parameter logic [BlockAw-1:0] SPI_DEVICE_READ_THRESHOLD_OFFSET = 13'h 30; + parameter logic [BlockAw-1:0] SPI_DEVICE_MAILBOX_ADDR_OFFSET = 13'h 34; + parameter logic [BlockAw-1:0] SPI_DEVICE_UPLOAD_STATUS_OFFSET = 13'h 38; + parameter logic [BlockAw-1:0] SPI_DEVICE_UPLOAD_STATUS2_OFFSET = 13'h 3c; + parameter logic [BlockAw-1:0] SPI_DEVICE_UPLOAD_CMDFIFO_OFFSET = 13'h 40; + parameter logic [BlockAw-1:0] SPI_DEVICE_UPLOAD_ADDRFIFO_OFFSET = 13'h 44; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_0_OFFSET = 13'h 48; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_1_OFFSET = 13'h 4c; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_2_OFFSET = 13'h 50; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_3_OFFSET = 13'h 54; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_4_OFFSET = 13'h 58; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_5_OFFSET = 13'h 5c; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_6_OFFSET = 13'h 60; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_FILTER_7_OFFSET = 13'h 64; + parameter logic [BlockAw-1:0] SPI_DEVICE_ADDR_SWAP_MASK_OFFSET = 13'h 68; + parameter logic [BlockAw-1:0] SPI_DEVICE_ADDR_SWAP_DATA_OFFSET = 13'h 6c; + parameter logic [BlockAw-1:0] SPI_DEVICE_PAYLOAD_SWAP_MASK_OFFSET = 13'h 70; + parameter logic [BlockAw-1:0] SPI_DEVICE_PAYLOAD_SWAP_DATA_OFFSET = 13'h 74; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_0_OFFSET = 13'h 78; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_1_OFFSET = 13'h 7c; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_2_OFFSET = 13'h 80; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_3_OFFSET = 13'h 84; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_4_OFFSET = 13'h 88; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_5_OFFSET = 13'h 8c; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_6_OFFSET = 13'h 90; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_7_OFFSET = 13'h 94; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_8_OFFSET = 13'h 98; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_9_OFFSET = 13'h 9c; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_10_OFFSET = 13'h a0; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_11_OFFSET = 13'h a4; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_12_OFFSET = 13'h a8; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_13_OFFSET = 13'h ac; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_14_OFFSET = 13'h b0; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_15_OFFSET = 13'h b4; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_16_OFFSET = 13'h b8; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_17_OFFSET = 13'h bc; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_18_OFFSET = 13'h c0; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_19_OFFSET = 13'h c4; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_20_OFFSET = 13'h c8; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_21_OFFSET = 13'h cc; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_22_OFFSET = 13'h d0; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_23_OFFSET = 13'h d4; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_EN4B_OFFSET = 13'h d8; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_EX4B_OFFSET = 13'h dc; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_WREN_OFFSET = 13'h e0; + parameter logic [BlockAw-1:0] SPI_DEVICE_CMD_INFO_WRDI_OFFSET = 13'h e4; parameter logic [BlockAw-1:0] SPI_DEVICE_TPM_CAP_OFFSET = 13'h 800; parameter logic [BlockAw-1:0] SPI_DEVICE_TPM_CFG_OFFSET = 13'h 804; parameter logic [BlockAw-1:0] SPI_DEVICE_TPM_STATUS_OFFSET = 13'h 808; @@ -819,13 +627,7 @@ package spi_device_reg_pkg; parameter logic [BlockAw-1:0] SPI_DEVICE_TPM_WRITE_FIFO_OFFSET = 13'h 838; // Reset values for hwext registers and their fields - parameter logic [11:0] SPI_DEVICE_INTR_TEST_RESVAL = 12'h 0; - parameter logic [0:0] SPI_DEVICE_INTR_TEST_GENERIC_RX_FULL_RESVAL = 1'h 0; - parameter logic [0:0] SPI_DEVICE_INTR_TEST_GENERIC_RX_WATERMARK_RESVAL = 1'h 0; - parameter logic [0:0] SPI_DEVICE_INTR_TEST_GENERIC_TX_WATERMARK_RESVAL = 1'h 0; - parameter logic [0:0] SPI_DEVICE_INTR_TEST_GENERIC_RX_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] SPI_DEVICE_INTR_TEST_GENERIC_RX_OVERFLOW_RESVAL = 1'h 0; - parameter logic [0:0] SPI_DEVICE_INTR_TEST_GENERIC_TX_UNDERFLOW_RESVAL = 1'h 0; + parameter logic [5:0] SPI_DEVICE_INTR_TEST_RESVAL = 6'h 0; parameter logic [0:0] SPI_DEVICE_INTR_TEST_UPLOAD_CMDFIFO_NOT_EMPTY_RESVAL = 1'h 0; parameter logic [0:0] SPI_DEVICE_INTR_TEST_UPLOAD_PAYLOAD_NOT_EMPTY_RESVAL = 1'h 0; parameter logic [0:0] SPI_DEVICE_INTR_TEST_UPLOAD_PAYLOAD_OVERFLOW_RESVAL = 1'h 0; @@ -834,11 +636,7 @@ package spi_device_reg_pkg; parameter logic [0:0] SPI_DEVICE_INTR_TEST_TPM_HEADER_NOT_EMPTY_RESVAL = 1'h 0; parameter logic [0:0] SPI_DEVICE_ALERT_TEST_RESVAL = 1'h 0; parameter logic [0:0] SPI_DEVICE_ALERT_TEST_FATAL_FAULT_RESVAL = 1'h 0; - parameter logic [23:0] SPI_DEVICE_ASYNC_FIFO_LEVEL_RESVAL = 24'h 0; - parameter logic [6:0] SPI_DEVICE_STATUS_RESVAL = 7'h 7a; - parameter logic [0:0] SPI_DEVICE_STATUS_RXF_EMPTY_RESVAL = 1'h 1; - parameter logic [0:0] SPI_DEVICE_STATUS_TXF_EMPTY_RESVAL = 1'h 1; - parameter logic [0:0] SPI_DEVICE_STATUS_ABORT_DONE_RESVAL = 1'h 1; + parameter logic [6:0] SPI_DEVICE_STATUS_RESVAL = 7'h 60; parameter logic [0:0] SPI_DEVICE_STATUS_CSB_RESVAL = 1'h 1; parameter logic [0:0] SPI_DEVICE_STATUS_TPM_CSB_RESVAL = 1'h 1; parameter logic [31:0] SPI_DEVICE_LAST_READ_ADDR_RESVAL = 32'h 0; @@ -861,13 +659,7 @@ package spi_device_reg_pkg; SPI_DEVICE_ALERT_TEST, SPI_DEVICE_CONTROL, SPI_DEVICE_CFG, - SPI_DEVICE_FIFO_LEVEL, - SPI_DEVICE_ASYNC_FIFO_LEVEL, SPI_DEVICE_STATUS, - SPI_DEVICE_RXF_PTR, - SPI_DEVICE_TXF_PTR, - SPI_DEVICE_RXF_ADDR, - SPI_DEVICE_TXF_ADDR, SPI_DEVICE_INTERCEPT_EN, SPI_DEVICE_LAST_READ_ADDR, SPI_DEVICE_FLASH_STATUS, @@ -937,86 +729,80 @@ package spi_device_reg_pkg; } spi_device_id_e; // Register width information to check illegal writes - parameter logic [3:0] SPI_DEVICE_PERMIT [79] = '{ - 4'b 0011, // index[ 0] SPI_DEVICE_INTR_STATE - 4'b 0011, // index[ 1] SPI_DEVICE_INTR_ENABLE - 4'b 0011, // index[ 2] SPI_DEVICE_INTR_TEST + parameter logic [3:0] SPI_DEVICE_PERMIT [73] = '{ + 4'b 0001, // index[ 0] SPI_DEVICE_INTR_STATE + 4'b 0001, // index[ 1] SPI_DEVICE_INTR_ENABLE + 4'b 0001, // index[ 2] SPI_DEVICE_INTR_TEST 4'b 0001, // index[ 3] SPI_DEVICE_ALERT_TEST - 4'b 1111, // index[ 4] SPI_DEVICE_CONTROL + 4'b 0001, // index[ 4] SPI_DEVICE_CONTROL 4'b 1111, // index[ 5] SPI_DEVICE_CFG - 4'b 1111, // index[ 6] SPI_DEVICE_FIFO_LEVEL - 4'b 0111, // index[ 7] SPI_DEVICE_ASYNC_FIFO_LEVEL - 4'b 0001, // index[ 8] SPI_DEVICE_STATUS - 4'b 1111, // index[ 9] SPI_DEVICE_RXF_PTR - 4'b 1111, // index[10] SPI_DEVICE_TXF_PTR - 4'b 1111, // index[11] SPI_DEVICE_RXF_ADDR - 4'b 1111, // index[12] SPI_DEVICE_TXF_ADDR - 4'b 0001, // index[13] SPI_DEVICE_INTERCEPT_EN - 4'b 1111, // index[14] SPI_DEVICE_LAST_READ_ADDR - 4'b 0111, // index[15] SPI_DEVICE_FLASH_STATUS - 4'b 0011, // index[16] SPI_DEVICE_JEDEC_CC - 4'b 0111, // index[17] SPI_DEVICE_JEDEC_ID - 4'b 0011, // index[18] SPI_DEVICE_READ_THRESHOLD - 4'b 1111, // index[19] SPI_DEVICE_MAILBOX_ADDR - 4'b 0011, // index[20] SPI_DEVICE_UPLOAD_STATUS - 4'b 0111, // index[21] SPI_DEVICE_UPLOAD_STATUS2 - 4'b 0001, // index[22] SPI_DEVICE_UPLOAD_CMDFIFO - 4'b 1111, // index[23] SPI_DEVICE_UPLOAD_ADDRFIFO - 4'b 1111, // index[24] SPI_DEVICE_CMD_FILTER_0 - 4'b 1111, // index[25] SPI_DEVICE_CMD_FILTER_1 - 4'b 1111, // index[26] SPI_DEVICE_CMD_FILTER_2 - 4'b 1111, // index[27] SPI_DEVICE_CMD_FILTER_3 - 4'b 1111, // index[28] SPI_DEVICE_CMD_FILTER_4 - 4'b 1111, // index[29] SPI_DEVICE_CMD_FILTER_5 - 4'b 1111, // index[30] SPI_DEVICE_CMD_FILTER_6 - 4'b 1111, // index[31] SPI_DEVICE_CMD_FILTER_7 - 4'b 1111, // index[32] SPI_DEVICE_ADDR_SWAP_MASK - 4'b 1111, // index[33] SPI_DEVICE_ADDR_SWAP_DATA - 4'b 1111, // index[34] SPI_DEVICE_PAYLOAD_SWAP_MASK - 4'b 1111, // index[35] SPI_DEVICE_PAYLOAD_SWAP_DATA - 4'b 1111, // index[36] SPI_DEVICE_CMD_INFO_0 - 4'b 1111, // index[37] SPI_DEVICE_CMD_INFO_1 - 4'b 1111, // index[38] SPI_DEVICE_CMD_INFO_2 - 4'b 1111, // index[39] SPI_DEVICE_CMD_INFO_3 - 4'b 1111, // index[40] SPI_DEVICE_CMD_INFO_4 - 4'b 1111, // index[41] SPI_DEVICE_CMD_INFO_5 - 4'b 1111, // index[42] SPI_DEVICE_CMD_INFO_6 - 4'b 1111, // index[43] SPI_DEVICE_CMD_INFO_7 - 4'b 1111, // index[44] SPI_DEVICE_CMD_INFO_8 - 4'b 1111, // index[45] SPI_DEVICE_CMD_INFO_9 - 4'b 1111, // index[46] SPI_DEVICE_CMD_INFO_10 - 4'b 1111, // index[47] SPI_DEVICE_CMD_INFO_11 - 4'b 1111, // index[48] SPI_DEVICE_CMD_INFO_12 - 4'b 1111, // index[49] SPI_DEVICE_CMD_INFO_13 - 4'b 1111, // index[50] SPI_DEVICE_CMD_INFO_14 - 4'b 1111, // index[51] SPI_DEVICE_CMD_INFO_15 - 4'b 1111, // index[52] SPI_DEVICE_CMD_INFO_16 - 4'b 1111, // index[53] SPI_DEVICE_CMD_INFO_17 - 4'b 1111, // index[54] SPI_DEVICE_CMD_INFO_18 - 4'b 1111, // index[55] SPI_DEVICE_CMD_INFO_19 - 4'b 1111, // index[56] SPI_DEVICE_CMD_INFO_20 - 4'b 1111, // index[57] SPI_DEVICE_CMD_INFO_21 - 4'b 1111, // index[58] SPI_DEVICE_CMD_INFO_22 - 4'b 1111, // index[59] SPI_DEVICE_CMD_INFO_23 - 4'b 1111, // index[60] SPI_DEVICE_CMD_INFO_EN4B - 4'b 1111, // index[61] SPI_DEVICE_CMD_INFO_EX4B - 4'b 1111, // index[62] SPI_DEVICE_CMD_INFO_WREN - 4'b 1111, // index[63] SPI_DEVICE_CMD_INFO_WRDI - 4'b 0111, // index[64] SPI_DEVICE_TPM_CAP - 4'b 0001, // index[65] SPI_DEVICE_TPM_CFG - 4'b 0111, // index[66] SPI_DEVICE_TPM_STATUS - 4'b 1111, // index[67] SPI_DEVICE_TPM_ACCESS_0 - 4'b 0001, // index[68] SPI_DEVICE_TPM_ACCESS_1 - 4'b 1111, // index[69] SPI_DEVICE_TPM_STS - 4'b 1111, // index[70] SPI_DEVICE_TPM_INTF_CAPABILITY - 4'b 1111, // index[71] SPI_DEVICE_TPM_INT_ENABLE - 4'b 0001, // index[72] SPI_DEVICE_TPM_INT_VECTOR - 4'b 1111, // index[73] SPI_DEVICE_TPM_INT_STATUS - 4'b 1111, // index[74] SPI_DEVICE_TPM_DID_VID - 4'b 0001, // index[75] SPI_DEVICE_TPM_RID - 4'b 1111, // index[76] SPI_DEVICE_TPM_CMD_ADDR - 4'b 1111, // index[77] SPI_DEVICE_TPM_READ_FIFO - 4'b 0001 // index[78] SPI_DEVICE_TPM_WRITE_FIFO + 4'b 0001, // index[ 6] SPI_DEVICE_STATUS + 4'b 0001, // index[ 7] SPI_DEVICE_INTERCEPT_EN + 4'b 1111, // index[ 8] SPI_DEVICE_LAST_READ_ADDR + 4'b 0111, // index[ 9] SPI_DEVICE_FLASH_STATUS + 4'b 0011, // index[10] SPI_DEVICE_JEDEC_CC + 4'b 0111, // index[11] SPI_DEVICE_JEDEC_ID + 4'b 0011, // index[12] SPI_DEVICE_READ_THRESHOLD + 4'b 1111, // index[13] SPI_DEVICE_MAILBOX_ADDR + 4'b 0011, // index[14] SPI_DEVICE_UPLOAD_STATUS + 4'b 0111, // index[15] SPI_DEVICE_UPLOAD_STATUS2 + 4'b 0001, // index[16] SPI_DEVICE_UPLOAD_CMDFIFO + 4'b 1111, // index[17] SPI_DEVICE_UPLOAD_ADDRFIFO + 4'b 1111, // index[18] SPI_DEVICE_CMD_FILTER_0 + 4'b 1111, // index[19] SPI_DEVICE_CMD_FILTER_1 + 4'b 1111, // index[20] SPI_DEVICE_CMD_FILTER_2 + 4'b 1111, // index[21] SPI_DEVICE_CMD_FILTER_3 + 4'b 1111, // index[22] SPI_DEVICE_CMD_FILTER_4 + 4'b 1111, // index[23] SPI_DEVICE_CMD_FILTER_5 + 4'b 1111, // index[24] SPI_DEVICE_CMD_FILTER_6 + 4'b 1111, // index[25] SPI_DEVICE_CMD_FILTER_7 + 4'b 1111, // index[26] SPI_DEVICE_ADDR_SWAP_MASK + 4'b 1111, // index[27] SPI_DEVICE_ADDR_SWAP_DATA + 4'b 1111, // index[28] SPI_DEVICE_PAYLOAD_SWAP_MASK + 4'b 1111, // index[29] SPI_DEVICE_PAYLOAD_SWAP_DATA + 4'b 1111, // index[30] SPI_DEVICE_CMD_INFO_0 + 4'b 1111, // index[31] SPI_DEVICE_CMD_INFO_1 + 4'b 1111, // index[32] SPI_DEVICE_CMD_INFO_2 + 4'b 1111, // index[33] SPI_DEVICE_CMD_INFO_3 + 4'b 1111, // index[34] SPI_DEVICE_CMD_INFO_4 + 4'b 1111, // index[35] SPI_DEVICE_CMD_INFO_5 + 4'b 1111, // index[36] SPI_DEVICE_CMD_INFO_6 + 4'b 1111, // index[37] SPI_DEVICE_CMD_INFO_7 + 4'b 1111, // index[38] SPI_DEVICE_CMD_INFO_8 + 4'b 1111, // index[39] SPI_DEVICE_CMD_INFO_9 + 4'b 1111, // index[40] SPI_DEVICE_CMD_INFO_10 + 4'b 1111, // index[41] SPI_DEVICE_CMD_INFO_11 + 4'b 1111, // index[42] SPI_DEVICE_CMD_INFO_12 + 4'b 1111, // index[43] SPI_DEVICE_CMD_INFO_13 + 4'b 1111, // index[44] SPI_DEVICE_CMD_INFO_14 + 4'b 1111, // index[45] SPI_DEVICE_CMD_INFO_15 + 4'b 1111, // index[46] SPI_DEVICE_CMD_INFO_16 + 4'b 1111, // index[47] SPI_DEVICE_CMD_INFO_17 + 4'b 1111, // index[48] SPI_DEVICE_CMD_INFO_18 + 4'b 1111, // index[49] SPI_DEVICE_CMD_INFO_19 + 4'b 1111, // index[50] SPI_DEVICE_CMD_INFO_20 + 4'b 1111, // index[51] SPI_DEVICE_CMD_INFO_21 + 4'b 1111, // index[52] SPI_DEVICE_CMD_INFO_22 + 4'b 1111, // index[53] SPI_DEVICE_CMD_INFO_23 + 4'b 1111, // index[54] SPI_DEVICE_CMD_INFO_EN4B + 4'b 1111, // index[55] SPI_DEVICE_CMD_INFO_EX4B + 4'b 1111, // index[56] SPI_DEVICE_CMD_INFO_WREN + 4'b 1111, // index[57] SPI_DEVICE_CMD_INFO_WRDI + 4'b 0111, // index[58] SPI_DEVICE_TPM_CAP + 4'b 0001, // index[59] SPI_DEVICE_TPM_CFG + 4'b 0111, // index[60] SPI_DEVICE_TPM_STATUS + 4'b 1111, // index[61] SPI_DEVICE_TPM_ACCESS_0 + 4'b 0001, // index[62] SPI_DEVICE_TPM_ACCESS_1 + 4'b 1111, // index[63] SPI_DEVICE_TPM_STS + 4'b 1111, // index[64] SPI_DEVICE_TPM_INTF_CAPABILITY + 4'b 1111, // index[65] SPI_DEVICE_TPM_INT_ENABLE + 4'b 0001, // index[66] SPI_DEVICE_TPM_INT_VECTOR + 4'b 1111, // index[67] SPI_DEVICE_TPM_INT_STATUS + 4'b 1111, // index[68] SPI_DEVICE_TPM_DID_VID + 4'b 0001, // index[69] SPI_DEVICE_TPM_RID + 4'b 1111, // index[70] SPI_DEVICE_TPM_CMD_ADDR + 4'b 1111, // index[71] SPI_DEVICE_TPM_READ_FIFO + 4'b 0001 // index[72] SPI_DEVICE_TPM_WRITE_FIFO }; endpackage diff --git a/hw/ip/spi_device/rtl/spi_device_reg_top.sv b/hw/ip/spi_device/rtl/spi_device_reg_top.sv index 76103611a69ed..5592f67efd60f 100644 --- a/hw/ip/spi_device/rtl/spi_device_reg_top.sv +++ b/hw/ip/spi_device/rtl/spi_device_reg_top.sv @@ -57,9 +57,9 @@ module spi_device_reg_top ( // also check for spurious write enables logic reg_we_err; - logic [78:0] reg_we_check; + logic [72:0] reg_we_check; prim_reg_we_check #( - .OneHotWidth(79) + .OneHotWidth(73) ) u_prim_reg_we_check ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -171,18 +171,6 @@ module spi_device_reg_top ( // Format: __{wd|we|qs} // or _{wd|we|qs} if field == 1 or 0 logic intr_state_we; - logic intr_state_generic_rx_full_qs; - logic intr_state_generic_rx_full_wd; - logic intr_state_generic_rx_watermark_qs; - logic intr_state_generic_rx_watermark_wd; - logic intr_state_generic_tx_watermark_qs; - logic intr_state_generic_tx_watermark_wd; - logic intr_state_generic_rx_error_qs; - logic intr_state_generic_rx_error_wd; - logic intr_state_generic_rx_overflow_qs; - logic intr_state_generic_rx_overflow_wd; - logic intr_state_generic_tx_underflow_qs; - logic intr_state_generic_tx_underflow_wd; logic intr_state_upload_cmdfifo_not_empty_qs; logic intr_state_upload_cmdfifo_not_empty_wd; logic intr_state_upload_payload_not_empty_qs; @@ -195,18 +183,6 @@ module spi_device_reg_top ( logic intr_state_readbuf_flip_wd; logic intr_state_tpm_header_not_empty_qs; logic intr_enable_we; - logic intr_enable_generic_rx_full_qs; - logic intr_enable_generic_rx_full_wd; - logic intr_enable_generic_rx_watermark_qs; - logic intr_enable_generic_rx_watermark_wd; - logic intr_enable_generic_tx_watermark_qs; - logic intr_enable_generic_tx_watermark_wd; - logic intr_enable_generic_rx_error_qs; - logic intr_enable_generic_rx_error_wd; - logic intr_enable_generic_rx_overflow_qs; - logic intr_enable_generic_rx_overflow_wd; - logic intr_enable_generic_tx_underflow_qs; - logic intr_enable_generic_tx_underflow_wd; logic intr_enable_upload_cmdfifo_not_empty_qs; logic intr_enable_upload_cmdfifo_not_empty_wd; logic intr_enable_upload_payload_not_empty_qs; @@ -220,12 +196,6 @@ module spi_device_reg_top ( logic intr_enable_tpm_header_not_empty_qs; logic intr_enable_tpm_header_not_empty_wd; logic intr_test_we; - logic intr_test_generic_rx_full_wd; - logic intr_test_generic_rx_watermark_wd; - logic intr_test_generic_tx_watermark_wd; - logic intr_test_generic_rx_error_wd; - logic intr_test_generic_rx_overflow_wd; - logic intr_test_generic_tx_underflow_wd; logic intr_test_upload_cmdfifo_not_empty_wd; logic intr_test_upload_payload_not_empty_wd; logic intr_test_upload_payload_overflow_wd; @@ -235,16 +205,8 @@ module spi_device_reg_top ( logic alert_test_we; logic alert_test_wd; logic control_we; - logic control_abort_qs; - logic control_abort_wd; - logic [1:0] control_mode_qs; - logic [1:0] control_mode_wd; - logic control_rst_txfifo_qs; - logic control_rst_txfifo_wd; - logic control_rst_rxfifo_qs; - logic control_rst_rxfifo_wd; - logic control_sram_clk_en_qs; - logic control_sram_clk_en_wd; + logic [1:0] control_qs; + logic [1:0] control_wd; logic cfg_we; logic cfg_cpol_qs; logic cfg_cpol_wd; @@ -254,46 +216,13 @@ module spi_device_reg_top ( logic cfg_tx_order_wd; logic cfg_rx_order_qs; logic cfg_rx_order_wd; - logic [7:0] cfg_timer_v_qs; - logic [7:0] cfg_timer_v_wd; logic cfg_addr_4b_en_qs; logic cfg_addr_4b_en_wd; logic cfg_mailbox_en_qs; logic cfg_mailbox_en_wd; - logic fifo_level_we; - logic [15:0] fifo_level_rxlvl_qs; - logic [15:0] fifo_level_rxlvl_wd; - logic [15:0] fifo_level_txlvl_qs; - logic [15:0] fifo_level_txlvl_wd; - logic async_fifo_level_re; - logic [7:0] async_fifo_level_rxlvl_qs; - logic [7:0] async_fifo_level_txlvl_qs; logic status_re; - logic status_rxf_full_qs; - logic status_rxf_empty_qs; - logic status_txf_full_qs; - logic status_txf_empty_qs; - logic status_abort_done_qs; logic status_csb_qs; logic status_tpm_csb_qs; - logic rxf_ptr_we; - logic [15:0] rxf_ptr_rptr_qs; - logic [15:0] rxf_ptr_rptr_wd; - logic [15:0] rxf_ptr_wptr_qs; - logic txf_ptr_we; - logic [15:0] txf_ptr_rptr_qs; - logic [15:0] txf_ptr_wptr_qs; - logic [15:0] txf_ptr_wptr_wd; - logic rxf_addr_we; - logic [15:0] rxf_addr_base_qs; - logic [15:0] rxf_addr_base_wd; - logic [15:0] rxf_addr_limit_qs; - logic [15:0] rxf_addr_limit_wd; - logic txf_addr_we; - logic [15:0] txf_addr_base_qs; - logic [15:0] txf_addr_base_wd; - logic [15:0] txf_addr_limit_qs; - logic [15:0] txf_addr_limit_wd; logic intercept_en_we; logic intercept_en_status_qs; logic intercept_en_status_wd; @@ -1551,169 +1480,7 @@ module spi_device_reg_top ( // Register instances // R[intr_state]: V(False) - // F[generic_rx_full]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_state_generic_rx_full ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_state_we), - .wd (intr_state_generic_rx_full_wd), - - // from internal hardware - .de (hw2reg.intr_state.generic_rx_full.de), - .d (hw2reg.intr_state.generic_rx_full.d), - - // to internal hardware - .qe (), - .q (reg2hw.intr_state.generic_rx_full.q), - .ds (), - - // to register interface (read) - .qs (intr_state_generic_rx_full_qs) - ); - - // F[generic_rx_watermark]: 1:1 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_state_generic_rx_watermark ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_state_we), - .wd (intr_state_generic_rx_watermark_wd), - - // from internal hardware - .de (hw2reg.intr_state.generic_rx_watermark.de), - .d (hw2reg.intr_state.generic_rx_watermark.d), - - // to internal hardware - .qe (), - .q (reg2hw.intr_state.generic_rx_watermark.q), - .ds (), - - // to register interface (read) - .qs (intr_state_generic_rx_watermark_qs) - ); - - // F[generic_tx_watermark]: 2:2 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_state_generic_tx_watermark ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_state_we), - .wd (intr_state_generic_tx_watermark_wd), - - // from internal hardware - .de (hw2reg.intr_state.generic_tx_watermark.de), - .d (hw2reg.intr_state.generic_tx_watermark.d), - - // to internal hardware - .qe (), - .q (reg2hw.intr_state.generic_tx_watermark.q), - .ds (), - - // to register interface (read) - .qs (intr_state_generic_tx_watermark_qs) - ); - - // F[generic_rx_error]: 3:3 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_state_generic_rx_error ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_state_we), - .wd (intr_state_generic_rx_error_wd), - - // from internal hardware - .de (hw2reg.intr_state.generic_rx_error.de), - .d (hw2reg.intr_state.generic_rx_error.d), - - // to internal hardware - .qe (), - .q (reg2hw.intr_state.generic_rx_error.q), - .ds (), - - // to register interface (read) - .qs (intr_state_generic_rx_error_qs) - ); - - // F[generic_rx_overflow]: 4:4 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_state_generic_rx_overflow ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_state_we), - .wd (intr_state_generic_rx_overflow_wd), - - // from internal hardware - .de (hw2reg.intr_state.generic_rx_overflow.de), - .d (hw2reg.intr_state.generic_rx_overflow.d), - - // to internal hardware - .qe (), - .q (reg2hw.intr_state.generic_rx_overflow.q), - .ds (), - - // to register interface (read) - .qs (intr_state_generic_rx_overflow_qs) - ); - - // F[generic_tx_underflow]: 5:5 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_state_generic_tx_underflow ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_state_we), - .wd (intr_state_generic_tx_underflow_wd), - - // from internal hardware - .de (hw2reg.intr_state.generic_tx_underflow.de), - .d (hw2reg.intr_state.generic_tx_underflow.d), - - // to internal hardware - .qe (), - .q (reg2hw.intr_state.generic_tx_underflow.q), - .ds (), - - // to register interface (read) - .qs (intr_state_generic_tx_underflow_qs) - ); - - // F[upload_cmdfifo_not_empty]: 6:6 + // F[upload_cmdfifo_not_empty]: 0:0 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessW1C), @@ -1740,7 +1507,7 @@ module spi_device_reg_top ( .qs (intr_state_upload_cmdfifo_not_empty_qs) ); - // F[upload_payload_not_empty]: 7:7 + // F[upload_payload_not_empty]: 1:1 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessW1C), @@ -1767,7 +1534,7 @@ module spi_device_reg_top ( .qs (intr_state_upload_payload_not_empty_qs) ); - // F[upload_payload_overflow]: 8:8 + // F[upload_payload_overflow]: 2:2 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessW1C), @@ -1794,7 +1561,7 @@ module spi_device_reg_top ( .qs (intr_state_upload_payload_overflow_qs) ); - // F[readbuf_watermark]: 9:9 + // F[readbuf_watermark]: 3:3 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessW1C), @@ -1821,7 +1588,7 @@ module spi_device_reg_top ( .qs (intr_state_readbuf_watermark_qs) ); - // F[readbuf_flip]: 10:10 + // F[readbuf_flip]: 4:4 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessW1C), @@ -1848,7 +1615,7 @@ module spi_device_reg_top ( .qs (intr_state_readbuf_flip_qs) ); - // F[tpm_header_not_empty]: 11:11 + // F[tpm_header_not_empty]: 5:5 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRO), @@ -1877,169 +1644,7 @@ module spi_device_reg_top ( // R[intr_enable]: V(False) - // F[generic_rx_full]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_enable_generic_rx_full ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_enable_we), - .wd (intr_enable_generic_rx_full_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.intr_enable.generic_rx_full.q), - .ds (), - - // to register interface (read) - .qs (intr_enable_generic_rx_full_qs) - ); - - // F[generic_rx_watermark]: 1:1 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_enable_generic_rx_watermark ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_enable_we), - .wd (intr_enable_generic_rx_watermark_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.intr_enable.generic_rx_watermark.q), - .ds (), - - // to register interface (read) - .qs (intr_enable_generic_rx_watermark_qs) - ); - - // F[generic_tx_watermark]: 2:2 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_enable_generic_tx_watermark ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_enable_we), - .wd (intr_enable_generic_tx_watermark_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.intr_enable.generic_tx_watermark.q), - .ds (), - - // to register interface (read) - .qs (intr_enable_generic_tx_watermark_qs) - ); - - // F[generic_rx_error]: 3:3 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_enable_generic_rx_error ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_enable_we), - .wd (intr_enable_generic_rx_error_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.intr_enable.generic_rx_error.q), - .ds (), - - // to register interface (read) - .qs (intr_enable_generic_rx_error_qs) - ); - - // F[generic_rx_overflow]: 4:4 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_enable_generic_rx_overflow ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_enable_we), - .wd (intr_enable_generic_rx_overflow_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.intr_enable.generic_rx_overflow.q), - .ds (), - - // to register interface (read) - .qs (intr_enable_generic_rx_overflow_qs) - ); - - // F[generic_tx_underflow]: 5:5 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_enable_generic_tx_underflow ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_enable_we), - .wd (intr_enable_generic_tx_underflow_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.intr_enable.generic_tx_underflow.q), - .ds (), - - // to register interface (read) - .qs (intr_enable_generic_tx_underflow_qs) - ); - - // F[upload_cmdfifo_not_empty]: 6:6 + // F[upload_cmdfifo_not_empty]: 0:0 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), @@ -2066,7 +1671,7 @@ module spi_device_reg_top ( .qs (intr_enable_upload_cmdfifo_not_empty_qs) ); - // F[upload_payload_not_empty]: 7:7 + // F[upload_payload_not_empty]: 1:1 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), @@ -2093,7 +1698,7 @@ module spi_device_reg_top ( .qs (intr_enable_upload_payload_not_empty_qs) ); - // F[upload_payload_overflow]: 8:8 + // F[upload_payload_overflow]: 2:2 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), @@ -2120,7 +1725,7 @@ module spi_device_reg_top ( .qs (intr_enable_upload_payload_overflow_qs) ); - // F[readbuf_watermark]: 9:9 + // F[readbuf_watermark]: 3:3 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), @@ -2147,7 +1752,7 @@ module spi_device_reg_top ( .qs (intr_enable_readbuf_watermark_qs) ); - // F[readbuf_flip]: 10:10 + // F[readbuf_flip]: 4:4 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), @@ -2174,7 +1779,7 @@ module spi_device_reg_top ( .qs (intr_enable_readbuf_flip_qs) ); - // F[tpm_header_not_empty]: 11:11 + // F[tpm_header_not_empty]: 5:5 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), @@ -2204,121 +1809,25 @@ module spi_device_reg_top ( // R[intr_test]: V(True) logic intr_test_qe; - logic [11:0] intr_test_flds_we; + logic [5:0] intr_test_flds_we; assign intr_test_qe = &intr_test_flds_we; - // F[generic_rx_full]: 0:0 + // F[upload_cmdfifo_not_empty]: 0:0 prim_subreg_ext #( .DW (1) - ) u_intr_test_generic_rx_full ( + ) u_intr_test_upload_cmdfifo_not_empty ( .re (1'b0), .we (intr_test_we), - .wd (intr_test_generic_rx_full_wd), + .wd (intr_test_upload_cmdfifo_not_empty_wd), .d ('0), .qre (), .qe (intr_test_flds_we[0]), - .q (reg2hw.intr_test.generic_rx_full.q), + .q (reg2hw.intr_test.upload_cmdfifo_not_empty.q), .ds (), .qs () ); - assign reg2hw.intr_test.generic_rx_full.qe = intr_test_qe; + assign reg2hw.intr_test.upload_cmdfifo_not_empty.qe = intr_test_qe; - // F[generic_rx_watermark]: 1:1 - prim_subreg_ext #( - .DW (1) - ) u_intr_test_generic_rx_watermark ( - .re (1'b0), - .we (intr_test_we), - .wd (intr_test_generic_rx_watermark_wd), - .d ('0), - .qre (), - .qe (intr_test_flds_we[1]), - .q (reg2hw.intr_test.generic_rx_watermark.q), - .ds (), - .qs () - ); - assign reg2hw.intr_test.generic_rx_watermark.qe = intr_test_qe; - - // F[generic_tx_watermark]: 2:2 - prim_subreg_ext #( - .DW (1) - ) u_intr_test_generic_tx_watermark ( - .re (1'b0), - .we (intr_test_we), - .wd (intr_test_generic_tx_watermark_wd), - .d ('0), - .qre (), - .qe (intr_test_flds_we[2]), - .q (reg2hw.intr_test.generic_tx_watermark.q), - .ds (), - .qs () - ); - assign reg2hw.intr_test.generic_tx_watermark.qe = intr_test_qe; - - // F[generic_rx_error]: 3:3 - prim_subreg_ext #( - .DW (1) - ) u_intr_test_generic_rx_error ( - .re (1'b0), - .we (intr_test_we), - .wd (intr_test_generic_rx_error_wd), - .d ('0), - .qre (), - .qe (intr_test_flds_we[3]), - .q (reg2hw.intr_test.generic_rx_error.q), - .ds (), - .qs () - ); - assign reg2hw.intr_test.generic_rx_error.qe = intr_test_qe; - - // F[generic_rx_overflow]: 4:4 - prim_subreg_ext #( - .DW (1) - ) u_intr_test_generic_rx_overflow ( - .re (1'b0), - .we (intr_test_we), - .wd (intr_test_generic_rx_overflow_wd), - .d ('0), - .qre (), - .qe (intr_test_flds_we[4]), - .q (reg2hw.intr_test.generic_rx_overflow.q), - .ds (), - .qs () - ); - assign reg2hw.intr_test.generic_rx_overflow.qe = intr_test_qe; - - // F[generic_tx_underflow]: 5:5 - prim_subreg_ext #( - .DW (1) - ) u_intr_test_generic_tx_underflow ( - .re (1'b0), - .we (intr_test_we), - .wd (intr_test_generic_tx_underflow_wd), - .d ('0), - .qre (), - .qe (intr_test_flds_we[5]), - .q (reg2hw.intr_test.generic_tx_underflow.q), - .ds (), - .qs () - ); - assign reg2hw.intr_test.generic_tx_underflow.qe = intr_test_qe; - - // F[upload_cmdfifo_not_empty]: 6:6 - prim_subreg_ext #( - .DW (1) - ) u_intr_test_upload_cmdfifo_not_empty ( - .re (1'b0), - .we (intr_test_we), - .wd (intr_test_upload_cmdfifo_not_empty_wd), - .d ('0), - .qre (), - .qe (intr_test_flds_we[6]), - .q (reg2hw.intr_test.upload_cmdfifo_not_empty.q), - .ds (), - .qs () - ); - assign reg2hw.intr_test.upload_cmdfifo_not_empty.qe = intr_test_qe; - - // F[upload_payload_not_empty]: 7:7 + // F[upload_payload_not_empty]: 1:1 prim_subreg_ext #( .DW (1) ) u_intr_test_upload_payload_not_empty ( @@ -2327,14 +1836,14 @@ module spi_device_reg_top ( .wd (intr_test_upload_payload_not_empty_wd), .d ('0), .qre (), - .qe (intr_test_flds_we[7]), + .qe (intr_test_flds_we[1]), .q (reg2hw.intr_test.upload_payload_not_empty.q), .ds (), .qs () ); assign reg2hw.intr_test.upload_payload_not_empty.qe = intr_test_qe; - // F[upload_payload_overflow]: 8:8 + // F[upload_payload_overflow]: 2:2 prim_subreg_ext #( .DW (1) ) u_intr_test_upload_payload_overflow ( @@ -2343,14 +1852,14 @@ module spi_device_reg_top ( .wd (intr_test_upload_payload_overflow_wd), .d ('0), .qre (), - .qe (intr_test_flds_we[8]), + .qe (intr_test_flds_we[2]), .q (reg2hw.intr_test.upload_payload_overflow.q), .ds (), .qs () ); assign reg2hw.intr_test.upload_payload_overflow.qe = intr_test_qe; - // F[readbuf_watermark]: 9:9 + // F[readbuf_watermark]: 3:3 prim_subreg_ext #( .DW (1) ) u_intr_test_readbuf_watermark ( @@ -2359,14 +1868,14 @@ module spi_device_reg_top ( .wd (intr_test_readbuf_watermark_wd), .d ('0), .qre (), - .qe (intr_test_flds_we[9]), + .qe (intr_test_flds_we[3]), .q (reg2hw.intr_test.readbuf_watermark.q), .ds (), .qs () ); assign reg2hw.intr_test.readbuf_watermark.qe = intr_test_qe; - // F[readbuf_flip]: 10:10 + // F[readbuf_flip]: 4:4 prim_subreg_ext #( .DW (1) ) u_intr_test_readbuf_flip ( @@ -2375,14 +1884,14 @@ module spi_device_reg_top ( .wd (intr_test_readbuf_flip_wd), .d ('0), .qre (), - .qe (intr_test_flds_we[10]), + .qe (intr_test_flds_we[4]), .q (reg2hw.intr_test.readbuf_flip.q), .ds (), .qs () ); assign reg2hw.intr_test.readbuf_flip.qe = intr_test_qe; - // F[tpm_header_not_empty]: 11:11 + // F[tpm_header_not_empty]: 5:5 prim_subreg_ext #( .DW (1) ) u_intr_test_tpm_header_not_empty ( @@ -2391,7 +1900,7 @@ module spi_device_reg_top ( .wd (intr_test_tpm_header_not_empty_wd), .d ('0), .qre (), - .qe (intr_test_flds_we[11]), + .qe (intr_test_flds_we[5]), .q (reg2hw.intr_test.tpm_header_not_empty.q), .ds (), .qs () @@ -2420,127 +1929,18 @@ module spi_device_reg_top ( // R[control]: V(False) - // F[abort]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_control_abort ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_we), - .wd (control_abort_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.abort.q), - .ds (), - - // to register interface (read) - .qs (control_abort_qs) - ); - - // F[mode]: 5:4 prim_subreg #( .DW (2), .SwAccess(prim_subreg_pkg::SwAccessRW), .RESVAL (2'h1), .Mubi (1'b0) - ) u_control_mode ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_we), - .wd (control_mode_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.mode.q), - .ds (), - - // to register interface (read) - .qs (control_mode_qs) - ); - - // F[rst_txfifo]: 16:16 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_control_rst_txfifo ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_we), - .wd (control_rst_txfifo_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.rst_txfifo.q), - .ds (), - - // to register interface (read) - .qs (control_rst_txfifo_qs) - ); - - // F[rst_rxfifo]: 17:17 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_control_rst_rxfifo ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_we), - .wd (control_rst_rxfifo_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.rst_rxfifo.q), - .ds (), - - // to register interface (read) - .qs (control_rst_rxfifo_qs) - ); - - // F[sram_clk_en]: 31:31 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_control_sram_clk_en ( + ) u_control ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (control_we), - .wd (control_sram_clk_en_wd), + .wd (control_wd), // from internal hardware .de (1'b0), @@ -2548,11 +1948,11 @@ module spi_device_reg_top ( // to internal hardware .qe (), - .q (reg2hw.control.sram_clk_en.q), + .q (reg2hw.control.q), .ds (), // to register interface (read) - .qs (control_sram_clk_en_qs) + .qs (control_qs) ); @@ -2588,457 +1988,15 @@ module spi_device_reg_top ( prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_cfg_cpha ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (cfg_we), - .wd (cfg_cpha_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.cfg.cpha.q), - .ds (), - - // to register interface (read) - .qs (cfg_cpha_qs) - ); - - // F[tx_order]: 2:2 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_cfg_tx_order ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (cfg_we), - .wd (cfg_tx_order_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.cfg.tx_order.q), - .ds (), - - // to register interface (read) - .qs (cfg_tx_order_qs) - ); - - // F[rx_order]: 3:3 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_cfg_rx_order ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (cfg_we), - .wd (cfg_rx_order_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.cfg.rx_order.q), - .ds (), - - // to register interface (read) - .qs (cfg_rx_order_qs) - ); - - // F[timer_v]: 15:8 - prim_subreg #( - .DW (8), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (8'h7f), - .Mubi (1'b0) - ) u_cfg_timer_v ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (cfg_we), - .wd (cfg_timer_v_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.cfg.timer_v.q), - .ds (), - - // to register interface (read) - .qs (cfg_timer_v_qs) - ); - - // F[addr_4b_en]: 16:16 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_cfg_addr_4b_en ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (cfg_we), - .wd (cfg_addr_4b_en_wd), - - // from internal hardware - .de (hw2reg.cfg.addr_4b_en.de), - .d (hw2reg.cfg.addr_4b_en.d), - - // to internal hardware - .qe (), - .q (reg2hw.cfg.addr_4b_en.q), - .ds (), - - // to register interface (read) - .qs (cfg_addr_4b_en_qs) - ); - - // F[mailbox_en]: 24:24 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_cfg_mailbox_en ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (cfg_we), - .wd (cfg_mailbox_en_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.cfg.mailbox_en.q), - .ds (), - - // to register interface (read) - .qs (cfg_mailbox_en_qs) - ); - - - // R[fifo_level]: V(False) - // F[rxlvl]: 15:0 - prim_subreg #( - .DW (16), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (16'h80), - .Mubi (1'b0) - ) u_fifo_level_rxlvl ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (fifo_level_we), - .wd (fifo_level_rxlvl_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.fifo_level.rxlvl.q), - .ds (), - - // to register interface (read) - .qs (fifo_level_rxlvl_qs) - ); - - // F[txlvl]: 31:16 - prim_subreg #( - .DW (16), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (16'h0), - .Mubi (1'b0) - ) u_fifo_level_txlvl ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (fifo_level_we), - .wd (fifo_level_txlvl_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.fifo_level.txlvl.q), - .ds (), - - // to register interface (read) - .qs (fifo_level_txlvl_qs) - ); - - - // R[async_fifo_level]: V(True) - // F[rxlvl]: 7:0 - prim_subreg_ext #( - .DW (8) - ) u_async_fifo_level_rxlvl ( - .re (async_fifo_level_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.async_fifo_level.rxlvl.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (async_fifo_level_rxlvl_qs) - ); - - // F[txlvl]: 23:16 - prim_subreg_ext #( - .DW (8) - ) u_async_fifo_level_txlvl ( - .re (async_fifo_level_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.async_fifo_level.txlvl.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (async_fifo_level_txlvl_qs) - ); - - - // R[status]: V(True) - // F[rxf_full]: 0:0 - prim_subreg_ext #( - .DW (1) - ) u_status_rxf_full ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.rxf_full.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_rxf_full_qs) - ); - - // F[rxf_empty]: 1:1 - prim_subreg_ext #( - .DW (1) - ) u_status_rxf_empty ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.rxf_empty.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_rxf_empty_qs) - ); - - // F[txf_full]: 2:2 - prim_subreg_ext #( - .DW (1) - ) u_status_txf_full ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.txf_full.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_txf_full_qs) - ); - - // F[txf_empty]: 3:3 - prim_subreg_ext #( - .DW (1) - ) u_status_txf_empty ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.txf_empty.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_txf_empty_qs) - ); - - // F[abort_done]: 4:4 - prim_subreg_ext #( - .DW (1) - ) u_status_abort_done ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.abort_done.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_abort_done_qs) - ); - - // F[csb]: 5:5 - prim_subreg_ext #( - .DW (1) - ) u_status_csb ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.csb.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_csb_qs) - ); - - // F[tpm_csb]: 6:6 - prim_subreg_ext #( - .DW (1) - ) u_status_tpm_csb ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.tpm_csb.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_tpm_csb_qs) - ); - - - // R[rxf_ptr]: V(False) - // F[rptr]: 15:0 - prim_subreg #( - .DW (16), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (16'h0), - .Mubi (1'b0) - ) u_rxf_ptr_rptr ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (rxf_ptr_we), - .wd (rxf_ptr_rptr_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.rxf_ptr.rptr.q), - .ds (), - - // to register interface (read) - .qs (rxf_ptr_rptr_qs) - ); - - // F[wptr]: 31:16 - prim_subreg #( - .DW (16), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (16'h0), - .Mubi (1'b0) - ) u_rxf_ptr_wptr ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.rxf_ptr.wptr.de), - .d (hw2reg.rxf_ptr.wptr.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (rxf_ptr_wptr_qs) - ); - - - // R[txf_ptr]: V(False) - // F[rptr]: 15:0 - prim_subreg #( - .DW (16), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (16'h0), - .Mubi (1'b0) - ) u_txf_ptr_rptr ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.txf_ptr.rptr.de), - .d (hw2reg.txf_ptr.rptr.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (txf_ptr_rptr_qs) - ); - - // F[wptr]: 31:16 - prim_subreg #( - .DW (16), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (16'h0), + .RESVAL (1'h0), .Mubi (1'b0) - ) u_txf_ptr_wptr ( + ) u_cfg_cpha ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface - .we (txf_ptr_we), - .wd (txf_ptr_wptr_wd), + .we (cfg_we), + .wd (cfg_cpha_wd), // from internal hardware .de (1'b0), @@ -3046,28 +2004,26 @@ module spi_device_reg_top ( // to internal hardware .qe (), - .q (reg2hw.txf_ptr.wptr.q), + .q (reg2hw.cfg.cpha.q), .ds (), // to register interface (read) - .qs (txf_ptr_wptr_qs) + .qs (cfg_cpha_qs) ); - - // R[rxf_addr]: V(False) - // F[base]: 15:0 + // F[tx_order]: 2:2 prim_subreg #( - .DW (16), + .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (16'h0), + .RESVAL (1'h0), .Mubi (1'b0) - ) u_rxf_addr_base ( + ) u_cfg_tx_order ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface - .we (rxf_addr_we), - .wd (rxf_addr_base_wd), + .we (cfg_we), + .wd (cfg_tx_order_wd), // from internal hardware .de (1'b0), @@ -3075,26 +2031,26 @@ module spi_device_reg_top ( // to internal hardware .qe (), - .q (reg2hw.rxf_addr.base.q), + .q (reg2hw.cfg.tx_order.q), .ds (), // to register interface (read) - .qs (rxf_addr_base_qs) + .qs (cfg_tx_order_qs) ); - // F[limit]: 31:16 + // F[rx_order]: 3:3 prim_subreg #( - .DW (16), + .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (16'h1fc), + .RESVAL (1'h0), .Mubi (1'b0) - ) u_rxf_addr_limit ( + ) u_cfg_rx_order ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface - .we (rxf_addr_we), - .wd (rxf_addr_limit_wd), + .we (cfg_we), + .wd (cfg_rx_order_wd), // from internal hardware .de (1'b0), @@ -3102,55 +2058,53 @@ module spi_device_reg_top ( // to internal hardware .qe (), - .q (reg2hw.rxf_addr.limit.q), + .q (reg2hw.cfg.rx_order.q), .ds (), // to register interface (read) - .qs (rxf_addr_limit_qs) + .qs (cfg_rx_order_qs) ); - - // R[txf_addr]: V(False) - // F[base]: 15:0 + // F[addr_4b_en]: 16:16 prim_subreg #( - .DW (16), + .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (16'h200), + .RESVAL (1'h0), .Mubi (1'b0) - ) u_txf_addr_base ( + ) u_cfg_addr_4b_en ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface - .we (txf_addr_we), - .wd (txf_addr_base_wd), + .we (cfg_we), + .wd (cfg_addr_4b_en_wd), // from internal hardware - .de (1'b0), - .d ('0), + .de (hw2reg.cfg.addr_4b_en.de), + .d (hw2reg.cfg.addr_4b_en.d), // to internal hardware .qe (), - .q (reg2hw.txf_addr.base.q), + .q (reg2hw.cfg.addr_4b_en.q), .ds (), // to register interface (read) - .qs (txf_addr_base_qs) + .qs (cfg_addr_4b_en_qs) ); - // F[limit]: 31:16 + // F[mailbox_en]: 24:24 prim_subreg #( - .DW (16), + .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (16'h3fc), + .RESVAL (1'h0), .Mubi (1'b0) - ) u_txf_addr_limit ( + ) u_cfg_mailbox_en ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface - .we (txf_addr_we), - .wd (txf_addr_limit_wd), + .we (cfg_we), + .wd (cfg_mailbox_en_wd), // from internal hardware .de (1'b0), @@ -3158,11 +2112,43 @@ module spi_device_reg_top ( // to internal hardware .qe (), - .q (reg2hw.txf_addr.limit.q), + .q (reg2hw.cfg.mailbox_en.q), .ds (), // to register interface (read) - .qs (txf_addr_limit_qs) + .qs (cfg_mailbox_en_qs) + ); + + + // R[status]: V(True) + // F[csb]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_status_csb ( + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.csb.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (status_csb_qs) + ); + + // F[tpm_csb]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_status_tpm_csb ( + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.tpm_csb.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (status_tpm_csb_qs) ); @@ -19562,7 +18548,7 @@ module spi_device_reg_top ( - logic [78:0] addr_hit; + logic [72:0] addr_hit; always_comb begin addr_hit = '0; addr_hit[ 0] = (reg_addr == SPI_DEVICE_INTR_STATE_OFFSET); @@ -19571,79 +18557,73 @@ module spi_device_reg_top ( addr_hit[ 3] = (reg_addr == SPI_DEVICE_ALERT_TEST_OFFSET); addr_hit[ 4] = (reg_addr == SPI_DEVICE_CONTROL_OFFSET); addr_hit[ 5] = (reg_addr == SPI_DEVICE_CFG_OFFSET); - addr_hit[ 6] = (reg_addr == SPI_DEVICE_FIFO_LEVEL_OFFSET); - addr_hit[ 7] = (reg_addr == SPI_DEVICE_ASYNC_FIFO_LEVEL_OFFSET); - addr_hit[ 8] = (reg_addr == SPI_DEVICE_STATUS_OFFSET); - addr_hit[ 9] = (reg_addr == SPI_DEVICE_RXF_PTR_OFFSET); - addr_hit[10] = (reg_addr == SPI_DEVICE_TXF_PTR_OFFSET); - addr_hit[11] = (reg_addr == SPI_DEVICE_RXF_ADDR_OFFSET); - addr_hit[12] = (reg_addr == SPI_DEVICE_TXF_ADDR_OFFSET); - addr_hit[13] = (reg_addr == SPI_DEVICE_INTERCEPT_EN_OFFSET); - addr_hit[14] = (reg_addr == SPI_DEVICE_LAST_READ_ADDR_OFFSET); - addr_hit[15] = (reg_addr == SPI_DEVICE_FLASH_STATUS_OFFSET); - addr_hit[16] = (reg_addr == SPI_DEVICE_JEDEC_CC_OFFSET); - addr_hit[17] = (reg_addr == SPI_DEVICE_JEDEC_ID_OFFSET); - addr_hit[18] = (reg_addr == SPI_DEVICE_READ_THRESHOLD_OFFSET); - addr_hit[19] = (reg_addr == SPI_DEVICE_MAILBOX_ADDR_OFFSET); - addr_hit[20] = (reg_addr == SPI_DEVICE_UPLOAD_STATUS_OFFSET); - addr_hit[21] = (reg_addr == SPI_DEVICE_UPLOAD_STATUS2_OFFSET); - addr_hit[22] = (reg_addr == SPI_DEVICE_UPLOAD_CMDFIFO_OFFSET); - addr_hit[23] = (reg_addr == SPI_DEVICE_UPLOAD_ADDRFIFO_OFFSET); - addr_hit[24] = (reg_addr == SPI_DEVICE_CMD_FILTER_0_OFFSET); - addr_hit[25] = (reg_addr == SPI_DEVICE_CMD_FILTER_1_OFFSET); - addr_hit[26] = (reg_addr == SPI_DEVICE_CMD_FILTER_2_OFFSET); - addr_hit[27] = (reg_addr == SPI_DEVICE_CMD_FILTER_3_OFFSET); - addr_hit[28] = (reg_addr == SPI_DEVICE_CMD_FILTER_4_OFFSET); - addr_hit[29] = (reg_addr == SPI_DEVICE_CMD_FILTER_5_OFFSET); - addr_hit[30] = (reg_addr == SPI_DEVICE_CMD_FILTER_6_OFFSET); - addr_hit[31] = (reg_addr == SPI_DEVICE_CMD_FILTER_7_OFFSET); - addr_hit[32] = (reg_addr == SPI_DEVICE_ADDR_SWAP_MASK_OFFSET); - addr_hit[33] = (reg_addr == SPI_DEVICE_ADDR_SWAP_DATA_OFFSET); - addr_hit[34] = (reg_addr == SPI_DEVICE_PAYLOAD_SWAP_MASK_OFFSET); - addr_hit[35] = (reg_addr == SPI_DEVICE_PAYLOAD_SWAP_DATA_OFFSET); - addr_hit[36] = (reg_addr == SPI_DEVICE_CMD_INFO_0_OFFSET); - addr_hit[37] = (reg_addr == SPI_DEVICE_CMD_INFO_1_OFFSET); - addr_hit[38] = (reg_addr == SPI_DEVICE_CMD_INFO_2_OFFSET); - addr_hit[39] = (reg_addr == SPI_DEVICE_CMD_INFO_3_OFFSET); - addr_hit[40] = (reg_addr == SPI_DEVICE_CMD_INFO_4_OFFSET); - addr_hit[41] = (reg_addr == SPI_DEVICE_CMD_INFO_5_OFFSET); - addr_hit[42] = (reg_addr == SPI_DEVICE_CMD_INFO_6_OFFSET); - addr_hit[43] = (reg_addr == SPI_DEVICE_CMD_INFO_7_OFFSET); - addr_hit[44] = (reg_addr == SPI_DEVICE_CMD_INFO_8_OFFSET); - addr_hit[45] = (reg_addr == SPI_DEVICE_CMD_INFO_9_OFFSET); - addr_hit[46] = (reg_addr == SPI_DEVICE_CMD_INFO_10_OFFSET); - addr_hit[47] = (reg_addr == SPI_DEVICE_CMD_INFO_11_OFFSET); - addr_hit[48] = (reg_addr == SPI_DEVICE_CMD_INFO_12_OFFSET); - addr_hit[49] = (reg_addr == SPI_DEVICE_CMD_INFO_13_OFFSET); - addr_hit[50] = (reg_addr == SPI_DEVICE_CMD_INFO_14_OFFSET); - addr_hit[51] = (reg_addr == SPI_DEVICE_CMD_INFO_15_OFFSET); - addr_hit[52] = (reg_addr == SPI_DEVICE_CMD_INFO_16_OFFSET); - addr_hit[53] = (reg_addr == SPI_DEVICE_CMD_INFO_17_OFFSET); - addr_hit[54] = (reg_addr == SPI_DEVICE_CMD_INFO_18_OFFSET); - addr_hit[55] = (reg_addr == SPI_DEVICE_CMD_INFO_19_OFFSET); - addr_hit[56] = (reg_addr == SPI_DEVICE_CMD_INFO_20_OFFSET); - addr_hit[57] = (reg_addr == SPI_DEVICE_CMD_INFO_21_OFFSET); - addr_hit[58] = (reg_addr == SPI_DEVICE_CMD_INFO_22_OFFSET); - addr_hit[59] = (reg_addr == SPI_DEVICE_CMD_INFO_23_OFFSET); - addr_hit[60] = (reg_addr == SPI_DEVICE_CMD_INFO_EN4B_OFFSET); - addr_hit[61] = (reg_addr == SPI_DEVICE_CMD_INFO_EX4B_OFFSET); - addr_hit[62] = (reg_addr == SPI_DEVICE_CMD_INFO_WREN_OFFSET); - addr_hit[63] = (reg_addr == SPI_DEVICE_CMD_INFO_WRDI_OFFSET); - addr_hit[64] = (reg_addr == SPI_DEVICE_TPM_CAP_OFFSET); - addr_hit[65] = (reg_addr == SPI_DEVICE_TPM_CFG_OFFSET); - addr_hit[66] = (reg_addr == SPI_DEVICE_TPM_STATUS_OFFSET); - addr_hit[67] = (reg_addr == SPI_DEVICE_TPM_ACCESS_0_OFFSET); - addr_hit[68] = (reg_addr == SPI_DEVICE_TPM_ACCESS_1_OFFSET); - addr_hit[69] = (reg_addr == SPI_DEVICE_TPM_STS_OFFSET); - addr_hit[70] = (reg_addr == SPI_DEVICE_TPM_INTF_CAPABILITY_OFFSET); - addr_hit[71] = (reg_addr == SPI_DEVICE_TPM_INT_ENABLE_OFFSET); - addr_hit[72] = (reg_addr == SPI_DEVICE_TPM_INT_VECTOR_OFFSET); - addr_hit[73] = (reg_addr == SPI_DEVICE_TPM_INT_STATUS_OFFSET); - addr_hit[74] = (reg_addr == SPI_DEVICE_TPM_DID_VID_OFFSET); - addr_hit[75] = (reg_addr == SPI_DEVICE_TPM_RID_OFFSET); - addr_hit[76] = (reg_addr == SPI_DEVICE_TPM_CMD_ADDR_OFFSET); - addr_hit[77] = (reg_addr == SPI_DEVICE_TPM_READ_FIFO_OFFSET); - addr_hit[78] = (reg_addr == SPI_DEVICE_TPM_WRITE_FIFO_OFFSET); + addr_hit[ 6] = (reg_addr == SPI_DEVICE_STATUS_OFFSET); + addr_hit[ 7] = (reg_addr == SPI_DEVICE_INTERCEPT_EN_OFFSET); + addr_hit[ 8] = (reg_addr == SPI_DEVICE_LAST_READ_ADDR_OFFSET); + addr_hit[ 9] = (reg_addr == SPI_DEVICE_FLASH_STATUS_OFFSET); + addr_hit[10] = (reg_addr == SPI_DEVICE_JEDEC_CC_OFFSET); + addr_hit[11] = (reg_addr == SPI_DEVICE_JEDEC_ID_OFFSET); + addr_hit[12] = (reg_addr == SPI_DEVICE_READ_THRESHOLD_OFFSET); + addr_hit[13] = (reg_addr == SPI_DEVICE_MAILBOX_ADDR_OFFSET); + addr_hit[14] = (reg_addr == SPI_DEVICE_UPLOAD_STATUS_OFFSET); + addr_hit[15] = (reg_addr == SPI_DEVICE_UPLOAD_STATUS2_OFFSET); + addr_hit[16] = (reg_addr == SPI_DEVICE_UPLOAD_CMDFIFO_OFFSET); + addr_hit[17] = (reg_addr == SPI_DEVICE_UPLOAD_ADDRFIFO_OFFSET); + addr_hit[18] = (reg_addr == SPI_DEVICE_CMD_FILTER_0_OFFSET); + addr_hit[19] = (reg_addr == SPI_DEVICE_CMD_FILTER_1_OFFSET); + addr_hit[20] = (reg_addr == SPI_DEVICE_CMD_FILTER_2_OFFSET); + addr_hit[21] = (reg_addr == SPI_DEVICE_CMD_FILTER_3_OFFSET); + addr_hit[22] = (reg_addr == SPI_DEVICE_CMD_FILTER_4_OFFSET); + addr_hit[23] = (reg_addr == SPI_DEVICE_CMD_FILTER_5_OFFSET); + addr_hit[24] = (reg_addr == SPI_DEVICE_CMD_FILTER_6_OFFSET); + addr_hit[25] = (reg_addr == SPI_DEVICE_CMD_FILTER_7_OFFSET); + addr_hit[26] = (reg_addr == SPI_DEVICE_ADDR_SWAP_MASK_OFFSET); + addr_hit[27] = (reg_addr == SPI_DEVICE_ADDR_SWAP_DATA_OFFSET); + addr_hit[28] = (reg_addr == SPI_DEVICE_PAYLOAD_SWAP_MASK_OFFSET); + addr_hit[29] = (reg_addr == SPI_DEVICE_PAYLOAD_SWAP_DATA_OFFSET); + addr_hit[30] = (reg_addr == SPI_DEVICE_CMD_INFO_0_OFFSET); + addr_hit[31] = (reg_addr == SPI_DEVICE_CMD_INFO_1_OFFSET); + addr_hit[32] = (reg_addr == SPI_DEVICE_CMD_INFO_2_OFFSET); + addr_hit[33] = (reg_addr == SPI_DEVICE_CMD_INFO_3_OFFSET); + addr_hit[34] = (reg_addr == SPI_DEVICE_CMD_INFO_4_OFFSET); + addr_hit[35] = (reg_addr == SPI_DEVICE_CMD_INFO_5_OFFSET); + addr_hit[36] = (reg_addr == SPI_DEVICE_CMD_INFO_6_OFFSET); + addr_hit[37] = (reg_addr == SPI_DEVICE_CMD_INFO_7_OFFSET); + addr_hit[38] = (reg_addr == SPI_DEVICE_CMD_INFO_8_OFFSET); + addr_hit[39] = (reg_addr == SPI_DEVICE_CMD_INFO_9_OFFSET); + addr_hit[40] = (reg_addr == SPI_DEVICE_CMD_INFO_10_OFFSET); + addr_hit[41] = (reg_addr == SPI_DEVICE_CMD_INFO_11_OFFSET); + addr_hit[42] = (reg_addr == SPI_DEVICE_CMD_INFO_12_OFFSET); + addr_hit[43] = (reg_addr == SPI_DEVICE_CMD_INFO_13_OFFSET); + addr_hit[44] = (reg_addr == SPI_DEVICE_CMD_INFO_14_OFFSET); + addr_hit[45] = (reg_addr == SPI_DEVICE_CMD_INFO_15_OFFSET); + addr_hit[46] = (reg_addr == SPI_DEVICE_CMD_INFO_16_OFFSET); + addr_hit[47] = (reg_addr == SPI_DEVICE_CMD_INFO_17_OFFSET); + addr_hit[48] = (reg_addr == SPI_DEVICE_CMD_INFO_18_OFFSET); + addr_hit[49] = (reg_addr == SPI_DEVICE_CMD_INFO_19_OFFSET); + addr_hit[50] = (reg_addr == SPI_DEVICE_CMD_INFO_20_OFFSET); + addr_hit[51] = (reg_addr == SPI_DEVICE_CMD_INFO_21_OFFSET); + addr_hit[52] = (reg_addr == SPI_DEVICE_CMD_INFO_22_OFFSET); + addr_hit[53] = (reg_addr == SPI_DEVICE_CMD_INFO_23_OFFSET); + addr_hit[54] = (reg_addr == SPI_DEVICE_CMD_INFO_EN4B_OFFSET); + addr_hit[55] = (reg_addr == SPI_DEVICE_CMD_INFO_EX4B_OFFSET); + addr_hit[56] = (reg_addr == SPI_DEVICE_CMD_INFO_WREN_OFFSET); + addr_hit[57] = (reg_addr == SPI_DEVICE_CMD_INFO_WRDI_OFFSET); + addr_hit[58] = (reg_addr == SPI_DEVICE_TPM_CAP_OFFSET); + addr_hit[59] = (reg_addr == SPI_DEVICE_TPM_CFG_OFFSET); + addr_hit[60] = (reg_addr == SPI_DEVICE_TPM_STATUS_OFFSET); + addr_hit[61] = (reg_addr == SPI_DEVICE_TPM_ACCESS_0_OFFSET); + addr_hit[62] = (reg_addr == SPI_DEVICE_TPM_ACCESS_1_OFFSET); + addr_hit[63] = (reg_addr == SPI_DEVICE_TPM_STS_OFFSET); + addr_hit[64] = (reg_addr == SPI_DEVICE_TPM_INTF_CAPABILITY_OFFSET); + addr_hit[65] = (reg_addr == SPI_DEVICE_TPM_INT_ENABLE_OFFSET); + addr_hit[66] = (reg_addr == SPI_DEVICE_TPM_INT_VECTOR_OFFSET); + addr_hit[67] = (reg_addr == SPI_DEVICE_TPM_INT_STATUS_OFFSET); + addr_hit[68] = (reg_addr == SPI_DEVICE_TPM_DID_VID_OFFSET); + addr_hit[69] = (reg_addr == SPI_DEVICE_TPM_RID_OFFSET); + addr_hit[70] = (reg_addr == SPI_DEVICE_TPM_CMD_ADDR_OFFSET); + addr_hit[71] = (reg_addr == SPI_DEVICE_TPM_READ_FIFO_OFFSET); + addr_hit[72] = (reg_addr == SPI_DEVICE_TPM_WRITE_FIFO_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -19723,103 +18703,53 @@ module spi_device_reg_top ( (addr_hit[69] & (|(SPI_DEVICE_PERMIT[69] & ~reg_be))) | (addr_hit[70] & (|(SPI_DEVICE_PERMIT[70] & ~reg_be))) | (addr_hit[71] & (|(SPI_DEVICE_PERMIT[71] & ~reg_be))) | - (addr_hit[72] & (|(SPI_DEVICE_PERMIT[72] & ~reg_be))) | - (addr_hit[73] & (|(SPI_DEVICE_PERMIT[73] & ~reg_be))) | - (addr_hit[74] & (|(SPI_DEVICE_PERMIT[74] & ~reg_be))) | - (addr_hit[75] & (|(SPI_DEVICE_PERMIT[75] & ~reg_be))) | - (addr_hit[76] & (|(SPI_DEVICE_PERMIT[76] & ~reg_be))) | - (addr_hit[77] & (|(SPI_DEVICE_PERMIT[77] & ~reg_be))) | - (addr_hit[78] & (|(SPI_DEVICE_PERMIT[78] & ~reg_be))))); + (addr_hit[72] & (|(SPI_DEVICE_PERMIT[72] & ~reg_be))))); end // Generate write-enables assign intr_state_we = addr_hit[0] & reg_we & !reg_error; - assign intr_state_generic_rx_full_wd = reg_wdata[0]; - - assign intr_state_generic_rx_watermark_wd = reg_wdata[1]; - - assign intr_state_generic_tx_watermark_wd = reg_wdata[2]; - - assign intr_state_generic_rx_error_wd = reg_wdata[3]; + assign intr_state_upload_cmdfifo_not_empty_wd = reg_wdata[0]; - assign intr_state_generic_rx_overflow_wd = reg_wdata[4]; + assign intr_state_upload_payload_not_empty_wd = reg_wdata[1]; - assign intr_state_generic_tx_underflow_wd = reg_wdata[5]; + assign intr_state_upload_payload_overflow_wd = reg_wdata[2]; - assign intr_state_upload_cmdfifo_not_empty_wd = reg_wdata[6]; + assign intr_state_readbuf_watermark_wd = reg_wdata[3]; - assign intr_state_upload_payload_not_empty_wd = reg_wdata[7]; - - assign intr_state_upload_payload_overflow_wd = reg_wdata[8]; - - assign intr_state_readbuf_watermark_wd = reg_wdata[9]; - - assign intr_state_readbuf_flip_wd = reg_wdata[10]; + assign intr_state_readbuf_flip_wd = reg_wdata[4]; assign intr_enable_we = addr_hit[1] & reg_we & !reg_error; - assign intr_enable_generic_rx_full_wd = reg_wdata[0]; - - assign intr_enable_generic_rx_watermark_wd = reg_wdata[1]; + assign intr_enable_upload_cmdfifo_not_empty_wd = reg_wdata[0]; - assign intr_enable_generic_tx_watermark_wd = reg_wdata[2]; + assign intr_enable_upload_payload_not_empty_wd = reg_wdata[1]; - assign intr_enable_generic_rx_error_wd = reg_wdata[3]; + assign intr_enable_upload_payload_overflow_wd = reg_wdata[2]; - assign intr_enable_generic_rx_overflow_wd = reg_wdata[4]; + assign intr_enable_readbuf_watermark_wd = reg_wdata[3]; - assign intr_enable_generic_tx_underflow_wd = reg_wdata[5]; + assign intr_enable_readbuf_flip_wd = reg_wdata[4]; - assign intr_enable_upload_cmdfifo_not_empty_wd = reg_wdata[6]; - - assign intr_enable_upload_payload_not_empty_wd = reg_wdata[7]; - - assign intr_enable_upload_payload_overflow_wd = reg_wdata[8]; - - assign intr_enable_readbuf_watermark_wd = reg_wdata[9]; - - assign intr_enable_readbuf_flip_wd = reg_wdata[10]; - - assign intr_enable_tpm_header_not_empty_wd = reg_wdata[11]; + assign intr_enable_tpm_header_not_empty_wd = reg_wdata[5]; assign intr_test_we = addr_hit[2] & reg_we & !reg_error; - assign intr_test_generic_rx_full_wd = reg_wdata[0]; - - assign intr_test_generic_rx_watermark_wd = reg_wdata[1]; - - assign intr_test_generic_tx_watermark_wd = reg_wdata[2]; - - assign intr_test_generic_rx_error_wd = reg_wdata[3]; + assign intr_test_upload_cmdfifo_not_empty_wd = reg_wdata[0]; - assign intr_test_generic_rx_overflow_wd = reg_wdata[4]; + assign intr_test_upload_payload_not_empty_wd = reg_wdata[1]; - assign intr_test_generic_tx_underflow_wd = reg_wdata[5]; + assign intr_test_upload_payload_overflow_wd = reg_wdata[2]; - assign intr_test_upload_cmdfifo_not_empty_wd = reg_wdata[6]; + assign intr_test_readbuf_watermark_wd = reg_wdata[3]; - assign intr_test_upload_payload_not_empty_wd = reg_wdata[7]; + assign intr_test_readbuf_flip_wd = reg_wdata[4]; - assign intr_test_upload_payload_overflow_wd = reg_wdata[8]; - - assign intr_test_readbuf_watermark_wd = reg_wdata[9]; - - assign intr_test_readbuf_flip_wd = reg_wdata[10]; - - assign intr_test_tpm_header_not_empty_wd = reg_wdata[11]; + assign intr_test_tpm_header_not_empty_wd = reg_wdata[5]; assign alert_test_we = addr_hit[3] & reg_we & !reg_error; assign alert_test_wd = reg_wdata[0]; assign control_we = addr_hit[4] & reg_we & !reg_error; - assign control_abort_wd = reg_wdata[0]; - - assign control_mode_wd = reg_wdata[5:4]; - - assign control_rst_txfifo_wd = reg_wdata[16]; - - assign control_rst_rxfifo_wd = reg_wdata[17]; - - assign control_sram_clk_en_wd = reg_wdata[31]; + assign control_wd = reg_wdata[5:4]; assign cfg_we = addr_hit[5] & reg_we & !reg_error; assign cfg_cpol_wd = reg_wdata[0]; @@ -19830,35 +18760,11 @@ module spi_device_reg_top ( assign cfg_rx_order_wd = reg_wdata[3]; - assign cfg_timer_v_wd = reg_wdata[15:8]; - assign cfg_addr_4b_en_wd = reg_wdata[16]; assign cfg_mailbox_en_wd = reg_wdata[24]; - assign fifo_level_we = addr_hit[6] & reg_we & !reg_error; - - assign fifo_level_rxlvl_wd = reg_wdata[15:0]; - - assign fifo_level_txlvl_wd = reg_wdata[31:16]; - assign async_fifo_level_re = addr_hit[7] & reg_re & !reg_error; - assign status_re = addr_hit[8] & reg_re & !reg_error; - assign rxf_ptr_we = addr_hit[9] & reg_we & !reg_error; - - assign rxf_ptr_rptr_wd = reg_wdata[15:0]; - assign txf_ptr_we = addr_hit[10] & reg_we & !reg_error; - - assign txf_ptr_wptr_wd = reg_wdata[31:16]; - assign rxf_addr_we = addr_hit[11] & reg_we & !reg_error; - - assign rxf_addr_base_wd = reg_wdata[15:0]; - - assign rxf_addr_limit_wd = reg_wdata[31:16]; - assign txf_addr_we = addr_hit[12] & reg_we & !reg_error; - - assign txf_addr_base_wd = reg_wdata[15:0]; - - assign txf_addr_limit_wd = reg_wdata[31:16]; - assign intercept_en_we = addr_hit[13] & reg_we & !reg_error; + assign status_re = addr_hit[6] & reg_re & !reg_error; + assign intercept_en_we = addr_hit[7] & reg_we & !reg_error; assign intercept_en_status_wd = reg_wdata[0]; @@ -19867,32 +18773,32 @@ module spi_device_reg_top ( assign intercept_en_sfdp_wd = reg_wdata[2]; assign intercept_en_mbx_wd = reg_wdata[3]; - assign last_read_addr_re = addr_hit[14] & reg_re & !reg_error; - assign flash_status_re = addr_hit[15] & reg_re & !reg_error; - assign flash_status_we = addr_hit[15] & reg_we & !reg_error; + assign last_read_addr_re = addr_hit[8] & reg_re & !reg_error; + assign flash_status_re = addr_hit[9] & reg_re & !reg_error; + assign flash_status_we = addr_hit[9] & reg_we & !reg_error; assign flash_status_busy_wd = reg_wdata[0]; assign flash_status_status_wd = reg_wdata[23:1]; - assign jedec_cc_we = addr_hit[16] & reg_we & !reg_error; + assign jedec_cc_we = addr_hit[10] & reg_we & !reg_error; assign jedec_cc_cc_wd = reg_wdata[7:0]; assign jedec_cc_num_cc_wd = reg_wdata[15:8]; - assign jedec_id_we = addr_hit[17] & reg_we & !reg_error; + assign jedec_id_we = addr_hit[11] & reg_we & !reg_error; assign jedec_id_id_wd = reg_wdata[15:0]; assign jedec_id_mf_wd = reg_wdata[23:16]; - assign read_threshold_we = addr_hit[18] & reg_we & !reg_error; + assign read_threshold_we = addr_hit[12] & reg_we & !reg_error; assign read_threshold_wd = reg_wdata[9:0]; - assign mailbox_addr_we = addr_hit[19] & reg_we & !reg_error; + assign mailbox_addr_we = addr_hit[13] & reg_we & !reg_error; assign mailbox_addr_wd = reg_wdata[31:0]; - assign upload_cmdfifo_re = addr_hit[22] & reg_re & !reg_error; - assign upload_addrfifo_re = addr_hit[23] & reg_re & !reg_error; - assign cmd_filter_0_we = addr_hit[24] & reg_we & !reg_error; + assign upload_cmdfifo_re = addr_hit[16] & reg_re & !reg_error; + assign upload_addrfifo_re = addr_hit[17] & reg_re & !reg_error; + assign cmd_filter_0_we = addr_hit[18] & reg_we & !reg_error; assign cmd_filter_0_filter_0_wd = reg_wdata[0]; @@ -19957,7 +18863,7 @@ module spi_device_reg_top ( assign cmd_filter_0_filter_30_wd = reg_wdata[30]; assign cmd_filter_0_filter_31_wd = reg_wdata[31]; - assign cmd_filter_1_we = addr_hit[25] & reg_we & !reg_error; + assign cmd_filter_1_we = addr_hit[19] & reg_we & !reg_error; assign cmd_filter_1_filter_32_wd = reg_wdata[0]; @@ -20022,7 +18928,7 @@ module spi_device_reg_top ( assign cmd_filter_1_filter_62_wd = reg_wdata[30]; assign cmd_filter_1_filter_63_wd = reg_wdata[31]; - assign cmd_filter_2_we = addr_hit[26] & reg_we & !reg_error; + assign cmd_filter_2_we = addr_hit[20] & reg_we & !reg_error; assign cmd_filter_2_filter_64_wd = reg_wdata[0]; @@ -20087,7 +18993,7 @@ module spi_device_reg_top ( assign cmd_filter_2_filter_94_wd = reg_wdata[30]; assign cmd_filter_2_filter_95_wd = reg_wdata[31]; - assign cmd_filter_3_we = addr_hit[27] & reg_we & !reg_error; + assign cmd_filter_3_we = addr_hit[21] & reg_we & !reg_error; assign cmd_filter_3_filter_96_wd = reg_wdata[0]; @@ -20152,7 +19058,7 @@ module spi_device_reg_top ( assign cmd_filter_3_filter_126_wd = reg_wdata[30]; assign cmd_filter_3_filter_127_wd = reg_wdata[31]; - assign cmd_filter_4_we = addr_hit[28] & reg_we & !reg_error; + assign cmd_filter_4_we = addr_hit[22] & reg_we & !reg_error; assign cmd_filter_4_filter_128_wd = reg_wdata[0]; @@ -20217,7 +19123,7 @@ module spi_device_reg_top ( assign cmd_filter_4_filter_158_wd = reg_wdata[30]; assign cmd_filter_4_filter_159_wd = reg_wdata[31]; - assign cmd_filter_5_we = addr_hit[29] & reg_we & !reg_error; + assign cmd_filter_5_we = addr_hit[23] & reg_we & !reg_error; assign cmd_filter_5_filter_160_wd = reg_wdata[0]; @@ -20282,7 +19188,7 @@ module spi_device_reg_top ( assign cmd_filter_5_filter_190_wd = reg_wdata[30]; assign cmd_filter_5_filter_191_wd = reg_wdata[31]; - assign cmd_filter_6_we = addr_hit[30] & reg_we & !reg_error; + assign cmd_filter_6_we = addr_hit[24] & reg_we & !reg_error; assign cmd_filter_6_filter_192_wd = reg_wdata[0]; @@ -20347,7 +19253,7 @@ module spi_device_reg_top ( assign cmd_filter_6_filter_222_wd = reg_wdata[30]; assign cmd_filter_6_filter_223_wd = reg_wdata[31]; - assign cmd_filter_7_we = addr_hit[31] & reg_we & !reg_error; + assign cmd_filter_7_we = addr_hit[25] & reg_we & !reg_error; assign cmd_filter_7_filter_224_wd = reg_wdata[0]; @@ -20412,19 +19318,19 @@ module spi_device_reg_top ( assign cmd_filter_7_filter_254_wd = reg_wdata[30]; assign cmd_filter_7_filter_255_wd = reg_wdata[31]; - assign addr_swap_mask_we = addr_hit[32] & reg_we & !reg_error; + assign addr_swap_mask_we = addr_hit[26] & reg_we & !reg_error; assign addr_swap_mask_wd = reg_wdata[31:0]; - assign addr_swap_data_we = addr_hit[33] & reg_we & !reg_error; + assign addr_swap_data_we = addr_hit[27] & reg_we & !reg_error; assign addr_swap_data_wd = reg_wdata[31:0]; - assign payload_swap_mask_we = addr_hit[34] & reg_we & !reg_error; + assign payload_swap_mask_we = addr_hit[28] & reg_we & !reg_error; assign payload_swap_mask_wd = reg_wdata[31:0]; - assign payload_swap_data_we = addr_hit[35] & reg_we & !reg_error; + assign payload_swap_data_we = addr_hit[29] & reg_we & !reg_error; assign payload_swap_data_wd = reg_wdata[31:0]; - assign cmd_info_0_we = addr_hit[36] & reg_we & !reg_error; + assign cmd_info_0_we = addr_hit[30] & reg_we & !reg_error; assign cmd_info_0_opcode_0_wd = reg_wdata[7:0]; @@ -20449,7 +19355,7 @@ module spi_device_reg_top ( assign cmd_info_0_busy_0_wd = reg_wdata[25]; assign cmd_info_0_valid_0_wd = reg_wdata[31]; - assign cmd_info_1_we = addr_hit[37] & reg_we & !reg_error; + assign cmd_info_1_we = addr_hit[31] & reg_we & !reg_error; assign cmd_info_1_opcode_1_wd = reg_wdata[7:0]; @@ -20474,7 +19380,7 @@ module spi_device_reg_top ( assign cmd_info_1_busy_1_wd = reg_wdata[25]; assign cmd_info_1_valid_1_wd = reg_wdata[31]; - assign cmd_info_2_we = addr_hit[38] & reg_we & !reg_error; + assign cmd_info_2_we = addr_hit[32] & reg_we & !reg_error; assign cmd_info_2_opcode_2_wd = reg_wdata[7:0]; @@ -20499,7 +19405,7 @@ module spi_device_reg_top ( assign cmd_info_2_busy_2_wd = reg_wdata[25]; assign cmd_info_2_valid_2_wd = reg_wdata[31]; - assign cmd_info_3_we = addr_hit[39] & reg_we & !reg_error; + assign cmd_info_3_we = addr_hit[33] & reg_we & !reg_error; assign cmd_info_3_opcode_3_wd = reg_wdata[7:0]; @@ -20524,7 +19430,7 @@ module spi_device_reg_top ( assign cmd_info_3_busy_3_wd = reg_wdata[25]; assign cmd_info_3_valid_3_wd = reg_wdata[31]; - assign cmd_info_4_we = addr_hit[40] & reg_we & !reg_error; + assign cmd_info_4_we = addr_hit[34] & reg_we & !reg_error; assign cmd_info_4_opcode_4_wd = reg_wdata[7:0]; @@ -20549,7 +19455,7 @@ module spi_device_reg_top ( assign cmd_info_4_busy_4_wd = reg_wdata[25]; assign cmd_info_4_valid_4_wd = reg_wdata[31]; - assign cmd_info_5_we = addr_hit[41] & reg_we & !reg_error; + assign cmd_info_5_we = addr_hit[35] & reg_we & !reg_error; assign cmd_info_5_opcode_5_wd = reg_wdata[7:0]; @@ -20574,7 +19480,7 @@ module spi_device_reg_top ( assign cmd_info_5_busy_5_wd = reg_wdata[25]; assign cmd_info_5_valid_5_wd = reg_wdata[31]; - assign cmd_info_6_we = addr_hit[42] & reg_we & !reg_error; + assign cmd_info_6_we = addr_hit[36] & reg_we & !reg_error; assign cmd_info_6_opcode_6_wd = reg_wdata[7:0]; @@ -20599,7 +19505,7 @@ module spi_device_reg_top ( assign cmd_info_6_busy_6_wd = reg_wdata[25]; assign cmd_info_6_valid_6_wd = reg_wdata[31]; - assign cmd_info_7_we = addr_hit[43] & reg_we & !reg_error; + assign cmd_info_7_we = addr_hit[37] & reg_we & !reg_error; assign cmd_info_7_opcode_7_wd = reg_wdata[7:0]; @@ -20624,7 +19530,7 @@ module spi_device_reg_top ( assign cmd_info_7_busy_7_wd = reg_wdata[25]; assign cmd_info_7_valid_7_wd = reg_wdata[31]; - assign cmd_info_8_we = addr_hit[44] & reg_we & !reg_error; + assign cmd_info_8_we = addr_hit[38] & reg_we & !reg_error; assign cmd_info_8_opcode_8_wd = reg_wdata[7:0]; @@ -20649,7 +19555,7 @@ module spi_device_reg_top ( assign cmd_info_8_busy_8_wd = reg_wdata[25]; assign cmd_info_8_valid_8_wd = reg_wdata[31]; - assign cmd_info_9_we = addr_hit[45] & reg_we & !reg_error; + assign cmd_info_9_we = addr_hit[39] & reg_we & !reg_error; assign cmd_info_9_opcode_9_wd = reg_wdata[7:0]; @@ -20674,7 +19580,7 @@ module spi_device_reg_top ( assign cmd_info_9_busy_9_wd = reg_wdata[25]; assign cmd_info_9_valid_9_wd = reg_wdata[31]; - assign cmd_info_10_we = addr_hit[46] & reg_we & !reg_error; + assign cmd_info_10_we = addr_hit[40] & reg_we & !reg_error; assign cmd_info_10_opcode_10_wd = reg_wdata[7:0]; @@ -20699,7 +19605,7 @@ module spi_device_reg_top ( assign cmd_info_10_busy_10_wd = reg_wdata[25]; assign cmd_info_10_valid_10_wd = reg_wdata[31]; - assign cmd_info_11_we = addr_hit[47] & reg_we & !reg_error; + assign cmd_info_11_we = addr_hit[41] & reg_we & !reg_error; assign cmd_info_11_opcode_11_wd = reg_wdata[7:0]; @@ -20724,7 +19630,7 @@ module spi_device_reg_top ( assign cmd_info_11_busy_11_wd = reg_wdata[25]; assign cmd_info_11_valid_11_wd = reg_wdata[31]; - assign cmd_info_12_we = addr_hit[48] & reg_we & !reg_error; + assign cmd_info_12_we = addr_hit[42] & reg_we & !reg_error; assign cmd_info_12_opcode_12_wd = reg_wdata[7:0]; @@ -20749,7 +19655,7 @@ module spi_device_reg_top ( assign cmd_info_12_busy_12_wd = reg_wdata[25]; assign cmd_info_12_valid_12_wd = reg_wdata[31]; - assign cmd_info_13_we = addr_hit[49] & reg_we & !reg_error; + assign cmd_info_13_we = addr_hit[43] & reg_we & !reg_error; assign cmd_info_13_opcode_13_wd = reg_wdata[7:0]; @@ -20774,7 +19680,7 @@ module spi_device_reg_top ( assign cmd_info_13_busy_13_wd = reg_wdata[25]; assign cmd_info_13_valid_13_wd = reg_wdata[31]; - assign cmd_info_14_we = addr_hit[50] & reg_we & !reg_error; + assign cmd_info_14_we = addr_hit[44] & reg_we & !reg_error; assign cmd_info_14_opcode_14_wd = reg_wdata[7:0]; @@ -20799,7 +19705,7 @@ module spi_device_reg_top ( assign cmd_info_14_busy_14_wd = reg_wdata[25]; assign cmd_info_14_valid_14_wd = reg_wdata[31]; - assign cmd_info_15_we = addr_hit[51] & reg_we & !reg_error; + assign cmd_info_15_we = addr_hit[45] & reg_we & !reg_error; assign cmd_info_15_opcode_15_wd = reg_wdata[7:0]; @@ -20824,7 +19730,7 @@ module spi_device_reg_top ( assign cmd_info_15_busy_15_wd = reg_wdata[25]; assign cmd_info_15_valid_15_wd = reg_wdata[31]; - assign cmd_info_16_we = addr_hit[52] & reg_we & !reg_error; + assign cmd_info_16_we = addr_hit[46] & reg_we & !reg_error; assign cmd_info_16_opcode_16_wd = reg_wdata[7:0]; @@ -20849,7 +19755,7 @@ module spi_device_reg_top ( assign cmd_info_16_busy_16_wd = reg_wdata[25]; assign cmd_info_16_valid_16_wd = reg_wdata[31]; - assign cmd_info_17_we = addr_hit[53] & reg_we & !reg_error; + assign cmd_info_17_we = addr_hit[47] & reg_we & !reg_error; assign cmd_info_17_opcode_17_wd = reg_wdata[7:0]; @@ -20874,7 +19780,7 @@ module spi_device_reg_top ( assign cmd_info_17_busy_17_wd = reg_wdata[25]; assign cmd_info_17_valid_17_wd = reg_wdata[31]; - assign cmd_info_18_we = addr_hit[54] & reg_we & !reg_error; + assign cmd_info_18_we = addr_hit[48] & reg_we & !reg_error; assign cmd_info_18_opcode_18_wd = reg_wdata[7:0]; @@ -20899,7 +19805,7 @@ module spi_device_reg_top ( assign cmd_info_18_busy_18_wd = reg_wdata[25]; assign cmd_info_18_valid_18_wd = reg_wdata[31]; - assign cmd_info_19_we = addr_hit[55] & reg_we & !reg_error; + assign cmd_info_19_we = addr_hit[49] & reg_we & !reg_error; assign cmd_info_19_opcode_19_wd = reg_wdata[7:0]; @@ -20924,7 +19830,7 @@ module spi_device_reg_top ( assign cmd_info_19_busy_19_wd = reg_wdata[25]; assign cmd_info_19_valid_19_wd = reg_wdata[31]; - assign cmd_info_20_we = addr_hit[56] & reg_we & !reg_error; + assign cmd_info_20_we = addr_hit[50] & reg_we & !reg_error; assign cmd_info_20_opcode_20_wd = reg_wdata[7:0]; @@ -20949,7 +19855,7 @@ module spi_device_reg_top ( assign cmd_info_20_busy_20_wd = reg_wdata[25]; assign cmd_info_20_valid_20_wd = reg_wdata[31]; - assign cmd_info_21_we = addr_hit[57] & reg_we & !reg_error; + assign cmd_info_21_we = addr_hit[51] & reg_we & !reg_error; assign cmd_info_21_opcode_21_wd = reg_wdata[7:0]; @@ -20974,7 +19880,7 @@ module spi_device_reg_top ( assign cmd_info_21_busy_21_wd = reg_wdata[25]; assign cmd_info_21_valid_21_wd = reg_wdata[31]; - assign cmd_info_22_we = addr_hit[58] & reg_we & !reg_error; + assign cmd_info_22_we = addr_hit[52] & reg_we & !reg_error; assign cmd_info_22_opcode_22_wd = reg_wdata[7:0]; @@ -20999,7 +19905,7 @@ module spi_device_reg_top ( assign cmd_info_22_busy_22_wd = reg_wdata[25]; assign cmd_info_22_valid_22_wd = reg_wdata[31]; - assign cmd_info_23_we = addr_hit[59] & reg_we & !reg_error; + assign cmd_info_23_we = addr_hit[53] & reg_we & !reg_error; assign cmd_info_23_opcode_23_wd = reg_wdata[7:0]; @@ -21024,27 +19930,27 @@ module spi_device_reg_top ( assign cmd_info_23_busy_23_wd = reg_wdata[25]; assign cmd_info_23_valid_23_wd = reg_wdata[31]; - assign cmd_info_en4b_we = addr_hit[60] & reg_we & !reg_error; + assign cmd_info_en4b_we = addr_hit[54] & reg_we & !reg_error; assign cmd_info_en4b_opcode_wd = reg_wdata[7:0]; assign cmd_info_en4b_valid_wd = reg_wdata[31]; - assign cmd_info_ex4b_we = addr_hit[61] & reg_we & !reg_error; + assign cmd_info_ex4b_we = addr_hit[55] & reg_we & !reg_error; assign cmd_info_ex4b_opcode_wd = reg_wdata[7:0]; assign cmd_info_ex4b_valid_wd = reg_wdata[31]; - assign cmd_info_wren_we = addr_hit[62] & reg_we & !reg_error; + assign cmd_info_wren_we = addr_hit[56] & reg_we & !reg_error; assign cmd_info_wren_opcode_wd = reg_wdata[7:0]; assign cmd_info_wren_valid_wd = reg_wdata[31]; - assign cmd_info_wrdi_we = addr_hit[63] & reg_we & !reg_error; + assign cmd_info_wrdi_we = addr_hit[57] & reg_we & !reg_error; assign cmd_info_wrdi_opcode_wd = reg_wdata[7:0]; assign cmd_info_wrdi_valid_wd = reg_wdata[31]; - assign tpm_cfg_we = addr_hit[65] & reg_we & !reg_error; + assign tpm_cfg_we = addr_hit[59] & reg_we & !reg_error; assign tpm_cfg_en_wd = reg_wdata[0]; @@ -21055,7 +19961,7 @@ module spi_device_reg_top ( assign tpm_cfg_tpm_reg_chk_dis_wd = reg_wdata[3]; assign tpm_cfg_invalid_locality_wd = reg_wdata[4]; - assign tpm_access_0_we = addr_hit[67] & reg_we & !reg_error; + assign tpm_access_0_we = addr_hit[61] & reg_we & !reg_error; assign tpm_access_0_access_0_wd = reg_wdata[7:0]; @@ -21064,37 +19970,37 @@ module spi_device_reg_top ( assign tpm_access_0_access_2_wd = reg_wdata[23:16]; assign tpm_access_0_access_3_wd = reg_wdata[31:24]; - assign tpm_access_1_we = addr_hit[68] & reg_we & !reg_error; + assign tpm_access_1_we = addr_hit[62] & reg_we & !reg_error; assign tpm_access_1_wd = reg_wdata[7:0]; - assign tpm_sts_we = addr_hit[69] & reg_we & !reg_error; + assign tpm_sts_we = addr_hit[63] & reg_we & !reg_error; assign tpm_sts_wd = reg_wdata[31:0]; - assign tpm_intf_capability_we = addr_hit[70] & reg_we & !reg_error; + assign tpm_intf_capability_we = addr_hit[64] & reg_we & !reg_error; assign tpm_intf_capability_wd = reg_wdata[31:0]; - assign tpm_int_enable_we = addr_hit[71] & reg_we & !reg_error; + assign tpm_int_enable_we = addr_hit[65] & reg_we & !reg_error; assign tpm_int_enable_wd = reg_wdata[31:0]; - assign tpm_int_vector_we = addr_hit[72] & reg_we & !reg_error; + assign tpm_int_vector_we = addr_hit[66] & reg_we & !reg_error; assign tpm_int_vector_wd = reg_wdata[7:0]; - assign tpm_int_status_we = addr_hit[73] & reg_we & !reg_error; + assign tpm_int_status_we = addr_hit[67] & reg_we & !reg_error; assign tpm_int_status_wd = reg_wdata[31:0]; - assign tpm_did_vid_we = addr_hit[74] & reg_we & !reg_error; + assign tpm_did_vid_we = addr_hit[68] & reg_we & !reg_error; assign tpm_did_vid_vid_wd = reg_wdata[15:0]; assign tpm_did_vid_did_wd = reg_wdata[31:16]; - assign tpm_rid_we = addr_hit[75] & reg_we & !reg_error; + assign tpm_rid_we = addr_hit[69] & reg_we & !reg_error; assign tpm_rid_wd = reg_wdata[7:0]; - assign tpm_cmd_addr_re = addr_hit[76] & reg_re & !reg_error; - assign tpm_read_fifo_we = addr_hit[77] & reg_we & !reg_error; + assign tpm_cmd_addr_re = addr_hit[70] & reg_re & !reg_error; + assign tpm_read_fifo_we = addr_hit[71] & reg_we & !reg_error; assign tpm_read_fifo_wd = reg_wdata[31:0]; - assign tpm_write_fifo_re = addr_hit[78] & reg_re & !reg_error; + assign tpm_write_fifo_re = addr_hit[72] & reg_re & !reg_error; // Assign write-enables to checker logic vector. always_comb begin @@ -21105,79 +20011,73 @@ module spi_device_reg_top ( reg_we_check[3] = alert_test_we; reg_we_check[4] = control_we; reg_we_check[5] = cfg_we; - reg_we_check[6] = fifo_level_we; - reg_we_check[7] = 1'b0; + reg_we_check[6] = 1'b0; + reg_we_check[7] = intercept_en_we; reg_we_check[8] = 1'b0; - reg_we_check[9] = rxf_ptr_we; - reg_we_check[10] = txf_ptr_we; - reg_we_check[11] = rxf_addr_we; - reg_we_check[12] = txf_addr_we; - reg_we_check[13] = intercept_en_we; + reg_we_check[9] = flash_status_we; + reg_we_check[10] = jedec_cc_we; + reg_we_check[11] = jedec_id_we; + reg_we_check[12] = read_threshold_we; + reg_we_check[13] = mailbox_addr_we; reg_we_check[14] = 1'b0; - reg_we_check[15] = flash_status_we; - reg_we_check[16] = jedec_cc_we; - reg_we_check[17] = jedec_id_we; - reg_we_check[18] = read_threshold_we; - reg_we_check[19] = mailbox_addr_we; - reg_we_check[20] = 1'b0; - reg_we_check[21] = 1'b0; - reg_we_check[22] = 1'b0; - reg_we_check[23] = 1'b0; - reg_we_check[24] = cmd_filter_0_we; - reg_we_check[25] = cmd_filter_1_we; - reg_we_check[26] = cmd_filter_2_we; - reg_we_check[27] = cmd_filter_3_we; - reg_we_check[28] = cmd_filter_4_we; - reg_we_check[29] = cmd_filter_5_we; - reg_we_check[30] = cmd_filter_6_we; - reg_we_check[31] = cmd_filter_7_we; - reg_we_check[32] = addr_swap_mask_we; - reg_we_check[33] = addr_swap_data_we; - reg_we_check[34] = payload_swap_mask_we; - reg_we_check[35] = payload_swap_data_we; - reg_we_check[36] = cmd_info_0_we; - reg_we_check[37] = cmd_info_1_we; - reg_we_check[38] = cmd_info_2_we; - reg_we_check[39] = cmd_info_3_we; - reg_we_check[40] = cmd_info_4_we; - reg_we_check[41] = cmd_info_5_we; - reg_we_check[42] = cmd_info_6_we; - reg_we_check[43] = cmd_info_7_we; - reg_we_check[44] = cmd_info_8_we; - reg_we_check[45] = cmd_info_9_we; - reg_we_check[46] = cmd_info_10_we; - reg_we_check[47] = cmd_info_11_we; - reg_we_check[48] = cmd_info_12_we; - reg_we_check[49] = cmd_info_13_we; - reg_we_check[50] = cmd_info_14_we; - reg_we_check[51] = cmd_info_15_we; - reg_we_check[52] = cmd_info_16_we; - reg_we_check[53] = cmd_info_17_we; - reg_we_check[54] = cmd_info_18_we; - reg_we_check[55] = cmd_info_19_we; - reg_we_check[56] = cmd_info_20_we; - reg_we_check[57] = cmd_info_21_we; - reg_we_check[58] = cmd_info_22_we; - reg_we_check[59] = cmd_info_23_we; - reg_we_check[60] = cmd_info_en4b_we; - reg_we_check[61] = cmd_info_ex4b_we; - reg_we_check[62] = cmd_info_wren_we; - reg_we_check[63] = cmd_info_wrdi_we; - reg_we_check[64] = 1'b0; - reg_we_check[65] = tpm_cfg_we; - reg_we_check[66] = 1'b0; - reg_we_check[67] = tpm_access_0_we; - reg_we_check[68] = tpm_access_1_we; - reg_we_check[69] = tpm_sts_we; - reg_we_check[70] = tpm_intf_capability_we; - reg_we_check[71] = tpm_int_enable_we; - reg_we_check[72] = tpm_int_vector_we; - reg_we_check[73] = tpm_int_status_we; - reg_we_check[74] = tpm_did_vid_we; - reg_we_check[75] = tpm_rid_we; - reg_we_check[76] = 1'b0; - reg_we_check[77] = tpm_read_fifo_we; - reg_we_check[78] = 1'b0; + reg_we_check[15] = 1'b0; + reg_we_check[16] = 1'b0; + reg_we_check[17] = 1'b0; + reg_we_check[18] = cmd_filter_0_we; + reg_we_check[19] = cmd_filter_1_we; + reg_we_check[20] = cmd_filter_2_we; + reg_we_check[21] = cmd_filter_3_we; + reg_we_check[22] = cmd_filter_4_we; + reg_we_check[23] = cmd_filter_5_we; + reg_we_check[24] = cmd_filter_6_we; + reg_we_check[25] = cmd_filter_7_we; + reg_we_check[26] = addr_swap_mask_we; + reg_we_check[27] = addr_swap_data_we; + reg_we_check[28] = payload_swap_mask_we; + reg_we_check[29] = payload_swap_data_we; + reg_we_check[30] = cmd_info_0_we; + reg_we_check[31] = cmd_info_1_we; + reg_we_check[32] = cmd_info_2_we; + reg_we_check[33] = cmd_info_3_we; + reg_we_check[34] = cmd_info_4_we; + reg_we_check[35] = cmd_info_5_we; + reg_we_check[36] = cmd_info_6_we; + reg_we_check[37] = cmd_info_7_we; + reg_we_check[38] = cmd_info_8_we; + reg_we_check[39] = cmd_info_9_we; + reg_we_check[40] = cmd_info_10_we; + reg_we_check[41] = cmd_info_11_we; + reg_we_check[42] = cmd_info_12_we; + reg_we_check[43] = cmd_info_13_we; + reg_we_check[44] = cmd_info_14_we; + reg_we_check[45] = cmd_info_15_we; + reg_we_check[46] = cmd_info_16_we; + reg_we_check[47] = cmd_info_17_we; + reg_we_check[48] = cmd_info_18_we; + reg_we_check[49] = cmd_info_19_we; + reg_we_check[50] = cmd_info_20_we; + reg_we_check[51] = cmd_info_21_we; + reg_we_check[52] = cmd_info_22_we; + reg_we_check[53] = cmd_info_23_we; + reg_we_check[54] = cmd_info_en4b_we; + reg_we_check[55] = cmd_info_ex4b_we; + reg_we_check[56] = cmd_info_wren_we; + reg_we_check[57] = cmd_info_wrdi_we; + reg_we_check[58] = 1'b0; + reg_we_check[59] = tpm_cfg_we; + reg_we_check[60] = 1'b0; + reg_we_check[61] = tpm_access_0_we; + reg_we_check[62] = tpm_access_1_we; + reg_we_check[63] = tpm_sts_we; + reg_we_check[64] = tpm_intf_capability_we; + reg_we_check[65] = tpm_int_enable_we; + reg_we_check[66] = tpm_int_vector_we; + reg_we_check[67] = tpm_int_status_we; + reg_we_check[68] = tpm_did_vid_we; + reg_we_check[69] = tpm_rid_we; + reg_we_check[70] = 1'b0; + reg_we_check[71] = tpm_read_fifo_we; + reg_we_check[72] = 1'b0; end // Read data return @@ -21185,33 +20085,21 @@ module spi_device_reg_top ( reg_rdata_next = '0; unique case (1'b1) addr_hit[0]: begin - reg_rdata_next[0] = intr_state_generic_rx_full_qs; - reg_rdata_next[1] = intr_state_generic_rx_watermark_qs; - reg_rdata_next[2] = intr_state_generic_tx_watermark_qs; - reg_rdata_next[3] = intr_state_generic_rx_error_qs; - reg_rdata_next[4] = intr_state_generic_rx_overflow_qs; - reg_rdata_next[5] = intr_state_generic_tx_underflow_qs; - reg_rdata_next[6] = intr_state_upload_cmdfifo_not_empty_qs; - reg_rdata_next[7] = intr_state_upload_payload_not_empty_qs; - reg_rdata_next[8] = intr_state_upload_payload_overflow_qs; - reg_rdata_next[9] = intr_state_readbuf_watermark_qs; - reg_rdata_next[10] = intr_state_readbuf_flip_qs; - reg_rdata_next[11] = intr_state_tpm_header_not_empty_qs; + reg_rdata_next[0] = intr_state_upload_cmdfifo_not_empty_qs; + reg_rdata_next[1] = intr_state_upload_payload_not_empty_qs; + reg_rdata_next[2] = intr_state_upload_payload_overflow_qs; + reg_rdata_next[3] = intr_state_readbuf_watermark_qs; + reg_rdata_next[4] = intr_state_readbuf_flip_qs; + reg_rdata_next[5] = intr_state_tpm_header_not_empty_qs; end addr_hit[1]: begin - reg_rdata_next[0] = intr_enable_generic_rx_full_qs; - reg_rdata_next[1] = intr_enable_generic_rx_watermark_qs; - reg_rdata_next[2] = intr_enable_generic_tx_watermark_qs; - reg_rdata_next[3] = intr_enable_generic_rx_error_qs; - reg_rdata_next[4] = intr_enable_generic_rx_overflow_qs; - reg_rdata_next[5] = intr_enable_generic_tx_underflow_qs; - reg_rdata_next[6] = intr_enable_upload_cmdfifo_not_empty_qs; - reg_rdata_next[7] = intr_enable_upload_payload_not_empty_qs; - reg_rdata_next[8] = intr_enable_upload_payload_overflow_qs; - reg_rdata_next[9] = intr_enable_readbuf_watermark_qs; - reg_rdata_next[10] = intr_enable_readbuf_flip_qs; - reg_rdata_next[11] = intr_enable_tpm_header_not_empty_qs; + reg_rdata_next[0] = intr_enable_upload_cmdfifo_not_empty_qs; + reg_rdata_next[1] = intr_enable_upload_payload_not_empty_qs; + reg_rdata_next[2] = intr_enable_upload_payload_overflow_qs; + reg_rdata_next[3] = intr_enable_readbuf_watermark_qs; + reg_rdata_next[4] = intr_enable_readbuf_flip_qs; + reg_rdata_next[5] = intr_enable_tpm_header_not_empty_qs; end addr_hit[2]: begin @@ -21221,12 +20109,6 @@ module spi_device_reg_top ( reg_rdata_next[3] = '0; reg_rdata_next[4] = '0; reg_rdata_next[5] = '0; - reg_rdata_next[6] = '0; - reg_rdata_next[7] = '0; - reg_rdata_next[8] = '0; - reg_rdata_next[9] = '0; - reg_rdata_next[10] = '0; - reg_rdata_next[11] = '0; end addr_hit[3]: begin @@ -21234,11 +20116,7 @@ module spi_device_reg_top ( end addr_hit[4]: begin - reg_rdata_next[0] = control_abort_qs; - reg_rdata_next[5:4] = control_mode_qs; - reg_rdata_next[16] = control_rst_txfifo_qs; - reg_rdata_next[17] = control_rst_rxfifo_qs; - reg_rdata_next[31] = control_sram_clk_en_qs; + reg_rdata_next[5:4] = control_qs; end addr_hit[5]: begin @@ -21246,106 +20124,70 @@ module spi_device_reg_top ( reg_rdata_next[1] = cfg_cpha_qs; reg_rdata_next[2] = cfg_tx_order_qs; reg_rdata_next[3] = cfg_rx_order_qs; - reg_rdata_next[15:8] = cfg_timer_v_qs; reg_rdata_next[16] = cfg_addr_4b_en_qs; reg_rdata_next[24] = cfg_mailbox_en_qs; end addr_hit[6]: begin - reg_rdata_next[15:0] = fifo_level_rxlvl_qs; - reg_rdata_next[31:16] = fifo_level_txlvl_qs; - end - - addr_hit[7]: begin - reg_rdata_next[7:0] = async_fifo_level_rxlvl_qs; - reg_rdata_next[23:16] = async_fifo_level_txlvl_qs; - end - - addr_hit[8]: begin - reg_rdata_next[0] = status_rxf_full_qs; - reg_rdata_next[1] = status_rxf_empty_qs; - reg_rdata_next[2] = status_txf_full_qs; - reg_rdata_next[3] = status_txf_empty_qs; - reg_rdata_next[4] = status_abort_done_qs; reg_rdata_next[5] = status_csb_qs; reg_rdata_next[6] = status_tpm_csb_qs; end - addr_hit[9]: begin - reg_rdata_next[15:0] = rxf_ptr_rptr_qs; - reg_rdata_next[31:16] = rxf_ptr_wptr_qs; - end - - addr_hit[10]: begin - reg_rdata_next[15:0] = txf_ptr_rptr_qs; - reg_rdata_next[31:16] = txf_ptr_wptr_qs; - end - - addr_hit[11]: begin - reg_rdata_next[15:0] = rxf_addr_base_qs; - reg_rdata_next[31:16] = rxf_addr_limit_qs; - end - - addr_hit[12]: begin - reg_rdata_next[15:0] = txf_addr_base_qs; - reg_rdata_next[31:16] = txf_addr_limit_qs; - end - - addr_hit[13]: begin + addr_hit[7]: begin reg_rdata_next[0] = intercept_en_status_qs; reg_rdata_next[1] = intercept_en_jedec_qs; reg_rdata_next[2] = intercept_en_sfdp_qs; reg_rdata_next[3] = intercept_en_mbx_qs; end - addr_hit[14]: begin + addr_hit[8]: begin reg_rdata_next[31:0] = last_read_addr_qs; end - addr_hit[15]: begin + addr_hit[9]: begin reg_rdata_next[0] = flash_status_busy_qs; reg_rdata_next[23:1] = flash_status_status_qs; end - addr_hit[16]: begin + addr_hit[10]: begin reg_rdata_next[7:0] = jedec_cc_cc_qs; reg_rdata_next[15:8] = jedec_cc_num_cc_qs; end - addr_hit[17]: begin + addr_hit[11]: begin reg_rdata_next[15:0] = jedec_id_id_qs; reg_rdata_next[23:16] = jedec_id_mf_qs; end - addr_hit[18]: begin + addr_hit[12]: begin reg_rdata_next[9:0] = read_threshold_qs; end - addr_hit[19]: begin + addr_hit[13]: begin reg_rdata_next[31:0] = mailbox_addr_qs; end - addr_hit[20]: begin + addr_hit[14]: begin reg_rdata_next[4:0] = upload_status_cmdfifo_depth_qs; reg_rdata_next[7] = upload_status_cmdfifo_notempty_qs; reg_rdata_next[12:8] = upload_status_addrfifo_depth_qs; reg_rdata_next[15] = upload_status_addrfifo_notempty_qs; end - addr_hit[21]: begin + addr_hit[15]: begin reg_rdata_next[8:0] = upload_status2_payload_depth_qs; reg_rdata_next[23:16] = upload_status2_payload_start_idx_qs; end - addr_hit[22]: begin + addr_hit[16]: begin reg_rdata_next[7:0] = upload_cmdfifo_qs; end - addr_hit[23]: begin + addr_hit[17]: begin reg_rdata_next[31:0] = upload_addrfifo_qs; end - addr_hit[24]: begin + addr_hit[18]: begin reg_rdata_next[0] = cmd_filter_0_filter_0_qs; reg_rdata_next[1] = cmd_filter_0_filter_1_qs; reg_rdata_next[2] = cmd_filter_0_filter_2_qs; @@ -21380,7 +20222,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_filter_0_filter_31_qs; end - addr_hit[25]: begin + addr_hit[19]: begin reg_rdata_next[0] = cmd_filter_1_filter_32_qs; reg_rdata_next[1] = cmd_filter_1_filter_33_qs; reg_rdata_next[2] = cmd_filter_1_filter_34_qs; @@ -21415,7 +20257,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_filter_1_filter_63_qs; end - addr_hit[26]: begin + addr_hit[20]: begin reg_rdata_next[0] = cmd_filter_2_filter_64_qs; reg_rdata_next[1] = cmd_filter_2_filter_65_qs; reg_rdata_next[2] = cmd_filter_2_filter_66_qs; @@ -21450,7 +20292,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_filter_2_filter_95_qs; end - addr_hit[27]: begin + addr_hit[21]: begin reg_rdata_next[0] = cmd_filter_3_filter_96_qs; reg_rdata_next[1] = cmd_filter_3_filter_97_qs; reg_rdata_next[2] = cmd_filter_3_filter_98_qs; @@ -21485,7 +20327,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_filter_3_filter_127_qs; end - addr_hit[28]: begin + addr_hit[22]: begin reg_rdata_next[0] = cmd_filter_4_filter_128_qs; reg_rdata_next[1] = cmd_filter_4_filter_129_qs; reg_rdata_next[2] = cmd_filter_4_filter_130_qs; @@ -21520,7 +20362,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_filter_4_filter_159_qs; end - addr_hit[29]: begin + addr_hit[23]: begin reg_rdata_next[0] = cmd_filter_5_filter_160_qs; reg_rdata_next[1] = cmd_filter_5_filter_161_qs; reg_rdata_next[2] = cmd_filter_5_filter_162_qs; @@ -21555,7 +20397,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_filter_5_filter_191_qs; end - addr_hit[30]: begin + addr_hit[24]: begin reg_rdata_next[0] = cmd_filter_6_filter_192_qs; reg_rdata_next[1] = cmd_filter_6_filter_193_qs; reg_rdata_next[2] = cmd_filter_6_filter_194_qs; @@ -21590,7 +20432,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_filter_6_filter_223_qs; end - addr_hit[31]: begin + addr_hit[25]: begin reg_rdata_next[0] = cmd_filter_7_filter_224_qs; reg_rdata_next[1] = cmd_filter_7_filter_225_qs; reg_rdata_next[2] = cmd_filter_7_filter_226_qs; @@ -21625,23 +20467,23 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_filter_7_filter_255_qs; end - addr_hit[32]: begin + addr_hit[26]: begin reg_rdata_next[31:0] = addr_swap_mask_qs; end - addr_hit[33]: begin + addr_hit[27]: begin reg_rdata_next[31:0] = addr_swap_data_qs; end - addr_hit[34]: begin + addr_hit[28]: begin reg_rdata_next[31:0] = payload_swap_mask_qs; end - addr_hit[35]: begin + addr_hit[29]: begin reg_rdata_next[31:0] = payload_swap_data_qs; end - addr_hit[36]: begin + addr_hit[30]: begin reg_rdata_next[7:0] = cmd_info_0_opcode_0_qs; reg_rdata_next[9:8] = cmd_info_0_addr_mode_0_qs; reg_rdata_next[10] = cmd_info_0_addr_swap_en_0_qs; @@ -21656,7 +20498,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_0_valid_0_qs; end - addr_hit[37]: begin + addr_hit[31]: begin reg_rdata_next[7:0] = cmd_info_1_opcode_1_qs; reg_rdata_next[9:8] = cmd_info_1_addr_mode_1_qs; reg_rdata_next[10] = cmd_info_1_addr_swap_en_1_qs; @@ -21671,7 +20513,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_1_valid_1_qs; end - addr_hit[38]: begin + addr_hit[32]: begin reg_rdata_next[7:0] = cmd_info_2_opcode_2_qs; reg_rdata_next[9:8] = cmd_info_2_addr_mode_2_qs; reg_rdata_next[10] = cmd_info_2_addr_swap_en_2_qs; @@ -21686,7 +20528,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_2_valid_2_qs; end - addr_hit[39]: begin + addr_hit[33]: begin reg_rdata_next[7:0] = cmd_info_3_opcode_3_qs; reg_rdata_next[9:8] = cmd_info_3_addr_mode_3_qs; reg_rdata_next[10] = cmd_info_3_addr_swap_en_3_qs; @@ -21701,7 +20543,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_3_valid_3_qs; end - addr_hit[40]: begin + addr_hit[34]: begin reg_rdata_next[7:0] = cmd_info_4_opcode_4_qs; reg_rdata_next[9:8] = cmd_info_4_addr_mode_4_qs; reg_rdata_next[10] = cmd_info_4_addr_swap_en_4_qs; @@ -21716,7 +20558,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_4_valid_4_qs; end - addr_hit[41]: begin + addr_hit[35]: begin reg_rdata_next[7:0] = cmd_info_5_opcode_5_qs; reg_rdata_next[9:8] = cmd_info_5_addr_mode_5_qs; reg_rdata_next[10] = cmd_info_5_addr_swap_en_5_qs; @@ -21731,7 +20573,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_5_valid_5_qs; end - addr_hit[42]: begin + addr_hit[36]: begin reg_rdata_next[7:0] = cmd_info_6_opcode_6_qs; reg_rdata_next[9:8] = cmd_info_6_addr_mode_6_qs; reg_rdata_next[10] = cmd_info_6_addr_swap_en_6_qs; @@ -21746,7 +20588,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_6_valid_6_qs; end - addr_hit[43]: begin + addr_hit[37]: begin reg_rdata_next[7:0] = cmd_info_7_opcode_7_qs; reg_rdata_next[9:8] = cmd_info_7_addr_mode_7_qs; reg_rdata_next[10] = cmd_info_7_addr_swap_en_7_qs; @@ -21761,7 +20603,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_7_valid_7_qs; end - addr_hit[44]: begin + addr_hit[38]: begin reg_rdata_next[7:0] = cmd_info_8_opcode_8_qs; reg_rdata_next[9:8] = cmd_info_8_addr_mode_8_qs; reg_rdata_next[10] = cmd_info_8_addr_swap_en_8_qs; @@ -21776,7 +20618,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_8_valid_8_qs; end - addr_hit[45]: begin + addr_hit[39]: begin reg_rdata_next[7:0] = cmd_info_9_opcode_9_qs; reg_rdata_next[9:8] = cmd_info_9_addr_mode_9_qs; reg_rdata_next[10] = cmd_info_9_addr_swap_en_9_qs; @@ -21791,7 +20633,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_9_valid_9_qs; end - addr_hit[46]: begin + addr_hit[40]: begin reg_rdata_next[7:0] = cmd_info_10_opcode_10_qs; reg_rdata_next[9:8] = cmd_info_10_addr_mode_10_qs; reg_rdata_next[10] = cmd_info_10_addr_swap_en_10_qs; @@ -21806,7 +20648,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_10_valid_10_qs; end - addr_hit[47]: begin + addr_hit[41]: begin reg_rdata_next[7:0] = cmd_info_11_opcode_11_qs; reg_rdata_next[9:8] = cmd_info_11_addr_mode_11_qs; reg_rdata_next[10] = cmd_info_11_addr_swap_en_11_qs; @@ -21821,7 +20663,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_11_valid_11_qs; end - addr_hit[48]: begin + addr_hit[42]: begin reg_rdata_next[7:0] = cmd_info_12_opcode_12_qs; reg_rdata_next[9:8] = cmd_info_12_addr_mode_12_qs; reg_rdata_next[10] = cmd_info_12_addr_swap_en_12_qs; @@ -21836,7 +20678,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_12_valid_12_qs; end - addr_hit[49]: begin + addr_hit[43]: begin reg_rdata_next[7:0] = cmd_info_13_opcode_13_qs; reg_rdata_next[9:8] = cmd_info_13_addr_mode_13_qs; reg_rdata_next[10] = cmd_info_13_addr_swap_en_13_qs; @@ -21851,7 +20693,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_13_valid_13_qs; end - addr_hit[50]: begin + addr_hit[44]: begin reg_rdata_next[7:0] = cmd_info_14_opcode_14_qs; reg_rdata_next[9:8] = cmd_info_14_addr_mode_14_qs; reg_rdata_next[10] = cmd_info_14_addr_swap_en_14_qs; @@ -21866,7 +20708,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_14_valid_14_qs; end - addr_hit[51]: begin + addr_hit[45]: begin reg_rdata_next[7:0] = cmd_info_15_opcode_15_qs; reg_rdata_next[9:8] = cmd_info_15_addr_mode_15_qs; reg_rdata_next[10] = cmd_info_15_addr_swap_en_15_qs; @@ -21881,7 +20723,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_15_valid_15_qs; end - addr_hit[52]: begin + addr_hit[46]: begin reg_rdata_next[7:0] = cmd_info_16_opcode_16_qs; reg_rdata_next[9:8] = cmd_info_16_addr_mode_16_qs; reg_rdata_next[10] = cmd_info_16_addr_swap_en_16_qs; @@ -21896,7 +20738,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_16_valid_16_qs; end - addr_hit[53]: begin + addr_hit[47]: begin reg_rdata_next[7:0] = cmd_info_17_opcode_17_qs; reg_rdata_next[9:8] = cmd_info_17_addr_mode_17_qs; reg_rdata_next[10] = cmd_info_17_addr_swap_en_17_qs; @@ -21911,7 +20753,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_17_valid_17_qs; end - addr_hit[54]: begin + addr_hit[48]: begin reg_rdata_next[7:0] = cmd_info_18_opcode_18_qs; reg_rdata_next[9:8] = cmd_info_18_addr_mode_18_qs; reg_rdata_next[10] = cmd_info_18_addr_swap_en_18_qs; @@ -21926,7 +20768,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_18_valid_18_qs; end - addr_hit[55]: begin + addr_hit[49]: begin reg_rdata_next[7:0] = cmd_info_19_opcode_19_qs; reg_rdata_next[9:8] = cmd_info_19_addr_mode_19_qs; reg_rdata_next[10] = cmd_info_19_addr_swap_en_19_qs; @@ -21941,7 +20783,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_19_valid_19_qs; end - addr_hit[56]: begin + addr_hit[50]: begin reg_rdata_next[7:0] = cmd_info_20_opcode_20_qs; reg_rdata_next[9:8] = cmd_info_20_addr_mode_20_qs; reg_rdata_next[10] = cmd_info_20_addr_swap_en_20_qs; @@ -21956,7 +20798,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_20_valid_20_qs; end - addr_hit[57]: begin + addr_hit[51]: begin reg_rdata_next[7:0] = cmd_info_21_opcode_21_qs; reg_rdata_next[9:8] = cmd_info_21_addr_mode_21_qs; reg_rdata_next[10] = cmd_info_21_addr_swap_en_21_qs; @@ -21971,7 +20813,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_21_valid_21_qs; end - addr_hit[58]: begin + addr_hit[52]: begin reg_rdata_next[7:0] = cmd_info_22_opcode_22_qs; reg_rdata_next[9:8] = cmd_info_22_addr_mode_22_qs; reg_rdata_next[10] = cmd_info_22_addr_swap_en_22_qs; @@ -21986,7 +20828,7 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_22_valid_22_qs; end - addr_hit[59]: begin + addr_hit[53]: begin reg_rdata_next[7:0] = cmd_info_23_opcode_23_qs; reg_rdata_next[9:8] = cmd_info_23_addr_mode_23_qs; reg_rdata_next[10] = cmd_info_23_addr_swap_en_23_qs; @@ -22001,34 +20843,34 @@ module spi_device_reg_top ( reg_rdata_next[31] = cmd_info_23_valid_23_qs; end - addr_hit[60]: begin + addr_hit[54]: begin reg_rdata_next[7:0] = cmd_info_en4b_opcode_qs; reg_rdata_next[31] = cmd_info_en4b_valid_qs; end - addr_hit[61]: begin + addr_hit[55]: begin reg_rdata_next[7:0] = cmd_info_ex4b_opcode_qs; reg_rdata_next[31] = cmd_info_ex4b_valid_qs; end - addr_hit[62]: begin + addr_hit[56]: begin reg_rdata_next[7:0] = cmd_info_wren_opcode_qs; reg_rdata_next[31] = cmd_info_wren_valid_qs; end - addr_hit[63]: begin + addr_hit[57]: begin reg_rdata_next[7:0] = cmd_info_wrdi_opcode_qs; reg_rdata_next[31] = cmd_info_wrdi_valid_qs; end - addr_hit[64]: begin + addr_hit[58]: begin reg_rdata_next[7:0] = tpm_cap_rev_qs; reg_rdata_next[8] = tpm_cap_locality_qs; reg_rdata_next[18:16] = tpm_cap_max_wr_size_qs; reg_rdata_next[22:20] = tpm_cap_max_rd_size_qs; end - addr_hit[65]: begin + addr_hit[59]: begin reg_rdata_next[0] = tpm_cfg_en_qs; reg_rdata_next[1] = tpm_cfg_tpm_mode_qs; reg_rdata_next[2] = tpm_cfg_hw_reg_dis_qs; @@ -22036,61 +20878,61 @@ module spi_device_reg_top ( reg_rdata_next[4] = tpm_cfg_invalid_locality_qs; end - addr_hit[66]: begin + addr_hit[60]: begin reg_rdata_next[0] = tpm_status_cmdaddr_notempty_qs; reg_rdata_next[22:16] = tpm_status_wrfifo_depth_qs; end - addr_hit[67]: begin + addr_hit[61]: begin reg_rdata_next[7:0] = tpm_access_0_access_0_qs; reg_rdata_next[15:8] = tpm_access_0_access_1_qs; reg_rdata_next[23:16] = tpm_access_0_access_2_qs; reg_rdata_next[31:24] = tpm_access_0_access_3_qs; end - addr_hit[68]: begin + addr_hit[62]: begin reg_rdata_next[7:0] = tpm_access_1_qs; end - addr_hit[69]: begin + addr_hit[63]: begin reg_rdata_next[31:0] = tpm_sts_qs; end - addr_hit[70]: begin + addr_hit[64]: begin reg_rdata_next[31:0] = tpm_intf_capability_qs; end - addr_hit[71]: begin + addr_hit[65]: begin reg_rdata_next[31:0] = tpm_int_enable_qs; end - addr_hit[72]: begin + addr_hit[66]: begin reg_rdata_next[7:0] = tpm_int_vector_qs; end - addr_hit[73]: begin + addr_hit[67]: begin reg_rdata_next[31:0] = tpm_int_status_qs; end - addr_hit[74]: begin + addr_hit[68]: begin reg_rdata_next[15:0] = tpm_did_vid_vid_qs; reg_rdata_next[31:16] = tpm_did_vid_did_qs; end - addr_hit[75]: begin + addr_hit[69]: begin reg_rdata_next[7:0] = tpm_rid_qs; end - addr_hit[76]: begin + addr_hit[70]: begin reg_rdata_next[23:0] = tpm_cmd_addr_addr_qs; reg_rdata_next[31:24] = tpm_cmd_addr_cmd_qs; end - addr_hit[77]: begin + addr_hit[71]: begin reg_rdata_next[31:0] = '0; end - addr_hit[78]: begin + addr_hit[72]: begin reg_rdata_next[7:0] = tpm_write_fifo_qs; end diff --git a/hw/ip/spi_device/rtl/spi_fwm_rxf_ctrl.sv b/hw/ip/spi_device/rtl/spi_fwm_rxf_ctrl.sv deleted file mode 100644 index 0fd1171fe9691..0000000000000 --- a/hw/ip/spi_device/rtl/spi_fwm_rxf_ctrl.sv +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Serial Peripheral Interface (SPI) Device module. -// - -module spi_fwm_rxf_ctrl #( - parameter int unsigned FifoDw = 8, - parameter int unsigned SramAw = 11, - parameter int unsigned SramDw = 32, - // Do not touch below - // SramDw should be multiple of FifoDw - localparam int unsigned NumBytes = SramDw/FifoDw, // derived parameter - localparam int unsigned SDW = $clog2(NumBytes), // derived parameter - localparam int unsigned PtrW = SramAw + SDW + 1 // derived parameter -) ( - input clk_i, - input rst_ni, - - input spi_device_pkg::spi_mode_e spi_mode_i, - - // Configuration - input [SramAw-1:0] base_index_i, - input [SramAw-1:0] limit_index_i, - input [7:0] timer_v, - input [PtrW-1:0] rptr, - output logic [PtrW-1:0] wptr, - output logic [PtrW-1:0] depth, - - output logic full, - - input fifo_valid, - output logic fifo_ready, - input [FifoDw-1:0] fifo_rdata, - - output logic sram_req, - output logic sram_write, - output logic [SramAw-1:0] sram_addr, - output logic [SramDw-1:0] sram_wdata, - output logic [SramDw-1:0] sram_wmask, - input sram_gnt, - input sram_rvalid, - input [SramDw-1:0] sram_rdata, - input [1:0] sram_error -); - - logic active; - - // Internal variable - logic [NumBytes-1:0] byte_enable; - logic [SDW-1:0] pos; // current byte position - logic [7:0] cur_timer; - logic [SramAw-1:0] sramf_limit; - - // State input - logic sramf_full; // SRAM Fifo full - logic full_sramwidth; // Write data filled full SRAM - logic timer_expired; - - // State output - logic update_wdata; - logic clr_byte_enable; - logic sram_req_d; - logic sram_write_d; - logic timer_rst; - logic update_wptr; - - typedef enum logic [2:0] { - StIdle = 'h0, - StPop = 'h1, - StWait = 'h2, - StWrite = 'h3, - StUpdate = 'h4 - } state_e; - - state_e st_next, st; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) st <= StIdle; - else st <= st_next; - end - - assign active = (spi_mode_i == spi_device_pkg::FwMode); - - logic [PtrW-1:0] ptr_cmp; - assign ptr_cmp = rptr ^ wptr; - // The FIFO assumes the partial write as full word write. So, even 3B left, - // still the FIFO is full. - assign sramf_full = (ptr_cmp[PtrW-1] == 1'b1) && (ptr_cmp[PtrW-2:SDW] == '0); - assign full = sramf_full; - - assign sramf_limit = limit_index_i - base_index_i; - - // Write pointer update - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - wptr <= '0; - end else if (update_wptr) begin - if (byte_enable == '0) begin - // as byte enable is cleared, it means full write was done - if (wptr[PtrW-2:SDW] == sramf_limit) begin - wptr[PtrW-1] <= ~wptr[PtrW-1]; - wptr[PtrW-2:0] <= '0; - end else begin - wptr[PtrW-2:SDW] <= wptr[PtrW-2:SDW] + 1'b1; - wptr[SDW-1:0] <= '0; - end - end else begin - wptr[SDW-1:0] <= pos; - end - end - end - - // Full check - assign full_sramwidth = (1'b1 == &byte_enable); - - // Depth - always_comb begin - if (wptr[PtrW-1] == rptr[PtrW-1]) begin - // Same phase - depth = {1'b0, wptr[PtrW-2:0]} - {1'b0, rptr[PtrW-2:0]}; - end else begin - depth = {1'b0, wptr[PtrW-2:0]} - + ({1'b0, sramf_limit,{SDW{1'b1}}} - {1'b0, rptr[PtrW-2:0]} + 1'b1); - end - end - - //timer - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - cur_timer <= '1; - end else if (timer_rst) begin - cur_timer <= timer_v; - end else if (st == StWait) begin - if (cur_timer != '0) cur_timer <= cur_timer - 1'b1; - end - end - assign timer_expired = (cur_timer == '0); - - // Data output - assign sram_addr = base_index_i + wptr[PtrW-2:SDW]; - - // Byte Enable control - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - byte_enable <= '0; - pos <= '0; - end else if (update_wdata) begin - byte_enable[pos] <= 1'b1; - if (pos == SDW'(NumBytes-1)) pos <= '0; - else pos <= pos + 1'b1; - end else if (clr_byte_enable) begin - byte_enable <= '0; - pos <= '0; - end - end - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - sram_wdata <= '0; - end else if (update_wdata) begin - sram_wdata[8*pos+:8] <= fifo_rdata; - end - end - - assign sram_wmask = (byte_enable == '0) ? '1 - : spi_device_pkg::sram_strb2mask(byte_enable); - - logic unused_sram; - assign unused_sram = ^{sram_rvalid, sram_rdata, sram_error}; - - // If FIFO is not empty, initiate SRAM write. - // As FIFOWidth and SRAM Width are different, RMW is required. - // If host writes always DWord size, it is easy but it is not guaranteed. - // - - // Next State & output logic - always_comb begin - // default output value - st_next = st; - fifo_ready = 1'b0; - update_wdata = 1'b0; - clr_byte_enable = 1'b0; - sram_req_d = 1'b0; - sram_write_d = 1'b0; - timer_rst = 1'b0; - update_wptr = 1'b0; - - unique case (st) - StIdle: begin - // Out of reset state. If SRAM Fifo is not full and RX Fifo is not empty, - // state machine starts process incoming data - if (active && fifo_valid && !sramf_full) begin - st_next = StPop; - fifo_ready = 1'b1; - update_wdata = 1'b1; - end else begin - st_next = StIdle; - end - end - - StPop: begin - // Pop entries from FIFO. It moves to WAIT if Fifo is empty and still not - // filled up full sram data width. If anytime while popping the entries - // and full sram data width is filled, it directly moves to Write state - if (fifo_valid && !full_sramwidth) begin - st_next = StPop; - fifo_ready = 1'b1; - update_wdata = 1'b1; - end else if (full_sramwidth) begin - st_next = StWrite; - clr_byte_enable = 1'b1; - sram_req_d = 1'b1; - sram_write_d = 1'b1; - end else begin - st_next = StWait; - timer_rst = 1'b1; - end - end - - StWait: begin - // Wait up to X clocks. This state is useful to reduce traffic to SRAM. - // State machine gathers up to SramDw then tries to write at once. - // If not, it needs to Read-Modify-Write for every byte - if (fifo_valid) begin - st_next = StPop; - fifo_ready = 1'b1; - update_wdata = 1'b1; - end else if (!fifo_valid && timer_expired) begin - // Partial write - st_next = StWrite; - sram_req_d = 1'b1; - sram_write_d = 1'b1; - end else begin - st_next = StWait; - end - end - - StWrite: begin - // Regardless of RMW or just full Words write, statemachine writes data - // into SRAM Fifo - if (sram_gnt) begin - st_next = StUpdate; - end else begin - st_next = StWrite; - sram_req_d = 1'b1; - sram_write_d = 1'b1; - end - end - - StUpdate: begin - // Now, update write pointer then goes back to StIdle. - // It can goes to StPop state directly but doesn't have to as SPI is slower - st_next = StIdle; - update_wptr = 1'b1; - end - - default: begin - st_next = StIdle; - end - endcase - end - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - sram_req <= 1'b0; - sram_write <= 1'b0; - end else begin - sram_req <= sram_req_d; - sram_write <= sram_write_d; - end - end - -endmodule diff --git a/hw/ip/spi_device/rtl/spi_fwm_txf_ctrl.sv b/hw/ip/spi_device/rtl/spi_fwm_txf_ctrl.sv deleted file mode 100644 index 2149b85e8f467..0000000000000 --- a/hw/ip/spi_device/rtl/spi_fwm_txf_ctrl.sv +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Serial Peripheral Interface (SPI) Device module. -// - -module spi_fwm_txf_ctrl #( - parameter int FifoDw = 8, - parameter int SramAw = 11, - parameter int SramDw = 32, - // SramDw should be multiple of FifoDw - localparam int NumBytes = SramDw/FifoDw, // derived parameter - localparam int SDW = $clog2(NumBytes), // derived parameter - localparam int PtrW = SramAw + SDW + 1 // derived parameter -) ( - input clk_i, - input rst_ni, - - input spi_device_pkg::spi_mode_e spi_mode_i, - - // Configuration - input [SramAw-1:0] base_index_i, - input [SramAw-1:0] limit_index_i, - - input abort, // Abort State Machine if TX Async at stuck - input [PtrW-1:0] wptr, - output logic [PtrW-1:0] rptr, - output logic [PtrW-1:0] depth, - - output logic fifo_valid, - input fifo_ready, - output logic [FifoDw-1:0] fifo_wdata, - - output logic sram_req, - output logic sram_write, - output logic [SramAw-1:0] sram_addr, - output logic [SramDw-1:0] sram_wdata, - input sram_gnt, - input sram_rvalid, - input [SramDw-1:0] sram_rdata, - input [1:0] sram_error -); - - logic active; - - logic [SDW-1:0] pos; // Current write position - logic [SramAw-1:0] sramf_limit; - - logic [SramDw-1:0] sram_rdata_q; - logic [SramDw-1:0] fifo_wdata_d; - - logic [PtrW-1:0] wptr_q; - - - // State input - logic sramf_empty; - logic cnt_eq_end; // pos goes 0 -> 1 -> 2 -> 3 -> then 0 - - // State output - logic sram_req_d; - logic update_rptr; - logic latch_wptr; - logic cnt_rst; // Reset pos to rptr[SDW-1:0] or 0 - logic cnt_incr; - logic txf_sel; // 0: sram_rdata, 1: sram_rdata_q - - - typedef enum logic [2:0] { - StIdle = 'h0, - StRead = 'h1, - StLatch = 'h2, - StPush = 'h3, - StUpdate = 'h4 - } state_e; - - state_e st_next, st; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) st <= StIdle; - else st <= st_next; - end - - assign active = (spi_mode_i == spi_device_pkg::FwMode); - - assign sramf_empty = (rptr == wptr_q); - - assign sramf_limit = limit_index_i - base_index_i; - - // State Machine next , output logic - always_comb begin - // default output value - st_next = st; - sram_req_d = 1'b0; - update_rptr = 1'b0; - latch_wptr = 1'b0; - fifo_valid = 1'b0; - txf_sel = 1'b0; // 0: sram_rdata, 1:sram_rdata_q - cnt_rst = 1'b0; // reset pos to rptr - cnt_incr = 1'b0; - unique case (st) - StIdle: begin - latch_wptr = 1'b1; - if (active && !sramf_empty && fifo_ready) begin - st_next = StRead; - sram_req_d = 1'b1; - end else begin - st_next = StIdle; - end - end - - StRead: begin - if (sram_gnt) begin - st_next = StLatch; - cnt_rst = 1'b1; - sram_req_d = 1'b0; - end else begin - st_next = StRead; - sram_req_d = 1'b1; - end - end - - StLatch: begin - if (sram_rvalid) begin - st_next = StPush; - fifo_valid = 1'b1; - txf_sel = 1'b0; // select current sram_rdata - cnt_incr = 1'b1; // increase pos to next byte - end else begin - st_next = StLatch; - end - end - - StPush: begin - if (abort) begin - st_next = StUpdate; - end else if (!fifo_ready) begin - st_next = StPush; - end else if (fifo_ready && !cnt_eq_end) begin - st_next = StPush; - fifo_valid = 1'b1; - txf_sel = 1'b1; // select sram_rdata_q - cnt_incr = 1'b1; - end else begin //if (fifo_ready && cnt_eq_end) begin - // current SRAM word is written to FIFO - st_next = StUpdate; - end - end - - StUpdate: begin - st_next = StIdle; - update_rptr = 1'b1; - end - - default: begin - st_next = StIdle; - end - endcase - end - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - pos <= '0; - end else if (cnt_rst) begin - // Reset to rptr to select bytes among fifo_wdata_d - pos <= rptr[SDW-1:0]; - end else if (cnt_incr) begin - // Increase position - pos <= pos + 1'b1; - end - end - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - wptr_q <= '0; - end else if (latch_wptr) begin - wptr_q <= wptr; - end - end - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - rptr <= '0; - end else if (update_rptr) begin - if (pos == '0) begin - // full sram word is written. - if (rptr[PtrW-2:SDW] != sramf_limit) begin - rptr[PtrW-1:SDW] <= rptr[PtrW-1:SDW] + 1'b1; - rptr[SDW-1:0] <= '0; - end else begin - rptr[PtrW-1] <= ~rptr[PtrW-1]; - rptr[PtrW-2:SDW] <= '0; - rptr[SDW-1:0] <= '0; - end - end else begin - // Abort, or partial update (fifo_full), or wptr_q is at the same entry - rptr[SDW-1:0] <= pos; - end - end - end - - // Depth - always_comb begin - if (wptr[PtrW-1] == rptr[PtrW-1]) begin - // Same phase - depth = {1'b0, wptr[PtrW-2:0]} - {1'b0, rptr[PtrW-2:0]}; - end else begin - depth = {1'b0, wptr[PtrW-2:0]} - + ({1'b0, sramf_limit,{SDW{1'b1}}} - {1'b0, rptr[PtrW-2:0]} + 1'b1); - end - end - - assign cnt_eq_end = (wptr_q[PtrW-1:SDW] == rptr[PtrW-1:SDW]) ? wptr_q[SDW-1:0] == pos : - pos == '0; - - - // Datapath - assign sram_addr = base_index_i + rptr[PtrW-2:SDW]; - assign sram_write = 1'b0; - assign sram_wdata = '0; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) sram_req <= 1'b0; - else sram_req <= sram_req_d; - end - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) sram_rdata_q <= '0; - else if (sram_rvalid) sram_rdata_q <= sram_rdata; - end - - assign fifo_wdata_d = (txf_sel) ? sram_rdata_q : sram_rdata ; - - always_comb begin - fifo_wdata = '0; - for (int unsigned i = 0 ; i < NumBytes ; i++) begin - if (pos == i[SDW-1:0]) fifo_wdata = fifo_wdata_d[8*i+:8]; - end - end - -endmodule diff --git a/hw/ip/spi_device/rtl/spi_fwmode.sv b/hw/ip/spi_device/rtl/spi_fwmode.sv deleted file mode 100644 index 5749129650eb1..0000000000000 --- a/hw/ip/spi_device/rtl/spi_fwmode.sv +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// SPI FW Mode: Intention of this mode is to download FW image. Doesn't parse Commands -// - -module spi_fwmode - import spi_device_pkg::*; -#( - parameter int FifoWidth = $bits(spi_byte_t), - parameter int FifoDepth = 8, - localparam int SDW = $clog2(SramDw/FifoWidth), - localparam int PtrW = SramAw + 1 + SDW, - localparam int AsFifoDepthW = $clog2(FifoDepth+1) -) ( - // clk - input clk_i, // main peripheral clock - input rst_ni, - - input clk_spi_in_i, - input rst_rxfifo_ni, - - input clk_spi_out_i, - input rst_txfifo_ni, - - input spi_mode_e spi_mode_i, - - // Configurations - // No sync logic. Configuration should be static when SPI operating - - output logic rxf_overflow_o, - output logic txf_underflow_o, - - // SRAM interface - output logic fwm_req_o, - output logic fwm_write_o, - output sram_addr_t fwm_addr_o, - output sram_data_t fwm_wdata_o, - output sram_strb_t fwm_wstrb_o, - input fwm_rvalid_i, - input sram_data_t fwm_rdata_i, - input sram_err_t fwm_rerror_i, - - // Serial to Parallel - input rx_data_valid_i, - input spi_byte_t rx_data_i, - output io_mode_e io_mode_o, - - // Parallel to SPI - output logic tx_wvalid_o, - output spi_byte_t tx_data_o, - input tx_wready_i, - - // CSRs - input [7:0] timer_v_i, // Wait timer inside rxf control - input [SramAw-1:0] sram_rxf_bindex_i, - input [SramAw-1:0] sram_txf_bindex_i, - input [SramAw-1:0] sram_rxf_lindex_i, - input [SramAw-1:0] sram_txf_lindex_i, - - input abort_i, - - // pointers - input [PtrW-1:0] sram_rxf_rptr_i, - output logic [PtrW-1:0] sram_rxf_wptr_o, - output logic [PtrW-1:0] sram_txf_rptr_o, - input [PtrW-1:0] sram_txf_wptr_i, - output logic [PtrW-1:0] sram_rxf_depth_o, - output logic [PtrW-1:0] sram_txf_depth_o, - output logic sram_rxf_full_o, - - output logic [AsFifoDepthW-1:0] as_txfifo_depth_o, - output logic [AsFifoDepthW-1:0] as_rxfifo_depth_o, - - // FIFO Status - output logic rxf_empty_o, - output logic rxf_full_o, - output logic txf_empty_o, - output logic txf_full_o - -); - - ///////////// - // Signals // - ///////////// - logic active; - assign active = (spi_mode_i == FwMode); - - // RX Async FIFO Signals - // Write: SCK positive edge - logic rxf_wvalid, rxf_wready; - spi_byte_t rxf_wdata; - // Read: Main clock - logic rxf_rvalid, rxf_rready; - spi_byte_t rxf_rdata; - - // TX Async FIFO Signals - // Read: SCK negative edge - logic txf_rvalid, txf_rready; - spi_byte_t txf_rdata; - // Write: Main clock - logic txf_wvalid, txf_wready; - spi_byte_t txf_wdata; - - // SRAM FIFO control - typedef enum logic { - FwModeRxFifo = 1'b0, - FwModeTxFifo = 1'b1 - } fwm_fifo_e; - - logic [1:0] fwm_sram_req; - logic [SramAw-1:0] fwm_sram_addr [2]; - logic [1:0] fwm_sram_write; - logic [SramDw-1:0] fwm_sram_wdata [2]; - logic [SramDw-1:0] fwm_sram_wmask [2]; - logic [1:0] fwm_sram_gnt; - logic [1:0] fwm_sram_rvalid; // RXF doesn't use - logic [SramDw-1:0] fwm_sram_rdata [2]; // RXF doesn't use - logic [1:0] fwm_sram_error [2]; - - - // Allow Async FIFO update only when the SpiMode is FwMode - assign rxf_wvalid = rx_data_valid_i && active; - assign rxf_wdata = rx_data_i; - - assign tx_wvalid_o = 1'b 1; - assign txf_rready = tx_wready_i; // not updated if !FwMode - assign tx_data_o = txf_rdata; - - // Generic Mode only uses SingleIO. s_i[0] is MOSI, s_o[1] is MISO. - assign io_mode_o = SingleIO; - - // Events: rx_overflow, tx_underflow - // Reminder: Those events are not 100% accurate. If the event happens at - // the end of the transaction right before CSb de-assertion, the event - // cannot be propagated to the main clock domain due to the reset and lack - // of SCK after CSb de-assertion. - // - // For these events to be propagated to the main clock domain, it needds - // one more clock edge to creates toggle signal in the pulse synchronizer. - assign rxf_overflow_o = rxf_wvalid & ~rxf_wready; - assign txf_underflow_o = txf_rready & ~txf_rvalid; - - assign rxf_empty_o = ~rxf_rvalid; - assign rxf_full_o = ~rxf_wready; - assign txf_empty_o = ~txf_rvalid; - assign txf_full_o = ~txf_wready; - /////////////// - // Instances // - /////////////// - - // FIFO: Connecting FwMode to SRAM CTRLs - prim_fifo_async #( - .Width (FifoWidth), - .Depth (FifoDepth) - ) u_rx_fifo ( - .clk_wr_i (clk_spi_in_i), - .rst_wr_ni (rst_rxfifo_ni), - - .clk_rd_i (clk_i), - .rst_rd_ni (rst_rxfifo_ni), - - .wvalid_i (rxf_wvalid), - .wready_o (rxf_wready), - .wdata_i (rxf_wdata), - - .rvalid_o (rxf_rvalid), - .rready_i (rxf_rready), - .rdata_o (rxf_rdata), - - .wdepth_o (), - .rdepth_o (as_rxfifo_depth_o) - ); - - prim_fifo_async #( - .Width (FifoWidth), - .Depth (FifoDepth) - ) u_tx_fifo ( - .clk_wr_i (clk_i), - .rst_wr_ni (rst_txfifo_ni), - - .clk_rd_i (clk_spi_out_i), - .rst_rd_ni (rst_txfifo_ni), - - .wvalid_i (txf_wvalid), - .wready_o (txf_wready), - .wdata_i (txf_wdata), - - .rvalid_o (txf_rvalid), - .rready_i (txf_rready), - .rdata_o (txf_rdata), - - .wdepth_o (as_txfifo_depth_o), - .rdepth_o () - ); - - // RX Fifo control (FIFO Read port --> SRAM request) - spi_fwm_rxf_ctrl #( - .FifoDw (FifoWidth), - .SramAw (SramAw), - .SramDw (SramDw) - ) u_rxf_ctrl ( - .clk_i, - .rst_ni, - - .spi_mode_i, - - .base_index_i (sram_rxf_bindex_i), - .limit_index_i (sram_rxf_lindex_i), - .timer_v (timer_v_i), - .rptr (sram_rxf_rptr_i), // Given by FW - .wptr (sram_rxf_wptr_o), // to Register interface - .depth (sram_rxf_depth_o), - .full (sram_rxf_full_o), - - .fifo_valid (rxf_rvalid), - .fifo_ready (rxf_rready), - .fifo_rdata (rxf_rdata), - - .sram_req (fwm_sram_req [FwModeRxFifo]), - .sram_write (fwm_sram_write [FwModeRxFifo]), - .sram_addr (fwm_sram_addr [FwModeRxFifo]), - .sram_wdata (fwm_sram_wdata [FwModeRxFifo]), - .sram_wmask (fwm_sram_wmask [FwModeRxFifo]), - .sram_gnt (fwm_sram_gnt [FwModeRxFifo]), - .sram_rvalid (fwm_sram_rvalid[FwModeRxFifo]), - .sram_rdata (fwm_sram_rdata [FwModeRxFifo]), - .sram_error (fwm_sram_error [FwModeRxFifo]) - ); - - // TX Fifo control (SRAM read request --> FIFO write) - spi_fwm_txf_ctrl #( - .FifoDw (FifoWidth), - .SramAw (SramAw), - .SramDw (SramDw) - ) u_txf_ctrl ( - .clk_i, - .rst_ni, - - .spi_mode_i, - - .base_index_i (sram_txf_bindex_i), - .limit_index_i (sram_txf_lindex_i), - - .abort (abort_i), - .rptr (sram_txf_rptr_o), - .wptr (sram_txf_wptr_i), - .depth (sram_txf_depth_o), - - .fifo_valid (txf_wvalid), - .fifo_ready (txf_wready), - .fifo_wdata (txf_wdata), - - .sram_req (fwm_sram_req [FwModeTxFifo]), - .sram_write (fwm_sram_write [FwModeTxFifo]), - .sram_addr (fwm_sram_addr [FwModeTxFifo]), - .sram_wdata (fwm_sram_wdata [FwModeTxFifo]), - .sram_gnt (fwm_sram_gnt [FwModeTxFifo]), - .sram_rvalid (fwm_sram_rvalid[FwModeTxFifo]), - .sram_rdata (fwm_sram_rdata [FwModeTxFifo]), - .sram_error (fwm_sram_error [FwModeTxFifo]) - ); - assign fwm_sram_wmask [FwModeTxFifo] = '1; - - // Arbiter for FIFOs : Connecting between SRAM Ctrls and SRAM interface - logic [SramDw-1:0] fwm_wmask; - - assign fwm_wstrb_o = sram_mask2strb(fwm_wmask); - - prim_sram_arbiter #( - .N (2), // RXF, TXF - .SramDw (SramDw), - .SramAw (SramAw) // 2kB - ) u_fwmode_arb ( - .clk_i, - .rst_ni, - - .req_i (fwm_sram_req), - .req_addr_i (fwm_sram_addr), - .req_write_i (fwm_sram_write), - .req_wdata_i (fwm_sram_wdata), - .req_wmask_i (fwm_sram_wmask), - .gnt_o (fwm_sram_gnt), - - .rsp_rvalid_o (fwm_sram_rvalid), - .rsp_rdata_o (fwm_sram_rdata), - .rsp_error_o (fwm_sram_error), - - .sram_req_o (fwm_req_o), - .sram_addr_o (fwm_addr_o), - .sram_write_o (fwm_write_o), - .sram_wdata_o (fwm_wdata_o), - .sram_wmask_o (fwm_wmask), - - .sram_rvalid_i(fwm_rvalid_i), - .sram_rdata_i (fwm_rdata_i), - .sram_rerror_i(fwm_rerror_i) - ); - - -endmodule diff --git a/hw/ip/spi_device/spi_device.core b/hw/ip/spi_device/spi_device.core index 31a0b64a376cf..e3cb7261f0c6c 100644 --- a/hw/ip/spi_device/spi_device.core +++ b/hw/ip/spi_device/spi_device.core @@ -22,9 +22,6 @@ filesets: - lowrisc:ip:spi_device_pkg files: - rtl/spi_device_reg_top.sv - - rtl/spi_fwm_rxf_ctrl.sv - - rtl/spi_fwm_txf_ctrl.sv - - rtl/spi_fwmode.sv - rtl/spi_cmdparse.sv - rtl/spid_readsram.sv - rtl/spid_readbuffer.sv diff --git a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson index e1dad95056676..ee6a2ada30cca 100644 --- a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson +++ b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson @@ -13475,42 +13475,6 @@ type: interrupt module_name: gpio } - { - name: spi_device_generic_rx_full - width: 1 - type: interrupt - module_name: spi_device - } - { - name: spi_device_generic_rx_watermark - width: 1 - type: interrupt - module_name: spi_device - } - { - name: spi_device_generic_tx_watermark - width: 1 - type: interrupt - module_name: spi_device - } - { - name: spi_device_generic_rx_error - width: 1 - type: interrupt - module_name: spi_device - } - { - name: spi_device_generic_rx_overflow - width: 1 - type: interrupt - module_name: spi_device - } - { - name: spi_device_generic_tx_underflow - width: 1 - type: interrupt - module_name: spi_device - } { name: spi_device_upload_cmdfifo_not_empty width: 1 diff --git a/hw/top_earlgrey/data/ip/chip_spi_device_testplan.hjson b/hw/top_earlgrey/data/ip/chip_spi_device_testplan.hjson index 4881d76445c98..11aa53cc5c728 100644 --- a/hw/top_earlgrey/data/ip/chip_spi_device_testplan.hjson +++ b/hw/top_earlgrey/data/ip/chip_spi_device_testplan.hjson @@ -6,41 +6,6 @@ name: chip_spi_device testpoints: [ // SPI_DEVICE (pre-verified IP) integration tests: - { - name: chip_sw_spi_device_tx_rx - desc: '''Verify the transmission of data on the chip's SPI device port in generic mode. - - - The testbench sends a known payload over the chip's SPI device input port. - - At the same time, the SW test sends a known payload out over the chip's SPI device - output port. - - On reception, both payloads are checked for integrity. - - SW validates the reception of the following interrupts: - - RX fifo full - - RX fifo over level - - TX fifo under level - - RX overflow - - TX underflow - - Run with min (6MHz), typical (24Mhz) and max(30MHz) SPI clk frequencies. - - Ensure that the spi_device does not receive transactions when the csb is high. - ''' - stage: V2 - // Can function as a smoketest, but also may be useful as part of a bootloader for early bring-up. - si_stage: SV2 - lc_states: [ - "TEST_UNLOCKED", - "DEV", - "PROD", - "PROD_END", - "RMA", - ] - features: [ - "SPI_DEVICE.MODE.GENERIC", - "SPI_DEVICE.MODE.GENERIC.ASYNC_FIFOS", - "SPI_DEVICE.MODE.GENERIC.DPSRAM_TXF_RXF", - ] - tests: ["chip_sw_spi_device_tx_rx"] - bazel: ["//sw/device/tests:spi_device_smoketest"] - } { name: chip_sw_spi_device_flash_mode desc: '''Verify the SPI device in flash mode. diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson index 0c6b6d7ada6d5..ce9559cc774ab 100644 --- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson +++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson @@ -685,12 +685,6 @@ sw_images: ["//sw/device/tests/sim_dv:i2c_device_tx_rx_test:1:new_rules"] en_run_modes: ["sw_test_mode_test_rom"] } - { - name: chip_sw_spi_device_tx_rx - uvm_test_seq: chip_sw_spi_device_tx_rx_vseq - sw_images: ["//sw/device/tests/sim_dv:spi_tx_rx_test:1:new_rules"] - en_run_modes: ["sw_test_mode_test_rom"] - } { name: chip_sw_spi_device_tpm uvm_test_seq: chip_sw_spi_device_tpm_vseq @@ -2165,7 +2159,7 @@ name: xcelium_ci_1 tests: ["chip_sw_rv_core_ibex_address_translation", "chip_sw_rv_timer_irq", - "chip_sw_spi_device_tx_rx", + "chip_sw_spi_device_tpm", "chip_sw_usb_ast_clk_calib", "chip_sw_plic_sw_irq", "chip_sw_aes_enc", diff --git a/hw/top_earlgrey/dv/env/chip_env.core b/hw/top_earlgrey/dv/env/chip_env.core index a35712a9091a3..1eb965d193368 100644 --- a/hw/top_earlgrey/dv/env/chip_env.core +++ b/hw/top_earlgrey/dv/env/chip_env.core @@ -100,7 +100,6 @@ filesets: - seq_lib/chip_sw_lc_ctrl_program_error_vseq.sv: {is_include_file: true} - seq_lib/chip_sw_otp_ctrl_vendor_test_csr_access_vseq.sv: {is_include_file: true} - seq_lib/chip_sw_otp_ctrl_escalation_vseq.sv: {is_include_file: true} - - seq_lib/chip_sw_spi_device_tx_rx_vseq.sv: {is_include_file: true} - seq_lib/chip_sw_spi_host_tx_rx_vseq.sv: {is_include_file: true} - seq_lib/chip_sw_spi_passthrough_collision_vseq.sv: {is_include_file: true} - seq_lib/chip_sw_spi_passthrough_vseq.sv: {is_include_file: true} diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tx_rx_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tx_rx_vseq.sv deleted file mode 100644 index 4f749c68707a1..0000000000000 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tx_rx_vseq.sv +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class chip_sw_spi_device_tx_rx_vseq extends chip_sw_base_vseq; - `uvm_object_utils(chip_sw_spi_device_tx_rx_vseq) - - `uvm_object_new - - localparam uint SPI_DEVICE_DATA_SIZE = 128; - localparam uint SPI_DEVICE_RX_SRAM_SIZE = 1024; - - // A set of bytes to be send from SPI_HOST to SPI_DEVICE RX FIFO. - rand bit [7:0] spi_device_rx_data[]; - constraint spi_device_rx_data_c { - spi_device_rx_data.size() == SPI_DEVICE_DATA_SIZE; - } - - // A set of bytes expected to be received on SPI_HOST from SPI_DEVICE TX FIFO. - rand bit [7:0] exp_spi_device_tx_data[]; - constraint exp_spi_device_tx_data_c { - exp_spi_device_tx_data.size() == SPI_DEVICE_DATA_SIZE; - } - - virtual task sync_with_sw(); - `DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInWfi) - `DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInTest) - endtask:sync_with_sw - - virtual task cpu_init(); - super.cpu_init(); - sw_symbol_backdoor_overwrite("spi_device_tx_data", exp_spi_device_tx_data); - sw_symbol_backdoor_overwrite("exp_spi_device_rx_data", spi_device_rx_data); - endtask - - virtual task body(); - bit [7:0] spi_device_tx_data[$]; - super.body(); - - // Wait SPI_DEVICE filled TX FIFO, otherwise SDO will be X - sync_with_sw(); - csr_spinwait(.ptr(ral.spi_device.status.txf_full), .exp_data('b1), .backdoor(1), - .spinwait_delay_ns(1)); - - // Send SPI_HOST data to SPI_DEVICE RX_FIFO and get tx_data from SPI_DEVICE TX_FIFO - // Check if received tx_data against expected value - send_spi_host_rx_data(spi_device_tx_data, SPI_DEVICE_DATA_SIZE); - foreach (spi_device_tx_data[i]) begin - `DV_CHECK_CASE_EQ(spi_device_tx_data[i], exp_spi_device_tx_data[i]) - end - - // Wait for the CPU to read out the RX_FIFO - sync_with_sw(); - - // Send data to fill RX_SRAM to test RX SRAM FIFO full interrupt - send_spi_host_rx_data(spi_device_tx_data, SPI_DEVICE_RX_SRAM_SIZE); - - // Wait for RX_FULL interrupt to fire - sync_with_sw(); - - // Send an extra data to test RX Async FIFO overflow - send_spi_host_rx_data(spi_device_tx_data, SPI_DEVICE_DATA_SIZE); - endtask - - virtual task send_spi_host_rx_data(ref bit [7:0] device_data[$],input int size); - spi_host_seq m_spi_host_seq; - `uvm_create_on(m_spi_host_seq, p_sequencer.spi_host_sequencer_h) - if (size == SPI_DEVICE_DATA_SIZE) begin - `DV_CHECK_RANDOMIZE_WITH_FATAL(m_spi_host_seq, - data.size() == size; - foreach (data[i]) {data[i] == spi_device_rx_data[i];}) - end else begin - `DV_CHECK_RANDOMIZE_WITH_FATAL(m_spi_host_seq, data.size() == size;) - end - `uvm_send(m_spi_host_seq) - device_data = m_spi_host_seq.rsp.data; - endtask - -endclass : chip_sw_spi_device_tx_rx_vseq diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv index 0a6755aa92f79..725156abc27e1 100644 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv +++ b/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv @@ -47,7 +47,6 @@ `include "chip_sw_lc_walkthrough_testunlocks_vseq.sv" `include "chip_sw_otp_ctrl_vendor_test_csr_access_vseq.sv" `include "chip_sw_otp_ctrl_escalation_vseq.sv" -`include "chip_sw_spi_device_tx_rx_vseq.sv" `include "chip_sw_spi_host_tx_rx_vseq.sv" `include "chip_sw_spi_passthrough_vseq.sv" `include "chip_sw_spi_passthrough_collision_vseq.sv" diff --git a/hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson b/hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson index 9c34c34b90ad8..fd14956a985b6 100644 --- a/hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson +++ b/hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson @@ -37,7 +37,7 @@ { name: "NumSrc", desc: "Number of interrupt sources", type: "int", - default: "185", + default: "179", local: "true" }, { name: "NumTarget", @@ -1541,54 +1541,6 @@ { bits: "1:0" } ], } - { name: "PRIO179", - desc: "Interrupt Source 179 Priority", - swaccess: "rw", - hwaccess: "hro", - fields: [ - { bits: "1:0" } - ], - } - { name: "PRIO180", - desc: "Interrupt Source 180 Priority", - swaccess: "rw", - hwaccess: "hro", - fields: [ - { bits: "1:0" } - ], - } - { name: "PRIO181", - desc: "Interrupt Source 181 Priority", - swaccess: "rw", - hwaccess: "hro", - fields: [ - { bits: "1:0" } - ], - } - { name: "PRIO182", - desc: "Interrupt Source 182 Priority", - swaccess: "rw", - hwaccess: "hro", - fields: [ - { bits: "1:0" } - ], - } - { name: "PRIO183", - desc: "Interrupt Source 183 Priority", - swaccess: "rw", - hwaccess: "hro", - fields: [ - { bits: "1:0" } - ], - } - { name: "PRIO184", - desc: "Interrupt Source 184 Priority", - swaccess: "rw", - hwaccess: "hro", - fields: [ - { bits: "1:0" } - ], - } { skipto: "0x00001000" } { multireg: { name: "IP", diff --git a/hw/top_earlgrey/ip_autogen/rv_plic/data/top_earlgrey_rv_plic.ipconfig.hjson b/hw/top_earlgrey/ip_autogen/rv_plic/data/top_earlgrey_rv_plic.ipconfig.hjson index e7abdec8a5258..b617ca46f9705 100644 --- a/hw/top_earlgrey/ip_autogen/rv_plic/data/top_earlgrey_rv_plic.ipconfig.hjson +++ b/hw/top_earlgrey/ip_autogen/rv_plic/data/top_earlgrey_rv_plic.ipconfig.hjson @@ -5,7 +5,7 @@ instance_name: top_earlgrey_rv_plic param_values: { - src: 185 + src: 179 target: 1 prio: 3 topname: earlgrey diff --git a/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic.sv b/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic.sv index 25360907e5afc..3a5e2ec4a44df 100644 --- a/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic.sv +++ b/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic.sv @@ -275,17 +275,11 @@ module rv_plic import rv_plic_reg_pkg::*; #( assign prio[176] = reg2hw.prio176.q; assign prio[177] = reg2hw.prio177.q; assign prio[178] = reg2hw.prio178.q; - assign prio[179] = reg2hw.prio179.q; - assign prio[180] = reg2hw.prio180.q; - assign prio[181] = reg2hw.prio181.q; - assign prio[182] = reg2hw.prio182.q; - assign prio[183] = reg2hw.prio183.q; - assign prio[184] = reg2hw.prio184.q; ////////////////////// // Interrupt Enable // ////////////////////// - for (genvar s = 0; s < 185; s++) begin : gen_ie0 + for (genvar s = 0; s < 179; s++) begin : gen_ie0 assign ie[0][s] = reg2hw.ie0[s].q; end @@ -311,7 +305,7 @@ module rv_plic import rv_plic_reg_pkg::*; #( //////// // IP // //////// - for (genvar s = 0; s < 185; s++) begin : gen_ip + for (genvar s = 0; s < 179; s++) begin : gen_ip assign hw2reg.ip[s].de = 1'b1; // Always write assign hw2reg.ip[s].d = ip[s]; end diff --git a/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic_reg_pkg.sv b/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic_reg_pkg.sv index dbb6bb55f0385..c5feab4ab8785 100644 --- a/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic_reg_pkg.sv +++ b/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic_reg_pkg.sv @@ -7,7 +7,7 @@ package rv_plic_reg_pkg; // Param list - parameter int NumSrc = 185; + parameter int NumSrc = 179; parameter int NumTarget = 1; parameter int PrioWidth = 2; parameter int NumAlerts = 1; @@ -735,30 +735,6 @@ package rv_plic_reg_pkg; logic [1:0] q; } rv_plic_reg2hw_prio178_reg_t; - typedef struct packed { - logic [1:0] q; - } rv_plic_reg2hw_prio179_reg_t; - - typedef struct packed { - logic [1:0] q; - } rv_plic_reg2hw_prio180_reg_t; - - typedef struct packed { - logic [1:0] q; - } rv_plic_reg2hw_prio181_reg_t; - - typedef struct packed { - logic [1:0] q; - } rv_plic_reg2hw_prio182_reg_t; - - typedef struct packed { - logic [1:0] q; - } rv_plic_reg2hw_prio183_reg_t; - - typedef struct packed { - logic [1:0] q; - } rv_plic_reg2hw_prio184_reg_t; - typedef struct packed { logic q; } rv_plic_reg2hw_ie0_mreg_t; @@ -793,192 +769,186 @@ package rv_plic_reg_pkg; // Register -> HW type typedef struct packed { - rv_plic_reg2hw_prio0_reg_t prio0; // [569:568] - rv_plic_reg2hw_prio1_reg_t prio1; // [567:566] - rv_plic_reg2hw_prio2_reg_t prio2; // [565:564] - rv_plic_reg2hw_prio3_reg_t prio3; // [563:562] - rv_plic_reg2hw_prio4_reg_t prio4; // [561:560] - rv_plic_reg2hw_prio5_reg_t prio5; // [559:558] - rv_plic_reg2hw_prio6_reg_t prio6; // [557:556] - rv_plic_reg2hw_prio7_reg_t prio7; // [555:554] - rv_plic_reg2hw_prio8_reg_t prio8; // [553:552] - rv_plic_reg2hw_prio9_reg_t prio9; // [551:550] - rv_plic_reg2hw_prio10_reg_t prio10; // [549:548] - rv_plic_reg2hw_prio11_reg_t prio11; // [547:546] - rv_plic_reg2hw_prio12_reg_t prio12; // [545:544] - rv_plic_reg2hw_prio13_reg_t prio13; // [543:542] - rv_plic_reg2hw_prio14_reg_t prio14; // [541:540] - rv_plic_reg2hw_prio15_reg_t prio15; // [539:538] - rv_plic_reg2hw_prio16_reg_t prio16; // [537:536] - rv_plic_reg2hw_prio17_reg_t prio17; // [535:534] - rv_plic_reg2hw_prio18_reg_t prio18; // [533:532] - rv_plic_reg2hw_prio19_reg_t prio19; // [531:530] - rv_plic_reg2hw_prio20_reg_t prio20; // [529:528] - rv_plic_reg2hw_prio21_reg_t prio21; // [527:526] - rv_plic_reg2hw_prio22_reg_t prio22; // [525:524] - rv_plic_reg2hw_prio23_reg_t prio23; // [523:522] - rv_plic_reg2hw_prio24_reg_t prio24; // [521:520] - rv_plic_reg2hw_prio25_reg_t prio25; // [519:518] - rv_plic_reg2hw_prio26_reg_t prio26; // [517:516] - rv_plic_reg2hw_prio27_reg_t prio27; // [515:514] - rv_plic_reg2hw_prio28_reg_t prio28; // [513:512] - rv_plic_reg2hw_prio29_reg_t prio29; // [511:510] - rv_plic_reg2hw_prio30_reg_t prio30; // [509:508] - rv_plic_reg2hw_prio31_reg_t prio31; // [507:506] - rv_plic_reg2hw_prio32_reg_t prio32; // [505:504] - rv_plic_reg2hw_prio33_reg_t prio33; // [503:502] - rv_plic_reg2hw_prio34_reg_t prio34; // [501:500] - rv_plic_reg2hw_prio35_reg_t prio35; // [499:498] - rv_plic_reg2hw_prio36_reg_t prio36; // [497:496] - rv_plic_reg2hw_prio37_reg_t prio37; // [495:494] - rv_plic_reg2hw_prio38_reg_t prio38; // [493:492] - rv_plic_reg2hw_prio39_reg_t prio39; // [491:490] - rv_plic_reg2hw_prio40_reg_t prio40; // [489:488] - rv_plic_reg2hw_prio41_reg_t prio41; // [487:486] - rv_plic_reg2hw_prio42_reg_t prio42; // [485:484] - rv_plic_reg2hw_prio43_reg_t prio43; // [483:482] - rv_plic_reg2hw_prio44_reg_t prio44; // [481:480] - rv_plic_reg2hw_prio45_reg_t prio45; // [479:478] - rv_plic_reg2hw_prio46_reg_t prio46; // [477:476] - rv_plic_reg2hw_prio47_reg_t prio47; // [475:474] - rv_plic_reg2hw_prio48_reg_t prio48; // [473:472] - rv_plic_reg2hw_prio49_reg_t prio49; // [471:470] - rv_plic_reg2hw_prio50_reg_t prio50; // [469:468] - rv_plic_reg2hw_prio51_reg_t prio51; // [467:466] - rv_plic_reg2hw_prio52_reg_t prio52; // [465:464] - rv_plic_reg2hw_prio53_reg_t prio53; // [463:462] - rv_plic_reg2hw_prio54_reg_t prio54; // [461:460] - rv_plic_reg2hw_prio55_reg_t prio55; // [459:458] - rv_plic_reg2hw_prio56_reg_t prio56; // [457:456] - rv_plic_reg2hw_prio57_reg_t prio57; // [455:454] - rv_plic_reg2hw_prio58_reg_t prio58; // [453:452] - rv_plic_reg2hw_prio59_reg_t prio59; // [451:450] - rv_plic_reg2hw_prio60_reg_t prio60; // [449:448] - rv_plic_reg2hw_prio61_reg_t prio61; // [447:446] - rv_plic_reg2hw_prio62_reg_t prio62; // [445:444] - rv_plic_reg2hw_prio63_reg_t prio63; // [443:442] - rv_plic_reg2hw_prio64_reg_t prio64; // [441:440] - rv_plic_reg2hw_prio65_reg_t prio65; // [439:438] - rv_plic_reg2hw_prio66_reg_t prio66; // [437:436] - rv_plic_reg2hw_prio67_reg_t prio67; // [435:434] - rv_plic_reg2hw_prio68_reg_t prio68; // [433:432] - rv_plic_reg2hw_prio69_reg_t prio69; // [431:430] - rv_plic_reg2hw_prio70_reg_t prio70; // [429:428] - rv_plic_reg2hw_prio71_reg_t prio71; // [427:426] - rv_plic_reg2hw_prio72_reg_t prio72; // [425:424] - rv_plic_reg2hw_prio73_reg_t prio73; // [423:422] - rv_plic_reg2hw_prio74_reg_t prio74; // [421:420] - rv_plic_reg2hw_prio75_reg_t prio75; // [419:418] - rv_plic_reg2hw_prio76_reg_t prio76; // [417:416] - rv_plic_reg2hw_prio77_reg_t prio77; // [415:414] - rv_plic_reg2hw_prio78_reg_t prio78; // [413:412] - rv_plic_reg2hw_prio79_reg_t prio79; // [411:410] - rv_plic_reg2hw_prio80_reg_t prio80; // [409:408] - rv_plic_reg2hw_prio81_reg_t prio81; // [407:406] - rv_plic_reg2hw_prio82_reg_t prio82; // [405:404] - rv_plic_reg2hw_prio83_reg_t prio83; // [403:402] - rv_plic_reg2hw_prio84_reg_t prio84; // [401:400] - rv_plic_reg2hw_prio85_reg_t prio85; // [399:398] - rv_plic_reg2hw_prio86_reg_t prio86; // [397:396] - rv_plic_reg2hw_prio87_reg_t prio87; // [395:394] - rv_plic_reg2hw_prio88_reg_t prio88; // [393:392] - rv_plic_reg2hw_prio89_reg_t prio89; // [391:390] - rv_plic_reg2hw_prio90_reg_t prio90; // [389:388] - rv_plic_reg2hw_prio91_reg_t prio91; // [387:386] - rv_plic_reg2hw_prio92_reg_t prio92; // [385:384] - rv_plic_reg2hw_prio93_reg_t prio93; // [383:382] - rv_plic_reg2hw_prio94_reg_t prio94; // [381:380] - rv_plic_reg2hw_prio95_reg_t prio95; // [379:378] - rv_plic_reg2hw_prio96_reg_t prio96; // [377:376] - rv_plic_reg2hw_prio97_reg_t prio97; // [375:374] - rv_plic_reg2hw_prio98_reg_t prio98; // [373:372] - rv_plic_reg2hw_prio99_reg_t prio99; // [371:370] - rv_plic_reg2hw_prio100_reg_t prio100; // [369:368] - rv_plic_reg2hw_prio101_reg_t prio101; // [367:366] - rv_plic_reg2hw_prio102_reg_t prio102; // [365:364] - rv_plic_reg2hw_prio103_reg_t prio103; // [363:362] - rv_plic_reg2hw_prio104_reg_t prio104; // [361:360] - rv_plic_reg2hw_prio105_reg_t prio105; // [359:358] - rv_plic_reg2hw_prio106_reg_t prio106; // [357:356] - rv_plic_reg2hw_prio107_reg_t prio107; // [355:354] - rv_plic_reg2hw_prio108_reg_t prio108; // [353:352] - rv_plic_reg2hw_prio109_reg_t prio109; // [351:350] - rv_plic_reg2hw_prio110_reg_t prio110; // [349:348] - rv_plic_reg2hw_prio111_reg_t prio111; // [347:346] - rv_plic_reg2hw_prio112_reg_t prio112; // [345:344] - rv_plic_reg2hw_prio113_reg_t prio113; // [343:342] - rv_plic_reg2hw_prio114_reg_t prio114; // [341:340] - rv_plic_reg2hw_prio115_reg_t prio115; // [339:338] - rv_plic_reg2hw_prio116_reg_t prio116; // [337:336] - rv_plic_reg2hw_prio117_reg_t prio117; // [335:334] - rv_plic_reg2hw_prio118_reg_t prio118; // [333:332] - rv_plic_reg2hw_prio119_reg_t prio119; // [331:330] - rv_plic_reg2hw_prio120_reg_t prio120; // [329:328] - rv_plic_reg2hw_prio121_reg_t prio121; // [327:326] - rv_plic_reg2hw_prio122_reg_t prio122; // [325:324] - rv_plic_reg2hw_prio123_reg_t prio123; // [323:322] - rv_plic_reg2hw_prio124_reg_t prio124; // [321:320] - rv_plic_reg2hw_prio125_reg_t prio125; // [319:318] - rv_plic_reg2hw_prio126_reg_t prio126; // [317:316] - rv_plic_reg2hw_prio127_reg_t prio127; // [315:314] - rv_plic_reg2hw_prio128_reg_t prio128; // [313:312] - rv_plic_reg2hw_prio129_reg_t prio129; // [311:310] - rv_plic_reg2hw_prio130_reg_t prio130; // [309:308] - rv_plic_reg2hw_prio131_reg_t prio131; // [307:306] - rv_plic_reg2hw_prio132_reg_t prio132; // [305:304] - rv_plic_reg2hw_prio133_reg_t prio133; // [303:302] - rv_plic_reg2hw_prio134_reg_t prio134; // [301:300] - rv_plic_reg2hw_prio135_reg_t prio135; // [299:298] - rv_plic_reg2hw_prio136_reg_t prio136; // [297:296] - rv_plic_reg2hw_prio137_reg_t prio137; // [295:294] - rv_plic_reg2hw_prio138_reg_t prio138; // [293:292] - rv_plic_reg2hw_prio139_reg_t prio139; // [291:290] - rv_plic_reg2hw_prio140_reg_t prio140; // [289:288] - rv_plic_reg2hw_prio141_reg_t prio141; // [287:286] - rv_plic_reg2hw_prio142_reg_t prio142; // [285:284] - rv_plic_reg2hw_prio143_reg_t prio143; // [283:282] - rv_plic_reg2hw_prio144_reg_t prio144; // [281:280] - rv_plic_reg2hw_prio145_reg_t prio145; // [279:278] - rv_plic_reg2hw_prio146_reg_t prio146; // [277:276] - rv_plic_reg2hw_prio147_reg_t prio147; // [275:274] - rv_plic_reg2hw_prio148_reg_t prio148; // [273:272] - rv_plic_reg2hw_prio149_reg_t prio149; // [271:270] - rv_plic_reg2hw_prio150_reg_t prio150; // [269:268] - rv_plic_reg2hw_prio151_reg_t prio151; // [267:266] - rv_plic_reg2hw_prio152_reg_t prio152; // [265:264] - rv_plic_reg2hw_prio153_reg_t prio153; // [263:262] - rv_plic_reg2hw_prio154_reg_t prio154; // [261:260] - rv_plic_reg2hw_prio155_reg_t prio155; // [259:258] - rv_plic_reg2hw_prio156_reg_t prio156; // [257:256] - rv_plic_reg2hw_prio157_reg_t prio157; // [255:254] - rv_plic_reg2hw_prio158_reg_t prio158; // [253:252] - rv_plic_reg2hw_prio159_reg_t prio159; // [251:250] - rv_plic_reg2hw_prio160_reg_t prio160; // [249:248] - rv_plic_reg2hw_prio161_reg_t prio161; // [247:246] - rv_plic_reg2hw_prio162_reg_t prio162; // [245:244] - rv_plic_reg2hw_prio163_reg_t prio163; // [243:242] - rv_plic_reg2hw_prio164_reg_t prio164; // [241:240] - rv_plic_reg2hw_prio165_reg_t prio165; // [239:238] - rv_plic_reg2hw_prio166_reg_t prio166; // [237:236] - rv_plic_reg2hw_prio167_reg_t prio167; // [235:234] - rv_plic_reg2hw_prio168_reg_t prio168; // [233:232] - rv_plic_reg2hw_prio169_reg_t prio169; // [231:230] - rv_plic_reg2hw_prio170_reg_t prio170; // [229:228] - rv_plic_reg2hw_prio171_reg_t prio171; // [227:226] - rv_plic_reg2hw_prio172_reg_t prio172; // [225:224] - rv_plic_reg2hw_prio173_reg_t prio173; // [223:222] - rv_plic_reg2hw_prio174_reg_t prio174; // [221:220] - rv_plic_reg2hw_prio175_reg_t prio175; // [219:218] - rv_plic_reg2hw_prio176_reg_t prio176; // [217:216] - rv_plic_reg2hw_prio177_reg_t prio177; // [215:214] - rv_plic_reg2hw_prio178_reg_t prio178; // [213:212] - rv_plic_reg2hw_prio179_reg_t prio179; // [211:210] - rv_plic_reg2hw_prio180_reg_t prio180; // [209:208] - rv_plic_reg2hw_prio181_reg_t prio181; // [207:206] - rv_plic_reg2hw_prio182_reg_t prio182; // [205:204] - rv_plic_reg2hw_prio183_reg_t prio183; // [203:202] - rv_plic_reg2hw_prio184_reg_t prio184; // [201:200] - rv_plic_reg2hw_ie0_mreg_t [184:0] ie0; // [199:15] + rv_plic_reg2hw_prio0_reg_t prio0; // [551:550] + rv_plic_reg2hw_prio1_reg_t prio1; // [549:548] + rv_plic_reg2hw_prio2_reg_t prio2; // [547:546] + rv_plic_reg2hw_prio3_reg_t prio3; // [545:544] + rv_plic_reg2hw_prio4_reg_t prio4; // [543:542] + rv_plic_reg2hw_prio5_reg_t prio5; // [541:540] + rv_plic_reg2hw_prio6_reg_t prio6; // [539:538] + rv_plic_reg2hw_prio7_reg_t prio7; // [537:536] + rv_plic_reg2hw_prio8_reg_t prio8; // [535:534] + rv_plic_reg2hw_prio9_reg_t prio9; // [533:532] + rv_plic_reg2hw_prio10_reg_t prio10; // [531:530] + rv_plic_reg2hw_prio11_reg_t prio11; // [529:528] + rv_plic_reg2hw_prio12_reg_t prio12; // [527:526] + rv_plic_reg2hw_prio13_reg_t prio13; // [525:524] + rv_plic_reg2hw_prio14_reg_t prio14; // [523:522] + rv_plic_reg2hw_prio15_reg_t prio15; // [521:520] + rv_plic_reg2hw_prio16_reg_t prio16; // [519:518] + rv_plic_reg2hw_prio17_reg_t prio17; // [517:516] + rv_plic_reg2hw_prio18_reg_t prio18; // [515:514] + rv_plic_reg2hw_prio19_reg_t prio19; // [513:512] + rv_plic_reg2hw_prio20_reg_t prio20; // [511:510] + rv_plic_reg2hw_prio21_reg_t prio21; // [509:508] + rv_plic_reg2hw_prio22_reg_t prio22; // [507:506] + rv_plic_reg2hw_prio23_reg_t prio23; // [505:504] + rv_plic_reg2hw_prio24_reg_t prio24; // [503:502] + rv_plic_reg2hw_prio25_reg_t prio25; // [501:500] + rv_plic_reg2hw_prio26_reg_t prio26; // [499:498] + rv_plic_reg2hw_prio27_reg_t prio27; // [497:496] + rv_plic_reg2hw_prio28_reg_t prio28; // [495:494] + rv_plic_reg2hw_prio29_reg_t prio29; // [493:492] + rv_plic_reg2hw_prio30_reg_t prio30; // [491:490] + rv_plic_reg2hw_prio31_reg_t prio31; // [489:488] + rv_plic_reg2hw_prio32_reg_t prio32; // [487:486] + rv_plic_reg2hw_prio33_reg_t prio33; // [485:484] + rv_plic_reg2hw_prio34_reg_t prio34; // [483:482] + rv_plic_reg2hw_prio35_reg_t prio35; // [481:480] + rv_plic_reg2hw_prio36_reg_t prio36; // [479:478] + rv_plic_reg2hw_prio37_reg_t prio37; // [477:476] + rv_plic_reg2hw_prio38_reg_t prio38; // [475:474] + rv_plic_reg2hw_prio39_reg_t prio39; // [473:472] + rv_plic_reg2hw_prio40_reg_t prio40; // [471:470] + rv_plic_reg2hw_prio41_reg_t prio41; // [469:468] + rv_plic_reg2hw_prio42_reg_t prio42; // [467:466] + rv_plic_reg2hw_prio43_reg_t prio43; // [465:464] + rv_plic_reg2hw_prio44_reg_t prio44; // [463:462] + rv_plic_reg2hw_prio45_reg_t prio45; // [461:460] + rv_plic_reg2hw_prio46_reg_t prio46; // [459:458] + rv_plic_reg2hw_prio47_reg_t prio47; // [457:456] + rv_plic_reg2hw_prio48_reg_t prio48; // [455:454] + rv_plic_reg2hw_prio49_reg_t prio49; // [453:452] + rv_plic_reg2hw_prio50_reg_t prio50; // [451:450] + rv_plic_reg2hw_prio51_reg_t prio51; // [449:448] + rv_plic_reg2hw_prio52_reg_t prio52; // [447:446] + rv_plic_reg2hw_prio53_reg_t prio53; // [445:444] + rv_plic_reg2hw_prio54_reg_t prio54; // [443:442] + rv_plic_reg2hw_prio55_reg_t prio55; // [441:440] + rv_plic_reg2hw_prio56_reg_t prio56; // [439:438] + rv_plic_reg2hw_prio57_reg_t prio57; // [437:436] + rv_plic_reg2hw_prio58_reg_t prio58; // [435:434] + rv_plic_reg2hw_prio59_reg_t prio59; // [433:432] + rv_plic_reg2hw_prio60_reg_t prio60; // [431:430] + rv_plic_reg2hw_prio61_reg_t prio61; // [429:428] + rv_plic_reg2hw_prio62_reg_t prio62; // [427:426] + rv_plic_reg2hw_prio63_reg_t prio63; // [425:424] + rv_plic_reg2hw_prio64_reg_t prio64; // [423:422] + rv_plic_reg2hw_prio65_reg_t prio65; // [421:420] + rv_plic_reg2hw_prio66_reg_t prio66; // [419:418] + rv_plic_reg2hw_prio67_reg_t prio67; // [417:416] + rv_plic_reg2hw_prio68_reg_t prio68; // [415:414] + rv_plic_reg2hw_prio69_reg_t prio69; // [413:412] + rv_plic_reg2hw_prio70_reg_t prio70; // [411:410] + rv_plic_reg2hw_prio71_reg_t prio71; // [409:408] + rv_plic_reg2hw_prio72_reg_t prio72; // [407:406] + rv_plic_reg2hw_prio73_reg_t prio73; // [405:404] + rv_plic_reg2hw_prio74_reg_t prio74; // [403:402] + rv_plic_reg2hw_prio75_reg_t prio75; // [401:400] + rv_plic_reg2hw_prio76_reg_t prio76; // [399:398] + rv_plic_reg2hw_prio77_reg_t prio77; // [397:396] + rv_plic_reg2hw_prio78_reg_t prio78; // [395:394] + rv_plic_reg2hw_prio79_reg_t prio79; // [393:392] + rv_plic_reg2hw_prio80_reg_t prio80; // [391:390] + rv_plic_reg2hw_prio81_reg_t prio81; // [389:388] + rv_plic_reg2hw_prio82_reg_t prio82; // [387:386] + rv_plic_reg2hw_prio83_reg_t prio83; // [385:384] + rv_plic_reg2hw_prio84_reg_t prio84; // [383:382] + rv_plic_reg2hw_prio85_reg_t prio85; // [381:380] + rv_plic_reg2hw_prio86_reg_t prio86; // [379:378] + rv_plic_reg2hw_prio87_reg_t prio87; // [377:376] + rv_plic_reg2hw_prio88_reg_t prio88; // [375:374] + rv_plic_reg2hw_prio89_reg_t prio89; // [373:372] + rv_plic_reg2hw_prio90_reg_t prio90; // [371:370] + rv_plic_reg2hw_prio91_reg_t prio91; // [369:368] + rv_plic_reg2hw_prio92_reg_t prio92; // [367:366] + rv_plic_reg2hw_prio93_reg_t prio93; // [365:364] + rv_plic_reg2hw_prio94_reg_t prio94; // [363:362] + rv_plic_reg2hw_prio95_reg_t prio95; // [361:360] + rv_plic_reg2hw_prio96_reg_t prio96; // [359:358] + rv_plic_reg2hw_prio97_reg_t prio97; // [357:356] + rv_plic_reg2hw_prio98_reg_t prio98; // [355:354] + rv_plic_reg2hw_prio99_reg_t prio99; // [353:352] + rv_plic_reg2hw_prio100_reg_t prio100; // [351:350] + rv_plic_reg2hw_prio101_reg_t prio101; // [349:348] + rv_plic_reg2hw_prio102_reg_t prio102; // [347:346] + rv_plic_reg2hw_prio103_reg_t prio103; // [345:344] + rv_plic_reg2hw_prio104_reg_t prio104; // [343:342] + rv_plic_reg2hw_prio105_reg_t prio105; // [341:340] + rv_plic_reg2hw_prio106_reg_t prio106; // [339:338] + rv_plic_reg2hw_prio107_reg_t prio107; // [337:336] + rv_plic_reg2hw_prio108_reg_t prio108; // [335:334] + rv_plic_reg2hw_prio109_reg_t prio109; // [333:332] + rv_plic_reg2hw_prio110_reg_t prio110; // [331:330] + rv_plic_reg2hw_prio111_reg_t prio111; // [329:328] + rv_plic_reg2hw_prio112_reg_t prio112; // [327:326] + rv_plic_reg2hw_prio113_reg_t prio113; // [325:324] + rv_plic_reg2hw_prio114_reg_t prio114; // [323:322] + rv_plic_reg2hw_prio115_reg_t prio115; // [321:320] + rv_plic_reg2hw_prio116_reg_t prio116; // [319:318] + rv_plic_reg2hw_prio117_reg_t prio117; // [317:316] + rv_plic_reg2hw_prio118_reg_t prio118; // [315:314] + rv_plic_reg2hw_prio119_reg_t prio119; // [313:312] + rv_plic_reg2hw_prio120_reg_t prio120; // [311:310] + rv_plic_reg2hw_prio121_reg_t prio121; // [309:308] + rv_plic_reg2hw_prio122_reg_t prio122; // [307:306] + rv_plic_reg2hw_prio123_reg_t prio123; // [305:304] + rv_plic_reg2hw_prio124_reg_t prio124; // [303:302] + rv_plic_reg2hw_prio125_reg_t prio125; // [301:300] + rv_plic_reg2hw_prio126_reg_t prio126; // [299:298] + rv_plic_reg2hw_prio127_reg_t prio127; // [297:296] + rv_plic_reg2hw_prio128_reg_t prio128; // [295:294] + rv_plic_reg2hw_prio129_reg_t prio129; // [293:292] + rv_plic_reg2hw_prio130_reg_t prio130; // [291:290] + rv_plic_reg2hw_prio131_reg_t prio131; // [289:288] + rv_plic_reg2hw_prio132_reg_t prio132; // [287:286] + rv_plic_reg2hw_prio133_reg_t prio133; // [285:284] + rv_plic_reg2hw_prio134_reg_t prio134; // [283:282] + rv_plic_reg2hw_prio135_reg_t prio135; // [281:280] + rv_plic_reg2hw_prio136_reg_t prio136; // [279:278] + rv_plic_reg2hw_prio137_reg_t prio137; // [277:276] + rv_plic_reg2hw_prio138_reg_t prio138; // [275:274] + rv_plic_reg2hw_prio139_reg_t prio139; // [273:272] + rv_plic_reg2hw_prio140_reg_t prio140; // [271:270] + rv_plic_reg2hw_prio141_reg_t prio141; // [269:268] + rv_plic_reg2hw_prio142_reg_t prio142; // [267:266] + rv_plic_reg2hw_prio143_reg_t prio143; // [265:264] + rv_plic_reg2hw_prio144_reg_t prio144; // [263:262] + rv_plic_reg2hw_prio145_reg_t prio145; // [261:260] + rv_plic_reg2hw_prio146_reg_t prio146; // [259:258] + rv_plic_reg2hw_prio147_reg_t prio147; // [257:256] + rv_plic_reg2hw_prio148_reg_t prio148; // [255:254] + rv_plic_reg2hw_prio149_reg_t prio149; // [253:252] + rv_plic_reg2hw_prio150_reg_t prio150; // [251:250] + rv_plic_reg2hw_prio151_reg_t prio151; // [249:248] + rv_plic_reg2hw_prio152_reg_t prio152; // [247:246] + rv_plic_reg2hw_prio153_reg_t prio153; // [245:244] + rv_plic_reg2hw_prio154_reg_t prio154; // [243:242] + rv_plic_reg2hw_prio155_reg_t prio155; // [241:240] + rv_plic_reg2hw_prio156_reg_t prio156; // [239:238] + rv_plic_reg2hw_prio157_reg_t prio157; // [237:236] + rv_plic_reg2hw_prio158_reg_t prio158; // [235:234] + rv_plic_reg2hw_prio159_reg_t prio159; // [233:232] + rv_plic_reg2hw_prio160_reg_t prio160; // [231:230] + rv_plic_reg2hw_prio161_reg_t prio161; // [229:228] + rv_plic_reg2hw_prio162_reg_t prio162; // [227:226] + rv_plic_reg2hw_prio163_reg_t prio163; // [225:224] + rv_plic_reg2hw_prio164_reg_t prio164; // [223:222] + rv_plic_reg2hw_prio165_reg_t prio165; // [221:220] + rv_plic_reg2hw_prio166_reg_t prio166; // [219:218] + rv_plic_reg2hw_prio167_reg_t prio167; // [217:216] + rv_plic_reg2hw_prio168_reg_t prio168; // [215:214] + rv_plic_reg2hw_prio169_reg_t prio169; // [213:212] + rv_plic_reg2hw_prio170_reg_t prio170; // [211:210] + rv_plic_reg2hw_prio171_reg_t prio171; // [209:208] + rv_plic_reg2hw_prio172_reg_t prio172; // [207:206] + rv_plic_reg2hw_prio173_reg_t prio173; // [205:204] + rv_plic_reg2hw_prio174_reg_t prio174; // [203:202] + rv_plic_reg2hw_prio175_reg_t prio175; // [201:200] + rv_plic_reg2hw_prio176_reg_t prio176; // [199:198] + rv_plic_reg2hw_prio177_reg_t prio177; // [197:196] + rv_plic_reg2hw_prio178_reg_t prio178; // [195:194] + rv_plic_reg2hw_ie0_mreg_t [178:0] ie0; // [193:15] rv_plic_reg2hw_threshold0_reg_t threshold0; // [14:13] rv_plic_reg2hw_cc0_reg_t cc0; // [12:3] rv_plic_reg2hw_msip0_reg_t msip0; // [2:2] @@ -987,7 +957,7 @@ package rv_plic_reg_pkg; // HW -> register type typedef struct packed { - rv_plic_hw2reg_ip_mreg_t [184:0] ip; // [377:8] + rv_plic_hw2reg_ip_mreg_t [178:0] ip; // [365:8] rv_plic_hw2reg_cc0_reg_t cc0; // [7:0] } rv_plic_hw2reg_t; @@ -1171,12 +1141,6 @@ package rv_plic_reg_pkg; parameter logic [BlockAw-1:0] RV_PLIC_PRIO176_OFFSET = 27'h 2c0; parameter logic [BlockAw-1:0] RV_PLIC_PRIO177_OFFSET = 27'h 2c4; parameter logic [BlockAw-1:0] RV_PLIC_PRIO178_OFFSET = 27'h 2c8; - parameter logic [BlockAw-1:0] RV_PLIC_PRIO179_OFFSET = 27'h 2cc; - parameter logic [BlockAw-1:0] RV_PLIC_PRIO180_OFFSET = 27'h 2d0; - parameter logic [BlockAw-1:0] RV_PLIC_PRIO181_OFFSET = 27'h 2d4; - parameter logic [BlockAw-1:0] RV_PLIC_PRIO182_OFFSET = 27'h 2d8; - parameter logic [BlockAw-1:0] RV_PLIC_PRIO183_OFFSET = 27'h 2dc; - parameter logic [BlockAw-1:0] RV_PLIC_PRIO184_OFFSET = 27'h 2e0; parameter logic [BlockAw-1:0] RV_PLIC_IP_0_OFFSET = 27'h 1000; parameter logic [BlockAw-1:0] RV_PLIC_IP_1_OFFSET = 27'h 1004; parameter logic [BlockAw-1:0] RV_PLIC_IP_2_OFFSET = 27'h 1008; @@ -1379,12 +1343,6 @@ package rv_plic_reg_pkg; RV_PLIC_PRIO176, RV_PLIC_PRIO177, RV_PLIC_PRIO178, - RV_PLIC_PRIO179, - RV_PLIC_PRIO180, - RV_PLIC_PRIO181, - RV_PLIC_PRIO182, - RV_PLIC_PRIO183, - RV_PLIC_PRIO184, RV_PLIC_IP_0, RV_PLIC_IP_1, RV_PLIC_IP_2, @@ -1404,7 +1362,7 @@ package rv_plic_reg_pkg; } rv_plic_id_e; // Register width information to check illegal writes - parameter logic [3:0] RV_PLIC_PERMIT [201] = '{ + parameter logic [3:0] RV_PLIC_PERMIT [195] = '{ 4'b 0001, // index[ 0] RV_PLIC_PRIO0 4'b 0001, // index[ 1] RV_PLIC_PRIO1 4'b 0001, // index[ 2] RV_PLIC_PRIO2 @@ -1584,28 +1542,22 @@ package rv_plic_reg_pkg; 4'b 0001, // index[176] RV_PLIC_PRIO176 4'b 0001, // index[177] RV_PLIC_PRIO177 4'b 0001, // index[178] RV_PLIC_PRIO178 - 4'b 0001, // index[179] RV_PLIC_PRIO179 - 4'b 0001, // index[180] RV_PLIC_PRIO180 - 4'b 0001, // index[181] RV_PLIC_PRIO181 - 4'b 0001, // index[182] RV_PLIC_PRIO182 - 4'b 0001, // index[183] RV_PLIC_PRIO183 - 4'b 0001, // index[184] RV_PLIC_PRIO184 - 4'b 1111, // index[185] RV_PLIC_IP_0 - 4'b 1111, // index[186] RV_PLIC_IP_1 - 4'b 1111, // index[187] RV_PLIC_IP_2 - 4'b 1111, // index[188] RV_PLIC_IP_3 - 4'b 1111, // index[189] RV_PLIC_IP_4 - 4'b 1111, // index[190] RV_PLIC_IP_5 - 4'b 1111, // index[191] RV_PLIC_IE0_0 - 4'b 1111, // index[192] RV_PLIC_IE0_1 - 4'b 1111, // index[193] RV_PLIC_IE0_2 - 4'b 1111, // index[194] RV_PLIC_IE0_3 - 4'b 1111, // index[195] RV_PLIC_IE0_4 - 4'b 1111, // index[196] RV_PLIC_IE0_5 - 4'b 0001, // index[197] RV_PLIC_THRESHOLD0 - 4'b 0001, // index[198] RV_PLIC_CC0 - 4'b 0001, // index[199] RV_PLIC_MSIP0 - 4'b 0001 // index[200] RV_PLIC_ALERT_TEST + 4'b 1111, // index[179] RV_PLIC_IP_0 + 4'b 1111, // index[180] RV_PLIC_IP_1 + 4'b 1111, // index[181] RV_PLIC_IP_2 + 4'b 1111, // index[182] RV_PLIC_IP_3 + 4'b 1111, // index[183] RV_PLIC_IP_4 + 4'b 0111, // index[184] RV_PLIC_IP_5 + 4'b 1111, // index[185] RV_PLIC_IE0_0 + 4'b 1111, // index[186] RV_PLIC_IE0_1 + 4'b 1111, // index[187] RV_PLIC_IE0_2 + 4'b 1111, // index[188] RV_PLIC_IE0_3 + 4'b 1111, // index[189] RV_PLIC_IE0_4 + 4'b 0111, // index[190] RV_PLIC_IE0_5 + 4'b 0001, // index[191] RV_PLIC_THRESHOLD0 + 4'b 0001, // index[192] RV_PLIC_CC0 + 4'b 0001, // index[193] RV_PLIC_MSIP0 + 4'b 0001 // index[194] RV_PLIC_ALERT_TEST }; endpackage diff --git a/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic_reg_top.sv b/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic_reg_top.sv index 46d746decd152..6e269ad4dd178 100644 --- a/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic_reg_top.sv +++ b/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic_reg_top.sv @@ -52,9 +52,9 @@ module rv_plic_reg_top ( // also check for spurious write enables logic reg_we_err; - logic [200:0] reg_we_check; + logic [194:0] reg_we_check; prim_reg_we_check #( - .OneHotWidth(201) + .OneHotWidth(195) ) u_prim_reg_we_check ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -658,24 +658,6 @@ module rv_plic_reg_top ( logic prio178_we; logic [1:0] prio178_qs; logic [1:0] prio178_wd; - logic prio179_we; - logic [1:0] prio179_qs; - logic [1:0] prio179_wd; - logic prio180_we; - logic [1:0] prio180_qs; - logic [1:0] prio180_wd; - logic prio181_we; - logic [1:0] prio181_qs; - logic [1:0] prio181_wd; - logic prio182_we; - logic [1:0] prio182_qs; - logic [1:0] prio182_wd; - logic prio183_we; - logic [1:0] prio183_qs; - logic [1:0] prio183_wd; - logic prio184_we; - logic [1:0] prio184_qs; - logic [1:0] prio184_wd; logic ip_0_p_0_qs; logic ip_0_p_1_qs; logic ip_0_p_2_qs; @@ -855,12 +837,6 @@ module rv_plic_reg_top ( logic ip_5_p_176_qs; logic ip_5_p_177_qs; logic ip_5_p_178_qs; - logic ip_5_p_179_qs; - logic ip_5_p_180_qs; - logic ip_5_p_181_qs; - logic ip_5_p_182_qs; - logic ip_5_p_183_qs; - logic ip_5_p_184_qs; logic ie0_0_we; logic ie0_0_e_0_qs; logic ie0_0_e_0_wd; @@ -1225,18 +1201,6 @@ module rv_plic_reg_top ( logic ie0_5_e_177_wd; logic ie0_5_e_178_qs; logic ie0_5_e_178_wd; - logic ie0_5_e_179_qs; - logic ie0_5_e_179_wd; - logic ie0_5_e_180_qs; - logic ie0_5_e_180_wd; - logic ie0_5_e_181_qs; - logic ie0_5_e_181_wd; - logic ie0_5_e_182_qs; - logic ie0_5_e_182_wd; - logic ie0_5_e_183_qs; - logic ie0_5_e_183_wd; - logic ie0_5_e_184_qs; - logic ie0_5_e_184_wd; logic threshold0_we; logic [1:0] threshold0_qs; logic [1:0] threshold0_wd; @@ -6263,174 +6227,6 @@ module rv_plic_reg_top ( ); - // R[prio179]: V(False) - prim_subreg #( - .DW (2), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (2'h0), - .Mubi (1'b0) - ) u_prio179 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (prio179_we), - .wd (prio179_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.prio179.q), - .ds (), - - // to register interface (read) - .qs (prio179_qs) - ); - - - // R[prio180]: V(False) - prim_subreg #( - .DW (2), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (2'h0), - .Mubi (1'b0) - ) u_prio180 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (prio180_we), - .wd (prio180_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.prio180.q), - .ds (), - - // to register interface (read) - .qs (prio180_qs) - ); - - - // R[prio181]: V(False) - prim_subreg #( - .DW (2), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (2'h0), - .Mubi (1'b0) - ) u_prio181 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (prio181_we), - .wd (prio181_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.prio181.q), - .ds (), - - // to register interface (read) - .qs (prio181_qs) - ); - - - // R[prio182]: V(False) - prim_subreg #( - .DW (2), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (2'h0), - .Mubi (1'b0) - ) u_prio182 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (prio182_we), - .wd (prio182_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.prio182.q), - .ds (), - - // to register interface (read) - .qs (prio182_qs) - ); - - - // R[prio183]: V(False) - prim_subreg #( - .DW (2), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (2'h0), - .Mubi (1'b0) - ) u_prio183 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (prio183_we), - .wd (prio183_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.prio183.q), - .ds (), - - // to register interface (read) - .qs (prio183_qs) - ); - - - // R[prio184]: V(False) - prim_subreg #( - .DW (2), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (2'h0), - .Mubi (1'b0) - ) u_prio184 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (prio184_we), - .wd (prio184_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.prio184.q), - .ds (), - - // to register interface (read) - .qs (prio184_qs) - ); - - // Subregister 0 of Multireg ip // R[ip_0]: V(False) // F[p_0]: 0:0 @@ -11281,168 +11077,6 @@ module rv_plic_reg_top ( .qs (ip_5_p_178_qs) ); - // F[p_179]: 19:19 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ip_5_p_179 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.ip[179].de), - .d (hw2reg.ip[179].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (ip_5_p_179_qs) - ); - - // F[p_180]: 20:20 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ip_5_p_180 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.ip[180].de), - .d (hw2reg.ip[180].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (ip_5_p_180_qs) - ); - - // F[p_181]: 21:21 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ip_5_p_181 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.ip[181].de), - .d (hw2reg.ip[181].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (ip_5_p_181_qs) - ); - - // F[p_182]: 22:22 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ip_5_p_182 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.ip[182].de), - .d (hw2reg.ip[182].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (ip_5_p_182_qs) - ); - - // F[p_183]: 23:23 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ip_5_p_183 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.ip[183].de), - .d (hw2reg.ip[183].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (ip_5_p_183_qs) - ); - - // F[p_184]: 24:24 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ip_5_p_184 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.ip[184].de), - .d (hw2reg.ip[184].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (ip_5_p_184_qs) - ); - // Subregister 0 of Multireg ie0 // R[ie0_0]: V(False) @@ -16294,168 +15928,6 @@ module rv_plic_reg_top ( .qs (ie0_5_e_178_qs) ); - // F[e_179]: 19:19 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ie0_5_e_179 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (ie0_5_we), - .wd (ie0_5_e_179_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.ie0[179].q), - .ds (), - - // to register interface (read) - .qs (ie0_5_e_179_qs) - ); - - // F[e_180]: 20:20 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ie0_5_e_180 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (ie0_5_we), - .wd (ie0_5_e_180_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.ie0[180].q), - .ds (), - - // to register interface (read) - .qs (ie0_5_e_180_qs) - ); - - // F[e_181]: 21:21 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ie0_5_e_181 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (ie0_5_we), - .wd (ie0_5_e_181_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.ie0[181].q), - .ds (), - - // to register interface (read) - .qs (ie0_5_e_181_qs) - ); - - // F[e_182]: 22:22 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ie0_5_e_182 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (ie0_5_we), - .wd (ie0_5_e_182_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.ie0[182].q), - .ds (), - - // to register interface (read) - .qs (ie0_5_e_182_qs) - ); - - // F[e_183]: 23:23 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ie0_5_e_183 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (ie0_5_we), - .wd (ie0_5_e_183_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.ie0[183].q), - .ds (), - - // to register interface (read) - .qs (ie0_5_e_183_qs) - ); - - // F[e_184]: 24:24 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_ie0_5_e_184 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (ie0_5_we), - .wd (ie0_5_e_184_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.ie0[184].q), - .ds (), - - // to register interface (read) - .qs (ie0_5_e_184_qs) - ); - // R[threshold0]: V(False) prim_subreg #( @@ -16554,7 +16026,7 @@ module rv_plic_reg_top ( - logic [200:0] addr_hit; + logic [194:0] addr_hit; always_comb begin addr_hit = '0; addr_hit[ 0] = (reg_addr == RV_PLIC_PRIO0_OFFSET); @@ -16736,28 +16208,22 @@ module rv_plic_reg_top ( addr_hit[176] = (reg_addr == RV_PLIC_PRIO176_OFFSET); addr_hit[177] = (reg_addr == RV_PLIC_PRIO177_OFFSET); addr_hit[178] = (reg_addr == RV_PLIC_PRIO178_OFFSET); - addr_hit[179] = (reg_addr == RV_PLIC_PRIO179_OFFSET); - addr_hit[180] = (reg_addr == RV_PLIC_PRIO180_OFFSET); - addr_hit[181] = (reg_addr == RV_PLIC_PRIO181_OFFSET); - addr_hit[182] = (reg_addr == RV_PLIC_PRIO182_OFFSET); - addr_hit[183] = (reg_addr == RV_PLIC_PRIO183_OFFSET); - addr_hit[184] = (reg_addr == RV_PLIC_PRIO184_OFFSET); - addr_hit[185] = (reg_addr == RV_PLIC_IP_0_OFFSET); - addr_hit[186] = (reg_addr == RV_PLIC_IP_1_OFFSET); - addr_hit[187] = (reg_addr == RV_PLIC_IP_2_OFFSET); - addr_hit[188] = (reg_addr == RV_PLIC_IP_3_OFFSET); - addr_hit[189] = (reg_addr == RV_PLIC_IP_4_OFFSET); - addr_hit[190] = (reg_addr == RV_PLIC_IP_5_OFFSET); - addr_hit[191] = (reg_addr == RV_PLIC_IE0_0_OFFSET); - addr_hit[192] = (reg_addr == RV_PLIC_IE0_1_OFFSET); - addr_hit[193] = (reg_addr == RV_PLIC_IE0_2_OFFSET); - addr_hit[194] = (reg_addr == RV_PLIC_IE0_3_OFFSET); - addr_hit[195] = (reg_addr == RV_PLIC_IE0_4_OFFSET); - addr_hit[196] = (reg_addr == RV_PLIC_IE0_5_OFFSET); - addr_hit[197] = (reg_addr == RV_PLIC_THRESHOLD0_OFFSET); - addr_hit[198] = (reg_addr == RV_PLIC_CC0_OFFSET); - addr_hit[199] = (reg_addr == RV_PLIC_MSIP0_OFFSET); - addr_hit[200] = (reg_addr == RV_PLIC_ALERT_TEST_OFFSET); + addr_hit[179] = (reg_addr == RV_PLIC_IP_0_OFFSET); + addr_hit[180] = (reg_addr == RV_PLIC_IP_1_OFFSET); + addr_hit[181] = (reg_addr == RV_PLIC_IP_2_OFFSET); + addr_hit[182] = (reg_addr == RV_PLIC_IP_3_OFFSET); + addr_hit[183] = (reg_addr == RV_PLIC_IP_4_OFFSET); + addr_hit[184] = (reg_addr == RV_PLIC_IP_5_OFFSET); + addr_hit[185] = (reg_addr == RV_PLIC_IE0_0_OFFSET); + addr_hit[186] = (reg_addr == RV_PLIC_IE0_1_OFFSET); + addr_hit[187] = (reg_addr == RV_PLIC_IE0_2_OFFSET); + addr_hit[188] = (reg_addr == RV_PLIC_IE0_3_OFFSET); + addr_hit[189] = (reg_addr == RV_PLIC_IE0_4_OFFSET); + addr_hit[190] = (reg_addr == RV_PLIC_IE0_5_OFFSET); + addr_hit[191] = (reg_addr == RV_PLIC_THRESHOLD0_OFFSET); + addr_hit[192] = (reg_addr == RV_PLIC_CC0_OFFSET); + addr_hit[193] = (reg_addr == RV_PLIC_MSIP0_OFFSET); + addr_hit[194] = (reg_addr == RV_PLIC_ALERT_TEST_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -16959,13 +16425,7 @@ module rv_plic_reg_top ( (addr_hit[191] & (|(RV_PLIC_PERMIT[191] & ~reg_be))) | (addr_hit[192] & (|(RV_PLIC_PERMIT[192] & ~reg_be))) | (addr_hit[193] & (|(RV_PLIC_PERMIT[193] & ~reg_be))) | - (addr_hit[194] & (|(RV_PLIC_PERMIT[194] & ~reg_be))) | - (addr_hit[195] & (|(RV_PLIC_PERMIT[195] & ~reg_be))) | - (addr_hit[196] & (|(RV_PLIC_PERMIT[196] & ~reg_be))) | - (addr_hit[197] & (|(RV_PLIC_PERMIT[197] & ~reg_be))) | - (addr_hit[198] & (|(RV_PLIC_PERMIT[198] & ~reg_be))) | - (addr_hit[199] & (|(RV_PLIC_PERMIT[199] & ~reg_be))) | - (addr_hit[200] & (|(RV_PLIC_PERMIT[200] & ~reg_be))))); + (addr_hit[194] & (|(RV_PLIC_PERMIT[194] & ~reg_be))))); end // Generate write-enables @@ -17506,25 +16966,7 @@ module rv_plic_reg_top ( assign prio178_we = addr_hit[178] & reg_we & !reg_error; assign prio178_wd = reg_wdata[1:0]; - assign prio179_we = addr_hit[179] & reg_we & !reg_error; - - assign prio179_wd = reg_wdata[1:0]; - assign prio180_we = addr_hit[180] & reg_we & !reg_error; - - assign prio180_wd = reg_wdata[1:0]; - assign prio181_we = addr_hit[181] & reg_we & !reg_error; - - assign prio181_wd = reg_wdata[1:0]; - assign prio182_we = addr_hit[182] & reg_we & !reg_error; - - assign prio182_wd = reg_wdata[1:0]; - assign prio183_we = addr_hit[183] & reg_we & !reg_error; - - assign prio183_wd = reg_wdata[1:0]; - assign prio184_we = addr_hit[184] & reg_we & !reg_error; - - assign prio184_wd = reg_wdata[1:0]; - assign ie0_0_we = addr_hit[191] & reg_we & !reg_error; + assign ie0_0_we = addr_hit[185] & reg_we & !reg_error; assign ie0_0_e_0_wd = reg_wdata[0]; @@ -17589,7 +17031,7 @@ module rv_plic_reg_top ( assign ie0_0_e_30_wd = reg_wdata[30]; assign ie0_0_e_31_wd = reg_wdata[31]; - assign ie0_1_we = addr_hit[192] & reg_we & !reg_error; + assign ie0_1_we = addr_hit[186] & reg_we & !reg_error; assign ie0_1_e_32_wd = reg_wdata[0]; @@ -17654,7 +17096,7 @@ module rv_plic_reg_top ( assign ie0_1_e_62_wd = reg_wdata[30]; assign ie0_1_e_63_wd = reg_wdata[31]; - assign ie0_2_we = addr_hit[193] & reg_we & !reg_error; + assign ie0_2_we = addr_hit[187] & reg_we & !reg_error; assign ie0_2_e_64_wd = reg_wdata[0]; @@ -17719,7 +17161,7 @@ module rv_plic_reg_top ( assign ie0_2_e_94_wd = reg_wdata[30]; assign ie0_2_e_95_wd = reg_wdata[31]; - assign ie0_3_we = addr_hit[194] & reg_we & !reg_error; + assign ie0_3_we = addr_hit[188] & reg_we & !reg_error; assign ie0_3_e_96_wd = reg_wdata[0]; @@ -17784,7 +17226,7 @@ module rv_plic_reg_top ( assign ie0_3_e_126_wd = reg_wdata[30]; assign ie0_3_e_127_wd = reg_wdata[31]; - assign ie0_4_we = addr_hit[195] & reg_we & !reg_error; + assign ie0_4_we = addr_hit[189] & reg_we & !reg_error; assign ie0_4_e_128_wd = reg_wdata[0]; @@ -17849,7 +17291,7 @@ module rv_plic_reg_top ( assign ie0_4_e_158_wd = reg_wdata[30]; assign ie0_4_e_159_wd = reg_wdata[31]; - assign ie0_5_we = addr_hit[196] & reg_we & !reg_error; + assign ie0_5_we = addr_hit[190] & reg_we & !reg_error; assign ie0_5_e_160_wd = reg_wdata[0]; @@ -17888,29 +17330,17 @@ module rv_plic_reg_top ( assign ie0_5_e_177_wd = reg_wdata[17]; assign ie0_5_e_178_wd = reg_wdata[18]; - - assign ie0_5_e_179_wd = reg_wdata[19]; - - assign ie0_5_e_180_wd = reg_wdata[20]; - - assign ie0_5_e_181_wd = reg_wdata[21]; - - assign ie0_5_e_182_wd = reg_wdata[22]; - - assign ie0_5_e_183_wd = reg_wdata[23]; - - assign ie0_5_e_184_wd = reg_wdata[24]; - assign threshold0_we = addr_hit[197] & reg_we & !reg_error; + assign threshold0_we = addr_hit[191] & reg_we & !reg_error; assign threshold0_wd = reg_wdata[1:0]; - assign cc0_re = addr_hit[198] & reg_re & !reg_error; - assign cc0_we = addr_hit[198] & reg_we & !reg_error; + assign cc0_re = addr_hit[192] & reg_re & !reg_error; + assign cc0_we = addr_hit[192] & reg_we & !reg_error; assign cc0_wd = reg_wdata[7:0]; - assign msip0_we = addr_hit[199] & reg_we & !reg_error; + assign msip0_we = addr_hit[193] & reg_we & !reg_error; assign msip0_wd = reg_wdata[0]; - assign alert_test_we = addr_hit[200] & reg_we & !reg_error; + assign alert_test_we = addr_hit[194] & reg_we & !reg_error; assign alert_test_wd = reg_wdata[0]; @@ -18096,28 +17526,22 @@ module rv_plic_reg_top ( reg_we_check[176] = prio176_we; reg_we_check[177] = prio177_we; reg_we_check[178] = prio178_we; - reg_we_check[179] = prio179_we; - reg_we_check[180] = prio180_we; - reg_we_check[181] = prio181_we; - reg_we_check[182] = prio182_we; - reg_we_check[183] = prio183_we; - reg_we_check[184] = prio184_we; - reg_we_check[185] = 1'b0; - reg_we_check[186] = 1'b0; - reg_we_check[187] = 1'b0; - reg_we_check[188] = 1'b0; - reg_we_check[189] = 1'b0; - reg_we_check[190] = 1'b0; - reg_we_check[191] = ie0_0_we; - reg_we_check[192] = ie0_1_we; - reg_we_check[193] = ie0_2_we; - reg_we_check[194] = ie0_3_we; - reg_we_check[195] = ie0_4_we; - reg_we_check[196] = ie0_5_we; - reg_we_check[197] = threshold0_we; - reg_we_check[198] = cc0_we; - reg_we_check[199] = msip0_we; - reg_we_check[200] = alert_test_we; + reg_we_check[179] = 1'b0; + reg_we_check[180] = 1'b0; + reg_we_check[181] = 1'b0; + reg_we_check[182] = 1'b0; + reg_we_check[183] = 1'b0; + reg_we_check[184] = 1'b0; + reg_we_check[185] = ie0_0_we; + reg_we_check[186] = ie0_1_we; + reg_we_check[187] = ie0_2_we; + reg_we_check[188] = ie0_3_we; + reg_we_check[189] = ie0_4_we; + reg_we_check[190] = ie0_5_we; + reg_we_check[191] = threshold0_we; + reg_we_check[192] = cc0_we; + reg_we_check[193] = msip0_we; + reg_we_check[194] = alert_test_we; end // Read data return @@ -18841,30 +18265,6 @@ module rv_plic_reg_top ( end addr_hit[179]: begin - reg_rdata_next[1:0] = prio179_qs; - end - - addr_hit[180]: begin - reg_rdata_next[1:0] = prio180_qs; - end - - addr_hit[181]: begin - reg_rdata_next[1:0] = prio181_qs; - end - - addr_hit[182]: begin - reg_rdata_next[1:0] = prio182_qs; - end - - addr_hit[183]: begin - reg_rdata_next[1:0] = prio183_qs; - end - - addr_hit[184]: begin - reg_rdata_next[1:0] = prio184_qs; - end - - addr_hit[185]: begin reg_rdata_next[0] = ip_0_p_0_qs; reg_rdata_next[1] = ip_0_p_1_qs; reg_rdata_next[2] = ip_0_p_2_qs; @@ -18899,7 +18299,7 @@ module rv_plic_reg_top ( reg_rdata_next[31] = ip_0_p_31_qs; end - addr_hit[186]: begin + addr_hit[180]: begin reg_rdata_next[0] = ip_1_p_32_qs; reg_rdata_next[1] = ip_1_p_33_qs; reg_rdata_next[2] = ip_1_p_34_qs; @@ -18934,7 +18334,7 @@ module rv_plic_reg_top ( reg_rdata_next[31] = ip_1_p_63_qs; end - addr_hit[187]: begin + addr_hit[181]: begin reg_rdata_next[0] = ip_2_p_64_qs; reg_rdata_next[1] = ip_2_p_65_qs; reg_rdata_next[2] = ip_2_p_66_qs; @@ -18969,7 +18369,7 @@ module rv_plic_reg_top ( reg_rdata_next[31] = ip_2_p_95_qs; end - addr_hit[188]: begin + addr_hit[182]: begin reg_rdata_next[0] = ip_3_p_96_qs; reg_rdata_next[1] = ip_3_p_97_qs; reg_rdata_next[2] = ip_3_p_98_qs; @@ -19004,7 +18404,7 @@ module rv_plic_reg_top ( reg_rdata_next[31] = ip_3_p_127_qs; end - addr_hit[189]: begin + addr_hit[183]: begin reg_rdata_next[0] = ip_4_p_128_qs; reg_rdata_next[1] = ip_4_p_129_qs; reg_rdata_next[2] = ip_4_p_130_qs; @@ -19039,7 +18439,7 @@ module rv_plic_reg_top ( reg_rdata_next[31] = ip_4_p_159_qs; end - addr_hit[190]: begin + addr_hit[184]: begin reg_rdata_next[0] = ip_5_p_160_qs; reg_rdata_next[1] = ip_5_p_161_qs; reg_rdata_next[2] = ip_5_p_162_qs; @@ -19059,15 +18459,9 @@ module rv_plic_reg_top ( reg_rdata_next[16] = ip_5_p_176_qs; reg_rdata_next[17] = ip_5_p_177_qs; reg_rdata_next[18] = ip_5_p_178_qs; - reg_rdata_next[19] = ip_5_p_179_qs; - reg_rdata_next[20] = ip_5_p_180_qs; - reg_rdata_next[21] = ip_5_p_181_qs; - reg_rdata_next[22] = ip_5_p_182_qs; - reg_rdata_next[23] = ip_5_p_183_qs; - reg_rdata_next[24] = ip_5_p_184_qs; end - addr_hit[191]: begin + addr_hit[185]: begin reg_rdata_next[0] = ie0_0_e_0_qs; reg_rdata_next[1] = ie0_0_e_1_qs; reg_rdata_next[2] = ie0_0_e_2_qs; @@ -19102,7 +18496,7 @@ module rv_plic_reg_top ( reg_rdata_next[31] = ie0_0_e_31_qs; end - addr_hit[192]: begin + addr_hit[186]: begin reg_rdata_next[0] = ie0_1_e_32_qs; reg_rdata_next[1] = ie0_1_e_33_qs; reg_rdata_next[2] = ie0_1_e_34_qs; @@ -19137,7 +18531,7 @@ module rv_plic_reg_top ( reg_rdata_next[31] = ie0_1_e_63_qs; end - addr_hit[193]: begin + addr_hit[187]: begin reg_rdata_next[0] = ie0_2_e_64_qs; reg_rdata_next[1] = ie0_2_e_65_qs; reg_rdata_next[2] = ie0_2_e_66_qs; @@ -19172,7 +18566,7 @@ module rv_plic_reg_top ( reg_rdata_next[31] = ie0_2_e_95_qs; end - addr_hit[194]: begin + addr_hit[188]: begin reg_rdata_next[0] = ie0_3_e_96_qs; reg_rdata_next[1] = ie0_3_e_97_qs; reg_rdata_next[2] = ie0_3_e_98_qs; @@ -19207,7 +18601,7 @@ module rv_plic_reg_top ( reg_rdata_next[31] = ie0_3_e_127_qs; end - addr_hit[195]: begin + addr_hit[189]: begin reg_rdata_next[0] = ie0_4_e_128_qs; reg_rdata_next[1] = ie0_4_e_129_qs; reg_rdata_next[2] = ie0_4_e_130_qs; @@ -19242,7 +18636,7 @@ module rv_plic_reg_top ( reg_rdata_next[31] = ie0_4_e_159_qs; end - addr_hit[196]: begin + addr_hit[190]: begin reg_rdata_next[0] = ie0_5_e_160_qs; reg_rdata_next[1] = ie0_5_e_161_qs; reg_rdata_next[2] = ie0_5_e_162_qs; @@ -19262,27 +18656,21 @@ module rv_plic_reg_top ( reg_rdata_next[16] = ie0_5_e_176_qs; reg_rdata_next[17] = ie0_5_e_177_qs; reg_rdata_next[18] = ie0_5_e_178_qs; - reg_rdata_next[19] = ie0_5_e_179_qs; - reg_rdata_next[20] = ie0_5_e_180_qs; - reg_rdata_next[21] = ie0_5_e_181_qs; - reg_rdata_next[22] = ie0_5_e_182_qs; - reg_rdata_next[23] = ie0_5_e_183_qs; - reg_rdata_next[24] = ie0_5_e_184_qs; end - addr_hit[197]: begin + addr_hit[191]: begin reg_rdata_next[1:0] = threshold0_qs; end - addr_hit[198]: begin + addr_hit[192]: begin reg_rdata_next[7:0] = cc0_qs; end - addr_hit[199]: begin + addr_hit[193]: begin reg_rdata_next[0] = msip0_qs; end - addr_hit[200]: begin + addr_hit[194]: begin reg_rdata_next[0] = '0; end diff --git a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv index 35a88b0250df5..82247aba69167 100644 --- a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv +++ b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv @@ -365,7 +365,7 @@ module top_earlgrey #( // rv_core_ibex - logic [184:0] intr_vector; + logic [178:0] intr_vector; // Interrupt source list logic intr_uart0_tx_watermark; logic intr_uart0_rx_watermark; @@ -400,12 +400,6 @@ module top_earlgrey #( logic intr_uart3_rx_timeout; logic intr_uart3_rx_parity_err; logic [31:0] intr_gpio_gpio; - logic intr_spi_device_generic_rx_full; - logic intr_spi_device_generic_rx_watermark; - logic intr_spi_device_generic_tx_watermark; - logic intr_spi_device_generic_rx_error; - logic intr_spi_device_generic_rx_overflow; - logic intr_spi_device_generic_tx_underflow; logic intr_spi_device_upload_cmdfifo_not_empty; logic intr_spi_device_upload_payload_not_empty; logic intr_spi_device_upload_payload_overflow; @@ -1184,12 +1178,6 @@ module top_earlgrey #( .cio_sd_en_o (cio_spi_device_sd_en_d2p), // Interrupt - .intr_generic_rx_full_o (intr_spi_device_generic_rx_full), - .intr_generic_rx_watermark_o (intr_spi_device_generic_rx_watermark), - .intr_generic_tx_watermark_o (intr_spi_device_generic_tx_watermark), - .intr_generic_rx_error_o (intr_spi_device_generic_rx_error), - .intr_generic_rx_overflow_o (intr_spi_device_generic_rx_overflow), - .intr_generic_tx_underflow_o (intr_spi_device_generic_tx_underflow), .intr_upload_cmdfifo_not_empty_o (intr_spi_device_upload_cmdfifo_not_empty), .intr_upload_payload_not_empty_o (intr_spi_device_upload_payload_not_empty), .intr_upload_payload_overflow_o (intr_spi_device_upload_payload_overflow), @@ -2631,126 +2619,120 @@ module top_earlgrey #( ); // interrupt assignments assign intr_vector = { - intr_edn1_edn_fatal_err, // IDs [184 +: 1] - intr_edn1_edn_cmd_req_done, // IDs [183 +: 1] - intr_edn0_edn_fatal_err, // IDs [182 +: 1] - intr_edn0_edn_cmd_req_done, // IDs [181 +: 1] - intr_entropy_src_es_fatal_err, // IDs [180 +: 1] - intr_entropy_src_es_observe_fifo_ready, // IDs [179 +: 1] - intr_entropy_src_es_health_test_failed, // IDs [178 +: 1] - intr_entropy_src_es_entropy_valid, // IDs [177 +: 1] - intr_csrng_cs_fatal_err, // IDs [176 +: 1] - intr_csrng_cs_hw_inst_exc, // IDs [175 +: 1] - intr_csrng_cs_entropy_req, // IDs [174 +: 1] - intr_csrng_cs_cmd_req_done, // IDs [173 +: 1] - intr_keymgr_op_done, // IDs [172 +: 1] - intr_otbn_done, // IDs [171 +: 1] - intr_kmac_kmac_err, // IDs [170 +: 1] - intr_kmac_fifo_empty, // IDs [169 +: 1] - intr_kmac_kmac_done, // IDs [168 +: 1] - intr_hmac_hmac_err, // IDs [167 +: 1] - intr_hmac_fifo_empty, // IDs [166 +: 1] - intr_hmac_hmac_done, // IDs [165 +: 1] - intr_flash_ctrl_corr_err, // IDs [164 +: 1] - intr_flash_ctrl_op_done, // IDs [163 +: 1] - intr_flash_ctrl_rd_lvl, // IDs [162 +: 1] - intr_flash_ctrl_rd_full, // IDs [161 +: 1] - intr_flash_ctrl_prog_lvl, // IDs [160 +: 1] - intr_flash_ctrl_prog_empty, // IDs [159 +: 1] - intr_sensor_ctrl_aon_init_status_change, // IDs [158 +: 1] - intr_sensor_ctrl_aon_io_status_change, // IDs [157 +: 1] - intr_aon_timer_aon_wdog_timer_bark, // IDs [156 +: 1] - intr_aon_timer_aon_wkup_timer_expired, // IDs [155 +: 1] - intr_adc_ctrl_aon_match_done, // IDs [154 +: 1] - intr_sysrst_ctrl_aon_event_detected, // IDs [153 +: 1] - intr_pwrmgr_aon_wakeup, // IDs [152 +: 1] - intr_usbdev_link_out_err, // IDs [151 +: 1] - intr_usbdev_powered, // IDs [150 +: 1] - intr_usbdev_frame, // IDs [149 +: 1] - intr_usbdev_rx_bitstuff_err, // IDs [148 +: 1] - intr_usbdev_rx_pid_err, // IDs [147 +: 1] - intr_usbdev_rx_crc_err, // IDs [146 +: 1] - intr_usbdev_link_in_err, // IDs [145 +: 1] - intr_usbdev_av_overflow, // IDs [144 +: 1] - intr_usbdev_rx_full, // IDs [143 +: 1] - intr_usbdev_av_empty, // IDs [142 +: 1] - intr_usbdev_link_resume, // IDs [141 +: 1] - intr_usbdev_link_suspend, // IDs [140 +: 1] - intr_usbdev_link_reset, // IDs [139 +: 1] - intr_usbdev_host_lost, // IDs [138 +: 1] - intr_usbdev_disconnected, // IDs [137 +: 1] - intr_usbdev_pkt_sent, // IDs [136 +: 1] - intr_usbdev_pkt_received, // IDs [135 +: 1] - intr_spi_host1_spi_event, // IDs [134 +: 1] - intr_spi_host1_error, // IDs [133 +: 1] - intr_spi_host0_spi_event, // IDs [132 +: 1] - intr_spi_host0_error, // IDs [131 +: 1] - intr_alert_handler_classd, // IDs [130 +: 1] - intr_alert_handler_classc, // IDs [129 +: 1] - intr_alert_handler_classb, // IDs [128 +: 1] - intr_alert_handler_classa, // IDs [127 +: 1] - intr_otp_ctrl_otp_error, // IDs [126 +: 1] - intr_otp_ctrl_otp_operation_done, // IDs [125 +: 1] - intr_rv_timer_timer_expired_hart0_timer0, // IDs [124 +: 1] - intr_pattgen_done_ch1, // IDs [123 +: 1] - intr_pattgen_done_ch0, // IDs [122 +: 1] - intr_i2c2_host_timeout, // IDs [121 +: 1] - intr_i2c2_unexp_stop, // IDs [120 +: 1] - intr_i2c2_acq_full, // IDs [119 +: 1] - intr_i2c2_tx_overflow, // IDs [118 +: 1] - intr_i2c2_tx_stretch, // IDs [117 +: 1] - intr_i2c2_cmd_complete, // IDs [116 +: 1] - intr_i2c2_sda_unstable, // IDs [115 +: 1] - intr_i2c2_stretch_timeout, // IDs [114 +: 1] - intr_i2c2_sda_interference, // IDs [113 +: 1] - intr_i2c2_scl_interference, // IDs [112 +: 1] - intr_i2c2_nak, // IDs [111 +: 1] - intr_i2c2_rx_overflow, // IDs [110 +: 1] - intr_i2c2_fmt_overflow, // IDs [109 +: 1] - intr_i2c2_rx_threshold, // IDs [108 +: 1] - intr_i2c2_fmt_threshold, // IDs [107 +: 1] - intr_i2c1_host_timeout, // IDs [106 +: 1] - intr_i2c1_unexp_stop, // IDs [105 +: 1] - intr_i2c1_acq_full, // IDs [104 +: 1] - intr_i2c1_tx_overflow, // IDs [103 +: 1] - intr_i2c1_tx_stretch, // IDs [102 +: 1] - intr_i2c1_cmd_complete, // IDs [101 +: 1] - intr_i2c1_sda_unstable, // IDs [100 +: 1] - intr_i2c1_stretch_timeout, // IDs [99 +: 1] - intr_i2c1_sda_interference, // IDs [98 +: 1] - intr_i2c1_scl_interference, // IDs [97 +: 1] - intr_i2c1_nak, // IDs [96 +: 1] - intr_i2c1_rx_overflow, // IDs [95 +: 1] - intr_i2c1_fmt_overflow, // IDs [94 +: 1] - intr_i2c1_rx_threshold, // IDs [93 +: 1] - intr_i2c1_fmt_threshold, // IDs [92 +: 1] - intr_i2c0_host_timeout, // IDs [91 +: 1] - intr_i2c0_unexp_stop, // IDs [90 +: 1] - intr_i2c0_acq_full, // IDs [89 +: 1] - intr_i2c0_tx_overflow, // IDs [88 +: 1] - intr_i2c0_tx_stretch, // IDs [87 +: 1] - intr_i2c0_cmd_complete, // IDs [86 +: 1] - intr_i2c0_sda_unstable, // IDs [85 +: 1] - intr_i2c0_stretch_timeout, // IDs [84 +: 1] - intr_i2c0_sda_interference, // IDs [83 +: 1] - intr_i2c0_scl_interference, // IDs [82 +: 1] - intr_i2c0_nak, // IDs [81 +: 1] - intr_i2c0_rx_overflow, // IDs [80 +: 1] - intr_i2c0_fmt_overflow, // IDs [79 +: 1] - intr_i2c0_rx_threshold, // IDs [78 +: 1] - intr_i2c0_fmt_threshold, // IDs [77 +: 1] - intr_spi_device_tpm_header_not_empty, // IDs [76 +: 1] - intr_spi_device_readbuf_flip, // IDs [75 +: 1] - intr_spi_device_readbuf_watermark, // IDs [74 +: 1] - intr_spi_device_upload_payload_overflow, // IDs [73 +: 1] - intr_spi_device_upload_payload_not_empty, // IDs [72 +: 1] - intr_spi_device_upload_cmdfifo_not_empty, // IDs [71 +: 1] - intr_spi_device_generic_tx_underflow, // IDs [70 +: 1] - intr_spi_device_generic_rx_overflow, // IDs [69 +: 1] - intr_spi_device_generic_rx_error, // IDs [68 +: 1] - intr_spi_device_generic_tx_watermark, // IDs [67 +: 1] - intr_spi_device_generic_rx_watermark, // IDs [66 +: 1] - intr_spi_device_generic_rx_full, // IDs [65 +: 1] + intr_edn1_edn_fatal_err, // IDs [178 +: 1] + intr_edn1_edn_cmd_req_done, // IDs [177 +: 1] + intr_edn0_edn_fatal_err, // IDs [176 +: 1] + intr_edn0_edn_cmd_req_done, // IDs [175 +: 1] + intr_entropy_src_es_fatal_err, // IDs [174 +: 1] + intr_entropy_src_es_observe_fifo_ready, // IDs [173 +: 1] + intr_entropy_src_es_health_test_failed, // IDs [172 +: 1] + intr_entropy_src_es_entropy_valid, // IDs [171 +: 1] + intr_csrng_cs_fatal_err, // IDs [170 +: 1] + intr_csrng_cs_hw_inst_exc, // IDs [169 +: 1] + intr_csrng_cs_entropy_req, // IDs [168 +: 1] + intr_csrng_cs_cmd_req_done, // IDs [167 +: 1] + intr_keymgr_op_done, // IDs [166 +: 1] + intr_otbn_done, // IDs [165 +: 1] + intr_kmac_kmac_err, // IDs [164 +: 1] + intr_kmac_fifo_empty, // IDs [163 +: 1] + intr_kmac_kmac_done, // IDs [162 +: 1] + intr_hmac_hmac_err, // IDs [161 +: 1] + intr_hmac_fifo_empty, // IDs [160 +: 1] + intr_hmac_hmac_done, // IDs [159 +: 1] + intr_flash_ctrl_corr_err, // IDs [158 +: 1] + intr_flash_ctrl_op_done, // IDs [157 +: 1] + intr_flash_ctrl_rd_lvl, // IDs [156 +: 1] + intr_flash_ctrl_rd_full, // IDs [155 +: 1] + intr_flash_ctrl_prog_lvl, // IDs [154 +: 1] + intr_flash_ctrl_prog_empty, // IDs [153 +: 1] + intr_sensor_ctrl_aon_init_status_change, // IDs [152 +: 1] + intr_sensor_ctrl_aon_io_status_change, // IDs [151 +: 1] + intr_aon_timer_aon_wdog_timer_bark, // IDs [150 +: 1] + intr_aon_timer_aon_wkup_timer_expired, // IDs [149 +: 1] + intr_adc_ctrl_aon_match_done, // IDs [148 +: 1] + intr_sysrst_ctrl_aon_event_detected, // IDs [147 +: 1] + intr_pwrmgr_aon_wakeup, // IDs [146 +: 1] + intr_usbdev_link_out_err, // IDs [145 +: 1] + intr_usbdev_powered, // IDs [144 +: 1] + intr_usbdev_frame, // IDs [143 +: 1] + intr_usbdev_rx_bitstuff_err, // IDs [142 +: 1] + intr_usbdev_rx_pid_err, // IDs [141 +: 1] + intr_usbdev_rx_crc_err, // IDs [140 +: 1] + intr_usbdev_link_in_err, // IDs [139 +: 1] + intr_usbdev_av_overflow, // IDs [138 +: 1] + intr_usbdev_rx_full, // IDs [137 +: 1] + intr_usbdev_av_empty, // IDs [136 +: 1] + intr_usbdev_link_resume, // IDs [135 +: 1] + intr_usbdev_link_suspend, // IDs [134 +: 1] + intr_usbdev_link_reset, // IDs [133 +: 1] + intr_usbdev_host_lost, // IDs [132 +: 1] + intr_usbdev_disconnected, // IDs [131 +: 1] + intr_usbdev_pkt_sent, // IDs [130 +: 1] + intr_usbdev_pkt_received, // IDs [129 +: 1] + intr_spi_host1_spi_event, // IDs [128 +: 1] + intr_spi_host1_error, // IDs [127 +: 1] + intr_spi_host0_spi_event, // IDs [126 +: 1] + intr_spi_host0_error, // IDs [125 +: 1] + intr_alert_handler_classd, // IDs [124 +: 1] + intr_alert_handler_classc, // IDs [123 +: 1] + intr_alert_handler_classb, // IDs [122 +: 1] + intr_alert_handler_classa, // IDs [121 +: 1] + intr_otp_ctrl_otp_error, // IDs [120 +: 1] + intr_otp_ctrl_otp_operation_done, // IDs [119 +: 1] + intr_rv_timer_timer_expired_hart0_timer0, // IDs [118 +: 1] + intr_pattgen_done_ch1, // IDs [117 +: 1] + intr_pattgen_done_ch0, // IDs [116 +: 1] + intr_i2c2_host_timeout, // IDs [115 +: 1] + intr_i2c2_unexp_stop, // IDs [114 +: 1] + intr_i2c2_acq_full, // IDs [113 +: 1] + intr_i2c2_tx_overflow, // IDs [112 +: 1] + intr_i2c2_tx_stretch, // IDs [111 +: 1] + intr_i2c2_cmd_complete, // IDs [110 +: 1] + intr_i2c2_sda_unstable, // IDs [109 +: 1] + intr_i2c2_stretch_timeout, // IDs [108 +: 1] + intr_i2c2_sda_interference, // IDs [107 +: 1] + intr_i2c2_scl_interference, // IDs [106 +: 1] + intr_i2c2_nak, // IDs [105 +: 1] + intr_i2c2_rx_overflow, // IDs [104 +: 1] + intr_i2c2_fmt_overflow, // IDs [103 +: 1] + intr_i2c2_rx_threshold, // IDs [102 +: 1] + intr_i2c2_fmt_threshold, // IDs [101 +: 1] + intr_i2c1_host_timeout, // IDs [100 +: 1] + intr_i2c1_unexp_stop, // IDs [99 +: 1] + intr_i2c1_acq_full, // IDs [98 +: 1] + intr_i2c1_tx_overflow, // IDs [97 +: 1] + intr_i2c1_tx_stretch, // IDs [96 +: 1] + intr_i2c1_cmd_complete, // IDs [95 +: 1] + intr_i2c1_sda_unstable, // IDs [94 +: 1] + intr_i2c1_stretch_timeout, // IDs [93 +: 1] + intr_i2c1_sda_interference, // IDs [92 +: 1] + intr_i2c1_scl_interference, // IDs [91 +: 1] + intr_i2c1_nak, // IDs [90 +: 1] + intr_i2c1_rx_overflow, // IDs [89 +: 1] + intr_i2c1_fmt_overflow, // IDs [88 +: 1] + intr_i2c1_rx_threshold, // IDs [87 +: 1] + intr_i2c1_fmt_threshold, // IDs [86 +: 1] + intr_i2c0_host_timeout, // IDs [85 +: 1] + intr_i2c0_unexp_stop, // IDs [84 +: 1] + intr_i2c0_acq_full, // IDs [83 +: 1] + intr_i2c0_tx_overflow, // IDs [82 +: 1] + intr_i2c0_tx_stretch, // IDs [81 +: 1] + intr_i2c0_cmd_complete, // IDs [80 +: 1] + intr_i2c0_sda_unstable, // IDs [79 +: 1] + intr_i2c0_stretch_timeout, // IDs [78 +: 1] + intr_i2c0_sda_interference, // IDs [77 +: 1] + intr_i2c0_scl_interference, // IDs [76 +: 1] + intr_i2c0_nak, // IDs [75 +: 1] + intr_i2c0_rx_overflow, // IDs [74 +: 1] + intr_i2c0_fmt_overflow, // IDs [73 +: 1] + intr_i2c0_rx_threshold, // IDs [72 +: 1] + intr_i2c0_fmt_threshold, // IDs [71 +: 1] + intr_spi_device_tpm_header_not_empty, // IDs [70 +: 1] + intr_spi_device_readbuf_flip, // IDs [69 +: 1] + intr_spi_device_readbuf_watermark, // IDs [68 +: 1] + intr_spi_device_upload_payload_overflow, // IDs [67 +: 1] + intr_spi_device_upload_payload_not_empty, // IDs [66 +: 1] + intr_spi_device_upload_cmdfifo_not_empty, // IDs [65 +: 1] intr_gpio_gpio, // IDs [33 +: 32] intr_uart3_rx_parity_err, // IDs [32 +: 1] intr_uart3_rx_timeout, // IDs [31 +: 1] diff --git a/hw/top_earlgrey/sw/autogen/chip/top_earlgrey.rs b/hw/top_earlgrey/sw/autogen/chip/top_earlgrey.rs index 8da0cde7ddf35..1bde6b1829da1 100644 --- a/hw/top_earlgrey/sw/autogen/chip/top_earlgrey.rs +++ b/hw/top_earlgrey/sw/autogen/chip/top_earlgrey.rs @@ -993,246 +993,234 @@ pub enum PlicIrqId { GpioGpio30 = 63, /// gpio_gpio 31 GpioGpio31 = 64, - /// spi_device_generic_rx_full - SpiDeviceGenericRxFull = 65, - /// spi_device_generic_rx_watermark - SpiDeviceGenericRxWatermark = 66, - /// spi_device_generic_tx_watermark - SpiDeviceGenericTxWatermark = 67, - /// spi_device_generic_rx_error - SpiDeviceGenericRxError = 68, - /// spi_device_generic_rx_overflow - SpiDeviceGenericRxOverflow = 69, - /// spi_device_generic_tx_underflow - SpiDeviceGenericTxUnderflow = 70, /// spi_device_upload_cmdfifo_not_empty - SpiDeviceUploadCmdfifoNotEmpty = 71, + SpiDeviceUploadCmdfifoNotEmpty = 65, /// spi_device_upload_payload_not_empty - SpiDeviceUploadPayloadNotEmpty = 72, + SpiDeviceUploadPayloadNotEmpty = 66, /// spi_device_upload_payload_overflow - SpiDeviceUploadPayloadOverflow = 73, + SpiDeviceUploadPayloadOverflow = 67, /// spi_device_readbuf_watermark - SpiDeviceReadbufWatermark = 74, + SpiDeviceReadbufWatermark = 68, /// spi_device_readbuf_flip - SpiDeviceReadbufFlip = 75, + SpiDeviceReadbufFlip = 69, /// spi_device_tpm_header_not_empty - SpiDeviceTpmHeaderNotEmpty = 76, + SpiDeviceTpmHeaderNotEmpty = 70, /// i2c0_fmt_threshold - I2c0FmtThreshold = 77, + I2c0FmtThreshold = 71, /// i2c0_rx_threshold - I2c0RxThreshold = 78, + I2c0RxThreshold = 72, /// i2c0_fmt_overflow - I2c0FmtOverflow = 79, + I2c0FmtOverflow = 73, /// i2c0_rx_overflow - I2c0RxOverflow = 80, + I2c0RxOverflow = 74, /// i2c0_nak - I2c0Nak = 81, + I2c0Nak = 75, /// i2c0_scl_interference - I2c0SclInterference = 82, + I2c0SclInterference = 76, /// i2c0_sda_interference - I2c0SdaInterference = 83, + I2c0SdaInterference = 77, /// i2c0_stretch_timeout - I2c0StretchTimeout = 84, + I2c0StretchTimeout = 78, /// i2c0_sda_unstable - I2c0SdaUnstable = 85, + I2c0SdaUnstable = 79, /// i2c0_cmd_complete - I2c0CmdComplete = 86, + I2c0CmdComplete = 80, /// i2c0_tx_stretch - I2c0TxStretch = 87, + I2c0TxStretch = 81, /// i2c0_tx_overflow - I2c0TxOverflow = 88, + I2c0TxOverflow = 82, /// i2c0_acq_full - I2c0AcqFull = 89, + I2c0AcqFull = 83, /// i2c0_unexp_stop - I2c0UnexpStop = 90, + I2c0UnexpStop = 84, /// i2c0_host_timeout - I2c0HostTimeout = 91, + I2c0HostTimeout = 85, /// i2c1_fmt_threshold - I2c1FmtThreshold = 92, + I2c1FmtThreshold = 86, /// i2c1_rx_threshold - I2c1RxThreshold = 93, + I2c1RxThreshold = 87, /// i2c1_fmt_overflow - I2c1FmtOverflow = 94, + I2c1FmtOverflow = 88, /// i2c1_rx_overflow - I2c1RxOverflow = 95, + I2c1RxOverflow = 89, /// i2c1_nak - I2c1Nak = 96, + I2c1Nak = 90, /// i2c1_scl_interference - I2c1SclInterference = 97, + I2c1SclInterference = 91, /// i2c1_sda_interference - I2c1SdaInterference = 98, + I2c1SdaInterference = 92, /// i2c1_stretch_timeout - I2c1StretchTimeout = 99, + I2c1StretchTimeout = 93, /// i2c1_sda_unstable - I2c1SdaUnstable = 100, + I2c1SdaUnstable = 94, /// i2c1_cmd_complete - I2c1CmdComplete = 101, + I2c1CmdComplete = 95, /// i2c1_tx_stretch - I2c1TxStretch = 102, + I2c1TxStretch = 96, /// i2c1_tx_overflow - I2c1TxOverflow = 103, + I2c1TxOverflow = 97, /// i2c1_acq_full - I2c1AcqFull = 104, + I2c1AcqFull = 98, /// i2c1_unexp_stop - I2c1UnexpStop = 105, + I2c1UnexpStop = 99, /// i2c1_host_timeout - I2c1HostTimeout = 106, + I2c1HostTimeout = 100, /// i2c2_fmt_threshold - I2c2FmtThreshold = 107, + I2c2FmtThreshold = 101, /// i2c2_rx_threshold - I2c2RxThreshold = 108, + I2c2RxThreshold = 102, /// i2c2_fmt_overflow - I2c2FmtOverflow = 109, + I2c2FmtOverflow = 103, /// i2c2_rx_overflow - I2c2RxOverflow = 110, + I2c2RxOverflow = 104, /// i2c2_nak - I2c2Nak = 111, + I2c2Nak = 105, /// i2c2_scl_interference - I2c2SclInterference = 112, + I2c2SclInterference = 106, /// i2c2_sda_interference - I2c2SdaInterference = 113, + I2c2SdaInterference = 107, /// i2c2_stretch_timeout - I2c2StretchTimeout = 114, + I2c2StretchTimeout = 108, /// i2c2_sda_unstable - I2c2SdaUnstable = 115, + I2c2SdaUnstable = 109, /// i2c2_cmd_complete - I2c2CmdComplete = 116, + I2c2CmdComplete = 110, /// i2c2_tx_stretch - I2c2TxStretch = 117, + I2c2TxStretch = 111, /// i2c2_tx_overflow - I2c2TxOverflow = 118, + I2c2TxOverflow = 112, /// i2c2_acq_full - I2c2AcqFull = 119, + I2c2AcqFull = 113, /// i2c2_unexp_stop - I2c2UnexpStop = 120, + I2c2UnexpStop = 114, /// i2c2_host_timeout - I2c2HostTimeout = 121, + I2c2HostTimeout = 115, /// pattgen_done_ch0 - PattgenDoneCh0 = 122, + PattgenDoneCh0 = 116, /// pattgen_done_ch1 - PattgenDoneCh1 = 123, + PattgenDoneCh1 = 117, /// rv_timer_timer_expired_hart0_timer0 - RvTimerTimerExpiredHart0Timer0 = 124, + RvTimerTimerExpiredHart0Timer0 = 118, /// otp_ctrl_otp_operation_done - OtpCtrlOtpOperationDone = 125, + OtpCtrlOtpOperationDone = 119, /// otp_ctrl_otp_error - OtpCtrlOtpError = 126, + OtpCtrlOtpError = 120, /// alert_handler_classa - AlertHandlerClassa = 127, + AlertHandlerClassa = 121, /// alert_handler_classb - AlertHandlerClassb = 128, + AlertHandlerClassb = 122, /// alert_handler_classc - AlertHandlerClassc = 129, + AlertHandlerClassc = 123, /// alert_handler_classd - AlertHandlerClassd = 130, + AlertHandlerClassd = 124, /// spi_host0_error - SpiHost0Error = 131, + SpiHost0Error = 125, /// spi_host0_spi_event - SpiHost0SpiEvent = 132, + SpiHost0SpiEvent = 126, /// spi_host1_error - SpiHost1Error = 133, + SpiHost1Error = 127, /// spi_host1_spi_event - SpiHost1SpiEvent = 134, + SpiHost1SpiEvent = 128, /// usbdev_pkt_received - UsbdevPktReceived = 135, + UsbdevPktReceived = 129, /// usbdev_pkt_sent - UsbdevPktSent = 136, + UsbdevPktSent = 130, /// usbdev_disconnected - UsbdevDisconnected = 137, + UsbdevDisconnected = 131, /// usbdev_host_lost - UsbdevHostLost = 138, + UsbdevHostLost = 132, /// usbdev_link_reset - UsbdevLinkReset = 139, + UsbdevLinkReset = 133, /// usbdev_link_suspend - UsbdevLinkSuspend = 140, + UsbdevLinkSuspend = 134, /// usbdev_link_resume - UsbdevLinkResume = 141, + UsbdevLinkResume = 135, /// usbdev_av_empty - UsbdevAvEmpty = 142, + UsbdevAvEmpty = 136, /// usbdev_rx_full - UsbdevRxFull = 143, + UsbdevRxFull = 137, /// usbdev_av_overflow - UsbdevAvOverflow = 144, + UsbdevAvOverflow = 138, /// usbdev_link_in_err - UsbdevLinkInErr = 145, + UsbdevLinkInErr = 139, /// usbdev_rx_crc_err - UsbdevRxCrcErr = 146, + UsbdevRxCrcErr = 140, /// usbdev_rx_pid_err - UsbdevRxPidErr = 147, + UsbdevRxPidErr = 141, /// usbdev_rx_bitstuff_err - UsbdevRxBitstuffErr = 148, + UsbdevRxBitstuffErr = 142, /// usbdev_frame - UsbdevFrame = 149, + UsbdevFrame = 143, /// usbdev_powered - UsbdevPowered = 150, + UsbdevPowered = 144, /// usbdev_link_out_err - UsbdevLinkOutErr = 151, + UsbdevLinkOutErr = 145, /// pwrmgr_aon_wakeup - PwrmgrAonWakeup = 152, + PwrmgrAonWakeup = 146, /// sysrst_ctrl_aon_event_detected - SysrstCtrlAonEventDetected = 153, + SysrstCtrlAonEventDetected = 147, /// adc_ctrl_aon_match_done - AdcCtrlAonMatchDone = 154, + AdcCtrlAonMatchDone = 148, /// aon_timer_aon_wkup_timer_expired - AonTimerAonWkupTimerExpired = 155, + AonTimerAonWkupTimerExpired = 149, /// aon_timer_aon_wdog_timer_bark - AonTimerAonWdogTimerBark = 156, + AonTimerAonWdogTimerBark = 150, /// sensor_ctrl_aon_io_status_change - SensorCtrlAonIoStatusChange = 157, + SensorCtrlAonIoStatusChange = 151, /// sensor_ctrl_aon_init_status_change - SensorCtrlAonInitStatusChange = 158, + SensorCtrlAonInitStatusChange = 152, /// flash_ctrl_prog_empty - FlashCtrlProgEmpty = 159, + FlashCtrlProgEmpty = 153, /// flash_ctrl_prog_lvl - FlashCtrlProgLvl = 160, + FlashCtrlProgLvl = 154, /// flash_ctrl_rd_full - FlashCtrlRdFull = 161, + FlashCtrlRdFull = 155, /// flash_ctrl_rd_lvl - FlashCtrlRdLvl = 162, + FlashCtrlRdLvl = 156, /// flash_ctrl_op_done - FlashCtrlOpDone = 163, + FlashCtrlOpDone = 157, /// flash_ctrl_corr_err - FlashCtrlCorrErr = 164, + FlashCtrlCorrErr = 158, /// hmac_hmac_done - HmacHmacDone = 165, + HmacHmacDone = 159, /// hmac_fifo_empty - HmacFifoEmpty = 166, + HmacFifoEmpty = 160, /// hmac_hmac_err - HmacHmacErr = 167, + HmacHmacErr = 161, /// kmac_kmac_done - KmacKmacDone = 168, + KmacKmacDone = 162, /// kmac_fifo_empty - KmacFifoEmpty = 169, + KmacFifoEmpty = 163, /// kmac_kmac_err - KmacKmacErr = 170, + KmacKmacErr = 164, /// otbn_done - OtbnDone = 171, + OtbnDone = 165, /// keymgr_op_done - KeymgrOpDone = 172, + KeymgrOpDone = 166, /// csrng_cs_cmd_req_done - CsrngCsCmdReqDone = 173, + CsrngCsCmdReqDone = 167, /// csrng_cs_entropy_req - CsrngCsEntropyReq = 174, + CsrngCsEntropyReq = 168, /// csrng_cs_hw_inst_exc - CsrngCsHwInstExc = 175, + CsrngCsHwInstExc = 169, /// csrng_cs_fatal_err - CsrngCsFatalErr = 176, + CsrngCsFatalErr = 170, /// entropy_src_es_entropy_valid - EntropySrcEsEntropyValid = 177, + EntropySrcEsEntropyValid = 171, /// entropy_src_es_health_test_failed - EntropySrcEsHealthTestFailed = 178, + EntropySrcEsHealthTestFailed = 172, /// entropy_src_es_observe_fifo_ready - EntropySrcEsObserveFifoReady = 179, + EntropySrcEsObserveFifoReady = 173, /// entropy_src_es_fatal_err - EntropySrcEsFatalErr = 180, + EntropySrcEsFatalErr = 174, /// edn0_edn_cmd_req_done - Edn0EdnCmdReqDone = 181, + Edn0EdnCmdReqDone = 175, /// edn0_edn_fatal_err - Edn0EdnFatalErr = 182, + Edn0EdnFatalErr = 176, /// edn1_edn_cmd_req_done - Edn1EdnCmdReqDone = 183, + Edn1EdnCmdReqDone = 177, /// edn1_edn_fatal_err - Edn1EdnFatalErr = 184, + Edn1EdnFatalErr = 178, } impl TryFrom for PlicIrqId { @@ -1304,126 +1292,120 @@ impl TryFrom for PlicIrqId { 62 => Ok(Self::GpioGpio29), 63 => Ok(Self::GpioGpio30), 64 => Ok(Self::GpioGpio31), - 65 => Ok(Self::SpiDeviceGenericRxFull), - 66 => Ok(Self::SpiDeviceGenericRxWatermark), - 67 => Ok(Self::SpiDeviceGenericTxWatermark), - 68 => Ok(Self::SpiDeviceGenericRxError), - 69 => Ok(Self::SpiDeviceGenericRxOverflow), - 70 => Ok(Self::SpiDeviceGenericTxUnderflow), - 71 => Ok(Self::SpiDeviceUploadCmdfifoNotEmpty), - 72 => Ok(Self::SpiDeviceUploadPayloadNotEmpty), - 73 => Ok(Self::SpiDeviceUploadPayloadOverflow), - 74 => Ok(Self::SpiDeviceReadbufWatermark), - 75 => Ok(Self::SpiDeviceReadbufFlip), - 76 => Ok(Self::SpiDeviceTpmHeaderNotEmpty), - 77 => Ok(Self::I2c0FmtThreshold), - 78 => Ok(Self::I2c0RxThreshold), - 79 => Ok(Self::I2c0FmtOverflow), - 80 => Ok(Self::I2c0RxOverflow), - 81 => Ok(Self::I2c0Nak), - 82 => Ok(Self::I2c0SclInterference), - 83 => Ok(Self::I2c0SdaInterference), - 84 => Ok(Self::I2c0StretchTimeout), - 85 => Ok(Self::I2c0SdaUnstable), - 86 => Ok(Self::I2c0CmdComplete), - 87 => Ok(Self::I2c0TxStretch), - 88 => Ok(Self::I2c0TxOverflow), - 89 => Ok(Self::I2c0AcqFull), - 90 => Ok(Self::I2c0UnexpStop), - 91 => Ok(Self::I2c0HostTimeout), - 92 => Ok(Self::I2c1FmtThreshold), - 93 => Ok(Self::I2c1RxThreshold), - 94 => Ok(Self::I2c1FmtOverflow), - 95 => Ok(Self::I2c1RxOverflow), - 96 => Ok(Self::I2c1Nak), - 97 => Ok(Self::I2c1SclInterference), - 98 => Ok(Self::I2c1SdaInterference), - 99 => Ok(Self::I2c1StretchTimeout), - 100 => Ok(Self::I2c1SdaUnstable), - 101 => Ok(Self::I2c1CmdComplete), - 102 => Ok(Self::I2c1TxStretch), - 103 => Ok(Self::I2c1TxOverflow), - 104 => Ok(Self::I2c1AcqFull), - 105 => Ok(Self::I2c1UnexpStop), - 106 => Ok(Self::I2c1HostTimeout), - 107 => Ok(Self::I2c2FmtThreshold), - 108 => Ok(Self::I2c2RxThreshold), - 109 => Ok(Self::I2c2FmtOverflow), - 110 => Ok(Self::I2c2RxOverflow), - 111 => Ok(Self::I2c2Nak), - 112 => Ok(Self::I2c2SclInterference), - 113 => Ok(Self::I2c2SdaInterference), - 114 => Ok(Self::I2c2StretchTimeout), - 115 => Ok(Self::I2c2SdaUnstable), - 116 => Ok(Self::I2c2CmdComplete), - 117 => Ok(Self::I2c2TxStretch), - 118 => Ok(Self::I2c2TxOverflow), - 119 => Ok(Self::I2c2AcqFull), - 120 => Ok(Self::I2c2UnexpStop), - 121 => Ok(Self::I2c2HostTimeout), - 122 => Ok(Self::PattgenDoneCh0), - 123 => Ok(Self::PattgenDoneCh1), - 124 => Ok(Self::RvTimerTimerExpiredHart0Timer0), - 125 => Ok(Self::OtpCtrlOtpOperationDone), - 126 => Ok(Self::OtpCtrlOtpError), - 127 => Ok(Self::AlertHandlerClassa), - 128 => Ok(Self::AlertHandlerClassb), - 129 => Ok(Self::AlertHandlerClassc), - 130 => Ok(Self::AlertHandlerClassd), - 131 => Ok(Self::SpiHost0Error), - 132 => Ok(Self::SpiHost0SpiEvent), - 133 => Ok(Self::SpiHost1Error), - 134 => Ok(Self::SpiHost1SpiEvent), - 135 => Ok(Self::UsbdevPktReceived), - 136 => Ok(Self::UsbdevPktSent), - 137 => Ok(Self::UsbdevDisconnected), - 138 => Ok(Self::UsbdevHostLost), - 139 => Ok(Self::UsbdevLinkReset), - 140 => Ok(Self::UsbdevLinkSuspend), - 141 => Ok(Self::UsbdevLinkResume), - 142 => Ok(Self::UsbdevAvEmpty), - 143 => Ok(Self::UsbdevRxFull), - 144 => Ok(Self::UsbdevAvOverflow), - 145 => Ok(Self::UsbdevLinkInErr), - 146 => Ok(Self::UsbdevRxCrcErr), - 147 => Ok(Self::UsbdevRxPidErr), - 148 => Ok(Self::UsbdevRxBitstuffErr), - 149 => Ok(Self::UsbdevFrame), - 150 => Ok(Self::UsbdevPowered), - 151 => Ok(Self::UsbdevLinkOutErr), - 152 => Ok(Self::PwrmgrAonWakeup), - 153 => Ok(Self::SysrstCtrlAonEventDetected), - 154 => Ok(Self::AdcCtrlAonMatchDone), - 155 => Ok(Self::AonTimerAonWkupTimerExpired), - 156 => Ok(Self::AonTimerAonWdogTimerBark), - 157 => Ok(Self::SensorCtrlAonIoStatusChange), - 158 => Ok(Self::SensorCtrlAonInitStatusChange), - 159 => Ok(Self::FlashCtrlProgEmpty), - 160 => Ok(Self::FlashCtrlProgLvl), - 161 => Ok(Self::FlashCtrlRdFull), - 162 => Ok(Self::FlashCtrlRdLvl), - 163 => Ok(Self::FlashCtrlOpDone), - 164 => Ok(Self::FlashCtrlCorrErr), - 165 => Ok(Self::HmacHmacDone), - 166 => Ok(Self::HmacFifoEmpty), - 167 => Ok(Self::HmacHmacErr), - 168 => Ok(Self::KmacKmacDone), - 169 => Ok(Self::KmacFifoEmpty), - 170 => Ok(Self::KmacKmacErr), - 171 => Ok(Self::OtbnDone), - 172 => Ok(Self::KeymgrOpDone), - 173 => Ok(Self::CsrngCsCmdReqDone), - 174 => Ok(Self::CsrngCsEntropyReq), - 175 => Ok(Self::CsrngCsHwInstExc), - 176 => Ok(Self::CsrngCsFatalErr), - 177 => Ok(Self::EntropySrcEsEntropyValid), - 178 => Ok(Self::EntropySrcEsHealthTestFailed), - 179 => Ok(Self::EntropySrcEsObserveFifoReady), - 180 => Ok(Self::EntropySrcEsFatalErr), - 181 => Ok(Self::Edn0EdnCmdReqDone), - 182 => Ok(Self::Edn0EdnFatalErr), - 183 => Ok(Self::Edn1EdnCmdReqDone), - 184 => Ok(Self::Edn1EdnFatalErr), + 65 => Ok(Self::SpiDeviceUploadCmdfifoNotEmpty), + 66 => Ok(Self::SpiDeviceUploadPayloadNotEmpty), + 67 => Ok(Self::SpiDeviceUploadPayloadOverflow), + 68 => Ok(Self::SpiDeviceReadbufWatermark), + 69 => Ok(Self::SpiDeviceReadbufFlip), + 70 => Ok(Self::SpiDeviceTpmHeaderNotEmpty), + 71 => Ok(Self::I2c0FmtThreshold), + 72 => Ok(Self::I2c0RxThreshold), + 73 => Ok(Self::I2c0FmtOverflow), + 74 => Ok(Self::I2c0RxOverflow), + 75 => Ok(Self::I2c0Nak), + 76 => Ok(Self::I2c0SclInterference), + 77 => Ok(Self::I2c0SdaInterference), + 78 => Ok(Self::I2c0StretchTimeout), + 79 => Ok(Self::I2c0SdaUnstable), + 80 => Ok(Self::I2c0CmdComplete), + 81 => Ok(Self::I2c0TxStretch), + 82 => Ok(Self::I2c0TxOverflow), + 83 => Ok(Self::I2c0AcqFull), + 84 => Ok(Self::I2c0UnexpStop), + 85 => Ok(Self::I2c0HostTimeout), + 86 => Ok(Self::I2c1FmtThreshold), + 87 => Ok(Self::I2c1RxThreshold), + 88 => Ok(Self::I2c1FmtOverflow), + 89 => Ok(Self::I2c1RxOverflow), + 90 => Ok(Self::I2c1Nak), + 91 => Ok(Self::I2c1SclInterference), + 92 => Ok(Self::I2c1SdaInterference), + 93 => Ok(Self::I2c1StretchTimeout), + 94 => Ok(Self::I2c1SdaUnstable), + 95 => Ok(Self::I2c1CmdComplete), + 96 => Ok(Self::I2c1TxStretch), + 97 => Ok(Self::I2c1TxOverflow), + 98 => Ok(Self::I2c1AcqFull), + 99 => Ok(Self::I2c1UnexpStop), + 100 => Ok(Self::I2c1HostTimeout), + 101 => Ok(Self::I2c2FmtThreshold), + 102 => Ok(Self::I2c2RxThreshold), + 103 => Ok(Self::I2c2FmtOverflow), + 104 => Ok(Self::I2c2RxOverflow), + 105 => Ok(Self::I2c2Nak), + 106 => Ok(Self::I2c2SclInterference), + 107 => Ok(Self::I2c2SdaInterference), + 108 => Ok(Self::I2c2StretchTimeout), + 109 => Ok(Self::I2c2SdaUnstable), + 110 => Ok(Self::I2c2CmdComplete), + 111 => Ok(Self::I2c2TxStretch), + 112 => Ok(Self::I2c2TxOverflow), + 113 => Ok(Self::I2c2AcqFull), + 114 => Ok(Self::I2c2UnexpStop), + 115 => Ok(Self::I2c2HostTimeout), + 116 => Ok(Self::PattgenDoneCh0), + 117 => Ok(Self::PattgenDoneCh1), + 118 => Ok(Self::RvTimerTimerExpiredHart0Timer0), + 119 => Ok(Self::OtpCtrlOtpOperationDone), + 120 => Ok(Self::OtpCtrlOtpError), + 121 => Ok(Self::AlertHandlerClassa), + 122 => Ok(Self::AlertHandlerClassb), + 123 => Ok(Self::AlertHandlerClassc), + 124 => Ok(Self::AlertHandlerClassd), + 125 => Ok(Self::SpiHost0Error), + 126 => Ok(Self::SpiHost0SpiEvent), + 127 => Ok(Self::SpiHost1Error), + 128 => Ok(Self::SpiHost1SpiEvent), + 129 => Ok(Self::UsbdevPktReceived), + 130 => Ok(Self::UsbdevPktSent), + 131 => Ok(Self::UsbdevDisconnected), + 132 => Ok(Self::UsbdevHostLost), + 133 => Ok(Self::UsbdevLinkReset), + 134 => Ok(Self::UsbdevLinkSuspend), + 135 => Ok(Self::UsbdevLinkResume), + 136 => Ok(Self::UsbdevAvEmpty), + 137 => Ok(Self::UsbdevRxFull), + 138 => Ok(Self::UsbdevAvOverflow), + 139 => Ok(Self::UsbdevLinkInErr), + 140 => Ok(Self::UsbdevRxCrcErr), + 141 => Ok(Self::UsbdevRxPidErr), + 142 => Ok(Self::UsbdevRxBitstuffErr), + 143 => Ok(Self::UsbdevFrame), + 144 => Ok(Self::UsbdevPowered), + 145 => Ok(Self::UsbdevLinkOutErr), + 146 => Ok(Self::PwrmgrAonWakeup), + 147 => Ok(Self::SysrstCtrlAonEventDetected), + 148 => Ok(Self::AdcCtrlAonMatchDone), + 149 => Ok(Self::AonTimerAonWkupTimerExpired), + 150 => Ok(Self::AonTimerAonWdogTimerBark), + 151 => Ok(Self::SensorCtrlAonIoStatusChange), + 152 => Ok(Self::SensorCtrlAonInitStatusChange), + 153 => Ok(Self::FlashCtrlProgEmpty), + 154 => Ok(Self::FlashCtrlProgLvl), + 155 => Ok(Self::FlashCtrlRdFull), + 156 => Ok(Self::FlashCtrlRdLvl), + 157 => Ok(Self::FlashCtrlOpDone), + 158 => Ok(Self::FlashCtrlCorrErr), + 159 => Ok(Self::HmacHmacDone), + 160 => Ok(Self::HmacFifoEmpty), + 161 => Ok(Self::HmacHmacErr), + 162 => Ok(Self::KmacKmacDone), + 163 => Ok(Self::KmacFifoEmpty), + 164 => Ok(Self::KmacKmacErr), + 165 => Ok(Self::OtbnDone), + 166 => Ok(Self::KeymgrOpDone), + 167 => Ok(Self::CsrngCsCmdReqDone), + 168 => Ok(Self::CsrngCsEntropyReq), + 169 => Ok(Self::CsrngCsHwInstExc), + 170 => Ok(Self::CsrngCsFatalErr), + 171 => Ok(Self::EntropySrcEsEntropyValid), + 172 => Ok(Self::EntropySrcEsHealthTestFailed), + 173 => Ok(Self::EntropySrcEsObserveFifoReady), + 174 => Ok(Self::EntropySrcEsFatalErr), + 175 => Ok(Self::Edn0EdnCmdReqDone), + 176 => Ok(Self::Edn0EdnFatalErr), + 177 => Ok(Self::Edn1EdnCmdReqDone), + 178 => Ok(Self::Edn1EdnFatalErr), _ => Err(val), } } @@ -1748,7 +1730,7 @@ impl TryFrom for AlertId { /// /// This array is a mapping from `PlicIrqId` to /// `PlicPeripheral`. -pub const PLIC_INTERRUPT_FOR_PERIPHERAL: [PlicPeripheral; 185] = [ +pub const PLIC_INTERRUPT_FOR_PERIPHERAL: [PlicPeripheral; 179] = [ // None -> PlicPeripheral::Unknown PlicPeripheral::Unknown, // Uart0TxWatermark -> PlicPeripheral::Uart0 @@ -1879,18 +1861,6 @@ pub const PLIC_INTERRUPT_FOR_PERIPHERAL: [PlicPeripheral; 185] = [ PlicPeripheral::Gpio, // GpioGpio31 -> PlicPeripheral::Gpio PlicPeripheral::Gpio, - // SpiDeviceGenericRxFull -> PlicPeripheral::SpiDevice - PlicPeripheral::SpiDevice, - // SpiDeviceGenericRxWatermark -> PlicPeripheral::SpiDevice - PlicPeripheral::SpiDevice, - // SpiDeviceGenericTxWatermark -> PlicPeripheral::SpiDevice - PlicPeripheral::SpiDevice, - // SpiDeviceGenericRxError -> PlicPeripheral::SpiDevice - PlicPeripheral::SpiDevice, - // SpiDeviceGenericRxOverflow -> PlicPeripheral::SpiDevice - PlicPeripheral::SpiDevice, - // SpiDeviceGenericTxUnderflow -> PlicPeripheral::SpiDevice - PlicPeripheral::SpiDevice, // SpiDeviceUploadCmdfifoNotEmpty -> PlicPeripheral::SpiDevice PlicPeripheral::SpiDevice, // SpiDeviceUploadPayloadNotEmpty -> PlicPeripheral::SpiDevice diff --git a/hw/top_earlgrey/sw/autogen/top_earlgrey.c b/hw/top_earlgrey/sw/autogen/top_earlgrey.c index 2aef52874b43b..7cc0fa9adeaad 100644 --- a/hw/top_earlgrey/sw/autogen/top_earlgrey.c +++ b/hw/top_earlgrey/sw/autogen/top_earlgrey.c @@ -11,7 +11,7 @@ * `top_earlgrey_plic_peripheral_t`. */ const top_earlgrey_plic_peripheral_t - top_earlgrey_plic_interrupt_for_peripheral[185] = { + top_earlgrey_plic_interrupt_for_peripheral[179] = { [kTopEarlgreyPlicIrqIdNone] = kTopEarlgreyPlicPeripheralUnknown, [kTopEarlgreyPlicIrqIdUart0TxWatermark] = kTopEarlgreyPlicPeripheralUart0, [kTopEarlgreyPlicIrqIdUart0RxWatermark] = kTopEarlgreyPlicPeripheralUart0, @@ -77,12 +77,6 @@ const top_earlgrey_plic_peripheral_t [kTopEarlgreyPlicIrqIdGpioGpio29] = kTopEarlgreyPlicPeripheralGpio, [kTopEarlgreyPlicIrqIdGpioGpio30] = kTopEarlgreyPlicPeripheralGpio, [kTopEarlgreyPlicIrqIdGpioGpio31] = kTopEarlgreyPlicPeripheralGpio, - [kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull] = kTopEarlgreyPlicPeripheralSpiDevice, - [kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark] = kTopEarlgreyPlicPeripheralSpiDevice, - [kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark] = kTopEarlgreyPlicPeripheralSpiDevice, - [kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError] = kTopEarlgreyPlicPeripheralSpiDevice, - [kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow] = kTopEarlgreyPlicPeripheralSpiDevice, - [kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow] = kTopEarlgreyPlicPeripheralSpiDevice, [kTopEarlgreyPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty] = kTopEarlgreyPlicPeripheralSpiDevice, [kTopEarlgreyPlicIrqIdSpiDeviceUploadPayloadNotEmpty] = kTopEarlgreyPlicPeripheralSpiDevice, [kTopEarlgreyPlicIrqIdSpiDeviceUploadPayloadOverflow] = kTopEarlgreyPlicPeripheralSpiDevice, diff --git a/hw/top_earlgrey/sw/autogen/top_earlgrey.h b/hw/top_earlgrey/sw/autogen/top_earlgrey.h index f1a0058113731..6b7db52bfc311 100644 --- a/hw/top_earlgrey/sw/autogen/top_earlgrey.h +++ b/hw/top_earlgrey/sw/autogen/top_earlgrey.h @@ -1080,127 +1080,121 @@ typedef enum top_earlgrey_plic_irq_id { kTopEarlgreyPlicIrqIdGpioGpio29 = 62, /**< gpio_gpio 29 */ kTopEarlgreyPlicIrqIdGpioGpio30 = 63, /**< gpio_gpio 30 */ kTopEarlgreyPlicIrqIdGpioGpio31 = 64, /**< gpio_gpio 31 */ - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull = 65, /**< spi_device_generic_rx_full */ - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark = 66, /**< spi_device_generic_rx_watermark */ - kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark = 67, /**< spi_device_generic_tx_watermark */ - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError = 68, /**< spi_device_generic_rx_error */ - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow = 69, /**< spi_device_generic_rx_overflow */ - kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow = 70, /**< spi_device_generic_tx_underflow */ - kTopEarlgreyPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty = 71, /**< spi_device_upload_cmdfifo_not_empty */ - kTopEarlgreyPlicIrqIdSpiDeviceUploadPayloadNotEmpty = 72, /**< spi_device_upload_payload_not_empty */ - kTopEarlgreyPlicIrqIdSpiDeviceUploadPayloadOverflow = 73, /**< spi_device_upload_payload_overflow */ - kTopEarlgreyPlicIrqIdSpiDeviceReadbufWatermark = 74, /**< spi_device_readbuf_watermark */ - kTopEarlgreyPlicIrqIdSpiDeviceReadbufFlip = 75, /**< spi_device_readbuf_flip */ - kTopEarlgreyPlicIrqIdSpiDeviceTpmHeaderNotEmpty = 76, /**< spi_device_tpm_header_not_empty */ - kTopEarlgreyPlicIrqIdI2c0FmtThreshold = 77, /**< i2c0_fmt_threshold */ - kTopEarlgreyPlicIrqIdI2c0RxThreshold = 78, /**< i2c0_rx_threshold */ - kTopEarlgreyPlicIrqIdI2c0FmtOverflow = 79, /**< i2c0_fmt_overflow */ - kTopEarlgreyPlicIrqIdI2c0RxOverflow = 80, /**< i2c0_rx_overflow */ - kTopEarlgreyPlicIrqIdI2c0Nak = 81, /**< i2c0_nak */ - kTopEarlgreyPlicIrqIdI2c0SclInterference = 82, /**< i2c0_scl_interference */ - kTopEarlgreyPlicIrqIdI2c0SdaInterference = 83, /**< i2c0_sda_interference */ - kTopEarlgreyPlicIrqIdI2c0StretchTimeout = 84, /**< i2c0_stretch_timeout */ - kTopEarlgreyPlicIrqIdI2c0SdaUnstable = 85, /**< i2c0_sda_unstable */ - kTopEarlgreyPlicIrqIdI2c0CmdComplete = 86, /**< i2c0_cmd_complete */ - kTopEarlgreyPlicIrqIdI2c0TxStretch = 87, /**< i2c0_tx_stretch */ - kTopEarlgreyPlicIrqIdI2c0TxOverflow = 88, /**< i2c0_tx_overflow */ - kTopEarlgreyPlicIrqIdI2c0AcqFull = 89, /**< i2c0_acq_full */ - kTopEarlgreyPlicIrqIdI2c0UnexpStop = 90, /**< i2c0_unexp_stop */ - kTopEarlgreyPlicIrqIdI2c0HostTimeout = 91, /**< i2c0_host_timeout */ - kTopEarlgreyPlicIrqIdI2c1FmtThreshold = 92, /**< i2c1_fmt_threshold */ - kTopEarlgreyPlicIrqIdI2c1RxThreshold = 93, /**< i2c1_rx_threshold */ - kTopEarlgreyPlicIrqIdI2c1FmtOverflow = 94, /**< i2c1_fmt_overflow */ - kTopEarlgreyPlicIrqIdI2c1RxOverflow = 95, /**< i2c1_rx_overflow */ - kTopEarlgreyPlicIrqIdI2c1Nak = 96, /**< i2c1_nak */ - kTopEarlgreyPlicIrqIdI2c1SclInterference = 97, /**< i2c1_scl_interference */ - kTopEarlgreyPlicIrqIdI2c1SdaInterference = 98, /**< i2c1_sda_interference */ - kTopEarlgreyPlicIrqIdI2c1StretchTimeout = 99, /**< i2c1_stretch_timeout */ - kTopEarlgreyPlicIrqIdI2c1SdaUnstable = 100, /**< i2c1_sda_unstable */ - kTopEarlgreyPlicIrqIdI2c1CmdComplete = 101, /**< i2c1_cmd_complete */ - kTopEarlgreyPlicIrqIdI2c1TxStretch = 102, /**< i2c1_tx_stretch */ - kTopEarlgreyPlicIrqIdI2c1TxOverflow = 103, /**< i2c1_tx_overflow */ - kTopEarlgreyPlicIrqIdI2c1AcqFull = 104, /**< i2c1_acq_full */ - kTopEarlgreyPlicIrqIdI2c1UnexpStop = 105, /**< i2c1_unexp_stop */ - kTopEarlgreyPlicIrqIdI2c1HostTimeout = 106, /**< i2c1_host_timeout */ - kTopEarlgreyPlicIrqIdI2c2FmtThreshold = 107, /**< i2c2_fmt_threshold */ - kTopEarlgreyPlicIrqIdI2c2RxThreshold = 108, /**< i2c2_rx_threshold */ - kTopEarlgreyPlicIrqIdI2c2FmtOverflow = 109, /**< i2c2_fmt_overflow */ - kTopEarlgreyPlicIrqIdI2c2RxOverflow = 110, /**< i2c2_rx_overflow */ - kTopEarlgreyPlicIrqIdI2c2Nak = 111, /**< i2c2_nak */ - kTopEarlgreyPlicIrqIdI2c2SclInterference = 112, /**< i2c2_scl_interference */ - kTopEarlgreyPlicIrqIdI2c2SdaInterference = 113, /**< i2c2_sda_interference */ - kTopEarlgreyPlicIrqIdI2c2StretchTimeout = 114, /**< i2c2_stretch_timeout */ - kTopEarlgreyPlicIrqIdI2c2SdaUnstable = 115, /**< i2c2_sda_unstable */ - kTopEarlgreyPlicIrqIdI2c2CmdComplete = 116, /**< i2c2_cmd_complete */ - kTopEarlgreyPlicIrqIdI2c2TxStretch = 117, /**< i2c2_tx_stretch */ - kTopEarlgreyPlicIrqIdI2c2TxOverflow = 118, /**< i2c2_tx_overflow */ - kTopEarlgreyPlicIrqIdI2c2AcqFull = 119, /**< i2c2_acq_full */ - kTopEarlgreyPlicIrqIdI2c2UnexpStop = 120, /**< i2c2_unexp_stop */ - kTopEarlgreyPlicIrqIdI2c2HostTimeout = 121, /**< i2c2_host_timeout */ - kTopEarlgreyPlicIrqIdPattgenDoneCh0 = 122, /**< pattgen_done_ch0 */ - kTopEarlgreyPlicIrqIdPattgenDoneCh1 = 123, /**< pattgen_done_ch1 */ - kTopEarlgreyPlicIrqIdRvTimerTimerExpiredHart0Timer0 = 124, /**< rv_timer_timer_expired_hart0_timer0 */ - kTopEarlgreyPlicIrqIdOtpCtrlOtpOperationDone = 125, /**< otp_ctrl_otp_operation_done */ - kTopEarlgreyPlicIrqIdOtpCtrlOtpError = 126, /**< otp_ctrl_otp_error */ - kTopEarlgreyPlicIrqIdAlertHandlerClassa = 127, /**< alert_handler_classa */ - kTopEarlgreyPlicIrqIdAlertHandlerClassb = 128, /**< alert_handler_classb */ - kTopEarlgreyPlicIrqIdAlertHandlerClassc = 129, /**< alert_handler_classc */ - kTopEarlgreyPlicIrqIdAlertHandlerClassd = 130, /**< alert_handler_classd */ - kTopEarlgreyPlicIrqIdSpiHost0Error = 131, /**< spi_host0_error */ - kTopEarlgreyPlicIrqIdSpiHost0SpiEvent = 132, /**< spi_host0_spi_event */ - kTopEarlgreyPlicIrqIdSpiHost1Error = 133, /**< spi_host1_error */ - kTopEarlgreyPlicIrqIdSpiHost1SpiEvent = 134, /**< spi_host1_spi_event */ - kTopEarlgreyPlicIrqIdUsbdevPktReceived = 135, /**< usbdev_pkt_received */ - kTopEarlgreyPlicIrqIdUsbdevPktSent = 136, /**< usbdev_pkt_sent */ - kTopEarlgreyPlicIrqIdUsbdevDisconnected = 137, /**< usbdev_disconnected */ - kTopEarlgreyPlicIrqIdUsbdevHostLost = 138, /**< usbdev_host_lost */ - kTopEarlgreyPlicIrqIdUsbdevLinkReset = 139, /**< usbdev_link_reset */ - kTopEarlgreyPlicIrqIdUsbdevLinkSuspend = 140, /**< usbdev_link_suspend */ - kTopEarlgreyPlicIrqIdUsbdevLinkResume = 141, /**< usbdev_link_resume */ - kTopEarlgreyPlicIrqIdUsbdevAvEmpty = 142, /**< usbdev_av_empty */ - kTopEarlgreyPlicIrqIdUsbdevRxFull = 143, /**< usbdev_rx_full */ - kTopEarlgreyPlicIrqIdUsbdevAvOverflow = 144, /**< usbdev_av_overflow */ - kTopEarlgreyPlicIrqIdUsbdevLinkInErr = 145, /**< usbdev_link_in_err */ - kTopEarlgreyPlicIrqIdUsbdevRxCrcErr = 146, /**< usbdev_rx_crc_err */ - kTopEarlgreyPlicIrqIdUsbdevRxPidErr = 147, /**< usbdev_rx_pid_err */ - kTopEarlgreyPlicIrqIdUsbdevRxBitstuffErr = 148, /**< usbdev_rx_bitstuff_err */ - kTopEarlgreyPlicIrqIdUsbdevFrame = 149, /**< usbdev_frame */ - kTopEarlgreyPlicIrqIdUsbdevPowered = 150, /**< usbdev_powered */ - kTopEarlgreyPlicIrqIdUsbdevLinkOutErr = 151, /**< usbdev_link_out_err */ - kTopEarlgreyPlicIrqIdPwrmgrAonWakeup = 152, /**< pwrmgr_aon_wakeup */ - kTopEarlgreyPlicIrqIdSysrstCtrlAonEventDetected = 153, /**< sysrst_ctrl_aon_event_detected */ - kTopEarlgreyPlicIrqIdAdcCtrlAonMatchDone = 154, /**< adc_ctrl_aon_match_done */ - kTopEarlgreyPlicIrqIdAonTimerAonWkupTimerExpired = 155, /**< aon_timer_aon_wkup_timer_expired */ - kTopEarlgreyPlicIrqIdAonTimerAonWdogTimerBark = 156, /**< aon_timer_aon_wdog_timer_bark */ - kTopEarlgreyPlicIrqIdSensorCtrlAonIoStatusChange = 157, /**< sensor_ctrl_aon_io_status_change */ - kTopEarlgreyPlicIrqIdSensorCtrlAonInitStatusChange = 158, /**< sensor_ctrl_aon_init_status_change */ - kTopEarlgreyPlicIrqIdFlashCtrlProgEmpty = 159, /**< flash_ctrl_prog_empty */ - kTopEarlgreyPlicIrqIdFlashCtrlProgLvl = 160, /**< flash_ctrl_prog_lvl */ - kTopEarlgreyPlicIrqIdFlashCtrlRdFull = 161, /**< flash_ctrl_rd_full */ - kTopEarlgreyPlicIrqIdFlashCtrlRdLvl = 162, /**< flash_ctrl_rd_lvl */ - kTopEarlgreyPlicIrqIdFlashCtrlOpDone = 163, /**< flash_ctrl_op_done */ - kTopEarlgreyPlicIrqIdFlashCtrlCorrErr = 164, /**< flash_ctrl_corr_err */ - kTopEarlgreyPlicIrqIdHmacHmacDone = 165, /**< hmac_hmac_done */ - kTopEarlgreyPlicIrqIdHmacFifoEmpty = 166, /**< hmac_fifo_empty */ - kTopEarlgreyPlicIrqIdHmacHmacErr = 167, /**< hmac_hmac_err */ - kTopEarlgreyPlicIrqIdKmacKmacDone = 168, /**< kmac_kmac_done */ - kTopEarlgreyPlicIrqIdKmacFifoEmpty = 169, /**< kmac_fifo_empty */ - kTopEarlgreyPlicIrqIdKmacKmacErr = 170, /**< kmac_kmac_err */ - kTopEarlgreyPlicIrqIdOtbnDone = 171, /**< otbn_done */ - kTopEarlgreyPlicIrqIdKeymgrOpDone = 172, /**< keymgr_op_done */ - kTopEarlgreyPlicIrqIdCsrngCsCmdReqDone = 173, /**< csrng_cs_cmd_req_done */ - kTopEarlgreyPlicIrqIdCsrngCsEntropyReq = 174, /**< csrng_cs_entropy_req */ - kTopEarlgreyPlicIrqIdCsrngCsHwInstExc = 175, /**< csrng_cs_hw_inst_exc */ - kTopEarlgreyPlicIrqIdCsrngCsFatalErr = 176, /**< csrng_cs_fatal_err */ - kTopEarlgreyPlicIrqIdEntropySrcEsEntropyValid = 177, /**< entropy_src_es_entropy_valid */ - kTopEarlgreyPlicIrqIdEntropySrcEsHealthTestFailed = 178, /**< entropy_src_es_health_test_failed */ - kTopEarlgreyPlicIrqIdEntropySrcEsObserveFifoReady = 179, /**< entropy_src_es_observe_fifo_ready */ - kTopEarlgreyPlicIrqIdEntropySrcEsFatalErr = 180, /**< entropy_src_es_fatal_err */ - kTopEarlgreyPlicIrqIdEdn0EdnCmdReqDone = 181, /**< edn0_edn_cmd_req_done */ - kTopEarlgreyPlicIrqIdEdn0EdnFatalErr = 182, /**< edn0_edn_fatal_err */ - kTopEarlgreyPlicIrqIdEdn1EdnCmdReqDone = 183, /**< edn1_edn_cmd_req_done */ - kTopEarlgreyPlicIrqIdEdn1EdnFatalErr = 184, /**< edn1_edn_fatal_err */ - kTopEarlgreyPlicIrqIdLast = 184, /**< \internal The Last Valid Interrupt ID. */ + kTopEarlgreyPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty = 65, /**< spi_device_upload_cmdfifo_not_empty */ + kTopEarlgreyPlicIrqIdSpiDeviceUploadPayloadNotEmpty = 66, /**< spi_device_upload_payload_not_empty */ + kTopEarlgreyPlicIrqIdSpiDeviceUploadPayloadOverflow = 67, /**< spi_device_upload_payload_overflow */ + kTopEarlgreyPlicIrqIdSpiDeviceReadbufWatermark = 68, /**< spi_device_readbuf_watermark */ + kTopEarlgreyPlicIrqIdSpiDeviceReadbufFlip = 69, /**< spi_device_readbuf_flip */ + kTopEarlgreyPlicIrqIdSpiDeviceTpmHeaderNotEmpty = 70, /**< spi_device_tpm_header_not_empty */ + kTopEarlgreyPlicIrqIdI2c0FmtThreshold = 71, /**< i2c0_fmt_threshold */ + kTopEarlgreyPlicIrqIdI2c0RxThreshold = 72, /**< i2c0_rx_threshold */ + kTopEarlgreyPlicIrqIdI2c0FmtOverflow = 73, /**< i2c0_fmt_overflow */ + kTopEarlgreyPlicIrqIdI2c0RxOverflow = 74, /**< i2c0_rx_overflow */ + kTopEarlgreyPlicIrqIdI2c0Nak = 75, /**< i2c0_nak */ + kTopEarlgreyPlicIrqIdI2c0SclInterference = 76, /**< i2c0_scl_interference */ + kTopEarlgreyPlicIrqIdI2c0SdaInterference = 77, /**< i2c0_sda_interference */ + kTopEarlgreyPlicIrqIdI2c0StretchTimeout = 78, /**< i2c0_stretch_timeout */ + kTopEarlgreyPlicIrqIdI2c0SdaUnstable = 79, /**< i2c0_sda_unstable */ + kTopEarlgreyPlicIrqIdI2c0CmdComplete = 80, /**< i2c0_cmd_complete */ + kTopEarlgreyPlicIrqIdI2c0TxStretch = 81, /**< i2c0_tx_stretch */ + kTopEarlgreyPlicIrqIdI2c0TxOverflow = 82, /**< i2c0_tx_overflow */ + kTopEarlgreyPlicIrqIdI2c0AcqFull = 83, /**< i2c0_acq_full */ + kTopEarlgreyPlicIrqIdI2c0UnexpStop = 84, /**< i2c0_unexp_stop */ + kTopEarlgreyPlicIrqIdI2c0HostTimeout = 85, /**< i2c0_host_timeout */ + kTopEarlgreyPlicIrqIdI2c1FmtThreshold = 86, /**< i2c1_fmt_threshold */ + kTopEarlgreyPlicIrqIdI2c1RxThreshold = 87, /**< i2c1_rx_threshold */ + kTopEarlgreyPlicIrqIdI2c1FmtOverflow = 88, /**< i2c1_fmt_overflow */ + kTopEarlgreyPlicIrqIdI2c1RxOverflow = 89, /**< i2c1_rx_overflow */ + kTopEarlgreyPlicIrqIdI2c1Nak = 90, /**< i2c1_nak */ + kTopEarlgreyPlicIrqIdI2c1SclInterference = 91, /**< i2c1_scl_interference */ + kTopEarlgreyPlicIrqIdI2c1SdaInterference = 92, /**< i2c1_sda_interference */ + kTopEarlgreyPlicIrqIdI2c1StretchTimeout = 93, /**< i2c1_stretch_timeout */ + kTopEarlgreyPlicIrqIdI2c1SdaUnstable = 94, /**< i2c1_sda_unstable */ + kTopEarlgreyPlicIrqIdI2c1CmdComplete = 95, /**< i2c1_cmd_complete */ + kTopEarlgreyPlicIrqIdI2c1TxStretch = 96, /**< i2c1_tx_stretch */ + kTopEarlgreyPlicIrqIdI2c1TxOverflow = 97, /**< i2c1_tx_overflow */ + kTopEarlgreyPlicIrqIdI2c1AcqFull = 98, /**< i2c1_acq_full */ + kTopEarlgreyPlicIrqIdI2c1UnexpStop = 99, /**< i2c1_unexp_stop */ + kTopEarlgreyPlicIrqIdI2c1HostTimeout = 100, /**< i2c1_host_timeout */ + kTopEarlgreyPlicIrqIdI2c2FmtThreshold = 101, /**< i2c2_fmt_threshold */ + kTopEarlgreyPlicIrqIdI2c2RxThreshold = 102, /**< i2c2_rx_threshold */ + kTopEarlgreyPlicIrqIdI2c2FmtOverflow = 103, /**< i2c2_fmt_overflow */ + kTopEarlgreyPlicIrqIdI2c2RxOverflow = 104, /**< i2c2_rx_overflow */ + kTopEarlgreyPlicIrqIdI2c2Nak = 105, /**< i2c2_nak */ + kTopEarlgreyPlicIrqIdI2c2SclInterference = 106, /**< i2c2_scl_interference */ + kTopEarlgreyPlicIrqIdI2c2SdaInterference = 107, /**< i2c2_sda_interference */ + kTopEarlgreyPlicIrqIdI2c2StretchTimeout = 108, /**< i2c2_stretch_timeout */ + kTopEarlgreyPlicIrqIdI2c2SdaUnstable = 109, /**< i2c2_sda_unstable */ + kTopEarlgreyPlicIrqIdI2c2CmdComplete = 110, /**< i2c2_cmd_complete */ + kTopEarlgreyPlicIrqIdI2c2TxStretch = 111, /**< i2c2_tx_stretch */ + kTopEarlgreyPlicIrqIdI2c2TxOverflow = 112, /**< i2c2_tx_overflow */ + kTopEarlgreyPlicIrqIdI2c2AcqFull = 113, /**< i2c2_acq_full */ + kTopEarlgreyPlicIrqIdI2c2UnexpStop = 114, /**< i2c2_unexp_stop */ + kTopEarlgreyPlicIrqIdI2c2HostTimeout = 115, /**< i2c2_host_timeout */ + kTopEarlgreyPlicIrqIdPattgenDoneCh0 = 116, /**< pattgen_done_ch0 */ + kTopEarlgreyPlicIrqIdPattgenDoneCh1 = 117, /**< pattgen_done_ch1 */ + kTopEarlgreyPlicIrqIdRvTimerTimerExpiredHart0Timer0 = 118, /**< rv_timer_timer_expired_hart0_timer0 */ + kTopEarlgreyPlicIrqIdOtpCtrlOtpOperationDone = 119, /**< otp_ctrl_otp_operation_done */ + kTopEarlgreyPlicIrqIdOtpCtrlOtpError = 120, /**< otp_ctrl_otp_error */ + kTopEarlgreyPlicIrqIdAlertHandlerClassa = 121, /**< alert_handler_classa */ + kTopEarlgreyPlicIrqIdAlertHandlerClassb = 122, /**< alert_handler_classb */ + kTopEarlgreyPlicIrqIdAlertHandlerClassc = 123, /**< alert_handler_classc */ + kTopEarlgreyPlicIrqIdAlertHandlerClassd = 124, /**< alert_handler_classd */ + kTopEarlgreyPlicIrqIdSpiHost0Error = 125, /**< spi_host0_error */ + kTopEarlgreyPlicIrqIdSpiHost0SpiEvent = 126, /**< spi_host0_spi_event */ + kTopEarlgreyPlicIrqIdSpiHost1Error = 127, /**< spi_host1_error */ + kTopEarlgreyPlicIrqIdSpiHost1SpiEvent = 128, /**< spi_host1_spi_event */ + kTopEarlgreyPlicIrqIdUsbdevPktReceived = 129, /**< usbdev_pkt_received */ + kTopEarlgreyPlicIrqIdUsbdevPktSent = 130, /**< usbdev_pkt_sent */ + kTopEarlgreyPlicIrqIdUsbdevDisconnected = 131, /**< usbdev_disconnected */ + kTopEarlgreyPlicIrqIdUsbdevHostLost = 132, /**< usbdev_host_lost */ + kTopEarlgreyPlicIrqIdUsbdevLinkReset = 133, /**< usbdev_link_reset */ + kTopEarlgreyPlicIrqIdUsbdevLinkSuspend = 134, /**< usbdev_link_suspend */ + kTopEarlgreyPlicIrqIdUsbdevLinkResume = 135, /**< usbdev_link_resume */ + kTopEarlgreyPlicIrqIdUsbdevAvEmpty = 136, /**< usbdev_av_empty */ + kTopEarlgreyPlicIrqIdUsbdevRxFull = 137, /**< usbdev_rx_full */ + kTopEarlgreyPlicIrqIdUsbdevAvOverflow = 138, /**< usbdev_av_overflow */ + kTopEarlgreyPlicIrqIdUsbdevLinkInErr = 139, /**< usbdev_link_in_err */ + kTopEarlgreyPlicIrqIdUsbdevRxCrcErr = 140, /**< usbdev_rx_crc_err */ + kTopEarlgreyPlicIrqIdUsbdevRxPidErr = 141, /**< usbdev_rx_pid_err */ + kTopEarlgreyPlicIrqIdUsbdevRxBitstuffErr = 142, /**< usbdev_rx_bitstuff_err */ + kTopEarlgreyPlicIrqIdUsbdevFrame = 143, /**< usbdev_frame */ + kTopEarlgreyPlicIrqIdUsbdevPowered = 144, /**< usbdev_powered */ + kTopEarlgreyPlicIrqIdUsbdevLinkOutErr = 145, /**< usbdev_link_out_err */ + kTopEarlgreyPlicIrqIdPwrmgrAonWakeup = 146, /**< pwrmgr_aon_wakeup */ + kTopEarlgreyPlicIrqIdSysrstCtrlAonEventDetected = 147, /**< sysrst_ctrl_aon_event_detected */ + kTopEarlgreyPlicIrqIdAdcCtrlAonMatchDone = 148, /**< adc_ctrl_aon_match_done */ + kTopEarlgreyPlicIrqIdAonTimerAonWkupTimerExpired = 149, /**< aon_timer_aon_wkup_timer_expired */ + kTopEarlgreyPlicIrqIdAonTimerAonWdogTimerBark = 150, /**< aon_timer_aon_wdog_timer_bark */ + kTopEarlgreyPlicIrqIdSensorCtrlAonIoStatusChange = 151, /**< sensor_ctrl_aon_io_status_change */ + kTopEarlgreyPlicIrqIdSensorCtrlAonInitStatusChange = 152, /**< sensor_ctrl_aon_init_status_change */ + kTopEarlgreyPlicIrqIdFlashCtrlProgEmpty = 153, /**< flash_ctrl_prog_empty */ + kTopEarlgreyPlicIrqIdFlashCtrlProgLvl = 154, /**< flash_ctrl_prog_lvl */ + kTopEarlgreyPlicIrqIdFlashCtrlRdFull = 155, /**< flash_ctrl_rd_full */ + kTopEarlgreyPlicIrqIdFlashCtrlRdLvl = 156, /**< flash_ctrl_rd_lvl */ + kTopEarlgreyPlicIrqIdFlashCtrlOpDone = 157, /**< flash_ctrl_op_done */ + kTopEarlgreyPlicIrqIdFlashCtrlCorrErr = 158, /**< flash_ctrl_corr_err */ + kTopEarlgreyPlicIrqIdHmacHmacDone = 159, /**< hmac_hmac_done */ + kTopEarlgreyPlicIrqIdHmacFifoEmpty = 160, /**< hmac_fifo_empty */ + kTopEarlgreyPlicIrqIdHmacHmacErr = 161, /**< hmac_hmac_err */ + kTopEarlgreyPlicIrqIdKmacKmacDone = 162, /**< kmac_kmac_done */ + kTopEarlgreyPlicIrqIdKmacFifoEmpty = 163, /**< kmac_fifo_empty */ + kTopEarlgreyPlicIrqIdKmacKmacErr = 164, /**< kmac_kmac_err */ + kTopEarlgreyPlicIrqIdOtbnDone = 165, /**< otbn_done */ + kTopEarlgreyPlicIrqIdKeymgrOpDone = 166, /**< keymgr_op_done */ + kTopEarlgreyPlicIrqIdCsrngCsCmdReqDone = 167, /**< csrng_cs_cmd_req_done */ + kTopEarlgreyPlicIrqIdCsrngCsEntropyReq = 168, /**< csrng_cs_entropy_req */ + kTopEarlgreyPlicIrqIdCsrngCsHwInstExc = 169, /**< csrng_cs_hw_inst_exc */ + kTopEarlgreyPlicIrqIdCsrngCsFatalErr = 170, /**< csrng_cs_fatal_err */ + kTopEarlgreyPlicIrqIdEntropySrcEsEntropyValid = 171, /**< entropy_src_es_entropy_valid */ + kTopEarlgreyPlicIrqIdEntropySrcEsHealthTestFailed = 172, /**< entropy_src_es_health_test_failed */ + kTopEarlgreyPlicIrqIdEntropySrcEsObserveFifoReady = 173, /**< entropy_src_es_observe_fifo_ready */ + kTopEarlgreyPlicIrqIdEntropySrcEsFatalErr = 174, /**< entropy_src_es_fatal_err */ + kTopEarlgreyPlicIrqIdEdn0EdnCmdReqDone = 175, /**< edn0_edn_cmd_req_done */ + kTopEarlgreyPlicIrqIdEdn0EdnFatalErr = 176, /**< edn0_edn_fatal_err */ + kTopEarlgreyPlicIrqIdEdn1EdnCmdReqDone = 177, /**< edn1_edn_cmd_req_done */ + kTopEarlgreyPlicIrqIdEdn1EdnFatalErr = 178, /**< edn1_edn_fatal_err */ + kTopEarlgreyPlicIrqIdLast = 178, /**< \internal The Last Valid Interrupt ID. */ } top_earlgrey_plic_irq_id_t; /** @@ -1210,7 +1204,7 @@ typedef enum top_earlgrey_plic_irq_id { * `top_earlgrey_plic_peripheral_t`. */ extern const top_earlgrey_plic_peripheral_t - top_earlgrey_plic_interrupt_for_peripheral[185]; + top_earlgrey_plic_interrupt_for_peripheral[179]; /** * PLIC Interrupt Target. diff --git a/sw/device/examples/BUILD b/sw/device/examples/BUILD index 87a20a0e7a6fc..7f453f28b7a59 100644 --- a/sw/device/examples/BUILD +++ b/sw/device/examples/BUILD @@ -11,7 +11,6 @@ cc_library( deps = [ "//sw/device/lib/arch:device", "//sw/device/lib/dif:gpio", - "//sw/device/lib/dif:spi_device", "//sw/device/lib/dif:uart", "//sw/device/lib/runtime:hart", "//sw/device/lib/runtime:log", diff --git a/sw/device/examples/demos.c b/sw/device/examples/demos.c index ebf72edc2683d..0337605bca17b 100644 --- a/sw/device/examples/demos.c +++ b/sw/device/examples/demos.c @@ -8,7 +8,6 @@ #include "sw/device/lib/arch/device.h" #include "sw/device/lib/dif/dif_gpio.h" -#include "sw/device/lib/dif/dif_spi_device.h" #include "sw/device/lib/dif/dif_uart.h" #include "sw/device/lib/runtime/hart.h" #include "sw/device/lib/runtime/log.h" @@ -62,18 +61,6 @@ uint32_t demo_gpio_to_log_echo(dif_gpio_t *gpio, uint32_t prev_gpio_state) { return gpio_state; } -void demo_spi_to_log_echo(dif_spi_device_handle_t *spi) { - uint32_t spi_buf[8]; - size_t spi_len; - CHECK_DIF_OK(dif_spi_device_recv(spi, spi_buf, sizeof(spi_buf), &spi_len)); - if (spi_len > 0) { - uint32_t echo_word = spi_buf[0] ^ 0x01010101; - CHECK_DIF_OK(dif_spi_device_send(spi, &echo_word, sizeof(uint32_t), - /*bytes_sent=*/NULL)); - LOG_INFO("SPI: %!s", spi_len, spi_buf); - } -} - void demo_uart_to_uart_and_gpio_echo(dif_uart_t *uart, dif_gpio_t *gpio) { while (true) { size_t chars_available; diff --git a/sw/device/examples/demos.h b/sw/device/examples/demos.h index 5fe8f42373add..52e12d618750a 100644 --- a/sw/device/examples/demos.h +++ b/sw/device/examples/demos.h @@ -8,7 +8,6 @@ #include #include "sw/device/lib/dif/dif_gpio.h" -#include "sw/device/lib/dif/dif_spi_device.h" #include "sw/device/lib/dif/dif_uart.h" /** @@ -37,12 +36,6 @@ void demo_gpio_startup(dif_gpio_t *gpio); */ uint32_t demo_gpio_to_log_echo(dif_gpio_t *gpio, uint32_t prev_gpio_state); -/** - * Attempts to read at most 32 bytes from SPI, and echo them as printable - * characters to LOG. - */ -void demo_spi_to_log_echo(dif_spi_device_handle_t *spi); - /** * Attempts to read characters from UART and immediately echo them back, * as well as to write its bits to GPIO pins 8-15. diff --git a/sw/device/examples/hello_usbdev/BUILD b/sw/device/examples/hello_usbdev/BUILD index b24cf2e888130..8a961fb0a610f 100644 --- a/sw/device/examples/hello_usbdev/BUILD +++ b/sw/device/examples/hello_usbdev/BUILD @@ -38,7 +38,6 @@ cc_library( "//sw/device/lib/crt", "//sw/device/lib/dif:gpio", "//sw/device/lib/dif:pinmux", - "//sw/device/lib/dif:spi_device", "//sw/device/lib/dif:uart", "//sw/device/lib/runtime:hart", "//sw/device/lib/runtime:log", diff --git a/sw/device/examples/hello_usbdev/hello_usbdev.c b/sw/device/examples/hello_usbdev/hello_usbdev.c index ff4bb1410edf6..5ab466df54162 100644 --- a/sw/device/examples/hello_usbdev/hello_usbdev.c +++ b/sw/device/examples/hello_usbdev/hello_usbdev.c @@ -9,7 +9,6 @@ #include "sw/device/lib/arch/device.h" #include "sw/device/lib/dif/dif_gpio.h" #include "sw/device/lib/dif/dif_pinmux.h" -#include "sw/device/lib/dif/dif_spi_device.h" #include "sw/device/lib/dif/dif_uart.h" #include "sw/device/lib/runtime/hart.h" #include "sw/device/lib/runtime/log.h" @@ -74,7 +73,6 @@ static size_t usb_chars_recved_total; static dif_gpio_t gpio; static dif_pinmux_t pinmux; -static dif_spi_device_handle_t spi; static dif_uart_t uart; /** @@ -161,26 +159,6 @@ void _ottf_main(void) { })); base_uart_stdout(&uart); - CHECK_DIF_OK(dif_spi_device_init_handle( - mmio_region_from_addr(TOP_EARLGREY_SPI_DEVICE_BASE_ADDR), &spi)); - dif_spi_device_config_t spi_config = { - .clock_polarity = kDifSpiDeviceEdgePositive, - .data_phase = kDifSpiDeviceEdgeNegative, - .tx_order = kDifSpiDeviceBitOrderMsbToLsb, - .rx_order = kDifSpiDeviceBitOrderMsbToLsb, - .device_mode = kDifSpiDeviceModeGeneric, - .mode_cfg = - { - .generic = - { - .rx_fifo_commit_wait = 63, - .rx_fifo_len = kDifSpiDeviceBufferLen / 2, - .tx_fifo_len = kDifSpiDeviceBufferLen / 2, - }, - }, - }; - CHECK_DIF_OK(dif_spi_device_configure(&spi, spi_config)); - CHECK_DIF_OK( dif_gpio_init(mmio_region_from_addr(TOP_EARLGREY_GPIO_BASE_ADDR), &gpio)); // Enable GPIO: 0-7 and 16 is input; 8-15 is output. @@ -211,7 +189,6 @@ void _ottf_main(void) { &pinmux, kTopEarlgreyPinmuxPeripheralInUsbdevSense, kTopEarlgreyPinmuxInselConstantOne)); } - CHECK_DIF_OK(dif_spi_device_send(&spi, "SPI!", 4, /*bytes_sent=*/NULL)); // The TI phy always uses a differential TX interface CHECK_STATUS_OK(usb_testutils_init(&usbdev, pinflip, differential_xcvr, @@ -236,7 +213,6 @@ void _ottf_main(void) { CHECK_STATUS_OK(usb_testutils_poll(&usbdev)); gpio_state = demo_gpio_to_log_echo(&gpio, gpio_state); - demo_spi_to_log_echo(&spi); while (true) { size_t chars_available; diff --git a/sw/device/examples/hello_world/BUILD b/sw/device/examples/hello_world/BUILD index f2ed53aad6805..50cf6a0368dd6 100644 --- a/sw/device/examples/hello_world/BUILD +++ b/sw/device/examples/hello_world/BUILD @@ -36,7 +36,6 @@ cc_library( "//sw/device/lib/crt", "//sw/device/lib/dif:gpio", "//sw/device/lib/dif:pinmux", - "//sw/device/lib/dif:spi_device", "//sw/device/lib/dif:uart", "//sw/device/lib/runtime:hart", "//sw/device/lib/runtime:log", diff --git a/sw/device/examples/hello_world/hello_world.c b/sw/device/examples/hello_world/hello_world.c index 2d7bedac29422..e7de5f1ce9792 100644 --- a/sw/device/examples/hello_world/hello_world.c +++ b/sw/device/examples/hello_world/hello_world.c @@ -6,7 +6,6 @@ #include "sw/device/lib/arch/device.h" #include "sw/device/lib/dif/dif_gpio.h" #include "sw/device/lib/dif/dif_pinmux.h" -#include "sw/device/lib/dif/dif_spi_device.h" #include "sw/device/lib/dif/dif_uart.h" #include "sw/device/lib/runtime/hart.h" #include "sw/device/lib/runtime/log.h" @@ -21,7 +20,6 @@ OTTF_DEFINE_TEST_CONFIG(); static dif_gpio_t gpio; static dif_pinmux_t pinmux; -static dif_spi_device_handle_t spi; static dif_uart_t uart; static dif_pinmux_index_t leds[] = { @@ -74,26 +72,6 @@ void _ottf_main(void) { })); base_uart_stdout(&uart); - CHECK_DIF_OK(dif_spi_device_init_handle( - mmio_region_from_addr(TOP_EARLGREY_SPI_DEVICE_BASE_ADDR), &spi)); - dif_spi_device_config_t spi_config = { - .clock_polarity = kDifSpiDeviceEdgePositive, - .data_phase = kDifSpiDeviceEdgeNegative, - .tx_order = kDifSpiDeviceBitOrderMsbToLsb, - .rx_order = kDifSpiDeviceBitOrderMsbToLsb, - .device_mode = kDifSpiDeviceModeGeneric, - .mode_cfg = - { - .generic = - { - .rx_fifo_commit_wait = 63, - .rx_fifo_len = kDifSpiDeviceBufferLen / 2, - .tx_fifo_len = kDifSpiDeviceBufferLen / 2, - }, - }, - }; - CHECK_DIF_OK(dif_spi_device_configure(&spi, spi_config)); - CHECK_DIF_OK( dif_gpio_init(mmio_region_from_addr(TOP_EARLGREY_GPIO_BASE_ADDR), &gpio)); // Enable GPIO: 0-3 is output; 8-11 is input. @@ -114,14 +92,10 @@ void _ottf_main(void) { "The LEDs show the lower nibble of the ASCII code of the last " "character."); - CHECK_DIF_OK(dif_spi_device_send(&spi, "SPI!", 4, - /*bytes_sent=*/NULL)); - uint32_t gpio_state = 0; while (true) { busy_spin_micros(10 * 1000); // 10 ms gpio_state = demo_gpio_to_log_echo(&gpio, gpio_state); - demo_spi_to_log_echo(&spi); demo_uart_to_uart_and_gpio_echo(&uart, &gpio); } } diff --git a/sw/device/lib/dif/autogen/dif_spi_device_autogen.c b/sw/device/lib/dif/autogen/dif_spi_device_autogen.c index 6fa8ec3a36659..134ee827d920d 100644 --- a/sw/device/lib/dif/autogen/dif_spi_device_autogen.c +++ b/sw/device/lib/dif/autogen/dif_spi_device_autogen.c @@ -54,24 +54,6 @@ dif_result_t dif_spi_device_alert_force(const dif_spi_device_t *spi_device, static bool spi_device_get_irq_bit_index(dif_spi_device_irq_t irq, bitfield_bit32_index_t *index_out) { switch (irq) { - case kDifSpiDeviceIrqGenericRxFull: - *index_out = SPI_DEVICE_INTR_COMMON_GENERIC_RX_FULL_BIT; - break; - case kDifSpiDeviceIrqGenericRxWatermark: - *index_out = SPI_DEVICE_INTR_COMMON_GENERIC_RX_WATERMARK_BIT; - break; - case kDifSpiDeviceIrqGenericTxWatermark: - *index_out = SPI_DEVICE_INTR_COMMON_GENERIC_TX_WATERMARK_BIT; - break; - case kDifSpiDeviceIrqGenericRxError: - *index_out = SPI_DEVICE_INTR_COMMON_GENERIC_RX_ERROR_BIT; - break; - case kDifSpiDeviceIrqGenericRxOverflow: - *index_out = SPI_DEVICE_INTR_COMMON_GENERIC_RX_OVERFLOW_BIT; - break; - case kDifSpiDeviceIrqGenericTxUnderflow: - *index_out = SPI_DEVICE_INTR_COMMON_GENERIC_TX_UNDERFLOW_BIT; - break; case kDifSpiDeviceIrqUploadCmdfifoNotEmpty: *index_out = SPI_DEVICE_INTR_COMMON_UPLOAD_CMDFIFO_NOT_EMPTY_BIT; break; @@ -98,9 +80,8 @@ static bool spi_device_get_irq_bit_index(dif_spi_device_irq_t irq, } static dif_irq_type_t irq_types[] = { - kDifIrqTypeEvent, kDifIrqTypeEvent, kDifIrqTypeEvent, kDifIrqTypeEvent, - kDifIrqTypeEvent, kDifIrqTypeEvent, kDifIrqTypeEvent, kDifIrqTypeEvent, - kDifIrqTypeEvent, kDifIrqTypeEvent, kDifIrqTypeEvent, kDifIrqTypeStatus, + kDifIrqTypeEvent, kDifIrqTypeEvent, kDifIrqTypeEvent, + kDifIrqTypeEvent, kDifIrqTypeEvent, kDifIrqTypeStatus, }; OT_WARN_UNUSED_RESULT diff --git a/sw/device/lib/dif/autogen/dif_spi_device_autogen.h b/sw/device/lib/dif/autogen/dif_spi_device_autogen.h index 2e4b0a0232166..55120dec782be 100644 --- a/sw/device/lib/dif/autogen/dif_spi_device_autogen.h +++ b/sw/device/lib/dif/autogen/dif_spi_device_autogen.h @@ -77,59 +77,35 @@ dif_result_t dif_spi_device_alert_force(const dif_spi_device_t *spi_device, * A spi_device interrupt request type. */ typedef enum dif_spi_device_irq { - /** - * RX SRAM FIFO Full - */ - kDifSpiDeviceIrqGenericRxFull = 0, - /** - * RX SRAM FIFO is above the level - */ - kDifSpiDeviceIrqGenericRxWatermark = 1, - /** - * TX SRAM FIFO is under the level - */ - kDifSpiDeviceIrqGenericTxWatermark = 2, - /** - * SDI in FwMode has error - */ - kDifSpiDeviceIrqGenericRxError = 3, - /** - * RX Async FIFO overflow - */ - kDifSpiDeviceIrqGenericRxOverflow = 4, - /** - * TX Async FIFO underflow - */ - kDifSpiDeviceIrqGenericTxUnderflow = 5, /** * Upload Command FIFO is not empty */ - kDifSpiDeviceIrqUploadCmdfifoNotEmpty = 6, + kDifSpiDeviceIrqUploadCmdfifoNotEmpty = 0, /** * Upload payload is not empty. The event occurs after SPI transaction * completed */ - kDifSpiDeviceIrqUploadPayloadNotEmpty = 7, + kDifSpiDeviceIrqUploadPayloadNotEmpty = 1, /** * Upload payload overflow event. When a SPI Host system issues a command * with payload more than 256B, this event is reported. When it happens, SW * should read the last written payload index CSR to figure out the starting * address of the last 256B. */ - kDifSpiDeviceIrqUploadPayloadOverflow = 8, + kDifSpiDeviceIrqUploadPayloadOverflow = 2, /** * Read Buffer Threshold event. The host system accesses greater than or * equal to the threshold of a buffer. */ - kDifSpiDeviceIrqReadbufWatermark = 9, + kDifSpiDeviceIrqReadbufWatermark = 3, /** * Read buffer flipped event. The host system accesses other side of buffer. */ - kDifSpiDeviceIrqReadbufFlip = 10, + kDifSpiDeviceIrqReadbufFlip = 4, /** * TPM Header(Command/Address) buffer available */ - kDifSpiDeviceIrqTpmHeaderNotEmpty = 11, + kDifSpiDeviceIrqTpmHeaderNotEmpty = 5, } dif_spi_device_irq_t; /** diff --git a/sw/device/lib/dif/autogen/dif_spi_device_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_spi_device_autogen_unittest.cc index ec6a7428e618d..61c593e4078ff 100644 --- a/sw/device/lib/dif/autogen/dif_spi_device_autogen_unittest.cc +++ b/sw/device/lib/dif/autogen/dif_spi_device_autogen_unittest.cc @@ -62,13 +62,13 @@ TEST_F(IrqGetTypeTest, NullArgs) { dif_irq_type_t type; EXPECT_DIF_BADARG(dif_spi_device_irq_get_type( - nullptr, kDifSpiDeviceIrqGenericRxFull, &type)); + nullptr, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, &type)); EXPECT_DIF_BADARG(dif_spi_device_irq_get_type( - &spi_device_, kDifSpiDeviceIrqGenericRxFull, nullptr)); + &spi_device_, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, nullptr)); EXPECT_DIF_BADARG(dif_spi_device_irq_get_type( - nullptr, kDifSpiDeviceIrqGenericRxFull, nullptr)); + nullptr, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, nullptr)); } TEST_F(IrqGetTypeTest, BadIrq) { @@ -84,7 +84,7 @@ TEST_F(IrqGetTypeTest, Success) { dif_irq_type_t type; EXPECT_DIF_OK(dif_spi_device_irq_get_type( - &spi_device_, kDifSpiDeviceIrqGenericRxFull, &type)); + &spi_device_, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, &type)); EXPECT_EQ(type, 0); } @@ -123,13 +123,13 @@ TEST_F(IrqIsPendingTest, NullArgs) { bool is_pending; EXPECT_DIF_BADARG(dif_spi_device_irq_is_pending( - nullptr, kDifSpiDeviceIrqGenericRxFull, &is_pending)); + nullptr, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, &is_pending)); EXPECT_DIF_BADARG(dif_spi_device_irq_is_pending( - &spi_device_, kDifSpiDeviceIrqGenericRxFull, nullptr)); + &spi_device_, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, nullptr)); EXPECT_DIF_BADARG(dif_spi_device_irq_is_pending( - nullptr, kDifSpiDeviceIrqGenericRxFull, nullptr)); + nullptr, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, nullptr)); } TEST_F(IrqIsPendingTest, BadIrq) { @@ -145,9 +145,9 @@ TEST_F(IrqIsPendingTest, Success) { // Get the first IRQ state. irq_state = false; EXPECT_READ32(SPI_DEVICE_INTR_STATE_REG_OFFSET, - {{SPI_DEVICE_INTR_STATE_GENERIC_RX_FULL_BIT, true}}); + {{SPI_DEVICE_INTR_STATE_UPLOAD_CMDFIFO_NOT_EMPTY_BIT, true}}); EXPECT_DIF_OK(dif_spi_device_irq_is_pending( - &spi_device_, kDifSpiDeviceIrqGenericRxFull, &irq_state)); + &spi_device_, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, &irq_state)); EXPECT_TRUE(irq_state); // Get the last IRQ state. @@ -168,7 +168,7 @@ TEST_F(AcknowledgeStateTest, NullArgs) { } TEST_F(AcknowledgeStateTest, AckSnapshot) { - constexpr uint32_t num_irqs = 12; + constexpr uint32_t num_irqs = 6; constexpr uint32_t irq_mask = (uint64_t{1} << num_irqs) - 1; dif_spi_device_irq_state_snapshot_t irq_snapshot = 1; @@ -206,8 +206,8 @@ TEST_F(AcknowledgeAllTest, Success) { class IrqAcknowledgeTest : public SpiDeviceTest {}; TEST_F(IrqAcknowledgeTest, NullArgs) { - EXPECT_DIF_BADARG( - dif_spi_device_irq_acknowledge(nullptr, kDifSpiDeviceIrqGenericRxFull)); + EXPECT_DIF_BADARG(dif_spi_device_irq_acknowledge( + nullptr, kDifSpiDeviceIrqUploadCmdfifoNotEmpty)); } TEST_F(IrqAcknowledgeTest, BadIrq) { @@ -218,9 +218,9 @@ TEST_F(IrqAcknowledgeTest, BadIrq) { TEST_F(IrqAcknowledgeTest, Success) { // Clear the first IRQ state. EXPECT_WRITE32(SPI_DEVICE_INTR_STATE_REG_OFFSET, - {{SPI_DEVICE_INTR_STATE_GENERIC_RX_FULL_BIT, true}}); - EXPECT_DIF_OK(dif_spi_device_irq_acknowledge(&spi_device_, - kDifSpiDeviceIrqGenericRxFull)); + {{SPI_DEVICE_INTR_STATE_UPLOAD_CMDFIFO_NOT_EMPTY_BIT, true}}); + EXPECT_DIF_OK(dif_spi_device_irq_acknowledge( + &spi_device_, kDifSpiDeviceIrqUploadCmdfifoNotEmpty)); // Clear the last IRQ state. EXPECT_WRITE32(SPI_DEVICE_INTR_STATE_REG_OFFSET, @@ -232,8 +232,8 @@ TEST_F(IrqAcknowledgeTest, Success) { class IrqForceTest : public SpiDeviceTest {}; TEST_F(IrqForceTest, NullArgs) { - EXPECT_DIF_BADARG( - dif_spi_device_irq_force(nullptr, kDifSpiDeviceIrqGenericRxFull, true)); + EXPECT_DIF_BADARG(dif_spi_device_irq_force( + nullptr, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, true)); } TEST_F(IrqForceTest, BadIrq) { @@ -244,9 +244,9 @@ TEST_F(IrqForceTest, BadIrq) { TEST_F(IrqForceTest, Success) { // Force first IRQ. EXPECT_WRITE32(SPI_DEVICE_INTR_TEST_REG_OFFSET, - {{SPI_DEVICE_INTR_TEST_GENERIC_RX_FULL_BIT, true}}); - EXPECT_DIF_OK(dif_spi_device_irq_force(&spi_device_, - kDifSpiDeviceIrqGenericRxFull, true)); + {{SPI_DEVICE_INTR_TEST_UPLOAD_CMDFIFO_NOT_EMPTY_BIT, true}}); + EXPECT_DIF_OK(dif_spi_device_irq_force( + &spi_device_, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, true)); // Force last IRQ. EXPECT_WRITE32(SPI_DEVICE_INTR_TEST_REG_OFFSET, @@ -261,13 +261,13 @@ TEST_F(IrqGetEnabledTest, NullArgs) { dif_toggle_t irq_state; EXPECT_DIF_BADARG(dif_spi_device_irq_get_enabled( - nullptr, kDifSpiDeviceIrqGenericRxFull, &irq_state)); + nullptr, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, &irq_state)); EXPECT_DIF_BADARG(dif_spi_device_irq_get_enabled( - &spi_device_, kDifSpiDeviceIrqGenericRxFull, nullptr)); + &spi_device_, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, nullptr)); EXPECT_DIF_BADARG(dif_spi_device_irq_get_enabled( - nullptr, kDifSpiDeviceIrqGenericRxFull, nullptr)); + nullptr, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, nullptr)); } TEST_F(IrqGetEnabledTest, BadIrq) { @@ -283,9 +283,9 @@ TEST_F(IrqGetEnabledTest, Success) { // First IRQ is enabled. irq_state = kDifToggleDisabled; EXPECT_READ32(SPI_DEVICE_INTR_ENABLE_REG_OFFSET, - {{SPI_DEVICE_INTR_ENABLE_GENERIC_RX_FULL_BIT, true}}); + {{SPI_DEVICE_INTR_ENABLE_UPLOAD_CMDFIFO_NOT_EMPTY_BIT, true}}); EXPECT_DIF_OK(dif_spi_device_irq_get_enabled( - &spi_device_, kDifSpiDeviceIrqGenericRxFull, &irq_state)); + &spi_device_, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, &irq_state)); EXPECT_EQ(irq_state, kDifToggleEnabled); // Last IRQ is disabled. @@ -303,7 +303,7 @@ TEST_F(IrqSetEnabledTest, NullArgs) { dif_toggle_t irq_state = kDifToggleEnabled; EXPECT_DIF_BADARG(dif_spi_device_irq_set_enabled( - nullptr, kDifSpiDeviceIrqGenericRxFull, irq_state)); + nullptr, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, irq_state)); } TEST_F(IrqSetEnabledTest, BadIrq) { @@ -318,10 +318,11 @@ TEST_F(IrqSetEnabledTest, Success) { // Enable first IRQ. irq_state = kDifToggleEnabled; - EXPECT_MASK32(SPI_DEVICE_INTR_ENABLE_REG_OFFSET, - {{SPI_DEVICE_INTR_ENABLE_GENERIC_RX_FULL_BIT, 0x1, true}}); + EXPECT_MASK32( + SPI_DEVICE_INTR_ENABLE_REG_OFFSET, + {{SPI_DEVICE_INTR_ENABLE_UPLOAD_CMDFIFO_NOT_EMPTY_BIT, 0x1, true}}); EXPECT_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device_, kDifSpiDeviceIrqGenericRxFull, irq_state)); + &spi_device_, kDifSpiDeviceIrqUploadCmdfifoNotEmpty, irq_state)); // Disable last IRQ. irq_state = kDifToggleDisabled; diff --git a/sw/device/lib/dif/dif_rv_plic_unittest.cc b/sw/device/lib/dif/dif_rv_plic_unittest.cc index 0b2d10d49abb5..33e13f182d70d 100644 --- a/sw/device/lib/dif/dif_rv_plic_unittest.cc +++ b/sw/device/lib/dif/dif_rv_plic_unittest.cc @@ -21,7 +21,7 @@ using testing::Test; // If either of these static assertions fail, then the unit-tests for related // API should be revisited. -static_assert(RV_PLIC_PARAM_NUM_SRC == 185, +static_assert(RV_PLIC_PARAM_NUM_SRC == 179, "PLIC instantiation parameters have changed."); static_assert(RV_PLIC_PARAM_NUM_TARGET == 1, "PLIC instantiation parameters have changed."); @@ -100,7 +100,7 @@ class IrqTest : public PlicTest { {RV_PLIC_IE0_2_REG_OFFSET, RV_PLIC_IE0_2_E_95_BIT}, {RV_PLIC_IE0_3_REG_OFFSET, RV_PLIC_IE0_3_E_127_BIT}, {RV_PLIC_IE0_4_REG_OFFSET, RV_PLIC_IE0_4_E_159_BIT}, - {RV_PLIC_IE0_5_REG_OFFSET, RV_PLIC_IE0_5_E_184_BIT}, + {RV_PLIC_IE0_5_REG_OFFSET, RV_PLIC_IE0_5_E_178_BIT}, }}; static constexpr std::array kPendingRegisters{{ @@ -109,7 +109,7 @@ class IrqTest : public PlicTest { {RV_PLIC_IP_2_REG_OFFSET, RV_PLIC_IP_2_P_95_BIT}, {RV_PLIC_IP_3_REG_OFFSET, RV_PLIC_IP_3_P_127_BIT}, {RV_PLIC_IP_4_REG_OFFSET, RV_PLIC_IP_4_P_159_BIT}, - {RV_PLIC_IP_5_REG_OFFSET, RV_PLIC_IP_5_P_184_BIT}, + {RV_PLIC_IP_5_REG_OFFSET, RV_PLIC_IP_5_P_178_BIT}, }}; // Set enable/disable multireg expectations, one bit per call. diff --git a/sw/device/lib/dif/dif_spi_device.c b/sw/device/lib/dif/dif_spi_device.c index 6a3261af7e415..3136349ce8315 100644 --- a/sw/device/lib/dif/dif_spi_device.c +++ b/sw/device/lib/dif/dif_spi_device.c @@ -44,10 +44,6 @@ static inline uint32_t build_control_word( config.tx_order == kDifSpiDeviceBitOrderLsbToMsb); val = bitfield_bit32_write(val, SPI_DEVICE_CFG_RX_ORDER_BIT, config.rx_order == kDifSpiDeviceBitOrderLsbToMsb); - if (config.device_mode == kDifSpiDeviceModeGeneric) { - val = bitfield_field32_write(val, SPI_DEVICE_CFG_TIMER_V_FIELD, - config.mode_cfg.generic.rx_fifo_commit_wait); - } return val; } @@ -68,8 +64,8 @@ dif_result_t dif_spi_device_configure(dif_spi_device_handle_t *spi, uint32_t device_mode; switch (config.device_mode) { - case kDifSpiDeviceModeGeneric: - device_mode = SPI_DEVICE_CONTROL_MODE_VALUE_FWMODE; + case kDifSpiDeviceModeDisabled: + device_mode = SPI_DEVICE_CONTROL_MODE_VALUE_DISABLED; break; case kDifSpiDeviceModeFlashEmulation: device_mode = SPI_DEVICE_CONTROL_MODE_VALUE_FLASHMODE; @@ -81,61 +77,18 @@ dif_result_t dif_spi_device_configure(dif_spi_device_handle_t *spi, return kDifBadArg; } - // NOTE: we do not write to any registers until performing all - // function argument checks, to avoid a halfway-configured SPI. - - if (config.device_mode == kDifSpiDeviceModeGeneric) { - uint16_t rx_fifo_start = 0x0; - uint16_t rx_fifo_end = config.mode_cfg.generic.rx_fifo_len - 1; - uint16_t tx_fifo_start = rx_fifo_end + 1; - uint16_t tx_fifo_end = - tx_fifo_start + config.mode_cfg.generic.tx_fifo_len - 1; - if (tx_fifo_end >= kDifSpiDeviceBufferLen) { - // We've overflown the SRAM region... - return kDifBadArg; - } - - uint32_t rx_fifo_bounds = 0; - rx_fifo_bounds = bitfield_field32_write( - rx_fifo_bounds, SPI_DEVICE_RXF_ADDR_BASE_FIELD, rx_fifo_start); - rx_fifo_bounds = bitfield_field32_write( - rx_fifo_bounds, SPI_DEVICE_RXF_ADDR_LIMIT_FIELD, rx_fifo_end); - - uint32_t tx_fifo_bounds = 0; - tx_fifo_bounds = bitfield_field32_write( - tx_fifo_bounds, SPI_DEVICE_TXF_ADDR_BASE_FIELD, tx_fifo_start); - tx_fifo_bounds = bitfield_field32_write( - tx_fifo_bounds, SPI_DEVICE_TXF_ADDR_LIMIT_FIELD, tx_fifo_end); - - mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_RXF_ADDR_REG_OFFSET, - rx_fifo_bounds); - mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_TXF_ADDR_REG_OFFSET, - tx_fifo_bounds); - } - uint32_t device_config = build_control_word(config); mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_CFG_REG_OFFSET, device_config); - // Turn off SRAM clock to change modes. uint32_t control = mmio_region_read32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET); - control = - bitfield_bit32_write(control, SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, false); - mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET, - control); - // Change mode. control = bitfield_field32_write(control, SPI_DEVICE_CONTROL_MODE_FIELD, device_mode); mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET, control); - // Re-enable SRAM clock. - control = - bitfield_bit32_write(control, SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, true); - mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET, - control); spi->config = config; return kDifOk; } @@ -164,345 +117,6 @@ dif_result_t dif_spi_device_set_passthrough_mode(dif_spi_device_handle_t *spi, return kDifOk; } -dif_result_t dif_spi_device_reset_generic_tx_fifo( - dif_spi_device_handle_t *spi) { - if (spi == NULL) { - return kDifBadArg; - } - uint32_t control = - mmio_region_read32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET); - control = - bitfield_bit32_write(control, SPI_DEVICE_CONTROL_RST_TXFIFO_BIT, true); - mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET, - control); - control = - bitfield_bit32_write(control, SPI_DEVICE_CONTROL_RST_TXFIFO_BIT, false); - mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET, - control); - return kDifOk; -} - -dif_result_t dif_spi_device_reset_generic_rx_fifo( - dif_spi_device_handle_t *spi) { - if (spi == NULL) { - return kDifBadArg; - } - uint32_t control = - mmio_region_read32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET); - control = - bitfield_bit32_write(control, SPI_DEVICE_CONTROL_RST_RXFIFO_BIT, true); - mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET, - control); - control = - bitfield_bit32_write(control, SPI_DEVICE_CONTROL_RST_RXFIFO_BIT, false); - mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET, - control); - return kDifOk; -} - -dif_result_t dif_spi_device_set_sram_clock_enable(dif_spi_device_handle_t *spi, - dif_toggle_t enable) { - if (spi == NULL || !dif_is_valid_toggle(enable)) { - return kDifBadArg; - } - bool clk_enable = dif_toggle_to_bool(enable); - uint32_t control = - mmio_region_read32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET); - control = bitfield_bit32_write(control, SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, - clk_enable); - mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET, - control); - return kDifOk; -} - -dif_result_t dif_spi_device_get_sram_clock_enable(dif_spi_device_handle_t *spi, - dif_toggle_t *enabled) { - if (spi == NULL || enabled == NULL) { - return kDifBadArg; - } - uint32_t control = - mmio_region_read32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET); - *enabled = dif_bool_to_toggle( - bitfield_bit32_read(control, SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT)); - return kDifOk; -} - -dif_result_t dif_spi_device_abort(dif_spi_device_handle_t *spi) { - if (spi == NULL) { - return kDifBadArg; - } - - // Set the `abort` bit, and then spin until `abort_done` is asserted. - uint32_t reg = - mmio_region_read32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET); - reg = bitfield_bit32_write(reg, SPI_DEVICE_CONTROL_ABORT_BIT, true); - mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_CONTROL_REG_OFFSET, reg); - - while (true) { - uint32_t reg = - mmio_region_read32(spi->dev.base_addr, SPI_DEVICE_STATUS_REG_OFFSET); - if (bitfield_bit32_read(reg, SPI_DEVICE_STATUS_ABORT_DONE_BIT)) { - return kDifOk; - } - } -} - -dif_result_t dif_spi_device_set_irq_levels(dif_spi_device_handle_t *spi, - uint16_t rx_level, - uint16_t tx_level) { - if (spi == NULL) { - return kDifBadArg; - } - - uint32_t compressed_limit = 0; - compressed_limit = bitfield_field32_write( - compressed_limit, SPI_DEVICE_FIFO_LEVEL_RXLVL_FIELD, rx_level); - compressed_limit = bitfield_field32_write( - compressed_limit, SPI_DEVICE_FIFO_LEVEL_TXLVL_FIELD, tx_level); - mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_FIFO_LEVEL_REG_OFFSET, - compressed_limit); - - return kDifOk; -} - -/** - * Parameters for compressing and decompressing a FIFO pointer register. - */ -typedef struct fifo_ptr_params { - ptrdiff_t reg_offset; - ptrdiff_t write_offset; - ptrdiff_t read_offset; - uint32_t write_mask; - uint32_t read_mask; -} fifo_ptr_params_t; - -/** - * Parameters for the transmission FIFO. - */ -static const fifo_ptr_params_t kTxFifoParams = { - .reg_offset = SPI_DEVICE_TXF_PTR_REG_OFFSET, - .write_offset = SPI_DEVICE_TXF_PTR_WPTR_OFFSET, - .write_mask = SPI_DEVICE_TXF_PTR_WPTR_MASK, - .read_offset = SPI_DEVICE_TXF_PTR_RPTR_OFFSET, - .read_mask = SPI_DEVICE_TXF_PTR_RPTR_MASK, -}; - -/** - * Parameters for the receipt FIFO. - */ -static const fifo_ptr_params_t kRxFifoParams = { - .reg_offset = SPI_DEVICE_RXF_PTR_REG_OFFSET, - .write_offset = SPI_DEVICE_RXF_PTR_WPTR_OFFSET, - .write_mask = SPI_DEVICE_RXF_PTR_WPTR_MASK, - .read_offset = SPI_DEVICE_RXF_PTR_RPTR_OFFSET, - .read_mask = SPI_DEVICE_RXF_PTR_RPTR_MASK, -}; - -/** - * An exploded FIFO pointer value, consisting of a `uint11_t` - * offset part (an offset into a FIFO), and a `uint1_t` phase - * (which indicates whether this pointer has wrapped around or not). - * - * See also `fifo_ptrs_t`. - */ -typedef struct fifo_ptr { - uint16_t offset; - bool phase; -} fifo_ptr_t; - -// Masks for extracting the phase and offset parts from a -// compressed FIFO pointer. -static const uint16_t kFifoPhaseMask = (1 << 12); -static const uint16_t kFifoOffsetMask = (1 << 12) - 1; - -/** - * Modifies a `fifo_ptr_t` into a FIFO of length `fifo_len` by - * incrementing it by `increment`, making sure to correctly flip the - * phase bit on overflow. - * - * @param ptr the pointer to increment. - * @param increment the amount to increment by. - * @param fifo_len the length of the FIFO the pointer points into. - */ -static void fifo_ptr_increment(fifo_ptr_t *ptr, uint16_t increment, - uint16_t fifo_len) { - uint32_t inc_with_overflow = ptr->offset + increment; - // If we would overflow, wrap and flip the overflow bit. - if (inc_with_overflow >= fifo_len) { - inc_with_overflow -= fifo_len; - ptr->phase = !ptr->phase; - } - - ptr->offset = inc_with_overflow & kFifoOffsetMask; -} - -/** - * A decompressed FIFO pointer register, consisting of a read offset - * and a write offset within the FIFO region. - * - * The offsets themselves are only `uint11_t`, with an additional - * 12th "phase" bit used for detecting the wrap around behavior of - * the ring buffer FIFOs. - */ -typedef struct fifo_ptrs { - fifo_ptr_t write_ptr; - fifo_ptr_t read_ptr; -} fifo_ptrs_t; - -/** - * Expands read and write FIFO pointers out of `spi`, using the given FIFO - * parameters. - * - * @param spi the SPI device. - * @param params bitfield parameters for the FIFO. - * @return expanded pointers read out of `spi`. - */ -static fifo_ptrs_t decompress_ptrs(const dif_spi_device_handle_t *spi, - fifo_ptr_params_t params) { - uint32_t ptr = mmio_region_read32(spi->dev.base_addr, params.reg_offset); - uint16_t write_val = - (uint16_t)((ptr >> params.write_offset) & params.write_mask); - uint16_t read_val = - (uint16_t)((ptr >> params.read_offset) & params.read_mask); - return (fifo_ptrs_t){ - .write_ptr = - { - .offset = write_val & kFifoOffsetMask, - .phase = (write_val & kFifoPhaseMask) != 0, - }, - .read_ptr = - { - .offset = read_val & kFifoOffsetMask, - .phase = (read_val & kFifoPhaseMask) != 0, - }, - }; -} - -/** - * Writes back read and write FIFO pointers into `spi`, using the given FIFO - * parameters. - * - * @param spi the SPI device. - * @param params bitfield parameters for the FIFO. - * @param ptrs the new pointer values. - */ -static void compress_ptrs(dif_spi_device_handle_t *spi, - fifo_ptr_params_t params, fifo_ptrs_t ptrs) { - uint16_t write_val = ptrs.write_ptr.offset; - if (ptrs.write_ptr.phase) { - write_val |= kFifoPhaseMask; - } - uint16_t read_val = ptrs.read_ptr.offset; - if (ptrs.read_ptr.phase) { - read_val |= kFifoPhaseMask; - } - - uint32_t ptr = 0; - ptr = bitfield_field32_write(ptr, - (bitfield_field32_t){ - .mask = params.write_mask, - .index = (uint32_t)params.write_offset, - }, - write_val); - ptr = bitfield_field32_write(ptr, - (bitfield_field32_t){ - .mask = params.read_mask, - .index = (uint32_t)params.read_offset, - }, - read_val); - mmio_region_write32(spi->dev.base_addr, params.reg_offset, ptr); -} - -/** - * Counts the number of bytes from the read pointer to the write pointer in - * `ptrs`, in a FIFO of length `fifo_len`. - * - * @param ptrs a set of FIFO pointers. - * @param fifo_len the length of the fifo, in bytes. - * @return the number of bytes "in use". - */ -static uint16_t fifo_bytes_in_use(fifo_ptrs_t ptrs, uint16_t fifo_len) { - // This represents the case where the valid data of the fifo is "inclusive", - // i.e., the buffer looks like (where a / represents valid data): - // [ ///// ] - // ^ ^ - // r w - // - // In particular, when r == w, the fifo is empty. - if (ptrs.write_ptr.phase == ptrs.read_ptr.phase) { - return ptrs.write_ptr.offset - ptrs.read_ptr.offset; - } - - // This represents the case where the valid data of the fifo is "exclusive", - // i.e., the buffer looks like (where a / represents valid data): - // [/ //////] - // ^ ^ - // w r - // - // In particular, when r == w, the fifo is full. - return fifo_len - (ptrs.read_ptr.offset - ptrs.write_ptr.offset); -} - -dif_result_t dif_spi_device_rx_pending(const dif_spi_device_handle_t *spi, - size_t *bytes_pending) { - if (spi == NULL || bytes_pending == NULL) { - return kDifBadArg; - } - - fifo_ptrs_t ptrs = decompress_ptrs(spi, kRxFifoParams); - *bytes_pending = - fifo_bytes_in_use(ptrs, spi->config.mode_cfg.generic.rx_fifo_len); - - return kDifOk; -} - -dif_result_t dif_spi_device_tx_pending(const dif_spi_device_handle_t *spi, - size_t *bytes_pending) { - if (spi == NULL || bytes_pending == NULL) { - return kDifBadArg; - } - - fifo_ptrs_t ptrs = decompress_ptrs(spi, kTxFifoParams); - *bytes_pending = - fifo_bytes_in_use(ptrs, spi->config.mode_cfg.generic.tx_fifo_len); - - return kDifOk; -} - -dif_result_t dif_spi_device_get_async_fifo_levels(dif_spi_device_handle_t *spi, - uint16_t *rx_fifo_level, - uint16_t *tx_fifo_level) { - if (spi == NULL || rx_fifo_level == NULL || tx_fifo_level == NULL) { - return kDifBadArg; - } - uint32_t async_fifo_level = mmio_region_read32( - spi->dev.base_addr, SPI_DEVICE_ASYNC_FIFO_LEVEL_REG_OFFSET); - *rx_fifo_level = (uint16_t)bitfield_field32_read( - async_fifo_level, SPI_DEVICE_ASYNC_FIFO_LEVEL_RXLVL_FIELD); - *tx_fifo_level = (uint16_t)bitfield_field32_read( - async_fifo_level, SPI_DEVICE_ASYNC_FIFO_LEVEL_TXLVL_FIELD); - return kDifOk; -} - -dif_result_t dif_spi_device_get_generic_fifo_status( - dif_spi_device_handle_t *spi, - dif_spi_device_generic_fifo_status_t *status) { - if (spi == NULL || status == NULL) { - return kDifBadArg; - } - uint32_t reg_val = - mmio_region_read32(spi->dev.base_addr, SPI_DEVICE_STATUS_REG_OFFSET); - status->rx_full = - bitfield_bit32_read(reg_val, SPI_DEVICE_STATUS_RXF_FULL_BIT); - status->rx_empty = - bitfield_bit32_read(reg_val, SPI_DEVICE_STATUS_RXF_EMPTY_BIT); - status->tx_full = - bitfield_bit32_read(reg_val, SPI_DEVICE_STATUS_TXF_FULL_BIT); - status->tx_empty = - bitfield_bit32_read(reg_val, SPI_DEVICE_STATUS_TXF_EMPTY_BIT); - return kDifOk; -} - dif_result_t dif_spi_device_get_csb_status(dif_spi_device_handle_t *spi, bool *csb) { if (spi == NULL || csb == NULL) { @@ -514,154 +128,6 @@ dif_result_t dif_spi_device_get_csb_status(dif_spi_device_handle_t *spi, return kDifOk; } -/** - * Performs a "memcpy" of sorts between a main memory buffer and SPI SRAM, - * which does not support non-word I/O. - * - * If `is_recv` is set, then the copy direction is `spi -> buf`. If it is - * unset, the copy direction is `buf -> spi`. - * - * @param spi a SPI device. - * @param fifo a decompressed FIFO pointer pair. - * @param fifo_base the offset from start of SRAM for the FIFO to copy to/from. - * @param fifo_len the length of the FIFO, in bytes. - * @param byte_buf a main memory buffer for copying from/to. - * @param buf_len the length of the main memory buffer. - * @param is_recv whether this is a SPI reciept or SPI transmit transaction. - * @return the number of bytes copied. - */ -static size_t spi_memcpy(dif_spi_device_handle_t *spi, fifo_ptrs_t *fifo, - uint16_t fifo_base, uint16_t fifo_len, - uint8_t *byte_buf, size_t buf_len, bool is_recv) { - uint16_t bytes_left = fifo_bytes_in_use(*fifo, fifo_len); - // When sending, the bytes left are the empty space still available. - if (!is_recv) { - bytes_left = fifo_len - bytes_left; - } - - if (bytes_left > buf_len) { - bytes_left = (uint16_t)buf_len; - } - if (bytes_left == 0) { - return 0; - } - const uint16_t total_bytes = bytes_left; - - // For receipt, we advance the read pointer, which indicates how far ahead - // we've read so far. For sending, we advance the write pointer, which - // indicates how far ahead we've written. - fifo_ptr_t *ptr; - if (is_recv) { - ptr = &fifo->read_ptr; - } else { - ptr = &fifo->write_ptr; - } - - // `mmio_region_memcpy_*_mmio32` functions assume sequential memory access - // while the SPI device uses a circular buffer. Therefore, we split the copy - // operation into chunks that access the device buffer sequentially. - while (bytes_left > 0) { - const uint32_t mmio_offset = - SPI_DEVICE_BUFFER_REG_OFFSET + fifo_base + ptr->offset; - const uint32_t bytes_until_wrap = fifo_len - ptr->offset; - uint16_t bytes_to_copy = bytes_left; - if (bytes_to_copy > bytes_until_wrap) { - bytes_to_copy = (uint16_t)bytes_until_wrap; - } - if (is_recv) { - // SPI device buffer -> `byte_buf` - mmio_region_memcpy_from_mmio32(spi->dev.base_addr, mmio_offset, byte_buf, - bytes_to_copy); - } else { - // `byte_buf` -> SPI device buffer - mmio_region_memcpy_to_mmio32(spi->dev.base_addr, mmio_offset, byte_buf, - bytes_to_copy); - } - fifo_ptr_increment(ptr, bytes_to_copy, fifo_len); - byte_buf += bytes_to_copy; - bytes_left -= bytes_to_copy; - } - - return total_bytes; -} - -dif_result_t dif_spi_device_recv(dif_spi_device_handle_t *spi, void *buf, - size_t buf_len, size_t *bytes_received) { - if (spi == NULL || buf == NULL) { - return kDifBadArg; - } - - uint16_t fifo_base = 0; - fifo_ptrs_t fifo = decompress_ptrs(spi, kRxFifoParams); - - size_t bytes = spi_memcpy(spi, &fifo, fifo_base, - spi->config.mode_cfg.generic.rx_fifo_len, - (uint8_t *)buf, buf_len, /*is_recv=*/true); - if (bytes_received != NULL) { - *bytes_received = bytes; - } - if (bytes > 0) { - // Commit the new RX FIFO pointers. - compress_ptrs(spi, kRxFifoParams, fifo); - } - return kDifOk; -} - -dif_result_t dif_spi_device_send(dif_spi_device_handle_t *spi, const void *buf, - size_t buf_len, size_t *bytes_sent) { - if (spi == NULL || buf == NULL) { - return kDifBadArg; - } - - // Start of the TX FIFO is the end of the RX FIFO. - fifo_ptrs_t fifo = decompress_ptrs(spi, kTxFifoParams); - - size_t bytes = - spi_memcpy(spi, &fifo, spi->config.mode_cfg.generic.rx_fifo_len, - spi->config.mode_cfg.generic.tx_fifo_len, (uint8_t *)buf, - buf_len, /*is_recv=*/false); - if (bytes_sent != NULL) { - *bytes_sent = bytes; - } - if (bytes > 0) { - // Commit the new TX FIFO pointers. - compress_ptrs(spi, kTxFifoParams, fifo); - } - return kDifOk; -} - -dif_result_t dif_spi_device_send_polled(dif_spi_device_handle_t *spi, - const void *buf, size_t buf_len) { - if (spi == NULL || buf == NULL || - buf_len > spi->config.mode_cfg.generic.tx_fifo_len) { - return kDifBadArg; - } - if (buf_len == 0) { - return kDifOk; - } - - fifo_ptrs_t tx_fifo; - uint16_t free_fifo_space_bytes = 0; - - do { - tx_fifo = decompress_ptrs(spi, kTxFifoParams); - free_fifo_space_bytes = - spi->config.mode_cfg.generic.tx_fifo_len - - fifo_bytes_in_use(tx_fifo, spi->config.mode_cfg.generic.tx_fifo_len); - } while (free_fifo_space_bytes < buf_len); - - size_t bytes_copied = - spi_memcpy(spi, &tx_fifo, spi->config.mode_cfg.generic.rx_fifo_len, - spi->config.mode_cfg.generic.tx_fifo_len, (uint8_t *)buf, - buf_len, /*is_recv=*/false); - compress_ptrs(spi, kTxFifoParams, tx_fifo); - - if (bytes_copied != buf_len) { - return kDifError; - } - return kDifOk; -} - dif_result_t dif_spi_device_enable_mailbox(dif_spi_device_handle_t *spi, uint32_t address) { if (spi == NULL) { diff --git a/sw/device/lib/dif/dif_spi_device.h b/sw/device/lib/dif/dif_spi_device.h index a49a6d508f840..e3bb41c6b721a 100644 --- a/sw/device/lib/dif/dif_spi_device.h +++ b/sw/device/lib/dif/dif_spi_device.h @@ -29,10 +29,9 @@ extern "C" { */ typedef enum dif_spi_device_mode { /** - * In the generic firmware mode, the hardware dumps incoming data to SRAM and - * outgoing data from the SRAM. + * spi_device will ignore all transactions in this mode configuration. */ - kDifSpiDeviceModeGeneric = 0, + kDifSpiDeviceModeDisabled = 0, /** * In flash emulation mode, the hardware behaves like a SPI NOR flash device. */ @@ -75,26 +74,6 @@ typedef enum dif_spi_device_bit_order { kDifSpiDeviceBitOrderLsbToMsb, } dif_spi_device_bit_order_t; -typedef struct dif_spi_device_generic_mode_config { - /** - * The length, in bytes, that should be reserved for the RX FIFO. - * - * `kDifSpiDeviceBufferLen / 2` is a good default for this value. - */ - uint16_t rx_fifo_len; - /** - * The length, in bytes, that should be reserved for the TX FIFO. - * - * `kDifSpiDeviceBufferLen / 2` is a good default for this value. - */ - uint16_t tx_fifo_len; - /** - * The number of bus clock cycles that the RX FIFO waits before committing a - * sub-word data item to the SRAM. Only used in Generic Mode. - */ - uint8_t rx_fifo_commit_wait; -} dif_spi_device_generic_mode_config_t; - /** * Runtime configuration for SPI. * @@ -107,9 +86,6 @@ typedef struct dif_spi_device_config { dif_spi_device_bit_order_t tx_order; dif_spi_device_bit_order_t rx_order; dif_spi_device_mode_t device_mode; - union { - dif_spi_device_generic_mode_config_t generic; - } mode_cfg; } dif_spi_device_config_t; /** @@ -172,161 +148,6 @@ OT_WARN_UNUSED_RESULT dif_result_t dif_spi_device_set_passthrough_mode(dif_spi_device_handle_t *spi, dif_toggle_t enable); -/** - * Resets the asynchronous TX FIFO in generic mode. - * - * This function should only be called when the upstream spi host is held in - * reset or otherwise is inactive. - * - * @param spi A SPI handle. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_reset_generic_tx_fifo(dif_spi_device_handle_t *spi); - -/** - * Resets the asynchronous RX FIFO in generic mode. - * - * This function should only be called when the upstream spi host is held in - * reset or otherwise is inactive. - * - * @param spi A SPI handle. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_reset_generic_rx_fifo(dif_spi_device_handle_t *spi); - -/** - * Enable or disable the clock for the SRAM backing all the various memory and - * FIFO-related functions. - * - * This function should only be called when the upstream spi host is held in - * reset or otherwise is inactive. - * - * @param spi A SPI handle. - * @param enable Whether to enable or disable the clock. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_set_sram_clock_enable(dif_spi_device_handle_t *spi, - dif_toggle_t enable); - -/** - * Get the current enablement state for the clock of the SRAM backing all the - * various memory and FIFO-related functions. - * - * This function should only be called when the upstream spi host is held in - * reset or otherwise is inactive. - * - * @param spi A SPI handle. - * @param[out] enabled Whether the clock is enabled or disabled. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_get_sram_clock_enable(dif_spi_device_handle_t *spi, - dif_toggle_t *enabled); - -/** - * Issues an "abort" to the given SPI device, causing all in-progress IO to - * halt. - * - * Applies only to generic mode. - * - * @param spi A SPI handle. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_abort(dif_spi_device_handle_t *spi); - -/** - * Sets up the "FIFO level" (that is, number of bytes present in a particular - * FIFO) at which the TxLevel and RxLevel IRQs will fire. - * - * For the reciept side, when the FIFO overflows `rx_level` (i.e., goes over - * the set level), an interrupt is fired. This can be used to detect that more - * data should be read from the RX FIFO. This is the - * `Spi Buffer -> Main Memory` case. - * - * Conversely, for the transmission side, when the FIFO underflows `tx_level` - * (i.e., goes below the set level), an interrupt is fired. This can be used - * to detect that there is free space to write more data to the TX FIFO. - * This is the `Main Memory -> Spi Buffer` case. - * - * Applies only to generic mode. - * - * @param spi A SPI handle. - * @param rx_level The new RX level, as described above. - * @param tx_level The new TX level, as described above. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_set_irq_levels(dif_spi_device_handle_t *spi, - uint16_t rx_level, - uint16_t tx_level); - -/** - * Returns the number of bytes still pending receipt by software in the RX FIFO. - * - * Applies only to generic mode. - * - * @param spi A SPI handle. - * @param[out] bytes_pending The number of bytes pending - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_rx_pending(const dif_spi_device_handle_t *spi, - size_t *bytes_pending); - -/** - * Returns the number of bytes still pending transmission by hardware in the TX - * FIFO. - * - * Applies only to generic mode. - * - * @param spi A SPI handle. - * @param[out] bytes_pending The number of bytes pending - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_tx_pending(const dif_spi_device_handle_t *spi, - size_t *bytes_pending); - -/** - * Get the current async FIFO occupancy levels. Only used in generic mode. - * - * @param spi A SPI handle. - * @param[out] rx_fifo_level The occupancy level of the RX FIFO. - * @param[out] tx_fifo_level The occupancy level of the TX FIFO. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_get_async_fifo_levels(dif_spi_device_handle_t *spi, - uint16_t *rx_fifo_level, - uint16_t *tx_fifo_level); - -/** Represents the status of the synchronous FIFOs in generic mode. */ -typedef struct dif_spi_device_generic_fifo_status { - /** Whether the RX FIFO is full. */ - bool rx_full; - /** Whether the RX FIFO is empty. */ - bool rx_empty; - /** Whether the TX FIFO is full. */ - bool tx_full; - /** Whether the TX FIFO is empty. */ - bool tx_empty; -} dif_spi_device_generic_fifo_status_t; - -/** - * Get the current empty/full status for generic mode's synchronous FIFOs. - * - * @param spi A SPI handle. - * @param[out] status The empty/full status for the FIFOs. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_get_generic_fifo_status( - dif_spi_device_handle_t *spi, dif_spi_device_generic_fifo_status_t *status); - /** * Get the current level of the CSB pin. * @@ -344,54 +165,6 @@ OT_WARN_UNUSED_RESULT dif_result_t dif_spi_device_get_csb_status(dif_spi_device_handle_t *spi, bool *csb); -/** - * Reads at most `buf_len` bytes from the RX FIFO; the number of bytes read - * will be written to `bytes_received`. - * - * Applies only to generic mode. - * - * @param spi A SPI device. - * @param[out] buf A pointer to valid memory. - * @param buf_len The length of the buffer `buf` points to. - * @param[out] bytes_received The number of bytes successfully read; may be - * null. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_recv(dif_spi_device_handle_t *spi, void *buf, - size_t buf_len, size_t *bytes_received); - -/** - * Writes at most `buf_len` bytes to the TX FIFO; the number of bytes actually - * written will be written to `bytes_sent`. - * - * Applies only to generic mode. - * - * @param spi A SPI device. - * @param buf A pointer to bytes to be written. - * @param buf_len The length of the buffer `buf` points to. - * @param[out] bytes_sent The number of bytes successfully written; may be null. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_send(dif_spi_device_handle_t *spi, const void *buf, - size_t buf_len, size_t *bytes_sent); - -/** - * Writes `buf_len` bytes to the TX FIFO, blocking until all bytes can be - * written. - * - * Applies only to generic mode. - * - * @param spi A SPI device. - * @param buf A pointer to bytes to be written. - * @param buf_len The length of the buffer `buf` points to. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_spi_device_send_polled(dif_spi_device_handle_t *spi, - const void *buf, size_t buf_len); - /** * Enable the mailbox region for spi_device flash / passthrough modes. * diff --git a/sw/device/lib/dif/dif_spi_device_unittest.cc b/sw/device/lib/dif/dif_spi_device_unittest.cc index 00a3b0a51109a..5dc4ce724abf5 100644 --- a/sw/device/lib/dif/dif_spi_device_unittest.cc +++ b/sw/device/lib/dif/dif_spi_device_unittest.cc @@ -19,23 +19,6 @@ using ::mock_mmio::LeInt; using ::mock_mmio::MmioTest; using ::mock_mmio::MockDevice; -// Convenience function for assembling a phased FIFO pointer. -uintptr_t FifoPtr(uintptr_t offset, bool phase) { - return offset | (static_cast(phase) << 12); -} - -// Convenience function for generating a vector full of noisy data. -std::vector MakeBlob(size_t len) { - std::vector buf; - buf.resize(len); - uint8_t val = 1; - for (auto &c : buf) { - c = val; - val *= 31; - } - return buf; -} - class SpiTest : public testing::Test, public MmioTest { public: static constexpr uint16_t kFifoLen = 0x800; @@ -51,907 +34,34 @@ static constexpr dif_spi_device_config_t kDefaultConfig = { .data_phase = kDifSpiDeviceEdgeNegative, .tx_order = kDifSpiDeviceBitOrderMsbToLsb, .rx_order = kDifSpiDeviceBitOrderMsbToLsb, - .device_mode = kDifSpiDeviceModeGeneric, - .mode_cfg = {.generic = - { - .rx_fifo_len = SpiTest::kFifoLen, - .tx_fifo_len = SpiTest::kFifoLen, - .rx_fifo_commit_wait = 63, - }}, + .device_mode = kDifSpiDeviceModeDisabled, }; -class AbortTest : public SpiTest {}; - -TEST_F(AbortTest, Immediate) { - EXPECT_MASK32(SPI_DEVICE_CONTROL_REG_OFFSET, - {{SPI_DEVICE_CONTROL_ABORT_BIT, 0x1, 0x1}}); - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, - {{SPI_DEVICE_STATUS_ABORT_DONE_BIT, 0x1}}); - - EXPECT_DIF_OK(dif_spi_device_abort(&spi_)); -} - -TEST_F(AbortTest, Delayed) { - EXPECT_MASK32(SPI_DEVICE_CONTROL_REG_OFFSET, - {{SPI_DEVICE_CONTROL_ABORT_BIT, 0x1, 0x1}}); - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, 0); - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, 0); - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, 0); - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, 0); - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, 0); - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, 0); - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, - {{SPI_DEVICE_STATUS_ABORT_DONE_BIT, 0x1}}); - - EXPECT_DIF_OK(dif_spi_device_abort(&spi_)); -} - -TEST_F(AbortTest, NullArgs) { - EXPECT_DIF_BADARG(dif_spi_device_abort(nullptr)); -} - class ConfigTest : public SpiTest {}; TEST_F(ConfigTest, BasicInit) { - EXPECT_WRITE32(SPI_DEVICE_RXF_ADDR_REG_OFFSET, - { - {SPI_DEVICE_RXF_ADDR_BASE_OFFSET, 0x000}, - {SPI_DEVICE_RXF_ADDR_LIMIT_OFFSET, 0x800 - 1}, - }); - EXPECT_WRITE32(SPI_DEVICE_TXF_ADDR_REG_OFFSET, - { - {SPI_DEVICE_TXF_ADDR_BASE_OFFSET, 0x800}, - {SPI_DEVICE_TXF_ADDR_LIMIT_OFFSET, 0x1000 - 1}, - }); EXPECT_WRITE32(SPI_DEVICE_CFG_REG_OFFSET, { {SPI_DEVICE_CFG_CPOL_BIT, 0}, {SPI_DEVICE_CFG_CPHA_BIT, 0}, {SPI_DEVICE_CFG_TX_ORDER_BIT, 0}, {SPI_DEVICE_CFG_RX_ORDER_BIT, 0}, - {SPI_DEVICE_CFG_TIMER_V_OFFSET, - kDefaultConfig.mode_cfg.generic.rx_fifo_commit_wait}, }); EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 0}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, + {SPI_DEVICE_CONTROL_MODE_OFFSET, 3}, }); EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, { {SPI_DEVICE_CONTROL_MODE_OFFSET, 0}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 0}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, - }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 0}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, - }); - EXPECT_DIF_OK(dif_spi_device_configure(&spi_, kDefaultConfig)); } -TEST_F(ConfigTest, ComplexInit) { - dif_spi_device_generic_mode_config_t generic_config = { - .rx_fifo_len = 0x24, - .tx_fifo_len = kFifoLen, - .rx_fifo_commit_wait = 42, - }; - dif_spi_device_config_t config = { - .clock_polarity = kDifSpiDeviceEdgeNegative, - .data_phase = kDifSpiDeviceEdgePositive, - .tx_order = kDifSpiDeviceBitOrderLsbToMsb, - .rx_order = kDifSpiDeviceBitOrderMsbToLsb, - .device_mode = kDifSpiDeviceModeGeneric, - }; - config.mode_cfg.generic = generic_config; - - EXPECT_WRITE32(SPI_DEVICE_RXF_ADDR_REG_OFFSET, - { - {SPI_DEVICE_RXF_ADDR_BASE_OFFSET, 0x000}, - {SPI_DEVICE_RXF_ADDR_LIMIT_OFFSET, 0x023}, - }); - EXPECT_WRITE32(SPI_DEVICE_TXF_ADDR_REG_OFFSET, - { - {SPI_DEVICE_TXF_ADDR_BASE_OFFSET, 0x024}, - {SPI_DEVICE_TXF_ADDR_LIMIT_OFFSET, 0x823}, - }); - EXPECT_WRITE32( - SPI_DEVICE_CFG_REG_OFFSET, - { - {SPI_DEVICE_CFG_CPOL_BIT, 1}, - {SPI_DEVICE_CFG_CPHA_BIT, 1}, - {SPI_DEVICE_CFG_TX_ORDER_BIT, 1}, - {SPI_DEVICE_CFG_RX_ORDER_BIT, 0}, - {SPI_DEVICE_CFG_TIMER_V_OFFSET, generic_config.rx_fifo_commit_wait}, - }); - EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 0}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, - }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 0}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, - }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 0}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, - }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 0}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, - }); - - EXPECT_DIF_OK(dif_spi_device_configure(&spi_, config)); - EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 0}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, - }); - EXPECT_DIF_BADARG( - dif_spi_device_set_passthrough_mode(&spi_, kDifToggleDisabled)); -} - TEST_F(ConfigTest, NullArgs) { EXPECT_DIF_BADARG(dif_spi_device_configure(nullptr, kDefaultConfig)); EXPECT_DIF_BADARG( dif_spi_device_set_passthrough_mode(nullptr, kDifToggleEnabled)); - EXPECT_DIF_BADARG(dif_spi_device_reset_generic_tx_fifo(nullptr)); - EXPECT_DIF_BADARG(dif_spi_device_reset_generic_rx_fifo(nullptr)); - EXPECT_DIF_BADARG( - dif_spi_device_set_sram_clock_enable(nullptr, kDifToggleEnabled)); - dif_toggle_t toggle; - EXPECT_DIF_BADARG(dif_spi_device_get_sram_clock_enable(nullptr, &toggle)); - EXPECT_DIF_BADARG(dif_spi_device_get_sram_clock_enable(&spi_, nullptr)); -} - -TEST_F(ConfigTest, InitSramOverflow) { - dif_spi_device_config_t config = kDefaultConfig; - config.mode_cfg.generic.rx_fifo_len = 0x1000; - EXPECT_DIF_BADARG(dif_spi_device_configure(&spi_, config)); -} - -TEST_F(ConfigTest, SramClockEnable) { - dif_toggle_t enabled; - EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, - }); - EXPECT_DIF_OK(dif_spi_device_get_sram_clock_enable(&spi_, &enabled)); - EXPECT_TRUE(enabled); - - EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, - }); - EXPECT_DIF_OK(dif_spi_device_get_sram_clock_enable(&spi_, &enabled)); - EXPECT_FALSE(enabled); - - EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 2}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, - }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 2}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, - }); - EXPECT_DIF_OK(dif_spi_device_set_sram_clock_enable(&spi_, kDifToggleEnabled)); - EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 2}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, - }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 2}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, - }); - EXPECT_DIF_OK( - dif_spi_device_set_sram_clock_enable(&spi_, kDifToggleDisabled)); -} - -class IrqTest : public SpiTest {}; - -TEST_F(IrqTest, Levels) { - EXPECT_WRITE32(SPI_DEVICE_FIFO_LEVEL_REG_OFFSET, - {{SPI_DEVICE_FIFO_LEVEL_RXLVL_OFFSET, 42}, - {SPI_DEVICE_FIFO_LEVEL_TXLVL_OFFSET, 123}}); - EXPECT_DIF_OK(dif_spi_device_set_irq_levels(&spi_, 42, 123)); -} - -TEST_F(IrqTest, LevelsNull) { - EXPECT_DIF_BADARG(dif_spi_device_set_irq_levels(nullptr, 123, 456)); -} - -class RxPendingTest : public SpiTest { - void SetUp() { spi_.config = kDefaultConfig; } -}; - -TEST_F(RxPendingTest, BothZero) { - EXPECT_READ32(SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, 0x0}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, 0x0}}); - size_t bytes_remaining; - EXPECT_DIF_OK(dif_spi_device_rx_pending(&spi_, &bytes_remaining)); - EXPECT_EQ(bytes_remaining, 0); -} - -TEST_F(RxPendingTest, InPhaseEmpty) { - EXPECT_READ32(SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(0x42, true)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x42, true)}}); - size_t bytes_remaining; - EXPECT_DIF_OK(dif_spi_device_rx_pending(&spi_, &bytes_remaining)); - EXPECT_EQ(bytes_remaining, 0); -} - -TEST_F(RxPendingTest, InPhase) { - EXPECT_READ32(SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(0x57, true)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x42, true)}}); - size_t bytes_remaining; - EXPECT_DIF_OK(dif_spi_device_rx_pending(&spi_, &bytes_remaining)); - EXPECT_EQ(bytes_remaining, 0x15); -} - -TEST_F(RxPendingTest, OutOfPhaseFull) { - EXPECT_READ32(SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(0x42, false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x42, true)}}); - size_t bytes_remaining; - EXPECT_DIF_OK(dif_spi_device_rx_pending(&spi_, &bytes_remaining)); - EXPECT_EQ(bytes_remaining, 0x800); -} - -TEST_F(RxPendingTest, OutOfPhase) { - EXPECT_READ32(SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(0x42, false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x57, true)}}); - size_t bytes_remaining; - EXPECT_DIF_OK(dif_spi_device_rx_pending(&spi_, &bytes_remaining)); - EXPECT_EQ(bytes_remaining, 0x7eb); -} - -TEST_F(RxPendingTest, NullArgs) { - size_t bytes_remaining; - EXPECT_DIF_BADARG(dif_spi_device_rx_pending(nullptr, &bytes_remaining)); - EXPECT_DIF_BADARG(dif_spi_device_rx_pending(&spi_, nullptr)); - EXPECT_DIF_BADARG(dif_spi_device_rx_pending(nullptr, nullptr)); -} - -TEST_F(RxPendingTest, AsyncFifo) { - uint16_t rx_level, tx_level; - EXPECT_READ32(SPI_DEVICE_ASYNC_FIFO_LEVEL_REG_OFFSET, - { - {SPI_DEVICE_ASYNC_FIFO_LEVEL_RXLVL_OFFSET, 10}, - {SPI_DEVICE_ASYNC_FIFO_LEVEL_TXLVL_OFFSET, 5}, - }); - EXPECT_DIF_OK( - dif_spi_device_get_async_fifo_levels(&spi_, &rx_level, &tx_level)); - EXPECT_EQ(rx_level, 10); - EXPECT_EQ(tx_level, 5); -} - -class TxPendingTest : public SpiTest { - void SetUp() { spi_.config = kDefaultConfig; } -}; - -TEST_F(TxPendingTest, BothZero) { - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, 0x0}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, 0x0}}); - size_t bytes_remaining; - EXPECT_DIF_OK(dif_spi_device_tx_pending(&spi_, &bytes_remaining)); - EXPECT_EQ(bytes_remaining, 0); -} - -TEST_F(TxPendingTest, InPhaseEmpty) { - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x42, true)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x42, true)}}); - size_t bytes_remaining; - EXPECT_DIF_OK(dif_spi_device_tx_pending(&spi_, &bytes_remaining)); - EXPECT_EQ(bytes_remaining, 0); -} - -TEST_F(TxPendingTest, InPhase) { - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x57, true)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x42, true)}}); - size_t bytes_remaining; - EXPECT_DIF_OK(dif_spi_device_tx_pending(&spi_, &bytes_remaining)); - EXPECT_EQ(bytes_remaining, 0x15); -} - -TEST_F(TxPendingTest, OutOfPhaseFull) { - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x42, false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x42, true)}}); - size_t bytes_remaining; - EXPECT_DIF_OK(dif_spi_device_tx_pending(&spi_, &bytes_remaining)); - EXPECT_EQ(bytes_remaining, 0x800); -} - -TEST_F(TxPendingTest, OutOfPhase) { - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x42, false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x57, true)}}); - size_t bytes_remaining; - EXPECT_DIF_OK(dif_spi_device_tx_pending(&spi_, &bytes_remaining)); - EXPECT_EQ(bytes_remaining, 0x7eb); -} - -TEST_F(TxPendingTest, NullArgs) { - size_t bytes_remaining; - EXPECT_DIF_BADARG(dif_spi_device_tx_pending(nullptr, &bytes_remaining)); - EXPECT_DIF_BADARG(dif_spi_device_tx_pending(&spi_, nullptr)); - EXPECT_DIF_BADARG(dif_spi_device_tx_pending(nullptr, nullptr)); -} - -class RecvTest : public SpiTest { - void SetUp() { spi_.config = kDefaultConfig; } -}; - -TEST_F(RecvTest, EmptyFifo) { - EXPECT_READ32(SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(0x5a, false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x5a, false)}}); - - std::string buf(16, '\0'); - size_t recv_len = 0; - EXPECT_DIF_OK(dif_spi_device_recv(&spi_, const_cast(buf.data()), - buf.size(), &recv_len)); - EXPECT_EQ(recv_len, 0); - buf.resize(recv_len); - EXPECT_EQ(buf, ""); -} - -TEST_F(RecvTest, FullFifoAligned) { - EXPECT_READ32(SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(0x50, true)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x50, false)}}); - - auto message = MakeBlob(kFifoLen); - auto fifo_base = SPI_DEVICE_BUFFER_REG_OFFSET; - for (int i = 0; i < kFifoLen; i += 4) { - auto idx = fifo_base + (i + 0x50) % kFifoLen; - EXPECT_READ32(idx, LeInt(&message[i])); - } - - EXPECT_WRITE32(SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(0x50, true)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x50, true)}}); - - std::vector buf; - buf.resize(message.size() * 2); - size_t recv_len = 0; - EXPECT_DIF_OK(dif_spi_device_recv(&spi_, buf.data(), buf.size(), &recv_len)); - EXPECT_EQ(recv_len, message.size()); - buf.resize(recv_len); - EXPECT_EQ(buf, message); -} - -TEST_F(RecvTest, FullFifoSmallBuf) { - size_t buf_len = 0x22; - - EXPECT_READ32(SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(0x50, true)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x50, false)}}); - - auto message = MakeBlob(kFifoLen); - auto fifo_base = SPI_DEVICE_BUFFER_REG_OFFSET; - for (size_t i = 0; i < buf_len; i += 4) { - auto idx = fifo_base + (i + 0x50) % kFifoLen; - EXPECT_READ32(idx, LeInt(&message[i])); - } - - EXPECT_WRITE32( - SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(0x50, true)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x50 + buf_len, false)}}); - - std::vector buf; - buf.resize(buf_len); - size_t recv_len = 0; - EXPECT_DIF_OK(dif_spi_device_recv(&spi_, buf.data(), buf.size(), &recv_len)); - EXPECT_EQ(recv_len, buf_len); - buf.resize(recv_len); - message.resize(recv_len); - EXPECT_EQ(buf, message); -} - -TEST_F(RecvTest, FullyAligned) { - std::string message = "Hello, SPI!!"; - ASSERT_EQ(message.size() % 4, 0); - - EXPECT_READ32( - SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(message.size(), false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x00, false)}}); - - auto fifo_base = SPI_DEVICE_BUFFER_REG_OFFSET; - EXPECT_READ32(fifo_base + 0x0, LeInt(&message[0x0])); - EXPECT_READ32(fifo_base + 0x4, LeInt(&message[0x4])); - EXPECT_READ32(fifo_base + 0x8, LeInt(&message[0x8])); - - EXPECT_WRITE32( - SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(message.size(), false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(message.size(), false)}}); - - std::string buf(message.size() * 2, '\0'); - size_t recv_len = 0; - EXPECT_DIF_OK(dif_spi_device_recv(&spi_, const_cast(buf.data()), - buf.size(), &recv_len)); - EXPECT_EQ(recv_len, message.size()); - buf.resize(recv_len); - EXPECT_EQ(buf, message); -} - -TEST_F(RecvTest, UnalignedMessage) { - std::string message = "Hello, SPI!!"; - ASSERT_EQ(message.size() % 4, 0); - - uintptr_t cropped_len = 9; - EXPECT_READ32(SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(cropped_len, false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x00, false)}}); - - auto fifo_base = SPI_DEVICE_BUFFER_REG_OFFSET; - EXPECT_READ32(fifo_base + 0x0, LeInt(&message[0x0])); - EXPECT_READ32(fifo_base + 0x4, LeInt(&message[0x4])); - EXPECT_READ32(fifo_base + 0x8, LeInt(&message[0x8])); - - EXPECT_WRITE32( - SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(cropped_len, false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(cropped_len, false)}}); - - std::string buf(message.size() * 2, '\0'); - size_t recv_len = 0; - EXPECT_DIF_OK(dif_spi_device_recv(&spi_, const_cast(buf.data()), - buf.size(), &recv_len)); - EXPECT_EQ(recv_len, cropped_len); - - buf.resize(message.size()); - EXPECT_NE(buf, message); - - buf.resize(recv_len); - EXPECT_EQ(buf, message.substr(0, cropped_len)); -} - -TEST_F(RecvTest, UnalignedStart) { - std::string message = "Hello, SPI!!"; - ASSERT_EQ(message.size() % 4, 0); - - uintptr_t cropped_start = 1; - uintptr_t cropped_len = 9; - EXPECT_READ32( - SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(cropped_len, false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(cropped_start, false)}}); - - auto fifo_base = SPI_DEVICE_BUFFER_REG_OFFSET; - EXPECT_READ32(fifo_base + 0x0, LeInt(&message[0x0])); - EXPECT_READ32(fifo_base + 0x4, LeInt(&message[0x4])); - EXPECT_READ32(fifo_base + 0x8, LeInt(&message[0x8])); - - EXPECT_WRITE32( - SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(cropped_len, false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(cropped_len, false)}}); - - std::string buf(message.size() * 2, '\0'); - size_t recv_len = 0; - EXPECT_DIF_OK(dif_spi_device_recv(&spi_, const_cast(buf.data()), - buf.size(), &recv_len)); - EXPECT_EQ(recv_len, cropped_len - cropped_start); - - buf.resize(message.size()); - EXPECT_NE(buf, message); - - buf.resize(recv_len); - EXPECT_EQ(buf, message.substr(cropped_start, cropped_len - cropped_start)); -} - -TEST_F(RecvTest, UnalignedSmall) { - std::string message = "Hello, SPI!!"; - ASSERT_EQ(message.size() % 4, 0); - - uintptr_t cropped_start = 1; - uintptr_t cropped_len = 3; - EXPECT_READ32( - SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(cropped_len, false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(cropped_start, false)}}); - - auto fifo_base = SPI_DEVICE_BUFFER_REG_OFFSET; - EXPECT_READ32(fifo_base + 0x0, LeInt(&message[0x0])); - - EXPECT_WRITE32( - SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(cropped_len, false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(cropped_len, false)}}); - - std::string buf(message.size() * 2, '\0'); - size_t recv_len = 0; - EXPECT_DIF_OK(dif_spi_device_recv(&spi_, const_cast(buf.data()), - buf.size(), &recv_len)); - EXPECT_EQ(recv_len, cropped_len - cropped_start); - - buf.resize(message.size()); - EXPECT_NE(buf, message); - - buf.resize(recv_len); - EXPECT_EQ(buf, message.substr(cropped_start, cropped_len - cropped_start)); -} - -TEST_F(RecvTest, NullArgs) { - std::string buf(16, '\0'); - size_t recv_len; - - EXPECT_DIF_BADARG(dif_spi_device_recv(nullptr, const_cast(buf.data()), - buf.size(), &recv_len)); - EXPECT_DIF_BADARG(dif_spi_device_recv(&spi_, nullptr, buf.size(), &recv_len)); - - EXPECT_READ32(SPI_DEVICE_RXF_PTR_REG_OFFSET, - {{SPI_DEVICE_RXF_PTR_WPTR_OFFSET, FifoPtr(0x5a, false)}, - {SPI_DEVICE_RXF_PTR_RPTR_OFFSET, FifoPtr(0x5a, false)}}); - EXPECT_DIF_OK(dif_spi_device_recv(&spi_, const_cast(buf.data()), - buf.size(), nullptr)); -} - -class SendTest : public SpiTest { - void SetUp() { spi_.config = kDefaultConfig; } -}; - -TEST_F(SendTest, FullFifo) { - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x5a, true)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x5a, false)}}); - - std::string message = "Hello, SPI!!"; - size_t send_len = 0; - EXPECT_DIF_OK( - dif_spi_device_send(&spi_, message.data(), message.size(), &send_len)); - EXPECT_EQ(send_len, 0); -} - -TEST_F(SendTest, EmptyToFull) { - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x50, true)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x50, true)}}); - - auto message = MakeBlob(kFifoLen); - auto fifo_base = - SPI_DEVICE_BUFFER_REG_OFFSET + spi_.config.mode_cfg.generic.rx_fifo_len; - for (int i = 0; i < kFifoLen; i += 4) { - auto idx = fifo_base + (i + 0x50) % kFifoLen; - EXPECT_WRITE32(idx, LeInt(&message[i])); - } - - EXPECT_WRITE32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x50, false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x50, true)}}); - - size_t sent_len = 0; - EXPECT_DIF_OK( - dif_spi_device_send(&spi_, message.data(), message.size(), &sent_len)); - EXPECT_EQ(sent_len, message.size()); -} - -TEST_F(SendTest, AlmostFull) { - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x4e, true)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x50, false)}}); - - std::string message = "Hello, world!"; - uintptr_t value = 0; - memcpy(&value, message.data(), 2); - - auto fifo_base = - SPI_DEVICE_BUFFER_REG_OFFSET + spi_.config.mode_cfg.generic.rx_fifo_len; - EXPECT_MASK32(fifo_base + 0x4c, {{0x10, 0xffff, value}}); - - EXPECT_WRITE32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x50, true)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x50, false)}}); - - size_t sent_len = 0; - EXPECT_DIF_OK( - dif_spi_device_send(&spi_, message.data(), message.size(), &sent_len)); - EXPECT_EQ(sent_len, 2); -} - -TEST_F(SendTest, FullyAligned) { - std::string message = "Hello, SPI!!"; - ASSERT_EQ(message.size() % 4, 0); - - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x00, false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x00, false)}}); - - auto fifo_base = - SPI_DEVICE_BUFFER_REG_OFFSET + spi_.config.mode_cfg.generic.rx_fifo_len; - EXPECT_WRITE32(fifo_base + 0x0, LeInt(&message[0x0])); - EXPECT_WRITE32(fifo_base + 0x4, LeInt(&message[0x4])); - EXPECT_WRITE32(fifo_base + 0x8, LeInt(&message[0x8])); - - EXPECT_WRITE32( - SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(message.size(), false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x0, false)}}); - - size_t send_len = 0; - EXPECT_DIF_OK( - dif_spi_device_send(&spi_, message.data(), message.size(), &send_len)); - EXPECT_EQ(send_len, message.size()); -} - -TEST_F(SendTest, UnalignedMessage) { - std::string message = "Hello, SPI!!"; - ASSERT_EQ(message.size() % 4, 0); - - uintptr_t cropped_len = 9; - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x00, false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x00, false)}}); - - auto fifo_base = - SPI_DEVICE_BUFFER_REG_OFFSET + spi_.config.mode_cfg.generic.rx_fifo_len; - EXPECT_WRITE32(fifo_base + 0x0, LeInt(&message[0x0])); - EXPECT_WRITE32(fifo_base + 0x4, LeInt(&message[0x4])); - - uintptr_t value = 0; - memcpy(&value, &message[0x8], 1); - EXPECT_MASK32(fifo_base + 0x8, {{0x0, 0xff, value}}); - - EXPECT_WRITE32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(cropped_len, false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x0, false)}}); - - size_t send_len = 0; - EXPECT_DIF_OK( - dif_spi_device_send(&spi_, message.data(), cropped_len, &send_len)); - EXPECT_EQ(send_len, cropped_len); -} - -TEST_F(SendTest, UnalignedStart) { - std::string message = "Hello, SPI!!"; - ASSERT_EQ(message.size() % 4, 0); - - uintptr_t cropped_start = 1; - uintptr_t cropped_len = 9; - EXPECT_READ32( - SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(cropped_start, false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(cropped_start, false)}}); - - auto fifo_base = - SPI_DEVICE_BUFFER_REG_OFFSET + spi_.config.mode_cfg.generic.rx_fifo_len; - - uintptr_t start_value = 0; - memcpy(&start_value, &message[0x0], 3); - EXPECT_MASK32(fifo_base + 0x0, {{0x8, 0xffffff, start_value}}); - EXPECT_WRITE32(fifo_base + 0x4, LeInt(&message[0x3])); - - uintptr_t end_value = 0; - memcpy(&end_value, &message[0x7], 2); - EXPECT_MASK32(fifo_base + 0x8, {{0x0, 0xffff, end_value}}); - - EXPECT_WRITE32( - SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, - FifoPtr(cropped_len + cropped_start, false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(cropped_start, false)}}); - - size_t send_len = 0; - EXPECT_DIF_OK( - dif_spi_device_send(&spi_, message.data(), cropped_len, &send_len)); - EXPECT_EQ(send_len, cropped_len); -} - -TEST_F(SendTest, UnalignedSmall) { - std::string message = "Hello, SPI!!"; - ASSERT_EQ(message.size() % 4, 0); - - uintptr_t cropped_start = 1; - uintptr_t cropped_len = 2; - EXPECT_READ32( - SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(cropped_start, false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(cropped_start, false)}}); - - auto fifo_base = - SPI_DEVICE_BUFFER_REG_OFFSET + spi_.config.mode_cfg.generic.rx_fifo_len; - - uintptr_t start_value = 0; - memcpy(&start_value, &message[0x0], 2); - EXPECT_MASK32(fifo_base + 0x0, {{0x8, 0xffff, start_value}}); - - EXPECT_WRITE32( - SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, - FifoPtr(cropped_len + cropped_start, false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(cropped_start, false)}}); - - size_t send_len = 0; - EXPECT_DIF_OK( - dif_spi_device_send(&spi_, message.data(), cropped_len, &send_len)); - EXPECT_EQ(send_len, cropped_len); -} - -TEST_F(SendTest, NullArgs) { - std::string buf(16, '\0'); - size_t recv_len; - - EXPECT_DIF_BADARG( - dif_spi_device_send(nullptr, buf.data(), buf.size(), &recv_len)); - EXPECT_DIF_BADARG(dif_spi_device_send(&spi_, nullptr, buf.size(), &recv_len)); - - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x5a, true)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x5a, false)}}); - EXPECT_DIF_OK(dif_spi_device_send(&spi_, buf.data(), buf.size(), nullptr)); -} - -class SendPolledTest : public SpiTest { - void SetUp() { spi_.config = kDefaultConfig; } -}; - -TEST_F(SendPolledTest, NullArgs) { - std::string buf(16, '\0'); - EXPECT_DIF_BADARG( - dif_spi_device_send_polled(nullptr, buf.data(), buf.size())); - EXPECT_DIF_BADARG(dif_spi_device_send_polled(&spi_, nullptr, buf.size())); -} - -TEST_F(SendPolledTest, BufTooBig) { - std::string buf(SpiTest::kFifoLen + 1, '\0'); - EXPECT_DIF_BADARG(dif_spi_device_send_polled(&spi_, buf.data(), buf.size())); -} - -TEST_F(SendPolledTest, ZeroLengthBuf) { - std::string buf(0, '\0'); - EXPECT_DIF_OK(dif_spi_device_send_polled(&spi_, buf.data(), buf.size())); -} - -TEST_F(SendPolledTest, InitiallyFullThenEmptyThenFullFifo) { - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x5c, true)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x5c, false)}}); - EXPECT_READ32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x5c, true)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x5c, true)}}); - - auto message = MakeBlob(kFifoLen); - auto fifo_base = - SPI_DEVICE_BUFFER_REG_OFFSET + spi_.config.mode_cfg.generic.rx_fifo_len; - for (int i = 0; i < kFifoLen; i += 4) { - auto idx = fifo_base + (i + 0x5c) % kFifoLen; - EXPECT_WRITE32(idx, LeInt(&message[i])); - } - - EXPECT_WRITE32(SPI_DEVICE_TXF_PTR_REG_OFFSET, - {{SPI_DEVICE_TXF_PTR_WPTR_OFFSET, FifoPtr(0x5c, false)}, - {SPI_DEVICE_TXF_PTR_RPTR_OFFSET, FifoPtr(0x5c, true)}}); - - EXPECT_DIF_OK( - dif_spi_device_send_polled(&spi_, message.data(), message.size())); -} - -class GenericTest : public SpiTest {}; - -TEST_F(GenericTest, NullArgs) { - uint16_t uint16_arg; - bool bool_arg; - dif_spi_device_generic_fifo_status_t fifo_status; - EXPECT_DIF_BADARG( - dif_spi_device_get_async_fifo_levels(nullptr, &uint16_arg, &uint16_arg)); - EXPECT_DIF_BADARG( - dif_spi_device_get_async_fifo_levels(&spi_, nullptr, &uint16_arg)); - EXPECT_DIF_BADARG( - dif_spi_device_get_async_fifo_levels(&spi_, &uint16_arg, nullptr)); - EXPECT_DIF_BADARG( - dif_spi_device_get_generic_fifo_status(nullptr, &fifo_status)); - EXPECT_DIF_BADARG(dif_spi_device_get_generic_fifo_status(&spi_, nullptr)); - EXPECT_DIF_BADARG(dif_spi_device_get_csb_status(nullptr, &bool_arg)); - EXPECT_DIF_BADARG(dif_spi_device_get_csb_status(&spi_, nullptr)); -} - -TEST_F(GenericTest, ResetFifos) { - EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, - }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, - {SPI_DEVICE_CONTROL_RST_TXFIFO_BIT, 1}, - }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, - {SPI_DEVICE_CONTROL_RST_TXFIFO_BIT, 0}, - }); - EXPECT_DIF_OK(dif_spi_device_reset_generic_tx_fifo(&spi_)); - - EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, - }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, - {SPI_DEVICE_CONTROL_RST_RXFIFO_BIT, 1}, - }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, - {SPI_DEVICE_CONTROL_RST_RXFIFO_BIT, 0}, - }); - EXPECT_DIF_OK(dif_spi_device_reset_generic_rx_fifo(&spi_)); -} - -TEST_F(GenericTest, FifoStatus) { - dif_spi_device_generic_fifo_status_t status; - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, - { - {SPI_DEVICE_STATUS_RXF_FULL_BIT, 1}, - {SPI_DEVICE_STATUS_RXF_EMPTY_BIT, 0}, - {SPI_DEVICE_STATUS_TXF_FULL_BIT, 0}, - {SPI_DEVICE_STATUS_TXF_EMPTY_BIT, 1}, - }); - EXPECT_DIF_OK(dif_spi_device_get_generic_fifo_status(&spi_, &status)); - EXPECT_TRUE(status.rx_full); - EXPECT_FALSE(status.rx_empty); - EXPECT_FALSE(status.tx_full); - EXPECT_TRUE(status.tx_empty); - - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, - { - {SPI_DEVICE_STATUS_RXF_FULL_BIT, 0}, - {SPI_DEVICE_STATUS_RXF_EMPTY_BIT, 1}, - {SPI_DEVICE_STATUS_TXF_FULL_BIT, 1}, - {SPI_DEVICE_STATUS_TXF_EMPTY_BIT, 0}, - }); - EXPECT_DIF_OK(dif_spi_device_get_generic_fifo_status(&spi_, &status)); - EXPECT_FALSE(status.rx_full); - EXPECT_TRUE(status.rx_empty); - EXPECT_TRUE(status.tx_full); - EXPECT_FALSE(status.tx_empty); -} - -TEST_F(GenericTest, CsbGpio) { - bool csb; - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, - { - {SPI_DEVICE_STATUS_CSB_BIT, 1}, - }); - EXPECT_DIF_OK(dif_spi_device_get_csb_status(&spi_, &csb)); - EXPECT_TRUE(csb); - - EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, - { - {SPI_DEVICE_STATUS_RXF_FULL_BIT, 1}, - {SPI_DEVICE_STATUS_RXF_EMPTY_BIT, 1}, - {SPI_DEVICE_STATUS_TXF_FULL_BIT, 1}, - {SPI_DEVICE_STATUS_TXF_EMPTY_BIT, 1}, - {SPI_DEVICE_STATUS_CSB_BIT, 0}, - }); - EXPECT_DIF_OK(dif_spi_device_get_csb_status(&spi_, &csb)); - EXPECT_FALSE(csb); } class FlashTest : public SpiTest { @@ -974,24 +84,11 @@ class FlashTest : public SpiTest { EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, { {SPI_DEVICE_CONTROL_MODE_OFFSET, 0}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, 0}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, - }); - EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, - { - {SPI_DEVICE_CONTROL_MODE_OFFSET, - SPI_DEVICE_CONTROL_MODE_VALUE_PASSTHROUGH}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 0}, - }); EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, { {SPI_DEVICE_CONTROL_MODE_OFFSET, SPI_DEVICE_CONTROL_MODE_VALUE_PASSTHROUGH}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, }); EXPECT_DIF_OK(dif_spi_device_configure(&spi_, config)); }; @@ -1094,31 +191,44 @@ TEST_F(FlashTest, NullArgs) { EXPECT_DIF_BADARG(dif_spi_device_get_flash_status_registers(&spi_, nullptr)); } +TEST_F(FlashTest, CsbGpio) { + bool csb; + EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, + { + {SPI_DEVICE_STATUS_CSB_BIT, 1}, + }); + EXPECT_DIF_OK(dif_spi_device_get_csb_status(&spi_, &csb)); + EXPECT_TRUE(csb); + + EXPECT_READ32(SPI_DEVICE_STATUS_REG_OFFSET, + { + {SPI_DEVICE_STATUS_CSB_BIT, 0}, + }); + EXPECT_DIF_OK(dif_spi_device_get_csb_status(&spi_, &csb)); + EXPECT_FALSE(csb); +} + TEST_F(FlashTest, PassthroughToggle) { EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, { {SPI_DEVICE_CONTROL_MODE_OFFSET, SPI_DEVICE_CONTROL_MODE_VALUE_PASSTHROUGH}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, }); EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, { {SPI_DEVICE_CONTROL_MODE_OFFSET, SPI_DEVICE_CONTROL_MODE_VALUE_FLASHMODE}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, }); EXPECT_DIF_OK(dif_spi_device_set_passthrough_mode(&spi_, kDifToggleDisabled)); EXPECT_READ32(SPI_DEVICE_CONTROL_REG_OFFSET, { {SPI_DEVICE_CONTROL_MODE_OFFSET, SPI_DEVICE_CONTROL_MODE_VALUE_FLASHMODE}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, }); EXPECT_WRITE32(SPI_DEVICE_CONTROL_REG_OFFSET, { {SPI_DEVICE_CONTROL_MODE_OFFSET, SPI_DEVICE_CONTROL_MODE_VALUE_PASSTHROUGH}, - {SPI_DEVICE_CONTROL_SRAM_CLK_EN_BIT, 1}, }); EXPECT_DIF_OK(dif_spi_device_set_passthrough_mode(&spi_, kDifToggleEnabled)); } diff --git a/sw/device/lib/runtime/BUILD b/sw/device/lib/runtime/BUILD index fd2886a86d00f..0153d77b55279 100644 --- a/sw/device/lib/runtime/BUILD +++ b/sw/device/lib/runtime/BUILD @@ -92,7 +92,6 @@ cc_library( "//sw/device/lib/base:macros", "//sw/device/lib/base:memory", "//sw/device/lib/base:status", - "//sw/device/lib/dif:spi_device", "//sw/device/lib/dif:uart", ], ) diff --git a/sw/device/lib/runtime/print.c b/sw/device/lib/runtime/print.c index 43fe292343679..7cc3b7f7d6e2b 100644 --- a/sw/device/lib/runtime/print.c +++ b/sw/device/lib/runtime/print.c @@ -12,7 +12,6 @@ #include "sw/device/lib/base/macros.h" #include "sw/device/lib/base/memory.h" #include "sw/device/lib/base/status.h" -#include "sw/device/lib/dif/dif_spi_device.h" #include "sw/device/lib/dif/dif_uart.h" // This is declared as an enum to force the values to be @@ -68,77 +67,6 @@ void base_set_stdout(buffer_sink_t out) { base_stdout = out; } -static const size_t kSpiDeviceFrameHeaderSizeBytes = 12; -static uint32_t spi_device_frame_num = 0; - -/** - * Sends data out of the SPI device. - * - * Data is packaged into a frame that is described below. Note, the 0xFF padding - * is to account for packet loss on the host side due to shortcomings in the - * HyperDebug firmware. The host side reads the header first, then decides how - * many words to read from the data section. - * - * ----------------------------------------------- - * | 0xFF_FF_FF_FF Pad | 4-bytes | | - * -----------------------------------| | - * | Frame Number | 4-bytes | Header | - * -----------------------------------| | - * | Data Length (bytes) | 4-bytes | | - * -----------------------------------|----------| - * | 0xFF_FF_FF_FF Pad | 4-bytes | | - * -----------------------------------| | - * | Data (word aligned) | Data | - * -----------------------------------| | - * | 0xFF Pad Bytes | <4-bytes | | - * -----------------------------------|----------| - */ -static size_t base_dev_spi_device(void *data, const char *buf, size_t len) { - dif_spi_device_handle_t *spi_device = (dif_spi_device_handle_t *)data; - - const size_t kDataPacketSizeBytes = ((len + 3u) & ~3u) + 4; - const size_t kFrameSizeBytes = - kSpiDeviceFrameHeaderSizeBytes + kDataPacketSizeBytes; - uint8_t frame_bytes[kFrameSizeBytes]; - - // Construct the frame header packet. - // Add the pad bytes. - for (size_t i = 0; i < 4; ++i) { - frame_bytes[i] = 0xff; - } - // Add the frame number. - for (size_t i = 0; i < 4; ++i) { - frame_bytes[i + 4] = (spi_device_frame_num >> (i * 8)) & 0xff; - } - // Add the data length. - for (size_t i = 0; i < 4; ++i) { - frame_bytes[i + 8] = (len >> (i * 8)) & 0xff; - } - - // Construct the frame data packet. - // Add the pad bytes. - for (size_t i = 0; i < 4; ++i) { - frame_bytes[i + 12] = 0xff; - } - // Add the data and pad bytes. - for (size_t i = 0; i < ((len + 3u) & ~3u); ++i) { - if (i < len) { - frame_bytes[i + 16] = buf[i]; - } else { - frame_bytes[i + 16] = 0xff; - } - } - - // Send the frame. - if (dif_spi_device_send_polled(spi_device, frame_bytes, - /*buf_len=*/kFrameSizeBytes) != kDifOk) { - return 0; - } - spi_device_frame_num++; - - return len; -} - static size_t base_dev_uart(void *data, const char *buf, size_t len) { const dif_uart_t *uart = (const dif_uart_t *)data; for (size_t i = 0; i < len; ++i) { @@ -149,13 +77,6 @@ static size_t base_dev_uart(void *data, const char *buf, size_t len) { return len; } -void base_spi_device_stdout(const dif_spi_device_handle_t *spi_device) { - // Reset the frame counter. - spi_device_frame_num = 0; - base_set_stdout((buffer_sink_t){.data = (void *)spi_device, - .sink = &base_dev_spi_device}); -} - void base_uart_stdout(const dif_uart_t *uart) { base_set_stdout( (buffer_sink_t){.data = (void *)uart, .sink = &base_dev_uart}); diff --git a/sw/device/lib/runtime/print.h b/sw/device/lib/runtime/print.h index 9f8db70a2d1f5..1949999a3ac0c 100644 --- a/sw/device/lib/runtime/print.h +++ b/sw/device/lib/runtime/print.h @@ -8,7 +8,6 @@ #include #include -#include "sw/device/lib/dif/dif_spi_device.h" #include "sw/device/lib/dif/dif_uart.h" /** @@ -280,16 +279,6 @@ size_t base_fhexdump_with(buffer_sink_t out, base_hexdump_fmt_t fmt, */ void base_set_stdout(buffer_sink_t out); -/** - * Configures SPI device stdout for `base_print.h` to use. - * - * Note that this function will save `spi_device` in a global variable, so the - * pointer must have static storage duration. - * - * @param spi_device The SPI device handle to use for stdout. - */ -void base_spi_device_stdout(const dif_spi_device_handle_t *spi_device); - /** * Configures UART stdout for `base_print.h` to use. * diff --git a/sw/device/lib/testing/test_framework/ottf_console.c b/sw/device/lib/testing/test_framework/ottf_console.c index a06cd325061fb..e6c44071b20ff 100644 --- a/sw/device/lib/testing/test_framework/ottf_console.c +++ b/sw/device/lib/testing/test_framework/ottf_console.c @@ -87,18 +87,9 @@ void ottf_console_init(void) { .data_phase = kDifSpiDeviceEdgeNegative, .tx_order = kDifSpiDeviceBitOrderMsbToLsb, .rx_order = kDifSpiDeviceBitOrderMsbToLsb, - .device_mode = kDifSpiDeviceModeGeneric, - .mode_cfg = - { - .generic = - { - .rx_fifo_commit_wait = kSpiDeviceRxCommitWait, - .rx_fifo_len = kDifSpiDeviceBufferLen / 2, - .tx_fifo_len = kDifSpiDeviceBufferLen / 2, - }, - }, + .device_mode = kDifSpiDeviceModeFlashEmulation, })); - base_spi_device_stdout(&ottf_console_spi_device); + CHECK(false, "spi_device not yet supported as OTTF console."); break; default: CHECK(false, "unsupported OTTF console interface."); diff --git a/sw/device/silicon_creator/lib/drivers/spi_device.c b/sw/device/silicon_creator/lib/drivers/spi_device.c index e821b419faed9..05f081c9ad13d 100644 --- a/sw/device/silicon_creator/lib/drivers/spi_device.c +++ b/sw/device/silicon_creator/lib/drivers/spi_device.c @@ -502,7 +502,6 @@ void spi_device_init(void) { reg = bitfield_bit32_write(reg, SPI_DEVICE_CFG_CPHA_BIT, false); reg = bitfield_bit32_write(reg, SPI_DEVICE_CFG_TX_ORDER_BIT, false); reg = bitfield_bit32_write(reg, SPI_DEVICE_CFG_RX_ORDER_BIT, false); - reg = bitfield_field32_write(reg, SPI_DEVICE_CFG_TIMER_V_FIELD, 0x7f); reg = bitfield_bit32_write(reg, SPI_DEVICE_CFG_ADDR_4B_EN_BIT, false); reg = bitfield_bit32_write(reg, SPI_DEVICE_CFG_MAILBOX_EN_BIT, false); abs_mmio_write32(kBase + SPI_DEVICE_CFG_REG_OFFSET, reg); diff --git a/sw/device/silicon_creator/lib/drivers/spi_device_unittest.cc b/sw/device/silicon_creator/lib/drivers/spi_device_unittest.cc index 9c6bb73f8d638..43093458aafa3 100644 --- a/sw/device/silicon_creator/lib/drivers/spi_device_unittest.cc +++ b/sw/device/silicon_creator/lib/drivers/spi_device_unittest.cc @@ -39,7 +39,6 @@ TEST_F(InitTest, Init) { {SPI_DEVICE_CFG_CPHA_BIT, 0}, {SPI_DEVICE_CFG_TX_ORDER_BIT, 0}, {SPI_DEVICE_CFG_RX_ORDER_BIT, 0}, - {SPI_DEVICE_CFG_TIMER_V_OFFSET, 0x7f}, {SPI_DEVICE_CFG_ADDR_4B_EN_BIT, 0}, {SPI_DEVICE_CFG_MAILBOX_EN_BIT, 0}, }); diff --git a/sw/device/silicon_owner/tock/tests/basic/BUILD b/sw/device/silicon_owner/tock/tests/basic/BUILD index 5e74cf1c0fe50..5354f9a715add 100644 --- a/sw/device/silicon_owner/tock/tests/basic/BUILD +++ b/sw/device/silicon_owner/tock/tests/basic/BUILD @@ -39,6 +39,10 @@ opentitan_test( name = "basic_test", cw310 = cw310_params( binaries = {":image": "firmware"}, + tags = [ + "broken", + "manual", + ], ), exec_env = { "//hw/top_earlgrey:fpga_cw310_test_rom": None, diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD index 5bf1a7023ef0c..26b213618b032 100644 --- a/sw/device/tests/BUILD +++ b/sw/device/tests/BUILD @@ -2916,48 +2916,6 @@ opentitan_test( ], ) -opentitan_test( - name = "spi_device_smoketest", - srcs = ["spi_device_smoketest.c"], - cw310 = new_cw310_params( - otp = "//hw/ip/otp_ctrl/data/earlgrey_a0_skus/sival:otp_img_prod_manuf_personalized", - test_cmd = """ - --bitstream="{bitstream}" - --bootstrap="{firmware}" - "{firmware:elf}" - """, - test_harness = "//sw/host/tests/chip/spi_device_smoketest", - ), - exec_env = dicts.add( - EARLGREY_SILICON_OWNER_ROM_EXT_ENVS, - { - "//hw/top_earlgrey:fpga_cw310_sival": None, - "//hw/top_earlgrey:fpga_cw310_test_rom": None, - "//hw/top_earlgrey:silicon_creator": None, - }, - ), - silicon = silicon_params( - test_cmd = """ - --bootstrap={firmware} - "{firmware:elf}" - """, - test_harness = "//sw/host/tests/chip/spi_device_smoketest", - ), - deps = [ - "//hw/top_earlgrey/sw/autogen:top_earlgrey", - "//sw/device/lib/arch:device", - "//sw/device/lib/base:mmio", - "//sw/device/lib/dif:base", - "//sw/device/lib/dif:rv_plic", - "//sw/device/lib/dif:spi_device", - "//sw/device/lib/runtime:hart", - "//sw/device/lib/runtime:irq", - "//sw/device/lib/runtime:log", - "//sw/device/lib/testing/test_framework:ottf_main", - "//sw/device/lib/testing/test_framework:status", - ], -) - opentitan_test( name = "spi_device_tpm_tx_rx_test", srcs = ["spi_device_tpm_tx_rx_test.c"], @@ -4141,41 +4099,6 @@ opentitan_test( ], ) -# TODO(#19902): Migrate to `opentitan_test` once there is support for the -# hyperdebug310 target. #19903 covers support for hyperdebug340, and #19901 -# covers support for cw340_params. -opentitan_functest( - name = "spi_device_ottf_console_test", - srcs = ["spi_device_ottf_console_test.c"], - cw310 = cw310_params( - interface = "hyper310", - test_cmds = [ - "--bitstream=\"$(location {bitstream})\"", - "--bootstrap=\"$(location {flash})\"", - ], - ), - cw340 = cw340_params( - interface = "hyper340", - tags = ["manual"], - test_cmds = [ - "--bitstream=\"$(location {bitstream})\"", - "--bootstrap=\"$(location {flash})\"", - ], - ), - targets = [ - "cw310_rom_with_fake_keys", - "cw310_test_rom", - "cw340_test_rom", - ], - test_harness = "//sw/host/tests/chip/spi_device_ottf_console", - deps = [ - "//hw/top_earlgrey/sw/autogen:top_earlgrey", - "//sw/device/lib/dif:spi_device", - "//sw/device/lib/runtime:log", - "//sw/device/lib/testing/test_framework:ottf_main", - ], -) - # TODO(#19902): Migrate to `opentitan_test` once there is support for the # hyperdebug310 target. opentitan_test( diff --git a/sw/device/tests/autogen/plic_all_irqs_test.c b/sw/device/tests/autogen/plic_all_irqs_test.c index cd6c4fe69e64e..9038a6e0a01ed 100644 --- a/sw/device/tests/autogen/plic_all_irqs_test.c +++ b/sw/device/tests/autogen/plic_all_irqs_test.c @@ -878,7 +878,7 @@ void ottf_external_isr(uint32_t *exc_info) { case kTopEarlgreyPlicPeripheralSpiDevice: { dif_spi_device_irq_t irq = (dif_spi_device_irq_t)( plic_irq_id - - (dif_rv_plic_irq_id_t)kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull); + (dif_rv_plic_irq_id_t)kTopEarlgreyPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty); CHECK(irq == spi_device_irq_expected, "Incorrect spi_device IRQ triggered: exp = %d, obs = %d", spi_device_irq_expected, irq); @@ -1990,7 +1990,7 @@ static void peripheral_irqs_trigger(void) { #if TEST_MIN_IRQ_PERIPHERAL <= 18 && 18 < TEST_MAX_IRQ_PERIPHERAL peripheral_expected = kTopEarlgreyPlicPeripheralSpiDevice; - for (dif_spi_device_irq_t irq = kDifSpiDeviceIrqGenericRxFull; + for (dif_spi_device_irq_t irq = kDifSpiDeviceIrqUploadCmdfifoNotEmpty; irq <= kDifSpiDeviceIrqTpmHeaderNotEmpty; ++irq) { spi_device_irq_expected = irq; LOG_INFO("Triggering spi_device IRQ %d.", irq); diff --git a/sw/device/tests/rstmgr_sw_rst_ctrl_test.c b/sw/device/tests/rstmgr_sw_rst_ctrl_test.c index 85b4cb5758a29..293550ab53ba4 100644 --- a/sw/device/tests/rstmgr_sw_rst_ctrl_test.c +++ b/sw/device/tests/rstmgr_sw_rst_ctrl_test.c @@ -69,16 +69,7 @@ static void spi_device_config(void *dif) { .data_phase = kDifSpiDeviceEdgeNegative, .tx_order = kDifSpiDeviceBitOrderLsbToMsb, .rx_order = kDifSpiDeviceBitOrderLsbToMsb, - .device_mode = kDifSpiDeviceModeGeneric, - .mode_cfg = - { - .generic = - { - .rx_fifo_commit_wait = 63, - .rx_fifo_len = 0x800, - .tx_fifo_len = 0x800, - }, - }, + .device_mode = kDifSpiDeviceModeDisabled, }; CHECK_DIF_OK(dif_spi_device_configure(handle, cfg)); } diff --git a/sw/device/tests/sim_dv/BUILD b/sw/device/tests/sim_dv/BUILD index d2b10974e0350..47be23c6d20a2 100644 --- a/sw/device/tests/sim_dv/BUILD +++ b/sw/device/tests/sim_dv/BUILD @@ -652,25 +652,6 @@ opentitan_test( ], ) -opentitan_test( - name = "spi_tx_rx_test", - srcs = ["spi_tx_rx_test.c"], - exec_env = {"//hw/top_earlgrey:sim_dv": None}, - deps = [ - "//hw/top_earlgrey/sw/autogen:top_earlgrey", - "//sw/device/lib/arch:device", - "//sw/device/lib/base:mmio", - "//sw/device/lib/dif:base", - "//sw/device/lib/dif:rv_plic", - "//sw/device/lib/dif:spi_device", - "//sw/device/lib/runtime:hart", - "//sw/device/lib/runtime:irq", - "//sw/device/lib/runtime:log", - "//sw/device/lib/testing/test_framework:ottf_main", - "//sw/device/lib/testing/test_framework:status", - ], -) - opentitan_test( name = "spi_host_tx_rx_test", srcs = ["spi_host_tx_rx_test.c"], diff --git a/sw/device/tests/sim_dv/spi_passthrough_test.c b/sw/device/tests/sim_dv/spi_passthrough_test.c index 44c7faf21dff8..1768f8ea1dc0b 100644 --- a/sw/device/tests/sim_dv/spi_passthrough_test.c +++ b/sw/device/tests/sim_dv/spi_passthrough_test.c @@ -402,11 +402,10 @@ bool test_main(void) { // Enable all spi_device and spi_host interrupts, and check that they do not // trigger unless command upload is enabled. dif_spi_device_irq_t all_spi_device_irqs[] = { - kDifSpiDeviceIrqGenericRxFull, kDifSpiDeviceIrqGenericRxWatermark, - kDifSpiDeviceIrqGenericTxWatermark, kDifSpiDeviceIrqGenericRxError, - kDifSpiDeviceIrqGenericRxOverflow, kDifSpiDeviceIrqGenericTxUnderflow, - kDifSpiDeviceIrqUploadCmdfifoNotEmpty, kDifSpiDeviceIrqReadbufWatermark, - kDifSpiDeviceIrqReadbufFlip, kDifSpiDeviceIrqTpmHeaderNotEmpty, + kDifSpiDeviceIrqUploadCmdfifoNotEmpty, + kDifSpiDeviceIrqReadbufWatermark, + kDifSpiDeviceIrqReadbufFlip, + kDifSpiDeviceIrqTpmHeaderNotEmpty, }; for (int i = 0; i < ARRAYSIZE(all_spi_device_irqs); ++i) { dif_spi_device_irq_t irq = all_spi_device_irqs[i]; @@ -419,12 +418,6 @@ bool test_main(void) { kDifToggleEnabled)); dif_rv_plic_irq_id_t spi_irqs[] = { - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull, - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark, - kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark, - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError, - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow, - kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow, kTopEarlgreyPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty, kTopEarlgreyPlicIrqIdSpiDeviceReadbufWatermark, kTopEarlgreyPlicIrqIdSpiDeviceReadbufFlip, diff --git a/sw/device/tests/sim_dv/spi_tx_rx_test.c b/sw/device/tests/sim_dv/spi_tx_rx_test.c deleted file mode 100644 index 96d8337a8c005..0000000000000 --- a/sw/device/tests/sim_dv/spi_tx_rx_test.c +++ /dev/null @@ -1,370 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -#include "sw/device/lib/arch/device.h" -#include "sw/device/lib/base/mmio.h" -#include "sw/device/lib/dif/dif_rv_plic.h" -#include "sw/device/lib/dif/dif_spi_device.h" -#include "sw/device/lib/runtime/hart.h" -#include "sw/device/lib/runtime/ibex.h" -#include "sw/device/lib/runtime/irq.h" -#include "sw/device/lib/runtime/log.h" -#include "sw/device/lib/testing/test_framework/check.h" -#include "sw/device/lib/testing/test_framework/ottf_main.h" -#include "sw/device/lib/testing/test_framework/status.h" - -#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" - -#define SPI_DEVICE_DATASET_SIZE 128 -#define SPI_DEVICE_NUM_IRQS 6 - -static const uint16_t kFifoLen = 0x400; -static dif_rv_plic_t plic0; -static dif_spi_device_handle_t spi_device; - -// A set of bytes to be send out by spi_device. -// This array will be override with random values in UVM sequence. -static const uint8_t spi_device_tx_data[SPI_DEVICE_DATASET_SIZE] = { - 0xe8, 0x50, 0xc6, 0xb4, 0xbe, 0x16, 0xed, 0x55, 0x16, 0x1d, 0xe6, 0x1c, - 0xde, 0x9f, 0xfd, 0x24, 0x89, 0x81, 0x4d, 0x0d, 0x1a, 0x12, 0x4f, 0x57, - 0xea, 0xd6, 0x6f, 0xc0, 0x7d, 0x46, 0xe7, 0x37, 0x81, 0xd3, 0x8e, 0x16, - 0xad, 0x7b, 0xd0, 0xe2, 0x4f, 0xff, 0x39, 0xe6, 0x71, 0x3c, 0x82, 0x04, - 0xec, 0x3a, 0x27, 0xcc, 0x3d, 0x58, 0x0e, 0x56, 0xd2, 0xd2, 0xb9, 0xa3, - 0xb5, 0x3d, 0xc0, 0x40, 0xba, 0x90, 0x16, 0xd8, 0xe3, 0xa4, 0x22, 0x74, - 0x80, 0xcb, 0x7b, 0xde, 0xd7, 0x3f, 0x4d, 0x93, 0x4d, 0x59, 0x79, 0x88, - 0x24, 0xe7, 0x68, 0x8b, 0x7a, 0x78, 0xb7, 0x07, 0x09, 0x26, 0xcf, 0x6b, - 0x52, 0xd9, 0x4c, 0xd3, 0x33, 0xdf, 0x2e, 0x0d, 0x3b, 0xab, 0x45, 0x85, - 0xc2, 0xc2, 0x19, 0xe5, 0xc7, 0x2b, 0xb0, 0xf6, 0xcb, 0x06, 0xf6, 0xe2, - 0xf5, 0xb1, 0xab, 0xef, 0x6f, 0xd8, 0x23, 0xfd, -}; - -// The set of bytes expected to be received by spi_device from spi_host. -// This array will be override with random values in UVM sequence. -static const uint8_t exp_spi_device_rx_data[SPI_DEVICE_DATASET_SIZE] = { - 0x1b, 0x95, 0xc5, 0xb5, 0x8a, 0xa4, 0xa8, 0x9f, 0x6a, 0x7d, 0x6b, 0x0c, - 0xcd, 0xd5, 0xa6, 0x8f, 0x07, 0x3a, 0x9e, 0x82, 0xe6, 0xa2, 0x2b, 0xe0, - 0x0c, 0x30, 0xe8, 0x5a, 0x05, 0x14, 0x79, 0x8a, 0xFf, 0x88, 0x29, 0xda, - 0xc8, 0xdd, 0x82, 0xd5, 0x68, 0xa5, 0x9d, 0x5a, 0x48, 0x02, 0x7f, 0x24, - 0x32, 0xaf, 0x9d, 0xca, 0xa7, 0x06, 0x0c, 0x96, 0x65, 0x18, 0xe4, 0x7f, - 0x26, 0x44, 0xf3, 0x14, 0xC1, 0xe7, 0xd9, 0x82, 0xf7, 0x64, 0xe8, 0x68, - 0xf9, 0x6c, 0xa9, 0xe7, 0xd1, 0x9b, 0xac, 0xe1, 0xFd, 0xd8, 0x59, 0xb7, - 0x8e, 0xdc, 0x24, 0xb8, 0xa7, 0xaf, 0x20, 0xee, 0x6c, 0x61, 0x48, 0x41, - 0xB4, 0x62, 0x3c, 0xcb, 0x2c, 0xbb, 0xe4, 0x44, 0x97, 0x8a, 0x5e, 0x2f, - 0x7f, 0x2b, 0x10, 0xcc, 0x7d, 0x89, 0x32, 0xfd, 0xfd, 0x58, 0x7f, 0xd8, - 0xc7, 0x33, 0xd1, 0x6a, 0xc7, 0xba, 0x78, 0x69, -}; - -// Set our expectation & event indications of the interrupts we intend to -// exercise in this test. These are declared volatile since they are used by the -// ISR. -static volatile bool expected_irqs[SPI_DEVICE_NUM_IRQS]; -static volatile bool fired_irqs[SPI_DEVICE_NUM_IRQS]; - -/** - * Provides external irq handling for this test. - * - * This function overrides the default OTTF external ISR. - */ -void ottf_external_isr(uint32_t *exc_info) { - // Find which interrupt fired at PLIC by claiming it. - dif_rv_plic_irq_id_t plic_irq_id; - CHECK_DIF_OK( - dif_rv_plic_irq_claim(&plic0, kTopEarlgreyPlicTargetIbex0, &plic_irq_id)); - - // Check if it is the right peripheral. - top_earlgrey_plic_peripheral_t peripheral = (top_earlgrey_plic_peripheral_t) - top_earlgrey_plic_interrupt_for_peripheral[plic_irq_id]; - CHECK(peripheral == kTopEarlgreyPlicPeripheralSpiDevice, - "Interurpt from unexpected peripheral: %d", peripheral); - - // Correlate the interrupt fired at PLIC with SPI DEVICE. - dif_spi_device_irq_t spi_device_irq = 0; - switch (plic_irq_id) { - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull: - spi_device_irq = kDifSpiDeviceIrqGenericRxFull; - CHECK(expected_irqs[spi_device_irq], "Unexpected RX full interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark: - spi_device_irq = kDifSpiDeviceIrqGenericRxWatermark; - CHECK(expected_irqs[spi_device_irq], - "Unexpected RX above level interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark: - spi_device_irq = kDifSpiDeviceIrqGenericTxWatermark; - CHECK(expected_irqs[spi_device_irq], - "Unexpected TX below level interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError: - spi_device_irq = kDifSpiDeviceIrqGenericRxError; - CHECK(expected_irqs[spi_device_irq], "Unexpected RX error interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow: - spi_device_irq = kDifSpiDeviceIrqGenericRxOverflow; - CHECK(expected_irqs[spi_device_irq], "Unexpected RX overflow interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow: - spi_device_irq = kDifSpiDeviceIrqGenericTxUnderflow; - CHECK(expected_irqs[spi_device_irq], "Unexpected TX underflow interrupt"); - // TxUnderflow keeps firing as TX fifo is empty but TB controls host to - // keep sending data and requesting data from device, so disable this - // interrupt once fired. Since TxUnderflow keeps firing, PC can not go - // back to the main program, disable the interrupt here instead of in the - // main program. - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device.dev, kDifSpiDeviceIrqGenericTxUnderflow, - kDifToggleDisabled)); - break; - default: - LOG_ERROR("Unexpected interrupt (at PLIC): %d", plic_irq_id); - test_status_set(kTestStatusFailed); - } - fired_irqs[spi_device_irq] = true; - LOG_INFO("%s: %d", __func__, spi_device_irq); - - // Check if the same interrupt fired at SPI DEVICE as well. - bool flag_out; - CHECK_DIF_OK(dif_spi_device_irq_is_pending(&spi_device.dev, spi_device_irq, - &flag_out)); - CHECK(flag_out, - "SPI_DEVICE interrupt fired at PLIC did not fire at SPI_DEVICE"); - - // Clear the interrupt at SPI DEVICE. - CHECK_DIF_OK(dif_spi_device_irq_acknowledge(&spi_device.dev, spi_device_irq)); - - // Complete the IRQ at PLIC. - CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic0, kTopEarlgreyPlicTargetIbex0, - plic_irq_id)); -} - -/** - * Initializes SPI_DEVICE and enables the relevant interrupts. - */ -static void spi_device_init_with_irqs( - mmio_region_t base_addr, dif_spi_device_handle_t *spi_device, - dif_spi_device_config_t spi_device_config) { - LOG_INFO("Initializing the SPI_DEVICE."); - CHECK_DIF_OK(dif_spi_device_init_handle(base_addr, spi_device)); - CHECK_DIF_OK(dif_spi_device_configure(spi_device, spi_device_config)); - - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxFull, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxWatermark, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericTxWatermark, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxError, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxOverflow, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericTxUnderflow, kDifToggleEnabled)); - - // Initialize the volatile irq variables. - for (int i = 0; i < SPI_DEVICE_NUM_IRQS; i++) { - expected_irqs[i] = false; - fired_irqs[i] = false; - } -} - -/** - * Initializes PLIC and enables the relevant SPI DEVICE interrupts. - */ -static void plic_init_with_irqs(mmio_region_t base_addr, dif_rv_plic_t *plic) { - LOG_INFO("Initializing the PLIC."); - - CHECK_DIF_OK(dif_rv_plic_init(base_addr, plic)); - - // Set the priority of SPI DEVICE interrupts at PLIC to be >=1 (so ensure the - // target does get interrupted). - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow, - kDifRvPlicMaxPriority)); - - // Set the threshold for the Ibex to 0. - CHECK_DIF_OK( - dif_rv_plic_target_set_threshold(plic, kTopEarlgreyPlicTargetIbex0, 0x0)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); -} - -static bool exp_irqs_fired(void) { - return fired_irqs[kDifSpiDeviceIrqGenericRxWatermark] && - fired_irqs[kDifSpiDeviceIrqGenericTxWatermark] && - fired_irqs[kDifSpiDeviceIrqGenericRxOverflow] && - fired_irqs[kDifSpiDeviceIrqGenericTxUnderflow] && - fired_irqs[kDifSpiDeviceIrqGenericRxFull]; -} - -static void sync_testbench(void) { - // Set WFI status for testbench synchronization, - // no actual WFI instruction is issued. - test_status_set(kTestStatusInWfi); - test_status_set(kTestStatusInTest); -} - -enum { - kTimeoutUs = 1000, -}; - -static bool execute_test(dif_spi_device_handle_t *spi_device) { - LOG_INFO("Executing the test."); - - size_t bytes_transferred = 0; - CHECK_DIF_OK(dif_spi_device_send(spi_device, spi_device_tx_data, - SPI_DEVICE_DATASET_SIZE, - &bytes_transferred)); - CHECK(!exp_irqs_fired()); - sync_testbench(); - CHECK(bytes_transferred == SPI_DEVICE_DATASET_SIZE, - "SPI_DEVICE TX_FIFO transferred bytes mismatched: {act: %d, exp: %d}", - bytes_transferred, SPI_DEVICE_DATASET_SIZE); - LOG_INFO("Transferred %d bytes to SPI_DEVICE TX_FIFO.", bytes_transferred); - - CHECK_DIF_OK(dif_spi_device_set_irq_levels( - spi_device, SPI_DEVICE_DATASET_SIZE, SPI_DEVICE_DATASET_SIZE / 2)); - expected_irqs[kDifSpiDeviceIrqGenericTxWatermark] = true; - - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericTxWatermark] && - expected_irqs[kDifSpiDeviceIrqGenericTxWatermark], - kTimeoutUs); - - // Set rx tx level back to default value so TxBelowLevel irq won't trigger. - CHECK_DIF_OK( - dif_spi_device_set_irq_levels(spi_device, SPI_DEVICE_DATASET_SIZE, 0)); - expected_irqs[kDifSpiDeviceIrqGenericTxWatermark] = false; - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark] = true; - LOG_INFO("SPI_DEVICE tx_below_level interrupt fired."); - - // Wait for SPI_HOST to send 128 bytes and trigger RxAboveLevel irq. - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxWatermark] && - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark], - kTimeoutUs); - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark] = false; - LOG_INFO("SPI_DEVICE rx_above_level interrupt fired."); - - // When 128 bytes received in RX_FIFO from SPI_HOST, - // read out and compare against the expected data. - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxWatermark], kTimeoutUs); - size_t bytes_recved = 0; - uint8_t spi_device_rx_data[SPI_DEVICE_DATASET_SIZE]; - CHECK_DIF_OK(dif_spi_device_recv(spi_device, spi_device_rx_data, - SPI_DEVICE_DATASET_SIZE, &bytes_recved)); - CHECK(bytes_recved == SPI_DEVICE_DATASET_SIZE, - "SPI_DEVICE RX_FIFO recvd bytes mismatched: {act: %d, exp: %d}", - bytes_recved, SPI_DEVICE_DATASET_SIZE); - LOG_INFO("Received %d bytes from SPI_DEVICE RX_FIFO.", bytes_recved); - - expected_irqs[kDifSpiDeviceIrqGenericTxUnderflow] = true; - fired_irqs[kDifSpiDeviceIrqGenericRxWatermark] = false; - - // Check data consistency. - LOG_INFO("Checking the received SPI_HOST RX_FIFO data for consistency."); - CHECK_ARRAYS_EQ(spi_device_rx_data, exp_spi_device_rx_data, - SPI_DEVICE_DATASET_SIZE); - - sync_testbench(); - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericTxUnderflow], kTimeoutUs); - LOG_INFO("SPI_DEVICE Tx underflow fired."); - - // expect SPI_HOST to send another 1024 bytes to fill RX SRAM FIFO. - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark] = true; - expected_irqs[kDifSpiDeviceIrqGenericTxUnderflow] = false; - - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxWatermark], kTimeoutUs); - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark] = false; - expected_irqs[kDifSpiDeviceIrqGenericRxFull] = true; - LOG_INFO("SPI_DEVICE RX Above level interrupt fired."); - - // After RX SRAM FIFO full, expect RX async FIFO overflow irq. - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxFull] && - !fired_irqs[kDifSpiDeviceIrqGenericRxOverflow], - kTimeoutUs); - LOG_INFO("SPI_DEVICE RX_FIFO full interrupt fired."); - - expected_irqs[kDifSpiDeviceIrqGenericRxFull] = false; - expected_irqs[kDifSpiDeviceIrqGenericRxOverflow] = true; - sync_testbench(); - // After RX SRAM FIFO full, expect RX async FIFO overflow irq. - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxOverflow], kTimeoutUs); - LOG_INFO("SPI_DEVICE RX_FIFO Overflow interrupt fired."); - - CHECK(exp_irqs_fired()); - - return true; -} - -OTTF_DEFINE_TEST_CONFIG(); - -bool test_main(void) { - mmio_region_t spi_device_base_addr = - mmio_region_from_addr(TOP_EARLGREY_SPI_DEVICE_BASE_ADDR); - dif_spi_device_config_t spi_device_config = { - .clock_polarity = kDifSpiDeviceEdgePositive, - .data_phase = kDifSpiDeviceEdgeNegative, - .tx_order = kDifSpiDeviceBitOrderMsbToLsb, - .rx_order = kDifSpiDeviceBitOrderMsbToLsb, - .device_mode = kDifSpiDeviceModeGeneric, - .mode_cfg = - { - .generic = - { - .rx_fifo_commit_wait = 63, - .rx_fifo_len = kFifoLen, - .tx_fifo_len = kFifoLen, - }, - }, - }; - - // Initialize SPI_DEVICE. - spi_device_init_with_irqs(spi_device_base_addr, &spi_device, - spi_device_config); - - mmio_region_t plic_base_addr = - mmio_region_from_addr(TOP_EARLGREY_RV_PLIC_BASE_ADDR); - // Initialize the PLIC. - plic_init_with_irqs(plic_base_addr, &plic0); - - // Enable the external IRQ at Ibex. - irq_global_ctrl(true); - irq_external_ctrl(true); - - return execute_test(&spi_device); -} diff --git a/sw/device/tests/sival/BUILD b/sw/device/tests/sival/BUILD index 082ea8098e53c..7cc4686dff1dd 100644 --- a/sw/device/tests/sival/BUILD +++ b/sw/device/tests/sival/BUILD @@ -52,7 +52,6 @@ test_suite( "//sw/device/tests:rv_dm_ndm_reset_req", "//sw/device/tests:rv_plic_smoketest", "//sw/device/tests:rv_timer_smoketest", - "//sw/device/tests:spi_device_smoketest", "//sw/device/tests:spi_host_winbond_flash_test", "//sw/device/tests:sram_ctrl_sleep_sram_ret_contents_no_scramble_test", "//sw/device/tests:sram_ctrl_sleep_sram_ret_contents_scramble_test", diff --git a/sw/device/tests/spi_device_ottf_console_test.c b/sw/device/tests/spi_device_ottf_console_test.c deleted file mode 100644 index a998e2efbbe98..0000000000000 --- a/sw/device/tests/spi_device_ottf_console_test.c +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -#include "sw/device/lib/dif/dif_spi_device.h" -#include "sw/device/lib/runtime/log.h" -#include "sw/device/lib/testing/test_framework/check.h" -#include "sw/device/lib/testing/test_framework/ottf_main.h" - -#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" - -OTTF_DEFINE_TEST_CONFIG(.console.type = kOttfConsoleSpiDevice, - .console.base_addr = TOP_EARLGREY_SPI_DEVICE_BASE_ADDR, - .console.test_may_clobber = false, ); - -static const char test_str[] = "This is a SPI device OTTF console test."; - -bool test_main(void) { - LOG_INFO("%s", test_str); - - return true; -} diff --git a/sw/device/tests/spi_device_smoketest.c b/sw/device/tests/spi_device_smoketest.c deleted file mode 100644 index e0a20f1b8390f..0000000000000 --- a/sw/device/tests/spi_device_smoketest.c +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -#include "sw/device/lib/arch/device.h" -#include "sw/device/lib/base/mmio.h" -#include "sw/device/lib/dif/dif_rv_plic.h" -#include "sw/device/lib/dif/dif_spi_device.h" -#include "sw/device/lib/runtime/hart.h" -#include "sw/device/lib/runtime/ibex.h" -#include "sw/device/lib/runtime/irq.h" -#include "sw/device/lib/runtime/log.h" -#include "sw/device/lib/testing/test_framework/check.h" -#include "sw/device/lib/testing/test_framework/ottf_main.h" -#include "sw/device/lib/testing/test_framework/status.h" - -#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" - -enum { - kSpiDeviceDatasetSize = 128, - kSpiDeviceNumIrqs = 6, - kFifoLen = 0x400, - kTimeoutUs = 125000, -}; - -static dif_rv_plic_t plic0; -static dif_spi_device_handle_t spi_device; - -// A set of bytes to be send out by spi_device. -static const uint8_t spi_device_tx_data[kSpiDeviceDatasetSize] = { - 0xe8, 0x50, 0xc6, 0xb4, 0xbe, 0x16, 0xed, 0x55, 0x16, 0x1d, 0xe6, 0x1c, - 0xde, 0x9f, 0xfd, 0x24, 0x89, 0x81, 0x4d, 0x0d, 0x1a, 0x12, 0x4f, 0x57, - 0xea, 0xd6, 0x6f, 0xc0, 0x7d, 0x46, 0xe7, 0x37, 0x81, 0xd3, 0x8e, 0x16, - 0xad, 0x7b, 0xd0, 0xe2, 0x4f, 0xff, 0x39, 0xe6, 0x71, 0x3c, 0x82, 0x04, - 0xec, 0x3a, 0x27, 0xcc, 0x3d, 0x58, 0x0e, 0x56, 0xd2, 0xd2, 0xb9, 0xa3, - 0xb5, 0x3d, 0xc0, 0x40, 0xba, 0x90, 0x16, 0xd8, 0xe3, 0xa4, 0x22, 0x74, - 0x80, 0xcb, 0x7b, 0xde, 0xd7, 0x3f, 0x4d, 0x93, 0x4d, 0x59, 0x79, 0x88, - 0x24, 0xe7, 0x68, 0x8b, 0x7a, 0x78, 0xb7, 0x07, 0x09, 0x26, 0xcf, 0x6b, - 0x52, 0xd9, 0x4c, 0xd3, 0x33, 0xdf, 0x2e, 0x0d, 0x3b, 0xab, 0x45, 0x85, - 0xc2, 0xc2, 0x19, 0xe5, 0xc7, 0x2b, 0xb0, 0xf6, 0xcb, 0x06, 0xf6, 0xe2, - 0xf5, 0xb1, 0xab, 0xef, 0x6f, 0xd8, 0x23, 0xfd, -}; - -// The set of bytes expected to be received by spi_device from spi_host. -static const uint8_t exp_spi_device_rx_data[kSpiDeviceDatasetSize] = { - 0x1b, 0x95, 0xc5, 0xb5, 0x8a, 0xa4, 0xa8, 0x9f, 0x6a, 0x7d, 0x6b, 0x0c, - 0xcd, 0xd5, 0xa6, 0x8f, 0x07, 0x3a, 0x9e, 0x82, 0xe6, 0xa2, 0x2b, 0xe0, - 0x0c, 0x30, 0xe8, 0x5a, 0x05, 0x14, 0x79, 0x8a, 0xFf, 0x88, 0x29, 0xda, - 0xc8, 0xdd, 0x82, 0xd5, 0x68, 0xa5, 0x9d, 0x5a, 0x48, 0x02, 0x7f, 0x24, - 0x32, 0xaf, 0x9d, 0xca, 0xa7, 0x06, 0x0c, 0x96, 0x65, 0x18, 0xe4, 0x7f, - 0x26, 0x44, 0xf3, 0x14, 0xC1, 0xe7, 0xd9, 0x82, 0xf7, 0x64, 0xe8, 0x68, - 0xf9, 0x6c, 0xa9, 0xe7, 0xd1, 0x9b, 0xac, 0xe1, 0xFd, 0xd8, 0x59, 0xb7, - 0x8e, 0xdc, 0x24, 0xb8, 0xa7, 0xaf, 0x20, 0xee, 0x6c, 0x61, 0x48, 0x41, - 0xB4, 0x62, 0x3c, 0xcb, 0x2c, 0xbb, 0xe4, 0x44, 0x97, 0x8a, 0x5e, 0x2f, - 0x7f, 0x2b, 0x10, 0xcc, 0x7d, 0x89, 0x32, 0xfd, 0xfd, 0x58, 0x7f, 0xd8, - 0xc7, 0x33, 0xd1, 0x6a, 0xc7, 0xba, 0x78, 0x69, -}; - -// Set our expectation & event indications of the interrupts we intend to -// exercise in this test. These are declared volatile since they are used by the -// ISR. -static volatile bool expected_irqs[kSpiDeviceNumIrqs]; -static volatile bool fired_irqs[kSpiDeviceNumIrqs]; - -/** - * Provides external irq handling for this test. - * - * This function overrides the default OTTF external ISR. - */ -void ottf_external_isr(void) { - // Find which interrupt fired at PLIC by claiming it. - dif_rv_plic_irq_id_t plic_irq_id; - CHECK_DIF_OK( - dif_rv_plic_irq_claim(&plic0, kTopEarlgreyPlicTargetIbex0, &plic_irq_id)); - - // Check if it is the right peripheral. - top_earlgrey_plic_peripheral_t peripheral = (top_earlgrey_plic_peripheral_t) - top_earlgrey_plic_interrupt_for_peripheral[plic_irq_id]; - CHECK(peripheral == kTopEarlgreyPlicPeripheralSpiDevice, - "Interurpt from unexpected peripheral: %d", peripheral); - - LOG_INFO("%s: %d", __func__, plic_irq_id); - // Correlate the interrupt fired at PLIC with SPI DEVICE. - dif_spi_device_irq_t spi_device_irq = 0; - switch (plic_irq_id) { - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull: - spi_device_irq = kDifSpiDeviceIrqGenericRxFull; - CHECK(expected_irqs[spi_device_irq], "Unexpected RX full interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark: - spi_device_irq = kDifSpiDeviceIrqGenericRxWatermark; - CHECK(expected_irqs[spi_device_irq], "Unexpected RxWatermark interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark: - spi_device_irq = kDifSpiDeviceIrqGenericTxWatermark; - CHECK(expected_irqs[spi_device_irq], "Unexpected TxWatermark interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError: - spi_device_irq = kDifSpiDeviceIrqGenericRxError; - CHECK(expected_irqs[spi_device_irq], "Unexpected RX error interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow: - spi_device_irq = kDifSpiDeviceIrqGenericRxOverflow; - CHECK(expected_irqs[spi_device_irq], "Unexpected RX overflow interrupt"); - break; - case kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow: - spi_device_irq = kDifSpiDeviceIrqGenericTxUnderflow; - CHECK(expected_irqs[spi_device_irq], "Unexpected TX underflow interrupt"); - // TxUnderflow keeps firing as TX fifo is empty but TB controls host to - // keep sending data and requesting data from device, so disable this - // interrupt once fired. Since TxUnderflow keeps firing, PC can not go - // back to the main program, disable the interrupt here instead of in the - // main program. - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device.dev, kDifSpiDeviceIrqGenericTxUnderflow, - kDifToggleDisabled)); - break; - default: - LOG_ERROR("Unexpected interrupt (at PLIC): %d", plic_irq_id); - test_status_set(kTestStatusFailed); - } - fired_irqs[spi_device_irq] = true; - - // Check if the same interrupt fired at SPI DEVICE as well. - bool flag_out; - CHECK_DIF_OK(dif_spi_device_irq_is_pending(&spi_device.dev, spi_device_irq, - &flag_out)); - CHECK(flag_out, - "SPI_DEVICE interrupt fired at PLIC did not fire at SPI_DEVICE"); - - // Clear the interrupt at SPI DEVICE. - CHECK_DIF_OK(dif_spi_device_irq_acknowledge(&spi_device.dev, spi_device_irq)); - - // Complete the IRQ at PLIC. - CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic0, kTopEarlgreyPlicTargetIbex0, - plic_irq_id)); -} - -/** - * Initializes SPI_DEVICE and enables the relevant interrupts. - */ -static void spi_device_init_with_irqs( - mmio_region_t base_addr, dif_spi_device_handle_t *spi_device, - dif_spi_device_config_t spi_device_config) { - LOG_INFO("Initializing the SPI_DEVICE."); - CHECK_DIF_OK(dif_spi_device_init_handle(base_addr, spi_device)); - CHECK_DIF_OK(dif_spi_device_configure(spi_device, spi_device_config)); - - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxFull, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxWatermark, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericTxWatermark, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxError, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericRxOverflow, kDifToggleEnabled)); - CHECK_DIF_OK(dif_spi_device_irq_set_enabled( - &spi_device->dev, kDifSpiDeviceIrqGenericTxUnderflow, kDifToggleEnabled)); - - // Initialize the volatile irq variables. - for (int i = 0; i < kSpiDeviceNumIrqs; i++) { - expected_irqs[i] = false; - fired_irqs[i] = false; - } -} - -/** - * Initializes PLIC and enables the relevant SPI DEVICE interrupts. - */ -static void plic_init_with_irqs(mmio_region_t base_addr, dif_rv_plic_t *plic) { - LOG_INFO("Initializing the PLIC."); - - CHECK_DIF_OK(dif_rv_plic_init(base_addr, plic)); - - // Set the priority of SPI DEVICE interrupts at PLIC to be >=1 (so ensure the - // target does get interrupted). - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow, - kDifRvPlicMaxPriority)); - CHECK_DIF_OK(dif_rv_plic_irq_set_priority( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow, - kDifRvPlicMaxPriority)); - - // Set the threshold for the Ibex to 0. - CHECK_DIF_OK( - dif_rv_plic_target_set_threshold(plic, kTopEarlgreyPlicTargetIbex0, 0x0)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); - - CHECK_DIF_OK(dif_rv_plic_irq_set_enabled( - plic, kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow, - kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled)); -} - -static bool exp_irqs_fired(void) { - return fired_irqs[kDifSpiDeviceIrqGenericRxWatermark] && - fired_irqs[kDifSpiDeviceIrqGenericTxWatermark] && - fired_irqs[kDifSpiDeviceIrqGenericRxOverflow] && - fired_irqs[kDifSpiDeviceIrqGenericTxUnderflow] && - fired_irqs[kDifSpiDeviceIrqGenericRxFull]; -} - -static void flush_fifo(dif_spi_device_handle_t *spi_device) { - size_t bytes_recved = 0; - uint8_t spi_device_rx_data[kFifoLen]; - CHECK_DIF_OK(dif_spi_device_recv(spi_device, spi_device_rx_data, - sizeof(spi_device_rx_data), &bytes_recved)); -} - -static void tx_watermark_test(dif_spi_device_handle_t *spi_device) { - LOG_INFO("%s", __func__); - - size_t bytes_transferred = 0; - CHECK_DIF_OK(dif_spi_device_send(spi_device, spi_device_tx_data, - kSpiDeviceDatasetSize, &bytes_transferred)); - CHECK(!exp_irqs_fired()); - - CHECK(bytes_transferred == kSpiDeviceDatasetSize, - "spi_device tx_fifo transferred bytes mismatched: {act: %d, exp: %d}", - bytes_transferred, kSpiDeviceDatasetSize); - - CHECK_DIF_OK(dif_spi_device_set_irq_levels(spi_device, - /*rx=*/kSpiDeviceDatasetSize + 1, - /*tx=*/kSpiDeviceDatasetSize / 2)); - expected_irqs[kDifSpiDeviceIrqGenericTxWatermark] = true; - // Note: The message bellow is used for syncronization with the host. - LOG_INFO("SYNC: TX_FIFO READY"); - LOG_INFO("Transferred %d bytes to spi_device tx_fifo.", bytes_transferred); - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericTxWatermark] && - expected_irqs[kDifSpiDeviceIrqGenericTxWatermark], - kTimeoutUs); - LOG_INFO("spi_device tx_watermark interrupt fired."); -} - -static void rx_watermark_test(dif_spi_device_handle_t *spi_device) { - LOG_INFO("%s", __func__); - - flush_fifo(spi_device); - // Set rx tx level back to default value so TxBelowLevel irq won't trigger. - CHECK_DIF_OK(dif_spi_device_set_irq_levels(spi_device, - /*rx=*/kSpiDeviceDatasetSize, - /*tx=*/kSpiDeviceDatasetSize + 1)); - expected_irqs[kDifSpiDeviceIrqGenericTxWatermark] = false; - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark] = true; - size_t bytes_transferred = 0; - CHECK_DIF_OK(dif_spi_device_send(spi_device, spi_device_tx_data, - kSpiDeviceDatasetSize, &bytes_transferred)); - // Note: The message below is used for synchronization with the host. - LOG_INFO("SYNC: RX_FIFO READY"); - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxWatermark] && - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark], - kTimeoutUs); - LOG_INFO("spi_device rx_watermark interrupt fired."); - - // When 128 bytes received in RX_FIFO from SPI_HOST, - // read out and compare against the expected data. - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxWatermark], kTimeoutUs); - size_t bytes_recved = 0; - uint8_t spi_device_rx_data[kSpiDeviceDatasetSize]; - CHECK_DIF_OK(dif_spi_device_recv(spi_device, spi_device_rx_data, - kSpiDeviceDatasetSize, &bytes_recved)); - CHECK(bytes_recved == kSpiDeviceDatasetSize, - "spi_device rx_fifo recvd bytes mismatched: {act: %d, exp: %d}", - bytes_recved, kSpiDeviceDatasetSize); - LOG_INFO("received %d bytes from spi_device rx_fifo.", bytes_recved); - // Check data consistency. - LOG_INFO("Checking the received spi_host rx_fifo data for consistency."); - CHECK_ARRAYS_EQ(spi_device_rx_data, exp_spi_device_rx_data, - kSpiDeviceDatasetSize); -} - -static void tx_underflow_test(dif_spi_device_handle_t *spi_device) { - LOG_INFO("%s", __func__); - - CHECK_DIF_OK(dif_spi_device_set_irq_levels( - spi_device, /*rx=*/kSpiDeviceDatasetSize * 2, /*tx=*/1)); - expected_irqs[kDifSpiDeviceIrqGenericTxUnderflow] = true; - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark] = false; - // Note: The message below is used for synchronization with the host. - LOG_INFO("SYNC: TX_FIFO UNDERFLOW READY"); - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericTxUnderflow], kTimeoutUs); - LOG_INFO("spi_device tx underflow fired."); -} - -static void rx_full_test(dif_spi_device_handle_t *spi_device) { - LOG_INFO("%s", __func__); - - flush_fifo(spi_device); - CHECK_DIF_OK(dif_spi_device_set_irq_levels(spi_device, /*rx=*/1024, - /*tx=*/kSpiDeviceDatasetSize)); - expected_irqs[kDifSpiDeviceIrqGenericRxWatermark] = false; - expected_irqs[kDifSpiDeviceIrqGenericRxFull] = true; - // Note: The message below is used for synchronization with the host. - LOG_INFO("SYNC: RX_FIFO FULL READY"); - // After RX SRAM FIFO full, expect RX async FIFO overflow irq. - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxFull] && - !fired_irqs[kDifSpiDeviceIrqGenericRxOverflow], - kTimeoutUs); - LOG_INFO("Spi_device rx_fifo full interrupt fired."); -} - -static void rx_overflow_test(dif_spi_device_handle_t *spi_device) { - LOG_INFO("%s", __func__); - - expected_irqs[kDifSpiDeviceIrqGenericRxFull] = false; - expected_irqs[kDifSpiDeviceIrqGenericRxOverflow] = true; - // Note: The message below is used for synchronization with the host. - LOG_INFO("SYNC: RX_FIFO OVERFLOW READY"); - // After RX SRAM FIFO full, expect RX async FIFO overflow irq. - IBEX_SPIN_FOR(fired_irqs[kDifSpiDeviceIrqGenericRxOverflow], kTimeoutUs); - LOG_INFO("Spi_device rx_fifo overflow interrupt fired."); - flush_fifo(spi_device); -} - -static void test_initialize(void) { - mmio_region_t spi_device_base_addr = - mmio_region_from_addr(TOP_EARLGREY_SPI_DEVICE_BASE_ADDR); - dif_spi_device_config_t spi_device_config = { - .clock_polarity = kDifSpiDeviceEdgePositive, - .data_phase = kDifSpiDeviceEdgeNegative, - .tx_order = kDifSpiDeviceBitOrderMsbToLsb, - .rx_order = kDifSpiDeviceBitOrderMsbToLsb, - .device_mode = kDifSpiDeviceModeGeneric, - .mode_cfg = - { - .generic = - { - .rx_fifo_commit_wait = 63, - .rx_fifo_len = kFifoLen, - .tx_fifo_len = kFifoLen, - }, - }, - }; - - // Initialize SPI_DEVICE. - spi_device_init_with_irqs(spi_device_base_addr, &spi_device, - spi_device_config); - - mmio_region_t plic_base_addr = - mmio_region_from_addr(TOP_EARLGREY_RV_PLIC_BASE_ADDR); - // Initialize the PLIC. - plic_init_with_irqs(plic_base_addr, &plic0); - - // Enable the external IRQ at Ibex. - irq_global_ctrl(true); - irq_external_ctrl(true); -} - -OTTF_DEFINE_TEST_CONFIG(); - -/** - * TODO: This test is based on the DV test - * `//sw/device/tests/sim_dv/spi_tx_rx_test.c` with some changes to make the - * hyperdebug happy. We should either refactor - * `hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tx_rx_vseq.sv` to do what - * the Rust side is doing or change hyperdebug to support full duplex - * transactions. - */ -bool test_main(void) { - test_initialize(); - - tx_watermark_test(&spi_device); - rx_watermark_test(&spi_device); - tx_underflow_test(&spi_device); - rx_full_test(&spi_device); - rx_overflow_test(&spi_device); - - CHECK(exp_irqs_fired()); - - return true; -} diff --git a/sw/device/tests/spi_device_tpm_tx_rx_test.c b/sw/device/tests/spi_device_tpm_tx_rx_test.c index 13289edc29f97..db40abcbb91ee 100644 --- a/sw/device/tests/spi_device_tpm_tx_rx_test.c +++ b/sw/device/tests/spi_device_tpm_tx_rx_test.c @@ -49,12 +49,6 @@ static void en_plic_irqs(dif_rv_plic_t *plic) { // Enable functional interrupts as well as error interrupts to make sure // everything is behaving as expected. const top_earlgrey_plic_irq_id_t kIrqs[] = { - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull, - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxWatermark, - kTopEarlgreyPlicIrqIdSpiDeviceGenericTxWatermark, - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxError, - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxOverflow, - kTopEarlgreyPlicIrqIdSpiDeviceGenericTxUnderflow, kTopEarlgreyPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty, kTopEarlgreyPlicIrqIdSpiDeviceUploadPayloadNotEmpty, kTopEarlgreyPlicIrqIdSpiDeviceUploadPayloadOverflow, @@ -77,13 +71,7 @@ static void en_plic_irqs(dif_rv_plic_t *plic) { } static void en_spi_device_irqs(dif_spi_device_t *spi_device) { - const dif_spi_device_irq_t kIrqs[] = {kDifSpiDeviceIrqGenericRxFull, - kDifSpiDeviceIrqGenericRxWatermark, - kDifSpiDeviceIrqGenericTxWatermark, - kDifSpiDeviceIrqGenericRxError, - kDifSpiDeviceIrqGenericRxOverflow, - kDifSpiDeviceIrqGenericTxUnderflow, - kDifSpiDeviceIrqUploadCmdfifoNotEmpty, + const dif_spi_device_irq_t kIrqs[] = {kDifSpiDeviceIrqUploadCmdfifoNotEmpty, kDifSpiDeviceIrqUploadPayloadNotEmpty, kDifSpiDeviceIrqUploadPayloadOverflow, kDifSpiDeviceIrqReadbufWatermark, @@ -104,7 +92,7 @@ void ottf_external_isr(uint32_t *exc_info) { spi_device_isr_ctx_t spi_device_ctx = { .spi_device = &spi_device.dev, .plic_spi_device_start_irq_id = - kTopEarlgreyPlicIrqIdSpiDeviceGenericRxFull, + kTopEarlgreyPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty, .expected_irq = kDifSpiDeviceIrqTpmHeaderNotEmpty, .is_only_irq = true}; diff --git a/sw/host/tests/chip/spi_device_ottf_console/BUILD b/sw/host/tests/chip/spi_device_ottf_console/BUILD deleted file mode 100644 index 95512357daee0..0000000000000 --- a/sw/host/tests/chip/spi_device_ottf_console/BUILD +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -load("@rules_rust//rust:defs.bzl", "rust_binary") - -package(default_visibility = ["//visibility:public"]) - -rust_binary( - name = "spi_device_ottf_console", - srcs = [ - "src/main.rs", - ], - deps = [ - "//sw/host/opentitanlib", - "//third_party/rust/crates:anyhow", - "//third_party/rust/crates:clap", - "//third_party/rust/crates:humantime", - "//third_party/rust/crates:log", - "//third_party/rust/crates:regex", - ], -) diff --git a/sw/host/tests/chip/spi_device_ottf_console/src/main.rs b/sw/host/tests/chip/spi_device_ottf_console/src/main.rs deleted file mode 100644 index 36dc45463b4d2..0000000000000 --- a/sw/host/tests/chip/spi_device_ottf_console/src/main.rs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -use anyhow::{anyhow, Result}; -use clap::Parser; -use regex::Regex; -use std::time::Duration; - -use opentitanlib::app::TransportWrapper; -use opentitanlib::console::spi::SpiConsoleDevice; -use opentitanlib::execute_test; -use opentitanlib::test_utils::init::InitializeTest; -use opentitanlib::uart::console::{ExitStatus, UartConsole}; - -#[derive(Debug, Parser)] -struct Opts { - #[command(flatten)] - init: InitializeTest, - - /// Console receive timeout. - #[arg(long, value_parser = humantime::parse_duration, default_value = "600s")] - timeout: Duration, - - /// Name of the SPI interface to connect to the OTTF console. - #[arg(long, default_value = "BOOTSTRAP")] - console_spi: String, -} - -fn spi_device_console_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> { - let mut console = UartConsole { - timeout: Some(opts.timeout), - exit_success: Some(Regex::new(r"PASS.*\n")?), - exit_failure: Some(Regex::new(r"(FAIL|FAULT).*\n")?), - newline: true, - ..Default::default() - }; - let mut stdout = std::io::stdout(); - let spi = transport.spi(&opts.console_spi)?; - let spi_console_device = SpiConsoleDevice::new(&*spi); - let _ = UartConsole::wait_for(&spi_console_device, r"Running [^\r\n]*", opts.timeout)?; - let result = console.interact(&spi_console_device, None, Some(&mut stdout))?; - match result { - ExitStatus::None | ExitStatus::CtrlC => Ok(()), - ExitStatus::Timeout => { - if console.exit_success.is_some() { - Err(anyhow!("Console timeout exceeded")) - } else { - Ok(()) - } - } - ExitStatus::ExitSuccess => { - log::info!( - "ExitSuccess({:?})", - console.captures(result).unwrap().get(0).unwrap().as_str() - ); - Ok(()) - } - ExitStatus::ExitFailure => { - log::info!( - "ExitFailure({:?})", - console.captures(result).unwrap().get(0).unwrap().as_str() - ); - Err(anyhow!("Matched exit_failure expression")) - } - } -} - -fn main() -> Result<()> { - let opts = Opts::parse(); - opts.init.init_logging(); - let transport = opts.init.init_target()?; - execute_test!(spi_device_console_test, &opts, &transport); - Ok(()) -} diff --git a/sw/host/tests/chip/spi_device_smoketest/BUILD b/sw/host/tests/chip/spi_device_smoketest/BUILD deleted file mode 100644 index 6ac94aece3ddc..0000000000000 --- a/sw/host/tests/chip/spi_device_smoketest/BUILD +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -load("@rules_rust//rust:defs.bzl", "rust_binary") - -package(default_visibility = ["//visibility:public"]) - -rust_binary( - name = "spi_device_smoketest", - srcs = [ - "src/main.rs", - ], - deps = [ - "//sw/host/opentitanlib", - "//third_party/rust/crates:anyhow", - "//third_party/rust/crates:clap", - "//third_party/rust/crates:humantime", - "//third_party/rust/crates:log", - "//third_party/rust/crates:regex", - "@crate_index//:object", - ], -) diff --git a/sw/host/tests/chip/spi_device_smoketest/src/main.rs b/sw/host/tests/chip/spi_device_smoketest/src/main.rs deleted file mode 100644 index 6b8cf26be5e8a..0000000000000 --- a/sw/host/tests/chip/spi_device_smoketest/src/main.rs +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -use anyhow::{bail, Result}; -use clap::Parser; -use regex::Regex; -use std::fs; -use std::path::PathBuf; -use std::time::Duration; - -use opentitanlib::app::TransportWrapper; -use opentitanlib::execute_test; -use opentitanlib::io::spi::Transfer; -use opentitanlib::test_utils; -use opentitanlib::test_utils::init::InitializeTest; -use opentitanlib::uart::console::{ExitStatus, UartConsole}; - -#[derive(Debug, Parser)] -struct Opts { - #[command(flatten)] - init: InitializeTest, - - /// Console receive timeout. - #[arg(long, value_parser = humantime::parse_duration, default_value = "600s")] - timeout: Duration, - - /// Name of the SPI interface to connect to the OTTF console. - #[arg(long, default_value = "BOOTSTRAP")] - spi: String, - - /// Path to the firmware's ELF file, for querying symbol addresses. - #[arg(value_name = "FIRMWARE_ELF")] - firmware_elf: PathBuf, -} - -fn device_tx_watermark_test( - opts: &Opts, - transport: &TransportWrapper, - tx_data: &[u8], - rx_data: &[u8], -) -> Result<()> { - let uart = transport.uart("console")?; - let spi = transport.spi(&opts.spi)?; - - /* Wait sync message. */ - let _ = UartConsole::wait_for(&*uart, r"SYNC: TX_FIFO READY\r\n", opts.timeout)?; - - let mut buf = vec![0u8; tx_data.len() - 1]; - // Due to the limitations of hyper310 (it does not support `Transfer::Both`) we first send one byte in order to - // read the device rx FIFO. - spi.run_transaction(&mut [Transfer::Write(&[tx_data[0]; 1]), Transfer::Read(&mut buf)])?; - // Due to the limitations above, the first rx byte is lost in the write operation, so we need - // to do this weird comparison. - assert_eq!(&buf, &rx_data[1..]); - Ok(()) -} - -fn device_rx_watermark_test( - opts: &Opts, - transport: &TransportWrapper, - tx_data: &[u8], -) -> Result<()> { - let uart = transport.uart("console")?; - let spi = transport.spi(&opts.spi)?; - - let _ = UartConsole::wait_for(&*uart, r"SYNC: RX_FIFO READY\r\n", opts.timeout)?; - spi.run_transaction(&mut [Transfer::Write(tx_data)]) -} - -fn device_tx_underflow_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> { - let uart = transport.uart("console")?; - let spi = transport.spi(&opts.spi)?; - /* Wait sync message. */ - let _ = UartConsole::wait_for(&*uart, r"SYNC: TX_FIFO UNDERFLOW READY\r\n", opts.timeout)?; - spi.run_transaction(&mut [Transfer::Write(&[0xAA; 2])]) -} - -fn device_rx_full_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> { - let uart = transport.uart("console")?; - let spi = transport.spi(&opts.spi)?; - /* Wait sync message. */ - let _ = UartConsole::wait_for(&*uart, r"SYNC: RX_FIFO FULL READY\r\n", opts.timeout)?; - spi.run_transaction(&mut [Transfer::Write(&[0xAB; 1024])]) -} - -fn device_rx_overflow_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> { - let uart = transport.uart("console")?; - let spi = transport.spi(&opts.spi)?; - /* Wait sync message. */ - let _ = UartConsole::wait_for(&*uart, r"SYNC: RX_FIFO OVERFLOW READY\r\n", opts.timeout)?; - spi.run_transaction(&mut [Transfer::Write(&[0xB5; 64])]) -} - -fn main() -> Result<()> { - let opts = Opts::parse(); - opts.init.init_logging(); - - /* Load the ELF binary and get the expect data.*/ - let elf_binary = fs::read(&opts.firmware_elf)?; - let object = object::File::parse(&*elf_binary)?; - - let spi_device_rx_data = test_utils::object::symbol_data(&object, "spi_device_tx_data")?; - let spi_device_tx_data = test_utils::object::symbol_data(&object, "exp_spi_device_rx_data")?; - - let transport = opts.init.init_target()?; - execute_test!( - device_tx_watermark_test, - &opts, - &transport, - &spi_device_tx_data, - &spi_device_rx_data - ); - - execute_test!( - device_rx_watermark_test, - &opts, - &transport, - &spi_device_tx_data - ); - - execute_test!(device_tx_underflow_test, &opts, &transport); - - execute_test!(device_rx_full_test, &opts, &transport); - - execute_test!(device_rx_overflow_test, &opts, &transport); - - let uart = transport.uart("console")?; - let mut console = UartConsole { - timeout: Some(opts.timeout), - exit_success: Some(Regex::new(r"PASS!\r\n")?), - exit_failure: Some(Regex::new(r"FAIL:")?), - ..Default::default() - }; - - // Now watch the console for the exit conditions. - let result = console.interact(&*uart, None, Some(&mut std::io::stdout()))?; - if result != ExitStatus::ExitSuccess { - bail!("FAIL: {:?}", result); - }; - - Ok(()) -}