您当前的位置: 首页 > 

耐心的小黑

暂无认证

  • 2浏览

    0关注

    323博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

chisel生成Verilog与基本测试(更新)

耐心的小黑 发布时间:2021-06-21 16:27:02 ,浏览量:2

主体内容摘自:https://blog.csdn.net/qq_34291505/article/details/87880730

一、生成Verilog

前面介绍Scala的内容里说过,Scala程序的入口是主函数。所以,生成Verilog的程序自然是在主函数里例化待编译的模块,然后运行这个主函数。

例化待编译模块需要特殊的方法调用。chisel3包里有一个单例对象Driver,它包含一个方法execute,该方法接收两个参数:

  • 第一个参数是命令行传入的实参即字符串数组args,
  • 第二个是返回待编译模块的对象的无参函数。

运行这个execute方法,就能得到Verilog代码。

假设在src/main/scala文件夹下有一个全加器的Chisel设计代码,如下所示:

// fulladder.scala
package test
 
import chisel3._
 
class FullAdder extends Module {
  val io = IO(new Bundle {
    val a = Input(UInt(1.W))
    val b = Input(UInt(1.W))
    val cin = Input(UInt(1.W))
    val s = Output(UInt(1.W))
    val cout = Output(UInt(1.W))  
  })
 
  io.s := io.a ^ io.b ^ io.cin
  io.cout := (io.a & io.b) | ((io.a | io.b) & io.cin)
}

接着,读者需要在src/test/scala文件夹下编写对应的主函数文件,如下所示:

// fullAdderGen.scala
package test
 
object FullAdderGen extends App {
  chisel3.Driver.execute(args, () => new FullAdder)
}

注1:chisel3.Driver.execute()函数的定义如下: 在这里插入图片描述

  • 第一个参数是args,它是用来传参的,可以在命令行传,也可以直接提供一个数组,具体下面再说;
  • 第二个参数dut用来传入一个用户编写的模块的,它是无参、返回类型是RawModule的函数字面量。因为Chisel的模块本质上还是Scala的class,所以只需用new构造一个对象作为返回结果即可。
  • 主函数里可以包括多个execute函数,也可以包含其它代码。

注2:chisel3.stage.ChiselStage.execute()函数说明:

上述函数已经不推荐使用了,若是想使用execute函数,现在推荐使用chisel3.stage.ChiselStage的execute,其实你在class ChiselStage里面找不到该函数的定义,那是因为这个函数继承自firrtl.Stage,定义和使用方法如下: 在这里插入图片描述

import chisel3.stage.{ChiselStage, ChiselGeneratorAnnotation}

(new chisel3.stage.ChiselStage).execute(args, Seq(ChiselGeneratorAnnotation(() => new FullAdder)))

注3:chisel3.stage.ChiselStage.emitVerilog()函数说明:

其实还有一个函数更被推荐使用,就是chisel3.stage.ChiselStage.emitVerilog(),该函数也可以用来生成verilog代码,定义如下,可以看出其实内部也是调用了chisel3.stage.ChiselStage.execute()这个函数,只不过所需传入的参数更加简单,第一参数不再需要传入一个返回RawModule的无参函数,而是直接将RawModule类型的对象传入即可,这用到了scala的传名参数的语法!!! 在这里插入图片描述

(new chisel3.stage.ChiselStage).emitVerilog(new FullAdder,args)

注4: 关于如何运行主函数的说明

建议把设计文件和主函数放在一个包里,比如这里的“package test”,这样省去了编写路径的麻烦。

这里需要注意的是,放在同一个包里并不是指的同一路径下,这和sbt的编译机制有关,为了简单起见,我们只需要按照sbt的要求存放文件即可,这样就可以省去编写路径的麻烦!!!

要运行这个主函数,需要在build.sbt文件所在的路径下打开终端,然后执行命令:

sbt 'test:runMain test.FullAdderGen'

注意,sbt后面有空格,再后面的内容都是被单引号对或双引号对包起来。其中,test:runMain是让sbt执行src/test/scala路径下的主函数的命令,而test.FullAdderGen就是要执行的那个主函数。其中test对应的就是package testFullAdderGen就是单例对象的名字。

其实主函数也可以直接和设计代码写在一起,也即写在 fulladder.scala文件中,注意这个文件在src/main/scala路径下,此时如果要运行该主函数,命令需要稍作改变:sbt 'runMain test.FullAdderGen'。可以看到唯一的区别就是少了test:,此时的含义是去执行src/main/scala路径下的主函数。

如果设计文件没有错误,那么最后就会看到“[success] Total time: 6 s, completed Feb 22, 2019 4:45:31 PM”这样的信息。此时,终端的路径下就会生成三个文件:FullAdder.anno.json、FullAdder.fir和FullAdder.v

第一个文件用于记录传递给Firrtl编译器的Scala注解,读者可以不用关心。第二个后缀为“.fir”的文件就是对应的Firrtl代码,第三个自然是对应的Verilog文件。

首先查看最关心的Verilog文件,内容如下:

// FullAdder.v
module FullAdder(
  input   clock,
  input   reset,
  input   io_a,
  input   io_b,
  input   io_cin,
  output  io_s,
  output  io_cout
);
  wire  _T; // @[fulladder.scala 14:16]
  wire  _T_2; // @[fulladder.scala 15:20]
  wire  _T_3; // @[fulladder.scala 15:37]
  wire  _T_4; // @[fulladder.scala 15:45]
  assign _T = io_a ^ io_b; // @[fulladder.scala 14:16]
  assign _T_2 = io_a & io_b; // @[fulladder.scala 15:20]
  assign _T_3 = io_a | io_b; // @[fulladder.scala 15:37]
  assign _T_4 = _T_3 & io_cin; // @[fulladder.scala 15:45]
  assign io_s = _T ^ io_cin; // @[fulladder.scala 14:8]
  assign io_cout = _T_2 | _T_4; // @[fulladder.scala 15:11]
endmodule

可以看到,代码逻辑与想要表达的意思完全一致,而且对应的代码都用注释标明了来自于Chisel源文件的哪里。但由于这是通过语法分析的脚本代码得到的,所以看上去显得很笨拙、僵硬,生成了大量无用的中间变量声明。对于下游的综合器而言是一个负担,可能会影响综合器的优化。而且在进行仿真时,要理解这些中间变量也很麻烦。对后端人员来说,这也是让人头疼的问题。

接着再看一看Firrtl代码,内容如下:

// FullAdder.fir
;buildInfoPackage: chisel3, version: 3.2-SNAPSHOT, scalaVersion: 2.12.6, sbtVersion: 1.1.1
circuit FullAdder : 
  module FullAdder : 
    input clock : Clock
    input reset : UInt
    output io : {flip a : UInt, flip b : UInt, flip cin : UInt, s : UInt, cout : UInt}
    
    node _T = xor(io.a, io.b) @[fulladder.scala 14:16]
    node _T_1 = xor(_T, io.cin) @[fulladder.scala 14:23]
    io.s             
关注
打赏
1640088279
查看更多评论
0.0413s