SystemC Conception conjointe au niveau système

publicité
Chapter 1: SystemC,
Joined design at system level
(based on SystemC 2.2)
B. Miramond
M2 – S2IC/ESA
B. Miramond - UCP
Plan du chapitre
I.
II.
III.
IV.
Introduction
Programmer en SystemC
Noyau de simulation
Niveaux d’abstraction :
une méthodologie de conception
VI. Modélisation matérielle en SystemC
VII. Modélisation TLM
VIII. Concepts avancés
B. Miramond - UCP
(30min)
(1h30)
(1h)
(30min)
(30min)
(1h)
(30min)
I.
SystemC …
What else ?
B. Miramond - UCP
Plan de la section I
1.
2.
3.
4.
5.
6.
Motivations
Historique
Qu’est ce que SystemC
Les concurrents
Les librairies SystemC
Quelques définitions pour démarrer
B. Miramond - UCP
1) Motivations




Changement d’échelle : conception de «systèmes» sur puce.
Sur des technos plus anciennes, la conception reliait un
microprocesseur, une mémoire et un ASIC (accélérateurs
matériels).
Des experts réalisaient alors le partitionnement de
l’application entre les parties logicielles et matérielles.
Pour la partie Hw, la spécification des ASICs correspondait
à qqs milliers de portes. Ce qui restait exprimable dans un
langage HDL à un niveau RTL.
RTL : Register Transfer Level
B. Miramond - UCP
Register Tranfer Level
A legacy from HDL

RTL description is a way of describing the operation of
a synchronous digital circuit. In RTL design, a circuit's
behavior is defined in terms of the flow of signals (or
transfer of data) between hardware registers, and the
logical operations performed on those signals.
Vhdl
process(clk)
begin
if rising_edge(clk)
then Q <= not Q;
end if;
end process;
The term refers to the fact that RTL focuses on describing
the flow of signals between registers
B. Miramond - UCP
Et maintenant …

Aujourd’hui, la technologie des SoCs autorise la
présence de







plusieurs proc., microcontrôleurs 32 bits ou DSP.
On-chip memory
Accélérateurs matériels pour fonctions dédiées
Contrôleurs de périphériques
Le tout relié par un réseau complexe de communication.
A ce niveau de complexité, le partitionnement n’est plus
évident entre logiciel et matériel.
La conception matérielle s’exprime en millions de
portes.
B. Miramond - UCP
SoC Architecture
Debug
port
JTAG
ARM 946E
core
Arbiter
Bridge
Timer
ICache
Boot ROM
DCache
SDRAM/Flash
Multiport memory
HW coprocessor
RISC core
DMA Controler
UART
RAM
Arbiter
B. Miramond - UCP
DSP
ADC/DAC
Conception cost evolution
System Level Methodology
Intelligent Testbecnh
Large block Reuse
$ 10.000.000.000
Small thin Eng.
In House P&R
$ 100.000.000.000
Small block Reuse
Conception cost
IC Implementatrion
[Roadmap for Semiconductors 2001]
predicted
measured
$ 1.000.000.000
$ 100.000.000
$ 10.000.000
1985
1990
1995
2000
B. Miramond - UCP
2005
2010
2015
2020
Conception niveau système




La prise de décision de l’implantation est
repoussée car elle doit être explorée.
Donc, pour décrire des systèmes encore à la fois
logiciels et matériels il faut aller au-delà du
niveau RTL, et à ce niveau les HDLs ne sont
plus adaptés.
On parle de conception au niveau système.
Et du besoin de langage de modélisation
supportant ce niveau.
B. Miramond - UCP
2) Positionnement du langage
Requirements
Matlab,
SPW,
S. Studio
Specifications
HW/SW
Behavior
SystemC
Functional
Verification
Test bench
RTL
Verilog
VHDL
System
Verilog
Gates
Transistor
B. Miramond - UCP
Objectifs


Environnement unifié de description matériel et
logiciel
Explorer les solutions de conception en
travaillant à un niveau système
=> Améliorer la productivité des concepteurs de
systèmes électroniques.
B. Miramond - UCP
3) Donc qu’est ce que SystemC ?

SystemC est un langage de modélisation au niveau système



Réseau de processus communiquant (HDL)
Supportant différents modèles de traitements (MoCs)
Permettant de modéliser des systèmes logiciels et matériels

C’est aussi un environnement de simulation temporelle (eventdriven simulation, cf. HDL).

Basé sur une librairie de classes C++


Open Source
SystemC n’est pas une méthodologie, mais vous avez besoin
d’une méthodologie pour l’utiliser !
B. Miramond - UCP
Méthodologie de conception
Spécifications
Software (C/C++)
Cosimulation
Modèle TLM
Environnement
de test
(SystemC)
Modèle RTL
(HDL/SystemC)
Synthèse
Portes
Layout
Software
Hardware
B. Miramond - UCP
Testbench
Quelques définitions



