uvm驗證環(huán)境里一般通過objection機制來控制仿真的結束,不過在機制之外,有時還需要通過看門狗來watchdog避免仿真環(huán)境掛死,watchdog配合objection一起來控制仿真的進行與結束。我一直自詡為對環(huán)境watchdog這件事爛熟于心了,不過沒想到這天還是被傷害到了。
事故背景
一個中規(guī)中矩的watchdog是怎么組織的呢?要明確一下watchdog發(fā)揮的作用,就是在objection的基礎上進行補充,在環(huán)境長時間沒有動靜的情況下能夠使環(huán)境報錯推出并打印此時阻止仿真結束的罪魁禍首。
基于這個認識,watchdog應該是base_test的run_phase()中進行調用,這樣既從時間全程參與又從空間上統(tǒng)攬全局。當然了,因為環(huán)境的主要行為集中在main_phase()中,所以把watchdog放在main_phase()中我覺得也是可以的。
task base_test::run_phase(uvm_phase phase): super.run_phase(phase); phase.raise_objection(this); this.watchdog(phase); phase.drop_objection(this); endtask: run_phasewatchdog上下的objection還是很有必要的,畢竟你要保證watchdog無論在哪里調用都可以執(zhí)行起來,別這個phase沒有objection就直接略過了。watchdog內部邏輯就是幾個并行的線程,簡單來說可以這樣寫:
task base_test::watchdog(uvm_phase phase): #1000; if(this.cfg.watchdog_en == 0) return; while(1)begin bit vr_reached; fork: timeout begin //normal finish phase.phase_done.wait_for_total_count(null, 1); vr_reached = 1; end begin //timeout #this.cfg.watchdog_th; `uvm_fatal(“watchdog”, $psprintf(“watchdog timeout(%s_phase):: %s”, phase.get_name(), phase.phase_done.convert2string())) end #100 @prj_scoreboard::feed_watchdog; #100 @harness.dut.hand_en; #100 wait(this.env.num != 0); join_any disable timeout; #10; if(vr_reached && phase.phase_done.get_objection_tatal == 1)begin `uvm_info(“watchdog”, $psprintf(“watchdog timeout(%s_phase) normal reached”, phase.get_name()), UVM_LOW) break; end end `uvm_note(“watchdog”, “watchdog Finished!”, UVM_LOW) endtask代碼的主體就是一個大的while(1)循環(huán),循環(huán)內以fork - join_any的形式起多個喂狗線程,根據(jù)fork - join_any的機制,只要任何一個線程完成了都會觸發(fā)喂狗機制。
線程1:正常結束的線程,因為本身watchdog占著一個raise_objection,所以只要等待wait_for_total_count(null, 1)就可以了,為1說明其他的objection都已經(jīng)drop了,那么就可以正常結束程序,和uvm本身的objection機制完全一樣;
線程2:超時線程,如果很長的時間里都沒有喂狗,那么報fatal推出仿真。注意這里必須是fatal使方正立即結束,報error的話環(huán)境還是會掛死狀態(tài);
線程3:所有的scoreboard都可以喂狗,因為scb里比對的一方是可以信任的環(huán)境預期,如果比對還在進行那么就說明仿真不應該結束;
線程N:可以喂狗的其他線程,使用rtl線程需要萬分謹慎,很有可能rtl里做錯了一致重復出數(shù)據(jù)導致仿真無法結束;
當喂狗一次后,就可以殺掉timeout這個線程了,然后根據(jù)情況看看是否重新回到看門狗循環(huán)中。
事故現(xiàn)場
看門狗的核心起始就是,確定仿真在“動”,能動就是還活著不能結束仿真,所以在fork-join_any里除了超時線程以外,其他的都是證明系統(tǒng)還活著的“喂狗”線程。這些線程里如果使用rtl的信號作為系統(tǒng)還活著的參照,一定要萬分的小心,萬分的小心,萬分的小心。第一點小心是該停止但是停不下來,取材自上個月的bug。
場景很簡單,#100 @harness.dut.hand_en這個線程里hand_en做錯了,進入了無限發(fā)包無限握手的死循環(huán),帶著環(huán)境也一直停不下來看門狗直接失效了。第二點小心是該仿真但是挺下來了,這個事我以前就沒想過能出現(xiàn)。
事故現(xiàn)場是這樣的還是#100 @harness.dut.hand_en這個線程(就是這么頭鐵,出過錯了還繼續(xù)用),這次確實是RTL正常的發(fā)包握手,但是,性能模式下外部沒有反壓拍拍握手成功,hand_en起來之后就沒見到下降沿!這就導致了什么問題呢,導致@harness.dut.hand_en線程根本就觸發(fā)不了!這就涉及到@和wait的區(qū)別了,@捕捉的是event trigger是信號的跳變,harness.dut.hand_en恒1不跳導致看門狗直接超時了。簡直目瞪口呆,只要每天比別人多碰到3個bug,兩年能積累別人五年經(jīng)驗。
事故解決我把@harness.dut.hand_en改成wait harness.dut.hand_en了
審核編輯:黃飛
-
看門狗
+關注
關注
10文章
562瀏覽量
70808 -
UVM
+關注
關注
0文章
182瀏覽量
19171 -
線程
+關注
關注
0文章
504瀏覽量
19683
原文標題:犄角旮旯的bug:UVM環(huán)境的看門狗怎么沒看住超時了?
文章出處:【微信號:IC修真院,微信公眾號:IC修真院】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論