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

Subversion Repositories neorv32

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

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

Rev 52 Rev 53
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_Zfinx    : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
    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) --
    PMP_NUM_REGIONS              : natural := 0;       -- number of regions (0..64)
    PMP_NUM_REGIONS              : natural := 0;       -- number of regions (0..64)
    PMP_MIN_GRANULARITY          : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
    PMP_MIN_GRANULARITY          : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
Line 178... 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_op     : 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 --
  type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP_ENTER, TRAP_EXIT, TRAP_EXECUTE, EXECUTE, ALU_WAIT,
  type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP_ENTER, TRAP_EXIT, TRAP_EXECUTE, EXECUTE, ALU_WAIT, BRANCH,
                                  BRANCH, FENCE_OP,LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS);
                                  FENCE_OP,LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, ATOMIC_SC_EVAL, SYS_ENV, CSR_ACCESS);
  type execute_engine_t is record
  type execute_engine_t is record
    state        : execute_engine_state_t;
    state        : execute_engine_state_t;
    state_nxt    : execute_engine_state_t;
    state_nxt    : execute_engine_state_t;
    state_prev   : execute_engine_state_t;
    state_prev   : execute_engine_state_t;
    --
    --
Line 200... Line 199...
    --
    --
    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 243... Line 240...
    env_call      : std_ulogic;
    env_call      : std_ulogic;
    break_point   : std_ulogic;
    break_point   : std_ulogic;
  end record;
  end record;
  signal trap_ctrl : trap_ctrl_t;
  signal trap_ctrl : trap_ctrl_t;
 
 
  -- atomic operations controller --
 
  type atomic_ctrl_t is record
 
    env_start  : std_ulogic; -- begin atomic operations
 
    env_end    : std_ulogic; -- end atomic operations
 
    env_end_ff : std_ulogic; -- end atomic operations dealyed
 
    env_abort  : std_ulogic; -- atomic operations abort (results in failure)
 
    lock       : std_ulogic; -- lock status
 
  end record;
 
  signal atomic_ctrl : atomic_ctrl_t;
 
 
 
  -- CPU main control bus --
  -- CPU main control bus --
  signal ctrl_nxt, ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0);
  signal ctrl_nxt, ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0);
 
 
  -- fast instruction fetch access --
  -- fast instruction fetch access --
  signal bus_fast_ir : std_ulogic;
  signal bus_fast_ir : std_ulogic;
Line 434... Line 421...
 
 
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
-- Instruction Prefetch Buffer
-- Instruction Prefetch Buffer
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
 
 
 
 
  -- Instruction Prefetch Buffer (FIFO) -----------------------------------------------------
  -- Instruction Prefetch Buffer (FIFO) -----------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  instr_prefetch_buffer: process(clk_i)
  instr_prefetch_buffer: process(clk_i)
  begin
  begin
    if rising_edge(clk_i) then
    if rising_edge(clk_i) then
Line 473... Line 459...
 
 
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
-- Instruction Issue (recoding of compressed instructions and 32-bit instruction word construction)
-- Instruction Issue (recoding of compressed instructions and 32-bit instruction word construction)
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
 
 
 
 
  -- Issue Engine FSM Sync ------------------------------------------------------------------
  -- Issue Engine FSM Sync ------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  issue_engine_fsm_sync: process(rstn_i, clk_i)
  issue_engine_fsm_sync: process(rstn_i, clk_i)
  begin
  begin
    if (rstn_i = '0') then
    if (rstn_i = '0') then
Line 603... Line 588...
 
 
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
-- Instruction Execution
-- Instruction Execution
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
 
 
 
 
  -- Immediate Generator --------------------------------------------------------------------
  -- Immediate Generator --------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  imm_gen: process(execute_engine.i_reg, clk_i)
  imm_gen: process(execute_engine.i_reg, clk_i)
    variable opcode_v : std_ulogic_vector(6 downto 0);
    variable opcode_v : std_ulogic_vector(6 downto 0);
  begin
  begin
