%------------------------------------------------------------------------------
% $Id: document-morpheo-vhdl_generation-fr-02_vhdl_declaration.tex 100 2009-01-08 13:06:27Z rosiere $
%------------------------------------------------------------------------------

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

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

\subSection{Interfaces}
L'interface est définie dans le modèle SystemC. Il n'est 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 composant (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 tous 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 fait 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).
Toutes les fonctions préfixées par un underscore n'effectuent 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 complexes, 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ésentant 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 à plein un soit à plein zéro.

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

Pour toutes 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éfinis grâce à la 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ée si le signal a 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 un champ d'un signal. Ceci se 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 renommé. Les deux derniers concernés le signal à renommé : le nom de ce dernier ainsi que l'intervalle. Pour le dernier paramètre, il est recommandé d'utiliser 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}
