通過ip覈實現五級流水線的板極驗證——Verilog

  • 實驗目的
    1加深對五級流水線的工程理解,通過適當修改使之能夠在板子上驗證流水線的跑動。本次實驗的板子對象是EGO1(具體的驗證方法將在下面詳細展開),同時使用的工具是vivado,要驗證的流水工程是上次提供的init_test項目(即對於一套指令的運行)。
    2通過IP核的引入,將原來的指令存儲器與數據存儲器通過IP核封裝起來,加深對ROM與RAM的理解,同時瞭解怎麼編寫初始化的coe文件,以及對IP核的使用方法。
    3、增強對項目的理解,拓展需要添加的功能,主要爲了適應板極驗證以及IP核的加入出現的問題,增強實驗工程的robust。通過優化程序使之能夠以較好的頻率(越高越好)運行,探索頻率在這個實驗中的一些影響。
  • 功能概述
  1. 板極驗證的功能介紹

一開始在想怎麼能夠在板子上有效地體現出流水線的跑動過程時有一點懵逼,因爲上一個項目的流水線是直接在Vivado的控制檯直接觀察同時在生成文件的基礎上進行對比驗證的,那麼這一次搬到板子上當然對於每個人都有很大的安排空間,於是我就從上一次驗證的方法入手開始研究怎麼有效地搬到板子上,首先是對於上一次的init_test指令的驗證,我們是在下圖的基礎上研究的:

                     

也就是說我們是通過觀察一系列指令的操作後數據存儲器的地址對應的數據是否正確來判斷指令操作的正確性,這就給我一個很大的方向了,那就是我們通過控制EGO1上的流水線開始工作後,當工作停止後,通過選擇數據存儲器的地址來觀察該地址所對應的數據是否正確來驗證init_test工程的運行,但是之後又覺得沒能體現出運行的過程,於是我又把運行過程中pc的變化值,以及對應時間點對於輸入數據存儲器的地址(即cpu對數據存儲器的請求地址輸出)以及此時對應地址的數據給呈現出來,這樣就會給人一種流水線不斷在跑動的感覺,同時可以看到執行過程中對數據儲存器的調用以及輸出,注意在執行過程中看到的數據地址對應的數據輸出可能與執行後最終的結果不一樣。

有了這種驗證方法,我就大致確定了最終的板極驗證方法了,就是通過一個按鈕作爲CPU運行的啓動鍵,其實在本實驗中就是start變量,一旦按動這個按鈕,我們的EGO1就開始了運行我們事先寫好的的init_test指令;然後當然我們還有一個撥動開關作爲reset鍵,作爲重置作用(這個大家應該都理解他的作用),注意本實驗中reset是低電平有效;然後是enable撥動開關,如下圖

這是一個闡述了reset以及enable對於流水線狀態機的運行影響效果圖,只有當enable一直爲高電平時程序才能不斷驅動流水線正常運行,一旦我們將使能端置零,流水線就會停下來使得我們程序中斷,那麼這時也是我們停下來觀察運行該過程中某個狀態的pc、數據存儲器的地址以及數據的好機會,也就是說,待會的板極驗證,我也會用到這個方法來中斷運行並觀察那個時刻的數據以及狀態;當我們再次將使能端有效化同時再次按動啓動鍵,流水線會正常繼續運行。上面是對於流水線的一個整體架構,也就是一個大概的啓動,中斷,以及重置,但是怎麼看到數據呢?別急,來了。

怎麼觀察數據變動?當然是數碼管嘍,上一次用到數碼管的實驗我記得是驅動七段譯碼管來顯示輸入的數據,因爲EGO1的七段譯碼管總共有八個,而且他們的位選是八位中選一位,但是前後四位的編碼輸入是不一樣的,也就是說我們必須分前後四位的數據進行輸入,這也就有了上一次輸入的原理圖會出現兩個數據輸入,一個位選輸入的原因,這一個是一個重要的問題,一開始在弄的時候忘了這個問題,折騰了好久纔想起這個錯誤。如下圖,這是我們之前實驗課上要實現輸入數據然後在板子通過的顯示管電路,注意我說的兩個數據輸出!(同時我們這是一位輸出數字,在本實驗中我們會利用時鐘信號進行掃描):

