lundi 15 avril 2013

Additionneur 4 bits


Ce programme a pour but d'additionner 2 données binaires de 4 bits représentées par les interrupteurs et d'afficher sur 2 afficheurs 7 segments. Il existe bien sur des circuits plus efficace mais l'idée est d'apprendre à se servir uniquement d'opérations logiques et donc la table de Karnaugh pour coder les différents circuits du schéma.

Addionneur 4 bits


Les sorties s0 à s3 des additionneurs sont reliées aux entrées v0 à v3.
Le comparateur contrôle les multiplexeurs pour sélectionner les entrées v quand la valeur décimale est inférieur à 10 et la sortie du circuit A quand celle-ci est supérieur ou égale à 10.
Lorsque l'on arrive à 10, soit "1010" en binaire, il faut que le circuit A convertisse les 3 bits de poids faible "1010" en "000" puis "1011" en "001" et ainsi de suite. La table de Karnaugh sera très utile dans ce cas.
L'addition pouvant aller jusqu'à 30, compte tenu du circuit B, l'affichage ce limite à 19.

Programme VHDL

Réalisé en 2 fichiers avec les composants regroupés dans une bibliotèques

LIBRARY ieee;
USE ieee.std_logic_1164.all;
use work.circuit_components.all;

entity part4 is
port (SW : in std_logic_vector(8 downto 0);
  HEX0,HEX1,HEX2,HEX3 : out std_logic_vector (0 to 6);
  LEDR : out std_logic_vector(8 downto 0);
  LEDG : out std_logic_vector(4 downto 0));
end;

architecture behavior of part4 is
--signal statement
signal outComp,c1,c2,c3 : std_logic;
signal outCircuitA : std_logic_vector (3 downto 0);
signal outMux : std_logic_vector (3 downto 0);
signal link : std_logic_vector (4 downto 0);


begin
--component instantiation
I1:comparator port map (Comp_in=>link, z=>outComp);
I2:CircuitA port map (CircA_in=>link(3 downto 0), CircA_out=>outCircuitA);
I3:mux port map (a=>link(3), b=>outCircuitA(3), s=>outComp,m=>outMux(3));
I4:mux port map (a=>link(2), b=>outCircuitA(2), s=>outComp,m=>outMux(2));
I5:mux port map (a=>link(1), b=>outCircuitA(1), s=>outComp,m=>outMux(1));
I6:mux port map (a=>link(0), b=>outCircuitA(0), s=>outComp,m=>outMux(0));
I7:decoder port map (m => outMux, HEX0 => HEX0);
I8:CircuitB port map (outComp, HEX1);
I9:adder port map (a=>SW(0), b=>SW(4), cin=>SW(8), s=>link(0), cout=>c1);
I10:adder port map (a=>SW(1), b=>SW(5), cin=>c1, s=>link(1), cout=>c2);
I11:adder port map (a=>SW(2), b=>SW(6), cin=>c2, s=>link(2), cout=>c3);
I12:adder port map (a=>SW(3), b=>SW(7), cin=>c3, s=>link(3), cout=>link(4));
I13:decoder port map (m => SW(3 downto 0), HEX0 => HEX2);
I14:decoder port map (m => SW(7 downto 4), HEX0 => HEX3);

LEDG <= link;
LEDR <= SW;
end behavior;


Les composants:

LIBRARY ieee;
USE ieee.std_logic_1164.all;

package circuit_components is

component comparator
port (Comp_in : in std_logic_vector(4 downto 0);
  z : out std_logic);
end component;

component CircuitA
port (CircA_in : in std_logic_vector(3 downto 0);
  CircA_out : out std_logic_vector(3 downto  0));
end component;

component CircuitB
port (inB : in std_logic;
  HEX1 : out std_logic_vector(6 downto  0));
end component;

component mux
port (a,b,s : in std_logic;
  m : out std_logic);
end component;

component decoder
port (m : in std_logic_vector(3 downto 0);
  HEX0 : out std_logic_vector(6 downto 0));
end component;

component adder
port (a,b,cin : in std_logic;
  s,cout : out std_logic);
end component;

end circuit_components;

LIBRARY ieee;
USE ieee.std_logic_1164.all;

entity comparator is
port (Comp_in : in std_logic_vector(4 downto 0);
  z : out std_logic);
end;

architecture Archit_Comparator of comparator is
begin
z <= (Comp_in(4) and not(Comp_in(3)) and not(Comp_in(2))) or (not(Comp_in(4)) and Comp_in(3) and Comp_in(1)) or (not(Comp_in(4)) and Comp_in(3) and Comp_in(2) and not(Comp_in(1)));
end Archit_Comparator;

LIBRARY ieee;
USE ieee.std_logic_1164.all;

entity CircuitA is
port (CircA_in : in std_logic_vector(3 downto 0);
  CircA_out : out std_logic_vector(3 downto  0));
end;

architecture Archit_CircuitA of CircuitA is
begin
CircA_out(0) <= (not(CircA_in(3)) and not(CircA_in(2)) and CircA_in(0)) or (CircA_in(3) and CircA_in(0));
CircA_out(1) <= (not(CircA_in(3)) and not(CircA_in(2)) and not(CircA_in(1))) or (CircA_in(3) and CircA_in(2) and not(CircA_in(1)));
CircA_out(2) <= (not(CircA_in(3)) and not(CircA_in(2)) and not(CircA_in(1))) or (CircA_in(3) and CircA_in(2) and CircA_in(1));
CircA_out(3) <= not(CircA_in(3)) and not(CircA_in(2)) and CircA_in(1);
end Archit_CircuitA;

LIBRARY ieee;
USE ieee.std_logic_1164.all;

entity mux is
port ( a,b,s : in bit;
   m : out bit);
end;

architecture Archit_Mux of mux is
begin
m <= (s and b) or (not(s) and a);
end Archit_Mux;

LIBRARY ieee;
USE ieee.std_logic_1164.all;

entity decoder is
port (m : in std_logic_vector(3 downto 0);
  HEX0 : out std_logic_vector(6 downto 0));
end;

architecture Archit_Decoder of decoder is
begin
with m(3 downto 0) select
 HEX0 <= "0000001" when "0000",
    "1001111" WHEN "0001",
    "0010010" WHEN "0010",
    "0000110" WHEN "0011",
    "1001100" WHEN "0100",
    "0100100" WHEN "0101",
    "0100000" WHEN "0110",
    "0001111" WHEN "0111",
    "0000000" WHEN "1000",
    "0000100" WHEN "1001",
    "1111111" when others;
end Archit_Decoder;

LIBRARY ieee;
USE ieee.std_logic_1164.all;

entity CircuitB is
 port (inB : in std_logic;
  HEX1 : out std_logic_vector(6 downto  0));
end;

architecture Archit_CircuitB of CircuitB is
begin
with inB select
 HEX1 <= "1001111" WHEN '1',
    "0000001" when others;
end Archit_CircuitB;

LIBRARY ieee;
USE ieee.std_logic_1164.all;

entity adder is
port (a,b,cin : in std_logic;
  s,cout : out std_logic);
end;

architecture Archit_Adder of adder is
begin
s <= a xor b xor cin;
cout <= (a and b) or (cin and (a xor b));
end Archit_Adder;



Exemple en image


9 + 5 = 14
Les leds rouges representent l'état des interrupteurs, les vertes la valeur du résultat en binaire.

Aucun commentaire:

Enregistrer un commentaire