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 69704761 : input logic clk,
30 69704761 : 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 61 : input logic [31:0] dbg_cmd_addr,
41 277 : input logic [31:0] dbg_cmd_wrdata,
42 4072 : input logic dbg_cmd_valid,
43 357 : 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 3898 : input logic dbg_dma_bubble, // Debug needs a bubble to send a valid
48 4816 : 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 2234776 : input logic dccm_ready, // dccm ready to accept DMA request
76 639461 : 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 301 : 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 29941 : input logic [63:0] dma_axi_wdata,
96 185760 : 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 305 : 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 1665 : logic fifo_write_in;
152 0 : logic fifo_posted_write_in;
153 4072 : logic fifo_dbg_in;
154 1042 : 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 327 : 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 5739 : logic dma_buffer_c1_clken;
187 5547 : logic dma_free_clken;
188 69672998 : logic dma_buffer_c1_clk;
189 69691946 : 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 3902 : logic dbg_dma_bubble_bus;
206 0 : logic stall_dma_in;
207 4249 : 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
|