Line 615... Line 599...
    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 | opcode_fsw_c => -- S-immediate
          when opcode_store_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 704... Line 688...
    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 734... Line 717...
  csr.addr <= execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c);
  csr.addr <= execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c);
 
 
 
 
  -- CPU Control Bus Output -----------------------------------------------------------------
  -- CPU Control Bus Output -----------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  ctrl_output: process(ctrl, fetch_engine, trap_ctrl, atomic_ctrl, bus_fast_ir, execute_engine, csr)
  ctrl_output: process(ctrl, fetch_engine, trap_ctrl, bus_fast_ir, execute_engine, csr)
  begin
  begin
    -- signals from execute engine --
    -- signals from execute engine --
    ctrl_o <= ctrl;
    ctrl_o <= ctrl;
    -- current privilege level --
    -- current privilege level --
    ctrl_o(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c) <= csr.privilege;
    ctrl_o(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c) <= csr.privilege;
Line 759... Line 742...
    ctrl_o(ctrl_alu_shift_ar_c)  <= execute_engine.i_reg(30); -- is arithmetic shift
    ctrl_o(ctrl_alu_shift_ar_c)  <= execute_engine.i_reg(30); -- is arithmetic shift
    -- instruction's function blocks (for co-processors) --
    -- instruction's function blocks (for co-processors) --
    ctrl_o(ctrl_ir_opcode7_6_c  downto ctrl_ir_opcode7_0_c) <= execute_engine.i_reg(instr_opcode_msb_c  downto instr_opcode_lsb_c);
    ctrl_o(ctrl_ir_opcode7_6_c  downto ctrl_ir_opcode7_0_c) <= execute_engine.i_reg(instr_opcode_msb_c  downto instr_opcode_lsb_c);
    ctrl_o(ctrl_ir_funct12_11_c downto ctrl_ir_funct12_0_c) <= execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c);
    ctrl_o(ctrl_ir_funct12_11_c downto ctrl_ir_funct12_0_c) <= execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c);
    ctrl_o(ctrl_ir_funct3_2_c   downto ctrl_ir_funct3_0_c)  <= execute_engine.i_reg(instr_funct3_msb_c  downto instr_funct3_lsb_c);
    ctrl_o(ctrl_ir_funct3_2_c   downto ctrl_ir_funct3_0_c)  <= execute_engine.i_reg(instr_funct3_msb_c  downto instr_funct3_lsb_c);
    -- locked bus operation (for atomic memory operations) --
 
    ctrl_o(ctrl_bus_lock_c) <= atomic_ctrl.lock; -- (bus) lock status
 
    -- cpu status --
    -- cpu status --
    ctrl_o(ctrl_sleep_c) <= execute_engine.sleep; -- cpu is in sleep mode
    ctrl_o(ctrl_sleep_c) <= execute_engine.sleep; -- cpu is in sleep mode
  end process ctrl_output;
  end process ctrl_output;
 
 
 
 
Line 778... Line 759...
    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_op     <= '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? --
