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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_bus.vhd] - Diff between revs 6 and 11

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

Rev 6 Rev 11
Line 41... Line 41...
library neorv32;
library neorv32;
use neorv32.neorv32_package.all;
use neorv32.neorv32_package.all;
 
 
entity neorv32_cpu_bus is
entity neorv32_cpu_bus is
  generic (
  generic (
 
    CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
    MEM_EXT_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout
    MEM_EXT_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout
  );
  );
  port (
  port (
    -- global control --
    -- global control --
    clk_i       : in  std_ulogic; -- global clock, rising edge
    clk_i       : in  std_ulogic; -- global clock, rising edge
Line 65... Line 66...
    be_instr_o  : out std_ulogic; -- bus error on instruction access
    be_instr_o  : out std_ulogic; -- bus error on instruction access
    be_load_o   : out std_ulogic; -- bus error on load data access
    be_load_o   : out std_ulogic; -- bus error on load data access
    be_store_o  : out std_ulogic; -- bus error on store data access
    be_store_o  : out std_ulogic; -- bus error on store data access
    bus_wait_o  : out std_ulogic; -- wait for bus operation to finish
    bus_wait_o  : out std_ulogic; -- wait for bus operation to finish
    bus_busy_o  : out std_ulogic; -- bus unit is busy
    bus_busy_o  : out std_ulogic; -- bus unit is busy
    exc_ack_i   : in  std_ulogic; -- exception controller ACK
 
    -- bus system --
    -- bus system --
    bus_addr_o  : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
    bus_addr_o  : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
    bus_rdata_i : in  std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
    bus_rdata_i : in  std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
    bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
    bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
    bus_ben_o   : out std_ulogic_vector(03 downto 0); -- byte enable
    bus_ben_o   : out std_ulogic_vector(03 downto 0); -- byte enable
    bus_we_o    : out std_ulogic; -- write enable
    bus_we_o    : out std_ulogic; -- write enable
    bus_re_o    : out std_ulogic; -- read enable
    bus_re_o    : out std_ulogic; -- read enable
 
    bus_cancel_o : out std_ulogic; -- cancel current bus transaction
    bus_ack_i   : in  std_ulogic; -- bus transfer acknowledge
    bus_ack_i   : in  std_ulogic; -- bus transfer acknowledge
    bus_err_i   : in  std_ulogic  -- bus transfer error
    bus_err_i   : in  std_ulogic  -- bus transfer error
  );
  );
end neorv32_cpu_bus;
end neorv32_cpu_bus;
 
 
Line 101... Line 102...
 
 
  -- Address and Control --------------------------------------------------------------------
  -- Address and Control --------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  mem_adr_reg: process(rstn_i, clk_i)
  mem_adr_reg: process(rstn_i, clk_i)
  begin
  begin
    if (rstn_i = '0') then
    if rising_edge(clk_i) then
      mar <= (others => '0');
 
    elsif rising_edge(clk_i) then
 
      if (ctrl_i(ctrl_bus_mar_we_c) = '1') then
      if (ctrl_i(ctrl_bus_mar_we_c) = '1') then
        mar <= alu_i;
        mar <= alu_i;
      end if;
      end if;
    end if;
    end if;
  end process mem_adr_reg;
  end process mem_adr_reg;
 
 
  -- address output --
  -- address output --
  bus_addr_o <= pc_i when ((bus_if_req or ctrl_i(ctrl_bus_if_c)) = '1') else mar; -- is instruction fetch?
  bus_addr_o <= pc_i when ((bus_if_req or ctrl_i(ctrl_bus_if_c)) = '1') else mar; -- is instruction fetch? keep output at PC as long as IF request is active
  mar_o      <= mar;
  mar_o      <= mar;
 
 
  -- write request output --
  -- write request output --
  bus_we_o <= ctrl_i(ctrl_bus_wr_c) and (not misaligned_data);
  bus_we_o <= ctrl_i(ctrl_bus_wr_c) and (not misaligned_data);
 
 
  -- read request output (also used for instruction fetch) --
  -- read request output (also used for instruction fetch) --
  bus_re_o <= (ctrl_i(ctrl_bus_rd_c) and (not misaligned_data)) or ((bus_if_req or ctrl_i(ctrl_bus_if_c)) and (not misaligned_instr));
  bus_re_o <= (ctrl_i(ctrl_bus_rd_c) and (not misaligned_data)) or (ctrl_i(ctrl_bus_if_c) and (not misaligned_instr)); -- FIXME i_reg and misaligned
 
 
 
 
  -- Write Data -----------------------------------------------------------------------------
  -- Write Data -----------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  mem_do_reg: process(clk_i)
  mem_do_reg: process(clk_i)
