不同抽象級別的Verilog HDL模型

2020-08-10 21:11:49

寫在最前面(記錄下自己):

7月初,畢業離校就開始自學IC驗證,某乎上面建議學習verilog、systemverilog、UVM。

花了三天時間看完了一本verilog語法,知道一些規則,就結合FPGA實戰專案(狀態機、交通燈等),學習了數位電路、Verilog,熟悉語法點、看的懂部分程式碼,通過quartus II進行了模擬(功能模擬、後模擬);

後來又去某乎,別人建議參考綠皮書、紅寶書、白皮書學習systemverilog、UVM,這有顏色的書是什麼呀?於是乎,就去各大輔導機構招生羣裡諮詢,最終確認:

  1. 綠皮書SystemVerilog驗證+測試平臺編寫指南
  2. 白皮書:張強的 UVM實戰
  3. 紅寶書:劉斌的 晶片驗證漫遊指南

接下來就去啃這三本書,看路桑的V2視訊,學完SystemVerilog、UVM,會簡單使用Questasim,只做了幾個簡單的練習,但是拋過課程,自己連個interface都不會寫,別說自己寫出testbench,發現這和FPGA的專案完全不一樣。後來就去練習Synopsys公司的一個的SV實驗,但實驗教學上面使用的VCS邏輯模擬工具,我用Questasim會出錯,於是就去找VCS。結果呢?

好吧,結果電腦BIOS進不去,虛擬化沒辦法開啓,虛擬機器沒辦法安裝,申請了免費的伺服器,被迫學習linux、shell、gvim。然後發現伺服器上安裝不了圖形化介面。好吧,人生中真正屬於自己的電腦該有了,把去年攢的獎學金全部拿出來,剛好入手戰神Z7-CT7NA(i7-9750H、GTX1660Ti)。

既然有了戰神,那速度還可以吧,虛擬機器就位,cenos7、Redhat就位,vcs就位。既然環境有了,就去學習VCS,結果又附加學習Makefile、DC、verilog。
 
 
這四十天,看的書有:《快速閱讀:一年輕鬆讀完1000本書》、《變態心理學》、《verilog程式設計藝術》、《細說linux基礎知識》、《晶片驗證漫遊指南》、《太極拳》、《壞小孩》、《非暴力溝通》、《自卑與超越》、《戴老師魔性詩詞課》、《共情式溝通》
這四十天,乾的農活有:曬小麥,栽ren,拔草,碾胡麻,到兔場清糞
這四十天,進過城,辦過貸款,打過斯諾克,開過奧迪A6L
 
 
突然就想去找夏老師的verilog實戰去看看,這篇文章就來了。
 

第九章 不同抽象級別的Verilog HDL模型

Verilog模型可以是實際電路不同級別的抽象。這些抽象的級別和它們對應的模型型別共有以下五種:
1) 系統級(system)
2) 演算法級(algorithmic)
3) RTL級(RegisterTransferLevel):
4) 門級(gate-level):
5) 開關級(switch-level)
 
一個複雜電路的完整Verilog HDL模型是由若幹個Verilog HDL模組構成的,每一個模組又可以由若幹個子模組構成。這些模組可以分別用不同抽象級別的Verilog HDL描述,在一個模組中也可以有多種級別的描述。利用Verilog HDL語言結構所提供的這種功能就可以構造一個模組間的清晰層次結構來描述極其複雜的大型設計。

門級結構描述

and 與門
nand 與非門
nor 或非門
or 或門
xor 互斥或門
xnor 互斥或非門
buf 緩衝器
not 非門
nand #10 nd1(a,data,clock,clear);
表示在模組中參照了一個名爲nd1的與非門(nand),輸入爲data、clock和clear,輸出爲a,輸出與輸入的延時爲10個單位時間。
 

1.如何用Verilog HDL語言描述D型主從觸發器模組?

門級結構描述D觸發器
 
門級結構描述D型主從觸發器模組的Verilog 程式碼如下:
//flop.v
module flop(data,clock,clear,q,qb);
		input data,clock,clear;
		output q,qb;

        nand  #10   nd1(a,data,clock,clear),    //  注意結束時用逗號,最後才用分號
                    nd2(b,ndata,clock),         // 表示nd1 到nd8 都是nand(與非門)
                    nd4(d,c,b,clear),
                    nd5(e,c,nclock),
                    nd6(f,d,nclock),
                    nd8(qb,q,f,clear);
        nand  #9    nd3(c,a,d),
                    nd7(q,e,qb);
        not #10     iv1(ndata,data),
                    iv2(nclock,clock);
endmodule
上面module和endmodule之間構成的模組,命名爲flop.v
 
當在其他模組中參照這個模組時,有兩種方法(順序法、埠名對應法)
 
順序法1) flop flop_d( d1, clk, clrb, q, qn);
埠名2) flop flop_d (.clock(clk),.q(q),.clear(clrb),.qb(qn),.data(d1));
 
它們都表示範例f1op_d 參照已編模組 flop。只是如果採取順序法範例的埠信號必須按照被參照模組的埠信號傳入;採用埠名法,範例的埠信號和被參照模組的埠信號必需一一列出
 

