Chisel入门
1.用Chisel点亮FPGA小灯
1.1 克隆项目
github:https://github.com/schoeberl/chisel-examples
1.2 编译运行
cmd命令如下
git clone https://github.com/schoeberl/chisel-examples.git
cd chisel-examples/hello-world/
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())
}
1.3 生成Verilog文件
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 19:23]
reg blkReg; // @[Hello.scala 20:23]
wire [31:0] _cntReg_T_1 = cntReg + 32'h1; // @[Hello.scala 22:20]
assign io_led = blkReg; // @[Hello.scala 27:10]
always @(posedge clock) begin
if (reset) begin // @[Hello.scala 19:23]
cntReg <= 32'h0; // @[Hello.scala 19:23]
end else if (cntReg == 32'h17d783f) begin // @[Hello.scala 23:28]
cntReg <= 32'h0; // @[Hello.scala 24:12]
end else begin
cntReg <= _cntReg_T_1; // @[Hello.scala 22:10]
end
if (reset) begin // @[Hello.scala 20:23]
blkReg <= 1'h0; // @[Hello.scala 20:23]
end else if (cntReg == 32'h17d783f) begin // @[Hello.scala 23:28]
blkReg <= ~blkReg; // @[Hello.scala 25: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
/* 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
1.4 上板验证
1.4.1 创建quartus项目
板子型号为 EP4CE115F29C7
1.4.2 加入.v文件
1.4.3 绑定引脚
1.4.4 实现效果
暂未
2.在DE2-115开发板上重做Verilog实验
2.1 流水灯
2.1.1 修改scala文件
修改 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())
}
2.1.2 重新编译
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 10:24]
reg [2:0] position; // @[Hello.scala 11:25]
wire [31:0] _counter_T_1 = counter + 32'h1; // @[Hello.scala 14:22]
wire [2:0] _position_T_1 = position + 3'h1; // @[Hello.scala 20:28]
assign io_led = 8'h1 << position; // @[Hello.scala 25:18]
always @(posedge clock) begin
if (reset) begin // @[Hello.scala 10:24]
counter <= 32'h0; // @[Hello.scala 10:24]
end else if (counter == 32'h4c4b40) begin // @[Hello.scala 15:30]
counter <= 32'h0; // @[Hello.scala 16:13]
end else begin
counter <= _counter_T_1; // @[Hello.scala 14:11]
end
if (reset) begin // @[Hello.scala 11:25]
position <= 3'h0; // @[Hello.scala 11:25]
end else if (counter == 32'h4c4b40) begin // @[Hello.scala 15:30]
if (position == 3'h7) begin // @[Hello.scala 17:28]
position <= 3'h0; // @[Hello.scala 18:16]
end else begin
position <= _position_T_1; // @[Hello.scala 20: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
2.1.3 引脚分配
2.1.4 编译下载
2.1.5 实现效果
暂未
参考链接
1.https://blog.youkuaiyun.com/weixin_68811361/article/details/139279336
2.Chisel-book: https://wwu.lanzoue.com/isdim08x8x5i