1 ----------------------------------------------------------------------------------
3 -- Uni : University of York
4 -- Course : Electronic Engineering
5 -- Module : Computer Architectures
6 -- Engineers : Y3839090 & Y3840426
8 -- Create Date : 13:19:20 02/17/2017
9 -- Design Name : ALU_param - Behavioral
10 -- Description : A paramateriable integer ALU.
12 ----------------------------------------------------------------------------------
14 use IEEE.STD_LOGIC_1164.
ALL;
15 use IEEE.NUMERIC_STD.
ALL;
20 N
: natural
:= 8 -- data size in bits
23 A
: in STD_LOGIC_VECTOR (N
-1 downto 0);
24 B
: in STD_LOGIC_VECTOR (N
-1 downto 0);
25 X
: in STD_LOGIC_VECTOR (log2
(N
)-1 downto 0); -- shift/rotate amount input
26 ctrl
: in STD_LOGIC_VECTOR (3 downto 0); -- control signals from opcode
27 O
: out STD_LOGIC_VECTOR (N
-1 downto 0);
28 flags
:out STD_LOGIC_VECTOR (7 downto 0) -- flags
32 architecture Behavioral
of ALU_param
is
34 -- internal signed signal for A and B inpy=uts
35 signal A_itrn
: SIGNED
(N
-1 downto 0);
36 signal B_itrn
: SIGNED
(N
-1 downto 0);
38 -- internal integer for X
39 signal X_itrn
: integer;
41 -- internal signed signal for output
42 signal O_itrn
: SIGNED
(N
-1 downto 0);
45 -- max positive and negitive N bit signed numbers
46 constant max_pos
: SIGNED
(N
-1 downto 0) := to_signed
(( 2 ** (N
-1) ) - 1, N
);
47 constant max_neg
: SIGNED
(N
-1 downto 0) := to_signed
( -2 ** (N
-1) , N
);
51 A_itrn
<= signed
(A
); -- converts A to signed and maps the result to A_itrn
52 B_itrn
<= signed
(B
); -- converts A to signed and maps the result to B_itrn
54 -- converts X to integer and maps the result to X_itrn
55 X_itrn
<= to_integer
(unsigned
(X
));
57 -- converts O_itrn to a plain std_logic_vector and maps it to O
58 O
<= std_logic_vector(O_itrn
);
60 -- Main ALU multiplexer for each possible command
62 A_itrn
when ctrl
= "
0000"
else -- Output A
63 A_itrn
and B_itrn
when ctrl
= "
0100"
else -- Output A & B
64 A_itrn
or B_itrn
when ctrl
= "
0101"
else -- Output A || B
65 A_itrn
xor B_itrn
when ctrl
= "
0110"
else -- Output A xor B
66 not A_itrn
when ctrl
= "
0111"
else -- Output not A
67 A_itrn
+ 1 when ctrl
= "
1000"
else -- Output A + 1
68 A_itrn
- 1 when ctrl
= "
1001"
else -- Output A - 1
69 A_itrn
+ B_itrn
when ctrl
= "
1010"
else -- Output A + B
70 A_itrn
- B_itrn
when ctrl
= "
1011"
else -- Output A - B
71 SHIFT_LEFT
(A_itrn
, X_itrn
) when ctrl
= "
1100"
else -- Output A sla X
72 SHIFT_RIGHT
(A_itrn
, X_itrn
) when ctrl
= "
1101"
else -- Output A sra X
73 ROTATE_LEFT
(A_itrn
, X_itrn
) when ctrl
= "
1110"
else -- Output A rotl X
74 ROTATE_RIGHT
(A_itrn
, X_itrn
) when ctrl
= "
1111"
else -- Output A rotr X
79 -- Will overflow if you add one to the max positive value
80 '1' when ctrl
= "
1000"
and A_itrn
= max_pos
else
82 -- Will overflow if you minus one to the max negitive value
83 '1' when ctrl
= "
1001"
and A_itrn
= max_neg
else
85 -- Will overflow if two neg values added give a pos result
86 '1' when ctrl
= "
1010"
and A_itrn
(N
-1) = '1' and B_itrn
(N
-1) = '1' and O_itrn
(N
-1) = '0' else
87 -- Will overflow if two pos values added give a neg result
88 '1' when ctrl
= "
1010"
and A_itrn
(N
-1) = '0' and B_itrn
(N
-1) = '0' and O_itrn
(N
-1) = '1' else
90 -- Will overflow if a pos value is subtracted from a neg value gives a pos result
91 '1' when ctrl
= "
1011"
and A_itrn
(N
-1) = '1' and B_itrn
(N
-1) = '0' and O_itrn
(N
-1) = '0' else
92 -- Will overflow if a neg value is subtracted from a pos value gives a neg result
93 '1' when ctrl
= "
1011"
and A_itrn
(N
-1) = '0' and B_itrn
(N
-1) = '1' and O_itrn
(N
-1) = '1'
95 -- If none of the above are true then the result hasn't overflown
99 flags
(6) <= '1' when O_itrn
>= 0 else '0'; -- grater than or equal to zero
100 flags
(5) <= '1' when O_itrn
<= 0 else '0'; -- less than or equal to zero
101 flags
(4) <= '1' when O_itrn
> 0 else '0'; -- grater than zero
102 flags
(3) <= '1' when O_itrn
< 0 else '0'; -- less than zero
103 flags
(2) <= '1' when O_itrn
= 1 else '0'; -- one flag
104 flags
(1) <= '1' when O_itrn
/= 0 else '0'; -- not zero flag
105 flags
(0) <= '1' when O_itrn
= 0 else '0'; -- zero flag