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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_control.vhd] - Diff between revs 63 and 64

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

Rev 63 Rev 64
Line 95... Line 95...
    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 interface --
    fpu_flags_i   : in  std_ulogic_vector(04 downto 0); -- exception flags
    fpu_flags_i   : in  std_ulogic_vector(04 downto 0); -- exception flags
    -- debug mode (halt) request --
    -- debug mode (halt) request --
    db_halt_req_i : in  std_ulogic;
    db_halt_req_i : in  std_ulogic;
    -- non-maskable interrupt --
 
    nm_irq_i      : in  std_ulogic;
 
    -- 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 356... Line 354...
    trig_halt    : std_ulogic; -- external request
    trig_halt    : std_ulogic; -- external request
    trig_step    : std_ulogic; -- single-stepping mode
    trig_step    : std_ulogic; -- single-stepping mode
    -- leave debug mode --
    -- leave debug mode --
    dret         : std_ulogic; -- executed DRET instruction
    dret         : std_ulogic; -- executed DRET instruction
    -- misc --
    -- misc --
    ext_halt_req : std_ulogic_vector(1 downto 0); -- rising edge detector for external halt request
    ext_halt_req : std_ulogic;
  end record;
  end record;
  signal debug_ctrl : debug_ctrl_t;
  signal debug_ctrl : debug_ctrl_t;
 
 
  -- (hpm) counter events --
  -- (hpm) counter events --
  signal cnt_event, cnt_event_nxt : std_ulogic_vector(hpmcnt_event_size_c-1 downto 0);
  signal cnt_event, cnt_event_nxt : std_ulogic_vector(hpmcnt_event_size_c-1 downto 0);
Line 688... Line 686...
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  execute_engine_fsm_sync: process(rstn_i, clk_i)
  execute_engine_fsm_sync: process(rstn_i, clk_i)
  begin
  begin
    if (rstn_i = '0') then
    if (rstn_i = '0') then
      -- registers that DO require a specific reset state --
      -- registers that DO require a specific reset state --
      execute_engine.pc       <= CPU_BOOT_ADDR(data_width_c-1 downto 1) & '0';
      execute_engine.pc       <= CPU_BOOT_ADDR(data_width_c-1 downto 2) & "00"; -- 32-bit aligned!
      execute_engine.state    <= SYS_WAIT;
      execute_engine.state    <= SYS_WAIT;
      execute_engine.sleep    <= '0';
      execute_engine.sleep    <= '0';
      execute_engine.branched <= '1'; -- reset is a branch from "somewhere"
      execute_engine.branched <= '1'; -- reset is a branch from "somewhere"
      -- no dedicated RESET required --
      -- no dedicated RESET required --
      execute_engine.state_prev <= SYS_WAIT; -- actual reset value is not relevant
      execute_engine.state_prev <= SYS_WAIT; -- actual reset value is not relevant
Line 799... Line 797...
    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);
    -- 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
    ctrl_o(ctrl_trap_c)  <= trap_ctrl.env_start_ack; -- cpu is starting a trap handler
    ctrl_o(ctrl_trap_c)  <= trap_ctrl.env_start_ack; -- cpu is starting a trap handler
    if (CPU_EXTENSION_RISCV_DEBUG = true) then
 
      ctrl_o(ctrl_debug_running_c) <= debug_ctrl.running; -- cpu is currently in debug mode
      ctrl_o(ctrl_debug_running_c) <= debug_ctrl.running; -- cpu is currently in debug mode
    else
 
      ctrl_o(ctrl_debug_running_c) <= '0';
 
    end if;
 
    -- FPU rounding mode --
    -- FPU rounding mode --
    ctrl_o(ctrl_alu_frm2_c downto ctrl_alu_frm0_c) <= csr.frm;
    ctrl_o(ctrl_alu_frm2_c downto ctrl_alu_frm0_c) <= csr.frm;
  end process ctrl_output;
  end process ctrl_output;
 
 
 
 
Line 1334... Line 1328...
        else
        else
          NULL;
          NULL;
        end if;
        end if;
 
 
      -- machine trap setup & handling --
      -- machine trap setup & handling --
      when csr_mstatus_c | csr_mstatush_c | csr_misa_c | csr_mie_c | csr_mtvec_c | csr_mcounteren_c | csr_mscratch_c | csr_mepc_c | csr_mcause_c =>
      when csr_mstatus_c | csr_mstatush_c | csr_misa_c | csr_mie_c | csr_mtvec_c | csr_mscratch_c | csr_mepc_c | csr_mcause_c | csr_mip_c | csr_mtval_c =>
        csr_acc_valid <= csr.priv_m_mode; -- M-mode only, NOTE: MISA is read-only in the NEORV32 but we do not cause an exception here for compatibility
        -- NOTE: MISA, MIP and MTVAL are read-only in the NEORV32 but we do not cause an exception here for compatibility.
      when csr_mip_c | csr_mtval_c => -- NOTE: MIP and MTVAL are read-only in the NEORV32!
        --       Machine-level code should read-back those CSRs after writing them to realize they are read-only.
        csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
        csr_acc_valid <= csr.priv_m_mode; -- M-mode only 
 
 
 
      when csr_mcounteren_c | csr_menvcfg_c | csr_menvcfgh_c => -- only available if U mode is implemented
 
        csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(CPU_EXTENSION_RISCV_U);
 
 
      -- physical memory protection (PMP) --
      -- physical memory protection (PMP) --
      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  | -- address
      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  | -- address
           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_pmpaddr8_c  | csr_pmpaddr9_c  | csr_pmpaddr10_c | csr_pmpaddr11_c | csr_pmpaddr12_c | csr_pmpaddr13_c | csr_pmpaddr14_c | csr_pmpaddr15_c |
           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_pmpaddr16_c | csr_pmpaddr17_c | csr_pmpaddr18_c | csr_pmpaddr19_c | csr_pmpaddr20_c | csr_pmpaddr21_c | csr_pmpaddr22_c | csr_pmpaddr23_c |
