|  | // Copyright lowRISC contributors. | 
|  | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | // SPDX-License-Identifier: Apache-2.0 | 
|  | { | 
|  | name:               "spi_host", | 
|  | human_name:         "SPI Host", | 
|  | one_line_desc:      "Serial peripheral interface for host mode, suitable for interfacing external serial NOR flash devices", | 
|  | one_paragraph_desc: ''' | 
|  | SPI Host bridges communications from the TileLink Uncached Light (TL-UL) bus and off-chip devices by acting as a SPI interface bus master, primarily intended for communication with serial NOR flash devices and other low-speed devices. | 
|  | While SPI is not a formal standard, this implementation aims to be general enough to support a variety of devices by providing a plethora of run-time configurable options. | 
|  | Communication with each device on the bus uses an independent chip select (CS), and each transaction may be individually configured regarding endianness, polarity and phase (CPOL/ CPHA), and full-duplex/half-duplex commands in standard mode. | 
|  | 32-bit TL-UL registers interface with receive and transmit data FIFOs as well as a command FIFO for encoding multiple sequential 'segments' making up a larger SPI transaction. | 
|  | This allows each segment to have an arbitrary byte-count, Std/Dual/Quad width, and direction, and it allows the CS to be managed automatically across multiple sequential segments. | 
|  | ''' | 
|  | design_spec:        "../doc", | 
|  | dv_doc:             "../doc/dv", | 
|  | hw_checklist:       "../doc/checklist", | 
|  | sw_checklist:       "/sw/device/lib/dif/dif_spi_host", | 
|  | revisions: [ | 
|  | { | 
|  | version:            "1.0", | 
|  | life_stage:         "L1", | 
|  | design_stage:       "D2S", | 
|  | verification_stage: "V2S", | 
|  | dif_stage:          "S2", | 
|  | } | 
|  | ] | 
|  | clocking: [ | 
|  | {clock: "clk_i", reset: "rst_ni", primary: true}, | 
|  | ] | 
|  | bus_interfaces: [ | 
|  | { protocol: "tlul", direction: "device" } | 
|  | ], | 
|  | inter_signal_list: [ | 
|  | { struct:  "passthrough", | 
|  | package: "spi_device_pkg", | 
|  | type:    "req_rsp", | 
|  | name:    "passthrough", | 
|  | act:     "rsp", | 
|  | width:   "1" | 
|  | } | 
|  | ] | 
|  | regwidth: "32", | 
|  | param_list: [ | 
|  | { name: "ByteOrder", | 
|  | desc: '''Byte order to use when transmitting or receiving data.  If ByteOrder = 0, | 
|  | the IP uses a Big-Endian ordering for the bytes in DATA. | 
|  | The most significant byte (MSB) of DATA is transmitted first, and | 
|  | received data is placed in the MSB location of DATA.  If ByteOrder = 1, | 
|  | a Little-Endian ordering is used for these registers, and the LSB of each | 
|  | gets priority for receiving and transmitting data.''' | 
|  | type: "logic", | 
|  | default: "1" | 
|  | }, | 
|  | { name: "NumCS", | 
|  | desc: "The number of active-low chip select (cs_n) lines to create.", | 
|  | type: "int", | 
|  | default: "1" | 
|  | }, | 
|  | { name: "TxDepth", | 
|  | desc: "The size of the Tx FIFO (in words)", | 
|  | type: "int", | 
|  | default: "72" | 
|  | }, | 
|  | { name: "RxDepth", | 
|  | desc: "The size of the Rx FIFO (in words)", | 
|  | type: "int", | 
|  | default: "64" | 
|  | }, | 
|  | { name: "CmdDepth", | 
|  | desc: "The size of the Cmd FIFO (one segment descriptor per entry)", | 
|  | type: "int", | 
|  | default: "4" | 
|  | } | 
|  | ], | 
|  | available_output_list: [ | 
|  | { name:  "sck" | 
|  | desc:  "SPI Clock" | 
|  | }, | 
|  | { name:  "csb" | 
|  | desc:  '''Chip Select# (One hot, active low).  The size of this port should match NumCS.''' | 
|  | width: "1" | 
|  | } | 
|  | ], | 
|  | available_inout_list: [ | 
|  | { name:  "sd", | 
|  | desc:  "SPI data bus", | 
|  | width: "4" | 
|  | }, | 
|  | ], | 
|  | interrupt_list: [ | 
|  | { name: "error", | 
|  | desc: '''Error-related interrupts, see !!ERROR_ENABLE register for more | 
|  | information.''' | 
|  | }, | 
|  | { name: "spi_event", | 
|  | desc: '''Event-related interrupts, see !!EVENT_ENABLE register for more | 
|  | information.''' | 
|  | } | 
|  | ], | 
|  | alert_list: [ | 
|  | { name: "fatal_fault", | 
|  | desc: ''' | 
|  | This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected. | 
|  | ''' | 
|  | } | 
|  | ], | 
|  | countermeasures: [ | 
|  | { name: "BUS.INTEGRITY", | 
|  | desc: "End-to-end bus integrity scheme." | 
|  | } | 
|  | ] | 
|  | registers: [ | 
|  | { name: "CONTROL", | 
|  | desc: "Control register", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | fields: [ | 
|  | { bits: "31", | 
|  | name: "SPIEN", | 
|  | desc: '''Enables the SPI host.  On reset, this field is 0, meaning | 
|  | that no transactions can proceed.''' | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "30", | 
|  | name: "SW_RST", | 
|  | desc: '''Clears the entire IP to the reset state when set to 1, including | 
|  | the FIFOs, the CDC's, the core state machine and the shift register. | 
|  | In the current implementation, the CDC FIFOs are drained not reset. | 
|  | Therefore software must confirm that both FIFO's empty before releasing | 
|  | the IP from reset.''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "29", | 
|  | name: "OUTPUT_EN", | 
|  | desc: '''Enable the SPI host output buffers for the sck, csb, and sd lines.  This allows | 
|  | the SPI_HOST IP to connect to the same bus as other SPI controllers without | 
|  | interference.''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "15:8", | 
|  | name: "TX_WATERMARK" | 
|  | desc: '''If !!EVENT_ENABLE.TXWM is set, the IP will send | 
|  | an interrupt when the depth of the TX FIFO drops below | 
|  | TX_WATERMARK words (32b each).''' | 
|  | resval: "0" | 
|  | }, | 
|  | { bits: "7:0", | 
|  | name: "RX_WATERMARK" | 
|  | desc: '''If !!EVENT_ENABLE.RXWM is set, the IP will send | 
|  | an interrupt when the depth of the RX FIFO reaches | 
|  | RX_WATERMARK words (32b each).''' | 
|  | resval: "127" | 
|  | }, | 
|  | ] | 
|  | }, | 
|  | { name: "STATUS", | 
|  | desc: "Status register", | 
|  | swaccess: "ro", | 
|  | hwaccess: "hwo", | 
|  | fields: [ | 
|  | { bits: "31", | 
|  | name: "READY", | 
|  | desc: '''When high, indicates the SPI host is ready to receive | 
|  | commands. Writing to COMMAND when READY is low is | 
|  | an error, and will trigger an interrupt. | 
|  | ''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "30", | 
|  | name: "ACTIVE", | 
|  | desc: '''When high, indicates the SPI host is processing a previously | 
|  | issued command.''' | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "29", | 
|  | name: "TXFULL", | 
|  | desc: '''When high, indicates that the transmit data fifo is full. | 
|  | Any further writes to !!RXDATA will create an error interrupt. | 
|  | ''' | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "28", | 
|  | name: "TXEMPTY", | 
|  | desc: '''When high, indicates that the transmit data fifo is empty. | 
|  | ''' | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "27" | 
|  | name: "TXSTALL", | 
|  | desc: '''If high, signifies that an ongoing transaction has stalled | 
|  | due to lack of data in the TX FIFO''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "26", | 
|  | name: "TXWM", | 
|  | desc: '''If high, the amount of data in the TX FIFO has fallen below the | 
|  | level of !!CONTROL.TX_WATERMARK words (32b each).''' | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "25", | 
|  | name: "RXFULL", | 
|  | desc: '''When high, indicates that the receive fifo is full.  Any | 
|  | ongoing transactions will stall until firmware reads some | 
|  | data from !!RXDATA.''' | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "24", | 
|  | name: "RXEMPTY", | 
|  | desc: '''When high, indicates that the receive fifo is empty. | 
|  | Any reads from RX FIFO will cause an error interrupt. | 
|  | ''' | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "23", | 
|  | name: "RXSTALL", | 
|  | desc: '''If high, signifies that an ongoing transaction has stalled | 
|  | due to lack of available space in the RX FIFO''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "22", | 
|  | name: "BYTEORDER", | 
|  | desc: '''The value of the ByteOrder parameter, provided so that firmware | 
|  | can confirm proper IP configuration.''' | 
|  | } | 
|  | { bits: "20", | 
|  | name: "RXWM", | 
|  | desc: '''If high, the number of 32-bits in the RX FIFO now exceeds the | 
|  | !!CONTROL.RX_WATERMARK entries (32b each).''' | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "19:16", | 
|  | name: "CMDQD", | 
|  | desc: '''Command queue depth. Indicates how many unread 32-bit words are | 
|  | currently in the command segment queue.''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "15:8", | 
|  | name: "RXQD", | 
|  | desc: '''Receive queue depth. Indicates how many unread 32-bit words are | 
|  | currently in the RX FIFO.  When active, this result may an | 
|  | underestimate due to synchronization delays.''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "7:0", | 
|  | name: "TXQD", | 
|  | desc: '''Transmit queue depth. Indicates how many unsent 32-bit words | 
|  | are currently in the TX FIFO.  When active, this result may | 
|  | be an overestimate due to synchronization delays, | 
|  | ''', | 
|  | resval: "0x0" | 
|  | } | 
|  | ] | 
|  | tags: [// Updated by the hw. Exclude from init and write-checks. | 
|  | "excl:CsrAllTests:CsrExclCheck"] | 
|  |  | 
|  | }, | 
|  | { multireg: { name: "CONFIGOPTS", | 
|  | desc: '''Configuration options register. | 
|  |  | 
|  | Contains options for controlling each peripheral. One register per | 
|  | cs_n line''', | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | cname: "configopts", | 
|  | count: "NumCS", | 
|  | fields: [ | 
|  | { bits: "31", | 
|  | name: "CPOL", | 
|  | desc: '''The polarity of the sck clock signal.  When CPOL is 0, | 
|  | sck is low when idle, and emits high pulses.   When CPOL | 
|  | is 1, sck is high when idle, and emits a series of low | 
|  | pulses. | 
|  | ''' | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "30", | 
|  | name: "CPHA", | 
|  | desc: '''The phase of the sck clock signal relative to the data. When | 
|  | CPHA = 0, the data changes on the trailing edge of sck | 
|  | and is typically sampled on the leading edge.  Conversely | 
|  | if CPHA = 1 high, data lines change on the leading edge of | 
|  | sck and are typically sampled on the trailing edge. | 
|  | CPHA should be chosen to match the phase of the selected | 
|  | device.  The sampling behavior is modified by the | 
|  | !!CONFIGOPTS.FULLCYC bit. | 
|  | ''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "29", | 
|  | name: "FULLCYC", | 
|  | desc: '''Full cycle.  Modifies the CPHA sampling behaviour to allow | 
|  | for longer device logic setup times.  Rather than sampling the SD | 
|  | bus a half cycle after shifting out data, the data is sampled | 
|  | a full cycle after shifting data out.  This means that if | 
|  | CPHA = 0, data is shifted out on the trailing edge, and | 
|  | sampled a full cycle later.  If CPHA = 1, data is shifted and | 
|  | sampled with the trailing edge, also separated by a | 
|  | full cycle.''', | 
|  | resval: 0 | 
|  | }, | 
|  | { bits: "27:24", | 
|  | name: "CSNLEAD", | 
|  | desc: '''CS_N Leading Time.  Indicates the number of half sck cycles, | 
|  | CSNLEAD+1, to leave between the falling edge of cs_n and | 
|  | the first edge of sck.  Setting this register to zero | 
|  | corresponds to the minimum delay of one-half sck cycle''' | 
|  | resval: 0 | 
|  | }, | 
|  | { bits: "23:20", | 
|  | name: "CSNTRAIL" | 
|  | desc: '''CS_N Trailing Time.  Indicates the number of half sck cycles, | 
|  | CSNTRAIL+1, to leave between last edge of sck and the rising | 
|  | edge of cs_n. Setting this register to zero corresponds | 
|  | to the minimum delay of one-half sck cycle.''' | 
|  | resval: 0 | 
|  | }, | 
|  | { bits: "19:16", | 
|  | name: "CSNIDLE" | 
|  | desc: '''Minimum idle time between commands. Indicates the minimum | 
|  | number of sck half-cycles to hold cs_n high between commands. | 
|  | Setting this register to zero creates a minimally-wide CS_N-high | 
|  | pulse of one-half sck cycle.''' | 
|  | resval: 0 | 
|  | }, | 
|  | { bits: "15:0", | 
|  | name: "CLKDIV", | 
|  | desc: '''Core clock divider.  Slows down subsequent SPI transactions by a | 
|  | factor of (CLKDIV+1) relative to the core clock frequency.  The | 
|  | period of sck, T(sck) then becomes `2*(CLK_DIV+1)*T(core)`''' | 
|  | resval: 0 | 
|  | }, | 
|  | ] | 
|  | } | 
|  | }, | 
|  | { name: "CSID", | 
|  | desc: '''Chip-Select ID | 
|  |  | 
|  | Controls which device to target with the next command.  This register | 
|  | is passed to the core whenever !!COMMAND is written.  The core then | 
|  | asserts cio_csb_o[!!CSID] during the execution of the command.''', | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | fields: [ | 
|  | { bits: "31:0", | 
|  | name: "CSID", | 
|  | desc: "Chip Select ID", | 
|  | resval: "0x0" | 
|  | } | 
|  | ] | 
|  | }, | 
|  | { name: "COMMAND", | 
|  | desc: '''Command Register | 
|  |  | 
|  | Parameters specific to each command segment.  Unlike the !!CONFIGOPTS multi-register, | 
|  | there is only one command register for controlling all attached SPI devices''', | 
|  | swaccess: "wo", | 
|  | hwaccess: "hro", | 
|  | hwext: "true", | 
|  | hwqe: "true", | 
|  | fields: [ | 
|  | { bits: "13:12", | 
|  | name: "DIRECTION", | 
|  | desc: '''The direction for the following command: "0" = Dummy cycles | 
|  | (no TX/RX). "1" = Rx only, "2" = Tx only, "3" = Bidirectional | 
|  | Tx/Rx (Standard SPI mode only).''' | 
|  | resval: "0x0" | 
|  | } | 
|  | { bits: "11:10", | 
|  | name: "SPEED", | 
|  | desc: '''The speed for this command segment: "0" = Standard SPI. "1" = Dual SPI. | 
|  | "2"=Quad SPI,  "3": RESERVED.''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "9", | 
|  | name: "CSAAT", | 
|  | desc: '''Chip select active after transaction.  If CSAAT = 0, the | 
|  | chip select line is raised immediately at the end of the | 
|  | command segment.   If !!COMMAND.CSAAT = 1, the chip select | 
|  | line is left low at the end of the current transaction | 
|  | segment.  This allows the creation longer, more | 
|  | complete SPI transactions, consisting of several separate | 
|  | segments for issuing instructions, pausing for dummy cycles, | 
|  | and transmitting or receiving data from the device.''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "8:0", | 
|  | name: "LEN", | 
|  | desc: '''Segment Length. | 
|  |  | 
|  | For read or write segments, this field controls the | 
|  | number of 1-byte bursts to transmit and or receive in | 
|  | this command segment.  The number of cyles required | 
|  | to send or received a byte will depend on !!COMMAND.SPEED. | 
|  | For dummy segments, (!!COMMAND.DIRECTION == 0), this register | 
|  | controls the number of dummy cycles to issue. | 
|  | The number of bytes (or dummy cycles) in the segment will be | 
|  | equal to !!COMMAND.LEN + 1. | 
|  | ''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | ], | 
|  | tags: [// Triggers exceptions if registers are improperly configured | 
|  | // Exclude from RW tests | 
|  | "excl:CsrAllTests:CsrExclWrite"] | 
|  | }, | 
|  | { window: { | 
|  | name: "RXDATA", | 
|  | items: "1", | 
|  | validbits: "32", | 
|  | desc: '''SPI Receive Data. | 
|  |  | 
|  | Reads from this window pull data from the RXFIFO. | 
|  |  | 
|  | The serial order of bit transmission | 
|  | is chosen to match SPI flash devices. Individual bytes | 
|  | are always transmitted with the most significant bit first. | 
|  | Only four-bute reads are supported. If ByteOrder = 0, | 
|  | the first byte received is packed in the MSB of !!RXDATA. | 
|  | For some processor architectures, this could lead to shuffling | 
|  | of flash data as compared to how it is written in memory. | 
|  | In which case, choosing ByteOrder = 1 can reverse the | 
|  | byte-order of each data read, causing the first byte | 
|  | received to be packed into the LSB of !!RXDATA. (Though within | 
|  | each byte the most significant bit is always pulled | 
|  | from the bus first.) | 
|  | ''' | 
|  | swaccess: "ro", | 
|  | } | 
|  | }, | 
|  | { window: { | 
|  | name: "TXDATA", | 
|  | items: "1", | 
|  | validbits: "32", | 
|  | byte-write: "true", | 
|  | desc: '''SPI Transmit Data. | 
|  |  | 
|  | Data written to this window is placed into the TXFIFO. | 
|  | Byte-enables are supported for writes. | 
|  |  | 
|  | The serial order of bit transmission | 
|  | is chosen to match SPI flash devices. Individual bytes | 
|  | are always transmitted with the most significant bit first. | 
|  | Multi-byte writes are also supported, and if ByteOrder = 0, | 
|  | the bits of !!TXDATA are transmitted strictly in order of | 
|  | decreasing signficance (i.e. most signicant bit first). | 
|  | For some processor architectures, this could lead to shuffling | 
|  | of flash data as compared to how it is written in memory. | 
|  | In which case, choosing ByteOrder = 1 can reverse the | 
|  | byte-order of multi-byte data writes.  (Though within | 
|  | each byte the most significant bit is always sent first.) | 
|  | ''' | 
|  | swaccess: "wo", | 
|  | unusual: "false" | 
|  | } | 
|  | }, | 
|  | { name: "ERROR_ENABLE", | 
|  | desc: "Controls which classes of errors raise an interrupt." | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | fields: [ | 
|  | # Bit 5 (Access Invalid) always triggers an error, so bit 5 is reserved. | 
|  | { bits: "4", | 
|  | name: "CSIDINVAL", | 
|  | desc: '''Invalid CSID: If this bit is set, the block sends an error interrupt whenever | 
|  | a command is submitted, but CSID exceeds NumCS.''', | 
|  | resval: "0x1" | 
|  | } | 
|  | { bits: "3", | 
|  | name: "CMDINVAL", | 
|  | desc: '''Invalid Command Errors: If this bit is set, the block sends an | 
|  | error interrupt whenever a command is sent with invalid values for | 
|  | !!COMMAND.SPEED or !!COMMAND.DIRECTION.''', | 
|  | resval: "0x1" | 
|  | }, | 
|  | { bits: "2", | 
|  | name: "UNDERFLOW", | 
|  | desc: '''Underflow Errors: If this bit is set, the block sends an | 
|  | error interrupt whenever there is a read from !!RXDATA | 
|  | but the RX FIFO is empty.''' | 
|  | resval: "0x1" | 
|  | }, | 
|  | { bits: "1", | 
|  | name: "OVERFLOW", | 
|  | desc: '''Overflow Errors: If this bit is set, the block sends an | 
|  | error interrupt whenever the TX FIFO overflows.''' | 
|  | resval: "0x1" | 
|  | }, | 
|  | { bits: "0", | 
|  | name: "CMDBUSY", | 
|  | desc: '''Command Error: If this bit is set, the block sends an error | 
|  | interrupt whenever a command is issued while busy (i.e. a 1 is | 
|  | when !!STATUS.READY is not asserted.)''', | 
|  | resval: "0x1" | 
|  | }, | 
|  | ] | 
|  | }, | 
|  | { name: "ERROR_STATUS", | 
|  | desc: '''Indicates that any errors that have occurred. | 
|  | When an error | 
|  | occurs, the corresponding bit must be cleared here before | 
|  | issuing any further commands.''' | 
|  | swaccess: "rw1c", | 
|  | hwaccess: "hrw", | 
|  | fields: [ | 
|  | { bits: "5", | 
|  | name: "ACCESSINVAL", | 
|  | desc: '''Indicates that TLUL attempted to write to TXDATA with no bytes enabled. Such | 
|  | 'zero byte' writes are not supported.''', | 
|  | resval: "0x0" | 
|  | tags: [// Updated by the hw. Exclude from init and write-checks. | 
|  | "excl:CsrAllTests:CsrExclCheck"] | 
|  | }, | 
|  | { bits: "4", | 
|  | name: "CSIDINVAL", | 
|  | desc: '''Indicates a command was attempted with an invalid value for !!CSID.''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "3", | 
|  | name: "CMDINVAL", | 
|  | desc: '''Indicates an invalid command segment, meaning either an invalid value of | 
|  | !!COMMAND.SPEED or a request for bidirectional data transfer at dual or quad | 
|  | speed''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "2", | 
|  | name: "UNDERFLOW", | 
|  | desc: '''Indicates that firmware has attempted to read from | 
|  | !!RXDATA when the RX FIFO is empty.''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "1", | 
|  | name: "OVERFLOW", | 
|  | desc: '''Indicates that firmware has overflowed the TX FIFO''' | 
|  | resval: "0x0" | 
|  | tags: [// Updated by the hw. Exclude from init and write-checks. | 
|  | "excl:CsrAllTests:CsrExclCheck"] | 
|  | }, | 
|  | { bits: "0", | 
|  | name: "CMDBUSY", | 
|  | desc: '''Indicates a write to !!COMMAND when !!STATUS.READY = 0. | 
|  | ''' | 
|  | resval: "0x0" | 
|  | }, | 
|  | ] | 
|  | }, | 
|  | { name: "EVENT_ENABLE", | 
|  | desc: "Controls which classes of SPI events raise an interrupt.", | 
|  | swaccess: "rw", | 
|  | hwaccess: "hro", | 
|  | fields: [ | 
|  | { bits: "5", | 
|  | name: "IDLE", | 
|  | desc: '''Assert to send a spi_event interrupt whenever !!STATUS.ACTIVE | 
|  | goes low''', | 
|  | resval: "0x0" | 
|  | } | 
|  | { bits: "4", | 
|  | name: "READY", | 
|  | desc: '''Assert to send a spi_event interrupt whenever !!STATUS.READY | 
|  | goes high''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "3", | 
|  | name: "TXWM", | 
|  | desc: '''Assert to send a spi_event interrupt whenever the number of 32-bit words in | 
|  | the TX FIFO is less than !!CONTROL.TX_WATERMARK.  To prevent the | 
|  | reassertion of this interrupt add more data to the TX FIFO, or | 
|  | reduce !!CONTROL.TX_WATERMARK.''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "2", | 
|  | name: "RXWM", | 
|  | desc: '''Assert to send a spi_event interrupt whenever the number of 32-bit words in | 
|  | the RX FIFO is greater than !!CONTROL.RX_WATERMARK. To prevent the | 
|  | reassertion of this interrupt, read more data from the RX FIFO, or | 
|  | increase !!CONTROL.RX_WATERMARK.''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "1", | 
|  | name: "TXEMPTY", | 
|  | desc: '''Assert to send a spi_event interrupt whenever !!STATUS.TXEMPTY | 
|  | goes high''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | { bits: "0", | 
|  | name: "RXFULL", | 
|  | desc: '''Assert to send a spi_event interrupt whenever !!STATUS.RXFULL | 
|  | goes high''', | 
|  | resval: "0x0" | 
|  | }, | 
|  | ] | 
|  | } | 
|  | ] | 
|  | } |