杂七杂八,都是网上搜集到的例子,对于Verilator一窍不通 希望能够通过这些对自己有个补充作用
若有冒犯请见谅,侵权删除
Verilator官方所给手册 C++例子
mkdir test_our //创建文件夹
cd test_our
cat >our.v <<'EOF'
module our; # 定义一个module
initial # 定义一个initial块
begin # initial块的开始
$display("Hello World"); # debug输出Hello World
$finish; # debug完成
end # initial块的结束
endmodule # our模块的结束
EOF
cat >sim_main.cpp <<'EOF'
#include "Vour.h" # our.v被verilator编译成Vour.h **得改
#include "verilated.h" # verialtor官方库
int main(int argc, char** argv, char** env) {
VerilatedContext* contextp = new VerilatedContext; # verilator上下文指针
contextp->commandArgs(argc, argv); # 检查参数
Vour* top = new Vour{contextp}; # 实例化our模块
while (!contextp->gotFinish()) { # 一直到contextp仿真完成才退出
top->eval(); # 更新电路状态,计算输出
}
delete top;
delete contextp;
return 0;
}
EOF
verilator -Wall --cc --exe --build top.v sim_main.cpp
执行生成的C++可执行文件,结果生成文件Vxxx
执行编译:
verilator -Wall top.v top_main.cpp --cc --trace --exe --build
#增加了--trace 是为了显示波形的,注意得加上--tarce 否则会报错(若前面有含波形的库)
./obj_dir/Vtop //必须执行这个,才会出现.vcd文件,需要强制退出
gtkwave wave.vcd //如果报错缺少canberra-gtk-module,apt安装即可
南京大学数字电路 二选一激励代码
#include "verilated.h"
#include "verilated_vcd_c.h"
#include "obj_dir/Vmux21.h" ***//得改***
VerilatedContext* contextp = NULL;
VerilatedVcdC* tfp = NULL;
static Vmux21* top;
void step_and_dump_wave(){
top->eval();
contextp->timeInc(1);
tfp->dump(contextp->time());
}
void sim_init(){
contextp = new VerilatedContext;
tfp = new VerilatedVcdC;
top = new Vmux21;
contextp->traceEverOn(true);
top->trace(tfp, 0);
tfp->open("dump.vcd");
}
void sim_exit(){
step_and_dump_wave();
tfp->close();
}
int main() { //不同情况,不同取值
sim_init();
top->s=0; top->a=0; top->b=0; step_and_dump_wave(); // 将s,a和b均初始化为“0”
top->b=1; step_and_dump_wave(); // 将b改为“1”,s和a的值不变,继续保持“0”,
top->a=1; top->b=0; step_and_dump_wave(); // 将a,b分别改为“1”和“0”,s的值不变,
top->b=1; step_and_dump_wave(); // 将b改为“1”,s和a的值不变,维持10个时间单位
top->s=1; top->a=0; top->b=0; step_and_dump_wave(); // 将s,a,b分别变为“1,0,0”,维持10个时间单位
top->b=1; step_and_dump_wave();
top->a=1; top->b=0; step_and_dump_wave();
top->b=1; step_and_dump_wave();
sim_exit();
}
语句学习01 *测试模块
#include "verilated_vcd_c.h" //可选,如果要导出vcd则需要加上
#include "VAccumulator.h"
vluint64_t main_time = 0; //initial 仿真时间
double sc_time_stamp()
{
return main_time;
}
int main(int argc, char **argv)
{
Verilated::commandArgs(argc, argv);
Verilated::traceEverOn(true); //导出vcd波形需要加此语句
VerilatedVcdC* tfp = new VerilatedVcdC; //导出vcd波形需要加此语句
VAccumulator *top = new VAccumulator("top"); //调用VAccumulator.h里面的IO struct
top->trace(tfp, 0);
tfp->open("wave.vcd"); //打开vcd
while (sc_time_stamp() < 20 && !Verilated::gotFinish()) { //控制仿真时间
top->io_din_0 = main_time + 0; //激励控制
top->io_din_1 = main_time + 1;
top->io_din_2 = main_time + 2;
top->io_din_3 = main_time + 3;
top->eval(); //计算输出
printf("%d + %d + %d + %d = %d\n",top->io_din_0,top->io_din_1,top->io_din_2,top->io_din_3,top->io_dout); //命令行输出仿真结果
tfp->dump(main_time); //dump wave
main_time++; //推动仿真时间
}
top->final();
tfp->close();
delete top;
return 0;
}
例子02
#include <verilated.h> // Defines common routines
#include <iostream> // Need std::cout
#include "Vtop.h" // From Verilating "top.v"
Vtop *top; // Instantiation of model
uint64_t main_time = 0; // Current simulation time
// This is a 64-bit integer to reduce wrap over issues and
// allow modulus. This is in units of the timeprecision
// used in Verilog (or from --timescale-override)
double sc_time_stamp() { // Called by $time in Verilog
return main_time; // converts to double, to match
// what SystemC does
}
int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv); // Remember args
top = new Vtop; // Create model
// Do not instead make Vtop as a file-scope static
// variable, as the "C++ static initialization order fiasco"
// may cause a crash
top->reset_l = 0; // Set some inputs
while (!Verilated::gotFinish()) {
if (main_time > 10) {
top->reset_l = 1; // Deassert reset
}
if ((main_time % 10) == 1) {
top->clk = 1; // Toggle clock
}
if ((main_time % 10) == 6) {
top->clk = 0;
}
top->eval(); // Evaluate model
cout << top->out << endl; // Read a output
main_time++; // Time passes...
}
top->final(); // Done simulating
// // (Though this example doesn't get here)
delete top;
}
补充学习:
-new 运算符 (C++) 是尝试分配和初始化指定类型或占位符类型的对象或对象数组,并返回指向对象(或指向数组初始对象)的适当类型化的非零指针。
使用 new 为 C++ 类对象分配内存时,将在分配内存后调用对象的构造函数。使用 delete 运算符解除由 new 运算符分配的内存。 使用 delete[] 运算符删除由 new 运算符分配的数组。
new学习
new和make的区别
new A() 这样方式的功能如下:
1 在堆上分配空间
2 在分配的空间上调用对象的构造函数
(这也是 new 和 malloc的主要区别,是否调用构造函数)
同理: 在调用 delete obj的时候:
1 首先调用 这个对象 的析构函数
2 然后释放这个对象的空间
C++ . -> :: 符号含义与区别
c++中当定义类对象是指针对象时候,就需要用到->指向类中的成员;当定义一般对象时候时就需要用到"."指向类中的成员。
箭头(->):左边必须为指针;
点号(.):左边必须为实体。把域看作是一个可视窗口全局域的对象在它被定义的整个文件里,一直到文件末尾都是可见的。在一个函数内被定义的对象是局域的(local scope), 它只在定义其的函数体内可见。每个类维持一个域,在这个域之外 ,它的成员是不可见的。