[sensor_ctrl / ast] slightly tweak alert handling in sensor_ctrl
- Address #4752
Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl.sv b/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl.sv
index 3610809..7cfbc66 100644
--- a/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl.sv
+++ b/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl.sv
@@ -54,13 +54,13 @@
// Alert handling
///////////////////////////
- logic [NumAlerts-1:0] diff_err;
logic [NumAlerts-1:0] alert_test;
logic [NumAlerts-1:0] alerts_vld, alerts_clr;
logic [NumAlerts-1:0] sw_ack_mode;
- // a particular alert is only valid if differential
- assign alerts_vld = ast_alert_i.alerts_p ^ ast_alert_i.alerts_n;
+ // While the alerts are differential, they are not perfectly aligned.
+ // Instead, each alert is treated independently.
+ assign alerts_vld = ast_alert_i.alerts_p | ~ast_alert_i.alerts_n;
// alert test connection
assign alert_test[AsSel] = reg2hw.alert_test.as.qe & reg2hw.alert_test.as.q;
@@ -71,16 +71,6 @@
assign alert_test[LsSel] = reg2hw.alert_test.ls.qe & reg2hw.alert_test.ls.q;
assign alert_test[OtSel] = reg2hw.alert_test.ot.qe & reg2hw.alert_test.ot.q;
- // Differential errors are devasting and should never happen.
- // If differential errors are detected, hold state on that permanently until reboot.
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- diff_err <= '0;
- end else if (&alerts_vld == '0) begin
- diff_err <= diff_err | ~alerts_vld;
- end
- end
-
// fire an alert whenever indicated, or whenever input no longer differential
for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_senders
@@ -90,11 +80,12 @@
assign sw_ack_mode[i] = ast_ack_mode_e'(reg2hw.ack_mode[i].q) == SwAck;
// if differential checks fail, generate alert
- assign valid_alert = ast_alert_i.alerts_p[i] | diff_err[i];
+ assign valid_alert = alerts_vld[i];
assign hw2reg.alert_state[i].d = sw_ack_mode[i];
assign hw2reg.alert_state[i].de = valid_alert;
logic alert_req;
+ logic alert_ack;
assign alert_req = alert_test[i] | (sw_ack_mode[i] ? reg2hw.alert_state[i].q : valid_alert);
prim_alert_sender #(
.AsyncOn(AsyncOn)
@@ -102,24 +93,21 @@
.clk_i,
.rst_ni,
.alert_req_i(alert_req),
- .alert_ack_o(),
+ .alert_ack_o(alert_ack),
.alert_rx_i(alert_rx_i[i]),
.alert_tx_o(alert_tx_o[i])
);
- assign alerts_clr[i] = sw_ack_mode[i] & reg2hw.alert_state[i].q & reg2hw.alert_state[i].qe;
+ assign alerts_clr[i] = sw_ack_mode[i] ? reg2hw.alert_state[i].q & reg2hw.alert_state[i].qe :
+ alert_req & alert_ack;
end
- // When in immediate ack mode, ack alerts as they come
+ // When in immediate ack mode, ack alerts as they are received by the sender
// When in software ack mode, only ack when software issues the command to clear alert_state
always_comb begin
ast_alert_o.alerts_ack = '0;
for (int i = 0; i < NumAlerts; i++) begin
- if (!sw_ack_mode[i]) begin
- ast_alert_o.alerts_ack[i] = ast_alert_i.alerts_p[i] & alerts_vld[i];
- end else begin
- ast_alert_o.alerts_ack[i] = alerts_clr[i];
- end
+ ast_alert_o.alerts_ack[i] = alerts_clr[i];
end
end