cocotb的出現(xiàn)使得我們能夠在做RTL仿真驗(yàn)證時(shí)依托Python來(lái)進(jìn)行測(cè)試用例的構(gòu)建,當(dāng)我們習(xí)慣了用Verilog、SystemVerilog來(lái)構(gòu)建測(cè)試用例時(shí),切換到cocotb后最直觀的方式便是我們能夠建立cocotb中的基礎(chǔ)語(yǔ)法與SystemVerilog中仿真常用的關(guān)鍵字又一個(gè)對(duì)應(yīng),能夠使我們又一個(gè)初步的對(duì)照。本篇就cocotb中的基礎(chǔ)語(yǔ)法與SystemVerilog中的常用語(yǔ)法做一個(gè)對(duì)照總結(jié)。
非阻塞賦值
在使用Systemverilog進(jìn)行仿真時(shí),對(duì)于接口信號(hào),往往建議采用非阻塞賦值進(jìn)行操作,其符號(hào)為“<=”.
在cocotb中,對(duì)于信號(hào)的賦值,其提供相應(yīng)的非阻塞賦值方式,其符號(hào)也同樣為“<=”。
在cocotb的手冊(cè)里提到:
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中這樣來(lái)進(jìn)行非阻塞賦值:
# 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
阻塞賦值
針對(duì)阻塞賦值(立即生效),cocotb提供了相應(yīng)的語(yǔ)法:
setimmediatevalue(value)
因而對(duì)于阻塞賦值,我們?cè)赾ocotb中可以這樣寫(xiě):
dut.input_signal.setimmediatevalue(1)
信號(hào)值讀取
對(duì)于信號(hào)的讀取,我們?cè)赟ystemVerilog中,可以直接讀取信號(hào)值,而在cocotb中,其為接口變量提供了value方法屬性用于獲取信號(hào)值。
讀取方式: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.
信號(hào)的讀取我們可以這么來(lái)寫(xiě):
#Time
在仿真里延遲等待是經(jīng)常遇到的,在cocotb里,我們通過(guò)Timer來(lái)實(shí)現(xiàn)延遲:
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是基于協(xié)程的,而延遲函數(shù)的執(zhí)行的時(shí)間長(zhǎng)度是依賴于仿真器的,因此Timer延遲的執(zhí)行需調(diào)用await:
await Timer(1, units='ns')
邊沿檢測(cè)
在SystemVerilog中我們常用posedge、negedge來(lái)檢測(cè)上升沿和下降沿,在cocotb里,針對(duì)邊沿檢測(cè),其提供了四個(gè)調(diào)用:
等待調(diào)變
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.
檢測(cè)等待指定到個(gè)數(shù)邊沿
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.
我們?cè)谑褂脮r(shí),可以這么來(lái)寫(xiě):
fork-join_none
SystemVerilog中的fork-join_none用于發(fā)起一個(gè)線程但不等待線程的結(jié)束,在cocotb中,相應(yīng)的語(yǔ)法為fork:
cocotb.fork()
Schedule a coroutine to be run concurrently
在寫(xiě)仿真代碼時(shí),我們可以這么寫(xiě):
這里值得注意的是,由于fork是起一個(gè)協(xié)程,因而resut_dut需添加async聲明。
fork-join
與SystemVerilog中相對(duì)應(yīng)的,cocotb等待一個(gè)協(xié)程的結(jié)束同樣提供了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語(yǔ)法,cocotb并無(wú)專門(mén)的對(duì)應(yīng)語(yǔ)法,但卻有相似的方法供調(diào)用:
class cocotb.triggers.First(*triggers)
等待第一個(gè)協(xié)程結(jié)束即返回
這里我們通過(guò)First等待t1、t2第一個(gè)返回的結(jié)果后await結(jié)束,并將第一個(gè)返回的協(xié)程的返回結(jié)果賦值給t_ret。
event
對(duì)于SystemVerilog中的event,在cocotb中同樣提供類似的event:
class cocotb.triggers.Event(name=None)
用于兩個(gè)協(xié)程間的同步
方法:
set(data=None):?jiǎn)拘阉械却撌录膮f(xié)程
wait(): 等待事件的出發(fā)(await),如果事件已經(jīng)觸發(fā),立即返回
clear(): 清楚以觸發(fā)的事件
is_set():判斷事件是否觸發(fā)
旗語(yǔ)
cocotb中提供了Lock操作用來(lái)實(shí)現(xiàn)與SystemVerilog中相似的操作,不過(guò)Lock不可聲明旗語(yǔ)為多個(gè):
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主要用于不同進(jìn)程間的通信,在cocotb中,普通的Python的隊(duì)列即可實(shí)現(xiàn)該功能(協(xié)程中無(wú)需沒(méi)有進(jìn)程間同步問(wèn)題)。
審核編輯就:劉清
-
仿真器
+關(guān)注
關(guān)注
14文章
1018瀏覽量
83752 -
RTL
+關(guān)注
關(guān)注
1文章
385瀏覽量
59797 -
python
+關(guān)注
關(guān)注
56文章
4797瀏覽量
84694
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論