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

下載本文檔

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

文檔簡(jiǎn)介

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

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

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語(yǔ)句塊1initialbegina=0;$display(“abydisplayis:”,a);//displayo$strobe("abystrobeis:",a);//display1a=1;endStrobe舉例//initial語(yǔ)句塊2initialbeginb<=0;$display("bbydisplayis:",b);//displayx$strobe("bbystrobeis:",b);//displayo#5;$display("#5bbydisplayis:",b);//displayo$strobe("#5bbystrobeis:",b);//display1b<=1;endendmodule$monitor一旦被調(diào)用后,將隨時(shí)對(duì)輸出變量名表項(xiàng)中列出的各個(gè)變量進(jìn)行檢測(cè),如發(fā)現(xiàn)其中的任何一個(gè)變量在模擬過(guò)程中的某一時(shí)刻發(fā)生了任何形式的改變,就會(huì)啟動(dòng)$monitor任務(wù),整個(gè)輸出列表中所有變量和表達(dá)式的值都會(huì)按照所規(guī)定的格式,在時(shí)間步結(jié)束時(shí)輸出結(jié)果。如果在同一仿真時(shí)刻,多個(gè)變量或表達(dá)式值發(fā)生變化,則該時(shí)刻只輸出顯示一次。如$monitor(“a=%b,b=%b,out=%b\n”,a,b,out)

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

