系統(tǒng)任務和函數(shù)_第1頁
系統(tǒng)任務和函數(shù)_第2頁
系統(tǒng)任務和函數(shù)_第3頁
系統(tǒng)任務和函數(shù)_第4頁
系統(tǒng)任務和函數(shù)_第5頁
已閱讀5頁,還剩77頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

為了便于設(shè)計者對仿真過程進行控制,以及對仿真結(jié)果進行分析比較,VerilogHDL提供了大量的系統(tǒng)功能調(diào)用,大致可以分成兩種:一種是任務型的功能調(diào)用,稱為系統(tǒng)任務;另一種是函數(shù)型的功能調(diào)用,稱為系統(tǒng)函數(shù)。VerilogHDL的系統(tǒng)任務與系統(tǒng)函數(shù)是以字符“$”開頭的標識符,一般在initial和always過程塊中調(diào)用系統(tǒng)任務和函數(shù)主要區(qū)別有兩點:系統(tǒng)任務可以沒有返回值,或有多個返回值,而系統(tǒng)函數(shù)只有一個返回值;系統(tǒng)任務可以帶有延遲,而系統(tǒng)函數(shù)不允許延遲,在0時刻執(zhí)行。依據(jù)實現(xiàn)功能的不同,可分成以下幾類:1)顯示任務(displaytask)2)文件輸入/輸出任務(FileI/Otask)3)時間標度任務(timescaletask)4)模擬控制任務(simulationcontroltask)5)時序驗證任務(timingchecktask)6)PLA建模任務(PLAmodelingtask)7)隨機建模任務(stochasticmodelingtask)8)實數(shù)變換函數(shù)(conversionfunctionsforreal)9)概率分布函數(shù)(probabilisticdistributionfunction)顯示系統(tǒng)任務用于信息顯示和輸出。這些系統(tǒng)任務進一步分為:?顯示和寫入任務?探測監(jiān)控任務?連續(xù)監(jiān)控任務$display與$write都屬于顯示類系統(tǒng)任務調(diào)用形式$display(“格式控制字符串”,輸出變量名表項);$write(“格式控制字符串”,輸出變量名表項);輸出變量名表項就是指要輸出的變量,各變量名之間以逗號相隔;格式控制字符串的內(nèi)容包括兩部分:需要與輸出變量一起在輸出時一并顯示的普通字符;對輸出變量顯示形式進行控制的格式說明符。格式相同區(qū)別:$display任務具有自動換行的功能下面以$display任務為例進行詳細說明。$display可以用來輸出字符串、表達式及變量值,其語法格式與C語言中的printf函數(shù)相同,可表示如下:$display(<format_specifiers>,signal,signal,……);其中,<format_specifiers>用來指定輸出格式。表7.1給出了各種不同的輸出格式。普通字符,即需要原樣輸出的字符。其中一些特殊的字符可以通過表2中的轉(zhuǎn)換序列來輸出。下面表中的字符形式用于格式字符串參數(shù)中,用來顯示特殊的字符

