wiki:TP3_2012_Monopro

TP3 : Déploiement de l'application MJPEG sur une architecture SoC monoprocesseur

TP Précédent : TP2_2012_MappingInfo

TODO : vérifiez qu'ils ne peuvent pas avoir accès au code le la task_library...

0. Objectif

Dans le précédent TP, nous avons vu comment DSX pouvait utiliser des informations de mapping (placement) par l'intermédiaire d'un format xml, afin de produire un binaire pour une architecture spécifique. Dans ce TP, nous allons cette fois-ci voir comment spécifier à DSX une partie de l'architecture afin que ce dernier produise lui-même les informations de mapping nécessaire pour cette architecture. En d'autres termes, le but est désormais de ne plus écrire le fichier map.xml à la main, mais de donner suffisamment d'informations à DSX pour qu'il puisse le produire. La première partie de ce TP vise donc à montrer comment décrire à DSX une architecture matérielle de système intégré sur puce, en exploitant les composants matériels de la bibliothèque SoCLib. On rappelle que la bibliothèque SoCLib contient un ensemble modèles de simulation de composants matériels (IP cores), décrits en langage SystemC.

La seconde partie du TP vous permettra d'utiliser DSX pour décrire et contrôler précisément le déploiement de l'application logicielle SplitMsg, sur l'architecture matérielle décrite dans la première partie. On validera ce déploiement en simulant l'exécution du code binaire de l'application logicielle sur le modèle SystemC de l'architecture matérielle.

La troisième partie du TP vous permettra d'atteindre notre véritable but, qui est de déployer l'application MJPEG, vue au TP1, sur l'architecture de SoC monoprocesseur décrite dans la première partie, en contrôlant précisément le placement des tâches sur les processeurs ou coprocesseurs, et le placement des objets logiciels les bancs mémoire embarqués.

1. Description de l'architecture matérielle

On se limitera dans ce TP à une architecture ne contenant qu'un seul processeur programmable de type MIPS32. Cette architecture matérielle est appelée 'VgmnMonopro' (voir le schéma simplifié de l'architecture ci-contre).

  • Elle est organisée autour d'un micro-réseau générique à interface VCI (composant VGMN). Le VGMN est générique dans le sens où il accepte un nombre quelconque d'initiateurs VCI, et un nombre quelconque de cibles VCI, ainsi qu'un paramètre définissant la latence du réseau : c'est-à-dire le nombre minimal de cycles pour une traversée du réseau ("one-way").
  • Elle comporte un processeur et son cache, deux contrôleurs mémoire RAM0 et RAM1, et un contrôleur de terminal TTY.

Commencez par récupérer l'archive suivante : attachment:tp3.tar.gz et décompressez-là dans un répertoire 'tp3' que vous aurez créé pour l'occasion avec la commande

$ mkdir tp3
$ cd !$
$ cp /path/to/downloaded/tp3.tar.gz ./
$ tar -xvzf tp3.tar.gz

Allez ensuite dans le répertoire 'splitmsg'. Y sont présent un fichier 'app.py' contenant le tcg de l'application et un répertoire 'platform' contenant la topcell de l'architecture.

Ouvrez le fichier 'platform/top.cpp' et observez-le.

  • Question 1 : Quels composants matériels sont présents dans cette architecture, qui ne sont pas représentés sur le schéma simplifié de l'architecture ci-dessus ? Pourquoi sont-ils nécessaires dans notre cas (exécution d'une application multi-tâches communiquants par canaux mwmr sur une architecture à 1 processeur) ?
  • Question 2 : Quelle est l'adresse physique de base du composant tty ? du composant timer ? du composant icu ?
  • Question 3 : Quelles sont la base et la taille des mémoires 'user' et 'kernel'

Créez ensuite dans le répertoire 'splitmsg' un fichier vgmn_monopro.py et saisissez-y le contenu suivant.

#!/usr/bin/env python

from dsx.hard.hard import *

def VgmnMonopro(nb_tty = 2):

    hd = Hardware(1, 1) # number of clusters and number of processor per cluster

    ####### peripherals ########
    hd.add(Tty('tty', cluster_id = 0, pbase = ..., channel_size = 16, nb_channel = nb_tty))
    hd.add(Timer('timer0', cluster_id = 0, pbase = ..., channel_size = 16, nb_channel = 1))
    hd.add(Icu('icu0', cluster_id = 0, pbase = ..., channel_size = 32, nb_channel = 1))

    ########## irqs ##########
    hd.add(Irq(cluster_id = 0, proc_id = 0, icu_irq_id = 0, peri = Timer, channel_id = 0))

    ########### Mems ##########
    hd.add(ROM("PSEG_ROM", cluster_id = 0, pbase = 0xbfc00000, size = 0x00010000))
    hd.add(RAM("PSEG_RAU", cluster_id = 0, ...))
    hd.add(RAM("PSEG_RAK", cluster_id = 0, ...))

    return hd