Niveau d’abstraction = est un niveau de description
d’un système apportant un niveau de détails données.
Un flot de conception est une succession de niveaux
d’abstraction.
Raffinement = Le raffinement est le mécanisme
permettant de passer d’un niveau d’abstraction à un
autre. Celui-ci doit être le plus possible automatisable.
Spécification exécutable = est un modèle fonctionnel
qui fournit le comportement d’un composant quelque
soit le niveau d’abstraction et de manière indépendante
de l’implémentation (plateforme).
B. Miramond - UCP
Caractéristiques du langage SystemC
1.
2.
3.
4.
5.
6.
Spécification et conception à différents niveaux
d’abstraction
Intégration de portions de logiciel embarqué, à la fois
sous la forme de modèles et de code : réutilisation,
Création de spécification exécutables.
Création de plateformes exécutables sur lesquelles
seront mappées les spécifications.
Simulations rapides pour permettre l’exploration de
l’espace de conception (spécifications + plateformes)
Structuration des modèles autorisant la séparation de la
fonctionnalité et de la communication


Adaptation flexible (IPs)
Besoin de réutilisation
B. Miramond - UCP
Propriétés supplémentaires


Basé sur un langage de programmation existant
pour bénéficier des outils de compilation, de
debug, …
Un langage orienté objet fournirait les
mécanismes de base pour la flexibilité des
modèles et la réutilisation. (héritage,
templates…)
B. Miramond - UCP
4) Historique
Synopsys- SCENIC
LWG / OSCI
Adelante AJRT Lib
Fixed Point Types
IMEC
CoWare N2C
SystemC 1.0
Master-Slave Lib
SystemC 1.2.1 Beta
Channels
SystemC 2.0
Bug fix
SystemC 2.0.1
Dynamic Processes
SystemC 2.1 puis 2.2
RTOS / Software
SystemC
3.0
B. Miramond - UCP
Future
4) Les concurrents
Sur le créneau de la modélisation niveau système :
 SpecC – D. Gajski de l’Université de Irvine


OCAPI - IMEC


http://www.imec.be/design/ocapi/unified_design.shtml
Cynlib – CynApps


http://www.ics.uci.edu/~specc/
http://www.forteds.com/technology/esl2gdsii.asp
…
B. Miramond - UCP
5) Librairies SystemC (sup.)

The SystemC Verification Library (SCV)





Architecture Description Language : ArchC



Extension de SystemC pour la description de processeurs
http://www.archc.org
Master/Slave library



Ajoute de fonctionnalités pour la vérification des design (Cadence)
Langage de développement de testbench (Testbuilder)
Constrained randomization, introspection, transaction recording
http://www.testbuilder.net
Protocole de communication
http://www.systemc.org
The Boost Library (C++)


Free peer-reviewed portable C++ source libraries
http://www.boost.org
B. Miramond - UCP
Bibliographie
Books
 System Design with SystemC (4th edition), Grötker et al., Kluwer Academic
Publisher, 2004


From the ground-up (SystemC 2.1), D. Black & J. Donovan, Kluwer Academic
Publisher, 2005


Bib. Ensea, dispo
Transaction level modeling with SystemC : TLM concepts and applications for embedded
systems, by Frank Ghenassia, Springer 2005.


Ensea, emprunté
Bib. Ensea, dispo
SystemC kernel extensions for heterogeneous system modeling : a framework
for Multi-MoC modeling & simulation, by Hiren D. Patel and Sandeep K.
Shukla, 2004

Ensea, dispo
Weblinks
 http://www.systemc.org
B. Miramond - UCP
I. Programmer en
SystemC
B. Miramond - UCP
Plan de partie II
Architecture du langage
Les structures
1.
2.
1.
1.
2.
3.
4.
Port
Channels
Interfaces
Hierarchical Channels
Processus
Évènements
4.
5.
1.
2.
sc_events
notification
Sensibilité
1.
2.
sc_module
Ports, Channels et
Interfaces
3.
1.
3.
4.
2.
3.
4.
Statique
Dynamique
Composition d’évènements
Timeout
Exemple de synthèse
Quelques exemples
supplémentaires
Debugging
1.
2.
3.
4.
B. Miramond - UCP
Debug Environnement
Testbench results
Waveform tracing
Resulting waveforms
1. Architecture du langage

http://www.systemc.org


Librairies SystemC téléchargeables gratuitement
European SystemC Users Group

http://www-ti.informatik.uni-tuebingen.de/~systemc
B. Miramond - UCP
Methodology Specific
Libraries
Standard Channels
Kahn Process Network, Static Dataflow,
Etc.
Master/Slave Library, etc.
Elementary Channels
Signal, Timer, Mutex, FIFO…
Core Language
Data-Types
Modules
Ports
Processes
Events
Interfaces
Channels
4-valued logic types (O1XZ)
4valued logic vectors
Bits and bit-vectors
Arbitrary-precision integers
Fixed point numbers
C++ user-defined types
Event-driven simulation Kernel
C++ Language Standard
B. Miramond - UCP
Architecture de SystemC
User Applications
Methodology Specific
Libraries
Standard Channels
Kahn Process Network, Static Dataflow,
Dataflow,
Etc.
Master/Slave Library, etc.
Elementary Channels
Signal, Timer, Mutex, FIFO…
Core Language
Data-Types
Modules
Ports
Processes
Events
Interfaces
Channels
4-valued logic types (O1XZ)
4valued logic vectors
Bits and bit-vectors
Arbitrary-precision integers
Fixed point numbers
C++ user-defined types
Event-driven simulation Kernel
C++ Language Standard
WorkStation Environment
B. Miramond - UCP
SystemC
Standard
Compilation d’un projet SystemC

