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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_control.vhd] - Diff between revs 71 and 72

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

Rev 71 Rev 72
Line 5... Line 5...
-- # parallel to implement a simple pipeline:                                                      #
-- # parallel to implement a simple pipeline:                                                      #
-- #  + Fetch engine:   Fetches 32-bit chunks of instruction words                                 #
-- #  + Fetch engine:   Fetches 32-bit chunks of instruction words                                 #
-- #  + Issue engine:   Decodes compressed instructions, aligns and queues instruction words       #
-- #  + Issue engine:   Decodes compressed instructions, aligns and queues instruction words       #
-- #  + Execute engine: Multi-cycle execution of instructions (generate control signals)           #
-- #  + Execute engine: Multi-cycle execution of instructions (generate control signals)           #
-- #  + Trap engine:    Handles interrupts and exceptions                                          #
-- #  + Trap engine:    Handles interrupts and exceptions                                          #
-- #  + CSR module:     Read/write accesses to CSRs & HW counters                                  #
-- #  + CSR module:     Read/write access to control and status registers                          #
-- #  + Debug module:   CPU debug mode handling (on-chip debugger)                                 #
-- #  + Debug module:   CPU debug mode handling (on-chip debugger)                                 #
 
-- #  + Trigger module: Hardware-assisted breakpoints (on-chip debugger)                           #
-- # ********************************************************************************************* #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License                                                                          #
-- # BSD 3-Clause License                                                                          #
-- #                                                                                               #
-- #                                                                                               #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved.                                     #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved.                                     #
-- #                                                                                               #
-- #                                                                                               #
Line 65... Line 66...
    CPU_EXTENSION_RISCV_Zicsr    : boolean; -- implement CSR system?
    CPU_EXTENSION_RISCV_Zicsr    : boolean; -- implement CSR system?
    CPU_EXTENSION_RISCV_Zicntr   : boolean; -- implement base counters?
    CPU_EXTENSION_RISCV_Zicntr   : boolean; -- implement base counters?
    CPU_EXTENSION_RISCV_Zihpm    : boolean; -- implement hardware performance monitors?
    CPU_EXTENSION_RISCV_Zihpm    : boolean; -- implement hardware performance monitors?
    CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
    CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
    CPU_EXTENSION_RISCV_Zmmul    : boolean; -- implement multiply-only M sub-extension?
    CPU_EXTENSION_RISCV_Zmmul    : boolean; -- implement multiply-only M sub-extension?
 
    CPU_EXTENSION_RISCV_Zxcfu    : boolean; -- implement custom (instr.) functions unit?
    CPU_EXTENSION_RISCV_DEBUG    : boolean; -- implement CPU debug mode?
    CPU_EXTENSION_RISCV_DEBUG    : boolean; -- implement CPU debug mode?
    -- Extension Options --
    -- Tuning Options --
 
    FAST_MUL_EN                  : boolean; -- use DSPs for M extension's multiplier
 
    FAST_SHIFT_EN                : boolean; -- use barrel shifter for shift operations
    CPU_CNT_WIDTH                : natural; -- total width of CPU cycle and instret counters (0..64)
    CPU_CNT_WIDTH                : natural; -- total width of CPU cycle and instret counters (0..64)
    CPU_IPB_ENTRIES              : natural; -- entries is instruction prefetch buffer, has to be a power of 2
    CPU_IPB_ENTRIES              : natural; -- entries is instruction prefetch buffer, has to be a power of 2
    -- Physical memory protection (PMP) --
    -- Physical memory protection (PMP) --
    PMP_NUM_REGIONS              : natural; -- number of regions (0..64)
    PMP_NUM_REGIONS              : natural; -- number of regions (0..64)
    PMP_MIN_GRANULARITY          : natural; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
    PMP_MIN_GRANULARITY          : natural; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
Line 342... Line 346...
    dcsr_prv          : std_ulogic_vector(01 downto 0); -- dcsr.prv (R/W): current privilege level when entering debug mode
    dcsr_prv          : std_ulogic_vector(01 downto 0); -- dcsr.prv (R/W): current privilege level when entering debug mode
    dcsr_cause        : std_ulogic_vector(02 downto 0); -- dcsr.cause (R/-): why was debug mode entered
    dcsr_cause        : std_ulogic_vector(02 downto 0); -- dcsr.cause (R/-): why was debug mode entered
    dcsr_rd           : std_ulogic_vector(data_width_c-1 downto 0); -- dcsr (R/(W)): debug mode control and status register
    dcsr_rd           : std_ulogic_vector(data_width_c-1 downto 0); -- dcsr (R/(W)): debug mode control and status register
    dpc               : std_ulogic_vector(data_width_c-1 downto 0); -- dpc (R/W): debug mode program counter
    dpc               : std_ulogic_vector(data_width_c-1 downto 0); -- dpc (R/W): debug mode program counter
    dscratch0         : std_ulogic_vector(data_width_c-1 downto 0); -- dscratch0 (R/W): debug mode scratch register 0
    dscratch0         : std_ulogic_vector(data_width_c-1 downto 0); -- dscratch0 (R/W): debug mode scratch register 0
 
    --
 
    tdata1_exe        : std_ulogic; -- enable (match) trigger
 
    tdata1_rd         : std_ulogic_vector(data_width_c-1 downto 0); -- tdata1 (R/(W)): trigger register read-back
 
    tdata2            : std_ulogic_vector(data_width_c-1 downto 0); -- tdata2 (R/W): address-match register
  end record;
  end record;
  signal csr : csr_t;
  signal csr : csr_t;
 
 
  -- debug mode controller --
  -- debug mode controller --
  type debug_ctrl_state_t is (DEBUG_OFFLINE, DEBUG_PENDING, DEBUG_ONLINE, DEBUG_EXIT);
  type debug_ctrl_state_t is (DEBUG_OFFLINE, DEBUG_PENDING, DEBUG_ONLINE, DEBUG_EXIT);
