<commit_before>// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// This is the integration wrapper layer for AST

`include "prim_assert.sv"

module sensor_ctrl import sensor_ctrl_pkg::*; #(
  parameter logic AsyncOn = 1'b0
) (
  // Primary module clocks
  input clk_i,
  input rst_ni,

  // Bus Interface
  input tlul_pkg::tl_h2d_t tl_i,
  output tlul_pkg::tl_d2h_t tl_o,

  // Interface from AST
  input ast_wrapper_pkg::ast_alert_req_t ast_alert_i,
  output ast_wrapper_pkg::ast_alert_rsp_t ast_alert_o,
  input ast_wrapper_pkg::ast_status_t ast_status_i,

  // Alerts
  input  prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i,
  output prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o

);


  ///////////////////////////
  // Register interface
  ///////////////////////////
  import sensor_ctrl_reg_pkg::*;
  sensor_ctrl_reg2hw_t reg2hw;
  sensor_ctrl_hw2reg_t hw2reg;

  sensor_ctrl_reg_top u_reg (
    .clk_i,
    .rst_ni,
    .tl_i,
    .tl_o,
    .reg2hw,
    .hw2reg,
    .devmode_i(1'b1)
  );

  assign hw2reg.status.d = ast_status_i.io_pok;
  assign hw2reg.status.de = 1'b1;


  ///////////////////////////
  // 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;

  // alert test connection
  assign alert_test[AsSel]   = reg2hw.alert_test.as.qe    & reg2hw.alert_test.as.q;
  assign alert_test[CgSel]   = reg2hw.alert_test.cg.qe    & reg2hw.alert_test.cg.q;
  assign alert_test[GdSel]   = reg2hw.alert_test.gd.qe    & reg2hw.alert_test.gd.q;
  assign alert_test[TsHiSel] = reg2hw.alert_test.ts_hi.qe & reg2hw.alert_test.ts_hi.q;
  assign alert_test[TsLoSel] = reg2hw.alert_test.ts_lo.qe & reg2hw.alert_test.ts_lo.q;
  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

    // when there is a valid alert, set the alert state
    logic valid_alert;

    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 hw2reg.alert_state[i].d  = sw_ack_mode[i];
    assign hw2reg.alert_state[i].de = valid_alert;

    logic alert_req;
    assign alert_req = alert_test[i] | (sw_ack_mode[i] ? reg2hw.alert_state[i].q : valid_alert);
    prim_alert_sender #(
      .AsyncOn(AsyncOn)
    ) i_prim_alert_sender (
      .clk_i,
      .rst_ni,
      .alert_req_i(alert_req),
      .alert_ack_o(),
      .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;
  end

  // When in immediate ack mode, ack alerts as they come
  // 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
    end
  end

  // alert trigger for test
  assign ast_alert_o.alerts_trig = reg2hw.alert_trig;

endmodule // sensor_ctrl
<commit_msg>[sensor_ctrl / ast] slightly tweak alert handling in sensor_ctrl<commit_after>// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// This is the integration wrapper layer for AST

`include "prim_assert.sv"

module sensor_ctrl import sensor_ctrl_pkg::*; #(
  parameter logic AsyncOn = 1'b0
) (
  // Primary module clocks
  input clk_i,
  input rst_ni,

  // Bus Interface
  input tlul_pkg::tl_h2d_t tl_i,
  output tlul_pkg::tl_d2h_t tl_o,

  // Interface from AST
  input ast_wrapper_pkg::ast_alert_req_t ast_alert_i,
  output ast_wrapper_pkg::ast_alert_rsp_t ast_alert_o,
  input ast_wrapper_pkg::ast_status_t ast_status_i,

  // Alerts
  input  prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i,
  output prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o

);


  ///////////////////////////
  // Register interface
  ///////////////////////////
  import sensor_ctrl_reg_pkg::*;
  sensor_ctrl_reg2hw_t reg2hw;
  sensor_ctrl_hw2reg_t hw2reg;

  sensor_ctrl_reg_top u_reg (
    .clk_i,
    .rst_ni,
    .tl_i,
    .tl_o,
    .reg2hw,
    .hw2reg,
    .devmode_i(1'b1)
  );

  assign hw2reg.status.d = ast_status_i.io_pok;
  assign hw2reg.status.de = 1'b1;


  ///////////////////////////
  // Alert handling
  ///////////////////////////

  logic [NumAlerts-1:0] alert_test;
  logic [NumAlerts-1:0] alerts_vld, alerts_clr;
  logic [NumAlerts-1:0] sw_ack_mode;

  // 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;
  assign alert_test[CgSel]   = reg2hw.alert_test.cg.qe    & reg2hw.alert_test.cg.q;
  assign alert_test[GdSel]   = reg2hw.alert_test.gd.qe    & reg2hw.alert_test.gd.q;
  assign alert_test[TsHiSel] = reg2hw.alert_test.ts_hi.qe & reg2hw.alert_test.ts_hi.q;
  assign alert_test[TsLoSel] = reg2hw.alert_test.ts_lo.qe & reg2hw.alert_test.ts_lo.q;
  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;

  // fire an alert whenever indicated, or whenever input no longer differential
  for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_senders

    // when there is a valid alert, set the alert state
    logic valid_alert;

    assign sw_ack_mode[i] = ast_ack_mode_e'(reg2hw.ack_mode[i].q) == SwAck;

    // if differential checks fail, generate alert
    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)
    ) i_prim_alert_sender (
      .clk_i,
      .rst_ni,
      .alert_req_i(alert_req),
      .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 :
                                            alert_req & alert_ack;
  end

  // 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
      ast_alert_o.alerts_ack[i] = alerts_clr[i];
    end
  end

  // alert trigger for test
  assign ast_alert_o.alerts_trig = reg2hw.alert_trig;

endmodule // sensor_ctrl

{'fraction_non_alphanumeric': 0.1285569105691057, 'fraction_numerical': 0.014227642276422764, 'mean_word_length': 2.9964467005076143, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7052592', 'n_tokens_mistral': 3092, 'n_tokens_neox': 2978, 'n_words': 626}