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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_control.vhd] - Diff between revs 14 and 15

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

Rev 14 Rev 15
Line 51... Line 51...
    CPU_BOOT_ADDR                : std_ulogic_vector(31 downto 0):= x"00000000"; -- cpu boot address
    CPU_BOOT_ADDR                : std_ulogic_vector(31 downto 0):= x"00000000"; -- cpu boot address
    -- RISC-V CPU Extensions --
    -- RISC-V CPU Extensions --
    CPU_EXTENSION_RISCV_C        : boolean := false; -- implement compressed extension?
    CPU_EXTENSION_RISCV_C        : boolean := false; -- implement compressed extension?
    CPU_EXTENSION_RISCV_E        : boolean := false; -- implement embedded RF extension?
    CPU_EXTENSION_RISCV_E        : boolean := false; -- implement embedded RF extension?
    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_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) --
 
    PMP_USE                      : boolean := false; -- implement physical memory protection?
 
    PMP_NUM_REGIONS              : natural := 4; -- number of regions (1..4)
 
    PMP_GRANULARITY              : natural := 0  -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...)
  );
  );
  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 83... Line 88...
    mtime_irq_i   : in  std_ulogic; -- machine timer interrupt
    mtime_irq_i   : in  std_ulogic; -- machine timer interrupt
    -- fast interrupts (custom) --
    -- fast interrupts (custom) --
    firq_i        : in  std_ulogic_vector(3 downto 0);
    firq_i        : in  std_ulogic_vector(3 downto 0);
    -- system time input from MTIME --
    -- system time input from MTIME --
    time_i        : in  std_ulogic_vector(63 downto 0); -- current system time
    time_i        : in  std_ulogic_vector(63 downto 0); -- current system time
 
    -- physical memory protection --
 
    pmp_addr_o     : out pmp_addr_if_t; -- addresses
 
    pmp_maddr_i    : in  pmp_addr_if_t; -- masked addresses
 
    pmp_ctrl_o     : out pmp_ctrl_if_t; -- configs
 
    priv_mode_o    : out std_ulogic_vector(1 downto 0); -- current CPU privilege level
    -- bus access exceptions --
    -- bus access exceptions --
    mar_i         : in  std_ulogic_vector(data_width_c-1 downto 0);  -- memory address register
    mar_i         : in  std_ulogic_vector(data_width_c-1 downto 0);  -- memory address register
    ma_instr_i    : in  std_ulogic; -- misaligned instruction address
    ma_instr_i    : in  std_ulogic; -- misaligned instruction address
    ma_load_i     : in  std_ulogic; -- misaligned load data address
    ma_load_i     : in  std_ulogic; -- misaligned load data address
    ma_store_i    : in  std_ulogic; -- misaligned store data address
    ma_store_i    : in  std_ulogic; -- misaligned store data address
Line 190... Line 200...
 
 
  -- fast bus access --
  -- fast bus 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_NUM_REGIONS-1) of std_ulogic_vector(7 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 csr_t is record
  type csr_t is record
    we           : std_ulogic; -- write enable
    we           : std_ulogic; -- write enable
    we_nxt       : std_ulogic;
    we_nxt       : std_ulogic;
    re           : std_ulogic; -- read enable
    re           : std_ulogic; -- read enable
    re_nxt       : std_ulogic;
    re_nxt       : std_ulogic;
Line 201... Line 213...
    mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/-)
    mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/-)
    mie_msie     : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W)
    mie_msie     : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W)
    mie_meie     : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W)
    mie_meie     : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W)
    mie_mtie     : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W
    mie_mtie     : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W
    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)
 
    mpp          : std_ulogic_vector(1 downto 0); -- machine previous privilege mode
 
    privilege    : std_ulogic_vector(1 downto 0); -- hart's current previous privilege mode
    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/-)
    mcause       : std_ulogic_vector(data_width_c-1 downto 0); -- mcause: machine trap cause (R/-)
    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)
    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(19 downto 0); -- mcycleh (R/W) - REDUCED BIT-WIDTH!
    mcycleh      : std_ulogic_vector(19 downto 0); -- mcycleh (R/W) - REDUCED BIT-WIDTH!
    minstreth    : std_ulogic_vector(19 downto 0); -- minstreth (R/W) - REDUCED BIT-WIDTH!
    minstreth    : std_ulogic_vector(19 downto 0); -- minstreth (R/W) - REDUCED BIT-WIDTH!
 
    pmpcfg       : pmp_ctrl_t; -- physical memory protection - configuration registers
 
    pmpaddr      : pmp_addr_t; -- physical memory protection - address registers
  end record;
  end record;
  signal csr : csr_t;
  signal csr : csr_t;
 
 
  signal mcycle_msb   : std_ulogic;
  signal mcycle_msb   : std_ulogic;
  signal minstret_msb : std_ulogic;
  signal minstret_msb : std_ulogic;
