首页 > 其他分享 >『chisel』通过最小项目理解 Chisel 项目结构

『chisel』通过最小项目理解 Chisel 项目结构

时间:2024-10-04 19:49:48浏览次数:11  
标签:info sbt scala chisel 项目 Chisel helloworld Hello

本文写于 2024年10月4日,此时 chisel 最新版本为 6.5.0 。

Overview

Chisel (Constructing Hardware In a Scala Embedded Language) 是新兴的硬件描述语言,是采用Scala作为基础、利用chisel第三方库的Domain Specific Language。本文记录了一次从github上的模板工程开始跑通一个最小Chisel工程以获得Verilog的过程。

获取 Github repo

首先通过这个链接获取 Github 项目模板并跟随指引部署到自己的 Github 仓库:Chisel Project Template
我把基于这个模板新建的repo命名为: chisel_helloworld 。这个仓库包含很多东西,其中我们需要关注的内容有:

chisel_helloworld
├── ...
├── README.md
├── src
│   ├── main
│   │   └── scala
│   │       ├── gcd
│   │       │   ├── DecoupledGCD.scala
│   │       │   └── GCD.scala
│   │       └── misc
│   │           └── Hello.scala
│   └── test
│       └── scala
│           └── gcd
│               └── GCDSpec.scala
├── build.sbt
└── build.sc

其中 src/main/scala/misc/Hello.scala 是我添加的文件,其内容为:

package misc

/*
 * This code is a minimal hardware described in Chisel.
 * 
 * Blinking LED: the FPGA version of Hello World
 */
import chisel3._

/**
 * The blinking LED component.
 */
class Hello extends Module {
  val io = IO(new Bundle {
    val led = Output(UInt(1.W))
  })
  val CNT_MAX = (50000000 / 2 - 1).U

  val cntReg = RegInit(0.U(32.W))
  val blkReg = RegInit(0.U(1.W))

  cntReg := cntReg + 1.U
  when(cntReg === CNT_MAX) {
    cntReg := 0.U
    blkReg := ~blkReg
  }
  io.led := blkReg
}

/**
 * An object extending App to generate the Verilog code.
 */
object Hello extends App {
  emitVerilog(new Hello())
}

这份代码来自 chisel-example 。我修改了两处:

  • 第一行的 package misc :在同一个 package 里面可以有很多份代码,会在后面再讨论这件事情
  • 倒数第二行的 emitVerilog(new Hello()) :顾名思义,这里是构建产生 .vverilog 文件的语句,其完整API路径是 chisel3.emitVerilog ,由于我们有一个 import chisel3._ 因此这里可以直接使用

构建项目得到 verilog 文件

Scala的构建工具有两个,一个是 SBT ,另一个是 mill 。从上面的文件目录树里可以看到有 build.sbtbuild.sc 两个文件,前者是 SBT 的配置文件,后者是 mill 的配置文件。只要有 build.sbt 就可以使用 SBT 进行构建;使用 mill 的项目则常常同时具有 build.sbtbuild.sc 。这两个文件是项目配置文件,打开 build.sbt 就能看到所用 Scala 以及 Chisel 的版本信息。
上面这个项目中的 build.sbt 文件长这样:

// See README.md for license details.

ThisBuild / scalaVersion     := "2.13.12"
ThisBuild / version          := "0.1.0"
ThisBuild / organization     := "com.github.playasmegumin"

val chiselVersion = "6.2.0"

lazy val root = (project in file("."))
  .settings(
    name := "chisel_helloworld",
    libraryDependencies ++= Seq(
      "org.chipsalliance" %% "chisel" % chiselVersion,
      "org.scalatest" %% "scalatest" % "3.2.16" % "test",
    ),
    scalacOptions ++= Seq(
      "-language:reflectiveCalls",
      "-deprecation",
      "-feature",
      "-Xcheckinit",
      "-Ymacro-annotations",
    ),
    addCompilerPlugin("org.chipsalliance" % "chisel-plugin" % chiselVersion cross CrossVersion.full),
  )

可以看到这里的 Chisel 版本是 6.2.0 。Chisel 的版本迭代非常快,在跑网络上的 demo 时如果出现编译问题请查看对应版本的 Chisel API ,链接在这: Docs - chisel-lang
因为没搞明白 mill 怎么使,这里我用的是 SBT ,直接在项目根目录运行 sbt run 即可。

$ sbt run
[info] welcome to sbt 1.9.7 (Eclipse Adoptium Java 17.0.12)
[info] loading settings for project chisel_helloworld-build from plugins.sbt ...
[info] loading project definition from /home/duzelong/ysyx/chisel/chisel_helloworld/project
[info] loading settings for project root from build.sbt ...
[info] set current project to chisel_helloworld (in build file:/home/duzelong/ysyx/chisel/chisel_helloworld/)
[info] compiling 1 Scala source to /home/duzelong/ysyx/chisel/chisel_helloworld/target/scala-2.13/classes ...