Line 1379... Line 1376...
        else
        else
          NULL;
          NULL;
        end if;
        end if;
 
 
      -- counters/timers --
      -- counters/timers --
      when csr_mcycle_c | csr_minstret_c =>
      when csr_mcycle_c | csr_mcycleh_c | csr_minstret_c | csr_minstreth_c =>
        csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(cpu_cnt_lo_width_c > 0)); -- M-mode only, access valid if really implemented
        csr_acc_valid <= csr.priv_m_mode; -- M-mode only
      when csr_mcycleh_c | csr_minstreth_c =>
      when csr_cycle_c | csr_cycleh_c =>
        csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(cpu_cnt_hi_width_c > 0)); -- M-mode only, access valid if really implemented
        csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- M-mode, U-mode if authorized, read-only
 
      when csr_instret_c | csr_instreth_c =>
      when csr_cycle_c =>
        csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- M-mode, U-mode if authorized, read-only
        csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy) and bool_to_ulogic_f(boolean(cpu_cnt_lo_width_c > 0)); -- M-mode, U-mode if authorized, read-only, access if implemented
 
      when csr_cycleh_c =>
 
        csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy) and bool_to_ulogic_f(boolean(cpu_cnt_hi_width_c > 0)); -- M-mode, U-mode if authorized, read-only, access if implemented
 
      when csr_instret_c =>
 
        csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir) and bool_to_ulogic_f(boolean(cpu_cnt_lo_width_c > 0)); -- M-mode, U-mode if authorized, read-only, access if implemented
 
      when csr_instreth_c =>
 
        csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir) and bool_to_ulogic_f(boolean(cpu_cnt_hi_width_c > 0)); -- M-mode, U-mode if authorized, read-only, access if implemented
 
 
 
      when csr_time_c | csr_timeh_c =>
      when csr_time_c | csr_timeh_c =>
        csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- M-mode, U-mode if authorized, read-only
        csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- M-mode, U-mode if authorized, read-only
 
 
      when csr_mcountinhibit_c =>
      when csr_mcountinhibit_c =>
        csr_acc_valid <= csr.priv_m_mode; -- M-mode only
        csr_acc_valid <= csr.priv_m_mode; -- M-mode only
 
 
 
 
      -- machine information registers, read-only --
      -- machine information registers, read-only --
      when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c | csr_mconfigptr_c =>
      when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c | csr_mconfigptr_c =>
        csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
        csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
 
 
      -- debug mode CSRs --
      -- debug mode CSRs --
Line 1559... Line 1547...
            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) or -- FENCE.I -- NO trap if not implemented
          if ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fencei_c) and (CPU_EXTENSION_RISCV_Zifencei = true)) or -- FENCE.I
             (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fence_c) then -- FENCE
             (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;
Line 1596... Line 1584...
          elsif (execute_engine.i_reg(instr_rd_msb_c  downto instr_rd_lsb_c)  = "00000") and
          elsif (execute_engine.i_reg(instr_rd_msb_c  downto instr_rd_lsb_c)  = "00000") and
                (execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
                (execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
            if (execute_engine.i_reg(instr_funct12_msb_c  downto instr_funct12_lsb_c) = funct12_ecall_c)  or -- ECALL
            if (execute_engine.i_reg(instr_funct12_msb_c  downto instr_funct12_lsb_c) = funct12_ecall_c)  or -- ECALL
               (execute_engine.i_reg(instr_funct12_msb_c  downto instr_funct12_lsb_c) = funct12_ebreak_c) or -- EBREAK 
               (execute_engine.i_reg(instr_funct12_msb_c  downto instr_funct12_lsb_c) = funct12_ebreak_c) or -- EBREAK 
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_mret_c) and (csr.priv_m_mode = '1')) or -- MRET (only allowed in M-mode)
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_mret_c) and (csr.priv_m_mode = '1')) or -- MRET (only allowed in M-mode)
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_dret_c) and (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1')) or -- DRET
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_dret_c) and (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1')) or -- DRET (only allowed in D-mode)
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_wfi_c) and ((csr.priv_m_mode = '1') or (csr.mstatus_tw = '0'))) then -- WFI allowed in M-mode or if mstatus.TW=0
               ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_wfi_c) and ((csr.priv_m_mode = '1') or (csr.mstatus_tw = '0'))) then -- WFI allowed in M-mode or if mstatus.TW=0
              illegal_instruction <= '0';
              illegal_instruction <= '0';
            else
            else
              illegal_instruction <= '1';
              illegal_instruction <= '1';
            end if;
            end if;
