IEC61499 在FPGA中的實現(xiàn)
掃描二維碼
隨時隨地手機看文章
PLC 與“軟件PLC“
早期的PLC 是使用繼電器實現(xiàn)邏輯控制的。也就是說,它們完全是硬件實現(xiàn)的。當微處理器出現(xiàn)之后,PLC 內(nèi)部使用了CPU和程序來實現(xiàn)控制邏輯?,F(xiàn)代PLC中也使用了實時操作系統(tǒng)以及各種網(wǎng)絡(luò)協(xié)議。自動控制行業(yè)的專家總是將在通用操作系統(tǒng)上運行的PLC控制程序成為“軟件PLC”,普遍認為軟件PLC 沒有PLC 設(shè)備可靠,實時性沒有PLC設(shè)備強。這其實是一種誤解。某種意義上講,現(xiàn)代的PLC 都是軟件PLC。它們之間的唯一差別是PLC設(shè)備是在特定硬件平臺上實現(xiàn)的實時操作系統(tǒng)和程序具有更高的實時性,確定性和穩(wěn)定性。它們經(jīng)過了廠商預先反復的測試。確保了軟硬件匹配的的更好。如果重視軟硬件的相互匹配,在通用硬件平臺上,同樣能夠?qū)崿F(xiàn)可靠運行的PLC 系統(tǒng)。比如倍福公司的工業(yè)電腦就是在微軟公司為其定制的windows 下運行。同樣非常的可靠。
在實時性方面,大多數(shù)PLC 使用實時操作系統(tǒng)(RTOS),比如VxWorks OS。這是一個可靠性,實時性極強的實時操作系統(tǒng)。不過,RTOS的處理能力也是有限的,設(shè)想編寫一個“巨大”的程序在PLC上運行, 也會出現(xiàn)性能下降問題。只是PLC 設(shè)備預留了足夠的資源來保證在特定的應用中的需要,通俗地講,“就是殺雞用牛刀”。
實時操作系統(tǒng)本質(zhì)上是操作系統(tǒng),只是內(nèi)部調(diào)度算法上考慮了對外部事件的響應事件而已。但是令人遺憾的是,幾乎所有的OS 調(diào)度算法都只是“盡力而為”。PLC 的做法是預留了足夠的硬件算力,來確保應用程序滿足實時性的要求。為了提高PLC 的算力,高性能的PLC內(nèi)部采用了FPGA 來實現(xiàn)實時性要求高的功能,例如產(chǎn)生高速PWM 和脈沖輸出,運動控制模塊,脈沖計數(shù),電機編解碼器等。
開放性的挑戰(zhàn)
現(xiàn)代控制系統(tǒng)對PLC 提出了越來越高的要求,例如導入更復雜的控制算法,AI模塊和云端交互功能,它們對PLC 內(nèi)部CPU/FPGA 提出更高的算力需求,另一方面,控制系統(tǒng)朝著開放性方向發(fā)展。第三方開發(fā)者和最終用戶參與PLC 功能塊的開發(fā)。在PLC 的生命周期內(nèi)會變更程序和功能塊升級。如此一來,PLC廠商其實能難預估應用程序?qū)λ懔Φ念A估。并且難以承諾產(chǎn)品的實時性。而是又第三方開發(fā)者和用戶能夠更高效地方式來保證系統(tǒng)的實時性能。
IEC61499 的實時性
目前大多數(shù)的IEC61499 功能塊和運行時是軟件實現(xiàn),并且在PC或者Linux 設(shè)備上運行。因此IEC61499 目前是一個典型的“軟”控制器。
問題的確是存在的,IEC61499 運行時的實時性和確定性的確令人擔心的。為了解決這個問題,可以吸取PLC 的方式
-
提高設(shè)備內(nèi)部的SOC算力的富余量
-
采取FPGA 對功能塊加速
-
硬件實現(xiàn)實時功能塊網(wǎng)絡(luò)。
采取FPGA 對功能塊加速
通過對一些對算力比較大的功能塊使用FPGA 實現(xiàn),能夠縮短功能塊的執(zhí)行時間。提高功能塊網(wǎng)絡(luò)的實時性。
功能塊內(nèi)部的算法由FPGA IP來實現(xiàn)。FB實現(xiàn)PS/PL 之間的數(shù)據(jù)交換。類似的FB包括:
-
高速PWM 發(fā)生器
-
高速脈沖計數(shù)器
-
FFT 快速傅里葉
-
數(shù)字濾波器
不過這種方式具有局限性,功能塊之間的數(shù)據(jù)和事件的傳遞和功能塊的調(diào)度仍然是由軟件實現(xiàn)的,存在著非確定性。對于像高速電機控制中,控制環(huán)由多個功能塊構(gòu)造而成,如果由軟件實現(xiàn)功能塊之間的數(shù)據(jù)傳遞,整個系統(tǒng)的實時性,確定性難以保證。
硬件實現(xiàn)實時功能塊網(wǎng)絡(luò)
將實時處理要求高的一端功能塊網(wǎng)絡(luò)(譬如一個PID 環(huán)控制)使用FPGA來實現(xiàn),而配置,監(jiān)控和事務(wù)交互功能塊仍然由軟件實現(xiàn)。這樣完整的硬件實現(xiàn),避免了軟件的干預而造成不確定性和實時性。并且能夠高速地處理控制算法和信號處理。
某一段功能塊網(wǎng)絡(luò)的硬件實現(xiàn)最好的方法是將這些硬件功能塊網(wǎng)封裝成為復合功能塊。通過工具軟件將這個復合功能塊轉(zhuǎn)換成為FPGA 硬件語言(HDL,verilog等)。由FPGA開發(fā)工具vivado 轉(zhuǎn)換成FPGA 比特流。
IEC61499 硬件功能塊的實現(xiàn)
筆者初步開始嘗試FPGA 實現(xiàn)IEC61499 的方法,使用xilinx zynq 作為SOC平臺。由于IEC61499 并不普及,網(wǎng)絡(luò)上相關(guān)的文章非常少。也只能自己慢慢摸索
在IEC61499 運行時的實現(xiàn)中,功能塊大多數(shù)采用了C++ 類實現(xiàn),因此我們希望采用HLS 來實現(xiàn)C++類為基礎(chǔ)的IEC61499 功能塊,但是發(fā)現(xiàn)HLS 幾乎是為復雜算法而準備的,使用C++類的介紹非常少,如果去實現(xiàn)與數(shù)字邏輯非常接近的功能塊,好像不如verilog 語言更簡單。
verilog 語言以module 為一個編程單元,相當于C語言中的一個函數(shù)(function),但是由于硬件的特殊性,所有的變量都是靜態(tài)分配的,所以與C++的類又有幾分相似,內(nèi)部實現(xiàn)ECC狀態(tài)機和算法十分方便。與此同時,verlog 的功能塊能夠?qū)嵗T诹硗獾哪K中實現(xiàn)實例。與IEC61499 功能塊實例化十分相像。使用verilog 語言編寫IEC61499 硬件功能塊更加合適。
例子1-E_CTD 功能塊
下面是筆者使用verilog 實現(xiàn)的一個E_CTD 計數(shù)器
`timescale 10ns / 1ns module e_ctd(cd,ld,cdo,ldo,pv,cv,q); input cd,ld; input [15:0] pv; output reg q,cdo,ldo; output reg [15:0] cv; reg [15:0] v; always@(posedge cd) begin if (cv==0)begin cv <= v; #5 q=1; end else begin cv <= cv - 1; #5 q=0; end #5 cdo=1; #5 cdo=0; end always@(posedge ld) begin v <= pv; cv <= pv; ldo=1; #10 ldo=0; end endmodule
在上面的程序中,忽略了ECC 的實現(xiàn)。module e_ctd是功能塊,下面的test 是仿真程序
仿真的結(jié)果
IEC61499 基本功能塊都是底層邏輯構(gòu)建得,使用verilog 語言描寫非常合適,如果要深入研究IEC61499 功能塊硬件化得課題,需要開發(fā) hardware function block 庫。在這個基礎(chǔ)上開發(fā)一些構(gòu)建工具(XML->verilog)
例2 -E_CYCLE 功能塊
`timescale 10ns / 1ns module e_cycle(start,stop,eo); input start,stop; output reg eo; parameter FREQ = 100000; // in constraint_mode parameter DUTY = 50; // in percentage parameter clk_pd = 1.0/(FREQ * 1e3) * 1e9; parameter clk_on = DUTY/100.0 * clk_pd; parameter clk_off = (100.0 - DUTY)/100.0 * clk_pd; reg start_clk; initial begin eo <= 0; start_clk <= 0; end always @(posedge start) begin if (start) start_clk=1; end always @(posedge stop) begin if (stop) start_clk=0; end always @(posedge start_clk) begin if (start_clk) begin while (start_clk) begin #(clk_on) eo=1; #(clk_off) eo=0; end end end endmodule
例3 -E_T_FF
`timescale 10ns / 1ns module E_T_FF(clk,eo,q); input clk; output reg eo,q; initial begin q=0; eo=0; end always @(posedge clk) begin if (clk) begin q <=~q; eo=1; #2 eo=0; end end endmodule
測試程序
測試程序完成IEC61499 功能塊網(wǎng)絡(luò)。
`timescale 10ns / 1ns module test(); reg cd,ld; wire cdo,ldo,q,q2; wire [15:0] cv; wire ecycle_eo,e_t_ff_eo; reg start,stop; E_CYCLE #(.FREQ(200000)) ecycle1(start,stop,ecycle_eo); E_CTD #(.PV(8)) etcd1(ecycle_eo,ld,cdo,ldo,cv,q); E_T_FF e_t_ff(cdo,e_t_ff_eo,q2); initial begin #5 ld =0; #5 ld=1; #5 start=1; #5 start=0; end initial $monitor("at time %t ,",$time,"CDO=%b,LDO=%b,Q=%b,CV=%b",ecycle_eo,ldo, q,q2); endmodule
仿真結(jié)果
軟硬件接口
實現(xiàn)IEC61499 硬件功能塊,需要設(shè)計一個統(tǒng)一的軟硬件接口。如下圖所示。
-
IEC61499 運行時通過HFB API 訪問硬件功能塊
API 包括:
Event_Action() 向硬件FB 發(fā)送事件
Put_Data 向FB 發(fā)送數(shù)據(jù)
Get_Data讀取FB數(shù)據(jù)
Event_Notify() 處理FB 輸出的事件中斷。(也可以是查詢方式)
-
ARM 處理器通過AXI-lite 接口與PL 端的AXI 外設(shè)IP 通信
write Register
readRegister
interrupt processing
AXI 外設(shè)寄存器
輸入事件寄存器(Input Event register)
輸出事件寄存器(Output Event register)
輸入數(shù)據(jù)寄存器(Input Data Register)
輸出數(shù)據(jù)寄存器(Output Data Register)
操作過程
事件輸入
當需要向功能塊注入事件時,運行時向輸入事件寄存器對應的bit 位置 1,硬件FB 檢測輸入事件寄存器的狀態(tài),一旦發(fā)現(xiàn)變化,轉(zhuǎn)向事件處理。完成后,清除對應的狀態(tài)位。
事件輸出
當功能塊輸出一個事件時,在輸出事件寄存器相關(guān)位置1,并產(chǎn)生一個中斷信號。由運行時軟件讀取事件寄存器,并且清零。
數(shù)據(jù)輸入/輸出
由軟件直接寫入或讀取數(shù)據(jù)輸入寄存器。這一點與軟件實現(xiàn)有所不同,軟件FB 處理時是通過 getDataIn根據(jù)connection 去數(shù)據(jù)源功能塊中讀取的。對于硬件FB,當事件來臨時,API要根據(jù)事件-數(shù)據(jù)關(guān)聯(lián)性,調(diào)用getDataIn 讀取數(shù)據(jù)后需要寫入數(shù)據(jù)輸入寄存器中。
結(jié)束語
這只是一個開頭,還有許多工作要做
1 軟件功能塊與硬件功能塊的接口的實現(xiàn)方式
2 如何將IEC61499 復合功能塊的XML 描述轉(zhuǎn)換成verilog 的模塊。
3 如何調(diào)用HLS 產(chǎn)生的IP






