Using Stateflow With the Design Flow
This tutorial demonstrates how to include Stateflow charts in your chip
design, and how to perform a logic verification simulation on your state
machine. It assumes that you already have basic knowledge of how
the use the design flow, and that you have created the Stateflow charts in
your design according to the limitations of the SF2VHD
translator. All the examples use Matlab R11.1, so if you are using any other
version there is no 100% guarantee that these instructions or the flow will
work.
Creating a Stateflow Design
First start up a UNIX shell and make sure that your environment is set up
correctly to run the flow. Then start Matlab (in whichever platform you prefer
-- I've had success using Matlab in both UNIX and NT), and open up the template
library for the flow. Assuming that you ran the startup configuration file which
set up your Matlab path for the flow, you should be able to just type 'template'
at a Matlab command prompt. If for some reason your path does not appear
correct, make sure the directory \\Hitz\Designs\scr\icmake\lib\mdl\R11
is included (at the time this tutorial was written, the libraries referenced were in
this location).
Now create a new Simulink library for your chip design (from the File menu of any Simulink
window) and drag the 'mychip'
mask onto the new window. Right-click on your copy and break the library link.
This gives you your own instance so you can modify it as you wish. Rename this
mask 'statechip' and save the library under the name 'statechip.mdl'. At this
point, your window should look like this:

By double-clicking on the statechip mask, you can verify that it is an
ICDesign subsystem, meaning it is the top level of the chip, and the scan chain
ports are already defined as single bits. Look under the mask. There should only be input and output ports for the scan chain and
nothing else in the subsystem. Now we can begin to create and add our state
machine to this new chip design.
With the current version of the design flow, all your Stateflow charts must
be defined in their own library, and linked to in the actual chip
design. Therefore, we will proceed by creating a new library for our state
machine. Create a new Simulink library, drag the 'myfsm' mask from the template library onto the new library
window, and break the library link. This state
machine will be a 3-bit counter with optional saturation, so rename the mask 'counter'. Look under
the counter mask, and name the Stateflow chart 'counter' as well. You should
always give the subsystem mask and its Stateflow chart the same name to
keep things easy. Save this new library under the name 'fsm.mdl'. Your counter subsystem window should now look like this:

Now that the framework is in place, we can design the state machine.
Double-click the counter, and you will see a blank Stateflow window. The first
step is to create data for the machine from the Add menu. Create a boolean input
from Simulink called 'sat_en' and a uint8 output to Simulink called 'count'.
Don't forget to set the minimum and maximum values for the data: set sat_en to 0
and 1, and count to 0 and 7 respectively (you can do so from the
Tools->Explore menu option if you forgot while creating them). Next create
the states, transitions, and actions based on the picture below. The result is a
state machine which counts from 0 to 7, and restarts from zero if sat_en is low
or stays at 7 while sat_en is high.
While we were designing the state machine, Simulink has been changing things
on the outside. Look at the counter subsystem, and note that there are now ports
on the Stateflow chart. Copy and rename subsystem ports (make sure the names are
exactly the same as the Stateflow data including case) and copy
fixed-point gateways for the new Stateflow data so that the subsystem looks like
this:

Once again, Simulink has been changing things outside this subsystem to keep
up with your work. Look at the top level of the design, and notice that your
counter subsystem mask now has the same ports. As the last step in creating the
state machine, we have to set the proper subsystem parameters. First, we need to
create new parameters for the new data we created. Left-click on the subsystem
mask and choose Edit Mask from the Edit menu. Go to the Initialization tab on
the Mask Editor dialog box and add two new parameters (one after bjcPortTypeIn2
and one after bjcPortTypeOut1). Keep the names the same and increment the
numbering for each data type you add, and set both the Prompt and Variable
fields to the same string. Make sure you set the Assignment field to Literal,
or else you will get errors later. After adding the new output port, the dialog
box should look like this:

Click OK to commit your changes. Now that the mask has the correct parameters
to choose from, you need to set them to the correct values. Double-click the
mask to get the Block Parameters dialog box. You will see a few empty fields,
two of which you just created, and two of which we haven't seen yet.
The new data ports need to have their type set. The numbers at the end of the
parameter name correspond to the numbers on the subsystem ports in the design.
Although it's easy to guess in this example, look back under the subsystem mask
and verify that input port 3 corresponds to sat_en. Since sat_en is a boolean,
we set the type to unit(1), just like the scan chain. For our new output count,
we have to calculate the data type ourselves. Since count is an unsigned integer
with range 0 to 7, we know that it must be 3 bits wide, so set the type to
uint(3). You must perfectly match the data type here with the range in
Stateflow, or else you may get false verification errors.
The last two blank fields are parameters which will be passed to the
translator and VHDL compiler. The bjcView_StateflowChart parameter must be set
to the name of the Stateflow chart itself (not the name of the subsystem mask,
in case you needed to name them differently). In our case, this is 'counter'.
The bjcView_StateflowMDLFile parameter must be set to the name of the MDL file
in which the state machine is defined (in other words, the name of the library
file which contains all our state machines). In our case, this is 'fsm.mdl'.
There is one other option for including Stateflow charts in the design. If
you want to use the translator manually and/or write VHDL yourself, you can
define the elaboration type to be 'VHDL' instead of 'Stateflow'. In this case,
you will need to remove the bjcView_StateflowChart or bjcView_StateflowMDLFile
parameters, and add new parameters called bjcView_SourceFile and
bjcView_EntityName. The source file parameter must be set to the full UNIX path
to the VHDL file to be synthesized. The entity name parameter must be set to the
entity name used in the VHDL file. For more information on how to use the
elaboration type parameters (and all the others), check the ICMake
parameter reference.
The block parameters dialog box should look like this once it's filled in:

Your state machine is finished and stored safely in the fsm.mdl library for
use in a design. Now it's time to add it to a chip and generate some test
vectors. Open up the statechip mask once again, which should still only contain
some ports for the scan chain. Now drag the counter mask from your fsm library
onto the statechip subsystem window. This time, do not break the library
link, since we want the Stateflow chart to stay in its own library. Connect all
the ports of your counter mask to subsystem ports, and make sure all the names
match. You should end up with a window that looks like this (I deleted and
recreated the subsystem port for ScanIn so that the numbers stayed in order):

Those subsystem ports you added need to have parameters added to the
statechip mask. Just like before, create new input and output port types for
sat_en and count, and set all the data types. The block parameters should end up
like this for the statechip mask:

At this point, your chip is ready to be synthesized, floorplanned, and
taped-out by following the general design flow instructions. The rest of this
tutorial will focus on how to perform logic verification for your state machine
(and other modules, if there were any in the design).
Vector Generation
The first step to verify your logic is to simulate the design in Simulink and
generate vectors based on the results. Create a new model (not a library
this time) and drag the statechip mask into the new window (again, you don't
need to break the library link either). Instead of subsytem ports, connect all
the sources and sinks you need to each port in the mask. Our counter is easy to
test -- you only need a step impulse to switch the saturation mode of the
counter. It doesn't matter what you do with the scan chain, as long as you
connect the ports. Insert fixed-point gateways as needed to keep all the blocks
happy. You need to connect every one of your signals (not including the scan
chain) to a workspace output. Set the variable of the workspace output to the
same name as the signal, and set the save format to matrix. This will cause
Matlab to store the value of each input and output at every time interval.

To generate the vectors for this example, I set a simulation time of 40 with
a step from 1 to 0 at time 20 (the sample time of the step was set to 1). Make
sure the simulation is also set at a fixed-step discrete sample time. For this
example, I left the interval on auto, since the integral sample time of the step
impulse will determine the sample time of the system.

Run the simulation, and the value of sat_en and count will be stored in a
matrix in the workspace. Open the workspace browser from the Matlab command
window toolbar, and you should see a matrix for sat_en, count, and tout (the
elapsed time at each sample). Verify that the counter is working properly. Now
export the data in the matrix into a file using the following command at the
Matlab command prompt: save 'filename' variable -ASCII
-double. The filename must follow the following syntax: netlist.signal.type.width.radix.{in,out}.mat. So
for this example, you can either type the following commands (without the
semicolons) or add the lines exactly as they are to an M file:
save 'statechip.sat_en.uint.1.1.in.mat' sat_en -ASCII -double;
save 'statechip.count.uint.3.3.out.mat' count -ASCII -double;
The files will be stored in the current working directory of the Matlab
command shell. You may want to move them to their own directory (like a
subdirectory of the design directory called 'vectors'). The files will be passed
to the m2epic.pl
script during verification to generate EPIC vectors.
Logic Verification and the Flow
We will now use the flow to translate the state machine into VHDL, synthesize
the result, and run a simulation using the vectors generated in the last
section. Open up a UNIX shell and create a new directory for this design. Copy
the following lines, changing my directories to the ones you have been using, into a file called 'ICMakefile' in the new directory:
DESIGN = statechip
SOURCEFILE = statechip.mdl
LIBFILES = fsm.mdl statechip.mdl route.mdl icwire.mdl
MDLPATH = /vol/hitz/vol1/designs/scr/icmake/lib/mdl/R11 /vol/hitz/users/kcamera/Research/tut
TOLERANCE = high
all: bcc elab ein buf sim
sim:
EPIC = statechip fsm counter /vol/hitz/users/kcamera/Research/tut/vectors
A complete description of the ICMakefile can be found in the documentation
for the flow, but I'll describe the basics here. The DESIGN is the name of your
toplevel mask, which has the type ICDesign. The SOURCEFILE is the name of the
Matlab library file which contains your ICDesign. The LIBFILES are a list of
files which the flow will need to reference to build your design. By default,
all designs need the route.mdl and icwire.mdl files, and anything with modules
will need fundamental.mdl as well (we don't use any here, so you don't need it).
For Stateflow blocks, you need to include the file which contains your state
machines as well (ours was fsm.mdl). The MDLPATH line is a list of directories
the flow will search to find the SOURCEFILE and LIBFILES. The first entry is the
location of the flow libraries, and the second entry is where I saved my Matlab
design files. The TOLERANCE setting specifies whether
or not the flow will tolerate errors. At this point, there are still bugs with
Stateflow integration, so you must have this set to high.
The last lines are
makefile-like. The 'all' target specifies what steps the flow should execute
(notice that we do not include any floorplanning or routing, and we do include
simulation). The 'sim' target defines the parameters of the simulation. On the
EPIC line, the 'statechip' represents the prefix of all vector filenames and
the subdirectory which will contain the test files, the 'fsm' is the name of the
library file which contains the simulation target, the 'counter' is the
name of the cell you are simulating (here we can only test the counter
cell itself, since the flow is not yet functional at the toplevel), and the last entry
is the path to the vectors you generated earlier. Note: the whitespace before EPIC is a tab, not spaces
-- last time I checked it must be a tab or else the line will not be properly
parsed.
Before we run the flow, we must generate the SFRESET signal by hand (this is
expected to be fixed later on). Open up one of the input vectors generated by
Matlab (we only have one, sat_en) in an editor, and set the first value to 0.0000000e+000
and all the rest to 1.0000000e+000. Save this file as
'statechip.SFRESET.uint.1.1.in.mat' in the same location as the other vectors.
The state machine will now get one cycle of active reset, and will initialize
properly.
Now all you have to do is type 'icmake' in the same directory as the
ICMakefile, and the flow will do all the work. You will see an error reporting
floating nodes, but that is a known problem and will be ignored due to the high
tolerance setting. When the process is finished, change to the 'epicrun'
subdirectory, and you will see a directory called 'statechip' as you requested
in the ICMakefile. Change to this directory and you will see the Matlab vector
files and lots of new files. Type 'source verify.epi' and the script will
simulate the design and report all deviations from the expected results. When
the script finishes, you will see a line reporting how many errors were found.
You should see the line "No errors reported in the .err file (timemill.err)".
The design is now verifiably working!
If you want to see the waveforms, you can run 'turboWave' and open the file 'timemill.out'.
All outputs will have dummy signals which represent the expected values based on
your Matlab vectors, and the rest are the actual simulation results.
Written by Kevin Camera (kcamera@eecs.berkeley.edu), August 2000
|