Main Content

Field-Oriented Control of a Permanent Magnet Synchronous Machine on a Xilinx Zynq Platform

This example models a field-oriented controller (FOC) for a permanent magnet synchronous machine (PMSM) on the Xilinx® Zynq®- UltraScale+™ MPSoC target. This example uses the Trenz Electronic™ Motor Control Development Kit TE0820 revision 4. If you do not have the required hardware, you can use this example to help you develop a controller for your own hardware configuration.


For more information about the hardware, see Trenz Electronic Motor Control Development kit support from Simulink.


This image shows the general process of creating, simulating, and deploying a design of a controller algorithm onto an embedded hardware board.

You simulate a system test bench to gain insight into the behavior of the controller algorithm design. Explore the design to see how the algorithm is partitioned. The high-rate portion of the algorithm is partitioned into a model that is configured for HDL code generation. The low-rate portion of the algorithm is partitioned into a model that is configured for C code generation. Generate C and HDL code from these models and learn how you can integrate this code into your design.

You can automate deployment of the algorithmic code into reference frameworks for the processor and programmable logic. Then, execute a test on the deployed application, log the results, and compare them to the simulation results.

Set up the Xilinx Zynq hardware board before starting the example. This example deploys a bitstream and ARM® executable to a Xilinx Zynq device. To ensure the correct setup of your environment, complete the Getting Started with Targeting Xilinx Zynq Platform example with your hardware configuration before starting this example.

Simulate Algorithm Behavior

First. open the example project, inspect the controller models, and verify the controller behavior through simulation. This example is packaged as a project. For more information on Simulink® projects, see What Are Projects?

1. Open the example project by entering this command at the MATLAB® command prompt.


2. Click the Project Shortcuts tab to view the shortcuts to the files and folders that this example uses.

3. Run task.t1_openSimulationTestBenchModel to open the focZynqTestBench model.


The Motor_And_Load subsystem consists of a mathematical model of a surface PMSM, motor load, encoder, and current sensor. The Controller_Algorithm subsystem includes:

  • I/O engineering unit conversion

  • Electrical position calculation

  • Rotor velocity calculation

  • Mode scheduler, and four control modes: disabled, open loop velocity control, encoder calibration, and closed loop velocity control.

The C/D and D/C subsystems convert the data from continuous- and variable-time step solvers and floating-point data types to discrete- and fixed-time step solvers and fixed-point data types.

If you do not have the Specialized Power Systems Library in Simscape™ Electrical™ installed, the Motor_And_Load subsystem contains a block that enables you to simulate the model with default motor and load parameters. In this case, you are not able to explore or modify parameters.

4. On the Simulation tab click Run to simulate the model.

5. After simulation completes, open the Simulation Data Inspector. On the Simulation tab, click Data Inspector. For more information on the Simulation Data Inspector, see Simulation Data Inspector.

6. In the Simulation Data Inspector, select the <commandType>, <velocityCommand>, <rotorVelocity>, and <controllerMode> signals.

For the first two seconds, the controller receives commands to calibrate the encoder position sensor. The encoder position sensor must be calibrated before the controller can achieve closed-loop control. During the first portion of position calibration, the motor accelerates using open-loop control to identify the index pulse of the encoder. After the index is found, the controller commands and holds a zero position until the encoder offset is identified. During this period, the velocity is zero. After two seconds, the controller changes into closed-loop control and follows the commanded velocity profile. During closed-loop velocity control, the FOC regulates phase current in the PMSM.

Partition Controller Algorithm and Generate Code

Next you partition the controller algorithm into complementary software and hardware implementations by generating C and HDL code for the software and hardware implementations, respectively. The reports created during code generation show how you can integrate this code into your own embedded design.

1. In the focZynqTestBench model, open the Controller_Algorithm subsystem. The controller algorithm contains the Algorithm_C and Algorithm_HDL blocks, which reference the focZynqC and focZynqHDL models, respectively. The focZynqC model contains the portion of the algorithm to be implemented in software. The focZynqHDL model contains the portion of the algorithm to be implemented on the hardware.

2. Run the task.t2_generateCCode function to open the focZynqC model, generate C code, and generate a report.


The focZynqC model contains the mode scheduler, velocity control loop, open-loop velocity controller, and a routine that automatically calibrates the encoder offset.

3. The code generation report shows how the generated code corresponds to the model. Click Code Interface Report to view the function interface of the code. The C code is portable and can integrate with any floating-point embedded processor that uses ANSI-C compiler. For more information on the Code Generation Report, see Reports for Code Generation (Embedded Coder).

4. Run the task.t3_generateHdlCode function to open the focZynqHdl model, generate HDL code, and generate a report.


The focZynqHdl model contains the electrical position calculation, rotor velocity calculation, over-current checks, and the field-oriented controller.

