Skip to content

Commit

Permalink
The helper function to connect CSR to xdmaStreamer easily (#296)
Browse files Browse the repository at this point in the history
* Initial Commit

* Bug Fix

* Bug Fix
  • Loading branch information
IveanEx committed Sep 1, 2024
1 parent ea22766 commit 1c4d263
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 85 deletions.
74 changes: 8 additions & 66 deletions hw/chisel/src/main/scala/snax/xdma/xdmaFrontend/DMACtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -219,79 +219,21 @@ class DMACtrl(
)
var remainingCSR = i_csrmanager.io.csr_config_out.bits.toIndexedSeq

// Pack the unstructured signal from csrManager to structured signal: Src side
// Connect agu_cfg.Ptr & readerPtr
preRoute_src_local.bits.aguCfg.ptr := Cat(remainingCSR(1), remainingCSR(0))
preRoute_src_local.bits.readerPtr := Cat(remainingCSR(1), remainingCSR(0))
preRoute_dst_local.bits.readerPtr := Cat(remainingCSR(1), remainingCSR(0))
remainingCSR = remainingCSR.tail.tail

// Connect aguCfg.spatialStrides
for (i <- 0 until preRoute_src_local.bits.aguCfg.spatialStrides.length) {
preRoute_src_local.bits.aguCfg.spatialStrides(i) := remainingCSR.head
remainingCSR = remainingCSR.tail
}

// Connect aguCfg.temporalStrides
for (i <- 0 until preRoute_src_local.bits.aguCfg.temporalStrides.length) {
preRoute_src_local.bits.aguCfg.temporalStrides(i) := remainingCSR.head
remainingCSR = remainingCSR.tail
}
// Connect reader + writer cfg to the structured signal: Src side
remainingCSR =
preRoute_src_local.bits.connectReaderWriterCfgWithList(remainingCSR)

// Connect aguCfg.temporalBounds
for (i <- 0 until preRoute_src_local.bits.aguCfg.temporalBounds.length) {
preRoute_src_local.bits.aguCfg.temporalBounds(i) := remainingCSR.head
remainingCSR = remainingCSR.tail
}
// Connect enabledChannel signal
preRoute_src_local.bits.readerwriterCfg.enabledChannel := remainingCSR.head
remainingCSR = remainingCSR.tail

// Connect enabledByte signal. As the enabledByte is not effective, so assign all true, and not take any value from CSR right now
preRoute_src_local.bits.readerwriterCfg.enabledByte := VecInit(
Seq.fill(readerparam.rwParam.tcdmParam.dataWidth / 8)(true.B)
).asUInt

// Connect extension signal
// Connect extension signal: Src side
for (i <- 0 until preRoute_src_local.bits.extCfg.length) {
preRoute_src_local.bits.extCfg(i) := remainingCSR.head
remainingCSR = remainingCSR.tail
}

// Pack the unstructured signal from csrManager to structured signal: Dst side
// Connect agu_cfg.Ptr & writerPtr
preRoute_dst_local.bits.aguCfg.ptr := Cat(remainingCSR(1), remainingCSR(0))
preRoute_src_local.bits.writerPtr := Cat(remainingCSR(1), remainingCSR(0))
preRoute_dst_local.bits.writerPtr := Cat(remainingCSR(1), remainingCSR(0))
remainingCSR = remainingCSR.tail.tail

// Connect aguCfg.spatialStrides
for (i <- 0 until preRoute_dst_local.bits.aguCfg.spatialStrides.length) {
preRoute_dst_local.bits.aguCfg.spatialStrides(i) := remainingCSR.head
remainingCSR = remainingCSR.tail
}

// Connect aguCfg.temporalStrides
for (i <- 0 until preRoute_dst_local.bits.aguCfg.temporalStrides.length) {
preRoute_dst_local.bits.aguCfg.temporalStrides(i) := remainingCSR.head
remainingCSR = remainingCSR.tail
}

// Connect aguCfg.temporalBounds
for (i <- 0 until preRoute_dst_local.bits.aguCfg.temporalBounds.length) {
preRoute_dst_local.bits.aguCfg.temporalBounds(i) := remainingCSR.head
remainingCSR = remainingCSR.tail
}

// Connect enabledChannel signal
preRoute_dst_local.bits.readerwriterCfg.enabledChannel := remainingCSR.head
remainingCSR = remainingCSR.tail

// Connect enabledByte signal. As the strb is effective, so assign the value from CSR
preRoute_dst_local.bits.readerwriterCfg.enabledByte := remainingCSR.head
remainingCSR = remainingCSR.tail
// Connect reader + writer cfg to the structured signal: Dst side
remainingCSR =
preRoute_dst_local.bits.connectReaderWriterCfgWithList(remainingCSR)

// Connect extension signal
// Connect extension signal: Dst side
for (i <- 0 until preRoute_dst_local.bits.extCfg.length) {
preRoute_dst_local.bits.extCfg(i) := remainingCSR.head
remainingCSR = remainingCSR.tail
Expand Down
19 changes: 19 additions & 0 deletions hw/chisel/src/main/scala/snax/xdma/xdmaFrontend/DMADataPath.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ class DMADataPathCfgIO(param: DMADataPathParam) extends Bundle {
param.rwParam.aguParam
) // Buffered within AGU
val readerwriterCfg = new ReaderWriterCfgIO(param.rwParam)

def connectReaderWriterCfgWithList(
csrList: IndexedSeq[UInt]
): IndexedSeq[UInt] = {
var remaincsrList = csrList
remaincsrList = aguCfg.connectWithList(remaincsrList)
remaincsrList = readerwriterCfg.connectWithList(remaincsrList)
remaincsrList
}

val extCfg = if (param.extParam.length != 0) {
Vec(
param.extParam.map { i => i.totalCsrNum }.reduce(_ + _) + 1,
Expand Down Expand Up @@ -68,6 +78,15 @@ class DMADataPathCfgInternalIO(param: DMADataPathParam)
val loopBack = Bool()
val readerPtr = UInt(param.axiParam.addrWidth.W)
val writerPtr = UInt(param.axiParam.addrWidth.W)
override def connectReaderWriterCfgWithList(
csrList: IndexedSeq[UInt]
): IndexedSeq[UInt] = {
var remainingCSR = csrList
readerPtr := Cat(remainingCSR(1), remainingCSR(0))
writerPtr := Cat(remainingCSR(1), remainingCSR(0))
remainingCSR = super.connectReaderWriterCfgWithList(remainingCSR)
remainingCSR
}
override def serialize(): UInt = {
super.serialize() ++ writerPtr ++ readerPtr
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,29 @@ class AddressGenUnitCfgIO(param: AddressGenUnitParam) extends Bundle {
Vec(param.spatialBounds.length, UInt(param.addressWidth.W))
val temporalStrides = Vec(param.temporalDimension, UInt(param.addressWidth.W))
val temporalBounds = Vec(param.temporalDimension, UInt(param.addressWidth.W))

def connectWithList(csrList: IndexedSeq[UInt]): IndexedSeq[UInt] = {
var remainingCSR = csrList
// Connect the ptr
ptr := Cat(remainingCSR(1), remainingCSR(0))
remainingCSR = remainingCSR.drop(2)
// Connect the spatial strides
for (i <- 0 until spatialStrides.length) {
spatialStrides(i) := remainingCSR.head
remainingCSR = remainingCSR.tail
}
// Connect the temporal strides
for (i <- 0 until temporalStrides.length) {
temporalStrides(i) := remainingCSR.head
remainingCSR = remainingCSR.tail
}
// Connect the temporal bounds
for (i <- 0 until temporalBounds.length) {
temporalBounds(i) := remainingCSR.head
remainingCSR = remainingCSR.tail
}
remainingCSR
}
}

/** AGU is the module to automatically generate the address for all ports.
Expand Down
5 changes: 5 additions & 0 deletions hw/chisel/src/main/scala/snax/xdma/xdmaStreamer/Reader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ class Reader(param: ReaderWriterParam, clusterName: String = "unnamed_cluster")

override val desiredName = s"${clusterName}_xdma_Reader"

require(
param.configurableByteMask == false,
"Byte Mask is not supported in Reader"
)

val io = IO(new ReaderIO(param))

// New Address Generator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@ class ReaderWriterCfgIO(val param: ReaderWriterParam) extends Bundle {
if (param.configurableChannel)
UInt(param.tcdmParam.numChannel.W)
else UInt(0.W)

def connectWithList(csrList: IndexedSeq[UInt]): IndexedSeq[UInt] = {
var remaincsrList = csrList
if (param.configurableChannel) {
enabledChannel := remaincsrList.head
remaincsrList = remaincsrList.tail
} else {
enabledChannel := Fill(param.tcdmParam.numChannel, 1.U)
}
if (param.configurableByteMask) {
enabledByte := remaincsrList.head
remaincsrList = remaincsrList.tail
} else {
enabledByte := Fill(param.tcdmParam.dataWidth / 8, 1.U)
}
remaincsrList
}
}

abstract class ReaderWriterCommomIO(val param: ReaderWriterParam)
Expand All @@ -24,6 +41,13 @@ abstract class ReaderWriterCommomIO(val param: ReaderWriterParam)
// The signal to control which byte is written to TCDM
val readerwriterCfg = Input(new ReaderWriterCfgIO(param))

def connectCfgWithList(csrList: IndexedSeq[UInt]): IndexedSeq[UInt] = {
var remaincsrList = csrList
remaincsrList = aguCfg.connectWithList(remaincsrList)
remaincsrList = readerwriterCfg.connectWithList(remaincsrList)
remaincsrList
}

// The signal trigger the start of Address Generator. The non-empty of address generator will cause data requestor to read the data
val start = Input(Bool())
// The module is busy if addressgen is busy or fifo in addressgen is not empty
Expand Down
8 changes: 6 additions & 2 deletions hw/chisel/src/main/scala/snax/xdma/xdmaTop/xdmaTop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@ object xdmaTopGen extends App {
tcdmSize = parsedArgs("tcdmSize").toInt,
numChannel =
parsedArgs("axiDataWidth").toInt / parsedArgs("tcdmDataWidth").toInt,
addressBufferDepth = parsedArgs("readerBufferDepth").toInt
addressBufferDepth = parsedArgs("readerBufferDepth").toInt,
configurableChannel = true,
configurableByteMask = false
)

val writerparam = new ReaderWriterParam(
Expand All @@ -180,7 +182,9 @@ object xdmaTopGen extends App {
tcdmSize = parsedArgs("tcdmSize").toInt,
numChannel =
parsedArgs("axiDataWidth").toInt / parsedArgs("tcdmDataWidth").toInt,
addressBufferDepth = parsedArgs("writerBufferDepth").toInt
addressBufferDepth = parsedArgs("writerBufferDepth").toInt,
configurableChannel = true,
configurableByteMask = true
)
var readerextensionparam = Seq[HasDMAExtension]()
var writerextensionparam = Seq[HasDMAExtension]()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ class DMADataPathTester extends AnyFreeSpec with ChiselScalatestTester {
new DMADataPath(
readerparam = new DMADataPathParam(
axiParam = new AXIParam,
rwParam = new ReaderWriterParam
rwParam = new ReaderWriterParam(configurableByteMask = false)
),
writerparam = new DMADataPathParam(
axiParam = new AXIParam,
rwParam = new ReaderWriterParam
rwParam = new ReaderWriterParam(configurableByteMask = true)
)
)
).withAnnotations(Seq(WriteVcdAnnotation, VerilatorBackendAnnotation)) {
Expand Down Expand Up @@ -81,7 +81,6 @@ class DMADataPathTester extends AnyFreeSpec with ChiselScalatestTester {
// Poke the reader agu
dut.io.readerCfg.aguCfg.ptr.poke(readerTestingParams.address)
dut.io.readerCfg.readerwriterCfg.enabledChannel.poke(0xff.U)
dut.io.readerCfg.readerwriterCfg.enabledByte.poke(0xff.U)
dut.io.readerCfg.aguCfg
.temporalBounds(0)
.poke(readerTestingParams.temporal_bound(0))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import snax.xdma.DesignParams._

class ReaderTester extends AnyFreeSpec with ChiselScalatestTester {
"Reader's behavior is as expected" in test(
new Reader(new ReaderWriterParam)
new Reader(new ReaderWriterParam(configurableByteMask = false))
).withAnnotations(Seq(WriteVcdAnnotation, VerilatorBackendAnnotation)) {
dut =>
// The accessed address is 1KB (0x0 - 0x400)
Expand All @@ -31,7 +31,6 @@ class ReaderTester extends AnyFreeSpec with ChiselScalatestTester {
dut.io.aguCfg.temporalBounds(1).poke(16)

dut.io.readerwriterCfg.enabledChannel.poke(0xff.U)
dut.io.readerwriterCfg.enabledByte.poke(0xff.U)

dut.io.start.poke(true)
dut.clock.step()
Expand Down
23 changes: 11 additions & 12 deletions hw/chisel/src/test/scala/snax/xdma/xdmaTop/xdmaTopTester.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,11 @@ class xDMATopTester extends AnyFreeSpec with ChiselScalatestTester {
new xdmaTop(
readerParam = new DMADataPathParam(
axiParam = new AXIParam,
rwParam = new ReaderWriterParam
rwParam = new ReaderWriterParam(configurableByteMask = false)
),
writerParam = new DMADataPathParam(
axiParam = new AXIParam,
rwParam = new ReaderWriterParam,
rwParam = new ReaderWriterParam(configurableByteMask = true),
extParam = Seq(HasVerilogMemset, HasMaxPool, HasTransposer)
)
)
Expand All @@ -129,13 +129,13 @@ class xDMATopTester extends AnyFreeSpec with ChiselScalatestTester {
address = 0,
spatialStrides = Array(8),
temporalStrides = Array(8, 0),
temporalBounds = Array(2048, 1),
temporalBounds = Array(2048, 1)
)
var writerAGUParam = new AGUParamTest(
address = 16 * 1024,
spatialStrides = Array(8),
temporalStrides = Array(8, 0),
temporalBounds = Array(2048, 1),
temporalBounds = Array(2048, 1)
)

var readerRWParam = new RWParamTest(
Expand Down Expand Up @@ -337,13 +337,13 @@ class xDMATopTester extends AnyFreeSpec with ChiselScalatestTester {
address = 0,
spatialStrides = Array(8),
temporalStrides = Array(64, 0),
temporalBounds = Array(256, 1),
temporalBounds = Array(256, 1)
)
writerAGUParam = new AGUParamTest(
address = 16 * 1024,
spatialStrides = Array(8),
temporalStrides = Array(64, 0),
temporalBounds = Array(256, 1),
temporalBounds = Array(256, 1)
)

readerRWParam = new RWParamTest(
Expand Down Expand Up @@ -529,7 +529,6 @@ class xDMATopTester extends AnyFreeSpec with ChiselScalatestTester {
) != 2
) {}


// Check whether the data in memory is coincide with the expectation
mem_to_be_checked = tcdm_mem.filter(_._1 >= 1024 * 16)
if (mem_to_be_checked.map(_._2 == 0).reduce(_ & _))
Expand All @@ -542,13 +541,13 @@ class xDMATopTester extends AnyFreeSpec with ChiselScalatestTester {
address = 0,
spatialStrides = Array(8),
temporalStrides = Array(64, 0),
temporalBounds = Array(256, 1),
temporalBounds = Array(256, 1)
)
writerAGUParam = new AGUParamTest(
address = 16 * 1024,
spatialStrides = Array(8),
temporalStrides = Array(64, 0),
temporalBounds = Array(256, 1),
temporalBounds = Array(256, 1)
)

readerRWParam = new RWParamTest(
Expand All @@ -559,7 +558,7 @@ class xDMATopTester extends AnyFreeSpec with ChiselScalatestTester {
enabledChannel = Integer.parseInt("11111111", 2),
enabledByte = Integer.parseInt("00000001", 2)
)

writerExtParam = new ExtParam(
bypassMemset = 0,
MemsetValue = 0xff,
Expand Down Expand Up @@ -781,13 +780,13 @@ class xDMATopTester extends AnyFreeSpec with ChiselScalatestTester {
address = 0,
spatialStrides = Array(8),
temporalStrides = Array(64, 0),
temporalBounds = Array(256, 1),
temporalBounds = Array(256, 1)
)
writerAGUParam = new AGUParamTest(
address = 16 * 1024,
spatialStrides = Array(8),
temporalStrides = Array(64, 0),
temporalBounds = Array(256, 1),
temporalBounds = Array(256, 1)
)

readerRWParam = new RWParamTest(
Expand Down

0 comments on commit 1c4d263

Please sign in to comment.