Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

STD_LOGIC_VECTOR multipication

I keep getting an error using the '*' to multiply SLV's:

use IEEE.numeric.std.all;

constant COEFF : STD_LOGIC_VECTOR (5 downto 0) := x"3F";

signal EXPx63_LTCHD : STD_LOGIC_VECTOR(27 downto 0);

signal EXP_LTCHD: STD_LOGIC_VECTOR(22 downto 0);

EXPx63_LTCHD <= unsigned(EXP_LTCHD) * unsigned(COEFF);

error is:

Error (10327): VHDL error at calculate.vhd(158): can't determine definition of operator ""*"" -- found 0 possible definitions

What have i done wrong in here?

D

10 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The multiplication returns and unsigned, not a std_logic_Vector. So with your code, you need to write:

    EXPx63_LTCHD <= std_logic_Vector( unsigned(EXP_LTCHD) * unsigned(COEFF) );

    But why have you used std_logic_vector. Surely its better just to write:

    
    constant COEFF : unsigned(5 downto 0) := x"3F";
    signal EXPx63_LTCHD : unsigned(27 downto 0);
    signal EXP_LTCHD:	unsigned(22 downto 0);
    EXPx63_LTCHD <= EXP_LTCHD * COEFF;
    

    Remember, ports do NOT have to be std_logic_Vector.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I am trying to write the VHDL code to do the same job as a few of the modules! I used SLV's with these modules and it all worked OK. Then I came back to the code and started using Integers to do the calculation and found I soon went past 32bits and overflowed some of my variables (as i believe integers are limited to 32bit). So I went back and started using SLV's in my claculations as I suspect they cannot be limited in the same way as integers.

    But you say that unsigned is the way to go? Can I get past 32bit arithmetic problems this way?

    Many thanks again tricky for your quick response!

    D
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    EXPx63_LTCHD <= std_logic_vector(unsigned(EXP_LTCHD) * unsigned(COEFF));

    Pay attention to x"3F" that might be considered as a negative number.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    EXPx63_LTCHD <= std_logic_vector(unsigned(EXP_LTCHD) * unsigned(COEFF));

    --- Quote End ---

    Yes this solves the first problem involved with the code.

    --- Quote Start ---

    Pay attention to x"3F" that might be considered as a negative number.

    --- Quote End ---

    There's no reason to expect this. But x"3F" is 8 bit length where 6 bits are needed.

    "111111" is the intended 6-Bit value.

    Third problem, the product bit length must be increased by one.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I am trying to write the VHDL code to do the same job as a few of the modules! I used SLV's with these modules and it all worked OK. Then I came back to the code and started using Integers to do the calculation and found I soon went past 32bits and overflowed some of my variables (as i believe integers are limited to 32bit). So I went back and started using SLV's in my claculations as I suspect they cannot be limited in the same way as integers.

    But you say that unsigned is the way to go? Can I get past 32bit arithmetic problems this way?

    Many thanks again tricky for your quick response!

    D

    --- Quote End ---

    Technically, integer has no bits, but it's maximum value is determined by the compiler. I think the VHDL LRM allows for any sized integer (8, 16, 32 or 64bit), but everyone sticks with 32 bits (well not quite - range is -2^-31+1 to 2^31-1, so not quite the full 32 bits range). Unisnged and signed are just arrays that allows the user to set the size using a natual, so an unsigned, signed or std_logic_vector can be up to 2^31 bits wide. SO yes, you get well around the integer limitations doing this (But never try to cast a number wider than 32 bits - 31 for unsigned - back to an integer type).

    --- Quote Start ---

    Pay attention to x"3F" that might be considered as a negative number.

    --- Quote End ---

    It wont be in unsigned arithmatic.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks FvM,

    I did spot the size issue with the product eventually. Thanks for your help.

    D
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I do have one final quick question relating to this:

    I have a variable called duty that is an unsigned(5 downto 0); and i want to slice off the (5 downto 0) bits of the following equation and assign it to DUTY;

    DUTY <= (((WIDTH_LTCHD*PERCENT)/PERIOD_LTCHD);

    AT the moment (in the example above) duty is unnecesarily 23 bits wide due to the variables in the equation, but I know for a fact (due to limits) that the result cannot be bigger than a 6bit result;

    I tried a few variations and couldnt get the slice right; i tried somethings like:

    DUTY <= (((WIDTH_LTCHD*PERCENT)/PERIOD_LTCHD),(5 downto 0));

    Thanks guys!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    [pedant]Its not a variable, with use of the <= assignment I see its a signal - there is a difference between the two [/pedant]

    try:

    DUTY <= ((WIDTH_LTCHD*PERCENT)/PERIOD_LTCHD)(5 downto 0);

    otherwise just use a temporary 23 bit signal and slice that:

    temp <= (WIDTH_LTCHD*PERCENT)/PERIOD_LTCHD;

    DATA <= temp(5 downto 0);
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks Tricky, sometimes I cant get out of thinking like a 'C' programmer, hence variables everywhere! ;-)

    D