Handle is a Finite-State-Machine (FSMs) generator based on Chisel.
As a RTL, Chisel describes FSMs in a verbose way. Handle is developed to help create FSMs with tight, deterministic timing in C-like primitives in Chisel, which can greatly simply the contoller parts in hardware.
Add all elements in matrix with only one adder.
class DoubleForAdder extends Module with Handle {
val io = IO(new Bundle {
val in = Input(Vec(4, Vec(4, UInt(8.W))))
val start = Input(Bool())
val done = Output(Bool())
val out = Output(UInt(8.W))
})
// DataPath
val r = RegInit(0.U(8.W))
val adder = Wire(UInt(8.W))
r := r + adder
adder := 0.U
// Control
Control()(
For(0 until 4)((i) =>
For(0 until 4)((j) => {
adder := io.in(i)(j)
})
)
)(
io.start,
reset,
io.done
)
io.out := r
makeHandle()
}
See more examples in the tests.
Control()(...)
The root of the control statements.Step(...)
Things that will happed in a single cycle.Block(...)
Statements will be executed in consecutive cycles.Fork(...)
Statments will be executed together, and will be joined to wait for the latest one.If(...){}.Else{}
Make a branch on the FSM.For(range){var => ...}
Iterate var in the range.Read(io){value => ...}
Read from a DecoupedIO, get the value once the handshake is done.Write(io){value => ...}
Write to a DecoupedIO, push the value once the handshake is done.Transfer(in, out){ (in_wire, out_wire) => }
Call the closure when input and output have both handshaked.WaitFor(value)
Wait for the value become 1. Required to be attached to step to avoid combinational loop.
We have stopped the development and maintainance on Handle.
We treat Chisel statements as black-boxes as Handle is embeded in Chisel, which prevents getting enough information to do more complex things.
As result, we are now developing a new embeded HDL in Rust as replacement, which allows more innovation in lower-levels.
Please check [https://github.com/pku-liang/Cement] for more infomation.