wiki:SoclibCourseTp2

Version 15 (modified by alain, 16 years ago) (diff)

--

TP2: Protocole de communication VCI/OCP

1 Objectif

L'objectif de ce second TP est d'introduire la modélisation SystemC d'architectures utilisant le protocole de communication VCI/OCP. Pour des raisons d'inter-opérabilité, tous les composants matériels de la plate-forme de prototypage SoCLib respectent le protocole de communication VCI/OCP présenté dans le cadre du cours MPSoC. On va donc modifier les deux composants matériels du TP1, pour qu'ils utilisent des ports de communication VCI plutôt que des ports FIFO. Ceci va permettre d'interconnecter plusieurs composants initiateurs et plusieurs composants cibles à travers un bus système.

2 Architecture matérielle cible

L'architecture matérielle qu'on souhaite prototyper dans ce second TP instancie 7 composants matériels de trois types différents : Les deux composants VciLcdCoprocessor et VciLcdMaster sont instanciés trois fois chacun. Ils ont des fonctionnalités identiques à celles des composants utilisés dans le premier TP, mais ces composants possèdent maintenant des ports de communication qui respectent le protocole VCI/OCP. Le composant VciLcdMaster se comporte comme un initiateur, et le composant VciLcdCoprocesseur se comporte come une cible. Le troisième composant VciVgbs (Virtual Generic System Bus) est un composant matériel modélisant un bus multi-maîtres, multi-cibles respectant le protocole VCI/OCP.

Le composant VciVgsb se comporte comme un bus, car il ne traite qu'une seule transaction à la fois. Si plusieurs initiateurs cherchent à envoyer un paquet commande, le contrôleur du bus sélectionne un initiateur (en respectant une priorité tournante de type round-robin), il aiguille la commande vers la bonne cible en décodant les bits de poids fort de l'adresse, attend la réponse de la cible, et aiguille celle-ci vers le bon initiateur. La transaction (n+1) n'est traitée que lorsque la ransaction (n) est entièrement terminée.

3 Protocole VCI/OCP

Le protocol de communication VCI permet de construire des architectures matérielles multi-processeurs à memoire partagée. Dans ce type de d'architecture, les différents composants matériels utilisent des transactions pour communiquer entre eux. Une transaction est un couple (paquet commande / paquet réponse). Une transaction est initiée par un composant initiateur, qui envoie un paquet commande, et est terminée par un composant cible, qui répond à la commande en renvoyant un paquet réponse.

3.1 Interconnection VCI

Dans la spécification VCI "advanced", il y a principalement deux types de commandes :

  • transaction CMD_WRITE : le paquet commande contient un ou plusieurs mots VCI (à des adresses constantes ou consécutives) Le paquet réponse contient un seul mot VCI pour acquitter la transaction.
  • transaction CMD_READ : le paquet commande contient un seul mot VCI (à l'adresse du premier mot VCIde la rafale) et le nombre de mots à lire est défini par le champs PLEN. Le paquet réponse contient un ou plusieurs mots VCI suivant la

longueur de la rafale.

Question : à quoi sert le paquet réponse dans le cas d'une transaction d'écriture ?

Dans une architecture à espace d'adressage partagé, n'importe quel initiateur est capable de communiquer avec n'importe quelle cible. La cible est désignée par les bits de poids fort de l'adresse. Le champs VCI ADDRESS doit donc être décodé par le (ou les) composant(s) matériel(s) qui réalise(nt) le sous-sytème d'interconnexion, pour aiguiller le paquet commande vers sa destination. De façon symètrique, le sous-système d'interconnexion doit décoder le champs VCI RSRCID pour aiguiller le paquet réponse vers l'initiateur concerné.

Question : Pourquoi les différents types de sous-sytèmes d'interconnexion (bus, cross-bar, micro-réseaux, etc.) sont-ils conçus de telle sorte qu'ils utilisent des ressources matérielles séparées pour aiguiller les commandes et les réponses ?

Un canal de communication VCI utilise donc deux sous-canaux : un sous-canal dans le sens (initiateur => cible) pour la commande et un sous-canal dans le sens (cible=>initiateur) pour la réponse. Il est intéressant de noter que chacun de ces deux sous-canaux respecte le protocole FIFO. Les signaux CMDVAL et CMDACK (resp. RSPVAL et RSPACK) correspondent aux signaux WOK et ROK du protocole FIFO pour le sous-canal commande (resp. réponse).

3.2 Les signaux VCI

La figure ci-dessous détaille les signaux utilisés par le protocole VCI.

La plupart des champs VCI on des largeurs paramètrables (en nombre de bits) :

  • le paramètre X définit le nombre de bits du champs ADDRESS. Les adresses VCI sont des adresses octets, mais elles doivent être alignées sur des frontières de mot.
  • le paramètre B définit le nombre d'octets d'un mot de donnée VCI. Ce paramètre définit le largeur des trois champs WDATA, RDATA et BE.
  • le paramètre K définit le nombres de bits termettant de coder la longueur PLEN d'un paquet (en nombre d'octets). La valeur PLEN doit également être un multiple du paramètre B.
  • le paramètre S définit le nombre de bits du champs SRCID, qui permet de coder le numéro de l'initiateur VCI qui a démarré la transaction. Ce paramètre définit donc le nombre maximum d'initiateurs dans le système.
  • Le paramètre E définit le nombre de bits permettant de coder le type d'erreur dans le champs RERROR du paquet commande. La valeur 0 signifie "pas d'erreur".
  • Les deux paramètres T et P définissent le nombre de bits des deux champs TRDID et PKTID. Ces deux champs permettent d'étiqueter une commande VCI par une numéro de thread et/ou par un numéro de transaction. Ils peuvent être utilisés par un initiateur pour envoyer une commande (n+1) sans attendre d'avoir reçu la réponse à la commande (n).