【例7.9】$display任務的例子。$display("HelloDrBlair");……output:HelloDrBlair$display($time)//目前的仿真時間……output:460counter=4'b10;$display("Thecountis%b",counter);……output:Thecountis0010在$display和$write的參數(shù)列表中,其“輸出表列”是需要輸出的一些數(shù)據(jù),可以是表達式,下面舉例說明例7-10moduledisp;initialbegin$display("\\\t%%\n\"\123");endendmodule輸出結(jié)果為\%"S”從上面的這個例子中可以看到一些特殊字符的輸出形式(八進制數(shù)123就是字符S)moduledisp;reg[31:0]rval;pulldown(pd);initialbeginrval=101;$display("rval=%hhex%ddecimal",rval,rval);$display("rval=%ootal%bbinary",rval,rval);$display("rvalhas%casciicharactervalue",rval);$display("pdstrengthvalueis%v",pd);$display("currentscopeis%m");$display("%sisasciivaluefor101",101);$display("simulationtimeis%t",$time);endendmodule其輸出結(jié)果為:rval=00000065hex101decimalrval=00000000145octal00000000000000000000000001100101binaryrvalhaseasciicharactervaluepdstrengthvalueisStXcurrentscopeisdispeisasciivaluefor101simulationtimeis01輸出列表中數(shù)據(jù)的顯示寬度是自動按照輸出格式進行調(diào)整的。2用表達式的最大可能值所占的位數(shù)來顯示表達式的當前值。3十進制數(shù)格式輸出時,輸出結(jié)果前面的0值用空格來代替。對moduleprintval;reg[11:0]r1;initialbeginr1=10;$display("Printingwithmaximumsize=%d=%h",r1,r1);$display("Printingwithminimumsize=%0d=%0h",r1,r1);endenmodule輸出結(jié)果為:Printingwithmaximumsize=10=00a:printingwithminimumsize=10=a在顯示輸出數(shù)據(jù)時,在經(jīng)過格式轉(zhuǎn)換以后,總是用最少的位數(shù)來顯示表達式的當前值$display("Simulationtimeis%t",$time);$display($time,":R=%b,Q=%b,QB=%b",R,S,Q,QB);//因為沒有指定格式,時間按十進制顯示。$write("Simulationtimeis:);$write("%t\n",$time);上述語句輸出$time、R、S、Q和QB等值的執(zhí)行結(jié)果如下:Simulationtimeis1010:R=1,S=0,Q=0,QB=1Simulationtimeis10end如果輸出列表中表達式的值包含有不確定的值或高阻值,其結(jié)果輸出遵循以下規(guī)則:(1).在輸出格式為十進制的情況下:如果表達式值的所有位均為不定值,則輸出結(jié)果為小寫的x。如果表達式值的所有位均為高阻值,則輸出結(jié)果為小寫的z。如果表達式值的部分位為不定值,則輸出結(jié)果為大寫的X。如果表達式值的部分位為高阻值,則輸出結(jié)果為大寫的Z。2).在輸出格式為十六進制和八進制的情況下:每4位二進制數(shù)為一組代表一位十六進制數(shù),每3位二進制數(shù)為一組代表一位八進制數(shù)。如果表達式值相對應的某進制數(shù)的所有位均為不定值,則該位進制數(shù)的輸出的結(jié)果為小寫的x。如果表達式值相對應的某進制數(shù)的所有位均為高阻值,則該位進制數(shù)的輸出結(jié)果為小寫的z。如果表達式值相對應的某進制數(shù)的部分位為不定值,則該位進制數(shù)輸出結(jié)果為大寫的X。如果表達式值相對應的某進制數(shù)的部分位為高阻值,則該位進制數(shù)輸出結(jié)果為大寫的Z。對于二進制輸出格式,表達式值的每一位的輸出結(jié)果為0、1、x、z。下面舉例說明:$display("%d",1'bx); 輸出結(jié)果為:x$display("%h",14'bx0_1010);輸出結(jié)果為:xxXa$display("%h%o",12'b001x_xx10_1x01,12'b001_xxx_101_x01); 輸出結(jié)果為:XXX1x5X注意:因為$write在輸出時不換行,要注意它的使用??梢栽?write中加入換行符\n,以確保明確的輸出顯示格式在VerilogHDL中,除了$display與$write這兩種主要的標準輸出任務外,還有以下幾種標準輸出任務:(1)?$displayb與$writeb(輸出二進制數(shù))。(2)?$displayo與$writeo(輸出八進制數(shù))。(3)?$displayh與$writeh(輸出十六進制數(shù))。通過顯示任務中的%m的選項,可以顯示任意級別的層次。例modulem;initial$display(“displayingin%m”)Endmodule顯示層次moduletop;mm1();mm2();mm3();Endmodule仿真輸出如下顯示:displayingintop.m1displayingintop.m2displayingintop.m3$strobe屬探測監(jiān)控任務,用于在某時刻所有的事件都已處理完畢后,在時間步的末尾將結(jié)果輸出。更多地用來顯示用非阻塞方式賦值的變量的值探測任務與顯示任務的不同之處在于:顯示任務在遇到語句時執(zhí)行,而探測任務的執(zhí)行要推遲到時間步結(jié)束時進行

integerCool;initialbeginCool=1;$display("Afterfirstassignment,Coolhasvalue%d"cool);$strobe("Whenstrobeisexecuted,Coolhasvalue%d"cool);Cool=2;$display("Aftersecondassignment,Coolhasvalue%d"cool);end產(chǎn)生的輸出為:Afterfirstassignment,Coolhasvalue1Whenstrobeisexecuted,Coolhasvalue2Aftersecondassignment,Coolhasvalue2modulestrobe_demo;rega,b;//initial語句塊1initialbegina=0;$display(“abydisplayis:”,a);//displayo$strobe("abystrobeis:",a);//display1a=1;endStrobe舉例//initial語句塊2initialbeginb<=0;$display("bbydisplayis:",b);//displayx$strobe("bbystrobeis:",b);//displayo#5;$display("#5bbydisplayis:",b);//displayo$strobe("#5bbystrobeis:",b);//display1b<=1;endendmodule$monitor一旦被調(diào)用后,將隨時對輸出變量名表項中列出的各個變量進行檢測,如發(fā)現(xiàn)其中的任何一個變量在模擬過程中的某一時刻發(fā)生了任何形式的改變,就會啟動$monitor任務,整個輸出列表中所有變量和表達式的值都會按照所規(guī)定的格式,在時間步結(jié)束時輸出結(jié)果。如果在同一仿真時刻,多個變量或表達式值發(fā)生變化,則該時刻只輸出顯示一次。如$monitor(“a=%b,b=%b,out=%b\n”,a,b,out)

