ysyx:verilator的初步学习

虽然已经看过了c语言,但是verilator用的语法我还是第一次见。

module top(
  input a,
  input b,
  output f
);
  assign f = a ^ b;
endmodule             //这是verilog代码,单另起一个文件,后缀用.v  不要当成c的代码
------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

while (???) {   //伪代码,要修改
  int a = rand() & 1;
  int b = rand() & 1;
  top->a = a;
  top->b = b;
  top->eval();
  printf("a = %d, b = %d, f = %d\n", a, b, top->f);
  assert(top->f == (a ^ b));
}

1. verilog的程序由模块组成。每个模块用module -----end module来进行分割。

2. 每个模块都需要声明input和output以及类型;模块的功能可以 用连续赋值语句(assign),过程赋值语句(always)。

3. verilog同样支持算术、逻辑、位运算符等,数组、常量等也支持。

  这个伪代码不能直接用,要自己动手改好。

 

修改后的c语言代码:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <verilated.h>
#include "Vverilog1.h"

int main() { int i=10;
Vverilog1 *top=new Vverilog1;
while (i--) { // 随机生成两个二进制数a和b int a = rand() & 1; int b = rand() & 1; // 把它们赋值给verilog模块的输入 top->a = a; top->b = b; // 调用eval函数来计算输出 top->eval(); printf("a = %d, b = %d, f = %d\n", a, b, top->f); // 检查结果是否正确 assert(top->f == (a ^ b)); } return 0; }

verilator的效果类似把verilog语言定义的模块转化成一个类。c++里可以直接引用头文件,然后调用。调用方法同类实例化。在调用时,需要同时引入verilated.h头文件和对应模块的头文件。对应模块的头文件名,就是verilog文件名,前面+V。

  比如我的模块文件名叫Verilog1.k,那么c++里就要调用Vverilog1.h。(top这个模块名反而不重要)

eval()函数会由.h文件提供,不用再多做处理。

 

  例子里的assign f=a^b就表示把a和b的按位异或结果赋值给f。 a或b其中有且只有一个为1,f为1. 反之f为0. 就这样实现了双控开关的效果。在主函数里面,随机生成了两个int变量a b,然后按位与,再调用top的eval函数,这个函数在这里的作用就是执行top模块的逻辑,更新当前top模块的内部状态

用以下代码来进行编译

verilator (-Wall) --cc Verilog1.v --exe test_verilog.c 

-Wall 表示开启警告   --cc表示生成c++的代码   -exe表示生成可执行文件(不是生成exe文件)

这一步后会生成一个obj_dir文件夹 .进入文件夹。可以看到相关文件,其中有一个后缀为.mk的,对应makefile文件。   然后用

make -f Vverilog1.mk

进行编译。编译好以后  ./Vverilog1即可查看效果。

或者,直接用这条指令,一次直接编译链接c++代码:

verilator --cc --exe --build --trace verilog1.v test_verilog.c

 

 

  如果之前c++代码有问题,在make时会进行报错。修改好以后,两段指令都重新执行一次。

程序输出了十次,正确表达了双控的模拟效果。

posted @ 2024-01-25 17:55  namezhyp  阅读(64)  评论(0编辑  收藏  举报