专栏首页FPGA开源工作室学会使用Hdlbits网页版Verilog代码仿真验证平台

学会使用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”,

打开后的界面如下图所示,全英文显示。如果感觉自己的英文水平欠佳,可以使用谷歌浏览器打开该网页,并选择在线翻译功能,翻译的正确率还是很高的。

2、点击Simulation下的 ”Run a Simulation(lcarus Verilog)“。

3、打开后的界面如下图所示,代码编辑框中给出了一个简单的例子。

4、点击下面的“Submit(new window)“在新界面中进行仿真。

5、在新打开的界面中我们可以看到编译的信息和仿真波形图。

二、实例演示

虽然看完了官方的模板演示,但我们要想立刻仿真验证自己设计的代码并不是那么容易,需要进行一番摸索。下面就是大家进行一个呼吸灯的设计实例演示。

1、学习过FPGA的朋友都知道要想对FPGA逻辑进行仿真一定要具备两个文件,一个是RTL代码文件,用来综合生成硬件电路的部分;第二个就是Testbench文件,用来验证RTL代码功能的仿真文件,这两者缺一不可。

2、根据观察发现官方模板中的代码编辑部分有两个module,大家也都知道一个.v 文件中只能有一个模块,也就是只能有一个module,而这里面有两个,那肯定就不对了。再仔细观察会发现代码编辑区域中的上半部分就是Testbench,而下半部分则是RTL代码,再结合仿真出的波形来更看验证了这个想法。原来 RTL 代码和Testbench都写在了一个编辑框里。

3、但是我们在提供的模板中发现一些我们平时几乎没有见过的新语法,如第4行的”initial `probe_start“、第6行的”`probe(clk)“、第26行的”`probe(in)“,通过模板的注释和多次实验发现这是官方定义的一个”宏“,也就是通过这个”宏“调用“probe”探针的功能,我们不用管这个”宏“是如何定义的,我们只需要会调用就可以了。

4、下面我们通过该网页来仿真验证一下自己设计的呼吸灯的例子。详细代码如下(呼吸灯逻辑和Testbench代码的编写方法这里我们不做讲解,会在以后的文章中再进行详细说明),标红处的注释是需要特别强调的(代码可以全部直接复制使用)。

`timescale1ns/1ns
//-------------------Tesebench--------------------
moduletop_module;       //仿真文件名必须是“top_module”
reg    sclk;
reg    rst_n;
wire   led;
initial `probe_start;   // Start the timing diagram
    `probe(sclk);         // Probe signal"clk",这是加载的系统时钟,只能在Tesebench中加载   
//初始化
initial    begin
    sclk   =1'b0;
    rst_n <= 1'b0;
    #200
    rst_n <= 1'b1;
    #5000                 //一定要设置仿真停止时间,如果仿真结束时间太久会提示
    $finish;
end
//产生20ns的时钟
always#10sclk =~sclk;
//为了减少仿真时间我们在仿真中重定义参数,不影响RTL代码中参数的值
defparam   breath_led_inst.CNT_1US_MAX = 1;
defparam   breath_led_inst.CNT_1MS_MAX  = 2;
defparam   breath_led_inst.CNT_1S_MAX   =2;

//-------------------breath_led--------------------
breath_ledbreath_led_inst(
    .sclk  (sclk  ),  //input    sclk  
    .rst_n(rst_n),  //input    rst_n 
    .led    (led  )   //output   led
);
endmodule 
//--------------------------------------------------
//-----------------------RTL------------------------
modulebreath_led
#(
    parameter  CNT_1US_MAX =6'd49,
    parameter  CNT_1MS_MAX =10'd999,
    parameter  CNT_1S_MAX  =10'd999
)
(
    input  wire   sclk   ,
    input  wire   rst_n  ,
    outputreg    led
);

reg[5:0]  cnt_1us;  
reg[9:0]  cnt_1ms;  
reg[9:0]  cnt_1s;

reg        cnt_1us_flag;
reg        cnt_1ms_flag;
reg        cnt_1s_flag;
//cnt_1us:1us计数器

