CHIPMUNK is a Scala package to extend the functionality of CHISEL. It features:
- Extra convenient methods for CHISEL's built-in types,
- Several syntactic sugar to sweeten your CHISEL experience,
- A set of commonly used components and interfaces.
WARNING: The code contained in this repo are provided AS IS, and I cannot make any guarantees for availability and correctness. Most of them have only been silicon-verified in academic research (and some even not). You should carefully review every line of code before using it in production.
Please open an issue if you have any questions.
CHIPMUNK is an extension of Chisel, so it needs to be used together with CHISEL.
Mill is required to build and publish CHIPMUNK.
mill chipmunk.publishLocal
Then add CHIPMUNK to your build file.
// Mill
def ivyDeps = Agg(..., ivy"com.zhutmost::chipmunk:0.1-SNAPSHOT")
// SBT
libraryDependencies ++= Seq(..., "com.zhutmost" %% "chipmunk" % "0.1-SNAPSHOT")
Import it as well as chisel3
in your Scala RTL code.
import chisel3._
import chisel3.util._
import chipmunk._
CHIPMUNK documents are provided on my blog.
Code example:
val myUInt = Wire(UInt(3.W)).dontTouch // equivalent to `DontTouch(...)`, but more convenient
when(...) {
myUInt.setAllTo(someBits.lsBit) // set all bits to true or false
} otherwise {
myUInt.clearAll()
}
val emptyStream = Decoupled(new EmptyBundle) // Bundle without elements
Code example:
class AxiIO extends Bundle with IsMasterSlave {
val aw = Master(new AxiWriteAddrChannelIO)
val ar = Master(new AxiReadAddrChannelIO)
val r = Slave(new AxiReadDataChannelIO)
val w = Master(new AxiWriteDataChannelIO)
val b = Slave(new AxiWriteRespChannelIO)
def isMaster = true // indicate this bundle is a Master
}
class AxiSlave extends Module {
val io = IO(new Bundle {
val axi = Slave(new AxiIO) // automatically flip the signal directions
})
// ...
}
Code example:
withClockAndReset(clock, reset) {
val regNeg1 = RegNegNext(nextVal)
val regNeg2 = RegNegEnable(nextVal, initVal, enable)
}
Code example:
val fsm = new StateMachine {
val s1 = new State with EntryPoint
val s2 = new State
s1
.whenIsActive {
when(io.a) {
goto(s2)
}
}
s2
.whenIsActive {
when(io.b) {
goto(s1)
}
}
}
io.out := fsm.isExiting(fsm.s2)
Code example:
val reset1 = AsyncResetSyncDessert.withImplicitClockDomain()
val reset2 = AsyncResetSyncDessert.withSpecificClockDomain(clockSys, coreReset, resetChainIn = reset1)
Code example:
import org.scalatest.Assertions
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class TestRunnerSpec extends AnyFlatSpec with Assertions with Matchers with VerilatorTestRunner {
val compiled = TestRunnerConfig(withWaveform = true).compile(new Module {
val io = IO(new Bundle {
val a = Input(SInt(3.W))
val b = Output(SInt(3.W))
val c = Output(UInt(3.W))
})
io.b := io.a
io.c := io.a.asUInt
})
"TestRunner" should "compile DUT and run simulation" in {
compiled.runSim { dut =>
import TestRunnerUtils._
dut.clock.step()
dut.io.a #= -1.S(3.W)
dut.clock.step()
dut.io.b expect -1
dut.io.c expect 7
}
}
}
Code example:
TODO
Code example:
TODO
(Not all above document pages are ready yet.)
I am sorry they are written in Chinese (Machine translation driven by AI is good enough now :D).
CHIPMUNK is standing on the shoulder of giants. Thanks for CHISEL, SpinalHDL and many other open-sourced projects.