Synthèse d'architectures

Les diapos du cours

Introduction

La synthèse d'architectures est un vieux rêve de concepteurs. Plutôt que de décrire au cycle prêt, au bit prêt et au registre prêt (synthèse RTL) le comportement de l'architecture matérielle désirée, on aimerait décrire :

  1. un algorithme de traitement à exécuter
  2. des contraintes de vitesse (fréquence d'horloge)
  3. des contraintes de latence (délai maximum, en nombre de cycles) entre la demande d'un traitement et le résultat 
  4. des contraintes de débit (nombre de traitementspar seconde)

Un outil de synthèse se chargerait alors de générer l'architecture adaptée.  

Les premiers outils proposés en ce sens datent de plus d'une vingtaine d'années; le terme consacré à ces outils est "HLS" pour "High Level Synthesis".

Les voies explorées sont assez diverses et l'adoption de ces outils dans les méthodologies de design de SoC n'est pas encore totalement évidente. Différents obstacles subsistent parmi lesquels:

  • Le choix du langage d'entrée (C, C++, SystemC, VHDL, Verilog)
  • La culture "langages" du public adressé: informaticiens (avec une faible culture d'architecture matérielle), électroniciens (avec une faible culture des langages de "haut niveau")
  • L'absence de normalisation de ce qu'est une représentation de haut niveau d'un système matériel.
  • L'usage quasi obligatoire  de "pragmas" de synthèse permettant de guider l'outil vers une solution "raisonnable". Ces pragmas utilisant un vocabulaire riche et malheureusement spécifique à chaque outil.

En clair, autant il est facile pour un concepteur de basculer d'un outil de synthèse RTL à un autre outil, autant chaque outil de synthèse HLS a ses propres particularités, ses propres limitations qui nécessitent un apprentissage ad-hoc. Le temps nécessaire à une bonne maîtrise de ces outils est perçu comme un obstacle par les concepteurs. Cependant, il n'est pas douteux qu'une fois maîtrisés,ces outils permettent de coder très rapidement les blocs hardwares spécifiques nécessaires à la conception d'un SoC.

Enfin, une autre difficulté de l'introduction de ces outils, est l'absence de tutoriels décrivants des cas réellement complexes.

Un exemple typique est un tutoriel présentant la réalisation d'un filtre à réponse inpulsionnelle finie: en clair, il faut recevoir des échantillons, faire des multiplications/accumulations et renvoyer des échantillons. Ce type de code s'écrit très rapidement en VHDL/Verilog RTL, le débutant en synthèse HLS ne voit pas trop l'intéret de se prendre la tête a trouver la meilleur façon de placer des pragmas de synthèse pour dérouler proprement les boucles de calcul et générer le parallélisme nécessaire. 

Un autre exemple est le calcul d'une DCT (Discrete Cosinus Transform): on est encore dans le cas de multiplications/accumulations. Faut-il encore passer du temps à trouver la bonne combinaison d'options de synthèse (pipeline, déroulement de boucles, mémoires simple port, memoire double ports, registres) ou simplement récupérer une IP codée en dur de manière efficace ?

On insiste généralement dans les tutoriels, sur ces aspects liés aux chemins de données  (déroulement de boucle, parrallélisme et pipeline), alors que le véritable potentiel des outils de synthèse d'architecture est ailleurs. Il s'agit, en effet, de la synthèse du contrôle et de la communication vers le monde extérieur. En effet, si nous reprenons le cas de la DCT, le problème que se pose le concepteur n'est pas

  • "je veux réaliser une DCT"

mais

  • je veux réaliser une DCT qui communique avec le monde extérieur par un bus esclave de la norme XXX avec une largeur de bus de données de valeur YYY, alors que les données traitées par la DCT sont de largeur ZZZ.

Les outils de synthèse HLS doivent permettre de traiter ce genre de situation.

Quelques principes de la synthèse HLS

Les étapes principales de la synthèse HLS sont, partant d'une fonction de traitement décrite par exemple en langage "C":

  • La construction d'une représentation du traitement sous forme d'un graphe de flux de données (DFG  pour Data Flow Graph): on représente l'algorithme sous la forme d'une succession d'opérations de base dans lesquelles les dépendances sont clairement exprimées.
  • L'allocation de ressources: à chaque opération élémentaire on associe une ressource matérielle, comme par exemple un additionneur 8bits.
  • L' ordonnancement: il s'agit d'assigner à chaque opération le cycle d'horloge pendant lequel elle devra être effectuée, ce qui par ailleurs détermine un graphe de flux de contrôle (CFG  pour Control Flow Graph) ; on connait alors une succession d'états de l'algorithme.

Les fameux pragmas de synthèse viennent modifier ces opérations pour permettre de respecter les contraintes voulues: faut-il ou non dérouler des boucles ?  faut-il ou non partager des opérateurs ? ....

Vous trouverez sur ce lien   un livre de référence sur la synthèse HLS. Les principes exposés précédemment sont décrits dans le chapitre 4.

Première Etape: Etudions un exemple de synthèse CTos.

L'objectif est de vous familiariser avec le vocabulaire, les structures, les scripts...

  • Vous trouverez une archive de travail  ici
  • Ce projet correspond à l'exemple décrit en détail dans le manuel d'utilisateur de CtoS au chapitre 15.2.6. 
  • Vous trouverez le manuel utilisateur ici
  1. Lisez attentivement, le chapitre 15.2.6 expliquant le code. Posez toutes les questions nécessaires à votre compréhension.
  2. Une fois l'archive installée, examinez la structure des répertoires.

Ctos propose systématiquement une structure comportant:

  1. Un testbench (répertoire tb) qui vérifie que le "device under test" génère bien les bonnes valeurs.
  2. Les sources du module à synthétiser (répertoire src). 
  3. Un script "ctos.tcl" qui lancera toutes les étapes de la synthèse:
    1. Configuration du design
    2. Mise en place des directives de synthèse
    3. Synthèse HLS proprement dite
    4. Création d'un sous-répertoire destiné à la synthèse du code RTL généré, avec son Makefile

Retrouvez dans les sources SystemC, et dans les scripts, les exemples de codes ou de directives telles qu'indiquées dans le manuel.​

  1. Enfin, un Makefile utilisé essentiellement pour simuler le design aux différentes étapes:
    1. make tlm_sim pour simuler en utilisant les FlexChannel au niveau TLM.
    2. make orig_sim pour simuler en utilisant les FLexChannel au niveau structurel.
    3. make rtl_sim pour simuler le design synthétisé au niveau RTL

Le fichier Makefile est bien commenté, vous pouvez demander, par exemple à réaliser une simulation interactive pour visualiser les signaux (SIM_GUI=1 make....)

Après avoir silmulé le design original, lancez la synthèse: ctos ctos.tcl

  1. C'est un peu longuet, examinez bien les logs générés et tentez de retrouver les différentes étapes de la synthèse
  2. Cherchez dans les logs, l'instant où ne pouvant pas faire tenir le design dans les timings voulus, le synthétiseur décide de modifier le niveau de pipeline.

Le synthétiseur a généré un code RTL pour circuit ASIC dans une technologie "de démo". Il est possible de lancer la synthèse RTL pour vérifier que le code généré respecte bien les contraintes de timing. Pour cela:

  1. Mettez en place la variable d'environnement suivante :  export LM_LICENSE_FILE='30000@licences.cnfm.fr'
  2. Exécutez make synth_gates
  3. C'est long...
  4. Puis rentrez dans le répertoire '"run_synth_gates" : vous y trouverez une netlist à base de portes logiques, ainsi que des fichiers de logs divers permettant de vérifier la qualité des résultats obtenus.

Deuxième Etape: Le TP AXI DMA 

Il s'agit de reprendre le TP que vous avez déjà réalisé, en utilisant un codage en SystemC, et la synthèse HLS CtoS.  Le projet se fera en plusieurs étapes:

  • Codage d'un DMA simple en code quasi "cycle accurate" (pas d'exploitation de pragmas de synthèse visant à améliorer les performances du dispositif).  Pour cela nous imposerons le style de codage suivant:
    • Utilisation des FlexChannel Ctos pour modéliser l'interface Axi
    • Séparation claire entre la partie Interface Axi et  la partie application pour obtenir un code facilement modifiable en cas de changement de protocole. Nous vous donnerons pour cela des squelettes de code que vous devrez compléter.
  • Intégration d'un coeur crypto DES dans le bloc DMA. Nous vous fournissons pour cela un code C, que vous devrez adapter à l'utilisation dans le cadre du code SystemC. On utilisera les directives de synthèse CtoS pour guider la synthèse vers un objectif de performance donné.

Le dépôt des sources du projet, ainsi que les explications se trouvent ici: git@gitlab.enst.fr:se303/TP_SYNTHESE_ARCHI.git

Mettez à jour votre dépôt personnel en récupérant la hiérarchie nécessaire:

git subtree add --prefix hls_dma git@gitlab.enst.fr:se303/TP_SYNTHESE_ARCHI.git master --squash

Puis suivez les consignes...

 

Fichier attachéTaille
PDF icon cadence_ctos_user_guide.pdf14.42 Mo
PDF icon se303_lhls_handout.pdf1.36 Mo