Line 222... Line 238...
  -- illegal instruction check --
  -- illegal instruction check --
  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
  signal illegal_compressed  : std_ulogic; -- only fir C-extension
  signal illegal_compressed  : std_ulogic; -- only fir C-extension
 
 
 
  -- access (privilege) check --
 
  signal csr_acc_valid : std_ulogic; -- valid CSR access (implemented and valid access rights)
 
 
begin
begin
 
 
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
-- Instruction Fetch
-- Instruction Fetch
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
Line 542... Line 561...
  end process ctrl_output;
  end process ctrl_output;
 
 
 
 
  -- Execute Engine FSM Comb ----------------------------------------------------------------
  -- Execute Engine FSM Comb ----------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  execute_engine_fsm_comb: process(execute_engine, fetch_engine, ipb, trap_ctrl, csr, ctrl,
  execute_engine_fsm_comb: process(execute_engine, fetch_engine, ipb, trap_ctrl, csr, ctrl, csr_acc_valid,
                                   alu_add_i, alu_wait_i, bus_d_wait_i, ma_load_i, be_load_i, ma_store_i, be_store_i)
                                   alu_add_i, alu_wait_i, bus_d_wait_i, ma_load_i, be_load_i, ma_store_i, be_store_i)
    variable alu_immediate_v : std_ulogic;
    variable alu_immediate_v : std_ulogic;
    variable alu_operation_v : std_ulogic_vector(2 downto 0);
    variable alu_operation_v : std_ulogic_vector(2 downto 0);
    variable rs1_is_r0_v     : std_ulogic;
    variable rs1_is_r0_v     : std_ulogic;
  begin
  begin
Line 742... Line 761...
            end if;
            end if;
            execute_engine.state_nxt <= SYS_WAIT;
            execute_engine.state_nxt <= SYS_WAIT;
 
 
          when opcode_syscsr_c => -- system/csr access
          when opcode_syscsr_c => -- system/csr access
          -- ------------------------------------------------------------
          -- ------------------------------------------------------------
            csr.re_nxt <= '1'; -- always read CSR - regardless of actual operation
            csr.re_nxt <= csr_acc_valid; -- read CSR if valid access
            if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system
            if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system
              case execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is
              case execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is
                when funct12_ecall_c => -- ECALL
                when funct12_ecall_c => -- ECALL
                  trap_ctrl.env_call <= '1';
                  trap_ctrl.env_call <= '1';
                when funct12_ebreak_c => -- EBREAK
                when funct12_ebreak_c => -- EBREAK
Line 783... Line 802...
          when funct3_csrrw_c => -- CSRRW
          when funct3_csrrw_c => -- CSRRW
            ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1
            ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1
            ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '0'; -- OPB = rs2
            ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '0'; -- OPB = rs2
            ctrl_nxt(ctrl_rf_clear_rs2_c)    <= '1'; -- rs2 = 0
            ctrl_nxt(ctrl_rf_clear_rs2_c)    <= '1'; -- rs2 = 0
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR
            csr.we_nxt <= '1'; -- always write CSR
            csr.we_nxt <= csr_acc_valid; -- always write CSR if valid access
          when funct3_csrrs_c => -- CSRRS
          when funct3_csrrs_c => -- CSRRS
            ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
            ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
            ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '1'; -- OPB = rs1
            ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '1'; -- OPB = rs1
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR
            csr.we_nxt <= not rs1_is_r0_v; -- write CSR if rs1 is not zero_reg
            csr.we_nxt <= (not rs1_is_r0_v) and csr_acc_valid; -- write CSR if rs1 is not zero_reg and if valid access
          when funct3_csrrc_c => -- CSRRC
          when funct3_csrrc_c => -- CSRRC
            ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
            ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
            ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '1'; -- OPB = rs1
            ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '1'; -- OPB = rs1
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear
            csr.we_nxt <= not rs1_is_r0_v; -- write CSR if rs1 is not zero_reg
            csr.we_nxt <= (not rs1_is_r0_v) and csr_acc_valid; -- write CSR if rs1 is not zero_reg and if valid access
          -- immediate operations --
          -- immediate operations --
          when funct3_csrrwi_c => -- CSRRWI
          when funct3_csrrwi_c => -- CSRRWI
            ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1
            ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1
            ctrl_nxt(ctrl_rf_clear_rs1_c)    <= '1'; -- rs1 = 0
            ctrl_nxt(ctrl_rf_clear_rs1_c)    <= '1'; -- rs1 = 0
            ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
            ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR
            csr.we_nxt <= '1'; -- always write CSR
            csr.we_nxt <= csr_acc_valid; -- always write CSR if valid access
          when funct3_csrrsi_c => -- CSRRSI
          when funct3_csrrsi_c => -- CSRRSI
            ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
            ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
            ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
            ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR
            csr.we_nxt <= not rs1_is_r0_v; -- write CSR if UIMM5 is not zero (bits from rs1 filed)
            csr.we_nxt <= (not rs1_is_r0_v) and csr_acc_valid; -- write CSR if UIMM5 is not zero (bits from rs1 filed) and if valid access
          when funct3_csrrci_c => -- CSRRCI
          when funct3_csrrci_c => -- CSRRCI
            ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
            ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
            ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
            ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear
            ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear
            csr.we_nxt <= not rs1_is_r0_v; -- write CSR if UIMM5 is not zero (bits from rs1 filed)
            csr.we_nxt <= (not rs1_is_r0_v) and csr_acc_valid; -- write CSR if UIMM5 is not zero (bits from rs1 filed) and if valid access
          when others => -- undefined
          when others => -- undefined
            NULL;
            NULL;
        end case;
        end case;
        -- RF write back --
        -- RF write back --
        ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "11"; -- RF input = CSR output
        ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "11"; -- RF input = CSR output