5. The code generation report shows how the HDL code corresponds to the model. Under Generated Source Files select the focZynqHdl.vhd file, which contains the entity specification. The HDL code for the algorithm is portable and can integrate with any FPGA that supports VHDL® code.

Set Up Xilinx Zynq Platform and Motor Boards

Next, set up and connect the hardware boards.

1. Run the hardware setup for the Xilinx Zynq platform. For information on the hardware setup, see Install Support for Xilinx Zynq Platform (Embedded Coder). You must install both Embedded Coder® Support Package for Xilinx Zynq Platform and HDL Coder™ Support Package for Xilinx FPGA and SoC Devices.

2. Connect the Trenz board as shown in the image.

The image shows these components:

  1. 5V DC power supply

  2. SD card

  3. Micro USB cable for UART and JTAG

  4. Ethernet connector

  5. Encoder connector

  6. 24 V DC power supply

  7. Motor power cable (A, B, C)

  8. 24 V brushless DC motor

  9. Switch 1 (S1), which controls power to the driver board

3. Ensure that jumper J4 on the carrier module is set to SD and J3 on the motor driver card is set up for a single ended encoder.

4. Insert the encoder cable according to the picture below. For more information on the jumper settings, visit the Trenz Electronic website.

5. Download the Trenz TE0820 Linux® Image, extract the ZIP archive, and copy the contents to the microSD card. Insert the microSD card in connector J8.

6. After you program FPGA bitstream, press the S1 switch located on the motor driver card once to connect the 24V to the MOSFETS. In case of any unexpected behavior from the device, use the S1 switch to disconnect the power.

Deploy Bitstream to Programmable Logic

Next, use the HDL Workflow Advisor to generate HDL code for the algorithm, package the HDL into an IP core, integrate the IP core into a Xilinx reference design, and create a bitstream. The path to the reference design used in this example is added automatically when you open the project if the HDL Coder Support Package for Xilinx FPGA and SoC Devices was already installed. Alternatively use this command to add the reference design files to your path:

addpath(genpath(fullfile(hdlcoder_amd_examples_root, 'TE0820FOC')));

1. Run the task.t4_openHdlWorkflowAdvisor function to open HDL Workflow Advisor.


2. In the HDL Workflow Advisor in the 1. Set Target > 1.1 Set Target Device and Synthesis Tool group, set the Target platform to Trenz TE0820 with CR00140. Trenz TE0820 with CR00140 is a Vivado® reference design that contains the ADC, encoder, and PWM components. For information on this reference design, see Define Custom Board and Reference Design for Zynq Workflow.

3. Select 1.2. Set Target Interface to identify the ports. The entries in the Target Platform Interfaces column of the table that have the prefix IP refer to connections that are registered with the Trenz motor control reference design.

4. Select 4.3 Build FPGA Bitstream > Run to Selected Task or run the task.t5_generateBitstreamAndInterfaceBlock function from the project to generate the HDL code for the algorithm and create the FPGA bitstream from the Xilinx reference design.


5. Follow the progress of bitstream generation in the DOS Command Prompt window. In addition to generating a bitstream the customized target generates the focZynqHdlAxiInterfaceLib software interface library. The library contains an AXI_Interface block. The AXI_Interface block, which contains the AXI4-Lite interface components, provides connectivity from the model deployed on the ARM processor to the model deployed on the programmable logic.

6. Run task 4.4 Program Target Device or run the task.t6_downloadBitstream function from the project to program the FPGA:


Deploy Executable to ARM processor

Next, generate C code for the controller and integrate this code with a Linux® reference framework to build, deploy, and run the model as an executable to the ARM processor. Data logged from the model running on the processor can then be compared to the results of the simulation.

1. Run the task.t7_openZynqArmModel function to open the focZynqArmDeployment model.


The focZynqArmDeployment model can generate C code, automate the integration with a Linux ARM reference framework, and deploy the executable to the ARM processor on the Xilinx Zynq platform. The deployment model references the original controller model and contains the test stimulus, scope, and AXI_Interface library block created in the Deploy Bitstream to Programmable Logic section.

2. On the Hardware tab, click Monitor & Tune to build, deploy, and run the model as an executable on the ARM processor. The generated code is compiled against the reference framework to create an executable. While executing, Simulink monitors the signals and shows them in the Scope block.

3. Open the Simulation Data Inspector to view the logged signals and compare them to the signals logged previously from focZynqTestBench model. On the Simulation tab, click Data Inspector.

4. In the Simulation Data Inspector, select the rotorVelocity signal. During the encoder calibration mode, the signals initially differ because the simulated and real motors started with different rotor positions. In contrast, the closed-loop velocity control from the simulation and hardware are very similar. Differences occur because the simulation model of the motor and sensors use data sheet values and do not explicitly account for the manufacturing tolerances of the physical motor.

Related Topics