Traigo un code-kata de un circuito digital. Se trata de un sumador completo de 1 bit. Es decir, es un circuito con 3 entradas y 2 salidas. Las tres entradas son: un acarreo, y los dos bits que vamos a sumar.
El funcionamiento es muy sencillo, corresponde a ésta tabla:
Acarreo de entrada | A | B | Acarreo de salida | Suma |
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 0 | 1 |
0 | 1 | 0 | 0 | 1 |
0 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 0 | 1 |
1 | 0 | 1 | 1 | 0 |
1 | 1 | 0 | 1 | 0 |
1 | 1 | 1 | 1 | 1 |
Podríamos no simplificar el código VHDL, directamente escribiendo todos los casos en que las salidas dan 1. Es el código siguiente, después el simplificado.
Al grano, el código fuente del sumador
Una posible definición sin simplificar las funciones, a modo de aprendizaje, podría ser:
-- Sumador completo de 1 bit
library IEEE;
use IEEE.std_logic_1164.all;
entity oneBitFullAdder is
port (
sum, carryOut : out std_logic;
a, b, carryIn : in std_logic
);
end entity;
architecture arch of oneBitFullAdder is
signal auxInVect : std_logic_vector (2 downto 0);
begin
auxInVect(2) <= carryIn;
auxInVect(1) <= a;
auxInVect(0) <= b;
sum <= '0' when auxInVect = "000" else
'1' when auxInVect = "001" else
'1' when auxInVect = "010" else
'0' when auxInVect = "011" else
'1' when auxInVect = "100" else
'0' when auxInVect = "101" else
'0' when auxInVect = "110" else
'1';
carryOut <= '0' when auxInVect = "000" else
'0' when auxInVect = "001" else
'0' when auxInVect = "010" else
'1' when auxInVect = "011" else
'0' when auxInVect = "100" else
'1' when auxInVect = "101" else
'1' when auxInVect = "110" else
'1';
end architecture;
El código fuente simplificado
Utilizando mapas de Karnaugh podemos llegar a la siguiente simplificación:
-- Sumador completo de 1 bit
library IEEE;
use IEEE.std_logic_1164.all;
entity oneBitFullAdder is
port (
sum, carryOut : out std_logic;
a, b, carryIn : in std_logic
);
end entity;
architecture arch of oneBitFullAdder is
begin
sum <= ((not carryIn) and (not a) and b)
or ((not carryIn) and a and (not b))
or (carryIn and (not a) and (not b))
or (carryIn and a and b);
carryOut <= (carryIn and b) or (a and b) or (carryIn and a);
end architecture;
El resultado es el mismo, pero el circuito que define es más simple.
El banco de pruebas
Simplemente es una entidad vacía, que hace port map de las entradas y salidas para generar señales de entrada y poder ver las de salida a ver si el funcionamiento es correcto:
-- Sumador completo de 1 bit
library IEEE;
use IEEE.std_logic_1164.all;
entity oneBitFullAdder_tb is
end entity;
architecture arch of oneBitFullAdder_tb is
component oneBitFullAdder is
port (
sum, carryOut : out std_logic;
a, b, carryIn : in std_logic
);
end component;
signal testInVect : std_logic_vector (2 downto 0);
signal testSumOut, testCarryOut : std_logic;
begin
unit_under_test: oneBitFullAdder port map (
sum => testSumOut,
carryOut => testCarryOut,
carryIn => testInVect(2),
a => testInVect(1),
b => testInVect(0)
);
generate_signals : process
begin
testInVect <= "000"; wait for 10 ns;
testInVect <= "001"; wait for 10 ns;
testInVect <= "010"; wait for 10 ns;
testInVect <= "011"; wait for 10 ns;
testInVect <= "100"; wait for 10 ns;
testInVect <= "101"; wait for 10 ns;
testInVect <= "110"; wait for 10 ns;
testInVect <= "111"; wait for 10 ns;
wait;
end process;
end architecture;
Si todo va bien, al simular el banco de pruebas debemos de ver señales como las de la imagen del principio.
Como puedo hacer para poner todo el código junto? lo estoy intentando en logisim evolution
Si te refieres a lo que finalmente te quedas para probar en FPGAs, o implementar finalmente en circuitos, es sólo el código del sumador, no el testbench. Con lo que no tienes que ponerlo todo junto. No se si me explico bien.
Saludos.
Como podría hacer un sumador restador de 8 bits ?? Ayuda, por favor
Buenas tardes Mariano.
Puedes hacer uno uniendo varios de 1 bit. En este post se explica cómo unir varios sumadores completos de 1 bit en otro de 4 bit:
https://jnjsite.com/vhdl-uniendo-circuitos-un-sumador-completo-de-4-bits/
Saludos.