# Partie 1 : FPGA, HDL, simulation, synthétisation ? 
Si vous êtes là, c'est que vous avez probablement entendu parler de FPGA quelque part et que vous souhaitez en savoir plus sur leur fonctionnement, éventuellement expérimenter sur eux. Vous avez donc besoin de quelques notions théoriques pour avancer.

Ca tombe bien, c'est l'objet de cette première partie.

[[_TOC_]]


## FPGA et Microcontrôleur

### Microcontrôleur
Vous êtes probablement familier avec le concept de **microcontrôleur** et leur principe de fonctionnement. De manière générale, il est composé d'une unité de calcul, d'entrées et de sortie, de mémoire volatile et non volatile.

Pour le faire fonctionner, vous développer un microprogramme qui, une fois compilé, est téléchargé dans la mémoire non volatile du microcontrôleur. 

Si vous avez déjà utilisé une carte Arduino, vous connaissez probablement le code C suivante : 
```c
/* 
 Source :https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}
```
### FPGA 
Un  **FPGA (Field Programmable Grid Array)** fonctionne quant à lui bien différemment et pou cause : ce n'est pas un microcontrôleur.

Un FPGA est un composant électronique dit de _circuits logiques programmables_, c'est à dire qu'il est composé d'un assemblage de porte logique (AND, OR, Not, etc ...), de module de routage et de mémoire non volatiles permettant de "câbler" le circuit logique.

Un FPGA n'execute donc pas de programme comme le ferais un microcontrôleur. Il fonctionne en effet sur un principe de logique combinatoire temp réel (synchrone, asynchrone ou hybride). Les langages permettant de concevoir cette logique sont donc des langages de description matériel et non par des langages de programmation.

Les langage de description matériel, aussi appelés **HDL (Hardware Description Language**),  sont assez nombreux. Les plus couramment utilisés sont le _Verilog_, _SystemC_ et le _VHDL_. Dans notre cas, nous nous intéresserons au dernier.
D'une manière générale, ces langages permettent la description, simulation de fonctionnement et synthétisation de composants matériels.

Un exemple  de VHDL :
```vhdl
--- Source http://esd.cs.ucr.edu/labs/tutorial/fsm.vhd
-----------------------------------------------------
-- VHDL FSM (Finite State Machine) modeling
-- (ESD book Figure 2.7)
-- by Weijun Zhang, 04/2001
--
-- FSM model consists of two concurrent processes
-- state_reg and comb_logic
-- we use case statement to describe the state 
-- transistion. All the inputs and signals are
-- put into the process sensitive list.  
-----------------------------------------------------

library ieee ;
use ieee.std_logic_1164.all;

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

entity seq_design is
port(	a:		in std_logic;
	clock:		in std_logic;
	reset:		in std_logic;
	x:		out std_logic
);
end seq_design;

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

architecture FSM of seq_design is

    -- define the states of FSM model

    type state_type is (S0, S1, S2, S3);
    signal next_state, current_state: state_type;

begin
    
    -- cocurrent process#1: state registers
    state_reg: process(clock, reset)
    begin

	if (reset='1') then
            current_state <= S0;
	elsif (clock'event and clock='1') then
	    current_state <= next_state;
	end if;

    end process;						  

    -- cocurrent process#2: combinational logic
    comb_logic: process(current_state, a)
    begin

	-- use case statement to show the 
	-- state transistion

	case current_state is

	    when S0 =>	x <= '0';
			if a='0' then
			    next_state <= S0;
			elsif a ='1' then
			    next_state <= S1;
			end if;

	    when S1 =>	x <= '0';
			if a='0' then 
			    next_state <= S1;
			elsif a='1' then 
			    next_state <= S2;
			end if;

	    when S2 =>	x <= '0';
			if a='0' then
			    next_state <= S2;
			elsif a='1' then
			    next_state <= S3;
			end if;

	    when S3 =>	x <= '1';
			if a='0' then 
			    next_state <= S3;
			elsif a='1' then 
			    next_state <= S0;
			end if;

	    when others =>
			x <= '0';
			next_state <= S0;

	end case;

    end process;

end FSM;

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

```

## Description, Simulation et Synthèse
Il existe trois étapes importante dans la création d'architecture matérielle :
- la description du fonctionnement d'un composant logique
- la simulation de ce composant et la validation de son fonctionnement
- la synthétisation du composant pour l'architecture du FPGA

### Description d'un composant
Comme pour les composants physiques, les composants logiques décrits en VHDL sont constitués d'entrés, de sorties et d'une logique effectuant un traitement. On pourrait le comparer par analogie à une fonction dans un programme.

En se basant sur l'extrait de code VHDL ci-dessus, on peut analyser comment est représenté un composant en VHDL :

1. **Déclaration des bibliothèques :**
   Les langages HDL étant normées et étant conçus sur une base d'éléments logiques pré-implémentés, il est nécessaire de déclarer quelques bibliothèques standards par défaut.
   ```vhdl
   library ieee ;
   use ieee.std_logic_1164.all;
   ```
2. **Déclaration d'une entité :**
   En VHDL, un composant est appelé une _entité_ et dispose de ports d'entrés et de sorties.
   Chaque port définis un mode de fonctionnement (in / out / etc ...) et son type, ici std_logic (booléen).
   ```vhdl
   entity design is
       port(	a:		in std_logic;
            clock:		in std_logic;
            reset:		in std_logic;
            x:		    out std_logic
        );
    end design;
   ```


3. **Déclaration d'une architecture :**
   Une entité doit au moins référencer une architecture logique.
   Elle décrit les opérations logiques qui permettent de modifier les états des sorties de l'entité en fonction des états des entrées.
   ```vhdl
   architecture RTL of seq_design is

		-- define the states of RTL model

		type state_type is (S0, S1, S2, S3);
		signal next_state, current_state: state_type;
	
	begin
		
		-- cocurrent process#1: state registers
		state_reg: process(clock, reset)
		begin

		if (reset='1') then
				current_state <= S0;
		elsif (clock'event and clock='1') then
			current_state <= next_state;
		end if;

		-- Some more logic 

		end process;
	end 

   ```
   On remarque alors deux bloc de code distinct : un premier comportant une définition de _type_ et _signal_, un second composé d'un _process_. 

   Le premier bloc correspond à ce que l'ont pourrait associer à une définition de type de donnée (ici une énumération) et de variable en développement logiciel. 

   Le second bloc s’apparente quant à lui à la fonction _loop()_ d'un programme Arduino : il s'agit d'un processus, c'est à dire une suite d'instructions séquentiel synchronisé sur une horloge.

   ⚠️ ATTENTION : le fonctionnement d'un processus est plus compliqué qu'une simple boucle infini : nous reviendrons sur ce sujet plus tard.

Vous avez donc maintenant une petite idée de comment est structuré une entité (composant) en VHDL. Bien entendu l'exemple est relativement simple et n'implémente pas d'autre composants, mais pas de stress car cela vas vite se complexifier

### Simulation et banc de test
Dans le monde de l'embarqué, nous aimons bien simuler le fonctionnement de systèmes durant leur phase de conception. Cela permets de s'assurer qu'ils réagissent correctement dans différents scénarios de fonctionnement et que leur comportement ne dévie pas des spécifications.


Je vous le donne dans le mille : il en va même pour les entité en VHDL.
La simu