ELEC390 : Initiation à SystemC

Objectifs du cours

Ce cours a pour but de vous présenter en une semaine les fondamentaux de SystemC. Sans faire de vous des spécialistes de ce "langage", vous en aurez acquis à l'issue de la semaine une bonne vision d'ensemble.

Le cours se décompose en deux phases :

  1. une phase d'apprentissage du langage, répartie sur 3 jours. Durant cette phase, vous apprendrez ce qu'est un HDL, les principes de la simulation par événement (qui sous-tendent les langages de description du matériel), et SystemC.
  2. une phase de mise en pratique, sous forme d'un mini-projet.

SystemC : le langage

Plutôt que vous faire un cours magistral, généralement rébarbatif et dont vous ne retiendrez pas grand chose, le cours se passe en ligne sous forme d'auto-apprentissage. Vous apprenez à votre rythme, sous le contrôle d'un enseignant qui est là pour répondre à vos questions.
Attention : même si ce cours est en auto-apprentissage, il est de votre responsabilité de poser à l'enseignant toutes les questions qui vous posent problème !!!

Tout au long du cours, vous aurez des exercices à faire pour vérifier que les notions principales ont bien été acquises. Ces exercices sont à rendre (sauf mention contraire) en passant par votre dépôt git.

Rappels

  • Configuration initiale
      git config --global user.name "‹nom prénom›"
      git config --global user.email  ‹votre mail›
      git config --global core.editor ‹nano# ou vi, emacs...
  • Cloner votre dépôt(si vous avez fourni votre clé ssh)
      git clone elec390@git.comelec.enst.fr:‹année›/‹PrenomNom›
  • Utilisation (basique)
      git add ‹nom des fichiers›
      git commit
      git push

Cette partie se décompose en deux phases :

  1. une introduction rapide aux HDL (langages de description de matériel) : cette partie vous explique pourquoi on a besoin de constructions spéciales pour modéliser des systèmes matériels (donc parallèles), les principes de la simulation événementielle, et les affectations différées. Cette partie comporte 4 chapitres (introduction, niveaux de description, simulation, et exercices). Tous les chapitres sont à lire et à comprendre, bien entendu. Ce n'est qu'à l'issue de cette partie que vous pourrez passer à SystemC. Si vous avez suivi le cours sur Verilog/SystemVerilog passez directement à l'étape 2.
  2. SystemC : où on vous présente la syntaxe de ce "langage", ses constructions et la façon dont on l'utilise. Cette partie comporte six chapitres, et finit par deux exercices un peu plus compliqués que ceux éparpillés dans le cours qui vous permettront de faire la synthèse de vos connaissances.

 

Mini-projet

Objectifs : le but de ce mini-projet est de vous faire modéliser un système de traitement vidéo, qui prend en entrée un flux vidéo CCIR656 et qui lui applique au vol des transformées basiques. On cherchera dans ce projet à être le plus efficace possible, en terme de ressources pour la simulation, de types de variables/signaux, de complexité et de lisibilité du code.

1. Plan du projet

Le travail demandé pour ce mini-projet se décompose en trois phases :

  • récupération d'un module de génération de flux vidéo et de son environnement de test
  • écriture d'un système de réception de flux vidéo
  • écriture du système de transformation vidéo, et test de ce système.

 

2. Contexte

On cherche à modéliser et simuler un système de traitement vidéo, qui doit prendre des flux vidéo en entrée, et restituer un flux transformé en sortie. Les transformations appliquées peuvent êtres multiples :

  • filtrage (flou léger)
  • zoom in / zoom out
  • ...

Le format de flux vidéo choisi est le CCIR 601. Il a toutefois été simplifié pour ne pas trop compliquer le système. En voici les grandes lignes (mais le web regorge d'information à ce sujet) :

  • Le flux vidéo est transmis sur un bus comprenant 3 parties
    • une horloge à la fréquence pixel
    • les pixels, sous forme d'un quadruplet RGBA (8 bits pour chacune des composantes R, G, et B, et 8 bits pour l'alpha. 0=transparent, 255=opaque).
    • deux signaux synchronisation : HREF et VREF.
  • Une ligne vidéo se compose d'environ 864 pixels, dont 720 actifs (c'est-à-dire qui contiennent des pixels valides. Les autres sont en nombre indéterminé, ils correspondent au temps nécessaire pour un retour ligne).
  • Une image se compose d'environ 625 lignes, dont 576 actives (les autres correspondent au temps de retour trame).

