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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_control.vhd] - Diff between revs 51 and 52

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

Rev 51 Rev 52
Line 53... Line 53...
    -- RISC-V CPU Extensions --
    -- RISC-V CPU Extensions --
    CPU_EXTENSION_RISCV_A        : boolean := false; -- implement atomic extension?
    CPU_EXTENSION_RISCV_A        : boolean := false; -- implement atomic extension?
    CPU_EXTENSION_RISCV_B        : boolean := false; -- implement bit manipulation extensions?
    CPU_EXTENSION_RISCV_B        : boolean := false; -- implement bit manipulation 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_F        : boolean := false; -- implement 32-bit floating-point 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_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 := false; -- implement instruction stream sync.?
    CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
    -- Physical memory protection (PMP) --
    -- Physical memory protection (PMP) --
Line 82... Line 83...
    -- data output --
    -- data output --
    imm_o         : out std_ulogic_vector(data_width_c-1 downto 0); -- immediate
    imm_o         : out std_ulogic_vector(data_width_c-1 downto 0); -- immediate
    fetch_pc_o    : out std_ulogic_vector(data_width_c-1 downto 0); -- PC for instruction fetch
    fetch_pc_o    : out std_ulogic_vector(data_width_c-1 downto 0); -- PC for instruction fetch
    curr_pc_o     : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC (corresponding to current instruction)
    curr_pc_o     : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC (corresponding to current instruction)
    csr_rdata_o   : out std_ulogic_vector(data_width_c-1 downto 0); -- CSR read data
    csr_rdata_o   : out std_ulogic_vector(data_width_c-1 downto 0); -- CSR read data
 
    -- FPU interface --
 
    fpu_rm_o      : out std_ulogic_vector(02 downto 0); -- rounding mode
 
    fpu_flags_i   : in  std_ulogic_vector(04 downto 0); -- exception flags
    -- interrupts (risc-v compliant) --
    -- interrupts (risc-v compliant) --
    msw_irq_i     : in  std_ulogic; -- machine software interrupt
    msw_irq_i     : in  std_ulogic; -- machine software interrupt
    mext_irq_i    : in  std_ulogic; -- machine external interrupt
    mext_irq_i    : in  std_ulogic; -- machine external interrupt
    mtime_irq_i   : in  std_ulogic; -- machine timer interrupt
    mtime_irq_i   : in  std_ulogic; -- machine timer interrupt
    -- fast interrupts (custom) --
    -- fast interrupts (custom) --
Line 174... Line 178...
    rs1_is_r0       : std_ulogic;
    rs1_is_r0       : std_ulogic;
    is_atomic_lr    : std_ulogic;
    is_atomic_lr    : std_ulogic;
    is_atomic_sc    : std_ulogic;
    is_atomic_sc    : std_ulogic;
    is_bitmanip_imm : std_ulogic;
    is_bitmanip_imm : std_ulogic;
    is_bitmanip_reg : std_ulogic;
    is_bitmanip_reg : std_ulogic;
 
    is_float_f_reg  : std_ulogic;
 
    is_float_i_reg  : std_ulogic;
    sys_env_cmd     : std_ulogic_vector(11 downto 0);
    sys_env_cmd     : std_ulogic_vector(11 downto 0);
  end record;
  end record;
  signal decode_aux : decode_aux_t;
  signal decode_aux : decode_aux_t;
 
 
  -- instruction execution engine --
  -- instruction execution engine --
Line 194... Line 200...
    --
    --
    is_ci        : std_ulogic; -- current instruction is de-compressed instruction
    is_ci        : std_ulogic; -- current instruction is de-compressed instruction
    is_ci_nxt    : std_ulogic;
    is_ci_nxt    : std_ulogic;
    is_cp_op     : std_ulogic; -- current instruction is a co-processor operation
    is_cp_op     : std_ulogic; -- current instruction is a co-processor operation
    is_cp_op_nxt : std_ulogic;
    is_cp_op_nxt : std_ulogic;
 
    is_fp        : std_ulogic; -- floating-point operation - do not access to integer register file
 
    is_fp_nxt    : std_ulogic;
    --
    --
    branch_taken : std_ulogic; -- branch condition fullfilled
    branch_taken : std_ulogic; -- branch condition fullfilled
    pc           : std_ulogic_vector(data_width_c-1 downto 0); -- actual PC, corresponding to current executed instruction
    pc           : std_ulogic_vector(data_width_c-1 downto 0); -- actual PC, corresponding to current executed instruction
    pc_mux_sel   : std_ulogic; -- source select for PC update
    pc_mux_sel   : std_ulogic; -- source select for PC update
    pc_we        : std_ulogic; -- PC update enabled
    pc_we        : std_ulogic; -- PC update enabled
Line 320... Line 328...
    --
    --
    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
    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
    pmpaddr_rd        : pmp_addr_rd_t; -- physical memory protection - actual read data
 
    --
 
    frm               : std_ulogic_vector(02 downto 0); -- frm (R/W): FPU rounding mode
 
    fflags            : std_ulogic_vector(04 downto 0); -- fflags (R/W): FPU exception flags
  end record;
  end record;
  signal csr : csr_t;
  signal csr : csr_t;
 
 
  -- counter low-to-high-word carry --
  -- counter low-to-high-word carry --
  signal mcycle_msb      : std_ulogic;
  signal mcycle_msb      : std_ulogic;
Line 604... Line 615...
    if rising_edge(clk_i) then
    if rising_edge(clk_i) then
      if (execute_engine.state = BRANCH) then -- next_PC as immediate for jump-and-link operations (=return address) via ALU.MOV_B
      if (execute_engine.state = BRANCH) then -- next_PC as immediate for jump-and-link operations (=return address) via ALU.MOV_B
        imm_o <= execute_engine.next_pc;
        imm_o <= execute_engine.next_pc;
      else -- "normal" immediate from instruction word
      else -- "normal" immediate from instruction word
        case opcode_v is -- save some bits here, the two LSBs are always "11" for rv32
        case opcode_v is -- save some bits here, the two LSBs are always "11" for rv32
          when opcode_store_c => -- S-immediate
          when opcode_store_c | opcode_fsw_c => -- S-immediate
            imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
            imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
            imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
            imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
            imm_o(04 downto 01) <= execute_engine.i_reg(11 downto 08);
            imm_o(04 downto 01) <= execute_engine.i_reg(11 downto 08);
            imm_o(00)           <= execute_engine.i_reg(07);
            imm_o(00)           <= execute_engine.i_reg(07);
          when opcode_branch_c => -- B-immediate
          when opcode_branch_c => -- B-immediate
