Line 6... |
Line 6... |
-- # words) and an execute engine (responsible for actually executing the instructions), a trap #
|
-- # words) and an execute engine (responsible for actually executing the instructions), a trap #
|
-- # handling controller and the RISC-V status and control register set (CSRs). #
|
-- # handling controller and the RISC-V status and control register set (CSRs). #
|
-- # ********************************************************************************************* #
|
-- # ********************************************************************************************* #
|
-- # BSD 3-Clause License #
|
-- # BSD 3-Clause License #
|
-- # #
|
-- # #
|
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved. #
|
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
|
-- # #
|
-- # #
|
-- # Redistribution and use in source and binary forms, with or without modification, are #
|
-- # Redistribution and use in source and binary forms, with or without modification, are #
|
-- # permitted provided that the following conditions are met: #
|
-- # permitted provided that the following conditions are met: #
|
-- # #
|
-- # #
|
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
|
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
|
Line 56... |
Line 56... |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
|
-- Physical memory protection (PMP) --
|
-- Physical memory protection (PMP) --
|
PMP_USE : boolean := false -- implement physical memory protection?
|
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
|
|
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
|
|
-- Hardware Performance Monitors (HPM) --
|
|
HPM_NUM_CNTS : natural := 0 -- number of inmplemnted HPM counters (0..29)
|
);
|
);
|
port (
|
port (
|
-- global control --
|
-- global control --
|
clk_i : in std_ulogic; -- global clock, rising edge
|
clk_i : in std_ulogic; -- global clock, rising edge
|
rstn_i : in std_ulogic; -- global reset, low-active, async
|
rstn_i : in std_ulogic; -- global reset, low-active, async
|
Line 106... |
Line 109... |
-- instruction fetch enginge --
|
-- instruction fetch enginge --
|
type fetch_engine_state_t is (IFETCH_RESET, IFETCH_REQUEST, IFETCH_ISSUE);
|
type fetch_engine_state_t is (IFETCH_RESET, IFETCH_REQUEST, IFETCH_ISSUE);
|
type fetch_engine_t is record
|
type fetch_engine_t is record
|
state : fetch_engine_state_t;
|
state : fetch_engine_state_t;
|
state_nxt : fetch_engine_state_t;
|
state_nxt : fetch_engine_state_t;
|
|
state_prev : fetch_engine_state_t;
|
pc : std_ulogic_vector(data_width_c-1 downto 0);
|
pc : std_ulogic_vector(data_width_c-1 downto 0);
|
pc_nxt : std_ulogic_vector(data_width_c-1 downto 0);
|
pc_nxt : std_ulogic_vector(data_width_c-1 downto 0);
|
reset : std_ulogic;
|
reset : std_ulogic;
|
bus_err_ack : std_ulogic;
|
bus_err_ack : std_ulogic;
|
end record;
|
end record;
|
Line 164... |
Line 168... |
-- instruction execution engine --
|
-- instruction execution engine --
|
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP, EXECUTE, ALU_WAIT, BRANCH, FENCE_OP, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS);
|
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP, EXECUTE, ALU_WAIT, BRANCH, FENCE_OP, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS);
|
type execute_engine_t is record
|
type execute_engine_t is record
|
state : execute_engine_state_t;
|
state : execute_engine_state_t;
|
state_nxt : execute_engine_state_t;
|
state_nxt : execute_engine_state_t;
|
|
state_prev : execute_engine_state_t;
|
--
|
--
|
i_reg : std_ulogic_vector(31 downto 0);
|
i_reg : std_ulogic_vector(31 downto 0);
|
i_reg_nxt : std_ulogic_vector(31 downto 0);
|
i_reg_nxt : std_ulogic_vector(31 downto 0);
|
i_reg_last : std_ulogic_vector(31 downto 0); -- last executed instruction
|
i_reg_last : std_ulogic_vector(31 downto 0); -- last executed instruction
|
--
|
--
|
Line 229... |
Line 234... |
|
|
-- fast instruction fetch access --
|
-- fast instruction fetch access --
|
signal bus_fast_ir : std_ulogic;
|
signal bus_fast_ir : std_ulogic;
|
|
|
-- RISC-V control and status registers (CSRs) --
|
-- RISC-V control and status registers (CSRs) --
|
type pmp_ctrl_t is array (0 to pmp_max_r_c-1) of std_ulogic_vector(7 downto 0);
|
type pmp_ctrl_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(7 downto 0);
|
type pmp_addr_t is array (0 to pmp_max_r_c-1) of std_ulogic_vector(data_width_c-1 downto 0);
|
type pmp_addr_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c-1 downto 0);
|
|
type pmp_ctrl_rd_t is array (0 to 63) of std_ulogic_vector(7 downto 0);
|
|
type pmp_addr_rd_t is array (0 to 63) of std_ulogic_vector(data_width_c-1 downto 0);
|
|
type mhpmevent_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(hpmcnt_event_size_c-1 downto 0);
|
|
type mhpmcnt_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(32 downto 0);
|
|
type mhpmcnth_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(31 downto 0);
|
|
type mhpmevent_rd_t is array (0 to 29) of std_ulogic_vector(hpmcnt_event_size_c-1 downto 0);
|
|
type mhpmcnt_rd_t is array (0 to 29) of std_ulogic_vector(32 downto 0);
|
|
type mhpmcnth_rd_t is array (0 to 29) of std_ulogic_vector(31 downto 0);
|
type csr_t is record
|
type csr_t is record
|
addr : std_ulogic_vector(11 downto 0); -- csr address
|
addr : std_ulogic_vector(11 downto 0); -- csr address
|
we : std_ulogic; -- csr write enable
|
we : std_ulogic; -- csr write enable
|
we_nxt : std_ulogic;
|
we_nxt : std_ulogic;
|
re : std_ulogic; -- csr read enable
|
re : std_ulogic; -- csr read enable
|
Line 252... |
Line 265... |
mie_firqe : std_ulogic_vector(3 downto 0); -- mie.firq*e: fast interrupt enabled (R/W)
|
mie_firqe : std_ulogic_vector(3 downto 0); -- mie.firq*e: fast interrupt enabled (R/W)
|
--
|
--
|
mcounteren_cy : std_ulogic; -- mcounteren.cy: allow cycle[h] access from user-mode
|
mcounteren_cy : std_ulogic; -- mcounteren.cy: allow cycle[h] access from user-mode
|
mcounteren_tm : std_ulogic; -- mcounteren.tm: allow time[h] access from user-mode
|
mcounteren_tm : std_ulogic; -- mcounteren.tm: allow time[h] access from user-mode
|
mcounteren_ir : std_ulogic; -- mcounteren.ir: allow instret[h] access from user-mode
|
mcounteren_ir : std_ulogic; -- mcounteren.ir: allow instret[h] access from user-mode
|
|
mcounteren_hpm : std_ulogic_vector(HPM_NUM_CNTS-1 downto 0); -- mcounteren.hpmx: allow mhpmcounterx[h] access from user-mode
|
--
|
--
|
mcountinhibit_cy : std_ulogic; -- mcounterinhibit.cy: enable auto-increment
|
mcountinhibit_cy : std_ulogic; -- mcounterinhibit.cy: enable auto-increment for [m]cycle[h]
|
mcountinhibit_ir : std_ulogic; -- mcounterinhibit.ir: enable auto-increment
|
mcountinhibit_ir : std_ulogic; -- mcounterinhibit.ir: enable auto-increment for [m]instret[h]
|
|
mcountinhibit_hpm : std_ulogic_vector(HPM_NUM_CNTS-1 downto 0); -- mcounterinhibit.hpm3: enable auto-increment for mhpmcounterx[h]
|
--
|
--
|
mip_status : std_ulogic_vector(interrupt_width_c-1 downto 0); -- current buffered IRQs
|
mip_status : std_ulogic_vector(interrupt_width_c-1 downto 0); -- current buffered IRQs
|
mip_clear : std_ulogic_vector(interrupt_width_c-1 downto 0); -- set bits clear the according buffered IRQ
|
mip_clear : std_ulogic_vector(interrupt_width_c-1 downto 0); -- set bits clear the according buffered IRQ
|
--
|
--
|
privilege : std_ulogic_vector(1 downto 0); -- hart's current privilege mode
|
privilege : std_ulogic_vector(1 downto 0); -- hart's current privilege mode
|
Line 267... |
Line 282... |
--
|
--
|
mepc : std_ulogic_vector(data_width_c-1 downto 0); -- mepc: machine exception pc (R/W)
|
mepc : std_ulogic_vector(data_width_c-1 downto 0); -- mepc: machine exception pc (R/W)
|
mcause : std_ulogic_vector(data_width_c-1 downto 0); -- mcause: machine trap cause (R/W)
|
mcause : std_ulogic_vector(data_width_c-1 downto 0); -- mcause: machine trap cause (R/W)
|
mtvec : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W), bit 1:0 == 00
|
mtvec : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W), bit 1:0 == 00
|
mtval : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/W)
|
mtval : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/W)
|
|
--
|
|
mhpmevent : mhpmevent_t; -- mhpmevent*: machine performance-monitoring event selector (R/W)
|
|
mhpmevent_rd : mhpmevent_rd_t; -- mhpmevent*: actual read data
|
|
--
|
mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W)
|
mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W)
|
mcycle : std_ulogic_vector(32 downto 0); -- mcycle (R/W), plus carry bit
|
mcycle : std_ulogic_vector(32 downto 0); -- mcycle (R/W), plus carry bit
|
minstret : std_ulogic_vector(32 downto 0); -- minstret (R/W), plus carry bit
|
minstret : std_ulogic_vector(32 downto 0); -- minstret (R/W), plus carry bit
|
|
--
|
mcycleh : std_ulogic_vector(31 downto 0); -- mcycleh (R/W)
|
mcycleh : std_ulogic_vector(31 downto 0); -- mcycleh (R/W)
|
minstreth : std_ulogic_vector(31 downto 0); -- minstreth (R/W)
|
minstreth : std_ulogic_vector(31 downto 0); -- minstreth (R/W)
|
|
--
|
|
mhpmcounter : mhpmcnt_t; -- mhpmcounter* (R/W), plus carry bit
|
|
mhpmcounterh : mhpmcnth_t; -- mhpmcounter*h (R/W)
|
|
mhpmcounter_rd : mhpmcnt_rd_t; -- mhpmcounter* (R/W): actual read data
|
|
mhpmcounterh_rd : mhpmcnth_rd_t; -- mhpmcounter*h (R/W): actual read data
|
|
--
|
pmpcfg : pmp_ctrl_t; -- physical memory protection - configuration registers
|
pmpcfg : pmp_ctrl_t; -- physical memory protection - configuration registers
|
|
pmpcfg_rd : pmp_ctrl_rd_t; -- physical memory protection - actual read data
|
pmpaddr : pmp_addr_t; -- physical memory protection - address registers
|
pmpaddr : pmp_addr_t; -- physical memory protection - address registers
|
|
pmpaddr_rd : pmp_addr_rd_t; -- physical memory protection - actual read data
|
end record;
|
end record;
|
signal csr : csr_t;
|
signal csr : csr_t;
|
|
|
|
-- counter low-to-high-word carry --
|
signal mcycle_msb : std_ulogic;
|
signal mcycle_msb : std_ulogic;
|
signal minstret_msb : std_ulogic;
|
signal minstret_msb : std_ulogic;
|
|
signal mhpmcounter_msb : std_ulogic_vector(HPM_NUM_CNTS-1 downto 0);
|
|
|
|
-- (hpm) counter events --
|
|
signal cnt_event, cnt_event_nxt : std_ulogic_vector(hpmcnt_event_size_c-1 downto 0);
|
|
signal hpmcnt_trigger : std_ulogic_vector(HPM_NUM_CNTS-1 downto 0);
|
|
|
-- illegal instruction check --
|
-- illegal instruction check --
|
signal illegal_opcode_lsbs : std_ulogic; -- if opcode != rv32
|
signal illegal_opcode_lsbs : std_ulogic; -- if opcode != rv32
|
signal illegal_instruction : std_ulogic;
|
signal illegal_instruction : std_ulogic;
|
signal illegal_register : std_ulogic; -- only for E-extension
|
signal illegal_register : std_ulogic; -- only for E-extension
|
Line 301... |
Line 335... |
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
fetch_engine_fsm_sync: process(rstn_i, clk_i)
|
fetch_engine_fsm_sync: process(rstn_i, clk_i)
|
begin
|
begin
|
if (rstn_i = '0') then
|
if (rstn_i = '0') then
|
fetch_engine.state <= IFETCH_RESET;
|
fetch_engine.state <= IFETCH_RESET;
|
|
fetch_engine.state_prev <= IFETCH_RESET;
|
fetch_engine.pc <= (others => '0');
|
fetch_engine.pc <= (others => '0');
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
if (fetch_engine.reset = '1') then
|
if (fetch_engine.reset = '1') then
|
fetch_engine.state <= IFETCH_RESET;
|
fetch_engine.state <= IFETCH_RESET;
|
else
|
else
|
fetch_engine.state <= fetch_engine.state_nxt;
|
fetch_engine.state <= fetch_engine.state_nxt;
|
end if;
|
end if;
|
|
fetch_engine.state_prev <= fetch_engine.state;
|
fetch_engine.pc <= fetch_engine.pc_nxt;
|
fetch_engine.pc <= fetch_engine.pc_nxt;
|
end if;
|
end if;
|
end process fetch_engine_fsm_sync;
|
end process fetch_engine_fsm_sync;
|
|
|
-- PC output --
|
-- PC output --
|
Line 636... |
Line 672... |
|
|
-- for registers that do NOT require a specific reset state --
|
-- for registers that do NOT require a specific reset state --
|
execute_engine_fsm_sync: process(clk_i)
|
execute_engine_fsm_sync: process(clk_i)
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
|
execute_engine.state_prev <= execute_engine.state;
|
execute_engine.i_reg <= execute_engine.i_reg_nxt;
|
execute_engine.i_reg <= execute_engine.i_reg_nxt;
|
execute_engine.is_ci <= execute_engine.is_ci_nxt;
|
execute_engine.is_ci <= execute_engine.is_ci_nxt;
|
execute_engine.is_cp_op <= execute_engine.is_cp_op_nxt;
|
execute_engine.is_cp_op <= execute_engine.is_cp_op_nxt;
|
-- next PC (next linear instruction) --
|
-- next PC (next linear instruction) --
|
if (execute_engine.state = EXECUTE) then
|
if (execute_engine.state = EXECUTE) then
|
Line 808... |
Line 845... |
|
|
|
|
when TRAP => -- Start trap environment (also used as cpu sleep state)
|
when TRAP => -- Start trap environment (also used as cpu sleep state)
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
execute_engine.pc_mux_sel <= "10"; -- csr.mtvec (trap)
|
execute_engine.pc_mux_sel <= "10"; -- csr.mtvec (trap)
|
fetch_engine.reset <= '1';
|
|
execute_engine.if_rst_nxt <= '1'; -- this will be a non-linear PC modification
|
execute_engine.if_rst_nxt <= '1'; -- this will be a non-linear PC modification
|
if (trap_ctrl.env_start = '1') then -- trap triggered?
|
if (trap_ctrl.env_start = '1') then -- trap triggered?
|
trap_ctrl.env_start_ack <= '1';
|
trap_ctrl.env_start_ack <= '1';
|
|
fetch_engine.reset <= '1';
|
execute_engine.pc_we <= '1';
|
execute_engine.pc_we <= '1';
|
execute_engine.sleep_nxt <= '0'; -- waky waky
|
execute_engine.sleep_nxt <= '0'; -- waky waky
|
execute_engine.state_nxt <= SYS_WAIT;
|
execute_engine.state_nxt <= SYS_WAIT;
|
end if;
|
end if;
|
|
|
Line 1099... |
Line 1136... |
|
|
-- Illegal CSR Access Check ---------------------------------------------------------------
|
-- Illegal CSR Access Check ---------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
invalid_csr_access_check: process(execute_engine.i_reg, csr)
|
invalid_csr_access_check: process(execute_engine.i_reg, csr)
|
variable csr_wacc_v : std_ulogic; -- to check access to read-only CSRs
|
variable csr_wacc_v : std_ulogic; -- to check access to read-only CSRs
|
|
variable csr_mcounteren_hpm_v : std_ulogic_vector(28 downto 0); -- max 29 HPM counters
|
-- variable csr_racc_v : std_ulogic; -- to check access to write-only CSRs
|
-- variable csr_racc_v : std_ulogic; -- to check access to write-only CSRs
|
begin
|
begin
|
-- is this CSR instruction really going to write/read to/from a CSR? --
|
-- is this CSR instruction really going to write/read to/from a CSR? --
|
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or
|
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or
|
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) then
|
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) then
|
Line 1111... |
Line 1149... |
else
|
else
|
csr_wacc_v := or_all_f(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c)); -- write allowed if rs1/uimm5 != 0
|
csr_wacc_v := or_all_f(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c)); -- write allowed if rs1/uimm5 != 0
|
-- csr_racc_v := '1'; -- always read CSR
|
-- csr_racc_v := '1'; -- always read CSR
|
end if;
|
end if;
|
|
|
|
-- low privilege level access to hpm counters? --
|
|
csr_mcounteren_hpm_v := (others => '0');
|
|
csr_mcounteren_hpm_v(HPM_NUM_CNTS-1 downto 0) := csr.mcounteren_hpm(HPM_NUM_CNTS-1 downto 0);
|
|
|
-- check CSR access --
|
-- check CSR access --
|
case csr.addr is
|
case csr.addr is
|
-- standard read/write CSRs --
|
-- standard read/write CSRs --
|
when csr_mstatus_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mstatus_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mstatush_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mstatush_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
Line 1126... |
Line 1168... |
when csr_mcause_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mcause_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mcounteren_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mcounteren_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mtval_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mtval_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mip_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mip_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
--
|
--
|
when csr_pmpcfg0_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 1)) and csr.priv_m_mode; -- M-mode only
|
when csr_pmpcfg0_c | csr_pmpcfg1_c | csr_pmpcfg2_c | csr_pmpcfg3_c | csr_pmpcfg4_c | csr_pmpcfg5_c | csr_pmpcfg6_c | csr_pmpcfg7_c |
|
when csr_pmpcfg1_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 5)) and csr.priv_m_mode; -- M-mode only
|
csr_pmpcfg8_c | csr_pmpcfg9_c | csr_pmpcfg10_c | csr_pmpcfg11_c | csr_pmpcfg12_c | csr_pmpcfg13_c | csr_pmpcfg14_c | csr_pmpcfg15_c =>
|
--
|
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_pmpaddr0_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 1)) and csr.priv_m_mode; -- M-mode only
|
--
|
when csr_pmpaddr1_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 2)) and csr.priv_m_mode; -- M-mode only
|
when csr_pmpaddr0_c | csr_pmpaddr1_c | csr_pmpaddr2_c | csr_pmpaddr3_c | csr_pmpaddr4_c | csr_pmpaddr5_c | csr_pmpaddr6_c | csr_pmpaddr7_c |
|
when csr_pmpaddr2_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 3)) and csr.priv_m_mode; -- M-mode only
|
csr_pmpaddr8_c | csr_pmpaddr9_c | csr_pmpaddr10_c | csr_pmpaddr11_c | csr_pmpaddr12_c | csr_pmpaddr13_c | csr_pmpaddr14_c | csr_pmpaddr15_c |
|
when csr_pmpaddr3_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 4)) and csr.priv_m_mode; -- M-mode only
|
csr_pmpaddr16_c | csr_pmpaddr17_c | csr_pmpaddr18_c | csr_pmpaddr19_c | csr_pmpaddr20_c | csr_pmpaddr21_c | csr_pmpaddr22_c | csr_pmpaddr23_c |
|
when csr_pmpaddr4_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 5)) and csr.priv_m_mode; -- M-mode only
|
csr_pmpaddr24_c | csr_pmpaddr25_c | csr_pmpaddr26_c | csr_pmpaddr27_c | csr_pmpaddr28_c | csr_pmpaddr29_c | csr_pmpaddr30_c | csr_pmpaddr31_c |
|
when csr_pmpaddr5_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 6)) and csr.priv_m_mode; -- M-mode only
|
csr_pmpaddr32_c | csr_pmpaddr33_c | csr_pmpaddr34_c | csr_pmpaddr35_c | csr_pmpaddr36_c | csr_pmpaddr37_c | csr_pmpaddr38_c | csr_pmpaddr39_c |
|
when csr_pmpaddr6_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 7)) and csr.priv_m_mode; -- M-mode only
|
csr_pmpaddr40_c | csr_pmpaddr41_c | csr_pmpaddr42_c | csr_pmpaddr43_c | csr_pmpaddr44_c | csr_pmpaddr45_c | csr_pmpaddr46_c | csr_pmpaddr47_c |
|
when csr_pmpaddr7_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 8)) and csr.priv_m_mode; -- M-mode only
|
csr_pmpaddr48_c | csr_pmpaddr49_c | csr_pmpaddr50_c | csr_pmpaddr51_c | csr_pmpaddr52_c | csr_pmpaddr53_c | csr_pmpaddr54_c | csr_pmpaddr55_c |
|
|
csr_pmpaddr56_c | csr_pmpaddr57_c | csr_pmpaddr58_c | csr_pmpaddr59_c | csr_pmpaddr60_c | csr_pmpaddr61_c | csr_pmpaddr62_c | csr_pmpaddr63_c =>
|
|
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
--
|
--
|
when csr_mcountinhibit_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mcountinhibit_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
--
|
--
|
|
when csr_mhpmevent3_c | csr_mhpmevent4_c | csr_mhpmevent5_c | csr_mhpmevent6_c | csr_mhpmevent7_c | csr_mhpmevent8_c |
|
|
csr_mhpmevent9_c | csr_mhpmevent10_c | csr_mhpmevent11_c | csr_mhpmevent12_c | csr_mhpmevent13_c | csr_mhpmevent14_c |
|
|
csr_mhpmevent15_c | csr_mhpmevent16_c | csr_mhpmevent17_c | csr_mhpmevent18_c | csr_mhpmevent19_c | csr_mhpmevent20_c |
|
|
csr_mhpmevent21_c | csr_mhpmevent22_c | csr_mhpmevent23_c | csr_mhpmevent24_c | csr_mhpmevent25_c | csr_mhpmevent26_c |
|
|
csr_mhpmevent27_c | csr_mhpmevent28_c | csr_mhpmevent29_c | csr_mhpmevent30_c | csr_mhpmevent31_c =>
|
|
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
|
--
|
when csr_mcycle_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mcycle_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_minstret_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_minstret_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
--
|
--
|
|
when csr_mhpmcounter3_c | csr_mhpmcounter4_c | csr_mhpmcounter5_c | csr_mhpmcounter6_c | csr_mhpmcounter7_c | csr_mhpmcounter8_c |
|
|
csr_mhpmcounter9_c | csr_mhpmcounter10_c | csr_mhpmcounter11_c | csr_mhpmcounter12_c | csr_mhpmcounter13_c | csr_mhpmcounter14_c |
|
|
csr_mhpmcounter15_c | csr_mhpmcounter16_c | csr_mhpmcounter17_c | csr_mhpmcounter18_c | csr_mhpmcounter19_c | csr_mhpmcounter20_c |
|
|
csr_mhpmcounter21_c | csr_mhpmcounter22_c | csr_mhpmcounter23_c | csr_mhpmcounter24_c | csr_mhpmcounter25_c | csr_mhpmcounter26_c |
|
|
csr_mhpmcounter27_c | csr_mhpmcounter28_c | csr_mhpmcounter29_c | csr_mhpmcounter30_c | csr_mhpmcounter31_c =>
|
|
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
|
--
|
when csr_mcycleh_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_mcycleh_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_minstreth_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
when csr_minstreth_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
|
--
|
|
when csr_mhpmcounter3h_c | csr_mhpmcounter4h_c | csr_mhpmcounter5h_c | csr_mhpmcounter6h_c | csr_mhpmcounter7h_c | csr_mhpmcounter8h_c |
|
|
csr_mhpmcounter9h_c | csr_mhpmcounter10h_c | csr_mhpmcounter11h_c | csr_mhpmcounter12h_c | csr_mhpmcounter13h_c | csr_mhpmcounter14h_c |
|
|
csr_mhpmcounter15h_c | csr_mhpmcounter16h_c | csr_mhpmcounter17h_c | csr_mhpmcounter18h_c | csr_mhpmcounter19h_c | csr_mhpmcounter20h_c |
|
|
csr_mhpmcounter21h_c | csr_mhpmcounter22h_c | csr_mhpmcounter23h_c | csr_mhpmcounter24h_c | csr_mhpmcounter25h_c | csr_mhpmcounter26h_c |
|
|
csr_mhpmcounter27h_c | csr_mhpmcounter28h_c | csr_mhpmcounter29h_c | csr_mhpmcounter30h_c | csr_mhpmcounter31h_c =>
|
|
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
|
|
|
-- standard read-only CSRs --
|
-- standard read-only CSRs --
|
when csr_cycle_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- M-mode, U-mode if authorized, read-only
|
when csr_cycle_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- M-mode, U-mode if authorized, read-only
|
when csr_time_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- M-mode, U-mode if authorized, read-only
|
when csr_time_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- M-mode, U-mode if authorized, read-only
|
when csr_instret_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- M-mode, U-mode if authorized, read-only
|
when csr_instret_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- M-mode, U-mode if authorized, read-only
|
--
|
--
|
|
when csr_hpmcounter3_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(0)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter4_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(1)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter5_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(2)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter6_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(3)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter7_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(4)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter8_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(5)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter9_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(6)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter10_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(7)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter11_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(8)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter12_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(9)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter13_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(10)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter14_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(11)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter15_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(12)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter16_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(13)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter17_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(14)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter18_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(15)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter19_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(16)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter20_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(17)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter21_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(18)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter22_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(19)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter23_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(20)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter24_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(21)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter25_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(22)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter26_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(23)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter27_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(24)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter28_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(25)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter29_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(26)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter30_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(27)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter31_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(28)); -- M-mode, U-mode if authorized, read-only
|
|
--
|
when csr_cycleh_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- M-mode, U-mode if authorized, read-only
|
when csr_cycleh_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- M-mode, U-mode if authorized, read-only
|
when csr_timeh_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- M-mode, U-mode if authorized, read-only
|
when csr_timeh_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- M-mode, U-mode if authorized, read-only
|
when csr_instreth_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- M-mode, U-mode if authorized, read-only
|
when csr_instreth_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- M-mode, U-mode if authorized, read-only
|
--
|
--
|
|
when csr_hpmcounter3h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(0)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter4h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(1)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter5h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(2)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter6h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(3)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter7h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(4)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter8h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(5)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter9h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(6)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter10h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(7)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter11h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(8)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter12h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(9)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter13h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(10)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter14h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(11)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter15h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(12)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter16h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(13)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter17h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(14)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter18h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(15)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter19h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(16)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter20h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(17)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter21h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(18)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter22h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(19)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter23h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(20)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter24h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(21)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter25h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(22)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter26h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(23)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter27h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(24)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter28h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(25)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter29h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(26)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter30h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(27)); -- M-mode, U-mode if authorized, read-only
|
|
when csr_hpmcounter31h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(28)); -- M-mode, U-mode if authorized, read-only
|
|
--
|
when csr_mvendorid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
|
when csr_mvendorid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
|
when csr_marchid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
|
when csr_marchid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
|
when csr_mimpid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
|
when csr_mimpid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
|
when csr_mhartid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
|
when csr_mhartid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
|
-- custom read-only CSRs --
|
-- custom read-only CSRs --
|
Line 1404... |
Line 1530... |
if (trap_ctrl.env_start = '0') then -- no started trap handler
|
if (trap_ctrl.env_start = '0') then -- no started trap handler
|
if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and -- exception/IRQ detected!
|
if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and -- exception/IRQ detected!
|
((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP))) then -- sample IRQs in EXECUTE or TRAP state only to continue execution even if permanent IRQ
|
((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP))) then -- sample IRQs in EXECUTE or TRAP state only to continue execution even if permanent IRQ
|
trap_ctrl.cause <= trap_ctrl.cause_nxt; -- capture source ID for program (for mcause csr)
|
trap_ctrl.cause <= trap_ctrl.cause_nxt; -- capture source ID for program (for mcause csr)
|
trap_ctrl.exc_ack <= '1'; -- clear execption
|
trap_ctrl.exc_ack <= '1'; -- clear execption
|
trap_ctrl.irq_ack <= trap_ctrl.irq_ack_nxt; -- capture and clear with interrupt ACK mask
|
trap_ctrl.irq_ack <= trap_ctrl.irq_ack_nxt; -- clear interrupt with interrupt ACK mask
|
trap_ctrl.env_start <= '1'; -- now execute engine can start trap handler
|
trap_ctrl.env_start <= '1'; -- now execute engine can start trap handler
|
end if;
|
end if;
|
else -- trap waiting to get started
|
else -- trap waiting to get started
|
if (trap_ctrl.env_start_ack = '1') then -- start of trap handler acknowledged by execution engine
|
if (trap_ctrl.env_start_ack = '1') then -- start of trap handler acknowledged by execution engine
|
trap_ctrl.exc_ack <= '0';
|
trap_ctrl.exc_ack <= '0';
|
Line 1426... |
Line 1552... |
|
|
-- current pending interrupts (for CSR.MIP register) --
|
-- current pending interrupts (for CSR.MIP register) --
|
csr.mip_status <= trap_ctrl.irq_buf;
|
csr.mip_status <= trap_ctrl.irq_buf;
|
|
|
|
|
-- Trap Priority Detector -----------------------------------------------------------------
|
-- Trap Priority Encoder ------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
trap_priority: process(trap_ctrl)
|
trap_priority: process(trap_ctrl)
|
begin
|
begin
|
-- defaults --
|
-- defaults --
|
trap_ctrl.cause_nxt <= (others => '0');
|
trap_ctrl.cause_nxt <= (others => '0');
|
Line 1474... |
Line 1600... |
elsif (trap_ctrl.irq_buf(interrupt_firq_3_c) = '1') then
|
elsif (trap_ctrl.irq_buf(interrupt_firq_3_c) = '1') then
|
trap_ctrl.cause_nxt <= trap_firq3_c;
|
trap_ctrl.cause_nxt <= trap_firq3_c;
|
trap_ctrl.irq_ack_nxt(interrupt_firq_3_c) <= '1';
|
trap_ctrl.irq_ack_nxt(interrupt_firq_3_c) <= '1';
|
|
|
|
|
-- the following traps are caused by *synchronous* exceptions (= classic exceptions)
|
-- the following traps are caused by *synchronous* exceptions (= 'classic' exceptions)
|
-- here we do not need a specific acknowledge mask since only one exception (the one
|
-- here we do not need a specific acknowledge mask since only one exception (the one
|
-- with highest priority) is evaluated at once
|
-- with highest priority) is evaluated at once
|
|
|
-- exception: 0.1 instruction access fault --
|
-- exception: 0.1 instruction access fault --
|
elsif (trap_ctrl.exc_buf(exception_iaccess_c) = '1') then
|
elsif (trap_ctrl.exc_buf(exception_iaccess_c) = '1') then
|
Line 1520... |
Line 1646... |
|
|
-- exception: 0.5 load access fault --
|
-- exception: 0.5 load access fault --
|
elsif (trap_ctrl.exc_buf(exception_laccess_c) = '1') then
|
elsif (trap_ctrl.exc_buf(exception_laccess_c) = '1') then
|
trap_ctrl.cause_nxt <= trap_lbe_c;
|
trap_ctrl.cause_nxt <= trap_lbe_c;
|
|
|
-- undefined / not implemented --
|
-- not implemented --
|
else
|
else
|
trap_ctrl.cause_nxt <= (others => '0');
|
trap_ctrl.cause_nxt <= (others => '0');
|
trap_ctrl.irq_ack_nxt <= (others => '0');
|
trap_ctrl.irq_ack_nxt <= (others => '0');
|
end if;
|
end if;
|
end process trap_priority;
|
end process trap_priority;
|
Line 1581... |
Line 1707... |
|
|
|
|
-- Control and Status Registers Write Access ----------------------------------------------
|
-- Control and Status Registers Write Access ----------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
csr_write_access: process(rstn_i, clk_i)
|
csr_write_access: process(rstn_i, clk_i)
|
|
variable pmpaddr_v : std_ulogic_vector(6 downto 0);
|
begin
|
begin
|
if (rstn_i = '0') then
|
if (rstn_i = '0') then
|
csr.we <= '0';
|
csr.we <= '0';
|
--
|
--
|
csr.mstatus_mie <= '0';
|
csr.mstatus_mie <= '0';
|
Line 1596... |
Line 1723... |
csr.mie_mtie <= '0';
|
csr.mie_mtie <= '0';
|
csr.mie_firqe <= (others => '0');
|
csr.mie_firqe <= (others => '0');
|
csr.mtvec <= (others => '0');
|
csr.mtvec <= (others => '0');
|
csr.mscratch <= x"19880704"; -- :)
|
csr.mscratch <= x"19880704"; -- :)
|
csr.mepc <= (others => '0');
|
csr.mepc <= (others => '0');
|
-- mcause = TRAP_CODE_RESET (hardware reset, 0x80000000)
|
-- mcause = TRAP_CODE_RESET (hardware reset, "non-maskable interrupt")
|
csr.mcause <= (others => '0');
|
csr.mcause <= (others => '0');
|
csr.mcause(csr.mcause'left) <= trap_reset_c(trap_reset_c'left);
|
csr.mcause(csr.mcause'left) <= trap_reset_c(trap_reset_c'left);
|
csr.mcause(trap_reset_c'left-1 downto 0) <= trap_reset_c(trap_reset_c'left-1 downto 0);
|
csr.mcause(trap_reset_c'left-1 downto 0) <= trap_reset_c(trap_reset_c'left-1 downto 0);
|
--
|
--
|
csr.mtval <= (others => '0');
|
csr.mtval <= (others => '0');
|
csr.mip_clear <= (others => '0');
|
csr.mip_clear <= (others => '0');
|
|
--
|
csr.pmpcfg <= (others => (others => '0'));
|
csr.pmpcfg <= (others => (others => '0'));
|
csr.pmpaddr <= (others => (others => '1'));
|
csr.pmpaddr <= (others => (others => '1'));
|
--
|
--
|
|
csr.mhpmevent <= (others => (others => '0'));
|
|
--
|
csr.mcounteren_cy <= '0';
|
csr.mcounteren_cy <= '0';
|
csr.mcounteren_tm <= '0';
|
csr.mcounteren_tm <= '0';
|
csr.mcounteren_ir <= '0';
|
csr.mcounteren_ir <= '0';
|
|
csr.mcounteren_hpm <= (others => '0');
|
|
--
|
csr.mcountinhibit_cy <= '0';
|
csr.mcountinhibit_cy <= '0';
|
csr.mcountinhibit_ir <= '0';
|
csr.mcountinhibit_ir <= '0';
|
--
|
csr.mcountinhibit_hpm <= (others => '0');
|
csr.mcycle <= (others => '0');
|
|
csr.minstret <= (others => '0');
|
|
csr.mcycleh <= (others => '0');
|
|
csr.minstreth <= (others => '0');
|
|
mcycle_msb <= '0';
|
|
minstret_msb <= '0';
|
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
-- write access? --
|
-- write access? --
|
csr.we <= csr.we_nxt;
|
csr.we <= csr.we_nxt;
|
if (CPU_EXTENSION_RISCV_Zicsr = true) then
|
if (CPU_EXTENSION_RISCV_Zicsr = true) then
|
|
|
Line 1658... |
Line 1784... |
csr.mtvec <= csr.wdata(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
|
csr.mtvec <= csr.wdata(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
|
when csr_mcounteren_c => -- R/W: machine counter enable register
|
when csr_mcounteren_c => -- R/W: machine counter enable register
|
csr.mcounteren_cy <= csr.wdata(0); -- enable user-level access to cycle[h]
|
csr.mcounteren_cy <= csr.wdata(0); -- enable user-level access to cycle[h]
|
csr.mcounteren_tm <= csr.wdata(1); -- enable user-level access to time[h]
|
csr.mcounteren_tm <= csr.wdata(1); -- enable user-level access to time[h]
|
csr.mcounteren_ir <= csr.wdata(2); -- enable user-level access to instret[h]
|
csr.mcounteren_ir <= csr.wdata(2); -- enable user-level access to instret[h]
|
|
csr.mcounteren_hpm <= csr.wdata(csr.mcounteren_hpm'left+3 downto 3); -- enable user-level access to mhpmcounterx[h]
|
|
|
-- machine trap handling --
|
-- machine trap handling --
|
-- --------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
when csr_mscratch_c => -- R/W: mscratch - machine scratch register
|
when csr_mscratch_c => -- R/W: mscratch - machine scratch register
|
csr.mscratch <= csr.wdata;
|
csr.mscratch <= csr.wdata;
|
Line 1681... |
Line 1808... |
csr.mip_clear(interrupt_firq_0_c) <= not csr.wdata(16);
|
csr.mip_clear(interrupt_firq_0_c) <= not csr.wdata(16);
|
csr.mip_clear(interrupt_firq_1_c) <= not csr.wdata(17);
|
csr.mip_clear(interrupt_firq_1_c) <= not csr.wdata(17);
|
csr.mip_clear(interrupt_firq_2_c) <= not csr.wdata(18);
|
csr.mip_clear(interrupt_firq_2_c) <= not csr.wdata(18);
|
csr.mip_clear(interrupt_firq_3_c) <= not csr.wdata(19);
|
csr.mip_clear(interrupt_firq_3_c) <= not csr.wdata(19);
|
|
|
-- physical memory protection - configuration --
|
-- physical memory protection: R/W: pmpcfg* - PMP configuration registers --
|
-- --------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
when csr_pmpcfg0_c => -- R/W: pmpcfg0 - PMP configuration register 0
|
when csr_pmpcfg0_c | csr_pmpcfg1_c | csr_pmpcfg2_c | csr_pmpcfg3_c | csr_pmpcfg4_c | csr_pmpcfg5_c | csr_pmpcfg6_c | csr_pmpcfg7_c |
|
if (PMP_USE = true) and (pmp_num_regions_c >= 1) then
|
csr_pmpcfg8_c | csr_pmpcfg9_c | csr_pmpcfg10_c | csr_pmpcfg11_c | csr_pmpcfg12_c | csr_pmpcfg13_c | csr_pmpcfg14_c | csr_pmpcfg15_c =>
|
for j in 0 to 3 loop -- bytes in pmpcfg CSR
|
for i in 0 to PMP_NUM_REGIONS-1 loop
|
if ((j+1) <= pmp_num_regions_c) then
|
if (csr.addr(3 downto 0) = std_ulogic_vector(to_unsigned(i, 4))) then
|
if (csr.pmpcfg(0+j)(7) = '0') then -- unlocked pmpcfg access
|
if (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpcfg access
|
csr.pmpcfg(0+j)(0) <= csr.wdata(j*8+0); -- R (rights.read)
|
csr.pmpcfg(i)(0) <= csr.wdata((i mod 4)*8+0); -- R (rights.read)
|
csr.pmpcfg(0+j)(1) <= csr.wdata(j*8+1); -- W (rights.write)
|
csr.pmpcfg(i)(1) <= csr.wdata((i mod 4)*8+1); -- W (rights.write)
|
csr.pmpcfg(0+j)(2) <= csr.wdata(j*8+2); -- X (rights.execute)
|
csr.pmpcfg(i)(2) <= csr.wdata((i mod 4)*8+2); -- X (rights.execute)
|
csr.pmpcfg(0+j)(3) <= csr.wdata(j*8+3) and csr.wdata(j*8+4); -- A_L
|
csr.pmpcfg(i)(3) <= csr.wdata((i mod 4)*8+3) and csr.wdata((i mod 4)*8+4); -- A_L
|
csr.pmpcfg(0+j)(4) <= csr.wdata(j*8+3) and csr.wdata(j*8+4); -- A_H - NAPOT/OFF only
|
csr.pmpcfg(i)(4) <= csr.wdata((i mod 4)*8+3) and csr.wdata((i mod 4)*8+4); -- A_H - NAPOT/OFF only
|
csr.pmpcfg(0+j)(5) <= '0'; -- reserved
|
csr.pmpcfg(i)(5) <= '0'; -- reserved
|
csr.pmpcfg(0+j)(6) <= '0'; -- reserved
|
csr.pmpcfg(i)(6) <= '0'; -- reserved
|
csr.pmpcfg(0+j)(7) <= csr.wdata(j*8+7); -- L (locked / rights also enforced in m-mode)
|
csr.pmpcfg(i)(7) <= csr.wdata((i mod 4)*8+7); -- L (locked / rights also enforced in m-mode)
|
end if;
|
|
end if;
|
|
end loop; -- j (bytes in CSR)
|
|
end if;
|
|
when csr_pmpcfg1_c => -- R/W: pmpcfg1 - PMP configuration register 1
|
|
if (PMP_USE = true) and (pmp_num_regions_c >= 5) then
|
|
for j in 0 to 3 loop -- bytes in pmpcfg CSR
|
|
if ((j+1+4) <= pmp_num_regions_c) then
|
|
if (csr.pmpcfg(4+j)(7) = '0') then -- unlocked pmpcfg access
|
|
csr.pmpcfg(4+j)(0) <= csr.wdata(j*8+0); -- R (rights.read)
|
|
csr.pmpcfg(4+j)(1) <= csr.wdata(j*8+1); -- W (rights.write)
|
|
csr.pmpcfg(4+j)(2) <= csr.wdata(j*8+2); -- X (rights.execute)
|
|
csr.pmpcfg(4+j)(3) <= csr.wdata(j*8+3) and csr.wdata(j*8+4); -- A_L
|
|
csr.pmpcfg(4+j)(4) <= csr.wdata(j*8+3) and csr.wdata(j*8+4); -- A_H - NAPOT/OFF only
|
|
csr.pmpcfg(4+j)(5) <= '0'; -- reserved
|
|
csr.pmpcfg(4+j)(6) <= '0'; -- reserved
|
|
csr.pmpcfg(4+j)(7) <= csr.wdata(j*8+7); -- L (locked / rights also enforced in m-mode)
|
|
end if;
|
|
end if;
|
end if;
|
end loop; -- j (bytes in CSR)
|
|
end if;
|
end if;
|
|
end loop; -- i (PMP regions)
|
|
|
-- physical memory protection - addresses --
|
-- physical memory protection: R/W: pmpaddr* - PMP address registers --
|
-- --------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
when csr_pmpaddr0_c | csr_pmpaddr1_c | csr_pmpaddr2_c | csr_pmpaddr3_c |
|
when csr_pmpaddr0_c | csr_pmpaddr1_c | csr_pmpaddr2_c | csr_pmpaddr3_c | csr_pmpaddr4_c | csr_pmpaddr5_c | csr_pmpaddr6_c | csr_pmpaddr7_c |
|
csr_pmpaddr4_c | csr_pmpaddr5_c | csr_pmpaddr6_c | csr_pmpaddr7_c => -- R/W: pmpaddr0..7 - PMP address register 0..7
|
csr_pmpaddr8_c | csr_pmpaddr9_c | csr_pmpaddr10_c | csr_pmpaddr11_c | csr_pmpaddr12_c | csr_pmpaddr13_c | csr_pmpaddr14_c | csr_pmpaddr15_c |
|
if (PMP_USE = true) then
|
csr_pmpaddr16_c | csr_pmpaddr17_c | csr_pmpaddr18_c | csr_pmpaddr19_c | csr_pmpaddr20_c | csr_pmpaddr21_c | csr_pmpaddr22_c | csr_pmpaddr23_c |
|
for i in 0 to pmp_num_regions_c-1 loop
|
csr_pmpaddr24_c | csr_pmpaddr25_c | csr_pmpaddr26_c | csr_pmpaddr27_c | csr_pmpaddr28_c | csr_pmpaddr29_c | csr_pmpaddr30_c | csr_pmpaddr31_c |
|
if (csr.addr(2 downto 0) = std_ulogic_vector(to_unsigned(i, 3))) and (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpaddr access
|
csr_pmpaddr32_c | csr_pmpaddr33_c | csr_pmpaddr34_c | csr_pmpaddr35_c | csr_pmpaddr36_c | csr_pmpaddr37_c | csr_pmpaddr38_c | csr_pmpaddr39_c |
|
|
csr_pmpaddr40_c | csr_pmpaddr41_c | csr_pmpaddr42_c | csr_pmpaddr43_c | csr_pmpaddr44_c | csr_pmpaddr45_c | csr_pmpaddr46_c | csr_pmpaddr47_c |
|
|
csr_pmpaddr48_c | csr_pmpaddr49_c | csr_pmpaddr50_c | csr_pmpaddr51_c | csr_pmpaddr52_c | csr_pmpaddr53_c | csr_pmpaddr54_c | csr_pmpaddr55_c |
|
|
csr_pmpaddr56_c | csr_pmpaddr57_c | csr_pmpaddr58_c | csr_pmpaddr59_c | csr_pmpaddr60_c | csr_pmpaddr61_c | csr_pmpaddr62_c | csr_pmpaddr63_c =>
|
|
for i in 0 to PMP_NUM_REGIONS-1 loop
|
|
pmpaddr_v := std_ulogic_vector(unsigned(csr_pmpaddr0_c(6 downto 0)) + i); -- adapt to *non-aligned* base address (csr_pmpaddr0_c)
|
|
if (csr.addr(6 downto 0) = pmpaddr_v) and (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpaddr access
|
csr.pmpaddr(i) <= csr.wdata;
|
csr.pmpaddr(i) <= csr.wdata;
|
csr.pmpaddr(i)(index_size_f(pmp_min_granularity_c)-4 downto 0) <= (others => '1');
|
csr.pmpaddr(i)(index_size_f(PMP_MIN_GRANULARITY)-4 downto 0) <= (others => '1');
|
end if;
|
|
end loop; -- i (CSRs)
|
|
end if;
|
end if;
|
|
end loop; -- i (PMP regions)
|
|
|
-- machine counter setup --
|
-- machine counter setup --
|
-- --------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
when csr_mcountinhibit_c => -- R/W: mcountinhibit - machine counter-inhibit register
|
when csr_mcountinhibit_c => -- R/W: mcountinhibit - machine counter-inhibit register
|
csr.mcountinhibit_cy <= csr.wdata(0); -- enable auto-increment of [m]cycle[h] counter
|
csr.mcountinhibit_cy <= csr.wdata(0); -- enable auto-increment of [m]cycle[h] counter
|
csr.mcountinhibit_ir <= csr.wdata(2); -- enable auto-increment of [m]instret[h] counter
|
csr.mcountinhibit_ir <= csr.wdata(2); -- enable auto-increment of [m]instret[h] counter
|
|
csr.mcountinhibit_hpm <= csr.wdata(csr.mcountinhibit_hpm'left+3 downto 3); -- enable auto-increment of [m]hpmcounter*[h] counter
|
|
|
|
-- machine performance-monitoring event selector --
|
|
-- --------------------------------------------------------------------
|
|
when csr_mhpmevent3_c | csr_mhpmevent4_c | csr_mhpmevent5_c | csr_mhpmevent6_c | csr_mhpmevent7_c | csr_mhpmevent8_c |
|
|
csr_mhpmevent9_c | csr_mhpmevent10_c | csr_mhpmevent11_c | csr_mhpmevent12_c | csr_mhpmevent13_c | csr_mhpmevent14_c |
|
|
csr_mhpmevent15_c | csr_mhpmevent16_c | csr_mhpmevent17_c | csr_mhpmevent18_c | csr_mhpmevent19_c | csr_mhpmevent20_c |
|
|
csr_mhpmevent21_c | csr_mhpmevent22_c | csr_mhpmevent23_c | csr_mhpmevent24_c | csr_mhpmevent25_c | csr_mhpmevent26_c |
|
|
csr_mhpmevent27_c | csr_mhpmevent28_c | csr_mhpmevent29_c | csr_mhpmevent30_c | csr_mhpmevent31_c => -- R/W: mhpmevent* - machine performance-monitoring event selector
|
|
for i in 0 to HPM_NUM_CNTS-1 loop
|
|
if (csr.addr(4 downto 0) = std_ulogic_vector(to_unsigned(i+3, 5))) then
|
|
csr.mhpmevent(i) <= csr.wdata(csr.mhpmevent(i)'left downto 0);
|
|
end if;
|
|
end loop; -- i (CSRs)
|
|
|
-- undefined --
|
-- undefined --
|
-- --------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
when others =>
|
when others =>
|
NULL;
|
NULL;
|
Line 1802... |
Line 1930... |
csr.mstatus_mpp <= priv_mode_m_c;
|
csr.mstatus_mpp <= priv_mode_m_c;
|
end if;
|
end if;
|
|
|
end if; -- hardware csr access
|
end if; -- hardware csr access
|
|
|
-- --------------------------------------------------------------------------------
|
end if;
|
-- Counter CSRs (each counter is split in two 32-bit counters)
|
end if;
|
-- --------------------------------------------------------------------------------
|
end process csr_write_access;
|
|
|
|
-- decode privilege mode --
|
|
csr.priv_m_mode <= '1' when (csr.privilege = priv_mode_m_c) or (CPU_EXTENSION_RISCV_U = false) else '0';
|
|
csr.priv_u_mode <= '1' when (csr.privilege = priv_mode_u_c) and (CPU_EXTENSION_RISCV_U = true) else '0';
|
|
|
|
-- PMP configuration output to bus unit --
|
|
pmp_output: process(csr)
|
|
begin
|
|
pmp_addr_o <= (others => (others => '0'));
|
|
pmp_ctrl_o <= (others => (others => '0'));
|
|
for i in 0 to PMP_NUM_REGIONS-1 loop
|
|
pmp_addr_o(i) <= csr.pmpaddr(i) & "11";
|
|
pmp_addr_o(i)(index_size_f(PMP_MIN_GRANULARITY)-4 downto 0) <= (others => '1');
|
|
pmp_ctrl_o(i) <= csr.pmpcfg(i);
|
|
end loop; -- i
|
|
end process pmp_output;
|
|
|
|
-- PMP read dummy --
|
|
pmp_rd_dummy: process(csr)
|
|
begin
|
|
csr.pmpcfg_rd <= (others => (others => '0'));
|
|
csr.pmpaddr_rd <= (others => (others => '0'));
|
|
for i in 0 to PMP_NUM_REGIONS-1 loop
|
|
csr.pmpcfg_rd(i) <= csr.pmpcfg(i);
|
|
csr.pmpaddr_rd(i) <= csr.pmpaddr(i);
|
|
if (csr.pmpcfg(i)(4 downto 3) = "00") then -- mode = off
|
|
csr.pmpaddr_rd(i)(index_size_f(PMP_MIN_GRANULARITY)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
|
|
end if;
|
|
end loop; -- i
|
|
end process pmp_rd_dummy;
|
|
|
|
|
|
-- Control and Status Registers - Counters ------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
csr_counters: process(clk_i)
|
|
begin
|
|
-- Counter CSRs (each counter is split into two 32-bit counters)
|
|
if rising_edge(clk_i) then
|
|
|
-- [m]cycle --
|
-- [m]cycle --
|
if (csr.we = '1') and (csr.addr = csr_mcycle_c) then -- write access
|
if (csr.we = '1') and (csr.addr = csr_mcycle_c) then -- write access
|
csr.mcycle <= '0' & csr.wdata;
|
csr.mcycle <= '0' & csr.wdata;
|
mcycle_msb <= '0';
|
mcycle_msb <= '0';
|
elsif (csr.mcountinhibit_cy = '0') and (execute_engine.sleep = '0') then -- non-inhibited automatic update (if CPU is not in sleep mode)
|
elsif (csr.mcountinhibit_cy = '0') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update
|
csr.mcycle <= std_ulogic_vector(unsigned(csr.mcycle) + 1);
|
csr.mcycle <= std_ulogic_vector(unsigned(csr.mcycle) + 1);
|
mcycle_msb <= csr.mcycle(csr.mcycle'left);
|
mcycle_msb <= csr.mcycle(csr.mcycle'left);
|
end if;
|
end if;
|
|
|
-- [m]cycleh --
|
-- [m]cycleh --
|
Line 1825... |
Line 1992... |
|
|
-- [m]instret --
|
-- [m]instret --
|
if (csr.we = '1') and (csr.addr = csr_minstret_c) then -- write access
|
if (csr.we = '1') and (csr.addr = csr_minstret_c) then -- write access
|
csr.minstret <= '0' & csr.wdata;
|
csr.minstret <= '0' & csr.wdata;
|
minstret_msb <= '0';
|
minstret_msb <= '0';
|
elsif (csr.mcountinhibit_ir = '0') and (execute_engine.state = EXECUTE) then -- non-inhibited automatic update (if CPU actually executes an instruction)
|
elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update
|
csr.minstret <= std_ulogic_vector(unsigned(csr.minstret) + 1);
|
csr.minstret <= std_ulogic_vector(unsigned(csr.minstret) + 1);
|
minstret_msb <= csr.minstret(csr.minstret'left);
|
minstret_msb <= csr.minstret(csr.minstret'left);
|
end if;
|
end if;
|
|
|
-- [m]instreth --
|
-- [m]instreth --
|
Line 1837... |
Line 2004... |
csr.minstreth <= csr.wdata;
|
csr.minstreth <= csr.wdata;
|
elsif ((minstret_msb xor csr.minstret(csr.minstret'left)) = '1') then -- automatic update (continued)
|
elsif ((minstret_msb xor csr.minstret(csr.minstret'left)) = '1') then -- automatic update (continued)
|
csr.minstreth <= std_ulogic_vector(unsigned(csr.minstreth) + 1);
|
csr.minstreth <= std_ulogic_vector(unsigned(csr.minstreth) + 1);
|
end if;
|
end if;
|
|
|
|
-- [machine] high performance counters --
|
|
for i in 0 to HPM_NUM_CNTS-1 loop
|
|
-- [m]hpmcounter* --
|
|
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3_c) + i)) then -- write access
|
|
csr.mhpmcounter(i) <= '0' & csr.wdata;
|
|
mhpmcounter_msb(i) <= '0';
|
|
elsif (csr.mcountinhibit_hpm(i) = '0') and (hpmcnt_trigger(i) = '1') then -- non-inhibited automatic update
|
|
csr.mhpmcounter(i) <= std_ulogic_vector(unsigned(csr.mhpmcounter(i)) + 1);
|
|
mhpmcounter_msb(i) <= csr.mhpmcounter(i)(csr.mhpmcounter(i)'left);
|
|
end if;
|
|
|
|
-- [m]hpmcounter*h --
|
|
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3h_c) + i)) then -- write access
|
|
csr.mhpmcounterh(i) <= csr.wdata;
|
|
elsif ((mhpmcounter_msb(i) xor csr.mhpmcounter(i)(csr.mhpmcounter(i)'left)) = '1') then -- automatic update (continued)
|
|
csr.mhpmcounterh(i) <= std_ulogic_vector(unsigned(csr.mhpmcounterh(i)) + 1);
|
end if;
|
end if;
|
|
end loop; -- i
|
|
|
end if;
|
end if;
|
end process csr_write_access;
|
end process csr_counters;
|
|
|
-- decode privilege mode --
|
-- hpm read dummy --
|
csr.priv_m_mode <= '1' when (csr.privilege = priv_mode_m_c) or (CPU_EXTENSION_RISCV_U = false) else '0';
|
hpm_rd_dummy: process(csr)
|
csr.priv_u_mode <= '1' when (csr.privilege = priv_mode_u_c) and (CPU_EXTENSION_RISCV_U = true) else '0';
|
begin
|
|
csr.mhpmevent_rd <= (others => (others => '0'));
|
|
csr.mhpmcounter_rd <= (others => (others => '0'));
|
|
csr.mhpmcounterh_rd <= (others => (others => '0'));
|
|
for i in 0 to HPM_NUM_CNTS-1 loop
|
|
csr.mhpmevent_rd(i) <= csr.mhpmevent(i);
|
|
csr.mhpmcounter_rd(i) <= csr.mhpmcounter(i);
|
|
csr.mhpmcounterh_rd(i) <= csr.mhpmcounterh(i);
|
|
end loop; -- i
|
|
end process hpm_rd_dummy;
|
|
|
-- PMP configuration output to bus unit --
|
|
pmp_output: process(csr)
|
-- (HPM) Counter Event Control ------------------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
hpmcnt_ctrl: process(clk_i)
|
begin
|
begin
|
pmp_addr_o <= (others => (others => '0'));
|
if rising_edge(clk_i) then
|
pmp_ctrl_o <= (others => (others => '0'));
|
cnt_event <= cnt_event_nxt;
|
if (PMP_USE = true) then
|
hpmcnt_trigger <= (others => '0'); -- default
|
for i in 0 to pmp_num_regions_c-1 loop
|
for i in 0 to HPM_NUM_CNTS-1 loop
|
pmp_addr_o(i) <= csr.pmpaddr(i) & "11";
|
-- enabled selected triggers by ANDing events and configuration bits --
|
pmp_addr_o(i)(index_size_f(pmp_min_granularity_c)-4 downto 0) <= (others => '1');
|
-- OR everything to see if counter should increment --
|
pmp_ctrl_o(i) <= csr.pmpcfg(i);
|
-- AND with inverted sleep flag to increment only when CPU is awake --
|
|
hpmcnt_trigger(i) <= (or_all_f(cnt_event and csr.mhpmevent(i)(cnt_event'left downto 0))) and (not execute_engine.sleep);
|
end loop; -- i
|
end loop; -- i
|
end if;
|
end if;
|
end process pmp_output;
|
end process hpmcnt_ctrl;
|
|
|
|
-- counter event trigger - RISC-V specific --
|
|
cnt_event_nxt(hpmcnt_event_cy_c) <= not execute_engine.sleep; -- active cycle
|
|
cnt_event_nxt(hpmcnt_event_never_c) <= '0'; -- undefined (never)
|
|
cnt_event_nxt(hpmcnt_event_ir_c) <= '1' when (execute_engine.state = EXECUTE) else '0'; -- retired instruction
|
|
|
|
-- counter event trigger - custom / NEORV32-specific --
|
|
cnt_event_nxt(hpmcnt_event_cir_c) <= '1' when (execute_engine.state = EXECUTE) and (execute_engine.is_ci = '1') else '0'; -- retired compressed instruction
|
|
cnt_event_nxt(hpmcnt_event_wait_if_c) <= '1' when (fetch_engine.state = IFETCH_ISSUE) and (fetch_engine.state_prev = IFETCH_ISSUE) else '0'; -- instruction fetch memory wait cycle
|
|
cnt_event_nxt(hpmcnt_event_wait_ii_c) <= '1' when (execute_engine.state = DISPATCH) and (execute_engine.state_prev = DISPATCH) else '0'; -- instruction issue wait cycle
|
|
|
|
cnt_event_nxt(hpmcnt_event_load_c) <= '1' when (execute_engine.state = LOADSTORE_1) and (ctrl(ctrl_bus_rd_c) = '1') else '0'; -- load operation
|
|
cnt_event_nxt(hpmcnt_event_store_c) <= '1' when (execute_engine.state = LOADSTORE_1) and (ctrl(ctrl_bus_wr_c) = '1') else '0'; -- store operation
|
|
cnt_event_nxt(hpmcnt_event_wait_ls_c) <= '1' when (execute_engine.state = LOADSTORE_2) and (execute_engine.state_prev = LOADSTORE_2) else '0'; -- load/store memory wait cycle
|
|
|
|
cnt_event_nxt(hpmcnt_event_jump_c) <= '1' when (execute_engine.state = BRANCH) and (execute_engine.i_reg(instr_opcode_lsb_c+2) = '1') else '0'; -- jump (unconditional)
|
|
cnt_event_nxt(hpmcnt_event_branch_c) <= '1' when (execute_engine.state = BRANCH) and (execute_engine.i_reg(instr_opcode_lsb_c+2) = '0') else '0'; -- branch (conditional, taken or not taken)
|
|
cnt_event_nxt(hpmcnt_event_tbranch_c) <= '1' when (execute_engine.state = BRANCH) and (execute_engine.i_reg(instr_opcode_lsb_c+2) = '0') and (execute_engine.branch_taken = '1') else '0'; -- taken branch (conditional)
|
|
|
|
cnt_event_nxt(hpmcnt_event_trap_c) <= '1' when (trap_ctrl.env_start_ack = '1') else '0'; -- entered trap
|
|
cnt_event_nxt(hpmcnt_event_illegal_c) <= '1' when (trap_ctrl.env_start_ack = '1') and (trap_ctrl.cause = trap_iil_c) else '0'; -- illegal operation
|
|
|
|
|
-- Control and Status Registers Read Access -----------------------------------------------
|
-- Control and Status Registers Read Access -----------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
csr_read_access: process(clk_i)
|
csr_read_access: process(clk_i)
|
Line 1904... |
Line 2122... |
csr.rdata <= csr.mtvec(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
|
csr.rdata <= csr.mtvec(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
|
when csr_mcounteren_c => -- R/W: machine counter enable register
|
when csr_mcounteren_c => -- R/W: machine counter enable register
|
csr.rdata(0) <= csr.mcounteren_cy; -- enable user-level access to cycle[h]
|
csr.rdata(0) <= csr.mcounteren_cy; -- enable user-level access to cycle[h]
|
csr.rdata(1) <= csr.mcounteren_tm; -- enable user-level access to time[h]
|
csr.rdata(1) <= csr.mcounteren_tm; -- enable user-level access to time[h]
|
csr.rdata(2) <= csr.mcounteren_ir; -- enable user-level access to instret[h]
|
csr.rdata(2) <= csr.mcounteren_ir; -- enable user-level access to instret[h]
|
|
csr.rdata(csr.mcounteren_hpm'left+3 downto 3) <= csr.mcounteren_hpm; -- enable user-level access to hpmcounterx[h]
|
|
|
-- machine trap handling --
|
-- machine trap handling --
|
when csr_mscratch_c => -- R/W: mscratch - machine scratch register
|
when csr_mscratch_c => -- R/W: mscratch - machine scratch register
|
csr.rdata <= csr.mscratch;
|
csr.rdata <= csr.mscratch;
|
when csr_mepc_c => -- R/W: mepc - machine exception program counter
|
when csr_mepc_c => -- R/W: mepc - machine exception program counter
|
Line 1925... |
Line 2144... |
csr.rdata(17) <= csr.mip_status(interrupt_firq_1_c);
|
csr.rdata(17) <= csr.mip_status(interrupt_firq_1_c);
|
csr.rdata(18) <= csr.mip_status(interrupt_firq_2_c);
|
csr.rdata(18) <= csr.mip_status(interrupt_firq_2_c);
|
csr.rdata(19) <= csr.mip_status(interrupt_firq_3_c);
|
csr.rdata(19) <= csr.mip_status(interrupt_firq_3_c);
|
|
|
-- physical memory protection - configuration --
|
-- physical memory protection - configuration --
|
when csr_pmpcfg0_c => -- R/W: pmpcfg0 - physical memory protection configuration register 0
|
when csr_pmpcfg0_c => csr.rdata <= csr.pmpcfg_rd(03) & csr.pmpcfg_rd(02) & csr.pmpcfg_rd(01) & csr.pmpcfg_rd(00); -- R/W: pmpcfg0
|
if (PMP_USE = true) then
|
when csr_pmpcfg1_c => csr.rdata <= csr.pmpcfg_rd(07) & csr.pmpcfg_rd(06) & csr.pmpcfg_rd(05) & csr.pmpcfg_rd(04); -- R/W: pmpcfg1
|
if (pmp_num_regions_c >= 1) then
|
when csr_pmpcfg2_c => csr.rdata <= csr.pmpcfg_rd(11) & csr.pmpcfg_rd(10) & csr.pmpcfg_rd(09) & csr.pmpcfg_rd(08); -- R/W: pmpcfg2
|
csr.rdata(07 downto 00) <= csr.pmpcfg(0);
|
when csr_pmpcfg3_c => csr.rdata <= csr.pmpcfg_rd(15) & csr.pmpcfg_rd(14) & csr.pmpcfg_rd(13) & csr.pmpcfg_rd(12); -- R/W: pmpcfg3
|
end if;
|
when csr_pmpcfg4_c => csr.rdata <= csr.pmpcfg_rd(19) & csr.pmpcfg_rd(18) & csr.pmpcfg_rd(17) & csr.pmpcfg_rd(16); -- R/W: pmpcfg4
|
if (pmp_num_regions_c >= 2) then
|
when csr_pmpcfg5_c => csr.rdata <= csr.pmpcfg_rd(23) & csr.pmpcfg_rd(22) & csr.pmpcfg_rd(21) & csr.pmpcfg_rd(20); -- R/W: pmpcfg5
|
csr.rdata(15 downto 08) <= csr.pmpcfg(1);
|
when csr_pmpcfg6_c => csr.rdata <= csr.pmpcfg_rd(27) & csr.pmpcfg_rd(26) & csr.pmpcfg_rd(25) & csr.pmpcfg_rd(24); -- R/W: pmpcfg6
|
end if;
|
when csr_pmpcfg7_c => csr.rdata <= csr.pmpcfg_rd(31) & csr.pmpcfg_rd(30) & csr.pmpcfg_rd(29) & csr.pmpcfg_rd(28); -- R/W: pmpcfg7
|
if (pmp_num_regions_c >= 3) then
|
when csr_pmpcfg8_c => csr.rdata <= csr.pmpcfg_rd(35) & csr.pmpcfg_rd(34) & csr.pmpcfg_rd(33) & csr.pmpcfg_rd(32); -- R/W: pmpcfg8
|
csr.rdata(23 downto 16) <= csr.pmpcfg(2);
|
when csr_pmpcfg9_c => csr.rdata <= csr.pmpcfg_rd(39) & csr.pmpcfg_rd(38) & csr.pmpcfg_rd(37) & csr.pmpcfg_rd(36); -- R/W: pmpcfg9
|
end if;
|
when csr_pmpcfg10_c => csr.rdata <= csr.pmpcfg_rd(43) & csr.pmpcfg_rd(42) & csr.pmpcfg_rd(41) & csr.pmpcfg_rd(40); -- R/W: pmpcfg10
|
if (pmp_num_regions_c >= 4) then
|
when csr_pmpcfg11_c => csr.rdata <= csr.pmpcfg_rd(47) & csr.pmpcfg_rd(46) & csr.pmpcfg_rd(45) & csr.pmpcfg_rd(44); -- R/W: pmpcfg11
|
csr.rdata(31 downto 24) <= csr.pmpcfg(3);
|
when csr_pmpcfg12_c => csr.rdata <= csr.pmpcfg_rd(51) & csr.pmpcfg_rd(50) & csr.pmpcfg_rd(49) & csr.pmpcfg_rd(48); -- R/W: pmpcfg12
|
end if;
|
when csr_pmpcfg13_c => csr.rdata <= csr.pmpcfg_rd(55) & csr.pmpcfg_rd(54) & csr.pmpcfg_rd(53) & csr.pmpcfg_rd(52); -- R/W: pmpcfg13
|
end if;
|
when csr_pmpcfg14_c => csr.rdata <= csr.pmpcfg_rd(59) & csr.pmpcfg_rd(58) & csr.pmpcfg_rd(57) & csr.pmpcfg_rd(56); -- R/W: pmpcfg14
|
when csr_pmpcfg1_c => -- R/W: pmpcfg1 - physical memory protection configuration register 1
|
when csr_pmpcfg15_c => csr.rdata <= csr.pmpcfg_rd(63) & csr.pmpcfg_rd(62) & csr.pmpcfg_rd(61) & csr.pmpcfg_rd(60); -- R/W: pmpcfg15
|
if (PMP_USE = true) then
|
|
if (pmp_num_regions_c >= 5) then
|
|
csr.rdata(07 downto 00) <= csr.pmpcfg(4);
|
|
end if;
|
|
if (pmp_num_regions_c >= 6) then
|
|
csr.rdata(15 downto 08) <= csr.pmpcfg(5);
|
|
end if;
|
|
if (pmp_num_regions_c >= 7) then
|
|
csr.rdata(23 downto 16) <= csr.pmpcfg(6);
|
|
end if;
|
|
if (pmp_num_regions_c >= 8) then
|
|
csr.rdata(31 downto 24) <= csr.pmpcfg(7);
|
|
end if;
|
|
end if;
|
|
|
|
-- physical memory protection - addresses --
|
-- physical memory protection - addresses --
|
when csr_pmpaddr0_c => -- R/W: pmpaddr0 - physical memory protection address register 0
|
when csr_pmpaddr0_c => csr.rdata <= csr.pmpaddr_rd(00); -- R/W: pmpaddr0
|
if (PMP_USE = true) and (pmp_num_regions_c >= 1) then
|
when csr_pmpaddr1_c => csr.rdata <= csr.pmpaddr_rd(01); -- R/W: pmpaddr1
|
csr.rdata <= csr.pmpaddr(0);
|
when csr_pmpaddr2_c => csr.rdata <= csr.pmpaddr_rd(02); -- R/W: pmpaddr2
|
if (csr.pmpcfg(0)(4 downto 3) = "00") then -- mode = off
|
when csr_pmpaddr3_c => csr.rdata <= csr.pmpaddr_rd(03); -- R/W: pmpaddr3
|
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
|
when csr_pmpaddr4_c => csr.rdata <= csr.pmpaddr_rd(04); -- R/W: pmpaddr4
|
end if;
|
when csr_pmpaddr5_c => csr.rdata <= csr.pmpaddr_rd(05); -- R/W: pmpaddr5
|
end if;
|
when csr_pmpaddr6_c => csr.rdata <= csr.pmpaddr_rd(06); -- R/W: pmpaddr6
|
when csr_pmpaddr1_c => -- R/W: pmpaddr1 - physical memory protection address register 1
|
when csr_pmpaddr7_c => csr.rdata <= csr.pmpaddr_rd(07); -- R/W: pmpaddr7
|
if (PMP_USE = true) and (pmp_num_regions_c >= 2) then
|
when csr_pmpaddr8_c => csr.rdata <= csr.pmpaddr_rd(08); -- R/W: pmpaddr8
|
csr.rdata <= csr.pmpaddr(1);
|
when csr_pmpaddr9_c => csr.rdata <= csr.pmpaddr_rd(09); -- R/W: pmpaddr9
|
if (csr.pmpcfg(1)(4 downto 3) = "00") then -- mode = off
|
when csr_pmpaddr10_c => csr.rdata <= csr.pmpaddr_rd(10); -- R/W: pmpaddr10
|
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
|
when csr_pmpaddr11_c => csr.rdata <= csr.pmpaddr_rd(11); -- R/W: pmpaddr11
|
end if;
|
when csr_pmpaddr12_c => csr.rdata <= csr.pmpaddr_rd(12); -- R/W: pmpaddr12
|
end if;
|
when csr_pmpaddr13_c => csr.rdata <= csr.pmpaddr_rd(13); -- R/W: pmpaddr13
|
when csr_pmpaddr2_c => -- R/W: pmpaddr2 - physical memory protection address register 2
|
when csr_pmpaddr14_c => csr.rdata <= csr.pmpaddr_rd(14); -- R/W: pmpaddr14
|
if (PMP_USE = true) and (pmp_num_regions_c >= 3) then
|
when csr_pmpaddr15_c => csr.rdata <= csr.pmpaddr_rd(15); -- R/W: pmpaddr15
|
csr.rdata <= csr.pmpaddr(2);
|
when csr_pmpaddr16_c => csr.rdata <= csr.pmpaddr_rd(16); -- R/W: pmpaddr16
|
if (csr.pmpcfg(2)(4 downto 3) = "00") then -- mode = off
|
when csr_pmpaddr17_c => csr.rdata <= csr.pmpaddr_rd(17); -- R/W: pmpaddr17
|
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
|
when csr_pmpaddr18_c => csr.rdata <= csr.pmpaddr_rd(18); -- R/W: pmpaddr18
|
end if;
|
when csr_pmpaddr19_c => csr.rdata <= csr.pmpaddr_rd(19); -- R/W: pmpaddr19
|
end if;
|
when csr_pmpaddr20_c => csr.rdata <= csr.pmpaddr_rd(20); -- R/W: pmpaddr20
|
when csr_pmpaddr3_c => -- R/W: pmpaddr3 - physical memory protection address register 3
|
when csr_pmpaddr21_c => csr.rdata <= csr.pmpaddr_rd(21); -- R/W: pmpaddr21
|
if (PMP_USE = true) and (pmp_num_regions_c >= 4) then
|
when csr_pmpaddr22_c => csr.rdata <= csr.pmpaddr_rd(22); -- R/W: pmpaddr22
|
csr.rdata <= csr.pmpaddr(3);
|
when csr_pmpaddr23_c => csr.rdata <= csr.pmpaddr_rd(23); -- R/W: pmpaddr23
|
if (csr.pmpcfg(3)(4 downto 3) = "00") then -- mode = off
|
when csr_pmpaddr24_c => csr.rdata <= csr.pmpaddr_rd(24); -- R/W: pmpaddr24
|
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
|
when csr_pmpaddr25_c => csr.rdata <= csr.pmpaddr_rd(25); -- R/W: pmpaddr25
|
end if;
|
when csr_pmpaddr26_c => csr.rdata <= csr.pmpaddr_rd(26); -- R/W: pmpaddr26
|
end if;
|
when csr_pmpaddr27_c => csr.rdata <= csr.pmpaddr_rd(27); -- R/W: pmpaddr27
|
when csr_pmpaddr4_c => -- R/W: pmpaddr4 - physical memory protection address register 4
|
when csr_pmpaddr28_c => csr.rdata <= csr.pmpaddr_rd(28); -- R/W: pmpaddr28
|
if (PMP_USE = true) and (pmp_num_regions_c >= 5) then
|
when csr_pmpaddr29_c => csr.rdata <= csr.pmpaddr_rd(29); -- R/W: pmpaddr29
|
csr.rdata <= csr.pmpaddr(4);
|
when csr_pmpaddr30_c => csr.rdata <= csr.pmpaddr_rd(30); -- R/W: pmpaddr30
|
if (csr.pmpcfg(4)(4 downto 3) = "00") then -- mode = off
|
when csr_pmpaddr31_c => csr.rdata <= csr.pmpaddr_rd(31); -- R/W: pmpaddr31
|
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
|
when csr_pmpaddr32_c => csr.rdata <= csr.pmpaddr_rd(32); -- R/W: pmpaddr32
|
end if;
|
when csr_pmpaddr33_c => csr.rdata <= csr.pmpaddr_rd(33); -- R/W: pmpaddr33
|
end if;
|
when csr_pmpaddr34_c => csr.rdata <= csr.pmpaddr_rd(34); -- R/W: pmpaddr34
|
when csr_pmpaddr5_c => -- R/W: pmpaddr5 - physical memory protection address register 5
|
when csr_pmpaddr35_c => csr.rdata <= csr.pmpaddr_rd(35); -- R/W: pmpaddr35
|
if (PMP_USE = true) and (pmp_num_regions_c >= 6) then
|
when csr_pmpaddr36_c => csr.rdata <= csr.pmpaddr_rd(36); -- R/W: pmpaddr36
|
csr.rdata <= csr.pmpaddr(5);
|
when csr_pmpaddr37_c => csr.rdata <= csr.pmpaddr_rd(37); -- R/W: pmpaddr37
|
if (csr.pmpcfg(5)(4 downto 3) = "00") then -- mode = off
|
when csr_pmpaddr38_c => csr.rdata <= csr.pmpaddr_rd(38); -- R/W: pmpaddr38
|
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
|
when csr_pmpaddr39_c => csr.rdata <= csr.pmpaddr_rd(39); -- R/W: pmpaddr39
|
end if;
|
when csr_pmpaddr40_c => csr.rdata <= csr.pmpaddr_rd(40); -- R/W: pmpaddr40
|
end if;
|
when csr_pmpaddr41_c => csr.rdata <= csr.pmpaddr_rd(41); -- R/W: pmpaddr41
|
when csr_pmpaddr6_c => -- R/W: pmpaddr6 - physical memory protection address register 6
|
when csr_pmpaddr42_c => csr.rdata <= csr.pmpaddr_rd(42); -- R/W: pmpaddr42
|
if (PMP_USE = true) and (pmp_num_regions_c >= 7) then
|
when csr_pmpaddr43_c => csr.rdata <= csr.pmpaddr_rd(43); -- R/W: pmpaddr43
|
csr.rdata <= csr.pmpaddr(6);
|
when csr_pmpaddr44_c => csr.rdata <= csr.pmpaddr_rd(44); -- R/W: pmpaddr44
|
if (csr.pmpcfg(6)(4 downto 3) = "00") then -- mode = off
|
when csr_pmpaddr45_c => csr.rdata <= csr.pmpaddr_rd(45); -- R/W: pmpaddr45
|
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
|
when csr_pmpaddr46_c => csr.rdata <= csr.pmpaddr_rd(46); -- R/W: pmpaddr46
|
end if;
|
when csr_pmpaddr47_c => csr.rdata <= csr.pmpaddr_rd(47); -- R/W: pmpaddr47
|
end if;
|
when csr_pmpaddr48_c => csr.rdata <= csr.pmpaddr_rd(48); -- R/W: pmpaddr48
|
when csr_pmpaddr7_c => -- R/W: pmpaddr7 - physical memory protection address register 7
|
when csr_pmpaddr49_c => csr.rdata <= csr.pmpaddr_rd(49); -- R/W: pmpaddr49
|
if (PMP_USE = true) and (pmp_num_regions_c >= 8) then
|
when csr_pmpaddr50_c => csr.rdata <= csr.pmpaddr_rd(50); -- R/W: pmpaddr50
|
csr.rdata <= csr.pmpaddr(7);
|
when csr_pmpaddr51_c => csr.rdata <= csr.pmpaddr_rd(51); -- R/W: pmpaddr51
|
if (csr.pmpcfg(7)(4 downto 3) = "00") then -- mode = off
|
when csr_pmpaddr52_c => csr.rdata <= csr.pmpaddr_rd(52); -- R/W: pmpaddr52
|
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
|
when csr_pmpaddr53_c => csr.rdata <= csr.pmpaddr_rd(53); -- R/W: pmpaddr53
|
end if;
|
when csr_pmpaddr54_c => csr.rdata <= csr.pmpaddr_rd(54); -- R/W: pmpaddr54
|
end if;
|
when csr_pmpaddr55_c => csr.rdata <= csr.pmpaddr_rd(55); -- R/W: pmpaddr55
|
|
when csr_pmpaddr56_c => csr.rdata <= csr.pmpaddr_rd(56); -- R/W: pmpaddr56
|
|
when csr_pmpaddr57_c => csr.rdata <= csr.pmpaddr_rd(57); -- R/W: pmpaddr57
|
|
when csr_pmpaddr58_c => csr.rdata <= csr.pmpaddr_rd(58); -- R/W: pmpaddr58
|
|
when csr_pmpaddr59_c => csr.rdata <= csr.pmpaddr_rd(59); -- R/W: pmpaddr59
|
|
when csr_pmpaddr60_c => csr.rdata <= csr.pmpaddr_rd(60); -- R/W: pmpaddr60
|
|
when csr_pmpaddr61_c => csr.rdata <= csr.pmpaddr_rd(61); -- R/W: pmpaddr61
|
|
when csr_pmpaddr62_c => csr.rdata <= csr.pmpaddr_rd(62); -- R/W: pmpaddr62
|
|
when csr_pmpaddr63_c => csr.rdata <= csr.pmpaddr_rd(63); -- R/W: pmpaddr63
|
|
|
-- machine counter setup --
|
-- machine counter setup --
|
-- --------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
when csr_mcountinhibit_c => -- R/W: mcountinhibit - machine counter-inhibit register
|
when csr_mcountinhibit_c => -- R/W: mcountinhibit - machine counter-inhibit register
|
csr.rdata(0) <= csr.mcountinhibit_cy; -- enable auto-increment of [m]cycle[h] counter
|
csr.rdata(0) <= csr.mcountinhibit_cy; -- enable auto-increment of [m]cycle[h] counter
|
csr.rdata(2) <= csr.mcountinhibit_ir; -- enable auto-increment of [m]instret[h] counter
|
csr.rdata(2) <= csr.mcountinhibit_ir; -- enable auto-increment of [m]instret[h] counter
|
|
csr.rdata(csr.mcountinhibit_hpm'left+3 downto 3) <= csr.mcountinhibit_hpm; -- enable auto-increment of [m]hpmcounterx[h] counter
|
|
|
|
-- machine performance-monitoring event selector --
|
|
when csr_mhpmevent3_c => csr.rdata(csr.mhpmevent_rd(00)'left downto 0) <= csr.mhpmevent_rd(00); -- R/W: mhpmevent3
|
|
when csr_mhpmevent4_c => csr.rdata(csr.mhpmevent_rd(01)'left downto 0) <= csr.mhpmevent_rd(01); -- R/W: mhpmevent4
|
|
when csr_mhpmevent5_c => csr.rdata(csr.mhpmevent_rd(02)'left downto 0) <= csr.mhpmevent_rd(02); -- R/W: mhpmevent5
|
|
when csr_mhpmevent6_c => csr.rdata(csr.mhpmevent_rd(03)'left downto 0) <= csr.mhpmevent_rd(03); -- R/W: mhpmevent6
|
|
when csr_mhpmevent7_c => csr.rdata(csr.mhpmevent_rd(04)'left downto 0) <= csr.mhpmevent_rd(04); -- R/W: mhpmevent7
|
|
when csr_mhpmevent8_c => csr.rdata(csr.mhpmevent_rd(05)'left downto 0) <= csr.mhpmevent_rd(05); -- R/W: mhpmevent8
|
|
when csr_mhpmevent9_c => csr.rdata(csr.mhpmevent_rd(06)'left downto 0) <= csr.mhpmevent_rd(06); -- R/W: mhpmevent9
|
|
when csr_mhpmevent10_c => csr.rdata(csr.mhpmevent_rd(07)'left downto 0) <= csr.mhpmevent_rd(07); -- R/W: mhpmevent10
|
|
when csr_mhpmevent11_c => csr.rdata(csr.mhpmevent_rd(08)'left downto 0) <= csr.mhpmevent_rd(08); -- R/W: mhpmevent11
|
|
when csr_mhpmevent12_c => csr.rdata(csr.mhpmevent_rd(09)'left downto 0) <= csr.mhpmevent_rd(09); -- R/W: mhpmevent12
|
|
when csr_mhpmevent13_c => csr.rdata(csr.mhpmevent_rd(10)'left downto 0) <= csr.mhpmevent_rd(10); -- R/W: mhpmevent13
|
|
when csr_mhpmevent14_c => csr.rdata(csr.mhpmevent_rd(11)'left downto 0) <= csr.mhpmevent_rd(11); -- R/W: mhpmevent14
|
|
when csr_mhpmevent15_c => csr.rdata(csr.mhpmevent_rd(12)'left downto 0) <= csr.mhpmevent_rd(12); -- R/W: mhpmevent15
|
|
when csr_mhpmevent16_c => csr.rdata(csr.mhpmevent_rd(13)'left downto 0) <= csr.mhpmevent_rd(13); -- R/W: mhpmevent16
|
|
when csr_mhpmevent17_c => csr.rdata(csr.mhpmevent_rd(14)'left downto 0) <= csr.mhpmevent_rd(14); -- R/W: mhpmevent17
|
|
when csr_mhpmevent18_c => csr.rdata(csr.mhpmevent_rd(15)'left downto 0) <= csr.mhpmevent_rd(15); -- R/W: mhpmevent18
|
|
when csr_mhpmevent19_c => csr.rdata(csr.mhpmevent_rd(16)'left downto 0) <= csr.mhpmevent_rd(16); -- R/W: mhpmevent19
|
|
when csr_mhpmevent20_c => csr.rdata(csr.mhpmevent_rd(17)'left downto 0) <= csr.mhpmevent_rd(17); -- R/W: mhpmevent20
|
|
when csr_mhpmevent21_c => csr.rdata(csr.mhpmevent_rd(18)'left downto 0) <= csr.mhpmevent_rd(18); -- R/W: mhpmevent21
|
|
when csr_mhpmevent22_c => csr.rdata(csr.mhpmevent_rd(19)'left downto 0) <= csr.mhpmevent_rd(19); -- R/W: mhpmevent22
|
|
when csr_mhpmevent23_c => csr.rdata(csr.mhpmevent_rd(20)'left downto 0) <= csr.mhpmevent_rd(20); -- R/W: mhpmevent23
|
|
when csr_mhpmevent24_c => csr.rdata(csr.mhpmevent_rd(21)'left downto 0) <= csr.mhpmevent_rd(21); -- R/W: mhpmevent24
|
|
when csr_mhpmevent25_c => csr.rdata(csr.mhpmevent_rd(22)'left downto 0) <= csr.mhpmevent_rd(22); -- R/W: mhpmevent25
|
|
when csr_mhpmevent26_c => csr.rdata(csr.mhpmevent_rd(23)'left downto 0) <= csr.mhpmevent_rd(23); -- R/W: mhpmevent26
|
|
when csr_mhpmevent27_c => csr.rdata(csr.mhpmevent_rd(24)'left downto 0) <= csr.mhpmevent_rd(24); -- R/W: mhpmevent27
|
|
when csr_mhpmevent28_c => csr.rdata(csr.mhpmevent_rd(25)'left downto 0) <= csr.mhpmevent_rd(25); -- R/W: mhpmevent28
|
|
when csr_mhpmevent29_c => csr.rdata(csr.mhpmevent_rd(26)'left downto 0) <= csr.mhpmevent_rd(26); -- R/W: mhpmevent29
|
|
when csr_mhpmevent30_c => csr.rdata(csr.mhpmevent_rd(27)'left downto 0) <= csr.mhpmevent_rd(27); -- R/W: mhpmevent30
|
|
when csr_mhpmevent31_c => csr.rdata(csr.mhpmevent_rd(28)'left downto 0) <= csr.mhpmevent_rd(28); -- R/W: mhpmevent31
|
|
|
-- counters and timers --
|
-- counters and timers --
|
when csr_cycle_c | csr_mcycle_c => -- R/(W): [m]cycle: Cycle counter LOW
|
when csr_cycle_c | csr_mcycle_c => -- (R)/(W): [m]cycle: Cycle counter LOW
|
csr.rdata <= csr.mcycle(31 downto 0);
|
csr.rdata <= csr.mcycle(31 downto 0);
|
when csr_time_c => -- R/-: time: System time LOW (from MTIME unit)
|
when csr_time_c => -- (R)/-: time: System time LOW (from MTIME unit)
|
csr.rdata <= time_i(31 downto 0);
|
csr.rdata <= time_i(31 downto 0);
|
when csr_instret_c | csr_minstret_c => -- R/(W): [m]instret: Instructions-retired counter LOW
|
when csr_instret_c | csr_minstret_c => -- (R)/(W): [m]instret: Instructions-retired counter LOW
|
csr.rdata <= csr.minstret(31 downto 0);
|
csr.rdata <= csr.minstret(31 downto 0);
|
when csr_cycleh_c | csr_mcycleh_c => -- R/(W): [m]cycleh: Cycle counter HIGH
|
when csr_cycleh_c | csr_mcycleh_c => -- (R)/(W): [m]cycleh: Cycle counter HIGH
|
csr.rdata <= csr.mcycleh(31 downto 0);
|
csr.rdata <= csr.mcycleh(31 downto 0);
|
when csr_timeh_c => -- R/-: timeh: System time HIGH (from MTIME unit)
|
when csr_timeh_c => -- (R)/-: timeh: System time HIGH (from MTIME unit)
|
csr.rdata <= time_i(63 downto 32);
|
csr.rdata <= time_i(63 downto 32);
|
when csr_instreth_c | csr_minstreth_c => -- R/(W): [m]instreth: Instructions-retired counter HIGH
|
when csr_instreth_c | csr_minstreth_c => -- (R)/(W): [m]instreth: Instructions-retired counter HIGH
|
csr.rdata <= csr.minstreth(31 downto 0);
|
csr.rdata <= csr.minstreth(31 downto 0);
|
|
|
|
-- hardware performance counters --
|
|
when csr_hpmcounter3_c | csr_mhpmcounter3_c => csr.rdata <= csr.mhpmcounter_rd(00)(31 downto 0); -- (R)/(W): [m]hpmcounter3 - low
|
|
when csr_hpmcounter4_c | csr_mhpmcounter4_c => csr.rdata <= csr.mhpmcounter_rd(01)(31 downto 0); -- (R)/(W): [m]hpmcounter4 - low
|
|
when csr_hpmcounter5_c | csr_mhpmcounter5_c => csr.rdata <= csr.mhpmcounter_rd(02)(31 downto 0); -- (R)/(W): [m]hpmcounter5 - low
|
|
when csr_hpmcounter6_c | csr_mhpmcounter6_c => csr.rdata <= csr.mhpmcounter_rd(03)(31 downto 0); -- (R)/(W): [m]hpmcounter6 - low
|
|
when csr_hpmcounter7_c | csr_mhpmcounter7_c => csr.rdata <= csr.mhpmcounter_rd(04)(31 downto 0); -- (R)/(W): [m]hpmcounter7 - low
|
|
when csr_hpmcounter8_c | csr_mhpmcounter8_c => csr.rdata <= csr.mhpmcounter_rd(05)(31 downto 0); -- (R)/(W): [m]hpmcounter8 - low
|
|
when csr_hpmcounter9_c | csr_mhpmcounter9_c => csr.rdata <= csr.mhpmcounter_rd(06)(31 downto 0); -- (R)/(W): [m]hpmcounter9 - low
|
|
when csr_hpmcounter10_c | csr_mhpmcounter10_c => csr.rdata <= csr.mhpmcounter_rd(07)(31 downto 0); -- (R)/(W): [m]hpmcounter10 - low
|
|
when csr_hpmcounter11_c | csr_mhpmcounter11_c => csr.rdata <= csr.mhpmcounter_rd(08)(31 downto 0); -- (R)/(W): [m]hpmcounter11 - low
|
|
when csr_hpmcounter12_c | csr_mhpmcounter12_c => csr.rdata <= csr.mhpmcounter_rd(09)(31 downto 0); -- (R)/(W): [m]hpmcounter12 - low
|
|
when csr_hpmcounter13_c | csr_mhpmcounter13_c => csr.rdata <= csr.mhpmcounter_rd(10)(31 downto 0); -- (R)/(W): [m]hpmcounter13 - low
|
|
when csr_hpmcounter14_c | csr_mhpmcounter14_c => csr.rdata <= csr.mhpmcounter_rd(11)(31 downto 0); -- (R)/(W): [m]hpmcounter14 - low
|
|
when csr_hpmcounter15_c | csr_mhpmcounter15_c => csr.rdata <= csr.mhpmcounter_rd(12)(31 downto 0); -- (R)/(W): [m]hpmcounter15 - low
|
|
when csr_hpmcounter16_c | csr_mhpmcounter16_c => csr.rdata <= csr.mhpmcounter_rd(13)(31 downto 0); -- (R)/(W): [m]hpmcounter16 - low
|
|
when csr_hpmcounter17_c | csr_mhpmcounter17_c => csr.rdata <= csr.mhpmcounter_rd(14)(31 downto 0); -- (R)/(W): [m]hpmcounter17 - low
|
|
when csr_hpmcounter18_c | csr_mhpmcounter18_c => csr.rdata <= csr.mhpmcounter_rd(15)(31 downto 0); -- (R)/(W): [m]hpmcounter18 - low
|
|
when csr_hpmcounter19_c | csr_mhpmcounter19_c => csr.rdata <= csr.mhpmcounter_rd(16)(31 downto 0); -- (R)/(W): [m]hpmcounter19 - low
|
|
when csr_hpmcounter20_c | csr_mhpmcounter20_c => csr.rdata <= csr.mhpmcounter_rd(17)(31 downto 0); -- (R)/(W): [m]hpmcounter20 - low
|
|
when csr_hpmcounter21_c | csr_mhpmcounter21_c => csr.rdata <= csr.mhpmcounter_rd(18)(31 downto 0); -- (R)/(W): [m]hpmcounter21 - low
|
|
when csr_hpmcounter22_c | csr_mhpmcounter22_c => csr.rdata <= csr.mhpmcounter_rd(19)(31 downto 0); -- (R)/(W): [m]hpmcounter22 - low
|
|
when csr_hpmcounter23_c | csr_mhpmcounter23_c => csr.rdata <= csr.mhpmcounter_rd(20)(31 downto 0); -- (R)/(W): [m]hpmcounter23 - low
|
|
when csr_hpmcounter24_c | csr_mhpmcounter24_c => csr.rdata <= csr.mhpmcounter_rd(21)(31 downto 0); -- (R)/(W): [m]hpmcounter24 - low
|
|
when csr_hpmcounter25_c | csr_mhpmcounter25_c => csr.rdata <= csr.mhpmcounter_rd(22)(31 downto 0); -- (R)/(W): [m]hpmcounter25 - low
|
|
when csr_hpmcounter26_c | csr_mhpmcounter26_c => csr.rdata <= csr.mhpmcounter_rd(23)(31 downto 0); -- (R)/(W): [m]hpmcounter26 - low
|
|
when csr_hpmcounter27_c | csr_mhpmcounter27_c => csr.rdata <= csr.mhpmcounter_rd(24)(31 downto 0); -- (R)/(W): [m]hpmcounter27 - low
|
|
when csr_hpmcounter28_c | csr_mhpmcounter28_c => csr.rdata <= csr.mhpmcounter_rd(25)(31 downto 0); -- (R)/(W): [m]hpmcounter28 - low
|
|
when csr_hpmcounter29_c | csr_mhpmcounter29_c => csr.rdata <= csr.mhpmcounter_rd(26)(31 downto 0); -- (R)/(W): [m]hpmcounter29 - low
|
|
when csr_hpmcounter30_c | csr_mhpmcounter30_c => csr.rdata <= csr.mhpmcounter_rd(27)(31 downto 0); -- (R)/(W): [m]hpmcounter30 - low
|
|
when csr_hpmcounter31_c | csr_mhpmcounter31_c => csr.rdata <= csr.mhpmcounter_rd(28)(31 downto 0); -- (R)/(W): [m]hpmcounter31 - low
|
|
|
|
when csr_hpmcounter3h_c | csr_mhpmcounter3h_c => csr.rdata <= csr.mhpmcounterh_rd(00)(31 downto 0); -- (R)/(W): [m]hpmcounter3h - high
|
|
when csr_hpmcounter4h_c | csr_mhpmcounter4h_c => csr.rdata <= csr.mhpmcounterh_rd(01)(31 downto 0); -- (R)/(W): [m]hpmcounter4h - high
|
|
when csr_hpmcounter5h_c | csr_mhpmcounter5h_c => csr.rdata <= csr.mhpmcounterh_rd(02)(31 downto 0); -- (R)/(W): [m]hpmcounter5h - high
|
|
when csr_hpmcounter6h_c | csr_mhpmcounter6h_c => csr.rdata <= csr.mhpmcounterh_rd(03)(31 downto 0); -- (R)/(W): [m]hpmcounter6h - high
|
|
when csr_hpmcounter7h_c | csr_mhpmcounter7h_c => csr.rdata <= csr.mhpmcounterh_rd(04)(31 downto 0); -- (R)/(W): [m]hpmcounter7h - high
|
|
when csr_hpmcounter8h_c | csr_mhpmcounter8h_c => csr.rdata <= csr.mhpmcounterh_rd(05)(31 downto 0); -- (R)/(W): [m]hpmcounter8h - high
|
|
when csr_hpmcounter9h_c | csr_mhpmcounter9h_c => csr.rdata <= csr.mhpmcounterh_rd(06)(31 downto 0); -- (R)/(W): [m]hpmcounter9h - high
|
|
when csr_hpmcounter10h_c | csr_mhpmcounter10h_c => csr.rdata <= csr.mhpmcounterh_rd(07)(31 downto 0); -- (R)/(W): [m]hpmcounter10h - high
|
|
when csr_hpmcounter11h_c | csr_mhpmcounter11h_c => csr.rdata <= csr.mhpmcounterh_rd(08)(31 downto 0); -- (R)/(W): [m]hpmcounter11h - high
|
|
when csr_hpmcounter12h_c | csr_mhpmcounter12h_c => csr.rdata <= csr.mhpmcounterh_rd(09)(31 downto 0); -- (R)/(W): [m]hpmcounter12h - high
|
|
when csr_hpmcounter13h_c | csr_mhpmcounter13h_c => csr.rdata <= csr.mhpmcounterh_rd(10)(31 downto 0); -- (R)/(W): [m]hpmcounter13h - high
|
|
when csr_hpmcounter14h_c | csr_mhpmcounter14h_c => csr.rdata <= csr.mhpmcounterh_rd(11)(31 downto 0); -- (R)/(W): [m]hpmcounter14h - high
|
|
when csr_hpmcounter15h_c | csr_mhpmcounter15h_c => csr.rdata <= csr.mhpmcounterh_rd(12)(31 downto 0); -- (R)/(W): [m]hpmcounter15h - high
|
|
when csr_hpmcounter16h_c | csr_mhpmcounter16h_c => csr.rdata <= csr.mhpmcounterh_rd(13)(31 downto 0); -- (R)/(W): [m]hpmcounter16h - high
|
|
when csr_hpmcounter17h_c | csr_mhpmcounter17h_c => csr.rdata <= csr.mhpmcounterh_rd(14)(31 downto 0); -- (R)/(W): [m]hpmcounter17h - high
|
|
when csr_hpmcounter18h_c | csr_mhpmcounter18h_c => csr.rdata <= csr.mhpmcounterh_rd(15)(31 downto 0); -- (R)/(W): [m]hpmcounter18h - high
|
|
when csr_hpmcounter19h_c | csr_mhpmcounter19h_c => csr.rdata <= csr.mhpmcounterh_rd(16)(31 downto 0); -- (R)/(W): [m]hpmcounter19h - high
|
|
when csr_hpmcounter20h_c | csr_mhpmcounter20h_c => csr.rdata <= csr.mhpmcounterh_rd(17)(31 downto 0); -- (R)/(W): [m]hpmcounter20h - high
|
|
when csr_hpmcounter21h_c | csr_mhpmcounter21h_c => csr.rdata <= csr.mhpmcounterh_rd(18)(31 downto 0); -- (R)/(W): [m]hpmcounter21h - high
|
|
when csr_hpmcounter22h_c | csr_mhpmcounter22h_c => csr.rdata <= csr.mhpmcounterh_rd(19)(31 downto 0); -- (R)/(W): [m]hpmcounter22h - high
|
|
when csr_hpmcounter23h_c | csr_mhpmcounter23h_c => csr.rdata <= csr.mhpmcounterh_rd(20)(31 downto 0); -- (R)/(W): [m]hpmcounter23h - high
|
|
when csr_hpmcounter24h_c | csr_mhpmcounter24h_c => csr.rdata <= csr.mhpmcounterh_rd(21)(31 downto 0); -- (R)/(W): [m]hpmcounter24h - high
|
|
when csr_hpmcounter25h_c | csr_mhpmcounter25h_c => csr.rdata <= csr.mhpmcounterh_rd(22)(31 downto 0); -- (R)/(W): [m]hpmcounter25h - high
|
|
when csr_hpmcounter26h_c | csr_mhpmcounter26h_c => csr.rdata <= csr.mhpmcounterh_rd(23)(31 downto 0); -- (R)/(W): [m]hpmcounter26h - high
|
|
when csr_hpmcounter27h_c | csr_mhpmcounter27h_c => csr.rdata <= csr.mhpmcounterh_rd(24)(31 downto 0); -- (R)/(W): [m]hpmcounter27h - high
|
|
when csr_hpmcounter28h_c | csr_mhpmcounter28h_c => csr.rdata <= csr.mhpmcounterh_rd(25)(31 downto 0); -- (R)/(W): [m]hpmcounter28h - high
|
|
when csr_hpmcounter29h_c | csr_mhpmcounter29h_c => csr.rdata <= csr.mhpmcounterh_rd(26)(31 downto 0); -- (R)/(W): [m]hpmcounter29h - high
|
|
when csr_hpmcounter30h_c | csr_mhpmcounter30h_c => csr.rdata <= csr.mhpmcounterh_rd(27)(31 downto 0); -- (R)/(W): [m]hpmcounter30h - high
|
|
when csr_hpmcounter31h_c | csr_mhpmcounter31h_c => csr.rdata <= csr.mhpmcounterh_rd(28)(31 downto 0); -- (R)/(W): [m]hpmcounter31h - high
|
|
|
-- machine information registers --
|
-- machine information registers --
|
when csr_mvendorid_c => -- R/-: mvendorid - vendor ID
|
when csr_mvendorid_c => -- R/-: mvendorid - vendor ID
|
csr.rdata <= (others => '0');
|
csr.rdata <= (others => '0');
|
when csr_marchid_c => -- R/-: marchid - arch ID
|
when csr_marchid_c => -- R/-: marchid - arch ID
|
csr.rdata(4 downto 0) <= "10011"; -- official RISC-V open-source arch ID
|
csr.rdata(4 downto 0) <= "10011"; -- official RISC-V open-source arch ID
|
Line 2048... |
Line 2354... |
|
|
-- custom machine read-only CSRs --
|
-- custom machine read-only CSRs --
|
when csr_mzext_c => -- R/-: mzext - available Z* extensions
|
when csr_mzext_c => -- R/-: mzext - available Z* extensions
|
csr.rdata(0) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr); -- RISC-V.Zicsr CPU extension
|
csr.rdata(0) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr); -- RISC-V.Zicsr CPU extension
|
csr.rdata(1) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- RISC-V.Zifencei CPU extension
|
csr.rdata(1) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- RISC-V.Zifencei CPU extension
|
csr.rdata(2) <= bool_to_ulogic_f(PMP_USE); -- RISC-V physical memory protection
|
|
|
|
-- undefined/unavailable --
|
-- undefined/unavailable --
|
when others =>
|
when others =>
|
csr.rdata <= (others => '0'); -- not implemented
|
csr.rdata <= (others => '0'); -- not implemented
|
|
|