Skip to content

Commit 4161912

Browse files
Merge pull request #92 from ucb-ucie/pattern-generator
Pattern generator
2 parents 8883194 + 88cf816 commit 4161912

35 files changed

+3244
-548
lines changed

src/main/scala/e2e/UCITop.scala

+21-6
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ class UCITop(
4242
val TLready_to_rcv = Input(Bool())
4343
val fault = Input(Bool())
4444
val soft_reset = Input(Bool())
45-
// IOs for connecting to the AFE
46-
val mbAfe_tx = Output(new MainbandIo(afeParams.mbLanes))
47-
val mbAfe_rx = Input(new MainbandIo(afeParams.mbLanes))
45+
// IOs for connecting to the AFE in the standalone mode
46+
val mbAfe_tx = if (afeParams.STANDALONE) Some(Output(new MainbandIo(afeParams.mbLanes))) else None
47+
val mbAfe_rx = if (afeParams.STANDALONE) Some(Input(new MainbandIo(afeParams.mbLanes))) else None
48+
val phyAfe = if (afeParams.STANDALONE) None else Some(Flipped(new MainbandLaneIO(afeParams)))
4849
val sbTxIO = Output(new SidebandIo)
4950
val sbRxIO = Input(new SidebandIo)
5051
})
@@ -83,12 +84,26 @@ class UCITop(
8384

8485
/** Mainband AFE connections to toplevel IOs
8586
*/
86-
io.mbAfe_tx <> dafe.io.mbTxData
87-
io.mbAfe_rx <> dafe.io.mbRxData
87+
if (afeParams.STANDALONE) { io.mbAfe_tx.get <> dafe.io.mbTxData }
88+
if (afeParams.STANDALONE) {
89+
io.mbAfe_rx.get <> dafe.io.mbRxData
90+
} else {
91+
dafe.io.mbRxData := 0.U.asTypeOf(dafe.io.mbRxData)
92+
}
8893

8994
/** Logphy connections to Digital AFE
9095
*/
91-
logPhy.io.mbAfe <> dafe.io.mbAfeIo
96+
if (afeParams.STANDALONE) {
97+
logPhy.io.mbAfe.get <> dafe.io.mbAfeIo
98+
} else {
99+
logPhy.io.phyAfe.get <> io.phyAfe.get
100+
// defaults to zero
101+
dafe.io.mbAfeIo.txData.valid := 0.U
102+
dafe.io.mbAfeIo.txData.bits := 0.U.asTypeOf(dafe.io.mbAfeIo.txData.bits)
103+
dafe.io.mbAfeIo.rxData.ready := 0.U
104+
dafe.io.mbAfeIo.txFreqSel := 0.U.asTypeOf(dafe.io.mbAfeIo.txFreqSel)
105+
dafe.io.mbAfeIo.rxEn := 0.U
106+
}
92107

93108
/* Connect the protocol IOs to the top for connections to the tilelink
94109
* interface */

src/main/scala/interfaces/Afe.scala

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ case class AfeParams(
4949
sbWidth: Int = 1,
5050
mbSerializerRatio: Int = 16,
5151
mbLanes: Int = 16,
52+
STANDALONE: Boolean = true
5253
)
5354

5455
/** The sideband analog front-end (AFE) interface, from the perspective of the

src/main/scala/logphy/DataWidthCoupler.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class DataWidthCoupler(params: DataWidthCouplerParams) extends Module {
5151
is(State.CHUNK_OR_COLLECT) {
5252
io.out.bits := inData
5353
.asTypeOf(Vec(ratio, Bits(params.outWidth.W)))(
54-
(ratio - 1).U - chunkCounter,
54+
chunkCounter,
5555
)
5656
io.out.valid := true.B
5757
when(io.out.fire) {
@@ -86,7 +86,7 @@ class DataWidthCoupler(params: DataWidthCouplerParams) extends Module {
8686
is(State.IDLE) {
8787
io.in.ready := true.B
8888
when(io.in.fire) {
89-
inData((ratio - 1).U - inSliceCounter) := io.in.bits
89+
inData(inSliceCounter) := io.in.bits
9090
inSliceCounter := inSliceCounter + 1.U
9191
}
9292
when(inSliceCounter === (ratio - 1).U) {
+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package edu.berkeley.cs.ucie.digital
2+
package logphy
3+
4+
import chisel3._
5+
import chisel3.util._
6+
import interfaces.AfeParams
7+
8+
/** TODO: need to do per-lane, not just aggregate */
9+
class ErrorCounter(afeParams: AfeParams) extends Module {
10+
11+
val io = IO(new Bundle {
12+
val req = Flipped(Valid(new Bundle {
13+
val pattern = TransmitPattern()
14+
val input = Input(
15+
Vec(afeParams.mbLanes, UInt(afeParams.mbSerializerRatio.W)),
16+
)
17+
}))
18+
val errorCount = Output(
19+
Vec(afeParams.mbLanes, UInt(log2Ceil(afeParams.mbSerializerRatio + 1).W)),
20+
)
21+
})
22+
23+
val lfsr = Module(
24+
new UCIeScrambler(afeParams = afeParams, numLanes = afeParams.mbLanes),
25+
)
26+
27+
lfsr.io.valid := io.req.valid && io.req.bits.pattern === TransmitPattern.LFSR
28+
lfsr.io.data_in := VecInit(
29+
Seq.fill(afeParams.mbLanes)(0.U(afeParams.mbSerializerRatio.W)),
30+
)
31+
32+
val expected = WireInit(
33+
VecInit(
34+
Seq.fill(afeParams.mbLanes)(0.U(afeParams.mbSerializerRatio.W)),
35+
),
36+
)
37+
38+
/** Assign expected value */
39+
switch(io.req.bits.pattern) {
40+
is(TransmitPattern.CLOCK) {
41+
assert(!io.req.valid, "Cannot do error count with sideband clock pattern")
42+
}
43+
is(TransmitPattern.LFSR) {
44+
expected := lfsr.io.data_out
45+
}
46+
is(TransmitPattern.PER_LANE_ID) {
47+
val perLaneId = VecInit(Seq.fill(afeParams.mbLanes)(0.U(16.W)))
48+
for (i <- 0 until afeParams.mbLanes) {
49+
perLaneId(i) := Cat("b1010".U(4.W), i.U(8.W), "b1010".U(4.W))
50+
}
51+
val ratio16 = afeParams.mbSerializerRatio / 16
52+
val patternVec = VecInit.tabulate(afeParams.mbLanes, ratio16) { (_, _) =>
53+
0.U(16.W)
54+
}
55+
for (i <- 0 until afeParams.mbLanes) {
56+
for (j <- 0 until ratio16) {
57+
patternVec(i)(j) := perLaneId(i)
58+
}
59+
}
60+
expected := patternVec.asTypeOf(expected)
61+
}
62+
is(TransmitPattern.VALTRAIN) {
63+
val valtrain = VecInit(
64+
Seq.fill(afeParams.mbLanes * afeParams.mbSerializerRatio / 8)(
65+
"b1111_0000".U(8.W),
66+
),
67+
)
68+
expected := valtrain.asTypeOf(expected)
69+
}
70+
}
71+
72+
/** count errors */
73+
val diffVec = Wire(
74+
Vec(afeParams.mbLanes, Vec(afeParams.mbSerializerRatio, UInt(1.W))),
75+
)
76+
for (i <- 0 until afeParams.mbLanes) {
77+
diffVec(i) := (expected(i) ^ io.req.bits.input(i)).asTypeOf(diffVec(i))
78+
io.errorCount(i) := diffVec(i).reduceTree(_ +& _)
79+
}
80+
81+
}

0 commit comments

Comments
 (0)