对任务和函数的改进
對任務(wù)和函數(shù)的改進
1、任務(wù)和函數(shù)的隱式語句組
SystemVerilog會推斷出begin…end
SystemVerilog簡化了任務(wù)和函數(shù)的定義,有多條語句時不在需要begin …end對多條語句進行打包。打包省略之后,任務(wù)或函數(shù)中的語句將會順序執(zhí)行,就像仍然在begin…end中一樣。
2、返回函數(shù)值
函數(shù)會創(chuàng)建一個與其名稱和類型一樣的隱含變量
SystemVerilog增加一條return語句,和C語言一樣,函數(shù)可以像C語言中一樣,使用return語句返回數(shù)值。
return語句的優(yōu)先級高于返回函數(shù)名的值
如果執(zhí)行return語句就會返回一個值。如果函數(shù)執(zhí)行到最后也沒有遇到return語句,那么與Verilog一樣,最后賦給函數(shù)名變量的值就是函數(shù)的返回值。即使使用了return語句,函數(shù)名仍然是一個變量,可以執(zhí)行return語句之前當作臨時內(nèi)存使用。
3、在任務(wù)和函數(shù)結(jié)束前返回
return語句可以用來在到達結(jié)尾前退出
在SystemVerilog中,使用return語句可以在執(zhí)行流的任何時刻退出任務(wù)或函數(shù),而不需要到達任務(wù)或函數(shù)的結(jié)尾。
4、空函數(shù)
SystemVerilog增加了一個類似C語言的類型–void。函數(shù)可以顯式地聲明為void數(shù)據(jù)類型,表示函數(shù)沒有返回值。空函數(shù)的調(diào)用方式和任務(wù)一樣。但同樣有函數(shù)在語法和語義上的限制。例如,函數(shù)不能包含任何類型的延遲或事件控制,也不能使用非阻塞賦值語句。空函數(shù)的另一個優(yōu)點是克服了函數(shù)不能調(diào)用任務(wù),這改善了難以在復(fù)雜函數(shù)添加編碼結(jié)構(gòu)的缺陷。不管怎樣,函數(shù)總可以調(diào)用其他函數(shù),調(diào)用空函數(shù)就可以得到和使用任務(wù)相同的結(jié)構(gòu)化編碼風格。
SystemVerilog的另一個改進之處是函數(shù)可以有output和inout的形式參數(shù)。這樣一來,雖然空函數(shù)沒有返回值,仍然可以傳送調(diào)用函數(shù)所產(chǎn)生的變化。
在可綜合的模塊中,使用空函數(shù)來代替任務(wù)
空函數(shù)的優(yōu)勢在于它可以像任務(wù)一樣被調(diào)用,但必須遵循函數(shù)編碼規(guī)則,例如函數(shù)不能包含事件控制,這樣的限制有助于確保能綜合處正確的結(jié)果。
5、使用名稱傳遞任務(wù)/函數(shù)的參數(shù)
SystemVerilog可以通過名稱傳遞變量值
在SystemVerilog中,增加了使用形式參數(shù)的名稱而不是順序來傳遞參數(shù)值的功能。通過參數(shù)名稱傳遞可以用任何順序,而且顯式的傳遞給指定的形式參數(shù)。
參數(shù)名稱傳遞可以減少錯誤
使用參數(shù)名稱傳遞的方式消除了原先那個數(shù)組應(yīng)該傳給那個參數(shù)的不確定性。任務(wù)或函數(shù)的調(diào)用代碼明確地指明了設(shè)計的意圖,而且減少了那些由于疏忽造成的不易察覺和調(diào)試的設(shè)計錯誤。
6、增強型函數(shù)形式參數(shù)
SystemVerilog的函數(shù)有輸入和輸出端口
SystemVerilog允許函數(shù)的形式參數(shù)像任務(wù)一樣,可以聲明為input、output和inout。函數(shù)可以有任意個輸出以及函數(shù)返回值,這極大地擴展了函數(shù)的建模范圍。
對有輸出的函數(shù)的調(diào)用限制
為了防止出現(xiàn)不合要求的以及不可綜合的邊緣效應(yīng),SystemVerilog對何處能調(diào)用有output或inout參數(shù)的函數(shù)進行了一定的限制。有輸出或輸入輸出參數(shù)的函數(shù)不能在一下幾種情況中調(diào)用:
- 事件表達式
- 使用過程持續(xù)賦值的表達式
- 不在過程語句內(nèi)的表達式
7、無形式參數(shù)的函數(shù)
SystemVerilog的函數(shù)可以沒有參數(shù)
8、形式參數(shù)的缺省方向和類型
缺省的形式參數(shù)方向是輸入
SystemVerilog簡化了任務(wù)和函數(shù)聲明的語法,形式參數(shù)的缺省方向為input。也就說,如果沒有聲明形式參數(shù)方向,所有參數(shù)假定是輸入的。一旦聲明了一個方向,后面的參數(shù)為聲明的方向。
缺省的形式參數(shù)類型是logic
9、缺省的形式參數(shù)值
SystemVerilog允許任務(wù)與函數(shù)為每個形式參數(shù)定義一個可選的缺省值。設(shè)定缺省值的語法與設(shè)置變量的初始值的語法類似。
調(diào)用任務(wù)或函數(shù)時可以對一些參數(shù)不指定
當調(diào)用任務(wù)或函數(shù)時,不一定非得給有缺省值的參數(shù)傳遞參數(shù)值。如果沒有給這種參數(shù)傳遞任何值,則在任務(wù)或函數(shù)調(diào)用時使用缺省值。
缺省的形式參數(shù)值允許任務(wù)或函數(shù)調(diào)用時只傳遞與該次調(diào)用相關(guān)的參數(shù)
SystemVerilog允許任務(wù)或函數(shù)的參數(shù)表達式數(shù)目小于形式的參數(shù)數(shù)目。
如果在調(diào)用中,沒有給任務(wù)或函數(shù)的參數(shù)傳遞數(shù)值,則該參數(shù)的形式定義中必須有一個缺省值。如果存在一個沒有缺省值,也沒有傳遞值的形式參數(shù),系統(tǒng)就會報告一個錯誤。
10、數(shù)組、結(jié)構(gòu)體和聯(lián)合體作為形式參數(shù)
形式參數(shù)可以是結(jié)構(gòu)體聯(lián)合體或數(shù)組
SystemVerilog允許非壓縮數(shù)組、壓縮或非壓縮結(jié)構(gòu)體和壓縮、非壓縮或標簽聯(lián)合體傳遞出/出任務(wù)和函數(shù)。對于結(jié)構(gòu)體和聯(lián)合體,形式參數(shù)必須定義為結(jié)構(gòu)體或聯(lián)合體類型(用typedef來定義這種類型)。壓縮數(shù)組在傳遞給任務(wù)或函數(shù)時被看做向量。如果調(diào)用的壓縮數(shù)組參數(shù)的寬度與形式參數(shù)不匹配,該向量就會按照Verilog向量賦值規(guī)則進行截斷或擴展。對于非壓縮數(shù)組,傳遞給任務(wù)或函數(shù)的調(diào)用數(shù)組參數(shù)必須與數(shù)組形式參數(shù)定義的結(jié)構(gòu)和元素類型精確匹配。為了匹配,調(diào)用參數(shù)和形式參數(shù)必須具有相同的數(shù)組維數(shù)和維度寬度,并且每個元素有效相同的壓縮寬度。
11、用引用取代復(fù)制來傳遞參數(shù)值
數(shù)值通過復(fù)制傳遞給任務(wù)和函數(shù)
當調(diào)用任務(wù)或函數(shù)時,系統(tǒng)會將輸入值復(fù)制到任務(wù)或函數(shù)中于是這些值變?yōu)槿蝿?wù)或函數(shù)的局部數(shù)值。當任務(wù)或函數(shù)執(zhí)行到末尾返回時,系統(tǒng)再將所有的輸出復(fù)制到任務(wù)或函數(shù)調(diào)用程序。
SystemVerilog可以通過引進任務(wù)/函數(shù)參數(shù)進行顯式傳遞
SystemVerilog對自動任務(wù)和函數(shù)進行擴展,可以使用引用而不是復(fù)制的方法傳遞數(shù)值。為了通過引用傳遞數(shù)值,形式參數(shù)用關(guān)鍵字ref取代方向關(guān)鍵字input,output,或inout進行聲明。ref參數(shù)名就成了對傳遞任務(wù)或函數(shù)的值的實際儲存區(qū)進行層次化引進的別名。任務(wù)或函數(shù)內(nèi)使用的是局部參數(shù)名而非外部信號名。這種引用提供了類似Verilog外部信號引用的能力,但沒有外部信號名必須硬編碼到任務(wù)或函數(shù)一樣。
ref形式參數(shù)是實際值的別名
通過引進傳遞,變量只需要在調(diào)用部分聲明,而不需要在任務(wù)或函數(shù)描述時再次聲明。這樣,任務(wù)或函數(shù)只在它調(diào)用的范圍內(nèi)引用這個變量。引用不傳遞到任務(wù)或函數(shù)內(nèi)的信號就像對外部信號的引用已經(jīng)隱含傳遞給任務(wù)或函數(shù)一樣。
為了具有ref參數(shù),任務(wù)或函數(shù)必需是自動的。任務(wù)或函數(shù)可以顯式聲明為自動的,也可以通過為定義為自動的模塊、接口或程序中聲明來推斷為自動的。
module chip(...);typedef struct{logic valid;logic [7:0] check;logic [63:0] data}packet_t;packet_t data_packet;bit[7:0] raw_data [0:7];always@(posedge clock)if(data_ready) fill_packet(.data_in(raw_data),.data_out(data_packet));function automatic void fill_packet(ref logic[7:0] data_in [0:7];//ref參數(shù)ref packed_t data_out //ref參數(shù));for(int i = 0;i <= 7;i++)begindata_out.data[(8*i)+:8]=data_in[i];data_out.check[i] = ^data_in[i];end endfunction ... endmodule只讀引用參數(shù)
通過引用傳遞的參數(shù)為只讀
通過將形式參數(shù)聲明為const ref類型,可以將引用形式參數(shù)聲明為只允許對引用的對象進行讀操作。這樣可以使任務(wù)或函數(shù)只能引用調(diào)用部分的信息,而禁止任務(wù)或函數(shù)改動信息的內(nèi)容。
任務(wù)ref參數(shù)對變化敏感
通過引用傳遞的參數(shù)允許對變化敏感
ref參數(shù)的一個重要特點是任務(wù)中的邏輯會對信號在調(diào)用程序內(nèi)發(fā)生的變化敏感。對變化的這種敏感對函數(shù)ref參數(shù)不適用。由于函數(shù)必需零延時執(zhí)行,函數(shù)不能包含對參數(shù)變化敏感的時間控制。
ref參數(shù)可以讀取當前值
ref參數(shù)可以立即傳播變化
如果任務(wù)的輸出通過復(fù)制來傳遞,需等到任務(wù)退出時才會將輸出值復(fù)制回調(diào)用模塊,假如在任務(wù)的輸出參數(shù)值發(fā)生變化時間和任務(wù)退出的時間之間存在時序控制或者事件控制,調(diào)用程序只能在任務(wù)退出時才能看到變量的這個變化,而不能在其發(fā)生變化時立即察覺。
如果任務(wù)的輸出通過引用來傳遞,任務(wù)將對調(diào)用模塊中變量直接賦值。因此調(diào)用模塊中對這個變量敏感的事件控制都會第一時間檢測到變化,而不是要等到任務(wù)執(zhí)行完將輸出參數(shù)復(fù)制回調(diào)用模塊時。
對使用ref參數(shù)進行函數(shù)調(diào)用的限制
帶有ref形式參數(shù)的函數(shù)可以修改函數(shù)外部變量的值,因此與帶有輸出參數(shù)的函數(shù)有相同的使用限制。有output、inout或ref參數(shù)的函數(shù)不能被以下幾種情況調(diào)用:
- 事件表達式
- 持續(xù)賦值中的表達式
- 過程持續(xù)賦值內(nèi)的表達式
- 不在過程語句內(nèi)的表達式
命名的任務(wù)和函數(shù)結(jié)尾
SystemVerilog允許用關(guān)鍵字endtask和endfunction指定名稱。
冒號前后的空格可以省略。結(jié)尾處指定的名稱必須與對應(yīng)的任務(wù)或函數(shù)的名稱一致。
function int add_and_inc (int a,b);return a+b+1; endfunciton:add_and_incrask autormatic check_result(input packet_t sent,ref packet_t received,ref logic done ); static int error_count; ... endtask:check_results13、空任務(wù)和函數(shù)
任務(wù)或函數(shù)可以為空
SystemVerilog允許任務(wù)和函數(shù)完全為空,即不包含任何語句或語句組。空函數(shù)將返回表示函數(shù)名的隱含變量的當前值。
空任務(wù)和空函數(shù)在非完整的代碼中預(yù)留出了空間。對于自頂向下的設(shè)計流程而言,可以在模塊的描述中創(chuàng)建空任務(wù)和函數(shù)作為模型文件,而在后面的設(shè)計步驟中逐步將其內(nèi)容添加完整。
總結(jié)