Bien sûr les valeurs de ces paramètres VCI doivent être les mêmes pour tous les composants matériels d'une même architecture, et doivent être définis dans la top-cell décrivant l'architecture générale du système.

3.3 Modélisation des interfaces VCI

La généricité des interfaces de communication VCI est évidemment une souplesse très utile, puisqu'elle permet d'adapter le protocole aux besoins particuliers de chaque application embarquée (on n'a pas toujours besoin de 4 Goctets d'espace adressable). Mais elle crée une difficulté pour la modélisation des composants matériels, puisqu'il faut écrire des modèles de simulation génériques, capable de s'adapter à différentes largeurs des champs adresse ou donnée. On utilise pour cela la techique des templates du langage C++ : on regroupe toutes les valeurs de ces paramêtres dans un oblet C++ de type VciParams?, qui est utilisé comme paramètre template par tous les composants matériels qui possèdent des ports de communication VCI. (voir fichier vci_param.h).

Comme on l'a fait pour le canal de communication FIFO, on définit trois objets, qui facilitent l'écriture des modèles de simulation CABA :

  • l'objet VciSignals? regroupe tous les signaux (commande et réponse) d'un canal VCI. (voir fichier vci_signals.h)
  • l'objet VciInitiator? regroupe tous les ports utilisés par un initiateur VCI pour émettre une commande, et recevoir la réponse. (voir fichier vci_initiator.h)
  • l'objet VciTarget? regroupe tous les ports utilisés par une cible VCI pour émettre une réponse, et recevoir une commande. (voir fichier vci_target.h)

Ces trois objets possèdent évidemment un paramètre template de type VciParams?.

4 Outillage logiciel

Dans cette section, on présente différentes classes C++ définies par la plate-forme de prototypage virtuel SoCLib pour faciliter et simplifier l'écriture des modèles de simulation.

4.1 Indexation des composants VCI

On assigne à tout composant matérielpossédant un port VCI (composant cible ou composant initiateur) un index permettant de l'identifier de façon unique. Cet index peut être éventuellement structuré (on parle d'index composite) si l'architecture est structurée clusters. Un index composite est la concaténation d'un index global (le numéro de cluster) et d'un index local (à l'intérieur d'un cluster).

La plate-forme SoCLib définit la classe C++ IntTab pour représenter ces index composites. (voir fichier int_tab.h). Dans ce TP, on utilisera un seul niveau d'indexation, mais il faut utiliser l'objet IntTab pour indexer les composants VCI.

4.2 Segmentation de l'espace addressable