Ce contenu est incomplet : à partir des observations faites aux trois premières questions, complétez ce fichier (les parties manquantes sont indiquées par '...').

2. Déploiement de l'application SplitMsg

Vous allez maintenant déployer l'application SplitMsg, qui ne comporte que deux tâches et un canal, sur votre architecture de SoC monoprocesseur.

  • Recopiez dans le répertoire 'splitmsg' les sources de l'application du TP précédent (répertoire src)
  • Créez, toujours dans le répertoire 'splitmsg', un fichier 'splitmsg.py' et saisissez-y le contenu suivant, qui contient le mapping de l'application sur l'architecture.
#!/usr/bin/env python

import dsx
from vgmn_monopro import VgmnMonopro
from app import tcg
from dsx.mapper.mapper import Mapper

hd = VgmnMonopro(nb_tty = 3)

mpr = Mapper(hd, tcg)

# canaux mwmr
mpr.map("fifo0", pseg = "PSEG_RAU")

# taches (proc et stack)
mpr.map("prod", cluster = 0, proc = 0, stack = "PSEG_RAU")
mpr.map("cons", ...)

# code appli et systeme
mpr.map("split_msg", code = "PSEG_RAU", data = "PSEG_RAU", ptab = "PSEG_RAU")
mpr.map("system", boot = "PSEG_ROM", kernel = "PSEG_RAK")

tcg.generate(dsx.Posix())
mpr.generate(dsx.Giet(outdir = "platform"))

On doit dans ce fichier placer les canaux de communication mwmr (segment mémoire pour les objets logiciels correspondants au tampon et au statut du canal), les tâches, le tcg et le système d'exploitation.

Question 4 : Quels objets logiciels doit-on placer dans l'espace addressable pour une tâche ? pour un tcg ? pour un processeur ? (Question pour moi : où est placé le code des drivers ?)

Complétez la ligne incomplète, puis exécutez la description de l'application :

$ ./splitmsg.py

La ligne 'tcg.generate(dsx.Posix())' du fichier 'splitmsg.py' doit créer un répertoire 'posix_split_msg' et un lien symbolique 'exe.posix.split_msg'. Vous pouvez exécuter l'application en natif en l'exécutant :

$ ./exe.posix.split_msg

La ligne 'mpr.generate(dsx.Giet(outdir = "platform"))' du fichier 'splitmsg.py' doit créer deux répertoires 'platform/soft' et 'platform/hard'. Ce dernier contient les coprocesseurs de l'application et est donc vide dans notre cas. Le répertoire 'platform/soft' contient le code de l'application et du système.

