學會使用Hdlbits網頁版Verilog代碼仿真驗證平臺

   給你們推薦一款網頁版的 Verilog代碼編輯仿真驗證平臺,這個平臺是國外的一家開源FPGA學習網站,經過「https://hdlbits.01xz.net/wiki/Main_Page」 地址連接進入網頁,在該網頁上能夠進行Verilog代碼的編寫、綜合,並且最後還可以仿真出波形來驗證設計代碼的正確性,該驗證平臺是基於Icarus Verilog(簡稱iVerilog,比較著名的開源HDL仿真工具,也有對應的安裝版本)的,讓你隨時隨地只需登陸網頁就可以享受Verilog編程仿真的樂趣!編程

1、官方模板演示

一、首先打開「https://hdlbits.01xz.net/wiki/Main_Page」,打開後的界面以下圖所示,全英文顯示。若是感受本身的英文水平欠佳,可使用谷歌瀏覽器打開該網頁,並選擇在線翻譯功能,翻譯的正確率仍是很高的。 瀏覽器

二、點擊Simulation下的 」Run a Simulation(lcarus Verilog)「。  工具

三、打開後的界面以下圖所示,代碼編輯框中給出了一個簡單的例子。學習

 

四、點擊下面的「Submit(new window)「在新界面中進行仿真。   網站

五、在新打開的界面中咱們能夠看到編譯的信息和仿真波形圖。spa

  

2、實例演示 

  雖然看完了官方的模板演示,但咱們要想馬上仿真驗證本身設計的代碼並非那麼容易,須要進行一番摸索。下面就是你們進行一個呼吸燈的設計實例演示。.net

一、學習過FPGA的朋友都知道要想對FPGA邏輯進行仿真必定要具有兩個文件,一個是RTL代碼文件,用來綜合生成硬件電路的部分;第二個就是Testbench文件,用來驗證RTL代碼功能的仿真文件,這二者缺一不可。翻譯

二、根據觀察發現官方模板中的代碼編輯部分有兩個module,你們也都知道一個.v 文件中只能有一個模塊,也就是隻能有一個module,而這裏面有兩個,那確定就不對了。再仔細觀察會發現代碼編輯區域中的上半部分就是Testbench,而下半部分則是RTL代碼,再結合仿真出的波形來更看驗證了這個想法。原來 RTL 代碼和Testbench都寫在了一個編輯框裏。設計

