懂得“數(shù)據(jù)結(jié)構(gòu)與算法” 寫出高效的代碼,懂得“設(shè)計(jì)模式”寫出高質(zhì)量的代碼。
何為高質(zhì)量的代碼?
下面這些詞匯是我們常用的形容好代碼的詞匯:
靈活性(flexibility)、可擴(kuò)展性(extensibility)、可維護(hù)性(maintainability)、可讀性(readability)、可理解性(understandability)、易修改性(changeability)、可復(fù)用(reusability)、可測試性(testability)、模塊化(modularity)、高內(nèi)聚低耦合(high cohesion loose coupling)、高效(high effciency)、高性能(high performance)、安全性(security)、兼容性(compatibility)、易用性(usability)、整潔(clean)、清晰(clarity)、簡單(simple)、直接(straightforward)、少即是多(less code is more)、文檔詳盡(well-documented)、分層清晰(well-layered)、正確性(correctness、bug free)、健壯性(robustness)、魯棒性(robustness)、可用性(reliability)、可伸縮性(scalability)、穩(wěn)定性(stability)、優(yōu)雅(elegant)、好(good)
如何寫出高質(zhì)量代碼?
-
面向?qū)ο?a href="http://hljzzgx.com/v/tag/1315/" target="_blank">編程因?yàn)槠渚哂胸S富的特性(封裝、抽象、繼承、多態(tài)),可以實(shí)現(xiàn)很多復(fù)雜的設(shè)計(jì)思路,是很多設(shè)計(jì)原則、設(shè)計(jì)模式等編碼實(shí)現(xiàn)的基礎(chǔ)。
-
設(shè)計(jì)原則是指導(dǎo)我們代碼設(shè)計(jì)的一些經(jīng)驗(yàn)總結(jié),對(duì)于某些場景下,是否應(yīng)該應(yīng)用某種設(shè)計(jì)模式,具有指導(dǎo)意義。
-
設(shè)計(jì)模式是針對(duì)軟件開發(fā)中經(jīng)常遇到的一些設(shè)計(jì)問題,總結(jié)出來的一套解決方案或者設(shè)計(jì)思路。應(yīng)用設(shè)計(jì)模式的主要目的是提高代碼的可擴(kuò)展性。
-
編程規(guī)范主要解決的是代碼的可讀性問題。
-
重構(gòu)作為保持代碼質(zhì)量不下降的有效手段。
面向?qū)ο?/span>
含義
面向?qū)ο缶幊痰挠⑽目s寫是 OOP,全稱是 Object Oriented Programming。對(duì)應(yīng)地,面向?qū)ο缶幊陶Z言的英文縮寫是 OOPL,全稱是 Object Oriented Programming Language。
面向?qū)ο缶幊讨杏袃蓚€(gè)非常重要、非?;A(chǔ)的概念,那就是類(class)和對(duì)象(object)。這兩個(gè)概念最早出現(xiàn)在 1960 年,在 Simula 這種編程語言中第一次使用。而面向?qū)ο缶幊踢@個(gè)概念第一次被使用是在 Smalltalk 這種編程語言中。Smalltalk 被認(rèn)為是第一個(gè)真正意義上的面向?qū)ο缶幊陶Z言。
Systemverilog作為面向?qū)ο蟮恼Z言,相比C++, 更"像“ Java. Java語言并不直接運(yùn)行在真實(shí)機(jī)器上,而是有一個(gè)虛擬機(jī)(即Java Virtual Machine ,JVM)來承載其運(yùn)行,JVM使用C++編寫的,而C++是C的超集。
UML
UML(Unified Model Language),統(tǒng)一建模語言。用畫圖表達(dá)面向?qū)ο蠡蛟O(shè)計(jì)模式的設(shè)計(jì)思路。對(duì)于UML的使用,純軟件人員之間仍存在一些爭議。
示例:
封裝(Encapsulation)
將屬性和方法封裝到到類中,但類中的屬性并不需要全部暴露出去,可以通過加上訪問權(quán)限控制這一語法機(jī)制,限制對(duì)類屬性的訪問,修改。
Java中的權(quán)限修飾符:
private 修飾的函數(shù)或者成員變量,只能在類內(nèi)部使用。
protected 修飾的函數(shù)或者成員變量,可以在類及其子類內(nèi)使用。
public 修飾的函數(shù)或者成員變量,可以被任意訪問。
SV中的訪問權(quán)限控制qualifiers限定符:
local:表示的成員或方法只對(duì)該類的對(duì)象可見,子類以及類外不可見。
protected:表示的成員或方法對(duì)該類以及子類可見,對(duì)類外不可見。
除此之外,我們還常見const, static修飾變量。
const:分為兩種:全局性、instance性的 (const 在run-time階段,而 localparam需要在elaboration-time
被賦值)
全局性const:在聲明時(shí)即賦值,之后不可修改;
instace性const:只使用const進(jìn)行聲明,賦值發(fā)生在new()中
const修飾的變量,不允許被修改,否則編譯器報(bào)錯(cuò)。
為什么const修飾的變量不可以被修改呢?其實(shí)無論SV,C++還是C語言,各種語言的語法不同,但是最終都是通過編譯器編譯后,程序運(yùn)行在系統(tǒng)內(nèi)存里,如果const修飾的變量被編譯器分配到了一個(gè).rodata只讀的內(nèi)存段,那么就可以很好的解釋為什么不可以被修改了。同理,static對(duì)應(yīng)靜態(tài)分配的地址(存儲(chǔ)在全局?jǐn)?shù)據(jù)區(qū)),該段地址相對(duì)automatic屬性的地址段,不會(huì)被釋放內(nèi)存,自然可以在整個(gè)仿真過程一直存在。
為了地址對(duì)齊,SV仿真器會(huì)把byte放在32bit的地址空間。
對(duì)于task/function調(diào)用,則對(duì)應(yīng)??臻g,如果使用的是input,output類型的參數(shù),開始調(diào)用時(shí)“input” 變量 copy到棧中,結(jié)束調(diào)用時(shí)“ouput” 變量再pop出棧。所以在task/function中修改變量,修改的結(jié)果對(duì)其他調(diào)用函數(shù)不可見。如果使用SV中的ref,一方面對(duì)于數(shù)據(jù)量較大的數(shù)組,不用copy到??臻g,可以獲得更佳的性能,同時(shí)修改變量的結(jié)果對(duì)外可見。
對(duì)于上述諸多的變量修飾符,從編譯存儲(chǔ)的角度分析,可以加深理解。C語言相對(duì)其他語言O(shè)OP語言,更接近硬件,可以通過objdump –dS a.out 反匯編查看各個(gè)變量的
main 函數(shù)位于.text段,GLOBAL修飾屬于External Linkage
‘A’ 位于 .rodata段
‘Hello World” 也位于.rodata段 hexdump –C a.out可以查看。
程序加載運(yùn)行時(shí), .rodata段和.text段通常合并到一個(gè)Segment中,操作系統(tǒng)將這個(gè)Segment的頁面只讀保護(hù)起來,防止意外的改寫。
.data段中有 ‘a(chǎn)’, ‘b’, ‘d’ , 其中a是GLOBAL全局變量,b被static修飾,為LOCAL,不會(huì)被鏈接器處理。d被static修飾,并位于main函數(shù)中,靜態(tài)分配。
.bss段緊挨著.data段,被0填充,不占內(nèi)存。所以c位于.bss段,未賦值初始化為0. .data 和.bss在加載時(shí)合并到一個(gè)Segment中,這個(gè)Segment是可讀可寫的。
‘e’ 位于函數(shù)內(nèi)部,放在棧上存儲(chǔ), 省略auto修飾
參考:Linux C編程一站式學(xué)習(xí) 宋勁杉 19.3 變量的存儲(chǔ)布局
抽象(Abstraction)
OOP中抽象這一特性本身就很“抽象”,如果單單從語法上看,SV在《IEEE Standard for SystemVerilog 1800-2012》才加入了像Java語言那樣支持抽象(面向接口編程)的語法。關(guān)鍵詞是 interface class, implements。
當(dāng)一個(gè)class implements 一個(gè) interface class時(shí),必須override interface class 中的純虛(pure virtual)方法,這也很符合 implements這個(gè)單詞本身的含義。
下面看一個(gè)列子(from IEEE Standard for SystemVerilog 1800-2012 8.26):
兩個(gè)interface class,PutImp, GetImp 分別包含純虛方法put, get的原型。class Fifo 和 class Stack 使用關(guān)鍵詞 implementes來實(shí)現(xiàn)這兩個(gè)interface class中的純虛方法。
class Fifo and class Stack share common behaviors without sharing a common implementation.
classs Fifo 和 class Stack 都有 put, get的操作,但是實(shí)現(xiàn)的具體方式不同(FIFO:先進(jìn)后出,Stack:先進(jìn)先出)。這就體現(xiàn)了“抽象”的含義,interface僅僅暴露出的是common behavirs,調(diào)用人員不需要關(guān)心具體的實(shí)現(xiàn)。
實(shí)際上,如果上升一個(gè)思考層面的話,抽象及其前面講到的封裝都是人類處理復(fù)雜性的有效手段。在面對(duì)復(fù)雜系統(tǒng)的時(shí)候,人腦能承受的信息復(fù)雜程度是有限的,所以我們必須忽略掉一些非關(guān)鍵性的實(shí)現(xiàn)細(xì)節(jié)。而抽象作為一種只關(guān)注功能點(diǎn)不關(guān)注實(shí)現(xiàn)的設(shè)計(jì)思路,正好幫我們的大腦過濾掉許多非必要的信息。
可能因?yàn)閕ntreface class這一語法加入SV較晚,并且EDA工具支持有一定延遲,在UVM源碼中,并沒有使用 interface class這一語法。但抽象僅僅是一個(gè)非常通用的設(shè)計(jì)思想, 比如一個(gè)上報(bào)錯(cuò)誤的function, 命名為report_error()就比命名為report_size_mismatch_error()抽象,具體的錯(cuò)誤類型,不必體現(xiàn)在函數(shù)命名上。( 2016 DVCon US : SystemVerilog Interface Classes - More Useful Than You Thought 涉及 interface classes 在實(shí)際項(xiàng)目中的使用)
在SV沒有加入接口類(intreface class)之前,也有抽象類(virtual class)可以代替抽象的特性。
抽象類不能直接例化,一個(gè)由抽象類擴(kuò)展而來的類只有在所有虛方法都有實(shí)體的時(shí)候才能被例化。抽象類中可以定義非純虛方法,但是接口類不行。
接口類的一些特性,抽象類并不具備。比如一個(gè)類可以實(shí)現(xiàn)多個(gè)接口類,并同時(shí)繼承某一個(gè)類。比如下面這個(gè)用例。
extends 和 implements還是有本質(zhì)區(qū)別的,extends繼承,是 is-a的關(guān)系,而implements更像是has-a的關(guān)系。所以SV中加入interface class,使其更接近高級(jí)語言所具備的特性。
抽象類和接口類如何選擇呢?抽象類是is-a的關(guān)系,解決代碼復(fù)用問題,接口類是has-a的關(guān)系,更側(cè)重于解耦,隔離接口和具體的實(shí)現(xiàn),提高代碼的擴(kuò)展性。
基于接口而非實(shí)現(xiàn)編程(Program to an interface, not an implementation),將接口(interface)和實(shí)現(xiàn)(implements)相分離,封裝不穩(wěn)定的實(shí)現(xiàn),暴露穩(wěn)定的接口。
上游系統(tǒng)面向接口而非實(shí)現(xiàn)編程,不依賴不穩(wěn)定的實(shí)現(xiàn)細(xì)節(jié),這樣當(dāng)實(shí)現(xiàn)發(fā)生變化的時(shí)候,上游系統(tǒng)的代碼基本上不需要做改動(dòng),以此來降低耦合性,提高擴(kuò)展性。
UVM驗(yàn)證平臺(tái),已規(guī)定好了hierarchy結(jié)構(gòu)和各component功能,驗(yàn)證工程師只需根據(jù)實(shí)際業(yè)務(wù)“填充”具體內(nèi)容,屬于硬件驗(yàn)證,而純軟件要實(shí)現(xiàn)多交互的復(fù)雜業(yè)務(wù)側(cè)重設(shè)計(jì),所以一般工作中沒有需求用到抽象類和接口類。對(duì)于沒有使用UVM方法學(xué),自己寫Systemverilog搭建的驗(yàn)證平臺(tái), 接口類,抽象類,純虛方法可以建立具有統(tǒng)一觀感的測試平臺(tái),這就使任何一個(gè)工程師都可以讀懂你的代碼并且快速理解其結(jié)構(gòu)。
繼承(Inheritance)
繼承是用來表示類之間的 is-a 關(guān)系,比如狗是一種哺乳動(dòng)物??梢酝ㄟ^extends 關(guān)鍵字來實(shí)現(xiàn)繼承(可以通過繼承+參數(shù)化的類來實(shí)現(xiàn)多繼承的效果,有點(diǎn)非常規(guī)操作,參考SystemVerilog: Reusable Class Features and Safe Initialization of Static Variables。另外interface class也可以實(shí)現(xiàn)多繼承),C++和Python既支持單重繼承,也支持多重繼承。
在構(gòu)造用例時(shí),一般會(huì)創(chuàng)建一個(gè)base_class作為父類,子類extends繼承父類的特性,使用super關(guān)鍵字指示編譯器來顯式的引用父類中定義的數(shù)據(jù)成員和方法。
SV語法規(guī)定父類的new()函數(shù)(構(gòu)造函數(shù)),子類必須顯示調(diào)用,寫出super.new()。如果父類new()函數(shù)有參數(shù),子類也需要傳入?yún)?shù)。不管子類是否重載new()函數(shù),都要顯式調(diào)用父類的構(gòu)造函數(shù)。
在實(shí)際驗(yàn)證工作中,一般不會(huì)出現(xiàn)下述問題,基本繼承2次就足以覆蓋大部分需求了,但是純軟件編程可能會(huì)因?yàn)闃I(yè)務(wù)復(fù)雜,導(dǎo)致繼承過度,采用 “多用組合少用繼承” 是一個(gè)規(guī)避辦法。
繼承的概念很好理解,也很容易使用。不過,過度使用繼承,繼承層次過深過復(fù)雜,就會(huì)導(dǎo)致代碼可讀性、可維護(hù)性變差。為了了解一個(gè)類的功能,我們不僅需要查看這個(gè)類的代碼,還需要按照繼承關(guān)系一層一層地往上查看“父類、父類的父類……”的代碼。還有,子類和父類高度耦合,修改父類的代碼,會(huì)直接影響到子類。
在SV使用中,我們也會(huì)遇到合成和繼承的選擇問題,合成使用了“有”(has-a)的關(guān)系,繼承使用了“是”(is-a)的關(guān)系。
SV構(gòu)建測試平臺(tái)并非標(biāo)準(zhǔn)的軟件開發(fā)項(xiàng)目,除了繼承與合成之外,根據(jù)現(xiàn)實(shí)的場景使用,把所用變量集成在一個(gè)類中,通過條件約束達(dá)到目的。Constraint-driven 的策略更有利于我們的驗(yàn)證工作。
如下示例:(Systemverilog驗(yàn)證 測試平臺(tái)編寫指南 8.4)
多態(tài)(Polymorphism)
多態(tài)是指,子類可以替換父類,父類句柄可以指向子類的實(shí)例。(子類句柄不可以指向父類的實(shí)例,因?yàn)樽宇愓{(diào)用的方法,父類實(shí)例中或許并不存在)
多態(tài)的例子這里就不再列舉了,建議學(xué)習(xí)《The UVM Primer》,這是一本很好學(xué)習(xí)OOP的書籍,足以應(yīng)對(duì)工作中的絕大部分內(nèi)容。
當(dāng)父類句柄指向子類的實(shí)例時(shí),通過父類句柄調(diào)用方法,如果方法使用virtual修飾,則會(huì)動(dòng)態(tài)的調(diào)用子類的方法(雖然是父類句柄,但是實(shí)例是子類,實(shí)際調(diào)用子類override(重寫or覆蓋)的方法)。如果方法沒有使用virtual修飾,則是靜態(tài)的根據(jù)句柄調(diào)用方法(動(dòng)態(tài):實(shí)例 靜態(tài):句柄)。
父類的task/function已經(jīng)用virtual修飾,子類沒有必要在加上virtual了。
所以多態(tài)的實(shí)現(xiàn)要依賴虛函數(shù)virtual,總結(jié)就是“繼承加方法重寫 ”。
SV語法目前還不支持overload(重載),override指的是重寫,也可以理解成覆蓋,一般不做詳細(xì)區(qū)分。
對(duì)于多態(tài)的底層實(shí)現(xiàn)及virtual, function override,$cast()轉(zhuǎn)化的底層原理,需要深入研究編程語言的編譯原理。檢索并沒有介紹Systemverilog的相關(guān)文章,可以通過學(xué)習(xí)C++或者Jave擴(kuò)充學(xué)習(xí),檢索內(nèi)存模型或者對(duì)象模型獲取相關(guān)知識(shí)。
除了上述“繼承加方法重寫”實(shí)現(xiàn)多態(tài)的方法,Systemverilog也可以采用之前介紹的 interface class實(shí)現(xiàn)多態(tài)。還有一種是利用 duck-typing 語法,SV并不支持,動(dòng)態(tài)語言Python才支持。
實(shí)例如下:
class Logger:
def record(self):
print(“I write a log into file.”)
class DB:
def record(self):
print(“I insert data into db. ”)
def test(recorder):
recorder.record()
def demo():
logger = Logger()
db = DB()
test(logger)
test(db)
設(shè)計(jì)模式之美 從這段代碼中,我們發(fā)現(xiàn),duck-typing 實(shí)現(xiàn)多態(tài)的方式非常靈活。Logger 和 DB 兩個(gè)類沒有任何關(guān)系,既不是繼承關(guān)系,也不是接口和實(shí)現(xiàn)的關(guān)系,但是只要它們都有定義了 record() 方法,就可以被傳遞到 test() 方法中,在實(shí)際運(yùn)行的時(shí)候,執(zhí)行對(duì)應(yīng)的 record() 方法。
設(shè)計(jì)原則
純軟件設(shè)計(jì)中的設(shè)計(jì)原則,對(duì)于IC的驗(yàn)證和設(shè)計(jì)工作也有指導(dǎo)意義,我們?nèi)粘9ぷ髦械囊恍傲?xí)慣”,可能就是在踐行某一個(gè)設(shè)計(jì)原則。依次列舉如下:
單一職責(zé)原則
一個(gè)類只負(fù)責(zé)一個(gè)功能,避免設(shè)計(jì)大而全的類,避免不相關(guān)的功能耦合,提高內(nèi)聚性。也可以延申到驗(yàn)證的測試用例,每個(gè)用例應(yīng)該對(duì)應(yīng)一個(gè)場景或者功能。
開閉原則
對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。對(duì)于新加的功能,應(yīng)在已有代碼基礎(chǔ)上擴(kuò)展,而非修改已有代碼。所以在最初代碼編寫時(shí),就應(yīng)該充分考慮可擴(kuò)展性,當(dāng)然也不是完全杜絕修改,要把握“粗細(xì)粒度”。對(duì)于已經(jīng)充分驗(yàn)證的rtl模塊,側(cè)重在原來基礎(chǔ)上新加功能,而不是“大修”原來的模塊,容易引入bug, 相應(yīng)的測試用例也可以做到最小修改。
里式替換原則
子類對(duì)象可以替換程序中出現(xiàn)的父類對(duì)象,并保證原來程序的邏輯行為的正確性。這一原則跟多態(tài)比較像,側(cè)重于繼承關(guān)系中子類該如何設(shè)計(jì)。
接口隔離原則
接口的調(diào)用者不應(yīng)該強(qiáng)迫依賴ta不需要的接口。如果B模塊內(nèi)包含B-1,B-2兩個(gè)模塊,A模塊的正常工作依賴于B-1模塊的初始配置,C模塊的正常工作依賴于B-2模塊的初始配置。B模塊的驗(yàn)證人員可以將B模塊的初始配置流程寫到一個(gè)函數(shù)中,這個(gè)函數(shù)供A,C模塊的驗(yàn)證人員調(diào)用,這個(gè)函數(shù)就像API接口一樣,調(diào)用者只負(fù)責(zé)調(diào)用,不用關(guān)心具體實(shí)現(xiàn)。如果B模塊的函數(shù)同時(shí)包含B-1,B-2的初始配置,A模塊的驗(yàn)證人員調(diào)用,雖然不會(huì)影響功能驗(yàn)證,但是B-2模塊與A模塊并無聯(lián)系,恰當(dāng)?shù)淖龇☉?yīng)該是將B-1,B-2模塊的初始配置隔離開來,供使用者按需調(diào)用。
依賴倒置原則
程序要依賴于抽象接口,不要依賴于具體實(shí)現(xiàn)。簡單的說就是要求對(duì)抽象進(jìn)行編程,不要對(duì)實(shí)現(xiàn)進(jìn)行編程,這樣就降低了客戶與實(shí)現(xiàn)模塊間的耦合。高層次的模塊不應(yīng)該依賴于低層次的模塊,他們都應(yīng)該依賴于抽象。和依賴接口編程的含義相近。
KISS、YANGI ,DRY原則
KISS: Keep It Stupid Simple 不要使用同事不懂的技術(shù);不要重復(fù)造輪子,使用現(xiàn)有的方法;不要過度優(yōu)化;
YANGI: You Ain't Gonna Need It 不要過度設(shè)計(jì)
DRT: Don't repeat yourself 減少重復(fù)的代碼。對(duì)于重復(fù)的代碼,思考是否可以通過封裝到函數(shù)中,通過傳參的方式實(shí)現(xiàn)。
迪米特法則
Talk only to your immediate friends and not to strangers,只與你的直接朋友交談,不跟“陌生人”說話。
如果兩個(gè)模塊實(shí)體無須直接通信,那么就不應(yīng)當(dāng)發(fā)生直接的相互調(diào)用,可以通過第三方轉(zhuǎn)發(fā)該調(diào)用。其目的是降低類之間的耦合度,提高模塊的相對(duì)獨(dú)立性。“高內(nèi)聚,松耦合”
規(guī)范與重構(gòu)
代碼風(fēng)格與規(guī)范:Easier UVM Coding Guidelines
代碼測試:SV單元測試方法SVUnit SVUnit Download SVUnit blog
SVUnit采用了一種特別的方式來生成task。一般task負(fù)責(zé)時(shí)序相關(guān)的驅(qū)動(dòng)和采樣,開發(fā)者根據(jù)設(shè)計(jì)文檔中的時(shí)序圖編寫task代碼,但是代碼的準(zhǔn)確性有待驗(yàn)證。SVUnit從另一個(gè)思路出發(fā),直接通過時(shí)序圖,來生成對(duì)應(yīng)task。這樣便保證了task中時(shí)序的準(zhǔn)確性,畢竟時(shí)序圖要是都錯(cuò)了,那只能通過review發(fā)現(xiàn)了。
SVUnit將時(shí)序圖轉(zhuǎn)化成task的方法,是通過編寫wavdrom可識(shí)別的json格式(有固定格式,但是很容易上手,支持網(wǎng)頁,linux, window平臺(tái)。UserGuide). 然后調(diào)用SVUnit中的腳本wavedromSVUnit.py解析json文件,生成時(shí)序圖對(duì)應(yīng)的代碼。SVUnit對(duì)json文件做了額外描述,可以參照 test/wavedrom_0/1下面的json文件深入理解。
示例:
json描述:
{
"name": "read",
"signal": [
{"name": "clk", "wave": "p|...|." , "node": ".ab...d"},
{"name": "psel", "wave": "0.1...0" },
{"name": "penable", "wave": "0..1..0" },
{"name": "paddr", "wave": "x.=...x" , "data": ["addr"] },
{"name": "pready", "wave": "0....10" , "input": "True", "node": "......c"},
{"name": "prdata", "wave": "x....=x" , "output": "True", "data": ["data"] }
],
"input": [
{"name": "addr", "type": "logic [7:0]"}
],
"output": [
{"name": "data", "type": "logic [31:0]"}
],
"edge": ["a~>b 8,12", "c->d pready==1"],
config: { hscale: 3 }
}
waverom生成的時(shí)序圖:
自動(dòng)生成的task:
這種方式的限制就是僅適用于直接測試用例。
絕大部分驗(yàn)證人員開發(fā)UVC,都是一遍debug DUT, 一遍調(diào)試驗(yàn)證平臺(tái),并不會(huì)專門使用SVUnit對(duì)UVC進(jìn)行驗(yàn)證。但是對(duì)于sv庫的開發(fā),使用SVUnit是一個(gè)很好的選擇。
不過仍建議在monitor, driver開發(fā)初期,同時(shí)RTL還沒有ready的情況下,使用SVUnit將波形轉(zhuǎn)化成直接的時(shí)序激勵(lì),做一些直接用例的測試,及早發(fā)現(xiàn)問題。如果設(shè)計(jì)文檔中的波形也是使用wavedrom繪制的,那么對(duì)于驗(yàn)證人員的工作又省了一步,可以直接拿設(shè)計(jì)人員波形的json文件生成用例。
重構(gòu):隨著項(xiàng)目的推進(jìn),迭代,原來的代碼也會(huì)慢慢變“差”,重構(gòu)可能是一條"挽回“路徑。在項(xiàng)目初期,盡可能地劃分好驗(yàn)證平臺(tái)的組件,目錄,文件調(diào)用,宏定義,腳本等,重構(gòu)的同時(shí)也在引入不確定性。
審核編輯 :李倩
-
UVM
+關(guān)注
關(guān)注
0文章
182瀏覽量
19167 -
代碼
+關(guān)注
關(guān)注
30文章
4779瀏覽量
68521 -
數(shù)據(jù)結(jié)構(gòu)
+關(guān)注
關(guān)注
3文章
573瀏覽量
40121
原文標(biāo)題:UVM設(shè)計(jì)模式:OOP特性、設(shè)計(jì)原則、規(guī)范與單元測試
文章出處:【微信號(hào):IP與SoC設(shè)計(jì),微信公眾號(hào):IP與SoC設(shè)計(jì)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論