作者:Daniele Bagni
賽靈思公司DsP 專家
電子郵箱:Daniele.bagni@xilinx.com
Giulio Corradi
賽靈思公司IsM 高級系統(tǒng)架構(gòu)師
電子郵箱:Giulio.corradi@xilinx.com
這種全新的賽靈思綜合工具可將手動流程實現(xiàn)自動化,從而消除大量的設(shè)計錯誤來源,并加速開發(fā)周期中極為漫長且經(jīng)常反復(fù)操作的部分的設(shè)計進程。
FPGA 技術(shù)是一種強大且高度靈活的PID 控制器實現(xiàn)方法。由于FPGA 器件擁有大量的并行資源,可為同步運算提供多個比例積分微分(PID)實例。此外,F(xiàn)PGA 還能夠在不影響此前設(shè)計的其它PID 的性能的情況下,根據(jù)應(yīng)用需求,靈活添加更多PID 環(huán)路。如果在新型賽靈思 Zynq™ -7000 All Programmable soC 的可編程邏輯(或架構(gòu))中實現(xiàn)PID,可以獲得更多新的優(yōu)勢,因為功能強大的板上ARM® Cortex ™雙A9 核處理系統(tǒng)可以直接利用FPGA 的功能。
但是,F(xiàn)PGA 器件一般要求使用VHDL 或Verilog 等寄存器傳輸級(RTL)設(shè)計語言,這可能與控制工程師的知識背景存在一定的差距,會妨礙FPGA 技術(shù)的使用。為消除這種差距,賽靈思新推出Vivado 高層次綜合(HLs)設(shè)計工具。這種工具能夠?qū)、C++ 或system C設(shè)計規(guī)范轉(zhuǎn)換為RTL 實現(xiàn)方案,以便綜合到賽靈思FPGA 中。這種轉(zhuǎn)換只需要對常見的C 或C++ 代碼稍作調(diào)整,因此不會造成嚴(yán)重的知識脫節(jié)。
另外,近年來電氣驅(qū)動器和機器人也正在設(shè)法進軍聯(lián)網(wǎng)控制系統(tǒng)的范疇,這類聯(lián)網(wǎng)系統(tǒng)在配備有通信信道的環(huán)路中使用PID。在這類應(yīng)用中,F(xiàn)PGA 實現(xiàn)的確定性和速度占巨大優(yōu)勢。
但是由于還是需要與軟件通信協(xié)議?;?,系統(tǒng)架構(gòu)師和控制工程師往往犧牲性能來換取全軟件實現(xiàn)。慶幸的是,Vivado 提供了一種更簡單、更通用的實現(xiàn)方法,可避開這種取舍。Vivado 只需通過把C或C++ 代碼重新映射到Zynq-7000 All Programmable soC 器件的FPGA 架構(gòu)上,就可以顯著改善已開發(fā)出的聯(lián)網(wǎng)控制系統(tǒng)的性能。
一種無所不在的器件
基本上所有自然和人為的控制系統(tǒng)均采用PID 或其變體PI(比例積分)或PD(比例微分)來反饋。大型工廠使用成千上萬的PID 控制器來監(jiān)控其化學(xué)或物理工藝。在汽車和運輸系統(tǒng)中,PID 用于控制和保持發(fā)動機速度,確保平穩(wěn)制動和控制眾多轉(zhuǎn)向功能;在電機中,PID 用于控制電機的電流和力矩;而在機器人中,PID 則用于驅(qū)動和穩(wěn)定機器人的手臂或腿部的軌跡。PID 無處不在,就連醫(yī)療系統(tǒng)中也有其身影,例如用于控制I 類糖尿患者的人工胰腺,模仿天然胰島素分泌特征。實際上生物系統(tǒng)自身也使用反饋來控制刺激反應(yīng),比如說視網(wǎng)膜系統(tǒng)適應(yīng)光照的過程。
典型的反饋控制系統(tǒng)由設(shè)備(即待控制的機械或電氣系統(tǒng))和PID 控制器組成。數(shù)模(D/A)轉(zhuǎn)換器將控制輸出轉(zhuǎn)換為適當(dāng)?shù)脑O(shè)備輸入,而模數(shù)(A/D)轉(zhuǎn)換器則將設(shè)備的輸出轉(zhuǎn)換為反饋信號。圖1 是PID 工作原理圖。簡單地說,PID 控制器將負責(zé)處理傳感器測出的設(shè)備輸出值y(n) 和基準(zhǔn)輸入值w(n)之間的信息差e(n),也稱為“誤差”,然后對系統(tǒng)的激勵器進行校正,以達到所需的命令輸出值。PID 的每一個部分都對應(yīng)一種特定的行為,或稱為“模式”。P 行為根據(jù)誤差的大小驅(qū)動控制器輸出u(n)。I 行為消除穩(wěn)態(tài)偏移,但可能會降低瞬態(tài)響應(yīng)速度。D 行為負責(zé)評估趨勢,預(yù)測輸出校正,從而提高系統(tǒng)的穩(wěn)定性,減少過沖并改善瞬態(tài)響應(yīng)。
沒有反饋控制的系統(tǒng)被稱為開環(huán),其傳輸函數(shù)(系統(tǒng)輸入映射到輸出的方式)的相移在單位增益下不得超過180°。開環(huán)的相位滯后度和單位增益下的相移(180°)之間的差異被稱為“相位裕量”。系統(tǒng)增益和相移一般表達為拉普拉斯轉(zhuǎn)換的模擬域s,或者Z 轉(zhuǎn)換的離散域z。假定P(z) 和H(z) 分別為設(shè)備和PID 控制器的離散轉(zhuǎn)換函數(shù),則整個閉環(huán)系統(tǒng)的轉(zhuǎn)換函數(shù)可表達為:
分式T(z) 的分子和分母中的z 的值分別稱為零點和極點。PID 的相位滯后進入環(huán)路,會增加總的相位滯后。因此,一個高速的PID 應(yīng)盡量降低這種滯后。在理想的情況下,PID 的響應(yīng)時間應(yīng)該是瞬間的,就像模擬控制器一樣。因此PID 的計算速度尤為重要。在閉環(huán)系統(tǒng)中,必須確保穩(wěn)定性,尤其是對機器人系統(tǒng)或電機驅(qū)動器這樣的高端應(yīng)用而言,更是如此。如果不穩(wěn)定,控制環(huán)路的響應(yīng)會發(fā)生寄生振蕩,或是響應(yīng)遲緩。穩(wěn)定性可通過PID 控制器極點和零點的補償來實現(xiàn),從而讓閉環(huán)系統(tǒng)盡可能實現(xiàn)最佳性能(增益和相位特性)。
在機器人和定位系統(tǒng)中,不管是單個PID 環(huán)路還是級聯(lián)環(huán)路都存在一定的復(fù)雜性。例如,力矩由電流環(huán)路PID 控制,電機速度由與電流PID 級聯(lián)的速率PID 控制,而位置則由與速度PID 級聯(lián)的空間PID 控制。在這種情況下,用軟件順序執(zhí)行每一個PID 環(huán)路的方法來降低總體計算延遲,效率會越來越低。
許多用于電力驅(qū)動器和機器人的PID 設(shè)計依賴浮點C、C++實現(xiàn)方案,這對控制工程師來說往往是最熟悉的表達方式。使用高速微處理器、微控制器或DsP 處理器就能夠輕松地修改軟件,無需花太多時間來設(shè)計更多硬件,直接就可以在軟件中實現(xiàn)許多高難度的控制結(jié)構(gòu)。
PID 控制器的基準(zhǔn)模型
下面舉一個實際案例來說明使用Vivado HLs 簡化數(shù)字PID 控制器設(shè)計工作的優(yōu)勢。在這個設(shè)計案例中,我們考慮一個只有一個環(huán)路和一部直流電機的設(shè)備。因此轉(zhuǎn)速是輸出,電壓是輸入。
該設(shè)備可表達為等式1,用于表達拉普拉斯域的開環(huán)傳輸函數(shù)。這里略去了直流電機和轉(zhuǎn)子的傳輸函數(shù)的詳細微分計算:
其中a、b、c、d 是設(shè)備的數(shù)值參數(shù)。等式2 是PID 控制器的傳輸函數(shù)。
其中U(s) 和E(s) 分別是PID 輸入和輸出信號u(n) 和e(n) 的拉普拉斯轉(zhuǎn)換。kp、kI 和kD 分別為比例級、積分級和微分級的增益。
梯形積分的Tustin 近似法就是將傳輸函數(shù)從拉普拉斯域轉(zhuǎn)換到Z 域的方法之一。這樣設(shè)備(等式1)和PID(等式2)的傳輸函數(shù)的數(shù)字化形式分別表達為等式3 和等式4:
其中TF 和Ts 分別為微分濾波時間和采樣時間。圖2 是由PID 控制器模塊和設(shè)備組成的離散系統(tǒng)。
Mathworks 的控制系統(tǒng)工具箱MATLAB 和simulink 是一種設(shè)計和仿真模擬及數(shù)字PID 控制系統(tǒng)的強大工具。下列MATLAB 代碼用于提供PID 控制器參數(shù)。圖3 所示的是閉環(huán)系統(tǒng)對階躍輸入信號的響應(yīng),PID 參數(shù)設(shè)為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:
通過逆向轉(zhuǎn)換等式5 和6,得到等式7 的公式,用于給離散時間域中的PID 控制器和設(shè)備模塊建立模型, 如下列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 實現(xiàn)的PID 設(shè)計的性能
Vivado HLs 是最新一代賽靈思設(shè)計工具。它能夠用C、C++ 和system C 編寫的高級規(guī)范自動生成生產(chǎn)質(zhì)量級RTL實現(xiàn)。換句話說,Vivado HLs 可實現(xiàn)手動流程的自動化,從而消除眾多設(shè)計錯誤來源,并加速開發(fā)周期中極為漫長且經(jīng)常反復(fù)操作的部分的設(shè)計進程。
Vivado HLs 在設(shè)計中采用了兩種截然不同的綜合方法。其中算法綜合負責(zé)取出函數(shù)內(nèi)容,在一定數(shù)量的時鐘周期里,把功能描述綜合到RTL 描述。而接口綜合則負責(zé)把函數(shù)參數(shù)轉(zhuǎn)換為有特定時序協(xié)議的RTL 端口,以便設(shè)計與系統(tǒng)中的其它設(shè)計通信。可以在全局變量、頂級函數(shù)參數(shù)和頂級函數(shù)返回值之上運行接口綜合。
綜合流程分步執(zhí)行。第一步是抽取C 代碼推斷的控制與數(shù)據(jù)路徑。接口綜合會影響算法綜合可實現(xiàn)的結(jié)果,反之亦然。與任何手動RTL 設(shè)計中得到的眾多決策一樣,結(jié)果將是大量可用的實現(xiàn)和優(yōu)化以及數(shù)量更大的根據(jù)其相互影響關(guān)系得到的變體。Vivado HLs 讓用戶從這些細節(jié)中脫身,以最短的時間高效率地確定最佳設(shè)計。Vivado HLs 根據(jù)自身的默省設(shè)置,加上用戶設(shè)定的約束和指令,迅速創(chuàng)建出最佳實現(xiàn)方案。
Vivado HLs 的核心流程是調(diào)度和捆綁。調(diào)度流程負責(zé)向特定時鐘周期分配每一次運算。調(diào)度流程中制定的決策需要考慮時鐘頻率、時鐘非確定性、器件技術(shù)庫的時序信息以及面積、時延和吞吐量指令等諸多因素。捆綁是用于判斷何種硬件資源或者內(nèi)核用于每次調(diào)度操作的流程。例如,Vivado HLs 會自動判斷是否同時使用加法器和減法器,或者是否單個加法減法器就能處理兩次運算。因為捆綁流程制定的決策會影響運算的調(diào)度,比如用流水線化的乘法器代替標(biāo)準(zhǔn)的組合乘法器,因此,調(diào)度過程中應(yīng)考慮捆綁決策。
Vivado HLs 通過如下方式可以加速驗證和設(shè)計優(yōu)化進程:
• 縮短以前的手動RTL 創(chuàng)建流程,并根據(jù)功能C 規(guī)范自動創(chuàng)建RTL,從而避免轉(zhuǎn)換錯誤;
• 迅速方便地完成多種架構(gòu)的評估,致力于打造出理想解決方案。
使用功能C 規(guī)范替代RTL 設(shè)計,加快仿真進程,盡早發(fā)現(xiàn)設(shè)計錯誤。
C 代碼實現(xiàn)與MATLAB 模型極其相似,如下所示。假定在現(xiàn)實世界中,PID 輸入和輸出信號達到用戶能控制的飽和度。PID 系數(shù)(等式7 的GI、GP、GD 和C)以及e(n) 和u(n) 信號的最大值和最小值假定在任何函數(shù)調(diào)用中都是順序加載在PID 內(nèi)核上的。假定兩個輸入和輸出信號也是相同的情況。
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;
}
設(shè)定Zynq-7010 CLG400-1 器件的目標(biāo)時鐘周期為10 納秒,PID 實現(xiàn)在該FPGA 的32 位浮點算術(shù)單元中。首次運行Vivado HLs(圖4 中的“solution1”),估計的時鐘周期為8.49納秒,與FPGA 的118MHz 時鐘頻率對應(yīng)。由于生成輸出需要49 個時鐘周期的時延,有效數(shù)據(jù)速率為2.4Msps。布局布線前估計FPGA 占用面積為7 個DsP48E slice,1,105 個觸發(fā)器和1,790 個查找表。
通過分析Vivado HLs 生成的報告文件,發(fā)現(xiàn)工具生成了兩個浮點加法減法器內(nèi)核。因此采用下列指令:
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 設(shè)計中設(shè)置待映射為FIFO的I/O 函數(shù)參數(shù),而后兩條指令將限制浮點乘法器和加法減法器數(shù)量,每個流程分配一個實例。
再次運行Vivado HLs(圖4 中的“solution2”),估計的時鐘周期為7.96 納秒,與FPGA 的125MHz 時鐘頻率對應(yīng)。對任何輸出值, 有50 時鐘周期的時延, 有效數(shù)據(jù)速率為2.5Msps。估計FPGA 占用面積為5 個DsP48E slice,1,156個觸發(fā)器和1,530 個查找表,這就是最理想的結(jié)果。圖4 的屏幕截圖對這兩種解決方案的Vivado HLs 綜合估計報告進行了比較。
下面的RTL 代碼段是Vivado HLs 自動為頂級函數(shù)生成的VHDL。工具生成的接口信號以clock reset(時鐘復(fù)位)和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ī)范著手,利用有限的資源高效地將數(shù)字PID 控制器實現(xiàn)在賽靈思FPGA 器件中,甚至是在32 位浮點算術(shù)單元中。Vivado HLs 自動生成的RTL 占用面積極小,Zynq-7000 器件僅占用5 個DsP48E slice、1,156 個觸發(fā)器和1,530 個LUT。FPGA 時鐘頻率為125MHz,有效數(shù)據(jù)速率為2.5Msps。僅三個工作日就得到這些設(shè)計結(jié)果,其中大部分時間用于構(gòu)建MATLAB 和C 模型,而非運行Vivado HLs 工具本身。運行僅花了半天時間。
與其他備選方法相比,這種方法具有明顯的優(yōu)勢。尤其是Vivado HLs 負責(zé)將浮點PID 直接映射到架構(gòu)中。這樣可以避免手動實現(xiàn)映射所需的中間步驟,從而改善項目的可移植性和一致性,與一般需要三個工作日以上的手動轉(zhuǎn)換相比,大幅度縮短總開發(fā)時間。