0 definiciones del operador "*" coinciden aquí para el tipo firmado (numeric_std, VHDL)

Estoy escribiendo un paquete para agregar funciones y tipos de soporte para crear un filtro FIR. En la multfunción, estoy tratando de multiplicar dos tipos firmados, que deberían ser compatibles con IEEE.numeric_stdla biblioteca. El error que recibo (usando Libero IDE) es:

0 definitions of operator "*" match here

Aquí está el código:

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;
Esto se queja de que no hay un operador " " con una firma [fract2 de retorno firmado, firmado]. Ha definido un tipo pero no ha proporcionado ningún operador de sobrecarga " " que admita la firma. Eso implica que es posible que desee escribir convertir algo.
Sí, ese parece ser exactamente el problema ahora (tengo el producto en una variable firmada ahora y estoy equiparando seq(i)en la siguiente declaración. ¿Cómo puedo crear operadores de conversión de firmado a mi tipo personalizado (todavía basado en std_logic)?
Actualización: corregido usando la función de conversión de tipo definida personalizada.

Respuestas (3)

Muéstrame por qué no puedes hacer subtipos fract y fract2 de 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;
Bastante nuevo en VHDL. Nunca había oído hablar de subtype. ¡Gracias!
Una solución un poco mejor: use signeddirectamente en lugar de std_logic_vector.
Mira, aquí está el problema, no estás mostrando cómo se usan. También podría simplemente usar números enteros restringidos por rango.
¿Integer tiene soporte para el operador de multiplicación?

fract2no es compatible con signed, por lo que no se puede encontrar ninguna función multiplicadora con el tipo de retorno correcto.

Cambie la definición de fracty fract2a esto:

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

El problema era que se esperaba que el resultado del producto fuera signed( fract2tipo personalizado definido aquí) en su lugar.

Entonces, necesitamos crear una función para convertir el tipo. La conversión de tipo se explica aquí .

El código para la función de conversión aquí:

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;
Siempre es una buena idea auto-responder una pregunta. Pero también debe mostrar dónde llamar a su nueva función de conversión. Solo esto hace que su respuesta sea útil para otros lectores.