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

Subversion Repositories neorv32

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

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

Rev 13 Rev 14
Line 75... Line 75...
    curr_pc_o     : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC (corresponding to current instruction)
    curr_pc_o     : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC (corresponding to current instruction)
    next_pc_o     : out std_ulogic_vector(data_width_c-1 downto 0); -- next PC (corresponding to current instruction)
    next_pc_o     : out std_ulogic_vector(data_width_c-1 downto 0); -- next PC (corresponding to current instruction)
    -- csr data interface --
    -- csr data interface --
    csr_wdata_i   : in  std_ulogic_vector(data_width_c-1 downto 0); -- CSR write data
    csr_wdata_i   : in  std_ulogic_vector(data_width_c-1 downto 0); -- CSR write data
    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
    -- external interrupt --
    -- interrupts (risc-v compliant) --
    msw_irq_i     : in  std_ulogic; -- software interrupt
    msw_irq_i     : in  std_ulogic; -- machine software interrupt
    clic_irq_i    : in  std_ulogic; -- CLIC interrupt request
    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) --
 
    firq_i        : in  std_ulogic_vector(3 downto 0);
    -- system time input from MTIME --
    -- system time input from MTIME --
    time_i        : in  std_ulogic_vector(63 downto 0); -- current system time
    time_i        : in  std_ulogic_vector(63 downto 0); -- current system time
    -- bus access exceptions --
    -- bus access exceptions --
    mar_i         : in  std_ulogic_vector(data_width_c-1 downto 0);  -- memory address register
    mar_i         : in  std_ulogic_vector(data_width_c-1 downto 0);  -- memory address register
    ma_instr_i    : in  std_ulogic; -- misaligned instruction address
    ma_instr_i    : in  std_ulogic; -- misaligned instruction address
Line 166... Line 168...
    irq_buf       : std_ulogic_vector(interrupt_width_c-1 downto 0);
    irq_buf       : std_ulogic_vector(interrupt_width_c-1 downto 0);
    irq_fire      : std_ulogic; -- set if there is a valid source in the interrupt buffer
    irq_fire      : std_ulogic; -- set if there is a valid source in the interrupt buffer
    exc_ack       : std_ulogic; -- acknowledge all exceptions
    exc_ack       : std_ulogic; -- acknowledge all exceptions
    irq_ack       : std_ulogic_vector(interrupt_width_c-1 downto 0); -- acknowledge specific interrupt
    irq_ack       : std_ulogic_vector(interrupt_width_c-1 downto 0); -- acknowledge specific interrupt
    irq_ack_nxt   : std_ulogic_vector(interrupt_width_c-1 downto 0);
    irq_ack_nxt   : std_ulogic_vector(interrupt_width_c-1 downto 0);
    cause         : std_ulogic_vector(4 downto 0); -- trap ID (for "mcause"), only for hw
    cause         : std_ulogic_vector(5 downto 0); -- trap ID (for "mcause"), only for hw
    cause_nxt     : std_ulogic_vector(4 downto 0);
    cause_nxt     : std_ulogic_vector(5 downto 0);
    --
    --
    env_start     : std_ulogic; -- start trap handler env
    env_start     : std_ulogic; -- start trap handler env
    env_start_ack : std_ulogic; -- start of trap handler acknowledged
    env_start_ack : std_ulogic; -- start of trap handler acknowledged
    env_end       : std_ulogic; -- end trap handler env
    env_end       : std_ulogic; -- end trap handler env
    --
    --
Line 197... Line 199...
    re_nxt       : std_ulogic;
    re_nxt       : std_ulogic;
    mstatus_mie  : std_ulogic; -- mstatus.MIE: global IRQ enable (R/W)
    mstatus_mie  : std_ulogic; -- mstatus.MIE: global IRQ enable (R/W)
    mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/-)
    mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/-)
    mie_msie     : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W)
    mie_msie     : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W)
    mie_meie     : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W)
    mie_meie     : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W)
    mie_mtie     : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W)
    mie_mtie     : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W
 
    mie_firqe    : std_ulogic_vector(3 downto 0); -- mie.firq*e: fast interrupt enabled (R/W)
    mepc         : std_ulogic_vector(data_width_c-1 downto 0); -- mepc: machine exception pc (R/W)
    mepc         : std_ulogic_vector(data_width_c-1 downto 0); -- mepc: machine exception pc (R/W)
    mcause       : std_ulogic_vector(data_width_c-1 downto 0); -- mcause: machine trap cause (R/W)
    mcause       : std_ulogic_vector(data_width_c-1 downto 0); -- mcause: machine trap cause (R/-)
    mtvec        : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W), bit 1:0 == 00
    mtvec        : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W), bit 1:0 == 00
    mtval        : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/W)
    mtval        : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/W)
    mscratch     : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W)
    mscratch     : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W)
    mcycle       : std_ulogic_vector(32 downto 0); -- mcycle (R/W), plus carry bit
    mcycle       : std_ulogic_vector(32 downto 0); -- mcycle (R/W), plus carry bit
    minstret     : std_ulogic_vector(32 downto 0); -- minstret (R/W), plus carry bit
    minstret     : std_ulogic_vector(32 downto 0); -- minstret (R/W), plus carry bit
