wiki:MultiCourseTP1

TP1 : Prototypage virtuel & Protocole PIBUS

(pirouz.bazargan-sabet@…)

A. Objectifs

Le but de ce premier TP est double :

  • On introduit les techniques de modélisation de matériel en langage SystemC (prototypage virtuel).
  • On analyse en détail le protocole du PIBUS, sur un tout petit système, ne contenant pas de processeur programmable.

On utilise la plate-forme de prototypage SoCLib, qui permet de modéliser et de simuler au cycle près des architectures matérielles intégrées sur puce. La plate-forme SoCLib contient des modèles de simulation de composants matériels (tels que des coeurs de processeurs, des contrôleurs de bus, des contrôleurs mémoire embarqués, ou des contrôleurs de périphériques). Ces modèles sont écrits en langage SystemC et peuvent être interconnectés entre eux pour construire un prototype virtuel de l'architecture matérielle.

Pour comprendre le fonctionnement du PIBUS, vous allez analyser la structure des automates qui contrôlent chacun des trois types de composants matériels connectés au bus : un initiateur, une cible, et l'arbitre du bus.

Outre l'arbitre du bus, l'architecture étudiée dans ce TME comporte donc un maître et deux cibles :

  • PibusSegBcu : Arbitre du bus
  • PibusSimpleMaster (Maître) : automate cablé
  • PibusSimpleRam (Cible) : contrôleur mémoire
  • PibusMultiTty (Cible) : contrôleur de terminal écran/clavier

Le maître PibusSimplemaster a uniquement pour but de faciliter la compréhension du protocole du PIBUS. C'est un automate cablé qui ne sait faire qu'une seule chose : il exécute une boucle infinie dans laquelle il effectue successivement, à chaque itération, les 4 actions suivantes :

  1. Lecture de la chaîne de caractères Hello World, stockée dans la mémoire. Pour cela, il effectue une première transaction sur le bus consistant à lire dans la mémoire une rafale de 4 mots de 32 bits (ce qui représente 4 * 4 = 16 caractères).
  2. Affichage de cette chaîne, caractère par caractère, sur le terminal TTY. Pour cela, il doit exécuter 16 transactions en écriture (une transaction par caractère à afficher), en écrivant chaque caractère à l'adresse correspondant au registre DISPLAY du terminal TTY.
  3. Attente qu'un caractère soit saisi au clavier du terminal. Pour cela le processeur tourne dans une boucle où il effectue une transaction de lecture du registre STATUS du terminal TTY, jusqu'à obtenir une valeur non nulle signifiant qu'un caractère est disponible dans le registre KEYBUF du terminal TTY.
  4. La dernière étape consiste à effectuer une transaction en lecture pour lire le caractère tapé au clavier dans le registre KEYBUF du terminal TTY.

Le composant matériel TTY possède au total 4 registres 32 bits adressables, et occupe donc 16 octets dans l'espace adressable. Si SEG_TTY_BASE est l'adresse de base du segment associé au composant TTY, les adresses de ces registres sont les suivantes:

DISPLAY SEG_TTY_BASE
STATUS SEG_TTY_BASE+4
KEYBUF SEG_TTY_BASE+8
CONFIG SEG_TTY_BASE+12

Concernant le protocole du PIBUS, on rappelle que, du point de vue du maître, une transaction simple (c'est-à-dire le transfert d'un seul mot de 32 bits) nécessite au minimum trois cycles :

  • cycle allocation : le maître demande l'allocation du bus
  • cycle commande : le maître envoie la commande contenant l'adresse.
  • cycle réponse : la cible envoie la réponse et la donnée est transmise.

Dans le cas des transactions de type rafale, on utilise une technique de pipeline, pour effectuer, dans le même cycle et sur deux nappes de fils séparées, le transfert de l'adresse (i+1), en même temps que le transfert de la donnée (i).

Dans tout système à mémoire partagée, l'adresse comporte deux parties :

  • Les bits de poids fort (MSB) permettent de désigner une cible particulière.
  • Les bits de poids faible (LSB) désignent un octet particulier dans la cible.

