From 7935cf955125c16f0aa4010319bc22bd5bcd08ef Mon Sep 17 00:00:00 2001 From: Yvan Tortorella Date: Wed, 28 Feb 2024 21:50:34 +0100 Subject: [PATCH] Added synchronous clear for fault recovery setback. --- common/local/util/sram_pulp.sv | 2 +- core/ariane_regfile_ff.sv | 19 ++- core/controller.sv | 37 +++-- core/csr_regfile.sv | 265 ++++++++++++++++++++++----------- core/cva6.sv | 6 +- core/issue_read_operands.sv | 1 + corev_apu/src/ariane.sv | 1 + 7 files changed, 222 insertions(+), 109 deletions(-) diff --git a/common/local/util/sram_pulp.sv b/common/local/util/sram_pulp.sv index f3c4773bf43..360b8c77ebd 100644 --- a/common/local/util/sram_pulp.sv +++ b/common/local/util/sram_pulp.sv @@ -25,7 +25,7 @@ module sram #( parameter USER_WIDTH = 1, parameter USER_EN = 0, parameter NUM_WORDS = 1024, - parameter SIM_INIT = "none", + parameter SIM_INIT = "zeros", parameter OUT_REGS = 0 // enables output registers in FPGA macro (read lat = 2) )( input logic clk_i, diff --git a/core/ariane_regfile_ff.sv b/core/ariane_regfile_ff.sv index ae5cbeb0d7c..fe3f417d829 100644 --- a/core/ariane_regfile_ff.sv +++ b/core/ariane_regfile_ff.sv @@ -31,6 +31,7 @@ module ariane_regfile #( // clock and reset input logic clk_i, input logic rst_ni, + input logic clear_i, // disable clock gates for testing input logic test_en_i, // read port @@ -63,14 +64,18 @@ module ariane_regfile #( if (~rst_ni) begin mem <= '{default: '0}; end else begin - for (int unsigned j = 0; j < CVA6Cfg.NrCommitPorts; j++) begin - for (int unsigned i = 0; i < NUM_WORDS; i++) begin - if (we_dec[j][i]) begin - mem[i] <= wdata_i[j]; + if (clear_i) begin + mem <= '{default: '0}; + end else begin + for (int unsigned j = 0; j < CVA6Cfg.NrCommitPorts; j++) begin + for (int unsigned i = 0; i < NUM_WORDS; i++) begin + if (we_dec[j][i]) begin + mem[i] <= wdata_i[j]; + end + end + if (ZERO_REG_ZERO) begin + mem[0] <= '0; end - end - if (ZERO_REG_ZERO) begin - mem[0] <= '0; end end end diff --git a/core/controller.sv b/core/controller.sv index b36b811efa5..441765486d7 100644 --- a/core/controller.sv +++ b/core/controller.sv @@ -22,6 +22,8 @@ module controller input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear, active high + input logic clear_i, // VS mode - CSR_REGFILE input logic v_i, // Reset microarchitecture - SUBSYSTEM @@ -379,8 +381,8 @@ module controller ) i_drain_cnt ( .clk_i, .rst_ni, - .clear_i (cache_busy_i), // Start counting from 0 when cache is busy - .en_i (drain_cnt != 4'hf), // Stop counting when saturated + .clear_i (cache_busy_i | clear_i), // Start counting from 0 when cache is busy + .en_i (drain_cnt != 4'hf), // Stop counting when saturated .load_i (1'b0), .down_i (1'b0), .d_i ('0), @@ -394,7 +396,7 @@ module controller ) i_pad_cnt ( .clk_i, .rst_ni, - .clear_i (1'b0), + .clear_i, .en_i (|pad_cnt), // Count until 0 .load_i (load_pad_cnt), // Start counting on positive edge of time irq .down_i (1'b1), // Always count down @@ -417,15 +419,26 @@ module controller priv_lvl_q <= riscv::PRIV_LVL_M; cache_init_q <= '0; end else begin - fence_t_state_q <= fence_t_state_d; - fence_active_q <= fence_active_d; - rst_uarch_cnt_q <= rst_uarch_cnt_d; - // register on the flush signal, this signal might be critical - flush_dcache_o <= flush_dcache; - rst_addr_q <= rst_addr_d; - time_irq_q <= time_irq_i; - priv_lvl_q <= priv_lvl_i; - cache_init_q <= cache_init_d; + if (clear_i) begin + fence_t_state_q <= IDLE; + rst_uarch_cnt_q <= 4'b0; + fence_active_q <= 1'b0; + flush_dcache_o <= 1'b0; + rst_addr_q <= boot_addr_i; + time_irq_q <= 1'b0; + priv_lvl_q <= riscv::PRIV_LVL_M; + cache_init_q <= '0; + end else begin + fence_t_state_q <= fence_t_state_d; + fence_active_q <= fence_active_d; + rst_uarch_cnt_q <= rst_uarch_cnt_d; + // register on the flush signal, this signal might be critical + flush_dcache_o <= flush_dcache; + rst_addr_q <= rst_addr_d; + time_irq_q <= time_irq_i; + priv_lvl_q <= priv_lvl_i; + cache_init_q <= cache_init_d; + end end end endmodule diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 047780d53de..e01ce8c872c 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -25,6 +25,8 @@ module csr_regfile input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high + input logic clear_i, // Timer threw a interrupt - SUBSYSTEM input logic time_irq_i, // send a flush request out when a CSR with a side effect changes - CONTROLLER @@ -2497,97 +2499,186 @@ module csr_regfile end end end else begin - priv_lvl_q <= priv_lvl_d; - // floating-point registers - fcsr_q <= fcsr_d; - // debug signals - if (CVA6Cfg.DebugEn) begin - debug_mode_q <= debug_mode_d; - dcsr_q <= dcsr_d; - dpc_q <= dpc_d; - dscratch0_q <= dscratch0_d; - dscratch1_q <= dscratch1_d; - end - // machine mode registers - mstatus_q <= mstatus_d; - mtvec_rst_load_q <= 1'b0; - mtvec_q <= mtvec_d; - mip_q <= mip_d; - mie_q <= mie_d; - mintstatus_q <= mintstatus_d; - mintthresh_q <= mintthresh_d; - mepc_q <= mepc_d; - mcause_q <= mcause_d; - mcounteren_q <= mcounteren_d; - mtvt_q <= mtvt_d; - mscratch_q <= mscratch_d; - if (CVA6Cfg.TvalEn) mtval_q <= mtval_d; - fiom_q <= fiom_d; - dcache_q <= dcache_d; - icache_q <= icache_d; - mcountinhibit_q <= mcountinhibit_d; - acc_cons_q <= acc_cons_d; - fence_t_pad_q <= fence_t_pad_d; - fence_t_ceil_q <= fence_t_ceil_d; - // supervisor mode registers - if (CVA6Cfg.RVS) begin - medeleg_q <= medeleg_d; - mideleg_q <= mideleg_d; - sepc_q <= sepc_d; - scause_q <= scause_d; - stvec_q <= stvec_d; - scounteren_q <= scounteren_d; - sscratch_q <= sscratch_d; - if (CVA6Cfg.TvalEn) stval_q <= stval_d; - satp_q <= satp_d; - end - if (CVA6Cfg.RVH) begin - v_q <= v_d; - mtval2_q <= mtval2_d; - mtinst_q <= mtinst_d; - // hypervisor mode registers - hstatus_q <= hstatus_d; - hedeleg_q <= hedeleg_d; - hideleg_q <= hideleg_d; - hgeie_q <= hgeie_d; - hgatp_q <= hgatp_d; - hcounteren_q <= hcounteren_d; - htval_q <= htval_d; - htinst_q <= htinst_d; - // virtual supervisor mode registers - vsstatus_q <= vsstatus_d; - vsepc_q <= vsepc_d; - vscause_q <= vscause_d; - vstvec_q <= vstvec_d; - vsscratch_q <= vsscratch_d; - vstval_q <= vstval_d; - vsatp_q <= vsatp_d; - en_ld_st_g_translation_q <= en_ld_st_g_translation_d; - end - // timer and counters - cycle_q <= cycle_d; - instret_q <= instret_d; - // aux registers - en_ld_st_translation_q <= en_ld_st_translation_d; - // wait for interrupt - wfi_q <= wfi_d; - // pmp - for (int i = 0; i < 16; i++) begin - if (i < CVA6Cfg.NrPMPEntries) begin - // We only support >=8-byte granularity, NA4 is disabled - if(!CVA6Cfg.PMPEntryReadOnly[i] && pmpcfg_d[i].addr_mode != riscv::NA4 && !(pmpcfg_d[i].access_type.r == '0 && pmpcfg_d[i].access_type.w == '1)) begin - pmpcfg_q[i] <= pmpcfg_d[i]; + if (clear_i) begin + priv_lvl_q <= riscv::PRIV_LVL_M; + // floating-point registers + fcsr_q <= '0; + // debug signals + debug_mode_q <= 1'b0; + if (CVA6Cfg.DebugEn) begin + dcsr_q <= '0; + dcsr_q.prv <= riscv::PRIV_LVL_M; + dcsr_q.xdebugver <= 4'h4; + dpc_q <= '0; + dscratch0_q <= {riscv::XLEN{1'b0}}; + dscratch1_q <= {riscv::XLEN{1'b0}}; + end + // machine mode registers + mstatus_q <= 64'b0; + // set to boot address + direct mode + 4 byte offset which is the initial trap + mtvec_rst_load_q <= 1'b1; + mtvec_q <= '0; + mip_q <= {riscv::XLEN{1'b0}}; + mie_q <= {riscv::XLEN{1'b0}}; + mintstatus_q <= 32'b0; + mintthresh_q <= 8'b0; + mepc_q <= {riscv::XLEN{1'b0}}; + mcause_q <= {riscv::XLEN{1'b0}}; + mcounteren_q <= {riscv::XLEN{1'b0}}; + mtvt_q <= {riscv::XLEN{1'b0}}; + mscratch_q <= {riscv::XLEN{1'b0}}; + mtval_q <= {riscv::XLEN{1'b0}}; + fiom_q <= '0; + dcache_q <= {{riscv::XLEN - 1{1'b0}}, 1'b1}; + icache_q <= {{riscv::XLEN - 1{1'b0}}, 1'b1}; + mcountinhibit_q <= '0; + acc_cons_q <= {{riscv::XLEN - 1{1'b0}}, CVA6Cfg.EnableAccelerator}; + fence_t_pad_q <= {riscv::XLEN{1'b0}}; + fence_t_ceil_q <= {riscv::XLEN{1'b0}}; + // supervisor mode registers + if (CVA6Cfg.RVS) begin + medeleg_q <= {riscv::XLEN{1'b0}}; + mideleg_q <= {riscv::XLEN{1'b0}}; + sepc_q <= {riscv::XLEN{1'b0}}; + scause_q <= {riscv::XLEN{1'b0}}; + stvec_q <= {riscv::XLEN{1'b0}}; + scounteren_q <= {riscv::XLEN{1'b0}}; + sscratch_q <= {riscv::XLEN{1'b0}}; + stval_q <= {riscv::XLEN{1'b0}}; + satp_q <= {riscv::XLEN{1'b0}}; + end + if (CVA6Cfg.RVH) begin + v_q <= '0; + mtval2_q <= {riscv::XLEN{1'b0}}; + mtinst_q <= {riscv::XLEN{1'b0}}; + hstatus_q <= {riscv::XLEN{1'b0}}; + hedeleg_q <= {riscv::XLEN{1'b0}}; + hideleg_q <= {riscv::XLEN{1'b0}}; + hgeie_q <= {riscv::XLEN{1'b0}}; + hgatp_q <= {riscv::XLEN{1'b0}}; + hcounteren_q <= {riscv::XLEN{1'b0}}; + htval_q <= {riscv::XLEN{1'b0}}; + htinst_q <= {riscv::XLEN{1'b0}}; + // virtual supervisor mode registers + vsstatus_q <= 64'b0; + vsepc_q <= {riscv::XLEN{1'b0}}; + vscause_q <= {riscv::XLEN{1'b0}}; + vstvec_q <= {riscv::XLEN{1'b0}}; + vsscratch_q <= {riscv::XLEN{1'b0}}; + vstval_q <= {riscv::XLEN{1'b0}}; + vsatp_q <= {riscv::XLEN{1'b0}}; + en_ld_st_g_translation_q <= 1'b0; + end + // timer and counters + cycle_q <= 64'b0; + instret_q <= 64'b0; + // aux registers + en_ld_st_translation_q <= 1'b0; + // wait for interrupt + wfi_q <= 1'b0; + // pmp + for (int i = 0; i < 16; i++) begin + if (i < CVA6Cfg.NrPMPEntries) begin + pmpcfg_q[i] <= riscv::pmpcfg_t'(CVA6Cfg.PMPCfgRstVal[i]); + pmpaddr_q[i] <= CVA6Cfg.PMPAddrRstVal[i][riscv::PLEN-3:0]; end else begin - pmpcfg_q[i] <= pmpcfg_q[i]; + pmpcfg_q[i] <= '0; + pmpaddr_q[i] <= '0; end - if (!CVA6Cfg.PMPEntryReadOnly[i]) begin - pmpaddr_q[i] <= pmpaddr_d[i]; + end + end else begin + priv_lvl_q <= priv_lvl_d; + // floating-point registers + fcsr_q <= fcsr_d; + // debug signals + if (CVA6Cfg.DebugEn) begin + debug_mode_q <= debug_mode_d; + dcsr_q <= dcsr_d; + dpc_q <= dpc_d; + dscratch0_q <= dscratch0_d; + dscratch1_q <= dscratch1_d; + end + // machine mode registers + mstatus_q <= mstatus_d; + mtvec_rst_load_q <= 1'b0; + mtvec_q <= mtvec_d; + mip_q <= mip_d; + mie_q <= mie_d; + mintstatus_q <= mintstatus_d; + mintthresh_q <= mintthresh_d; + mepc_q <= mepc_d; + mcause_q <= mcause_d; + mcounteren_q <= mcounteren_d; + mtvt_q <= mtvt_d; + mscratch_q <= mscratch_d; + if (CVA6Cfg.TvalEn) mtval_q <= mtval_d; + fiom_q <= fiom_d; + dcache_q <= dcache_d; + icache_q <= icache_d; + mcountinhibit_q <= mcountinhibit_d; + acc_cons_q <= acc_cons_d; + fence_t_pad_q <= fence_t_pad_d; + fence_t_ceil_q <= fence_t_ceil_d; + // supervisor mode registers + if (CVA6Cfg.RVS) begin + medeleg_q <= medeleg_d; + mideleg_q <= mideleg_d; + sepc_q <= sepc_d; + scause_q <= scause_d; + stvec_q <= stvec_d; + scounteren_q <= scounteren_d; + sscratch_q <= sscratch_d; + if (CVA6Cfg.TvalEn) stval_q <= stval_d; + satp_q <= satp_d; + end + if (CVA6Cfg.RVH) begin + v_q <= v_d; + mtval2_q <= mtval2_d; + mtinst_q <= mtinst_d; + // hypervisor mode registers + hstatus_q <= hstatus_d; + hedeleg_q <= hedeleg_d; + hideleg_q <= hideleg_d; + hgeie_q <= hgeie_d; + hgatp_q <= hgatp_d; + hcounteren_q <= hcounteren_d; + htval_q <= htval_d; + htinst_q <= htinst_d; + // virtual supervisor mode registers + vsstatus_q <= vsstatus_d; + vsepc_q <= vsepc_d; + vscause_q <= vscause_d; + vstvec_q <= vstvec_d; + vsscratch_q <= vsscratch_d; + vstval_q <= vstval_d; + vsatp_q <= vsatp_d; + en_ld_st_g_translation_q <= en_ld_st_g_translation_d; + end + // timer and counters + cycle_q <= cycle_d; + instret_q <= instret_d; + // aux registers + en_ld_st_translation_q <= en_ld_st_translation_d; + // wait for interrupt + wfi_q <= wfi_d; + // pmp + for (int i = 0; i < 16; i++) begin + if (i < CVA6Cfg.NrPMPEntries) begin + // We only support >=8-byte granularity, NA4 is disabled + if(!CVA6Cfg.PMPEntryReadOnly[i] && pmpcfg_d[i].addr_mode != riscv::NA4 && !(pmpcfg_d[i].access_type.r == '0 && pmpcfg_d[i].access_type.w == '1)) begin + pmpcfg_q[i] <= pmpcfg_d[i]; + end else begin + pmpcfg_q[i] <= pmpcfg_q[i]; + end + if (!CVA6Cfg.PMPEntryReadOnly[i]) begin + pmpaddr_q[i] <= pmpaddr_d[i]; + end else begin + pmpaddr_q[i] <= pmpaddr_q[i]; + end end else begin - pmpaddr_q[i] <= pmpaddr_q[i]; + pmpcfg_q[i] <= '0; + pmpaddr_q[i] <= '0; end - end else begin - pmpcfg_q[i] <= '0; - pmpaddr_q[i] <= '0; end end end diff --git a/core/cva6.sv b/core/cva6.sv index 42285e1b02f..88ac5219910 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -119,6 +119,8 @@ module cva6 input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high + input logic clear_i, // Reset boot address - SUBSYSTEM input logic [riscv::VLEN-1:0] boot_addr_i, // Hard ID reflected as CSR - SUBSYSTEM @@ -520,7 +522,7 @@ module cva6 if (~rst_ni) begin rst_uarch_n <= 1'b0; end else begin - rst_uarch_n <= rst_uarch_controller_n; + rst_uarch_n <= rst_uarch_controller_n & ~clear_i; end end @@ -1446,7 +1448,7 @@ module cva6 instr_tracer_if tracer_if (clk_i); // assign instruction tracer interface // control signals - assign tracer_if.rstn = rst_ni; + assign tracer_if.rstn = rst_ni & ~clear_i; assign tracer_if.flush_unissued = flush_unissued_instr_ctrl_id; assign tracer_if.flush = flush_ctrl_ex; // fetch diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index a09b1484809..4ed42a93bba 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -557,6 +557,7 @@ module issue_read_operands .NR_READ_PORTS(3), .ZERO_REG_ZERO(0) ) i_ariane_fp_regfile ( + .clear_i (~rst_uarch_ni), .test_en_i(1'b0), .raddr_i (fp_raddr_pack), .rdata_o (fprdata), diff --git a/corev_apu/src/ariane.sv b/corev_apu/src/ariane.sv index a0690e8181e..b6d4fedb2be 100644 --- a/corev_apu/src/ariane.sv +++ b/corev_apu/src/ariane.sv @@ -61,6 +61,7 @@ module ariane import ariane_pkg::*; #( ) i_cva6 ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), + .clear_i ( '0 ), .boot_addr_i ( boot_addr_i ), .hart_id_i ( hart_id_i ), .irq_i ( irq_i ),