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 : // Owner:
21 : // Function: lsu interface with interface queue
22 : // Comments:
23 : //
24 : //********************************************************************************
25 : module el2_lsu_bus_intf
26 : import el2_pkg::*;
27 : #(
28 : `include "el2_param.vh"
29 : )(
30 69840565 : input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
31 2 : input logic clk_override, // Override non-functional clock gating
32 338 : input logic rst_l, // reset, active low
33 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
34 : /*verilator coverage_off*/
35 : input logic scan_mode, // scan mode
36 : /*verilator coverage_on*/
37 0 : input logic dec_tlu_external_ldfwd_disable, // disable load to load forwarding for externals
38 6 : input logic dec_tlu_wb_coalescing_disable, // disable write buffer coalescing
39 322 : input logic dec_tlu_sideeffect_posted_disable, // disable the posted sideeffect load store to the bus
40 :
41 : // various clocks needed for the bus reads and writes
42 2048772 : input logic lsu_bus_obuf_c1_clken, // obuf clock enable
43 1087248 : input logic lsu_busm_clken, // bus clock enable
44 :
45 69840565 : input logic lsu_c1_r_clk, // r pipe single pulse clock
46 69840565 : input logic lsu_c2_r_clk, // r pipe double pulse clock
47 69840565 : input logic lsu_bus_ibuf_c1_clk, // ibuf single pulse clock
48 0 : input logic lsu_bus_obuf_c1_clk, // obuf single pulse clock
49 69840565 : input logic lsu_bus_buf_c1_clk, // buf single pulse clock
50 69840565 : input logic lsu_free_c2_clk, // free clock double pulse clock
51 69840565 : input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
52 0 : input logic lsu_busm_clk, // bus clock
53 :
54 2282093 : input logic dec_lsu_valid_raw_d, // Raw valid for address computation
55 1675428 : input logic lsu_busreq_m, // bus request is in m
56 :
57 477824 : input el2_lsu_pkt_t lsu_pkt_m, // lsu packet flowing down the pipe
58 477821 : input el2_lsu_pkt_t lsu_pkt_r, // lsu packet flowing down the pipe
59 :
60 349991 : input logic [31:0] lsu_addr_m, // lsu address flowing down the pipe
61 346180 : input logic [31:0] lsu_addr_r, // lsu address flowing down the pipe
62 :
63 350181 : input logic [31:0] end_addr_m, // lsu address flowing down the pipe
64 346364 : input logic [31:0] end_addr_r, // lsu address flowing down the pipe
65 :
66 54916 : input logic [31:0] store_data_r, // store data flowing down the pipe
67 0 : input logic dec_tlu_force_halt,
68 :
69 2285226 : input logic lsu_commit_r, // lsu instruction in r commits
70 36448 : input logic is_sideeffects_m, // lsu attribute is side_effects
71 59220 : input logic flush_m_up, // flush
72 29688 : input logic flush_r, // flush
73 36584 : input logic ldst_dual_d, ldst_dual_m, ldst_dual_r,
74 :
75 1665222 : output logic lsu_busreq_r, // bus request is in r
76 814960 : output logic lsu_bus_buffer_pend_any, // bus buffer has a pending bus entry
77 48802 : output logic lsu_bus_buffer_full_any, // write buffer is full
78 1193711 : output logic lsu_bus_buffer_empty_any, // write buffer is empty
79 200 : output logic [31:0] bus_read_data_m, // the bus return data
80 :
81 :
82 2 : output logic lsu_imprecise_error_load_any, // imprecise load bus error
83 2 : output logic lsu_imprecise_error_store_any, // imprecise store bus error
84 292 : output logic [31:0] lsu_imprecise_error_addr_any, // address of the imprecise error
85 :
86 : // Non-blocking loads
87 880628 : output logic lsu_nonblock_load_valid_m, // there is an external load -> put in the cam
88 504631 : output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // the tag of the external non block load
89 0 : output logic lsu_nonblock_load_inv_r, // invalidate signal for the cam entry for non block loads
90 504628 : output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // tag of the enrty which needs to be invalidated
91 919880 : output logic lsu_nonblock_load_data_valid,// the non block is valid - sending information back to the cam
92 2 : output logic lsu_nonblock_load_data_error,// non block load has an error
93 36606 : 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
94 71598 : output logic [31:0] lsu_nonblock_load_data, // Data of the non block load
95 :
96 : // PMU events
97 1673139 : output logic lsu_pmu_bus_trxn,
98 36422 : output logic lsu_pmu_bus_misaligned,
99 4 : output logic lsu_pmu_bus_error,
100 67742 : output logic lsu_pmu_bus_busy,
101 :
102 : // AXI Write Channels
103 861975 : output logic lsu_axi_awvalid,
104 1114135 : input logic lsu_axi_awready,
105 0 : output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_awid,
106 292 : output logic [31:0] lsu_axi_awaddr,
107 336 : output logic [3:0] lsu_axi_awregion,
108 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
109 : /*verilator coverage_off*/
110 : output logic [7:0] lsu_axi_awlen,
111 : /*verilator coverage_on*/
112 0 : output logic [2:0] lsu_axi_awsize,
113 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
114 : /*verilator coverage_off*/
115 : output logic [1:0] lsu_axi_awburst,
116 : output logic lsu_axi_awlock,
117 : /*verilator coverage_on*/
118 3029 : output logic [3:0] lsu_axi_awcache,
119 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
120 : /*verilator coverage_off*/
121 : output logic [2:0] lsu_axi_awprot,
122 : output logic [3:0] lsu_axi_awqos,
123 : /*verilator coverage_on*/
124 :
125 861975 : output logic lsu_axi_wvalid,
126 1114135 : input logic lsu_axi_wready,
127 31427 : output logic [63:0] lsu_axi_wdata,
128 224869 : output logic [7:0] lsu_axi_wstrb,
129 339 : output logic lsu_axi_wlast,
130 :
131 875196 : input logic lsu_axi_bvalid,
132 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
133 : /*verilator coverage_off*/
134 : output logic lsu_axi_bready,
135 : /*verilator coverage_on*/
136 2 : input logic [1:0] lsu_axi_bresp,
137 0 : input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid,
138 :
139 : // AXI Read Channels
140 867946 : output logic lsu_axi_arvalid,
141 1114471 : input logic lsu_axi_arready,
142 0 : output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_arid,
143 292 : output logic [31:0] lsu_axi_araddr,
144 336 : output logic [3:0] lsu_axi_arregion,
145 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
146 : /*verilator coverage_off*/
147 : output logic [7:0] lsu_axi_arlen,
148 : /*verilator coverage_on*/
149 0 : output logic [2:0] lsu_axi_arsize,
150 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
151 : /*verilator coverage_off*/
152 : output logic [1:0] lsu_axi_arburst,
153 : output logic lsu_axi_arlock,
154 : /*verilator coverage_on*/
155 3029 : output logic [3:0] lsu_axi_arcache,
156 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
157 : /*verilator coverage_off*/
158 : output logic [2:0] lsu_axi_arprot,
159 : output logic [3:0] lsu_axi_arqos,
160 : /*verilator coverage_on*/
161 :
162 928708 : input logic lsu_axi_rvalid,
163 : /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */
164 : /*verilator coverage_off*/
165 : output logic lsu_axi_rready,
166 : /*verilator coverage_on*/
167 0 : input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid,
168 28820 : input logic [63:0] lsu_axi_rdata,
169 2 : input logic [1:0] lsu_axi_rresp,
170 :
171 338 : input logic lsu_bus_clk_en
172 :
173 : );
174 :
175 :
176 :
177 338 : logic lsu_bus_clk_en_q;
178 :
179 8193 : logic [3:0] ldst_byteen_m, ldst_byteen_r;
180 0 : logic [7:0] ldst_byteen_ext_m, ldst_byteen_ext_r;
181 0 : logic [3:0] ldst_byteen_hi_m, ldst_byteen_hi_r;
182 430861 : logic [3:0] ldst_byteen_lo_m, ldst_byteen_lo_r;
183 36426 : logic is_sideeffects_r;
184 :
185 125006 : logic [63:0] store_data_ext_r;
186 1948 : logic [31:0] store_data_hi_r;
187 63470 : logic [31:0] store_data_lo_r;
188 :
189 1707011 : logic addr_match_dw_lo_r_m;
190 1665415 : logic addr_match_word_lo_r_m;
191 98672 : logic no_word_merge_r, no_dword_merge_r;
192 :
193 654 : logic ld_addr_rhit_lo_lo, ld_addr_rhit_hi_lo, ld_addr_rhit_lo_hi, ld_addr_rhit_hi_hi;
194 0 : logic [3:0] ld_byte_rhit_lo_lo, ld_byte_rhit_hi_lo, ld_byte_rhit_lo_hi, ld_byte_rhit_hi_hi;
195 :
196 56 : logic [3:0] ld_byte_hit_lo, ld_byte_rhit_lo;
197 0 : logic [3:0] ld_byte_hit_hi, ld_byte_rhit_hi;
198 :
199 16 : logic [31:0] ld_fwddata_rpipe_lo;
200 0 : logic [31:0] ld_fwddata_rpipe_hi;
201 :
202 0 : logic [3:0] ld_byte_hit_buf_lo, ld_byte_hit_buf_hi;
203 74 : logic [31:0] ld_fwddata_buf_lo, ld_fwddata_buf_hi;
204 :
205 74 : logic [63:0] ld_fwddata_lo, ld_fwddata_hi;
206 804 : logic [63:0] ld_fwddata_m;
207 :
208 5732 : logic ld_full_hit_hi_m, ld_full_hit_lo_m;
209 10312 : logic ld_full_hit_m;
210 :
211 : assign ldst_byteen_m[3:0] = ({4{lsu_pkt_m.by}} & 4'b0001) |
212 : ({4{lsu_pkt_m.half}} & 4'b0011) |
213 : ({4{lsu_pkt_m.word}} & 4'b1111);
214 :
215 : // Read/Write Buffer
216 : el2_lsu_bus_buffer #(.pt(pt)) bus_buffer (
217 : .*
218 : );
219 :
220 : // Logic to determine if dc5 store can be coalesced or not with younger stores. Bypass ibuf if cannot colaesced
221 : assign addr_match_dw_lo_r_m = (lsu_addr_r[31:3] == lsu_addr_m[31:3]);
222 : assign addr_match_word_lo_r_m = addr_match_dw_lo_r_m & ~(lsu_addr_r[2]^lsu_addr_m[2]);
223 :
224 : assign no_word_merge_r = lsu_busreq_r & ~ldst_dual_r & lsu_busreq_m & (lsu_pkt_m.load | ~addr_match_word_lo_r_m);
225 : assign no_dword_merge_r = lsu_busreq_r & ~ldst_dual_r & lsu_busreq_m & (lsu_pkt_m.load | ~addr_match_dw_lo_r_m);
226 :
227 : // Create Hi/Lo signals
228 : assign ldst_byteen_ext_m[7:0] = {4'b0,ldst_byteen_m[3:0]} << lsu_addr_m[1:0];
229 : assign ldst_byteen_ext_r[7:0] = {4'b0,ldst_byteen_r[3:0]} << lsu_addr_r[1:0];
230 :
231 : assign store_data_ext_r[63:0] = {32'b0,store_data_r[31:0]} << {lsu_addr_r[1:0],3'b0};
232 :
233 : assign ldst_byteen_hi_m[3:0] = ldst_byteen_ext_m[7:4];
234 : assign ldst_byteen_lo_m[3:0] = ldst_byteen_ext_m[3:0];
235 : assign ldst_byteen_hi_r[3:0] = ldst_byteen_ext_r[7:4];
236 : assign ldst_byteen_lo_r[3:0] = ldst_byteen_ext_r[3:0];
237 :
238 : assign store_data_hi_r[31:0] = store_data_ext_r[63:32];
239 : assign store_data_lo_r[31:0] = store_data_ext_r[31:0];
240 :
241 : assign ld_addr_rhit_lo_lo = (lsu_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
242 : assign ld_addr_rhit_lo_hi = (end_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
243 : assign ld_addr_rhit_hi_lo = (lsu_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
244 : assign ld_addr_rhit_hi_hi = (end_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r;
245 :
246 : for (genvar i=0; i<4; i++) begin: GenBusBufFwd
247 : assign ld_byte_rhit_lo_lo[i] = ld_addr_rhit_lo_lo & ldst_byteen_lo_r[i] & ldst_byteen_lo_m[i];
248 : assign ld_byte_rhit_lo_hi[i] = ld_addr_rhit_lo_hi & ldst_byteen_lo_r[i] & ldst_byteen_hi_m[i];
249 : assign ld_byte_rhit_hi_lo[i] = ld_addr_rhit_hi_lo & ldst_byteen_hi_r[i] & ldst_byteen_lo_m[i];
250 : assign ld_byte_rhit_hi_hi[i] = ld_addr_rhit_hi_hi & ldst_byteen_hi_r[i] & ldst_byteen_hi_m[i];
251 :
252 : assign ld_byte_hit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i] |
253 : ld_byte_hit_buf_lo[i];
254 :
255 : assign ld_byte_hit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i] |
256 : ld_byte_hit_buf_hi[i];
257 :
258 : assign ld_byte_rhit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i];
259 : assign ld_byte_rhit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i];
260 :
261 : assign ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_lo[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) |
262 : ({8{ld_byte_rhit_hi_lo[i]}} & store_data_hi_r[(8*i)+7:(8*i)]);
263 :
264 : assign ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_hi[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) |
265 : ({8{ld_byte_rhit_hi_hi[i]}} & store_data_hi_r[(8*i)+7:(8*i)]);
266 :
267 : // Final muxing between m/r
268 : assign ld_fwddata_lo[(8*i)+7:(8*i)] = ld_byte_rhit_lo[i] ? ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] : ld_fwddata_buf_lo[(8*i)+7:(8*i)];
269 :
270 : assign ld_fwddata_hi[(8*i)+7:(8*i)] = ld_byte_rhit_hi[i] ? ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] : ld_fwddata_buf_hi[(8*i)+7:(8*i)];
271 :
272 : end
273 :
274 339 : always_comb begin
275 339 : ld_full_hit_lo_m = 1'b1;
276 339 : ld_full_hit_hi_m = 1'b1;
277 339 : for (int i=0; i<4; i++) begin
278 1356 : ld_full_hit_lo_m &= (ld_byte_hit_lo[i] | ~ldst_byteen_lo_m[i]);
279 1356 : ld_full_hit_hi_m &= (ld_byte_hit_hi[i] | ~ldst_byteen_hi_m[i]);
280 : end
281 : end
282 :
283 : // This will be high if all the bytes of load hit the stores in pipe/write buffer (m/r/wrbuf)
284 : assign ld_full_hit_m = ld_full_hit_lo_m & ld_full_hit_hi_m & lsu_busreq_m & lsu_pkt_m.load & ~is_sideeffects_m;
285 :
286 : assign ld_fwddata_m[63:0] = 64'({ld_fwddata_hi[31:0], ld_fwddata_lo[31:0]} >> (8*lsu_addr_m[1:0]));
287 : assign bus_read_data_m[31:0] = ld_fwddata_m[31:0];
288 :
289 : // Fifo flops
290 :
291 : rvdff #(.WIDTH(1)) clken_ff (.din(lsu_bus_clk_en), .dout(lsu_bus_clk_en_q), .clk(active_clk), .*);
292 :
293 : rvdff #(.WIDTH(1)) is_sideeffects_rff (.din(is_sideeffects_m), .dout(is_sideeffects_r), .clk(lsu_c1_r_clk), .*);
294 :
295 : rvdff #(4) lsu_byten_rff (.*, .din(ldst_byteen_m[3:0]), .dout(ldst_byteen_r[3:0]), .clk(lsu_c1_r_clk));
296 :
297 : `ifdef RV_ASSERT_ON
298 :
299 : // Assertion to check AXI write address is aligned to size
300 : property lsu_axi_awaddr_aligned;
301 : @(posedge lsu_busm_clk) disable iff(~rst_l) lsu_axi_awvalid |-> ((lsu_axi_awsize[2:0] == 3'h0) |
302 : ((lsu_axi_awsize[2:0] == 3'h1) & (lsu_axi_awaddr[0] == 1'b0)) |
303 : ((lsu_axi_awsize[2:0] == 3'h2) & (lsu_axi_awaddr[1:0] == 2'b0)) |
304 : ((lsu_axi_awsize[2:0] == 3'h3) & (lsu_axi_awaddr[2:0] == 3'b0)));
305 : endproperty
306 : assert_lsu_axi_awaddr_aligned: assert property (lsu_axi_awaddr_aligned) else
307 : $display("Assertion lsu_axi_awaddr_aligned failed: lsu_axi_awvalid=1'b%b, lsu_axi_awsize=3'h%h, lsu_axi_awaddr=32'h%h",lsu_axi_awvalid, lsu_axi_awsize[2:0], lsu_axi_awaddr[31:0]);
308 : // Assertion to check awvalid stays stable during entire bus clock
309 :
310 : // Assertion to check AXI read address is aligned to size
311 : property lsu_axi_araddr_aligned;
312 : @(posedge lsu_busm_clk) disable iff(~rst_l) lsu_axi_arvalid |-> ((lsu_axi_arsize[2:0] == 3'h0) |
313 : ((lsu_axi_arsize[2:0] == 3'h1) & (lsu_axi_araddr[0] == 1'b0)) |
314 : ((lsu_axi_arsize[2:0] == 3'h2) & (lsu_axi_araddr[1:0] == 2'b0)) |
315 : ((lsu_axi_arsize[2:0] == 3'h3) & (lsu_axi_araddr[2:0] == 3'b0)));
316 : endproperty
317 : assert_lsu_axi_araddr_aligned: assert property (lsu_axi_araddr_aligned) else
318 : $display("Assertion lsu_axi_araddr_aligned failed: lsu_axi_awvalid=1'b%b, lsu_axi_awsize=3'h%h, lsu_axi_araddr=32'h%h",lsu_axi_awvalid, lsu_axi_awsize[2:0], lsu_axi_araddr[31:0]);
319 :
320 : // Assertion to check awvalid stays stable during entire bus clock
321 : property lsu_axi_awvalid_stable;
322 : @(posedge clk) disable iff(~rst_l) (lsu_axi_awvalid != $past(lsu_axi_awvalid)) |-> ($past(lsu_bus_clk_en) | dec_tlu_force_halt);
323 : endproperty
324 : assert_lsu_axi_awvalid_stable: assert property (lsu_axi_awvalid_stable) else
325 : $display("LSU AXI awvalid changed in middle of bus clock");
326 :
327 : // Assertion to check awid stays stable during entire bus clock
328 : property lsu_axi_awid_stable;
329 : @(posedge clk) disable iff(~rst_l) (lsu_axi_awvalid & (lsu_axi_awid[pt.LSU_BUS_TAG-1:0] != $past(lsu_axi_awid[pt.LSU_BUS_TAG-1:0]))) |-> $past(lsu_bus_clk_en);
330 : endproperty
331 : assert_lsu_axi_awid_stable: assert property (lsu_axi_awid_stable) else
332 : $display("LSU AXI awid changed in middle of bus clock");
333 :
334 : // Assertion to check awaddr stays stable during entire bus clock
335 : property lsu_axi_awaddr_stable;
336 : @(posedge clk) disable iff(~rst_l) (lsu_axi_awvalid & (lsu_axi_awaddr[31:0] != $past(lsu_axi_awaddr[31:0]))) |-> $past(lsu_bus_clk_en);
337 : endproperty
338 : assert_lsu_axi_awaddr_stable: assert property (lsu_axi_awaddr_stable) else
339 : $display("LSU AXI awaddr changed in middle of bus clock");
340 :
341 : // Assertion to check awsize stays stable during entire bus clock
342 : property lsu_axi_awsize_stable;
343 : @(posedge clk) disable iff(~rst_l) (lsu_axi_awvalid & (lsu_axi_awsize[2:0] != $past(lsu_axi_awsize[2:0]))) |-> $past(lsu_bus_clk_en);
344 : endproperty
345 : assert_lsu_axi_awsize_stable: assert property (lsu_axi_awsize_stable) else
346 : $display("LSU AXI awsize changed in middle of bus clock");
347 :
348 : // Assertion to check wstrb stays stable during entire bus clock
349 : property lsu_axi_wstrb_stable;
350 : @(posedge clk) disable iff(~rst_l) (lsu_axi_wvalid & (lsu_axi_wstrb[7:0] != $past(lsu_axi_wstrb[7:0]))) |-> $past(lsu_bus_clk_en);
351 : endproperty
352 : assert_lsu_axi_wstrb_stable: assert property (lsu_axi_wstrb_stable) else
353 : $display("LSU AXI wstrb changed in middle of bus clock");
354 :
355 : // Assertion to check wdata stays stable during entire bus clock
356 : property lsu_axi_wdata_stable;
357 : @(posedge clk) disable iff(~rst_l) (lsu_axi_wvalid & (lsu_axi_wdata[63:0] != $past(lsu_axi_wdata[63:0]))) |-> $past(lsu_bus_clk_en);
358 : endproperty
359 : assert_lsu_axi_wdata_stable: assert property (lsu_axi_wdata_stable) else
360 : $display("LSU AXI wdata changed in middle of bus clock");
361 :
362 : // Assertion to check awvalid stays stable during entire bus clock
363 : property lsu_axi_arvalid_stable;
364 : @(posedge clk) disable iff(~rst_l) (lsu_axi_arvalid != $past(lsu_axi_arvalid)) |-> ($past(lsu_bus_clk_en) | dec_tlu_force_halt);
365 : endproperty
366 : assert_lsu_axi_arvalid_stable: assert property (lsu_axi_arvalid_stable) else
367 : $display("LSU AXI awvalid changed in middle of bus clock");
368 :
369 : // Assertion to check awid stays stable during entire bus clock
370 : property lsu_axi_arid_stable;
371 : @(posedge clk) disable iff(~rst_l) (lsu_axi_arvalid & (lsu_axi_arid[pt.LSU_BUS_TAG-1:0] != $past(lsu_axi_arid[pt.LSU_BUS_TAG-1:0]))) |-> $past(lsu_bus_clk_en);
372 : endproperty
373 : assert_lsu_axi_arid_stable: assert property (lsu_axi_arid_stable) else
374 : $display("LSU AXI awid changed in middle of bus clock");
375 :
376 : // Assertion to check awaddr stays stable during entire bus clock
377 : property lsu_axi_araddr_stable;
378 : @(posedge clk) disable iff(~rst_l) (lsu_axi_arvalid & (lsu_axi_araddr[31:0] != $past(lsu_axi_araddr[31:0]))) |-> $past(lsu_bus_clk_en);
379 : endproperty
380 : assert_lsu_axi_araddr_stable: assert property (lsu_axi_araddr_stable) else
381 : $display("LSU AXI awaddr changed in middle of bus clock");
382 :
383 : // Assertion to check awsize stays stable during entire bus clock
384 : property lsu_axi_arsize_stable;
385 : @(posedge clk) disable iff(~rst_l) (lsu_axi_awvalid & (lsu_axi_arsize[2:0] != $past(lsu_axi_arsize[2:0]))) |-> $past(lsu_bus_clk_en);
386 : endproperty
387 : assert_lsu_axi_arsize_stable: assert property (lsu_axi_arsize_stable) else
388 : $display("LSU AXI awsize changed in middle of bus clock");
389 :
390 : `endif
391 :
392 : endmodule // el2_lsu_bus_intf
|