Skip to content
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

Pattern generator #92

Merged
merged 16 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions src/main/scala/e2e/UCITop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ class UCITop(
val TLready_to_rcv = Input(Bool())
val fault = Input(Bool())
val soft_reset = Input(Bool())
// IOs for connecting to the AFE
val mbAfe_tx = Output(new MainbandIo(afeParams.mbLanes))
val mbAfe_rx = Input(new MainbandIo(afeParams.mbLanes))
// IOs for connecting to the AFE in the standalone mode
val mbAfe_tx = if (afeParams.STANDALONE) Some(Output(new MainbandIo(afeParams.mbLanes))) else None
val mbAfe_rx = if (afeParams.STANDALONE) Some(Input(new MainbandIo(afeParams.mbLanes))) else None
val phyAfe = if (afeParams.STANDALONE) None else Some(Flipped(new MainbandLaneIO(afeParams)))
val sbTxIO = Output(new SidebandIo)
val sbRxIO = Input(new SidebandIo)
})
Expand Down Expand Up @@ -83,12 +84,26 @@ class UCITop(

/** Mainband AFE connections to toplevel IOs
*/
io.mbAfe_tx <> dafe.io.mbTxData
io.mbAfe_rx <> dafe.io.mbRxData
if (afeParams.STANDALONE) { io.mbAfe_tx.get <> dafe.io.mbTxData }
if (afeParams.STANDALONE) {
io.mbAfe_rx.get <> dafe.io.mbRxData
} else {
dafe.io.mbRxData := 0.U.asTypeOf(dafe.io.mbRxData)
}

/** Logphy connections to Digital AFE
*/
logPhy.io.mbAfe <> dafe.io.mbAfeIo
if (afeParams.STANDALONE) {
logPhy.io.mbAfe.get <> dafe.io.mbAfeIo
} else {
logPhy.io.phyAfe.get <> io.phyAfe.get
// defaults to zero
dafe.io.mbAfeIo.txData.valid := 0.U
dafe.io.mbAfeIo.txData.bits := 0.U.asTypeOf(dafe.io.mbAfeIo.txData.bits)
dafe.io.mbAfeIo.rxData.ready := 0.U
dafe.io.mbAfeIo.txFreqSel := 0.U.asTypeOf(dafe.io.mbAfeIo.txFreqSel)
dafe.io.mbAfeIo.rxEn := 0.U
}

/* Connect the protocol IOs to the top for connections to the tilelink
* interface */
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/interfaces/Afe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ case class AfeParams(
sbWidth: Int = 1,
mbSerializerRatio: Int = 16,
mbLanes: Int = 16,
STANDALONE: Boolean = true
)

/** The sideband analog front-end (AFE) interface, from the perspective of the
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/logphy/DataWidthCoupler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class DataWidthCoupler(params: DataWidthCouplerParams) extends Module {
is(State.CHUNK_OR_COLLECT) {
io.out.bits := inData
.asTypeOf(Vec(ratio, Bits(params.outWidth.W)))(
(ratio - 1).U - chunkCounter,
chunkCounter,
)
io.out.valid := true.B
when(io.out.fire) {
Expand Down Expand Up @@ -86,7 +86,7 @@ class DataWidthCoupler(params: DataWidthCouplerParams) extends Module {
is(State.IDLE) {
io.in.ready := true.B
when(io.in.fire) {
inData((ratio - 1).U - inSliceCounter) := io.in.bits
inData(inSliceCounter) := io.in.bits
inSliceCounter := inSliceCounter + 1.U
}
when(inSliceCounter === (ratio - 1).U) {
Expand Down
81 changes: 81 additions & 0 deletions src/main/scala/logphy/ErrorCounter.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package edu.berkeley.cs.ucie.digital
package logphy

import chisel3._
import chisel3.util._
import interfaces.AfeParams

/** TODO: need to do per-lane, not just aggregate */
class ErrorCounter(afeParams: AfeParams) extends Module {

val io = IO(new Bundle {
val req = Flipped(Valid(new Bundle {
val pattern = TransmitPattern()
val input = Input(
Vec(afeParams.mbLanes, UInt(afeParams.mbSerializerRatio.W)),
)
}))
val errorCount = Output(
Vec(afeParams.mbLanes, UInt(log2Ceil(afeParams.mbSerializerRatio + 1).W)),
)
})

val lfsr = Module(
new UCIeScrambler(afeParams = afeParams, numLanes = afeParams.mbLanes),
)

lfsr.io.valid := io.req.valid && io.req.bits.pattern === TransmitPattern.LFSR
lfsr.io.data_in := VecInit(
Seq.fill(afeParams.mbLanes)(0.U(afeParams.mbSerializerRatio.W)),
)

val expected = WireInit(
VecInit(
Seq.fill(afeParams.mbLanes)(0.U(afeParams.mbSerializerRatio.W)),
),
)

/** Assign expected value */
switch(io.req.bits.pattern) {
is(TransmitPattern.CLOCK) {
assert(!io.req.valid, "Cannot do error count with sideband clock pattern")
}
is(TransmitPattern.LFSR) {
expected := lfsr.io.data_out
}
is(TransmitPattern.PER_LANE_ID) {
val perLaneId = VecInit(Seq.fill(afeParams.mbLanes)(0.U(16.W)))
for (i <- 0 until afeParams.mbLanes) {
perLaneId(i) := Cat("b1010".U(4.W), i.U(8.W), "b1010".U(4.W))
}
val ratio16 = afeParams.mbSerializerRatio / 16
val patternVec = VecInit.tabulate(afeParams.mbLanes, ratio16) { (_, _) =>
0.U(16.W)
}
for (i <- 0 until afeParams.mbLanes) {
for (j <- 0 until ratio16) {
patternVec(i)(j) := perLaneId(i)
}
}
expected := patternVec.asTypeOf(expected)
}
is(TransmitPattern.VALTRAIN) {
val valtrain = VecInit(
Seq.fill(afeParams.mbLanes * afeParams.mbSerializerRatio / 8)(
"b1111_0000".U(8.W),
),
)
expected := valtrain.asTypeOf(expected)
}
}

/** count errors */
val diffVec = Wire(
Vec(afeParams.mbLanes, Vec(afeParams.mbSerializerRatio, UInt(1.W))),
)
for (i <- 0 until afeParams.mbLanes) {
diffVec(i) := (expected(i) ^ io.req.bits.input(i)).asTypeOf(diffVec(i))
io.errorCount(i) := diffVec(i).reduceTree(_ +& _)
}

}
Loading
Loading