学会使用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代码的编写方法这里我们不做讲解,会在以后的文章中再进行详细说明),下面代码可以全部直接复制使用(代码中的注释请详细阅读)。
`timescale 1ns/1ns //----------------Tesebench-----------------
module top_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 = 'b0;
rst_n <= 'b0;
#
rst_n <= 'b1;
# //一定要设置仿真停止时间,如果仿真结束时间太久会提示
$finish;
end //产生20ns的时钟
always #10 sclk = ~sclk; //为了减少仿真时间我们在仿真中重定义参数,不影响RTL代码中参数的值
defparam breath_led_inst.CNT_1US_MAX = ;
defparam breath_led_inst.CNT_1MS_MAX = ;
defparam breath_led_inst.CNT_1S_MAX = ; //----------------breath_led-----------------
breath_led breath_led_inst(
.sclk (sclk ), //input sclk
.rst_n (rst_n), //input rst_n .led (led ) //output led
); endmodule //----------------RTL-----------------
module breath_led
#(
parameter CNT_1US_MAX = 'd49,
parameter CNT_1MS_MAX = 'd999,
parameter CNT_1S_MAX = 'd999
)
(
input wire sclk ,
input wire rst_n , output reg led
); reg [:] cnt_1us;
reg [:] cnt_1ms;
reg [:] cnt_1s;
reg cnt_1us_flag;
reg cnt_1ms_flag;
reg cnt_1s_flag; //cnt_1us:1us计数器
always@(posedge sclk or negedge rst_n)
if(rst_n == 'b0)
cnt_1us <= 'b0;
else if(cnt_1us == CNT_1US_MAX)
cnt_1us <= 'b0;
else
cnt_1us <= cnt_1us + 'b1; //cnt_1us_flag:1us计数器标志信号
always@(posedge sclk or negedge rst_n)
if(rst_n == 'b0)
cnt_1us_flag <= 'b0;
else if(cnt_1us == CNT_1US_MAX)
cnt_1us_flag <= 'b1;
else
cnt_1us_flag <= 'b0; //cnt_1ms:1ms计数器
always@(posedge sclk or negedge rst_n)
if(rst_n == 'b0)
cnt_1ms <= 'b0;
else if(cnt_1ms == CNT_1MS_MAX && cnt_1us_flag == 'b1)
cnt_1ms <= 'b0;
else if(cnt_1us_flag == 'b1)
cnt_1ms <= cnt_1ms + 'b1; //cnt_1ms_flag:1ms计数器标志信号
always@(posedge sclk or negedge rst_n)
if(rst_n == 'b0)
cnt_1ms_flag <= 'b0;
else if(cnt_1ms == CNT_1MS_MAX && cnt_1us_flag == 'b1)
cnt_1ms_flag <= 'b1;
else
cnt_1ms_flag <= 'b0; //cnt_1s:1s计数器
always@(posedge sclk or negedge rst_n)
if(rst_n == 'b0)
cnt_1s <= 'b0;
else if(cnt_1s == CNT_1S_MAX && cnt_1ms_flag == 'b1)
cnt_1s <= 'b0;
else if(cnt_1ms_flag == 'b1)
cnt_1s <= cnt_1s + 'b1; //cnt_1s_flag:1s计数器标志信号
always@(posedge sclk or negedge rst_n)
if(rst_n == 'b0)
cnt_1s_flag <= 'b0;
else if(cnt_1s == CNT_1S_MAX && cnt_1ms_flag == 'b1)
cnt_1s_flag <= ~cnt_1s_flag; //led:一个LED灯
always@(posedge sclk or negedge rst_n)
if(rst_n == 'b0)
led <= 'b0;
else if((cnt_1s_flag == 'b1 && cnt_1ms <= cnt_1s) || (cnt_1s_flag == 1'b0 && cnt_1ms > cnt_1s))
led <= 'b1;
else
led <= '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技术学习交流群,本群致力于为广大FPGAer提供良好的学习交流环境,不定期提供各种本行业相关资料!
QQ交流群号:450843130

学会使用Hdlbits网页版Verilog代码仿真验证平台的更多相关文章
- verilog代码 想法验证---与寄存器输出有关
verilog代码 想法验证---与寄存器输出有关 1. module test_mind( input wire clk, input wire reset, input wire i, outpu ...
- verilog 代码分析与仿真
verilog 代码分析与仿真 注意:使用vivado 自带的仿真工具, reg和wire等信号需要赋予初始值 边沿检测 module signal_test( input wire cmos_pcl ...
- 基于jQuery仿QQ音乐播放器网页版代码
基于jQuery仿QQ音乐播放器网页版代码是一款黑色样式风格的网页QQ音乐播放器样式代码.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div class="m ...
- jQuery实践-别踩白块儿网页版
▓▓▓▓▓▓ 大致介绍 终于结束了考试,放假回家了.这次的别踩白块儿网页版要比之前做的 jQuery实践-网页版2048小游戏 要简单一点,基本的思路都差不多. 预览:别踩白块网页版 这篇博客并不是详 ...
- jQuery实践-网页版2048小游戏
▓▓▓▓▓▓ 大致介绍 看了一个实现网页版2048小游戏的视频,觉得能做出自己以前喜欢玩的小游戏很有意思便自己动手试了试,真正的验证了这句话-不要以为你以为的就是你以为的,看视频时觉得看懂了,会写了, ...
- 原生js写的贪吃蛇网页版游戏特效
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <bo ...
- 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
- 网页版电子表格控件tmlxSpreadsheet免费下载地址
tmlxSpreadsheet 是一个由JavaScript 和 PHP 写成的电子表格控件(包含WP插件, Joomla插件等等).. 程序员可以容易的添加一个类似Excel功能的,可编辑的表格功能 ...
- 基于HTML5的捕鱼达人游戏网页版
之前给大家分享了html5实现的水果忍者,愤怒的小鸟,中国象棋游戏.今天给大家分享一款捕鱼达人(fishjoy)网页版游戏的源码.可以在线玩也可以下载到本地.它使用html5技术和javascript ...
随机推荐
- POJ 1330 Nearest Common Ancestors(裸LCA)
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 39596 Accept ...
- 写给Android 混淆小白的快速混淆方法
为啥子要混淆 简单来说,Android 进行ProGuard,可以起到压缩,混淆,预检,优化的功能,虽然不能说更安全但还是一个不容忽视的环节. 开始混淆第一步 首先在build.gradle 中将混淆 ...
- linux多线程入门
linux下的多线程通过pthread实现,下面给个简单的例子. #include <stdio.h> #include <stdlib.h> #include <pth ...
- Redis服务器和客户端的通信
Redis客户端使用RESP(Redis序列化协议)与Redis服务器进行通信,RESP在位于TCP之上,而网络模型上客户端和服务器是保持的双工的连接.如图1 而一个简单的请求/响应的串行通信模型如下 ...
- 封锁阳光大学(染色)P1330
题目:https://www.luogu.com.cn/problem/P1330 阳光大学的校园是一张由 n 个点构成的无向图,n 个点之间由 m 条道路连接.每只河蟹可以对一个点进行封锁,当某个点 ...
- Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.
今天上传图片遇到这个报错 百度了下,网上说是input标签type=file所以导致的问题,可是我的type=hidden 解决办法: 把上面的代码改成如下问题就解决了
- for do-while while区别
分别用for do-while while求1-100的和
- Leetcode_236. 二叉树的最近公共祖先
求二叉树的LCA code /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *le ...
- C#黔驴技巧之去重(Distinct)
前言 关于C#中默认的Distinct方法在什么情况下才能去重,这个就不用我再多讲,针对集合对象去重默认实现将不再满足,于是乎我们需要自定义实现来解决这个问题,接下来我们详细讲解几种常见去重方案,孰好 ...
- JPA---Spring-data-JPA---Hibernate
Spring Data JPA--搭建环境 版本---maven 3.6.3 <properties> <spring.version>5.2.5.RELEASE</s ...