任務(task)可以用來描述共同的代碼段,并在模塊內任意位置被調用,讓代碼更加的直觀易讀。task 更像一個過程,過程內一般按順序執行,完成各種邏輯控制。
調試 testbench 中的 task 時,新手可能會遇到一些問題。典型的問題有兩個,一個是 task 內部聲明使用的變量為什么不能在 Verdi 波形中查看,另一個是 task 輸出端連接的信號為什么不隨 task 內部賦值變量的變化而變化。本節將對這兩個問題進行講解說明。
Verdi 查看 task 內部變量
創建一個簡單的 task,包含內部變量 reg 和 output,如下所示。
//varialbes in task
task reg_in_task ;
output [7:0] data_test1 ;
reg [7:0] data_test2 ;
begin
#100 ;
data_test1 = 8'h13 ;
data_test2 = 8'h24 ;
#100 ;
data_test1 = 8'h1a ;
data_test2 = 8'h2b ;
end
endtask
在 testbench 的 initial 語句中調用該task,并定義變量 data_test1_t,連接到該 task 輸出端,如下所示。
`timescale 1ns/1ps
module test ;
......
reg [7:0] data_test1_t ;
initial begin
reg_in_task(data_test1_t) ;
end
endmodule
./simv -ucli -i wave_gen.tcl -l sim.log
打開 Verdi 和 fsdb 波形文件,添加 task 內部的變量 data_test1 和輸出端 data_test2 時,會提示相關信號無法找到。
為解決上述問題,使用 simv 進行仿真時需要添加特殊選項 +fsdb+functions,如下所示。
./simv +fsdb+functions -ucli -i wave_gen.tcl -l sim.log
此時再在 Verdi 中添加 task 內部的變量 data_test2 和輸出端 data_test1,其變化過程會在波形上顯示,如下所示。
◆ 小結:VCS 仿真時,需要在 simv 仿真時添加 fsdb+functions 參數,才可在 Verdi 中打開 fsdb 波形并查看 task 內部變量的變化情況。
TASK 操作全局變量
上述仿真波形中,細心的讀者可能會看到,雖然連線信號 data_test1_t 連接的是 task 輸出端,但是 data_test1_t 并不隨 task 輸出端的變化而變化。
這是因為 testbench 中的代碼一般是順序執行,并沒有對應的實際硬件結構。所以 task 輸出端連接的對應信號不可以理解為連續賦值,而是理解為一個返回值。即 task 執行完畢時,只返回輸出端連接的信號一個最終結果。所以,data_test1_t 只會在 task 結束時 (對應200ns) 被賦值為 8'h1a,并不會體現中間的變化過程。
如果一個信號在 task 中的變化能夠體現在 task 外部,則該信號需要定義為全局變量。即信號需要定義在 task 外部,但是在 task 內部中驅動。
上述示例中,刪除輸出端 data_test1,并在 task 中直接對全局變量 data_test1_t 進行賦值驅動。
`timescale 1ns/1ps
module test ;
reg [7:0] data_test1_t
//varialbes in task
task reg_in_task ;
reg [7:0] data_test2 ;
begin
#100 ;
data_test1_t = 8'h13 ;
data_test2 = 8'h24 ;
#100 ;
data_test1_t = 8'h1a ;
data_test2 = 8'h2b ;
end
endtask
initial begin
reg_in_task ;
end
endmodule
仿真結果如下。此時全局變量 data_test1_t 的變化過程并不局限于 task 內部。
testbench 不用“Think In Hardware”,寫法比較自由。在多個 task 中對同一個全局變量信號進行多驅動也是沒有問題的,只要時間軸上分開驅動事件的先后順序即可。
上述示例中再增加一個 task ,用以驅動全局信號 data_test1_t,則代碼和仿真結果如下。這里不再分析。
task task_mult_drive ;
begin
#150 ;
data_test1_t = 8'hc8 ;
end
endtask
initial begin
task_mult_drive ;
end
小結:task 執行完畢時,只返回輸出端連接的信號一個最終結果。如果 task 中信號的變化過程能夠在 task 外部實時體現,則該信號也需要定義在 task 外部。
-
模塊
+關注
關注
7文章
2695瀏覽量
47433 -
信號
+關注
關注
11文章
2790瀏覽量
76731 -
代碼
+關注
關注
30文章
4780瀏覽量
68527 -
Verdi
+關注
關注
0文章
22瀏覽量
8775 -
變量
+關注
關注
0文章
613瀏覽量
28361
發布評論請先 登錄
相關推薦
評論