0

&I am trying to create the logic for unsigned addition in the ALU of a 32-bit MIPS single cycle processor but keep getting this error:

cannot convert type logic to type unsigned

This is what I have so far (Feel free to look through it,I feel like its mostly there but I might be a bit off with some of the logic :

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ALU is
    Port (
        A: in  STD_LOGIC_VECTOR (31 downto 0);
        B: in  STD_LOGIC_VECTOR (31 downto 0);
        A_u,B_u:in unsigned(31 downto 0);
        ALUCntl: in  STD_LOGIC_VECTOR (3 downto 0);
        Carryin: in  STD_LOGIC;
        ALUOut: out  STD_LOGIC_VECTOR (31 downto 0);
        Zero: out  STD_LOGIC;
        Carryout: out std_logic;
        Overflow: out  STD_LOGIC
    );
end ALU;

architecture Behavioral of ALU is
    signal ALU_Result : std_logic_vector (31 downto 0);
    signal add_result, sub_result, a32, b32, c32: std_logic_vector(32 downto 0) := (others => '0');
    signal add_ov, sub_ov: std_logic;
begin
    -- Add, Sub, and Bitwise Operations
    with ALUCntl select
        ALU_Result <= add_result(31 downto 0) when "0010", --Add
                      sub_result(31 downto 0) when "0110", --sub
                      A AND B when "0000",
                      A OR  B when "0001",
                      A XOR B when "0011",
                      A NOR B when "1100",
                      A when others; ---condition for all other alu control signals
                      
                      
    ALUOut <= ALU_Result;

    -- Addition Operation and carry out generation
    a32   <= '0' & A;
    b32   <= '0' & B;
    c32(0) <= Carryin;
    add_result <= a32 + b32 + c32;
    sub_result <= a32 - b32;


    -- Unsigned addition
with ALUCntl select
    add_result <= std_logic_vector(unsigned(A_u) + unsigned(B_u) + unsigned(Carryin)) when "0010",
                  std_logic_vector(unsigned(A_u) + unsigned(B_u)) when "0101",
                  (others => '0') when others;
ALU_Result <= add_result(31 downto 0);



    
    -- Unsigned subtraction
    sub_result <= std_logic_vector(unsigned(A_u) - unsigned(B_u));
    ALU_Result <= sub_result(31 downto 0) when ALUCntl = "0100" else ALU_Result;
   
    -- Zero flag
    Zero <= '1' when ALU_Result = x"00000000" else '0';
    


    -- Overflow flag
    add_ov <= (A(31) and B(31) and (not ALU_Result(31))) or ((not A(31)) and (not B(31)) and ALU_Result(31));
    sub_ov <= (A(31) and (not B(31)) and (not ALU_Result(31))) or ((not A(31)) and B(31) and ALU_Result(31));
    with ALUCntl select
        Overflow <= add_ov when "0010",
                    sub_ov when "0110",
                    'Z' when others;

    -- Carryout
    with ALUCntl select
        Carryout <= add_result(32) when "0010",
                    sub_result(32) when "0110",
                    'Z' when others;
process (ALUCntl, A, B) 
begin
    -- Signed SLT
    if (ALUCntl = "1001") then 
        if (signed(A) < signed(B)) then 
            ALU_Result <= "00000001"; -- set ALU output to 1 if A < B
        else 
            ALU_Result <= "00000000"; -- set ALU output to 0 if A >= B
        end if;
    end if;

    -- Unsigned SLT
    if (ALUCntl = "1010") then 
        if (unsigned(A) < unsigned(B)) then 
            ALU_Result <= "00000001"; -- set ALU output to 1 if A < B
        else 
            ALU_Result <= "00000000"; -- set ALU output to 0 if A >= B
        end if;
    end if;
end process;

end Behavioral;

I think

  • 1
    Welcome to StackOverflow! Please take the [tour] to learn how this site works, and read "[ask]". -- I have formatted your question to show the source as code. Please get used to this if you show code. -- Please add a [mre] by [edit]ing your question. – the busybee Feb 27 '23 at 09:07
  • It seems that the issue is with the `A_u` variables. Can you add to the question how are they defined? – Fra93 Feb 27 '23 at 11:44
  • It'd be useful to have the complete error message. besides the semantic error pointing to line 49 character position (CarryIn, declared as type std_logic which is not closely related to type unsigned), there are numerous other errors. This one is addressed by the standard (e.g. IEEE Std 1076-2008 3.6 Types conversion). CarryIn could be converted to an unsigned array type without the type conversion by concatenating an empty string `std_logic_vector(unsigned(A_u) + unsigned(B_u) + "" & Carryin)`. – user16145658 Feb 27 '23 at 23:05

2 Answers2

3

The problem is that CarryIn is simply a single std_logic, but arithmatic with signed or unsigned requires it to be part of an array. You simply cannot convert an enumerated type like std_logic into an array, you have to create an array aggregate from it, and it is particularly easy because unsigned or signed are simply arrays of std_logic like std_logic_vector. There are several options here:

  1. Use an aggregate assignment
std_logic_vector(unsigned(A_u) + unsigned(B_u) + (0=>Carryin));

This works because you are assigning CarryIn to bit 0 of an array, and the compiler knows it must be unsigned because of the context of being part of a "+" function

  1. Concatenate with a null array.
std_logic_vector(unsigned(A_u) + unsigned(B_u) + (""&Carryin));

Because VHDL allows null arrays, and "" is simply a 0 length bit string literal, it now knows it can create an array, and then it knows it is unsigned from the context.

  1. Use a temporary signal

probably the most involved, but is fine:

signal cin_a : unsigned(0 downto 0);

cin_a(0) <=  CarryIn;

std_logic_vector(unsigned(A_u) + unsigned(B_u) + cin_a)

Again, now you know it is an unsigned.

Tricky
  • 3,791
  • 3
  • 10
  • 23
  • Sadly none of those replacements worked , I am fairly certain it cannot be this hard to preform unsigned addition in an ALU. – Iman Kassim Mar 01 '23 at 08:01
  • you need to update the original post with the updated code. Simply saying "it doesnt work" makes me believe you have not done it correctly or done something else in error. I know the above all work for signed/unsigned addition of std_logic signals. – Tricky Mar 01 '23 at 09:20
-1

i guess it's the carryin that cause problem, it's just 1bit so doesn't make sens to convert it to either unsigned or signed.

  • A 1 bit `std_logic` can easily be converted to either, and can help with the symantics of VHDL. the simplest way would be with `"" & my_sl` which may or may not need a qualifier depending on the context. – Tricky Feb 27 '23 at 16:42