Line 873... Line 892...
 
 
    end case;
    end case;
  end process execute_engine_fsm_comb;
  end process execute_engine_fsm_comb;
 
 
 
 
 
-- ****************************************************************************************************************************
 
-- Invalid Instruction / CSR access check
 
-- ****************************************************************************************************************************
 
 
 
 
 
  -- Illegal CSR Access Check ---------------------------------------------------------------
 
  -- -------------------------------------------------------------------------------------------
 
  invalid_csr_access_check: process(execute_engine, csr)
 
    variable is_m_mode_v : std_ulogic;
 
  begin
 
    -- are we in machine mode? --
 
    is_m_mode_v := '0';
 
    if (csr.privilege = m_priv_mode_c) then
 
      is_m_mode_v := '1';
 
    end if;
 
 
 
    -- check CSR access --
 
    csr_acc_valid <= '0'; -- default
 
    case execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is
 
      when x"300" => csr_acc_valid <= is_m_mode_v; -- mstatus
 
      when x"301" => csr_acc_valid <= is_m_mode_v; -- misa
 
      when x"304" => csr_acc_valid <= is_m_mode_v; -- mie
 
      when x"305" => csr_acc_valid <= is_m_mode_v; -- mtvev
 
      when x"340" => csr_acc_valid <= is_m_mode_v; -- mscratch
 
      when x"341" => csr_acc_valid <= is_m_mode_v; -- mepc
 
      when x"342" => csr_acc_valid <= is_m_mode_v; -- mcause
 
      when x"343" => csr_acc_valid <= is_m_mode_v; -- mtval
 
      when x"344" => csr_acc_valid <= is_m_mode_v; -- mip
 
      --
 
      when x"3a0" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >=  1)) and is_m_mode_v; -- pmpacfg0
 
      when x"3a1" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >=  5)) and is_m_mode_v; -- pmpacfg1
 
      --
 
      when x"3b0" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >=  1)) and is_m_mode_v; -- pmpaddr0
 
      when x"3b1" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >=  2)) and is_m_mode_v; -- pmpaddr1
 
      when x"3b2" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >=  3)) and is_m_mode_v; -- pmpaddr2
 
      when x"3b3" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >=  4)) and is_m_mode_v; -- pmpaddr3
 
      when x"3b4" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >=  5)) and is_m_mode_v; -- pmpaddr4
 
      when x"3b5" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >=  6)) and is_m_mode_v; -- pmpaddr5
 
      when x"3b6" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >=  7)) and is_m_mode_v; -- pmpaddr6
 
      when x"3b7" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >=  8)) and is_m_mode_v; -- pmpaddr7
 
      --
 
      when x"c00" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- cycle
 
      when x"c01" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- time
 
      when x"c02" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- instret
 
      when x"c80" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- cycleh
 
      when x"c81" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- timeh
 
      when x"c82" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- instreth
 
      --
 
      when x"b00" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE) and is_m_mode_v; -- mcycle
 
      when x"b02" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE) and is_m_mode_v; -- minstret
 
      when x"b80" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE) and is_m_mode_v; -- mcycleh
 
      when x"b82" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE) and is_m_mode_v; -- minstreth
 
      --
 
      when x"f11" => csr_acc_valid <= is_m_mode_v; -- mvendorid
 
      when x"f12" => csr_acc_valid <= is_m_mode_v; -- marchid
 
      when x"f13" => csr_acc_valid <= is_m_mode_v; -- mimpid
 
      when x"f14" => csr_acc_valid <= is_m_mode_v; -- mhartid
 
      --
 
      when others => csr_acc_valid <= '0'; -- undefined
 
    end case;
 
  end process invalid_csr_access_check;
 
 
 
 
  -- Illegal Instruction Check --------------------------------------------------------------
  -- Illegal Instruction Check --------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  illegal_instruction_check: process(execute_engine, csr, ctrl_nxt)
  illegal_instruction_check: process(execute_engine, csr, ctrl_nxt, csr_acc_valid)
  begin
  begin
    -- illegal instructions are checked in the EXECUTE stage
    -- illegal instructions are checked in the EXECUTE stage
    -- the execute engine will only commit valid instructions
    -- the execute engine will only commit valid instructions
    if (execute_engine.state = EXECUTE) then
    if (execute_engine.state = EXECUTE) then
      -- defaults --
      -- defaults --
