Estoy tratando de crear esquemas para un multiplicador de bloque paralelo de NxM-bit usando parámetros genéricos para definir el tamaño del multiplicador y generar sentencias para describir la estructura interna. Tengo algunos problemas con mis sumas y gastos de transporte y no puedo implementar lo que quiero hacer en el código VHDL.
Esto es lo que obtuve hasta ahora:
Multiplicador de 1 bit:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity mult is
port (
a : in std_logic;
b : in std_logic;
Sin : in std_logic; --sum-in
Cin : in std_logic; --carry-in
Sout : out std_logic; --sum-out
Cout : out std_logic --carry-out
);
end mult;
architecture mult of mult is
begin
Sout <= '1' when a = '0' and b = '0' and Sin = '0' and Cin = '1' else
'1' when a = '0' and b = '0' and Sin = '1' and Cin = '0' else
'1' when a = '0' and b = '1' and Sin = '1' and Cin = '0' else
'1' when a = '0' and b = '1' and Sin = '0' and Cin = '1' else
'1' when a = '1' and b = '0' and Sin = '0' and Cin = '1' else
'1' when a = '1' and b = '0' and Sin = '1' and Cin = '0' else
'1' when a = '1' and b = '1' and Sin = '0' and Cin = '0' else
'1' when a = '1' and b = '1' and Sin = '1' and Cin = '1' else
'0';
Cout <= '1' when a = '0' and b = '0' and Sin = '1' and Cin = '1' else
'1' when a = '0' and b = '1' and Sin = '1' and Cin = '1' else
'1' when a = '1' and b = '0' and Sin = '1' and Cin = '1' else
'1' when a = '1' and b = '1' and Sin = '0' and Cin = '1' else
'1' when a = '1' and b = '1' and Sin = '1' and Cin = '0' else
'1' when a = '1' and b = '1' and Sin = '1' and Cin = '1' else
'0';
end mult;
Lo usé como un componente en un multiplicador NxM:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity generic_mult is
generic (bits: integer);
port (
a : in std_logic_vector(bits-1 downto 0);
b : in std_logic_vector(bits-1 downto 0);
answer: out std_logic_vector(bits*2-1 downto 0) --sum-out
);
end entity generic_mult;
architecture behavioral of generic_mult is
component mult is
port (
a : in std_logic;
b : in std_logic;
Sin : in std_logic; --sum-in
Cin : in std_logic; --carry-in
Sout : out std_logic; --sum-out
Cout : out std_logic --carry-out
);
end component;
type mem_word is array (0 to bits) of std_logic_vector(bits downto 0);
signal carry_internal : mem_word;
signal sum_internal : mem_word;
begin
this_is_label: for N in 1 to bits generate --Im sorry, my labels are horrible :(
this_is_label3: for M in 0 to bits-1 generate
this_is_label2: mult
port map (
a => a(N-1),
b => b(M),
Cin => carry_internal(M)(N),
Cout => carry_internal(M+1)(N),
Sin => sum_internal(M)(N),
Sout => sum_internal(M+1)(N-1)
);
end generate;
end generate;
labellll: for N in 0 to bits-1 generate
sum_internal(N+1)(N) <= carry_internal(N)(N);
carry_internal(0) <= (others => '0');
sum_internal(0) <= (others => '0');
answer(bits*2-1) <= carry_internal(bits)(bits);
answer(bits downto 0) <= sum_internal(bits);
end generate;
end behavioral;
Y un banco de pruebas para ello:
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity NM_mult_tb is
end NM_mult_tb;
architecture behavioral of NM_mult_tb is
component generic_mult
generic (bits: integer := 4);
port (
a : in std_logic_vector(bits-1 downto 0);
b : in std_logic_vector(bits-1 downto 0);
answer: out std_logic_vector(bits*2-1 downto 0) --sum-out
);
end component;
--declaring inputs and initializing them
signal a : std_logic_vector(3 downto 0) :="0101";
signal b : std_logic_vector(3 downto 0) :="1010";
signal Sin: std_logic_vector(3 downto 0) :="0000";
signal Cin: std_logic := '0';
--declaring outputs and initializing them
signal answer : std_logic_vector(7 downto 0); --sum-out
signal correct: std_logic; --carry-out
BEGIN
-- Instantiating the Design Under Test (DUT)
dut: generic_mult
GENERIC MAP (4)
PORT MAP (
a => a,
b => b,
answer => answer
);
-- Stimulus process
correct <= '1' when to_integer(unsigned(a))*to_integer(unsigned(b)) =
to_integer(unsigned(answer)) else '0';
stim_proc: process
begin
wait for 1 ns;
a <= a + 1;
if a = "0" then b <= b + 1; end if;
end process;
END;
Cuando lo simulo, veo que hay algo mal con los acarreos y sumas y salidas y mi respuesta tiene bits indefinidos:
(No se me permiten imágenes incrustadas en esta publicación antes de tener 10 reputación, por lo que aquí hay un enlace a la imagen :) enlace
Si has leído mi publicación hasta aquí, muchas gracias por tu atención. ¡Si alguien pudiera encontrar el tiempo para ayudarme con mi problema, estaría muy agradecido!
Atentamente,
Un principiante confundido en VHDL