Skip to content

Commit

Permalink
Merge pull request jijingg#17 from pwang7/dev
Browse files Browse the repository at this point in the history
handshake more examples
  • Loading branch information
jijingg authored May 30, 2021
2 parents 97013d4 + 6140824 commit fdc6948
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 27 deletions.
101 changes: 76 additions & 25 deletions exercises/Examples/src/main/scala/exercises/HandShakePipe.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// https://www.itdev.co.uk/blog/pipelining-axi-buses-registered-ready-signals

package exercises

import spinal.core._
import spinal.core.sim._
import spinal.lib._
import spinal.sim._
import spinal.lib.sim.SimData

class HandShakePipe(width: Int) extends Component {
val io = new Bundle {
Expand Down Expand Up @@ -57,34 +58,18 @@ class S2MHandShakePipe(
val validReg = Reg(Bool) init (False)

if (noBubble) {
// io.output.payload := validReg ? doutReg | io.input.payload
io.output.valid := io.input.valid || validReg
io.output.payload := validReg ? doutReg | io.input.payload

when(io.output.ready && !readyReg) {
io.output.payload := validReg ? doutReg | io.input.payload
io.output.valid := validReg || io.input.valid
io.input.ready := !validReg
doutReg := 0
validReg := False
}.elsewhen(io.output.ready && readyReg) {
io.output.payload := io.input.payload
io.output.valid := io.input.valid
io.input.ready := readyReg // True
doutReg := 0
io.input.ready := ~validReg

when(io.output.ready) {
validReg := False
}.elsewhen(!io.output.ready && readyReg) { // Cache input data if valid
io.output.payload := io.input.payload
io.output.valid := io.input.valid
io.input.ready := readyReg // True
}

when(io.input.ready && ~io.output.ready) {
doutReg := io.input.payload
validReg := io.input.valid
}.otherwise { // !io.output.ready && !readyReg
io.output.payload := validReg ? doutReg | io.input.payload
io.output.valid := io.input.valid || validReg
io.input.ready := !validReg
when(io.input.valid && io.input.ready) { // Cache input data if valid
doutReg := io.input.payload
validReg := True
}
}
} else {
io.input.ready := readyReg
Expand All @@ -103,3 +88,69 @@ class S2MHandShakePipe(
}
}
}

class BothHandShakePipe(
width: Int
) extends HandShakePipe(width) {
val primDataReg = Reg(UInt(width bits)) init (0)
val primVldReg = Reg(Bool) init (False)

val sideDataReg = Reg(UInt(width bits)) init (0)
val sideVldReg = Reg(Bool) init (False)

io.input.ready := ~sideVldReg
io.output.valid := primVldReg || sideVldReg
io.output.payload := sideVldReg ? sideDataReg | primDataReg

when(io.output.ready) {
sideVldReg := False
}

when(io.input.ready) {
primDataReg := io.input.payload
primVldReg := io.input.valid

when(~io.output.ready) {
sideDataReg := primDataReg
sideVldReg := primVldReg
}
}
}

class BothHandShakePipe2(
width: Int
) extends HandShakePipe(width) {
val firstDataReg = Reg(UInt(width bits)) init (0)
val firstVldReg = Reg(Bool) init (False)

val interStream = Stream(UInt(width bits))

val secondDataReg = Reg(UInt(width bits)) init (0)
val secondVldReg = Reg(Bool) init (False)

val s2mArea = new Area {
io.input.ready := ~firstVldReg
interStream.valid := io.input.valid || firstVldReg
interStream.payload := firstVldReg ? firstDataReg | io.input.payload

when(interStream.ready) {
firstVldReg := False
}

when(io.input.ready && ~interStream.ready) {
firstDataReg := io.input.payload
firstVldReg := io.input.valid
}
}

val m2sArea = new Area {
io.output.valid := secondVldReg
io.output.payload := secondDataReg
interStream.ready := io.output.ready || ~secondVldReg

when(interStream.ready) {
secondDataReg := interStream.payload
secondVldReg := interStream.valid
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ class HandShakePipeTest extends AnyFunSuite {
io.sout << io.sin.s2mPipe()
}

class BothPipeStream(width: Int) extends PipeStream(width) {
io.sout << io.sin.m2sPipe().s2mPipe()
}

class BothPipeStream2(width: Int) extends PipeStream(width) {
io.sout << io.sin.s2mPipe().m2sPipe()
}

abstract class PipeTB(width: Int) extends Component {
val pipe: HandShakePipe
val stream: PipeStream
Expand All @@ -93,6 +101,22 @@ class HandShakePipeTest extends AnyFunSuite {
pipe.doutReg.simPublic()
}

class BothPipeTB(width: Int) extends PipeTB(width) {
override val pipe = new BothHandShakePipe(width)
override val stream = new BothPipeStream(width)

pipe.io.simPublic()
stream.io.simPublic()
}

class BothPipe2TB(width: Int) extends PipeTB(width) {
override val pipe = new BothHandShakePipe2(width)
override val stream = new BothPipeStream2(width)

pipe.io.simPublic()
stream.io.simPublic()
}

def simTest(dut: PipeTB) {
SimTimeout(1000)
dut.clockDomain.forkStimulus(2)
Expand Down Expand Up @@ -184,6 +208,21 @@ class HandShakePipeTest extends AnyFunSuite {
SimConfig
.withWave
.compile(new S2MPipeTB(width))
.doSim(simTest(_))//(seed = 896944298)
.doSim(simTest(_))
}

test("valid pipeline + ready pipeline") {
SimConfig
.withWave
.compile(new BothPipeTB(width))
.doSim(simTest(_))
}
}

test("ready pipeline + valid pipeline") {
SimConfig
.withWave
.compile(new BothPipe2TB(width))
.doSim(simTest(_))
}
}

0 comments on commit fdc6948

Please sign in to comment.