Thursday, July 22, 2010

DDS in System Generator: how to set up periods?

If you use DDS Compiler in System Generator, you will notice there are 4 clock periods you need to deal with (circled in red in the snapshot below). This can be confusing for first time users. Hopefully this blog can clear up some of the confusions.

  1. FPGA clock period (ns): only used for FPGA synthesis and implementation. This value does NOT affect simulation in Simulink (i.e. it will NOT affect output frequency of the DDS block).
  2. Simulink System Period: only used in Simulink simulation. This is the lowest sampling period (highest sampling frequency) among all blocks in the model. There is no significance in its absolute value as long as the sampling periods of all other blocks are multiple of the Simulink System Period. Usually it is set to 1 to keep everything simple. (e.g. every tick in a scope is 1 clock cycle).
  3. DDS System Clock (Mhz): It's used to calculate the phase increment for DDS block (see the DDS datasheet for details). Set it to match the FPGA clock period (i.e. DDS System Clock (Mhz) = 1/FPGA clock period).
  4. Explicit Sample Period: This is the sample period used for the DDS block. IMPORTANT: if you set Simulink System Period to anything other than 1, "Use explicit period" MUST be checked and "Explicit Period" set to the same value as Simulink System period. Otherwise, Simulink will use the sample period of 1 for the DDS core and the output frequency will be wrong. This is likely a bug.
 Let's use a simple model (download the model for test1 here) below to show how all these periods play together in SysGen. The clock frequency of the SineGen block is 1/100th of the Simulink System Period (or 1MHz for a 100MHz clock input).
FPGA clock period (ns) = 10
Simulink system period = 1
DDS System Clock (MHz) = 100
Use Explicit Sample Period checked and Explicit Period = 1
DDS Output (MHz) = 1

As shown in the scope below the DDS output matches the SineGen output:

FPGA clock period (ns) = 10
Simulink system period = 0.1
DDS System Clock (MHz) = 100
Use Explicit Sample Period checked and Explicit Period = 0.1
DDS Output (MHz) = 1

As shown in the scope below the DDS output matches the SineGen output. Note that the Simulink system period is now 1/10th of the period in Test1, so there are 10x more clock cycles in this test with the same simulation time.
FPGA clock period (ns) = 10
Simulink system period = 0.1
DDS System Clock (MHz) = 100
Use Explicit Sample Period unchecked
DDS Output (MHz) = 1

As shown in the scope below the DDS output frequency is 1/10th of SinGen output. The incorrect DDS output frequency is caused by that when "Use Explicit Sample Period" is unchecked Simulink use a sample period of 1 for the DDS block. So it's very important to check this checkbox and set the explicit period to match the Simulink system period if it's not 1. It's worth mentioning that for sampling frequency related issues it's very helpful to turn on "Sample Time Display" (under Format menu) and then update the diagram by pressing CTRL-D. You can easily see if the sample time used for a particular is correct with sampling time displayed on all signals.

Tuesday, July 13, 2010

FFT: Valid Values of Number of Stages Using Block RAM

If you have used the FFT block in System Generator, you probably have seen the error message below.

You've got to love these "you-did-something-wrong-but-I-am-not-gonna-tell-you-how-to-fix-it" error messages. If you read through the datasheet, you will find it's not any better as it asks you to run Core Generator to get the valid values for the FFT transform length you chose. I've gone through this quite a few times, so I put together the table below showing valid values of "Number of Stages Using Block RAM" for all supported FFT sizes (data extracted from CoreGen 12.1) for me to use it as a quick reference. I hope this will also save other people a few minutes by not having to run CoreGen to get this simple info which should have been clearly stated in the error message.

FFT SizeNumber of Stages Using Block RAM

Sunday, July 4, 2010

FFT results from Matlab fft, Bit Accurate C model and SysGen FFT block

The usage of the FFT core is straightforward, however, it does have a lot more knobs to turn compared to a simple fft() function in Matlab. Sometimes when the output from the FFT core doesn't match Matlab fft() result you start to question if there is a bug in the FFT core. I will use a simple example here hopefully to
  • provide some assurance that the result from the FFT core match well with Matlab fft() function and FFT bit accurate C model
  • provide a starting point so you can look at configurations as well as timing of control and data signals of the core in case you didn't have time to read the FFT core data sheet
Below is the SysGen model that uses a 256-point FFT with pipelined streaming IO and unscaled output in natural order. The input vector is a simple ramp (-128:127)/128 in fixed 16.15 format.
The waveform below shows the FFT signals at the beginning of the simulation in WaveScope (a great tool in Xilinx Blockset for debugging, by the way). Note that in FFT v7.0 and newer, there is no longer a requirement of 3 cycle offset between xn_index and xn_re/xn_im inputs.

The waveform below is at the end of FFT computation and data start to unload. Note that xk_index is incrementing as the core output is in natural order.

The simulation results are collected in workspace. A m script is then run to compare the results from Matlab fft(), FFT bit accurate C model, and the Simulink simulation. Below is an overlay plot showing all three outputs, where the difference is negligible.

The script also prints all elements of outputs side by side for easy comparison.

idx    Matlab       Bit Accurate SysGen
0      1.000000     1.000000     1.000000
1      81.489376    81.489504    81.489595
2      40.747756    40.747746    40.747868
3      27.168581    27.168709    27.168739
4      20.380016    20.380048    20.380078
5      16.307697    16.307667    16.307587
251    16.307697    16.307667    16.307545
252    20.380016    20.380048    20.380017
253    27.168581    27.168709    27.168495
254    40.747756    40.747746    40.747960
255    81.489376    81.489504    81.489687

In case you want to play with the example design, you can download it from here. You will need to download the bit accurate C model from FFT core web site yourself because it requires registration.