Secure Circuits and Embedded Systems Research

Download Report

Transcript Secure Circuits and Embedded Systems Research

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
Type
ipblock M(in address
in wr,rd
in idata
out odata
iptype "ram";
ipparm "wl=8";
ipparm "size=32";
}
Interface
:
:
:
:
ns(5);
ns(1);
ns(8);
ns(8)) {
Parameters
2
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
3
Who develops ipblock?
GEZEL Designers
GEZEL Users
ipblock
with generic use
design-specific
4
How are ipblock implemented?
aipblock
GEZEL class lib
(data types,
symbol table, ...)
C++
ipblock
statically linked
EXE
dynamic-link library
ld.so
fdlsim/gplatform
5
Operational Principle
•
•
ipblock are cycle-based simulation models
A cycle-based simulation has two phases
per cycle: evaluate and (state) update
R1
logic L1
R2
logic L2
R3
6
Operational Principle
•
•
ipblock are cycle-based simulation models
A cycle-based simulation has two phases
per cycle: evaluate and (state) update
R1
logic L1
R2
R1
R2
logic L2
R3
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;
7
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
logic L1
logic L2
R3
GEZEL ensures that all Evaluate( ) are properly sorted:
Logic_L1(R1) will be called BEFORE Logic L2(L1_output)
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 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')
9
Combinational ipblock
•
By default, have a single evaluate function,
called once per clock cycle
fsmd
ipblock
ipblock
ipblock
OK
Not OK
10
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());
}
+
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();
};
a
b
c
ioval[0]
ioval[1]
ioval[2]
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";
}
C++
class myblock : public aipblock {
public:
• run() is called once per clock cycle
void run();
• 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());
}
13
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 *);
};
void myblock::run() {
ioval[2]->assignulong(ioval[0]->toulong() +
ioval[1]->toulong());
}
call constructor
for each 'ipparm'
call setparam
for each cycle
call run
void myblock::setparam(char *n) {
// ...
}
14
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
C++
• checkterminal verifies that ioval[0] is an
class myblock : public aipblock
{ "a", ioval[1] is input "b", ...
input name
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;
}
15
Terminal-check function
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 *);
void checkterminal(..);
};
call constructor
for each 'ipparm'
call setparam
for each i/o port
call checkterminal
for each cycle
call run
16
Completing the C++
myblock.h
#ifndef myblock_h
#define myblock_h
Access to GEZEL library functions
(aipblock definition, arbitrary-precision data types, ..)
#include "ipblock.h"
extern "C" aipblock *create_myblock(char *instname);
class myblock : public aipblock {
public:
Called by the dynamic-link facility,
myblock(char *name);
Function name depends on class name!
void setparm(char *);
void run();
bool checkterminal(int n, char *tname, aipblock::iodir d);
bool cannotSleepTest();
bool needsWakeupTest();
};
#endif
simulator control
(see part 2)
17
Completing the C++
myblock.cxx
#include "myblock.h"
Called by dynamic-link facility
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
18
Compilation-Simulation Example
Compile:
g++ -fPIC -O3 -I/opt/gezel-2.2/include/gezel -c myblock.cxx
Create dynamic-link library
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
\
19
Compilation-Simulation Example
position-independent code
Compile:
g++ -fPIC -O3 -I/opt/gezel-2.2/include/gezel -c myblock.cxx
.so library
Create dynamic-link library
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
path to gezel lib
gezel lib and predefined ipblocks
arbitrary precision
math lib
dynamic link lib
20
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;
}
21
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
Per clock cycle:
output:
set
a 0
a 1
a 2
a 3
a 4
parm:
b 2 c
b 2 c
b 2 c
b 2 c
b 2 c
thisparam=thatval
2
3
4
5
6
define all FSM next-state
evaluate output of each dp
call ipblock with no output
update dp registers
22
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
23
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
24
Sleep Cycle Mechanism
Software
Hardware
(typ 1Mc/s)
(typ 10K/s)
100K cycles
100 cycles
100K cycles
100 cycles
100K cycles
25
Sleep Cycle Mechanism
Software
Hardware
(typ 1Mc/s)
(typ 10K/s)
100K cycles
100 cycles
100K cycles
100 cycles
100K cycles
Without sleep-cycle:
300,200 cycles @ 10K/s
=
30.02 seconds
26
Sleep Cycle Mechanism
Software
Hardware
(typ 1Mc/s)
(typ 10K/s)
100K cycles
100 cycles
100K cycles
With sleep-cycle:
300K cycles @ 1M/s +
300K cycles (testing_overhead) +
200cycles
cycles @ 10K/s
100K
=
less than 0.5 seconds!
100 cycles
27
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
28
Sleep Cycle Mechanism
•
Transition from active to passive
sleep_test = false
Active
sleep_test = true
wakeup_test = true
Passive
wakeup_test = false
29
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)
30
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)
•
31
Example: 8051 cosimulation interface
8051
4 bi-directional ports
ipblock my8051 {
iptype "i8051system";
ipparm "exec=driver.ihx";
ipparm "verbose=1";
ipparm "period=1";
}
Three GEZEL ipblock:
Core
ipblock my8051_datain(out data : ns(8)) {
iptype "i8051systemsource";
ipparm "core=my8051";
Input port
ipparm "port=P1";
}
ipblock my8051_dataout(in data : ns(8)) {
iptype "i8051systemsink";
ipparm "core=my8051";
ipparm "port=P2";
Output port
}
32
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;
}
33
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)
34
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 function
externalwrite(address, data) each time is performs a port write
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 function
externalwrite(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
36
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;
}
As a result of
the 8051 WRITING
to the hardware,
the cycle-simulation
will wake-up
void i8051systemsource::touch() {
interfacewritten = true;
}
void i8051externalwrite(int dev, unsigned char d) {
i8051devmap[dev]->ioval[0]->assignulong((long) d);
i8051devmap[dev]->touch();
}
37
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();
};
OK!
#endif
38
Ipblock are combinational
•
By default, have a single evaluate function,
run( ), called once per clock cycle
fsmd
ipblock
ipblock
ipblock
OK
Not OK
39
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
40
Support for Sequential IPblock
•
For example, assume you develop a C++
class for this structure:
ipblock
Sequential output
Comb
Function
Combinational output
41
Support for Sequential IP block
•
This will simulate fine !
ipblock
Comb
Function
0
Comb
Function
42
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
43
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
// }
armsfu2x1::armsfu2x1(char *name) : aipblock(name) {
deviceid = 0;
hook = 0;
myarm = 0;
interfacewritten = false;
regOutput(0); // d1 and d2 are registered
regOutput(1);
}
44
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
// }
Stable at the start of a clock cycle
d1
d2
armsfu2x2 q1
q2
Custom
Datapath
(combinational)
OK!
45
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.
46
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();
}
47
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
48