Line 353... Line 361...
    state        : debug_ctrl_state_t;
    state        : debug_ctrl_state_t;
    -- decoded state --
    -- decoded state --
    running      : std_ulogic; -- debug mode active
    running      : std_ulogic; -- debug mode active
    pending      : std_ulogic; -- waiting to start debug mode
    pending      : std_ulogic; -- waiting to start debug mode
    -- entering triggers --
    -- entering triggers --
 
    trig_hw      : std_ulogic; -- hardware trigger
    trig_break   : std_ulogic; -- ebreak instruction
    trig_break   : std_ulogic; -- ebreak instruction
    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
Line 376... Line 385...
  signal illegal_compressed  : std_ulogic; -- illegal compressed instruction - C-extension
  signal illegal_compressed  : std_ulogic; -- illegal compressed instruction - C-extension
 
 
  -- access (privilege) check --
  -- access (privilege) check --
  signal csr_acc_valid : std_ulogic; -- valid CSR access (implemented and valid access rights)
  signal csr_acc_valid : std_ulogic; -- valid CSR access (implemented and valid access rights)
 
 
 
  -- hardware trigger module --
 
  signal hw_trigger_fire : std_ulogic;
 
 
begin
begin
 
 
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
-- Instruction Fetch (always fetch 32-bit-aligned 32-bit chunks of data)
-- Instruction Fetch (always fetch 32-bit-aligned 32-bit chunks of data)
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
Line 679... Line 691...
  -- Execute Engine FSM Sync ----------------------------------------------------------------
  -- Execute Engine FSM Sync ----------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  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 --
 
      execute_engine.pc         <= CPU_BOOT_ADDR(data_width_c-1 downto 2) & "00"; -- 32-bit aligned!
 
      execute_engine.state      <= SYS_WAIT;
 
      execute_engine.sleep      <= '0';
 
      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
      execute_engine.i_reg      <= (others => def_rst_val_c);
      execute_engine.i_reg      <= (others => def_rst_val_c);
      execute_engine.is_ci      <= def_rst_val_c;
      execute_engine.is_ci      <= def_rst_val_c;
      execute_engine.is_ici     <= def_rst_val_c;
      execute_engine.is_ici     <= def_rst_val_c;
      execute_engine.last_pc    <= (others => def_rst_val_c);
      execute_engine.last_pc    <= (others => def_rst_val_c);
      execute_engine.i_reg_last <= (others => def_rst_val_c);
      execute_engine.i_reg_last <= (others => def_rst_val_c);
      execute_engine.next_pc    <= (others => def_rst_val_c);
      execute_engine.next_pc    <= (others => def_rst_val_c);
      ctrl                      <= (others => def_rst_val_c);
      ctrl                      <= (others => def_rst_val_c);
 
      -- registers that DO require a specific reset state --
 
      execute_engine.pc         <= CPU_BOOT_ADDR(data_width_c-1 downto 2) & "00"; -- 32-bit aligned!
 
      execute_engine.state      <= SYS_WAIT;
 
      execute_engine.sleep      <= '0';
 
      execute_engine.branched   <= '1'; -- reset is a branch from "somewhere"
      ctrl(ctrl_bus_rd_c)       <= '0';
      ctrl(ctrl_bus_rd_c)       <= '0';
      ctrl(ctrl_bus_wr_c)       <= '0';
      ctrl(ctrl_bus_wr_c)       <= '0';
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      -- PC update --
      -- PC update --
      if (execute_engine.pc_we = '1') then
      if (execute_engine.pc_we = '1') then
