La partie matérielle du système est décrite dans le fichier C++ top.cpp
Le SoC contient deux types de modules:
L’interface utilisée par la majorité des modules de SocLib est une interface VCI. Elle fonctionne sur le principe de requêtes/réponses dissociées:
Dans les modèles SystemC de la bibliothèque SocLib, cette interface est paramétrable. Pour le HelloWorld, nous avons une interface 32 bits données/adresse avec jusqu’à 256 initiateurs sans modes spéciaux d’adressage.
La structure VciParams, regroupe ces paramètres et sert
de "template" aux modules utilisant l’interface VCI.
typedef soclib::caba::VciParams<4,8,32,1,1,1,8,1,1,1> vci_param;Avec dans l’ordre:
cell_size : taille de la cellule 4(octets) =>
interface 32 bitsplen_size : la taille des paquets (transferts
multiples/bursts) est codée sur 8 bitsaddr_size : la taille du bus d’adresse est de 32
bitsrerror_size: les messages d’erreurs codés sur 1 bit
(erreur ou ok)clen_size : nombre de paquets dans une chaine codée sur
1 bitrflag_size : les indicateurs d’erreur sont codés sur 1
bitsrcid_size : l’identifiant des sources est codé sur
8bits (jusqu’à 256 initiateurs)pktid_size : l’identifiant des paquets est sur
1bittrdid_size : l’identifiant des threads est sur
1bitwrplen_size: le dernier paramètre correspond à
l’adressage circulaire des burstsLa structure vci_param est en suite utilisée pour
paramétrer tous les modules et interfaces VCI.
Par exemple, la définition du signal VCI servant à connecter la mémoire ROM:
soclib::caba::VciSignals signal_vci_rom("signal_vci_vcirom");C’est l’interface que vous utiliserez pour vos périphériques. Son fonctionnement est plus simple que celui du VCI les requêtes sont bloquantes jusqu’à l’acquittement.
L’interface WishBone peut aussi être paramétrée en définissant la largeur du bus de données et du bus d’adresses. Pour le helloworld, les données et les adresses font 32 bits.
typedef soclib::caba::WbParams<32,32> wb_param;wb_data_width : largeur du bus de donnéeswb_addr_width : largeur du bus d’adressesComme pour les paramètres VCI , les paramètres WishBone sont ensuite utilisés pour tous les signaux et toutes les interfaces WishBone.
Par exemple, le signal servant à connecter le processeur au bus:
soclib::caba::WbSignal<wb_param> signal_wb_lm32("signal_wb_lm32");La table d’adressage permet de décrire les plages de l’espace mémoire réservée à chaque élément du système. C’est un module pour la "simulation" qui permet de vérifier qu’il n’y a pas d’incohérence dans les adresses des différents modules. Il permet aussi de centraliser ces informations.
La table prend 4 arguments à la construction:
soclib::common::MappingTable maptab(32, IntTab(8), IntTab(8), 0x80000000);Dans cet exemple nous utilisons 32 bits pour les adresses dont les 8 bits de poids fort permettent d’identifier les cibles/esclaves. Si le bit 31 de l’adresse est non nul alors les requêtes vers cette plage mémoire ne passent pas par le cache du processeur.
On ajoute à cette table des segments correspondants aux cibles/esclave. On précise un nom, une adresse de base, une taille, un index et un indicateur de "cachabilité" (cet index doit être cohérent avec le masque donné à la définition de la table)
maptab.add(Segment("rom" , ROM_BASE , ROM_SIZE , IntTab(0), true));Dans cet exemple, on définit un segment correspondant à la mémoire
ROM. Le nom de ce segment est "rom", son
adresse de base est ROM_BASE et sa taille est
ROM_SIZE. Il sera identifié comme la cible "0" et les
requêtes vers cette ROM passeront par le cache du processeur.
Toutes les requêtes à faite une adresse appartenant à l’intervalle
[ROM_BASE, ROM_BASE+ROM_SIZE] seront transmise au
contrôleur de ROM.
Les constantes utilisées sont toutes définies dans le fichier
segmentation.h. Ainsi, nous pouvons avoir un fichier unique
décrivant la carte mémoire (map) qui pourra être utilisé pour
le logiciel embarqué.
La cohérence de cette table est vérifiée avant le début de la simulation.
Nous disposons d’un ISS (Instruction Set Simulator) qui permet de simuler l’exécution d’un flot d’instruction sur un lm32.
Cet ISS est n’est pas un module C++, il n’est donc pas instancié
directement dans la plateforme. La bibliothèque SocLib propose des
modules génériques (des wrappers d’iss) avec des
configurations de cache et des interfaces différentes qui permettent
d’encapsuler les ISS. Ces Wrappers permettent de simuler indifféremment
un mips, un sparc ou un lm32… Le code responsable de la gestion du
cache, et des entrées/sorties des processeurs est ainsi mutualisé.
Ici, comme nous allons travailler avec l’interface WishBone et que
notre CPU a une cache, nous utilisons le
WbXcacheWrapper.
soclib::caba::WbXcacheWrapper
<wb_param, soclib::common::Iss2Simhelper<soclib::common::LM32Iss<false> > >
lm32("lm32", 0, maptab,IntTab(0), 2,128,8, 2,128,8);Dans cet exemple on construit un modèle de LM32 avec les paramètres suivants:
lm32"false" indique que
le lm32 est big endian contrairement à la convention SocLib.Nous utiliseront le WbInterc (WishBone interconnect). Ce
module simule le comportement d’une interconnexion à bus multiplexé avec
arbitrage à priorité tournante (round robin) .
soclib::caba::WbInterco<wb_param> wbinterco("wbinterco",maptab, 1, 3);Les paramètres du constructeur sont:
Le WbInterco possède, en plus d’un port d’horloge
(p_clk) et d’un port de remisee à zéro
(p_resetn), un port pour relier les maîtres
(p_from_master) et les esclaves (p_to_slave).
Ces deux derniers ports sont des vecteurs où l’indice de chaque
connexion doit correspondre à l’indice du périphérique dans la table
d’adressage. Ces ports sont reliés à des signaux WishBone qui sont
reliés aux ports des éléments respectifs.
wbinterco.p_clk(signal_clk);
wbinterco.p_resetn(signal_resetn);
wbinterco.p_from_master[0](signal_wb_lm32);
wbinterco.p_to_slave[0](signal_wb_rom);
wbinterco.p_to_slave[1](signal_wb_ram);Ici, nous avons le signal venant du lm32 relié au port maître 0, la rom au port esclave 0 et la ram au port esclave 1.
Les éléments VCI ne peuvent pas être connectés directement au bus WishBone. Nous devons utiliser un adaptateur (wrapper) qui converti les requêtes venant des maîtres WishBone en transaction VCI.
Ce wrapper se comporte comme esclave WishBone et maître VCI. Il
possède un port d’horloge (p_clk), un port de reset
(p_resetn), un port WishBone esclave pour se connecter à
l’interconnect et un port VCI maître pour se connecter au module
VCI.
soclib::caba::WbSlaveVciInitiatorWrapper<vci_param, wb_param> tty_w ("tty_w") ;
tty_w.p_clk (signal_clk);
tty_w.p_resetn (signal_resetn);
tty_w.p_vci (signal_vci_tty); // Vers le module tty
tty_w.p_wb (signal_wb_tty); // Vers WbIntercoLe wrapper a comme arguments de template les paramètres WishBone et VCI et comme argument de constructeur le nom du module SystemC.
La simulation est initiée en utilisant la fonction sc_start().
sc_start(SC_ZERO_TIME); // démarre la simulation mais ne fait pas avancer le temps
signal_resetn = false; // Remise à zéro du système
sc_start(sc_core::sc_time(1, SC_NS)); // avance la simulation de "1ns"
signal_resetn = true; // Fin de la remise à zéro du système
sc_start(); // lance la simulation
// La simulation s'arrêtera à l'appel de sc_stop()