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

Error 10327: Can't determine definition of operator ""+""

Altera_Forum
Honored Contributor II
22,138 Views

Hello to everybody, 

could someone tell me what's wrong in the following code?  

 

 

library ieee; 

use ieee.std_logic_1164.all; 

use ieee.numeric_std.all; 

 

entity round16to12 is 

 

 

port  

a : in std_logic_vector(15 downto 0); 

q : out std_logic_vector(11 downto 0) 

); 

 

end entity; 

 

architecture beh of round16to12 is 

signal roundoff : std_logic_vector(11 downto 0) := (0 => a(3), others => '0'); 

begin 

 

process(a) 

begin 

line 23: q <= (not( a(15)) & a(14 downto 4)) + roundoff; 

end process; 

 

end beh; 

 

 

The error message is the following: 

Error (10327): VHDL error at round16to12.vhd(23): can't determine definition of operator ""+"" -- found 0 possible definitions 

 

Thank for your support
0 Kudos
30 Replies
Altera_Forum
Honored Contributor II
11,728 Views

Hello, 

 

addtion isn't defined for std_logic_vector. You can use explicite numeric types SIGNED or UNSIGNED. Alternatively you can use a library that treats all std_logic_vector as SIGNED or UNSIGNED type: IEEE.STD_LOGIC_SIGNED respectively IEEE.STD_LOGIC_UNSIGNED. 

 

Regards, 

Frank 

 

B.T.W: I see this message every time, when I start writing a new component. It's cause VHDL is so strictly typified.
0 Kudos
Altera_Forum
Honored Contributor II
11,728 Views

To add to what Frank said, if you are doing arithmetic, it is quicker (simulation-wise) to use INTEGER types, rather than vectors of bits. Other things that you get from this are errors if you use restricted ranges of integer and it goes outside of the range. This does mean that if you want modulo-n rollover in a counter or similar, you have to code it explicitly: 

 

