Xilinx ISE: found '0' definitions of operator "+", cannot determine exact overloaded matching definition for "+" - vhdl

I am writing Bin to BCD code Multiplier and in the top module Xilinx ISE gives this error:
Line 30: found '0' definitions of operator "+", cannot determine exact
overloaded matching definition for "+"
while I have mapped the ports to the top module
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
-- library UNISIM;
-- use UNISIM.VComponents.all;
entity EightDisplayControl is
Port ( clk : in STD_LOGIC;
leftL, near_leftL : in STD_LOGIC_VECTOR (3 downto 0);
near_rightL, rightL : in STD_LOGIC_VECTOR (3 downto 0);
leftR, near_leftR : in STD_LOGIC_VECTOR (3 downto 0);
near_rightR, rightR : in STD_LOGIC_VECTOR (3 downto 0);
select_display : out STD_LOGIC_VECTOR (7 downto 0);
segments : out STD_LOGIC_VECTOR (6 downto 0));
end EightDisplayControl;
architecture Behavioral of EightDisplayControl is
signal Display : std_logic_vector(2 downto 0);
signal div : std_logic_vector(16 downto 0);
signal convert_me : std_logic_vector(3 downto 0);
begin
div<= div+1 when rising_edge(clk);
Display <= div(16 downto 14);
process(Display, leftL, near_leftL, near_rightL, rightL, leftR, near_leftR, near_rightR, rightR)
begin
if Display ="111" then select_display <= "11111110"; convert_me <= leftL;
elsif Display ="110" then select_display <= "11111101"; convert_me <= near_leftL;
elsif Display ="101" then select_display <= "11111011"; convert_me <= near_rightL;
elsif Display ="100" then select_display <= "11110111"; convert_me <= rightL;
elsif Display ="011" then select_display <= "11101111"; convert_me <= leftR;
elsif Display ="010" then select_display <= "11011111"; convert_me <= near_leftR;
elsif Display ="001" then select_display <= "10111111"; convert_me <= near_rightR;
else select_display <= "01111111"; convert_me <= rightR;
end if;
end process;
decoder : entity work.segment_decoder
port map (convert_me, segments);
end Behavioral;

