Skip to content

Commit 145d763

Browse files
committed
Add support for unsigned operation instructions
- i32 gt_u, lt_u, ge_u, le_u, div_u and rem_u have been implemented in GammaCPU - GammaALU updated appropriately to support this - Tests added for this new functionality to the CPU & ALU test benches
1 parent 471824a commit 145d763

4 files changed

Lines changed: 533 additions & 57 deletions

File tree

GammaALU.vhdl

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,48 +28,90 @@ begin
2828
result <= std_logic_vector(signed(a) - signed(b));
2929
when 2 => -- MUL
3030
result <= std_logic_vector(resize(signed(a) * signed(b), 32)); -- Resize to 32 bits
31-
when 3 => -- DIV
32-
if b /= "00000000000000000000000000000000" then
33-
result <= std_logic_vector(signed(a) / signed(b));
31+
when 3 => -- DIV (signed division b / a)
32+
if a /= "00000000000000000000000000000000" then
33+
result <= std_logic_vector(signed(b) / signed(a));
3434
else
3535
result <= (others => '0'); -- Handle division by zero
3636
end if;
37-
when 4 => -- equal
37+
when 4 => -- eq (equal) - for i32.eq and i32.eqz
3838
if a = b then
3939
result <= std_logic_vector(to_signed(1, 32));
4040
else
4141
result <= std_logic_vector(to_signed(0, 32));
4242
end if;
43-
when 5 => -- inequality
43+
when 5 => -- ne (not equal) - for i32.ne
4444
if a /= b then
4545
result <= std_logic_vector(to_signed(1, 32));
4646
else
4747
result <= std_logic_vector(to_signed(0, 32));
4848
end if;
49-
when 6 => -- greater than
50-
if a > b then
49+
when 6 => -- gt_s (greater than signed) - for i32.gt_s
50+
if signed(b) > signed(a) then
5151
result <= std_logic_vector(to_signed(1, 32));
5252
else
5353
result <= std_logic_vector(to_signed(0, 32));
5454
end if;
55-
when 7 => -- less than
56-
if a < b then
55+
when 7 => -- lt_s (less than signed) - for i32.lt_s
56+
if signed(b) < signed(a) then
5757
result <= std_logic_vector(to_signed(1, 32));
5858
else
5959
result <= std_logic_vector(to_signed(0, 32));
6060
end if;
61-
when 8 => -- greater than or equal to
62-
if a >= b then
61+
when 8 => -- ge_s (greater than or equal signed) - for i32.ge_s
62+
if signed(b) >= signed(a) then
6363
result <= std_logic_vector(to_signed(1, 32));
6464
else
6565
result <= std_logic_vector(to_signed(0, 32));
6666
end if;
67-
when 9 => -- less than or equal to
68-
if a <= b then
67+
when 9 => -- le_s (less than or equal signed) - for i32.le_s
68+
if signed(b) <= signed(a) then
6969
result <= std_logic_vector(to_signed(1, 32));
7070
else
7171
result <= std_logic_vector(to_signed(0, 32));
7272
end if;
73+
when 10 => -- le_s (less than or equal signed) - duplicate for backward compatibility
74+
if signed(b) <= signed(a) then
75+
result <= std_logic_vector(to_signed(1, 32));
76+
else
77+
result <= std_logic_vector(to_signed(0, 32));
78+
end if;
79+
when 11 => -- gt_u (greater than unsigned)
80+
if unsigned(b) > unsigned(a) then
81+
result <= std_logic_vector(to_signed(1, 32));
82+
else
83+
result <= std_logic_vector(to_signed(0, 32));
84+
end if;
85+
when 12 => -- lt_u (less than unsigned)
86+
if unsigned(b) < unsigned(a) then
87+
result <= std_logic_vector(to_signed(1, 32));
88+
else
89+
result <= std_logic_vector(to_signed(0, 32));
90+
end if;
91+
when 13 => -- ge_u (greater than or equal unsigned)
92+
if unsigned(b) >= unsigned(a) then
93+
result <= std_logic_vector(to_signed(1, 32));
94+
else
95+
result <= std_logic_vector(to_signed(0, 32));
96+
end if;
97+
when 14 => -- le_u (less than or equal unsigned)
98+
if unsigned(b) <= unsigned(a) then
99+
result <= std_logic_vector(to_signed(1, 32));
100+
else
101+
result <= std_logic_vector(to_signed(0, 32));
102+
end if;
103+
when 15 => -- div_u (unsigned division b / a)
104+
if unsigned(a) /= 0 then
105+
result <= std_logic_vector(unsigned(b) / unsigned(a));
106+
else
107+
result <= (others => '0'); -- Handle division by zero
108+
end if;
109+
when 16 => -- rem_u (unsigned remainder b mod a)
110+
if unsigned(a) /= 0 then
111+
result <= std_logic_vector(unsigned(b) mod unsigned(a));
112+
else
113+
result <= (others => '0'); -- Handle division by zero
114+
end if;
73115
when others =>
74116
result <= (others => '0');
75117
end case;

