-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
D2D Dummy Loopback Module #49
base: main
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ project/**/metals.sbt | |
|
||
### Chiseltest ### | ||
test_run_dir/ | ||
vlog/ | ||
|
||
### IDEs ### | ||
.vscode/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,9 @@ If you are running `sbt` commands frequently, you may find it useful | |
to leave the sbt shell (launched by running `sbt` with no arguments) open. | ||
You can then compile/test the code from the sbt shell. | ||
|
||
`sbt` can not [compile the Scala compiler bridge under JDK21](https://github.com/sbt/sbt/issues/7235) (without bumping the Scala minor version - for which the chisel compiler plugin is unavailable). | ||
To work around this, install an older JDK and pass its path to sbt (e.g. `sbt --java-home /usr/lib/jvm/java-17-openjdk/`). | ||
|
||
## Documentation | ||
|
||
See the [API documentation](https://ucb-ucie.github.io/uciedigital/edu/berkeley/cs/ucie/digital/index.html). | ||
|
@@ -29,7 +32,7 @@ If you'd like to contribute, please let us know. You can: | |
|
||
- Open an issue. | ||
- Email [email protected] and [email protected]. | ||
|
||
Documentation updates, tests, and bugfixes are always welcome. | ||
For larger feature additions, please discuss your ideas with us before implementing them. | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,94 @@ | ||||||||
package edu.berkeley.cs.ucie.digital | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should go in the main build, in the |
||||||||
|
||||||||
import chisel3._ | ||||||||
import chisel3.util._ | ||||||||
import chisel3.experimental.FlatIO | ||||||||
import interfaces._ | ||||||||
|
||||||||
import chisel3.stage.ChiselStage | ||||||||
|
||||||||
// LatencyPipe from rocket-chip | ||||||||
// https://github.com/chipsalliance/rocket-chip/blob/master/src/main/scala/util/LatencyPipe.scala | ||||||||
Comment on lines
+10
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We may want to vendor utils from rocket-chip in a dedicated package / directory (there are definitely more things we want to steal, e.g. |
||||||||
class LatencyPipe[T <: Data](typ: T, latency: Int) extends Module { | ||||||||
val io = IO(new Bundle { | ||||||||
val in = Flipped(Decoupled(typ)) | ||||||||
val out = Decoupled(typ) | ||||||||
}) | ||||||||
|
||||||||
def doN[S](n: Int, func: S => S, in: S): S = | ||||||||
(0 until n).foldLeft(in)((last, _) => func(last)) | ||||||||
|
||||||||
io.out <> doN(latency, (last: DecoupledIO[T]) => Queue(last, 1, true), io.in) | ||||||||
} | ||||||||
|
||||||||
object LatencyPipe { | ||||||||
def apply[T <: Data](in: DecoupledIO[T], latency: Int): DecoupledIO[T] = { | ||||||||
val pipe = Module(new LatencyPipe(chiselTypeOf(in.bits), latency)) | ||||||||
pipe.io.in <> in | ||||||||
pipe.io.out | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
class D2DDummyLoopback(latency: Int = 8) extends Module { | ||||||||
// 64 bit wide data bus, 8 bit wide side channel bus | ||||||||
val fdiParams = FdiParams(width = 8, dllpWidth = 8, sbWidth = 8) | ||||||||
|
||||||||
val io = FlatIO(Flipped(new Fdi(fdiParams))) // implicit module clock = lclk | ||||||||
|
||||||||
when(io.lpData.valid) { | ||||||||
/* For now, the protocol layer must assert lpData.valid and lpData.irdy | ||||||||
* together */ | ||||||||
chisel3.assert( | ||||||||
io.lpData.irdy, | ||||||||
"lpData.valid was asserted without lpData.irdy", | ||||||||
) | ||||||||
} | ||||||||
|
||||||||
// Restructure lpData as Decoupled[UInt] | ||||||||
val lpDataDecoupled = Wire(DecoupledIO(chiselTypeOf(io.lpData.bits))) | ||||||||
lpDataDecoupled.bits := io.lpData.bits | ||||||||
lpDataDecoupled.valid := io.lpData.valid | ||||||||
io.lpData.ready := lpDataDecoupled.ready | ||||||||
|
||||||||
// Loopback lpData to plData with some fixed latency | ||||||||
val pipe = Module(new LatencyPipe(chiselTypeOf(io.lpData.bits), latency)) | ||||||||
pipe.io.in <> lpDataDecoupled | ||||||||
pipe.io.out.ready := true.B // immediately fetch the data after <latency> cycles | ||||||||
io.plData.valid := pipe.io.out.valid | ||||||||
io.plData.bits := pipe.io.out.bits | ||||||||
|
||||||||
// Tieoffs | ||||||||
io.plProtocol := Protocol.streaming | ||||||||
io.plProtocolFlitFormat := FlitFormat.raw | ||||||||
io.plProtocolValid := true.B // TODO: need to model this signal changing from false to true upon training completion | ||||||||
io.plInbandPres := false.B // TODO: this depends on the FSM state | ||||||||
io.plCerror := false.B | ||||||||
io.plFlitCancel := false.B | ||||||||
io.plRxActiveReq := false.B // TODO: this signal indicates when the protocol layer can receive bits | ||||||||
io.plClkReq := true.B // we don't support dynamic clock gating | ||||||||
io.plRetimerCrd := false.B // this is an optional signal anyways | ||||||||
io.plStream.protoStack := ProtoStack.stack0 | ||||||||
io.plStream.protoType := ProtoStreamType.Stream | ||||||||
io.plNfError := false.B // TODO: we want to be able to inject errors from the adapter to protocol layer | ||||||||
io.plDllp.valid := false.B // we don't use the DLLP interface due to no PCIe support | ||||||||
io.plDllp.bits := 0.U | ||||||||
io.plDllpOfc := false.B | ||||||||
io.plPhyInL1 := false.B // TODO: need to use these if the D2D adapter handles multiple power states | ||||||||
io.plPhyInL2 := false.B | ||||||||
io.plConfigCredit := false.B // TODO: need to handle sideband packets | ||||||||
io.plConfig.valid := false.B | ||||||||
io.plConfig.bits := 0.U | ||||||||
io.plStallReq := false.B // TODO: need to model D2D adapter requesting protocol layer to flush flits | ||||||||
io.plWakeAck := RegNext(io.lpWakeReq) | ||||||||
io.plLinkWidth := PhyWidth.width64 // TODO: this is a PHY-level parameter | ||||||||
io.plSpeedMode := SpeedMode.speed4 // TODO: this is a runtime PHY knob | ||||||||
io.plPhyInRecenter := false.B // TODO: this is part of the FDI state machine | ||||||||
io.plTrainError := false.B // TODO: need to model fatal errors of the PHY | ||||||||
io.plError := false.B // TODO: need to model framing errors | ||||||||
io.plStateStatus := PhyState.active // TODO: this is part of the FDI state machine | ||||||||
} | ||||||||
|
||||||||
object D2DDummyLoopbackMain extends App { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To suppress the SFC deprecation warning:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, we will just disable the warning. CirctStage is only a thing in Chisel 5+ and Chipyard will be stuck on Chisel 3.6 for a while. This is also not maintained anymore, so there's no point in using it (https://github.com/sifive/chisel-circt). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||
new ChiselStage() | ||||||||
.emitVerilog(new D2DDummyLoopback(), args = Array("--target-dir", "vlog")) | ||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package edu.berkeley.cs.ucie.digital | ||
|
||
import chiseltest._ | ||
import org.scalatest.freespec.AnyFreeSpec | ||
|
||
class D2DTest extends AnyFreeSpec with ChiselScalatestTester { | ||
"D2D Dummy Loopback module should elaborate" in { | ||
test(new D2DDummyLoopback()) { c => | ||
c.clock.step() | ||
} | ||
} | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should keep the IOs in the bundle even if we are never using them, and drive them with constants / add assertions instead; this way our IO is always spec-compliant.