Line 693... Line 704...
    if rising_edge(clk_i) then
    if rising_edge(clk_i) then
      execute_engine.state_prev <= execute_engine.state;
      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;
 
      execute_engine.is_fp      <= execute_engine.is_fp_nxt;
      -- PC & IR of "last executed" instruction --
      -- PC & IR of "last executed" instruction --
      if (execute_engine.state = EXECUTE) then
      if (execute_engine.state = EXECUTE) then
        execute_engine.last_pc    <= execute_engine.pc;
        execute_engine.last_pc    <= execute_engine.pc;
        execute_engine.i_reg_last <= execute_engine.i_reg;
        execute_engine.i_reg_last <= execute_engine.i_reg;
      end if;
      end if;
Line 766... Line 778...
    decode_aux.rs1_is_r0       <= '0';
    decode_aux.rs1_is_r0       <= '0';
    decode_aux.is_atomic_lr    <= '0';
    decode_aux.is_atomic_lr    <= '0';
    decode_aux.is_atomic_sc    <= '0';
    decode_aux.is_atomic_sc    <= '0';
    decode_aux.is_bitmanip_imm <= '0';
    decode_aux.is_bitmanip_imm <= '0';
    decode_aux.is_bitmanip_reg <= '0';
    decode_aux.is_bitmanip_reg <= '0';
 
    decode_aux.is_float_f_reg  <= '0';
 
    decode_aux.is_float_i_reg  <= '0';
 
 
    -- is immediate ALU operation? --
    -- is immediate ALU operation? --
    decode_aux.alu_immediate <= not execute_engine.i_reg(instr_opcode_msb_c-1);
    decode_aux.alu_immediate <= not execute_engine.i_reg(instr_opcode_msb_c-1);
 
 
    -- is rs1 == r0? --
    -- is rs1 == r0? --
    decode_aux.rs1_is_r0 <= not or_all_f(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c));
    decode_aux.rs1_is_r0 <= not or_all_f(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c));
 
 
    -- is atomic load-reservate/store-conditional? --
    -- is atomic load-reservate/store-conditional? --
    if (CPU_EXTENSION_RISCV_A = true) and (execute_engine.i_reg(instr_opcode_lsb_c+2) = '1') then -- valid atomic sub-opcode
    if (CPU_EXTENSION_RISCV_A = true) and (execute_engine.i_reg(instr_opcode_lsb_c+3 downto instr_opcode_lsb_c+2) = "11") then -- valid atomic sub-opcode
      decode_aux.is_atomic_lr <= not execute_engine.i_reg(instr_funct5_lsb_c);
      decode_aux.is_atomic_lr <= not execute_engine.i_reg(instr_funct5_lsb_c);
      decode_aux.is_atomic_sc <=     execute_engine.i_reg(instr_funct5_lsb_c);
      decode_aux.is_atomic_sc <=     execute_engine.i_reg(instr_funct5_lsb_c);
    end if;
    end if;
 
 
    -- is BITMANIP instruction? --
    -- is BITMANIP instruction? --
Line 818... Line 832...
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0010100") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "001")) or -- SBSET
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0010100") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "001")) or -- SBSET
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0110100") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "001")) or -- SBINV
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0110100") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "001")) or -- SBINV
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0100100") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "101")) then -- SBSEXT
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0100100") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "101")) then -- SBSEXT
      decode_aux.is_bitmanip_reg <= '1';
      decode_aux.is_bitmanip_reg <= '1';
    end if;
    end if;
 
 
 
    -- floating-point FLOAT_register operations --
 
    if ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "11110")) or -- FMV.W.X
 
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "00000")) or -- FADD.S
 
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "00001")) or -- FSUB.S
 
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "00010")) or -- FMUL.S
 
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "00011")) or -- FDIV.S
 
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "01011") and (execute_engine.i_reg(instr_funct12_lsb_c+4 downto instr_funct12_lsb_c) = "00000")) or -- FSQRT.S
 
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "00100") and (execute_engine.i_reg(instr_funct3_msb_c) = '0')) or -- FSGNJ[N/X].S
 
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "00101") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_msb_c-1) = "00")) or -- FMIN.S / FMAX.S
 
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "11010") and (execute_engine.i_reg(instr_funct12_lsb_c+4 downto instr_funct12_lsb_c+1) = "0000")) then -- FCVT.S.W*
 
      decode_aux.is_float_f_reg <= '1';
 
    end if;
 
    -- floating-point INTEGER_register operations --
 
    if ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "11100") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_msb_c-1) = "00")) or -- FMV.X.W / FCLASS.S
 
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "10100") and (execute_engine.i_reg(instr_funct3_msb_c) = '0')) or -- FEQ.S / FLT.S / FLE.S
 
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "11000") and (execute_engine.i_reg(instr_funct12_lsb_c+4 downto instr_funct12_lsb_c+1) = "0000")) then -- FCVT.W*.S
 
      decode_aux.is_float_i_reg <= '1';
 
    end if;
 
 
    -- system/environment instructions --
    -- system/environment instructions --
    sys_env_cmd_mask_v := funct12_ecall_c or funct12_ebreak_c or funct12_mret_c or funct12_wfi_c; -- sum-up set bits
    sys_env_cmd_mask_v := funct12_ecall_c or funct12_ebreak_c or funct12_mret_c or funct12_wfi_c; -- sum-up set bits
    decode_aux.sys_env_cmd(11 downto 0) <= execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) and sys_env_cmd_mask_v; -- set unsued bits to always-zero
    decode_aux.sys_env_cmd(11 downto 0) <= execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) and sys_env_cmd_mask_v; -- set unsued bits to always-zero
  end process decode_helper;
  end process decode_helper;
 
 
Line 835... Line 869...
    -- arbiter defaults --
    -- arbiter defaults --
    execute_engine.state_nxt    <= execute_engine.state;
    execute_engine.state_nxt    <= execute_engine.state;
    execute_engine.i_reg_nxt    <= execute_engine.i_reg;
    execute_engine.i_reg_nxt    <= execute_engine.i_reg;
    execute_engine.is_cp_op_nxt <= execute_engine.is_cp_op;
    execute_engine.is_cp_op_nxt <= execute_engine.is_cp_op;
    execute_engine.is_ci_nxt    <= execute_engine.is_ci;
    execute_engine.is_ci_nxt    <= execute_engine.is_ci;
 
    execute_engine.is_fp_nxt    <= execute_engine.is_fp;
    execute_engine.sleep_nxt    <= execute_engine.sleep;
    execute_engine.sleep_nxt    <= execute_engine.sleep;
    execute_engine.branched_nxt <= execute_engine.branched;
    execute_engine.branched_nxt <= execute_engine.branched;
    --
    --
    execute_engine.pc_mux_sel   <= '0';
    execute_engine.pc_mux_sel   <= '0';
    execute_engine.pc_we        <= '0';
    execute_engine.pc_we        <= '0';