可以通過系統(tǒng)任務$monitoron打開監(jiān)控任務,通過系統(tǒng)任務$monitoroff關(guān)閉監(jiān)控任務。多模塊調(diào)試時,會有多個模塊調(diào)用monitor,但是任意時刻只能有一個monitor被啟動,這就需要用$monitoron和$monitoroff在特定時刻啟動需要檢測的模塊,關(guān)閉其它模塊。缺省情況下,監(jiān)控任務在仿真開始時自動打開。

【例7-13】系統(tǒng)任務$monitor的例子。modulemyTest;integera,b;initialbegina=2;b=4;foreverbegin#5a=a+b;#5b=a-1;endendinitial#40$finish;initialbegin$monitor($time,"a=%d,b=%d",a,b);endendmodule輸出結(jié)果為:0a=2,b=45a=6,b=410a=6,b=515a=11,b=520a=11,b=1025a=21,b=1030a=21,b=2035a=41,b=20不要用monitor監(jiān)控周期性循環(huán)變化的信號下面是模塊textio仿真的輸出:$writeb輸出:0xxxxxxxxx注意data是32位數(shù)據(jù),由8位十六進制數(shù)表示。時間以沒有前導零的十進制形式輸出。缺省情況下,值以十進制顯示,忽略前導零,與%0d格式符相同。可以在一個格式化符前插入一個0使Verilog忽略開頭的零。$displayh:00000000000000f000000101注意當前時間,一個64位量,需要16個十六進制的數(shù)。$display:1020$strobe:1030moduletextio;regflag;reg[31:0]data;initialbegin

$writeb($time,,%d,%h"\t",data,,flag,"\n");#15flag=1;data=16;

$displayh($time,,data,,flag);endinitialbegin#10data=20;

$strobe($time,,data);

$display($time,,data);

data=30;endendmodule調(diào)用形式$finish;$stop;$finish(n);$stop(n);$finish的作用就是終止仿真器的運行,結(jié)束$stop暫時掛起仿真器,進入Verilog界面,可以通過輸入相應命令使仿真繼續(xù)運行,$stop的作用只相當于一個pause暫停語句。n只能取以下三個值:0:不輸出任何信息。1:輸出結(jié)束仿真的時間及模擬文件的位置2:在1的基礎(chǔ)上增加對CPU時間、機器內(nèi)存占有情況等統(tǒng)計結(jié)果的輸出。當$finish不帶參數(shù)時,對應于缺省值1?!纠?-15】仿真結(jié)束任務的例子。initialbeginclock=1'b0;…… //需要完成的任務#200$stop //暫停仿真并進入交互方式#500$finish //結(jié)束仿真任務End又if()$stope;或#ntime$finish;系統(tǒng)函數(shù)$time與$realtime都屬模擬時標類系統(tǒng)函數(shù),調(diào)用形式:$time$realtime都返回從模擬程序開始執(zhí)行到被調(diào)用時刻的時間,$time返回64位的整數(shù),指定當前的仿真時間;$realtime以實數(shù)形式返回當前的仿真時間。時刻是以模塊的仿真時間尺度為基準的。`timescale10ns/1nsmoduletest;regset;parameterp=1.6;initialbegin$monitor($time,,"set=",set);#pset=0;#pset=1;endendmodule輸出結(jié)果為:0set=x2set=03set=1`timescale10ns/1nsmoduletest;regset;parameterp=1.55;initialbegin$monitor($realtime,,"set=",set);#pset=0;#pset=1;endendmodule輸出結(jié)果為:0set=x1.6set=03.2set=1從本例可以看出,$realtime將仿真時刻經(jīng)過尺度變換以后即輸出,不需進行取整作。所以$realtime返回的時刻是實型數(shù)