Multiple main classes detected. Select one to run:
 [1] gcd.GCD
 [2] misc.Hello

Enter number:

因为在 src/main/scala 下面有两个 “包” :

└── src
    └── main
        └── scala
            ├── gcd
            │   ├── DecoupledGCD.scala
            │   └── GCD.scala
            └── misc
                └── Hello.scala

所以这里 SBT 给了我们两个选项,一个是 gcd 包的 GCD ,另一个是 misc 包的 Hello 。这里需要辨析一下,包的归属和目录结构没有什么关系,主要是在 GCD.scalaHello.scala 分别用 package gcdpackage misc 定义了各自所属的包名。文件夹结构可以随你喜欢的设置,不会有很大的影响。一开始我还尝试了这样的放置方法:

└── src
    └── main
        └── scala
            ├── gcd
            │   ├── DecoupledGCD.scala
            │   └── GCD.scala
            └── Hello.scala

也并不影响文件和 package 的从属关系,这个 package 事实上很像命名空间。如果采用下面的目录结构,同时删除 src/main/scala/Hello.scalapackage misc

└── src
    └── main
        └── scala
            ├── gcd
            │   ├── DecoupledGCD.scala
            │   └── GCD.scala
            ├── misc
            │   └── Hello.scala
            └── Hello.scala         

则运行 sbt run 后会显示:

$ sbt run
[info] welcome to sbt 1.9.7 (Eclipse Adoptium Java 17.0.12)
[info] loading settings for project chisel_helloworld-build from plugins.sbt ...
[info] loading project definition from /home/duzelong/ysyx/chisel/chisel_helloworld/project
[info] loading settings for project root from build.sbt ...
[info] set current project to chisel_helloworld (in build file:/home/duzelong/ysyx/chisel/chisel_helloworld/)
[info] compiling 1 Scala source to /home/duzelong/ysyx/chisel/chisel_helloworld/target/scala-2.13/classes ...

Multiple main classes detected. Select one to run:
 [1] Hello
 [2] gcd.GCD
 [3] misc.Hello

Enter number:

可见,在不同包里的 Hello 模块不会互相冲突,但是如果两个 Hello.scala 中都有 package misc ,则会下面的结果:

