Introduction_to_Simulink_SKARAB - david-macmahon/wiki_convert_test GitHub Wiki
Tutorial 1: Introduction to Simulink
Authors: Amish Patel (Version 1)
Estimated completion time: 2 hours
In this tutorial, you will create a simple Simulink design using both standard Xilinx system generator blockset, as well as library blocks specific to SKARAB. At the end of this tutorial, you will have an fpg file and you will know how to interact with your running hardware design using casperfpga via a Python Interface.
The lab at the workshop is pre-configured with the CASPER libraries, MATLAB and Xilinx tools. If you want to try this tutorial in your lab, please refer the topics : H/W & S/W requirements , SET-UP of Tutorials at WORKSHOP 2011, Compiling the Design & Programming on ROACH FPGA and Locations & Files information for the WORKSHOP 2011 wherever applicable in the link Complete information of Tutorial Lab & Setup.
In order to open MATLAB with the required Xilinx libraries, navigate to the mlib_devel folder under SKARAB and execute the following command in your terminal window:
./startsg startsg.local.caltech2017
This ensures that you have the Xilinx Blockset and CASPER tools loaded into your Simulink library.
Next, open Simulink (either by typing simulink on the MATLAB command line, or by clicking the Simulink icon in the MATLAB taskbar).
Create a new model:
It is a good time to save this new design. There are some Matlab limitations you should be aware-of:
Do not use spaces in your filenames, or anywhere in the file path as it will break the toolflow.
Total path length cannot be more than 64 characters. This refers to not only the file path, but also the path to any block within your design. For example, if you save this file to c:\projects\myfile.slx, the longest Matlab-indexed path would be c:\projects\myfile.slx\counter_led. While this is quite short, but there can be additional blocks hidden underneath some of your top level blocks. This is the case with GPIO, for example. This will become clearer later when we demonstrate the use of SubSystems. For now, try to keep your names short.
Please save your design in your home directory.under /projects/<YOUR_INITIALS>_t1.slx.
Add a System generator block from the Xilinx library by locating the Xilinx Blockset library's Basic Elements subsection and dragging a System Generator token onto your new file.
Do not configure it directly, but rather add a SKARAB Yellow block from the CASPER XPS System Blockset library to do this for you:
All hardware-related blocks are yellow and can be found in the CASPER XPS library. This library contains all the board-specific components colloquially called "Yellow Blocks."
DSP related blocks are found in the CASPER DSP library and have other colours. Tutorial 3 will introduce you to these blocks.
Double click on the SKARAB block that you just added. The Hardware Platform should already be set to SKARAB:xc7vx690t, so go ahead and set the User IP Clock Source to sys_clk. sys_clk is the on-board crystal and runs at 156.25MHz.
The User IP Clock Rate (MHZ) is the rate at which you want your design to run on the board, which should ideally be greater than the sys_clk. Set the User IP Clock Rate (MHZ) to a value greater than 156.25MHz (e.g. 230MHz).
This will go off and configure the System Generator block which you previously added.
You need to add these two blocks for all CASPER designs.
Before moving on, rename the "SKARAB" block, by double-clicking the name, and replace spaces (" ") with underscores ("_").
To demonstrate the basic use of hardware interfaces, we will make an LED flash. With the FPGA running at 156.25MHz (or greater), the most significant bit (msb) of a 27 bit counter will toggle approximately every 0.86 seconds. We can output this bit to an LED on a SKARAB. SKARAB's have eight LEDs - four green LEDs and four red LEDs. We will now connect a counter to the first one (LED 0 on SKA-SA and LED 5 on the Peralex faceplate).
Add a counter to your design by navigating to Xilinx Blockset -> Basic Elements -> Counter and dragging it onto your model.
Double-click it and set it for free running, 27 bits, unsigned.
We now need to select the most significant bit (msb) of the counter. We do this using a slice block, which Xilinx provides. Xilinx Blockset -> Basic Elements -> Slice.
Double-click on the newly added slice block. There are multiple ways to select which bit(s) you want. In this case, it is simplest to index from the upper end and select the first bit. If you wanted the least significant bit (lsb), you can also index from that position. You can either select the width and offset, or two bit locations.
Set it for 1 bit wide with offset from top bit at zero.
From: CASPER XPS library -> gpio.
Set it to use ROACH2's LED bank as output. Set the data type to Boolean and the bitwidth to 1 and the GPIO bit index 0 (the first LED).
To prevent warnings (from MATLAB & Simulink) about unconnected outputs, terminate all unused outputs using a Terminator:
From: Simulink -> Sinks -> Terminator
Note that all blocks from the Simulink library (usually white), will not be compiled into hardware. They are present for simulation only and expect continuous signals, not discreet.
Only Xilinx blocks (they are blue with Xilinx logo) will be compiled to hardware.
For this reason, you need to use gateway blocks whenever connecting a Simulink-provided block (like a scope or constant) for simulations. Some of the CASPER blocks (like the GPIO block) do this for you with sim_reg and sim_out. We will see later how to use a Simulink Scope - a software oscilloscope - to monitor these lines.
It is a good idea to rename your blocks to something more sensible, like counter_led instead of just counter. Do this simply by double-clicking on the name of the block and editing the text appropriately.
To connect the blocks simply click and drag from the 'output arrow' on one block and drag it to the 'input arrow' of another block. Connect the blocks together: Counter -> Slice -> gpio as showing in digram below.
Remember to save your design often.
To demonstrate the use of software registers and control of the FPGA through the PPC, we will add a controllable counter to the above design. The counter can be started and stopped from software and also reset. We will be able to monitor the counter's current value too.
By the end of this section, you will create a system that looks like this:
We need two software registers. One to control the counter, and a second one to read its current value. From the CASPER XPS System Blockset library, drag two Software Registers onto your design.
Set the I/O direction to From Processor on the first one (counter control) to enable dataflow to the FPGA fabric. Set it to To Processor on the second one (counter value) to enable dataflow from the FPGA fabric. Set both registers to a bitwidth of 32 bits.
Rename the registers to something sensible, as these names are mapped to filenames in the PPC for controlling the design. Avoid using spaces, slashes and other funny characters in these names (spaces automatically get remapped to underscores anyway, but should be avoided for clarity). Perhaps counter_ctrl and counter_value, to represent the control and output registers respectively.
Also note that the software registers have sim_reg and sim_out ports. The input port provides a means of simulating this register's value (as would be set by the PPC) using the sim_reg line. The output port provides a means to simulate this register's current FPGA-assigned value.
For now, set the sim_reg port to constant one using a Simulink-type constant. Found in Simulink -> Sources. This will enable the counter during simulations.
During simulation, we can monitor the counter's value using a scope (Simulink -> Sinks):
You can do this either by copying your existing counter block (copy-paste, or ctrl-click-drag-drop) or by placing a new one from the library.
Configure it with a reset and enable port as follows:
Now we need some way to control the enable and reset ports of the counter. We could do this using two separate software registers, but this is wasteful since each register is 32 bits anyway.
So we'll use a single register and slice out one bit for enabling the counter, and another bit for resetting it. Either copy your existing slice block (copy-paste it or hold ctrl while dragging/dropping it) or add two more from the library.
The enable and reset ports of the counter require boolean values (which Simulink interprets differently from ordinary 1-bit unsigned numbers). Configure the slices as follows:
Slice for enable:
Slice for reset:
Now we need to connect all these blocks together. To neaten things up, consider resizing the slice blocks and hiding their names. Their function is clear enough from their icon without needing to see their names.
Do so by right-clicking and unchecking Format → Show Block Name. You could do this with the counter too, but it's not a good idea with the software registers, because otherwise you wouldn't know how to address them when looking at your diagram.
To demonstrate some simple mathematical operations, we will create an adder. It will add two numbers on demand and output the result to another software register. Almost all astronomy DSP is done using fixed-point (integer) notation, and this adder will be no different.
We will calculate a+b=sum_a_b.
Add two more input software registers. These will allow us to specify the two numbers to add. Add another output register for the sum output.
Either copy your existing software register blocks (copy-paste or holding ctrl while dragging/dropping it) or add three more from the library. Set the I/O direction to From Processor on the first two and set it to To Processor on the third one.
Locate the adder/subtractor block, Xilinx Blockset -> Math -> AddSub and drag one onto your design. This block can optionally perform addition or subtraction. Let's leave it set at it's default, for addition.
The output register is 32 bits. If we add two 32 bit numbers, we will have 33 bits.
There are a number of ways of fixing this:
- limit the input bitwidth(s) with slice blocks
- limit the output bitwidth with slice blocks
- create a 32 bit adder.
Since you have already seen slice blocks demonstrated, let's try to set the AddSub block to be a 32 bit saturating adder. On the second tab, set it for user-defined precision, unsigned 32 bits.
Also, under overflow, set it to saturate. Now if we add two very large numbers, it will simply return 2^32 -1.
Either copy your existing scope and simulation constants (copy-paste or ctrl-drag) or place a new one from the library as before. Set the values of the simulation inputs to anything you like.
Like this:
The design can be simulated with clock-for-clock accuracy directly from within Simulink. Set the number of clock cycles that you'd like to simulate and press the play button in the top toolbar.
You can watch the simulation progress in the status bar in the bottom right. It will complete in the blink of an eye for this small design with just 10 clock cycles.
You can double-click on the scopes to see what the signals look like on those lines. For example, the one connected to the counter should look like this:
The one connected to your adder should return a constant, equal to the sum of the two numbers you entered. You might have to press the Autoscale button to scale the scope appropriately.
Once you have verified that that design functions as you'd like, you're ready to compile for the FPGA...
Essentially, you have constructed three completely separate little instruments. You have a flashing LED, a counter which you can start/stop/reset from software and also an adder. These components are all clocked off the same 156.25MHz system clock crystal and to your specified User IP Clock Rate, but they will operate independently.
In order to compile this to an FPGA bitstream, execute the following command in the MATLAB Command Line window:
>> jasper
This will run the complete build process over two stages. The first involving Xilinx's System Generator, which compiles any Xilinx blocks in your Simulink design, and the windows below should pop up.
After this, the second stage involves synthesis of your design through Vivado, and creating the final output fpg file that you will use to program your FPGA. This file will be situated in the 'outputs' folder in the working directory of your Simulink model. Note: Compile time is approximately 15-20 minutes.
Should you want to run the two stages separately, you can run the following command in the MATLAB Command Line:
>> jasper_frontend
This will run the first of two build processes and output a few debug messages to the MATLAB Command Line window along the way. Again, during the compilation and build process Vivado's system generator will be run, and the windows shown above will pop up.
After this is completed, the last debug message to be output should be as follows:
Run '/path_to/mlib_devel/jasper_library/exec_flow.py -m /home/user/path_to/skarab/tut_intro/skarab_tut_intro.slx --middleware --backend --software' to finish flow
To execute this (second of two build processes):
- Open a new terminal window
- Navigate to mlib_devel/ folder on your development machine
- Run the
'exec_flow.py ...'
command preceded by the 'python' command (as below)
user@this-pc:~/path_to/mlib_devel/$ python exec_flow.py -m /home/user/path_to/skarab/tut_intro/skarab_tut_intro.slx --middleware --backend --software
Should you receive any errors during this, mainly complaining about Environment Variables, you can solve that by
- Navigating to the directory where startsg.local is stored (probably mlib_devel/)
- Executing
source startsg.local
will populate the environment variables required - Run the
'exec_flow.py ...'
command again to initiate the second stage of the build process
Reconfiguration of the SKARAB's SDRAM is done via the casperfpga python library. The casperfpga package for python, created by the SA-SKA group, wraps the Telnet commands in python. and is probably the most commonly used in the CASPER community. We will focus on programming and interacting with the FPGA using this method.
These are pre-installed on the server in the workshop and you do not need to do any further configuration.
As per the previous figure, navigate to the outputs folder and (secure)copy this across to a test folder on the workshop server.
scp path_to/your/model_folder/your_model_name/outputs/your_fpgfile.fpg user@server:/path/to/test/folder/
SSH into the server that the SKARAB is connected to and navigate to the folder in which your .fpg file is stored.
Start interactive python by running:
ipython
Now import the fpga control library. This will automatically pull-in the KATCP library and any other required communications libraries.
import casperfpga
To connect to the SKARAB we create an instance of the SKARAB board; let's call it fpga. The wrapper's fpgaclient initiator requires just one argument: the IP hostname or address of the SKARAB board.
fpga = casperfpga.CasperFpga('skarab_name or ip_address')
The first thing we do is configure the FPGA.
fpga.upload_to_ram_and_program('your_fpgfile.fpg')
Should the execution of this command return true, you can safely assume the FPGA is now configured with your design. You should see the LED on the SKARAB flashing. All the available/configured registers can be displayed using:
fpga.listdev()
The adder and counter can be controlled by writing to and reading from registers added in the design using:
fpga.write_int('a',10)
fpga.write_int('b',20)
fpga.read_int('sum_a_b')
fpga.write_int('counter_ctrl',10')
fpga.read_uint('counter_value')
This concludes the first SKARAB Tutorial. You have learned how to construct a simple Simulink design, program a SKARAB board and interact with it using casperfpga via Python.
In the next tutorial you will learn how to use the 40GbE network interfaces on SKARAB boards to communicate to another SKARAB. Again, this will be implemented through MATLAB and tested via casperfpga in an ipython session.