- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
Many of you may not be aware of what saturation instructions do in PSoC 5LP. PSoC 5LP uses Cortex-M3 core which has two special instructions called "SSAT" (Signed saturation) and "USAT" (Unsigned saturation). These instructions are used to limit a variable or a value to a certain number of bits. (Reference:
For example, if you have an 8 bit variable and for sure if you know that the value of the variable will not exceed a number 127 say, you would like to round off any value above 127 as 127 itself ( saturation) and any value below 0 as zero itself. In this case you need to write a big C code using if-else conditional statement to compare the variable with 127 and take the necessary action. Instead, to simplify this logic, you can make use of the saturation assembly instructions which Cortex-M3 (core of PSoC 5LP) supports. Please note that both GCC and MDK compilers do not append this instruction by itself for an equivalent C code.
For example, in the above example, the number of bits to restrict my result to would be 7 (2^7-1 = 127). Assuming I have the unsaturated value in register r0 and if I would like to store the saturated result in register r3, my assembly instruction would be
"usat r3, 8, r0"
Similar syntax is for signed saturation for specifying a positive limit and a negative limit for a signed variable. I hope you know the syntax to include an assembly instruction in C code.
Regards,
Asha
Note:
FYI, if you would like to assign a variable to a particular register, the syntax is "register (data type)* variable_name asm("register name");"
For example: register uint8* output asm ("r0");
Solved! Go to Solution.
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just adding one more point on the usage of saturation instruction based on the compiler- (GCC or MDK )
While using GCC compiler, as mentioned above, we need to use the registers. eg: asm(“USAT r3,8,r0");
So first we need to store the variables that will contain the unsaturated and saturated results using the syntax given in the first post.
However, for MDK compilers you can directly use the local variables along with this instruction and there is no need to specify the registers:
eg: __asm(“ssat data_sat,8,data_unsat");
Regards
PSoC Wonders
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Good to learn somthing new. However, except for some time critial functions, most project managers would prefer to use high level language.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Asha, as you point out the feature of staurating arithmetic very importent to high
performance DSP applications, which C solution would severly impact, eg. sample
rate, etc..
Coupled with inline C makes it easy to implement.
Interesting. Makes me wonder how much code space/speed could be saved/improved in replacement
of ....
var = ( var > 10 ) ? 10, var + 1; // type of constructs.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
... not too much code. Since your given "10" from your example will not work (it is not a power of two) we have to rewite the above example to
var = (var > 127)?0:var+1; // Remember: C needs a colon to separate the two values
I've built an example project to see how many instructions will be needed to perform the wanted task. I had to add some hardware, so GCC did not optimize out all my code (wich really did happen!! No code left in main()).
Additionally it took me some time to understand the result in main.lst which does what I wrote but does not look like what I wrote.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I did indeed mistype the test statement. You can see where I spend most of my
time in a design.....
As I was doing the post I wondered (but did not do my homework) if saturation
was limited to power of two, thanks for clarifiying that.
As an aside in posting a recent sine generator using IIR and positive fdbk I experimented
with seed values and got the middle example shown below because I did not use sat
arithmetic.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
... turns out to be a complicated way to write "MWMW"
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanx for the link, hli. It reminded me of the take-off at Cape Caneveral of the mars-mission MAVEN.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
Yes, the example given by you ( var = (var > 127)?0:var+1;) is right. However, the saturation limit is restricted to 2^n-1 where you can specify the value of n.
Though most of them prefer using high level C code, this operand might be useful for DSP operations.
Regards,
Asha
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just adding one more point on the usage of saturation instruction based on the compiler- (GCC or MDK )
While using GCC compiler, as mentioned above, we need to use the registers. eg: asm(“USAT r3,8,r0");
So first we need to store the variables that will contain the unsaturated and saturated results using the syntax given in the first post.
However, for MDK compilers you can directly use the local variables along with this instruction and there is no need to specify the registers:
eg: __asm(“ssat data_sat,8,data_unsat");
Regards
PSoC Wonders