As has already been stated in comments, the problem is that you have defined signal div as a std_logic_vector. The IEEE.numeric_std library does not define an addition operation for std_logic_vector.
Looking in the library we see:
--============================================================================
-- Id: A.3
function "+" (L, R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
-- Result: Adds two UNSIGNED vectors that may be of different lengths.
-- Id: A.4
function "+" (L, R: SIGNED) return SIGNED;
-- Result subtype: SIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
-- Result: Adds two SIGNED vectors that may be of different lengths.
-- Id: A.5
function "+" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
-- Result subtype: UNSIGNED(L'LENGTH-1 downto 0).
-- Result: Adds an UNSIGNED vector, L, with a non-negative INTEGER, R.
-- Id: A.6
function "+" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED(R'LENGTH-1 downto 0).
-- Result: Adds a non-negative INTEGER, L, with an UNSIGNED vector, R.
-- Id: A.7
function "+" (L: INTEGER; R: SIGNED) return SIGNED;
-- Result subtype: SIGNED(R'LENGTH-1 downto 0).
-- Result: Adds an INTEGER, L(may be positive or negative), to a SIGNED
-- vector, R.
-- Id: A.8
function "+" (L: SIGNED; R: INTEGER) return SIGNED;
-- Result subtype: SIGNED(L'LENGTH-1 downto 0).
-- Result: Adds a SIGNED vector, L, to an INTEGER, R.
--============================================================================
This clearly shows that only functions for adding unsigned, signed, natural, and integer are supported.
As #Tricky has stated in the comments, you need to define div as an unsigned.

Related

Can't normally see result in wave (Modesim)

I have code designed for Vivid software. How I can translate this code into ModelSIM? In vivado, I should get the following values, but in modelsim I get completely different ones.
This is noise generator. Successful in adding pseudorandom noise sequence to our sine wave, but now we are trying to add Gaussian noise. The code and the simulation results for ADDITION OF PSEUDORANDOM NOISE SEQUENCE TO SINE WAVE IS GIVEN BELOW:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL; --try to use this library as much as possible.
entity sine_wave is
generic ( width : integer := 4 );
port (clk :in std_logic;
random_num : out std_logic_vector (width-1 downto 0);
data_out : out STD_LOGIC_VECTOR(7 downto 0)
);
end sine_wave;
architecture Behavioral of sine_wave is
signal data_out1,rand_temp1,noisy_signal : integer;
signal noisy_signal1 : STD_LOGIC_VECTOR(7 downto 0);
signal i : integer range 0 to 29:=0;
--type memory_type is array (0 to 29) of integer;
type memory_type is array (0 to 29) of std_logic_vector(7 downto 0);
--ROM for storing the sine values generated by MATLAB.
signal sine : memory_type := ("01001101","01011101","01101100","01111010","10000111","10010000","10010111","10011010","10011010");
--hi
begin
process(clk)
variable rand_temp : std_logic_vector(width-1 downto 0):=(width-1 => '1',others => '0');
variable temp : std_logic := '0';
begin
--to check the rising edge of the clock signal
if(rising_edge(clk)) then
temp := rand_temp(width-1) xor rand_temp(width-2);
rand_temp(width-1 downto 1) := rand_temp(width-2 downto 0);
rand_temp(0) := temp;
--data_out <= sine(i);
i <= i+ 1;
if(i = 29) then
i <= 0;
end if;
end if;
data_out <= sine(i);
data_out1<=to_integer(unsigned(sine(i)));
random_num <= rand_temp;
rand_temp1<=to_integer(unsigned(rand_temp));
noisy_signal<=data_out1+rand_temp1;
noisy_signal1<= std_logic_vector(to_signed(noisy_signal,8));
end process;
end Behavioral;
Vivado
ModelSIM

VHDL - GHDL Initialise std_logic_vector with smaller bit length

I have a signal dataIn : std_logic_vector ( 15 downto 0);
I want to give an input less than 16-bits for example dataIn <= x"000a" and those bits occupy the most significant bits and the rest to be zero.
In verilog you can do that very easy but in VHDL you get the error:
"string length does not match that of the anonymous integer subtype defined t... ".
I know that if you use 16x"bit_string" solves the problem but this is only for VHDL-2008 and ghdl doesn't support yet VHDL-2008.
Are there any method for IEEE Std 1076-2002?
For VHDL-87/93/2002 you could use the resize function from the numeric_std package.
library ieee;
use ieee.numeric_std.all;
...
constant FOO : std_logic_vector(2 downto 0) := "010";
signal dataIn : std_logic_vector(15 downto 0) := std_logic_vector(resize(unsigned(FOO), 16));
Note that the resize function is only defined for types signed and unsigned.
If you want the short bit string to be placed into the MSBs you may need to use the 'reverse_order attribute.
Often you will find it easier to define a dedicated function which encapsulates more complicated initializations.
constant FOO : std_logic_vector(2 downto 0) := "010";
function init_dataIn (bar : std_logic_vector; len : integer) return std_logic_vector is
begin
return bar & (len - bar'length - 1 downto 0 => '0');
end function init_dataIn;
signal dataIn : std_logic_vector(15 downto 0) := init_dataIn(FOO, 16);

4-bit ALU using VHDL showing error: no function declarations for operator "+" ("-", "*",and "/")

When I compile this code using ghdl it produces errors.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity alu is
generic ( constant N: natural := 1 );
port( a,b : in std_logic_vector(3 downto 0);
sel : in std_logic_vector(3 downto 0);
y : out std_logic_vector(3 downto 0);
x: out std_logic_vector(7 downto 0);
cout : out std_logic);
end alu;
architecture behavioral of alu is
signal rslt : std_logic_vector(3 downto 0);
signal tmp : std_logic_vector(4 downto 0);
begin
process(a,b,sel)
begin
case sel is
when "0000"=>
rslt<= a + b; -- Line 33
when "0001"=>
rslt<= a - b; -- Line 35
when "0010"=>
x<= (unsigned(a)) * (unsigned(b)); -- Line 37
when "0011"=>
x<=(unsigned(a)) / (unsigned(b)); -- Line 39
when "0100"=>
rslt<=std_logic_vector(unsigned(a) sll N);
when "0101"=>
rslt<=std_logic_vector(unsigned(a) srl N);
when "0110"=>
rslt<=std_logic_vector(unsigned(a) rol N);
when "0111"=>
rslt<=std_logic_vector(unsigned(a) ror N);
when "1000"=>
rslt<= a and b;
when "1001"=>
rslt<= a or b;
when "1010"=>
rslt<= a xor b;
when "1011"=>
rslt<= a xnor b;
when "1100"=>
rslt<= a nand b;
when "1101"=>
rslt<= a nor b;
when "1110"=>
if (a > b) then
rslt<= "0001";
else
rslt<="0000";
end if;
when "1111"=>
if (a = b)then
rslt<="0001";
else
rslt<="0000";
end if;
when others=>
rslt<= "0000";
end case;
end process;
y<=rslt;
tmp<= ('0' & a) + ('0' & b); -- Line 78
cout<=tmp(4);
end behavioral;
ghdl -a alu.vhdl
alu.vhdl:33:19:error: no function declarations for operator "+"
alu.vhdl:35:19:error: no function declarations for operator "-"
alu.vhdl:37:29:error: no function declarations for operator "*"
alu.vhdl:39:28:error: no function declarations for operator "/"
alu.vhdl:78:17:error: no function declarations for operator "+"
When using unsigned arithmetic, How can I make these operators available?
Welcome on Stackoverflow. You are apparently not very familiar with typed languages. VHDL is a typed language in which variables, signals, constants have a type, like bit, integer, std_logic_vector(3 downto 0) or unsigned(3 downto 0). And these types define what can be done and what cannot.
By default you cannot add two std_logic_vector(3 downto 0) and get a result that is also a std_logic_vector(3 downto 0). This is what you try to do with rslt<= a + b;. The compiler simply tells you that no such "+" operator is visible.
Same for rslt<= a - b; with the "-" operator.
x<= (unsigned(a)) * (unsigned(b)); is slightly better because you did not try to multiply two std_logic_vector(3 downto 0). You converted them to unsigned(3 downto 0) instead. Good choice because the ieee.numeric_std package overloads the "*" operator for the unsigned(...) types. Unfortunately you try to assign the result to a std_logic_vector(7 downto 0) while the ieee.numeric_std."*" operator returns a unsigned(7 downto 0). So, here again, the compiler complains that it does not find a suitable "*" operator. Note: the parentheses are not needed. You could simply write unsigned(a) * unsigned(b).
The other errors are left unexplained as an exercise.
I suggest that you read again your VHDL book and understand what types are, what kind of operations are defined by default on std_logic_vector(...) and unsigned(...) types and what extra operations are defined on the same types by the two packages you declare (ieee.std_logic_1164 and ieee.numeric_std).

VHDL n-bit barrel shifter

I have a 32 bit barrel shifter using behavior architecture. Now I need to convert it to an n-bit shifter. The problem that I'm facing is that there is some kind of restriction to the for loop that I have to put a constant as sentinel value.
Following is my Code
library IEEE;
use IEEE.std_logic_1164.all;
Entity bshift is -- barrel shifter
port (left : in std_logic; -- '1' for left, '0' for right
logical : in std_logic; -- '1' for logical, '0' for arithmetic
shift : in std_logic_vector(4 downto 0); -- shift count
input : in std_logic_vector (31 downto 0);
output : out std_logic_vector (31 downto 0) );
end entity bshift;
architecture behavior of bshift is
function to_integer(sig : std_logic_vector) return integer is
variable num : integer := 0; -- descending sig as integer
begin
for i in sig'range loop
if sig(i)='1' then
num := num*2+1;
else
num := num*2;
end if;
end loop; -- i
return num;
end function to_integer;
begin -- behavior
shft32: process(left, logical, input, shift)
variable shft : integer;
variable out_right_arithmetic : std_logic_vector(31 downto 0);
variable out_right_logical : std_logic_vector(31 downto 0);
variable out_left_logical : std_logic_vector(31 downto 0);
begin
shft := to_integer(shift);
if logical = '0' then
out_right_arithmetic := (31 downto 32-shft => input(31)) &
input(31 downto shft);
output <= out_right_arithmetic after 250 ps;
else
if left = '1' then
out_left_logical := input(31-shft downto 0) &
(shft-1 downto 0 => '0');
output <= out_left_logical after 250 ps;
else
out_right_logical := (31 downto 32-shft => '0') &
input(31 downto shft);
output <= out_right_logical after 250 ps;
end if;
end if;
end process shft32;
end architecture behavior; -- of bshift
any help will be appreciated
Your code is not a barrel shifter implementation, because a barrel shift is a mux-tree.
If you have a 32 bit BarrelShifter module, you will need a 5 bit Shift input, wherein every bit position i enables a 2^i shift operation.
So for example shift = 5d -> 00101b enables a mux in stage 1 to shift for 1 bit and a mux in stage 3 to shift 4 bits. All other mux stages are set to pass through (shift(i) = 0).
I also would not advice to mix up basic shifting with shift modes (arithmetic, logic, rotate) and directions (left, right).
arithmetic and logic is only different in the shift-in value
shift right can be done by a conversion => shiftright = reverse(shiftleft(reverse(input), n)
An open source implementation can be found here:
https://github.com/VLSI-EDA/PoC/blob/master/src/arith/arith_shifter_barrel.vhdl

Multiplication of a scalar with a vector

I am writing code in VHDL in which a number is multiplied by a vector. But it gives an error.
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity multi is
port ( clk : in std_logic;
ipixel : in std_logic_vector(15 downto 0);
opixel : out std_logic_vector(15 downto 0)
);
end entity multi;
architecture rtl of multi is
begin
process (clk) begin
if rising_edge (clk) then
opixel (15 downto 11) <= std_logic_vector(unsigned(ipixel(15 downto 11))*3);
opixel (10 downto 5) <= std_logic_vector(unsigned(ipixel(10 downto 5))* 3);
opixel (4 downto 0) <= std_logic_vector(unsigned(ipixel(4 downto 0))* 3);
end if;
end process;
end architecture rtl;
The error is:
Target slice 5 elements; Value is 10 elements
When you multiply an unsigned value with a natural, this is defined in NUMERIC_STD as follows:
function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
begin
return L * TO_UNSIGNED(R, L'LENGTH);
end "*";
Return value will result in 2 * length of your unsigned factor!

Resources