Imperix firmware IP product guide
Table of Contents
This page documents the imperix firmware IP for Xilinx Vivado, which contains the imperix FPGA logic of the imperix controllers (the B-Box RCP and the B-Board PRO).
The imperix firmware IP enables the user to:
- Exchange data between the application control code running in the CPU (PS) and the logic in the FPGA (PL);
- Drive the PWM output chain, comprised of a dead-time generation system and the hardware protection mechanisms;
- Retrieve ADC conversion results as soon as they are available, directly from within the FPGA;
- Have direct access to physical I/Os pins such as USR, GPI and GPO pins.
Requirement to use the imperix firmware IP
- It is required to install Xilinx Vivado Design Suite to use the imperix firmware IP
- The imperix IP is provided in the sandbox sources available from the download page
- The getting started with FPGA control development page explains how use the imperix firmware IP in a Vivado project
- To exchange data with the FPGA and configure the PWM outputs, the necessary drivers are included in ACG SDK (graphical programming) and CPP SDK (C++ programming)
- A custom SPI communication interface for an A/D converter is presented in TN130.
- FPGA-based hysteresis current control is presented in TN120. The same application is also addressed in TN121, which relies on automated HDL code generation using Matlab HDL Coder.
- Automated code generation using Xilinx Vivado HLS is addressed in TN133. This note uses the Direct Torque Control (DTC) of a synchronous motor as the application example.
The imperix firmware IP
The B-Board is based on a Xilinx Zynq XC7Z030 System-on-Chip which consists of a Processing System area (PS) with two CPU cores and a Programmable Logic (PL) area.
- CPU0: Running on Linux, the first core is responsible for loading the application code, supervising the system execution and managing the data logging.
- CPU1: Running on BBOS (lightweight secured proprietary operating system), the second core executes the application-level control code developed by the user.
- FPGA: The PL contains all the application-specific peripherals.
The fixed part of the FPGA firmware containing the pre-implemented peripherals is packaged in the imperix firmware IP. This IP also provides interfaces to the user as illustrated by the user-programmable FPGA area on the image.
The imperix firmware IP is designed such that it provides interfaces for implementing special user HDL logic in the so-called sandbox. It gives access to some of the I/Os (ADC, PWM,…) as well as ways to exchange data with the CPU (SBI, SBO).
The content of the imperix firmware IP is obfuscated and cannot be either read or edited.
IP port descriptions
This section describes the ports of the imperix firmware IP.
Digital I/Os drivers
These ports drive the physical-digital I/Os of the B-Board. The description of the peripherals driving these ports and the physical location of their I/Os are available in the B-Board datasheet.
|output||Pulse-width modulated outputs|
These ports are necessary to communicate with the various components on the B-Board. Modifying these connections could alter the proper behavior of the device.
The user interfaces include data ports and timing signals to exchange data with the CPU, drive PWM outputs, and access ADC value.
|output||ADC 16-bit result in 2’s complement format. If in a B-Box, registers 00 to 15 hold the results the B-Box (external) ADCs. Otherwise, registers 00 to 07 hold the results of the B-Board on-board ADCs and registers 08 to 15 return zero.|
|output||Output to the Sandbox, registers used by the CPU to send data towards the FPGA. The user can write to these registers from C++ drivers or graphical blocksets.|
|input||Input from the Sandbox, registers used by the FPGA to send data to the CPU. The user can read to these registers from C++ drivers or graphical blocksets.|
|output||Indicates the timer period of the CLOCK.|
|output||Indicates the prescaler division value of the CLOCK.|
|output||Clock enable generated by the prescaler, provides the counting rate of |
|output||Timer counting from 0 to |
|output||Asserted for the duration of the READ phase, signaling that |
|output||Asserted for one clock period at each ADC sampling instant.|
|output||Asserted for one clock period at the end of the configuration phase (end of system startup sequence). It may be used as a synchronous reset. In the case where multiple B-Boards (B-Boxes) are connected, this pulse occurs simultaneously in all devices and can be used to synchronize counters.|
|input||User firmware identification number. When a customized firmware is loaded, this number is sent to Cockpit and is available from the Target config window in the FPGA bitstream section. It can be used to ensure that the correct firmware has been loaded.|
|output||Asserted when the B-Board is in a B-Box, cleared otherwise.|
Understanding the real-time behavior of the firmware
A proper understanding of the system behavior during real-time execution is necessary to correctly develop and integrate custom logic in the B-Board FPGA.
The four phases of a control cycle
The next figure is a simplified representation of the elements involved in the real-time execution of the control algorithm on an imperix controller. It shows the four phases constituting a control cycle, which are:
- ACQ: Analog-to-digital conversion (physical chips) and results acquisition (transfer to FPGA);
- READ: Real-time DMA read, FPGA data flagged as real-time are sent to the CPU read buffer;
- PROCESSING: Execution by the CPU of the main control task, processing the user control code. At the beginning of this phase, the CPU read buffer is read. At the end, the CPU write buffer is updated.
- WRITE: Real-time DMA write, data flagged as real-time are transferred from the CPU write buffer to the FPGA peripherals (across the network of multiple B-Boards if needed).
To learn more about the various delays involved when running an imperix digital controller please read the discrete control delay identification page.
Four ports of the imperix firmware IP provide timing information, as shown in the next figure. The ACQ phase starts with the assertion of
sampling_pulse and ends with the assertion of
adc_done_pulse, indicating that new ADC values are available in the
ADC registers. A pulse on
read_pulse signals the start of the READ phase when
SBI registers flagged as real-time are sent toward the CPU. At the end of the WRITE phase
data_valid_pulse is asserted notifying that new data is available in the real-time
Configuring the control cycle timings
The control execution rate is configured using the Configuration block. It is also possible to run the analog input sampling faster than the CPU algorithm execution thanks to the oversampling parameter. The image below shows an example where the oversampling is set to evenly distributed with a number of samples per period of 4.
Exchanging data between the CPU and the FPGA
The 16-bit Output towards the SandBox (
SBI) and Input from the SandBox (
SBO) registers allow data exchange between the user control code in the CPU and the user logic in the FPGA. These registers can be read/written using their respective blocks (SBO and SBI).
The getting started with FPGA development page goes into further details on how to exchange data between the CPU and the FPGA through a step-by-step example.
The configuration phase occurs only once at the system startup and aims to initiate FPGA-based peripherals and configure the real-time data traffic, possibly across the control network. During this phase, interrupts and PWM operations are not yet active.
With the ACG SDK, s
BO registers that are only written once are called configuration registers, opposing to real-time registers. The user selects which registers are set as configuration registers from the “Registers” tab of the SBO block and then set up their values from the “Configuration reg. values” tab. When using C++ SDK, the
SBO registers can be read/written during the configuration phase by using
Sbo_WriteDirectly in the
Sbo_WriteDirectlyfunctions infer immediate data transfers, which are performance-wise rather time-consuming and therefore cannot be used during real-time execution.
SBO register as a real-time register indicates that the value of this register is to be transferred at each control task execution. Configuring a register as real-time is done by using the C++ function
In Simulink, real-time registers are clearly distinguished from configuration registers. They take their run-time values from the block inputs.
Before entering the control interrupt, the data that have previously been configured as real-time are retrieved from the FPGA peripherals and placed into the CPU read buffer (READ phase). As such, they can readily be used from inside the control interrupt using
Reciprocally, using the
Sbo_Write function inside the control interrupt stores data into the write buffer, waiting to be sent back to the FPGA once the interrupt is completed (WRITE phase).
In Simulink real-time data can be easily manipulated using signal wires.
Retrieving ADC conversion results
Inside the FPGA, ADC results are available from the
ADC interface of the firmware IP. The port
sampling_pulse indicates the start of an ADC conversion and
adc_done_pulse indicates that the results are available in the
ADC interface. The conversion 16-bit results are in 2’s complement format.
Driving PWM outputs
On the firmware IP, the
sb_pwm[31:0] port provides access to the same PWM output chain as that used by other modulators (CB-PWM, PP-PWM, DO-PWM and SS-PWM). This allows the user to generate complementary signals with dead-time, use the standard activate and deactivate functions and rely on the protection mechanism that blocks PWM outputs when a fault is detected. A use example is available on the page Custom PWM modulator implementation in FPGA.
The PWM chain can be configured using the C++ function from
Code language: C++ (cpp)
void SbPwm_ConfigureOutputMode(tPwmOutput output, tPwmOutMode outMode, unsigned int device=0); void SbPwm_ConfigureDeadTime(tPwmOutput output, float deadTime, unsigned int device=0); void SbPwm_Activate(tPwmOutput output, unsigned int device=0); void SbPwm_Deactivate(tPwmOutput output, unsigned int device=0);
or using the corresponding Simulink SB-PWM block.
Each bit of the
sb_pwm[31:0] IP port corresponds to a PWM lane.
sb_pwm: lane #0
sb_pwm: lane #1
sb_pwm: lane #2
sb_pwm, etc.). An example of such a configuration is available in TN120.
pwmport as this would bypass the enable/disable mechanism! Instead, the SB-PWM port is meant to provide proper access to PWM outputs, which should be used in all cases.
On B-Box RCP, this is only relatively sensitive as hardware protections exist. However, on B-Board PRO, this is critical since this mechanism also handles the fault management !