Le composant matériel PibusSegBcu doit analyser les bits de poids fort de l'adresse pour désigner la cible concernée par la transaction. La table des segments est décrite dans le fichier qui décrit l'architecture matérielle. Cette table des segments permet au concepteur du système de définir l'organisation (c'est-à-dire le découpage en segments) de l'espace adressable physique : Le concepteur peut associer à chaque cible instanciée dans le système un (ou plusieurs) segment(s) de l'espace adressable. Les cibles peuvent être soit des bancs mémoires (composant PibusSimpleRam), soit des périphériques adressables (composant PibusMultiTty). Le concepteur doit également définir le nombre de bits de poids fort de l'adresse qui seront décodés par le BCU pour sélectionner une cible particulière. La « ROM de décodage », contenue dans le composant BCU, est un décodeur qui prend en entrée les N bits de poids fort de l'adresse et fournit en sortie l'index de la cible sélectionnée (codé en "one hot"). Cette ROM est construite (c'est-à-dire initialisée) par le constructeur du composant PibusSegBcu, à partir des informations saisies dans la table des segments.

B. Pour démarrer

L'archive attachment:multi_tp1.tgz contient différents fichiers dont vous aurez besoin pour ce premier TP. Créez dans votre compte un répertoire tp1, et décompressez l'archive dans ce répertoire. Vous devez obtenir les 2 fichiers tp1_top.cpp et tp1.desc décrivant l'architecture matérielle, ainsi que le fichier string_file contenant la chaîne de caractères.

Les fichiers contenant les modèles de simulation des composants matériels utilisés dans les différentes architectures matérielles qui seront étudiées dans cette U.E. sont rangés dans le répertoire :

/users/outil/soc/soclib-lip6/pibus

Vous n'aurez pas besoin de modifier ces fichiers, et il n'est donc pas nécessaire de les recopier sur votre compte.

C. Automate du composant PibusSimpleRam

Le composant matériel PibusSimpleRam possède l'interface suivante :

  • 4 ports d'entrée : SEL (sélection de la cible), READ (sens de l'échange sur le PIBUS), A (adresse PIBUS), et OPC (non utilisé)
  • 1 port de sortie : ACK (acquittement PIBUS)
  • 1 port bi-directionnel DT (donnée transférée sur le PIBUS)

Dans ce TP et dans les suivants, on considère des systèmes synchrones : tous les composants matériels sont synchronisés par le même signal d'horloge, et le temps de cycle du processeur est égal au temps de cycle du bus, qui est lui-même égal au temps de cycle du contrôleur mémoire.

Cette hypothèse n'est pas réaliste pour ce qui concerne la mémoire : Suivant la fréquence de fonctionnement choisie pour le processeur, le contrôleur mémoire ne répond pas nécessairement en un cycle : il faut parfois attendre plusieurs cycles entre la réception d'une commande de lecture et l'obtention de la donnée. Pour reproduire ce comportement, il est possible de faire varier la latence du contrôleur mémoire en introduisant un nombre fixe de cycles d'attentes. Ce nombre L de cycles d'attente est un paramètre matériel du modèle du contrôleur mémoire, ce qui signifie qu'il ne peut pas être modifié par logiciel pendant la simulation. Dans le modèle de simulation du contrôleur mémoire, un compteur de cycles (COUNT) est initialisé dans l'état IDLE à la valeur L. Si la valeur du paramètre L est non nulle, le composant passe dans un état d'attente lorsqu'il reçoit une commande de lecture ou d'écriture. Le compteur est décrémenté à chaque cycle, et la réponse à la transaction n'est effectivement envoyée que lorsque le compteur atteint la valeur zéro.

L'automate de Moore qui contrôle ce composant possède 6 états. Cet automate constitue une partie du composant PibusSimpleRam, et possède sa propre interface décrite ci-dessous. Il a lui même 5 signaux Booléens en entrée : les signaux SEL et READ du Pibus, le signal GO (qui vaut 1 lorsque le compteur de latence atteint la valeur 0), le signal DELAY (qui vaut 1 lorsque la valeur du paramètre L est non nulle), et ADR_OK (qui vaut 1 lorsque l'adresse appartient bien au segment associé à la RAM).

