Skip to content
Snippets Groups Projects
Commit 0b75b1ba authored by Deike, Benedikt's avatar Deike, Benedikt
Browse files

Upload New File

parent bbf8f7bb
No related branches found
No related tags found
No related merge requests found
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity datapath is
port (
--------------------------------------------------
-- external processor signals --------------------
--------------------------------------------------
clock : in std_logic;
nR : in std_logic;
--------------------------------------------------
-- internal processor signals --------------------
--------------------------------------------------
omnibus : inout std_logic_vector(15 downto 0);
-- signals that are required by the register file
AX : in std_logic_vector(3 downto 0);
AY : in std_logic_vector(3 downto 0);
eAX15 : in std_logic;
regNWE : in std_logic;
-- signals that are required by the ALU
opCoALU : in std_logic_vector(4 downto 0);
carry : inout std_logic;
imm4 : in std_logic_vector(3 downto 0);
DX : inout std_logic_vector(15 downto 0);
DY : inout std_logic_vector(15 downto 0);
-- signals that are required by the C register
eC : in std_logic;
-- signals that are required by buffers
eBuffDX : in std_logic;
eBuffALU : in std_logic
);
end datapath;
architecture arcDatapath of datapath is
type tyRF is array (15 downto 0) of std_logic_vector(15 downto 0);
-- output signals of the AX15 logic:
-- from AX15 to ALU
signal outAX15 : std_logic_vector(3 downto 0);
-- output singals of the ALU:
-- from ALU to ALU buffer or C register
signal outALU : std_logic_vector(15 downto 0);
signal outC : std_logic;
begin
AX15 : process (eAX15, AX) is
begin
if eAX15 = '1' then
outAX15 <= (others => '1');
else
outAX15 <= AX;
end if;
end process AX15;
registerFile : process (clock) is
variable RF : tyRF;
begin
if rising_edge(clock) then
if regNWE = '0' then
RF(to_integer(unsigned(outAX15))) := omnibus;
else
DX <= RF(to_integer(unsigned(outAX15)));
DY <= RF(to_integer(unsigned(AY)));
end if;
end if;
end process registerFile;
ALU : process (opCoALU, imm4, DX, DY) is
-- auxiliary variable
variable vectorHelper : std_logic_vector(15 downto 0);
begin
-- reset auxiliary variable
vectorHelper := (others => '0');
case opCoALU is
-- DY
when "00000" =>
outALU <= DY;
-- DX + DY
when "00001" =>
outALU <= std_logic_vector(signed(DX) + signed(DY));
-- DX + DY + carry, carry update
when "00010" =>
vectorHelper(0) := carry;
if (to_integer(signed(DX)) + to_integer(signed(DY)) + to_integer(signed(vectorHelper)) > 32767) then
outC <= '1';
outALU <= std_logic_vector(to_signed(to_integer(signed(DX))
+ to_integer(signed(DY))
+ to_integer(signed(vectorHelper)) - 32767,16));
else
outC <= '0';
outALU <= std_logic_vector(signed(DX) + signed(DY) + signed(vectorHelper));
end if;
-- DX - DY
when "00011" =>
outALU <= std_logic_vector(signed(DX)-signed(DY));
-- DX and DY
when "00100" =>
outALU <= DX and DY;
-- DX or DY
when "00101" =>
outALU <= DX or DY;
-- DX xor DY
when "00110" =>
outALU <= DX xor DY;
-- not DX
when "00111" =>
outALU <= not DX;
-- arithmetic shift left: DX << DY <3:0>
when "01000" =>
outALU <= std_logic_vector(shift_left(signed(DX), to_integer(unsigned(DY(3 downto 0)))));
-- logical shift right: DX >>> DY <3:0>
when "01001" =>
outALU <= std_logic_vector(shift_right(unsigned(DX), to_integer(unsigned(DY(3 downto 0)))));
-- DX >> DY <3:0>
when "01010" =>
outALU <= std_logic_vector(shift_right(signed(DX), to_integer(unsigned(DY(3 downto 0)))));
-- undefined
when "01011" =>
outALU <= "UUUUUUUUUUUUUUUU";
-- DX << 1, outC: DX[15]
when "01100" =>
outC <= DX(15);
outALU <= std_logic_vector(shift_left(signed(DX), 1));
-- DX >>> 1, outC: DX[0]
when "01101" =>
outC <= DX(0);
outALU <= std_logic_vector(shift_right(unsigned(DX), 1));
-- DX >> 1, outC: DX[0]
when "01110" =>
outC <= DX(0);
outALU <= std_logic_vector(shift_right(signed(DX), 1));
-- undefined
when "01111" =>
outALU <= "UUUUUUUUUUUUUUUU";
-- DX, outC: (DX == DY)
when "10000" =>
outALU <= DX;
if DX = DY then
outC <= '1';
else
outC <= '0';
end if;
-- DX, outC: (DX != DY)
when "10001" =>
outALU <= DX;
if DX = DY then
outC <= '0';
else
outC <= '1';
end if;
-- DX, outC: (DX > DY)
when "10010" =>
outALU <= DX;
if DX > DY then
outC <= '1';
else
outC <= '0';
end if;
-- DX, outC: (DX < DY)
when "10011" =>
outALU <= DX;
if DX < DY then
outC <= '1';
else
outC <= '0';
end if;
-- IMM4
when "10100" =>
vectorHelper(3 downto 0) := imm4;
outALU <= vectorHelper;
-- DX + IMM4
when "10101" =>
vectorHelper(3 downto 0) := imm4;
outALU <= std_logic_vector(signed(DX) + signed(vectorHelper));
-- DX - IMM4
when "10110" =>
vectorHelper(3 downto 0) := imm4;
outALU <= std_logic_vector(signed(DX) - signed(vectorHelper));
-- DX and IMM4
when "10111" =>
vectorHelper(3 downto 0) := imm4;
outALU <= DX and vectorHelper;
-- DX << IMM4
when "11000" =>
outALU <= std_logic_vector(shift_left(signed(DX), to_integer(unsigned(imm4))));
-- DX >>> IMM4
when "11001" =>
outALU <= std_logic_vector(shift_right(unsigned(DX), to_integer(unsigned(imm4))));
-- set bit IMM4 in DX
when "11010" =>
vectorHelper := DX;
vectorHelper(to_integer(unsigned(imm4))) := '1';
outALU <= vectorHelper;
-- clear bit IMM4 in DX
when "11011" =>
vectorHelper := DX;
vectorHelper(to_integer(unsigned(imm4))) := '0';
outALU <= vectorHelper;
-- 111** = undefined
when others =>
outALU <= "UUUUUUUUUUUUUUUU";
end case;
end process ALU;
buffALU : process (outALU, eBuffALU) is
begin
if eBuffALU = '1' then
omnibus <= outALU;
else
omnibus <= (others => 'Z');
end if;
end process buffALU;
buffDX : process (DX, eBuffDX) is
begin
if eBuffDX = '1' then
omnibus <= DX;
else
omnibus <= (others => 'Z');
end if;
end process buffDX;
C : process (clock, nR) is
begin
if nR = '0' then
carry <= '0';
else
if rising_edge(clock) then
if eC = '1' then
carry <= outC;
end if;
end if;
end if;
end process C;
end arcDatapath;
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment