Line Coverage for Module :
prim_ram_1p_adv
| Line No. | Total | Covered | Percent |
TOTAL | | 23 | 23 | 100.00 |
CONT_ASSIGN | 102 | 1 | 1 | 100.00 |
CONT_ASSIGN | 103 | 1 | 1 | 100.00 |
CONT_ASSIGN | 123 | 1 | 1 | 100.00 |
ALWAYS | 126 | 3 | 3 | 100.00 |
CONT_ASSIGN | 133 | 1 | 1 | 100.00 |
CONT_ASSIGN | 134 | 1 | 1 | 100.00 |
CONT_ASSIGN | 135 | 1 | 1 | 100.00 |
CONT_ASSIGN | 136 | 1 | 1 | 100.00 |
CONT_ASSIGN | 137 | 1 | 1 | 100.00 |
CONT_ASSIGN | 138 | 0 | 0 | |
CONT_ASSIGN | 147 | 1 | 1 | 100.00 |
CONT_ASSIGN | 156 | 1 | 1 | 100.00 |
CONT_ASSIGN | 248 | 0 | 0 | |
CONT_ASSIGN | 249 | 1 | 1 | 100.00 |
CONT_ASSIGN | 251 | 1 | 1 | 100.00 |
CONT_ASSIGN | 255 | 1 | 1 | 100.00 |
CONT_ASSIGN | 310 | 1 | 1 | 100.00 |
CONT_ASSIGN | 311 | 1 | 1 | 100.00 |
CONT_ASSIGN | 312 | 1 | 1 | 100.00 |
CONT_ASSIGN | 313 | 1 | 1 | 100.00 |
CONT_ASSIGN | 314 | 0 | 0 | |
CONT_ASSIGN | 353 | 1 | 1 | 100.00 |
CONT_ASSIGN | 354 | 1 | 1 | 100.00 |
CONT_ASSIGN | 356 | 0 | 0 | |
CONT_ASSIGN | 359 | 1 | 1 | 100.00 |
101
102 1/1 assign req_q_b = mubi4_test_true_loose(req_q);
Tests: T1 T2 T3
103 1/1 assign write_q_b = mubi4_test_true_loose(write_q);
Tests: T1 T2 T3
104
105 prim_ram_1p #(
106 .MemInitFile (MemInitFile),
107
108 .Width (TotalWidth),
109 .Depth (Depth),
110 .DataBitsPerMask (LocalDataBitsPerMask)
111 ) u_mem (
112 .clk_i,
113
114 .req_i (req_q_b),
115 .write_i (write_q_b),
116 .addr_i (addr_q),
117 .wdata_i (wdata_q),
118 .wmask_i (wmask_q),
119 .rdata_o (rdata_sram),
120 .cfg_i
121 );
122
123 1/1 assign rvalid_sram_d = mubi4_and_hi(req_q, mubi4_t'(~write_q));
Tests: T1 T2 T3
124
125 always_ff @(posedge clk_i or negedge rst_ni) begin
126 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
127 1/1 rvalid_sram_q <= MuBi4False;
Tests: T1 T2 T3
128 end else begin
129 1/1 rvalid_sram_q <= rvalid_sram_d;
Tests: T1 T2 T3
130 end
131 end
132
133 1/1 assign req_d = mubi4_bool_to_mubi(req_i);
Tests: T1 T2 T3
134 1/1 assign write_d = mubi4_bool_to_mubi(write_i);
Tests: T1 T2 T3
135 1/1 assign addr_d = addr_i;
Tests: T1 T2 T3
136 1/1 assign rvalid_o = mubi4_test_true_loose(rvalid_q);
Tests: T1 T2 T3
137 1/1 assign rdata_o = rdata_q;
Tests: T4 T5 T6
138 unreachable assign rerror_o = rerror_q;
139
140 prim_buf #(
141 .Width(MuBi4Width)
142 ) u_req_d_buf (
143 .in_i (req_d),
144 .out_o(req_buf_b_d)
145 );
146
147 1/1 assign req_buf_d = mubi4_t'(req_buf_b_d);
Tests: T1 T2 T3
148
149 prim_buf #(
150 .Width(MuBi4Width)
151 ) u_write_d_buf (
152 .in_i (write_d),
153 .out_o(write_buf_b_d)
154 );
155
156 1/1 assign write_buf_d = mubi4_t'(write_buf_b_d);
Tests: T1 T2 T3
157
158 /////////////////////////////
159 // ECC / Parity Generation //
160 /////////////////////////////
161
162 if (EnableParity == 0 && EnableECC) begin : gen_secded
163 logic unused_wmask;
164 assign unused_wmask = ^wmask_i;
165
166 // check supported widths
167 `ASSERT_INIT(SecDecWidth_A, Width inside {16, 32})
168
169 // the wmask is constantly set to 1 in this case
170 `ASSERT(OnlyWordWritePossibleWithEccPortA_A, req_i |->
171 wmask_i == {Width{1'b1}})
172
173 assign wmask_d = {TotalWidth{1'b1}};
174
175 if (Width == 16) begin : gen_secded_22_16
176 if (HammingECC) begin : gen_hamming
177 prim_secded_inv_hamming_22_16_enc u_enc (
178 .data_i(wdata_i),
179 .data_o(wdata_d)
180 );
181 prim_secded_inv_hamming_22_16_dec u_dec (
182 .data_i (rdata_sram),
183 .data_o (rdata_d[0+:Width]),
184 .syndrome_o ( ),
185 .err_o (rerror_d)
186 );
187 end else begin : gen_hsiao
188 prim_secded_inv_22_16_enc u_enc (
189 .data_i(wdata_i),
190 .data_o(wdata_d)
191 );
192 prim_secded_inv_22_16_dec u_dec (
193 .data_i (rdata_sram),
194 .data_o (rdata_d[0+:Width]),
195 .syndrome_o ( ),
196 .err_o (rerror_d)
197 );
198 end
199 end else if (Width == 32) begin : gen_secded_39_32
200 if (HammingECC) begin : gen_hamming
201 prim_secded_inv_hamming_39_32_enc u_enc (
202 .data_i(wdata_i),
203 .data_o(wdata_d)
204 );
205 prim_secded_inv_hamming_39_32_dec u_dec (
206 .data_i (rdata_sram),
207 .data_o (rdata_d[0+:Width]),
208 .syndrome_o ( ),
209 .err_o (rerror_d)
210 );
211 end else begin : gen_hsiao
212 prim_secded_inv_39_32_enc u_enc (
213 .data_i(wdata_i),
214 .data_o(wdata_d)
215 );
216 prim_secded_inv_39_32_dec u_dec (
217 .data_i (rdata_sram),
218 .data_o (rdata_d[0+:Width]),
219 .syndrome_o ( ),
220 .err_o (rerror_d)
221 );
222 end
223 end
224
225 end else if (EnableParity) begin : gen_byte_parity
226
227 `ASSERT_INIT(WidthNeedsToBeByteAligned_A, Width % 8 == 0)
228 `ASSERT_INIT(ParityNeedsByteWriteMask_A, DataBitsPerMask == 8)
229
230 always_comb begin : p_parity
231 rerror_d = '0;
232 for (int i = 0; i < Width/8; i ++) begin
233 // Data mapping. We have to make 8+1 = 9 bit groups
234 // that have the same write enable such that FPGA tools
235 // can map this correctly to BRAM resources.
236 wmask_d[i*9 +: 8] = wmask_i[i*8 +: 8];
237 wdata_d[i*9 +: 8] = wdata_i[i*8 +: 8];
238 rdata_d[i*8 +: 8] = rdata_sram[i*9 +: 8];
239
240 // parity generation (odd parity)
241 wdata_d[i*9 + 8] = ~(^wdata_i[i*8 +: 8]);
242 wmask_d[i*9 + 8] = &wmask_i[i*8 +: 8];
243 // parity decoding (errors are always uncorrectable)
244 rerror_d[1] |= ~(^{rdata_sram[i*9 +: 8], rdata_sram[i*9 + 8]});
245 end
246 end
247 end else begin : gen_nosecded_noparity
248 unreachable assign wmask_d = wmask_i;
249 1/1 assign wdata_d = wdata_i;
Tests: T1 T2 T3
250
251 1/1 assign rdata_d = rdata_sram[0+:Width];
Tests: T4 T5 T6
252 assign rerror_d = '0;
253 end
254
255 1/1 assign rvalid_d = rvalid_sram_q;
Tests: T1 T2 T3
256
257 /////////////////////////////////////
258 // Input/Output Pipeline Registers //
259 /////////////////////////////////////
260
261 if (EnableInputPipeline) begin : gen_regslice_input
262 // Put the register slices between ECC encoding to SRAM port
263
264 // If no ECC or parity is used, do not use prim_flop to allow synthesis
265 // tool to optimize the registers.
266 if (EnableECC || EnableParity) begin : gen_prim_flop
267 prim_flop #(
268 .Width(MuBi4Width),
269 .ResetValue(MuBi4Width'(MuBi4False))
270 ) u_write_flop (
271 .clk_i,
272 .rst_ni,
273 .d_i(MuBi4Width'(write_buf_d)),
274 .q_o({write_q})
275 );
276
277 prim_flop #(
278 .Width(MuBi4Width),
279 .ResetValue(MuBi4Width'(MuBi4False))
280 ) u_req_flop (
281 .clk_i,
282 .rst_ni,
283 .d_i(MuBi4Width'(req_buf_d)),
284 .q_o({req_q})
285 );
286 end else begin: gen_no_prim_flop
287 always_ff @(posedge clk_i or negedge rst_ni) begin
288 if (!rst_ni) begin
289 write_q <= MuBi4False;
290 req_q <= MuBi4False;
291 end else begin
292 write_q <= write_buf_d;
293 req_q <= req_buf_d;
294 end
295 end
296 end
297
298 always_ff @(posedge clk_i or negedge rst_ni) begin
299 if (!rst_ni) begin
300 addr_q <= '0;
301 wdata_q <= '0;
302 wmask_q <= '0;
303 end else begin
304 addr_q <= addr_d;
305 wdata_q <= wdata_d;
306 wmask_q <= wmask_d;
307 end
308 end
309 end else begin : gen_dirconnect_input
310 1/1 assign req_q = req_buf_d;
Tests: T1 T2 T3
311 1/1 assign write_q = write_buf_d;
Tests: T1 T2 T3
312 1/1 assign addr_q = addr_d;
Tests: T1 T2 T3
313 1/1 assign wdata_q = wdata_d;
Tests: T1 T2 T3
314 unreachable assign wmask_q = wmask_d;
315 end
316
317 if (EnableOutputPipeline) begin : gen_regslice_output
318 // Put the register slices between ECC decoding to output
319
320 // If no ECC or parity is used, do not use prim_flop to allow synthesis
321 // tool to optimize the registers.
322 if (EnableECC || EnableParity) begin : gen_prim_rvalid_flop
323 prim_flop #(
324 .Width(MuBi4Width),
325 .ResetValue(MuBi4Width'(MuBi4False))
326 ) u_rvalid_flop (
327 .clk_i,
328 .rst_ni,
329 .d_i(MuBi4Width'(rvalid_d)),
330 .q_o({rvalid_q})
331 );
332 end else begin: gen_no_prim_rvalid_flop
333 always_ff @(posedge clk_i or negedge rst_ni) begin
334 if (!rst_ni) begin
335 rvalid_q <= MuBi4False;
336 end else begin
337 rvalid_q <= rvalid_d;
338 end
339 end
340 end
341
342 always_ff @(posedge clk_i or negedge rst_ni) begin
343 if (!rst_ni) begin
344 rdata_q <= '0;
345 rerror_q <= '0;
346 end else begin
347 rdata_q <= rdata_d;
348 // tie to zero if the read data is not valid
349 rerror_q <= rerror_d & {2{mubi4_test_true_loose(rvalid_d)}};
350 end
351 end
352 end else begin : gen_dirconnect_output
353 1/1 assign rvalid_q = rvalid_d;
Tests: T1 T2 T3
354 1/1 assign rdata_q = rdata_d;
Tests: T4 T5 T6
355 // tie to zero if the read data is not valid
356 unreachable assign rerror_q = rerror_d & {2{mubi4_test_true_loose(rvalid_d)}};
357 end
358
359 1/1 assign alert_o = mubi4_test_invalid(req_q) | mubi4_test_invalid(write_q) |
Tests: T1 T2 T3
Branch Coverage for Module :
prim_ram_1p_adv
| Line No. | Total | Covered | Percent |
Branches |
|
2 |
2 |
100.00 |
IF |
126 |
2 |
2 |
100.00 |
126 if (!rst_ni) begin
-1-
127 rvalid_sram_q <= MuBi4False;
==>
128 end else begin
129 rvalid_sram_q <= rvalid_sram_d;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
Assert Coverage for Module :
prim_ram_1p_adv
Assertion Details
CannotHaveEccAndParity_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
1690 |
1690 |
0 |
0 |
T1 |
1 |
1 |
0 |
0 |
T2 |
1 |
1 |
0 |
0 |
T3 |
1 |
1 |
0 |
0 |
T4 |
1 |
1 |
0 |
0 |
T5 |
1 |
1 |
0 |
0 |
T6 |
1 |
1 |
0 |
0 |
T7 |
1 |
1 |
0 |
0 |
T8 |
1 |
1 |
0 |
0 |
T9 |
1 |
1 |
0 |
0 |
T10 |
1 |
1 |
0 |
0 |