0
votes

I'm trying to use a function created by myself (it's the first time I try it so I might probably have done something wrong there).

When I try to compile I get the following error message: Error (13815): VHDL Qualified Expression error at Averageador.vhd(38): divide type specified in Qualified Expression must match unsigned type that is implied for expression by context

Divide is the name of my function. This function divides any 16bit unsigned value by an unknown unsigned value and gives the result as a fixed point 32bit unsigned value, where 16bit are on each side of the point. This is the code:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

package propios is

 --function declaration.
function divide (a : UNSIGNED; b: UNSIGNED) return UNSIGNED;
end propios;   --end of package.

package body propios is  --start of package body
--definition of function
function  divide (a : UNSIGNED; b: UNSIGNED) return UNSIGNED is
variable a_int : unsigned(a'length+7 downto 0):= (others => '0');
variable b_int : unsigned(b'length-1 downto 0):=b;
variable r : unsigned(b'length downto 0):= (others => '0');
variable q : unsigned(31 downto 0):= (others => '0');
begin
a_int(a'length+7 downto 16):=a;
for i in a'length+7 downto 0 loop
    r(b'length downto 1):=r(b'length-1 downto 0);
    r(0) := a_int(i);
    if (r>=q) then
        r:=r-b_int;
        q(i):='1';
    end if;
end loop;
return q;
end divide;
--end function
end propios;  --end of the package body

I return q which is a 32-bit unsigned.

This is a code in which I use the function and prompts the error message:

   library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.propios.all;

ENTITY test IS --Con alimentación de datos posición a posición, no vector de golpe.

END test;
Architecture simple of test is
signal a:unsigned(15 downto 0);
signal b:unsigned(13 downto 0);
signal c: unsigned(31 downto 0);
begin


process 
begin
a<="1100100110100111";
b<="00000000000010";
c<= divide(a,b);


end process;


end simple;

Any suggestions? Thank you

1
You don't show the declarations for vector32 and vector24. Don't cross between std_logic_arith (package propios) and numeric_std (Averagador). It's definitely not portable, both declare signed and unsigned, every declaration is unique (use numeric_std). Show us the function testbench that fails instead of Averageador. The idea is to be able to reproduce the problem. You appear to be mixing metaphors between signed and unsigned. In Averageador there are two drivers for num_vectores, all assignments should be in the same process. - user1155120
if posicion <= "00000000" then posicion is unsigned, it's never less than 0. - user1155120
For Averageador inter (function parameter a) length 24, a_int length 32 a_int(a'length + 7 downto 16) := a; will generate an error in function divide. IEEE Std 1076-2008 10.6.2 Simple variable assignments, 10.6.2.1 paragraphs 5 and 7. The subtype of the right hand side expression does not belong to the target subtype, that's an error. - user1155120
If you look at VHDL - Qualified Expression must match the type that is implied for the expression by context The reported error may be caused by using std_logic_arith in one place and numeric_std in another, both declaring unsigned, etc. - user1155120
Thanks for the quick response!! As you said it was because of using std_logic_arith on one side and numeric_std on the other. Also thanks for pointing out the other issues, I will keep them in mind. Just for clarity if anyone else sees this post in the future I will also post the code of the test. Thanks again! - Iñaki Martín Soroa

1 Answers

0
votes

The problem is caused (as user1155120 said) by using the package std_logic_arith on the package and numeric_std on the test. Therefore, even if both are called unsigned they are not compatible with each other.

Both codes contained other errors which have also been corrected but were not related to this first error.

This is the package with a function for dividing 2 unsigned numbers with 16bits after the coma:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

package propios is

 --function declaration.
function divide (a : UNSIGNED; b: UNSIGNED) return UNSIGNED;
end propios;   --end of package.

package body propios is  --start of package body
--definition of function
function  divide (a : UNSIGNED; b: UNSIGNED) return UNSIGNED is
variable a_int : unsigned(a'length+15 downto 0):= (others => '0');--Length is 16 bit longer than a
variable b_int : unsigned(b'length-1 downto 0):=b;
variable r : unsigned(b'length downto 0):= (others => '0');
variable q : unsigned(a'length+15 downto 0):= (others => '0');--Same length as a_int
variable i: natural;

begin
a_int(a'length+15 downto 16):=a;--the MSBits are "a" and the rest will be 0's
for i in a'length+15 downto 0 loop--division using a modified version of integer division (unsigned) with remainder as seen in:
--https://en.wikipedia.org/wiki/Division_algorithm
    r(b'length downto 1):=r(b'length-1 downto 0);
    r(0) := a_int(i);
    if (r>=b_int) then
        r:=r-b_int;
        q(i):='1';
    end if;
end loop;
return q;
end divide;
--end function
end propios;  --end of the package body

This is a simple test to check its functionality:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.propios.all;

ENTITY test IS --Con alimentación de datos posición a posición, no vector de golpe.

END test;
Architecture simple of test is
signal a:unsigned(23 downto 0);
signal b:unsigned(13 downto 0);
signal c: unsigned(39 downto 0);
begin


process 
begin
a<="000000001100100110100111";
b<="00000000010010";
wait for 200ps;
c<= divide (a , b);

wait;   
end process;


end simple;

To check the result have in mind that the last 16 bits of the result are behind the fixed point.