前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CIRCT-LLHD仿真计数器电路

CIRCT-LLHD仿真计数器电路

作者头像
hunterzju
发布2021-12-09 13:58:23
1.4K0
发布2021-12-09 13:58:23
举报
文章被收录于专栏:编译器开发

CIRCT项目尝试基于LLVM和MLIR构建一套模块化、语义清晰一致、可重用的硬件设计基础设施。LLHD是其中一种用于硬件电路的中间表示(IR)。本文记录尝试用LLHD进行硬件电路仿真的过程。

数字计数器verilog源码

这里以一个非常简单的不带进位的十六进制加减计数器为例,verilog设计代码如下:

代码语言:javascript
复制
module up_down_counter(
    input clk, reset,up_down, 
    output[3:0]  counter
    );
reg [3:0] counter_up_down;

// down counter
always @(posedge clk or posedge reset)
begin
if(reset)
 counter_up_down <= 4'h0;
else if(~up_down)
 counter_up_down <= counter_up_down + 4'd1;
else
 counter_up_down <= counter_up_down - 4'd1;
end 
assign counter = counter_up_down;

endmodule

然后还需要一个testbench来给模块添加测试激励:

代码语言:javascript
复制
`timescale 10ns/1ns                   // 时间单位/时间精度

// 测试顶层模块
module updowncounter_tb();
reg clk, reset,up_down;
wire [3:0] counter;

// 例化一个待测试模块
up_down_counter dut(clk, reset,up_down, counter);

// 指定时钟行为
initial begin 
clk=0;
forever #5ns clk=~clk;
end
// 其它控制信号行为
initial begin
reset=1;
up_down=0;
#20ns;
reset=0;
#200ns;
up_down=1;
end
endmodule

LLHD编译器Moore使用

llhd使用rust编写了一个支持systemverilog的编译器,也能实现对verilog的兼容,可以将verilog源码转换为LLHD IR的表示形式。Moore编译器在github上开源:https://github.com/fabianschuiki/moore,下文就使用moore来编译上文中的计数器:

首先,按照moore项目中的readme文件编译moore应用(需要先安装好rust环境):

然后使用moore编译verilog代码:

代码语言:javascript
复制
./moore -f mlir -e updowncounter_tb -o udcounter.mlir counter_ud_tb.v counter_ud.v

其中-f参数指定输出的格式,可选项有mlir|llhdllhd是使用rust编写的仿真器llhd-sim支持的格式,mlir是继承到CIRCT中的仿真器支持的格式;-e参数指定顶层模块名,上文中testbench中顶层模块名为updowncounter_tb-o参数指定输出文件名;其余参数被当作输入文件。

moore编译器会将verilog代码转换为SSA(静态单赋值)形式的LLHD IR表示;这里以mlir格式为例,截取综合出来的部分IR代码:

代码语言:javascript
复制
llhd.entity @updowncounter_tb() -> () {
    %0 = hw.constant 0 : i1
    %clk = llhd.sig "clk" %0 : i1
    %reset = llhd.sig "reset" %0 : i1
    %up_down = llhd.sig "up_down" %0 : i1
    %1 = hw.constant 0 : i4
    %counter = llhd.sig "counter" %1 : i4
    // 待验证电路示例
    llhd.inst "inst" @up_down_counter.param1(%clk, %reset, %up_down) -> (%counter) : (!llhd.sig<i1>, !llhd.sig<i1>, !llhd.sig<i1>) -> (!llhd.sig<i4>)
    // 时钟clk信号驱动逻辑块
    llhd.inst "inst1" @updowncounter_tb.initial.63.0() -> (%clk) : () -> (!llhd.sig<i1>)
    // 其他控制信号驱动逻辑块
    llhd.inst "inst2" @updowncounter_tb.initial.112.0() -> (%reset, %up_down) : () -> (!llhd.sig<i1>, !llhd.sig<i1>)
}

LLHD仿真器llhd-sim使用

llhd-sim实现基于LLHD IR的电路仿真,最开始是采用rust编写的应用:https://github.com/fabianschuiki/llhd;目前合入到了CIRCT项目中,但是CIRCT中的llhd-sim输出格式为自定义格式,需要自己写脚本转换为VCD格式后才能用GTKWave查看。

对于Rust编写的llhd-sim,在使用moore编译verilog代码时需要将输出格式指定为llhd。然后执行仿真操作:

代码语言:javascript
复制
./llhd-sim ../udcounter.llhd -N 100 -o udcounter.vcd

上述-N参数指定仿真执行多少步。此时,输出的vcd文件可以用gtkwave查看仿真波形:

代码语言:javascript
复制
gtkwave ./udcounter.vcd

仿真波形如图,电路在reset信号清零后,按照逻辑描述随着时钟信号增加计数:

对于CIRCT中的llhd-sim,使用moore:

代码语言:javascript
复制
./bin/llhd-sim ./udcounter.mlir -r updowncounter_tb -n 100 -o ./udcounter.sim

这里的-r参数指定仿真的root模块,-n参数指定仿真执行多少步。此时得到的仿真结果是llhd自己定义的格式,并不是标准的vcd格式,需要自己编写脚本进行一下格式转换。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数字计数器verilog源码
  • LLHD编译器Moore使用
  • LLHD仿真器llhd-sim使用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档