%------------------------------------------------------------------------------
% $Id: document-morpheo-vhdl_generation-fr.tex 98 2008-12-31 10:18:08Z rosiere $
%------------------------------------------------------------------------------

\SEction{Introduction}

Ce document est une aide pour les développeur des générateurs de modèles VHDL de \cpu.
Il est décomposé en 6 sections :
\begin{itemize}
\item Dans la section \ref{tree}, nous présentons l'arborescence des répertoires.
\item Dans la section \ref{vhdl_declaration}, nous expliciterons l'API ({\it Application Programming Interface}) pour la déclaration des signaux et des types du VHDL.
\item Dans la section \ref{vhdl_body}, nous présenterons l'API pour générer le comportement des composants.
\item Dans la section \ref{vhdl_structural}, nous expliquerons la manière de créer des sous composants.
\item Dans la section \ref{example}, nous montrerons quelques exemples.
\item Dans la section \ref{testbench}, nous présenterons la méthodologie de test.
\end{itemize}

\Section{Arborescence}\label{tree}

Dans le répertoire contenant le projet, nous avons les répertoires suivant :
\begin{description}
\item[IPs/systemC/processor/Morpheo/Documentation/ :] Contient différent document décrivant certain point du projet, dont cette documentation.
\item[IPs/systemC/processor/Morpheo/Behavioural/ :] 
\item[IPs/systemC/processor/Morpheo/Behavioural/include/ :]
  \begin{description}
  \item [Parameters.h :] Contient la classe {\it Parameters}, cette classe définit les paramètres constants.
  \item [Vhdl.h :] Contient la classe {\it Vhdl}. 
  \end{description}
\item[IPs/systemC/processor/Morpheo/Behavioural/\dots/Component :] Chaque composant est inclue dans un répertoire spécifique.
\item[IPs/systemC/processor/Morpheo/Behavioural/\dots/Component/include :]
  \begin{description}
  \item [Parameters.h :] Contient la classe {\it Parameters}, elle dérive de la classe contenu dans le fichier le répertoire {\it \dots/Behavioural/include/}.
  \item [Component.h  :] Contient la classe {\it Component}. Il définit l'interface, les registres ainsi que les méthodes du modèle systemC.
  \item [Types.h      :] Contient les types spéciaux.
  \end{description}
\item[IPs/systemC/processor/Morpheo/Behavioural/\dots/Component/src :]
  \begin{description}
  \item [Component\_transition.cpp :]
  \item [Component\_genMoore.cpp :]
  \item [Component\_genMealy\_XXX.cpp :]

  \item [Component\_vhdl\_declaration.cpp :]
  \item [Component\_vhdl\_body.cpp :]
  \end{description}
\item[IPs/systemC/processor/Morpheo/Behavioural/\dots/Component/Selftest :]
\end{description}

\Section{VHDL : déclaration}\label{vhdl_declaration}

Les déclarations ce font dans le fichier {\it Component\_vhdl\_declaration.cpp}.

\subSection{Interfaces}
L'interface est définit dans le modèle SystemC. Il n'ont pas nécessaire de la redéfinir pour le modèle VHDL.

La nomenclature est la suivante :
\begin{itemize}
\item La direction en minuscule ({\it in}, {\it out}).
\item Le nom de l'interface en majuscule ({\it READ}, {\it PUSH}, \dots).
\item Le numéro de l'interface (la première interface aura le numéro 0. S'il n'y a qu'une interface, celle ci aura tout de même le numéro 0).
\item Le nom du signal en majuscule ({\it VAL}, {\it ADDRESS}, \dots).
\end{itemize}

Par exemple pour la 2 ème interface de lecture d'un banc de registre :
\lstparam{VHDL}
\begin{lstlisting}
 in_READ_1_VAL     : in  std_logic;
out_READ_1_ACK     : out std_logic;
 in_READ_1_ADDRESS : in  std_logic_vector(8 downto 0);
out_READ_1_DATA    : out std_logic_vector(31 downto 0);
\end{lstlisting}

Chaque composent (aussi bien combinatoire que séquentielle) possède un signal d'horloge et un signal de reset. (Ce dernier est actif à l'état bas). Ils ont tout les deux le même nom quelque soit le composant.
\lstparam{VHDL}
\begin{lstlisting}
 in_CLOCK  : in std_logic;
 in_NRESET : in std_logic;
\end{lstlisting}

\subSection{Types}

Le type de base utilisé est le {\it std\_logic\_vector} (ou std\_logic si le vecteur est sur un seul bit). Pour cela on utilise la fonction suivante :

\lstparam{C++}
\begin{lstlisting}
std::string std_logic (uint32_t size);
\end{lstlisting}

Pour accéder à une partie du vecteur on utilise la fonction {\it std\_logic\_range}. Elle a les prototypes suivant :
\lstparam{C++}
\begin{lstlisting}
std::string std_logic_range  (uint32_t size,
                              uint32_t max ,
                              uint32_t min);
std::string std_logic_range  (uint32_t max ,
                              uint32_t min);
std::string std_logic_range  (uint32_t size);
std::string _std_logic_range (uint32_t size,
                              uint32_t max ,
                              uint32_t min);
std::string _std_logic_range (uint32_t max ,
                              uint32_t min);
std::string _std_logic_range (uint32_t size);
\end{lstlisting}

La première fonction fais un test sur la taille que la seconde ne fait pas.
L'argument de la troisième définit la taille (ce qui implique que la borne minimum est 0 et la borne maximum est size-1).
Toute les fonctions avec préfixé par un underscore n'effectue pas de test sur les bornes.

Par exemple :
\begin{verbatim}
 std_logic_range(4) renvoie "(3 downto 0)".
 std_logic_range(1) renvoie "(0)".
_std_logic_range(1) renvoie "(0 downto 0)".
\end{verbatim}

Pour les types plus complexe, la classe {\it Vhdl} possède une méthode générique. Le premier argument est le nom du type le second est le type.

\lstparam{C++}
\begin{lstlisting}
void set_type (std::string name,
               std::string type);
\end{lstlisting}

L'exemple suivant définit un type représentat un tableau de {\it nb\_word} mots de {\it size\_word} bit chacun :
\lstparam{C++}
\begin{lstlisting}
vhdl->set_type ("Tregfile", 
                "array "+std_logic_range(nb_word)+" of "+std_logic(size_word));
\end{lstlisting}

\subSection{Constantes}

La déclaration de constante, ce fait avec la méthode {\it set\_constant} de la classe {\it Vhdl}. Les différentes surcharges de cette méthode est le type des arguments {\it type} et {\it init}. 

\lstparam{C++}
\begin{lstlisting}
void set_constant (std::string name,
                   std::string type,
                   std::string init);
void set_constant (std::string name,
                   uint32_t    size,
                   std::string init);
void set_constant (std::string name,
                   uint32_t    size,
                   uint32_t    init);
\end{lstlisting}

Par exemple pour coder les états d'un automate à 5 états en One Hot :
\lstparam{C++}
\begin{lstlisting}
vhdl->set_constant ("State_idle",5,1);
\end{lstlisting}

Dans le cas de signaux de type {\it std\_logic}, au lieu de déclarer des constantes, il existe deux fonctions permettant d'utiliser des constantes directement dans le corps du composant.
La première est {\it std\_logic\_others}. Elle permet de définir des constantes dont soit les bits sont à pleins un soit à plein zéro.

\lstparam{C++}
\begin{lstlisting}
std::string std_logic_others (uint32_t size,
                              bool cst  );
\end{lstlisting}

Pour toute les autres constantes, la méthode {\it std\_logic\_conv} transforme un entier en {\it std\_logic\_vector}.

\lstparam{C++}
\begin{lstlisting}
std::string std_logic_conv (uint32_t    size,
                            std::string value);
std::string std_logic_conv (uint32_t    size,
                            uint32_t    value);
\end{lstlisting}


\subSection{Signaux internes}

Les signaux internes sont définit grâce au méthode {\it set\_signal}. Le premier argument est le nom du signal. Le second est soit un type soit une taille (dans le cas où le type est un  {\it std\_logic\_vector}).
\lstparam{C++}
\begin{lstlisting}
void set_signal (std::string name,
                 std::string type);
void set_signal (std::string name,
                 uint32_t    size);
\end{lstlisting}

La méthode est également surchargé si le signal à besoin d'une initialisation.

\lstparam{C++}
\begin{lstlisting}
void set_signal (std::string name,
                 std::string type,
                 std::string init);
void set_signal (std::string name,
                 uint32_t    size,
                 std::string init);
void set_signal (std::string name,
                 uint32_t    size,
                 uint32_t    init);
\end{lstlisting}

En vhdl il est possible de renommer une champ d'un signal. Ceci ce fait à l'aide de la fonction {\it set\_alias}. Elle prend 4 arguments. Le premier étant le nom du signal après le renommage. le second est soit le type, soit la taille du {\it std\_logic\_vector} du signal rénommé. Les deux derniers conserné le signal à renommé : le nom de ce dernier ainsi que l'intervalle. Pour le dernier paramètre il est recommandé d'utilisé la fonction {\it std\_logic\_range}.

\lstparam{C++}
\begin{lstlisting}
void set_alias (std::string name1 ,
                std::string type1 ,
                std::string name2 ,
                std::string range2);
void set_alias (std::string name1 ,
                uint32_t    size1 ,
                std::string name2 ,
                std::string range2);
\end{lstlisting}

\Section{VHDL : comportement}\label{vhdl_body}

Le comportement du composant est définit dans le fichier  {\it Component\_vhdl\_body.cpp}.

Il n'y a pas de fonction aidant à l'écriture du Vhdl.
La méthode {\it set\_body} permet de définir une ligne de code VHDL. Un retour à la ligne est automatiquement inséré. Le premier argument est pour l'indentation.
\lstparam{C++}
\begin{lstlisting}
void set_body (uint32_t    depth,
               std::string text );
void set_body (std::string text );
\end{lstlisting}

Pour les commentaires, il y a la fonction {\it set\_comment}.
\lstparam{C++}
\begin{lstlisting}
void set_comment (uint32_t    depth,
                  std::string text );
void set_comment (std::string text );
\end{lstlisting}

\Section{VHDL : structurelle}\label{vhdl_structural}

\subSection{Description du fichier {\it Component\_vhdl.cpp}}
Les modèles systemC structurelle sont des modèles qui instancie d'autre modèle. Il n'y a pas de description comportementale. Ces modèles sont générés automatiquement. 
Par contre les modèles systemC comportementales peuvent être décrit par un modèle VHDL mixte (incluant une description comportementale et des instances d'autre composant).

Les modèles génériques sont dans le répertoire {\it IPs/systemC/processor/Morpheo/Behavioural/Generic}.

\lstparam{C++}
\begin{lstlisting}[caption={Component\_vhdl.cpp}, label=component_vhdl.cpp]
  void component::vhdl (void)
  {
    Vhdl * vhdl = new Vhdl (_name);

    _interfaces->set_port(vhdl);
    _component->vhdl_instance(vhdl);

    vhdl_declaration (vhdl);
    vhdl_body        (vhdl);

    vhdl->generate_file();

    delete vhdl;
  };
\end{lstlisting}


La première étape est d'éditer le fichier {\it Component\_vhdl.cpp}. Le listing \ref{component_vhdl.cpp} représente le contenu de ce fichier. 
\begin{itemize}
\item Ligne 3 : Déclaration et construction de la variable {\it vhdl} qui est du  type {\it Vhdl}.
\item Ligne 5 : Ajout dans le modèle VHDL des interfaces présentes dans le modèle SystemC. (cf fichiers Component.h).
\item Ligne 6 : Ajout dans le modèle VHDL des composants internes  dans le modèle SystemC. (cf fichiers Component.h et Component\_allocation.cpp).
\item Ligne 8 : Ajout dans le modèle VHDL des déclarations définit dans le fichiers Component\_vhdl\_declaration.cpp (cf section \ref{vhdl_declaration}).
\item Ligne 9 : Ajout dans le modèle VHDL de la description comportemental définit dans le fichiers Component\_vhdl\_body.cpp (cf section \ref{vhdl_body}).
\item Ligne 11 : Génération des fichiers VHDL. Le nom du fichier est construit à partir du nom fournit lors de la construction de la variable {\it vhdl}.
\item Ligne 13 : Destruction de l'objet. 
\end{itemize}

Pour la suite, nous allons supposer l'instanciation d'une FIFO.

\subSection{Ajout d'une instance}

Dans le fichier Component\_vhdl.cpp :
\begin{enumerate}
\item Inclure la définition de la classe désirée.
\lstparam{C++}
\begin{lstlisting}
#include "Behavioural/Generic/Queue/include/Queue.h"
\end{lstlisting}
\item Creer les paramètres du modèles.
\lstparam{C++}
\begin{lstlisting}
    morpheo::behavioural::generic::queue::Parameters * param_queue;
    param_queue = new morpheo::behavioural::generic::queue::Parameters
      (16, //size_queue
       32);//size_data 
\end{lstlisting}
\item Creer le modèle
\lstparam{C++}
\begin{lstlisting}
    morpheo::behavioural::generic::queue::Queue      * queue;
    std::string queue_name = _name + "_queue";

    queue = new morpheo::behavioural::generic::queue::Queue
      (queue_name.c_str() // nom du modèle
#ifdef STATISTICS
       ,NULL              // Pas paramètres pour les statistiques
#endif
       ,param_queue       // Paramètres de la file
       ,USE_VHDL);        // Utilisation du modèle VHDL
\end{lstlisting}
\item Inclure le modèle dans la liste des composants internes
\lstparam{C++}
\begin{lstlisting}
    _component->set_component(queue->_component
#ifdef POSITION
                              , 20, 20, 20, 20   
                              // Coordonée pour l'outil de visualisation
#endif
                              , INSTANCE_LIBRARY 
                              // Instancier uniquement les libraries
                              );
\end{lstlisting}
\item Indiquer dans le fichier Makefile.deps que le composant dépends de ce modèle. 
\lstparam{make}
\begin{lstlisting}
# Inclure les dépendances
ifndef Queue
include  $(DIR_MORPHEO)/Behavioural/Generic/Queue/Makefile.deps
endif

# Inclure les librairies
Component_LIBRARY       = -lComponent     \
                          $(Queue_LIBRARY)

# Les chemins vers les libraries
Component_DIR_LIBRARY   = -L$(Component_DIR)/lib  \
                          $(Queue_DIR_LIBRARY)

# Construction de la librarie ``Component''
Component_library       :
                        @\
                        $(MAKE) Queue_library; \
                        $(MAKE) --directory=$(Component_DIR) --makefile=Makefile;

# Effacement des fichiers générés
Component_library_clean :
                        @\
                        $(MAKE) Queue_library_clean; \
                        $(MAKE) --directory=$(Component_DIR) --makefile=Makefile clean;
\end{lstlisting}
\end{enumerate}

\subSection{Instanciation}
L'instanciation ce fait comme avec des composants VHDL classique :
\lstparam{C++}
\begin{lstlisting}
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"-- Instance queue                  ");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"");

    vhdl->set_body   (0,"instance_"+_name+"_queue : "+_name+"_queue");
    vhdl->set_body   (0,"port map (");
    vhdl->set_body   (1,"  in_CLOCK       \t=>\t      in_CLOCK ");
    vhdl->set_body   (1,", in_NRESET      \t=>\t      in_NRESET");
    vhdl->set_body   (1,", in_INSERT_VAL  \t=>\tinternal_QUEUE_INSERT_VAL");
    vhdl->set_body   (1,",out_INSERT_ACK  \t=>\tinternal_QUEUE_INSERT_ACK");
    vhdl->set_body   (1,", in_INSERT_DATA \t=>\tinternal_QUEUE_INSERT_DATA");
    vhdl->set_body   (1,",out_RETIRE_VAL  \t=>\tinternal_QUEUE_RETIRE_VAL");
    vhdl->set_body   (1,", in_RETIRE_ACK  \t=>\tinternal_QUEUE_RETIRE_ACK");
    vhdl->set_body   (1,",out_RETIRE_DATA \t=>\tinternal_QUEUE_RETIRE_DATA");
    vhdl->set_body   (0,");");
\end{lstlisting}

\Section{Exemples}\label{example}

\subSection{Banc de Registres Monolithique}

\subsubSection{Fichier RegisterFile\_Monolithic\_vhdl.cpp}

\lstparam{C++}
\begin{lstlisting}[caption={RegisterFile\_Monolithic\_vhdl.cpp}]
void RegisterFile_Monolithic::vhdl (void)
{
  Vhdl * vhdl = new Vhdl (_name);

  _interfaces->set_port     (vhdl);
  _component ->vhdl_instance(vhdl);

  vhdl_declaration (vhdl);
  vhdl_body        (vhdl);

  vhdl->generate_file();

  delete vhdl;
};
\end{lstlisting}


\subsubSection{Fichier RegisterFile\_Monolithic\_vhdl\_declaration.cpp}

\lstparam{C++}
\begin{lstlisting}[caption={RegisterFile\_Monolithic\_vhdl\_declaration.cpp}]
void RegisterFile_Monolithic::vhdl_declaration (Vhdl * & vhdl)
{
  vhdl->set_type ("Tregfile", "array " + std_logic_range(_param->_nb_word,true)+
                              " of "+
                              std_logic(_param->_size_word));

  vhdl->set_signal ("reg_DATA", "Tregfile");
};
\end{lstlisting}

\subsubSection{Fichier RegisterFile\_Monolithic\_vhdl\_body.cpp}

