@@ -120,44 +120,71 @@ module ibex_lockstep import ibex_pkg::*; #(
120
120
// - The reset of the shadow core is synchronously released.
121
121
// The comparison is started in the following clock cycle.
122
122
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
+ );
129
147
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;
131
154
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 ;
134
157
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 ];
144
161
145
162
// The primitives below are used to place size-only constraints in order to prevent
146
163
// synthesis optimizations and preserve anchor points for constraining backend tools.
147
164
prim_flop # (
148
- .Width (1 ),
149
- .ResetValue (1'b0 )
165
+ .Width (IbexMuBiWidth ),
166
+ .ResetValue (IbexMuBiOff )
150
167
) u_prim_rst_shadow_set_flop (
151
168
.clk_i (clk_i),
152
169
.rst_ni (rst_ni),
153
170
.d_i (rst_shadow_set_d),
154
171
.q_o (rst_shadow_set_q)
155
172
);
156
173
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
+
157
184
prim_clock_mux2 # (
158
185
.NoFpgaBufG (1'b1 )
159
186
) u_prim_rst_shadow_n_mux2 (
160
- .clk0_i (rst_shadow_set_q ),
187
+ .clk0_i (rst_shadow_set_single_bit ),
161
188
.clk1_i (scan_rst_ni),
162
189
.sel_i (test_en_i),
163
190
.clk_o (rst_shadow_n)
@@ -458,8 +485,10 @@ module ibex_lockstep import ibex_pkg::*; #(
458
485
459
486
logic outputs_mismatch;
460
487
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;
463
492
assign alert_major_bus_o = shadow_alert_major_bus;
464
493
assign alert_minor_o = shadow_alert_minor;
465
494
0 commit comments