g++ -I$ (SYSTEMC) /include \
-L$ (SYSTEMC) /lib-$ (ARCH) –lsystemc \
$(SRC)
systemc
Le résultat contient à la fois votre code
applicatif et le code de la machine de
simulation SystemC !!
File1.h
File1.cpp
…
Filen.h
Filen.cpp
systemc.h
g++
File1.o
…
Filen.o
B. Miramond - UCP
STL
…
ld
.exe
2. Structures




 Processes (Concurrency)
Modules (Structure)
Channels (Communication)
Séparées  Events (time,
synchronisation)
Port
(Structure)
 Data types (Hardware,
Fonctionnalité
Communication
Interfaces
(Communication
/ Traitement
refinement)
fixed point)
Port
Module
Process 1
Module
Channel
Interface
B. Miramond - UCP
P2
P3
a. Modules


sc_module
Un module est un conteneur (container).
Il contient :
Des ports qui permettent de communiquer avec
d’autres modules
 Des processus qui décrivent la fonctionnalité du
module
 Des données internes représentant l’état et des
canaux internes pour la communication entre les
processus du module
 Et hiérarchiquement, d’autres modules

B. Miramond - UCP
Déclaration par la macro
SC_MODULE
class Adder : public sc_module {
// Ports, processes, internal data …
Adder (sc_module_name name, int other_param) : sc_module(name){
// Body of constructor :
// Process declaration, sensitivities
}
};



Cette déclaration crée une nouvelle classe d’objets de type Adder.
Les définition sont réalisées dans des fichier .CPP.
Les déclaration dans des fichiers .H
B. Miramond - UCP
Instanciation de SC_MODULE
Les SC_MODULE peuvent être instanciés
 lors de la phase d’élaboration uniquement (cf. section III)
 En précisant un nom de module
 Avec la syntaxe suivante :
Adder MyAdder(‘’MyAdder’’);
B. Miramond - UCP
3. Interfaces, Ports et channels



En modélisation matériel classique (RTL), le signal est le
moyen de communication entre processus.
Au niveau système, le moyen de communication n’a pas
encore d’implantation établie (bus Hw, appel de service
logiciel comme FIFO, mutex…).
SystemC offre cette flexibilité par la séparation entre



Les canaux qui sont le moyen de transmission des données
Les interfaces qui fournissent les prototypes des services
d’accès au canal
Les ports qui sont une instanciation des interfaces dans un
module client.
B. Miramond - UCP
a. Interfaces


Un canal exporte son interface à travers la classe abstraite
sc_interface.
L’interface spécifie donc uniquement la signature (le
prototype) des opérations/services fournies par son
canal.
Rappel :
 Les sc_interface sont des classes templates C++. Une
classe template permet de paramétrer le type des données
qu’elle manipule en placant le type entre ‘<T>’.
B. Miramond - UCP
Exemple
sc_signal_in_if<T>
Dérive directement de sc_interface et est paramétrée par
le type T.
Elle ne fournit qu’un seul service : read() qui retourne une
référence à la valeur de type T.
 sc_signal_inout_if<T>
Celle-ci fournit en plus une fonction virtuelle write() qui
prend en paramètre la valeur à placer.
Cette seconde interface dérive de sc_signal_in_if et hérite
donc de la fonction read().

B. Miramond - UCP
sc_interface
register_port()
(virtual)
sc_signal_in_if<T>
read()
sc_signal_inout_if<T>
write()
B. Miramond - UCP
class sc_signal_in_if :
virtual public sc_interface
{
public :
virtual const T& read() = 0;
}
sc_signal est utilisé
pour la
communication à
l’intérieur d’un
module entre
processus.
Built-in primitive Channels



sc_signal<int> S1, S2;
sc_buffer<T> B;
sc_fifo<T> F;

sc_mutex M;
sc_semaphore P(1);

S1.write(S2.read());

// déclaration
// Affectation
B. Miramond - UCP
b. Ports



Les ports sont utilisés comme déclaration de connexion
à un canal via son interface.
La déclaration doit spécifier l’interface à laquelle il
correspond.
Déclaration




sc_port<sc_signal_inout_if<int> > p;
p->read();
p->write();
Ceci est un exemple d’IMC (Interface Method Call).
B. Miramond - UCP
Ports prédéfinis dans SystemC
Template <class T>
class sc_in :
public sc_port<sc_signal_in_if<T> > …;
Template <class T>
class sc_inout :
public sc_port<sc_signal_inout_if<T> > …;
B. Miramond - UCP
Exemple (suite)
Adder
class Adder : public sc_module {
// Ports, processes, internal data …
sc_in <int> a;
sc_in <int> b;
sc_in <int> c;
Adder (sc_module_name name, int
other_param) : sc_module(name){
// Body of constructor :
// Process declaration, sensitivities
}
};
La déclaration des ports
doit intervenir en
premier dans le
module!!
Et l’ordre a une
importance.
B. Miramond - UCP
c. Channels




sc_channel
Alors que les ports et interfaces définissent
quelles fonctions sont disponibles, le canal décrit
l’implémentation de ces fonctions.
Tous les canaux héritent de
sc_prime_channel.
La classe canal doit gérer les accès multiples (tel
que sur un bus).
Ses méthodes d’accès suivent un schéma dit :
Request-Update
B. Miramond - UCP
d. Hierarchical Channels



Plusieurs canaux peuvent implémenter la même interface.
Ainsi, un ‘primitive channel’ ne contient pas d’autres
structures SystemC (modules, process…).
Au contraire, il est parfois nécessaire de modéliser des
structures de communication plus complexes :

