1 / 48

ipblock design in GEZEL

ipblock design in GEZEL. Patrick Schaumont Virginia Tech Dept. of Electrical and Computer Engineering September 2010. What are ipblock?. An ipblock is a black-box simulation entity for GEZEL. Name. Interface. ipblock M(in address : ns(5); in wr,rd   : ns(1);

chavi
Télécharger la présentation

ipblock design in GEZEL

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ipblock design in GEZEL Patrick Schaumont Virginia Tech Dept. of Electrical and Computer Engineering September 2010

  2. What are ipblock? • An ipblock is a black-box simulation entity for GEZEL Name Interface ipblock M(in address : ns(5); in wr,rd   : ns(1); in idata   : ns(8); out odata   : ns(8)) { iptype "ram"; ipparm "wl=8"; ipparm "size=32"; } Type Parameters

  3. Applications of ipblock • Capture functionality not available as FSMD • FSMD does not exist: memory modules • FSMD unavailable: IP, complex modules, .. • Interfaces to other simulation engines • Instruction-set simulators: ARM, 8051 • Other languages/environments: SystemC,... • Extensions of GEZEL simulation capabilities • Collect signal statistics • Debug facility

  4. Who develops ipblock? GEZEL Designers GEZEL Users ipblock with generic use design-specific

  5. How are ipblock implemented? aipblock GEZEL class lib (data types, symbol table, ...) C++ ipblock statically linked dynamic-link library ld.so EXE fdlsim/gplatform

  6. Operational Principle • ipblock are cycle-based simulation models • A cycle-based simulation has two phases per cycle: evaluate and (state) update R1 R2 R3 logic L1 logic L2

  7. Operational Principle • ipblock are cycle-based simulation models • A cycle-based simulation has two phases per cycle: evaluate and (state) update R1 R1 logic L1 Evaluate: next_R1 = ... next_R2 = Logic_L1(R1); next_R3 = Logic_L2(R2); Update: R1 = next_R1; R2 = next_R2; R3 = next_R3; R2 R2 logic L2 R3 R3 Cycle N + 1 Cycle N

  8. Operational Principle • ipblock are cycle-based simulation models • A cycle-based simulation has two phases per cycle: evaluate and (state) update • Evaluate and update can be called only once per cycle R1 R3 logic L1 logic L2 GEZEL ensures that all Evaluate( ) are properly sorted: Logic_L1(R1) will be called BEFORE Logic L2(L1_output)

  9. Operational Principle • ipblock are cycle-based simulation models • A cycle-based simulation has two phases per cycle: evaluate and (state) update • Evaluate and update are called only once per cycle logic L1 logic L1 logic L2 If the execution order for Evaluate( ) cannot be determined, the simulator terminates ('combinatorial loop')

  10. Combinational ipblock • By default, have a single evaluate function, called once per clock cycle fsmd OK ipblock Not OK ipblock ipblock

  11. Simple ipblock: combinational GEZEL ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; } C++ class myblock : public aipblock { public: void run(); }; void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong()); } +

  12. Simple ipblock: combinational GEZEL ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; } a ioval[0] C++ b ioval[1] c ioval[2] class myblock : public aipblock { public: void run(); }; void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong()); }

  13. Simple ipblock: combinational GEZEL ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; } C++ class myblock : public aipblock { public: void run(); }; • run() is called once per clock cycle • When called, input ioval[ ] reflects proper value for that clock cycle • When called, output ioval[ ] must be assigned proper value for that clock cycle void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong()); }

  14. Adding parameters GEZEL ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; ipparm "thisparam=thatval"; } C++ class myblock : public aipblock { public: void run(); void setparam(char *); }; call constructor for each 'ipparm' call setparam void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong()); } void myblock::setparam(char *n) { // ... } for each cycle call run

  15. Terminal-check function GEZEL ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; ipparm "thisparam=thatval"; } • ipblock use positional port matching • checkterminal verifies that ioval[0] is an input name "a", ioval[1] is input "b", ... C++ class myblock : public aipblock { public: void run(); void setparam(char *); bool checkterminal(int n, char *tname, iodir d); }; bool myblock::checkterminal(int n, char *tname, iodir d) { switch(n) { case 0 : return (isinput(d) && isname(tname, "a")); break; ... } return false; }

  16. Terminal-check function GEZEL ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; ipparm "thisparam=thatval"; } call constructor C++ class myblock : public aipblock { public: void run(); void setparam(char *); void checkterminal(..); }; for each 'ipparm' call setparam for each i/o port call checkterminal for each cycle call run

  17. Completing the C++ myblock.h Access to GEZEL library functions(aipblock definition, arbitrary-precision data types, ..) #ifndef myblock_h #define myblock_h #include "ipblock.h" extern "C" aipblock *create_myblock(char *instname); class myblock : public aipblock { public: myblock(char *name); void setparm(char *); void run(); bool checkterminal(int n, char *tname, aipblock::iodir d); bool cannotSleepTest(); bool needsWakeupTest(); }; #endif Called by the dynamic-link facility, Function name depends on class name! simulator control (see part 2)

  18. Completing the C++ myblock.cxx Called by dynamic-link facility #include "myblock.h" extern "C" aipblock *create_myblock(char *instname) { return new myblock(instname); } myblock::myblock(char *name) : aipblock(name) {..} void myblock::setparm(char *_name) {..} void myblock::run() {..} bool myblock::checkterminal(..) {..} bool myblock::cannotSleepTest(){ return false; } bool myblock::needsWakeupTest(){ return true; } Default implementation for combinational modules

  19. Compilation-Simulation Example Compile: g++ -fPIC -O3 -I/opt/gezel-2.2/include/gezel -c myblock.cxx g++ -shared -O3 \ -Wl,--rpath -Wl,/home/schaum/gezel/devel/build/lib \ myblock.o \ /opt/gezel-2.2/lib/libipconfig.so \ /opt/gezel-2.2/lib/libfdl.so \ -lgmp -ldl -o libmyblock.so Create dynamic-link library

  20. Compilation-Simulation Example position-independent code Compile: g++ -fPIC -O3 -I/opt/gezel-2.2/include/gezel -c myblock.cxx g++ -shared -O3 \ -Wl,--rpath -Wl,/home/schaum/gezel/devel/build/lib \ myblock.o \ /opt/gezel-2.2/lib/libipconfig.so \ /opt/gezel-2.2/lib/libfdl.so \ -lgmp -ldl -o libmyblock.so .so library Create dynamic-link library path to gezel lib gezel lib and predefined ipblocks arbitrary precision math lib dynamic link lib

  21. GEZEL File ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; ipparm "thisparam=thatval"; } dp top { sig a, b, c : ns(8); reg a1 : ns(8); use ablock(a, b, c); always { a = a1; b = 2; $display("a ", a, " b ", b, " c ",c); a1 = a1 + 1; } } system S { top; }

  22. Simulation 1. parse ipb.fdl 2. instantiate ipblock 2.1. link dynamic-link lib 3. simulate 5 cycles > /opt/gezel-2.2/bin/fdlsim ipb.fdl 5 set parm: thisparam=thatval a 0 b 2 c 2 a 1 b 2 c 3 a 2 b 2 c 4 a 3 b 2 c 5 a 4 b 2 c 6 Per clock cycle: output: define all FSM next-state evaluate output of each dp call ipblock with no output update dp registers

  23. Summary #ifndef myblock_h #define myblock_h #include "ipblock.h" class myblock : public aipblock { public: myblock(char *name); void setparm(char *); void run(); bool checkterminal(int n, char *tname, aipblock::iodir d); bool cannotSleepTest(); bool needsWakeupTest(); }; #endif

  24. Sleep Cycle Mechanism #ifndefmyblock_h #define myblock_h #include "ipblock.h" classmyblock : publicaipblock { public: myblock(char *name); voidsetparm(char *); void run(); boolcheckterminal(int n, char *tname, aipblock::iodir d); boolcannotSleepTest(); boolneedsWakeupTest(); }; #endif

  25. Sleep Cycle Mechanism Software (typ 1Mc/s) Hardware (typ 10K/s) 100K cycles 100 cycles 100K cycles 100 cycles 100K cycles

  26. Sleep Cycle Mechanism Software (typ 1Mc/s) Hardware (typ 10K/s) 100K cycles 100 cycles 100K cycles 100 cycles Without sleep-cycle:300,200 cycles @ 10K/s = 30.02 seconds 100K cycles

  27. Sleep Cycle Mechanism Software (typ 1Mc/s) Hardware (typ 10K/s) 100K cycles 100 cycles 100K cycles With sleep-cycle:300K cycles @ 1M/s +300K cycles (testing_overhead) + 200 cycles @ 10K/s = less than 0.5 seconds! 100 cycles 100K cycles

  28. Sleep Cycle Mechanism • GEZEL simulator has two states: • Active: • each clock cycle, evaluate all datapath outputs (and dependent signals), evaluate all registers, evaluate all ipblock • perform sleep test • Passive: • perform wakeup test

  29. Sleep Cycle Mechanism • Transition from active to passive sleep_test = false Active sleep_test = true wakeup_test = true Passive wakeup_test = false

  30. Sleep Test • Sleep test evaluates to false in cycle X if: • Any register changes state during a clock X • Any FSM changes state during clock cycle X • Any ipblock returns true in aipblock::cannotSleepTest() • GEZEL simulator will call cannotSleepTest () once per cycle in active mode, default value should be false • (why is my GEZEL cosimulation so slow?Might be because there is remaining HW activity in idle phases)

  31. Wakeup Test • Wakeup test evaluates to true in cycle X if: • Any ipblock returns true in aipblock::needsWakeupTest() • GEZEL simulator will call needsWakeupTest () once per cycle in passive mode, default value should be false • If needsWakeupTest() never returns false, your simulation will never sleep (may be the cause of a slow cosimulation) • If needsWakeupTest() never returns true, your simulation will never wakeup (may be the cause of a ‘halted’ cosimulation)

  32. Example: 8051 cosimulation interface 8051 4 bi-directional ports ipblock my8051 { iptype "i8051system"; ipparm "exec=driver.ihx"; ipparm "verbose=1"; ipparm "period=1"; } ipblock my8051_datain(out data : ns(8)) { iptype "i8051systemsource"; ipparm "core=my8051"; ipparm "port=P1"; } ipblock my8051_dataout(in data : ns(8)) { iptype "i8051systemsink"; ipparm "core=my8051"; ipparm "port=P2"; } Core Three GEZEL ipblock: Input port Output port

  33. The Core void i8051system::run() { if (sim.IsRunning()) { period_cnt--; if (period_cnt == 0) { period_cnt = period; sim.ClockTick(); if (! sim.IsRunning()) glbRunningISS--; } } } bool i8051system::cannotSleepTest() { return false; // the ISS will continue to run in sleep mode // so we can also return 'OK to sleep' } bool i8051system::needsWakeupTest() { run(); return false; }

  34. The Input Port void i8051systemsink::run() { if (hook) { hook->writeRAM(address, ioval[0]->toulong()); } } bool i8051systemsink::cannotSleepTest() { return false; } (If you do not specify needsWakeupTest(), default implementation is used, which returns false)

  35. The Output Port void i8051systemsource::run() { } Obviously, it is the 8051 simulator that decides what the value of the output port should be. The 8051 simulator calls a functionexternalwrite(address, data) each time is performs a port write

  36. The Output Port void i8051systemsource::run() { } Obviously, it is the 8051 simulator that decides what the value of the output port should be. The 8051 simulator calls a functionexternalwrite(address, data) each time is performs a port write void i8051externalwrite(int dev, unsigned char d) { i8051devmap[dev]->ioval[0]->assignulong((long) d); i8051devmap[dev]->touch(); } I8051devmap is an array of output port ipblocks that are implemented by GEZEL The result of the externalwrite( ) is that an ipblock output is updated

  37. The Output Port void i8051systemsource::run() { } bool i8051systemsource::needsWakeupTest() { bool v = interfacewritten; interfacewritten = false; return v; } bool i8051systemsource::cannotSleepTest() { bool v = interfacewritten; interfacewritten = false; return v; } void i8051systemsource::touch() { interfacewritten = true; } As a result ofthe 8051 WRITING to the hardware,the cycle-simulation will wake-up void i8051externalwrite(int dev, unsigned char d) { i8051devmap[dev]->ioval[0]->assignulong((long) d); i8051devmap[dev]->touch(); }

  38. Review: One C++ class #ifndefmyblock_h #define myblock_h #include "ipblock.h" classmyblock : publicaipblock { public: myblock(char *name); voidsetparm(char *); void run(); boolcheckterminal(int n, char *tname, aipblock::iodir d); boolcannotSleepTest(); boolneedsWakeupTest(); }; #endif OK!

  39. Ipblock are combinational • By default, have a single evaluate function, run( ), called once per clock cycle fsmd OK ipblock Not OK ipblock ipblock

  40. Support for sequential IP block • Define sequential IP block:a sequential ipblock is an ipblock with an output which is is known and stable at the start of a clock cycle. • Thus, ‘sequential’ is a property of an output, not an entire ipblock

  41. Support for Sequential IPblock • For example, assume you develop a C++ class for this structure: ipblock Sequential output Comb Function Combinational output

  42. Support for Sequential IP block • This will simulate fine ! ipblock Comb Function Comb Function 0

  43. Sequential IP Block in C++ #ifndefmyblock_h #define myblock_h #include "ipblock.h" classmyblock : publicaipblock { public: myblock(char *name); voidsetparm(char *); void run(); boolcheckterminal(int n, char *tname, aipblock::iodir d); boolcannotSleepTest(); boolneedsWakeupTest(); voidregOutput();voidout_run(); }; #endif

  44. regOutput • Used in constructor to define an ipblock output as sequential // ipblockmysfu(out d1 : ns(32); out d2 : ns(32); // in q1 : ns(32); in q2 : ns(32)) { // iptype "armsfu2x2"; // ipparm "core = mycore"; -- core to hook into // ipparm "device = 0"; -- 2 possible devices per sfu type // } armsfu2x1::armsfu2x1(char *name) : aipblock(name) { deviceid = 0; hook = 0; myarm = 0; interfacewritten = false; regOutput(0); // d1 and d2 are registered regOutput(1); }

  45. regOutput • Used in constructor to define an ipblock output as sequential // ipblockmysfu(out d1 : ns(32); out d2 : ns(32); // in q1 : ns(32); in q2 : ns(32)) { // iptype "armsfu2x2"; // ipparm "core = mycore"; -- core to hook into // ipparm "device = 0"; -- 2 possible devices per sfu type // } Stable at the start of a clock cycle d1 d2 Custom Datapath(combinational) OK! armsfu2x2 q1 q2

  46. out_run( ) • out_run( ) is called at the start of the clock cycle, before any other run( ) is called, and before any signal or register is evaluated. • Typically, out_run( ) is used to initialize regOutput outputs to a stable value for that clock cycle.

  47. Example: accumulator ipblock ipblock add ipblock acc(in d : ns(8); out q : ns(8)) { iptype “accumulator”; } myacc::myacc(char *name) : aipblock(name) { regOutput(0); accvalue = 0; } myacc::out_run() { ioval[0]->assignulong(accvalue); } myacc::run() { accvalue = accvalue + ioval[1]->toulong();}

  48. Final hints • ipblock are a powerful extension mechanism for GEZEL • Puts a designer in control of design environment • Allows to put hardware design in context • Other neat tool: icg (incremental code generator) • Generates ipblock C++ out of GEZEL code • Useful to speed up simulation (3X – 10X faster) • Useful to compile HW to SW nice open research problems left here

More Related