GammaCPU.vhdl

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,34 +140,58 @@ begin
140140
alu_op <= to_unsigned(3, 16); -- DIV
141141
state <= Execute;
142142

143-
-- Comparisions
143+
-- Comparisons
144144
when x"45" => -- i32.eqz
145-
alu_op <= to_unsigned(4, 16); -- Equal to zero
145+
alu_op <= to_unsigned(4, 16); -- Equal (use with b=0)
146146
only_first_stack <= '1';
147147
state <= Execute;
148148

149149
when x"46" => -- i32.eq
150-
alu_op <= to_unsigned(5, 16); -- Equal
150+
alu_op <= to_unsigned(4, 16); -- Equal
151151
state <= Execute;
152152

153153
when x"47" => -- i32.ne
154-
alu_op <= to_unsigned(6, 16); -- Not Equal
154+
alu_op <= to_unsigned(5, 16); -- Not Equal
155155
state <= Execute;
156156

157157
when x"4b" => -- i32.gt_s
158-
alu_op <= to_unsigned(7, 16); -- Greater than
158+
alu_op <= to_unsigned(6, 16); -- Greater than signed
159159
state <= Execute;
160160

161161
when x"48" => -- i32.lt_s
162-
alu_op <= to_unsigned(8, 16); -- Less than
162+
alu_op <= to_unsigned(7, 16); -- Less than signed
163163
state <= Execute;
164164

165165
when x"4e" => -- i32.ge_s
166-
alu_op <= to_unsigned(9, 16); -- Greater than or equal
166+
alu_op <= to_unsigned(8, 16); -- Greater than or equal signed
167167
state <= Execute;
168168

169169
when x"4C" => -- i32.le_s
170-
alu_op <= to_unsigned(10, 16); -- Less than or equal
170+
alu_op <= to_unsigned(9, 16); -- Less than or equal signed
171+
state <= Execute;
172+
173+
when x"4A" => -- i32.gt_u
174+
alu_op <= to_unsigned(11, 16); -- Greater than unsigned
175+
state <= Execute;
176+
177+
when x"49" => -- i32.lt_u
178+
alu_op <= to_unsigned(12, 16); -- Less than unsigned
179+
state <= Execute;
180+
181+
when x"4F" => -- i32.ge_u
182+
alu_op <= to_unsigned(13, 16); -- Greater than or equal unsigned
183+
state <= Execute;
184+
185+
when x"4D" => -- i32.le_u
186+
alu_op <= to_unsigned(14, 16); -- Less than or equal unsigned
187+
state <= Execute;
188+
189+
when x"6E" => -- i32.div_u
190+
alu_op <= to_unsigned(15, 16); -- Unsigned division
191+
state <= Execute;
192+
193+
when x"70" => -- i32.rem_u
194+
alu_op <= to_unsigned(16, 16); -- Unsigned remainder
171195
state <= Execute;
172196

173197
when others =>

0 commit comments

Comments
 (0)