下面是對於七段譯碼管的譯碼說明,如圖他說開發板上的數碼管是共陰極的,所以我們編碼的時候也需要注意這個問題:

有了這個七段譯碼管我們就好辦多了,首先只要我們把pc的數值輸出到前兩位就可以啦,然後接下來兩位就是數據存儲器的地址,接下來4位就是我們數據存儲器的數據嘍,簡單地呈現出來,就是這麼直觀。

還有一個我們之前提到的點,就是我們執行結束後,可以通過撥動開關調節要看的數據存儲器的的地址進而觀察到此時相應地址對應的數據是否正確,也就是說我們需要一排8位撥動開關作爲數據存儲器的地址輸入,再有一個撥動開關使得這個輸入有效,進而將此時的數據顯示出來以供我們檢查是否正確。這就是我們在板極驗證待會能看到的大致內容。

 

  1. 實現程序的功能介紹

對於板極驗證的功能擴展,首先對於我們的PCPU程序影響是不大的,爲什麼?因爲我們的五級流水線不會因爲板子而改變嘛,只是我們需要把他們給顯示出來而已,問題來了,我們需要改什麼?你這麼一說的話好像不用改了,錯了!要改。因爲我們需要明確要輸出什麼,顯示什麼。首先最重要的是數據存儲器的輸入地址以及它的數據輸出,這個因爲是我們PCPU的輸入輸出變量,可以直接在頂層文件調用,因此不用改動,其次那些reset、start等等都是有的也不用改,要改的是pc,注意我們的pc是定義在內部的變量,也就是說我們的頂層文件並不會調用到它哦,所以我們需要再添加一個變量來讀取它,同時在這裏提醒一下大家,如果你想顯示更多的reg_c等等的寄存器的數據或者是不同流水線中的ex_ir等等的指令,你可以再多加一個輸入作爲選擇器,選擇要輸出的這個值(我們這裏設置爲pc)是什麼,這樣可以使得你可以看到更多寄存器以及指令操作的值,但是我覺得去分析具體的指令比比較數據更繁瑣,同時難以檢查,所以省去了這個選擇器。

主體的程序已經解決了,接下來就是IP核嘍,我們對於IP的使用是在ROM與RAM中遇到的,當時其實可以通過自己寫出類似於IP核的程序出來,只是封裝起來更方便,同時調用的格式它也給我們設定好了,直接複製改一下就得了,主要在於初始化文件的設定上有需要自己動手的地方。我們首先來看那個指令寄存器,因爲它是隻讀的寄存器,所以我們把他設置爲ROM,然後把init_test的指令通過二進制的值進行初始化輸入就可以了;然後是數據存儲器,因爲它是可讀可寫,所以必須給一個RAM,這是一個我們也設定好初值的寄存器,同樣初始文件需要我們先設定好。這是我們對於數據存儲器的初始化文件,給予給定的初值:

然後是我們對於指令寄存器的賦值,就是將指令翻譯爲數值就行,可以是十六進制,也可以是二進制。如下圖:

 二進制指令初始化文件

如果我們採用十六進制的話,只需將radix改爲16,接下來的初始化就用16進制就行了,盜一下助教師兄的圖來說明一下:

十六進制初始化文件

