verilog-hdl的故事之反應(yīng)和調(diào)試過程_第1頁
verilog-hdl的故事之反應(yīng)和調(diào)試過程_第2頁
verilog-hdl的故事之反應(yīng)和調(diào)試過程_第3頁
verilog-hdl的故事之反應(yīng)和調(diào)試過程_第4頁
verilog-hdl的故事之反應(yīng)和調(diào)試過程_第5頁
已閱讀5頁,還剩37頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第七章反應(yīng)和調(diào)試過 輸出的珍貴信 實驗二十六:優(yōu)化VGA的同步模 遲了一步的數(shù) 實驗二十七:VGA模塊仿 即時結(jié)果和非即時結(jié) 實驗二十八:即時結(jié)果的需 波形圖在我的腦海 總 輸出中珍貴的信在這一章中,我們主要討論的東西恰好是和前一章180度不同。一章中筆者說了,刺激在激勵過程中怎樣又怎樣。反之這一章,筆者要說的東西是反應(yīng)在激勵過程中,怎樣又怎樣?!胺磻?yīng)”在“激勵”中是“輸出”的意思,故“輸出”不只是在仿真軟件上看到的波形圖而已,然而“輸出”在仿真中也代表“模塊的反應(yīng)”。我們把“模塊的反應(yīng)”攤開先不說,畢竟面的實驗,筆者有形或無形的提及過。還是先把焦點圍繞著“波形圖的身上。因為只要把波形圖看懂了,自然而然讀者什么都會明白。滿許多有用的信息,可是要把這些信息看懂或者和VerilogHDL語言扯上關(guān)系(明白VerilogHDL語言對輸出的影響說實話真這是一件苦差事而且過程比起建模更。在現(xiàn)實中就像普通人看病例書一樣,完全都看不懂,但是醫(yī)生卻看得動,模塊是,看看模塊“哪里不舒服”和“吃錯什么了”等。在這里,筆者就以《VerilogHDL那些事兒-建模篇》中實驗九之一的vga模塊里的sync_module.v作為實例。選擇它的原因很簡單,因為sync_module.v用不著編輯復(fù)雜的事情就是從仿真中調(diào)試sync_module.v,使得它更優(yōu)化。(老實說,筆者這樣作就像址,y地址和顯示有效信號(Ready_Sigsync_module.v是負責著“顯示標準”的工作。在這里我們以800x600x60Hz為例。800x600xabcde段-總共n個列HSYNC列像800x600xopqrs段-總共n個行VSYNC行像41上表是以800x600x60Hz顯示標準的時序分段(具體的解釋請參考建模篇。我們知道在VGA800x600x60Hz為顯示25ns40Mhz為驅(qū)動頻率。在仿真的時候我們不可能以一個時鐘一個時鐘去計以筆者將它們轉(zhuǎn)換us。800x600x60Hz為顯示標準:一個列像素=顯示主頻的周期=1/40Mhz=25ns=10561056*25800x600xabcde段-總共n個列HSYNC列像800x600xopqrs段-總共n個行VSYNC行像CLK,Column_Addr_Sig,Row_Addr_SiginputCLK;inputoutputVSYNC_Sig;outputHSYNC_Sig;outputReady_Sig;output[10:0]Row_Addr_Sig;regalways@(posedgeCLKornegedgeRSTn)if(!RSTn)Count_H<=elseif(Count_H==11'd1056Count_H<=Count_H<=Count_H+1'b1; regalways@(posedgeCLKornegedgeRSTnif(!RSTnCount_V<=elseif(Count_V==11'd628Count_V<=elseif(Count_H==11'd1056Count_V<=Count_V+1'b1; regalways@(posedgeCLKornegedgeRSTnif(!RSTnisReady<=elseif((Count_H>11'd216&&Count_H<11'd1017)(Count_V>11'd27&&Count_V<11'd627)isReady<= assignVSYNC_Sig=(Count_V<=11'd4)?1'b0:assignHSYNC_Sig=(Count_H<=11'd128)?1'b0: assignColumn_Addr_Sig=isReady?Count_H-11'd217:11'd0;//CountfromassignRow_Addr_Sig=isReady?Count_V-11'd28:11'd0;//Countfrom0 67.sync_module.v`timescale1ps/1moduleregCLK;wireHSYNC_Sig;wireVSYNC_Sig;wireReady_Sig;wiresync_moduleRSTn=0;;RSTn=CLK=0;forever#12500CLK=36.1ps800x600x60Hz25nsns,無法取得完整的半周期時間(12.5小數(shù)必須進位或者割舍。30行,筆者設(shè)置了ps1us的復(fù)位。然而在31行,筆者設(shè)置12500ps12.5ns12500psx225000ps25ns優(yōu)化過a3.2us。C2~C3b2.2us。C3~C4d段,時間20us。C4~C5e1us。1056C1~C5,時間大約是26.4us(C5C1的時間??磥鞨YSNC_Sig的驅(qū)動很完美,沒有什么東西好修改VSYNC_Sigao4*1056*25ns(C1~C2)亦即105.6us。從波形圖上,我們看到VSYNC_Sig拉高之前,有5個1056*(C1~C3)的列像素。這有點問題,理論上是4個而已呀,怎么多了一個(C2~C3)? 25n(C1~C2嗯?VSYNC_Sig的o段出現(xiàn)問題,既然沒有對一個行像素照成影響。在這里,一定是 assign assignVSYNC_Sig=(Count_V<=11'd4)?1'b0: assignVSYNC_Sig=(Count_V<=11'd3)?1'b0:sync_module.v55Count_V11'd4Count_V3。上圖是經(jīng)修改sync_module.v第55行代碼后再一次仿真的結(jié)果。焦點依然是VSYNC_SigoVSYNC_Sigo4*1056*25ns(C1~C2,時間大約是105.6us。嗯,這個結(jié)果符合要求了。我們繼續(xù)往下調(diào)式。VSYNC_Sigpp23*1056*25nsusC2~C31056*25ns(C3~C4?哪里又發(fā)生問題了?elseif((Count_H>11'd216&&Count_H<11'd1017)(Count_V>11'd27&&Count_V<11'd627)elseif((Count_H>=11'd216&&Count_H<11'd1017)(Count_V>=11'd27&&Count_V<11'd627)47~48Count_H11'd216Count_V11'd27,,上圖是經(jīng)過修改第47~48行后,重新仿真的結(jié)果。該焦點依然是VSYNC_Sigp段。(C1~C2_SigpVSYNC_SigpqColumn_Addr_Sig0開始計數(shù),反之Row_Addr_Sig02047生在63行。 assign assignRow_Addr_Sig=isReady?Count_V-11'd28: assignRow_Addr_Sig=isReady?Count_V-11'd27:Count_V11'd28Count_V11'd2763行以后,VSYNC_Sigpq段,Row_Addr_Sig0開始)VSYNC_SigqHSYNC_SigC段,每一個列像xVSYNC_Sigqy地105612888(HSYNC_Siga+b段)個列像素開始,是當前y地址的0~799個列像素。但是在上面的仿真圖中,Column_Addr_Sig(x地址)應(yīng)該是0開始計數(shù)到799,但是它多計數(shù)1個列像素了(計數(shù)到800。然后再稍微注意一下Ready_Sig,它應(yīng)該是Column_Addr_Sig計數(shù)到799之后拉低才合理嗎?elseif((Count_H>=11'd216&&Count_H<11'd1017)(Count_V>=11'd27&&Count_V<11'd627)elseif((Count_H>=11'd216&&Count_H<11'd1016)(Count_V>=11'd27&&Count_V<11'd627)看來問題是發(fā)生在第47Count_H11'd1017,Count_H然后再一次啟動仿上圖是經(jīng)過修改47行的仿真結(jié)果,當Column_Addr_Sig計數(shù)到799的時候,它停止Ready_SigVSYNC_Sigq段第一個行像素調(diào)式成功,接下來的599個行像素也是一樣的結(jié)果。HYSNC_Siga~dVSYNC_Sigo~q段。剩下的只有VSYNC_Sig的r段。47C1~C2VSYNC_Sigq15840us。結(jié)果符合VSYNC_Sigqrr11056*,26.4usq800x600(Row_Addr_Sig599之后,Ready_Sig就拉低sync_module.v(CLK,Column_Addr_Sig, inputinputoutputoutputoutputoutputregalways@(posedgeCLKornegedgeRSTnif(!RSTnCount_H<=elseif(Count_H==11'd1056Count_H<=Count_H<=Count_H+1'b1; regalways@(posedgeCLKornegedgeRSTnif(!RSTnCount_V<=elseif(Count_V==11'd628Count_V<=elseif(Count_H==11'd1056Count_V<=Count_V+1'b1; regalways@(posedgeCLKornegedgeRSTnif(!RSTnisReady<=elseif((Count_H>=11'd216&&Count_H<11'd1016)//(*(Count_V>=11'd27&&Count_V<))//(*isReady<=isReady<=assignVSYNC_Sig=(Count_V<=11'd3)?1'b0: //(*assignHSYNC_Sig=(Count_H<=11'd128)?1'b0:assignReady_Sig=assignColumn_Addr_Sig=isReady?Count_H-11'd217:assignRow_Addr_Sig=isReady?Count_V-11'd27://(*.v(*),亦即,4748,55,63實驗二十(波形圖sync_module.v的代碼修改,直到最終sync_module.v的輸出達到可接受的范圍。實驗二十仿真中,比起驗證部分,綜合部分更加親近模塊的設(shè)計筆者之所以故意選sync_module.v作為仿真對象,就想表達一點“仿真最重要的不是學會編輯什么激勵文很多時候VerilogHDL遲了一步的數(shù)一章節(jié)中,我們優(yōu)化了sync_module.v模塊。在這一章節(jié)之中,sync_module.v模塊組合與《VerilogHDL那些事兒-建模篇》中實驗九之一的vga模塊里的vga_control_module.v,成為簡單的vga模塊并且執(zhí)后從輸(波形圖)實驗二十七:vga模塊仿真我們稍微回憶一下《VerilogHDL那些事兒-建模篇》中實驗九之一的vga模塊里vga_control_module.vvga_control_module.vvga模塊中,它是負責圖像顯示的工作。然而在《VerilogHDL那些事兒-建模篇中實驗九之一里它是負責顯示10(y0~y9長為799(x1~x799)不知道讀者還是否記得,在《VerilogHDL那些事兒-建模篇》中實驗九之一里,sync_module.v和vga_control_module.v使用了同樣的時鐘頻率。其實這一句舉動使得10x799xx1開始,x地址,使得該矩形從x2開始顯示。預(yù)想結(jié) 實際結(jié)新對vga_control_module.v內(nèi)容的認識。modulemodule(CLK,Red_Sig,Green_Sig,Blue_SiginputCLK;inputinput[10:0]Row_Addr_Sig;outputRed_Sig;outputoutputregalways@(posedgeCLKornegedgeRSTn)if(!RSTn)isRectangle<=elseif(Column_Addr_Sig>11'd0&&Row_Addr_Sig<11'd100isRectangle<=isRectangle<=assignRed_Sig=Ready_Sig&&isRectangle?1'b1:1'b0;assignGreen_Sig=Ready_Sig&&isRectangle?1'b1:1'b0;assignBlue_Sig=Ready_Sig&&isRectangle?1'b1:1'b0;37.在上面的內(nèi)容中,第23行的if條件決定了該矩形的面積和顯示位置。其中Coum_Addr_Sig11'd0x11~799,Row_Addr_Sig11'd100表示矩形從y00~99。在這里請注意,矩形的表示是以isRectangle標志寄存器來指示。無論是在“流水操和module(Red_Sig,Green_Sig,SQ_Ready,SQ_Column, inputinputinputoutputoutputoutputoutputoutputoutputoutputoutputwirewirewiresync_module(.RSTn(RSTn.VSYNC_Sig(VSYNC_Sig //output-to //output-to.Column_Addr_Sig(Column_Addr_Sig //output-to.Row_Addr_Sig(Row_Addr_Sig //output-to //output-to vga_control_module(.RSTn(RSTn//input-from.Column_Addr_Sig(//input-from.Row_Addr_Sig(Row_Addr_Sig//input-from.Red_Sig(Red_Sig//output-to.Green_Sig(Green_Sig//output-to.Blue_Sig(Blue_Sig//output-toassignSQ_Ready=assignSQ_Column=assignSQ_Row=vgavga_module.v組合模塊不同的是,筆者拿掉pll_module.v,并且將3~4CLK_SyncCLK_Control的輸入U1.CLK的輸入信號(31行U2.CLK的輸入信號(44(不知道是不是筆者人品的關(guān)系,每當筆者在做仿真的時候,凡是有ip出現(xiàn)的地方,仿真的工作會非常的不順利...所以筆者在作仿真的時候都故意把ip拿掉,用其他辦法來`timescale1ps/1moduleregCLK_40Mhz;regCLK_80Mhz;regRSTn;wireVSYNC_Sig;wirewirewirewirewirewirewireenv_vga_module(.SQ_Ready(SQ_Ready.SQ_Row(SQ_Row RSTn=0; ;RSTn=CLK_40Mhz= ;forever#12500CLK_40Mhz=CLK_80Mhz=1;forever#6250CLK_80Mhz=env_vga_module.v33~35行復(fù)位信號的刺激,38~4040Mhz43~4680Mhz里先無視那個CLK_80Mhz20~21行U1和U2亦即sync_module.vvga_control_module.vCLK_40Mhz4Mh4Mh:vga_control_module.v開始顯示矩形的時候。SQ_Row,SQ_Column和SQ_Ready它們分別對應(yīng)sync_module.v的輸出Row_Addr_Sig,Column_Addr_SigReady_Sig。在(Cursor省略為)C1的未來,SQ_ReadC1這個時鐘,sync_module.vSQ_RowSQ_Column也開始反饋當前的顯示地址y想和x。由于vga_control_module.v和sync_module.v使用同樣的時鐘,在C1這個時候C2的時候,C2未來SQ_Row不變,SQ_Column已經(jīng)遞增為1。在這個時候vga_control_module.vSQ_Column的過去值,還是是邏輯0。它還是一樣什么也沒C3的時候,C3SQ_Column已經(jīng)遞增為2。在個時候vga_control_modul.v檢測SQ_Column的過去值是1。if條件成立,它“決定”使能isRectangle寄存器。所以C3的未來Red/Green/Blue_Sig被拉高。上述的內(nèi)容,如果簡單歸納的話sync_module.v(U1)vga_control_module.v(U2)x0,y地址0的時候,U2U1U2x1,y0的時候,這時候的U2才反應(yīng)過來,U2開始會意U1的時候,事實上它已經(jīng)慢了一個時鐘。最終結(jié)果,vga_control_module.vx2x1上圖的仿真結(jié)果表示了,在該矩形的長度結(jié)束顯示在799,因為在C2之前,亦即SQ_Column值為799之前,Red/Green/Blue_Sig的過去都是被拉高。換句話說,矩形從x2開始顯示到x799結(jié)束顯示,長度為798,亦即有一個長度顯示失敗。0~99C1之前,亦即SQ_Row在這里我們可以如此總結(jié):矩形的高度顯示沒有問題,但是矩形的長度顯示就有問題。它向右偏移了一個像素。上初學者們都會把sync_module.v和vga_module.v集成在一個文件里,亦即單文件主義。RTL的方式來編寫模塊,組合邏輯的過分出現(xiàn)不但會使代碼的有一種更有效的辦法,也是這一章節(jié)的重點,那就是 使用更的時鐘頻`timescale1ps/1moduleregCLK_40Mhz;regCLK_80Mhz;regRSTn;wireRed_Sig;wireBlue_Sig;wireGreen_Sig;wireSQ_Ready;wirewire.SQ_Ready(SQ_Ready.SQ_Row(SQ_RowRSTn=0;;RSTn=CLK_40Mhz= ;forever#12500CLK_40Mhz=CLK_80Mhz=1;forever#6250CLK_80Mhz=50.上面是env_vga_module.v的激勵文件。其中在21行vga_control_module.vCLK_80Mhzsync_module.v4h/8h:sync_module.vC1SQ_Ready被拉高,SQ_Row和SQ_Column均反饋0,亦即當前顯xy0C1~C2之間由于SQ_Column為0,所以vga_control_module無視。在C2的未來sync_module.v反饋了SQ_Column為1vga_control_module.v是由80Mhz的時鐘頻率驅(qū)動著。C2的未來亦即sync_module.v的vga_control_module.v在這個時候檢測SQ_Column的過去值是0,它C3sync_module.vvga_control_module.v另一個新周期(上升沿。vga_control_module.vC3檢測了if(開始顯示矩形C2,C3C4vga_control_module.v的執(zhí)行頻率高于sync_module.v一倍。每當sync_module.v更新SQ_Column,vga_control_module.v在sync_module.v的后半周期就可以檢測到sync_module.v更新以后的值,然后vga_control_module.v在自己當前時鐘“決定”干些什么。由此一來,我們可以避免數(shù)上圖的仿真結(jié)果,vga_control_module.v顯示的矩形長度最長為799由于vga_control_module.v的執(zhí)行頻率比sync_module.v2倍。sync_module.v的輸出一旦更新,vga_control_module.vsync_module.v的后vga_control_moduel.v只用sync_module.v的后半周期去更新和保留Red/Green/Blue_Sig的輸出。vga_control_module.vsync_module的3/4Red/Green/Blue_SigRed/Green/Blue_Sigvga_control_module.vsync_module.v4倍的執(zhí)行頻率。但是這些事情不是強制性實驗二十sync_module.vvga_control_module.v遲了一個時鐘去。具體的原因是sync_module.v和vga_control_module.v使用了相同vga_control_module.v2sync_module.v的時鐘頻率以后,實驗二十vga_control_module.v的時鐘頻率就可以解決數(shù)vga_control_module.v,而且解決問題的過程也只道sync_module.v和vga_control_module.v之間的溝通出現(xiàn)問題(數(shù)據(jù)延遲)了。這一個實驗再一次證明,從波形圖中(輸出)(輸出)的信息所使用的一套“思想”和建模的時候所使用的“思想”是一樣的。即時結(jié)果和非即時結(jié)always”,無論它是否有沒有在always區(qū)域里,它都是,“時間點”的概念,它多求得的初學者常常都會誤會“<=”是always區(qū)域里的賦值運算符,其實“=”也可以使always=RTL級的設(shè)計亂了套。如果要在RTL級設(shè)計里區(qū)運用好“<=”,前提條件就是要掌握好基礎(chǔ)。在這一個實驗中筆者《VerilogHDL那些事兒-建模篇》實驗十九演示中一段控制程inputinputoutput[3:0]SQ_i,output[4:0]SQ_X,output[6:0]SQ_Y,outputSQ_isCount,output parameterT1US=7'd80; regregregalways@(posedgeCLKornegedgeRSTnif(!RSTnC1<=elseif(C1==T1USC1<=elseif(isCountC1<=C1+C1<=regalways@(posedgeCLKornegedgeRSTnif(!RSTnCUS<=elseif(CUS==rTimesCUS<=elseif(C1==T1USCUS<=CUS+regregalways@(posedgeCLKornegedgeRSTnif(!RSTnY<=case(i0:Y<=2:Y<=4:Y<=6:Y<=8:Y<=10:Y<=regregregalways@(posedgeCLKornegedgeRSTnif(!RSTni<=rAddr<=X<=isCount<=rTimes<=case(i 0,2,4,6,8, if(X==16)beginrAddr<=7'd0;X<=5'd0;isWrite<=1'b0;i<=i+1'b1; elsebeginrAddr<=Y+X;X=X+1'b1;isWrite<=1'b1;end 1,3,5,7,9, if(CUS==rTimes)beginisCount<=1'b0;i<=i+1'b1; elsebeginrTimes<=10'd250;isCount<=1'b1;end i<= assignSQ_i=assignSQ_X=assignSQ_Y=assignSQ_Addr=rAddr;assignSQ_isCount=isCount;assignSQ_isWrite=110..vVerilogHDL-vga_interface_demo.v250ms,vgaRAM寫入16wordsx16bits的數(shù)據(jù)。6~11行,筆者將i,X,Y,rAddr,isCount,isWrite全部引出來。該文件不再使用40Mhz80Mhzmsus171us21~47行分別1us定時器us級計數(shù)49~63行是根據(jù)不同i更新偏移量Y(注意:此時Y的賦值是使用非阻塞賦值)第69~97行是控制程序的部分,當步驟i是偶數(shù)的時候,Y更新偏移量,然后拉高isWriteY16i是奇數(shù)的時候就延遲`timescale1ps/1moduleregregwire[3:0]SQ_i;wire[4:0]SQ_X;wire[6:0]SQ_Y;wireSQ_isCount;wireSQ_isWrite;gm_control_moduleRSTn=0;;RSTn=CLK_80Mhz=1;forever#6250CLK_80Mhz=36.gm_control_module.v1ps1us80Mhz省略C)C1~C4Y值開始輸16個遞增的地址。C1的過去,由于是初始化的關(guān)016個遞增地址的輸出,SQ_Addr的輸出從0~15。上圖仿真結(jié)果表示了,每一次Y偏移量更新都需要延遲250us上圖的仿真結(jié)果是當.v2的時候。C1~C4表示了第二次Y偏移量更新。C1的時候,.v文件檢測到SQ_i的過去值是2Y偏移量,也就是說Y偏移量的更新發(fā)生在C1的未來。SQ_Addr的第一個輸出應(yīng)該是從16開始才對嘛?為什么會是Y(使用非阻塞賦值,C1YSQ_YC10C1的未來,SQ_Addr的輸出是YX,(XSQ_XC10)rAddr00,0C2SQ_Addr取得是SQ_YC216SQ_Addr取得的XSQ_XC21C2的未來,SQ_Addr的輸出是161,17SQ_Addr14個遞增輸都是正.v4Y偏移量更新。同樣的問題也取得的YSQ_YC116(Y偏移量后的遺留結(jié)果。在同一個時間SQ_Addr也取得SQ_X在C1的過去值,亦即0。所以在C1的未來SQ_Addr的輸出是rAddr<=16+0,結(jié)果是16而不是32。C2的時候,Y已經(jīng)更新完畢,SQ_Addr取得的Y是SQ_Y在C2的過去值,亦即32SQ_Addr取得的XSQ_XC21C2的未來,SQ_Addr的輸出是,rAddr<=32+1,結(jié)果是33。SQ_Addr其后的14個遞增輸出地址都是正4~6Y偏移量的更新,SQ_Addr第一個的輸出地址都會不正常??赡茏x者SQ_Addr在讀取第一個SQ_Y的值的時候都失敗。要解決這個問題很簡單,就是在.v文件里將Y所使用的非阻塞賦值“<=”改為阻塞inputinputoutput[3:0]SQ_i,output[4:0]SQ_X,output[6:0]SQ_Y,output output13. parameterT1US=7'd80; regregregalways@(posedgeCLKornegedgeRSTnif(!RSTnC1<=elseif(C1==T1USC1<=elseif(isCountC1<=C1+C1<=regalways@(posedgeCLKornegedgeRSTnif(!RSTnCUS<=elseif(CUS==rTimesCUS<=elseif(C1==T1USCUS<=CUS+regregalways@(posedgeCLKornegedgeRSTnif(!RSTnY<=case(i0:Y=2:Y=4:Y=6:Y=8:Y=10:Y=regregregalways@(posedgeCLKornegedgeRSTnif(!RSTni<=rAddr<=X<=isCount<=rTimes<=case(i 0,2,4,6,8, if(X==16)beginrAddr<=7'd0;X<=5'd0;isWrite<=1'b0;i<=i+1'b1; elsebeginrAddr<=Y+X;X=X+1'b1;isWrite<=1'b1;end 1,3,5,7,9, if(CUS==rTimes)beginisCount<=1'b0;i<=i+1'b1; elsebeginrTimes<=10'd250;isCount<=1'b1;end i<= assignSQ_i=i;assignSQ_X=X;assignSQ_Y=assignSQ_Addr=rAddr;assignSQ_isCount=isCount;assignSQ_isWrite=110.上面.v文件是經(jīng)過修改的gm_control_module.v58~63行中都改為“。使用同樣的激勵文上圖的仿真結(jié)果是.v文件在步驟0的時候C1~C4是SQ_Addr輸出的16個地址。無論Y有沒有取得“既是結(jié)不會影響SQ_Addr的輸出。因為在初始化的時候,Y已經(jīng)被初始化為0。上圖仿真結(jié)果表示,每一次Y更新時候的延遲。時間大約是250us.vY偏移量的時候。C1~C4SQ_Addr輸出的十在同一個時候,SQ_Addr取得的Y再也不是在C1,SQ_YY的“即時SQ_Addr取得的X是SQ_X的過去值,亦即0C1SQ_Addr的輸出是rAddr<=16+0,結(jié)果是16。SQ_Addr在接下來15個遞增輸出地址都正常。.v文件第三次更新Y偏移量。C1~C4SQ_Addr輸出的十六個遞增地址。在C1的時候.v文件檢測到SQ_i4,Y32。在同一個時候,SQ_Addr取得的YC1,SQ_YY的“即時SQ_Addr取得的X是SQ_X0C1SQ_Addr的輸出是rAddr<=32+0,結(jié)果是32。SQ_Addr在接下來15個遞增輸出地址都正常。實驗二十在實驗二十八中,由于Y偏移量更新的時候是使用非阻塞賦值“<=”,即遵守“時間點”的概念。結(jié)果使得SQ_Addr的第一個輸出地址帶來錯誤(應(yīng)該說是慢了一步。當更SQ_YSQ_Addr的第一個輸出地址的錯同樣的問題也發(fā)生regalways@(posedgeCLKornegedgeRSTnif(!RSTnZ<=case(i0:Z<=2:Z<=《VerilogHDL那些事兒_control_module.v44~55

12'b100_100_000_000:Z<=時候,考慮到初學者對eriogL的不熟悉,筆者將圖像的第一列和最后一列都空白處初次之外,讀者可能要問:“為什么在激勵文件中,不是使用其他的時鐘頻率,而是使用80Mhz的時鐘頻率?”筆者這樣作,絕對有筆者的原因,具體的原因就自己去摸索吧,就當筆者賣個關(guān)子好了。實驗二十真的虛擬實驗的重點就VerilogHDL的基本功看是如何從波(輸出波形圖在我的腦海我們就以一個簡單的例子來助讀者回憶一些數(shù)碼管接口的功能。smg_scan_module.v會每隔1ms低電平使能不同的數(shù)碼管,smg_control_module.v1msNumber_Sigsmg_encode_module.v。smg_encode_module.v是加碼模塊,它會將Number_Data加碼1ms。下面是數(shù)碼管加碼模塊的部分代碼,其中最關(guān)鍵的部分是第20~39行,它表示了數(shù)碼管加碼模塊在加碼數(shù)據(jù)的時候,由于該模塊是用寄存器來寄存加碼后的數(shù)據(jù),所以它至少需要一個時鐘的消耗。20.20.always@(posedgeCLKornegedgeRSTnif(!RSTnrSMG<=case(Number_Data4'd0:rSMG<=4'd1:rSMG<=4'd2:rSMG<=4'd3:rSMG<=4'd4:rSMG<=4'd5:rSMG<=4'd6:rSMG<=4'd7:rSMG<=4'd8:rSMG<=4'd9:rSMG<=假設(shè)筆者使用的時鐘頻率是20Mhz,那1ms的定時常1ms/(1/20Mhz)=1E-3/50E-9=也就是說每一位數(shù)碼管在動態(tài)掃描中都使用大約20000個時鐘。在第一個1ms的時候,由1SMG_Data19999Scan_Sig20000SMG_Data多了一個時鐘。數(shù)碼管動態(tài)顯示的效果不會因為 的輸出少了一個時鐘而影響實際的效果(人類眼是很遲鈍的,所以很多時候我們用不著特意去仿真這個數(shù)碼管接口筆者再來舉個例上圖GUI系統(tǒng)中的led_control_module

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論