吃透Chisel语言.10.Chisel项目构建、运行和测试(二)——Chisel中生成Verilog代码&Chisel开发流程

Chisel项目构建、运行和测试(二)——Chisel中生成Verilog代码&Chisel开发流程

上一篇文章我们提到了怎么用sbt构建Chisel项目并运行Chisel代码,但是毕竟还是在电脑上运行的。而在实践中,我们写的Chisel代码最终应该综合到FPGA或ASIC上,所以必须把Chisel翻译到一个综合工具能处理的硬件描述语言,比如Verilog。那怎么用Chisel代码生成Verilog代码呢?Chisel的开发流程又是怎样的呢?这篇文章来学习一下。

Chisel生成Verilog代码

Chisel是可以生成可综合的Verilog代码的,把生成Verilog的代码放到一个应用入口里面就可以了。这个应用入口就是个Scala对象,是从App拓展来的,上一节提到过,它会在程序启动的时候隐式地生成主函数。这个应用入口里面只有一行代码,它创建了一个新的Hello对象,然后传递给Chisel的emitVerilog()函数,它会生成Hello模块对应的Verilog文件Hello.v。代码如下:

object Hello extends App {
    emitVerilog(new Hello())
}

不过这种调用emitVerilog的写法会把生成的文件默认地放到项目根目录下,也就是运行sbt命令的路径。如果想要把生成的文件放到指定文件夹下的话,就需要给emitVerilog()指定选项。构建选项可以设置为emitVerilog()的第二个参数,参数类型是字符串的数组。上一篇文章讲Chisel项目目录结构的时候提到过,建议把生成的文件放到generated文件夹下,下面的代码就能实现这个需求:

object HelloOption extends App {
    emitVerilog(new Hello(), Array("--target-dir", "generated"))
}

如果我们不想把Verilog代码输出为文件,只是想把它作为Scala字符串在命令行输出的话,只需要使用getVerilogString()函数即可:

object HelloString extends App {
    val s = getVerilogString(new Hello())
    println(s)
}

这种生成方法在小Chisel项目中很好用,比如这个网页上Led灯闪烁的例子Hello World - Scastie (scala-lang.org),用getVerilogString函数输出了该模块对应的Verilog代码。

另外这个Scastie其实是个在线的Scala开发环境,我们如果本地没有配环境的话也完全可以用这个在线环境来进行简单的Chisel开发,能免去配环境的麻烦。

Chisel的工具流开发流程

下面我们运行一个简单但完整的生成Verilog的例子,对应的电路就是直接四位的有符号输入连接到四位的有符号输出:

package my.hello

import chisel3._

class ModuleSample extends Module {
    val io = IO(new Bundle {
        val in_a = Input(SInt(4.W))
        val out_b = Output(SInt(4.W))
    })
    
    io.out_b := io.in_a
}

object MyModule extends App {
    emitVerilog(new ModuleSample(), Array("--target-dir", "generated"))
}

但是我们可以惊奇的看到,generated文件夹下除了*.v的Verilog文件,还有*.fir文件和*.anno.json文件:

在这里插入图片描述

也就是不光生成了Verilog代码,还生成了其他文件,说到原因就涉及到Chisel的工具流了。Chisel的工具流如下图所示:

在这里插入图片描述

我们写的数字电路是其实就是Chisel的类,也就是图中的Hello.scala,本质是Scala源码。但Chisel区别于Scala的地方在于编译的时候不光用到了Scala的库scala.lib,还用到了Chisel的库chisel3.lib

有了Chisel源码,Scala的编译器基于Chisel、Scala的库将我们的代码生成Java类文件Hello.class,也就是字节码文件。这类文件是可以在标准的JVM(Java Virtual Machine,Java虚拟机)上直接执行的。

用Chisel驱动执行这个字节码文件会生成FIRRTL文件Hello.fir。这个FIRRTL全称为Flexible Intermediate Representation for RTL,即RTL的可变中间表示,是数字电路的的中间表示。FIRRTL编译器可以在电路上执行一些变换,是Chisel到其他硬件描述语言的关键桥梁,如果想理解更高阶的Chisel的内容甚至为Chisel开源代码做贡献,那就需要深入学习FIRRTL了。

再往下的Treadle是一个FIRRTL的解释器,用于电路的仿真。配合Chisel测试器,它可以用于调试和测试Chisel电路。根据输出的断言信息我们可以得到测试的结果。Treadle还可以生成波形文件,即Hello.vcd,这个波形文件是可以用波形查看器查看的,比如可以在GTKWare或Modelsim等上查看。

回到FIRRTL编译器部分,Verilog Emitter也是FIRRTL变换之一,可以用Hello.fir生成可综合的Verilog代码Hello.v。接着我们就可以用一个电路综合工具(比如Intel的Quartus,Xilinx的Vivado或其他的ASIC工具)来综合电路。在FPGA设计的工作流中,综合工具会生成FPGA比特流用于配置FPGA,即Hello.bit

结语

现在我们已经学会了怎么在Chisel中生成Verilog代码,也对用Chisel进行开发的工具流有了基本的了解。学会了怎么编译、怎么运行,接下来就得学习怎么测试了。我们肯定不能每次调试都把工具流走完来试错,比如每次修改完代码后都生成FPGA比特流进行测试,这样一是找不到错误所在,二是耗费时间太久。所以必须要在Chisel阶段就测试明白,对于小的模块是如此,对于更大规模的数字电路更得做好测试。后面几篇文章就讲讲几种Chisel测试框架怎么使用,测试代码该怎么写。

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值