Line 981... Line 993...
          trap_ctrl.instr_ma        <= cmd_issue.data(33) and (not bool_to_ulogic_f(CPU_EXTENSION_RISCV_C)); -- misaligned instruction fetch address, if C disabled
          trap_ctrl.instr_ma        <= cmd_issue.data(33) and (not bool_to_ulogic_f(CPU_EXTENSION_RISCV_C)); -- misaligned instruction fetch address, if C disabled
          trap_ctrl.instr_be        <= cmd_issue.data(34); -- bus access fault during instruction fetch
          trap_ctrl.instr_be        <= cmd_issue.data(34); -- bus access fault during instruction fetch
          execute_engine.is_ici_nxt <= cmd_issue.data(35); -- invalid decompressed instruction
          execute_engine.is_ici_nxt <= cmd_issue.data(35); -- invalid decompressed instruction
          -- any reason to go to trap state? --
          -- any reason to go to trap state? --
          if (execute_engine.sleep = '1') or -- enter sleep state
          if (execute_engine.sleep = '1') or -- enter sleep state
             (trap_ctrl.exc_fire = '1') or -- exception during LAST instruction (illegal instruction)
             (trap_ctrl.exc_fire = '1') or -- exception during LAST instruction (e.g. illegal instruction)
             (trap_ctrl.env_start = '1') or -- pending trap (IRQ or exception)
             (trap_ctrl.env_start = '1') or -- pending trap (IRQ or exception)
             ((cmd_issue.data(33) = '1') and (CPU_EXTENSION_RISCV_C = false)) or -- misaligned instruction fetch address, if C disabled
             ((cmd_issue.data(33) = '1') and (CPU_EXTENSION_RISCV_C = false)) or -- misaligned instruction fetch address (if C disabled)
             (cmd_issue.data(34) = '1') then -- bus access fault during instruction fetch
             (cmd_issue.data(34) = '1') then -- bus access fault during instruction fetch
            execute_engine.state_nxt <= TRAP_ENTER;
            execute_engine.state_nxt <= TRAP_ENTER;
          else
          else
            execute_engine.state_nxt <= EXECUTE;
            execute_engine.state_nxt <= EXECUTE;
          end if;
          end if;
Line 1125... Line 1137...
            else
            else
              execute_engine.state_nxt <= SYS_WAIT;
              execute_engine.state_nxt <= SYS_WAIT;
            end if;
            end if;
 
 
 
 
 
          when opcode_cust0_c => -- CFU: custom RISC-V instructions (CUSTOM0 OPCODE space)
 
          -- ------------------------------------------------------------
 
            if (CPU_EXTENSION_RISCV_Zxcfu = true) then
 
              ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_cfu_c; -- trigger CFU CP
 
              ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_copro_c;
 
              execute_engine.state_nxt <= ALU_WAIT;
 
            else
 
              execute_engine.state_nxt <= SYS_WAIT;
 
            end if;
 
 
 
 
          when others => -- system/csr access OR illegal opcode - nothing bad (= no commits) will happen here if there is an illegal opcode
          when others => -- system/csr access OR illegal opcode - nothing bad (= no commits) will happen here if there is an illegal opcode
          -- ------------------------------------------------------------
          -- ------------------------------------------------------------
            if (CPU_EXTENSION_RISCV_Zicsr = true) then
            if (CPU_EXTENSION_RISCV_Zicsr = true) then
              if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system/environment
              if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system/environment
                execute_engine.state_nxt <= SYS_ENV;
                execute_engine.state_nxt <= SYS_ENV;
