[otbn] Clear External CSRs RTL Signed-off-by: Vladimir Rozic <vrozic@lowrisc.org>
diff --git a/hw/ip/otbn/data/otbn.hjson b/hw/ip/otbn/data/otbn.hjson index f8b94b6..0e0e86a 100644 --- a/hw/ip/otbn/data/otbn.hjson +++ b/hw/ip/otbn/data/otbn.hjson
@@ -301,9 +301,18 @@ Refer to the "List of Errors" section for a detailed description of the errors. + + The host CPU can clear this register when OTBN is not running, + by writing any value. Write attempts while OTBN is running are ignored. ''', - swaccess: "ro", - hwaccess: "hwo", + swaccess: "rw", + hwaccess: "hrw", + hwext: "true", + hwqe: "true", + tags: [ + // Don't write this register in the automated CSR tests; + "excl:CsrAllTests:CsrExclWrite" + ], fields: [ // Software errors { bits: "0", @@ -450,10 +459,14 @@ count towards the total. Always reads as 0 if OTBN is locked. + + The host CPU can clear this register when OTBN is not running, + by writing any value. Write attempts while OTBN is running are ignored. ''', + swaccess: "rw", + hwaccess: "hrw", hwext: "true", - swaccess: "ro", - hwaccess: "hwo", + hwqe: "true", fields: [ { bits: "31:0", name: "insn_cnt", @@ -461,6 +474,10 @@ desc: ''' The number of executed instructions. ''' + tags: [ + // Don't write this field in the automated CSR tests; + "excl:CsrAllTests:CsrExclWrite" + ] } ] }
diff --git a/hw/ip/otbn/dv/verilator/otbn_top_sim.sv b/hw/ip/otbn/dv/verilator/otbn_top_sim.sv index 1e49939..aa11074 100644 --- a/hw/ip/otbn/dv/verilator/otbn_top_sim.sv +++ b/hw/ip/otbn/dv/verilator/otbn_top_sim.sv
@@ -101,6 +101,7 @@ .edn_urnd_data_i ( edn_urnd_data ), .insn_cnt_o ( insn_cnt ), + .insn_cnt_clear_i ( 1'b0 ), .bus_intg_violation_i ( 1'b0 ), .illegal_bus_access_i ( 1'b0 ),
diff --git a/hw/ip/otbn/rtl/otbn.sv b/hw/ip/otbn/rtl/otbn.sv index 84b43d4..4da29b5 100644 --- a/hw/ip/otbn/rtl/otbn.sv +++ b/hw/ip/otbn/rtl/otbn.sv
@@ -95,9 +95,14 @@ logic locked; logic illegal_bus_access_d, illegal_bus_access_q; - err_bits_t err_bits; logic recoverable_err; logic reg_intg_violation; + err_bits_t err_bits, err_bits_d, err_bits_q; + logic err_bits_en; + + // ERR_BITS register should be cleared due to a write request from the host processor + // when OTBN is not running. + logic err_bits_clear; logic software_errs_fatal_q, software_errs_fatal_d; @@ -641,48 +646,34 @@ // ERR_BITS register // The error bits for an OTBN operation get stored on the cycle that done is // asserted. Software is expected to read them out before starting the next operation. - assign hw2reg.err_bits.bad_data_addr.de = done; - assign hw2reg.err_bits.bad_data_addr.d = err_bits.bad_data_addr; - assign hw2reg.err_bits.bad_insn_addr.de = done; - assign hw2reg.err_bits.bad_insn_addr.d = err_bits.bad_insn_addr; - - assign hw2reg.err_bits.call_stack.de = done; - assign hw2reg.err_bits.call_stack.d = err_bits.call_stack; - - assign hw2reg.err_bits.illegal_insn.de = done; - assign hw2reg.err_bits.illegal_insn.d = err_bits.illegal_insn; - - assign hw2reg.err_bits.loop.de = done; - assign hw2reg.err_bits.loop.d = err_bits.loop; - - assign hw2reg.err_bits.key_invalid.de = done; - assign hw2reg.err_bits.key_invalid.d = err_bits.key_invalid; - - assign hw2reg.err_bits.imem_intg_violation.de = done; - assign hw2reg.err_bits.imem_intg_violation.d = err_bits.imem_intg_violation; - - assign hw2reg.err_bits.dmem_intg_violation.de = done; - assign hw2reg.err_bits.dmem_intg_violation.d = err_bits.dmem_intg_violation; - - assign hw2reg.err_bits.reg_intg_violation.de = done; - assign hw2reg.err_bits.reg_intg_violation.d = err_bits.reg_intg_violation; - - assign hw2reg.err_bits.bus_intg_violation.de = done; - assign hw2reg.err_bits.bus_intg_violation.d = err_bits.bus_intg_violation; - - assign hw2reg.err_bits.bad_internal_state.de = done; - assign hw2reg.err_bits.bad_internal_state.d = err_bits.bad_internal_state; - - assign hw2reg.err_bits.illegal_bus_access.de = done; - assign hw2reg.err_bits.illegal_bus_access.d = err_bits.illegal_bus_access; - - assign hw2reg.err_bits.lifecycle_escalation.de = done; - assign hw2reg.err_bits.lifecycle_escalation.d = err_bits.lifecycle_escalation; - - assign hw2reg.err_bits.fatal_software.de = done; + assign hw2reg.err_bits.bad_data_addr.d = err_bits_q.bad_data_addr; + assign hw2reg.err_bits.bad_insn_addr.d = err_bits_q.bad_insn_addr; + assign hw2reg.err_bits.call_stack.d = err_bits_q.call_stack; + assign hw2reg.err_bits.illegal_insn.d = err_bits_q.illegal_insn; + assign hw2reg.err_bits.loop.d = err_bits_q.loop; + assign hw2reg.err_bits.key_invalid.d = err_bits_q.key_invalid; + assign hw2reg.err_bits.imem_intg_violation.d = err_bits_q.imem_intg_violation; + assign hw2reg.err_bits.dmem_intg_violation.d = err_bits_q.dmem_intg_violation; + assign hw2reg.err_bits.reg_intg_violation.d = err_bits_q.reg_intg_violation; + assign hw2reg.err_bits.bus_intg_violation.d = err_bits_q.bus_intg_violation; + assign hw2reg.err_bits.bad_internal_state.d = err_bits_q.bad_internal_state; + assign hw2reg.err_bits.illegal_bus_access.d = err_bits_q.illegal_bus_access; + assign hw2reg.err_bits.lifecycle_escalation.d = err_bits_q.lifecycle_escalation; assign hw2reg.err_bits.fatal_software.d = err_bits.fatal_software; + assign err_bits_clear = reg2hw.err_bits.bad_data_addr.qe & ~busy_execute_q; + assign err_bits_d = err_bits_clear ? '0 : err_bits; + assign err_bits_en = err_bits_clear | done; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + err_bits_q <= '0; + end else if (err_bits_en) begin + err_bits_q <= err_bits_d; + end + end + // FATAL_ALERT_CAUSE register. The .de and .d values are equal for each bit, so that it can only // be set, not cleared. assign hw2reg.fatal_alert_cause.imem_intg_violation.de = insn_fetch_err; @@ -700,11 +691,13 @@ assign hw2reg.fatal_alert_cause.lifecycle_escalation.de = lifecycle_escalation; assign hw2reg.fatal_alert_cause.lifecycle_escalation.d = lifecycle_escalation; assign hw2reg.fatal_alert_cause.fatal_software.de = done; - assign hw2reg.fatal_alert_cause.fatal_software.d = err_bits.fatal_software; + assign hw2reg.fatal_alert_cause.fatal_software.d = err_bits_d.fatal_software; // INSN_CNT register logic [31:0] insn_cnt; + logic insn_cnt_clear; assign hw2reg.insn_cnt.d = insn_cnt; + assign insn_cnt_clear = reg2hw.insn_cnt.qe & ~busy_execute_q; // Alerts ==================================================================== @@ -927,6 +920,7 @@ .edn_urnd_data_i (edn_urnd_data), .insn_cnt_o (insn_cnt_rtl), + .insn_cnt_clear_i (insn_cnt_clear), .bus_intg_violation_i (bus_intg_violation), .illegal_bus_access_i (illegal_bus_access_q), @@ -938,6 +932,7 @@ .sideload_key_shares_valid_i ({2{keymgr_key_i.valid}}) ); `else + otbn_core #( .RegFile(RegFile), .DmemSizeByte(DmemSizeByte), @@ -981,6 +976,7 @@ .edn_urnd_data_i (edn_urnd_data), .insn_cnt_o (insn_cnt), + .insn_cnt_clear_i (insn_cnt_clear), .bus_intg_violation_i (bus_intg_violation), .illegal_bus_access_i (illegal_bus_access_q),
diff --git a/hw/ip/otbn/rtl/otbn_controller.sv b/hw/ip/otbn/rtl/otbn_controller.sv index ad80403..f5b6fac 100644 --- a/hw/ip/otbn/rtl/otbn_controller.sv +++ b/hw/ip/otbn/rtl/otbn_controller.sv
@@ -133,6 +133,7 @@ input logic state_reset_i, output logic [31:0] insn_cnt_o, + input logic insn_cnt_clear_i, input logic bus_intg_violation_i, input logic illegal_bus_access_i, input logic lifecycle_escalation_i, @@ -239,6 +240,7 @@ logic rf_a_indirect_err, rf_b_indirect_err, rf_d_indirect_err, rf_indirect_err; logic [31:0] insn_cnt_d, insn_cnt_q; + logic insn_cnt_clear; logic [4:0] ld_insn_bignum_wr_addr_q; err_bits_t err_bits; @@ -476,19 +478,8 @@ always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin - err_bits_q.fatal_software <= 1'b0; - err_bits_q.lifecycle_escalation <= 1'b0; - err_bits_q.illegal_bus_access <= 1'b0; - err_bits_q.bus_intg_violation <= 1'b0; - err_bits_q.reg_intg_violation <= 1'b0; - err_bits_q.dmem_intg_violation <= 1'b0; - err_bits_q.imem_intg_violation <= 1'b0; - err_bits_q.illegal_insn <= 1'b0; - err_bits_q.bad_data_addr <= 1'b0; - err_bits_q.loop <= 1'b0; - err_bits_q.call_stack <= 1'b0; - err_bits_q.bad_insn_addr <= 1'b0; recoverable_err_q <= 1'b0; + err_bits_q <= '0; end else if (err_bits_en) begin err_bits_q <= err_bits_d; recoverable_err_q <= recoverable_err_d; @@ -528,8 +519,10 @@ end end + assign insn_cnt_clear = state_reset_i | (state_q == OtbnStateLocked) | insn_cnt_clear_i; + always_comb begin - if (state_reset_i || state_q == OtbnStateLocked) begin + if (insn_cnt_clear) begin insn_cnt_d = 32'd0; end else if (insn_executing & ~stall & (insn_cnt_q != 32'hffffffff)) begin insn_cnt_d = insn_cnt_q + 32'd1;
diff --git a/hw/ip/otbn/rtl/otbn_core.sv b/hw/ip/otbn/rtl/otbn_core.sv index 655a41d..42107bd 100644 --- a/hw/ip/otbn/rtl/otbn_core.sv +++ b/hw/ip/otbn/rtl/otbn_core.sv
@@ -69,6 +69,7 @@ input logic [EdnDataWidth-1:0] edn_urnd_data_i, output logic [31:0] insn_cnt_o, + input logic insn_cnt_clear_i, // An integrity check on an incoming bus transaction failed. Results in a fatal error. input logic bus_intg_violation_i, @@ -417,6 +418,7 @@ .state_reset_i (state_reset), .insn_cnt_o (insn_cnt), + .insn_cnt_clear_i, .bus_intg_violation_i, .illegal_bus_access_i, .lifecycle_escalation_i,
diff --git a/hw/ip/otbn/rtl/otbn_reg_pkg.sv b/hw/ip/otbn/rtl/otbn_reg_pkg.sv index dfa40ec..1c523a7 100644 --- a/hw/ip/otbn/rtl/otbn_reg_pkg.sv +++ b/hw/ip/otbn/rtl/otbn_reg_pkg.sv
@@ -51,6 +51,70 @@ } otbn_reg2hw_ctrl_reg_t; typedef struct packed { + struct packed { + logic q; + logic qe; + } bad_data_addr; + struct packed { + logic q; + logic qe; + } bad_insn_addr; + struct packed { + logic q; + logic qe; + } call_stack; + struct packed { + logic q; + logic qe; + } illegal_insn; + struct packed { + logic q; + logic qe; + } loop; + struct packed { + logic q; + logic qe; + } key_invalid; + struct packed { + logic q; + logic qe; + } imem_intg_violation; + struct packed { + logic q; + logic qe; + } dmem_intg_violation; + struct packed { + logic q; + logic qe; + } reg_intg_violation; + struct packed { + logic q; + logic qe; + } bus_intg_violation; + struct packed { + logic q; + logic qe; + } bad_internal_state; + struct packed { + logic q; + logic qe; + } illegal_bus_access; + struct packed { + logic q; + logic qe; + } lifecycle_escalation; + struct packed { + logic q; + logic qe; + } fatal_software; + } otbn_reg2hw_err_bits_reg_t; + + typedef struct packed { + logic [31:0] q; + logic qe; + } otbn_reg2hw_insn_cnt_reg_t; + + typedef struct packed { logic [31:0] q; logic qe; } otbn_reg2hw_load_checksum_reg_t; @@ -72,59 +136,45 @@ typedef struct packed { struct packed { logic d; - logic de; } bad_data_addr; struct packed { logic d; - logic de; } bad_insn_addr; struct packed { logic d; - logic de; } call_stack; struct packed { logic d; - logic de; } illegal_insn; struct packed { logic d; - logic de; } loop; struct packed { logic d; - logic de; } key_invalid; struct packed { logic d; - logic de; } imem_intg_violation; struct packed { logic d; - logic de; } dmem_intg_violation; struct packed { logic d; - logic de; } reg_intg_violation; struct packed { logic d; - logic de; } bus_intg_violation; struct packed { logic d; - logic de; } bad_internal_state; struct packed { logic d; - logic de; } illegal_bus_access; struct packed { logic d; - logic de; } lifecycle_escalation; struct packed { logic d; - logic de; } fatal_software; } otbn_hw2reg_err_bits_reg_t; @@ -173,21 +223,23 @@ // Register -> HW type typedef struct packed { - otbn_reg2hw_intr_state_reg_t intr_state; // [51:51] - otbn_reg2hw_intr_enable_reg_t intr_enable; // [50:50] - otbn_reg2hw_intr_test_reg_t intr_test; // [49:48] - otbn_reg2hw_alert_test_reg_t alert_test; // [47:44] - otbn_reg2hw_cmd_reg_t cmd; // [43:35] - otbn_reg2hw_ctrl_reg_t ctrl; // [34:33] + otbn_reg2hw_intr_state_reg_t intr_state; // [112:112] + otbn_reg2hw_intr_enable_reg_t intr_enable; // [111:111] + otbn_reg2hw_intr_test_reg_t intr_test; // [110:109] + otbn_reg2hw_alert_test_reg_t alert_test; // [108:105] + otbn_reg2hw_cmd_reg_t cmd; // [104:96] + otbn_reg2hw_ctrl_reg_t ctrl; // [95:94] + otbn_reg2hw_err_bits_reg_t err_bits; // [93:66] + otbn_reg2hw_insn_cnt_reg_t insn_cnt; // [65:33] otbn_reg2hw_load_checksum_reg_t load_checksum; // [32:0] } otbn_reg2hw_t; // HW -> register type typedef struct packed { - otbn_hw2reg_intr_state_reg_t intr_state; // [119:118] - otbn_hw2reg_ctrl_reg_t ctrl; // [117:117] - otbn_hw2reg_status_reg_t status; // [116:108] - otbn_hw2reg_err_bits_reg_t err_bits; // [107:80] + otbn_hw2reg_intr_state_reg_t intr_state; // [105:104] + otbn_hw2reg_ctrl_reg_t ctrl; // [103:103] + otbn_hw2reg_status_reg_t status; // [102:94] + otbn_hw2reg_err_bits_reg_t err_bits; // [93:80] otbn_hw2reg_fatal_alert_cause_reg_t fatal_alert_cause; // [79:64] otbn_hw2reg_insn_cnt_reg_t insn_cnt; // [63:32] otbn_hw2reg_load_checksum_reg_t load_checksum; // [31:0] @@ -216,6 +268,21 @@ parameter logic [7:0] OTBN_CMD_CMD_RESVAL = 8'h 0; parameter logic [0:0] OTBN_CTRL_RESVAL = 1'h 0; parameter logic [0:0] OTBN_CTRL_SOFTWARE_ERRS_FATAL_RESVAL = 1'h 0; + parameter logic [23:0] OTBN_ERR_BITS_RESVAL = 24'h 0; + parameter logic [0:0] OTBN_ERR_BITS_BAD_DATA_ADDR_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_BAD_INSN_ADDR_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_CALL_STACK_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_ILLEGAL_INSN_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_LOOP_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_KEY_INVALID_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_IMEM_INTG_VIOLATION_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_DMEM_INTG_VIOLATION_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_REG_INTG_VIOLATION_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_BUS_INTG_VIOLATION_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_BAD_INTERNAL_STATE_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_ILLEGAL_BUS_ACCESS_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_LIFECYCLE_ESCALATION_RESVAL = 1'h 0; + parameter logic [0:0] OTBN_ERR_BITS_FATAL_SOFTWARE_RESVAL = 1'h 0; parameter logic [31:0] OTBN_INSN_CNT_RESVAL = 32'h 0; parameter logic [31:0] OTBN_INSN_CNT_INSN_CNT_RESVAL = 32'h 0; parameter logic [31:0] OTBN_LOAD_CHECKSUM_RESVAL = 32'h 0;
diff --git a/hw/ip/otbn/rtl/otbn_reg_top.sv b/hw/ip/otbn/rtl/otbn_reg_top.sv index 1101867..cd15371 100644 --- a/hw/ip/otbn/rtl/otbn_reg_top.sv +++ b/hw/ip/otbn/rtl/otbn_reg_top.sv
@@ -180,20 +180,36 @@ logic ctrl_qs; logic ctrl_wd; logic [7:0] status_qs; + logic err_bits_re; + logic err_bits_we; logic err_bits_bad_data_addr_qs; + logic err_bits_bad_data_addr_wd; logic err_bits_bad_insn_addr_qs; + logic err_bits_bad_insn_addr_wd; logic err_bits_call_stack_qs; + logic err_bits_call_stack_wd; logic err_bits_illegal_insn_qs; + logic err_bits_illegal_insn_wd; logic err_bits_loop_qs; + logic err_bits_loop_wd; logic err_bits_key_invalid_qs; + logic err_bits_key_invalid_wd; logic err_bits_imem_intg_violation_qs; + logic err_bits_imem_intg_violation_wd; logic err_bits_dmem_intg_violation_qs; + logic err_bits_dmem_intg_violation_wd; logic err_bits_reg_intg_violation_qs; + logic err_bits_reg_intg_violation_wd; logic err_bits_bus_intg_violation_qs; + logic err_bits_bus_intg_violation_wd; logic err_bits_bad_internal_state_qs; + logic err_bits_bad_internal_state_wd; logic err_bits_illegal_bus_access_qs; + logic err_bits_illegal_bus_access_wd; logic err_bits_lifecycle_escalation_qs; + logic err_bits_lifecycle_escalation_wd; logic err_bits_fatal_software_qs; + logic err_bits_fatal_software_wd; logic fatal_alert_cause_imem_intg_violation_qs; logic fatal_alert_cause_dmem_intg_violation_qs; logic fatal_alert_cause_reg_intg_violation_qs; @@ -203,7 +219,9 @@ logic fatal_alert_cause_lifecycle_escalation_qs; logic fatal_alert_cause_fatal_software_qs; logic insn_cnt_re; + logic insn_cnt_we; logic [31:0] insn_cnt_qs; + logic [31:0] insn_cnt_wd; logic load_checksum_re; logic load_checksum_we; logic [31:0] load_checksum_qs; @@ -363,354 +381,200 @@ ); - // R[err_bits]: V(False) + // R[err_bits]: V(True) // F[bad_data_addr]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_bad_data_addr ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.bad_data_addr.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_bad_data_addr_wd), .d (hw2reg.err_bits.bad_data_addr.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.bad_data_addr.qe), + .q (reg2hw.err_bits.bad_data_addr.q), .qs (err_bits_bad_data_addr_qs) ); // F[bad_insn_addr]: 1:1 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_bad_insn_addr ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.bad_insn_addr.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_bad_insn_addr_wd), .d (hw2reg.err_bits.bad_insn_addr.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.bad_insn_addr.qe), + .q (reg2hw.err_bits.bad_insn_addr.q), .qs (err_bits_bad_insn_addr_qs) ); // F[call_stack]: 2:2 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_call_stack ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.call_stack.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_call_stack_wd), .d (hw2reg.err_bits.call_stack.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.call_stack.qe), + .q (reg2hw.err_bits.call_stack.q), .qs (err_bits_call_stack_qs) ); // F[illegal_insn]: 3:3 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_illegal_insn ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.illegal_insn.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_illegal_insn_wd), .d (hw2reg.err_bits.illegal_insn.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.illegal_insn.qe), + .q (reg2hw.err_bits.illegal_insn.q), .qs (err_bits_illegal_insn_qs) ); // F[loop]: 4:4 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_loop ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.loop.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_loop_wd), .d (hw2reg.err_bits.loop.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.loop.qe), + .q (reg2hw.err_bits.loop.q), .qs (err_bits_loop_qs) ); // F[key_invalid]: 5:5 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_key_invalid ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.key_invalid.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_key_invalid_wd), .d (hw2reg.err_bits.key_invalid.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.key_invalid.qe), + .q (reg2hw.err_bits.key_invalid.q), .qs (err_bits_key_invalid_qs) ); // F[imem_intg_violation]: 16:16 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_imem_intg_violation ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.imem_intg_violation.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_imem_intg_violation_wd), .d (hw2reg.err_bits.imem_intg_violation.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.imem_intg_violation.qe), + .q (reg2hw.err_bits.imem_intg_violation.q), .qs (err_bits_imem_intg_violation_qs) ); // F[dmem_intg_violation]: 17:17 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_dmem_intg_violation ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.dmem_intg_violation.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_dmem_intg_violation_wd), .d (hw2reg.err_bits.dmem_intg_violation.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.dmem_intg_violation.qe), + .q (reg2hw.err_bits.dmem_intg_violation.q), .qs (err_bits_dmem_intg_violation_qs) ); // F[reg_intg_violation]: 18:18 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_reg_intg_violation ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.reg_intg_violation.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_reg_intg_violation_wd), .d (hw2reg.err_bits.reg_intg_violation.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.reg_intg_violation.qe), + .q (reg2hw.err_bits.reg_intg_violation.q), .qs (err_bits_reg_intg_violation_qs) ); // F[bus_intg_violation]: 19:19 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_bus_intg_violation ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.bus_intg_violation.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_bus_intg_violation_wd), .d (hw2reg.err_bits.bus_intg_violation.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.bus_intg_violation.qe), + .q (reg2hw.err_bits.bus_intg_violation.q), .qs (err_bits_bus_intg_violation_qs) ); // F[bad_internal_state]: 20:20 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_bad_internal_state ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.bad_internal_state.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_bad_internal_state_wd), .d (hw2reg.err_bits.bad_internal_state.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.bad_internal_state.qe), + .q (reg2hw.err_bits.bad_internal_state.q), .qs (err_bits_bad_internal_state_qs) ); // F[illegal_bus_access]: 21:21 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_illegal_bus_access ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.illegal_bus_access.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_illegal_bus_access_wd), .d (hw2reg.err_bits.illegal_bus_access.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.illegal_bus_access.qe), + .q (reg2hw.err_bits.illegal_bus_access.q), .qs (err_bits_illegal_bus_access_qs) ); // F[lifecycle_escalation]: 22:22 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_lifecycle_escalation ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.lifecycle_escalation.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_lifecycle_escalation_wd), .d (hw2reg.err_bits.lifecycle_escalation.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.lifecycle_escalation.qe), + .q (reg2hw.err_bits.lifecycle_escalation.q), .qs (err_bits_lifecycle_escalation_qs) ); // F[fatal_software]: 23:23 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0) + prim_subreg_ext #( + .DW (1) ) u_err_bits_fatal_software ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.err_bits.fatal_software.de), + .re (err_bits_re), + .we (err_bits_we), + .wd (err_bits_fatal_software_wd), .d (hw2reg.err_bits.fatal_software.d), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) + .qre (), + .qe (reg2hw.err_bits.fatal_software.qe), + .q (reg2hw.err_bits.fatal_software.q), .qs (err_bits_fatal_software_qs) ); @@ -922,12 +786,12 @@ .DW (32) ) u_insn_cnt ( .re (insn_cnt_re), - .we (1'b0), - .wd ('0), + .we (insn_cnt_we), + .wd (insn_cnt_wd), .d (hw2reg.insn_cnt.d), .qre (), - .qe (), - .q (), + .qe (reg2hw.insn_cnt.qe), + .q (reg2hw.insn_cnt.q), .qs (insn_cnt_qs) ); @@ -1002,7 +866,40 @@ assign ctrl_we = addr_hit[5] & reg_we & !reg_error; assign ctrl_wd = reg_wdata[0]; + assign err_bits_re = addr_hit[7] & reg_re & !reg_error; + assign err_bits_we = addr_hit[7] & reg_we & !reg_error; + + assign err_bits_bad_data_addr_wd = reg_wdata[0]; + + assign err_bits_bad_insn_addr_wd = reg_wdata[1]; + + assign err_bits_call_stack_wd = reg_wdata[2]; + + assign err_bits_illegal_insn_wd = reg_wdata[3]; + + assign err_bits_loop_wd = reg_wdata[4]; + + assign err_bits_key_invalid_wd = reg_wdata[5]; + + assign err_bits_imem_intg_violation_wd = reg_wdata[16]; + + assign err_bits_dmem_intg_violation_wd = reg_wdata[17]; + + assign err_bits_reg_intg_violation_wd = reg_wdata[18]; + + assign err_bits_bus_intg_violation_wd = reg_wdata[19]; + + assign err_bits_bad_internal_state_wd = reg_wdata[20]; + + assign err_bits_illegal_bus_access_wd = reg_wdata[21]; + + assign err_bits_lifecycle_escalation_wd = reg_wdata[22]; + + assign err_bits_fatal_software_wd = reg_wdata[23]; assign insn_cnt_re = addr_hit[9] & reg_re & !reg_error; + assign insn_cnt_we = addr_hit[9] & reg_we & !reg_error; + + assign insn_cnt_wd = reg_wdata[31:0]; assign load_checksum_re = addr_hit[10] & reg_re & !reg_error; assign load_checksum_we = addr_hit[10] & reg_we & !reg_error;