Chisel入门——在windows下vscode搭建|部署Scala2.13.3开发环境|用Chisel点亮FPGA小灯等实验

文章目录

  • 前言
  • 一、vscode搭建scala开发环境
    • [1.1 安装Scala官方插件](#1.1 安装Scala官方插件)
    • [1.2 创建hello_world.scala文件](#1.2 创建hello_world.scala文件)
    • [1.3 确认java的版本(博主使用的是1.8)](#1.3 确认java的版本(博主使用的是1.8))
    • [1.4 下载Scala Windows版本的二进制文件](#1.4 下载Scala Windows版本的二进制文件)
    • [1.5 配置环境变量](#1.5 配置环境变量)
    • [1.6 交互模式测试一下](#1.6 交互模式测试一下)
    • [1.7 vscode运行scala](#1.7 vscode运行scala)
  • 二、windows安装sbt
    • [2.1 下载sbt](#2.1 下载sbt)
    • [2.2 设置环境变量](#2.2 设置环境变量)
    • [2.3 sbt配置](#2.3 sbt配置)
    • [2.4 设置阿里云镜像](#2.4 设置阿里云镜像)
    • [2.5 验证](#2.5 验证)
  • 三、用Chisel点亮FPGA小灯
    • [3.1 参考文档](#3.1 参考文档)
    • [3.2 得到Verilog文件](#3.2 得到Verilog文件)
      • [1. 环境搭建](#1. 环境搭建)
      • [2. 克隆项目](#2. 克隆项目)
      • [3. 编译运行](#3. 编译运行)
      • [4. 生成Verilog文件](#4. 生成Verilog文件)
    • [3.3 上板验证](#3.3 上板验证)
      • [1. 创建quartus项目](#1. 创建quartus项目)
      • [2. 加入.v文件](#2. 加入.v文件)
      • [3. 绑定引脚](#3. 绑定引脚)
      • [4. 上板烧录](#4. 上板烧录)
  • 四、在DE2-115开发板上重做Verilog实验
    • [4.1 流水灯](#4.1 流水灯)
  • 总结
  • 参考

前言

由于verilog效率比较低下,重复劳动太多了QAQ

所以打算用近两年比较火的chisel进行开发。

于是先装一波环境,踩了一天的坑。

传统数字芯片的RTL设计采用Verilog语言为主,Chisel语言的全称是Constructing Harward in Scala Embeded Language,即在Scala语言中导入Chisel3库,即可使用Chisel语言。其特点是面向对象编程,可以方便地参数化定制硬件电路,加快设计流程。目前在RISC-V生态中应用较多,中科院计算所主持的培育下一代处理器设计人才的"一生一芯"项目也在极力推进该语言。


一、vscode搭建scala开发环境

1.1 安装Scala官方插件

在VS Code 中安装插件,先安装 Scala Syntax (official) ,再安装 Scala (Metals):

(官方插件,有个语法高亮功能也挺香的)

1.2 创建hello_world.scala文件

代码如下:

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解压目录,例如:

c 复制代码
SBT_HOME=C:\Programs\sbt;

添加到 系统变量 中:

添加到 path 中:

2.3 sbt配置

修改 sbt\conf\sbtconfig.txt 为以下内容:

bash 复制代码
# 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 文件,内容为:

bash 复制代码
[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命令下,

c 复制代码
git clone https://github.com/schoeberl/chisel-examples.git
cd chisel-examples/hello-world/

执行编译 sbt run

第一次编译需要等待很长时间,然后显示成功。(因为我编译过了,所以第二次很快)。

Hello.scala

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 文件:

scala 复制代码
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

scala 复制代码
/* 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 文件为:

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 文件,直接将该文件设置为顶层文件:

scala 复制代码
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环境安装教程(图文并茂)

相关推荐
Piink3 分钟前
Mac使用Vscode教程
ide·vscode·macos
jingcairensheng4 分钟前
vscode 配置Python虚拟环境基于扩展和原生miniconda的区别
ide·vscode·python
像枫一样16 分钟前
STM32串口轮询收发实战教程
arm开发·c++·stm32·单片机·嵌入式硬件·fpga开发·51单片机
传感器与混合集成电路36 分钟前
DLM8676计数控制集成电路DC-DC一体化与RS422隔离接口设计
fpga开发
AlfredZhao2 小时前
低配虚拟机安装 Win10 LTSB 2016 跳转机实录
windows
嵌入式软硬件攻城狮15 小时前
9.读写DDR测试
fpga开发
长成一棵参天树18 小时前
React15 vs React16 核心区别
git·vscode
爱吃火鸡面呀18 小时前
Spark RDD 行动算子(Action)详解
windows·ajax·spark
dlhto19 小时前
Windows 使用 Rufus 制作 AlmaLinux 10.2 启动 U 盘:从 ISO 下载到服务器安装
运维·服务器·windows
小矮强19 小时前
输入凭证也没用?Windows 共享文件夹“来宾访问被安全策略阻止”
windows·经验分享