Line 895... Line 930...
        execute_engine.state_nxt <= DISPATCH;
        execute_engine.state_nxt <= DISPATCH;
 
 
 
 
      when DISPATCH => -- Get new command from instruction issue engine
      when DISPATCH => -- Get new command from instruction issue engine
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
 
        -- housekeeping --
 
        execute_engine.is_cp_op_nxt <= '0'; -- init
 
        execute_engine.is_fp_nxt    <= '0'; -- init
        -- PC update --
        -- PC update --
        execute_engine.pc_mux_sel <= '0'; -- linear next PC
        execute_engine.pc_mux_sel <= '0'; -- linear next PC
        -- IR update --
        -- IR update --
        execute_engine.is_ci_nxt <= cmd_issue.data(32); -- flag to indicate a de-compressed instruction
        execute_engine.is_ci_nxt <= cmd_issue.data(32); -- flag to indicate a de-compressed instruction
        execute_engine.i_reg_nxt <= cmd_issue.data(31 downto 0);
        execute_engine.i_reg_nxt <= cmd_issue.data(31 downto 0);
Line 1024... Line 1062...
            end if;
            end if;
            ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU result
            ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU result
            ctrl_nxt(ctrl_rf_wb_en_c)  <= '1'; -- valid RF write-back
            ctrl_nxt(ctrl_rf_wb_en_c)  <= '1'; -- valid RF write-back
            execute_engine.state_nxt   <= DISPATCH;
            execute_engine.state_nxt   <= DISPATCH;
 
 
          when opcode_load_c | opcode_store_c | opcode_atomic_c => -- load/store / atomic memory access
          when opcode_load_c | opcode_store_c | opcode_atomic_c | opcode_flw_c | opcode_fsw_c => -- load/store / atomic memory access / floating-point load/store 
          -- ------------------------------------------------------------
          -- ------------------------------------------------------------
            ctrl_nxt(ctrl_alu_opa_mux_c) <= '0'; -- use RS1 as ALU.OPA
            ctrl_nxt(ctrl_alu_opa_mux_c) <= '0'; -- use RS1 as ALU.OPA
            ctrl_nxt(ctrl_alu_opb_mux_c) <= '1'; -- use IMM as ALU.OPB
            ctrl_nxt(ctrl_alu_opb_mux_c) <= '1'; -- use IMM as ALU.OPB
            ctrl_nxt(ctrl_bus_mo_we_c)   <= '1'; -- write to MAR and MDO (MDO only relevant for store)
            ctrl_nxt(ctrl_bus_mo_we_c)   <= '1'; -- write to MAR and MDO (MDO only relevant for store)
 
            if (CPU_EXTENSION_RISCV_F = true) and (execute_engine.i_reg(instr_opcode_lsb_c+3 downto instr_opcode_lsb_c+2) = "01") then -- floating-point load/store
 
              execute_engine.is_fp_nxt    <= decode_aux.is_float_f_reg; -- no integer register file write back for FPU internal operations
 
              ctrl_nxt(ctrl_bus_wd_sel_c) <= '1'; -- use memory-write-data from FPU co-processor (only relevant for float STORE)
 
            end if;
            --
            --
            if (CPU_EXTENSION_RISCV_A = false) or (execute_engine.i_reg(instr_opcode_lsb_c+2) = '0') then -- atomic (A) extension disabled or normal load/store
            if (CPU_EXTENSION_RISCV_A = false) or -- atomic extension disabled
 
               (execute_engine.i_reg(instr_opcode_lsb_c+3 downto instr_opcode_lsb_c+2) = "00") or  -- normal integerload/store
 
               ((CPU_EXTENSION_RISCV_F = true) and (execute_engine.i_reg(instr_opcode_lsb_c+3 downto instr_opcode_lsb_c+2) = "01")) then -- floating-point load/store
              execute_engine.state_nxt <= LOADSTORE_0;
              execute_engine.state_nxt <= LOADSTORE_0;
            else -- atomic operation
            else -- atomic operation
              atomic_ctrl.env_start <= not execute_engine.i_reg(instr_funct5_lsb_c); -- LR: start LOCKED memory access environment
              atomic_ctrl.env_start <= not execute_engine.i_reg(instr_funct5_lsb_c); -- LR: start LOCKED memory access environment
              if (execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c) = funct5_a_sc_c) or -- store-conditional
              if (execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c) = funct5_a_sc_c) or -- store-conditional
                 (execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c) = funct5_a_lr_c) then -- load-reservate
                 (execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c) = funct5_a_lr_c) then -- load-reservate
Line 1072... Line 1116...
              end if;
              end if;
            else
            else
              execute_engine.state_nxt <= SYS_WAIT;
              execute_engine.state_nxt <= SYS_WAIT;
            end if;
            end if;
 
 
 
          when opcode_fop_c => -- floating-point operations (1 or 2 operands)
 
          -- ------------------------------------------------------------
 
            execute_engine.state_nxt <= SYS_WAIT;
 
            if (CPU_EXTENSION_RISCV_F = true) then
 
              execute_engine.is_fp_nxt                           <= decode_aux.is_float_f_reg; -- no integer register file write back for FPU internal operations
 
              ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_fpu_c; -- use FPU CP
 
              execute_engine.is_cp_op_nxt                        <= '1'; -- this is a CP operation
 
              ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
 
              execute_engine.state_nxt                           <= ALU_WAIT;
 
            end if;
 
 
          when others => -- undefined
          when others => -- undefined
          -- ------------------------------------------------------------
          -- ------------------------------------------------------------
            execute_engine.state_nxt <= SYS_WAIT;
            execute_engine.state_nxt <= SYS_WAIT;
 
 
        end case;
        end case;
Line 1112... Line 1167...
 
 
 
 
      when ALU_WAIT => -- wait for multi-cycle ALU operation (shifter or CP) to finish
      when ALU_WAIT => -- wait for multi-cycle ALU operation (shifter or CP) to finish
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
        ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU result
        ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU result
 
        if (CPU_EXTENSION_RISCV_F = false) then
        ctrl_nxt(ctrl_rf_wb_en_c)  <= '1'; -- valid RF write-back (permanent write-back)
        ctrl_nxt(ctrl_rf_wb_en_c)  <= '1'; -- valid RF write-back (permanent write-back)
 
        else
 
          ctrl_nxt(ctrl_rf_wb_en_c) <= not execute_engine.is_fp; -- allow write back if NOT <FPU-internal operation>
 
        end if;
        -- cp access or alu.shift? --
        -- cp access or alu.shift? --
        if (execute_engine.is_cp_op = '1') then
        if (execute_engine.is_cp_op = '1') then
          ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
          ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
        else
        else
          ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_shift_c;
          ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_shift_c;
