Inverter Model

  • IP-Core of a 3 phase inverter

  • Simulates the inverter on the FPGA

  • Intended for controller-in-the-loop (CIL) on the UltraZohm

  • IP-Core clock frequency must be \(f_{clk}=100\,MHz\)!

Model Description

The Simscape model of the inverter is shown in the figure below. While in the light blue areas, only the inputs are handled (mainly switching between PS and PL inputs depending on the configuration) and in the yellow area the ouputs are realized, the central part of the model is placed in the dark blue areas. The power electronics part is modelled with six N-channel MOSFET from the Simscape parts library. Note that their electrical parameters are listed in the table below and can only be changed in the Simscape model but not after the IP-core generation. The MOSFETs are placed to model three half bridges (HB) and each of the switches can be controlled individually. There is no logic implemented to prevent short circuits, if top and bottom switch of one HB are closed simultaneously. Because the physical references of the Simscape model will be lost after the IP-core generation, the two controlled currents sources from phases a and b to phase c are placed. The usage of the IP-core demands the user to feed back the actual flowing currents in the current application to the inverter for it to determine the voltage drop across the switches and diodes. If the user does not feed back any currents or sets the feedback to zero, no voltage drops will be considered for the ouput voltage. The voltages are output as line-to-line voltages \(u_{ab},u_{bc},u_{ca}\).


Fig. 139 Overview of Simscape inverter model uz_inverter_3ph.slx

Table 31 Parameter Switch (MOSFET and body diode)




on resistance MOSFET


\(0.01 \Omega\)

off conductance MOSFET


\(1 \cdot 10^{6} S\)

threshold voltage MOSFET


\(0.5 V\)

on resistance diode


\(0.001 \Omega\)

off conductance diode


\(1 \cdot 10^{-5} S\)

threshold voltage diode


\(0.8 V\)

IP-Core Interfaces

Table 32 IP-core Interfaces Switch

Port Name

Port Type

Data Type







AXI 0x100

true: gate signals from PS; false: gate signals from PL




AXI 0x104

true: current values from PS; false: current values from PL



single (3)

AXI 0x110-0x118

input current values from PS in the form of uz_3ph_abc_t



sfix27_En18 (3)

External Signal

-256 to +255

input current values from PL in the form of uz_3ph_abc_t



boolean (6)

AXI 0x140-0x154

input gate signals from PS in the form of uz_inverter_3ph_gate_ps_t



ufix1 (6)

External Signal

0 to 1

input gate signals from PL in the form of uz_inverter_3ph_gate_ps_t




AXI 0x108

set DC link voltage



single (3)

AXI 0x170-0x178

output voltage values to PS in the form of uz_3ph_abc_t (note: line-to-line voltages \(u_{ab};u_{bc};u_{ca}\)!)



sfix27_En16 (3)

External Signal

-1024 to +1023

output voltage values to PL in the form of uz_3ph_abc_t (note: line-to-line voltages \(u_{ab};u_{bc};u_{ca}\)!)

Driver Reference

typedef struct uz_inverter_3ph_t uz_inverter_3ph_t

Object data type definition of the inverter model IP-Core driver.

struct uz_inverter_3ph_config_t

Configuration struct for the Inverter model IP-Core driver.

Public Members

uint32_t base_address

Base address of the IP-Core instance to which the driver is coupled

uint32_t ip_core_frequency_Hz

Clock frequency of IP-Core

bool switch_pspl_abc

True: use currents from PS, False: use currents from PL

bool switch_pspl_gate

True: use gate signals from PS, False: use gate signals from PL

float udc

Value of DC bus voltage

struct uz_inverter_3ph_gate_ps_t

Struct to pass gate signals to the inverter Model.

Public Members

float gate1

Gate 1 signal: HB1T

float gate2

Gate 2 signal: HB1B

float gate3

Gate 3 signal: HB2T

float gate4

Gate 4 signal: HB2B

float gate5

Gate 5 signal: HB3T

float gate6

Gate 6 signal: HB3B

uz_inverter_3ph_t *uz_inverter_3ph_init(struct uz_inverter_3ph_config_t config)

Initialize an instance of the driver.

  • config – Config struct


uz_inverter_3ph_t* Pointer to an initialized instance of the driver

uz_3ph_abc_t uz_inverter_3ph_get_u_abc_ps(uz_inverter_3ph_t *self)

Returns outputs.

  • self – Pointer to driver instance