Line 826... Line 806...
         (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "111") or -- ANDN
         (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "111") or -- ANDN
         (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "110") or -- ORN
         (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "110") or -- ORN
         (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100")    -- XORN
         (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100")    -- XORN
         )
         )
        ) or
        ) or
 
       ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0010000") and
 
        (
 
         (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "010") or -- SH1ADD
 
         (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100") or -- SH2ADD
 
         (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "110")    -- SH3ADD
 
         )
 
        ) or
       ((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) = "001")) or -- SBCLR
       ((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) = "001")) or -- SBCLR
       ((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 --
    -- floating-point operations (Zfinx) --
    if ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "11110")) or -- FMV.W.X
    if ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+3) = "0000")) or -- FADD.S / FSUB.S
       ((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) = "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) = "11100") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "001")) or -- FCLASS.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) = "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) = "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) = "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) = "11010") and (execute_engine.i_reg(instr_funct12_lsb_c+4 downto instr_funct12_lsb_c+1) = "0000")) or -- FCVT.S.W*
       ((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
       ((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';
      decode_aux.is_float_op <= '1';
    end if;
    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
Line 869... Line 849...
    -- 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 894... Line 873...
 
 
    -- CSR access --
    -- CSR access --
    csr.we_nxt                  <= '0';
    csr.we_nxt                  <= '0';
    csr.re_nxt                  <= '0';
    csr.re_nxt                  <= '0';
 
 
    -- atomic operations control --
 
    atomic_ctrl.env_start       <= '0';
 
    atomic_ctrl.env_end         <= '0';
 
    atomic_ctrl.env_abort       <= '0';
 
 
 
    -- CONTROL DEFAULTS --
    -- CONTROL DEFAULTS --
    ctrl_nxt <= (others => '0'); -- default: all off
    ctrl_nxt <= (others => '0'); -- default: all off
    -- ALU main control --
    -- ALU main control --
    ctrl_nxt(ctrl_alu_addsub_c) <= '0'; -- ADD(I)
    ctrl_nxt(ctrl_alu_addsub_c) <= '0'; -- ADD(I)
    ctrl_nxt(ctrl_alu_func1_c  downto ctrl_alu_func0_c) <= alu_func_cmd_arith_c; -- default ALU function select: arithmetic
    ctrl_nxt(ctrl_alu_func1_c  downto ctrl_alu_func0_c) <= alu_func_cmd_arith_c; -- default ALU function select: arithmetic
Line 911... Line 885...
    if (execute_engine.i_reg(instr_opcode_lsb_c+4) = '1') then -- ALU ops
    if (execute_engine.i_reg(instr_opcode_lsb_c+4) = '1') then -- ALU ops
      ctrl_nxt(ctrl_alu_unsigned_c) <= execute_engine.i_reg(instr_funct3_lsb_c+0); -- unsigned ALU operation? (SLTIU, SLTU)
      ctrl_nxt(ctrl_alu_unsigned_c) <= execute_engine.i_reg(instr_funct3_lsb_c+0); -- unsigned ALU operation? (SLTIU, SLTU)
    else -- branches
    else -- branches
      ctrl_nxt(ctrl_alu_unsigned_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1); -- unsigned branches? (BLTU, BGEU)
      ctrl_nxt(ctrl_alu_unsigned_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1); -- unsigned branches? (BLTU, BGEU)
    end if;
    end if;
 
    -- bus interface --
 
    ctrl_nxt(ctrl_bus_excl_c) <= ctrl(ctrl_bus_excl_c); -- keep exclusive bus access request alive if set
 
 
 
 
    -- state machine --
    -- state machine --
    case execute_engine.state is
    case execute_engine.state is
 
 
Line 932... Line 908...
 
 
      when DISPATCH => -- Get new command from instruction issue engine
      when DISPATCH => -- Get new command from instruction issue engine
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
        -- housekeeping --
        -- housekeeping --
        execute_engine.is_cp_op_nxt <= '0'; -- init
        execute_engine.is_cp_op_nxt <= '0'; -- init
        execute_engine.is_fp_nxt    <= '0'; -- init
        ctrl_nxt(ctrl_bus_excl_c)   <= '0'; -- clear exclusive data bus access
        -- 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 1062... Line 1038...
            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 | opcode_flw_c | opcode_fsw_c => -- load/store / atomic memory access / floating-point load/store 
          when opcode_load_c | opcode_store_c | opcode_atomic_c => -- load/store / atomic memory access
          -- ------------------------------------------------------------
          -- ------------------------------------------------------------
            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 -- atomic extension disabled
            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
               (execute_engine.i_reg(instr_opcode_lsb_c+3 downto instr_opcode_lsb_c+2) = "00") then  -- 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
 
              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
                execute_engine.state_nxt <= LOADSTORE_0;
                execute_engine.state_nxt <= LOADSTORE_0;
              else -- unimplemented (atomic) instruction
              else -- unimplemented (atomic) instruction
                execute_engine.state_nxt <= SYS_WAIT;
                execute_engine.state_nxt <= SYS_WAIT;
Line 1116... Line 1086...
              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)
          when opcode_fop_c => -- floating-point operations
          -- ------------------------------------------------------------
          -- ------------------------------------------------------------
            execute_engine.state_nxt <= SYS_WAIT;
            if (CPU_EXTENSION_RISCV_Zfinx = true) then
            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
              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
              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;
              ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
              execute_engine.state_nxt                           <= ALU_WAIT;
              execute_engine.state_nxt                           <= ALU_WAIT;
 
            else
 
              execute_engine.state_nxt <= SYS_WAIT;
            end if;
            end if;
 
 
          when others => -- undefined
          when others => -- undefined
          -- ------------------------------------------------------------
          -- ------------------------------------------------------------
            execute_engine.state_nxt <= SYS_WAIT;
            execute_engine.state_nxt <= SYS_WAIT;
Line 1167... Line 1137...
 
 
 
 
      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 1225... Line 1191...
        end if;
        end if;
 
 
 
 
      when LOADSTORE_0 => -- trigger memory request
      when LOADSTORE_0 => -- trigger memory request
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
 
        ctrl_nxt(ctrl_bus_excl_c) <= decode_aux.is_atomic_lr; -- atomic.LR: exclusive memory access request
        if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_atomic_lr = '1') then -- normal load or atomic load-reservate
        if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_atomic_lr = '1') then -- normal load or atomic load-reservate
          ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request
          ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request
        else -- store
        else -- store
          ctrl_nxt(ctrl_bus_wr_c) <= '1'; -- write request
          ctrl_nxt(ctrl_bus_wr_c) <= '1'; -- write request
        end if;
        end if;
Line 1236... Line 1203...
 
 
 
 
      when LOADSTORE_1 => -- memory latency
      when LOADSTORE_1 => -- memory latency
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
        ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- write input data to MDI (only relevant for LOAD)
        ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- write input data to MDI (only relevant for LOAD)
 
        if (CPU_EXTENSION_RISCV_A = true) and (decode_aux.is_atomic_sc = '1') then -- execute and evaluate atomic store-conditional
 
          execute_engine.state_nxt <= ATOMIC_SC_EVAL;
 
        else -- normal load/store
        execute_engine.state_nxt   <= LOADSTORE_2;
        execute_engine.state_nxt   <= LOADSTORE_2;
 
        end if;
 
 
 
 
      when LOADSTORE_2 => -- wait for bus transaction to finish
      when LOADSTORE_2 => -- wait for bus transaction to finish
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
        -- ALU control (only relevant for atomic memory operations) --
 
        if (CPU_EXTENSION_RISCV_A = true) then
 
          ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_atomic_c; -- atomic.SC: result comes from "atomic co-processor"
 
          ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
 
        end if;
 
        -- register file write-back --
 
        if (decode_aux.is_atomic_sc = '1') then
 
          ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU.res (only relevant for atomic.SC)
 
        else
 
          ctrl_nxt(ctrl_rf_in_mux_c) <= '1'; -- RF input = memory input (only relevant for LOADs)
 
        end if;
 
        --
 
        ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for load operations)
        ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for load operations)
 
        ctrl_nxt(ctrl_rf_in_mux_c) <= '1'; -- RF input = memory input (only relevant for LOADs)
        -- wait for memory response --
        -- wait for memory response --
        if ((ma_load_i or be_load_i or ma_store_i or be_store_i) = '1') then -- abort if exception
        if ((ma_load_i or be_load_i or ma_store_i or be_store_i) = '1') then -- abort if exception
          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
 
          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
          -- data write-back
            ctrl_nxt(ctrl_rf_wb_en_c) <= not execute_engine.is_fp; -- allow write back if NOT <FPU-internal operation>
          if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_atomic_lr = '1') then -- normal load OR atomic load
 
            ctrl_nxt(ctrl_rf_wb_en_c) <= '1';
          end if;
          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;
 
          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;
 
 
 
 
 
      when ATOMIC_SC_EVAL => -- wait for bus transaction to finish and evaluate if SC was successful
 
      -- ------------------------------------------------------------
 
        if (CPU_EXTENSION_RISCV_A = true) then
 
          -- atomic.SC: result comes from "atomic co-processor" --
 
          ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_atomic_c;
 
          execute_engine.is_cp_op_nxt                        <= '1'; -- this is a CP operation
 
          ctrl_nxt(ctrl_rf_in_mux_c)                         <= '0'; -- RF input = ALU.res
 
          ctrl_nxt(ctrl_rf_wb_en_c)                          <= '1'; -- allow reg file write back
 
          -- wait for memory response --
 
          if ((ma_load_i or be_load_i or ma_store_i or be_store_i) = '1') then -- abort if exception
 
            ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; -- trigger atomic-coprocessor operation for SC status evaluation
 
            execute_engine.state_nxt <= ALU_WAIT;
 
          elsif (bus_d_wait_i = '0') then -- wait for bus to finish transaction
 
            ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; -- trigger atomic-coprocessor operation for SC status evaluation
 
            execute_engine.state_nxt <= ALU_WAIT;
 
          end if;
 
        else
 
          execute_engine.state_nxt <= SYS_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 1283... Line 1259...
 
 
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
-- Invalid Instruction / CSR access check
-- Invalid Instruction / CSR access check
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
 
 
 
 
  -- CSR Access Check -----------------------------------------------------------------------
  -- CSR Access Check -----------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  csr_access_check: process(execute_engine.i_reg, csr)
  csr_access_check: process(execute_engine.i_reg, csr)
    variable csr_wacc_v           : std_ulogic; -- to check access to read-only CSRs
    variable csr_wacc_v           : std_ulogic; -- to check access to read-only CSRs
