mercredi 5 juin 2013

Communication PC => Carte FPGA via port RS232

Schéma synoptique du fonctionnement globale



Tout ce qui est en gris reste à programmer.


Détails sur le protocole de communication

La communication du PC vers la carte est pour l'instant assez simple, il suffit d'entrer un premier message, le drapeau ou trame de début pour amorcer l'acquisition des coordonnées à 4 chiffres et une trame de fin.

 


Les trames de début et de fin sont définies sur 8 bits, dans la vidéo que j'ai présenté, il s'agit respectivement du caractère "A" et "retour à la ligne" en codage ASCII. Pour les données utiles, seul les 4 premiers bits sont nécessaires pour chacun des chiffres. Ces valeurs sont ensuite comparées à la position du chariot (voir codeur optique) dans un comparateur pour piloter le moteur dans un sens ou dans l'autre.


La machine à états




Ce diagramme décrit le processus d'acquisition des données. Les étapes pour les dizaine et unité ne sont pas mentionnées par souci de taille de l'image, c'est le même principe que les centaines et milliers .Notons que la mémoire n'est pas vraiment utile pour l'instant, je ne m'en suis pas vraiment servi dans ce programme, mais ce qui m'intéressait avant tout c'est la façon de transférer les données dans le bloque mémoire M4K de la puce. Je ne prétends pas que c'est la meilleur façon de procéder, je ne suis pas un expert en VHDL. Toutes autres solutions seraient bienvenue.

Dans la première étape, le système attend que la donnée data_in issu de l'uart RS232 correspond à la lettre "A" en ASCII avant de passer à l'étape d'acquisition du chiffre des milliers, data_done est un signal qui permet de valider la transmission complète de la trame du port série. Avant chaque écriture dans la mémoire grâce au signal d'horloge memory_clock, on incrémente l'adresse mémoire pour ne pas écraser la donnée précédente. L'étape task permet d'activer le moteur en fin de trame en attendant que le déplacement se termine avant de retourner à l'état initial.

Programme VHDL

en construction...

lundi 6 mai 2013

PWM

Un exemple de PWM (Pulse With Modulation) en VHDL. Le rapport cyclique du signal de sortie est contrôlé à l'entrée duty_cycle de 0 à 100% par pas de 10.


~\Bureau\pwm2.vhd.html
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity pwm is port (
      clk: in std_logic;
      SW : in std_logic_vector (3 downto 0); --rapport cyclique (de 0 à 10) 
      reset : in std_logic;
      GPIO_0 : out std_logic_vector(35 downto 0)); -- sortie
end pwm;

architecture behavior of pwm is

signal cnt : std_logic_vector(3 downto 0) := "0000";
signal s : std_logic;

