diff --git a/README.md b/README.md
index 237042e..bd894b2 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# EL2 SweRV RISC-V CoreTM 1.1 from Western Digital
+# EL2 SweRV RISC-V CoreTM 1.2 from Western Digital
This repository contains the SweRV EL2 CoreTM design RTL
@@ -191,6 +191,10 @@ The `$RV_ROOT/testbench/hex` directory contains precompiled hex files of the tes
**Note**: The testbench has a simple synthesizable bridge that allows you to load the ICCM via load/store instructions. This is only supported for AXI4 builds.
+**Building an FPGA speed optimized model:**
+Use ``-set=fpga_optimize=1`` option to ``swerv.config`` to build a model that is removes clock gating logic from flop model so that the FPGA builds can run a higher speeds.
+
+
----
Western Digital, the Western Digital logo, G-Technology, SanDisk, Tegile, Upthere, WD, SweRV Core, SweRV ISS,
and OmniXtend are registered trademarks or trademarks of Western Digital Corporation or its affiliates in the US
diff --git a/configs/swerv.config b/configs/swerv.config
index 20379e0..5c12152 100755
--- a/configs/swerv.config
+++ b/configs/swerv.config
@@ -1,4 +1,19 @@
#! /usr/bin/env perl
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2020 Western Digital Corporation or its affiliates.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
use strict; # Do not turn this off or else
use Data::Dumper;
@@ -384,7 +399,7 @@ our %csr = (#{{{
"mie" => {
"reset" => "0x0",
# Only external, timer, local, and software writeable
- "mask" => "0x40000888",
+ "mask" => "0x70000888",
"exists" => "true",
},
"mip" => {
@@ -393,7 +408,7 @@ our %csr = (#{{{
"mask" => "0x0",
# Bits corresponding to error overflow, external, timer and stoftware
# interrupts are modifiable
- "poke_mask" => "0x40000888",
+ "poke_mask" => "0x70000888",
"exists" => "true",
},
"mcountinhibit" => {
@@ -414,7 +429,7 @@ our %csr = (#{{{
"exists" => "true",
},
"mimpid" => {
- "reset" => "0x1",
+ "reset" => "0x2",
"mask" => "0x0",
"exists" => "true",
},
@@ -535,6 +550,42 @@ our %csr = (#{{{
"mask" => "0x0",
"exists" => "true",
},
+ "mitcnt0" => {
+ "number" => "0x7d2",
+ "reset" => "0x0",
+ "mask" => "0xffffffff",
+ "exists" => "true",
+ },
+ "mitbnd0" => {
+ "number" => "0x7d3",
+ "reset" => "0xffffffff",
+ "mask" => "0xffffffff",
+ "exists" => "true",
+ },
+ "mitctl0" => {
+ "number" => "0x7d4",
+ "reset" => "0x1",
+ "mask" => "0x00000007",
+ "exists" => "true",
+ },
+ "mitcnt1" => {
+ "number" => "0x7d5",
+ "reset" => "0x0",
+ "mask" => "0xffffffff",
+ "exists" => "true",
+ },
+ "mitbnd1" => {
+ "number" => "0x7d6",
+ "reset" => "0xffffffff",
+ "mask" => "0xffffffff",
+ "exists" => "true",
+ },
+ "mitctl1" => {
+ "number" => "0x7d7",
+ "reset" => "0x1",
+ "mask" => "0x0000000f",
+ "exists" => "true",
+ },
"mcpc" => {
"comment" => "Core pause",
"number" => "0x7c2",
@@ -658,7 +709,7 @@ our %csr = (#{{{
"mscause" => {
"number" => "0x7ff",
"reset" => "0x0",
- "mask" => "0x00000007",
+ "mask" => "0x0000000f",
"exists" => "true",
},
);#}}}
@@ -739,8 +790,10 @@ our %config = (#{{{
"iccm_only" => 'derived', # Used by design
"icache_only" => 'derived', # Used by design
"no_iccm_no_icache" => 'derived', # Used by design
+ "timer_legal_en" => '1', # Design Parm, Overridable
"fast_interrupt_redirect" => "$fast_interrupt_redirect", # Design Parm, Overridable
"lsu2dma" => $lsu2dma, # used by design/TB for LSU to DMA bridge
+ "fpga_optimize" => "0", # Optimize fpga speed by removing clock gating
},
"dccm" => {
@@ -949,6 +1002,7 @@ our %config = (#{{{
# for now autosize to the data
our %verilog_parms = (
"lsu2dma" => '1',
+ "timer_legal_en" => '1',
"fast_interrupt_redirect" => '1',
"inst_access_enable0" => '1',
"inst_access_addr0" => '32',
@@ -1520,7 +1574,7 @@ if (hex($config{protection}{data_access_enable0}) > 0 ||
$config{protection}{data_access_mask0} = "0xefffffff";
$config{protection}{data_access_enable0} = "1";
} else {
- my $hreg = hex($config{memmap}{external_mem_hole}>>28);
+ my $hreg = $config{memmap}{external_mem_hole}>>28;
$config{protection}{data_access_addr0} = sprintf("0x%x", (($hreg^8)&8)<<28);
$config{protection}{data_access_mask0} = "0x7fffffff";
$config{protection}{data_access_addr1} = sprintf("0x%x", ($hreg&8) << 28 |(($hreg^4)&4)<<28);
@@ -2097,6 +2151,11 @@ sub dump_whisper_config{#{{{
# Collect CSRs not included in verilog.
my @removed_csrs;
+ if (! $config{core}{timer_legal_en}) {
+ push(@removed_csrs, $_) for qw (mitcnt0 mitbnd0 mitctl0
+ mitcnt1 mitbnd1 mitctl1);
+ }
+
# Collect fast interrupt enable.
if (exists $config{core}{fast_interrupt_redirect}) {
$jh{fast_interrupt_redirect} = $config{core}{fast_interrupt_redirect};
diff --git a/design/dec/csrdecode b/design/dec/csrdecode
index 5fa2ba2..4082ccc 100644
--- a/design/dec/csrdecode
+++ b/design/dec/csrdecode
@@ -57,6 +57,12 @@ csr_mpmc = [011111000110]
csr_mcgc = [011111111000]
csr_mcpc = [011111000010]
csr_mfdc = [011111111001]
+csr_mitctl0 = [011111010100]
+csr_mitctl1 = [011111010111]
+csr_mitb0 = [011111010011]
+csr_mitb1 = [011111010110]
+csr_mitcnt0 = [011111010010]
+csr_mitcnt1 = [011111010101]
csr_perfva = [101100000111]
csr_perfvb = [101100001...]
csr_perfvc = [10110001....]
@@ -136,6 +142,12 @@ csr = {
csr_mhpme5
csr_mhpme6
csr_mcountinhibit
+ csr_mitctl0
+ csr_mitctl1
+ csr_mitb0
+ csr_mitb1
+ csr_mitcnt0
+ csr_mitcnt1
csr_perfva
csr_perfvb
csr_perfvc
@@ -223,6 +235,12 @@ csr[ csr_dicad0h ] = { csr_dicad0h }
csr[ csr_dicad0 ] = { csr_dicad0 }
csr[ csr_dicad1 ] = { csr_dicad1 }
csr[ csr_dicago ] = { csr_dicago }
+csr[ csr_mitctl0 ] = { csr_mitctl0 }
+csr[ csr_mitctl1 ] = { csr_mitctl1 }
+csr[ csr_mitb0 ] = { csr_mitb0 }
+csr[ csr_mitb1 ] = { csr_mitb1 }
+csr[ csr_mitcnt0 ] = { csr_mitcnt0 }
+csr[ csr_mitcnt1 ] = { csr_mitcnt1 }
csr[ csr_mfdht ] = { csr_mfdht }
csr[ csr_mfdhs ] = { csr_mfdhs }
csr[ csr_mcountinhibit] = { csr_mcountinhibit presync postsync }
diff --git a/design/dec/el2_dec_tlu_ctl.sv b/design/dec/el2_dec_tlu_ctl.sv
index a24caeb..b8cedde 100644
--- a/design/dec/el2_dec_tlu_ctl.sv
+++ b/design/dec/el2_dec_tlu_ctl.sv
@@ -265,8 +265,8 @@ import el2_pkg::*;
logic mstatus_mie_ns;
logic [30:0] mtvec_ns, mtvec;
logic [15:2] dcsr_ns, dcsr;
- logic [3:0] mip_ns, mip;
- logic [3:0] mie_ns, mie;
+ logic [5:0] mip_ns, mip;
+ logic [5:0] mie_ns, mie;
logic [31:0] mcyclel_ns, mcyclel;
logic [31:0] mcycleh_ns, mcycleh;
logic [31:0] minstretl_ns, minstretl;
@@ -288,7 +288,7 @@ import el2_pkg::*;
logic [31:1] mepc_ns, mepc;
logic [31:1] dpc_ns, dpc;
logic [31:0] mcause_ns, mcause;
- logic [2:0] mscause_ns, mscause, mscause_type;
+ logic [3:0] mscause_ns, mscause, mscause_type;
logic [31:0] mtval_ns, mtval;
logic dec_pause_state_f, dec_tlu_wr_pause_r_d1, pause_expired_r, pause_expired_wb;
logic tlu_flush_lower_r, tlu_flush_lower_r_d1;
@@ -304,10 +304,9 @@ import el2_pkg::*;
logic ebreak_r, ebreak_to_debug_mode_r, ecall_r, illegal_r, mret_r, inst_acc_r, fence_i_r,
ic_perr_r, iccm_sbecc_r, ebreak_to_debug_mode_r_d1, kill_ebreak_count_r, inst_acc_second_r;
logic ic_perr_r_d1, iccm_sbecc_r_d1;
- logic ce_int_ready, ext_int_ready, timer_int_ready, soft_int_ready, mhwakeup_ready,
- take_ext_int, take_ce_int, take_timer_int, take_soft_int, take_nmi, take_nmi_r_d1;
- logic i0_exception_valid_r, interrupt_valid_r, i0_exception_valid_r_d1, interrupt_valid_r_d1, exc_or_int_valid_r, exc_or_int_valid_r_d1,
- mdccme_ce_req, miccme_ce_req, mice_ce_req;
+ logic ce_int_ready, ext_int_ready, timer_int_ready, soft_int_ready, int_timer0_int_ready, int_timer1_int_ready, mhwakeup_ready,
+ take_ext_int, take_ce_int, take_timer_int, take_soft_int, take_int_timer0_int, take_int_timer1_int, take_nmi, take_nmi_r_d1, int_timer0_int_possible, int_timer1_int_possible;
+ logic i0_exception_valid_r, interrupt_valid_r, i0_exception_valid_r_d1, interrupt_valid_r_d1, exc_or_int_valid_r, exc_or_int_valid_r_d1, mdccme_ce_req, miccme_ce_req, mice_ce_req;
logic synchronous_flush_r;
logic [4:0] exc_cause_r, exc_cause_wb;
logic mcyclel_cout, mcyclel_cout_f;
@@ -341,9 +340,9 @@ import el2_pkg::*;
logic inst_acc_r_raw, trigger_hit_dmode_r, trigger_hit_dmode_r_d1;
logic [8:0] mcgc;
logic [18:0] mfdc;
- logic i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, pmu_fw_halt_req_ns, pmu_fw_halt_req_f,
+ logic i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, pmu_fw_halt_req_ns, pmu_fw_halt_req_f, int_timer_stalled,
fw_halt_req, enter_pmu_fw_halt_req, pmu_fw_tlu_halted, pmu_fw_tlu_halted_f, internal_pmu_fw_halt_mode,
- internal_pmu_fw_halt_mode_f;
+ internal_pmu_fw_halt_mode_f, int_timer0_int_hold, int_timer1_int_hold, int_timer0_int_hold_f, int_timer1_int_hold_f;
logic nmi_int_delayed, nmi_int_detected;
logic [3:0] trigger_execute, trigger_data, trigger_store;
logic dec_tlu_pmu_fw_halted;
@@ -359,6 +358,17 @@ import el2_pkg::*;
logic dbg_halt_req_held_ns, dbg_halt_req_held, dbg_halt_req_final;
logic iccm_repair_state_ns, iccm_repair_state_d1, iccm_repair_state_rfnpc;
+
+ // internal timer, isolated for size reasons
+ logic [31:0] dec_timer_rddata_d;
+ logic dec_timer_read_d, dec_timer_t0_pulse, dec_timer_t1_pulse;
+ logic csr_mitctl0;
+ logic csr_mitctl1;
+ logic csr_mitb0;
+ logic csr_mitb1;
+ logic csr_mitcnt0;
+ logic csr_mitcnt1;
+
logic nmi_int_sync, timer_int_sync, soft_int_sync, i_cpu_halt_req_sync, i_cpu_run_req_sync, mpc_debug_halt_req_sync, mpc_debug_run_req_sync, mpc_debug_halt_req_sync_raw;
logic csr_wr_clk;
logic lsu_r_wb_clk;
@@ -474,6 +484,13 @@ import el2_pkg::*;
logic wr_mdeau_r;
logic trigger_hit_for_dscr_cause_r_d1;
+ logic [3:0] ifu_mscause ;
+
+ logic conditionally_illegal;
+
+
+ el2_dec_timer_ctl #(.pt(pt)) int_timers(.*);
+ // end of internal timers
assign clk_override = dec_tlu_dec_clk_override;
@@ -519,12 +536,16 @@ import el2_pkg::*;
assign nmi_lsu_store_type = (nmi_lsu_detected & lsu_imprecise_error_store_any & ~(nmi_int_detected_f & ~take_nmi_r_d1)) | (nmi_lsu_store_type_f & ~take_nmi_r_d1);
`define MSTATUS_MIE 0
-`define MIP_MCEIP 3
+`define MIP_MCEIP 5
+`define MIP_MITIP0 4
+`define MIP_MITIP1 3
`define MIP_MEIP 2
`define MIP_MTIP 1
`define MIP_MSIP 0
-`define MIE_MCEIE 3
+`define MIE_MCEIE 5
+`define MIE_MITIE0 4
+`define MIE_MITIE1 3
`define MIE_MEIE 2
`define MIE_MTIE 1
`define MIE_MSIE 0
@@ -659,7 +680,7 @@ import el2_pkg::*;
assign dec_tlu_flush_pause_r = dec_tlu_wr_pause_r_d1 & ~interrupt_valid_r & ~take_ext_int_start;
// detect end of pause counter and rfpc
- assign pause_expired_r = ~dec_pause_state & dec_pause_state_f & ~(ext_int_ready | ce_int_ready | timer_int_ready | soft_int_ready | nmi_int_detected | ext_int_freeze_d1) & ~interrupt_valid_r_d1 & ~debug_halt_req_f & ~pmu_fw_halt_req_f & ~halt_taken_f;
+ assign pause_expired_r = ~dec_pause_state & dec_pause_state_f & ~(ext_int_ready | ce_int_ready | timer_int_ready | soft_int_ready | int_timer0_int_hold_f | int_timer1_int_hold_f | nmi_int_detected | ext_int_freeze_d1) & ~interrupt_valid_r_d1 & ~debug_halt_req_f & ~pmu_fw_halt_req_f & ~halt_taken_f;
assign dec_tlu_flush_leak_one_r = dec_tlu_flush_lower_r & dcsr[`DCSR_STEP] & (dec_tlu_resume_ack | dcsr_single_step_running) & ~dec_tlu_flush_noredir_r;
assign dec_tlu_flush_err_r = dec_tlu_flush_lower_r & (ic_perr_r_d1 | iccm_sbecc_r_d1);
@@ -770,12 +791,14 @@ import el2_pkg::*;
assign i_cpu_halt_req_sync_qual = i_cpu_halt_req_sync & ~dec_tlu_debug_mode & ~ext_int_freeze_d1;
assign i_cpu_run_req_sync_qual = i_cpu_run_req_sync & ~dec_tlu_debug_mode & pmu_fw_tlu_halted_f & ~ext_int_freeze_d1;
- rvdff #(8) exthaltff (.*, .clk(free_clk), .din({i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, cpu_halt_status,
+ rvdff #(10) exthaltff (.*, .clk(free_clk), .din({i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, cpu_halt_status,
cpu_halt_ack, cpu_run_ack, internal_pmu_fw_halt_mode,
- pmu_fw_halt_req_ns, pmu_fw_tlu_halted}),
+ pmu_fw_halt_req_ns, pmu_fw_tlu_halted,
+ int_timer0_int_hold, int_timer1_int_hold}),
.dout({i_cpu_halt_req_d1, i_cpu_run_req_d1_raw, o_cpu_halt_status,
o_cpu_halt_ack, o_cpu_run_ack, internal_pmu_fw_halt_mode_f,
- pmu_fw_halt_req_f, pmu_fw_tlu_halted_f}));
+ pmu_fw_halt_req_f, pmu_fw_tlu_halted_f,
+ int_timer0_int_hold_f, int_timer1_int_hold_f}));
// only happens if we aren't in dgb_halt
assign ext_halt_pulse = i_cpu_halt_req_sync_qual & ~i_cpu_halt_req_d1;
@@ -801,7 +824,7 @@ import el2_pkg::*;
`endif
// high priority interrupts can wakeup from external halt, so can unmasked timer interrupts
- assign i_cpu_run_req_d1 = i_cpu_run_req_d1_raw | ((nmi_int_detected | timer_int_ready | soft_int_ready | (mhwakeup & mhwakeup_ready)) & o_cpu_halt_status & ~i_cpu_halt_req_d1);
+ assign i_cpu_run_req_d1 = i_cpu_run_req_d1_raw | ((nmi_int_detected | timer_int_ready | soft_int_ready | int_timer0_int_hold_f | int_timer1_int_hold_f | (mhwakeup & mhwakeup_ready)) & o_cpu_halt_status & ~i_cpu_halt_req_d1);
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
@@ -917,6 +940,8 @@ import el2_pkg::*;
assign exc_cause_r[4:0] = ( ({5{take_ext_int}} & 5'h0b) |
({5{take_timer_int}} & 5'h07) |
({5{take_soft_int}} & 5'h03) |
+ ({5{take_int_timer0_int}} & 5'h1d) |
+ ({5{take_int_timer1_int}} & 5'h1c) |
({5{take_ce_int}} & 5'h1e) |
({5{illegal_r}} & 5'h02) |
({5{ecall_r}} & 5'h0b) |
@@ -943,8 +968,21 @@ import el2_pkg::*;
assign soft_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[`MIP_MSIP] & mie_ns[`MIE_MSIE];
assign timer_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[`MIP_MTIP] & mie_ns[`MIE_MTIE];
- assign internal_dbg_halt_timers = internal_dbg_halt_mode_f & ~dcsr_single_step_running;
+ // MIP for internal timers pulses for 1 clock, resets the timer counter. Mip won't hold past the various stall conditions.
+ assign int_timer0_int_possible = mstatus_mie_ns & mie_ns[`MIE_MITIE0];
+ assign int_timer0_int_ready = mip[`MIP_MITIP0] & int_timer0_int_possible;
+ assign int_timer1_int_possible = mstatus_mie_ns & mie_ns[`MIE_MITIE1];
+ assign int_timer1_int_ready = mip[`MIP_MITIP1] & int_timer1_int_possible;
+ // Internal timers pulse and reset. If core is PMU/FW halted, the pulse will cause an exit from halt, but won't stick around
+ // Make it sticky, also for 1 cycle stall conditions.
+ assign int_timer_stalled = dec_csr_stall_int_ff | synchronous_flush_r | exc_or_int_valid_r_d1 | mret_r;
+
+ assign int_timer0_int_hold = (int_timer0_int_ready & (pmu_fw_tlu_halted_f | int_timer_stalled)) | (int_timer0_int_possible & int_timer0_int_hold_f & ~interrupt_valid_r & ~take_ext_int_start & ~internal_dbg_halt_mode_f);
+ assign int_timer1_int_hold = (int_timer1_int_ready & (pmu_fw_tlu_halted_f | int_timer_stalled)) | (int_timer1_int_possible & int_timer1_int_hold_f & ~interrupt_valid_r & ~take_ext_int_start & ~internal_dbg_halt_mode_f);
+
+
+ assign internal_dbg_halt_timers = internal_dbg_halt_mode_f & ~dcsr_single_step_running;
assign block_interrupts = ( (internal_dbg_halt_mode & (~dcsr_single_step_running | dec_tlu_i0_valid_r)) | // No ints in db-halt unless we are single stepping
internal_pmu_fw_halt_mode | i_cpu_halt_req_d1 |// No ints in PMU/FW halt. First we exit halt
@@ -987,12 +1025,16 @@ end
assign take_ce_int = ce_int_ready & ~ext_int_ready & ~block_interrupts;
assign take_soft_int = soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts;
assign take_timer_int = timer_int_ready & ~soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts;
+ assign take_int_timer0_int = (int_timer0_int_ready | int_timer0_int_hold_f) & int_timer0_int_possible & ~dec_csr_stall_int_ff &
+ ~timer_int_ready & ~soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts;
+ assign take_int_timer1_int = (int_timer1_int_ready | int_timer1_int_hold_f) & int_timer1_int_possible & ~dec_csr_stall_int_ff &
+ ~(int_timer0_int_ready | int_timer0_int_hold_f) & ~timer_int_ready & ~soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts;
assign take_reset = reset_delayed & mpc_reset_run_req;
assign take_nmi = nmi_int_detected & ~internal_pmu_fw_halt_mode & (~internal_dbg_halt_mode | (dcsr_single_step_running_f & dcsr[`DCSR_STEPIE] & ~dec_tlu_i0_valid_r & ~dcsr_single_step_done_f)) &
~synchronous_flush_r & ~mret_r & ~take_reset & ~ebreak_to_debug_mode_r & (~ext_int_freeze_d1 | (take_ext_int_start_d3 & |lsu_fir_error[1:0]));
- assign interrupt_valid_r = take_ext_int | take_timer_int | take_soft_int | take_nmi | take_ce_int;
+ assign interrupt_valid_r = take_ext_int | take_timer_int | take_soft_int | take_nmi | take_ce_int | take_int_timer0_int | take_int_timer1_int;
// Compute interrupt path:
@@ -1116,6 +1158,8 @@ end
// MIP (RW)
//
// [30] MCEIP : (RO) M-Mode Correctable Error interrupt pending
+ // [29] MITIP0 : (RO) M-Mode Internal Timer0 interrupt pending
+ // [28] MITIP1 : (RO) M-Mode Internal Timer1 interrupt pending
// [11] MEIP : (RO) M-Mode external interrupt pending
// [7] MTIP : (RO) M-Mode timer interrupt pending
// [3] MSIP : (RO) M-Mode software interrupt pending
@@ -1123,20 +1167,22 @@ end
assign ce_int = (mdccme_ce_req | miccme_ce_req | mice_ce_req);
- assign mip_ns[3:0] = {ce_int, mexintpend, timer_int_sync, soft_int_sync};
- rvdff #(4) mip_ff (.*, .clk(free_clk), .din(mip_ns[3:0]), .dout(mip[3:0]));
+ assign mip_ns[5:0] = {ce_int, dec_timer_t0_pulse, dec_timer_t1_pulse, mexintpend, timer_int_sync, soft_int_sync};
+ rvdff #(6) mip_ff (.*, .clk(free_clk), .din(mip_ns[5:0]), .dout(mip[5:0]));
// ----------------------------------------------------------------------
// MIE (RW)
// [30] MCEIE : (RO) M-Mode Correctable Error interrupt enable
+ // [29] MITIE0 : (RO) M-Mode Internal Timer0 interrupt enable
+ // [28] MITIE1 : (RO) M-Mode Internal Timer1 interrupt enable
// [11] MEIE : (RW) M-Mode external interrupt enable
// [7] MTIE : (RW) M-Mode timer interrupt enable
// [3] MSIE : (RW) M-Mode software interrupt enable
`define MIE 12'h304
assign wr_mie_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == `MIE);
- assign mie_ns[3:0] = wr_mie_r ? {dec_csr_wrdata_r[30], dec_csr_wrdata_r[11], dec_csr_wrdata_r[7], dec_csr_wrdata_r[3]} : mie[3:0];
- rvdff #(4) mie_ff (.*, .clk(csr_wr_clk), .din(mie_ns[3:0]), .dout(mie[3:0]));
+ assign mie_ns[5:0] = wr_mie_r ? {dec_csr_wrdata_r[30:28], dec_csr_wrdata_r[11], dec_csr_wrdata_r[7], dec_csr_wrdata_r[3]} : mie[5:0];
+ rvdff #(6) mie_ff (.*, .clk(csr_wr_clk), .din(mie_ns[5:0]), .dout(mie[5:0]));
// ----------------------------------------------------------------------
@@ -1286,18 +1332,21 @@ end
assign wr_mscause_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == `MSCAUSE);
- assign mscause_type[2:0] = ( ({3{lsu_i0_exc_r}} & lsu_error_pkt_r.mscause[2:0]) |
- ({3{i0_trigger_hit_r}} & 3'b001) |
- ({3{inst_acc_r}} & {1'b0,dec_tlu_packet_r.icaf_type[1:0]})
+ assign ifu_mscause[3:0] = (dec_tlu_packet_r.icaf_type[1:0] == 2'b00) ? 4'b1001 :
+ {2'b00 , dec_tlu_packet_r.icaf_type[1:0]} ;
+
+ assign mscause_type[3:0] = ( ({4{lsu_i0_exc_r}} & lsu_error_pkt_r.mscause[3:0]) |
+ ({4{i0_trigger_hit_r}} & 4'b0001) |
+ ({4{ebreak_r}} & 4'b0010) |
+ ({4{inst_acc_r}} & ifu_mscause[3:0])
);
-
- assign mscause_ns[2:0] = ( ({3{exc_or_int_valid_r}} & mscause_type[2:0]) |
- ({3{ wr_mscause_r & ~exc_or_int_valid_r}} & dec_csr_wrdata_r[2:0]) |
- ({3{~wr_mscause_r & ~exc_or_int_valid_r}} & mscause[2:0])
+ assign mscause_ns[3:0] = ( ({4{exc_or_int_valid_r}} & mscause_type[3:0]) |
+ ({4{ wr_mscause_r & ~exc_or_int_valid_r}} & dec_csr_wrdata_r[3:0]) |
+ ({4{~wr_mscause_r & ~exc_or_int_valid_r}} & mscause[3:0])
);
- rvdff #(3) mscause_ff (.*, .clk(e4e5_int_clk), .din(mscause_ns[2:0]), .dout(mscause[2:0]));
+ rvdff #(4) mscause_ff (.*, .clk(e4e5_int_clk), .din(mscause_ns[3:0]), .dout(mscause[3:0]));
// ----------------------------------------------------------------------
// MTVAL (RW)
// [31:0] : Exception address if relevant
@@ -2036,7 +2085,7 @@ else
({1{(mhpme_vec[i][9:0] == `MHPME_DMA_DCCM_STALL )}} & { dma_dccm_stall_any}) |
({1{(mhpme_vec[i][9:0] == `MHPME_DMA_ICCM_STALL )}} & { dma_iccm_stall_any}) |
({1{(mhpme_vec[i][9:0] == `MHPME_EXC_TAKEN )}} & { (i0_exception_valid_r | i0_trigger_hit_r | lsu_exc_valid_r)}) |
- ({1{(mhpme_vec[i][9:0] == `MHPME_TIMER_INT_TAKEN )}} & { take_timer_int}) |
+ ({1{(mhpme_vec[i][9:0] == `MHPME_TIMER_INT_TAKEN )}} & { take_timer_int | take_int_timer0_int | take_int_timer1_int}) |
({1{(mhpme_vec[i][9:0] == `MHPME_EXT_INT_TAKEN )}} & { take_ext_int}) |
({1{(mhpme_vec[i][9:0] == `MHPME_FLUSH_LOWER )}} & { tlu_flush_lower_r}) |
({1{(mhpme_vec[i][9:0] == `MHPME_BR_ERROR )}} & {(dec_tlu_br0_error_r | dec_tlu_br0_start_error_r) & rfpc_i0_r}) |
@@ -2048,7 +2097,7 @@ else
({1{(mhpme_vec[i][9:0] == `MHPME_IBUS_STALL )}} & {ifu_pmu_bus_busy}) |
({1{(mhpme_vec[i][9:0] == `MHPME_DBUS_STALL )}} & {lsu_pmu_bus_busy}) |
({1{(mhpme_vec[i][9:0] == `MHPME_INT_DISABLED )}} & {~mstatus[`MSTATUS_MIE]}) |
- ({1{(mhpme_vec[i][9:0] == `MHPME_INT_STALLED )}} & {~mstatus[`MSTATUS_MIE] & |(mip[3:0] & mie[3:0])}) |
+ ({1{(mhpme_vec[i][9:0] == `MHPME_INT_STALLED )}} & {~mstatus[`MSTATUS_MIE] & |(mip[5:0] & mie[5:0])}) |
({1{(mhpme_vec[i][9:0] == `MHPME_INST_BITMANIP )}} & {(pmu_i0_itype_qual == BITMANIPU)}) |
({1{(mhpme_vec[i][9:0] == `MHPME_DBUS_LOAD )}} & {tlu_i0_commit_cmt & lsu_pmu_load_external_r}) |
({1{(mhpme_vec[i][9:0] == `MHPME_DBUS_STORE )}} & {tlu_i0_commit_cmt & lsu_pmu_store_external_r}) |
@@ -2252,7 +2301,7 @@ assign csr_mvendorid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[7]
assign csr_marchid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[7]
&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
-assign csr_mimpid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[3]
+assign csr_mimpid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[6]
&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]);
assign csr_mhartid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[7]
@@ -2261,8 +2310,8 @@ assign csr_mhartid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[7]
assign csr_mstatus = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]);
-assign csr_mtvec = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[5]
- &dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]);
+assign csr_mtvec = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[6]
+ &!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]);
assign csr_mip = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[2]);
@@ -2297,13 +2346,13 @@ assign csr_mcause = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
assign csr_mscause = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[2]);
-assign csr_mtval = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[1]
+assign csr_mtval = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[1]
&dec_csr_rdaddr_d[0]);
assign csr_mrac = (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]);
-assign csr_dmst = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[3]
+assign csr_dmst = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]);
assign csr_mdseac = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]
@@ -2398,10 +2447,28 @@ assign csr_mcountinhibit = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
&!dec_csr_rdaddr_d[0]);
-assign csr_mpmc = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2]
- &dec_csr_rdaddr_d[1]);
+assign csr_mitctl0 = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
+ &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
-assign csr_mcpc = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
+assign csr_mitctl1 = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[3]
+ &dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]);
+
+assign csr_mitb0 = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]
+ &!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]);
+
+assign csr_mitb1 = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[2]
+ &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
+
+assign csr_mitcnt0 = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
+ &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]);
+
+assign csr_mitcnt1 = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[2]
+ &!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]);
+
+assign csr_mpmc = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
+ &dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]);
+
+assign csr_mcpc = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]);
assign csr_meicpct = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[6]
@@ -2410,13 +2477,13 @@ assign csr_meicpct = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[6]
assign csr_mdeau = (!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[7]
&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[3]);
-assign csr_micect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
+assign csr_micect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
-assign csr_miccmect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[4]
+assign csr_miccmect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[0]);
-assign csr_mdccmect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[4]
+assign csr_mdccmect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
assign csr_mfdht = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2]
@@ -2432,13 +2499,13 @@ assign csr_dicawics = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[5]
assign csr_dicad0h = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[3]
&dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]);
-assign csr_dicad0 = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[5]
+assign csr_dicad0 = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]
&dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]);
assign csr_dicad1 = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
-assign csr_dicago = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[7]
+assign csr_dicago = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]);
assign presync = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
@@ -2455,107 +2522,118 @@ assign presync = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
assign postsync = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
- &!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]
+ &!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]
&dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[10]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[0]) | (
!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[7]
- &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]) | (
- dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
- &!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]);
+ &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
+ &!dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]
+ &!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]);
-assign legal = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
+assign legal = (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
+ &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
+ &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
+ &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
+ &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
+ &!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
+ &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]) | (
+ !dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
&dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (
dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]
- &!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
- &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]
- &!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
- &!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[11]
- &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
- &!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[0]) | (
- !dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
- &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
- &dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
- &dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (
- !dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
- &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
- &dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2]
- &!dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]
- &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]
- &dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]
- &!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]) | (
- !dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
- &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
- &dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
- &!dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]
- &dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
- &!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
- &!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
+ &!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
+ &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]
+ &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
- &dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
- &!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[1]) | (
+ &dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
+ &dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2]
+ &dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
+ &dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
+ &dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
+ &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | (
dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
- &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2]
- &!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]
+ &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
+ &dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]
+ &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]
+ &!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[3]
+ &!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11]
+ &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
+ &!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
+ &dec_csr_rdaddr_d[2]) | (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]
+ &dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
+ &!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
+ &dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (
+ !dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
+ &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
+ &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
+ &dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]
+ &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]
+ &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]
+ &!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2]) | (dec_csr_rdaddr_d[11]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]) | (
!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
- &dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]) | (dec_csr_rdaddr_d[11]
- &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
- &dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
- &dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]) | (!dec_csr_rdaddr_d[11]
- &dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
- &dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
- &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
- &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
- &!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
- &dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]
- &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
- &dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
- &dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (
- !dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
- &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
- &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
- &!dec_csr_rdaddr_d[2]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
+ &dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (
+ dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
+ &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]
+ &!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]) | (
+ dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
+ &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]
+ &!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]
+ &!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]) | (!dec_csr_rdaddr_d[11]
&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
- &dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
- &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
- &!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
- &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]
- &!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11]
- &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
- &!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
- &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]) | (
- !dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
- &dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]
- &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]
- &!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
+ &dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
+ &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[1]) | (
+ !dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
+ &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
+ &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[0]) | (
+ !dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
+ &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
+ &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
+ &!dec_csr_rdaddr_d[2]) | (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]
+ &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]
+ &!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
+ &!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]) | (
+ dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
+ &dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
+ &dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]
- &!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[3]) | (
+ &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
+ &!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]) | (!dec_csr_rdaddr_d[11]
+ &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
+ &!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
+ &!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (
+ !dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
+ &dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
+ &dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[3]) | (dec_csr_rdaddr_d[11]
+ &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
+ &!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[3]) | (
!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]) | (dec_csr_rdaddr_d[11]
&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
- &!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[3]) | (
- dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
- &dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
- &dec_csr_rdaddr_d[4]);
+ &!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]);
+
assign dec_tlu_presync_d = presync & dec_csr_any_unq_d & ~dec_csr_wen_unq_d;
assign dec_tlu_postsync_d = postsync & dec_csr_any_unq_d;
+ // allow individual configuration of these features
+assign conditionally_illegal = (csr_mitcnt0 | csr_mitcnt1 | csr_mitb0 | csr_mitb1 | csr_mitctl0 | csr_mitctl1) & ~pt.TIMER_LEGAL_EN;
+
+
assign valid_csr = ( legal & (~(csr_dcsr | csr_dpc | csr_dmst | csr_dicawics | csr_dicad0 | csr_dicad0h | csr_dicad1 | csr_dicago) | dbg_tlu_halted_f)
- & ~fast_int_meicpct);
+ & ~fast_int_meicpct & ~conditionally_illegal);
assign dec_csr_legal_d = ( dec_csr_any_unq_d &
valid_csr & // of a valid CSR
@@ -2565,12 +2643,12 @@ assign dec_csr_legal_d = ( dec_csr_any_unq_d &
assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) |
({32{csr_mvendorid}} & 32'h00000045) |
({32{csr_marchid}} & 32'h00000010) |
- ({32{csr_mimpid}} & 32'h1) |
+ ({32{csr_mimpid}} & 32'h2) |
({32{csr_mhartid}} & {core_id[31:4], 4'b0}) |
({32{csr_mstatus}} & {19'b0, 2'b11, 3'b0, mstatus[1], 3'b0, mstatus[0], 3'b0}) |
({32{csr_mtvec}} & {mtvec[30:1], 1'b0, mtvec[0]}) |
- ({32{csr_mip}} & {1'b0, mip[3], 18'b0, mip[2], 3'b0, mip[1], 3'b0, mip[0], 3'b0}) |
- ({32{csr_mie}} & {1'b0, mie[3], 18'b0, mie[2], 3'b0, mie[1], 3'b0, mie[0], 3'b0}) |
+ ({32{csr_mip}} & {1'b0, mip[5:3], 16'b0, mip[2], 3'b0, mip[1], 3'b0, mip[0], 3'b0}) |
+ ({32{csr_mie}} & {1'b0, mie[5:3], 16'b0, mie[2], 3'b0, mie[1], 3'b0, mie[0], 3'b0}) |
({32{csr_mcyclel}} & mcyclel[31:0]) |
({32{csr_mcycleh}} & mcycleh_inc[31:0]) |
({32{csr_minstretl}} & minstretl_read[31:0]) |
@@ -2578,7 +2656,7 @@ assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) |
({32{csr_mscratch}} & mscratch[31:0]) |
({32{csr_mepc}} & {mepc[31:1], 1'b0}) |
({32{csr_mcause}} & mcause[31:0]) |
- ({32{csr_mscause}} & {29'b0, mscause[2:0]}) |
+ ({32{csr_mscause}} & {28'b0, mscause[3:0]}) |
({32{csr_mtval}} & mtval[31:0]) |
({32{csr_mrac}} & mrac[31:0]) |
({32{csr_mdseac}} & mdseac[31:0]) |
@@ -2616,7 +2694,158 @@ assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) |
({32{csr_mhpme5}} & {22'b0,mhpme5[9:0]}) |
({32{csr_mhpme6}} & {22'b0,mhpme6[9:0]}) |
({32{csr_mcountinhibit}} & {25'b0, mcountinhibit[6:0]}) |
- ({32{csr_mpmc}} & {30'b0, mpmc[1], 1'b0})
+ ({32{csr_mpmc}} & {30'b0, mpmc[1], 1'b0}) |
+ ({32{dec_timer_read_d}} & dec_timer_rddata_d[31:0])
);
endmodule // el2_dec_tlu_ctl
+
+module el2_dec_timer_ctl #(
+`include "el2_param.vh"
+ )
+ (
+ input logic clk,
+ input logic free_clk,
+ input logic rst_l,
+ input logic dec_csr_wen_r_mod, // csr write enable at wb
+ input logic [11:0] dec_csr_rdaddr_d, // read address for csr
+ input logic [11:0] dec_csr_wraddr_r, // write address for csr
+ input logic [31:0] dec_csr_wrdata_r, // csr write data at wb
+
+ input logic csr_mitctl0,
+ input logic csr_mitctl1,
+ input logic csr_mitb0,
+ input logic csr_mitb1,
+ input logic csr_mitcnt0,
+ input logic csr_mitcnt1,
+
+
+ input logic dec_pause_state, // Paused
+ input logic dec_tlu_pmu_fw_halted, // pmu/fw halted
+ input logic internal_dbg_halt_timers, // debug halted
+
+ output logic [31:0] dec_timer_rddata_d, // timer CSR read data
+ output logic dec_timer_read_d, // timer CSR address match
+ output logic dec_timer_t0_pulse, // timer0 int
+ output logic dec_timer_t1_pulse, // timer1 int
+
+ input logic scan_mode
+ );
+ `define MITCTL_ENABLE 0
+ `define MITCTL_ENABLE_HALTED 1
+ `define MITCTL_ENABLE_PAUSED 2
+
+ logic [31:0] mitcnt0_ns, mitcnt0, mitcnt1_ns, mitcnt1, mitb0, mitb1, mitb0_b, mitb1_b, mitcnt0_inc, mitcnt1_inc;
+ logic [2:0] mitctl0_ns, mitctl0;
+ logic [3:0] mitctl1_ns, mitctl1;
+ logic wr_mitcnt0_r, wr_mitcnt1_r, wr_mitb0_r, wr_mitb1_r, wr_mitctl0_r, wr_mitctl1_r;
+ logic mitcnt0_inc_ok, mitcnt1_inc_ok;
+
+ logic mit0_match_ns;
+ logic mit1_match_ns;
+ logic mitctl0_0_b_ns;
+ logic mitctl0_0_b;
+ logic mitctl1_0_b_ns;
+ logic mitctl1_0_b;
+
+ assign mit0_match_ns = (mitcnt0[31:0] >= mitb0[31:0]);
+ assign mit1_match_ns = (mitcnt1[31:0] >= mitb1[31:0]);
+
+ assign dec_timer_t0_pulse = mit0_match_ns;
+ assign dec_timer_t1_pulse = mit1_match_ns;
+ // ----------------------------------------------------------------------
+ // MITCNT0 (RW)
+ // [31:0] : Internal Timer Counter 0
+
+ `define MITCNT0 12'h7d2
+
+ assign wr_mitcnt0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == `MITCNT0);
+
+ assign mitcnt0_inc_ok = mitctl0[`MITCTL_ENABLE] & (~dec_pause_state | mitctl0[`MITCTL_ENABLE_PAUSED]) & (~dec_tlu_pmu_fw_halted | mitctl0[`MITCTL_ENABLE_HALTED]) & ~internal_dbg_halt_timers;
+
+ assign mitcnt0_inc[31:0] = mitcnt0[31:0] + {31'b0, 1'b1};
+ assign mitcnt0_ns[31:0] = mit0_match_ns ? 'b0 : wr_mitcnt0_r ? dec_csr_wrdata_r[31:0] : mitcnt0_inc[31:0];
+
+ rvdffe #(32) mitcnt0_ff (.*, .en(wr_mitcnt0_r | mitcnt0_inc_ok | mit0_match_ns), .din(mitcnt0_ns[31:0]), .dout(mitcnt0[31:0]));
+
+ // ----------------------------------------------------------------------
+ // MITCNT1 (RW)
+ // [31:0] : Internal Timer Counter 0
+
+ `define MITCNT1 12'h7d5
+
+ assign wr_mitcnt1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == `MITCNT1);
+
+ assign mitcnt1_inc_ok = mitctl1[`MITCTL_ENABLE] & (~dec_pause_state | mitctl1[`MITCTL_ENABLE_PAUSED]) & (~dec_tlu_pmu_fw_halted | mitctl1[`MITCTL_ENABLE_HALTED]) & ~internal_dbg_halt_timers;
+
+ // only inc MITCNT1 if not cascaded with 0, or if 0 overflows
+ assign mitcnt1_inc[31:0] = mitcnt1[31:0] + {31'b0, (~mitctl1[3] | mit0_match_ns)};
+ assign mitcnt1_ns[31:0] = mit1_match_ns ? 'b0 : wr_mitcnt1_r ? dec_csr_wrdata_r[31:0] : mitcnt1_inc[31:0];
+
+ rvdffe #(32) mitcnt1_ff (.*, .en(wr_mitcnt1_r | mitcnt1_inc_ok | mit1_match_ns), .din(mitcnt1_ns[31:0]), .dout(mitcnt1[31:0]));
+
+ // ----------------------------------------------------------------------
+ // MITB0 (RW)
+ // [31:0] : Internal Timer Bound 0
+
+ `define MITB0 12'h7d3
+
+ assign wr_mitb0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == `MITB0);
+
+ rvdffe #(32) mitb0_ff (.*, .en(wr_mitb0_r), .din(~dec_csr_wrdata_r[31:0]), .dout(mitb0_b[31:0]));
+ assign mitb0[31:0] = ~mitb0_b[31:0];
+
+ // ----------------------------------------------------------------------
+ // MITB1 (RW)
+ // [31:0] : Internal Timer Bound 1
+
+ `define MITB1 12'h7d6
+
+ assign wr_mitb1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == `MITB1);
+
+ rvdffe #(32) mitb1_ff (.*, .en(wr_mitb1_r), .din(~dec_csr_wrdata_r[31:0]), .dout(mitb1_b[31:0]));
+ assign mitb1[31:0] = ~mitb1_b[31:0];
+
+ // ----------------------------------------------------------------------
+ // MITCTL0 (RW) Internal Timer Ctl 0
+ // [31:3] : Reserved, reads 0x0
+ // [2] : Enable while PAUSEd
+ // [1] : Enable while HALTed
+ // [0] : Enable (resets to 0x1)
+
+ `define MITCTL0 12'h7d4
+
+ assign wr_mitctl0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == `MITCTL0);
+ assign mitctl0_ns[2:0] = wr_mitctl0_r ? {dec_csr_wrdata_r[2:0]} : {mitctl0[2:0]};
+
+ assign mitctl0_0_b_ns = ~mitctl0_ns[0];
+ rvdff #(3) mitctl0_ff (.*, .clk(free_clk), .din({mitctl0_ns[2:1], mitctl0_0_b_ns}), .dout({mitctl0[2:1], mitctl0_0_b}));
+ assign mitctl0[0] = ~mitctl0_0_b;
+
+ // ----------------------------------------------------------------------
+ // MITCTL1 (RW) Internal Timer Ctl 1
+ // [31:4] : Reserved, reads 0x0
+ // [3] : Cascade
+ // [2] : Enable while PAUSEd
+ // [1] : Enable while HALTed
+ // [0] : Enable (resets to 0x1)
+
+ `define MITCTL1 12'h7d7
+
+ assign wr_mitctl1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == `MITCTL1);
+ assign mitctl1_ns[3:0] = wr_mitctl1_r ? {dec_csr_wrdata_r[3:0]} : {mitctl1[3:0]};
+
+ assign mitctl1_0_b_ns = ~mitctl1_ns[0];
+ rvdff #(4) mitctl1_ff (.*, .clk(free_clk), .din({mitctl1_ns[3:1], mitctl1_0_b_ns}), .dout({mitctl1[3:1], mitctl1_0_b}));
+ assign mitctl1[0] = ~mitctl1_0_b;
+ assign dec_timer_read_d = csr_mitcnt1 | csr_mitcnt0 | csr_mitb1 | csr_mitb0 | csr_mitctl0 | csr_mitctl1;
+ assign dec_timer_rddata_d[31:0] = ( ({32{csr_mitcnt0}} & mitcnt0[31:0]) |
+ ({32{csr_mitcnt1}} & mitcnt1[31:0]) |
+ ({32{csr_mitb0}} & mitb0[31:0]) |
+ ({32{csr_mitb1}} & mitb1[31:0]) |
+ ({32{csr_mitctl0}} & {29'b0, mitctl0[2:0]}) |
+ ({32{csr_mitctl1}} & {28'b0, mitctl1[3:0]})
+ );
+
+
+endmodule // dec_timer_ctl
diff --git a/design/el2_swerv.sv b/design/el2_swerv.sv
index b6943b0..578c149 100644
--- a/design/el2_swerv.sv
+++ b/design/el2_swerv.sv
@@ -793,6 +793,12 @@ import el2_pkg::*;
logic lsu_fastint_stall_any;
+ logic [7:0] pic_claimid;
+ logic [3:0] pic_pl, dec_tlu_meicurpl, dec_tlu_meipt;
+ logic mexintpend;
+ logic mhwakeup;
+
+
//assign lsu_fastint_stall_any = 1'b0;
assign active_state = (~dec_pause_state_cg | dec_tlu_flush_lower_r) | dec_tlu_misc_clk_override;
@@ -882,12 +888,6 @@ import el2_pkg::*;
);
- logic [7:0] pic_claimid;
- logic [3:0] pic_pl, dec_tlu_meicurpl, dec_tlu_meipt;
-
- logic mexintpend;
- logic mhwakeup;
-
el2_pic_ctrl #(.pt(pt)) pic_ctrl_inst (
.clk_override(dec_tlu_pic_clk_override),
.picm_mken (picm_mken),
diff --git a/design/include/el2_def.sv b/design/include/el2_def.sv
index 9acbcf7..2b283ca 100644
--- a/design/include/el2_def.sv
+++ b/design/include/el2_def.sv
@@ -164,7 +164,7 @@ typedef struct packed {
logic single_ecc_error;
logic inst_type; //0: Load, 1: Store
logic exc_type; //0: MisAligned, 1: Access Fault
- logic [2:0] mscause;
+ logic [3:0] mscause;
logic [31:0] addr;
} el2_lsu_error_pkt_t;
diff --git a/design/lsu/el2_lsu_addrcheck.sv b/design/lsu/el2_lsu_addrcheck.sv
index 77329fc..e63db2b 100644
--- a/design/lsu/el2_lsu_addrcheck.sv
+++ b/design/lsu/el2_lsu_addrcheck.sv
@@ -45,7 +45,7 @@ import el2_pkg::*;
output logic access_fault_d, // access fault
output logic misaligned_fault_d, // misaligned
- output logic [2:0] exc_mscause_d, // mscause for access/misaligned faults
+ output logic [3:0] exc_mscause_d, // mscause for access/misaligned faults
output logic fir_dccm_access_error_d, // Fast interrupt dccm access error
output logic fir_nondccm_access_error_d,// Fast interrupt dccm access error
@@ -66,8 +66,8 @@ import el2_pkg::*;
logic base_reg_dccm_or_pic;
logic unmapped_access_fault_d, mpu_access_fault_d, picm_access_fault_d, regpred_access_fault_d;
logic regcross_misaligned_fault_d, sideeffect_misaligned_fault_d;
- logic [2:0] access_fault_mscause_d;
- logic misaligned_fault_mscause_d;
+ logic [3:0] access_fault_mscause_d;
+ logic [3:0] misaligned_fault_mscause_d;
if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable
// Start address check
@@ -169,7 +169,7 @@ import el2_pkg::*;
end
assign access_fault_d = (unmapped_access_fault_d | mpu_access_fault_d | picm_access_fault_d | regpred_access_fault_d) & lsu_pkt_d.valid & ~lsu_pkt_d.dma;
- assign access_fault_mscause_d[2:0] = unmapped_access_fault_d ? 3'h0 : mpu_access_fault_d ? 3'h3 : regpred_access_fault_d ? 3'h5 : picm_access_fault_d ? 3'h6 : 3'h7;
+ assign access_fault_mscause_d[3:0] = unmapped_access_fault_d ? 4'h2 : mpu_access_fault_d ? 4'h3 : regpred_access_fault_d ? 4'h5 : picm_access_fault_d ? 4'h6 : 4'h0;
// Misaligned happens due to 2 reasons
// 0. Region cross
@@ -177,9 +177,9 @@ import el2_pkg::*;
assign regcross_misaligned_fault_d = (start_addr_d[31:28] != end_addr_d[31:28]);
assign sideeffect_misaligned_fault_d = (is_sideeffects_d & ~is_aligned_d);
assign misaligned_fault_d = (regcross_misaligned_fault_d | (sideeffect_misaligned_fault_d & addr_external_d)) & lsu_pkt_d.valid & ~lsu_pkt_d.dma;
- assign misaligned_fault_mscause_d = regcross_misaligned_fault_d ? 1'b0 : 1'b1;
+ assign misaligned_fault_mscause_d[3:0] = regcross_misaligned_fault_d ? 4'h2 : sideeffect_misaligned_fault_d ? 4'h1 : 4'h0;
- assign exc_mscause_d[2:0] = misaligned_fault_d ? {2'b0,misaligned_fault_mscause_d} : access_fault_mscause_d[2:0];
+ assign exc_mscause_d[3:0] = misaligned_fault_d ? misaligned_fault_mscause_d[3:0] : access_fault_mscause_d[3:0];
// Fast interrupt error logic
assign fir_dccm_access_error_d = ((start_addr_in_dccm_region_d & ~start_addr_in_dccm_d) |
diff --git a/design/lsu/el2_lsu_lsc_ctl.sv b/design/lsu/el2_lsu_lsc_ctl.sv
index ed748b1..1df3e2f 100644
--- a/design/lsu/el2_lsu_lsc_ctl.sv
+++ b/design/lsu/el2_lsu_lsc_ctl.sv
@@ -128,7 +128,7 @@ import el2_pkg::*;
logic fir_dccm_access_error_d, fir_nondccm_access_error_d;
logic fir_dccm_access_error_m, fir_nondccm_access_error_m;
- logic [2:0] exc_mscause_d, exc_mscause_m;
+ logic [3:0] exc_mscause_d, exc_mscause_m;
logic [31:0] rs1_d_raw;
logic [31:0] store_data_d, store_data_pre_m, store_data_m_in;
logic [31:0] bus_read_data_r;
@@ -173,7 +173,7 @@ import el2_pkg::*;
if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U_Plus1_1
logic access_fault_r, misaligned_fault_r;
- logic [2:0] exc_mscause_r;
+ logic [3:0] exc_mscause_r;
logic fir_dccm_access_error_r, fir_nondccm_access_error_r;
// Generate exception packet
@@ -181,14 +181,14 @@ import el2_pkg::*;
assign lsu_error_pkt_r.single_ecc_error = lsu_single_ecc_error_r & ~lsu_error_pkt_r.exc_valid & ~lsu_pkt_r.dma;
assign lsu_error_pkt_r.inst_type = lsu_pkt_r.store;
assign lsu_error_pkt_r.exc_type = ~misaligned_fault_r;
- assign lsu_error_pkt_r.mscause[2:0] = (lsu_double_ecc_error_r & ~misaligned_fault_r & ~access_fault_r) ? 3'h1 : exc_mscause_r[2:0];
+ assign lsu_error_pkt_r.mscause[3:0] = (lsu_double_ecc_error_r & ~misaligned_fault_r & ~access_fault_r) ? 4'h1 : exc_mscause_r[3:0];
assign lsu_error_pkt_r.addr[31:0] = lsu_addr_r[31:0];
assign lsu_fir_error[1:0] = fir_nondccm_access_error_r ? 2'b11 : (fir_dccm_access_error_r ? 2'b10 : ((lsu_pkt_r.fast_int & lsu_double_ecc_error_r) ? 2'b01 : 2'b00));
rvdff #(1) access_fault_rff (.din(access_fault_m), .dout(access_fault_r), .clk(lsu_c1_r_clk), .*);
rvdff #(1) misaligned_fault_rff (.din(misaligned_fault_m), .dout(misaligned_fault_r), .clk(lsu_c1_r_clk), .*);
- rvdff #(3) exc_mscause_rff (.din(exc_mscause_m[2:0]), .dout(exc_mscause_r[2:0]), .clk(lsu_c1_r_clk), .*);
+ rvdff #(4) exc_mscause_rff (.din(exc_mscause_m[3:0]), .dout(exc_mscause_r[3:0]), .clk(lsu_c1_r_clk), .*);
rvdff #(1) fir_dccm_access_error_mff (.din(fir_dccm_access_error_m), .dout(fir_dccm_access_error_r), .clk(lsu_c1_r_clk), .*);
rvdff #(1) fir_nondccm_access_error_mff (.din(fir_nondccm_access_error_m), .dout(fir_nondccm_access_error_r), .clk(lsu_c1_r_clk), .*);
@@ -200,7 +200,7 @@ import el2_pkg::*;
assign lsu_error_pkt_m.single_ecc_error = lsu_single_ecc_error_m & ~lsu_error_pkt_m.exc_valid & ~lsu_pkt_m.dma;
assign lsu_error_pkt_m.inst_type = lsu_pkt_m.store;
assign lsu_error_pkt_m.exc_type = ~misaligned_fault_m;
- assign lsu_error_pkt_m.mscause[2:0] = (lsu_double_ecc_error_m & ~misaligned_fault_m & ~access_fault_m) ? 3'h1 : exc_mscause_m[2:0];
+ assign lsu_error_pkt_m.mscause[3:0] = (lsu_double_ecc_error_m & ~misaligned_fault_m & ~access_fault_m) ? 4'h1 : exc_mscause_m[3:0];
assign lsu_error_pkt_m.addr[31:0] = lsu_addr_m[31:0];
assign lsu_fir_error_m[1:0] = fir_nondccm_access_error_m ? 2'b11 : (fir_dccm_access_error_m ? 2'b10 : ((lsu_pkt_m.fast_int & lsu_double_ecc_error_m) ? 2'b01 : 2'b00));
@@ -318,7 +318,7 @@ import el2_pkg::*;
rvdff #(1) access_fault_mff (.din(access_fault_d), .dout(access_fault_m), .clk(lsu_c1_m_clk), .*);
rvdff #(1) misaligned_fault_mff (.din(misaligned_fault_d), .dout(misaligned_fault_m), .clk(lsu_c1_m_clk), .*);
- rvdff #(3) exc_mscause_mff (.din(exc_mscause_d[2:0]), .dout(exc_mscause_m[2:0]), .clk(lsu_c1_m_clk), .*);
+ rvdff #(4) exc_mscause_mff (.din(exc_mscause_d[3:0]), .dout(exc_mscause_m[3:0]), .clk(lsu_c1_m_clk), .*);
rvdff #(1) fir_dccm_access_error_mff (.din(fir_dccm_access_error_d), .dout(fir_dccm_access_error_m), .clk(lsu_c1_m_clk), .*);
rvdff #(1) fir_nondccm_access_error_mff (.din(fir_nondccm_access_error_d), .dout(fir_nondccm_access_error_m), .clk(lsu_c1_m_clk), .*);
diff --git a/release-notes.md b/release-notes.md
index 169c669..1e3f79a 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -1,3 +1,14 @@
+# EL2 SweRV RISC-V CoreTM 1.2 from Western Digital
+
+## Release Notes
+
+### Bug fixes
+
+### Improvements
+
+Internal timers.
+
+
# EL2 SweRV RISC-V CoreTM 1.1 from Western Digital
## Release Notes
diff --git a/tools/addassign b/tools/addassign
index c1b9998..a1d4217 100755
--- a/tools/addassign
+++ b/tools/addassign
@@ -1,4 +1,19 @@
#!/usr/bin/perl
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2020 Western Digital Corporation or its affiliates.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
use Getopt::Long;
diff --git a/tools/coredecode b/tools/coredecode
index f2ce7ef..5daad7d 100755
--- a/tools/coredecode
+++ b/tools/coredecode
@@ -1,4 +1,19 @@
#!/usr/bin/perl
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2020 Western Digital Corporation or its affiliates.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
use Getopt::Long;
diff --git a/tools/picmap b/tools/picmap
index 06df0d5..f2a2d04 100755
--- a/tools/picmap
+++ b/tools/picmap
@@ -1,4 +1,19 @@
#!/usr/bin/perl
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2020 Western Digital Corporation or its affiliates.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
use Getopt::Long;
diff --git a/tools/smalldiv b/tools/smalldiv
index 48495be..80cad8e 100755
--- a/tools/smalldiv
+++ b/tools/smalldiv
@@ -1,4 +1,19 @@
#!/usr/bin/perl
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2020 Western Digital Corporation or its affiliates.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
use Getopt::Long;