1將數(shù)據(jù)和分析的工作從testbench中隔離出來,便于協(xié)同工作。2,可通過其它軟件工具c/c++、matlab等快速產(chǎn)生數(shù)據(jù)3,將數(shù)據(jù)寫入文檔后,同通過c/c++、excel以及matlab工具分析。因此在測試代碼中完成文件輸入輸出操作,是測試大型設(shè)計的必備手段。為什么要用veriloghdl語言讀取/寫入文件呢?Verilog的結(jié)果通常輸出到標準輸出或verilog.log文本中,通過輸入輸出任務可將結(jié)果定向選擇輸出到指定的文件首先定義integer指針,然后調(diào)用$fopen(file_name,mode)任務,不需要模式時,調(diào)用$fopen(file_name),常用mode包括:“w"打開文件并從文件頭開始寫,如果不存在就創(chuàng)建文件?!皐+"打開文件并從文件頭開始讀寫,如果不存在就創(chuàng)建文件"a"打開文件并從文件末尾開始寫,如果不存在就創(chuàng)建文件“a+"打開文件并從文件末尾開始讀寫,如果不存在就創(chuàng)建文件用法integerfile_id;file_id=fopen("file_path/file_name");$fopen將返回關(guān)于文件file_name的整數(shù)(指針),并把它賦給整形變量file_id打開文件例integerhandle1,handle2,handle3;//標準輸出是打開的,descriptor=32`h0000_0001initialbeginhandle1=$fopen("file1.out");//handle1=32`h0000_0002handle2=$fopen("file2.out");//handle1=32`h0000_0004handle3=$fopen("file3.out");//handle1=32`h0000_0008顯示、寫入、探測和監(jiān)控系統(tǒng)任務都有一個用于向文件輸出的相應副本,該副本可用于將信息寫入文件調(diào)用格式:$fdisplay(file_id,p1,p2,…,pn)$fmonitor(file_id,p1,p2,…,pn)$fstrobe(file_id,p1,p2,…,pn)$fwrite(file_id,p1,p2,…,pn)p1,p2,…,pn可以是變量、信號名或者帶引號的字符串。file_id是一個多通道描述符,他可以是一個句柄或者多個文件句柄按位的組合。Verilog會將輸出寫到與file_id中值為1的位相關(guān)聯(lián)的所有文件中。//所有的file_id都在上例中定義integerdesc1,desc2,desc3;initialbegindesc1=handle1│1;$fdisplay(desc1,"display1");//寫到文件file1_out和標準輸出stdoutdesc2=handle1│handle1;$fdisplay(desc1,"display2");//寫到文件file1_out和file2_outdesc3=handle3;$fdisplay(desc3,"display2");//只寫到文件file3_out$fclose(file_id);系統(tǒng)函數(shù)$fopen用于打開一個文件,并還回一個整數(shù)指針.然后,$fdisplay就可以使用這個文件指針在文件中寫入信息寫完后,則可以使用$fclose系統(tǒng)關(guān)閉這個文件例如:integerwrite_out_file;//定義一個文件指針

integerwrite_out_file=$fopen("write_out_file.txt");