Line 631... Line 634...
        if (ipb.avail = '1') then -- instruction available?
        if (ipb.avail = '1') then -- instruction available?
          ipb.re <= '1';
          ipb.re <= '1';
          trap_ctrl.instr_ma <= ipb.rdata(33); -- misaligned instruction fetch address
          trap_ctrl.instr_ma <= ipb.rdata(33); -- misaligned instruction fetch address
          trap_ctrl.instr_be <= ipb.rdata(34); -- bus access fault druing instrucion fetch
          trap_ctrl.instr_be <= ipb.rdata(34); -- bus access fault druing instrucion fetch
          illegal_compressed <= ipb.rdata(35); -- invalid decompressed instruction
          illegal_compressed <= ipb.rdata(35); -- invalid decompressed instruction
          if (trap_ctrl.env_start = '1') or ((ipb.rdata(33) or ipb.rdata(34) or ipb.rdata(35)) = '1') then -- exception/interrupt?
 
            execute_engine.state_nxt <= TRAP;
 
          else
 
            execute_engine.is_ci_nxt <= ipb.rdata(32); -- flag to indicate this is a compressed instruction beeing executed
            execute_engine.is_ci_nxt <= ipb.rdata(32); -- flag to indicate this is a compressed instruction beeing executed
            execute_engine.i_reg_nxt <= ipb.rdata(31 downto 0);
            execute_engine.i_reg_nxt <= ipb.rdata(31 downto 0);
            execute_engine.pc_nxt    <= ipb.raddr; -- the PC according to the current instruction
            execute_engine.pc_nxt    <= ipb.raddr; -- the PC according to the current instruction
            if (execute_engine.sleep = '1') then
          -- ipb.rdata(35) is not immediately checked here!
 
          if (execute_engine.sleep = '1') or (trap_ctrl.env_start = '1') or ((ipb.rdata(33) or ipb.rdata(34)) = '1') then
              execute_engine.state_nxt <= TRAP;
              execute_engine.state_nxt <= TRAP;
            else
            else
              execute_engine.state_nxt <= EXECUTE;
              execute_engine.state_nxt <= EXECUTE;
            end if;
            end if;
          end if;
          end if;
        end if;
 
 
 
      when TRAP => -- Start trap environment (also used as cpu sleep state)
      when TRAP => -- Start trap environment (also used as cpu sleep state)
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
        fetch_engine.reset <= '1';
        fetch_engine.reset <= '1';
        if (trap_ctrl.env_start = '1') then -- check here again if we came directly from DISPATCH
        if (trap_ctrl.env_start = '1') then -- check here again if we came directly from DISPATCH