Line 1186... Line 1209...
      when ALU_WAIT => -- wait for multi-cycle ALU operation (co-processor) to finish
      when ALU_WAIT => -- wait for multi-cycle ALU operation (co-processor) to finish
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
        ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_copro_c;
        ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_copro_c;
        -- wait for completion or abort on illegal instruction exception (the co-processor will also terminate operations)
        -- wait for completion or abort on illegal instruction exception (the co-processor will also terminate operations)
        if (alu_idone_i = '1') or (trap_ctrl.exc_buf(exception_iillegal_c) = '1') then
        if (alu_idone_i = '1') or (trap_ctrl.exc_buf(exception_iillegal_c) = '1') then
          ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
          ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back (won't happen in case of an illegal instruction)
          execute_engine.state_nxt  <= DISPATCH;
          execute_engine.state_nxt  <= DISPATCH;
        end if;
        end if;
 
 
 
 
      when BRANCH => -- update PC for taken branches and jumps
      when BRANCH => -- update PC for taken branches and jumps
Line 1294... Line 1317...
           csr_mcycle_c | csr_mcycleh_c | csr_minstret_c | csr_minstreth_c | csr_mcountinhibit_c =>
           csr_mcycle_c | csr_mcycleh_c | csr_minstret_c | csr_minstreth_c | csr_mcountinhibit_c =>
        -- NOTE: MISA and MTVAL are read-only in the NEORV32 but we do not cause an exception here for compatibility.
        -- NOTE: MISA and MTVAL are read-only in the NEORV32 but we do not cause an exception here for compatibility.
        -- Machine-level code should read-back those CSRs after writing them to realize they are read-only.
        -- Machine-level code should read-back those CSRs after writing them to realize they are read-only.
        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 & NEORV32-specific 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_mxisa_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
 
 
      -- user-mode registers --
      -- user-mode registers --
      when csr_mcounteren_c | csr_menvcfg_c | csr_menvcfgh_c =>
      when csr_mcounteren_c | csr_menvcfg_c | csr_menvcfgh_c =>
        csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(CPU_EXTENSION_RISCV_U);
        csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(CPU_EXTENSION_RISCV_U);
Line 1346... Line 1369...
 
 
      -- debug mode CSRs --
      -- debug mode CSRs --
      when csr_dcsr_c | csr_dpc_c | csr_dscratch0_c =>
      when csr_dcsr_c | csr_dpc_c | csr_dscratch0_c =>
        csr_acc_valid <= debug_ctrl.running and bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG); -- access only in debug-mode
        csr_acc_valid <= debug_ctrl.running and bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG); -- access only in debug-mode
 
 
 
      -- trigger module CSRs --
 
      when csr_tselect_c | csr_tdata1_c | csr_tdata2_c | csr_tdata3_c | csr_tinfo_c | csr_tcontrol_c | csr_mcontext_c | csr_scontext_c =>
 
        -- access in debug-mode or M-mode (M-mode: writes are ignored as DMODE is hardwired to 1)
 
        csr_acc_valid <= (debug_ctrl.running or csr.priv_m_mode) and bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG);
 
 
      -- undefined / not implemented --
      -- undefined / not implemented --
      when others =>
      when others =>
        csr_acc_valid <= '0'; -- invalid access
        csr_acc_valid <= '0'; -- invalid access
    end case;
    end case;
  end process csr_access_check;
  end process csr_access_check;
Line 1554... Line 1582...
          else
          else
            illegal_instruction <= '1';
            illegal_instruction <= '1';
          end if;
          end if;
          -- illegal E-CPU register? --
          -- illegal E-CPU register? --
          -- FIXME: rs2 is not checked!
          -- FIXME: rs2 is not checked!
          illegal_register <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c);
          illegal_register <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx) and (execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c));
 
 
 
        when opcode_cust0_c => -- CFU: custom instructions
 
        -- ------------------------------------------------------------
 
          if (CPU_EXTENSION_RISCV_Zxcfu = true) then -- CFU extension implemented
 
            illegal_instruction <= '0';
 
          else
 
            illegal_instruction <= '1';
 
          end if;
 
          -- illegal E-CPU register? --
 
          illegal_register <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zxcfu) and (execute_engine.i_reg(instr_rs2_msb_c) or execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c));
 
 
        when others => -- undefined instruction -> illegal!
        when others => -- undefined instruction -> illegal!
        -- ------------------------------------------------------------
        -- ------------------------------------------------------------
          illegal_instruction <= '1';
          illegal_instruction <= '1';
 
 
Line 1618... Line 1656...
            (trap_ctrl.break_point and csr.priv_u_mode and (not csr.dcsr_ebreaku) and (not debug_ctrl.running))); -- break to machine-trap-handler when in user mode on "ebreak"
            (trap_ctrl.break_point and csr.priv_u_mode and (not csr.dcsr_ebreaku) and (not debug_ctrl.running))); -- break to machine-trap-handler when in user mode on "ebreak"
        else
        else
          trap_ctrl.exc_buf(exception_break_c) <= (trap_ctrl.exc_buf(exception_break_c) or trap_ctrl.break_point) and (not trap_ctrl.exc_clr);
          trap_ctrl.exc_buf(exception_break_c) <= (trap_ctrl.exc_buf(exception_break_c) or trap_ctrl.break_point) and (not trap_ctrl.exc_clr);
        end if;
        end if;
 
 
        -- exception/interrupt buffer: enter debug mode --
        -- exception queue / interrupt buffer: enter debug mode --
        trap_ctrl.exc_buf(exception_db_break_c) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG) and (trap_ctrl.exc_buf(exception_db_break_c) or debug_ctrl.trig_break) and (not trap_ctrl.exc_clr);
        trap_ctrl.exc_buf(exception_db_break_c) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG) and (trap_ctrl.exc_buf(exception_db_break_c) or debug_ctrl.trig_break) and (not trap_ctrl.exc_clr);
 
        trap_ctrl.exc_buf(exception_db_hw_c)    <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG) and (trap_ctrl.exc_buf(exception_db_hw_c)    or debug_ctrl.trig_hw)    and (not trap_ctrl.exc_clr);
        trap_ctrl.irq_buf(interrupt_db_halt_c)  <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG) and debug_ctrl.trig_halt;
        trap_ctrl.irq_buf(interrupt_db_halt_c)  <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG) and debug_ctrl.trig_halt;
        trap_ctrl.irq_buf(interrupt_db_step_c)  <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG) and debug_ctrl.trig_step;
        trap_ctrl.irq_buf(interrupt_db_step_c)  <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG) and debug_ctrl.trig_step;
 
 
        -- 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 msw_irq_i;
        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 mext_irq_i;
        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 mtime_irq_i;
        trap_ctrl.irq_buf(interrupt_mtime_irq_c) <= csr.mie_mtie and mtime_irq_i;
 
 
        -- interrupt queue: NEORV32-specific fast interrupts (FIRQ) --
        -- interrupt *queue*: NEORV32-specific fast interrupts (FIRQ) - require manual ACK/clear --
        trap_ctrl.irq_buf(interrupt_firq_15_c downto interrupt_firq_0_c) <= (trap_ctrl.irq_buf(interrupt_firq_15_c downto interrupt_firq_0_c) or (csr.mie_firqe and firq_i)) and (not csr.mip_clr);
        trap_ctrl.irq_buf(interrupt_firq_15_c downto interrupt_firq_0_c) <= (trap_ctrl.irq_buf(interrupt_firq_15_c downto interrupt_firq_0_c) or (csr.mie_firqe and firq_i)) and (not csr.mip_clr);
 
 
        -- trap environment control --
        -- trap environment 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 -- exception triggered!
          if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and -- exception triggered!