寫好了數據存儲器與指令存儲器後其實我們還會發現一個問題,就是IP裏面的執行速度是有限的他不能實現你一讀進去就讀出來,也就是說這可能造成CPU在想要獲取數值的時候產生錯誤(我覺得這也有點像hazard),所以你至少需要把IP指定的頻率設定爲高於CPU執行的頻率,因此我們需要使用一個“Clocking Wizard” IP來生成高於100MHz的時鐘,在這裏我使用了200MHz的頻率來供給給數據存儲器以及指令存儲    器以使得它們的運行正常化。

     整體的程序架構已經出來了,接下來就是我們的頂層文件,其實我們都寫過頂層文件,只要分配好要給每個子程序的變量就行了,例如我們提過的需要給數據還有指令寄存器更高的時鐘頻率,而給CPU一個更低的頻率,同時還有七段譯碼管我們也需要給一個高的頻率才能保證它能正常顯示,還有一個需要注意的事情是當我們運用到板極驗證時與仿真是不同的,因爲仿真我們可以在原有較高的頻率下運行,但是一旦接到板子上我們就要降頻率了,所以可以寫一個計數器當計數到一定值的時候再取反時鐘信號就行了,這樣就解決了仿真與板極驗證的問題。還有兩個小問題也提一下吧,一個是“Clocking Wizard” IP提供的locked信號,這個信號它在穩定性上有一定作用,只有當locked有效時才能說明輸出時鐘鎖定成功,輸出有效,所以這也是我們在仿真時一開始遇到的問題,一旦locked沒準備好仿真的數據是錯的,而只有等到locked是有效時我們才能得到有效的輸出,但是在板極驗證就可以忽略這個問題(最好還是注意一下,萬一手速太快),因爲板子沒有那麼快,一般運行是我們已經等到了鎖相環的有效輸出了。還有一個問題是按鍵的消抖,爲了有效的看出運行過程,start只能短暫的拉高,如果CPU執行到HALT了,start還是高電平,CPU就會繼續跑了。但是我在設計過程中發現其實我們的程序運行頻率降低下來後消抖變得不是很重要(和指令有關係),我們可以通過控制enable開關停止操作工程來控制一定的負面影響,也就是說消抖是一個方法,但是我們依然可以很好的利用enable控制過程,同時使能端對於停下來看數據發揮重要的作用。當然這裏最好加上消抖部分,簡單講一下消抖的方法,我們需要用到狀態機來解決這個問題,首先肯定有一個狀態是沒觸發的狀態,我們把它叫做零狀態,在零狀態下我們沒有觸發就仍然是零狀態,一旦觸發就進入下一個檢驗狀態,注意是檢驗狀態;在檢驗狀態下,我們必須讓他下一個狀態就發生轉移,轉移到另一個停滯狀態,在停滯狀態下,有觸發仍然是停滯狀態,沒觸發就恢復零狀態;爲什麼要有停滯狀態呢,因爲我們需要對按太久的按鍵信號只處理成一次,也就是說我們只需要給檢驗狀態下輸出有效值就好了,其他狀態都給出無效值就好啦,這就是消抖,我覺得這樣講應該挺清楚了的,還有狀態機的運行基於時鐘信號,這樣就解決了。

 

三、實驗步驟

  1. 編寫文本文件並編譯

    根據前面的實驗分析、功能介紹,其實我們主要只需在原有的實驗項目上添加IP核就好了,包括數據寄存器的IP核,指令寄存器的IP核還有時鐘加倍的IP核,下面是對於IP核的說明:

                                     數據寄存器的IP核設定

主要考慮是RAM,同時有根據輸入輸出的信道設定寬度深度就好。其他都與之前的RAM設定基本一樣,都是有一個寫使能端、地址選擇端、數據輸出端、數據讀入端。

                                 指令寄存器的IP核

因爲是ROM我們只需讀入時鐘端以及地址端,然後讀出輸出就好。

                                   時鐘限定鎖相環

注意此處主要設定都是默認的,但是要把輸出設定爲200MHz使得輸出我們需要的加倍頻率。

然後具體的頂層文件其實就是將時鐘信號給到時鐘限定的IP核中使得它輸出兩倍的時鐘信號,然後把這個信號給到數據寄存器以及指令寄存器的時鐘端,而它們的輸入輸出就和之前實驗的設計一樣,需要注意的還有CPU的頻率,如果是自動執行的話,需要弄一個降頻來滿足我們的觀察,同時數碼管則需要給一個較高的頻率,但也不能太高,實驗發現過高的頻率出現了錯誤的現象。其他的就是一些細節問題了,例如弄一個控制我們自己輸入數據地址的使能端,弄一個七段譯碼管的函數等等。

2、進行仿真,通過觀察運行過程中的各種執行碼的正確性以及寄存器的變化,同時讀出最終的數據寄存器的地址對應的值進行比對。

3、進行板極驗證,觀察結果。詳細見下面結果的分析。

 

實驗原理

 

Lab2:五級流水線

 

首先對於該實驗,基礎仍然是五級流水線,整體的思路沒有變,我們甚至可以考慮到後面的hazard處理,因爲衝突的存在需要我們不斷去添加一些Nop使得流水線流程能不會產生錯誤的結果,同時也會大大簡化我們對於初始化文件的編寫,例如指令寄存器的初始化我們可以減少很多Nop指令的編寫而直接寫出需要的指令。當然我們這個板極驗證具體原理還是下面這個圖(五級流水線):

 

 

