You may know "output reg" in Verilog, very helpful feature.
But in Chisel I can't find how to do similar things. When I need register output I should do this:
package filter
import chisel3._
class TestReg extends Module {
val io = IO( new Bundle {
val din = Input(SInt(32.W))
val ena = Input(Bool())
val dout = Output(SInt())
})
val dout = RegInit(0.S(32.W))
when (io.ena) {
dout := io.din + 77.S
}
io.dout <> dout
}
Is there a more "short" way to create output reg?
What I'm looking for is to define Reg in IO bundle and write into it as into register
Something like this:
class TestReg extends Module {
val io = IO( new Bundle {
val din = Input(SInt(32.W))
val ena = Input(Bool())
val dout = Output(RegInit(0.S(32.W)))
})
when (io.ena) {
io.dout := io.din + 77.S
}
}
Registers are disallowed in Bundle
to preserve their purity as interfaces. They're closer to SystemVerilog structs than Verilog 95/2001 port declarations.
With the existing libraries, the easiest way to do what you want is to use RegNext
:
io.dout := RegNext(io.din + 77.S, 0.S(32.W))
Note: that this will not set the width of io.dout
until the FIRRTL compiler infers the width. This can sometimes cause problems if you ever try to get the width of io.dout
for something.
Ignoring the standard library, you can also do this more manually by defining your own utility for creating registered connections in one of two possible ways:
object ConnectionUtilities {
def regConnect(lhs: Data, rhs: Data): Unit = {
val rhsReg = Reg(chiselTypeOf(rhs))
rhsReg := rhs
lhs := rhsReg
}
}
With this, you can then use this method for doing connections and generate the necessary register:
import ConnectionUtilities.regConnect
regConnect(io.out, io.in + 77.S)
Data
. This is more advanced and has the potential to confuse people reading your code. However, it lets you extend the Chisel domain specific language with your own domain specific language.object ConnectUtilities2 {
implicit class DataWithRegConnect(lhs: Data) {
def `:=r` (rhs: Data): Unit = {
val rhsReg = Reg(chiselTypeOf(rhs))
rhsReg := rhs
lhs := rhsReg
}
}
}
You can then use this new method (noting that this requires the backticks because :=r
isn't a legal name by itself).
import ConnectUtilities2.DataWithRegConnect
io.dout `:=r` (io.din + 77.S)