天津 重庆 南京 成都 济南 义乌 广州 佛山 贵阳 西安

学会使用Hdlbits网页版Verilog代码仿真验证平台

发布时间:2021年11月24日责任编辑:李小强

大家推荐一款网页版的 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/

1

ns

//-------------------Tesebench--------------------

moduletop_module;

//仿真文件名必须是“top_module”

regsclk;

regrst_n;

wireled;

initial`probe_start;

//Startthetimingdiagram

`probe(sclk);

//Probesignal"clk",这是加载的系统时钟,只能在Tesebench中加载

//初始化

initialbegin

sclk=

1"b

0;

rst_n<=

1"b

0;

#200

rst_n<=

1"b

1;

#5000//一定要设置仿真停止时间,如果仿真结束时间太久会提示

$finish;

end

//产生20ns的时钟

always

#10sclk=~sclk;

//为了减少仿真时间我们在仿真中重定义参数,不影响RTL代码中参数的值

defparambreath_led_inst.CNT_1US_MAX=

1

;

defparambreath_led_inst.CNT_1MS_MAX=

2

;

defparambreath_led_inst.CNT_1S_MAX=

2

;

//-------------------breath_led--------------------

breath_ledbreath_led_inst(

.sclk(sclk),

//inputsclk

.rst_n(rst_n),

//inputrst_n

.led(led)

//outputled

);

endmodule

//--------------------------------------------------

//-----------------------RTL------------------------

modulebreath_led

#(

parameterCNT_1US_MAX=

6"

d49,

parameterCNT_1MS_MAX=

10"

d999,

parameterCNT_1S_MAX=

10"

d999

)

(

inputwiresclk,

inputwirerst_n,

outputregled

);

reg[

5

:

0

]cnt_1us;

reg[

9

:

0

]cnt_1ms;

reg[

9

:

0

] cnt_1s;

regcnt_1us_flag;

regcnt_1ms_flag;

reg cnt_1s_flag;

//cnt_1us:1us计数器

always@(posedgesclkornegedgerst_n)

if

(rst_n==

1"b

0)

cnt_1us<=

6"b

0;

else

if

(cnt_1us==CNT_1US_MAX)

cnt_1us<=

6"b

0;

else

cnt_1us <=cnt_1us +

1"b

1;

//cnt_1us_flag:1us计数器标志信号

always@(posedgesclkornegedgerst_n)

if

(rst_n==

1"b

0)

cnt_1us_flag<=

1"b

0;

else

if

(cnt_1us==CNT_1US_MAX)

cnt_1us_flag<=

1"b

1;

else

cnt_1us_flag<=

1"b

0;

//cnt_1ms:1ms计数器

always@(posedgesclkornegedgerst_n)

if

(rst_n==

1"b

0)

cnt_1ms<=

10"b

0;

else

if

(cnt_1ms==CNT_1MS_MAX&&cnt_1us_flag==

1"b

1)

cnt_1ms<=

10"b

0;

else

if

(cnt_1us_flag==

1"b

1)

cnt_1ms<=cnt_1ms+

1"b

1;

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

always@(posedgesclkornegedgerst_n)

if

(rst_n==

1"b

0)

cnt_1ms_flag<=

1"b

0;

else

if

(cnt_1ms==CNT_1MS_MAX&&cnt_1us_flag==

1"b

1)

cnt_1ms_flag<=

1"b

1;

else

cnt_1ms_flag<=

1"b

0;

//cnt_1s:1s计数器

always@(posedgesclkornegedgerst_n)

if

(rst_n==

1"b

0)

cnt_1s<=

10"b

0;

else

if

(cnt_1s==CNT_1S_MAX&&cnt_1ms_flag==

1"b

1)

cnt_1s<=

10"b

0;

else

if

(cnt_1ms_flag==

1"b

1)

cnt_1s<=cnt_1s+

1"b

1;

//cnt_1s_flag:1s计数器标志信号

always@(posedgesclkornegedgerst_n)

if

(rst_n==

1"b

0)

cnt_1s_flag<=

1"b

0;

else

if

(cnt_1s==CNT_1S_MAX&&cnt_1ms_flag==

1"b

1)

cnt_1s_flag<=~cnt_1s_flag;

//led:一个LED灯

always@(posedgesclkornegedgerst_n)

if

(rst_n==

1"b

0)

led<=

1"b

0;

else

if

((cnt_1s_flag==

1"b

1&&cnt_1ms<=cnt_1s)||(cnt_1s_flag==

1"b

0&&cnt_1ms>cnt_1s))

led<=

1"b

1;

else

led<=

1"b

0;

//添加要观察的信号名

`probe(rst_n);

//Sub-modulescanalsohave`probe()

`probe(cnt_1us);

//Sub-modulescanalsohave`probe()

`probe(cnt_1us_flag);

//Sub-modulescanalsohave`probe()

`probe(cnt_1ms);

//Sub-modulescanalsohave`probe()

`probe(cnt_1ms_flag);

//Sub-modulescanalsohave`probe()

`probe(cnt_1s);

//Sub-modulescanalsohave`probe()

`probe(cnt_1s_flag);

//Sub-modulescanalsohave`probe()

`probe(led);

//Sub-modulescanalsohave`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

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

关于答案所有题目没有标准答案,github上很多答案,大家在遇到问题的时候可以去搜索参考,建议遇到问题多思考,才能学能所用。

网站简介 联系方式 隐私政策 投诉及建议 发展历程 垃圾信息处理邮箱tousu572@163.com
icp备案号 浙ICP备10048612号 不良信息举报平台 互联网安全管理备案 Copyright 2021 www.100jianzhan.com All Rights Reserved