--  variable csr_racc_v           : std_ulogic; -- to check access to write-only CSRs
--  variable csr_racc_v           : std_ulogic; -- to check access to write-only CSRs
Line 1312... Line 1287...
    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_fflags_c | csr_frm_c | csr_fcsr_c => csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- full access for everyone if Zfinx 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
Line 1644... Line 1619...
            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)
        when opcode_fop_c => -- floating point operations - single/dual operands
        -- ------------------------------------------------------------
        -- ------------------------------------------------------------
          if (CPU_EXTENSION_RISCV_F = true) and -- F extension enabled
          if (CPU_EXTENSION_RISCV_Zfinx = 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
             (execute_engine.i_reg(instr_funct7_lsb_c+1 downto instr_funct7_lsb_c) = float_single_c) and -- single-precision operations only
             ((decode_aux.is_float_f_reg = '1') or (decode_aux.is_float_i_reg = '1')) then -- float_reg or int_reg operations
             (decode_aux.is_float_op = '1') then -- is correct/supported floating-point instruction
            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';
            illegal_instruction <= '0';
          else
          else
            illegal_instruction <= '1';
            illegal_instruction <= '1';
          end if;
          end if;
 
 
Line 1683... Line 1649...
 
 
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
-- Exception and Interrupt (= Trap) Control
-- Exception and Interrupt (= Trap) Control
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
 
 
 
 
  -- Trap Controller ------------------------------------------------------------------------
  -- Trap Controller ------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  trap_controller: process(rstn_i, clk_i)
  trap_controller: process(rstn_i, clk_i)
    variable mode_m_v, mode_u_v : std_ulogic;
    variable mode_m_v, mode_u_v : std_ulogic;
  begin
  begin
Line 1914... Line 1879...
      trap_ctrl.irq_ack_nxt <= (others => '0');
      trap_ctrl.irq_ack_nxt <= (others => '0');
    end if;
    end if;
  end process trap_priority;
  end process trap_priority;
 
 
 
 
  -- Atomic Memory Access - Status Controller -----------------------------------------------
 
  -- -------------------------------------------------------------------------------------------
 
  atomic_memacc_controller: process(rstn_i, clk_i)
 
  begin
 
    if (rstn_i = '0') then
 
      atomic_ctrl.lock       <= '0';
 
      atomic_ctrl.env_end_ff <= '0';
 
    elsif rising_edge(clk_i) then
 
      if (CPU_EXTENSION_RISCV_A = true) then
 
        if (atomic_ctrl.env_end_ff = '1') or -- normal termination
 
           (atomic_ctrl.env_abort = '1') or  -- fast termination (error)
 
           (trap_ctrl.env_start = '1') then  -- triggered trap -> failure
 
          atomic_ctrl.lock <= '0';
 
        elsif (atomic_ctrl.env_start = '1') then
 
          atomic_ctrl.lock <= '1';
 
        end if;
 
        atomic_ctrl.env_end_ff <= atomic_ctrl.env_end;
 
      else
 
        atomic_ctrl.lock       <= '0';
 
        atomic_ctrl.env_end_ff <= '0';
 
      end if;
 
    end if;
 
  end process atomic_memacc_controller;
 
 
 
 
 
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
-- Control and Status Registers (CSRs)
-- Control and Status Registers (CSRs)
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
 
 
  -- Control and Status Registers Write Data ------------------------------------------------
  -- Control and Status Registers Write Data ------------------------------------------------
Line 2020... Line 1960...
 
 
          -- user floating-point CSRs --
          -- user floating-point CSRs --
          -- --------------------------------------------------------------------
          -- --------------------------------------------------------------------
          if (csr.addr(11 downto 4) = csr_class_float_c) then -- floating point CSR class
          if (csr.addr(11 downto 4) = csr_class_float_c) then -- floating point CSR class
            -- R/W: fflags - floating-point (FPU) exception flags --
            -- 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
            if (csr.addr(3 downto 0) = csr_fflags_c(3 downto 0)) and (CPU_EXTENSION_RISCV_Zfinx = true) then
              csr.fflags <= csr.wdata(4 downto 0);
              csr.fflags <= csr.wdata(4 downto 0);
            end if;
            end if;
            -- R/W: frm - floating-point (FPU) rounding mode --
            -- 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
            if (csr.addr(3 downto 0) = csr_frm_c(3 downto 0)) and (CPU_EXTENSION_RISCV_Zfinx = true) then
              csr.frm <= csr.wdata(2 downto 0);
              csr.frm <= csr.wdata(2 downto 0);
            end if;
            end if;
            -- R/W: fflags - floating-point (FPU) control/status (frm + fflags) --
            -- 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
            if (csr.addr(3 downto 0) = csr_fcsr_c(3 downto 0)) and (CPU_EXTENSION_RISCV_Zfinx = true) then
              csr.frm    <= csr.wdata(7 downto 5);
              csr.frm    <= csr.wdata(7 downto 5);
              csr.fflags <= csr.wdata(4 downto 0);
              csr.fflags <= csr.wdata(4 downto 0);
            end if;
            end if;
          end if;
          end if;
 
 
Line 2168... Line 2108...
        -- --------------------------------------------------------------------------------
        -- --------------------------------------------------------------------------------
        else
        else
 
 
          -- floating-point (FPU) exception flags --
          -- floating-point (FPU) exception flags --
          -- --------------------------------------------------------------------
          -- --------------------------------------------------------------------
          if (CPU_EXTENSION_RISCV_F = true) and (execute_engine.state = ALU_WAIT) then -- FIXME?
          if (CPU_EXTENSION_RISCV_Zfinx = true) and (execute_engine.state = ALU_WAIT) then
            csr.fflags <= csr.fflags or fpu_flags_i; -- accumulate flags ("accrued exception flags")
            csr.fflags <= csr.fflags or fpu_flags_i; -- accumulate flags ("accrued exception flags")
          end if;
          end if;
 
 
          -- mcause, mepc, mtval: machine trap cause, PC and value register --
          -- mcause, mepc, mtval: machine trap cause, PC and value register --
          -- --------------------------------------------------------------------
          -- --------------------------------------------------------------------
Line 2253... Line 2193...
        csr.mcounteren_hpm    <= (others => '0');
        csr.mcounteren_hpm    <= (others => '0');
        csr.mcountinhibit_hpm <= (others => '0');
        csr.mcountinhibit_hpm <= (others => '0');
      end if;
      end if;
 
 
      -- floating-point extension disabled --
      -- floating-point extension disabled --
      if (CPU_EXTENSION_RISCV_F = false) then
      if (CPU_EXTENSION_RISCV_Zfinx = false) then
        csr.fflags <= (others => '0');
        csr.fflags <= (others => '0');
        csr.frm    <= (others => '0');
        csr.frm    <= (others => '0');
      end if;
      end if;
 
 
    end if;
    end if;
Line 2423... Line 2363...
 
 
          -- user floating-point CSRs --
          -- user floating-point CSRs --
          -- --------------------------------------------------------------------
          -- --------------------------------------------------------------------
          when csr_fflags_c => -- R/W: fflags - floating-point (FPU) exception flags
          when csr_fflags_c => -- R/W: fflags - floating-point (FPU) exception flags
            csr.rdata <= (others => '0');
            csr.rdata <= (others => '0');
            if (CPU_EXTENSION_RISCV_F = true) then -- FPU implemented
            if (CPU_EXTENSION_RISCV_Zfinx = true) then -- FPU implemented
              csr.rdata(4 downto 0) <= csr.fflags;
              csr.rdata(4 downto 0) <= csr.fflags;
            end if;
            end if;
          when csr_frm_c => -- R/W: frm - floating-point (FPU) rounding mode
          when csr_frm_c => -- R/W: frm - floating-point (FPU) rounding mode
            csr.rdata <= (others => '0');
            csr.rdata <= (others => '0');
            if (CPU_EXTENSION_RISCV_F = true) then -- FPU implemented
            if (CPU_EXTENSION_RISCV_Zfinx = true) then -- FPU implemented
              csr.rdata(2 downto 0) <= csr.frm;
              csr.rdata(2 downto 0) <= csr.frm;
            end if;
            end if;
          when csr_fcsr_c => -- R/W: fflags - floating-point (FPU) control/status (frm + fflags)
          when csr_fcsr_c => -- R/W: fflags - floating-point (FPU) control/status (frm + fflags)
            csr.rdata <= (others => '0');
            csr.rdata <= (others => '0');
            if (CPU_EXTENSION_RISCV_F = true) then -- FPU implemented
            if (CPU_EXTENSION_RISCV_Zfinx = true) then -- FPU implemented
              csr.rdata(7 downto 5) <= csr.frm;
              csr.rdata(7 downto 5) <= csr.frm;
              csr.rdata(4 downto 0) <= csr.fflags;
              csr.rdata(4 downto 0) <= csr.fflags;
            end if;
            end if;
 
 
          -- machine trap setup --
          -- machine trap setup --
Line 2452... Line 2392...
          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(05) <= '0';                                         -- 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)