Il contrôle 4 signaux en sortie : Le signal ACK_EN est un Booléen qui autorise l'émission de la réponse sur le bus ACK du PIBUS. Le signal ACK_VALUE définit la valeur de la réponse et peut prendre 3 valeurs : WAIT, READY, ERROR. Le signal MEM_CMD est la commande vers la mémoire, et peut prendre 3 valeurs : NOP (ni lecture ni écriture), READ, WRITE. Le signal DT_EN est un Booléen qui autorise l'écriture sur le bus DT du PIBUS. Cet automate se comporte comme un automate de Moore : les valeurs des signaux de sortie ne dépendent pas des valeurs des signaux d'entrée.

Question C1 : Complétez le graphe représentant l'automate à 6 états qui contrôle le composant matériel PibusSimpleRam. Il faut préciser la fonction de transition en attachant à chaque transition une expression Booléenne dépendant des signaux d'entrée de l'automate... sans oublier de vérifier les conditions de complétude et d'orthogonalité.

Question C2 : Précisez la fonction de génération de cet automate (c'est-à-dire les signaux définissant la réponse sur le bus), en remplissant le tableau ci-dessous.

ACK_EN ACK_VALUE DT_EN MEM_CMD
IDLE
R_WAIT
R_OK
W_WAIT
W_OK
ERROR

Attention : On rappelle que les signaux ACK et DT du PIBUS sont des signaux « bussés » (c'est-à-dire multi-émetteurs). Par conséquent, le composant PIBUS_MULTI_RAM n'émet une valeur sur ces signaux de sortie que dans les états où il a le droit de le faire.

Pour vérifier vos résultats, vous pouvez comparer l'automate que vous aurez défini à celui qui est codé dans les fichiers :

/users/outil/soc/soclib-lip6/pibus/pibus_simple_ram/source/include/pibus_simple_ram.h
/users/outil/soc/soclib-lip6/pibus/pibus_simple_ram/source/src/pibus_simple_ram.cpp

D. Automate du composant PibusSimpleMaster

Le composant matériel PibusSimpleMaster possède l'interface suivante :

  • 2 ports d'entrée : GNT, ACK (acquittement PIBUS).
  • 5 ports de sortie : REQ, A (adresse PIBUS), READ, LOCK, OPC (commande PIBUS)
  • 1 port bi-directionnel : DT (donnée transférée sur le PIBUS)

En plus du registre d'état de l'automate (FSM_STATE), ce composant stocke les 16 octets lus en mémoire dans une petite mémoire locale (BUF) possédant une capacité de 4 mots de 32 bits, et il possède un petit compteur interne permettant de compter le nombre de caractères qui ont été envoyés au terminal TTY.

L'automate de Moore qui contrôle ce composant possède lui-même 4 sigaux Booléens en entrée : GNT (le bus est alloué), READY (signal indiquant que le bus ACK du PIBUS a la valeur READY), LAST (signal provenant d'un compteur auxiliaire, indiquant qu'il s'agit du dernier caractère de la chaîne), NUL (signal provenant d'un décodeur auxiliaire, indiquant que la donnée lue sur le bus DT du PIBUS a la valeur 0).

Puisque ce composant est un automate cablé (non programmable), il ne peut pas y avoir d'erreur d'adressage logicielle, et on suppose que les cibles ne renvoient jamais la valeur ERROR sur le bus ACK, ce qui simplifie l'automate.

Il contrôle 6 signaux en sortie : Le signal REQ est le signal Booléen envoyé vers le BCU pour demander l'allocation du bus), le signal CMD_EN est un Booléen qui autorise l'émission sur le bus de commande. ADR_VALUE définit la valeur de l'adresse (Il y a 7 valeurs possibles: RAM_BASE, RAM_BASE+4, RAM_BASE+8, RAM_BASE+12, TTY_BASE, TTY_BASE+4, TTY_BASE+8). Les signaux READ_VALUE et LOCK_VALUE indiquent respectivement le sens de l'échange sur le bus et le fait que la commande émise n'est pas la dernière d'une rafale. Enfin, le signal DT_EN est un Booléen qui autorise l'écriture sur le bus DT du PIBUS.

Question D1 : Complêter le graphe représentant l'automate ci-dessous, en attachant à chaque transition une expression Booléenne dépendant des 4 signaux GNT, READY, LAST, et NUL.

Question D2 : Précisez la fonction de génération, en remplissant le tableau définissant, pour chacun des états de l'automate, les valeurs des signaux de sortie contrôlés par cet automate.

REQ CMD_EN ADR_VALUE READ_VALUE LOCK_VALUE DT_EN
INIT
RAM_REQ
RAM_A0
RAM_A1_D0
RAM_A2_D1
RAM_A3_D2
RAM_D3
W_REQ
W_AD
W_DT
STS_REQ
STS_AD
STS_DT
BUF_REQ
BUF_AD
BUF_DT

On rappelle qu'il s'agit d'un automate de Moore.

Pour vérifier vos résultats, vous pouvez comparer l'automate que vous aurez défini à celui qui est codé dans les fichiers :

/users/outil/soc/soclib-lip6/pibus/pibus_simple_master/source/include/pibus_simple_master.h
/users/outil/soc/soclib-lip6/pibus/pibus_simple_master/source/src/pibus_simple_master.cpp

E. Automate du composant PibusSegBcu

Dans le cas où il y a un seul maître et deux cibles, le contrôleur de bus PibusSegBcu possède l'interface suivante :

  • 4 signaux d'entrée : REQ, LOCK, ACK, A
  • 3 signaux de sortie GNT, SEL0, SEL1

On rappelle que les deux fonctions principales de l'arbitreur du bus sont les suivantes :

  • allouer le bus à un maïtre (en respectant une priorité tournante lorsqu'il y a plusieurs demandes simultanées).
  • sélectionner la cible désignée par les bits de poids fort de l'adresse émise par le maître qui a obtenu l'accès au bus.

Attention: Le composant BCU n'intervient pas dans le traitement des erreurs d'adressage. il ne fait pas la différence entre une réponse ACK==READY (signalant un succès) ou ACK==ERROR (signalant un échec). Il a seulement besoin de savoir que la cible sélectionnée a fourni une réponse (c'est-à-dire ACK!=WAIT), pour détecter la fin de la transaction en cours.

Ce composant est réalisé comme un automate de Mealy : les valeurs des trois signaux de sortie dépendent directement (c'est-à-dire de façon combinatoire) des signaux d'entrée.

Les 4 états de l'automate correspondent aux différents états possibles du pipeline, et ont la signification suivante:

  • IDLE : aucune transaction n'est en cours, et l'arbitreur attend qu'au moins un maître demande à utiliser le bus
  • AD : Le bus a été alloué à un maître, et c'est la première commande
  • DTAD : Le bus a été alloué à un maitre, et on est au milieu d'un transaction rafale : CMD(i) / RSP(i-1)
  • DT : le bus a été alloué à un maitre, et c'est la réponse à la dernière commande

Question E1 : Complétez le graphe représentant l'automate à 4 états du composant matériel PibusSegBcu ci-dessous, en attachant à chaque transition une expression Booléenne dépendant des signaux d'entrée REQ, ACK, et LOCK.

Question E2 : Précisez la fonction de génération, en remplissant le tableau définissant les valeurs des signaux de sortie GNT, SEL0 et SEL1 pour chacun des 4 états de l'automate.

GNT SEL0 SEL1
IDLE  
AD
DTAD
DT

Attention : L'automate du BCU se comporte comme un automate de Mealy, et les valeurs contenues dans ce tableau peuvent dépendre des valeurs des signaux d'entrée REQ, ACK & LOCK, ainsi que de l'adresse A.

Question E3: Expliquer pourquoi l'allocation (choix d'un maître) est réalisée non seulement dans l'état IDLE, mais aussi dans l'état DT.

Pour vérifier vos résultats, vous pouvez comparer l'automate que vous aurez défini à celui qui est codé dans les fichiers :

/users/outil/soc/soclib-lip6/pibus/pibus_seg_bcu/source/include/pibus_seg_bcu.h
/users/outil/soc/soclib-lip6/pibus/pibus_seg_bcu/source/src/pibus_seg_bcu.cpp

F. Modélisation de l'architecture matérielle

Le fichier tp1_top.cpp contient une description (volontairement incomplète) de l'architecture du système : on fournit une carcasse qui ne contient que le composant PibusBcu et le composant PibusMultiTty. La description de l'architecture se décompose en 5 parties:

  1. declaration des signaux permettant d'interconnecter les composants
  2. définition de la table des segments (voir ci-dessous)
  3. définition et paramétrisation des composants (on exécute le constructeur de chaque composant instancié)
  4. définition de la net-list
  5. lancement de la simulation

Question F1 : Complétez le fichier tp1_top.cpp en instanciant et en connectant les 2 composants matériels manquant : PibusSimpleMaster et PibusSimpleRam. Vous devez ouvrir les fichiers pibus_simple_ram.h et pibus_simple_master.h pour comprendre quels arguments doivent être définis lors de l'instanciation de ces deux composants (l'instanciation est réalisée par l'appel du constructeur du composant).

La segmentation de l'espace adressable est également définie dans le fichier tp1_top.cpp. La table des segments est une table associative, où un segment est défini par 5 caractéristiques :

  • un nom de segment
  • une adresse de base
  • une taille (en octets)
  • l'index de la cible à laquelle il est associé
  • un Booléen définissant si le segment est cachable

Cette architecture non programmable (tout est cablé) n'utilise que deux segments : un segment associé à la RAM, et un segment associé au terminal TTY.

Question F2 : Complétez le fichier tp1_top.cpp, en définissant le segment associé au contrôleur TTY (Le segment associé à la RAM est déjà défini). On utilise des mnémoniques pour définir la base et la longueur des segments. Ces mêmes mnémoniques sont utilisés comme arguments du constructeur du composant PibusSimpleMaster.

Question F3 : Ouvrez le fichier pibus_simple_ram.cpp pour déterminer comment est initialisée la chaîne de caractère "Hello World!" dans la mémoire, au début du segment seg_ram associé à la mémoire.

G. Simulation

Dans cette dernière partie, on va - enfin - lancer la simulation.

Compilez le fichier tp1_top.cpp pour créer l'exécutable de simulation simul.x, en utilisant la version SystemC 2.1 . On utilise pour cela l'outil soclib-cc. Il faut pour ajouter le chemin d'accès à soclib-cc dans votre path en exécutant le script :

$ source /users/outil/soc/env_soclib.sh

Puis lancer la commande :

$ soclib-cc -p tp1.desc -t systemcass -o simul.x

Lancez la simulation pour 1000000 cycles en utilisant la commande :

$  ./simul.x -NCYCLES 10000000

Question G1 : Quelle est la vitesse de simulation (mesurée en nombre de cycles simulés par seconde) ? Pour répondre à cette question, le plus simple est d'utiliser votre montre.

Pour bien comprendre ce qui se passe, re-exécutez la simulation en traçant les valeurs des signaux du bus, ainsi que les états internes des automates des trois composants PibusSimpleMaster, PibusSimpleRam et PibusBcu. Pour cela, il faut utiliser les options -TRACE (pour activer le mode trace) et -NCYCLES (pour limiter le nombre de cycles simulés), et rediriger la trace dans un fichier trace:

$ ./simul.x -DEBUG 0 -NCYCLES 10000 > trace

Analysez ce fichier trace pour répondre aux questions suivantes:

Question G2 : Combien y-a-t-il de cycles d'attente dans les états de l'automate du composant maître où celui-ci demande au BCU l'allocation du bus? Expliquez ce comportement.

Question G3 : Combien y-a-t-il de cycles d'attente dans les états de l'automate du composant maître ou celui-ci attend la réponse de la RAM ? Expliquez ce comportement.

Question G4 : Combien faut-il de cycles à l'automate du composant maître pour afficher un caractère sur le composant PIBUS_MULTI_TTY ?

Question G5 : Dessinez le chronogramme correspondant aux 20 premiers cycles d'exécution, en représentant : les états internes des 4 automates des 4 composants, ainsi que les signaux du Pibus : REQ, GNT, SEL_RAM, SEL_TTY, A, LOCK, READ, D, ACK.

H. Compte-Rendu

Les réponses aux questions ci-dessus doivent être rédigées sous éditeur de texte et ce compte-rendu doit être rendu au début de la séance de TP suivante. De même, le simulateur, fera l'objet d'un contrôle (par binôme) au début de la séance de TP de la semaine suivante.

Last modified 15 months ago Last modified on Feb 9, 2023, 3:53:14 PM

Attachments (7)

Download all attachments as: .zip