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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_control.vhd] - Diff between revs 33 and 34

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

Rev 33 Rev 34
Line 129... Line 129...
    re    : std_ulogic; -- read enable
    re    : std_ulogic; -- read enable
    avail : std_ulogic; -- data available?
    avail : std_ulogic; -- data available?
    --
    --
    w_pnt : std_ulogic_vector(index_size_f(ipb_entries_c) downto 0); -- write pointer
    w_pnt : std_ulogic_vector(index_size_f(ipb_entries_c) downto 0); -- write pointer
    r_pnt : std_ulogic_vector(index_size_f(ipb_entries_c) downto 0); -- read pointer
    r_pnt : std_ulogic_vector(index_size_f(ipb_entries_c) downto 0); -- read pointer
 
    match : std_ulogic;
    empty : std_ulogic;
    empty : std_ulogic;
    full  : std_ulogic;
    full  : std_ulogic;
    --
    --
    data  : ipb_data_fifo_t; -- fifo memory
    data  : ipb_data_fifo_t; -- fifo memory
  end record;
  end record;
Line 390... Line 391...
 
 
  -- async read --
  -- async read --
  ipb.rdata <= ipb.data(to_integer(unsigned(ipb.r_pnt(ipb.r_pnt'left-1 downto 0))));
  ipb.rdata <= ipb.data(to_integer(unsigned(ipb.r_pnt(ipb.r_pnt'left-1 downto 0))));
 
 
  -- status --
  -- status --
  ipb.full  <= '1' when (ipb.r_pnt(ipb.r_pnt'left) /= ipb.w_pnt(ipb.w_pnt'left)) and (ipb.r_pnt(ipb.r_pnt'left-1 downto 0) = ipb.w_pnt(ipb.w_pnt'left-1 downto 0)) else '0';
  ipb.match <= '1' when (ipb.r_pnt(ipb.r_pnt'left-1 downto 0) = ipb.w_pnt(ipb.w_pnt'left-1 downto 0)) else '0';
  ipb.empty <= '1' when (ipb.r_pnt(ipb.r_pnt'left)  = ipb.w_pnt(ipb.w_pnt'left)) and (ipb.r_pnt(ipb.r_pnt'left-1 downto 0) = ipb.w_pnt(ipb.w_pnt'left-1 downto 0)) else '0';
  ipb.full  <= '1' when (ipb.r_pnt(ipb.r_pnt'left) /= ipb.w_pnt(ipb.w_pnt'left)) and (ipb.match = '1') else '0';
 
  ipb.empty <= '1' when (ipb.r_pnt(ipb.r_pnt'left)  = ipb.w_pnt(ipb.w_pnt'left)) and (ipb.match = '1') else '0';
  ipb.free  <= not ipb.full;
  ipb.free  <= not ipb.full;
  ipb.avail <= not ipb.empty;
  ipb.avail <= not ipb.empty;
 
 
 
 
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
Line 548... Line 549...
  end process instruction_buffer_ctrl;
  end process instruction_buffer_ctrl;
 
 
  instruction_buffer_data: process(clk_i)
  instruction_buffer_data: process(clk_i)
  begin
  begin
    if rising_edge(clk_i) then
    if rising_edge(clk_i) then
      if (i_buf.we = '1') and (ipb.clear = '0') then
      if (i_buf.we = '1') and (i_buf.clear = '0') then
        i_buf.rdata <= i_buf.wdata;
        i_buf.rdata <= i_buf.wdata;
      end if;
      end if;
    end if;
    end if;
  end process instruction_buffer_data;
  end process instruction_buffer_data;
 
 
Line 595... Line 596...
          imm_o(19 downto 12) <= execute_engine.i_reg(19 downto 12);
          imm_o(19 downto 12) <= execute_engine.i_reg(19 downto 12);
          imm_o(11)           <= execute_engine.i_reg(20);
          imm_o(11)           <= execute_engine.i_reg(20);
          imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
          imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
          imm_o(04 downto 01) <= execute_engine.i_reg(24 downto 21);
          imm_o(04 downto 01) <= execute_engine.i_reg(24 downto 21);
          imm_o(00)           <= '0';
          imm_o(00)           <= '0';
        when opcode_syscsr_c => -- CSR-immediate
        when opcode_syscsr_c => -- CSR-immediate (uimm5)
          imm_o(31 downto 05) <= (others => '0');
          imm_o(31 downto 05) <= (others => '0');
          imm_o(04 downto 00) <= execute_engine.i_reg(19 downto 15);
          imm_o(04 downto 00) <= execute_engine.i_reg(19 downto 15);
        when others => -- I-immediate
        when others => -- I-immediate
          imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
          imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
          imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
          imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
Line 797... Line 798...
          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)
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
 
        -- stay here for sleep
 
        if (trap_ctrl.env_start = '1') then -- trap triggered?
        fetch_engine.reset        <= '1';
        fetch_engine.reset        <= '1';
        execute_engine.if_rst_nxt <= '1'; -- this is a non-linear PC modification
        execute_engine.if_rst_nxt <= '1'; -- this is a non-linear PC modification
        if (trap_ctrl.env_start = '1') then -- check here again if we came directly from DISPATCH
 
          trap_ctrl.env_start_ack  <= '1';
          trap_ctrl.env_start_ack  <= '1';
          execute_engine.pc_nxt    <= csr.mtvec;
          execute_engine.pc_nxt    <= csr.mtvec;
          execute_engine.sleep_nxt <= '0'; -- waky waky
          execute_engine.sleep_nxt <= '0'; -- waky waky
          execute_engine.state_nxt <= SYS_WAIT;
          execute_engine.state_nxt <= SYS_WAIT;
        end if;
        end if;
Line 1480... Line 1482...
      csr.mepc         <= (others => '0');
      csr.mepc         <= (others => '0');
      csr.mcause       <= (others => '0');
      csr.mcause       <= (others => '0');
      csr.mtval        <= (others => '0');
      csr.mtval        <= (others => '0');
      csr.pmpcfg       <= (others => (others => '0'));
      csr.pmpcfg       <= (others => (others => '0'));
      csr.pmpaddr      <= (others => (others => '0'));
      csr.pmpaddr      <= (others => (others => '0'));
 
      --
 
      csr.mcycle       <= (others => '0');
 
      csr.minstret     <= (others => '0');
 
      csr.mcycleh      <= (others => '0');
 
      csr.minstreth    <= (others => '0');
 
      mcycle_msb       <= '0';
 
      minstret_msb     <= '0';
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
 
 
      -- write access? --
      -- write access? --
      csr.we <= csr.we_nxt;
      csr.we <= csr.we_nxt;
 
 
Line 1658... Line 1667...
          csr.privilege   <= priv_mode_m_c;
          csr.privilege   <= priv_mode_m_c;
          csr.mstatus_mpp <= priv_mode_m_c;
          csr.mstatus_mpp <= priv_mode_m_c;
        end if;
        end if;
      end if;
      end if;
 
 
 
      -- --------------------------------------------------------------------------------
 
      -- Counter CSRs
 
      -- --------------------------------------------------------------------------------
 
      if (CPU_EXTENSION_RISCV_Zicsr = true) then
 
 
 
        -- mcycle (cycle) --
 
        mcycle_msb <= csr.mcycle(csr.mcycle'left);
 
        if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_mcycle_c) then -- write access
 
          csr.mcycle(31 downto 0) <= csr.wdata;
 
          csr.mcycle(32) <= '0';
 
        elsif (execute_engine.sleep = '0') then -- automatic update (if CPU is not in sleep mode)
 
          csr.mcycle <= std_ulogic_vector(unsigned(csr.mcycle) + 1);
 
        end if;
 
 
 
        -- mcycleh (cycleh) --
 
        if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_mcycleh_c) then -- write access
 
          csr.mcycleh <= csr.wdata(csr.mcycleh'left downto 0);
 
        elsif ((mcycle_msb xor csr.mcycle(csr.mcycle'left)) = '1') then -- automatic update
 
          csr.mcycleh <= std_ulogic_vector(unsigned(csr.mcycleh) + 1);
 
        end if;
 
 
 
        -- minstret (instret) --
 
        minstret_msb <= csr.minstret(csr.minstret'left);
 
        if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_minstret_c) then -- write access
 
          csr.minstret(31 downto 0) <= csr.wdata;
 
          csr.minstret(32) <= '0';
 
        elsif (execute_engine.state_prev /= EXECUTE) and (execute_engine.state = EXECUTE) then -- automatic update
 
          csr.minstret <= std_ulogic_vector(unsigned(csr.minstret) + 1);
 
        end if;
 
 
 
        -- minstreth (instreth) --
 
        if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_minstreth_c) then -- write access
 
          csr.minstreth <= csr.wdata(csr.minstreth'left downto 0);
 
        elsif ((minstret_msb xor csr.minstret(csr.minstret'left)) = '1') then -- automatic update
 
          csr.minstreth <= std_ulogic_vector(unsigned(csr.minstreth) + 1);
 
        end if;
 
      end if;
    end if;
    end if;
  end process csr_write_access;
  end process csr_write_access;
 
 
 
  -- CPU's current privilege level --
 
  priv_mode_o <= csr.privilege;
 
 
 
  -- PMP output --
 
  pmp_output: process(csr)
 
  begin
 
    pmp_addr_o <= (others => (others => '0'));
 
    pmp_ctrl_o <= (others => (others => '0'));
 
    if (PMP_USE = true) then
 
      for i in 0 to PMP_NUM_REGIONS-1 loop
 
        pmp_addr_o(i) <= csr.pmpaddr(i) & "00";
 
        pmp_ctrl_o(i) <= csr.pmpcfg(i);
 
      end loop; -- i
 
    end if;
 
  end process pmp_output;
 
 
 
 
  -- Control and Status Registers Read Access -----------------------------------------------
  -- Control and Status Registers Read Access -----------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  csr_read_access: process(clk_i)
  csr_read_access: process(clk_i)
  begin
  begin
Line 1840... Line 1902...
            csr.rdata <= csr.minstreth(31 downto 0);
            csr.rdata <= csr.minstreth(31 downto 0);
 
 
          -- machine information registers --
          -- machine information registers --
          when csr_mvendorid_c => -- R/-: mvendorid - vendor ID
          when csr_mvendorid_c => -- R/-: mvendorid - vendor ID
            csr.rdata <= (others => '0');
            csr.rdata <= (others => '0');
          when csr_marchid_c => -- R/-: marchid - architecture ID
          when csr_marchid_c => -- R/-: marchid - arch ID
            csr.rdata(4 downto 0) <= "10011"; -- official open-source arch ID
            csr.rdata(4 downto 0) <= "10011"; -- official RISC-V open-source arch ID
          when csr_mimpid_c => -- R/-: mimpid - implementation ID
          when csr_mimpid_c => -- R/-: mimpid - implementation ID
            csr.rdata <= hw_version_c; -- NEORV32 hardware version
            csr.rdata <= hw_version_c; -- NEORV32 hardware version
          when csr_mhartid_c => -- R/-: mhartid - hardware thread ID
          when csr_mhartid_c => -- R/-: mhartid - hardware thread ID
            csr.rdata <= HW_THREAD_ID;
            csr.rdata <= HW_THREAD_ID;
 
 
Line 1865... Line 1927...
  end process csr_read_access;
  end process csr_read_access;
 
 
  -- CSR read data output --
  -- CSR read data output --
  csr_rdata_o <= csr.rdata;
  csr_rdata_o <= csr.rdata;
 
 
  -- CPU's current privilege level --
 
  priv_mode_o <= csr.privilege;
 
 
 
  -- PMP output --
 
  pmp_output: process(csr)
 
  begin
 
    pmp_addr_o <= (others => (others => '0'));
 
    pmp_ctrl_o <= (others => (others => '0'));
 
    if (PMP_USE = true) then
 
      for i in 0 to PMP_NUM_REGIONS-1 loop
 
        pmp_addr_o(i) <= csr.pmpaddr(i) & "00";
 
        pmp_ctrl_o(i) <= csr.pmpcfg(i);
 
      end loop; -- i
 
    end if;
 
  end process pmp_output;
 
 
 
 
 
  -- RISC-V Counter CSRs --------------------------------------------------------------------
 
  -- -------------------------------------------------------------------------------------------
 
  csr_counters: process(rstn_i, clk_i)
 
  begin
 
    if (rstn_i = '0') then
 
      csr.mcycle    <= (others => '0');
 
      csr.minstret  <= (others => '0');
 
      csr.mcycleh   <= (others => '0');
 
      csr.minstreth <= (others => '0');
 
      mcycle_msb    <= '0';
 
      minstret_msb  <= '0';
 
    elsif rising_edge(clk_i) then
 
 
 
      -- mcycle (cycle) --
 
      mcycle_msb <= csr.mcycle(csr.mcycle'left);
 
      if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_mcycle_c) then -- write access
 
        csr.mcycle(31 downto 0) <= csr.wdata;
 
        csr.mcycle(32) <= '0';
 
      elsif (execute_engine.sleep = '0') then -- automatic update (if CPU is not in sleep mode)
 
        csr.mcycle <= std_ulogic_vector(unsigned(csr.mcycle) + 1);
 
      end if;
 
 
 
      -- mcycleh (cycleh) --
 
      if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_mcycleh_c) then -- write access
 
        csr.mcycleh <= csr.wdata(csr.mcycleh'left downto 0);
 
      elsif ((mcycle_msb xor csr.mcycle(csr.mcycle'left)) = '1') then -- automatic update
 
        csr.mcycleh <= std_ulogic_vector(unsigned(csr.mcycleh) + 1);
 
      end if;
 
 
 
      -- minstret (instret) --
 
      minstret_msb <= csr.minstret(csr.minstret'left);
 
      if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_minstret_c) then -- write access
 
        csr.minstret(31 downto 0) <= csr.wdata;
 
        csr.minstret(32) <= '0';
 
      elsif (execute_engine.state_prev /= EXECUTE) and (execute_engine.state = EXECUTE) then -- automatic update
 
        csr.minstret <= std_ulogic_vector(unsigned(csr.minstret) + 1);
 
      end if;
 
 
 
      -- minstreth (instreth) --
 
      if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_minstreth_c) then -- write access
 
        csr.minstreth <= csr.wdata(csr.minstreth'left downto 0);
 
      elsif ((minstret_msb xor csr.minstret(csr.minstret'left)) = '1') then -- automatic update
 
        csr.minstreth <= std_ulogic_vector(unsigned(csr.minstreth) + 1);
 
      end if;
 
    end if;
 
  end process csr_counters;
 
 
 
 
 
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.