Line 1654... Line 1642...
  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
    if (rstn_i = '0') then
    if (rstn_i = '0') then
      trap_ctrl.exc_buf   <= (others => '0');
      trap_ctrl.exc_buf   <= (others => '0');
      trap_ctrl.irq_buf   <= (others => def_rst_val_c);
      trap_ctrl.irq_buf   <= (others => '0');
      trap_ctrl.irq_buf(interrupt_nm_irq_c)   <= '0'; -- NMI
 
      trap_ctrl.irq_buf(interrupt_db_halt_c)  <= '0'; -- enter debug mode
 
      trap_ctrl.irq_buf(interrupt_db_step_c)  <= '0'; -- enter debug mode
 
      trap_ctrl.exc_ack   <= '0';
      trap_ctrl.exc_ack   <= '0';
      trap_ctrl.irq_ack   <= (others => '0');
      trap_ctrl.irq_ack   <= (others => '0');
      trap_ctrl.env_start <= '0';
      trap_ctrl.env_start <= '0';
      trap_ctrl.cause     <= (others => def_rst_val_c);
      trap_ctrl.cause     <= (others => def_rst_val_c);
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      if (CPU_EXTENSION_RISCV_Zicsr = true) then
      if (CPU_EXTENSION_RISCV_Zicsr = true) then
 
 
        -- exception buffer: misaligned load/store/instruction address
        -- exception queue: misaligned load/store/instruction address
        trap_ctrl.exc_buf(exception_lalign_c) <= (trap_ctrl.exc_buf(exception_lalign_c) or ma_load_i)          and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_lalign_c) <= (trap_ctrl.exc_buf(exception_lalign_c) or ma_load_i)          and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_salign_c) <= (trap_ctrl.exc_buf(exception_salign_c) or ma_store_i)         and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_salign_c) <= (trap_ctrl.exc_buf(exception_salign_c) or ma_store_i)         and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_ialign_c) <= (trap_ctrl.exc_buf(exception_ialign_c) or trap_ctrl.instr_ma) and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_ialign_c) <= (trap_ctrl.exc_buf(exception_ialign_c) or trap_ctrl.instr_ma) and (not trap_ctrl.exc_ack);
 
 
        -- exception buffer: load/store/instruction bus access error
        -- exception queue: load/store/instruction bus access error
        trap_ctrl.exc_buf(exception_laccess_c) <= (trap_ctrl.exc_buf(exception_laccess_c) or be_load_i)          and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_laccess_c) <= (trap_ctrl.exc_buf(exception_laccess_c) or be_load_i)          and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_saccess_c) <= (trap_ctrl.exc_buf(exception_saccess_c) or be_store_i)         and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_saccess_c) <= (trap_ctrl.exc_buf(exception_saccess_c) or be_store_i)         and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_iaccess_c) <= (trap_ctrl.exc_buf(exception_iaccess_c) or trap_ctrl.instr_be) and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_iaccess_c) <= (trap_ctrl.exc_buf(exception_iaccess_c) or trap_ctrl.instr_be) and (not trap_ctrl.exc_ack);
 
 
        -- exception buffer: illegal instruction / env call / break point
        -- exception queue: illegal instruction / environment call / break point
        trap_ctrl.exc_buf(exception_m_envcall_c) <= (trap_ctrl.exc_buf(exception_m_envcall_c) or (trap_ctrl.env_call and csr.priv_m_mode)) and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_m_envcall_c) <= (trap_ctrl.exc_buf(exception_m_envcall_c) or (trap_ctrl.env_call and csr.priv_m_mode)) and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_u_envcall_c) <= (trap_ctrl.exc_buf(exception_u_envcall_c) or (trap_ctrl.env_call and csr.priv_u_mode)) and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_u_envcall_c) <= (trap_ctrl.exc_buf(exception_u_envcall_c) or (trap_ctrl.env_call and csr.priv_u_mode)) and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_iillegal_c)  <= (trap_ctrl.exc_buf(exception_iillegal_c)  or trap_ctrl.instr_il)                       and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_iillegal_c)  <= (trap_ctrl.exc_buf(exception_iillegal_c)  or trap_ctrl.instr_il)                       and (not trap_ctrl.exc_ack);
        if (CPU_EXTENSION_RISCV_DEBUG = true) then
        if (CPU_EXTENSION_RISCV_DEBUG = true) then
          trap_ctrl.exc_buf(exception_break_c) <= (trap_ctrl.exc_buf(exception_break_c) or
          trap_ctrl.exc_buf(exception_break_c) <= (trap_ctrl.exc_buf(exception_break_c) or
Line 1693... Line 1678...
        end if;
        end if;
 
 
        -- enter debug mode --
        -- enter debug mode --
        if (CPU_EXTENSION_RISCV_DEBUG = true) then
        if (CPU_EXTENSION_RISCV_DEBUG = true) then
          trap_ctrl.exc_buf(exception_db_break_c) <= (trap_ctrl.exc_buf(exception_db_break_c) or debug_ctrl.trig_break) and (not trap_ctrl.exc_ack);
          trap_ctrl.exc_buf(exception_db_break_c) <= (trap_ctrl.exc_buf(exception_db_break_c) or debug_ctrl.trig_break) and (not trap_ctrl.exc_ack);
          trap_ctrl.irq_buf(interrupt_db_halt_c)  <= (trap_ctrl.irq_buf(interrupt_db_halt_c)  or debug_ctrl.trig_halt)  and (not trap_ctrl.irq_ack(interrupt_db_halt_c));
          trap_ctrl.irq_buf(interrupt_db_halt_c)  <= debug_ctrl.trig_halt;
          trap_ctrl.irq_buf(interrupt_db_step_c)  <= (trap_ctrl.irq_buf(interrupt_db_step_c)  or debug_ctrl.trig_step)  and (not trap_ctrl.irq_ack(interrupt_db_step_c));
          trap_ctrl.irq_buf(interrupt_db_step_c)  <= debug_ctrl.trig_step;
        else
        else
          trap_ctrl.exc_buf(exception_db_break_c) <= '0';
          trap_ctrl.exc_buf(exception_db_break_c) <= '0';
          trap_ctrl.irq_buf(interrupt_db_halt_c)  <= '0';
          trap_ctrl.irq_buf(interrupt_db_halt_c)  <= '0';
          trap_ctrl.irq_buf(interrupt_db_step_c)  <= '0';
          trap_ctrl.irq_buf(interrupt_db_step_c)  <= '0';
        end if;
        end if;
 
 
        -- interrupt buffer: non-maskable interrupt
 
        trap_ctrl.irq_buf(interrupt_nm_irq_c)    <= (trap_ctrl.irq_buf(interrupt_nm_irq_c) or nm_irq_i) and (not trap_ctrl.irq_ack(interrupt_nm_irq_c));
 
        -- interrupt buffer: machine software/external/timer interrupt
        -- interrupt buffer: machine software/external/timer interrupt
        trap_ctrl.irq_buf(interrupt_msw_irq_c)   <= csr.mie_msie and (trap_ctrl.irq_buf(interrupt_msw_irq_c)   or msw_irq_i)   and (not trap_ctrl.irq_ack(interrupt_msw_irq_c));
        trap_ctrl.irq_buf(interrupt_msw_irq_c)   <= csr.mie_msie and msw_irq_i;
        trap_ctrl.irq_buf(interrupt_mext_irq_c)  <= csr.mie_meie and (trap_ctrl.irq_buf(interrupt_mext_irq_c)  or mext_irq_i)  and (not trap_ctrl.irq_ack(interrupt_mext_irq_c));
        trap_ctrl.irq_buf(interrupt_mext_irq_c)  <= csr.mie_meie and mext_irq_i;
        trap_ctrl.irq_buf(interrupt_mtime_irq_c) <= csr.mie_mtie and (trap_ctrl.irq_buf(interrupt_mtime_irq_c) or mtime_irq_i) and (not trap_ctrl.irq_ack(interrupt_mtime_irq_c));
        trap_ctrl.irq_buf(interrupt_mtime_irq_c) <= csr.mie_mtie and mtime_irq_i;
        -- interrupt buffer: NEORV32-specific fast interrupts
        -- interrupt queue: NEORV32-specific fast interrupts
        for i in 0 to 15 loop
        for i in 0 to 15 loop
          trap_ctrl.irq_buf(interrupt_firq_0_c+i) <= csr.mie_firqe(i) and (trap_ctrl.irq_buf(interrupt_firq_0_c+i) or firq_i(i)) and (not trap_ctrl.irq_ack(interrupt_firq_0_c+i));
          trap_ctrl.irq_buf(interrupt_firq_0_c+i) <= csr.mie_firqe(i) and (trap_ctrl.irq_buf(interrupt_firq_0_c+i) or firq_i(i)) and (not trap_ctrl.irq_ack(interrupt_firq_0_c+i));
        end loop;
        end loop;
 
 
        -- trap control --
        -- trap control --
        if (trap_ctrl.env_start = '0') then -- no started trap handler
        if (trap_ctrl.env_start = '0') then -- no started trap handler
          if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and -- trap triggered!
          if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and -- trap triggered!
             ((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP_ENTER))) then -- fire IRQs in EXECUTE or TRAP state only to continue execution even on permanent IRQ
             ((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP_ENTER))) then -- fire IRQs in EXECUTE or TRAP state only to continue execution even on permanent IRQ
            trap_ctrl.cause     <= trap_ctrl.cause_nxt;   -- capture source ID for program (for mcause csr)
            trap_ctrl.cause     <= trap_ctrl.cause_nxt;   -- capture source ID for program (for mcause csr)
            trap_ctrl.exc_ack   <= '1';                   -- clear exception
            trap_ctrl.exc_ack   <= '1';                   -- clear exceptions (no ack mask: these have highest priority and are always evaluated first!)
            trap_ctrl.irq_ack   <= trap_ctrl.irq_ack_nxt; -- clear interrupt with interrupt ACK mask
            trap_ctrl.irq_ack   <= trap_ctrl.irq_ack_nxt; -- clear interrupt with ACK mask
            trap_ctrl.env_start <= '1';                   -- now execute engine can start trap handler
            trap_ctrl.env_start <= '1';                   -- now execute engine can start trap handler
          end if;
          end if;
        else -- trap waiting to get started
        else -- trap waiting to get started
          if (trap_ctrl.env_start_ack = '1') then -- start of trap handler acknowledged by execution engine
          if (trap_ctrl.env_start_ack = '1') then -- start of trap handler acknowledged by execution engine
            trap_ctrl.exc_ack   <= '0';
            trap_ctrl.exc_ack   <= '0';
