Merge pull request #382 from ekiwi/chisel

add chisel blink example
This commit is contained in:
Sean Cross 2020-11-20 14:51:59 +08:00 committed by GitHub
commit e66e87e864
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 170 additions and 0 deletions

17
chisel/blink/.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
# Verilog/SystemVerilog generated from src/Blink.scala
/Blink.sv
/Blink.v
# Annotations for the firrtl compiler, also generated from src/Blink.scala
/Blink.anno.json
# Intermediate representation of the circuit generated from src/Blink.scala
/Blink.fir
# IntelliJ IDE folder
/.idea/
# Scala build artifacts
target/
# same as for the verilog example
blink.json
blink.asc
blink.bit
blink.dfu

63
chisel/blink/Makefile Normal file
View File

@ -0,0 +1,63 @@
# Simple Fomu Makefile
# --------------------
# This Makefile shows the steps to generate a DFU loadable image onto
# Fomu hacker board.
include ../../board.mk
# Default target: run all required targets to build the DFU image.
all: blink.dfu
@true
.DEFAULT: all
# Call sbt to generate the Blink.sv from Chisel.
# Please note that in general, it is a lot faster to
# start `sbt` once and then to run `run` on the `sbt`
# command line every time you want to rebuild the verilog.
# Unfortunately `sbt` start up times are notoriously bad :(
Blink.sv: src/Blink.scala build.sbt
sbt "run $(FOMU_REV)"
# Use *Yosys* to generate the synthesized netlist.
# This is called the **synthesis** and **tech mapping** step.
blink.json: Blink.sv
yosys \
$(YOSYSFLAGS) \
-p 'synth_ice40 -top Blink -json blink.json' Blink.sv
# Use **nextpnr** to generate the FPGA configuration.
# This is called the **place** and **route** step.
blink.asc: blink.json
nextpnr-ice40 \
$(PNRFLAGS) \
--json blink.json \
--asc blink.asc
# Use icepack to convert the FPGA configuration into a "bitstream" loadable onto the FPGA.
# This is called the bitstream generation step.
blink.bit: blink.asc
icepack blink.asc blink.bit
# Use dfu-suffix to generate the DFU image from the FPGA bitstream.
blink.dfu: blink.bit
cp blink.bit blink.dfu
dfu-suffix -v 1209 -p 70b1 -a blink.dfu
# Use df-util to load the DFU image onto the Fomu.
load: blink.dfu
dfu-util -D blink.dfu
.PHONY: load
# Cleanup the generated files.
clean:
-rm -f Blink.fir
-rm -f Blink.anno.json
-rm -f Blink.sv
-rm -f blink.json # Generate netlist
-rm -f blink.asc # FPGA configuration
-rm -f blink.bit # FPGA bitstream
-rm -f blink.dfu # DFU image loadable onto the Fomu
.PHONY: clean

6
chisel/blink/build.sbt Normal file
View File

@ -0,0 +1,6 @@
name := "fomu-blink"
version := "0.1"
scalaVersion := "2.12.8"
libraryDependencies += "edu.berkeley.cs" %% "chisel3" % "3.4.0"
scalaSource in Compile := baseDirectory.value / "src"
scalaSource in Test := baseDirectory.value / "test"

View File

@ -0,0 +1 @@
sbt.version=1.3.13

View File

@ -0,0 +1,83 @@
import chisel3._
import chisel3.experimental._
import chisel3.stage.ChiselStage
import firrtl.annotations.PresetAnnotation
class Blink(rev: String) extends RawModule {
val clki = IO(Input(Clock()))
val rgb0 = IO(Output(Bool()))
val rgb1 = IO(Output(Bool()))
val rgb2 = IO(Output(Bool()))
val usb_dp = IO(Output(Bool()))
val usb_dn = IO(Output(Bool()))
val usb_dp_pu = IO(Output(Bool()))
usb_dp := false.B
usb_dn := false.B
usb_dp_pu := false.B
// initialize registers to their reset value when the bitstream is programmed since there is no reset wire
val reset = IO(Input(AsyncReset()))
annotate(new ChiselAnnotation {
override def toFirrtl = PresetAnnotation(reset.toTarget)
})
// clock buffer
val clk_gb = Module(new SB_GB)
clk_gb.USER_SIGNAL_TO_GLOBAL_BUFFER := clki
val clk = clk_gb.GLOBAL_BUFFER_OUTPUT
// led driver
val leds = Module(new SB_RGBA_DRV)
leds.CURREN := true.B
leds.RGBLEDEN := true.B
rgb0 := leds.RGB0
rgb1 := leds.RGB1
rgb2 := leds.RGB2
// Now that we have set up the clock and reset, we define a scope
// in which all registers and modules will automatically use it.
chisel3.withClockAndReset(clk, reset) {
val (red, green, blue) = rev.toLowerCase match {
case "hacker" => (leds.RGB2PWM, leds.RGB1PWM, leds.RGB0PWM)
case "pvt" => (leds.RGB1PWM, leds.RGB0PWM, leds.RGB2PWM)
case other => throw new RuntimeException(s"Unsupported device: $other")
}
val counter = RegInit(0.U(26.W))
counter := counter + 1.U
red := counter(24)
green := counter(23)
blue := counter(25)
}
}
class SB_GB extends ExtModule {
val USER_SIGNAL_TO_GLOBAL_BUFFER = IO(Input(Clock()))
val GLOBAL_BUFFER_OUTPUT = IO(Output(Clock()))
}
class SB_RGBA_DRV extends ExtModule(Map(
"CURRENT_MODE" -> "0b0",
"RGB0_CURRENT" -> "0b000011",
"RGB1_CURRENT" -> "0b000011",
"RGB2_CURRENT" -> "0b000011",
)) {
val CURREN = IO(Input(Bool()))
val RGBLEDEN = IO(Input(Bool()))
val RGB0PWM = IO(Input(Bool()))
val RGB1PWM = IO(Input(Bool()))
val RGB2PWM = IO(Input(Bool()))
val RGB0 = IO(Output(Bool()))
val RGB1 = IO(Output(Bool()))
val RGB2 = IO(Output(Bool()))
}
// This main function reads in the version (pvt or hacker) and generates SystemVerilog from our Chisel design.
object VerilogGenerator extends App {
val rev = args.headOption.getOrElse("pvt")
(new ChiselStage).emitSystemVerilog(new Blink(rev))
}