UVM學習之路(6)— QuestaSim的調試方法
一、前言
在使用仿真器的過程中會涉及到庫視窗、仿真視窗和過程視窗,他們将與硬體、模型 和線上運作的程序一一對應。
二、庫視窗
所有編譯成功的硬體(module、interface、program)和軟體(class、package)都可以被放入庫中,如果不指定放入的位置,他們會被放入預設的work庫中。如下所示,是QuestaSim的庫視窗;

三、仿真視窗
仿真視窗(sim window)代表目前正在進行的仿真結構,一般在驗證環境中,應該包含硬體測試的結構元件和待測設計(DUT)。如下所示,是QuestaSim的仿真(sim)視窗,我們可以看到除了有我們自己編寫後被編譯出來的庫,還有被預設引入的标準庫;
不過需要注意的是,仿真視窗隻能提供靜态的 層次結構,即由module、program、interface和package的内容,但是對于class的例化執行個體這種在驗證環境中十分重要的動态軟體内容,則需要在類視窗(class window)和對象視窗(object window)中檢視。
四、過程視窗
過程視窗(process window)代表着整個仿真在某一個時間點上所有過程語句塊(initial、always、assign)的狀态。如下所示,是QuestaSim的過程視窗;
如果狀态為
active
,代表該程序塊正在執行,如果是
ready
狀态,代表該程序塊是非活躍狀态。
五、檢視信号和波形
我們在啟動仿真後仿真器會自動打開波形(Wave)視窗,如下所示
然後我們就可以在仿真視窗或者信号視窗(objects window)中選中需要的信号添加到波形視窗處,如下所示,選中要添加的波形,右鍵點選【Add Wave】即可
這樣我們點選運作後即可在Wave視窗中看到波形了
另外,在指令視窗(transcript window)使用指令
log -r/*
在開始仿真前調用,可以確定TB層次下所有信号都可以儲存到資料庫以供檢視任何信号的波形。
六、測量時鐘
在Wave視窗中點選綠色+号的【Insert cursor】圖示,添加一個時間軸
然後我們移動時間軸,可以看到兩個時間軸之間的時間間隔
接着格式設定圖示,
将【Show frequency in cursor delta】勾選上
我們就可以看到,之前的時間間隔變成了頻率格式
七、設定斷點
設定斷點可以便于檢視軟體程式(function、task、object)中局部變量的數值。因為軟體部分的變量(即動态變量dynamic variable)是無法添加到波形視窗的,是以軟體部分的變量我們需要通過設定斷點的方法來檢視。編寫代碼如下所示
module breakpoint1;
int val1;
int val2;
int result;
function int incr_static(input int a);
result = a + 1;
return result;
endfunction
function automatic int incr_dynamic(input int a);
int result;
result = a + 1;
return result;
endfunction
initial begin
val1 = 0;
val1 = incr_static(val1);
val1 = incr_static(val1); // breakpoint line8 result == ?
end
initial begin
val2 = 0;
val2 = incr_dynamic(val2);
val2 = incr_dynamic(val2); // breakpoint line14 result == ?
end
endmodule
編譯仿真運作,然後在仿真視窗輕按兩下子產品名稱
我們就可以看到代碼視窗打開了,并在子產品聲明行出現了 一個小旗子
接着在代碼視窗左邊的行号上點選一下即可設定一個斷點了
然後我們點選【Run -All】圖示,或者輸入
run -all
指令,讓代碼運作到14行斷點處
然後我們可以在【Locals】視窗中看到動态變量的值
八、強制修改信号
編寫代碼如下所示,
module simstart1;
logic a1=0;
logic a2, a3, a4, a5;
bit rstn, clk;
assign a2 = a1; // assign
initial begin // initial
a3 = a1;
end
always @(posedge clk, negedge rstn) begin // sequential logic
if(rstn === 'b0) a4 <= 0;
else a4 <= a1;
end
always @(a1) begin // combination logic
a5 <= a1;
end
initial begin
#10ns rstn <= 0;
#20ns rstn <= 1;
end
initial forever #5ns clk <= !clk;
endmodule
在第19行設定斷點,仿真運作100ns,會發現我們無法運作到斷點處,這是因為仿真過程中a1的值一直沒有改變
我們在【Objects】視窗中選中
a1
,右鍵選擇【Modify】->【Force…】以強行修改a1的值
編輯如下所示,将要修改為的值輸入
1'h1
,延時等待時間輸入
10ns
,點選OK儲存
然後輸入指令
run 20ns
運作20ns,可以看到,在10ns時運作到斷點處停下來了
但是此時
a5
并沒有變化
我們在輸入
run 0
指令讓仿真再運作一個時間片,可以看到,a5的值 已經變成
1'h1
了,然後運作箭頭也離開了19行