pos機開機一直初始化,如何初始化應用表單位置

 新聞資訊  |   2023-03-04 08:57  |  投稿人:pos機之家

網上有很多關于pos機開機一直初始化,如何初始化應用表單位置的知識,也有很多人為大家解答關于pos機開機一直初始化的問題,今天pos機之家(www.tonybus.com)為大家整理了關于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、pos機開機一直初始化

pos機開機一直初始化

FPGA調試本身就是挺辛苦的一件事情,尤其是在剛開始調試FPGA的時候,無論培訓的時候如何強調一些注意事項,如跨時鐘域問題,如接口問題,以及RAM讀寫沖突問題,但一旦做起項目來,每每還是有同學必須要親自往這些坑里面跳一次才真正懂得這些BUG的含義。如雙口RAM在功能仿真時沒有出現問題,但上板調試過程中運行很久才偶爾出現一次BUG,這時就需要花費大量的時間去追溯問題的源頭,最后花一周甚至更長的時間才能找到是雙口RAM讀寫沖突的問題,時間早早的就浪費掉了。事實上,上面說跨時鐘域或者雙口RAM讀寫沖突的這些問題是可以通過時序仿真仿真出來的。

FPGA驗證在芯片設計流程中具有重要的作用,有時候為了找到某些BUG,不得不對FPGA綜合出來的網表進行后仿真。后仿真又叫時序仿真,跟課程前面介紹的對寫出來的Verilog hdl設計代碼和testbench代碼建工程進行的功能仿真不同,時序仿真是把綜合出來電路中的時延信息加入到仿真的過程中,模擬出跟更接近于在FPGA上真實運行的情況。本文以Quartus II軟件為例進行介紹后仿真的步驟和流程。ISE或VIVADO流程類似或關聯ModelSim后更自動化。

什么是功能仿真?什么是時序仿真

仿真過程是正確實現設計的關鍵環節,用來驗證設計者的設計思想是否正確,及在設計實現過程中各種分布參數引入后,其設計的功能是否依然正確無誤。仿真主要分為功能仿真和時序仿真。功能仿真是在設計輸入后進行; 時序仿真是在邏輯綜合后或布局布線后進行。

1. 功能仿真 ( 前仿真 )

功能仿真是指在一個設計中, 在設計實現前對所創建的邏輯進行的驗證其功能是否正確的過程。 布局布線以前的仿真都稱作功能仿真, 它包括綜合前仿真( Pre-Synthesis Simulation )和綜合后仿真( Post-Synthesis Simulation )。 綜合前仿真主要針對原理框圖的設計 ; 綜合后仿真既適合原理圖設計 , 也適合基于 HDL 語言的設計。

2. 時序仿真(后仿真)

時序仿真使用布局布線后器件給出的模塊和連線的延時信息, 在最壞的情況下對電路的行為作出實際地估價。 時序仿真使用的仿真器和功能仿真使用的仿真器是相同的, 所需的流程和激勵也是相同的; 惟一的差別是為時序仿真加載到仿真器的設計包括基于實際布局布線設計的最壞情況的布局布線延時, 并且在仿真結果波形圖中,時序仿真后的信號加載了時延, 而功能仿真沒有。

一、用Quartus II建立工程。

具體過程可參考如下鏈接:

https://jingyan.baidu.com/article/cbcede07ef59cf02f40b4ddb.html。建立工程后的文件如下圖所示。我們以一個簡單的8位計數器為例進行說明。


建立工程的過程中可以配置好綜合之后要產生用來做后仿真的網表文件,如果沒有提前配置,也可以建好工程后再配置,具體如下圖,點擊右鍵,選擇settings.


settings打開后出來如下窗口,在左側選擇Simulation,在右側EDA Netlist Writer settings里面選擇門級網表產生的語言以及路徑,之后確定即可。


如下圖,點擊編譯按鈕,開始進行綜合。


綜合后的界面如下。


找到剛設置的網表文件的輸出目錄,在該目錄下要選擇兩個文件,一個是.vo的網表文件,另一個是.sdo的時延信息文件。


打開.vo的文件可以看到里面有如下圖的三行,就是把時延信息文件.sdo反標到網表文件中。沒有這一句或者時延信息反標不成功,是做不成后仿真的。


用ModelSim進行后仿真