Le standard OCB = On-Chip Bus de VSIA :
Arbitrer
Control Program
Unit
Decoder
Unit
L’avantage des ports et interfaces est donc clair, ils permettent de
découpler l’interface de son implémentation et donc de raffiner les
communications (par ex.) d’un B.canal
simple
à un canal hiérarchique.
Miramond
- UCP
4. Processus




Process
La nature parallèle des systèmes électronique
nécessite la description de fonctionnalités
concurrentes.
A process SystemC doit être contenu dans un
module.
Le code associé au process doit être une
fonction membre du SC_MODULE
Les processus accèdent aux canaux extérieurs
par l’intermédiaire des ports de leur module.
B. Miramond - UCP
Exemple (suite)
Adder
class Adder : public sc_module {
// Ports, processes, internal data …
sc_in <int> a;
sc_in <int> b;
sc_out<int> c;
void compute (){
c = a + b;
}
SC_HAS_PROCESS(Adder);
Adder (sc_module_name name, int other_param) : sc_module(name){
// Process declaration, sensitivities
SC_METHOD(compute);
sensitive << a << b;
}
};
B. Miramond - UCP
Pièges




Le fait de déclarer une nouvelle méthode dans un
SC_MODULE ne fait pas d’elle un process.
C’est l’appel à SC_METHOD qui enregistre la
méthode en paramètre auprès du scheduler de
SystemC.
Cet enregistrement (l’appel à SC_METHOD) ne
peut être fait qu’à la phase d’élaboration, pas
pendant la simulation.
Les SC_METHOD ne peuvent être intérrompus, il
ne doivent donc pas contenir de boucle infinies !!
B. Miramond - UCP
Plusieurs sortes de process

SC_METHOD()




SC_THREAD()




Processus ne pouvant être interrompus (ils ne peuvent appelé wait())
Le code doit être fonction membre d’un SC_MODULE
Le plus rapide à la simulation.
Processus pouvant être interrompus (par wait)
Ses variables sont persistantes (contrairement au SC_METHOD)
Le code n’est pas nécessairement fonction membre du module
sc_spawn() // cf. Chapitres suivants


Autorise la création dynamique de processus, donc après la phase
d’élaboration.
Le code n’est pas nécessairement fonction membre du module
B. Miramond - UCP
Structure of a process
SC_METHOD : simulation engine call them repeatedly
void my_process (){ // run to completion scheme
// treatment
}
 SC_THREAD :
void my_thread(){
// infinite loop scheme
while (1){
// treatment
wait();
// static event
}
}

B. Miramond - UCP
5. Events




Un processus dispose d’une liste de sensibilité
décrivant les événements auxquels il doit réagir.
Lorsque l’exécution d’un processus rencontre un
wait(), il est interrompu.
Il attend le déclenchement (implicite) d’un des
évènements de sa liste de sensibilité statique.
Lorsqu’un de ses événements est déclenché, le
scheduler place le Thread dans la liste des
processus READY.
B. Miramond - UCP
a. sc_event

Un event est un objet de classe sc_event.



Il n’a ni durée, ni valeur.
L’acte d’indiquer une modification d’un évènement est
appelé notification.




sc_event e;
e.notify();
notify(e);
L’évènement garde une liste des processus qui lui sont
sensibles (par wait(e)).
Lorsque un event est notifié, il informe le scheduler des
processus à (re)lancer.
B. Miramond - UCP
b. Notification

Immediate : e.notify();


Delta_delay : e.notify(SC_ZERO_TIME);


Notification immédiate, le processus en attente est
replacé immédiatement dans la liste Ready
Notification après un cycle d’évaluation appelé
Delta-cycle, lorsque tous les processus en attente se
seront exécutés.
Non-zero delay : e.notify(t);

Place l’évènement en fil d’attente jusqu’à la durée
indiquée.
B. Miramond - UCP
6. Sensitivity

a. Sensibilité statique =



La liste des évènements d’activation d’un process est
déterminé avant la simulation (dans les constructeurs).
sensitive << a << b;
b. Sensibilité dynamique =



Permet de remplacer la liste statique par un évènement
désigné lors de la simulation.
Le processus n’est alors plus sensible aux évènements de sa
liste statique.
wait(e);
B. Miramond - UCP
Exemple (suite)
class Adder : public sc_module {
// Ports, processes, internal data …
sc_in <int> a;
sc_in <int> b;
sc_out<int> c;
Adder
Cas particulier :
Ici a et b sont des sc_ports.
void compute (){
La sensibilité se fait par
c = a + b;
l’intérmédiaire de la
}
fonction default_event
SC_HAS_PROCESS(Adder);
associée.
Adder (sc_module_name name) : sc_module(name){
// Process declaration, sensitivities
SC_METHOD(compute);
sensitive << a << b;
}
};
B. Miramond - UCP
c. Composition d’évènements

Conjonction :



wait (e1 & e2 & e3); ou wait (timeout | e1 | e2);
Activation si les 3 event sont déclenchés
Disjonction :




wait(e1 | e2 | e3); ou wait (timeout | e1 | e2);
Activation si 1 des 3 event est déclenché ou bien un timeout
Il n’est pas possible de savoir quel événement a provoqué le
déclenchement.
Par contre il est possible de savoir si c’est le timeout :


wait(t_Delay | ack_event | bus_error_event);
if (timed_out()) … // action associated to timeout
B. Miramond - UCP
d. Attente d’un TimeOut