get output voltages as line-to-line in the struct uz_3ph_abc_t

void uz_inverter_3ph_set_i_abc_ps(uz_inverter_3ph_t *self, uz_3ph_abc_t i_abc)

Set inputs of the model and write them to the Inverter model IP-Core.

  • self – Pointer to driver instance

  • i_abc – set flowing currents if switch_pspl_abc is true

void uz_inverter_3ph_set_gate_ps(uz_inverter_3ph_t *self, struct uz_inverter_3ph_gate_ps_t gate_signal)

Set inputs of the model and write them to the Inverter model IP-Core.

  • self – Pointer to driver instance

  • gate_signal – set gate signals if switch_pspl_gate is true

void uz_inverter_3ph_trigger_u_abc_ps_strobe(uz_inverter_3ph_t *self)

Takes the values of the AXI shadow register and pass them to the actual output.

  • self – Pointer to driver instance

void uz_inverter_3ph_trigger_i_abc_ps_strobe(uz_inverter_3ph_t *self)

Takes the values of the AXI shadow register and pass them to the actual input.

  • self – Pointer to driver instance

void uz_inverter_3ph_trigger_gate_ps_strobe(uz_inverter_3ph_t *self)

Takes the values of the AXI shadow register and pass them to the actual input.

  • self – Pointer to driver instance

Example Usage

The inverter IP-core can be used in several different ways because the inputs and outputs can be accessed from PS or PL individually. For this example only the access via PS is shown. Using the IP-core in PL mainly demands the usage of other IP-cores to provide the inputs and utilize the outputs which is shown in Multi-phase PMSM Model. To use the IP-core with the PS only, the PL inputs do not need to be connected, although the u_abc_pl in the figure below is connected to an ILA in the greyed area. This is not necessary and only done for verification purposes.


Fig. 140 Placement of the IP-core in Vivado for PS only access

The following code is used in main.c (initialization) and isr.c (application):

Listing 168 initialization in main.c (R5)
#include "IP_Cores/uz_inverter_3ph/uz_inverter_3ph.h"
uz_inverter_3ph_t *inverter=NULL;
struct uz_inverter_3ph_config_t inverter_config = {   // example config values
  .ip_core_frequency_Hz = 100000000.0f,
  .switch_pspl_abc = true,
  .switch_pspl_gate = true,
  .udc = 560.f};

// .. rest of the code in main.c before loop
int main(void)
// ..
  case init_ip_cores: // default line from main.c
  inverter = uz_inverter_3ph_init(inverter_config);
Listing 169 usage in isr.c
#include "../IP_Cores/uz_inverter_3ph/uz_inverter_3ph.h"
extern uz_inverter_3ph_t *inverter;                              // pointer to Inverter object
uz_3ph_abc_t out_voltages = {0};                                 // stores output voltages
uz_3ph_abc_t in_currents = {                                     // stores flowing currents (made up values for this example)
  .a = 10,
  .b = 10,
  .c = 10};
struct uz_inverter_3ph_gate_ps_t gate_signals = {
  .gate1 = true,
  .gate2 = false,
  .gate3 = false,
  .gate4 = true,
  .gate5 = false,
  .gate6 = true};

// .. rest of the code in isr.c before loop
void ISR_Control(void *data)
// ..
  update_speed_and_position_of_encoder_on_D5(&Global_Data);      // default line from isr.c

  uz_inverter_3ph_set_gate_ps(inverter,gate_signals);            // set example gate values
  uz_inverter_3ph_set_i_abc_ps(inverter,in_currents);            // set example currents
  uz_inverter_3ph_trigger_gate_ps_strobe(inverter);              // write values to PL
  uz_inverter_3ph_trigger_i_abc_ps_strobe(inverter);             // write values to PL
  uz_inverter_3ph_trigger_u_abc_ps_strobe(inverter);             // read values from PL
  out_voltages = uz_inverter_3ph_get_u_abc_ps(inverter);         // read output values to voltages struct

The values of the variable out_voltages from the example is shown below and matches the Simulink model.

\[\begin{split}\begin{align} out-voltages = \begin{bmatrix} u_{ab} \\ u_{bc} \\ u_{ca} \end{bmatrix} = \begin{bmatrix} 559.9999 \\ -0.3000183 \\ -559.6998 \end{bmatrix} \end{align}\end{split}\]


“Troubleshoot conversion of simscape permanent magnet synchronous motor to hdlcompatible simulink model.” [Online]. Available: