Código:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY Multiplicador_tb IS
END Multiplicador_tb;
ARCHITECTURE behavior OF Multiplicador_tb IS
COMPONENT mult_sec
PORT(inbus : IN std_logic_vector(15 downto 0);
outbus : OUT std_logic_vector(15 downto 0);
I : IN std_logic;
clk : IN std_logic;
reset : IN std_logic);
END COMPONENT;
--Entradas
signal inbus : std_logic_vector(15 downto 0) := (others => '0');
signal I : std_logic := '0';
signal clk : std_logic := '0';
signal reset : std_logic := '1';
--Salidas
signal outbus : std_logic_vector(15 downto 0);
constant periodo : time := 100 ns; --10 MHz
BEGIN
uut: mult_sec PORT MAP (
inbus => inbus,
outbus => outbus,
I => I,
clk => clk,
reset => reset);
clk <= not clk after periodo/2;
-- Asignación secuencial de estimulos
tb: PROCESS
BEGIN
reset <= '1'; --reset inicial
wait for 2*periodo;
reset <= '0'; --desactivamos el reset
wait for 1*periodo;
inbus <= "0000110100001011"; -- operandos M = 11, Q = 13.
I <= '1'; -- activamos señal escritura
wait for 2*periodo;
I <= '0'; -- desactivamos señal de escritura
wait for 2*periodo;
inbus <= "0000000000000000"; -- Inbus = 0
wait for 16*periodo; -- resultado aparece tras 16 ciclos
wait;
END PROCESS;
END;
Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity mult_sec is
Port ( inbus : in STD_LOGIC_VECTOR (15 downto 0);
outbus : out STD_LOGIC_VECTOR (15 downto 0);
I : in STD_LOGIC;
clk : in STD_LOGIC;
reset : in STD_LOGIC
);
end mult_sec;
architecture Behavioral of mult_sec is
type type_state is(INICIO, SUMACU, DESDEC);
signal state, nextstate: type_state;--
signal init, ld, sh, Z: std_logic;
signal CA, pp: std_logic_vector (8 downto 0);
signal Q, M: std_logic_vector (7 downto 0);
signal cnt: unsigned (2 downto 0);
begin
-- Registros C y A
process (clk, reset)
begin
if reset='1' then
CA <= (others => '0'); -- Unión de acumulador y acarreo, CA
elsif (clk'event and clk='1') then
if (init = '1') then
CA <= (others => '0');
elsif (ld = '1') then -- instrucción de carga
CA <= pp; -- pp = producto parcial
elsif (sh = '1') then
CA <= '0' & CA (8 downto 1); -- desplazamiento
end if;
end if;
end process;
-- Registro Q
process (clk, reset)
begin
if reset = '1' then
Q <= (others => '0');
elsif (clk'event and clk = '1') then
if (I = '1') then--si carga habilitada
Q <= inbus (15 downto 8); --tomamos Q del byte de mayor peso del inbus
elsif (sh='1') then--si carga habilitada
Q <= CA(0) & Q(7 downto 1);--tomamos M del byte me menor peso del inbus
end if;
end if;
end process;
-- Registro M
process (clk, reset)
begin
if reset = '1' then
M <= (others => '0');
elsif (clk'event and clk = '1') then
if (I = '1') then
M <= inbus (7 downto 0);
end if;
end if;
end process;
--Sumador
pp <= std_logic_vector(unsigned('0' & CA(7 downto 0)) + unsigned('0' & M)); -- la suma puede producir 9 bits(pp)
--Salida
outbus <= CA(7 downto 0) & Q;
--Contador
process (reset, clk)
begin
if (reset = '1') then
cnt <= (others => '0');
elsif clk = '1' and clk'event then
if (init = '1') then
cnt <= "111"; -- iniciamos a 7 y bajando
elsif (sh = '1') then
cnt <= cnt - 1;
end if;
end if;
end process;
--Detector de cero
process(cnt)
begin
if (cnt = "000") then
Z <= '1';
else
Z <= '0';
end if;
end process;
-- Unidad de Control:
process(reset, clk)
begin
if (reset = '1') then
state <= INICIO;
elsif clk'event and clk = '1' then
state <= nextstate;
end if;
end process;
process(state, I, Q(0), Z)
begin
init <= '0'; ld <= '0'; sh <= '0';
case state is
when INICIO =>
if (I = '1') then
init <= '1';
nextstate <= SUMACU;
else
init <= '0';
nextstate <= INICIO;
end if;
when SUMACU =>
if (Q(0) = '1') then
ld <= '1';
else
ld <= '0';
end if;
nextstate <= DESDEC;
when DESDEC =>
if (Z = '1') then
nextstate <= INICIO;
else
nextstate <= SUMACU;
end if;
sh <= '1';
end case;
end process;
end Behavioral;