$fdisplay(write_out_file,"@%h\n%h",addr,data);$fclose("write_out_file");以上語法是將addr,data分別顯示在"@%h\n%h"中的2個%h的位置,并寫入write_out_file文件指針所指向的write_out_file.txt中.$fopen打開一個文件并返回一個多通道描述符(MCD)。MCD是與文件唯一對應的32位無符號整數(shù)。如果文件不能打開并進行寫操作,MCD將等于0。如果文件成功打開,MCD中的一位將被置位。以$f開始的顯示系統(tǒng)任務將輸出寫入與MCD相對應的文件中...integerMCD1;

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);......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)為標準輸出及verilog.logVerilogHDL程序中有兩個系統(tǒng)任務$readmemb和$readmemh能夠把一個數(shù)據(jù)文件中的數(shù)據(jù)內(nèi)容,讀入到一個指定的存儲器中.。其區(qū)別在于,前者要求以二進制數(shù)據(jù)格式存放數(shù)據(jù)文件,而后者要求以十六進制數(shù)據(jù)格式存放數(shù)據(jù)文件這兩個系統(tǒng)任務可以在仿真的任何時刻被執(zhí)行使用其使用格式共有以下六種:$readmemb("<數(shù)據(jù)文件名>",<存貯器名>);$readmemb("<數(shù)據(jù)文件名>",<存貯器名>,<起始地址>);$readmemb("<數(shù)據(jù)文件名>",<存貯器名>,<起始地址>,<結(jié)束地址>);$readmemh("<數(shù)據(jù)文件名>",<存貯器名>);$readmemh("<數(shù)據(jù)文件名>",<存貯器名>,<起始地址>);$readmemh("<數(shù)據(jù)文件名>",<存貯器名>,<起始地址>,<結(jié)束地址>);在這兩個系統(tǒng)任務中,被讀取的數(shù)據(jù)文件的內(nèi)容只能包含:空白位置(空格,換行,制表格(tab)和form-feeds),注釋行(//形式的和/*...*/形式的都允許),二進制或十六進制的數(shù)字。數(shù)字中不能包含位寬說明和格式說明,對于$readmemb系統(tǒng)任務,每個數(shù)字必須是二進制數(shù)字,對于$readmemh系統(tǒng)任務,每個數(shù)字必須是十六進制數(shù)字。數(shù)字中不定值x或X,高阻值z或Z,和下劃線(_)的使用方法及代表的意義與一般VerilogHDL程序中的用法及意義是一樣的。另外數(shù)字必須用空白位置或注釋行來分隔開。在下面的討論中,地址一詞指對存貯器(memory)建模的數(shù)組的尋址指針。當數(shù)據(jù)文件被讀取時,每一個被讀取的數(shù)字都被存放到地址連續(xù)的存貯器單元中去。存貯器單元的存放地址范圍由系統(tǒng)任務聲明語句中的起始地址和結(jié)束地址來說明,每個數(shù)據(jù)的存放地址在數(shù)據(jù)文件中進行說明。當?shù)刂烦霈F(xiàn)在數(shù)據(jù)文件中,其格式為字符“@”后跟上十六進制數(shù)。如:@hh...h對于這個十六進制的地址數(shù)中,允許大寫和小寫的數(shù)字。在字符“@”和數(shù)字之間不允許存在空白位置??梢栽跀?shù)據(jù)文件里出現(xiàn)多個地址。當系統(tǒng)任務遇到一個地址說明時,系統(tǒng)任務將該地址后的數(shù)據(jù)存放到存貯器中相應的地址單元中去。【例7-16】從文件中讀出數(shù)據(jù)到存儲器的例子。moduletestmemory;reg[7:0]memory[9:0];integerindex;initialbegin$readmemb("mem.dat",memory);for(index=0;index<10;index=index+1)$display("memory[%d]=%b",index[4:0],memory[index]);endendmodule1如果系統(tǒng)任務聲明語句中和數(shù)據(jù)文件里都沒有進行地址說明,則缺省的存放起始地址為該存貯器定義語句中的起始地址。數(shù)據(jù)文件里的數(shù)據(jù)被連續(xù)存放到該存貯器中,直到該存貯器單元存滿為止或數(shù)據(jù)文件里的數(shù)據(jù)存完。2如果系統(tǒng)任務中說明了存放的起始地址,沒有說明存放的結(jié)束地址,則數(shù)據(jù)從起始地址開始存放,存放到該存貯器定義語句中的結(jié)束地址為止。3如果在系統(tǒng)任務聲明語句中,起始地址和結(jié)束地址都進行了說明,則數(shù)據(jù)文件里的數(shù)據(jù)按該起始地址開始存放到存貯器單元中,直到該結(jié)束地址,而不考慮該存貯器的定義語句中的起始地址和結(jié)束地址。4如果地址信息在系統(tǒng)任務和數(shù)據(jù)文件里都進行了說明,那么數(shù)據(jù)文件里的地址必須在系統(tǒng)任務中地址參數(shù)聲明的范圍之內(nèi)。否則將提示錯誤信息,并且裝載數(shù)據(jù)到存貯器中的操作被中斷。5如果數(shù)據(jù)文件里的數(shù)據(jù)個數(shù)和系統(tǒng)任務中起始地址及結(jié)束地址暗示的數(shù)據(jù)個數(shù)不同的話,也要提示錯誤信息。modulereadmem;

reg[7:0]mem[7:0];

reg[2:0]i;

integerfile;

initial

begin

file=$fopen("memory.txt","w");

$readmemb("memoryb.txt",mem,4,0);//從文本的讀取數(shù)據(jù)向mem[4]開始寫入,直到寫到mem[0]

for(i=0;i<7;i=i+1)

begin

$display("mem[%d]=%b",i,mem[i]);

$fdisplay(file,"mem[%d]=%b",i,mem[i]);

end

$readmemh("memoryh.txt",mem);//如果沒有地址的限制,就默認從//mem[0]到mem定義的最大地址。

for(i=0;i<7;i=i+1)

begin

$display("mem[%d]=%h",i,mem[i]);

$fdisplay(file,"mem[%d]=%h",i,mem[i]);

end

$fclose(file);

end

endmodulemeomoryb.txt的文本文件,文件內(nèi)容如下:1010110100011101011011110110000100000001111111101111111111101110控制臺輸出與生成的memory.txt中內(nèi)容一致。mem[0]=00000001mem[1]=01100001mem[2]=01101111mem[3]=00011101mem[4]=10101101mem[5]=xxxxxxxxmem[6]=xxxxxxxxmem[0]=32mem[1]=36mem[2]=4fmem[3]=8amem[4]=admem[5]=xxmem[6]=xx結(jié)果分析:首先讀取memoryb.txt中從地址4到地址0的數(shù)據(jù)寫入mem[0]至mem[4],沒有寫入的存儲器內(nèi)容為xx,然后讀取memoryh.txt從地址0到地址6的數(shù)據(jù)寫入mem[0]至mem[6],由于memoryh.txt只有4個數(shù)據(jù),mem[4]以后的數(shù)據(jù)就沒有了,保持上一次寫的內(nèi)容,所以,mem[4]為ad(十六進制)即二進制10101101VCD文件(valuechangedump文件)是常用的波形記錄文件,與波形的作用等同,是一個ASCII文件。包含設(shè)計中指定變量取值變化的信息。它的主要目的是為其它后處理工具提供信息。dump系統(tǒng)任務基本都在initial模塊中使用下面的系統(tǒng)任務用于創(chuàng)建和將信息導入VCD文件。1)$dumpfile:本系統(tǒng)任務指定轉(zhuǎn)儲文件名。例如:$dumpfile(“uart.dump”);2)$dumpvars:本系統(tǒng)任務指定哪些變量值變化時轉(zhuǎn)儲進轉(zhuǎn)儲文件。$dumpvars;//無參數(shù),它指定在設(shè)計中轉(zhuǎn)儲所有變量。$dumpvars(level,module_name);//在指定模塊和所有指定層次下面的模塊中的轉(zhuǎn)儲變量。$dumpvars(1,UART);//只轉(zhuǎn)儲模塊UART中的變量。$dumpvars(2,UART);//轉(zhuǎn)儲UART及其下一層模塊中的所有變量。$dumpvars(0,UART);//第0層導致UART模塊及其下面層次中所有模塊中的各個變量被轉(zhuǎn)儲。$dumpvars(0,P_State,N_State);//轉(zhuǎn)儲關(guān)于P_State和N_State的變量信息。層次數(shù)與此例無關(guān),但是必須給出//層次數(shù)。$dumpvars(3,Div.Clk,UART);//層次數(shù)只作用于模塊本身及其下面兩個層次中的所有變量。在此例中,只作用于模塊UART,即UART中所有變量及UART下面兩個層次中各模塊的所有變量,同時轉(zhuǎn)儲變量Div.Clk上值的變化。3)$dumpoff:本系統(tǒng)任務促使轉(zhuǎn)儲任務被掛起。$dumpoff;4)$dumpon:本系統(tǒng)任務促使所有轉(zhuǎn)儲任務被掛起。語法如下:$dumpon;5)$dumpall:本系統(tǒng)任務執(zhí)行時轉(zhuǎn)儲所有當前指定的變量值。語法如下:$dumpall6)$dumplimit:本系統(tǒng)任務為VCD文件指定最大長度(字節(jié))。轉(zhuǎn)儲在到達此界限時停止。例如,$dumplimit(1024);//VCD文件的最大值為1024字節(jié)。7)$dumpflush:本系統(tǒng)任務刷新操作系統(tǒng)VCD文件緩沖區(qū)中的數(shù)據(jù),將數(shù)據(jù)存到VCD文件中。執(zhí)行此系統(tǒng)任務后,轉(zhuǎn)儲任務處于喚醒狀態(tài)。$dumpflush;?文件頭信息:提供日期、模擬器版本和時間標度單位。?節(jié)點信息:定義轉(zhuǎn)儲作用域和變量類型。?取值變化:實際取值隨時間變化。記錄絕對模擬時間。下面是在5~12之間計數(shù)的可逆計數(shù)器的例子:moduleCountUpDown(Clk,Count,Up_Down);inputClk,Up_Down;output[0:3]Count;reg[0:3]Count;initialCount=4‘d5;always@(posedgeClk)beginif(Up_Down)beginCount=Count+1;if(Count>12)Count=12;endelsebeginCount=Count-1;if(Count<5)Count=5;endendendmodulemoduletest;regClock,UpDn;wire[0:3]Cnt_Out;parameterON_DELAY=1,OFF_DELAY=2;CountUpDown