if (counter + 1 > t_counter'high) then 

counter := 0; 

else 

counter := counter +1; 

end if; 

 

If t_counter'high is a power of 2, then the "counter+1>" comparison will usually optimise out in synthesis. 

 

Cheers, 

Martin
0 Kudos
Altera_Forum
Honored Contributor II
11,728 Views

If you use integer types, declare each object with a specific range if possible. Integer types require 32-bits in Quartus II. If you simply add two integer objects, you'll get a 32-bit adder initially, which Quartus II may or may not be able to optimize fully. For sure, it won't always find the solution you can get by simply defining the appropriate dynamic range for each object. It will certainly improve the compile-time/memory use in Quartus II!  

 

I generally use signed/unsigned from ieee.numeric_std, using integer types only for very limited purposes, such as array indices (it's a pain to convert from signed/unsigned to integer all the time :)
0 Kudos
Altera_Forum
Honored Contributor II
11,728 Views

Does Quartus not optimise based on reachability analysis? If I code a counter that wraps around at 255, does it not infer an 8-bit counter? I know Max Plus II never did, but surely Quartus can do this... 

 

Also, why do you say use signed/unsigned all the time? Most of the time, you only *need* vectors for the top level port pins. Just pass integers around your design hierarchy the rest of the time. Typing to_integer() isn't that much grief anyway is it? :-)? All IMHO of course! 

 

Cheers, 

Martin
0 Kudos
Altera_Forum
Honored Contributor II
11,728 Views

Alternatively use LPM_ADD_SUB, more code to write but less chance of something being misinterpreted than with a +

0 Kudos
Altera_Forum
Honored Contributor II
11,728 Views

Though I expect most synthesis tools to do a decent job optimizing my arithmetic, I don't expect miracles. I almost always specify a precise dynamic range if I use integer types. If you use INTEGER all over the place, I see two problems:  

 

First, most tools extract single hierarchies, which are later merged and optimized. Initially, the tool extracts 32-bits for every INTEGER object. If you know something only stores 8-bits of data, that's a lot of wasted bits that consume runtime and memory.  

 

Second, if you use Incremental Compilation flow, you will find the all-INTEGER approach unworkable. If a partition boundary contains a 32-bit INTEGER port, then it will take 32-bits in the final netlist - the tool can't use the dynamic range of the input to optimize the arithmetic.  

 

I prefer unsigned/signed because they force me to think about the size of my data path, and it's easy to access specific bits in the value.  

 

PS: I think my_ram(addr) looks much better than my_ram(to_integer(addr)) :)
0 Kudos
Altera_Forum
Honored Contributor II
11,728 Views

Hello, 

 

I'm not sure about all implications of using INTEGER type for bit vectors that represent numbers. It should be stated clearly, that it's possible, including entity ports, also at the top level. Compile time behaviour could be different, as HDL Guru mentioned. But if only an insignificant effect, this shouldn't determine the design methodology. 

 

The other thing is functionality when designing with parameterized reusable modules. Numerical parameters then always need associated generics defining ranges exept for a few cases, where the range is fixed by design function, e. g. a MAC address having always 32 bit. There is no basic difference with SIGNED/UNSIGNED or INTEGER. With INTEGER, one could try to have parameters, that are either be SIGNED or UNSIGNED, depending on range generics.  

 

Cause INTEGER type is only an implicite bit vector, without explicitely defining the bit positions, it could be, that bit operations I'm used to with SIGNED/UNSIGNED could be more complicated or even require type conversion. But I didn't yet try, cause my usage of INTEGER is mainly limited to indexes. 

 

It's been said (I think, in another discussion), that INTEGER usage is shown in most VHDL text books. That is correct so far, as the type and the RANGE syntax are shown, but equivalence to bit vectors isn't discussed necessarily. I was surprized at first look, when I found Uwe Meyer-Baese using INTEGER in many examples in digital signal processing with fpga. Many people with some knowledge of VHDL think, INTEGER can't be synthesized at all. 

 

As a last remark, VHDL always need type conversion in some places, cause it is so typified. At least when instantiating Altera LPM or IP cores, they are necessary. Some logic functions can't be inferred from HDL, e. g. dividers or dual port RAM with different port widths. 

 

Regards, 

Frank
0 Kudos
Altera_Forum
Honored Contributor II
11,728 Views

 

--- Quote Start ---  

Hello, 

 

I'm not sure about all implications of using INTEGER type for bit vectors that represent numbers. It should be stated clearly, that it's possible, including entity ports, also at the top level.  

 

 

--- Quote End ---  

 

 

It should also be noted that if you *do* use integers at the top level you'll need an extra wrapper around any post-synth or post-fit netlists you want to simulate, as they'll end up as logic vectors in the end. 

 

 

--- Quote Start ---  

 

Cause INTEGER type is only an implicite bit vector, without explicitely defining the bit positions, it could be, that bit operations I'm used to with SIGNED/UNSIGNED could be more complicated or even require type conversion. But I didn't yet try, cause my usage of INTEGER is mainly limited to indexes. 

 

--- Quote End ---  

 

 

Also agreed - if you want to do bitwise things, it makes sense to use a vector representation from the start.  

 

 

--- Quote Start ---  

 

It's been said (I think, in another discussion), that INTEGER usage is shown in most VHDL text books. That is correct so far, as the type and the RANGE syntax are shown, but equivalence to bit vectors isn't discussed necessarily. I was surprized at first look, when I found Uwe Meyer-Baese using INTEGER in many examples in digital signal processing with fpga. Many people with some knowledge of VHDL think, INTEGER can't be synthesized at all. 

 

--- Quote End ---  

 

 

Not helped by the amount of example code which start with 

use ieee.std_logic_unsigned.all; 

 

and the use of slv's as unsigned vectors :-) 

 

<snip> 

 

Cheers, 

Martin
0 Kudos
Altera_Forum
Honored Contributor II
11,728 Views

I wite a code for multiplier and I have a problem with this erro " can't determine definition of operator ""+"". I have used almost library as you see and tried many ways that I know but it's still bad. Help me plz. can you help me re-write this code or show me a good way to solve. Thanks alot. I use Quatus II , Web edition 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.STD_LOGIC_ARITH.ALL; 

use ieee.numeric_std.all; 

use ieee.std_logic_signed.all; 

--------------------------  

entity mul is 

port(a: in bit_vector(3 downto 0); 

b: in bit_vector(3 downto 0); 

kq: out bit_vector( 7 downto 0)); 

end mul; 

-------------------------- 

architecture mul of mul is  

type arr is array( 0 to 3) of bit_vector(7 downto 0); 

begin  

process(a,b) 

variable x: arr; 

variable t: bit_vector(7 downto 0); 

begin 

for j in 0 to 3 loop 

if b(j)='1' then 

x(j):=("0000"& a); 

x(j):=(x(j) sll j);  

else 

x(j):=(others =>'0'); 

end if; 

t:=(t+x(j)); 

end loop; 

kq<=t; 

end process; 

end mul;
0 Kudos
Altera_Forum
Honored Contributor II
11,729 Views

I have the same problem.. Error (10327): can't determine definition of operator ""+"" -- found 0 possible definitions 

 

I write this program: 

 

LIBRARY ieee; 

USE ieee.std_logic_1164.ALL; 

use ieee.numeric_std.all; 

use ieee.std_logic_signed.all; 

 

ENTITY filter_iir IS 

GENERIC ( L: INTEGER :=3; 

W1: INTEGER :=16; 

W2: INTEGER :=32; 

W3: INTEGER :=33; 

W4: INTEGER :=14 

); 

PORT ( --x_in: IN signed (15 downto 0);; --INPUT 

--y_out: OUT BITS14; --RESULT 

x_in : in BITS16; 

y_out : out signed (31 downto 0);  

 

clk : IN STD_LOGIC); 

END filter_iir; 

 

ARCHITECTURE myiir of FILTER_IIR IS 

 

SIGNAL x : ARRAY16TO3; 

signal x_num : ARRAY32TO3; 

 

constant b0 : signed(W1-1 downto 0) :=x"0119"; 

constant b1 : signed(W1-1 downto 0) :=x"0232"; 

constant b2 : signed(W1-1 downto 0) :=x"0119"; 

constant a1 : signed(W1-1 downto 0) :=x"FFB5"; 

constant a2 : signed(W1-1 downto 0) :=x"00B0"; 

shared variable acc : signed (W2-1 downto 0):= (others => '0');  

shared variable y : signed (W2-1 downto 0):= (others => '0'); -- 28 bit 

shared variable y_den : signed (W2-1 downto 0):= (others => '0'); -- 27 bit (11+16) 

 

BEGIN 

 

sop: PROCESS 

BEGIN 

wait until (clk='1') ; 

 

x(0)<=x_in; 

x_num(0)<=b0*x(0); -- b0x(k) 

debugx<=x_num(0); 

 

x_num(1)<=b1*x(1); -- b1x(k-1) 

debugx1<=x_num(1); 

 

x_num(2)<=b2*x(2); -- b2x(k-2) 

debugx2<=x_num(2); 

 

for i in 0 to L-2 loop 

x(i+1)<=x(i); 

end loop; 

 

for j in 0 to L-3 loop 

y(j+1):=y(j); 

end loop; 

 

 

y(0):=(x_num(0)+x_num(1)+x_num(2)+y_den(0)+y_den(1)); 

 

acc:=y(0); 

 

 

y_den(0):=a1*y(0)(15 downto 0); -- a1y(k-1)  

 

 

y_den(1):=a2*y(1)(15 downto 0); -- a2y(k-2) 

 

 

end process; 

 

y_out <= y(0)(31 downto 0); 

 

end myiir; 

 

 

when it sum these parts Y(0):=(x_num(0)+x_num(1)+x_num(2)+y_den(0)+y_den(1)) the compiler give me an error.. why? 

i use ieee.std_numeric.all library and in this library there is the definition of "+"....?!?!?:confused::confused::confused: 

Boh.. i search the error but i don't understad.. 

so initially i think that this function want the adder at the same lengths.. but i read the source code.. and seem that it isn't a problem... 

 

x_num is array of signed with length 16 and y_den is array of signed with length 32.. and y(0) is 32bit signed register.. 

so i don't know where is the problem? 

can somebody help me..?
0 Kudos
Altera_Forum
Honored Contributor II
11,729 Views

you havent shown the definition of ARRAY32TO3 type.

0 Kudos
Altera_Forum
Honored Contributor II
11,729 Views

Actually, y_den is a single signed number, not an array of signed. Y_den(0) is a single bit - you cannot add that to a signed.

0 Kudos
Altera_Forum
Honored Contributor II
11,729 Views

 

--- Quote Start ---  

Actually, y_den is a single signed number, not an array of signed. Y_den(0) is a single bit - you cannot add that to a signed. 

--- Quote End ---  

 

 

Oh.. Yes..sorry. i forget to post the first file.. with the definition of subtype and type.. so i correct y_den into array32to2 but the error of "+" don't change..  

 

LIBRARY ieee; 

USE ieee.std_logic_1164.ALL; 

use ieee.numeric_std.all; 

use ieee.std_logic_signed.all; 

 

PACKAGE width_bit_signed IS 

SUBTYPE BITS16 IS signed(15 downto 0) ; --11bit 

SUBTYPE BITS32 IS signed(31 downto 0); --22bit 

 

TYPE ARRAY16TO3 IS ARRAY (0 TO 2) OF BITS16; 

TYPE ARRAY32TO2 IS ARRAY (0 TO 1) OF BITS32; 

TYPE ARRAY32TO3 IS ARRAY (0 TO 2) OF BITS32; 

END width_bit_signed; 

 

Mh... i compile this program last week and it function ..then i change the size of the register into 11 and 22 bit instead of 16 and 32 and it don't function so i rewrite the original program with 16 and 32 bit but.. there is alway the error that don't recognize "+" why????:confused::( 

thank for your response Tricky..
0 Kudos
Altera_Forum
Honored Contributor II
11,729 Views

 

--- Quote Start ---  

Oh.. Yes..sorry. i forget to post the first file.. with the definition of subtype and type.. so i correct y_den into array32to2 but the error of "+" don't change..  

 

LIBRARY ieee; 

USE ieee.std_logic_1164.ALL; 

use ieee.numeric_std.all; 

use ieee.std_logic_signed.all; 

 

PACKAGE width_bit_signed IS 

SUBTYPE BITS16 IS signed(15 downto 0) ; --11bit 

SUBTYPE BITS32 IS signed(31 downto 0); --22bit 

 

TYPE ARRAY16TO3 IS ARRAY (0 TO 2) OF BITS16; 

TYPE ARRAY32TO2 IS ARRAY (0 TO 1) OF BITS32; 

TYPE ARRAY32TO3 IS ARRAY (0 TO 2) OF BITS32; 

END width_bit_signed; 

 

Mh... i compile this program last week and it function ..then i change the size of the register into 11 and 22 bit instead of 16 and 32 and it don't function so i rewrite the original program with 16 and 32 bit but.. there is alway the error that don't recognize "+" why????:confused::( 

thank for your response Tricky.. 

--- Quote End ---  

 

 

 

at 19:40 i resolve my problem when i rewrite i don't put y like an array but only single register.. 

sorry.. i'm tired.. all day in front of the pc.. and so i write crazy code... 

Thank you Tricky!:-P 

Can i engage you like my personal debugger??? :o
0 Kudos
Altera_Forum
Honored Contributor II
11,729 Views

i've got the same error for the operator "-". Using signed type and ieee.numeric_std. I would like to ask if my usage of "for" is correct. 

 

 

 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.STD_LOGIC_signed.ALL; 

use IEEE.STD_LOGIC_TEXTIO.ALL; 

use ieee.numeric_std.all; 

 

 

entity stage_1 is 

Port (  

clk : in bit; 

imagem: in SIGNED (19999 DOWNTO 0); 

imagemanterior: in SIGNED (19999 DOWNTO 0); 

Ix: out SIGNED (24999 DOWNTO 0); 

Iy: out SIGNED (24999 DOWNTO 0); 

It: out SIGNED (24999 DOWNTO 0) 

); 

end stage_1; 

 

 

 

 

 

 

architecture Behavioral of stage_1 is 

begin 

 

 

process (clk) 

begin 

If (clk 'event and clk = '1') then 

 

 

for I in 0 to 2448 loop  

Ix(I*10+9 DOWNTO I*10) <= 1/4 * (imagemanterior((I+1)*8+7 DOWNTO (I+1)*8) - imagemanterior(I*8+7 DOWNTO I*8) + imagemanterior ((I+1)*8+407 DOWNTO (I+1)*8+400) - imagemanterior(I*8+407 DOWNTO I*8+400) + imagem((I+1)*8+7 DOWNTO(I+1)*8) - imagem(I*8+7 DOWNTO I*8)+ imagem((I+1)*8+407 DOWNTO(I+1)*8) - imagem((I)*8+407 DOWNTO I*8 +400)); 

Iy(I*10+9 DOWNTO I*10) <= 1/4*(imagemanterior((I*8)+407 DOWNTO (I)*8+400) - imagemanterior(I*8+7 DOWNTO I*8) + imagemanterior((I+1)*8+407 DOWNTO (I+1)*8) - imagemanterior((I+1)*8+7 DOWNTO(I+1)*8) + imagem(I*8+407 DOWNTO I*8+400) - imagem(I*8+7 DOWNTO I*68) + imagem((I+1)*8+407 DOWNTO (I+1)*8+400) -imagem((I+1)*8+7 DOWNTO(I+1)*8)); 

It(I*10+9 DOWNTO I*10) <= 1/4 * (imagem(I*8+7 DOWNTO I*8)- imagemanterior((I*8+7)-I*8) + imagem((I*8)+407 DOWNTO I*8+400)- imagemanterior(I*8+407 DOWNTO I*8+400) +imagem((I+1)*8+7 DOWNTO(I+1)*8)- imagemanterior((I+1)*8+7 DOWNTO(I+1)*8) + imagem((I+1)*8+407 DOWNTO (I+1)*8+400)- imagemanterior((I+1)*8+407 DOWNTO (I+1)*8+400)); 

 

 

end loop; 

 

 

end if ; 

 

 

end process; 

 

end Behavioral;
0 Kudos
Altera_Forum
Honored Contributor II
11,729 Views

wow - those are possibly the largest busses I have ever seen 

Why have you got busses so wide? 

Plus there are many problems. 

1/4 = 0 when it is rounded down. 

Why do you have such a massive for loop?
0 Kudos
Altera_Forum
Honored Contributor II
11,729 Views

 

--- Quote Start ---  

wow - those are possibly the largest busses I have ever seen 

Why have you got busses so wide? 

Plus there are many problems. 

1/4 = 0 when it is rounded down. 

Why do you have such a massive for loop? 

--- Quote End ---  

 

 

 

My idea was to implement the same architecture for pixels (0,0) to (48,48) arriving at the same time in a 50x50 image. Replacing the 1/4 by a division would solve the issue? 

 

Thanks.
0 Kudos
Altera_Forum
Honored Contributor II
11,729 Views

Almost definately not. 

How do you expect a 50x50 image to arrive at the same time? why did you make some massive array of unsigned? why not just a 2d array of unsigned: 

 

type image_array_t is array(0 to 49, 0 to 49) of unsigned(7 downto 0); signal my_image : image_array_t; for x in my_image'range(1) loop for y in my_image'range(2) loop my_image(x,y) <= something; end loop end loop;  

 

But if you expect a 50x50 image to just magically appear, I suspect there is something more fundamentally wrong with your design than a '-' function not working. The error you had will be because you sliced something wrong somewhere (and because it is rather hideous to look at I cant be bothered to find it right now)
0 Kudos
Altera_Forum
Honored Contributor II
11,729 Views

i've got the error for the operator ""-"" in the following code. I'm not sure about accessing the indivdual bits of each unsigned in the array. 

 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use Ieee.numeric_std.all; 

 

use work.genetica_type.all; 

 

entity binario_fitness is 

Port (  

clk : in std_logic; 

individuos: in genetica; 

adaptacao: out fitness; 

somafitness: out unsigned (7 downto 0) 

); 

end binario_fitness; 

 

 

architecture Behavioral of binario_fitness is 

begin 

 

 

 

process (clk) 

begin 

If (clk 'event and clk = '1') then 

 

for x in 0 to 49 loop 

 

adaptacao(x) <= individuos(x)(0)-individuos(x)(1) +individuos(x)(2)- individuos(x)(3)+individuos(x)(4)- individuos(x)(5)+individuos(x)(6)-individuos(x)(7); 

somafitness<=(others=>'0');  

end loop; 

 

end if ; 

 

end process; 

 

end Behavioral; 

which includes the genetica_type in another file: 

 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.STD_LOGIC_TEXTIO.ALL; 

use ieee.numeric_std.all; 

 

package genetica_type is 

type genetica is array(0 to 49) of unsigned(7 downto 0); 

type fitness is array(0 to 49) of unsigned (2 downto 0); 

end package genetica_type;
0 Kudos
Altera_Forum
Honored Contributor II
9,145 Views

Why are you trying to access individual bits of a number? You cannot sum them as they are just std_logic so no arithmetic is defined for them.  

 

I think you need to make a function to count the bits for you.
0 Kudos
Reply