把上述過程中產生的.vo和.sdo文件拷貝到要做后仿真的工程文件夾下建立仿真工程,除了測試文件采用前仿真的測試文件外,還要添加一些Quartus的庫文件,主要有三個,220model.v,altera_mf.v和cyclone_atoms(這個文件需要根據進行綜合時選擇的FPGA的型號來定)。注意,此工程是不能添加原始設計代碼的,而是用綜合后的網表文件替代。建立工程后的截圖如下。

時序仿真的工程


功能仿真的工程

從上面兩圖可以明顯對比出,功能仿真和時序仿真工程中的代碼僅有count.v(功能仿真)和count.vo(時序仿真)不同,其余都完全一樣。

編譯成功后開始仿真。


右鍵點擊下圖中tb_count選擇信號到波形文件的窗口。


運行后的結果截圖,可以看出計數器是按照時鐘的上升沿在自加1跳變的。


選擇局部,計數數據由7跳變到8的時刻進行放大,可以看到,7狀態后不是立即跳變到8的,而是經過了很多個中間狀態。同時開始跳變的時刻也不是時鐘的上升沿到來后立即跳變的,而是延遲了一段時間才開始的。


再進行放大,可以看到7變為8中間還經歷了11和9兩個中間狀態,同時觀察下面每Bit信號的跳變,可以發現每1位信號的跳變時刻也是不同的,這是因為在FPGA內部,總線型信號布局布線后每bit的走的路徑是不同的,連線引入的時延也是不同的,這也進一步證明了后仿真的時延信息是成功的反標到了網表文件中了。同時,這種總線型信號跳變有很多中間狀態的特點,也是區別于前仿真或者叫功能仿真的一種最直接的標記。

我們回過頭來對比一下功能仿真的波形,如下圖,很明顯的看出來在計數跳變的過程中,沒有任何中間狀態的改變。

動圖介紹ModelSim建工程到仿真

使用Modelsim建立仿真環境進行仿真的操作步驟動圖如下:

補充知識--前仿真和后仿真的概念

功能仿真和時序仿真常常又分別被叫做前仿真和后仿真。

前仿真和后仿真的區別:前仿真就是指綜合前的仿真,也就是行為級的仿真,如你在Modelsim直接寫代碼的仿真。后仿真指的是綜合后的仿真,也就是功能仿真。比如你在Modelsim中用VHDL寫了個計數器,行為級得仿真通過了,你把它加到quartus中或者其他的綜合工具進行綜合,綜合完后生成功能網表,它把行為語言變成寄存器傳送級語言,這時候你把它加到Modelsim中仿真叫后仿真,后仿真成功后,你還要在quartus中進行映射,布局布線,完后進行時序分析,生成時序網表,描述器件里門或者布線的延時,最后把延時網表和功能網表一起加到Modelsim中仿真叫門級仿真。

門級仿真和時序仿真的區別:門級仿真是quartus生成的網表文件.vo。門級則不考慮互聯延遲,二只考慮了器件的延遲。時序仿真是選擇具體器件并布局布線后進行的包含定時關系的仿真,主要驗證是否滿足時間約束關系、延時、最大工作頻率和消耗的資源等。時序仿真是需添加時延文件.sdo。

modelsim 是專門進行仿真的軟件,可以分別進行前仿真和后仿真。前仿真也稱為功能仿真,主旨在于驗證電路的功能是否符合設計要求,其特點是不考慮電路門延遲與線延遲,主要是驗證電路與理想情況是否一致。可綜合FPGA代碼是用RTL級代碼語言描述的,其輸入為RTL級代碼與testbench。后仿真也稱為時序仿真或者布局布線后仿真,是指電路已經映射到特定的工藝環境以后,綜合考慮電路的路徑延遲與門延遲的影響,驗證電路能否在一定時序條件下滿足設計構想的過程,是否存在時序違規。其輸入文件為從布局布線結果抽象出來的門級網表、testbench和擴展為sdo或sdf的標準時延文件。sdo、sdf的標準時延文件不僅包含門延遲,還包括實際布線延遲,能較好地反映芯片的實際工作情況。一般來說后仿真是必選的,檢查設計時序與實際的FPGA運行情況是否一致,確保設計的可靠性和穩定性。

在進行網表仿真時,經常會遇到一些不定態問題(紅線的說法稍顯不專業),通常一個模塊中某個寄存器出現X狀態,就會造成整個仿真都出現X狀態,仿真無法進行。這時我們需要找出最先出現X態的邏輯,找出錯誤的原因并消除后才能重新進行仿真。

