Relacionado con esto: Escalado de una entrada en VHDL , pero lo suficientemente diferente que creo que merece una nueva pregunta.
Siento que esto debería ser más simple que lo estoy haciendo.
Tengo un flujo de muestras firmadas de 16 bits que quiero atenuar en aproximadamente 0,5 dB, pero solo usemos números más bonitos para ilustrar. Necesito:
-32000 (almost -1.0) -> -25600
+32000 (almost +1.0) -> +25600
etc
simple ¿verdad? Estoy atascado porque el operador de multiplicación debe tomar los operandos firmados o sin firmar , no una mezcla de ambos (eso tiene sentido).
Esto es lo que intenté inicialmente:
variable scale_factor : std_logic_vector(15 downto 0) := x"EFFF";
attenuated_sample <= std_logic_vector(unsigned(sample) * unsigned(scale_factor));
Esto no funciona; hace que las muestras positivas sean más pequeñas, pero las muestras negativas más negativas.
La única manera de lograr lo que quiero es multiplicando la muestra firmada por un factor de escala firmada , pero he tenido que hacer la escala El factor tiene unos pocos ceros adicionales en la parte frontal para que siempre sea positivo. Es decir,
variable temp : std_logic_vector(39 downto 0);
variable scale_factor : std_logic_vector(19 downto 0) := x"0EFFF";
temp := std_logic_vector(resize(signed(sample), 20) * signed(scale_factor);
attenuated_sample <= temp(31 downto 16);
Esto parece funcionar, pero no me gusta porque es feo. ¿Cuál es la forma correcta de hacer esto?