Model Me, Model World

Model Me, Model World

Blayground

Chisel中文教程-入门

准备软件

正确安装并配置 jdk。环境变量 PATH 里需保证 jdk 的 java 得比系统自带的 java 优先级高。 下载安装sbt。 一般的文本编辑器编辑 Scala 代码也未尝不可,不过建议用IntelliJ IDEA,提升效率。 如需使用 Chisel 的 C++仿真功能,安装 gcc/g++。Windows 下建议用Cygwin。 同时 Chisel 仿真时可生成波形,用gtkwave可以查看。

Chisel 工作流

建立工程文件夹

整个 demo 工程文件夹所有文件如下所示。本指南会按顺序提供每个文件的内容,没有提到的文件可暂时不创建。

demo/
├── build.sbt
├── run.sh
├── project
│   └── build.properties
└── src
    └── main
        └── scala
            └── Alu.scala

文件内容

build.sbt:注意其中每两行之间都有一空行。

organization := "cn.edu.zju.cs"

version := "0.1"

name := "demo"

scalaVersion := "2.10.4"

scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked", "-language:reflectiveCalls")

val chiselVersion_h = System.getProperty("chiselVersion", "latest.release")

libraryDependencies ++= ( if (chiselVersion_h != "None" ) ("edu.berkeley.cs" %% "chisel" % chiselVersion_h) :: Nil; else Nil)

build.properties

sbt.version=0.13.6

编写硬件描述代码

Alu.scala

import Chisel._

class Alu extends Module {
  val io = new Bundle {
    val a = UInt(INPUT, 32)
    val b = UInt(INPUT, 32)
    val opcode = UInt(INPUT, 3)
    val out = UInt(OUTPUT, 32)
  }

  io.out := MuxCase(UInt(0),
    Array(
      (io.opcode === UInt(0)) -> (io.a + io.b),
      (io.opcode === UInt(1)) -> (io.a - io.b),
      (io.opcode === UInt(2)) -> (io.a & io.b),
      (io.opcode === UInt(3)) -> (io.a | io.b),
      (io.opcode === UInt(4)) -> (io.a ^ io.b),
      (io.opcode === UInt(5)) -> (io.a >> io.b),
      (io.opcode === UInt(6)) -> (io.a << io.b)
    )
  )

}

class AluTests(c: Alu) extends Tester(c) {
}


object Alu {
  def main(args: Array[String]): Unit = {
    args.foreach(arg => println(arg))
    chiselMainTest(args, () => Module(new Alu())) {
      c => new AluTests(c) }
  }
}

cd到工程的根文件夹下(即和build.sbt平行)。然后在命令行中执行sbt run来编译代码。 第一次运行编译时会自动下载 Chisel 以及相关依赖包,具体时间取决于网络质量。成功运行一次后将直接从本地调用。 如果编译通过的话可以用sbt "run --backend v"生成 Verilog,不过没测试过的代码直接下板调试似乎不太合适。

编写测试代码

Alu.scala:补全class AluTests(c: Alu) extends Tester(c)里的测试代码。

class AluTests(c: Alu) extends Tester(c) {

  for (i <- 0 until 7) {
    val a      = rnd.nextInt(1 << 16)
    val b      = rnd.nextInt(1 << 4)
    val opcode = i
    var output = 0
    if (opcode == 0) {
      output = ((a+b) & 0xFFFFFFFF)
    } else if (opcode == 1) {
      output = ((a-b) & 0xFFFFFFFF)
    } else if (opcode == 2) {
      output = ((a&b) & 0xFFFFFFFF)
    } else if (opcode == 3) {
      output = ((a|b) & 0xFFFFFFFF)
    } else if (opcode == 4) {
      output = ((a^b) & 0xFFFFFFFF)
    } else if (opcode == 5) {
      output = ((a>>b) & 0xFFFFFFFF)
    } else if (opcode == 6) {
      output = ((a<<b) & 0xFFFFFFFF)
    } else if (opcode == 7) {
      output = (0 & 0xFFFFFFFF)
    }
    poke(c.io.a, a)
    poke(c.io.b, b)
    poke(c.io.opcode, opcode)
    step(1)
    expect(c.io.out, output)
  }

}

生成 C++仿真代码,并运行测试。

sbt "run --backend c --compile --genHarness --test"

可选参数 --debug除了调试 io 接口外,内部逻辑也能调试,也就是说可以对除了 io 口意外的逻辑进行 peek/poke。 --vcd可生成波形辅助调试。用 gtkwave 打开生成的 vcd 文件。 --debugMem调试 Mem,可以对一个 Mem 类型元素执行 peekAt/pokeAt。 --vcdMem生成波形文件时将 Mem 内容也导出。

