姜麗云,田 澤,2,吳曉成,張 駿,2
(1.中國航空工業集團 西安航空計算技術研究所,陜西 西安 710068;2.集成電路與微系統設計航空科技重點實驗室,陜西 西安 710068)
隨著集成電路設計和制造技術的發展,集成電路的規模及復雜程度成倍增加。圖形處理器需要在RTL設計之前快速地對硬件架構和軟件算法進行驗證,要支持更高的仿真速度、支持時序和行為分開建模和軟硬件混合建模、支持從系統到門級無縫過渡及系統性能分析。傳統的設計模式中使用C、C++語言描述系統設計,使用硬件描述語言(HDL)描述寄存器傳輸級(RTL)設計無法滿足這些要求,因此能夠快速完成對硬件結構和功能驗證的事務級建模(transaction-level modeling,TLM)勢在必行。TLM模型既能充分地掌握各種系統需求和約束,又能基于模擬的方法或形式化方法進行系統功能的驗證,從而在設計早期排除了各種錯誤的可能[1]。
GPU片段處理單元(ROU)位于GPU渲染管線的末尾[2],如圖1所示。片段處理是片段在寫入幀緩存之前所要進行的最后操作,選擇要寫入幀緩存中的片段以及根據條件改變幀緩存中的值。片段處理單元ROU執行OpenGL2.0所規定的片段操作,包括測試(裁剪測試、Apha測試、深度測試、模板測試)、混合、屏蔽、邏輯等操作,以及針對緩沖區的清除操作和累積操作。

圖1 片段處理單元在OpenGL渲染管線中的位置
文中聯合使用統一描述語言UML和SystemC語言在事務級對GPU片段處理單元進行建模研究,采用這種建模方法既可以快速地驗證架構和算法設計中的不足和錯誤之處,節約設計時間和成本,又可以作為基礎模型支持新一代產品的研發,同時,可以對模型進行量化評估,作為模型約束的參考項[3],有利于對結構快速分析,利于架構設計師對其修改和優化[4],最后通過模型仿真結果驗證算法和架構的正確性。
UML作為一種可視化的建模語言,具有概念明確、圖形結構清晰和面向對象等特點,支持各個級別的抽象綜合。在描述復雜的系統結構時,它具有定義良好、易于表達并支持各個級別的有利于開發者快速的確定需求,對方案的有效性和可行性進行評估,衡量各種可選方案的利弊,對軟件設計進行敏捷的思考。UML使用了9種模型圖來對面向對象的軟件系統進行建模[5],滿足了對靜態結構和動態行為進行建模的需求,彌補了傳統SoC設計方法的不足。文中搭建ROU單元的UML視圖模型,開發過程系統的建模行為為驅動,按照建模的不同階段,根據顆粒度從大到小將單元的架構和算法逐層梳理。以下以用例圖、類圖、結構圖和行為圖為例,描述GPU片段處理單元UML建模的過程。
用例圖用于在需求分析階段從用戶的視角來描述和建模整個系統,描述了系統中參與者、用例以及它們之間的關聯、依賴、泛化等關系。ROU單元的用例圖如圖2所示。

圖2 片段處理單元用例圖
其中,ROU單元參與者有PCIE單元、輸出控制單元(OCU)和參數管理單元(SGU)。與PCIE單元關聯的用例有讀、寫ROU單元體系結構寄存器;與OCU單元關聯的用例有查詢ROU單元Ready服務和輸入片段數據到ROU單元;與SGU單元關聯的用例有下發圖形功能命令到ROU單元及狀態查詢服務等。
類圖描述了構成軟件系統的類、接口、子類以及它們之間的關系,是構建其他視圖的基礎,在后面的模型設計中就是通過編程語言構建這些類從而實現系統功能。ROU類關聯于SystemC庫中的sc_module類,繼承了sc_module關聯的所有公共屬性及操作;與ROU單元有依賴關系的模塊包括OCU單元、SGU單元、PCIE單元。接口提供了一組只有名稱的純虛函數,本質是一個使用C++語法定義的抽象類。ROU單元類實現了Ocu2RouPixelIf、PCIeBackendRegIf和SguGraphFunIf接口中提供的方法,內部通過端口來實現對外的連接,端口調用接口中的方法。具體的調用關系及方法定義如圖3所示。

圖3 片段處理單元類圖
ROU單元作為一個結構實體,是用來細化設計的基本塊,內部使用進程來劃分不同執行階段。ROU單元接收來OCU單元輸出的片段數據,存儲在內部的fragmentFifo,經過片段處理進程Fragment_Process_Thread()處理后輸出到顏色緩沖區(PCache)和深度緩沖區(ZCache)。ROU單元還實現接收來自SGU單元的功能碼,由功能碼處理進程Function_Code_Thread()處理來實現特定的累積、遮擋查詢、清除緩沖區等功能,模塊間使用端口傳遞數據,ROU模塊的結構圖及模塊間互聯關系如圖4所示。

