從Verilog設(shè)計(jì)到AI芯片架構(gòu):微觀與宏觀的設(shè)計(jì)理念框架共通
一、Verilog的設(shè)計(jì)思維
想要使用一種代碼語言做開發(fā),只知道編程語言的語法是沒有意義的,工具只是表面,背后的設(shè)計(jì)思維才是關(guān)鍵。初學(xué)者經(jīng)過一定的學(xué)習(xí),可能可以很快地對Verilog設(shè)計(jì)的基本方式有一些了解,比如通過狀態(tài)機(jī)來控制模塊整體的工作過程等,然而,這通常只是一種粗略的感知,以至于在面對真正復(fù)雜的代碼時(shí)可能還是感覺不太能理解過來,這時(shí)候就是實(shí)戰(zhàn)層面的事情了——看不懂是因?yàn)椴焕斫饽承﹥?nèi)容的意圖,或者不了解芯片設(shè)計(jì)中常見的單元與方法。實(shí)際上,想要提高對Verilog的理解能力,我們得在設(shè)計(jì)思維上做一點(diǎn)提煉嗎,以便更清楚地知道在設(shè)計(jì)電路時(shí)該從哪開始思考、如何用明確的方法實(shí)現(xiàn)需求。
想要有條理地設(shè)計(jì)或理解代碼,我認(rèn)為關(guān)鍵是分清數(shù)字設(shè)計(jì)的2大基本方面:數(shù)據(jù)通路和控制通路。數(shù)據(jù)通路搭載的是電路中說到底想要傳遞的那些“有實(shí)質(zhì)意義”的信號,比如卷積模塊的最終目的是做卷積計(jì)算,這個(gè)計(jì)算說到底是由模塊對輸入特征、權(quán)重/偏置參數(shù)、輸出特征的流動(dòng)做出具體的引導(dǎo)來實(shí)現(xiàn)的。數(shù)據(jù)通路代表著數(shù)字設(shè)計(jì)中具象的思維,其搭載的數(shù)據(jù)流是設(shè)計(jì)者具體地想象好的,所有需要參與運(yùn)算的數(shù)據(jù)按照設(shè)想好的方式流轉(zhuǎn),比如脈動(dòng)陣列里的權(quán)重穩(wěn)定(WS)和輸出穩(wěn)定(OS)數(shù)據(jù)流,就是通過特定的數(shù)據(jù)調(diào)度方式來實(shí)現(xiàn)不同類型的復(fù)用嗎。具體地說,數(shù)據(jù)通路中數(shù)據(jù)信號的走向和軌跡會反映到比如流水線的結(jié)構(gòu)、哪些東西并行、哪些東西串行、計(jì)算電路的規(guī)模(乘法器具體幾個(gè)等)、多路數(shù)據(jù)之間的相互配合等。而控制通路搭載的是為了實(shí)現(xiàn)電路中不同組件的協(xié)同工作所必須存在的那些起控制作用的信號,比如狀態(tài)機(jī)、握手信號(ready/valid)、各種使能信號、標(biāo)識某個(gè)過程起止的start/end信號、標(biāo)識某個(gè)核心或特殊的情況發(fā)生的flag信號等等。控制通路偏向于抽象思維,它們常常很難用單一的具象時(shí)序圖或者其他直白的形式所概括,比如在握手過程當(dāng)中,你不知道現(xiàn)實(shí)中模塊外部的ready或valid會在什么時(shí)候有效,嚴(yán)格來說你只能將握手這件事總結(jié)成一套確切的條件并直接轉(zhuǎn)化為邏輯電路(只不過我們可以通過各種假設(shè)的時(shí)序圖來輔助理解)。控制流伴隨著數(shù)據(jù)流一起在電路中傳遞,從而保證不同組件之間能夠正確地完成信息的交互并各自實(shí)現(xiàn)自己的功能。
在實(shí)際設(shè)計(jì)中,數(shù)據(jù)通路和控制通路是相互交織的。數(shù)據(jù)通路雖然具象,但是往往比較宏觀,而微觀的細(xì)節(jié)與控制通路緊密聯(lián)系。比如你可能可以把一個(gè)模塊的運(yùn)轉(zhuǎn)過程劃分為多個(gè)階段,設(shè)定好每路數(shù)據(jù)的流轉(zhuǎn)方式,但是一方面,具體每個(gè)階段會花多少時(shí)鐘周期來完成是不一定的,這可能要看比如外部輸入過來的源數(shù)據(jù)是每隔多久才會valid一波,或者不同階段之間有沒有處理難度、數(shù)據(jù)量等方面的差異,另一方面,各路數(shù)據(jù)的流轉(zhuǎn)方式復(fù)雜了以后,模塊內(nèi)部的控制往往也更復(fù)雜(比如可能會引入仲裁等過程),從而導(dǎo)致了時(shí)序上的不確定性。因此,具象的數(shù)據(jù)通路主管整體性的模塊結(jié)構(gòu)和數(shù)據(jù)走向,抽象的控制通路則主管底層的交互細(xì)節(jié)。有趣的是,數(shù)據(jù)通路的具象需求會讓一些控制信號也變得具象,比如盡管你無法預(yù)測某個(gè)計(jì)數(shù)器在真實(shí)工作時(shí)的計(jì)數(shù)過程是否是均勻變動(dòng)的、如是不均勻則具體是怎樣的不均勻,但你可以明確地寫出當(dāng)計(jì)數(shù)值等于某個(gè)確切值的時(shí)候,就觸發(fā)狀態(tài)機(jī)的某個(gè)轉(zhuǎn)換,或者生成一個(gè)start/end/flag,這很常見。另外,由于在握手中每個(gè)模塊一定會作為數(shù)據(jù)的發(fā)送者、接收者當(dāng)中的至少一方,所以許多時(shí)候我們的模塊所要輸出給其他模塊的ready或valid其實(shí)也是由我們自己具象地設(shè)定的。因此,總體來看數(shù)據(jù)通路也不是完全具象的,控制通路也不是完全抽象的,只是它們包含的思維方式讓我們懂得去分析每個(gè)信號的具體情況,弄清楚哪些東西要主動(dòng)確定、哪些則要被動(dòng)接受,從而理清所有的東西。明白了這些之后,可以通過這個(gè)視頻來了解一下中央控制和逐級反壓方式的流水線寫法分別是怎樣的——《芯片流水線設(shè)計(jì)思路分享》,一般而言,用于教學(xué)的流水線CPU demo往往基于前者,但后者實(shí)際上也是一種重要且規(guī)范的做法,而且在控制流上更加直觀。
二、AI芯片中的數(shù)據(jù)流與控制流
事實(shí)上,控制流和數(shù)據(jù)流的區(qū)分不僅是微觀設(shè)計(jì)層面的思維,也是我們需要在整體的架構(gòu)設(shè)計(jì)層面建立的認(rèn)識。一般來說,我們把芯片工作模式中像指令調(diào)度這樣的部分稱為控制流,而把一些具有特定的數(shù)據(jù)計(jì)算與流動(dòng)方式的部分稱為數(shù)據(jù)流。這種區(qū)分非常好理解——指令控制著模塊或者說某一電路部分的工作起止,反映到微觀代碼設(shè)計(jì)的層面可能就與模塊里的狀態(tài)機(jī)息息相關(guān),而宏觀意義與微觀意義上的數(shù)據(jù)流也明顯具有相通的含義。有了這樣的概念后,我們就能更清晰地反觀和梳理一下AI芯片的設(shè)計(jì)理念——在AI芯片當(dāng)中,定制化設(shè)計(jì)(即領(lǐng)域定制架構(gòu)思想)被特別強(qiáng)調(diào),因?yàn)橥ㄟ^對算法特性的具體分析和利用才能更好地提高硬件的性能和效率,但如果從控制流和數(shù)據(jù)流這一對概念的角度理解這個(gè)問題,現(xiàn)在如果再來反觀領(lǐng)域定制架構(gòu)思想,就會意識到定制化程度的提高在某種意義上就是在放大數(shù)據(jù)流的重要性,因?yàn)楫?dāng)我們根據(jù)AI算法在計(jì)算過程、訪存模式、數(shù)據(jù)稀疏性等方面的特點(diǎn)而設(shè)計(jì)一些定制化的硬件時(shí),其實(shí)就是在創(chuàng)造特定的數(shù)據(jù)流,從而達(dá)到提高計(jì)算并行度、減少冗余訪存、跳過冗余計(jì)算、簡化復(fù)雜操作等各種各樣的目的。這種對數(shù)據(jù)流優(yōu)化的格外強(qiáng)調(diào),我覺得是AI芯片區(qū)別于傳統(tǒng)處理器芯片的關(guān)鍵。
在芯片設(shè)計(jì)中,控制流與數(shù)據(jù)流的相互平衡和各司其職是非常重要的。盡管AI芯片需要我們特別關(guān)注數(shù)據(jù)流的設(shè)計(jì),但是數(shù)據(jù)流在芯片架構(gòu)與工作模式中具體占有多大的比重,則是一個(gè)需要我們自己折中的問題。在計(jì)算機(jī)架構(gòu)理論中,人們一般把通用處理器架構(gòu)(一般認(rèn)為即是馮·諾依曼架構(gòu))稱為control flow架構(gòu),并定義了所謂的data flow架構(gòu)來表示與control flow架構(gòu)相反、以數(shù)據(jù)驅(qū)動(dòng)計(jì)算的架構(gòu)[1][2]。其中,第2篇博客對data flow架構(gòu)的解讀比較好地解釋了我們在這里想要強(qiáng)調(diào)的對控制流與數(shù)據(jù)流之平衡的反思,即最原始的、狹義的data flow架構(gòu)中是沒有任何控制調(diào)度部分的,而是在硬件開始工作前先由AI編譯器(或人為地)規(guī)劃好計(jì)算通路對應(yīng)的硬件結(jié)構(gòu),讓AI計(jì)算圖被直接映射成硬件上的數(shù)據(jù)流。這種完全基于數(shù)據(jù)流的架構(gòu)或多或少會因?yàn)閷μ囟ㄓ布Y(jié)構(gòu)的過高需求而在通用性上受到限制,一旦算法對象有所變化,就必須重新生成對應(yīng)的硬件,這件事即使對于能重新燒錄的FPGA來說在現(xiàn)實(shí)情景中也很有困難,并且我們未必能保證對于任意規(guī)模的算法都能拿出足夠充足的硬件資源來把計(jì)算圖的所有部分映射成分立的硬件。因此,為了實(shí)現(xiàn)一種更均衡的方案,AI加速器最終還是需要控制流與數(shù)據(jù)流的良好結(jié)合。一方面,我們可以把控制流負(fù)責(zé)的部分定義在以算子模塊為最小單位的層面上,而在算子模塊自身內(nèi)部可以設(shè)計(jì)定制化的數(shù)據(jù)流(比如脈動(dòng)陣列),這樣既能夠直接地兼容那些涉及同樣算子但在結(jié)構(gòu)和計(jì)算過程上有區(qū)別的同類算法,又保留了數(shù)據(jù)流創(chuàng)新的空間,從而真正提升加速器的各方面效果。另一方面,我們可以像上面的第2篇博客所說的那樣把原始的data flow架構(gòu)作為一種思想,實(shí)際采用以片上互連網(wǎng)絡(luò)(NoC)連接硬件單元的形式,保留通過頂層的控制模塊做控制調(diào)度的部分,并把控制調(diào)度最終轉(zhuǎn)化為比如NoC中硬件單元間連接規(guī)則的配置,從而實(shí)現(xiàn)定制化但又可調(diào)整的計(jì)算通路,遇到硬件資源不足以支撐算法對象全流水計(jì)算的情況也可以按分輪次計(jì)算的模式做調(diào)度,這樣便能具有更好的通用性。需要注意的是,這2種做法之間其實(shí)也沒有太涇渭分明的界限,例如在Overlay架構(gòu)中,雖然算子模塊一般是各自作為通過總線與存儲模塊相連的主機(jī),但如果我們在算子模塊之間添加一些直接的互連并定義配套的指令控制規(guī)則,而非讓算子模塊的工作完全隔離,也就可以實(shí)現(xiàn)類似于上述第二種做法的思路了。總而言之,AI芯片中的控制流與數(shù)據(jù)流需要找到一個(gè)平衡點(diǎn),這里討論的設(shè)計(jì)范式也只是作為參考,至于具體的創(chuàng)新與實(shí)現(xiàn),就看實(shí)際研究中的探索了。

浙公網(wǎng)安備 33010602011771號