Line 1202... Line 1261...
          atomic_ctrl.env_abort     <= '1'; -- LOCKED (atomic) memory access environment failed (forces SC result to be non-zero => failure)
          atomic_ctrl.env_abort     <= '1'; -- LOCKED (atomic) memory access environment failed (forces SC result to be non-zero => failure)
          ctrl_nxt(ctrl_rf_wb_en_c) <= decode_aux.is_atomic_sc; -- SC failes: allow write back of non-zero result
          ctrl_nxt(ctrl_rf_wb_en_c) <= decode_aux.is_atomic_sc; -- SC failes: allow write back of non-zero result
          execute_engine.state_nxt  <= DISPATCH;
          execute_engine.state_nxt  <= DISPATCH;
        elsif (bus_d_wait_i = '0') then -- wait for bus to finish transaction
        elsif (bus_d_wait_i = '0') then -- wait for bus to finish transaction
          if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_atomic_lr = '1') or (decode_aux.is_atomic_sc = '1') then -- load / load-reservate / store conditional
          if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_atomic_lr = '1') or (decode_aux.is_atomic_sc = '1') then -- load / load-reservate / store conditional
            ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
            ctrl_nxt(ctrl_rf_wb_en_c) <= not execute_engine.is_fp; -- allow write back if NOT <FPU-internal operation>
 
          end if;
 
          if (CPU_EXTENSION_RISCV_F = true) and (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) = opcode_flw_c(6 downto 2)) then -- floating-point LOAD.word
 
            ctrl_nxt(ctrl_cp_fpu_mem_we_c) <= '1'; -- co-processor register file write-back
          end if;
          end if;
          atomic_ctrl.env_end      <= not decode_aux.is_atomic_lr; -- normal end of LOCKED (atomic) memory access environment - if we are not starting it via LR instruction
          atomic_ctrl.env_end      <= not decode_aux.is_atomic_lr; -- normal end of LOCKED (atomic) memory access environment - if we are not starting it via LR instruction
          execute_engine.state_nxt <= DISPATCH;
          execute_engine.state_nxt <= DISPATCH;
        end if;
        end if;
 
 
Line 1241... Line 1303...
--    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? --
    -- low privilege level access to hpm counters? --
    csr_mcounteren_hpm_v := (others => '0');
    csr_mcounteren_hpm_v := (others => '0');
    if (CPU_EXTENSION_RISCV_U = true) then -- 'mcounteren' CSR is hardwired to zero if user mode is not implemented
    if (CPU_EXTENSION_RISCV_U = true) then
      csr_mcounteren_hpm_v(HPM_NUM_CNTS-1 downto 0) := csr.mcounteren_hpm(HPM_NUM_CNTS-1 downto 0);
      csr_mcounteren_hpm_v(HPM_NUM_CNTS-1 downto 0) := csr.mcounteren_hpm(HPM_NUM_CNTS-1 downto 0);
 
    else -- 'mcounteren' CSR is hardwired to zero if user mode is not implemented
 
      csr_mcounteren_hpm_v := (others => '0');
    end if;
    end if;
 
 
    -- check CSR access --
    -- check CSR access --
    case csr.addr is
    case csr.addr is
      -- standard read/write CSRs --
      -- standard read/write CSRs --
 
      when csr_fflags_c | csr_frm_c | csr_fcsr_c => csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_F); -- full access for everyone if F extension is enabled
 
      --
      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
      when csr_misa_c          => csr_acc_valid <= csr.priv_m_mode;-- and (not csr_wacc_v); -- M-mode only, MISA is read-only in the NEORV32 but we do not cause an exception here for compatibility
      when csr_misa_c          => csr_acc_valid <= csr.priv_m_mode;-- and (not csr_wacc_v); -- M-mode only, MISA is read-only in the NEORV32 but we do not cause an exception here for compatibility
      when csr_mie_c           => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
      when csr_mie_c           => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
      when csr_mtvec_c         => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
      when csr_mtvec_c         => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
Line 1408... Line 1474...
      -- check instructions --
      -- check instructions --
      opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11";
      opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11";
      case opcode_v is
      case opcode_v is
 
 
        -- check sufficient LUI, UIPC, JAL (only check actual OPCODE) --
        -- check sufficient LUI, UIPC, JAL (only check actual OPCODE) --
 
        -- ------------------------------------------------------------
        when opcode_lui_c | opcode_auipc_c | opcode_jal_c =>
        when opcode_lui_c | opcode_auipc_c | opcode_jal_c =>
          illegal_instruction <= '0';
          illegal_instruction <= '0';
          -- illegal E-CPU register? --
          -- illegal E-CPU register? --
          if (CPU_EXTENSION_RISCV_E = true) and (execute_engine.i_reg(instr_rd_msb_c) = '1') then
          if (CPU_EXTENSION_RISCV_E = true) and (execute_engine.i_reg(instr_rd_msb_c) = '1') then
            illegal_register <= '1';
            illegal_register <= '1';
          end if;
          end if;
 
 
        when opcode_alu_c => -- check ALU.funct3 & ALU.funct7
        when opcode_alu_c => -- check ALU.funct3 & ALU.funct7
 
        -- ------------------------------------------------------------
          if (execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV
          if (execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV
            if (CPU_EXTENSION_RISCV_M = false) then -- not implemented
            if (CPU_EXTENSION_RISCV_M = false) then -- not implemented
              illegal_instruction <= '1';
              illegal_instruction <= '1';
            end if;
            end if;
          elsif (decode_aux.is_bitmanip_reg = '1') then -- bit manipulation
          elsif (decode_aux.is_bitmanip_reg = '1') then -- bit manipulation
Line 1439... Line 1507...
             ((execute_engine.i_reg(instr_rs2_msb_c) = '1') or (execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
             ((execute_engine.i_reg(instr_rs2_msb_c) = '1') or (execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
            illegal_register <= '1';
            illegal_register <= '1';
          end if;
          end if;
 
 
        when opcode_alui_c => -- check ALUI.funct7
        when opcode_alui_c => -- check ALUI.funct7
 
        -- ------------------------------------------------------------
          if (decode_aux.is_bitmanip_imm = '1') then -- bit manipulation
          if (decode_aux.is_bitmanip_imm = '1') then -- bit manipulation
            if (CPU_EXTENSION_RISCV_B = false) then -- not implemented
            if (CPU_EXTENSION_RISCV_B = false) then -- not implemented
              illegal_instruction <= '1';
              illegal_instruction <= '1';
            end if;
            end if;
          elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and
          elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and
Line 1458... Line 1527...
          if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
          if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
            illegal_register <= '1';
            illegal_register <= '1';
          end if;
          end if;
 
 
        when opcode_load_c => -- check LOAD.funct3
        when opcode_load_c => -- check LOAD.funct3
 
        -- ------------------------------------------------------------
          if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lb_c) or
          if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lb_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lh_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lh_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lw_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lw_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lbu_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lbu_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lhu_c) then
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lhu_c) then
Line 1473... Line 1543...
          if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
          if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
            illegal_register <= '1';
            illegal_register <= '1';
          end if;
          end if;
 
 
        when opcode_store_c => -- check STORE.funct3
        when opcode_store_c => -- check STORE.funct3
 
        -- ------------------------------------------------------------
          if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sb_c) or
          if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sb_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sh_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sh_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sw_c) then
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sw_c) then
            illegal_instruction <= '0';
            illegal_instruction <= '0';
          else
          else