\lstparam{C++}
\begin{lstlisting}[caption={RegisterFile\_Monolithic\_vhdl\_body.cpp}]
void RegisterFile_Monolithic::vhdl_body (Vhdl * & vhdl)
{
  vhdl->set_body   (0,"");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_comment(0," Ack");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_body   (0,"");

  for (uint32_t i = 0; i < _param->_nb_port_read; i++)
    vhdl->set_body   (0,"out_READ_"+toString(i)+"_ACK  <= '1';");
  for (uint32_t i = 0; i < _param->_nb_port_write; i++)
    vhdl->set_body   (0,"out_WRITE_"+toString(i)+"_ACK <= '1';");

  vhdl->set_body   (0,"");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_comment(0," Read RegisterFile");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_body   (0,"");
  
  for (uint32_t i = 0; i < _param->_nb_port_read; i++)
    {
      std::string str_address;
      if (_param->_have_port_address)
        str_address = "conv_integer(in_READ_"+toString(i)+"_ADDRESS)";
      else
        str_address = "0";

      vhdl->set_body   (0,"out_READ_"+toString(i)+"_DATA <= reg_DATA ("+str_address+
                           ") when in_READ_"+toString(i)+"_VAL = '1' else "+
                           std_logic_others(_param->_size_word,0)+";");
    }

  vhdl->set_body   (0,"");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_comment(0," Write RegisterFile");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_body   (0,"");

  vhdl->set_body   (0,"RegisterFile_write: process (in_CLOCK)");
  vhdl->set_body   (0,"begin  -- process RegisterFile_write");
  vhdl->set_body   (1,"if in_CLOCK'event and in_CLOCK = '1' then");
  
  for (uint32_t i = 0; i < _param->_nb_port_write; i++)
    {
      std::string str_address;
      if (_param->_have_port_address)
        str_address = "conv_integer(in_WRITE_"+toString(i)+"_ADDRESS)";
      else
        str_address = "0";

      vhdl->set_body   (2,"if (in_WRITE_"+toString(i)+"_VAL = '1') then");
      vhdl->set_body   (3,"reg_DATA("+str_address+") <= in_WRITE_"+toString(i)+"_DATA;");
      vhdl->set_body   (2,"end if;");
    }

  vhdl->set_body   (1,"end if;");
  vhdl->set_body   (0,"end process RegisterFile_write;");
};
\end{lstlisting}

\subsubSection{Fichier RegisterFile\_Monolithic.vhdl}

\lstparam{VHDL}
\begin{lstlisting}[caption={RegisterFile\_Monolithic.cpp}]
  library ieee;
  use ieee.numeric_bit.all;       
  use ieee.numeric_std.all;       
  use ieee.std_logic_1164.all;    
  use ieee.std_logic_arith.all;   
  use ieee.std_logic_misc.all;    
--use ieee.std_logic_signed.all;  
  use ieee.std_logic_unsigned.all;
--use ieee.std_logic_textio.all;  


library work;
use work.RegisterFile_Monolithic_Pack.all;


entity RegisterFile_Monolithic is
  port ( in_CLOCK          : in  std_logic;
         in_NRESET         : in  std_logic;
         in_READ_0_VAL     : in  std_logic;
        out_READ_0_ACK     : out std_logic;
         in_READ_0_ADDRESS : in  std_logic_vector(8 downto 0);
        out_READ_0_DATA    : out std_logic_vector(31 downto 0);
         in_WRITE_0_VAL    : in  std_logic;
        out_WRITE_0_ACK    : out std_logic;
         in_WRITE_0_ADDRESS: in  std_logic_vector(8 downto 0);
         in_WRITE_0_DATA   : in  std_logic_vector(31 downto 0)
       );
end RegisterFile_Monolithic;

architecture behavioural of RegisterFile_Monolithic is
  type Tregfile   is array (511 downto 0) of std_logic_vector(31 downto 0);

  signal reg_DATA : Tregfile;

begin
  -----------------------------------------------------
  -- Ackitement
  -----------------------------------------------------
  
  out_READ_0_ACK  <= '1';
  out_WRITE_0_ACK <= '1';
  
  -----------------------------------------------------
  -- Read RegisterFile
  -----------------------------------------------------
  
  out_READ_0_DATA <= reg_DATA (conv_integer(in_READ_0_ADDRESS)) 
                     when in_READ_0_VAL = '1'
                     else (others => '0');
  
  -----------------------------------------------------
  -- Write RegisterFile
  -----------------------------------------------------
  
  RegisterFile_write: process (in_CLOCK)
  begin  -- process RegisterFile_write
    if in_CLOCK'event and in_CLOCK = '1' then
      if (in_WRITE_0_VAL = '1') then
        reg_DATA(conv_integer(in_WRITE_0_ADDRESS)) <= in_WRITE_0_DATA;
      end if;
    end if;
  end process RegisterFile_write;
end behavioural;
\end{lstlisting}

