-
Notifications
You must be signed in to change notification settings - Fork 1
/
ALU.vhd
132 lines (127 loc) · 4.46 KB
/
ALU.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
USE std.textio.ALL;
USE ieee.std_logic_textio.ALL;
USE IEEE.math_real.ALL;
USE IEEE.STD_LOGIC_MISC.ALL;
ENTITY ALU IS
PORT (
Cin : IN STD_LOGIC;
Sel : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
Reg1, Reg2 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
Result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
Flags : OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
);
END ALU;
ARCHITECTURE ALUArch OF ALU IS
COMPONENT Adder IS
GENERIC (n : INTEGER := 8);
PORT (
First, Second : IN STD_LOGIC_VECTOR(n - 1 DOWNTO 0);
CarryIn : STD_LOGIC;
Sum : OUT STD_LOGIC_VECTOR(n - 1 DOWNTO 0);
CarryOut : OUT STD_LOGIC);
END COMPONENT Adder;
COMPONENT Rotate IS PORT (
Data : IN STD_LOGIC_VECTOR(32 DOWNTO 0);
Amount : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
Enable : IN STD_LOGIC;
Direction : IN STD_LOGIC;
RData : OUT STD_LOGIC_VECTOR(32 DOWNTO 0));
END COMPONENT Rotate;
SIGNAL TempA, TempB, TempOut : STD_LOGIC_VECTOR (31 DOWNTO 0);
SIGNAL TempCin, TempCout : STD_LOGIC;
SIGNAL TempResult : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL Temp : STD_LOGIC_VECTOR(32 DOWNTO 0);
SIGNAL RotateDirction : STD_LOGIC;
SIGNAL RotateOut : STD_LOGIC_VECTOR(32 DOWNTO 0);
SIGNAL RotateEnable : STD_LOGIC;
BEGIN
u0 : Adder GENERIC MAP(32) PORT MAP(TempA, TempB, TempCin, TempOut, TempCout);
r0 : Rotate PORT MAP(Temp, Reg2,RotateEnable ,RotateDirction, RotateOut);
RotateEnable <=
'1' WHEN Sel = "1011" OR Sel = "1100" ELSE
'0';
PROCESS (Sel, Reg1, Reg2, TempOut, RotateOut,TempCout)
BEGIN
Temp <= Cin & Reg1;
IF Sel = "0000" THEN --passing the first operand
TempResult <= Reg1;
Flags(2) <= Cin;
ELSIF Sel = "0001" THEN --passing the second operand
TempResult <= Reg2;
Flags(2) <= Cin;
ELSIF Sel = "0010" THEN -- A+B
TempA <= Reg1;
TempB <= Reg2;
TempCin <= '0';
TempResult <= TempOut;
Flags(2) <= TempCout;
ELSIF Sel = "0011" THEN -- A-B
TempA <= Reg1;
TempB <= NOT Reg2;
TempCin <= '1';
TempResult <= TempOut;
Flags(2) <= TempCout;
ELSIF Sel = "0100" THEN -- A AND B
TempResult <= Reg1 AND Reg2;
Flags(2) <= Cin;
ELSIF Sel = "0101" THEN -- A OR B
TempResult <= Reg1 OR Reg2;
Flags(2) <= Cin;
ELSIF Sel = "0110" THEN -- A XOR B
TempResult <= Reg1 XOR Reg2;
Flags(2) <= Cin;
ELSIF Sel = "0111" THEN -- NOT A
TempResult <= NOT Reg1;
Flags(2) <= Cin;
ELSIF Sel = "1000" THEN -- Negative A
TempA <= (OTHERS => '0');
TempB <= NOT Reg1;
TempCin <= '1';
TempResult <= TempOut;
Flags(2) <= TempCout;
ELSIF Sel = "1001" THEN -- A+1
TempA <= Reg1;
TempB <= (OTHERS => '0');
TempB(0) <= '1';
TempCin <= '0';
TempResult <= TempOut;
Flags(2) <= TempCout;
ELSIF Sel = "1010" THEN -- A-1
TempA <= Reg1;
TempB <= (OTHERS => '1');
TempCin <= '0';
TempResult <= TempOut;
Flags(2) <= TempCout;
ELSIF Sel = "1011" THEN -- RCL -- assume that the value of Reg2 betwenn 0 and 32
RotateDirction <= '0';
TempResult <= RotateOut(31 DOWNTO 0);
Flags(2) <= RotateOut(32);
ELSIF Sel = "1100" THEN -- RCR
RotateDirction <= '1';
TempResult <= RotateOut(31 DOWNTO 0);
Flags(2) <= RotateOut(32);
ELSIF Sel = "1101" THEN -- BitSet
Flags(2) <= Reg1(to_integer(unsigned(Reg2)));
TempResult <= Reg1;
TempResult(to_integer(unsigned(Reg2))) <= '1';
ELSIF Sel = "1110" THEN
TempA <= Reg1;
TempB <= x"00000002";
TempCin <= '0';
TempResult <= TempOut;
Flags(2) <= TempCout;
ELSIF Sel = "1111" THEN
TempA <= Reg1;
TempB <= x"FFFFFFFE";
TempCin <= '0';
TempResult <= TempOut;
Flags(2) <= TempCout;
END IF;
END PROCESS;
Result <= TempResult;
Flags(1) <= TempResult(31); -- Negative Flag
Flags(0) <= (NOT OR_REDUCE(TempResult)); --Zero Flag
END ALUArch;