1 |
2 |
riedelx |
library IEEE;
|
2 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
3 |
|
|
use IEEE.STD_LOGIC_ARITH.ALL;
|
4 |
|
|
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
5 |
|
|
|
6 |
|
|
use work.TinyXconfig.ALL;
|
7 |
|
|
|
8 |
|
|
-- Uncomment the following lines to use the declarations that are
|
9 |
|
|
-- provided for instantiating Xilinx primitive components.
|
10 |
|
|
--library UNISIM;
|
11 |
|
|
--use UNISIM.VComponents.all;
|
12 |
|
|
|
13 |
|
|
entity ALU is
|
14 |
|
|
Port ( opa : in cpuWord;
|
15 |
|
|
opb : in cpuWord;
|
16 |
|
|
res : out cpuWord;
|
17 |
|
|
cin : in std_logic;
|
18 |
|
|
cout : out std_logic;
|
19 |
|
|
zero : out std_logic;
|
20 |
|
|
sign : out std_logic;
|
21 |
|
|
over : out std_logic;
|
22 |
|
|
what : in std_logic_vector(3 downto 0));
|
23 |
|
|
end ALU;
|
24 |
|
|
|
25 |
|
|
architecture Behavioral of ALU is
|
26 |
|
|
|
27 |
|
|
constant alu_mov : std_logic_vector(3 downto 0) := "0000";
|
28 |
|
|
constant alu_and : std_logic_vector(3 downto 0) := "0001";
|
29 |
|
|
constant alu_or : std_logic_vector(3 downto 0) := "0010";
|
30 |
|
|
constant alu_xor : std_logic_vector(3 downto 0) := "0011";
|
31 |
|
|
constant alu_add : std_logic_vector(3 downto 0) := "0100";
|
32 |
|
|
constant alu_sub : std_logic_vector(3 downto 0) := "0101";
|
33 |
|
|
constant alu_ror : std_logic_vector(3 downto 0) := "0110";
|
34 |
|
|
constant alu_lsr : std_logic_vector(3 downto 0) := "0111";
|
35 |
|
|
constant alu_lsra : std_logic_vector(3 downto 0) := "1000";
|
36 |
|
|
constant alu_swap : std_logic_vector(3 downto 0) := "1001";
|
37 |
|
|
constant alu_swapb : std_logic_vector(3 downto 0) := "1010";
|
38 |
|
|
constant alu_inc : std_logic_vector(3 downto 0) := "1011";
|
39 |
|
|
constant alu_dec : std_logic_vector(3 downto 0) := "1100";
|
40 |
|
|
constant alu_rorb : std_logic_vector(3 downto 0) := "1101";
|
41 |
|
|
|
42 |
|
|
begin
|
43 |
|
|
|
44 |
|
|
assert XLEN > 31 report "XLEN must at least 32 and multiple of 8";
|
45 |
|
|
assert (XLEN rem 8) = 0 report "XLEN must at least 32 and multiple of 8";
|
46 |
|
|
|
47 |
|
|
process(opa, opb, cin, what)
|
48 |
|
|
variable temp : std_logic_vector(XLEN downto 0);
|
49 |
|
|
variable ctr : integer;
|
50 |
|
|
variable help : std_logic_vector((XLEN-1) downto 0);
|
51 |
|
|
variable helper : std_logic_vector(XLEN downto 0);
|
52 |
|
|
begin
|
53 |
|
|
case what is
|
54 |
|
|
when alu_mov =>
|
55 |
|
|
res <= opb;
|
56 |
|
|
temp := ("0" & opb);
|
57 |
|
|
cout <= cin;
|
58 |
|
|
over <= '0';
|
59 |
|
|
when alu_and =>
|
60 |
|
|
res <= opa and opb;
|
61 |
|
|
temp := ("0" & opa) and ("0" & opb);
|
62 |
|
|
cout <= cin;
|
63 |
|
|
over <= '0';
|
64 |
|
|
when alu_or =>
|
65 |
|
|
res <= opa or opb;
|
66 |
|
|
temp := ("0" & opa) or ("0" & opb);
|
67 |
|
|
cout <= cin;
|
68 |
|
|
over <= '0';
|
69 |
|
|
when alu_xor =>
|
70 |
|
|
res <= opa xor opb;
|
71 |
|
|
temp := ("0" & opa) xor ("0" & opb);
|
72 |
|
|
cout <= cin;
|
73 |
|
|
over <= '0';
|
74 |
|
|
when alu_add =>
|
75 |
|
|
res <= opa + opb + (getStdLogicVectorZeroes(XLEN-1) & cin);
|
76 |
|
|
temp := ("0" & opa) + ("0" & opb) + (getStdLogicVectorZeroes(XLEN-1) & cin);
|
77 |
|
|
cout <= temp(XLEN);
|
78 |
|
|
over <= (opa(XLEN-1) and opb(XLEN-1) and not temp(XLEN-1)) OR (not opa(XLEN-1) and not opb(XLEN-1) and temp(XLEN-1));
|
79 |
|
|
when alu_sub =>
|
80 |
|
|
res <= opa - opb - (getStdLogicVectorZeroes(XLEN-1) & cin);
|
81 |
|
|
temp := ("0" & opa) - ("0" & opb) - (getStdLogicVectorZeroes(XLEN-1) & cin);
|
82 |
|
|
cout <= temp(XLEN);
|
83 |
|
|
over <= (opa(XLEN-1) and opb(XLEN-1) and not temp(XLEN-1)) OR (not opa(XLEN-1) and not opb(XLEN-1) and temp(XLEN-1));
|
84 |
|
|
when alu_ror =>
|
85 |
|
|
res <= opa(0) & opa((XLEN-1) downto 1);
|
86 |
|
|
temp := "0" & opa(0) & opa((XLEN-1) downto 1);
|
87 |
|
|
cout <= opa(0);
|
88 |
|
|
over <= '0';
|
89 |
|
|
when alu_lsr =>
|
90 |
|
|
res <= cin & opa((XLEN-1) downto 1);
|
91 |
|
|
temp := "00" & opa((XLEN-1) downto 1);
|
92 |
|
|
cout <= opa(0);
|
93 |
|
|
over <= '0';
|
94 |
|
|
when alu_lsra =>
|
95 |
|
|
res <= opa(XLEN-1) & opa((XLEN-1) downto 1);
|
96 |
|
|
temp := "0" & opa(XLEN-1) & opa((XLEN-1) downto 1);
|
97 |
|
|
cout <= opa(0);
|
98 |
|
|
over <= '0';
|
99 |
|
|
when alu_swap =>
|
100 |
|
|
res <= opa((XLEN/2-1) downto 0) & opa((XLEN-1) downto (XLEN/2));
|
101 |
|
|
temp := "0" & opa((XLEN/2-1) downto 0) & opa((XLEN-1) downto (XLEN/2));
|
102 |
|
|
cout <= cin;
|
103 |
|
|
over <= '0';
|
104 |
|
|
when alu_swapb =>
|
105 |
|
|
ctr := XLEN / 8;
|
106 |
|
|
help := opa(7 downto 0) & getStdLogicVectorZeroes(XLEN-8);
|
107 |
|
|
swb: for index in 1 to ctr-2 loop
|
108 |
|
|
help := help or (getStdLogicVectorZeroes(index*8) & opa(((index+1)*8-1) downto (index*8)) & getStdLogicVectorZeroes((ctr-index-1)*8));
|
109 |
|
|
end loop;
|
110 |
|
|
help := help or (getStdLogicVectorZeroes(XLEN-8) & opa((XLEN-1) downto (XLEN-8)));
|
111 |
|
|
res <= help;
|
112 |
|
|
helper := "0" & opa(7 downto 0) & getStdLogicVectorZeroes(XLEN-8);
|
113 |
|
|
swt: for index in 1 to ctr-2 loop
|
114 |
|
|
helper := helper or ("0" & getStdLogicVectorZeroes(index*8) & opa(((index+1)*8-1) downto (index*8)) & getStdLogicVectorZeroes((ctr-index-1)*8));
|
115 |
|
|
end loop;
|
116 |
|
|
helper := helper or ("0" & getStdLogicVectorZeroes(XLEN-8) & opa((XLEN-1) downto (XLEN-8)));
|
117 |
|
|
temp := helper;
|
118 |
|
|
--res <= opa(7 downto 0) & opa(15 downto 8) & opa(23 downto 16) & opa(31 downto 24);
|
119 |
|
|
--temp := "0" & opa(7 downto 0) & opa(15 downto 8) & opa(23 downto 16) & opa(31 downto 24);
|
120 |
|
|
cout <= cin;
|
121 |
|
|
over <= '0';
|
122 |
|
|
when alu_inc =>
|
123 |
|
|
res <= opa + "1" + cin;
|
124 |
|
|
temp := opa + "1" + cin;
|
125 |
|
|
cout <= temp(XLEN);
|
126 |
|
|
over <= '0';
|
127 |
|
|
when alu_dec =>
|
128 |
|
|
res <= opa - "1" - cin;
|
129 |
|
|
temp := opa - "1" - cin;
|
130 |
|
|
cout <= temp(XLEN);
|
131 |
|
|
over <= '0';
|
132 |
|
|
when alu_rorb =>
|
133 |
|
|
res <= opa(7 downto 0) & opa((XLEN-1) downto 8);
|
134 |
|
|
temp := "0" & opa(7 downto 0) & opa((XLEN-1) downto 8);
|
135 |
|
|
cout <= cin;
|
136 |
|
|
over <= '0';
|
137 |
|
|
when others =>
|
138 |
|
|
res <= getStdLogicVectorZeroes(XLEN);
|
139 |
|
|
temp := getStdLogicVectorZeroes(XLEN);
|
140 |
|
|
cout <= cin;
|
141 |
|
|
over <= '0';
|
142 |
|
|
end case;
|
143 |
|
|
sign <= temp(XLEN-1);
|
144 |
|
|
if temp((XLEN-1) downto 0) = 0 then
|
145 |
|
|
zero <= '1';
|
146 |
|
|
else
|
147 |
|
|
zero <= '0';
|
148 |
|
|
end if;
|
149 |
|
|
end process;
|
150 |
|
|
end Behavioral;
|
151 |
|
|
|