From f6b8a5a63594d9400225f7797780ba6e7124c61e Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 10:37:15 +0200 Subject: [PATCH 01/19] light refactoring to enable split main <-> test --- .../scala/snax/csr_manager/CsrManager.scala | 11 --- .../main/scala/snax/streamer/DataMover.scala | 6 +- .../main/scala/snax/streamer/DataReader.scala | 11 +-- .../main/scala/snax/streamer/DataWriter.scala | 11 +-- .../src/main/scala/snax/streamer/FIFO.scala | 12 +-- .../main/scala/snax/streamer/Parameters.scala | 39 ++++----- .../snax/streamer/SpatialAddrGenUnit.scala | 9 +- .../main/scala/snax/streamer/Streamer.scala | 53 +----------- .../snax/streamer/StreamerTestParameter.scala | 32 ++++++++ .../scala/snax/streamer/StreamerTop.scala | 82 +------------------ .../snax/streamer/TemporalAddrGenUnit.scala | 9 +- .../snax/csr_manager/CsrManagerGenerate.scala | 0 .../scala/snax/streamer/DataReaderTest.scala | 4 +- .../scala/snax/streamer/DataWriterTest.scala | 4 +- .../test/scala/snax/streamer/FIFOTest.scala | 2 +- .../streamer/SpatialAddrGenUnitTest.scala | 12 +-- .../scala/snax/streamer/StreamerTest.scala | 20 ++--- .../snax/streamer/StreamerTopGenerate.scala | 1 + .../scala/snax/streamer/StreamerTopTest.scala | 28 ++++--- .../streamer/TemporalAddrGenUnitTest.scala | 10 +-- 20 files changed, 110 insertions(+), 246 deletions(-) create mode 100644 hw/chisel/src/test/scala/snax/csr_manager/CsrManagerGenerate.scala create mode 100644 hw/chisel/src/test/scala/snax/streamer/StreamerTopGenerate.scala diff --git a/hw/chisel/src/main/scala/snax/csr_manager/CsrManager.scala b/hw/chisel/src/main/scala/snax/csr_manager/CsrManager.scala index d56052f95..5f5e0fee3 100644 --- a/hw/chisel/src/main/scala/snax/csr_manager/CsrManager.scala +++ b/hw/chisel/src/main/scala/snax/csr_manager/CsrManager.scala @@ -116,14 +116,3 @@ class CsrManager( } -// Scala main function for generating CsrManager system verilog file -object CsrManager extends App { - emitVerilog( - new CsrManager( - csrManagerTestParameters.csrNum, - csrManagerTestParameters.csrAddrWidth, - csrManagerTestParameters.csrModuleTagName - ), - Array("--target-dir", "generated/csr_manager") - ) -} diff --git a/hw/chisel/src/main/scala/snax/streamer/DataMover.scala b/hw/chisel/src/main/scala/snax/streamer/DataMover.scala index fcdee2ebd..d9ab326ea 100644 --- a/hw/chisel/src/main/scala/snax/streamer/DataMover.scala +++ b/hw/chisel/src/main/scala/snax/streamer/DataMover.scala @@ -15,7 +15,7 @@ import chisel3.util._ * @param params * The parameter class contains all the parameters of a data mover module */ -class DataMoverIO(params: DataMoverParams = DataMoverParams()) extends Bundle { +class DataMoverIO(params: DataMoverParams) extends Bundle { // signals for write request address generation val ptr_agu_i = Flipped(Decoupled(UInt(params.addrWidth.W))) @@ -46,7 +46,7 @@ class DataMoverIO(params: DataMoverParams = DataMoverParams()) extends Bundle { * The parameter class contains all the parameters of a data mover module */ class DataMover( - params: DataMoverParams = DataMoverParams(), + params: DataMoverParams, tagName: String = "" ) extends Module with RequireAsyncReset { @@ -222,7 +222,7 @@ class DataMover( // classes which extend the DataMover module, but are just // set to 0 here for testing purposes. class DataMoverTester( - params: DataMoverParams = DataMoverParams() + params: DataMoverParams, ) extends DataMover(params) { for (i <- 0 until params.tcdmPortsNum) { diff --git a/hw/chisel/src/main/scala/snax/streamer/DataReader.scala b/hw/chisel/src/main/scala/snax/streamer/DataReader.scala index f09a13219..527515719 100644 --- a/hw/chisel/src/main/scala/snax/streamer/DataReader.scala +++ b/hw/chisel/src/main/scala/snax/streamer/DataReader.scala @@ -12,7 +12,7 @@ import chisel3.util._ * The parameter class contains all the parameters of a data mover module */ class DataReaderIO( - params: DataMoverParams = DataMoverParams() + params: DataMoverParams, ) extends DataMoverIO(params) { // tcdm response @@ -40,7 +40,7 @@ class DataReaderIO( * The parameter class contains all the parameters of a data mover module */ class DataReader( - params: DataMoverParams = DataMoverParams(), + params: DataMoverParams, tagName: String = "" ) extends DataMover(params, tagName) { override val desiredName = tagName + "DataReader" @@ -136,10 +136,3 @@ class DataReader( } -// Scala main function for generating system verilog file for the DataReader module -object DataReader extends App { - emitVerilog( - new DataReader(DataMoverParams()), - Array("--target-dir", "generated/streamer") - ) -} diff --git a/hw/chisel/src/main/scala/snax/streamer/DataWriter.scala b/hw/chisel/src/main/scala/snax/streamer/DataWriter.scala index a4d50e3ee..c85f85508 100644 --- a/hw/chisel/src/main/scala/snax/streamer/DataWriter.scala +++ b/hw/chisel/src/main/scala/snax/streamer/DataWriter.scala @@ -11,7 +11,7 @@ import chisel3.util._ * The parameter class contains all the parameters of a data mover module */ class DataWriterIO( - params: DataMoverParams = DataMoverParams() + params: DataMoverParams, ) extends DataMoverIO(params) { // valid data from the queue @@ -32,7 +32,7 @@ class DataWriterIO( * The parameter class contains all the parameters of a data mover module */ class DataWriter( - params: DataMoverParams = DataMoverParams(), + params: DataMoverParams, tagName: String = "" ) extends DataMover(params) { override val desiredName = tagName + "DataWriter" @@ -63,10 +63,3 @@ class DataWriter( } -// Scala main function for generating system verilog file for the DataWriter module -object DataWriter extends App { - emitVerilog( - new DataWriter(DataMoverParams()), - Array("--target-dir", "generated/streamer") - ) -} diff --git a/hw/chisel/src/main/scala/snax/streamer/FIFO.scala b/hw/chisel/src/main/scala/snax/streamer/FIFO.scala index df68a68eb..701d46e1e 100644 --- a/hw/chisel/src/main/scala/snax/streamer/FIFO.scala +++ b/hw/chisel/src/main/scala/snax/streamer/FIFO.scala @@ -5,15 +5,15 @@ import chisel3.util._ // Customized FIFO with an extra almost_full signal. // almost_full will be asserted when there is Depth-1 elements in the FIFO -class FIFOIO(width: Int = FIFOTestParameters.fifoWidth) extends Bundle { +class FIFOIO(width: Int) extends Bundle { val in = Flipped(Decoupled(UInt(width.W))) val out = Decoupled(UInt(width.W)) val almost_full = Output(Bool()) } class FIFO( - depth: Int = FIFOTestParameters.fifoDepth, - width: Int = FIFOTestParameters.fifoWidth, + depth: Int, + width: Int, tagName: String = "" ) extends Module with RequireAsyncReset { @@ -33,9 +33,3 @@ class FIFO( } -object FIFO extends App { - emitVerilog( - new (FIFO), - Array("--target-dir", "generated/streamer") - ) -} diff --git a/hw/chisel/src/main/scala/snax/streamer/Parameters.scala b/hw/chisel/src/main/scala/snax/streamer/Parameters.scala index 3298d284c..2ac413a74 100644 --- a/hw/chisel/src/main/scala/snax/streamer/Parameters.scala +++ b/hw/chisel/src/main/scala/snax/streamer/Parameters.scala @@ -26,9 +26,9 @@ trait CommonParams { * The bit width of the address. */ case class TemporalAddrGenUnitParams( - loopDim: Int = TemporalAddrGenUnitTestParameters.loopDim, - loopBoundWidth: Int = TemporalAddrGenUnitTestParameters.loopBoundWidth, - addrWidth: Int = TemporalAddrGenUnitTestParameters.addrWidth + loopDim: Int, + loopBoundWidth: Int, + addrWidth: Int, ) /** This class represents all the parameters for the Spatial Address Generation @@ -41,9 +41,9 @@ case class TemporalAddrGenUnitParams( * The bit width of the address. */ case class SpatialAddrGenUnitParams( - loopDim: Int = SpatialAddrGenUnitTestParameters.loopDim, - loopBounds: Seq[Int] = SpatialAddrGenUnitTestParameters.loopBounds, - addrWidth: Int = SpatialAddrGenUnitTestParameters.addrWidth + loopDim: Int, + loopBounds: Seq[Int], + addrWidth: Int, ) /** This class represents all the parameters for the Data Mover (including Data @@ -63,11 +63,11 @@ case class SpatialAddrGenUnitParams( * FIFO width */ case class DataMoverParams( - tcdmPortsNum: Int = DataMoverTestParameters.tcdmPortsNum, - spatialBounds: Seq[Int] = DataMoverTestParameters.spatialBounds, - spatialDim: Int = DataMoverTestParameters.spatialDim, - elementWidth: Int = DataMoverTestParameters.elementWidth, - fifoWidth: Int = DataMoverTestParameters.fifoWidth + tcdmPortsNum: Int, + spatialBounds: Seq[Int], + spatialDim: Int, + elementWidth: Int, + fifoWidth: Int, ) extends CommonParams /** FIFO parameters @@ -173,15 +173,12 @@ trait HasStreamerInferredParams extends HasStreamerCoreParams { * default value of these parameters is from the StreamerTestConstant object */ case class StreamerParams( - temporalAddrGenUnitParams: TemporalAddrGenUnitParams = - StreamerTestConstant.temporalAddrGenUnitParams, - stationarity: Seq[Int] = StreamerTestConstant.stationarity, - dataReaderParams: Seq[DataMoverParams] = - StreamerTestConstant.dataReaderParams, - dataWriterParams: Seq[DataMoverParams] = - StreamerTestConstant.dataWriterParams, - fifoReaderParams: Seq[FIFOParams] = StreamerTestConstant.fifoReaderParams, - fifoWriterParams: Seq[FIFOParams] = StreamerTestConstant.fifoWriterParams, - tagName: String = StreamerTestConstant.tagName + temporalAddrGenUnitParams: TemporalAddrGenUnitParams, + stationarity: Seq[Int], + dataReaderParams: Seq[DataMoverParams], + dataWriterParams: Seq[DataMoverParams], + fifoReaderParams: Seq[FIFOParams], + fifoWriterParams: Seq[FIFOParams], + tagName: String, ) extends HasStreamerCoreParams with HasStreamerInferredParams diff --git a/hw/chisel/src/main/scala/snax/streamer/SpatialAddrGenUnit.scala b/hw/chisel/src/main/scala/snax/streamer/SpatialAddrGenUnit.scala index 454ca02b6..0afd806cc 100644 --- a/hw/chisel/src/main/scala/snax/streamer/SpatialAddrGenUnit.scala +++ b/hw/chisel/src/main/scala/snax/streamer/SpatialAddrGenUnit.scala @@ -79,7 +79,7 @@ trait WithSpatialLoopIndices { * The bit width of the address. */ class SpatialAddrGenUnit( - params: SpatialAddrGenUnitParams = SpatialAddrGenUnitParams(), + params: SpatialAddrGenUnitParams, tagName: String = "" ) extends Module with RequireAsyncReset @@ -158,10 +158,3 @@ class SpatialAddrGenUnit( } -// Scala main function for generating system verilog file for the SpatialAddrGenUnit module -object SpatialAddrGenUnit extends App { - emitVerilog( - new SpatialAddrGenUnit(SpatialAddrGenUnitParams()), - Array("--target-dir", "generated/streamer") - ) -} diff --git a/hw/chisel/src/main/scala/snax/streamer/Streamer.scala b/hw/chisel/src/main/scala/snax/streamer/Streamer.scala index b7361ac41..327671b9b 100644 --- a/hw/chisel/src/main/scala/snax/streamer/Streamer.scala +++ b/hw/chisel/src/main/scala/snax/streamer/Streamer.scala @@ -27,7 +27,7 @@ class DataFromAcceleratorX( // csr related io class StreamerCsrIO( - params: StreamerParams = StreamerParams() + params: StreamerParams, ) extends Bundle { // configurations interface for a new data operation @@ -373,55 +373,4 @@ class Streamer( } -// Scala main function for generating test streamer system verilog file -object StreamerTester extends App { - emitVerilog( - new Streamer(StreamerParams()), - Array("--target-dir", "generated/streamer/tester") - ) -} - -// Scala main function for generating system verilog file for different accelerators -// including GEMM, Post-processing SIMD and MAC engine -object GemmStreamer extends App { - emitVerilog( - new Streamer( - StreamerParams( - temporalAddrGenUnitParams = - GeMMStreamerParameters.temporalAddrGenUnitParams, - fifoReaderParams = GeMMStreamerParameters.fifoReaderParams, - fifoWriterParams = GeMMStreamerParameters.fifoWriterParams, - stationarity = GeMMStreamerParameters.stationarity, - dataReaderParams = GeMMStreamerParameters.dataReaderParams, - dataWriterParams = GeMMStreamerParameters.dataWriterParams - ) - ), - Array("--target-dir", "generated/streamer/gemm") - ) -} -object PostProcessingStreamer extends App { - emitVerilog( - new Streamer( - StreamerParams( - temporalAddrGenUnitParams = - PostProcessingStreamerParameters.temporalAddrGenUnitParams, - fifoReaderParams = PostProcessingStreamerParameters.fifoReaderParams, - fifoWriterParams = PostProcessingStreamerParameters.fifoWriterParams, - stationarity = PostProcessingStreamerParameters.stationarity, - dataReaderParams = PostProcessingStreamerParameters.dataReaderParams, - dataWriterParams = PostProcessingStreamerParameters.dataWriterParams - ) - ), - Array("--target-dir", "generated/streamer/pp") - ) -} - -object MacStreamer extends App { - emitVerilog( - new Streamer( - StreamerParams() - ), - Array("--target-dir", "generated/streamer/mac") - ) -} diff --git a/hw/chisel/src/main/scala/snax/streamer/StreamerTestParameter.scala b/hw/chisel/src/main/scala/snax/streamer/StreamerTestParameter.scala index 9d4e2993d..aa3c9af77 100644 --- a/hw/chisel/src/main/scala/snax/streamer/StreamerTestParameter.scala +++ b/hw/chisel/src/main/scala/snax/streamer/StreamerTestParameter.scala @@ -90,6 +90,38 @@ object StreamerTestConstant extends CommonParams { def tagName: String = "" } +object TestParameters { + val streamer = StreamerParams( + temporalAddrGenUnitParams = StreamerTestConstant.temporalAddrGenUnitParams, + stationarity = StreamerTestConstant.stationarity, + dataReaderParams = StreamerTestConstant.dataReaderParams, + dataWriterParams = StreamerTestConstant.dataWriterParams, + fifoReaderParams = StreamerTestConstant.fifoReaderParams, + fifoWriterParams = StreamerTestConstant.fifoWriterParams, + tagName = "abc" + ) + + val temporalAddrGenUnit = TemporalAddrGenUnitParams( + loopDim = 3, + loopBoundWidth = 8, + addrWidth = 32 + ) + + val spatialAddrGenUnit = SpatialAddrGenUnitParams ( + loopBounds = Seq(8, 8), + loopDim = 2, + addrWidth = 32 + ) + + val dataMover = DataMoverParams ( + tcdmPortsNum = 8, + spatialBounds = Seq(8, 8), + fifoWidth = 512, + elementWidth = 8, + spatialDim = 2, + ) +} + object FIFOTestParameters { def fifoWidth = 512 def fifoDepth = 4 diff --git a/hw/chisel/src/main/scala/snax/streamer/StreamerTop.scala b/hw/chisel/src/main/scala/snax/streamer/StreamerTop.scala index 0fad72900..272a57446 100644 --- a/hw/chisel/src/main/scala/snax/streamer/StreamerTop.scala +++ b/hw/chisel/src/main/scala/snax/streamer/StreamerTop.scala @@ -14,7 +14,7 @@ import chisel3.experimental.{prefix, noPrefix} * the parameters class instantiation for the streamer top module */ class StreamerTopIO( - params: StreamerParams = StreamerParams(), + params: StreamerParams, csrAddrWidth: Int ) extends Bundle { @@ -34,7 +34,7 @@ class StreamerTopIO( * the parameters class instantiation for the streamer top module */ class StreamerTop( - params: StreamerParams = StreamerParams() + params: StreamerParams, ) extends Module with RequireAsyncReset { @@ -154,82 +154,4 @@ class StreamerTop( } -// Scala main function for generating test streamerTop system verilog file -object StreamerTopTester extends App { - emitVerilog( - new StreamerTop( - StreamerParams( - temporalAddrGenUnitParams = - StreamerTestConstant.temporalAddrGenUnitParams, - fifoReaderParams = StreamerTestConstant.fifoReaderParams, - fifoWriterParams = StreamerTestConstant.fifoWriterParams, - stationarity = StreamerTestConstant.stationarity, - dataReaderParams = StreamerTestConstant.dataReaderParams, - dataWriterParams = StreamerTestConstant.dataWriterParams - ) - ), - Array("--target-dir", "generated/streamertop/tester") - ) -} - -// streamertop for GEMM -object GeMMStreamerTop { - def main(args: Array[String]): Unit = { - val outPath = args.headOption.getOrElse("generated/streamertop/gemm") - emitVerilog( - new StreamerTop( - StreamerParams( - temporalAddrGenUnitParams = - GeMMStreamerParameters.temporalAddrGenUnitParams, - fifoReaderParams = GeMMStreamerParameters.fifoReaderParams, - fifoWriterParams = GeMMStreamerParameters.fifoWriterParams, - stationarity = GeMMStreamerParameters.stationarity, - dataReaderParams = GeMMStreamerParameters.dataReaderParams, - dataWriterParams = GeMMStreamerParameters.dataWriterParams, - tagName = "GeMM" - ) - ), - Array("--target-dir", outPath) - ) - } -} -// streamertop for PP-SIMD -object PostProcessingStreamerTop { - def main(args: Array[String]): Unit = { - val outPath = args.headOption.getOrElse("generated/streamertop/simd") - emitVerilog( - new StreamerTop( - StreamerParams( - temporalAddrGenUnitParams = - PostProcessingStreamerParameters.temporalAddrGenUnitParams, - fifoReaderParams = PostProcessingStreamerParameters.fifoReaderParams, - fifoWriterParams = PostProcessingStreamerParameters.fifoWriterParams, - stationarity = PostProcessingStreamerParameters.stationarity, - dataReaderParams = PostProcessingStreamerParameters.dataReaderParams, - dataWriterParams = PostProcessingStreamerParameters.dataWriterParams, - tagName = "PostProcessingSIMD" - ) - ), - Array("--target-dir", outPath) - ) - } -} - -// streamertop for MAC -object MacStreamerTop extends App { - emitVerilog( - new StreamerTop( - StreamerParams( - temporalAddrGenUnitParams = - MacStreamerParameters.temporalAddrGenUnitParams, - fifoReaderParams = MacStreamerParameters.fifoReaderParams, - fifoWriterParams = MacStreamerParameters.fifoWriterParams, - stationarity = MacStreamerParameters.stationarity, - dataReaderParams = MacStreamerParameters.dataReaderParams, - dataWriterParams = MacStreamerParameters.dataWriterParams - ) - ), - Array("--target-dir", "generated/streamertop/mac") - ) -} diff --git a/hw/chisel/src/main/scala/snax/streamer/TemporalAddrGenUnit.scala b/hw/chisel/src/main/scala/snax/streamer/TemporalAddrGenUnit.scala index 51df5e900..cc2989d82 100644 --- a/hw/chisel/src/main/scala/snax/streamer/TemporalAddrGenUnit.scala +++ b/hw/chisel/src/main/scala/snax/streamer/TemporalAddrGenUnit.scala @@ -67,7 +67,7 @@ class TemporalAddrGenUnitIO( * The bit width of the addresses. */ class TemporalAddrGenUnit( - params: TemporalAddrGenUnitParams = TemporalAddrGenUnitParams(), + params: TemporalAddrGenUnitParams, tagName: String = "" ) extends Module with RequireAsyncReset { @@ -208,10 +208,3 @@ class TemporalAddrGenUnit( io.done := addr_gen_finish } -// Scala main function for generating system verilog file for the TemporalAddrGenUnit module -object TemporalAddrGenUnit extends App { - emitVerilog( - new TemporalAddrGenUnit(TemporalAddrGenUnitParams()), - Array("--target-dir", "generated/streamer") - ) -} diff --git a/hw/chisel/src/test/scala/snax/csr_manager/CsrManagerGenerate.scala b/hw/chisel/src/test/scala/snax/csr_manager/CsrManagerGenerate.scala new file mode 100644 index 000000000..e69de29bb diff --git a/hw/chisel/src/test/scala/snax/streamer/DataReaderTest.scala b/hw/chisel/src/test/scala/snax/streamer/DataReaderTest.scala index 214365b50..ebf050daf 100644 --- a/hw/chisel/src/test/scala/snax/streamer/DataReaderTest.scala +++ b/hw/chisel/src/test/scala/snax/streamer/DataReaderTest.scala @@ -14,7 +14,7 @@ class DataReaderTest with ChiselScalatestTester with Matchers { "DUT" should "pass" in { - test(new DataReader(DataMoverParams())).withAnnotations( + test(new DataReader(TestParameters.dataMover)).withAnnotations( Seq(WriteVcdAnnotation) ) { dut => dut.clock.step(5) @@ -23,7 +23,7 @@ class DataReaderTest dut.io.spatialStrides_csr_i.bits(1).poke(8) dut.io.spatialStrides_csr_i.valid.poke(1) dut.io.data_fifo_o.ready.poke(1) - for (i <- 0 until DataMoverTestParameters.tcdmPortsNum) { + for (i <- 0 until TestParameters.dataMover.tcdmPortsNum) { dut.io.tcdm_req(i).ready.poke(1) dut.io.tcdm_rsp(i).bits.data.poke(1) } diff --git a/hw/chisel/src/test/scala/snax/streamer/DataWriterTest.scala b/hw/chisel/src/test/scala/snax/streamer/DataWriterTest.scala index 65f73e158..1881cc038 100644 --- a/hw/chisel/src/test/scala/snax/streamer/DataWriterTest.scala +++ b/hw/chisel/src/test/scala/snax/streamer/DataWriterTest.scala @@ -14,7 +14,7 @@ class DataWriterTest with ChiselScalatestTester with Matchers { "DUT" should "pass" in { - test(new DataWriter(DataMoverParams())).withAnnotations( + test(new DataWriter(TestParameters.dataMover)).withAnnotations( Seq(WriteVcdAnnotation) ) { dut => dut.clock.step(5) @@ -23,7 +23,7 @@ class DataWriterTest dut.io.spatialStrides_csr_i.bits(1).poke(8) dut.io.spatialStrides_csr_i.valid.poke(1) dut.io.data_fifo_i.valid.poke(1) - for (i <- 0 until DataMoverTestParameters.tcdmPortsNum) { + for (i <- 0 until TestParameters.dataMover.tcdmPortsNum) { dut.io.tcdm_req(i).ready.poke(1) } dut.clock.step(5) diff --git a/hw/chisel/src/test/scala/snax/streamer/FIFOTest.scala b/hw/chisel/src/test/scala/snax/streamer/FIFOTest.scala index 73b4651c5..18b2ffe4d 100644 --- a/hw/chisel/src/test/scala/snax/streamer/FIFOTest.scala +++ b/hw/chisel/src/test/scala/snax/streamer/FIFOTest.scala @@ -9,7 +9,7 @@ import org.scalatest.Tag class FIFOTest extends AnyFlatSpec with ChiselScalatestTester with Matchers { "DUT" should "pass" in { - test(new FIFO) + test(new FIFO(width=FIFOTestParameters.fifoWidth, depth=FIFOTestParameters.fifoDepth)) .withAnnotations( Seq(WriteVcdAnnotation) ) { dut => diff --git a/hw/chisel/src/test/scala/snax/streamer/SpatialAddrGenUnitTest.scala b/hw/chisel/src/test/scala/snax/streamer/SpatialAddrGenUnitTest.scala index d759c8d24..8c88d6e47 100644 --- a/hw/chisel/src/test/scala/snax/streamer/SpatialAddrGenUnitTest.scala +++ b/hw/chisel/src/test/scala/snax/streamer/SpatialAddrGenUnitTest.scala @@ -14,20 +14,20 @@ class SpatialAddrGenUnitTest with ChiselScalatestTester with Matchers { "DUT" should "pass" in { - test(new SpatialAddrGenUnit(SpatialAddrGenUnitParams())).withAnnotations( + test(new SpatialAddrGenUnit(TestParameters.spatialAddrGenUnit)).withAnnotations( Seq(WriteVcdAnnotation) ) { dut => dut.clock.step(5) // random config generation val strides = - Seq.fill(SpatialAddrGenUnitTestParameters.loopDim)( + Seq.fill(TestParameters.spatialAddrGenUnit.loopDim)( ( scala.util.Random.nextInt(10) ) ) // sending these configuration to the dut - for (i <- 0 until SpatialAddrGenUnitTestParameters.loopDim) { + for (i <- 0 until TestParameters.spatialAddrGenUnit.loopDim) { val stride = strides(i).U dut.io.strides_i(i).poke(stride) } @@ -38,11 +38,11 @@ class SpatialAddrGenUnitTest // check the result (for loopDim = 2) val ptr_0 = 16 - for (i <- 0 until SpatialAddrGenUnitTestParameters.loopBounds(0)) { - for (j <- 0 until SpatialAddrGenUnitTestParameters.loopBounds(1)) { + for (i <- 0 until TestParameters.spatialAddrGenUnit.loopBounds(0)) { + for (j <- 0 until TestParameters.spatialAddrGenUnit.loopBounds(1)) { val ptr = ptr_0 + i * strides(0) + j * strides(1) dut.io - .ptr_o(i + j * SpatialAddrGenUnitTestParameters.loopBounds(0)) + .ptr_o(i + j * TestParameters.spatialAddrGenUnit.loopBounds(0)) .expect(ptr) } } diff --git a/hw/chisel/src/test/scala/snax/streamer/StreamerTest.scala b/hw/chisel/src/test/scala/snax/streamer/StreamerTest.scala index 014e2efc7..b17aa6dd5 100644 --- a/hw/chisel/src/test/scala/snax/streamer/StreamerTest.scala +++ b/hw/chisel/src/test/scala/snax/streamer/StreamerTest.scala @@ -12,7 +12,7 @@ class StreamerTest with ChiselScalatestTester with Matchers { "DUT" should "pass" in { - test(new Streamer(StreamerParams())) + test(new Streamer(TestParameters.streamer)) .withAnnotations( Seq(WriteVcdAnnotation) ) { dut => @@ -20,12 +20,12 @@ class StreamerTest // give valid transaction config dut.io.csr.valid.poke(1.B) - for (i <- 0 until StreamerParams().temporalDim) { + for (i <- 0 until TestParameters.streamer.temporalDim) { dut.io.csr.bits.loopBounds_i(i).poke(2) } // give the proper spatial strides so that is a aligned in one TCDM bank - for (i <- 0 until StreamerParams().dataMoverNum) { + for (i <- 0 until TestParameters.streamer.dataMoverNum) { dut.io.csr.bits.spatialStrides_csr_i(i)(0).poke(4) } @@ -35,37 +35,37 @@ class StreamerTest dut.clock.step(5) // give tcdm ports signals, no contention scene - for (i <- 0 until StreamerParams().dataReaderTcdmPorts.sum) { + for (i <- 0 until TestParameters.streamer.dataReaderTcdmPorts.sum) { dut.io.data.tcdm_req(i).ready.poke(1.B) dut.io.data.tcdm_rsp(i).valid.poke(1.B) } dut.clock.step(10) // give accelerator signals - for (i <- 0 until StreamerParams().dataReaderNum) { + for (i <- 0 until TestParameters.streamer.dataReaderNum) { dut.io.data.streamer2accelerator.data(i).ready.poke(1.B) } dut.clock.step(10) - for (i <- 0 until StreamerParams().dataReaderTcdmPorts.sum) { + for (i <- 0 until TestParameters.streamer.dataReaderTcdmPorts.sum) { dut.io.data.tcdm_req(i).ready.poke(0.B) dut.io.data.tcdm_rsp(i).valid.poke(0.B) } // mimic accelerator gives valid data dut.clock.step(10) - for (i <- 0 until StreamerParams().dataWriterNum) { + for (i <- 0 until TestParameters.streamer.dataWriterNum) { dut.io.data.accelerator2streamer.data(i).valid.poke(1.B) } dut.clock.step(4) - for (i <- 0 until StreamerParams().dataWriterNum) { + for (i <- 0 until TestParameters.streamer.dataWriterNum) { dut.io.data.accelerator2streamer.data(i).valid.poke(0.B) } // mimic tcdm is ready for write request - for (i <- 0 until StreamerParams().dataWriterTcdmPorts.sum) { + for (i <- 0 until TestParameters.streamer.dataWriterTcdmPorts.sum) { dut.io.data - .tcdm_req(i + StreamerParams().dataReaderTcdmPorts.sum) + .tcdm_req(i + TestParameters.streamer.dataReaderTcdmPorts.sum) .ready .poke(1.B) } diff --git a/hw/chisel/src/test/scala/snax/streamer/StreamerTopGenerate.scala b/hw/chisel/src/test/scala/snax/streamer/StreamerTopGenerate.scala new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/hw/chisel/src/test/scala/snax/streamer/StreamerTopGenerate.scala @@ -0,0 +1 @@ + diff --git a/hw/chisel/src/test/scala/snax/streamer/StreamerTopTest.scala b/hw/chisel/src/test/scala/snax/streamer/StreamerTopTest.scala index 600dc05a8..0652a7986 100644 --- a/hw/chisel/src/test/scala/snax/streamer/StreamerTopTest.scala +++ b/hw/chisel/src/test/scala/snax/streamer/StreamerTopTest.scala @@ -13,11 +13,19 @@ class StreamerTopTest with ChiselScalatestTester with Matchers { "DUT" should "pass" in { - test(new StreamerTop(new StreamerParams())) + test(new StreamerTop(new StreamerParams( + temporalAddrGenUnitParams = StreamerTestConstant.temporalAddrGenUnitParams, + stationarity = StreamerTestConstant.stationarity, + dataReaderParams = StreamerTestConstant.dataReaderParams, + dataWriterParams = StreamerTestConstant.dataWriterParams, + fifoReaderParams = StreamerTestConstant.fifoReaderParams, + fifoWriterParams = StreamerTestConstant.fifoWriterParams, + tagName = "abc", + ))) .withAnnotations( Seq(WriteVcdAnnotation) ) { dut => - dut.clock.step(5) + dut.clock.step(5) // write csr helper function def write_csr(addr: Int, data: Int) = { @@ -66,7 +74,7 @@ class StreamerTopTest // give valid transaction config // temporal loop bound - val temporal_loop_bound = 20 + val temporal_loop_bound = 20 write_csr(0, temporal_loop_bound) // temporal loop strides @@ -107,39 +115,39 @@ class StreamerTopTest dut.clock.step(5) // give tcdm ports signals, no contention scene - for (i <- 0 until StreamerParams().dataReaderTcdmPorts.sum) { + for (i <- 0 until TestParameters.streamer.dataReaderTcdmPorts.sum) { dut.io.data.tcdm_req(i).ready.poke(1.B) dut.io.data.tcdm_rsp(i).valid.poke(1.B) } // give accelerator ready to get input signals - for (i <- 0 until StreamerParams().dataReaderNum) { + for (i <- 0 until TestParameters.streamer.dataReaderNum) { dut.io.data.streamer2accelerator.data(i).ready.poke(1.B) } // wait for temporal_loop_bound cycles dut.clock.step(temporal_loop_bound * 2) - for (i <- 0 until StreamerParams().dataReaderTcdmPorts.sum) { + for (i <- 0 until TestParameters.streamer.dataReaderTcdmPorts.sum) { dut.io.data.tcdm_req(i).ready.poke(0.B) dut.io.data.tcdm_rsp(i).valid.poke(0.B) } // mimic accelerator gives valid data - for (i <- 0 until StreamerParams().dataWriterNum) { + for (i <- 0 until TestParameters.streamer.dataWriterNum) { dut.io.data.accelerator2streamer.data(i).valid.poke(1.B) } // mimic tcdm is ready for write request - for (i <- 0 until StreamerParams().dataWriterTcdmPorts.sum) { + for (i <- 0 until TestParameters.streamer.dataWriterTcdmPorts.sum) { dut.io.data - .tcdm_req(i + StreamerParams().dataReaderTcdmPorts.sum) + .tcdm_req(i + TestParameters.streamer.dataReaderTcdmPorts.sum) .ready .poke(1.B) } // wait for temporal_loop_bound cycles dut.clock.step(temporal_loop_bound * 2) - for (i <- 0 until StreamerParams().dataWriterNum) { + for (i <- 0 until TestParameters.streamer.dataWriterNum) { dut.io.data.accelerator2streamer.data(i).valid.poke(0.B) } diff --git a/hw/chisel/src/test/scala/snax/streamer/TemporalAddrGenUnitTest.scala b/hw/chisel/src/test/scala/snax/streamer/TemporalAddrGenUnitTest.scala index 2ea89da9a..913472910 100644 --- a/hw/chisel/src/test/scala/snax/streamer/TemporalAddrGenUnitTest.scala +++ b/hw/chisel/src/test/scala/snax/streamer/TemporalAddrGenUnitTest.scala @@ -15,7 +15,7 @@ class TemporalAddrGenUnitTest with Matchers with WithSpatialLoopIndices { "DUT" should "pass" in { - test(new TemporalAddrGenUnit(TemporalAddrGenUnitParams())).withAnnotations( + test(new TemporalAddrGenUnit(TestParameters.temporalAddrGenUnit)).withAnnotations( Seq(WriteVcdAnnotation) ) { dut => def test_once() = { @@ -23,20 +23,20 @@ class TemporalAddrGenUnitTest // random config generation val base_ptr = scala.util.Random.nextInt(100) val loopBounds = - Seq.fill(TemporalAddrGenUnitTestParameters.loopDim)( + Seq.fill(TestParameters.temporalAddrGenUnit.loopDim)( ( scala.util.Random.nextInt(5) + 1 ) ) val strides = - Seq.fill(TemporalAddrGenUnitTestParameters.loopDim)( + Seq.fill(TestParameters.temporalAddrGenUnit.loopDim)( ( scala.util.Random.nextInt(10) ) ) // sending these configuration to the dut - for (i <- 0 until TemporalAddrGenUnitTestParameters.loopDim) { + for (i <- 0 until TestParameters.temporalAddrGenUnit.loopDim) { val lb = loopBounds(i).U val ts = strides(i).U dut.io.loopBounds_i.bits(i).poke(lb) @@ -65,7 +65,7 @@ class TemporalAddrGenUnitTest while (dut.io.done.peekBoolean() == false) { val indices = genSpatialLoopIndices( - TemporalAddrGenUnitTestParameters.loopDim, + TestParameters.temporalAddrGenUnit.loopDim, loopBounds, counter ) From 2f4132a6166985d2fe71f6adbb913c6efb9b358f Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 10:47:34 +0200 Subject: [PATCH 02/19] enable CI to actually run the Chisel unit tests --- .github/workflows/scala-unit-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scala-unit-test.yml b/.github/workflows/scala-unit-test.yml index ba1d27022..f1f1a1d0c 100644 --- a/.github/workflows/scala-unit-test.yml +++ b/.github/workflows/scala-unit-test.yml @@ -20,6 +20,6 @@ jobs: steps: - uses: actions/checkout@v2 - name: Run the unit tests - working-directory: util/chiselgen + working-directory: hw/chisel run: | sbt test From 3bb6d334799a8ffabf6c007019a60debe417eeac Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 11:01:28 +0200 Subject: [PATCH 03/19] remove unused instance parameters --- .../streamer/StreamerInstanceParameters.scala | 151 ------------------ 1 file changed, 151 deletions(-) delete mode 100644 hw/chisel/src/main/scala/snax/streamer/StreamerInstanceParameters.scala diff --git a/hw/chisel/src/main/scala/snax/streamer/StreamerInstanceParameters.scala b/hw/chisel/src/main/scala/snax/streamer/StreamerInstanceParameters.scala deleted file mode 100644 index e8616f18e..000000000 --- a/hw/chisel/src/main/scala/snax/streamer/StreamerInstanceParameters.scala +++ /dev/null @@ -1,151 +0,0 @@ -package snax.streamer - -import chisel3._ -import chisel3.util._ - -// streamer parameters for the GEMM Accelerator -object GeMMStreamerParameters extends CommonParams { - - def temporalAddrGenUnitParams: TemporalAddrGenUnitParams = - TemporalAddrGenUnitParams( - loopDim = 3, - loopBoundWidth = 8, - addrWidth - ) - - def fifoReaderParams: Seq[FIFOParams] = Seq( - FIFOParams(512, 2), - FIFOParams(512, 2) - ) - - def fifoWriterParams: Seq[FIFOParams] = Seq(FIFOParams(2048, 2)) - - def dataReaderParams: Seq[DataMoverParams] = Seq( - DataMoverParams( - tcdmPortsNum = 8, - spatialBounds = Seq(8, 8), - spatialDim = 2, - elementWidth = 8, - fifoWidth = fifoReaderParams(0).width - ), - DataMoverParams( - tcdmPortsNum = 8, - spatialBounds = Seq(8, 8), - spatialDim = 2, - elementWidth = 8, - fifoWidth = fifoReaderParams(1).width - ) - ) - - def dataWriterParams: Seq[DataMoverParams] = Seq( - DataMoverParams( - tcdmPortsNum = 32, - spatialBounds = Seq(8, 8), - spatialDim = 2, - elementWidth = 32, - fifoWidth = fifoWriterParams(0).width - ) - ) - - def stationarity = Seq(0, 0, 1) - -} - -// streamer parameters for the Post-processing SIMD Accelerator -object PostProcessingStreamerParameters extends CommonParams { - - def temporalAddrGenUnitParams: TemporalAddrGenUnitParams = - TemporalAddrGenUnitParams( - loopDim = 2, - loopBoundWidth = 8, - addrWidth - ) - - def fifoReaderParams: Seq[FIFOParams] = Seq( - FIFOParams(2048, 2) - ) - - def fifoWriterParams: Seq[FIFOParams] = Seq(FIFOParams(512, 2)) - - def dataReaderParams: Seq[DataMoverParams] = Seq( - DataMoverParams( - tcdmPortsNum = 32, - spatialBounds = Seq(8, 8), - spatialDim = 2, - elementWidth = 32, - fifoWidth = fifoReaderParams(0).width - ) - ) - - def dataWriterParams: Seq[DataMoverParams] = Seq( - DataMoverParams( - tcdmPortsNum = 8, - spatialBounds = Seq(8, 8), - spatialDim = 2, - elementWidth = 8, - fifoWidth = fifoWriterParams(0).width - ) - ) - - def stationarity = Seq(0, 0) - -} - -object MacStreamerParameters extends CommonParams { - - def MacScalingFactor = 4 - - def temporalAddrGenUnitParams: TemporalAddrGenUnitParams = - TemporalAddrGenUnitParams( - loopDim = 1, - loopBoundWidth = 8, - addrWidth - ) - - def fifoReaderParams: Seq[FIFOParams] = Seq( - FIFOParams(64 * MacScalingFactor, 2), - FIFOParams(64 * MacScalingFactor, 2), - FIFOParams(64, 2) - ) - - def fifoWriterParams: Seq[FIFOParams] = Seq( - FIFOParams(64 * MacScalingFactor, 2) - ) - - def stationarity = Seq(0, 0, 1, 1) - - def dataReaderParams: Seq[DataMoverParams] = Seq( - DataMoverParams( - tcdmPortsNum = 1 * MacScalingFactor, - spatialBounds = Seq(2 * MacScalingFactor), - spatialDim = 1, - elementWidth = 32, - fifoWidth = fifoReaderParams(0).width - ), - DataMoverParams( - tcdmPortsNum = 1 * MacScalingFactor, - spatialBounds = Seq(2 * MacScalingFactor), - spatialDim = 1, - elementWidth = 32, - fifoWidth = fifoReaderParams(1).width - ), - DataMoverParams( - tcdmPortsNum = 1, - spatialBounds = Seq(2), - spatialDim = 1, - elementWidth = 32, - fifoWidth = fifoReaderParams(2).width - ) - ) - - def dataWriterParams: Seq[DataMoverParams] = Seq( - DataMoverParams( - tcdmPortsNum = 1 * MacScalingFactor, - spatialBounds = Seq(2 * MacScalingFactor), - spatialDim = 1, - elementWidth = 32, - fifoWidth = fifoWriterParams(0).width - ) - ) - -} From 68572c090ddca60a20b6a07de6f6a1cf45fae15e Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 11:02:44 +0200 Subject: [PATCH 04/19] formatting --- .../src/main/scala/snax/csr_manager/CsrManager.scala | 1 - hw/chisel/src/main/scala/snax/streamer/DataMover.scala | 2 +- .../src/main/scala/snax/streamer/DataReader.scala | 3 +-- .../src/main/scala/snax/streamer/DataWriter.scala | 3 +-- hw/chisel/src/main/scala/snax/streamer/FIFO.scala | 1 - .../src/main/scala/snax/streamer/Parameters.scala | 10 +++++----- .../main/scala/snax/streamer/SpatialAddrGenUnit.scala | 1 - hw/chisel/src/main/scala/snax/streamer/Streamer.scala | 4 +--- .../src/main/scala/snax/streamer/StreamerTop.scala | 4 +--- .../main/scala/snax/streamer/TemporalAddrGenUnit.scala | 1 - 10 files changed, 10 insertions(+), 20 deletions(-) diff --git a/hw/chisel/src/main/scala/snax/csr_manager/CsrManager.scala b/hw/chisel/src/main/scala/snax/csr_manager/CsrManager.scala index 5f5e0fee3..826286158 100644 --- a/hw/chisel/src/main/scala/snax/csr_manager/CsrManager.scala +++ b/hw/chisel/src/main/scala/snax/csr_manager/CsrManager.scala @@ -115,4 +115,3 @@ class CsrManager( io.csr_config_out.bits <> csr } - diff --git a/hw/chisel/src/main/scala/snax/streamer/DataMover.scala b/hw/chisel/src/main/scala/snax/streamer/DataMover.scala index d9ab326ea..04082a7f0 100644 --- a/hw/chisel/src/main/scala/snax/streamer/DataMover.scala +++ b/hw/chisel/src/main/scala/snax/streamer/DataMover.scala @@ -222,7 +222,7 @@ class DataMover( // classes which extend the DataMover module, but are just // set to 0 here for testing purposes. class DataMoverTester( - params: DataMoverParams, + params: DataMoverParams ) extends DataMover(params) { for (i <- 0 until params.tcdmPortsNum) { diff --git a/hw/chisel/src/main/scala/snax/streamer/DataReader.scala b/hw/chisel/src/main/scala/snax/streamer/DataReader.scala index 527515719..4e7751ca4 100644 --- a/hw/chisel/src/main/scala/snax/streamer/DataReader.scala +++ b/hw/chisel/src/main/scala/snax/streamer/DataReader.scala @@ -12,7 +12,7 @@ import chisel3.util._ * The parameter class contains all the parameters of a data mover module */ class DataReaderIO( - params: DataMoverParams, + params: DataMoverParams ) extends DataMoverIO(params) { // tcdm response @@ -135,4 +135,3 @@ class DataReader( } } - diff --git a/hw/chisel/src/main/scala/snax/streamer/DataWriter.scala b/hw/chisel/src/main/scala/snax/streamer/DataWriter.scala index c85f85508..ea4a91f31 100644 --- a/hw/chisel/src/main/scala/snax/streamer/DataWriter.scala +++ b/hw/chisel/src/main/scala/snax/streamer/DataWriter.scala @@ -11,7 +11,7 @@ import chisel3.util._ * The parameter class contains all the parameters of a data mover module */ class DataWriterIO( - params: DataMoverParams, + params: DataMoverParams ) extends DataMoverIO(params) { // valid data from the queue @@ -62,4 +62,3 @@ class DataWriter( io.data_fifo_i.ready := io.ptr_agu_i.ready } - diff --git a/hw/chisel/src/main/scala/snax/streamer/FIFO.scala b/hw/chisel/src/main/scala/snax/streamer/FIFO.scala index 701d46e1e..15bd0ed0a 100644 --- a/hw/chisel/src/main/scala/snax/streamer/FIFO.scala +++ b/hw/chisel/src/main/scala/snax/streamer/FIFO.scala @@ -32,4 +32,3 @@ class FIFO( } } - diff --git a/hw/chisel/src/main/scala/snax/streamer/Parameters.scala b/hw/chisel/src/main/scala/snax/streamer/Parameters.scala index 2ac413a74..ede35f485 100644 --- a/hw/chisel/src/main/scala/snax/streamer/Parameters.scala +++ b/hw/chisel/src/main/scala/snax/streamer/Parameters.scala @@ -28,7 +28,7 @@ trait CommonParams { case class TemporalAddrGenUnitParams( loopDim: Int, loopBoundWidth: Int, - addrWidth: Int, + addrWidth: Int ) /** This class represents all the parameters for the Spatial Address Generation @@ -43,7 +43,7 @@ case class TemporalAddrGenUnitParams( case class SpatialAddrGenUnitParams( loopDim: Int, loopBounds: Seq[Int], - addrWidth: Int, + addrWidth: Int ) /** This class represents all the parameters for the Data Mover (including Data @@ -67,7 +67,7 @@ case class DataMoverParams( spatialBounds: Seq[Int], spatialDim: Int, elementWidth: Int, - fifoWidth: Int, + fifoWidth: Int ) extends CommonParams /** FIFO parameters @@ -173,12 +173,12 @@ trait HasStreamerInferredParams extends HasStreamerCoreParams { * default value of these parameters is from the StreamerTestConstant object */ case class StreamerParams( - temporalAddrGenUnitParams: TemporalAddrGenUnitParams, + temporalAddrGenUnitParams: TemporalAddrGenUnitParams, stationarity: Seq[Int], dataReaderParams: Seq[DataMoverParams], dataWriterParams: Seq[DataMoverParams], fifoReaderParams: Seq[FIFOParams], fifoWriterParams: Seq[FIFOParams], - tagName: String, + tagName: String ) extends HasStreamerCoreParams with HasStreamerInferredParams diff --git a/hw/chisel/src/main/scala/snax/streamer/SpatialAddrGenUnit.scala b/hw/chisel/src/main/scala/snax/streamer/SpatialAddrGenUnit.scala index 0afd806cc..46495b870 100644 --- a/hw/chisel/src/main/scala/snax/streamer/SpatialAddrGenUnit.scala +++ b/hw/chisel/src/main/scala/snax/streamer/SpatialAddrGenUnit.scala @@ -157,4 +157,3 @@ class SpatialAddrGenUnit( ) } - diff --git a/hw/chisel/src/main/scala/snax/streamer/Streamer.scala b/hw/chisel/src/main/scala/snax/streamer/Streamer.scala index 327671b9b..f748b2c64 100644 --- a/hw/chisel/src/main/scala/snax/streamer/Streamer.scala +++ b/hw/chisel/src/main/scala/snax/streamer/Streamer.scala @@ -27,7 +27,7 @@ class DataFromAcceleratorX( // csr related io class StreamerCsrIO( - params: StreamerParams, + params: StreamerParams ) extends Bundle { // configurations interface for a new data operation @@ -372,5 +372,3 @@ class Streamer( } } - - diff --git a/hw/chisel/src/main/scala/snax/streamer/StreamerTop.scala b/hw/chisel/src/main/scala/snax/streamer/StreamerTop.scala index 272a57446..9602fbf89 100644 --- a/hw/chisel/src/main/scala/snax/streamer/StreamerTop.scala +++ b/hw/chisel/src/main/scala/snax/streamer/StreamerTop.scala @@ -34,7 +34,7 @@ class StreamerTopIO( * the parameters class instantiation for the streamer top module */ class StreamerTop( - params: StreamerParams, + params: StreamerParams ) extends Module with RequireAsyncReset { @@ -153,5 +153,3 @@ class StreamerTop( io.data <> streamer.io.data } - - diff --git a/hw/chisel/src/main/scala/snax/streamer/TemporalAddrGenUnit.scala b/hw/chisel/src/main/scala/snax/streamer/TemporalAddrGenUnit.scala index cc2989d82..c8d9db388 100644 --- a/hw/chisel/src/main/scala/snax/streamer/TemporalAddrGenUnit.scala +++ b/hw/chisel/src/main/scala/snax/streamer/TemporalAddrGenUnit.scala @@ -207,4 +207,3 @@ class TemporalAddrGenUnit( io.done := addr_gen_finish } - From a42e5c217d328d99d49f16678012173d387ee1df Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 11:47:43 +0200 Subject: [PATCH 05/19] cleaning up some test params --- .../main/scala/snax/streamer/Parameters.scala | 2 +- .../snax/streamer/StreamerTestParameter.scala | 38 ++++--------------- .../test/scala/snax/streamer/FIFOTest.scala | 4 +- 3 files changed, 11 insertions(+), 33 deletions(-) diff --git a/hw/chisel/src/main/scala/snax/streamer/Parameters.scala b/hw/chisel/src/main/scala/snax/streamer/Parameters.scala index ede35f485..18422ad90 100644 --- a/hw/chisel/src/main/scala/snax/streamer/Parameters.scala +++ b/hw/chisel/src/main/scala/snax/streamer/Parameters.scala @@ -179,6 +179,6 @@ case class StreamerParams( dataWriterParams: Seq[DataMoverParams], fifoReaderParams: Seq[FIFOParams], fifoWriterParams: Seq[FIFOParams], - tagName: String + tagName: String = "" ) extends HasStreamerCoreParams with HasStreamerInferredParams diff --git a/hw/chisel/src/main/scala/snax/streamer/StreamerTestParameter.scala b/hw/chisel/src/main/scala/snax/streamer/StreamerTestParameter.scala index aa3c9af77..b1369d4ec 100644 --- a/hw/chisel/src/main/scala/snax/streamer/StreamerTestParameter.scala +++ b/hw/chisel/src/main/scala/snax/streamer/StreamerTestParameter.scala @@ -5,31 +5,6 @@ import chisel3.util._ /* the meaning of these testing parameters can be found at Parameter.scala */ -object TemporalAddrGenUnitTestParameters { - def loopDim = 3 - def loopBoundWidth = 8 - def addrWidth = 32 - -} - -object SpatialAddrGenUnitTestParameters { - def loopBounds = Seq(8, 8) - def loopDim = loopBounds.length - def addrWidth = 32 -} - -object DataMoverTestParameters { - def tcdmPortsNum = 8 - def tcdmDataWidth = 64 - def spatialBounds = Seq(8, 8) - def addrWidth = 32 - def fifoWidth = 512 - def elementWidth = 8 - - def spatialDim = spatialBounds.length - -} - object StreamerTestConstant extends CommonParams { def MacScalingFactor = 4 @@ -105,13 +80,13 @@ object TestParameters { loopDim = 3, loopBoundWidth = 8, addrWidth = 32 - ) + ) val spatialAddrGenUnit = SpatialAddrGenUnitParams ( loopBounds = Seq(8, 8), loopDim = 2, addrWidth = 32 - ) + ) val dataMover = DataMoverParams ( tcdmPortsNum = 8, @@ -120,9 +95,10 @@ object TestParameters { elementWidth = 8, spatialDim = 2, ) -} -object FIFOTestParameters { - def fifoWidth = 512 - def fifoDepth = 4 + val fifo = FIFOParams ( + width = 512, + depth = 4 + ) } + diff --git a/hw/chisel/src/test/scala/snax/streamer/FIFOTest.scala b/hw/chisel/src/test/scala/snax/streamer/FIFOTest.scala index 18b2ffe4d..1478a705a 100644 --- a/hw/chisel/src/test/scala/snax/streamer/FIFOTest.scala +++ b/hw/chisel/src/test/scala/snax/streamer/FIFOTest.scala @@ -9,7 +9,9 @@ import org.scalatest.Tag class FIFOTest extends AnyFlatSpec with ChiselScalatestTester with Matchers { "DUT" should "pass" in { - test(new FIFO(width=FIFOTestParameters.fifoWidth, depth=FIFOTestParameters.fifoDepth)) + test(new FIFO( + width=TestParameters.fifo.width, + depth=TestParameters.fifo.depth)) .withAnnotations( Seq(WriteVcdAnnotation) ) { dut => From f379d608914ee761e122af9a8556e1cd631585ed Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 11:48:50 +0200 Subject: [PATCH 06/19] resolve trailing space --- .github/workflows/scala-unit-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scala-unit-test.yml b/.github/workflows/scala-unit-test.yml index f1f1a1d0c..0b334ef54 100644 --- a/.github/workflows/scala-unit-test.yml +++ b/.github/workflows/scala-unit-test.yml @@ -5,7 +5,7 @@ # Xiaoling Yi # Run Scala Unit Test -name: Unit Test +name: Run Scala Unit Test on: push: branches: ["main"] @@ -20,6 +20,6 @@ jobs: steps: - uses: actions/checkout@v2 - name: Run the unit tests - working-directory: hw/chisel + working-directory: hw/chisel run: | sbt test From 407b5577de3a716ad080114c19e46f98b0f7abe7 Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 13:43:19 +0200 Subject: [PATCH 07/19] add chisel .gitignore --- hw/chisel/.gitignore | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 hw/chisel/.gitignore diff --git a/hw/chisel/.gitignore b/hw/chisel/.gitignore new file mode 100644 index 000000000..ab4110b20 --- /dev/null +++ b/hw/chisel/.gitignore @@ -0,0 +1,5 @@ +generated +project +target +test_run_dir +.bsp From e12104fd4660e6a67511e458d5406afcb448fb26 Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 13:47:56 +0200 Subject: [PATCH 08/19] add verilog generator scripts to test --- .../snax/csr_manager/CsrManagerGenerate.scala | 16 ++++++++++++++++ .../snax/streamer/StreamerTopGenerate.scala | 15 +++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/hw/chisel/src/test/scala/snax/csr_manager/CsrManagerGenerate.scala b/hw/chisel/src/test/scala/snax/csr_manager/CsrManagerGenerate.scala index e69de29bb..464d50b1e 100644 --- a/hw/chisel/src/test/scala/snax/csr_manager/CsrManagerGenerate.scala +++ b/hw/chisel/src/test/scala/snax/csr_manager/CsrManagerGenerate.scala @@ -0,0 +1,16 @@ +package snax.csr_manager + +import chisel3._ +import org.scalatest.flatspec.AnyFlatSpec +import chiseltest._ + +class CsrManagerTopGenerate +extends AnyFlatSpec { + + emitVerilog( + new CsrManager(10, 32), + Array("--target-dir", "generated/") + ) + +} + diff --git a/hw/chisel/src/test/scala/snax/streamer/StreamerTopGenerate.scala b/hw/chisel/src/test/scala/snax/streamer/StreamerTopGenerate.scala index 8b1378917..f45778bd6 100644 --- a/hw/chisel/src/test/scala/snax/streamer/StreamerTopGenerate.scala +++ b/hw/chisel/src/test/scala/snax/streamer/StreamerTopGenerate.scala @@ -1 +1,16 @@ +package snax.streamer + +import chisel3._ +import org.scalatest.flatspec.AnyFlatSpec +import chiseltest._ + +class StreamerTopGenerate +extends AnyFlatSpec { + + emitVerilog( + new StreamerTop(TestParameters.streamer), + Array("--target-dir", "generated/") + ) + +} From 0aabecce4f2b638fb5e4c2d2a944909adbe487c6 Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 15:09:21 +0200 Subject: [PATCH 09/19] use TestParameters --- .../src/test/scala/snax/streamer/StreamerTopTest.scala | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/hw/chisel/src/test/scala/snax/streamer/StreamerTopTest.scala b/hw/chisel/src/test/scala/snax/streamer/StreamerTopTest.scala index 0652a7986..4f2f3bb2f 100644 --- a/hw/chisel/src/test/scala/snax/streamer/StreamerTopTest.scala +++ b/hw/chisel/src/test/scala/snax/streamer/StreamerTopTest.scala @@ -13,15 +13,7 @@ class StreamerTopTest with ChiselScalatestTester with Matchers { "DUT" should "pass" in { - test(new StreamerTop(new StreamerParams( - temporalAddrGenUnitParams = StreamerTestConstant.temporalAddrGenUnitParams, - stationarity = StreamerTestConstant.stationarity, - dataReaderParams = StreamerTestConstant.dataReaderParams, - dataWriterParams = StreamerTestConstant.dataWriterParams, - fifoReaderParams = StreamerTestConstant.fifoReaderParams, - fifoWriterParams = StreamerTestConstant.fifoWriterParams, - tagName = "abc", - ))) + test(new StreamerTop(TestParameters.streamer)) .withAnnotations( Seq(WriteVcdAnnotation) ) { dut => From e10f33ed21b8351187818c56284677b5c30dc44a Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 15:13:06 +0200 Subject: [PATCH 10/19] move test parameters back to /tests --- .../scala/snax/csr_manager/CsrManagerTestParameters.scala | 0 .../scala/snax/csr_manager}/StreamerTestParameter.scala | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename hw/chisel/src/{main => test}/scala/snax/csr_manager/CsrManagerTestParameters.scala (100%) rename hw/chisel/src/{main/scala/snax/streamer => test/scala/snax/csr_manager}/StreamerTestParameter.scala (100%) diff --git a/hw/chisel/src/main/scala/snax/csr_manager/CsrManagerTestParameters.scala b/hw/chisel/src/test/scala/snax/csr_manager/CsrManagerTestParameters.scala similarity index 100% rename from hw/chisel/src/main/scala/snax/csr_manager/CsrManagerTestParameters.scala rename to hw/chisel/src/test/scala/snax/csr_manager/CsrManagerTestParameters.scala diff --git a/hw/chisel/src/main/scala/snax/streamer/StreamerTestParameter.scala b/hw/chisel/src/test/scala/snax/csr_manager/StreamerTestParameter.scala similarity index 100% rename from hw/chisel/src/main/scala/snax/streamer/StreamerTestParameter.scala rename to hw/chisel/src/test/scala/snax/csr_manager/StreamerTestParameter.scala From c1f3c715d519153daa49d277d0a74ce1c7f3c5d8 Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 15:46:19 +0200 Subject: [PATCH 11/19] add streamer documentation --- hw/chisel/doc/streamer.MD | 231 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 hw/chisel/doc/streamer.MD diff --git a/hw/chisel/doc/streamer.MD b/hw/chisel/doc/streamer.MD new file mode 100644 index 000000000..f7f78e669 --- /dev/null +++ b/hw/chisel/doc/streamer.MD @@ -0,0 +1,231 @@ +# Flexible Streamer Generator for SNAX + +Every accelerator has a specific layout for data that comes in and goes out, but the data layout in memory may not be in the same format. This causes data layout management overhead on both the accelerator side and the compiler side. The Flexible Streamer Generator is a tool to generate _Streamers_ for an accelerator. A Streamer is a reusable hardware block designed to handle the memory accesses, decoupling the accelerator from the actual memory system, and simplifying the interface to the accelerator. The streamer's accelerator and data interfaces follow the valid-ready handshake. On top of this, the pre-fetch mechanism inside the Streamer also helps to relieve data contention in the memory, maximizing an accelerator's data-compute bandwidth. + +The Streamer has a compatible interface with the [SNAX core](https://github.com/KULeuven-micas/snitch_cluster) and can be integrated into it as a data streaming engine. + +It is written in CHISEL 5.0.0 and is intended to be connected to the SNAX accelerator RISC-V manager core through a SystemVerilog wrapper. + +Thanks to the strong expression power of Chisel, the Flexible Streamer Generator has the capability of dealing with any number of temporal loops and any number of parallel loops for data address generation. More importantly, the Streamer generator is accelerator agnostic, highly flexible, and parameterizable which means it is suitable for a wide range of accelerators employing a [tiled-strided-layout](https://github.com/KULeuven-MICAS/snax-mlir/tree/main/compiler/ir/tsl). We have generated Streamers for three accelerators, including the SNAX-GEMM, SNAX-PostProcessing-SIMD, and MAC Engine. + +## Microarchitecture +The microarchitecture of the Flexible Streamer Generator is shown below. + +

