Xilinx SysGen Tutorial - YL
Xilinx SysGen Tutorial - YL
User’s Guide
February 16, 2007
*Xilinx ISE Design Suite 11-> DSP Tools - > Xilinx System Generator
*tutorial_simplefir file location:
DSP_Tools\nt\sysgen\examples\demos
A Tutorial Introduction
Getting Started
A simple digital filter implements the following difference equation:
where a is a parameter. The System Generator model for this single-input, single-output system
follows directly from this specification, as shown in Figure 1. (Click to Open this model)
The tapped-delay line is comprised of the System Generator blocks delay, constant, multiplier, and
adder-subtractor. It is embedded in a test circuit, or testbench, that consists of a data source built from
Simulink blocks (the sum of a high frequency and low frequency sine wave) and an output sink
(scope). System Generator “gateway” blocks convert between Simulink’s double-precision floating-
point signals and System Generator’s fixed-point arithmetic type. To run the simulation, click on the
Start Simulation button. Double-clicking on the scope block brings up a graphical display of the
18
Getting Started
input and output of the filter. It can be readily seen that the filter largely eliminates the high frequency
component of the input signal.
graph 1
To construct this model, start MATLAB and open the Simulink library browser by typing
simulink in the command window.
rotate - Ctrl-R
The library taxonomy tree shows installed libraries, and may differ from that shown in Figure 3. Open
a new design by clicking on the “blank page” icon near the upper left corner of the library browser, or
by selecting File->New->Model in the pull-down menu. Construct the model by dragging block icons
from the library browser into the block diagram, and by connecting signals between ports by mouse
dragging between the desired source and sink ports.
To generate a hardware description of the digital filter, double-click on the System Generator block to
open its dialog box (Figure 4). This graphical interface is used to control simulation and code
generation. Selecting HDL Netlist as the compilation target instructs System Generator to generate a
hardware description of the model (in this case, VHDL language) for the specified FPGA (in this case,
Xilinx System Generator User's Guide
www.xilinx.com
20
Getting Started
a Virtex-II xc2v1000 device), into the directory specified as the Target Directory. Assuming you
haven’t made any errors in constructing your model, clicking the Generate button invokes the code
generator and creates the hardware description.
During code generation, any non-Xilinx blocks are discarded. If the Simulink model is called
simple_fir.mdl, then the corresponding top level VHDL entity is in a file named
simple_fir.vhd in the target directory.
graph 2
Some further explanation is in order. System Generator provides two Simulink simulation libraries,
the “Xilinx Blockset” and “Xilinx Reference Blockset”. Each contains blocks that can be used to
construct models in Simulink. These blocks provide arithmetic, logic, memory, and signal processing
abstractions suitable for implementing DSP systems in an FPGA. In addition to these simulation
libraries, System Generator provides implementations for each function, and code generation software
for translating subsystems comprised of Xilinx blocks into hardware descriptions of the system model.
The simulation models are bit-accurate to the hardware description. They are also clock cycle accurate
to the hardware at sample rates observable in Simulink. Consequently, the detailed hardware behavior
can be understood from the Simulink simulation.
A System Generator model is constructed of blocks from the Xilinx blocksets, each of which
Xilinx System Generator User's Guide
www.xilinx.com
21
Getting Started
contributes to the hardware description created by the code generator. Like the testbench in the filter
example, models typically involve other Simulink blocks for providing stimuli to the System Generator
design and for analyzing or visualizing the output of the design. One of the primary advantages of
designing hardware using System Generator is the rich simulation framework Simulink provides to
stimulate, debug, and analyze the executable model.
Every System Generator model must contain a “System Generator” block, which is found in the
“Xilinx Blockset/Basic Elements” library. This block is used to configure and invoke the code
generator, and to resolve the relative time scale between Simulink simulation and the clock signal
running in the FPGA hardware. The “FPGA clock period” defines the clock frequency in hardware,
and the “Simulink System Period” defines the “Simulink time” that corresponds to this clock
frequency. As shown in Figure 4, one second in Simulink corresponds to ten nanoseconds, i.e., a
100MHz clock. It is often expedient to normalize sample times in Simulink to integers for
convenience. The software reports a Simulink error if a model does not contain a System Generator
block.
Each realizable signal (i.e., translatable into hardware) must be sampled and be either a fixed-point or
Boolean type. Simulink allows the modeling of continuous time signals (denoted by a sample time of
zero), but System Generator does not support this abstraction, since its goal is to model realizable
digital systems. Data types and sample rates are propagated through a System Generator model under
normal Simulink propagation rules. This means that any source to a System Generator subsystem must
be sampled and quantized. Signals passing from Simulink blocks to Xilinx blocks must go through
Xilinx gateways, which enforce these constraints. Getting back to the model, double-clicking on the
“gateway in” block exposes the controls by which the signal type can be defined (Figure 5).
An output data type can be boolean, unsigned, or signed two’s complement, with a user-defined
numerical precision. Figure 5 shows a gateway that coerces inputs to be a 14-bit signed two’s
complement value, with 12 fractional bits. The sample time must be a positive number, indicating the
rate at which the input signal is sampled.
In addition to coercing input type, gateways (and indeed most Xilinx blocks) also affect how hardware
is generated. A gateway is ordinarily converted into a port on the top level entity. This port can bound
to a particular input-output block (IOB) on an FPGA.
In Simulink, subsystems play a similar role, providing a means of using hierarchy to manage system
complexity, as well as to reuse components. For example, in DSP applications, a multiply-accumulate
(MAC) function is a commonly occurring function. The System Generator libraries do not provide this
as a primitive block, but one can be easily constructed using a multiplier and accumulator block as
shown in Figure 1. (Click to Open this model)
*tutorial_mac file
location:
DSP_Tools\nt\sysgen\
examples\demos
Left-clicking a bounding box around the multiplier and accumulator blocks selects them in the editor.
Typing Ctrl-g creates a new Simulink subsystem containing the selected blocks, and inserts this
subsystem in place. This subsystem can be copied by right-clicking and dragging the mouse in the
block editor. Double-clicking on the subsystem opens it in the editor. Renaming the input and output
ports with meaningful names (e.g., the port names of the block ports they drive) makes the subsystem
easier to reuse.
Functions become far more useful reusable components when they have parameters (i.e., arguments)
that control their behavior. Similarly, it is often desirable to define parameters on a subsystem that
control its behavior. In Simulink, this is done by “masking” a subsystem (i.e., creating an interface
that provides a “face” or mask to a “caller”). It is then possible to define mask parameters that can be
used within the scope of the subsystem, much as variables can be used in a block-scoped programming
language. This is accomplished by right-clicking on the subsystem as shown in
Once a subsystem has been masked, double-clicking on it opens up a Mask Dialog Box that provides
definitions for its mask parameters. Simulink provides a mask editor for adding mask parameters and
binding graphical controls to their customization. Right-clicking on the masked subsystem and
selecting Edit Mask from the pull-down menu opens up the mask editor. In the case of our MAC
engine, it is useful to define mask parameters to specify the input and output types of the multiplier and
the accumulator (Figure 3).
graph 3
If there are sensible default values for the mask parameters, they can be entered in the mask Dialog
Box. As shown, the precision of the A input is 14 bits with 12 bits of fraction, the B input is 18 bits
with 16 bits of fraction, and the accumulator is defined to have 36 bits.
The mask parameters for the MAC subsystem can be used to control the precision of the multiplier and
accumulator blocks inside the subsystem, so that the blocks automatically change precision when the
MAC parameters are changed. To enter the subsystem in the block editor, right-click and select Look
Under Mask from the pull-down menu.
Parameters do not have to be initialized with constant values. Any parameter that is customized using
a Dialog Box can be defined by a MATLAB expression (including function calls). For example, in the
multiplier block, the precision can set to be a_nbits + b_nbits wide with a_binpt +
b_binpt fractional bits. This ensures that a minimal number of FPGA resources are used, while
avoiding arithmetic overflow. The number of bits in the accumulator should be set to be
accum_nbits.
Defining individual block parameters in terms of a subsystem’s mask parameters allows the
programmer to define broadly parametric models in Simulink. Block customization becomes a
combination of user specification (via dialog boxes), data type propagation (via Simulink’s
propagation rules), and function application. For example, controlling the arithmetic precision by
Xilinx System Generator User's Guide
www.xilinx.com
27
Subsystems and Mask Variables
parameters allows our MAC subsystem to “right-size” itself in response to the context in which it is
instantiated. The implications of having access to the MATLAB interpreter during model
customization should not be underestimated; the simple MAC example barely scratches the surface of
what can be done.
Before moving on, it is worth presenting another way in which MATLAB can be used to customize a
System Generator model. We have seen that Simulink diagrams have scoping rules for mask variables
that are similar to those of a block-scoped programming language, and that block parameters can be
defined in terms of subsystem masks. In fact, there is also a “global” scope that is also available for
setting block parameters; this is the MATLAB workspace.
Any variable that has been defined in the MATLAB workspace (e.g., by typing directly in the
command shell or by executing a MATLAB script) can also be used (subsystem masks can shadow
this). Often during the design phase of an algorithm, it is desirable to iterate through a range of
parameters. By defining workspace variables (say, in a MATLAB script) and binding block
parameters to these variables, it is possible to achieve sweeping parameter changes with local
modifications of a single script.
Simulink provides a mechanism to bind a MATLAB script to a model so that the script is executed
every time the model is opened. This can ensure that every block parameter is well defined. As an
example, suppose the MATLAB script mac_init.m contains the following variable definitions:
a_nbits = 14;
a_binpt = 12; type in all these blanks in Mask Editor
b_nbits = 18;
b_binpt = 16;
accum_nbits = 36;
This script can be bound to the MAC model by opening the top level model (not the MAC subsystem),
typing the following command in the MATLAB command window, and then saving the model.
Every model has many parameters. One of these is the “pre-load” function that Simulink executes
before the model is opened. The set_param command assigns the script mac_init.m to this model
parameter (gcs is a function that returns the current system).
It is now possible to double click on the MAC subsystem and change the default values of the mask
parameters to be a_nbits, a_binpt, b_nbits, b_binpt, accum_nbits rather than constants.
Note the mask parameters shadow the variables defined in the MATLAB workspace.
The Sysgen application provides labeling to denote parts of a model that run at different rates (i.e.,
each portion of a model that runs at a particular rate has the label in the diagram). This can be useful
for a quick visualization of the rates in your system. To turn on this feature, select the Sysgen block
and then modify the Block Icon Display to Sample Rates (See Figure 1: Sample Rates ). After the
next simulation run (Ctrl-t) the ports of blocks will be labeled with related rate information (See
Figure 2).
Simulation -> Start
graph 5
graph 4
Normalized sample
periods
The up-sample and down-sample blocks are used for rate conversion and rate matching. As an
example, the down-sample block can be used to construct a decimating commutator that breaks a data
stream into lower rate polyphase streams. A one-to-two commutator, shown in Figure 2, is
constructed using two down-samplers and a delay block. In this model, the System Generator “Sample
Time” blocks are used to extract the sample periods both before and after the down-sampler to show
the difference in sample times.
Click on this link (Commutator) to open a simulink model containing a fully synthesizable
commutator.
The down-sampler block has mask parameters for controlling the down-sampling factor. It also has a
phase-selection parameter with two choices: the first or last sample of an output frame. When
translating the block into a hardware description, the latter choice is considerably more efficient; it
requires only a single register. Selecting the first sample of a frame (as shown in the example in
Figure 2) results in an additional multiplexer in the hardware, which not only requires additional logic
resources, but also introduces a combinational path into the circuit that can in some circumstances
Interpolating:
zero inserted!
The up-sample block is used for increasing a sample rate by an integer factor. It has two modes. The
first is for use in an interpolator, where zeros are inserted between successive input samples (L-1 zeros
are inserted for an up-sample by L interpolator). The second mode simply copies input samples (L-1
copies are inserted for an up-sample by L rate change). The latter mode is useful because many
System Generator blocks require all inputs to run at the same rate. Both modes are demonstrated in the
model shown in Figure 4.
Interleaving:
the 2nd independent
sample is inserted
In this model, each up-sampler doubles its input rate. The first two up-samplers copy their input
samples so that all inputs to the multiplexer (whose select line is driven by a one-bit counter running at
the up-sampled rate) are the same. The effect is to interleave the two data streams into a single stream
running at twice the rate. The third up-sampler demonstrates the interpolation mode, with a zero
inserted between each input sample.
Branching Constructs
Block diagrams are a natural way to describe many computations, especially data path intensive
systems. System Generator provides a wide variety of blocks for constructing FPGA circuits, ranging
from arithmetic operators and memories, to DSP functions like FIR filters, FFTs, and error correcting
codes. However, there are some functions that are better described using a language other than a
Simulink block diagram. For example, multi-way branching constructs like “switch” and “if then else”
statements are often more conveniently expressed in MATLAB code or a hardware description
language (HDL) than they are in a block diagram.
System Generator provides several mechanisms in addition to the basic logic blocks to facilitate
building “control-oriented” branching functions. The first is a Black Box block that can be used to
import an HDL module written in VHDL or Verilog into Simulink (of course, the HDL module is not
restricted to being a control function). The second mechanism is an m-code block that imports a
MATLAB function into a System Generator model. Yet another mechanism for implementing
sophisticated control functions is an 8-bit microcontroller that has been integrated into the Xilinx
Blockset.
Each of these mechanisms is described in detail later in the User Guide. In this section, we use the
MCode block to implement a finite state machine, a commonly used class of control functions that
involve branching constructs. The MCode block accepts as a parameter a combinational function
written in the MATLAB language. The function can include arbitrarily nested branching statements
(switch, if, then, else), conditional operators, variable assignment, and a limited set of arithmetic
operators.
Consider the following specification of a finite state machine that describes the simplified behavior of
an electric car, with transition function shown in Figure 1.
In the transition diagram, the label a’+b/0 on the arc from the stopped state back to itself is interpreted
to mean that if the accelerator is not pressed or the brake is applied, the state of the machine remains
stopped and the velocity is zero.
Here is the transition function in m-code, which of course can be developed and executed using the
MATLAB interpreter:
In MATLAB, the input arguments can be fixed-point values (System Generator provides a MATLAB
fixed-point type) or double precision. When the function is imported into the m-code block, the types
are inferred from the block inputs. Output types are inferred to be the minimal fixed-point type based
on usage, or can be specified explicitly via constructors based on MATLAB objects.
This style of transition function leads to a classical Huffman state machine implementation (Figure
2).
The System Generator model looks similar to the Huffman machine. The m-function is specified as a
parameter to the m-code block, which customizes its icon to match the inputs and outputs as shown in
Figure 3. The state register is implemented within the mcode persistent variable.
During code generation, the m-function is translated into an equivalent VHDL module. In our
example, the two-state machine is encoded with a one-bit register. For a one-hot state encoding, the
register width would be two bits, and the m-code would be changed to encode states into the values 1
and 2.
Hardware Co-Simulation
System Generator blocksets allow you to construct bit-accurate and cycle-accurate models of an FPGA
circuit in Simulink. Nevertheless, it is universally true that a hardware engineer wants to see the
design running in hardware. System Generator provides hardware co-simulation interfaces that make
it possible to incorporate an FPGA directly into a Simulink simulation. The code generator has
“Hardware Co-simulation” compilation targets (analogous to the HDL Netlist target) that
automatically create a bitstream. After creating the bitstream, System Generator automatically
incorporates an FPGA hardware platform configured with this bitstream back into Simulink as a run-
time block. When the design is simulated in Simulink, results for the compiled portion are calculated
in hardware. This allows the compiled portion to be tested in actual hardware, and can speed up
simulation dramatically. This process and other aspects of hardware co-simulation are the subject of
Chapter 4 of this User Guide.
At this point, we have touched upon some of the mechanics of building FPGA realizations of digital
systems using System Generator. It is possible to build surprisingly useful, high performance systems
using the ideas we have touched upon. And it is probably a good idea to take the time to put this
assertion to the test before continuing with this document.
We have avoided nearly all detail, and of course, understanding the details is required to take full
advantage of the software. The remainder of this User Guide attempts to fill in what has been left out
in this brief introduction. We have not described the blocksets, but they are better explored than
explained. Details for each of the blocks are available in the on-line help (i.e., “Help” button on the
Dialog Boxes) and in the reference material in Chapter 8.
System Generator provides demonstration examples of varying complexity that can be used as starting
points for further exploration (the Xilinx Reference Blockset is another good place to start). Each
design is self-documented, and indicates ways in which you can build efficient hardware using
Simulink as a programming language. To run these demos, type demo in the MATLAB command
window and navigate to the Xilinx Blockset designs.