圖4 片段處理單元靜態結構圖
行為圖用來描述系統的動態模型和對象之間的交互關系,描述了內部進程的具體執行流程。片段處理進程Fragment_Process_Thread()實現了在片段數據實際存儲到幀緩沖區之前進行的各種測試,包括裁剪測試、alpha測試、模板測試、深度測試;隨后,將要執行混合操作,邏輯操作及單色擴展操作;最后執行掩碼的屏蔽操作后將片段輸出到深度緩沖區和顏色緩沖區,如圖5所示。

圖5 片段處理進程行為圖
功能碼處理進程Function_Code_Thread()處理來自SGU單元的功能碼,實現了清除緩沖區、累積操作、遮擋查詢[6]等指定的功能,ROU單元執行的功能碼如表1所示。

表1 片段處理單元執行的功能碼
TLM模型建立在SystemC標準之上,包括SystemC核心語言、結構化元素、預定義通道、數據類型等概念。SystemC的描述能力支持不同層次的抽象行為,向上可以描述系統級的算法模型,向下可以描述硬件電路的RTL級行為[7]。軟硬件工程師可以基于SystemC在同一個環境下同時描述軟硬件結構和接口,將通信與功能分開,解決了傳統片上系統設計方法中不同級別使用不同描述語言帶來的過渡問題,能提供更高設計效率[8]。
SystemC對標準C++進行了擴充,為系統結構建模提供了硬件時序、并發等概念,體現在核語言的描述上,包括模塊(module)、端口(port)、接口(interface)、信道(channel)、進程(process)、信號(signal)、事件(event)等;另一方面,SystemC支持8種可綜合的數據類型,包括二值信號(sc_bit)、位向量(sc_bv

圖6 TLM模型層次結構及SystemC語言結構
模塊是SystemC設計的最基本單位,實際上就是一個有構造函數和析構函數的類,類似于VHDL中的entity和verilog中的module。模塊使用C++的語法,可以方便地把復雜系統劃分為更小的塊,并且可以方便地隱藏內部的數據和算法,只需要公開接口,以利于其他模塊的調用,是一個能夠包含其他的模塊與進程的層次化實體。下面使用module來描述片段處理單元的框架結構,對應于UML中的結構圖和類圖。
ROU單元module內部包括ports(端口)、processes(進程)、internal data(內部信號)和channels(通道)等部分[11],其中ports用于模塊之間的通信;processes描述module的功能;internal data and channels用于管理module內部的各種狀態,用于module內部processes之間的通信。具體實現如下:
class G3D_ROU:public sc_module,
public Ocu2RouPixelIf,
public PcieBackendRegIf,
public SguGraphFunIf
{
public:
sc_in_clk clock; //時鐘
sc_port
sc_port
……
//例化端口
sc_export
sc_export
……
SC_HAS_PROCESS(G3D_ROU);
//片段處理進程聲明
SC_HAS_PROCESS(Fragment_Process_Thread);
//功能碼處理進程聲明
SC_HAS_PROCESS(Function_Code_Thread);
//構造函數定義
G3D_ROU(sc_module_name _name, sc_trace_file *tf);
//構造函數定義
virtual ~G3D_ROU();
……
private:
//內部變量定義
ds_func_rou::S_Segment segment;
ds_func_rou::S_Rou_Register reg;
sc_uint<8> graphFunCode;
//內部信號定義
sc_signal
sc_signal
……
//FIFO定義
ds_arch_fifo::Fifo< WIDTH> *fragmentFifo;
//內部進程定義
voidFragment_Process_Thread();
voidFunction_Code_Thread();
//內部方法定義
……}
在構造函數G3D_ROU∷G3D_ROU():sc_module(_name)內部,初始化成員變量:Ocu2RouPixelExport(*this); rouArchRegExport(*this);……
將定義的進程注冊到仿真kernel中:
SC_THREAD(Fragment_Process_Thread);
sensitive_pos(clock);
SC_THREAD(Function_Code_Thread);
sensitive_pos(clock);
其中,敏感(sensitivity)與Verilog中的@類似,設置時鐘為敏感事件,敏感向量列表中的信號被觸發后,進程將會被重新激活[12]。
SystemC使用進程對并行行為進行建模,進程作為一個基本執行單位來仿真目標系統的行為,實現模塊的算法細節,具有動態性、并發性、獨立性、異步性和結構性五大特征。進程包括SC_METHOD、SC_THREAD和SC_CTHREAD三種,其中SC_METHOD用于描述方法進程,是唯一可綜合的寄存區傳輸級進程;SC_THREAD用于描述線程,線程能夠被掛起和重新激活;SC_CTHREAD用于描述鐘線程,時鐘線程能在時鐘的上升沿或者下降沿被觸發或者激活,能夠產生更好的行為綜合。
ROU單元定義了片段處理線程Fragment_Process_Thread()和功能碼處理線程Function_Code_Thread(),進程使用wait()掛起,當敏感表中有事件發生,進程被重新激活運行到遇到新的wait()語句再重新掛起。
以Fragment_Process_Thread()為例來描述建模的進程實現方法:
void G3D_ROU∷Fragment_Process_Thread()
{
wait();
segment=fragmentFifo->read();//讀FIFO
if(0x0 !=segment.tileMask)
{
……
segmen.scissor_test(reg);//scissor測試
segment.alpha_test(reg);//alpha測試
if(need_read_depth_buffer()==true)
{
Read_Depth_Buffer();
}
segment.depth_test(reg);//depth測試
segment.stencil_test(reg);//stencil測試
if(need_read_color_buffer()==true)
{
Read_Color_Buffer();
segment.Blend_Operation(reg);//混合操作
segment.Logic_Operation(reg);//邏輯操作
segment.Single_Color_Expand_Operation(reg);//單色擴展操作
}
……
//更新深度/模板緩沖區
Write_Depth_Buffer();
//更新顏色緩沖區
Write_Color_Buffer();
}}
其中,以邏輯操作為例,具體描述算法的實現過程:
void Logic_Operation(S_Rou_Register reg)
{
if(reg.logicOpEn)//判斷邏輯操作使能開關
{
for(pixelNum=0; pixelNum //依次輪詢每個像素 { //判斷邏輯操作類型 switch(reg.logicOperationFunc) { case ds_func_spmu::GL_CLEAR : …… case ds_func_spmu::GL_COPY : …… case ds_func_spmu::GL_XOR : logic_ color_r[pixelNum]=src_r[pixelNum]^color_buf_r[pixelNum]; logic_ color_g[pixelNum]=src_g[pixelNum]^color_buf_g[pixelNum]; logic_ color_b[pixelNum]=src_b[pixelNum]^color_buf_b[pixelNum]; logic_ color_a[pixelNum]=src_a[pixelNum]^color_buf_a[pixelNum]; break; default :} 文中搭建的仿真平臺應用程序運行在Tight-VNC1.3.9版本軟件上,VNC是一款基于Linux和UNIX操作系統的開源軟件[13]。配置Linux內核版本為64位:TARGET_ARCH=linux64。配置SystemC庫版本為SystemC2.3.1,SystemC2.3.1不僅提供了SystemC的語言結構,也提供了用于仿真的kernel[14]。編譯器采用通用的GCC編譯器。對比平臺采用Mesa,Mesa是國際官方組織發布的實現OpenGL應用程序接口純軟件模型,不依賴任何硬件[15]。 本節搭建基于OpenGL2.0標準的GPU片段處理單元測試用例:定義分辨率為1 024*768,首先將屏幕劃分為4個視口,在視口glViewport(0,0,W/2,H/2)繪制原始圖像,繪制一組點、線、三角形和多邊形;在視口glViewport(W/2,0,W/2,H/2)使能邏輯操作并配置邏輯操作類型為GL_XOR,繪制圖像;在視口glViewport(0,H/2,W/2,H/2)使能混合操作,配置像素的RGBA分量的混合等式為GL_FUNC_REVERSE_SUBTRACT,配置像素RGBA源混合因子計算模式為GL_SRC_COLOR,目的混合因子計算模式為GL_DST_COLOR,繪制圖像;在視口glViewport(W/2,H/2,W/2,H/2)使能深度測試,清除深度緩沖區的深度值為0.5,配置glDepthFunc(GL_LESS),繪制圖像。 模型繪制結果和Mesa的繪圖結果分別如圖7(a)、7(b)所示。該實驗驗證了ROU片段處理流程的正確性。 (a)模型繪制結果 (b)Mesa繪制結果 文中聯合使用UML的統一描述語言和基于SystemC的體系結構建模對片段處理單元進行了TLM建模,最后以邏輯操作、混合操作和深度測試為例通過模型仿真結果驗證算法和流程的正確性。采用這種建模方法實現了在RTL設計之前快速的對硬件架構和軟件算法進行探索和驗證,為RTL設計提供參考依據。SystemC支持更高的仿真速度、支持軟硬件混合建模和從系統到門的無縫過渡,在進一步的研究中,可以利用SystemC進行基于虛擬原型系統之上的開發,加速GPU的軟硬件協同設計。2.3 仿真驗證


3 結束語