Skip to content

Commit 17a5e2a

Browse files
committed
difftest: pipeline FPGA batch bus + beat-serialize AXIS to ease congestion
- Cut the wide Gateway->Host path with a register slice to reduce long routes. - Replace 16008-bit per-beat shift with beat-indexed serialization to shrink active cones. - Intended to ease routing congestion and improve PCIe-clock timing.
1 parent 2e0188d commit 17a5e2a

File tree

2 files changed

+28
-28
lines changed

2 files changed

+28
-28
lines changed

src/main/scala/Gateway.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,11 @@ class GatewayEndpoint(instanceWithDelay: Seq[(DifftestBundle, Int)], config: Gat
288288
control.enable := batch.enable
289289
GatewaySink.batch(Batch.getTemplate, control, batch.io, config)
290290
if (config.isFPGA) {
291-
fpgaIO.get.data := batch.io.asUInt
292-
fpgaIO.get.enable := batch.enable
291+
val fpgaData = RegEnable(batch.io.data, 0.U((config.batchArgByteLen._1 * 8).W), batch.enable)
292+
val fpgaInfo = RegEnable(batch.io.info, 0.U((config.batchArgByteLen._2 * 8).W), batch.enable)
293+
val fpgaEnable = RegNext(batch.enable, false.B)
294+
fpgaIO.get.data := Cat(fpgaData, fpgaInfo)
295+
fpgaIO.get.enable := fpgaEnable
293296
}
294297
} else {
295298
val sink_enable = VecInit(toSink.map(_.valid).toSeq).asUInt.orR

src/main/scala/fpga/Host.scala

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class Difftest2AXIs(val difftest_width: Int, val axis_width: Int) extends Module
3333
val numPacketPerRange = 8 // packet in each range
3434
val pkt_id_w = 8 // pkt = (difftest_data, pkt_id)
3535
val axis_send_len = (difftest_width + pkt_id_w + axis_width - 1) / axis_width
36+
val payload_width = axis_send_len * axis_width
37+
val payload_pad_width = payload_width - difftest_width - pkt_id_w
3638
val fifo_depth = 16
3739
val fifo_addr_width = log2Ceil(fifo_depth)
3840

@@ -49,19 +51,12 @@ class Difftest2AXIs(val difftest_width: Int, val axis_width: Int) extends Module
4951
val wr_occupancy = wr_cnt - rd_cnt_sync // Calculate occupancy in write clock domain
5052

5153
// Write side (difftest side)
52-
val pktID = RegInit(0.U(pkt_id_w.W))
53-
val wrRangeCounter = RegInit(0.U(3.W)) // 0 to 7
5454
val fifo_not_full = wr_occupancy < (fifo_depth - 1).U
5555
val wr_en = io.difftest.enable && fifo_not_full
5656

5757
when(wr_en) {
5858
fifo_ram.write(wr_ptr, io.difftest.data)
5959
wr_ptr := wr_ptr + 1.U
60-
wrRangeCounter := Mux(wrRangeCounter === (numPacketPerRange - 1).U, 0.U, wrRangeCounter + 1.U)
61-
// Increment packet ID when starting a new range
62-
when(wrRangeCounter === (numPacketPerRange - 1).U) {
63-
pktID := pktID + 1.U
64-
}
6560
wr_cnt := wr_cnt + 1.U // Increment write counter
6661
}
6762

@@ -75,27 +70,35 @@ class Difftest2AXIs(val difftest_width: Int, val axis_width: Int) extends Module
7570
val rd_occupancy = wr_cnt_sync - rd_cnt // Calculate occupancy in read clock domain
7671

7772
val inTransfer = RegInit(false.B)
78-
val mix_data = RegInit(0.U((difftest_width + pkt_id_w).W))
73+
val packetBeats = RegInit(VecInit(Seq.fill(axis_send_len)(0.U(axis_width.W))))
7974
val sendCnt = RegInit(0.U(log2Ceil(axis_send_len).W))
8075
val sendLast = sendCnt === (axis_send_len - 1).U
8176
val counter = RegInit(0.U(3.W)) // 0 to 7
8277
val currentPktID = RegInit(0.U(pkt_id_w.W))
8378
val sendPacketEnd = counter === (numPacketPerRange - 1).U
8479
// Read from FIFO
8580
val fifo_out = fifo_ram.read(rd_ptr)
81+
val packetPayload =
82+
if (payload_pad_width > 0) {
83+
Cat(0.U(payload_pad_width.W), fifo_out, currentPktID)
84+
} else {
85+
Cat(fifo_out, currentPktID)
86+
}
87+
val packetPayloadBeats = packetPayload.asTypeOf(Vec(axis_send_len, UInt(axis_width.W)))
88+
val startTransfer = !inTransfer && rd_occupancy >= numPacketPerRange.U
89+
val loadNextPacket = startTransfer || (io.axis.fire && sendLast && !sendPacketEnd)
8690

87-
// Counter for throttling debug prints
8891
// Start transfer when we have data available
89-
when(!inTransfer) {
90-
when(rd_occupancy >= numPacketPerRange.U) {
91-
mix_data := Cat(fifo_out, currentPktID) // First data in range
92-
rd_ptr := rd_ptr + 1.U
93-
rd_cnt := rd_cnt + 1.U // Increment read counter
94-
// counter := 0.U // 0~7
95-
inTransfer := true.B
96-
sendCnt := 0.U
97-
}
98-
}.otherwise {
92+
when(loadNextPacket) {
93+
packetBeats := packetPayloadBeats
94+
rd_ptr := rd_ptr + 1.U
95+
rd_cnt := rd_cnt + 1.U // Increment read counter
96+
}
97+
98+
when(startTransfer) {
99+
inTransfer := true.B
100+
sendCnt := 0.U
101+
}.elsewhen(inTransfer) {
99102
when(io.axis.fire) {
100103
when(sendLast) {
101104
sendCnt := 0.U
@@ -105,23 +108,17 @@ class Difftest2AXIs(val difftest_width: Int, val axis_width: Int) extends Module
105108
counter := 0.U
106109
currentPktID := currentPktID + 1.U // Increment ID for next range
107110
}.otherwise {
108-
// Read next data in range
109-
mix_data := Cat(fifo_out, currentPktID)
110-
rd_ptr := rd_ptr + 1.U
111-
rd_cnt := rd_cnt + 1.U // Increment read counter
112111
counter := counter + 1.U
113112
}
114113
}.otherwise {
115-
// Still sending beats of current data
116114
sendCnt := sendCnt + 1.U
117-
mix_data := mix_data >> axis_width
118115
}
119116
}
120117
}
121118

122119
// AXI output
123120
io.axis.valid := inTransfer
124-
io.axis.bits.data := mix_data(axis_width - 1, 0)
121+
io.axis.bits.data := packetBeats(sendCnt)
125122
io.axis.bits.last := inTransfer && sendLast && sendPacketEnd
126123
}
127124
}

0 commit comments

Comments
 (0)