Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
`ifndef __PID_SV__
`define __PID_SV__
`include "../common.sv"
module Pid #(
parameter W = 32, FW = 16,
parameter real P = 8, real I = 192, real D = 0,
parameter real N = 100, real TS = 0.002,
parameter real LIMIT = 10000
)(
input wire clk, rst, en,
input wire signed [W-1:0] in,
output logic signed [W-1:0] out
);
import Fixedpoint::*;
wire signed [W-1:0] p = P * (2.0 ** FW);
wire signed [W-1:0] i = (I * TS) * (2.0 ** FW);
wire signed [W-1:0] d = D * (2.0 ** FW);
wire signed [W-1:0] n = N * (2.0 ** FW);
wire signed [W-1:0] ts = TS * (2.0 ** FW);
wire signed [W-1:0] lim = LIMIT * (2.0 ** FW);
`DEF_FP_MUL(mul, W-FW, FW, W-FW, FW, FW);
wire signed [W-1:0] xp = mul(in, p);
wire signed [W-1:0] xi = mul(in, i);
logic signed [W-1:0] xi_acc;
always_ff@(posedge clk) begin
if(rst) xi_acc <= 1'sb0;
else if(en) begin
if(xi_acc + xi > lim) xi_acc <= lim;
else if(xi_acc + xi < -lim) xi_acc <= -lim;
else xi_acc <= xi_acc + xi;
end
end
logic signed [W-1:0] dacc;
wire signed [W-1:0] xd = mul(in, d);
wire signed [W-1:0] xnd = mul((xd - dacc), n);
wire signed [W-1:0] tnd = mul(xnd, ts);
always_ff@(posedge clk) begin
if(rst) dacc <= 1'sb0;
else if(en) begin
if(dacc + tnd > lim) dacc = lim;
else if(dacc + tnd < -lim) dacc = -lim;
else dacc <= dacc + tnd;
end
end
always_ff@(posedge clk) begin
if(rst) out <= 1'sb0;
else if(en) out <= xp + xi_acc + xnd;
end
endmodule
`endif
b772052b4This file is pinned to the selected release. Download the original to open it in your design tool.