Cannot convert type STD_Logic to type unsigned

601 Views Asked by At

&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

2

There are 2 best solutions below

1
user9858829 On

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.

2
Tricky On

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.