簡談FPGA Verilog testbench

2021-12-23 FPGA設計論壇

大家好,又到了每日學習的時間了,今天我們來聊一聊FPGA中測試文件編寫的相關知識,聊一聊激勵仿真。



        對於testbench而言,埠應當和被測試的module一一對應。埠分為input,output和inout類型產生激勵信號的時候,input對應的埠應當申明為reg, output對應的埠申明為wire,inout埠比較特殊,下面專門講解。

   


        一般用initial塊給信號賦初值,initial塊執行一次,always或者forever表示由事件激發反覆執行。

        舉例,一個module

module exam();

reg rst_n;

reg clk;

reg data;

initial

begin

       clk=1'b0;

       rst=1'b1;

       #10

       rst=1'b0;

       #500

       rst=1'b1;

end

always

begin

       #10

       clk=~clk;

end

        大家應該注意到有個#符號,該符號的意思是指延遲相應的時間單位。該時間單位由timscale決定.一般在testbench的開頭定義時間單位和仿真 精度,比如`timescale 1ns/1ps,前面一個是代表時間單位,後面一個代表仿真時間精度。以上面的例子而言,一個時鐘周期是20個單位,也就是20ns。而仿真時間精度的概 念就是,你能看到1.001ns時對應的信號值,而假如timescale 1ns/1ns,1.001ns時候的值就無法看到。對於一個設計而言,時間刻度應該統一,如果設計文件和testbench裡面的時間刻度不一致,仿真 器默認以testbench為準。一個較好的辦法是寫一個global.v文件,然後用include的辦法,可以防止這個問題。

        對於反覆執行的操作,可寫成task,然後調用,比如

task load_count;

       input [3:0] load_value;

       begin

            @(negedge clk_50);

                     $display($time, " << Loading the counter with %h >>", load_value);

            load_l = 1』b0;

            count_in = load_value;

            @(negedge clk_50);

            load_l = 1』b1;

       end

endtask //of load_count

initial

begin

   load_count(4』hA);   // 調用task