C1(Clock,Cnt_Out,UpDn);alwaysbeginClock=1;#ON_DELAY;Clock=0;#OFF_DELAY;endinitialbeginUpDn=0;#50UpDn=1;#100$dumpflush;$stop;//停止模擬。endinitialbegin$dumpfile(“count.dump”);$dumplimit(4096);$dumpvars(0,Test;)$dumpvars(0,Cl.Count,Cl.Clk,C1.Up_Down);endendmodule當進行模塊測試時,常需要提供隨機脈沖序列,該功能可以通過系統(tǒng)函數(shù)$random來實現(xiàn),它的語法格式為$random%<number>;其中,<number>為一大于0的整數(shù),用來指定所產(chǎn)生隨機數(shù)的范圍,即-<number>+1到<number>-1。這個系統(tǒng)函數(shù)提供了一個產(chǎn)生隨機數(shù)的手段。當函數(shù)被調(diào)用時返回一個32bit的隨機數(shù)。reg[23:0]rand;rand=$random%60;上面的例子給出了一個范圍在-59到59之間的隨機數(shù),下面的例子通過位并接操作產(chǎn)生一個值在0到59之間的數(shù)。reg[23:0]rand;rand={$random}%60;“編譯預處理”是VerilogHDL編譯系統(tǒng)的一個組成部分。VerilogHDL語言允許在程序中使用幾種特殊的命令(它們不是一般的語句)。VerilogHDL編譯系統(tǒng)通常先對這些特殊的命令進行“預處理”,然后將預處理的結(jié)果和源程序一起在進行通常的編譯處理。與C語言中的編譯預處理指令類似,VerilogHDL中提供了大量的編譯指令。通過這些編譯指令,EDA工具開發(fā)商使他們的工具解釋VerilogHDL模型變得相當容易。(1)編譯指令以字符“`”開頭。