a. 首先應該查看是否所有的RAM都進行了初始化操作。雖然很多RAM在實現功能時并不需要初始化,但后仿時沒有初始化的RAM讀出X態,X會蔓延出去,造成整個系統都出現X態??刹捎胿erilog中系統任務readmemh對RAM進行初始化操作。

b. 異步時鐘域信號賦值很可能會導致后仿出現紅線,但這并不能說明系統錯誤,通常我們讓仿真平臺不去檢查異步時鐘域賦值導致的時序違例,從而消除這部分紅線。

c. DUT與外部testbench模型接口時序不匹配導致,系統采進來數據錯誤導致紅線。比如以太網的GMII接口,最開始建立ephy模型時是在RTL仿真環境下描述的,在Rx_clk上升沿發出Rxd數據;但在做后仿真時由于時延等的影響,按上升沿進來的數據就會出現時序違例。這時就需要我們修改ephy模型,讓數據Rxd在上升沿后延遲一段時間再送出,使GMII接口滿足時序要求。

d. 組合邏輯路徑過長導致的時序為例。如下圖所示是讀取RAM的時序波形,讀地址ADR,讀使能ME,時鐘CLK,當時鐘上升沿到來時,應該讀取ADR為0x40地址的數據,但是由于兩個寄存器之間的組合邏輯時延很大,在讀RAM的上升沿到來時RAM地址沒有保持穩定,出現時序為例,導致輸出數據線是X態。如果是在代碼設計時,我們應該盡量避免這種情況的發生,減小組合邏輯的復雜度以減小時延。

后仿中時序問題

加快后仿真的方法

在做后仿時,跑1ms的數據通常是前仿的幾十倍,甚至幾百倍,所以如果要把前仿的所有測試例都跑完通常幾天幾夜也不一定能走完所有流程,而且仿真過程中還可能經常遇到一些問題,阻止仿真進行下去。如果能夠加快仿真的速度,將會大大提高我們的工作效率。

a. 通常測試過程中,我們會把互相不影響的測試例分開運行,這樣既可以同時運行多個測試例,又可以在某一個測試例發生錯誤時,減少重新測試需要的時間。

b. 在運行某一個測試例時,如果這個測試例需要運行的模塊可以完全獨立于其它模塊,那么我們就可以利用force語句將其它模塊的時鐘強制拉低,這樣其它模塊就不會運行。例如在測試CPU的外設時,并不會對設計模塊部分進行任何操作,如果把設計模塊的時鐘拉低,會大大縮短外設測試的時間。但在做后仿時force語句應慎用,如果把設計模塊里的時鐘拉低,跟這一模塊相連的時鐘信號也可能被拉低,造成需要測試的部分無法運行,只有把測試部分模塊的時鐘重新釋放(release)掉才能正常運行。

c. 有些需要CPU初始化的RAM,如流控、隊列門限等RAM,在CPU寫RAM的過程需要大量的時間,如果RAM讀寫測試已經通過,沒有必要再通過CPU寫RAM,可以利用上面RAM初始化文件的方法,把需要配置的值寫進RAM中,可以大大縮短運行時間。


應用實戰

雙口RAM的讀寫沖突問題在FPGA調試中經常遇到,并且,往往是那種費了好大勁追信號追到吐血后才確認到的問題。在初學FPGA調試中,常常為了所謂的省事,在寫代碼設計仿真階段就忽略了雙口RAM的讀寫沖突問題(讀和寫對同一個地址同時進行操作,功能仿真時可能沒有出現,但因為有時延的原因,在時序仿真時就出現了),導致在FPGA上板調試中浪費大量的時間。在進行FPGA工程上板調試前,如果能夠進行雙口RAM的后仿真,就可以避免后期無窮盡的追信號最后定位到雙口RAM讀寫沖突上了。希望能夠給大家提個醒,內容雖然簡單,但的確是不容忽視的一個隱藏很深的大問題。

FPGA 內部塊RAM 的讀時序如下圖:

可知,塊RAM的讀延時為兩個時鐘周期。

FPGA 內部塊RAM 的寫時序如下圖:

可知,塊RAM 的寫延時為0,但是RAM 中的內容是在寫的下一個時鐘改變。