+ +

+ +The main module of the Streamer is the data mover, including the data reader (reads data from the real memory system and acts as the producer for the accelerator) and data writer (writes data to the real memory system and acts as the consumer for the accelerator). Each data mover has its own address generation unit and works independently so that each data mover can do the data transfer as quickly as possible. + +The data reader gives read requests to the memory system (the address, and read signal, etc.) and gets the response. When all the responses of one transaction are obtained, it pushes the valid data into a FIFO for the accelerator to consume. If the accelerator is consumed successfully, the FIFO will pop the data. The data reader will keep getting new data from the real memory system (pre-fetch) until the FIFO is full or all the input data has been fetched. + +The data writer obtains valid data from the FIFO output (written by the accelerator) and sends write request to the memory system. When there is a valid output from the accelerator (and the FIFO is not full), the valid output will be pushed to the FIFO. When the FIFO is not empty, the data writer will keep sending write requests. When one write transaction is successful, the data will be pop from the FIFO. + +The StreamerTop module has a csrManage to manage the CSR read/write operations from the SNAX core. The Streamer has its own CSRs to store the configuration for the address generation and transaction number etc. The configuration, such as the temporal loop bound and strides, is written in the CSRs via a CsrManager when all the CSR configurations are valid. When doing the current transaction, the configuration for the next transaction operation can already be written into the CsrManager. When the current transaction finishes, the SNAX core can send the configuration valid signal then the CSR value in the CsrManager will be loaded in to the Streamer. + +## Parameters +`Parameters.scala` contains the list of all the parameters for the Streamer. Each hardware module has its parameter class. The table below lists the descriptions of all the parameter classes and the parameter formats for the Streamer. + +|Class| Parameters | Description | +| - | - | - | +|CommonParams | addrWidth | The bit width of the memory system address. | +| | tcdmDataWidth | Data width for each TCDM* port. | +|TemporalAddrGenUnitParams | loopDim | The dimension of the temporal loops = the number of for loops. | +| | loopBoundWidth | The bit width of the loop bounds. | +| | addrWidth | The bit width of the memory system address. | +|SpatialAddrGenUnitParams | loopDim | The number of nested spatial(parfor) loops. | +| | loopBounds | The bounds of each spatial(parfor) loop dimension. | +| | addrWidth | The bit width of the memory system address. | +| DataMoverParams | tcdmPortsNum | The number of TCDM ports connected to each data mover. | +| | spatialBounds | Spatial unrolling factors (your parfor) for each data mover. | +| | spatialDim | The dimension of spatial unrolling factors (your parfor) for each data mover. | +| | elementWidth | Single data element width for each data mover, useful for generating spatial addresses. | +| | fifoWidth |FIFO width. | +| StreamerParams | temporalAddrGenUnitParams | The parameters for the temporal address generation unit. Even though there are independent temporal address generation unit for each data mover, each data mover actually share the same temporal address generation unit parameters. | +| | stationarity | The parameters for stationarity for each data mover. If the stationarity bit is set, the innermost loop for that data mover is set to 1.| +| | dataReaderParams | A sequence of the parameters for dataReader. Each dataReader parameter can be different. The number of the parameters can also be any, meaning there is no constraint on how many the dataReader should be. | +| | dataWriterParams | Similar as dataReaderParams. A sequence of the parameters for dataWriter. Each dataWriter parameter can be different. The number of the parameters can also be any, meaning there is no constraint on how many the dataWriter should be. | +| | fifoReaderParams | A sequence of the parameters for the FIFOs for dataReaders. The sequence length should matches the length of dataReaderParams.| +| | fifoWriterParams | A sequence of the parameters for the FIFOs for dataWriters. The sequence length should matches the length of dataWriterParams.| + +*TCDM is the memory that the Streamer interacts to. + +### Instantiate Streamers + +A custom streamer can be generated by creating specific parameters according to the specification in `streamer/Params.scala`, and can then be used directly in Chisel. If you are using the SNAX flow instead, the paramers defined in `cfg/configuration.hjson` is used to generate these parameters automatically, and thus need not be defined manually. + +#### Example: Streamer parameter configuration for a simple MAC Engine +```scala +object MacStreamerParameters extends CommonParams { + + def MacScalingFactor = 4 + + def temporalAddrGenUnitParams: TemporalAddrGenUnitParams = + TemporalAddrGenUnitParams( + loopDim = 1, + loopBoundWidth = 8, + addrWidth + ) + + def fifoReaderParams: Seq[FIFOParams] = Seq( + FIFOParams(64 * MacScalingFactor, 2), + FIFOParams(64 * MacScalingFactor, 2), + FIFOParams(64, 2) + ) + + def fifoWriterParams: Seq[FIFOParams] = Seq( + FIFOParams(64 * MacScalingFactor, 2) + ) + + def stationarity = Seq(0, 0, 1, 1) + + def dataReaderParams: Seq[DataMoverParams] = Seq( + DataMoverParams( + tcdmPortsNum = 1 * MacScalingFactor, + spatialBounds = Seq(2 * MacScalingFactor), + spatialDim = 1, + elementWidth = 32, + fifoWidth = fifoReaderParams(0).width + ), + DataMoverParams( + tcdmPortsNum = 1 * MacScalingFactor, + spatialBounds = Seq(2 * MacScalingFactor), + spatialDim = 1, + elementWidth = 32, + fifoWidth = fifoReaderParams(1).width + ), + DataMoverParams( + tcdmPortsNum = 1, + spatialBounds = Seq(2), + spatialDim = 1, + elementWidth = 32, + fifoWidth = fifoReaderParams(2).width + ) + ) + + def dataWriterParams: Seq[DataMoverParams] = Seq( + DataMoverParams( + tcdmPortsNum = 1 * MacScalingFactor, + spatialBounds = Seq(2 * MacScalingFactor), + spatialDim = 1, + elementWidth = 32, + fifoWidth = fifoWriterParams(0).width + ) + ) + +} +``` +## Address generation description + +The access pattern for the Streamer is represented by a set of nested for loops. Every for loop can specify a _stride_ which we use to increment a base pointer. On top of this, some of the for loops can be _spatially unrolled_, to enable parallel data accesses by the accelerator. This splits address generation in two parts, the temporal address generation and spatial address generation. The temporal address is based on the temporal loop counters and the temporal strides configuration. The spatial address is based on the spatial unrolling factor of the accelerator and the spatial strides configuration. The spatial address generation unit will generate a unique address for each data element which is accessed in parallel. As there may be multiple data elements per memory word, these addresses are then merged for proper data alignment with the memory bank width. + +We formulate the address generation formula below: +``` +for(;;temporalbound_n-1) + for(;;temporalbound_n-2) + … + for(;;temporalbound_0) + parfor(;;spatialbound_m-1) + parfor(;;spatialbound_m-2) + … + parfor(;;spatialbound_0) + temporal_address = (temporal_unrolling_loop_counters.zip(tempStride).map { case (a, b) => a * b }).reduce(_ +& _) + spatial_address = (spatial_unrolling_loop_counters.zip(spatialStride).map { case (a, b) => a * b }).reduce(_ +& _) + add_o = base_ptr + temporal_address + spatial_address +``` + +Take a SIMD accelerator as an example (1 temporal loop and 1 spatial loop), Vu = 8, the address generation is: +``` +for (ti = 0 to VEC_LEN/Vu – 1): + parfor (si = 0 to Vu -1): + addr_o[Vu-1:0] = base_ptr + ti*(tempStride) +  [Vu-1:0]*(spatialStride) +``` +Which actually translates to: +``` +addr_o[0] = base_ptr + ti*(tempStride) +  [0]*(spatialStride) +addr_o[1] = base_ptr + ti*(tempStride) +  [1]*(spatialStride) +addr_o[2] = base_ptr + ti*(tempStride) +  [2]*(spatialStride) +addr_o[3] = base_ptr + ti*(tempStride) +  [3]*(spatialStride) +addr_o[4] = base_ptr + ti*(tempStride) +  [4]*(spatialStride) +addr_o[5] = base_ptr + ti*(tempStride) +  [5]*(spatialStride) +addr_o[6] = base_ptr + ti*(tempStride) +  [6]*(spatialStride) +addr_o[7] = base_ptr + ti*(tempStride) +  [7]*(spatialStride) +``` +Take GEMM Accelerator input data A as an example(3 temporal loop and 2 spatial loop), the address generation is: + +``` +for (m1 = 0 to M’/Mu-1) + for (n1 = 0 to N’/Nu-1) + for (k1 = 0 to K’/Ku-1) + parfor(0 to Mu) + parfor(0 to Ku) + temporal_address = m1*t_str_m1 + n1*t_str_n1 + k1*t_str_k1 + spatial_address = [Mu-1:0]*s_str_m + [Ku-1:0]*str_str_k + addr_o[Mu-1:0][Ku-1:0] = ptr_o + temporal_address + spatial_address + +``` +where `t_str_*` - are temporal strides and `s_str_*` - are spatial strides. + +Which translates to: +``` +addr_o[0][0] = ptr_o + m1*t_str_m1 + n1*t_str_n1 + k1*t_str_k1 + [0]*s_str_m + [0]*str_str_k +addr_o[0][1] = ptr_o + m1*t_str_m1 + n1*t_str_n1 + k1*t_str_k1 + [0]*s_str_m + [1]*str_str_k +addr_o[0][2] = ptr_o + m1*t_str_m1 + n1*t_str_n1 + k1*t_str_k1 + [0]*s_str_m + [2]*str_str_k +… +addr_o[m][k] = ptr_o + m1*t_str_m1 + n1*t_str_n1 + k1*t_str_k1 + [m]*s_str_m + [k]*str_str_k +… +addr_o[Mu-1][Ku-3] = ptr_o + m1*t_str_m1 + n1*t_str_n1 + k1*t_str_k1 + [Mu-1]*s_str_m + [Ku-3]*str_str_k +addr_o[Mu-1][Ku-2] = ptr_o + m1*t_str_m1 + n1*t_str_n1 + k1*t_str_k1 + [Mu-1]*s_str_m + [Ku-2]*str_str_k +addr_o[Mu-1][Ku-1] = ptr_o + m1*t_str_m1 + n1*t_str_n1 + k1*t_str_k1 + [Mu-1]*s_str_m + [Ku-1]*str_str_k +``` + + +## IO ports +The input and output ports of the Streamer are shown in the table below. + +The Streamer uses a simplified CSR request/response interface for CSR write/read operation. A more detailed description of the CSR operation interface can be found [here](https://kuleuven-micas.github.io/snitch_cluster/rm/snax_cluster.html). + +The Streamer uses a simplified TCDM request/response interface to read and write data from/to the TCDM. A more detailed description of the TCDM request/response interface can be found [here](https://kuleuven-micas.github.io/snitch_cluster/rm/snax_cluster.html). + +The Streamer uses the Decoupled interface for accelerator input and output data. A more detailed description of the Decoupled interface can be found [here](https://www.chisel-lang.org/docs/explanations/interfaces-and-connections#the-standard-ready-valid-interface-readyvalidio--decoupled). + +The simplified interface for the CSR and TCDM request/response contains the core signals and can be found at `TypeDefine.scala`. The complete signals for the CSR request/response interface and TCDM request/response interface will be added in the SystemVerilog wrapper. + +|Signal bundle| Signals | Signal name in generated SV | Width | Dir | Description | +| - | - | - | - | - | - | +| csr.req | data | io_csr_req_bits_data | 32| In| The write data from CSR request. | +| | addr | io_csr_req_bits_addr | 32| In| The address indicates which CSR to be wrote or read. | +| | write | io_csr_req_bits_write | 1| In| The signal indicates this request is for CSR write or read. | +| | valid | io_csr_req_valid | 1 | In| The signal indicates if this request is valid. | +| | ready | io_csr_req_ready | 1 | Out| The signal indicates if the accelerator is ready for this CSR operation.| +| csr.rsp | data | io_csr_rsp_bits_data | 32| Out| The response data for CSR read operation. | +| | valid | io_csr_rsp_valid | 1 | Out| The signal indicates if this response is valid. | +| | ready | io_csr_rsp_ready | 1 | In| The signal indicates if the SNAX core is ready for this CSR response. | +| tcdm_req | data | io_data_tcdm_req_0_bits_data | 64| Out| The data from TCDM request. This data is only valuable when it is a write request. | +| tcdm_req | addr | io_data_tcdm_req_0_bits_addr | 32| Out| The address from TCDM request. | +| tcdm_req | write | io_data_tcdm_req_0_bits_write | 1| Out| The signal indicates this request is for CSR write or read. | +| tcdm_req | valid | io_data_tcdm_req_0_valid | 1| Out| The signal indicates if this request is valid. | +| tcdm_req | ready | io_data_tcdm_req_0_ready | 1| Int| The signal indicates if the TCDM is ready for this CSR request. | +| | . | . | . | . | There can be a large number of tcdm_req ports depending on the spatial unrolling factors for the data readers and the data writers. tcdm_req ports for readers have lower index number. A detailed mapping for the tcdm_req ports and the data mover ports can be found at `Streamer.scala` line 269-311.| +| tcdm_rsp | data | io_data_tcdm_rsp_0_bits_data | 64| In| The response data from the read request. | +| tcdm_rsp | valid | io_data_tcdm_rsp_0_valid | 1| In| The signal indicates if this response is valid. | +| | . | . | . | . | The tcdm_rsp ports number is the same as tcdm_req. | +| streamer2accelerator | data | io_data_streamer2accelerator_data_0_bits | First read FIFO width| Out | The data for the acceleratorX input. | +| streamer2accelerator | valid | io_data_streamer2accelerator_data_0_valid | 1| Out| The signal indicates if this data is valid. | +| streamer2accelerator | ready | io_data_streamer2accelerator_data_0_ready | 1| In| The signal indicates if the acceleratorX is ready for this data (has used this data already). | +| | . | . | . | . | The streamer2accelerator ports number is the same as data reader number. The index 0 corresponds to the first input data and 2 for second input data and so on. | +| accelerator2streamer | data | io_data_accelerator2streamer_data_0_bits | First write FIFO width| In| The data from the acceleratorX output. | +| accelerator2streamer | valid | io_data_accelerator2streamer_data_0_valid | 1| In| The signal indicates if this data is valid. | +| accelerator2streamer | ready | io_data_accelerator2streamer_data_0_ready | 1| Out| The signal indicates if the data writer is ready for taking in this data (not full). | +| | . | . | . | . | The accelerator2streamer ports number is the same as data writer number. The index 0 corresponds to the first output data and 2 for second output data (if any) and so on.| +| | | | | | | | + +### CSR definition +The offset below is defined by the SNAX core. A more detailed explanation of what are these configurations can be found at `StreamerTop.scala`. + +| Address | CSR name | Notes | +|---------|--------------------------|-------------------------------------| +| offset + [0..temporalDim - 1] | temporalLoopBoundCSRs | temporal loop bound for each temporal dimension. | +| offset + temporalDim + [0..temdataMoverNum * temporalDimporalDim - 1] | temporalLoopSrtidesCSRs | temporal loop strides for each temporal dimension and for each data mover. | +| offset + temporalDim + dataMoverNum * temporalDim + [0..spatialDim.sum - 1] | spatialLoopSrtidesCSRs | spatial loop strides for each data mover and for corresponding spatial dimension. The spatial dimension for each data mover can be different. It depends on the accelerator. | +| offset + temporalDim + dataMoverNum * temporalDim + spatialDim.sum + [0..dataMoverNum - 1] | basePtrCSRs | base pointers for each data mover. | From 868a8187ee9614f3e4c58763697ec6df9f476b3c Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 15:47:57 +0200 Subject: [PATCH 12/19] rename documentation file --- hw/chisel/README.md | 0 hw/chisel/doc/{streamer.MD => streamer.md} | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 hw/chisel/README.md rename hw/chisel/doc/{streamer.MD => streamer.md} (100%) diff --git a/hw/chisel/README.md b/hw/chisel/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/hw/chisel/doc/streamer.MD b/hw/chisel/doc/streamer.md similarity index 100% rename from hw/chisel/doc/streamer.MD rename to hw/chisel/doc/streamer.md From 67602b5bdc934081579ed9ad2e0f362a94ff2eac Mon Sep 17 00:00:00 2001 From: Joren Dumoulin Date: Wed, 8 May 2024 15:51:15 +0200 Subject: [PATCH 13/19] add chisel readme --- hw/chisel/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/chisel/README.md b/hw/chisel/README.md index e69de29bb..44d4000f9 100644 --- a/hw/chisel/README.md +++ b/hw/chisel/README.md @@ -0,0 +1,8 @@ +# SNAX Framework Chisel components +This directory contains SNAX framework components developed in Chisel. You can find documentation for these modules here: + +### Streamer +[documentation](doc/streamer.md) + +### CSR Manager +TODO From 1513480aed21dedbe0c9080cf150d78b9c00e07b Mon Sep 17 00:00:00 2001 From: Joren Dumoulin Date: Wed, 8 May 2024 19:52:14 +0200 Subject: [PATCH 14/19] add documentation image --- hw/chisel/doc/microarch.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 hw/chisel/doc/microarch.svg diff --git a/hw/chisel/doc/microarch.svg b/hw/chisel/doc/microarch.svg new file mode 100644 index 000000000..f8fd39c7e --- /dev/null +++ b/hw/chisel/doc/microarch.svg @@ -0,0 +1 @@ +
TCDM
TCDM
snitch
snitch
Accelerator X
Accelerator X
Steamers
Steamers
fifo
fifo
decoupled interface
data,ready,valid
decoupled interface...
tcdm_req/rsp
read
tcdm_req/rsp...
config loop bound and strides
config loop bound and strides
config operation
config operation
tcdm_req/rsp
write
tcdm_req/rsp...
csrManager
csrManager
data read mover
data read...
fifo
fifo
fifo
fifo
addr
addr
addr
addr
tcdm_read_req
tcdm_read_req
tcdm_write_req
tcdm_write_req
write data in
write data...
read data out
read data...
write data in
write data...
read data out
read data...
tcdm_rsp
tcdm_rsp
ready
ready
valid
valid
decoupled interface
decoupled...
decoupled interface
decoupled...
decoupled interface
decoupled...
AGU
AGU
fifo
fifo
data read mover
data read...
AGU
AGU
fifo
fifo
data write mover
data write...
AGU
AGU
spatrial addr gen
spatrial a...
spatrial addr gen
spatrial a...
read mode data mover
read mode data mov...
write mode data mover
write mode data...
req
rsp
req...
StreamerTop
StreamerTop
Text is not SVG - cannot display
\ No newline at end of file From 0cd1956c9f97e34b827acfe5e85f1775eed5349e Mon Sep 17 00:00:00 2001 From: Joren Dumoulin Date: Wed, 8 May 2024 19:53:05 +0200 Subject: [PATCH 15/19] update image path --- hw/chisel/doc/streamer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/chisel/doc/streamer.md b/hw/chisel/doc/streamer.md index f7f78e669..bb1db3d2d 100644 --- a/hw/chisel/doc/streamer.md +++ b/hw/chisel/doc/streamer.md @@ -12,7 +12,7 @@ Thanks to the strong expression power of Chisel, the Flexible Streamer Generator The microarchitecture of the Flexible Streamer Generator is shown below.