always@(posedgesclk ornegedgerst_n)
    if(rst_n ==1'b0)
       cnt_1us <=6'b0; 
    else   if(cnt_1us== CNT_1US_MAX)  
       cnt_1us <=6'b0;
    else
       cnt_1us <=cnt_1us + 1'b1;
//cnt_1us_flag:1us计数器标志信号

always@(posedgesclk ornegedgerst_n)
    if(rst_n ==1'b0)
       cnt_1us_flag <= 1'b0;   
    else   if(cnt_1us==  CNT_1US_MAX) 
       cnt_1us_flag <= 1'b1;
    else
       cnt_1us_flag <= 1'b0;
//cnt_1ms:1ms计数器

always@(posedgesclk ornegedgerst_n)
    if(rst_n ==1'b0)
       cnt_1ms <=10'b0;
    else   if(cnt_1ms==  CNT_1MS_MAX && cnt_1us_flag ==1'b1)  
       cnt_1ms <=10'b0;
    else   if(cnt_1us_flag ==1'b1)
       cnt_1ms <=cnt_1ms + 1'b1;     

//cnt_1ms_flag:1ms计数器标志信号

always@(posedgesclk ornegedgerst_n)
    if(rst_n ==1'b0)
       cnt_1ms_flag  <=  1'b0; 
    else   if(cnt_1ms==  CNT_1MS_MAX && cnt_1us_flag ==1'b1)  
       cnt_1ms_flag <= 1'b1;
    else  
       cnt_1ms_flag <= 1'b0;
//cnt_1s:1s计数器

always@(posedgesclk ornegedgerst_n)
    if(rst_n ==1'b0)
       cnt_1s<=  10'b0;
    else   if(cnt_1s ==CNT_1S_MAX &&cnt_1ms_flag ==1'b1)
       cnt_1s<=  10'b0;
    else   if(cnt_1ms_flag ==1'b1)
       cnt_1s<=  cnt_1s+1'b1;
//cnt_1s_flag:1s计数器标志信号

always@(posedgesclk ornegedgerst_n)
    if(rst_n ==1'b0)
       cnt_1s_flag <= 1'b0;
    else   if(cnt_1s ==CNT_1S_MAX &&cnt_1ms_flag ==1'b1)
       cnt_1s_flag <= ~cnt_1s_flag;   
//led:一个LED灯

always@(posedgesclk ornegedgerst_n)
    if(rst_n ==1'b0)
       led<=1'b0;  
    else   if((cnt_1s_flag ==1'b1 &&cnt_1ms <= cnt_1s)|| (cnt_1s_flag  == 1'b0 &&cnt_1ms >cnt_1s))
       led<=1'b1;
    else  
       led<=1'b0;
//添加要观察的信号名

    `probe(rst_n          );  //Sub-modules can also have `probe()
    `probe(cnt_1us        );  //Sub-modules can also have `probe()
    `probe(cnt_1us_flag  );  //Sub-modules can also have `probe()
    `probe(cnt_1ms       );  //Sub-modules can also have `probe()
    `probe(cnt_1ms_flag  );  //Sub-modules can also have `probe()
    `probe(cnt_1s         );  //Sub-modules can also have `probe()
    `probe(cnt_1s_flag   );  //Sub-modules can also have `probe()
    `probe(led            );  //Sub-modules can also have `probe()
endmodule
//--------------------------------------------------

5、将上面编写好的Testbench代码和RTL代码放到一个文件中(Testbench在上面,RTL代码在下面,仅在该平台仿真时可以将两种文件放在一起,在其他平台仿真时要独立放到两个.v文件中),然后复制粘贴到代码编辑框中,点击“Submit(new window)“执行仿真。

6、也可以将写好的Testbench代码和RTL代码放到同一个.v文件中,然后点击下面的代码编辑框下面的“Upload a source file...”,在展开的界面中选择添加.v文件后,再点击”Upload and simulate”启动仿真。

7、仿真波形如下所示,因为界面空间有限,拖动波形显示框下面的滚动条,可以看到后面的波形显示。

8、在波形显示框中右击鼠标可以选择保存为PNG格式或SVG格式,将完整的波形信息保存下来。

9、保存为SVG格式后的完整波形图如下所示。

10、如果我们在第58行处代码设置一个错误后,再点击执行仿真,此时在仿真窗口中不会显示波形,而是提示错误的内容,将错误修改后再执行仿真即可。

11、该网页还有其他更多有趣的功能,如组合逻辑代码编写训练、时序逻辑代码编写训练、单片机嵌入式仿真等等,有兴趣的朋友可以自己探索,这里不再一一演示。

本文分享自微信公众号 - FPGA开源工作室(leezym0317),作者:相量子

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • FPGA图像处理之高斯滤波算法理论篇

    对计算机视觉、多媒体应用、通信技术等领域来说,实时的数字图像处理是其中的重点学科之一。传统的前端数字信号处理(Digital SignalProcessing...

    FPGA开源工作室
  • 基于FPGA的比特平面分层

    像素是由比特组成的数字。例如,在256级灰度图像中,每个像素的灰度是由8比特(也就是1个字节)组成。一幅8比特图像可以认为由8个1比特平面组成,如图1所示,其中...

    FPGA开源工作室
  • Matlab音频信号的基本处理与分析

    info =audioinfo('sample_orig.mp3');%获取音频文件的信息

    FPGA开源工作室
  • 再谈systemverilog中automatic与static

    如果变量被声明为automatic,那么进入该方法后,就会自动创建,离开该方法后,就会被销毁;而static则是在仿真开始时就会被创建,直到仿真结束,可以被多个...

    数字IC小站
  • 基于basys2用verilog设计多功能数字钟(重写)

    话不多说先上图 ? 前言          自从学习FPGA以来,唯一做过的完整系统就是基于basys2得多功能数字表。记得当时做的时候也没少头疼,最后用时间磨...

    NingHeChuan
  • Kaggle :第二届 YouTube-8M 视频理解挑战赛

    朱晓霞
  • 攻击者侵入系统后如何提升账户权限:提权技术详细分析

    提权 通常而言,恶意攻击者侵入到某个系统最初往往只能获取到一个普通权限的账户。但这无疑给进一步的渗透带来了阻碍,因此攻击者会开始尝试通过各种手段来提升自己的账户...

    FB客服
  • iOS开发中利用MJExtension进行归档

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

    用户1451823
  • 解密网络安全重武器-态势感知

    本期来和大家一起解密态势感知,目前国内外无论安全厂商还是ICT厂商都在紧跟网络安全最新趋势,也都陆续推出各家的态势感知产品。刚刚发布的等保2.0也明...

    ICT售前新说
  • SAP 采购订单如何设定最早收货及最晚收货?

    SAP采购订单标准功能中可以设置采购订单最早不能早于某个日期,最晚不能晚于某个日期收货,用于控制采购入库,具体操作及设定如下:

    用户5495712

扫码关注云+社区

领取腾讯云代金券