cocotb的出現使得我們能夠在做RTL仿真驗證時依托Python來進行測試用例的構建,當我們習慣了用Verilog、SystemVerilog來構建測試用例時,切換到cocotb后最直觀的方式便是我們能夠建立cocotb中的基礎語法與SystemVerilog中仿真常用的關鍵字又一個對應,能夠使我們又一個初步的對照。本篇就cocotb中的基礎語法與SystemVerilog中的常用語法做一個對照總結。
非阻塞賦值
在使用Systemverilog進行仿真時,對于接口信號,往往建議采用非阻塞賦值進行操作,其符號為“<=”.
在cocotb中,對于信號的賦值,其提供相應的非阻塞賦值方式,其符號也同樣為“<=”。
在cocotb的手冊里提到:
The syntaxsig<=?new_value?is a short form of?sig.value?=?new_value. It not only resembles HDL syntax, but also has the same semantics: writes are not applied immediately, but delayed until the next write cycle.
因而我們可以在cocotb中這樣來進行非阻塞賦值:
# Get a reference to the "clk" signal and assign a valueclk = dut.clkclk.value = 1 # Direct assignment through the hierarchydut.input_signal <= 12 # Assign a value to a memory deep in the hierarchydut.sub_block.memory.array[4] <= 2
阻塞賦值
針對阻塞賦值(立即生效),cocotb提供了相應的語法:
setimmediatevalue(value)
因而對于阻塞賦值,我們在cocotb中可以這樣寫:
dut.input_signal.setimmediatevalue(1)
信號值讀取
對于信號的讀取,我們在SystemVerilog中,可以直接讀取信號值,而在cocotb中,其為接口變量提供了value方法屬性用于獲取信號值。
讀取方式:sig.value
返回類型:BinaryValue
Accessing thevalueproperty of a handle object will return aBinaryValueobject. Any unresolved bits are preserved and can be accessed using thebinstrattribute, or a resolved integer value can be accessed using theintegerattribute.
信號的讀取我們可以這么來寫:
#Time
在仿真里延遲等待是經常遇到的,在cocotb里,我們通過Timer來實現延遲:
cocotb.triggers.Timer(time_ps,units=None)
Parameters
time_ps (numbers.Real or decimal.Decimal) – The time value. Note that despite the name this is not actually in picoseconds but depends on the units argument.
units (str or None, optional) – One of None, 'fs', 'ps', 'ns', 'us', 'ms', 'sec'. When no units is given (None) the timestep is determined by the simulator.
由于cocotb是基于協程的,而延遲函數的執行的時間長度是依賴于仿真器的,因此Timer延遲的執行需調用await:
await Timer(1, units='ns')
邊沿檢測
在SystemVerilog中我們常用posedge、negedge來檢測上升沿和下降沿,在cocotb里,針對邊沿檢測,其提供了四個調用:
等待調變
class cocotb.triggers.Edge(*args, **kwargs)
Fires on any value change of signal.
等待上升沿
class cocotb.triggers.RisingEdge(*args, **kwargs)
Fires on the rising edge of signal, on a transition from 0 to 1.
等待下降沿
class cocotb.triggers.FallingEdge(*args, **kwargs)
Fires on the falling edge of signal, on a transition from 1 to 0.
檢測等待指定到個數邊沿
class cocotb.triggers.ClockCycles(signal,num_cycles,rising=True)
Fires after num_cycles transitions of signal from 0 to 1.
Parameters
signal – The signal to monitor.
num_cycles (int) – The number of cycles to count.
rising (bool, optional) – If True, the default, count rising edges. Otherwise, count falling edges.
我們在使用時,可以這么來寫:
fork-join_none
SystemVerilog中的fork-join_none用于發起一個線程但不等待線程的結束,在cocotb中,相應的語法為fork:
cocotb.fork()
Schedule a coroutine to be run concurrently
在寫仿真代碼時,我們可以這么寫:
這里值得注意的是,由于fork是起一個協程,因而resut_dut需添加async聲明。
fork-join
與SystemVerilog中相對應的,cocotb等待一個協程的結束同樣提供了join方法:
class cocotb.triggers.Join(*args, **kwargs)
Fires when a fork()ed coroutine completes.
The result of blocking on the trigger can be used to get the coroutine result:
使用方式:
fork-any
相較于SystemVerilog中的join-any語法,cocotb并無專門的對應語法,但卻有相似的方法供調用:
class cocotb.triggers.First(*triggers)
等待第一個協程結束即返回
這里我們通過First等待t1、t2第一個返回的結果后await結束,并將第一個返回的協程的返回結果賦值給t_ret。
event
對于SystemVerilog中的event,在cocotb中同樣提供類似的event:
class cocotb.triggers.Event(name=None)
用于兩個協程間的同步
方法:
set(data=None):喚醒所有等待該事件的協程
wait(): 等待事件的出發(await),如果事件已經觸發,立即返回
clear(): 清楚以觸發的事件
is_set():判斷事件是否觸發
旗語
cocotb中提供了Lock操作用來實現與SystemVerilog中相似的操作,不過Lock不可聲明旗語為多個:
class cocotb.triggers.Lock(name=None)
方法:
locked : True if the lock is held.
acquire():Produce a trigger which fires when the lock is acquired.
release(): Release the lock.
mailbox
SystemVerilog中的mailbox主要用于不同進程間的通信,在cocotb中,普通的Python的隊列即可實現該功能(協程中無需沒有進程間同步問題)。
審核編輯就:劉清
-
仿真器
+關注
關注
14文章
1016瀏覽量
83649 -
RTL
+關注
關注
1文章
385瀏覽量
59710 -
python
+關注
關注
56文章
4783瀏覽量
84474
發布評論請先 登錄
相關推薦
評論