begin
process (clk,rst) begin
  if reset ='1' then s<=(others=>'0');
  elsif (clk'event and clk='1') then
    if (cnt < SW) then s <='1'; --met la sortie à 1 jusqu'a 
    else s <='0';               --la valeur du rapport cyclique
    end if;
    if (cnt >= "1001") then cnt<="0000"; --remet à 0 quand on a
    else cnt <= cnt + 1;                 -- compté jusqu'a 10
    end if;
  end if;
end process;
GPIO_0(29) <= s;
end behavior;


Simulation ModelSim

Encodeur en quadrature de phase

Le signal de sortie d'un encodeur optique à la forme suivante:


Ce signal est intéressant car déphasé de 90° il permet de déterminer le sens de déplacement. En effet, si la voie A est en avance par rapport à la voie B on se déplace dans un sens, dans le cas contraire on se déplace dans l'autre sens.
Dans le programme VHDL, j'utilise une machine à états finis (FSM Finite State Machine) pour compter ou décompter en fonction du niveau du signal reçu.

Diagramme d'état

Le schéma suivant présente les états possibles en fonction du niveau logique issu du capteur optique. Chaque cycle peut compter jusqu'a 4 incréments ou décréments. Il est toujours possible de modifier le programme de façon à prendre en compte que 1 ou 2 incréments par cycle en fonction de la précision que l'on désire.


Le diagramme d'état:


Le diagramme d'état prend en compte toutes les transitions possibles, ce qui correspond par exemple à des cas ou le cycle ne s'est pas totalement terminé. Imaginons que l'on se trouve à D5, le compteur à déjà compté jusqu'a 3, si on recule avant d'arriver à D6, on passe à l'état G2 qui immédiatement décrémentera d'une unité.

Programme VHDL associé
~\Bureau\Exercice VHDL\PersoExo\Incrementation\FSM_incrementeur.vhd.html
library ieee;
use ieee.std_logic_1164.all;

entity FSM_encoder is
port (
                clk: in std_logic;
                init: in std_logic;
                wayA_B : in std_logic_vector(1 downto 0);
                en: out std_logic; -- enable
                du: out std_logic); --down/up
end FSM_encoder;


architecture machine_behavior of FSM_encoder is

type state is (idle,D0,D1,D2,D3,D4,D5,D6,G0,G1,G2,G3,G4,G5,G6);
signal next_state,reg_state:state;

begin

process(clk)
        begin
                if rising_edge(clk) then
                        if init='1' then reg_state<=idle;
                        else reg_state<=next_state;
                        end if;
                end if;
end process;
----
process (reg_state,wayA_B)
        begin
        case reg_state is

                        when idle=>
                                        if (wayA_B = "01") then next_state<=G0;
                                        elsif (wayA_B = "10") then next_state<=D0;
                                        else next_state<=idle;
                                        end if;

                        when D0=> next_state<=D1;
                        when D1=>
                                        if (wayA_B = "10") then next_state<=D1;
                                        elsif (wayA_B = "11") then next_state<=D2;
                                        elsif (wayA_B = "00") then next_state<=G6;
                                        else next_state<=idle;
                                        end if;
                        when D2=> next_state<=D3;
                        when D3=>
                                        if (wayA_B = "01") then next_state<=D4;
                                        elsif (wayA_B = "10") then next_state<=G4;
                                        elsif (wayA_B = "11") then next_state<=D3;
                                        else next_state<=idle;
                                        end if;
                        when D4=> next_state<=D5;
                        when D5=>
                                        if (wayA_B = "00") then next_state<=D6;
                                        elsif (wayA_B = "01") then next_state<=D5;
                                        elsif (wayA_B = "11") then next_state<=G2;
                                        else next_state<=idle;
                                        end if;
                        when D6=> next_state<=idle;

                        when G0=> next_state<=G1;
                        when G1=>
                                        if (wayA_B = "01") then next_state<=G1;
                                        elsif (wayA_B = "11") then next_state<=G2;
                                        elsif (wayA_B = "00") then next_state<=D6;
                                        else next_state<=idle;
                                        end if;
                        when G2=> next_state<=G3;
                        when G3=>
                                        if (wayA_B = "01") then next_state<=D4;
                                        elsif (wayA_B = "10") then next_state<=G4;
                                        elsif (wayA_B = "11") then next_state<=G3;
                                        else next_state<=idle;
                                        end if;
                        when G4=> next_state<=G5;
                        when G5=>
                                        if (wayA_B = "00") then next_state<=G6;
                                        elsif (wayA_B = "10") then next_state<=G5;
                                        elsif (wayA_B = "11") then next_state<=D2;
                                        else next_state<=idle;
                                        end if;
                        when G6=> next_state<=idle;
        end case;
end process;

--down/up assignement
en<='1' when (reg_state=D0 or reg_state=D2 or reg_state=D4 or reg_state=D6 or reg_state=G0 or reg_state=G2 or reg_state=G4 or reg_state=G6) else '0';
du<='1' when (reg_state=D0 or reg_state=D2 or reg_state=D4 or reg_state=D6) else '0';

end machine_behavior;
Ce programme est utilisé dans le cas ou la sortie est connectée à des compteurs décimaux mise en cascade. La sortie en(enable) valide le comptage si sa valeur est '1' et du(down/up) détermine si on incrémente ou décrémente suivant sa valeur '0' ou '1'.

Voici un extrait de la simulation sous ModelSim avec l'exemple énoncé précédemment. On remarque bien que la valeur de du passe à '0' quand on revient vers la gauche momentanément.
(cette image est a mettre à jour car on ne distingue pas bien les noms des signaux)


vendredi 19 avril 2013

RS-232 en VHDL

Présentation
Le port série ou RS-232 est un bus de communication qui permet de transférer des données en série sur deux fils, TxD (Tansmission Data) et RxD(Reception Data) en utilisant un UART (Universal Asynchronous Receiver Transmitter).
Protocole de communication
Pour la bonne transmission des données il est nécessaire que l'émetteur et le récepteur utilisent le même protocole.
Composition de la trame:

  • 1 bit de start :  ce bit correspond à un niveau logique 0, il permet la synchronisation de l'horloge du recepteur
  • 5 à 8 bits de données : ce sont les données à transmettre
  • 0 ou 1 bit de parité : pas obligatoire, ce bit permet de verifier la présence d'erreurs
  • Bit(s) de stop : on retourne au niveau logique 1 qui est l'état de repos de la ligne
Le debit de la liaison RS232 va de 110 à 115200 baud.

Programme VHDL
Dans ce programme nous travaillerons avec un débit de 19 200 baud. Ce paramètre peut être ajusté directement dans le programme. Pour plus de détails sur le fonctionnement consulter Design Example : UART pdf
  • Composant générateur d'horloge d'échantillonnage:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity mod_m_cnter is
 generic(
    N: integer := 8;
    M: integer := 163);
 port(
   clk, reset: in std_logic;
   clk_cnt: out std_logic);
end mod_m_cnter;

architecture arch of mod_m_cnter is
signal r_reg: unsigned(N-1 downto 0);
signal r_next: unsigned(N-1 downto 0);
begin
 process(clk, reset)
 begin
  if (reset = '0') then
   r_reg <= (others => '0');
  elsif (clk'event and clk='1') then
   r_reg <= r_next;
  end if;
 end process;
-- next state logic
r_next <= (others => '0') when r_reg=(M-1) else r_reg + 1;
clk_cnt <= '1' when r_reg=(M-1) else '0';
-- output logic
end arch;
  • Composant UART Rx
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity uart_rx is
generic(
   DBIT: integer := 8;
   SB_TICK: integer := 16 -- (16, 24 and 32 for 1, 1.5 and 2 stop bits)
   );
port(
  reset, clk: in std_logic;
  rx: in std_logic;
  s_tick: in std_logic;
  rx_done_tick: out std_logic;
  dout: out std_logic_vector(7 downto 0)
  );
end uart_rx;


architecture arch of uart_rx is
type state_type is (idle, start, data, stop);
signal state_reg, state_next: state_type;
signal s_reg, s_next: unsigned(3 downto 0);
signal n_reg, n_next: unsigned(2 downto 0);
signal b_reg, b_next: std_logic_vector(7 downto 0);

begin
process(clk, reset) -- FSMD state and data regs.
 begin
  if (reset = '0') then
  state_reg <= idle;
  s_reg <= (others => '0');
  n_reg <= (others => '0');
  b_reg <= (others => '0');
  elsif (clk'event and clk='1') then
  state_reg <= state_next;
  s_reg <= s_next;
  n_reg <= n_next;
  b_reg <= b_next;
  end if;
end process;

-- next state logic
process (state_reg, s_reg, n_reg, b_reg, s_tick, rx)
begin
state_next <= state_reg;
s_next <= s_reg;
n_next <= n_reg;
b_next <= b_reg;
rx_done_tick <= '0';


 case state_reg is
   when idle =>
   if (s_tick = '1') then
    if (rx = '0') then
    state_next <= start;
    s_next <= (others => '0');
    end if;
   end if;

   when start =>
    if (s_tick = '1') then
     if (s_reg = 7) then
      state_next <= data;
      s_next <= (others => '0');
      n_next <= (others => '0');
     else
      s_next <= s_reg + 1;
     end if;
    end if;

   when data =>
    if (s_tick = '1') then
     if (s_reg = 15) then
     s_next <= (others => '0');
     b_next <= rx & b_reg(7 downto 1);
      if (n_reg = (DBIT - 1)) then
      state_next <= stop;
      else
      n_next <= n_reg + 1;
      end if;
     else
     s_next <= s_reg + 1;
     end if;
    end if;
   when stop =>
    if (s_tick = '1') then
     if (s_reg >= (SB_TICK-1)) then
     state_next <= idle;
     rx_done_tick <= '1';
     else
     s_next <= s_reg + 1;
     end if;
    end if;
 end case;
end process;

dout <= b_reg;
end arch;


  • Composant UART Tx
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity uart_tx is
 generic(
    DBIT: integer := 8;
    SB_TICK: integer := 16
    );
 port(
    reset,clk: in std_logic;
    tx_start: in std_logic;
    s_tick: in std_logic;
    din: in std_logic_vector(7 downto 0);
    tx_done_tick: out std_logic;
    tx: out std_logic
    );
end uart_tx;


architecture arch of uart_tx is
type state_type is (idle, start, data, stop);
signal state_reg, state_next: state_type;
signal s_reg, s_next: unsigned(3 downto 0);
signal n_reg, n_next: unsigned(2 downto 0);
signal b_reg, b_next: std_logic_vector(7 downto 0);
signal tx_reg, tx_next: std_logic;
begin

 process(clk, reset) -- FSMD state and data regs.
 begin
  if (reset = '0') then
  state_reg <= idle;
  s_reg <= (others => '0');
  n_reg <= (others => '0');
  b_reg <= (others => '0');
  tx_reg <= '1';
  elsif (clk'event and clk='1') then
  state_reg <= state_next;
  s_reg <= s_next;
  n_reg <= n_next;
  b_reg <= b_next;
  tx_reg <= tx_next;
  end if;
end process;

-- next state logic
 process (state_reg, s_reg, n_reg, b_reg, s_tick,tx_reg, tx_start, din)
 begin
 state_next <= state_reg;
 s_next <= s_reg;
 n_next <= n_reg;
 b_next <= b_reg;
 tx_next <= tx_reg;
 tx_done_tick <= '0';

  case state_reg is
    when idle => tx_next <= '1';
     if (tx_start= '1') then
      state_next <= start;
      s_next <= (others => '0');
      b_next <= din;
     end if;
    when start => tx_next <= '0';
     if (s_tick = '1') then
      if (s_reg = 15) then
      state_next <= data;
      s_next <= (others => '0');
      n_next <= (others => '0');
      else
      s_next <= s_reg + 1;
      end if;
     end if;
    when data => tx_next <= b_reg(0);
     if (s_tick = '1') then
      if (s_reg = 15) then
      s_next <= (others => '0');
      b_next <= '0' & b_reg(7 downto 1);
       if (n_reg = (DBIT - 1)) then
       state_next <= stop;
       else
       n_next <= n_reg + 1;
       end if;

      else
      s_next <= s_reg + 1;
      end if;
     end if;
    when stop => tx_next <= '1';
     if (s_tick = '1') then
      if (s_reg = (SB_TICK-1)) then
      state_next <= idle;
      tx_done_tick <= '1';
      else
      s_next <= s_reg + 1;
      end if;
     end if;
  end case;
end process;
tx <= tx_reg;
end arch;


  • Composant générateur d'impulsion de durée réglable
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity pulse is
  generic(
          lenght: integer := 159 --clock period
          );
  port(                 
        clock,Key :in std_logic;
        s :out std_logic
        );
end;

architecture behavior of pulse is
  type state_type is (idle, impulse, stop);
  signal state : state_type;
  signal count : integer := 0;
 
  begin
    process (clock,state)
  begin
         if (clock'EVENT and clock ='1')  then
          
                case state is
     
                  when idle => s<='0';
       if key ='1' then state <= impulse;
       else state <= idle;
       end if;
                  when impulse => s<='1';
         if count=lenght then state <= stop;
       else count<=count+1;
       end if; 

                  when stop => s<='0'; count<=0;
            if Key ='0' then state <= idle;
                  else state <= stop;
                  end if; 
             end case;
          end if;

    end process;
end behavior;


  • Composant registre
library ieee;
use ieee.std_logic_1164.all;

entity registre is
port (d_out : in std_logic_vector(7 downto 0);
enable, reset : in std_logic;
out_d : out std_logic_vector(7 downto 0));
end;

architecture arch of registre is
begin
process (enable)
begin
  if (reset = '0') then
  out_d <= (others=>'0');
  elsif (enable'event and enable='1') then out_d <= d_out;
  end if;
end process;
end arch;

  • Fichier principal : module RS232
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity module_RS232 is
port (
  uart_rxd :  in std_logic;
  uart_txd :  out std_logic;
  KEY : in std_logic_vector(1 downto 0);
  SW : in std_logic_vector(7 downto 0);
  CLOCK_50 : in std_logic;
  LEDG : out std_logic_vector(7 downto 0));
end;


architecture behavior of module_RS232 is
---------------------------------------------------
component mod_m_cnter
generic(
N: integer := 8;
M: integer := 163);
port(
clk, reset: in std_logic;
clk_cnt: out std_logic
);
end component;
---------------------------------------------------
component uart_rx is
generic(
DBIT: integer := 8;
SB_TICK: integer := 16 -- (16, 24 and 32 for 1, 1.5 and 2 stop bits)
);
port(
clk, reset: in std_logic;
rx: in std_logic;
s_tick: in std_logic;
rx_done_tick: out std_logic;
dout: out std_logic_vector(7 downto 0));
end component;
------------------------------------------------------
component uart_tx is
generic(
DBIT: integer := 8;
SB_TICK: integer := 16);

port(
reset,clk: in std_logic;
  tx_start: in std_logic;
  s_tick: in std_logic;
  din: in std_logic_vector(7 downto 0);
  tx_done_tick: out std_logic;
  tx: out std_logic
);
end component;

-------------------------------------------------PULSE
component pulse IS
  generic(
          lenght: integer := 159 --clock period
          );
  PORT(                 
        clock,Key :IN std_logic;
        s :OUT std_logic
        );
END component;

-------------------------------------------------

signal wire_clk_cnt, s_tick, wire_rx_done ,wire_tx_done, wire_reg_enable, wire_pulse : std_logic;
signal wire_dataout: std_logic_vector(7 downto 0);


begin

I1 : mod_m_cnter port map (clk=>CLOCK_50, reset=>(KEY(0)), clk_cnt=>wire_clk_cnt);
I2 : uart_rx port map (clk=>CLOCK_50, s_tick=>wire_clk_cnt, reset=>(KEY(0)), rx=>uart_rxd, dout=>wire_dataout, rx_done_tick=>wire_reg_enable);
I3 : uart_tx port map (clk=>CLOCK_50, s_tick=>wire_clk_cnt, reset=>(KEY(0)), tx=>uart_txd, din=>SW,tx_done_tick=>wire_tx_done, tx_start=>wire_pulse);
I4 : registre port map (reset=>(KEY(0)), d_out=>wire_dataout, out_d =>LEDG, enable=>wire_reg_enable);
I5 : pulse port map(clock => CLOCK_50, Key => not(KEY(1)), s => wire_pulse);
end behavior;



Quelques modifications ont été apportées pour le générateur d'horloge d'échantillonage et pour l'UART ou la machine à état s'arrête parfois à cause d'un défaut de synchronisation du signal reçu. Des circuits ont été supprimés pour plus de simplicité et un générateur d'impulsion réglable a été ajouté pour envoyer les données une à une vers l'ordinateur. Lorsque l'on appuie sur le bouton pour émettre, on applique sur l'entrée tx_data une impulsion de même durée que la trame de donnée afin de s'assurer que toute cette trame à bien été envoyée.

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.