# How To Truncate bits of decimal part in sfixed data?

Status
Not open for further replies.

#### soujanya04

##### Newbie level 4
Hello all,
I am trying to design a digital PID controller using Spartan 3e FPGA and VHDL coding.

I used sfixed data. Initially I assumed input, delayed output and system_output to be sfixed(7 downto -8). After arithmetic operations I got the output c(22 downto -51), which I have to store it back in to system_output(7 downto -8). The main part here is to truncate/round off the resultant output to remove 15 bits from the decimal part.

Code:
 system_output => resize(c,system_output'high, system_output'low, fixed_overflow_style,fixed_round);
Using the above command gives a huge error.

Please suggest me a way to approximately represent the (22 downto -51) data into (7 downto -8) length variable.

I am using Xilinx 14.7 version.

#### FvM

##### Super Moderator
Staff member
What kind of error do you observe?

#### soujanya04

##### Newbie level 4
Hello,
In converting (22 downto -51) data to (7 downto -8) data, 15 bits of decimal part should be removed. By doing this the actual value cannot be approximated to the nearer value.

For my application this percentage of error is more. Can you help me to reduce this approximation error.

Actually, there is no error in the code. I have simulated it also. But the issue is with the truncated value being different from the calculated c(22 downto -51).

Last edited by a moderator:

#### K-J

Hello,
In converting (22 downto -51) data to (7 downto -8) data, 15 bits of decimal part should be removed. By doing this the actual value cannot be approximated to the nearer value.

For my application this percentage of error is more. Can you help me to reduce this approximation error.

Actually, there is no error in the code. I have simulated it also. But the issue is with the truncated value being different from the calculated c(22 downto -51).

You're leaving a lot to the imagination here. On the one hand you've done some calculations that end up with the MSB being 22, but then by saying you're trying to cram it into a 7 downto 8 value this implies that the resulting output is less than 2^7 since you can't fit anything larger into that size.

Based on your first post, it seems to me that the calculated output is not in the range that you think and the calculated result is in fact greater than 127. That being the case, you have to go back to the drawing board here and figure out how many bits of precision you really need and the range of those calculations and from that figure out how to store the result.

Kevin Jennings

#### soujanya04

##### Newbie level 4
Hello,

I have attached my code.

Yes, as you said I am concerned with the change in value due to change in the range.

#### Attachments

• PID_sys_code.txt
3.2 KB · Views: 4
• my_pack_1.txt
424 bytes · Views: 2
Last edited:

#### vGoodtimes

s3 <= s1+s2;
s4 <= s3+m5; -- this looks wrong. s1, s2, s3 are all delayed by 1 extra cycle

There may be other similar errors. likewise, you have a long pipeline but appear to assume single-cycle feedback. While there may also be issues with numerical accuracy, there appear to be larger problems with the structure.

Pipelined IIR filters tend to have specific features/limitations that allow an efficient implementation. (eg, the pipelined accumulator.) They are uncommon enough that I've heard multiple designers claim pipeline IIR as impossible.

You probably want to have a sample enable input that occurs every N cycles, and allows the N stages to run.

#### soujanya04

##### Newbie level 4
Thank you for the information.

As you said, I got delays., it took more than one clock cycle for the operations that I assumed would be done in a single clock cycle. Can I know the reason for it taking an extra cycle.

As far as I searched, I got to know that PID contrllers were designed on FPGAs which implies that pipelined IIRs have also been implemented.

I am concerned with the accuracy issues as you mentioned. I would be thankful if you provide me a solution to reduce the accuracy issue.

Last edited:

#### vGoodtimes

The signal assign (non-blocking assign in verilog) simply schedules an assignment to take place once all triggered processes have been evaluated. This may seem odd, but it makes more sense when you think about how processes describe hardware.

You should try to keep track of cycle-delays vs sample delays. Basically, you should only update the shift registers when there is a new sample. The rest of the logic can be updated every cycle. this means you should try to update the shift register every N (or more) cycles, where N is the number of cycles required to compute the next values.

You should fix your structural issues in HLD, but you should look at the accuracy issues in MATLAB (or other languages).

#### FvM

##### Super Moderator
Staff member
There may be other similar errors. likewise, you have a long pipeline but appear to assume single-cycle feedback. While there may also be issues with numerical accuracy, there appear to be larger problems with the structure.

Pipelined IIR filters tend to have specific features/limitations that allow an efficient implementation. (eg, the pipelined accumulator.) They are uncommon enough that I've heard multiple designers claim pipeline IIR as impossible.

The problem is that the shown PID code runs at full clock speed without any clock enable. That's inappropriate for most real PID applications (actually any PID I did ever see). A digital PID is a sampled data system and expected to run at a specific sample rate, which is in a 100 Hz up to multiple 10 kHz range in most cases. System clock rates are at least factor 100 above, so pipelining isn't a problem at all. Running the PID too fast isn't only a problem of pipelining. Much more serious, you get unsuitable small KI and KD coefficients which enforce huge word widths inside the PID.

Status
Not open for further replies.