Line 1072... Line 1072...
        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 buffer: illegal instruction / env 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 (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 (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_break_c)     <= (trap_ctrl.exc_buf(exception_break_c)     or trap_ctrl.break_point) and (not trap_ctrl.exc_ack);
        trap_ctrl.exc_buf(exception_break_c)     <= (trap_ctrl.exc_buf(exception_break_c)     or trap_ctrl.break_point) 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);
        -- interrupt buffer: machine software/external/timer interrupt
        -- interrupt buffer (RISC-V compliant): 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 (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_mext_irq_c)  <= csr.mie_meie and (trap_ctrl.irq_buf(interrupt_mext_irq_c)  or clic_irq_i)   and (not trap_ctrl.irq_ack(interrupt_mext_irq_c));
        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_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 (trap_ctrl.irq_buf(interrupt_mtime_irq_c) or mtime_irq_i)  and (not trap_ctrl.irq_ack(interrupt_mtime_irq_c));
 
        -- interrupt buffer (custom): fast interrupts
 
        trap_ctrl.irq_buf(interrupt_firq_0_c)    <= csr.mie_firqe(0) and (trap_ctrl.irq_buf(interrupt_firq_0_c) or firq_i(0)) and (not trap_ctrl.irq_ack(interrupt_firq_0_c));
 
        trap_ctrl.irq_buf(interrupt_firq_1_c)    <= csr.mie_firqe(1) and (trap_ctrl.irq_buf(interrupt_firq_1_c) or firq_i(1)) and (not trap_ctrl.irq_ack(interrupt_firq_1_c));
 
        trap_ctrl.irq_buf(interrupt_firq_2_c)    <= csr.mie_firqe(2) and (trap_ctrl.irq_buf(interrupt_firq_2_c) or firq_i(2)) and (not trap_ctrl.irq_ack(interrupt_firq_2_c));
 
        trap_ctrl.irq_buf(interrupt_firq_3_c)    <= csr.mie_firqe(3) and (trap_ctrl.irq_buf(interrupt_firq_3_c) or firq_i(3)) and (not trap_ctrl.irq_ack(interrupt_firq_3_c));
 
 
        -- 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 -- exception/IRQ detected!
          if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and -- exception/IRQ detected!
             ((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP))) then -- sample IRQs in EXECUTE or TRAP state only -> continue execution even if permanent IRQ
             ((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP))) then -- sample IRQs in EXECUTE or TRAP state only -> continue execution even if permanent IRQ
