Creating register is very different than VHDL/Verilog.
In Spinal, you don’t have process/always blocks. Registers are explicitly defined at the declaration.
This difference against traditional event driven HDL has a big impact :

  • You can assign registers and wires in the same scope, you don’t have to split your code between process/always blocks
  • It make things much more flexible (see Functions)

The way how clock and reset wire are managed are explained in the Clock domain chapter.


There is 4 ways to Instantiate a register :

Syntax Description
Reg(type : Data) Register of the given type
RegInit(resetValue : Data) Register loaded with the given resetValue when a reset occur
RegNext(nextValue : Data) Register that sample the given nextValue each cycle
RegNextWhen(nextValue : Data, cond : Bool) Register that sample the given nextValue when a condition occurs

There is some usage examples :

//UInt register of 4 bits    
val reg1 = Reg(UInt(4 bit))  

//Register that sample toto each cycle  
val reg2 = RegNext(reg1 + 1)    

//UInt register of 4 bits initialized with 0 when the reset occur
val reg3 = RegInit(U"0000")
reg3 := reg2
when(reg2 === 5){
  reg3 := 0xF

//Register toto when cond is True
val reg4 = RegNextWhen(reg3,cond)

The code above will infer the following logic :

Also, RegNext is an abstraction which is build over the Reg syntax. The two followings sequances of code are strictly equivalents :

//Standard way
val something = Bool
val value = Reg(Bool)
value := something

//Short way
val something = Bool
val value = RegNext(something)

Reset value

In addition of the RegInit(value : Data) syntax which directly create the register with a reset logic, you can also set the reset value by calling the init(value : Data) function on the register.

//UInt register of 4 bits initialized with 0 when the reset occur
val reg1 = Reg(UInt(4 bit)) init(0)

If you have a Bundle register, you can use the init function on each elements of that Bundle.

case class ValidRGB() extends Bundle{
  val valid = Bool
  val r,g,b = UInt(8 bits)

val reg = Reg(ValidRGB())
reg.valid init(False)  //Only the valid of that register bundle will have an reset value.

Initialization value for simulation purposes

For register that doesn’t need a reset value in RTL, but need an initialization value for simulation (avoid x-propagation), you can ask for an initialization random value by calling the randBoot() function.

// UInt register of 4 bits initialized with a random value
val reg1 = Reg(UInt(4 bit)) randBoot()