增加chisel框架
This commit is contained in:
parent
68a30caea2
commit
37c144d66d
|
@ -0,0 +1,22 @@
|
|||
*.*
|
||||
*
|
||||
!*/
|
||||
!Makefile
|
||||
!*.mk
|
||||
!*.scala
|
||||
!*.[cSh]
|
||||
!*.v
|
||||
!*.cpp
|
||||
!*.cc
|
||||
!.gitignore
|
||||
!.scalafmt.conf
|
||||
!build.sc
|
||||
!README.md
|
||||
build/
|
||||
|
||||
# mill
|
||||
out/
|
||||
.bsp/
|
||||
.idea/
|
||||
.idea_modules/
|
||||
test_run_dir/
|
|
@ -0,0 +1,33 @@
|
|||
version = 2.6.4
|
||||
|
||||
maxColumn = 120
|
||||
align = most
|
||||
continuationIndent.defnSite = 2
|
||||
assumeStandardLibraryStripMargin = true
|
||||
docstrings = ScalaDoc
|
||||
lineEndings = preserve
|
||||
includeCurlyBraceInSelectChains = false
|
||||
danglingParentheses = true
|
||||
|
||||
align.tokens.add = [
|
||||
{
|
||||
code = ":"
|
||||
},
|
||||
{
|
||||
code = ":="
|
||||
},
|
||||
{
|
||||
code = "="
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
newlines.alwaysBeforeCurlyBraceLambdaParams = false
|
||||
newlines.alwaysBeforeMultilineDef = false
|
||||
newlines.implicitParamListModifierForce = [before]
|
||||
|
||||
verticalMultiline.atDefnSite = true
|
||||
|
||||
optIn.annotationNewlines = true
|
||||
|
||||
rewrite.rules = [SortImports, PreferCurlyFors, AvoidInfix]
|
|
@ -0,0 +1,37 @@
|
|||
BUILD_DIR = ./build
|
||||
|
||||
export PATH := $(PATH):$(abspath ./utils)
|
||||
|
||||
test:
|
||||
mill -i __.test
|
||||
|
||||
verilog:
|
||||
$(call git_commit, "generate verilog")
|
||||
mkdir -p $(BUILD_DIR)
|
||||
mill -i __.test.runMain Elaborate -td $(BUILD_DIR)
|
||||
|
||||
help:
|
||||
mill -i __.test.runMain Elaborate --help
|
||||
|
||||
compile:
|
||||
mill -i __.compile
|
||||
|
||||
bsp:
|
||||
mill -i mill.bsp.BSP/install
|
||||
|
||||
reformat:
|
||||
mill -i __.reformat
|
||||
|
||||
checkformat:
|
||||
mill -i __.checkFormat
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILD_DIR)
|
||||
|
||||
.PHONY: test verilog help compile bsp reformat checkformat clean
|
||||
|
||||
sim:
|
||||
$(call git_commit, "sim RTL") # DO NOT REMOVE THIS LINE!!!
|
||||
@echo "Write this Makefile by yourself."
|
||||
|
||||
-include ../Makefile
|
|
@ -0,0 +1,37 @@
|
|||
Chisel Project Template
|
||||
=======================
|
||||
|
||||
Another version of the [Chisel template](https://github.com/ucb-bar/chisel-template) supporting mill.
|
||||
mill is another Scala/Java build tool without obscure DSL like SBT. It is much faster than SBT.
|
||||
|
||||
Contents at a glance:
|
||||
|
||||
* `.gitignore` - helps Git ignore junk like generated files, build products, and temporary files.
|
||||
* `build.sc` - instructs mill to build the Chisel project
|
||||
* `Makefile` - rules to call mill
|
||||
* `playground/src/GCD.scala` - GCD source file
|
||||
* `playground/src/DecoupledGCD.scala` - another GCD source file
|
||||
* `playground/src/Elaborate.scala` - wrapper file to call chisel command with the GCD module
|
||||
* `playground/test/src/GCDSpec.scala` - GCD tester
|
||||
|
||||
Feel free to rename or delete files under `playground/` or use them as a reference/template.
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, install mill by referring to the documentation [here](https://com-lihaoyi.github.io/mill).
|
||||
|
||||
To run all tests in this design (recommended for test-driven development):
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
To generate Verilog:
|
||||
```bash
|
||||
make verilog
|
||||
```
|
||||
|
||||
## Change FIRRTL Compiler
|
||||
|
||||
You can change the FIRRTL compiler between SFC (Scala-based FIRRTL compiler) and
|
||||
MFC (MLIR-based FIRRTL compiler) by modifying the `useMFC` variable in `playground/src/Elaborate.scala`.
|
||||
The latter one requires `firtool`, which is included under `utils/`.
|
|
@ -0,0 +1,37 @@
|
|||
// import Mill dependency
|
||||
import mill._
|
||||
import mill.scalalib._
|
||||
import mill.scalalib.scalafmt.ScalafmtModule
|
||||
import mill.scalalib.TestModule.ScalaTest
|
||||
// support BSP
|
||||
import mill.bsp._
|
||||
|
||||
object playground extends ScalaModule with ScalafmtModule { m =>
|
||||
val useChisel5 = true
|
||||
override def scalaVersion = "2.13.10"
|
||||
override def scalacOptions = Seq(
|
||||
"-language:reflectiveCalls",
|
||||
"-deprecation",
|
||||
"-feature",
|
||||
"-Xcheckinit"
|
||||
)
|
||||
override def ivyDeps = Agg(
|
||||
if (useChisel5) ivy"org.chipsalliance::chisel:5.0.0" else
|
||||
ivy"edu.berkeley.cs::chisel3:3.6.0",
|
||||
)
|
||||
override def scalacPluginIvyDeps = Agg(
|
||||
if (useChisel5) ivy"org.chipsalliance:::chisel-plugin:5.0.0" else
|
||||
ivy"edu.berkeley.cs:::chisel3-plugin:3.6.0",
|
||||
)
|
||||
object test extends ScalaTests with ScalaTest {
|
||||
override def ivyDeps = m.ivyDeps() ++ Agg(
|
||||
ivy"com.lihaoyi::utest:0.8.1",
|
||||
if (useChisel5) ivy"edu.berkeley.cs::chiseltest:5.0.0" else
|
||||
ivy"edu.berkeley.cs::chiseltest:0.6.0",
|
||||
)
|
||||
}
|
||||
def repositoriesTask = T.task { Seq(
|
||||
coursier.MavenRepository("https://maven.aliyun.com/repository/central"),
|
||||
coursier.MavenRepository("https://repo.scala-sbt.org/scalasbt/maven-releases"),
|
||||
) ++ super.repositoriesTask() }
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
import chisel3._
|
||||
import chisel3.util.Decoupled
|
||||
|
||||
class GcdInputBundle(val w: Int) extends Bundle {
|
||||
val value1 = UInt(w.W)
|
||||
val value2 = UInt(w.W)
|
||||
}
|
||||
|
||||
class GcdOutputBundle(val w: Int) extends Bundle {
|
||||
val value1 = UInt(w.W)
|
||||
val value2 = UInt(w.W)
|
||||
val gcd = UInt(w.W)
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute Gcd using subtraction method.
|
||||
* Subtracts the smaller from the larger until register y is zero.
|
||||
* value input register x is then the Gcd.
|
||||
* Unless first input is zero then the Gcd is y.
|
||||
* Can handle stalls on the producer or consumer side
|
||||
*/
|
||||
class DecoupledGcd(width: Int) extends Module {
|
||||
val input = IO(Flipped(Decoupled(new GcdInputBundle(width))))
|
||||
val output = IO(Decoupled(new GcdOutputBundle(width)))
|
||||
|
||||
val xInitial = Reg(UInt())
|
||||
val yInitial = Reg(UInt())
|
||||
val x = Reg(UInt())
|
||||
val y = Reg(UInt())
|
||||
val busy = RegInit(false.B)
|
||||
val resultValid = RegInit(false.B)
|
||||
|
||||
input.ready := !busy
|
||||
output.valid := resultValid
|
||||
output.bits := DontCare
|
||||
|
||||
when(busy) {
|
||||
when(x > y) {
|
||||
x := x - y
|
||||
}.otherwise {
|
||||
y := y - x
|
||||
}
|
||||
when(x === 0.U || y === 0.U) {
|
||||
when(x === 0.U) {
|
||||
output.bits.gcd := y
|
||||
}.otherwise {
|
||||
output.bits.gcd := x
|
||||
}
|
||||
|
||||
output.bits.value1 := xInitial
|
||||
output.bits.value2 := yInitial
|
||||
resultValid := true.B
|
||||
|
||||
when(output.ready && resultValid) {
|
||||
busy := false.B
|
||||
resultValid := false.B
|
||||
}
|
||||
}
|
||||
}.otherwise {
|
||||
when(input.valid) {
|
||||
val bundle = input.deq()
|
||||
x := bundle.value1
|
||||
y := bundle.value2
|
||||
xInitial := bundle.value1
|
||||
yInitial := bundle.value2
|
||||
busy := true.B
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import circt.stage._
|
||||
|
||||
object Elaborate extends App {
|
||||
def top = new GCD()
|
||||
val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
|
||||
(new ChiselStage).execute(args, generator :+ CIRCTTargetAnnotation(CIRCTTarget.Verilog))
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import chisel3._
|
||||
|
||||
/**
|
||||
* Compute GCD using subtraction method.
|
||||
* Subtracts the smaller from the larger until register y is zero.
|
||||
* value in register x is then the GCD
|
||||
*/
|
||||
class GCD extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val value1 = Input(UInt(16.W))
|
||||
val value2 = Input(UInt(16.W))
|
||||
val loadingValues = Input(Bool())
|
||||
val outputGCD = Output(UInt(16.W))
|
||||
val outputValid = Output(Bool())
|
||||
})
|
||||
|
||||
val x = Reg(UInt())
|
||||
val y = Reg(UInt())
|
||||
|
||||
when(x > y) { x := x - y }.otherwise { y := y - x }
|
||||
|
||||
when(io.loadingValues) {
|
||||
x := io.value1
|
||||
y := io.value2
|
||||
}
|
||||
|
||||
io.outputGCD := x
|
||||
io.outputValid := y === 0.U
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
import chisel3._
|
||||
import chiseltest._
|
||||
import chisel3.experimental.BundleLiterals._
|
||||
|
||||
import utest._
|
||||
|
||||
/**
|
||||
* This is a trivial example of how to run this Specification
|
||||
* From within sbt use:
|
||||
* {{{
|
||||
* testOnly gcd.GcdDecoupledTester
|
||||
* }}}
|
||||
* From a terminal shell use:
|
||||
* {{{
|
||||
* sbt 'testOnly gcd.GcdDecoupledTester'
|
||||
* }}}
|
||||
*/
|
||||
object GCDSpec extends ChiselUtestTester {
|
||||
val tests = Tests {
|
||||
test("GCD") {
|
||||
testCircuit(new DecoupledGcd(16)) {
|
||||
dut =>
|
||||
dut.input.initSource()
|
||||
dut.input.setSourceClock(dut.clock)
|
||||
dut.output.initSink()
|
||||
dut.output.setSinkClock(dut.clock)
|
||||
val testValues = for {x <- 0 to 10; y <- 0 to 10} yield (x, y)
|
||||
val inputSeq = testValues.map { case (x, y) => (new GcdInputBundle(16)).Lit(_.value1 -> x.U, _.value2 -> y.U) }
|
||||
val resultSeq = testValues.map { case (x, y) =>
|
||||
(new GcdOutputBundle(16)).Lit(_.value1 -> x.U, _.value2 -> y.U, _.gcd -> BigInt(x).gcd(BigInt(y)).U)
|
||||
}
|
||||
fork {
|
||||
// push inputs into the calculator, stall for 11 cycles one third of the way
|
||||
val (seq1, seq2) = inputSeq.splitAt(resultSeq.length / 3)
|
||||
dut.input.enqueueSeq(seq1)
|
||||
dut.clock.step(11)
|
||||
dut.input.enqueueSeq(seq2)
|
||||
}.fork {
|
||||
// retrieve computations from the calculator, stall for 10 cycles one half of the way
|
||||
val (seq1, seq2) = resultSeq.splitAt(resultSeq.length / 2)
|
||||
dut.output.expectDequeueSeq(seq1)
|
||||
dut.clock.step(10)
|
||||
dut.output.expectDequeueSeq(seq2)
|
||||
}.join()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue