文章目录
- 前言
- Chisel介绍
- 一、vscode搭建scala开发环境
- 1.1 安装Scala官方插件
- 1.2 创建hello_world.scala文件
- 1.3 确认java的版本(博主使用的是1.8)
- 1.4 下载Scala Windows版本的二进制文件
- 1.5 配置环境变量
- 1.6 交互模式测试一下
- 1.7 vscode运行scala
- 二、windows安装sbt
- 2.1 下载sbt
- 2.2 设置环境变量
- 2.3 sbt配置
- 2.4 设置阿里云镜像
- 2.5 验证
- 三、用Chisel点亮FPGA小灯
- 3.1 参考文档
- 3.2 得到Verilog文件
- 1. 环境搭建
- 2. 克隆项目
- 3. 编译运行
- 4. 生成Verilog文件
- 3.3 上板验证
- 1. 创建quartus项目
- 2. 加入.v文件
- 3. 绑定引脚
- 4. 上板烧录
- 四、在DE2-115开发板上重做Verilog实验
- 4.1 流水灯
- 总结
- 参考
前言
由于verilog效率比较低下,重复劳动太多了QAQ
所以打算用近两年比较火的chisel进行开发。
于是先装一波环境,踩了一天的坑。
传统数字芯片的RTL设计采用Verilog语言为主,Chisel语言的全称是Constructing Harward in Scala Embeded Language,即在Scala语言中导入Chisel3库,即可使用Chisel语言。其特点是面向对象编程,可以方便地参数化定制硬件电路,加快设计流程。目前在RISC-V生态中应用较多,中科院计算所主持的培育下一代处理器设计人才的“一生一芯”项目也在极力推进该语言。
Chisel介绍
Chisel 是一种构建硬件描述语言(HDL)的高级编程语言,它允许硬件设计师以更抽象的方式编写代码,然后编译生成低级的硬件描述语言(通常是Verilog)代码,进而用于 FPGA 或 ASIC 的设计实现。Chisel 由加州大学伯克利分校的伯克利软件定义硬件(BSDH)项目开发,其主要目标是提高硬件设计的生产效率、可读性和可维护性。
概念:
Chisel 结合了现代软件工程的原理与硬件设计的实践,支持面向对象编程特性,如类、继承、多态等,同时也引入了静态类型和类型安全的概念,有助于在设计阶段捕捉错误。它利用Scala 语言作为基础,这意味着设计师可以利用Scala 强大的库和工具生态系统。Chisel 提供了一套丰富的数据类型和构造,使得设计者能够以高层次的抽象来描述数字电路,比如向量、内存、多路复用器等,并且支持参数化模块,便于设计复用和配置。
用途:
提高设计效率:Chisel 的高层抽象能力使得设计师可以更快地实现复杂的数字电路设计,减少手动编写底层 HDL 代码的工作量。
增强可读性和可维护性:通过使用高级语言特性,Chisel 设计的代码更加接近自然语言,易于阅读和理解,有利于团队协作和长期维护。
促进设计复用:Chisel 支持模块化和参数化设计,便于创建可配置的组件库,加速后续项目开发。
简化验证流程:Chisel 设计可以直接与验证框架(如Chisel Testers 2)集成,支持快速创建测试平台,加速设计验证过程。
教育和研究:Chisel 的高级特性降低了硬件设计的入门门槛,使其成为教学和研究的理想工具,特别是在计算机体系结构和并行计算领域。
综上所述,Chisel 作为一种现代化的硬件设计语言,极大地提升了硬件设计的抽象层次,促进了设计的灵活性、高效性和质量,是现代硬件设计和研究中的一个重要工具。
学习Chisel语法规则等可以在吃透Chisel语言吃透Chisel语言进行学习
一、vscode搭建scala开发环境
1.1 安装Scala官方插件
在VS Code中安装插件,先安装 Scala Syntax (official)
,再安装 Scala (Metals)
:
(官方插件,有个语法高亮功能也挺香的)
1.2 创建hello_world.scala文件
代码如下:
object HelloWorld
{
def main(args: Array[String]): Unit = {
println("Hello, world!")
}
}
1.3 确认java的版本(博主使用的是1.8)
1.4 下载Scala Windows版本的二进制文件
下载链接:
https://downloads.lightbend.com/scala/2.13.3/scala-2.13.3.msi
双击进行安装,并一路 next
记住安装路径,等下配置环境变量需要用
博主的安装路径为:
1.5 配置环境变量
1.刚刚让记的那个 安装路径
2.PATH变量下再新增值
至此 安装完毕
。
1.6 交互模式测试一下
至此 Scala开发环境搭建成功
1.7 vscode运行scala
二、windows安装sbt
2.1 下载sbt
官网:http://www.scala-sbt.org/download.html
无脑执行下一步即可,注意 记住安装位置 ,方便后续环境变量的配置
2.2 设置环境变量
#SBT_HOME
设置为sbt解压目录,例如:
SBT_HOME=C:\Programs\sbt;
添加到 系统变量 中:
添加到 path 中:
2.3 sbt配置
修改 sbt\conf\sbtconfig.txt
为以下内容:
# sbt configuration file for Windows
# Set the java args
#-mem 1024 was added in sbt.bat as default
-Xms1024m
-Xmx1024m
-Xss4M
-XX:ReservedCodeCacheSize=128m
# Set the extra sbt options
-Dsbt.log.format=true
-Dsbt.boot.directory=D:/SoftWare/scala-2.13.3/sbt/boot/
-Dsbt.global.base=D:/SoftWare/scala-2.13.3/sbt/.sbt
-Dsbt.ivy.home=D:/SoftWare/scala-2.13.3/sbt/.ivy2
-Dsbt.repository.config=D:/SoftWare/scala-2.13.3/sbt/conf/repo.properties
-Dsbt.override.build.repos=true
2.4 设置阿里云镜像
国内的网络环境复杂,阿里云还挺好用的,在 sbt\conf\
下新建 repo.properties
文件,内容为:
[repositories]
local
aliyun-central: https://maven.aliyun.com/repository/central
aliyun-public: https://maven.aliyun.com/repository/public
jcenter: https://jcenter.bintray.com/
repo1: https://repo1.maven.org/maven2/
store_2: https://repo2.maven.org/maven2/
aliyun-releases: https://maven.aliyun.com/repository/releases
aliyun-apache-snapshots: https://maven.aliyun.com/repository/apache-snapshots
aliyun-google: https://maven.aliyun.com/repository/google
aliyun-jcenter: https://maven.aliyun.com/repository/jcenter
aliyun-spring: https://maven.aliyun.com/repository/spring
aliyun-spring-plugin: https://maven.aliyun.com/repository/spring-plugin
sbt-plugin: https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/
sonatype: https://oss.sonatype.org/content/repositories/snapshots
typesafe: https://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly
typesafe2: https://repo.typesafe.com/typesafe/releases/
atlassian: https://packages.atlassian.com/content/repositories/atlassian-public/
spring-plugin: https://repo.spring.io/plugins-release/
hortonworks: https://repo.hortonworks.com/content/repositories/releases/
2.5 验证
完成后打开cmd,输入 sbt,可能会有一段下载依赖包的过程,成功后会进入命令行,即sbt安装成功。
退出方式:在命令框中输入 exit 即可退出:
三、用Chisel点亮FPGA小灯
3.1 参考文档
参考的chisel书为chisel-book,是一个PDF文档,
Chisel-book: https://wwu.lanzoue.com/isdim08x8x5i
3.2 得到Verilog文件
1. 环境搭建
找到其中 WINDOWS开发环境搭建。
OK,按着以上内容下载所需要的软件(前面我们已经配置好了环境)。
question: 哪能找到一个Chisel例程?
OK,继续看这本书,这是本好书,Hello world例程书里有了,代码在Git上
2. 克隆项目
继续找到了GIT上的chisel-examples.
OK 点击去GIT上 克隆下来,
github:https://github.com/schoeberl/chisel-examples
好了,找到helloworld例程了。现在想想例程怎么编译?生成Verilog代码在哪?
书中3.7章节有写
3. 编译运行
书里只写了Chisel下的编译生成。至于下载到FPGA文档里说要自己动手,不在文档教程内了。
具体流程:
cmd命令下,
git clone https://github.com/schoeberl/chisel-examples.git
cd chisel-examples/hello-world/
执行编译 sbt run
第一次编译需要等待很长时间,然后显示成功。(因为我编译过了,所以第二次很快)。
Hello.scala
//点亮小灯
/*
* 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 {
(new chisel3.stage.ChiselStage).emitVerilog(new Hello())
}
4. 生成Verilog文件
OK,现在找生成的Verilog,书中说是 Hello.v文件
。
生成的 Hello.v 文件:
module Hello(
input clock,
input reset,
output io_led
);
`ifdef RANDOMIZE_REG_INIT
reg [31:0] _RAND_0;
reg [31:0] _RAND_1;
`endif // RANDOMIZE_REG_INIT
reg [31:0] cntReg; // @[Hello.scala 23:23]
reg blkReg; // @[Hello.scala 24:23]
wire [31:0] _cntReg_T_1 = cntReg + 32'h1; // @[Hello.scala 26:20]
assign io_led = blkReg; // @[Hello.scala 31:10]
always @(posedge clock) begin
if (reset) begin // @[Hello.scala 23:23]
cntReg <= 32'h0; // @[Hello.scala 23:23]
end else if (cntReg == 32'h17d783f) begin // @[Hello.scala 27:28]
cntReg <= 32'h0; // @[Hello.scala 28:12]
end else begin
cntReg <= _cntReg_T_1; // @[Hello.scala 26:10]
end
if (reset) begin // @[Hello.scala 24:23]
blkReg <= 1'h0; // @[Hello.scala 24:23]
end else if (cntReg == 32'h17d783f) begin // @[Hello.scala 27:28]
blkReg <= ~blkReg; // @[Hello.scala 29:12]
end
end
// Register and memory initialization
`ifdef RANDOMIZE_GARBAGE_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_INVALID_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_MEM_INIT
`define RANDOMIZE
`endif
`ifndef RANDOM
`define RANDOM $random
`endif
`ifdef RANDOMIZE_MEM_INIT
integer initvar;
`endif
`ifndef SYNTHESIS
`ifdef FIRRTL_BEFORE_INITIAL
`FIRRTL_BEFORE_INITIAL
`endif
initial begin
`ifdef RANDOMIZE
`ifdef INIT_RANDOM
`INIT_RANDOM
`endif
`ifndef VERILATOR
`ifdef RANDOMIZE_DELAY
#`RANDOMIZE_DELAY begin end
`else
#0.002 begin end
`endif
`endif
`ifdef RANDOMIZE_REG_INIT
_RAND_0 = {1{`RANDOM}};
cntReg = _RAND_0[31:0];
_RAND_1 = {1{`RANDOM}};
blkReg = _RAND_1[0:0];
`endif // RANDOMIZE_REG_INIT
`endif // RANDOMIZE
end // initial
`ifdef FIRRTL_AFTER_INITIAL
`FIRRTL_AFTER_INITIAL
`endif
`endif // SYNTHESIS
endmodule
以及顶层文件 hello_top.v
:
hello_top.v
/* Minimal top level for the Chisel Hello World.
Wire reset to 0. */
module hello_top(input clk, output led);
wire h_io_led;
wire res;
assign led = h_io_led;
assign res = 1'h0;
Hello h(.clock(clk), .reset(res),
.io_led( h_io_led ));
endmodule
3.3 上板验证
1. 创建quartus项目
板子型号为 EP4CE115F29C7
2. 加入.v文件
将生成的 Hello.v文件
和 hello_top.v文件
添加到项目中,并设置hello_top.v为顶层文件
3. 绑定引脚
根据技术文档,led的引脚如下,任意选择一个led
绑定引脚
4. 上板烧录
实现效果:
四、在DE2-115开发板上重做Verilog实验
4.1 流水灯
修改 Hello.scala 文件为:
import chisel3._
import chisel3.util._
class Hello extends Module {
val io = IO(new Bundle {
val led = Output(UInt(8.W)) // 8 位 LED 输出
})
val maxCount = (50000000 / 10).U // 调整这个参数改变流水灯的速度(DE2-115 使用 50MHz 时钟)
val counter = RegInit(0.U(32.W))
val position = RegInit(0.U(3.W))
// 计数器逻辑
counter := counter + 1.U
when(counter === maxCount) {
counter := 0.U
when(position === 7.U) {
position := 0.U
}.otherwise {
position := position + 1.U
}
}
// LED 输出逻辑
io.led := (1.U << position)
}
object Hello extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new Hello())
}
重新运行:
生成的Hello.v 文件,直接将该文件设置为顶层文件:
module Hello(
input clock,
input reset,
output [7:0] io_led
);
`ifdef RANDOMIZE_REG_INIT
reg [31:0] _RAND_0;
reg [31:0] _RAND_1;
`endif // RANDOMIZE_REG_INIT
reg [31:0] counter; // @[Hello.scala 57:24]
reg [2:0] position; // @[Hello.scala 58:25]
wire [31:0] _counter_T_1 = counter + 32'h1; // @[Hello.scala 61:22]
wire [2:0] _position_T_1 = position + 3'h1; // @[Hello.scala 67:28]
assign io_led = 8'h1 << position; // @[Hello.scala 72:18]
always @(posedge clock) begin
if (reset) begin // @[Hello.scala 57:24]
counter <= 32'h0; // @[Hello.scala 57:24]
end else if (counter == 32'h4c4b40) begin // @[Hello.scala 62:30]
counter <= 32'h0; // @[Hello.scala 63:13]
end else begin
counter <= _counter_T_1; // @[Hello.scala 61:11]
end
if (reset) begin // @[Hello.scala 58:25]
position <= 3'h0; // @[Hello.scala 58:25]
end else if (counter == 32'h4c4b40) begin // @[Hello.scala 62:30]
if (position == 3'h7) begin // @[Hello.scala 64:28]
position <= 3'h0; // @[Hello.scala 65:16]
end else begin
position <= _position_T_1; // @[Hello.scala 67:16]
end
end
end
// Register and memory initialization
`ifdef RANDOMIZE_GARBAGE_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_INVALID_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_MEM_INIT
`define RANDOMIZE
`endif
`ifndef RANDOM
`define RANDOM $random
`endif
`ifdef RANDOMIZE_MEM_INIT
integer initvar;
`endif
`ifndef SYNTHESIS
`ifdef FIRRTL_BEFORE_INITIAL
`FIRRTL_BEFORE_INITIAL
`endif
initial begin
`ifdef RANDOMIZE
`ifdef INIT_RANDOM
`INIT_RANDOM
`endif
`ifndef VERILATOR
`ifdef RANDOMIZE_DELAY
#`RANDOMIZE_DELAY begin end
`else
#0.002 begin end
`endif
`endif
`ifdef RANDOMIZE_REG_INIT
_RAND_0 = {1{`RANDOM}};
counter = _RAND_0[31:0];
_RAND_1 = {1{`RANDOM}};
position = _RAND_1[2:0];
`endif // RANDOMIZE_REG_INIT
`endif // RANDOMIZE
end // initial
`ifdef FIRRTL_AFTER_INITIAL
`FIRRTL_AFTER_INITIAL
`endif
`endif // SYNTHESIS
endmodule
引脚分配:
编译。没有错误了,OK,下载。
没反应!!!!准备要哭了,随便点了个开发板上reset按键,哦,哦,哦,流水灯居然正常工作了。
看看上面代码 ,
好像chisel里面代码生成里面有 if(res_n)判断,猜是判断按键吧?那么我把按键直接去掉试试?
好了,在逻辑判断里面,设置为复位之后有效即可,原先是需要手动按键才能触发:
实验效果:
总结
学习Chisel语言是一段既充满挑战又极具启发性的旅程。Chisel以Scala为基础,它的抽象级别高,极大提升了硬件设计效率,让代码更简洁且易于维护。通过Chisel,我体验了用近似软件工程的思维做硬件设计的便捷,特别是在模块化、参数化设计上的优势,这为复用代码和快速迭代创造了条件。Chisel结合Scala的强大生态,使得测试和验证更加高效,同时降低了硬件设计的学习曲线,尤其适合教学和研究用途。亲手实践,如在IDEA中配置环境并实现流水灯项目,让我深刻理解了理论到实践的每一步,过程中遇到问题的解决也锻炼了自我探索能力。总之,Chisel正引领硬件设计的新风潮,它不仅丰富了我的技术栈,也激发了对硬件设计未来无限可能的想象。
参考
WIN10系统下,用Chisel开发入门FPGA的HelloWorld呼吸灯
【多图预警】Windows 安装 SBT、IDEA 使用 SBT 构建项目指南
Scala安装出现neither build.sbt nor a…问题解决
Chisel入门之路(一)之在windows下vscode搭建|部署Scala2.13.3开发环境|安装教程
Chisel速成——跟着这个Chisel教程来就行了(已完结)
【IC设计】Windows下基于IDEA的Chisel环境安装教程(图文并茂)