2.3 Control Flow ‘:=’ Last Connect Semantics It is possible to issue multiple connect statements to the same component. When this happens, the last statement wins.
1 2 3 4 5 6 7 8 9 10 class LastConnect extends Module { val io = IO (new Bundle { val in = Input (UInt (4. W )) val out = Output (UInt (4. W )) }) io.out := 1. U io.out := 2. U io.out := 3. U io.out := 4. U }
Chisel Conditional Logic
Actions taken in the bodies of the the three can be complex blocks and may contain nested when
and allies.
when (chiselBool Type), if (scalaBoolean Type)
1 2 3 4 5 6 7 when(chiselBoolType) { }.elsewhen(someOtherBooleanCondition) { }.otherwise { }
Unlike Scala if
, values are not returned by the blocks associated with when
.
1 2 val result = when(squareIt) { x * x }.otherwise { x }
We will discuss the solution to this in the Wires section.
Wire Wire
defines a circuit component that can appear on the right hand side or left hand side of a connect :=
operator.
1 val wire = Wire (Uint (12. W ))
example
Use Wire
so that the $x^2$ computation appears only once in the module and so that there is a single connection to the output.
$x^2 - 2x + 1$
$2x^2 + 6x + 3$
$4x^2 - 10x -5$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Polynomial extends Module { val io = IO (new Bundle { val select = Input (UInt (2. W )) val x = Input (SInt (32. W )) val fOfX = Output (SInt (32. W )) }) val result = Wire (SInt (32. W )) val square = Wire (SInt (32. W )) square := io.x * io.x when(io.select === 0. U ){ result := square - 2. S * io.x + 1. S }.elsewhen(io.select === 1. U ){ result := 2. S * square + 6. S * io.x + 3. S }.otherwise{ result := 4. S * square - 10. S * io.x - 5. S } io.fOfX := result }
Precedence: coffee > idea > pressure
Test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def states = Map ("idle" -> 0 , "coding" -> 1 , "writing" -> 2 , "grad" -> 3 )def gradLife (state: Int , coffee: Boolean , idea: Boolean , pressure: Boolean ): Int = { var nextState = states("idle" ) if (state == states("idle" )) { if (coffee) { nextState = states("coding" ) } else if (idea) { nextState = states("idle" ) } else if (pressure) { nextState = states("writing" ) } } else if (state == states("coding" )) { if (coffee) { nextState = states("coding" ) } else if (idea || pressure) { nextState = states("writing" ) } } else if (state == states("writing" )) { if (coffee || idea) { nextState = states("writing" ) } else if (pressure) { nextState = states("grad" ) } } nextState }
Module
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class GradLife extends Module { val io = IO (new Bundle { val state = Input (UInt (2. W )) val coffee = Input (Bool ()) val idea = Input (Bool ()) val pressure = Input (Bool ()) val nextState = Output (UInt (2. W )) }) val idle :: coding :: writing :: grad :: Nil = Enum (4 ) when (io.state === idle) { when (io.coffee) { io.nextState := coding } .elsewhen (io.idea) { io.nextState := idle} .elsewhen (io.pressure) { io.nextState := writing} .otherwise { io.nextState := idle} }.elsewhen (io.state === coding) { when (io.coffee) { io.nextState := coding } .elsewhen (io.idea || io.pressure) { io.nextState := writing} .otherwise { io.nextState := idle} }.elsewhen (io.state === writing) { when (io.coffee || io.idea) { io.nextState := writing } .elsewhen (io.pressure) { io.nextState := grad} .otherwise { io.nextState := idle} }.otherwise { io.nextState := idle} }