@@ -120,44 +120,71 @@ module ibex_lockstep import ibex_pkg::*; #(
120120 // - The reset of the shadow core is synchronously released.
121121 // The comparison is started in the following clock cycle.
122122
123- logic [LockstepOffsetW- 1 : 0 ] rst_shadow_cnt_d, rst_shadow_cnt_q, rst_shadow_cnt_incr;
124- // Internally generated resets cause IMPERFECTSCH warnings
125- /* verilator lint_off IMPERFECTSCH */
126- logic rst_shadow_set_d, rst_shadow_set_q;
127- logic rst_shadow_n, enable_cmp_q;
128- /* verilator lint_on IMPERFECTSCH */
123+ logic [LockstepOffsetW- 1 : 0 ] rst_shadow_cnt;
124+ logic rst_shadow_cnt_err;
125+ ibex_mubi_t rst_shadow_set_d, rst_shadow_set_q;
126+ logic rst_shadow_n, rst_shadow_set_single_bit;
127+ ibex_mubi_t enable_cmp_d, enable_cmp_q;
128+
129+ // This counter primitive starts counting to LockstepOffset after a system
130+ // reset. The counter value saturates at LockstepOffset.
131+ prim_count # (
132+ .Width (LockstepOffsetW ),
133+ .ResetValue (LockstepOffsetW ' (1'b0 ) )
134+ ) u_rst_shadow_cnt (
135+ .clk_i (clk_i ),
136+ .rst_ni (rst_ni ),
137+ .clr_i (1'b0 ),
138+ .set_i (1'b0 ),
139+ .set_cnt_i ('0 ),
140+ .incr_en_i (1'b1 ),
141+ .decr_en_i (1'b0 ),
142+ .step_i (LockstepOffsetW ' (1'b1 ) ),
143+ .cnt_o (rst_shadow_cnt ),
144+ .cnt_next_o ( ),
145+ .err_o (rst_shadow_cnt_err )
146+ );
129147
130- assign rst_shadow_cnt_incr = rst_shadow_cnt_q + 1'b1 ;
148+ // When the LockstepOffset counter value is reached, activate the lockstep
149+ // comparison. We do not explicitly check whether rst_shadow_set_q forms a valid
150+ // multibit signal as this value is implicitly checked by the enable_cmp
151+ // comparison below.
152+ assign rst_shadow_set_d =
153+ (rst_shadow_cnt >= LockstepOffsetW ' (LockstepOffset - 1 )) ? IbexMuBiOn : IbexMuBiOff;
131154
132- assign rst_shadow_set_d = (rst_shadow_cnt_q == LockstepOffsetW ' (LockstepOffset - 1 ));
133- assign rst_shadow_cnt_d = rst_shadow_set_d ? rst_shadow_cnt_q : rst_shadow_cnt_incr ;
155+ // Enable lockstep comparison.
156+ assign enable_cmp_d = rst_shadow_set_q ;
134157
135- always_ff @ (posedge clk_i or negedge rst_ni) begin
136- if (! rst_ni) begin
137- rst_shadow_cnt_q <= '0 ;
138- enable_cmp_q <= '0 ;
139- end else begin
140- rst_shadow_cnt_q <= rst_shadow_cnt_d;
141- enable_cmp_q <= rst_shadow_set_q;
142- end
143- end
158+ // This assignment is needed in order to avoid "Warning-IMPERFECTSCH" messages.
159+ // TODO: Remove when updating Verilator #2134.
160+ assign rst_shadow_set_single_bit = rst_shadow_set_q[0 ];
144161
145162 // The primitives below are used to place size-only constraints in order to prevent
146163 // synthesis optimizations and preserve anchor points for constraining backend tools.
147164 prim_flop # (
148- .Width (1 ),
149- .ResetValue (1'b0 )
165+ .Width (IbexMuBiWidth ),
166+ .ResetValue (IbexMuBiOff )
150167 ) u_prim_rst_shadow_set_flop (
151168 .clk_i (clk_i),
152169 .rst_ni (rst_ni),
153170 .d_i (rst_shadow_set_d),
154171 .q_o (rst_shadow_set_q)
155172 );
156173
174+ prim_flop # (
175+ .Width (IbexMuBiWidth),
176+ .ResetValue (IbexMuBiOff)
177+ ) u_prim_enable_cmp_flop (
178+ .clk_i (clk_i),
179+ .rst_ni (rst_ni),
180+ .d_i (enable_cmp_d),
181+ .q_o (enable_cmp_q)
182+ );
183+
157184 prim_clock_mux2 # (
158185 .NoFpgaBufG (1'b1 )
159186 ) u_prim_rst_shadow_n_mux2 (
160- .clk0_i (rst_shadow_set_q ),
187+ .clk0_i (rst_shadow_set_single_bit ),
161188 .clk1_i (scan_rst_ni),
162189 .sel_i (test_en_i),
163190 .clk_o (rst_shadow_n)
@@ -458,8 +485,10 @@ module ibex_lockstep import ibex_pkg::*; #(
458485
459486 logic outputs_mismatch;
460487
461- assign outputs_mismatch = enable_cmp_q & (shadow_outputs_q != core_outputs_q[0 ]);
462- assign alert_major_internal_o = outputs_mismatch | shadow_alert_major_internal;
488+ assign outputs_mismatch =
489+ (enable_cmp_q != IbexMuBiOff) & (shadow_outputs_q != core_outputs_q[0 ]);
490+ assign alert_major_internal_o
491+ = outputs_mismatch | shadow_alert_major_internal | rst_shadow_cnt_err;
463492 assign alert_major_bus_o = shadow_alert_major_bus;
464493 assign alert_minor_o = shadow_alert_minor;
465494
0 commit comments