Attente de 200 nanosecondes :
wait(200, SC_NS);
 Ou bien
 sc_time t(200, SC_NS);
 wait(t);


Attente d’un Delta-cycle :


wait(0);
Combinaisons event(s) | timeout:

wait(200, SC_NS, e);
B. Miramond - UCP
7. Final Example


A la manière des classes et des objets, les
modèles sont à opposés aux instances (de
modules et de canaux) en SystemC comme en
HDL.
Exemple hiérarchique :
in1
in2
Adder1
sum
Adder2
in3
Add3
B. Miramond - UCP
class Add3 : public sc_module {
sc_in<int>
in1;
sc_in<int>
in2;
sc_in<int>
in3;
sc_out<int>
sum;
in1
in2
sum
Adder2
in3
Add3
// signal (channel) interne
sc_signal<int>
Adder1
temp
temp;
Adder* adder1;
Adder* adder2;
Add3(sc_name name) : sc_module(name){
adder 1 = new Adder(‘’Adder1’’);
(*adder1)(in1, in2, temp);
// Connectique forme positionnelle
adder 2 = new Adder(‘’Adder2’’);
adder2->a(temp);
adder2->c(sum);
adder2->b(in3);
// Connectique forme nommée
// Pas d’ordre imposé
}
}
B. Miramond - UCP
int sc_main(int argc, char* argv[]){
// initialisation
// simulation
top_level();
// Nettoyage des structures
return 0;
}
temp
in1
in2
Adder1
sum
Adder2
in3
Add3
top_level(){
sc_signal <int> sig_a, sig_b, sig_c;
Add3 my_adder(‘’my_adder’’);
//Autres modules et tesbenchs qui positionnent
// les valeurs de sig_a et sig_b
//Lance la phase d’Elaboration puis celle de Simulation
//Exécution durant 1000 secondes (de temps de simulation)
sc_start(1000, SC_SEC);
//Suite de la simulation pendant 100 ms
sc_start(100, SC_MS);
}
B. Miramond - UCP
8. Debugging
#include “systemc.h“
Class nand2 : public sc_module
{
sc_port<sc_signal_in_if<bool>, 1> A;
sc_in<bool> B;
sc_out<bool> F;
A
//input signal port
//other writing
//output signal port
void do_nand2(){
F.write( !(A.read() && b.read()) );
}
SC_HAS_PROCESS(nand2);
nand2 (sc_name name) : sc_module(name){ // Constructor
SC_METHOD(do_nand2);// register do_nand2 with scheduler
sensitive << A << B;
}
};
B. Miramond - UCP
B
F
2-input xor
F = A ⊕ B = ( A + B).( A + B )
A
S2
F
S1
S3
B
B. Miramond - UCP
#include “systemc.h“
#include “nand2.h“
…
xor2(sc_name name) : n1(‘N1’), n2(‘N2’),
n3(‘N3’), n4(‘N4’)
class xor2 : public sc_module {
{
n1.A(A);
sc_in<bool> A, B;
n1.B(B);
sc_out<bool> F;
n1.F(S1);
nand2 n1, n2, n3, n4;
(*n2)(A, S1, S2);
sc_signal<bool> S1, S2, S3;
…
n3.A(S1);
n3.B(B);
n3.F(S3);
A
n4.A(S2);
n4.B(S3);
n4.F(F);
S2
F
S1
S3
}
B
};
B. Miramond - UCP
a. Debug Environnement
xor2
A
A
S2
Stimuli
Generator
F
S1
Monitor
S3
B
B
Clock
B. Miramond - UCP
CK
#include ‘’systemc.h’’
class stim : public sc_module{
sc_out<bool> A, B;
sc_in_clk Clk;
void StimGen(){
A.write(false);
B.write(false);
wait();
A.write(false);
B.write(true);
wait();
A.write(true);
B.write(false);
wait();
A.write(true);
B.write(true);
wait();
sc_stop();
}
SC_HAS_PROCESS(stim);
stim(sc_name name) : sc_module(name){
SC_THREAD(StimGen);
sensitive << Clk.pos();
}
};
#include ‘systemc.h’
#include <iomanip.h>
class monitor : public sc_module{
sc_in<bool> A,B, F;
sc_in<bool> Clk;
void do_monitor(){
cout << setw(10) << ‘time’;
cout << setw(2) << ‘A’;
// …
while(true){
cout << setw(10) << sc_time_stamp();
cout << setw(2) << A.read();
// …
wait();
}
}
SC_HAS_PROCESS(monitor);
monitor(sc_name name) : sc_module(name){
SC_THREAD(monitor):
sensitive << Clk.pos();
}
};
B. Miramond - UCP
b. Testbench results
#include ‘systemc.h’
#include ‘stim.h’
#include ‘exor2.h’
#include ‘mon.h’
int sc_main (…){
sc_signal<bool> ASig, BSig, FSig;
sc_clock TestClk(‘TestCk’, 10, SC_NS,
0,5);
stim Stim1(‘Stimulus’);
exor2 DUT(‘exor2’);
monitor Monitor1(‘Monitor’);
Time A B F
,,,,,,1 ns 0 0 0
11 ns 0 0 0
21 ns 0 1 1
31 ns 1 0 1
41 ns 1 1 0
// Connection with ASig, BSig et FSig
sc_start(); // run forever
return 0;
}
B. Miramond - UCP
#include ‘systemc.h’
#include ‘stim.h’
#include ‘exor2.h’
#include ‘mon.h’
c. Waveform
tracing
int sc_main(int argc, char *argv[]){
sc_signal<bool> ASig, BSig, FSig;
sc_clock TestClk(‘TestClock’, 10, SC_NS, 0,5, 1, SC_NS);
… instance of stim
exor2 DUT(‘exor2’);
DUT.A(ASig); DUT.B(BSig); DUT.F(FSig);
… instance of monitor
•Declare the trace
sc_trace_file* Tf;
Tf = sc_create_vcd_trace_file(‘traces’);
Tf->set_time_unit(1, SC_NS);
•(optional : specify the trace time unit)
//deprecated :
//((vcd_trace_file*)Tf)->sc_set_vcd_time_unit(-9);
sc_trace(Tf, ASig, ‘A’);
sc_trace(Tf, BSig, ‘B’);
sc_trace(Tf, FSig, ‘F’);
sc_trace(Tf, DUT.S1, ‘S1’);
sc_trace(Tf, DUT.S2, ‘S2’);
sc_trace(Tf, DUT.S3, ‘S3’);
sc_start();
sc_close_vcd_trace_file(Tf);
return 0;
•Create trace file
•Register signals or variables for tracing
(even hierarchically : DUT.S1)
// DUT = Design Under Test
•Run the simulation
•Close the trace file
B. Miramond - UCP
d. Resulting waveforms
B. Miramond - UCP
III. Simulation
Kernel
B. Miramond - UCP
Concurrence simulée


L’objectif du scheduler SystemC est de simuler
l’exécution parallèle de la plateforme matérielle
décrite bien que la simulation tourne sur une
station de travail mono-processeur.
La concurrence simulée en SystemC n’est pas
préemptive, c’est le code de chaque processus
qui redonne la main au scheduler (wait).
B. Miramond - UCP
Section organisation
Time management
SystemC scheduler
SystemC scheduling steps
1.
2.
3.
1.
2.
3.
4.
5.
6.
The case of Channels : Evaluate-update
Concurrency and time
4.
5.
1.
2.
3.
6.
Delayed notification
Timed notification
Immediate notification
Simulation steps synthesis
Dont_intialize !
Ending simuation
Perceived concurrency
Zero-time execution
Scheduled concurrency
Event-driven simulators (not yet)
B. Miramond - UCP
1. Gestion du temps
a) sc_time



