Historique de SystemC Regroupe 4 courants didées: SCENIC Project : Synopsys+UC Irvine Philips System-Level Data Types, VSIA SLD DWG IMEC, Hardware-Software CoDesign (CoWare) OSCI, Language Working Group
SystemC heritage
Why SystemC ?
What is SystemC
A C++ library
SystemC design environment
SystemC advantages
SystemC layered environment
Commencer en SystemC POO : Classe, objet, instance en C++ Application : Réécrire ladditionneur VHDL en SystemC à partir de deux demi-additionneurs.
Intérêt de la POO : modularité technique de décomposition de systèmes réduire la complexité dun système par un assemblage de sous- systèmes plus simples La réussite de la technique dépend du degré dindépendance entre les sous-systèmes (ou degré de couplage) on appelle module, un sous-système dont le couplage avec les autres est relativement faible par rapport au couplage de ses propres parties Truisme pour un microélectronicien, déjà confronté au problème
Encapsulation technique pour favoriser la modularité (lindépendance) des sous- systèmes séparer linterface dun module de son implémentation, interface (partie publique): liste des services offerts (quoi) implémentation (partie privée): réalisation des services (comment) structure de données instructions et algorithmes protection des données par des règles (dans les instructions): les modules communiquent par messages, pas par accès aux données
Représentation dun objet
Intérêt des classes Une classe sert à définir les possibilités des objets d'un type donné. décrit un ensemble de données et les opérations possibles sur ces données. une classe sert de "modèle" pour la création d'objets (instances de la classe)
Structure des classes Une classe est un agrégat d'attributs et de méthodes : les membres Les membres sont accessibles via une instance de la classe Une méthode particulière, le constructeur, est appelée lors de la création de linstance
Héritage le problème : une application a besoin de services dont une partie seulement est proposée par une classe déjà définie, et ce dans un délai très bref. ne pas réécrire le code solution en POO : définir une nouvelle classe à partir de la classe déjà existante, c'est l'héritage le code d'une classe peut ainsi être réutilisé autant de fois que nécessaire pour créer de nouvelles sous-classes Les sous-classes fournissent un comportement spécialisé au comportement commun fourni par la super-classe Permet de créer des nouveaux types ou objets évolutifs très rapidement, contrairement à VHDL Elévation du niveau dabstraction et possibilité de MoC + évolués
SystemC et POO Tout module SystemC dérive de la classe module de base Il en a donc le comportement par défaut Un module a des ports Input, output, inout Un module a des processus Correspond à la description comportementale de VHDL
En C++ Méthodologie C++ : 2 fichiers.h,.cpp Inclure « systemc.h ».h contient la description du module Linterface du module Les signaux internes Le constructeur Le prototype des méthodes.cpp contient les définitions des méthodes (processus et utilitaires)
Creating a module
Modules
Module example
SystemC Module
SC_MODULE Skeleton
SC_MODULE syntax
Ports, channels, interfaces
SystemC port
SystemC port syntax
SystemC signal
sc_signal syntax
Data member syntax
SystemC datatypes
sc_int / sc_uint
SystemC operators<
SystemC SC_CTOR
SystemC process
SystemC process types
Creating a process
Member functions
Creating a submodule
Top-level of design
Creating clock and start simulation
SystemC clock
SystemC system
Conceptual thread of executionsc_main
Constructeur Données membres, linterface Nom du module half_adder.h // File : half_adder.h #include "systemc.h" SC_MODULE(half_adder) { sc_in a,b; sc_out sum,carry; void prc_half_adder(); SC_CTOR(half_adder) { SC_METHOD(prc_half_adder); sensitive << a << b; } }; half_adder.h
SC_METHOD (1) // File : half_adder.h #include "systemc.h" SC_MODULE(half_adder) { sc_in a,b; sc_out sum,carry; void prc_half_adder(); SC_CTOR(half_adder) { SC_METHOD(prc_half_adder); sensitive << a << b; } }; Déclare un process sans mémoire appelé prc_half_adder() Ne peut utiliser les wait Sensibilité « statique » sur a et b
SC_METHOD (2) // File : half_adder.cpp #include "half_adder.h" void half_adder::prc_half_adder() { sum = a ^ b; carry = a & b; }
Description de la hiérarchie // File : full_adder.h #include "half_adder.h" SC_MODULE(full_adder) { sc_in a,b,carry_in; sc_out sum,carry_out; sc_signal c1,s1,c2; void prc_or(); half_adder *ha1_ptr,*ha2_ptr; SC_CTOR(full_adder) { ha1_ptr=new half_adder("ha1"); // Named association: ha1_ptr->a(a); ha1_ptr->b(b); ha1_ptr->sum(s1); ha1_ptr->carry(c1); ha2_ptr=new half_adder("ha2"); // Positional association: (*ha2_ptr)(s1,carry_in,sum,c2); SC_METHOD(prc_or); sensitive << c1 << c2; } // A destructor ~full_adder() { delete ha1_ptr; delete ha2_ptr; } }; // File : full_adder.cpp #include "full_adder.h" void full_adder::prc_or() { carry_out = c1 | c2; }
driver.h, driver.cpp // File : driver.h #include "systemc.h" SC_MODULE(driver) { sc_out d_a,d_b,d_cin; void prc_driver(); SC_CTOR(driver) { SC_THREAD(prc_driver); } }; // File : driver.cpp #include "driver.h" void driver::prc_driver() { sc_uint pattern; pattern=0; while (1) { d_a=pattern[0]; d_b=pattern[1]; d_cin=pattern[2]; wait(5,SC_NS); pattern++; }
monitor.h, monitor.cpp // File : monitor.h #include "systemc.h" SC_MODULE(monitor) { sc_in m_a,m_b,m_cin,m_sum,m_cout; void prc_monitor(); SC_CTOR(monitor) { SC_METHOD(prc_monitor); sensitive << m_a << m_b << m_cin << m_sum << m_cout; } }; // File : monitor.cpp #include "monitor.h" void monitor::prc_monitor() { cout << "At time " << sc_time_stamp() << "::"; cout << "(a, b, carry_in): "; cout << m_a << m_b << m_cin; cout << " (sum, carry_out): " << m_sum << m_cout << endl; }
Schématique du toplevel driver full_adder monitor
Le toplevel // File : full_adder_main.cpp #include "driver.h" #include "monitor.h" #include "full_adder.h" int sc_main(int argc,char *argv[]) { sc_signal t_a, t_b, t_cin, t_sum, t_cout; full_adder f1("FullAdderWithHalfAdder"); // Connect using positional association: f1 << t_a << t_b << t_cin << t_sum << t_cout; driver d1("GenerateWaveforms"); // Connect using named association: d1.d_a(t_a); d1.d_b(t_b); d1.d_cin(t_cin); monitor mo1("MonitorWaveforms"); mo1 << t_a << t_b << t_cin << t_sum << t_cout; sc_start(100,SC_NS); return(0); } A éviter A utiliser
Tracing signals
Trace de simulation
Pour ajouter des traces (.vcd)
Comparaison VHDL-SystemC // File : half_adder.h #include "systemc.h" SC_MODULE(half_adder) { sc_in a,b; sc_out sum,carry; void prc_half_adder(); SC_CTOR(half_adder) { SC_METHOD(prc_half_adder); sensitive << a << b; } }; // File : half_adder.cpp #include "half_adder.h" void half_adder::prc_half_adder() { sum = a ^ b; carry = a & b; } ARCHITECTURE half_adder_d OF half_adder IS BEGIN sum <= (a XOR b); carry <= (a AND b); END half_adder_d; ENTITY half_adder IS PORT( a, b: IN BIT; sum, carry: OUT BIT); END half_adder;
VHDL – SystemC (1) entity my_model is port( input1: in BIT; input2: in BIT; output1: out BIT; output2: out BIT; ); end my_model; architecture my_arch of my_model is begin process( input1, input2) variable my_var1,my_var2: BIT; begin my_var1 := not input1; my_var2 := not input2; output1 <= input1 and my_var2; output2 <= input2 and my_var1; end process; end my_arch; #include systemc.h SC_MODULE (my_model) { sc_in input1; sc_in input2; sc_out output1; sc_out output2; SC_CTOR (my_model) { SC_METHOD ( process ); sensitive << input1 << input2; } void process( ) { bool my_var1, my_var2; my_var1 = ~input1; my_var2 = ~input2; output1 = input1 & my_var2; output2 = input2 & my_var1; } };
VHDL – SystemC (2) process( input1, input2 ) process(clk)... if ( clkevent and clk = 1) then SC_METHOD ( process ); sensitive << input1 << input2; SC_METHOD ( process ); sensitive_pos << clk;