2
\$\begingroup\$

I'm writing a package to add supporting functions and types for creating an FIR filter. In the mult function, I'm trying to multiply two signed types, which should be supported in IEEE.numeric_std library. The error I'm getting (using Libero IDE) is:

0 definitions of operator "*" match here

Here's the code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

package fir_pkg is
    constant taps : integer := 8;
    constant bit_width : integer := 8;
    type fract is array(bit_width-1 downto 0) of std_logic;
    type fract2 is array((2*bit_width)-1 downto 0) of std_logic;
    type fract_sequence is array(taps-1 downto 0) of fract;
    type fract2_sequence is array(taps-1 downto 0) of fract2;
    function mult(a,b: fract_sequence) return fract2_sequence;
end package fir_pkg;

package body fir_pkg is

    function mult(a,b: fract_sequence) return fract2_sequence is
        variable a_s, b_s:signed(bit_width-1 downto 0);
        variable seq: fract2_sequence;
    begin
        for i in a'range loop
            a_s := signed(a(i));
            b_s := signed(b(i));
            seq(i) := a_s * b_s;
        end loop;
        return seq;
    end mult;

end fir_pkg;
\$\endgroup\$
3
  • 1
    \$\begingroup\$ This is complaining that there isn't a "" operator with a signature [signed, signed return fract2]. You've defined a type but provided no overload operator "" that supports the signature. That implies you might want to type convert something. \$\endgroup\$
    – user8352
    Commented Feb 18, 2016 at 6:57
  • \$\begingroup\$ Yeah, that seems to be exactly the problem now (I've got the product on a signed variable now and am equating seq(i) in the next statement. How can I create conversion operators from signed to my custom type (still based on std_logic)? \$\endgroup\$
    – Prabhpreet
    Commented Feb 18, 2016 at 7:04
  • \$\begingroup\$ Update: fixed using custom defined type conversion function. \$\endgroup\$
    – Prabhpreet
    Commented Feb 18, 2016 at 7:18

3 Answers 3

3
\$\begingroup\$

Show me why you can't make fract and fract2 subtypes of std_logic_vector:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

package fir_pkg is
    constant taps : integer := 8;
    constant bit_width : integer := 8;

    subtype fract is std_logic_vector (bit_width-1 downto 0);
    -- type fract is array(bit_width-1 downto 0) of std_logic;
    -- type fract2 is array((2*bit_width)-1 downto 0) of std_logic;
    subtype fract2 is std_logic_vector(2*bit_width-1 downto 0);

    type fract_sequence is array(taps-1 downto 0) of fract;
    type fract2_sequence is array(taps-1 downto 0) of fract2;
    function mult(a,b: fract_sequence) return fract2_sequence;
end package fir_pkg;

package body fir_pkg is

    function mult(a,b: fract_sequence) return fract2_sequence is
        variable a_s, b_s:signed(bit_width-1 downto 0);
        variable seq: fract2_sequence;
    begin
        for i in a'range loop
            a_s := signed(a(i));
            b_s := signed(b(i));
            seq(i) := std_logic_vector(a_s * b_s);
        end loop;
        return seq;
    end mult;

end fir_pkg;
\$\endgroup\$
4
  • \$\begingroup\$ Fairly new to VHDL. Had never heard about subtype. Thanks! \$\endgroup\$
    – Prabhpreet
    Commented Feb 18, 2016 at 9:08
  • 1
    \$\begingroup\$ A little better solution: use signed directly instead of std_logic_vector. \$\endgroup\$
    – Prabhpreet
    Commented Feb 18, 2016 at 9:16
  • \$\begingroup\$ See, here's the problem, you're not showing how they are used. You could also simply used range constrained integers. \$\endgroup\$
    – user8352
    Commented Feb 18, 2016 at 9:19
  • \$\begingroup\$ Does integer have support for the multiplication operator? \$\endgroup\$
    – Prabhpreet
    Commented Feb 18, 2016 at 9:21
1
\$\begingroup\$

fract2 is not compatible with signed, and so no multiplier function can be found with the correct return type.

Change the definition of fract and fract2 to this:

subtype fract is signed(bit_width-1 downto 0);
subtype fract2 is signed((2*bit_width)-1 downto 0);
\$\endgroup\$
0
\$\begingroup\$

Problem was that the result of product was expected to be signed but was fract2 (custom type defined here) instead.

So, we need to create a function to convert the type. Type conversion is explained here.

The code for the conversion function here:

function conv_fract2(a:signed) return fract2 is
    variable var:fract2;
begin
    assert a'length = bit_width;
    for i in a'range loop
        var(i) := a(i);
    end loop;
    return var;
end conv_fract2;
\$\endgroup\$
1
  • \$\begingroup\$ It is always a good idea to self-answer a question. But, you should also show where to call your new convert function. Only this makes your answer helpful for further readers. \$\endgroup\$ Commented Feb 18, 2016 at 14:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.