diff --git a/Bender.yml b/Bender.yml index 6a8f493be..dd3c10430 100644 --- a/Bender.yml +++ b/Bender.yml @@ -26,6 +26,7 @@ dependencies: iDMA: { git: "https://github.com/pulp-platform/iDMA.git", version: 0.5.1 } irq_router: { git: "https://github.com/pulp-platform/irq_router.git", version: 0.0.1-beta.1 } opentitan_peripherals: { git: "https://github.com/pulp-platform/opentitan_peripherals.git", version: 0.4.0 } + redundancy_cells: { git: "https://github.com/pulp-platform/redundancy_cells.git", rev: f5451c323350eebd5820e1c2e1772f50d8301c4a } # branch: astral register_interface: { git: "https://github.com/pulp-platform/register_interface.git", version: 0.4.2 } riscv-dbg: { git: "https://github.com/pulp-platform/riscv-dbg.git", version: 0.8.0 } serial_link: { git: "https://github.com/pulp-platform/serial_link.git", version: 1.1.0 } diff --git a/hw/cheshire_pkg.sv b/hw/cheshire_pkg.sv index b99fec6b0..b64ade845 100644 --- a/hw/cheshire_pkg.sv +++ b/hw/cheshire_pkg.sv @@ -140,6 +140,7 @@ package cheshire_pkg; bit Clic; bit IrqRouter; bit BusErr; + bit Cva6DMR; // Parameters for Debug Module jtag_idcode_t DbgIdCode; dw_bt DbgMaxReqs; @@ -570,6 +571,7 @@ package cheshire_pkg; Clic : 0, IrqRouter : 0, BusErr : 1, + Cva6DMR : 1, // Debug DbgIdCode : CheshireIdCode, DbgMaxReqs : 4, diff --git a/hw/cheshire_soc.sv b/hw/cheshire_soc.sv index a2f102776..aff00f22b 100644 --- a/hw/cheshire_soc.sv +++ b/hw/cheshire_soc.sv @@ -612,6 +612,8 @@ module cheshire_soc import cheshire_pkg::*; #( .AxiDataWidth ( Cfg.AxiDataWidth ), .AxiIdWidth ( Cva6IdWidth ), .ClicNumIrqs ( $clog2(NumClicIntrs) ), + .reg_req_t ( reg_req_t ), + .reg_rsp_t ( reg_rsp_t ), .axi_ar_chan_t ( axi_cva6_ar_chan_t ), .axi_aw_chan_t ( axi_cva6_aw_chan_t ), .axi_w_chan_t ( axi_cva6_w_chan_t ), diff --git a/hw/cva6_wrap.sv b/hw/cva6_wrap.sv index fed68bff0..fff1a5fda 100644 --- a/hw/cva6_wrap.sv +++ b/hw/cva6_wrap.sv @@ -7,13 +7,17 @@ module cva6_wrap import riscv::*; import cheshire_pkg::*; +import rapid_recovery_pkg::*; #( + parameter cheshire_pkg::cheshire_cfg_t Cfg = '0, parameter ariane_pkg::ariane_cfg_t Cva6Cfg = ariane_pkg::ArianeDefaultConfig, parameter int unsigned NumHarts = 1, parameter int unsigned AxiAddrWidth = ariane_axi::AddrWidth, parameter int unsigned AxiDataWidth = ariane_axi::DataWidth, parameter int unsigned AxiIdWidth = ariane_axi::IdWidth, parameter int unsigned ClicNumIrqs = $clog2(Cva6Cfg.CLICNumInterruptSrc), + parameter type reg_req_t = logic, + parameter type reg_rsp_t = logic, parameter type axi_ar_chan_t = ariane_axi::ar_chan_t, parameter type axi_aw_chan_t = ariane_axi::aw_chan_t, parameter type axi_w_chan_t = ariane_axi::w_chan_t, @@ -42,7 +46,57 @@ import cheshire_pkg::*; input axi_rsp_t [NumHarts-1:0] axi_rsp_i ); -for (genvar i = 0; i < NumHarts; i++) begin +typedef struct packed { + doub_bt bootaddress; + doub_bt hart_id; + logic [1:0] irq; + logic ipi; + logic time_irq; + logic debug_req; + logic clic_irq_valid; + logic [ClicNumIrqs-1:0] clic_irq_id; + logic [7:0] clic_irq_level; + riscv::priv_lvl_t clic_irq_priv; + logic clic_irq_v; + logic [5:0] clic_irq_vsid; + logic clic_irq_shv; + logic clic_kill_req; + axi_rsp_t axi_rsp; +} cva6_inputs_t; + +typedef struct packed { + logic clic_irq_ready; + logic clic_kill_ack; + axi_req_t axi_req; +} cva6_outputs_t; + +cva6_inputs_t [NumHarts-1:0] sys2hmr, hmr2core; +cva6_outputs_t [NumHarts-1:0] hmr2sys, core2hmr; + +for (genvar i = 0; i < NumHarts; i++) begin: gen_hmr_binding + // Bind system inputs to HMR. + assign sys2hmr[i].bootaddress = bootaddress_i; // TODO: differentiate? + assign sys2hmr[i].hart_id = hart_id_i + 64'(i); + assign sys2hmr[i].irq = irq_i[i]; + assign sys2hmr[i].ipi = ipi_i[i]; + assign sys2hmr[i].time_irq = time_irq_i[i]; + assign sys2hmr[i].debug_req = debug_req_i[i]; + assign sys2hmr[i].clic_irq_valid = clic_irq_valid_i[i]; + assign sys2hmr[i].clic_irq_id = clic_irq_id_i[i]; + assign sys2hmr[i].clic_irq_level = clic_irq_level_i[i]; + assign sys2hmr[i].clic_irq_priv = clic_irq_priv_i[i]; + assign sys2hmr[i].clic_irq_v = clic_irq_v_i[i]; + assign sys2hmr[i].clic_irq_vsid = clic_irq_vsid_i[i]; + assign sys2hmr[i].clic_irq_shv = clic_irq_shv_i[i]; + assign sys2hmr[i].clic_kill_req = clic_kill_req_i[i]; + assign sys2hmr[i].axi_rsp = axi_rsp_i[i]; + // Bind HMR outputs to system. + assign clic_irq_ready_o[i] = hmr2sys[i].clic_irq_ready; + assign clic_kill_ack_o[i] = hmr2sys[i].clic_kill_ack; + assign axi_req_o[i] = hmr2sys[i].axi_req; +end + +for (genvar i = 0; i < NumHarts; i++) begin: gen_cva6_cores cva6 #( .ArianeCfg ( Cva6Cfg ), .AxiAddrWidth ( AxiAddrWidth ), @@ -54,32 +108,82 @@ for (genvar i = 0; i < NumHarts; i++) begin .axi_req_t ( axi_req_t ), .axi_rsp_t ( axi_rsp_t ) ) i_core_cva6 ( - .clk_i ( clk_i ), - .rst_ni ( rstn_i ), - .boot_addr_i ( bootaddress_i ), - .hart_id_i ( hart_id_i + 64'(i) ), - .irq_i ( irq_i[i] ), - .ipi_i ( ipi_i[i] ), - .time_irq_i ( time_irq_i[i] ), - .debug_req_i ( debug_req_i[i] ), - .clic_irq_valid_i ( clic_irq_valid_i[i] ), - .clic_irq_id_i ( clic_irq_id_i[i] ), - .clic_irq_level_i ( clic_irq_level_i[i] ), - .clic_irq_priv_i ( clic_irq_priv_i[i] ), - .clic_irq_shv_i ( clic_irq_shv_i[i] ), - .clic_irq_v_i ( clic_irq_v_i[i] ), - .clic_irq_vsid_i ( clic_irq_vsid_i[i] ), - .clic_irq_ready_o ( clic_irq_ready_o[i] ), - .clic_kill_req_i ( clic_kill_req_i[i] ), - .clic_kill_ack_o ( clic_kill_ack_o[i] ), - .rvfi_o ( ), - .cvxif_req_o ( ), - .cvxif_resp_i ( '0 ), - .l15_req_o ( ), - .l15_rtrn_i ( '0 ), - .axi_req_o ( axi_req_o[i] ), - .axi_resp_i ( axi_rsp_i[i] ) + .clk_i ( clk_i ), + .rst_ni ( rstn_i ), + .boot_addr_i ( hmr2core[i].bootaddress ), + .hart_id_i ( hmr2core[i].hart_id ), + .irq_i ( hmr2core[i].irq ), + .ipi_i ( hmr2core[i].ipi ), + .time_irq_i ( hmr2core[i].time_irq ), + .debug_req_i ( hmr2core[i].debug_req ), + .clic_irq_valid_i ( hmr2core[i].clic_irq_valid ), + .clic_irq_id_i ( hmr2core[i].clic_irq_id ), + .clic_irq_level_i ( hmr2core[i].clic_irq_level ), + .clic_irq_priv_i ( hmr2core[i].clic_irq_priv ), + .clic_irq_shv_i ( hmr2core[i].clic_irq_shv ), + .clic_irq_v_i ( hmr2core[i].clic_irq_v ), + .clic_irq_vsid_i ( hmr2core[i].clic_irq_vsid ), + .clic_irq_ready_o ( core2hmr[i].clic_irq_ready ), + .clic_kill_req_i ( hmr2core[i].clic_kill_req ), + .clic_kill_ack_o ( core2hmr[i].clic_kill_ack ), + .rvfi_o ( ), + .cvxif_req_o ( ), + .cvxif_resp_i ( '0 ), + .l15_req_o ( ), + .l15_rtrn_i ( '0 ), + .axi_req_o ( core2hmr[i].axi_req ), + .axi_resp_i ( hmr2core[i].axi_rsp ) ); -end +end + +hmr_unit #( + .NumCores ( NumHarts ), + .DMRSupported ( Cfg.Cva6DMR ), + .DMRFixed ( 0 ), // TODO: make configurable + .TMRSupported ( 0 ), + .RapidRecovery ( 1 ), + .SeparateData ( 0 ), + .RfAddrWidth ( 5 ), + .SysDataWidth ( 64 ), + .all_inputs_t ( cva6_inputs_t ), // Inputs from the system to the HMR + .nominal_outputs_t ( cva6_outputs_t ), + // .core_backup_t ( '0 ), // TODO + // .bus_outputs_t ( '0 ), // TODO + .reg_req_t ( reg_req_t ), // TODO + .reg_rsp_t ( reg_rsp_t ), // TODO + .rapid_recovery_t ( rapid_recovery_pkg::rapid_recovery_t ) // TODO +) i_cva6_hmr ( + .clk_i ( clk_i ), + .rst_ni ( rstn_i ), + .reg_request_i ( '0 ), // TODO + .reg_response_o ( /* TODO */ ), + .tmr_failure_o ( /* Not used */), + .tmr_error_o ( /* Not used */), // Should this not be NumTMRCores? or NumCores? + .tmr_resynch_req_o ( /* Not used */), + .tmr_sw_synch_req_o ( /* Not used */), + .tmr_cores_synch_i ( '0 ), // Not used + + // DMR signals + .dmr_failure_o ( /* TODO */ ), + .dmr_error_o ( /* TODO */ ), // Should this not be NumDMRCores? or NumCores? + .dmr_resynch_req_o ( /* TODO */ ), + .dmr_sw_synch_req_o ( /* TODO */ ), + .dmr_cores_synch_i ( '0 ), + + // Rapid recovery buses + .rapid_recovery_o ( /* TODO */ ), + .core_backup_i ( '0 ), // TODO + + .sys_inputs_i ( sys2hmr ), + .sys_nominal_outputs_o ( hmr2sys ), + .sys_bus_outputs_o ( ), + .sys_fetch_en_i ( '0 ), // TODO? + .enable_bus_vote_i ( '0 ), // TODO? + + .core_setback_o ( /* TODO */ ), + .core_inputs_o ( hmr2core ), + .core_nominal_outputs_i ( core2hmr ), + .core_bus_outputs_i ( '0 ) // TODO? +); endmodule: cva6_wrap