作者:Daniele Bagni
賽靈思公司DsP 專家
電子郵箱:Daniele.bagni@xilinx.com
Giulio Corradi
賽靈思公司IsM 高級系統架構師
電子郵箱:Giulio.corradi@xilinx.com
這種全新的賽靈思綜合工具可將手動流程實現自動化,,從而消除大量的設計錯誤來源,,并加速開發(fā)周期中極為漫長且經常反復操作的部分的設計進程。
FPGA 技術是一種強大且高度靈活的PID 控制器實現方法,。由于FPGA 器件擁有大量的并行資源,,可為同步運算提供多個比例積分微分(PID)實例,。此外,FPGA 還能夠在不影響此前設計的其它PID 的性能的情況下,,根據應用需求,,靈活添加更多PID 環(huán)路。如果在新型賽靈思 Zynq™ -7000 All Programmable soC 的可編程邏輯(或架構)中實現PID,,可以獲得更多新的優(yōu)勢,,因為功能強大的板上ARM® Cortex ™雙A9 核處理系統可以直接利用FPGA 的功能。
但是,,FPGA 器件一般要求使用VHDL 或Verilog 等寄存器傳輸級(RTL)設計語言,,這可能與控制工程師的知識背景存在一定的差距,會妨礙FPGA 技術的使用,。為消除這種差距,,賽靈思新推出Vivado 高層次綜合(HLs)設計工具。這種工具能夠將C,、C++ 或system C設計規(guī)范轉換為RTL 實現方案,,以便綜合到賽靈思FPGA 中。這種轉換只需要對常見的C 或C++ 代碼稍作調整,,因此不會造成嚴重的知識脫節(jié),。
另外,近年來電氣驅動器和機器人也正在設法進軍聯網控制系統的范疇,,這類聯網系統在配備有通信信道的環(huán)路中使用PID,。在這類應用中,FPGA 實現的確定性和速度占巨大優(yōu)勢,。
但是由于還是需要與軟件通信協議?;樱到y架構師和控制工程師往往犧牲性能來換取全軟件實現,。慶幸的是,,Vivado 提供了一種更簡單,、更通用的實現方法,可避開這種取舍,。Vivado 只需通過把C或C++ 代碼重新映射到Zynq-7000 All Programmable soC 器件的FPGA 架構上,,就可以顯著改善已開發(fā)出的聯網控制系統的性能。
一種無所不在的器件
基本上所有自然和人為的控制系統均采用PID 或其變體PI(比例積分)或PD(比例微分)來反饋,。大型工廠使用成千上萬的PID 控制器來監(jiān)控其化學或物理工藝,。在汽車和運輸系統中,PID 用于控制和保持發(fā)動機速度,,確保平穩(wěn)制動和控制眾多轉向功能,;在電機中,PID 用于控制電機的電流和力矩,;而在機器人中,,PID 則用于驅動和穩(wěn)定機器人的手臂或腿部的軌跡。PID 無處不在,,就連醫(yī)療系統中也有其身影,,例如用于控制I 類糖尿患者的人工胰腺,模仿天然胰島素分泌特征,。實際上生物系統自身也使用反饋來控制刺激反應,,比如說視網膜系統適應光照的過程。
典型的反饋控制系統由設備(即待控制的機械或電氣系統)和PID 控制器組成,。數模(D/A)轉換器將控制輸出轉換為適當的設備輸入,,而模數(A/D)轉換器則將設備的輸出轉換為反饋信號。圖1 是PID 工作原理圖,。簡單地說,,PID 控制器將負責處理傳感器測出的設備輸出值y(n) 和基準輸入值w(n)之間的信息差e(n),也稱為“誤差”,,然后對系統的激勵器進行校正,,以達到所需的命令輸出值。PID 的每一個部分都對應一種特定的行為,,或稱為“模式”,。P 行為根據誤差的大小驅動控制器輸出u(n)。I 行為消除穩(wěn)態(tài)偏移,,但可能會降低瞬態(tài)響應速度,。D 行為負責評估趨勢,預測輸出校正,,從而提高系統的穩(wěn)定性,,減少過沖并改善瞬態(tài)響應。
沒有反饋控制的系統被稱為開環(huán),,其傳輸函數(系統輸入映射到輸出的方式)的相移在單位增益下不得超過180°,。開環(huán)的相位滯后度和單位增益下的相移(180°)之間的差異被稱為“相位裕量”,。系統增益和相移一般表達為拉普拉斯轉換的模擬域s,或者Z 轉換的離散域z,。假定P(z) 和H(z) 分別為設備和PID 控制器的離散轉換函數,,則整個閉環(huán)系統的轉換函數可表達為:
分式T(z) 的分子和分母中的z 的值分別稱為零點和極點。PID 的相位滯后進入環(huán)路,,會增加總的相位滯后,。因此,一個高速的PID 應盡量降低這種滯后,。在理想的情況下,,PID 的響應時間應該是瞬間的,就像模擬控制器一樣,。因此PID 的計算速度尤為重要。在閉環(huán)系統中,,必須確保穩(wěn)定性,,尤其是對機器人系統或電機驅動器這樣的高端應用而言,更是如此,。如果不穩(wěn)定,,控制環(huán)路的響應會發(fā)生寄生振蕩,或是響應遲緩,。穩(wěn)定性可通過PID 控制器極點和零點的補償來實現,,從而讓閉環(huán)系統盡可能實現最佳性能(增益和相位特性)。
在機器人和定位系統中,,不管是單個PID 環(huán)路還是級聯環(huán)路都存在一定的復雜性,。例如,力矩由電流環(huán)路PID 控制,,電機速度由與電流PID 級聯的速率PID 控制,,而位置則由與速度PID 級聯的空間PID 控制。在這種情況下,,用軟件順序執(zhí)行每一個PID 環(huán)路的方法來降低總體計算延遲,,效率會越來越低。
許多用于電力驅動器和機器人的PID 設計依賴浮點C,、C++實現方案,,這對控制工程師來說往往是最熟悉的表達方式。使用高速微處理器,、微控制器或DsP 處理器就能夠輕松地修改軟件,,無需花太多時間來設計更多硬件,直接就可以在軟件中實現許多高難度的控制結構,。
PID 控制器的基準模型
下面舉一個實際案例來說明使用Vivado HLs 簡化數字PID 控制器設計工作的優(yōu)勢,。在這個設計案例中,,我們考慮一個只有一個環(huán)路和一部直流電機的設備。因此轉速是輸出,,電壓是輸入,。
該設備可表達為等式1,用于表達拉普拉斯域的開環(huán)傳輸函數,。這里略去了直流電機和轉子的傳輸函數的詳細微分計算:
其中a,、b、c,、d 是設備的數值參數,。等式2 是PID 控制器的傳輸函數。
其中U(s) 和E(s) 分別是PID 輸入和輸出信號u(n) 和e(n) 的拉普拉斯轉換,。kp,、kI 和kD 分別為比例級、積分級和微分級的增益,。
梯形積分的Tustin 近似法就是將傳輸函數從拉普拉斯域轉換到Z 域的方法之一,。這樣設備(等式1)和PID(等式2)的傳輸函數的數字化形式分別表達為等式3 和等式4:
其中TF 和Ts 分別為微分濾波時間和采樣時間。圖2 是由PID 控制器模塊和設備組成的離散系統,。
Mathworks 的控制系統工具箱MATLAB 和simulink 是一種設計和仿真模擬及數字PID 控制系統的強大工具,。下列MATLAB 代碼用于提供PID 控制器參數。圖3 所示的是閉環(huán)系統對階躍輸入信號的響應,,PID 參數設為kP=35.3675,、kI=102.2398、kD=0.29161,。
Ts = 1/100; t = 0 : Ts : 2.56-Ts;
% (Laplace transform) transfer function of
% the continuous system to be controlled
a=1; b=1; c=10; d=20; num=a; den=[b c d];
plant = tf(num,den);
% (Z transform) transfer function of
% the discrete system
plant_d = c2d(plant, Ts, ‘tustin’)
% dummy parameters to generate a PID
Kp=1; Ki=1; Kd=1; Tf=20;
C_be = pid(Kp, Ki, Kd, Tf, Ts, ...
‘IFormula’,’Trapezoidal’, ...
‘DFormula’,’Trapezoidal’);
% tuning the PID with more
% suitable parameters
contr_d = pidtune(plant_d, C_be)
Kp = contr_d.Kp;
Ki = contr_d.Ki;
Kd = contr_d.Kd;
Tf = contr_d.Tf;
sys_d = feedback(contr_d*plant_d,1);
% closed loop system
figure; step(sys_d);
title([‘Closed-loop output to step ‘ ...
‘signal: Kp=’,num2str(contr_d.Kp), ...
‘ Ki=’, num2str(contr_d.Ki), ...
‘ Kd=’, num2str(contr_d.Kd)]);
axis([0 2.0 0 1.5]); grid;
等式3 和等式4 可分別正式寫成等式5 和等式6:
通過逆向轉換等式5 和6,,得到等式7 的公式,用于給離散時間域中的PID 控制器和設備模塊建立模型,, 如下列MATLAB 代碼段所示:
w = ones(1, numel(t)); w(1:4) = 0;
C = (contr_d.Ts - 2*contr_d.Tf) / ...
(contr_d.Ts + 2*contr_d.Tf);
Gd = 2*contr_d.Kd / (contr_d.Ts + ...
2*contr_d.Tf);
Gi = contr_d.Ki * contr_d.Ts/2;
Gp = contr_d.Kp;
% closed loop
e_prev = 0; % e(n-1)
yi_prev = 0; % yi(n-1)
yd_prev = 0; % yd(n-1)
y_z1 = 0; % y(n-1)
y_z2 = 0; % y(n-2)
u_z1 = 0; % u(n-1)
u_z2 = 0; % u(n-2)
for i = 1 : numel(w)
% error
e(i) = w(i) - y_z1; % CLOSED LOOP
% derivation
yd(i) = -C*yd_prev + e(i) - e_prev;
yd_prev = yd(i);
% integration
yi(i) = yi_prev + e(i) + e_prev;
yi_prev = yi(i); e_prev = e(i);
% PID
u(i) = e(i) * Gp + Gd*yd(i) + Gi*yi(i);
% plant
y(i) = 1.903*y_z1 -0.9048*y_z2 + ...
1e-5*(2.38*u(i) + 4.76*u_z1 + ...
2.38*u_z2);
y_z2 = y_z1; y_z1 = y(i);
u_z2 = u_z1; u_z1 = u(i);
end
figure; plot(t, y, ‘g’); grid;
title ‘Closed Loop Step: plant+contr’;
使用VIVADO HLS 實現的PID 設計的性能
Vivado HLs 是最新一代賽靈思設計工具,。它能夠用C、C++ 和system C 編寫的高級規(guī)范自動生成生產質量級RTL實現,。換句話說,,Vivado HLs 可實現手動流程的自動化,從而消除眾多設計錯誤來源,,并加速開發(fā)周期中極為漫長且經常反復操作的部分的設計進程,。
Vivado HLs 在設計中采用了兩種截然不同的綜合方法。其中算法綜合負責取出函數內容,,在一定數量的時鐘周期里,,把功能描述綜合到RTL 描述。而接口綜合則負責把函數參數轉換為有特定時序協議的RTL 端口,,以便設計與系統中的其它設計通信,??梢栽谌肿兞俊㈨敿壓瘮祬岛晚敿壓瘮捣祷刂抵线\行接口綜合,。
綜合流程分步執(zhí)行,。第一步是抽取C 代碼推斷的控制與數據路徑。接口綜合會影響算法綜合可實現的結果,,反之亦然,。與任何手動RTL 設計中得到的眾多決策一樣,結果將是大量可用的實現和優(yōu)化以及數量更大的根據其相互影響關系得到的變體,。Vivado HLs 讓用戶從這些細節(jié)中脫身,,以最短的時間高效率地確定最佳設計。Vivado HLs 根據自身的默省設置,,加上用戶設定的約束和指令,,迅速創(chuàng)建出最佳實現方案。
Vivado HLs 的核心流程是調度和捆綁,。調度流程負責向特定時鐘周期分配每一次運算,。調度流程中制定的決策需要考慮時鐘頻率、時鐘非確定性,、器件技術庫的時序信息以及面積、時延和吞吐量指令等諸多因素,。捆綁是用于判斷何種硬件資源或者內核用于每次調度操作的流程,。例如,Vivado HLs 會自動判斷是否同時使用加法器和減法器,,或者是否單個加法減法器就能處理兩次運算,。因為捆綁流程制定的決策會影響運算的調度,比如用流水線化的乘法器代替標準的組合乘法器,,因此,,調度過程中應考慮捆綁決策。
Vivado HLs 通過如下方式可以加速驗證和設計優(yōu)化進程:
• 縮短以前的手動RTL 創(chuàng)建流程,,并根據功能C 規(guī)范自動創(chuàng)建RTL,,從而避免轉換錯誤;
• 迅速方便地完成多種架構的評估,,致力于打造出理想解決方案,。
使用功能C 規(guī)范替代RTL 設計,加快仿真進程,,盡早發(fā)現設計錯誤,。
C 代碼實現與MATLAB 模型極其相似,如下所示,。假定在現實世界中,,PID 輸入和輸出信號達到用戶能控制的飽和度,。PID 系數(等式7 的GI、GP,、GD 和C)以及e(n) 和u(n) 信號的最大值和最小值假定在任何函數調用中都是順序加載在PID 內核上的,。假定兩個輸入和輸出信號也是相同的情況。
void PID_Controller(bool ResetN, float
coeff[8], float din[2], float dout[2])
{
// local variables for I/O signals
float Gi, Gd, C, Gp, Y, W, E, U;
// previous PID states:
// Y1(n-1), X1(n-1), INT(n-1)
static float prev_X1, prev_Y1;
static float prev_INT;
// current local states:
// X1(n), X2(n)
float X1, X2, Y1, Y2, INT;
// local variables
float max_limE, max_limU;
float min_limE, min_limU;
float tmp, pid_mult, pid_addsub;
// get PID input coefficients
Gi = coeff[0]; Gd = coeff[1];
C = coeff[2]; Gp = coeff[3];
max_limE = coeff[4];
max_limU = coeff[5];
min_limE = coeff[6];
min_limU = coeff[7];
// get PID input signals
// effective input signal
W = din[0];
// closed loop signal
Y = din[1];
if (ResetN==0)
{
// reset INTegrator stage
prev_INT = 0;
// reset Derivative stage
prev_X1 = 0;
}
// compute error signal E = W - Y
pid_addsub = W - Y;
pid_addsub = (pid_addsub>max_limE) ?
max_limE : pid_addsub;
E = (pid_addsubmin_limE : pid_addsub;
// Derivation
// Y1(n) = -C * Y1(n-1) + X1(n) -
// X1(n-1) = X1 - (prev_X1+C*Y1)
X1 = Gd * E;
pid_mult = C * prev_Y1;
pid_addsub = pid_mult + prev_X1;
pid_addsub = X1 - pid_addsub;
// update Y1(n)
Y1 = pid_addsub;
// Integrator
// INT(n) = CLIP(X2(n) + INT(n-1))
// Y2(n) = INT(n-1) + INT(n)
X2 = Gi * E;
pid_addsub = prev_INT + X2;
pid_addsub=(pid_addsub>max_limE)?
max_limE : pid_addsub;
INT = (pid_addsubmin_limE : pid_addsub;
Y2 = INT + prev_INT;
// output signal U(n)
pid_mult = Gp * E;
pid_addsub = Y1 + Y2;
tmp = pid_addsub + pid_mult;
tmp = (tmp > max_limU) ?
max_limU : tmp;
U = (tmp < min_limU) ?
min_limU : tmp;
// PID effective
// output signal
dout[0] = U;
// test the PID error
// signal as output
dout[1] = E;
// update internal states
// for the next iteration
prev_X1 = X1;
prev_Y1 = Y1;
prev_INT= INT;
return;
}
設定Zynq-7010 CLG400-1 器件的目標時鐘周期為10 納秒,,PID 實現在該FPGA 的32 位浮點算術單元中,。首次運行Vivado HLs(圖4 中的“solution1”),估計的時鐘周期為8.49納秒,,與FPGA 的118MHz 時鐘頻率對應,。由于生成輸出需要49 個時鐘周期的時延,有效數據速率為2.4Msps,。布局布線前估計FPGA 占用面積為7 個DsP48E slice,,1,105 個觸發(fā)器和1,790 個查找表。
通過分析Vivado HLs 生成的報告文件,,發(fā)現工具生成了兩個浮點加法減法器內核,。因此采用下列指令:
set_directive_interface -mode ap_fifo
"PID_Controller" coeff
set_directive_interface -mode ap_fifo
"PID_Controller" din
set_directive_interface -mode ap_fifo
"PID_Controller" dout
set_directive_allocation -limit 1 -type
core "PID_Controller" fAddSub
set_directive_allocation -limit 1 -type
core "PID_Controller" fMul
前三條指令在自動生成的RTL 設計中設置待映射為FIFO的I/O 函數參數,而后兩條指令將限制浮點乘法器和加法減法器數量,,每個流程分配一個實例,。
再次運行Vivado HLs(圖4 中的“solution2”),估計的時鐘周期為7.96 納秒,,與FPGA 的125MHz 時鐘頻率對應,。對任何輸出值, 有50 時鐘周期的時延,, 有效數據速率為2.5Msps,。估計FPGA 占用面積為5 個DsP48E slice,1,156個觸發(fā)器和1,530 個查找表,,這就是最理想的結果,。圖4 的屏幕截圖對這兩種解決方案的Vivado HLs 綜合估計報告進行了比較。
下面的RTL 代碼段是Vivado HLs 自動為頂級函數生成的VHDL,。工具生成的接口信號以clock reset(時鐘復位)和start(啟動) 為輸入端口,,以done(完成) 和idle(閑置)為輸出端口。輸入陣列din 和coeff 映射為輸入FIFO 端口,,故有empty 和read 信號,。輸出陣列dout 映射為輸出FIFO 端口,故有其full 和write 信號,。
— RTL generated by Vivado(TM) HLS - High-
— Level Synthesis from C, C++ and SystemC
— Version: 2012.2
— Copyright (C) 2012 Xilinx Inc. All
— rights reserved.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
library work;
use work.AESL_components.all;
entity PID_Controller is
port (
ap_clk : IN STD_LOGIC;
ap_rst : IN STD_LOGIC;
ap_start : IN STD_LOGIC;
ap_done : OUT STD_LOGIC;
ap_idle : OUT STD_LOGIC;
coeff_empty_n : IN STD_LOGIC;
coeff_read : OUT STD_LOGIC;
dout_full_n : IN STD_LOGIC;
dout_write : OUT STD_LOGIC;
din_empty_n : IN STD_LOGIC;
din_read : OUT STD_LOGIC;
ResetN : IN
STD_LOGIC_VECTOR ( 0 downto 0);
coeff_dout : IN
STD_LOGIC_VECTOR (31 downto 0);
din_dout : IN
STD_LOGIC_VECTOR (31 downto 0);
dout_din : OUT
STD_LOGIC_VECTOR (31 downto 0));
end;
三個工作日
可以從C 模型規(guī)范著手,,利用有限的資源高效地將數字PID 控制器實現在賽靈思FPGA 器件中,甚至是在32 位浮點算術單元中。Vivado HLs 自動生成的RTL 占用面積極小,,Zynq-7000 器件僅占用5 個DsP48E slice,、1,156 個觸發(fā)器和1,530 個LUT。FPGA 時鐘頻率為125MHz,,有效數據速率為2.5Msps,。僅三個工作日就得到這些設計結果,其中大部分時間用于構建MATLAB 和C 模型,,而非運行Vivado HLs 工具本身,。運行僅花了半天時間。
與其他備選方法相比,,這種方法具有明顯的優(yōu)勢,。尤其是Vivado HLs 負責將浮點PID 直接映射到架構中。這樣可以避免手動實現映射所需的中間步驟,,從而改善項目的可移植性和一致性,,與一般需要三個工作日以上的手動轉換相比,大幅度縮短總開發(fā)時間,。