(TODO : vérifier que c'est toujours le cas avant le TP ; i.e. que le code du giet est toujours intégralement recopié)

On peut maintenant compiler la plateforme matérielle. Faites :

$ cd platform
$ make
  • Vous pouvez maintenant simuler l'exécution de l'application logicielle sur le modèle SystemC du SoC :
$ ./simul.x
  • Question 5 : Qu'observez-vous ? En quoi est-ce différent de ce qui se passe dans la version pour station de travail ?
  • Question 6 : Ouvrez le fichier soft/map.xml produit par dsx. À quelle adresse virtuelle ...?

(TODO : trouver une question sur le fichier map.xml)

Avant de quitter ce répertoire, vous pouvez effectuer les commandes suivantes afin de libérer de l'espace disque :

$ ./splitmsg.py -m clean
$ make realclean

La première commande détruit tous les fichiers générés par les différentes compilations effectuées. Ce ménage est indispensable pour vous éviter de dépasser votre quota d'espace disque.

3. Déploiement de l'application MJPEG

L'application MJPEG est différente de l'application SplitMsg car elle utilise deux périphériques d'entrée/sortie spécialisés :

  • le coprocesseur Tg : un composant matériel qui récupère le flux binaire MJPEG (fournit par un signal radio-fréquence, par exemple), effectue la conversion analogique/numérique et écrit le résultat dans un canal MWMR
  • le coprocesseur Ramdac : un composant matériel qui lit une image décompressée dans un canal MWMR et génère le signal vidéo pour affichage sur l'écran.

Pour pouvoir déployer ces deux tâches sous forme de coprocesseurs matériels, il faut prévenir DSX qu'il existe des coprocesseurs implémentant ces tâches. Vous allez donc modifier les déclarations des modèles de tâches en conséquence.

Retournez dans le répertoire mjpeg du TP1, et exécutez la commande ./mjpeg -m clean. Recopiez le contenu de ce répertoire mjpeg nettoyé dans votre répertoire 'tp3', par exemple avec la commande cp -r * ../../tp3/mjpeg/. Revenez dans le répertoire mjpeg du TP3, et renommez le fichier 'mjpeg.py' en 'app.py' (comme pour SplitMsg, on sépare en deux fichiers le tcg de l'application et le mapping).

Ouvrez le fichier 'platform/top.cpp' contenant la description de l'architecture matériel en soclib et observez-le.

  • Question 7 : Quels composants matériels ont été rajoutés par rapport à l'architecture utilisée pour l'application SplitMsg ? Pourquoi à votre avis est-il nécessaire d'avoir ces composants dans l'architecture ?

Modifiez la définition des modèles de tâches tg et ramdac pour introduire leurs implémentations matérielles. Comme ces deux implémentations sont définies dans soclib, la directive import soclib doit être présente avant la description des tâches dans votre fichier de description de tâche (.tsk).

  • Pour la tâche tg, modifiez la déclaration de la tâche pour ajouter l'implémentation matérielle virtuelle (SyntheticTask):
TaskModel(
    'mjpeg_tg',
    ports = {
             'output':MwmrOutput()
            },
    impls = [ SwTask('tg',
                     stack_size = 4096,
                     sources = [ 'tg.c' ],
                     headers = [ '../common/jpeg.h' ],
                     defines = [ 'FILE_NAME' ]),
              SyntheticTask()
            ],
    uses = ['tty']
)
  • De même, pour la tâche ramdac.
  • Recopiez dans le répertoire mjpeg la description DSX vgmn_monopro.py que vous avez écrite dans la première partie, puis ajoutez-y les deux lignes suivantes dans la description de l'architecture :
hd.add(MwmrCoprocTaskWrapper("tg_coproc",     cluster_id = 0, pbase = 0x94000000, channel_size = 32, sc_name = 'TgCoproc'))
hd.add(MwmrCoprocTaskWrapper("ramdac_coproc", cluster_id = 0, pbase = 0x95000000, channel_size = 32, sc_name = 'RamdacCoproc'))
  • Question 8 : à quoi doit être égal le champ 'sc_name' dans les lignes ci-dessus ? Pourquoi DSX a-t-il besoin de connaître cette information ?
  • En vous inspirant de ce qui a été fait pour déployer SplitMsg, déployez l'application MJPEG sur la plateforme en créant le fichier de description mjpeg.py.
    • Les coprocesseurs tg et ramdac sont spécifiques, ils doivent faire l'objet d'un déploiement non pas en tant que tâches logicielles sur un processeur, mais en tant que coprocesseurs. Vous devez pour cela utiliser la syntaxe suivante : m.map(<task>, coproc = <coproc>)
  • Relancez la description, recompilez et lancez la simulation.
    $ ./mjpeg
    $ cd platform
    $ make
    $ ./simul.x
    

Pour avoir des statistiques, vous pouvez positionner la variable d'environnement STATS_EVERY à un nombre de cycles (par exemple tous les 500000 cycles):

$ STATS_EVERY=500000 ./simul.x

L'avion fait le "tour" en 25 images. Vous avez un compteur de cycles sur le terminal qui contient le simulateur.

  • Question 9 : Combien faut-il de cycles, approximativement, pour décompresser 25 images ?
  • Question 10 : Supposant un SoC cadencé à 200MHz, combien d'images sont affichées en une seconde ?
  • Question 11 : En consultant les headers de l'objet binaire généré, déterminez la capacité mémoire minimale nécessaire pour chacun des deux bancs mémoire RAU et RAK.

Pour analyser les headers d'un fichier binaire, servez vous des commandes suivantes :

$ mipsel-unknown-elf-objdump -h platform/soft/soft.elf

4. Compte-rendu

Vous rendrez une archive dans le même format que la semaine précédente, nommée binome0_binome1.tar.gz (en minuscules), contenant exactement les fichiers:

tp2/
tp2/rapport.pdf
tp2/vgmn_monopro.py
tp2/splitmsg/
tp2/splitmsg/producer.c
tp2/splitmsg/producer.task
tp2/splitmsg/consumer.c
tp2/splitmsg/consumer.task
tp2/splitmsg/splitmsg
tp2/mjpeg/mjpeg
tp2/mjpeg/src/
tp2/mjpeg/src/iqzz/
tp2/mjpeg/src/iqzz/iqzz.c
tp2/mjpeg/src/iqzz/iqzz.task
tp2/mjpeg/src/libu/
tp2/mjpeg/src/libu/libu.c
tp2/mjpeg/src/libu/libu.task
  • Les fichiers splitmsg et mjpeg seront complets, avec vos descriptions de TCG et le mapping.
  • Le répertoire mjpeg/src contiendra uniquement les implémentation de vos deux tâches libu et iqzz (éventuellement mises à jour par rapport à la semaine dernière) vous ayant servi à exécuter les tests de ce TP.
  • Le rapport sera court (une à deux pages), répondant aux questions posées dans le texte, et nommé exactement tp2/rapport.pdf.

Vous enverrez cette archive avant le (jour) (date), 18h00 à [MailAsim:quentin.meunier Quentin Meunier].

Suite

TP Suivant : TP4_2012_Multipro

Last modified 12 years ago Last modified on Oct 9, 2012, 11:38:41 AM

Attachments (2)

Download all attachments as: .zip