Line 1129... Line 1134...
    elsif (trap_ctrl.irq_buf(interrupt_msw_irq_c) = '1') then
    elsif (trap_ctrl.irq_buf(interrupt_msw_irq_c) = '1') then
      trap_ctrl.cause_nxt <= trap_msi_c;
      trap_ctrl.cause_nxt <= trap_msi_c;
      trap_ctrl.irq_ack_nxt(interrupt_msw_irq_c) <= '1';
      trap_ctrl.irq_ack_nxt(interrupt_msw_irq_c) <= '1';
 
 
 
 
 
    -- interrupt: 1.16 fast interrupt channel 0 --
 
    elsif (trap_ctrl.irq_buf(interrupt_firq_0_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_firq0_c;
 
      trap_ctrl.irq_ack_nxt(interrupt_firq_0_c) <= '1';
 
 
 
    -- interrupt: 1.17 fast interrupt channel 1 --
 
    elsif (trap_ctrl.irq_buf(interrupt_firq_1_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_firq1_c;
 
      trap_ctrl.irq_ack_nxt(interrupt_firq_1_c) <= '1';
 
 
 
    -- interrupt: 1.18 fast interrupt channel 2 --
 
    elsif (trap_ctrl.irq_buf(interrupt_firq_2_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_firq2_c;
 
      trap_ctrl.irq_ack_nxt(interrupt_firq_2_c) <= '1';
 
 
 
    -- interrupt: 1.19 fast interrupt channel 3 --
 
    elsif (trap_ctrl.irq_buf(interrupt_firq_3_c) = '1') then
 
      trap_ctrl.cause_nxt <= trap_firq3_c;
 
      trap_ctrl.irq_ack_nxt(interrupt_firq_3_c) <= '1';
 
 
 
 
    -- the following traps are caused by synchronous exceptions
    -- the following traps are caused by synchronous exceptions
    -- here we do not need a specific acknowledge mask since only one exception (the one
    -- here we do not need a specific acknowledge mask since only one exception (the one
    -- with highest priority) can trigger at once
    -- with highest priority) can trigger at once
 
 
    -- trap/fault: 0.1 instruction access fault --
    -- trap/fault: 0.1 instruction access fault --
Line 1148... Line 1174...
      trap_ctrl.cause_nxt <= trap_ima_c;
      trap_ctrl.cause_nxt <= trap_ima_c;
 
 
 
 
    -- trap/fault: 0.11 environment call from M-mode --
    -- trap/fault: 0.11 environment call from M-mode --
    elsif (trap_ctrl.exc_buf(exception_m_envcall_c) = '1') then
    elsif (trap_ctrl.exc_buf(exception_m_envcall_c) = '1') then
      trap_ctrl.cause_nxt <= trap_env_c;
      trap_ctrl.cause_nxt <= trap_menv_c;
 
 
    -- trap/fault: 0.3 breakpoint --
    -- trap/fault: 0.3 breakpoint --
    elsif (trap_ctrl.exc_buf(exception_break_c) = '1') then
    elsif (trap_ctrl.exc_buf(exception_break_c) = '1') then
      trap_ctrl.cause_nxt <= trap_brk_c;
      trap_ctrl.cause_nxt <= trap_brk_c;
 
 
Line 1196... Line 1222...
      csr.mstatus_mie  <= '0';
      csr.mstatus_mie  <= '0';
      csr.mstatus_mpie <= '0';
      csr.mstatus_mpie <= '0';
      csr.mie_msie     <= '0';
      csr.mie_msie     <= '0';
      csr.mie_meie     <= '0';
      csr.mie_meie     <= '0';
      csr.mie_mtie     <= '0';
      csr.mie_mtie     <= '0';
 
      csr.mie_firqe    <= (others => '0');
      csr.mtvec        <= (others => '0');
      csr.mtvec        <= (others => '0');
      csr.mscratch     <= (others => '0');
      csr.mscratch     <= (others => '0');
      csr.mepc         <= (others => '0');
      csr.mepc         <= (others => '0');
      csr.mcause       <= (others => '0');
      csr.mcause       <= (others => '0');
      csr.mtval        <= (others => '0');
      csr.mtval        <= (others => '0');
Line 1219... Line 1246...
              case execute_engine.i_reg(23 downto 20) is
              case execute_engine.i_reg(23 downto 20) is
                when x"0" => -- R/W: mstatus - machine status register
                when x"0" => -- R/W: mstatus - machine status register
                  csr.mstatus_mie  <= csr_wdata_i(03);
                  csr.mstatus_mie  <= csr_wdata_i(03);
                  csr.mstatus_mpie <= csr_wdata_i(07);
                  csr.mstatus_mpie <= csr_wdata_i(07);
                when x"4" => -- R/W: mie - machine interrupt-enable register
                when x"4" => -- R/W: mie - machine interrupt-enable register
                  csr.mie_msie <= csr_wdata_i(03); -- SW IRQ enable
                  csr.mie_msie <= csr_wdata_i(03); -- machine SW IRQ enable
                  csr.mie_mtie <= csr_wdata_i(07); -- TIMER IRQ enable
                  csr.mie_mtie <= csr_wdata_i(07); -- machine TIMER IRQ enable
                  csr.mie_meie <= csr_wdata_i(11); -- EXT IRQ enable
                  csr.mie_meie <= csr_wdata_i(11); -- machine EXT IRQ enable
 
                  --
 
                  csr.mie_firqe(0) <= csr_wdata_i(16); -- fast interrupt channel 0
 
                  csr.mie_firqe(1) <= csr_wdata_i(17); -- fast interrupt channel 1
 
                  csr.mie_firqe(2) <= csr_wdata_i(18); -- fast interrupt channel 2
 
                  csr.mie_firqe(3) <= csr_wdata_i(19); -- fast interrupt channel 3
                when x"5" => -- R/W: mtvec - machine trap-handler base address (for ALL exceptions)
                when x"5" => -- R/W: mtvec - machine trap-handler base address (for ALL exceptions)
                  csr.mtvec <= csr_wdata_i(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
                  csr.mtvec <= csr_wdata_i(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
                when others =>
                when others =>
                  NULL;
                  NULL;
              end case;
              end case;
Line 1235... Line 1267...
              case execute_engine.i_reg(23 downto 20) is
              case execute_engine.i_reg(23 downto 20) is
                when x"0" => -- R/W: mscratch - machine scratch register
                when x"0" => -- R/W: mscratch - machine scratch register
                  csr.mscratch <= csr_wdata_i;
                  csr.mscratch <= csr_wdata_i;
                when x"1" => -- R/W: mepc - machine exception program counter
                when x"1" => -- R/W: mepc - machine exception program counter
                  csr.mepc <= csr_wdata_i(data_width_c-1 downto 1) & '0';
                  csr.mepc <= csr_wdata_i(data_width_c-1 downto 1) & '0';
                when x"2" => -- R/W: mcause - machine trap cause
 
                  csr.mcause <= csr_wdata_i;
 
                when x"3" => -- R/W: mtval - machine bad address or instruction
                when x"3" => -- R/W: mtval - machine bad address or instruction
                  csr.mtval <= csr_wdata_i;
                  csr.mtval <= csr_wdata_i;
                when others =>
                when others =>
                  NULL;
                  NULL;
              end case;
              end case;
Line 1248... Line 1278...
          end if;
          end if;
 
 
        -- automatic update by hardware --
        -- automatic update by hardware --
        else
        else
 
 
          -- machine exception PC & trap value register --
          -- machine exception PC & machine trap value register --
          if (trap_ctrl.env_start_ack = '1') then -- trap handler starting?
          if (trap_ctrl.env_start_ack = '1') then -- trap handler starting?
            csr.mcause <= trap_ctrl.cause(4) & "000" & x"000000" & trap_ctrl.cause(3 downto 0);
            csr.mcause <= trap_ctrl.cause(trap_ctrl.cause'left) & "000" & x"00000" & "000" & trap_ctrl.cause(4 downto 0);
            if (trap_ctrl.cause(4) = '1') then -- for INTERRUPTS only (is mcause(31))
            if (trap_ctrl.cause(trap_ctrl.cause'left) = '1') then -- for INTERRUPTS only (is mcause(31))
              csr.mepc  <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- this is the CURRENT pc = interrupted instruction
              csr.mepc  <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- this is the CURRENT pc = interrupted instruction
              csr.mtval <= (others => '0'); -- mtval is zero for interrupts
              csr.mtval <= (others => '0'); -- mtval is zero for interrupts
            else -- for EXCEPTIONS (according to their priority)
            else -- for EXCEPTIONS (according to their priority)
              csr.mepc <= execute_engine.last_pc(data_width_c-1 downto 1) & '0'; -- this is the LAST pc = last executed instruction
              csr.mepc <= execute_engine.last_pc(data_width_c-1 downto 1) & '0'; -- this is the LAST pc = last executed instruction
              if (trap_ctrl.cause(3 downto 0) = trap_iba_c(3 downto 0)) or -- instr access error OR
              if (trap_ctrl.cause(4 downto 0) = trap_iba_c(4 downto 0)) or -- instr access error OR
                 (trap_ctrl.cause(3 downto 0) = trap_ima_c(3 downto 0)) or -- misaligned instruction OR
                 (trap_ctrl.cause(4 downto 0) = trap_ima_c(4 downto 0)) or -- misaligned instruction OR
                 (trap_ctrl.cause(3 downto 0) = trap_brk_c(3 downto 0)) or -- breakpoint OR
                 (trap_ctrl.cause(4 downto 0) = trap_brk_c(4 downto 0)) or -- breakpoint OR
                 (trap_ctrl.cause(3 downto 0) = trap_env_c(3 downto 0)) then -- env call OR
                 (trap_ctrl.cause(4 downto 0) = trap_menv_c(4 downto 0)) then -- env call OR
                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
              elsif (trap_ctrl.cause(3 downto 0) = trap_iil_c(3 downto 0)) then -- illegal instruction
              elsif (trap_ctrl.cause(4 downto 0) = trap_iil_c(4 downto 0)) then -- illegal instruction
                csr.mtval <= execute_engine.i_reg; -- faulting instruction itself
                csr.mtval <= execute_engine.i_reg; -- faulting instruction itself
              else -- load/store misalignments/access errors
              else -- load/store misalignments/access errors
                csr.mtval <= mar_i; -- faulting data access address
                csr.mtval <= mar_i; -- faulting data access address
              end if;
              end if;
            end if;
            end if;
Line 1305... Line 1335...
          when x"301" => -- R/-: misa - ISA and extensions
          when x"301" => -- R/-: misa - ISA and extensions
            csr_rdata_o(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C);     -- C CPU extension
            csr_rdata_o(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C);     -- C CPU extension
            csr_rdata_o(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E);     -- E CPU extension
            csr_rdata_o(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E);     -- E CPU extension
            csr_rdata_o(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
            csr_rdata_o(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
            csr_rdata_o(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M);     -- M CPU extension
            csr_rdata_o(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M);     -- M CPU extension
 
            csr_rdata_o(23) <= '1';                                         -- X CPU extension (non-std extensions)
            csr_rdata_o(25) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr) and bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Z CPU extension
            csr_rdata_o(25) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr) and bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Z CPU extension
            csr_rdata_o(30) <= '1'; -- 32-bit architecture (MXL lo)
            csr_rdata_o(30) <= '1'; -- 32-bit architecture (MXL lo)
            csr_rdata_o(31) <= '0'; -- 32-bit architecture (MXL hi)
            csr_rdata_o(31) <= '0'; -- 32-bit architecture (MXL hi)
          when x"304" => -- R/W: mie - machine interrupt-enable register
          when x"304" => -- R/W: mie - machine interrupt-enable register
            csr_rdata_o(03) <= csr.mie_msie; -- software IRQ enable
            csr_rdata_o(03) <= csr.mie_msie; -- machine software IRQ enable
            csr_rdata_o(07) <= csr.mie_mtie; -- timer IRQ enable
            csr_rdata_o(07) <= csr.mie_mtie; -- machine timer IRQ enable
            csr_rdata_o(11) <= csr.mie_meie; -- external IRQ enable
            csr_rdata_o(11) <= csr.mie_meie; -- machine external IRQ enable
 
            --
 
            csr_rdata_o(16) <= csr.mie_firqe(0); -- fast interrupt channel 0
 
            csr_rdata_o(17) <= csr.mie_firqe(1); -- fast interrupt channel 1
 
            csr_rdata_o(18) <= csr.mie_firqe(2); -- fast interrupt channel 2
 
            csr_rdata_o(19) <= csr.mie_firqe(3); -- fast interrupt channel 3
          when x"305" => -- R/W: mtvec - machine trap-handler base address (for ALL exceptions)
          when x"305" => -- R/W: mtvec - machine trap-handler base address (for ALL exceptions)
            csr_rdata_o <= csr.mtvec(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
            csr_rdata_o <= csr.mtvec(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
 
 
          -- machine trap handling --
          -- machine trap handling --
          when x"340" => -- R/W: mscratch - machine scratch register
          when x"340" => -- R/W: mscratch - machine scratch register
            csr_rdata_o <= csr.mscratch;
            csr_rdata_o <= csr.mscratch;
          when x"341" => -- R/W: mepc - machine exception program counter
          when x"341" => -- R/W: mepc - machine exception program counter
            csr_rdata_o <= csr.mepc(data_width_c-1 downto 1) & '0';
            csr_rdata_o <= csr.mepc(data_width_c-1 downto 1) & '0';
          when x"342" => -- R/W: mcause - machine trap cause
          when x"342" => -- R/-: mcause - machine trap cause
            csr_rdata_o <= csr.mcause;
            csr_rdata_o <= csr.mcause;
          when x"343" => -- R/W: mtval - machine bad address or instruction
          when x"343" => -- R/W: mtval - machine bad address or instruction
            csr_rdata_o <= csr.mtval;
            csr_rdata_o <= csr.mtval;
          when x"344" => -- R/W: mip - machine interrupt pending
          when x"344" => -- R/W: mip - machine interrupt pending
            csr_rdata_o(03) <= trap_ctrl.irq_buf(interrupt_msw_irq_c);
            csr_rdata_o(03) <= trap_ctrl.irq_buf(interrupt_msw_irq_c);
            csr_rdata_o(07) <= trap_ctrl.irq_buf(interrupt_mtime_irq_c);
            csr_rdata_o(07) <= trap_ctrl.irq_buf(interrupt_mtime_irq_c);
            csr_rdata_o(11) <= trap_ctrl.irq_buf(interrupt_mext_irq_c);
            csr_rdata_o(11) <= trap_ctrl.irq_buf(interrupt_mext_irq_c);
 
            --
 
            csr_rdata_o(16) <= trap_ctrl.irq_buf(interrupt_firq_0_c);
 
            csr_rdata_o(17) <= trap_ctrl.irq_buf(interrupt_firq_1_c);
 
            csr_rdata_o(18) <= trap_ctrl.irq_buf(interrupt_firq_2_c);
 
            csr_rdata_o(19) <= trap_ctrl.irq_buf(interrupt_firq_3_c);
 
 
          -- counter and timers --
          -- counter and timers --
          when x"c00" | x"b00" => -- R/(W): cycle/mcycle: Cycle counter LOW
          when x"c00" | x"b00" => -- R/(W): cycle/mcycle: Cycle counter LOW
            csr_rdata_o <= csr.mcycle(31 downto 0);
            csr_rdata_o <= csr.mcycle(31 downto 0);
          when x"c01" => -- R/-: time: System time LOW (from MTIME unit)
          when x"c01" => -- R/-: time: System time LOW (from MTIME unit)

powered by: WebSVN 2.1.0

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