- +

The main module of the Streamer is the data mover, including the data reader (reads data from the real memory system and acts as the producer for the accelerator) and data writer (writes data to the real memory system and acts as the consumer for the accelerator). Each data mover has its own address generation unit and works independently so that each data mover can do the data transfer as quickly as possible. From 11d3da5bb93151f8111e560cb7c57286d4b6e86d Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Wed, 8 May 2024 19:50:48 +0200 Subject: [PATCH 16/19] address comments --- hw/chisel/.gitignore | 4 +++- hw/chisel/doc/streamer.md | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/chisel/.gitignore b/hw/chisel/.gitignore index ab4110b20..e4f3f71dd 100644 --- a/hw/chisel/.gitignore +++ b/hw/chisel/.gitignore @@ -1,5 +1,7 @@ generated -project +project/* +!project/plugins.sbt +!project/build.properties target test_run_dir .bsp diff --git a/hw/chisel/doc/streamer.md b/hw/chisel/doc/streamer.md index bb1db3d2d..55c4b4b43 100644 --- a/hw/chisel/doc/streamer.md +++ b/hw/chisel/doc/streamer.md @@ -206,7 +206,7 @@ The simplified interface for the CSR and TCDM request/response contains the core | tcdm_req | write | io_data_tcdm_req_0_bits_write | 1| Out| The signal indicates this request is for CSR write or read. | | tcdm_req | valid | io_data_tcdm_req_0_valid | 1| Out| The signal indicates if this request is valid. | | tcdm_req | ready | io_data_tcdm_req_0_ready | 1| Int| The signal indicates if the TCDM is ready for this CSR request. | -| | . | . | . | . | There can be a large number of tcdm_req ports depending on the spatial unrolling factors for the data readers and the data writers. tcdm_req ports for readers have lower index number. A detailed mapping for the tcdm_req ports and the data mover ports can be found at `Streamer.scala` line 269-311.| +| | . | . | . | . | There can be a large number of tcdm_req ports depending on the spatial unrolling factors for the data readers and the data writers. tcdm_req ports for readers have lower index number. A detailed mapping for the tcdm_req ports and the data mover ports can be found at `Streamer.scala`.| | tcdm_rsp | data | io_data_tcdm_rsp_0_bits_data | 64| In| The response data from the read request. | | tcdm_rsp | valid | io_data_tcdm_rsp_0_valid | 1| In| The signal indicates if this response is valid. | | | . | . | . | . | The tcdm_rsp ports number is the same as tcdm_req. | @@ -229,3 +229,4 @@ The offset below is defined by the SNAX core. A more detailed explanation of wha | offset + temporalDim + [0..temdataMoverNum * temporalDimporalDim - 1] | temporalLoopSrtidesCSRs | temporal loop strides for each temporal dimension and for each data mover. | | offset + temporalDim + dataMoverNum * temporalDim + [0..spatialDim.sum - 1] | spatialLoopSrtidesCSRs | spatial loop strides for each data mover and for corresponding spatial dimension. The spatial dimension for each data mover can be different. It depends on the accelerator. | | offset + temporalDim + dataMoverNum * temporalDim + spatialDim.sum + [0..dataMoverNum - 1] | basePtrCSRs | base pointers for each data mover. | +| offset + temporalDim + dataMoverNum * temporalDim + spatialDim.sum + dataMoverNum + 1| statusCSR | Performance counter for the busy state of the streamer module From 3180d7239ee41f2a6080c2498ee752aa44e36c83 Mon Sep 17 00:00:00 2001 From: Joren Dumoulin Date: Fri, 10 May 2024 08:53:39 +0200 Subject: [PATCH 17/19] update streamer.md image --- hw/chisel/doc/streamer.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/hw/chisel/doc/streamer.md b/hw/chisel/doc/streamer.md index 55c4b4b43..f372ee6f6 100644 --- a/hw/chisel/doc/streamer.md +++ b/hw/chisel/doc/streamer.md @@ -11,9 +11,7 @@ Thanks to the strong expression power of Chisel, the Flexible Streamer Generator ## Microarchitecture The microarchitecture of the Flexible Streamer Generator is shown below. -

- -

+![image](https://github.com/KULeuven-MICAS/snitch_cluster/assets/47864363/b499c7be-f897-462d-a662-1a0dd18d9c3f) The main module of the Streamer is the data mover, including the data reader (reads data from the real memory system and acts as the producer for the accelerator) and data writer (writes data to the real memory system and acts as the consumer for the accelerator). Each data mover has its own address generation unit and works independently so that each data mover can do the data transfer as quickly as possible. From c054ee8ec144f77981c1b24ced6954878415966e Mon Sep 17 00:00:00 2001 From: Joren Dumoulin Date: Fri, 10 May 2024 08:53:52 +0200 Subject: [PATCH 18/19] Delete hw/chisel/doc/microarch.svg --- hw/chisel/doc/microarch.svg | 1 - 1 file changed, 1 deletion(-) delete mode 100644 hw/chisel/doc/microarch.svg diff --git a/hw/chisel/doc/microarch.svg b/hw/chisel/doc/microarch.svg deleted file mode 100644 index f8fd39c7e..000000000 --- a/hw/chisel/doc/microarch.svg +++ /dev/null @@ -1 +0,0 @@ -
TCDM
TCDM
snitch
snitch
Accelerator X
Accelerator X
Steamers
Steamers
fifo
fifo
decoupled interface
data,ready,valid
decoupled interface...
tcdm_req/rsp
read
tcdm_req/rsp...
config loop bound and strides
config loop bound and strides
config operation
config operation
tcdm_req/rsp
write
tcdm_req/rsp...
csrManager
csrManager
data read mover
data read...
fifo
fifo
fifo
fifo
addr
addr
addr
addr
tcdm_read_req
tcdm_read_req
tcdm_write_req
tcdm_write_req
write data in
write data...
read data out
read data...
write data in
write data...
read data out
read data...
tcdm_rsp
tcdm_rsp
ready
ready
valid
valid
decoupled interface
decoupled...
decoupled interface
decoupled...
decoupled interface
decoupled...
AGU
AGU
fifo
fifo
data read mover
data read...
AGU
AGU
fifo
fifo
data write mover
data write...
AGU
AGU
spatrial addr gen
spatrial a...
spatrial addr gen
spatrial a...
read mode data mover
read mode data mov...
write mode data mover
write mode data...
req
rsp
req...
StreamerTop
StreamerTop
Text is not SVG - cannot display
\ No newline at end of file From 9b4649c82cbb68c1919203711df71d330c0f44b7 Mon Sep 17 00:00:00 2001 From: jorendumoulin Date: Fri, 10 May 2024 09:31:40 +0200 Subject: [PATCH 19/19] move test parameters to correct folder --- .../snax/{csr_manager => streamer}/StreamerTestParameter.scala | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename hw/chisel/src/test/scala/snax/{csr_manager => streamer}/StreamerTestParameter.scala (100%) diff --git a/hw/chisel/src/test/scala/snax/csr_manager/StreamerTestParameter.scala b/hw/chisel/src/test/scala/snax/streamer/StreamerTestParameter.scala similarity index 100% rename from hw/chisel/src/test/scala/snax/csr_manager/StreamerTestParameter.scala rename to hw/chisel/src/test/scala/snax/streamer/StreamerTestParameter.scala