3

I have been searching this for a while and have not been able to replicate any posted solutions online so I was hoping some of you wonderful people could help me out. I am creating an ALU. i have a two 32 bit inputs and one 32 bit output along with a 5 bit shamt and a 4 bit control signal. My code is as follows with the error location commented on.

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

Entity mips_alu IS
    PORT(ALUControl : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    inputA, inputB      : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
    shamt                   : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
    Zero                    : OUT STD_LOGIC;
    ALU_Result          : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
    );
END mips_alu;

ARCHITECTURE behavior of mips_alu IS
BEGIN
    PROCESS(ALUControl)
    BEGIN
        CASE ALUControl is
        WHEN "0000" =>
            ALU_Result <= inputA AND inputB;
        WHEN "0001" =>
            ALU_Result <= inputA OR inputB;
        WHEN "0010" =>
            ALU_Result <= inputA + inputB;
        WHEN "0110" =>
            ALU_Result <= inputA - inputB;
        WHEN "0111" =>
            IF (inputA < inputB) THEN
                ALU_Result <= inputA;
            END IF;
        WHEN "1000" =>
            ALU_Result <= shift_left(inputB, to_integer(unsigned(shamt)));
            -- The line above is where i get my first error, The following lines will have the same issue
        WHEN "1001" =>
            ALU_Result <= shift_right(inputB, shamt);
        WHEN "1010" =>
            ALU_Result <= shift_left(inputB, inputA);
        WHEN "1011" =>
            ALU_Result <= shift_right(inputB, inputA);
        WHEN "1100" =>
            ALU_Result <= inputA NOR inputB;
        WHEN "1101" =>
            ALU_Result <= inputB(31 DOWNTO 16);
        WHEN OTHERS =>
            ALU_Result <= inputA;
        END CASE;
    END PROCESS;
END behavior;

The error I am getting says:

10511 VHDL Qualified Expression error at mips_alu.vhd(33): shift_left type specified in qualified expression must match std_logic_vector type that is implied for expression by context

I have tried several variations of this so if i am missing something please let me know, all help is appreciated as I am a bit of a novice to vhdl

Zannith
  • 429
  • 4
  • 21
  • @user1155120 apologies, i missed the first part of the error code. I am editing to add it. Also I am not sure of what you mean about mixing the Synopsys. ieee.numeric_std_unsigned.all is not recognized. – Zannith Mar 29 '17 at 20:22
  • 1
    Either use std_logic_arith (conv_integer) or use numeric_std and type conversions like crazy, or make your mips_alu ports type unsigned, or use intermediary unsigned variables in the process with type conversions to/from unsigned. –  Mar 29 '17 at 21:13
  • Quartus II/Prime didn't support IEEE package numeric_std_unsigned, which could replace STD_LOGIC_UNSIGNED here as of March 2016. (The issue being you can't use the unsigned declarations in std_logic_arith referenced by std_logic_unsigned with functions in numeric_std made with it's unsigned declaration. Each declaration in VHDL is unique, meaning the two unsigned declarations aren't referencing the same type/subtype). –  Mar 29 '17 at 21:17

2 Answers2

2

In the numeric_std document you can find the function shift_left or shift_right. In both descriptions there you can see that function SHIFT_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;. So you need to use casting of your std_logic_vector to unsigned.
In your case it will looks like:

ALU_Result <= std_logic_vector(shift_left(unsigned(inputB), to_integer(unsigned(shamt))));

end etc. for other lines where you use shift_left or shift_right function.

Roman
  • 375
  • 2
  • 7
  • Yes, that is what I have been looking for, thank you for the link to numeric_std as well. That actually explains my error code too. It is always simpler than I think. – Zannith Mar 30 '17 at 14:08
0

What I usually do is just this:

ALU_Result <= inputB(30 downto 0) & '0';

This stores is ALU_Result a vector equal to InputB shifted once. In case you want to shift it more times you can use a loop.

while (i<to_integer(unsigned(shamt))) loop
ALU_Result <= inputB(30 downto 0) & '0';
i:=i+1;
end loop;

Its not an elegant solution but it will probably work.

For shifting to the right do:

ALU_Result <= '0' & inputB(31 downto 1);
  • Interesting way to do it, and it makes sense, I was able to make the other method work thanks to Roman Matveev. Thank you for your input though! – Zannith Mar 30 '17 at 14:10
  • So I take it the & doesn't mean a logical AND, it means to add onto the end of? I.E.- 1010 & 0 => 10100 or 11 & 1010 => 111010 ? – Chef Flambe Feb 11 '18 at 06:37