Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—el2_dma_ctrl.sv Coverage Hit Total
Test Date: 14-11-2024 Toggle 90.7% 146 161
Test: all Branch 100.0% 4 4

            Line data    Source code
       1              : // SPDX-License-Identifier: Apache-2.0
       2              : // Copyright 2020 Western Digital Corporation or its affiliates.
       3              : //
       4              : // Licensed under the Apache License, Version 2.0 (the "License");
       5              : // you may not use this file except in compliance with the License.
       6              : // You may obtain a copy of the License at
       7              : //
       8              : // http://www.apache.org/licenses/LICENSE-2.0
       9              : //
      10              : // Unless required by applicable law or agreed to in writing, software
      11              : // distributed under the License is distributed on an "AS IS" BASIS,
      12              : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13              : // See the License for the specific language governing permissions and
      14              : // limitations under the License.
      15              : 
      16              : //********************************************************************************
      17              : // $Id$
      18              : //
      19              : // Function: Top level VeeR core file
      20              : // Comments:
      21              : //
      22              : //********************************************************************************
      23              : 
      24              : module el2_dma_ctrl 
      25              : import el2_pkg::*;
      26              : #(
      27              : `include "el2_param.vh"
      28              :  )(
      29     69904239 :    input logic         clk,
      30     69904239 :    input logic         free_clk,
      31          362 :    input logic         rst_l,
      32          346 :    input logic         dma_bus_clk_en, // slave bus clock enable
      33            2 :    input logic         clk_override,
      34              :    // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
      35              :    /*verilator coverage_off*/
      36              :    input logic         scan_mode,
      37              :    /*verilator coverage_on*/
      38              : 
      39              :    // Debug signals
      40           53 :    input logic [31:0]  dbg_cmd_addr,
      41          275 :    input logic [31:0]  dbg_cmd_wrdata,
      42         3856 :    input logic         dbg_cmd_valid,
      43          325 :    input logic         dbg_cmd_write, // 1: write command, 0: read_command
      44         1466 :    input logic [1:0]   dbg_cmd_type, // 0:gpr 1:csr 2: memory
      45         1165 :    input logic [1:0]   dbg_cmd_size, // size of the abstract mem access debug command
      46              : 
      47         3682 :    input  logic        dbg_dma_bubble,   // Debug needs a bubble to send a valid
      48         4600 :    output logic        dma_dbg_ready,    // DMA is ready to accept debug request
      49              : 
      50         1404 :    output logic        dma_dbg_cmd_done,
      51          204 :    output logic        dma_dbg_cmd_fail,
      52         1225 :    output logic [31:0] dma_dbg_rddata,
      53              : 
      54              :    // Core side signals
      55         1292 :    output logic        dma_dccm_req,  // DMA dccm request (only one of dccm/iccm will be set)
      56         1380 :    output logic        dma_iccm_req,  // DMA iccm request
      57          611 :    output logic [2:0]  dma_mem_tag,   // DMA Buffer entry number
      58          291 :    output logic [31:0] dma_mem_addr,  // DMA request address
      59           64 :    output logic [2:0]  dma_mem_sz,    // DMA request size
      60          276 :    output logic        dma_mem_write, // DMA write to dccm/iccm
      61          909 :    output logic [63:0] dma_mem_wdata, // DMA write data
      62              : 
      63          684 :    input logic         dccm_dma_rvalid,    // dccm data valid for DMA read
      64           31 :    input logic         dccm_dma_ecc_error, // ECC error on DMA read
      65          159 :    input logic [2:0]   dccm_dma_rtag,      // Tag of the DMA req
      66        39694 :    input logic [63:0]  dccm_dma_rdata,     // dccm data for DMA read
      67          716 :    input logic         iccm_dma_rvalid,    // iccm data valid for DMA read
      68           30 :    input logic         iccm_dma_ecc_error, // ECC error on DMA read
      69          140 :    input logic [2:0]   iccm_dma_rtag,      // Tag of the DMA req
      70          146 :    input logic [63:0]  iccm_dma_rdata,     // iccm data for DMA read
      71              : 
      72         2513 :    output logic        dma_active,         // DMA is busy
      73         1240 :    output logic        dma_dccm_stall_any, // stall dccm pipe (bubble) so that DMA can proceed
      74         1298 :    output logic        dma_iccm_stall_any, // stall iccm pipe (bubble) so that DMA can proceed
      75      2234183 :    input logic         dccm_ready, // dccm ready to accept DMA request
      76       639193 :    input logic         iccm_ready, // iccm ready to accept DMA request
      77          345 :    input logic [2:0]   dec_tlu_dma_qos_prty,    // DMA QoS priority coming from MFDC [18:15]
      78              : 
      79              :    // PMU signals
      80          710 :    output logic        dma_pmu_dccm_read,
      81          582 :    output logic        dma_pmu_dccm_write,
      82         1450 :    output logic        dma_pmu_any_read,
      83         1206 :    output logic        dma_pmu_any_write,
      84              : 
      85              :    // AXI Write Channels
      86          760 :    input  logic                        dma_axi_awvalid,
      87         1040 :    output logic                        dma_axi_awready,
      88          327 :    input  logic [pt.DMA_BUS_TAG-1:0]   dma_axi_awid,
      89          410 :    input  logic [31:0]                 dma_axi_awaddr,
      90            2 :    input  logic [2:0]                  dma_axi_awsize,
      91              : 
      92              : 
      93          760 :    input  logic                        dma_axi_wvalid,
      94          544 :    output logic                        dma_axi_wready,
      95        29939 :    input  logic [63:0]                 dma_axi_wdata,
      96       185623 :    input  logic [7:0]                  dma_axi_wstrb,
      97              : 
      98          658 :    output logic                        dma_axi_bvalid,
      99           94 :    input  logic                        dma_axi_bready,
     100          504 :    output logic [1:0]                  dma_axi_bresp,
     101          426 :    output logic [pt.DMA_BUS_TAG-1:0]   dma_axi_bid,
     102              : 
     103              :    // AXI Read Channels
     104          906 :    input  logic                        dma_axi_arvalid,
     105          647 :    output logic                        dma_axi_arready,
     106            3 :    input  logic [pt.DMA_BUS_TAG-1:0]   dma_axi_arid,
     107          414 :    input  logic [31:0]                 dma_axi_araddr,
     108            3 :    input  logic [2:0]                  dma_axi_arsize,
     109              : 
     110          906 :    output logic                        dma_axi_rvalid,
     111          926 :    input  logic                        dma_axi_rready,
     112          426 :    output logic [pt.DMA_BUS_TAG-1:0]   dma_axi_rid,
     113         1220 :    output logic [63:0]                 dma_axi_rdata,
     114          504 :    output logic [1:0]                  dma_axi_rresp,
     115          347 :    output logic                        dma_axi_rlast
     116              : );
     117              : 
     118              : 
     119              :    localparam DEPTH = pt.DMA_BUF_DEPTH;
     120              :    localparam DEPTH_PTR = $clog2(DEPTH);
     121              :    localparam NACK_COUNT = 7;
     122              : 
     123          610 :    logic [DEPTH-1:0]        fifo_valid;
     124           80 :    logic [DEPTH-1:0][1:0]   fifo_error;
     125           94 :    logic [DEPTH-1:0]        fifo_error_bus;
     126          280 :    logic [DEPTH-1:0]        fifo_rpend;
     127          610 :    logic [DEPTH-1:0]        fifo_done;      // DMA trxn is done in core
     128          610 :    logic [DEPTH-1:0]        fifo_done_bus;  // DMA trxn is done in core but synced to bus clock
     129           37 :    logic [DEPTH-1:0][31:0]  fifo_addr;
     130           12 :    logic [DEPTH-1:0][2:0]   fifo_sz;
     131            7 :    logic [DEPTH-1:0][7:0]   fifo_byteen;
     132           30 :    logic [DEPTH-1:0]        fifo_write;
     133            0 :    logic [DEPTH-1:0]        fifo_posted_write;
     134           11 :    logic [DEPTH-1:0]        fifo_dbg;
     135              :    logic [DEPTH-1:0][63:0]  fifo_data;
     136           66 :    logic [DEPTH-1:0][pt.DMA_BUS_TAG-1:0]  fifo_tag;
     137            0 :    logic [DEPTH-1:0][pt.DMA_BUS_ID-1:0]   fifo_mid;
     138            0 :    logic [DEPTH-1:0][pt.DMA_BUS_PRTY-1:0] fifo_prty;
     139              : 
     140          890 :    logic [DEPTH-1:0]        fifo_cmd_en;
     141          730 :    logic [DEPTH-1:0]        fifo_data_en;
     142          280 :    logic [DEPTH-1:0]        fifo_pend_en;
     143          612 :    logic [DEPTH-1:0]        fifo_done_en;
     144          612 :    logic [DEPTH-1:0]        fifo_done_bus_en;
     145           94 :    logic [DEPTH-1:0]        fifo_error_en;
     146           94 :    logic [DEPTH-1:0]        fifo_error_bus_en;
     147          610 :    logic [DEPTH-1:0]        fifo_reset;
     148          404 :    logic [DEPTH-1:0][1:0]   fifo_error_in;
     149              :    logic [DEPTH-1:0][63:0]  fifo_data_in;
     150              : 
     151         1533 :    logic                    fifo_write_in;
     152            0 :    logic                    fifo_posted_write_in;
     153         3856 :    logic                    fifo_dbg_in;
     154         3102 :    logic [31:0]             fifo_addr_in;
     155          606 :    logic [2:0]              fifo_sz_in;
     156           34 :    logic [7:0]              fifo_byteen_in;
     157              : 
     158          611 :    logic [DEPTH_PTR-1:0]    RspPtr, NxtRspPtr;
     159          611 :    logic [DEPTH_PTR-1:0]    WrPtr, NxtWrPtr;
     160          611 :    logic [DEPTH_PTR-1:0]    RdPtr, NxtRdPtr;
     161         2968 :    logic                    WrPtrEn, RdPtrEn, RspPtrEn;
     162              : 
     163          153 :    logic [1:0]              dma_dbg_sz;
     164            0 :    logic [1:0]              dma_dbg_addr;
     165         1237 :    logic [31:0]             dma_dbg_mem_rddata;
     166          321 :    logic [31:0]             dma_dbg_mem_wrdata;
     167          204 :    logic                    dma_dbg_cmd_error;
     168         1404 :    logic                    dma_dbg_cmd_done_q;
     169              : 
     170         3247 :    logic                    fifo_full, fifo_full_spec, fifo_empty;
     171            0 :    logic                    dma_address_error, dma_alignment_error;
     172            0 :    logic [3:0]              num_fifo_vld;
     173         2548 :    logic                    dma_mem_req;
     174          291 :    logic [31:0]             dma_mem_addr_int;
     175           64 :    logic [2:0]              dma_mem_sz_int;
     176           54 :    logic [7:0]              dma_mem_byteen;
     177          524 :    logic                    dma_mem_addr_in_dccm;
     178          553 :    logic                    dma_mem_addr_in_iccm;
     179            0 :    logic                    dma_mem_addr_in_pic;
     180          550 :    logic                    dma_mem_addr_in_pic_region_nc;
     181          550 :    logic                    dma_mem_addr_in_dccm_region_nc;
     182          593 :    logic                    dma_mem_addr_in_iccm_region_nc;
     183              : 
     184          345 :    logic [2:0]              dma_nack_count, dma_nack_count_d, dma_nack_count_csr;
     185              : 
     186         5523 :    logic                    dma_buffer_c1_clken;
     187         5331 :    logic                    dma_free_clken;
     188     69872476 :    logic                    dma_buffer_c1_clk;
     189     69891424 :    logic                    dma_free_clk;
     190        44310 :    logic                    dma_bus_clk;
     191              : 
     192         1564 :    logic                    bus_rsp_valid, bus_rsp_sent;
     193         1664 :    logic                    bus_cmd_valid, bus_cmd_sent;
     194            0 :    logic                    bus_cmd_write, bus_cmd_posted_write;
     195           34 :    logic [7:0]              bus_cmd_byteen;
     196          606 :    logic [2:0]              bus_cmd_sz;
     197          368 :    logic [31:0]             bus_cmd_addr;
     198          156 :    logic [63:0]             bus_cmd_wdata;
     199          372 :    logic [pt.DMA_BUS_TAG-1:0]  bus_cmd_tag;
     200            0 :    logic [pt.DMA_BUS_ID-1:0]   bus_cmd_mid;
     201            0 :    logic [pt.DMA_BUS_PRTY-1:0] bus_cmd_prty;
     202            0 :    logic                    bus_posted_write_done;
     203              : 
     204            0 :    logic                    fifo_full_spec_bus;
     205         3686 :    logic                    dbg_dma_bubble_bus;
     206            0 :    logic                    stall_dma_in;
     207         4033 :    logic                    dma_fifo_ready;
     208              : 
     209          760 :    logic                       wrbuf_en, wrbuf_data_en;
     210          758 :    logic                       wrbuf_cmd_sent, wrbuf_rst, wrbuf_data_rst;
     211          759 :    logic                       wrbuf_vld, wrbuf_data_vld;
     212          327 :    logic [pt.DMA_BUS_TAG-1:0]  wrbuf_tag;
     213            6 :    logic [2:0]                 wrbuf_sz;
     214           23 :    logic [31:0]                wrbuf_addr;
     215          156 :    logic [63:0]                wrbuf_data;
     216           34 :    logic [7:0]                 wrbuf_byteen;
     217              : 
     218          906 :    logic                       rdbuf_en;
     219          906 :    logic                       rdbuf_cmd_sent, rdbuf_rst;
     220          906 :    logic                       rdbuf_vld;
     221            7 :    logic [pt.DMA_BUS_TAG-1:0]  rdbuf_tag;
     222            7 :    logic [2:0]                 rdbuf_sz;
     223           27 :    logic [31:0]                rdbuf_addr;
     224              : 
     225          838 :    logic                       axi_mstr_prty_in, axi_mstr_prty_en;
     226          832 :    logic                       axi_mstr_priority;
     227          759 :    logic                       axi_mstr_sel;
     228              : 
     229            0 :    logic                       axi_rsp_valid, axi_rsp_sent;
     230          276 :    logic                       axi_rsp_write;
     231          426 :    logic [pt.DMA_BUS_TAG-1:0]  axi_rsp_tag;
     232          504 :    logic [1:0]                 axi_rsp_error;
     233         1220 :    logic [63:0]                axi_rsp_rdata;
     234              : 
     235              :    //------------------------LOGIC STARTS HERE---------------------------------
     236              : 
     237              :    // FIFO inputs
     238              :    assign fifo_addr_in[31:0]    = dbg_cmd_valid ? dbg_cmd_addr[31:0] : bus_cmd_addr[31:0];
     239              :    assign fifo_byteen_in[7:0]   = {8{~dbg_cmd_valid}} & bus_cmd_byteen[7:0];    // Byte enable is used only for bus requests
     240              :    assign fifo_sz_in[2:0]       = dbg_cmd_valid ? {1'b0,dbg_cmd_size[1:0]} : bus_cmd_sz[2:0];
     241              :    assign fifo_write_in         = dbg_cmd_valid ? dbg_cmd_write : bus_cmd_write;
     242              :    assign fifo_posted_write_in  = ~dbg_cmd_valid & bus_cmd_posted_write;
     243              :    assign fifo_dbg_in           = dbg_cmd_valid;
     244              : 
     245              :    for (genvar i=0 ;i<DEPTH; i++) begin: GenFifo
     246              :       assign fifo_cmd_en[i]   = ((bus_cmd_sent & dma_bus_clk_en) | (dbg_cmd_valid & dbg_cmd_type[1])) & (i == WrPtr[DEPTH_PTR-1:0]);
     247              :       assign fifo_data_en[i] = (((bus_cmd_sent & fifo_write_in & dma_bus_clk_en) | (dbg_cmd_valid & dbg_cmd_type[1] & dbg_cmd_write))  & (i == WrPtr[DEPTH_PTR-1:0])) |
     248              :                                ((dma_address_error | dma_alignment_error) & (i == RdPtr[DEPTH_PTR-1:0])) |
     249              :                                (dccm_dma_rvalid & (i == DEPTH_PTR'(dccm_dma_rtag[2:0]))) |
     250              :                                (iccm_dma_rvalid & (i == DEPTH_PTR'(iccm_dma_rtag[2:0])));
     251              :       assign fifo_pend_en[i] = (dma_dccm_req | dma_iccm_req) & ~dma_mem_write & (i == RdPtr[DEPTH_PTR-1:0]);
     252              :       assign fifo_error_en[i] = ((dma_address_error | dma_alignment_error | dma_dbg_cmd_error) & (i == RdPtr[DEPTH_PTR-1:0])) |
     253              :                                 ((dccm_dma_rvalid & dccm_dma_ecc_error) & (i == DEPTH_PTR'(dccm_dma_rtag[2:0]))) |
     254              :                                 ((iccm_dma_rvalid & iccm_dma_ecc_error) & (i == DEPTH_PTR'(iccm_dma_rtag[2:0])));
     255              :       assign fifo_error_bus_en[i] = (((|fifo_error_in[i][1:0]) & fifo_error_en[i]) | (|fifo_error[i])) & dma_bus_clk_en;
     256              :       assign fifo_done_en[i] = ((|fifo_error[i] | fifo_error_en[i] | ((dma_dccm_req | dma_iccm_req) & dma_mem_write)) & (i == RdPtr[DEPTH_PTR-1:0])) |
     257              :                                (dccm_dma_rvalid & (i == DEPTH_PTR'(dccm_dma_rtag[2:0]))) |
     258              :                                (iccm_dma_rvalid & (i == DEPTH_PTR'(iccm_dma_rtag[2:0])));
     259              :       assign fifo_done_bus_en[i] = (fifo_done_en[i] | fifo_done[i]) & dma_bus_clk_en;
     260              :       assign fifo_reset[i] = (((bus_rsp_sent | bus_posted_write_done) & dma_bus_clk_en) | dma_dbg_cmd_done) & (i == RspPtr[DEPTH_PTR-1:0]);
     261              :       assign fifo_error_in[i]   = (dccm_dma_rvalid & (i == DEPTH_PTR'(dccm_dma_rtag[2:0]))) ? {1'b0,dccm_dma_ecc_error} : (iccm_dma_rvalid & (i == DEPTH_PTR'(iccm_dma_rtag[2:0]))) ? {1'b0,iccm_dma_ecc_error}  :
     262              :                                                                                                                 {(dma_address_error | dma_alignment_error | dma_dbg_cmd_error), dma_alignment_error};
     263              :       assign fifo_data_in[i]   = (fifo_error_en[i] & (|fifo_error_in[i])) ? {32'b0,fifo_addr[i]} :
     264              :                                                         ((dccm_dma_rvalid & (i == DEPTH_PTR'(dccm_dma_rtag[2:0])))  ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid & (i == DEPTH_PTR'(iccm_dma_rtag[2:0]))) ? iccm_dma_rdata[63:0] :
     265              :                                                                                                                                                        (dbg_cmd_valid ? {2{dma_dbg_mem_wrdata[31:0]}} : bus_cmd_wdata[63:0]));
     266              : 
     267              :       rvdffsc #(1) fifo_valid_dff (.din(1'b1), .dout(fifo_valid[i]), .en(fifo_cmd_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
     268              :       rvdffsc #(2) fifo_error_dff (.din(fifo_error_in[i]), .dout(fifo_error[i]), .en(fifo_error_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
     269              :       rvdffsc #(1) fifo_error_bus_dff (.din(1'b1), .dout(fifo_error_bus[i]), .en(fifo_error_bus_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
     270              :       rvdffsc #(1) fifo_rpend_dff (.din(1'b1), .dout(fifo_rpend[i]), .en(fifo_pend_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
     271              :       rvdffsc #(1) fifo_done_dff (.din(1'b1), .dout(fifo_done[i]), .en(fifo_done_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
     272              :       rvdffsc #(1) fifo_done_bus_dff (.din(1'b1), .dout(fifo_done_bus[i]), .en(fifo_done_bus_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
     273              :       rvdffe  #(32) fifo_addr_dff (.din(fifo_addr_in[31:0]), .dout(fifo_addr[i]), .en(fifo_cmd_en[i]), .*);
     274              :       rvdffs  #(3) fifo_sz_dff (.din(fifo_sz_in[2:0]), .dout(fifo_sz[i]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
     275              :       rvdffs  #(8) fifo_byteen_dff (.din(fifo_byteen_in[7:0]), .dout(fifo_byteen[i]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
     276              :       rvdffs  #(1) fifo_write_dff (.din(fifo_write_in), .dout(fifo_write[i]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
     277              :       rvdffs  #(1) fifo_posted_write_dff (.din(fifo_posted_write_in), .dout(fifo_posted_write[i]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
     278              :       rvdffs  #(1) fifo_dbg_dff (.din(fifo_dbg_in), .dout(fifo_dbg[i]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
     279              :       rvdffe  #(64) fifo_data_dff (.din(fifo_data_in[i]), .dout(fifo_data[i]), .en(fifo_data_en[i]), .*);
     280              :       rvdffs  #(pt.DMA_BUS_TAG) fifo_tag_dff(.din(bus_cmd_tag[pt.DMA_BUS_TAG-1:0]), .dout(fifo_tag[i][pt.DMA_BUS_TAG-1:0]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
     281              :       rvdffs  #(pt.DMA_BUS_ID) fifo_mid_dff(.din(bus_cmd_mid[pt.DMA_BUS_ID-1:0]), .dout(fifo_mid[i][pt.DMA_BUS_ID-1:0]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
     282              :       rvdffs  #(pt.DMA_BUS_PRTY) fifo_prty_dff(.din(bus_cmd_prty[pt.DMA_BUS_PRTY-1:0]), .dout(fifo_prty[i][pt.DMA_BUS_PRTY-1:0]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
     283              :    end
     284              : 
     285              :    // Pointer logic
     286              :    assign NxtWrPtr[DEPTH_PTR-1:0] = (WrPtr[DEPTH_PTR-1:0] == (DEPTH-1)) ? '0 : WrPtr[DEPTH_PTR-1:0] + 1'b1;
     287              :    assign NxtRdPtr[DEPTH_PTR-1:0] = (RdPtr[DEPTH_PTR-1:0] == (DEPTH-1)) ? '0 : RdPtr[DEPTH_PTR-1:0] + 1'b1;
     288              :    assign NxtRspPtr[DEPTH_PTR-1:0] = (RspPtr[DEPTH_PTR-1:0] == (DEPTH-1)) ? '0 : RspPtr[DEPTH_PTR-1:0] + 1'b1;
     289              : 
     290              :    assign WrPtrEn = |fifo_cmd_en[DEPTH-1:0];
     291              :    assign RdPtrEn = dma_dccm_req | dma_iccm_req | (dma_address_error | dma_alignment_error | dma_dbg_cmd_error);
     292              :    assign RspPtrEn = (dma_dbg_cmd_done | (bus_rsp_sent | bus_posted_write_done) & dma_bus_clk_en);
     293              : 
     294              :    rvdffs #(DEPTH_PTR) WrPtr_dff(.din(NxtWrPtr[DEPTH_PTR-1:0]), .dout(WrPtr[DEPTH_PTR-1:0]), .en(WrPtrEn), .clk(dma_free_clk), .*);
     295              :    rvdffs #(DEPTH_PTR) RdPtr_dff(.din(NxtRdPtr[DEPTH_PTR-1:0]), .dout(RdPtr[DEPTH_PTR-1:0]), .en(RdPtrEn), .clk(dma_free_clk), .*);
     296              :    rvdffs #(DEPTH_PTR) RspPtr_dff(.din(NxtRspPtr[DEPTH_PTR-1:0]), .dout(RspPtr[DEPTH_PTR-1:0]), .en(RspPtrEn), .clk(dma_free_clk), .*);
     297              : 
     298              :    // Miscellaneous signals
     299              :    assign fifo_full = fifo_full_spec_bus;
     300              : 
     301          347 :    always_comb begin
     302          347 :       num_fifo_vld[3:0] = {3'b0,bus_cmd_sent} - {3'b0,bus_rsp_sent};
     303          347 :       for (int i=0; i<DEPTH; i++) begin
     304         1735 :          num_fifo_vld[3:0] += {3'b0,fifo_valid[i]};
     305              :       end
     306              :    end
     307              :    assign fifo_full_spec          = (num_fifo_vld[3:0] >= DEPTH);
     308              : 
     309              :    assign dma_fifo_ready = ~(fifo_full | dbg_dma_bubble_bus);
     310              : 
     311              :    // Error logic
     312              :    assign dma_address_error = fifo_valid[RdPtr] & ~fifo_done[RdPtr] & ~fifo_dbg[RdPtr] & (~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm));    // request not for ICCM or DCCM
     313              :    assign dma_alignment_error = fifo_valid[RdPtr] & ~fifo_done[RdPtr] & ~fifo_dbg[RdPtr] & ~dma_address_error &
     314              :                                 (((dma_mem_sz_int[2:0] == 3'h1) & dma_mem_addr_int[0])                                                             |    // HW size but unaligned
     315              :                                  ((dma_mem_sz_int[2:0] == 3'h2) & (|dma_mem_addr_int[1:0]))                                                        |    // W size but unaligned
     316              :                                  ((dma_mem_sz_int[2:0] == 3'h3) & (|dma_mem_addr_int[2:0]))                                                        |    // DW size but unaligned
     317              :                                  (dma_mem_addr_in_iccm & ~((dma_mem_sz_int[1:0] == 2'b10) | (dma_mem_sz_int[1:0] == 2'b11)))                       |    // ICCM access not word size
     318              :                                  (dma_mem_addr_in_dccm & dma_mem_write & ~((dma_mem_sz_int[1:0] == 2'b10) | (dma_mem_sz_int[1:0] == 2'b11)))       |    // DCCM write not word size
     319              :                                  (dma_mem_write & (dma_mem_sz_int[2:0] == 3'h2) & (dma_mem_addr_int[2:0] == 3'h0) & (dma_mem_byteen[3:0] != 4'hf)) |    // Write byte enables not aligned for word store
     320              :                                  (dma_mem_write & (dma_mem_sz_int[2:0] == 3'h2) & (dma_mem_addr_int[2:0] == 3'h4) & (dma_mem_byteen[7:4] != 4'hf)) |    // Write byte enables not aligned for word store
     321              :                                  (dma_mem_write & (dma_mem_sz_int[2:0] == 3'h3) & ~((dma_mem_byteen[7:0] == 8'h0f) | (dma_mem_byteen[7:0] == 8'hf0) | (dma_mem_byteen[7:0] == 8'hff)))); // Write byte enables not aligned for dword store
     322              : 
     323              : 
     324              :    //Dbg outputs
     325              :    assign dma_dbg_ready    = fifo_empty & dbg_dma_bubble;
     326              :    assign dma_dbg_cmd_done = (fifo_valid[RspPtr] & fifo_dbg[RspPtr] & fifo_done[RspPtr]);
     327              :    assign dma_dbg_cmd_fail     = (|fifo_error[RspPtr] & dma_dbg_cmd_done) ;
     328              : 
     329              :    assign dma_dbg_sz[1:0]          = fifo_sz[RspPtr][1:0];
     330              :    assign dma_dbg_addr[1:0]        = fifo_addr[RspPtr][1:0];
     331              :    assign dma_dbg_mem_rddata[31:0] = fifo_addr[RspPtr][2] ? fifo_data[RspPtr][63:32] : fifo_data[RspPtr][31:0];
     332              :    assign dma_dbg_rddata[31:0]     = ({32{(dma_dbg_sz[1:0] == 2'h0)}} & ((dma_dbg_mem_rddata[31:0] >> 8*dma_dbg_addr[1:0]) & 32'hff)) |
     333              :                                      ({32{(dma_dbg_sz[1:0] == 2'h1)}} & ((dma_dbg_mem_rddata[31:0] >> 16*dma_dbg_addr[1]) & 32'hffff)) |
     334              :                                      ({32{(dma_dbg_sz[1:0] == 2'h2)}} & dma_dbg_mem_rddata[31:0]);
     335              : 
     336              :    assign dma_dbg_cmd_error = fifo_valid[RdPtr] & ~fifo_done[RdPtr] & fifo_dbg[RdPtr] &
     337              :                                  ((~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm | dma_mem_addr_in_pic)) |             // Address outside of ICCM/DCCM/PIC
     338              :                                   ((dma_mem_addr_in_iccm | dma_mem_addr_in_pic) & (dma_mem_sz_int[1:0] != 2'b10)));    // Only word accesses allowed for ICCM/PIC
     339              : 
     340              :    assign dma_dbg_mem_wrdata[31:0] = ({32{dbg_cmd_size[1:0] == 2'h0}} & {4{dbg_cmd_wrdata[7:0]}}) |
     341              :                                      ({32{dbg_cmd_size[1:0] == 2'h1}} & {2{dbg_cmd_wrdata[15:0]}}) |
     342              :                                      ({32{dbg_cmd_size[1:0] == 2'h2}} & dbg_cmd_wrdata[31:0]);
     343              : 
     344              :    // Block the decode if fifo full
     345              :    assign dma_dccm_stall_any = dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & (dma_nack_count >= dma_nack_count_csr);
     346              :    assign dma_iccm_stall_any = dma_mem_req & dma_mem_addr_in_iccm & (dma_nack_count >= dma_nack_count_csr);
     347              : 
     348              :    // Used to indicate ready to debug
     349              :    assign fifo_empty     = ~((|(fifo_valid[DEPTH-1:0])) | bus_cmd_sent);
     350              : 
     351              :    // Nack counter, stall the lsu pipe if 7 nacks
     352              :    assign dma_nack_count_csr[2:0] = dec_tlu_dma_qos_prty[2:0];
     353              :    assign dma_nack_count_d[2:0] = (dma_nack_count[2:0] >= dma_nack_count_csr[2:0]) ? ({3{~(dma_dccm_req | dma_iccm_req)}} & dma_nack_count[2:0]) :
     354              :                                                                                     (dma_mem_req & ~(dma_dccm_req | dma_iccm_req)) ? (dma_nack_count[2:0] + 1'b1) : 3'b0;
     355              : 
     356              :    rvdffs #(3) nack_count_dff(.din(dma_nack_count_d[2:0]), .dout(dma_nack_count[2:0]), .en(dma_mem_req), .clk(dma_free_clk), .*);
     357              : 
     358              :    // Core outputs
     359              :    assign dma_mem_req         = fifo_valid[RdPtr] & ~fifo_rpend[RdPtr] & ~fifo_done[RdPtr] & ~(dma_address_error | dma_alignment_error | dma_dbg_cmd_error);
     360              :    assign dma_dccm_req        = dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & dccm_ready;
     361              :    assign dma_iccm_req        = dma_mem_req & dma_mem_addr_in_iccm & iccm_ready;
     362              :    assign dma_mem_tag[2:0]    = 3'(RdPtr);
     363              :    assign dma_mem_addr_int[31:0] = fifo_addr[RdPtr];
     364              :    assign dma_mem_sz_int[2:0] = fifo_sz[RdPtr];
     365              :    assign dma_mem_addr[31:0]  = (dma_mem_write & ~fifo_dbg[RdPtr] & (dma_mem_byteen[7:0] == 8'hf0)) ? {dma_mem_addr_int[31:3],1'b1,dma_mem_addr_int[1:0]} : dma_mem_addr_int[31:0];
     366              :    assign dma_mem_sz[2:0]     = (dma_mem_write & ~fifo_dbg[RdPtr] & ((dma_mem_byteen[7:0] == 8'h0f) | (dma_mem_byteen[7:0] == 8'hf0))) ? 3'h2 : dma_mem_sz_int[2:0];
     367              :    assign dma_mem_byteen[7:0] = fifo_byteen[RdPtr];
     368              :    assign dma_mem_write       = fifo_write[RdPtr];
     369              :    assign dma_mem_wdata[63:0] = fifo_data[RdPtr];
     370              : 
     371              :    // PMU outputs
     372              :    assign dma_pmu_dccm_read   = dma_dccm_req & ~dma_mem_write;
     373              :    assign dma_pmu_dccm_write  = dma_dccm_req & dma_mem_write;
     374              :    assign dma_pmu_any_read    = (dma_dccm_req | dma_iccm_req) & ~dma_mem_write;
     375              :    assign dma_pmu_any_write   = (dma_dccm_req | dma_iccm_req) & dma_mem_write;
     376              : 
     377              :    // Address check  dccm
     378              :    if (pt.DCCM_ENABLE) begin: Gen_dccm_enable
     379              :       rvrangecheck #(.CCM_SADR(pt.DCCM_SADR),
     380              :                      .CCM_SIZE(pt.DCCM_SIZE)) addr_dccm_rangecheck (
     381              :          .addr(dma_mem_addr_int[31:0]),
     382              :          .in_range(dma_mem_addr_in_dccm),
     383              :          .in_region(dma_mem_addr_in_dccm_region_nc)
     384              :       );
     385              :    end else begin: Gen_dccm_disable
     386              :       assign dma_mem_addr_in_dccm = '0;
     387              :       assign dma_mem_addr_in_dccm_region_nc = '0;
     388              :    end // else: !if(pt.ICCM_ENABLE)
     389              : 
     390              :    // Address check  iccm
     391              :    if (pt.ICCM_ENABLE) begin: Gen_iccm_enable
     392              :       rvrangecheck #(.CCM_SADR(pt.ICCM_SADR),
     393              :                      .CCM_SIZE(pt.ICCM_SIZE)) addr_iccm_rangecheck (
     394              :          .addr(dma_mem_addr_int[31:0]),
     395              :          .in_range(dma_mem_addr_in_iccm),
     396              :          .in_region(dma_mem_addr_in_iccm_region_nc)
     397              :       );
     398              :    end else begin: Gen_iccm_disable
     399              :       assign dma_mem_addr_in_iccm = '0;
     400              :       assign dma_mem_addr_in_iccm_region_nc = '0;
     401              :    end // else: !if(pt.ICCM_ENABLE)
     402              : 
     403              : 
     404              :    // PIC memory address check
     405              :    rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR),
     406              :                   .CCM_SIZE(pt.PIC_SIZE)) addr_pic_rangecheck (
     407              :       .addr(dma_mem_addr_int[31:0]),
     408              :       .in_range(dma_mem_addr_in_pic),
     409              :       .in_region(dma_mem_addr_in_pic_region_nc)
     410              :     );
     411              : 
     412              :    // Inputs
     413              :    rvdff_fpga #(1) fifo_full_bus_ff     (.din(fifo_full_spec),   .dout(fifo_full_spec_bus), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
     414              :    rvdff_fpga #(1) dbg_dma_bubble_ff    (.din(dbg_dma_bubble),   .dout(dbg_dma_bubble_bus), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
     415              :    rvdff      #(1) dma_dbg_cmd_doneff   (.din(dma_dbg_cmd_done), .dout(dma_dbg_cmd_done_q), .clk(free_clk), .*);
     416              : 
     417              :    // Clock Gating logic
     418              :    assign dma_buffer_c1_clken = (bus_cmd_valid & dma_bus_clk_en) | dbg_cmd_valid | clk_override;
     419              :    assign dma_free_clken = (bus_cmd_valid | bus_rsp_valid | dbg_cmd_valid | dma_dbg_cmd_done | dma_dbg_cmd_done_q | (|fifo_valid[DEPTH-1:0]) | clk_override);
     420              : 
     421              :    rvoclkhdr dma_buffer_c1cgc ( .en(dma_buffer_c1_clken), .l1clk(dma_buffer_c1_clk), .* );
     422              :    rvoclkhdr dma_free_cgc (.en(dma_free_clken), .l1clk(dma_free_clk), .*);
     423              : 
     424              : `ifdef RV_FPGA_OPTIMIZE
     425              :    assign dma_bus_clk = 1'b0;
     426              : `else
     427              :    rvclkhdr  dma_bus_cgc (.en(dma_bus_clk_en), .l1clk(dma_bus_clk), .*);
     428              : `endif
     429              : 
     430              :    // Write channel buffer
     431              :    assign wrbuf_en       = dma_axi_awvalid & dma_axi_awready;
     432              :    assign wrbuf_data_en  = dma_axi_wvalid & dma_axi_wready;
     433              :    assign wrbuf_cmd_sent = bus_cmd_sent & bus_cmd_write;
     434              :    assign wrbuf_rst      = wrbuf_cmd_sent & ~wrbuf_en;
     435              :    assign wrbuf_data_rst = wrbuf_cmd_sent & ~wrbuf_data_en;
     436              : 
     437              :    rvdffsc_fpga  #(.WIDTH(1))              wrbuf_vldff       (.din(1'b1), .dout(wrbuf_vld),      .en(wrbuf_en),      .clear(wrbuf_rst),      .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
     438              :    rvdffsc_fpga  #(.WIDTH(1))              wrbuf_data_vldff  (.din(1'b1), .dout(wrbuf_data_vld), .en(wrbuf_data_en), .clear(wrbuf_data_rst), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
     439              :    rvdffs_fpga   #(.WIDTH(pt.DMA_BUS_TAG)) wrbuf_tagff       (.din(dma_axi_awid[pt.DMA_BUS_TAG-1:0]), .dout(wrbuf_tag[pt.DMA_BUS_TAG-1:0]), .en(wrbuf_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
     440              :    rvdffs_fpga   #(.WIDTH(3))              wrbuf_szff        (.din(dma_axi_awsize[2:0]),  .dout(wrbuf_sz[2:0]),     .en(wrbuf_en),                  .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
     441              :    rvdffe        #(.WIDTH(32))             wrbuf_addrff      (.din(dma_axi_awaddr[31:0]), .dout(wrbuf_addr[31:0]),  .en(wrbuf_en & dma_bus_clk_en), .*);
     442              :    rvdffe        #(.WIDTH(64))             wrbuf_dataff      (.din(dma_axi_wdata[63:0]),  .dout(wrbuf_data[63:0]),  .en(wrbuf_data_en & dma_bus_clk_en), .*);
     443              :    rvdffs_fpga   #(.WIDTH(8))              wrbuf_byteenff    (.din(dma_axi_wstrb[7:0]),   .dout(wrbuf_byteen[7:0]), .en(wrbuf_data_en),             .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
     444              : 
     445              :    // Read channel buffer
     446              :    assign rdbuf_en    = dma_axi_arvalid & dma_axi_arready;
     447              :    assign rdbuf_cmd_sent = bus_cmd_sent & ~bus_cmd_write;
     448              :    assign rdbuf_rst   = rdbuf_cmd_sent & ~rdbuf_en;
     449              : 
     450              :    rvdffsc_fpga  #(.WIDTH(1))              rdbuf_vldff  (.din(1'b1), .dout(rdbuf_vld), .en(rdbuf_en), .clear(rdbuf_rst), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
     451              :    rvdffs_fpga   #(.WIDTH(pt.DMA_BUS_TAG)) rdbuf_tagff  (.din(dma_axi_arid[pt.DMA_BUS_TAG-1:0]), .dout(rdbuf_tag[pt.DMA_BUS_TAG-1:0]), .en(rdbuf_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
     452              :    rvdffs_fpga   #(.WIDTH(3))              rdbuf_szff   (.din(dma_axi_arsize[2:0]),  .dout(rdbuf_sz[2:0]),    .en(rdbuf_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
     453              :    rvdffe       #(.WIDTH(32))              rdbuf_addrff (.din(dma_axi_araddr[31:0]), .dout(rdbuf_addr[31:0]), .en(rdbuf_en & dma_bus_clk_en), .*);
     454              : 
     455              :    assign dma_axi_awready = ~(wrbuf_vld & ~wrbuf_cmd_sent);
     456              :    assign dma_axi_wready  = ~(wrbuf_data_vld & ~wrbuf_cmd_sent);
     457              :    assign dma_axi_arready = ~(rdbuf_vld & ~rdbuf_cmd_sent);
     458              : 
     459              :    //Generate a single request from read/write channel
     460              :    assign bus_cmd_valid                     = (wrbuf_vld & wrbuf_data_vld) | rdbuf_vld;
     461              :    assign bus_cmd_sent                      = bus_cmd_valid & dma_fifo_ready;
     462              :    assign bus_cmd_write                     = axi_mstr_sel;
     463              :    assign bus_cmd_posted_write              = '0;
     464              :    assign bus_cmd_addr[31:0]                = axi_mstr_sel ? wrbuf_addr[31:0] : rdbuf_addr[31:0];
     465              :    assign bus_cmd_sz[2:0]                   = axi_mstr_sel ? wrbuf_sz[2:0] : rdbuf_sz[2:0];
     466              :    assign bus_cmd_wdata[63:0]               = wrbuf_data[63:0];
     467              :    assign bus_cmd_byteen[7:0]               = wrbuf_byteen[7:0];
     468              :    assign bus_cmd_tag[pt.DMA_BUS_TAG-1:0]   = axi_mstr_sel ? wrbuf_tag[pt.DMA_BUS_TAG-1:0] : rdbuf_tag[pt.DMA_BUS_TAG-1:0];
     469              :    assign bus_cmd_mid[pt.DMA_BUS_ID-1:0]    = '0;
     470              :    assign bus_cmd_prty[pt.DMA_BUS_PRTY-1:0] = '0;
     471              : 
     472              :    // Sel=1 -> write has higher priority
     473              :    assign axi_mstr_sel     = (wrbuf_vld & wrbuf_data_vld & rdbuf_vld) ? axi_mstr_priority : (wrbuf_vld & wrbuf_data_vld);
     474              :    assign axi_mstr_prty_in = ~axi_mstr_priority;
     475              :    assign axi_mstr_prty_en = bus_cmd_sent;
     476              :    rvdffs_fpga #(.WIDTH(1)) mstr_prtyff(.din(axi_mstr_prty_in), .dout(axi_mstr_priority), .en(axi_mstr_prty_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
     477              : 
     478              :    assign axi_rsp_valid                   = fifo_valid[RspPtr] & ~fifo_dbg[RspPtr] & fifo_done_bus[RspPtr];
     479              :    assign axi_rsp_rdata[63:0]             = fifo_data[RspPtr];
     480              :    assign axi_rsp_write                   = fifo_write[RspPtr];
     481              :    assign axi_rsp_error[1:0]              = fifo_error[RspPtr][0] ? 2'b10 : (fifo_error[RspPtr][1] ? 2'b11 : 2'b0);
     482              :    assign axi_rsp_tag[pt.DMA_BUS_TAG-1:0] = fifo_tag[RspPtr];
     483              : 
     484              :    // AXI response channel signals
     485              :    assign dma_axi_bvalid                  = axi_rsp_valid & axi_rsp_write;
     486              :    assign dma_axi_bresp[1:0]              = axi_rsp_error[1:0];
     487              :    assign dma_axi_bid[pt.DMA_BUS_TAG-1:0] = axi_rsp_tag[pt.DMA_BUS_TAG-1:0];
     488              : 
     489              :    assign dma_axi_rvalid                  = axi_rsp_valid & ~axi_rsp_write;
     490              :    assign dma_axi_rresp[1:0]              = axi_rsp_error;
     491              :    assign dma_axi_rdata[63:0]             = axi_rsp_rdata[63:0];
     492              :    assign dma_axi_rlast                   = 1'b1;
     493              :    assign dma_axi_rid[pt.DMA_BUS_TAG-1:0] = axi_rsp_tag[pt.DMA_BUS_TAG-1:0];
     494              : 
     495              :    assign bus_posted_write_done = 1'b0;
     496              :    assign bus_rsp_valid      = (dma_axi_bvalid | dma_axi_rvalid);
     497              :    assign bus_rsp_sent       = (dma_axi_bvalid & dma_axi_bready) | (dma_axi_rvalid & dma_axi_rready);
     498              : 
     499              :    assign dma_active  = wrbuf_vld | rdbuf_vld | (|fifo_valid[DEPTH-1:0]);
     500              : 
     501              : 
     502              : `ifdef RV_ASSERT_ON
     503              : 
     504              :    for (genvar i=0; i<DEPTH; i++) begin
     505              :       assert_fifo_done_and_novalid: assert #0 (~fifo_done[i] | fifo_valid[i]);
     506              :    end
     507              : 
     508              :    // Assertion to check awvalid stays stable during entire bus clock
     509              :    property dma_axi_awvalid_stable;
     510              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_awvalid != $past(dma_axi_awvalid)) |-> $past(dma_bus_clk_en);
     511              :    endproperty
     512              :    assert_dma_axi_awvalid_stable: assert property (dma_axi_awvalid_stable) else
     513              :       $display("DMA AXI awvalid changed in middle of bus clock");
     514              : 
     515              :    // Assertion to check awid stays stable during entire bus clock
     516              :    property dma_axi_awid_stable;
     517              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_awvalid & (dma_axi_awid[pt.DMA_BUS_TAG-1:0] != $past(dma_axi_awid[pt.DMA_BUS_TAG-1:0]))) |-> $past(dma_bus_clk_en);
     518              :    endproperty
     519              :    assert_dma_axi_awid_stable: assert property (dma_axi_awid_stable) else
     520              :       $display("DMA AXI awid changed in middle of bus clock");
     521              : 
     522              :    // Assertion to check awaddr stays stable during entire bus clock
     523              :    property dma_axi_awaddr_stable;
     524              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_awvalid & (dma_axi_awaddr[31:0] != $past(dma_axi_awaddr[31:0]))) |-> $past(dma_bus_clk_en);
     525              :    endproperty
     526              :    assert_dma_axi_awaddr_stable: assert property (dma_axi_awaddr_stable) else
     527              :       $display("DMA AXI awaddr changed in middle of bus clock");
     528              : 
     529              :    // Assertion to check awsize stays stable during entire bus clock
     530              :    property dma_axi_awsize_stable;
     531              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_awvalid & (dma_axi_awsize[2:0] != $past(dma_axi_awsize[2:0]))) |-> $past(dma_bus_clk_en);
     532              :    endproperty
     533              :    assert_dma_axi_awsize_stable: assert property (dma_axi_awsize_stable) else
     534              :       $display("DMA AXI awsize changed in middle of bus clock");
     535              : 
     536              :    // Assertion to check wstrb stays stable during entire bus clock
     537              :    property dma_axi_wstrb_stable;
     538              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_wvalid & (dma_axi_wstrb[7:0] != $past(dma_axi_wstrb[7:0]))) |-> $past(dma_bus_clk_en);
     539              :    endproperty
     540              :    assert_dma_axi_wstrb_stable: assert property (dma_axi_wstrb_stable) else
     541              :       $display("DMA AXI wstrb changed in middle of bus clock");
     542              : 
     543              :    // Assertion to check wdata stays stable during entire bus clock
     544              :    property dma_axi_wdata_stable;
     545              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_wvalid & (dma_axi_wdata[63:0] != $past(dma_axi_wdata[63:0]))) |-> $past(dma_bus_clk_en);
     546              :    endproperty
     547              :    assert_dma_axi_wdata_stable: assert property (dma_axi_wdata_stable) else
     548              :       $display("DMA AXI wdata changed in middle of bus clock");
     549              : 
     550              :    // Assertion to check awvalid stays stable during entire bus clock
     551              :    property dma_axi_arvalid_stable;
     552              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_arvalid != $past(dma_axi_arvalid)) |-> $past(dma_bus_clk_en);
     553              :    endproperty
     554              :    assert_dma_axi_arvalid_stable: assert property (dma_axi_arvalid_stable) else
     555              :       $display("DMA AXI awvalid changed in middle of bus clock");
     556              : 
     557              :    // Assertion to check awid stays stable during entire bus clock
     558              :    property dma_axi_arid_stable;
     559              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_arvalid & (dma_axi_arid[pt.DMA_BUS_TAG-1:0] != $past(dma_axi_arid[pt.DMA_BUS_TAG-1:0]))) |-> $past(dma_bus_clk_en);
     560              :    endproperty
     561              :    assert_dma_axi_arid_stable: assert property (dma_axi_arid_stable) else
     562              :       $display("DMA AXI awid changed in middle of bus clock");
     563              : 
     564              :    // Assertion to check awaddr stays stable during entire bus clock
     565              :    property dma_axi_araddr_stable;
     566              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_arvalid & (dma_axi_araddr[31:0] != $past(dma_axi_araddr[31:0]))) |-> $past(dma_bus_clk_en);
     567              :    endproperty
     568              :    assert_dma_axi_araddr_stable: assert property (dma_axi_araddr_stable) else
     569              :       $display("DMA AXI awaddr changed in middle of bus clock");
     570              : 
     571              :    // Assertion to check awsize stays stable during entire bus clock
     572              :    property dma_axi_arsize_stable;
     573              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_awvalid & (dma_axi_arsize[2:0] != $past(dma_axi_arsize[2:0]))) |-> $past(dma_bus_clk_en);
     574              :    endproperty
     575              :    assert_dma_axi_arsize_stable: assert property (dma_axi_arsize_stable) else
     576              :       $display("DMA AXI awsize changed in middle of bus clock");
     577              : 
     578              :    // Assertion to check bvalid stays stable during entire bus clock
     579              :    property dma_axi_bvalid_stable;
     580              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_bvalid != $past(dma_axi_bvalid)) |-> $past(dma_bus_clk_en);
     581              :    endproperty
     582              :    assert_dma_axi_bvalid_stable: assert property (dma_axi_bvalid_stable) else
     583              :       $display("DMA AXI bvalid changed in middle of bus clock");
     584              : 
     585              :    // Assertion to check bvalid stays stable if bready is low
     586              :    property dma_axi_bvalid_stable_till_bready;
     587              :       @(posedge clk) disable iff(~rst_l)  (~dma_axi_bvalid && $past(dma_axi_bvalid)) |-> $past(dma_axi_bready);
     588              :    endproperty
     589              :    assert_dma_axi_bvalid_stable_till_bready: assert property (dma_axi_bvalid_stable_till_bready) else
     590              :       $display("DMA AXI bvalid deasserted without bready");
     591              : 
     592              :    // Assertion to check bresp stays stable during entire bus clock
     593              :    property dma_axi_bresp_stable;
     594              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_bvalid & (dma_axi_bresp[1:0] != $past(dma_axi_bresp[1:0]))) |-> $past(dma_bus_clk_en);
     595              :    endproperty
     596              :    assert_dma_axi_bresp_stable: assert property (dma_axi_bresp_stable) else
     597              :       $display("DMA AXI bresp changed in middle of bus clock");
     598              : 
     599              :    // Assertion to check bid stays stable during entire bus clock
     600              :    property dma_axi_bid_stable;
     601              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_bvalid & (dma_axi_bid[pt.DMA_BUS_TAG-1:0] != $past(dma_axi_bid[pt.DMA_BUS_TAG-1:0]))) |-> $past(dma_bus_clk_en);
     602              :    endproperty
     603              :    assert_dma_axi_bid_stable: assert property (dma_axi_bid_stable) else
     604              :       $display("DMA AXI bid changed in middle of bus clock");
     605              : 
     606              :    // Assertion to check rvalid stays stable during entire bus clock
     607              :    property dma_axi_rvalid_stable;
     608              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_rvalid != $past(dma_axi_rvalid)) |-> $past(dma_bus_clk_en);
     609              :    endproperty
     610              :    assert_dma_axi_rvalid_stable: assert property (dma_axi_rvalid_stable) else
     611              :       $display("DMA AXI bvalid changed in middle of bus clock");
     612              : 
     613              :    // Assertion to check rvalid stays stable if bready is low
     614              :    property dma_axi_rvalid_stable_till_ready;
     615              :       @(posedge clk) disable iff(~rst_l)  (~dma_axi_rvalid && $past(dma_axi_rvalid)) |-> $past(dma_axi_rready);
     616              :    endproperty
     617              :    assert_dma_axi_rvalid_stable_till_ready: assert property (dma_axi_rvalid_stable_till_ready) else
     618              :       $display("DMA AXI bvalid changed in middle of bus clock");
     619              : 
     620              :    // Assertion to check rresp stays stable during entire bus clock
     621              :    property dma_axi_rresp_stable;
     622              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_rvalid & (dma_axi_rresp[1:0] != $past(dma_axi_rresp[1:0]))) |-> $past(dma_bus_clk_en);
     623              :    endproperty
     624              :    assert_dma_axi_rresp_stable: assert property (dma_axi_rresp_stable) else
     625              :       $display("DMA AXI bresp changed in middle of bus clock");
     626              : 
     627              :    // Assertion to check rid stays stable during entire bus clock
     628              :    property dma_axi_rid_stable;
     629              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_rvalid & (dma_axi_rid[pt.DMA_BUS_TAG-1:0] != $past(dma_axi_rid[pt.DMA_BUS_TAG-1:0]))) |-> $past(dma_bus_clk_en);
     630              :    endproperty
     631              :    assert_dma_axi_rid_stable: assert property (dma_axi_rid_stable) else
     632              :       $display("DMA AXI bid changed in middle of bus clock");
     633              : 
     634              :    // Assertion to check rdata stays stable during entire bus clock
     635              :    property dma_axi_rdata_stable;
     636              :       @(posedge clk) disable iff(~rst_l)  (dma_axi_rvalid & (dma_axi_rdata[63:0] != $past(dma_axi_rdata[63:0]))) |-> $past(dma_bus_clk_en);
     637              :    endproperty
     638              :    assert_dma_axi_rdata_stable: assert property (dma_axi_rdata_stable) else
     639              :       $display("DMA AXI bid changed in middle of bus clock");
     640              : 
     641              : `endif
     642              : 
     643              : endmodule // el2_dma_ctrl