Le simulateur SystemC est discret. Il utilise un quantum
de temps minimal qui peut être définit par
sc_set_time_resolution(int, sc_time_unit)
Par défaut, la plus petite résolution du temps est 1
picoseconde (10-12s)
SystemC définit un type énuméré des unités de temps,
sc_time_unit :






SC_FS
SC_PS
SC_NS
SC_US
SC_MS
SC_SEC
femtoseconde
picoseonde
nanoseconde
microseconde
milliseconde
(10-15s)
(10-12s)
(10-9s)
(10-6s)
(10-3s)
B. Miramond - UCP
Default
SC_TIME
sc_time est le type utilisé pour déclarer des variables de
temps
Déclaration : sc_time t1(42, SC_PS);

sc_time sc_time_stamp()
retourne le temps courant
de simulation
double sc_simulation_time() retourne le temps
courant de simulation
en unité de temps par défaut
B. Miramond - UCP
b) Déclaration d’horloges : sc_clock


Utilisées pour la synchronisation
Les arguments sont :







Un label,
La période de l’horloge : valeur + unité
Le temps passé à l’état haut
La date du premier front
Et un booléen indiquant si le premier front est montant ou
descendant.
sc_clock(« Clk », 1, SC_NS);
sc_clock(« Clk », 1, SC_NS, 0.5, 0, SC_NS, true);
B. Miramond - UCP
Services de l’horloge










En SystemC les horloges sont des canaux hiérarchiques,
Ils offrent les services suivants :
period();
// returns sc_time
duty_cycle();
// returns a double (fraction of the period)
posedge();
// returns a reference to the positive clock
edge;
negedge();
// negative…
read();
// return the current value
event();
// detects if there has been a change on
clock
posedge_event(); // returns an event notification for pos
clock edge
negedge_event(); // returns an event notification for neg
clock edge
B. Miramond - UCP
Ports dédiés

Un module peut utiliser les ports dédiés de
l’horloge pour pouvoir être synchrone :
sc_in_clock
 sc_out_clock
 sc_inout_clock



Les horloges ne sont
lancées qu’après l’appel à
sc_start()
Ce ne sont rien de plus que des sc_in<bool>
Mais ils fournissent les méthodes pos() et neg()
qui font appel à pos_edge_event() et
neg_edge_event()
B. Miramond - UCP
2. Scheduler SystemC

Le séquencement des opération réalisé par
SystemC est
Déterministe : l’ordre des opérations sera toujours le
même dans les même conditions
 Mais l’utilisateur n’a pas de moyen de connaître ce
séquencement à l’avance
 Il est donc déconseillé de faire communiquer 2
processus par variable partagé globale, car l’ordre de
lecture/écriture n’est pas spécifié.

B. Miramond - UCP
sc_main()
3. Simulation steps
SystemC Simulation Kernel
.notify(); // immediate
Elaboration
sc_start();
Initialize
Evaluate
∆
Advance
Time
while process ready
Cleanup
.notify(SC_ZERO_TIME);
// delayed
B. Miramond - UCP
.notify(t); // timed
Simulation steps

