Rendszerszintű tervezés: SystemC I. Czirkos Zoltán BME EET 2016. február 24.
Miről lesz szó? Magas szintű tervezés programozási nyelvek segítségével HDL leírás (Verilog / VHDL) is emlékeztet egy programra Ne kelljen kézzel előálĺıtani HDL kódot, legyen elég egy ismert programozási nyelven elkészíteni a rendszer leírását Miért programozási nyelv segítségével? Nem kell még eldönteni, mi lesz hardverben, mi lesz szoftverben Együtt tervezhető a hardver és a szoftver Mi a hardvertervezés részre koncentrálunk SystemC C++ osztályok gyűjteménye, amelyekkel lehetőségünk van C++ fejlesztői környezetben a hardvert is reprezentálni Ún. compiled code szimuláció is és hardverszintézis is lehetséges Nyílt megoldás
Hardver-szoftver együttes tervezés ESL: Electronic System Level design HSCD: Hardware-Software Co-Design Lényeg: elsődleges szempontnak tekintjük, hogy az adott rendszert minél magasabb absztrakciós szinten írjuk le. Az ESL szemlélet a rendszerszintű terveknél egyre elterjedtebb. A világ vezető system-on-a-chip (SoC) tervező cégei irányelvüknek tekintik. A hardver-szoftver együttes tervezés céljai: magas absztrakciós szint, könnyebben átlátható terv legyen, hibákat gyorsabban meg lehessen találni, optimalizálni lehessen a hardver/szoftver particionálást, csökkenjen a piacra kerülés átfutási ideje, és hogy csökkenjenek a fejlesztési költségek. SystemC a HSCD jellegzetes eszköze
A SystemC I. A SystemC nyelv egy C++ könyvtár és metódus gyűjtemény, ami igen hatékonyan használható szoftveres algoritmusok készítésére, hardver architektúrák modellezésére, valamint SoC és rendszer szintű modellek interfészének megvalósítására. A SystemC és a hagyományos C++ fejlesztői környezet használatával rendszer szintű modellek írhatók le, ezek azután gyorsan szimulálhatók és optimalizálhatók. A rendszert leíró modell egy C++ program, ami futtatva ugyanazt a viselkedést produkálja, amit maga a rendszer
A SystemC II. A SystemC olyan osztályokat tartalmaz, amelyekkel a megszokott nyelv és feljesztő eszközök használatával képesek leszünk hardver leírására A SystemC olyan hardverhez közeli modellezési lehetőségeket biztosít, mint a párhuzamosság, időzítések, késleltetések, hardverközeli kommunikációs csatornák (pl. portok), hardver-megvalósításokban használt adattípusok, melyek a C++-ban nincsenek meg, hiszen az egy szekvenciális programozási nyelv, amely szoftverfejlesztéshez való.
A SystemC célja Rendszerszintű modellek fejlesztése magas absztrakciós szint a működés vizsgálata szimulációval Magasszintű hardverleírásból szintézis szintetizálható kódot kell írni bizonyos nyelvi elemeket pl. pointereket kerülni kell kimenet: Verilog vagy VHDL leírás, ami egy target technológiára valóban szintetizálható Szimulációhoz: SystemC library és egy C++ fordító kell Szintézis: szabad hozzáférésű programokkal megoldható. Pl. SystemC könyvtár CvSDL Waveform Viewer 0.3.1 SystemCrafter SC v2.0.0.3 Xilinx ISE WebPack 8.2i
SystemC alapú szintézis és szimuláció
A SystemC komponensei Modul egy container, ami más modulokat és process-eket foglalhat magában (C++ osztály) Process folyamat egy adott funkcionalitás leírására szolgál Signal jel támogatott a 2 (0,1) és 4 (0,1,X,Z) értékű logika is Port jelek csatlakozó pontja Adattípusok sokféle típus, különféle szempontok szerint használhatók. Vigyázat szintetizálhatóság! Órajel az idő modellezésére szolgáló spec. jel Szimulációs kernel lehetővé teszi a gyors (compiled kódú) szimulációt Jelalak-figyelés VCD (Value Change Dump), WIF (Waveform Intermediate Format) és ISDB (Integrated Signal Data Base) formátumú jelalak fájlok támogatása
Az idő modellezése A SystemC könyvtár egyik legfontosabb komponense a már emĺıtett időmodellezés. Ezt a nyelv 64-bites előjel nélküli egész számokkal írja le. Ez a programozó számára az sc time típus mögé van bújtatva. Ilyen módon történő implementálása miatt az idő nem írható le folytonos, analóg módon, csak diszkrét értékekkel. Ennek következtében van egy legkisebb ábrázolható időkvantum, amit időfelbontásnak nevezünk. Ez a nyelv használója által beálĺıtható. Default egység: ps. 2 64 ps = 213 nap. :)
Hardver adattípusok A hardver modellezés céljára a SystemC-ben hasonló adattípusok léteznek, mint a Verilog-ban, pl. sc logic, sc lv. Pl. DSP jellegű hardverekhez, számítási algoritmusok implementálására szolgáló típusok a sc fixed és az sc int Mivel a SystemC a C++-on alapul, értelemszerűen minden C++ adattípus használható, ha nem szükséges valamit SystemC típussal reprezentálni. Fontos szempontok az adattípusokkal kapcsolatban: Bizonyos adattípusok használata nem teszi lehetővé a hardverszintézist. Minden olyan modulban, amit esetleg hardverként szeretnénk megvalósítani, az ilyen típusokat kerülni kell. A SystemC adattípusok sok memóriát igényelnek, és jelentősen lassíthatják a szimulációt.
Modulok és metódusok A modulok egy SystemC terv alapvető építőkövei, hasonlóan a C++ osztályokhoz. Egy modul egy másik modulban példányosítható (pl. több flipflop egy számlálóban) Minden alacsonyabb szintű modul példányosítható magasabb szintű modulokban Az SC METHOD és az SC THREAD típusú függvények jelentik a modellezés alapját a SystemC-ben. SC METHOD nem kerül időbe a végrehajtásuk SC THREAD egy eseményre várnak (pl. órajel pozitív éle), aztán egy adott ideig futnak
Hello world SystemC-ben modulok szintaxisa #include systemc.h SC MODULE(hello world) { // hello world: modul neve SC CTOR(hello world) { // ez most üres void say hello() { cout << Hello World.\n ; ; int sc main(int argc, char argv[]) { hello world hello( hello ); // modul példányosítása hello.say hello(); return 0;
Második példa: inverter I. a modul Az inverter nevű modulnak egy-egy 1 bites bemene és kimenete van. A működést leíró függvény a bement jelszintjének bármely irányú változására lefut. #include systemc.h SC MODULE(inverter) { sc in<bool> be; // bemenet sc out<bool> ki; // kimenet void inverterproc(); SC CTOR(inverter) { SC METHOD(inverterproc); sensitive << be; ; #include inverter.h void inverter::inverterproc() { ki.write(!be.read()); A működés egyszerű: beolvassuk a bemenetet (read), invertáljuk (felkiáltójel operátor) és kíırjuk a kimenetre (write).
Második példa: inverter II. a testbench #include inverter.h int sc main(int argc, char argv[]) { // vezetékek sc signal<bool> BE, KI; // példányosítás inverter i1( i1 ); // bemenet és kimenet bekötése i1.be(be); i1.ki(ki); sc start(1, SC NS); // trace fájl megnyitása sc trace file tf = sc create vcd trace file( out ); sc trace(tf, BE, BE ); sc trace(tf, KI, KI ); // bemenetek változtatása BE=0; sc start(2, SC NS); BE=1; sc start(2, SC NS); BE=0; sc start(2, SC NS); BE=1; sc start(2, SC NS); BE=0; sc start(2, SC NS); // trace fájl bezárása sc close vcd trace file(tf); return 0;
Második példa: inverter III. magyarázatok Az inverter i1( i1 ); sorban történik a példányosítás, az i1.be(be); pedig azt jelenti, hogy az i1 néven példányosított inverter be nevű portjához kötjük a fent deklarált BE jelet. Az sc start(1, SC NS) lépteti 1 ns-mal a szimulációs kernelt (szimulációs órát). A jelalakfigyeléshez létrehozunk egy out.vcd nevű fájlt, amelyre a kód további részében tf néven fogunk hivatkozni. Az ezt követő két sor mondja meg, hogy mely fájlba melyik jel változásait jegyezze fel a SystemC, és milyen néven jelenítse meg azt. Amint az látható, az inverter bemeneti portjához kötött jelnek értéket adunk, majd léptjük a szimulációt 2 egységgel, stb. A végén lezárjuk a jelalakot tartalmazó fájlt.
Harmadik példa: számláló SC MODULE(first counter) { // kimenetek, bemenetek sc in clk clock; sc in<bool> reset; sc in<bool> enable; sc out<sc uint<4> > counter out; // belső állapotok (regiszterek) sc uint<4> count; // konstruktor SC CTOR(first counter) { SC METHOD(incr count); sensitive << clock.pos(); // felfutó él void incr count() { // számláló logika // reset jel? if (reset.read() == 1) { count = 0; counter out.write(count); // ha engedélyezve van, számol else if (enable.read() == 1) { count = count + 1; counter out.write(count); cout << @ << sc time stamp()<< :: Incremented Counter <<counter out.read()<<endl; ;
Negyedik példa: órajelgenerátor SC MODULE(ClockGen) { // Clock gen sc out clk clock out; ; void clockgen() { while (true) { clock out = true; wait(500, SC US); clock out = false; wait(500, SC US); SC CTOR(ClockGen) { SC THREAD(clockgen); Ez nem szintetizálható, tesztelésre (testbench-be) viszont kitűnő.
Irodalom http://www.asic-world.com/systemc/tutorial.html 1666-2005 IEEE Standard SystemC Language Reference Manual http://shop.ieee.org/ieeestore/product.aspx?product_ no=ss95505 SystemC User s Guide v2.0.1 https://www.systemc.org/ projects/sitedocs/document/v201_users_guide/en/1 SystemC Language Reference Manual v2.1 https://www.systemc.org/download/5/3/60/104/ SystemC to Verilog Synthesizable Subset Translator http: //www.opencores.org/projects.cgi/web/sc2v/overview