2.如何參照上面的模組flop,構成一個四位暫存器?

由已經設計成的模組來構成更高一層的模組

參照上面的模組flop,構成一個四位暫存器,程式碼如下:

//hardreg.v
//` include  " flop.v"
module	hardreg(d,clk,clrb,q);
input		clk,clrb;
input[3:0]	d;
output[3:0]	q;

flop	  f1(d[0],clk,clrb,q[0],),   // 注意結束時用逗號,最後才用分號
          f2(d[1],clk,clrb,q[1],),   // 表示f1 到f4 都是flop
          f3(d[2],clk,clrb,q[2],),
f4(d[3],clk,clrb,q[3],);

endmodule

既然四位暫存器的verilog已經出爐了,我最關心的部分已經來了。

3.如何對於上面的四位暫存器進行驗證?

testbench程式碼如下。

//hardreg_top.v
//`include "flop.v"
//`include " hardreg.v"      //模擬時需要包含檔案"hardreg.v" 和 "flop.v" 
/***如果模擬環境可以把有關的檔案安排在一個專案中,只要底層模組經過編譯,並記錄在編譯的庫中,可以不用包含檔案。**/
module  hardreg_top;         //頂層模組,沒有輸入和輸出的埠
reg clock, clearb;           //爲產生測試用的時鐘和清零信號需要暫存器 
reg [3:0] data;           //爲產生測試用數據需要用暫存器
wire [3:0] qout;            //爲觀察輸出信號需要從模組範例埠中引出線

 `define  stim  #100 data=4'b	        //宏定義 stim,可使源程式簡潔
  event  end_first_pass;		        //定義事件end_first_pass

hardreg  reg_4bit (.d(data), .clk(clock), .clrb(clearb), .q(qout));
/************************************************************************
把本模組中產生的測試信號data、clock、clearb輸入範例reg_4bit以觀察輸出信號qout。
範例reg_4bit實際上是已經設計好的模組hardreg。
範例參照的hardreg模組,根據包含檔案的不同, 可以是表示行爲的模組也可以是表示結構的模組。
***********************************************************************/

initial
	begin
	 clock = 0;
	 clearb = 1;
	end	
	
	always #50 clock = ~clock;

	always @(end_first_pass)
	clearb = ~clearb;

	always @(posedge clock)
           $display("at time %0d clearb= %b data= %d qout= %d",
                      $time, clearb, data, qout);
/*****************************************************
    類似於C語言的 printf 語句,可列印不同時刻的信號值
******************************************************/
initial
	begin
	repeat(4)		//重複四次產生下面 下麪的data變化
		begin
			data=4'b0000;
			`stim 0001;
/***************************************************************
			  宏定義stim參照,等同於 #100 data=4'b0001;。注意參照時要用 `符號。
******************************************************/
			`stim 0010;
			`stim 0011;
			`stim 0100;
			`stim 0101;
			`stim 0110;
			`stim 0111;
			`stim 1000;
			`stim 1001;
			`stim 1010;
			`stim 1011;
			`stim 1100;
			`stim 1101;
			`stim 1110;
			`stim 1111;
			#200 -> end_first_pass;
		 end
/***********************************************
延遲200個單位時間,觸發事件end_first_pass
************************************************/
		$finish;		//結束模擬
	end
endmodule

4.既然有了所有的程式碼,就進入linux開始VCS編譯模擬

編譯

 
執行上面的命令,產生的效果如下(多了四個檔案):
 
 

模擬

執行上面的命令,產生的效果如下(是不是多了兩個檔案):

執行./simv -gui開啓DVE圖形化介面

好吧,我暫且認爲是自己的testbench中沒有加$vcdpluson()造成的。

5.重新盤一下第四步爲什麼沒有波形檔案

1、編譯

要想有波形檔案,必須在testbench中加入$vcdpluson類似的的語句,最簡單的格式如下:

initial begin
    $vcdpluson;
end

編譯的時候,必須加上「+vcd+vcdpluson」開關,在模擬時才能 纔能產生波形檔案,使用如下命令編譯:

vcs *.v -l readme.log +v2k  -debug_all +vcd+vcdpluson

vcs  *.v                  就是編譯的主要命令

-l readme.log         就是把編譯過程記錄在檔案readme.log中,以備後面檢視

+v2k                       好像是遵守verilog 2005 標準編譯吧

-debug_all              就是開啓所有的debug開關,還有-debug_pp、-debug

+vcd+vcdpluson     在模擬時才能 纔能產生波形檔案

2.模擬

命令如下:

./simv -l run.log

./simv         就可以生成波形檔案vcdpluson.vpd

-l run.log   把模擬的過程記錄在檔案run.log中,以備後面檢視

3.看波形

dve –vpd vcdpluson.vpd

結果又報錯了,儘管打開了dve,但是打不開波形檔案

修改檔名,繼續!結果不知道爲什麼是這樣!就這樣吧

寫在最後

我現在真的不知道該怎麼學習驗證了。昨天問學長,他怎麼學的verilog,他說就簡單看了一下verilog語法,也沒練習。我該怎麼做呀!有點難搞,炸裂,裂開。