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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_bus.vhd] - Diff between revs 70 and 71

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

Rev 70 Rev 71
Line 191... Line 191...
        mar <= addr_i;
        mar <= addr_i;
      end if;
      end if;
    end if;
    end if;
  end process mem_adr_reg;
  end process mem_adr_reg;
 
 
  -- read-back for exception controller --
  -- address read-back for exception controller --
  mar_o <= mar;
  mar_o <= mar;
 
 
  -- alignment check --
  -- alignment check --
  misaligned_d_check: process(mar, ctrl_i)
  misaligned_d_check: process(mar, ctrl_i)
  begin
  begin
    -- check data access --
 
    d_misaligned <= '0'; -- default
 
    case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is -- data size
    case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is -- data size
      when "00" => -- byte
      when "00" => -- byte
        d_misaligned <= '0';
        d_misaligned <= '0';
      when "01" => -- half-word
      when "01" => -- half-word
        if (mar(0) /= '0') then
        if (mar(0) /= '0') then
          d_misaligned <= '1';
          d_misaligned <= '1';
 
        else
 
          d_misaligned <= '0';
        end if;
        end if;
      when others => -- word
      when others => -- word
        if (mar(1 downto 0) /= "00") then
        if (mar(1 downto 0) /= "00") then
          d_misaligned <= '1';
          d_misaligned <= '1';
 
        else
 
          d_misaligned <= '0';
        end if;
        end if;
    end case;
    end case;
  end process misaligned_d_check;
  end process misaligned_d_check;
 
 
 
 
Line 228... Line 230...
      end if;
      end if;
    end if;
    end if;
  end process mem_do_reg;
  end process mem_do_reg;
 
 
  -- byte enable and output data alignment --
  -- byte enable and output data alignment --
  byte_enable: process(mar, mdo, ctrl_i)
  write_align: process(mar, mdo, ctrl_i)
  begin
  begin
    case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is -- data size
    case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is -- data size
      when "00" => -- byte
      when "00" => -- byte
        d_bus_wdata(07 downto 00) <= mdo(07 downto 00);
        d_bus_wdata(07 downto 00) <= mdo(7 downto 0);
        d_bus_wdata(15 downto 08) <= mdo(07 downto 00);
        d_bus_wdata(15 downto 08) <= mdo(7 downto 0);
        d_bus_wdata(23 downto 16) <= mdo(07 downto 00);
        d_bus_wdata(23 downto 16) <= mdo(7 downto 0);
        d_bus_wdata(31 downto 24) <= mdo(07 downto 00);
        d_bus_wdata(31 downto 24) <= mdo(7 downto 0);
        case mar(1 downto 0) is
        case mar(1 downto 0) is
          when "00"   => d_bus_ben <= "0001";
          when "00"   => d_bus_ben <= "0001";
          when "01"   => d_bus_ben <= "0010";
          when "01"   => d_bus_ben <= "0010";
          when "10"   => d_bus_ben <= "0100";
          when "10"   => d_bus_ben <= "0100";
          when others => d_bus_ben <= "1000";
          when others => d_bus_ben <= "1000";
        end case;
        end case;
      when "01" => -- half-word
      when "01" => -- half-word
        d_bus_wdata(31 downto 16) <= mdo(15 downto 00);
        d_bus_wdata(31 downto 16) <= mdo(15 downto 0);
        d_bus_wdata(15 downto 00) <= mdo(15 downto 00);
        d_bus_wdata(15 downto 00) <= mdo(15 downto 0);
        if (mar(1) = '0') then
        if (mar(1) = '0') then
          d_bus_ben <= "0011"; -- low half-word
          d_bus_ben <= "0011"; -- low half-word
        else
        else
          d_bus_ben <= "1100"; -- high half-word
          d_bus_ben <= "1100"; -- high half-word
        end if;
        end if;
      when others => -- word
      when others => -- word
        d_bus_wdata <= mdo;
        d_bus_wdata <= mdo;
        d_bus_ben   <= "1111"; -- full word
        d_bus_ben   <= "1111"; -- full word
    end case;
    end case;
  end process byte_enable;
  end process write_align;
 
 
 
 
  -- Data Interface: Read Data --------------------------------------------------------------
  -- Data Interface: Read Data --------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  mem_di_reg: process(rstn_i, clk_i)
  mem_di_reg: process(rstn_i, clk_i)