$ sbt run
[info] welcome to sbt 1.9.7 (Eclipse Adoptium Java 17.0.12)
[info] loading settings for project chisel_helloworld-build from plugins.sbt ...
[info] loading project definition from /home/duzelong/ysyx/chisel/chisel_helloworld/project
[info] loading settings for project root from build.sbt ...
[info] set current project to chisel_helloworld (in build file:/home/duzelong/ysyx/chisel/chisel_helloworld/)
[info] compiling 1 Scala source to /home/duzelong/ysyx/chisel/chisel_helloworld/target/scala-2.13/classes ...
[info] compiling 2 Scala sources to /home/duzelong/ysyx/chisel/chisel_helloworld/target/scala-2.13/classes ...
[error] /home/duzelong/ysyx/chisel/chisel_helloworld/src/main/scala/misc/Hello.scala:14:7: Hello is already defined as class Hello
[error] class Hello extends Module {
[error]       ^
[error] /home/duzelong/ysyx/chisel/chisel_helloworld/src/main/scala/misc/Hello.scala:34:8: Hello is already defined as object Hello
[error] object Hello extends App {
[error]        ^
[error] two errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 2 s, completed 2024年10月4日 下午7:29:02

就是很经典的符号冲突错误。
接上面的步骤,我们运行 sbt run 后选择 misc.Hello ,则有:

$ sbt run
[info] welcome to sbt 1.9.7 (Eclipse Adoptium Java 17.0.12)
[info] loading settings for project chisel_helloworld-build from plugins.sbt ...
[info] loading project definition from /home/duzelong/ysyx/chisel/chisel_helloworld/project
[info] loading settings for project root from build.sbt ...
[info] set current project to chisel_helloworld (in build file:/home/duzelong/ysyx/chisel/chisel_helloworld/)
[info] compiling 2 Scala sources to /home/duzelong/ysyx/chisel/chisel_helloworld/target/scala-2.13/classes ...

Multiple main classes detected. Select one to run:
 [1] Hello
 [2] gcd.GCD
 [3] misc.Hello

Enter number: 3
[info] running misc.Hello 
[success] Total time: 10 s, completed 2024年10月4日 下午7:31:03

然后会在根目录里发现多了一个 Hello.sv ,里面就是我们需要的 Verilog 代码,至此本文的目的就达成了。

Others

当然这里还有其他几个值得细究的点。

在哪里都能运行 sbt run 吗?

目前看来是不行,如果在 src/ 目录下运行 sbt run 就会有这样的后果:

src$ sbt run
[warn] No sbt.version set in project/build.properties, base directory: /home/duzelong/ysyx/chisel/chisel_helloworld/src
[info] welcome to sbt 1.10.2 (Eclipse Adoptium Java 17.0.12)
[info] set current project to src (in build file:/home/duzelong/ysyx/chisel/chisel_helloworld/src/)
[error] java.lang.RuntimeException: No main class detected.
[error] 	at scala.sys.package$.error(package.scala:30)
[error] stack trace is suppressed; run last Compile / bgRun for the full output
[error] (Compile / bgRun) No main class detected.
[error] Total time: 1 s, completed 2024年10月4日 下午7:32:24

看来在哪里运行 sbt runSBT 就会把哪里当作项目的根目录。

生成 Hello.sv 的位置可以改吗?

在项目根目录运行 sbt run 的时候就会在根目录生成 Hello.sv 。我猜测是直接把输出文件生成在了运行 sbt run 的目录。但是实际上只能在项目根目录运行 sbt run ,因此我的猜测没什么意义。
如果要修改生成 verilog 文件的路径,可能需要深入 SBT 的构建脚本,那就之后再看。

生成 verilog 文件的项目组件是什么?

似乎是用 FIRRTL 生成的,可以再看看。这块应该是 Chisel 自身的特性。

标签:info,sbt,scala,chisel,项目,Chisel,helloworld,Hello
From: https://www.cnblogs.com/Chorolop/p/18447183

相关文章

  • 项目总结
    一.gee-web1.实现目标GeeWeb是一个极简的Go语言Web框架,设计目标是为开发者提供一个简单、高效且易于扩展的Web框架。它通过Go的内置并发特性(goroutine)、接口和反射等机制,实现了基本的路由、请求处理、分组、中间件等功能,帮助开发者快速构建Web应用程序。2.总的......
  • 从零开始创建一个空白的Vue项目(自用)
    目录一、配置node环境1.安装nvm2.安装node二、创建Vue项目1.创建Vue项目2.空白页面三、安装Vue3UI框架(ElementPlus)一、配置node环境1.安装nvm    可以在github下载nvm安装包,安装路径不要有中文。     在vscode里面按ctrl+shift+~打开命......
  • Vue3的项目搭建
    有两种方式可以搭建:一:使用vue-cli中的webpack创建 第二:推荐使用vite来创建项目vite是新一代前端构建工具,新的前端构建工具,比webpack要快一些。npmcreatevue@latest创建完项目后,我们可以看到项目最外层有index.htmlVite项目中,index.html是项目的入口文件,在项目最外层。......
  • [Electron] 搭建 Vite+Electron 项目
    安装搭建Vite项目(根据官方文档搭建),安装electron、nodemon。pnpminstallelectronnodemon-D配置electron/main.jsfile:[electron/main.js]import{app,BrowserWindow}from"electron";constcreateWindow=()=>{constwin=newBrowserWindow({wid......
  • 使用Maven创建多模块项目
    主项目:pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/......
  • SpringBoot项目使用yml文件链接数据库异常
    SpringBoot使用properties连接数据库时没有出现问题SpringBoot使用yml连接数据库时出现:UnabletoconnecttoRedis并在报错信息中出现:发现是用户或者密码出现问题通过查询知道yml是区分数据类型的,所以如果用户名或者密码是数字的话,就要注意将密码用双引号括起来,将其识别为......
  • Xcode11上新创建项目build fail
    在mac上新装Xcode11,新创建了一个工程,点击运行一直buildfail,并且没有显示报错。点击xcode左侧边栏最右边的ShowtheReportnavigator,显示报表导航器,如下图报错信息为ShowingRecentIssuesCouldn'tcreateworkspacearenafolder'/Users/hyt/Library/Developer/Xcode/Deriv......
  • o1 式开源推理链项目 g1:可基于 Llama 3.2-90b 模型
    g1简介g1是一个开源项目,利用Llama3.170b模型在Groq硬件上实现类似OpenAIo1的推理链能力。项目通过精心设计的提示策略引导语言模型进行逐步推理,解决了传统语言模型在逻辑推理方面的不足。工作原理利用动态推理链,逐步引导Llama3.1模型完成复杂逻辑问题模型按......
  • IDEA创建、导入、删除maven项目
    全局配置:1.File->CloseProject2.Customize->Allsettings3.Apply4.选择JRE版本->Apply5.选择字节码版本->Apply->OK全局配置结束创建maven项目:1.File->New->Module2.Buildsystem选择MavenGroupId:域名反写ArtifactId:模块名(设置Location)Create3.编写的java......
  • VUE前后端分离毕业设计题目项目有哪些,VUE程序开发常见毕业论文设计推荐
               目录0为什么选择Vue.js1Vue.js的主要特点2前后端分离毕业设计项目推荐3后端推荐4总结0为什么选择Vue.js        使用Vue.js开发计算机毕业设计是一个很好的选择,因为它不仅具有现代前端框架的所有优点,还能让你专注于构建高性......