版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
第14章對驗證的支持學(xué)習(xí)內(nèi)容理解Verilog文本輸出理解不同的讀取仿真時間的系統(tǒng)函數(shù)理解Verilog文件I/O功能1驗證系統(tǒng)中的任務(wù)(task)及函數(shù)(function)Verilog讀取當(dāng)前仿真時間的系統(tǒng)函數(shù)$time $stime $realtimeVerilog支持文本輸出的系統(tǒng)任務(wù): $display $strobe $write $monitor2仿真時間訪問仿真時間$time,$realtime,和$stime函數(shù)返回當(dāng)前仿真時間。這些函數(shù)的返回值使用調(diào)用模塊中`timescale定義的時間單位$time返回一個64位整數(shù)時間值。$stime返回一個32位整數(shù)時間值。$realtime返回一個實數(shù)時間值。$stime函數(shù)返回一個32位整數(shù)時間值。對大于232的時間,返回模232的值。使用它可以節(jié)省顯示及打印空間。3輸出格式化時間信息`timescale10ns/100psmoduletop;regin1;notm1(o1,in1);initialbegin
$timeformat(-9,2,"ns",10);in1=0;#8in1=1;#10$display("%t%b%b",$realtime,in1,o1);#10$finish;endendmodule在這個例子中,顯示的時間為:180.00nsunit:0(s)到-15(fs)之間的整數(shù),表示時間度量precision:要顯示的十進制小數(shù)位數(shù)。suffix:在時間值后顯示的字符串min_width:顯示前三項的最小寬度若使用多個`timescale,以最小的時間精度顯示時間值。可用系統(tǒng)任務(wù)$timeformat結(jié)合格式符%t全局控制時間顯示方式。$timeformat系統(tǒng)任務(wù)的語法為:
$timeformat(<unit>,<precision>,<suffix>,<min_width>);4輸出格式化時間信息`timescale1ns/10psmoduletop;regin1;not#9.53n1(o1,in1);initialbegin$display("timerealtimestime\tin1\to1");
$timeformat(-9,2,"ns",10);
$monitor("%d%t%d\t%b\t%b",$time,$realtime,$stime,in1,o1);in1=0;#10in1=1;#10$finish;endendmoduletimerealtimestimein1o100.00ns00x109.53ns10011010.00ns10112019.53ns20105輸出格式化時間信息對#延遲,Verilog將延遲值舍入最近(四舍五入)時間精度值。例如,上面的例子修改為:`timescale1ns/100psnot#9.42n1(o1,in1);結(jié)果為:timerealtimestimein1o100.00ns00x99.40ns9011010.00ns10111919.40ns1910`timescale1ns/100psnot#9.49n1(o1,in1);結(jié)果為:timerealtimestimein1o100.00ns00x99.50ns9011010.00ns10111919.50ns19106顯示信號值—$display$display輸出參數(shù)列表中信號的當(dāng)前值。
語法:$display([“format_specifiers”,]<argument_list>)$display輸出時自動換行。
$display($time,“%b\t%h\t%d\t%o”,sig1,sig2,sig3,sig4);$display($time,“%b\t”,sig1,“%h\t”,sig2,“%d\t”,sig3,“%o”,sig4);$display支持二進制、八進制、十進制和十六進制。缺省基數(shù)為十進制。
$display(sig1,sig2,sig3,sig4);$displayb(sig1,sig2,sig3,sig4);$displayo(sig1,sig2,sig3,sig4);$displayh(sig1,sig2,sig3,sig4);%h%o%d%b%c%s%v%m%thexoctaldecimalbinaryASCIIstringstrengthmoduletime\t\n\\\"\<1-3digitoctalnumber>%0dtab換行反斜杠雙引號上述的ASCII表示無前導(dǎo)0的十進制數(shù)格式符轉(zhuǎn)義符7顯示信號值—$write和$strobe$write與$display相同,不同的是不會自動換行。$write($time,“%b\t%h\t%d\t%o\t”,sig1,sig2,sig3,sig4);$strobe與$display相同,不同的是在仿真時間前進之前的信號值。而$display和$write立即顯示信號值。也就是說$strobe顯示穩(wěn)定狀態(tài)信號值,而$display和$write可以顯示信號的中間狀態(tài)值。$strobe($time,“%b\t%h\t%d\t%o\t”,sig1,sig2,sig3,sig4);$write和$strobe都支持多種數(shù)基,缺省為十進制。 $writeb $strobeb $writeo $strobeo $writeh $strobeh8顯示信號值—$write和$strobe下面是模塊textio仿真的輸出:$writeb輸出:0xxxxxxxxx注意data是32位數(shù)據(jù),由8位十六進制數(shù)表示。時間以沒有前導(dǎo)零的十進制形式輸出。缺省情況下,值以十進制顯示,忽略前導(dǎo)零,與%0d格式符相同??梢栽谝粋€格式化符前插入一個0使Verilog忽略開頭的零。$displayh:000f000000101注意當(dāng)前時間,一個64位量,需要16個十六進制的數(shù)。$display:1020$strobe:1030moduletextio;regflag;reg[31:0]data;initialbegin$writeb("%d",$time,,"%h\t",data,,flag,"\n");#15flag=1;data=16;$displayh($time,,data,,flag);endinitialbegin#10data=20;$strobe($time,,data);$display($time,,data);data=30;endendmodule9監(jiān)視信號值—$monitor$monitor持續(xù)監(jiān)視參數(shù)列表中的變量。在一個時間片中,參數(shù)表中任何信號發(fā)生變化,$monitor將在仿真時間前進前顯示參數(shù)表的信號值。后面的$monitor將覆蓋前面的$monitor??梢杂孟到y(tǒng)任務(wù)$monitoron和$monitoroff控制持續(xù)監(jiān)視。$monitor支持多種基數(shù)。缺省為十進制。$monitor($time,“%b\t%h\t%d\t%o”,sig1,sig2,sig3,sig4);10監(jiān)示信號值—$monitor$monitor是唯一的不斷輸出信號值的系統(tǒng)任務(wù)。其它系統(tǒng)任務(wù)在返回值之后就結(jié)束。$monitor和$strobe一樣,顯示參數(shù)列表中信號的穩(wěn)定狀態(tài)值,也就是在仿真時間前進之前顯示信號。在一個時間步中,參數(shù)列表中信號值的任何變化將觸發(fā)$monitor。但$time,$stime,$realtime不能觸發(fā)。任何后續(xù)的$monitor覆蓋前面調(diào)用的$monitor。只有新的$monitor的參數(shù)列表中的信號被監(jiān)視,而前面的$monitor的參數(shù)則不被監(jiān)視??梢杂?monitoron和$monitoroff系統(tǒng)任務(wù)控制持續(xù)監(jiān)視,使用戶可以在仿真時只監(jiān)視特定時間段的信號。$monitor參數(shù)列表的形式與$display相同。$monitor支持多種基數(shù)。缺省為十進制。 $monitorb $monitoro $monitorh11文件輸出$fopen打開一個文件并返回一個多通道描述符(MCD)。MCD是與文件唯一對應(yīng)的32位無符號整數(shù)。如果文件不能打開并進行寫操作,MCD將等于0。如果文件成功打開,MCD中的一位將被置位。以$f開始的顯示系統(tǒng)任務(wù)將輸出寫入與MCD相對應(yīng)的文件中。...integer
MCD1;
MCD1=$fopen("<name_of_file>");$fdisplay(MCD1,P1,P2,..,Pn);$fwrite(MCD1,P1,P2,..,Pn);$fstrobe(MCD1,P1,P2,..,Pn);$fmonitor(MCD1,P1,P2,..,Pn);$fclose(MCD1);...12文件輸出$fopen打開參數(shù)中指定的文件并返回一個32位無符號整數(shù)MCD,MCD是與文件一一對應(yīng)的多通道描述符。如果文件不能打開并進行寫操作,它返回0。$fclose關(guān)閉MCD指定的通道。輸出信息到log文件和標(biāo)準(zhǔn)輸出的四個格式化顯示任務(wù)($display,$write,$monitor,$strobe)都有相對應(yīng)的任務(wù)用于向指定文件輸出。這些對應(yīng)的任務(wù)($fdisplay,$fwrite,$fmonitor,$fstrobe)的參數(shù)形式與對應(yīng)的任務(wù)相同,只有一個例外:第一個參數(shù)必須是一個指定向何哪個文件輸出的MCD。MCD可以是一個表達式,但其值必須是一個32位的無符號整數(shù)。這個值決定了該任務(wù)向哪個打開的文件寫入。MCD可以看作由32個標(biāo)志構(gòu)成的組,每個標(biāo)志代表一個單一的輸出通道。13文件輸出...integermessages,broadcast,cpu_chann,alu_chann;initialbegin
cpu_chann=$fopen("cpu.dat");if(!cpu_chann)$finish;
alu_chann=$fopen("alu.dat");if(!alu_chann)$finish;//channeltobothcpu.datandalu.dat
messages=cpu_chann|alu_chann;//channeltobothfiles,standardout,andverilog.log
broadcast=1|messages;endalways@(posedgeclock)//printthefollowingtoalu.dat
$fdisplay(alu_chann,"acc=%hf=%ha=%hb=%h",acc,f,a,b);/*ateveryresetprintamessagetoalu.dat,cpu.dat,standardoutputandtheverilog.logfile*/always@(negedgereset)$fdisplay(broadcast,"systemresetattime%d",$time);...必須聲明為integer通道0(編號為1)為標(biāo)準(zhǔn)輸出及verilog.log14文件輸入Verilog中有兩個系統(tǒng)任務(wù)可以將數(shù)據(jù)文件讀入寄存器組。一個讀取二進制數(shù)據(jù),另一個讀取十六進制數(shù)據(jù):$readmemb$readmemb("",<memory_name>);$readmemb("",<memory_name>,<start_addr>);$readmemb("",<memory_name>,<start_addr>,<finish_addr>);$readmemh$readmemh("",<memory_name>);$readmemh("",<memory_name>,<start_addr>);$readmemh("",<memory_name>,<start_addr>,<finish_addr>);15文件輸入系統(tǒng)任務(wù)$readmemb和$readmemh從一個文本文件讀取數(shù)據(jù)并寫入存儲器。如果數(shù)據(jù)為二進制,使用$readmemb;如果數(shù)據(jù)為十六進制,使用$readmemh。指定要調(diào)入的文件。mem_name指定存儲器名。start和finish決定存儲器將被裝載的地址。Start為開始地址,finish為結(jié)束地址。如果不指定開始和結(jié)束地址,$readmem按從低端開始讀入數(shù)據(jù),與說明順序無關(guān)。16文件輸入$readmemb和$readmemh的文件格式:$readmemb("mem_file.txt",mema);0000_00000110_00010011_0010//地址3~255沒有定義@100//hex1111_1100//地址257~1022沒有定義@3FF1110_0010文本文件:mem_聲明的存儲器組reg[0:7]mema[0:1023]modulereadmem;reg[0:7]mema[0:1023]initial$readmemb(“mem_”,mema);endmodule17文件輸入$readmemb和$readmemh的文件格式:$readmemb("mem_file.txt",mema);可以指定二進制(b)或十六進制(h)數(shù)用下劃線(_)提高可讀性??梢园瑔涡谢蚨嘈凶⑨???梢杂每崭窈蛽Q行區(qū)分存儲器字??梢越o后面的值設(shè)定一個特定的地址,格式為:
@(hex_address)十六進制地址的大小寫不敏感。在@和數(shù)字之間不允許有空格。
18復(fù)習(xí)問題:哪個系統(tǒng)任務(wù)顯示參數(shù)列表中信號的穩(wěn)定狀態(tài)值?每次能打開多少個輸出文件?解答:系統(tǒng)任務(wù)$monitor和$strobe顯示參數(shù)列表中信號的穩(wěn)定狀態(tài)值。這些任務(wù)在時間前進之前輸出信號值。每次只能打開一個輸出文件,包括已由仿真器打開的任何log文件。19第十五章VerilogTestBench使用簡介學(xué)習(xí)內(nèi)容:用一個復(fù)雜的testbench復(fù)習(xí)設(shè)計的組織與仿真建立testbench通常使用的編碼風(fēng)格及方法20設(shè)計組織虛線表示編譯時檢測輸入文件是否存在及可讀并允許生成輸出文件。21testbench組織簡單的testbench向要驗證的設(shè)計提供向量,人工驗證輸出。復(fù)雜的testbench是自檢測的,其結(jié)果自動驗證。stimulus要驗證的設(shè)計簡單的testbench復(fù)雜的testbench激勵驗證結(jié)果要驗證的設(shè)計22并行塊fork…join塊在測試文件中很常用。他們的并行特性使用戶可以說明絕對時間,并且可以并行的執(zhí)行復(fù)雜的過程結(jié)構(gòu),如循環(huán)或任務(wù)。moduleinline_tb;reg[7:0]data_bus;//instanceofDUTinitialforkdata_bus=8'b00;#10data_bus=8'h45;#20repeat(10)#10data_bus=data_bus+1;#25repeat(5)#20data_bus=data_bus<<1;#140data_bus=8'h0f;joinendmodule上面的兩個repeat循環(huán)從不同時間開始,并行執(zhí)行。象這樣的特殊的激勵集在單個的begin…end塊中將很難實現(xiàn)。Time|data_bus0|8’b0000_000010|8’b0100_010130|8’b0100_011040|8’b0100_011145|8’b1000_111050|8’b1000_111160|8’b1001_000065|8’b0010_000070|8’b0010_000180|8’b0010_001085|8’b0100_010090|8’b0100_0101100|8’b0100_0110105|8’b1000_1100110|8’b1000_1101120|8’b1000_1110125|8’b0001_1100140|8’b0000_111123包含文件包含文件用于讀入代碼的重復(fù)部分或公共數(shù)據(jù)。moduleclk_gen(clk);outputclk;regclk;`include"common.txt"initialbeginwhile($time<sim_end)beginclk=initial_clock;#(period/2)clk=!initial_clock;#(period/2);end$finish;endendmodule在上面的例子中,公共參數(shù)在一個獨立的文件中定義。此文件在不同的仿真中可被不同的測試文件調(diào)用。//common.txt//clockandsimulatorconstantsparameterinitial_clock=1;parameterperiod=15;parametermax_cyc=100;parametersim_end=period*max_cyc24施加激勵產(chǎn)生激勵并加到設(shè)計有很多種方法。一些常用的方法有:從一個initial塊中施加線激勵從一個循環(huán)或always塊施加激勵從一個向量或整數(shù)數(shù)組施加激勵記錄一個仿真過程,然后在另一個仿真中回放施加激勵25線性激勵線性激勵有以下特性:只有變量的值改變時才列出易于定義復(fù)雜的時序關(guān)系對一個復(fù)雜的測試,測試基準(zhǔn)(testbench)可能非常大moduleinline_tb;reg[7:0]data_bus,addr;wire[7:0]results;DUTu1(results,data_bus,addr);initialforkdata_bus=8'h00;addr=8'h3f;#10data_bus=8'h45;#15addr=8'hf0;#40data_bus=8'h0f;#60$finish;joinendmodule26循環(huán)激勵從循環(huán)產(chǎn)生激勵有以下特性:在每一次循環(huán),修改同一組激勵變量時序關(guān)系規(guī)則代碼緊湊moduleloop_tb;regclk;reg[7:0]stimulus;wire[7:0]results;integeri;DUTu1(results,stimulus);alwaysbegin//clockgenerationclk=1;#5clk=0;#5endinitialbeginfor(i=0;i<256;i=i+1)@(negedgeclk)stimulus=i;#20$finish;endendmodule27數(shù)組激勵從數(shù)組產(chǎn)生激勵有以下特性:在每次反復(fù)中,修改同一組激勵變量激勵數(shù)組可以直接從文件中讀取modulearray_tb;reg[7:0]data_bus,stim_array[0:15];//數(shù)組integeri;DUTu1(results,stimulus);initialbegin//從數(shù)組讀入數(shù)據(jù)#20stimulus=stim_array[0];#30stimulus=stim_array[15];//線激勵#20stimulus=stim_array[1];for(i=14;i>1;i=i-1)//循環(huán)#50stimulus=stim_array[i];#30$finish;endendmodule28矢量采樣在仿真過程中可以對激勵和響應(yīng)矢量進行采樣,作為其它仿真的激勵和期望結(jié)果。modulecapture_tb;parameterperiod=20reg[7:0]in_vec,out_vec;integerRESULTS,STIMULUS;DUTu1(out_vec,in_vec);initialbeginSTIMULUS=$fopen("stimulus.txt");RESULTS=$fopen("results.txt");fork
if(STIMULUS!=0)forever#(period/2)$fstrobeb(STIMULUS,"%b",in_vec);
if(RESULTS!=0)#(period/2)forever#(period/2)$fstrobeb(RESULTS,"%b",out_vec);joinendendmodule29矢量回放保存在文件中的矢量反過來可以作為激勵moduleread_;parameternum_vecs=256;reg[7:0]data_bus;reg[7:0]stim[num_vecs-1:0];integeri;DUTu1(results,data_bus)initialbegin//Vectorsareloaded$readmemb("vec.txt",stim);for(i=0;i<num_vecs;i=i+1)#50data_bus=stim[i];endendmodule//激勵文件vec.txt..使用矢量文件輸入/輸出的優(yōu)點:激勵修改簡單設(shè)計反復(fù)驗證時直接使用工具比較矢量文件。30錯誤及警告報告使用文本或文件輸出類的系統(tǒng)任務(wù)報告錯誤及警告always@(posedgepar_err)$display("error-busparityerrorsdetected");always@(posedgecor_err)$display("warning-correctableerrordetected");一個更為復(fù)雜的testbench可以:不但能報告錯誤,而能進行一些動作,如取消一個激勵塊并跳轉(zhuǎn)到下一個激勵。在內(nèi)部保持錯誤跟蹤,并在每次測試結(jié)束時產(chǎn)生一個錯誤報告。31強制激勵在過程塊中,可以用兩種持續(xù)賦值語句驅(qū)動一個值或表達式到一個信號。過程持續(xù)賦值通常不可綜合,所以它們通常用于測試基準(zhǔn)描述。對每一種持續(xù)賦值,都有對應(yīng)的命令停止信號賦值。不允許在賦值語句內(nèi)部出現(xiàn)時序控制。對一個寄存器使用assign和deassign,將覆蓋所有其他在該信號上的賦值。這個寄存器可以是RTL設(shè)計中的一個節(jié)點或測試基準(zhǔn)中在多個地方賦值的信號等。
initialbegin#10assigntop.dut.fsm1.state_reg=`init_state;#20deassigntop.dut.fsm1.state_reg;end在register和net上(例如一個門級掃描寄存器的輸出)使用force和release,將覆蓋該信號上的所有其他驅(qū)動。
initialbegin#10forcetop.dut.counter.scan_reg.q=0;#20releasetop.dut.counter.scan_reg.q;end32強制激勵可以強制(force)并釋放一個信號的指定位、部分位或連接,但位的指定不能是一個變量(例如out_vec[i])不能對register的一位或部分位使用assign和deassign對同一個信號,force覆蓋assign。后面的assign或force語句覆蓋以前相同類型的語句。如果對一個信號先assign然后force,它將保持force值。在對其進行release后,信號為assign值。如果在一個信號上force多個值,然后release該信號,則不出現(xiàn)任何force值。在上面兩個例子中,在net或register上所賦的常數(shù)值,覆蓋所有在時刻10和時刻20之間可能發(fā)生在該信號上的其他任何賦值或驅(qū)動。如果所賦值是一個表達式,則該表達式將被持續(xù)計算。33建立時鐘例1:雖然有時候在設(shè)計中給出時鐘,但通常時鐘是測試基準(zhǔn)中建立。下面介紹如何產(chǎn)生不同的時鐘波形。同時給出用門級和行為級描述方法下面是一個簡單對稱時鐘的例子:regck;alwaysbegin#(period/2)ck=0;#(period/2)ck=1;endreggo;wireck;nand#(period/2)u1(ck,ck,go);initialbegingo=0;#(period/2)go=1;end注意:在一些仿真器中,時鐘與設(shè)計使用相同的抽象級描述時,仿真性能會好一些。產(chǎn)生的波形(假定period為20)34建立時鐘例2:有啟動延時的對稱時鐘的例子:regck;initialbeginck=0;#(period)forever#(period/2)ck=!ck;endreggo;wireck;nand#(period/2)u1(ck,ck,go);initialbegingo=0;#(period)go=1;end注意:在行為描述中,在時間0將CK初始化為0;而在結(jié)構(gòu)描述中,直到period/2才影響CK值。當(dāng)go信號在時間0初始化時,CK值到period/2才變化??梢允褂锰厥饷頵orce和release立即影響CK值。產(chǎn)生的波形(假定period為20)35建立時鐘例3:有不規(guī)則啟動延時的不對稱時鐘的例子:注意:在行為描述中,CK值立刻被影響;而在結(jié)構(gòu)描述中,在傳播延時后才輸出正確波形。產(chǎn)生的波形(假定period為20)regck;initialbegin#(period+1)ck=1;#(period/2–1)foreverbegin#(period/4)ck=0;#(3*period/4)ck=1;endendreggo;wireck;nand#(3*period/4,period/4)u1(ck,ck,go);initialbegin#(period/4+1)go=0;#(5*period/4–1)go=1;end36使用task在testbench中使用task可以壓縮重復(fù)操作,提高代碼效率。modulebus_ctrl_tb;reg[7:0]data;regdata_valid,data_rd;cpuu1(data_valid,data,data_rd);initialbegincpu_driver(8'b0000_0000);cpu_driver(8'b1010_1010);cpu_driver(8'b0101_0101);endtaskcpu_driver;input[7:0]data_in;begin#30data_valid=1;wait(data_rd==1);#20data=data_in;wait(data_rd==0);#20data=8'hzz;#30data_valid=0;endendtaskendmodule
37使用task產(chǎn)生的波形38復(fù)習(xí)問題:什么操作可以容易的在fork…join塊做到,而不容易在begin…end塊做到?通常怎樣產(chǎn)生規(guī)則激勵和不規(guī)則激勵?從一個文件中讀取激勵時使用什么數(shù)據(jù)類型?在行為級時鐘模型中能做哪些在門級時鐘模型中很難或不能作到的事?解答:fork…join塊中不但能夠賦值,還可以并行執(zhí)行循環(huán)、條件語句、任務(wù)或函數(shù)調(diào)用。循環(huán)或always塊能有效地產(chǎn)生規(guī)則激勵,不規(guī)則激勵適合用在initial塊產(chǎn)生。用寄存器組(存儲器)并用$readmem系統(tǒng)任務(wù)從一個文件以讀取向量。行為級代碼可以很容易地產(chǎn)生一個啟動時間不規(guī)則的時鐘波形,并且可以在時刻零初始化時鐘。39第16章存儲器建模學(xué)習(xí)內(nèi)容:如何描述存儲器如何描述雙向端口40存儲器件建模描述存儲器必須做兩件事:說明一個適當(dāng)容量的存儲器。提供內(nèi)容訪問的級別,例如:只讀讀和寫寫同時讀多個讀操作,同時進行單個寫操作同時有多個讀和多個寫操作,有保證一致性的方法41簡單ROM描述下面的ROM描述中使用二維寄存器組定義了一個存儲器mem。ROM的數(shù)據(jù)單獨保存在文件my_rom_data中,如右邊所示。通常用這種方法使ROM數(shù)據(jù)獨立于ROM描述。`timescale1ns/10psmodulemyrom(read_data,addr,read_en_);inputread_en_;input[3:0]addr;output[3:0]read_data;reg[3:0]read_data;reg[3:0]mem[0:15];initial
$readmemb("my_rom_data",mem);always@(addrorread_en_)if(!read_en_)read_data=mem[addr];endmodulemy_rom_data000001011100001111010010001111111000100110000001110110100001110142簡單的RAM描述RAM描述比ROM略微復(fù)雜,因為必須既有讀功能又有寫功能,而讀寫通常使用同一數(shù)據(jù)總線。這要求使用新的處理雙向數(shù)據(jù)線的建模技術(shù)。在下面的例子中,若讀端口未使能,則模型不驅(qū)動數(shù)據(jù)總線;此時若數(shù)據(jù)總線沒有寫數(shù)據(jù)驅(qū)動,則總線為高阻態(tài)Z。這避免了RAM寫入時的沖突。`timescale1ns/1nsmodulemymem(data,addr,read,write);inout[3:0]data;input[3:0]addr;inputread,write;reg[3:0]memory[0:15];//16*4//讀assigndata=read?memory[addr]:4'bz;//寫always@(posedgewrite)memory[addr]=data;endmodule
這個描述可綜合,但許多工具僅僅產(chǎn)生一個寄存器堆,因此與一個真正的存儲器相比耗費更多的面積。43參數(shù)化存儲器描述在下面的例子中,給出如何定義一個字長和地址均參數(shù)化的只讀存儲器件。modulescalable_ROM(mem_word,address);
parameteraddr_bits=8;//地址總線寬度
parameterwordsize=8;//字寬
parameterwords=(1<<addr_bits);//mem容量
output[wordsize:1]mem_word;//存儲器字
input[addr_bits:1]address;//地址總線
reg[wordsize:1]mem[0:words-1];//mem聲明//輸出存儲器的一個字
wire[wordsize:1]mem_word=mem[address];endmodule
例中存儲器字范圍從0而不是1開始,因為存儲器直接用地址線確定地址。也可以用下面的方式聲明存儲器并尋址。reg[wordsize:1]mem[1:words];//從地址1開始的存儲器//存儲器尋址時地址必須加1wire[wordsize:1]mem_word=mem[address+1];
44存儲器數(shù)據(jù)裝入可以使用循環(huán)或系統(tǒng)任務(wù)給存儲器裝入初始化數(shù)據(jù)用循環(huán)給存儲器的每個字賦值for(i=0;i<memsize;i=i+1)
//initializememorymema[i]={wordsize{1'b1}};
調(diào)用系統(tǒng)任務(wù)$readmem$readmemb("mem_file.txt",mema);
可以用系統(tǒng)任務(wù)$readmem給一個ROM或RAM加載數(shù)據(jù)。對于ROM,開始時寫入的數(shù)據(jù)就是其實際內(nèi)容。對于RAM,可以通過初始化,而不是用不同的寫周期給每個字裝入數(shù)據(jù)以減少仿真時間。45使用雙向端口用關(guān)鍵詞inout聲明一個雙向端口
inout[7:0]databus;雙向端口聲明遵循下列規(guī)則:inout端口不能聲明為寄存器類型,只能是net類型。這樣仿真器若有多個驅(qū)動時可以確定結(jié)果值。對inout端口可以從任意一個方向驅(qū)動數(shù)據(jù)。端口數(shù)據(jù)類型缺省為net類型。不能對net進行過程賦值,只能在過程塊外部持續(xù)賦值,或?qū)⑺B接到基本單元。在同一時間應(yīng)只從一個方向驅(qū)動inout端口。例如:在RAM模型中,如果使用雙向數(shù)據(jù)總線讀取RAM數(shù)據(jù),同時在數(shù)據(jù)總線上驅(qū)動寫數(shù)據(jù),則會產(chǎn)生邏輯沖突,使數(shù)據(jù)總線變?yōu)槲粗?。必須設(shè)計與inout端口相關(guān)的邏輯以確保正確操作。當(dāng)把該端口作為輸入使用時,必須禁止輸出邏輯。46雙向端口建?!褂没締卧odulebus_xcvr(bus_a,bus_b,en_a_b,en_b_a);inoutbus_a,bus_b;inputen_a_b,en_b_a;bufif1b1(bus_b,bus_a,en_a_b);bufif1b2(bus_a,bus_b,en_b_a);//Structuralmodulelogicendmodule
若en_a_b=1,基本單元b1使能,bus_a數(shù)據(jù)傳送到bus_b若en_b_a=1,基本單元b2使能,bus_b數(shù)據(jù)傳送到bus_a信號en_a_b和en_b_a控制使能47雙向端口建模—使用持續(xù)賦值建模modulebus_xcvr(bus_a,bus_b,en_a_b,en_b_a);inoutbus_a,bus_b;inputen_a_b,en_b_a;assignbus_b=en_a_b?bus_a:'bz;assignbus_a=en_b_a?bus_b:'bz;//Structuralmodulelogicendmodule
若en_a_b=1,賦值語句驅(qū)動bus_a數(shù)據(jù)到bus_b若en_b_a=1,賦值語句驅(qū)動bus_b值到bus_a信號en_a_b和en_b_a控制使能48雙向端口建模—存儲器端口建模moduleram_cell(databus,rd,wr);inoutdatabus;inputrd,wr;regdatareg;assigndatabus=rd?datareg:'bz;always@(negedgewr)datareg<=databus;endmodule當(dāng)rd=1時,datareg的值賦值databus在wr下降沿,databus數(shù)據(jù)寫入datareg49復(fù)習(xí)問題:在Verilog中用什么結(jié)構(gòu)定義一個存儲器組?如何向存儲器加載數(shù)據(jù)?如何通過一個雙向(inout)端口傳送數(shù)據(jù)?解答:在Verilog中將存儲器聲明為一個一個2維寄存器陣列??梢杂孟到y(tǒng)任務(wù)$readmem或$readmemb或用過程賦值向存儲器加載數(shù)據(jù)因為inout兩端信號必須都是net數(shù)據(jù)類型,因此只能使用基本單元,子模塊,或持續(xù)賦值驅(qū)動數(shù)據(jù)。同時還必須注意確保在任何一端不要發(fā)生驅(qū)動沖突。50Xp#s%v)y0B3F6I9LdOgSjVmYq!t&w-z1D4G7JbMePhTkWoZr$u(x+A2E5H9KcNfRiUlXp#s&v)y0C3F6IaLdPgSjVnYq!t*w-A1D4G8JbMeQhTkWoZr%u(x+B2E5H9KcOfRiUmXp#s&v)z0C3F7IaLdPgSkVnYq$t*w-A1D5G8JbNeQhTlWo#r%u(y+B2E6H9LcOfRjUmXp!s&w)z0C4F7IaMdPgSkVnZq$t*x-A1D5G8KbNeQiTlWo#r%v(y+B3E6H9LcOgRjUmYp!s&w)z1C4F7JaMdPhSkWnZq$u*x-A2D5H8KbNfQiTlXo#r%v(y0B3E6I9LcOgRjVmYp!t&w)z1C4G7JaMePhSkWnZr$u*x+A2D5H8KcNfQiUlXo#s%v)y0B3F6I9LdOgSjVmYq!t&w-z1C4G7JbMePhTkWnZr$u(x+A2E5H8KcNfRiUlXp#s%v)y0C3F6IaLdOgSjVnYq!t*w-z1D4G8JbMeQhTkWoZr%u(x+B2E5H9KcOfRiUmXp#s&v)y0C3F7IaLdPgSjVnYq$t*w-A1D4G8JbNeQhTlWoZr%u(y+B2E6H9KcOfRjUmXp!s&v)z0C4F7IaMdPgSkVnZq$t*x-A1D5G8JbNeQiTlWo#r%u(y+B3E6H9LcOfRjUmYp!s&w)z0C4F7JaMdPhSkVnZq$u*x-A2D5G8KbNfQiTlXo#r%v(y0B3E6I9LcOgRjVmYp!t&w)z1C4F7JaMePhSkWnZq$u*x+A2D5H8KbNfQiUlXo#s%v(y0B3F6I9LdOgRjVmYq!t&w-z1C4G7JbMePhTkWnZr$u(x+A2E5H8KcNfQiUlXp#s%v)y0B3F6IaLdOgSjVmYq!t*w-z1D4G7JbMeQhTkWoZr$u(x+B2E5H9KcNfRiUmXp#s&v)y0C3F7IaLdPgSjVnYq!t*w-A1D4G8JbMeQhTlWoZr%u(x+B2E6H9KcOfRiUmXp!s&v)z0C3F7IaMdPgSkVnYq$t*x-A1D5G8JbNeQiTlWo#r%u(y+B3E6H9LcOfRjUmXp!s&w)z0C4F7IaMdPhSkVnZq$t*x-A2D5G8KbNUmXp!s&v)z0C3F7IaMdPgSkVnYq$t*x-A1D5G8JbNeQhTlWo#r%u(y+B2E6H9LcOfRjUmXp!s&w)z0C4F7IaMdPhSkVnZq$t*x-A2D5G8KbNeQiTlXo#r%v(y+B3E6I9LcOgRjUmYp!t&w)z1C4F7JaMdPhSkWnZq$u*x-A2D5H8KbNfQiTlXo#s%v(y0B3E6I9LdOgRjVmYp!t&w-z1C4G7JaMePhTkWnZr$u*x+A2E5H8KcNfQiUlXo#s%v)y0B3F6I9LdOgSjVmYq!t&w-z1D4G7JbMePhTkWoZr$u(x+A2E5H9KcNfRiUlXp#s&v)y0C3F6IaLdPgSjVnYq!t*w-z1D4G8JbMeQhTkWoZr%u(x+B2E5H9KcOfRiUmXp#s&v)z0C3F7IaLdPgSkVnYq$t*w-A1D5G8JbNeQhTlWo#r%u(y+B2E6H9LcOfRjUmXp!s&v)z0C4F7IaMdPgSkVnZq$t*x-A1D5G8KbNeQiTlWo#r%v(y+B3E6H9LcOgRjUmYp!s&w)z1C4F7JaMdPhSkWnZq$u*x-A2D5G8KbNfQiTlXo#r%v(y0B3E6I9LcOgRjVmYp!t&w)z1C4G7JaMePhSkWnZr$u*x+A2D5H8KcNfQiUlXo#s%v)y0B3F6I9LdOgRjVmYq!t&w-z1C4G7JbMePhTkWnZr$u(x+A2E5H8KcNfRiUlXp#s%v)y0C3F6IaLdOgSjVnYq!t*w-z1D4G8JbMeQhTkWoZr%u(x+B2E5H9KcNfRiUmXp#s&v)y0C3F7IaLdPgSjVnYq$t*w-A1D4G8JbNeQhTlWoZr%u(y+B2E6H9KcOfRjUmXp!s&v)z0C4F7IaMdPgSkVnYq$t*x-A1D5G8JbNeQiTlWo#r%u(y+B3E6H9LcOfRjUmYp!s&w)z0C4F7JaMdPhSkVnZq$u*x-A2D5GcOfRjUmXp!s&v)z0C3F7IaMdPgSkVnYq$t*x-A1D5G8JbNeQiTlWo#r%u(y+B3E6H9LcOfRjUmYp!s&w)z0C4F7JaMdPhSkVnZq$u*x-A2D5G8KbNeQiTlXo#r%v(y+B3E6I9LcOgRjUmYp!t&w)z1C4F7JaMePhSkWnZq$u*x+A2D5H8KbNfQiUlXo#s%v(y0B3F6I9LdOgRjVmYq!t&w-z1C4G7JaMePhTkWnZr$u*x+A2E5H8KcNfQiUlXp#s%v)y0B3F6IaLdOgSjVmYq!t*w-z1D4G7JbMeQhTkWoZr$u(x+B2E5H9KcNfRiUlXp#s&v)y0C3F6IaLdPgSjVnYq!t*w-A1D4G8JbMeQhTlWoZr%u(x+B2E6H9KcOfRiUmXp!s&v)z0C3F7IaMdPgSkVnYq$t*w-A1D5G8JbNeQhTlWo#r%u(y+B2E6H9LcOfRjUmXp!s&w)z0C4F7IaMdPhSkVnZq$t*x-A2D5G8KbNeQiTlXo#r%v(y+B3E6I9LcOgRjUmYp!s&w)z1C4F7JaMdTlWo#r%u(y+B2E6H9LcOfRjUmXp!s&w)z0C4F7IaMdPhSkVnZq$t*x-A2D5G8KbNeQiTlWo#r%v(y+B3E6H9LcOgRjUmYp!s&w)z1C4F7JaMdPhSkWnZq$u*x-A2D5H8KbNfQiTlXo#s%v(y0B3E6I9L
溫馨提示
- 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)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 河南省名校聯(lián)考2025-2026學(xué)年高三一模原文試卷(含答案)
- 中學(xué)學(xué)生社團管理制度
- 【寒假專項】《利率》人教版六年級數(shù)學(xué)下冊應(yīng)用題專項訓(xùn)練(含答案)
- 養(yǎng)老院家屬溝通制度
- 企業(yè)員工績效考核評價制度
- 智慧養(yǎng)老新篇章
- 2025年天津市化學(xué)工業(yè)學(xué)校招聘考試真題
- 阜陽潁東法院書記員招聘考試真題庫2025
- 我國上市公司橫向并購風(fēng)險管理深度剖析
- 我國上市公司并購溢價影響因素的多維度實證剖析
- 2026中國電信四川公用信息產(chǎn)業(yè)有限責(zé)任公司社會成熟人才招聘備考題庫及答案詳解參考
- 郵政服務(wù)操作流程與規(guī)范(標(biāo)準(zhǔn)版)
- 2025年年輕人生活方式洞察報告-海惟智庫
- 2026昆山鈔票紙業(yè)有限公司校園招聘15人備考題庫及1套完整答案詳解
- 南瑞9622型6kV變壓器差動保護原理及現(xiàn)場校驗實例培訓(xùn)課件
- 2026年重慶市江津區(qū)社區(qū)專職人員招聘(642人)考試參考題庫及答案解析
- 統(tǒng)編版(2024)七年級上冊道德與法治期末復(fù)習(xí)必背知識點考點清單
- 新華資產(chǎn)招聘筆試題庫2026
- 2026年春節(jié)放假前員工安全培訓(xùn)
- 造口常用護理用品介紹
- 小米銷售新人培訓(xùn)
評論
0/150
提交評論