Line 1486... Line 1557...
          if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs2_msb_c) = '1') or (execute_engine.i_reg(instr_rs1_msb_c) = '1')) then
          if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs2_msb_c) = '1') or (execute_engine.i_reg(instr_rs1_msb_c) = '1')) then
            illegal_register <= '1';
            illegal_register <= '1';
          end if;
          end if;
 
 
        when opcode_branch_c => -- check BRANCH.funct3
        when opcode_branch_c => -- check BRANCH.funct3
 
        -- ------------------------------------------------------------
          if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_beq_c) or
          if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_beq_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bne_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bne_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_blt_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_blt_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bge_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bge_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bltu_c) or
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bltu_c) or
Line 1502... Line 1574...
          if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs2_msb_c) = '1') or (execute_engine.i_reg(instr_rs1_msb_c) = '1')) then
          if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs2_msb_c) = '1') or (execute_engine.i_reg(instr_rs1_msb_c) = '1')) then
            illegal_register <= '1';
            illegal_register <= '1';
          end if;
          end if;
 
 
        when opcode_jalr_c => -- check JALR.funct3
        when opcode_jalr_c => -- check JALR.funct3
 
        -- ------------------------------------------------------------
          if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "000") then
          if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "000") then
            illegal_instruction <= '0';
            illegal_instruction <= '0';
          else
          else
            illegal_instruction <= '1';
            illegal_instruction <= '1';
          end if;
          end if;
          -- illegal E-CPU register? --
          -- illegal E-CPU register? --
          if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
          if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
            illegal_register <= '1';
            illegal_register <= '1';
          end if;
          end if;
 
 
        when opcode_fence_c => -- fence instructions --
        when opcode_fence_c => -- fence instructions
 
        -- ------------------------------------------------------------
          if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fencei_c) and (CPU_EXTENSION_RISCV_Zifencei = true) then -- FENCE.I
          if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fencei_c) and (CPU_EXTENSION_RISCV_Zifencei = true) then -- FENCE.I
            illegal_instruction <= '0';
            illegal_instruction <= '0';
          elsif (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fence_c) then -- FENCE
          elsif (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fence_c) then -- FENCE
            illegal_instruction <= '0';
            illegal_instruction <= '0';
          else
          else
            illegal_instruction <= '1';
            illegal_instruction <= '1';
          end if;
          end if;
 
 
        when opcode_syscsr_c => -- check system instructions --
        when opcode_syscsr_c => -- check system instructions
 
        -- ------------------------------------------------------------
          -- CSR access --
          -- CSR access --
          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_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
Line 1559... Line 1634...
            end if;
            end if;
          else
          else
            illegal_instruction <= '1';
            illegal_instruction <= '1';
          end if;
          end if;
 
 
        when opcode_atomic_c => -- atomic instructions --
        when opcode_atomic_c => -- atomic instructions
 
        -- ------------------------------------------------------------
          if (CPU_EXTENSION_RISCV_A = true) and -- atomic memory operations (A extension) enabled
          if (CPU_EXTENSION_RISCV_A = true) and -- atomic memory operations (A extension) enabled
             ((execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c) = funct5_a_lr_c) or -- LR
             ((execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c) = funct5_a_lr_c) or -- LR
              (execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c) = funct5_a_sc_c)) then -- SC
              (execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c) = funct5_a_sc_c)) then -- SC
            illegal_instruction <= '0';
            illegal_instruction <= '0';
          else
          else
            illegal_instruction <= '1';
            illegal_instruction <= '1';
          end if;
          end if;
 
 
 
        when opcode_fop_c => -- floating point operations (dual-operand)
 
        -- ------------------------------------------------------------
 
          if (CPU_EXTENSION_RISCV_F = true) and -- F extension enabled
 
             (execute_engine.i_reg(instr_funct7_lsb_c+1 downto instr_funct7_lsb_c) = float_single_c) and -- single-precision operations
 
             ((decode_aux.is_float_f_reg = '1') or (decode_aux.is_float_i_reg = '1')) then -- float_reg or int_reg operations
 
            illegal_instruction <= '0';
 
          else
 
            illegal_instruction <= '1';
 
          end if;
 
 
 
        when opcode_flw_c | opcode_fsw_c => -- floating point load/store word
 
        -- ------------------------------------------------------------
 
          if (CPU_EXTENSION_RISCV_F = true) and -- F extension enabled
 
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "010") then -- 32-bit transfer size
 
            illegal_instruction <= '0';
 
          else
 
            illegal_instruction <= '1';
 
          end if;
 
 
        when others => -- undefined instruction -> illegal!
        when others => -- undefined instruction -> illegal!
 
        -- ------------------------------------------------------------
          illegal_instruction <= '1';
          illegal_instruction <= '1';
 
 
      end case;
      end case;
    else
    else
      illegal_opcode_lsbs <= '0';
      illegal_opcode_lsbs <= '0';
Line 1868... Line 1964...
      when others => csr.wdata <= csr_operand_v; -- CSRRW(I)
      when others => csr.wdata <= csr_operand_v; -- CSRRW(I)
    end case;
    end case;
  end process csr_write_data;
  end process csr_write_data;
 
 
 
 
  -- 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 1888... Line 1983...
      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');
      csr.mcause       <= trap_reset_c; -- mcause = TRAP_CODE_RESET (hardware reset, "non-maskable interrupt")
      csr.mcause       <= trap_reset_c; -- mcause = TRAP_CODE_RESET (hardware reset, "non-maskable interrupt")
      --
 
      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'));