Line 272... Line 274...
    end if;
    end if;
  end process mem_di_reg;
  end process mem_di_reg;
 
 
  -- input data alignment and sign extension --
  -- input data alignment and sign extension --
  read_align: process(mdi, mar, ctrl_i)
  read_align: process(mdi, mar, ctrl_i)
    variable byte_in_v  : std_ulogic_vector(07 downto 0);
    variable shifted_data_v : std_ulogic_vector(31 downto 0);
    variable hword_in_v : std_ulogic_vector(15 downto 0);
 
  begin
  begin
    -- sub-word input --
    -- align input word --
    case mar(1 downto 0) is
    case mar(1 downto 0) is
      when "00"   => byte_in_v := mdi(07 downto 00); hword_in_v := mdi(15 downto 00); -- byte 0 / half-word 0
      when "00"   => shifted_data_v :=             mdi(31 downto 00);
      when "01"   => byte_in_v := mdi(15 downto 08); hword_in_v := mdi(15 downto 00); -- byte 1 / half-word 0
      when "01"   => shifted_data_v := x"00" &     mdi(31 downto 08);
      when "10"   => byte_in_v := mdi(23 downto 16); hword_in_v := mdi(31 downto 16); -- byte 2 / half-word 1
      when "10"   => shifted_data_v := x"0000" &   mdi(31 downto 16);
      when others => byte_in_v := mdi(31 downto 24); hword_in_v := mdi(31 downto 16); -- byte 3 / half-word 1
      when others => shifted_data_v := x"000000" & mdi(31 downto 24);
    end case;
    end case;
    -- actual data size --
    -- actual data size and sign-extension --
    case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is
    case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is
      when "00" => -- byte
      when "00" => -- byte
        rdata_align(31 downto 08) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and byte_in_v(7))); -- sign extension
        rdata_align(31 downto 08) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and shifted_data_v(7))); -- sign extension
        rdata_align(07 downto 00) <= byte_in_v;
        rdata_align(07 downto 00) <= shifted_data_v(07 downto 00);
      when "01" => -- half-word
      when "01" => -- half-word
        rdata_align(31 downto 16) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and hword_in_v(15))); -- sign extension
        rdata_align(31 downto 16) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and shifted_data_v(15))); -- sign extension
        rdata_align(15 downto 00) <= hword_in_v; -- high half-word
        rdata_align(15 downto 00) <= shifted_data_v(15 downto 00); -- high half-word
      when others => -- word
      when others => -- word
        rdata_align <= mdi; -- full word
        rdata_align <= shifted_data_v; -- full word
    end case;
    end case;
  end process read_align;
  end process read_align;
 
 
  -- insert exclusive lock status for SC operations only --
  -- insert exclusive lock status for SC operations only --
  rdata_o <= exclusive_lock_status when (CPU_EXTENSION_RISCV_A = true) and (ctrl_i(ctrl_bus_ch_lock_c) = '1') else rdata_align;
  rdata_o <= exclusive_lock_status when (CPU_EXTENSION_RISCV_A = true) and (ctrl_i(ctrl_bus_ch_lock_c) = '1') else rdata_align;
Line 317... Line 318...
        d_arbiter.rd_req    <= ctrl_i(ctrl_bus_rd_c);
        d_arbiter.rd_req    <= ctrl_i(ctrl_bus_rd_c);
        d_arbiter.err_align <= d_misaligned;
        d_arbiter.err_align <= d_misaligned;
        d_arbiter.err_bus   <= '0';
        d_arbiter.err_bus   <= '0';
      else -- in progress
      else -- in progress
        d_arbiter.err_align <= (d_arbiter.err_align or d_misaligned) and (not ctrl_i(ctrl_bus_derr_ack_c));
        d_arbiter.err_align <= (d_arbiter.err_align or d_misaligned) and (not ctrl_i(ctrl_bus_derr_ack_c));
        d_arbiter.err_bus   <= (d_arbiter.err_bus or d_bus_err_i or (st_pmp_fault and d_arbiter.wr_req) or (ld_pmp_fault and d_arbiter.rd_req)) and
        d_arbiter.err_bus   <= (d_arbiter.err_bus or d_bus_err_i or (st_pmp_fault and d_arbiter.wr_req) or (ld_pmp_fault and d_arbiter.rd_req)) and (not ctrl_i(ctrl_bus_derr_ack_c));
                               (not ctrl_i(ctrl_bus_derr_ack_c));
 
        if ((d_bus_ack_i = '1') and (d_bus_err_i = '0')) or (ctrl_i(ctrl_bus_derr_ack_c) = '1') then -- wait for normal termination / CPU abort
        if ((d_bus_ack_i = '1') and (d_bus_err_i = '0')) or (ctrl_i(ctrl_bus_derr_ack_c) = '1') then -- wait for normal termination / CPU abort
          d_arbiter.wr_req <= '0';
          d_arbiter.wr_req <= '0';
          d_arbiter.rd_req <= '0';
          d_arbiter.rd_req <= '0';
        end if;
        end if;
      end if;
      end if;
Line 405... Line 405...
      -- instruction fetch request --
      -- instruction fetch request --
      if (i_arbiter.rd_req = '0') then -- idle
      if (i_arbiter.rd_req = '0') then -- idle
        i_arbiter.rd_req    <= ctrl_i(ctrl_bus_if_c);
        i_arbiter.rd_req    <= ctrl_i(ctrl_bus_if_c);
        i_arbiter.err_align <= i_misaligned;
        i_arbiter.err_align <= i_misaligned;
        i_arbiter.err_bus   <= '0';
        i_arbiter.err_bus   <= '0';
      else -- in progres
      else -- in progress
        i_arbiter.err_align <= (i_arbiter.err_align or i_misaligned) and (not ctrl_i(ctrl_bus_ierr_ack_c));
        i_arbiter.err_align <= (i_arbiter.err_align or i_misaligned) and (not ctrl_i(ctrl_bus_ierr_ack_c));
        i_arbiter.err_bus   <= (i_arbiter.err_bus or i_bus_err_i or if_pmp_fault) and (not ctrl_i(ctrl_bus_ierr_ack_c));
        i_arbiter.err_bus   <= (i_arbiter.err_bus or i_bus_err_i or if_pmp_fault) and (not ctrl_i(ctrl_bus_ierr_ack_c));
        if ((i_bus_ack_i = '1') and (i_bus_err_i = '0')) or (ctrl_i(ctrl_bus_ierr_ack_c) = '1') then -- wait for normal termination / CPU abort
        if ((i_bus_ack_i = '1') and (i_bus_err_i = '0')) or (ctrl_i(ctrl_bus_ierr_ack_c) = '1') then -- wait for normal termination / CPU abort
          i_arbiter.rd_req <= '0';
          i_arbiter.rd_req <= '0';
        end if;
        end if;

powered by: WebSVN 2.1.0

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