HDL Coder is a tool that generates portable, synthesizable VHDL and Verilog code from MATLAB functions, Simulink models, and Stateflow charts. It provides a workflow advisor that automates the programming of Xilinx and Altera FPGAs. In this blog series, we put HDL Coder to the test by using a Simulink model to generate the HDL files required to transmit a tone in Nutaq’s ZeptoSDR system, which is based on the Zynq processor.
First, let’s create the Simulink model.
The first step in creating a compatible Simulink model that can automatically generate hardware description language (HDL) code is to filter the Simulink block library to keep only the blocks that are supported by HDL Coder (in other words, blocks that work with fixed-point samples). At the MATLAB command prompt, enter the hdllib command. The following window will appear:
You will probably see that the blockset library is much more limited than before. It’s more than enough, however, for what we need to do at this moment.
The next step is to create a new Simulink model based around this library that generates the tone. To transmit a tone to the radio card on the ZeptoSDR, you need a complex tone generator and an interleaver (the I & Q data are interleaved on the radio card). Here’s an example of such a model:
The sine wave can be found in the DSP toolbox library (highly recommended for DSP applications):
Configure the Sine Wave block as follows:
Many things are important to understand to set this block correctly. First, let’s consider the ratio between the Sample time and the Frequency settings. Briefly, Sample time divided by Frequency gives you the number of samples in one period. So, depending on the clock source that we will use to clock our tone later at the real-time implementation stage, the frequency can change but we will keep the same number of samples per period. For example, a clock of 20 MHz will give us a tone of 200 kHz.
The other important setting is Samples per frame. It needs to be 1, simply because an FPGA works at the bit level. At each clock edge, each piece of hardware in the FPGA is processing its inputs bits. Frames are not supported by HDL Coder; it will drop an error during compilation process.
Finally, Output data type needs to be set to ‘fixdt’ because we are creating code for a fixed-point processor (FPGA). In our case, ‘fixdt(1,12,11)’ configures the output amplitude to be represented using 12 bits of resolution, with 11 binary points (this means that the dynamic range of the amplitude will vary approximately between -1 and 0.995). The number of resolution bits can vary depending on the application and the required precision. Keep in mind that we are creating code for an FPGA, in which each bit is a signal, so each bit counts. More bits mean a higher dynamic range but will cost more in resources. In our case, the resolution is easily determined as the radio card digital-analog convertors (DACs) can use a maximum of 12 bits.
The next block that we need is a counter. The counter simply counts from 0 to 1. Used in conjunction with a switch, it creates our interleaver. The output of the switch is as follows:
Looking at the output, one might observe that to achieve the required output, the output rate of the switch needs to be twice as fast as the output rate of the tone. How do we achieve this? First, the counter (or the selector) needs to run twice as fast. We do this by setting the Sample time of the counter:
The Sample time is 0.5, compared to the tone (which is 1). This means that the counter, relatively to the tone, will run twice as fast. It’s important to understand that this value doesn’t define the actual sampling frequency of the processing blocks – it defines the ratio between them. For example, let’s say that we successfully generated the HDL code for our FPGA and that we connected a 20 MHz clock. The counter will run at 20 MHz, the tone at 10 MHz, and in the end an interleaved tone of 100 kHz will be sent to the ZeptoSDR radio card’s DACs. If you change the sample time of the tone to 124 and the counter to 62, the generated HDL code and the results would be the same, as it’s the ratio that’s important.
In the next post in this series, we will use our model to start the HDL code generation process.