Line 1716... Line 1755...
    -- (re-)enter debug mode requests: basically, these are standard traps that have some
    -- (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
    -- special handling - they have the highest INTERRUPT priority in order to go to debug when requested
    -- even if other IRQs are pending right now
    -- even if other IRQs are pending right now
    -- ----------------------------------------------------------------------------------------
    -- ----------------------------------------------------------------------------------------
 
 
 
    -- hardware trigger (sync) --
 
    elsif (trap_ctrl.exc_buf(exception_db_hw_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_db_hw_c;
 
 
    -- break instruction (sync) --
    -- break instruction (sync) --
    elsif (trap_ctrl.exc_buf(exception_db_break_c) = '1') then
    elsif (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 (async) --
    -- external halt request (async) --
Line 1889... Line 1932...
      csr.dcsr_step         <= '0';
      csr.dcsr_step         <= '0';
      csr.dcsr_prv          <= (others => def_rst_val_c);
      csr.dcsr_prv          <= (others => def_rst_val_c);
      csr.dcsr_cause        <= (others => def_rst_val_c);
      csr.dcsr_cause        <= (others => def_rst_val_c);
      csr.dpc               <= (others => def_rst_val_c);
      csr.dpc               <= (others => def_rst_val_c);
      csr.dscratch0         <= (others => def_rst_val_c);
      csr.dscratch0         <= (others => def_rst_val_c);
 
      --
 
      csr.tdata1_exe        <= '0';
 
      csr.tdata2            <= (others => def_rst_val_c);
 
 
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      -- write access? --
      -- write access? --
      csr.we <= csr.we_nxt;
      csr.we <= csr.we_nxt;
 
 
Line 2059... Line 2105...
                csr.dscratch0 <= csr.wdata;
                csr.dscratch0 <= csr.wdata;
              end if;
              end if;
            end if;
            end if;
          end if;
          end if;
 
 
 
          -- trigger module CSRs - only writable in DEBUG MODE (dmode == 1) --
 
          -- --------------------------------------------------------------------
 
          if (CPU_EXTENSION_RISCV_DEBUG = true) then
 
            if (csr.addr(11 downto 4) = csr_class_trigger_c) then -- trigger CSR class
 
              if (debug_ctrl.running = '1') then -- actual write only in debug mode
 
                -- R/W: tdata1 - match control --
 
                if (csr.addr(3 downto 0) = csr_tdata1_c(3 downto 0)) then
 
                  csr.tdata1_exe <= csr.wdata(2);
 
                end if;
 
                -- R/W: tdata2 - address compare --
 
                if (csr.addr(3 downto 0) = csr_tdata2_c(3 downto 0)) then
 
                  csr.tdata2 <= csr.wdata(data_width_c-1 downto 1) & '0';
 
                end if;
 
              end if;
 
            end if;
 
          end if;
 
 
 
 
        -- --------------------------------------------------------------------------------
        -- --------------------------------------------------------------------------------
        -- CSR access by hardware
        -- CSR access by hardware
        -- --------------------------------------------------------------------------------
        -- --------------------------------------------------------------------------------
        else
        else
Line 2212... Line 2275...
        csr.dcsr_cause   <= (others => '0');
        csr.dcsr_cause   <= (others => '0');
        csr.dpc          <= (others => '0');
        csr.dpc          <= (others => '0');
        csr.dscratch0    <= (others => '0');
        csr.dscratch0    <= (others => '0');
      end if;
      end if;
 
 
 
      -- trigger module disabled --
 
      if (CPU_EXTENSION_RISCV_DEBUG = false) then
 
        csr.tdata1_exe <= '0';
 
        csr.tdata2     <= (others => '0');
 
      end if;
 
 
    end if;
    end if;
  end process csr_write_access;
  end process csr_write_access;
 
 
  -- decode current privilege mode --
  -- decode current privilege mode --
  csr.privilege_rd <= priv_mode_m_c when (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1') else csr.privilege; -- effective privilege mode ("machine" when in debug mode)
  csr.privilege_rd <= priv_mode_m_c when (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1') else csr.privilege; -- effective privilege mode ("machine" when in debug mode)
Line 2268... Line 2337...
      -- [m]cycle --
      -- [m]cycle --
      if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
      if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
        csr.mcycle_ovfl(0) <= csr.mcycle_nxt(csr.mcycle_nxt'left) and (not csr.mcountinhibit_cy);
        csr.mcycle_ovfl(0) <= csr.mcycle_nxt(csr.mcycle_nxt'left) and (not csr.mcountinhibit_cy);
        if (csr.we = '1') and (csr.addr = csr_mcycle_c) then -- write access
        if (csr.we = '1') and (csr.addr = csr_mcycle_c) then -- write access
          csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
          csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
        elsif (csr.mcountinhibit_cy = '0') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update
        elsif (csr.mcountinhibit_cy = '0') and (cnt_event(hpmcnt_event_cy_c) = '1') and (debug_ctrl.running = '0') then -- non-inhibited automatic update and not in debug mode
          csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.mcycle_nxt(cpu_cnt_lo_width_c-1 downto 0);
          csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.mcycle_nxt(cpu_cnt_lo_width_c-1 downto 0);
        end if;
        end if;
      else
      else
        csr.mcycle <= (others => '-');
        csr.mcycle <= (others => '-');
        csr.mcycle_ovfl(0) <= '-';
        csr.mcycle_ovfl(0) <= '-';
Line 2293... Line 2362...
      -- [m]instret --
      -- [m]instret --
      if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
      if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
        csr.minstret_ovfl(0) <= csr.minstret_nxt(csr.minstret_nxt'left) and (not csr.mcountinhibit_ir);
        csr.minstret_ovfl(0) <= csr.minstret_nxt(csr.minstret_nxt'left) and (not csr.mcountinhibit_ir);
        if (csr.we = '1') and (csr.addr = csr_minstret_c) then -- write access
        if (csr.we = '1') and (csr.addr = csr_minstret_c) then -- write access
          csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
          csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
        elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') then -- non-inhibited automatic update
        elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') and (debug_ctrl.running = '0') then -- non-inhibited automatic update and not in debug mode
          csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.minstret_nxt(cpu_cnt_lo_width_c-1 downto 0);
          csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.minstret_nxt(cpu_cnt_lo_width_c-1 downto 0);
        end if;
        end if;
      else
      else
        csr.minstret <= (others => '-');
        csr.minstret <= (others => '-');
        csr.minstret_ovfl(0) <= '-';
        csr.minstret_ovfl(0) <= '-';
Line 2387... Line 2456...
      -- enable selected triggers by ANDing actual events and according CSR configuration bits --
      -- enable selected triggers by ANDing actual events and according CSR configuration bits --
      -- OR everything to see if counter should increment --
      -- OR everything to see if counter should increment --
      hpmcnt_trigger <= (others => '0'); -- default
      hpmcnt_trigger <= (others => '0'); -- default
      if (HPM_NUM_CNTS /= 0) then
      if (HPM_NUM_CNTS /= 0) then
        for i in 0 to HPM_NUM_CNTS-1 loop
        for i in 0 to HPM_NUM_CNTS-1 loop
          hpmcnt_trigger(i) <= or_reduce_f(cnt_event and csr.mhpmevent(i)(cnt_event'left downto 0));
          -- do not increment if CPU is in debug mode --
 
          hpmcnt_trigger(i) <= or_reduce_f(cnt_event and csr.mhpmevent(i)(cnt_event'left downto 0)) and (not debug_ctrl.running);
        end loop; -- i
        end loop; -- i
      end if;
      end if;
    end if;
    end if;
  end process hpmcnt_ctrl;
  end process hpmcnt_ctrl;
 
 
Line 2714... Line 2784...
          -- --------------------------------------------------------------------
          -- --------------------------------------------------------------------
          when csr_dcsr_c      => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= csr.dcsr_rd;   else NULL; end if; -- dcsr (r/w): debug mode control and status
          when csr_dcsr_c      => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= csr.dcsr_rd;   else NULL; end if; -- dcsr (r/w): debug mode control and status
          when csr_dpc_c       => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= csr.dpc;       else NULL; end if; -- dpc (r/w): debug mode program counter
          when csr_dpc_c       => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= csr.dpc;       else NULL; end if; -- dpc (r/w): debug mode program counter
          when csr_dscratch0_c => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= csr.dscratch0; else NULL; end if; -- dscratch0 (r/w): debug mode scratch register 0
          when csr_dscratch0_c => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= csr.dscratch0; else NULL; end if; -- dscratch0 (r/w): debug mode scratch register 0
 
 
 
          -- trigger module CSRs --
 
          -- --------------------------------------------------------------------
 
--        when csr_tselect_c  => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= (others => '0'); else NULL; end if; -- tselect (r/w): always zero = only 1 trigger available
 
          when csr_tdata1_c   => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= csr.tdata1_rd;   else NULL; end if; -- tdata1 (r/w): match control
 
          when csr_tdata2_c   => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= csr.tdata2;      else NULL; end if; -- tdata2 (r/w): address-compare
 
--        when csr_tdata3_c   => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= (others => '0'); else NULL; end if; -- tdata3 (r/w): implemented but always zero
 
          when csr_tinfo_c    => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= x"00000004";     else NULL; end if; -- tinfo (r/w): address-match trigger only
 
--        when csr_tcontrol_c => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= (others => '0'); else NULL; end if; -- tcontrol (r/w): implemented but always zero
 
--        when csr_mcontext_c => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= (others => '0'); else NULL; end if; -- mcontext (r/w): implemented but always zero
 
--        when csr_scontext_c => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= (others => '0'); else NULL; end if; -- scontext (r/w): implemented but always zero
 
 
 
          -- NEORV32-specific (RISC-V "custom") read-only CSRs --
 
          -- --------------------------------------------------------------------
 
          -- machine extended ISA extensions information --
 
          when csr_mxisa_c =>
 
            -- ISA (sub-)extensions --
 
            csr.rdata(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr);    -- Zicsr: privileged architecture (!!!)
 
            csr.rdata(01) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Zifencei: instruction stream sync.
 
            csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zmmul);    -- Zmmul: mul/div
 
            csr.rdata(03) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zxcfu);    -- Zxcfu: custom RISC-V instructions
 
            csr.rdata(04) <= '0'; -- reserved
 
            csr.rdata(05) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx);    -- Zfinx: FPU using x registers, "F-alternative"
 
            csr.rdata(06) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicntr) and
 
                             bool_to_ulogic_f(boolean(CPU_CNT_WIDTH /= 64)); -- Zxscnt: reduced-size CPU counters (from Zicntr)
 
            csr.rdata(07) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicntr);   -- Zicntr: base instructions, cycle and time CSRs
 
            csr.rdata(08) <= bool_to_ulogic_f(boolean(PMP_NUM_REGIONS > 0)); -- PMP: physical memory protection (Zspmp)
 
            csr.rdata(09) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zihpm);    -- Zihpm: hardware performance monitors
 
            csr.rdata(10) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG);    -- RISC-V debug mode
 
            -- ISA options --
 
            csr.rdata(30) <= bool_to_ulogic_f(FAST_MUL_EN);                  -- DSP-based multiplication (M extensions only)
 
            csr.rdata(31) <= bool_to_ulogic_f(FAST_SHIFT_EN);                -- parallel logic for shifts (barrel shifters)
 
 
          -- undefined/unavailable --
          -- undefined/unavailable --
          -- --------------------------------------------------------------------
          -- --------------------------------------------------------------------
          when others =>
          when others =>
            NULL; -- not implemented, read as zero
            NULL; -- not implemented, read as zero
 
 
Line 2751... Line 2853...
        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
            if (debug_ctrl.trig_halt = '1') or -- external request (from DM)
            if (debug_ctrl.trig_halt = '1') or -- external request (from DM)
               (debug_ctrl.trig_break = '1') or -- ebreak instruction
               (debug_ctrl.trig_break = '1') or -- ebreak instruction
 
               (debug_ctrl.trig_hw = '1') or     -- hardware trigger module
               (debug_ctrl.trig_step = '1') then -- single-stepping mode
               (debug_ctrl.trig_step = '1') then -- single-stepping mode
              debug_ctrl.state <= DEBUG_PENDING;
              debug_ctrl.state <= DEBUG_PENDING;
            end if;
            end if;
 
 
          when DEBUG_PENDING => -- waiting to start debug mode
          when DEBUG_PENDING => -- waiting to start debug mode
Line 2786... Line 2889...
  -- state decoding --
  -- state decoding --
  debug_ctrl.pending <= '1' when (debug_ctrl.state = DEBUG_PENDING) and (CPU_EXTENSION_RISCV_DEBUG = true) else '0';
  debug_ctrl.pending <= '1' when (debug_ctrl.state = DEBUG_PENDING) and (CPU_EXTENSION_RISCV_DEBUG = true) else '0';
  debug_ctrl.running <= '1' when ((debug_ctrl.state = DEBUG_ONLINE) or (debug_ctrl.state = DEBUG_EXIT)) and (CPU_EXTENSION_RISCV_DEBUG = true) else '0';
  debug_ctrl.running <= '1' when ((debug_ctrl.state = DEBUG_ONLINE) or (debug_ctrl.state = DEBUG_EXIT)) and (CPU_EXTENSION_RISCV_DEBUG = true) else '0';
 
 
  -- 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_hw    <= hw_trigger_fire and (not debug_ctrl.running); -- enter debug mode by HW trigger module request
 
  debug_ctrl.trig_break <= trap_ctrl.break_point and (debug_ctrl.running or -- 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 <= debug_ctrl.ext_halt_req and (not debug_ctrl.running); -- 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)
 
 
Line 2802... Line 2906...
  csr.dcsr_rd(15) <= csr.dcsr_ebreakm; -- ebreakm: what happens on ebreak in m-mode? (normal trap OR debug-enter)
  csr.dcsr_rd(15) <= csr.dcsr_ebreakm; -- ebreakm: what happens on ebreak in m-mode? (normal trap OR debug-enter)
  csr.dcsr_rd(14) <= '0'; -- ebreakh: hypervisor mode not implemented
  csr.dcsr_rd(14) <= '0'; -- ebreakh: hypervisor mode not implemented
  csr.dcsr_rd(13) <= '0'; -- ebreaks: supervisor mode not implemented
  csr.dcsr_rd(13) <= '0'; -- ebreaks: supervisor mode not implemented
  csr.dcsr_rd(12) <= csr.dcsr_ebreaku when (CPU_EXTENSION_RISCV_U = true) else '0'; -- ebreaku: what happens on ebreak in u-mode? (normal trap OR debug-enter)
  csr.dcsr_rd(12) <= csr.dcsr_ebreaku when (CPU_EXTENSION_RISCV_U = true) else '0'; -- ebreaku: what happens on ebreak in u-mode? (normal trap OR debug-enter)
  csr.dcsr_rd(11) <= '0'; -- stepie: interrupts are disabled during single-stepping
  csr.dcsr_rd(11) <= '0'; -- stepie: interrupts are disabled during single-stepping
  csr.dcsr_rd(10) <= '0'; -- stopcount: counters increment as usual FIXME/TODO ???
  csr.dcsr_rd(10)           <= '1'; -- stopcount: standard counters and HPMs are stopped when in debug mode
  csr.dcsr_rd(09) <= '0'; -- stoptime: timers increment as usual FIXME/TODO ???
  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) <= '0'; -- nmip: no pending non-maskable interrupt
  csr.dcsr_rd(03) <= '0'; -- nmip: no 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
 
 
 
 
 
-- ****************************************************************************************************************************
 
-- Hardware Trigger Module (Part of the On-Chip Debugger)
 
-- ****************************************************************************************************************************
 
 
 
  -- trigger to enter debug-mode: instruction address match (fire AFTER execution) --
 
  hw_trigger_fire <= '1' when (CPU_EXTENSION_RISCV_DEBUG = true) and (csr.tdata1_exe = '1') and
 
                              (csr.tdata2(data_width_c-1 downto 1) = execute_engine.pc(data_width_c-1 downto 1)) else '0';
 
 
 
 
 
  -- Match Control CSR (mcontrol @ tdata1) - Read-Back --------------------------------------
 
  -- -------------------------------------------------------------------------------------------
 
  csr.tdata1_rd(31 downto 28) <= "0010"; -- type: address(/data) match trigger
 
  csr.tdata1_rd(27)           <= '1'; -- dmode: only debug-mode can write tdata* registers
 
  csr.tdata1_rd(26 downto 21) <= "000000"; -- maskmax: only exact values
 
  csr.tdata1_rd(20)           <= '0'; -- hit: feature not implemented
 
  csr.tdata1_rd(19)           <= '0'; -- select: fire on address match
 
  csr.tdata1_rd(18)           <= '1'; -- timing: trigger **after** executing the triggering instruction
 
  csr.tdata1_rd(17 downto 16) <= "00"; -- sizelo: match against an access of any size
 
  csr.tdata1_rd(15 downto 12) <= "0001"; -- action: enter debug mode on trigger
 
  csr.tdata1_rd(11)           <= '0'; -- chain: chaining not supported - there is only one trigger
 
  csr.tdata1_rd(10 downto 07) <= "0000"; -- match: only full-address-match
 
  csr.tdata1_rd(6)            <= '1'; -- m: trigger enabled when in machine mode
 
  csr.tdata1_rd(5)            <= '0'; -- h: hypervisor mode not supported
 
  csr.tdata1_rd(4)            <= '0'; -- s: supervisor mode not supported
 
  csr.tdata1_rd(3)            <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U); -- u: trigger enabled when in user mode
 
  csr.tdata1_rd(2)            <= csr.tdata1_exe; -- execute: enable trigger
 
  csr.tdata1_rd(1)            <= '0'; -- store: store address or data matching not supported
 
  csr.tdata1_rd(0)            <= '0'; -- load: load address or data matching not supported
 
 
 
 
end neorv32_cpu_control_rtl;
end neorv32_cpu_control_rtl;
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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