Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16606 Discussions

STD_LOGIC_VECTOR multipication

Altera_Forum
Honored Contributor II
1,576 Views

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
0 Kudos
10 Replies
Altera_Forum
Honored Contributor II
462 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
462 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
462 Views

Hi,  

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

 

Pay attention to x"3F" that might be considered as a negative number.
0 Kudos
Altera_Forum
Honored Contributor II
462 Views

 

--- 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.
0 Kudos
Altera_Forum
Honored Contributor II
462 Views

 

--- 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! 

--- 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.
0 Kudos
Altera_Forum
Honored Contributor II
462 Views

Thanks FvM,  

 

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

D
0 Kudos
Altera_Forum
Honored Contributor II
462 Views

Thanks all. Really helpful as always. 

D
0 Kudos
Altera_Forum
Honored Contributor II
462 Views

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!
0 Kudos
Altera_Forum
Honored Contributor II
462 Views

[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);
0 Kudos
Altera_Forum
Honored Contributor II
462 Views

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

D
0 Kudos
Reply