Go
back
240 always_ff @(posedge clk_i or negedge rst_ni) begin
241 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
242 1/1 non_zero_wait_timer_limit <= '0;
Tests: T1 T2 T3
243 1/1 end else if (timer_update) begin
Tests: T1 T2 T3
244 1/1 non_zero_wait_timer_limit <= |wait_timer_limit_i;
Tests: T2 T11 T9
245 end
MISSING_ELSE
246 end
247
248 logic [TimerPrescalerW-1:0] wait_timer_prescaler_d;
249 always_ff @(posedge clk_i or negedge rst_ni) begin
250 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
251 1/1 wait_timer_prescaler_d <= '0;
Tests: T1 T2 T3
252 1/1 end else if (timer_update) begin
Tests: T1 T2 T3
253 1/1 wait_timer_prescaler_d <= wait_timer_prescaler_i;
Tests: T2 T11 T9
254 end
MISSING_ELSE
255 end
256
257 // Timers ===================================================================
258 always_ff @(posedge clk_i or negedge rst_ni) begin
259 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
260 1/1 timer_value <= '0;
Tests: T1 T2 T3
261 1/1 end else if (timer_update) begin
Tests: T1 T2 T3
262 1/1 timer_value <= timer_limit;
Tests: T2 T11 T9
263 1/1 end else if (timer_expired) begin
Tests: T1 T2 T3
264 1/1 timer_value <= '0; // keep the value
Tests: T1 T2 T3
265 1/1 end else if (timer_enable && timer_pulse && |timer_value) begin // if non-zero timer v
Tests: T1 T2 T3
266 1/1 timer_value <= timer_value - 1'b 1;
Tests: T53 T90 T91
267 end
MISSING_ELSE
268 end
269
270 1/1 assign timer_limit = TimerW'(wait_timer_limit_i);
Tests: T1 T2 T3
271
272 always_ff @(posedge clk_i or negedge rst_ni) begin
273 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
274 1/1 timer_expired <= 1'b 0;
Tests: T1 T2 T3
275 1/1 end else if (timer_update) begin
Tests: T1 T2 T3
276 1/1 timer_expired <= 1'b 0;
Tests: T2 T11 T9
277 1/1 end else if (timer_enable && (timer_value == '0)) begin
Tests: T1 T2 T3
278 1/1 timer_expired <= 1'b 1;
Tests: T1 T2 T3
279 end
MISSING_ELSE
280 end
281
282 // Prescaler
283 always_ff @(posedge clk_i or negedge rst_ni) begin
284 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
285 1/1 prescaler_cnt <= '0;
Tests: T1 T2 T3
286 1/1 end else if (timer_update) begin
Tests: T1 T2 T3
287 1/1 prescaler_cnt <= wait_timer_prescaler_i;
Tests: T2 T11 T9
288 1/1 end else if (timer_enable && prescaler_cnt == '0) begin
Tests: T1 T2 T3
289 1/1 prescaler_cnt <= wait_timer_prescaler_d;
Tests: T1 T2 T3
290 1/1 end else if (timer_enable) begin
Tests: T1 T2 T3
291 1/1 prescaler_cnt <= prescaler_cnt - 1'b 1;
Tests: T2 T11 T9
292 end
MISSING_ELSE
293 end
294
295 1/1 assign timer_pulse = (timer_enable && prescaler_cnt == '0);
Tests: T1 T2 T3
296 // Timers -------------------------------------------------------------------
297
298 // Hash Counter
299 logic threshold_hit;
300 logic threshold_hit_q, threshold_hit_clr; // latched hit
301
302 logic hash_progress_d, hash_progress_q;
303 always_ff @(posedge clk_i or negedge rst_ni) begin
304 2/2 if (!rst_ni) hash_progress_q <= 1'b 0;
Tests: T1 T2 T3 | T1 T2 T3
305 1/1 else hash_progress_q <= hash_progress_d;
Tests: T1 T2 T3
306 end
307
308 1/1 assign hash_progress_d = in_keyblock_i;
Tests: T1 T2 T3
309
310 logic hash_cnt_clr;
311 1/1 assign hash_cnt_clr = hash_cnt_clr_i || threshold_hit || entropy_refresh_req_i;
Tests: T1 T2 T3
312
313 logic hash_cnt_en;
314 1/1 assign hash_cnt_en = hash_progress_q && !hash_progress_d;
Tests: T1 T2 T3
315
316 logic hash_count_error;
317
318 // SEC_CM CTR.REDUN
319 // This primitive is used to place a hardened counter
320 prim_count #(
321 .Width(HashCntW)
322 ) u_hash_count (
323 .clk_i,
324 .rst_ni,
325 .clr_i(hash_cnt_clr),
326 .set_i(1'b0),
327 .set_cnt_i(HashCntW'(0)),
328 .incr_en_i(hash_cnt_en),
329 .decr_en_i(1'b0),
330 .step_i(HashCntW'(1)),
331 .commit_i(1'b1),
332 .cnt_o(hash_cnt_o),
333 .cnt_after_commit_o(),
334 .err_o(hash_count_error)
335 );
336
337 1/1 assign threshold_hit = |hash_threshold_i && (hash_threshold_i <= hash_cnt_o);
Tests: T1 T2 T3
338
339 always_ff @(posedge clk_i or negedge rst_ni) begin
340 2/2 if (!rst_ni) threshold_hit_q <= 1'b 0;
Tests: T1 T2 T3 | T1 T2 T3
341 2/2 else if (threshold_hit_clr) threshold_hit_q <= 1'b 0;
Tests: T1 T2 T3 | T95 T96 T97
342 2/2 else if (threshold_hit) threshold_hit_q <= 1'b 1;
Tests: T1 T2 T3 | T15 T96 T98
MISSING_ELSE
343 end
344
345 always_ff @(posedge clk_i or negedge rst_ni) begin
346 2/2 if (!rst_ni) mode_q <= EntropyModeNone;
Tests: T1 T2 T3 | T1 T2 T3
347 2/2 else if (mode_latch) mode_q <= mode_i;
Tests: T1 T2 T3 | T1 T2 T3
MISSING_ELSE
348 end
349
350 // PRNG primitive ===========================================================
351
352 `ASSERT_KNOWN(ModeKnown_A, mode_i)
353 1/1 assign seed = (mode_q == EntropyModeSw) ? seed_data_i : entropy_data_i;
Tests: T1 T2 T3
354
355 // We employ a single unrolled Bivium stream cipher primitive to generate
356 // 800 bits per clock cycle.
357 prim_trivium #(
358 .BiviumVariant (1),
359 .OutputWidth (EntropyOutputW),
360 .StrictLockupProtection(1),
361 .SeedType (prim_trivium_pkg::SeedTypeStatePartial),
362 .PartialSeedWidth (edn_pkg::ENDPOINT_BUS_WIDTH),
363 .RndCnstTriviumLfsrSeed(RndCnstLfsrSeed)
364 ) u_prim_trivium (
365 .clk_i (clk_i),
366 .rst_ni(rst_ni),
367
368 .en_i (prng_en || msg_mask_en_i),
369 .allow_lockup_i ('0), // Not used.
370 .seed_en_i (seed_en),
371 .seed_done_o (seed_done),
372 .seed_req_o (seed_req),
373 .seed_ack_i (seed_ack),
374 .seed_key_i ('0), // Not used.
375 .seed_iv_i ('0), // Not used.
376 .seed_state_full_i ('0), // Not used.
377 .seed_state_partial_i(seed),
378
379 .key_o(prng_data),
380 .err_o()
381 );
382
383 // Add a permutation layer to obfuscate the output of the PRNG primitive.
384 for (genvar i = 0; i < EntropyOutputW; i++) begin : gen_perm
385 800/800 assign prng_data_permuted[i] = prng_data[RndCnstLfsrPerm[i]];
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
386 end
387
388 // Buffer stage to prevent glitches happening inside the PRNG primitive from
389 // propagating into the masked processing core.
390 always_ff @(posedge clk_i or negedge rst_ni) begin
391 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
392 1/1 rand_data_q <= RndCnstBufferLfsrSeed;
Tests: T1 T2 T3
393 1/1 end else if (data_update || msg_mask_en_i) begin
Tests: T1 T2 T3
394 1/1 rand_data_q <= prng_data_permuted;
Tests: T1 T2 T3
395 end
MISSING_ELSE
396 end
397
398 // Forwrad LSBs for masking the message.
399 1/1 assign msg_mask_o = rand_data_q[MsgWidth-1:0];
Tests: T1 T2 T3
400
401 // PRNG primitive ----------------------------------------------------------
402
403 // Auxiliary randomness =====================================================
404 1/1 assign aux_rand_d = aux_update ? rand_data_q[EntropyOutputW - 1] :
Tests: T1 T2 T3
405 aux_rand_q;
406 always_ff @(posedge clk_i or negedge rst_ni) begin
407 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
408 1/1 aux_rand_q <= '0;
Tests: T1 T2 T3
409 end else begin
410 1/1 aux_rand_q <= aux_rand_d;
Tests: T1 T2 T3
411 end
412 end
413
414 // Auxiliary randomness -----------------------------------------------------
415
416 // PRNG enable randomness ===================================================
417 1/1 assign prng_en_rand_d =
Tests: T1 T2 T3
418 aux_update ? rand_data_q[EntropyOutputW - 2 -: 4] : // refresh
419 {1'b0, prng_en_rand_q[3:1]}; // shift out
420
421 always_ff @(posedge clk_i or negedge rst_ni) begin
422 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
423 1/1 prng_en_rand_q <= '0;
Tests: T1 T2 T3
424 end else begin
425 1/1 prng_en_rand_q <= prng_en_rand_d;
Tests: T1 T2 T3
426 end
427 end
428
429 // PRNG enable randomness ---------------------------------------------------
430
431 // Randomness outputs =======================================================
432 1/1 assign rand_data_o = rand_data_q;
Tests: T1 T2 T3
433 1/1 assign rand_aux_o = aux_rand_q;
Tests: T1 T2 T3
434
435 // entropy valid
436 always_ff @(posedge clk_i or negedge rst_ni) begin
437 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
438 1/1 rand_valid_o <= 1'b 0;
Tests: T1 T2 T3
439 1/1 end else if (rand_valid_set) begin
Tests: T1 T2 T3
440 1/1 rand_valid_o <= 1'b 1;
Tests: T1 T2 T3
441 1/1 end else if (rand_valid_clear) begin
Tests: T1 T2 T3
442 1/1 rand_valid_o <= 1'b 0;
Tests: T1 T2 T3
443 end
MISSING_ELSE
444 end
445
446 // Let consumers know that the randomness will be valid in the next clock cycle.
447 1/1 assign rand_early_o = rand_valid_set;
Tests: T1 T2 T3
448
449 // The Keccak core is not supposed to ever consume randomness unless it's marked
450 // as valid. The only exception is if the reseeding of the PRNG just finished
451 // in the previous clock cycle. Because it's possible for the randomness to stay
452 // valid throughout the reseeding (the valid is for sure de-asserted at the end).
453 // The Keccak core may base its decision to start processing / consuming entropy
454 // before the valid is de-asserted. If this happens, the current buffer output
455 // might be used for both remasking and as auxiliary randomness which isn't ideal
456 // but given this happens only very rarely it should be okay.
457 `ASSUME(ConsumeNotAssertWhenNotValid_M,
458 rand_update_i | rand_consumed_i |-> rand_valid_o || $past(seed_done))
459
460 // Upon escalation or in case the EDN wait timer expires the entropy_req signal
461 // can be dropped before getting acknowledged. This may leave EDN in a strange
462 // state. We thus hold the request until it's actually acknowledged. In case the
463 // request is acknowledged while the FSM is in the StRandErr already, the
464 // incoming entropy is simply dropped.
465 1/1 assign entropy_req_o = entropy_req | entropy_req_hold_q;
Tests: T1 T2 T3
466 1/1 assign entropy_req_hold_d = (entropy_req_hold_q | entropy_req) & ~entropy_ack_i;
Tests: T1 T2 T3
467 always_ff @(posedge clk_i or negedge rst_ni) begin
468 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
469 1/1 entropy_req_hold_q <= '0;
Tests: T1 T2 T3
470 end else begin
471 1/1 entropy_req_hold_q <= entropy_req_hold_d;
Tests: T1 T2 T3
472 end
473 end
474
475 // Randomness outputs -------------------------------------------------------
476
477 // Remaining outputs
478 1/1 assign count_error_o = hash_count_error;
Tests: T1 T2 T3
479
480 ///////////////////
481 // State Machine //
482 ///////////////////
483
484 rand_st_e st, st_d;
485
486 // State FF
487 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, st_d, st, rand_st_e, StRandReset)
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
PRIM_FLOP_SPARSE_FSM(u_state_regs, st_d, st, rand_st_e, StRandReset):
487.1 `ifdef SIMULATION
487.2 prim_sparse_fsm_flop #(
487.3 .StateEnumT(rand_st_e),
487.4 .Width($bits(rand_st_e)),
487.5 .ResetValue($bits(rand_st_e)'(StRandReset)),
487.6 .EnableAlertTriggerSVA(1),
487.7 .CustomForceName("st")
487.8 ) u_state_regs (
487.9 .clk_i ( clk_i ),
487.10 .rst_ni ( rst_ni ),
487.11 .state_i ( st_d ),
487.12 .state_o ( )
487.13 );
487.14 always_ff @(posedge clk_i or negedge rst_ni) begin
487.15 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
487.16 1/1 st <= StRandReset;
Tests: T1 T2 T3
487.17 end else begin
487.18 1/1 st <= st_d;
Tests: T1 T2 T3
487.19 end
487.20 end
487.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (st === u_state_regs.state_o))
487.22 else begin
487.23 `ifdef UVM
487.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE,
487.25 "../src/lowrisc_ip_kmac_0.1/rtl/kmac_entropy.sv", 487, "", 1);
487.26 `else
487.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__,
487.28 `PRIM_STRINGIFY(u_state_regs_A));
487.29 `endif
487.30 end
487.31 `else
487.32 prim_sparse_fsm_flop #(
487.33 .StateEnumT(rand_st_e),
487.34 .Width($bits(rand_st_e)),
487.35 .ResetValue($bits(rand_st_e)'(StRandReset)),
487.36 .EnableAlertTriggerSVA(1)
487.37 ) u_state_regs (
487.38 .clk_i ( `PRIM_FLOP_CLK ),
487.39 .rst_ni ( `PRIM_FLOP_RST ),
487.40 .state_i ( st_d ),
487.41 .state_o ( st )
487.42 );
487.43 `endif488
489 // State: Next State and Output Logic
490 // SEC_CM: FSM.SPARSE
491 always_comb begin
492 1/1 st_d = st;
Tests: T1 T2 T3
493 1/1 sparse_fsm_error_o = 1'b 0;
Tests: T1 T2 T3
494
495 // Default Timer values
496 1/1 timer_enable = 1'b 0;
Tests: T1 T2 T3
497 1/1 timer_update = 1'b 0;
Tests: T1 T2 T3
498
499 1/1 threshold_hit_clr = 1'b 0;
Tests: T1 T2 T3
500
501 // rand is valid when this logic expands the entropy.
502 // FSM sets the valid signal, the signal is cleared by `consume` signal
503 // or FSM clear signal.
504 // Why split the signal to set and clear?
505 // FSM only set the signal to make entropy valid while processing other
506 // tasks such as EDN request.
507 1/1 rand_valid_set = 1'b 0;
Tests: T1 T2 T3
508 1/1 rand_valid_clear = 1'b 0;
Tests: T1 T2 T3
509
510 // mode_latch to store mode_i into mode_q
511 1/1 mode_latch = 1'b 0;
Tests: T1 T2 T3
512
513 // PRNG reseed handling
514 1/1 seed_en = 1'b 0;
Tests: T1 T2 T3
515 1/1 seed_ack = 1'b 0;
Tests: T1 T2 T3
516 1/1 entropy_req = 1'b 0;
Tests: T1 T2 T3
517
518 // Randomness control signals
519 1/1 prng_en = 1'b 0;
Tests: T1 T2 T3
520 1/1 data_update = 1'b 0;
Tests: T1 T2 T3
521 1/1 aux_update = 1'b 0;
Tests: T1 T2 T3
522
523 // Error
524 1/1 err_o = '{valid: 1'b 0, code: ErrNone, info: '0};
Tests: T1 T2 T3
525
526 1/1 unique case (st)
Tests: T1 T2 T3
527 StRandReset: begin
528 1/1 if (entropy_ready_i) begin
Tests: T1 T2 T3
529
530 // As SW ready, discard current dummy entropy and refresh.
531 1/1 rand_valid_clear = 1'b 1;
Tests: T1 T2 T3
532
533 1/1 mode_latch = 1'b 1;
Tests: T1 T2 T3
534 // SW has configured KMAC
535 1/1 unique case (mode_i)
Tests: T1 T2 T3
536 EntropyModeSw: begin
537 // Start reseeding the PRNG via ENTROPY_SEED CSR.
538 1/1 seed_en = 1'b 1;
Tests: T1 T3 T49
539 1/1 st_d = StSwSeedWait;
Tests: T1 T3 T49
540 end
541
542 EntropyModeEdn: begin
543 // Start reseeding the PRNG via EDN.
544 1/1 seed_en = 1'b 1;
Tests: T2 T11 T9
545 1/1 st_d = StRandEdn;
Tests: T2 T11 T9
546
547 // Timer reset
548 1/1 timer_update = 1'b 1;
Tests: T2 T11 T9
549 end
550
551 default: begin
552 // EntropyModeNone or other values
553 // Error. No valid mode given, report to SW
554 st_d = StRandErrIncorrectMode;
555 end
556 endcase
557 end else begin
558 1/1 st_d = StRandReset;
Tests: T1 T2 T3
559
560 // Setting the dummy rand gate until SW prepares.
561 // This lets the Application Interface move forward out of reset
562 // without SW intervention.
563 1/1 rand_valid_set = 1'b 1;
Tests: T1 T2 T3
564 end
565 end
566
567 StRandReady: begin
568 1/1 timer_enable = 1'b 1; // If limit is zero, timer won't work
Tests: T1 T2 T3
569
570 1/1 prng_en = prng_en_rand_q[0];
Tests: T1 T2 T3
571
572 1/1 if ((rand_update_i || rand_consumed_i) &&
Tests: T1 T2 T3
573 ((fast_process_i && in_keyblock_i) || !fast_process_i)) begin
574 // If fast_process is set, don't clear the rand valid, even
575 // consumed. So, the logic does not expand the entropy again.
576 // If fast_process is not set, then every rand_consume signal
577 // triggers rand expansion.
578 1/1 prng_en = 1'b 1;
Tests: T1 T2 T3
579 1/1 data_update = 1'b 1;
Tests: T1 T2 T3
580
581 1/1 if (rand_consumed_i) begin
Tests: T1 T2 T3
582 1/1 st_d = StRandGenerate;
Tests: T1 T2 T3
583
584 1/1 rand_valid_clear = 1'b 1;
Tests: T1 T2 T3
585 end else begin
586 1/1 st_d = StRandReady;
Tests: T1 T2 T3
587 end
588 1/1 end else if ((mode_q == EntropyModeEdn) &&
Tests: T1 T2 T3
589 (entropy_refresh_req_i || threshold_hit_q)) begin
590 // Start reseeding the PRNG via EDN.
591 1/1 seed_en = 1'b 1;
Tests: T95 T96 T97
592 1/1 st_d = StRandEdn;
Tests: T95 T96 T97
593
594 // Timer reset
595 1/1 timer_update = 1'b 1;
Tests: T95 T96 T97
596
597 // Clear the threshold as it refreshes the hash
598 1/1 threshold_hit_clr = 1'b 1;
Tests: T95 T96 T97
599 end else begin
600 1/1 st_d = StRandReady;
Tests: T1 T2 T3
601 end
602 end
603
604 StRandEdn: begin
605 // Forward request of PRNG primitive.
606 1/1 entropy_req = seed_req;
Tests: T2 T11 T9
607
608 // Wait timer
609 1/1 timer_enable = 1'b 1;
Tests: T2 T11 T9
610
611 1/1 if (timer_expired && non_zero_wait_timer_limit) begin
Tests: T2 T11 T9
612 // If timer count is non-zero and expired;
613 1/1 st_d = StRandErrWaitExpired;
Tests: T99 T100 T85
614
615 1/1 end else if (entropy_req_o && entropy_ack_i) begin
Tests: T2 T11 T9
616 1/1 seed_ack = 1'b 1;
Tests: T2 T11 T9
617
618 1/1 if (seed_done) begin
Tests: T2 T11 T9
619 1/1 st_d = StRandGenerate;
Tests: T2 T11 T9
620
621 1/1 if ((fast_process_i && in_keyblock_i) || !fast_process_i) begin
Tests: T2 T11 T9
622 1/1 prng_en = 1'b 1;
Tests: T2 T11 T10
623 1/1 data_update = 1'b 1;
Tests: T2 T11 T10
624 1/1 rand_valid_clear = 1'b 1;
Tests: T2 T11 T10
625 end
MISSING_ELSE
626 end else begin
627 1/1 st_d = StRandEdn;
Tests: T2 T11 T9
628 end
629 1/1 end else if ((rand_update_i || rand_consumed_i) &&
Tests: T2 T11 T9
630 ((fast_process_i && in_keyblock_i) || !fast_process_i)) begin
631 // Somehow, while waiting the EDN entropy, the KMAC or SHA3 logic
632 // consumed the remained entropy. This can happen when the previous
633 // SHA3/ KMAC op completed and this Entropy FSM has moved to this
634 // state to refresh the entropy and the SW initiates another hash
635 // operation while waiting for the EDN response.
636 1/1 st_d = StRandEdn;
Tests: T95 T101 T102
637
638 1/1 prng_en = 1'b 1;
Tests: T95 T101 T102
639 1/1 data_update = 1'b 1;
Tests: T95 T101 T102
640 1/1 rand_valid_clear = rand_consumed_i;
Tests: T95 T101 T102
641 end else begin
642 1/1 st_d = StRandEdn;
Tests: T2 T11 T9
643 end
644 end
645
646 StSwSeedWait: begin
647 // Forward ack driven by software.
648 1/1 seed_ack = seed_req & seed_update_i;
Tests: T1 T3 T49
649
650 1/1 if (seed_done) begin
Tests: T1 T3 T49
651 1/1 st_d = StRandGenerate;
Tests: T1 T3 T49
652
653 1/1 prng_en = 1'b 1;
Tests: T1 T3 T49
654 1/1 data_update = 1'b 1;
Tests: T1 T3 T49
655
656 1/1 rand_valid_clear = 1'b 1;
Tests: T1 T3 T49
657 end else begin
658 1/1 st_d = StSwSeedWait;
Tests: T1 T3 T49
659 end
660 end
661
662 StRandGenerate: begin
663 // The current buffer output is used as auxiliary randomness and -
664 // depending on whether keccak_round is parametrized to always forward
665 // the buffer output and not use intermediate randomness - forwarded
666 // to the DOM multipliers without them updating in this cycle. We don't
667 // need to advance the PRNG as there is no risk of accidentally
668 // re-using the same randomness twice since after the current cycle:
669 // - We either load and re-mask the message/key which will use
670 // different PRNG output bits. The PRNG is advanced once per 64 bits
671 // loaded.
672 // - Or, the Keccak/SHA3 core is operated but it always starts with
673 // the linear layers which don't require fresh randomness. While
674 // processing the linear layers, the PRNG is advanced to have fresh
675 // randomness for the non-linear layer requiring it.
676 1/1 aux_update = 1'b 1;
Tests: T1 T2 T3
677 1/1 rand_valid_set = 1'b 1;
Tests: T1 T2 T3
678 1/1 prng_en = prng_en_rand_q[0];
Tests: T1 T2 T3
679
680 1/1 st_d = StRandReady;
Tests: T1 T2 T3
681 end
682
683 StRandErrWaitExpired: begin
684 1/1 st_d = StRandErr;
Tests: T99 T100 T85
685
686 1/1 err_o = '{ valid: 1'b 1,
Tests: T99 T100 T85
687 code: ErrWaitTimerExpired,
688 info: 24'(timer_value)
689 };
690 end
691
692 StRandErrIncorrectMode: begin
693 1/1 st_d = StRandErr;
Tests: T51 T61 T93
694
695 1/1 err_o = '{ valid: 1'b 1,
Tests: T51 T61 T93
696 code: ErrIncorrectEntropyMode,
697 info: 24'(mode_q)
698 };
699 end
700
701 StRandErr: begin
702 // Keep entropy signal valid to complete current hashing even with error
703 1/1 rand_valid_set = 1'b 1;
Tests: T51 T61 T93
704
705 // Advance the PRNG after the entropy has been used.
706 1/1 prng_en = (rand_update_i | rand_consumed_i) &
Tests: T51 T61 T93
707 ((fast_process_i & in_keyblock_i) | ~fast_process_i);
708 1/1 data_update = prng_en;
Tests: T51 T61 T93
709
710 1/1 if (err_processed_i) begin
Tests: T51 T61 T93
711 1/1 st_d = StRandReset;
Tests: T51 T61 T93
712
713 end else begin
714 1/1 st_d = StRandErr;
Tests: T51 T61 T93
715 end
716
717 end
718
719 StTerminalError: begin
720 // this state is terminal
721 1/1 st_d = st;
Tests: T9 T10 T17
722 1/1 sparse_fsm_error_o = 1'b 1;
Tests: T9 T10 T17
723 end
724
725 default: begin
726 st_d = StTerminalError;
727 sparse_fsm_error_o = 1'b 1;
728 end
729 endcase
730
731 // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC
732 // Unconditionally jump into the terminal error state
733 // if the life cycle controller triggers an escalation.
734 1/1 if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin
Tests: T1 T2 T3
735 1/1 st_d = StTerminalError;
Tests: T9 T10 T17
736 end
MISSING_ELSE
737 end
738 `ASSERT_KNOWN(RandStKnown_A, st)
739
740 // mubi4 sender
741
742 1/1 assign entropy_configured = (st != StRandReset)
Tests: T1 T2 T3