Line 2704... Line 2644...
            csr.rdata <= hw_version_c; -- NEORV32 hardware version
            csr.rdata <= hw_version_c; -- NEORV32 hardware version
          when csr_mhartid_c => -- R/-: mhartid - hardware thread ID
          when csr_mhartid_c => -- R/-: mhartid - hardware thread ID
            csr.rdata <= std_ulogic_vector(to_unsigned(HW_THREAD_ID, 32));
            csr.rdata <= std_ulogic_vector(to_unsigned(HW_THREAD_ID, 32));
 
 
          -- custom machine read-only CSRs --
          -- custom machine read-only CSRs --
          when csr_mzext_c => -- R/-: mzext - available RISC-V Z* extensions
          when csr_mzext_c => -- R/-: mzext - available RISC-V Z* sub-extensions
            csr.rdata(0) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr);    -- Zicsr
            csr.rdata(0) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr);    -- Zicsr
            csr.rdata(1) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Zifencei
            csr.rdata(1) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Zifencei
            csr.rdata(2) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B);        -- Zbb
            csr.rdata(2) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B);        -- Zbb (B)
            csr.rdata(3) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B);        -- Zbs
            csr.rdata(3) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B);        -- Zbs (B)
 
            csr.rdata(4) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B);        -- Zba (B)
 
            csr.rdata(5) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx);    -- Zfinx ("F-alternative")
 
 
          -- undefined/unavailable --
          -- undefined/unavailable --
          when others =>
          when others =>
            csr.rdata <= (others => '0'); -- not implemented
            csr.rdata <= (others => '0'); -- not implemented
 
 

powered by: WebSVN 2.1.0

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