// Copyright lowRISC contributors (OpenTitan project). // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 { name: “dma” import_testplans: [“hw/dv/tools/dvsim/testplans/csr_testplan.hjson”, “hw/dv/tools/dvsim/testplans/alert_test_testplan.hjson”, “hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson”, “hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson”] testpoints: [ //–––––––––––––––––––––––––––––––––– // Tests for DMA DUT ‘memory-to-memory’ and ‘hardware handshake’ modes //–––––––––––––––––––––––––––––––––– { name: dma_memory_smoke desc: ‘’’ Smoke test in which random DMA operations are performed with ‘memory-to-memory’ mode

          Stimulus:
            - Configure DMA
              * Randomize DMA memory region base and limit
              * Randomize source and destination address space IDs and address pointers such that all valid source and destination combinations are covered at least once
              * Randomize Total transfer width and transaction size
              * Update DMAC.op_code and disable hardware_handshake mode
            - Start DMA operation by setting DMAC.GO bit
            - Wait for TLUL transactions on the output interface
            - Respond with data from the TLUL agent in the testbench
            - Wait for the operation to complete
            - Repeat the operation randomly with different source and destination parameters

          Checking:
            - Check that the data presented at the source TLUL interface appears unchanged on the destination TLUL interface
            - Check for the assertion of PLIC interrupt if INTR_ENABLE.int_enable else check for DMAC.DONE after every iteration
            - Check for any spurious requests from the remaining TLUL interfaces
            - Check if the number of requests on TLUL agent matches the expected data size
            - Check if DMAC.busy bit is set throughout the operation in each iteration
          '''
    stage: V1
    tests: ["dma_memory_smoke"]
  }
  {
    name: dma_handshake_smoke
    desc: '''
          Smoke test in which 'hardware handshake' DMA operations are performed

          Stimulus:
            - Configure DMA
              * Randomize DMA memory region base and limit
              * Randomize source and destination address space IDs and address pointers such that all valid source and destination combinations are covered at least once
              * Randomize total transfer width and transaction sizes
              * Program DMAC.op_code and enable 'hardware handshake' mode
            - Start DMA operation by setting DMAC.GO bit
          - Assert Low Speed IO (LSIO) interrupt
          - Wait for TLUL transaction on the output interface
          - Respond with random number of data items from TLUL agent in the testbench
          - Deassert LSIO interrupt
          - Wait for the operation to complete
          - Repeat the copy operation with different source and destination parameters

          Checking:
          - Check if DMA operation is completed successfully
            * Check that the data presented at the source TLUL interface appears unchanged on the destination TLUL interface
            * Check for assertion of PLIC interrupt if INTR_ENABLE.int_enable else check for DMAC.DONE after every iteration
            * Check if the number of requests on TLUL agent matches the expected data size
          - Check if STATUS.busy bit is set until 'hardware handshake' mode is disabled
          - Check if STATUS.done is set after LSIO interrupt is deasserted
          '''
    stage: V1
    tests: ["dma_handshake_smoke"]
  }
  {
    name: dma_generic_smoke
    desc: '''
          Smoke test with both 'memory-to-memory' and 'hardware handshaking' transfers.

          Stimulus:
          - FW allocates DMA enabled Memory Space for the data movement
          - FW configures Source Address and ASID
          - FW configures Destination Address and ASID
          - FW completes other configuration such as:
              i)    Operation Size
              ii)   Opcode
          - FW triggers the DMA operation
          - FW either
              i)    Poll for completion
              ii)   Waits for Completion Interrupt
          - Reset memory contents at the end of iteration
          '''
    stage: V1
    tests: ["dma_generic_smoke"]
  }
  {
    name: dma_memory_region_lock
    desc:'''
          Test to check DMA memory region lock functionality

          Stimulus:
            - Configure DMA
              * Randomize DMA memory region base and limit
              * Randomize source and destination address space IDs and address pointers such that all valid source and destination combinations are covered at least once
              * Randomize Total transfer width and transaction size
              * Lock DMA memory configuration registers
              * Program DMAC register with OP code and randomize 'hardware handshake' mode enable bit
            - Start DMA operation by setting DMAC.GO bit
          - Randomly change the DMA memory region base and limit
          - Wait for the operation to complete
          - Reset the design by asserting rst_n
          - Repeat DMA operation without locking the DMA memory configuration registers

          Checking:
          - Check that DMA operation is completed successfully
            * Check for assertion of interrupt if INTR_ENABLE.int_enable else check for DMAC.DONE after every iteration
          - Check if writes to DMA memory region and base values are ignored until range_regwen.regwen is cleared
          - Check if the range_regwen.regwen is set to MuBi4True after deassertion of reset
          '''
    stage: V2
    tests: ["dma_memory_region_lock"]
  }
  {
    name: dma_memory_tl_error
    desc: '''
          Test to check TLUL error behavior on DMA interfaces

          Stimulus:
          - Configure DMA to perform a copy operation with different source and destination parameters in 'memory-to-memory' mode
          - Start DMA operation by setting DMAC.GO bit
          - Respond with an error on either source or destination TLUL interface request
          - Wait for PLIC interrupt assertion if INTR_ENABLE.int_enable is set else poll for DMAC.ABORTED bit

          Checking:
          - Check if STATUS.error bit is set (This indicates DMA operation is aborted)
          - Check that there are no TLUL transactions on source and destination interfaces after error response
          - Check if DMA generates an alert
          '''
    stage: V2
    tests: ["dma_memory_stress"]
  }
  {
    name: dma_handshake_tl_error
    desc: '''
          Test to check TLUL error behavior on DMA interfaces with 'hardware handshake' mode

          Stimulus:
          - Configure DMA to perform a copy operation with different source and destination parameters in hardware_handshake mode
          - Start DMA operation by setting DMAC.GO bit
          - Respond with an error on either source or destination TLUL interface request
          - Wait for PLIC interrupt assertion if INTR_ENABLE.int_enable is set else poll for DMAC.DONE bit

          Checking:
          - Check if STATUS.error bit is set (This indicates DMA operation is aborted)
          - Check that there are no TLUL transactions on source and destination interfaces after error response
          - Check if DMA generates an alert
          '''
    stage: V2
    tests: ["dma_handshake_stress"]
  }
  {
    name: dma_handshake_stress
    desc: '''
          Stress test in which hardware handshake DMA operations are performed. Goal is to achieve maximum possible coverage of DMA configuration space in 'hardware handshake' mode

          Stimulus:
            - Configure DMA
              * Randomize DMA memory region base and limit
              * Randomize source and destination address space IDs and address pointers
                such that all valid source and destination combinations are covered at least once
              * Randomize total transfer width and transaction size
              * Randomize DMAC.data_direction
              * Randomize DMAC.FIFO_addr_auto_increment_enable and DMAC.memory_addr_auto_increment_enable
              * Program DMAC register with OP code and enable 'hardware handshake' mode
            - Start DMA operation by setting DMAC.GO bit
          - Start DMA operation by setting DMAC.GO bit
          - Assert Low Speed IO (LSIO) interrupt
          - Wait for TLUL transaction on the output interface
          - Respond with random number of data items from TLUL agent in the testbench
          - Deassert LSIO interrupt
          - Wait for the operation to complete

          Checking:
          - Check if DMA operation is completed successfully in each iteration
            * Check if DMAC.GO bit is not set until the DMA operation is complete
            * Check if STATUS.busy bit is set until 'hardware handshake' mode is disabled
            * Check if STATUS.done is set after LSIO interrupt is deasserted
          '''
    stage: V2
    tests: ["dma_handshake_stress"]
  }
  {
    name: dma_memory_stress
    desc:'''
         Stress test in which random DMA operations are performed with 'memory-to-memory' mode. Goal is to achieve maximum possible coverage of DMA configuration space in 'memory-to-memory' mode

         Stimulus:
          - Configure DMA
            * Randomize DMA memory region base and limit
            * Randomize source and destination address space IDs and address pointers
            * Randomize Total transfer width and transaction size
            * Program DMAC register with OP code and disable 'hardware handshake' mode
          - Start DMA operation by setting DMAC.GO bit
          - Wait for the operation to complete
          - Repeat operation with different source and destination addresses

         Checking:
          - Check that DMA operation is completed successfully
            * Check that the number of TLUL requests matches the expected data size
            * Check that the data presented at the source TLUL interface appears unchanged on the destination TLUL interface
            * Check if STATUS.busy bit is set until the copy operation is complete
            * Check if STATUS.done bit is set after the copy operation
         '''
    stage: V2
    tests: ["dma_memory_stress"]
  }
  {
    name: dma_generic_stress
    desc: '''
          Stress test which combines `dma_memory_stress` and `dma_handshake_stress` to ensure that both 'memory-to-memory' and 'hardware handshaking' modes are exercised together without intervening resets.
          '''
    stage: V2
    tests: ["dma_generic_stress"]
  }
  {
    name: dma_handshake_mem_buffer_overflow
    desc: '''
          Test to check DMA memory buffer threshold and limit behavior with 'hardware handshake' mode

          Stimulus:
          - Configure DMA for 'hardware handshake' mode
          - Set memory_buffer_addr_auto_increment
          - Start DMA operation by setting DMAC.GO bit
          - Assert Low Speed IO (LSIO) interrupt
          - Wait for TLUL transaction on the output interface
          - Deassert LSIO interrupt
          - Wait for the operation to complete
          - Repeat the operation with different source and destination parameters

          Checking:
          - Check if DMA operation is completed successfully in each iteration
            * Check if DMAC.GO bit is set until the DMA operation is complete
            * Check if STATUS.busy bit is set until 'hardware handshake' mode is disabled
            * Check if STATUS.done is set after LSIO interrupt is deasserted
          - Check if PLIC interrupt is asserted when memory_buffer_auto_increment is enabled
          '''
    stage: V2
    tests: ["dma_handshake_stress"]
  }
  {
    name: dma_abort
    desc: '''
          Test to check DMAC.abort functionality

          Stimulus:
          - Configure DMA to perform a copy operation randomly with different source and destination parameters
          - Randomly enable hardware_handshake mode
          - Start DMA operation
          - Abort DMA operation before completion by setting DMAC.abort
          - Wait for PLIC interrupt assertion if INTR_ENABLE.int_enable is set else poll for DMAC.DONE bit
          - Repeat operation with different source and destination parameters

          Checking:
          - Check if STATUS.aborted bit is set (This indicates DMA operation is aborted)
          - Check if there all outstanding transactions on OT internal TLUL interface are complete
          '''
    stage: V2
    tests: ["dma_abort"]
  }
  {
    name: dma_stress_all
    desc: '''
          Run the other tests in random order while injecting TL errors and running automated CSR tests in parallel.
          '''
    stage: V2
    tests: ["dma_stress_all"]
  }
  {
    name: dma_illegal_addr_range
    desc: '''
          Test to check DMA hardware enforced security check for illegal source or destination address

          Stimulus:
          - Configure DMA
            * Update DMA memory region base and limit
            * Update Source and Destination address pointers and address space IDs such that the address source or destination address is outside the DMA memory region
          - Configure DMA with total transfer width and transaction size
          - Enable 'hardware handshake' mode and direction randomly
          - Start DMA operation
          - Wait for interrupt assertion if INTR_ENABLE.int_enable is set else poll for STATUS.abort bit

          Checking:
          - Check if STATUS.aborted bit is set (This indicates DMA operation is aborted)
          - Check if DMA generates an alert
          '''
    stage: V2S
    tests: ["dma_generic_stress", "dma_handshake_stress", "dma_mem_enabled"]
  }
  {
    name: dma_config_lock
    desc: '''
          Attempt to change the configuration registers whilst the DMA controller is active.
          The majority of the configuration registers are protected using the `CFG_REGWEN` write enable register.
          Since the enable is controlled exclusively by the hardware itself, the standard CSR tests are unable to test that it operates correctly.

          Stimulus:
          - Configure and start the DUT performing a long transfer.
          - Choose one or more random configuration registers that should be protected by `CFG_REGWEN`.
          - Whilst the DUT is still operating, attempt to invert the contents of the protected registers.

          Checking:
          - Check the value of the `CFG_REGWEN` register before and after starting the DMA transfer.
          - Check that the contents of the chosen configuration registers do not change.
          - Check the value of the `CFG_REGWEN` register after the transfer has completed.
          '''
    stage: V2S
    tests: ["dma_config_lock"]
  }
]
covergroups: [
  {
    name: dma_config_cg
    desc: '''
           - Cover the following configuration registers when starting a transfer (i.e., when writing the `go` bit of the `CONTROL` register):
             * Source and destination address
             * Source and destination address space ID (ASID)
             * DMA-enabled memory range base and limit
             * Total data size
             * Chunk data size
             * Transfer width
             * Control register fields:
               + opcode
               + hardware handshake enable
               + memory buffer auto increment enable
               + FIFO auto increment enable
               + data direction
               + initial transfer
               + *exclude the `go` bit because it's used to sample this CG*
               + *exclude the `abort` bit because when aborting the internal state of the DMA is much more relevant than the values in the configuration registers*
           - Cross coverage:
             * source address and source ASID
             * destination address and destination ASID
             * opcode, source and destination ASIDs, hardware handshake enable, and data direction
             * opcode, chunk data size, source and destination ASIDs, and data direction
             * opcode, total data size, transfer width, and data direction
             * opcode, hardware handshake enable, chunk data size, transfer width, and data direction
             * opcode, hardware handshake enable, memory buffer auto increment enable, FIFO auto increment enable, and data direction
             * opcode, hardware handshake enable, data direction, and initial transfer
             * source and destination address, DMA-enabled memory range base and limit, and data direction
             * source and destination address alignment, total data size alignment, and transfer width
             * memory buffer auto increment enable, data direction, and the results of (destination address + total data size)
           '''
  }
  {
    name: dma_tlul_error_cg
    desc: '''
          Cover TL-UL error responses differentiated between TL-UL ports and cross them with the following configuration values:
          - source and destination ASID and data direction
          '''
  }
  {
    name: dma_status_cg
    desc: '''
          Cover all fields of the status register.
          '''
  }
  {
    name: dma_error_code_cg
    desc: '''
          Cover all fields of the error code register.
          '''
  }
  {
    name: dma_interrupt_cg
    desc: '''
          - Cover the following configuration registers when starting a transfer (i.e., when writing the `go` bit of the `CONTROL` register):
            * handshake interrupt enable
            * interrupt source clearing enablement
            * interrupt source clearing bus selection
          - Cross coverage:
            * handshake interrupt enable, interrupt source clearing enablement, and interrupt source clearing bus selection
          '''
  }
  {
    name: dma_intr_src_cg
    desc: '''
          - Cover the interrupt-clearing address and write values, as observed on the TL-UL buses rather than in the configuration that was chosen:
            * interrupt source clearing address alignment; required bins:
              + bits [3:2] - all four permutations.
            * interrupt source clearing write values; required bins:
              + all zeros
              + not all zeros
          - Cross coverage:
            * handshake interrupt enable, interrupt source clearing enablement, and interrupt source clearing address alignment
            * handshake interrupt enable, interrupt source clearing enablement, and interrupt source clearing write values
          '''
  }
]

}