• 硬件描述语言 Chisel 入门教程


    硬件描述语言 Chisel 入门教程

    硬件描述语言 Chisel 入门教程

    目录

    1. Chisel简介
    2. 安装Chisel环境

    Chisel简介

    Chisel是一个Scala库,用于构建高级别的、可综合的、模块化的硬件设计。它允许设计师在高层次上定义硬件的行为,然后通过一系列的转换步骤将其转换为低层次的Verilog或VHDL代码。这使得设计师可以专注于实现硬件的功能,而不需要关心底层的细节。

    Chisel的主要特点包括:

    • 高级抽象:使用Scala的高级别抽象来描述硬件行为。
    • 可综合:生成的Verilog或VHDL代码可以直接用于ASIC或FPGA的设计。
    • 模块化:可以将设计分解为多个独立的模块,每个模块都可以独立地进行测试和验证。
    • 交互式开发:可以在Scala REPL中直接运行Chisel代码,以便于调试和验证。

    安装Chisel环境

    要开始使用Chisel,首先需要安装Scala和sbt(Simple Build Tool)。以下是在Ubuntu系统上安装Chisel环境的步骤:

    1. 安装Java Development Kit (JDK) 8或更高版本。可以使用以下命令进行安装:
    sudo apt-get update
    sudo apt-get install openjdk-8-jdk
    
    • 1
    • 2
    1. 安装sbt。可以使用以下命令进行安装:
    echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
    sudo apt-get update
    sudo apt-get install sbt
    
    • 1
    • 2
    • 3
    1. 安装Chisel。可以使用以下命令进行安装:
    echo "addSbtPlugin("io.github.chipsalliance" % "chisel3" % "3.4.3")" | sbt -- new file > build.sbt
    
    • 1
    1. 创建一个新的Chisel项目。可以使用以下命令进行创建:
    sbt new chisel3.examples.HelloWorld --compiler=firrtl --backend-name verilator --main-class examples.HelloWorld --copy-resources
    
    • 1
    1. 进入项目目录并编译项目。可以使用以下命令进行编译:
    cd helloworld && sbt "runMain examples.HelloWorld"
    
    • 1

    现在,你已经成功安装了Chisel环境,并创建了一个简单的HelloWorld项目。接下来,你可以开始学习如何使用Chisel编写硬件设计了。

    硬件描述语言 Chisel 入门教程

    本教程将介绍硬件描述语言 Chisel 的基本语法和如何构建 Chisel 项目。

    基础语法

    Chisel 是一种基于 Scala 的硬件描述语言,用于设计和实现可重用的硬件组件。以下是一些基本的 Chisel 语法:

    定义数据类型

    在 Chisel 中,可以使用 typedef 关键字定义新的数据类型。例如,定义一个名为 MyData 的数据类型:

    import chisel3._
    
    class MyData extends Bundle {
      val data = UInt(8.W)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    定义模块

    使用 module 关键字定义一个新的 Chisel 模块。例如,定义一个名为 MyModule 的模块:

    import chisel3._
    import MyData
    
    class MyModule extends Module {
      val io = IO(new MyData)
      // ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    实例化模块

    在 Chisel 中,可以使用 withClock() 方法为模块添加时钟信号。例如,实例化一个名为 myInstanceMyModule

    import chisel3._
    import MyData
    import MyModule
    
    val myInstance = Module(new MyModule()).withClock(io.clock)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    构建 Chisel 项目

    要构建一个 Chisel 项目,需要遵循以下步骤:

    1. 安装 Chisel:首先需要安装 Chisel,可以通过以下命令安装:

      sbt install # for Linux/macOS users, or...
      gradlew install # for Windows users, or...
      
      • 1
      • 2
    2. 创建一个新的 Chisel 项目:可以使用 sbt newgradle init 命令创建一个新的 Chisel 项目。例如,使用 sbt new 命令创建一个名为 myProject 的新项目:

      sbt new myProject/helloworld.g8 # replace "myProject" with your desired project name, and "helloworld" with your desired template name.
      
      • 1
    3. 编写 Chisel 代码:在项目中编写 Chisel 代码,并保存到相应的文件中。例如,在 src/main/scala/myProject/HelloWorld.scala 文件中编写以下代码:

      import chisel3._
      import chisel3.util._ // optional: import the necessary libraries from chisel3-util package, e.g., for Verilog generation.
      // ... define your Chisel modules here ...
      
      • 1
      • 2
      • 3
    4. 编译和运行项目:使用 sbt rungradle run 命令编译和运行项目。例如,使用 sbt run 命令编译和运行项目:

      sbt run # on Linux/macOS users, or...
      gradlew run # on Windows users, or...
      
      • 1
      • 2

    模块定义与使用

    在硬件描述语言 Chisel 中,模块是构建电路的基本单位。一个模块可以包含一系列的输入输出端口、内部信号以及用于描述电路行为的函数。要创建一个模块,需要继承 chisel3.Module 类并重写其 build() 方法。以下是一个简单的模块定义示例:

    import chisel3._
    
    class MyModule extends Module {
      val io = IO(new Bundle {
        val in = Input(UInt(8.W))
        val out = Output(UInt(8.W))
      })
    
      io.out := io.in + 1.U
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这个示例中,我们定义了一个名为 MyModule 的模块,它有一个 8 位无符号整数输入端口 in,一个 8 位无符号整数输出端口 out,以及一个内部信号 out。build() 方法中的代码将 in 端口的值加 1,然后将结果赋值给 out 端口。

    接下来,我们需要将这个模块实例化到硬件上。这可以通过创建一个新的 Chisel 工程并添加上述模块定义来实现。以下是一个简单的 Chisel 工程结构:

    my_project/
    |-- src/
    |   |-- main/
    |   |   |-- resources/
    |   |-- test/
    |-- build.sbt
    |-- project/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    src/main/resources 目录下创建一个名为 MyModule.scala 的文件,将上述模块定义粘贴到该文件中。然后,在 build.sbt 文件中添加以下依赖项:

    libraryDependencies += "edu.berkeley.cs" %% "chisel3" % "3.4.3"
    
    • 1

    最后,在 src/main/scala 目录下创建一个名为 Main.scala 的文件,并添加以下代码以实例化 MyModule:

    import chisel3._
    import my_project.src.main.resources.MyModule
    
    object Main extends App {
      (new ChiselStage).emitVerilog(new MyModule())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    现在,你可以使用 sbt 编译和运行这个项目。在终端中进入项目根目录,然后执行以下命令:

    sbt "runMain my_project.src.main.scala.Main"
    
    • 1

    这将生成 Verilog 文件并将其打印到控制台。你可以将这些文件导入到你的 FPGA 设计工具中进行进一步的开发和调试。

    生成Verilog代码

    在硬件描述语言Chisel中,我们可以通过定义模块并使用emitVerilog方法来生成Verilog代码。以下是一个简单的例子:

    import chisel3._
    
    class MyModule extends Module {
      val io = IO(new Bundle {
        val in = Input(UInt(8.W))
        val out = Output(UInt(8.W))
      })
    
      io.out := io.in + 1.U
    }
    
    object MyModule extends App {
      chisel3.Driver.execute(args, () => new MyModule())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这个例子中,我们定义了一个名为MyModule的模块,它有一个输入in和一个输出out。然后我们在main方法中使用chisel3.Driver.execute方法来生成Verilog代码。

    测试与验证

    在Chisel中,我们可以使用Scala的断言(assert)来进行测试和验证。以下是一个简单的例子:

    import chisel3._
    import org.scalatest._
    import chisel3.util._
    
    class MyModuleTest extends FreeSpec with ChiselScalatestTester {
      "MyModule" should "work correctly" in {
        test(new MyModule) { c =>
          c.io.in := 2.U
          c.clock.step(10)
          c.io.out.expect(3.U)
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这个例子中,我们定义了一个名为MyModuleTest的测试类,它继承自FreeSpecChiselScalatestTester。然后我们在should work correctly这个测试中,创建了一个MyModule的实例,设置了输入为2,然后让时钟走10个周期,最后检查输出是否为3。

    硬件描述语言 Chisel 高级特性

    Chisel 是一种硬件描述语言,它允许开发者使用 Scala 或 Java 来定义硬件。在掌握了基本的 Chisel 语法和概念之后,我们可以开始学习一些高级特性。

    1. 类型层次结构

    Chisel 支持丰富的类型层次结构,包括 Bits、Bool、Int、FixedPoint 等。通过继承这些基本类型,我们可以创建自定义的硬件数据类型。

    import chisel3._
    
    class MyData extends Bundle {
      val myBits = UInt(8.W)
      val myBool = Bool()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2. 组合逻辑和时序逻辑

    Chisel 支持组合逻辑和时序逻辑的混合设计。我们可以通过 withClock 方法将一个组合逻辑模块转换为时序逻辑模块。

    import chisel3._
    import chisel3.util._
    
    class MyModule extends Module {
      val io = IO(new MyBundle)
      val myReg = Reg(UInt(8.W))
    
      withClock(io.clock) {
        myReg := io.myIn
        io.myOut := myReg
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3. 状态机设计

    Chisel 提供了一套简洁的状态机设计方法,我们可以通过 wheniselsewhenotherwise 等关键词来定义状态转换逻辑。

    import chisel3._
    import chisel3.util._
    
    class MyFSM extends Module {
      val io = IO(new MyBundle)
      val stateReg = RegInit(0.U(2.W))
    
      when (io.reset) {
        stateReg := 0.U
      } .otherwise {
        when (io.next) {
          stateReg := stateReg + 1.U
        } .otherwise {
          stateReg := stateReg - 1.U
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    leetcode做题笔记126. 单词接龙 II
    分布式架构在云计算平台中的应用及优缺点
    Spring底层原理学习笔记--第三讲--(bean生命周期与模板方法)
    【进程同步】 JAVA 单生产者-单消费者
    docker技术简介
    SpringCloud 学习笔记总结 (二)
    一文带你入门微服务,通俗易懂
    kafka的“直接内存映射技术”,有没有内存修改数据的问题?
    我们用python来写一个节点间消息收发的demo
    企业级智能PDF及文档处理SDK GdPicture.NET 14.2 Crack
  • 原文地址:https://blog.csdn.net/raw_inputhello/article/details/136291691