\subSection{Tampon entre la boucle d'exécutione et le buffer de réordonnancement}

\subsubSection{Fichier Execute\_queue\_vhdl.cpp}

\lstparam{C++}
\begin{lstlisting}[caption={Execute\_queue\_vhdl.cpp}]
void Execute_queue::vhdl (void)
{
  morpheo::behavioural::generic::queue::Parameters * param_queue;
  
  param_queue = new morpheo::behavioural::generic::queue::Parameters
    (_param->_size_queue,
     _param->_size_internal_queue
     );
  
  morpheo::behavioural::generic::queue::Queue      * queue;

  std::string queue_name = _name + "_queue";
  queue = new morpheo::behavioural::generic::queue::Queue
    (queue_name.c_str()
#ifdef STATISTICS
     ,NULL
#endif
     ,param_queue
     ,USE_VHDL);
  
  _component->set_component(queue->_component
#ifdef POSITION
                            , 50, 50, 50, 50
#endif
                            , INSTANCE_LIBRARY
                            );

  Vhdl * vhdl = new Vhdl (_name);

  _interfaces->set_port(vhdl);
  _component->vhdl_instance(vhdl);

  vhdl_declaration (vhdl);
  vhdl_body        (vhdl);

  vhdl->generate_file();

  delete vhdl;
};
\end{lstlisting}

\subsubSection{Fichier Execute\_queue\_vhdl\_declaration.cpp}

\lstparam{C++}
\begin{lstlisting}[caption={Execute\_queue\_vhdl\_declaration.cpp}]
void Execute_queue::vhdl_declaration (Vhdl * & vhdl)
{
  vhdl->set_alias  ("internal_QUEUE_INSERT_VAL ",
                    1,
                    " in_EXECUTE_QUEUE_IN_VAL",
                    std_logic_range(1));
  vhdl->set_alias  ("internal_QUEUE_INSERT_ACK ",
                    1,
                    "out_EXECUTE_QUEUE_IN_ACK",
                    std_logic_range(1));
  vhdl->set_signal ("internal_QUEUE_INSERT_DATA",
                    _param->_size_internal_queue);
  vhdl->set_signal ("internal_QUEUE_RETIRE_DATA",
                    _param->_size_internal_queue);
  vhdl->set_alias  ("internal_QUEUE_RETIRE_VAL ",
                    1,
                    "out_EXECUTE_QUEUE_OUT_VAL",
                    std_logic_range(1));
  vhdl->set_alias  ("internal_QUEUE_RETIRE_ACK ",
                    1,
                    " in_EXECUTE_QUEUE_OUT_ACK",
                    std_logic_range(1));

  uint32_t min = 0;
  uint32_t max, size;

  if(_param->_have_port_context_id   )
    {
  size = _param->_size_context_id;
  max = min-1+size;
  vhdl->set_alias ("internal_EXECUTE_QUEUE_OUT_CONTEXT_ID           ",
                   std_logic(size),
                   "internal_QUEUE_RETIRE_DATA",
                   std_logic_range(_param->_size_internal_queue,max,min));
  min = max+1;
    }
  if(_param->_have_port_front_end_id   )
    {
  size = _param->_size_front_end_id;
  max = min-1+size;
  vhdl->set_alias ("internal_EXECUTE_QUEUE_OUT_FRONT_END_ID         ",
                   std_logic(size),
                   "internal_QUEUE_RETIRE_DATA",
                   std_logic_range(_param->_size_internal_queue,max,min));
  min = max+1;
    }
  if(_param->_have_port_ooo_engine_id   )
    {
  size = _param->_size_ooo_engine_id;
  max = min-1+size;
  vhdl->set_alias ("internal_EXECUTE_QUEUE_OUT_OOO_ENGINE_ID        ",
                   std_logic(size),
                   "internal_QUEUE_RETIRE_DATA",
                   std_logic_range(_param->_size_internal_queue,max,min));
  min = max+1;
    }
  if(_param->_have_port_rob_ptr)
    {
  size = _param->_size_rob_ptr;
  max = min-1+size;
  vhdl->set_alias ("internal_EXECUTE_QUEUE_OUT_PACKET_ID            ",
                   std_logic(size),
                   "internal_QUEUE_RETIRE_DATA",
                   std_logic_range(_param->_size_internal_queue,max,min));
  min = max+1;
    }

  size = _param->_size_special_data;
  max = min-1+size;
  vhdl->set_alias ("internal_EXECUTE_QUEUE_OUT_FLAGS                ",
                   std_logic(size),
                   "internal_QUEUE_RETIRE_DATA",
                   std_logic_range(_param->_size_internal_queue,max,min));
  min = max+1;

  size = _param->_size_exception;    
  max = min-1+size;
  vhdl->set_alias ("internal_EXECUTE_QUEUE_OUT_EXCEPTION            ",
                   std_logic(size),
                   "internal_QUEUE_RETIRE_DATA",
                   std_logic_range(_param->_size_internal_queue,max,min));
  min = max+1;

  size = 1;
  max = min-1+size;
  vhdl->set_alias ("internal_EXECUTE_QUEUE_OUT_NO_SEQUENCE          ",
                   std_logic(size),
                   "internal_QUEUE_RETIRE_DATA",
                   std_logic_range(_param->_size_internal_queue,max,min));
  min = max+1;

  size = _param->_size_instruction_address;
  max = min-1+size;
  vhdl->set_alias ("internal_EXECUTE_QUEUE_OUT_ADDRESS              ",
                   std_logic(size),
                   "internal_QUEUE_RETIRE_DATA",
                   std_logic_range(_param->_size_internal_queue,max,min));
  min = max+1;

  size = _param->_size_general_data;
  max = min-1+size;
  vhdl->set_alias ("internal_EXECUTE_QUEUE_OUT_DATA                 ",
                   std_logic(size),
                   "internal_QUEUE_RETIRE_DATA",
                   std_logic_range(_param->_size_internal_queue,max,min));
  min = max+1;
};
\end{lstlisting}

\subsubSection{Fichier Execute\_queue\_vhdl\_body.cpp}

\lstparam{C++}
\begin{lstlisting}[caption={Execute\_queue\_vhdl\_body.cpp}]
void Execute_queue::vhdl_body (Vhdl * & vhdl)
{
  vhdl->set_comment(0,"");
  vhdl->set_comment(0,"-----------------------------------");
  vhdl->set_comment(0,"-- Instance queue                  ");
  vhdl->set_comment(0,"-----------------------------------");
  vhdl->set_comment(0,"");

  vhdl->set_body   (0,"instance_"+_name+"_queue : "+_name+"_queue");
  vhdl->set_body   (0,"port map (");
  vhdl->set_body   (1,"  in_CLOCK       \t=>\t      in_CLOCK ");
  vhdl->set_body   (1,", in_NRESET      \t=>\t      in_NRESET");
  vhdl->set_body   (1,", in_INSERT_VAL  \t=>\tinternal_QUEUE_INSERT_VAL");
  vhdl->set_body   (1,",out_INSERT_ACK  \t=>\tinternal_QUEUE_INSERT_ACK");
  vhdl->set_body   (1,", in_INSERT_DATA \t=>\tinternal_QUEUE_INSERT_DATA");
  vhdl->set_body   (1,",out_RETIRE_VAL  \t=>\tinternal_QUEUE_RETIRE_VAL");
  vhdl->set_body   (1,", in_RETIRE_ACK  \t=>\tinternal_QUEUE_RETIRE_ACK");
  vhdl->set_body   (1,",out_RETIRE_DATA \t=>\tinternal_QUEUE_RETIRE_DATA");
  vhdl->set_body   (0,");");

  vhdl->set_comment(0,"");
  vhdl->set_comment(0,"-----------------------------------");
  vhdl->set_comment(0,"-- Input  Buffer                   ");
  vhdl->set_comment(0,"-----------------------------------");
  vhdl->set_comment(0,"");

  {
  uint32_t min = 0;
  uint32_t max, size;
  uint32_t size_queue = _param->_size_internal_queue;

  if(_param->_have_port_context_id   )
    {
  size = _param->_size_context_id;
  max = min-1+size;
  vhdl->set_body   (0,"internal_QUEUE_INSERT_DATA "+std_logic_range(size_queue,max,min)+
                      " <= in_EXECUTE_QUEUE_IN_CONTEXT_ID;");
  min = max+1;
    }
  if(_param->_have_port_front_end_id   )
    {
  size = _param->_size_front_end_id;
  max = min-1+size;
  vhdl->set_body   (0,"internal_QUEUE_INSERT_DATA "+std_logic_range(size_queue,max,min)+
                      " <= in_EXECUTE_QUEUE_IN_FRONT_END_ID;");
  min = max+1;
    }
  if(_param->_have_port_ooo_engine_id   )
    {
  size = _param->_size_ooo_engine_id;
  max = min-1+size;
  vhdl->set_body   (0,"internal_QUEUE_INSERT_DATA "+std_logic_range(size_queue,max,min)+
                      " <= in_EXECUTE_QUEUE_IN_OOO_ENGINE_ID;");
  min = max+1;
    }
  if(_param->_have_port_rob_ptr)
    {
  size = _param->_size_rob_ptr;
  max = min-1+size;
  vhdl->set_body   (0,"internal_QUEUE_INSERT_DATA "+std_logic_range(size_queue,max,min)+
                      " <= in_EXECUTE_QUEUE_IN_PACKET_ID;");
  min = max+1;
    }

  size = _param->_size_special_data;
  max = min-1+size;
  vhdl->set_body   (0,"internal_QUEUE_INSERT_DATA "+std_logic_range(size_queue,max,min)+
                      " <= in_EXECUTE_QUEUE_IN_FLAGS;");
  min = max+1;

  size = _param->_size_exception;    
  max = min-1+size;
  vhdl->set_body   (0,"internal_QUEUE_INSERT_DATA "+std_logic_range(size_queue,max,min)+
                      " <= in_EXECUTE_QUEUE_IN_EXCEPTION;");
  min = max+1;

  size = 1;
  max = min-1+size;
  vhdl->set_body   (0,"internal_QUEUE_INSERT_DATA "+std_logic_range(size_queue,max,min)+
                      " <= in_EXECUTE_QUEUE_IN_NO_SEQUENCE;");
  min = max+1;

  size = _param->_size_instruction_address;
  max = min-1+size;
  vhdl->set_body   (0,"internal_QUEUE_INSERT_DATA "+std_logic_range(size_queue,max,min)+
                      " <= in_EXECUTE_QUEUE_IN_ADDRESS;");
  min = max+1;

  size = _param->_size_general_data;
  max = min-1+size;
  vhdl->set_body   (0,"internal_QUEUE_INSERT_DATA "+std_logic_range(size_queue,max,min)+
                      " <= in_EXECUTE_QUEUE_IN_DATA;");
  min = max+1;
  }

  vhdl->set_comment(0,"");
  vhdl->set_comment(0,"-----------------------------------");
  vhdl->set_comment(0,"-- Output Buffer                   ");
  vhdl->set_comment(0,"-----------------------------------");
  vhdl->set_comment(0,"");

  if(_param->_have_port_context_id)
  vhdl->set_body   (0,"out_EXECUTE_QUEUE_OUT_CONTEXT_ID   "+
                      " <= internal_EXECUTE_QUEUE_OUT_CONTEXT_ID   ;");
  if(_param->_have_port_front_end_id)
  vhdl->set_body   (0,"out_EXECUTE_QUEUE_OUT_FRONT_END_ID "+
                      " <= internal_EXECUTE_QUEUE_OUT_FRONT_END_ID ;");
  if(_param->_have_port_ooo_engine_id)
  vhdl->set_body   (0,"out_EXECUTE_QUEUE_OUT_OOO_ENGINE_ID"+
                      " <= internal_EXECUTE_QUEUE_OUT_OOO_ENGINE_ID;");
  if(_param->_have_port_rob_ptr)
  vhdl->set_body   (0,"out_EXECUTE_QUEUE_OUT_PACKET_ID    "+
                      " <= internal_EXECUTE_QUEUE_OUT_PACKET_ID    ;");
  vhdl->set_body   (0,"out_EXECUTE_QUEUE_OUT_FLAGS        "+
                      " <= internal_EXECUTE_QUEUE_OUT_FLAGS        ;");
  vhdl->set_body   (0,"out_EXECUTE_QUEUE_OUT_EXCEPTION    "+
                      " <= internal_EXECUTE_QUEUE_OUT_EXCEPTION    ;");
  vhdl->set_body   (0,"out_EXECUTE_QUEUE_OUT_NO_SEQUENCE  "+
                      " <= internal_EXECUTE_QUEUE_OUT_NO_SEQUENCE  ;");
  vhdl->set_body   (0,"out_EXECUTE_QUEUE_OUT_ADDRESS      "+
                      " <= internal_EXECUTE_QUEUE_OUT_ADDRESS      ;");
  vhdl->set_body   (0,"out_EXECUTE_QUEUE_OUT_DATA         "+
                      " <= internal_EXECUTE_QUEUE_OUT_DATA         ;");
};
\end{lstlisting}

\subsubSection{Fichier Execute\_queue.vhdl}

\lstparam{VHDL}
\begin{lstlisting}[caption={Execute\_queue.cpp}]
library ieee;
  use ieee.numeric_bit.all;       
  use ieee.numeric_std.all;       
  use ieee.std_logic_1164.all;    
  use ieee.std_logic_arith.all;   
  use ieee.std_logic_misc.all;    
--use ieee.std_logic_signed.all;  
  use ieee.std_logic_unsigned.all;
--use ieee.std_logic_textio.all;  

library work;
use work.Execute_queue_0_Pack.all;
use work.Execute_queue_0_queue_Pack.all;

entity Execute_queue_0 is
  port (
   in_CLOCK                           : in  std_logic;
   in_NRESET                          : in  std_logic;
   in_EXECUTE_QUEUE_IN_VAL            : in  std_logic;
  out_EXECUTE_QUEUE_IN_ACK            : out std_logic;
   in_EXECUTE_QUEUE_IN_CONTEXT_ID     : in  std_logic;
   in_EXECUTE_QUEUE_IN_FRONT_END_ID   : in  std_logic;
   in_EXECUTE_QUEUE_IN_OOO_ENGINE_ID  : in  std_logic;
   in_EXECUTE_QUEUE_IN_PACKET_ID      : in  std_logic_vector(5 downto 0);
   in_EXECUTE_QUEUE_IN_FLAGS          : in  std_logic_vector(1 downto 0);
   in_EXECUTE_QUEUE_IN_EXCEPTION      : in  std_logic_vector(4 downto 0);
   in_EXECUTE_QUEUE_IN_NO_SEQUENCE    : in  std_logic;
   in_EXECUTE_QUEUE_IN_ADDRESS        : in  std_logic_vector(31 downto 0);
   in_EXECUTE_QUEUE_IN_DATA           : in  std_logic_vector(31 downto 0);
  out_EXECUTE_QUEUE_OUT_VAL           : out std_logic;
   in_EXECUTE_QUEUE_OUT_ACK           : in  std_logic;
  out_EXECUTE_QUEUE_OUT_CONTEXT_ID    : out std_logic;
  out_EXECUTE_QUEUE_OUT_FRONT_END_ID  : out std_logic;
  out_EXECUTE_QUEUE_OUT_OOO_ENGINE_ID : out std_logic;
  out_EXECUTE_QUEUE_OUT_PACKET_ID     : out std_logic_vector(5 downto 0);
  out_EXECUTE_QUEUE_OUT_FLAGS         : out std_logic_vector(1 downto 0);
  out_EXECUTE_QUEUE_OUT_EXCEPTION     : out std_logic_vector(4 downto 0);
  out_EXECUTE_QUEUE_OUT_NO_SEQUENCE   : out std_logic;
  out_EXECUTE_QUEUE_OUT_ADDRESS       : out std_logic_vector(31 downto 0);
  out_EXECUTE_QUEUE_OUT_DATA          : out std_logic_vector(31 downto 0)
  );
end Execute_queue_0;

architecture behavioural of Execute_queue_0 is

  signal internal_QUEUE_INSERT_DATA              : std_logic_vector(80 downto 0);
  signal internal_QUEUE_RETIRE_DATA              : std_logic_vector(80 downto 0);

  alias internal_QUEUE_INSERT_VAL                : std_logic                     is
          in_EXECUTE_QUEUE_IN_VAL;
  alias internal_QUEUE_INSERT_ACK                : std_logic                     is
         out_EXECUTE_QUEUE_IN_ACK;
  alias internal_QUEUE_RETIRE_VAL                : std_logic                     is
        out_EXECUTE_QUEUE_OUT_VAL;
  alias internal_QUEUE_RETIRE_ACK                : std_logic                     is
         in_EXECUTE_QUEUE_OUT_ACK;
  alias internal_EXECUTE_QUEUE_OUT_CONTEXT_ID    : std_logic                     is
        internal_QUEUE_RETIRE_DATA   (0);
  alias internal_EXECUTE_QUEUE_OUT_FRONT_END_ID  : std_logic                     is
        internal_QUEUE_RETIRE_DATA   (1);
  alias internal_EXECUTE_QUEUE_OUT_OOO_ENGINE_ID : std_logic                     is
        internal_QUEUE_RETIRE_DATA   (2);
  alias internal_EXECUTE_QUEUE_OUT_PACKET_ID     : std_logic_vector(5 downto 0)  is
        internal_QUEUE_RETIRE_DATA   (8 downto 3);
  alias internal_EXECUTE_QUEUE_OUT_FLAGS         : std_logic_vector(1 downto 0)  is
        internal_QUEUE_RETIRE_DATA   (10 downto 9);
  alias internal_EXECUTE_QUEUE_OUT_EXCEPTION     : std_logic_vector(4 downto 0)  is
        internal_QUEUE_RETIRE_DATA   (15 downto 11);
  alias internal_EXECUTE_QUEUE_OUT_NO_SEQUENCE   : std_logic                     is
        internal_QUEUE_RETIRE_DATA   (16);
  alias internal_EXECUTE_QUEUE_OUT_ADDRESS       : std_logic_vector(31 downto 0) is
        internal_QUEUE_RETIRE_DATA   (48 downto 17);
  alias internal_EXECUTE_QUEUE_OUT_DATA          : std_logic_vector(31 downto 0) is
        internal_QUEUE_RETIRE_DATA   (80 downto 49);

begin
  -- 
  -- -----------------------------------
  -- -- Instance queue                  
  -- -----------------------------------
  -- 
  instance_Execute_queue_0_queue : Execute_queue_0_queue
  port map (
            in_CLOCK              =>            in_CLOCK 
          , in_NRESET             =>            in_NRESET
          , in_INSERT_VAL         =>      internal_QUEUE_INSERT_VAL
          ,out_INSERT_ACK         =>      internal_QUEUE_INSERT_ACK
          , in_INSERT_DATA        =>      internal_QUEUE_INSERT_DATA
          ,out_RETIRE_VAL         =>      internal_QUEUE_RETIRE_VAL
          , in_RETIRE_ACK         =>      internal_QUEUE_RETIRE_ACK
          ,out_RETIRE_DATA        =>      internal_QUEUE_RETIRE_DATA
  );
  -- 
  -- -----------------------------------
  -- -- Input  Buffer                   
  -- -----------------------------------
  -- 
  internal_QUEUE_INSERT_DATA (0)            <= in_EXECUTE_QUEUE_IN_CONTEXT_ID;
  internal_QUEUE_INSERT_DATA (1)            <= in_EXECUTE_QUEUE_IN_FRONT_END_ID;
  internal_QUEUE_INSERT_DATA (2)            <= in_EXECUTE_QUEUE_IN_OOO_ENGINE_ID;
  internal_QUEUE_INSERT_DATA (8 downto 3)   <= in_EXECUTE_QUEUE_IN_PACKET_ID;
  internal_QUEUE_INSERT_DATA (10 downto 9)  <= in_EXECUTE_QUEUE_IN_FLAGS;
  internal_QUEUE_INSERT_DATA (15 downto 11) <= in_EXECUTE_QUEUE_IN_EXCEPTION;
  internal_QUEUE_INSERT_DATA (16)           <= in_EXECUTE_QUEUE_IN_NO_SEQUENCE;
  internal_QUEUE_INSERT_DATA (48 downto 17) <= in_EXECUTE_QUEUE_IN_ADDRESS;
  internal_QUEUE_INSERT_DATA (80 downto 49) <= in_EXECUTE_QUEUE_IN_DATA;
  -- 
  -- -----------------------------------
  -- -- Output Buffer                   
  -- -----------------------------------
  -- 
  out_EXECUTE_QUEUE_OUT_CONTEXT_ID    <= internal_EXECUTE_QUEUE_OUT_CONTEXT_ID;
  out_EXECUTE_QUEUE_OUT_FRONT_END_ID  <= internal_EXECUTE_QUEUE_OUT_FRONT_END_ID;
  out_EXECUTE_QUEUE_OUT_OOO_ENGINE_ID <= internal_EXECUTE_QUEUE_OUT_OOO_ENGINE_ID;
  out_EXECUTE_QUEUE_OUT_PACKET_ID     <= internal_EXECUTE_QUEUE_OUT_PACKET_ID;
  out_EXECUTE_QUEUE_OUT_FLAGS         <= internal_EXECUTE_QUEUE_OUT_FLAGS;
  out_EXECUTE_QUEUE_OUT_EXCEPTION     <= internal_EXECUTE_QUEUE_OUT_EXCEPTION;
  out_EXECUTE_QUEUE_OUT_NO_SEQUENCE   <= internal_EXECUTE_QUEUE_OUT_NO_SEQUENCE;
  out_EXECUTE_QUEUE_OUT_ADDRESS       <= internal_EXECUTE_QUEUE_OUT_ADDRESS;
  out_EXECUTE_QUEUE_OUT_DATA          <= internal_EXECUTE_QUEUE_OUT_DATA;

end behavioural;
\end{lstlisting}


\Section {Test du VHDL}\label{testbench}

Lors d'une simulation systemC, \cpu va générer des fichiers de tests pour le modèle VHDL de chaque composant interne.
Ces tests sont tous écrit de la même façon. Soit l'interface X et le signal Y :
\begin{itemize}
\item Une variable {\it counter} indique le numéro de cycle courant. Elle est initialisé à 0. Elle est incrémenté à chaque cycle.
\item Le composant est instancé avec des signaux internes de même nom.
\item Pour chaque cycle, on affecte à chaque entrée la valeur obtenu lors de la simulation systemC.
\item Pour chaque sortie, on définit un signal dont le nom est {\it out\_X\_Y\_test}. Ces signaux sont affecté au valeur obtenu des sorties lors la simulation systemC.
\item Le signal {\it interface\_X\_test\_ok} est égal à 1 si chaque sortie calculé par la simulation VHDL est égal au sortie attendu (calculé par la simulation systemC).
\item Le signal {\it interface\_X\_test\_transaction} est à 1 si tous les signaux de validité et d'aquittement sont à 1.
\item Le signal {\it interface\_X\_test\_tmp} est à 1 si la simulation systemC indique qu'il y a une transaction et que la simulation vhdl indique également une transaction et que toute les sortie sont bien les sorties obtenu. Si la simulation systemC n'indique pas de transaction, on vérifie que c'est également le cas pour la simulation VHDL.
\item Le signal {\it interface\_X\_test} est égal au signal {\it interface\_X\_test\_tmp} quand il n'y a pas de reset. sinon il est positionné à 1.
\item Le signal {\it test} est un et logique entre tout tous les signaux {\it interface\_X\_test}.
\item La simulation VHDL ce termine si le signal {\it test} vaut 0 (dans ce cas, le test est un échec), ou que le registre {\it counter} vaut le nombre de cycle requis par la simulation systemC (dans ce cas, le test est un succès).
\end{itemize}

Nous pouvons remarquer que :
\begin{itemize}
\item Nous vérifions la compatibilité au cycle des transactions entre le modèle systemC et le modèle VHDL.
\item Nous vérifions la compatibilité au bit près des données échangé lors qu'il y a une transaction sur une interface.
\item Nous ne vérifions pas la compatibilité au bit près des données présente sur une interface qui ne fait pas de transaction lors d'un cycle.
\end{itemize}

\lstparam{VHDL}
\begin{lstlisting}[caption={Execute\_queue\_Testbench.vhdl}]
library ieee;
  use ieee.numeric_bit.all;       
  use ieee.numeric_std.all;       
  use ieee.std_logic_1164.all;    
  use ieee.std_logic_arith.all;   
  use ieee.std_logic_misc.all;    
--use ieee.std_logic_signed.all;  
  use ieee.std_logic_unsigned.all;
--use ieee.std_logic_textio.all;  

library work;
use work.Execute_queue_0_Pack.all;

entity Execute_queue_0_Testbench is
end Execute_queue_0_Testbench;

architecture behavioural of Execute_queue_0_Testbench is

  signal  in_CLOCK                              : std_logic := '0';
  signal  in_NRESET                             : std_logic := '0';
  signal  in_EXECUTE_QUEUE_IN_VAL               : std_logic;
  signal out_EXECUTE_QUEUE_IN_ACK               : std_logic;
  signal out_EXECUTE_QUEUE_IN_ACK_test          : std_logic;
  signal  in_EXECUTE_QUEUE_IN_PACKET_ID         : std_logic_vector(3 downto 0);
  signal  in_EXECUTE_QUEUE_IN_FLAGS             : std_logic_vector(1 downto 0);
  signal  in_EXECUTE_QUEUE_IN_EXCEPTION         : std_logic_vector(4 downto 0);
  signal  in_EXECUTE_QUEUE_IN_NO_SEQUENCE       : std_logic;
  signal  in_EXECUTE_QUEUE_IN_ADDRESS           : std_logic_vector(31 downto 0);
  signal  in_EXECUTE_QUEUE_IN_DATA              : std_logic_vector(31 downto 0);
  signal out_EXECUTE_QUEUE_OUT_VAL              : std_logic;
  signal out_EXECUTE_QUEUE_OUT_VAL_test         : std_logic;
  signal  in_EXECUTE_QUEUE_OUT_ACK              : std_logic;
  signal out_EXECUTE_QUEUE_OUT_PACKET_ID        : std_logic_vector(3 downto 0);
  signal out_EXECUTE_QUEUE_OUT_PACKET_ID_test   : std_logic_vector(3 downto 0);
  signal out_EXECUTE_QUEUE_OUT_FLAGS            : std_logic_vector(1 downto 0);
  signal out_EXECUTE_QUEUE_OUT_FLAGS_test       : std_logic_vector(1 downto 0);
  signal out_EXECUTE_QUEUE_OUT_EXCEPTION        : std_logic_vector(4 downto 0);
  signal out_EXECUTE_QUEUE_OUT_EXCEPTION_test   : std_logic_vector(4 downto 0);
  signal out_EXECUTE_QUEUE_OUT_NO_SEQUENCE      : std_logic;
  signal out_EXECUTE_QUEUE_OUT_NO_SEQUENCE_test : std_logic;
  signal out_EXECUTE_QUEUE_OUT_ADDRESS          : std_logic_vector(31 downto 0);
  signal out_EXECUTE_QUEUE_OUT_ADDRESS_test     : std_logic_vector(31 downto 0);
  signal out_EXECUTE_QUEUE_OUT_DATA             : std_logic_vector(31 downto 0);
  signal out_EXECUTE_QUEUE_OUT_DATA_test        : std_logic_vector(31 downto 0);

  signal counter                                      : natural;
  signal test                                         : std_logic;
  signal interface_test                               : std_logic;
  signal interface_test_ok                            : std_logic;
  signal interface_execute_queue_in_test              : std_logic;
  signal interface_execute_queue_in_test_ok           : std_logic;
  signal interface_execute_queue_in_test_transaction  : std_logic;
  signal interface_execute_queue_in_test_tmp          : std_logic;
  signal interface_execute_queue_out_test             : std_logic;
  signal interface_execute_queue_out_test_ok          : std_logic;
  signal interface_execute_queue_out_test_transaction : std_logic;
  signal interface_execute_queue_out_test_tmp         : std_logic;

begin
  
  ------------------------------------------------------
  -- Component - Intanciation
  ------------------------------------------------------
  
  instance_Execute_queue_0 : Execute_queue_0
  port map (
      in_CLOCK                         =>  in_CLOCK
    , in_NRESET                        =>  in_NRESET
    , in_EXECUTE_QUEUE_IN_VAL          =>  in_EXECUTE_QUEUE_IN_VAL
    ,out_EXECUTE_QUEUE_IN_ACK          => out_EXECUTE_QUEUE_IN_ACK
    , in_EXECUTE_QUEUE_IN_PACKET_ID    =>  in_EXECUTE_QUEUE_IN_PACKET_ID
    , in_EXECUTE_QUEUE_IN_FLAGS        =>  in_EXECUTE_QUEUE_IN_FLAGS
    , in_EXECUTE_QUEUE_IN_EXCEPTION    =>  in_EXECUTE_QUEUE_IN_EXCEPTION
    , in_EXECUTE_QUEUE_IN_NO_SEQUENCE  =>  in_EXECUTE_QUEUE_IN_NO_SEQUENCE
    , in_EXECUTE_QUEUE_IN_ADDRESS      =>  in_EXECUTE_QUEUE_IN_ADDRESS
    , in_EXECUTE_QUEUE_IN_DATA         =>  in_EXECUTE_QUEUE_IN_DATA
    ,out_EXECUTE_QUEUE_OUT_VAL         => out_EXECUTE_QUEUE_OUT_VAL
    , in_EXECUTE_QUEUE_OUT_ACK         =>  in_EXECUTE_QUEUE_OUT_ACK
    ,out_EXECUTE_QUEUE_OUT_PACKET_ID   => out_EXECUTE_QUEUE_OUT_PACKET_ID
    ,out_EXECUTE_QUEUE_OUT_FLAGS       => out_EXECUTE_QUEUE_OUT_FLAGS
    ,out_EXECUTE_QUEUE_OUT_EXCEPTION   => out_EXECUTE_QUEUE_OUT_EXCEPTION
    ,out_EXECUTE_QUEUE_OUT_NO_SEQUENCE => out_EXECUTE_QUEUE_OUT_NO_SEQUENCE
    ,out_EXECUTE_QUEUE_OUT_ADDRESS     => out_EXECUTE_QUEUE_OUT_ADDRESS
    ,out_EXECUTE_QUEUE_OUT_DATA        => out_EXECUTE_QUEUE_OUT_DATA
     );
  ------------------------------------------------------
  -- interface ""
  ------------------------------------------------------
  
  -- Test exhaustive
  
  interface_test_ok <= '1' when true
    else '0';
  
  interface_test <= '1' when (in_NRESET = '0') else interface_test_ok;
  ------------------------------------------------------
  -- interface "execute_queue_in"
  ------------------------------------------------------
  
  with counter select
    in_EXECUTE_QUEUE_IN_VAL <=
    '0' when 0,
    '0' when 1,
    '0' when 2,
    '0' when 3,
    '0' when 4,
    '1' when 5,
    '1' when 6,
    '0' when 7,
    '0' when 8,
    '1' when 9,
    '1' when 10,
    '1' when 11,
    '1' when 12,
    '1' when 13,
    '1' when 14,
    '1' when 15,
    '1' when 16,
    '0' when 17,
    '1' when 18,
    '1' when 19,
    '1' when 20,
    '0' when 21,
    '1' when 22,
    '1' when 23,
    '0' when 24,
    '1' when 25,
    '0' when 26,
    '0' when others;
  
  with counter select
    out_EXECUTE_QUEUE_IN_ACK_test <=
    '0' when 0,
    '1' when 1,
    '1' when 2,
    '1' when 3,
    '1' when 4,
    '1' when 5,
    '1' when 6,
    '1' when 7,
    '1' when 8,
    '1' when 9,
    '1' when 10,
    '1' when 11,
    '1' when 12,
    '1' when 13,
    '1' when 14,
    '1' when 15,
    '1' when 16,
    '1' when 17,
    '1' when 18,
    '1' when 19,
    '1' when 20,
    '1' when 21,
    '1' when 22,
    '1' when 23,
    '1' when 24,
    '1' when 25,
    '1' when 26,
    '0' when others;
  
  with counter select
    in_EXECUTE_QUEUE_IN_PACKET_ID <=
    "0000" when 0,
    "0000" when 1,
    "0000" when 2,
    "0000" when 3,
    "0000" when 4,
    "0000" when 5,
    "0001" when 6,
    "0001" when 7,
    "0001" when 8,
    "0010" when 9,
    "0011" when 10,
    "0100" when 11,
    "0101" when 12,
    "0110" when 13,
    "0111" when 14,
    "1000" when 15,
    "1001" when 16,
    "1001" when 17,
    "1010" when 18,
    "1011" when 19,
    "1100" when 20,
    "1100" when 21,
    "1101" when 22,
    "1110" when 23,
    "1110" when 24,
    "1111" when 25,
    "1111" when 26,
    (others => '0') when others;
  
  with counter select
    in_EXECUTE_QUEUE_IN_FLAGS <=
    "00" when 0,
    "00" when 1,
    "00" when 2,
    "00" when 3,
    "00" when 4,
    "11" when 5,
    "11" when 6,
    "11" when 7,
    "11" when 8,
    "00" when 9,
    "11" when 10,
    "11" when 11,
    "11" when 12,
    "10" when 13,
    "01" when 14,
    "01" when 15,
    "11" when 16,
    "11" when 17,
    "10" when 18,
    "00" when 19,
    "11" when 20,
    "11" when 21,
    "10" when 22,
    "01" when 23,
    "01" when 24,
    "01" when 25,
    "01" when 26,
    (others => '0') when others;
  
  with counter select
    in_EXECUTE_QUEUE_IN_EXCEPTION <=
    "00000" when 0,
    "00000" when 1,
    "00000" when 2,
    "00000" when 3,
    "00000" when 4,
    "10001" when 5,
    "10010" when 6,
    "10010" when 7,
    "10010" when 8,
    "11011" when 9,
    "10011" when 10,
    "10001" when 11,
    "11000" when 12,
    "11011" when 13,
    "00001" when 14,
    "00001" when 15,
    "01010" when 16,
    "01010" when 17,
    "01100" when 18,
    "01100" when 19,
    "11011" when 20,
    "11011" when 21,
    "00101" when 22,
    "01001" when 23,
    "01001" when 24,
    "10001" when 25,
    "10001" when 26,
    (others => '0') when others;
  
  with counter select
    in_EXECUTE_QUEUE_IN_NO_SEQUENCE <=
    '0' when 0,
    '0' when 1,
    '0' when 2,
    '0' when 3,
    '0' when 4,
    '1' when 5,
    '1' when 6,
    '1' when 7,
    '1' when 8,
    '1' when 9,
    '1' when 10,
    '1' when 11,
    '1' when 12,
    '1' when 13,
    '1' when 14,
    '1' when 15,
    '1' when 16,
    '1' when 17,
    '1' when 18,
    '1' when 19,
    '1' when 20,
    '1' when 21,
    '1' when 22,
    '1' when 23,
    '1' when 24,
    '1' when 25,
    '1' when 26,
    '0' when others;
  
  with counter select
    in_EXECUTE_QUEUE_IN_ADDRESS <=
    "00000000000000000000000000000000" when 0,
    "00000000000000000000000000000000" when 1,
    "00000000000000000000000000000000" when 2,
    "00000000000000000000000000000000" when 3,
    "00000000000000000000000000000000" when 4,
    "00101010111010001001010001001010" when 5,
    "01111001111000101010100111100011" when 6,
    "01111001111000101010100111100011" when 7,
    "01111001111000101010100111100011" when 8,
    "00010001100100001100110111100111" when 9,
    "01000001101001111100010011001001" when 10,
    "00100101011100010011000010100011" when 11,
    "01100111011000111000010001011110" when 12,
    "01110001111100110010010001010100" when 13,
    "01110011011110111000110111011100" when 14,
    "01000100000010111010110111111100" when 15,
    "01010001111010101101001101101011" when 16,
    "01010001111010101101001101101011" when 17,
    "00011101010011101101010000111011" when 18,
    "00111000010000110111111111011011" when 19,
    "01111001101000011101111010101010" when 20,
    "01111001101000011101111010101010" when 21,
    "01100100100110111011011101111100" when 22,
    "00010101101101011010111101011100" when 23,
    "00010101101101011010111101011100" when 24,
    "01010111100110111110010011110001" when 25,
    "01010111100110111110010011110001" when 26,
    (others => '0') when others;
  
  with counter select
    in_EXECUTE_QUEUE_IN_DATA <=
    "00000000000000000000000000000000" when 0,
    "00000000000000000000000000000000" when 1,
    "00000000000000000000000000000000" when 2,
    "00000000000000000000000000000000" when 3,
    "00000000000000000000000000000000" when 4,
    "01100010010101010101100011101100" when 5,
    "01110101010001011110000101000110" when 6,
    "01110101010001011110000101000110" when 7,
    "01110101010001011110000101000110" when 8,
    "01100110111011110100001110001101" when 9,
    "01101011011010000000011110011010" when 10,
    "01100010101110111101100101011010" when 11,
    "01110101101000101010100011010100" when 12,
    "00101100101010001000011000010001" when 13,
    "01101100111010101111000010000111" when 14,
    "00000101000001110010001101100111" when 15,
    "00101101010100010111011110010110" when 16,
    "00101101010100010111011110010110" when 17,
    "01110010010110100000011011111011" when 18,
    "01110110010001001010010001011100" when 19,
    "01110101110001101100001100111010" when 20,
    "01110101110001101100001100111010" when 21,
    "00100111010110101100011110010100" when 22,
    "01110100000100100010011010111011" when 23,
    "01110100000100100010011010111011" when 24,
    "00110001000011000101000010110011" when 25,
    "00110001000011000101000010110011" when 26,
    (others => '0') when others;
  
  -- Test partial
  
  interface_execute_queue_in_test_ok <= '1' when true
    and out_EXECUTE_QUEUE_IN_ACK = out_EXECUTE_QUEUE_IN_ACK_test
    else '0';
  
  interface_execute_queue_in_test_transaction <= '1'
    and in_EXECUTE_QUEUE_IN_VAL
    and out_EXECUTE_QUEUE_IN_ACK
    ;
  
  with counter select
    interface_execute_queue_in_test_tmp <=
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 5,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 6,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 9,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 10,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 11,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 12,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 13,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 14,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 15,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 16,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 18,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 19,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 20,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 22,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 23,
    interface_execute_queue_in_test_transaction and interface_execute_queue_in_test_ok 
      when 25,
    not interface_execute_queue_in_test_transaction when others;
  
  interface_execute_queue_in_test <= '1' when (in_NRESET = '0') else
                                     interface_execute_queue_in_test_tmp;
  ------------------------------------------------------
  -- interface "execute_queue_out"
  ------------------------------------------------------
  
  with counter select
    out_EXECUTE_QUEUE_OUT_VAL_test <=
    '0' when 0,
    '0' when 1,
    '0' when 2,
    '0' when 3,
    '0' when 4,
    '0' when 5,
    '1' when 6,
    '1' when 7,
    '0' when 8,
    '0' when 9,
    '1' when 10,
    '1' when 11,
    '1' when 12,
    '1' when 13,
    '1' when 14,
    '1' when 15,
    '1' when 16,
    '1' when 17,
    '0' when 18,
    '1' when 19,
    '1' when 20,
    '1' when 21,
    '1' when 22,
    '1' when 23,
    '1' when 24,
    '0' when 25,
    '1' when 26,
    '0' when others;
  
  with counter select
    in_EXECUTE_QUEUE_OUT_ACK <=
    '0' when 0,
    '0' when 1,
    '0' when 2,
    '0' when 3,
    '0' when 4,
    '1' when 5,
    '1' when 6,
    '1' when 7,
    '1' when 8,
    '0' when 9,
    '1' when 10,
    '1' when 11,
    '1' when 12,
    '1' when 13,
    '1' when 14,
    '1' when 15,
    '1' when 16,
    '1' when 17,
    '1' when 18,
    '1' when 19,
    '1' when 20,
    '0' when 21,
    '1' when 22,
    '1' when 23,
    '1' when 24,
    '1' when 25,
    '1' when 26,
    '0' when others;
  
  with counter select
    out_EXECUTE_QUEUE_OUT_PACKET_ID_test <=
    "0000" when 0,
    "0000" when 1,
    "0000" when 2,
    "0000" when 3,
    "0000" when 4,
    "0000" when 5,
    "0000" when 6,
    "0001" when 7,
    "0001" when 8,
    "0001" when 9,
    "0010" when 10,
    "0011" when 11,
    "0100" when 12,
    "0101" when 13,
    "0110" when 14,
    "0111" when 15,
    "1000" when 16,
    "1001" when 17,
    "1001" when 18,
    "1010" when 19,
    "1011" when 20,
    "1100" when 21,
    "1100" when 22,
    "1101" when 23,
    "1110" when 24,
    "1110" when 25,
    "1111" when 26,
    (others => '0') when others;
  
  with counter select
    out_EXECUTE_QUEUE_OUT_FLAGS_test <=
    "00" when 0,
    "00" when 1,
    "00" when 2,
    "00" when 3,
    "00" when 4,
    "00" when 5,
    "11" when 6,
    "11" when 7,
    "11" when 8,
    "11" when 9,
    "00" when 10,
    "11" when 11,
    "11" when 12,
    "11" when 13,
    "10" when 14,
    "01" when 15,
    "01" when 16,
    "11" when 17,
    "11" when 18,
    "10" when 19,
    "00" when 20,
    "11" when 21,
    "11" when 22,
    "10" when 23,
    "01" when 24,
    "01" when 25,
    "01" when 26,
    (others => '0') when others;
  
  with counter select
    out_EXECUTE_QUEUE_OUT_EXCEPTION_test <=
    "00000" when 0,
    "00000" when 1,
    "00000" when 2,
    "00000" when 3,
    "00000" when 4,
    "00000" when 5,
    "10001" when 6,
    "10010" when 7,
    "10010" when 8,
    "10010" when 9,
    "11011" when 10,
    "10011" when 11,
    "10001" when 12,
    "11000" when 13,
    "11011" when 14,
    "00001" when 15,
    "00001" when 16,
    "01010" when 17,
    "01010" when 18,
    "01100" when 19,
    "01100" when 20,
    "11011" when 21,
    "11011" when 22,
    "00101" when 23,
    "01001" when 24,
    "01001" when 25,
    "10001" when 26,
    (others => '0') when others;
  
  with counter select
    out_EXECUTE_QUEUE_OUT_NO_SEQUENCE_test <=
    '0' when 0,
    '0' when 1,
    '0' when 2,
    '0' when 3,
    '0' when 4,
    '0' when 5,
    '1' when 6,
    '1' when 7,
    '1' when 8,
    '1' when 9,
    '1' when 10,
    '1' when 11,
    '1' when 12,
    '1' when 13,
    '1' when 14,
    '1' when 15,
    '1' when 16,
    '1' when 17,
    '1' when 18,
    '1' when 19,
    '1' when 20,
    '1' when 21,
    '1' when 22,
    '1' when 23,
    '1' when 24,
    '1' when 25,
    '1' when 26,
    '0' when others;
  
  with counter select
    out_EXECUTE_QUEUE_OUT_ADDRESS_test <=
    "00000000000000000000000000000000" when 0,
    "00000000000000000000000000000000" when 1,
    "00000000000000000000000000000000" when 2,
    "00000000000000000000000000000000" when 3,
    "00000000000000000000000000000000" when 4,
    "00000000000000000000000000000000" when 5,
    "00101010111010001001010001001010" when 6,
    "01111001111000101010100111100011" when 7,
    "01111001111000101010100111100011" when 8,
    "01111001111000101010100111100011" when 9,
    "00010001100100001100110111100111" when 10,
    "01000001101001111100010011001001" when 11,
    "00100101011100010011000010100011" when 12,
    "01100111011000111000010001011110" when 13,
    "01110001111100110010010001010100" when 14,
    "01110011011110111000110111011100" when 15,
    "01000100000010111010110111111100" when 16,
    "01010001111010101101001101101011" when 17,
    "01010001111010101101001101101011" when 18,
    "00011101010011101101010000111011" when 19,
    "00111000010000110111111111011011" when 20,
    "01111001101000011101111010101010" when 21,
    "01111001101000011101111010101010" when 22,
    "01100100100110111011011101111100" when 23,
    "00010101101101011010111101011100" when 24,
    "00010101101101011010111101011100" when 25,
    "01010111100110111110010011110001" when 26,
    (others => '0') when others;
  
  with counter select
    out_EXECUTE_QUEUE_OUT_DATA_test <=
    "00000000000000000000000000000000" when 0,
    "00000000000000000000000000000000" when 1,
    "00000000000000000000000000000000" when 2,
    "00000000000000000000000000000000" when 3,
    "00000000000000000000000000000000" when 4,
    "00000000000000000000000000000000" when 5,
    "01100010010101010101100011101100" when 6,
    "01110101010001011110000101000110" when 7,
    "01110101010001011110000101000110" when 8,
    "01110101010001011110000101000110" when 9,
    "01100110111011110100001110001101" when 10,
    "01101011011010000000011110011010" when 11,
    "01100010101110111101100101011010" when 12,
    "01110101101000101010100011010100" when 13,
    "00101100101010001000011000010001" when 14,
    "01101100111010101111000010000111" when 15,
    "00000101000001110010001101100111" when 16,
    "00101101010100010111011110010110" when 17,
    "00101101010100010111011110010110" when 18,
    "01110010010110100000011011111011" when 19,
    "01110110010001001010010001011100" when 20,
    "01110101110001101100001100111010" when 21,
    "01110101110001101100001100111010" when 22,
    "00100111010110101100011110010100" when 23,
    "01110100000100100010011010111011" when 24,
    "01110100000100100010011010111011" when 25,
    "00110001000011000101000010110011" when 26,
    (others => '0') when others;
  
  -- Test partial
  
  interface_execute_queue_out_test_ok <= '1' when true
    and out_EXECUTE_QUEUE_OUT_VAL = out_EXECUTE_QUEUE_OUT_VAL_test
    and out_EXECUTE_QUEUE_OUT_PACKET_ID = out_EXECUTE_QUEUE_OUT_PACKET_ID_test
    and out_EXECUTE_QUEUE_OUT_FLAGS = out_EXECUTE_QUEUE_OUT_FLAGS_test
    and out_EXECUTE_QUEUE_OUT_EXCEPTION = out_EXECUTE_QUEUE_OUT_EXCEPTION_test
    and out_EXECUTE_QUEUE_OUT_NO_SEQUENCE = out_EXECUTE_QUEUE_OUT_NO_SEQUENCE_test
    and out_EXECUTE_QUEUE_OUT_ADDRESS = out_EXECUTE_QUEUE_OUT_ADDRESS_test
    and out_EXECUTE_QUEUE_OUT_DATA = out_EXECUTE_QUEUE_OUT_DATA_test
    else '0';
  
  interface_execute_queue_out_test_transaction <= '1'
    and out_EXECUTE_QUEUE_OUT_VAL
    and in_EXECUTE_QUEUE_OUT_ACK
    ;
  
  with counter select
    interface_execute_queue_out_test_tmp <=
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 6,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 7,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 10,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 11,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 12,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 13,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 14,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 15,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 16,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 17,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 19,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 20,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 22,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 23,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 24,
    interface_execute_queue_out_test_transaction and interface_execute_queue_out_test_ok 
      when 26,
    not interface_execute_queue_out_test_transaction when others;
  
  interface_execute_queue_out_test <= '1' when (in_NRESET = '0') else
                                      interface_execute_queue_out_test_tmp;
  
  ------------------------------------------------------
  -- Test
  ------------------------------------------------------
  
  test <= '1' 
           and interface_test
           and interface_execute_queue_in_test
           and interface_execute_queue_out_test;
  
  ------------------------------------------------------
  -- reset
  ------------------------------------------------------
  
  -- if the systemC simulate have multiple reset, we make the last
  in_NRESET <= '1' after 150 ns;
  
  ------------------------------------------------------
  -- process clock_name
  ------------------------------------------------------
  
  in_CLOCK <= not in_CLOCK after 50 ns;
  
  process (in_CLOCK)
  begin
    if (in_CLOCK'event and in_CLOCK = '1') then
  
      if (in_NRESET = '0') then
        counter <= 4;
      else
        counter <= counter+1;

        assert not (counter >= 27) report "Test OK" severity FAILURE;
        assert not (test = '0') report "Test KO" severity FAILURE;
      end if;
    end if;
  end process;
end behavioural;
\end{lstlisting}
