0 Definitionen des Operators "*" passen hier für signierten Typ (numeric_std, VHDL)

Ich schreibe ein Paket, um unterstützende Funktionen und Typen zum Erstellen eines FIR-Filters hinzuzufügen. In der multFunktion versuche ich, zwei signierte Typen zu multiplizieren, die in der IEEE.numeric_stdBibliothek unterstützt werden sollten. Der Fehler, den ich bekomme (mit Libero IDE) ist:

0 definitions of operator "*" match here

Hier ist der 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;
Dies beschwert sich darüber, dass es keinen " " Operator mit einer Signatur [signed, signed return fract2] gibt. Sie haben einen Typ definiert, aber keinen Überladungsoperator " " angegeben, der die Signatur unterstützt. Das bedeutet, dass Sie vielleicht etwas konvertieren möchten.
Ja, das scheint jetzt genau das Problem zu sein (ich habe das Produkt jetzt auf einer signierten Variablen und vergleiche es seq(i)in der nächsten Anweisung. Wie kann ich Konvertierungsoperatoren von signiert zu meinem benutzerdefinierten Typ erstellen (immer noch basierend auf std_logic)?
Update: mit benutzerdefinierter Typkonvertierungsfunktion behoben.

Antworten (3)

Zeigen Sie mir, warum Sie keine fract- und fract2-Untertypen von std_logic_vector erstellen können:

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;
Ziemlich neu in VHDL. Hatte noch nie davon gehört subtype. Danke!
Eine etwas bessere Lösung: Verwenden Sie signeddirekt anstelle von std_logic_vector.
Sehen Sie, hier ist das Problem, Sie zeigen nicht, wie sie verwendet werden. Sie könnten auch einfach bereichsbeschränkte Ganzzahlen verwenden.
Unterstützt Integer den Multiplikationsoperator?

fract2ist nicht kompatibel mit signed, daher kann keine Multiplikatorfunktion mit dem richtigen Rückgabetyp gefunden werden.

Ändern Sie die Definition von fractund fract2wie folgt:

subtype fract is signed(bit_width-1 downto 0);
subtype fract2 is signed((2*bit_width)-1 downto 0);

Das Problem war, dass das Ergebnis des Produkts erwartet wurde, signedaber fract2stattdessen (hier definierter benutzerdefinierter Typ) war.

Also müssen wir eine Funktion erstellen, um den Typ zu konvertieren. Die Typumwandlung wird hier erklärt .

Der Code für die Konvertierungsfunktion hier:

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;
Es ist immer eine gute Idee, eine Frage selbst zu beantworten. Aber Sie sollten auch zeigen, wo Sie Ihre neue Konvertierungsfunktion aufrufen können. Nur so ist Ihre Antwort für weitere Leser hilfreich.