Upload
chavi
View
42
Download
0
Tags:
Embed Size (px)
DESCRIPTION
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); - PowerPoint PPT Presentation
Citation preview
ipblock design in GEZEL
Patrick Schaumont
Virginia TechDept. of Electrical and Computer Engineering
September 2010
2
What are ipblock?
• An ipblock is a black-box simulation entity for GEZEL
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"; }
InterfaceName
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
ipblock
GEZEL class lib(data types,
symbol table, ...)C++
ld.sofdlsim/gplatform
dynamic-link librarystatically linked
EXE
6
Operational Principle
• ipblock are cycle-based simulation models• A cycle-based simulation has two phases
per cycle: evaluate and (state) update
R1 R2 R3logic 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
R2
R3
logic L1
logic L2
R1
R2
R3
Cycle N Cycle N + 1
Evaluate: next_R1 = ... next_R2 = Logic_L1(R1); next_R3 = Logic_L2(R2);
Update: R1 = next_R1; R2 = next_R2; R3 = next_R3;
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 R3logic 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
ipblock
ipblockipblock
fsmd
OK
Not OK
11
Simple ipblock: combinational
ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock";}
GEZEL
C++
void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong());}
class myblock : public aipblock { public: void run();};
+
12
Simple ipblock: combinational
ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock";}
GEZEL
C++
void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong());}
class myblock : public aipblock { public: void run();};
ioval[0]
ioval[1]
ioval[2]
a
b
c
13
Simple ipblock: combinational
ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock";}
GEZEL
C++
void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong());}
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
14
Adding parameters
ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; ipparm "thisparam=thatval";}
GEZEL
C++
void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong());}
void myblock::setparam(char *n) { // ...}
class myblock : public aipblock { public: void run(); void setparam(char *);};
call constructor
for each 'ipparm'call setparam
for each cyclecall run
15
Terminal-check function
ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; ipparm "thisparam=thatval";}
GEZEL
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;}
• ipblock use positional port matching• checkterminal verifies that ioval[0] is
an input name "a", ioval[1] is input "b", ...
16
Terminal-check function
ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; ipparm "thisparam=thatval";}
GEZEL
C++
class myblock : public aipblock { public: void run(); void setparam(char *); void checkterminal(..);};
call constructor
for each 'ipparm'call setparam
for each cyclecall run
for each i/o portcall checkterminal
17
Completing the C++
#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
myblock.h
Access to GEZEL library functions(aipblock definition, arbitrary-precision data types, ..)
Called by the dynamic-link facility,Function name depends on class name!
simulator control(see part 2)
18
Completing the C++
myblock.cxx
#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 implementationfor combinational modules
Called by dynamic-link facility
19
Compilation-Simulation Example
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
Compile:
Create dynamic-link library
20
Compilation-Simulation Example
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
Compile:
Create dynamic-link library
position-independent code
.so library
path to gezel lib
gezel lib and predefined ipblocks
arbitrary precisionmath 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
> /opt/gezel-2.2/bin/fdlsim ipb.fdl 5
set parm: thisparam=thatvala 0 b 2 c 2a 1 b 2 c 3a 2 b 2 c 4a 3 b 2 c 5a 4 b 2 c 6
1. parse ipb.fdl2. instantiate ipblock 2.1. link dynamic-link lib3. simulate 5 cycles
output:
define all FSM next-state
evaluate output of each dp
call ipblock with no output
update dp registers
Per clock cycle:
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
#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
25
Sleep Cycle Mechanism
Software(typ 1Mc/s)
Hardware(typ 10K/s)
100K cycles
100 cycles
100 cycles
100K cycles
100K cycles
26
Sleep Cycle Mechanism
Software(typ 1Mc/s)
Hardware(typ 10K/s)
100K cycles
100 cycles
100 cycles
100K cycles
100K cycles
Without sleep-cycle:300,200 cycles @ 10K/s
=30.02 seconds
27
Sleep Cycle Mechanism
Software(typ 1Mc/s)
Hardware(typ 10K/s)
100K cycles
100 cycles
100 cycles
100K cycles
100K cycles
With sleep-cycle:300K cycles @ 1M/s +
300K cycles (testing_overhead) +200 cycles @ 10K/s
=less than 0.5 seconds!
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
Active
Passive
sleep_test = false
sleep_test = truewakeup_test = true
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
Three GEZEL ipblock:
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
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;}
void i8051externalwrite(int dev, unsigned char d) { i8051devmap[dev]->ioval[0]->assignulong((long) d); i8051devmap[dev]->touch();}
As a result ofthe 8051 WRITING
to the hardware,the cycle-simulation
will wake-up
38
Review: One C++ class
#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
OK!
39
Ipblock are combinational
• By default, have a single evaluate function, run( ), called once per clock cycle
ipblock
ipblockipblock
fsmd
OK
Not OK
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
CombFunction
Sequential output
Combinational output
42
Support for Sequential IP block
• This will simulate fine !
ipblock
CombFunction
CombFunction
0
43
Sequential IP Block in C++
#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(); void regOutput(); void out_run();};
#endif
44
regOutput
• Used in constructor to define an ipblock output as sequential
armsfu2x1::armsfu2x1(char *name) : aipblock(name) { deviceid = 0; hook = 0; myarm = 0; interfacewritten = false; regOutput(0); // d1 and d2 are registered regOutput(1);}
// ipblock mysfu(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// }
45
regOutput
• Used in constructor to define an ipblock output as sequential
// ipblock mysfu(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// }
armsfu2x2Custom
Datapath(combinational)
d1d2
q1q2
OK!
Stable at the start of a clock cycle
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