任務(wù)(task)可以用來(lái)描述共同的代碼段,并在模塊內(nèi)任意位置被調(diào)用,讓代碼更加的直觀易讀。task 更像一個(gè)過(guò)程,過(guò)程內(nèi)一般按順序執(zhí)行,完成各種邏輯控制。
調(diào)試 testbench 中的 task 時(shí),新手可能會(huì)遇到一些問(wèn)題。典型的問(wèn)題有兩個(gè),一個(gè)是 task 內(nèi)部聲明使用的變量為什么不能在 Verdi 波形中查看,另一個(gè)是 task 輸出端連接的信號(hào)為什么不隨 task 內(nèi)部賦值變量的變化而變化。本節(jié)將對(duì)這兩個(gè)問(wèn)題進(jìn)行講解說(shuō)明。
Verdi 查看 task 內(nèi)部變量
創(chuàng)建一個(gè)簡(jiǎn)單的 task,包含內(nèi)部變量 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 語(yǔ)句中調(diào)用該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 進(jìn)行仿真,不用添加特殊選項(xiàng),如下所示。
./simv -ucli -i wave_gen.tcl -l sim.log
打開(kāi) Verdi 和 fsdb 波形文件,添加 task 內(nèi)部的變量 data_test1 和輸出端 data_test2 時(shí),會(huì)提示相關(guān)信號(hào)無(wú)法找到。
為解決上述問(wèn)題,使用 simv 進(jìn)行仿真時(shí)需要添加特殊選項(xiàng) +fsdb+functions,如下所示。
./simv +fsdb+functions -ucli -i wave_gen.tcl -l sim.log
此時(shí)再在 Verdi 中添加 task 內(nèi)部的變量 data_test2 和輸出端 data_test1,其變化過(guò)程會(huì)在波形上顯示,如下所示。
◆ 小結(jié):VCS 仿真時(shí),需要在 simv 仿真時(shí)添加 fsdb+functions 參數(shù),才可在 Verdi 中打開(kāi) fsdb 波形并查看 task 內(nèi)部變量的變化情況。
TASK 操作全局變量
上述仿真波形中,細(xì)心的讀者可能會(huì)看到,雖然連線信號(hào) data_test1_t 連接的是 task 輸出端,但是 data_test1_t 并不隨 task 輸出端的變化而變化。
這是因?yàn)?testbench 中的代碼一般是順序執(zhí)行,并沒(méi)有對(duì)應(yīng)的實(shí)際硬件結(jié)構(gòu)。所以 task 輸出端連接的對(duì)應(yīng)信號(hào)不可以理解為連續(xù)賦值,而是理解為一個(gè)返回值。即 task 執(zhí)行完畢時(shí),只返回輸出端連接的信號(hào)一個(gè)最終結(jié)果。所以,data_test1_t 只會(huì)在 task 結(jié)束時(shí) (對(duì)應(yīng)200ns) 被賦值為 8'h1a,并不會(huì)體現(xiàn)中間的變化過(guò)程。
如果一個(gè)信號(hào)在 task 中的變化能夠體現(xiàn)在 task 外部,則該信號(hào)需要定義為全局變量。即信號(hào)需要定義在 task 外部,但是在 task 內(nèi)部中驅(qū)動(dòng)。
上述示例中,刪除輸出端 data_test1,并在 task 中直接對(duì)全局變量 data_test1_t 進(jìn)行賦值驅(qū)動(dòng)。
`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
仿真結(jié)果如下。此時(shí)全局變量 data_test1_t 的變化過(guò)程并不局限于 task 內(nèi)部。
testbench 不用“Think In Hardware”,寫(xiě)法比較自由。在多個(gè) task 中對(duì)同一個(gè)全局變量信號(hào)進(jìn)行多驅(qū)動(dòng)也是沒(méi)有問(wèn)題的,只要時(shí)間軸上分開(kāi)驅(qū)動(dòng)事件的先后順序即可。
上述示例中再增加一個(gè) task ,用以驅(qū)動(dòng)全局信號(hào) data_test1_t,則代碼和仿真結(jié)果如下。這里不再分析。
task task_mult_drive ;
begin
#150 ;
data_test1_t = 8'hc8 ;
end
endtask
initial begin
task_mult_drive ;
end
小結(jié):task 執(zhí)行完畢時(shí),只返回輸出端連接的信號(hào)一個(gè)最終結(jié)果。如果 task 中信號(hào)的變化過(guò)程能夠在 task 外部實(shí)時(shí)體現(xiàn),則該信號(hào)也需要定義在 task 外部。
-
模塊
+關(guān)注
關(guān)注
7文章
2738瀏覽量
47802 -
信號(hào)
+關(guān)注
關(guān)注
11文章
2809瀏覽量
77167 -
代碼
+關(guān)注
關(guān)注
30文章
4841瀏覽量
69144 -
Verdi
+關(guān)注
關(guān)注
0文章
22瀏覽量
8824 -
變量
+關(guān)注
關(guān)注
0文章
613瀏覽量
28478
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論