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 : //
20 : // Function: Top level file for load store unit
21 : // Comments:
22 : //
23 : //
24 : // DC1 -> DC2 -> DC3 -> DC4 (Commit)
25 : //
26 : //********************************************************************************
27 :
28 : module el2_lsu
29 : import el2_pkg::*;
30 : #(
31 : `include "el2_param.vh"
32 : )
33 : (
34 :
35 2 : input logic clk_override, // Override non-functional clock gating
36 59234 : input logic dec_tlu_flush_lower_r, // I0/I1 writeback flush. This is used to flush the old packets only
37 29690 : input logic dec_tlu_i0_kill_writeb_r, // I0 is flushed, don't writeback any results to arch state
38 0 : input logic dec_tlu_force_halt, // This will be high till TLU goes to debug halt
39 :
40 : // chicken signals
41 0 : input logic dec_tlu_external_ldfwd_disable, // disable load to load forwarding for externals
42 6 : input logic dec_tlu_wb_coalescing_disable, // disable the write buffer coalesce
43 322 : input logic dec_tlu_sideeffect_posted_disable, // disable the posted sideeffect load store to the bus
44 8 : input logic dec_tlu_core_ecc_disable, // disable the generation of the ecc
45 :
46 413533 : input logic [31:0] exu_lsu_rs1_d, // address rs operand
47 81504 : input logic [31:0] exu_lsu_rs2_d, // store data
48 270454 : input logic [11:0] dec_lsu_offset_d, // address offset operand
49 :
50 623733 : input el2_lsu_pkt_t lsu_p, // lsu control packet
51 2283261 : input logic dec_lsu_valid_raw_d, // Raw valid for address computation
52 0 : input logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control
53 :
54 45313 : output logic [31:0] lsu_result_m, // lsu load data
55 36052 : output logic [31:0] lsu_result_corr_r, // This is the ECC corrected data going to RF
56 48822 : output logic lsu_load_stall_any, // This is for blocking loads in the decode
57 59146 : output logic lsu_store_stall_any, // This is for blocking stores in the decode
58 4 : output logic lsu_fastint_stall_any, // Stall the fastint in decode-1 stage
59 1346584 : output logic lsu_idle_any, // lsu buffers are empty and no instruction in the pipeline. Doesn't include DMA
60 1346245 : output logic lsu_active, // Used to turn off top level clk
61 :
62 24696 : output logic [31:1] lsu_fir_addr, // fast interrupt address
63 0 : output logic [1:0] lsu_fir_error, // Error during fast interrupt lookup
64 :
65 4 : output logic lsu_single_ecc_error_incr, // Increment the ecc counter
66 4 : output el2_lsu_error_pkt_t lsu_error_pkt_r, // lsu exception packet
67 2 : output logic lsu_imprecise_error_load_any, // bus load imprecise error
68 2 : output logic lsu_imprecise_error_store_any, // bus store imprecise error
69 401 : output logic [31:0] lsu_imprecise_error_addr_any, // bus store imprecise error address
70 :
71 : // Non-blocking loads
72 881246 : output logic lsu_nonblock_load_valid_m, // there is an external load -> put in the cam
73 504987 : output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // the tag of the external non block load
74 0 : output logic lsu_nonblock_load_inv_r, // invalidate signal for the cam entry for non block loads
75 504984 : output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // tag of the enrty which needs to be invalidated
76 920472 : output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam
77 2 : output logic lsu_nonblock_load_data_error, // non block load has an error
78 36572 : output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error
79 71596 : output logic [31:0] lsu_nonblock_load_data, // Data of the non block load
80 :
81 891386 : output logic lsu_pmu_load_external_m, // PMU : Bus loads
82 813400 : output logic lsu_pmu_store_external_m, // PMU : Bus loads
83 48802 : output logic lsu_pmu_misaligned_m, // PMU : misaligned
84 1673968 : output logic lsu_pmu_bus_trxn, // PMU : bus transaction
85 36422 : output logic lsu_pmu_bus_misaligned, // PMU : misaligned access going to the bus
86 4 : output logic lsu_pmu_bus_error, // PMU : bus sending error back
87 67776 : output logic lsu_pmu_bus_busy, // PMU : bus is not ready
88 :
89 : // Trigger signals
90 0 : input el2_trigger_pkt_t [3:0] trigger_pkt_any, // Trigger info from the decode
91 0 : output logic [3:0] lsu_trigger_match_m, // lsu trigger hit (one bit per trigger)
92 :
93 : // DCCM ports
94 262894 : output logic dccm_wren, // DCCM write enable
95 561000 : output logic dccm_rden, // DCCM read enable
96 18811 : output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo, // DCCM write address low bank
97 18811 : output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi, // DCCM write address hi bank
98 471434 : output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo, // DCCM read address low bank
99 677829 : output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi, // DCCM read address hi bank (hi and low same if aligned read)
100 5376 : output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, // DCCM write data for lo bank
101 5376 : output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // DCCM write data for hi bank
102 :
103 47176 : input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // DCCM read data low bank
104 47176 : input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // DCCM read data hi bank
105 :
106 : // PIC ports
107 8 : output logic picm_wren, // PIC memory write enable
108 2 : output logic picm_rden, // PIC memory read enable
109 10 : output logic picm_mken, // Need to read the mask for stores to determine which bits to write/forward
110 435 : output logic [31:0] picm_rdaddr, // address for pic read access
111 435 : output logic [31:0] picm_wraddr, // address for pic write access
112 92722 : output logic [31:0] picm_wr_data, // PIC memory write data
113 0 : input logic [31:0] picm_rd_data, // PIC memory read/mask data
114 :
115 : // AXI Write Channels
116 862452 : output logic lsu_axi_awvalid,
117 1114186 : input logic lsu_axi_awready,
118 0 : output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_awid,
119 401 : output logic [31:0] lsu_axi_awaddr,
120 336 : output logic [3:0] lsu_axi_awregion,
121 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
122 : /*verilator coverage_off*/
123 : output logic [7:0] lsu_axi_awlen,
124 : /*verilator coverage_on*/
125 0 : output logic [2:0] lsu_axi_awsize,
126 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
127 : /*verilator coverage_off*/
128 : output logic [1:0] lsu_axi_awburst,
129 : output logic lsu_axi_awlock,
130 : /*verilator coverage_on*/
131 3029 : output logic [3:0] lsu_axi_awcache,
132 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
133 : /*verilator coverage_off*/
134 : output logic [2:0] lsu_axi_awprot,
135 : output logic [3:0] lsu_axi_awqos,
136 : /*verilator coverage_on*/
137 :
138 862452 : output logic lsu_axi_wvalid,
139 1114186 : input logic lsu_axi_wready,
140 31437 : output logic [63:0] lsu_axi_wdata,
141 224891 : output logic [7:0] lsu_axi_wstrb,
142 339 : output logic lsu_axi_wlast,
143 :
144 875678 : input logic lsu_axi_bvalid,
145 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
146 : /*verilator coverage_off*/
147 : output logic lsu_axi_bready,
148 : /*verilator coverage_on*/
149 2 : input logic [1:0] lsu_axi_bresp,
150 0 : input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid,
151 :
152 : // AXI Read Channels
153 868564 : output logic lsu_axi_arvalid,
154 1114368 : input logic lsu_axi_arready,
155 0 : output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_arid,
156 401 : output logic [31:0] lsu_axi_araddr,
157 336 : output logic [3:0] lsu_axi_arregion,
158 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
159 : /*verilator coverage_off*/
160 : output logic [7:0] lsu_axi_arlen,
161 : /*verilator coverage_on*/
162 0 : output logic [2:0] lsu_axi_arsize,
163 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
164 : /*verilator coverage_off*/
165 : output logic [1:0] lsu_axi_arburst,
166 : output logic lsu_axi_arlock,
167 : /*verilator coverage_on*/
168 3029 : output logic [3:0] lsu_axi_arcache,
169 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
170 : /*verilator coverage_off*/
171 : output logic [2:0] lsu_axi_arprot,
172 : output logic [3:0] lsu_axi_arqos,
173 : /*verilator coverage_on*/
174 :
175 929300 : input logic lsu_axi_rvalid,
176 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
177 : /*verilator coverage_off*/
178 : output logic lsu_axi_rready,
179 : /*verilator coverage_on*/
180 0 : input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid,
181 28812 : input logic [63:0] lsu_axi_rdata,
182 2 : input logic [1:0] lsu_axi_rresp,
183 673636 : input logic lsu_axi_rlast,
184 :
185 338 : input logic lsu_bus_clk_en, // external drives a clock_en to control bus ratio
186 :
187 : // DMA slave
188 0 : input logic dma_dccm_req, // DMA read/write to dccm
189 12 : input logic [2:0] dma_mem_tag, // DMA request tag
190 0 : input logic [31:0] dma_mem_addr, // DMA address
191 0 : input logic [2:0] dma_mem_sz, // DMA access size
192 22 : input logic dma_mem_write, // DMA access is a write
193 12 : input logic [63:0] dma_mem_wdata, // DMA write data
194 :
195 0 : output logic dccm_dma_rvalid, // lsu data valid for DMA dccm read
196 4 : output logic dccm_dma_ecc_error, // DMA load had ecc error
197 12 : output logic [2:0] dccm_dma_rtag, // DMA request tag
198 39564 : output logic [63:0] dccm_dma_rdata, // lsu data for DMA dccm read
199 2232486 : output logic dccm_ready, // lsu ready for DMA access
200 :
201 : // DCCM ECC status
202 4 : output logic lsu_dccm_rd_ecc_single_err,
203 4 : output logic lsu_dccm_rd_ecc_double_err,
204 :
205 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
206 : /*verilator coverage_off*/
207 : input logic scan_mode, // scan mode
208 : /*verilator coverage_on*/
209 69830461 : input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
210 69830461 : input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
211 338 : input logic rst_l, // reset, active low
212 :
213 593765 : output logic [31:0] lsu_pmp_addr_start,
214 593791 : output logic [31:0] lsu_pmp_addr_end,
215 166874 : input logic lsu_pmp_error_start,
216 166874 : input logic lsu_pmp_error_end,
217 1072759 : output logic lsu_pmp_we,
218 1423948 : output logic lsu_pmp_re
219 :
220 : );
221 :
222 561000 : logic lsu_dccm_rden_m;
223 561000 : logic lsu_dccm_rden_r;
224 81504 : logic [31:0] store_data_m;
225 56592 : logic [31:0] store_data_r;
226 91180 : logic [31:0] store_data_hi_r, store_data_lo_r;
227 62472 : logic [31:0] store_datafn_hi_r, store_datafn_lo_r;
228 47176 : logic [31:0] sec_data_lo_m, sec_data_hi_m;
229 2 : logic [31:0] sec_data_lo_r, sec_data_hi_r;
230 :
231 54456 : logic [31:0] lsu_ld_data_m;
232 47176 : logic [31:0] dccm_rdata_hi_m, dccm_rdata_lo_m;
233 154095 : logic [6:0] dccm_data_ecc_hi_m, dccm_data_ecc_lo_m;
234 4 : logic lsu_single_ecc_error_m;
235 4 : logic lsu_double_ecc_error_m;
236 :
237 0 : logic [31:0] lsu_ld_data_r;
238 24696 : logic [31:0] lsu_ld_data_corr_r;
239 0 : logic [31:0] dccm_rdata_hi_r, dccm_rdata_lo_r;
240 0 : logic [6:0] dccm_data_ecc_hi_r, dccm_data_ecc_lo_r;
241 4 : logic single_ecc_error_hi_r, single_ecc_error_lo_r;
242 4 : logic lsu_single_ecc_error_r;
243 4 : logic lsu_double_ecc_error_r;
244 4 : logic ld_single_ecc_error_r, ld_single_ecc_error_r_ff;
245 : assign lsu_dccm_rd_ecc_single_err = lsu_single_ecc_error_r;
246 : assign lsu_dccm_rd_ecc_double_err = lsu_double_ecc_error_r;
247 :
248 0 : logic [31:0] picm_mask_data_m;
249 :
250 593763 : logic [31:0] lsu_addr_d, lsu_addr_m, lsu_addr_r;
251 594163 : logic [31:0] end_addr_d, end_addr_m, end_addr_r;
252 : assign lsu_pmp_addr_start = lsu_addr_d;
253 : assign lsu_pmp_addr_end = end_addr_d;
254 :
255 477975 : el2_lsu_pkt_t lsu_pkt_d, lsu_pkt_m, lsu_pkt_r;
256 0 : logic lsu_i0_valid_d, lsu_i0_valid_m, lsu_i0_valid_r;
257 : assign lsu_pmp_we = lsu_pkt_d.store & lsu_pkt_d.valid;
258 : assign lsu_pmp_re = lsu_pkt_d.load & lsu_pkt_d.valid;
259 :
260 : // Store Buffer signals
261 258932 : logic store_stbuf_reqvld_r;
262 258932 : logic ldst_stbuf_reqvld_r;
263 :
264 2286394 : logic lsu_commit_r;
265 80 : logic lsu_exc_m;
266 :
267 614422 : logic addr_in_dccm_d, addr_in_dccm_m, addr_in_dccm_r;
268 12 : logic addr_in_pic_d, addr_in_pic_m, addr_in_pic_r;
269 36584 : logic ldst_dual_d, ldst_dual_m, ldst_dual_r;
270 614788 : logic addr_external_m;
271 :
272 258448 : logic stbuf_reqvld_any;
273 0 : logic stbuf_reqvld_flushed_any;
274 18811 : logic [pt.LSU_SB_BITS-1:0] stbuf_addr_any;
275 7576 : logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any;
276 50849 : logic [pt.DCCM_ECC_WIDTH-1:0] stbuf_ecc_any;
277 2 : logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r_ff, sec_data_hi_r_ff;
278 50849 : logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_hi_r_ff, sec_data_ecc_lo_r_ff;
279 :
280 614442 : logic lsu_cmpen_m;
281 5218 : logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_m;
282 4892 : logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_m;
283 4200 : logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_m;
284 4202 : logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_m;
285 :
286 262890 : logic lsu_stbuf_commit_any;
287 258787 : logic lsu_stbuf_empty_any; // This is for blocking loads
288 10324 : logic lsu_stbuf_full_any;
289 :
290 : // Bus signals
291 1666360 : logic lsu_busreq_r;
292 815379 : logic lsu_bus_buffer_pend_any;
293 1194486 : logic lsu_bus_buffer_empty_any;
294 48818 : logic lsu_bus_buffer_full_any;
295 1676596 : logic lsu_busreq_m;
296 200 : logic [31:0] bus_read_data_m;
297 :
298 29690 : logic flush_m_up, flush_r;
299 36448 : logic is_sideeffects_m;
300 12 : logic [2:0] dma_mem_tag_d, dma_mem_tag_m;
301 258942 : logic ldst_nodma_mtor;
302 0 : logic dma_dccm_wen, dma_pic_wen;
303 0 : logic [31:0] dma_dccm_wdata_lo, dma_dccm_wdata_hi;
304 0 : logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_lo, dma_dccm_wdata_ecc_hi;
305 :
306 : // Clocks
307 1087987 : logic lsu_busm_clken;
308 2049907 : logic lsu_bus_obuf_c1_clken;
309 69830461 : logic lsu_c1_m_clk, lsu_c1_r_clk;
310 69830461 : logic lsu_c2_m_clk, lsu_c2_r_clk;
311 69830461 : logic lsu_store_c1_m_clk, lsu_store_c1_r_clk;
312 :
313 69830461 : logic lsu_stbuf_c1_clk;
314 69830461 : logic lsu_bus_ibuf_c1_clk, lsu_bus_obuf_c1_clk, lsu_bus_buf_c1_clk;
315 0 : logic lsu_busm_clk;
316 69830461 : logic lsu_free_c2_clk;
317 :
318 18836 : logic lsu_raw_fwd_lo_m, lsu_raw_fwd_hi_m;
319 18768 : logic lsu_raw_fwd_lo_r, lsu_raw_fwd_hi_r;
320 :
321 : assign lsu_raw_fwd_lo_m = (|stbuf_fwdbyteen_lo_m[pt.DCCM_BYTE_WIDTH-1:0]);
322 : assign lsu_raw_fwd_hi_m = (|stbuf_fwdbyteen_hi_m[pt.DCCM_BYTE_WIDTH-1:0]);
323 :
324 : el2_lsu_lsc_ctl #(.pt(pt)) lsu_lsc_ctl (.*);
325 :
326 : // block stores in decode - for either bus or stbuf reasons
327 : assign lsu_store_stall_any = lsu_stbuf_full_any | lsu_bus_buffer_full_any | ld_single_ecc_error_r_ff;
328 : assign lsu_load_stall_any = lsu_bus_buffer_full_any | ld_single_ecc_error_r_ff;
329 : assign lsu_fastint_stall_any = ld_single_ecc_error_r; // Stall the fastint in decode-1 stage
330 :
331 : // Ready to accept dma trxns
332 : // There can't be any inpipe forwarding from non-dma packet to dma packet since they can be flushed so we can't have st in r when dma is in m
333 : assign dma_mem_tag_d[2:0] = dma_mem_tag[2:0];
334 : assign ldst_nodma_mtor = (lsu_pkt_m.valid & ~lsu_pkt_m.dma & (addr_in_dccm_m | addr_in_pic_m) & lsu_pkt_m.store);
335 :
336 : assign dccm_ready = ~(dec_lsu_valid_raw_d | ldst_nodma_mtor | ld_single_ecc_error_r_ff);
337 :
338 : assign dma_dccm_wen = dma_dccm_req & dma_mem_write & addr_in_dccm_d & dma_mem_sz[1]; // Perform DMA writes only for word/dword
339 : assign dma_pic_wen = dma_dccm_req & dma_mem_write & addr_in_pic_d;
340 : assign {dma_dccm_wdata_hi[31:0], dma_dccm_wdata_lo[31:0]} = 64'(dma_mem_wdata[63:0] >> {dma_mem_addr[2:0], 3'b000}); // Shift the dma data to lower bits to make it consistent to lsu stores
341 :
342 :
343 : // Generate per cycle flush signals
344 : assign flush_m_up = dec_tlu_flush_lower_r;
345 : assign flush_r = dec_tlu_i0_kill_writeb_r;
346 :
347 : // lsu idle
348 : // lsu halt idle. This is used for entering the halt mode. Also, DMA accesses are allowed during fence.
349 : // Indicates non-idle if there is a instruction valid in d-r or read/write buffers are non-empty since they can come with error
350 : // Store buffer now have only non-dma dccm stores
351 : // stbuf_empty not needed since it has only dccm stores
352 : assign lsu_idle_any = ~((lsu_pkt_m.valid & ~lsu_pkt_m.dma) |
353 : (lsu_pkt_r.valid & ~lsu_pkt_r.dma)) &
354 : lsu_bus_buffer_empty_any;
355 :
356 : assign lsu_active = (lsu_pkt_m.valid | lsu_pkt_r.valid | ld_single_ecc_error_r_ff) | ~lsu_bus_buffer_empty_any; // This includes DMA. Used for gating top clock
357 :
358 : // Instantiate the store buffer
359 : assign store_stbuf_reqvld_r = lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_dccm_r & ~flush_r & (~lsu_pkt_r.dma | ((lsu_pkt_r.by | lsu_pkt_r.half) & ~lsu_double_ecc_error_r));
360 :
361 : // Disable Forwarding for now
362 : assign lsu_cmpen_m = lsu_pkt_m.valid & (lsu_pkt_m.load | lsu_pkt_m.store) & (addr_in_dccm_m | addr_in_pic_m);
363 :
364 : // Bus signals
365 : assign lsu_busreq_m = lsu_pkt_m.valid & ((lsu_pkt_m.load | lsu_pkt_m.store) & addr_external_m) & ~flush_m_up & ~lsu_exc_m & ~lsu_pkt_m.fast_int;
366 :
367 : // Dual signals
368 : assign ldst_dual_d = (lsu_addr_d[2] != end_addr_d[2]);
369 : assign ldst_dual_m = (lsu_addr_m[2] != end_addr_m[2]);
370 : assign ldst_dual_r = (lsu_addr_r[2] != end_addr_r[2]);
371 :
372 : // PMU signals
373 : assign lsu_pmu_misaligned_m = lsu_pkt_m.valid & ((lsu_pkt_m.half & lsu_addr_m[0]) | (lsu_pkt_m.word & (|lsu_addr_m[1:0])));
374 : assign lsu_pmu_load_external_m = lsu_pkt_m.valid & lsu_pkt_m.load & addr_external_m;
375 : assign lsu_pmu_store_external_m = lsu_pkt_m.valid & lsu_pkt_m.store & addr_external_m;
376 :
377 : el2_lsu_dccm_ctl #(.pt(pt)) dccm_ctl (
378 : .lsu_addr_d(lsu_addr_d[31:0]),
379 : .end_addr_d(end_addr_d[pt.DCCM_BITS-1:0]),
380 : .lsu_addr_m(lsu_addr_m[pt.DCCM_BITS-1:0]),
381 : .lsu_addr_r(lsu_addr_r[31:0]),
382 :
383 : .end_addr_m(end_addr_m[pt.DCCM_BITS-1:0]),
384 : .end_addr_r(end_addr_r[pt.DCCM_BITS-1:0]),
385 : .*
386 : );
387 :
388 : el2_lsu_stbuf #(.pt(pt)) stbuf (
389 : .lsu_addr_d(lsu_addr_d[pt.LSU_SB_BITS-1:0]),
390 : .end_addr_d(end_addr_d[pt.LSU_SB_BITS-1:0]),
391 :
392 : .*
393 :
394 : );
395 :
396 : el2_lsu_ecc #(.pt(pt)) ecc (
397 : .lsu_addr_r(lsu_addr_r[pt.DCCM_BITS-1:0]),
398 : .end_addr_r(end_addr_r[pt.DCCM_BITS-1:0]),
399 : .lsu_addr_m(lsu_addr_m[pt.DCCM_BITS-1:0]),
400 : .end_addr_m(end_addr_m[pt.DCCM_BITS-1:0]),
401 : .*
402 : );
403 :
404 : el2_lsu_trigger #(.pt(pt)) trigger (
405 : .store_data_m(store_data_m[31:0]),
406 : .*
407 : );
408 :
409 : // Clk domain
410 : el2_lsu_clkdomain #(.pt(pt)) clkdomain (.*);
411 :
412 : // Bus interface
413 : el2_lsu_bus_intf #(.pt(pt)) bus_intf (
414 : .lsu_addr_m(lsu_addr_m[31:0] & {32{addr_external_m & lsu_pkt_m.valid}}),
415 : .lsu_addr_r(lsu_addr_r[31:0] & {32{lsu_busreq_r}}),
416 :
417 : .end_addr_m(end_addr_m[31:0] & {32{addr_external_m & lsu_pkt_m.valid}}),
418 : .end_addr_r(end_addr_r[31:0] & {32{lsu_busreq_r}}),
419 :
420 : .store_data_r(store_data_r[31:0] & {32{lsu_busreq_r}}),
421 : .*
422 : );
423 :
424 : //Flops
425 : rvdff #(3) dma_mem_tag_mff (.*, .din(dma_mem_tag_d[2:0]), .dout(dma_mem_tag_m[2:0]), .clk(lsu_c1_m_clk));
426 : rvdff #(2) lsu_raw_fwd_r_ff (.*, .din({lsu_raw_fwd_hi_m, lsu_raw_fwd_lo_m}), .dout({lsu_raw_fwd_hi_r, lsu_raw_fwd_lo_r}), .clk(lsu_c2_r_clk));
427 :
428 : `ifdef RV_ASSERT_ON
429 : logic [1:0] store_data_bypass_sel;
430 : assign store_data_bypass_sel[1:0] = {lsu_p.store_data_bypass_d, lsu_p.store_data_bypass_m};
431 :
432 : property exception_no_lsu_flush;
433 : @(posedge clk) disable iff(~rst_l) lsu_lsc_ctl.lsu_error_pkt_m.exc_valid |-> ##[1:2] (flush_r );
434 : endproperty
435 : assert_exception_no_lsu_flush: assert property (exception_no_lsu_flush) else
436 : $display("No flush within 2 cycles of exception");
437 :
438 : // offset should be zero for fast interrupt
439 : property offset_0_fastint;
440 : @(posedge clk) disable iff(~rst_l) (lsu_p.valid & lsu_p.fast_int) |-> (dec_lsu_offset_d[11:0] == 12'b0);
441 : endproperty
442 : assert_offset_0_fastint: assert property (offset_0_fastint) else
443 : $display("dec_tlu_offset_d not zero for fast interrupt redirect");
444 :
445 : // DMA req should assert dccm rden/wren
446 : property dmareq_dccm_wren_or_rden;
447 : @(posedge clk) disable iff(~rst_l) dma_dccm_req |-> (dccm_rden | dccm_wren | addr_in_pic_d);
448 : endproperty
449 : assert_dmareq_dccm_wren_or_rden: assert property(dmareq_dccm_wren_or_rden) else
450 : $display("dccm rden or wren not asserted during DMA request");
451 :
452 : // fastint_stall should cause load/store stall next cycle
453 : property fastint_stall_imply_loadstore_stall;
454 : @(posedge clk) disable iff(~rst_l) (lsu_fastint_stall_any & (lsu_commit_r | lsu_pkt_r.dma)) |-> ##1 ((lsu_load_stall_any | lsu_store_stall_any) | ~ld_single_ecc_error_r_ff);
455 : endproperty
456 : assert_fastint_stall_imply_loadstore_stall: assert property (fastint_stall_imply_loadstore_stall) else
457 : $display("fastint_stall should be followed by lsu_load/store_stall_any");
458 :
459 : // Single ECC error implies rfnpc flush
460 : property single_ecc_error_rfnpc_flush;
461 : @(posedge clk) disable iff(~rst_l) (lsu_error_pkt_r.single_ecc_error & lsu_pkt_r.load) |=> ~lsu_commit_r;
462 : endproperty
463 : assert_single_ecc_error_rfnpc_flush: assert property (single_ecc_error_rfnpc_flush) else
464 : $display("LSU commit next cycle after single ecc error");
465 :
466 : `endif
467 :
468 : endmodule // el2_lsu
|