Dans une architecture à mémoire partagée, on assigne à tout composant cible un (ou plusieurs) segment(s) dans l'espace adressable. Un segment est une tranche" de l'espace adressable. Il possède donc une adresse de base, et une taille (en nombre d'octets). La taille d'un segment peut être très variable : de quelques d'octets pour un périphériques adressable, à quelques Moctets pour un contrôleur mémoire. C'est en analysant les bits de poids fort de l'adresse que le sous-système d'interconnexion détermine à quel segment appartient l'adresse, et donc vers quelle cible un paquet commande doit être aiguillé. Le découpage de l'espace adressable en segments et l'assignation de ces segments aux différentes cibles est donc un caractéristique globale de l'architecture, et doit donc être définie dans la top-cell décrivant l'architecture générale du système.

La plate-forme SoCLib définit la classe C++ MappingTable permettant de centraliser dans un même objet toutes les informations concernant la segmentation de l'espace addressable, et la correspondance entre les cible VCI (identifiées par leur index), et les segments. (voir fichiers mapping_table.h et segment.h).

Un segment est caractérisé par 5 informations :

  • un nom
  • une adresse de base
  • une taille (en octets)
  • l'index de la cible VCI à laquelle il est assigné
  • un attribut de cachabilité

Pour plus de détails, vous pouvez consulter le site WEB du projet SoCLib : https://www.soclib.fr/trac/dev/wiki/Component/MappingTable.

4.3 Décodage des champs ADDRESS et SRCID

Dans une architecture à mémoire partagée, l'adresse VCI est décodée à différents endroits : les bits de poids faibles sont décodés par les périphériques adressables pour déterminer l'action à réaliser, et les bits de poids fort sont décodés par le sous-système d'interconnexion pour déterminer l'index de la cible concernée. Pour faciliter ce décodage, la plate-forme SoCLib définit la classe C++ AddressDecodingTable (voir fichier address_decoding_table.h).

4.4 Allocation de tableaux

On a parfois besoin d'utiliser des tableaux d'objets complexes. Par exemple, le composant VciVgsb possède un nombre variable de ports VCI initiateur, et un nombre variable de ports VCI cibles. Ces ports sont donc définis comme des tableaux de ports. Pour pouvoir nommer chacun des éléments d'un tableau, la plate-forme SoCLib définit un mécanisme générique d'allocation et de désallocation de tableaux (voir fichier alloc_elems.h).

5 Travail à réaliser

L'archive attachement:soclib_tp2.tgz contient différents fichiers dont vous aurez besoin pour ce TP. Créez un répertoire de travail spécifique TP2, recopiez l'archive dans ce répertoire TP2, et décompressez-la:

$ tar xzvf soclib_tp2.tgz

Cette archive contient les fichiers généraux suivants, extraits de la plate-forme SoCLib :

  • vci_param.h : definition des paramètres VCI.
  • vci_signals.h : definition d'un canal VCI.
  • vci_initiator.h : définition d'un port VCI initiateur.
  • vci_target.h : définition d'un port VCI cible.
  • int_tab.h : définition des index composites.
  • segment.h : définition d'un segment de l'espace adressable.
  • segment.cpp : implémentation des méthodes du segment.
  • mapping_table.h : définition de la mapping table.
  • mapping_table.cpp : implémentation des méthodes de la mapping table.
  • address_decoding_table.h : Table indexée par une partie de l'adresse.
  • address_decoding_table.cpp : implémentation des méthodes de la table indexée.
  • alloc_elems.h" : allocation de tableaux d'objets complexes

L'archive contient également les fichiers suivants :

  • vci_lcd_master.h : définition du composant VciLcdMaster (fichier complet)
  • vci_lcd_master.cpp : méthodes associées (fichier incomplet)
  • vci_lcd_coprocessor.h : définition du composant VciLcdCoprocessor. (fichier complet)
  • vci_lcd_coprocessor.cpp : méthodes associées (fichier incomplet)
  • vci_gsb.h : définition du composant VciGsb. (fichier complet)
  • vci_gsb.cpp : méthodes associées (fichier complet)
  • tp2_simple_top.cpp : top-cell d'une architecture simple à deux composants (fichier incomplet)

5.1 Composant VciLcdCoprocessor

Le composant VciLcdCoprocessor se comporte comme un périphérique adressable, et doit donc être modélisé comme une cible VCI. Il possède un seul port de type VciTarget, et 4 registres (ou pseudo-registres) implantés dans l'espace addressable, qui peuvent donc - en principe - être lus ou écrits par n'importe quel initiateur du sytème. Chacun de ces registres a une largeur de 4 octets. Par conséquent, le segment occupé par ce périphérique dans l'espace adressable a une taille de 4*4 = 16octets.

Pour simplifier le décodage des adresses, on impose la contrainte que l'adresse de base de ce segment est un multiple de sa longueur (on dit que le segment est aligné). La carte d'implantation des registres est définit comme suit :

Nom du registre Offset Mode
r_opa 0x0 Write Only
r_opb 0x4 Write Only
r_start 0x8 Write Only
r_res 0xc Read Only

Attention : Il n'existe pas réellement de registre r_start dans le composant matériel. Lorsque le composant VciLcdCoprocessor reçoit une commande d'écriture à l'adresse correspondant à l'adresse de r_start, la donnée WDATA correspondante n'est écrite nulle part, mais la commande est interprêtée par le coprocesseur comme un ordre de démarrage du calcul.

Une erreur est signalée si le coprocesseur reçoit une commande de longueur supérieure à un mot, ou si l'adresse reçue n'appartient pas au segment qui a été défini pour le coprocesseur, ou si le mode d'accès (Read ou Write) ne respecte pas les contraintes ci-dessus.

Question : comment sont traitées les erreurs dans ce modèle de simulation? à quoi servent ces vérifications ?

La figure ci-dessous décrit la structure de l'automate de contrôle du composant VciLcdCoprocessor.

Le fichier vci_lcd_coprocessor.h contient une définition complête du composant VciLcdCoprocessor. Il n'a pas besoin d'être modifié, mais vous aurez besoin de le lire attentivement pour modifier le fichier vci_lcd_coprocessor.cpp, qui contient une description incomplête des méthodes associées à ce composant. Complêtez le code des méthodes transition() et genMoore().

5.2 Composant VciLcdMaster

Le composant VciLcdMaster est un initiateur VCI, qui exécute une boucle infinie dans laquelle il exécute successivement les 6 actions suivantes:

  1. calcul de deux valeurs aléatoires (entiers positifs codés sur 32 bits)
  2. écriture de l'opérande OPA dans le registre r_opa du coprocesseur LCD.
  3. écriture de l'opérande OPB dans le registre r_opb du coprocesseur LCD.
  4. écriture dans le pseudo-registre r_start du coprocesseur LCD.
  5. lecture du résultat dans le registre r_res du coprocesseur LCD.
  6. affichage des résultats.

Pour accéder au coprocesseur LCD, le composant a besoin de l'adresse de base du segment de l'espace adressable aui a été assigné au coprocesseur LCD. Le composant VciLcdMaster étant un automate cablé (non programmable), on considère que cette adresse est également "cablée". Elle est donc définie comme un paramètre du constructeur. La figure ci-dessous décrit la structure de l'automate de contrôle du composant VciLcdMaster.

Chaque transaction VCI nécessite deux états dans l'automate: un premier état pour envoyer la commande (on reste dans cet état tant qu'on a pas reçu confirmation que la commande a été acceptée), et un second état dans lequel on attend la réponse (on reste dans cet état tant qu'on a pas reçu une réponse valide).

Le fichier vci_lcd_coprocessor.h contient une description complête du composant VciLcdMaster. Il n'a pas besoin d'être modifié, mais vous devez le lire attentivement pour modifier le fichier vci_lcd_coprocessor.cpp, qui contient une description incomplête des méthodes associées à ce composant. Complêtez le code des méthodes transition() et genMoore().

5.3 Architecture minimale

Pour valider les modèles de simulation des composants VciLcdMaster et VciLcdCoprocessor, on construit une architecture minimale ne contenant que deux composants matériels, conformément au schéma ci-dessous :

En vous inspirant de ce que vous avez fait dans le TP1, complétez le fichier tp2_simple_top.cpp qui vous est fourni, en précisant

  • les valeurs des paramètres VCI.
  • les caractéristiques du segment mémoire associé au coprocesseur LCD.
  • les valeurs des arguments des constructeurs des deux composants.

5.4 Compilation et génération du simulateur

Il faut ensuite compiler les différents fichiers pour générer le simulateur.

5.5 Architecture multi-maitres

En vous inspirant du fichier tp2_simple_top.cpp de la question précédente, écrivez le fichier tp2_multi_top.cpp, qui décrit l'architecture à 7 composants décrite au début de ce TP. Vous ferez en sorte que le maitre (i) communique avec le coprocesseur (i). N'oubliez pas de définir 3 segments différents pour les trois coprocesseurs.

6. Compte-rendu

Il ne vous est pas demandé de compte-rendu pour ce TP, mais on vous demandera une démonstration de votre simulateur au début du TP de la semaine suivante...

Attachments (8)

Download all attachments as: .zip