Pendant la transmission de pixels actifs d'une ligne, un signal de synchronisation, HREF, est mis à 1. Pendant le reste du temps, HREF vaut 0.
Au début d'une trame, un signal de synchronisation verticale, VREF, est mis à 1 pendant 3 lignes. Le front montant de VREF coincide avec celui de HREF.

Les pixels sont transmis à la cadence de 13.5Mhz, synchrones sur front montant de l'horloge.

 

3. Module d'entrée

Pour tester votre système, vous allez avoir besoin de modules d'entrée et de sortie vidéo, qui vont respectivement produire un flux vidéo à partir d'une série d'images au format PNG, et produire des images PNG à partir du flux vidéo de sortie. Pour cela, on utilisera les fonctions de la libpng, une bibliothèque libre qui fournit des fonctions pour lire et écrire des images au format PNG. On aurait pu utiliser d'autres bibliothèques pour lire directement des flux vidéo, mais cela aurait été un peu plus compliqué.

Le module de génération de flux vidéo est déjà écrit. Il est disponible dans le dépôt Git suivant:

Vous pouvez, cloner le dépôt séparément et copier manuellement les fichiers dans votre dépôt personnel ou le fusionner (merger) directement avec votre dépôt personnel comme suit:

    git remote add projet  elec390@git.comelec.enst.fr:projet
    git pull projet master

Vous obtiendrez à la racine du dépôt un dossier projet_video contenant:

  • un fichier de fonctions pratiques pour accéder aux fonctionnalités de libpng (image.*)
  • le module de génération de flux vidéo proprement dit (video_in.*)
  • un environnement de test sommaire (system.cpp)
  • un Makefile
  • des images de test, tirées d'un film d'animation bien connu.

Pour des raisons de simplicité on se limite à des images en niveaux de gris. Les pixels venant du générateur de flux ne sont donc codés que sur 8bits

Vous pouvez simuler le système tel quel, mais les résultats (simulation_trace.vcd) sont peu parlant. Simulez le quand même, et familiarisez-vous avec les chronogrammes du flux pseudo-CCIR601.

 

4. Au travail : module de sortie

Maintenant que vous avez un module qui vous fournit un flux vidéo, il serait sympa d'avoir un module qui fait l'inverse, pour vérifier visuellement les transformations vidéo. C'est l'objet d'un module appelé video_out.

Le travail de cette séance :

  • écrire un module de récupération du flux vidéo, qui crée des images PNG à partir du flux vidéo.
  • instanciation dans votre environnement de test des deux modules video_in et video_out
  • relier les deux modules directement entre eux, à l'intérieur de votre testbench et simuler le tout. Les images de sorties doivent être les mêmes que celles d'entrée. Vous pouvez le vérifier en les affichant, par la commande display par exemple (display output0.png).

Attention : votre module video_out ne doit surtout pas compter sur le fait que les trames font 625 lignes ni 864 pixels ! C'est à lui de se synchroniser (à l'aide de HREF et VREF) sur le flux entrant. Il peut par contre compter sur le fait que dans chaque trames il y aura 720*576 pixels valides.

 

5. Effets spéciaux

Le but du jeu est maintenant de construire un système qui va opérer sur un flux sortant du premier module. Vous avez d'ores-et-déjà un module qui fournit des flux vidéos et un module qui en génère des png. Reste à écrire ce qui va s'interposer entre les deux. On implémentera ces filtres (dans l'ordre) :

  • filtre moyenneur sur 8 pixels ajdacents (les 8 voisins) : dans la mesure du possible, ce filtre doit effectuer son traitement au vol.
  • zoom * 2 : on fera un zoom centré, en dupliquant chaque pixel. Un traitement au vol est-il possible et/ou adapté ?

Vérifiez visuellement que tout marche bien.