(2)編譯指令并非VerilogHDL的描述,因而編譯指令末尾不需要分號。

(3)編譯指令不受模塊與文件的限制。在進行Verilog語言編譯時,已定義的編譯指令一直有效,直到有其它的編譯指令修改它或?qū)⒃摼幾g指令關(guān)閉VerilogHDL中文件包含指令`include類似于C語言中的編譯指令#include?,文件包含指令在模塊調(diào)用時非常有用,可以通過該指令包含諸如類型聲明與函數(shù)之類的Verilog碼把語句中指定的源文件全部包含到當前的文件中形式定義:`include“文件名”幾點說明:1.每條`include語句只能用于對一個文件的包含,多個文件的包含只需用多條語句分別注明即可。2.文件包含允許嵌套。3.`include命令可以出現(xiàn)在VerilogHDL源程序的任何地方,被包含文件名可以是相對路徑名,也可以是絕對路徑名。例如:'include"parts/count.v“4可以將多個`include命令寫在一行,在`include命令行,只可以出空格和注釋行。例如下面的寫法是合法的。'include"fileB"'include"fileC"http://includingfileBandfileC

【例7-17】文件包含指令的例子。//文件file1.v的內(nèi)容`defineWORDSIZE8function[WORDSIZE-1:0]fastadder;……endfunction//文件secondfile的內(nèi)容modulesecondfile(in1,in2,out)`includefile1.vwire[WORDSIZE-1:0]temp;assigntemp=fastadder(in1,in2);……endmodule用一個指定的標識符來代表一個字符串,它的一般形式為:`define標識符(宏名)字符串(宏內(nèi)容)如:`definesignalstring它的作用是指定用標識符signal來代替string這個字符串,在編譯預處理時,把程序中在該命令以后所有的signal都替換成string。這種方法使用戶能以一個簡單的名字代替一個長的字符串,也可以用一個有含義的名字來代替沒有含義的數(shù)字和符號,因此把這個標識符(名字)稱為“宏名”,在編譯預處理時將宏名替換成字符串的過程稱為“宏展開”。`define是宏定義命令。這里需要注意的是,文本內(nèi)容必須在一行中定義,不能采用多行。宏替換指令與參數(shù)定義的區(qū)別在于,參數(shù)具有全局可見性,而宏替換指令只局限于宏函數(shù)。

【例7-18】宏替換的例子。