Elaboration



Initialisation




Les processus sont exécutés en fonction de leur sensibilité
Advance time


Débute après l’appel à sc_start()
Les processus créées à l’élaboration sont lancés.
Tous les processus sont placés dans la file READY.
Evaluate-Update


Les modules SystemC sont construits
Les SC_METHOD et SC_THREAD sont créées.
Time management
Cleanup

Clean objects and structures
B. Miramond - UCP
Rappel

Seul les SC_THREAD font des appels à wait()


Ils ne sont exécutés qu’une seule fois, mais peuvent
être interrompus.
Tous les SC_METHOD ont une liste statique et
sont re-déclenché à chaque nouvelle notification.

Ils sont exécutés autant de fois que nécessaire.
B. Miramond - UCP
Files d’attente duDurant
scheduler
son exécution, un
processus peut réaliser des
a. Delayed notification
notifications qui réveillent d’autres
Ready
Running
P1
P4
P2
P3
processus en attente (Waiting).
Events
Waiting
P5
E1@0
P6
E2@t1
E3@t2
Un par un, les processus
sont pris aléatoirement de la
fileDelta-cycle
Ready et désignés
Après un
comme Running jusqu’à
rencontrer un wait() ou un
return().
B. Miramond - UCP
E4@()
sc_main()
Elaboration
sc_start();
Simulation steps
SystemC Simulation Kernel
Les processus attendant un événement notifié avec un
délai SC_ZERO_TIME(.notify(0)) sont replacés dans la
file Ready au prochain cycle de simulation.
Ce cycle est appelé Delta-Cycle Delay.
Initialize
Evaluate
∆
Cleanup
.notify(SC_ZERO_TIME);
// delayed
B. Miramond - UCP
Advance
Time
while process ready
b. Timed notification
Events
Ready
Running
Waiting
P1
P4
P5
E1@0
P6
E2@t1
E3@t2
P2
P3
E4@()
Après un temps t1
B. Miramond - UCP
sc_main()
Elaboration
sc_start();
Simulation steps
SystemC Simulation Kernel
Les processus attendant un événement notifié avec un
délai non-nul sont placés dans la file Waiting et le temps
est avancé jusqu’au temps du premier événement de la
liste. A cet instant les processus en attente sont placés en
file Ready.
Initialize
Evaluate
∆
Advance
Time
while process ready
Cleanup
.notify(t); // timed
B. Miramond - UCP
c. Immediate notification
Events
Ready
Running
Waiting
P1
P4
P5
E1@0
P6
E2@t1
E3@t2
P2
P3
E4@()
Dans le même cycle
B. Miramond - UCP
sc_main()
Simulation steps
SystemC Simulation Kernel
.notify(); // immediate
Elaboration
sc_start();
Initialize
Evaluate
∆
Cleanup
Advance
Time
while process ready
Une notification immédiate place directement les
processus en attente durant le même delta-cycle. Ceci
peut se produire plusieurs fois jusqu’à rencontré une
notification timée.
B. Miramond - UCP
d. Synthèse des étapes de simulation
du scheduler SystemC
1.
2.
3.
4.
5.
6.
7.
8.
Initialisation
Evaluation
S’il y a encore des processus prèt, retour en 2
Update
S’il y a eu des notifications Delta-cyle, déterminer les
processus READY et retour en 2.
S’il n’y a plus de ‘non-Zero notifications’, la
simulation est terminée
Sinon, avancer le temps au prochain temps de
notification
Déterminer les processus READY, retour en 2.
B. Miramond - UCP
e. La fonction dont_initialize()


Normallement tous les processus sont exécutés la
première fois durant la phase d’initialisation.
SystemC permet de spécifier que certains processus ne
seront pas exécutés à cette phase :




SC_METHOD(waiting_method)
sensitive << a << b;
dont_initialize();
La fonction nécessite une liste de sensibilité statique !!
Sinon, le processus ne sera pas démarré.
B. Miramond - UCP
f. End of simulation
1.
2.
3.
sc_start(argument); // where argument precise the
amount of simulation time. Only used with timed
models !!
sc_stop(); // inside a component. It terminates
simulation when a specified functional condition is
atteined. Too local !
Terminator module, which call the sc_stop() primitive
only when the logical sum of products on the endproces boolean condition is true. Global untimed halt
condition.
B. Miramond - UCP
4) Le cas des channels :
evaluate-update


Les canaux simples utilisent une procédure de
mise à jour particulière appelée :
request_update/update scheme.
Ce schéma permet de construire des canaux
supportant des changements d’état intervenant
sur des durées infinitésimales (∆Cycle) et donc
d’exprimer la concurrence à son niveau le plus
précis.
B. Miramond - UCP
Exemple 1
On cherche à swapper la valeur présente dans 2
registres au moment de l’horloge.
 Si on modélise les registres par des variables, il
est nécessaire d’utiliser une 3e variable
temporaire pour faire le swap.
 Si on utilise des signaux, 2 sont suffisants car