在進行代碼設計時應該盡量避免對一塊RAM的同一個地址同時進行讀寫操作,防止讀寫沖突時讀出數據是X態。

對于單端口RAM不能對同一RAM進行讀寫,對于雙端口RAM可以從兩個端口對同一地址進行讀操作,但不能同時進行寫操作也不能同時進行讀寫操作。

? 問題

隊列長度信息RAM a b口讀寫異常,更新出錯。

? 現象:

端口卡死,某隊列長度達到最大門限,但是發送調度顯示隊列為空,新數據幀入隊申請,不滿足門限要求而丟棄,輸出沒有調度結果,也不能出隊操作;

? 分析定位:

根據現象中停止發送,對隊列長度信息更新相關信號進行Debug測試,定位出問題的根源位置如圖a所示,該隊里進行入隊操作后,隊列長度信息被入隊調度通過隊列信息RAM a口更新寫入長度13,此時出隊操作正在執行,在獲取隊列長度信時,在a口剛寫入后的一個clk,讀取得到隊列長度信息為12,再經過1個clk,數據穩定在13;但是異常數據12被出隊操作獲取到并用于出隊號隊列長度的更新,隊列長度更新出錯,若干次操作后,當最后一幀出隊完成后,會將隊列長度更新為負數,如圖b所示,FPGA中不操作負數,即二進制中很大的正數,遠大于隊列最大門限,后面再進行入隊操作時,入隊操作不滿足門限要求,無法入隊操作,同時出隊操作認為隊列為空,不會調度該隊列出隊操作,進入卡死狀態;隊列長度13的二進制表示為1101’b,12的二進制表示為1100’b,說明出現了單bit翻轉錯誤的問題。

圖a 雙口RAM a b口讀寫異常

圖b 隊列長度信息更新出現負數

? 解決方法:

首先考慮對RAM輸出加寄存操作,但是這樣會整體引入操作時延,即使入隊和出隊操作不是同一隊列,每次在RAM讀數據情況下都需要多等一個clk,為了解決該問題,采用的方法是在出隊操作需要讀隊列長度時,如果前一個時刻a口剛更新該隊列,此時a口晚一個clk再用數據,保證第二個clk讀出的數據是a口寫入穩定輸出的,其他情況下不引入時延。

源碼

1、tb_count.v

`timescale 1ns/100ps

module tb_count;

reg clk;

reg reset;

reg d;

wire [7:0] q;

initial

begin

clk=1\'b0;

reset = 1\'b0;

d = 1\'b0;

#10 reset = 1\'b1;

#1 d = 1\'b1;

#10 reset = 1\'b0;

#34 d = 1\'b0;

#1000 $stop;

end

always #10

clk = ~clk;

counter u_counter(

.clk(clk),

.reset(reset),

.d(d),

.q(q)

);

endmodule

2、counter.v

`timescale 1ns/100ps

module counter(

clk,

reset,

d,

q );

input clk;

input d;

input reset;

output [7:0] q;

reg [7:0] q;

reg [7:0] q_ff1;

reg [7:0] q_ff2;

reg d_ff1;

reg d_ff2;

wire d_pos;

wire d_neg;

always @(posedge clk or posedge reset)

begin

if(reset == 1\'b1)

d_ff1<= 1\'b0;

else

d_ff1<=#1 d;

end

always @(posedge clk or posedge reset)

begin

if(reset == 1\'b1)

d_ff2<= 1\'b0;

else

d_ff2<=#1 d_ff1;

end

assign d_pos = d & (~d_ff1);

assign d_neg = ~d & d_ff1;

always @(posedge clk or posedge reset)

begin

if(reset == 1\'b1)

q<= 8\'b0;

else

q<= q + 1\'b1;

end

always @(posedge clk or posedge reset)

begin

if(reset == 1\'b1)

q_ff1<= 8\'b0;

else

q_ff1<= q ;

end

always @(posedge clk or posedge reset)

begin

if(reset == 1\'b1)

q_ff2<= 8\'b0;

else

q_ff2<= q_ff1 ;

end

endmodule

全文完。

以上就是關于pos機開機一直初始化,如何初始化應用表單位置的知識,后面我們會繼續為大家整理關于pos機開機一直初始化的知識,希望能夠幫助到大家!

轉發請帶上網址:http://www.tonybus.com/news/4912.html

你可能會喜歡:

版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 babsan@163.com 舉報,一經查實,本站將立刻刪除。