end

        其他像forever,for,function等等語句用法類似,雖然不一定都能綜合,但是用在testbench裡面很方便,大家可以自行查閱參考文檔

   


        有時候,需要大量的數據輸入,直接賦值的話比較繁瑣,可以先生成數據,再將數據讀入到寄存器中,需要時取出即可。用 $readmemb系統任務從文本文件中讀取二進位向量(可以包含輸入激勵和輸出期望值)。$readmemh 用於讀取十六進位文件。例如:

        reg [7:0]   mem[1:256]   //   a 8-bit, 256-word 定義存儲器mem

        initial   $readmemh ( "E:/readhex/mem.dat", mem ) // 將.dat文件讀入寄存器mem中

        initial   $readmemh ( "E:/readhex/mem.dat", mem, 128, 1 ) // 參數為寄存器加載數據的地址始終

     


        對於簡單的module來說,要在modelsim的仿真窗口裡面看波形,就用add wave ..命令

        比如,testbench的頂層module名叫tb,要看時鐘信號,就用add wave tb.clk

        要查看所有信號的時候,就用 add wave /*

        當然,也可以在workspace下的sim窗口裡面右鍵單擊instance來添加波形

        對於複雜的仿真,免不了要記錄波形和數據到文件裡面去。

        1)波形文件記錄

        常見的波形文件一般有兩種,vcd和fsdb,debussy是個很好的工具,支持fsdb,所以最好是modelsim+debussy的組合

        默認情況下,modelsim不認識fsdb,所以需要先裝debussy,再生成fsdb文件。

        $dumpfile和$dumpvar是verilog語言中的兩個系統任務,可以調用這兩個系統任務來創建和將指定信息導入VCD文件.

        對於fsdb文件來說,對應的命令是fsdbDumpfile,dumpfsdbvars

        (什麼是VCD文件? 答:VCD文件是在對設計進行的仿真過程中,記錄各種信號取值變化情況的信息記錄文件。EDA工具通過讀取VCD格式的文件,顯示圖形化的仿真波形,所以,可以把VCD文件簡單地視為波形記錄文件.)下面分別描述它們的用法並舉例說明之。

        $dumpfile系統任務:為所要創建的VCD文件指定文件名。

        舉例("//"符號後的內容為注釋文字):

        initial

        $dumpfile ("myfile.dump"); //指定VCD文件的名字為myfile.dump,仿真信息將記錄到此文件

        $dumpvar系統任務:指定需要記錄到VCD文件中的信號,可以指定某一模塊層次上的所有信號,也可以單獨指定某一個信號。

        典型語法為$dumpvar(level, module_name); 參數level為一個整數,用於指定層次數,參數module則指定要記錄的模塊。整句的意思就是,對於指定的模塊,包括其下各個層次(層次數由 level指定)的信號,都需要記錄到VCD文件中去。

        舉例:

        initial

        $dumpvar (0, top); //指定層次數為0,則top模塊及其下面各層次的所有信號將被記錄

        initial

        $dumpvar (1, top); //記錄模塊實例top以下一層的信號

        //層次數為1,即記錄top模塊這一層次的信號

        //對於top模塊中調用的更深層次的模塊實例,則不記錄其信號變化

        initial

        $dumpvar (2, top); //記錄模塊實例top以下兩層的信號

        //即top模塊及其下一層的信號將被記錄

        假設模塊top中包含有子模塊module1,而我們希望記錄top.module1模塊以下兩層的信號,則語法舉例如下:

        initial

        $dumpvar (2, top.module1); //模塊實例top.module1及其下一層的信號將被記錄

        假設模塊top包含信號signal1和signal2(注意是變量而不是子模塊), 如我們希望只記錄這兩個信號,則語法舉例如下:

        initial

        $dumpvar (0, top.signal1, top.signal2); //雖然指定了層次數,但層次數是不影響單獨指定的信號的

        //即指定層次數和單獨指定的信號無關

        我們甚至可以在同一個$dumpvar的調用中,同時指定某些層次上的所有信號和某個單獨的信號,假設模塊top包含信號signal1,同時包含有子模 塊module1,如果我們不但希望記錄signal1這個獨立的信號,而且還希望記錄子模塊module1以下三層的所有信號,則語法舉例如下:

        initial

        $dumpvar (3, top.signal1, top.module1); //指定層次數和單獨指定的信號無關

        //所以層次數3隻作用於模塊top.module1, 而與信號

        top.signal1無關

        上面這個例子和下面的語句是等效的:

        initial

        begin

        $dumpvar (0, top.signal1);

        $dumpvar (3, top.module1);

        end

        $dumpvar的特別用法(不帶任何參數):

        initial

        $dumpvar; //無參數,表示設計中的所有信號都將被記錄

        最後,我們將$dumpfile和$dumpvar這兩個系統任務的使用方法在下面的例子中綜合說明,假設我們有一個設計實例,名為 i_design,此設計中包含模塊module1,模塊module1下面還有很多層次,我們希望對這個設計進行仿真,並將仿真過程中模塊 module1及其以下所有層次中所有信號的變化情況,記錄存儲到名為mydesign.dump的VCD文件中去,則例示如下:

        initial

        begin

        $dumpfile ("mydesign.dump"); //指定VCD文件名為mydesign.dump

        $dumpvar (0, i_design.module1); //記錄i_design.module1模塊及其下面層次中所有模塊的所有信號

        end

        對於生成fsdb文件而言,也是類似的

        initial

              begin

                 $fsdbDumpfile("tb_xxx.fsdb");

                 $fsdbDumpvars(0,tb_xxx);   

              end

        2)文件輸出結果

        integer out_file;   // out_file 是一個文件描述,需要定義為 integer類型

        out_file = $fopen ( " cpu.data " ); // cpu.data 是需要打開的文件,也就是最終的輸出文本

        設計中的信號值可以通過$fmonitor, $fdisplay,$fwrite

        其中$fmonitor只要有變化就一直記錄,$fdisplay和$fwrite需要觸發條件才記錄

        例子:

        initial begin

            $fmonitor(file_id, "%m: %t in1=%d o1=%h", $time, in1, o1);

        end

  

        always@(a or b)

        begin

           $fwrite(file_id,"At time%t a=%b b=%b",$realtime,a,b);

        end

   


        1).如果激勵中有一些重複的項目,可以考慮將這些語句編寫成一個task,這樣會給書寫和仿真帶來很大方便。例如,一個存儲器的testbench的激勵可以包含write,read等task。

        2).如果DUT中包含雙向信號(inout),在編寫testbench時要注意。需要一個reg變量來表示其輸入,還需要一個wire變量表示其輸出。

        3).如果initial塊語句過於複雜,可以考慮將其分為互補相干的幾個部分,用數個initial塊來描述。在仿真時,這些initial塊會並發運行。這樣方便閱讀和修改。

        4).每個testbench都最好包含$stop語句,用以指明仿真何時結束。

        5).加載測試向量時,避免在時鐘的上下沿變化,比如數據最好在時鐘上升沿之前變化,這也符合建立時間的要求。



module counter (clk, reset, enable, count);

input clk, reset, enable;

output [3:0] count;

reg [3:0] count;                                 

  

always @ (posedge clk)

if (reset == 1'b1) begin

count <= 0;

end else if ( enable == 1'b1) begin

count <= count + 1;

end

  

endmodule

testbench

module counter_tb;

reg clk, reset, enable;

wire [3:0] count;

   

counter U0 (

.clk (clk),

.reset   (reset),

.enable (enable),

.count   (count)

);

   

initial begin

   clk = 0;

   reset = 0;

   enable = 0;

end

   

always  

   #5   clk =   ! clk;

   

initial   begin

   $dumpfile ("counter.vcd");

   $dumpvars;

end

   

initial   begin

   $display("\t\ttime,\tclk,\treset,\tenable,\tcount");

   $monitor("‰d,\t‰b,\t‰b,\t‰b,\t‰d",$time, clk,reset,enable,count);

end

   

initial

    #100   $finish;

   

//Rest of testbench code after this line

   

   endmodule

   


        晶片外部引腳很多都使用inout類型的,為的是節省管腿。一般信號線用做總線等雙向數據傳輸的時候就要用到INOUT類型了。就是一個埠同時做輸入和 輸出。inout在具體實現上一般用三態門來實現。三態門的第三個狀態就是高阻'Z'。當inout埠不輸出時,將三態門置高阻。這樣信號就不會因為兩端同時 輸出而出錯了,更詳細的內容可以搜索一下三態門tri-state的資料.

        1 使用inout類型數據,可以用如下寫法:

inout data_inout;

input data_in;

reg data_reg;//data_inout的映象寄存器

reg link_data;

assign data_inout=link_data?data_reg:1』bz;//link_data控制三態門

        //對於data_reg,可以通過組合邏輯或者時序邏輯根據data_in對其賦值.通過控制link_data的高低電平,從而設置data_inout是輸出數據還是處於高阻態,如果處於高阻態,則此時當作輸入埠使用.link_data可以通過相關電路來控制.

        2 編寫測試模塊時,對於inout類型的埠,需要定義成wire類型變量,而其它輸入埠都定義成reg類型,這兩者是有區別的.

        當上面例子中的data_inout用作輸入時,需要賦值給data_inout,其餘情況可以斷開.此時可以用assign語句實現:assign data_inout=link?data_in_t:1』bz;其中的link ,data_in_t是reg類型變量,在測試模塊中賦值.

        另外,可以設置一個輸出埠觀察data_inout用作輸出的情況:

Wire data_out;

Assign data_out_t=(!link)?data_inout:1』bz;

else,in RTL

inout use in top module(PAD)

dont use inout(tri) in sub module

        也就是說,在內部模塊最好不要出現inout,如果確實需要,那麼用兩個port實現,到頂層的時候再用三態實現。理由是:在非頂層模塊用雙向口的話,該 雙向口必然有它的上層跟它相連。既然是雙向口,則上層至少有一個輸入口和一個輸出口聯到該雙向口上,則發生兩個內部輸出單元連接到一起的情況出現,這樣在 綜合時往往會出錯。

        對雙向口,我們可以將其理解為2個分量:一個輸入分量,一個輸出分量。另外還需要一個控制信號控制輸出分量何時輸出。此時,我們就可以很容易地對雙向埠建模。

例子:

CODE:

module dual_port (

....

inout_pin,

....

);

inout inout_pin;

wire inout_pin;

wire input_of_inout;

wire output_of_inout;

wire out_en;

assign input_of_inout = inout_pin;

assign inout_pin = out_en ? output_of_inout : 高阻;

endmodule

        可見,此時input_of_inout和output_of_inout就可以當作普通信號使用了。

        在仿真的時候,需要注意雙向口的處理。如果是直接與另外一個模塊的雙向口連接,那麼只要保證一個模塊在輸出的時候,另外一個模塊沒有輸出(處於高阻態)就可以了。

如果是在ModelSim中作為單獨的模塊仿真,那麼在模塊輸出的時候,不能使用force命令將其設為高阻態,而是使用release命令將總線釋放掉

        很多初學者在寫testbench進行仿真和驗證的時候,被inout雙向口難住了。仿真器老是提示錯誤不能進行。下面是我個人對inout埠寫 testbench仿真的一些總結,並舉例進行說明。在這裡先要說明一下inout口在testbench中要定義為wire型變量。

        先假設有一原始碼為:

module xx(data_inout , ...);

inout data_inout;

....

assign data_inout=(! link)?datareg:1'bz;

endmodule

方法一:使用相反控制信號inout口,等於兩個模塊之間用inout雙向口互連。這種方法要注意assign 語句只能放在initial和always塊內。

module test();

wire data_inout;

reg data_reg;

reg link;

initial begin

end

assign data_inout=link?data_reg:1'bz;

endmodule

方法二:使用force和release語句,但這種方法不能準確反映雙向埠的信號變化,但這種方法可以反在塊內。

module test();

wire data_inout;

reg data_reg;

reg link;

#xx;        //延時

force data_inout=1'bx;           //強制作為輸入埠

#xx;

release data_inout;       //釋放輸入埠

endmodule

        很多讀者反映仿真雙向埠的時候遇到困難,這裡介紹一下雙向埠的仿真方法。一個典型的雙向埠如圖1所示。

        其中inner_port與晶片內部其他邏輯相連,outer_port為晶片外部管腳,out_en用於控制雙向埠的方向,out_en為1時,埠為輸出方向,out_en為0時,埠為輸入方向。

用Verilog語言描述如下:

module bidirection_io(inner_port,out_en,outer_port);

input out_en;

inout[7:0] inner_port;

inout[7:0] outer_port;

assign outer_port=(out_en==1)?inner_port:8'hzz;

assign inner_port=(out_en==0)?outer_port:8'hzz;

endmodule

用VHDL語言描述雙向埠如下:

library ieee;

use IEEE.STD_LOGIC_1164.ALL;

entity bidirection_io is

port ( inner_port : inout std_logic_vector(7 downto 0);

out_en : in std_logic;

outer_port : inout std_logic_vector(7 downto 0) );

end bidirection_io;

architecture behavioral of bidirection_io is

begin

outer_port<=inner_port when out_en='1' else (OTHERS=>'Z');

inner_port<=outer_port when out_en='0' else (OTHERS=>'Z');

end behavioral;

        仿真時需要驗證雙向埠能正確輸出數據,以及正確讀入數據,因此需要驅動out_en埠,當out_en埠為1時,testbench驅動 inner_port埠,然後檢查outer_port埠輸出的數據是否正確;當out_en埠為0時,testbench驅動 outer_port埠,然後檢查inner_port埠讀入的數據是否正確。由於inner_port和outer_port埠都是雙向埠(在 VHDL和Verilog語言中都用inout定義),因此驅動方法與單向埠有所不同。

        驗證該雙向埠的testbench結構如圖2所示。

        這是一個self-checking testbench,可以自動檢查仿真結果是否正確,並在Modelsim控制臺上列印出提示信息。圖中Monitor完成信號採樣、結果自動比較的功能。

        testbench的工作過程為

        1)out_en=1時,雙向埠處於輸出狀態,testbench給inner_port_tb_reg信號賦值,然後讀取outer_port_tb_wire的值,如果兩者一致,雙向埠工作正常。

        2)out_en=0時,雙向埠處於輸如狀態,testbench給outer_port_tb_reg信號賦值,然後讀取inner_port_tb_wire的值,如果兩者一致,雙向埠工作正常。

        用Verilog代碼編寫的testbench如下,其中使用了自動結果比較,隨機化激勵產生等技術。

`timescale 1ns/10ps

module tb();

reg[7:0] inner_port_tb_reg;

wire[7:0] inner_port_tb_wire;

reg[7:0] outer_port_tb_reg;

wire[7:0] outer_port_tb_wire;

reg out_en_tb;

integer i;

initial

begin

out_en_tb=0;

inner_port_tb_reg=0;

outer_port_tb_reg=0;

i=0;

repeat(20)

begin

#50

i=$random;

out_en_tb=i[0]; //randomize out_en_tb

inner_port_tb_reg=$random; //randomize data

outer_port_tb_reg=$random;

end

end

//**** drive the ports connecting to bidirction_io

assign inner_port_tb_wire=(out_en_tb==1)?inner_port_tb_reg:8'hzz;

assign outer_port_tb_wire=(out_en_tb==0)?outer_port_tb_reg:8'hzz;

//instatiate the bidirction_io module

bidirection_io bidirection_io_inst(.inner_port(inner_port_tb_wire),

.out_en(out_en_tb),

.outer_port(outer_port_tb_wire));

//***** monitor ******

always@(out_en_tb,inner_port_tb_wire,outer_port_tb_wire)

begin

#1;

if(outer_port_tb_wire===inner_port_tb_wire)

begin

$display("\n **** time=%t ****",$time);

$display("OK! out_en=%d",out_en_tb);

$display("OK! outer_port_tb_wire=%d,inner_port_tb_wire=%d",

outer_port_tb_wire,inner_port_tb_wire);

end

else

begin

$display("\n **** time=%t ****",$time);

$display("ERROR! out_en=%d",out_en_tb);

$display("ERROR! outer_port_tb_wire != inner_port_tb_wire" );

$display("ERROR! outer_port_tb_wire=%d, inner_port_tb_wire=%d",

outer_port_tb_wire,inner_port_tb_wire);

end

end

endmodule







   

歡迎關注至芯科技

至芯官網:www.zxopen.com

至芯科技技術論壇:www.fpgaw.com

至芯科技淘寶網址:

https://shop101836044.taobao.com/spm=a230r.7195193.1997079397.2.9gJ436

至芯科技FPGA初級課程 :

https://ww.bilibili.com/video/BV1Yh411d733?from=search&seid=10043829254555203948 

至芯科技-FPGA 交流群(QQ):282124839

點擊觀看FPGA初級課程

  



相關焦點

  • FPGA中的testbench
    testbench就是對寫的FPGA文件進行測試的文件,可以是verilog也可以是VHDL。verilog和VHDL的國際標準裡面有很多不能被綜合實現的語句,比如initial,forever,repeat,延時語句#1等等,這些語句就是用來測試的時候使用的。運行環境一般是ise或者vivado或者quartus自帶的仿真工具,或者如modelsim一樣的第三方仿真工具。
  • 十天學會FPGA之三——testbench的寫法
    廢話不多說直接上乾貨,testbench就是對寫的FPGA文件進行測試的文件,可以是verilog也可以是VHDL
  • FPGA開發分析一個testbench
    分析Xilinx提供的testbench可以為我們編寫自己的testbench提供很好的參考。FIFO的RTL代碼和testbench代碼放在ISEexamples\fifo_ver_131和fifo_vhd_131下。
  • 零基礎學FPGA(十五)Testbenth 很重要,前仿真全過程筆記(上篇)
    這次課程,小墨同學將和大家從建立工程開始,一步步梳理testbench的書寫過程,幫助大家對仿真有一個深刻的概念。以後在做項目時,不要動不動就把程序下到板子裡調試,看問題不對再去改程序,再下到板子裡調試,如此往返,會浪費大量的時間,簡單的項目還好,但是到了大型項目的話,是不可能有這麼多時間讓我們這樣調的。因此,小墨同學在這裡說,testbench很重要,做好了仿真,可以為我們節約大量的開發時間。
  • VHDL與Verilog硬體描述語言TestBench的編寫
    module test_bench; 埠聲明語句 library ieee; --庫聲明use ieee.std_logic_1164.all;entity test_bench
  • 通過點燈的邏輯體驗FPGA的編程流程以及Verilog語法基礎
    assign led = 1'b0; endmodule編譯分配管腳(查找管腳映射表,通過電路圖或項目中的表格)生成jed文件查看資源佔用情況下載到16管腳的FPGA模塊上項目2 - 讓LED燈跳動起來在module的埠中添加clk的輸入信號在verilog
  • DUT 和 testbench 是如何連接的
    總體來說,接口就是在 testbench 這邊定義了訪問的 DUT 的管腳的集合,通過對接口中管腳信號的操作,來實現對 DUT 的管腳的操作, 這樣能夠實現驗證平臺和待測模塊的分離。驗證工程師和設計工程師只要定義好接口關係,就可以分別開展工作。
  • 零基礎學FPGA(五)Verilog語法基基礎基礎(下)
    (3)時間度量系統函數$time  在verilog hdl語法中有兩種時間度量系統函數,分別是$time和$realtime,用這兩個系統函數可以得到當前的仿真時刻。$time可以返回一個64位的值來記錄當前的仿真時刻。  (4)$finish  系統任務$finish的作用是退出仿真器,返回主作業系統,也就是結束仿真過程。
  • Verilog 裡面,always,assign和always@(*)區別
    2.如果沒有@,那就是不會滿足特定條件才執行,而是執行完一次後立馬執行下一次,一直重複執行,比如testbench裡面產生50Mhz的時鐘就(假設時間尺度是1ns)可以寫成 一般always@(*)是指裡面的語句是組合邏輯的。*代替了敏感變量。
  • Cordic算法(sinx,cosx)的Verilog實現
    在某些特殊情況,比如asic開發,現有的編譯軟體自帶的IP核是不能使用的,比如我最近需要做的東西,需要的信號發生器(正弦波發生器)就只能自己使用verilog進行實現。(一個周期內採集了 2^{18} 個點)testbench是用戶自己編寫,由於cordic實際上只需要計算[0,90°]的正餘弦即可獲得整個周期的函數值,但是,sinx與cosx在使用cordic算法時,接近0,90,180,270,360時會出現極大的誤差,單純使用cordic27級流水線最終在這些點處的誤差大約為 10^{-4},10^{-5} 量級。
  • 基於FPGA的任意分頻器設計
    以10分頻為例,相應的verilog代碼如下:  regclk_div10;  reg [2:0]cnt;  always@(posedge clk or posedge rst) begin  if(rst)begin //復位  cnt<=0;  clk_div10<=0;  end
  • (轉載)如何學習FPGA
    一、入門首先要掌握HDL(HDL=verilog+VHDL)。       第一句話是:還沒學數電的先學數電。
  • Verilog 最全經驗總結(建議收藏)
    如果是在ModelSim中作為單獨的模塊仿真,那麼在模塊輸出的時候,不能使用force命令將其設為高阻態,而是使用release命令將總線釋放掉很多初學者在寫testbench進行仿真和驗證的時候,被inout雙向口難住了。仿真器老是提示錯誤不能進行。下面是我個人對inout埠寫testbench仿真的一些總結,並舉例進行說明。
  • FPGA程式語言——verilog語法
    簡單的組合電路 always@(a or b) // 只要其中a或b一個變化就執行always塊內語句 begin if(en) // verilog .c(c_sum)//埠連接輸出 );endmodule這個小程序表述了一個.v文件包含了常用的verilog
  • 零基礎學FPGA(四)Verilog語法基基礎基礎(中)
    fpga相關文章:fpga是什麼 c語言相關文章:c語言教程
  • 詳解MySQL基準測試和sysbench工具
    /configureexport LD_LIBRARY_PATH=/usr/local/mysql/include #這裡換成機器中mysql路徑下的includemakemake install[root@test sysbench-1.0]# sysbench --versionsysbench 1.0.9sysbench語法執行
  • 詳解 MySQL 基準測試和sysbench工具
    sysbench-1.0]# sysbench --versionsysbench 1.0.9sysbench語法執行sysbench –help,可以看到sysbench的詳細使用方法。2.testname testname指定了要進行的測試,在老版本的sysbench中,可以通過--test參數指定測試的腳本;而在新版本中,--test參數已經聲明為廢棄,可以不使用--test,而是直接指定腳本。例如,如下兩種方法效果是一樣的:sysbench --test=.
  • 詳解 MySQL 基準測試和 sysbench 工具
    ; sysbench-1.0]# sysbench --versionsysbench 1.0.93、sysbench語法執行sysbench –help,可以看到sysbench的詳細使用方法。(2)testnametestname指定了要進行的測試,在老版本的sysbench中,可以通過–test參數指定測試的腳本;而在新版本中,–test參數已經聲明為廢棄,可以不使用–test,而是直接指定腳本。例如,如下兩種方法效果是一樣的:sysbench --test=.
  • 關於學習verilog
    以前在學校的時候,總是覺得將RTL級代碼做好就行了,仿真驗證只是形式而已,所以對HDL的行為描述方面的語法不屑一顧,對testbench也一直不願意去學--因為覺得畫波形圖方便;對於系統結構設計更是一點都不懂了。  到了公司接觸了些東西才發現完全不是這樣。