pj2vlog
or pj2vcs
take?
Q. How does cosimulation work?
Cosimulation works by executing a program in picoJava RTL (pj2vcs/pj2vlog)
and in picoJava IAS. The user executes cosimulation by invoking the
RTL binary pj2vcs
or pj2vlog
with the
+cosim
option. Specifying this option causes
pj2vcs
or pj2vlog
to fire off an IAS process.
the RTL maintains an unnamed pipe along which it communicates to this
child IAS process. Communication between the RTL and IAS is
mostly one-way (RTL to IAS) with only acknowledgments flowing back the other
way (IAS to RTL).
IAS is not invoked specially or with any options - RTL redirects IAS's standard input, and sends along commands on it's STDIN. IAS thinks it's simply reading regular user input.
Note that RTL and IAS are two different processes, with only a pipe connection to communicate on. There is no shared memory - specifically, even though the same loader module (libloader.a) is *linked* in with both the RTL and IAS, there are 2 different instances of this module at run-time, one in each process.
At the end of each instruction or set of instructions completed
by the RTL - that is, when the instruction reaches W-stage,
the compareResults
command is sent across
to IAS along with the values of all RTL
registers, and the top 5 entries of the stack. IAS executes
the instruction(s) using the step
command, and then performs a
comparison between register values and stackTop 1..5 it sees, and
the values it received from RTL.
At the end of the program, RTL sends across compareMemory
commands
for each memory location which cause IAS to compare that memory
location in it's own memory with the RTL's value.
Folding is handled by sending across the number of instructions folded
together in the instruction group which reached the RTL's W-stage. this
information is kept around in the RTL (purely for cosimulation purposes) in a signal
called CPU.iu.ifu.instrs_folded_w
. This value is sent as part of
the arguments to the compareResults
command. IAS then knows how many
instructions to step before performing the comparison.
Q. How are interrupts handled?
In the RTL, interrupts and traps are handled just like
an instruction. A trap pseudo-instruction is introduced into
the pipe, flows down, and completes in the W-stage. Similarly, IAS
counts the action of taking a trap or interrupt as one instruction.
Hence, cosimulation treats each interrupt just like any other instruction,
except that instrs_folded_w
is 0 - if IAS sees this value as 0 in
the compareResults
function, it knows that this must be due to an
interrupt, so it simply steps once.
Note: While IAS takes it's own (emulation and other kinds of) traps,
it is explicitly told by RTL about when to take an interrupt using the
intr
command. Since RTL can be given random interrupts using the
+int_random
option, it is up to RTL to inform IAS
exactly when after which instruction it has taken an interrupt. This means that if for
some reason the RTL does not take an interrupt it should have, this error
will be masked out by cosimulation because IAS on it's own has no way of knowing
that an interrupt was supposed to be taken.
The scheduling feature of IAS interrupts is never used during cosimulation - (RTL gives IAS only non-repeating interrupts with count 0).
Q. How are the stackTop contents handled?
The top 5 entries on the stack are compared, *provided* they are available in the S-Cache memory in the RTL. The number of Stack Cache entries which are valid in any given clock can be determined by comparing OPTOP and SC_BOTTOM. If all top 5 entries are not available in S-Cache memory in the RTL, a magic value (0xdeeddeed) is sent across to IAS in it's place - IAS suppresses compares of that stackTop location if it sees that magic value.
Q. Are memory or cache contents compared between IAS and RTL?
Cache contents cannot be compared between IAS and RTL since there are dribbling differences in IAS and RTL. See IAS documentation on exactly how the stack cache is handled in IAS. This changes D-cache access patterns between IAS and RTL. Therefore, for cosimulation, memory contents are compared between IAS and RTL only at the end of the program. For this comparison to be valid, there must also be no dirty data in the D-Cache, since the IAS and RTL cache contents can be different. Hence, most tests specify an option "-flush" to flush the Dcache at the end of the program.
However, since IAS and RTL implement scache dribbling differently, we could end up with mismatches even after cache flushing in memory locations which have possibly been dribbled to, in either the IAS or RTL.
An example scenario is this: The temporary stack data gets dribbled out to memory in IAS when the number of entries becomes greater than the high watermark. Before RTL can dribble the same data out, the stack entries get popped by the program such that the number of entries is no longer greater than the high watermark. Hence that temporary stack data is never committed to memory in RTL, but has already been committed in IAS.
Such false mismatches occur fairly frequently in practice, so they are suppressed by IAS maintaining watermarks for the minimum and maximum value of sc_bottom whichever occurred during the program, and disabling comparison on this memory area and a small area surrounding this.
Q. What is small compare and big compare?
After reset, only a few registers contain known initial values. Other registers are invalid. Hence we cannot initially compare all registers between IAS and RTL. To solve this problem, we start off in "small compare" mode where only registers known to have a poweron value and the stackTop contents are compared. When reset code sets up deterministic values for all the registers, it typically enables "big compare" (by writing to a magic memory location) and all registers and stacktop contents are compared. A warning is printed when only small compare is being performed, since it could mask miscompares if only small compare is on throughout the simulation.
Q. What options does pj2vlog
or pj2vcs
take?
Here is a detailed list of RTL options. The command "pj2vcs/pj2vlog +usage" will list out the options.
Q. How are these options communicated to IAS?
Usually with a set of magic memory locations. Before the program starts,
RTL sends across a few memPoke commands, which control IAS behaviour.
classes loaded with the +class+<classfile> option are communicated to IAS using
the loadClass
command. RTL also creates a file called
"cos"
in the current
directory which contains the commands it sent across to IAS to perform
the necessary set up. It is useful to execute command "source cos"
in IAS if you are running IAS standalone to recreate a problem
which occurred during cosimulation.
Q. Where is the memory map documented?
In Chapter 2 of the picoJava-II Verification Guide. Also
check $DSVHOME/ldr/src/cm.h
.
Q. What PLI functions are linked in to the RTL?
The functions in $DSVHOME/ldr/src/rw.c
are linked into the RTL.
You can link in PLI's for 3rd party tools like Signalscan following
add PLI instructions.
Q. What files contain the relevant code for cosimulation?
Some important files:
$PICOJAVAHOME/$PROJECT/sim/env/sys.v
and $PICOJAVAHOME/$PROJECT/sim/env/*.v
-
System level testbench - Processes all the
options, communicates with IAS, etc. A thorough read of sys.v
should
answer most questions.
$DSVHOME/ldr/src/rw.c
- PLI functions
$DSVHOME/sim/src/sim.tcl
- Tcl frontend for IAS - provides the functions
for comparison of register or memory contents.