Skip to content

Add a vhdl PID for the PandA#230

Draft
DiamondRC wants to merge 7 commits intomasterfrom
pid-for-panda
Draft

Add a vhdl PID for the PandA#230
DiamondRC wants to merge 7 commits intomasterfrom
pid-for-panda

Conversation

@DiamondRC
Copy link
Copy Markdown

Created a PID block for use on PandA devices.

The PID accepts four parameters from input signals, allowing for custom tuning to fit the system. These include: a proportioal term, a derivative term, an integral term and a feed-forward term.

The PID takes a setpoint value and a measured value and returns a correction term for motion.

Currently the PID caps values at the signed limits, which are dynamically calculated from the size of the input/output signals. Whilst this provides flexability, if the values are fixed then this could be simplified to conserve board space.

Comment thread modules/pid/hdl/pid.vhd Outdated
Comment thread modules/pid/hdl/pid.vhd Outdated
Comment thread modules/pid/hdl/pid.vhd Outdated
end process;

-- Error calc
in_error <= setpoint - in_signal;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the in_error be updated inside the process?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would mean the derivative and integral term would need to wait until the next clock edge to use the in_error value? Keeping it outside the process allows the value to be immediately available.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that will be the behaviour.

However, I think calculating in_error outside the process makes it asynchronous. Since both in_signal and setpoint are synchronous, updating in_error outside the process could introduce timing issues, especially since the PID loop uses it in the same clock cycle.

In digital control systems, it's common for all control terms (proportional, derivative and integral) to be computed based on values sampled at discrete time intervals, not continuously. Therefore I would say that it is expected that the systems waits for the next clock edge before using updated values.

It might be safer to move the calculation inside the process to keep everything aligned with the clock. I’d also consider doing the same for out_signal, as that might help handle the mismatch between the Panda and PPMAC clocks.

I'm not an expert in FPGA design, so I might be missing something, but this seems like a more robust approach. I'm happy to hear other perspectives.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LeandroMartinsdS, just think of in_error as an intermediate value in the calculation. From an FPGA timing point of view I'd be more concerned about the multiplies. A single tick 32x32 => 64 multiply with unregistered inputs ... you can get away with a lot on a 125 MHz clock, but even so I will expect serious timing problems with this design.

More to the point, I think I see the integral term being updated on every tick. Mmm. This is ambitious, and you're going to need a very small integral term for most sensible applications. Normally I'd expect the PID controller to update at a slower tempo than the FPGA clock; I'd recommend an input strobe to drive this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhhh. Oh dear. I just noticed: slo_clk_i is an ordinary signal being used as a fabric clock.

The FPGA doesn't work like that, I'll put a review comment in the appropriate place above.

Comment thread modules/pid/hdl/pid.vhd Outdated
Copy link
Copy Markdown
Contributor

@Araneidae Araneidae left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of extra thoughts:

  • This needs to be marked as Draft as it has clearly never been synthesised
  • There is no testbench, there really does need to be something

Comment thread modules/pid/hdl/pid.vhd Outdated
Comment on lines +59 to +64
process(slo_clk_i)
constant max_lim : signed(out_signal'range) := (out_signal'left => '0', others => '1');
constant min_lim : signed(out_signal'range) := (out_signal'left => '1', others => '0');

begin
if rising_edge(slo_clk_i) then
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slo_clk_i is an ordinary signal derived from the bit bus (this is clear from its definition below in pid.block.ini). I'm afraid you simply cannot use this a "fabric" clock, which is what you're trying to do here. Instead you need to write:

process (clk_i) begin
    if rising_edge(clk_i) then
        if slo_clk_i then
            ... do stuff ...
        end if;
    end if;
end process;

Things then get more tricky, you'll need to figure out just how quickly everything proceeds, and you might need to internally create 1 and 2 tick delayed versions of slo_clk_i to help manage your calculations.

@Araneidae Araneidae marked this pull request as draft May 28, 2025 08:03
@LeandroMartinsdS
Copy link
Copy Markdown

It might be worth to have a look at the #188

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (master@61de7b0). Learn more about missing BASE report.

Additional details and impacted files
@@            Coverage Diff            @@
##             master     #230   +/-   ##
=========================================
  Coverage          ?   69.98%           
=========================================
  Files             ?       20           
  Lines             ?     1206           
  Branches          ?        0           
=========================================
  Hits              ?      844           
  Misses            ?      362           
  Partials          ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@EmilioPeJu
Copy link
Copy Markdown
Contributor

CI is failing because master is now using ipk packages instead of zpg, you can fix it by rebasing your branch on top of master

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants