日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

对任务和函数的改进

發布時間:2023/12/15 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对任务和函数的改进 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對任務和函數的改進

1、任務和函數的隱式語句組
SystemVerilog會推斷出begin…end
SystemVerilog簡化了任務和函數的定義,有多條語句時不在需要begin …end對多條語句進行打包。打包省略之后,任務或函數中的語句將會順序執行,就像仍然在begin…end中一樣。

function states_t NextState(State_t State);NextState = State;//默認次態case(State)WAITE:if(start) NextState = LOAD;LOAD:if(done) NextState = STORE;STORE: NextState = WAITE;endcase endfunction

2、返回函數值
函數會創建一個與其名稱和類型一樣的隱含變量
SystemVerilog增加一條return語句,和C語言一樣,函數可以像C語言中一樣,使用return語句返回數值。

function int add_and_inc(input int a,b)return a+b+1; endfunction

return語句的優先級高于返回函數名的值
如果執行return語句就會返回一個值。如果函數執行到最后也沒有遇到return語句,那么與Verilog一樣,最后賦給函數名變量的值就是函數的返回值。即使使用了return語句,函數名仍然是一個變量,可以執行return語句之前當作臨時內存使用。

funciton int add_and_inc(input int a,b);add_and_inc = a + b;return ++ add_and_inc; endfunction

3、在任務和函數結束前返回
return語句可以用來在到達結尾前退出
在SystemVerilog中,使用return語句可以在執行流的任何時刻退出任務或函數,而不需要到達任務或函數的結尾。

function automatic int log2(input int n);if(n <= 1) return 1; //異常中止函數log2 = 0;while(n>1)beginn = n/2;log2++;end endfunction

4、空函數
SystemVerilog增加了一個類似C語言的類型–void。函數可以顯式地聲明為void數據類型,表示函數沒有返回值。空函數的調用方式和任務一樣。但同樣有函數在語法和語義上的限制。例如,函數不能包含任何類型的延遲或事件控制,也不能使用非阻塞賦值語句。空函數的另一個優點是克服了函數不能調用任務,這改善了難以在復雜函數添加編碼結構的缺陷。不管怎樣,函數總可以調用其他函數,調用空函數就可以得到和使用任務相同的結構化編碼風格。
SystemVerilog的另一個改進之處是函數可以有output和inout的形式參數。這樣一來,雖然空函數沒有返回值,仍然可以傳送調用函數所產生的變化。

typedef struct{logic valid;logic [7:0] check;logic [63:0] data; }packet_t;function void fill_packet(input logic [63:0] data_in;output packe_t data_out );data_out.data = data_in;for(int i = 0; i <= 7; i++)data_out.check[i] =^data_in[8*i +:8];data_out.valid = 1;endfunction

在可綜合的模塊中,使用空函數來代替任務
空函數的優勢在于它可以像任務一樣被調用,但必須遵循函數編碼規則,例如函數不能包含事件控制,這樣的限制有助于確保能綜合處正確的結果。
5、使用名稱傳遞任務/函數的參數
SystemVerilog可以通過名稱傳遞變量值
在SystemVerilog中,增加了使用形式參數的名稱而不是順序來傳遞參數值的功能。通過參數名稱傳遞可以用任何順序,而且顯式的傳遞給指定的形式參數。

always@(posedge clock)result <= divide(.denominator(b),.numerator(a));function int divide(input int numerator,denominator);if(denominator == 0)beginif(denominator == 0)begin$display("Error!divide by zero");return 0;endendelsereturn = numerator / demoinator;endfunction

參數名稱傳遞可以減少錯誤
使用參數名稱傳遞的方式消除了原先那個數組應該傳給那個參數的不確定性。任務或函數的調用代碼明確地指明了設計的意圖,而且減少了那些由于疏忽造成的不易察覺和調試的設計錯誤。
6、增強型函數形式參數
SystemVerilog的函數有輸入和輸出端口
SystemVerilog允許函數的形式參數像任務一樣,可以聲明為input、output和inout。函數可以有任意個輸出以及函數返回值,這極大地擴展了函數的建模范圍。

//SystemVerilog風格的函數形式參數 function [63:0] add(input [63:0] a,boutput overflow); {overflow,add} = a +b; endfunction

對有輸出的函數的調用限制
為了防止出現不合要求的以及不可綜合的邊緣效應,SystemVerilog對何處能調用有output或inout參數的函數進行了一定的限制。有輸出或輸入輸出參數的函數不能在一下幾種情況中調用:

  • 事件表達式
  • 使用過程持續賦值的表達式
  • 不在過程語句內的表達式

7、無形式參數的函數
SystemVerilog的函數可以沒有參數
8、形式參數的缺省方向和類型
缺省的形式參數方向是輸入
SystemVerilog簡化了任務和函數聲明的語法,形式參數的缺省方向為input。也就說,如果沒有聲明形式參數方向,所有參數假定是輸入的。一旦聲明了一個方向,后面的參數為聲明的方向。

function int compare(int a,b); ... endfunciton //a,b是輸入,y1,y2是輸出 task mytask(a,b,output y1,y2); ... endtask

缺省的形式參數類型是logic
9、缺省的形式參數值
SystemVerilog允許任務與函數為每個形式參數定義一個可選的缺省值。設定缺省值的語法與設置變量的初始值的語法類似。

形式參數count的缺省值是0,形式參數step的缺省值是1function int incrementer(int count = 0,step = 1);incrementer = count + step; endfunction

調用任務或函數時可以對一些參數不指定
當調用任務或函數時,不一定非得給有缺省值的參數傳遞參數值。如果沒有給這種參數傳遞任何值,則在任務或函數調用時使用缺省值。

函數incrementer在調用時只給了一個值, 這個值會傳遞給函數的第一個形式參數。 而第二個形式參數step,會使用缺省值1always@(posedge clock)result = incrementer(data_bus);

缺省的形式參數值允許任務或函數調用時只傳遞與該次調用相關的參數
SystemVerilog允許任務或函數的參數表達式數目小于形式的參數數目。
如果在調用中,沒有給任務或函數的參數傳遞數值,則該參數的形式定義中必須有一個缺省值。如果存在一個沒有缺省值,也沒有傳遞值的形式參數,系統就會報告一個錯誤。
10、數組、結構體和聯合體作為形式參數
形式參數可以是結構體聯合體或數組
SystemVerilog允許非壓縮數組、壓縮或非壓縮結構體和壓縮、非壓縮或標簽聯合體傳遞出/出任務和函數。對于結構體和聯合體,形式參數必須定義為結構體或聯合體類型(用typedef來定義這種類型)。壓縮數組在傳遞給任務或函數時被看做向量。如果調用的壓縮數組參數的寬度與形式參數不匹配,該向量就會按照Verilog向量賦值規則進行截斷或擴展。對于非壓縮數組,傳遞給任務或函數的調用數組參數必須與數組形式參數定義的結構和元素類型精確匹配。為了匹配,調用參數和形式參數必須具有相同的數組維數和維度寬度,并且每個元素有效相同的壓縮寬度。

typedef struct packed{logic valid;logic [7:0] check;logic [63:0] data; }packet_t; function void fill_packed(input logic [7:0] data_in [0:7];//數組參數output packed_t data_out //結構體參數 ); for(int i = 0;i <= 7; i++) begindata_out.data[(8*i) + :8] = data_in[i];data_out.check[i] = ^data_in[i]; enddata_out.valid = 1; endtask

11、用引用取代復制來傳遞參數值
數值通過復制傳遞給任務和函數
當調用任務或函數時,系統會將輸入值復制到任務或函數中于是這些值變為任務或函數的局部數值。當任務或函數執行到末尾返回時,系統再將所有的輸出復制到任務或函數調用程序。
SystemVerilog可以通過引進任務/函數參數進行顯式傳遞
SystemVerilog對自動任務和函數進行擴展,可以使用引用而不是復制的方法傳遞數值。為了通過引用傳遞數值,形式參數用關鍵字ref取代方向關鍵字input,output,或inout進行聲明。ref參數名就成了對傳遞任務或函數的值的實際儲存區進行層次化引進的別名。任務或函數內使用的是局部參數名而非外部信號名。這種引用提供了類似Verilog外部信號引用的能力,但沒有外部信號名必須硬編碼到任務或函數一樣。
ref形式參數是實際值的別名
通過引進傳遞,變量只需要在調用部分聲明,而不需要在任務或函數描述時再次聲明。這樣,任務或函數只在它調用的范圍內引用這個變量。引用不傳遞到任務或函數內的信號就像對外部信號的引用已經隱含傳遞給任務或函數一樣。

注意:只有自動任務和函數可以具有ref參數

為了具有ref參數,任務或函數必需是自動的。任務或函數可以顯式聲明為自動的,也可以通過為定義為自動的模塊、接口或程序中聲明來推斷為自動的。

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參數ref packed_t data_out //ref參數);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

只讀引用參數
通過引用傳遞的參數為只讀
通過將形式參數聲明為const ref類型,可以將引用形式參數聲明為只允許對引用的對象進行讀操作。這樣可以使任務或函數只能引用調用部分的信息,而禁止任務或函數改動信息的內容。

function automatic void fill_packet(const ref logic[7:0] data_in [0:7];//ref參數ref packed_t data_out //ref參數);...endfunction

任務ref參數對變化敏感
通過引用傳遞的參數允許對變化敏感
ref參數的一個重要特點是任務中的邏輯會對信號在調用程序內發生的變化敏感。對變化的這種敏感對函數ref參數不適用。由于函數必需零延時執行,函數不能包含對參數變化敏感的時間控制。

typedef struct packed{logic valid;logic [7:0] check;logic [63:0] data; }packet_t; packet_t send_packet,receive_packed;task automatic check_results(input packet_t sent,ref packet_t received,ref logic done );static int error_count;wait(done)if(sent !== receive)beginerror_count++;$display("ERROR! receive bad packet");end endtask

ref參數可以讀取當前值
ref參數可以立即傳播變化
如果任務的輸出通過復制來傳遞,需等到任務退出時才會將輸出值復制回調用模塊,假如在任務的輸出參數值發生變化時間和任務退出的時間之間存在時序控制或者事件控制,調用程序只能在任務退出時才能看到變量的這個變化,而不能在其發生變化時立即察覺。
如果任務的輸出通過引用來傳遞,任務將對調用模塊中變量直接賦值。因此調用模塊中對這個變量敏感的事件控制都會第一時間檢測到變化,而不是要等到任務執行完將輸出參數復制回調用模塊時。
對使用ref參數進行函數調用的限制
帶有ref形式參數的函數可以修改函數外部變量的值,因此與帶有輸出參數的函數有相同的使用限制。有output、inout或ref參數的函數不能被以下幾種情況調用:

  • 事件表達式
  • 持續賦值中的表達式
  • 過程持續賦值內的表達式
  • 不在過程語句內的表達式

命名的任務和函數結尾
SystemVerilog允許用關鍵字endtask和endfunction指定名稱。

endtask:<task_name> endfunciton:<funciton_name>

冒號前后的空格可以省略。結尾處指定的名稱必須與對應的任務或函數的名稱一致。

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_results

13、空任務和函數
任務或函數可以為空
SystemVerilog允許任務和函數完全為空,即不包含任何語句或語句組。空函數將返回表示函數名的隱含變量的當前值。
空任務和空函數在非完整的代碼中預留出了空間。對于自頂向下的設計流程而言,可以在模塊的描述中創建空任務和函數作為模型文件,而在后面的設計步驟中逐步將其內容添加完整。

總結

以上是生活随笔為你收集整理的对任务和函数的改进的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。