-
Notifications
You must be signed in to change notification settings - Fork 0
/
ALU.vhd
151 lines (132 loc) · 3.9 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library WORK;
use WORK.MIPS_CONSTANT_PKG.ALL;
entity ALU is
generic(
N : integer := 64;
M : natural := 6
);
port(
X : in STD_LOGIC_VECTOR(N-1 downto 0);
Y : in STD_LOGIC_VECTOR(N-1 downto 0);
R : out STD_LOGIC_VECTOR(N-1 downto 0);
SHIFT : in STD_LOGIC_VECTOR(M-1 downto 0);
FUNC : in ALU_FUNC
);
end ALU;
architecture Behavioral of ALU is
component Adder is
generic (N : integer := 64);
port (
A : in STD_LOGIC_VECTOR(N-1 downto 0);
B : in STD_LOGIC_VECTOR(N-1 downto 0);
R : out STD_LOGIC_VECTOR(N-1 downto 0);
CARRY_IN : in STD_LOGIC
);
end component;
component ShifterVariable is
generic (
N : natural := 64;
M : natural := 6
);
port (
I : in STD_LOGIC_VECTOR(N-1 downto 0);
O : out STD_LOGIC_VECTOR(N-1 downto 0);
Left : in STD_LOGIC;
Arith : in STD_LOGIC;
Count : in STD_LOGIC_VECTOR(M-1 downto 0)
);
end component;
-- Adder signals
signal add_a : STD_LOGIC_VECTOR(N-1 downto 0);
signal add_b : STD_LOGIC_VECTOR(N-1 downto 0);
signal add_carry_in : STD_LOGIC;
-- Shifter signals
signal shift_left : STD_LOGIC;
signal shift_arith : STD_LOGIC;
-- Result signals
signal r_shift : STD_LOGIC_VECTOR(N-1 downto 0);
signal r_addsub : STD_LOGIC_VECTOR(N-1 downto 0);
signal r_and : STD_LOGIC_VECTOR(N-1 downto 0);
signal r_or : STD_LOGIC_VECTOR(N-1 downto 0);
signal r_xor : STD_LOGIC_VECTOR(N-1 downto 0);
signal r_nor : STD_LOGIC_VECTOR(N-1 downto 0);
signal r_lui : STD_LOGIC_VECTOR(N-1 downto 0);
-- Other signals
signal y_new : STD_LOGIC_VECTOR(N-1 downto 0);
signal result : STD_LOGIC_VECTOR(N-1 downto 0);
begin
ADDER_SUBTRACTOR : Adder
generic map (N => N)
port map(
A => X,
B => y_new,
R => r_addsub,
CARRY_IN => add_carry_in
);
SHIFTER : ShifterVariable
generic map (
N => N,
M => M
)
port map (
I => Y,
O => r_shift,
Left => shift_left,
Arith => shift_arith,
Count => SHIFT
);
INVERT_Y : process(Y, FUNC)
begin
if FUNC = ALU_SUB then
y_new <= not Y;
add_carry_in <= '1';
else
y_new <= Y;
add_carry_in <= '0';
end if;
end process;
SHIFTIFIER : process(FUNC)
begin
case FUNC is
when ALU_SLL =>
shift_left <= '1';
shift_arith <= '0';
when ALU_SRL =>
shift_left <= '0';
shift_arith <= '0';
when ALU_SRA =>
shift_left <= '0';
shift_arith <= '1';
when others =>
shift_left <= '0';
shift_arith <= '0';
end case;
end process;
-- Logic
r_and <= X and Y;
r_or <= X or Y;
r_xor <= X xor Y;
r_nor <= not r_or;
-- LUI
r_lui <= Y(N/2-1 downto 0) & (N/2-1 downto 0 => '0');
RESULTIFIER : process(FUNC, r_shift, r_addsub, r_and, r_or, r_xor, r_nor, r_lui)
begin
case FUNC is
when ALU_SLL => result <= r_shift;
when ALU_SRL => result <= r_shift;
when ALU_SRA => result <= r_shift;
when ALU_ADD => result <= r_addsub;
when ALU_SUB => result <= r_addsub;
when ALU_AND => result <= r_and;
when ALU_OR => result <= r_or;
when ALU_XOR => result <= r_xor;
when ALU_NOR => result <= r_nor;
when ALU_LUI => result <= r_lui;
when others => result <= (others => '0');
end case;
end process;
R <= result;
end Behavioral;