三、可是咱們在提供的模板中發現一些咱們平時幾乎沒有見過的新語法,如第4行的」initial `probe_start「、第6行的」`probe(clk)「、第26行的」`probe(in)「,經過模板的註釋和屢次實驗發現這是官方定義的一個」宏「,也就是經過這個」宏「調用「probe」探針的功能,咱們不用管這個」宏「是如何定義的,咱們只須要會調用就能夠了。3d

四、下面咱們經過該網頁來仿真驗證一下本身設計的呼吸燈的例子。詳細代碼以下(呼吸燈邏輯和Testbench代碼的編寫方法這裏咱們不作講解,會在之後的文章中再進行詳細說明),下面代碼能夠所有直接複製使用(代碼中的註釋請詳細閱讀)。

  1 `timescale    1ns/1ns
  2 
  3 //----------------Tesebench-----------------
  4 module    top_module;      //仿真文件名必須是「top_module」
  5 
  6 reg     sclk;
  7 reg     rst_n;
  8 
  9 wire    led;
 10     
 11 initial `probe_start;      // Start the timing diagram
 12 
 13     `probe(sclk);          // Probe signal "clk",這是加載的系統時鐘,只能在Tesebench中加載    
 14     
 15 //初始化
 16 initial    begin
 17     sclk   = 1'b0;
 18     rst_n <= 1'b0;
 19     #200        
 20     rst_n <= 1'b1;
 21     #5000                   //必定要設置仿真中止時間,若是仿真結束時間過久會提示
 22     $finish; 
 23 end
 24 
 25 //產生20ns的時鐘
 26 always #10 sclk = ~sclk;
 27 
 28 //爲了減小仿真時間咱們在仿真中重定義參數,不影響RTL代碼中參數的值
 29 defparam breath_led_inst.CNT_1US_MAX = 1;
 30 defparam breath_led_inst.CNT_1MS_MAX = 2;
 31 defparam breath_led_inst.CNT_1S_MAX  = 2;
 32 
 33 //----------------breath_led-----------------
 34 breath_led    breath_led_inst(
 35     .sclk   (sclk ),    //input        sclk    
 36     .rst_n  (rst_n),    //input        rst_n    
 37                           
 38     .led    (led  )     //output       led
 39 );
 40 
 41 endmodule    
 42 
 43 //----------------RTL-----------------
 44 module    breath_led
 45 #(
 46     parameter    CNT_1US_MAX = 6'd49,
 47     parameter    CNT_1MS_MAX = 10'd999,
 48     parameter    CNT_1S_MAX  = 10'd999
 49 )
 50 (
 51     input    wire    sclk    ,
 52     input    wire    rst_n    ,
 53     
 54     output   reg     led
 55 );
 56 
 57 reg    [5:0]   cnt_1us;    
 58 reg    [9:0]   cnt_1ms;    
 59 reg    [9:0]   cnt_1s;        
 60 reg            cnt_1us_flag;
 61 reg            cnt_1ms_flag;
 62 reg            cnt_1s_flag;
 63 
 64 //cnt_1us:1us計數器
 65 always@(posedge sclk or negedge rst_n)
 66     if(rst_n == 1'b0)    
 67         cnt_1us <= 6'b0;    
 68     else    if(cnt_1us == CNT_1US_MAX)    
 69         cnt_1us <= 6'b0;
 70     else
 71         cnt_1us <= cnt_1us + 1'b1;
 72 
 73 //cnt_1us_flag:1us計數器標誌信號
 74 always@(posedge sclk or negedge rst_n)
 75     if(rst_n == 1'b0)    
 76         cnt_1us_flag <= 1'b0;    
 77     else    if(cnt_1us == CNT_1US_MAX)    
 78         cnt_1us_flag <= 1'b1;
 79     else
 80         cnt_1us_flag <= 1'b0;
 81 
 82 //cnt_1ms:1ms計數器
 83 always@(posedge sclk or negedge rst_n)
 84     if(rst_n == 1'b0)    
 85         cnt_1ms <= 10'b0;    
 86     else    if(cnt_1ms == CNT_1MS_MAX && cnt_1us_flag == 1'b1)    
 87         cnt_1ms <= 10'b0;
 88     else    if(cnt_1us_flag == 1'b1)
 89         cnt_1ms <= cnt_1ms + 1'b1;
 90         
 91 //cnt_1ms_flag:1ms計數器標誌信號
 92 always@(posedge sclk or negedge rst_n)
 93     if(rst_n == 1'b0)    
 94         cnt_1ms_flag <= 1'b0;    
 95     else    if(cnt_1ms == CNT_1MS_MAX && cnt_1us_flag == 1'b1)    
 96         cnt_1ms_flag <= 1'b1;
 97     else    
 98         cnt_1ms_flag <= 1'b0;
 99 
100 //cnt_1s:1s計數器
101 always@(posedge sclk or negedge rst_n)
102     if(rst_n == 1'b0)    
103         cnt_1s <= 10'b0;    
104     else    if(cnt_1s == CNT_1S_MAX && cnt_1ms_flag == 1'b1)    
105         cnt_1s <= 10'b0;
106     else    if(cnt_1ms_flag == 1'b1)
107         cnt_1s <= cnt_1s + 1'b1;
108 
109 //cnt_1s_flag:1s計數器標誌信號
110 always@(posedge sclk or negedge rst_n)
111     if(rst_n == 1'b0)   
112         cnt_1s_flag <= 1'b0;    
113     else    if(cnt_1s == CNT_1S_MAX && cnt_1ms_flag == 1'b1)    
114         cnt_1s_flag <= ~cnt_1s_flag;    
115     
116 //led:一個LED燈
117 always@(posedge sclk or negedge rst_n)
118     if(rst_n == 1'b0)
119         led <= 1'b0;    
120     else    if((cnt_1s_flag == 1'b1 && cnt_1ms <= cnt_1s) || (cnt_1s_flag == 1'b0 && cnt_1ms > cnt_1s))
121         led <= 1'b1;
122     else    
123         led <= 1'b0;
124     
125 //添加要觀察的信號名
126     `probe(rst_n       );    // Sub-modules can also have `probe()
127     `probe(cnt_1us     );    // Sub-modules can also have `probe()
128     `probe(cnt_1us_flag);    // Sub-modules can also have `probe()
129     `probe(cnt_1ms     );    // Sub-modules can also have `probe()
130     `probe(cnt_1ms_flag);    // Sub-modules can also have `probe()
131     `probe(cnt_1s      );    // Sub-modules can also have `probe()
132     `probe(cnt_1s_flag );    // Sub-modules can also have `probe()
133     `probe(led         );    // Sub-modules can also have `probe()
134 
135 endmodule 

五、將上面編寫好的Testbench代碼和RTL代碼放到一個文件中(Testbench在上面,RTL代碼在下面,僅在該平臺仿真時能夠將兩種文件放在一塊兒,在其餘平臺仿真時要獨立放到兩個.v文件中),而後複製粘貼到代碼編輯框中,點擊「Submit(new window)「執行仿真。 

六、也能夠將寫好的Testbench代碼和RTL代碼放到同一個.v文件中,而後點擊下面的代碼編輯框下面的「Upload a source file...」,在展開的界面中選擇添加.v文件後,再點擊」Upload and simulate」啓動仿真。  

七、仿真波形以下所示,由於界面空間有限,拖動波形顯示框下面的滾動條,能夠看到後面的波形顯示。

八、在波形顯示框中右擊鼠標能夠選擇保存爲PNG格式或SVG格式,將完整的波形信息保存下來。 

九、保存爲SVG格式後的完整波形圖以下所示。

十、若是咱們在第58行處代碼設置一個錯誤後,再點擊執行仿真,此時在仿真窗口中不會顯示波形,而是提示錯誤的內容,將錯誤修改後再執行仿真便可。  

 

十一、該網頁還有其餘更多有趣的功能,如組合邏輯代碼編寫訓練、時序邏輯代碼編寫訓練、單片機嵌入式仿真等等,有興趣的朋友能夠本身探索,這裏再也不一一演示。

歡迎加入FPGA技術學習交流羣,本羣致力於爲廣大FPGAer提供良好的學習交流環境,不按期提供各類本行業相關資料!
QQ交流羣號:450843130 

 

相關文章
相關標籤/搜索