选择--vcd后产生的 vcd 文件用 gtkwave 打开即可。 可以通过"Write Save File"来保存当前工作环境,这样下次就不用一个个手动添加信号线了。 ”Reload Waveform“可以在 vcd 文件更新后重新载入,十分方便。

结束

生成 Verilog 代码,进入传统工作流下板验证。

sbt "run --backend v"

可选参数 --genHarness:生成一个空的 Verilog test bench。 ###传统工作流

  • 将生成的 Verilog 代码导入 ISE/Quartus/Diamond 工程中。

  • 可使用Alu-harness.v仿真。

    • 这个文件是按照与 Synposys VCS兼容的方式写的,用别的工具调用需修改过。
  • 执行 Verilog 仿真(小于 1M Cycle 建议采用 Chisel 仿真)

  • 下板验证

和直接使用 Verilog 的一些对比

alu.v

module Alu (/*AUTOARG*/
   // Outputs
   out,
   // Inputs
   a, b, s
   );

   input [31:0]    a;
   input [31:0]    b;
   input [3:0]     s;
   output [31:0]   out;

   reg [31:0]      out;
   always @*
     begin
        case(s)
          3'b000: out = a + b;
          3'b001: out = a - b;
          3'b010: out = a & b;
          3'b011: out = a | b;
          3'b100: out = a ^ b;
          3'b101: out = a << b;
          3'b110: out = a >> b;
        endcase
     end

endmodule

首先 Alu 应该是一个组合逻辑。上面 Verilog 代码为了使用 case 不得不写了 always 模块,并且声明了 out 为寄存器变量,综合出来的结果中会有寄存器,但是按照常理来说不应该有寄存器。当然 Verilog 里面使用三目运算符也能达到全组合逻辑的效果,不过写起来十分麻烦罢了。

使用 Chisel 的优点

  • 写测试代码十分方便,强调先测试仿真通过了再下板。Verilog 的 test bench 太繁琐。
  • 编辑代码可以使用 IDE,效率大大提高。
  • 端口声明修改方便,不像改一个名字得修改上下两处代码。
  • 实例化模块并连线方便,不用一条条线连,直接总线对接。
  • 避开使用看不清楚的 begin-end 对来包裹代码。
  • 组合逻辑时序逻辑区别清晰。
    • 比如,多周期 CPU 中计算下一个状态(next-state)时应该使用组合逻辑,所有中间变量都应该是 wire 类型,只有状态(state)寄存器声明成 reg 变量,每次在时钟上升沿更新为组合逻辑生成的 next-state。
    • 并不一定能用手写出很好的 Verilog 代码,所以让自动化工具生成合适的代码。

(实例待添加)

附:自动侦测修改并编译

若输入时不用sbt "run --test"而用sbt "~run --test"的话,每次完成后 sbt 不会退出,而会等待源码修改,帧测到修改后自动编译。 由于输入命令较多,这里提供一个脚本,每次就不用重复输入命令了。 run.sh

if [ "$1" == "clean" ]
then
    rm -rf emulator*
    rm -rf Alu*
    rm -rf target*
    rm -rf project/target*
fi

if [ "$1" == "c" ]
then
    sbt "~run --backend c --compile --genHarness --test --debug --vcd --debugMem --vcdMem"
fi

if [ "$1" == "v" ]
then
    sbt "~run --backend v --genHarness"
fi

用法: bash run.sh c生成仿真文件并测试。 bash run.sh v生成 Verilog 文件。 bash run.sh clean清理所有零时文件,包括生成的 C++/Verilog 文件。 ####附件:综合以及布线报告 Target Device: ZC7020
Vivado 2014.4

alu.v

---------------------------------------------------------------------------------
Start RTL Hierarchical Component Statistics
---------------------------------------------------------------------------------
Hierarchical RTL Component report
Module Alu
Detailed RTL Component Info :
+---Adders :
           3 Input     32 Bit       Adders := 1
+---XORs :
           2 Input     32 Bit         XORs := 1
+---Muxes :
           2 Input     32 Bit        Muxes := 1
           8 Input     32 Bit        Muxes := 1
           2 Input      1 Bit        Muxes := 1
           8 Input      1 Bit        Muxes := 1
---------------------------------------------------------------------------------
Finished RTL Hierarchical Component Statistics
---------------------------------------------------------------------------------

+-------------------------+------+-------+-----------+-------+
|        Site Type        | Used | Fixed | Available | Util% |
+-------------------------+------+-------+-----------+-------+
| Slice LUTs              |  268 |     0 |     53200 |  0.50 |
|   LUT as Logic          |  268 |     0 |     53200 |  0.50 |
|   LUT as Memory         |    0 |     0 |     17400 |  0.00 |
| Slice Registers         |   32 |     0 |    106400 |  0.03 |
|   Register as Flip Flop |    0 |     0 |    106400 |  0.00 |
|   Register as Latch     |   32 |     0 |    106400 |  0.03 |
| F7 Muxes                |   32 |     0 |     26600 |  0.12 |
| F8 Muxes                |    0 |     0 |     13300 |  0.00 |
+-------------------------+------+-------+-----------+-------+

