0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

cocotb中的基礎(chǔ)語法

FPGA之家 ? 來源:FPGA之家 ? 作者:FPGA之家 ? 2022-07-21 09:18 ? 次閱讀

cocotb的出現(xiàn)使得我們能夠在做RTL仿真驗(yàn)證時(shí)依托Python來進(jìn)行測試用例的構(gòu)建,當(dāng)我們習(xí)慣了用Verilog、SystemVerilog來構(gòu)建測試用例時(shí),切換到cocotb后最直觀的方式便是我們能夠建立cocotb中的基礎(chǔ)語法與SystemVerilog中仿真常用的關(guān)鍵字又一個(gè)對應(yīng),能夠使我們又一個(gè)初步的對照。本篇就cocotb中的基礎(chǔ)語法與SystemVerilog中的常用語法做一個(gè)對照總結(jié)。

非阻塞賦值

在使用Systemverilog進(jìn)行仿真時(shí),對于接口信號,往往建議采用非阻塞賦值進(jìn)行操作,其符號為“<=”.

在cocotb中,對于信號的賦值,其提供相應(yīng)的非阻塞賦值方式,其符號也同樣為“<=”。

在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中這樣來進(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

阻塞賦值

針對阻塞賦值(立即生效),cocotb提供了相應(yīng)的語法:

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.

信號的讀取我們可以這么來寫:

# Read a value back from the DUTcount=dut.counter.valueprint(count.binstr)1X1010# Resolve the value to an integer (X or Z treated as 0)print(count.integer)42# Show number of bits in a valueprint(count.n_bits)6

#Time

在仿真里延遲等待是經(jīng)常遇到的,在cocotb里,我們通過Timer來實(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í)間長度是依賴于仿真器的,因此Timer延遲的執(zhí)行需調(diào)用await:

await Timer(1, units='ns')

邊沿檢測

在SystemVerilog中我們常用posedge、negedge來檢測上升沿和下降沿,在cocotb里,針對邊沿檢測,其提供了四個(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.

檢測等待指定到個(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.

我們在使用時(shí),可以這么來寫:

#等待信號signalA發(fā)生變化await cocotb.triggers.Edge(dut.signalA)#等待signalA從0變?yōu)?await cocotb.triggers.RisingEdge(dut.signalA)#等待signalA從1變?yōu)?await cocotb.triggers.FallingEdge(dut.signalA)#等待signalA從0變?yōu)?三次awaitcocotb.triggers.ClockCycles(dut.signalA,3,true)

fork-join_none

SystemVerilog中的fork-join_none用于發(fā)起一個(gè)線程但不等待線程的結(jié)束,在cocotb中,相應(yīng)的語法為fork:

cocotb.fork()

Schedule a coroutine to be run concurrently

在寫仿真代碼時(shí),我們可以這么寫:

async def reset_dut(reset_n, duration_ns):    reset_n <= 0    await Timer(duration_ns, units='ns')    reset_n <= 1    reset_n._log.debug("Reset complete")reset_thread = cocotb.fork(reset_dut(reset_n, duration_ns=500))

這里值得注意的是,由于fork是起一個(gè)協(xié)程,因而resut_dut需添加async聲明。

fork-join

與SystemVerilog中相對應(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:

使用方式:

async def coro_inner():    await Timer(1, units='ns')    return "Hello world"
task = cocotb.fork(coro_inner())result = await Join(task)assert result == "Hello world"

fork-any

相較于SystemVerilog中的join-any語法,cocotb并無專門的對應(yīng)語法,但卻有相似的方法供調(diào)用:

class cocotb.triggers.First(*triggers)

等待第一個(gè)協(xié)程結(jié)束即返回

t1 = Timer(10, units='ps')t2 = Timer(11, units='ps')t_ret = await First(t1, t2)

這里我們通過First等待t1、t2第一個(gè)返回的結(jié)果后await結(jié)束,并將第一個(gè)返回的協(xié)程的返回結(jié)果賦值給t_ret。

event

對于SystemVerilog中的event,在cocotb中同樣提供類似的event:

class cocotb.triggers.Event(name=None)

用于兩個(gè)協(xié)程間的同步

方法:

set(data=None):喚醒所有等待該事件的協(xié)程

wait(): 等待事件的出發(fā)(await),如果事件已經(jīng)觸發(fā),立即返回

clear(): 清楚以觸發(fā)的事件

is_set():判斷事件是否觸發(fā)

旗語

cocotb中提供了Lock操作用來實(shí)現(xiàn)與SystemVerilog中相似的操作,不過Lock不可聲明旗語為多個(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é)程中無需沒有進(jìn)程間同步問題)。

審核編輯 :李倩

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4671

    瀏覽量

    67765
  • 語法
    +關(guān)注

    關(guān)注

    0

    文章

    40

    瀏覽量

    9726
  • 非阻塞賦值
    +關(guān)注

    關(guān)注

    0

    文章

    10

    瀏覽量

    9990

原文標(biāo)題:cocotb—基礎(chǔ)語法對照篇

文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    用python寫驗(yàn)證環(huán)境cocotb

    本文介紹了cocotb的安裝、python tb文件的寫法、用xrun仿真cocotb的腳本等,我們來看看體驗(yàn)如何。
    的頭像 發(fā)表于 07-24 09:38 ?296次閱讀
    用python寫驗(yàn)證環(huán)境<b class='flag-5'>cocotb</b>

    FPGA學(xué)習(xí)筆記---基本語法

    Verilog語法是指硬件能夠?qū)崿F(xiàn)的語法。它的子集很小。常用的RTL語法結(jié)構(gòu)如下: 1、模塊聲明:module ... end module 2、端口聲明:input, output, inout
    發(fā)表于 06-23 14:58

    oracle和mysql語法區(qū)別大嗎

    Oracle和MySQL是兩種不同的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)(RDBMS)。雖然它們都是遵循SQL標(biāo)準(zhǔn),但在語法和特性上仍存在一些區(qū)別。以下是對Oracle和MySQL語法區(qū)別的詳細(xì)說明: 數(shù)據(jù)類型
    的頭像 發(fā)表于 12-06 10:26 ?854次閱讀

    oracle case when 語法介紹

    Oracle的CASE WHEN語法是一種在數(shù)據(jù)庫查詢中使用的條件語句,它提供了一種在SELECT語句中根據(jù)條件對結(jié)果進(jìn)行轉(zhuǎn)換或篩選的方法。在本文中,我們將詳細(xì)介紹Oracle的CASE WHEN
    的頭像 發(fā)表于 12-06 10:21 ?1391次閱讀

    oracle的update語法

    Oracle是一種強(qiáng)大的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),具有廣泛的應(yīng)用,UPDATE語句是用于修改數(shù)據(jù)庫現(xiàn)有記錄的重要操作之一。在本文中,我們將詳細(xì)介紹Oracle的UPDATE語法及其用法。 首先,我們
    的頭像 發(fā)表于 12-05 16:22 ?1818次閱讀

    javascript的基本語法遵循的標(biāo)準(zhǔn)

    的基本語法。 變量聲明與賦值 在JavaScript,可以使用關(guān)鍵字 var 、 let 或 const 聲明變量。其中, var 是舊版的聲明方式, let 和 const 是ES6引入的新特性。變量名
    的頭像 發(fā)表于 12-03 11:35 ?2434次閱讀

    JavaScript的語法和基本功能

    語法和基本功能。JavaScript可以在網(wǎng)頁實(shí)現(xiàn)交互和動態(tài)效果,為用戶提供更好的使用體驗(yàn)。 JavaScript最早由網(wǎng)景公司(Netscape)的布蘭登·艾奇(Brendan Eich)在
    的頭像 發(fā)表于 12-03 11:15 ?501次閱讀

    java switch case的語法規(guī)則

    在Java,switch case語句是一種用于多分支選擇的控制流語句。它允許根據(jù)某個(gè)表達(dá)式的值來執(zhí)行不同的代碼塊。下面是關(guān)于switch case語法規(guī)則的詳細(xì)解釋。 基本語法 switch語句
    的頭像 發(fā)表于 11-30 14:40 ?1303次閱讀

    Configuration Wizard的語法規(guī)則

    Configuration Wizard的語法規(guī)則 大家如果有使用過HTML語法,這里就非常容易理解了,它和 HTML一樣,使用成對的標(biāo)簽來代表不同的功能,如 >和>,其中 * 代表不同的功能標(biāo)簽
    的頭像 發(fā)表于 11-23 18:09 ?1019次閱讀
    Configuration Wizard的<b class='flag-5'>語法</b>規(guī)則

    select語句的基本語法

    SELECT語句是SQL(Structured Query Language,結(jié)構(gòu)化查詢語言)的一種查詢語句,用于從數(shù)據(jù)庫檢索數(shù)據(jù)。它是數(shù)據(jù)庫操作中最常用和基本的語句之一。在本文中,我將為您詳盡
    的頭像 發(fā)表于 11-17 16:23 ?1347次閱讀

    PLC編程循環(huán)語法使用方法

    不管什么CPU,什么編程語言,都有循環(huán)語法,可以用于實(shí)現(xiàn)循環(huán)。當(dāng)然,很多時(shí)候,語言對循環(huán)支持的并不夠理想。通常還要有指針,間接尋址等配合。所以在PLC編程,屬于難度比較高的題目。
    發(fā)表于 11-13 15:30 ?918次閱讀
    PLC編程循環(huán)<b class='flag-5'>語法</b>使用方法

    shell編程基本語法

    在Shell編程,有一些基本語法需要了解。 變量:在Shell,變量不需要事先聲明,可以直接創(chuàng)建和使用。變量名區(qū)分大小寫,使用美元符號 $ 訪問變量的內(nèi)容。例如, name="John" 創(chuàng)建
    的頭像 發(fā)表于 11-08 10:46 ?364次閱讀

    C編程中指針的語法和工作原理

    指針對許多 C 編程至關(guān)重要,但它們可能很難理解。本文通過實(shí)際示例來復(fù)習(xí)它們的語法以及它們的工作原理。
    發(fā)表于 10-21 17:54 ?693次閱讀

    Java的基礎(chǔ)語法

    上一次我們學(xué)習(xí)了怎么安裝JDK和開發(fā)工具IDEA,同時(shí)也給大家寫了一個(gè)hello world的演示代碼。今天我們給大家從 hello world 展開講講Java的基礎(chǔ)語法。 話不多說,直接
    的頭像 發(fā)表于 10-10 16:21 ?337次閱讀
    Java的基礎(chǔ)<b class='flag-5'>語法</b>

    quartus基本語法集合

    quartus基本語法集合
    發(fā)表于 09-26 07:05