`definecycle20//clockperiod

always#(cycle/4)clk=~clk;

`defineNAND(dval)nand#(dval)

`NAND(3)i1(y,a,b);

`NAND(3:4:5)i2(o,c,d);可以利用`undef指令來取消宏定義。1宏名可以用大寫字母表示,也可以用小寫字母表示。建議使用大寫字母,以與變量名相區(qū)別。2`define命令可以出現(xiàn)在模塊定義里面,也可以出現(xiàn)在模塊定義外面。宏名的有效范圍為定義命令之后到原文件結(jié)束。通常,`define命令寫在模塊定義的外面,作為程序的一部分,在此程序內(nèi)有效。3在引用已定義的宏名時,必須在宏名的前面加上符號“`”,表示該名字是一個經(jīng)過宏定義的名字。4宏定義是用宏名代替一個字符串,也就是作簡單的置換,不作語法檢查。預處理時照樣代入,不管含義是否正確。只有在編譯已被宏展開后的源程序時才報錯5使用宏名代替一個字符串,可以減少程序中重復書寫某些字符串的工作量。而且記住一個宏名要比記住一個無規(guī)律的字符串容易,這樣在讀程序時能立即知道它的含義,當需要改變某一個變量時,可以只改變`define命令行,一改全改。如例1中,先定義WORDSIZE代表常量8,這時寄存器data是一個8位的寄存器。如果需要改變寄存器的大小,只需把該命令行改為:`defineWORDSIZE16。這樣寄存器data則變?yōu)橐粋€16位的寄存器。由此可見使用宏定義,可以提高程序的可植性和可讀性。6宏定義不是VerilogHDL語句,不必在行末加分號。如果加了分號會連分號一起進行置換。

如:moduletest;rega,b,c,d,e,out;`defineexpressiona+b+c+d;assignout=`expression+e;...endmodule經(jīng)過宏展開以后,該語句為:assignout=a+b+c+d;+e;顯然出現(xiàn)語法錯誤7在進行宏定義時,可以引用已定義的宏名,可以層層置換。如:[例7-19]:moduletest;rega,b,c;wireout;`defineaaa+b`defineccc+`aaassignout=`cc;endmodule這樣經(jīng)過宏展開以后,assign語句為assignout=c+a+b;8宏名和宏內(nèi)容必須在同一行中進行聲明。如果在宏內(nèi)容中包含有注釋行,注釋行不會作為被置換的內(nèi)容。如:module`definetyp_nandnand#5//defineanandwithtypicaldelay`typ_nandg121(q21,n10,n11);………endmodule經(jīng)過宏展開以后,該語句為:nand#5g121(q21,n10,n11);宏內(nèi)容可以是空格,在這種情況下,宏內(nèi)容被定義為空的。當引用這個宏名時,不會有內(nèi)容被置換組成宏內(nèi)容的字符串不能夠被以下的語句記號分隔開的。注釋行數(shù)字字符串確認符關(guān)鍵詞雙目和三目字符運算符如下面的宏定義聲明和引用是非法的。`definefirst_half"startofstring$display(`first_halfendofstring");注意在使用宏定義時要注意以下情況:1對于某些EDA軟件,在編寫源程序時,如使用和預處理命令名相同的宏名會發(fā)生沖突,因此建議不要使用和預處理命令名相同的宏名。2宏名可以是普通的標識符(變量名)。例如signal_name和‘signal_name的意義是不同的。但是這樣容易引起混淆,建議不要這樣使用。`timescale命令用來說明跟在該命令后的模塊的時間單位和時間精度。使用`timescale命令可以在同一個設(shè)計里包含采用了不同的時間單位的模塊。例如,一個設(shè)計中包含了兩個模塊,其中一個模塊的時間延遲單位為ns,另一個模塊的時間延遲單位為ps。EDA工具仍然可以對這個設(shè)計進行仿真測試。`timescale命令的格式如下:`timescale<時間單位>/<時間精度>在這條命令中,時間單位參量是用來定義模塊中仿真時間和延遲時間的基準單位的。時間精度參量是用來聲明該模塊的仿真時間的精確程度的,該參量被用來對延遲時間值進行取整操作(仿真前),因此該參量又可以被稱為取整精度。如果在同一個程序設(shè)計里,存在多個`timescale命令,則用最小的時間精度值來決定仿真的時間單位。另外時間精度至少要和時間單位一樣精確,時間精度值不能大于時間單位值。在`timescale命令中,用于說明時間單位和時間精度參量值的數(shù)字必須是整數(shù)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 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

提交評論