+-------------------------------------------------------------+---------+-------+-----------+-------+
|                          Site Type                          |   Used  | Fixed | Available | Util% |
+-------------------------------------------------------------+---------+-------+-----------+-------+
| Slice                                                       |      81 |     0 |     13300 |  0.60 |
|   SLICEL                                                    |      57 |     0 |           |       |
|   SLICEM                                                    |      24 |     0 |           |       |
| LUT as Logic                                                |     268 |     0 |     53200 |  0.50 |
|   using O5 output only                                      |       0 |       |           |       |
|   using O6 output only                                      |     189 |       |           |       |
|   using O5 and O6                                           |      79 |       |           |       |
| LUT as Memory                                               |       0 |     0 |     17400 |  0.00 |
|   LUT as Distributed RAM                                    |       0 |     0 |           |       |
|   LUT as Shift Register                                     |       0 |     0 |           |       |
| LUT Flip Flop Pairs                                         |     268 |     0 |     53200 |  0.50 |
|   fully used LUT-FF pairs                                   |      32 |       |           |       |
|   LUT-FF pairs with unused LUT                              |       0 |       |           |       |
|   LUT-FF pairs with unused Flip Flop                        |     236 |       |           |       |
| Unique Control Sets                                         |       1 |       |           |       |
| Minimum number of registers lost to control set restriction | 0(Lost) |       |           |       |
+-------------------------------------------------------------+---------+-------+-----------+-------+

Alu.scala

---------------------------------------------------------------------------------
Start RTL Hierarchical Component Statistics
---------------------------------------------------------------------------------
Hierarchical RTL Component report
Module Alu
Detailed RTL Component Info :
+---Adders :
           3 Input     32 Bit       Adders := 1
+---XORs :
           2 Input     32 Bit         XORs := 1
+---Muxes :
           3 Input     32 Bit        Muxes := 3
           2 Input     32 Bit        Muxes := 5
---------------------------------------------------------------------------------
Finished RTL Hierarchical Component Statistics
---------------------------------------------------------------------------------

+-------------------------+------+-------+-----------+-------+
|        Site Type        | Used | Fixed | Available | Util% |
+-------------------------+------+-------+-----------+-------+
| Slice LUTs              |  285 |     0 |     53200 |  0.53 |
|   LUT as Logic          |  285 |     0 |     53200 |  0.53 |
|   LUT as Memory         |    0 |     0 |     17400 |  0.00 |
| Slice Registers         |    0 |     0 |    106400 |  0.00 |
|   Register as Flip Flop |    0 |     0 |    106400 |  0.00 |
|   Register as Latch     |    0 |     0 |    106400 |  0.00 |
| F7 Muxes                |    0 |     0 |     26600 |  0.00 |
| F8 Muxes                |    0 |     0 |     13300 |  0.00 |
+-------------------------+------+-------+-----------+-------+

+-------------------------------------------------------------+---------+-------+-----------+-------+
|                          Site Type                          |   Used  | Fixed | Available | Util% |
+-------------------------------------------------------------+---------+-------+-----------+-------+
| Slice                                                       |      82 |     0 |     13300 |  0.61 |
|   SLICEL                                                    |      61 |     0 |           |       |
|   SLICEM                                                    |      21 |     0 |           |       |
| LUT as Logic                                                |     285 |     0 |     53200 |  0.53 |
|   using O5 output only                                      |       1 |       |           |       |
|   using O6 output only                                      |     223 |       |           |       |
|   using O5 and O6                                           |      61 |       |           |       |
| LUT as Memory                                               |       0 |     0 |     17400 |  0.00 |
|   LUT as Distributed RAM                                    |       0 |     0 |           |       |
|   LUT as Shift Register                                     |       0 |     0 |           |       |
| LUT Flip Flop Pairs                                         |     284 |     0 |     53200 |  0.53 |
|   fully used LUT-FF pairs                                   |       0 |       |           |       |
|   LUT-FF pairs with unused LUT                              |       0 |       |           |       |
|   LUT-FF pairs with unused Flip Flop                        |     284 |       |           |       |
| Unique Control Sets                                         |       0 |       |           |       |
| Minimum number of registers lost to control set restriction | 0(Lost) |       |           |       |
+-------------------------------------------------------------+---------+-------+-----------+-------+

Blog maintained by Tao J

No longer hosted on GitHub Pages — Theme by mattgraham