三、實驗結果

• Lab2:

  1. 綜合的RTL電路圖

      

                                        圖一:流水線RTL圖

      如圖一所示,綜合出的RTL圖顯示時鐘加倍後送到數據、指令寄存器中,與CPU進行通信,同時送到7段顯示管進行顯示,沒毛病。

  1. 仿真結果

我們下來看display的結果,就是下圖:

 

可以看到一系列的運行過程,我們要怎麼說它是對的呢,首先看id_ir吧,因爲這是執行指令,是從指令寄存器中取出來的,我們對照前面的那個指令寄存器的初始化文件,有沒有發現是一一對應的?這就說明了我們仿真運行的指令提取正確了,當然會有例外,例如有jump時要注意調到哪裏的指令,這是會有一個變化,但仍然在我們能找到的指令集中。

我們再簡單看一下運行的過程中的一些值的變化吧,(在沒添加hazard時)例如第一條指令將0100送到gr7,在三條指令後我們可以看到gr7出現了0100,第二條指令是要將b600送到r1寄存器,我們看到三個指令後gr1出現了b600,而在這三個指令的間隔中我們也可以看到reg_c1的變化(倒數接受了b600),以及reg_c的變化(倒二接受了b600),還有之前的alu的值都可以明顯看到一系列過程下來的數據流水過程。

接下來看一下運行過程當中的數據輸出地址變化以數據的值,這對於我們之後的板上的現象有一定的對比驗證。

這是對於數據存儲器地址輸入的仿真結果我們可以看到,因爲一開始沒有對於地址的需求,所以reg_C給到數據存儲器的地址是00,選出了fffd,但是由於接下來c號寄存器變爲10,但是時鐘沿沒到因此此時的數據存儲器的數據輸出依然是fffd,對於10地址的響應是到了下一個時鐘沿,即下一次才輸出0000,同樣對於接下來地址00的輸入也是下一次才做出響應,從這裏我們可以看到數據存儲器有受限於時間的影響,因此可以看到IP核的時間需要至少保持在2倍以上的頻率才能響應到我們需要的值的讀出,但由於本仿真實驗中指令被Nop隔開同時到板子上頻率很低的關係在這個小點上沒有暴露這個問題,但是對於板極驗證就一定要改正這個東西,這會嚴重影響實驗結果。這個同時對於reg_c一旦有值就會影響數據讀出,但是是否接受要看下一級的選擇器,即對指令load等的需求。下面是波形的一些部分,對應於我們上面看到的地址信號。

都是在驗證前面對於數據存儲器地址的讀入。

綜上仿真結果合理。

4、開發板的顯示效果圖
- 10 -
正如前面的那個功能簡介已經說了,我們把一號波動開關設爲地址輸入的有效信號,具體的地址信
號在右邊那一行的撥動開關(注意是那一排小的),然後二號撥動開關是 reset 信號,三號撥動開關
是 enable 信號,而按鈕鍵是 start。所以實驗開始時,我們先讓 reset 置零,看到如下:
因爲我們一開始的 pc 和地址都是 0,可以看到數據是 fffd。
接下來我們點擊 start,然後通過撥動 enable 讓程序停下來,記錄數據後撥動它變成有效,再點擊
start 使它繼續執行,看到收集的幾張數據記錄,可以與上面的仿真數據相比較是對應着的。
圖一 圖二
可以看到此時的 pc 執行到分別是 0a 和 2b,那麼這兩個 pc 對應的數據端地址信號分別是 01,03,我們看
仿真表二,當數到第十行時數據端地址爲 01,同時我們查看最後的數據輸出(看上一次項目 dmem 文件的
輸出)可以看到正確的顯示第一號爲數據爲 0004,同樣驗證圖二可以看到 03 地址數據輸出爲 c369。
圖三 圖四
- 11 -
同樣適用於第 13 行的 pc 我們查仿真表二第 13 行是 04 數據地址輸入,因此驗證了現象,同時可以看到
04 位對應於最後的輸出是 69C3,圖四依然驗證了 1b 位的輸出 3690。
接下來我們驗證執行後的數據存儲器的數據正確性,首先是將第一位撥動開關調至有效,然後點擊 start,
運行後然後撥動開關選擇地址,查看數據。(此時 pc 一直爲 00)
通過查看數據我們可以看到當調到 00000010 時,即是選擇 2 號地址輸出 0005;而調到 5(00000101)時
輸出 0041 合理!
當我們調到 1f 時顯示 00c3,同時調到 2f 時顯示 0069,都與上次實驗最後的輸出結果一致,得到驗證。