Line 221... Line 220...
      bus_wr_req  <= '0';
      bus_wr_req  <= '0';
      access_err  <= '0';
      access_err  <= '0';
      align_err   <= '0';
      align_err   <= '0';
      bus_timeout <= (others => '0');
      bus_timeout <= (others => '0');
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      if (bus_busy = '0') then -- wait for new request
      if (bus_busy = '0') or (ctrl_i(ctrl_bus_reset_c) = '1') then -- wait for new request or reset
        bus_busy      <= ctrl_i(ctrl_bus_if_c) or ctrl_i(ctrl_bus_rd_c) or ctrl_i(ctrl_bus_wr_c); -- any request at all?
        bus_busy      <= ctrl_i(ctrl_bus_if_c) or ctrl_i(ctrl_bus_rd_c) or ctrl_i(ctrl_bus_wr_c); -- any request at all?
        bus_if_req    <= ctrl_i(ctrl_bus_if_c); -- instruction fetch
        bus_if_req    <= ctrl_i(ctrl_bus_if_c); -- instruction fetch
        bus_rd_req    <= ctrl_i(ctrl_bus_rd_c); -- store access
        bus_rd_req    <= ctrl_i(ctrl_bus_rd_c); -- store access
        bus_wr_req    <= ctrl_i(ctrl_bus_wr_c); -- load access
        bus_wr_req    <= ctrl_i(ctrl_bus_wr_c); -- load access
        bus_timeout   <= std_ulogic_vector(to_unsigned(MEM_EXT_TIMEOUT, index_size_f(MEM_EXT_TIMEOUT)));
        bus_timeout   <= std_ulogic_vector(to_unsigned(MEM_EXT_TIMEOUT, index_size_f(MEM_EXT_TIMEOUT)));
        access_err    <= '0';
        access_err    <= '0';
        align_err     <= '0';
        align_err     <= '0';
      else -- bus transfer in progress
      else -- bus transfer in progress
        bus_timeout <= std_ulogic_vector(unsigned(bus_timeout) - 1);
        bus_timeout <= std_ulogic_vector(unsigned(bus_timeout) - 1);
        align_err   <= (align_err or misaligned_data or misaligned_instr) and (not exc_ack_i);
        align_err   <= (align_err or misaligned_data or misaligned_instr) and (not ctrl_i(ctrl_bus_exc_ack_c));
        access_err  <= (access_err or (not or_all_f(bus_timeout)) or bus_err_i) and (not exc_ack_i);
        access_err  <= (access_err or (not or_all_f(bus_timeout)) or bus_err_i) and (not ctrl_i(ctrl_bus_exc_ack_c));
        if (align_err = '1') or (access_err = '1') then
        if (align_err = '1') or (access_err = '1') then
          if (exc_ack_i = '1') then -- wait for controller to ack exception
          if (ctrl_i(ctrl_bus_exc_ack_c) = '1') then -- wait for controller to ack exception
            bus_if_req <= '0';
            bus_if_req <= '0';
            bus_rd_req <= '0';
            bus_rd_req <= '0';
            bus_wr_req <= '0';
            bus_wr_req <= '0';
            bus_busy   <= '0';
            bus_busy   <= '0';
          end if;
          end if;
Line 260... Line 259...
  -- output alignment error to controller --
  -- output alignment error to controller --
  ma_instr_o <= bus_if_req and align_err;
  ma_instr_o <= bus_if_req and align_err;
  ma_load_o  <= bus_rd_req and align_err;
  ma_load_o  <= bus_rd_req and align_err;
  ma_store_o <= bus_wr_req and align_err;
  ma_store_o <= bus_wr_req and align_err;
 
 
 
  -- terminate bus access --
 
  bus_cancel_o <= (bus_busy and (align_err or access_err)) or ctrl_i(ctrl_bus_reset_c);
 
 
  -- wait for bus --
  -- wait for bus --
  bus_busy_o <= bus_busy;
  bus_busy_o <= bus_busy;
  bus_wait_o <= bus_busy and (not bus_ack_i); -- FIXME: 'async' ack
  bus_wait_o <= bus_busy and (not bus_ack_i); -- FIXME: 'async' ack
 
 
 
 
Line 289... Line 291...
 
 
  misaligned_i_check: process(ctrl_i, pc_i)
  misaligned_i_check: process(ctrl_i, pc_i)
  begin
  begin
    -- check instruction access --
    -- check instruction access --
    misaligned_instr <= '0'; -- default
    misaligned_instr <= '0'; -- default
    if (ctrl_i(ctrl_sys_c_ext_en_c) = '1') then -- 16-bit and 32-bit instruction accesses
    if (CPU_EXTENSION_RISCV_C = true) then -- 16-bit and 32-bit instruction accesses
      misaligned_instr <= '0';
      misaligned_instr <= '0'; -- no alignment exceptions possible
    else -- 32-bit instruction accesses only
    else -- 32-bit instruction accesses only
      if (pc_i(1 downto 0) /= "00") then
      if (pc_i(1) = '1') then -- PC(0) is always zero
        misaligned_instr <= '1';
        misaligned_instr <= '1';
      end if;
      end if;
    end if;
    end if;
  end process misaligned_i_check;
  end process misaligned_i_check;
 
 

powered by: WebSVN 2.1.0

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