-- `Deep Thought', a softcore CPU implemented on a FPGA -- -- Copyright (C) 2010 Markus Hofstaetter -- Copyright (C) 2010 Martin Perner -- Copyright (C) 2010 Stefan Rebernig -- Copyright (C) 2010 Manfred Schwarz -- Copyright (C) 2010 Bernhard Urban -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.common_pkg.all; use work.core_pkg.all; use work.mem_pkg.all; use work.extension_pkg.all; use work.extension_imp_pkg.all; architecture behav of extension_imp is signal w1_st_co, w1_st_co_nxt, w2_im_addr, w2_im_addr_nxt, w3_im_data, w3_im_data_nxt, w4_im_notused, w4_im_notused_nxt : gp_register_t; signal new_im_data, new_im_data_nxt: std_logic; begin syn : process (clk, reset) begin if (reset = RESET_VALUE) then w1_st_co <= (others=>'0'); w2_im_addr(31 downto 16) <= (others=>'0'); -- todo mit einer konstante versehen w2_im_addr(15 downto 0) <= x"0003"; w3_im_data <= (others=>'0'); w4_im_notused <= (others=>'0'); --im only new_im_data <= '0'; elsif rising_edge(clk) then w1_st_co <= w1_st_co_nxt; w2_im_addr <= w2_im_addr_nxt; w3_im_data <= w3_im_data_nxt; w4_im_notused <= w4_im_notused_nxt; --im only new_im_data <= new_im_data_nxt; end if; end process syn; -------------------------- LESEN UND SCHREIBEN ANFANG ------------------------------------------------------------ gwriten : process (ext_reg,w1_st_co,w2_im_addr,w3_im_data,w4_im_notused) variable tmp_data : gp_register_t; begin w1_st_co_nxt <= w1_st_co; w2_im_addr_nxt <= w2_im_addr; w3_im_data_nxt <= w3_im_data; w4_im_notused_nxt <= w4_im_notused; if ext_reg.sel = '1' and ext_reg.wr_en = '1' then tmp_data := (others =>'0'); if ext_reg.byte_en(0) = '1' then tmp_data(byte_t'range) :=ext_reg.data(byte_t'range); end if; if ext_reg.byte_en(1) = '1' then tmp_data((2*byte_t'length-1) downto byte_t'length) := ext_reg.data((2*byte_t'length-1) downto byte_t'length); end if; if ext_reg.byte_en(2) = '1' then tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := ext_reg.data((3*byte_t'length-1) downto 2*byte_t'length); end if; if ext_reg.byte_en(3) = '1' then tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := ext_reg.data((4*byte_t'length-1) downto 3*byte_t'length); end if; case ext_reg.addr(1 downto 0) is when "00" => w1_st_co_nxt <= tmp_data; when "01" => -- -1 wegen increment des addr registers tmp_data := tmp_data - '1'; w2_im_addr_nxt <= tmp_data; when "10" => w1_st_co_nxt(0) <= '1'; -- busy flag set w2_im_addr_nxt <= w2_im_addr + '1'; w3_im_data_nxt <= tmp_data; when "11" => --w4_im_notused_nxt <= tmp_data; sollte nur gelesen werden when others => null; end case; end if; end process gwriten; gread : process (clk,ext_reg,w1_st_co,w2_im_addr,w3_im_data,w4_im_notused) variable tmp_data : gp_register_t; begin if ext_reg.sel = '1' and ext_reg.wr_en = '0' then case ext_reg.addr(1 downto 0) is when "00" => tmp_data := (others =>'0'); if ext_reg.byte_en(0) = '1' then tmp_data(byte_t'range) := w1_st_co(byte_t'range); end if; if ext_reg.byte_en(1) = '1' then tmp_data((2*byte_t'length-1) downto byte_t'length) := w1_st_co((2*byte_t'length-1) downto byte_t'length); end if; if ext_reg.byte_en(2) = '1' then tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w1_st_co((3*byte_t'length-1) downto 2*byte_t'length); end if; if ext_reg.byte_en(3) = '1' then tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w1_st_co((4*byte_t'length-1) downto 3*byte_t'length); end if; data_out <= tmp_data; when "01" => tmp_data := (others =>'0'); if ext_reg.byte_en(0) = '1' then tmp_data(byte_t'range) := w2_im_addr(byte_t'range); end if; if ext_reg.byte_en(1) = '1' then tmp_data((2*byte_t'length-1) downto byte_t'length) := w2_im_addr((2*byte_t'length-1) downto byte_t'length); end if; if ext_reg.byte_en(2) = '1' then tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w2_im_addr((3*byte_t'length-1) downto 2*byte_t'length); end if; if ext_reg.byte_en(3) = '1' then tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w2_im_addr((4*byte_t'length-1) downto 3*byte_t'length); end if; data_out <= tmp_data; when "10" => tmp_data := (others =>'0'); if ext_reg.byte_en(0) = '1' then tmp_data(byte_t'range) := w3_im_data(byte_t'range); end if; if ext_reg.byte_en(1) = '1' then tmp_data((2*byte_t'length-1) downto byte_t'length) := w3_im_data((2*byte_t'length-1) downto byte_t'length); end if; if ext_reg.byte_en(2) = '1' then tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w3_im_data((3*byte_t'length-1) downto 2*byte_t'length); end if; if ext_reg.byte_en(3) = '1' then tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w3_im_data((4*byte_t'length-1) downto 3*byte_t'length); end if; data_out <= tmp_data; when "11" => tmp_data := (others =>'0'); if ext_reg.byte_en(0) = '1' then tmp_data(byte_t'range) := w4_im_notused(byte_t'range); end if; if ext_reg.byte_en(1) = '1' then tmp_data((2*byte_t'length-1) downto byte_t'length) := w4_im_notused((2*byte_t'length-1) downto byte_t'length); end if; if ext_reg.byte_en(2) = '1' then tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w4_im_notused((3*byte_t'length-1) downto 2*byte_t'length); end if; if ext_reg.byte_en(3) = '1' then tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w4_im_notused((4*byte_t'length-1) downto 3*byte_t'length); end if; data_out <= tmp_data; when others => null; end case; else data_out <= (others=>'0'); end if; end process gread; -------------------------- LESEN UND SCHREIBEN ENDE --------------------------------------------------------------- -------------------------- INTERNE VERARBEITUNG ANFANG ------------------------------------------------------------ dataprocess : process (ext_reg) begin new_im_data_nxt <= '0'; if ext_reg.sel = '1' and ext_reg.wr_en = '1' then case ext_reg.addr(1 downto 0) is when "00" => when "01" => when "10" => new_im_data_nxt <= '1'; when "11" => when others => null; end case; end if; end process dataprocess; -- asyncrone verarbeitung im_addr <= w2_im_addr; im_data <= w3_im_data; new_im_data_out <= new_im_data; -------------------------- INTERNE VERARBEITUNG ENDE -------------------------------------------------------------- end behav;