注:以下所有配置在Ubuntu22.04笔记本中运行
复制项目模板文件
git clone https://github.com/schoeberl/chisel-examples.git
安装vscode插件Metals
打开顶层目录,并设置为项目文件夹
打开终端输入
tree -L 3 # 查看三层目录结构
得到如下目录结构(helloworld文件夹示例下的结构)
$ tree -L 3
.
├── build.sbt
├── Makefile
├── quartus
│ ├── altde0
│ │ ├── hello.qpf
│ │ └── hello.qsf
│ ├── altde1
│ │ ├── hello.qpf
│ │ └── hello.qsf
│ ├── altde2-115
│ │ ├── hello.qpf
│ │ └── hello.qsf
│ ├── bemicro
│ │ ├── hello.cdf
│ │ ├── hello.qpf
│ │ ├── hello.qsf
│ │ └── hello.sdc
│ ├── bemicro_cv_a9
│ │ ├── hello.cdf
│ │ ├── hello.qpf
│ │ ├── hello.qsf
│ │ └── hello.sdc
│ └── de10-nano
│ ├── hello.cdf
│ ├── hello.qpf
│ └── hello.qsf
├── README.md
├── src
│ ├── main
│ │ └── scala
│ └── test
│ └── scala
├── verilog
│ └── hello_top.v
└── vivado
├── arty-a7-100
│ ├── Arty-A7-100-Master.xdc
│ ├── project.tcl
│ └── README.md
└── basys3
├── Basys-3-Master.xdc
├── project.tcl
└── README.md
16 directories, 27 files
在./src/main目录下定义模块文件
在./src/test目录下编写test测试文件
在./verilog目录下生成相应的Verilog代码
在./src/main目录下定义自动售货机的chisel样例
import chisel3._
import chisel3.util._
class FSM extends Module{
val io = IO(new Bundle{
val coin_one = Input(Bool()) // 由于均为1bit数据,这里使用的数据类型为布尔类型,等效为 val coin_one = Input(Uint(1.W))
val coin_half = Input(Bool())
val coin_back = Output(Bool())
val water = Output(Bool())
})
val s_idle :: s05 :: s10 :: s15 :: s_ok :: Nil = Enum(5) // 建立状态机列表
val current_state = RegInit(s_idle) // 定义初态(初始化)
// 使用switch函数完成状态机的构建
switch(current_state) {
is(s_idle) {
when(io.coin_half) {current_state := s05}
when(io.coin_one) {current_state := s10}
}
is(s05) {
when(io.coin_half) {current_state := s10}
when(io.coin_one) {current_state := s15}
}
is(s10) {
when(io.coin_half) {current_state := s15}
when(io.coin_one) {current_state := s_ok}
}
is(s15) {
when(io.coin_half) {current_state := s_ok}
when(io.coin_one) {
current_state := s_ok
}
}
is(s_ok) {
current_state := s_idle
}
}
io.water := (current_state === s_ok)
io.coin_back := (current_state === s15 & io.coin_one === true.B)
}
/* An object extending App to generate the Verilog code*/
object FSM extends App { // 生成相应的Verilog代码
// 这里设置生成Verilog的目录位置
(new chisel3.stage.ChiselStage).emitVerilog(new FSM(), Array("--target-dir", "./verilog/FSM"))
}
在主目录下输入
make # 此处等效于sbt run
选择顶层项目
$ make
sbt run
[info] welcome to sbt 1.9.7 (Private Build Java 17.0.9)
[info] loading settings for project hello-world-build-build from metals.sbt ...
[info] loading project definition from /home/wzm/Graduation Design/task/HyGCN Accelerator/chisel_try_nouse/chisel-examples/hello-world/project/project
[info] loading settings for project hello-world-build from metals.sbt ...
[info] loading project definition from /home/wzm/Graduation Design/task/HyGCN Accelerator/chisel_try_nouse/chisel-examples/hello-world/project
[success] Generated .bloop/hello-world-build.json
[success] Total time: 1 s, completed 2024年1月15日 下午3:15:28
[info] loading settings for project hello-world from build.sbt ...
[info] set current project to hello-world (in build file:/home/wzm/Graduation%20Design/task/HyGCN%20Accelerator/chisel_try_nouse/chisel-examples/hello-world/)
Multiple main classes detected. Select one to run:
[1] FSM
[2] Hello
[3] mux
Enter number: 1 # 此处进行主项目的选择
[info] running FSM
[success] Total time: 34 s, completed 2024年1月15日 下午3:16:02
在./verilog目录下查看生成的代码
一共是三个文件
—FSM.V
—FSM.fir
—FSM.anno.json
这里只关心FSM.v
生成代码如下:
module FSM(
input clock,
input reset,
input io_coin_one,
input io_coin_half,
output io_coin_back,
output io_water
);
`ifdef RANDOMIZE_REG_INIT
reg [31:0] _RAND_0;
`endif // RANDOMIZE_REG_INIT
reg [2:0] current_state; // @[FSM.scala 12:28]
wire [2:0] _GEN_2 = io_coin_half ? 3'h2 : current_state; // @[FSM.scala 12:28 19:{28,43}]
wire [2:0] _GEN_4 = io_coin_half ? 3'h3 : current_state; // @[FSM.scala 12:28 23:{28,43}]
wire [2:0] _GEN_5 = io_coin_one ? 3'h4 : _GEN_4; // @[FSM.scala 24:{28,43}]
wire [2:0] _GEN_6 = io_coin_half ? 3'h4 : current_state; // @[FSM.scala 12:28 27:{28,43}]
wire [2:0] _GEN_7 = io_coin_one ? 3'h4 : _GEN_6; // @[FSM.scala 28:28 29:29]
wire [2:0] _GEN_8 = 3'h4 == current_state ? 3'h0 : current_state; // @[FSM.scala 13:23 33:23 12:28]
wire [2:0] _GEN_9 = 3'h3 == current_state ? _GEN_7 : _GEN_8; // @[FSM.scala 13:23]
assign io_coin_back = current_state == 3'h3 & io_coin_one; // @[FSM.scala 37:40]
assign io_water = current_state == 3'h4; // @[FSM.scala 36:28]
always @(posedge clock) begin
if (reset) begin // @[FSM.scala 12:28]
current_state <= 3'h0; // @[FSM.scala 12:28]
end else if (3'h0 == current_state) begin // @[FSM.scala 13:23]
if (io_coin_one) begin // @[FSM.scala 16:28]
current_state <= 3'h2; // @[FSM.scala 16:43]
end else if (io_coin_half) begin // @[FSM.scala 15:28]
current_state <= 3'h1; // @[FSM.scala 15:43]
end
end else if (3'h1 == current_state) begin // @[FSM.scala 13:23]
if (io_coin_one) begin // @[FSM.scala 20:28]
current_state <= 3'h3; // @[FSM.scala 20:43]
end else begin
current_state <= _GEN_2;
end
end else if (3'h2 == current_state) begin // @[FSM.scala 13:23]
current_state <= _GEN_5;
end else begin
current_state <= _GEN_9;
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}};
current_state = _RAND_0[2:0];
`endif // RANDOMIZE_REG_INIT
`endif // RANDOMIZE
end // initial
`ifdef FIRRTL_AFTER_INITIAL
`FIRRTL_AFTER_INITIAL
`endif
`endif // SYNTHESIS
endmodule