SPRADD8 November   2024 F29H850TU , F29H859TU-Q1

 

  1.   1
  2.   Abstract
  3.   Trademarks
  4. 1Introduction to Real-Time Control
  5. 2C29 CPU and Key Features
    1. 2.1 Parallel Architecture and Compiler Entitlement
  6. 3C29 Performance Benchmarks
    1. 3.1 Signal Chain Benchmark with ACI Motor Control
    2. 3.2 Real-time Control and DSP Performance
      1. 3.2.1 Examples and Factors Contributing to Results
        1. 3.2.1.1 Saturation (or Limiting) Example
        2. 3.2.1.2 Dead Zone Example
        3. 3.2.1.3 Space Vector Generation (SVGEN) Example
        4. 3.2.1.4 Software Pipelining
      2. 3.2.2 Customer Control and Math Benchmarks
    3. 3.3 General Purpose Processing (GPP) Performance
      1. 3.3.1 Examples and Factors Contributing to Results
        1. 3.3.1.1 Discontinuity Management
        2. 3.3.1.2 Switch() Example
    4. 3.4 Model-Based Design Benchmarks
    5. 3.5 Application Benchmarks
      1. 3.5.1 Single Phase 7kW OBC Description
      2. 3.5.2 Vienna Rectifier-Based Three Phase Power Factor Correction
      3. 3.5.3 Single-Phase Inverter
      4. 3.5.4 Machine Learning
    6. 3.6 Flash Memory Efficiency
    7. 3.7 Code-size Efficiency
  7. 4Summary
  8. 5References

Saturation (or Limiting) Example

Saturation type code commonly occurs in real-time applications. shows a summary of two different ways saturation is implemented in C.

The code block below shows the if..else based approach to implementing saturation. The C29 (11 cycles, independent of input) outperforms the Cortex-M7 (14-27 cycles, dependent on input). On the C29, the if() is implemented through a conditional branch instruction (BC), and for the remaining two paths (the elseif and else), a compare (CMPF) followed by a conditional instruction (XCP) is used, thus avoiding branches.

volatile float in;
volatile float out; 
const float max =1.0f;
const float min = -1.0f; 
if(in > max) 
 out = max; 
else if(in < min) 
 out = min; 
else 
 out = in; 

C29 Implementation
LD.32  M1,@in 
||ONEF M0   
CMPF   TDM0,M.GT,M1,M0  
ONEF   M1   
|| BC   @($LBB0_2),TDM0.NZ   
LD.32  M1,@in   
|| NEGONEF M2   
CMPF   TDM0,M.LT,M1,M2  
XCP    #0x1,TDM0.Z   
|| LD.32 M1,@in  
SELECT TDM0,M1,M2,M1  
$LBB0_2:
ST.32 @out,M1  

M7 Implementation
MOVW R0,#in2
MOVT R0,#in2   
MOVS R1,#+1   
MOVT R1,#+16256   
VLDR S0,[R0, #0]   
VMOV S1,R1   
VCMP.F32 S0,S1   
FMSTAT  
BLT.N saturation_0  
MOV R2,#+1065353216  
STR R2,[R0, #+4]   
B   saturation_2
saturation_0:   
VMOV.F32 S0,#-1.0   
VLDR  S1,[R0, #0]   
VCMP.F32 S1,S0   
FMSTAT  
BPL.N saturation1_1  
VSTR S0,[R0, #+4]   
B  saturation_2   
saturation_1:
LDR R1,[R0, #+0]   
STR R1,[R0, #+4]   
saturation_2:

The code block below shows the ternary operator '?' based approach to implementing saturation. The C29 (three cycles, independent of input) outperforms the Cortex-M7 (18-22 cycles, dependent on input), through the MINMAXF instruction without any branches.

volatile float in;
volatile float out; 
const float max =1.0f;
const float min = -1.0f;

float temp = in; 
temp = (temp > max)? max: ((temp < min)? min: temp); 
out = temp; 

C29 Implementation
ONEF    M0  || LD.32 M1,@in  || NEGONEF M2 MINMAXF M1,M0,M2 ST.32   @out,M1  

M7 Implementation
MOVW R0,#in2
MOVS R1,#+1   
MOVT R0,#in2   
MOVT R1,#+16256   
VMOV S2,R1   
VLDR S0,[R0, #0]   
VCMP.F32 S0,S2   
VMOV.F32 S1,S0   
FMSTAT  
IT  GE   
VMOVGE.F32 S1,#1.0   
BGE.N saturation_0  
VMOV.F32  S2,#-1.0   
VCMP.F32  S0,S2   
FMSTAT  
IT  MI   
VMOVMI.F32 S1,S2   
saturation_0:
VSTR  S1,[R0, #+8]   
Attention:

The C29 compiler is enhanced to generate equal performance regardless of the if..else or the ternary operator based approaches.

|| denotes instructions occurring in parallel with the above instructions.