Line 1734... Line 1717...
    end if;
    end if;
  end process trap_controller;
  end process trap_controller;
 
 
  -- any exception/interrupt? --
  -- any exception/interrupt? --
  trap_ctrl.exc_fire <= or_reduce_f(trap_ctrl.exc_buf); -- exceptions/faults CANNOT be masked
  trap_ctrl.exc_fire <= or_reduce_f(trap_ctrl.exc_buf); -- exceptions/faults CANNOT be masked
  trap_ctrl.irq_fire <= (or_reduce_f(trap_ctrl.irq_buf) and csr.mstatus_mie and trap_ctrl.db_irq_en) or trap_ctrl.db_irq_fire; -- interrupts CAN be masked
  trap_ctrl.irq_fire <= (or_reduce_f(trap_ctrl.irq_buf) and csr.mstatus_mie and trap_ctrl.db_irq_en) or trap_ctrl.db_irq_fire; -- interrupts CAN be masked (but not the DEBUG halt IRQ)
 
 
  -- debug mode (entry) interrupts --
  -- debug mode (entry) interrupts --
  trap_ctrl.db_irq_en   <= '0' when (CPU_EXTENSION_RISCV_DEBUG = true) and ((debug_ctrl.running = '1') or (csr.dcsr_step = '1')) else '1'; -- no interrupts when IN debug mode or IN single-step mode
  trap_ctrl.db_irq_en   <= '0' when (CPU_EXTENSION_RISCV_DEBUG = true) and ((debug_ctrl.running = '1') or (csr.dcsr_step = '1')) else '1'; -- no interrupts when IN debug mode or IN single-step mode
  trap_ctrl.db_irq_fire <= (trap_ctrl.irq_buf(interrupt_db_step_c) or trap_ctrl.irq_buf(interrupt_db_halt_c)) when (CPU_EXTENSION_RISCV_DEBUG = true) else '0'; -- "NMI" for debug mode entry
  trap_ctrl.db_irq_fire <= (trap_ctrl.irq_buf(interrupt_db_step_c) or trap_ctrl.irq_buf(interrupt_db_halt_c)) when (CPU_EXTENSION_RISCV_DEBUG = true) else '0'; -- "NMI" for debug mode entry
 
 
