OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_control.vhd] - Diff between revs 41 and 42

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 41 Rev 42
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
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.