【例7-13】系統(tǒng)任務(wù)$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)變化的信號(hào)下面是模塊textio仿真的輸出:$writeb輸出:0xxxxxxxxx注意data是32位數(shù)據(jù),由8位十六進(jìn)制數(shù)表示。時(shí)間以沒(méi)有前導(dǎo)零的十進(jìn)制形式輸出。缺省情況下,值以十進(jìn)制顯示,忽略前導(dǎo)零,與%0d格式符相同。可以在一個(gè)格式化符前插入一個(gè)0使Verilog忽略開(kāi)頭的零。$displayh:00000000000000f000000101注意當(dāng)前時(shí)間,一個(gè)64位量,需要16個(gè)十六進(jìn)制的數(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的作用就是終止仿真器的運(yùn)行,結(jié)束$stop暫時(shí)掛起仿真器,進(jìn)入Verilog界面,可以通過(guò)輸入相應(yīng)命令使仿真繼續(xù)運(yùn)行,$stop的作用只相當(dāng)于一個(gè)pause暫停語(yǔ)句。n只能取以下三個(gè)值:0:不輸出任何信息。1:輸出結(jié)束仿真的時(shí)間及模擬文件的位置2:在1的基礎(chǔ)上增加對(duì)CPU時(shí)間、機(jī)器內(nèi)存占有情況等統(tǒng)計(jì)結(jié)果的輸出。當(dāng)$finish不帶參數(shù)時(shí),對(duì)應(yīng)于缺省值1?!纠?-15】仿真結(jié)束任務(wù)的例子。initialbeginclock=1'b0;…… //需要完成的任務(wù)#200$stop //暫停仿真并進(jìn)入交互方式#500$finish //結(jié)束仿真任務(wù)End又if()$stope;或#ntime$finish;系統(tǒng)函數(shù)$time與$realtime都屬模擬時(shí)標(biāo)類系統(tǒng)函數(shù),調(diào)用形式:$time$realtime都返回從模擬程序開(kāi)始執(zhí)行到被調(diào)用時(shí)刻的時(shí)間,$time返回64位的整數(shù),指定當(dāng)前的仿真時(shí)間;$realtime以實(shí)數(shù)形式返回當(dāng)前的仿真時(shí)間。時(shí)刻是以模塊的仿真時(shí)間尺度為基準(zhǔn)的。`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將仿真時(shí)刻經(jīng)過(guò)尺度變換以后即輸出,不需進(jìn)行取整作。所以$realtime返回的時(shí)刻是實(shí)型數(shù)

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

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

$fdisplay(write_out_file,"@%h\n%h",addr,data);$fclose("write_out_file");以上語(yǔ)法是將addr,data分別顯示在"@%h\n%h"中的2個(gè)%h的位置,并寫(xiě)入write_out_file文件指針?biāo)赶虻膚rite_out_file.txt中.$fopen打開(kāi)一個(gè)文件并返回一個(gè)多通道描述符(MCD)。MCD是與文件唯一對(duì)應(yīng)的32位無(wú)符號(hào)整數(shù)。如果文件不能打開(kāi)并進(jìn)行寫(xiě)操作,MCD將等于0。如果文件成功打開(kāi),MCD中的一位將被置位。以$f開(kāi)始的顯示系統(tǒng)任務(wù)將輸出寫(xiě)入與MCD相對(duì)應(yīng)的文件中...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(編號(hào)為1)為標(biāo)準(zhǔn)輸出及verilog.logVerilogHDL程序中有兩個(gè)系統(tǒng)任務(wù)$readmemb和$readmemh能夠把一個(gè)數(shù)據(jù)文件中的數(shù)據(jù)內(nèi)容,讀入到一個(gè)指定的存儲(chǔ)器中.。其區(qū)別在于,前者要求以二進(jìn)制數(shù)據(jù)格式存放數(shù)據(jù)文件,而后者要求以十六進(jìn)制數(shù)據(jù)格式存放數(shù)據(jù)文件這兩個(gè)系統(tǒng)任務(wù)可以在仿真的任何時(shí)刻被執(zhí)行使用其使用格式共有以下六種:$readmemb("<數(shù)據(jù)文件名>",<存貯器名>);$readmemb("<數(shù)據(jù)文件名>",<存貯器名>,<起始地址>);$readmemb("<數(shù)據(jù)文件名>",<存貯器名>,<起始地址>,<結(jié)束地址>);$readmemh("<數(shù)據(jù)文件名>",<存貯器名>);$readmemh("<數(shù)據(jù)文件名>",<存貯器名>,<起始地址>);$readmemh("<數(shù)據(jù)文件名>",<存貯器名>,<起始地址>,<結(jié)束地址>);在這兩個(gè)系統(tǒng)任務(wù)中,被讀取的數(shù)據(jù)文件的內(nèi)容只能包含:空白位置(空格,換行,制表格(tab)和form-feeds),注釋行(//形式的和/*...*/形式的都允許),二進(jìn)制或十六進(jìn)制的數(shù)字。數(shù)字中不能包含位寬說(shuō)明和格式說(shuō)明,對(duì)于$readmemb系統(tǒng)任務(wù),每個(gè)數(shù)字必須是二進(jìn)制數(shù)字,對(duì)于$readmemh系統(tǒng)任務(wù),每個(gè)數(shù)字必須是十六進(jìn)制數(shù)字。數(shù)字中不定值x或X,高阻值z(mì)或Z,和下劃線(_)的使用方法及代表的意義與一般VerilogHDL程序中的用法及意義是一樣的。另外數(shù)字必須用空白位置或注釋行來(lái)分隔開(kāi)。在下面的討論中,地址一詞指對(duì)存貯器(memory)建模的數(shù)組的尋址指針。當(dāng)數(shù)據(jù)文件被讀取時(shí),每一個(gè)被讀取的數(shù)字都被存放到地址連續(xù)的存貯器單元中去。存貯器單元的存放地址范圍由系統(tǒng)任務(wù)聲明語(yǔ)句中的起始地址和結(jié)束地址來(lái)說(shuō)明,每個(gè)數(shù)據(jù)的存放地址在數(shù)據(jù)文件中進(jìn)行說(shuō)明。當(dāng)?shù)刂烦霈F(xiàn)在數(shù)據(jù)文件中,其格式為字符“@”后跟上十六進(jìn)制數(shù)。如:@hh...h對(duì)于這個(gè)十六進(jìn)制的地址數(shù)中,允許大寫(xiě)和小寫(xiě)的數(shù)字。在字符“@”和數(shù)字之間不允許存在空白位置??梢栽跀?shù)據(jù)文件里出現(xiàn)多個(gè)地址。當(dāng)系統(tǒng)任務(wù)遇到一個(gè)地址說(shuō)明時(shí),系統(tǒng)任務(wù)將該地址后的數(shù)據(jù)存放到存貯器中相應(yīng)的地址單元中去?!纠?-16】從文件中讀出數(shù)據(jù)到存儲(chǔ)器的例子。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)任務(wù)聲明語(yǔ)句中和數(shù)據(jù)文件里都沒(méi)有進(jìn)行地址說(shuō)明,則缺省的存放起始地址為該存貯器定義語(yǔ)句中的起始地址。數(shù)據(jù)文件里的數(shù)據(jù)被連續(xù)存放到該存貯器中,直到該存貯器單元存滿為止或數(shù)據(jù)文件里的數(shù)據(jù)存完。2如果系統(tǒng)任務(wù)中說(shuō)明了存放的起始地址,沒(méi)有說(shuō)明存放的結(jié)束地址,則數(shù)據(jù)從起始地址開(kāi)始存放,存放到該存貯器定義語(yǔ)句中的結(jié)束地址為止。3如果在系統(tǒng)任務(wù)聲明語(yǔ)句中,起始地址和結(jié)束地址都進(jìn)行了說(shuō)明,則數(shù)據(jù)文件里的數(shù)據(jù)按該起始地址開(kāi)始存放到存貯器單元中,直到該結(jié)束地址,而不考慮該存貯器的定義語(yǔ)句中的起始地址和結(jié)束地址。4如果地址信息在系統(tǒng)任務(wù)和數(shù)據(jù)文件里都進(jìn)行了說(shuō)明,那么數(shù)據(jù)文件里的地址必須在系統(tǒng)任務(wù)中地址參數(shù)聲明的范圍之內(nèi)。否則將提示錯(cuò)誤信息,并且裝載數(shù)據(jù)到存貯器中的操作被中斷。5如果數(shù)據(jù)文件里的數(shù)據(jù)個(gè)數(shù)和系統(tǒng)任務(wù)中起始地址及結(jié)束地址暗示的數(shù)據(jù)個(gè)數(shù)不同的話,也要提示錯(cuò)誤信息。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]開(kāi)始寫(xiě)入,直到寫(xiě)到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);//如果沒(méi)有地址的限制,就默認(rèn)從//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控制臺(tái)輸出與生成的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ù)寫(xiě)入mem[0]至mem[4],沒(méi)有寫(xiě)入的存儲(chǔ)器內(nèi)容為xx,然后讀取memoryh.txt從地址0到地址6的數(shù)據(jù)寫(xiě)入mem[0]至mem[6],由于memoryh.txt只有4個(gè)數(shù)據(jù),mem[4]以后的數(shù)據(jù)就沒(méi)有了,保持上一次寫(xiě)的內(nèi)容,所以,mem[4]為ad(十六進(jìn)制)即二進(jìn)制10101101VCD文件(valuechangedump文件)是常用的波形記錄文件,與波形的作用等同,是一個(gè)ASCII文件。包含設(shè)計(jì)中指定變量取值變化的信息。它的主要目的是為其它后處理工具提供信息。dump系統(tǒng)任務(wù)基本都在initial模塊中使用下面的系統(tǒng)任務(wù)用于創(chuàng)建和將信息導(dǎo)入VCD文件。1)$dumpfile:本系統(tǒng)任務(wù)指定轉(zhuǎn)儲(chǔ)文件名。例如:$dumpfile(“uart.dump”);2)$dumpvars:本系統(tǒng)任務(wù)指定哪些變量值變化時(shí)轉(zhuǎn)儲(chǔ)進(jìn)轉(zhuǎn)儲(chǔ)文件。$dumpvars;//無(wú)參數(shù),它指定在設(shè)計(jì)中轉(zhuǎn)儲(chǔ)所有變量。$dumpvars(level,module_name);//在指定模塊和所有指定層次下面的模塊中的轉(zhuǎn)儲(chǔ)變量。$dumpvars(1,UART);//只轉(zhuǎn)儲(chǔ)模塊UART中的變量。$dumpvars(2,UART);//轉(zhuǎn)儲(chǔ)UART及其下一層模塊中的所有變量。$dumpvars(0,UART);//第0層導(dǎo)致UART模塊及其下面層次中所有模塊中的各個(gè)變量被轉(zhuǎn)儲(chǔ)。$dumpvars(0,P_State,N_State);//轉(zhuǎn)儲(chǔ)關(guān)于P_State和N_State的變量信息。層次數(shù)與此例無(wú)關(guān),但是必須給出//層次數(shù)。$dumpvars(3,Div.Clk,UART);//層次數(shù)只作用于模塊本身及其下面兩個(gè)層次中的所有變量。在此例中,只作用于模塊UART,即UART中所有變量及UART下面兩個(gè)層次中各模塊的所有變量,同時(shí)轉(zhuǎn)儲(chǔ)變量Div.Clk上值的變化。3)$dumpoff:本系統(tǒng)任務(wù)促使轉(zhuǎn)儲(chǔ)任務(wù)被掛起。$dumpoff;4)$dumpon:本系統(tǒng)任務(wù)促使所有轉(zhuǎn)儲(chǔ)任務(wù)被掛起。語(yǔ)法如下:$dumpon;5)$dumpall:本系統(tǒng)任務(wù)執(zhí)行時(shí)轉(zhuǎn)儲(chǔ)所有當(dāng)前指定的變量值。語(yǔ)法如下:$dumpall6)$dumplimit:本系統(tǒng)任務(wù)為VCD文件指定最大長(zhǎng)度(字節(jié))。轉(zhuǎn)儲(chǔ)在到達(dá)此界限時(shí)停止。例如,$dumplimit(1024);//VCD文件的最大值為1024字節(jié)。7)$dumpflush:本系統(tǒng)任務(wù)刷新操作系統(tǒng)VCD文件緩沖區(qū)中的數(shù)據(jù),將數(shù)據(jù)存到VCD文件中。執(zhí)行此系統(tǒng)任務(wù)后,轉(zhuǎn)儲(chǔ)任務(wù)處于喚醒狀態(tài)。$dumpflush;?文件頭信息:提供日期、模擬器版本和時(shí)間標(biāo)度單位。?節(jié)點(diǎn)信息:定義轉(zhuǎn)儲(chǔ)作用域和變量類型。?取值變化:實(shí)際取值隨時(shí)間變化。記錄絕對(duì)模擬時(shí)間。下面是在5~12之間計(jì)數(shù)的可逆計(jì)數(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當(dāng)進(jìn)行模塊測(cè)試時(shí),常需要提供隨機(jī)脈沖序列,該功能可以通過(guò)系統(tǒng)函數(shù)$random來(lái)實(shí)現(xiàn),它的語(yǔ)法格式為$random%<number>;其中,<number>為一大于0的整數(shù),用來(lái)指定所產(chǎn)生隨機(jī)數(shù)的范圍,即-<number>+1到<number>-1。這個(gè)系統(tǒng)函數(shù)提供了一個(gè)產(chǎn)生隨機(jī)數(shù)的手段。當(dāng)函數(shù)被調(diào)用時(shí)返回一個(gè)32bit的隨機(jī)數(shù)。reg[23:0]rand;rand=$random%60;上面的例子給出了一個(gè)范圍在-59到59之間的隨機(jī)數(shù),下面的例子通過(guò)位并接操作產(chǎn)生一個(gè)值在0到59之間的數(shù)。reg[23:0]rand;rand={$random}%60;“編譯預(yù)處理”是VerilogHDL編譯系統(tǒng)的一個(gè)組成部分。VerilogHDL語(yǔ)言允許在程序中使用幾種特殊的命令(它們不是一般的語(yǔ)句)。VerilogHDL編譯系統(tǒng)通常先對(duì)這些特殊的命令進(jìn)行“預(yù)處理”,然后將預(yù)處理的結(jié)果和源程序一起在進(jìn)行通常的編譯處理。與C語(yǔ)言中的編譯預(yù)處理指令類似,VerilogHDL中提供了大量的編譯指令。通過(guò)這些編譯指令,EDA工具開(kāi)發(fā)商使他們的工具解釋VerilogHDL模型變得相當(dāng)容易。(1)編譯指令以字符“`”開(kāi)頭。

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

(3)編譯指令不受模塊與文件的限制。在進(jìn)行Verilog語(yǔ)言編譯時(shí),已定義的編譯指令一直有效,直到有其它的編譯指令修改它或?qū)⒃摼幾g指令關(guān)閉VerilogHDL中文件包含指令`include類似于C語(yǔ)言中的編譯指令#include?,文件包含指令在模塊調(diào)用時(shí)非常有用,可以通過(guò)該指令包含諸如類型聲明與函數(shù)之類的Verilog碼把語(yǔ)句中指定的源文件全部包含到當(dāng)前的文件中形式定義:`include“文件名”幾點(diǎn)說(shuō)明:1.每條`include語(yǔ)句只能用于對(duì)一個(gè)文件的包含,多個(gè)文件的包含只需用多條語(yǔ)句分別注明即可。2.文件包含允許嵌套。3.`include命令可以出現(xiàn)在VerilogHDL源程序的任何地方,被包含文件名可以是相對(duì)路徑名,也可以是絕對(duì)路徑名。例如:'include"parts/count.v“4可以將多個(gè)`include命令寫(xiě)在一行,在`include命令行,只可以出空格和注釋行。例如下面的寫(xiě)法是合法的。'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用一個(gè)指定的標(biāo)識(shí)符來(lái)代表一個(gè)字符串,它的一般形式為:`define標(biāo)識(shí)符(宏名)字符串(宏內(nèi)容)如:`definesignalstring它的作用是指定用標(biāo)識(shí)符signal來(lái)代替string這個(gè)字符串,在編譯預(yù)處理時(shí),把程序中在該命令以后所有的signal都替換成string。這種方法使用戶能以一個(gè)簡(jiǎn)單的名字代替一個(gè)長(zhǎng)的字符串,也可以用一個(gè)有含義的名字來(lái)代替沒(méi)有含義的數(shù)字和符號(hào),因此把這個(gè)標(biāo)識(shí)符(名字)稱為“宏名”,在編譯預(yù)處理時(shí)將宏名替換成字符串的過(guò)程稱為“宏展開(kāi)”。`define是宏定義命令。這里需要注意的是,文本內(nèi)容必須在一行中定義,不能采用多行。宏替換指令與參數(shù)定義的區(qū)別在于,參數(shù)具有全局可見(jiàn)性,而宏替換指令只局限于宏函數(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指令來(lái)取消宏定義。1宏名可以用大寫(xiě)字母表示,也可以用小寫(xiě)字母表示。建議使用大寫(xiě)字母,以與變量名相區(qū)別。2`define命令可以出現(xiàn)在模塊定義里面,也可以出現(xiàn)在模塊定義外面。宏名的有效范圍為定義命令之后到原文件結(jié)束。通常,`define命令寫(xiě)在模塊定義的外面,作為程序的一部分,在此程序內(nèi)有效。3在引用已定義的宏名時(shí),必須在宏名的前面加上符號(hào)“`”,表示該名字是一個(gè)經(jīng)過(guò)宏定義的名字。4宏定義是用宏名代替一個(gè)字符串,也就是作簡(jiǎn)單的置換,不作語(yǔ)法檢查。預(yù)處理時(shí)照樣代入,不管含義是否正確。只有在編譯已被宏展開(kāi)后的源程序時(shí)才報(bào)錯(cuò)5使用宏名代替一個(gè)字符串,可以減少程序中重復(fù)書(shū)寫(xiě)某些字符串的工作量。而且記住一個(gè)宏名要比記住一個(gè)無(wú)規(guī)律的字符串容易,這樣在讀程序時(shí)能立即知道它的含義,當(dāng)需要改變某一個(gè)變量時(shí),可以只改變`define命令行,一改全改。如例1中,先定義WORDSIZE代表常量8,這時(shí)寄存器data是一個(gè)8位的寄存器。如果需要改變寄存器的大小,只需把該命令行改為:`defineWORDSIZE16。這樣寄存器data則變?yōu)橐粋€(gè)16位的寄存器。由此可見(jiàn)使用宏定義,可以提高程序的可植性和可讀性。6宏定義不是VerilogHDL語(yǔ)句,不必在行末加分號(hào)。如果加了分號(hào)會(huì)連分號(hào)一起進(jìn)行置換。

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

溫馨提示

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

評(píng)論

0/150

提交評(píng)論