Line 1747... Line 1730...
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  trap_priority: process(trap_ctrl)
  trap_priority: process(trap_ctrl)
  begin
  begin
    -- defaults --
    -- defaults --
    trap_ctrl.cause_nxt   <= (others => '0');
    trap_ctrl.cause_nxt   <= (others => '0');
    trap_ctrl.irq_ack_nxt <= (others => '0');
    trap_ctrl.irq_ack_nxt <= (others => '0'); -- used for internal IRQ queues only
 
 
 
    -- NOTE: Synchronous exceptions (from trap_ctrl.exc_buf) have higher priority than asynchronous
 
    -- exceptions (from trap_ctrl.irq_buf).
 
 
    -- ----------------------------------------------------------------------------------------
    -- ----------------------------------------------------------------------------------------
    -- enter debug mode requests; basically, these are standard interrupt that have some
    -- the following traps are caused by *synchronous* exceptions; here we do not need a
    -- special handling - they have the highest priority in order to go to debug when requested
    -- specific acknowledge mask since only _one_ exception (the one with highest priority)
    -- even if other traps are pending right now; the <trap_ctrl.cause_nxt> value will be
    -- is allowed to kick in at once
    -- written to csr.dcsr_cause instead of mcause
    -- ----------------------------------------------------------------------------------------
 
 
 
    -- exception: 0.0 instruction address misaligned --
 
    if (trap_ctrl.exc_buf(exception_ialign_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_ima_c;
 
 
 
    -- exception: 0.1 instruction access fault --
 
    elsif (trap_ctrl.exc_buf(exception_iaccess_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_iba_c;
 
 
 
    -- exception: 0.2 illegal instruction --
 
    elsif (trap_ctrl.exc_buf(exception_iillegal_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_iil_c;
 
 
 
 
 
    -- exception: 0.11 environment call from M-mode --
 
    elsif (trap_ctrl.exc_buf(exception_m_envcall_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_menv_c;
 
 
 
    -- exception: 0.8 environment call from U-mode --
 
    elsif (trap_ctrl.exc_buf(exception_u_envcall_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_uenv_c;
 
 
 
    -- exception: 0.3 breakpoint --
 
    elsif (trap_ctrl.exc_buf(exception_break_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_brk_c;
 
 
 
 
 
    -- exception: 0.6 store address misaligned -
 
    elsif (trap_ctrl.exc_buf(exception_salign_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_sma_c;
 
 
 
    -- exception: 0.4 load address misaligned --
 
    elsif (trap_ctrl.exc_buf(exception_lalign_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_lma_c;
 
 
 
    -- exception: 0.7 store access fault --
 
    elsif (trap_ctrl.exc_buf(exception_saccess_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_sbe_c;
 
 
 
    -- exception: 0.5 load access fault --
 
    elsif (trap_ctrl.exc_buf(exception_laccess_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_lbe_c;
 
 
 
 
 
    -- ----------------------------------------------------------------------------------------
 
    -- (re-)enter debug mode requests; basically, these are standard traps that have some
 
    -- special handling - they have the highest INTERRUPT priority in order to go to debug when requested
 
    -- even if other IRQs are pending right now
    -- ----------------------------------------------------------------------------------------
    -- ----------------------------------------------------------------------------------------
 
 
    -- break instruction --
    -- break instruction --
    if (CPU_EXTENSION_RISCV_DEBUG = true) and (trap_ctrl.exc_buf(exception_db_break_c) = '1') then
    elsif (CPU_EXTENSION_RISCV_DEBUG = true) and (trap_ctrl.exc_buf(exception_db_break_c) = '1') then
      trap_ctrl.cause_nxt <= trap_db_break_c;
      trap_ctrl.cause_nxt <= trap_db_break_c;
 
 
    -- external halt request --
    -- external halt request --
    elsif (CPU_EXTENSION_RISCV_DEBUG = true) and (trap_ctrl.irq_buf(interrupt_db_halt_c) = '1') then
    elsif (CPU_EXTENSION_RISCV_DEBUG = true) and (trap_ctrl.irq_buf(interrupt_db_halt_c) = '1') then
      trap_ctrl.cause_nxt <= trap_db_halt_c;
      trap_ctrl.cause_nxt <= trap_db_halt_c;
      trap_ctrl.irq_ack_nxt(interrupt_db_halt_c) <= '1';
 
 
    -- single stepping --
 
    elsif (CPU_EXTENSION_RISCV_DEBUG = true) and (trap_ctrl.irq_buf(interrupt_db_step_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_db_step_c;
 
 
 
 
    -- ----------------------------------------------------------------------------------------
    -- ----------------------------------------------------------------------------------------
    -- the following traps are caused by *asynchronous* exceptions (= interrupts)
    -- the following traps are caused by *asynchronous* exceptions (= interrupts)
    -- here we do need a specific acknowledge mask since several sources can trigger at once
 
    -- ----------------------------------------------------------------------------------------
    -- ----------------------------------------------------------------------------------------
 
 
    -- interrupt: 1.0 non-maskable interrupt --
    -- custom FAST interrupt requests --
    elsif (trap_ctrl.irq_buf(interrupt_nm_irq_c) = '1') then
    -- here we do need a specific acknowledge mask for the FIRQs only since they are edge-triggered and internally buffered
      trap_ctrl.cause_nxt <= trap_nmi_c;
 
      trap_ctrl.irq_ack_nxt(interrupt_nm_irq_c) <= '1';
 
 
 
 
 
    -- interrupt: 1.11 machine external interrupt --
 
    elsif (trap_ctrl.irq_buf(interrupt_mext_irq_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_mei_c;
 
      trap_ctrl.irq_ack_nxt(interrupt_mext_irq_c) <= '1';
 
 
 
    -- interrupt: 1.3 machine SW interrupt --
 
    elsif (trap_ctrl.irq_buf(interrupt_msw_irq_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_msi_c;
 
      trap_ctrl.irq_ack_nxt(interrupt_msw_irq_c) <= '1';
 
 
 
    -- interrupt: 1.7 machine timer interrupt --
 
    elsif (trap_ctrl.irq_buf(interrupt_mtime_irq_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_mti_c;
 
      trap_ctrl.irq_ack_nxt(interrupt_mtime_irq_c) <= '1';
 
 
 
 
 
    -- interrupt: 1.16 fast interrupt channel 0 --
    -- interrupt: 1.16 fast interrupt channel 0 --
    elsif (trap_ctrl.irq_buf(interrupt_firq_0_c) = '1') then
    elsif (trap_ctrl.irq_buf(interrupt_firq_0_c) = '1') then
      trap_ctrl.cause_nxt <= trap_firq0_c;
      trap_ctrl.cause_nxt <= trap_firq0_c;
      trap_ctrl.irq_ack_nxt(interrupt_firq_0_c) <= '1';
      trap_ctrl.irq_ack_nxt(interrupt_firq_0_c) <= '1';
Line 1874... Line 1891...
    elsif (trap_ctrl.irq_buf(interrupt_firq_15_c) = '1') then
    elsif (trap_ctrl.irq_buf(interrupt_firq_15_c) = '1') then
      trap_ctrl.cause_nxt <= trap_firq15_c;
      trap_ctrl.cause_nxt <= trap_firq15_c;
      trap_ctrl.irq_ack_nxt(interrupt_firq_15_c) <= '1';
      trap_ctrl.irq_ack_nxt(interrupt_firq_15_c) <= '1';
 
 
 
 
    -- ----------------------------------------------------------------------------------------
    -- standard RISC-V interrupts --
    -- the following traps are caused by *synchronous* exceptions (= 'classic' exceptions)
    -- these will stay asserted until explicitly ACKed by the software - no irq_ack_nxt required
    -- here we do not need a specific acknowledge mask since only one exception (the one
 
    -- with highest priority) is evaluated at once
 
    -- ----------------------------------------------------------------------------------------
 
 
 
    -- exception: 0.1 instruction access fault --
 
    elsif (trap_ctrl.exc_buf(exception_iaccess_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_iba_c;
 
 
 
    -- exception: 0.2 illegal instruction --
    -- interrupt: 1.11 machine external interrupt --
    elsif (trap_ctrl.exc_buf(exception_iillegal_c) = '1') then
    elsif (trap_ctrl.irq_buf(interrupt_mext_irq_c) = '1') then
      trap_ctrl.cause_nxt <= trap_iil_c;
      trap_ctrl.cause_nxt <= trap_mei_c;
 
 
    -- exception: 0.0 instruction address misaligned --
 
    elsif (trap_ctrl.exc_buf(exception_ialign_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_ima_c;
 
 
 
 
 
    -- exception: 0.11 environment call from M-mode --
 
    elsif (trap_ctrl.exc_buf(exception_m_envcall_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_menv_c;
 
 
 
    -- exception: 0.8 environment call from U-mode --
 
    elsif (trap_ctrl.exc_buf(exception_u_envcall_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_uenv_c;
 
 
 
    -- exception: 0.3 breakpoint --
 
    elsif (trap_ctrl.exc_buf(exception_break_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_brk_c;
 
 
 
 
 
    -- exception: 0.6 store address misaligned -
 
    elsif (trap_ctrl.exc_buf(exception_salign_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_sma_c;
 
 
 
    -- exception: 0.4 load address misaligned --
 
    elsif (trap_ctrl.exc_buf(exception_lalign_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_lma_c;
 
 
 
    -- exception: 0.7 store access fault --
 
    elsif (trap_ctrl.exc_buf(exception_saccess_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_sbe_c;
 
 
 
    -- exception: 0.5 load access fault --
 
    elsif (trap_ctrl.exc_buf(exception_laccess_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_lbe_c;
 
 
 
 
    -- interrupt: 1.3 machine SW interrupt --
 
    elsif (trap_ctrl.irq_buf(interrupt_msw_irq_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_msi_c;
 
 
    -- ----------------------------------------------------------------------------------------
    -- interrupt: 1.7 machine timer interrupt --
    -- re-enter debug mode during single-stepping; this debug mode entry trap has the lowest
    elsif (trap_ctrl.irq_buf(interrupt_mtime_irq_c) = '1') then
    -- priority to let "normal" traps kick in during single stepping
      trap_ctrl.cause_nxt <= trap_mti_c;
    -- ----------------------------------------------------------------------------------------
 
 
 
    -- single stepping --
 
    elsif (CPU_EXTENSION_RISCV_DEBUG = true) and (trap_ctrl.irq_buf(interrupt_db_step_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_db_step_c;
 
      trap_ctrl.irq_ack_nxt(interrupt_db_step_c) <= '1';
 
    end if;
    end if;
  end process trap_priority;
  end process trap_priority;
 
 
 
 
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
Line 2075... Line 2049...
            end if;
            end if;
          end if;
          end if;
 
 
          -- machine trap handling --
          -- machine trap handling --
          -- --------------------------------------------------------------------
          -- --------------------------------------------------------------------
          if (csr.addr(11 downto 3) = csr_class_trap_c) then -- machine trap handling CSR class
          if (csr.addr(11 downto 4) = csr_class_trap_c) then -- machine trap handling CSR class
            -- R/W: mscratch - machine scratch register --
            -- R/W: mscratch - machine scratch register --
            if (csr.addr(2 downto 0) = csr_mscratch_c(2 downto 0)) then
            if (csr.addr(3 downto 0) = csr_mscratch_c(3 downto 0)) then
              csr.mscratch <= csr.wdata;
              csr.mscratch <= csr.wdata;
            end if;
            end if;
            -- R/W: mepc - machine exception program counter --
            -- R/W: mepc - machine exception program counter --
            if (csr.addr(2 downto 0) = csr_mepc_c(2 downto 0)) then
            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;
            end if;
            end if;
            -- R/W: mcause - machine trap cause --
            -- R/W: mcause - machine trap cause --
            if (csr.addr(2 downto 0) = csr_mcause_c(2 downto 0)) then
            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
            end if;
            end if;
          end if;
          end if;
 
 
Line 2166... Line 2140...
                  csr.dcsr_prv <= priv_mode_m_c;
                  csr.dcsr_prv <= priv_mode_m_c;
                end if;
                end if;
              end if;
              end if;
              -- R/W: dpc - debug mode program counter --
              -- R/W: dpc - debug mode program counter --
              if (csr.addr(1 downto 0) = csr_dpc_c(1 downto 0)) then
              if (csr.addr(1 downto 0) = csr_dpc_c(1 downto 0)) then
                csr.dpc <= csr.wdata;
                csr.dpc <= csr.wdata(data_width_c-1 downto 1) & '0';
              end if;
              end if;
              -- R/W: dscratch0 - debug mode scratch register 0 --
              -- R/W: dscratch0 - debug mode scratch register 0 --
              if (csr.addr(1 downto 0) = csr_dscratch0_c(1 downto 0)) then
              if (csr.addr(1 downto 0) = csr_dscratch0_c(1 downto 0)) then
                csr.dscratch0 <= csr.wdata;
                csr.dscratch0 <= csr.wdata;
              end if;
              end if;
Line 2209... Line 2183...
              -- trap value --
              -- trap value --
              case trap_ctrl.cause is
              case trap_ctrl.cause is
                when trap_ima_c | trap_iba_c => -- misaligned instruction address OR instruction access error
                when trap_ima_c | trap_iba_c => -- misaligned instruction address OR instruction access error
                  csr.mtval <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- address of faulting instruction
                  csr.mtval <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- address of faulting instruction
                when trap_brk_c => -- breakpoint
                when trap_brk_c => -- breakpoint
                  csr.mtval <= execute_engine.last_pc(data_width_c-1 downto 1) & '0'; -- address of breakpoint instruction
                  csr.mtval <= execute_engine.last_pc; -- address of breakpoint instruction
                when trap_lma_c | trap_lbe_c | trap_sma_c | trap_sbe_c => -- misaligned load/store address OR load/store access error
                when trap_lma_c | trap_lbe_c | trap_sma_c | trap_sbe_c => -- misaligned load/store address OR load/store access error
                  csr.mtval <= mar_i; -- faulting data access address
                  csr.mtval <= mar_i; -- faulting data access address
                when trap_iil_c => -- illegal instruction
                when trap_iil_c => -- illegal instruction
                  csr.mtval <= execute_engine.i_reg_last; -- faulting instruction itself
                  csr.mtval <= execute_engine.i_reg_last; -- faulting instruction itself
                when others => -- everything else including all interrupts
                when others => -- everything else including all interrupts
Line 2535... Line 2509...
 
 
 
 
  -- Control and Status Registers - Read Access ---------------------------------------------
  -- Control and Status Registers - Read Access ---------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  csr_read_access: process(rstn_i, clk_i)
  csr_read_access: process(rstn_i, clk_i)
 
    variable csr_addr_v : std_ulogic_vector(11 downto 0);
  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
        csr_addr_v(11 downto 10) := csr.addr(11 downto 10);
 
        csr_addr_v(09 downto 08) := (others => csr.addr(8)); -- !!! WARNING: MACHINE (11) and USER (00) registers ONLY !!!
 
        csr_addr_v(07 downto 00) := csr.addr(07 downto 00);
 
        case csr_addr_v is
 
 
          -- floating-point CSRs --
          -- floating-point CSRs --
          -- --------------------------------------------------------------------
          -- --------------------------------------------------------------------
          when csr_fflags_c => -- fflags (r/w): floating-point (FPU) exception flags
          when csr_fflags_c => -- fflags (r/w): floating-point (FPU) exception flags
            if (CPU_EXTENSION_RISCV_Zfinx = true) then csr.rdata(4 downto 0) <= csr.fflags; else NULL; end if;
            if (CPU_EXTENSION_RISCV_Zfinx = true) then csr.rdata(4 downto 0) <= csr.fflags; else NULL; end if;
Line 2845... Line 2823...
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  debug_control: process(rstn_i, clk_i)
  debug_control: process(rstn_i, clk_i)
  begin
  begin
    if (rstn_i = '0') then
    if (rstn_i = '0') then
      debug_ctrl.state        <= DEBUG_OFFLINE;
      debug_ctrl.state        <= DEBUG_OFFLINE;
      debug_ctrl.ext_halt_req <= "00";
      debug_ctrl.ext_halt_req <= '0';
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      if (CPU_EXTENSION_RISCV_DEBUG = true) then
      if (CPU_EXTENSION_RISCV_DEBUG = true) then
 
 
        -- rising edge detector --
        -- rising edge detector --
        debug_ctrl.ext_halt_req <= debug_ctrl.ext_halt_req(0) & db_halt_req_i;
        debug_ctrl.ext_halt_req <= db_halt_req_i;
 
 
        -- state machine --
        -- state machine --
        case debug_ctrl.state is
        case debug_ctrl.state is
 
 
          when DEBUG_OFFLINE => -- not in debug mode, waiting for entering request
          when DEBUG_OFFLINE => -- not in debug mode, waiting for entering request
Line 2883... Line 2861...
            debug_ctrl.state <= DEBUG_OFFLINE;
            debug_ctrl.state <= DEBUG_OFFLINE;
 
 
        end case;
        end case;
      else -- debug mode NOT implemented
      else -- debug mode NOT implemented
        debug_ctrl.state        <= DEBUG_OFFLINE;
        debug_ctrl.state        <= DEBUG_OFFLINE;
        debug_ctrl.ext_halt_req <= "00";
        debug_ctrl.ext_halt_req <= '0';
      end if;
      end if;
    end if;
    end if;
  end process debug_control;
  end process debug_control;
 
 
  -- state decoding --
  -- state decoding --
Line 2896... Line 2874...
 
 
  -- entry debug mode triggers --
  -- entry debug mode triggers --
  debug_ctrl.trig_break <= trap_ctrl.break_point and (debug_ctrl.running or -- we are in debug mode: re-enter debug mode
  debug_ctrl.trig_break <= trap_ctrl.break_point and (debug_ctrl.running or -- we are in debug mode: re-enter debug mode
                           (csr.priv_m_mode and csr.dcsr_ebreakm and (not debug_ctrl.running)) or -- enabled goto-debug-mode in machine mode on "ebreak"
                           (csr.priv_m_mode and csr.dcsr_ebreakm and (not debug_ctrl.running)) or -- enabled goto-debug-mode in machine mode on "ebreak"
                           (csr.priv_u_mode and csr.dcsr_ebreaku and (not debug_ctrl.running))); -- enabled goto-debug-mode in user mode on "ebreak"
                           (csr.priv_u_mode and csr.dcsr_ebreaku and (not debug_ctrl.running))); -- enabled goto-debug-mode in user mode on "ebreak"
  debug_ctrl.trig_halt <= (not debug_ctrl.ext_halt_req(1)) and debug_ctrl.ext_halt_req(0) and (not debug_ctrl.running); -- rising edge detector from external halt request (if not halted already)
  debug_ctrl.trig_halt <= debug_ctrl.ext_halt_req and (not debug_ctrl.running); -- external halt request (if not halted already)
  debug_ctrl.trig_step <= csr.dcsr_step and (not debug_ctrl.running); -- single-step mode (trigger when NOT CURRENTLY in debug mode)
  debug_ctrl.trig_step <= csr.dcsr_step and (not debug_ctrl.running); -- single-step mode (trigger when NOT CURRENTLY in debug mode)
 
 
 
 
  -- Debug Control and Status Register (dcsr) - Read-Back -----------------------------------
  -- Debug Control and Status Register (dcsr) - Read-Back -----------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
Line 2921... Line 2899...
    csr.dcsr_rd(10) <= '0'; -- stopcount: counters increment as usual FIXME ???
    csr.dcsr_rd(10) <= '0'; -- stopcount: counters increment as usual FIXME ???
    csr.dcsr_rd(09) <= '0'; -- stoptime: timers increment as usual
    csr.dcsr_rd(09) <= '0'; -- stoptime: timers increment as usual
    csr.dcsr_rd(08 downto 06) <= csr.dcsr_cause; -- debug mode entry cause
    csr.dcsr_rd(08 downto 06) <= csr.dcsr_cause; -- debug mode entry cause
    csr.dcsr_rd(05) <= '0'; -- reserved
    csr.dcsr_rd(05) <= '0'; -- reserved
    csr.dcsr_rd(04) <= '0'; -- mprven: mstatus.mprv is ignored in debug mode
    csr.dcsr_rd(04) <= '0'; -- mprven: mstatus.mprv is ignored in debug mode
    csr.dcsr_rd(03) <= trap_ctrl.irq_buf(interrupt_nm_irq_c); -- nmip: pending non-maskable interrupt
    csr.dcsr_rd(03) <= '0'; -- nmip: pending non-maskable interrupt
    csr.dcsr_rd(02) <= csr.dcsr_step; -- step: single-step mode
    csr.dcsr_rd(02) <= csr.dcsr_step; -- step: single-step mode
    csr.dcsr_rd(01 downto 00) <= csr.dcsr_prv; -- prv: privilege mode when debug mode was entered
    csr.dcsr_rd(01 downto 00) <= csr.dcsr_prv; -- prv: privilege mode when debug mode was entered
  end generate;
  end generate;
 
 
 
 

powered by: WebSVN 2.1.0

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