Line 979... Line 1061...
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrs_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrs_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrc_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrc_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrsi_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrsi_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrci_c) then
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrci_c) then
            -- valid CSR? --
            -- valid CSR access? --
            if (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"300") or -- mstatus
            if (csr_acc_valid = '1') then
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"301") or -- misa
 
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"304") or -- mie
 
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"305") or -- mtvev
 
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"340") or -- mscratch
 
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"341") or -- mepc
 
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"342") or -- mcause
 
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"343") or -- mtval
 
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"344") or -- mip
 
               --
 
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c00") and (CSR_COUNTERS_USE = true)) or -- cycle
 
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c01") and (CSR_COUNTERS_USE = true)) or -- time
 
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c02") and (CSR_COUNTERS_USE = true)) or -- instret
 
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c80") and (CSR_COUNTERS_USE = true)) or -- cycleh
 
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c81") and (CSR_COUNTERS_USE = true)) or -- timeh
 
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c82") and (CSR_COUNTERS_USE = true)) or -- instreth
 
               --
 
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b00") and (CSR_COUNTERS_USE = true)) or -- mcycle
 
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b02") and (CSR_COUNTERS_USE = true)) or -- minstret
 
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b80") and (CSR_COUNTERS_USE = true)) or -- mcycleh
 
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b82") and (CSR_COUNTERS_USE = true)) or -- minstreth
 
               --
 
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f11") or -- mvendorid
 
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f12") or -- marchid
 
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f13") or -- mimpid
 
               (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f14") then -- mhartid
 
              illegal_instruction <= '0';
              illegal_instruction <= '0';
            else
            else
              illegal_instruction <= '1';
              illegal_instruction <= '1';
            end if;
            end if;
 
 
Line 1228... Line 1285...
      csr.mtvec        <= (others => '0');
      csr.mtvec        <= (others => '0');
      csr.mscratch     <= (others => '0');
      csr.mscratch     <= (others => '0');
      csr.mepc         <= (others => '0');
      csr.mepc         <= (others => '0');
      csr.mcause       <= (others => '0');
      csr.mcause       <= (others => '0');
      csr.mtval        <= (others => '0');
      csr.mtval        <= (others => '0');
 
      csr.mpp          <= m_priv_mode_c; -- start in MACHINE mode
 
      csr.privilege    <= m_priv_mode_c; -- start in MACHINE mode
 
      csr.pmpcfg       <= (others => (others => '0'));
 
      csr.pmpaddr      <= (others => (others => '0'));
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      if (CPU_EXTENSION_RISCV_Zicsr = true) then
      if (CPU_EXTENSION_RISCV_Zicsr = true) then
        -- access --
        -- access --
        csr.we <= csr.we_nxt;
        csr.we <= csr.we_nxt;
        csr.re <= csr.re_nxt;
        csr.re <= csr.re_nxt;
 
 
        -- registers that can be modified by user --
        -- registers that can be modified by user --
        if (csr.we = '1') then -- manual update
        if (csr.we = '1') then -- manual update
 
 
          -- Machine CSRs: Standard read/write
          -- Machine CSRs --
          if (execute_engine.i_reg(31 downto 28) = x"3") then
          if (execute_engine.i_reg(31 downto 28) = x"3") then
            -- machine trap setup --
            -- machine trap setup --
            if (execute_engine.i_reg(27 downto 24) = x"0") then
            if (execute_engine.i_reg(27 downto 24) = x"0") then
              case execute_engine.i_reg(23 downto 20) is
              case execute_engine.i_reg(23 downto 20) is
                when x"0" => -- R/W: mstatus - machine status register
                when x"0" => -- R/W: mstatus - machine status register
                  csr.mstatus_mie  <= csr_wdata_i(03);
                  csr.mstatus_mie  <= csr_wdata_i(03);
                  csr.mstatus_mpie <= csr_wdata_i(07);
                  csr.mstatus_mpie <= csr_wdata_i(07);
 
                  --
 
                  if (CPU_EXTENSION_RISCV_U = true) then -- user mode implemented
 
                    csr.mpp(0) <= csr_wdata_i(11) and csr_wdata_i(12);
 
                    csr.mpp(1) <= csr_wdata_i(11) and csr_wdata_i(12);
 
                  end if;
                when x"4" => -- R/W: mie - machine interrupt-enable register
                when x"4" => -- R/W: mie - machine interrupt-enable register
                  csr.mie_msie <= csr_wdata_i(03); -- machine SW IRQ enable
                  csr.mie_msie <= csr_wdata_i(03); -- machine SW IRQ enable
                  csr.mie_mtie <= csr_wdata_i(07); -- machine TIMER IRQ enable
                  csr.mie_mtie <= csr_wdata_i(07); -- machine TIMER IRQ enable
                  csr.mie_meie <= csr_wdata_i(11); -- machine EXT IRQ enable
                  csr.mie_meie <= csr_wdata_i(11); -- machine EXT IRQ enable
                  --
                  --
Line 1273... Line 1339...
                  csr.mtval <= csr_wdata_i;
                  csr.mtval <= csr_wdata_i;
                when others =>
                when others =>
                  NULL;
                  NULL;
              end case;
              end case;
            end if;
            end if;
 
            -- machine physical memory protection (pmp) --
 
            if (PMP_USE = true) then
 
              -- pmpcfg --
 
              if (execute_engine.i_reg(27 downto 24) = x"a") then
 
                if (PMP_NUM_REGIONS >= 1) then
 
                  if (execute_engine.i_reg(23 downto 20) = x"0") then -- pmpcfg0
 
                    for j in 0 to 3 loop -- bytes in pmpcfg CSR
 
                      if ((j+1) <= PMP_NUM_REGIONS) then
 
                        if (csr.pmpcfg(0+j)(7) = '0') then -- unlocked pmpcfg access
 
                          csr.pmpcfg(0+j)(0) <= csr_wdata_i(j*8+0); -- R
 
                          csr.pmpcfg(0+j)(1) <= csr_wdata_i(j*8+1); -- W
 
                          csr.pmpcfg(0+j)(2) <= csr_wdata_i(j*8+2); -- X
 
                          csr.pmpcfg(0+j)(3) <= csr_wdata_i(j*8+3) and csr_wdata_i(j*8+4); -- A_L
 
                          csr.pmpcfg(0+j)(4) <= csr_wdata_i(j*8+3) and csr_wdata_i(j*8+4); -- A_H - NAPOT/OFF only
 
                          csr.pmpcfg(0+j)(5) <= '0'; -- reserved
 
                          csr.pmpcfg(0+j)(6) <= '0'; -- reserved
 
                          csr.pmpcfg(0+j)(7) <= csr_wdata_i(j*8+7); -- L
 
                        end if;
 
                      end if;
 
                    end loop; -- j (bytes in CSR)
 
                  end if;
 
                end if;
 
                if (PMP_NUM_REGIONS >= 5) then
 
                  if (execute_engine.i_reg(23 downto 20) = x"1") then -- pmpcfg1
 
                    for j in 0 to 3 loop -- bytes in pmpcfg CSR
 
                      if ((j+1+4) <= PMP_NUM_REGIONS) then
 
                        if (csr.pmpcfg(4+j)(7) = '0') then -- unlocked pmpcfg access
 
                          csr.pmpcfg(4+j)(0) <= csr_wdata_i(j*8+0); -- R
 
                          csr.pmpcfg(4+j)(1) <= csr_wdata_i(j*8+1); -- W
 
                          csr.pmpcfg(4+j)(2) <= csr_wdata_i(j*8+2); -- X
 
                          csr.pmpcfg(4+j)(3) <= csr_wdata_i(j*8+3) and csr_wdata_i(j*8+4); -- A_L
 
                          csr.pmpcfg(4+j)(4) <= csr_wdata_i(j*8+3) and csr_wdata_i(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_i(j*8+7); -- L
 
                        end if;
 
                      end if;
 
                    end loop; -- j (bytes in CSR)
 
                  end if;
 
                end if;
 
              end if;
 
              -- pmpaddr --
 
              if (execute_engine.i_reg(27 downto 24) = x"b") then
 
                for i in 0 to PMP_NUM_REGIONS-1 loop
 
                  if (execute_engine.i_reg(23 downto 20) = std_ulogic_vector(to_unsigned(i, 4))) and (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpaddr access
 
                    csr.pmpaddr(i) <= csr_wdata_i;
 
                  end if;
 
                end loop; -- i (CSRs)
 
              end if;
 
            end if; -- implement PMP at all?
          end if;
          end if;
 
 
        -- automatic update by hardware --
        -- automatic update by hardware --
        else
        else
 
 
Line 1300... Line 1416...
              end if;
              end if;
            end if;
            end if;
          end if;
          end if;
 
 
          -- context switch in mstatus --
          -- context switch in mstatus --
          if (trap_ctrl.env_start_ack = '1') then -- trap handler starting?
          if (trap_ctrl.env_start_ack = '1') then -- ENTER: trap handler starting?
            csr.mstatus_mie <= '0';
            csr.mstatus_mie  <= '0'; -- disable interrupts
            if (csr.mstatus_mpie = '0') then -- prevent loosing the prev MIE state in nested traps
            csr.mstatus_mpie <= csr.mstatus_mie; -- buffer previous mie state
              csr.mstatus_mpie <= csr.mstatus_mie;
            if (CPU_EXTENSION_RISCV_U = true) then -- implement user mode
 
              csr.privilege <= m_priv_mode_c; -- execute trap in machine mode
 
              csr.mpp       <= csr.privilege; -- buffer previous privilege mode
 
            end if;
 
          elsif (trap_ctrl.env_end = '1') then -- EXIT: return from exception
 
            csr.mstatus_mie  <= csr.mstatus_mpie; -- restore global IRQ enable flag
 
            csr.mstatus_mpie <= '1';
 
            if (CPU_EXTENSION_RISCV_U = true) then -- implement user mode
 
              csr.privilege <= csr.mpp; -- go back to previous privilege mode
 
              csr.mpp       <= u_priv_mode_c;
            end if;
            end if;
          elsif (trap_ctrl.env_end = '1') then -- return from exception
 
            csr.mstatus_mie <= csr.mstatus_mpie;
 
          end if;
          end if;
 
 
 
          -- user mode NOT implemented --
 
          if (CPU_EXTENSION_RISCV_U = false) then -- implement user mode
 
            csr.privilege <= m_priv_mode_c;
 
            csr.mpp       <= m_priv_mode_c;
 
          end if;
        end if;
        end if;
      end if;
      end if;
    end if;
    end if;
  end process csr_write_access;
  end process csr_write_access;
 
 
Line 1328... Line 1456...
 
 
          -- machine trap setup --
          -- machine trap setup --
          when x"300" => -- R/W: mstatus - machine status register
          when x"300" => -- R/W: mstatus - machine status register
            csr_rdata_o(03) <= csr.mstatus_mie; -- MIE
            csr_rdata_o(03) <= csr.mstatus_mie; -- MIE
            csr_rdata_o(07) <= csr.mstatus_mpie; -- MPIE
            csr_rdata_o(07) <= csr.mstatus_mpie; -- MPIE
            csr_rdata_o(11) <= '1'; -- MPP low - M-mode
            csr_rdata_o(11) <= csr.mpp(0); -- MPP: machine previous privilege mode low
            csr_rdata_o(12) <= '1'; -- MPP high - M-mode
            csr_rdata_o(12) <= csr.mpp(1); -- MPP: machine previous privilege mode high
          when x"301" => -- R/-: misa - ISA and extensions
          when x"301" => -- R/-: misa - ISA and extensions
            csr_rdata_o(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C);     -- C CPU extension
            csr_rdata_o(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C);     -- C CPU extension
            csr_rdata_o(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E);     -- E CPU extension
            csr_rdata_o(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E);     -- E CPU extension
            csr_rdata_o(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
            csr_rdata_o(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
            csr_rdata_o(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M);     -- M CPU extension
            csr_rdata_o(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M);     -- M CPU extension
 
            csr_rdata_o(20) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U);     -- U CPU extension
            csr_rdata_o(23) <= '1';                                         -- X CPU extension (non-std extensions)
            csr_rdata_o(23) <= '1';                                         -- X CPU extension (non-std extensions)
            csr_rdata_o(25) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr) and bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Z CPU extension
            csr_rdata_o(25) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr) and bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Z CPU extension
            csr_rdata_o(30) <= '1'; -- 32-bit architecture (MXL lo)
            csr_rdata_o(30) <= '1'; -- 32-bit architecture (MXL lo)
            csr_rdata_o(31) <= '0'; -- 32-bit architecture (MXL hi)
            csr_rdata_o(31) <= '0'; -- 32-bit architecture (MXL hi)
          when x"304" => -- R/W: mie - machine interrupt-enable register
          when x"304" => -- R/W: mie - machine interrupt-enable register
Line 1370... Line 1499...
            csr_rdata_o(16) <= trap_ctrl.irq_buf(interrupt_firq_0_c);
            csr_rdata_o(16) <= trap_ctrl.irq_buf(interrupt_firq_0_c);
            csr_rdata_o(17) <= trap_ctrl.irq_buf(interrupt_firq_1_c);
            csr_rdata_o(17) <= trap_ctrl.irq_buf(interrupt_firq_1_c);
            csr_rdata_o(18) <= trap_ctrl.irq_buf(interrupt_firq_2_c);
            csr_rdata_o(18) <= trap_ctrl.irq_buf(interrupt_firq_2_c);
            csr_rdata_o(19) <= trap_ctrl.irq_buf(interrupt_firq_3_c);
            csr_rdata_o(19) <= trap_ctrl.irq_buf(interrupt_firq_3_c);
 
 
 
          -- physical memory protection --
 
          when x"3a0" => -- R/W: pmpcfg0 - physical memory protection configuration register 0
 
            if (PMP_USE = true) then
 
              if (PMP_NUM_REGIONS >= 1) then
 
                csr_rdata_o(07 downto 00) <= csr.pmpcfg(0);
 
              end if;
 
              if (PMP_NUM_REGIONS >= 2) then
 
                csr_rdata_o(15 downto 08) <= csr.pmpcfg(1);
 
              end if;
 
              if (PMP_NUM_REGIONS >= 3) then
 
                csr_rdata_o(23 downto 16) <= csr.pmpcfg(2);
 
              end if;
 
              if (PMP_NUM_REGIONS >= 4) then
 
                csr_rdata_o(31 downto 24) <= csr.pmpcfg(3);
 
              end if;
 
            end if;
 
          when x"3a1" => -- R/W: pmpcfg1 - physical memory protection configuration register 1
 
            if (PMP_USE = true) then
 
              if (PMP_NUM_REGIONS >= 5) then
 
                csr_rdata_o(07 downto 00) <= csr.pmpcfg(4);
 
              end if;
 
              if (PMP_NUM_REGIONS >= 6) then
 
                csr_rdata_o(15 downto 08) <= csr.pmpcfg(5);
 
              end if;
 
              if (PMP_NUM_REGIONS >= 7) then
 
                csr_rdata_o(23 downto 16) <= csr.pmpcfg(6);
 
              end if;
 
              if (PMP_NUM_REGIONS >= 8) then
 
                csr_rdata_o(31 downto 24) <= csr.pmpcfg(7);
 
              end if;
 
            end if;
 
 
 
          when x"3b0" => -- R/W: pmpaddr0 - physical memory protection address register 0
 
            if (PMP_USE = true) and (PMP_NUM_REGIONS >= 1) then
 
              csr_rdata_o <= pmp_maddr_i(0)(33 downto 2);
 
              if (csr.pmpcfg(0)(4 downto 3) = "00") then -- mode = off
 
                csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
 
              else -- mode = NAPOT
 
                csr_rdata_o(PMP_GRANULARITY-2 downto 0) <= (others => '1');
 
              end if;
 
            end if;
 
          when x"3b1" => -- R/W: pmpaddr1 - physical memory protection address register 1
 
            if (PMP_USE = true) and (PMP_NUM_REGIONS >= 2) then
 
              csr_rdata_o <= pmp_maddr_i(1)(33 downto 2);
 
              if (csr.pmpcfg(1)(4 downto 3) = "00") then -- mode = off
 
                csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
 
              else -- mode = NAPOT
 
                csr_rdata_o(PMP_GRANULARITY-2 downto 0) <= (others => '1');
 
              end if;
 
            end if;
 
          when x"3b2" => -- R/W: pmpaddr2 - physical memory protection address register 2
 
            if (PMP_USE = true) and (PMP_NUM_REGIONS >= 3) then
 
              csr_rdata_o <= pmp_maddr_i(2)(33 downto 2);
 
              if (csr.pmpcfg(2)(4 downto 3) = "00") then -- mode = off
 
                csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
 
              else -- mode = NAPOT
 
                csr_rdata_o(PMP_GRANULARITY-2 downto 0) <= (others => '1');
 
              end if;
 
            end if;
 
          when x"3b3" => -- R/W: pmpaddr3 - physical memory protection address register 3
 
            if (PMP_USE = true) and (PMP_NUM_REGIONS >= 4) then
 
              csr_rdata_o <= pmp_maddr_i(3)(33 downto 2);
 
              if (csr.pmpcfg(3)(4 downto 3) = "00") then -- mode = off
 
                csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
 
              else -- mode = NAPOT
 
                csr_rdata_o(PMP_GRANULARITY-2 downto 0) <= (others => '1');
 
              end if;
 
            end if;
 
          when x"3b4" => -- R/W: pmpaddr4 - physical memory protection address register 4
 
            if (PMP_USE = true) and (PMP_NUM_REGIONS >= 5) then
 
              csr_rdata_o <= pmp_maddr_i(4)(33 downto 2);
 
              if (csr.pmpcfg(4)(4 downto 3) = "00") then -- mode = off
 
                csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
 
              else -- mode = NAPOT
 
                csr_rdata_o(PMP_GRANULARITY-2 downto 0) <= (others => '1');
 
              end if;
 
            end if;
 
          when x"3b5" => -- R/W: pmpaddr5 - physical memory protection address register 5
 
            if (PMP_USE = true) and (PMP_NUM_REGIONS >= 6) then
 
              csr_rdata_o <= pmp_maddr_i(5)(33 downto 2);
 
              if (csr.pmpcfg(5)(4 downto 3) = "00") then -- mode = off
 
                csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
 
              else -- mode = NAPOT
 
                csr_rdata_o(PMP_GRANULARITY-2 downto 0) <= (others => '1');
 
              end if;
 
            end if;
 
          when x"3b6" => -- R/W: pmpaddr6 - physical memory protection address register 6
 
            if (PMP_USE = true) and (PMP_NUM_REGIONS >= 7) then
 
              csr_rdata_o <= pmp_maddr_i(6)(33 downto 2);
 
              if (csr.pmpcfg(6)(4 downto 3) = "00") then -- mode = off
 
                csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
 
              else -- mode = NAPOT
 
                csr_rdata_o(PMP_GRANULARITY-2 downto 0) <= (others => '1');
 
              end if;
 
            end if;
 
          when x"3b7" => -- R/W: pmpaddr7 - physical memory protection address register 7
 
            if (PMP_USE = true) and (PMP_NUM_REGIONS >= 8) then
 
              csr_rdata_o <= pmp_maddr_i(7)(33 downto 2);
 
              if (csr.pmpcfg(7)(4 downto 3) = "00") then -- mode = off
 
                csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
 
              else -- mode = NAPOT
 
                csr_rdata_o(PMP_GRANULARITY-2 downto 0) <= (others => '1');
 
              end if;
 
            end if;
 
 
          -- counter and timers --
          -- counter and timers --
          when x"c00" | x"b00" => -- R/(W): cycle/mcycle: Cycle counter LOW
          when x"c00" | x"b00" => -- R/(W): cycle/mcycle: Cycle counter LOW
            csr_rdata_o <= csr.mcycle(31 downto 0);
            csr_rdata_o <= csr.mcycle(31 downto 0);
          when x"c01" => -- R/-: time: System time LOW (from MTIME unit)
          when x"c01" => -- R/-: time: System time LOW (from MTIME unit)
            csr_rdata_o <= systime(31 downto 0);
            csr_rdata_o <= systime(31 downto 0);
Line 1408... Line 1642...
  end process csr_read_access;
  end process csr_read_access;
 
 
  -- time[h] CSR --
  -- time[h] CSR --
  systime <= time_i when (CSR_COUNTERS_USE = true) else (others => '0');
  systime <= time_i when (CSR_COUNTERS_USE = true) else (others => '0');
 
 
 
  -- CPU's current privilege level --
 
  priv_mode_o <= csr.privilege;
 
 
 
  -- PMP output --
 
  pmp_output: process(csr)
 
  begin
 
    pmp_addr_o <= (others => (others => '0'));
 
    pmp_ctrl_o <= (others => (others => '0'));
 
    if (PMP_USE = true) then
 
      for i in 0 to PMP_NUM_REGIONS-1 loop
 
        pmp_addr_o(i) <= csr.pmpaddr(i) & "00";
 
        pmp_ctrl_o(i) <= csr.pmpcfg(i);
 
      end loop; -- i
 
    end if;
 
  end process pmp_output;
 
 
 
 
  -- RISC-V Counter CSRs --------------------------------------------------------------------
  -- RISC-V Counter CSRs --------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  csr_counters: process(rstn_i, clk_i)
  csr_counters: process(rstn_i, clk_i)
  begin
  begin

powered by: WebSVN 2.1.0

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