In this series:

In Part 3 of this series, I show how System Generator provides direct support for the MATLAB language via a special block named MCode. The MCode block accepts as input a MATLAB M-function written in Xilinx’s fixed-point data type. The input ports of the MCode block are defined by input arguments of the M-function while the output ports are defined by the output arguments. This beautiful feature of System Generator enables a designer to easily create the control logic for a finite state machine (FSM) in an efficient manner. Readers can refer to the section “Compiling MATLAB into FPGA” in System Generator’s user guide for more details

[1].

The following sections show how to create an initialization FSM for a moving average (MA) filter using the MCode block in the Simulink environment. An MA filter is a very common method in digital signal processing (DSP) to remove random noise while maintaining a sharp step response for time-domain signals. The basic principle behind an MA filter is the averaging of a number of samples from the input signal to produce one sample of the resulting signal. A mathematical representation of an MA filter is written as follows:

where x[], y[], and M are the input signal, output signal, and average length, respectively. For example, a 4-point MA filter output can be rewritten as follows:

y[1] can be rewritten as follows:

The resulting architecture is very simple. It includes a delay element, an accumulator, a subtraction, and a shift register for scaling, as shown in Figure 1.

Figure 1: MA filter architecture

Figure 1: MA filter architecture

The delay element would be an embedded RAM block in the FPGA or, if a Xilinx FGPA (SRL16) is used, 16-bit shift registers. We need to initialize the delay element to zero to avoiding unexpected results at startup. Thus, the implementation of an FSM is necessary to add zeros to the delay element at reset. Preparing an M-function using Xilinx’s fixed-point data type is required before creating a MCode block.  A code snippet of a simple M-function filling the content of 256 samples-depth SRL16 shift registers is shown in Figure 2.

Figure 2: Filling SRL16 register content on reset with M-function

Figure 2: Filling SRL16 register content on reset with M-function

Creating MCode block

Figure 3 shows the location of the MCode block in the Xilinx Blockset library. We need to point it to the M-function file when it’s dragged into the user project. If there is no error in the M-function, System Generator will automatically map the input/output arguments of the M-function to the input/output ports of the MCode block.

Figure 3: Location of MCode block in library

Figure 3: Location of MCode block in library

Interfacing with other System Generator blocks

The resulting MCode block can connect to the other blocks within the project without any problems. Figure 4 shows the MCode block interfacing with an analog-digital converter (ADC) interface and the MA filter processing in a complete example design. In this figure, the white noise generator is reused from a previous blog post [2] to create white noise at the output of the digital-analog converter (DAC) block of the ADAC250 module [3]. Input to the ADC block is a noisy sine wave (a combination of pure sine wave and DAC output) for simulation purposes only. The reset, run, MA initialization, and output noise gain ports are interfaced with a custom register (CR) on the Perseus 601x platform [4] to enable you to control the design. A simulation result of the MA filter provides a smooth sine wave at the output port of the MA filter, as show in Figure 5.

Figure 4: Interfacing MCode FSM block with other blocks

Figure 4: Interfacing MCode FSM block with other blocks

Figure 5: MA filter simulation result

Figure 5: MA filter simulation result

Hardware testbed

The ADAC250 module stacks on top of the Perseus 601x platform via an FPGA mezzanine card (FMC) connector inside the PicoSDR 2×2 chassis [5], as shown in Figure 6 (the front faceplate has been removed). 16-bit digital white noise samples are converted into an analog signal at the ADAC250 module’s DAC-A port and then combined with a pure sine wave from a signal generator in order to generate the noisy sine wave signal. The resulting filtered 100 kHz sine wave samples (pink) can be seen in the ChipScope, as shown in Figure 7.

Figure 6: MA filter and white noise generator hardware setup

Figure 6: MA filter and white noise generator hardware setup

Figure 7: Noisy (blue) and MA filtered (pink) sine wave samples captured via ChipScope

Figure 7: Noisy (blue) and MA filtered (pink) sine wave samples captured via ChipScope

Conclusion

This blog post described an approach that enables FPGA designers to use the MATLAB M-function to quickly develop FSMs using Xilinx’s fixed-point data type in System Generator. For demonstration purposes, an MA filter with an initialization stage was implemented as an FSM M-function embedded in an MCode block.

References

[1] Xilinx Inc. (2012) System Generator User Guide. [Online]. http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_4/sysgen_user.pdf

[2] Minh-Quang Nguyen. (2014) Xilinx System Generator tips and tricks – Part 2: HDL code reusability. [Online]. http://www.nutaq.com/blog/xilinx-system-generator-tips-and-tricks-%E2%80%93-part-2-hdl-code-reusability

[3] Nutaq Inc. (2014) ADAC250. [Online]. http://www.nutaq.com/products/adac250

[4] Nutaq Inc. (2014) Perseus 601X. [Online]. http://www.nutaq.com/products/perseus-601x

[5] Nutaq Inc. (2014) PicoSDR. [Online]. http://www.nutaq.com/products/picosdr

[6] David Quinn. (2014) Xilinx System Generator tips and tricks – Part 1: An introduction. [Online]. http://www.nutaq.com/blog/xilinx-system-generator-tips-and-tricks-%E2%80%93-part-1-introduction