• AVR Freaks

Hot!Code Generated for Fixed Point numbers

Author
FilippoMonti
Starting Member
  • Total Posts : 31
  • Reward points : 0
  • Joined: 2017/11/03 03:10:15
  • Location: 0
  • Status: offline
2019/04/01 01:59:53 (permalink)
0

Code Generated for Fixed Point numbers

Dear Lubin and Forum users,
 
I am generating the code for dsPIC from a project done in Simulink.
For speedness of the dsPIC I use mainly fixed point numbers. Then I have read the generated code and something seems strange in the fixed point numbers coding.
 
For example, having in Simulink a signal ufix16_15 (i.e. unsigned 16bit with 15 as fraction length):
 
     - I should suggest that the word length is 16, then the fractional part is 15 and the "integer" part is 1
           i.e.    1.111111111111111
     - But, in the generated code I have found this:
 
  rtb_DiscreteTimeIntegrator1_o1 = rtDW.ADC_o2 << 15;   
       
The complete function in simulink is to convert the ADC reading in ufix(16,15) and then I have set two constraints: if the signal is >0.8 the output is high and if the signal < 0.5 the output is low. The complete code is:
 
rtb_DiscreteTimeIntegrator1_o1 = rtDW.ADC_o2 << 15;   
                                                                                                          
   if (rtb_DiscreteTimeIntegrator1_o1 >= 26214U) {             //>0.8
                    rtDW.Relay3_Mode = true;
                  }
else {
                    if (rtb_DiscreteTimeIntegrator1_o1 <= 16384U) {         //<0.5
                      rtDW.Relay3_Mode = false;
                    }
                  }
 
As you can see, in the code it only performs a left shift of 15.
--> So that the resulting number is a 16+15=31bit number. It seems a strange manage of the fixed point numbers.
 
Is the generated code correct? Can someone explain me better the conversion?
 
Thank you.
 
Filippo
 
 
 
#1
Gort2015
Klaatu Barada Nikto
  • Total Posts : 3122
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: Code Generated for Fixed Point numbers 2019/04/01 02:35:24 (permalink)
0
Why not use the dsPic accumulators A and B?
If 16bit then bit 14 can be tested to check if a number is smaller or greater than 0.5
 
What are the types?
 
Original value before shift?
rtb_DiscreteTimeIntegrator1_o1 = rtDW.ADC_o2
post edited by Gort2015 - 2019/04/01 02:36:31

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#2
Lubin
Moderator
  • Total Posts : 359
  • Reward points : 5
  • Joined: 2007/03/31 07:38:15
  • Location: Bayonne, France
  • Status: offline
Re: Code Generated for Fixed Point numbers 2019/04/01 03:02:00 (permalink)
0
Hi Filippo,
 
Simulink handling of fractional datatype is working great (using it for many years, never encountered issue with datatype handling yet)
Let try providing a shed light on datatype representation with simulink.
 
You perform an ADC conversion and expect a fractional output.
The ADC block is configured for signed conversion with left align of the result (or should be set like this).
 
Note that whatever the ADC block configuration, its output is always a pure integer: the ADC peripheral output conversion register.
Your signed left aligned result is within +-32767/8. (with 4 or 8 LSB set with 0)
 
You must indicate your model that this output represents a fractional "Q1.15".
==> add the Data type Converter block after the ADC block.
1) You are modifying the representation: select "Stored Integer" instead of Real Word Value. The bitfield is not modified (not converted)
2) Specify the datatype it represents.
The datatype converter block output is a fractional which represent values within +-1 (roughly).
 
Now your ADC output through the Conversion block provide values within [-1 1] ; you can perform the comparisons with the values 0.5 and 0.8.
 
Note that in the generated code, everything is handled as integer. 
Simulink will handle any shift required in an efficient way (in your case here, you should not see any shift).
 
You benefit from fractional representation at Simulink design level, and efficient code generated underneath.
 
A side remark: you might directly make the datatype converter block output to represent your physical value. If it is volt, setting the slope (value of the LSB) to 3.3/65535 and your output datatype represent Volts (with no calculation time cost so far).
 
You might post your model if you still encounter issue. Simulink docs might provide examples with datatypes.
Maybe the fixed-point toolbox is required to do advanced things with datatype.
 
Lubin
 
#3
FilippoMonti
Starting Member
  • Total Posts : 31
  • Reward points : 0
  • Joined: 2017/11/03 03:10:15
  • Location: 0
  • Status: offline
Re: Code Generated for Fixed Point numbers 2019/04/01 04:27:54 (permalink)
0
Dear Lubin and Gort2015,
 
I am just trying to understand the coding of fixed point numbers. To do so, I am trying with simple and meaningless Simulink projects to generate code and trying to understand it.
 
For example, in the attachments you can find an example.
Here, I obtain this code that I do not understand well:
 
dsPIC_PWM_3phase_CodeGen_01_B.Gain6 = (uint16_T)((rtb_LogicalOperator << 13) * 13999L >> 14);
 
The shift seems related to the fractional part of the type Q2.14, isn't it?
Can you better explain this code generated from Simulink?
The number 13999 is the number I have in the gain blocks, it is the PWMmax constant.
 
For Gort2015: the original value was 16bit signal coming from the ADC.
 
Thank you.
 
Filippo

Attached Image(s)

#4
crosland
Super Member
  • Total Posts : 1582
  • Reward points : 0
  • Joined: 2005/05/10 10:55:05
  • Location: Bucks, UK
  • Status: offline
Re: Code Generated for Fixed Point numbers 2019/04/01 06:14:57 (permalink)
1 (1)
Gort2015
Why not use the dsPic accumulators A and B?
If 16bit then bit 14 can be tested to check if a number is smaller or greater than 0.5

It's generated code, I doubt to OP has that option. You need to address your suggestion to the people who write the PIC code generator for Simulink.
#5
Lubin
Moderator
  • Total Posts : 359
  • Reward points : 5
  • Joined: 2007/03/31 07:38:15
  • Location: Bayonne, France
  • Status: offline
Re: Code Generated for Fixed Point numbers 2019/04/01 11:06:26 (permalink)
0
Hi Filippo

Your ADC is configured for unsigned 10 bit conversion with right aligned result (integer).
 
 You want the input voltage range [0 3.3]v to be represented by values in [0 1] within your simulink model , use for the convert the datatype fixdt (0,16,10)
 
Playing with datatype within simulation models might help understanding Simulink datatype representation. Once your simulation is ok, the generated code is also ok. You might simulate your ADC output swiht with a simple Counter Free-Running set with 10 bits. 

Lubin
#6
Jump to:
© 2019 APG vNext Commercial Version 4.5