四、附錄報告

對於功率報告如下:

通過功率報告我們可以看到該實驗項目中總共的功率0.273w以及它的一個分配,整體我覺得不算高耗能,還行。主要消耗在時鐘管理上。同時IO口的輸入輸出也佔據了比較大的部分,但是我們可以大概猜到時鐘管理相比那些其他的邏輯門(它們甚至數量更多)耗能更大,它佔到的比例更高,可能是影響實驗運行的一個重要因素,不管是速度還是頻率接受。

對於利用指數報告:

我們也可以看到佔用較多的是MMCM時鐘管理這一部分,包括前面的那個功率消耗也是它相對較高。應該說對於實驗來說這個時鐘管理顯得極爲佔空間和功率。

而對於時序報告,我採用了兩種方式來研究本次項目實驗的時鐘運行頻率,首先是在軟件上不斷改動我們的頻率(通過約束文件進行改動)進而通過查看時序文件是否報錯來看仿真(或者說理論上的可運行頻率)可以達到多少,當我調節時鐘週期到10ns時可以看到綜合時出現了critical warning,(後來經過不斷試值,好像只要小於10都會出現這種警告)但是在這種情況下,直接改成100ns生成的時序文件如下圖所示,並沒有紅色報錯,初步推測在10MHz下的頻率可以正常工作,但是當我後來把約束條件寫成4ns雖然有提示警告,但時序報告是沒報錯的,所以先預測在250MHz內。時序報告如下圖所示:

紅色的臨界值出現點:

在此基礎上我大概把實驗的頻率約定在150到250MHz以內,當然我們需要用第二種方法,即通過板極驗證來查看是否能夠在板子上正常運行。當然要用這一點的話我還需要做一點點的改變,因爲前面的板極驗證我是經過降頻處理後再加到CPU的處理時鐘上的,現在要用到100Mhz甚至更高,我們可以查看到實際上板子能夠提供給我們的最高頻率(固定頻率)也就100MHz,當我們需要200MHz,250MHz等等,我們是無法通過板子直接給到的,所以這個時候給到CPU的時鐘也是需要通過clk的IP核來實現加倍,即我們知道之前的數據存儲器以及指令存儲器是給到了200MHz的頻率時鐘的,這一次我們把這個200MHz給到我們的CPU時鐘上,然後再製作一個更加高的頻率,本次實驗我用到了600MHz作爲他們的一個頻率時鐘給予數據寄存器以及指令寄存器的時鐘端。實現這一步主要是要改動我們的時鐘管理IP核,(注意此時的約束文件已經可以改回原來的10ns了)設置如下圖:

通過以上設置我們基本實現了200Mhz的輸入時鐘頻率,因爲本次的頻率較高,我將enable鍵放在了按鈕上,以便更加的快速操作,即start鍵隔壁。可以看到我們可以同樣通過運行後(因爲本次運行太快,無法觀察實驗流程的數據變動),通過輸入地址查看輸出數據的準確性。如下圖:

進行到終止時我們可以看到當我撥動到 2a 位置時,查看上次那個數據存儲器文件可以看到數據是 e1b4,
而當我們選到位置爲 1c 時數據是 8000,完全正確!!!
同樣對於 07 位置是 0001,得到驗證。所以基本確定本次實驗的時鐘頻率大致是 200MHz。

四、實驗感想

這一次實驗更多的是對於之前知識的運用與理解,例如主體工程是五級流水線,這個工程已經寫出來了,再多加修改就行了,還有是7段譯碼管的使用,之前也用過,還有IP核的加深理解,同樣的知識點,只是還是需要我們不斷琢磨推敲最終實現。怎麼去調用使用IP,怎麼去驅動數碼管都是我們必須注意的問題,當然更多的是我們怎麼去處理CPU之間時鐘的問題。

發佈了12 篇原創文章 · 獲贊 9 · 訪問量 2719
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章