FrontPanel 3.x / Impulse C Architecture Introduction
- The FrontPanel 3 CoDeveloper Architecture is preliminary and has not been released yet.
Impulse C CoDeveloper allows C-language applications to be compiled into optimized FPGA logic. Using the Impulse CoDeveloper™ tools, you have the power to accelerate algorithms by orders of magnitude (as much as 300X) over traditional processor implementations.
Impulse Accelerated Technologies, Inc. was formed in October of 2002 to serve the needs of embedded systems designers through the development and distribution of software-to-hardware compilation and verification tools, through user education and through ongoing customer support.
Opal Kelly has been working with Impulse to build an integrated board support environment allowing you to target Opal Kelly modules from within ImpulseC. Together, this makes the Opal Kelly FrontPanel-enabled devices a very low-cost integration platform for users of ImpulseC.
Architecture Overview
To ease utilization of the ImpulseC CoDeveloper C-to-FPGA synthesis tool with Opal Kelly products, a complete architecture within CoDeveloper has been implemented that will generate and organize all HDL wrapper files necessary for complete compilation in the Xilinx ISE. Files are also included to perform simulation in ModelSim.
- Currently, only VHDL is supported natively by the architecture, but this is the preferred language of the CoDeveloper environment.
- ImpulseC 16-bit co_signals are supported as
okWire
components, and 16-bit and 32-bit co_streams are supported by modules constructed with FIFO’s mated tookBlockPipe
components. The details of this implementation are handled by an included Library wrapper file,okImpulseLibrary.vhd
. - FrontPanel 3 is required. Some files will need to be copied from your installation directory, and a board UCF will need to be edited.
Components of the Architecture
Within CoDeveloper, navigate to Options→Generate→Platform Support Package and select Opal Kelly FrontPanel USB (VHDL). Now, once the HDL is exported, the hardware build directory will be populated with the following files:
Top-level Wrapper
A top-level wrapper file, (name)_fp_wrapper.vhd, is generated automatically by the Opal Kelly FrontPanel 3 Architecture installed with CoDeveloper. This wrapper file brings together all of the underlying components and is the top-level file for synthesis. It has several other components as well:
- An
okWireIn
modules is present for each output co_stream created. This module brings in a value from the PC that tells the HDL code how large output blocks of data will be. This will be explained more below.- All input data blocks are assumed to be 1024 bytes or less (this room is reserved in the input FIFO)
- A single
okTriggerIn
module is present with bit 0 at endpoint address 0x40 combined with a global reset from a DCM. If the DCM DLL is locking only a clock, or if the user triggers this bit from the PC, a global reset to all CoDeveloper modules will occur.
okImpulseLibrary.vhd
The file okImpulseLibrary.vhd defines some key modules constructed from Xilinx and Opal Kelly component with a bit of added logic:
simple_dcm
: A very basic DCM implementation on the incoming clock signal. The LOCKED DCM signal is outputted as a global system resetokImpulsePipeIn16
: An ISE Coregen created first-word-fall-through 16 bits x 8192 deep FIFO mated to anokBTPipeIn
(Opal Kelly Block Throttled Pipe In) module. There are two state machines:- The first monitors the CoDeveloper stream it’s attached to. If the interface is ready for data and the FIFO is not empty, data will be provided.
- The second monitors the fullness of the FIFO. Assuming that a block of data can come through the
okBTPipeIn
module of at most 1024 bytes, if room in the FIFO allows, the module is given a Readysignal. Otherwise, the module is told to wait and data is throttled automatically (if pending).
okImpulsePipeIn32
: Identical in form and function tookImpulsePipeIn16
, but the FIFO received up to 16 bits x 8192 of incoming data and converts it to 32 bits x 4096 for the stream input.okImpulsePipeOut16
: An ISE Coregen created standard 16 bits x 8192 deep FIFO mated to anokBTPipeOut
(Opal Kelly Block Throttled Pipe Out) module. There is also an input of blockSize from the top-level wrapper and two state machines:- The
blockSize
value comes from an okWire in module in the top-level and tells the state machine described below when enough data is ready for a block transfer. - The first state machine monitors the CoDeveloper output stream it’s attached to. If the stream has data and FIFO is not full, the stream data will be added to the FIFO.
- The second state machine monitors the fullness of the FIFO. If there is enough data in the FIFO to fullfill a complete block transfer (which depends on the provided size), the
okBTPipeOut
module is given a Ready signal. Otherwise, the module is told to wait and the transfer out is throttled automatically (if pending) until enough data is present in the FIFO.
- The
okImpulsePipeOut32
: Identical in form and function tookImpulsePipeOut16
, but the FIFO received up to 32 bits x 4096 of stream data and converts it to 16 bits x 8192 for output through a standardokBTPipeOut
.
Support Files
- Two VHDL source files should be generated, (name)_comp.vhd and (name)_top.vhd. These are the standard CoDeveloper files that contain the actual hardware implementation of your C code.
- lib directory, containing the standard CoDeveloper library of components possibly used in your design
- ForISE directory, containing the Xilix Coregen FIFO XCO files used for streams. These will be copied to your main ISE project folder and can be modified, recustomized, and then recompiled to suit your streaming needs.
- sim directory, containing a barebone test fixture, simulation do file, and the behaviorial simulation files for the FIFOs described above.
Software Operation
This is a general overview of how functions should be called to communicate with a FrontPanel 3 connected CoDevloper Project.
You must check the wrapper file to find out what the endpoint address for the various components have been assigned to. The starting address for okWireIn
modules is 00h, for okBTPipeIn
modules it is 80h (assigned in the okImpulsePipeInXX
block), and for okBTPipeOut
modules it is A0h (assign in the okImpulsePipeOutXX
block).
- Begin general use by activating a global reset with:
ActivateTriggerIn(0x40, 0) // endpoint, bit
- All Pipe streams in FrontPanel are passed as unsigned char arrays (8-bit). Create, for example, a 32-byte array called bufin and fill it with configuration data. Send this data to the 80h endpoint
okImpulsePipeInXX
with the command:WriteToBlockPipeIn(0x80, 32, 32, bufin) // endpoint, length, block size, unsigned char array
- If the module at endpoint 80h is
okImpulsePipeIn16
, the data will come out as 16, 16-bit words. If the module at endpoint 80h isokImpulsePipeIn32
, the data will come out at 8, 32-bit doublewords. High bit/high byte first.
- If the module at endpoint 80h is
- To retreive a stream of data, first tell the system how large the blocks of data will be that you will request. The larger the block (up to 1024), and the larger the transfer length, the better the performance will be. For the Mandelbrot example, the maximum size is used:
SetWireInValue(0x00, 1024, xffff); // xffff is a data mask UpdateWireIns(); // send all updated Wire values to device
- Now, you may call a large transfer of data:
ReadFromBlockPipeOut(0xA0, 1024x32x24, 1024, bufout); // endpoint, length, block size, unsigned char array)
- If your Impulse C algorithm is not prepared to generate enough data to full fill the stream request, the function call will timeout. Full error code checking is supportted.
Mandelbrot Design Example for Opal Kelly XEM3010
Below is a brief step-by-step description of the steps necessary to build and synthesis all files necessary for the Mandelbrot_1 example for an Opal Kelly XEM3010. Virtually all the steps provided here apply to any CoDeveloper/FrontPanel 3 project.
Project Settings and Export
- The example located in CoDeveloper2ExamplesOpalKellyMandelbrot should already be setup for the correct board support package. If you project is not, follow these steps:
- Navigate to Options→Generate→Platform Support Package and select Opal Kelly FrontPanel USB (VHDL).
- In this same Options tab, make sure Enable constant propagation, Scalarize array variables, and Use std_logic types for VHDL interface are chosen.
- From the top menu, select Generate HDL.
Xilinx ISE Compilation
- Begin by creating a new ISE Project in a sub directory of your CoDeveloper project.
- Setup the project for the processor in your XEM. For the XEM3010-1500P, this would be a Spartan 3, XC3S1500, FG320, -4.
- Don’t add any design files to the project yet. Continue on to Finish.
- Select Project→Add Souce. Navigate to the /hw directory and add
(name)_wrapper.vhd
,(name)_comp.vhd
,(name)_top.vhd
, andokImpulseLibrary.vhd
to the project. Make sure,(name)_wrapper
is the top-level file. - Select Project→New Source from the top menu, choose VHDL Library and call it Impulse. Navigate to the Libraries tab in the Sources dialog, right-click on the impulse library, and choose Add source. This time navigate to /hw/lib and add all the ImpulseC library files.
- From your FrontPanel application installed directory, you need a valid UCF file for your board and
okLibrary.vhd
. Copy these somewhere to the project (your ISE folder perhaps) and modify the UCF file as needed. You can view the signals required in the(name)_wrapper.vhd
file (for instance, the name of the clock in the UCF file you should be renamed clk_in) and add them as sources. - Copy all the standard Opal Kelly *.ngc modules located in the FrontPanel installation directory (choose the ones for your ISE version or the latest available) to your root ISE project folder.
- Copy from the local /hw/ForISE/ directory all the FIFO XCO files to your root ISE project folder. Add them as sources to the ISE project.
- You can navigate to any of these FIFO Coregen modules in ISE, select the file, and then in the Processwindow, double-click Manage Cores to work with the XCO files.
- Manage Cores will open the Xilinx CORE Generator. These FIFO’s were originally FIFO Coregen Version 3.2. If you have newer or older IP, you may need to recustomize them here to update the files. You may also change the size of the FIFO to better fit your design. Doing so might change the size of some of the status registers and they will have to be altered in
okImpulseLibrary.vhd
.
You should now be ready to select the top-level file and generate a programming file. If you haven’t already built the FIFO components, you will be asked sequentially to generate the files. Any random errors during or after generation of the FIFO’s is most likely caused by Xilinx IP mismatches. Recustomize the IP as described above.
PC Application Compilation in Visual Studios
- Begin by creating a generic Win32 Console Application in Visual Studios. Don’t use precompiled headers or any other options at this point.
- Change the Solution Configuration to
Release
. - If you are using VS 2005 or newer, under project options (for Release build), you may need to change the Character Set to
Use Multi-Byte Character Set
- Remove all the default, pre-generated
.cpp
and.h
files from the project. - Copy from the FrontPanel application installed directory
okFrontPanelDLL.h
andokFrontPanelDLL.cpp
to the root example directory where the other source files are located. - From the main project folder, add
mand.h
andokFrontPanelDLL.h
to your header files. Also addmandelbrot.c
andokFrontPanelDLL.cpp
to source files. - Build the project.
- Copy from the FrontPanel application installed directory the
okFrontPanel.dll
to theRelease
folder. Also, copy the*.bit
file you generated in ISE here as well and rename the file tomandelbrot.bit
. - In a command prompt, you may now run the application. You will have to call the function with
executable_name.exe 40
- In this case, 40 sets the frequency at which the application will run.
You should see your Mandelbrot.bmp file in the Release
folder when done.
FrontPanel 3 within Impulse CoDeveloper
Behavioral Simulation in ModelSim
Before starting with simulation, make sure you are familiar with Opal Kelly FrontPanel simulation in general. There is an online tutorial here to help. In the very least, you will need to have the FrontPanel simulation libraries installed in ModelSim.
- Begin by creating a new
sim
folder in the root project directory. - Copy all the files from the generated
hwsim
to this new simulation folder. - From your ISE project directory, the Xilinx Coregen created simulation files for the 4 Coregen FIFOs with the extension
*.vhd
. Copy those 4 files to you new simulation folder. - Now open the
simulation_tf.vhd
file to tailor it to your project.- On line 32 and 54, you will need to change the name of the component to the name of the actual project top-level. In the Mandelbrot example, this would be
mand_fp_wrapper
.
- On line 32 and 54, you will need to change the name of the component to the name of the actual project top-level. In the Mandelbrot example, this would be
- The file
simulation.do
should be almost setup to compile theimpulse
library, a localwork
library with all other files, and initialize the simulation. You will need to open the file first and change the top-level entity in the vsim command. In the example file, this top-level isSimple_Test
.
Open ModelSim, change the work directory to you new sim
folder, and type do simualtion.do
. The files should be compiled and the simulation will be initialized.
Maximizing Read/Write performance
From the FrontPanel 3 Users Manual:
“Pipes are the fastest way to transmit or receive bulk data. Due to overhead, performance is best with long transfers. Each time you perform a pipe transfer, several layers of setup are required including those at the firmware level, APIlevel, and operating system level. Therefore, it is best to design around using long transfers, if possible. This generally means using large buffer sizes on the FPGA and relying on external memory when possible.”
Performance with Block Throttled Pipes is greatly improved with longer transfers of larger block sizes. For instance, with an few megabyte transfer with 1024 byte blocks, the user may see 38 MB/s read and write performance to the FPGA.
The wrapper library file okImpulseLibrary.vhd
is designed to work well with 1024 byte block sizes (the largest), but the total FIFO space is small (defaults to 16384 bytes). If your design could feed in data into the FIFO, have the data processed in your Impulse CoDeveloper module, and then output into another FIFO, you could transfer in 32768 bytes of data and then transfer out that same amount. However, the last byte in any standard FIFO implementation my be lost in the hardware implementation so please design for this.
However, to achieve the greatest performance, you will not be able to solely rely on the finite FIFO space of the FPGA. Most Opal Kelly FPGA modules come with embedded SDRAM and we have a simplified SDRAM controller in our Ramtester
example that works with blocks of data and is readily attached to a standard FIFO. By combining small FIFO’s with an SDRAM controller, a more sophisticated okImpulseLibrary.vhd
could be developed that utilizes the large SDRAM as large pseudo input and output FIFO. This will facilitate very large and very fast transfer sizes.
Of course, if your Impulse CoDeveloper module is FPGA processing bound, the system as currently designed may suit your needs.
Opal Kelly Endpoint Generation
Each FrontPanel module must have an endpoint address. These are partitioned into groups of addresses depending on the type of module.
As you build your CoDeveloper application, co_streams and co_registers will be automatically linked to FrontPanel Block Throttled Pipes and Wire modules respectively.
- Input co_registers will be linked with okWireIn modules with the enumeration starting at 0x00.
- Output co_registers will be linked with okWireOut modules with the enumeration starting at 0x20.
- Input co_streams will be linked with okBTPipeIn modules with the enumeration starting at 0x80.
- Output co_streams will be linked with okBTPipeOut modules with the enumeration starting at 0xA0.
- Each output co_stream will also have an okWireIn modules associated with it. The data sent through this module will tell the interface how large the output block size will be. These modules are enumerated along with the okWireIn modules above.
After exporting your CoDeveloper project to HDL, open your generated xxxx.fp_wrapper.vhd
that will be located in the hw
folder. You will need to verify the choosen endpoint addresses here before writing code for a PC application to communicate with the design. In the Mandelbrot example, the following addresses are typically made by the tool:
- The
config_stream
, which is a 32-bit input co_stream is located at endpoint 0x80. - The
pixel_stream
, which is a 32-bit output co_stream is located at endpoint 0xA0. It has an associatedokWireIn
module at endpoint 0x00. Writing a value of 1024 to thisokWireIn
module will mean that data block sizes of 1024 bytes should be streamed out of this port.