Line 1905... Line 1999...
      csr.mcounteren_hpm    <= (others => '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.mcountinhibit_hpm <= (others => '0');
 
      --
 
      csr.fflags <= (others => '0');
 
      csr.frm    <= (others => '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 1918... Line 2015...
 
 
        -- --------------------------------------------------------------------------------
        -- --------------------------------------------------------------------------------
        -- CSR access by application software
        -- CSR access by application software
        -- --------------------------------------------------------------------------------
        -- --------------------------------------------------------------------------------
        if (csr.we = '1') then -- manual update
        if (csr.we = '1') then -- manual update
          case csr.addr is
 
 
          -- user floating-point CSRs --
 
          -- --------------------------------------------------------------------
 
          if (csr.addr(11 downto 4) = csr_class_float_c) then -- floating point CSR class
 
            -- R/W: fflags - floating-point (FPU) exception flags --
 
            if (csr.addr(3 downto 0) = csr_fflags_c(3 downto 0)) and (CPU_EXTENSION_RISCV_F = true) then
 
              csr.fflags <= csr.wdata(4 downto 0);
 
            end if;
 
            -- R/W: frm - floating-point (FPU) rounding mode --
 
            if (csr.addr(3 downto 0) = csr_frm_c(3 downto 0)) and (CPU_EXTENSION_RISCV_F = true) then
 
              csr.frm <= csr.wdata(2 downto 0);
 
            end if;
 
            -- R/W: fflags - floating-point (FPU) control/status (frm + fflags) --
 
            if (csr.addr(3 downto 0) = csr_fcsr_c(3 downto 0)) and (CPU_EXTENSION_RISCV_F = true) then
 
              csr.frm    <= csr.wdata(7 downto 5);
 
              csr.fflags <= csr.wdata(4 downto 0);
 
            end if;
 
          end if;
 
 
            -- machine trap setup --
            -- machine trap setup --
            -- --------------------------------------------------------------------
            -- --------------------------------------------------------------------
            when csr_mstatus_c => -- R/W: mstatus - machine status register
          if (csr.addr(11 downto 4) = csr_setup_c) then -- ftrap setup CSR class
 
            -- R/W: mstatus - machine status register --
 
            if (csr.addr(3 downto 0) = csr_mstatus_c(3 downto 0)) then
              csr.mstatus_mie  <= csr.wdata(03);
              csr.mstatus_mie  <= csr.wdata(03);
              csr.mstatus_mpie <= csr.wdata(07);
              csr.mstatus_mpie <= csr.wdata(07);
              if (CPU_EXTENSION_RISCV_U = true) then -- user mode implemented
              if (CPU_EXTENSION_RISCV_U = true) then -- user mode implemented
                csr.mstatus_mpp(0) <= csr.wdata(11) or csr.wdata(12);
                csr.mstatus_mpp(0) <= csr.wdata(11) or csr.wdata(12);
                csr.mstatus_mpp(1) <= csr.wdata(11) or csr.wdata(12);
                csr.mstatus_mpp(1) <= csr.wdata(11) or csr.wdata(12);
              else -- only machine mode is available
              else -- only machine mode is available
                csr.mstatus_mpp <= priv_mode_m_c;
                csr.mstatus_mpp <= priv_mode_m_c;
              end if;
              end if;
            when csr_mie_c => -- R/W: mie - machine interrupt enable register
            end if;
 
            -- R/W: mie - machine interrupt enable register --
 
            if (csr.addr(3 downto 0) = csr_mie_c(3 downto 0)) then
              csr.mie_msie <= csr.wdata(03); -- machine SW IRQ enable
              csr.mie_msie <= csr.wdata(03); -- machine SW IRQ enable
              csr.mie_mtie <= csr.wdata(07); -- machine TIMER IRQ enable
              csr.mie_mtie <= csr.wdata(07); -- machine TIMER IRQ enable
              csr.mie_meie <= csr.wdata(11); -- machine EXT IRQ enable
              csr.mie_meie <= csr.wdata(11); -- machine EXT IRQ enable
              for i in 0 to 15 loop -- fast interrupt channels 0..15
              for i in 0 to 15 loop -- fast interrupt channels 0..15
                csr.mie_firqe(i) <= csr.wdata(16+i);
                csr.mie_firqe(i) <= csr.wdata(16+i);
              end loop; -- i
              end loop; -- i
            when csr_mtvec_c => -- R/W: mtvec - machine trap-handler base address (for ALL exceptions)
            end if;
 
            -- R/W: mtvec - machine trap-handler base address (for ALL exceptions) --
 
            if (csr.addr(3 downto 0) = csr_mtvec_c(3 downto 0)) then
              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
            end if;
 
            -- R/W: machine counter enable register --
 
            if (csr.addr(3 downto 0) = csr_mcounteren_c(3 downto 0)) then
              if (CPU_EXTENSION_RISCV_U = true) then -- this CSR is hardwired to zero if user mode is not implemented
              if (CPU_EXTENSION_RISCV_U = true) then -- this CSR is hardwired to zero if user mode is not implemented
                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 hpmcounterx[h]
                csr.mcounteren_hpm <= csr.wdata(csr.mcounteren_hpm'left+3 downto 3); -- enable user-level access to hpmcounterx[h]
              else
              end if;
                NULL;
            end if;
              end if;
              end if;
 
 
            -- machine trap handling --
            -- machine trap handling --
            -- --------------------------------------------------------------------
            -- --------------------------------------------------------------------
            when csr_mscratch_c =>  -- R/W: mscratch - machine scratch register
          if (csr.addr(11 downto 4) = csr_class_trap_c) then -- machine trap handling CSR class
 
            -- R/W: mscratch - machine scratch register --
 
            if (csr.addr(3 downto 0) = csr_mscratch_c(3 downto 0)) then
              csr.mscratch <= csr.wdata;
              csr.mscratch <= csr.wdata;
            when csr_mepc_c => -- R/W: mepc - machine exception program counter
            end if;
 
            -- R/W: mepc - machine exception program counter --
 
            if (csr.addr(3 downto 0) = csr_mepc_c(3 downto 0)) then
              csr.mepc <= csr.wdata(data_width_c-1 downto 1) & '0';
              csr.mepc <= csr.wdata(data_width_c-1 downto 1) & '0';
            when csr_mcause_c => -- R/W: mcause - machine trap cause
            end if;
 
            -- R/W: mcause - machine trap cause --
 
            if (csr.addr(3 downto 0) = csr_mcause_c(3 downto 0)) then
              csr.mcause(csr.mcause'left) <= csr.wdata(31); -- 1: interrupt, 0: exception
              csr.mcause(csr.mcause'left) <= csr.wdata(31); -- 1: interrupt, 0: exception
              csr.mcause(4 downto 0)      <= csr.wdata(4 downto 0); -- identifier
              csr.mcause(4 downto 0)      <= csr.wdata(4 downto 0); -- identifier
            when csr_mtval_c => -- R/W: mtval - machine bad address/instruction
            end if;
 
            -- R/W: mtval - machine bad address/instruction --
 
            if (csr.addr(3 downto 0) = csr_mtval_c(3 downto 0)) then
              csr.mtval <= csr.wdata;
              csr.mtval <= csr.wdata;
            when csr_mip_c => -- R/W: mip - machine interrupt pending
            end if;
 
            -- R/W: mip - machine interrupt pending --
 
            if (csr.addr(3 downto 0) = csr_mip_c(3 downto 0)) then
              csr.mip_clear(interrupt_msw_irq_c)   <= not csr.wdata(03);
              csr.mip_clear(interrupt_msw_irq_c)   <= not csr.wdata(03);
              csr.mip_clear(interrupt_mtime_irq_c) <= not csr.wdata(07);
              csr.mip_clear(interrupt_mtime_irq_c) <= not csr.wdata(07);
              csr.mip_clear(interrupt_mext_irq_c)  <= not csr.wdata(11);
              csr.mip_clear(interrupt_mext_irq_c)  <= not csr.wdata(11);
              for i in 0 to 15 loop -- fast interrupt channels 0..15
              for i in 0 to 15 loop -- fast interrupt channels 0..15
                csr.mip_clear(interrupt_firq_0_c+i) <= not csr.wdata(16+i);
                csr.mip_clear(interrupt_firq_0_c+i) <= not csr.wdata(16+i);
              end loop; -- i
              end loop; -- i
 
            end if;
 
          end if;
 
 
            -- physical memory protection: R/W: pmpcfg* - PMP configuration registers --
            -- physical memory protection: R/W: pmpcfg* - PMP configuration registers --
            -- --------------------------------------------------------------------
            -- --------------------------------------------------------------------
            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 (csr.addr(11 downto 4) = csr_class_pmpcfg_c) then -- pmp configuration CSR class
                 csr_pmpcfg8_c | csr_pmpcfg9_c | csr_pmpcfg10_c | csr_pmpcfg11_c | csr_pmpcfg12_c | csr_pmpcfg13_c | csr_pmpcfg14_c | csr_pmpcfg15_c =>
 
              if (PMP_NUM_REGIONS > 0) then
              if (PMP_NUM_REGIONS > 0) then
                for i in 0 to PMP_NUM_REGIONS-1 loop
                for i in 0 to PMP_NUM_REGIONS-1 loop
                  if (csr.addr(3 downto 0) = std_ulogic_vector(to_unsigned(i, 4))) then
                  if (csr.addr(3 downto 0) = std_ulogic_vector(to_unsigned(i, 4))) then
                    if (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpcfg access
                    if (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpcfg access
                      csr.pmpcfg(i)(0) <= csr.wdata((i mod 4)*8+0); -- R (rights.read)
                      csr.pmpcfg(i)(0) <= csr.wdata((i mod 4)*8+0); -- R (rights.read)
Line 1988... Line 2121...
                      csr.pmpcfg(i)(6) <= '0'; -- reserved
                      csr.pmpcfg(i)(6) <= '0'; -- reserved
                      csr.pmpcfg(i)(7) <= csr.wdata((i mod 4)*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 if;
                  end if;
                end loop; -- i (PMP regions)
                end loop; -- i (PMP regions)
              else
            end if;
                NULL;
 
              end if;
              end if;
 
 
            -- physical memory protection: R/W: pmpaddr* - PMP address registers --
            -- physical memory protection: R/W: pmpaddr* - PMP address registers --
            -- --------------------------------------------------------------------
            -- --------------------------------------------------------------------
            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  |
          if (csr.addr(11 downto 4) =  csr_pmpaddr0_c(11 downto 4)) or (csr.addr(11 downto 4) = csr_pmpaddr16_c(11 downto 4)) or
                 csr_pmpaddr8_c  | csr_pmpaddr9_c  | csr_pmpaddr10_c | csr_pmpaddr11_c | csr_pmpaddr12_c | csr_pmpaddr13_c | csr_pmpaddr14_c | csr_pmpaddr15_c |
             (csr.addr(11 downto 4) = csr_pmpaddr32_c(11 downto 4)) or (csr.addr(11 downto 4) = csr_pmpaddr48_c(11 downto 4)) 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 |
 
                 csr_pmpaddr24_c | csr_pmpaddr25_c | csr_pmpaddr26_c | csr_pmpaddr27_c | csr_pmpaddr28_c | csr_pmpaddr29_c | csr_pmpaddr30_c | csr_pmpaddr31_c |
 
                 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 =>
 
              if (PMP_NUM_REGIONS > 0) then
              if (PMP_NUM_REGIONS > 0) then
                for i in 0 to PMP_NUM_REGIONS-1 loop
                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) = std_ulogic_vector(unsigned(csr_pmpaddr0_c(6 downto 0)) + i)) and (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpaddr access
                  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)-4 downto 0) <= (others => '1');
                    csr.pmpaddr(i)(index_size_f(PMP_MIN_GRANULARITY)-4 downto 0) <= (others => '1');
                  end if;
                  end if;
                end loop; -- i (PMP regions)
                end loop; -- i (PMP regions)
              else
            end if;
                NULL;
 
              end if;
              end if;
 
 
            -- machine counter setup --
            -- machine counter setup --
            -- --------------------------------------------------------------------
            -- --------------------------------------------------------------------
            when csr_mcountinhibit_c => -- R/W: mcountinhibit - machine counter-inhibit register
          -- R/W: mcountinhibit - machine counter-inhibit register --
 
          if (csr.addr = csr_mcountinhibit_c) then
              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
              csr.mcountinhibit_hpm <= csr.wdata(csr.mcountinhibit_hpm'left+3 downto 3); -- enable auto-increment of [m]hpmcounter*[h] counter
 
          end if;
 
 
            -- machine performance-monitoring event selector --
            -- machine performance-monitoring event selector --
            -- --------------------------------------------------------------------
            -- --------------------------------------------------------------------
            when csr_mhpmevent3_c  | csr_mhpmevent4_c  | csr_mhpmevent5_c  | csr_mhpmevent6_c  | csr_mhpmevent7_c  | csr_mhpmevent8_c  |
          if (unsigned(csr.addr) >= unsigned(csr_mhpmevent3_c)) and (unsigned(csr.addr) <= unsigned(csr_mhpmevent31_c)) then
                 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
 
              if (HPM_NUM_CNTS > 0) then
              if (HPM_NUM_CNTS > 0) then
                for i in 0 to HPM_NUM_CNTS-1 loop
                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
                  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);
                    csr.mhpmevent(i) <= csr.wdata(csr.mhpmevent(i)'left downto 0);
                    csr.mhpmevent(i)(1) <= '0'; -- would be used for "TIME"
                    csr.mhpmevent(i)(1) <= '0'; -- would be used for "TIME"
                  end if;
                  end if;
                end loop; -- i (CSRs)
                end loop; -- i (CSRs)
              else
            end if;
                NULL;
 
              end if;
              end if;
 
 
            -- undefined --
 
            -- --------------------------------------------------------------------
 
            when others =>
 
              NULL;
 
 
 
          end case;
 
 
 
        -- --------------------------------------------------------------------------------
        -- --------------------------------------------------------------------------------
        -- CSR access by hardware
        -- CSR access by hardware
        -- --------------------------------------------------------------------------------
        -- --------------------------------------------------------------------------------
        else
        else
 
 
 
          -- floating-point (FPU) exception flags --
 
          -- --------------------------------------------------------------------
 
          if (CPU_EXTENSION_RISCV_F = true) and (execute_engine.state = ALU_WAIT) then -- FIXME?
 
            csr.fflags <= csr.fflags or fpu_flags_i; -- accumulate flags ("accrued exception flags")
 
          end if;
 
 
          -- mcause, mepc, mtval: machine trap cause, PC and value register --
          -- mcause, mepc, mtval: machine trap cause, PC and value register --
          -- --------------------------------------------------------------------
          -- --------------------------------------------------------------------
          if (trap_ctrl.env_start_ack = '1') then -- trap handler starting?
          if (trap_ctrl.env_start_ack = '1') then -- trap handler starting?
            -- trap cause ID code --
            -- trap cause ID code --
            csr.mcause(csr.mcause'left) <= trap_ctrl.cause(trap_ctrl.cause'left); -- 1: interrupt, 0: exception
            csr.mcause(csr.mcause'left) <= trap_ctrl.cause(trap_ctrl.cause'left); -- 1: interrupt, 0: exception
Line 2101... Line 2222...
          if (CPU_EXTENSION_RISCV_U = false) then
          if (CPU_EXTENSION_RISCV_U = false) then
            csr.privilege   <= priv_mode_m_c;
            csr.privilege   <= priv_mode_m_c;
            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;
 
 
 
      -- --------------------------------------------------------------------------------
 
      -- override write access for disabled functions
 
      -- --------------------------------------------------------------------------------
 
 
 
      -- user mode disabled --
 
      if (CPU_EXTENSION_RISCV_U = false) then
 
        csr.privilege      <= priv_mode_m_c;
 
        csr.mstatus_mpp    <= priv_mode_m_c;
 
        csr.mcounteren_cy  <= '0';
 
        csr.mcounteren_tm  <= '0';
 
        csr.mcounteren_ir  <= '0';
 
        csr.mcounteren_hpm <= (others => '0');
 
      end if;
 
 
 
      -- pmp disabled --
 
      if (PMP_NUM_REGIONS = 0) then
 
        csr.pmpcfg  <= (others => (others => '0'));
 
        csr.pmpaddr <= (others => (others => '1'));
 
      end if;
 
 
 
      -- hpms disabled --
 
      if (HPM_NUM_CNTS = 0) then
 
        csr.mhpmevent         <= (others => (others => '0'));
 
        csr.mcounteren_hpm    <= (others => '0');
 
        csr.mcountinhibit_hpm <= (others => '0');
 
      end if;
 
 
 
      -- floating-point extension disabled --
 
      if (CPU_EXTENSION_RISCV_F = false) then
 
        csr.fflags <= (others => '0');
 
        csr.frm    <= (others => '0');
      end if;
      end if;
 
 
    end if;
    end if;
  end process csr_write_access;
  end process csr_write_access;
 
 
  -- decode privilege mode --
  -- decode privilege mode --
  csr.priv_m_mode <= '1' when (csr.privilege = priv_mode_m_c) else '0';
  csr.priv_m_mode <= '1' when (csr.privilege = priv_mode_m_c) else '0';
Line 2137... Line 2291...
        csr.pmpaddr_rd(i)(index_size_f(PMP_MIN_GRANULARITY)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
        csr.pmpaddr_rd(i)(index_size_f(PMP_MIN_GRANULARITY)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
      end if;
      end if;
    end loop; -- i
    end loop; -- i
  end process pmp_rd_dummy;
  end process pmp_rd_dummy;
 
 
 
  -- FPU rounding mode --
 
  fpu_rm_o <= csr.frm;
 
 
 
 
  -- Control and Status Registers - Counters ------------------------------------------------
  -- Control and Status Registers - Counters ------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  csr_counters: process(clk_i)
  csr_counters: process(clk_i)
  begin
  begin
Line 2252... Line 2409...
 
 
  cnt_event_nxt(hpmcnt_event_trap_c)    <= '1' when (trap_ctrl.env_start_ack = '1')                                    else '0'; -- entered trap
  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
  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)
  begin
  begin
    if rising_edge(clk_i) then
    if rising_edge(clk_i) then
      csr.re    <= csr.re_nxt; -- read access?
      csr.re    <= csr.re_nxt; -- read access?
      csr.rdata <= (others => '0'); -- default output
      csr.rdata <= (others => '0'); -- default output
      if (CPU_EXTENSION_RISCV_Zicsr = true) and (csr.re = '1') then
      if (CPU_EXTENSION_RISCV_Zicsr = true) and (csr.re = '1') then
        case csr.addr is
        case csr.addr is
 
 
 
          -- user floating-point CSRs --
 
          -- --------------------------------------------------------------------
 
          when csr_fflags_c => -- R/W: fflags - floating-point (FPU) exception flags
 
            csr.rdata <= (others => '0');
 
            if (CPU_EXTENSION_RISCV_F = true) then -- FPU implemented
 
              csr.rdata(4 downto 0) <= csr.fflags;
 
            end if;
 
          when csr_frm_c => -- R/W: frm - floating-point (FPU) rounding mode
 
            csr.rdata <= (others => '0');
 
            if (CPU_EXTENSION_RISCV_F = true) then -- FPU implemented
 
              csr.rdata(2 downto 0) <= csr.frm;
 
            end if;
 
          when csr_fcsr_c => -- R/W: fflags - floating-point (FPU) control/status (frm + fflags)
 
            csr.rdata <= (others => '0');
 
            if (CPU_EXTENSION_RISCV_F = true) then -- FPU implemented
 
              csr.rdata(7 downto 5) <= csr.frm;
 
              csr.rdata(4 downto 0) <= csr.fflags;
 
            end if;
 
 
          -- machine trap setup --
          -- machine trap setup --
          when csr_mstatus_c => -- R/W: mstatus - machine status register
          when csr_mstatus_c => -- R/W: mstatus - machine status register
            csr.rdata(03) <= csr.mstatus_mie; -- MIE
            csr.rdata(03) <= csr.mstatus_mie; -- MIE
            csr.rdata(06) <= '1' and bool_to_ulogic_f(CPU_EXTENSION_RISCV_U); -- UBE: CPU/Processor is BIG-ENDIAN (in user-mode)
            csr.rdata(06) <= '1' and bool_to_ulogic_f(CPU_EXTENSION_RISCV_U); -- UBE: CPU/Processor is BIG-ENDIAN (in user-mode)
            csr.rdata(07) <= csr.mstatus_mpie; -- MPIE
            csr.rdata(07) <= csr.mstatus_mpie; -- MPIE
Line 2276... Line 2452...
          when csr_misa_c => -- R/-: misa - ISA and extensions
          when csr_misa_c => -- R/-: misa - ISA and extensions
            csr.rdata(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_A);     -- A CPU extension
            csr.rdata(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_A);     -- A CPU extension
            csr.rdata(01) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B);     -- B CPU extension
            csr.rdata(01) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B);     -- B CPU extension
            csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C);     -- C CPU extension
            csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C);     -- C CPU extension
            csr.rdata(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E);     -- E CPU extension
            csr.rdata(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E);     -- E CPU extension
 
            csr.rdata(05) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_F);     -- F CPU extension
            csr.rdata(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
            csr.rdata(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
            csr.rdata(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M);     -- M CPU extension
            csr.rdata(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M);     -- M CPU extension
            csr.rdata(20) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U);     -- U CPU extension
            csr.rdata(20) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U);     -- U CPU extension
            csr.rdata(23) <= '1';                                         -- X CPU extension (non-std extensions)
            csr.rdata(23) <= '1';                                         -- X CPU extension (non-std extensions)
            csr.rdata(30) <= '1'; -- 32-bit architecture (MXL lo)
            csr.rdata(30) <= '1'; -- 32-bit architecture (MXL lo)

powered by: WebSVN 2.1.0

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