Pour faciliter le développement du modèle de votre SoC, nous vous proposons un module réutilisable permettant d’initier des requêtes “maitre” sur le bus Wishbone.
Ce module peut être ajouté à un module SystemC pour contrôler une interface maitre Wishbone. Il contient ainsi la machine à état permettant de générer des requêtes unitaires ou par bloc de lecture et d’écriture.
Attention vous n’êtes pas obligés d’utiliser systématiquement ce module. Il est parfois plus simple de réécrire la séquence d’une requête Wishbone.
De plus ce module fait appel à des fonctions bloquantes de
SystemC et ne peut donc être utilisé que dans des
SC_THREAD.
Le code de ce module se trouve dans le dossier:
IPs/wb_master_fsmWbMasterFsm (
sc_in<bool> &p_clk,
WbMaster<wb_param> &p_wb
);Les arguments passés au constructeur sont:
p_wbp_clk correspondant à
l’horlogeCe module va manipuler les signaux connectés à un port Wishbone maitre, les arguments sont passés par référence pour pouvoir y accéder directement.
Ce module n’est pas un module SystemC, pour être utilisé, doit d’abord être instancié dans un module SystemC.
Une fois instancié, vous pouvez initier des requêtes sur le bus en utilisant les méthodes suivantes. Les Requêtes se font sur des mots de 32 bits.
uint32_t wb_read_at (
uint32_t addr // 32-bit address
);void wb_write_at (
uint32_t addr, // 32-bit address
uint8_t mask, // 4-bit mask
uint32_t data // 32-bit data
);void wb_read_blk (
uint32_t saddr, // 32-bit start address
uint32_t num , // number of 32-bit transactions
uint8_t *dest // pointer to the destination byte buffer
);ATTENTION: dest doit pointer vers une
zone allouée au préalable. La taille de la zone allouée doit être de 4
fois le nombre de requêtes.
Pour être compatible avec l’endianness du LM32, les octets sont stockés dans l’ordre big-endian.
void wb_write_blk (
uint32_t saddr, // 32-bit start address
uint8_t *mask, // pointer to the data masks
uint8_t *data, // pointer data byte buffer
uint32_t num // number of 32-bit transactions
);Remarque Si le pointeur de masque mask est égal
NULL, tous les masques sont mis à 0xF. Tous
les octets sont donc modifiés.
Un exemple d’utilisation est disponible dans le dossier:
IPs/dummy_wb_masterVoici les principales étapes pour utiliser le module dans l’exemple:
Dans le fichier d’en-tête dummy_wb_master.h nous
avons:
WbMasterFsm master0;Dans le fichier d’implémentation dummy_wb_master.cpp
nous avons:
DummyWbMaster (sc_module_name name ) : ...
master0(p_clk,p_wb)// Écrire 0xC01dCafe à l'adresse 0x40000000 avec le masque d'octets 0xF
master0.wb_write_at(0x40000000,0xf,0xC01dCafe);
// Lire la donnée se trouvant à l'adresse 0x40000000
val = master0.wb_read_at(0x40000000);
// Écrire consécutivement 20 mots de 32bits
// DATA pointe vers un buffer contenant au minimum 20x4 octets
// MASK pointe vers les 20 masques correspondants
master0.wb_write_blk(0x40000000,MASK,DATA,20);
// Écrire consécutivement 20 mots de 32bits avec un masque égale à 0xF
master0.wb_write_blk(0x40000000,NULL,DATA,20);
// Lire 20 mots de 32 bits
// Le résultat est stocké dans la zone pointée par RDATA
// RDATA pointe vers une zone pré-allouée pouvant contenir 4x20 octets
// Les octets sont organisés dans l'ordre big-endian
master0.wb_read_blk(0x40000000,20,RDATA)Pour tester l’ensemble, vous pouvez instancier le module
DummyWbMaster dans votre modèle de SoC et observer, par
exemple, les différences entre les requêtes simples et les requêtes par
bloc.