2023-07-18 08:51 PM
Hello everyone. I want to understand the CORDIC engine, using the nucleo-u575zi board. The guide says that the cordic uses data in q1.31 format. Could please someone explain how to convert results into an ordinary int value? And how to convert an int value into a q1.31 value for loading into the cordic?
Solved! Go to Solution.
2024-05-23 01:58 PM - edited 2024-05-23 02:11 PM
This question is actually multiple questions:
The answer to the first is quite simple: Q1.31 values are ordinary int32_t values. The difference is that their meaning includes an implied division of 2^31. In other words, an integer storing a value in Q1.31 format is storing the numerator of a fraction having a predetermined constant denominator of 2,147,483,648. For example, The number +0.5 = +1/2 = +2^(-1) so it would be encoded in Q1.31 as 2^(-1) * 2^31 = 2^30 = 0x40000000 = = 1,073,741,824. Consequently, zero in Q1.31 format is zero. Negative numbers are slightly trickier, but the key is to recall that the rules are the same as for ordinary (2's compliment) integers. For example, -0.75 = -3/4 = -(2^-1 + 2^-2) and would be encoded in Q1.31 as -(2^-1 + 2^-2) * 2^31 = -(2^30 + 2^29) = -(1,073,741,824 + 536,870,912) = -1,610,612,736 = 4,294,967,296 - 1,610,612,736 = 2,684,354,560 = 0xA0000000.
There's a handy online tool for visualizing this at: https://chummersone.github.io/qformat.html
The answer to the second question depends on the particular function that you want to perform with the CORDIC coprocessor, and you will need to provide more context in order for anyone to give you a suitable answer. Table 194 in RM0456 (reference manual for your STM32U575) shows values input and output for the implemented CORDIC functions. As an example, consider the arctangent function: it's arguments (input) and results (output) are shown in Table 199. In that case, the input 'x' is represents the tangent of some angle (pure/dimensionless number) pre-divided by some 2^k so that its magnitude is less than 1 (and thus can be represented in Q1.31 format). Then the output is a Q1.31 number in units of 2^k * pi radians. For the simple example of arctan(1/2) = 45 degrees = pi/4 radians, x = 1/2 (already less than 1 so k=0, that is, there is no need to scale it down) = 0x40000000 (Q1.31 representation of 1/2) and the expected result would be 0x20000000 (Q1.31) = 1/4 since units are pi radians.
2023-07-19 02:14 AM
Hello @Skfir
If you convert an integer to q1.31 number representation the values > 1 will overflow.
Fixed point number in q1.31 are represented as fractionnal 31 bit value and limit number -1 to 1 as integer part.
Maybe it seems better to perform conversion from float to q1.31 and vice-versa using ARM CMSIS DSP support functions:
https://www.keil.com/pack/doc/CMSIS/DSP/html/group__float__to__x.html
BR
Romain,
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2024-05-23 01:58 PM - edited 2024-05-23 02:11 PM
This question is actually multiple questions:
The answer to the first is quite simple: Q1.31 values are ordinary int32_t values. The difference is that their meaning includes an implied division of 2^31. In other words, an integer storing a value in Q1.31 format is storing the numerator of a fraction having a predetermined constant denominator of 2,147,483,648. For example, The number +0.5 = +1/2 = +2^(-1) so it would be encoded in Q1.31 as 2^(-1) * 2^31 = 2^30 = 0x40000000 = = 1,073,741,824. Consequently, zero in Q1.31 format is zero. Negative numbers are slightly trickier, but the key is to recall that the rules are the same as for ordinary (2's compliment) integers. For example, -0.75 = -3/4 = -(2^-1 + 2^-2) and would be encoded in Q1.31 as -(2^-1 + 2^-2) * 2^31 = -(2^30 + 2^29) = -(1,073,741,824 + 536,870,912) = -1,610,612,736 = 4,294,967,296 - 1,610,612,736 = 2,684,354,560 = 0xA0000000.
There's a handy online tool for visualizing this at: https://chummersone.github.io/qformat.html
The answer to the second question depends on the particular function that you want to perform with the CORDIC coprocessor, and you will need to provide more context in order for anyone to give you a suitable answer. Table 194 in RM0456 (reference manual for your STM32U575) shows values input and output for the implemented CORDIC functions. As an example, consider the arctangent function: it's arguments (input) and results (output) are shown in Table 199. In that case, the input 'x' is represents the tangent of some angle (pure/dimensionless number) pre-divided by some 2^k so that its magnitude is less than 1 (and thus can be represented in Q1.31 format). Then the output is a Q1.31 number in units of 2^k * pi radians. For the simple example of arctan(1/2) = 45 degrees = pi/4 radians, x = 1/2 (already less than 1 so k=0, that is, there is no need to scale it down) = 0x40000000 (Q1.31 representation of 1/2) and the expected result would be 0x20000000 (Q1.31) = 1/4 since units are pi radians.
2024-05-23 06:22 PM
Thank you very much for such a detailed answer, Jacob!