本文讲述使用HDLBits进行FPGA代码在线综合仿真以及时序图生成,用于验证自己的设计。
学习完本教程后,通过每次查看"仿真必备要素总结"小节即可轻松的构建自己的仿真了!
HDLBits 最被大家熟知的是作为一款网页版的 Verilog代码编辑仿真验证平台,这个平台是国外的一家开源FPGA学习网站,通过“https://hdlbits.01xz.net/wiki/Main_Page”地址进入网页,在该网页上可以进行Verilog代码的编写、综合,而且最后还能够仿真出波形来验证设计代码的正确性,该验证平台是基于Icarus Verilog(简称iVerilog,比较著名的开源HDL仿真工具,也有对应的安装版本)的,让你随时随地只需登录网页就能够享受Verilog编程仿真的乐趣!
它是一个很适合Verilog初学者快速上手的刷题网址,包含对Verilog语法、组合逻辑、时序逻辑、仿真等等练习。在网页中你的代码会通过 Altera Quartus 的综合器综合为硬件电路。你的综合电路会通过功能仿真来检查其功能是否正确。HDLBits 使用 ModelSim 同时仿真你的代码和参考解决方案,然后比较两者的输出。
更全面地,它也包含帮助您学习计算机设计基础知识的工具,其中包含了HDLBits、ASMBits、CPUlator,通过’‘https://www.01xz.net/wiki/Main_Page’‘地址进入网页。
HDLBits:在Verilog中练习数字电路设计的问题集和在线判断;
ASMBits:就像HDLBits一样,但用于练习Nios II或ARMv7汇编语言;
CPUlator:浏览器内全系统MIPS、Nios II和ARMv7模拟器和调试器。
HDLBits除了用于Verilog刷题练习外,还可以用于FPGA代码在线综合仿真以及时序图生成,验证自己的设计,允许您运行任何您想要的模拟。
在网页左上角点击Simulation下的“Run a Simulation(lcarus Verilog)”。
首先我们通过官方模板来学习如何使用该仿真功能。
官方模板代码如下:
module top_module ();
reg clk=0;
always #5 clk = ~clk; // Create clock with period=10
initial `probe_start; // Start the timing diagram
`probe(clk); // Probe signal "clk"
// A testbench
reg in=0;
initial begin
#10 in <= 1;
#10 in <= 0;
#20 in <= 1;
#20 in <= 0;
$display ("Hello world! The current time is (%0d ps)", $time);
#50 $finish; // Quit the simulation
end
invert inst1 ( .in(in) ); // Sub-modules work too.
endmodule
module invert(input in, output out);
assign out = ~in;
`probe(in); // Sub-modules can also have `probe()
`probe(out);
endmodule
根据官方的模板,总结出进行仿真需要具备的要素。
首先,对FPGA逻辑进行仿真一定要具备两个文件,一个是RTL代码文件,用来综合生成硬件电路的部分;第二个就是Testbench文件,用来验证RTL代码功能的仿真文件,这两者缺一不可。这里需要将 RTL 代码和Testbench都写在一个编辑框里。
其次,第4行的“initial probe_start”、第6行的“probe(clk)”、第26行的“probe(in)”,是官方定义的一个”宏“,也就是通过这个”宏“调用“probe”探针的功能,我们不用管这个”宏“是如何定义的,我们只需要会调用就可以了。注意这不是verilog中的语法,仅用于网页仿真中的波形图绘制。
因此代码编辑区域中编写代码时的必备要素如下:
要素 | 代码位置 |
---|---|
RTL 代码和Testbench写在了一个编辑框内,两者前后顺序任意 | 第1行和23行共两个module,并分别以endmodule结尾 |
也可以单独用一个top_module进行仿真 | 本文最后“单独的top_module仿真”小节有讲解 |
仿真文件名必须是“top_module” | 第1行 |
initial `probe_start; | 第4行,用于启动时序图 |
`probe(XX); | 第6、26、27行,括号内表示需要画图的信号 |
#50 $finish; | 第16行,一定要设置仿真停止时间,如果仿真结束时间太久会提示 |
下方补充了关于时序图绘制的使用与局限:每个信号只能添加一次。最多可以有512个信号。每个信号可以是不超过512位的总线。
点击“Submit(new window)“在新界面中进行仿真。编译的信息和仿真波形图会出现在新打开的界面。
点击’‘Share’‘,将会将页面代码生成网页,你可以将它分享给别人。
我们以此例题真值表为例https://hdlbits.01xz.net/wiki/Truthtable1进行演示。输入信号x3,x2,x1;输出信号f。编写Verilog代码并仿真画出时序图。
Row | Inputs | Outputs | ||
---|---|---|---|---|
number | x3 | x2 | x1 | f |
0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 1 | 0 |
2 | 0 | 1 | 0 | 1 |
3 | 0 | 1 | 1 | 1 |
4 | 1 | 0 | 0 | 0 |
5 | 1 | 0 | 1 | 1 |
6 | 1 | 1 | 0 | 0 |
7 | 1 | 1 | 1 | 1 |
此处就不再阐述实现细节,思路为用真值表的最小项进行化简。
//--------------RTL------------------
module Truthtable(
input x3,
input x2,
input x1, // three inputs
output f // one output
);
assign f =(~x3 & x2) | (x3 & x1);
endmodule
`timescale 1ns/1ns
//----------------Tesebench-----------------
module top_module (); //仿真文件名必须是“top_module”
reg clk=0;
always #5 clk = ~clk; // Create clock with period=10
// A testbench
reg x1,x2,x3;
initial begin
x3 <= 0 ;
x2 <= 0 ;
x1 <= 0 ;
#10
x3 <= 0 ;
x2 <= 0 ;
x1 <= 1 ;
#10
x3 <= 0 ;
x2 <= 1 ;
x1 <= 0 ;
#10
x3 <= 0 ;
x2 <= 1 ;
x1 <= 1 ;
#10
x3 <= 1 ;
x2 <= 0 ;
x1 <= 0 ;
#10
x3 <= 1 ;
x2 <= 0 ;
x1 <= 1 ;
#10
x3 <= 1 ;
x2 <= 1 ;
x1 <= 0 ;
#10
x3 <= 1 ;
x2 <= 1 ;
x1 <= 1 ;
#10 $finish; // Quit the simulation
end
Truthtable inst1 (
.x3(x3),
.x2(x2),
.x1(x1)
); // Sub-modules work too.
endmodule
//--------------RTL------------------
module Truthtable(
input x3,
input x2,
input x1, // three inputs
output f // one output
);
assign f =(~x3 & x2) | (x3 & x1);
`probe(f);
endmodule
`timescale 1ns/1ns
//----------------Tesebench-----------------
module top_module (); //仿真文件名必须是“top_module”
reg clk=0;
always #5 clk = ~clk; // Create clock with period=10
initial `probe_start; // Start the timing diagram
`probe(clk); // Probe signal "clk"
// A testbench
reg x1,x2,x3;
initial begin
x3 <= 0 ;
x2 <= 0 ;
x1 <= 0 ;
#10
x3 <= 0 ;
x2 <= 0 ;
x1 <= 1 ;
#10
x3 <= 0 ;
x2 <= 1 ;
x1 <= 0 ;
#10
x3 <= 0 ;
x2 <= 1 ;
x1 <= 1 ;
#10
x3 <= 1 ;
x2 <= 0 ;
x1 <= 0 ;
#10
x3 <= 1 ;
x2 <= 0 ;
x1 <= 1 ;
#10
x3 <= 1 ;
x2 <= 1 ;
x1 <= 0 ;
#10
x3 <= 1 ;
x2 <= 1 ;
x1 <= 1 ;
#10 $finish; // Quit the simulation
end
Truthtable inst1 (
.x3(x3),
.x2(x2),
.x1(x1)
); // Sub-modules work too.
`probe(x3);
`probe(x2);
`probe(x1);
endmodule
在时序图显示框中右击鼠标可以选择保存为PNG格式或者SVG格式进行导出,PNG格式导出好像有问题,可以使用SVG导出。
如果编译出错,可以根据提示进行修改。
用模块来实现验证Verilog中的除法和取模运算规则。
`timescale 1ns/1ns
module top_module;
reg [7:0] a, b;
reg [7:0] quotient, remainder;
initial `probe_start ;
initial begin
a = 46;
b = 16;
$display("a = %d, b = %d, quotient = %d, remainder = %d", a, b, quotient, remainder);
#10
a = 35;
b = 6;
$display("a = %d, b = %d, quotient = %d, remainder = %d", a, b, quotient, remainder);
#10
a = 27;
b = 9;
$display("a = %d, b = %d, quotient = %d, remainder = %d", a, b, quotient, remainder);
#30 $finish;
end
//画图
`probe(a);
`probe(b);
`probe(quotient);
`probe(remainder);
//赋值
assign quotient = a / b; // 执行整数除法
assign remainder = a % b; // 执行模运算
endmodule
得到编译信息和相应的时序波形。需要注意的是:波形的汇总不是必须的,如果去掉`probe宏部分也是允许的。
Running Icarus Verilog simulator...
a = 46, b = 16, quotient = 2, remainder = 14
VCD info: dumping is suppressed.
a = 35, b = 6, quotient = 5, remainder = 5
a = 27, b = 9, quotient = 3, remainder = 0
Hint: Total mismatched samples is 0 out of 0 samples
Simulation finished at 50000 ps
Mismatches: 0 in 0 samples
图中以16进制显示数值:
去掉`probe宏后只显示编译信息,无波形:
以上便是使用Hdlbits进行FPGA代码在线综合仿真以及时序图生成的全部内容,希望对你有帮助!