I'm supposed to write a simple 32 Bit Alu in VHDL. Everything is working fine, except for two things. The ALU is supposed to have an carry out and overflow flag and I cant't figure out how to implement that.
First a general question. The circuit diagram shows that for subtraction the ALU inverts the subtrahend and adds "1" to create the negative equivalent of the input value in 2s-complement. Does this mean that I should work with unsigned values for the input? Or should I stick to std_logic_vector?
Since the carry out bit is the bit which does not "fit" into the result word, I tried to zero extend the Summands, create a temporary 33 bit Sum signal and then simply divide the result into Carry Out and actual sum. Unfortunately all I get when simulating is "UU...U" as output for the sum.( I did it as described here: https://en.wikibooks.org/wiki/VHDL_for_FPGA_Design/4-Bit_ALU)
And for the Overflow flag: Since the description of the ALU is behavioral I don't have access to any carries, which means I can't determine if an overflow occured by simply xoring the last two carries(assuming that the values are in 2s-complement, but I'm not quite sure in this point as my first question shows...). Is there another way to identify the overflow? Like simply turning the "An overflow occurs when..." rules one finds on the internet into if statements?
This is my code so far. This version is giving me "UUU...U" for the output when adding/ subtracting.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ALU is
Port ( Clk : in STD_LOGIC;
A : in std_logic_vector (31 downto 0);
B : in std_logic_vector(31 downto 0);
Y : out std_logic_vector(31 downto 0);
OP : in std_logic_vector(2 downto 0);
Nul : out boolean;
Cout : out STD_LOGIC);
end ALU;
architecture Behavioral of ALU is
signal Smd0, Smd1, Sum : std_logic_vector (31 downto 0);
signal temp : std_logic_vector (32 downto 0);
signal Cry : STD_LOGIC;
signal snul : boolean;
begin
Smd0 <= A;
Smd1 <= B;
Y <= Sum;
Cout <= Cry;
nul <= snul;
process(Clk) begin
if (rising_edge(Clk)) then
if ( Sum = "00000000000000000000000000000000") then -------Zero flag
snul <= true;
else
snul <= false;
end if;
case OP is
when "000" =>
Sum <= Smd0 and Smd1;
when "001" =>
Sum <= Smd0 xor Smd1;
when "010" =>
temp <= std_logic_vector((unsigned("0" & Smd0) + unsigned(Smd1)));
Sum <= temp(31 downto 0);
Cry <= temp(32);
when "100" =>
Sum <= Smd0 and not Smd1;
when "101" =>
Sum <= Smd0 xor not Smd1;
when "110" =>
Sum <= std_logic_vector((unsigned(Smd0) - unsigned(Smd1)));
when "111" =>
if (A < B) then
Sum <= "00000000000000000000000000000001";
else
Sum <= "00000000000000000000000000000000";
end if;
when others =>
NULL;
end case;
end if;
end process;
end Behavioral;
Any comments on the code would be greatly appreciated since I'm completely new to VHDL(We talked about it half a lecture...) and this is what I figured out by googling and playing around.
That's the given circuit diagram:
//Edit:
Another thing. My Zero flag does not work properly after "000". Any idea why it's output is good except for the first case?