-
Notifications
You must be signed in to change notification settings - Fork 27
/
alu.vhd
76 lines (64 loc) · 2.32 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
library ieee;
use ieee.std_logic_1164.all;
entity alu is
port (
n : in std_logic_vector (3 downto 0);
m : in std_logic_vector (3 downto 0);
opcode : in std_logic_vector (1 downto 0);
d : out std_logic_vector (3 downto 0);
cout : out std_logic
);
end alu;
architecture behavioral of alu is
component carry_ripple_adder
port (
a : in std_logic_vector (3 downto 0);
b : in std_logic_vector (3 downto 0);
ci : in std_logic;
s : out std_logic_vector (3 downto 0);
co : out std_logic
);
end component;
signal m_inverted : std_logic_vector (3 downto 0);
signal nand_result : std_logic_vector (3 downto 0);
signal nor_result : std_logic_vector (3 downto 0);
signal adder_result : std_logic_vector (3 downto 0);
signal adder_carry_out : std_logic;
signal operation_type : std_logic;
signal sub : std_logic;
begin
-- Make sense from control bits
operation_type <= opcode(1); -- Are we doing logical or arithmetic operation?
sub <= opcode(0); -- Are we doing addition/NAND or subtraction/NOR?
-- Here we calculate inverted bits for subtraction if necessary
m_inverted(0) <= not m(0);
m_inverted(1) <= not m(1);
m_inverted(2) <= not m(2);
m_inverted(3) <= not m(3);
-- Addition
adder_instance: carry_ripple_adder
port map(
a => n,
b => m_inverted,
ci => '1',
s => adder_result,
co => adder_carry_out
);
-- Logical NAND operation
nand_result(0) <= not m(0) and n(0);
nand_result(1) <= not m(1) and n(1);
nand_result(2) <= not m(2) and n(2);
nand_result(3) <= not m(3) and n(3);
-- Logical NOR operation
nor_result(0) <= not m(0) or n(0);
nor_result(1) <= not m(1) or n(1);
nor_result(2) <= not m(2) or n(2);
nor_result(3) <= not m(3) or n(3);
-- Select output based on which operation was requested
d <= nand_result when opcode ="10" else
nor_result when opcode ="11" else
adder_result;
-- Carry out bit
cout <= (adder_carry_out xor sub) when operation_type = '0' else
'0';
end;