Sysgen User
Sysgen User
Sysgen User
Generator for
DSP
User Guide
R
R
Xilinx is disclosing this Document and Intellectual Property (hereinafter “the Design”) to you for use in the development of designs to operate
on, or interface with Xilinx FPGAs. Except as stated herein, none of the Design may be copied, reproduced, distributed, republished,
downloaded, displayed, posted, or transmitted in any form or by any means including, but not limited to, electronic, mechanical,
photocopying, recording, or otherwise, without the prior written consent of Xilinx. Any unauthorized use of the Design may violate copyright
laws, trademark laws, the laws of privacy and publicity, and communications regulations and statutes.
Xilinx does not assume any liability arising out of the application or use of the Design; nor does Xilinx convey any license under its patents,
copyrights, or any rights of others. You are responsible for obtaining any rights you may require for your use or implementation of the
Design. Xilinx reserves the right to make changes, at any time, to the Design as deemed desirable in the sole discretion of Xilinx. Xilinx
assumes no obligation to correct any errors contained herein or to advise you of any correction if such be made. Xilinx will not assume any
liability for the accuracy or correctness of any engineering or technical support or assistance provided to you in connection with the Design.
THE DESIGN IS PROVIDED “AS IS” WITH ALL FAULTS, AND THE ENTIRE RISK AS TO ITS FUNCTION AND IMPLEMENTATION IS
WITH YOU. YOU ACKNOWLEDGE AND AGREE THAT YOU HAVE NOT RELIED ON ANY ORAL OR WRITTEN INFORMATION OR
ADVICE, WHETHER GIVEN BY XILINX, OR ITS AGENTS OR EMPLOYEES. XILINX MAKES NO OTHER WARRANTIES, WHETHER
EXPRESS, IMPLIED, OR STATUTORY, REGARDING THE DESIGN, INCLUDING ANY WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NONINFRINGEMENT OF THIRD-PARTY RIGHTS.
IN NO EVENT WILL XILINX BE LIABLE FOR ANY CONSEQUENTIAL, INDIRECT, EXEMPLARY, SPECIAL, OR INCIDENTAL
DAMAGES, INCLUDING ANY LOST DATA AND LOST PROFITS, ARISING FROM OR RELATING TO YOUR USE OF THE DESIGN,
EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE TOTAL CUMULATIVE LIABILITY OF XILINX IN
CONNECTION WITH YOUR USE OF THE DESIGN, WHETHER IN CONTRACT OR TORT OR OTHERWISE, WILL IN NO EVENT
EXCEED THE AMOUNT OF FEES PAID BY YOU TO XILINX HEREUNDER FOR USE OF THE DESIGN. YOU ACKNOWLEDGE THAT
THE FEES, IF ANY, REFLECT THE ALLOCATION OF RISK SET FORTH IN THIS AGREEMENT AND THAT XILINX WOULD NOT MAKE
AVAILABLE THE DESIGN TO YOU WITHOUT THESE LIMITATIONS OF LIABILITY.
The Design is not designed or intended for use in the development of on-line control equipment in hazardous environments requiring fail-
safe controls, such as in the operation of nuclear facilities, aircraft navigation or communications systems, air traffic control, life support, or
weapons systems (“High-Risk Applications”). Xilinx specifically disclaims any express or implied warranties of fitness for such High-Risk
Applications. You represent that use of the Design in such High-Risk Applications is fully at your risk.
© 2002-2008 Xilinx, Inc. All rights reserved. XILINX, the Xilinx logo, and other designated brands included herein are trademarks of Xilinx,
Inc. PowerPC is a trademark of IBM, Inc. All other trademarks are the property of their respective owners.
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Preface
Guide Contents
This User Guide contains information the following topics:
• Hardware Design using System Generator
• Hardware Software Co-Design
• Hardware Co-Simulation
• Importing HDL Modules
• System Generator Compilation Types
Additional Resources
To find additional documentation, see the Xilinx website at:
http://www.xilinx.com/literature.
To search the Answer Database of silicon, software, and IP questions and answers, or to
create a technical support WebCase, see the Xilinx website at:
http://www.xilinx.com/support.
Conventions
This document uses the following conventions. An example illustrates each convention.
Typographical
The following typographical conventions are used in this document:
Online Document
The following conventions are used in this document:
Conventions
Chapter 1
Notes for Higher Performance Suggests design practices in System Generator that
FPGA Design lead to an efficient and high-performance
implementation in an FPGA.
Processing a System Generator Describes how to take the low-level HDL produced by
Design with FPGA Physical System Generator and use it in tools like Xilinx's
Design Tools Project Navigator, ModelSim, and Synplicity's
Synplify.
Resetting Auto-Generated Clock Describes the behavior of rate changing blocks from
Enable Logic the System Generator library when the ce_clr signal
is used for re-synchronization.
Design Styles for the DSP48 Describes three ways to implement and configure a
DSP48 (Xtreme DSP Slice) in System Generator
Using FDATool in Digital Filter Demonstrates one way to specify, implement and
Applications simulate a FIR filter using the FDATool block.
Generating Multiple Cycle-True Describes how to implement multi-clock designs in
Islands for Distinct Clocks System Generator
Using ChipScope Pro Analyzer Demonstrated how to connect and use the Xilinx
for Real-Time Hardware Debug Tool called ChipScope Pro within System
Debugging Generator
MHz are common today) and a highly-distributed memory architecture gives the system
designer an ability to exploit parallelism in DSP (and other) applications that operate on
data streams. For example, the raw memory bandwidth of a large FPGA running at a clock
rate of 150 MHz can be hundreds of terabytes per second.
There are many DSP applications (e.g., digital up/down converters) that can be
implemented only in custom integrated circuits (ICs) or in an FPGA; a von Neumann
processor lacks both the compute capability and the memory bandwidth required.
Advantages of using an FPGA include significantly lower non-recurring engineering costs
than those associated with a custom IC (FPGAs are commercial off-the-shelf devices),
shorter time to market, and the configurability of an FPGA, which allows a design to be
modified, even after deployment in an end application.
When working in System Generator, it is important to keep in mind that an FPGA has
many degrees of freedom in implementing signal processing functions. You have, for
example, the freedom to define data path widths throughout your system and to employ
many individual data processors (e.g., multiply-accumulate engines), depending on
system requirements. System Generator provides abstractions that allow you to design for
an FPGA largely by thinking about the algorithm you want to implement. However, the
more you know about the underlying FPGA, the more likely you are to exploit the unique
capabilities an FPGA provides in achieving high performance.
The remainder of this topic is a brief introduction to some of the logic resources available in
the FPGA, so that you gain some appreciation for the abstractions provided in System
Generator.
The figure above shows a physical view of a Virtex-4 FPGA. To a signal DSP engineer, an
FPGA can be thought of as a 2-D array of logic slices striped with columns of hard macro
blocks (block memory and arithmetic blocks) suitable for implementing DSP functions,
embedded within a configurable interconnect mesh. In a Virtex-4 FPGA, the DSP blocks
(shown in the next figure) can run in excess of 450 MHz, and are pitch-matched to dual
port memory blocks (BRAMs) whose ports can be configured to a wide range of word sizes
(18 Kb total per BRAM). The Virtex-4 SX55 device contains 512 such DSP blocks and
BRAMs. In System Generator, you can access all of these resources through arithmetic and
logic abstractions to build very high performance digital filters, FFTs, and other arithmetic
and signal processing functions.
Each logic slice contains two 4-input lookup tables (LUTs), two configurable D-flip flops,
multiplexers, dedicated carry logic, and gates used for creating slice-based multipliers.
Each LUT can implement an arbitrary 4-input Boolean function. Coupled with dedicated
logic for implementing fast carry circuits, the LUTs can also be used to build fast
adder/subtractors and multipliers of essentially any word size. In addition to
implementing Boolean functions, each LUT can also be configured as a 16x1 bit RAM or as
a shift register (SRL16). An SRL16 shift register is a synchronously clocked 16x1 bit delay
line with a dynamically addressable tap point.
In System Generator, these different memory options are represented with higher-level
abstractions. Instead of providing a D-flip flop primitive, System Generator provides a
register of arbitrary size. There are two blocks that provide abstractions of arbitrary
width, arbitrary depth delay lines that map directly onto the SRL16 configuration. The
delay block can be used for pipeline balancing, and can also be used as storage for time-
division multiplexed (TDM) data streams. The addressable shift register (ASR) block,
with a function depicted in the figure below, provides an arbitrary width, arbitrary depth
tapped delay line. This block is of particular interest to the DSP engineer, since it can be
used to implement tapped delay lines as well as sweeping through TDM data streams.
Although random access memories can be constructed either out of the BRAM or LUT
(RAM16x1) primitives, doing so can require considerable care to ensure most efficient
mappings, and considerable clerical attention to detail to correctly assemble the primitives
into larger structures. System Generator removes the need for such tasks.
For example, the dual port RAM (DPRAM) block shown in the figure below maps
efficiently onto as many BRAM or RAM16x1 components on the device as are necessary to
implement the desired memory. As can be seen from the mask dialog box for the DPRAM,
the interface allows you to specify a type of memory (BRAM or RAM16x1), depth (data
width is inferred from the Simulink signal driving a particular input port), initial memory
contents, and other characteristics.
In general, System Generator maps abstractions onto device primitives efficiently, freeing
you from worrying about interconnections between the primitives. System Generator
employs libraries of intellectual property (IP) when appropriate to provide efficient
implementations of functions in the block libraries. In this way, you don’t always have to
have detailed knowledge of the underlying FPGA details. However, when it makes sense
to implement an algorithm using basic functions (e.g., adder, register, memory), System
Generator allows you to exploit your FPGA knowledge while reducing the clerical tasks of
managing all signals explicitly.
System Generator library blocks and the mapping from Simulink to hardware are
described in detail in subsequent topics of this documentation. There is a wealth of
detailed information about FPGAs that can be found online at http://support.xilinx.com,
including data books, application notes, white papers, and technical articles.
Algorithm Exploration
System Generator is particularly useful for algorithm exploration, design prototyping, and
model analysis. When these are the goals, you can use the tool to flesh out an algorithm in
order to get a feel for the design problems that are likely to be faced, and perhaps to
estimate the cost and performance of an implementation in hardware. The work is
preparatory, and there is little need to translate the design into hardware.
In this setting, you assemble key portions of the design without worrying about fine points
or detailed implementation. Simulink blocks and MATLAB M-code provide stimuli for
simulations, and for analyzing results. Resource estimation gives a rough idea of the cost
of the design in hardware. Experiments using hardware generation can suggest the
hardware speeds that are possible.
Once a promising approach has been identified, the design can be fleshed out. System
Generator allows refinements to be done in steps, so some portions of the design can be
made ready for implementation in hardware, while others remain high-level and abstract.
System Generator's facilities for hardware co-simulation are particularly useful when
portions of a design are being refined.
• Project files and scripts that allow various synthesis tools, such as XST and Synplify
Pro to operate on System Generator HDL
• Files that allow the System Generator HDL to be used as a project in Project
Navigator.
For details concerning the files that System Generator writes, see the topic Compilation
Results.
System Generator blocks are bit-accurate and cycle-accurate. Bit-accurate blocks produce
values in Simulink that match corresponding values produced in hardware; cycle-accurate
blocks produce corresponding values at corresponding times.
Xilinx Blockset
The Xilinx Blockset is a family of libraries that contain basic System Generator blocks.
Some blocks are low-level, providing access to device-specific hardware. Others are high-
level, implementing (for example) signal processing and advanced communications
algorithms. For convenience, blocks with broad applicability (e.g., the Gateway I/O
blocks) are members of several libraries. Every block is contained in the Index library. The
libraries are described below.
Library Description
Index Every block in the Xilinx Blockset.
Note: More information concerning blocks can be found in the topic Xilinx Blockset.
Library Description
Communication Blocks commonly used in digital communications systems
Control Logic LogicBlocks used for control circuitry and state machines
DSP Digital signal processing (DSP) blocks
Imaging Image processing blocks
Math Blocks that implement mathematical functions
Each block in this blockset is a composite, i.e., is implemented as a masked subsystem, with
parameters that configure the block.
You can use blocks from the Reference Blockset libraries as is, or as starting points when
constructing designs that have similar characteristics. Each reference block has a
Signal Types
In order to provide bit-accurate simulation of hardware, System Generator blocks operate
on Boolean and arbitrary precision fixed-point values. By contrast, the fundamental scalar
signal type in Simulink is double precision floating point. The connection between Xilinx
blocks and non-Xilinx blocks is provided by gateway blocks. The gateway in converts a
double precision signal into a Xilinx signal, and the gateway out converts a Xilinx signal into
double precision. Simulink continuous time signals must be sampled by the Gateway In
block.
Most Xilinx blocks are polymorphic, i.e., they are able to deduce appropriate output types
based on their input types. When full precision is specified for a block in its parameters
dialog box, System Generator chooses the output type to ensure no precision is lost. Sign
extension and zero padding occur automatically as necessary. User-specified precision is
usually also available. This allows you to set the output type for a block and to specify how
quantization and overflow should be handled. Quantization possibilities include unbiased
rounding towards plus or minus infinity, depending on sign, or truncation. Overflow
options include saturation, truncation, and reporting overflow as an error.
Note: System Generator data types can be displayed by selecting Format > Port Data Types in
Simulink. Displaying data types makes it easy to determine precision throughout a model. If, for
example, the type for a port is Fix_11_9, then the signal is a two's complement signed 11-bit number
having nine fractional bits. Similarly, if the type is Ufix_5_3, then the signal is an unsigned 5-bit
number having three fractional bits.
In the System Generator portion of a Simulink model, every signal must be sampled.
Sample times may be inherited using Simulink's propagation rules, or set explicitly in a
block customization dialog box. When there are feedback loops, System Generator is
sometimes unable to deduce sample periods and/or signal types, in which case the tool
issues an error message. Assert blocks must be inserted into loops to address this problem.
It is not necessary to add assert blocks at every point in a loop; usually it suffices to add an
assert block at one point to “break” the loop.
Note: Simulink can display a model by shading blocks and signals that run at different rates with
different colors (Format > Sample Time Colors in the Simulink pulldown menus). This is often useful
in understanding multirate designs
The Gateway In block is configured with a sample period of one second. The Gateway Out
block converts the Xilinx fixed-point signal back to a double (so it can analyzed in the
Simulink scope), but does not alter sample rates. The scope output below shows the
unaltered and sampled versions of the sine wave.
Multirate Models
System Generator supports multirate designs, i.e., designs having signals running at
several sample rates. System Generator automatically compiles multirate models into
hardware. This allows multirate designs to be implemented in a way that is both natural
and straightforward in Simulink.
Rate-Changing Blocks
System Generator includes blocks that change sample rates. The most basic rate changers
are the Up Sample and Down Sample blocks. As shown in the figure below, these blocks
explicitly change the rate of a signal by a fixed multiple that is specified in the block’s
dialog box.
Other blocks (e.g., the Parallel To Serial and Serial To Parallel converters) change rates
implicitly in a way determined by block parameterization.
Consider the simple multirate example below. This model has two sample periods, SP1
and SP2. The Gateway In dialog box defines the sample period SP1. The Down Sample
block causes a rate change in the model, creating a new rate SP2 which is half as fast as SP1.
Hardware Oversampling
Some System Generator blocks are oversampled, i.e., their internal processing is done at a
rate that is faster than their data rates. In hardware, this means that the block requires more
than one clock cycle to process a data sample. In Simulink such blocks do not have an
observable effect on sample rates.
One block that can be oversampled is the DAFIR FIR filter. An oversampled DAFIR
processes samples serially, thus running at a higher rate, but using less hardware.
Although blocks that are oversampled do not cause an explicit sample rate change in
Simulink, System Generator considers the internal block rate along with all other sample
rates when generating clocking logic for the hardware implementation. This means that
you must consider the internal processing rates of oversampled blocks when you specify
the Simulink system period value in the System Generator block dialog box.
Asynchronous Clocking
System Generator focuses on the design of hardware that is synchronous to a single clock.
It can, under some circumstances, be used to design systems that contain more than one
clock. This is possible provided the design can be partitioned into individual clock
domains with the exchange of information between domains being regulated by dual port
memories and FIFOs. System Generator fully supports such multi-clock designs, including
the ability to simulate them in Simulink and to generate complete hardware descriptions.
Details are discussed in the topic Generating Multiple Cycle-True Islands for Distinct
Clocks. The remainder of this topic focuses exclusively on the clock-synchronous aspects
of System Generator. This discussion is relevant to both single-clock and multiple-clock
designs.
Synchronous Clocking
As shown in the figure below, when you use the System Generator token to compile a
design into hardware, there are three clocking options for Multirate implementation: (1)
Clock Enables (the default), (2) Clock Generator(DCM), and (3) Expose Clock Ports.
Known Limitations: The following System Generator blocks are not supported by the
Clock Generator(DCM) Option:
• Clock Enable Probe
• Clock Probe
• DAFIR
• Downsample - when the Sample option First value of the frame is selected
• FIR Compiler - when the core rate is not equal to the input sample rate
• Parallel to Serial- when the Latency option is specified as 0 (zero)
• Time Division De-Multiplexer
• Time Division Multiplexer
• Upsample - when the Copy samples (otherwise zeros are inserted) option is not
selected.
Note: For Release 10.1, the Clock Generator(DCM) option was tested in hardware using Virtex 4
and Virtex 5 platforms at 400MHz and the Spartan-3A DSP platform at 190MHz.
2. Double-click on the System Generator token to bring up the following dialog box:
As shown above, select Clock Generator(DCM), then click Generate. After a few
moments, a sub-directory named hdl_netlist is created in the current working directory
containing the generated files.
b. Observe that System Generator automatically infers and instantiates the DCM
instance and its parameters according to the required clock outputs.
c. Close the VHDL file.
Next, you are going to examine the clock propagation by examining the ISE timing report.
To be able to see the DCM clock outputs in the ISE timing report, you must first create a
simple user constraint file (UCF).
7. Under the Processes tab > User Constraints, double-click on Create Timing
Constraints. Constrain the design as shown in the figure below, then save the file.
8. Examine the DCM clock outputs: Under Processes tab > Implement Design > Place &
Route > Generate Post-Place & Route Static Timing
9. Once finished, double -click on Analyze Post-Place & Route Static Timing and you
should see the information in the figure below:
The timing report validates the correct clock propagation by System Generator - 10 ns
and 50 ns.
Next you want to perform a behavior simulation using the ModelSim.
10. As shown in the following figure, move to the Sources for dialog box in the Sources
window, then select Behavioral Simulation
Note: System Generator automatically creates the top-wrapper VHDL testbench, script file and
input/output stimulus data files. The Processes tab changes and displays according to the
Sources type being selected.
1. Select
2. Double Click
11. Simulate the design, as shown above, by double-click on Simulate Behavioral Model
in the Processes window
12. After the simulation is finished, you should be able to observe the simulation
waveforms as shown in the figure below:
Summary
When you select the Clock Generator(DCM) option, System Generator automatically
infers and instantiates a DCM without further manual intervention. You do not have to set
attributes or specify DCM clock outputs. Clock rates are determined by the same
methodology when you use the Clock Enables option. You should expect minimal clock
skew when selecting the Clock Generator (DCM) option compared to the Clock Enables
option.
2. Double-click on the System Generator token to bring up the following dialog box:
As shown above, select Expose Clock Ports, then click Generate. After a few moments, a
sub-directory named hdl_netlist is created in the current working directory containing the
generated files.
3. Launch ISE, then load the ISE project at pathname
./hdl_netlist/expose_clock_ports_case1_mcw.ise
4. Under the Project Navigator Processes tab, double-click on Implement Design.
5. From the Project Navigator Sources tab, do the following:
a. double-click on the file expost_clock_ports_case1_mcw.vhd, then scroll
down to view the entity named expose_clock_ports_mcw, as shown below:
b. Observe that System Generator infers the clocks based on the different rates in the
design and brings the clock ports to the top-level wrapper. Since this design
contains two clock rates, clocks clk_1 and clk_5 are pulled to the top-level
wrapper. This will allow you to directly drive the multiple synchronous clocks
from outside the System Generator design.
c. Close the VHDL file.
Next you want to perform a behavior simulation using the ModelSim.
6. As shown below, move to the Sources for dialog box in the Sources window, then
select Behavioral Simulation
Note: System Generator automatically creates the top-wrapper VHDL testbench, script file and
input/output stimulus data files. The Processes tab changes and displays according to the
Sources type being selected.
1. Select
2. Double Click
Summary
When you select the Expose Clock Ports option, System Generator automatically infers the
correct clocks from the design rates and exposes the clock ports in the top-level wrapper.
The clock rates are determined by the same methodology when you use the Clock Enables
option. You can now drive the exposed clock ports from an external synchronous clock
source.
Synchronization Mechanisms
System Generator does not make implicit synchronization mechanisms available. Instead,
synchronization is the responsibility of the designer, and must be done explicitly.
Valid Ports
System Generator provides several blocks (in particular, a FIFO) that can be used for
synchronization. Several blocks provide input (respectively, output) ports that specify
when an input (resp., output) sample is valid. Such ports can be chained, affording a
primitive form of flow control. Blocks with such ports include the FFT, FIR, and Viterbi.
Indeterminate Data
Indeterminate values are common in many hardware simulation environments. Often they
are called “don’t cares” or “Xs”. In particular, values in System Generator simulations can
be indeterminate. A dual port memory block, for example, can produce indeterminate
results if both ports of the memory attempt to write the same address simultaneously.
What actually happens in hardware depends upon effectively random implementation
details that determine which port sees the clock edge first. Allowing values to become
indeterminate gives the system designer greater flexibility. Continuing the example, there
is nothing wrong with writing to memory in an indeterminate fashion if subsequent
processing does not rely on the indeterminate result.
HDL modules that are brought into the simulation through HDL co-simulation are a
common source for indeterminate data samples. System Generator presents indeterminate
values to the inputs of an HDL co-simulating module as the standard logic vector 'XXX . .
. XX'.
Indeterminate values that drive a Gateway Out become what are called NaNs. (NaN
abbreviates “not a number”.) In a Simulink scope, NaN values are not plotted. Conversely,
NaNs that drive a Gateway In become indeterminate values. System Generator provides
an Indeterminate Probe block that allows for the detection of indeterminate values. This
probe cannot be translated into hardware.
In System Generator, any arithmetic signal can be indeterminate, but Boolean signals
cannot be. If a simulation reaches a condition that would force a Boolean to become
indeterminate, the simulation is halted and an error is reported. Many Xilinx blocks have
control ports that only allow Boolean signals as inputs. The rule concerning indeterminate
Booleans means that such blocks never see an indeterminate on a control port
A UFix_1_0 is a type that is equivalent to Boolean except for the above restriction
concerning indeterminate data.
Block Masks
In Simulink, blocks are parameterized through a mechanism called masking. In essence, a
block can be assigned mask variables whose values can be specified by a user through dialog
box prompts or can be calculated in mask initialization commands. Variables are stored in
a mask workspace. A mask workspace is local to the blocks under the mask and cannot be
accessed by external blocks.
Note: It is possible for a mask to access global variables and variables in the base workspace. To
access a base workspace variable, use the MATLAB evalin function. For more information on the
MATLAB and Simulink scoping rules, refer to the manuals titled Using MATLAB and Using Simulink
from The Mathworks, Inc.
Parameter Passing
It is often desirable to pass variables to blocks inside a masked subsystem. Doing so allows
the block’s configuration to be determined by parameters on the enclosing subsystem. This
technique can be applied to parameters on blocks in the Xilinx blockset whose values are
set using a listbox, radio button, or checkbox. For example, when building a subsystem
that consists of a multiply and accumulate block, you can create a parameter on the
subsystem that allows you to specify whether to truncate or round the result. This
parameter will be called trunc_round as shown in the figure below.
As shown below, in the parameter editing dialog for the accumulator and multiplier
blocks, there are radio buttons that allow either the truncate or round option to be selected.
In order to use a parameter rather than the radio button selection, right click on the radio
button and select: “Define With Expression”. A MATLAB expression can then be used as
the parameter setting. In the example below, the trunc_round parameter from the
subsystem mask can be used in both the accumulator and multiply blocks so that each
block will use the same setting from the mask variable on the subsystem.
Resource Estimation
System Generator supplies tools that estimate the FPGA hardware resources needed to
implement a design. Estimates include numbers of slices, lookup tables, flip-flops, block
memories, embedded multipliers, I/O blocks and tristate buffers. These estimates make it
easy to determine how design choices affect hardware requirements. To estimate the
resources needed for a subsystem, drag a Resource Estimator block into the subsystem,
double-click on the estimator, and press the Estimate button.
Compiling and Simulating Using Describes how to use the System Generator block to
the System Generator Block compile designs into equivalent low-level HDL.
Compilation Results Describes the low-level files System Generator
produces when HDL Netlist is selected on the System
Generator block and Generate is pushed.
HDL Testbench Describes the VHDL testbench that System Generator
can produce.
Control Description
Part Defines the FPGA part to be used.
Target Directory Defines where System Generator should write compilation results.
Because System Generator and the FPGA physical design tools
typically create many files, it is best to create a separate target
directory, i.e., a directory other than the directory containing your
Simulink model files. The directory can be an absolute path (e.g.
c:\netlist) or a path relative to the directory containing the model
(e.g. netlist).
Control Description
Synthesis Tool Specifies the tool to be used to synthesize the design. The
possibilities are Synplify, Synplify Pro and Xilinx XST.
Hardware Description Specifies the language to be used for HDL netlist of the design. The
Language possibilities are VHDL and Verilog.
Create Testbench This instructs System Generator to create an HDL testbench.
Simulating the testbench in an HDL simulator compares Simulink
simulation results with ones obtained from the compiled version of
the design. To construct test vectors, System Generator simulates the
design in Simulink, and saves the values seen at gateways. The top
HDL file for the testbench is named <name>_testbench.vhd/.v,
where <name> is a name derived from the portion of the design
being tested and the extension is dependent on the hardware
description language.
Import as Tells System Generator to do two things: 1) Construct a block to
Configurable which the results of compilation are associated, and 2) Construct a
configurable subsystem consisting of the block and the original
subsystem from which the block was derived. See Configurable
Subsystems and System Generator for details.
FPGA Clock Period Defines the period in nanoseconds of the hardware clock. The value
need not be an integer. The period is passed to the Xilinx
implementation tools through a constraints file, where it is used as
the global PERIOD constraint. Multicycle paths are constrained to
integer multiples of this value.
Clock Pin Location Defines the pin location for the hardware clock. This information is
passed to the Xilinx implementation tools through a constraints file.
Multirate Clock Enables (default): Creates a clock enable generator circuit to
implementation drive a multirate design.
Clock Generator(DCM): Creates a clock wrapper with a DCM that
can drive up to three clock ports at different rates for Virtex-4 and
Virtex-5 and up to two clock ports for Spartan-3A DSP. The mapping
of rates to the DCM output ports is done using the following priority
scheme: CLK0 > CLK2x > CLKdv > CLKfx
Expose Clock Ports: This option exposes multiple clock ports on the
top-level of the System Generator design so you can apply multiple
synchronous clock inputs from outside the design.
Provide clock enable This instructs System Generator to provide a ce_clr port on the
clear pin top-level clock wrapper. The ce_clr signal is used to reset the
clock enable generation logic. Capability to reset clock enable
generations logic allows designs to have dynamic control for
specifying the beginning of data path sampling. See the topic for
details.
acceptable. Sample periods arise in three ways: some are specified explicitly, some are
calculated automatically, and some arise implicitly within blocks that involve internal rate
changes. For more information on how the system period setting affects the hardware
clock, refer to Timing and Clocking.
Before running a simulation or compiling the design, System Generator verifies that the
period evenly divides every sample period in the design. If a problem is found, System
Generator opens a dialog box suggesting an appropriate value. Clicking the button labeled
Update instructs System Generator to use the suggested value. To see a summary of period
conflicts, click the button labeled View Conflict Summary. If you allow System Generator
to update the period, you must restart the simulation or compilation.
It is possible to assemble a System Generator model that is inconsistent because its periods
cannot be reconciled. (For example, certain blocks require that they run at the system rate.
Driving an up-sampler with such a block produces an inconsistent model.) If, even after
updating the system period, System Generator reports there are conflicts, then the model is
inconsistent and must be corrected.
The period control is hierarchical; see the discussion of hierarchical controls below for
details.
Hierarchical Controls
The Simulink System Period control (see the topic Simulink System Period above) on the
System Generator block is hierarchical. A hierarchical control on a System Generator block
applies to the portion of the design within the scope of the block, but can be overridden on
other System Generator blocks deeper in the design. For example, suppose Simulink
System Period is set in a System Generator block at the top of the design, but is changed in
a System Generator block within a subsystem S. Then that subsystem will have the second
period, but the rest of the design will use the period set in the top level.
Compilation Results
In topic discusses the low-level files System Generator produces when HDL Netlist is
selected on the System Generator block and Generate is clicked. The files consist of HDL,
NGC and EDIF that implement the design. In addition, System Generator produces
auxiliary files that simplify downstream processing, e.g., bringing the design into Project
Navigator, simulating using an HDL simulator, and synthesizing using various synthesis
tools. All files are written to the target directory specified on the System Generator block. If
no testbench is requested, then the key files produced by System Generator are the
following:
vcom.do This script can be used in ModelSim to compile the HDL for a
behavioral simulation of the design.
If a testbench is requested, then, in addition to the above, System Generator produces files
that allow simulation results to be compared. The comparisons are between Simulink
simulation results and corresponding results from ModelSim. The additional files are the
following:
Constraints Example
The figure below shows a small multirate design and the constraints System Generator
produces for it.
The up sampler doubles the rate, and the down sampler divides the rate by three. Assume
the system clock period is 10 ns. Then the clock periods are 10 ns for the FIR, 20 ns for the
input register, and 30 ns for the output register. The following text describes the constraints
that convey this information.
The lines that indicate the system clock period is10 ns are the following:
# Global period constraint
NET "clk" TNM_NET = "clk_392b7670";
TIMESPEC "TS_clk_392b7670" = PERIOD "clk_392b7670" 10.0 ns HIGH 50 %;
To build timing constraints, the blocks in the design are partitioned into timing groups.
Two blocks are in the same timing group if and only if they run at the same sample rate. In
this design there are three timing groups, corresponding to the three rates. The nature of
constraints dictates that no name is needed for the fastest group. The remaining groups are
named ce_2_392b7670_group and ce_3_392b7670_group; they correspond to periods 20 ns
and 30 ns respectively.
The FIR runs at the system (i.e., fastest) rate and therefore is constrained using the global
period constraint shown above. The logic used to generate clocks always runs at the
system rate and is also constrained to the system rate.
The ce_2_392b7670_group consists of the blocks that operate at half the system rate, i.e., the
input register and the up sampler. Every block in the group is driven by the clock enable
net named ce2_sysgen. The constraints that define the group are the following:
# ce_2_392b7670_group and inner group constraint
Net "ce_2_sg_x0*" TNM_NET = "ce_2_392b7670_group";
TIMESPEC "TS_ce_2_392b7670_group_to_ce_2_392b7670_group" = FROM
"ce_2_392b7670_group" TO "ce_2_392b7670_group" 20.0 ns;
Note: A wildcard character is added to the net name to constrain any additional copies of this net
that may be generated when clock enable logic is replicated. The maximum fanout of a clock enable
net can be controlled in the synthesis tool.
The ce_3_392b7670_group operates at one third the system rate. It contains the down
sampler and the output register, and is defined in a similar manner to the ce2_group.
# ce_3_392b7670_group and inner group constraint
Net "ce_3_sg_x0*" TNM_NET = "ce_3_392b7670_group";
TIMESPEC "TS_ce_3_392b7670_group_to_ce_3_392b7670_group" = FROM
"ce_3_392b7670_group" TO "ce_3_392b7670_group" 30.0 ns;
Group to group constraints establish relative speeds. Here are the constraints that relate
the speeds of ce_2_392b7670_group and ce_3_392b7670_group:
# Group-to-group constraints
TIMESPEC "TS_ce_2_392b7670_group_to_ce_3_392b7670_group" = FROM
"ce_2_392b7670_group" TO "ce_3_392b7670_group" 20.0 ns;
TIMESPEC "TS_ce_3_392b7670_group_to_ce_2_392b7670_group" = FROM
"ce_3_392b7670_group" TO "ce_2_392b7670_group" 20.0 ns;
Port timing requirements can be set in the parameter dialog boxes for gateways. These
requirements are translated into port constraints such as those shown below. In this
example, the 3-bit din input is constrained to operate at its gateway's sample rate
(corresponding to a period of 20 ns). The "FAST" attributes indicate the ports should be
implemented using hardware that reduces delay. The reduction comes at a cost of
increased noise and power consumption.
# Offset in constraints
NET "din(0)" OFFSET = IN : 20.0 : BEFORE "clk";
NET "din(0)" FAST;
NET "din(1)" OFFSET = IN : 20.0 : BEFORE "clk";
NET "din(1)" FAST;
NET "din(2)" OFFSET = IN : 20.0 : BEFORE "clk";
NET "din(2)" FAST;
Selecting Specify IOB Location Constraints for a gateway allows port locations to be
specified. The locations must be entered as a cell array of strings in the box labeled IOB
Pad Locations. Locations are package-specific; in this example a Virtex-E 2000 in a FG680
package is used. The location constraints for the din bus are provided in the dialog box as
"{'D35', 'B36', 'C35' }". This is translated into constraints in the .xcf (or .ncf) file in the
following way:
# Loc constraints
NET "din(2)" LOC = "D35";
NET "din(1)" LOC = "B36";
NET "din(0)" LOC = "C35";
Clock Handling in HDL
be driven by the same clock, ce_1 must be tied high, and ce_2 must vary at a rate half that
of clk_1 and clk_2.
The clock wrapper consists of two components: one for the design itself, and one clock
driver component that generate clocks and clock enables. The clock driver is contained in a
file named <design>_cw.vhd/.v. The logic within the <design>_cw generates the
ce_x signals. The optional ce_clr port would be generated if the design was generated
by selecting Provide clock enable clear pin on the System Generator block. The ports that
are not clocks or clock enables are passed through to the exterior of the clock wrapper.
Schematically, the clock wrapper looks like the diagram below.
Note: The clock wrapper exposes a port named ce. The port does nothing except to serve as a
companion to the clk port on the wrapper. The reason for having the port is to allow the clock wrapper
to be used as a black box in System Generator designs.
Core Caching
System Generator uses cores produced by Xilinx CORE Generator (coregen) to implement
parts of designs. Generating cores can be expensive, so System Generator caches
previously generated ones. Before coregen is called, System Generator looks in the cache,
and if the core has already been generated, System Generator reuses it.
By default, the cache is the directory $TEMP/sg_core_cache. And by default, System
Generator caches no more than 2,000 cores. When the limit is reached, System Generator
deletes cached cores to make room for new ones.
Note: Environment variables can be used to change the location of the cache and the cache size
limit. The variables are described below.
HDL Testbench
Ordinarily, System Generator designs are bit and cycle-accurate, so Simulink simulation
results exactly match those seen in hardware. There are, however, times when it is useful to
compare Simulink simulation results against those obtained from an HDL simulator. In
particular, this makes sense when the design contains black boxes. The Create Testbench
checkbox in the System Generator block makes this possible.
Suppose the design is named <design>, and a System Generator block is placed at the top
of the design. Suppose also that in the block the Compilation field is set to HDL Netlist,
and the Create Testbench checkbox is selected. When the Generate button is clicked,
System Generator produces the usual files for the design, and in addition writes the
following:
1. A file named <design>_tb.vhd/.v that contains a testbench HDL entity;
2. Various .dat files that contain test vectors for use in an HDL testbench simulation.
3. Scripts vcom.do and vsim.do that can be used in ModelSim to compile and simulate
the testbench, comparing Simulink test vectors against those produced in HDL.
System Generator generates the .dat files by saving the values that pass through
gateways. In the HDL simulation, input values from the .dat files are stimuli, and output
values are expected results. The testbench is simply a wrapper that feeds the stimuli to the
HDL for the design, then compares HDL results against expected ones.
Simple Selector
This example is a simple controller for a data path, which assigns the maximum value of
two inputs to the output. The M-function is specified as the following and is saved in an M-
file xlmax.m:
function z = xlmax(x, y)
if x > y
z = x;
else
z = y;
end
The xlmax.m file should be either saved in the same directory of the model file or should
be in the MATLAB path. Once the xlmax.m has been saved to the appropriate place, you
should drag a MCode block into your model, open the block parameter dialog box, and
enter xlmax into the MATLAB Function field. After clicking the OK button, the block has
two input ports x and y, and one output port z.
The following figure shows what the block looks like after the model is compiled. You can
see that the block calculates and sets the necessary fixed-point data type to the output port.
M-functions using Xilinx data types and functions can be tested in the MATLAB command
window. For example, if you type: [z1, z2, z3, z4] = xlSimpleArith(2, 3) in
the MATLAB command window, you'll get the following lines:
UFix(9, 3): 3.500000
Fix(12, 4): -8.687500
Fix(12, 8): 7.996094
Bool: true
Notice that the two integer arguments (2 and 3) are converted to fixed-point numbers
automatically. If you have a floating-point number as an argument, an xfix call is
required.
Two delay blocks are added after the MCode block. By selecting the option Implement
using behavioral HDL on the Delay blocks, the downstream logic synthesis tool is able to
perform the appropriate optimizations to achieve higher performance.
Shift Operations
This example shows how to implement bit-shift operations using the MCode block. Shift
operations are accomplished with multiplication and division by powers of two. For
example, multiplying by 4 is equivalent to a 2-bit left-shift, and dividing by 8 is equivalent
to a 3-bit right-shift. Shift operations are implemented by moving the binary point position
and if necessary, expanding the bit width. Consequently, multiplying a Fix_8_4 number by
4 results in a Fix_8_2 number, and multiplying a Fix_8_4 number by 64 results in a
Fix_10_0 number.
The following shows the xlsimpleshift.m file which specifies one left-shift and one
right-shift:
function [lsh3, rsh2] = xlsimpleshift(din)
% [lsh3, rsh2] = xlsimpleshift(din) does a left shift
% 3 bits and a right shift 2 bits.
% The shift operation is accomplished by
% multiplication and division of power
% of two constant.
lsh3 = din * 8;
rsh2 = din / 4;
The following diagram shows the sub-system after compilation:
To pass parameters to each MCode block in the diagram above, you can click the Edit
Interface button on the block GUI then set the values for the M-function arguments. The
mask for MCode block signed convert 1 is shown below:
The above interface window sets the M-function argument nbits to be 10 and binpt to
be 5. The mask for the MCode block signed convert 2 is shown below:
The above interface window sets the M-function argument nbits to be 8 and binpt to be
4.
The Block Interface Editor of the MCode block labeled add is shown in below.
As a result, the add block features two input ports a and b; it performs full precision
addition. Input parameter sub of the MCode block labeled addsub is not bound with any
value. Consequently, the addsub block features three input ports: a, b, and sub; it
performs full precision addition or subtraction based on the value of input port sub.
The M-function that is used by the MCode block contains a transition function, which
computes the next state based on the current state and the current input. Unlike example 3
though, the M-function in this example defines persistent state variables to store the state
of the finite state machine in the MCode block. The following M-code, which defines
function detect1011_w_state is contained in file detect1011_w_state.m:
function matched = detect1011_w_state(din)
% This is the detect1011 function with states for detecting a
% pattern of 1011.
switch state
case seen_none
if din==1
state = seen_1;
else
state = seen_none;
end
case seen_1 % seen first 1
if din==1
state = seen_1;
else
state = seen_10;
end
case seen_10 % seen 10
if din==1
state = seen_101;
else
% no part of sequence seen, go to seen_none
state = seen_none;
end
case seen_101
if din==1
state = seen_1;
matched = true;
else
state = seen_10;
matched = false;
end
end
The following diagram shows a state machine subsystem containing a MCode block after
compilation; the MCode block uses M-function detect1101_w_state.
Parameterizable Accumulator
This example shows how to use the MCode block to build an accumulator using persistent
state variables and parameters to provide implementation flexibility. The following M-
code, which defines function xl_accum is contained in file xl_accum.m:
function q = xl_accum(b, rst, load, en, nbits, ov, op,
feed_back_down_scale)
% q = xl_accum(b, rst, nbits, ov, op, feed_back_down_scale) is
% equivalent to our Accumulator block.
binpt = xl_binpt(b);
init = 0;
precision = {xlSigned, nbits, binpt, xlTruncate, ov};
persistent s, s = xl_state(init, precision);
q = s;
if rst
if load
% reset from the input port
s = b;
else
Optional inputs rst and load of block Accum_MCode1 are disabled in the cell array of the
Function Parameter Bindings parameter. The block mask for block MCode Accumulator is
shown below:
The example contains two additional accumulator subsystems with MCode blocks using
the same M-function, but different parameter settings to accomplish different accumulator
implementations.
The model contains two FIR blocks. Both are modeled with the MCode block and both are
synthesizable. The following are the two functions that model those two blocks.
function y = simple_fir(x, lat, coefs, len, c_nbits, c_binpt, o_nbits,
o_binpt)
coef_prec = {xlSigned, c_nbits, c_binpt, xlRound, xlWrap};
out_prec = {xlSigned, o_nbits, o_binpt};
sum = x * coef_vec(0);
for idx = 1:len-1
sum = sum + x_line(idx-1) * coef_vec(idx);
sum = xfix(out_prec, sum);
end
y = p.back;
p.push_front_pop_back(sum);
x_line.push_front_pop_back(x);
function y = fir_transpose(x, lat, coefs, len, c_nbits, c_binpt,
o_nbits, o_binpt)
coef_prec = {xlSigned, c_nbits, c_binpt, xlRound, xlWrap};
out_prec = {xlSigned, o_nbits, o_binpt};
coefs_xfix = xfix(coef_prec, coefs);
persistent coef_vec, coef_vec = xl_state(coefs_xfix, coef_prec);
In order to verify that the functionality of two blocks are equal, we also use another MCode
block to compare the outputs of two blocks. If the two outputs are not equal at any given
time, the error checking block will report the error. The following function does the error
checking:
function eq = error_ne(a, b, report, mod)
persistent cnt, cnt = xl_state(0, {xlUnsigned, 16, 0});
switch mod
case 1
eq = a==b;
case 2
eq = isnan(a) || isnan(b) || a == b;
case 3
eq = ~isnan(a) && ~isnan(b) && a == b;
otherwise
eq = false;
error(['wrong value of mode ', num2str(mod)]);
end
if report
if ~eq
error(['two inputs are not equal at time ', num2str(cnt)]);
end
end
cnt = cnt + 1;
The block is configured as following:
RPN Calculator
This example shows how to use the MCode block to model a RPN calculator which is a
stack machine. The block is synthesizable.
OP_NEG = 5;
OP_DROP = 6;
q = acc;
active = acc_active;
if rst
acc = 0;
acc_active = false;
stack_pt = 0;
elseif en
if ~is_oper
% enter data, push
if acc_active
stack_pt = xfix(stack_pt_prec, stack_pt + 1);
mem(stack_pt) = acc;
stack_active = true;
else
acc_active = true;
end
acc = din;
else
if op == OP_NEG
% unary op, no stack op
acc = -acc;
elseif stack_active
b = mem(stack_pt);
switch double(op)
case OP_ADD
acc = acc + b;
case OP_SUB
acc = b - acc ;
case OP_MULT
acc = acc * b;
case OP_DROP
acc = b;
end
stack_pt = stack_pt - 1;
elseif acc_active
acc_active = false;
acc = 0;
end
end
end
stack_active = stack_pt ~= 0;
Here are the lines that are displayed on the MATLAB console for the first simulation step.
mcode_block_disp/MCode (Simulink time: 0.000000, FPGA clock: 0)
Hello World!
num2str(dly) is [0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000]
disp(dly) is
type: Fix_11_7,
maxlen: 8,
length: 8,
0: binary 0000.0000000, double 0.000000,
1: binary 0000.0000000, double 0.000000,
2: binary 0000.0000000, double 0.000000,
3: binary 0000.0000000, double 0.000000,
4: binary 0000.0000000, double 0.000000,
5: binary 0000.0000000, double 0.000000,
6: binary 0000.0000000, double 0.000000,
7: binary 0000.0000000, double 0.000000,
disp(rom) is
type: Fix_11_7,
maxlen: 4,
length: 4,
0: binary 0011.0000000, double 3.0,
1: binary 0010.0000000, double 2.0,
2: binary 0001.0000000, double 1.0,
3: binary 0000.0000000, double 0.0,
a = 0.000000, b = 0.000000, x = 0.000000
1
disp(10) is
type: UFix_4_0, binary: 1010, double: 10.0
disp(-10) is
type: Fix_5_0, binary: 10110, double: -10.0
disp(a) is
type: Fix_11_7, binary: 0000.0000000, double: 0.000000
disp(a == b)
type: Bool, binary: 1, double: 1
A Step-by-Step Example
In this example, two HDL netlists from System Generator are integrated into a larger
VHDL design. Design #1 is named SPRAM and design #2 is named MAC_FIR. The top-
level VHDL entity combines the two data ports and a control signal from the SPRAM
design to create a bidirectional bus. The top-level VHDL also instantiates the MAC_FIR
design and supplies a separate clock signal named clk2. A block diagram of this design is
shown below.
The files used in this example are located in the System Generator tree at pathname
<sysgen_tree>/examples/projnav/mult_diff_designs. The following files are
provided:
• spram.mdl - System Generator design #1
• mac_fir.mdl - System Generator design #2
Files within the sub-directory named top_level:
• top_level.ise – ProjNav project for compiling top_level design
• top_level.vhd – Top-level VHDL file
• top_level_testbench.do – Custom ModelSim .do file
• top_level_testbench.vhd – Top-level VHDL testbench file
• wave.do – ModelSim .do file called by top_level_testbench.do to display
waveforms
2. Add the System Generator source: under the Sources tab, right-click on
u_spram_cw -> Add Source…at
<sysgen_tree>/examples/projnav/mult_diff_designs/hdl_netlist1/s
pram_cw.sgp
3. Repeat item 2 with u_mac_fir at
<sysgen_tree>/examples/projnav/mult_diff_designs/hdl_netlist2/m
ac_fir_cw.sgp
4. As shown below, make sure the file top_level is selected, then implement the design
by double clicking on Processes tab > Implement Design. Once the implementation is
finished, Project Navigator should look like the figure below.
5. Examine the timing constraints in the PAR report file: Processes tab > Implement
Design > Place & Route > Place & Route Report
Note that in the PAR report the multirate constraints were met:
Constraints for each System Generator design were created and translated to a UCF (User
Constraint File). These UCF constraint files were then consolidated and associated during
ISE implementation (NGDBUILD). They are briefly described as follows:
A system sample period of 100 ns was set in the System Generator block for both designs
(1 & 2)
• TS_clk_f488215c2 constraints are from the SRAM design (1)
• The TS_clk_c4b7e2441 constraints are from the FIR design (2)
• The ce16_c4b7e244_group_to_ce16_cb47e244_group1 constraint is for all the
synchronous elements after the down sampler and it is set to sixteen, the system
sample period (3)
• The down sampling block in the SRAM design performs a down sample by 2. The
ce2_f488215c_group_to_ce2_f488215c_group2 constraint is for all the synchronous
elements after the down sampler and is set to twice the system sample period (4)
With the new integration between System Generator and Project Navigator, these
constraints are automatically associated and consolidated by Project Navigator up to the
top-level design. This flow is only available starting with Release 10.1.
The previous screen shot shows the ModelSim commands used to compile the VHDL code
generated by System Generator. To simulate the top_level design, double left click on the
Simulate Behavioral Model process. The ModelSim .do file compiles the VHDL code and
runs the simulation for 10000 ns. The resulting waveform is shown below.
Summary
This topic has shown you how to import a System Generator Design into a larger system.
There are a few important things to keep in mind during each phase of the process.
While creating a System Generator design:
• IOB constraints should not be specified on Gateways in the System Generator model;
neither should the System Generator block specify a clock pin location.
• Use the HDL Netlist compilation target in the System Generator block. The HDL
Netlist file that System Generator produces contains both the RTL, EDIF and
constraint information for your design.
To instantiate the System Generator design in the top_level HDL:
• Use a black box and assign the appropriate black box attribute The ce port is not
connected to registers within your design. It is provide so that the VHDL file can be
imported as a Black Box within System Generator.
For top-level simulation:
• Create a custom ModelSim .do file in order to compile the VHDL files created by
System Generator. Modify the Project Navigator settings to use this custom .do file
New capabilities:
• Add System Generator Source type project file (.sgp) into Project Navigator as a sub-
module design
• Consolidate and associate System Generator constraints into the top-level design
• Launch MATLAB and System Generator MDL directly from Project Navigator to
perform certain design iterations
• Drag a template block into the library. (Templates can be found in the Simulink library
browser under Simulink/Ports & Subsystems/Configurable Subsystem.)
• Right-click on the instance, and under Block choice select the block that should be
used as the underlying implementation for the instance.
• Double click on the template, and turn on the checkbox next to the added block.
• Drag a manager block into the subsystem opened above. (The manager block can be
found in Xilinx Blockset/Tools/Configurable Subsystem Manager).
• Double click to open the GUI on the manager, then select the block that should be
used for hardware generation in the configurable subsystem.
HDL Simulation
System Generator creates custom .do files for use with your generated project and a
ModelSim simulator. To use these files, you must have ModelSim (PE or EE/SE) or the
Xilinx Edition of ModelSim (MXE). You may run your simulations from the standalone
ModelSim tool, or you may associate it with the Xilinx ISE Project Navigator, and run your
simulations from within Project Navigator as part of the full software implementation
flow.
Compiling Your IP
Before you can simulate your design, you must compile your IP (cores) libraries with
ModelSim.
xlDoc
If you plan to use ModelSim XE (Xilinx Edition), download the MXE pre-compiled
libraries from the Xilinx web site. The latest libraries are located at:
http://www.xilinx.com/ise/optional_prod/mxe.htm
Unzip these MXE libraries into your MXE installed directory, e.g.: C:/Modeltech_XE/.
This is the location where MXE expects to find your Xilinx compiled libraries, so you do
not need to make any changes to your modelsim.ini file. This file should point to the
correct installed location.
The Project Navigator project is already set up to run simulations at four different stages of
implementation. System Generator creates four different ModelSim .do files when the
Create Testbench option is selected on the System Generator block. The ModelSim do files
created by System Generator are:
• pn_behavioral.do - for a behavioral (HDL) simulation on the HDL files in the
project, before any synthesis or implementation.
• pn_posttranslate.do - this file runs a simulation on the output of the Xilinx
translation (ngdbuild) step, the first step of implementation.
• pn_postmap.do - to run a simulation after your design has been mapped. This file
also includes a back-annotated simulation on the post-mapped design.
• pn_postpar.do - to run a simulation after your design has been placed and routed.
This file also includes a back-annotated simulation step.
In the Project Navigator Sources window, use the pull-down menu labeled Sources for
to select Behavioral Simulation, Post-Translate Simulation, Post-Map Simulation, or Post-
Route Simulation (corresponding to pn_behavioral.do, pn_posttranslate.do,
pn_postmap.do, and pn_postpar.do respectively).
If you select the <your design>_tb.vhd/.v file in the Project Navigator Sources
window, the ModelSim Simulator will become available in the Process window. Expand
the ModelSim Simulator process by clicking on the plus button to the left of it. A
simulation process associated with the ModelSim Simulator will appear (in the image
below the process is labeled Simulate Behavioral Model).
The Process Properties dialog box shows that the System Generator.do file is already
associated as a custom file for this process.
Now if you double-click on the simulation process, the ModelSim console opens, and the
associated custom do file is used to compile and run your System Generator testbench. The
testbench uses the same input stimuli that was generated in Simulink, and compares the
HDL simulation results with the Simulink results. Provided that your design was error
free, ModelSim reports that the simulation finished without errors.
This brings up the Project Properties window. From this window, you can change your
part, package, speed, and synthesis compiler. Note that if you change the device family, the
Xilinx IP cores that were produced by System Generator must be regenerated. In such a
case, it is better if you return to the System Generator and re-generate your project.
In the Processes window, if you right-click on Generate Programming File and select Run,
you are instructing Project Navigator to run through whatever processes are necessary to
produce a programming file (FPGA bitstream) from the selected HDL source. In the
messages console window, you see that Project Navigator is synthesizing, translating,
mapping, routing, and generating a bitstream for your design.
Now that you have generated a bitstream for your design, you have access to all the files
that were produced on the way to bitstream creation.
The effect of ce_clr signal cannot be simulated using the original System Generator
design. To model this behavior within Simulink follow the steps below:
1. Select Provide clock enable clear pin and NGC Netlist Compilation option on the
System Generator block.
2. Press the Generate button on the System Generator block.
3. Run the following command from the MATLAB console to produce the post translate
VHDL netlist. Use “-ofmt verilog” with netgen for generating Verilog netlist:
>> !netgen -ofmt vhdl ./<target_directory>/<design_name>_cw.ngc
4. Bring in the post translate VHDL/Verilog file as a Black Box within Simulink and use
HDL co-simulation to model the effect of asserting ce_clr signal on your design.
Synchronized to
ce after ce_clr
Synchronized Behavior after ce_clr is de-asserted
Block Name deasserted
to ce_clr and the next ce pulse
( 1 sample cycle
delay)
Down Sampler Yes N/A The last sampled value is held till the
with Last Value new ce signal arrives.
of frame
Down Sampler No No Re-synchronization does not occur
with First Value after de-assertion of the ce_clr signal.
of frame
Up Sampler Yes N/A In hardware, this block is
with copy implemented as a wire.
samples
Up Sampler No Yes The last value (zero or sample) is held
with zeros till the next destination ce signal
inserted arrives.
Time Division No Yes The TDM block samples through all
Multiplexer the remaining input channels and
then sets the output to 0 till the next ce
arrives. The new ce signal re-
synchronizes the output to the new
frame definition.
Time Division No Yes The TDD block holds the output
Demultiplexer channels to the same value till the
next ce signal arrives. The new ce
signal re-synchronizes the output to
the new frame definition.
Parallel to Serial No Yes The p2s block samples through all the
remaining data words and then holds
the output to the last sampled word
until the next ce arrives. The new ce
signal starts the conversion of the
parallel data stream to a serial one.
Serial to Parallel No Yes The s2p block holds the output when
the ce_clr is asserted. When de-
asserted, the input is sampled on the
last value of the input sample frame,
and the output occurs on the first ce
pulse corresponding to the output
rate.
Synchronized to
ce after ce_clr
Synchronized Behavior after ce_clr is de-asserted
Block Name deasserted
to ce_clr and the next ce pulse
( 1 sample cycle
delay)
The ASR block will hold the values in
the shift register when ce_clr is
Addressable
asserted. When de-asserted, the
Shift Register No Yes
stored values will be shifted out, and
(ASR)
new data will be put into the shift
register.
Interpolating or Decimating FIR does
not work with the ce_clr signal unless
Polyphase FIR No No
the optional reset port is used to reset
the FIR after the ce_clr is de-asserted.
B, BCIN BCOUT
18 18
A
18 P, PCOUT
48
PCIN
48
C
48 = optional register with
optional reset and
Op to various clock enable
11 control ports
The DSP48 combines an 18-bit by 18-bit signed multiplier with a 48-bit adder and a
programmable mux to select the adder's inputs. It implements the basic operation: "p=a*b
+(c+cin);", however other operations can be selected dynamically. Optional input and
multiplier pipeline registers are also included and must be used to achieve maximum
speed. Also included with the DSP48 are high performance local interconnects between
adjacent DSP48 blocks (BCIN-BCOUT and PCIN-PCOUT). The DSP48 also includes
support for symmetric rounding. This combination of features enables DSP systems which
use the higher-speedDSP48 devices to be clocked at over 500 MHz.
There are three ways to program a DSP48 in System Generator:
• Use Standard Components - Map designs to Mult and AddSub blocks or use higher-
level IP such as the MACFIR filter generator blocks. This approach is useful if the
design needs to be compatible with V2P or S3 devices or uses a lower-speed clock and
the mapping to DSP48s is not required.
• Use Synthesizable Blocks - Structure the design to map onto the DSP48's internal
architecture and compose the design from synthesizable Mult, AddSub, Mux and
Delay blocks. This approach relies on logic synthesis to infer DSP48 blocks where
appropriate. This approach gives the compiler the most freedom and can often
achieve full-rate performance.
• Use DSP48 Blocks - Use System Generator's DSP48 and DSP48 Macro blocks to
directly implement DSP48-based designs. This is the highest performance design
technique. Be aware however that obtaining maximum performance and minimum
area for designs using DSP48s may require careful mapping of the target algorithm to
the DSP48's internal architecture, as well as the physical planning of the design.
To obtain the best possible performance, you should set the multiplier latency to 3 and
include an input register to cover the delay from the DSP48's output to the adder. The
performance of this circuit is in the 200-300 MHz range with V-44-11 devices, and is limited
by the adder speed. In Virtex-4, unlike V2P and S3 devices, the multiply speed in nearly
independent of bit width. For medium speed designs, this approach works fine.
An additional way to use the DSP48 is to use IP blocks optimized for the DSP48 such as the
MACFIR block available from coregen, or to use the architecture wizard to generate a
custom configured DSP48. Both of these approached require importing the logic
containing the DSP48 as a black box into System Generator. Simulation will require
modelsim HDL cosim.
If the design is composed of synthesizable blocks, both Synplify Pro and XST have
demonstrated the ability to infer DSP48s and to make use of the DSP48's local interconnect
buses (PCOUT-PCIN and BCOUT-BCIN). In the above example, three blocks have been
built using the MCode blocks which are defined by the following M-functions.
function o = xlsynmux2(i0,i1,sel)
if (sel==0) o=i0; else o=i1; end
function p = xlsynmult(a,b)
p=a*b;
function s = xlsynadd(a,b)
s=a+b;
For synthesis to work, the circuit must be mappable to the DSP48 and signal bitwidths
must be less than the equivalent buses in the DPS48.
You should kept in mind that the logic synthesis tools are rapidly evolving and that
inferring DPS48 configurations is more of an art than a science. This means that some
mappable designs may not be mapped efficiently, or that the mapping results may not be
consistent. It will be necessary to inspect the post synthesis netlist using a tool similar to
Synplify Pro's gate-level technology viewer to determine if the design is being correctly
mapped. If not, it may be possible to recast it to be correctly inferred. A model of a fully
synthesizable FIR filter is located at the follwing pathname in the System Generator
software tree:
.../sysgen/examples/dsp48/synth_fir/synth_fir_tb.mdl
The DSP48 block is effectively a wrapper for the DSP48 UNISIM primitive. Because of this,
any possible DSP48 design can be implemented. This low-level implementation however
requires an 11-bit binary opmode to be routed to the DSP48's control ports in order to
configure its function. The Constant block has a special mode enabling it to generate a
DSP48 control field. The DSP48's parameters dialog box is used to configure the pipelining
mode of the DSP48 as well as the use of the DSP48's local interconnect buses named
PCOUT-PCIN and BCOUT-BCIN. You can try out the DSP48 block by opening the
simulink model that is located at the follwing pathname in the System Generator software
tree:
.../sysgen/examples/dsp48/dsp48_primitive.mdl
method of generating this type of control pattern is to use a mux to select the DSP48
instruction on a clock by clock basis.
The above example illustrates the use of a DSP48 and Constant blocks to implement a 35-
bit by 35-bit multiplier over 4 clock cycles. During synthesis, the mux and constant logic is
reduced by logic optimization. In the example above, the DSP48 block and the 4:1 mux are
reduced to just two 4-LUTs. A Simulink model that illustrates how to implement both
parallel and sequential 35*35-bit multipliers using dynamic operation for the sequential
mode of operation is located at the follwing pathname in the System Generator software
tree:
.../sysgen/examples/dsp48/mult35x35/mult35x35_tb.mdl
The DSP48 Macro block is a wrapper for the DSP48 block which makes it simple to
implement a sequence of DSP48 instructions (known as dynamic instructions). In addition,
it provides support for specifying input and output types. For example, in the model
above, a DSP48 Macro block is configured to implement a complex multiplier using a
sequence of four different instructions. The instructions are entered in a text window in the
DSP48 Macro's dialog menu. You can try out the DSP48 Macro block by opening the
simulink model that is located at the follwing pathname in the System Generator software
tree:
.../sysgen/examples/dsp48/dsp48_macro.mdl
1. Always use DSP48, BRAM16, FIFO16 with input, mult and output registers
2. Use additional FF to buffer DSP48 and BRAM outputs if necessary
3. Plan out the usage of the PCOUT-PCIN bus to allow DSP48 chaining
4. Add registers to any path that is greater than 20 - 40 slices long
5. Limit fanout to 32 loads located within a 20 slice distance
6. Add output registers to any LUT-based logic
7. Limit LUTs to 1 level or a 4:1 MUX and insure a local register for input or output
8. Use RAMs, SRL16 to clock out control patterns instead of state machines
9. Use DSP48 to implement counters and adders greater than 8-16 bits
10. Use area constraints – "INST ff1* LOC = SLICE_X0Y8:SLICE_X1Y23;"
C-Input Sharing
Each pair of DSP48s share a single C input. You should be aware of this when you do
resource planning. Since the placer will not always find the most optimal placement to
share C inputs, DSP48s should avoid using C inputs if possible.
Placement
Most designs will benefit from some placement of DSP48 and BRAMs. Use of area
constraints to constrain LUT fabric logic placement may also be beneficial.
Generator upsampled and downsampled clock domains. This requires the manual use of
clock enables for logic that runs at less than the system clock rate.
Synthesis Flow
• Use Synplify Pro with retiming and pipelining enabled to avoid having to manually
pipeline every LUT and signal.
• Use Synplify Pro with the fanout limit set around 32 to avoid long net delays.
• Open compiled projects in Synplify Pro and inspect the generated logic using the
RTL- and Gate-level views to get a good idea of what logic is being generated.
• The file syn.pl is available in the examples/dsp48 directory. Place this file in
<sysgen_tree>/scripts directory to modify the synthesis options in System
Generator
Fanout Planning
Avoid fanouts of more than 32 LUTs or 8 DSP48s or BRAMs. This can be avoided by
inserting additional pipeline registers in these signals paths.
Register Retiming
Check retiming on delay blocks to allow them to be used as registers for pipelining. Then
use Synplify Pro or XST with retiming enabled to allow the synthesis tool to move registers
into optimal positions.
Although a single MAC engine FIR filter is used for this example, we strongly recommend
that you look at the DSP Reference Library provided as a part of the Xilinx Reference
Blockset. The DSP Reference Library consists of multi-MAC, as well as, multi-channel
implementation examples with variations on the type of memory used.
A demo included in the System Generator demos library also shows an efficient way to
implement a MAC-based interpolation filter. To see the demo, type the following in the
MATLAB command window:
>> demo blockset xilinx
then select FIR filtering: Polyphase 1:8 filter using SRL16Es from the list of demo designs.
Design Overview
This design uses the random number source block from the DSP Blockset library to drive
two different implementations of a FIR filter:
• The first filter is the one that could be implemented in a Xilinx device. It is a fixed-
point FIR filter implemented with a dual-port Block memory and a single multiply-
accumulator.
• The second filter is what is refered to as reference filter. It is a double-precision, direct-
form II transpose filter.
The frequency response of each filter is then plotted in a transfer function scope.
6. Enter the parameter values for coef, coef_width, coef_binpt, data_width, data_binpt
and Fs as shown below.
In order to be able to preload the coefficients without having to regenerate them with
the FDA Tool each time, the mac_df2t.mdl simulink model is opened, you are now
going to save it into a file.
At this point, the MAC filter is set up for a 10-bit signed input data (Fix_10_8), a 12-bit
signed coefficient (Fix_12_12), and 43 taps. All these parameters can be modified directly
from the MAC block GUI. The coefficients and data need to be stored in a memory system.
For the tutorial, you choose to use a dual-port memory to store the data and coefficients,
with the data being captured and read out using a circular RAM buffer. The RAM is used
in a mixed-mode configuration: values are written and read from port A (RAM mode), and
the coefficients are only read from port B (ROM mode).
The multiplier is set up to use the embedded multiplier resource available in Xilinx Virtex-
II and Virtex-II Pro devices as well as three levels of latency in order to achieve the fastest
performance possible. The precision required for the multiplier and the accumulator is a
function of the filter taps (coefficients) and the number of taps. Since these are fixed at
design time, it is possible to tailor the hardware resources to the filter specification. The
accumulator need only have sufficient precision to accumulate maximal input against the
filter taps, which is calculated asa follows:
acc_nbits = ceil(log2(sum(abs(coef*2^coef_width_bp)))) + data_width+ 1;
Upon reset, the accumulator re-initializes to its current input value rather than zero, which
allows the MAC engine to stream data without stalling. A capture register is required for
streaming operation since the MAC engine reloads its accumulator with an incoming
sample after computing the last partial product for an output sample.
Finally, a downsampler reduces the capture register sample period to the output sample
period. The block is configured with latency to obtain the most efficient hardware
implementation. The downsampling rate is equal to the coefficient array length.
You can now run the simulation and notice that the Xilinx implementation of the MAC-
based FIR filter meets the original filter specifications and that its frequency response is
almost identical to the double precision Simulink models.
As you can see, the filter passband response measurement as well as zeros can clearly be
seen. Your FIR filter is perfect!
It is possible to increase or decrease the precision of the Xilinx Filter in order to reach the
perfect area/performance/quality trade off required by your design specifications.
Stop the simulation and modify the data width to FIX_8_6 and the coefficient width to
FIX_10_10 from the block GUI. Update the model (Ctrl-d) and push into the MAC
engine block. You should now notice that the datapath has been automatically updated to
only eighteen bits on the output of the multiplier and twenty on the output of the
accumulator.
Restart the simulation and observe how the frequency response has been affected. The
attenuation has indeed degraded (less than 40dB) due to the fixed-wordlength effects.
requirements and would only be employed if the sample rate were very fast. An
alternative approach is to clock the FIR filter at the sample rate, creating one sample per
cycle. This scenario takes an intermediate amount of hardware and would be used for
intermediate sample rates. If the sample rate is slow, the FIR filter may be clocked at a rate
several times faster than the sample rate, perhaps by means of a DCM that multiplies the
sample-rate clock. In this way the multiplier-accumulator units of the FIR filter may be
reused several times during the calculation of each sample output, requiring the least
amount of hardware. This last method would use a symbol-rate clock domain, a high-
speed processing clock domain, and a sample-rate clock domain.
A good FPGA design practice is to have each resource in the FPGA device operating at the
highest possible rate to optimize hardware usage. In general, it is best to use a single clock
domain when possible and to use clock enables to gate slower circuitry, creating multicycle
paths. The drawback to this technique is that it increases power consumption and may
make it difficult to route the high-speed clock enable. As a result, separate domains for
high-speed processing are preferable in some instances. Also, it may not be possible to
avoid dealing with different clock domains when dealing with asynchronous data inputs
and outputs.
The To FIFO block is put in the domain in which it is to be written. The From FIFO is put
in the domain in which it is to be read. The two blocks are linked by the name of the
Shared memory name parameter. The FIFO is implemented in hardware using the Xilinx
FIFO Generator core. Using FIFO blocks is the safest and easiest-to-use of the three blocks
which cross domains and is the best for high-bandwidth, sequential data transfers.
The diagram below illustrates the concept of putting domain-crossing blocks into their
own subsystem. When a multiple-domain design is netlisted, System Generator does the
following:
• Creates an HDL file for Domain 0 (on the left), excluding the To FIFO block, and calls
the netlister to create a black-box netlist delivered as an NGC file;
• Creates an HDL file for Domain 1 (on the right), excluding the From FIFO block, and
calls the netlister to create a black-box netlist delivered as an NGC file;
• Invokes the Xilinx CORE Generator to produce a core for the FIFO block (middle);
• Creates a top-level HDL wrapper that instantiates three block components.
Step-by-Step Example
This example shows how design hierarchy can be used to partition a System Generator
design into multiple asynchronous clock islands. The example also demonstrates how
Xilinx Shared Memory blocks may be used to communicate between these islands. Lastly,
the example describes how the Multiple Subsystem Generator block can be used to netlist
the complete multi-clock design.
1. From the MATLAB window, change directory to the following:
<sysgen_tree>/examples/multiple_clocks/.
2. Open the two_async_clks model from the MATLAB command window, and save it
into a temporary directory of your choosing.
Subsystem hierarchy is used in the example to partition the design into two synchronous
clock domains, to which you refer as domains A and B, that are internally synchronous to
a single clock, but asynchronous relative to each other. The design includes two
subsystems named ss_clk_domainA and ss_clk_domainB, which include logic
associated with clock domains, A and B, respectively. The blocks inside the
ss_clk_domainA subsystem operate in clock domain A while all blocks inside the
ss_clk_domainB subsystem operate in a second clock domain, B.
The asynchronous islands in the example communicate with one another via a shared
memory interface implemented using a pair of Xilinx Shared Memory blocks. The two
Shared Memory blocks are distributed so that one block resides in domain
ss_clk_domainA and the other resides in domain ss_clk_domainB. Both blocks
specify the same shared memory object name, bram_iface. This allows the Shared
Memory blocks to access a common address space during simulation. Note that in the
diagram there is no physical connection shown between the two shared memory halves.
This is because the connection is implicitly defined by the fact that the two Shared Memory
blocks specify the same shared memory object name and therefore, share an address space.
When the two subsystems are wired together and translated into hardware, the shared
memory blocks are moved from their respective subsystems and merged into a block RAM
core. For more information on how this works, refer to the topic Multiple Subsystem
Generator.
The synchronous islands sample different input sources. Island ss_clk_domainA samples a
sinusoid input, while ss_clk_domainB samples a saw-tooth wave input. Each subsystem
writes its samples into opposite halves of the shared memory. Once an island has filled its
half of memory, it reads samples from the other island's half. You can simulate the design
to visualize of the model's behavior.
3. Press the Simulink Start button to simulate the design.
4. Open the scope to visualize the output signals.
Also shown in the output scope are the two clocks, clk_A and clk_B. At the default time
scale, it is difficult to distinguish the two. Zoom in to get a more detailed view.
Notice that clk_A and clk_B have different periods and are out of phase with one
another. Earlier, it was claimed that System Generator uses a single clock source per
design. In the scope, you clearly see two different clocks. How is this possible?
The answer is in the hierarchical construction of the design. All blocks are buried in at least
one level of hierarchy using subsystems. Because there is no System Generator block at the
top level, you can consider each subsystem as a completely separate System Generator
design (at least for the time being). In this model, you have effectively defined two clock
domains by giving the ss_clk_domainA and ss_clk_domainB subsystems different
Simulink system periods. This is allowed since you are treating these subsystems as
separate System Generator designs. The clock probes in the ss_clk_domainA and
ss_clk_domainB subsystems use the Simulink system periods in their respective
subsystems to determine their output, hence different system periods yield different
system clocks.
Now consider the clocks defined by the System Generator block in the ss_clk_domainA
and ss_clk_domainB subsystems.
5. Open the System Generator block parameter dialog boxes inside the
ss_clk_domainA and ss_clk_domainB subsystems.
The System Generator block dialog box in the ss_clk_domainA subsystem defines an
FPGA clock period of 10ns (i.e., a frequency of 100MHz). To simplify the sample period
values in the model, the 10 ns clock is normalized to a Simulink system period value of 2
sec. In the ss_clk_domainB subsystem, an FPGA clock period of 15ns (i.e., a frequency
66.7 MHz) is defined. Normalizing this clock period gives us a Simulink system period
value of 3 sec.
Because the two subsystems in this example implement multiple, synchronous, System
Generator domains, you will use the Multiple Subsystem Generator block to wire the
subsystems together into a single HDL top-level component that exposes two clock ports.
When the Multiple Subsystem Generator translates a design into hardware, it generates
each subsystem individually as an NGC netlist file. It also creates a top-level VHDL
component or Verilog module that instantiates the subsystem netlist files as black boxes,
and wires them together using shared memory cores as clock domain bridges.
You begin by using the Multiple Subsystem Generator block to netlist subsystems
ss_clk_domainA and ss_clk_domainB.
6. Open the Multiple Subsystem Generator dialog box by double clicking on the Multiple
Subsystem Generator block included in the top-level of the two_async_clks model.
7. Pick a suitable target directory inside the Multiple Subsystem Generator dialog box.
The default directory is netlist.
8. Press the Generate button. You may leave the Part, Synthesis Tool, and Hardware
Description Language fields as they are.
Once the Multiple Subsystem Generator block is finished running, it will display a
message box indicating that generation is complete. It is worthwhile to take a look at the
generated results.
9. cd into the design's target directory, netlist.
There are two NGC files in this directory: ss_clk_domaina_cw.ngc and
ss_clk_domainb_cw.ngc. These files store the netlist and constraints information
corresponding to the subsystems ss_clk_domaina and ss_clk_domainb. Note that
these NGC files include the clock wrapper layer logic associated with each subsystem. This
is necessary to ensure that any clock enable logic required by a multirate design is included
in netlist file. By using the clock wrapper layer of a design, the corresponding clock driver
components are automatically included in the netlist.
Also in this directory is a dual port memory core netlist file named
dual_port_block_memory_virtex2_6_1_ef64ec122427b7be.edn. This core
provides the hardware implementation for the Shared Memory blocks used in the original
design. The width and depth of the memory are based on values used in the Shared
Memory block configurations.
You will now take a look at the top-level HDL component that the Multiple Subsystem
Generator block produced for the design.
10. Open the two_async_clks.vhd file in a text editor.
This component defines the HDL top-level for the two_async_clks model.
entity two_async_clks is
port (
din_a: in std_logic_vector(7 downto 0);
din_b: in std_logic_vector(7 downto 0);
ss_clk_domaina_cw_ce: in std_logic := '1';
ss_clk_domaina_cw_clk: in std_logic;
ss_clk_domainb_cw_ce: in std_logic := '1';
ss_clk_domainb_cw_clk: in std_logic;
dout_a: out std_logic_vector(7 downto 0);
dout_b: out std_logic_vector(7 downto 0)
);
end two_async_clks;
There are several interesting things to notice about the port interface. First, the component
exposes two clock ports (shown in bold text). The two clock ports are named after the
subsystems from which they are derived (e.g., ss_clk_domaina), and are wired to their
respective subsystem NGC netlist files. Also note that the top-level ports of each
subsystem (e.g., din_a and dout_a) appear as top-level ports in the port interface.
The Multiple Subsystem Generator block does not generate circuitry (e.g., a DCM) to
generate multiple clock sources. You may modify the top-level HDL component to include
the circuitry, or instantiate the top-level HDL as a component in a separate wrapper that
includes the clocking circuitry.
use unisim.vcomponents.all;
entity top_wrapper is
port (
clk : in std_logic;
din_a : in std_logic_vector(7 downto 0);
din_b : in std_logic_vector(7 downto 0);
dout_a : out std_logic_vector(7 downto 0);
dout_b : out std_logic_vector(7 downto 0)
);
end top_wrapper;
----------------------------------------------------------------------
---------
-- The top level instantiates the SysGen design, a DCM, and two BUFGs.
-- The DCM generates two clocks of different frequencies.
-- These two clocks are used to drive the two different clock domains
-- in the SysGen block.
----------------------------------------------------------------------
---------
begin
dcm0: dcm
-- synopsys translate_off
generic map (dll_frequency_mode => frequency_mode,
clkdv_divide => clkdv_divide_generic,
clkfx_multiply => clkfx_multiply_generic,
clkfx_divide => clkfx_divide_generic)
-- synopsys translate_on
port map (clkin => clk,
clkfb => clk0buf,
dssen => '0',
psincdec => '0',
psen => '0',
psclk => '0',
rst => dcm_rst,
clk0 => clk0unbuf,
clk2x => clk2xunbuf,
--------------------------------------------------------------------
-- This is the DCM reset. It is a four-cycle shift register used to
-- hold the DCM in reset for a few cycles after programming.
--------------------------------------------------------------------
flop1: FDS port map (D => '0', C => clk, Q => ff1, S => '0');
flop2: FD port map (D => ff1, C => clk, Q => ff2);
flop3: FD port map (D => ff2, C => clk, Q => ff3);
flop4: FD port map (D => ff3, C => clk, Q => ff4);
dcm_rst <= ff2 or ff3 or ff4;
------------------------------------------------------------
-- SysGen Component Port Mapping
-- One clock input is being connected to clk0 of the DCM,
-- and the other clock is being connected to clkfx.
------------------------------------------------------------
two_async_clks: two_async_clks
port map (
din_a => din_a,
din_b => din_b,
ss_clk_domaina_cw_ce => '1',
ss_clk_domaina_cw_clk => clk0buf,
ss_clk_domainb_cw_ce => '1',
ss_clk_domainb_cw_clk => clkfxbuf,
dout_b => dout_b);
end structural;
4. Simulate the model by clicking on the Start simulation Icon At this point, without
modifying the model, you should be able to see the following plot.
♦ The first plot represents the most significant bit of the 8-bit counter. The MSB
becomes 1 when the counter output is within the range of 128 through 255.
♦ The second plot represents the full output of the counter.
♦ The third plot shows the sine. If you zoom in at the beginning of time, you will
notice a 2 clock-cycle delay due to the pipelining implemented in the SineCosine
table.
♦ The fourth output represents the cosine. This output has the same 2 clock-cycle
delay as the Sine Wave.
5. Integrate ChipScope in the Simulink model. The ChipScope block can be found in the
Simulink Library Browser in the Xilinx Blockset, under the Tools library. While
holding down the left mouse button, select the ChipScope block and drag it into the
open chip Simulink model.
6. Double click on the ChipScope block in order to set the following parameters:
♦ Number of trigger ports: Multiple trigger ports allow a larger range of events to
be detected and can reduce the number of values that must be stored. Up to 16
trigger ports can be selected. In this example, only one is used.
♦ Display settings for trigger port: For each trigger port, the number of match units
and the match type need to be set. The pulldown menu displays options for a
particular trigger port. For N ports, the display options for trigger port 0 to N-1
can be shown. In this example, there is one Trigger port named Trig0. This option
should therefore be set to 0.
♦ Number of match units: Using multiple match units per trigger port increases the
flexibility of event detection. One to four match units can be used in conjunction
to test for a trigger event. In this example, this option should be set to 1 since you
are only checking for one condition (i.e., the 8-bit counter value). You will set the
trigger value at run-time in the ChipScope Pro Analyzer.
♦ Match type: This option can be set to one of the following six types:
1. Basic: performs = or <> comparisons
2. Basic With Edges: in addition to the basic operations high/low, low/high
transitions can also be detected
3. Extended: performs =, <>,>,<, <=, >= comparisons
4. Extended With Edges: in addition to the extended operations, high/low,
low/high transitions can also be detected.
5. Range: performs =, <>, >, >=, <, <=, in range, not in range comparisons
6. Range With Edges: in addition to the range operations, high/low, low/high
transitions can also be detected.
In this example, set the Match Type to Basic with Edges
♦ Number of data ports: Up to 256 bits can be captured per sample. This means that
the sum over all ports of the bits used per port must be less than or equal to 256.
System Generator propagates the data width automatically; therefore, only the
number of data ports needs to be specified. In this example, you want to view the
sine and cosine, hence you enter 2.
♦ Depth of capture buffer: The depth of the capture buffer is a power of 2, up to
16384 samples for Virtex-II, Virtex-II Pro, and Spartan-3 device families, and 4096
for Virtex, Virtex-E, Spartan-II and Spartan-IIE device families. In this example,
set the depth to 512.
After parameterization the ChipScope GUI should look like the following:
Note that the names of the ports on the ChipScope block are specified by names given
to the signals connected to the block, e.g. Sin and Cos.
8. Location Constraints
Now that the design is fully implemented and simulates correctly, the next step is to
prepare it for connection to our hardware target. Although it can work on any
hardware platform, the process is described for the XtremeDSP Development kit.
Two pins need to be locked down in this design: The LED and the clock pin.
♦ LED Pin: Double click on the Gateway Out1 block, select Specify IOB Location
constraint and type in {'Y11'} (note the need for single quotes).
♦ Clock Pin: Double click on the System Generator block, set the clock period to
25ns and the clock pin location to Y13
If you are using a different board, pin location should be modified appropriately.
9. System Generator GUI settings
The last two parameters that should be updated before generating a bitstream are the
target device and the compilation target.
♦ Double click on the System Generator token and select the part Virtex2 xc2v2000-
4fg676 or xc2v3000-4fg676 depending on which part you have on your board.
♦ Set the Compilation target to Bitstream.
♦ Double check that your System Generator parameters match the ones shown on
the following screen shot:
Real-Time Debug
The next step is to run the design on the XtremeDSP development kit and view the probed
outputs with the ChipScope Pro Analyzer.
1. Connect Parallel Cable IV to the General JTAG (J13) header of the XtremeDSP
development kit. The VCC pin is the pin closest to the top edge of the board, furthest
away from the PCI connector. It is also necessary to connect it to the USB port for
power up.
If you have any issues with this procedure, please refer to the XtremeDSP
Development Kit User's Guide.
3. Open ChipScope Pro Analyzer (Refer to the topic Software Prerequisites for details on
the version to use)
♦ Open JTAG Chain by clicking on the following Icon , or by clicking on JTAG
Chain > Xilinx Parallel Cable and selecting Xilinx Parallel IV Cable.
Note the index for the Virtex-II devices available on the XtremeDSP kit: xc2v2000 or
xc2v3000 is index 3, and xc2v80 is index 4.
4. Configure the FPGAs
♦ Under the New Project Window, right click on Device 3 and select Configure >
Device 3. At this point, you need to look for the bitstream which was generated in
step 10 of the previous topic. Select New File and scroll to your project directory:
<sysgen_tree>/examples/chipscope/netlist/chip_cw.bit. After
configuration, the status window at the bottom of the ChipScope Analyzer should
reflect that one ChipScope core was found in the JTAG chain.
♦ Similarly, select Device 4 and Configure it with the osc_clock_2v80.bit file
provided in the ChipScope project directory. This second bitstream is used to
program the clock driver FPGA on the board.
5. Import ChipScope Project File
System generator creates a project file for ChipScope in order to group data signals into
buses. A bus is created for each data port so that it can be viewed in the same manner
(sign and precision) in which it was viewed in the Simulink environment.
Load this project file by going under File > Import > Select New File, and select
<sysgen_tree>/examples/chipscope/netlist/temp/chip_chipscope.cd
c.
6. Plot the Sine Waves
In the New Project window, under Device 3 > Unit 0 ILA, double click on Bus Plot.
A Bus Plot window appears. Select Cos and Sin in the Bus Selection section, and then
arm the trigger by hitting the button. Since you have not yet set any trigger
conditions, values are captured immediately. Both the sine and cosine appear as
shown below. You can change the display option to represent the waveforms with
points, lines, or both.
7. Setup Trigger
In the Trigger Setup window, change the current XXXX-XXXX value with all 0000-
0000. Once the counter hits 0, ChipScope starts capturing values. Earlier, you setup the
buffer to 512, so 512 data points can be visualized in ChipScope.
Re-capture the data by hitting then button.
Again, you see a 2 clock delay at the beginning of time on the sine wave due to the 2
clock latency through the SineCos Look Up Table. Modify the trigger value to 0000-
0010 (decimal 2) and re-capture the data. Now the sine and cosine start respectively at
0 and 1.
2. Start MATLAB and change the current working directory to the location where you
saved sinecos.prn.
♦ Type xlLoadChipScopeData('sinecos.prn'); This loads the data from the
.prn file into the MATLAB workspace. In the workspace there are two new arrays
named Sin and Cos.
3. You can plot the values using the MATLAB plot function.
♦ Type: plot(1:512, Sin, 1:512, Cos) and the following plot is generated:
Chapter 2
Hardware/Software Co-Design
The Chapter covers topics regarding developing software and hardware in System
Generator.
PicoBlaze Block
The PicoBlaze block provides the smallest degree of flexibility but is the least complex to
use. The Xilinx PicoBlaze Microcontroller block implements an embedded 8-bit
microcontroller using the PicoBlaze macro, and exposes a fixed interface to System
Generator. Ordinarily, a single block ROM containing 1024 or fewer 8 bit words serves as
the program store. You can program the PicoBlaze using the PicoBlaze Assembler
language. This flow is documented in the topic Designing PicoBlaze Microcontroller
Applications.
The EDK Processor block provides a solution to both these problems through automation.
The EDK Processor block encourages the interface between the processor and the custom
logic to be specified via shared-memories. Shared-memories are used to provide storage
locations that can be referenced by name. This allows a memory map and the associated
software drivers to be generated.
Please refer to the EDK Processor block documentation for information on the use of the
block. The topics that follow describe the memory map and software features of the drivers
that are generated.
A System Generator model is shown on the bottom-right of the figure above. The System
Generator model corresponds to custom logic that will be integrated with the MicroBlaze
processor. In the construction of the model, shared-memories are used in locations where
software access is required. For instance, the status of the hardware might be kept in a
register. To make that status information visible in the processor, the register is replaced by
a named shared-register. Naming the shared-register "status" gives the name of the
memory context that will be useful later on during software development.
The block GUI of the EDK Processor block allows these shared-memories to be added to
the memory map of the processor (bottom-left of the figure). The block diagram at the top
of the figure above shows the flow of data. When a shared memory is added to the memory
map of the processor, the EDK Processor block creates the corresponding matching shared
memory. This shared memory is attached to the memory map that is generated for that
EDK Processor block. Next, a bus adaptor is used to connect that memory map to the
MicroBlaze processor.
When hardware is generated, each shared memory pair is implemented with a single
physical memory. The implementation for each class of shared memory is documented in
the topic Shared Memory Support, found under the topic Using Hardware Co-Simulation.
Hardware Generation
The EDK Processor block supports two modes of operation: EDK pcore generation and
HDL netlisting. The different modes of operation are illustrated below and can be chosen
from a list-box in the EDK Processor block's GUI.
processor described in the EDK project will be imported into System Generator as a black
box. The supplied EDK project is also augmented with the bus interfaces necessary to
connect the System Generator memory map to the processor. During netlisting, the
MicroBlaze and the generated memory-map hardware are both netlisted into hardware.
This mode can be used for software-based simulation of the processor, or hardware co-
simulation.
Hardware Co-Simulation
Currently the EDK Processor block provides hardware-based simulation through
hardware co-simulation. Creation of a hardware co-simulation block follows the standard
co-simulation flow described in the topic Using Hardware Co-Simulation.
You may use the EDK's XPS tool to write and compile your software. However before
simulation can begin, the Compile and update bitstream button in the co-simulation
block's Software tab must be used to put the compiled C-code into the bitstream.
When used in conjunction with a hardware-board supported by network-based hardware
co-simulation, it is possible to free up the JTAG port on the FPGA and use that for software
debug with XMD.
The figure above shows a screen capture of the EDK XPS tool. Locate the System Generator
peripheral from the System Assembly view and right click for a pop-up menu. Select
View API Documentation to bring up the documentation. If this option is not available,
the drivers need to be compiled. This can be done in XPS by selecting the menu option
Software > Generate Libraries and BSPs.
Please refer to the generated documentation for header file information, driver calls,
memory maps and also example code.
The generated software drivers contain four basic functions for accessing shared-
memories. In the table below, <inst> refers to the instance name given to the peripheral.
int <inst>_Read (unsigned int memName,
unsigned int addr,
unsigned int* val);
int <inst>_ArrayRead (unsigned int memName,
unsigned int startAddr,
unsigned int transferLength,
unsigned int** valBuf);
int <inst>_Write (unsigned int memName,
unsigned int addr,
unsigned int val);
int <inst>_ArrayWrite (unsigned int memName,
unsigned int startAddr,
unsigned int transferLength,
const unsigned int* valBuf);
When Dual Clock is enabled and a design is netlisted for Hardware Co-simulation, a
slightly different clock wiring topology is used. This is shown in the figure below. The
clock source from the board is bifurcated with one branch going into the Hardware Co-
simulation module before being connected to the clk clock (depicted in the figure above).
The other branch is routed through a clock buffer and connected to the xps_clk clock
signal.
This topology allows for the custom logic designed in System Generator to be single-
stepped, while allowing the MicroBlaze to continue in free-running mode. This allows for
clock-sensitive peripherals (such as the RS232 UARTS) to work when the Hardware Co-
Simulation token is set to single-step.
In Hardware Co-simulation, the processor subsystem is driven by the board clock directly.
This means that the processor subsystem must be able to meet the requirements set by this
clock. In hardware co-simulation, it is possible for users to select different ratios of clock
frequencies based of the input board frequency. Note that this hardware co-simulation
clock is generated in the hardware co-simulation module and is not available to the
processor subsystem.
For exmaple, if the input board frequency is 125MHz, and the hardware co-simulation
frequency is set to 33 Mhz, only the custom logic portion of the design will be constrained
to 33 MHz, the MicroBlaze must still run at 125 MHz. If the MicroBlaze cannot meet timing
at this speed, the user needs to instance a clock generator pheripheral in their XPS project
and slow down the clock in that way.
EDK Support
EDK Support
There are two ways to launch the EDK Import Wizard in the EDK Processor block: (1) press
the Import… button, or (2) select HDL netlisting when the EDK project field is empty.
Note: When you import the EDK Project into System Generator, there are modifications made to the
EDK project. These modifications are described in the following topic.
Note: The import process will alter your EDK project to work inside System Generator. If you wish
to retain an unadulterated version, please make a copy before importing. System Generator
automatically backs up the hardware platform specification (i.e., the MHS file) and the software
platform specification (the MSS file) of the EDK project to files with the "bak" suffix.
When an EDK project is imported into System Generator, the EDK project is augmented
with a pair of FSL, or a PLB46 interface depending on the options made on the EDK
Processor block. A pcore (xlsg_iface for FSL and xlsg_plbiface for PLB) is also added to
provide software drivers for the interface.The MHS and MSS files in the EDK project will
be altered. Following that, the HDL files that describe the processor will be generated and
linked to your System Generator project.
Limitations
Currently the Wizard can only import single processor projects. Only the MicroBlaze
processor is supported. Peripherals added to the processor cannot conflict with the
resources used by other System Generator services. For instance, if network-based
hardware co-simulation is used, the EDK project cannot make use of the peripherals using
the Ethernet MAC.
EDK Support
The top-right box in the figure above shows a snippet from an EDK project in XPS. The
external port list has among other ports, a user-defined port called myExternalPort.
After importing the EDK project, open up the processor's block GUI in System Generator.
Select the Advanced tab to reveal the processor port interface table.
The port list shows all the top-level ports available on the processor. This port list has been
filtered to remove clock ports and also signals used by System Generator to implement the
memory-map interface. In this example, the RS232 ports, sys_rst_pin and myexternalport are
shown to be ports that can be exposed to the top-level of the System Generator block.
Selecting the expose check box will cause the port to be exposed on the EDK Processor
block. As shown in the figure above, the display name of the port can be changed, should
the original name be too long.
This mechanism allows ports from the processor to be directly exposed to the System
Generator design without going through the memory map generated by System
Generator. You may choose to do this to expose the reset ports on the processor, or to
expose interrupt ports directly to the System Generator diagram.
Exporting a pcore
System Generator designs containing an EDK Processor block can be exported as an EDK
pcore using the EDK Export Tool compilation target on the System Generator block.
Before exporting to the EDK as a pcore, the EDK Processor block must be configured for
"EDK pcore generation". This can be done by opening the EDK Processor block GUI and
selecting the relevant drop down option in the "Configure processor for" parameter.
Please refer to the topic EDK Export Tool for more information.
PicoBlaze Overview
The following example uses PicoBlaze 3 (hereto referred to simply as PicoBlaze), which is
optimized for low resource requirements. A memory block is used as a program store for
up to 1024 instructions.
Architecture Highlights
• Predictable performance, two clock cycles per instruction
• 43 - 66 MIPS (dependent upon device type and speed grade)
• Fast interrupt response
• 96 slices, 0.5 to 1 block RAM
• 16 8-bit general-purpose registers
• 64-byte internal RAM
• Internal 31-location CALL/RETURN stack
• 256 input and 256 output ports
Program Counter
CALL/RETURN
1Kx18
31x10
PORT_ID
Stack
64-Byte
(PC)
Flags
Instruction Constants Z Zero
Decoder
C Carry
INTERRUPT
16 Byte-Wide Registers
IE Enable Operand 1 ALU
s0 s1 s2 s3
s4 s5 s6 s7
IN_PORT s8 s9 sA sB
sC sD sE sF
Operand 2
ALU
The Arithmetic Logic Unit (ALU) provides operations such as add, sub, load, and, or, xor,
shift, rotate, compare, and test. The first operand to each instruction is a register to which
the result is stored. Operations requiring a second operand can specify either a second
register or an 8-bit constant value.
Input/Output
There are 256 input ports and 256 output ports. The port being accessed is indicated by an
8-bit address value provided on port_id. The port address can be specified in the
program as an absolute value or indirectly specified as the contents of a register. During an
input operation, the value provided to in_port is transferred into any of the 16 registers.
During an output operation, a value is transferred from a register to out_port.
Interrupt
The processor provides a single interrupt input port, brk. When interrupts are enabled,
setting brk to 1 causes the program counter to be set to memory location 0x3FF, where a
jump vector to the interrupt service routine is stored. At this time, a pulse is generated on
the ack port (two clock cycles after brk is asserted), the control flags are preserved and
further interrupts are disabled. The return instruction ensures that the end of an interrupt
routine restores the status of the control flags and specifies if future interrupts should be
enabled.
For extensive details regarding the feature and instruction set, please refer online to the
topic PicoBlaze User Resources.
b. Double-click the block and set Version to PicoBlaze 3. Turn off the option to
Display internal state. Connect the ports to the existing lines in the model.
c. Find the PicoBlaze Instruction Display block in the Index or Tools Library and add it
to the model where indicated. Make sure it is connected properly, as shown in the
figure below:
d. Double-click the PicoBlaze Instruction Display block and set the Version to
PicoBlaze 3. Check the Disable Display option. Disabling the display option
allows the simulation to run without the overhead of updating the block display.
e. Find the ROM block in the Memory Library and add it to the model where
indicated. Flip the block by Right clicking on the block and selecting Format > Flip
Block. Attach the ports to the existing lines.
f. Change the Single-Step Simulation block to be in continuous mode by double
clicking on the block.
4. Configure the program store. Double click the ROM to do the following.
With the Basic tab selected:
a. The ROM block is used to store the PicoBlaze instructions. The depth of the ROM
must be set to 1024. This is because the program uses interrupts and setting brk to
1 causes the program counter to be set to 0x3FF.
b. As detailed in step 5, the code is assembled and produces an initialization file for
the memory named fill_pico_code_program_store.m. Hence the ROM
Initial Value Vector should be set to fill_pico_code_program_store.
c. To increase the performance for synchronous designs, the Latency should be set to
1.
Notice the sine wave frequency increasing proportionally to the phase increment.
8. Utilize Debug Tools
If the program is not working properly, there are several tools that can be utilized to ease
debugging. Deselecting the Disable Display checkbox in the PicoBlaze Instruction
Display block causes the block to be activated, displaying the updated program counter
and instruction each clock cycle. In conjunction with enabling the display, the registers and
control flag values can be viewed by selecting the Display Internal State in the PicoBlaze
Microcontroller block. Change the Single-Step Simulation block to single-step mode by
double clicking on the block. Step through the simulation to debug.
2. Prepare to export the pcore. Drag an EDK processor block into the model. Configure
the processor block by double clicking on the block to bring up the block's dialog box,
as shown below:
Add all available shared memories in the model to the EDK Processor by
verifying/selecting <all> , then click the Add button. As shown above, ensure that the
EDK Processor block has been configured for EDK pcore generation in the Configure
processor for drop-down menu. Dismiss the GUI by clicking the OK button. The EDK
Processor will then create a memory map for the shared memories.
3. Expore the pcore. Double click on the System Generator token to open up the System
Generator dialog box. You will use the EDK Export Tool to create the pcore. Options in
the EDK Export Tool are more fully detailed in the topic System Generator
Compilation Types.:
As shown above, set the Compilation type to be Export as a pcore to EDK. Click on the
Settings... button to open up options for the compilation target. Accept the default settings
so that the pcore is generated and exported into the model's target directory.
Click on the Generate button to initiate the pcore export process.
4. Integrate the Exported pcore in the XPS
You will now create an XPS project and integrate the pcore into the XPS project.
Information on how to create an XPS project can be found in the topic Using XPS. Follow
the directions there to create an XPS project.
Once the XPS project is created, copy the pcore that is created by System Generator into its
local pcore repository. Since System Generator is instructed to place the pcore inside the
target directory in the previous step, you should find a directory named pcore inside the
target directory. Copy the contents of the directory into the corresponding pcore directory
inside your XPS project. If your XPS project does not contain a pcore directory, create one
before copying.
In the XPS menu, select Project > Rescan User Repositories. The pcore exported by System
Generator, named rgb2gray_plbw, will appear on the list of EDK Peripherals after the
rescan.
Follow the directions in the topic Using XPS for information on how to connect up a pcore
to the MicroBlaze processor in the EDK tool.
After connecting up the pcore, compile the netlist by selecting Hardware > Generate
Netlist.
Write Software
Create a new software application in your XPS project. Again, information on how to do
this can be found in the topic Using XPS. Add the following code to your application and
compile the software.
#include "xparameters.h"
#include "stdio.h"
#include "xutil.h"
xc_iface_t *iface;
xc_from_reg_t *fromreg_gray;
xc_to_reg_t *toreg_red, *toreg_green, *toreg_blue;
There can be multiple instances of a System Generator pcore in an XPS project. Each of the
instances is associated with a device ID, which can be found in “xparameter.h”. Assume
that the instance of interest has a device ID of 0 based on the following information in
“xparameter.h”.
Use the device ID of a System Generator pcore instance to select the corresponding item in
RGB2GRAY_PLBW_ConfigTable, which is then provided to xc_create to retrieve the
settings of the specific Systen Generator pcore instance.
The topic Integrating a Processor with Custom Logic contains more information on how
the hardware is wired up and other software issues.
Running the code will produce the following print out on a RS232 terminal.
You will now configure the EDK Processor block to import the XPS project. The import
process will make changes to the XPS project. Thus, ensure that the XPS project is not
currently opened by Xilinx Platform Studio before importing.
Double click on the processor block to bring up the block dialog box. In the Configure
processor for drop-down menu, select HDL netlisting. The Import… button is enabled as
a result of the selection.
Note that the Import… button is disabled when the processor is configured for EDK pcore
generation. In EDK pcore generation mode, it is expected that you will create a pcore in
System Generator and export it to be used in another XPS project. In this case, the
processor is not instanced inside the EDK Processor block. In HDL netlisting mode, it is
expected that you import an XPS project into the System Generator model and netlist it
with other System Generator blocks.
If no XPS project is ever imported, configuring the processor for HDL netlisting will
automatically trigger the launching of the XPS Import Wizard. The XPS Import Wizard can
be launched manually by pressing the Import… button.
In the pop-up file selection dialog, browse to the XPS project created in earlier steps. The
import process starts once a XPS project file (xmp file) is selected. The import process
copies necessary files into the XPS project and changes the project accordingly to allow the
MicroBlaze processor to communicate with the System Generator model.
Note that if there is any software applications contained by the imported XPS project, they
are not compiled during import.
The above figure shows a portion of the System Assembly View of the XPS project in Xilinx
Platform Studio. A sg_plbiface peripheral is automatically added to an XPS project after it is
successfully imported into System Generator. The sg_plbiface peripheral connects the PLB
bus attached to the imported MicroBlaze processor to the System Generator model
through a memory-mapped interface, and to capture information on how to generate the
corresponding device software drivers. Right click on sg_plbiface in the System Assembly
View to see its API documentation.
Follow the instructions in the API documentation to include the following header file and
initialize the software driver in MyProject.c.
#include "sg_plbiface.h"
xc_iface_t *iface;
So in order to write a value to the a shared register, you need to first obtain its settings
through xc_get_shmem and thus:
xc_to_reg_t *toreg_a;
xc_get_shmem(iface, "a", (void **) &toreg_a);
Note: Calling xc_get_shmem is expensive. You should cache the returned toreg_a for later use
and avoid calling xc_get_shmem multiple times in a program.
You can then use the following single-word write access function to write to the a shared
register:
// -- Set the a port register to 2
xc_write(iface, toreg_a->din, 2);
Return to the testbench model. Double click on the Processor Subsystem hwcosim block to
bring up the dialog box shown above. To compile the software contained in the XPS project
listed in the Software tab and load it into the hardware co-simulation bitstream, click the
button labeled Compile and update bitstream.
Since Point-to-point Ethernet co-simulation is chosen, you need to configure the Ethernet
interface and also the Configuration interface of the Processor Subsystem hwcosim block.
Select a valid Host interface for your Ethernet communications, and set the configure
interface to Point-to-point Ethernet. Refer to the topic Using Hardware Co-Simulation for
more usage information of the hardware co-simulation block.
Using XPS
This topic provides a quick tutorial on several aspects of the Xilinx Embedded
Development Kit (EDK). Please refer to the EDK documentation for more in depth
explanations and tutorials.
3. Next, tell Base System Builder that you wish to create a new design by selecting the I
would like to create a new design radio button. Click Next.
4. Base System Builder – Select Board. Select the kind of board you want to make use of,
then click Next.
5. Base System Builder – Select a processor. Next, you are asked to select a processor.
Select MicroBlaze, then click Next.
6. Base System Builder – Configure MicroBlaze. You will now configure the MicroBlaze.
The Configure MicroBlase dialog box is shown below.:
7. Base System Builder – Configure IO Interfaces. You only want the RS232 interface. Set
the parameters of the RS232_Uart as shown below, then un-select the other IO
interfaces
8. Base System Builder – Configure Additional IO Interfaces. The next dialog contains
additional IO interfaces supported by this board. Depending on the board, there may
be multiple dialog pages of "Additional IO Interfaces". At this time, you have no need
for any additional IO interfaces, so un-select them all, then click Next
9. Base System Builder – Add Internal Peripherals. You have no internal peripherals to
add. Click Next
10. Base System Builder – Software Setup. In this dialog box, you can select the input and
output of STDIN and STDOUT. By default they should be routed to the RS232_Uart.
You may also select to have example code produced in the project for you. Click Next.
11. Base System Builder – System Created. This dialog shows a summary of the options
selected. Click on Generate to cause the EDK project to be created
12. Base System Builder – Finished. This last dialog box shows the files generated. Click
Finish to end the Base System Builder and allow you to continue the EDK flow using
XPS. At this point you have created a basic EDK system.
3. The first item on this page is Add Software Application Project … Double click on this
to bring up the Add Software Application Project dialog box. Type in a project name,
then click OK.
4. By default, the project is created and not set to be initialized into BRAMS. Make sure to
initialized the project into BRAMS; otherwise, the software code will not be compiled
and added to the bitstream. Also, if you have more than one application, ensure that all
other applications have Marked to Initialize BRAM unchecked.
5. Next, create Source or header files. Double click on the Sources branch of a project tree
to cause a File Open Dialog to pop-up. The dialog is rooted at the base location of your
EDK project. It is good to create a directory named after your project and keep your
source and header files there; in this case, MyProject. Create the directory in the same
directory as your EDK.xmp file
Available FSL-based pcores are listed on the right hand window. Select the relevant pcore,
then click on the Add button. The Configure Coprocessor tool takes care of connecting the
clock and reset signals for the FSL bus, however, any user signals must be wired up by you.
Chapter 3
When a compilation target is selected, the fields on the System Generator block dialog box
are automatically configured with settings appropriate for the selected compilation target.
System Generator remembers the dialog box settings for each compilation target. These
settings are saved when a new target is selected, and restored when the target is recalled.
The code generator produces a FPGA configuration bitstream for your design that is
suitable for hardware co-simulation. System Generator not only generates the HDL and
netlist files for your model during the compilation process, but it also runs the downstream
tools necessary to produce an FPGA configuration file.
Note: A status dialog box (shown below) will appear after you press the Generate button. During
compilation, the status box provides a Cancel and Show Details button. Pressing the Cancel button
will stop compilation. Pressing the Show Details button exposes details about each phase of
compilation as it is run. It is possible to hide the compilation details by pressing the Hide Details
button on the status dialog box.
The configuration bitstream contains the hardware associated with your model, and also
contains additional interfacing logic that allows System Generator to communicate with
your design using a physical interface between the platform and the PC. This logic
includes a memory map interface over which System Generator can read and write values
to the input and output ports on your design. It also includes any platform-specific
circuitry (e.g., DCMs, external component wiring) that is required for the target FPGA
platform to function correctly.
out of the library and use it in your System Generator design as you would other Simulink
and System Generator blocks.
The hardware co-simulation block assumes the external interface of the model or
subsystem from which it is derived. The port names on the hardware co-simulation block
match the ports names on the original subsystem. The port types and rates also match the
original design.
Hardware co-simulation blocks are used in a Simulink design the same way other blocks
are used. During simulation, a hardware co-simulation block interacts with the underlying
FPGA platform, automating tasks such as device configuration, data transfers, and
clocking. A hardware co-simulation block consumes and produces the same types of
signals that other System Generator blocks use. When a value is written to one of the
block's input ports, the block sends the corresponding data to the appropriate location in
hardware. Similarly, the block retrieves data from hardware when there is an event on an
output port.
Hardware co-simulation blocks may be driven by Xilinx fixed-point signal types, Simulink
fixed-point signal types, or Simulink doubles. Output ports assume a signal type that is
appropriate for the block they drive. If an output port connects to a System Generator
block, the output port produces a Xilinx fixed-point signal. Alternatively, the port
produces a Simulink data type when the port drives a Simulink block directly.
Note: When Simulink data types are used as the block signal type, quantization of the input data is
handled by rounding, and overflow is handled by saturation.
Like other System Generator blocks, hardware co-simulation blocks provide parameter
dialog boxes that allow them to be configured with different settings. The parameters that
a hardware co-simulation block provides depend on the FPGA platform the block is
implemented for (i.e., different FPGA platforms provide their own customized hardware
co-simulation blocks).
As shown below, you set the target clock frequency at compilation time, by clicking the
Settings button on the System Generator block dialog box, then select the frequency in the
pulldown menu.
1. Click
2. Select
Clocking Modes
There are several ways in which a System Generator hardware co-simulation block can be
synchronized with its associated FPGA hardware. In single-step mode, the FPGA is in
effect clocked from Simulink, whereas in free-running clock mode, the FPGA runs off an
internal clock, and is sampled asynchronously when Simulink wakes up the hardware co-
simulation block.
Single-Step Clock
In single-step clock mode, the hardware is kept in lock step with the software simulation.
This is achieved by providing a single clock pulse (or some number of clock pulses if the
FPGA is over-clocked with respect to the input/output rates) to the hardware for each
simulation cycle. In this mode, the hardware co-simulation block is bit-true and cycle-true
to the original model.
Because the hardware co-simulation block is in effect producing the clock signal for the
FPGA hardware only when Simulink awakes it, the overhead associated with the rest of
the Simulink model's simulation, and the communication overhead (e.g. bus latency)
between Simulink and the FPGA platform can significantly limit the performance
achieved by the hardware. As a general rule of thumb, as long as the amount of
computation inside the FPGA is significant with respect to the communication overhead
(e.g. the amount of logic is large, or the hardware is significantly over-clocked), the
hardware will provide significant simulation speed-up.
Free-Running Clock
In free-running clock mode, the hardware runs asynchronously relative to the software
simulation. Unlike the single-step clock mode, where Simulink effectively generates the
FPGA clock, in free-running mode, the hardware clock runs continuously inside the FPGA
itself.
In this mode, simulation is not bit and cycle true to the original model, because Simulink is
only sampling the internal state of the hardware at the times when Simulink awakes the
hardware co-simulation block. The FPGA port I/O is no longer synchronized with events
in Simulink. When an event occurs on a Simulink port, the value is either read from or
written to the corresponding port in hardware at that time. However, since an unknown
number of clock cycles have elapsed in hardware between port events, the current state of
the hardware cannot be reconciled to the original System Generator model. For many
streaming applications, this is in fact highly desirable, as it allows the FPGA to work at full
speed, synchronizing only periodically to Simulink.
In free-running mode, you must build explicit synchronization mechanisms into the
System Generator model. A simple example is a status register, exposed as an output port
on the hardware co-simulation block, which is set in hardware when a condition is met.
The rest of the System Generator model can poll the status register to determine the state of
the hardware.
Note: The clocking options available to a hardware co-simulation block depend on the FPGA
platform being used (i.e., some platforms may not support a free-running clock source, in which case
it is not available as a dialog box parameter).
Generator compiles the design into hardware, it connects the signals that are associated
with the Gateways to the appropriate external devices they signify in hardware.
Interface Features
The interface supports 10/100/1000 Mbps half/full duplex modes. Jumbo Frame is also
supported on a Gigabit Ethernet, provided it is enabled by the underlying connection. For
FPGA device configuration, the interface supports either JTAG-based configuration over a
Xilinx Parallel Cable IV or a Xilinx Platform USB cable, or Ethernet-based configuration
over the same Point-to-point Ethernet connection for co-simulation.
Note: This co-simulation interface utilizes an evaluation version of the Ethernet MAC core. Because
this is an evaluation version of the core, it will become dysfunctional after continuous, prolonged
operation (e.g., around 7 hours) in the target FPGA. Operation of the core will restart with a new
simulation. For more information about obtaining the full version of the core, please visit the product
page at http://www.xilinx.com/xlnx/xebiz/designResources/ip_product_details.jsp?key=TEMAC.
Select a Clock
Select an Interface
♦ From the Host interface panel, use the pulldown list to select the appropriate
network interface for co-simulation.
Note: The pull down list only shows those Ethernet-compatible network interfaces installed
on the host, which support 10/100/1000 Mbps, and are currently enabled and attached to an
active Ethernet segment. If the target interface is not listed as expected, examine the
connection and click the Refresh button to update the list.
♦ The information box beneath the pull-down list provides the details about the
selected interface. Examine the information to ensure the appropriate interface is
chosen, and adjust the network settings in the operating system when necessary.
4. Depending on which configuration method is chosen, the MAC address in the FPGA
interface panel may need to be changed.
a. For Point-to-point Ethernet-based configuration:
Observe the MAC address displayed on the LCD screen of the target board when the
configuration boot-loader is running. Change the FPGA MAC address in the co-
simulation block if the default value does not match the target board. Refer to Optional
Step to set the Ethernet MAC Address and the IPv4 Address for details about
assigning the MAC address on a ML402 board.
Note: The MAC address must be specified using six pairs of two-digit hexadecimal number
separated by colons (for example, 00:0a:35:11:22:33).
2. The final configuration file is then transferred to the target board using the selected
download cable, and used to configure the FPGA device. The progress of
configuration is shown in the dialog box when the configuration is performed over a
Point-to-point Ethernet connection.
Known Issues
• If you encounter problems transmitting data over a point-to-point Ethernet
connection or experience instability issues, please disable the Hyper-Threading
option in the BIOS on an Intel platform.
• IP fragmentation is not supported by the network-based Ethernet configuration.
Please ensure the connection established between the host and the target FPGA
platform can handle a maximum transmission unit (MTU) size of at least 1300 bytes
without fragmentation.
Setup Procedures
1. Network-based Ethernet co-simulation performs device configuration over the
network configuration. Before using network configuration, you must ensure the IP
address, MAC address, and configuration server are properly setup on the System
ACE CompactFlash. Refer to the topic Optional Step to set the Ethernet MAC Address
and the IPv4 Address for information on how to do this.
2. The target FPGA listens on the UDP port 9999. Please ensure the underlying network
does not block the associated traffic.
Known Issues
IP fragmentation is not supported by the network-based Ethernet co-simulation interface.
Please ensure the connection established between the host and the target FPGA platform
can handle a maximum transmission unit (MTU) size of at least 1300 bytes without
fragmentation.
There are two ways in which shared memories are compiled for hardware co-simulation.
The type of compilation depends on whether the shared memory name is unique in the
design, or if the shared memory has a partner who shares the same name. The following
topics describe the two types of compilation behavior.
The shared memory hardware and interface logic are completely encapsulated by the
hardware co-simulation block that is generated for the design. By co-simulating a
hardware co-simulation block that contains a shared memory, it is possible for your design
logic and host PC software to share a common address space on the FPGA.
Note: The name of the hardware shared memory is the same as the shared memory name used by
the original shared memory block. For example, if a shared memory block uses "my_memory," the
hardware implementation of the block can be accessed using the "my_memory" name.
All shared memories embedded inside the FPGA are automatically created and initialized
before the start of a simulation by their respective co-simulation blocks. This means that
any other shared memory objects that wish to access the hardware shared memory must
specify Ownership and initialization parameter as Owned and initialized elsewhere.
Doing so causes the software-based shared memories to attach automatically to the shared
memories that reside inside the FPGA.
Note that because both sides of the shared memory connect to user design logic, it is not
possible to communicate with these shared memories directly from the host PC.
The shared memory information table describes the type, bit width, and depth of each
shared memory in the design. For Shared Memory blocks, it also specifies the Access
Protection mode. Clicking on the [+] or [-] symbol next to the shared memory icon expands
or collapses the shared memory table, respectively.
The icons associated with each shared memory type are shown in the table below.
Shared Memory
Shared FIFO
Shared Register
When software shared memory objects read or write data to the shared memory, a proxy
seamlessly handles communication with the hardware memory resource.
The following figure shows an example of unprotected shared memory implemented in
the FPGA that is communicating with three shared memory objects running on the host
PC. In this example, the software shared memory objects access the hardware shared
memory by specifying the same shared memory name, my_mem. From the perspective of
the software shared memories, the implementation of the shared memory resource is
irrelevant; the hardware shared memory is treated as any another shared memory object.
Read and writes to the shared memory are handled by the shared memory API.
Note: Not all shared memory objects need to be created or executed in the Simulink environment.
The C++ application in the figure below is just one example of an external application that may
communicate with the hardware shared memory data using the shared memory API.
shared memories include additional logic to handle the mutual exclusion. The interaction
between hardware and software lockable shared memories is shown in the figure below: .
The red circle in the figure above represents a lock token. This token may be passed to any
shared memory object, regardless of whether it is implemented in hardware or software.
The dashed circle represents lock placeholders and signifies that lock can be passed to the
block it is associated with. The diamond in the figure above represents a modifiable token.
This token illustrates that when hardware has lock of the memory, the hardware shared
memory image may be modified. Likewise, when a software shared memory object has
lock, the software shared memory image may be modified.
Having two shared memory images requires synchronization between software and
hardware to ensure the images are coherent. This synchronization is accomplished by
transferring the memory image between software and hardware upon lock transfer.
System Generator performs high speed data transfers between the host PC and FPGA. The
semantics associated with these transactions are shown in the figure below. .
is possible for the PC to write to the register using System Generator's hardware co-
simulation interfaces.
When a To Register block is compiled for hardware co-simulation, as shown in the figure
below, the input ports are wired to user logic while the output port is wired to PC interface
logic. You may access a shared register during hardware co-simulation using the other half
of the shared register (i.e., using a To or From Register block), a C program or executable
(System Generator API), or a MATLAB program.
For designs that use hardware co-simulation, shared register pairs are typically distributed
between software and FPGA hardware. In other words, one half of the pair is implemented
in the FPGA while the other half is simulated in software using a To or From Register
block. When data is written to a software To Register block, the hardware register is
updated to with the same data. Similarly, when data is written into the hardware register,
the same data is read by the From Register software block. A software shared register may
connect to a hardware shared register simply by specifying the name of the shared register
as it was compiled for hardware co-simulation.
Note: You may find the names of all shared memories embedded inside an FPGA co-simulation
design by viewing the Shared Memories tab on a hardware co-simulation block.
When a software / hardware shared memory pair is co-simulated, System Generator
transparently manages the interaction between the PC and FPGA hardware. This means
that a shared register pair simulated in software should behave the same as a shared
register pair distributed between the PC and FPGA hardware.
Asynchronous FIFOs are typically used in multi-clock applications to safely cross clock
domain boundaries. When a Free-Running Clock mode is used for hardware co-
simulation, the FPGA operates asynchronously relative to the Simulink simulation. That is,
the FPGA is not kept in lockstep with the simulation. Using the Free-Running Clock mode
effectively establishes two clock domains: the Simulink simulation clock domain and the
FPGA free-running clock domain. In these designs, Shared FIFOs provide a reliable and
safe way to transfer data between the host PC and FPGA platform.
Shared FIFOs may also be used to support burst transfers during co-simulation. It is
possible to create vectors or frames of data, and transfer the data to the FPGA in a single
transaction with the hardware. These interfaces can be used to further accelerate
simulation speeds beyond what is typically possible with hardware co-simulation. For
more information on how this is accomplished, refer to the topic Frame-Based Acceleration
using Hardware Co-Simulation.
When a shared FIFO pair is generated for co-simulation, a single asynchronous FIFO core
replaces the two software shared FIFO blocks. As shown in the figure below, the read /
write FIFO sides are attached to user design logic (i.e., logic derived from the original
System Generator model) that attached to the From FIFO and To FIFO blocks. Because both
FIFO sides attach to user logic in hardware, the PC does not share control of the FIFO with
the design. Instead, the FIFO behavior is similar to a System Generator design that
includes a traditional FIFO block.
Note that even though the FIFO exposes independent clock ports, the same co-simulation
clock drives both ports when a FIFO pair is compiled. This is different from compiling a
shared FIFO pair using the Multiple Subsystem Generator block, where the clocks are from
distinct clock domains.
Single shared FIFO blocks are treated differently than shared FIFO pairs. A single To FIFO
or From FIFO block is replaced by an asynchronous FIFO core when it is compiled for
hardware co-simulation. One side of the FIFO (i.e., the unused shared FIFO half in System
Generator) is connected to PC interface logic. The other side is connected to user design
logic that attached to the original To or From FIFO block. In this manner, control over the
FIFO is distributed between the PC and FPGA design.
As shown in the following figure, when a To FIFO block is compiled for hardware co-
simulation, the write side of the FIFO is connected to the same logic that attached to To
FIFO block in user design. The read side of the FIFO is connected to PC interface logic that
allows the PC to read data from the FIFO during simulation.
In the figure below, the opposite wiring approach is used when a From FIFO block is
compiled for hardware co-simulation. In this case, the write side of the FIFO is connected
to PC interface logic, while the read side is connected to the user design logic. The host PC
writes data into the FIFO and the design logic may read data from the FIFO.
For designs that use hardware co-simulation, shared FIFO pairs are typically distributed
between software and FPGA hardware. In other words, one half of the pair is implemented
in the FPGA while the other half is simulated in software using a To or From FIFO block.
Together, the software and hardware portions form a fully functional asynchronous FIFO.
When a software / hardware shared FIFO pair is co-simulated, System Generator
transparently manages the necessary transactions between the PC and FPGA hardware.
When data is written to a software To FIFO block during simulation, the same data is
written to the FIFO in hardware. The design in hardware may then retrieve this data by
reading from the FIFO. Similarly, when data is written into the hardware FIFO by design
logic, the data may be read by the From FIFO software block. Note that the empty, full, read
and write count ports on the shared FIFO blocks pessimistically reflect the state of the
hardware FIFO counterpart. A software shared FIFO may connect to a hardware shared
FIFO simply by specifying the name of the shared FIFO as it was compiled for hardware
co-simulation.
Note: You may find the names of all shared memories embedded inside an FPGA co-simulation
design by viewing the Shared Memories tab on a hardware co-simulation block.
The Hardware Co-Simulation Settings dialog box, shown below, allows you to specify
options files other than the default options files provided by the compilation target.
Shared Memories
Before a System Generator design can support vector transfers, it must be augmented with
appropriate input and output buffers. In hardware, these buffers are implemented using
internal memory (e.g., BRAMs) and are used to store vectors of simulation data that are
written to and read from the FPGA by the PC. This means that the maximum size of the
buffers is limited by the amount of internal memory available on the target device. In
System Generator, shared memory blocks provide interfaces that implement such buffers.
A question that quickly comes to mind is why not use standard FIFO or memory blocks?
The buffers required for hardware co-simulation differ from traditional FIFOs and
memories in that they must be controllable by both the PC and FPGA user design logic.
The standard FIFO and memory blocks provided by System Generator can only interface
with user design logic.
There are two types of shared memories that provide this control: lockable shared
memories and shared FIFOs. These blocks provide different buffering styles; each with
their own handshaking protocols that determine when and how burst transactions with
the FPGA occur. In this tutorial, primary attention is focused on shared FIFO buffers. For
an example on how to use lockable shared memories, please refer to the tutorial entitled
Real-Time Signal Processing using Hardware Co-Simulation. You may find the lockable
shared memory and FIFO blocks in the Shared Memory library of the Xilinx Blockset.
Because shared FIFOs play a central role in enabling vector transfers, it is worth a brief
aside to discuss their behavior. A shared FIFO pair is comprised of a To FIFO block and a
From FIFO block that specify the same name (e.g., Bar in the figure above). The To FIFO
block provides the "write side" control signals, while the From FIFO block provides the
"read side" control signals. When used together, a shared FIFO pair is conceptually the
same thing as a single FIFO – only the control signals for the two sides are graphically
disjoint. This means that a shared FIFO pair shares the same FIFO memory space. For
example, if you write data into a To FIFO block, you may retrieve the same data by reading
from the From FIFO block. The connection between these two blocks is implicit; shared
FIFOs are associated with one another by name and not by explicit Simulink wires.
Shared FIFOs and shared memories in general may be compiled for hardware co-
simulation. Note that although this tutorial touches briefly on how shared FIFOs are co-
simulated, it is useful to refer to the topic titled Co-Simulating Shared FIFOs for more in-
depth information. When one-half of a shared FIFO block is compiled for hardware co-
simulation, a full FIFO block is embedded in the FPGA using the FIFO Generator core. One
side of the FIFO connects to user design logic (i.e., the System Generator logic that
connected to the shared FIFO block). The other half connects to interface logic that allows
it to be controlled by the PC. This side of the FIFO may be controlled by other System
Generator software model logic (e.g., the half of the shared FIFO), by a C program or
software executable, or by a MATLAB program. By compiling shared FIFOs for hardware
co-simulation, you create embedded FIFO-style buffers in the FPGA that can be controlled
directly by a PC.
There are several ways to communicate with a shared FIFO that is embedded inside the
FPGA. The most common approach is to include the other half of the shared FIFO in the
System Generator design. It is also possible to communicate with the shared FIFO using a
C program or MATLAB program. System Generator provides additional blocks that
support vector transfers to and from the FIFO. These blocks will be touched on later in the
tutorial as they play a key role in supporting burst transfers to and from the FPGA.
available in the input FIFO. Conversely, data is written into the output FIFO whenever
valid data is present on the data path.
To gain a better understanding of how the Shared FIFOs are used, you will now take a look
at an example design that uses vector transfers to accelerate a MAC filter design.
1. From the MATLAB console, change directory to
<sysgen_tree>/examples/shared_memory/hardware_cosim/frame_acc.
2. Open macfir_sw_w_fifos.mdl from the MATLAB console.
The example design implements a 32-tap MAC FIR filter that removes additive white noise
from a sinusoid input source. The amount of white noise can be adjusted interactively by
moving the Slider Gain control bar before or during simulation. An output scope compares
the filtered output data against the unfiltered input data. The MAC filter itself is contained
inside a subsystem named hw_cosim. This subsystem contains all of the logic that will be
compiled into the FPGA for hardware co-simulation. You consider everything else in the
design (i.e., all blocks in the top-level) as the design testbench.
Pushing into the hw_cosim subsystem, you have an n-tap MAC FIR Filter block that
implements the design data path. Wrapping the filter are From FIFO and To FIFO blocks
that provide the input and output buffers, respectively. The MAC filter in the example
design is a modified version of the n-tap MAC filter available in the System Generator DSP
Reference Blockset library. In the example, the filter is modified to include valid in and
valid out ports in order to support the FIFO flow control scheme.
In total, there are four shared memory blocks in the design that define the CA and VA
shared FIFO pairs. In truth, you only need the shared FIFO blocks contained inside the
hw_cosim subsystem to successfully compile the design for hardware co-simulation.
Because you would like to simulate the complete design, including FPGA hardware, you
include a CA To FIFO block and VA From FIFO block in the testbench logic. These shared
FIFO blocks are responsible for writing and reading test data from the shared FIFOs in the
hw_cosim subsystem.
Unfiltered data from the din Gateway In block is written into the CA To FIFO block. At this
point, the CA From FIFO block in the hw_cosim subsystem reads data from the FIFO and
writes it into the MAC filter. The MAC filter in turn processes the data and writes it into the
output buffer, represented by the VA To FIFO block. Lastly, the VA From FIFO block in the
top-level reads the data and sends it to the Scope block for visualization.
For this example, you have chosen a maximum buffer size of 4K. This parameter is set by
specifying 4K for the Depth parameter on the CA From FIFO and VA To FIFO block dialog
boxes. Note that because shared FIFOs are implemented using asynchronous FIFO
Generator cores, the actual depth of the hardware FIFO is n-1 words, where n is the depth
specified on the dialog box.
You will now have a chance to simulate the design to see how fast it runs in software.
3. Press the Simulink Start button to simulate the design in software.
4. Record the time required to simulate the design for 10000 cycles. To get an accurate
measurement, it is preferable to leave the scope block closed since the graphic updates
may affect simulation performance.
You may adjust the Slider Gain bar during simulation to see how the presence of additional
noise affects the filter performance. You may view the filtered and unfiltered data in the
output scope block. The top axis shows the unfiltered input data. The bottom axis shows
the filtered data results.
7. Press the Generate button on the System Generator dialog box to generate the design.
A new hardware co-simulation library and block are created once System Generator
finishes compiling the design. Note that the new hardware co-simulation block does not
have any input or output ports. This is because the subsystem that was compiled did not
contain gateway blocks or Simulink ports. Instead, all connections to other Simulink blocks
are handled implicitly through shared memories that were compiled into the FPGA.
Because you left the To FIFO and From FIFO blocks as part of the software testbench, the
software FIFOs will automatically attach to the FIFOs in hardware at the beginning of
simulation.
It is often necessary to examine the type and configuration of a shared memory that was
compiled for hardware co-simulation. The information about each shared memory is
available in a Shared Memories tab on the hardware co-simulation block dialog box. This
tab contains a tree view of information about each shared memory embedded in the
design.
8. Double-click on the hardware co-simulation block to open the parameters dialog box.
9. Select the Shared Memories tab in the hardware co-simulation block dialog box.
The tree-view contains information about the CA and VA shared FIFO blocks that were
compiled. If your co-simulation design contains other shared memory blocks, information
about these blocks will also be displayed here. You may expand or collapse shared
memory information by clicking on the (+) or (-) icons located adjacent to the shared
memory icons.
13. Configure the hardware co-simulation block with any settings necessary to co-
simulate using single-step clock mode.
14. Press the Simulink Start button to start the design.
15. Record the amount of time required to simulate the design for 10000 cycles.
16. Close the design, but leave the hardware co-simulation library open since you will
need it in the next topic.
In the simulation above, hardware co-simulation uses single word transfers. That is,
whenever there is a new simulation value to be read or written to the hardware co-
simulation, the PC initiates a transaction with the FPGA. The next topic describes how
vector transfers may be used to increase simulation speed by making more efficient use of
the available hardware co-simulation bandwidth.
The Shared Memory Write block accepts a Simulink scalar, vector, matrix or frame data
type and writes the data sequentially into a shared memory. The complete contents of the
Simulink signal are written into the shared memory in a single simulation cycle. As is the
case with all shared memory blocks, an association is made between a Shared Memory
Read or Write block and another shared memory by specifying the same shared memory
name.
Matrix types are treated as having a column-major order. That is, when data is written
sequentially into a shared memory, the elements in a column are written first before
advancing to the next column. For example, assume you have the matrix of data shown
below. During simulation, this matrix data is written into the FIFO (or shared memory) in
the following order:
Using these blocks, it is possible to read or write full vector, frame, or matrix signals into
shared memories, provided the following conditions are met:
• The input signal driven to a shared memory write block is an 8-bit, 16-bit, or 32-bit
signed or unsigned integer;
• The number of elements in the vector or matrix does not exceed the depth of the
shared memory or FIFO.
• The data width of the Shared Memory Read or Write block (i.e., the bitwidth of the
scalar, or vector or matrix element) equals the shared memory or FIFO data width.
You can use these blocks in the example design to read and write vectors of data samples
to the MAC filter in a single software / hardware transaction.
17. Open macfir_hw_w_frames_tb.mdl from the MATLAB console.
This design is a very similar to the previous design, with a few modifications made to
support the Shared Memory Read and Write blocks. Before simulating the design, you
consider each of these modifications. Most importantly, Shared Memory Read and Write
blocks have been substituted in place of the To and From FIFO testbench blocks in the
previous design. By specifying CA and VA as the Write and Read shared memory names,
respectively, an association is automatically made to the input and output FIFO buffers in
the FPGA hardware during simulation.
A Simulink Buffer block builds a frame of scalar input samples by sequentially buffering
the unfiltered input data. A simple analogy is that the Buffer block is performing a serial to
parallel conversion. Recalling that you compiled the FIFO buffers with a depth of 4K, you
choose a frame size of 4095.
Note that the buffer block introduces a sample rate change in the design. For every 4095
inputs, there is only one output. Thus if the data input sample period is 1, the buffer data
output sample period is 4095. This means that the Shared Memory Write block need only
send a new frame of data to the FPGA on every 4095th simulation cycle (which is
considerably more efficient than initiating a hardware transaction during every simulation
cycle).
Because the Buffer block introduces a rate change, you must adjust the downstream blocks
to accommodate the slower sample period. You begin by telling the Shared Memory Read
block to read a frame of data every 4095th simulation cycle.
18. Double-click on the Shared Memory Read block to open its parameters dialog box.
On the Type field under the Basic tab, you have configured the block to use shared FIFOs.
To ensure a new frame is read at the appropriate time, you configure the Shared Memory
Read block with a Sample time value of 4095.
The Shared Memory Read block allows you to specify the output data type and
dimensions.
19. On the parameters dialog box, switch to the Output Type tab.
There are several things of interest on this tab. First, you set the output data type as an int32
to match the filter data path output width of 32-bits. Note the design will not simulate
unless these widths match. Secondly, you choose an output dimension that is 4095 words
deep in the Output dimensions field. Finally, you tell the block to generate frame-based
output since frame data types are required by the downstream Unbuffer block.
20. Close the parameters dialog box.
The Simulink Unbuffer block takes the frame data from the Shared Memory Read block
and deserializes it into sequential scalar values. The Simulink Unbuffer block also
introduces a sample rate change in the diagram. Because the input sample period to the
block is 4095, and the frame size is 4095 words, the Unbuffer block output sample period is
1. This works out nicely since you have data moving through the overall system at an
effective sample period of 1.
Because the Shared Memory Write and Read block operate on integer values, you must
insert Simulink type conversion blocks into the diagram so that the data is interpreted
correctly in various portions of the model. The in_data_conv subsystem converts the
Simulink doubles into 16-bit integer values that can be interpreted appropriately by the
FPGA hardware. On the output side, the out_data_conv subsystem converts the 32-bit
integers into 32-bit Simulink fixed-precision values.
Before simulating the design, you must add the hardware co-simulation block you created
from the previous design.
21. Add the hardware co-simulation block to the design as shown below.
As mentioned before, the Shared Memory Write block writes a new input frame of 4095
words to the FPGA on every 4095th clock cycle. Likewise, the Shared Memory Read block
reads an output frame of 4095 words from the FPGA on every 4095th clock cycle. This
means that the FPGA must process the entire frame in a single-cycle. How exactly is this
accomplished?
The first step is to configure the FPGA in free-running clock mode. In doing so, you allow
the FPGA to process data considerably faster than if it were otherwise kept in lockstep with
the Simulink simulation. Whereas in single-step mode the FPGA can only process one data
per Simulink cycle, the FPGA processing speed is limited only by the system clock
frequency when operating in free-running clock mode. Even so, if the buffer is large
enough, the FPGA may not have time to process the complete buffer before the next block
in the design is woken up. You still need a way to stall the rest of the simulation while the
FPGA processes the entire buffer.
The Shared Memory Read block checks the number of FIFO words available in the output
buffer before trying to read a frame. If the number of words in the buffer is insufficient, the
Read block waits for a small amount of time, and then checks again to determine if the
words have become available. It only reads the frame once all of the words are available in
the output buffer, in this case 4095. In this manner, the Shared Memory Read block can stall
the simulation until the complete frame has been processed by the FPGA.
Two steps necessary to run the simulation using Simulink frames signals are provided
below:
22. Double-click on the hardware co-simulation block to bring up the parameters dialog
box.
23. Select Free running clock mode as shown below.
24. Configure the hardware co-simulation block with any additional settings necessary for
simulation according to the requirements of your co-simulation platform.
25. Press the Simulink Start button to start the design.
26. Record the amount of time required to simulate the design for 10000 cycles.
from the host PC, through the interface, and back to the host PC. Operation of the I/O
buffering interface is shown in the flow chart below:
Notice that the buffering interface design includes several data valid ports. These ports are
used for data flow control. A "true" output from the Input Buffer dout_valid port
indicates new data is ready to be processed by the data path. Likewise, when the data path
is finished processing the data, it should drive the Output Buffer subsystem's
din_valid port to "true" to indicate valid output data (the din_valid port is analogous to
a write enable control signal).
The example includes a placeholder that should be replaced by a System Generator data
path. You may insert any data path in the buffer interface provided that it works within the
valid signal semantics described above.
Note: The output buffer shared memory does not release lock until the output buffer is full. To avoid
deadlock, the number of valid assertions by the data path should equal the output memory buffer size
for a given processing cycle.
The data path uses line buffers to properly align data samples in the filter kernel. The size
of these line buffers can be parameterized to accommodate different frame sizes. In this
example, the line buffers are implemented in the Virtex2 5 Line Buffer block in the
conv5x5_video_ex/5x5_filter subsystem, and are pre-configured with a line size of
128. If you decide to process a different size frame, the Line Size parameter should be
updated accordingly.
An addressable shift register block (ASR) is used to delay the valid bit. The offset port is
used to control the address of the ASR block, which in turn controls the amount of latency
the valid bit incurs. By simply delaying the valid bit generated by the input buffer block,
You ensure the number of words written to the output buffer is always equal to the buffer
size. Note that when the design is run in hardware, a change in the offset value will cause
the vertical alignment of the filtered images to change.
The coefficient_memory contains a copy of the most recently loaded filter coefficients,
which are stored in an unprotected shared memory named coef_buffer. During run-
time, the subsystem monitors the shared memory contents, and initiates a reload sequence
if detects a change. By co-simulating the unprotected shared memory, any process on the
host PC may write new kernel coefficients simply by writing to a shared memory object
named coef_buffer. This interface is convenient, as communication with the FPGA
hardware is completely abstracted through the Shared Memory API.
Hardware co-simulation blocks include information about any shared memories, registers,
or FIFOs that were compiled as part of the design. You may view this information by
double-clicking on the hardware co-simulation block to open the parameters dialog box.
Once the dialog box is open, selecting the Shared Memories tab reveals information
about each shared memory in the compiled design.
Go ahead and leave the hardware co-simulation library open. In the next topic you will
include the hardware co-simulation block in a video processing testbench design.
lock of Foo and Bar, causing the FPGA shared memory images to be transferred
back to the host PC.
c. The Shared Memory Read block wakes up and requests lock of the output buffer
lockable shared memory Bar. The block reads a video from the output buffer and
drives its output port with the processed video frame data.
Note that the three steps listed above assume a specific sequencing of the hardware co-
simulation and Shared Memory Read and Write blocks. To ensure these blocks are
properly sequenced, you can set block priorities, where a lower priority block is woken up
first during simulation.
9. Add the hardware co-simulation block to the testbench model in place of the turquoise
placeholder residing in the FPGA Processing subsystem.
The Shared Memory Write block in the testbench is pre-configured with a priority of 1, and
the Shared Memory Read block is pre-configured with a priority of 3. Since you want the
hardware co-simulation block to wake up second in the simulation sequence, you must set
the hardware co-simulation block priority to 2.
10. Right-click on the hardware co-simulation block, and select Block Properties.
The left image is the original video frame. The image on the right is the same frame that has
been processed using the "smooth" filter kernel. Note that the smoothing filter is just one of
several filters that can be applied to the video source.
1. As shown below, from the Start menu, select Control Panel, then right-click on Local
Area Connection, then select Properties.
2. As shown below, select Internet Protocol (TCP/IP), then click on the Properties button
and set the IP Address 192.168.8.2 and Subnet mask to 255.255.255.0. (The last digit of
the IP Address must be something other than 1, because 192.168.8.1 is the default IP
address for the ML402. See the topic Load the Sysgen ML402 HW Co-Sim
Configuration Files below for further details.)
3. Click on the Configure button, select the Advanced tab, select Flow Control, then
select Auto.
4. Set Speed & Duplex to Auto, then click out using the OK button.
The following files and folder should now be listed on the CompactFlash drive:
Optional Step to set the Ethernet MAC Address and the IPv4 Address
Note: The following step may be necessary if the default MAC and IP addresses conflict with your
default network settings, or if you wish to co-simulate two or more ML402 boards concurrently. If not,
proceed to the next topic.
After writing the data to the card, you will find two files, mac.dat and ip.dat, in the
card root directory. The mac.dat and ip.dat files specify the Ethernet MAC address
and IPv4 address associated with the board, respectively. These addresses are used to
uniquely identify a target board during Ethernet hardware co-simulation.
a. Open mac.dat in a text editor and change the Ethernet MAC address. The MAC
address must be specified as a six pair of two-digit hexadecimal separated by
colons (e.g. 00:0a:35:11:22:33). All-zeros, broadcast, or multicast MAC
addresses are not supported.
b. Open ip.dat in a text editor and change the IP address. The IP address must be
specified in IPv4 dotted decimal notation (e.g. 192.168.8.1). All-zeros,
broadcast, multicast, or loop-back IP address are not supported. After changing
the IP address for ML402 board, update the IP address for the network connection
on the PC accordingly as mentioned in topic Setup the Local Area Network on the
PC. For direct connection, the ML402 and the PC must be on the same subnet.
Otherwise, the ML402 IP address should be reachable from the PC and vice versa.
1. Position the ML402 board so the Virtex™-4 and Xilinx logos are oriented near the top
edge of the board.
2. Make sure the power switch, located in the upper-right corner of the board, is in the
OFF position.
3. As shown below, Eject the CompactFlash card from the CompactFlash Reader.
Note: The CompactFlash card provided with your board might differ.
Caution! Be careful when inserting or removing the CompactFlash card from the slot. Do not
force it.
6. Connect the AC power cord to the power supply brick. Plug the power supply adapter
cable into the ML402 board. Plug in the power supply to AC power.
Caution! Make sure you use an appropriate power supply with corrrect voltage and power
ratings.
7. Using the RJ45 Male/Male Ethernet Cable, connect the Ethernet connector on the
ML402 board directly to the Ethernet connector on the host PC.
8. Set the Configuration Address DIP Switches.
As shown below, set the Configuration Address DIP Switches as follows: 1:on, 2:off,
3:off, 4:on, 5:off, 6:on]
As shown below, set the Configuration Source Selector Switch to SYS ACE
d. If the LCD display does not show the information correctly, press the System ACE
Reset button to reconfigure the FPGA.
e. Check the status LEDs again to ensure the configuration sequence completed
successfully.
11. Verify the Ethernet Interface and Connection Status
a. Connect the Ethernet interface of the board to a network connection, or directly to
a host.
b. Check the on-board Ethernet status LEDs to make sure the Ethernet interface is
attached to an active Ethernet segment. The LEDs should reflect the link speed and
the duplex mode at which the interface is operating. The TX and RX leds should
flash on and off occasionally depending on the network traffic. If no LED is on,
press the CPU Reset button to reset the FPGA, and also examine whether the
Ethernet segment is active.
c. To ensure the board is reachable by the host, issue ICMP ping from the host to
check the connectivity. For example, type "ping 192.168.8.1" on a console to test the
connectivity to a board with IP address 192.168.8.1.
d. The target FPGA listens on the UDP port 9999. Please ensure the underlying
network does not block the associated traffic when network-based Ethernet
configuration is used. This does not affect point-to-point Ethernet configuration.
2. As shown below, select Internet Protocol (TCP/IP), then click on the Properties button
and set the IP address 192.168.8.2 and the Subnet mask to 255.255.255.0. (The last digit
of the IP Address must be something other than 1 because 192,168.8.1 is the default IP
address fo ML506. See Load the Sysgen ML506 HW Co-Sim Configuration Files for
further details.).
3. Click on the Configure button, select the Advanced tab, select Flow Control, then
select Auto.
4. Set Speed & Duplex to Auto, then click out using the OK button.
The following files and folder should now be listed on the CompactFlash drive:
Optional Step to set the Ethernet MAC Address and the IPv4 Address
Note: The following step may be necessary if the default MAC and IP addresses conflict with your
default network settings, or if you wish to co-simulate two or more ML506 boards concurrently. If not,
proceed to the next topic.
After writing the data to the card, you will find two files, mac.dat and ip.dat, in the
card root directory. The mac.dat and ip.dat files specify the Ethernet MAC address
and IPv4 address associated with the board, respectively. These addresses are used to
uniquely identify a target board during Ethernet hardware co-simulation.
a. Open mac.dat in a text editor and change the Ethernet MAC address. The MAC
address must be specified as a six pair of two-digit hexadecimal separated by
colons (e.g. 00:0a:35:11:22:33). All-zeros, broadcast, or multicast MAC
addresses are not supported.
a. Open ip.dat in a text editor and change the IP address. The IP address must be
specified in IPv4 dotted decimal notation (e.g. 192.168.8.1). All-zeros,
broadcast, multicast, or loop-back IP address are not supported. After changing
the IP address for the ML506 board, update the IP address for the network
connection on the PC accordingly as mentioned in the topic Setup the Local Area
Network on the PC. For direct connection, the ML506 and the PC must be on the
same subnet. Otherwise, the ML506 IP address should be reachable from the PC
and vice versa.
Configuration Address
DIP Switches (SW3) Power Connector Power Switch
Ethernet
1. Position the ML506 board so the Xilinx logo is oriented near the lower-left corner.
2. Make sure the power switch, located in the upper-right corner of the board, is in the
OFF position.
3. As shown below, Eject the CompactFlash card from the CompactFlash Reader.
6. Connect the AC power cord to the power supply brick. Plug the 5V power supply
adapter cable into the ML506 board. Plug in the power supply to AC power.
Caution! Make sure you use an appropriate power supply with correct voltage and power
ratings.
7. Using the RJ45 Male/Male Ethernet Cable, connect the Ethernet connector on the
ML506 board directly to the Ethernet connector on the host PC.
SW3 Configuration
Address
DIP Switches
(not yet configured)
d. If the LCD display does not show the information correctly, press the System ACE
Reset button to reconfigure the FPGA.
e. Check the status LEDs again to ensure the configuration sequence completed
successfully.
11. Verify the Ethernet Interface and Connection Status
a. Connect the Ethernet interface of the board to a network connection, or directly to
a host.
b. Check the on-board Ethernet status LEDs to make sure the Ethernet interface is
attached to an active Ethernet segment. The LEDs should reflect the link speed and
the duplex mode at which the interface is operating. The TX and RX leds should
flash on and off occasionally depending on the network traffic. If no LED is on,
press the CPU Reset button to reset the FPGA, and also examine whether the
Ethernet segment is active.
c. To ensure the board is reachable by the host, issue ICMP ping from the host to
check the connectivity. For example, type "ping 192.168.8.1" on a console to test the
connectivity to a board with IP address 192.168.8.1.
d. The target FPGA listens on the UDP port 9999. Please ensure the underlying
network does not block the associated traffic when network-based Ethernet
configuration is used. This does not affect point-to-point Ethernet configuration.
1. As shown below, from the Start menu, select Control Panel, then right-click on Local
Area Connection, then select Properties.
2. As shown below, select Internet Protocol (TCP/IP), then click on the Properties button
and set the IP address 192.168.8.2 and the Subnet mask to 255.255.255.0. (The last digit
of the IP Address must be something other than 1 because 192.168.8.1 is the default IP
address for Starter Platform.
3. Click on the Configure button, select the Advanced tab, select Flow Control, then
select Auto.
4. Set Speed & Duplex to Auto, then click out using the OK button.
2. As shown below, select Internet Protocol (TCP/IP), then click on the Properties button
and set the IP address 192.168.8.2 and the Subnet mask to 255.255.255.0. (The last digit
of the IP Address must be something other than 1 because 192,168.8.1 is the default IP
address fo ML506. See Load the Sysgen ML506 HW Co-Sim Configuration Files for
further details.).
3. Click on the Configure button, select the Advanced tab, select Flow Control, then
select Auto.
4. Set Speed & Duplex to Auto, then click out using the OK button.
Optional Step to set the Ethernet MAC Address and the IPv4 Address
Note: The following step may be necessary if the default MAC and IP addresses conflict with your
default network settings, or if you wish to co-simulate two or more ML506 boards concurrently. If not,
proceed to the next topic.
After writing the data to the card, you will find two files, mac.dat and ip.dat, in the
card root directory. The mac.dat and ip.dat files specify the Ethernet MAC address
and IPv4 address associated with the board, respectively. These addresses are used to
uniquely identify a target board during Ethernet hardware co-simulation.
a. Open mac.dat in a text editor and change the Ethernet MAC address. The MAC
address must be specified as a six pair of two-digit hexadecimal separated by
colons (e.g. 00:0a:35:11:22:33). All-zeros, broadcast, or multicast MAC
addresses are not supported.
a. Open ip.dat in a text editor and change the IP address. The IP address must be
specified in IPv4 dotted decimal notation (e.g. 192.168.8.1). All-zeros,
broadcast, multicast, or loop-back IP address are not supported. After changing
the IP address for the ML506 board, update the IP address for the network
connection on the PC accordingly as mentioned in the topic Setup the Local Area
Network on the PC. For direct connection, the ML506 and the PC must be on the
same subnet. Otherwise, the ML506 IP address should be reachable from the PC
and vice versa.
Power Switch
Configuration
Address
DIP Switches (S2)
System ACE
Reset Button
The figure below illustrates the Spartan-3A 3400A Board (Rev D) components of interest in
this setup procedure:
Configuration
Address
DIP Switches (S2)
System ACE
Reset Button
LCD
Power Switch
Compact Flash Card +5V Power Connector
1. Position the Spartan-3A 3400A Development Board as shown above with the LCD
display at the bottom.
2. Make sure the power switch is in the OFF position.
3. As shown below, Eject the CompactFlash card from the CompactFlash Reader.
6. If you are using a “Rev C” 3400A Development Platform, plug the +12V power supply
adapter cable into the power connector. Plug in the power supply into AC power.
If you are using a “Rev D” 3400A Development Platform, plug the +5V power supply
adapter cable into the power connector. Plug in the power supply into AC power.
Caution! Make sure you use an appropriate power supply with the correct voltage
and power ratings.
7. Using the RJ45 Male/Male Ethernet Cable, connect the Ethernet connector on the
Spartan-3A 3400A board directly to the Ethernet connector on the host PC.
c. If the LCD display does not show the information correctly, press the System ACE
Reset button to reconfigure the FPGA.
11. Verify the Ethernet Interface and Connection Status
a. To ensure the board is reachable by the host, issue ICMP ping from the host to
check the connectivity. For example, type "ping 192.168.8.1" on a console to test the
connectivity to a board with IP address 192.168.8.1.
b. The target FPGA listens on the UDP port 9999. Please ensure the underlying
network does not block the associated traffic when network-based Ethernet
configuration is used. This does not affect point-to-point Ethernet configuration.
For indepth reference information on the Spartan-3A 3400A Development Platform, plese
refer to the following online manual:
http://www.xilinx.com/bvdocs/ipcenter/user_guide_user_manual/s3a-dsp-3400a-
userguide.pdf
1. Position the ML402 board so the Virtex™-4 and Xilinx logos are oriented near the top
edge of the board.
2. Make sure the power switch, located in the upper-right corner of the board, is in the
OFF position.
3. If you are using a Xilinx Parallel Cable IV, follow steps 3a through 3d.
a. Connect the DB25 Plug Connector on the Xilinx Parallel Cable IV to the IEEE-1284
compliant PC Parallel (Printer) Port Connector .
b. Using the narrow (14 pin) 6” High Performance Ribbon cable, connect the pod end
of the Xilinx Parallel Cable IV to the FPGA & CPU Debug Port (shown above) on
the ML402 Board.
c. Connect the attached Power Jack cable to the Keyboard/Mouse connector on the
PC.
d. If necessary, connect the male end of the Keyboard/Mouse cable to the associated
female connector on the Xilinx Power Jack cable (splitter cable) .
4. If you are using a Xilinx Platform Cable USB, follow step 4a and 4b..
a. Connect the Xilinx Platform Cable USB to a USB port on the PC.
b. Using the narrow (14 pin) 6” High Performance Ribbon cable, connect the pod end
of the Xilinx Platform Cable USB to the FPGA & CPU Debug Port (shown above)
on the ML402 Board.
5. Connect the AC power cord to the power supply brick. Plug the power supply adapter
cable into the ML402 board. Plug in the power supply to AC power.
Caution! Make sure you use an appropriate power supply with correct voltage and power
ratings.
6. Turn the ML402 Board Power switch ON.
Hardware Requirements
An FPGA platform can support the JTAG hardware co-simulation interface, provided it
includes the following hardware components:
• A Xilinx FPGA part that is available in System Generator as a supported device (i.e., a
device that can be chosen in the Part field of the System Generator block dialog box);
• An on-board oscillator that supplies the FPGA with a free-running clock source;
• A JTAG header that provides access to the FPGA.
Once the main dialog box is open, you may create a board support package by filling in the
required fields described below:
Board Name: Tells a descriptive name of the board. This is the name that will be listed in
System Generator when selecting your JTAG hardware co-simulation platform for
compilation.
System Clock: JTAG hardware co-simulation requires an on-board clock to drive the
System Generator design. The fields described below specify information about the
board's system clock:
• Frequency (MHz): Specifies the frequency of the on-board system clock in MHz.
• Pin Location: Specifies the FPGA input pin to which the system clock is connected.
JTAG Options: System Generator needs to know several things about the FPGA board's
JTAG chain to be able to program the FPGA for hardware co-simulation. The topic
Obtaining Platform Information describes how and where to find the information required
for these fields. If you are unsure of the specifications of your board, please refer to the
manufacturer's documentation. The fields specific to JTAG Options are described below:
• Boundary Scan Position: Specifies the position of the target FPGA on the JTAG chain.
This value should be indexed from 1. (e.g. the first device in the chain has an index of
1, the second device has an index of 2, etc.)
• IR Lengths: Specifies the lengths of the instruction registers for all of the devices on
the JTAG chain. This list may be delimited by spaces, commas, or semicolons.
• Detect: This action attempts to identify the IR Lengths automatically by querying the
FPGA board. The board must be powered and connected to a Parallel Cable IV for this
to function properly. Any unknown devices on the JTAG chain will be represented
with a "?" in the list, and must be specified manually.
Targetable Devices: This table displays a list of available FPGAs on the board for
programming. This is not a description of all of the devices on the JTAG chain, but rather a
description of the possible devices that may exist at the aforementioned boundary scan
position. For most boards, only one device needs to be specified, but some boards may
have alternate, e.g., a choice between an xcv1000 or an xcv2000 in the same socket. Use the
Add and Delete buttons described below to build the device list:
• Add: Brings up a menu to select a new device for the board. As shown in the figure
below, devices are organized by family, then part name, then speed, and finally the
package type.
• Delete: Remove the selected device from the list.
Non-Memory-Mapped Ports: You can add support for your own board-specific ports
when creating a board support package. Board-specific ports are useful when you have on-
board components (e.g., external memories, DACs, or ADCs) that you would like the
FPGA to interface to during hardware co-simulation. Board specific ports are also referred
to as non-memory-mapped because when the design is compiled for hardware co-
simulation, these ports will be mapped to their physical locations, rather than creating
Simulink ports. See Specifying Non-Memory Mapped Ports for more information. The
Add, Edit, and Delete buttons provide the controls needed for configuring non-memory
mapped ports.
• Add: Brings up the dialog to enter information about the new port.
• Edit: Make changes to the selected port.
• Delete: Remove the selected port from the list.
Help: Displays this documentation.
Load: Fill in the form with values stored in an SBDBuilder Saved Description XML file.
This file is automatically saved with every plugin that you create, so it is useful for
reloading old plugin files for easy modification.
Save Zip: Prompts you for a filename and a target pathname. This will create a zip file with
all of the plugin files for System Generator. The zip will be in a suitable format for passing
to the System Generator xlInstallPlugin function.
Exit: Quit the application.
The port editor dialog presents the following controls for port configuration:
Port Options: Specifies the options that will affect the entire port.
• Port Name: This is the name that will describe the port in System Generator. It should
be a MATLAB-compatible name (begins with a letter, followed by only letters,
numbers, and underscores).
• Input/Output: Specifies the direction of the port.
New Pin: This is the entry point to add pins to a port. Ports may consist of a single pin for
a Boolean value, or multiple pins for a vector or bus.
• Pin LOC: Defines the absolute placement of the pin within the FPGA by specifying a
location constraint. It is necessary to define this for every pin to make sure that the
FPGA programming corresponds to the actual hardware connections.
• PULLUP: A constraint that can be applied to each pin. It guarantees a logic High level
to allow 3-stated nets to avoid floating when not being driven.
• FAST: A constraint that can be applied to each pin. It increases the speed of an IOB
output. FAST produces a faster output but may increase noise and power
consumption.
• Add Pin: Add a pin to the port. Note that the pin is not part of the port until this
button is selected.
Note: Pressing 'enter' while the cursor is in the Pin LOC field is equivalent to pressing this
button.
Pin List:
• Index: (Cannot edit directly) Since a port can be more than one bit, it is represented as
a vector of pins. The index indicates which bit position a particular pin represents in
the port. Zero is the least-significant bit.
• Move Up/Down: Move the selected pin up or down in the pin list. This is useful to
correct the vector bit-ordering of the port.
• Delete Pin: Removes the selected pin from the list.
Save and Start New: Save the port to the board support package. The form will then be
cleared so that you may enter a new port.
Save and Close: Save the port to the board support package and return to the main screen.
Cancel: Discard changes to the current port and return to the main screen.
When you are finished entering a port, it will look similar to the dialog box shown below:
At this point, you can save the board support package into a System Generator plugin zip
file or as the raw board support package files described in the topic Board Support Package
Files, plus the additional SBDBuilder files described below:
• yourboard.xml: This is the SBDBuilder Saved Description, which allows SBDBuilder
to reload plugins you have previously created. The name you select for this file
('yourboard') will propagate into the names of the other files as well.
• yourboard_libgen.m: Automates the process of creating the gateways for the non-
memory-mapped ports on this device. Running this script results in the creation a
library like that shown below:
Information Description
Clock pin location Pin location constraint for the FPGA system clock source.
Clock period Period constraint for the FPGA system clock source.
Device position in Tells the position of the target FPGA in the platform's Boundary
the Boundary Scan Scan Chain. Indexing begins at 1, with device 1 being the first
Chain device in the chain.
Instruction register Instruction register length of every device in the Boundary Scan
lengths Chain.
You may obtain the clock pin location and period from any number of possible sources,
including the vendor documentation, existing constraints files, or vendor online
documentation/support.
If you do not know which devices are in your platform's boundary scan chain, you may
use iMPACT to assist you in finding this information. iMPACT is a tool that is included
with the Xilinx ISE software that allows you to perform device configuration and file
generation functions. When the tool is invoked, it automatically detects the contents of
your platform's boundary scan chain, and displays these contents graphically, as shown
below.
Once you have determined which devices are in the Boundary Scan Chain, you must
determine the instruction register lengths for each device. The table below specifies the
instruction register lengths for various Xilinx families. You may use the auto detection
capability of SBDBuilder to determine the instruction register lengths. If this utility does
not work, you may use the following table to find the instruction register lengths for a
particular part family.
Family IR Length
XC1800 / XC18V00 8
XC4000XL/XLA 3
Spartan-XL 3
System_ACE-CF 8
Virtex / Virtex-E(EM) 5
Spartan-II / Spartan-IIE 5
Virtex-II 6
Spartan-3 6
Spartan-3E 6
Spartan-3A/Spartan-3AN 6
Spartan-3A DSP 6
Virtex-II Pro 2, 4, 7 10
Virtex-II Pro 20, 30, 40, 50, 70, 100 14
Virtex-II Pro 125 16
Virtex-4 LX 10
Virtex-4 SX 10
Virtex-4 FX 12, 20 10
Virtex-4 FX 40, 60, 100, 140 14
Virtex-5 LX 10
XCR3000XL 5
XCR3000A / XCR3128 4
XCR3320 / XCR3960 5
XCR5128 / XCR5032C / XCR5064C / XCR5128C 4
CoolRunner-II 8
Platform Flash XCFxxS 8
Platform Flash XCFxxP 16
non_mm_ports.('adc1_d') = ('in',14);
Direction
Note: A subsystem (as shown below) is a convenient place to store the gateway out and convert
block pairs.
Plugins Directory
The System Generator software provides a special directory in which the board support
package files for new compilation targets can be added. This directory,
plugins/compilation, provides a repository for System Generator compilation target
plugins, and has unique properties that are discussed later in this topic. Your System
Generator software tree should resemble the tree hierarchy shown below.
The board support package files for you platform should be saved in a subdirectory, or
series of subdirectories, under the plugins/compilation directory.
Note: All configuration files associated with a board support package must be saved in the same
directory.
System Generator searches this directory (and subdirectories) for compilation targets.
Recall that the xltarget.m file tells System Generator the platform should be used as a
compilation target. When the tool searches the plugins/compilation directory, it adds
a compilation target to the System Generator block dialog box for every xltarget.m file
that it encounters.
The System Generator block dialog box Compilation submenus mirror the directory
structure under the plugins/compilation directory. When you create a new directory,
or directory hierarchy, for a board support package, the names of the directories define the
taxonomy of the compilation target submenus.
Chapter 4
HDL Co-Simulation
Configuring the HDL Simulator Explains how to configure ISE or ModelSim to co-
simulate the HDL in the Black Box block.
Co-Simulating Multiple Black Describes how to co-simulate several Black Box blocks
Boxes in a single HDL simulator session.
Black Box Tutorial Example 1: Describes an approach that uses the System Generator
Importing a Core Generator Black Box Configuration Wizard.
Module that Satisfies Black Box
HDL Requirements
Black Box Tutorial Example 2: Describes an approach that requires that you to
Importing a Core Generator provide a VHDL core wrapper. Simulation issues are
Module that Needs a VHDL also addressed.
Wrapper to Satisfy Black Box
HDL Requirements
Black Box Tutorial Example 3: Describes how to use the Black Box block to import
Importing a VHDL Module VHDL into a System Generator design and how to use
ModelSim to co-simulate.
Black Box Tutorial Example 4: Demonstrates how Verilog black boxes can be used in
Importing a Verilog Module System Generator and co-simulated using ModelSim.
Black Box Tutorial Example 5: Demonstrates dynamic black boxes using a transpose
Dynamic Black Boxes FIR filter black box that dynamically adjusts to
changes in the widths of its inputs.
Black Box Tutorial Example 6: Demonstrates how several System Generator Black
Simulating Several Black Boxes Box Blocks can be co-simulated simultaneously, using
Simultaneously only one ModelSim license while doing so.
Black Box Tutorial Exercise 7: Describes how to design a Black Box block with a
Advanced Black Box Example dynamic port interface and how to configure a black
Using ModelSim box using mask parameters. Also, describes how to
assign generic values based on input port data types
and how to save black box blocks in Simulink libraries
for later reuse. How to specify custom scripts for
ModelSim HDL co-simulation is also covered.
After searching the model's directory for .vhd and .v files, the Configuration Wizard
opens a new window that lists the possible files that can be imported. An example
screenshot is shown below:
You can select the file you would like to import by selecting the file, and then pressing the
Open button. At this point, the configuration wizard generates a configuration M-function
and associates it with the black box block.
Note: The configuration M-function is saved in the model's directory as <module>_config.m,
where <module> is the name of the module that you are importing.
function sample_block_config(this_block)
A SysgenBlockDescriptor object provides methods for specifying information about the
black box. Ports on a block descriptor are defined separately using port descriptors.
Language Selection
The black box can import VHDL and Verilog modules. SysgenBlockDescriptor provides a
method, setTopLevelLanguage, that tells the black box what type of module you are
importing. This method should be invoked once in the configuration M-function. The
following code shows how to select between the VHDL and Verilog languages.
VHDL Module:
this_block.setTopLevelLanguage('VHDL');
Verilog Module:
this_block.setTopLevelLanguage('Verilog');
Note: The Configuration Wizard automatically selects the appropriate language when it generates
a configuration M-function.
Note: The Configuration Wizard automatically sets the name of the top-level entity when it
generates a configuration M-function.
dout.setType('Ufix_12_8');
The first code segment sets the port attributes using individual method calls. The second
code segment defines the signal type by specifying the signal type as a string. Both code
segments are functionally equivalent.
The black box supports HDL modules with 1-bit ports that are declared using either single
bit port (e.g., std_logic) or vectors (e.g., std_logic_vector(0 downto 0)) notation. By default,
System Generator assumes ports to be declared as vectors. You may change the default
behavior using the useHDLVector method of the descriptor. Setting this method to true
tells System Generator to interpret the port as a vector. A false value tells System
Generator to interpret the port as single bit.
dout.useHDLVector(true); % std_logic_vector
dout.useHDLVector(false); % std_logic
Note: The Configuration Wizard automatically sets the port types when it generates a configuration
M-function.
port sample period and the Simulink system clock period defined by the System Generator block
dialog box.
Assume you have a model in which the Simulink system period value for the model is
defined as 2 sec. Also assume, the example dout port is assigned a rate of 3 by invoking
the setRate method as follows:
dout.setRate(3);
A rate of 3 means that a new sample is generated on the dout port every 3 Simulink system
periods. Since the Simulink system period is 2 sec, this means the Simulink sample rate of
the port is 3 x 2 = 6 sec.
Note: If your port is a non-sampled constant, you may define it as so in the configuration M-function
using the setConstant method of SysgenPortDescriptor. You can also define a constant by passing
Inf to the setRate method.
and clock enables must be defined as a pair, and exist as a pair in the imported module.
This is true for both single rate and multirate designs.
Note: Although clock and clock enables must exist as pairs, System Generator drives all clock ports
on your imported module with the FPGA system clock. The clock enable ports are driven by clock
enable signals derived from the FPGA system clock.
SysgenBlockDescriptor provides a method, addClkCEPair, which allows you to define
clock and clock enable information for a black box. This method accepts three parameters.
The first parameter defines the name of the clock port (as it appears in the module). The
second parameter defines the name of the clock enable port (also as it appears in the
module).
The port names of a clock and clock enable pair must follow the naming conventions
provided below:
• The clock port must contain the substring clk
• The clock enable must contain the substring ce
• The strings containing the substrings clk and ce must be the same (e.g., my_clk_1
and my_ce_1).
The third parameter defines the rate relationship between the clock and the clock enable
port. The rate parameter should not be thought of as a Simulink sample rate. Instead, this
parameter tells System Generator the relationship between the clock sample period, and
the desired clock enable sample period. The rate parameter is an integer value that defines
the ratio between the clock rate and the corresponding clock enable rate.
For example, assume you have a clock enable port named ce_3 that would like to have a
period three times larger than the system clock period. The following function call
establishes this clock enable port:
addClkCEPair('clk_3','ce_3',3);
When System Generator compiles a black box into hardware, it produces the appropriate
clock enable signals for your module, and automatically wires them up to the appropriate
clock enable ports.
Combinational Paths
If the module you are importing has at least one combinational path (i.e., a change on any
input can effect an output port without a clock event), you must indicate this in the
configuration M-function. SysgenBlockDescriptor object provides a
tagAsCombinational method that indicates your module has a combinational path. It
should be invoked as follows in the configuration M-function:
this_block.tagAsCombinational;
addGeneric('dout_width','Integer','12');
It is also possible to set generic values based on port on propagated input port information
(e.g., a generic specifying the width of a dynamic output port).
Because a black box's configuration M-function is invoked at several different times when
a model is compiled, the configuration function may be invoked before the data types (or
rates) have been propagated to the black box. If you are setting generic values based on
input port types or rates, the addGeneric calls should be nested inside a conditional
statement that checks the value of the inputTypesKnown or inputRatesKnown
variables. For example, the width of the dout port can be set based on the value of din as
follows:
if (this_block.inputTypesKnown)
% set generics that depend on input port types
this_block.addGeneric('dout_width', ...
this_block.port('din').width);
end
Generic values can be configured based on mask parameters associated with a block box.
SysgenBlockDescriptor provides a member variable, blockName, which is a string
representation of the black box's name in Simulink. You may use this variable to gain
access the black box associated with the particular configuration M-function. For example,
assume a black box defines a parameter named init_value. A generic with name
init_value can be set as follows:
simulink_block = this_block.blockName;
init_value = get_param(simulink_block,'init_value');
this_block.addGeneric('init_value', 'String', init_value);
Note: You can add your own parameters (e.g., values that specify generic values) to the black box
by doing the following:
• Copy a black box into a Simulink library or model;
• Break the link on the black box;
• Add the desired parameters to the black box dialog box.
Error Checking
It is often necessary to perform error checking on the port types, rates, and mask
parameters of a black box. SysgenBlockDescriptor provides a method, setError, which
allows you to specify an error message that is reported to the user. The string parameter
passed to setError is the error message that is seen by user.
SysgenBlockDescriptor Methods
Method Description
setTopLevelLanguage(language) Declares language for the top-level entity (or
module) of the black box. language should be
'VHDL' or 'Verilog'.
setEntityName(name) Sets name of the entity or module.
addSimulinkInport(pname) Adds an input port to the black box. pname tells the
name the port should have.
addSimulinkOutport(pname) Adds an output port to the black box. pname tells
the name the port should have.
setSimulinkPorts(in,out) Adds input and output ports to the black box. in
(respectively, out) is a cell array whose element tell
the names to use for the input (resp., output) ports.
addInoutport(pname) Adds a bi-directional port to the black box. pname
spcefies the name the port should have. Bi-
directional ports can only be added during the
'config_netlist_interface' phase of configuration.
tagAsCombinational() Indicate that the block has a combinational path (i.e.,
direct feedthrough) from an input port to an output
port.
addClkCEPair(clkPname, cePname, Defines a clock/clock enable port pair for the block.
rate) clkPname and cePname tell the names for the clock
and clock enable ports respectively. rate, a double,
tells the rate at which the port pair runs. The rate
must be a positive integer. Note the clock
(respectively, clock enable) name must contain the
substring clk (resp., ce). The names must be parallel
in the sense that the clock enable name is obtained
from the clock name by replacing clk with ce.
port(name) Returns the SysgenPortDescriptor that describes a
given input port. indx tells the index of the port to
look for, and should be between 1 and
numInputPorts.
inport(indx) Returns the SysgenPortDescriptor that describes a
given input port. indx tells the index of the port to
look for, and should be between 1 and
numInputPorts.
outport(indx) Returns the SysgenPortDescriptor that describes a
given output port. indx tells the index of the port to
look for, and should be between 1 and
numOutputPorts.
Method Description
addGeneric(identifier, value) Defines a generic (or parameter if using Verilog) for
the block. identifier is a string that tells the name of
the generic. value can be a double or a string. The
type of the generic is inferred from value's type. If
value is an integral double, e.g., 4.0, the type of the
generic is set to integer. For a non-integral double,
the type is set to real. When value is a string
containing only zeros and ones, e.g., `0101', the type
is set to bit_vector. For any other string value the
type is set to string.
addGeneric(identifier, type, value) Explicitly specifies the name, type, and value for a
generic (or parameter if using Verilog) for the block.
All three arguments are strings. identifier tells the
name, type tells the type, and value tells the value.
addFile(fn) Adds a file name to the list of files associated to this
black box. fn is the file name. Ordinarily, HDL files
are associated to black boxes, but any sorts of files
are acceptable. VHDL (respectively, Verilog) file
names should end in .vhd (resp., .v). The order in
which file names are added is preserved, and
becomes the order in which HDL files are compiled.
File names can be absolute or relative. Relative file
names are interpreted with respect to the location of
the .mdl or library .mdl for the design.
SysgenPortDescriptor Methods
Method Description
HDL Co-Simulation
Method Description
setConstant() Makes this port constant
setGatewayFileName(filename) Sets the dat file name that will be used in simulations
and test-bench generation for this port. This function
is only meant for use with bi-directional ports so that
a hand written data file can be used during
simulation. Setting this parameter for input or
output ports is invalid and will be ignored.
setRate(rate) Assigns the rate for this port. rate must be a positive
integer expressed as a MATLAB double or Inf for
constants.
useHDLVector(s) Tells whether a 1-bit port is represented as single-bit
(ex: std_logic) or vector (ex: std_logic_vector(0
downto 0)).
HDLTypeIsVector() Sets representation of the 1-bit port to
std_logic_vector(0 downto 0).
HDL Co-Simulation
Introduction
This topic describes how a mixed language/mixed flow design that includes Xilinx blocks,
HDL modules, and a Simulink block diagram can be simulated in its entirety.
System Generator simulates black boxes by automatically launching an HDL simulator,
generating additional HDL as needed (analogous to an HDL testbench), compiling HDL,
scheduling simulation events, and handling the exchange of data between the Simulink
and the HDL simulator. This is called HDL co-simulation.
ISE Simulator
To use the ISE Simulator for co-simulating the HDL associated with the black box, select
ISE Simulator as the option for the Simulation mode parameter on the black box as shown
in the following figure. The model is then ready to be simulated and the HDL co-
simulation takes place automatically.
ModelSim Simulator
To use the ModelSim simulator by Model Technology, Inc., you must first add the
ModelSim block that appears in the Tools library of the Xilinx Blockset to your Simulink
diagram.
For each black box that you wish to have co-simulated using ModelSim simulator, you
need to open its block parameterization dialog and set it to use the ModelSim session
represented by the black box that was just added. You do this by making the following two
settings:
HDL Co-Simulation
The block parameter dialog for the ModelSim block includes some parameters that you
can use to control various options for the ModelSim session. See the Modelsim block help
pages for details. The model is then ready to be simulated with these options, and the HDL
co-simulation takes place automatically.
Black Box Tutorial Example 1: Describes an approach that uses the System Generator
Importing a Core Generator Black Box Configuration Wizard.
Module that Satisfies Black Box
HDL Requirements
Black Box Tutorial Example 2: Describes an approach that requires that you to
Importing a Core Generator provide a VHDL core wrapper. Simulation issues are
Module that Needs a VHDL also addressed.
Wrapper to Satisfy Black Box
HDL Requirements
Black Box Tutorial Example 3: Describes how to use the Black Box block to import
Importing a VHDL Module VHDL into a System Generator design and how to use
ModelSim to co-simulate.
Black Box Tutorial Example 4: Demonstrates how Verilog black boxes can be used in
Importing a Verilog Module System Generator and co-simulated using ModelSim.
Black Box Tutorial Example 5: Demonstrates dynamic black boxes using a transpose
Dynamic Black Boxes FIR filter black box that dynamically adjusts to
changes in the widths of its inputs.
Black Box Tutorial Example 6: Demonstrates how several System Generator Black
Simulating Several Black Boxes Box Blocks can be co-simulated simultaneously, using
Simultaneously only one ModelSim license while doing so.
Black Box Tutorial Exercise 7: Describes how to design a Black Box block with a
Advanced Black Box Example dynamic port interface and how to configure a black
Using ModelSim box using mask parameters. Also, describes how to
assign generic values based on input port data types
and how to save black box blocks in Simulink libraries
for later reuse. How to specify custom scripts for
ModelSim HDL co-simulation is also covered.
write a VHDL wrapper to import CORE generator modules as black boxes. The flow graph
below illustrates the process of importing CORE generator modules.
2. Double click the CORDIC 3.0 icon to launch the customization GUI
3. Parameterize and generate the CORDIC 3.0 core with component name
cordic_sincos, a functional Selection of Sin and Cos and the remaining options set
to be the default values as shown below:
4. Click Generate. Core Generator produces the following files after generation:
♦ cordic_sincos.edn: Implementation netlist
♦ cordic_sincos.vhd: VHDL wrapper for behavioral simulation
♦ cordic_sincos.vho: Core instantiation template
♦ cordic_sincos.xco: Parameters selected for core generation
7. Connect the input and output ports of the black box to the open wires.
8. Open the cordic_sincos_config.m file, and add the EDIF netlist to the black box
file list as shown below. This file will get included as part of the System Generator
netlist for the design when it is netlisted.
9. Open the black box parameterization GUI and select ISE Simulator for the simulation
mode.
10. Press the Simulate button to compile and co-simulate the CORDIC core using the ISE
simulator. The simulation results are as shown below.
3. Customize and generate the MAC FIR Filter 5.1 core with the following parameters:
♦ Component Name: mac_fir_8tap
♦ Number of Taps: 8
♦ Impulse Response: Symmetric
♦ Load Coefficients: mac_fir_8tap.coe file located in sysgen directory
♦ System Clock Rate: 100 Mhz, Input rate: 25 Mhz
♦ Copy the port declaration for the component mac_fir_8tap and paste it for the
mac_fir_8tap entity declaration
(after ---- Add Port declaration for entity ----)
♦ Add the ce port to the top-level entity declaration, and change the case of the CLK
port to clk.
9. Drag and drop the black box from the "Basic Elements" library in the
coregen_import_example2.mdl. Select mac_fir_8tap_wrapper.vhd for the
top-level HDL file.
Note: The order in which the files are added in the configuration function is the order in which they
get compiled during synthesis and simulation.
12. Open the black box parameterization GUI and select the ISE Simulator for simulation
mode.
13. Press the Simulate button to compile and co-simulate the FIR core using the ISE
simulator. The simulation results are as shown below.
♦ transpose_fir.vhd - Top-level VHDL for a transpose form FIR filter. This file
is the VHDL that is associated with the black box.
♦ mac.vhd – Multiply and add component used to build the transpose FIR filter.
2. Open the black_box_intro model from the MATLAB command window by
typing
>> black_box_intro
3. Open the subsystem named Transpose FIR Filter Black Box. At this point, the
subsystem contains two inports and one outport. The black box subsystem is shown
below:
4. Go to the Simulink Library Browser and add a black box block to this subsystem. The
black box is located in the Xilinx Blockset's Basic Elements library. The Black Box
Configuration Wizard is automatically invoked when a new black box is added to the
subsystem. A browser window appears that lists the VHDL source files that can be
associated with the black box. From this window, select the top -level VHDL file
transpose_fir.vhd. This is illustrated in the figure below:
Note: The wizard will only run if the black box is added to a model that has been saved to a file. If
the model has not been saved, the wizard does not know where to search for files and System
Generator will instead display a warning that looks like the following:
5. The wizard parses the VHDL to generate a configuration M-function for the black box.
This is a MATLAB script that, among other things, associates the black box to the
VHDL and creates black box ports. Once the function has run, the ports on the black
box match those in the top-level VHDL entity (not including clock and clock enable
ports). This is illustrated below:
9. Go to the Simulink Library Browser and add a ModelSim block to this subsystem. The
ModelSim block is located in the Xilinx Blockset /Tools library. This block enables the
black box to communicate with a ModelSim simulator. Double click on the ModelSim
block to open the dialog box shown below:
10. Make sure the parameters match those shown in the preceding figure. Close the dialog
box.
11. From the Simulink menu, select Port Data Types from the Format menu to display the
port types for the black box. Compile the model (Ctrl-d) to ensure the port data types
are up to date. Notice that the black box port output type is UFix_26_0. This means it
is unsigned, 26 bits wide and has a binary point 0 positions to the left of the least
significant bit.
12. Open the configuration M-function transpose_fir_config.m and change the
output type from UFix_26_0 to Fix_26_12. The modified line should read:
dout_port.setType('Fix_26_12');
13. Edit the configuration M-function to associate an additional HDL file with the black
box. Locate the line:
this_block.addFile('transpose_fir.vhd');
Immediately above this line, add the following:
this_block.addFile('mac.vhd');
14. Save the changes to the configuration M-function and recompile the model (Ctrl-d).
Your subsystem should appear as follows:
15. From the black box block parameter dialog box, change the Simulation mode field
from Inactive to External co-simulator. Enter ModelSim in the HDL co-simulator to
use field. The name in this field corresponds to the name of the ModelSim block that
you added to the model. The black box dialog box should appear as follows:
Note: Note: Only ModelSim XE and SE simulators are supported by System Generator.
16. Run the simulation. A ModelSim command window and waveform viewer opens.
ModelSim simulates the VHDL while Simulink controls the overall simulation. The
resulting waveform looks something like the following:
They are caused by the black box VHDL not specifying initial values at the start of
simulation.
17. Examine the scope output after the simulation has completed. When the Simulation
Mode was set to Inactive, the Output Signal scope displayed constant zero. Notice the
waveform is no longer zero. Instead, Output Signal shows the results from the
ModelSim simulation.
This is a simple design with two black boxes, one VHDL and the other Verilog. The
VHDL black box computes the parity of each input word, and the Verilog black box
latches the words that have odd parity. No Simulink model is used to compute the
behavior of the black boxes; instead, HDL co-simulation is used. The example model is
shown in the figure below.
You must have a license for mixed-mode ModelSim simulation to run this example. If
you do and you run the simulation, you will see a ModelSim waveform window that
looks like the one captured below. The behavior of both black boxes is shown. You can
browse the design structure in ModelSim to see how System Generator has combined
the two black boxes.
2. Change the input type to an arbitrary type and rerun the simulation. Both black boxes
adjust in the appropriate way to the change.
3. Reduce the number of bits on the gateway Din Gateway In from 16 bits down to 12
and the binary point from 14 to 10, then run the simulation again. Note that both the
input and output widths on the black box adjust automatically. The black box
subsystem and simulation results should look like those shown below.
4. The black box is able to adjust to changes in input width because of its configuration
M-function. To make this work, the M-function must be augmented by hand. Open the
M-function file transpose_fir_parametric.m. The important points are described
below.
• Obtaining data input width:
input_bitwidth = this_block.port('din').width;
• Calculating output width:
output_bitwidth = ceil(log2(2^(input_bitwidth-1)*2^(coef_bitwidth-1) *
number_of_coef));
• Setting output data type:
dout_port.makeSigned;
dout_port.width = output_bitwidth;
dout_port.binpt = 12;
• Passing input and output bit widths to VHDL as generics:
this_block.addGeneric('input_bitwidth',this_block.port('din').width);
this_block.addGeneric('output_bitwidth',output_bitwidth);
For details concerning the black box configuration M-function, seethe topic Black Box
Configuration M-Function.
If you examine the black box VHDL file transpose_fir_parametric.vhd you see generics
input_bitwidth and output_bitwidth that specify input and output width. These
are passed to lower-level VHDL components.
• parity_block.vhd: VHDL for a simple state machine that tracks the running
parity of an 8-bit input word.
• parity_block_config.m: The configuration M-function for the black boxes. The
code has barely been changed from what was produced by the Configuration Wizard:
the line that tagged the block as having a combinational feed-through path
(this_block.tagAsCombinational) has been removed.
the connection between the black boxes and ModelSim. The example model is shown in
the figure below.
If you run the simulation, you will see a Simulink scope and ModelSim waveform window
that look like the figures below. The scope shows that the black boxes produce matching
parity results (as expected), but with one delayed from the other by one clock cycle. The
waveform window shows the same results, but viewed in ModelSim and expressed in
binary. System Generator automatically configures the waveform viewer to display the
input and output signals of each black box. You can also browse the design structure in
ModelSim to see how System Generator has elaborated the design to combine the two
black boxes.
signal is represented in two ways in the ModelSim viewer – binary and analog. The
ModelSim waveforms for the black_box_ex5 simulation are shown below.
3. Double click on the Simulink scope in the model. The output is shown below and
resembles the analog signal in the ModelSim waveform viewer.
The black box in this example is configured using mask parameters. There are many
situations in which this is useful. In this case, the number of black box input ports, i.e.,
the number of scope inputs, is determined by a mask parameter.
4. Double click on the waveform scope black box. Notice a Number of Input Ports field is
included in the block dialog box and is unique to this black box instance. The dialog
box is shown below:
5. Change the number of input ports from 3 to 4 and apply the changes. The black box
now has an additional input port labeled sig4 and should look like the following:
Every black box has a standard list of mask parameters. The black box in this example
has an additional mask parameter nports that stores the number of input ports
selected by the user. To change a black box mask it is necessary to disable the link to the
library. When a black box is changed in this way, it is best to save the black box in a
library. (See the Simulink documentation on libraries for details.) The tutorial library
scope_lib.mdl contains the modified signal scope black box used in this example.
When a black box configuration M-function adds an HDL file, the path to the file can
be relative to the directory in which the library is saved. This eliminates the need to
copy the HDL into the same directory as the model.
The black box's configuration M-function is invoked whenever the block parameter
dialog box is modified. This allows the M-function to check the mask parameters and
configure the black box accordingly. In this example, the M-function adjusts the
number of block input ports based on the nports parameter specified in the mask.
6. Open the file scope_config.m that defines the configuration M-function for the
example black box. Locate the line:
simulink_block = this_block.blockName;
This obtains the Simulink name of the black box and assigns it to the variable
simulink_block. The name is useful because it is the handle that MATLAB
functions need to manipulate the block.
7. Locate the line:
nports = eval(get_param(simulink_block,'nports'));
The value of the nports mask parameter is obtained by the get_param command.
The get_param returns a string containing the number of ports. An eval encloses the
get_param and converts the string into an integer that is assigned to the nports
variable.
8. Once the number of input ports is determined, the M-function adds the input ports to
the black box. The code that does this is shown below.
for i=1:nports
this_block.addSimulinkInport(sprintf('sig%d',i));
end
There are four VHDL files, named scope1.vhd, scope2.vhd, scope3.vhd, and
scope4.vhd, which the black box in this example can use. The black box associates
itself to the one that declares an appropriate number of ports.
9. The configuration M-function selects the appropriate VHDL file for the black box.
Locate the following line in scope_config.m:
entityName = sprintf('scope%d',nports);
The HDL entity name for the black box is constructed by appending the value of
nports to scope. The VHDL is associated with the black box in the following line:
this_block.addFile(['vhdl/' entityName '.vhd']);
10. The input port widths for each VHDL entity are assigned using generics. The generic
name identifies the input port to which the width is assigned. For example, the width3
generic specifies the width of the third input. In scope_config.m, the generic names
and values are set as follows:
% -----------------------------
if (this_block.inputTypesKnown)
for i=1:nports
width = this_block.inport(i).width;
this_block.addGeneric(sprintf('width%d',i),width);
end
end % if(inputTypesKnown)
% -----------------------------
11. You can change the way ModelSim displays the signal waveforms during simulation
by using custom tcl scripts in the ModelSim block. Double click on the ModelSim block
in the black_box_ex5 model. The following dialog box appears:
Custom scripts are defined by selecting the Add Custom Scripts checkbox. In this
case, a script named waveform.do is specified in the Script to Run after vsim field.
This script contains the ModelSim commands necessary to display the adder output as
an analog waveform.
Chapter 5
HDL Netlist Compilation System Generator uses the HDL Netlist compilation
type as the default generation target. More details
regarding the HDL Netlist compilation flow can be
found in the topic Compilation Results.
NGC Netlist Compilation Describes how System Generator can be configured to
compile your design into a standalone NGC file.
Bitstream Compilation Describes how System Generator can be configured to
compile your design into an FPGA configuration
bitstream.
EDK Export Tool Describes how System Generator can be configured to
compile your design into an FPGA configuration
bitstream that is appropriate for the selected part.
Hardware Co-Simulation Describes how System Generator can be configured to
Compilation compile your design into FPGA hardware that can be
used by Simulink and ModelSim.
Timing Analysis Compilation Describes how to use the System Generator Timing
Analysis tool compilation target.
Creating Compilation Targets Describes how to add custom compilation targets to
the System Generator block.
Bitstream Compilation
3. Combines synthesis results, core netlists, black box netlists, and optionally the
constraints files into a single NGC file.
As shown below, you may select the NGC compilation target by left-clicking the
Compilation submenu control on the System Generator block dialog box, and selecting the
NGC Netlist target.
You may access additional compilation settings specific to NGC Netlist compilation by
clicking on the Settings... button when NGC Netlist is selected as the compilation type in
the System Generator block dialog box. Parameters specific to the NGC Netlist Settings
dialog box include:
• Include Clock Wrapper: Selecting this checkbox tells System Generator whether the
clock wrapper portion of your design should be included in the NGC netlist file. Refer
to the topic Compilation Results for more information on the clock wrapper.
Note: If you exclude the clock wrapper from multirate designs, you will need to drive the clock
enable ports with appropriate signals from your own top-level design.
• Include Constraints File: Selecting this checkbox tells System Generator whether the
constraints file associated with the design should be included in the NGC netlist file.
Note: When the constraints file is excluded, you should supply your own constraints to ensure
the multi-cycle paths in the System Generator design are appropriately constrained.
Bitstream Compilation
The Bitstream compilation type allows you to compile your design into a Xilinx
configuration bitstream file that is suitable for the FPGA part that is selected in the System
Generator dialog box. The bitstream file is named <design>_cw.bit and is placed in the
design's target directory, where <design> is derived from the portion of the design being
compiled.
System Generator produces the bitstream file by performing the following steps during
compilation:
1. Generates an HDL netlist for the design;
2. Runs the selected synthesis tool to produce a lower-level netlist. The type of netlist
(e.g., EDIF for Synplify Pro, NGC for XST) depends on which synthesis tool is chosen
for compilation.
3. Runs XFLOW to produce a configuration bitstream.
As shown below, you may select the Bitstream compilation by left-clicking the
Compilation submenu control on the System Generator block dialog box, and selecting the
Bitstream target.
System Generator uses XFLOW to run the tools necessary to produce the configuration
bitstream. Execution of XFLOW is broken into two flows, implementation and configuration.
The implementation flow is responsible for compiling the synthesis tool netlist output
(e.g., EDIF or NGC) into a placed and routed NCD file. In summary, the implementation
flow performs the following tasks:
1. Combines synthesis results, core netlists, black box netlists, and constraints files using
NGDBuild.
2. Runs MAP, PAR, and Trace on the design (in that particular order).
The configuration flow type runs the tools (e.g., BitGen) necessary to create an FPGA BIT
file, using the fully elaborated NCD file as input.
Bitstream Compilation
Additional Settings
You may access additional compilation settings specific to Bitstream compilation by
clicking on the Settings... button when Bitstream is selected as the compilation type in the
System Generator block dialog box. Parameters specific to the Bitstream Settings dialog
box include:
• Import Top-level Netlist: Allows you to specify your own top-level netlist into which
the System Generator portion of the design is included as a module. You may choose
to import your own top-level netlist if you have a larger design that instantiates the
System Generator clock wrapper level as a component. Refer to the Compilation
Results topic for more information on the clock wrapper level. This top-level netlist is
included in the bitstream file that is generated during compilation. Selecting this
checkbox enables the edit fields Top-level Netlist File (EDIF or NGC) and Search Path
for Additional Netlist and Constraint Files.
♦ Top-level Netlist File (EDIF or NGC): Specifies the name and location of the top-
level netlist file to include during compilation. Note that any HDL components
that are used by your top-level (including the top-level itself) must have been
previously synthesized into netlist files.
♦ Search Path for Additional Netlist and Constraint Files: Specifies the directory
where System Generator should look for additional netlist and constraint files
that go along with the top-level netlist file. System Generator copies all netlist
(e.g., .edn, .edf, .ngc) and constraints files (e.g., .ucf, .xcf, .ncf) into the
implementation directory when this directory is specified. If you do not specify a
directory, System Generator will only copy the netlist file specified in the Top-
level Netlist File field.
• Specify Alternate Clock Wrapper: Allows you to substitute your own clock wrapper
logic in place of the clock wrapper HDL System Generator produces. The clock
wrapper level is the top-level HDL file that is created for a System Generator design,
and is responsible for driving the clock and clock enable signals in that design.
Sometimes you may want to supply your own clock wrapper, for example, if your
design uses multiple clock signals, or if you have a board-specific hardware you
would like your design to interface to.
Note: The name of the alternate clock wrapper file must be named <design>_cw.vhd or
<design>_cw.v or it will not be used during bitstream generation.
• XFLOW Option Files: When a design is compiled for System Generator hardware co-
simulation, the command line tool, XFLOW, is used to implement and configure your
design for the selected FPGA platform. XFLOW defines various flows that determine
the sequence of programs that should be run on your design during compilation.
There are typically multiple flows that must be run in order to achieve the desired
output results, which in the case of hardware co-simulation targets, is a configuration
bitstream.
♦ Implementation Phase (NBDBuild, MAP, PAR, TRACE): Specifies the options
file that is used by the implement flow type. By default, System Generator will
use the implement options file that is specified by the compilation target.
♦ Configuration Phase (BitGen): Specifies the options file that is used by the
configuration flow type. By default, System Generator will use the configuration
options file that is specified by the compilation target.
where
xmp_file is the pathname to the imported EDK project file
bit_file is the pathname to the Sysgen bitstream file
bmm_file is the pathname of the back-annotated BMM file produced by Sysgen during bitstream
compilation
Clicking on the Settings… button brings up the EDK export settings dialog.
Pcore options allow you to do the following:
• Assign a version number to your pcore
• Select Pcore under development
This feature works for both FSL- and PLB-based pcore export. When a pcore is marked
as Pcore under development, XPS will not cache the HDL produced for this pcore.
This is useful when you are developing pcores in System Generator and testing them
out in XPS. You can just enable this checkbox, make changes in System Generator and
compiled in XPS. XPS always compiles the generated pcore, so you don’t have to
empty the XPS cache which may contain caches of other peripherals, thus slowing
down the compile of the final bitstream.
• Select Enable custom bus interfaces
This feature works for both FSL- and PLB-based pcore export and allows you to create
custom bus interfaces that will be understood in XPS.
2. Select 3. Click
1. Double Click
4. Select
5. Click
6. Enter Data
You follow the sequence in the figure above to bring up the Bus Interface dialog box. In
this dialog box, you define a new Bus Interface called vid_out that is marked as a
myVideoBus Bus Standard and is Bus Type INITIATOR. (Other supported Bus Types
include: Target, Master, Slave, Master-slave, Monitor.) Next, in the Port-Bus Mapping
table, you list all the gateways that you want in the bus, then give each a Bus Interface
Name. You then Netlist the design as a pcore. Remember that you marked this pcore bus as
INITIATOR since it contains outputs.
In another model (shown below), you create corresponding input gateways. You set this
up as a TARGET bus giving the bus interface the same Bus Standard myVideoBus. XPS
will use the Bus Standard name to match different bus interfaces. XPS will then connect the
outputs to the inputs with the same Bus Interface Names.
You export this pcore to the XPS project. When these two pcores are used in the same XPS
project, XPS will detect that they have compatible buses and will allow you to connect
them if you wish.
The following table shows subdirectory structure of the pcore that is generated by System
Generator:
pcore
Description
Subdirectory
data The data directory contains four files: BBD, PAO, MPD and
TCL.
• The BBD (black-box definition) file tells the EDK what EDN
or NGC files are used in the design.
• The PAO (peripheral analyze order) file tells the EDK the
analyze order of the HDL files.
• The MPD (Microprocessor Peripheral Description) file tells
the EDK how the peripheral will connect to the processor.
• The TCL file is used by LibGen when elaborating software
drivers for this peripheral.
doc Documentation files in HTML format.
hdl The hdl directory contains the hdl files produced by System
Generator.
netlist The netlist directory contains the EDN and NGC files listed by
the BBD file
src Source files for the software drivers.
See Also:
EDK Processor
After filling out the dialog box, click the Generate button and System Generator will
perform the following steps:
1. The design is compiled using Simulink.
2. The design is netlisted by System Generator into HDL source.
3. The HDL Synthesis Tool is called to turn the HDL into an EDIF (Synplify/Synplify
Pro) or NGC (XST) netlist.
4. NGD Build is called to turn the netlist into an NGD netlist file.
5. The ISE Mapper software is called to map elements of logic together into slices; this
creates an NCD file.
6. The ISE Place & Route software is called to place the slices and other elements on the
Xilinx die and to route the connections between the slices. This creates another NCD
file.
7. The ISE Trace software is called to analyze the NCD and to find the paths with the
worst slack. This creates a trace report.
8. The System Generator Timing Analyzer tool appears, displaying the data from the
trace report.
Note: If timing data is generated using this method and you wish to view it again at a later time, then
enter the following command at the MATLAB command line:
>>xlTimingAnalysis('timing')
where 'timing' is the name of the target directory in which a prior analysis was carried out.
The path shown is from the Q output of the register on the left (register3) to the D input of
the register on the right (parity_reg). The path goes through two LUTs (lookup tables) that
are configured as 4-input XOR gates. This path has two levels of logic. That means that it
goes through two separate combinational elements (the two LUTs).
The requested period for this path is 10ns. This path easily meets timing. The second of the
two red comma-separated numbers above each logic elements shows the slack for the path.
The slack is the amount of time by which the path 'meets timing'. In this case the slack is
7.79ns. That means that the path could be 7.79ns slower and still meet the 10ns period
requirement. A negative slack value indicates that the path does not meet timing and has
a setup (or hold) time violation.
The top section of the display shows a list of slow paths, while the bottom section of the
display shows details of the path that is selected. The elements of this display are explained
here:
• Timing Constraint: You may opt to view the paths from all timing constraints or just a
single constraint. A typical System Generator design has but a single timing
constraint which defines the period of the system clock. This is the constraint shown
in this example. TS_clk_a5c9593d is the name of the constraint; the (sometimes
confusing) suffix is a hash meant to make the identifier unique when multiple System
Generator designs are used as components inside a larger design. The timing group
clk_a5c9593 is a group of synchronous logic, again with a hash suffix. The group in
this case contains all the synchronous elements in the design. The period of the clock
here is 10ns with a 50% duty cycle.
• Source: The System Generator block that drives the path.
• Destination: This is the System Generator block that is the terminus of the path.
• Slack: The slack for this particular path. See the topic entitled Period and Slack for
more details.
• Delay (Path): The delay of the entire path, including the setup time requirement.
• % Route Delay: This is the percentage of the path that is consumed by routing (net)
delay. The remainder portion of the path is consumed by logic delay.
• Levels of Logic: The number of levels of combinatorial logic in the path. The
combinatorial logic typically comprises LUTs, F5 muxes, and carry chain muxes.
• Path Element: This shows the logic and net elements in the highlighted path.
• Delay (Element): This shows the delay through the logic and net elements in the
highlighted path.
• Type of Delay: This is the kind of delay incurred by the given path element. These
values are defined in the Xilinx part's data sheet. In the example shown above, Tcko is
the clk-to-out time of a flip-flop; net is a net delay; Tilo is the delay through a LUT, and
Tas is the setup time of a flip-flop.
You may click on the column headings to reorder the paths or elements according to delay,
slack, path name, or other column headings. Failing paths are highlighted in red/pink.
Cross-Probing
Highlighting a path in the Slow Paths view will highlight the blocks in the path in the
System Generator diagram. The path's source and destination blocks, as well as
combinational blocks through which the path passes, will be highlighted in red. The
diagram below shows how the model appears when the path that has Registerc as its
source and parity_reg as its destination is highlighted. The blocks xor_1b, xor_2a, and
xor_3a are also highlighted because they are part of the path.
Histogram Charts
Clicking on the Charts icon displays a histogram of the slow paths. This histogram is a
useful metric in analyzing the design. You may know that the design will only run at, for
example, 99MHz in your part when you wish it to run at 100MHz. But how close is the
design to meeting timing and how much work is involved in meeting this requirement?
The histogram will quickly give you an estimate of the work involved. For example, look
at the histogram of the results of a simple design below:
This shows that most of the slow paths are concentrated about 1.5ns. The slowest path is
about 2.35ns. The numbers at the tops of the bins show the number of paths in each bin.
There is only one path in the bin which encompasses the time range 2.31ns-2.39ns. The bins
to the right of it are empty. This shows that the slowest path is an outlier and that if your
timing requirement were for a period of, for example, 2ns, you would need only to speed
up this single path to meet your timing requirements.
Histogram Detail
The slider bar allows you to adjust the width of the bins in the histogram. This allows you
to get more detail about the paths if desired. The display below shows the results of a
different design with a larger number of bins than the diagram above:
This diagram shows the paths grouped into three regions, with each forming a rough bell
curve distribution. These groups are probably from different portions of the circuit or from
different timing constraints that are from different clock regions. If you wish to analyze the
paths from a single timing constraint, you may select a single constraint for viewing from
the Timing constraint pulldown menu at the top of the display.
Note the bins and portions thereof shown in red. These are the paths that have negative
slack; i.e., they do not meet the timing constraint. In this example you can see that some
paths have failed but not by a large margin so it seems reasonable that with some work this
design could be reworked to meet timing.
Statistics
Clicking on the Statistics icon displays several design statistics, including the number of
constraints, paths analyzed, and maximum frequency of the design.
Trace Report
Clicking on the Trace icon shows the raw text report from the Trace program. This file gives
considerable detail about the paths analyzed. Each path analyzed contains information
about every net and logic delay, clock skew, and clock uncertainty. The box at the bottom
left of this display shows the path name of the timing report.
f. Using Hard Cores. Are you using a ROM that is implemented in distributed RAM
when it would operate much faster in a block memory hard core? Do you have a
wide adder that would benefit from being put in a DSP48 block, which can operate
at 500MHz? Take advantage of the embedded hard cores.
g. New Paradigms. Do you need to create a large delay? Instead of using a counter
with a long carry chain, why not build a delay out of cascaded Johnson rings using
SRL16s? Or how about using an LFSR? Neither requires a carry chain and can
operate much faster. Sometimes you have to rethink certain design elements
completely.
2. Eliminate overconstraints. Ensure that elements of your design that only need to be
operated at a subsampled rate are designed that way by using the downsample and
upsample blocks in System Generator. If these blocks are not used, then the timing
analyzer is not aware that these sections of the circuit are subsampled, and the design
is overconstrainted.
3. Change the constraints. Is it possible to run the design at a lower clock speed? If so,
this is an easy way to meet your requirements. Unfortunately, this is rarely possible
due to design requirements.
4. Increase PAR effort levels. The mapper and place & route tools (PAR) in ISE take
effort levels as arguments. When using ISE (from the Project Navigator GUI), try the –
timing option in MAP. You may also increase the PAR effort levels which will increase
the PAR execution time but may also result in a faster design.
5. Multipass PAR. PAR is an iterative process and is somewhat chaotic in that the initial
conditions can vastly influence the final result. PAR uses a seed value to determine the
initial conditions. This is referred to as the cost table value. You may change this value
in the Project Navigator by hand. Even better, you may perform a multipass PAR
process which runs PAR multiple times with different cost table values. This is time-
consuming but often effective.
6. Floorplanning. This step should be avoided if possible, but can yield huge
improvements. The automatic placer in PAR can be improved upon by human
intervention. Floorplanning places critical elements close to each other on the Xilinx
die, reducing net delays. The PACE and Floorplanner tools in ISE may be used for this.
A more advanced tool, PlanAhead, is also available separately from Xilinx to aid in
this task.
7. Use a faster part. This is often the first solution seized upon, but is also expensive. If
you are using an old Xilinx part, porting your design to a newer, faster Xilinx part may
often save money because the new parts may be cheaper on account of Moore's Law.
However, moving to a faster part in the same family incurs significant extra costs, and
often isn't necessary if the previous steps are followed.
The design has eight one-bit gateway inputs that are registered by one-bit registers. These
are processed by seven 2-input XOR blocks. These have a latency of zero and thus are
purely combinational. The final register, parity_reg, registers the final result (the parity)
which is connected to an output gateway. The design appears to have three levels of logic,
because each path fanning in to parity_reg goes through three XOR blocks.
There are two failing paths, normally highlighted in red/pink. (The top path is gray
because it is selected.) The negative slack values are shown in boldface. The worst of the
two fails by 96ps.
Note that there are two levels of logic in the path shown. How can this be? The System
Generator diagram shows three levels of logic in all paths. The reason is that the
implemented design does not correlate exactly to the System Generator diagram. In this
case, the synthesizer has compressed some of the 2-bit XOR blocks into 4-input LUTs and
created the 8-input XOR using only two levels of logic as shown in this Synplify Pro
schematic:
LUT4_6996
LUT2_L_6
registerh_q_net[0:0]
registerg_q_net[0:0]
registerf_q_net[0:0] xor_3a_y_net[0:0]
registere_q_net[0:0]
y_5[0] y[0]
LUT4_6996
registerd_q_net[0:0]
registerc_q_net[0:0]
registerb_q_net[0:0]
registera_q_net[0:0]
y_4[0]
Note how the net and block names have all been munged, requiring the magic un-
munging capabilities of the timing analyzer.
Also note the details of the selected path. The logic delays cannot be reduced. One of the
net delays is 813ps. This could possibly be reduced by means of floorplanning, multipass
PAR, or simply by increasing the PAR effort level.
This will add a register to the end of the XOR gate. We will change the latency on blocks
xor_2a and xor_2b. We know from examining the Synplify Pro schematic that the
outputs of these blocks form the output of the first level of logic in the synthesized design.
The modified System Generator looks very similar with the exception of the z-1 on the
labels of the two modified XOR blocks, indicating their new latency.
Excellent! No more failing paths! The design has been rescued, all in record time and
without using a more expensive part. Surely raises and promotions shall follow you for all
your days.
Note that all paths now have but a single level of logic. What exactly has happened here?
Let us examine the Synplify Pro schematic to see how the modified circuit was
synthesized:
xor_2b_f0fd230c1d
LUT4_L_6996 xor_3a_7e73f4292b
1.18,0.45
0.35,-0.06
LUT2_L_6 parity_reg_3123b0b42f
0.98,0.45
1.18,-0.06 1.43,-0.06
0.98,0.45 FD
1.18,0.45
0.98,0.45 1.18,0.45
D
Q 0.98,-0.06 FD
1.43,-0.06
0.98,0.45 C 0.35,-0.06 0.98,-0.06 D
1.18,-0.06 Q
C
latency_pipe_5_26_0_
fully_2_1_bit[0] y[0] op_mem_19_20_0_
xor_3a parity_reg
xor_2b
xor_2a_8d6908ffef
LUT4_L_6996
1.18,0.45
0.35,-0.06
0.98,0.45
0.98,0.45 FD
1.18,0.45
0.98,0.45 1.18,0.45
D
Q 0.35,-0.06
0.98,0.45 C
latency_pipe_5_26_0_
fully_2_1_bit[0]
xor_2a
See that there is an extra set of registers (highlighted in red) in between the two levels of
logic. The circuit functions the same as before but with an additional cycle of latency.
with it. New compilation targets can be created that extend the HDL Netlist target so that
additional tools can be applied to the resulting HDL netlist files.
This topic explains how you can create new compilation targets that extend the HDL
Netlist target in order to produce and configure FPGA hardware. More specifically, it
describes how to configure System Generator to produce a bitstream for a model, and how
to invoke various tools once the bitstream is created.
Although an xltarget function can specify multiple targets, it is not uncommon for each
compilation target to have its own xltarget function. The directories these functions are
saved in distinguish the targets. This means that each xltarget.m file must be saved in
its own subdirectory under the plugins/compilation directory.
An xltarget function returns a cell array of target information. Different elements in this
cell array define different compilation targets. The elements in this cell array are MATLAB
structs that define two parameters:
1. The name of the compilation target as it should appear in the Compilation field of the
System Generator parameters dialog box;
2. The name of the MATLAB function it should invoke to find out more information (e.g.,
System Generator dialog box parameters, which post-generation function to use, if
any) about the target.
The following code shows how to define three compilation targets named Standalone
Bitstream, iMPACT, and ChipScope Pro Analyzer:
function s = xltarget
s = {};
target_1.('name') = 'Standalone Bitstream';
target_1.('target_info') = 'xltools_target';
target_2.('name') = 'iMPACT';
target_2.('target_info') = 'xltools_target';
target_3.('name') = 'ChipScope Pro Analyzer';
target_3.('target_info') = 'xltools_target';
s = {target_1, target_2, target_3};
The name field in the code shown above specifies the name of the compilation target, as it
should appear in the Compilation field of the System Generator dialog box:
target_1.('name') = 'Standalone Bitstream';
The target_info field tells System Generator the target info function it should call to find
out more information about the target. This function can have any name provided it is
saved in the same directory as the corresponding xltarget.m file, or it is saved somewhere
in the MATLAB path.
target_1.('target_info') = 'xltools_target';
Note: An example xltarget function is included in the examples/comp_targets directory of your
System Generator install tree. You can modify this function to define your own bitstream-related
compilation targets.
Post-generation Functions
One way to extend System Generator compilation is by defining a new variety of
compilation that specifies a post-generation function. A post-generation function is a
MATLAB function that tells System Generator how to process the HDL and netlist files
once they are generated. This function is run after System Generator finishes the normal
code generation steps involved with HDL Netlist compilation (i.e., producing an HDL
description of the design, running CORE Generator, etc). For example, a hardware co-
simulation target defines a post-generation function that in turn runs the tools necessary to
produce hardware that can be used in the Simulink simulation loop.
Note: Two post-generation functions xlBitstreamPostGeneration.m and
xltools_postgeneration.m, are included in the examples/comp_targets directory of your
System Generator install tree.
xlBitstreamPostGeneration.m
This example post-generation function compiles your model into a configuration bitstream
that is appropriate for the settings (e.g., FPGA part, clock frequency, clock pin location)
given in the System Generator dialog box of your design.
It then uses an XFLOW-based flow to invoke the Xilinx tools necessary to produce an
FPGA configuration bitstream.
It is possible to configure the tools and configurations for each tool invoked by XFLOW.
For more information on how to do this, refer to the topic in this example entitled Using
XFLOW
xltools_postgeneration.m
Sometimes you may want to run tools that configure and run the FPGA after a
configuration bitstream has been generated (e.g., iMPACT, ChipScope Pro Analyzer). The
xltools_postgeneration function first calls the xlBitstreamGeneration function to generate
the bitstream. It then invokes the appropriate tool (or tools) depending on the compilation
target that is selected.
For example, you may want a compilation target that invokes iMPACT after the bitstream
is generated. This can be done as follows (assuming iMPACT is in your system path):
if (strcmp(params.compilation, 'iMPACT'))
dos('impact');
end;
The first line checks the name of the compilation target. The second line sets up a DOS
command that invokes iMPACT. ChipScope Pro Analyzer can be invoked similarly to the
code above:
if (strcmp(params.compilation, 'ChipScope Pro Analyzer'))
xlCallChipScopeAnalyzer;
end;
Note: xlCallChipScopeAnalyzer is a MATLAB function provided by System Generator to invoke
ChipScope.
Using XFLOW
The post-generation scripting included with this example uses XFLOW to produce a
configuration file for your FPGA. XFLOW allows you to automate the process of design
synthesis, implementation, and simulation using a command line interface. XFLOW uses
command files to tell it which tools to run, and how they should be run.
This example contains two XFLOW options files, balanced_xltools.opt and
bitgen_xltools.opt. These files are associated with the implementation and
configuration flows of XFLOW, respectively. The balanced_xltools.opt options files
runs the Xilinx NGDBUILD, MAP, and PAR tools. The settings for each tool are specified in
the options files . The bitgen_xltools.opt file runs BITGEN to produce a
configuration file for your FPGA. You may modify these files as desired (e.g., to run the
timing analyzer after PAR).
using ChipScope Pro 126 Frame-Based Acceleration designing and simulating Mi-
Defining New Compilation Targets 343 using Hardware Co-Sim 201 croBlaze Processor Systems
160
Target Info functions FSL-based pcore 138
using EDK 169
xltools_target 344 Full Precision signal type 22
using PicoBlase in System Gen-
the xltarget Function 343 erator 150
Discrete Time Systems 23
Distinct Clocks G HDL Co-Sim
configuring the HDL simulator 283
generating multiple cycle-true is- Generating co-simulating multiple black boxes
lands 114 285
an FPGA bitstream 92
DSP48 HDL Netlist Compilation 320
EDK software drivers 141
design styles for 98 HDL Testbench 49
Generating an FPGA Bitstream
design techniques 102 Hierarchical Controls 42
Generating an FPGA Bitstream 92
mapping from the DSP48 block 100 Histogram Charts
mapping standard components to from Timing Analyzer 334, 336
99 H
mapping to from logic synthesis
tools 99 Hardware
physical planning for 104 oversampling 25
I
DSP48 Macro block 101 Hardware Co-Sim 175 Implementing
blocks 177 a complete design 17
choosing a compilation target 176 part of a design 17
E compiling shared memories 190 Importing
EDK co-simulating lockable shared mem- a System Generator design 71
ories 193 an EDK processor 145
generating software drivers 141
co-simulating shared FIFOs 196 an EDK project 140
support from System Generator 145
co-simulating shared registers 195 Importing a System Generator Design 71
writing software drivers 142
co-simulating unprotected shared integration design rules 71
EDK Export Tool 325
memories 192
exporting a pcore 148 integration flow with Project Navi-
invoking the code generator 176 gator 72
EDK Import Wizard 145
JTAG hardware requirements 255 step-by-step example 73
EDK Processor
Network-Based Ethernet 188 Installation
exposing processor ports 147
Point-to-Point Ethernet 184 Installing a Spartan-3A DSP 1800A
importing 145 Starter Platform for Hardware Co-
processor integration 141
Ethernet-based HW Co-Sim 242 Sim 242
restrictions on shared memories 199
Export pcore Installing am ML402 Board for JTAG
selecting the target clock frequency
enable Custom Bus Interfaces 326 180 Hardware Co-Sim 254
Exporting shared memory support 189 Introduction
a pcore 148 using for frame-based acceleration to FPGAs 12
a System Generator model as a pcore 201
140 using for real-time signal processing
Expose Clock Ports Option 214 J
tutorial 32 Xilinx tool flow settings 199 JTAG Hardware Co-Sim
Hardware Co-Simulation Compilation board support package files 261
329
Detecting New Board Packages 267
F Hardware Debugging
installing board-support packages
using ChipScope Pro 126 266
Fanout Reduction
Hardware Generation 140 manually specifying board-specific
for Clock Enable 88
Hardware Generation Mode ports 264
FDATool
EDK pcore 140 obtaining platform information 262
using in digital filter applications
106 HDL netlist 140 providing your own top-level 265
FPGA Hardware/Software Co-Design 138 supporting new platforms 255
a brief introduction 12 Examples JTAG-based HW Co-Sim 254
generating a bitstream 92 creating MicroBlaze Peripherals
in System Generator 155
notes for higher performance 87
U
Underdevelopment