l’écriture et la lecture ne se font pas dans le
même cycle.
B. Miramond - UCP
Exemple 2
Q2
Q1
DATA
D
Reg3
Reg2
Reg1
Q
D
SYNC
Comportement attendu :
2. Q4 = Q3
3. Q3 = Q2
4. Q2 = Q1
5. Q1 = DATA
Reg4
Q3
D
Q
Q
Q4
D
Q
Pour que la fonctionnalité soit
respectée,
L’ordre est important
Chaque registre est un processus
indépendant.
Or le simulateur ne précise aucun
ordre sur les processus.
B. Miramond - UCP
Solution : 2 données du canal ‘Signal’
Chaque signal a deux lieux de mémorisation :



New value
Et current value
Lors d’une écriture,
3.
le signal place la valeur dans ‘New value’
4.
Puis le processus appelle request_update() pour que le simulateur
appelle à son tour la fonction update() du canal lors de la
prochaine phase.
5.
Lorsque la phase d’évaluation est réellement terminée (il n’y a
plus de processus en état Ready), le simulateur appelle update()
pour chaque canal ayant fait un appel à request_update().
6.
Le canal recopie la nouvelle valeur et notifie un sc_event pour
indiquer un changement de valeur.

Donc si un process écrit sur un signal et lit immédiatement, il
trouvera la valeur inchangé !!
B. Miramond - UCP
New/Current value
Delta-Cycle
New Value
Canaux
Current Value
S1 = V2
S1= V0
S2 = V3
S2= V1
Update()
B. Miramond - UCP
The Update Simulation step
sc_main()
SystemC Simulation Kernel
Elaboration
sc_start();
Initialize
Evaluate
∆
Cleanup
Update
B. Miramond - UCP
Advance
Time
Exemple
// Declaration
Int
count;
sc_string
message_tmp;
sc_signal<int>
count_sig;
sc_signal<sc_string> message_sig;
// Intializing during first delta cycle
count_sig.write(10);
message_sig.write(‘Hello’);
count = 11;
message_temp = ‘Bonjour’;
print_state(count, count_sig, message_temp, message_sig);
wait(SC_ZERO_TIME);
// 2nd delta cycle
count = 20;
count_sig.write(count);
print_state(count, count_sig, message_temp, message_sig);
wait(SC_ZERO_TIME);
// 3rd delta cycle
message_sig.write(message_temp = ‘New message’);
print_state(count, count_sig, message_temp, message_sig);
B. Miramond - UCP
// Konsole
// First delta cycle
count is
count_sig is
message_temp is
message_sig is
// 2nd delta cycle
count is
count_sig is
message_temp is
message_sig is
// 3rd delta cycle
count is
count_sig is
message_temp is
message_sig is
11
0
Bonjour
‘’
20
10
Bonjour
Hello
20
20
New Message
Hello
Guide d’utilisation

Pour bien utiliser ces canaux :
1.
2.
3.
4.

Utiliser comme convention de nommage pour les
signaux avec le suffixe _sig
Lire tous les ports et signaux dans une variable
locale
Réaliser les traitements sur ces variables locales
Écrire le résultat sur les ports et les signaux
Concept proche d’un automate de Moore…
B. Miramond - UCP
Résumé du schéma
request_update/update


Ce schéma correspond à dire que la mise à jour
de ces signaux est retardée d’un Delta-cycle.
Ce schéma ne s’applique qu’aux canaux
primitifs, mais pas à tous :
sc_signal
 sc_fifo
 mais pas sc_mutex et sc_semaphore (cf. section IV)

B. Miramond - UCP
5) Concurrence
et évolution du temps
Process A(){
// @ t0
codeA1;
codeA2;
wait(t1);
codeA3;
codeA4;
wait(t2);
codeA5;
codeA6;
wait(t3);
}
Process B(){
// @ t0
codeB1;
codeB2;
wait(t1);
codeB3;
codeB4;
wait(t2);
codeB5;
codeB6;
wait(t3);
}
Process C(){
// @ t0
codeC1;
codeC2;
wait(t1);
codeC3;
codeC4;
wait(t2);
codeC5;
codeC6;
wait(t3);
}
B. Miramond - UCP
Process D(){
// @ t0
codeD1;
codeD2;
wait(t1);
codeD3;
wait(0);
codeD4;
wait(t3);
}
Activité perçue lors de la simulation
A
B
A1; A2;
A3; A4;
A5; 16;
B1; B2;
B3; B4;
B5; B6;
C1; C2;
C3; C4;
C5; C6;
D1; D2;
D3; D4;
…
C
D
t1
t2
B. Miramond - UCP
t3
Activité réelle lors de la simulation (1)
A
B
C
A3; A4;
A1; A2;
A5; 16;
Chaque portion de code est
exécutée en temps nul !!!
B1; B2;
B3; B4;
B5; B6;
C1;
C2;
C3; C4;
C5; C6;
D1; D2;
D3; D4;
…
Ce sont les wait(t) qui font
avancer le temps !
D
t1
t2
B. Miramond - UCP
t3
Activité réelle lors de la simulation (2)
A1; A2;
A3; A4;
A
B
C1; C2;
A1; A2;
Les opérations qui
apparaissent concurrentes à
l’utilisateur sont séquencées
B5; B6; par le
B1;scheduler
B2;
SystemC.
Cet ordre est déterministe
mais non prévisible !
B3; B4;
B1; B2;
A5; 16;
C5; C6;
C3; C4;
C1; C2;
C
D1; D2;
D1; D2;
D4;
D
Rq: Extansion du temps
t1
t2
B. Miramond - UCP
t3
6. Event-based simulators

VHDL, Verilog …
B. Miramond - UCP
End of Green
B. Miramond - UCP
Téléchargement