From a53b00e4b0c0b843799599875ef791fcbb7ecf89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 18 Dec 2022 18:21:45 +0100 Subject: [PATCH 001/120] ci: update iverilog --- tools.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools.sh b/tools.sh index 156da8ec01..1e89ce8345 100644 --- a/tools.sh +++ b/tools.sh @@ -1,7 +1,7 @@ #!/bin/sh install_verilator(){ - sudo apt install -y git make autoconf g++ flex libfl-dev bison # First time prerequisites + sudo apt install -y git make autoconf build-essential flex libfl-dev bison # First time prerequisites git clone http://git.veripool.org/git/verilator # Only first time unset VERILATOR_ROOT # For bash cd verilator @@ -15,7 +15,7 @@ install_verilator(){ } install_ghdl(){ - sudo apt install -y gnat-9 libgnat-9 zlib1g-dev libboost-dev + sudo apt install -y gnat-9 libgnat-9 zlib1g-dev libboost-dev git clone https://github.com/ghdl/ghdl ghdl-build && cd ghdl-build git reset --hard "v1.0.0" mkdir build @@ -27,9 +27,9 @@ install_ghdl(){ } install_iverilog(){ - sudo apt install -y gperf readline-common bison flex libfl-dev - curl -fsSL https://github.com/steveicarus/iverilog/archive/v10_3.tar.gz | tar -xvz - cd iverilog-10_3 + sudo apt install -y gperf readline-common build-essential bison flex libfl-dev + curl -fsSL https://github.com/steveicarus/iverilog/archive/v11_0.tar.gz | tar -xvz + cd iverilog-11_0 autoconf ./configure --prefix ~/tools make -j$(nproc) From f147fd190c235df9efa7f9472e80abb604862f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 18 Dec 2022 18:54:25 +0100 Subject: [PATCH 002/120] ci: just install verilog --- tools.sh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tools.sh b/tools.sh index 1e89ce8345..e9294507b0 100644 --- a/tools.sh +++ b/tools.sh @@ -27,14 +27,7 @@ install_ghdl(){ } install_iverilog(){ - sudo apt install -y gperf readline-common build-essential bison flex libfl-dev - curl -fsSL https://github.com/steveicarus/iverilog/archive/v11_0.tar.gz | tar -xvz - cd iverilog-11_0 - autoconf - ./configure --prefix ~/tools - make -j$(nproc) - make install - cd .. + sudo apt install -y iverilog } install_cocotb(){ From cacd0d6cd2f9d65e246c2e7c650b6c67fc5682eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 19:57:33 +0100 Subject: [PATCH 003/120] refactor: move CocotbBase to tester/main --- build.sbt | 13 ++++++------- .../spinal/tester}/SpinalTesterCocotbBase.scala | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) rename tester/src/{test/scala/spinal/tester/scalatest => main/scala/spinal/tester}/SpinalTesterCocotbBase.scala (99%) diff --git a/build.sbt b/build.sbt index 43574ae26b..3af234b815 100644 --- a/build.sbt +++ b/build.sbt @@ -126,7 +126,7 @@ val defaultSettingsWithPlugin = defaultSettings ++ Seq( }.value ) -lazy val core = (project in file("core")) +lazy val core: Project = (project in file("core")) .dependsOn(idslplugin) .settings( defaultSettingsWithPlugin, @@ -153,18 +153,17 @@ lazy val core = (project in file("core")) ) .dependsOn(sim) -lazy val lib = (project in file("lib")) +lazy val lib: Project = (project in file("lib")) .settings( defaultSettingsWithPlugin, name := "SpinalHDL-lib", libraryDependencies += "commons-io" % "commons-io" % "2.4", - version := SpinalVersion.lib + version := SpinalVersion.lib, + Test / unmanagedClasspath ++= (LocalProject("tester") / Compile / fullClasspath).value ) - .dependsOn (sim, core) + .dependsOn(sim, core) - - -lazy val tester = (project in file("tester")) +lazy val tester: Project = (project in file("tester")) .settings( defaultSettingsWithPlugin, name := "SpinalHDL-tester", diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalTesterCocotbBase.scala b/tester/src/main/scala/spinal/tester/SpinalTesterCocotbBase.scala similarity index 99% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalTesterCocotbBase.scala rename to tester/src/main/scala/spinal/tester/SpinalTesterCocotbBase.scala index 90f97b7e3a..19d05dc5ea 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalTesterCocotbBase.scala +++ b/tester/src/main/scala/spinal/tester/SpinalTesterCocotbBase.scala @@ -1,4 +1,4 @@ -package spinal.tester.scalatest +package spinal.tester import java.io.File import java.nio.charset.Charset From 6480f87738efb5573bdcd37d625614ce7db48196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 19:59:55 +0100 Subject: [PATCH 004/120] refactor: rename AhbLite3CrossbarFactory.scala --- .../{AhbLite3Interconnect.scala => AhbLite3CrossbarFactory.scala} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/src/main/scala/spinal/lib/bus/amba3/ahblite/{AhbLite3Interconnect.scala => AhbLite3CrossbarFactory.scala} (100%) diff --git a/lib/src/main/scala/spinal/lib/bus/amba3/ahblite/AhbLite3Interconnect.scala b/lib/src/main/scala/spinal/lib/bus/amba3/ahblite/AhbLite3CrossbarFactory.scala similarity index 100% rename from lib/src/main/scala/spinal/lib/bus/amba3/ahblite/AhbLite3Interconnect.scala rename to lib/src/main/scala/spinal/lib/bus/amba3/ahblite/AhbLite3CrossbarFactory.scala From fa282848cdcb8aa5d1f200be15adc93ac82d25af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:01:13 +0100 Subject: [PATCH 005/120] refactor: move AhbLite3CrossbarTester --- .../lib/bus/amba3/ahblite/AhbLite3CrossbarFactory.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/AhbLite3InterconnectTester.scala => lib/src/test/scala/spinal/lib/bus/amba3/ahblite/AhbLite3CrossbarFactory.scala (94%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/AhbLite3InterconnectTester.scala b/lib/src/test/scala/spinal/lib/bus/amba3/ahblite/AhbLite3CrossbarFactory.scala similarity index 94% rename from tester/src/test/scala/spinal/tester/scalatest/AhbLite3InterconnectTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba3/ahblite/AhbLite3CrossbarFactory.scala index 685e01e713..652797cf3f 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/AhbLite3InterconnectTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba3/ahblite/AhbLite3CrossbarFactory.scala @@ -1,9 +1,8 @@ -package spinal.tester.scalatest +package spinal.lib.bus.amba3.ahblite import spinal.core._ import spinal.lib._ -import spinal.lib.bus.amba3.ahblite.{AhbLite3CrossbarFactory, AhbLite3, AhbLite3Master, AhbLite3Config} - +import spinal.tester.SpinalTesterCocotbBase object AhbLite3CrossbarTester{ class AhbLite3CrossbarTester extends Component { From 2d23372867d16deac5ca9fcd0d4ea15436982b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:01:39 +0100 Subject: [PATCH 006/120] refactor: move AhbLite3OnChipRamTester --- .../spinal/lib/bus/amba3/ahblite/AhbLite3OnChipRam.scala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/AhbLite3OnChipRamTester.scala => lib/src/test/scala/spinal/lib/bus/amba3/ahblite/AhbLite3OnChipRam.scala (90%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/AhbLite3OnChipRamTester.scala b/lib/src/test/scala/spinal/lib/bus/amba3/ahblite/AhbLite3OnChipRam.scala similarity index 90% rename from tester/src/test/scala/spinal/tester/scalatest/AhbLite3OnChipRamTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba3/ahblite/AhbLite3OnChipRam.scala index 3eb66d45b6..131fb425bd 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/AhbLite3OnChipRamTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba3/ahblite/AhbLite3OnChipRam.scala @@ -1,10 +1,8 @@ -package spinal.tester.scalatest +package spinal.lib.bus.amba3.ahblite import spinal.core._ import spinal.lib._ -import spinal.lib.bus.amba3.ahblite._ - - +import spinal.tester.SpinalTesterCocotbBase object AhbLite3OnChipRamTester{ class AhbLite3OnChipRamTester extends Component { From 8e72b6c8ce065c2e65b93d4b4ef542cebf00e498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:02:10 +0100 Subject: [PATCH 007/120] refactor: move Axi4AdapterTester --- .../lib/bus/amba4/axi}/Axi4AdapterTester.scala | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) rename {tester/src/test/scala/spinal/tester/scalatest => lib/src/test/scala/spinal/lib/bus/amba4/axi}/Axi4AdapterTester.scala (98%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Axi4AdapterTester.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4AdapterTester.scala similarity index 98% rename from tester/src/test/scala/spinal/tester/scalatest/Axi4AdapterTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4AdapterTester.scala index 2fe7e811a7..45c8638432 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Axi4AdapterTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4AdapterTester.scala @@ -1,16 +1,17 @@ -package spinal.tester.scalatest +package spinal.lib.bus.amba4.axi + +import scala.collection.mutable +import scala.util.Random import spinal.core._ import spinal.core.sim._ -import org.scalatest.funsuite.AnyFunSuite -import spinal.core.sim.SimCompiled import spinal.lib.bus.amba4.axi.sim.{Axi4ReadOnlyMasterAgent, Axi4ReadOnlyMonitor, Axi4ReadOnlySlaveAgent, Axi4WriteOnlyMasterAgent, Axi4WriteOnlyMonitor, Axi4WriteOnlySlaveAgent} -import spinal.lib.bus.amba4.axi.{Axi4, Axi4Config, Axi4ReadOnly, Axi4ReadOnlyDownsizer, Axi4ReadOnlyIdRemover, Axi4ReadOnlyUpsizer, Axi4SharedIdRemover, Axi4WriteOnly, Axi4WriteOnlyDownsizer, Axi4WriteOnlyIdRemover, Axi4WriteOnlyUpsizer} import spinal.lib.bus.misc.SizeMapping import spinal.lib.{master, slave} -import scala.collection.mutable -import scala.util.Random +import spinal.tester.SpinalTesterCocotbBase + +import org.scalatest.funsuite.AnyFunSuite class Axi4UpsizerTester extends AnyFunSuite { From a9ff1393cdfea985497a7771fc875f1939498b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:02:35 +0100 Subject: [PATCH 008/120] refactor: move Axi4CrossbarTester --- .../scala/spinal/lib/bus/amba4/axi/Axi4CrossbarFactory.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/Axi4InterconnectTester.scala => lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4CrossbarFactory.scala (94%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Axi4InterconnectTester.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4CrossbarFactory.scala similarity index 94% rename from tester/src/test/scala/spinal/tester/scalatest/Axi4InterconnectTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4CrossbarFactory.scala index 3ae3e5c735..d72c51f125 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Axi4InterconnectTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4CrossbarFactory.scala @@ -1,10 +1,9 @@ -package spinal.tester.scalatest - +package spinal.lib.bus.amba4.axi import spinal.core._ import spinal.lib._ -import spinal.lib.bus.amba4.axi._ +import spinal.tester.SpinalTesterCocotbBase object Axi4CrossbarTester{ class Axi4CrossbarTester extends Component { From abbe6d80c3d9d60dae5d428cef50a6bde54c7f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:03:46 +0100 Subject: [PATCH 009/120] refactor: move Apb3I2cSlaveTester --- .../src/test/scala/spinal/lib/com/i2c/Apb3I2cCtrl.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/Apb3I2cSlaveTester.scala => lib/src/test/scala/spinal/lib/com/i2c/Apb3I2cCtrl.scala (94%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Apb3I2cSlaveTester.scala b/lib/src/test/scala/spinal/lib/com/i2c/Apb3I2cCtrl.scala similarity index 94% rename from tester/src/test/scala/spinal/tester/scalatest/Apb3I2cSlaveTester.scala rename to lib/src/test/scala/spinal/lib/com/i2c/Apb3I2cCtrl.scala index 47ef35249d..19b8b97509 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Apb3I2cSlaveTester.scala +++ b/lib/src/test/scala/spinal/lib/com/i2c/Apb3I2cCtrl.scala @@ -16,11 +16,11 @@ * License along with this library. */ -package spinal.tester.scalatest +package spinal.lib.com.i2c import spinal.core._ -import spinal.lib.com.i2c._ +import spinal.tester.SpinalTesterCocotbBase class Apb3I2cSlaveTester extends SpinalTesterCocotbBase { override def getName: String = "Apb3I2cSlaveTester" From 5788091ec3fe65b7a5579329d8b3049492442a95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:05:03 +0100 Subject: [PATCH 010/120] refactor: move Apb3SpiMasterCtrlTester --- .../test/scala/spinal/lib/com/spi/Apb3SpiMasterCtrl.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/Apb3SpiMasterCtrlTester.scala => lib/src/test/scala/spinal/lib/com/spi/Apb3SpiMasterCtrl.scala (88%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Apb3SpiMasterCtrlTester.scala b/lib/src/test/scala/spinal/lib/com/spi/Apb3SpiMasterCtrl.scala similarity index 88% rename from tester/src/test/scala/spinal/tester/scalatest/Apb3SpiMasterCtrlTester.scala rename to lib/src/test/scala/spinal/lib/com/spi/Apb3SpiMasterCtrl.scala index 8c9bb05371..aaa6a06937 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Apb3SpiMasterCtrlTester.scala +++ b/lib/src/test/scala/spinal/lib/com/spi/Apb3SpiMasterCtrl.scala @@ -16,12 +16,11 @@ * License along with this library. */ -package spinal.tester.scalatest +package spinal.lib.com.spi import spinal.core._ -import spinal.lib.com.i2c._ -import spinal.lib.com.spi.{SpiMasterCtrlGenerics, Apb3SpiMasterCtrl, SpiMasterCtrlMemoryMappedConfig} +import spinal.tester.SpinalTesterCocotbBase class Apb3SpiMasterCtrlTester extends SpinalTesterCocotbBase { override def getName: String = "Apb3SpiMasterCtrlTester" From 7c5ebbf37b67c457e636af06c881f01435ba3e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:05:19 +0100 Subject: [PATCH 011/120] refactor: move Apb3SpiSlaveCtrlTester --- .../src/test/scala/spinal/lib/com/spi/Apb3SpiSlaveCtrl.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/Apb3SpiSlaveCtrlTester.scala => lib/src/test/scala/spinal/lib/com/spi/Apb3SpiSlaveCtrl.scala (90%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Apb3SpiSlaveCtrlTester.scala b/lib/src/test/scala/spinal/lib/com/spi/Apb3SpiSlaveCtrl.scala similarity index 90% rename from tester/src/test/scala/spinal/tester/scalatest/Apb3SpiSlaveCtrlTester.scala rename to lib/src/test/scala/spinal/lib/com/spi/Apb3SpiSlaveCtrl.scala index aa9cdb617f..8e875357ba 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Apb3SpiSlaveCtrlTester.scala +++ b/lib/src/test/scala/spinal/lib/com/spi/Apb3SpiSlaveCtrl.scala @@ -16,11 +16,11 @@ * License along with this library. */ -package spinal.tester.scalatest +package spinal.lib.com.spi import spinal.core._ -import spinal.lib.com.spi.{Apb3SpiSlaveCtrl, SpiSlaveCtrlGenerics, SpiSlaveCtrlMemoryMappedConfig} +import spinal.tester.SpinalTesterCocotbBase class Apb3SpiSlaveCtrlTester extends SpinalTesterCocotbBase { override def getName: String = "Apb3SpiSlaveCtrlTester" From a262e9800d9c0bae07ad9c3c0afb195b8db4e712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:07:35 +0100 Subject: [PATCH 012/120] refactor: move Axi4CrossbarTester2 --- .../bus/amba4/axi/Axi4CrossbarFactory.scala | 52 ++++++++++++++++- .../scalatest/Axi4InterconnectTester2.scala | 56 ------------------- 2 files changed, 51 insertions(+), 57 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/Axi4InterconnectTester2.scala diff --git a/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4CrossbarFactory.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4CrossbarFactory.scala index d72c51f125..0f989ee342 100644 --- a/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4CrossbarFactory.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4CrossbarFactory.scala @@ -34,4 +34,54 @@ class Axi4CrossbarTesterCocotbBoot extends SpinalTesterCocotbBase { override def getName: String = "Axi4CrossbarTester" override def pythonTestLocation: String = "tester/src/test/python/spinal/Axi4CrossbarTester" override def createToplevel: Component = new Axi4CrossbarTester.Axi4CrossbarTester -} \ No newline at end of file +} + +object Axi4CrossbarTester2{ + class Axi4CrossbarTester2 extends Component { + val axiMasterConfig = Axi4Config(addressWidth = 15,dataWidth = 32,idWidth = 4) + val axiSlaveConfig = Axi4Config(addressWidth = 15,dataWidth = 32,idWidth = 8) + + val axiMasters = Vec(slave(Axi4(axiMasterConfig)),2) + val axiSlaves = Vec(master(Axi4(axiSlaveConfig)),2) + + val axiReadOnlyMasters = Vec(slave(Axi4ReadOnly(axiMasterConfig)),2) + val axiReadOnlySlaves = Vec(master(Axi4ReadOnly(axiSlaveConfig)),2) + + val axiWriteOnlyMasters = Vec(slave(Axi4WriteOnly(axiMasterConfig)),2) + val axiWriteOnlySlaves = Vec(master(Axi4WriteOnly(axiSlaveConfig)),2) + + val axiSharedMasters = Vec(slave(Axi4Shared(axiMasterConfig)),2) + val axiSharedSlaves = Vec(master(Axi4Shared(axiSlaveConfig)),2) + + val crossbarFactory = Axi4CrossbarFactory() + .addSlaves( + axiSlaves(0) -> (0x0000,0x800), + axiSlaves(1) -> (0x0800,0x800), + axiSharedSlaves(0) -> (0x1000,0x800), + axiSharedSlaves(1) -> (0x1800,0x800), + axiReadOnlySlaves(0) -> (0x2000,0x800), + axiReadOnlySlaves(1) -> (0x2800,0x800), + axiWriteOnlySlaves(0) -> (0x3000,0x800), + axiWriteOnlySlaves(1) -> (0x3800,0x800) + ) + .addConnections( + axiMasters(0) -> (axiSlaves ++ axiReadOnlySlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves), + axiMasters(1) -> (axiSlaves ++ axiReadOnlySlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves), + axiSharedMasters(0) -> (axiSlaves ++ axiReadOnlySlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves), + axiSharedMasters(1) -> (axiSlaves ++ axiReadOnlySlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves), + axiReadOnlyMasters(0) -> (axiSlaves ++ axiReadOnlySlaves ++ axiSharedSlaves), + axiReadOnlyMasters(1) -> (axiSlaves ++ axiReadOnlySlaves ++ axiSharedSlaves), + axiWriteOnlyMasters(0) -> (axiSlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves), + axiWriteOnlyMasters(1) -> (axiSlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves) + ) + + val crossbar = crossbarFactory.build() + } +} + +class Axi4CrossbarTester2CocotbBoot extends SpinalTesterCocotbBase { + override def getName: String = "Axi4CrossbarTester2" + override def pythonTestLocation: String = "tester/src/test/python/spinal/Axi4CrossbarTester2" + override def createToplevel: Component = new Axi4CrossbarTester2.Axi4CrossbarTester2 + override def backendConfig(config: SpinalConfig): SpinalConfig = super.backendConfig(config) +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/Axi4InterconnectTester2.scala b/tester/src/test/scala/spinal/tester/scalatest/Axi4InterconnectTester2.scala deleted file mode 100644 index 7a32e1228f..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/Axi4InterconnectTester2.scala +++ /dev/null @@ -1,56 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.lib._ -import spinal.lib.bus.amba4.axi._ -import scala.collection.Seq - -object Axi4CrossbarTester2{ - class Axi4CrossbarTester2 extends Component { - val axiMasterConfig = Axi4Config(addressWidth = 15,dataWidth = 32,idWidth = 4) - val axiSlaveConfig = Axi4Config(addressWidth = 15,dataWidth = 32,idWidth = 8) - - val axiMasters = Vec(slave(Axi4(axiMasterConfig)),2) - val axiSlaves = Vec(master(Axi4(axiSlaveConfig)),2) - - val axiReadOnlyMasters = Vec(slave(Axi4ReadOnly(axiMasterConfig)),2) - val axiReadOnlySlaves = Vec(master(Axi4ReadOnly(axiSlaveConfig)),2) - - val axiWriteOnlyMasters = Vec(slave(Axi4WriteOnly(axiMasterConfig)),2) - val axiWriteOnlySlaves = Vec(master(Axi4WriteOnly(axiSlaveConfig)),2) - - val axiSharedMasters = Vec(slave(Axi4Shared(axiMasterConfig)),2) - val axiSharedSlaves = Vec(master(Axi4Shared(axiSlaveConfig)),2) - - val crossbarFactory = Axi4CrossbarFactory() - .addSlaves( - axiSlaves(0) -> (0x0000,0x800), - axiSlaves(1) -> (0x0800,0x800), - axiSharedSlaves(0) -> (0x1000,0x800), - axiSharedSlaves(1) -> (0x1800,0x800), - axiReadOnlySlaves(0) -> (0x2000,0x800), - axiReadOnlySlaves(1) -> (0x2800,0x800), - axiWriteOnlySlaves(0) -> (0x3000,0x800), - axiWriteOnlySlaves(1) -> (0x3800,0x800) - ) - .addConnections( - axiMasters(0) -> (axiSlaves ++ axiReadOnlySlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves), - axiMasters(1) -> (axiSlaves ++ axiReadOnlySlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves), - axiSharedMasters(0) -> (axiSlaves ++ axiReadOnlySlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves), - axiSharedMasters(1) -> (axiSlaves ++ axiReadOnlySlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves), - axiReadOnlyMasters(0) -> (axiSlaves ++ axiReadOnlySlaves ++ axiSharedSlaves), - axiReadOnlyMasters(1) -> (axiSlaves ++ axiReadOnlySlaves ++ axiSharedSlaves), - axiWriteOnlyMasters(0) -> (axiSlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves), - axiWriteOnlyMasters(1) -> (axiSlaves ++ axiWriteOnlySlaves ++ axiSharedSlaves) - ) - - val crossbar = crossbarFactory.build() - } -} - -class Axi4CrossbarTester2CocotbBoot extends SpinalTesterCocotbBase { - override def getName: String = "Axi4CrossbarTester2" - override def pythonTestLocation: String = "tester/src/test/python/spinal/Axi4CrossbarTester2" - override def createToplevel: Component = new Axi4CrossbarTester2.Axi4CrossbarTester2 - override def backendConfig(config: SpinalConfig): SpinalConfig = super.backendConfig(config) -} \ No newline at end of file From 84e60e4a29f76f8fb1fbfa418300477e5a07007e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:12:43 +0100 Subject: [PATCH 013/120] refactor: move Axi4SharedSdramCtrlTesterCocotbBoot --- .../spinal/lib/memory/sdram/sdr/Axi4SharedSdramCtrl.scala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/Axi4SharedSdramCtrlTester.scala => lib/src/test/scala/spinal/lib/memory/sdram/sdr/Axi4SharedSdramCtrl.scala (80%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Axi4SharedSdramCtrlTester.scala b/lib/src/test/scala/spinal/lib/memory/sdram/sdr/Axi4SharedSdramCtrl.scala similarity index 80% rename from tester/src/test/scala/spinal/tester/scalatest/Axi4SharedSdramCtrlTester.scala rename to lib/src/test/scala/spinal/lib/memory/sdram/sdr/Axi4SharedSdramCtrl.scala index 5406a6fdda..83b7329565 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Axi4SharedSdramCtrlTester.scala +++ b/lib/src/test/scala/spinal/lib/memory/sdram/sdr/Axi4SharedSdramCtrl.scala @@ -1,10 +1,8 @@ -package spinal.tester.scalatest +package spinal.lib.memory.sdram.sdr import spinal.core._ -import spinal.lib._ -import spinal.lib.memory.sdram._ -import spinal.lib.memory.sdram.sdr.{Axi4SharedSdramCtrl, MT48LC16M16A2} +import spinal.tester.SpinalTesterCocotbBase class Axi4SharedSdramCtrlTesterCocotbBoot extends SpinalTesterCocotbBase { override def getName: String = "Axi4SharedSdramCtrlTester" From f249505523c210db85ec74d308e32a5a6f6fbc3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:25:17 +0100 Subject: [PATCH 014/120] refactor: move Axi4SlaveFactoryTester --- .../scala/spinal/lib/bus/amba4/axi/Axi4SlaveFactory.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/Axi4SlaveFactoryTester.scala => lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SlaveFactory.scala (91%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Axi4SlaveFactoryTester.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SlaveFactory.scala similarity index 91% rename from tester/src/test/scala/spinal/tester/scalatest/Axi4SlaveFactoryTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SlaveFactory.scala index 35418196e9..725238f252 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Axi4SlaveFactoryTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SlaveFactory.scala @@ -1,8 +1,9 @@ -package spinal.tester.scalatest +package spinal.lib.bus.amba4.axi import spinal.core._ import spinal.lib._ -import spinal.lib.bus.amba4.axi.{Axi4, Axi4Config, Axi4SlaveFactory} + +import spinal.tester.SpinalTesterCocotbBase object Axi4SlaveFactoryTester { def axi4Config = Axi4Config( From d4bc8b847269fe2001cb0b8dd6ab212b263f333c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:31:00 +0100 Subject: [PATCH 015/120] refactor: move Axi4StreamSimpleWidthAdapterTester --- .../amba4/axis/Axi4StreamSimpleWidthAdapter.scala | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/Axi4StreamSimpleWidthAdapterTester.scala => lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4StreamSimpleWidthAdapter.scala (94%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Axi4StreamSimpleWidthAdapterTester.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4StreamSimpleWidthAdapter.scala similarity index 94% rename from tester/src/test/scala/spinal/tester/scalatest/Axi4StreamSimpleWidthAdapterTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4StreamSimpleWidthAdapter.scala index 0e9a9b543e..60615f31f7 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Axi4StreamSimpleWidthAdapterTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4StreamSimpleWidthAdapter.scala @@ -1,14 +1,13 @@ -package spinal.tester.scalatest +package spinal.lib.bus.amba4.axis import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ -import spinal.lib._ import spinal.core.sim._ -import spinal.lib.bus.amba4.axis.Axi4Stream.{Axi4Stream, Axi4StreamBundle} -import spinal.lib.bus.amba4.axis._ +import spinal.lib._ + import spinal.lib.sim.{ScoreboardInOrder, StreamDriver, StreamMonitor, StreamReadyRandomizer} -import scala.BigInt import scala.collection.mutable.ListBuffer case class Axi4StreamSimpleWidthAdapterFixture(inSize: Int, outSize: Int, useLast: Boolean = true) extends Component { @@ -80,7 +79,7 @@ class Axi4StreamSimpleWidthAdapterTester extends AnyFunSuite { } }) - def copyCheckByte(axisBundle: Axi4StreamBundle, idx: Int): Axi4CheckByte = { + def copyCheckByte(axisBundle: Axi4Stream.Axi4StreamBundle, idx: Int): Axi4CheckByte = { val data = (axisBundle.data.toBigInt >> 8*idx) & BigInt(0xFF) val strb = if (axisBundle.config.useStrb) axisBundle.strb.toBigInt.testBit(idx) else true val keep = if (axisBundle.config.useKeep) axisBundle.keep.toBigInt.testBit(idx) else true @@ -94,7 +93,7 @@ class Axi4StreamSimpleWidthAdapterTester extends AnyFunSuite { Axi4CheckByte(data = data, strb = strb, keep = keep, last = last, id = id, dest = dest, user = user) } - def streamByteTransactionMonitor(stream: Axi4Stream, clockDomain: ClockDomain)(callback: (Seq[Axi4CheckByte]) => Unit) = { + def streamByteTransactionMonitor(stream: Axi4Stream.Axi4Stream, clockDomain: ClockDomain)(callback: (Seq[Axi4CheckByte]) => Unit) = { var currentTransaction = ListBuffer[Axi4CheckByte]() StreamMonitor(stream, clockDomain)(p => { From 29a333110e0f80d001c3d4fd925aa52bd3e5b7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:32:27 +0100 Subject: [PATCH 016/120] refactor: move Axi4StreamTester --- .../test/scala/spinal/lib/bus/amba4/axis/Axi4Stream.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/Axi4StreamTester.scala => lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4Stream.scala (97%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Axi4StreamTester.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4Stream.scala similarity index 97% rename from tester/src/test/scala/spinal/tester/scalatest/Axi4StreamTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4Stream.scala index a0442035f8..acde93b474 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Axi4StreamTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4Stream.scala @@ -1,10 +1,10 @@ -package spinal.tester.scalatest +package spinal.lib.bus.amba4.axis import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ -import spinal.lib._ import spinal.core.sim._ -import spinal.lib.bus.amba4.axis._ +import spinal.lib._ case class Axi4StreamEndianFixture[T <: Data](config: Axi4StreamConfig, outType: HardType[T]) extends Component { val io = new Bundle { From d2d646dcb449f0fb2b397f75f6e73745fe76ce1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:34:12 +0100 Subject: [PATCH 017/120] refactor: move Axi4StreamWidthAdapterTester --- .../bus/amba4/axis/Axi4StreamWidthAdapter.scala | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/Axi4StreamWidthAdapterTester.scala => lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4StreamWidthAdapter.scala (94%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Axi4StreamWidthAdapterTester.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4StreamWidthAdapter.scala similarity index 94% rename from tester/src/test/scala/spinal/tester/scalatest/Axi4StreamWidthAdapterTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4StreamWidthAdapter.scala index 60bee2a6d1..aa135a90bb 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Axi4StreamWidthAdapterTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axis/Axi4StreamWidthAdapter.scala @@ -1,15 +1,14 @@ -package spinal.tester.scalatest +package spinal.lib.bus.amba4.axis + +import scala.collection.mutable.ListBuffer import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ -import spinal.lib._ import spinal.core.sim._ -import spinal.lib.bus.amba4.axis.Axi4Stream.{Axi4Stream, Axi4StreamBundle} -import spinal.lib.bus.amba4.axis._ -import spinal.lib.sim.{ScoreboardInOrder, StreamDriver, StreamMonitor, StreamReadyRandomizer} +import spinal.lib._ -import scala.BigInt -import scala.collection.mutable.ListBuffer +import spinal.lib.sim.{ScoreboardInOrder, StreamDriver, StreamMonitor, StreamReadyRandomizer} case class Axi4StreamWidthAdapterFixture(inSize: Int, outSize: Int, compact: Boolean) extends Component { var inputConfig = Axi4StreamConfig(dataWidth = inSize, @@ -78,7 +77,7 @@ class Axi4StreamWidthAdapterTester extends AnyFunSuite { } }) - def copyCheckByte(axisBundle: Axi4StreamBundle, idx: Int): Axi4CheckByte = { + def copyCheckByte(axisBundle: Axi4Stream.Axi4StreamBundle, idx: Int): Axi4CheckByte = { val data = (axisBundle.data.toBigInt >> 8*idx) & BigInt(0xFF) val strb = if (axisBundle.config.useStrb) axisBundle.strb.toBigInt.testBit(idx) else true val keep = if (axisBundle.config.useKeep) axisBundle.keep.toBigInt.testBit(idx) else true @@ -92,7 +91,7 @@ class Axi4StreamWidthAdapterTester extends AnyFunSuite { Axi4CheckByte(data = data, strb = strb, keep = keep, last = last, id = id, dest = dest, user = user) } - def streamByteTransactionMonitor(stream: Axi4Stream, clockDomain: ClockDomain)(callback: (Seq[Axi4CheckByte]) => Unit) = { + def streamByteTransactionMonitor(stream: Axi4Stream.Axi4Stream, clockDomain: ClockDomain)(callback: (Seq[Axi4CheckByte]) => Unit) = { var currentTransaction = ListBuffer[Axi4CheckByte]() StreamMonitor(stream, clockDomain)(p => { From 9816b755d654de1b12f7e809076f725ac6966622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 20:36:31 +0100 Subject: [PATCH 018/120] refactor: move AxiLite4SlaveFactoryTester --- .../spinal/lib/bus/amba4/axilite/AxiLite4SlaveFactory.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/AxiLite4SlaveFactoryTester.scala => lib/src/test/scala/spinal/lib/bus/amba4/axilite/AxiLite4SlaveFactory.scala (90%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/AxiLite4SlaveFactoryTester.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axilite/AxiLite4SlaveFactory.scala similarity index 90% rename from tester/src/test/scala/spinal/tester/scalatest/AxiLite4SlaveFactoryTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba4/axilite/AxiLite4SlaveFactory.scala index d848a3f5b6..b66cc3c96e 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/AxiLite4SlaveFactoryTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axilite/AxiLite4SlaveFactory.scala @@ -1,8 +1,9 @@ -package spinal.tester.scalatest +package spinal.lib.bus.amba4.axilite import spinal.core._ import spinal.lib._ -import spinal.lib.bus.amba4.axilite.{AxiLite4SlaveFactory, AxiLite4, AxiLite4Config} + +import spinal.tester.SpinalTesterCocotbBase object AxiLite4SlaveFactoryTester{ def axiLite4Config = AxiLite4Config( From 7aee70c5eb57fe25066d87828f36094e344a6954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 21:09:13 +0100 Subject: [PATCH 019/120] build: add test dependencies to core --- build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sbt b/build.sbt index 3af234b815..664f4c8353 100644 --- a/build.sbt +++ b/build.sbt @@ -134,6 +134,8 @@ lazy val core: Project = (project in file("core")) libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value, libraryDependencies += "com.github.scopt" %% "scopt" % "3.7.1", libraryDependencies += "com.lihaoyi" %% "sourcecode" % "0.2.7", + Test / unmanagedClasspath ++= (LocalProject("tester") / Compile / fullClasspath).value, + Test / unmanagedClasspath ++= (LocalProject("lib") / Compile / fullClasspath).value, resolvers += Resolver.sonatypeRepo("public"), version := SpinalVersion.core, From bdddf82b3f32a9e9587672c828d62ee67089654a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 21:10:36 +0100 Subject: [PATCH 020/120] refactor: mv more tester/test to tester/main It is just moving items for now, maybe more structure would be better. --- .../spinal/tester/SpinalSimFunSuite.scala | 34 ++++++ .../spinal/tester}/SpinalSimMiscTester.scala | 103 ++---------------- .../scala/spinal/tester/SpinalSimTester.scala | 44 ++++++++ .../spinal/tester/SpinalSimTesterTest.scala | 13 +++ 4 files changed, 100 insertions(+), 94 deletions(-) create mode 100644 tester/src/main/scala/spinal/tester/SpinalSimFunSuite.scala rename tester/src/{test/scala/spinal/tester/scalatest => main/scala/spinal/tester}/SpinalSimMiscTester.scala (76%) create mode 100644 tester/src/main/scala/spinal/tester/SpinalSimTester.scala create mode 100644 tester/src/main/scala/spinal/tester/SpinalSimTesterTest.scala diff --git a/tester/src/main/scala/spinal/tester/SpinalSimFunSuite.scala b/tester/src/main/scala/spinal/tester/SpinalSimFunSuite.scala new file mode 100644 index 0000000000..ccd8723f56 --- /dev/null +++ b/tester/src/main/scala/spinal/tester/SpinalSimFunSuite.scala @@ -0,0 +1,34 @@ +package spinal.tester + +import org.scalatest.funsuite.AnyFunSuite + +class SpinalSimFunSuite extends AnyFunSuite { + var tester: SpinalSimTester = null + def SimConfig = tester.SimConfig + var durationFactor = 0.0 + var ghdlEnabled = true + var iverilogEnabled = true + + def onlyVerilator(): Unit = { + iverilogEnabled = false + ghdlEnabled = false + } + + def test(testName: String)(testFun: => Unit): Unit = { + super.test("verilator_" + testName) { + tester = SpinalSimTester.Verilator + durationFactor = SpinalSimTester.Verilator.durationFactor + testFun + } + if (ghdlEnabled) super.test("ghdl_" + testName) { + tester = SpinalSimTester.Ghdl + durationFactor = SpinalSimTester.Ghdl.durationFactor + testFun + } + if (iverilogEnabled) super.test("iverilog_" + testName) { + tester = SpinalSimTester.IVerilog + durationFactor = SpinalSimTester.IVerilog.durationFactor + testFun + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimMiscTester.scala b/tester/src/main/scala/spinal/tester/SpinalSimMiscTester.scala similarity index 76% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimMiscTester.scala rename to tester/src/main/scala/spinal/tester/SpinalSimMiscTester.scala index 8dede4724d..d896b21ff3 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimMiscTester.scala +++ b/tester/src/main/scala/spinal/tester/SpinalSimMiscTester.scala @@ -1,16 +1,12 @@ -package spinal.tester.scalatest +package spinal.tester -import org.scalatest.{FixtureContext, Succeeded} import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ +import scala.util.Random + import spinal.sim._ -import spinal.core.sim.{SpinalSimConfig, _} +import spinal.core._ +import spinal.core.sim._ import spinal.lib.{BufferCC, OHMasking, SetFromFirstOne} -import spinal.tester -import spinal.tester.scalatest - -import scala.concurrent.{Await, Future} -import scala.util.Random object SpinalSimMiscTester{ class SpinalSimMiscTesterCounter extends Component{ @@ -28,91 +24,10 @@ object SpinalSimMiscTester{ } -abstract class SpinalSimTester{ - def SimConfig : SpinalSimConfig - def durationFactor : Double - def designFactor : Double - def prefix : String - def language : SpinalMode -} - -object SpinalSimTesterGhdl extends SpinalSimTester{ - override def SimConfig: SpinalSimConfig = spinal.core.sim.SimConfig.withGhdl - override def durationFactor: Double = 0.005 - override def designFactor: Double = 0.05 - override def prefix: String = "ghdl_" - override def language: SpinalMode = VHDL -} - -object SpinalSimTesterIVerilog extends SpinalSimTester{ - override def SimConfig: SpinalSimConfig = spinal.core.sim.SimConfig.withIVerilog - override def durationFactor: Double = 0.005 - override def designFactor: Double = 0.05 - override def prefix: String = "iverilog_" - override def language: SpinalMode = Verilog -} - -object SpinalSimTesterVerilator extends SpinalSimTester{ - override def SimConfig: SpinalSimConfig = spinal.core.sim.SimConfig.withVerilator - override def durationFactor: Double = 0.5 - override def designFactor: Double = 0.5 - override def prefix: String = "verilator_" - override def language: SpinalMode = Verilog -} - -object SpinalSimTester{ - - def apply(body : => SpinalSimTester => Unit): Unit = { - body(SpinalSimTesterGhdl) - body(SpinalSimTesterIVerilog) - body(SpinalSimTesterVerilator) - } -} - -class SpinalSimTesterTest extends AnyFunSuite { - SpinalSimTester{ env => - import env._ - - test(prefix + "a"){ - println(SimConfig._backend + " " + durationFactor) - } - } -} - -class SpinalSimFunSuite extends AnyFunSuite{ - var tester : SpinalSimTester = null - def SimConfig = tester.SimConfig - var durationFactor = 0.0 - var ghdlEnabled = true - var iverilogEnabled = true - - def onlyVerilator(): Unit ={ - iverilogEnabled = false - ghdlEnabled = false - } - def test(testName: String)(testFun: => Unit): Unit = { - super.test("verilator_" + testName) { - tester = SpinalSimTesterVerilator - durationFactor = SpinalSimTesterVerilator.durationFactor - testFun - } - if(ghdlEnabled) super.test("ghdl_" + testName) { - tester = SpinalSimTesterGhdl - durationFactor = SpinalSimTesterGhdl.durationFactor - testFun - } - if(iverilogEnabled) super.test("iverilog_" + testName) { - tester = SpinalSimTesterIVerilog - durationFactor = SpinalSimTesterIVerilog.durationFactor - testFun - } - } -} - class SpinalSimMiscTester extends AnyFunSuite { SpinalSimTester { env => import env._ - var compiled: SimCompiled[tester.scalatest.SpinalSimMiscTester.SpinalSimMiscTesterCounter] = null + var compiled: SimCompiled[SpinalSimMiscTester.SpinalSimMiscTesterCounter] = null test(prefix + "testForkSensitive") { SimConfig.compile(new Component { @@ -137,7 +52,7 @@ class SpinalSimMiscTester extends AnyFunSuite { test(prefix + "compile") { - compiled = SimConfig.compile(new tester.scalatest.SpinalSimMiscTester.SpinalSimMiscTesterCounter) + compiled = SimConfig.compile(new SpinalSimMiscTester.SpinalSimMiscTesterCounter) } def doStdtest(name: String): Unit = { @@ -292,7 +207,7 @@ class SpinalSimMiscTester extends AnyFunSuite { } test(prefix + "testRecompile1") { - SimConfig.doSim(new tester.scalatest.SpinalSimMiscTester.SpinalSimMiscTesterCounter)(dut => { + SimConfig.doSim(new SpinalSimMiscTester.SpinalSimMiscTesterCounter)(dut => { dut.clockDomain.forkStimulus(10) var counterModel = 0 @@ -311,7 +226,7 @@ class SpinalSimMiscTester extends AnyFunSuite { test(prefix + "testRecompile2") { - SimConfig.doSim(new tester.scalatest.SpinalSimMiscTester.SpinalSimMiscTesterCounter)(dut => { + SimConfig.doSim(new SpinalSimMiscTester.SpinalSimMiscTesterCounter)(dut => { dut.clockDomain.forkStimulus(10) var counterModel = 0 diff --git a/tester/src/main/scala/spinal/tester/SpinalSimTester.scala b/tester/src/main/scala/spinal/tester/SpinalSimTester.scala new file mode 100644 index 0000000000..e228650db3 --- /dev/null +++ b/tester/src/main/scala/spinal/tester/SpinalSimTester.scala @@ -0,0 +1,44 @@ +package spinal.tester + +import spinal.core.sim.SpinalSimConfig +import spinal.core.{SpinalMode, Verilog, VHDL} + +abstract class SpinalSimTester { + def SimConfig: SpinalSimConfig + def durationFactor: Double + def designFactor: Double + def prefix: String + def language: SpinalMode +} + +object SpinalSimTester { + def apply(body: => SpinalSimTester => Unit): Unit = { + body(Ghdl) + body(IVerilog) + body(Verilator) + } + + object Ghdl extends SpinalSimTester { + override def SimConfig: SpinalSimConfig = spinal.core.sim.SimConfig.withGhdl + override def durationFactor: Double = 0.005 + override def designFactor: Double = 0.05 + override def prefix: String = "ghdl_" + override def language: SpinalMode = VHDL + } + + object IVerilog extends SpinalSimTester { + override def SimConfig: SpinalSimConfig = spinal.core.sim.SimConfig.withIVerilog + override def durationFactor: Double = 0.005 + override def designFactor: Double = 0.05 + override def prefix: String = "iverilog_" + override def language: SpinalMode = Verilog + } + + object Verilator extends SpinalSimTester { + override def SimConfig: SpinalSimConfig = spinal.core.sim.SimConfig.withVerilator + override def durationFactor: Double = 0.5 + override def designFactor: Double = 0.5 + override def prefix: String = "verilator_" + override def language: SpinalMode = Verilog + } +} diff --git a/tester/src/main/scala/spinal/tester/SpinalSimTesterTest.scala b/tester/src/main/scala/spinal/tester/SpinalSimTesterTest.scala new file mode 100644 index 0000000000..1c9c9d8265 --- /dev/null +++ b/tester/src/main/scala/spinal/tester/SpinalSimTesterTest.scala @@ -0,0 +1,13 @@ +package spinal.tester + +import org.scalatest.funsuite.AnyFunSuite + +class SpinalSimTesterTest extends AnyFunSuite { + SpinalSimTester{ env => + import env._ + + test(prefix + "a"){ + println(SimConfig._backend + " " + durationFactor) + } + } +} From b3cfcbf41094aac157c8a5b488f58cc7a24fe2fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 21:10:51 +0100 Subject: [PATCH 021/120] refactor: move BlackboxTester --- .../src/test/scala/spinal/core/BlackBox.scala | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/BlackboxTester.scala => core/src/test/scala/spinal/core/BlackBox.scala (89%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/BlackboxTester.scala b/core/src/test/scala/spinal/core/BlackBox.scala similarity index 89% rename from tester/src/test/scala/spinal/tester/scalatest/BlackboxTester.scala rename to core/src/test/scala/spinal/core/BlackBox.scala index fb2ef241f0..eb65f5d13c 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/BlackboxTester.scala +++ b/core/src/test/scala/spinal/core/BlackBox.scala @@ -1,10 +1,10 @@ -package spinal.tester.scalatest +package spinal.core +import spinal.core.sim._ -import spinal.core._ -import spinal.lib._ +import spinal.tester.{SpinalSimFunSuite, SpinalTesterCocotbBase} -object BlackboxTester { +object BlackBoxTester { case class BBGenerics(aWidth: Int, bWidth: Int) extends Generic @@ -41,14 +41,13 @@ object BlackboxTester { class BlackboxTesterCocotbBoot extends SpinalTesterCocotbBase { override def getName: String = "BlackBoxTester" - override def createToplevel: Component = new BlackboxTester.BlackBoxTester + override def createToplevel: Component = new BlackBoxTester.BlackBoxTester override def pythonTestLocation: String = "tester/src/test/python/spinal/BlackBoxTester" } -import spinal.core.sim._ class SpinalSimBlackboxTester extends SpinalSimFunSuite { test("test"){ - SimConfig.addRtl(s"tester/src/test/python/spinal/BlackBoxTester/BlackBoxToTest.${if(tester.language == VHDL) "vhd" else "v"}").doSim(new BlackboxTester.BlackBoxTester) {dut => + SimConfig.addRtl(s"tester/src/test/python/spinal/BlackBoxTester/BlackBoxToTest.${if(tester.language == VHDL) "vhd" else "v"}").doSim(new BlackBoxTester.BlackBoxTester) {dut => dut.clockDomain.forkStimulus(10) var outA_ref = 0 var outB_ref = 0 From e967100b32a7b51ce790aafbc000eecfad9c13b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 21:12:17 +0100 Subject: [PATCH 022/120] refactor: move LatchTester --- .../src/test/scala/spinal/core/Latch.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/LatchTester.scala => core/src/test/scala/spinal/core/Latch.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/LatchTester.scala b/core/src/test/scala/spinal/core/Latch.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/LatchTester.scala rename to core/src/test/scala/spinal/core/Latch.scala index 08c8461b0e..a66b596bd0 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/LatchTester.scala +++ b/core/src/test/scala/spinal/core/Latch.scala @@ -1,9 +1,11 @@ -package spinal.tester.scalatest +package spinal.core import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ + import spinal.core.sim._ +import spinal.tester.SpinalSimTester + class LatchTester extends AnyFunSuite { test("bad latch") { var didRaise = false From 6c09452be5d4b1bfb4ec55d0f008e22f0de7157e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 21:15:39 +0100 Subject: [PATCH 023/120] refactor: move BundleTester --- .../src/test/scala/spinal/core/Bundle.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/BundleTester.scala => core/src/test/scala/spinal/core/Bundle.scala (94%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/BundleTester.scala b/core/src/test/scala/spinal/core/Bundle.scala similarity index 94% rename from tester/src/test/scala/spinal/tester/scalatest/BundleTester.scala rename to core/src/test/scala/spinal/core/Bundle.scala index a139ebd2a9..4d55d56248 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/BundleTester.scala +++ b/core/src/test/scala/spinal/core/Bundle.scala @@ -16,9 +16,9 @@ * License along with this library. */ -package spinal.tester.scalatest +package spinal.core -import spinal.core._ +import spinal.tester.SpinalTesterCocotbBase object BundleTester { class BundleAA extends BundleA(True,3) { @@ -32,7 +32,7 @@ object BundleTester { } } -import spinal.tester.scalatest.BundleTester._ +import BundleTester._ class BundleTester extends Component { val io = new Bundle { From 983aa883a6f66529a21037994badd12cfda298af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 21:17:42 +0100 Subject: [PATCH 024/120] refactor: move WhenTester --- .../src/test/scala/spinal/core/when.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/WhenTester.scala => core/src/test/scala/spinal/core/when.scala (97%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/WhenTester.scala b/core/src/test/scala/spinal/core/when.scala similarity index 97% rename from tester/src/test/scala/spinal/tester/scalatest/WhenTester.scala rename to core/src/test/scala/spinal/core/when.scala index 8b77f6d07f..ee3f73b394 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/WhenTester.scala +++ b/core/src/test/scala/spinal/core/when.scala @@ -16,9 +16,10 @@ * License along with this library. */ -package spinal.tester.scalatest +package spinal.core + +import spinal.tester.SpinalTesterCocotbBase -import spinal.core._ class WhenTester extends Component { val io = new Bundle { val conds = in Vec(Bool(),8) From 646e2ff4902cd3a99362494df64ccf6ca4a47564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 4 Dec 2022 21:20:05 +0100 Subject: [PATCH 025/120] refactor: move UartTester --- .../src/test/scala/spinal/lib/com/uart/UartCtrl.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/UartTester.scala => lib/src/test/scala/spinal/lib/com/uart/UartCtrl.scala (90%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/UartTester.scala b/lib/src/test/scala/spinal/lib/com/uart/UartCtrl.scala similarity index 90% rename from tester/src/test/scala/spinal/tester/scalatest/UartTester.scala rename to lib/src/test/scala/spinal/lib/com/uart/UartCtrl.scala index 9d1adcf728..df3ac550e1 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/UartTester.scala +++ b/lib/src/test/scala/spinal/lib/com/uart/UartCtrl.scala @@ -1,7 +1,8 @@ -package spinal.tester.scalatest +package spinal.lib.com.uart import spinal.core._ -import spinal.lib.com.uart._ + +import spinal.tester.SpinalTesterCocotbBase class UartTester extends Component { val io = new Bundle { From e69f1b605890fa6c6c5a4ae173b8f8e9f8312f77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 20:27:52 +0100 Subject: [PATCH 026/120] refactor: move SpinalTesterGhdlBase to tester/main --- .../scala/spinal/tester}/SpinalTesterGhdlBase.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename tester/src/{test/scala/spinal/tester/scalatest => main/scala/spinal/tester}/SpinalTesterGhdlBase.scala (98%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalTesterGhdlBase.scala b/tester/src/main/scala/spinal/tester/SpinalTesterGhdlBase.scala similarity index 98% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalTesterGhdlBase.scala rename to tester/src/main/scala/spinal/tester/SpinalTesterGhdlBase.scala index 3e97c49c51..d61badb871 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalTesterGhdlBase.scala +++ b/tester/src/main/scala/spinal/tester/SpinalTesterGhdlBase.scala @@ -1,6 +1,7 @@ -package spinal.tester.scalatest +package spinal.tester import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import scala.sys.process._ From 5e2cb352bfd5c1135abbceae5daa6010d2ecfe1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 20:28:08 +0100 Subject: [PATCH 027/120] refactor: move StreamTester --- .../src/test/scala/spinal/lib/Stream.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/StreamTester.scala => lib/src/test/scala/spinal/lib/Stream.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/StreamTester.scala b/lib/src/test/scala/spinal/lib/Stream.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/StreamTester.scala rename to lib/src/test/scala/spinal/lib/Stream.scala index 115fec4dae..07cf6b93d5 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/StreamTester.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -1,8 +1,8 @@ -package spinal.tester.scalatest +package spinal.lib import spinal.core._ -import spinal.lib._ +import spinal.tester.{SpinalTesterCocotbBase, SpinalTesterGhdlBase} object StreamTester{ case class BundleA(aaa : Int) extends Bundle{ @@ -11,7 +11,7 @@ object StreamTester{ } } -import spinal.tester.scalatest.StreamTester._ +import StreamTester._ class StreamTester extends Component { val io = new Bundle { From 2a2a301843d12a2212239636396724303e041bf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 20:29:45 +0100 Subject: [PATCH 028/120] refactor: move StreamTester2 --- lib/src/test/scala/spinal/lib/Stream.scala | 39 ++++++++++++++++- .../tester/scalatest/StreamTester2.scala | 42 ------------------- 2 files changed, 38 insertions(+), 43 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/StreamTester2.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index 07cf6b93d5..cab4a16aff 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -87,4 +87,41 @@ class StreamTesterCocotbBoot extends SpinalTesterCocotbBase { override def pythonTestLocation: String = "tester/src/test/python/spinal/StreamTester" override def createToplevel: Component = new StreamTester override def noVhdl = true -} \ No newline at end of file +} + +object StreamTester2 { + case class BundleA() extends Bundle{ + val a = UInt(8 bit) + val b = Bool() + } + + class StreamTester2 extends Component{ + val fifoA = new StreamFifo(BundleA(),16) + val fifoAPush = slave(cloneOf(fifoA.io.push)) + val fifoAPop = master(cloneOf(fifoA.io.pop)) + val fifoAOccupancy = out(cloneOf(fifoA.io.occupancy)) + fifoA.io.push << fifoAPush + fifoA.io.pop >> fifoAPop + fifoA.io.occupancy <> fifoAOccupancy + assert(2 == LatencyAnalysis(fifoAPush.a,fifoAPop.a)) + assert(1 == LatencyAnalysis(fifoAPop.ready,fifoAPush.ready)) + + + val fifoB = new StreamFifoLowLatency(BundleA(),16) + val fifoBPush = slave(cloneOf(fifoB.io.push)) + val fifoBPop = master(cloneOf(fifoB.io.pop)) + val fifoBOccupancy = out(cloneOf(fifoB.io.occupancy)) + fifoB.io.push << fifoBPush + fifoB.io.pop >> fifoBPop + fifoB.io.occupancy <> fifoBOccupancy + assert(0 == LatencyAnalysis(fifoBPush.a,fifoBPop.a)) + assert(1 == LatencyAnalysis(fifoBPop.ready,fifoBPush.ready)) + } +} + +class StreamTester2CocotbBoot extends SpinalTesterCocotbBase { + override def getName: String = "StreamTester2" + override def pythonTestLocation: String = "tester/src/test/python/spinal/StreamTester2" + override def createToplevel: Component = new StreamTester2.StreamTester2 + override def backendConfig(config: SpinalConfig): SpinalConfig = config +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/StreamTester2.scala b/tester/src/test/scala/spinal/tester/scalatest/StreamTester2.scala deleted file mode 100644 index 27ed578d61..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/StreamTester2.scala +++ /dev/null @@ -1,42 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.lib._ - - -object StreamTester2 { - case class BundleA() extends Bundle{ - val a = UInt(8 bit) - val b = Bool() - } - - class StreamTester2 extends Component{ - val fifoA = new StreamFifo(BundleA(),16) - val fifoAPush = slave(cloneOf(fifoA.io.push)) - val fifoAPop = master(cloneOf(fifoA.io.pop)) - val fifoAOccupancy = out(cloneOf(fifoA.io.occupancy)) - fifoA.io.push << fifoAPush - fifoA.io.pop >> fifoAPop - fifoA.io.occupancy <> fifoAOccupancy - assert(2 == LatencyAnalysis(fifoAPush.a,fifoAPop.a)) - assert(1 == LatencyAnalysis(fifoAPop.ready,fifoAPush.ready)) - - - val fifoB = new StreamFifoLowLatency(BundleA(),16) - val fifoBPush = slave(cloneOf(fifoB.io.push)) - val fifoBPop = master(cloneOf(fifoB.io.pop)) - val fifoBOccupancy = out(cloneOf(fifoB.io.occupancy)) - fifoB.io.push << fifoBPush - fifoB.io.pop >> fifoBPop - fifoB.io.occupancy <> fifoBOccupancy - assert(0 == LatencyAnalysis(fifoBPush.a,fifoBPop.a)) - assert(1 == LatencyAnalysis(fifoBPop.ready,fifoBPush.ready)) - } -} - -class StreamTester2CocotbBoot extends SpinalTesterCocotbBase { - override def getName: String = "StreamTester2" - override def pythonTestLocation: String = "tester/src/test/python/spinal/StreamTester2" - override def createToplevel: Component = new StreamTester2.StreamTester2 - override def backendConfig(config: SpinalConfig): SpinalConfig = config -} \ No newline at end of file From 828bd6c06bfdc0f7a6a48cb46e494aad66903d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 20:32:29 +0100 Subject: [PATCH 029/120] refactor: move MemTester --- .../src/test/scala/spinal/core/Mem.scala | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/MemTester.scala => core/src/test/scala/spinal/core/Mem.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/MemTester.scala b/core/src/test/scala/spinal/core/Mem.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/MemTester.scala rename to core/src/test/scala/spinal/core/Mem.scala index e277f3a485..c566ca5bdd 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/MemTester.scala +++ b/core/src/test/scala/spinal/core/Mem.scala @@ -1,11 +1,8 @@ -package spinal.tester.scalatest +package spinal.core -import spinal.core._ import spinal.lib._ import spinal.lib.bus.amba3.ahblite._ - - object MemTester extends App{ class MemTester extends Component { val mem = Mem(Bits(32 bits), 16) From b726221668683809d11257b99057208e78c05858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 20:35:49 +0100 Subject: [PATCH 030/120] refactor: move InOutTester --- .../src/test/scala/spinal/core/IODirection.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/InOutTester.scala => core/src/test/scala/spinal/core/IODirection.scala (98%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/InOutTester.scala b/core/src/test/scala/spinal/core/IODirection.scala similarity index 98% rename from tester/src/test/scala/spinal/tester/scalatest/InOutTester.scala rename to core/src/test/scala/spinal/core/IODirection.scala index 63e0da0fe1..971a5d1b2b 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/InOutTester.scala +++ b/core/src/test/scala/spinal/core/IODirection.scala @@ -18,13 +18,15 @@ * License along with this library. */ -package spinal.tester.scalatest +package spinal.core import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ + import spinal.lib._ import spinal.lib.io.{TriState, TriStateArray} +import spinal.tester.SpinalTesterCocotbBase + object InOutTester { def analogType = Bool() case class Bus() extends Bundle with IMasterSlave{ From 5d543eebf18c8766d1c6ed7830536cfe054ac051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 20:48:35 +0100 Subject: [PATCH 031/120] refactor: move GrayCounterTester --- .../main/scala/spinal/lib/GrayCounter.scala | 22 ++++++++++++++++ lib/src/main/scala/spinal/lib/Utils.scala | 20 --------------- .../test/scala/spinal/lib/GrayCounter.scala | 25 +++---------------- 3 files changed, 26 insertions(+), 41 deletions(-) create mode 100644 lib/src/main/scala/spinal/lib/GrayCounter.scala rename tester/src/test/scala/spinal/tester/scalatest/GrayCounterTester.scala => lib/src/test/scala/spinal/lib/GrayCounter.scala (78%) diff --git a/lib/src/main/scala/spinal/lib/GrayCounter.scala b/lib/src/main/scala/spinal/lib/GrayCounter.scala new file mode 100644 index 0000000000..ac2b2b4ad7 --- /dev/null +++ b/lib/src/main/scala/spinal/lib/GrayCounter.scala @@ -0,0 +1,22 @@ +package spinal.lib + +import spinal.core._ + +object GrayCounter { + def apply(width: Int, enable: Bool): UInt = { + val gray = RegInit(U(0, width bit)) + val even = RegInit(True) + val word = Cat(True, gray(width - 3 downto 0), even) + when(enable) { + var found = False + for (i <- 0 until width) { + when(word(i) && !found) { + gray(i) := !gray(i) + found \= True + } + } + even := !even + } + return gray + } +} diff --git a/lib/src/main/scala/spinal/lib/Utils.scala b/lib/src/main/scala/spinal/lib/Utils.scala index 57f0d1076e..9a0eb54dfc 100644 --- a/lib/src/main/scala/spinal/lib/Utils.scala +++ b/lib/src/main/scala/spinal/lib/Utils.scala @@ -383,26 +383,6 @@ object fromGray { } } -object GrayCounter { - def apply(width: Int, enable: Bool): UInt = { - val gray = RegInit(U(0, width bit)) - val even = RegInit(True) - val word = Cat(True, gray(width - 3 downto 0), even) - when(enable) { - var found = False - for (i <- 0 until width) { - when(word(i) && !found) { - gray(i) := !gray(i) - found \= True - } - } - even := !even - } - return gray - } -} - - /****************************************************************************** * Big-Endian <-> Little-Endian */ diff --git a/tester/src/test/scala/spinal/tester/scalatest/GrayCounterTester.scala b/lib/src/test/scala/spinal/lib/GrayCounter.scala similarity index 78% rename from tester/src/test/scala/spinal/tester/scalatest/GrayCounterTester.scala rename to lib/src/test/scala/spinal/lib/GrayCounter.scala index f27aa119a7..7c237c7857 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/GrayCounterTester.scala +++ b/lib/src/test/scala/spinal/lib/GrayCounter.scala @@ -1,21 +1,14 @@ -package spinal.tester.scalatest +package spinal.lib import spinal.core._ -import spinal.lib._ -import spinal.tester.scalatest.GrayCounterTester.GrayCounterTester -import language.postfixOps - -object GrayCounterTester { +import spinal.tester.SpinalTesterCocotbBase +object GrayCounterTester { class GrayCnt(size : Int = 4) extends Component { - - // All IO signals for the Gray counter val io = new Bundle { - // Counter output port val gval = out UInt(size bits) - } // Helper bit for toggling @@ -32,7 +25,6 @@ object GrayCounterTester { // Handle all 'middle' bits for(i <- 1 to size - 2) { - // This equation checks the 0^* pattern val tmp = cnt(i - 1) && cnt(i - 2 downto 0).asBools.fold(True)((lastResult,cntBit) => lastResult && !cntBit) && toggle @@ -46,7 +38,6 @@ object GrayCounterTester { // Map the register to the output logic; io.gval := cnt - } class GrayCounterTester(n: Int) extends Component { @@ -58,16 +49,8 @@ object GrayCounterTester { } - -//class GrayCounterTesterGhdlBoot extends SpinalTesterGhdlBase { -// override def getName: String = "GrayCounterTester" -// -// withWaveform = true -// override def createToplevel: Component = new GrayCounterTester(8) -//} - class GrayCounterTesterCocotbBoot extends SpinalTesterCocotbBase { override def getName: String = "GrayCounterTester" override def pythonTestLocation: String = "tester/src/test/python/spinal/GrayCounterTester" - override def createToplevel: Component = new GrayCounterTester(8) + override def createToplevel: Component = new GrayCounterTester.GrayCounterTester(8) } \ No newline at end of file From ec9a1b63e5b41e65a2553e273fbf15f65081ae22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 20:57:34 +0100 Subject: [PATCH 032/120] refactor: move UsbDeviceCtrlTester --- .../scala/spinal/lib/com/usb/udc/UsbDeviceCtrl.scala | 5 ++--- .../scala/spinal/lib/com/usb/udc/UsbDeviceCtrl.scala | 11 ++++++----- 2 files changed, 8 insertions(+), 8 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/UsbDeviceCtrlTester.scala => lib/src/test/scala/spinal/lib/com/usb/udc/UsbDeviceCtrl.scala (99%) diff --git a/lib/src/main/scala/spinal/lib/com/usb/udc/UsbDeviceCtrl.scala b/lib/src/main/scala/spinal/lib/com/usb/udc/UsbDeviceCtrl.scala index bd67eb5a94..23547f516b 100644 --- a/lib/src/main/scala/spinal/lib/com/usb/udc/UsbDeviceCtrl.scala +++ b/lib/src/main/scala/spinal/lib/com/usb/udc/UsbDeviceCtrl.scala @@ -1,13 +1,12 @@ package spinal.lib.com.usb.udc import spinal.core._ -import spinal.lib import spinal.lib._ + import spinal.lib.bus.bmb._ import spinal.lib.bus.misc.MaskMapping -import spinal.lib.com.eth.{Crc, CrcKind} import spinal.lib.com.usb._ -import spinal.lib.com.usb.ohci.{OhciPortParameter, UsbOhci, UsbOhciParameter, UsbPid} +import spinal.lib.com.usb.ohci.UsbPid import spinal.lib.eda.bench.{Bench, Rtl, XilinxStdTargets} import spinal.lib.fsm._ diff --git a/tester/src/test/scala/spinal/tester/scalatest/UsbDeviceCtrlTester.scala b/lib/src/test/scala/spinal/lib/com/usb/udc/UsbDeviceCtrl.scala similarity index 99% rename from tester/src/test/scala/spinal/tester/scalatest/UsbDeviceCtrlTester.scala rename to lib/src/test/scala/spinal/lib/com/usb/udc/UsbDeviceCtrl.scala index 3f1bc99956..9f8fa3d188 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/UsbDeviceCtrlTester.scala +++ b/lib/src/test/scala/spinal/lib/com/usb/udc/UsbDeviceCtrl.scala @@ -1,8 +1,13 @@ -package spinal.tester.scalatest +package spinal.lib.com.usb.udc import org.scalatest.funsuite.AnyFunSuite + +import scala.collection.mutable +import scala.util.Random + import spinal.core._ import spinal.core.sim._ + import spinal.lib.bus.bmb.BmbParameter import spinal.lib.bus.bmb.sim.BmbDriver import spinal.lib.bus.misc.SizeMapping @@ -10,12 +15,8 @@ import spinal.lib.com.usb.ohci.UsbPid import spinal.lib.com.usb.phy.UsbDevicePhyNative import spinal.lib.com.usb.sim.UsbLsFsPhyAbstractIoAgent import spinal.lib.com.usb.udc.UsbDeviceCtrl.{Regs, Status} -import spinal.lib.com.usb.udc.{UsbDeviceCtrl, UsbDeviceCtrlParameter} import spinal.lib.sim.MemoryRegionAllocator -import scala.collection.mutable -import scala.util.Random - case class UsbDeviceCtrlTesterTop() extends Component { val ctrlCd = ClockDomain.external("ctrlCd", frequency = FixedFrequency(100 MHz)) val phyCd = ClockDomain.external("phyCd", frequency = FixedFrequency(48 MHz)) From d1b74107c2deb8998e3470e3a870ae5a51da3ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 21:00:27 +0100 Subject: [PATCH 033/120] refactor: remove empty files --- .../tester/scalatest/I2CIoMasterTester.scala | 36 ---- .../scalatest/SdramXdrDdr3S7Cocotb.scala | 145 ------------- .../tester/scalatest/SdramXdrSdrCocotb.scala | 204 ------------------ .../tester/scalatest/SpinalSimUsbTester.scala | 64 ------ 4 files changed, 449 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/I2CIoMasterTester.scala delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SdramXdrDdr3S7Cocotb.scala delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SdramXdrSdrCocotb.scala delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimUsbTester.scala diff --git a/tester/src/test/scala/spinal/tester/scalatest/I2CIoMasterTester.scala b/tester/src/test/scala/spinal/tester/scalatest/I2CIoMasterTester.scala deleted file mode 100644 index 14d726a31e..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/I2CIoMasterTester.scala +++ /dev/null @@ -1,36 +0,0 @@ -///* -// * SpinalHDL -// * Copyright (c) Dolu, All rights reserved. -// * -// * This library is free software; you can redistribute it and/or -// * modify it under the terms of the GNU Lesser General Public -// * License as published by the Free Software Foundation; either -// * version 3.0 of the License, or (at your option) any later version. -// * -// * This library is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// * Lesser General Public License for more details. -// * -// * You should have received a copy of the GNU Lesser General Public -// * License along with this library. -// */ -// -//package spinal.tester.scalatest -// -//import spinal.core._ -//import spinal.lib._ -//import spinal.lib.com.i2c._ -// -// -//class I2CIoMasterTester extends SpinalTesterCocotbBase { -// override def getName: String = "I2cIoMasterTester" -// override def pythonTestLocation: String = "tester/src/test/python/spinal/I2CTester2/IoMasterTester" -// override def createToplevel: Component = new I2cIoMaster(I2cIoMasterGenerics( -// samplingSize = 3, -// samplingClockDividerWidth = 10 bits, -// timerClockDividerWidth = 20 bits, -// timeoutBaudRatioLog2 = 5 -// )) -//} -// diff --git a/tester/src/test/scala/spinal/tester/scalatest/SdramXdrDdr3S7Cocotb.scala b/tester/src/test/scala/spinal/tester/scalatest/SdramXdrDdr3S7Cocotb.scala deleted file mode 100644 index 9c78343cec..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SdramXdrDdr3S7Cocotb.scala +++ /dev/null @@ -1,145 +0,0 @@ -//package spinal.tester.scalatest -// -//import spinal.core._ -//import spinal.lib.bus.bmb._ -//import spinal.lib.memory.sdram.sdr.{MT41K128M16JT, MT48LC16M16A2} -//import spinal.lib.memory.sdram.xdr.{BmbPortParameter, CoreParameter, CtrlParameter, CtrlWithPhy, CtrlWithoutPhy, mt41k128m16jt_model, mt48lc16m16a2_model} -//import spinal.lib._ -//import spinal.lib.bus.amba3.apb.{Apb3, Apb3SlaveFactory} -//import spinal.lib.eda.bench.Rtl -//import spinal.lib.memory.sdram.xdr.phy.{SdrInferedPhy, XilinxS7Phy} -// -////CONFIGURE_OPTS="LDFLAGS=-m32 CFLAGS=-m32 --enable-shared" LD_LIBRARY_PATH=`pwd`/versions/2.7.13/lib:$LD_LIBRARY_PATH pyenv install 2.7.13 -vfk -// -//case class SdramXdrDdr3S7TesterCocotbTop() extends Component{ -// -// val clk0, clk90, rst0 = in Bool() -// val serdesClk0, serdesClk90 = in Bool() -// -// -// Clock.sync(clk0, clk90) -// Clock.sync(clk0, serdesClk0) -// Clock.sync(clk0, serdesClk90) -// -// -// val system = new ClockingArea(ClockDomain(clk0, rst0)) { -// // val dq = Analog(Bits(16 bits)) -// -// val sl = MT41K128M16JT.layout -// val cp = CtrlParameter( -// core = CoreParameter( -// portTockenMin = 4, -// portTockenMax = 8, -// timingWidth = 4, -// refWidth = 16, -// writeLatencies = List(3), -// readLatencies = List(5) -// ), -// ports = Seq( -// BmbPortParameter( -// bmb = BmbParameter( -// addressWidth = sl.byteAddressWidth, -// dataWidth = 64, -// lengthWidth = 4, -// sourceWidth = 3, -// contextWidth = 8 -// ), -// cmdBufferSize = 16, -// dataBufferSize = 16, -// rspBufferSize = 16, -// clockDomain = ClockDomain.current -// )/*, -// -// BmbPortParameter( -// bmb = BmbParameter( -// addressWidth = sl.byteAddressWidth, -// dataWidth = 16, -// lengthWidth = 4, -// sourceWidth = 5, -// contextWidth = 12 -// ), -// cmdBufferSize = 2, -// rspBufferSize = 5 -// ), -// -// BmbPortParameter( -// bmb = BmbParameter( -// addressWidth = sl.byteAddressWidth, -// dataWidth = 16, -// lengthWidth = 5, -// sourceWidth = 6, -// contextWidth = 16 -// ), -// cmdBufferSize = 8, -// rspBufferSize = 2 -// )*/ -// ) -// ) -// -// val io = new Bundle { -// val ctrlApb = slave(Apb3(12, 32)) -// val phyApb = slave(Apb3(12, 32)) -// val ports = Vec(cp.ports.map(p => slave(Bmb(p.bmb)))) -// } -// -// val phy = XilinxS7Phy(sl, clkRatio = 2, ClockDomain(clk90), ClockDomain(serdesClk0), ClockDomain(serdesClk90)) -// phy.driveFrom(Apb3SlaveFactory(io.phyApb)) -// -// phy.children.foreach { -// case bb: BlackBox => bb.clearBlackBox() -// case _ => -// } -// -// val ctrl = new CtrlWithoutPhy(cp, phy.pl) -// ctrl.io.bmb <> io.ports -// ctrl.io.apb <> io.ctrlApb -// ctrl.io.phy <> phy.io.ctrl -// -// -// val sdram = mt41k128m16jt_model() -// sdram.rst_n := phy.io.memory.RESETn -// sdram.ck := phy.io.memory.CK -// sdram.ck_n := phy.io.memory.CKn -// sdram.cke := phy.io.memory.CKE -// sdram.cs_n := phy.io.memory.CSn -// sdram.ras_n := phy.io.memory.RASn -// sdram.cas_n := phy.io.memory.CASn -// sdram.we_n := phy.io.memory.WEn -// sdram.odt := phy.io.memory.ODT -// sdram.ba := phy.io.memory.BA -// sdram.addr := phy.io.memory.ADDR -// -// val dq = Analog(Bits(16 bits)) -// val dqs = Analog(Bits(2 bits)) -// val dqs_n = Analog(Bits(2 bits)) -// val dm_tdqs = Analog(Bits(2 bits)) -// -// dq := sdram.dq -// dqs := sdram.dqs -// dqs_n := sdram.dqs_n -// dm_tdqs := sdram.dm_tdqs -// -// -// dq := phy.io.memory.DQ -// dqs := phy.io.memory.DQS -// dqs_n := phy.io.memory.DQSn -// -// // dq := B(0, widthOf(sdram.dq) bits) -// // dqs := B(0, widthOf(sdram.dqs) bits) -// // dqs_n := B(0, widthOf(sdram.dqs_n) bits) -// // dm_tdqs := B(0, widthOf(sdram.dm_tdqs) bits) -// -// } -// -//} -// -// -//class SdramXdrDdr3S7TesterCocotb extends SpinalTesterCocotbBase { -// override def getName: String = "SdramXdrDdr3S7TesterCocotbTop" -// override def pythonTestLocation: String = "tester/src/test/python/spinal/SdramXdr/Ddr3S7Tester" -// override def createToplevel: Component = { -// SdramXdrDdr3S7TesterCocotbTop().setDefinitionName(getName) -// } -// override def noVhdl = true -// withWaveform = true -//} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SdramXdrSdrCocotb.scala b/tester/src/test/scala/spinal/tester/scalatest/SdramXdrSdrCocotb.scala deleted file mode 100644 index 1ea8e02661..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SdramXdrSdrCocotb.scala +++ /dev/null @@ -1,204 +0,0 @@ -//package spinal.tester.scalatest -// -//import spinal.core._ -//import spinal.lib.bus.bmb._ -//import spinal.lib.memory.sdram.sdr.MT48LC16M16A2 -//import spinal.lib.memory.sdram.xdr.{BmbPortParameter, CoreParameter, CtrlWithPhy, CtrlParameter, mt48lc16m16a2_model} -//import spinal.lib._ -//import spinal.lib.bus.amba3.apb.Apb3 -//import spinal.lib.eda.bench.Rtl -//import spinal.lib.memory.sdram.xdr.phy.SdrInferedPhy -// -//case class SdramSdrTesterCocotbTop() extends Component{ -// val sl = MT48LC16M16A2.layout -// val cp = CtrlParameter( -// core = CoreParameter( -// portTockenMin = 4, -// portTockenMax = 8, -// timingWidth = 4, -// refWidth = 16, -// writeLatencies = List(0), -// readLatencies = List(2) -// ), -// ports = Seq( -// BmbPortParameter( -// bmb = BmbParameter( -// addressWidth = sl.byteAddressWidth, -// dataWidth = 16, -// lengthWidth = 3, -// sourceWidth = 3, -// contextWidth = 8 -// ), -// clockDomain = ClockDomain.current, -// cmdBufferSize = 4, -// dataBufferSize = 6, -// rspBufferSize = 4 -// ), -// -// BmbPortParameter( -// bmb = BmbParameter( -// addressWidth = sl.byteAddressWidth, -// dataWidth = 16, -// lengthWidth = 4, -// sourceWidth = 5, -// contextWidth = 12 -// ), -// clockDomain = ClockDomain.current, -// cmdBufferSize = 2, -// dataBufferSize = 2, -// rspBufferSize = 5 -// ), -// -// BmbPortParameter( -// bmb = BmbParameter( -// addressWidth = sl.byteAddressWidth, -// dataWidth = 16, -// lengthWidth = 5, -// sourceWidth = 6, -// contextWidth = 16 -// ), -// clockDomain = ClockDomain.current, -// cmdBufferSize = 8, -// dataBufferSize = 8, -// rspBufferSize = 2 -// ) -// ) -// ) -// -// val io = new Bundle { -// val apb = slave(Apb3(12, 32)) -// val ports = Vec(cp.ports.map(p => slave(Bmb(p.bmb)))) -// } -// -// val dq = Analog(Bits(16 bits)) -// -// val ctrl = new CtrlWithPhy(cp, SdrInferedPhy(sl)) -// io.ports <> ctrl.io.bmb -// io.apb <> ctrl.io.apb -// when(ctrl.io.memory.DQ.writeEnable) { -// dq := ctrl.io.memory.DQ.write -// } -// ctrl.io.memory.DQ.read := dq -// -// val sdram = mt48lc16m16a2_model() -// sdram.Addr := ctrl.io.memory.ADDR -// sdram.Ba := ctrl.io.memory.BA -// sdram.Clk := ClockDomain.current.readClockWire -// sdram.Cke := ctrl.io.memory.CKE -// sdram.Cs_n := ctrl.io.memory.CSn -// sdram.Ras_n := ctrl.io.memory.RASn -// sdram.Cas_n := ctrl.io.memory.CASn -// sdram.We_n := ctrl.io.memory.WEn -// sdram.Dqm := ctrl.io.memory.DQM -// dq := sdram.Dq -// -//} -// -// -////TODO REGRESSION -////class SdramSdrTesterCocotb extends SpinalTesterCocotbBase { -//// override def getName: String = "SdramSdrTesterCocotbTop" -//// override def pythonTestLocation: String = "tester/src/test/python/spinal/SdramXdr/SdrTester" -//// override def createToplevel: Component = { -//// SdramSdrTesterCocotbTop().setDefinitionName(getName) -//// } -//// override def noVhdl = true -//// withWaveform = true -////} -// -//import spinal.core._ -//import spinal.lib.eda.bench._ -// -////object SdramSdrSyntBench extends App{ -//// val sl = MT48LC16M16A2.layout.copy(bankWidth = 3) -//// val cp = CtrlParameter( -//// core = CoreParameter( -//// portTockenMin = 4, -//// portTockenMax = 8, -//// rspFifoSize = 4, -//// timingWidth = 4, -//// refWidth = 16, -//// writeLatencies = List(0), -//// readLatencies = List(2) -//// ), -//// ports = Seq( -//// BmbPortParameter( -//// bmb = BmbParameter( -//// addressWidth = sl.byteAddressWidth, -//// dataWidth = 16, -//// lengthWidth = 3, -//// sourceWidth = 0, -//// contextWidth = 0 -//// ), -//// clockDomain = ClockDomain.current, -//// cmdBufferSize = 4, -//// rspBufferSize = 4 -//// ), -//// -//// BmbPortParameter( -//// bmb = BmbParameter( -//// addressWidth = sl.byteAddressWidth, -//// dataWidth = 16, -//// lengthWidth = 4, -//// sourceWidth = 0, -//// contextWidth = 0 -//// ), -//// clockDomain = ClockDomain.current, -//// cmdBufferSize = 2, -//// rspBufferSize = 5 -//// )/*, -//// -//// BmbPortParameter( -//// bmb = BmbParameter( -//// addressWidth = sl.byteAddressWidth, -//// dataWidth = 16, -//// lengthWidth = 5, -//// sourceWidth = 0, -//// contextWidth = 0 -//// ), -//// clockDomain = ClockDomain.current, -//// cmdBufferSize = 8, -//// rspBufferSize = 2 -//// )*//*, -//// -//// BmbPortParameter( -//// bmb = BmbParameter( -//// addressWidth = sl.byteAddressWidth, -//// dataWidth = 16, -//// lengthWidth = 5, -//// sourceWidth = 0, -//// contextWidth = 0 -//// ), -//// clockDomain = ClockDomain.current, -//// cmdBufferSize = 8, -//// rspBufferSize = 2 -//// )*/ -//// ) -//// ) -//// -//// -//// val ports4 = new Rtl { -//// override def getName(): String = "Port4" -//// override def getRtlPath(): String = "Port4.v" -//// SpinalVerilog({ -//// val c = new CtrlWithPhy(cp, SdrInferedPhy(sl)).setDefinitionName(getRtlPath().split("\\.").head) -//// c -//// }) -//// } -//// -//// -//// val rtls = List(ports4) -//// -//// val targets = XilinxStdTargets( -//// vivadoArtix7Path = "/media/miaou/HD/linux/Xilinx/Vivado/2018.3/bin" -//// ) ++ AlteraStdTargets( -//// quartusCycloneIVPath = "/media/miaou/HD/linux/intelFPGA_lite/18.1/quartus/bin", -//// quartusCycloneVPath = "/media/miaou/HD/linux/intelFPGA_lite/18.1/quartus/bin" -//// ) -//// -//// Bench(rtls, targets, "/media/miaou/HD/linux/tmp") -//// -//// -//// -//// -////} \ No newline at end of file diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimUsbTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimUsbTester.scala deleted file mode 100644 index 702e444ae0..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimUsbTester.scala +++ /dev/null @@ -1,64 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.core.sim._ -import spinal.lib._ -import spinal.lib.com.eth._ -import spinal.lib.com.usb.phy.{UsbHubLsFs, UsbLsFsPhy} -import spinal.lib.sim.{StreamDriver, StreamMonitor, StreamReadyRandomizer} - -import scala.collection.mutable -import scala.util.Random - -class SpinalSimUsbTester extends AnyFunSuite{ -// implicit class UsbLsFsCtrlPimper(self : UsbHubLsFs.Ctrl)(implicit cd : ClockDomain){ -// def init(): Unit = { -// self.tx.kind #= UsbHubLsFs.TxKind.NONE -// cd.waitSampling(10) -// } -// -// def issue(cmd : UsbHubLsFs.TxKind.E): Unit ={ -// self.tx.kind #= cmd -// cd.waitSamplingWhere(self.tx.ready.toBoolean) -// self.tx.kind #= UsbHubLsFs.TxKind.NONE -// } -// -// def reset(): Unit ={ -// issue(UsbHubLsFs.TxKind.RESET) -// } -// def suspend(): Unit ={ -// issue(UsbHubLsFs.TxKind.SUSPEND) -// } -// def resume(): Unit ={ -// issue(UsbHubLsFs.TxKind.RESUME) -// } -// def packet(bytes : Seq[Int]): Unit ={ -// for((byte, i) <- bytes.zipWithIndex) { -// self.tx.data #= byte -// self.tx.last #= i == bytes.length-1 -// issue(UsbHubLsFs.TxKind.PACKET) -// } -// } -// -// } - -// test("UsbLsFsPhy"){ -// SimConfig.withFstWave.compile(UsbLsFsPhy(4)).doSim{dut => -// implicit val cd = dut.clockDomain -// cd.forkStimulus(20833) -// -// dut.io.ctrl.fullSpeed #= true -// dut.io.ctrl.init() -// dut.io.ctrl.reset() -// cd.waitSampling(100) -// dut.io.ctrl.suspend() -// cd.waitSampling(100) -// dut.io.ctrl.resume() -// cd.waitSampling(100) -// dut.io.ctrl.packet(List(0x00, 0xAA, 0xAA, 0x55, 0x55, 0x00, 0xFF, 0xFF)) -// dut.io.ctrl.packet(List(0x00, 0xAA, 0xAA, 0x55, 0x55, 0x00, 0xFF, 0xFF)) -// cd.waitSampling(100) -// } -// } -} From 411933c2e6f6b49613172b05d886b74792d05118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 21:02:45 +0100 Subject: [PATCH 034/120] refactor: move SdramCtrlTester --- .../spinal/lib/memory/sdram/sdr/SdramCtrl.scala | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SdramCtrlTester.scala => lib/src/test/scala/spinal/lib/memory/sdram/sdr/SdramCtrl.scala (54%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SdramCtrlTester.scala b/lib/src/test/scala/spinal/lib/memory/sdram/sdr/SdramCtrl.scala similarity index 54% rename from tester/src/test/scala/spinal/tester/scalatest/SdramCtrlTester.scala rename to lib/src/test/scala/spinal/lib/memory/sdram/sdr/SdramCtrl.scala index 2761dbc5d6..68f419ccc9 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SdramCtrlTester.scala +++ b/lib/src/test/scala/spinal/lib/memory/sdram/sdr/SdramCtrl.scala @@ -1,18 +1,17 @@ -package spinal.tester.scalatest +package spinal.lib.memory.sdram.sdr import spinal.core._ -import spinal.lib._ -import spinal.lib.memory.sdram._ -import spinal.lib.memory.sdram.sdr.{MT48LC16M16A2, SdramCtrl} +import spinal.tester.SpinalTesterCocotbBase class SdramCtrlTesterCocotbBoot extends SpinalTesterCocotbBase { override def getName: String = "SdramCtrlTester" override def pythonTestLocation: String = "tester/src/test/python/spinal/SdramCtrlTester" override def createToplevel: Component = { val device = MT48LC16M16A2 - SdramCtrl(device.layout,device.timingGrade7.copy(tPOW = 5 us),CAS = 2,UInt(8 bits)).setDefinitionName(getName) + SdramCtrl(device.layout, device.timingGrade7.copy(tPOW = 5 us), CAS = 2, UInt(8 bits)).setDefinitionName(getName) } - override def backendConfig(config: SpinalConfig): SpinalConfig = config.copy(defaultClockDomainFrequency = FixedFrequency(133 MHz)) + override def backendConfig(config: SpinalConfig): SpinalConfig = + config.copy(defaultClockDomainFrequency = FixedFrequency(133 MHz)) override def noVhdl = true -} \ No newline at end of file +} From f61be711eb6f9b0b6e9197fbda78dd70e2c9d758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 21:08:04 +0100 Subject: [PATCH 035/120] refactor: move I2cSlaveTester --- .../scala/spinal/lib/com/i2c/I2CSlave.scala | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/I2CSlaveTester.scala => lib/src/test/scala/spinal/lib/com/i2c/I2CSlave.scala (80%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/I2CSlaveTester.scala b/lib/src/test/scala/spinal/lib/com/i2c/I2CSlave.scala similarity index 80% rename from tester/src/test/scala/spinal/tester/scalatest/I2CSlaveTester.scala rename to lib/src/test/scala/spinal/lib/com/i2c/I2CSlave.scala index 76bab804c7..ce8daddab0 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/I2CSlaveTester.scala +++ b/lib/src/test/scala/spinal/lib/com/i2c/I2CSlave.scala @@ -16,25 +16,24 @@ * License along with this library. */ -package spinal.tester.scalatest +package spinal.lib.com.i2c import spinal.core._ -import spinal.lib._ -import spinal.lib.com.i2c._ +import spinal.tester.SpinalTesterCocotbBase class I2cSlaveTester extends SpinalTesterCocotbBase { override def getName: String = "I2cSlaveTester" override def pythonTestLocation: String = "tester/src/test/python/spinal/I2CTester2/I2cSlaveTester" override def createToplevel: Component = { - val ret = new I2cSlave(I2cSlaveGenerics( - samplingWindowSize = 3, - samplingClockDividerWidth = 10 bits, - timeoutWidth = 20 bits - )) + val ret = new I2cSlave( + I2cSlaveGenerics( + samplingWindowSize = 3, + samplingClockDividerWidth = 10 bits, + timeoutWidth = 20 bits + ) + ) ret.io.bus.cmd.kind.fixEncoding(binarySequential) ret } - } - From c47ca397f203d248bc5567d954661abce994bb09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 21:12:27 +0100 Subject: [PATCH 036/120] refactor: remove useless file --- .../spinal/lib/experimental/chisel/Test1.scala | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 lib/src/test/scala/spinal/lib/experimental/chisel/Test1.scala diff --git a/lib/src/test/scala/spinal/lib/experimental/chisel/Test1.scala b/lib/src/test/scala/spinal/lib/experimental/chisel/Test1.scala deleted file mode 100644 index 5c275848da..0000000000 --- a/lib/src/test/scala/spinal/lib/experimental/chisel/Test1.scala +++ /dev/null @@ -1,15 +0,0 @@ -package spinal.lib.experimental.chisel - - -object Test1 { - class TopLevel extends Module{ - val io = new Bundle{ - val a,b,c = new Bool().asInput() - val result = new Bool().asOutput() - } - io.result := io.a || io.b || io.c - } - def main(args: Array[String]) { - spinal.core.SpinalVerilog(new TopLevel) - } -} From a7c82367f5a2523c563c9dec3caefd0e406a9df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 21:12:43 +0100 Subject: [PATCH 037/120] refactor: move SerdesSerialTester --- .../experimental/com/serial}/SerdesSerialTester.scala | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) rename {tester/src/test/scala/spinal/tester/scalatest => lib/src/test/scala/spinal/lib/experimental/com/serial}/SerdesSerialTester.scala (90%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SerdesSerialTester.scala b/lib/src/test/scala/spinal/lib/experimental/com/serial/SerdesSerialTester.scala similarity index 90% rename from tester/src/test/scala/spinal/tester/scalatest/SerdesSerialTester.scala rename to lib/src/test/scala/spinal/lib/experimental/com/serial/SerdesSerialTester.scala index db51044ff7..f420ad53c6 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SerdesSerialTester.scala +++ b/lib/src/test/scala/spinal/lib/experimental/com/serial/SerdesSerialTester.scala @@ -1,20 +1,17 @@ -package spinal.tester.scalatest +package spinal.lib.experimental.com.serial import spinal.core._ import spinal.lib._ -import spinal.lib.experimental.com.serial._ -object SerdesSerialTester { +import spinal.tester.SpinalTesterGhdlBase +object SerdesSerialTester { class BundleA extends Bundle { val a = UInt(8 bit) val b = Bool() } - } -import spinal.tester.scalatest.StreamTester._ - class SerdesSerialTester extends Component { val io = new Bundle { val rx = slave Flow (Bits(8 bit)) From 81249ea1c757ad12deba25a5c1f493c394155ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 21:17:51 +0100 Subject: [PATCH 038/120] refactor: move RomTester --- core/src/test/scala/spinal/core/Mem.scala | 176 +++++++++++++++- .../spinal/tester/scalatest/RomTester.scala | 192 ------------------ 2 files changed, 169 insertions(+), 199 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/RomTester.scala diff --git a/core/src/test/scala/spinal/core/Mem.scala b/core/src/test/scala/spinal/core/Mem.scala index c566ca5bdd..3a1ae7c8c3 100644 --- a/core/src/test/scala/spinal/core/Mem.scala +++ b/core/src/test/scala/spinal/core/Mem.scala @@ -3,6 +3,9 @@ package spinal.core import spinal.lib._ import spinal.lib.bus.amba3.ahblite._ +import spinal.tester.{SpinalTesterCocotbBase, SpinalTesterGhdlBase} +import org.scalatest.funsuite.AnyFunSuite + object MemTester extends App{ class MemTester extends Component { val mem = Mem(Bits(32 bits), 16) @@ -52,10 +55,169 @@ object MemTester extends App{ SpinalVhdl(new MemTester) } -//class MemTesterCocotbBoot extends SpinalTesterCocotbBase { -// override def getName: String = "MemTester" -// override def pythonTestLocation: String = "tester/src/test/python/spinal/MemTester" -// override def createToplevel: Component = new MemTester.MemTester -// override def backendConfig(config: SpinalConfig): SpinalConfig = config.dumpWave() -// override def noVhdl = true -//} \ No newline at end of file +object RomTester { + object MyEnum extends SpinalEnum{ + val a,b,c = newElement() + } + + class DataStruct extends Bundle{ + val bool = Bool() + val bits = Bits(9 bits) + val uint = UInt(10 bits) + val sint = SInt(11 bits) + val enumeration = MyEnum() + } + + class RomTester extends Component { + def lit(bool : Boolean,bits : Int,uint : Int,sint : Int,enumeration : MyEnum.E) = { + val data = new DataStruct + data.bool := Bool(bool) + data.bits := B(bits) + data.uint := U(uint) + data.sint := S(sint) + data.enumeration := enumeration + data + } + def initValues = List( + lit(false,0,0,0,MyEnum.a), + lit(true,0,0,0,MyEnum.a), + lit(false,0x1FF,0,0,MyEnum.a), + lit(false,0,0x3FF,0,MyEnum.a), + lit(false,0,0,-1,MyEnum.a), + lit(false,0,0,0,MyEnum.c), + lit(false,43,74,88,MyEnum.b) + ) + val rom = Mem(new DataStruct,initValues) + + val address = in UInt(3 bits) + val data = out(rom(address)) + } + + class RomTesterSymbols extends Component { + val rom = Mem(Bits(32 bits),8) init(Seq( + BigInt(0x01234567l), + BigInt(0x12345670l), + BigInt(0x10293857l), + BigInt(0x0abcfe23l), + BigInt(0x02938571l), + BigInt(0xabcfe230l), + BigInt(0x717833aal), + BigInt(0x17833aa6l) + )) + rom.write(U"000",B(0, 32 bits),False,B"0000") + val address = in UInt(3 bits) + val data = out(rom(address)) + } + + class RomTesterSymbolsSInt extends Component { + val rom = Mem(SInt(32 bits),8) init(Seq( + S(0x01234567, 32 bits), + S(0x12345670, 32 bits), + S(0x10293857, 32 bits), + S(0x0abcfe23, 32 bits), + S(0x02938571, 32 bits), + S(0xabcfe230, 32 bits), + S(0x717833aa, 32 bits), + S(0x17833aa6, 32 bits) + )) + rom.write(U"000",S(0, 32 bits),False,B"0000") + val address = in UInt(3 bits) + val data = out(rom(address)) + } +} + +import RomTester.{RomTesterSymbols, RomTesterSymbolsSInt} + +class RomTesterGhdlBoot extends SpinalTesterGhdlBase { + override def getName: String = "RomTester" + override def createToplevel: Component = new RomTester.RomTester +} + +class RomTesterCocotbBoot extends SpinalTesterCocotbBase { + override def getName: String = "RomTester" + override def pythonTestLocation: String = "tester/src/test/python/spinal/RomTester" + override def createToplevel: Component = new RomTester.RomTester + override def noVhdl = true + override def backendConfig(config: SpinalConfig) = config.copy(inlineRom = true) +} + +class RomTesterCocotbBoot2 extends SpinalTesterCocotbBase { + override def getName: String = "RomTester2" + override def pythonTestLocation: String = "tester/src/test/python/spinal/RomTester2" + override def createToplevel: Component = new RomTester.RomTester().setDefinitionName("RomTester2") + override def noVhdl = true + override def backendConfig(config: SpinalConfig) = config.copy(inlineRom = false) + + override def genVerilog: Unit = { + super.genVerilog + import scala.sys.process._ + s"rm $pythonTestLocation/RomTester2.v_toplevel_rom.bin".! + s"cp RomTester2.v_toplevel_rom.bin $pythonTestLocation".! + } +} + +class RomTesterCocotbBoot3 extends SpinalTesterCocotbBase { + override def getName: String = "RomTester2" + override def pythonTestLocation: String = "tester/src/test/python/spinal/RomTester3" + override def createToplevel: Component = new RomTester.RomTesterSymbols().setDefinitionName("RomTester3") + override def noVhdl = true + override def backendConfig(config: SpinalConfig) = config.copy(inlineRom = false) + + override def genVerilog: Unit = { + super.genVerilog + import scala.sys.process._ + for(i <- 0 to 3) { + s"rm $pythonTestLocation/RomTester3.v_toplevel_rom_symbol$i.bin".! + s"cp RomTester3.v_toplevel_rom_symbol$i.bin $pythonTestLocation".! + } + } +} + +class SpinalSimRomTester extends AnyFunSuite { + test("test1"){ + import spinal.core.sim._ + import spinal.sim._ + SimConfig.compile(new RomTesterSymbols()).doSim{ dut => + val rom = Seq( + BigInt(0x01234567l), + BigInt(0x12345670l), + BigInt(0x10293857l), + BigInt(0x0abcfe23l), + BigInt(0x02938571l), + BigInt(0xabcfe230l), + BigInt(0x717833aal), + BigInt(0x17833aa6l) + ) + + for(repeat <- 0 until 100){ + dut.address.randomize() + sleep(1) + assert(dut.data.toBigInt == rom(dut.address.toInt)) + } + + } + } + + test("testSInt"){ + import spinal.core.sim._ + import spinal.sim._ + SimConfig.compile(new RomTesterSymbolsSInt()).doSim{ dut => + val rom = Seq( + BigInt(0x01234567), + BigInt(0x12345670), + BigInt(0x10293857), + BigInt(0x0abcfe23), + BigInt(0x02938571), + BigInt(0xabcfe230), + BigInt(0x717833aa), + BigInt(0x17833aa6) + ) + + for(repeat <- 0 until 100){ + dut.address.randomize() + sleep(1) + assert(dut.data.toBigInt == rom(dut.address.toInt)) + } + } + } +} \ No newline at end of file diff --git a/tester/src/test/scala/spinal/tester/scalatest/RomTester.scala b/tester/src/test/scala/spinal/tester/scalatest/RomTester.scala deleted file mode 100644 index bdb8d478ca..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/RomTester.scala +++ /dev/null @@ -1,192 +0,0 @@ - - -/* - * SpinalHDL - * Copyright (c) Dolu, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ - -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.tester.scalatest.RomTester.{RomTesterSymbols, RomTesterSymbolsSInt} -object RomTester { - - object MyEnum extends SpinalEnum{ - val a,b,c = newElement() - } - - class DataStruct extends Bundle{ - val bool = Bool() - val bits = Bits(9 bits) - val uint = UInt(10 bits) - val sint = SInt(11 bits) - val enumeration = MyEnum() - } - - class RomTester extends Component { - def lit(bool : Boolean,bits : Int,uint : Int,sint : Int,enumeration : MyEnum.E) = { - val data = new DataStruct - data.bool := Bool(bool) - data.bits := B(bits) - data.uint := U(uint) - data.sint := S(sint) - data.enumeration := enumeration - data - } - def initValues = List( - lit(false,0,0,0,MyEnum.a), - lit(true,0,0,0,MyEnum.a), - lit(false,0x1FF,0,0,MyEnum.a), - lit(false,0,0x3FF,0,MyEnum.a), - lit(false,0,0,-1,MyEnum.a), - lit(false,0,0,0,MyEnum.c), - lit(false,43,74,88,MyEnum.b) - ) - val rom = Mem(new DataStruct,initValues) - - val address = in UInt(3 bits) - val data = out(rom(address)) - } - - class RomTesterSymbols extends Component { - - val rom = Mem(Bits(32 bits),8) init(Seq( - BigInt(0x01234567l), - BigInt(0x12345670l), - BigInt(0x10293857l), - BigInt(0x0abcfe23l), - BigInt(0x02938571l), - BigInt(0xabcfe230l), - BigInt(0x717833aal), - BigInt(0x17833aa6l) - )) - rom.write(U"000",B(0, 32 bits),False,B"0000") - val address = in UInt(3 bits) - val data = out(rom(address)) - } - class RomTesterSymbolsSInt extends Component { - - val rom = Mem(SInt(32 bits),8) init(Seq( - S(0x01234567, 32 bits), - S(0x12345670, 32 bits), - S(0x10293857, 32 bits), - S(0x0abcfe23, 32 bits), - S(0x02938571, 32 bits), - S(0xabcfe230, 32 bits), - S(0x717833aa, 32 bits), - S(0x17833aa6, 32 bits) - )) - rom.write(U"000",S(0, 32 bits),False,B"0000") - val address = in UInt(3 bits) - val data = out(rom(address)) - } -} - - -class RomTesterGhdlBoot extends SpinalTesterGhdlBase { - override def getName: String = "RomTester" - override def createToplevel: Component = new RomTester.RomTester -} - -class RomTesterCocotbBoot extends SpinalTesterCocotbBase { - override def getName: String = "RomTester" - override def pythonTestLocation: String = "tester/src/test/python/spinal/RomTester" - override def createToplevel: Component = new RomTester.RomTester - override def noVhdl = true - override def backendConfig(config: SpinalConfig) = config.copy(inlineRom = true) -} - -class RomTesterCocotbBoot2 extends SpinalTesterCocotbBase { - override def getName: String = "RomTester2" - override def pythonTestLocation: String = "tester/src/test/python/spinal/RomTester2" - override def createToplevel: Component = new RomTester.RomTester().setDefinitionName("RomTester2") - override def noVhdl = true - override def backendConfig(config: SpinalConfig) = config.copy(inlineRom = false) - - override def genVerilog: Unit = { - super.genVerilog - import scala.sys.process._ - s"rm $pythonTestLocation/RomTester2.v_toplevel_rom.bin".! - s"cp RomTester2.v_toplevel_rom.bin $pythonTestLocation".! - } -} - -class RomTesterCocotbBoot3 extends SpinalTesterCocotbBase { - override def getName: String = "RomTester2" - override def pythonTestLocation: String = "tester/src/test/python/spinal/RomTester3" - override def createToplevel: Component = new RomTester.RomTesterSymbols().setDefinitionName("RomTester3") - override def noVhdl = true - override def backendConfig(config: SpinalConfig) = config.copy(inlineRom = false) - - override def genVerilog: Unit = { - super.genVerilog - import scala.sys.process._ - for(i <- 0 to 3) { - s"rm $pythonTestLocation/RomTester3.v_toplevel_rom_symbol$i.bin".! - s"cp RomTester3.v_toplevel_rom_symbol$i.bin $pythonTestLocation".! - } - } -} - -class SpinalSimRomTester extends AnyFunSuite { - test("test1"){ - import spinal.core.sim._ - import spinal.sim._ - SimConfig.compile(new RomTesterSymbols()).doSim{ dut => - val rom = Seq( - BigInt(0x01234567l), - BigInt(0x12345670l), - BigInt(0x10293857l), - BigInt(0x0abcfe23l), - BigInt(0x02938571l), - BigInt(0xabcfe230l), - BigInt(0x717833aal), - BigInt(0x17833aa6l) - ) - - for(repeat <- 0 until 100){ - dut.address.randomize() - sleep(1) - assert(dut.data.toBigInt == rom(dut.address.toInt)) - } - - } - } - test("testSInt"){ - import spinal.core.sim._ - import spinal.sim._ - SimConfig.compile(new RomTesterSymbolsSInt()).doSim{ dut => - val rom = Seq( - BigInt(0x01234567), - BigInt(0x12345670), - BigInt(0x10293857), - BigInt(0x0abcfe23), - BigInt(0x02938571), - BigInt(0xabcfe230), - BigInt(0x717833aa), - BigInt(0x17833aa6) - ) - - for(repeat <- 0 until 100){ - dut.address.randomize() - sleep(1) - assert(dut.data.toBigInt == rom(dut.address.toInt)) - } - - } - } -} \ No newline at end of file From a90b6993203f0ca59862c1f36f037a5a04748219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 5 Dec 2022 21:26:52 +0100 Subject: [PATCH 039/120] refactor: move Axi4SharedOnChipRamTester --- .../spinal/lib/bus/amba4/axi/Axi4SharedOnChipRam.scala | 10 ++++++++++ .../bus/amba4/axi/Axi4SharedOnChipRamMultiPort.scala | 8 -------- 2 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SharedOnChipRam.scala rename tester/src/test/scala/spinal/tester/scalatest/Axi4SharedOnChipRamTester.scala => lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SharedOnChipRamMultiPort.scala (94%) diff --git a/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SharedOnChipRam.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SharedOnChipRam.scala new file mode 100644 index 0000000000..6b2260fd78 --- /dev/null +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SharedOnChipRam.scala @@ -0,0 +1,10 @@ +package spinal.lib.bus.amba4.axi + +import spinal.tester.SpinalTesterCocotbBase + +class Axi4SharedOnChipRamTester extends SpinalTesterCocotbBase { + override def getName = "Axi4SharedOnChipRamTester" + override def pythonTestLocation = "tester/src/test/python/spinal/Axi4SharedOnChipRamTester" + override def createToplevel = Axi4SharedOnChipRam(32, 4096, 4).setDefinitionName(getName) + override def noVhdl = true +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/Axi4SharedOnChipRamTester.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SharedOnChipRamMultiPort.scala similarity index 94% rename from tester/src/test/scala/spinal/tester/scalatest/Axi4SharedOnChipRamTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SharedOnChipRamMultiPort.scala index ef5ac77760..dfa04f4eee 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Axi4SharedOnChipRamTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4SharedOnChipRamMultiPort.scala @@ -5,14 +5,6 @@ import spinal.core._ import spinal.lib._ import spinal.lib.bus.amba4.axi._ - -class Axi4SharedOnChipRamTester extends SpinalTesterCocotbBase { - override def getName: String = "Axi4SharedOnChipRamTester" - override def pythonTestLocation: String = "tester/src/test/python/spinal/Axi4SharedOnChipRamTester" - override def createToplevel: Component = Axi4SharedOnChipRam(32,4096,4).setDefinitionName(getName) - override def noVhdl = true -} - import scala.collection.mutable import scala.util.Random import org.scalatest.funsuite.AnyFunSuite From bec42559cc2923b795f47caba833c0884a6478bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Wed, 7 Dec 2022 20:49:08 +0100 Subject: [PATCH 040/120] refactor: move Axi4SimAgentTester --- .../scala/spinal/lib/bus/amba4/axi/sim/Agent.scala | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/Axi4SimAgentTester.scala => lib/src/test/scala/spinal/lib/bus/amba4/axi/sim/Agent.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Axi4SimAgentTester.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axi/sim/Agent.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/Axi4SimAgentTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba4/axi/sim/Agent.scala index ed2aa79897..8ca49d37a2 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Axi4SimAgentTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axi/sim/Agent.scala @@ -1,18 +1,11 @@ -package spinal.tester.scalatest +package spinal.lib.bus.amba4.axi.sim import spinal.core._ import spinal.core.sim._ + import org.scalatest.funsuite.AnyFunSuite -import spinal.core.sim.SimCompiled + import spinal.lib._ -import spinal.lib.bus.amba4.axi.sim.{ - Axi4ReadOnlyMasterAgent, - Axi4ReadOnlyMonitor, - Axi4ReadOnlySlaveAgent, - Axi4WriteOnlyMasterAgent, - Axi4WriteOnlyMonitor, - Axi4WriteOnlySlaveAgent -} import spinal.lib.bus.amba4.axi.{Axi4, Axi4Config} import spinal.lib.bus.misc.SizeMapping From 61794c39739fcbf76543c3fef554fd9cc5d4f287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Wed, 7 Dec 2022 20:50:58 +0100 Subject: [PATCH 041/120] refactor: move Axi4UnburstTester --- .../test/scala/spinal/lib/bus/amba4/axi/Axi4Unburster.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/Axi4UnburstTester.scala => lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4Unburster.scala (98%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Axi4UnburstTester.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4Unburster.scala similarity index 98% rename from tester/src/test/scala/spinal/tester/scalatest/Axi4UnburstTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4Unburster.scala index 90823de1b0..2d2c49063b 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Axi4UnburstTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4Unburster.scala @@ -1,8 +1,9 @@ -package spinal.tester.scalatest +package spinal.lib.bus.amba4.axi import org.scalatest.funsuite.AnyFunSuite + import spinal.core.sim._ -import spinal.lib.bus.amba4.axi._ + import spinal.lib.bus.amba4.axi.sim.{Axi4ReadOnlyMasterAgent, Axi4ReadOnlyMonitor, Axi4ReadOnlySlaveAgent, Axi4WriteOnlyMasterAgent, Axi4WriteOnlyMonitor, Axi4WriteOnlySlaveAgent} import spinal.lib.bus.misc.SizeMapping import spinal.lib.sim.ScoreboardInOrder From fc835dbb85ebce39df80c3a13e24cbdadac53aba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Wed, 7 Dec 2022 21:47:00 +0100 Subject: [PATCH 042/120] refactor: CheckTester -> GenerationShould fail ... ps: sorry I had to prettify things here --- .scalafmt.conf | 37 +- .../spinal/tester/GenerationShould.scala | 24 + .../spinal/tester/CrossClockTester.scala | 181 ++++++++ ...cksTester.scala => GenerationShould.scala} | 417 ++++++++---------- .../scalatest/CrossClockCheckerTester.scala | 192 -------- ...nalSimBmbInterconnectGeneratorTester.scala | 8 +- 6 files changed, 433 insertions(+), 426 deletions(-) create mode 100644 tester/src/main/scala/spinal/tester/GenerationShould.scala create mode 100644 tester/src/test/scala/spinal/tester/CrossClockTester.scala rename tester/src/test/scala/spinal/tester/{scalatest/ChecksTester.scala => GenerationShould.scala} (50%) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/CrossClockCheckerTester.scala diff --git a/.scalafmt.conf b/.scalafmt.conf index 92dc1fca15..e5728d5df5 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,5 +1,40 @@ version = 3.6.0 runner.dialect = scala212 align.preset = some -maxColumn = 120 +align.tokens."+" = [ + { + code = "=" + owners = [{ + regex = "Defn\\.Val" + }] + } + { + code = ":=" + owners = [{ + regex = "Term\\.ApplyInfix" + parents = ["Term\\.Block|Template"] + }] + } + { + code = "#=" + owners = [{ + regex = "Term\\.ApplyInfix" + parents = ["Term\\.Block|Template"] + }] + } + { + code = "port" + owners = [{ + regex = "Term\\.ApplyInfix" + parents = ["Defn\\.Val"] + }] + } + { + code = "->" + owners = [{ + regex = "Term\\.ApplyInfix" + }] + } +] docstrings.wrap = no +docstrings.oneline = fold diff --git a/tester/src/main/scala/spinal/tester/GenerationShould.scala b/tester/src/main/scala/spinal/tester/GenerationShould.scala new file mode 100644 index 0000000000..0a887ef78b --- /dev/null +++ b/tester/src/main/scala/spinal/tester/GenerationShould.scala @@ -0,0 +1,24 @@ +package spinal.tester + +import spinal.core._ + +object GenerationShould { + private def fails(f: => Unit): Boolean = { + var failed = false + try { f } + catch { + case e: Throwable => failed = true + } + failed + } + + def fail(gen: => Component): Unit = { + assert(fails { SpinalVhdl(gen) }) + assert(fails { SpinalVerilog(gen) }) + } + + def pass(gen: => Component): Unit = { + assert(!fails { SpinalVhdl(gen) }) + assert(!fails { SpinalVerilog(gen) }) + } +} diff --git a/tester/src/test/scala/spinal/tester/CrossClockTester.scala b/tester/src/test/scala/spinal/tester/CrossClockTester.scala new file mode 100644 index 0000000000..c0bae4fad1 --- /dev/null +++ b/tester/src/test/scala/spinal/tester/CrossClockTester.scala @@ -0,0 +1,181 @@ +package spinal.tester + +import spinal.core._ + +import org.scalatest.funsuite.AnyFunSuite + +case class BBA(cd: ClockDomain) extends BlackBox { + val i = in port Bool() +} + +case class BBB(cd: ClockDomain) extends BlackBox { + val o = out port Bool() +} + +case class CrossClockA() extends Component { + val clkA = ClockDomain.external("clkA") + val clkB = ClockDomain.external("clkB") + + val reg = clkA(RegNext(in port Bool())) + + val bb = BBA(clkB) + bb.i := reg +} + +case class CrossClockB() extends Component { + val clkA = ClockDomain.external("clkA") + val clkB = ClockDomain.external("clkB") + + val reg = in port Bool() + + val bb = BBA(clkB) + bb.i := reg +} + +case class CrossClockC() extends Component { + val clkA = ClockDomain.external("clkA") + val clkB = ClockDomain.external("clkB") + + val reg = out port Bool() + + val bb = BBB(clkB) + bb.o <> reg +} + +class CrossClockCheckerTester extends AnyFunSuite { + test("a") { + GenerationShould pass CrossClockA() + } + + test("b") { + GenerationShould fail { + val c = CrossClockA() + c.bb.i.addTag(ClockDomainTag(c.clkB)) + c + } + } + + test("c") { + GenerationShould fail { + val c = CrossClockB() + c.reg.addTag(ClockDomainTag(c.clkA)) + c.bb.i.addTag(ClockDomainTag(c.clkB)) + c + } + } + + test("d") { + GenerationShould fail { + val c = CrossClockC() + c.reg.addTag(ClockDomainTag(c.clkA)) + c.bb.o.addTag(ClockDomainTag(c.clkB)) + c + } + } +} + +case class SyncronousA() extends Component { + val ck, rst = in port Bool() + val input = in port UInt(8 bits) + val output = out port UInt(8 bits) + + val cd = ClockDomain(ck, rst) + val logic = cd on new Area { + val a = RegNext(input) + val b = RegNext(a) + output := b + } +} + +case class SyncronousB() extends Component { + val ck1, rst = in port Bool() + val input = in port UInt(8 bits) + val output = out port UInt(8 bits) + + val ck2 = CombInit(ck1) + + val cd1 = ClockDomain(ck1, rst) + val cd2 = ClockDomain(ck2, rst) + + val logic1 = cd1 on new Area { + val a = RegNext(input) + val b = RegNext(a) + output := b + } + + val logic2 = cd2 on new Area { + val a = out port RegNext(logic1.a) + } +} + +case class SyncronousC(v: Int) extends Component { + val ck1, ck2, rst = in port Bool() + val input = in port UInt(8 bits) + val output = out port UInt(8 bits) + + val clk1Buf = List.fill(3)(Bool()).foldLeft(ck1) { (i, o) => o := i; o } + val clk2Buf = List.fill(3)(Bool()).foldLeft(ck2) { (i, o) => o := i; o } + + val cd1 = ClockDomain(clk1Buf, rst) + val cd2 = ClockDomain(clk2Buf, rst) + v match { + case 0 => + case 1 => cd1.setSyncWith(cd2) + case 2 => cd2.setSyncWith(cd1) + case 3 => ClockDomain(ck1).setSyncWith(cd2) + case 4 => ClockDomain(ck2).setSyncWith(cd1) + case 5 => ClockDomain(ck1).setSyncWith(ClockDomain(ck2)) + } + + val logic1 = cd1 on new Area { + val a = RegNext(input) + val b = RegNext(a) + output := b + } + + val logic2 = cd2 on new Area { + val a = out port RegNext(logic1.a) + } +} + +case class SyncronousCheckerTesterD(v: Int) extends Component { + val ck1, rst = in port Bool() + val input = in port UInt(8 bits) + val output = out port UInt(8 bits) + + val ck2 = ck1 && input === 0 + + val cd1 = ClockDomain(ck1, rst) + val cd2 = ClockDomain(ck2, rst) + + v match { + case 0 => + case 1 => cd1.setSyncWith(cd2) + case 2 => Clock.syncDrive(source = ck1, sink = ck2) + } + + val logic1 = cd1 on new Area { + val a = RegNext(input) + val b = RegNext(a) + output := b + } + + val logic2 = cd2 on new Area { + val a = out port RegNext(logic1.a) + } +} + +class SyncronousCheckerTester extends AnyFunSuite { + test("a") { GenerationShould pass SyncronousA() } + test("b") { GenerationShould pass SyncronousB() } + test("c0") { GenerationShould fail SyncronousC(0) } + test("c1") { GenerationShould pass SyncronousC(1) } + test("c2") { GenerationShould pass SyncronousC(2) } + test("c3") { GenerationShould pass SyncronousC(3) } + test("c4") { GenerationShould pass SyncronousC(4) } + test("c5") { GenerationShould pass SyncronousC(5) } + test("d0") { GenerationShould fail SyncronousCheckerTesterD(0) } + test("d1") { GenerationShould pass SyncronousCheckerTesterD(1) } + test("d2") { GenerationShould pass SyncronousCheckerTesterD(2) } +// test("d3") { GenerationShould fail (SyncronousCheckerTesterD(3)) } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/ChecksTester.scala b/tester/src/test/scala/spinal/tester/GenerationShould.scala similarity index 50% rename from tester/src/test/scala/spinal/tester/scalatest/ChecksTester.scala rename to tester/src/test/scala/spinal/tester/GenerationShould.scala index fe957dfd11..0b021cf6fa 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/ChecksTester.scala +++ b/tester/src/test/scala/spinal/tester/GenerationShould.scala @@ -1,73 +1,40 @@ -package spinal.tester.scalatest +package spinal.tester import java.io.File - import org.apache.commons.io.FileUtils + import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import spinal.core.internals.GraphUtils + import spinal.lib.com.i2c._ import spinal.lib.com.uart.{UartCtrl, UartCtrlGenerics} import spinal.lib.soc.pinsec.{Pinsec, PinsecConfig} -import spinal.lib.{Delay, StreamFifo} - -import scala.collection.mutable.ArrayBuffer -import scala.sys.process._ -object CheckTester{ - def checkFailure(func : => Unit) : Boolean = { - try{func} catch { - case e: Throwable => { - print(e) - return true - } - } - return false - } - - def generationShouldFaild(gen : => Component): Unit ={ - println("[Warning] generationShouldFaild is deprecated! Use generationShouldFail") - generationShouldFail(gen) - } - - def generationShouldFail(gen : => Component): Unit ={ - assert(checkFailure{SpinalVhdl(gen)}) - assert(checkFailure{SpinalVerilog(gen)}) - } - - def generationShouldPass(gen : => Component): Unit ={ - assert(!checkFailure{SpinalVhdl(gen)}) - assert(!checkFailure{SpinalVerilog(gen)}) - } -} - -class ChecksTester extends AnyFunSuite { - import CheckTester._ - - - test("BlackBoxInputUnconnected"){ - generationShouldFail(new Component{ - class Sub extends BlackBox{ - val input = in Bool() +class GenerationShouldTester extends AnyFunSuite { + test("BlackBoxInputUnconnected") { + GenerationShould fail (new Component { + class Sub extends BlackBox { + val input = in port Bool() } val sub = new Sub }) } - test("literalWidth"){ - val t = SpinalVhdl(new Component{ - val a = out(B"32'h0") + test("literalWidth") { + val t = SpinalVhdl(new Component { + val a = out port B"32'h0" }).toplevel assert(widthOf(t.a) == 32) } - test("componentNamedByIo") { - val t = SpinalVerilog(new Component{ - val miaou = new Component{ + val t = SpinalVerilog(new Component { + val miaou = new Component { val io = new Bundle { - val x = out Bool() + val x = out port Bool() } assert(io.x.getName() == "io_x") }.io @@ -77,82 +44,77 @@ class ChecksTester extends AnyFunSuite { assert(t.miaou.getName() == "io") } - - test("checkWidthAssignment") { - generationShouldFail(new Component{ - val output = out Bits(8 bits) + GenerationShould fail (new Component { + val output = out Bits (8 bits) output := "00" }) } - test("checkCombinatorialLoop") { - generationShouldFail(new Component{ - val input = in Bits(8 bits) - val cond = in Bool() + GenerationShould fail (new Component { + val input = in Bits (8 bits) + val cond = in Bool () - val tempA = Bits(4 bits) - val output = out Bits(8 bits) + val tempA = Bits(4 bits) + val output = out Bits (8 bits) tempA := input(7 downto 4) val tempB = Bits(4 bits) tempB := tempA - when(cond){ + when(cond) { tempA(1) := tempB(0) } - output(3 downto 0) := input (3 downto 0) + output(3 downto 0) := input(3 downto 0) output(7 downto 4) := tempB }) } test("checkNoPartialAssignment") { - generationShouldPass(new Component{ - val cond = in Bool() - val input = in Bits(8 bits) - val output = out Bits(8 bits) - when(cond){ + GenerationShould pass (new Component { + val cond = in Bool () + val input = in Bits (8 bits) + val output = out Bits (8 bits) + when(cond) { output(7 downto 1) := input.resized - when(cond){ + when(cond) { output(0) := cond - } otherwise{ + } otherwise { output(0) := cond } - }otherwise{ + } otherwise { output := input } }) - generationShouldFail(new Component{ - val cond = in Bool() - val input = in Bits(8 bits) - val output = out Bits(8 bits) - when(cond){ + GenerationShould fail (new Component { + val cond = in port Bool() + val input = in port Bits(8 bits) + val output = out port Bits(8 bits) + when(cond) { output(7 downto 1) := input.resized - when(cond){ - - } otherwise{ + when(cond) {} otherwise { output(0) := cond } - }otherwise{ + } otherwise { output := input } }) } test("checkNoMissingDefault") { - generationShouldPass(new Component{ - val cond = in Bool() - val input = in Bits(8 bits) - val output = out Bits(8 bits) - when(cond){ + GenerationShould pass (new Component { + val cond = in port Bool() + val input = in port Bits(8 bits) + val output = out port Bits(8 bits) + when(cond) { output := input - }otherwise{ + } otherwise { when(cond) { output := input - when(cond){ + when(cond) { output := input } } otherwise { @@ -161,15 +123,15 @@ class ChecksTester extends AnyFunSuite { } }) - generationShouldFail(new Component{ - val cond = in Bool() - val input = in Bits(8 bits) - val output = out Bits(8 bits) - when(cond){ + GenerationShould fail (new Component { + val cond = in port Bool() + val input = in port Bits(8 bits) + val output = out port Bits(8 bits) + when(cond) { output := input - }otherwise{ + } otherwise { when(cond) { - when(cond){ + when(cond) { output := input } } otherwise { @@ -180,112 +142,110 @@ class ChecksTester extends AnyFunSuite { } test("checkClockCrossing") { - generationShouldFail(new Component{ - val clockA = in Bool() - val clockB = in Bool() + GenerationShould fail (new Component { + val clockA = in port Bool() + val clockB = in port Bool() - val areaA = new ClockingArea(ClockDomain(clockA)){ + val areaA = new ClockingArea(ClockDomain(clockA)) { val reg = Reg(Bool()) - reg := in(Bool) + reg := in port Bool() } - val areaB = new ClockingArea(ClockDomain(clockB)){ + val areaB = new ClockingArea(ClockDomain(clockB)) { val reg = Reg(Bool()) reg := areaA.reg - val output = out Bool() + val output = out port Bool() output := reg } }) } test("checkClockCrossingCheckingCheckSourcesPaths") { - generationShouldPass(new Component{ - val clock = in Bool() - val clockA = Bool - val clockB = Bool + GenerationShould pass (new Component { + val clock = in port Bool() + val clockA = Bool + val clockB = Bool clockA := clock - val sub = new Component{ - val cIn = in Bool() - val cOut = out Bool() + val sub = new Component { + val cIn = in port Bool() + val cOut = out port Bool() val tmp = Bool() - tmp := cIn + tmp := cIn cOut := tmp } sub.cIn := clock - clockB := sub.cOut - val areaA = new ClockingArea(ClockDomain(clockA)){ + clockB := sub.cOut + val areaA = new ClockingArea(ClockDomain(clockA)) { val reg = Reg(Bool()) - reg := in(Bool) + reg := in port Bool() } - val areaB = new ClockingArea(ClockDomain(clockB)){ + val areaB = new ClockingArea(ClockDomain(clockB)) { val reg = Reg(Bool()) reg := areaA.reg - val output = out Bool() + val output = out port Bool() output := reg } }) } test("checkClockCrossingCheckingCheckSourcesPathsFalure") { - generationShouldFail(new Component{ - val clock1 = in Bool() - val clock2 = in Bool() - val clockA = Bool - val clockB = Bool + GenerationShould fail (new Component { + val clock1 = in port Bool() + val clock2 = in port Bool() + val clockA = Bool() + val clockB = Bool() clockA := clock1 - val sub = new Component{ - val cIn = in Bool() - val cOut = out Bool() + val sub = new Component { + val cIn = in port Bool() + val cOut = out port Bool() val tmp = Bool() - tmp := cIn + tmp := cIn cOut := tmp } sub.cIn := clock2 - clockB := sub.cOut - val areaA = new ClockingArea(ClockDomain(clockA)){ + clockB := sub.cOut + val areaA = new ClockingArea(ClockDomain(clockA)) { val reg = Reg(Bool()) - reg := in(Bool) + reg := in port Bool() } - val areaB = new ClockingArea(ClockDomain(clockB)){ + val areaB = new ClockingArea(ClockDomain(clockB)) { val reg = Reg(Bool()) reg := areaA.reg - val output = out Bool() + val output = out port Bool() output := reg } }) } test("checkNoInputAssignment") { - generationShouldFail(new Component{ - val input = in Bool() - val output = out Bool() + GenerationShould fail (new Component { + val input = in port Bool() + val output = out port Bool() output := input - input := False + input := False }) } test("checkNoSubOutputAssignment") { - generationShouldFail(new Component{ - val sub = new Component{ - val output = out(True) + GenerationShould fail (new Component { + val sub = new Component { + val output = out port True } sub.output := False }) } - - test("checkNoSubSignalAssignment") { - generationShouldFail(new Component{ - val sub = new Component{ + GenerationShould fail (new Component { + val sub = new Component { val tmp = True } sub.tmp := False @@ -293,16 +253,16 @@ class ChecksTester extends AnyFunSuite { } test("checkNoOverrides") { - generationShouldPass(new Component{ - val a = out Bool() + GenerationShould pass (new Component { + val a = out port Bool() a := True when(True === True) { a := False } }) - generationShouldPass(new Component{ - val a = out Bool() + GenerationShould pass (new Component { + val a = out port Bool() when(True === True) { a := False } otherwise { @@ -310,13 +270,13 @@ class ChecksTester extends AnyFunSuite { } }) - generationShouldFail(new Component{ - val a = out Bool() + GenerationShould fail (new Component { + val a = out port Bool() a := True a := False }) - generationShouldFail(new Component{ - val a = out Bool() + GenerationShould fail (new Component { + val a = out port Bool() a := True when(True === True) { a := False @@ -324,108 +284,104 @@ class ChecksTester extends AnyFunSuite { } }) - generationShouldFail(new Component{ - val a = out Bool() + GenerationShould fail (new Component { + val a = out port Bool() when(True === True) { a := False } a := True }) - generationShouldFail(new Component{ - val sub = new Component{ - val a = in Bool() - val result = out Bool() + GenerationShould fail (new Component { + val sub = new Component { + val a = in port Bool() + val result = out port Bool() result := a } - val result = out Bool() + val result = out port Bool() result := sub.result }) - generationShouldFail(new Component{ - val sub = new Component{ - val result = out Bool() + GenerationShould fail (new Component { + val sub = new Component { + val result = out port Bool() } - val result = out Bool() + val result = out port Bool() result := sub.result }) - generationShouldFail(new Component{ - val sub = new Component{ - val a = in Bool() - val result = out Bool() + GenerationShould fail (new Component { + val sub = new Component { + val a = in port Bool() + val result = out port Bool() result := a } - val result = out Bool() + val result = out port Bool() result := sub.result - when(True){ + when(True) { sub.a := True } }) - - - } test("checkNoResetFail") { - generationShouldFail(new Component{ - ClockDomain(in Bool()) { - val output = out(RegInit(False)).setName("aaa") + GenerationShould fail (new Component { + ClockDomain(in port Bool()) { + val output = out port RegInit(False).setName("aaa") } }) } test("checkOnlyIoInIoBundle") { - class CheckOnlyIoInBundle extends Component{ - val io = new Bundle{ + class CheckOnlyIoInBundle extends Component { + val io = new Bundle { val x = Bool() } } - generationShouldFail(new CheckOnlyIoInBundle) + GenerationShould fail (new CheckOnlyIoInBundle) } - test("catchNegativeRangedAccess1") { - generationShouldFail(new Component { + GenerationShould fail (new Component { Bits(32 bits)(4 downto 7) }) } test("catchNegativeRangedAccess2") { - generationShouldFail(new Component { + GenerationShould fail (new Component { Bits(32 bits)(-1 downto -2) }) } test("catchNegativeRangedAccess3") { - generationShouldFail(new Component { + GenerationShould fail (new Component { Bits(32 bits)(4 downto 7) := 0 }) } test("catchNegativeRangedAccess4") { - generationShouldFail(new Component { - val input = in Bits(8 bits) + GenerationShould fail (new Component { + val input = in port Bits(8 bits) val currState = Vec(Bits(64 bits), 25) currState.assignFromBits(input, 0, 8) }) } - test("catchShiftBig"){ - generationShouldFail(new Component { + test("catchShiftBig") { + GenerationShould fail (new Component { val a = B(1) val b = a << U(2, 30 bits) }) } - test("litRange"){ - def failBody(body : => Unit): Unit ={ - generationShouldFail(new Component {body}) + test("litRange") { + def failBody(body: => Unit): Unit = { + GenerationShould fail (new Component { body }) } - def passBody(body : => Unit): Unit ={ - generationShouldPass(new Component {body}) + def passBody(body: => Unit): Unit = { + GenerationShould pass (new Component { body }) } failBody(out(in(Bits(8 bits)) === B(256))) @@ -455,28 +411,27 @@ class ChecksTester extends AnyFunSuite { passBody(out(in(SInt(9 bits)) <= S(-256))) } - - test("scopeProperty"){ - object FixedPointProperty extends ScopeProperty[Int]{ + test("scopeProperty") { + object FixedPointProperty extends ScopeProperty[Int] { override def default = 42 } - def check(ref : Int): Unit ={ + def check(ref: Int): Unit = { println(s"ref:$ref dut:${FixedPointProperty.get}") assert(ref == FixedPointProperty.get) } - class Sub extends Component{ + class Sub extends Component { check(666) } - class Toplevel extends Component{ + class Toplevel extends Component { check(55) - val logic = FixedPointProperty(666) on new Area{ + val logic = FixedPointProperty(666) on new Area { check(666) val x = new Sub check(666) - FixedPointProperty(1234){ + FixedPointProperty(1234) { check(1234) - x.rework{ + x.rework { check(666) } check(1234) @@ -487,9 +442,8 @@ class ChecksTester extends AnyFunSuite { check(55) } - check(42) - FixedPointProperty(55){ + FixedPointProperty(55) { check(55) val config = SpinalConfig() // try { @@ -505,75 +459,81 @@ class ChecksTester extends AnyFunSuite { } -class RepeatabilityTester extends AnyFunSuite{ +class RepeatabilityTester extends AnyFunSuite { var checkOutputHashCounter = 0 - def checkOutputHash(gen : => Component): Unit ={ + def checkOutputHash(gen: => Component): Unit = { checkOutputHashCounter = checkOutputHashCounter + 1 var ref = "" - for(i <- 0 until 8) { - val report = SpinalConfig(defaultClockDomainFrequency = FixedFrequency(50 MHz)).generateVerilog(gen.setDefinitionName(s"checkOutputHash_${checkOutputHashCounter}")) - FileUtils.copyFile(new File(report.generatedSourcesPaths.head),new File(report.generatedSourcesPaths.head + "_" + i + ".v")) + for (i <- 0 until 8) { + val report = + SpinalConfig(defaultClockDomainFrequency = FixedFrequency(50 MHz)) + .generateVerilog( + gen.setDefinitionName(s"checkOutputHash_${checkOutputHashCounter}") + ) + FileUtils.copyFile( + new File(report.generatedSourcesPaths.head), + new File(report.generatedSourcesPaths.head + "_" + i + ".v") + ) import sys.process._ val hash = s"md5sum ${report.generatedSourcesPaths.head}".!! - if(i == 0) ref = hash + if (i == 0) ref = hash else assert(ref == hash) } } def configI2C = I2cSlaveMemoryMappedGenerics( - ctrlGenerics = I2cSlaveGenerics(), + ctrlGenerics = I2cSlaveGenerics(), addressFilterCount = 0, - masterGenerics = I2cMasterMemoryMappedGenerics(timerWidth = 32) + masterGenerics = I2cMasterMemoryMappedGenerics(timerWidth = 32) ) - test("Apb3I2cCtrlGraph"){ - val dut = SpinalConfig(defaultClockDomainFrequency = FixedFrequency(50 MHz)).generateVerilog(new Apb3I2cCtrl(configI2C)).toplevel + test("Apb3I2cCtrlGraph") { + val dut = SpinalConfig(defaultClockDomainFrequency = FixedFrequency(50 MHz)) + .generateVerilog(new Apb3I2cCtrl(configI2C)) + .toplevel assert(GraphUtils.countNames(dut) == 221) } - test("UartGraph"){ + test("UartGraph") { val dut = SpinalVerilog(new UartCtrl(UartCtrlGenerics())).toplevel assert(GraphUtils.countNames(dut) == 94) } - - - test("Apb3I2cCtrlVerilog"){ + test("Apb3I2cCtrlVerilog") { checkOutputHash(new Apb3I2cCtrl(configI2C)) } - - test("UartVerilog"){ + test("UartVerilog") { checkOutputHash(new UartCtrl(UartCtrlGenerics())) } - test("PinsecVerilog"){ + test("PinsecVerilog") { checkOutputHash(new Pinsec(PinsecConfig.default)) } - test("BmbInterconnectVerilog"){ - checkOutputHash(SpinalSimBmbInterconnectGeneratorTester.f()) + test("BmbInterconnectVerilog") { + checkOutputHash(scalatest.SpinalSimBmbInterconnectGeneratorTester.component) } } class NameingTester extends AnyFunSuite { - import CheckTester._ - - test("reflectionNaming") { - val t = SpinalVhdl(new Component{ - val a = new Area{ + val t = SpinalVhdl(new Component { + val a = new Area { val aa = Bool() - val bb = new Area{ + val bb = new Area { val aaa = Bool() - val bbb = Vec(Bool(),4) - val ccc = Vec(new Bundle{ - val aaaa = Bool() - val bbbb = Vec(Bool(),8) - val cccc = Vec( Vec( Vec(Bool(),8),8),8) - val dddd = List.fill(4)(Bool) - val eeee = List.fill(4)(List.fill(4)(Bool)) - },4) + val bbb = Vec(Bool(), 4) + val ccc = Vec( + new Bundle { + val aaaa = Bool() + val bbbb = Vec(Bool(), 8) + val cccc = Vec(Vec(Vec(Bool(), 8), 8), 8) + val dddd = List.fill(4)(Bool) + val eeee = List.fill(4)(List.fill(4)(Bool)) + }, + 4 + ) } } val b = Bool() @@ -590,6 +550,3 @@ class NameingTester extends AnyFunSuite { assert(t.a.bb.ccc(3).eeee(3)(2).getName() == "a_bb_ccc_3_eeee_3_2") } } - - - diff --git a/tester/src/test/scala/spinal/tester/scalatest/CrossClockCheckerTester.scala b/tester/src/test/scala/spinal/tester/scalatest/CrossClockCheckerTester.scala deleted file mode 100644 index 545f9ea035..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/CrossClockCheckerTester.scala +++ /dev/null @@ -1,192 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ - - -class BBA(val cd : ClockDomain) extends BlackBox{ - val i = in(Bool) -} - -class BBB(val cd : ClockDomain) extends BlackBox{ - val o = out(Bool) -} - -class CrossClockCheckerTesterA extends Component{ - val clkA = ClockDomain.external("clkA") - val clkB = ClockDomain.external("clkB") - - val reg = clkA(RegNext(in Bool())) - - val bb = new BBA(clkB) - bb.i := reg -} - - -class CrossClockCheckerTesterB extends Component{ - val clkA = ClockDomain.external("clkA") - val clkB = ClockDomain.external("clkB") - - val reg = in Bool() - - val bb = new BBA(clkB) - bb.i := reg -} - -class CrossClockCheckerTesterC extends Component{ - val clkA = ClockDomain.external("clkA") - val clkB = ClockDomain.external("clkB") - - val reg = out Bool() - - val bb = new BBB(clkB) - bb.o <> reg -} - - -class CrossClockCheckerTester extends AnyFunSuite{ - import CheckTester._ - - test("a") { - generationShouldPass(new CrossClockCheckerTesterA) - } - - test("b") { - generationShouldFail({ - val c = new CrossClockCheckerTesterA - c.bb.i.addTag(ClockDomainTag(c.clkB)) - c - }) - } - - test("c") { - generationShouldFail({ - val c = new CrossClockCheckerTesterB - c.reg.addTag(ClockDomainTag(c.clkA)) - c.bb.i.addTag(ClockDomainTag(c.clkB)) - c - }) - } - - test("d") { - generationShouldFail({ - val c = new CrossClockCheckerTesterC - c.reg.addTag(ClockDomainTag(c.clkA)) - c.bb.o.addTag(ClockDomainTag(c.clkB)) - c - }) - } -} - - -class SyncronousCheckerTesterA extends Component{ - val clk,reset = in Bool() - val input = in UInt(8 bits) - val output = out UInt(8 bits) - - val cd = ClockDomain(clk, reset) - val logic = cd on new Area{ - val a = RegNext(input) - val b = RegNext(a) - output := b - } -} - -class SyncronousCheckerTesterB extends Component{ - val clk1,reset = in Bool() - val input = in UInt(8 bits) - val output = out UInt(8 bits) - - - val clk2 = CombInit(clk1) - - val cd1 = ClockDomain(clk1, reset) - val cd2 = ClockDomain(clk2, reset) - - val logic1 = cd1 on new Area{ - val a = RegNext(input) - val b = RegNext(a) - output := b - } - - val logic2 = cd2 on new Area{ - val a = out(RegNext(logic1.a)) - - } -} - -class SyncronousCheckerTesterC(v : Int) extends Component{ - val clk1, clk2, reset = in Bool() - val input = in UInt(8 bits) - val output = out UInt(8 bits) - - val clk1Buf = List.fill(3)(Bool).foldLeft(clk1){(i,o) => o := i; o} - val clk2Buf = List.fill(3)(Bool).foldLeft(clk2){(i,o) => o := i; o} - - val cd1 = ClockDomain(clk1Buf, reset) - val cd2 = ClockDomain(clk2Buf, reset) - v match{ - case 0 => - case 1 => cd1.setSyncWith(cd2) - case 2 => cd2.setSyncWith(cd1) - case 3 => ClockDomain(clk1).setSyncWith(cd2) - case 4 => ClockDomain(clk2).setSyncWith(cd1) - case 5 => ClockDomain(clk1).setSyncWith(ClockDomain(clk2)) - } - - val logic1 = cd1 on new Area{ - val a = RegNext(input) - val b = RegNext(a) - output := b - } - - val logic2 = cd2 on new Area{ - val a = out(RegNext(logic1.a)) - } -} - - -class SyncronousCheckerTesterD(v : Int) extends Component{ - val clk1,reset = in Bool() - val input = in UInt(8 bits) - val output = out UInt(8 bits) - - - val clk2 = clk1 && input === 0 - - val cd1 = ClockDomain(clk1, reset) - val cd2 = ClockDomain(clk2, reset) - - v match { - case 0 => - case 1 => cd1.setSyncWith(cd2) - case 2 => Clock.syncDrive(source = clk1, sink = clk2) - } - - val logic1 = cd1 on new Area{ - val a = RegNext(input) - val b = RegNext(a) - output := b - } - - val logic2 = cd2 on new Area{ - val a = out(RegNext(logic1.a)) - } -} - -class SyncronousCheckerTester extends AnyFunSuite{ - import CheckTester._ - - test("a") { generationShouldPass(new SyncronousCheckerTesterA) } - test("b") { generationShouldPass(new SyncronousCheckerTesterB) } - test("c0") { generationShouldFail(new SyncronousCheckerTesterC(0)) } - test("c1") { generationShouldPass(new SyncronousCheckerTesterC(1)) } - test("c2") { generationShouldPass(new SyncronousCheckerTesterC(2)) } - test("c3") { generationShouldPass(new SyncronousCheckerTesterC(3)) } - test("c4") { generationShouldPass(new SyncronousCheckerTesterC(4)) } - test("c5") { generationShouldPass(new SyncronousCheckerTesterC(5)) } - test("d0") { generationShouldFail(new SyncronousCheckerTesterD(0)) } - test("d1") { generationShouldPass(new SyncronousCheckerTesterD(1)) } - test("d2") { generationShouldPass(new SyncronousCheckerTesterD(2)) } -// test("d3") { generationShouldFail(new SyncronousCheckerTesterD(3)) } -} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbInterconnectGeneratorTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbInterconnectGeneratorTester.scala index 9d599ae227..3f333e9e2f 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbInterconnectGeneratorTester.scala +++ b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbInterconnectGeneratorTester.scala @@ -11,11 +11,13 @@ import spinal.lib.bus.misc.SizeMapping import spinal.lib.generator._ import spinal.lib.sim.Phase +import spinal.tester.SpinalSimFunSuite + import scala.collection.mutable import scala.util.Random object SpinalSimBmbInterconnectGeneratorTester { - def f() = { + def component() = { new Component{ val interconnect = BmbInterconnectGenerator() @@ -180,10 +182,10 @@ object SpinalSimBmbInterconnectGeneratorTester { } //TODO handle generation when a master has no slave -class SpinalSimBmbInterconnectGeneratorTester extends SpinalSimFunSuite{ +class SpinalSimBmbInterconnectGeneratorTester extends SpinalSimFunSuite { test("test1") { - SimConfig.allOptimisation.compile(SpinalSimBmbInterconnectGeneratorTester.f).doSimUntilVoid("test1", 42) { dut => //TODO remove seed + SimConfig.allOptimisation.compile(SpinalSimBmbInterconnectGeneratorTester.component).doSimUntilVoid("test1", 42) { dut => //TODO remove seed Phase.boot() Phase.setup { dut.clockDomain.forkStimulus(10) From a37769b2f359ce30ecd8aacc1037226e269005a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Wed, 7 Dec 2022 21:50:35 +0100 Subject: [PATCH 043/120] refactor: move ClockDomainConfigTester --- .../src/test/scala/spinal/core/ClockDomain.scala | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/ClockDomainConfigTester.scala => core/src/test/scala/spinal/core/ClockDomain.scala (95%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/ClockDomainConfigTester.scala b/core/src/test/scala/spinal/core/ClockDomain.scala similarity index 95% rename from tester/src/test/scala/spinal/tester/scalatest/ClockDomainConfigTester.scala rename to core/src/test/scala/spinal/core/ClockDomain.scala index b92a5d74fb..59fc0199a0 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/ClockDomainConfigTester.scala +++ b/core/src/test/scala/spinal/core/ClockDomain.scala @@ -1,9 +1,6 @@ -package spinal.tester.scalatest +package spinal.core -import spinal.core._ -import spinal.tester.scalatest.ClockDomainConfigTester.ClockDomainConfigTester -import spinal.tester.scalatest.GrayCounterTester.GrayCounterTester -import language.postfixOps +import spinal.tester.SpinalTesterCocotbBase object ClockDomainConfigTester { class ClockDomainConfigTester() extends Component { @@ -195,9 +192,8 @@ object ClockDomainConfigTester { } - class ClockDomainConfigTesterCocotbBoot extends SpinalTesterCocotbBase { override def getName: String = "ClockDomainConfigTester" override def pythonTestLocation: String = "tester/src/test/python/spinal/ClockDomainConfigTester" - override def createToplevel: Component = new ClockDomainConfigTester() -} \ No newline at end of file + override def createToplevel: Component = new ClockDomainConfigTester.ClockDomainConfigTester() +} From 3250f01c0fb9de2bbf0c26fa32c85a2e28e4d3f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Wed, 7 Dec 2022 21:54:39 +0100 Subject: [PATCH 044/120] refactor: move FixedPointTester --- .../test/scala/spinal/core/FixedPoint.scala | 38 ++++++++++++- .../tester/scalatest/FixedPointTester.scala | 53 ------------------- 2 files changed, 37 insertions(+), 54 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/FixedPointTester.scala diff --git a/core/src/test/scala/spinal/core/FixedPoint.scala b/core/src/test/scala/spinal/core/FixedPoint.scala index bd280f8eaa..ea1de95844 100644 --- a/core/src/test/scala/spinal/core/FixedPoint.scala +++ b/core/src/test/scala/spinal/core/FixedPoint.scala @@ -1,9 +1,45 @@ package spinal.core import org.scalatest.funsuite.AnyFunSuite + import spinal.core.sim._ +import spinal.tester.SpinalTesterCocotbBase + +object FixedPointTester { + case class BundleA(width : Int) extends Bundle{ + val a = BundleAA(width) + } + case class BundleAA(width : Int) extends Bundle{ + val sfix = SFix(4 exp,width bit) + } + + class FixedPointTester extends Component { + val io = new Bundle { + val inSFix = in(Vec(Seq(SFix(4 exp,16 bit),SFix(2 exp,12 bit)))) + val outSFix = out(Vec(Seq(SFix(4 exp,16 bit),SFix(8 exp,24 bit)))) + + val inSFix2 = in SFix(0 exp, -8 exp) + val outSFix2 = out(SFix(2 exp, -8 exp)) + + val inBundleA = in(BundleA(8)) + val outBundleA = out(BundleA(6)) + } + io.outSFix(0) := (io.inSFix(0) + io.inSFix(1)) + io.outSFix(1) := (io.inSFix(0) * io.inSFix(1)).truncated + + io.outSFix2 := ((io.inSFix2 <<|1) + io.inSFix2 ) <<|1 + io.inBundleA.a.sfix.addTag(tagTruncated) + io.outBundleA <> io.inBundleA + } +} + +class FixedPointTesterCocotbBoot extends SpinalTesterCocotbBase { + override def getName: String = "FixedPointTester" + override def pythonTestLocation: String = "tester/src/test/python/spinal/FixedPointTester" + override def createToplevel: Component = new FixedPointTester.FixedPointTester +} -class XFixTest extends AnyFunSuite { +class UFixTest extends AnyFunSuite { test("UFix Mux") { case class MuxDut() extends Component { val io = new Bundle { diff --git a/tester/src/test/scala/spinal/tester/scalatest/FixedPointTester.scala b/tester/src/test/scala/spinal/tester/scalatest/FixedPointTester.scala deleted file mode 100644 index 96ec150c44..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/FixedPointTester.scala +++ /dev/null @@ -1,53 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.lib.com.uart._ -import spinal.tester.scalatest.FixedPointTester.FixedPointTester - -object FixedPointTester{ - - case class BundleA(width : Int) extends Bundle{ - val a = BundleAA(width) - } - case class BundleAA(width : Int) extends Bundle{ - val sfix = SFix(4 exp,width bit) - } - - class FixedPointTester extends Component { - val io = new Bundle { - val inSFix = in(Vec(Seq(SFix(4 exp,16 bit),SFix(2 exp,12 bit)))) - val outSFix = out(Vec(Seq(SFix(4 exp,16 bit),SFix(8 exp,24 bit)))) - - val inSFix2 = in SFix(0 exp, -8 exp) - val outSFix2 = out(SFix(2 exp, -8 exp)) - - val inBundleA = in(BundleA(8)) - val outBundleA = out(BundleA(6)) - } - io.outSFix(0) := (io.inSFix(0) + io.inSFix(1)) - //28 bit point at 28-6=22 target is at 24-8=16 - io.outSFix(1) := (io.inSFix(0) * io.inSFix(1)).truncated - - io.outSFix2 := ((io.inSFix2 <<|1) + io.inSFix2 ) <<|1 - //io.outSFix(0).raw := S(0,16 bit) - //io.outSFix(1).raw := S(0,24 bit) - //io.outBundleA.a.sfix.raw := S(0,6 bit) - io.inBundleA.a.sfix.addTag(tagTruncated) - io.outBundleA <> io.inBundleA - - - - } -} - -// -//class FixedPointTesterGhdlBoot extends SpinalTesterGhdlBase { -// override def getName: String = "FixedPointTester" -// override def createToplevel: Component = new FixedPointTester -//} - -class FixedPointTesterCocotbBoot extends SpinalTesterCocotbBase { - override def getName: String = "FixedPointTester" - override def pythonTestLocation: String = "tester/src/test/python/spinal/FixedPointTester" - override def createToplevel: Component = new FixedPointTester -} \ No newline at end of file From fdd8097aa11edde7a3179da35a471351e738caf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 8 Dec 2022 22:10:27 +0100 Subject: [PATCH 045/120] refactor: move FloatingTester --- .../test/scala/spinal/lib/experimental/math/Floating.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/FloatingTester.scala => lib/src/test/scala/spinal/lib/experimental/math/Floating.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/FloatingTester.scala b/lib/src/test/scala/spinal/lib/experimental/math/Floating.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/FloatingTester.scala rename to lib/src/test/scala/spinal/lib/experimental/math/Floating.scala index 5960f94a1a..5a150f0f45 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/FloatingTester.scala +++ b/lib/src/test/scala/spinal/lib/experimental/math/Floating.scala @@ -1,8 +1,8 @@ -package spinal.tester.scalatest +package spinal.lib.experimental.math import spinal.core._ -import spinal.lib._ -import spinal.lib.experimental.math._ + +import spinal.tester.SpinalTesterCocotbBase class FloatingTester extends Component { val io = new Bundle { From ca59d37ae6a21624d1e162c582dd3740126d1d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 8 Dec 2022 22:15:03 +0100 Subject: [PATCH 046/120] refactor: move FormalArbiterTester --- lib/src/test/scala/spinal/lib/Stream.scala | 379 +++++++++++++++++ .../scalatest/FormalArbiterTester.scala | 383 ------------------ 2 files changed, 379 insertions(+), 383 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/FormalArbiterTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index cab4a16aff..946a802a17 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -1,6 +1,8 @@ package spinal.lib import spinal.core._ +import spinal.core.formal._ +import spinal.lib.formal._ import spinal.tester.{SpinalTesterCocotbBase, SpinalTesterGhdlBase} @@ -125,3 +127,380 @@ class StreamTester2CocotbBoot extends SpinalTesterCocotbBase { override def createToplevel: Component = new StreamTester2.StreamTester2 override def backendConfig(config: SpinalConfig): SpinalConfig = config } + +class FormalArbiterTester extends SpinalFormalFunSuite { + def usualVerify[T <: Data]( + inputs: Vec[Stream[T]], + output: Stream[T], + portCount: Int, + select: UInt, + selectOH: Bits, + reset: Bool, + withLock: Boolean, + locked: Bool + ) = new Area { + output.formalCovers(2) + when(reset || past(reset)) { + for (i <- 0 until portCount) { + assume(inputs(i).valid === False) + } + assert(select === 0) + if (withLock) assert(!locked) + } + + for (i <- 0 until portCount) { + inputs(i).formalAssumesSlave() + } + + assert(select < portCount) + assert(select === OHToUInt(selectOH)) + assert(selectOH === OHMasking.first(selectOH)) + assert(output.fire === inputs(select).fire) + assert(output.payload === inputs(select).payload) + } + + def prepareContext(withLock: Boolean) = new Area { + val portCount = 5 + val select = UInt(log2Up(portCount) bit) + val selectOH = Bits(portCount bit) + val dataType = Bits(8 bits) + val locked = Bool() + + val reset = ClockDomain.current.isResetActive + val notReset = !(reset || past(reset)) + cover(notReset) + assumeInitial(reset) + + val inputs = Vec(slave(Stream(dataType)), portCount) + val output = master(Stream(dataType)) + val usual = usualVerify(inputs, output, portCount, select, selectOH, reset, withLock, locked) + + val inputsValid = Vec(inputs.map(_.valid)) + val selStableCond = past(output.isStall) && notReset + val selectUnLockCond = !locked || past(output.fire) + } + + def prepareContextFragment(withLock: Boolean) = new Area { + val portCount = 5 + val select = UInt(log2Up(portCount) bit) + val selectOH = Bits(portCount bit) + val dataType = Fragment(Bits(8 bits)) + val locked = Bool() + + val reset = ClockDomain.current.isResetActive + val notReset = !(reset || past(reset)) + cover(notReset) + assumeInitial(reset) + + val inputs = Vec(slave(Stream(dataType)), portCount) + val output = master(Stream(dataType)) + val usual = usualVerify(inputs, output, portCount, select, selectOH, reset, withLock, locked) + + val inputsValid = Vec(inputs.map(_.valid)) + val selStableCond = !past((inputsValid.asBits === 0) || output.last || reset) + val selectUnLockCond = !locked || past(output.last && output.fire) + } + + def sequentialOrderVerify(select: UInt, portCount: Int) = new Area { + val d1 = anyconst(UInt(log2Up(portCount) bit)) + assume(d1 < portCount) + val d2 = UInt(log2Up(portCount) bit) + d2 := (d1 + 1) % portCount + + val cntSeqCheck = changed(select) && (select === d2) + cover(cntSeqCheck) + when(cntSeqCheck) { + assert(past(select) === d1) + } + } + + def lowFirstVerify( + selectOH: Bits, + inputsvalid: Vec[Bool], + unLockCond: Bool + ) = new Area { + val inputsLowerFirst = OHMasking.first(inputsvalid).asBits + cover(unLockCond) + when(unLockCond) { + assert(selectOH === inputsLowerFirst) + } + } + + def roundRobinVerify( + selectOH: Bits, + inputsValid: Vec[Bool], + portCount: Int, + maskLocked: Vec[Bool], + unLockCond: Bool + ) = new Area { + val requests = inputsValid.asBits.asUInt + val uGranted = selectOH.asUInt + val doubleRequests = requests @@ requests + val doubleGrant = doubleRequests & ~(doubleRequests - uGranted) + val masked = doubleGrant(portCount, portCount bits) | doubleGrant(0, portCount bits) + val inputsRoundRobinOH = masked.asBits + + cover(unLockCond) + when(unLockCond) { + assert(selectOH === inputsRoundRobinOH) + } + // used for Prove + assert(maskLocked === OHMasking.first(maskLocked)) + } + + def selStableVerify(selectOH: Bits, selStableCond: Bool, withLock: Boolean) = new Area { + if (withLock) { + cover(selStableCond) + when(selStableCond) { + assert(stable(selectOH)) + } + } + } + + def withAssertsVerify[T <: Data](outisStall: Bool, verifyCond: Vec[Bool], output: Stream[T], withLock: Boolean) = + new Area { + if (withLock) { + val stallStableSel = outisStall && stable(verifyCond) + cover(stallStableSel) + when(stallStableSel) { + output.formalAssertsMaster() + } + } + } + + test("Arbiter-sequentialOrder-verify") { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(20) + // .withDebug + .doVerify(new Component { + val withLock = true + val context = prepareContext(withLock) + val dut = FormalDut( + new StreamArbiter(context.dataType, context.portCount)( + StreamArbiter.Arbitration.sequentialOrder, + StreamArbiter.Lock.none + ) + ) + + context.select := dut.io.chosen + context.selectOH := dut.io.chosenOH + context.locked := dut.locked + context.output << dut.io.output + for (i <- 0 until context.portCount) { + context.inputs(i) >> dut.io.inputs(i) + } + + val withAssert = withAssertsVerify(context.output.isStall, context.inputsValid, context.output, withLock) + val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) + val sequentialOrder = sequentialOrderVerify(context.select, context.portCount) + }) + } + + test("Arbiter-lowerfirst-none-verify") { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(20) + // .withDebug + .doVerify(new Component { + val withLock = false + val context = prepareContext(withLock) + val dut = FormalDut( + new StreamArbiter(context.dataType, context.portCount)( + StreamArbiter.Arbitration.lowerFirst, + StreamArbiter.Lock.none + ) + ) + + context.select := dut.io.chosen + context.selectOH := dut.io.chosenOH + context.locked := dut.locked + context.output << dut.io.output + for (i <- 0 until context.portCount) { + context.inputs(i) >> dut.io.inputs(i) + } + + val withAssert = withAssertsVerify(context.output.isStall, context.inputsValid, context.output, withLock) + val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) + val lowFirst = lowFirstVerify(context.selectOH, context.inputsValid, context.selectUnLockCond) + }) + } + + test("Arbiter-lowerfirst-transactionLock-verify") { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(20) + // .withDebug + .doVerify(new Component { + + val withLock = true + val context = prepareContext(withLock) + val dut = FormalDut( + new StreamArbiter(context.dataType, context.portCount)( + StreamArbiter.Arbitration.lowerFirst, + StreamArbiter.Lock.transactionLock + ) + ) + + context.select := dut.io.chosen + context.selectOH := dut.io.chosenOH + context.locked := dut.locked + context.output << dut.io.output + for (i <- 0 until context.portCount) { + context.inputs(i) >> dut.io.inputs(i) + } + // used for Prove + when(context.notReset) { + assert(past(context.output.isStall) === dut.locked) + } + + val withAssert = withAssertsVerify(context.output.isStall, context.inputsValid, context.output, withLock) + val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) + val lowFirst = lowFirstVerify(context.selectOH, context.inputsValid, context.selectUnLockCond) + }) + } + + test("Arbiter-lowerfirst-fragment-verify") { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(20) + // .withDebug + .doVerify(new Component { + val withLock = true + val context = prepareContextFragment(withLock) + val dut = FormalDut( + new StreamArbiter(context.dataType, context.portCount)( + StreamArbiter.Arbitration.lowerFirst, + StreamArbiter.Lock.fragmentLock + ) + ) + + context.select := dut.io.chosen + context.selectOH := dut.io.chosenOH + context.locked := dut.locked + context.output << dut.io.output + for (i <- 0 until context.portCount) { + context.inputs(i) >> dut.io.inputs(i) + } + + val withAssert = withAssertsVerify(context.output.isStall, context.inputsValid, context.output, withLock) + val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) + val lowFirst = lowFirstVerify(context.selectOH, context.inputsValid, context.selectUnLockCond) + }) + } + + test("Arbiter-roundrobin-none-verify") { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(20) + // .withDebug + .doVerify(new Component { + val withLock = false + val context = prepareContext(withLock) + val dut = FormalDut( + new StreamArbiter(context.dataType, context.portCount)( + StreamArbiter.Arbitration.roundRobin, + StreamArbiter.Lock.none + ) + ) + + context.select := dut.io.chosen + context.selectOH := dut.io.chosenOH + context.locked := dut.locked + context.output << dut.io.output + for (i <- 0 until context.portCount) { + context.inputs(i) >> dut.io.inputs(i) + } + + val roundRobin = roundRobinVerify( + context.selectOH, + context.inputsValid, + context.portCount, + dut.maskLocked, + context.selectUnLockCond + ) + val withAssert = withAssertsVerify(context.output.isStall, roundRobin.masked.asBools, context.output, withLock) + val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) + }) + } + + test("Arbiter-roundrobin-transactionLock-verify") { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(20) + .withDebug + .doVerify(new Component { + val withLock = true + val context = prepareContext(withLock) + val dut = FormalDut( + new StreamArbiter(context.dataType, context.portCount)( + StreamArbiter.Arbitration.roundRobin, + StreamArbiter.Lock.transactionLock + ) + ) + + context.select := dut.io.chosen + context.selectOH := dut.io.chosenOH + context.locked := dut.locked + context.output << dut.io.output + for (i <- 0 until context.portCount) { + context.inputs(i) >> dut.io.inputs(i) + } + // used for Prove + when(context.notReset) { + assert(past(context.output.isStall) === dut.locked) + } + val roundRobin = roundRobinVerify( + context.selectOH, + context.inputsValid, + context.portCount, + dut.maskLocked, + context.selectUnLockCond + ) + val withAssert = withAssertsVerify(context.output.isStall, roundRobin.masked.asBools, context.output, withLock) + val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) + }) + } + + test("Arbiter-roundrobin-fragment-verify") { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(20) + // .withDebug + .doVerify(new Component { + val withLock = true + val context = prepareContextFragment(withLock) + val dut = FormalDut( + new StreamArbiter(context.dataType, context.portCount)( + StreamArbiter.Arbitration.roundRobin, + StreamArbiter.Lock.fragmentLock + ) + ) + + context.select := dut.io.chosen + context.selectOH := dut.io.chosenOH + context.locked := dut.locked + context.output << dut.io.output + for (i <- 0 until context.portCount) { + context.inputs(i) >> dut.io.inputs(i) + } + + val roundRobin = roundRobinVerify( + context.selectOH, + context.inputsValid, + context.portCount, + dut.maskLocked, + context.selectUnLockCond + ) + val withAssert = withAssertsVerify(context.output.isStall, roundRobin.masked.asBools, context.output, withLock) + val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) + }) + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalArbiterTester.scala b/tester/src/test/scala/spinal/tester/scalatest/FormalArbiterTester.scala deleted file mode 100644 index d34f9392c8..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalArbiterTester.scala +++ /dev/null @@ -1,383 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.core.formal._ -import spinal.lib._ -import spinal.lib.formal._ - -class FormalArbiterTester extends SpinalFormalFunSuite { - def usualVerify[T <: Data]( - inputs: Vec[Stream[T]], - output: Stream[T], - portCount: Int, - select: UInt, - selectOH: Bits, - reset: Bool, - withLock: Boolean, - locked: Bool - ) = new Area { - output.formalCovers(2) - when(reset || past(reset)) { - for (i <- 0 until portCount) { - assume(inputs(i).valid === False) - } - assert(select === 0) - if (withLock) assert(!locked) - } - - for (i <- 0 until portCount) { - inputs(i).formalAssumesSlave() - } - - assert(select < portCount) - assert(select === OHToUInt(selectOH)) - assert(selectOH === OHMasking.first(selectOH)) - assert(output.fire === inputs(select).fire) - assert(output.payload === inputs(select).payload) - } - - def prepareContext(withLock: Boolean) = new Area { - val portCount = 5 - val select = UInt(log2Up(portCount) bit) - val selectOH = Bits(portCount bit) - val dataType = Bits(8 bits) - val locked = Bool() - - val reset = ClockDomain.current.isResetActive - val notReset = !(reset || past(reset)) - cover(notReset) - assumeInitial(reset) - - val inputs = Vec(slave(Stream(dataType)), portCount) - val output = master(Stream(dataType)) - val usual = usualVerify(inputs, output, portCount, select, selectOH, reset, withLock, locked) - - val inputsValid = Vec(inputs.map(_.valid)) - val selStableCond = past(output.isStall) && notReset - val selectUnLockCond = !locked || past(output.fire) - } - - def prepareContextFragment(withLock: Boolean) = new Area { - val portCount = 5 - val select = UInt(log2Up(portCount) bit) - val selectOH = Bits(portCount bit) - val dataType = Fragment(Bits(8 bits)) - val locked = Bool() - - val reset = ClockDomain.current.isResetActive - val notReset = !(reset || past(reset)) - cover(notReset) - assumeInitial(reset) - - val inputs = Vec(slave(Stream(dataType)), portCount) - val output = master(Stream(dataType)) - val usual = usualVerify(inputs, output, portCount, select, selectOH, reset, withLock, locked) - - val inputsValid = Vec(inputs.map(_.valid)) - val selStableCond = !past((inputsValid.asBits === 0) || output.last || reset) - val selectUnLockCond = !locked || past(output.last && output.fire) - } - - def sequentialOrderVerify(select: UInt, portCount: Int) = new Area { - val d1 = anyconst(UInt(log2Up(portCount) bit)) - assume(d1 < portCount) - val d2 = UInt(log2Up(portCount) bit) - d2 := (d1 + 1) % portCount - - val cntSeqCheck = changed(select) && (select === d2) - cover(cntSeqCheck) - when(cntSeqCheck) { - assert(past(select) === d1) - } - } - - def lowFirstVerify( - selectOH: Bits, - inputsvalid: Vec[Bool], - unLockCond: Bool - ) = new Area { - val inputsLowerFirst = OHMasking.first(inputsvalid).asBits - cover(unLockCond) - when(unLockCond) { - assert(selectOH === inputsLowerFirst) - } - } - - def roundRobinVerify( - selectOH: Bits, - inputsValid: Vec[Bool], - portCount: Int, - maskLocked: Vec[Bool], - unLockCond: Bool - ) = new Area { - val requests = inputsValid.asBits.asUInt - val uGranted = selectOH.asUInt - val doubleRequests = requests @@ requests - val doubleGrant = doubleRequests & ~(doubleRequests - uGranted) - val masked = doubleGrant(portCount, portCount bits) | doubleGrant(0, portCount bits) - val inputsRoundRobinOH = masked.asBits - - cover(unLockCond) - when(unLockCond) { - assert(selectOH === inputsRoundRobinOH) - } - // used for Prove - assert(maskLocked === OHMasking.first(maskLocked)) - } - - def selStableVerify(selectOH: Bits, selStableCond: Bool, withLock: Boolean) = new Area { - if (withLock) { - cover(selStableCond) - when(selStableCond) { - assert(stable(selectOH)) - } - } - } - - def withAssertsVerify[T <: Data](outisStall: Bool, verifyCond: Vec[Bool], output: Stream[T], withLock: Boolean) = - new Area { - if (withLock) { - val stallStableSel = outisStall && stable(verifyCond) - cover(stallStableSel) - when(stallStableSel) { - output.formalAssertsMaster() - } - } - } - - test("Arbiter-sequentialOrder-verify") { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(20) - // .withDebug - .doVerify(new Component { - val withLock = true - val context = prepareContext(withLock) - val dut = FormalDut( - new StreamArbiter(context.dataType, context.portCount)( - StreamArbiter.Arbitration.sequentialOrder, - StreamArbiter.Lock.none - ) - ) - - context.select := dut.io.chosen - context.selectOH := dut.io.chosenOH - context.locked := dut.locked - context.output << dut.io.output - for (i <- 0 until context.portCount) { - context.inputs(i) >> dut.io.inputs(i) - } - - val withAssert = withAssertsVerify(context.output.isStall, context.inputsValid, context.output, withLock) - val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) - val sequentialOrder = sequentialOrderVerify(context.select, context.portCount) - }) - } - - test("Arbiter-lowerfirst-none-verify") { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(20) - // .withDebug - .doVerify(new Component { - val withLock = false - val context = prepareContext(withLock) - val dut = FormalDut( - new StreamArbiter(context.dataType, context.portCount)( - StreamArbiter.Arbitration.lowerFirst, - StreamArbiter.Lock.none - ) - ) - - context.select := dut.io.chosen - context.selectOH := dut.io.chosenOH - context.locked := dut.locked - context.output << dut.io.output - for (i <- 0 until context.portCount) { - context.inputs(i) >> dut.io.inputs(i) - } - - val withAssert = withAssertsVerify(context.output.isStall, context.inputsValid, context.output, withLock) - val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) - val lowFirst = lowFirstVerify(context.selectOH, context.inputsValid, context.selectUnLockCond) - }) - } - - test("Arbiter-lowerfirst-transactionLock-verify") { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(20) - // .withDebug - .doVerify(new Component { - - val withLock = true - val context = prepareContext(withLock) - val dut = FormalDut( - new StreamArbiter(context.dataType, context.portCount)( - StreamArbiter.Arbitration.lowerFirst, - StreamArbiter.Lock.transactionLock - ) - ) - - context.select := dut.io.chosen - context.selectOH := dut.io.chosenOH - context.locked := dut.locked - context.output << dut.io.output - for (i <- 0 until context.portCount) { - context.inputs(i) >> dut.io.inputs(i) - } - // used for Prove - when(context.notReset) { - assert(past(context.output.isStall) === dut.locked) - } - - val withAssert = withAssertsVerify(context.output.isStall, context.inputsValid, context.output, withLock) - val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) - val lowFirst = lowFirstVerify(context.selectOH, context.inputsValid, context.selectUnLockCond) - }) - } - - test("Arbiter-lowerfirst-fragment-verify") { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(20) - // .withDebug - .doVerify(new Component { - val withLock = true - val context = prepareContextFragment(withLock) - val dut = FormalDut( - new StreamArbiter(context.dataType, context.portCount)( - StreamArbiter.Arbitration.lowerFirst, - StreamArbiter.Lock.fragmentLock - ) - ) - - context.select := dut.io.chosen - context.selectOH := dut.io.chosenOH - context.locked := dut.locked - context.output << dut.io.output - for (i <- 0 until context.portCount) { - context.inputs(i) >> dut.io.inputs(i) - } - - val withAssert = withAssertsVerify(context.output.isStall, context.inputsValid, context.output, withLock) - val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) - val lowFirst = lowFirstVerify(context.selectOH, context.inputsValid, context.selectUnLockCond) - }) - } - - test("Arbiter-roundrobin-none-verify") { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(20) - // .withDebug - .doVerify(new Component { - val withLock = false - val context = prepareContext(withLock) - val dut = FormalDut( - new StreamArbiter(context.dataType, context.portCount)( - StreamArbiter.Arbitration.roundRobin, - StreamArbiter.Lock.none - ) - ) - - context.select := dut.io.chosen - context.selectOH := dut.io.chosenOH - context.locked := dut.locked - context.output << dut.io.output - for (i <- 0 until context.portCount) { - context.inputs(i) >> dut.io.inputs(i) - } - - val roundRobin = roundRobinVerify( - context.selectOH, - context.inputsValid, - context.portCount, - dut.maskLocked, - context.selectUnLockCond - ) - val withAssert = withAssertsVerify(context.output.isStall, roundRobin.masked.asBools, context.output, withLock) - val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) - }) - } - - test("Arbiter-roundrobin-transactionLock-verify") { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(20) - .withDebug - .doVerify(new Component { - val withLock = true - val context = prepareContext(withLock) - val dut = FormalDut( - new StreamArbiter(context.dataType, context.portCount)( - StreamArbiter.Arbitration.roundRobin, - StreamArbiter.Lock.transactionLock - ) - ) - - context.select := dut.io.chosen - context.selectOH := dut.io.chosenOH - context.locked := dut.locked - context.output << dut.io.output - for (i <- 0 until context.portCount) { - context.inputs(i) >> dut.io.inputs(i) - } - // used for Prove - when(context.notReset) { - assert(past(context.output.isStall) === dut.locked) - } - val roundRobin = roundRobinVerify( - context.selectOH, - context.inputsValid, - context.portCount, - dut.maskLocked, - context.selectUnLockCond - ) - val withAssert = withAssertsVerify(context.output.isStall, roundRobin.masked.asBools, context.output, withLock) - val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) - }) - } - - test("Arbiter-roundrobin-fragment-verify") { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(20) - // .withDebug - .doVerify(new Component { - val withLock = true - val context = prepareContextFragment(withLock) - val dut = FormalDut( - new StreamArbiter(context.dataType, context.portCount)( - StreamArbiter.Arbitration.roundRobin, - StreamArbiter.Lock.fragmentLock - ) - ) - - context.select := dut.io.chosen - context.selectOH := dut.io.chosenOH - context.locked := dut.locked - context.output << dut.io.output - for (i <- 0 until context.portCount) { - context.inputs(i) >> dut.io.inputs(i) - } - - val roundRobin = roundRobinVerify( - context.selectOH, - context.inputsValid, - context.portCount, - dut.maskLocked, - context.selectUnLockCond - ) - val withAssert = withAssertsVerify(context.output.isStall, roundRobin.masked.asBools, context.output, withLock) - val selStable = selStableVerify(context.selectOH, context.selStableCond, withLock) - }) - } -} From 16737c9f12950dcdef8870e3781083b988826362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 8 Dec 2022 22:18:00 +0100 Subject: [PATCH 047/120] refactor: move FormalDeMuxTester --- lib/src/test/scala/spinal/lib/Stream.scala | 119 +++++++++++++++++ .../tester/scalatest/FormalDeMuxTester.scala | 125 ------------------ 2 files changed, 119 insertions(+), 125 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/FormalDeMuxTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index 946a802a17..a4e8ab2bbf 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -504,3 +504,122 @@ class FormalArbiterTester extends SpinalFormalFunSuite { }) } } + +class FormalDeMuxTester extends SpinalFormalFunSuite { + def formaldemux(selWithCtrl: Boolean = false) = { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(20) + // .withDebug + .doVerify(new Component { + val portCount = 5 + val dataType = Bits(8 bits) + val dut = FormalDut(new StreamDemux(dataType, portCount)) + + val reset = ClockDomain.current.isResetActive + + assumeInitial(reset) + + val demuxSelect = anyseq(UInt(log2Up(portCount) bit)) + val demuxInput = slave(Stream(dataType)) + val demuxOutputs = Vec(master(Stream(dataType)), portCount) + + dut.io.select := demuxSelect + demuxInput >> dut.io.input + + when(reset || past(reset)) { + assume(demuxInput.valid === False) + } + + val selStableCond = if (selWithCtrl) past(demuxOutputs(demuxSelect).isStall) else null + if (selWithCtrl) { + cover(selStableCond) + when(selStableCond) { + assume(stable(demuxSelect)) + } + } + + assumeInitial(demuxSelect < portCount) + cover(demuxInput.fire) + demuxInput.formalAssumesSlave() + demuxInput.formalCovers(5) + + val inputFireStableSelChanged = past(demuxInput.fire) && demuxInput.fire && changed(demuxSelect) + cover(inputFireStableSelChanged) + + for (i <- 0 until portCount) { + demuxOutputs(i) << dut.io.outputs(i) + demuxOutputs(i).formalAssertsMaster() + demuxOutputs(i).formalCovers(5) + } + + for (i <- 0 until portCount) { + assert(demuxOutputs(i).payload === demuxInput.payload) + when(i =/= demuxSelect) { + assert(demuxOutputs(i).valid === False) + } + } + when(demuxSelect < portCount) { + assert(demuxOutputs(demuxSelect) === demuxInput) + } + }) + } + test("demux_sel_with_control") { + formaldemux(true) + } + test("demux_sel_without_control") { + shouldFail(formaldemux(false)) + } + + test("demux_with_selector") { + FormalConfig + .withProve(20) + .withCover(20) + .doVerify(new Component { + val portCount = 5 + val dataType = Bits(8 bits) + val dut = FormalDut(new StreamDemux(dataType, portCount)) + val selector = dut.io.createSelector() + + val reset = ClockDomain.current.isResetActive + assumeInitial(reset) + + val demuxSelector = slave(Stream(UInt(log2Up(portCount) bit))) + demuxSelector >> selector + val demuxInput = slave(Stream(dataType)) + demuxInput >> dut.io.input + val demuxOutputs = Vec(master(Stream(dataType)), portCount) + for (i <- 0 until portCount) { + demuxOutputs(i) << dut.io.outputs(i) + } + + when(reset || past(reset)) { + assume(demuxInput.valid === False) + assume(demuxSelector.valid === False) + } + + assumeInitial(demuxSelector.payload < portCount) + demuxSelector.formalAssumesSlave() + demuxInput.formalAssumesSlave() + demuxInput.formalCovers(5) + + val inputFireStableSelChanged = past(demuxInput.fire) && demuxInput.fire && changed(dut.io.select) + cover(inputFireStableSelChanged) + + for (i <- 0 until portCount) { + demuxOutputs(i).formalAssertsMaster() + demuxOutputs(i).formalCovers(5) + } + + for (i <- 0 until portCount) { + when(i =/= dut.io.select) { + assert(demuxOutputs(i).valid === False) + } + } + when(dut.io.select < portCount) { + assert(demuxOutputs(dut.io.select) === demuxInput) + } + }) + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalDeMuxTester.scala b/tester/src/test/scala/spinal/tester/scalatest/FormalDeMuxTester.scala deleted file mode 100644 index 4c2bdb10b1..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalDeMuxTester.scala +++ /dev/null @@ -1,125 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.core.formal._ -import spinal.lib._ -import spinal.lib.formal._ - -class FormalDeMuxTester extends SpinalFormalFunSuite { - def formaldemux(selWithCtrl: Boolean = false) = { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(20) - // .withDebug - .doVerify(new Component { - val portCount = 5 - val dataType = Bits(8 bits) - val dut = FormalDut(new StreamDemux(dataType, portCount)) - - val reset = ClockDomain.current.isResetActive - - assumeInitial(reset) - - val demuxSelect = anyseq(UInt(log2Up(portCount) bit)) - val demuxInput = slave(Stream(dataType)) - val demuxOutputs = Vec(master(Stream(dataType)), portCount) - - dut.io.select := demuxSelect - demuxInput >> dut.io.input - - when(reset || past(reset)) { - assume(demuxInput.valid === False) - } - - val selStableCond = if (selWithCtrl) past(demuxOutputs(demuxSelect).isStall) else null - if (selWithCtrl) { - cover(selStableCond) - when(selStableCond) { - assume(stable(demuxSelect)) - } - } - - assumeInitial(demuxSelect < portCount) - cover(demuxInput.fire) - demuxInput.formalAssumesSlave() - demuxInput.formalCovers(5) - - val inputFireStableSelChanged = past(demuxInput.fire) && demuxInput.fire && changed(demuxSelect) - cover(inputFireStableSelChanged) - - for (i <- 0 until portCount) { - demuxOutputs(i) << dut.io.outputs(i) - demuxOutputs(i).formalAssertsMaster() - demuxOutputs(i).formalCovers(5) - } - - for (i <- 0 until portCount) { - assert(demuxOutputs(i).payload === demuxInput.payload) - when(i =/= demuxSelect) { - assert(demuxOutputs(i).valid === False) - } - } - when(demuxSelect < portCount) { - assert(demuxOutputs(demuxSelect) === demuxInput) - } - }) - } - test("demux_sel_with_control") { - formaldemux(true) - } - test("demux_sel_without_control") { - shouldFail(formaldemux(false)) - } - - test("demux_with_selector") { - FormalConfig - .withProve(20) - .withCover(20) - .doVerify(new Component { - val portCount = 5 - val dataType = Bits(8 bits) - val dut = FormalDut(new StreamDemux(dataType, portCount)) - val selector = dut.io.createSelector() - - val reset = ClockDomain.current.isResetActive - assumeInitial(reset) - - val demuxSelector = slave(Stream(UInt(log2Up(portCount) bit))) - demuxSelector >> selector - val demuxInput = slave(Stream(dataType)) - demuxInput >> dut.io.input - val demuxOutputs = Vec(master(Stream(dataType)), portCount) - for (i <- 0 until portCount) { - demuxOutputs(i) << dut.io.outputs(i) - } - - when(reset || past(reset)) { - assume(demuxInput.valid === False) - assume(demuxSelector.valid === False) - } - - assumeInitial(demuxSelector.payload < portCount) - demuxSelector.formalAssumesSlave() - demuxInput.formalAssumesSlave() - demuxInput.formalCovers(5) - - val inputFireStableSelChanged = past(demuxInput.fire) && demuxInput.fire && changed(dut.io.select) - cover(inputFireStableSelChanged) - - for (i <- 0 until portCount) { - demuxOutputs(i).formalAssertsMaster() - demuxOutputs(i).formalCovers(5) - } - - for (i <- 0 until portCount) { - when(i =/= dut.io.select) { - assert(demuxOutputs(i).valid === False) - } - } - when(dut.io.select < portCount) { - assert(demuxOutputs(dut.io.select) === demuxInput) - } - }) - } -} From 21f66b4436d135ba4ae08ecbd0f5f4c792bac23b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 8 Dec 2022 22:19:25 +0100 Subject: [PATCH 048/120] refactor: move FormalDispatcherSequencialTester --- lib/src/test/scala/spinal/lib/Stream.scala | 60 +++++++++++++++++ .../FormalDispatcherSequencial.scala | 66 ------------------- 2 files changed, 60 insertions(+), 66 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/FormalDispatcherSequencial.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index a4e8ab2bbf..d93ee285e8 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -623,3 +623,63 @@ class FormalDeMuxTester extends SpinalFormalFunSuite { }) } } + +class FormalDispatcherSequencialTester extends SpinalFormalFunSuite { + test("DispatcherSequencial-verify") { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(40) + // .withDebug + .doVerify(new Component { + val portCount = 5 + val dataType = Bits(8 bits) + val reset = ClockDomain.current.isResetActive + val dut = FormalDut(new StreamDispatcherSequencial(dataType, portCount)) + + assumeInitial(reset) + + val muxInput = slave(Stream(dataType)) + val muxOutputs = Vec(master(Stream(dataType)), portCount) + + muxInput >> dut.io.input + for (i <- 0 until portCount) { + muxOutputs(i) << dut.io.outputs(i) + } + + when(reset || past(reset)) { + assume(muxInput.valid === False) + } + + cover(muxInput.fire) + + muxInput.formalAssumesSlave() + muxInput.formalCovers(3) + + for (i <- 0 until portCount) { + cover(dut.counter.value === i) + muxOutputs(i).formalAssertsMaster() + muxOutputs(i).formalCovers() + } + + for (i <- 0 until portCount) { + when(dut.counter.value =/= i) { + assert(muxOutputs(i).valid === False) + } otherwise { + assert(muxOutputs(i) === muxInput) + } + } + + val d1 = anyconst(UInt(log2Up(portCount) bit)) + assume(d1 < portCount) + val d2 = UInt(log2Up(portCount) bit) + d2 := (d1 + 1) % portCount + + val cntSeqCheck = changed(dut.counter.value) && (dut.counter.value === d2) + cover(cntSeqCheck) + when(cntSeqCheck) { + assert(past(dut.counter.value) === d1) + } + }) + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalDispatcherSequencial.scala b/tester/src/test/scala/spinal/tester/scalatest/FormalDispatcherSequencial.scala deleted file mode 100644 index 839efb2722..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalDispatcherSequencial.scala +++ /dev/null @@ -1,66 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.core.formal._ -import spinal.lib._ -import spinal.lib.formal._ - -class FormalDispatcherSequencialTester extends SpinalFormalFunSuite { - test("DispatcherSequencial-verify") { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(40) - // .withDebug - .doVerify(new Component { - val portCount = 5 - val dataType = Bits(8 bits) - val reset = ClockDomain.current.isResetActive - val dut = FormalDut(new StreamDispatcherSequencial(dataType, portCount)) - - assumeInitial(reset) - - val muxInput = slave(Stream(dataType)) - val muxOutputs = Vec(master(Stream(dataType)), portCount) - - muxInput >> dut.io.input - for (i <- 0 until portCount) { - muxOutputs(i) << dut.io.outputs(i) - } - - when(reset || past(reset)) { - assume(muxInput.valid === False) - } - - cover(muxInput.fire) - - muxInput.formalAssumesSlave() - muxInput.formalCovers(3) - - for (i <- 0 until portCount) { - cover(dut.counter.value === i) - muxOutputs(i).formalAssertsMaster() - muxOutputs(i).formalCovers() - } - - for (i <- 0 until portCount) { - when(dut.counter.value =/= i) { - assert(muxOutputs(i).valid === False) - } otherwise { - assert(muxOutputs(i) === muxInput) - } - } - - val d1 = anyconst(UInt(log2Up(portCount) bit)) - assume(d1 < portCount) - val d2 = UInt(log2Up(portCount) bit) - d2 := (d1 + 1) % portCount - - val cntSeqCheck = changed(dut.counter.value) && (dut.counter.value === d2) - cover(cntSeqCheck) - when(cntSeqCheck) { - assert(past(dut.counter.value) === d1) - } - }) - } -} From 7cc85b5266c0c67278f3625d7493e8aa3defe337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 8 Dec 2022 22:20:27 +0100 Subject: [PATCH 049/120] refactor: move FormalFifoCCTester --- lib/src/test/scala/spinal/lib/Stream.scala | 186 +++++++++++++++++ .../tester/scalatest/FormalFifoCCTester.scala | 192 ------------------ 2 files changed, 186 insertions(+), 192 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/FormalFifoCCTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index d93ee285e8..942ed317f9 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -683,3 +683,189 @@ class FormalDispatcherSequencialTester extends SpinalFormalFunSuite { }) } } + +class FormalFifoCCTester extends SpinalFormalFunSuite { + def formalContext(pushPeriod: Int, popPeriod: Int, seperateReset: Boolean = false) = new Area { + val back2backCycles = 2 + val fifoDepth = 4 + + val pushClock = ClockDomain.current + val reset = pushClock.isResetActive + val popClock = ClockDomain.external("pop") + val popReset = popClock.isResetActive + + val inValue = in(UInt(3 bits)) + val inValid = in(Bool()) + val outReady = in(Bool()) + val gclk = GlobalClock() + + assumeInitial(reset) + assumeInitial(popReset) + + gclk.assumeClockTiming(pushClock, pushPeriod) + gclk.assumeResetReleaseSync(pushClock) + if (!seperateReset) { + gclk.keepBoolLeastCycles(reset, popPeriod) + } + + gclk.assumeClockTiming(popClock, popPeriod) + if (seperateReset) { + gclk.assumeResetReleaseSync(popClock) + gclk.alignAsyncResetStart(pushClock, popClock) + } + + val dut = FormalDut(new StreamFifoCC(cloneOf(inValue), fifoDepth, pushClock, popClock, !seperateReset)) + gclk.assumeIOSync2Clock(pushClock, dut.io.push.valid) + gclk.assumeIOSync2Clock(pushClock, dut.io.push.payload) + gclk.assumeIOSync2Clock(popClock, dut.io.pop.ready) + + dut.io.push.payload := inValue + dut.io.push.valid := inValid + dut.io.pop.ready := outReady + + // assume no valid while reset and one clock later. + when(reset || past(reset)) { + assume(inValid === False) + } + + dut.formalAsserts(gclk.domain) + + val pushArea = new ClockingArea(pushClock) { + dut.io.push.formalAssumesSlave() + dut.io.push.formalCovers() + } + + // back to back transaction cover test. + val popCheckDomain = if (seperateReset) popClock else popClock.copy(reset = reset) + val popArea = new ClockingArea(popCheckDomain) { + dut.io.pop.formalCovers(back2backCycles) + dut.io.pop.formalAssertsMaster() + } + } + + def testMain(pushPeriod: Int, popPeriod: Int, seperateReset: Boolean = false) = { + val proveCycles = 8 + val coverCycles = 8 + val maxPeriod = Math.max(pushPeriod, popPeriod) + + FormalConfig + .withProve(maxPeriod * proveCycles) + .withCover(maxPeriod * coverCycles) + .withAsync + .doVerify(new Component { + val context = formalContext(pushPeriod, popPeriod, seperateReset) + }) + } + + test("fifo-verify fast pop") { + testMain(5, 3) + } + + test("fifo-verify fast push") { + testMain(3, 5) + } + +// test("fifo-verify ultra fast pop") { +// testMain(11, 2) +// } + +// test("fifo-verify ultra fast push") { +// testMain(2, 11) +// } + + test("fifo-verify fast pop reset seperately") { + testMain(5, 3, true) + } + + test("fifo-verify fast push reset seperately") { + testMain(3, 5, true) + } + +// test("fifo-verify ultra fast pop reset seperately") { +// testMain(11, 2, true) +// } + +// test("fifo-verify ultra fast push reset seperately") { +// testMain(2, 11, true) +// } + + def testNoLoss(pushPeriod: Int, popPeriod: Int, seperateReset: Boolean = false) = { + val proveCycles = 8 + val coverCycles = 8 + val maxPeriod = Math.max(pushPeriod, popPeriod) + + FormalConfig + .withCover(maxPeriod * coverCycles) + .withAsync + .withDebug + .doVerify(new Component { + val context = formalContext(pushPeriod, popPeriod, seperateReset) + + val d1 = anyconst(cloneOf(context.inValue)) + val d1_in = RegInit(False) + when(context.inValue === d1 & context.dut.io.push.fire) { + d1_in := True + } + when(d1_in) { assume(context.inValue =/= d1) } + + val popCheckArea = new ClockingArea(context.popCheckDomain) { + val d1_inCC = BufferCC(d1_in) + val cond = d1_inCC & context.dut.io.pop.fire + val hist = History(context.dut.io.pop.payload, context.fifoDepth, cond) + val counter = Counter(context.fifoDepth, inc = cond) + when(!d1_inCC) { counter.clear() } + cover(counter.willOverflow & !hist.sContains(d1)) + } + + val globalCheckArea = new ClockingArea(context.popCheckDomain) { + def checkValidData(cond: UInt => Bool): Seq[Bool] = context.dut.rework { + val maps = for (i <- 0 until context.fifoDepth) yield { + val index = context.dut.popCC.popPtr + i + val out = False + when(i < context.dut.pushCC.pushPtr - context.dut.popCC.popPtr) { + out := cond(context.dut.ram(index.resized)) + } + out + } + maps + } + val fits = checkValidData(_ === d1.pull()) + val containD1 = fits.reduce(_ || _) + when(!d1_in) { assume(!containD1) } + } + }) + } + + test("noloss fast pop") { + shouldFail(testNoLoss(5, 3)) + } + + test("noloss fast push") { + shouldFail(testNoLoss(3, 5)) + } + + // test("noloss ultra fast pop") { + // shouldFail(testNoLoss(11, 2)) + // } + + // test("noloss ultra fast push") { + // shouldFail(testNoLoss(2, 11)) + // } + + test("noloss fast pop reset seperately") { + shouldFail(testNoLoss(5, 3, true)) + } + + test("noloss fast push reset seperately") { + shouldFail(testNoLoss(3, 5, true)) + } + + // test("noloss ultra fast pop reset seperately") { + // shouldFail(testNoLoss(11, 2, true)) + // } + + // test("noloss ultra fast push reset seperately") { + // shouldFail(testNoLoss(2, 11, true)) + // } + +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalFifoCCTester.scala b/tester/src/test/scala/spinal/tester/scalatest/FormalFifoCCTester.scala deleted file mode 100644 index fb460ccb3b..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalFifoCCTester.scala +++ /dev/null @@ -1,192 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.core.formal._ -import spinal.lib._ -import spinal.lib.formal._ - -class FormalFifoCCTester extends SpinalFormalFunSuite { - def formalContext(pushPeriod: Int, popPeriod: Int, seperateReset: Boolean = false) = new Area { - val back2backCycles = 2 - val fifoDepth = 4 - - val pushClock = ClockDomain.current - val reset = pushClock.isResetActive - val popClock = ClockDomain.external("pop") - val popReset = popClock.isResetActive - - val inValue = in(UInt(3 bits)) - val inValid = in(Bool()) - val outReady = in(Bool()) - val gclk = GlobalClock() - - assumeInitial(reset) - assumeInitial(popReset) - - gclk.assumeClockTiming(pushClock, pushPeriod) - gclk.assumeResetReleaseSync(pushClock) - if (!seperateReset) { - gclk.keepBoolLeastCycles(reset, popPeriod) - } - - gclk.assumeClockTiming(popClock, popPeriod) - if (seperateReset) { - gclk.assumeResetReleaseSync(popClock) - gclk.alignAsyncResetStart(pushClock, popClock) - } - - val dut = FormalDut(new StreamFifoCC(cloneOf(inValue), fifoDepth, pushClock, popClock, !seperateReset)) - gclk.assumeIOSync2Clock(pushClock, dut.io.push.valid) - gclk.assumeIOSync2Clock(pushClock, dut.io.push.payload) - gclk.assumeIOSync2Clock(popClock, dut.io.pop.ready) - - dut.io.push.payload := inValue - dut.io.push.valid := inValid - dut.io.pop.ready := outReady - - // assume no valid while reset and one clock later. - when(reset || past(reset)) { - assume(inValid === False) - } - - dut.formalAsserts(gclk.domain) - - val pushArea = new ClockingArea(pushClock) { - dut.io.push.formalAssumesSlave() - dut.io.push.formalCovers() - } - - // back to back transaction cover test. - val popCheckDomain = if (seperateReset) popClock else popClock.copy(reset = reset) - val popArea = new ClockingArea(popCheckDomain) { - dut.io.pop.formalCovers(back2backCycles) - dut.io.pop.formalAssertsMaster() - } - } - - def testMain(pushPeriod: Int, popPeriod: Int, seperateReset: Boolean = false) = { - val proveCycles = 8 - val coverCycles = 8 - val maxPeriod = Math.max(pushPeriod, popPeriod) - - FormalConfig - .withProve(maxPeriod * proveCycles) - .withCover(maxPeriod * coverCycles) - .withAsync - .doVerify(new Component { - val context = formalContext(pushPeriod, popPeriod, seperateReset) - }) - } - - test("fifo-verify fast pop") { - testMain(5, 3) - } - - test("fifo-verify fast push") { - testMain(3, 5) - } - -// test("fifo-verify ultra fast pop") { -// testMain(11, 2) -// } - -// test("fifo-verify ultra fast push") { -// testMain(2, 11) -// } - - test("fifo-verify fast pop reset seperately") { - testMain(5, 3, true) - } - - test("fifo-verify fast push reset seperately") { - testMain(3, 5, true) - } - -// test("fifo-verify ultra fast pop reset seperately") { -// testMain(11, 2, true) -// } - -// test("fifo-verify ultra fast push reset seperately") { -// testMain(2, 11, true) -// } - - def testNoLoss(pushPeriod: Int, popPeriod: Int, seperateReset: Boolean = false) = { - val proveCycles = 8 - val coverCycles = 8 - val maxPeriod = Math.max(pushPeriod, popPeriod) - - FormalConfig - .withCover(maxPeriod * coverCycles) - .withAsync - .withDebug - .doVerify(new Component { - val context = formalContext(pushPeriod, popPeriod, seperateReset) - - val d1 = anyconst(cloneOf(context.inValue)) - val d1_in = RegInit(False) - when(context.inValue === d1 & context.dut.io.push.fire) { - d1_in := True - } - when(d1_in) { assume(context.inValue =/= d1) } - - val popCheckArea = new ClockingArea(context.popCheckDomain) { - val d1_inCC = BufferCC(d1_in) - val cond = d1_inCC & context.dut.io.pop.fire - val hist = History(context.dut.io.pop.payload, context.fifoDepth, cond) - val counter = Counter(context.fifoDepth, inc = cond) - when(!d1_inCC) { counter.clear() } - cover(counter.willOverflow & !hist.sContains(d1)) - } - - val globalCheckArea = new ClockingArea(context.popCheckDomain) { - def checkValidData(cond: UInt => Bool): Seq[Bool] = context.dut.rework { - val maps = for (i <- 0 until context.fifoDepth) yield { - val index = context.dut.popCC.popPtr + i - val out = False - when(i < context.dut.pushCC.pushPtr - context.dut.popCC.popPtr) { - out := cond(context.dut.ram(index.resized)) - } - out - } - maps - } - val fits = checkValidData(_ === d1.pull()) - val containD1 = fits.reduce(_ || _) - when(!d1_in) { assume(!containD1) } - } - }) - } - - test("noloss fast pop") { - shouldFail(testNoLoss(5, 3)) - } - - test("noloss fast push") { - shouldFail(testNoLoss(3, 5)) - } - - // test("noloss ultra fast pop") { - // shouldFail(testNoLoss(11, 2)) - // } - - // test("noloss ultra fast push") { - // shouldFail(testNoLoss(2, 11)) - // } - - test("noloss fast pop reset seperately") { - shouldFail(testNoLoss(5, 3, true)) - } - - test("noloss fast push reset seperately") { - shouldFail(testNoLoss(3, 5, true)) - } - - // test("noloss ultra fast pop reset seperately") { - // shouldFail(testNoLoss(11, 2, true)) - // } - - // test("noloss ultra fast push reset seperately") { - // shouldFail(testNoLoss(2, 11, true)) - // } - -} From ecbeccb0e2ff86230d702ffb246e8b8b868ab881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 8 Dec 2022 22:23:32 +0100 Subject: [PATCH 050/120] refactor: move FormalFifoTester --- lib/src/test/scala/spinal/lib/Stream.scala | 66 +++++++++++++++++ .../tester/scalatest/FormalFifoTester.scala | 72 ------------------- 2 files changed, 66 insertions(+), 72 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/FormalFifoTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index 942ed317f9..9ebec5430b 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -869,3 +869,69 @@ class FormalFifoCCTester extends SpinalFormalFunSuite { // } } + +class FormalFifoTester extends SpinalFormalFunSuite { + test("fifo-verify all") { + val initialCycles = 2 + val inOutDelay = 2 + val coverCycles = 10 + FormalConfig + .withBMC(10) + .withProve(10) + .withCover(coverCycles) + // .withDebug + .doVerify(new Component { + val depth = 4 + val dut = FormalDut(new StreamFifo(UInt(7 bits), depth)) + val reset = ClockDomain.current.isResetActive + + assumeInitial(reset) + + val inValue = anyseq(UInt(7 bits)) + val inValid = anyseq(Bool()) + val outReady = anyseq(Bool()) + dut.io.push.payload := inValue + dut.io.push.valid := inValid + dut.io.pop.ready := outReady + + // assume no valid while reset and one clock later. + when(reset || past(reset)) { + assume(inValid === False) + } + + dut.io.push.formalAssumesSlave() + dut.io.pop.formalAssertsMaster() + + dut.io.push.formalCovers() + // back to back transaction cover test. + dut.io.pop.formalCovers(coverCycles - initialCycles - inOutDelay - 1) + + val d1 = anyconst(UInt(7 bits)) + val d2 = anyconst(UInt(7 bits)) + + val (d1_in, d2_in) = dut.io.push.formalAssumesOrder(d1, d2) + val (d1_out, d2_out) = dut.io.pop.formalAssertsOrder(d1, d2) + + when(!d1_in) { assume(!dut.formalContains(d1)) } + when(d1_in && !d1_out) { assert(dut.formalCount(d1) === 1) } + + when(!d2_in) { assume(!dut.formalContains(d2)) } + when(d2_in && !d2_out) { assert(dut.formalCount(d2) === 1) } + + when(d1_in && d2_in && !d1_out) { assert(!d2_out) } + + def getCompId(x: UInt): UInt = { + val id = OHToUInt(dut.formalCheck(_ === x.pull()).asBits) + val extId = id +^ depth + val compId = CombInit(extId) + when(id >= dut.logic.popPtr) { + compId := id.resized + } + compId + } + when(d1_in && d2_in && !d1_out && !d2_out) { + assert(getCompId(d1) < getCompId(d2)) + } + }) + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalFifoTester.scala b/tester/src/test/scala/spinal/tester/scalatest/FormalFifoTester.scala deleted file mode 100644 index 7e5645e880..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalFifoTester.scala +++ /dev/null @@ -1,72 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.core.formal._ -import spinal.lib.{StreamFifo, History, OHToUInt} -import spinal.lib.formal._ - -class FormalFifoTester extends SpinalFormalFunSuite { - test("fifo-verify all") { - val initialCycles = 2 - val inOutDelay = 2 - val coverCycles = 10 - FormalConfig - .withBMC(10) - .withProve(10) - .withCover(coverCycles) - // .withDebug - .doVerify(new Component { - val depth = 4 - val dut = FormalDut(new StreamFifo(UInt(7 bits), depth)) - val reset = ClockDomain.current.isResetActive - - assumeInitial(reset) - - val inValue = anyseq(UInt(7 bits)) - val inValid = anyseq(Bool()) - val outReady = anyseq(Bool()) - dut.io.push.payload := inValue - dut.io.push.valid := inValid - dut.io.pop.ready := outReady - - // assume no valid while reset and one clock later. - when(reset || past(reset)) { - assume(inValid === False) - } - - dut.io.push.formalAssumesSlave() - dut.io.pop.formalAssertsMaster() - - dut.io.push.formalCovers() - // back to back transaction cover test. - dut.io.pop.formalCovers(coverCycles - initialCycles - inOutDelay - 1) - - val d1 = anyconst(UInt(7 bits)) - val d2 = anyconst(UInt(7 bits)) - - val (d1_in, d2_in) = dut.io.push.formalAssumesOrder(d1, d2) - val (d1_out, d2_out) = dut.io.pop.formalAssertsOrder(d1, d2) - - when(!d1_in) { assume(!dut.formalContains(d1)) } - when(d1_in && !d1_out) { assert(dut.formalCount(d1) === 1) } - - when(!d2_in) { assume(!dut.formalContains(d2)) } - when(d2_in && !d2_out) { assert(dut.formalCount(d2) === 1) } - - when(d1_in && d2_in && !d1_out) { assert(!d2_out) } - - def getCompId(x: UInt): UInt = { - val id = OHToUInt(dut.formalCheck(_ === x.pull()).asBits) - val extId = id +^ depth - val compId = CombInit(extId) - when(id >= dut.logic.popPtr) { - compId := id.resized - } - compId - } - when(d1_in && d2_in && !d1_out && !d2_out) { - assert(getCompId(d1) < getCompId(d2)) - } - }) - } -} From 93238d7b9f293d66e622aa2ed6985273658ef6a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 8 Dec 2022 22:25:37 +0100 Subject: [PATCH 051/120] refactor: move FormalForkTester --- lib/src/test/scala/spinal/lib/Stream.scala | 99 +++++++++++++++++ .../tester/scalatest/FormalForkTester.scala | 105 ------------------ 2 files changed, 99 insertions(+), 105 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/FormalForkTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index 9ebec5430b..62daead1a6 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -935,3 +935,102 @@ class FormalFifoTester extends SpinalFormalFunSuite { }) } } + +class FormalForkTester extends SpinalFormalFunSuite { + def formalfork (synchronous: Boolean = false, back2BackCheck: Boolean = false ) = { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(20) + // .withDebug + .doVerify(new Component { + val portCount = 2 + val dataType = Bits(8 bits) + val dut = FormalDut(new StreamFork(dataType, portCount, synchronous)) + + val reset = ClockDomain.current.isResetActive + + assumeInitial(reset) + + val input = slave(Stream(dataType)) + val outputs = Vec(master(Stream(dataType)), portCount) + + input >> dut.io.input + for (i <- 0 until portCount) { + outputs(i) << dut.io.outputs(i) + } + + when(reset || past(reset)) { + assume(input.valid === False) + } + + cover(input.fire) + + input.formalAssumesSlave() + if(back2BackCheck) input.formalCovers(3) + + for (i <- 0 until portCount) { + assert(outputs(i).payload === input.payload) + outputs(i).formalAssertsMaster() + if(back2BackCheck) outputs(i).formalCovers(3) + } + + val fired = if(!synchronous)Vec(RegInit(True), portCount) else null // store fire status, + val outputsFireAsync = if(!synchronous){fired(0) =/= fired(1)} else null + val out0FireFirst = if(!synchronous){fired(1) && !fired(0)} else null + val out1FireFirst = if(!synchronous){fired(0) && !fired(1)} else null + val out0FireLast = if(!synchronous){~(input.fire ^ outputs(0).fire)} else null + val out1FireLast = if(!synchronous){~(input.fire ^ outputs(1).fire)} else null + + if(synchronous){ + for (i <- 0 until portCount) { + assert(outputs(i).fire === input.fire) + + } + } + else{ + for(i <- 0 until portCount){ + cover(input.ready) + when(input.ready){ + fired(i) := True + } + cover(!input.ready && outputs(i).fire) + when(!input.ready && outputs(i).fire){ + fired(i) := False + } + + assert(fired(i) === dut.logic.linkEnable(i)) + } + + cover(out0FireFirst && !outputs(1).fire) + cover(out1FireFirst && !outputs(0).fire) + + when(outputsFireAsync) { + assert(!past(input.fire)) + } + + when(out0FireFirst) { + assert(out1FireLast) + assert(!outputs(0).valid) + } + + when(out1FireFirst) { + assert(out0FireLast) + assert(!outputs(1).valid) + } + } + }) + } + + test("fork-verify sync") { + formalfork(true,false) + } + + test("fork-verify sync back2Back fail") { + shouldFail(formalfork(true,true)) + } + + test("fork-verify async") { + formalfork(false,true) + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalForkTester.scala b/tester/src/test/scala/spinal/tester/scalatest/FormalForkTester.scala deleted file mode 100644 index 179e513905..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalForkTester.scala +++ /dev/null @@ -1,105 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.core.formal._ -import spinal.lib._ -import spinal.lib.formal._ - -class FormalForkTester extends SpinalFormalFunSuite { - def formalfork (synchronous: Boolean = false, back2BackCheck: Boolean = false ) = { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(20) - // .withDebug - .doVerify(new Component { - val portCount = 2 - val dataType = Bits(8 bits) - val dut = FormalDut(new StreamFork(dataType, portCount, synchronous)) - - val reset = ClockDomain.current.isResetActive - - assumeInitial(reset) - - val input = slave(Stream(dataType)) - val outputs = Vec(master(Stream(dataType)), portCount) - - input >> dut.io.input - for (i <- 0 until portCount) { - outputs(i) << dut.io.outputs(i) - } - - when(reset || past(reset)) { - assume(input.valid === False) - } - - cover(input.fire) - - input.formalAssumesSlave() - if(back2BackCheck) input.formalCovers(3) - - for (i <- 0 until portCount) { - assert(outputs(i).payload === input.payload) - outputs(i).formalAssertsMaster() - if(back2BackCheck) outputs(i).formalCovers(3) - } - - val fired = if(!synchronous)Vec(RegInit(True), portCount) else null // store fire status, - val outputsFireAsync = if(!synchronous){fired(0) =/= fired(1)} else null - val out0FireFirst = if(!synchronous){fired(1) && !fired(0)} else null - val out1FireFirst = if(!synchronous){fired(0) && !fired(1)} else null - val out0FireLast = if(!synchronous){~(input.fire ^ outputs(0).fire)} else null - val out1FireLast = if(!synchronous){~(input.fire ^ outputs(1).fire)} else null - - if(synchronous){ - for (i <- 0 until portCount) { - assert(outputs(i).fire === input.fire) - - } - } - else{ - for(i <- 0 until portCount){ - cover(input.ready) - when(input.ready){ - fired(i) := True - } - cover(!input.ready && outputs(i).fire) - when(!input.ready && outputs(i).fire){ - fired(i) := False - } - - assert(fired(i) === dut.logic.linkEnable(i)) - } - - cover(out0FireFirst && !outputs(1).fire) - cover(out1FireFirst && !outputs(0).fire) - - when(outputsFireAsync) { - assert(!past(input.fire)) - } - - when(out0FireFirst) { - assert(out1FireLast) - assert(!outputs(0).valid) - } - - when(out1FireFirst) { - assert(out0FireLast) - assert(!outputs(1).valid) - } - } - }) - } - - test("fork-verify sync") { - formalfork(true,false) - } - - test("fork-verify sync back2Back fail") { - shouldFail(formalfork(true,true)) - } - - test("fork-verify async") { - formalfork(false,true) - } -} \ No newline at end of file From c63130f27fc0b6c984fa0f7b08243a7618c4986b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 8 Dec 2022 22:32:52 +0100 Subject: [PATCH 052/120] refactor: move FormalHistoryModifyableTester --- .../src/test/scala/spinal/lib/Utils.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tester/src/test/scala/spinal/tester/scalatest/FormalHistoryTester.scala => lib/src/test/scala/spinal/lib/Utils.scala (99%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalHistoryTester.scala b/lib/src/test/scala/spinal/lib/Utils.scala similarity index 99% rename from tester/src/test/scala/spinal/tester/scalatest/FormalHistoryTester.scala rename to lib/src/test/scala/spinal/lib/Utils.scala index 6134c2237c..6893ce67aa 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalHistoryTester.scala +++ b/lib/src/test/scala/spinal/lib/Utils.scala @@ -1,4 +1,4 @@ -package spinal.tester.scalatest +package spinal.lib import spinal.core._ import spinal.core.formal._ From c0eea48a359fa9064a622fd8007ad17ef4a91580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 8 Dec 2022 22:38:21 +0100 Subject: [PATCH 053/120] refactor: move FormalJoinTester --- lib/src/test/scala/spinal/lib/Stream.scala | 63 +++++++++++++++++ .../tester/scalatest/FormalJoinTester.scala | 69 ------------------- 2 files changed, 63 insertions(+), 69 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/FormalJoinTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index 62daead1a6..6024346abe 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -1034,3 +1034,66 @@ class FormalForkTester extends SpinalFormalFunSuite { formalfork(false,true) } } + +class Join[T1 <: Data, T2 <: Data](dataType_0: T1, dataType_1: T2) extends Component { + val io = new Bundle { + val inputs_0 = slave(Stream (dataType_0)) + val inputs_1 = slave(Stream (dataType_1)) + val output = master(Stream(TupleBundle2( + dataType_0, + dataType_1 + ))) + } + val logic = StreamJoin(io.inputs_0,io.inputs_1) + io.output << logic +} + +class FormalJoinTester extends SpinalFormalFunSuite { + test("StreamJoinTester-verify") { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(20) + + // .withDebug + .doVerify(new Component { + val portCount = 5 + val dataType_0 = Bits(8 bits) + val dataType_1 = Bits(16 bits) + val dut = FormalDut(new Join(dataType_0, dataType_1)) + val reset = ClockDomain.current.isResetActive + + assumeInitial(reset) + + val inputs_0 = slave Stream (dataType_0) + val inputs_1 = slave Stream (dataType_1) + val output = master( + Stream( + TupleBundle2( + dataType_0, + dataType_1 + ) + ) + ) + + inputs_0 >> dut.io.inputs_0 + inputs_1 >> dut.io.inputs_1 + output << dut.io.output + + when(reset || past(reset)) { + assume(inputs_0.valid === False) + assume(inputs_1.valid === False) + } + + inputs_0.formalAssumesSlave() + inputs_1.formalAssumesSlave() + output.formalAssertsMaster() + output.formalCovers(3) + + assert(inputs_0.fire === inputs_1.fire) + assert(output.fire === inputs_0.fire) + assert(output.payload._1 === inputs_0.payload) + assert(output.payload._2 === inputs_1.payload) + }) + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalJoinTester.scala b/tester/src/test/scala/spinal/tester/scalatest/FormalJoinTester.scala deleted file mode 100644 index 9e2e819284..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalJoinTester.scala +++ /dev/null @@ -1,69 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.core.formal._ -import spinal.lib._ -import spinal.lib.formal._ - -class StreamJoin[T1 <: Data, T2 <: Data](dataType_0: T1, dataType_1: T2) extends Component { - val io = new Bundle { - val inputs_0 = slave(Stream (dataType_0)) - val inputs_1 = slave(Stream (dataType_1)) - val output = master(Stream(TupleBundle2( - dataType_0, - dataType_1 - ))) - } - val logic = StreamJoin(io.inputs_0,io.inputs_1) - io.output << logic -} - -class FormalJoinTester extends SpinalFormalFunSuite { - test("StreamJoinTester-verify") { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(20) - - // .withDebug - .doVerify(new Component { - val portCount = 5 - val dataType_0 = Bits(8 bits) - val dataType_1 = Bits(16 bits) - val dut = FormalDut(new StreamJoin(dataType_0, dataType_1)) - val reset = ClockDomain.current.isResetActive - - assumeInitial(reset) - - val inputs_0 = slave Stream (dataType_0) - val inputs_1 = slave Stream (dataType_1) - val output = master( - Stream( - TupleBundle2( - dataType_0, - dataType_1 - ) - ) - ) - - inputs_0 >> dut.io.inputs_0 - inputs_1 >> dut.io.inputs_1 - output << dut.io.output - - when(reset || past(reset)) { - assume(inputs_0.valid === False) - assume(inputs_1.valid === False) - } - - inputs_0.formalAssumesSlave() - inputs_1.formalAssumesSlave() - output.formalAssertsMaster() - output.formalCovers(3) - - assert(inputs_0.fire === inputs_1.fire) - assert(output.fire === inputs_0.fire) - assert(output.payload._1 === inputs_0.payload) - assert(output.payload._2 === inputs_1.payload) - }) - } -} From 1c45776eaae8d02ec292207d12394db90e70c75c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 8 Dec 2022 22:39:18 +0100 Subject: [PATCH 054/120] refactor: move FormalMuxTester --- lib/src/test/scala/spinal/lib/Stream.scala | 117 +++++++++++++++++ .../tester/scalatest/FormalMuxTester.scala | 123 ------------------ 2 files changed, 117 insertions(+), 123 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/FormalMuxTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index 6024346abe..f5a40ec729 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -1097,3 +1097,120 @@ class FormalJoinTester extends SpinalFormalFunSuite { }) } } + +class FormalMuxTester extends SpinalFormalFunSuite { + def formalmux(selWithCtrl: Boolean = false) = { + FormalConfig + .withBMC(20) + .withProve(20) + .withCover(20) + // .withDebug + .doVerify(new Component { + val portCount = 5 + val dataType = Bits(8 bits) + val dut = FormalDut(new StreamMux(dataType, portCount)) + + val reset = ClockDomain.current.isResetActive + + assumeInitial(reset) + + val muxSelect = anyseq(UInt(log2Up(portCount) bit)) + val muxInputs = Vec(slave(Stream(dataType)), portCount) + val muxOutput = master(Stream(dataType)) + + dut.io.select := muxSelect + muxOutput << dut.io.output + + assumeInitial(muxSelect < portCount) + val selStableCond = if (selWithCtrl) past(muxOutput.isStall) else null + + when(reset || past(reset)) { + for (i <- 0 until portCount) { + assume(muxInputs(i).valid === False) + } + } + + if (selWithCtrl) { + cover(selStableCond) + when(selStableCond) { + assume(stable(muxSelect)) + } + } + muxOutput.formalAssertsMaster() + muxOutput.formalCovers(5) + + for (i <- 0 until portCount) { + muxInputs(i) >> dut.io.inputs(i) + muxInputs(i).formalAssumesSlave() + } + + cover(muxOutput.fire) + + for (i <- 0 until portCount) { + cover(dut.io.select === i) + muxInputs(i).formalAssumesSlave() + } + + when(muxSelect < portCount) { + assert(muxOutput === muxInputs(muxSelect)) + } + }) + } + test("mux_sel_with_control") { + formalmux(true) + } + test("mux_sel_without_control") { + shouldFail(formalmux(false)) + } + + test("mux_with_selector") { + FormalConfig + .withProve(20) + .withCover(20) + .doVerify(new Component { + val portCount = 5 + val dataType = Bits(8 bits) + val dut = FormalDut(new StreamMux(dataType, portCount)) + val selector = dut.io.createSelector() + + val reset = ClockDomain.current.isResetActive + assumeInitial(reset) + + val muxSelector = slave(cloneOf(selector)) + muxSelector >> selector + val muxInputs = Vec(slave(Stream(dataType)), portCount) + for (i <- 0 until portCount) { + muxInputs(i) >> dut.io.inputs(i) + } + val muxOutput = master(Stream(dataType)) + muxOutput << dut.io.output + + assumeInitial(muxSelector.payload < portCount) + muxSelector.formalAssumesSlave() + + when(reset || past(reset)) { + for (i <- 0 until portCount) { + assume(muxInputs(i).valid === False) + } + assume(muxSelector.valid === False) + } + + muxOutput.formalAssertsMaster() + muxOutput.formalCovers(5) + cover(dut.io.select =/= muxSelector.payload) + cover(changed(muxSelector.payload) & stable(muxSelector.valid) & muxSelector.valid) + val readyBits = muxInputs.map(_.ready).asBits() + assert((readyBits === 0) || (CountOne(readyBits) === 1)) + + for (i <- 0 until portCount) { + cover(dut.io.select === i) + muxInputs(i).formalAssumesSlave() + } + + when(dut.io.select < portCount) { + assert(muxOutput === muxInputs(dut.io.select)) + } + }) + + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalMuxTester.scala b/tester/src/test/scala/spinal/tester/scalatest/FormalMuxTester.scala deleted file mode 100644 index f13842fc24..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalMuxTester.scala +++ /dev/null @@ -1,123 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.core.formal._ -import spinal.lib._ -import spinal.lib.formal._ - -class FormalMuxTester extends SpinalFormalFunSuite { - def formalmux(selWithCtrl: Boolean = false) = { - FormalConfig - .withBMC(20) - .withProve(20) - .withCover(20) - // .withDebug - .doVerify(new Component { - val portCount = 5 - val dataType = Bits(8 bits) - val dut = FormalDut(new StreamMux(dataType, portCount)) - - val reset = ClockDomain.current.isResetActive - - assumeInitial(reset) - - val muxSelect = anyseq(UInt(log2Up(portCount) bit)) - val muxInputs = Vec(slave(Stream(dataType)), portCount) - val muxOutput = master(Stream(dataType)) - - dut.io.select := muxSelect - muxOutput << dut.io.output - - assumeInitial(muxSelect < portCount) - val selStableCond = if (selWithCtrl) past(muxOutput.isStall) else null - - when(reset || past(reset)) { - for (i <- 0 until portCount) { - assume(muxInputs(i).valid === False) - } - } - - if (selWithCtrl) { - cover(selStableCond) - when(selStableCond) { - assume(stable(muxSelect)) - } - } - muxOutput.formalAssertsMaster() - muxOutput.formalCovers(5) - - for (i <- 0 until portCount) { - muxInputs(i) >> dut.io.inputs(i) - muxInputs(i).formalAssumesSlave() - } - - cover(muxOutput.fire) - - for (i <- 0 until portCount) { - cover(dut.io.select === i) - muxInputs(i).formalAssumesSlave() - } - - when(muxSelect < portCount) { - assert(muxOutput === muxInputs(muxSelect)) - } - }) - } - test("mux_sel_with_control") { - formalmux(true) - } - test("mux_sel_without_control") { - shouldFail(formalmux(false)) - } - - test("mux_with_selector") { - FormalConfig - .withProve(20) - .withCover(20) - .doVerify(new Component { - val portCount = 5 - val dataType = Bits(8 bits) - val dut = FormalDut(new StreamMux(dataType, portCount)) - val selector = dut.io.createSelector() - - val reset = ClockDomain.current.isResetActive - assumeInitial(reset) - - val muxSelector = slave(cloneOf(selector)) - muxSelector >> selector - val muxInputs = Vec(slave(Stream(dataType)), portCount) - for (i <- 0 until portCount) { - muxInputs(i) >> dut.io.inputs(i) - } - val muxOutput = master(Stream(dataType)) - muxOutput << dut.io.output - - assumeInitial(muxSelector.payload < portCount) - muxSelector.formalAssumesSlave() - - when(reset || past(reset)) { - for (i <- 0 until portCount) { - assume(muxInputs(i).valid === False) - } - assume(muxSelector.valid === False) - } - - muxOutput.formalAssertsMaster() - muxOutput.formalCovers(5) - cover(dut.io.select =/= muxSelector.payload) - cover(changed(muxSelector.payload) & stable(muxSelector.valid) & muxSelector.valid) - val readyBits = muxInputs.map(_.ready).asBits() - assert((readyBits === 0) || (CountOne(readyBits) === 1)) - - for (i <- 0 until portCount) { - cover(dut.io.select === i) - muxInputs(i).formalAssumesSlave() - } - - when(dut.io.select < portCount) { - assert(muxOutput === muxInputs(dut.io.select)) - } - }) - - } -} From e0699993b48d061ab374837475beff8fa7154424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 8 Dec 2022 22:40:29 +0100 Subject: [PATCH 055/120] refactor: move FormalStreamExtender --- lib/src/test/scala/spinal/lib/Stream.scala | 199 +++++++++++++++++ .../scalatest/FormalStreamExtender.scala | 205 ------------------ 2 files changed, 199 insertions(+), 205 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/FormalStreamExtender.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index f5a40ec729..8989e96c19 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -1214,3 +1214,202 @@ class FormalMuxTester extends SpinalFormalFunSuite { } } + +class FormalStreamExtender extends SpinalFormalFunSuite { + def counterTester() { + FormalConfig + // .withBMC(10) + .withProve(10) + .withCover(10) + .doVerify(new Component { + val inStream = slave Stream (UInt(2 bits)) + val outStream = master Stream (UInt(2 bits)) + val count = in UInt (3 bits) + val dut = FormalDut(StreamTransactionCounter(inStream, outStream, count, false)) + + val inReady = in Bool () + inStream.ready := inReady + val outValid = in Bool () + outStream.valid := outValid + val outPayload = in UInt (2 bits) + outStream.payload := outPayload + + val reset = ClockDomain.current.isResetActive + assumeInitial(reset) + + val countHist = History(count, 2, inStream.fire, init = count.getZero) + when(!dut.io.available) { assume(inReady === False) } + + when(pastValid & past(!reset & inStream.fire)) { assert(dut.io.working) } + when(pastValid & past(dut.io.done & !inStream.fire)) { assert(!dut.io.working) } + + when(dut.io.done) { assert(dut.counter.value >= countHist(1)) } + when(dut.io.working) { + assert(countHist(1) === dut.expected) // key to sync verification logic and internal logic. + when(dut.counter.value === countHist(1) & outStream.fire) { assert(dut.io.done) } + when(!dut.io.done) { assert(!dut.io.available) } + .otherwise { assert(dut.io.available) } + } + .otherwise { assert(dut.io.available) } + val counterHelper = dut.formalAsserts() + + cover(inStream.fire & outStream.fire & dut.io.done) + cover(pastValid & past(dut.io.working) & !dut.io.working) + + inStream.formalAssumesSlave() + outStream.formalAssumesSlave() + + for(i <- 1 until 2) { + inStream.formalCovers(i) + outStream.formalCovers(i) + } + }) + } + + def counterNoDelayTester() { + FormalConfig + // .withBMC(10) + .withProve(10) + .withCover(10) + .doVerify(new Component { + val inStream = slave Stream (UInt(2 bits)) + val outStream = master Stream (UInt(2 bits)) + val count = in UInt (3 bits) + val dut = FormalDut(StreamTransactionCounter(inStream, outStream, count, true)) + + val inReady = in Bool () + inStream.ready := inReady + val outValid = in Bool () + outStream.valid := outValid + val outPayload = in UInt (2 bits) + outStream.payload := outPayload + + val reset = ClockDomain.current.isResetActive + assumeInitial(reset) + + val countHist = History(count, 2, inStream.fire, init = count.getZero) + val expected = countHist(1).getAheadValue() + when(!dut.io.available) { assume(inReady === False) } + + when(inStream.fire) { assert(dut.io.working) } + when(pastValid & past(dut.io.done) & !inStream.fire) { assert(!dut.io.working) } + + when(dut.io.done) { assert(dut.counter.value >= expected) } + when(dut.io.working) { + assert(expected === dut.expected) // key to sync verification logic and internal logic. + when(dut.counter.value === expected & outStream.fire) { assert(dut.io.done) } + when(!inStream.fire) { assert(!dut.io.available) } + .otherwise { assert(dut.io.available) } + } + .otherwise { assert(dut.io.available) } + cover(pastValid & past(dut.io.done) & inStream.fire) + cover(pastValid & past(dut.io.working) & !dut.io.working) + + inStream.formalAssumesSlave() + outStream.formalAssumesSlave() + + for(i <- 1 until 2) { + inStream.formalCovers(i) + outStream.formalCovers(i) + } + }) + } + + def extenderTester() { + FormalConfig + // .withBMC(10) + .withProve(10) + .withCover(10) + .doVerify(new Component { + val inStream = slave Stream (UInt(2 bits)) + val outStream = master Stream (UInt(2 bits)) + val count = in UInt (3 bits) + val dut = FormalDut(StreamTransactionExtender(inStream, outStream, count) { (_, p, _) => p }) + + val reset = ClockDomain.current.isResetActive + assumeInitial(reset) + + val countHist = History(count, 2, inStream.fire, init = count.getZero) + + when(pastValid & past(!reset & inStream.fire)) { assert(dut.io.working) } + when(pastValid & past(dut.io.done & !inStream.fire)) { assert(!dut.io.working) } + + when(dut.io.done) { assert(dut.counter.counter.value >= countHist(1)) } + when(dut.io.working) { + assert(countHist(1) === dut.counter.expected) // key to sync verification logic and internal logic. + when(dut.counter.counter.value === countHist(1) & outStream.fire) { assert(dut.io.done) } + when(!dut.io.done) { assert(!inStream.ready) } + } + cover(inStream.fire & outStream.fire & dut.io.done) + cover(pastValid & past(dut.io.working) & !dut.io.working) + + inStream.formalAssumesSlave() + outStream.formalAssertsMaster() + + for(i <- 1 until 2) { + inStream.formalCovers(i) + outStream.formalCovers(i) + } + }) + } + + + def extenderNoDelayTester() { + FormalConfig + // .withBMC(10) + .withProve(10) + .withCover(10) + .doVerify(new Component { + val inStream = slave Stream (UInt(2 bits)) + val outStream = master Stream (UInt(2 bits)) + val count = in UInt (3 bits) + val dut = FormalDut(StreamTransactionExtender(inStream, outStream, count, true) { (_, p, _) => p }) + + val reset = ClockDomain.current.isResetActive + assumeInitial(reset) + + val countHist = History(count, 2, inStream.fire, init = count.getZero) + val expected = countHist(1).getAheadValue() + + when(inStream.fire) { assert(dut.io.working) } + when(pastValid & past(dut.io.done) & !inStream.fire) { assert(!dut.io.working) } + + when(dut.io.done) { assert(dut.counter.counter.value >= expected) } + when(dut.io.working) { + assert(expected === dut.counter.expected) // key to sync verification logic and internal logic. + when(dut.counter.counter.value === expected & outStream.fire) { assert(dut.io.done) } + when(!inStream.fire) { assert(!dut.counter.io.available) } + .otherwise { assert(dut.counter.io.available) } + when(!dut.io.input.fire) { assert(!inStream.ready) } + when(dut.io.input.fire) { assert(dut.io.input.payload === dut.io.output.payload) } + .otherwise { assert(dut.io.output.payload === dut.payloadReg) } + } + cover(pastValid & past(dut.io.done) & inStream.fire) + cover(pastValid & past(dut.io.working) & !dut.io.working) + + inStream.formalAssumesSlave() + outStream.formalAssertsMaster() + + for(i <- 1 until 2) { + inStream.formalCovers(i) + outStream.formalCovers(i) + } + }) + } + + test("transaction counter") { + counterTester() + } + + test("transaction counter without delay") { + counterNoDelayTester() + } + + test("transaction extender") { + extenderTester() + } + + test("transaction extender without delay") { + extenderNoDelayTester() + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalStreamExtender.scala b/tester/src/test/scala/spinal/tester/scalatest/FormalStreamExtender.scala deleted file mode 100644 index 02ee10eea1..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalStreamExtender.scala +++ /dev/null @@ -1,205 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.core.formal._ -import spinal.lib._ -import spinal.lib.formal._ - -class FormalStreamExtender extends SpinalFormalFunSuite { - def counterTester() { - FormalConfig - // .withBMC(10) - .withProve(10) - .withCover(10) - .doVerify(new Component { - val inStream = slave Stream (UInt(2 bits)) - val outStream = master Stream (UInt(2 bits)) - val count = in UInt (3 bits) - val dut = FormalDut(StreamTransactionCounter(inStream, outStream, count, false)) - - val inReady = in Bool () - inStream.ready := inReady - val outValid = in Bool () - outStream.valid := outValid - val outPayload = in UInt (2 bits) - outStream.payload := outPayload - - val reset = ClockDomain.current.isResetActive - assumeInitial(reset) - - val countHist = History(count, 2, inStream.fire, init = count.getZero) - when(!dut.io.available) { assume(inReady === False) } - - when(pastValid & past(!reset & inStream.fire)) { assert(dut.io.working) } - when(pastValid & past(dut.io.done & !inStream.fire)) { assert(!dut.io.working) } - - when(dut.io.done) { assert(dut.counter.value >= countHist(1)) } - when(dut.io.working) { - assert(countHist(1) === dut.expected) // key to sync verification logic and internal logic. - when(dut.counter.value === countHist(1) & outStream.fire) { assert(dut.io.done) } - when(!dut.io.done) { assert(!dut.io.available) } - .otherwise { assert(dut.io.available) } - } - .otherwise { assert(dut.io.available) } - val counterHelper = dut.formalAsserts() - - cover(inStream.fire & outStream.fire & dut.io.done) - cover(pastValid & past(dut.io.working) & !dut.io.working) - - inStream.formalAssumesSlave() - outStream.formalAssumesSlave() - - for(i <- 1 until 2) { - inStream.formalCovers(i) - outStream.formalCovers(i) - } - }) - } - - def counterNoDelayTester() { - FormalConfig - // .withBMC(10) - .withProve(10) - .withCover(10) - .doVerify(new Component { - val inStream = slave Stream (UInt(2 bits)) - val outStream = master Stream (UInt(2 bits)) - val count = in UInt (3 bits) - val dut = FormalDut(StreamTransactionCounter(inStream, outStream, count, true)) - - val inReady = in Bool () - inStream.ready := inReady - val outValid = in Bool () - outStream.valid := outValid - val outPayload = in UInt (2 bits) - outStream.payload := outPayload - - val reset = ClockDomain.current.isResetActive - assumeInitial(reset) - - val countHist = History(count, 2, inStream.fire, init = count.getZero) - val expected = countHist(1).getAheadValue() - when(!dut.io.available) { assume(inReady === False) } - - when(inStream.fire) { assert(dut.io.working) } - when(pastValid & past(dut.io.done) & !inStream.fire) { assert(!dut.io.working) } - - when(dut.io.done) { assert(dut.counter.value >= expected) } - when(dut.io.working) { - assert(expected === dut.expected) // key to sync verification logic and internal logic. - when(dut.counter.value === expected & outStream.fire) { assert(dut.io.done) } - when(!inStream.fire) { assert(!dut.io.available) } - .otherwise { assert(dut.io.available) } - } - .otherwise { assert(dut.io.available) } - cover(pastValid & past(dut.io.done) & inStream.fire) - cover(pastValid & past(dut.io.working) & !dut.io.working) - - inStream.formalAssumesSlave() - outStream.formalAssumesSlave() - - for(i <- 1 until 2) { - inStream.formalCovers(i) - outStream.formalCovers(i) - } - }) - } - - def extenderTester() { - FormalConfig - // .withBMC(10) - .withProve(10) - .withCover(10) - .doVerify(new Component { - val inStream = slave Stream (UInt(2 bits)) - val outStream = master Stream (UInt(2 bits)) - val count = in UInt (3 bits) - val dut = FormalDut(StreamTransactionExtender(inStream, outStream, count) { (_, p, _) => p }) - - val reset = ClockDomain.current.isResetActive - assumeInitial(reset) - - val countHist = History(count, 2, inStream.fire, init = count.getZero) - - when(pastValid & past(!reset & inStream.fire)) { assert(dut.io.working) } - when(pastValid & past(dut.io.done & !inStream.fire)) { assert(!dut.io.working) } - - when(dut.io.done) { assert(dut.counter.counter.value >= countHist(1)) } - when(dut.io.working) { - assert(countHist(1) === dut.counter.expected) // key to sync verification logic and internal logic. - when(dut.counter.counter.value === countHist(1) & outStream.fire) { assert(dut.io.done) } - when(!dut.io.done) { assert(!inStream.ready) } - } - cover(inStream.fire & outStream.fire & dut.io.done) - cover(pastValid & past(dut.io.working) & !dut.io.working) - - inStream.formalAssumesSlave() - outStream.formalAssertsMaster() - - for(i <- 1 until 2) { - inStream.formalCovers(i) - outStream.formalCovers(i) - } - }) - } - - - def extenderNoDelayTester() { - FormalConfig - // .withBMC(10) - .withProve(10) - .withCover(10) - .doVerify(new Component { - val inStream = slave Stream (UInt(2 bits)) - val outStream = master Stream (UInt(2 bits)) - val count = in UInt (3 bits) - val dut = FormalDut(StreamTransactionExtender(inStream, outStream, count, true) { (_, p, _) => p }) - - val reset = ClockDomain.current.isResetActive - assumeInitial(reset) - - val countHist = History(count, 2, inStream.fire, init = count.getZero) - val expected = countHist(1).getAheadValue() - - when(inStream.fire) { assert(dut.io.working) } - when(pastValid & past(dut.io.done) & !inStream.fire) { assert(!dut.io.working) } - - when(dut.io.done) { assert(dut.counter.counter.value >= expected) } - when(dut.io.working) { - assert(expected === dut.counter.expected) // key to sync verification logic and internal logic. - when(dut.counter.counter.value === expected & outStream.fire) { assert(dut.io.done) } - when(!inStream.fire) { assert(!dut.counter.io.available) } - .otherwise { assert(dut.counter.io.available) } - when(!dut.io.input.fire) { assert(!inStream.ready) } - when(dut.io.input.fire) { assert(dut.io.input.payload === dut.io.output.payload) } - .otherwise { assert(dut.io.output.payload === dut.payloadReg) } - } - cover(pastValid & past(dut.io.done) & inStream.fire) - cover(pastValid & past(dut.io.working) & !dut.io.working) - - inStream.formalAssumesSlave() - outStream.formalAssertsMaster() - - for(i <- 1 until 2) { - inStream.formalCovers(i) - outStream.formalCovers(i) - } - }) - } - - test("transaction counter") { - counterTester() - } - - test("transaction counter without delay") { - counterNoDelayTester() - } - - test("transaction extender") { - extenderTester() - } - - test("transaction extender without delay") { - extenderNoDelayTester() - } -} From 119bcee6d6271e1875a49ff2cb158f00631d3964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sat, 10 Dec 2022 01:21:17 +0100 Subject: [PATCH 056/120] refactor: move Issue963 --- .../Issue963Tester.scala => issues/Issue963.scala} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tester/src/test/scala/{spinal/tester/scalatest/Issue963Tester.scala => issues/Issue963.scala} (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/Issue963Tester.scala b/tester/src/test/scala/issues/Issue963.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/Issue963Tester.scala rename to tester/src/test/scala/issues/Issue963.scala index 3b9eea9be7..f04ab88ba6 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/Issue963Tester.scala +++ b/tester/src/test/scala/issues/Issue963.scala @@ -1,10 +1,10 @@ -package spinal.tester.scalatest +package issues import org.scalatest.funsuite.AnyFunSuite import spinal.core._ -import spinal.lib._ import spinal.core.sim._ +import spinal.lib._ // unit test for issue #963 @@ -27,7 +27,7 @@ import spinal.core.sim._ // [info] Tests: succeeded 0, failed 1, canceled 0, ignored 0, pending 0 // [info] *** 1 TEST FAILED *** -class Issue963Tester extends AnyFunSuite { +class Issue963 extends AnyFunSuite { test("Minimal example for Issue963 which fails Spinal elaboration") { class Dut extends Component { val io = new Bundle { From cf3e99ca8fb24a31c6cdc447ea476b4733ea1db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sat, 10 Dec 2022 01:21:41 +0100 Subject: [PATCH 057/120] refactor: move MultiClockTester --- .../test/scala/spinal/core/ClockDomain.scala | 37 +++++++++++++ .../tester/scalatest/MultiClockTester.scala | 52 ------------------- 2 files changed, 37 insertions(+), 52 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/MultiClockTester.scala diff --git a/core/src/test/scala/spinal/core/ClockDomain.scala b/core/src/test/scala/spinal/core/ClockDomain.scala index 59fc0199a0..9dfd85f0fd 100644 --- a/core/src/test/scala/spinal/core/ClockDomain.scala +++ b/core/src/test/scala/spinal/core/ClockDomain.scala @@ -197,3 +197,40 @@ class ClockDomainConfigTesterCocotbBoot extends SpinalTesterCocotbBase { override def pythonTestLocation: String = "tester/src/test/python/spinal/ClockDomainConfigTester" override def createToplevel: Component = new ClockDomainConfigTester.ClockDomainConfigTester() } + +class MultiClockTester extends Component { + import spinal.lib._ + + class BundleA extends Bundle{ + val a = UInt(8 bit) + val b = Bool() + } + + val io = new Bundle { + val clkA = in Bool() + val resetA = in Bool() + val clkB = in Bool() + val resetB = in Bool() + + val slave0 = slave Stream(new BundleA) + val master0 = master Stream(new BundleA) + val fifo0_pushOccupancy = out UInt() + val fifo0_popOccupancy = out UInt() + } + + val clockDomainA = ClockDomain(io.clkA,io.resetA) + val clockDomainB = ClockDomain(io.clkB,io.resetB) + + val fifo0 = new StreamFifoCC(new BundleA,16,clockDomainA,clockDomainB) + fifo0.io.push << io.slave0 + fifo0.io.pop >> io.master0 + io.fifo0_pushOccupancy := fifo0.io.pushOccupancy + io.fifo0_popOccupancy := fifo0.io.popOccupancy + +} + +class MultiClockTesterCocotbBoot extends SpinalTesterCocotbBase { + override def getName: String = "MultiClockTester" + override def pythonTestLocation: String = "tester/src/test/python/spinal/MultiClockTester" + override def createToplevel: Component = new MultiClockTester +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/MultiClockTester.scala b/tester/src/test/scala/spinal/tester/scalatest/MultiClockTester.scala deleted file mode 100644 index 5f3a9a6dfe..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/MultiClockTester.scala +++ /dev/null @@ -1,52 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.lib._ - - -object MultiClockTester{ - class BundleA extends Bundle{ - val a = UInt(8 bit) - val b = Bool() - } -} - -import spinal.tester.scalatest.StreamTester._ - -class MultiClockTester extends Component { - import MultiClockTester._ - val io = new Bundle { - val clkA = in Bool() - val resetA = in Bool() - val clkB = in Bool() - val resetB = in Bool() - - val slave0 = slave Stream(new BundleA) - val master0 = master Stream(new BundleA) - val fifo0_pushOccupancy = out UInt() - val fifo0_popOccupancy = out UInt() - } - - val clockDomainA = ClockDomain(io.clkA,io.resetA) - val clockDomainB = ClockDomain(io.clkB,io.resetB) - - val fifo0 = new StreamFifoCC(new BundleA,16,clockDomainA,clockDomainB) - fifo0.io.push << io.slave0 - fifo0.io.pop >> io.master0 - io.fifo0_pushOccupancy := fifo0.io.pushOccupancy - io.fifo0_popOccupancy := fifo0.io.popOccupancy - -} - - - -//class MultiClockTesterGhdlBoot extends SpinalTesterGhdlBase { -// override def getName: String = "MultiClockTester" -// override def createToplevel: Component = new MultiClockTester -//} - -class MultiClockTesterCocotbBoot extends SpinalTesterCocotbBase { - override def getName: String = "MultiClockTester" - override def pythonTestLocation: String = "tester/src/test/python/spinal/MultiClockTester" - override def createToplevel: Component = new MultiClockTester -} \ No newline at end of file From ad688254263c77c3b46b630d38c5c2c1ac543740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sat, 10 Dec 2022 01:26:43 +0100 Subject: [PATCH 058/120] refactor: move PDMTester --- .../src/test/scala/spinal/lib/misc/PDM.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/PDMTester.scala => lib/src/test/scala/spinal/lib/misc/PDM.scala (88%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/PDMTester.scala b/lib/src/test/scala/spinal/lib/misc/PDM.scala similarity index 88% rename from tester/src/test/scala/spinal/tester/scalatest/PDMTester.scala rename to lib/src/test/scala/spinal/lib/misc/PDM.scala index 844e5848c7..77ef977c33 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/PDMTester.scala +++ b/lib/src/test/scala/spinal/lib/misc/PDM.scala @@ -1,8 +1,7 @@ -package spinal.tester.scalatest +package spinal.lib.misc.pdm import spinal.core._ -import spinal.lib._ -import spinal.lib.misc.pdm._ +import spinal.tester.SpinalTesterCocotbBase class PDMTester extends Component { val io = new Bundle { From 2788d7d632c78622baddf53c40f98681fe42b19c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 12:47:53 +0100 Subject: [PATCH 059/120] refactor: move PinsecTester --- .../scala/spinal/lib/soc/pinsec/Pinsec.scala | 55 +++++++++ .../tester/scalatest/PinsecTester.scala | 108 ------------------ 2 files changed, 55 insertions(+), 108 deletions(-) create mode 100644 lib/src/test/scala/spinal/lib/soc/pinsec/Pinsec.scala delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/PinsecTester.scala diff --git a/lib/src/test/scala/spinal/lib/soc/pinsec/Pinsec.scala b/lib/src/test/scala/spinal/lib/soc/pinsec/Pinsec.scala new file mode 100644 index 0000000000..5699bbea29 --- /dev/null +++ b/lib/src/test/scala/spinal/lib/soc/pinsec/Pinsec.scala @@ -0,0 +1,55 @@ +package spinal.lib.soc.pinsec + +import org.scalatest.{Stepwise, Sequential, Suites} +import spinal.tester.SpinalTesterCocotbBase + +import spinal.core._ +import spinal.lib._ +import spinal.lib.io.TriStateArray +import spinal.lib.com.jtag.Jtag +import spinal.lib.com.uart.Uart + +class PinsecTesterCocotbBoot extends SpinalTesterCocotbBase { + override def getName: String = "PinsecTester" + + override def pythonTests: Seq[(String, String)] = List( + "jtag" -> "tester/src/test/python/spinal/Pinsec/jtag", + "uart" -> "tester/src/test/python/spinal/Pinsec/uart" + ) + + override def createToplevel: Component = { + val pinsec = new Pinsec(PinsecConfig.default.copy(axiFrequency = 133 MHz)) + pinsec.axi.ram.ram.randBoot() + + val sdramPowerupCounter = pinsec.axi.sdramCtrl.ctrl.powerup.counter + sdramPowerupCounter.component.rework( + sdramPowerupCounter init sdramPowerupCounter.maxValue - 100 + ) + + val miaou = pinsec.axi.ram.rework(new Area { + import pinsec.axi.ram._ + + val port = ram.writePort + port.valid.setName("ram_port0_write") := False + port.address.setName("ram_port0_address") := 0 + port.data.setName("ram_port0_writeData") := 0 + + val a = Bool().setName("ram_port0_enable") + val b = Bits(4 bits).setName("ram_port0_mask") + a := False + b := 0 + }) + + miaou.a.pull() + miaou.b.pull() + pinsec + } + + override def backendConfig(config: SpinalConfig) = config.mode match { + case `Verilog` => + config.copy(mergeAsyncProcess = false) // avoid iverilog bug + case _ => config + } + + override def noVhdl = true +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/PinsecTester.scala b/tester/src/test/scala/spinal/tester/scalatest/PinsecTester.scala deleted file mode 100644 index 4b6d5f7c9d..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/PinsecTester.scala +++ /dev/null @@ -1,108 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.{Stepwise, Sequential, Suites} -import spinal.core._ -import spinal.lib._ -import spinal.lib.com.jtag.Jtag -import spinal.lib.com.uart.Uart -import spinal.lib.io.TriStateArray -import spinal.lib.memory.sdram.sdr.IS42x320D -import spinal.lib.{master, slave} -import spinal.lib.soc.pinsec.{PinsecConfig, PinsecTimerCtrlExternal, Pinsec} - -/** - * Created by PIC32F_USER on 22/08/2016. -*/ - - - -//object PinsecTester{ -// case class SdramModel() extends BlackBox{ -// val Dq = in Bool() -// val Addr = in Bool() -// val Ba = in Bool() -// val Clk = in Bool() -// val Cke = in Bool() -// val Cs_n = in Bool() -// val Ras_n = in Bool() -// val Cas_n = in Bool() -// val We_n = in Bool() -// val Dqm = in Bool() -// } -// -// case class PinsecTester() extends Component{ -// val io = new Bundle{ -// val asyncReset = in Bool() -// val axiClk = in Bool() -// val jtag_tck = in Bool() -// val jtag = slave(Jtag()) -// val gpioA = master(TriStateArray(32 bits)) -// val gpioB = master(TriStateArray(32 bits)) -// val timerExternal = in(PinsecTimerCtrlExternal()) -// val uart = master(Uart()) -// } -// -// val pinsec = new Pinsec() -// io.asyncReset <> pinsec.io.asyncReset -// io.axiClk <> pinsec.io.axiClk -// io.jtag_tck <> pinsec.io.jtag_tck -// io.jtag <> pinsec.io.jtag -// io.gpioA <> pinsec.io.gpioA -// io.gpioB <> pinsec.io.gpioB -// io.timerExternal <> pinsec.io.timerExternal -// io.uart <> pinsec.io.uart -// } -//} - -class PinsecTesterCocotbBoot extends SpinalTesterCocotbBase { - override def getName: String = "PinsecTester" - override def pythonTests: Seq[(String,String)] = List( - "jtag" -> "tester/src/test/python/spinal/Pinsec/jtag", - "uart" -> "tester/src/test/python/spinal/Pinsec/uart" - ) - override def createToplevel: Component = { - val pinsec = new Pinsec(PinsecConfig.default.copy(axiFrequency = 133 MHz)) -// pinsec.axi.rom.ram.randBoot() - pinsec.axi.ram.ram.randBoot() - val sdramPowerupCounter = pinsec.axi.sdramCtrl.ctrl.powerup.counter - sdramPowerupCounter.component.rework( - sdramPowerupCounter init(sdramPowerupCounter.maxValue - 100) - ) - val miaou = pinsec.axi.ram.rework(new Area{ - import pinsec.axi.ram._ - - val port = ram.writePort - port.valid.setName("ram_port0_write") := False - port.address.setName("ram_port0_address") := 0 - port.data.setName("ram_port0_writeData") := 0 - - val a = Bool().setName("ram_port0_enable") - val b = Bits(4 bits).setName("ram_port0_mask") - a := False - b := 0 - }) - miaou.a.pull() - miaou.b.pull() - pinsec - } - override def backendConfig(config: SpinalConfig) = config.mode match { - case `Verilog` => config.copy(mergeAsyncProcess = false) // avoid iverilog bug - case _ => config - } - override def noVhdl = true - -// withWaveform = true -} - - -// -//class OrderedSuite extends Stepwise( -// new BundleTesterCocotbBoot, -// -// new FixedPointTesterCocotbBoot, -// new WhenTesterCocotbBoot, -// new StreamTesterCocotbBoot, -// new BlackboxTesterCocotbBoot -// , -// new ZeroWidthTesterCocotbBoot -//) \ No newline at end of file From 8652fa36006aa1658444a89957d1a06e7dd22e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 13:02:55 +0100 Subject: [PATCH 060/120] refactor: move SimBigIntPimperTest --- .../src/test/scala/spinal/core/sim/package.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SimBigIntPimperTest.scala => core/src/test/scala/spinal/core/sim/package.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SimBigIntPimperTest.scala b/core/src/test/scala/spinal/core/sim/package.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/SimBigIntPimperTest.scala rename to core/src/test/scala/spinal/core/sim/package.scala index 53f9d960af..72303c96e0 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SimBigIntPimperTest.scala +++ b/core/src/test/scala/spinal/core/sim/package.scala @@ -1,7 +1,6 @@ -package spinal.tester.scalatest +package spinal.core.sim import org.scalatest.funsuite.AnyFunSuite -import spinal.core.sim._ import spinal.core.{BIG, Endianness, LITTLE} class SimBigIntPimperTest extends AnyFunSuite { From 408004aec9553832739ca705073aeaf9d14dcb67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 13:11:12 +0100 Subject: [PATCH 061/120] refactor: move Pr990 --- .../scalatest/PR990TesterDut.scala => issues/Pr990.scala} | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename tester/src/test/scala/{spinal/tester/scalatest/PR990TesterDut.scala => issues/Pr990.scala} (95%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/PR990TesterDut.scala b/tester/src/test/scala/issues/Pr990.scala similarity index 95% rename from tester/src/test/scala/spinal/tester/scalatest/PR990TesterDut.scala rename to tester/src/test/scala/issues/Pr990.scala index 4733811f17..3b0021eb0d 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/PR990TesterDut.scala +++ b/tester/src/test/scala/issues/Pr990.scala @@ -1,4 +1,6 @@ -package spinal.tester.scalatest +package issues + +import spinal.tester.SpinalSimFunSuite import spinal.core._ import spinal.core.sim._ @@ -34,7 +36,7 @@ class PR990TesterDut extends Component { ) } -class PR990Tester extends SpinalSimFunSuite { +class Pr990 extends SpinalSimFunSuite { test("ccexercise") { val sim =SpinalSimConfig().allOptimisation.compile(new PR990TesterDut) sim.doSimUntilVoid("ccexercise") { dut => From 0fcb8d93a4d247faeab5586d4f96e5ae73989205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 13:13:16 +0100 Subject: [PATCH 062/120] refactor: rename issues -> fixes --- tester/src/test/scala/{issues => fixes}/Issue963.scala | 2 +- tester/src/test/scala/{issues => fixes}/Pr990.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename tester/src/test/scala/{issues => fixes}/Issue963.scala (99%) rename tester/src/test/scala/{issues => fixes}/Pr990.scala (99%) diff --git a/tester/src/test/scala/issues/Issue963.scala b/tester/src/test/scala/fixes/Issue963.scala similarity index 99% rename from tester/src/test/scala/issues/Issue963.scala rename to tester/src/test/scala/fixes/Issue963.scala index f04ab88ba6..07579f2b8a 100644 --- a/tester/src/test/scala/issues/Issue963.scala +++ b/tester/src/test/scala/fixes/Issue963.scala @@ -1,4 +1,4 @@ -package issues +package fixes import org.scalatest.funsuite.AnyFunSuite diff --git a/tester/src/test/scala/issues/Pr990.scala b/tester/src/test/scala/fixes/Pr990.scala similarity index 99% rename from tester/src/test/scala/issues/Pr990.scala rename to tester/src/test/scala/fixes/Pr990.scala index 3b0021eb0d..8e01b7dc64 100644 --- a/tester/src/test/scala/issues/Pr990.scala +++ b/tester/src/test/scala/fixes/Pr990.scala @@ -1,4 +1,4 @@ -package issues +package fixes import spinal.tester.SpinalSimFunSuite From 76fbeda60f138a79ee00169c7062f0164caaf81b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 13:24:28 +0100 Subject: [PATCH 063/120] refactor: move SpinalSimApbI2C --- .../spinal/lib/com/i2c/Apb3I2cCtrl.scala | 479 ++++++++++++++++- .../tester/scalatest/SpinalSimApbI2C.scala | 488 ------------------ 2 files changed, 478 insertions(+), 489 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimApbI2C.scala diff --git a/lib/src/test/scala/spinal/lib/com/i2c/Apb3I2cCtrl.scala b/lib/src/test/scala/spinal/lib/com/i2c/Apb3I2cCtrl.scala index 19b8b97509..4b379a9052 100644 --- a/lib/src/test/scala/spinal/lib/com/i2c/Apb3I2cCtrl.scala +++ b/lib/src/test/scala/spinal/lib/com/i2c/Apb3I2cCtrl.scala @@ -19,8 +19,13 @@ package spinal.lib.com.i2c import spinal.core._ +import spinal.core.sim._ +import spinal.lib._ +import spinal.lib.bus.amba3.apb.Apb3 -import spinal.tester.SpinalTesterCocotbBase +import spinal.tester.{SpinalSimFunSuite, SpinalTesterCocotbBase} + +import scala.collection.mutable.ListBuffer class Apb3I2cSlaveTester extends SpinalTesterCocotbBase { override def getName: String = "Apb3I2cSlaveTester" @@ -37,3 +42,475 @@ class Apb3I2cSlaveTester extends SpinalTesterCocotbBase { ).setDefinitionName("Apb3I2cSlave") } +trait I2CEvent + +case class Start_i2c() extends I2CEvent { + override def toString: String = "Start" +} + +case class Restart_i2c() extends I2CEvent { + override def toString: String = "reStart" +} + +case class Stop_i2c() extends I2CEvent { + override def toString: String = "Stop" +} + +case class DataRead_i2c(value: Byte, ack: Boolean) extends I2CEvent { + def ==(that: DataWrite_i2c) = (this.value == that.value) && (this.ack == that.ack) + override def toString: String = f"Data Read (0x${value}%02X / ${ack})" +} + +case class DataWrite_i2c(value: Byte, ack: Boolean) extends I2CEvent { + def ==(that: DataWrite_i2c) = (this.value == that.value) && (this.ack == that.ack) + override def toString: String = f"Data Write (0x${value}%02X / ${ack})" +} + + + + +case class Apb3Sim(dut: Apb3, clockDomain: ClockDomain){ + + def initIO(): Unit = { + dut.PSEL #= 0 + dut.PADDR.randomize() + dut.PENABLE.randomize() + dut.PWRITE.randomize() + dut.PWDATA.randomize() + } + + def write(address: BigInt, data: BigInt, sel: BigInt = 1): Unit ={ + dut.PADDR #= address + dut.PSEL #= sel + dut.PENABLE #= false + dut.PWRITE #= true + dut.PWDATA #= data + clockDomain.waitActiveEdge() + dut.PENABLE #= true + + clockDomain.waitActiveEdgeWhere(dut.PREADY.toBoolean) + initIO() + } + + def read(address: BigInt, sel: BigInt = 1): BigInt = { + dut.PADDR #= address + dut.PSEL #= sel + dut.PENABLE #= false + dut.PWRITE #= false + dut.PWDATA.randomize() + clockDomain.waitActiveEdge() + + dut.PENABLE #= true + clockDomain.waitActiveEdgeWhere(dut.PREADY.toBoolean) + initIO() + + return dut.PRDATA.toBigInt + } +} + +class OpenDrainSoftConnection(interconnect: OpenDrainInterconnect){ + + var _value = true + + def write(value: Boolean): Unit ={ + if(_value != value){ + _value = value + interconnect.evaluate() + } + } + + def read(): Boolean = interconnect.value +} + + +class OpenDrainInterconnect(clockDomain: ClockDomain){ + + val hardWriters = ListBuffer[Bool]() + val hardReaders = ListBuffer[Bool]() + val softConnections = ListBuffer[OpenDrainSoftConnection]() + var value = true + + def pinWatcher(driver: Bool) = fork{ + var state = driver.toBoolean + while(true){ + waitUntil(state != driver.toBoolean) + state = driver.toBoolean + evaluate() + } + } + + def newSoftConnection(): OpenDrainSoftConnection ={ + val endPoint = new OpenDrainSoftConnection(this) + softConnections += endPoint + return endPoint + } + + def addHardDriver(driver: Bool) = { + hardWriters += driver + pinWatcher(driver ) + } + + def addHardReader(reader: Bool) = { + hardReaders += reader + reader #= true + } + + def evaluate(): Unit = { + var newValue = true + + for(soft <- softConnections){ + newValue &= soft._value + } + + for (hard <- hardWriters){ + newValue &= hard.toBoolean + } + + if (newValue != value){ + value = newValue + for (reader <- hardReaders){ + reader #= value + } + } + + clockDomain.waitActiveEdge() + } +} + + + +class SpinalSimApbI2C extends SpinalSimFunSuite { + + case class I2CSlaveModel(sda: OpenDrainSoftConnection, scl: OpenDrainSoftConnection){ + + val cmdSlave = new ListBuffer[I2CEvent]() + + def run() = fork{ + + var busy = true + var index = 0 + + waitUntil(cmdSlave.length != 0) + + while(busy){ + + val cmd = cmdSlave(index) + + if(cmd.isInstanceOf[Start_i2c] || cmd.isInstanceOf[Restart_i2c]){ +// println("I2cModel - Start ") + var detector = false + while(!detector){ + var lastSDA = sda.read() + waitUntil(lastSDA != sda.read()) + if(lastSDA && !sda.read() && scl.read()){ + detector = true + } + } + waitUntil(!scl.read()) + }else if(cmd.isInstanceOf[Stop_i2c]){ +// println("I2cModel - Stop ") + var detector = false + while(!detector){ + var lastSDA = sda.read() + waitUntil(lastSDA != sda.read()) + if(!lastSDA && sda.read() && scl.read()){ + detector = true + } + } + }else if(cmd.isInstanceOf[DataRead_i2c]){ + + val cmdData = cmd.asInstanceOf[DataRead_i2c] + + var cntBit = 0 + while(cntBit != 8){ + sda.write( ((cmdData.value >> (7 - cntBit)) & 0x01) == 0x01 ) + val sclLast = scl.read() + waitUntil(sclLast != scl.read()) + cntBit += 1 + waitUntil(!scl.read()) + } + + sda.write(true) + + // Read Ack + waitUntil(scl.read()) +// println(s"I2cModel - ACK ${sda.read()}") + waitUntil(!scl.read()) + + + }else if(cmd.isInstanceOf[DataWrite_i2c]){ + + val cmdData = cmd.asInstanceOf[DataWrite_i2c] + + var cntBit = 0 + var dataRead = 0 + while(cntBit != 8){ + val sclLast = scl.read() + waitUntil(sclLast != scl.read()) + dataRead |= ((if(sda.read()) 0x01 else 0x00) << (7 - cntBit)) + cntBit += 1 + + waitUntil(!scl.read()) + } + +// println(f"I2cModel - Data write ${dataRead}%02X") +// assert(cmdData.value == dataRead.toByte, "Byte Write error") + + // Write ACK + + sda.write(cmdData.ack) + + waitUntil(scl.read()) + + waitUntil(!scl.read()) + + sda.write(true) + + waitUntil(!scl.read()) + } + + index += 1 + + + if(index >= cmdSlave.length){ + busy = false + } + } + } + + } + + case class I2CHelper(apb: Apb3Sim){ + + case class Register(){ + def tx_data = 0x00 + def tx_ack = 0x04 + def rx_data = 0x08 + def rx_ack = 0x0C + def interrupt = 0x20 + def sampling_clock = 0x28 + def timeout = 0x2C + def tsu_data = 0x30 + def status_master = 0x40 + def t_low = 0x50 + def t_high = 0x54 + def t_buf = 0x58 + def status_filtering = 0x80 + def hit_context = 0x84 + def filtering_config = 0x88 + } + + def reg = Register() + + def I2C_MASTER_START = 0x010 + def I2C_MASTER_STOP = 0x020 + + def I2C_TX_VALID = 0x100 + def I2C_TX_ENABLE = 0x200 + def I2C_TX_REPEAT = 0x400 + def I2C_TX_CONFLIT = 0x800 + + def I2C_RX_VALID = 0x100 + def I2C_RX_LISTEN = 0x200 + def I2C_IS_BUSY = 0x001 + + var bufferCmd = new ListBuffer[I2CEvent]() + + + def polling_rx_ack(): (Byte, Byte) ={ + var status = BigInt(0) + + while((status & I2C_RX_VALID) != I2C_RX_VALID){ + status = apb.read(reg.rx_ack) + } + + // read dummy data to release txvalid + val dataRead = apb.read(reg.rx_data) + + return (dataRead.toByte, (status & 0x01) toByte) + } + + def stop(): Unit = { + apb.write(reg.status_master, I2C_MASTER_STOP) + + bufferCmd += Stop_i2c() + + // wait until the end of the emission of the stop bit + while((apb.read(reg.status_master) & I2C_MASTER_STOP) != 0){} + } + + def write(data: Int): Unit ={ + + apb.write(reg.tx_data, data | I2C_TX_VALID | I2C_TX_ENABLE ) + + val(dataRead, ack) = polling_rx_ack() + + bufferCmd += DataWrite_i2c(dataRead, (ack == 0x01)) + + () + } + + def read(ack: Boolean): Byte = { + + apb.write(reg.rx_data, I2C_RX_LISTEN) + + apb.write(reg.tx_data, 0x00 | I2C_TX_VALID) + + apb.write(reg.tx_ack, (if(ack) 0x01 else 0x00) | I2C_TX_VALID | I2C_TX_ENABLE) + + val (dataRead, ackRead) = polling_rx_ack() + + bufferCmd += DataRead_i2c(dataRead, (ackRead == 0x01)) + + return apb.read(reg.rx_data).toByte + } + + + def start(isRestart: Boolean = false): Unit = { + apb.write(reg.status_master, I2C_MASTER_START) + + // wait until it started + while((apb.read(reg.status_master) & I2C_MASTER_START) != 0){} + + apb.write(reg.rx_ack, I2C_RX_LISTEN) + bufferCmd += (if(isRestart) Restart_i2c() else Start_i2c()) + () + } + + def restart(): Unit = start(true) + + def checkCmd(slave: ListBuffer[I2CEvent]) = { + assert(bufferCmd.zip(slave).map(i2c => i2c._1 == i2c._2).reduce( _ && _ ), s"Mismatch between slave and master \nMaster : \n ${bufferCmd.mkString("\n ")} \nSlave : \n ${slave.mkString("\n ")}") + } + } + + test("1 Master <-> 1 Slave") { + + + def configI2C = I2cSlaveMemoryMappedGenerics( + ctrlGenerics = I2cSlaveGenerics(), + addressFilterCount = 0, + masterGenerics = I2cMasterMemoryMappedGenerics(timerWidth = 32) + ) + + SimConfig.withConfig(SpinalConfig(defaultClockDomainFrequency = FixedFrequency(50 MHz))).compile(new Apb3I2cCtrl(configI2C)).doSim { dut => + + val apb = Apb3Sim(dut.io.apb, dut.clockDomain) + val i2c = I2CHelper(apb) + val frequency_i2c = 400 kHz + + val sdaInterconnect = new OpenDrainInterconnect(dut.clockDomain) + sdaInterconnect.addHardDriver(dut.io.i2c.sda.write) + sdaInterconnect.addHardReader(dut.io.i2c.sda.read) + + val sclInterconnect = new OpenDrainInterconnect(dut.clockDomain) + sclInterconnect.addHardDriver(dut.io.i2c.scl.write) + sclInterconnect.addHardReader(dut.io.i2c.scl.read) + + val mainClkPeriod = (1e12 / dut.clockDomain.frequency.getValue.toDouble).toLong + + dut.clockDomain.forkStimulus(mainClkPeriod) + + apb.initIO() + + dut.clockDomain.waitSampling() + + + /** + * I2C Configuration + */ + + // Master configuration + apb.write(i2c.reg.t_buf, ((frequency_i2c.toTime / 2) * dut.clockDomain.frequency.getValue).toBigInt) + apb.write(i2c.reg.t_high, ((frequency_i2c.toTime / 2) * dut.clockDomain.frequency.getValue).toBigInt) + apb.write(i2c.reg.t_low, ((frequency_i2c.toTime / 2) * dut.clockDomain.frequency.getValue).toBigInt) + + // I2C Configuration + apb.write(i2c.reg.sampling_clock, (dut.clockDomain.frequency.getValue / (10 MHz)).toBigInt) // sampling frequency 10 MHz + apb.write(i2c.reg.timeout, (dut.clockDomain.frequency.getValue * 2).toBigDecimal.toBigInt) // Timeout after 2 secondes + apb.write(i2c.reg.tsu_data, 25) + + + /** + * Create slave model + */ + val slave = I2CSlaveModel(sdaInterconnect.newSoftConnection(), sclInterconnect.newSoftConnection()) + + /** + * Check Write operation + */ + slave.cmdSlave.clear() + slave.cmdSlave += Start_i2c() + slave.cmdSlave += DataWrite_i2c(0x06.toByte, false) + slave.cmdSlave += DataWrite_i2c(0xAA.toByte, true) + slave.cmdSlave += Stop_i2c() + slave.run() + + i2c.bufferCmd.clear() + i2c.start() + i2c.write(0x06) + i2c.write(0xAA) + i2c.stop() + + i2c.checkCmd(slave.cmdSlave) + + + dut.clockDomain.waitActiveEdge(10) + + + /** + * Check Write and read operations + */ + slave.cmdSlave.clear() + slave.cmdSlave += Start_i2c() + slave.cmdSlave += DataWrite_i2c(0x07.toByte, false) + slave.cmdSlave += DataRead_i2c(0xAA.toByte, false) + slave.cmdSlave += DataRead_i2c(0x55.toByte, true) + slave.cmdSlave += Stop_i2c() + slave.run() + + + i2c.bufferCmd.clear() + i2c.start() + i2c.write(0x07) + i2c.read(false) + i2c.read(true) + i2c.stop() + + i2c.checkCmd(slave.cmdSlave) + + + dut.clockDomain.waitActiveEdge(10) + + /** + * Check Write, Restart and read operations + */ + slave.cmdSlave.clear() + slave.cmdSlave += Start_i2c() + slave.cmdSlave += DataWrite_i2c(0x07.toByte, false) + slave.cmdSlave += DataWrite_i2c(0x00.toByte, false) + slave.cmdSlave += Restart_i2c() + slave.cmdSlave += DataWrite_i2c(0x07.toByte, false) + slave.cmdSlave += DataRead_i2c(0x3D.toByte, false) + slave.cmdSlave += DataRead_i2c(0x5A.toByte, true) + slave.cmdSlave += Stop_i2c() + slave.run() + + + i2c.bufferCmd.clear() + i2c.start() + i2c.write(0x07) + i2c.write(0x00) + i2c.restart() + i2c.write(0x07) + i2c.read(false) + i2c.read(true) + i2c.stop() + + i2c.checkCmd(slave.cmdSlave) + + + dut.clockDomain.waitActiveEdge(200) + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimApbI2C.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimApbI2C.scala deleted file mode 100644 index e14fb6b840..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimApbI2C.scala +++ /dev/null @@ -1,488 +0,0 @@ -package spinal.tester.scalatest - - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.core.internals.GraphUtils -import spinal.core.sim._ -import spinal.lib.bus.amba3.apb.Apb3 -import spinal.lib.com.i2c._ -import spinal.sim._ -import spinal.lib._ - -import scala.collection.mutable.ListBuffer - - -trait I2CEvent - -case class Start_i2c() extends I2CEvent { - override def toString: String = "Start" -} - -case class Restart_i2c() extends I2CEvent { - override def toString: String = "reStart" -} - -case class Stop_i2c() extends I2CEvent { - override def toString: String = "Stop" -} - -case class DataRead_i2c(value: Byte, ack: Boolean) extends I2CEvent { - def ==(that: DataWrite_i2c) = (this.value == that.value) && (this.ack == that.ack) - override def toString: String = f"Data Read (0x${value}%02X / ${ack})" -} - -case class DataWrite_i2c(value: Byte, ack: Boolean) extends I2CEvent { - def ==(that: DataWrite_i2c) = (this.value == that.value) && (this.ack == that.ack) - override def toString: String = f"Data Write (0x${value}%02X / ${ack})" -} - - - - -case class Apb3Sim(dut: Apb3, clockDomain: ClockDomain){ - - def initIO(): Unit = { - dut.PSEL #= 0 - dut.PADDR.randomize() - dut.PENABLE.randomize() - dut.PWRITE.randomize() - dut.PWDATA.randomize() - } - - def write(address: BigInt, data: BigInt, sel: BigInt = 1): Unit ={ - dut.PADDR #= address - dut.PSEL #= sel - dut.PENABLE #= false - dut.PWRITE #= true - dut.PWDATA #= data - clockDomain.waitActiveEdge() - dut.PENABLE #= true - - clockDomain.waitActiveEdgeWhere(dut.PREADY.toBoolean) - initIO() - } - - def read(address: BigInt, sel: BigInt = 1): BigInt = { - dut.PADDR #= address - dut.PSEL #= sel - dut.PENABLE #= false - dut.PWRITE #= false - dut.PWDATA.randomize() - clockDomain.waitActiveEdge() - - dut.PENABLE #= true - clockDomain.waitActiveEdgeWhere(dut.PREADY.toBoolean) - initIO() - - return dut.PRDATA.toBigInt - } -} - -class OpenDrainSoftConnection(interconnect: OpenDrainInterconnect){ - - var _value = true - - def write(value: Boolean): Unit ={ - if(_value != value){ - _value = value - interconnect.evaluate() - } - } - - def read(): Boolean = interconnect.value -} - - -class OpenDrainInterconnect(clockDomain: ClockDomain){ - - val hardWriters = ListBuffer[Bool]() - val hardReaders = ListBuffer[Bool]() - val softConnections = ListBuffer[OpenDrainSoftConnection]() - var value = true - - def pinWatcher(driver: Bool) = fork{ - var state = driver.toBoolean - while(true){ - waitUntil(state != driver.toBoolean) - state = driver.toBoolean - evaluate() - } - } - - def newSoftConnection(): OpenDrainSoftConnection ={ - val endPoint = new OpenDrainSoftConnection(this) - softConnections += endPoint - return endPoint - } - - def addHardDriver(driver: Bool) = { - hardWriters += driver - pinWatcher(driver ) - } - - def addHardReader(reader: Bool) = { - hardReaders += reader - reader #= true - } - - def evaluate(): Unit = { - var newValue = true - - for(soft <- softConnections){ - newValue &= soft._value - } - - for (hard <- hardWriters){ - newValue &= hard.toBoolean - } - - if (newValue != value){ - value = newValue - for (reader <- hardReaders){ - reader #= value - } - } - - clockDomain.waitActiveEdge() - } -} - - - -class SpinalSimApbI2C extends SpinalSimFunSuite { - - case class I2CSlaveModel(sda: OpenDrainSoftConnection, scl: OpenDrainSoftConnection){ - - val cmdSlave = new ListBuffer[I2CEvent]() - - def run() = fork{ - - var busy = true - var index = 0 - - waitUntil(cmdSlave.length != 0) - - while(busy){ - - val cmd = cmdSlave(index) - - if(cmd.isInstanceOf[Start_i2c] || cmd.isInstanceOf[Restart_i2c]){ -// println("I2cModel - Start ") - var detector = false - while(!detector){ - var lastSDA = sda.read() - waitUntil(lastSDA != sda.read()) - if(lastSDA && !sda.read() && scl.read()){ - detector = true - } - } - waitUntil(!scl.read()) - }else if(cmd.isInstanceOf[Stop_i2c]){ -// println("I2cModel - Stop ") - var detector = false - while(!detector){ - var lastSDA = sda.read() - waitUntil(lastSDA != sda.read()) - if(!lastSDA && sda.read() && scl.read()){ - detector = true - } - } - }else if(cmd.isInstanceOf[DataRead_i2c]){ - - val cmdData = cmd.asInstanceOf[DataRead_i2c] - - var cntBit = 0 - while(cntBit != 8){ - sda.write( ((cmdData.value >> (7 - cntBit)) & 0x01) == 0x01 ) - val sclLast = scl.read() - waitUntil(sclLast != scl.read()) - cntBit += 1 - waitUntil(!scl.read()) - } - - sda.write(true) - - // Read Ack - waitUntil(scl.read()) -// println(s"I2cModel - ACK ${sda.read()}") - waitUntil(!scl.read()) - - - }else if(cmd.isInstanceOf[DataWrite_i2c]){ - - val cmdData = cmd.asInstanceOf[DataWrite_i2c] - - var cntBit = 0 - var dataRead = 0 - while(cntBit != 8){ - val sclLast = scl.read() - waitUntil(sclLast != scl.read()) - dataRead |= ((if(sda.read()) 0x01 else 0x00) << (7 - cntBit)) - cntBit += 1 - - waitUntil(!scl.read()) - } - -// println(f"I2cModel - Data write ${dataRead}%02X") -// assert(cmdData.value == dataRead.toByte, "Byte Write error") - - // Write ACK - - sda.write(cmdData.ack) - - waitUntil(scl.read()) - - waitUntil(!scl.read()) - - sda.write(true) - - waitUntil(!scl.read()) - } - - index += 1 - - - if(index >= cmdSlave.length){ - busy = false - } - } - } - - } - - case class I2CHelper(apb: Apb3Sim){ - - case class Register(){ - def tx_data = 0x00 - def tx_ack = 0x04 - def rx_data = 0x08 - def rx_ack = 0x0C - def interrupt = 0x20 - def sampling_clock = 0x28 - def timeout = 0x2C - def tsu_data = 0x30 - def status_master = 0x40 - def t_low = 0x50 - def t_high = 0x54 - def t_buf = 0x58 - def status_filtering = 0x80 - def hit_context = 0x84 - def filtering_config = 0x88 - } - - def reg = Register() - - def I2C_MASTER_START = 0x010 - def I2C_MASTER_STOP = 0x020 - - def I2C_TX_VALID = 0x100 - def I2C_TX_ENABLE = 0x200 - def I2C_TX_REPEAT = 0x400 - def I2C_TX_CONFLIT = 0x800 - - def I2C_RX_VALID = 0x100 - def I2C_RX_LISTEN = 0x200 - def I2C_IS_BUSY = 0x001 - - var bufferCmd = new ListBuffer[I2CEvent]() - - - def polling_rx_ack(): (Byte, Byte) ={ - var status = BigInt(0) - - while((status & I2C_RX_VALID) != I2C_RX_VALID){ - status = apb.read(reg.rx_ack) - } - - // read dummy data to release txvalid - val dataRead = apb.read(reg.rx_data) - - return (dataRead.toByte, (status & 0x01) toByte) - } - - def stop(): Unit = { - apb.write(reg.status_master, I2C_MASTER_STOP) - - bufferCmd += Stop_i2c() - - // wait until the end of the emission of the stop bit - while((apb.read(reg.status_master) & I2C_MASTER_STOP) != 0){} - } - - def write(data: Int): Unit ={ - - apb.write(reg.tx_data, data | I2C_TX_VALID | I2C_TX_ENABLE ) - - val(dataRead, ack) = polling_rx_ack() - - bufferCmd += DataWrite_i2c(dataRead, (ack == 0x01)) - - () - } - - def read(ack: Boolean): Byte = { - - apb.write(reg.rx_data, I2C_RX_LISTEN) - - apb.write(reg.tx_data, 0x00 | I2C_TX_VALID) - - apb.write(reg.tx_ack, (if(ack) 0x01 else 0x00) | I2C_TX_VALID | I2C_TX_ENABLE) - - val (dataRead, ackRead) = polling_rx_ack() - - bufferCmd += DataRead_i2c(dataRead, (ackRead == 0x01)) - - return apb.read(reg.rx_data).toByte - } - - - def start(isRestart: Boolean = false): Unit = { - apb.write(reg.status_master, I2C_MASTER_START) - - // wait until it started - while((apb.read(reg.status_master) & I2C_MASTER_START) != 0){} - - apb.write(reg.rx_ack, I2C_RX_LISTEN) - bufferCmd += (if(isRestart) Restart_i2c() else Start_i2c()) - () - } - - def restart(): Unit = start(true) - - def checkCmd(slave: ListBuffer[I2CEvent]) = { - assert(bufferCmd.zip(slave).map(i2c => i2c._1 == i2c._2).reduce( _ && _ ), s"Mismatch between slave and master \nMaster : \n ${bufferCmd.mkString("\n ")} \nSlave : \n ${slave.mkString("\n ")}") - } - } - - test("1 Master <-> 1 Slave") { - - - def configI2C = I2cSlaveMemoryMappedGenerics( - ctrlGenerics = I2cSlaveGenerics(), - addressFilterCount = 0, - masterGenerics = I2cMasterMemoryMappedGenerics(timerWidth = 32) - ) - - SimConfig.withConfig(SpinalConfig(defaultClockDomainFrequency = FixedFrequency(50 MHz))).compile(new Apb3I2cCtrl(configI2C)).doSim { dut => - - val apb = Apb3Sim(dut.io.apb, dut.clockDomain) - val i2c = I2CHelper(apb) - val frequency_i2c = 400 kHz - - val sdaInterconnect = new OpenDrainInterconnect(dut.clockDomain) - sdaInterconnect.addHardDriver(dut.io.i2c.sda.write) - sdaInterconnect.addHardReader(dut.io.i2c.sda.read) - - val sclInterconnect = new OpenDrainInterconnect(dut.clockDomain) - sclInterconnect.addHardDriver(dut.io.i2c.scl.write) - sclInterconnect.addHardReader(dut.io.i2c.scl.read) - - val mainClkPeriod = (1e12 / dut.clockDomain.frequency.getValue.toDouble).toLong - - dut.clockDomain.forkStimulus(mainClkPeriod) - - apb.initIO() - - dut.clockDomain.waitSampling() - - - /** - * I2C Configuration - */ - - // Master configuration - apb.write(i2c.reg.t_buf, ((frequency_i2c.toTime / 2) * dut.clockDomain.frequency.getValue).toBigInt) - apb.write(i2c.reg.t_high, ((frequency_i2c.toTime / 2) * dut.clockDomain.frequency.getValue).toBigInt) - apb.write(i2c.reg.t_low, ((frequency_i2c.toTime / 2) * dut.clockDomain.frequency.getValue).toBigInt) - - // I2C Configuration - apb.write(i2c.reg.sampling_clock, (dut.clockDomain.frequency.getValue / (10 MHz)).toBigInt) // sampling frequency 10 MHz - apb.write(i2c.reg.timeout, (dut.clockDomain.frequency.getValue * 2).toBigDecimal.toBigInt) // Timeout after 2 secondes - apb.write(i2c.reg.tsu_data, 25) - - - /** - * Create slave model - */ - val slave = I2CSlaveModel(sdaInterconnect.newSoftConnection(), sclInterconnect.newSoftConnection()) - - /** - * Check Write operation - */ - slave.cmdSlave.clear() - slave.cmdSlave += Start_i2c() - slave.cmdSlave += DataWrite_i2c(0x06.toByte, false) - slave.cmdSlave += DataWrite_i2c(0xAA.toByte, true) - slave.cmdSlave += Stop_i2c() - slave.run() - - i2c.bufferCmd.clear() - i2c.start() - i2c.write(0x06) - i2c.write(0xAA) - i2c.stop() - - i2c.checkCmd(slave.cmdSlave) - - - dut.clockDomain.waitActiveEdge(10) - - - /** - * Check Write and read operations - */ - slave.cmdSlave.clear() - slave.cmdSlave += Start_i2c() - slave.cmdSlave += DataWrite_i2c(0x07.toByte, false) - slave.cmdSlave += DataRead_i2c(0xAA.toByte, false) - slave.cmdSlave += DataRead_i2c(0x55.toByte, true) - slave.cmdSlave += Stop_i2c() - slave.run() - - - i2c.bufferCmd.clear() - i2c.start() - i2c.write(0x07) - i2c.read(false) - i2c.read(true) - i2c.stop() - - i2c.checkCmd(slave.cmdSlave) - - - dut.clockDomain.waitActiveEdge(10) - - /** - * Check Write, Restart and read operations - */ - slave.cmdSlave.clear() - slave.cmdSlave += Start_i2c() - slave.cmdSlave += DataWrite_i2c(0x07.toByte, false) - slave.cmdSlave += DataWrite_i2c(0x00.toByte, false) - slave.cmdSlave += Restart_i2c() - slave.cmdSlave += DataWrite_i2c(0x07.toByte, false) - slave.cmdSlave += DataRead_i2c(0x3D.toByte, false) - slave.cmdSlave += DataRead_i2c(0x5A.toByte, true) - slave.cmdSlave += Stop_i2c() - slave.run() - - - i2c.bufferCmd.clear() - i2c.start() - i2c.write(0x07) - i2c.write(0x00) - i2c.restart() - i2c.write(0x07) - i2c.read(false) - i2c.read(true) - i2c.stop() - - i2c.checkCmd(slave.cmdSlave) - - - dut.clockDomain.waitActiveEdge(200) - } - } -} - From 766e505803257d731c65e533501195936d8541cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 13:26:08 +0100 Subject: [PATCH 064/120] refactor: move SpinalSimAFixTester --- .../src/test/scala/spinal/core/AFix.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimAFixTester.scala => core/src/test/scala/spinal/core/AFix.scala (99%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimAFixTester.scala b/core/src/test/scala/spinal/core/AFix.scala similarity index 99% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimAFixTester.scala rename to core/src/test/scala/spinal/core/AFix.scala index 1ca350634b..b8378bb490 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimAFixTester.scala +++ b/core/src/test/scala/spinal/core/AFix.scala @@ -1,9 +1,8 @@ -package spinal.tester.scalatest +package spinal.core -import spinal.core._ -import org.scalatest.funsuite.AnyFunSuite import spinal.core.sim._ +import org.scalatest.funsuite.AnyFunSuite import java.math.MathContext import scala.collection.mutable import scala.math.BigDecimal.RoundingMode From 78aa0d35df6c2379d4ea4d0e03c266a27fb21345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 14:13:07 +0100 Subject: [PATCH 065/120] refactor: move SpinalSimAccessSubComponents --- .../test/scala/spinal/core/sim/package.scala | 83 +++++++++++++++++- .../SpinalSimAccessSubComponents.scala | 85 ------------------- 2 files changed, 82 insertions(+), 86 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimAccessSubComponents.scala diff --git a/core/src/test/scala/spinal/core/sim/package.scala b/core/src/test/scala/spinal/core/sim/package.scala index 72303c96e0..dc40e3ef8c 100644 --- a/core/src/test/scala/spinal/core/sim/package.scala +++ b/core/src/test/scala/spinal/core/sim/package.scala @@ -1,7 +1,9 @@ package spinal.core.sim import org.scalatest.funsuite.AnyFunSuite -import spinal.core.{BIG, Endianness, LITTLE} + +import spinal.core._ +import spinal.tester.SpinalSimTester class SimBigIntPimperTest extends AnyFunSuite { def toBytes(bi: BigInt, bits: Int = -1, endian: Endianness = LITTLE) = @@ -40,3 +42,82 @@ class SimBigIntPimperTest extends AnyFunSuite { assertThrows[java.lang.AssertionError] { toBytes(-256, 8) } } } + +object SpinalSimAccessSubComponents { + class SubSub extends Component { + val io = new Bundle { + val a,b = in UInt(8 bits) + val result = out UInt(8 bits) + } + + io.result := io.a ^ io.b + val miaou = (io.a & io.b) + + val miaouVec = Vec(UInt(8 bits), 4) + miaouVec := Vec(io.a,io.b,io.result,miaou) + } + + class Sub extends Component { + val io = new Bundle { + val a,b = in UInt(8 bits) + val result = out UInt(8 bits) + } + val subSubInst = new SubSub + subSubInst.io.a <> io.a + subSubInst.io.b <> io.b + subSubInst.io.result <> io.result + } + + class Dut extends Component { + val io = new Bundle { + val a,b = in UInt(8 bits) + val result = out UInt(8 bits) + } + + val subInst = new Sub + subInst.io.a <> io.a + subInst.io.b <> io.b + subInst.io.result <> io.result + } + +} + +class SpinalSimAccessSubComponents extends AnyFunSuite { + SpinalSimTester { env => + import env._ + + var compiled: SimCompiled[SpinalSimAccessSubComponents.Dut] = null + test(prefix + "compile") { + compiled = env.SimConfig.compile { + val dut = new SpinalSimAccessSubComponents.Dut + dut.subInst.subSubInst.miaouVec.simPublic() + dut.subInst.subSubInst.io.a.simPublic() + dut.subInst.subSubInst.miaou.simPublic() + dut.subInst.subSubInst.miaou.pull() + dut.subInst.subSubInst.io.pull() + dut.subInst.subSubInst.miaouVec.pull() + dut.subInst.subSubInst.miaouVec.pull() + dut.subInst.subSubInst.miaouVec.pull() + dut.subInst.subSubInst.miaouVec.pull() + dut + } + } + + test(prefix + "simulate") { + compiled.doSim { dut => + for (repeat <- 0 until 1000) { + dut.io.a.randomize() + dut.io.b.randomize() + sleep(1) + assert(dut.io.result.toInt == (dut.io.a.toInt ^ dut.io.b.toInt)) + assert(dut.subInst.subSubInst.miaou.toInt == (dut.io.a.toInt & dut.io.b.toInt)) + assert(dut.subInst.subSubInst.io.a.toInt == (dut.io.a.toInt)) + assert(dut.subInst.subSubInst.miaouVec(0).toInt == (dut.io.a.toInt)) + assert(dut.subInst.subSubInst.miaouVec(1).toInt == (dut.io.b.toInt)) + assert(dut.subInst.subSubInst.miaouVec(2).toInt == (dut.io.a.toInt ^ dut.io.b.toInt)) + assert(dut.subInst.subSubInst.miaouVec(3).toInt == (dut.io.a.toInt & dut.io.b.toInt)) + } + } + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimAccessSubComponents.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimAccessSubComponents.scala deleted file mode 100644 index 43d3e10e1d..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimAccessSubComponents.scala +++ /dev/null @@ -1,85 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.core.sim._ -import spinal.sim._ - -object SpinalSimAccessSubComponents { - class SubSub extends Component { - val io = new Bundle { - val a,b = in UInt(8 bits) - val result = out UInt(8 bits) - } - - io.result := io.a ^ io.b - val miaou = (io.a & io.b) - - val miaouVec = Vec(UInt(8 bits), 4) - miaouVec := Vec(io.a,io.b,io.result,miaou) - } - - class Sub extends Component { - val io = new Bundle { - val a,b = in UInt(8 bits) - val result = out UInt(8 bits) - } - val subSubInst = new SubSub - subSubInst.io.a <> io.a - subSubInst.io.b <> io.b - subSubInst.io.result <> io.result - } - - class Dut extends Component { - val io = new Bundle { - val a,b = in UInt(8 bits) - val result = out UInt(8 bits) - } - - val subInst = new Sub - subInst.io.a <> io.a - subInst.io.b <> io.b - subInst.io.result <> io.result - } - -} - -class SpinalSimAccessSubComponents extends AnyFunSuite { - SpinalSimTester { env => - import env._ - - var compiled: SimCompiled[SpinalSimAccessSubComponents.Dut] = null - test(prefix + "compile") { - compiled = SimConfig.compile { - val dut = new SpinalSimAccessSubComponents.Dut - dut.subInst.subSubInst.miaouVec.simPublic() - dut.subInst.subSubInst.io.a.simPublic() - dut.subInst.subSubInst.miaou.simPublic() - dut.subInst.subSubInst.miaou.pull() - dut.subInst.subSubInst.io.pull() - dut.subInst.subSubInst.miaouVec.pull() - dut.subInst.subSubInst.miaouVec.pull() - dut.subInst.subSubInst.miaouVec.pull() - dut.subInst.subSubInst.miaouVec.pull() - dut - } - } - - test(prefix + "simulate") { - compiled.doSim { dut => - for (repeat <- 0 until 1000) { - dut.io.a.randomize() - dut.io.b.randomize() - sleep(1) - assert(dut.io.result.toInt == (dut.io.a.toInt ^ dut.io.b.toInt)) - assert(dut.subInst.subSubInst.miaou.toInt == (dut.io.a.toInt & dut.io.b.toInt)) - assert(dut.subInst.subSubInst.io.a.toInt == (dut.io.a.toInt)) - assert(dut.subInst.subSubInst.miaouVec(0).toInt == (dut.io.a.toInt)) - assert(dut.subInst.subSubInst.miaouVec(1).toInt == (dut.io.b.toInt)) - assert(dut.subInst.subSubInst.miaouVec(2).toInt == (dut.io.a.toInt ^ dut.io.b.toInt)) - assert(dut.subInst.subSubInst.miaouVec(3).toInt == (dut.io.a.toInt & dut.io.b.toInt)) - } - } - } - } -} From e6ba7a08d15d2736413864b2e493d0a7180c2949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 14:16:16 +0100 Subject: [PATCH 066/120] refactor: move SpinalSimClockDomainTest --- .../test/scala/spinal/core/ClockDomain.scala | 185 ++++++++++++++++- .../scalatest/SpinalSimClockDomainTest.scala | 190 ------------------ 2 files changed, 184 insertions(+), 191 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimClockDomainTest.scala diff --git a/core/src/test/scala/spinal/core/ClockDomain.scala b/core/src/test/scala/spinal/core/ClockDomain.scala index 9dfd85f0fd..ce40b570c0 100644 --- a/core/src/test/scala/spinal/core/ClockDomain.scala +++ b/core/src/test/scala/spinal/core/ClockDomain.scala @@ -1,6 +1,9 @@ package spinal.core -import spinal.tester.SpinalTesterCocotbBase +import scala.util.Random + +import spinal.core.sim._ +import spinal.tester.{SpinalSimFunSuite, SpinalTesterCocotbBase} object ClockDomainConfigTester { class ClockDomainConfigTester() extends Component { @@ -234,3 +237,183 @@ class MultiClockTesterCocotbBoot extends SpinalTesterCocotbBase { override def pythonTestLocation: String = "tester/src/test/python/spinal/MultiClockTester" override def createToplevel: Component = new MultiClockTester } + +object SpinalSimClockDomainTest{ + class SpinalSimClockDomainTest1 extends Component { + val io = new Bundle { + val mClk, mReset = in Bool() + val a, b, c = in UInt (8 bits) + val result = out UInt (8 bits) + } + + val tmpClk, tmpReset = Bool() + tmpClk := io.mClk + tmpReset := io.mReset + ClockDomain(tmpClk, tmpReset){ + io.result := RegNext(io.a + io.b - io.c) init(0) + } + } + + class SpinalSimClockDomainTest2 extends Component { + val io = new Bundle { + val mClk, mReset = in Bool() + val a, b, c = in UInt (8 bits) + val result = out UInt (8 bits) + } + + ClockDomain(io.mClk, io.mReset){ + io.result := RegNext(io.a + io.b - io.c) init(0) + } + } + class SpinalSimClockDomainTest3 extends Component { + val io = new Bundle { + val a, b, c = in UInt (8 bits) + val result = out UInt (8 bits) + } + + io.result := RegNext(io.a + io.b - io.c) init(0) + } + + class SpinalSimClockDomainTest4 extends Component { + val io = new Bundle { + val enable = in Bool() + val result = out UInt (8 bits) + } + + val reg = RegInit(U(42, 8 bits)) + when(io.enable){ + reg := reg + 1 + } + io.result := reg + } +} + +class SpinalSimClockDomainTest extends SpinalSimFunSuite { + val resetKinds = List(SYNC,ASYNC) + test("Test1") { + for (resetKind <- resetKinds) { + val compiled = SimConfig + .withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = resetKind))) + .compile(new SpinalSimClockDomainTest.SpinalSimClockDomainTest1().setDefinitionName("SpinalSimClockDomainTest1" + resetKind.getClass.getSimpleName.toString.take(4))) + .doSim(resetKind.toString) { dut => + // dut.clockDomain.forkStimulus(period = 10) + val cd = ClockDomain(dut.io.mClk, dut.io.mReset) + cd.forkStimulus(period = 10) + + for (repeat2 <- 0 until 10000) { + val a, b, c = Random.nextInt(256) + dut.io.a #= a + dut.io.b #= b + dut.io.c #= c + cd.waitActiveEdge(); sleep(0) + if (cd.isResetDeasserted) assert(dut.io.result.toInt == ((a + b - c) & 0xFF)) + } + } + } + } + + test("TestDeltaCycle wake") { + for (resetKind <- resetKinds) { + val compiled = SimConfig + .withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = resetKind))) + .compile(new SpinalSimClockDomainTest.SpinalSimClockDomainTest1().setDefinitionName("SpinalSimClockDomainTest1" + resetKind.getClass.getSimpleName.toString.take(4))) + .doSim(resetKind.toString) { dut => + // dut.clockDomain.forkStimulus(period = 10) + val cd = ClockDomain(dut.io.mClk, dut.io.mReset) + dut.io.a #= 0 + dut.io.b #= 0 + dut.io.c #= 0 + sleep(10) + cd.forkStimulus(period = 10) + cd.waitSampling() + cd.waitSampling() + dut.io.a #= 42 + cd.waitSampling() + assert(dut.io.result.toInt == 0) //Wakeup while rising edge, but before FF got the result out + sleep(0) + assert(dut.io.result.toInt == 42) + } + } + } + + + test("Test2") { + for (resetKind <- resetKinds) { + SimConfig + .withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = resetKind))) + .compile((new SpinalSimClockDomainTest.SpinalSimClockDomainTest2().setDefinitionName("SpinalSimClockDomainTest2" + resetKind.getClass.getSimpleName.toString.take(4)))) + .doSim(resetKind.toString) { dut => + // dut.clockDomain.forkStimulus(period = 10) + val cd = ClockDomain(dut.io.mClk, dut.io.mReset) + cd.forkStimulus(period = 10) + + var counter = 0 + while (true) { + val a, b, c = Random.nextInt(256) + dut.io.a #= a + dut.io.b #= b + dut.io.c #= c + cd.waitActiveEdge(); + sleep(0) + if (cd.isResetDeasserted) assert(dut.io.result.toInt == ((a + b - c) & 0xFF)) + counter += 1 + if (counter == 10000) simSuccess() + } + } + } + } + + test("Test3") { + for (resetKind <- resetKinds) { + SimConfig + .withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = resetKind))) + .compile((new SpinalSimClockDomainTest.SpinalSimClockDomainTest3().setDefinitionName("SpinalSimClockDomainTest3" + resetKind.getClass.getSimpleName.toString.take(4)))) + .doSim(resetKind.toString) { dut => + dut.clockDomain.forkStimulus(period = 10) + var model = BigInt(0) + for (repeat <- 0 until 10000) { + dut.io.a.randomize() + dut.io.b.randomize() + dut.io.c.randomize() + dut.clockDomain.waitActiveEdge() + if (dut.clockDomain.isResetDeasserted) { + assert(dut.io.result.toInt == model) + model = ((dut.io.a.toBigInt + dut.io.b.toLong - dut.io.c.toInt) & 0xFF) + } + } + } + } + } + + + test("Test4") { + SimConfig + .doSim(new SpinalSimClockDomainTest.SpinalSimClockDomainTest4) { dut => + dut.clockDomain.forkStimulus(period = 10) + var model = 42 + for (repeat <- 0 until 10000) { + dut.io.enable.randomize() + dut.clockDomain.waitActiveEdge(); sleep(0) + if (dut.io.enable.toBoolean) model = (model + 1) & 0xFF + assert(dut.io.result.toInt == model) + } + } + } + + test("Test5") { + SimConfig + .doSim(new SpinalSimClockDomainTest.SpinalSimClockDomainTest4) { dut => + dut.clockDomain.forkStimulus(period = 10) + var model = 42 + dut.io.enable #= false + dut.clockDomain.waitActiveEdge(1) + for (repeat <- 0 until 10000) { + dut.io.enable.randomize() + val waited = Random.nextInt(10) + dut.clockDomain.waitActiveEdge(waited); sleep(0) + if (dut.io.enable.toBoolean) model = (model + waited) & 0xFF + assert(dut.io.result.toInt == model) + } + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimClockDomainTest.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimClockDomainTest.scala deleted file mode 100644 index acd5104143..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimClockDomainTest.scala +++ /dev/null @@ -1,190 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.sim._ -import spinal.core.sim._ -import spinal.tester.scalatest - -import scala.concurrent.{Await, Future} -import scala.util.Random - -object SpinalSimClockDomainTest{ - class SpinalSimClockDomainTest1 extends Component { - val io = new Bundle { - val mClk, mReset = in Bool() - val a, b, c = in UInt (8 bits) - val result = out UInt (8 bits) - } - - val tmpClk, tmpReset = Bool() - tmpClk := io.mClk - tmpReset := io.mReset - ClockDomain(tmpClk, tmpReset){ - io.result := RegNext(io.a + io.b - io.c) init(0) - } - } - - class SpinalSimClockDomainTest2 extends Component { - val io = new Bundle { - val mClk, mReset = in Bool() - val a, b, c = in UInt (8 bits) - val result = out UInt (8 bits) - } - - ClockDomain(io.mClk, io.mReset){ - io.result := RegNext(io.a + io.b - io.c) init(0) - } - } - class SpinalSimClockDomainTest3 extends Component { - val io = new Bundle { - val a, b, c = in UInt (8 bits) - val result = out UInt (8 bits) - } - - io.result := RegNext(io.a + io.b - io.c) init(0) - } - - class SpinalSimClockDomainTest4 extends Component { - val io = new Bundle { - val enable = in Bool() - val result = out UInt (8 bits) - } - - val reg = RegInit(U(42, 8 bits)) - when(io.enable){ - reg := reg + 1 - } - io.result := reg - } -} - -class SpinalSimClockDomainTest extends SpinalSimFunSuite { - val resetKinds = List(SYNC,ASYNC) - test("Test1") { - for (resetKind <- resetKinds) { - val compiled = SimConfig - .withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = resetKind))) - .compile(new scalatest.SpinalSimClockDomainTest.SpinalSimClockDomainTest1().setDefinitionName("SpinalSimClockDomainTest1" + resetKind.getClass.getSimpleName.toString.take(4))) - .doSim(resetKind.toString) { dut => - // dut.clockDomain.forkStimulus(period = 10) - val cd = ClockDomain(dut.io.mClk, dut.io.mReset) - cd.forkStimulus(period = 10) - - for (repeat2 <- 0 until 10000) { - val a, b, c = Random.nextInt(256) - dut.io.a #= a - dut.io.b #= b - dut.io.c #= c - cd.waitActiveEdge(); sleep(0) - if (cd.isResetDeasserted) assert(dut.io.result.toInt == ((a + b - c) & 0xFF)) - } - } - } - } - - test("TestDeltaCycle wake") { - for (resetKind <- resetKinds) { - val compiled = SimConfig - .withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = resetKind))) - .compile(new scalatest.SpinalSimClockDomainTest.SpinalSimClockDomainTest1().setDefinitionName("SpinalSimClockDomainTest1" + resetKind.getClass.getSimpleName.toString.take(4))) - .doSim(resetKind.toString) { dut => - // dut.clockDomain.forkStimulus(period = 10) - val cd = ClockDomain(dut.io.mClk, dut.io.mReset) - dut.io.a #= 0 - dut.io.b #= 0 - dut.io.c #= 0 - sleep(10) - cd.forkStimulus(period = 10) - cd.waitSampling() - cd.waitSampling() - dut.io.a #= 42 - cd.waitSampling() - assert(dut.io.result.toInt == 0) //Wakeup while rising edge, but before FF got the result out - sleep(0) - assert(dut.io.result.toInt == 42) - } - } - } - - - test("Test2") { - for (resetKind <- resetKinds) { - SimConfig - .withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = resetKind))) - .compile((new scalatest.SpinalSimClockDomainTest.SpinalSimClockDomainTest2().setDefinitionName("SpinalSimClockDomainTest2" + resetKind.getClass.getSimpleName.toString.take(4)))) - .doSim(resetKind.toString) { dut => - // dut.clockDomain.forkStimulus(period = 10) - val cd = ClockDomain(dut.io.mClk, dut.io.mReset) - cd.forkStimulus(period = 10) - - var counter = 0 - while (true) { - val a, b, c = Random.nextInt(256) - dut.io.a #= a - dut.io.b #= b - dut.io.c #= c - cd.waitActiveEdge(); - sleep(0) - if (cd.isResetDeasserted) assert(dut.io.result.toInt == ((a + b - c) & 0xFF)) - counter += 1 - if (counter == 10000) simSuccess() - } - } - } - } - - test("Test3") { - for (resetKind <- resetKinds) { - SimConfig - .withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = resetKind))) - .compile((new scalatest.SpinalSimClockDomainTest.SpinalSimClockDomainTest3().setDefinitionName("SpinalSimClockDomainTest3" + resetKind.getClass.getSimpleName.toString.take(4)))) - .doSim(resetKind.toString) { dut => - dut.clockDomain.forkStimulus(period = 10) - var model = BigInt(0) - for (repeat <- 0 until 10000) { - dut.io.a.randomize() - dut.io.b.randomize() - dut.io.c.randomize() - dut.clockDomain.waitActiveEdge() - if (dut.clockDomain.isResetDeasserted) { - assert(dut.io.result.toInt == model) - model = ((dut.io.a.toBigInt + dut.io.b.toLong - dut.io.c.toInt) & 0xFF) - } - } - } - } - } - - - test("Test4") { - SimConfig - .doSim(new SpinalSimClockDomainTest.SpinalSimClockDomainTest4) { dut => - dut.clockDomain.forkStimulus(period = 10) - var model = 42 - for (repeat <- 0 until 10000) { - dut.io.enable.randomize() - dut.clockDomain.waitActiveEdge(); sleep(0) - if (dut.io.enable.toBoolean) model = (model + 1) & 0xFF - assert(dut.io.result.toInt == model) - } - } - } - - test("Test5") { - SimConfig - .doSim(new SpinalSimClockDomainTest.SpinalSimClockDomainTest4) { dut => - dut.clockDomain.forkStimulus(period = 10) - var model = 42 - dut.io.enable #= false - dut.clockDomain.waitActiveEdge(1) - for (repeat <- 0 until 10000) { - dut.io.enable.randomize() - val waited = Random.nextInt(10) - dut.clockDomain.waitActiveEdge(waited); sleep(0) - if (dut.io.enable.toBoolean) model = (model + waited) & 0xFF - assert(dut.io.result.toInt == model) - } - } - } -} From de69606dfb515e3a8f30a907159936e408d07b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 14:19:41 +0100 Subject: [PATCH 067/120] refactor: move SpinalSimMacTester --- .../src/test/scala/spinal/lib/com/eth/MacRx.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimMacTester.scala => lib/src/test/scala/spinal/lib/com/eth/MacRx.scala (98%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimMacTester.scala b/lib/src/test/scala/spinal/lib/com/eth/MacRx.scala similarity index 98% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimMacTester.scala rename to lib/src/test/scala/spinal/lib/com/eth/MacRx.scala index 714098fbc2..6bcc4d23cd 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimMacTester.scala +++ b/lib/src/test/scala/spinal/lib/com/eth/MacRx.scala @@ -1,11 +1,10 @@ -package spinal.tester.scalatest +package spinal.lib.com.eth import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import spinal.core.sim._ -import spinal.lib._ -import spinal.lib.com.eth._ -import spinal.lib.sim.{FlowMonitor, StreamDriver, StreamMonitor, StreamReadyRandomizer} +import spinal.lib.sim.{StreamDriver, StreamMonitor, StreamReadyRandomizer} import scala.collection.mutable import scala.util.Random From 87a1a68228e526392b4330abc68cd327965d7d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 14:29:29 +0100 Subject: [PATCH 068/120] refactor: move SpinalSimStreamWidthAdapterTester --- lib/src/test/scala/spinal/lib/Stream.scala | 470 ++++++++++++++++- .../SpinalSimStreamWidthAdapterTester.scala | 476 ------------------ 2 files changed, 469 insertions(+), 477 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamWidthAdapterTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index 8989e96c19..3df9f97683 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -1,10 +1,15 @@ package spinal.lib import spinal.core._ +import spinal.core.sim._ import spinal.core.formal._ import spinal.lib.formal._ +import spinal.lib.sim._ -import spinal.tester.{SpinalTesterCocotbBase, SpinalTesterGhdlBase} +import spinal.tester.{SpinalTesterCocotbBase, SpinalTesterGhdlBase, SpinalSimFunSuite} + +import scala.collection.mutable +import scala.util.Random object StreamTester{ case class BundleA(aaa : Int) extends Bundle{ @@ -1413,3 +1418,466 @@ class FormalStreamExtender extends SpinalFormalFunSuite { extenderNoDelayTester() } } + +class SpinalSimStreamWidthAdapterTester extends SpinalSimFunSuite { + test("test2xOut") { + //Compile the simulator + val baseWidth = 32 + val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ + val input = slave Stream(UInt(baseWidth bits)) + val output = master Stream(UInt(baseWidth*2 bits)) + val rtl = StreamWidthAdapter(input, output) + } + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val queueModel = mutable.Queue[BigInt]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + + val driver = StreamDriver(dut.input, dut.clockDomain) { _ => + true + } + val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => + queueModel.enqueue(p.toBigInt) + } + + val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) + val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => + assert(queueModel.nonEmpty) + val low = queueModel.dequeue() + assert(queueModel.nonEmpty) + val high = queueModel.dequeue() + val value = (high << baseWidth) + low + assert(p.toBigInt == value) + } + + dut.clockDomain.waitSampling(10000) + simSuccess() + } + } + + test("test2xIn") { + //Compile the simulator + val baseWidth = 32 + val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ + val input = slave Stream(UInt(baseWidth*2 bits)) + val output = master Stream(UInt(baseWidth bits)) + val rtl = StreamWidthAdapter(input, output) + } + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val inQueue = mutable.Queue[BigInt]() + val lowQueue = mutable.Queue[BigInt]() + val highQueue = mutable.Queue[BigInt]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + def check(){ + if(inQueue.nonEmpty && lowQueue.nonEmpty && highQueue.nonEmpty){ + val low = lowQueue.dequeue() + val high = highQueue.dequeue() + val value = (high << baseWidth) + low + assert(inQueue.dequeue() == value) + } + } + + val driver = StreamDriver(dut.input, dut.clockDomain) { p => + true + } + val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => + inQueue.enqueue(p.toBigInt) + check() + } + + val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) + val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => + if (lowQueue.length <= highQueue.length){ + lowQueue.enqueue(p.toBigInt) + } else { + highQueue.enqueue(p.toBigInt) + } + check() + } + + dut.clockDomain.waitSampling(10000) + simSuccess() + } + } + + test("test2xOutHighFirst") { + //Compile the simulator + val baseWidth = 32 + val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ + val input = slave Stream(UInt(baseWidth bits)) + val output = master Stream(UInt(baseWidth*2 bits)) + val rtl = StreamWidthAdapter(input, output, order = HIGHER_FIRST) + } + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val queueModel = mutable.Queue[BigInt]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + + val driver = StreamDriver(dut.input, dut.clockDomain) { _ => + true + } + val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => + queueModel.enqueue(p.toBigInt) + } + + val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) + val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => + assert(queueModel.nonEmpty) + val high = queueModel.dequeue() + assert(queueModel.nonEmpty) + val low = queueModel.dequeue() + val value = (high << baseWidth) + low + assert(p.toBigInt == value) + } + + dut.clockDomain.waitSampling(10000) + simSuccess() + } + } + + test("test2xInHighFirst") { + //Compile the simulator + val baseWidth = 32 + val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ + val input = slave Stream(UInt(baseWidth*2 bits)) + val output = master Stream(UInt(baseWidth bits)) + val rtl = StreamWidthAdapter(input, output, order = HIGHER_FIRST) + } + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val inQueue = mutable.Queue[BigInt]() + val lowQueue = mutable.Queue[BigInt]() + val highQueue = mutable.Queue[BigInt]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + def check(){ + if(inQueue.nonEmpty && lowQueue.nonEmpty && highQueue.nonEmpty){ + val low = lowQueue.dequeue() + val high = highQueue.dequeue() + val value = (high << baseWidth) + low + assert(inQueue.dequeue() == value) + } + } + + val driver = StreamDriver(dut.input, dut.clockDomain) { p => + true + } + val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => + inQueue.enqueue(p.toBigInt) + check() + } + + val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) + val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => + if (lowQueue.length > highQueue.length){ + lowQueue.enqueue(p.toBigInt) + } else { + highQueue.enqueue(p.toBigInt) + } + check() + } + + dut.clockDomain.waitSampling(10000) + simSuccess() + } + } + + test("test2xOutWithNegPadding") { + //Compile the simulator + val baseWidth = 16 + val extraWidth = -2 + val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ + val input = slave Stream(UInt(baseWidth bits)) + val output = master Stream(UInt(baseWidth*2+extraWidth bits)) + val rtl = StreamWidthAdapter(input, output, padding=true) + } + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val queueModel = mutable.Queue[BigInt]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + + val driver = StreamDriver(dut.input, dut.clockDomain) { _ => + true + } + val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => + queueModel.enqueue(p.toBigInt) + } + + val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) + val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => + assert(queueModel.nonEmpty) + val low = queueModel.dequeue() + assert(queueModel.nonEmpty) + val high = queueModel.dequeue() + val mask = ((BigInt(1) << dut.output.payload.getBitsWidth) - 1) + val value = ((high << baseWidth) + low) & mask + assert(p.toBigInt == value) + } + + dut.clockDomain.waitSampling(10000) + simSuccess() + } + } + + test("test2xInWithNegPadding") { + //Compile the simulator + val baseWidth = 16 + val extraWidth = -2 + val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ + val input = slave Stream(UInt(baseWidth*2+extraWidth bits)) + val output = master Stream(UInt(baseWidth bits)) + val rtl = StreamWidthAdapter(input, output, padding=true) + } + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val inQueue = mutable.Queue[BigInt]() + val lowQueue = mutable.Queue[BigInt]() + val highQueue = mutable.Queue[BigInt]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + def check(){ + if(inQueue.nonEmpty && lowQueue.nonEmpty && highQueue.nonEmpty){ + val low = lowQueue.dequeue() + val high = highQueue.dequeue() + val value = (high << baseWidth) + low + assert(inQueue.dequeue() == value) + } + } + + val driver = StreamDriver(dut.input, dut.clockDomain) { p => + true + } + val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => + inQueue.enqueue(p.toBigInt) + check() + } + + val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) + val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => + if (lowQueue.length <= highQueue.length){ + lowQueue.enqueue(p.toBigInt) + } else { + highQueue.enqueue(p.toBigInt) + } + check() + } + + dut.clockDomain.waitSampling(10000) + simSuccess() + } + } + + test("test2xInWithPosPadding") { + //Compile the simulator + val baseWidth = 16 + val extraWidth = 2 + val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ + val input = slave Stream(UInt(baseWidth*2+extraWidth bits)) + val output = master Stream(UInt(baseWidth bits)) + val rtl = StreamWidthAdapter(input, output, padding=true) + } + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val inQueue = mutable.Queue[BigInt]() + val lowQueue = mutable.Queue[BigInt]() + val midQueue = mutable.Queue[BigInt]() + val highQueue = mutable.Queue[BigInt]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + def check(){ + if(inQueue.nonEmpty && lowQueue.nonEmpty && midQueue.nonEmpty && highQueue.nonEmpty){ + val low = lowQueue.dequeue() + val mid = midQueue.dequeue() + val high = highQueue.dequeue() + val value = (high << baseWidth*2) + (mid << baseWidth) + low + assert(inQueue.dequeue() == value) + } + } + + val driver = StreamDriver(dut.input, dut.clockDomain) { p => + true + } + val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => + inQueue.enqueue(p.toBigInt) + check() + } + + val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) + val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => + if (lowQueue.isEmpty || lowQueue.length < midQueue.length){ + lowQueue.enqueue(p.toBigInt) + } else if (midQueue.isEmpty || midQueue.length < highQueue.length){ + midQueue.enqueue(p.toBigInt) + } else { + highQueue.enqueue(p.toBigInt) + } + check() + } + + dut.clockDomain.waitSampling(10000) + simSuccess() + } + } + + test("test2xOutWithPosPadding") { + //Compile the simulator + val baseWidth = 16 + val extraWidth = 2 + val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ + val input = slave Stream(UInt(baseWidth bits)) + val output = master Stream(UInt(baseWidth*2+extraWidth bits)) + val rtl = StreamWidthAdapter(input, output, padding=true) + } + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val queueModel = mutable.Queue[BigInt]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + + val driver = StreamDriver(dut.input, dut.clockDomain) { _ => + true + } + val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => + queueModel.enqueue(p.toBigInt) + } + + val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) + val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => + assert(queueModel.nonEmpty) + val low = queueModel.dequeue() + assert(queueModel.nonEmpty) + val mid = queueModel.dequeue() + assert(queueModel.nonEmpty) + val high = queueModel.dequeue() + val mask = ((BigInt(1) << dut.output.payload.getBitsWidth) - 1) + val value = ((high << baseWidth*2) + (mid << baseWidth) + low) & mask + assert(p.toBigInt == value) + } + + dut.clockDomain.waitSampling(10000) + simSuccess() + } + } + + test("test2xOutHighFirstPadding") { + //Compile the simulator + val baseWidth = 32 + val extraWidth = -2 + val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ + val input = slave Stream(UInt(baseWidth bits)) + val output = master Stream(UInt(baseWidth*2+extraWidth bits)) + val rtl = StreamWidthAdapter(input, output, order = HIGHER_FIRST, padding=true) + } + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val queueModel = mutable.Queue[BigInt]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + + val driver = StreamDriver(dut.input, dut.clockDomain) { _ => + true + } + val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => + queueModel.enqueue(p.toBigInt) + } + + val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) + val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => + assert(queueModel.nonEmpty) + val high = queueModel.dequeue() + assert(queueModel.nonEmpty) + val low = queueModel.dequeue() + val mask = ((BigInt(1) << dut.output.payload.getBitsWidth) - 1) + val value = ((high << baseWidth) + low) & mask + assert(p.toBigInt == value) + } + + dut.clockDomain.waitSampling(10000) + simSuccess() + } + } + + test("test2xInHighFirstPadding") { + //Compile the simulator + val baseWidth = 32 + val extraWidth = -2 + val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ + val input = slave Stream(UInt(baseWidth*2+extraWidth bits)) + val output = master Stream(UInt(baseWidth bits)) + val rtl = StreamWidthAdapter(input, output, order = HIGHER_FIRST, padding=true) + } + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val inQueue = mutable.Queue[BigInt]() + val lowQueue = mutable.Queue[BigInt]() + val highQueue = mutable.Queue[BigInt]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + def check(){ + if(inQueue.nonEmpty && lowQueue.nonEmpty && highQueue.nonEmpty){ + val low = lowQueue.dequeue() + val high = highQueue.dequeue() + val mask = ((BigInt(1) << dut.output.payload.getBitsWidth) - 1) + val value = ((high << baseWidth) + low) & mask + assert(inQueue.dequeue() == value) + } + } + + val driver = StreamDriver(dut.input, dut.clockDomain) { p => + true + } + val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => + inQueue.enqueue(p.toBigInt) + check() + } + + val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) + val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => + if (lowQueue.length > highQueue.length){ + lowQueue.enqueue(p.toBigInt) + } else { + highQueue.enqueue(p.toBigInt) + } + check() + } + + dut.clockDomain.waitSampling(10000) + simSuccess() + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamWidthAdapterTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamWidthAdapterTester.scala deleted file mode 100644 index ae5f50e448..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamWidthAdapterTester.scala +++ /dev/null @@ -1,476 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.lib._ -import spinal.sim._ -import spinal.core.sim._ -import spinal.lib.StreamWidthAdapter -import spinal.lib.sim._ -import spinal.tester - -import scala.collection.mutable -import scala.util.Random - -class SpinalSimStreamWidthAdapterTester extends SpinalSimFunSuite { - test("test2xOut") { - //Compile the simulator - val baseWidth = 32 - val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ - val input = slave Stream(UInt(baseWidth bits)) - val output = master Stream(UInt(baseWidth*2 bits)) - val rtl = StreamWidthAdapter(input, output) - } - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val queueModel = mutable.Queue[BigInt]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - - val driver = StreamDriver(dut.input, dut.clockDomain) { _ => - true - } - val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => - queueModel.enqueue(p.toBigInt) - } - - val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) - val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => - assert(queueModel.nonEmpty) - val low = queueModel.dequeue() - assert(queueModel.nonEmpty) - val high = queueModel.dequeue() - val value = (high << baseWidth) + low - assert(p.toBigInt == value) - } - - dut.clockDomain.waitSampling(10000) - simSuccess() - } - } - - test("test2xIn") { - //Compile the simulator - val baseWidth = 32 - val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ - val input = slave Stream(UInt(baseWidth*2 bits)) - val output = master Stream(UInt(baseWidth bits)) - val rtl = StreamWidthAdapter(input, output) - } - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val inQueue = mutable.Queue[BigInt]() - val lowQueue = mutable.Queue[BigInt]() - val highQueue = mutable.Queue[BigInt]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - def check(){ - if(inQueue.nonEmpty && lowQueue.nonEmpty && highQueue.nonEmpty){ - val low = lowQueue.dequeue() - val high = highQueue.dequeue() - val value = (high << baseWidth) + low - assert(inQueue.dequeue() == value) - } - } - - val driver = StreamDriver(dut.input, dut.clockDomain) { p => - true - } - val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => - inQueue.enqueue(p.toBigInt) - check() - } - - val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) - val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => - if (lowQueue.length <= highQueue.length){ - lowQueue.enqueue(p.toBigInt) - } else { - highQueue.enqueue(p.toBigInt) - } - check() - } - - dut.clockDomain.waitSampling(10000) - simSuccess() - } - } - - test("test2xOutHighFirst") { - //Compile the simulator - val baseWidth = 32 - val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ - val input = slave Stream(UInt(baseWidth bits)) - val output = master Stream(UInt(baseWidth*2 bits)) - val rtl = StreamWidthAdapter(input, output, order = HIGHER_FIRST) - } - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val queueModel = mutable.Queue[BigInt]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - - val driver = StreamDriver(dut.input, dut.clockDomain) { _ => - true - } - val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => - queueModel.enqueue(p.toBigInt) - } - - val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) - val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => - assert(queueModel.nonEmpty) - val high = queueModel.dequeue() - assert(queueModel.nonEmpty) - val low = queueModel.dequeue() - val value = (high << baseWidth) + low - assert(p.toBigInt == value) - } - - dut.clockDomain.waitSampling(10000) - simSuccess() - } - } - - test("test2xInHighFirst") { - //Compile the simulator - val baseWidth = 32 - val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ - val input = slave Stream(UInt(baseWidth*2 bits)) - val output = master Stream(UInt(baseWidth bits)) - val rtl = StreamWidthAdapter(input, output, order = HIGHER_FIRST) - } - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val inQueue = mutable.Queue[BigInt]() - val lowQueue = mutable.Queue[BigInt]() - val highQueue = mutable.Queue[BigInt]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - def check(){ - if(inQueue.nonEmpty && lowQueue.nonEmpty && highQueue.nonEmpty){ - val low = lowQueue.dequeue() - val high = highQueue.dequeue() - val value = (high << baseWidth) + low - assert(inQueue.dequeue() == value) - } - } - - val driver = StreamDriver(dut.input, dut.clockDomain) { p => - true - } - val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => - inQueue.enqueue(p.toBigInt) - check() - } - - val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) - val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => - if (lowQueue.length > highQueue.length){ - lowQueue.enqueue(p.toBigInt) - } else { - highQueue.enqueue(p.toBigInt) - } - check() - } - - dut.clockDomain.waitSampling(10000) - simSuccess() - } - } - - test("test2xOutWithNegPadding") { - //Compile the simulator - val baseWidth = 16 - val extraWidth = -2 - val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ - val input = slave Stream(UInt(baseWidth bits)) - val output = master Stream(UInt(baseWidth*2+extraWidth bits)) - val rtl = StreamWidthAdapter(input, output, padding=true) - } - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val queueModel = mutable.Queue[BigInt]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - - val driver = StreamDriver(dut.input, dut.clockDomain) { _ => - true - } - val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => - queueModel.enqueue(p.toBigInt) - } - - val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) - val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => - assert(queueModel.nonEmpty) - val low = queueModel.dequeue() - assert(queueModel.nonEmpty) - val high = queueModel.dequeue() - val mask = ((BigInt(1) << dut.output.payload.getBitsWidth) - 1) - val value = ((high << baseWidth) + low) & mask - assert(p.toBigInt == value) - } - - dut.clockDomain.waitSampling(10000) - simSuccess() - } - } - - test("test2xInWithNegPadding") { - //Compile the simulator - val baseWidth = 16 - val extraWidth = -2 - val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ - val input = slave Stream(UInt(baseWidth*2+extraWidth bits)) - val output = master Stream(UInt(baseWidth bits)) - val rtl = StreamWidthAdapter(input, output, padding=true) - } - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val inQueue = mutable.Queue[BigInt]() - val lowQueue = mutable.Queue[BigInt]() - val highQueue = mutable.Queue[BigInt]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - def check(){ - if(inQueue.nonEmpty && lowQueue.nonEmpty && highQueue.nonEmpty){ - val low = lowQueue.dequeue() - val high = highQueue.dequeue() - val value = (high << baseWidth) + low - assert(inQueue.dequeue() == value) - } - } - - val driver = StreamDriver(dut.input, dut.clockDomain) { p => - true - } - val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => - inQueue.enqueue(p.toBigInt) - check() - } - - val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) - val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => - if (lowQueue.length <= highQueue.length){ - lowQueue.enqueue(p.toBigInt) - } else { - highQueue.enqueue(p.toBigInt) - } - check() - } - - dut.clockDomain.waitSampling(10000) - simSuccess() - } - } - - test("test2xInWithPosPadding") { - //Compile the simulator - val baseWidth = 16 - val extraWidth = 2 - val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ - val input = slave Stream(UInt(baseWidth*2+extraWidth bits)) - val output = master Stream(UInt(baseWidth bits)) - val rtl = StreamWidthAdapter(input, output, padding=true) - } - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val inQueue = mutable.Queue[BigInt]() - val lowQueue = mutable.Queue[BigInt]() - val midQueue = mutable.Queue[BigInt]() - val highQueue = mutable.Queue[BigInt]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - def check(){ - if(inQueue.nonEmpty && lowQueue.nonEmpty && midQueue.nonEmpty && highQueue.nonEmpty){ - val low = lowQueue.dequeue() - val mid = midQueue.dequeue() - val high = highQueue.dequeue() - val value = (high << baseWidth*2) + (mid << baseWidth) + low - assert(inQueue.dequeue() == value) - } - } - - val driver = StreamDriver(dut.input, dut.clockDomain) { p => - true - } - val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => - inQueue.enqueue(p.toBigInt) - check() - } - - val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) - val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => - if (lowQueue.isEmpty || lowQueue.length < midQueue.length){ - lowQueue.enqueue(p.toBigInt) - } else if (midQueue.isEmpty || midQueue.length < highQueue.length){ - midQueue.enqueue(p.toBigInt) - } else { - highQueue.enqueue(p.toBigInt) - } - check() - } - - dut.clockDomain.waitSampling(10000) - simSuccess() - } - } - - test("test2xOutWithPosPadding") { - //Compile the simulator - val baseWidth = 16 - val extraWidth = 2 - val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ - val input = slave Stream(UInt(baseWidth bits)) - val output = master Stream(UInt(baseWidth*2+extraWidth bits)) - val rtl = StreamWidthAdapter(input, output, padding=true) - } - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val queueModel = mutable.Queue[BigInt]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - - val driver = StreamDriver(dut.input, dut.clockDomain) { _ => - true - } - val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => - queueModel.enqueue(p.toBigInt) - } - - val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) - val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => - assert(queueModel.nonEmpty) - val low = queueModel.dequeue() - assert(queueModel.nonEmpty) - val mid = queueModel.dequeue() - assert(queueModel.nonEmpty) - val high = queueModel.dequeue() - val mask = ((BigInt(1) << dut.output.payload.getBitsWidth) - 1) - val value = ((high << baseWidth*2) + (mid << baseWidth) + low) & mask - assert(p.toBigInt == value) - } - - dut.clockDomain.waitSampling(10000) - simSuccess() - } - } - - test("test2xOutHighFirstPadding") { - //Compile the simulator - val baseWidth = 32 - val extraWidth = -2 - val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ - val input = slave Stream(UInt(baseWidth bits)) - val output = master Stream(UInt(baseWidth*2+extraWidth bits)) - val rtl = StreamWidthAdapter(input, output, order = HIGHER_FIRST, padding=true) - } - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val queueModel = mutable.Queue[BigInt]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - - val driver = StreamDriver(dut.input, dut.clockDomain) { _ => - true - } - val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => - queueModel.enqueue(p.toBigInt) - } - - val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) - val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => - assert(queueModel.nonEmpty) - val high = queueModel.dequeue() - assert(queueModel.nonEmpty) - val low = queueModel.dequeue() - val mask = ((BigInt(1) << dut.output.payload.getBitsWidth) - 1) - val value = ((high << baseWidth) + low) & mask - assert(p.toBigInt == value) - } - - dut.clockDomain.waitSampling(10000) - simSuccess() - } - } - - test("test2xInHighFirstPadding") { - //Compile the simulator - val baseWidth = 32 - val extraWidth = -2 - val compiled = SimConfig.allOptimisation.compile(rtl = new Component{ - val input = slave Stream(UInt(baseWidth*2+extraWidth bits)) - val output = master Stream(UInt(baseWidth bits)) - val rtl = StreamWidthAdapter(input, output, order = HIGHER_FIRST, padding=true) - } - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val inQueue = mutable.Queue[BigInt]() - val lowQueue = mutable.Queue[BigInt]() - val highQueue = mutable.Queue[BigInt]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - def check(){ - if(inQueue.nonEmpty && lowQueue.nonEmpty && highQueue.nonEmpty){ - val low = lowQueue.dequeue() - val high = highQueue.dequeue() - val mask = ((BigInt(1) << dut.output.payload.getBitsWidth) - 1) - val value = ((high << baseWidth) + low) & mask - assert(inQueue.dequeue() == value) - } - } - - val driver = StreamDriver(dut.input, dut.clockDomain) { p => - true - } - val inMonitor = StreamMonitor(dut.input, dut.clockDomain) { p => - inQueue.enqueue(p.toBigInt) - check() - } - - val ready = StreamReadyRandomizer(dut.output, dut.clockDomain) - val outMonitor = StreamMonitor(dut.output, dut.clockDomain) { p => - if (lowQueue.length > highQueue.length){ - lowQueue.enqueue(p.toBigInt) - } else { - highQueue.enqueue(p.toBigInt) - } - check() - } - - dut.clockDomain.waitSampling(10000) - simSuccess() - } - } -} From a2fd612ab992c306b499a0ab22911008663fc09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 14:40:30 +0100 Subject: [PATCH 069/120] refactor: move SpinalSimLibTester --- core/src/main/scala/spinal/core/Vec.scala | 2 +- core/src/test/scala/spinal/core/Vec.scala | 33 ++++++++ lib/src/test/scala/spinal/lib/Utils.scala | 44 +++++++++++ .../tester/scalatest/SpinalSimLibTester.scala | 77 ------------------- 4 files changed, 78 insertions(+), 78 deletions(-) create mode 100644 core/src/test/scala/spinal/core/Vec.scala delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimLibTester.scala diff --git a/core/src/main/scala/spinal/core/Vec.scala b/core/src/main/scala/spinal/core/Vec.scala index d7f2726069..ba43e28b3b 100644 --- a/core/src/main/scala/spinal/core/Vec.scala +++ b/core/src/main/scala/spinal/core/Vec.scala @@ -311,7 +311,7 @@ class VecBitwisePimper[T <: Data with BitwiseOp[T]](pimped : Vec[T]) extends Bit private def map2with(f: (T, T) => T)(other: Vec[T]): Vec[T] = { if (pimped.length != other.length) - SpinalError(s"Cannot apply a bitwize opration on vectors with different size (${pimped.length} vs ${other.length})") + SpinalError(s"Cannot apply a bitwize operation on vectors with different sizes (${pimped.length} vs ${other.length})") Vec((pimped, other).zipped.map(f)) } } diff --git a/core/src/test/scala/spinal/core/Vec.scala b/core/src/test/scala/spinal/core/Vec.scala new file mode 100644 index 0000000000..452d2dbd66 --- /dev/null +++ b/core/src/test/scala/spinal/core/Vec.scala @@ -0,0 +1,33 @@ +package spinal.core + +import spinal.core.sim._ + +import org.scalatest.funsuite.AnyFunSuite + +class VecBitwisePimperTester extends AnyFunSuite { + for (n <- 0 until 12) { + test("Vec (op) Vec on " + n + " elements") { + SimConfig.noOptimisation + .compile(new Component { + val a, b = in Vec (SInt(8 bits), n) + val xor = out(a ^ b) + val or = out(a | b) + val and = out(a & b) + val not = out(~a) + }) + .doSim(seed = 42) { dut => + for (_ <- 0 until 100) { + dut.a.randomize() + dut.b.randomize() + sleep(1) + for (i <- 0 until n) { + assert(dut.xor(i).toInt == (dut.a(i).toInt ^ dut.b(i).toInt)) + assert(dut.or(i).toInt == (dut.a(i).toInt | dut.b(i).toInt)) + assert(dut.and(i).toInt == (dut.a(i).toInt & dut.b(i).toInt)) + assert(dut.not(i).toInt == ~dut.a(i).toInt) + } + } + } + } + } +} diff --git a/lib/src/test/scala/spinal/lib/Utils.scala b/lib/src/test/scala/spinal/lib/Utils.scala index 6893ce67aa..67cfd97e8b 100644 --- a/lib/src/test/scala/spinal/lib/Utils.scala +++ b/lib/src/test/scala/spinal/lib/Utils.scala @@ -1,10 +1,14 @@ package spinal.lib import spinal.core._ +import spinal.core.sim._ import spinal.core.formal._ import spinal.lib._ import spinal.lib.formal._ +import org.scalatest.funsuite.AnyFunSuite +import scala.util.Random + class FormalHistoryModifyableTester extends SpinalFormalFunSuite { test("pop_any") { FormalConfig @@ -90,3 +94,43 @@ class FormalHistoryModifyableTester extends SpinalFormalFunSuite { }) } } + +class SpinalSimLibTester extends AnyFunSuite { + for (bitCount <- 0 until 12) { + test("CountOnes" + bitCount) { + LutInputs(Random.nextInt(5) + 2).on { + SimConfig.noOptimisation + .compile(new Component { + val input = in Bits (bitCount bits) + val output = out(CountOne(input)) + }) + .doSim(seed = 42) { dut => + for (_ <- 0 until 100 + (1 << bitCount) * 4) { + dut.input.randomize() + sleep(1) + assert(dut.output.toInt === dut.input.toBigInt.bitCount) + } + } + } + } + } + + for (bitCount <- 0 until 12) { + test("CountOneOnEach" + bitCount) { + SimConfig.noOptimisation + .compile(new Component { + val input = in Bits (bitCount bits) + val output = out Vec (CountOneOnEach(input)) + }) + .doSim(seed = 42) { dut => + for (_ <- 0 until 100 + (1 << bitCount) * 4) { + dut.input.randomize() + sleep(1) + val input = dut.input.toBigInt + for (i <- 0 until bitCount; mask = ((1 << i + 1) - 1)) + assert(dut.output(i).toInt === (input & mask).bitCount) + } + } + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimLibTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimLibTester.scala deleted file mode 100644 index 253497cc20..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimLibTester.scala +++ /dev/null @@ -1,77 +0,0 @@ -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.core.sim._ -import spinal.lib._ -import spinal.lib.com.eth._ -import spinal.lib.sim.{FlowMonitor, StreamDriver, StreamMonitor, StreamReadyRandomizer} - -import scala.collection.mutable -import scala.util.Random - -class SpinalSimLibTester extends AnyFunSuite { - for (n <- 0 until 12) { - test("Vec (op) Vec on " + n + " elements") { - SimConfig.noOptimisation - .compile(new Component { - val a, b = in Vec (SInt(8 bits), n) - val xor = out(a ^ b) - val or = out(a | b) - val and = out(a & b) - val not = out(~a) - }) - .doSim(seed = 42) { dut => - for (_ <- 0 until 100) { - dut.a.randomize() - dut.b.randomize() - sleep(1) - for (i <- 0 until n) { - assert(dut.xor(i).toInt == (dut.a(i).toInt ^ dut.b(i).toInt)) - assert(dut.or(i).toInt == (dut.a(i).toInt | dut.b(i).toInt)) - assert(dut.and(i).toInt == (dut.a(i).toInt & dut.b(i).toInt)) - assert(dut.not(i).toInt == ~dut.a(i).toInt) - } - } - - def isEq(a: UInt, b: UInt): Boolean = a.toInt == b.toInt - } - } - } - - for (bitCount <- 0 until 12) { - test("CountOnes" + bitCount) { - LutInputs(Random.nextInt(5) + 2).on { - SimConfig.noOptimisation - .compile(new Component { - val input = in Bits (bitCount bits) - val output = out(CountOne(input)) - }) - .doSim(seed = 42) { dut => - for (_ <- 0 until 100 + (1 << bitCount) * 4) { - dut.input.randomize() - sleep(1) - assert(dut.output.toInt === dut.input.toBigInt.bitCount) - } - } - } - } - } - - for (bitCount <- 0 until 12) { - test("CountOneOnEach" + bitCount) { - SimConfig.noOptimisation - .compile(new Component { - val input = in Bits (bitCount bits) - val output = out Vec (CountOneOnEach(input)) - }) - .doSim(seed = 42) { dut => - for (_ <- 0 until 100 + (1 << bitCount) * 4) { - dut.input.randomize() - sleep(1) - val input = dut.input.toBigInt - for (i <- 0 until bitCount; mask = ((1 << i + 1) - 1)) - assert(dut.output(i).toInt === (input & mask).bitCount) - } - } - } - } -} From 2baee9c61c53f1874ecd4d386e4a6c126b284178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 14:43:03 +0100 Subject: [PATCH 070/120] refactor: move SpinalSimWishboneAdapterTester --- .../scala/spinal/lib/bus/wishbone/WishboneAdapter.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneAdapterTester.scala => lib/src/test/scala/spinal/lib/bus/wishbone/WishboneAdapter.scala (97%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneAdapterTester.scala b/lib/src/test/scala/spinal/lib/bus/wishbone/WishboneAdapter.scala similarity index 97% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneAdapterTester.scala rename to lib/src/test/scala/spinal/lib/bus/wishbone/WishboneAdapter.scala index 2161f16920..926da0ec2b 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneAdapterTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/wishbone/WishboneAdapter.scala @@ -1,13 +1,13 @@ -package spinal.tester.scalatest +package spinal.lib.bus.wishbone import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import spinal.core.sim._ -import spinal.sim._ import spinal.lib._ -import spinal.lib.bus.wishbone._ import spinal.lib.wishbone.sim._ import spinal.lib.sim._ + import scala.util.Random class WishboneSimpleBusAdapted( configIn : WishboneConfig, From 9f27b8379838666b0e5d739ddd40d956adb0300d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 14:52:48 +0100 Subject: [PATCH 071/120] refactor: move SpinalSimWishboneArbiterTester --- .../scala/spinal/lib/bus/wishbone/WishboneArbiter.scala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneArbiterTester.scala => lib/src/test/scala/spinal/lib/bus/wishbone/WishboneArbiter.scala (98%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneArbiterTester.scala b/lib/src/test/scala/spinal/lib/bus/wishbone/WishboneArbiter.scala similarity index 98% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneArbiterTester.scala rename to lib/src/test/scala/spinal/lib/bus/wishbone/WishboneArbiter.scala index bd82641359..9cfae8a39e 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneArbiterTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/wishbone/WishboneArbiter.scala @@ -1,13 +1,15 @@ -package spinal.tester.scalatest +package spinal.lib.bus.wishbone import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import spinal.core.sim._ -import spinal.sim._ import spinal.lib._ -import spinal.lib.bus.wishbone._ import spinal.lib.wishbone.sim._ import spinal.lib.sim._ + +import spinal.sim._ + import scala.util.Random import scala.collection.Seq From 33000a5b3c498a999dfc7f07c140820f38468e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 14:54:49 +0100 Subject: [PATCH 072/120] refactor: move SpinalSimWishboneDecoderTester --- .../scala/spinal/lib/bus/wishbone/WishboneDecoder.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneDecoderTester.scala => lib/src/test/scala/spinal/lib/bus/wishbone/WishboneDecoder.scala (97%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneDecoderTester.scala b/lib/src/test/scala/spinal/lib/bus/wishbone/WishboneDecoder.scala similarity index 97% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneDecoderTester.scala rename to lib/src/test/scala/spinal/lib/bus/wishbone/WishboneDecoder.scala index 8dc707d216..c170b4c0d3 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneDecoderTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/wishbone/WishboneDecoder.scala @@ -1,14 +1,14 @@ -package spinal.tester.scalatest +package spinal.lib.bus.wishbone import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import spinal.core.sim._ -import spinal.sim._ import spinal.lib._ import spinal.lib.bus.misc._ -import spinal.lib.bus.wishbone._ import spinal.lib.wishbone.sim._ import spinal.lib.sim._ + import scala.util.Random class WishboneDecoderComponent(config : WishboneConfig,decodings : Seq[SizeMapping]) extends Component{ From 65e6e9bade867c21bfb7eb749bc12c5226dc5ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 14:57:22 +0100 Subject: [PATCH 073/120] refactor: move SpinalSimWishboneSimInterconTester --- .../spinal/lib/bus/wishbone/WishboneSimIntercon.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSimInterconTester.scala => lib/src/test/scala/spinal/lib/bus/wishbone/WishboneSimIntercon.scala (95%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSimInterconTester.scala b/lib/src/test/scala/spinal/lib/bus/wishbone/WishboneSimIntercon.scala similarity index 95% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSimInterconTester.scala rename to lib/src/test/scala/spinal/lib/bus/wishbone/WishboneSimIntercon.scala index 9739e05bb4..f2e90834e6 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSimInterconTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/wishbone/WishboneSimIntercon.scala @@ -1,15 +1,15 @@ -package spinal.tester.scalatest +package spinal.lib.bus.wishbone import org.scalatest.funsuite.AnyFunSuite -import spinal.tester + import spinal.core._ import spinal.core.sim._ import spinal.sim._ import spinal.lib._ import spinal.lib.bus.misc._ -import spinal.lib.bus.wishbone._ import spinal.lib.wishbone.sim._ import spinal.lib.sim._ + import scala.util.Random import scala.collection.Seq @@ -55,7 +55,7 @@ class SpinalSimWishboneSimInterconTester extends AnyFunSuite{ } } - scala.util.Random.shuffle(slaves).foreach{slave => + Random.shuffle(slaves).foreach{slave => driver_slave(slave).slaveSink() monitor_slave(slave, scoreboard_master) (0 to req).foreach{x => sequencer_master.addTransaction(WishboneTransaction(data=id).randomAdressInRange(slave._2))} @@ -91,7 +91,7 @@ class SpinalSimWishboneSimInterconTester extends AnyFunSuite{ val masterPool = scala.collection.mutable.ListBuffer[SimThread]() val sss = scala.collection.mutable.ListBuffer[((Wishbone,Int),(Wishbone,SizeMapping))]() - scala.util.Random.shuffle(masters.zipWithIndex).foreach{master => + Random.shuffle(masters.zipWithIndex).foreach{master => masterPool += fork{ send_transaction(master._2,master._1,slaves,1) } From 083b7ac160b07fc8abc76bfccbb65545993a2939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 14:59:11 +0100 Subject: [PATCH 074/120] refactor: move SpinalSimWishboneSlaveFactoryTester --- .../spinal/lib/bus/wishbone/WishboneSlaveFactory.scala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSlaveFactoryTester.scala => lib/src/test/scala/spinal/lib/bus/wishbone/WishboneSlaveFactory.scala (94%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSlaveFactoryTester.scala b/lib/src/test/scala/spinal/lib/bus/wishbone/WishboneSlaveFactory.scala similarity index 94% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSlaveFactoryTester.scala rename to lib/src/test/scala/spinal/lib/bus/wishbone/WishboneSlaveFactory.scala index e39e2bac61..6a3e5d699b 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSlaveFactoryTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/wishbone/WishboneSlaveFactory.scala @@ -1,14 +1,12 @@ -package spinal.tester.scalatest +package spinal.lib.bus.wishbone import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import spinal.core.sim._ -import spinal.sim._ import spinal.lib._ -import spinal.lib.bus.wishbone._ import spinal.lib.wishbone.sim._ import spinal.lib.sim._ -import scala.util.Random class WishboneSimpleSlave(config : WishboneConfig) extends Component{ val io = new Bundle{ From ce448b2858517fa5cc7c4c2194cab5d430b96c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 15:00:46 +0100 Subject: [PATCH 075/120] refactor: move SpinalSimWishboneSimTester --- .../src/test/scala/spinal/lib/bus/wishbone/Wishbone.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSimTester.scala => lib/src/test/scala/spinal/lib/bus/wishbone/Wishbone.scala (98%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSimTester.scala b/lib/src/test/scala/spinal/lib/bus/wishbone/Wishbone.scala similarity index 98% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSimTester.scala rename to lib/src/test/scala/spinal/lib/bus/wishbone/Wishbone.scala index f83731a273..abdd5b85e5 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimWishboneSimTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/wishbone/Wishbone.scala @@ -1,11 +1,10 @@ -package spinal.tester.scalatest +package spinal.lib.bus.wishbone import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ -import spinal.core.sim.{SimCompiled, _} -import spinal.sim._ +import spinal.core.sim._ import spinal.lib._ -import spinal.lib.bus.wishbone._ import spinal.lib.wishbone.sim._ import spinal.lib.sim._ From 5eea0713e792a3bdb7d9b58b5dde257052cff868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 15:07:15 +0100 Subject: [PATCH 076/120] refactor: move SpinalSimStreamExtenderTester --- lib/src/test/scala/spinal/lib/Stream.scala | 151 ++++++++++++++++ .../SpinalSimStreamExtenderTester.scala | 161 ------------------ 2 files changed, 151 insertions(+), 161 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamExtenderTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index 3df9f97683..a319485ff9 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -1881,3 +1881,154 @@ class SpinalSimStreamWidthAdapterTester extends SpinalSimFunSuite { } } } + +class SpinalSimStreamExtenderTester extends SpinalSimFunSuite { + def prepare( + dut: StreamTransactionExtender[UInt, UInt], + alwaysInput: Boolean = false, + alwaysOutput: Boolean = false, + inQueue: mutable.Queue[BigInt], + outQueue: mutable.Queue[BigInt], + countQueue: mutable.Queue[BigInt], + lastQueue: mutable.Queue[Boolean] + ) { + dut.clockDomain.forkStimulus(period = 10) + dut.io.input.valid #= false + + if (alwaysOutput) { + dut.io.output.ready #= true + } else { + val randomReady = StreamReadyRandomizer(dut.io.output, dut.clockDomain) + } + + val driver = StreamDriver(dut.io.input, dut.clockDomain) { payload => + if (inQueue.nonEmpty) { + payload #= inQueue.dequeue() + dut.io.count #= countQueue.dequeue() + true + } else { + false + } + } + driver.transactionDelay = () => { + if (!alwaysInput) { + val x = Random.nextDouble() + (x * x * 10).toInt + } else { + 0 + } + } + + val monitor = StreamMonitor(dut.io.output, dut.clockDomain) { payload => + { + val address = outQueue.dequeue() + val last = lastQueue.dequeue() + // println("##pop out queue:" + address.toString(16)) + val data = payload.toBigInt + assert((data >> 1) == address) + assert(((data & 1) == 1) == last) + } + } + + for (j <- 0 until 10000) { + val count = Random.nextInt(20) + val address = Random.nextInt(0xffffff) + + inQueue.enqueue(address) + countQueue.enqueue(count) + + for (i <- 0 to count) { + outQueue.enqueue(address) + lastQueue.enqueue(i == count) + } + } + } + + test("testRandomInOut") { + val lastQueue = mutable.Queue[Boolean]() + val compiled = SimConfig.allOptimisation.compile { + val dut = new StreamTransactionExtender( + UInt(32 bits), + UInt(33 bits), + 12, + false, + (id, payload: UInt, last) => payload @@ last + ) + dut + } + compiled.doSimUntilVoid { dut => + val inQueue = mutable.Queue[BigInt]() + val outQueue = mutable.Queue[BigInt]() + val countQueue = mutable.Queue[BigInt]() + prepare(dut, false, false, inQueue, outQueue, countQueue, lastQueue) + dut.clockDomain.waitSampling((1 KiB).toInt) + simSuccess() + } + } + + test("testRandomIn") { + val lastQueue = mutable.Queue[Boolean]() + val compiled = SimConfig.allOptimisation.compile { + val dut = new StreamTransactionExtender( + UInt(32 bits), + UInt(33 bits), + 12, + false, + (id, payload: UInt, last) => payload @@ last + ) + dut + } + compiled.doSimUntilVoid { dut => + val inQueue = mutable.Queue[BigInt]() + val outQueue = mutable.Queue[BigInt]() + val countQueue = mutable.Queue[BigInt]() + prepare(dut, false, true, inQueue, outQueue, countQueue, lastQueue) + dut.clockDomain.waitSampling((1 KiB).toInt) + simSuccess() + } + } + + test("testRandomOut") { + val lastQueue = mutable.Queue[Boolean]() + val compiled = SimConfig.allOptimisation.compile { + val dut = new StreamTransactionExtender( + UInt(32 bits), + UInt(33 bits), + 12, + false, + (id, payload: UInt, last) => payload @@ last + ) + dut + } + compiled.doSimUntilVoid { dut => + val inQueue = mutable.Queue[BigInt]() + val outQueue = mutable.Queue[BigInt]() + val countQueue = mutable.Queue[BigInt]() + prepare(dut, true, false, inQueue, outQueue, countQueue, lastQueue) + dut.clockDomain.waitSampling((1 KiB).toInt) + simSuccess() + } + } + + test("testFullPipeline") { + val lastQueue = mutable.Queue[Boolean]() + val compiled = SimConfig.allOptimisation.compile { + val dut = new StreamTransactionExtender( + UInt(32 bits), + UInt(33 bits), + 12, + false, + (id, payload: UInt, last) => payload @@ last + ) + dut + } + compiled.doSimUntilVoid { dut => + val inQueue = mutable.Queue[BigInt]() + val outQueue = mutable.Queue[BigInt]() + val countQueue = mutable.Queue[BigInt]() + prepare(dut, true, true, inQueue, outQueue, countQueue, lastQueue) + dut.clockDomain.waitSampling((1 KiB).toInt) + simSuccess() + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamExtenderTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamExtenderTester.scala deleted file mode 100644 index 7e0f9f7ac8..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamExtenderTester.scala +++ /dev/null @@ -1,161 +0,0 @@ -package spinal.tester.scalatest - -import scala.collection.mutable -import scala.util.Random -import org.scalatest.funsuite.AnyFunSuite - -import spinal.core._ -import spinal.lib._ -import spinal.lib.sim._ -import spinal.core.sim._ - -class SpinalSimStreamExtenderTester extends SpinalSimFunSuite { - def prepare( - dut: StreamTransactionExtender[UInt, UInt], - alwaysInput: Boolean = false, - alwaysOutput: Boolean = false, - inQueue: mutable.Queue[BigInt], - outQueue: mutable.Queue[BigInt], - countQueue: mutable.Queue[BigInt], - lastQueue: mutable.Queue[Boolean] - ) { - dut.clockDomain.forkStimulus(period = 10) - dut.io.input.valid #= false - - if (alwaysOutput) { - dut.io.output.ready #= true - } else { - val randomReady = StreamReadyRandomizer(dut.io.output, dut.clockDomain) - } - - val driver = StreamDriver(dut.io.input, dut.clockDomain) { payload => - if (inQueue.nonEmpty) { - payload #= inQueue.dequeue() - dut.io.count #= countQueue.dequeue() - true - } else { - false - } - } - driver.transactionDelay = () => { - if (!alwaysInput) { - val x = Random.nextDouble() - (x * x * 10).toInt - } else { - 0 - } - } - - val monitor = StreamMonitor(dut.io.output, dut.clockDomain) { payload => - { - val address = outQueue.dequeue() - val last = lastQueue.dequeue() - // println("##pop out queue:" + address.toString(16)) - val data = payload.toBigInt - assert((data >> 1) == address) - assert(((data & 1) == 1) == last) - } - } - - for (j <- 0 until 10000) { - val count = Random.nextInt(20) - val address = Random.nextInt(0xffffff) - - inQueue.enqueue(address) - countQueue.enqueue(count) - - for (i <- 0 to count) { - outQueue.enqueue(address) - lastQueue.enqueue(i == count) - } - } - } - - test("testRandomInOut") { - val lastQueue = mutable.Queue[Boolean]() - val compiled = SimConfig.allOptimisation.compile { - val dut = new StreamTransactionExtender( - UInt(32 bits), - UInt(33 bits), - 12, - false, - (id, payload: UInt, last) => payload @@ last - ) - dut - } - compiled.doSimUntilVoid { dut => - val inQueue = mutable.Queue[BigInt]() - val outQueue = mutable.Queue[BigInt]() - val countQueue = mutable.Queue[BigInt]() - prepare(dut, false, false, inQueue, outQueue, countQueue, lastQueue) - dut.clockDomain.waitSampling((1 KiB).toInt) - simSuccess() - } - } - - test("testRandomIn") { - val lastQueue = mutable.Queue[Boolean]() - val compiled = SimConfig.allOptimisation.compile { - val dut = new StreamTransactionExtender( - UInt(32 bits), - UInt(33 bits), - 12, - false, - (id, payload: UInt, last) => payload @@ last - ) - dut - } - compiled.doSimUntilVoid { dut => - val inQueue = mutable.Queue[BigInt]() - val outQueue = mutable.Queue[BigInt]() - val countQueue = mutable.Queue[BigInt]() - prepare(dut, false, true, inQueue, outQueue, countQueue, lastQueue) - dut.clockDomain.waitSampling((1 KiB).toInt) - simSuccess() - } - } - - test("testRandomOut") { - val lastQueue = mutable.Queue[Boolean]() - val compiled = SimConfig.allOptimisation.compile { - val dut = new StreamTransactionExtender( - UInt(32 bits), - UInt(33 bits), - 12, - false, - (id, payload: UInt, last) => payload @@ last - ) - dut - } - compiled.doSimUntilVoid { dut => - val inQueue = mutable.Queue[BigInt]() - val outQueue = mutable.Queue[BigInt]() - val countQueue = mutable.Queue[BigInt]() - prepare(dut, true, false, inQueue, outQueue, countQueue, lastQueue) - dut.clockDomain.waitSampling((1 KiB).toInt) - simSuccess() - } - } - - test("testFullPipeline") { - val lastQueue = mutable.Queue[Boolean]() - val compiled = SimConfig.allOptimisation.compile { - val dut = new StreamTransactionExtender( - UInt(32 bits), - UInt(33 bits), - 12, - false, - (id, payload: UInt, last) => payload @@ last - ) - dut - } - compiled.doSimUntilVoid { dut => - val inQueue = mutable.Queue[BigInt]() - val outQueue = mutable.Queue[BigInt]() - val countQueue = mutable.Queue[BigInt]() - prepare(dut, true, true, inQueue, outQueue, countQueue, lastQueue) - dut.clockDomain.waitSampling((1 KiB).toInt) - simSuccess() - } - } -} From 0832dbe3f14524d4f291606429a8b20205afd9bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 15:10:40 +0100 Subject: [PATCH 077/120] refactor: move SpinalSimStreamFifoCCTester --- lib/src/test/scala/spinal/lib/Stream.scala | 250 +++++++++++++++++ .../SpinalSimStreamFifoCCTester.scala | 261 ------------------ 2 files changed, 250 insertions(+), 261 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoCCTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index a319485ff9..bc8defc541 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -2032,3 +2032,253 @@ class SpinalSimStreamExtenderTester extends SpinalSimFunSuite { } } } + +class SpinalSimStreamFifoCCTester extends SpinalSimFunSuite { + +// onlyVerilator() + + def testbench(dut : StreamFifoCC[Bits]): Unit ={ + val queueModel = mutable.Queue[Long]() + + //Push data randomly and fill the queueModel with pushed transactions + val pushThread = fork{ + while(true){ + dut.io.push.valid.randomize() + dut.io.push.payload.randomize() + dut.pushClock.waitSampling() + if(dut.io.push.valid.toBoolean && dut.io.push.ready.toBoolean){ + queueModel.enqueue(dut.io.push.payload.toLong) + } + } + } + + //Pop data randomly and check that it match with the queueModel + val popThread = fork{ + dut.io.pop.ready #= false + dut.pushClock.waitSampling() + dut.popClock.waitSampling() + for(repeat <- 0 until 10000){ + dut.io.pop.ready.randomize() + dut.popClock.waitSampling() + if(dut.io.pop.valid.toBoolean && dut.io.pop.ready.toBoolean){ + assert(dut.io.pop.payload.toLong == queueModel.dequeue()) + } + } + simSuccess() + } + } + + for(pushResetLevel <- List(LOW, HIGH); + popResetLevel <- List(LOW, HIGH); + popResetEnable <- List(false, true)) { + val postfix = s"${pushResetLevel}_${popResetLevel}_${popResetEnable}" + test("testAsyncReset_" + postfix) { + //Compile the simulator + val compiled = SimConfig.allOptimisation.compile( + rtl = new StreamFifoCC( + dataType = Bits(32 bits), + depth = 32, + pushClock = ClockDomain.external("clkA", config = ClockDomainConfig(resetActiveLevel = pushResetLevel)), + popClock = ClockDomain.external("clkB", withReset = popResetEnable, config = ClockDomainConfig(resetActiveLevel = popResetLevel)), + withPopBufferedReset = !popResetEnable + ) + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + fork { + //Clear clock domains signals, to be sure the simulation capture their first edge. + dut.pushClock.fallingEdge() + dut.popClock.fallingEdge() + dut.pushClock.deassertReset() + if(popResetEnable) dut.popClock.deassertReset() + sleep(0) + + //Do the resets + dut.pushClock.assertReset() + if(popResetEnable)dut.popClock.assertReset() + sleep(10) + dut.pushClock.deassertReset() + if(popResetEnable)dut.popClock.deassertReset() + sleep(1) + + //Forever, randomly toggle one of the clocks (will create asynchronous clocks without fixed frequencies) + while (true) { + if (Random.nextBoolean()) { + dut.pushClock.clockToggle() + } else { + dut.popClock.clockToggle() + } + sleep(1) + } + } + testbench(dut) + } + } + + test("testSyncReset_" + postfix) { + //Compile the simulator + val compiled = SimConfig.withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = SYNC))).allOptimisation.compile( + rtl = new StreamFifoCC( + dataType = Bits(32 bits), + depth = 32, + pushClock = ClockDomain.external("clkA", config = ClockDomainConfig(resetActiveLevel = pushResetLevel)), + popClock = ClockDomain.external("clkB", withReset = popResetEnable, config = ClockDomainConfig(resetActiveLevel = popResetLevel)), + withPopBufferedReset = !popResetEnable + ) + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + dut.pushClock.fallingEdge() + dut.popClock.fallingEdge() + dut.pushClock.deassertReset() + if(popResetEnable) dut.popClock.deassertReset() + fork { + //Clear clock domains signals, to be sure the simulation capture their first edge. + sleep(0) + + //Do the resets + dut.pushClock.assertReset() + if(popResetEnable) dut.popClock.assertReset() + sleep(10) + dut.pushClock.deassertReset() + if(popResetEnable) dut.popClock.deassertReset() + sleep(1) + } + + fork { + sleep(1) + for (i <- 0 until 5) { + dut.pushClock.clockToggle() + dut.popClock.clockToggle() + sleep(1) + } + //Forever, randomly toggle one of the clocks (will create asynchronous clocks without fixed frequencies) + while (true) { + if (Random.nextBoolean()) { + dut.pushClock.clockToggle() + } else { + dut.popClock.clockToggle() + } + sleep(1) + } + } + testbench(dut) + } + } + } + + test("testBootReset") { + //Compile the simulator + val compiled = SimConfig.withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = BOOT))).allOptimisation.compile( + rtl = new StreamFifoCC( + dataType = Bits(32 bits), + depth = 32, + pushClock = ClockDomain.external("clkA"), + popClock = ClockDomain.external("clkB", withReset = false) + ) + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + fork { + dut.pushClock.fallingEdge() + dut.popClock.fallingEdge() + sleep(1) + //Forever, randomly toggle one of the clocks (will create asynchronous clocks without fixed frequencies) + while (true) { + if (Random.nextBoolean()) { + dut.pushClock.clockToggle() + } else { + dut.popClock.clockToggle() + } + sleep(1) + } + } + testbench(dut) + } + } +} + + +object TesterBugPlay extends App{ + + def testbench(dut : StreamFifoCC[Bits]): Unit ={ + val queueModel = mutable.Queue[Long]() + + //Push data randomly and fill the queueModel with pushed transactions + val pushThread = fork{ + while(true){ + dut.io.push.valid.randomize() + dut.io.push.payload.randomize() + dut.pushClock.waitSampling() + if(dut.io.push.valid.toBoolean && dut.io.push.ready.toBoolean){ + queueModel.enqueue(dut.io.push.payload.toLong) + } + } + } + + //Pop data randomly and check that it match with the queueModel + val popThread = fork{ + for(repeat <- 0 until 10000){ + dut.io.pop.ready.randomize() + dut.popClock.waitSampling() + if(dut.io.pop.valid.toBoolean && dut.io.pop.ready.toBoolean){ + assert(dut.io.pop.payload.toLong == queueModel.dequeue()) + } + } + simSuccess() + } + } + val compiled = SimConfig.withIVerilog.withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = SYNC))).allOptimisation.compile( + rtl = new StreamFifoCC( + dataType = Bits(32 bits), + depth = 32, + pushClock = ClockDomain.external("clkA"), + popClock = ClockDomain.external("clkB", withReset = false) + ) + ) + + for(i <- 132 until 1000) { + + //Run the simulation + compiled.doSimUntilVoid(seed = i) { dut => + dut.pushClock.fallingEdge() + dut.popClock.fallingEdge() + dut.pushClock.deassertReset() +// dut.popClock.deassertReset() + fork { + //Clear clock domains signals, to be sure the simulation capture their first edge. + sleep(0) + + //Do the resets + dut.pushClock.assertReset() +// dut.popClock.assertReset() + sleep(10) + dut.pushClock.deassertReset() +// dut.popClock.deassertReset() + sleep(1) + } + + fork { + sleep(1) + for(i <- 0 until 5) { + dut.pushClock.clockToggle() + dut.popClock.clockToggle() + sleep(1) + } + //Forever, randomly toggle one of the clocks (will create asynchronous clocks without fixed frequencies) + while (true) { + if (Random.nextBoolean()) { + dut.pushClock.clockToggle() + } else { + dut.popClock.clockToggle() + } + sleep(1) + } + } + testbench(dut) + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoCCTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoCCTester.scala deleted file mode 100644 index 1d5c311fca..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoCCTester.scala +++ /dev/null @@ -1,261 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.sim._ -import spinal.core.sim._ -import spinal.lib.StreamFifoCC -import spinal.tester - -import scala.collection.mutable -import scala.util.Random - -class SpinalSimStreamFifoCCTester extends SpinalSimFunSuite { - -// onlyVerilator() - - def testbench(dut : StreamFifoCC[Bits]): Unit ={ - val queueModel = mutable.Queue[Long]() - - //Push data randomly and fill the queueModel with pushed transactions - val pushThread = fork{ - while(true){ - dut.io.push.valid.randomize() - dut.io.push.payload.randomize() - dut.pushClock.waitSampling() - if(dut.io.push.valid.toBoolean && dut.io.push.ready.toBoolean){ - queueModel.enqueue(dut.io.push.payload.toLong) - } - } - } - - //Pop data randomly and check that it match with the queueModel - val popThread = fork{ - dut.io.pop.ready #= false - dut.pushClock.waitSampling() - dut.popClock.waitSampling() - for(repeat <- 0 until 10000){ - dut.io.pop.ready.randomize() - dut.popClock.waitSampling() - if(dut.io.pop.valid.toBoolean && dut.io.pop.ready.toBoolean){ - assert(dut.io.pop.payload.toLong == queueModel.dequeue()) - } - } - simSuccess() - } - } - - for(pushResetLevel <- List(LOW, HIGH); - popResetLevel <- List(LOW, HIGH); - popResetEnable <- List(false, true)) { - val postfix = s"${pushResetLevel}_${popResetLevel}_${popResetEnable}" - test("testAsyncReset_" + postfix) { - //Compile the simulator - val compiled = SimConfig.allOptimisation.compile( - rtl = new StreamFifoCC( - dataType = Bits(32 bits), - depth = 32, - pushClock = ClockDomain.external("clkA", config = ClockDomainConfig(resetActiveLevel = pushResetLevel)), - popClock = ClockDomain.external("clkB", withReset = popResetEnable, config = ClockDomainConfig(resetActiveLevel = popResetLevel)), - withPopBufferedReset = !popResetEnable - ) - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - fork { - //Clear clock domains signals, to be sure the simulation capture their first edge. - dut.pushClock.fallingEdge() - dut.popClock.fallingEdge() - dut.pushClock.deassertReset() - if(popResetEnable) dut.popClock.deassertReset() - sleep(0) - - //Do the resets - dut.pushClock.assertReset() - if(popResetEnable)dut.popClock.assertReset() - sleep(10) - dut.pushClock.deassertReset() - if(popResetEnable)dut.popClock.deassertReset() - sleep(1) - - //Forever, randomly toggle one of the clocks (will create asynchronous clocks without fixed frequencies) - while (true) { - if (Random.nextBoolean()) { - dut.pushClock.clockToggle() - } else { - dut.popClock.clockToggle() - } - sleep(1) - } - } - testbench(dut) - } - } - - test("testSyncReset_" + postfix) { - //Compile the simulator - val compiled = SimConfig.withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = SYNC))).allOptimisation.compile( - rtl = new StreamFifoCC( - dataType = Bits(32 bits), - depth = 32, - pushClock = ClockDomain.external("clkA", config = ClockDomainConfig(resetActiveLevel = pushResetLevel)), - popClock = ClockDomain.external("clkB", withReset = popResetEnable, config = ClockDomainConfig(resetActiveLevel = popResetLevel)), - withPopBufferedReset = !popResetEnable - ) - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - dut.pushClock.fallingEdge() - dut.popClock.fallingEdge() - dut.pushClock.deassertReset() - if(popResetEnable) dut.popClock.deassertReset() - fork { - //Clear clock domains signals, to be sure the simulation capture their first edge. - sleep(0) - - //Do the resets - dut.pushClock.assertReset() - if(popResetEnable) dut.popClock.assertReset() - sleep(10) - dut.pushClock.deassertReset() - if(popResetEnable) dut.popClock.deassertReset() - sleep(1) - } - - fork { - sleep(1) - for (i <- 0 until 5) { - dut.pushClock.clockToggle() - dut.popClock.clockToggle() - sleep(1) - } - //Forever, randomly toggle one of the clocks (will create asynchronous clocks without fixed frequencies) - while (true) { - if (Random.nextBoolean()) { - dut.pushClock.clockToggle() - } else { - dut.popClock.clockToggle() - } - sleep(1) - } - } - testbench(dut) - } - } - } - - test("testBootReset") { - //Compile the simulator - val compiled = SimConfig.withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = BOOT))).allOptimisation.compile( - rtl = new StreamFifoCC( - dataType = Bits(32 bits), - depth = 32, - pushClock = ClockDomain.external("clkA"), - popClock = ClockDomain.external("clkB", withReset = false) - ) - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - fork { - dut.pushClock.fallingEdge() - dut.popClock.fallingEdge() - sleep(1) - //Forever, randomly toggle one of the clocks (will create asynchronous clocks without fixed frequencies) - while (true) { - if (Random.nextBoolean()) { - dut.pushClock.clockToggle() - } else { - dut.popClock.clockToggle() - } - sleep(1) - } - } - testbench(dut) - } - } -} - - -object TesterBugPlay extends App{ - - def testbench(dut : StreamFifoCC[Bits]): Unit ={ - val queueModel = mutable.Queue[Long]() - - //Push data randomly and fill the queueModel with pushed transactions - val pushThread = fork{ - while(true){ - dut.io.push.valid.randomize() - dut.io.push.payload.randomize() - dut.pushClock.waitSampling() - if(dut.io.push.valid.toBoolean && dut.io.push.ready.toBoolean){ - queueModel.enqueue(dut.io.push.payload.toLong) - } - } - } - - //Pop data randomly and check that it match with the queueModel - val popThread = fork{ - for(repeat <- 0 until 10000){ - dut.io.pop.ready.randomize() - dut.popClock.waitSampling() - if(dut.io.pop.valid.toBoolean && dut.io.pop.ready.toBoolean){ - assert(dut.io.pop.payload.toLong == queueModel.dequeue()) - } - } - simSuccess() - } - } - val compiled = SimConfig.withIVerilog.withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = SYNC))).allOptimisation.compile( - rtl = new StreamFifoCC( - dataType = Bits(32 bits), - depth = 32, - pushClock = ClockDomain.external("clkA"), - popClock = ClockDomain.external("clkB", withReset = false) - ) - ) - - for(i <- 132 until 1000) { - - //Run the simulation - compiled.doSimUntilVoid(seed = i) { dut => - dut.pushClock.fallingEdge() - dut.popClock.fallingEdge() - dut.pushClock.deassertReset() -// dut.popClock.deassertReset() - fork { - //Clear clock domains signals, to be sure the simulation capture their first edge. - sleep(0) - - //Do the resets - dut.pushClock.assertReset() -// dut.popClock.assertReset() - sleep(10) - dut.pushClock.deassertReset() -// dut.popClock.deassertReset() - sleep(1) - } - - fork { - sleep(1) - for(i <- 0 until 5) { - dut.pushClock.clockToggle() - dut.popClock.clockToggle() - sleep(1) - } - //Forever, randomly toggle one of the clocks (will create asynchronous clocks without fixed frequencies) - while (true) { - if (Random.nextBoolean()) { - dut.pushClock.clockToggle() - } else { - dut.popClock.clockToggle() - } - sleep(1) - } - } - testbench(dut) - } - } -} \ No newline at end of file From 2d7be51c5c8ef7f1a1717cf438c6ead6a5906834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 15:13:49 +0100 Subject: [PATCH 078/120] refactor: move SpinalSimStreamFifoMultiChannelSharedSpaceTester --- lib/src/test/scala/spinal/lib/Stream.scala | 35 ++++++++++++++ ...eamFifoMultiChannelSharedSpaceTester.scala | 46 ------------------- 2 files changed, 35 insertions(+), 46 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoMultiChannelSharedSpaceTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index bc8defc541..1091f14c68 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -8,6 +8,7 @@ import spinal.lib.sim._ import spinal.tester.{SpinalTesterCocotbBase, SpinalTesterGhdlBase, SpinalSimFunSuite} +import org.scalatest.funsuite.AnyFunSuite import scala.collection.mutable import scala.util.Random @@ -2282,3 +2283,37 @@ object TesterBugPlay extends App{ } } } + +class SpinalSimStreamFifoMultiChannelSharedSpaceTester extends AnyFunSuite { + test("t1") { + SimConfig.compile(new StreamFifoMultiChannelSharedSpace(Bits(32 bits), 4, 16)).doSimUntilVoid(seed = 42) { dut => + val queueModel = mutable.ArrayBuffer.fill(4)(mutable.Queue[Long]()) + + SimTimeout(1000000) + dut.clockDomain.forkStimulus(2) + //Push data randomly and fill the queueModel with pushed transactions + dut.io.push.stream.valid #= false + dut.io.pop.stream.ready #= true + + val successCount = Array.fill(4)(0) + dut.clockDomain.onSamplings { + assert(!(dut.io.push.full.toBoolean && (dut.io.availability.toInt > 1))) + + if (dut.io.push.stream.valid.toBoolean && dut.io.push.stream.ready.toBoolean) { + queueModel(log2Up(dut.io.push.channel.toInt)).enqueue(dut.io.push.stream.payload.toLong) + } + if (dut.io.pop.stream.valid.toBoolean && dut.io.pop.stream.ready.toBoolean) { + val channel = log2Up(dut.io.pop.channel.toInt) + assert(dut.io.pop.stream.payload.toLong == queueModel(channel).dequeue()) + successCount(channel) += 1 + if (successCount.forall(_ > 20000)) simSuccess() + } + dut.io.push.stream.valid.randomize() + dut.io.push.stream.payload.randomize() + dut.io.push.channel #= (1 << Random.nextInt(dut.channelCount)) + dut.io.pop.stream.ready.randomize() + dut.io.pop.channel #= (1 << Random.nextInt(dut.channelCount)) + } + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoMultiChannelSharedSpaceTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoMultiChannelSharedSpaceTester.scala deleted file mode 100644 index a45e572126..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoMultiChannelSharedSpaceTester.scala +++ /dev/null @@ -1,46 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.sim._ -import spinal.core.sim._ -import spinal.lib.{StreamFifoCC, StreamFifoMultiChannelSharedSpace} -import spinal.tester - -import scala.collection.mutable -import scala.collection.mutable.ArrayBuffer -import scala.util.Random - -class SpinalSimStreamFifoMultiChannelSharedSpaceTester extends AnyFunSuite { - test("t1") { - SimConfig.compile(new StreamFifoMultiChannelSharedSpace(Bits(32 bits), 4, 16)).doSimUntilVoid(seed = 42) { dut => - val queueModel = ArrayBuffer.fill(4)(mutable.Queue[Long]()) - - SimTimeout(1000000) - dut.clockDomain.forkStimulus(2) - //Push data randomly and fill the queueModel with pushed transactions - dut.io.push.stream.valid #= false - dut.io.pop.stream.ready #= true - - val successCount = Array.fill(4)(0) - dut.clockDomain.onSamplings { - assert(!(dut.io.push.full.toBoolean && (dut.io.availability.toInt > 1))) - - if (dut.io.push.stream.valid.toBoolean && dut.io.push.stream.ready.toBoolean) { - queueModel(log2Up(dut.io.push.channel.toInt)).enqueue(dut.io.push.stream.payload.toLong) - } - if (dut.io.pop.stream.valid.toBoolean && dut.io.pop.stream.ready.toBoolean) { - val channel = log2Up(dut.io.pop.channel.toInt) - assert(dut.io.pop.stream.payload.toLong == queueModel(channel).dequeue()) - successCount(channel) += 1 - if (successCount.forall(_ > 20000)) simSuccess() - } - dut.io.push.stream.valid.randomize() - dut.io.push.stream.payload.randomize() - dut.io.push.channel #= (1 << Random.nextInt(dut.channelCount)) - dut.io.pop.stream.ready.randomize() - dut.io.pop.channel #= (1 << Random.nextInt(dut.channelCount)) - } - } - } -} From 678a472229f52278e5ede4d6bddee6aaf36f8267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 15:14:56 +0100 Subject: [PATCH 079/120] refactor: move SpinalSimStreamFifoTester --- lib/src/test/scala/spinal/lib/Stream.scala | 259 +++++++++++++++++ .../scalatest/SpinalSimStreamFifoTester.scala | 271 ------------------ 2 files changed, 259 insertions(+), 271 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoTester.scala diff --git a/lib/src/test/scala/spinal/lib/Stream.scala b/lib/src/test/scala/spinal/lib/Stream.scala index 1091f14c68..afeec803a2 100644 --- a/lib/src/test/scala/spinal/lib/Stream.scala +++ b/lib/src/test/scala/spinal/lib/Stream.scala @@ -5,6 +5,7 @@ import spinal.core.sim._ import spinal.core.formal._ import spinal.lib.formal._ import spinal.lib.sim._ +import spinal.lib.graphic.Rgb import spinal.tester.{SpinalTesterCocotbBase, SpinalTesterGhdlBase, SpinalSimFunSuite} @@ -2317,3 +2318,261 @@ class SpinalSimStreamFifoMultiChannelSharedSpaceTester extends AnyFunSuite { } } } + +class SpinalSimStreamFifoTester extends SpinalSimFunSuite { + test("testBits") { + //Compile the simulator + val compiled = SimConfig.allOptimisation.compile( + rtl = new StreamFifo( + dataType = Bits(32 bits), + depth = 32 + ) + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val queueModel = mutable.Queue[Long]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + + dut.io.flush #= false + + //Push data randomly and fill the queueModel with pushed transactions + dut.io.push.valid #= false + dut.clockDomain.onSamplings { + if (dut.io.push.valid.toBoolean && dut.io.push.ready.toBoolean) { + queueModel.enqueue(dut.io.push.payload.toLong) + } + dut.io.push.valid.randomize() + dut.io.push.payload.randomize() + } + + //Pop data randomly and check that it match with the queueModel + val popThread = fork { + dut.io.pop.ready #= true + for (repeat <- 0 until 10000) { + dut.io.pop.ready.randomize() + dut.clockDomain.waitSampling() + if (dut.io.pop.valid.toBoolean && dut.io.pop.ready.toBoolean) { + assert(dut.io.pop.payload.toLong == queueModel.dequeue()) + } + } + simSuccess() + } + } + } + + + test("testOne") { + //Compile the simulator + val compiled = SimConfig.allOptimisation.compile( + rtl = new StreamFifo( + dataType = Bits(32 bits), + depth = 1 + ) + ) + + //Run the simulation + compiled.doSimUntilVoid { dut => + val queueModel = mutable.Queue[Long]() + + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + + dut.io.flush #= false + + //Push data randomly and fill the queueModel with pushed transactions + dut.io.push.valid #= false + dut.clockDomain.onSamplings { + if (dut.io.push.valid.toBoolean && dut.io.push.ready.toBoolean) { + queueModel.enqueue(dut.io.push.payload.toLong) + } + dut.io.push.valid.randomize() + dut.io.push.payload.randomize() + } + + //Pop data randomly and check that it match with the queueModel + val popThread = fork { + dut.io.pop.ready #= true + for (repeat <- 0 until 10000) { + dut.io.pop.ready.randomize() + dut.clockDomain.waitSampling() + if (dut.io.pop.valid.toBoolean && dut.io.pop.ready.toBoolean) { + assert(dut.io.pop.payload.toLong == queueModel.dequeue()) + } + } + simSuccess() + } + } + } + + + test("testBundle") { + //Bundle used as fifo payload + case class Transaction() extends Bundle { + val flag = Bool() + val data = Bits(8 bits) + val color = Rgb(5, 6, 5) + + override def clone = Transaction() + } + + val compiled = SimConfig.allOptimisation.compile( + rtl = new StreamFifo( + dataType = Transaction(), + depth = 32 + ) + ) + + //Run the simulation + compiled.doSim { dut => + //Inits + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + dut.clockDomain.forkSimSpeedPrinter() + dut.io.flush #= false + + val scoreboard = ScoreboardInOrder[SimData]() + + //Drivers + StreamDriver(dut.io.push, dut.clockDomain) { payload => + payload.randomize() + true + } + StreamReadyRandomizer(dut.io.pop, dut.clockDomain) + + //Monitors + StreamMonitor(dut.io.push, dut.clockDomain) { payload => + scoreboard.pushRef(payload) + } + StreamMonitor(dut.io.pop, dut.clockDomain) { payload => + scoreboard.pushDut(payload) + } + + waitUntil(scoreboard.matches == 10000) + } + } + + test("testTwoDepth") { + //Bundle used as fifo payload + case class Transaction() extends Bundle { + val flag = Bool() + val data = Bits(8 bits) + val color = Rgb(5, 6, 5) + } + + val compiled = SimConfig.allOptimisation.compile( + rtl = new StreamFifo( + dataType = Transaction(), + depth = 2 + ) + ) + + //Run the simulation + compiled.doSim { dut => + //Inits + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + dut.clockDomain.forkSimSpeedPrinter() + dut.io.flush #= false + + val scoreboard = ScoreboardInOrder[SimData]() + + //Drivers + StreamDriver(dut.io.push, dut.clockDomain) { payload => + payload.randomize() + true + } + StreamReadyRandomizer(dut.io.pop, dut.clockDomain) + + //Monitors + StreamMonitor(dut.io.push, dut.clockDomain) { payload => + scoreboard.pushRef(payload) + } + StreamMonitor(dut.io.pop, dut.clockDomain) { payload => + scoreboard.pushDut(payload) + } + + waitUntil(scoreboard.matches == 10000) + } + } + + + test("lowLatency_0") { + //Bundle used as fifo payload + case class Transaction() extends Bundle { + val flag = Bool() + val data = Bits(8 bits) + val color = Rgb(5, 6, 5) + } + + val compiled = SimConfig.allOptimisation.compile( + rtl = new StreamFifoLowLatency( + dataType = Transaction(), + depth = 2, + latency = 0 + ) + ) + + //Run the simulation + compiled.doSim { dut => + //Inits + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + dut.clockDomain.forkSimSpeedPrinter() + dut.io.flush #= false + + val scoreboard = ScoreboardInOrder[SimData]() + + //Drivers + StreamDriver(dut.io.push, dut.clockDomain) { payload => payload.randomize(); true } + StreamReadyRandomizer(dut.io.pop, dut.clockDomain) + + //Monitors + StreamMonitor(dut.io.push, dut.clockDomain) { payload => scoreboard.pushRef(payload) } + StreamMonitor(dut.io.pop, dut.clockDomain) { payload => scoreboard.pushDut(payload) } + + waitUntil(scoreboard.matches == 10000) + } + } + + + test("lowLatency_1") { + //Bundle used as fifo payload + case class Transaction() extends Bundle { + val flag = Bool() + val data = Bits(8 bits) + val color = Rgb(5, 6, 5) + } + + val compiled = SimConfig.allOptimisation.compile( + rtl = new StreamFifoLowLatency( + dataType = Transaction(), + depth = 4, + latency = 1 + ) + ) + + //Run the simulation + compiled.doSim { dut => + //Inits + SimTimeout(1000000 * 8) + dut.clockDomain.forkStimulus(2) + dut.clockDomain.forkSimSpeedPrinter() + dut.io.flush #= false + + val scoreboard = ScoreboardInOrder[SimData]() + + //Drivers + StreamDriver(dut.io.push, dut.clockDomain) { payload => payload.randomize(); true } + StreamReadyRandomizer(dut.io.pop, dut.clockDomain) + + //Monitors + StreamMonitor(dut.io.push, dut.clockDomain) { payload => scoreboard.pushRef(payload) } + StreamMonitor(dut.io.pop, dut.clockDomain) { payload => scoreboard.pushDut(payload) } + + waitUntil(scoreboard.matches == 10000) + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoTester.scala deleted file mode 100644 index 6811ff91ed..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimStreamFifoTester.scala +++ /dev/null @@ -1,271 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.sim._ -import spinal.core.sim._ -import spinal.lib.{StreamFifo, StreamFifoLowLatency} -import spinal.lib.graphic.Rgb -import spinal.lib.sim._ -import spinal.tester - -import scala.collection.mutable -import scala.util.Random - -class SpinalSimStreamFifoTester extends SpinalSimFunSuite { - test("testBits") { - //Compile the simulator - val compiled = SimConfig.allOptimisation.compile( - rtl = new StreamFifo( - dataType = Bits(32 bits), - depth = 32 - ) - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val queueModel = mutable.Queue[Long]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - - dut.io.flush #= false - - //Push data randomly and fill the queueModel with pushed transactions - dut.io.push.valid #= false - dut.clockDomain.onSamplings { - if (dut.io.push.valid.toBoolean && dut.io.push.ready.toBoolean) { - queueModel.enqueue(dut.io.push.payload.toLong) - } - dut.io.push.valid.randomize() - dut.io.push.payload.randomize() - } - - //Pop data randomly and check that it match with the queueModel - val popThread = fork { - dut.io.pop.ready #= true - for (repeat <- 0 until 10000) { - dut.io.pop.ready.randomize() - dut.clockDomain.waitSampling() - if (dut.io.pop.valid.toBoolean && dut.io.pop.ready.toBoolean) { - assert(dut.io.pop.payload.toLong == queueModel.dequeue()) - } - } - simSuccess() - } - } - } - - - test("testOne") { - //Compile the simulator - val compiled = SimConfig.allOptimisation.compile( - rtl = new StreamFifo( - dataType = Bits(32 bits), - depth = 1 - ) - ) - - //Run the simulation - compiled.doSimUntilVoid { dut => - val queueModel = mutable.Queue[Long]() - - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - - dut.io.flush #= false - - //Push data randomly and fill the queueModel with pushed transactions - dut.io.push.valid #= false - dut.clockDomain.onSamplings { - if (dut.io.push.valid.toBoolean && dut.io.push.ready.toBoolean) { - queueModel.enqueue(dut.io.push.payload.toLong) - } - dut.io.push.valid.randomize() - dut.io.push.payload.randomize() - } - - //Pop data randomly and check that it match with the queueModel - val popThread = fork { - dut.io.pop.ready #= true - for (repeat <- 0 until 10000) { - dut.io.pop.ready.randomize() - dut.clockDomain.waitSampling() - if (dut.io.pop.valid.toBoolean && dut.io.pop.ready.toBoolean) { - assert(dut.io.pop.payload.toLong == queueModel.dequeue()) - } - } - simSuccess() - } - } - } - - - test("testBundle") { - //Bundle used as fifo payload - case class Transaction() extends Bundle { - val flag = Bool() - val data = Bits(8 bits) - val color = Rgb(5, 6, 5) - - override def clone = Transaction() - } - - val compiled = SimConfig.allOptimisation.compile( - rtl = new StreamFifo( - dataType = Transaction(), - depth = 32 - ) - ) - - //Run the simulation - compiled.doSim { dut => - //Inits - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - dut.clockDomain.forkSimSpeedPrinter() - dut.io.flush #= false - - val scoreboard = ScoreboardInOrder[SimData]() - - //Drivers - StreamDriver(dut.io.push, dut.clockDomain) { payload => - payload.randomize() - true - } - StreamReadyRandomizer(dut.io.pop, dut.clockDomain) - - //Monitors - StreamMonitor(dut.io.push, dut.clockDomain) { payload => - scoreboard.pushRef(payload) - } - StreamMonitor(dut.io.pop, dut.clockDomain) { payload => - scoreboard.pushDut(payload) - } - - waitUntil(scoreboard.matches == 10000) - } - } - - test("testTwoDepth") { - //Bundle used as fifo payload - case class Transaction() extends Bundle { - val flag = Bool() - val data = Bits(8 bits) - val color = Rgb(5, 6, 5) - } - - val compiled = SimConfig.allOptimisation.compile( - rtl = new StreamFifo( - dataType = Transaction(), - depth = 2 - ) - ) - - //Run the simulation - compiled.doSim { dut => - //Inits - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - dut.clockDomain.forkSimSpeedPrinter() - dut.io.flush #= false - - val scoreboard = ScoreboardInOrder[SimData]() - - //Drivers - StreamDriver(dut.io.push, dut.clockDomain) { payload => - payload.randomize() - true - } - StreamReadyRandomizer(dut.io.pop, dut.clockDomain) - - //Monitors - StreamMonitor(dut.io.push, dut.clockDomain) { payload => - scoreboard.pushRef(payload) - } - StreamMonitor(dut.io.pop, dut.clockDomain) { payload => - scoreboard.pushDut(payload) - } - - waitUntil(scoreboard.matches == 10000) - } - } - - - test("lowLatency_0") { - //Bundle used as fifo payload - case class Transaction() extends Bundle { - val flag = Bool() - val data = Bits(8 bits) - val color = Rgb(5, 6, 5) - } - - val compiled = SimConfig.allOptimisation.compile( - rtl = new StreamFifoLowLatency( - dataType = Transaction(), - depth = 2, - latency = 0 - ) - ) - - //Run the simulation - compiled.doSim { dut => - //Inits - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - dut.clockDomain.forkSimSpeedPrinter() - dut.io.flush #= false - - val scoreboard = ScoreboardInOrder[SimData]() - - //Drivers - StreamDriver(dut.io.push, dut.clockDomain) { payload => payload.randomize(); true } - StreamReadyRandomizer(dut.io.pop, dut.clockDomain) - - //Monitors - StreamMonitor(dut.io.push, dut.clockDomain) { payload => scoreboard.pushRef(payload) } - StreamMonitor(dut.io.pop, dut.clockDomain) { payload => scoreboard.pushDut(payload) } - - waitUntil(scoreboard.matches == 10000) - } - } - - - test("lowLatency_1") { - //Bundle used as fifo payload - case class Transaction() extends Bundle { - val flag = Bool() - val data = Bits(8 bits) - val color = Rgb(5, 6, 5) - } - - val compiled = SimConfig.allOptimisation.compile( - rtl = new StreamFifoLowLatency( - dataType = Transaction(), - depth = 4, - latency = 1 - ) - ) - - //Run the simulation - compiled.doSim { dut => - //Inits - SimTimeout(1000000 * 8) - dut.clockDomain.forkStimulus(2) - dut.clockDomain.forkSimSpeedPrinter() - dut.io.flush #= false - - val scoreboard = ScoreboardInOrder[SimData]() - - //Drivers - StreamDriver(dut.io.push, dut.clockDomain) { payload => payload.randomize(); true } - StreamReadyRandomizer(dut.io.pop, dut.clockDomain) - - //Monitors - StreamMonitor(dut.io.push, dut.clockDomain) { payload => scoreboard.pushRef(payload) } - StreamMonitor(dut.io.pop, dut.clockDomain) { payload => scoreboard.pushDut(payload) } - - waitUntil(scoreboard.matches == 10000) - } - } -} From 3ab5dcda46c23b9792cad08de077654aecb91e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 15:19:31 +0100 Subject: [PATCH 080/120] refactor: move SpinalSimPhaseTester --- .../src/test/scala/spinal/lib/sim/Misc.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimPhaseTester.scala => lib/src/test/scala/spinal/lib/sim/Misc.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimPhaseTester.scala b/lib/src/test/scala/spinal/lib/sim/Misc.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimPhaseTester.scala rename to lib/src/test/scala/spinal/lib/sim/Misc.scala index fd85b2d86a..2059bf6965 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimPhaseTester.scala +++ b/lib/src/test/scala/spinal/lib/sim/Misc.scala @@ -1,8 +1,9 @@ -package spinal.tester.scalatest +package spinal.lib.sim import org.scalatest.funsuite.AnyFunSuite +import spinal.tester.SpinalSimFunSuite + import spinal.core.sim._ -import spinal.lib.sim._ import spinal.core._ import spinal.lib._ import spinal.lib.graphic.Rgb From 0e9c99023e3069ed8c057b4476ee609e8709a242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 15:31:41 +0100 Subject: [PATCH 081/120] refactor: move SpinalSimOneEntryRamTester --- core/src/test/scala/spinal/core/Mem.scala | 186 ++++++++++++++++- .../SpinalSimOneEntryRamTester.scala | 187 ------------------ 2 files changed, 184 insertions(+), 189 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimOneEntryRamTester.scala diff --git a/core/src/test/scala/spinal/core/Mem.scala b/core/src/test/scala/spinal/core/Mem.scala index 3a1ae7c8c3..5caeeecd27 100644 --- a/core/src/test/scala/spinal/core/Mem.scala +++ b/core/src/test/scala/spinal/core/Mem.scala @@ -1,9 +1,10 @@ package spinal.core +import spinal.core.sim._ import spinal.lib._ import spinal.lib.bus.amba3.ahblite._ -import spinal.tester.{SpinalTesterCocotbBase, SpinalTesterGhdlBase} +import spinal.tester.{SpinalTesterCocotbBase, SpinalTesterGhdlBase, SpinalSimFunSuite} import org.scalatest.funsuite.AnyFunSuite object MemTester extends App{ @@ -220,4 +221,185 @@ class SpinalSimRomTester extends AnyFunSuite { } } } -} \ No newline at end of file +} + +class SpinalSimOneEntryRamTester extends SpinalSimFunSuite{ + test("general") { + SimConfig.doSim(new Component { + val mem = Mem(Bits(8 bits), 1).randBoot() + val writePort = slave(mem.writePort) + val readSyncPort = slave(mem.readSyncPort) + val readAsyncPort = new Area { + val address = in(UInt(0 bits)) + val data = out(mem(address)) + } + }) { dut => + dut.clockDomain.forkStimulus(10) + + dut.writePort.valid #= true + dut.writePort.data #= 42 + dut.clockDomain.waitSampling() + dut.writePort.valid #= false + dut.readSyncPort.cmd.valid #= true + dut.clockDomain.waitSampling() + + var readSyncModel = 42 + var ramModel = 42 + for (repeat <- 0 to 100) { + dut.writePort.randomize() + dut.readSyncPort.cmd.randomize() + dut.readAsyncPort.address.randomize() + + dut.clockDomain.waitSampling() + assert(dut.readSyncPort.rsp.toInt == readSyncModel) + assert(dut.readAsyncPort.data.toInt == ramModel) + if (dut.readSyncPort.cmd.valid.toBoolean) { + readSyncModel = ramModel + } + if (dut.writePort.valid.toBoolean) { + ramModel = dut.writePort.data.toInt + } + sleep(1) + assert(dut.readAsyncPort.data.toInt == ramModel) + } + } + } + + test("rwPort") { + SimConfig.doSim(new Component { + val mem = Mem(Bits(8 bits), 1).randBoot() + val readWrite = new Area { + val address = U"" + val writeData = in Bits (8 bits) + val enable, write = in Bool() + val readData = out(mem.readWriteSync(address, writeData, enable, write)) + } + val readSyncPort = slave(mem.readSyncPort) + val readAsyncPort = new Area { + val address = in(UInt(0 bits)) + val data = out(mem(address)) + } + }) { dut => + dut.clockDomain.forkStimulus(10) + + dut.readWrite.enable #= true + dut.readWrite.write #= true + dut.readWrite.writeData #= 42 + dut.clockDomain.waitSampling() + dut.readWrite.write #= true + dut.readSyncPort.cmd.valid #= true + dut.clockDomain.waitSampling() + + var readWriteModel = 42 + var readSyncModel = 42 + var ramModel = 42 + for (repeat <- 0 until 100) { + dut.readWrite.enable.randomize() + dut.readWrite.write.randomize() + dut.readWrite.writeData.randomize() + dut.readSyncPort.cmd.randomize() + dut.readAsyncPort.address.randomize() + + dut.clockDomain.waitSampling() + assert(dut.readSyncPort.rsp.toInt == readSyncModel) + assert(dut.readAsyncPort.data.toInt == ramModel) + if (dut.readSyncPort.cmd.valid.toBoolean) { + readSyncModel = ramModel + } + if (dut.readWrite.enable.toBoolean && !dut.readWrite.write.toBoolean) { + readWriteModel = ramModel + } + if (dut.readWrite.enable.toBoolean && dut.readWrite.write.toBoolean) { + ramModel = dut.readWrite.writeData.toInt + } + sleep(1) + assert(dut.readAsyncPort.data.toInt == ramModel) + } + } + } + + test("rom") { + SimConfig.doSim(new Component { + val mem = Mem(Bits(8 bits), 1) init (Seq(B"xAA")) + val readSyncPort = slave(mem.readSyncPort) + val readAsyncPort = new Area { + val address = in(UInt(0 bits)) + val data = out(mem(address)) + } + }) { dut => + dut.clockDomain.forkStimulus(10) + + dut.clockDomain.waitSampling() + dut.readSyncPort.cmd.valid #= true + dut.clockDomain.waitSampling() + + var readSyncModel = 0xAA + var ramModel = 0xAA + for (repeat <- 0 until 100) { + dut.readSyncPort.cmd.randomize() + dut.readAsyncPort.address.randomize() + + dut.clockDomain.waitSampling() + assert(dut.readSyncPort.rsp.toInt == readSyncModel) + assert(dut.readAsyncPort.data.toInt == ramModel) + if (dut.readSyncPort.cmd.valid.toBoolean) { + readSyncModel = ramModel + } + sleep(1) + assert(dut.readAsyncPort.data.toInt == ramModel) + } + } + } +} + + +class SpinalSimRamTester extends AnyFunSuite { + test("general") { + SimConfig.withConfig(SpinalConfig(device = Device.XILINX)).compile(new Component { + val ram = Mem(Bits(32 bits), 256) + + val wrEnable = in Bool() + val wrAddress = in UInt(8 bits) + val wrData = in Bits(32 bits) + val wrMask = in Bits(4 bits) + + ram.write(wrAddress, wrData, wrEnable, wrMask) + + val rdAddress = in UInt(8 bits) + val rdData = out Bits(32 bits) + rdData := ram.readAsync(rdAddress) + }).doSim{dut => + dut.clockDomain.forkStimulus(10) + + + def wr(address : Int, data : Long, mask : Long): Unit ={ + dut.clockDomain.waitSampling() + dut.wrEnable #= true + dut.wrAddress #= address + dut.wrData #= data + dut.wrMask #= mask + dut.clockDomain.waitSampling() + } + + wr(42, 0x00112233l, 0x1) + wr(43, 0x44556677l, 0x3) + wr(44, 0x8899AABBl, 0xF) + wr(42, 0xFFFFFFFFl, 0xE) + wr(43, 0xFFFFFFFFl, 0xC) + wr(44, 0xFFFFFFFFl, 0x0) + + dut.clockDomain.waitSampling() + dut.clockDomain.waitSampling() + + def rdCheck(address : Int, data : Long, mask : Long): Unit ={ + dut.rdAddress #= address + sleep(1) + assert((dut.rdData.toLong & mask) == (data & mask)) + } + + rdCheck(42, 0x00112233l, 0x000000FF) + rdCheck(43, 0x44556677l, 0x0000FFFF) + rdCheck(44, 0x8899AABBl, 0xFFFFFFFF) + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimOneEntryRamTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimOneEntryRamTester.scala deleted file mode 100644 index 17c429a138..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimOneEntryRamTester.scala +++ /dev/null @@ -1,187 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core.sim._ -import spinal.core._ -import spinal.lib._ - -class SpinalSimOneEntryRamTester extends SpinalSimFunSuite{ - test("general") { - SimConfig.doSim(new Component { - val mem = Mem(Bits(8 bits), 1).randBoot() - val writePort = slave(mem.writePort) - val readSyncPort = slave(mem.readSyncPort) - val readAsyncPort = new Area { - val address = in(UInt(0 bits)) - val data = out(mem(address)) - } - }) { dut => - dut.clockDomain.forkStimulus(10) - - dut.writePort.valid #= true - dut.writePort.data #= 42 - dut.clockDomain.waitSampling() - dut.writePort.valid #= false - dut.readSyncPort.cmd.valid #= true - dut.clockDomain.waitSampling() - - var readSyncModel = 42 - var ramModel = 42 - for (repeat <- 0 to 100) { - dut.writePort.randomize() - dut.readSyncPort.cmd.randomize() - dut.readAsyncPort.address.randomize() - - dut.clockDomain.waitSampling() - assert(dut.readSyncPort.rsp.toInt == readSyncModel) - assert(dut.readAsyncPort.data.toInt == ramModel) - if (dut.readSyncPort.cmd.valid.toBoolean) { - readSyncModel = ramModel - } - if (dut.writePort.valid.toBoolean) { - ramModel = dut.writePort.data.toInt - } - sleep(1) - assert(dut.readAsyncPort.data.toInt == ramModel) - } - } - } - - test("rwPort") { - SimConfig.doSim(new Component { - val mem = Mem(Bits(8 bits), 1).randBoot() - val readWrite = new Area { - val address = U"" - val writeData = in Bits (8 bits) - val enable, write = in Bool() - val readData = out(mem.readWriteSync(address, writeData, enable, write)) - } - val readSyncPort = slave(mem.readSyncPort) - val readAsyncPort = new Area { - val address = in(UInt(0 bits)) - val data = out(mem(address)) - } - }) { dut => - dut.clockDomain.forkStimulus(10) - - dut.readWrite.enable #= true - dut.readWrite.write #= true - dut.readWrite.writeData #= 42 - dut.clockDomain.waitSampling() - dut.readWrite.write #= true - dut.readSyncPort.cmd.valid #= true - dut.clockDomain.waitSampling() - - var readWriteModel = 42 - var readSyncModel = 42 - var ramModel = 42 - for (repeat <- 0 until 100) { - dut.readWrite.enable.randomize() - dut.readWrite.write.randomize() - dut.readWrite.writeData.randomize() - dut.readSyncPort.cmd.randomize() - dut.readAsyncPort.address.randomize() - - dut.clockDomain.waitSampling() - assert(dut.readSyncPort.rsp.toInt == readSyncModel) - assert(dut.readAsyncPort.data.toInt == ramModel) - if (dut.readSyncPort.cmd.valid.toBoolean) { - readSyncModel = ramModel - } - if (dut.readWrite.enable.toBoolean && !dut.readWrite.write.toBoolean) { - readWriteModel = ramModel - } - if (dut.readWrite.enable.toBoolean && dut.readWrite.write.toBoolean) { - ramModel = dut.readWrite.writeData.toInt - } - sleep(1) - assert(dut.readAsyncPort.data.toInt == ramModel) - } - } - } - - test("rom") { - SimConfig.doSim(new Component { - val mem = Mem(Bits(8 bits), 1) init (Seq(B"xAA")) - val readSyncPort = slave(mem.readSyncPort) - val readAsyncPort = new Area { - val address = in(UInt(0 bits)) - val data = out(mem(address)) - } - }) { dut => - dut.clockDomain.forkStimulus(10) - - dut.clockDomain.waitSampling() - dut.readSyncPort.cmd.valid #= true - dut.clockDomain.waitSampling() - - var readSyncModel = 0xAA - var ramModel = 0xAA - for (repeat <- 0 until 100) { - dut.readSyncPort.cmd.randomize() - dut.readAsyncPort.address.randomize() - - dut.clockDomain.waitSampling() - assert(dut.readSyncPort.rsp.toInt == readSyncModel) - assert(dut.readAsyncPort.data.toInt == ramModel) - if (dut.readSyncPort.cmd.valid.toBoolean) { - readSyncModel = ramModel - } - sleep(1) - assert(dut.readAsyncPort.data.toInt == ramModel) - } - } - } -} - - -class SpinalSimRamTester extends AnyFunSuite { - test("general") { - SimConfig.withConfig(SpinalConfig(device = Device.XILINX)).compile(new Component { - val ram = Mem(Bits(32 bits), 256) - - val wrEnable = in Bool() - val wrAddress = in UInt(8 bits) - val wrData = in Bits(32 bits) - val wrMask = in Bits(4 bits) - - ram.write(wrAddress, wrData, wrEnable, wrMask) - - val rdAddress = in UInt(8 bits) - val rdData = out Bits(32 bits) - rdData := ram.readAsync(rdAddress) - }).doSim{dut => - dut.clockDomain.forkStimulus(10) - - - def wr(address : Int, data : Long, mask : Long): Unit ={ - dut.clockDomain.waitSampling() - dut.wrEnable #= true - dut.wrAddress #= address - dut.wrData #= data - dut.wrMask #= mask - dut.clockDomain.waitSampling() - } - - wr(42, 0x00112233l, 0x1) - wr(43, 0x44556677l, 0x3) - wr(44, 0x8899AABBl, 0xF) - wr(42, 0xFFFFFFFFl, 0xE) - wr(43, 0xFFFFFFFFl, 0xC) - wr(44, 0xFFFFFFFFl, 0x0) - - dut.clockDomain.waitSampling() - dut.clockDomain.waitSampling() - - def rdCheck(address : Int, data : Long, mask : Long): Unit ={ - dut.rdAddress #= address - sleep(1) - assert((dut.rdData.toLong & mask) == (data & mask)) - } - - rdCheck(42, 0x00112233l, 0x000000FF) - rdCheck(43, 0x44556677l, 0x0000FFFF) - rdCheck(44, 0x8899AABBl, 0xFFFFFFFF) - } - } -} From 7da9e5ebc10629fad765d81a20f93309547da5d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:25:16 +0100 Subject: [PATCH 082/120] refactor: move SpinalSimPackedBundleTester --- .../src/test/scala/spinal/lib/PackedBundle.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimPackedBundleTester.scala => lib/src/test/scala/spinal/lib/PackedBundle.scala (98%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimPackedBundleTester.scala b/lib/src/test/scala/spinal/lib/PackedBundle.scala similarity index 98% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimPackedBundleTester.scala rename to lib/src/test/scala/spinal/lib/PackedBundle.scala index 1897f81292..5ff8fc6acf 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimPackedBundleTester.scala +++ b/lib/src/test/scala/spinal/lib/PackedBundle.scala @@ -1,8 +1,8 @@ -package spinal.tester.scalatest +package spinal.lib import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ -import spinal.lib._ import spinal.core.sim._ class SpinalSimPackedBundleTester extends AnyFunSuite { From 8fbd62afbefd146a631111fd33b2ba1708f5b5b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:30:02 +0100 Subject: [PATCH 083/120] refactor: move SpinalSimBmbAlignerTester --- .../test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbAlignerTester.scala => lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbAlignerTester.scala b/lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbAlignerTester.scala rename to lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala index 155f279d3a..a4469fb665 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbAlignerTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala @@ -1,10 +1,9 @@ -package spinal.tester.scalatest - +package spinal.lib.bus.bmb import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import spinal.core.sim.SimConfig -import spinal.lib.bus.bmb.{BmbAligner, BmbDownSizerBridge, BmbParameter} import spinal.lib.bus.bmb.sim.BmbBridgeTester class SpinalSimBmbAlignerTester extends AnyFunSuite { From f45392de322ce48feb5087f7d88c2b896786f3ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:32:44 +0100 Subject: [PATCH 084/120] refactor: move SpinalSimBmbDecoderOutOfOrderTester --- .../scala/spinal/lib/bus/bmb/BmbDecoder.scala | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbDecoderOutOfOrderTester.scala => lib/src/test/scala/spinal/lib/bus/bmb/BmbDecoder.scala (94%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbDecoderOutOfOrderTester.scala b/lib/src/test/scala/spinal/lib/bus/bmb/BmbDecoder.scala similarity index 94% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbDecoderOutOfOrderTester.scala rename to lib/src/test/scala/spinal/lib/bus/bmb/BmbDecoder.scala index 606c30b3cb..488d38b49a 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbDecoderOutOfOrderTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/bmb/BmbDecoder.scala @@ -1,21 +1,14 @@ -package spinal.tester.scalatest +package spinal.lib.bus.bmb import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import spinal.core.sim._ -import spinal.lib.{StreamFifoMultiChannelSharedSpace, master, slave} -import spinal.lib.bus.bmb.sim.{BmbInterconnectTester, BmbMasterAgent, BmbMemoryAgent, BmbMemoryTester} -import spinal.lib.bus.bmb.{Bmb, BmbAccessParameter, BmbDecoder, BmbDecoderOutOfOrder, BmbDecoderPerSource, BmbParameter, BmbSourceParameter} +import spinal.lib.{master, slave} +import spinal.lib.bus.bmb.sim.BmbInterconnectTester import spinal.lib.bus.misc.{DefaultMapping, SizeMapping} import spinal.lib.eda.bench.{Bench, Rtl, XilinxStdTargets} -import scala.collection.mutable -import scala.collection.mutable.ArrayBuffer -import scala.util.Random - - - - class SpinalSimBmbDecoderOutOfOrderTester extends AnyFunSuite { def doIt(outputCount : Int, sourceCount : Int, withDefault : Boolean): Unit ={ val p = BmbParameter( From 0372648d41c1ecc355eeb18f0de798c8e8f61c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:35:03 +0100 Subject: [PATCH 085/120] refactor: move SpinalSimBmbDownSizerBridgeTester --- .../spinal/lib/bus/bmb/BmbDownSizerBridge.scala | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbDownSizerBridgeTester.scala => lib/src/test/scala/spinal/lib/bus/bmb/BmbDownSizerBridge.scala (83%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbDownSizerBridgeTester.scala b/lib/src/test/scala/spinal/lib/bus/bmb/BmbDownSizerBridge.scala similarity index 83% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbDownSizerBridgeTester.scala rename to lib/src/test/scala/spinal/lib/bus/bmb/BmbDownSizerBridge.scala index 197e4b8333..e6fc7866f1 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbDownSizerBridgeTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/bmb/BmbDownSizerBridge.scala @@ -1,16 +1,9 @@ -package spinal.tester.scalatest +package spinal.lib.bus.bmb -import org.scalatest.funsuite.AnyFunSuite -import spinal.core.sim._ -import spinal.lib.bus.amba3.apb.Apb3Config -import spinal.lib.bus.amba3.apb.sim.Apb3Monitor -import spinal.lib.bus.bmb.{BmbDownSizerBridge, BmbParameter, BmbToApb3Bridge} -import spinal.lib.bus.bmb.sim.{BmbBridgeTester, BmbMasterAgent, BmbMemoryAgent, BmbRegionAllocator} -import spinal.lib.bus.misc.SizeMapping -import spinal.lib.sim._ +import spinal.tester.SpinalSimFunSuite -import scala.collection.mutable -import scala.util.Random +import spinal.core.sim._ +import spinal.lib.bus.bmb.sim.BmbBridgeTester class SpinalSimBmbDownSizerBridgeTester extends SpinalSimFunSuite{ test("test1"){ From e137130fbddcda53add2d98dc291a88aa1660923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:37:07 +0100 Subject: [PATCH 086/120] refactor: move SpinalSimBmbExclusiveMonitorTester --- .../scala/spinal/lib/bus/bmb/BmbExclusiveMonitor.scala | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbExclusiveMonitorTester.scala => lib/src/test/scala/spinal/lib/bus/bmb/BmbExclusiveMonitor.scala (92%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbExclusiveMonitorTester.scala b/lib/src/test/scala/spinal/lib/bus/bmb/BmbExclusiveMonitor.scala similarity index 92% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbExclusiveMonitorTester.scala rename to lib/src/test/scala/spinal/lib/bus/bmb/BmbExclusiveMonitor.scala index da0b19f16b..5b7e5b64ee 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbExclusiveMonitorTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/bmb/BmbExclusiveMonitor.scala @@ -1,20 +1,14 @@ -package spinal.tester.scalatest +package spinal.lib.bus.bmb import org.scalatest.funsuite.AnyFunSuite + import spinal.core.sim._ import spinal.lib.Fragment -import spinal.lib.bus.amba3.apb.Apb3Config -import spinal.lib.bus.amba3.apb.sim.Apb3Monitor -import spinal.lib.bus.bmb.{Bmb, BmbAccessParameter, BmbCmd, BmbDownSizerBridge, BmbExclusiveMonitor, BmbInvalidationParameter, BmbParameter, BmbRsp, BmbSourceParameter, BmbToApb3Bridge} -import spinal.lib.bus.bmb.sim.{BmbBridgeTester, BmbMasterAgent, BmbMemoryAgent, BmbRegionAllocator} -import spinal.lib.bus.misc.SizeMapping import spinal.lib.sim._ import scala.collection.mutable import scala.util.Random - - private object IDLE private object READ_CMD private object READ_RSP From 23401809e6dc7d93e3d42162247e374af284d481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:39:18 +0100 Subject: [PATCH 087/120] refactor: move SpinalSimBmbInterconnectGeneratorTester --- .../bus/bmb/BmbInterconnectGenerator.scala | 13 +++- .../spinal/tester/RepeatabilitySuite.scala | 32 +++++++++ .../spinal/tester/GenerationShould.scala | 65 ------------------- .../spinal/tester/RepeatabilitySuite.scala | 41 ++++++++++++ 4 files changed, 83 insertions(+), 68 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbInterconnectGeneratorTester.scala => lib/src/test/scala/spinal/lib/bus/bmb/BmbInterconnectGenerator.scala (97%) create mode 100644 tester/src/main/scala/spinal/tester/RepeatabilitySuite.scala create mode 100644 tester/src/test/scala/spinal/tester/RepeatabilitySuite.scala diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbInterconnectGeneratorTester.scala b/lib/src/test/scala/spinal/lib/bus/bmb/BmbInterconnectGenerator.scala similarity index 97% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbInterconnectGeneratorTester.scala rename to lib/src/test/scala/spinal/lib/bus/bmb/BmbInterconnectGenerator.scala index 3f333e9e2f..8a63c9d698 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbInterconnectGeneratorTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/bmb/BmbInterconnectGenerator.scala @@ -1,14 +1,15 @@ -package spinal.tester.scalatest +package spinal.lib.bus.bmb import org.scalatest.funsuite.AnyFunSuite +import spinal.tester.RepeatabilitySuite + import spinal.core._ import spinal.core.fiber._ import spinal.core.sim._ import spinal.lib._ +import spinal.lib.generator._ import spinal.lib.bus.bmb.sim._ -import spinal.lib.bus.bmb._ import spinal.lib.bus.misc.SizeMapping -import spinal.lib.generator._ import spinal.lib.sim.Phase import spinal.tester.SpinalSimFunSuite @@ -268,3 +269,9 @@ class SpinalSimBmbInterconnectGeneratorTester extends SpinalSimFunSuite { } } } + +class RepeatabilityTester extends RepeatabilitySuite { + test("BmbInterconnectVerilog") { + checkOutputHash(SpinalSimBmbInterconnectGeneratorTester.component) + } +} diff --git a/tester/src/main/scala/spinal/tester/RepeatabilitySuite.scala b/tester/src/main/scala/spinal/tester/RepeatabilitySuite.scala new file mode 100644 index 0000000000..023d86baf1 --- /dev/null +++ b/tester/src/main/scala/spinal/tester/RepeatabilitySuite.scala @@ -0,0 +1,32 @@ +package spinal.tester + +import org.scalatest.funsuite.AnyFunSuite + +import spinal.core._ + +import java.io.File +import org.apache.commons.io.FileUtils + +class RepeatabilitySuite extends AnyFunSuite { + var checkOutputHashCounter = 0 + def checkOutputHash(gen: => Component): Unit = { + checkOutputHashCounter = checkOutputHashCounter + 1 + var ref = "" + for (i <- 0 until 8) { + val report = + SpinalConfig(defaultClockDomainFrequency = FixedFrequency(50 MHz)) + .generateVerilog( + gen.setDefinitionName(s"checkOutputHash_${checkOutputHashCounter}") + ) + FileUtils.copyFile( + new File(report.generatedSourcesPaths.head), + new File(report.generatedSourcesPaths.head + "_" + i + ".v") + ) + + import sys.process._ + val hash = s"md5sum ${report.generatedSourcesPaths.head}".!! + if (i == 0) ref = hash + else assert(ref == hash) + } + } +} diff --git a/tester/src/test/scala/spinal/tester/GenerationShould.scala b/tester/src/test/scala/spinal/tester/GenerationShould.scala index 0b021cf6fa..c8490390df 100644 --- a/tester/src/test/scala/spinal/tester/GenerationShould.scala +++ b/tester/src/test/scala/spinal/tester/GenerationShould.scala @@ -1,16 +1,8 @@ package spinal.tester -import java.io.File -import org.apache.commons.io.FileUtils - import org.scalatest.funsuite.AnyFunSuite import spinal.core._ -import spinal.core.internals.GraphUtils - -import spinal.lib.com.i2c._ -import spinal.lib.com.uart.{UartCtrl, UartCtrlGenerics} -import spinal.lib.soc.pinsec.{Pinsec, PinsecConfig} class GenerationShouldTester extends AnyFunSuite { test("BlackBoxInputUnconnected") { @@ -459,63 +451,6 @@ class GenerationShouldTester extends AnyFunSuite { } -class RepeatabilityTester extends AnyFunSuite { - var checkOutputHashCounter = 0 - def checkOutputHash(gen: => Component): Unit = { - checkOutputHashCounter = checkOutputHashCounter + 1 - var ref = "" - for (i <- 0 until 8) { - val report = - SpinalConfig(defaultClockDomainFrequency = FixedFrequency(50 MHz)) - .generateVerilog( - gen.setDefinitionName(s"checkOutputHash_${checkOutputHashCounter}") - ) - FileUtils.copyFile( - new File(report.generatedSourcesPaths.head), - new File(report.generatedSourcesPaths.head + "_" + i + ".v") - ) - - import sys.process._ - val hash = s"md5sum ${report.generatedSourcesPaths.head}".!! - if (i == 0) ref = hash - else assert(ref == hash) - } - } - def configI2C = I2cSlaveMemoryMappedGenerics( - ctrlGenerics = I2cSlaveGenerics(), - addressFilterCount = 0, - masterGenerics = I2cMasterMemoryMappedGenerics(timerWidth = 32) - ) - - test("Apb3I2cCtrlGraph") { - val dut = SpinalConfig(defaultClockDomainFrequency = FixedFrequency(50 MHz)) - .generateVerilog(new Apb3I2cCtrl(configI2C)) - .toplevel - assert(GraphUtils.countNames(dut) == 221) - } - - test("UartGraph") { - val dut = SpinalVerilog(new UartCtrl(UartCtrlGenerics())).toplevel - assert(GraphUtils.countNames(dut) == 94) - } - - test("Apb3I2cCtrlVerilog") { - checkOutputHash(new Apb3I2cCtrl(configI2C)) - } - - test("UartVerilog") { - checkOutputHash(new UartCtrl(UartCtrlGenerics())) - } - - test("PinsecVerilog") { - checkOutputHash(new Pinsec(PinsecConfig.default)) - } - - test("BmbInterconnectVerilog") { - checkOutputHash(scalatest.SpinalSimBmbInterconnectGeneratorTester.component) - } -} - class NameingTester extends AnyFunSuite { test("reflectionNaming") { val t = SpinalVhdl(new Component { diff --git a/tester/src/test/scala/spinal/tester/RepeatabilitySuite.scala b/tester/src/test/scala/spinal/tester/RepeatabilitySuite.scala new file mode 100644 index 0000000000..37f9a95fe1 --- /dev/null +++ b/tester/src/test/scala/spinal/tester/RepeatabilitySuite.scala @@ -0,0 +1,41 @@ +package spinal.tester + +import spinal.core._ +import spinal.core.sim._ +import spinal.core.internals.GraphUtils + +import spinal.lib.com.i2c._ +import spinal.lib.com.uart.{UartCtrl, UartCtrlGenerics} +import spinal.lib.soc.pinsec.{Pinsec, PinsecConfig} + +class RepeatabilityTester extends RepeatabilitySuite { + def configI2C = I2cSlaveMemoryMappedGenerics( + ctrlGenerics = I2cSlaveGenerics(), + addressFilterCount = 0, + masterGenerics = I2cMasterMemoryMappedGenerics(timerWidth = 32) + ) + + test("Apb3I2cCtrlGraph") { + val dut = SpinalConfig(defaultClockDomainFrequency = FixedFrequency(50 MHz)) + .generateVerilog(new Apb3I2cCtrl(configI2C)) + .toplevel + assert(GraphUtils.countNames(dut) == 221) + } + + test("UartGraph") { + val dut = SpinalVerilog(new UartCtrl(UartCtrlGenerics())).toplevel + assert(GraphUtils.countNames(dut) == 94) + } + + test("Apb3I2cCtrlVerilog") { + checkOutputHash(new Apb3I2cCtrl(configI2C)) + } + + test("UartVerilog") { + checkOutputHash(new UartCtrl(UartCtrlGenerics())) + } + + test("PinsecVerilog") { + checkOutputHash(new Pinsec(PinsecConfig.default)) + } +} From 5876f60ebd4b933c0a1a799ec76b7b50c2c2ab58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:40:38 +0100 Subject: [PATCH 088/120] refactor: move SpinalSimBmbLengthFixerTester --- .../lib/bus/bmb/BmbSpecificBridges.scala | 88 ++++++++++++++++++ .../SpinalSimBmbLengthFixerTester.scala | 93 ------------------- 2 files changed, 88 insertions(+), 93 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbLengthFixerTester.scala diff --git a/lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala b/lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala index a4469fb665..df78b8ab25 100644 --- a/lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala +++ b/lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala @@ -1,6 +1,7 @@ package spinal.lib.bus.bmb import org.scalatest.funsuite.AnyFunSuite +import spinal.tester.SpinalSimFunSuite import spinal.core._ import spinal.core.sim.SimConfig @@ -118,3 +119,90 @@ class SpinalSimBmbAlignerTester extends AnyFunSuite { } } } + +class SpinalSimBmbLengthFixerTester extends SpinalSimFunSuite { + test("bypass") { + SimConfig.compile { + val c = BmbLengthFixer( + ip = BmbParameter( + addressWidth = 16, + dataWidth = 32, + lengthWidth = 6, + sourceWidth = 4, + contextWidth = 3, + alignmentMin = 2, + canRead = true, + canWrite = true, + alignment = BmbParameter.BurstAlignement.WORD + ), + fixedWidth = 2 + ) + c + }.doSimUntilVoid("test") { dut => + new BmbBridgeTester( + master = dut.io.input, + masterCd = dut.clockDomain, + slave = dut.io.output, + slaveCd = dut.clockDomain, + alignmentMinWidth = dut.ip.access.alignmentMin + ) + } + } + + test("3") { + SimConfig.compile { + val c = BmbLengthFixer( + ip = BmbParameter( + addressWidth = 16, + dataWidth = 32, + lengthWidth = 6, + sourceWidth = 4, + contextWidth = 3, + alignmentMin = 3, + canRead = true, + canWrite = true, + alignment = BmbParameter.BurstAlignement.WORD + ), + fixedWidth = 3 + ) + c + }.doSimUntilVoid("test") { dut => + new BmbBridgeTester( + master = dut.io.input, + masterCd = dut.clockDomain, + slave = dut.io.output, + slaveCd = dut.clockDomain, + alignmentMinWidth = dut.ip.access.alignmentMin + ) + } + } + + test("4") { + SimConfig.compile { + val c = BmbLengthFixer( + ip = BmbParameter( + addressWidth = 16, + dataWidth = 32, + lengthWidth = 6, + sourceWidth = 4, + contextWidth = 3, + alignmentMin = 4, + canRead = true, + canWrite = true, + alignment = BmbParameter.BurstAlignement.WORD + ), + fixedWidth = 4 + ) + c + }.doSimUntilVoid("test") { dut => + new BmbBridgeTester( + master = dut.io.input, + masterCd = dut.clockDomain, + slave = dut.io.output, + slaveCd = dut.clockDomain, + alignmentMinWidth = dut.ip.access.alignmentMin + ) + } + } + +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbLengthFixerTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbLengthFixerTester.scala deleted file mode 100644 index b5dd6afb60..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbLengthFixerTester.scala +++ /dev/null @@ -1,93 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.lib.bus.bmb.sim.BmbBridgeTester -import spinal.lib.bus.bmb.{BmbAligner, BmbLengthFixer, BmbParameter} - -class SpinalSimBmbLengthFixerTester extends SpinalSimFunSuite { - test("bypass") { - SimConfig.compile { - val c = BmbLengthFixer( - ip = BmbParameter( - addressWidth = 16, - dataWidth = 32, - lengthWidth = 6, - sourceWidth = 4, - contextWidth = 3, - alignmentMin = 2, - canRead = true, - canWrite = true, - alignment = BmbParameter.BurstAlignement.WORD - ), - fixedWidth = 2 - ) - c - }.doSimUntilVoid("test") { dut => - new BmbBridgeTester( - master = dut.io.input, - masterCd = dut.clockDomain, - slave = dut.io.output, - slaveCd = dut.clockDomain, - alignmentMinWidth = dut.ip.access.alignmentMin - ) - } - } - - test("3") { - SimConfig.compile { - val c = BmbLengthFixer( - ip = BmbParameter( - addressWidth = 16, - dataWidth = 32, - lengthWidth = 6, - sourceWidth = 4, - contextWidth = 3, - alignmentMin = 3, - canRead = true, - canWrite = true, - alignment = BmbParameter.BurstAlignement.WORD - ), - fixedWidth = 3 - ) - c - }.doSimUntilVoid("test") { dut => - new BmbBridgeTester( - master = dut.io.input, - masterCd = dut.clockDomain, - slave = dut.io.output, - slaveCd = dut.clockDomain, - alignmentMinWidth = dut.ip.access.alignmentMin - ) - } - } - - test("4") { - SimConfig.compile { - val c = BmbLengthFixer( - ip = BmbParameter( - addressWidth = 16, - dataWidth = 32, - lengthWidth = 6, - sourceWidth = 4, - contextWidth = 3, - alignmentMin = 4, - canRead = true, - canWrite = true, - alignment = BmbParameter.BurstAlignement.WORD - ), - fixedWidth = 4 - ) - c - }.doSimUntilVoid("test") { dut => - new BmbBridgeTester( - master = dut.io.input, - masterCd = dut.clockDomain, - slave = dut.io.output, - slaveCd = dut.clockDomain, - alignmentMinWidth = dut.ip.access.alignmentMin - ) - } - } - -} From dab5ce5fadd139587af4ae6ddbad6f1842d6c24d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:42:11 +0100 Subject: [PATCH 089/120] refactor: move SpinalSimBmbLengthSpliterTester --- .../lib/bus/bmb/BmbSpecificBridges.scala | 89 +++++++++++++++++ .../SpinalSimBmbLengthSpliterTester.scala | 95 ------------------- 2 files changed, 89 insertions(+), 95 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbLengthSpliterTester.scala diff --git a/lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala b/lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala index df78b8ab25..9e88598568 100644 --- a/lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala +++ b/lib/src/test/scala/spinal/lib/bus/bmb/BmbSpecificBridges.scala @@ -206,3 +206,92 @@ class SpinalSimBmbLengthFixerTester extends SpinalSimFunSuite { } } + +class SpinalSimBmbLengthSpliterTester extends AnyFunSuite { + for(w <- List(false, true); r <- List(false, true); if w || r) { + val header = "_" + (if (w) "w" else "") + (if (r) "r" else "") + test("bypass" + header) { + SimConfig.compile { + val c = BmbAlignedSpliter( + ip = BmbAccessParameter( + addressWidth = 16, + dataWidth = 32 + ).addSources(16, BmbSourceParameter( + lengthWidth = 6, + contextWidth = 3, + alignmentMin = 0, + canRead = r, + canWrite = w, + alignment = BmbParameter.BurstAlignement.WORD + )).toBmbParameter(), + lengthMax = 4 + ) + c + }.doSimUntilVoid("test") { dut => + new BmbBridgeTester( + master = dut.io.input, + masterCd = dut.clockDomain, + slave = dut.io.output, + slaveCd = dut.clockDomain, + alignmentMinWidth = dut.ip.access.alignmentMin + ) + } + } + + test("8" + header) { + SimConfig.withWave.compile { + val c = BmbAlignedSpliter( + ip = BmbAccessParameter( + addressWidth = 16, + dataWidth = 32 + ).addSources(16, BmbSourceParameter( + lengthWidth = 6, + contextWidth = 8, + alignmentMin = 0, + canRead = r, + canWrite = w, + alignment = BmbParameter.BurstAlignement.WORD + )).toBmbParameter(), + lengthMax = 8 + ) + c + }.doSimUntilVoid("test", 42) { dut => + new BmbBridgeTester( + master = dut.io.input, + masterCd = dut.clockDomain, + slave = dut.io.output, + slaveCd = dut.clockDomain, + alignmentMinWidth = dut.ip.access.alignmentMin + ) + } + } + + test("16" + header) { + SimConfig.compile { + val c = BmbAlignedSpliter( + ip = BmbAccessParameter( + addressWidth = 16, + dataWidth = 32 + ).addSources(16, BmbSourceParameter( + lengthWidth = 6, + contextWidth = 8, + alignmentMin = 0, + canRead = r, + canWrite = w, + alignment = BmbParameter.BurstAlignement.WORD + )).toBmbParameter(), + lengthMax = 16 + ) + c + }.doSimUntilVoid("test") { dut => + new BmbBridgeTester( + master = dut.io.input, + masterCd = dut.clockDomain, + slave = dut.io.output, + slaveCd = dut.clockDomain, + alignmentMinWidth = dut.ip.access.alignmentMin + ) + } + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbLengthSpliterTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbLengthSpliterTester.scala deleted file mode 100644 index 2653b12875..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbLengthSpliterTester.scala +++ /dev/null @@ -1,95 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core.sim.SimConfig -import spinal.lib.bus.bmb.sim.BmbBridgeTester -import spinal.lib.bus.bmb.{BmbAccessParameter, BmbAlignedSpliter, BmbParameter, BmbSourceParameter} - -class SpinalSimBmbLengthSpliterTester extends AnyFunSuite { - for(w <- List(false, true); r <- List(false, true); if w || r) { - val header = "_" + (if (w) "w" else "") + (if (r) "r" else "") - test("bypass" + header) { - SimConfig.compile { - val c = BmbAlignedSpliter( - ip = BmbAccessParameter( - addressWidth = 16, - dataWidth = 32 - ).addSources(16, BmbSourceParameter( - lengthWidth = 6, - contextWidth = 3, - alignmentMin = 0, - canRead = r, - canWrite = w, - alignment = BmbParameter.BurstAlignement.WORD - )).toBmbParameter(), - lengthMax = 4 - ) - c - }.doSimUntilVoid("test") { dut => - new BmbBridgeTester( - master = dut.io.input, - masterCd = dut.clockDomain, - slave = dut.io.output, - slaveCd = dut.clockDomain, - alignmentMinWidth = dut.ip.access.alignmentMin - ) - } - } - - test("8" + header) { - SimConfig.withWave.compile { - val c = BmbAlignedSpliter( - ip = BmbAccessParameter( - addressWidth = 16, - dataWidth = 32 - ).addSources(16, BmbSourceParameter( - lengthWidth = 6, - contextWidth = 8, - alignmentMin = 0, - canRead = r, - canWrite = w, - alignment = BmbParameter.BurstAlignement.WORD - )).toBmbParameter(), - lengthMax = 8 - ) - c - }.doSimUntilVoid("test", 42) { dut => - new BmbBridgeTester( - master = dut.io.input, - masterCd = dut.clockDomain, - slave = dut.io.output, - slaveCd = dut.clockDomain, - alignmentMinWidth = dut.ip.access.alignmentMin - ) - } - } - - test("16" + header) { - SimConfig.compile { - val c = BmbAlignedSpliter( - ip = BmbAccessParameter( - addressWidth = 16, - dataWidth = 32 - ).addSources(16, BmbSourceParameter( - lengthWidth = 6, - contextWidth = 8, - alignmentMin = 0, - canRead = r, - canWrite = w, - alignment = BmbParameter.BurstAlignement.WORD - )).toBmbParameter(), - lengthMax = 16 - ) - c - }.doSimUntilVoid("test") { dut => - new BmbBridgeTester( - master = dut.io.input, - masterCd = dut.clockDomain, - slave = dut.io.output, - slaveCd = dut.clockDomain, - alignmentMinWidth = dut.ip.access.alignmentMin - ) - } - } - } -} From cdf3221ef54fd70eb0bc9ebdedec3ebf3b95ffc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:46:10 +0100 Subject: [PATCH 090/120] refactor: move SpinalSimBmbOnChipRamTester --- .../scala/spinal/lib/bus/bmb/BmbOnChipRam.scala | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbOnChipRamTester.scala => lib/src/test/scala/spinal/lib/bus/bmb/BmbOnChipRam.scala (74%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbOnChipRamTester.scala b/lib/src/test/scala/spinal/lib/bus/bmb/BmbOnChipRam.scala similarity index 74% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbOnChipRamTester.scala rename to lib/src/test/scala/spinal/lib/bus/bmb/BmbOnChipRam.scala index 4bf5500971..095a4d413c 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbOnChipRamTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/bmb/BmbOnChipRam.scala @@ -1,19 +1,12 @@ -package spinal.tester.scalatest +package spinal.lib.bus.bmb + +import spinal.tester.SpinalSimFunSuite -import org.scalatest.funsuite.AnyFunSuite -import spinal.core.sim._ -import spinal.lib.sim._ import spinal.core._ -import spinal.lib._ -import spinal.lib.bus.bmb.{Bmb, BmbOnChipRam, BmbParameter} -import spinal.lib.bus.bmb.sim.{BmbMasterAgent, BmbMemoryAgent, BmbMemoryTester, BmbRegionAllocator} -import spinal.lib.bus.misc.SizeMapping +import spinal.lib.bus.bmb.sim.BmbMemoryTester import scala.util.Random - - - class SpinalSimBmbOnChipRamTester extends SpinalSimFunSuite { test("test1") { val memInit = new Array[Byte](64 * 1024) From be3dcb022b47a734b4fdb9cfc893ef8059d9805d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:48:56 +0100 Subject: [PATCH 091/120] refactor: move SpinalSimBmbToApb3BridgeTester --- .../test/scala/spinal/lib/bus/bmb/BmbToApb3Bridge.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbToApb3BridgeTester.scala => lib/src/test/scala/spinal/lib/bus/bmb/BmbToApb3Bridge.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbToApb3BridgeTester.scala b/lib/src/test/scala/spinal/lib/bus/bmb/BmbToApb3Bridge.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbToApb3BridgeTester.scala rename to lib/src/test/scala/spinal/lib/bus/bmb/BmbToApb3Bridge.scala index 7d8ce94109..2a93bef949 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbToApb3BridgeTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/bmb/BmbToApb3Bridge.scala @@ -1,11 +1,10 @@ -package spinal.tester.scalatest +package spinal.lib.bus.bmb + +import spinal.tester.SpinalSimFunSuite -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ import spinal.core.sim._ import spinal.lib.bus.amba3.apb.Apb3Config import spinal.lib.bus.amba3.apb.sim.Apb3Monitor -import spinal.lib.bus.bmb.{BmbOnChipRam, BmbToApb3Bridge} import spinal.lib.bus.bmb.sim.{BmbMasterAgent, BmbMemoryAgent, BmbRegionAllocator} import spinal.lib.bus.misc.SizeMapping import spinal.lib.sim._ From 82f5b6759263af0f748e1bcea474bd8a8bcf35f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:50:09 +0100 Subject: [PATCH 092/120] refactor: move SpinalSimBmbUnburstifyTester --- .../src/test/scala/spinal/lib/bus/bmb/BmbUnburstify.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbUnburstifyTester.scala => lib/src/test/scala/spinal/lib/bus/bmb/BmbUnburstify.scala (92%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbUnburstifyTester.scala b/lib/src/test/scala/spinal/lib/bus/bmb/BmbUnburstify.scala similarity index 92% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbUnburstifyTester.scala rename to lib/src/test/scala/spinal/lib/bus/bmb/BmbUnburstify.scala index 54d2a654c2..b52130218d 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbUnburstifyTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/bmb/BmbUnburstify.scala @@ -1,9 +1,9 @@ -package spinal.tester.scalatest +package spinal.lib.bus.bmb import org.scalatest.funsuite.AnyFunSuite + import spinal.core.sim.SimConfig import spinal.lib.bus.bmb.sim.BmbBridgeTester -import spinal.lib.bus.bmb.{BmbAccessParameter, BmbLengthFixer, BmbParameter, BmbSourceParameter, BmbUnburstify} class SpinalSimBmbUnburstifyTester extends AnyFunSuite { test("miaou") { From b6148492a7774a28ec1c6c18e8da8fae99e823cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 18:53:25 +0100 Subject: [PATCH 093/120] refactor: move SpinalSimBmbUpSizerBridgeTester --- .../test/scala/spinal/lib/bus/bmb/BmbUpSizerBridge.scala | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbUpSizerBridgeTester.scala => lib/src/test/scala/spinal/lib/bus/bmb/BmbUpSizerBridge.scala (92%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbUpSizerBridgeTester.scala b/lib/src/test/scala/spinal/lib/bus/bmb/BmbUpSizerBridge.scala similarity index 92% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbUpSizerBridgeTester.scala rename to lib/src/test/scala/spinal/lib/bus/bmb/BmbUpSizerBridge.scala index b8c1aba5ad..f785c6fb4c 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBmbUpSizerBridgeTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/bmb/BmbUpSizerBridge.scala @@ -1,11 +1,8 @@ -package spinal.tester.scalatest +package spinal.lib.bus.bmb -import org.scalatest.funsuite.AnyFunSuite -import spinal.core.sim._ -import spinal.lib.bus.bmb.sim.BmbBridgeTester -import spinal.lib.bus.bmb.{BmbAccessParameter, BmbParameter, BmbSourceParameter, BmbUpSizerBridge} +import spinal.tester.SpinalSimFunSuite -import scala.collection.mutable +import spinal.lib.bus.bmb.sim.BmbBridgeTester class SpinalSimBmbUpSizerBridgeTester extends SpinalSimFunSuite{ for((canRead, canWrite) <- List((true,true),(true, false), (false, true))) { From ee592138465df00367b3f6ece445cd22da878c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 19:18:35 +0100 Subject: [PATCH 094/120] refactor: move SimRandomizeTester --- .../test/scala/spinal/core/sim/package.scala | 54 +++++++++++++++++ .../scalatest/SpinalSimRandomizeTester.scala | 60 ------------------- 2 files changed, 54 insertions(+), 60 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimRandomizeTester.scala diff --git a/core/src/test/scala/spinal/core/sim/package.scala b/core/src/test/scala/spinal/core/sim/package.scala index dc40e3ef8c..23d93448d0 100644 --- a/core/src/test/scala/spinal/core/sim/package.scala +++ b/core/src/test/scala/spinal/core/sim/package.scala @@ -121,3 +121,57 @@ class SpinalSimAccessSubComponents extends AnyFunSuite { } } } + + +object SomeEnum extends SpinalEnum { + val sIdle, sStart, sData, sParity, sStop = newElement() +} + +case class SimRandomizeTester() extends Component { + val io = new Bundle { + val b = in(Bool()) + val ui = in(UInt(4 bit)) + val uil = in(UInt(33 bit)) + val si = in(SInt(4 bit)) + val sil = in(UInt(33 bit)) + val e = in(SomeEnum()) + val uf = in(UFix(peak = 8 exp, resolution = -2 exp)) + val sf = in(SFix(peak = 8 exp, resolution = -2 exp)) + val af = in(AFix.UQ(2 bit, 2 bit)) + val af_out_of_range = in(AFix(8, -4, -2 exp)) + } +} + +class SpinalSimRandomizeTest extends AnyFunSuite { + val dut = SimConfig.compile { SimRandomizeTester() } + + test("randomize returns the value driven next") { + dut.doSim("randomize returns the value driven next") { dut => + for (_ <- 0 to 100) { + val b = dut.io.b.randomize() + val ui = dut.io.ui.randomize() + val uil = dut.io.uil.randomize() + val si = dut.io.si.randomize() + val sil = dut.io.sil.randomize() + val e = dut.io.e.randomize() + val uf = dut.io.uf.randomize() + val sf = dut.io.sf.randomize() + val af = dut.io.af.randomize() + val af_out_of_range = dut.io.af_out_of_range.randomize(inRange = false) + + sleep(10) + + assert(b == dut.io.b.toBoolean) + assert(ui == dut.io.ui.toBigInt) + assert(uil == dut.io.uil.toBigInt) + assert(si == dut.io.si.toBigInt) + assert(sil == dut.io.sil.toBigInt) + assert(e == dut.io.e.toEnum) + assert(uf == dut.io.uf.toBigDecimal) + assert(sf == dut.io.sf.toBigDecimal) + assert(af == dut.io.af.toBigDecimal) + assert(af_out_of_range == dut.io.af_out_of_range.toBigDecimal) + } + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimRandomizeTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimRandomizeTester.scala deleted file mode 100644 index bbd7912f55..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimRandomizeTester.scala +++ /dev/null @@ -1,60 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.core.sim._ - -import scala.language.postfixOps - -object SomeEnum extends SpinalEnum { - val sIdle, sStart, sData, sParity, sStop = newElement() -} - -case class SimRandomizeTester() extends Component { - val io = new Bundle { - val b = in(Bool()) - val ui = in(UInt(4 bit)) - val uil = in(UInt(33 bit)) - val si = in(SInt(4 bit)) - val sil = in(UInt(33 bit)) - val e = in(SomeEnum()) - val uf = in(UFix(peak = 8 exp, resolution = -2 exp)) - val sf = in(SFix(peak = 8 exp, resolution = -2 exp)) - val af = in(AFix.UQ(2 bit, 2 bit)) - val af_out_of_range = in(AFix(8, -4, -2 exp)) - } -} - -class SpinalSimRandomizeTest extends AnyFunSuite { - val dut = SimConfig.compile { SimRandomizeTester() } - - test("randomize returns the value driven next") { - dut.doSim("randomize returns the value driven next") { dut => - for (_ <- 0 to 100) { - val b = dut.io.b.randomize() - val ui = dut.io.ui.randomize() - val uil = dut.io.uil.randomize() - val si = dut.io.si.randomize() - val sil = dut.io.sil.randomize() - val e = dut.io.e.randomize() - val uf = dut.io.uf.randomize() - val sf = dut.io.sf.randomize() - val af = dut.io.af.randomize() - val af_out_of_range = dut.io.af_out_of_range.randomize(inRange = false) - - sleep(10) - - assert(b == dut.io.b.toBoolean) - assert(ui == dut.io.ui.toBigInt) - assert(uil == dut.io.uil.toBigInt) - assert(si == dut.io.si.toBigInt) - assert(sil == dut.io.sil.toBigInt) - assert(e == dut.io.e.toEnum) - assert(uf == dut.io.uf.toBigDecimal) - assert(sf == dut.io.sf.toBigDecimal) - assert(af == dut.io.af.toBigDecimal) - assert(af_out_of_range == dut.io.af_out_of_range.toBigDecimal) - } - } - } -} From 7f9407c0114f877cf22e72be4e163a9815534872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 19:20:41 +0100 Subject: [PATCH 095/120] refactor: move SpinalSimRamAccessTester --- core/src/test/scala/spinal/core/Mem.scala | 138 +++++++++++++++++ .../scalatest/SpinalSimRamAccessTester.scala | 145 ------------------ 2 files changed, 138 insertions(+), 145 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimRamAccessTester.scala diff --git a/core/src/test/scala/spinal/core/Mem.scala b/core/src/test/scala/spinal/core/Mem.scala index 5caeeecd27..14ecca2a1b 100644 --- a/core/src/test/scala/spinal/core/Mem.scala +++ b/core/src/test/scala/spinal/core/Mem.scala @@ -6,6 +6,7 @@ import spinal.lib.bus.amba3.ahblite._ import spinal.tester.{SpinalTesterCocotbBase, SpinalTesterGhdlBase, SpinalSimFunSuite} import org.scalatest.funsuite.AnyFunSuite +import scala.util.Random object MemTester extends App{ class MemTester extends Component { @@ -403,3 +404,140 @@ class SpinalSimRamTester extends AnyFunSuite { } } } + +class SpinalSimRamAccessTester extends SpinalSimFunSuite { + ghdlEnabled = false //TODO + + test("test1") { + SimConfig.compile(new Component{ + val mem = Mem(UInt(16 bits), 32).simPublic() + val write = slave(mem.writePort) + val read = new Area{ + val address = in(mem.addressType()) + val data = out(mem.readAsync(address)) + } + }).doSim{ dut => + val model = Array.fill(32)(Random.nextInt(1024*64)) + for ((v, i) <- model.zipWithIndex) dut.mem.setBigInt(i, v) + + def simWrite() { + val address = Random.nextInt(32) + val data = Random.nextInt(1024*64) + dut.mem.setBigInt(address, data) + model(address) = data + sleep(1) + } + def simCheck() = { + val address = Random.nextInt(32) + val readed = dut.mem.getBigInt(address) + assert(readed == model(address)) + } + + dut.write.valid #= false + def dutWrite() { + dut.clockDomain.waitSampling() + val address = Random.nextInt(32) + val data = Random.nextInt(1024*64) + dut.write.valid #= true + dut.write.address #= address + dut.write.data #= data + dut.clockDomain.waitSampling() + dut.write.valid #= false + dut.clockDomain.waitSampling() + model(address) = data + } + def dutCheck() = { + sleep(1) + val address = Random.nextInt(32) + dut.read.address #= address + sleep(1) + if(Random.nextBoolean()) sleep(1) else dut.clockDomain.waitSampling() + assert(dut.read.data.toInt == model(address)) + } + + + dut.clockDomain.forkStimulus(10) + dut.clockDomain.waitSampling(10) + for(i <- 0 until 1000) Random.nextInt(4) match { + case 0 => simWrite() + case 1 => simCheck() + case 2 => dutWrite() + case 3 => dutCheck() + } + println(simTime()) + } + } + + test("test2") { + SimConfig.compile(new Component{ + val mem = Mem(UInt(16 bits), 32).simPublic() + val write = new Area{ + val valid = in Bool() + val address = in(mem.addressType()) + val data = in(mem.wordType()) + val mask = in Bits(4 bits) + mem.write(address, data, enable = valid, mask = mask) + } + val read = new Area{ + val address = in(mem.addressType()) + val data = out(mem.readAsync(address)) + } + }).doSim{ dut => + val model = Array.fill(32)(Random.nextInt(1024*64)) + for ((v, i) <- model.zipWithIndex) dut.mem.setBigInt(i, v) + + def simWrite() { + val address = Random.nextInt(32) + val data = Random.nextInt(1024*64) + dut.mem.setBigInt(address, data) + model(address) = data + sleep(1) + } + def simCheck() = { + val address = Random.nextInt(32) + assert(dut.mem.getBigInt(address) == model(address)) + } + + dut.write.valid #= false + def dutWrite() { + dut.clockDomain.waitSampling() + val address = Random.nextInt(32) + val data = Random.nextInt(1024*64) + val mask = Random.nextInt(16) + dut.write.valid #= true + dut.write.address #= address + dut.write.data #= data + dut.write.mask #= mask + dut.clockDomain.waitSampling() + dut.write.valid #= false + dut.clockDomain.waitSampling() + var buffer = model(address) + for(i <- 0 until 4 if (mask & (1 << i)) != 0){ + val m = 0xF << 4*i + buffer = (buffer & ~m) | (data & m) + } + model(address) = buffer + } + def dutCheck() = { + sleep(1) + val address = Random.nextInt(32) + dut.read.address #= address + sleep(1) + if(Random.nextBoolean()) sleep(1) else dut.clockDomain.waitSampling() + assert(dut.read.data.toInt == model(address)) + } + + + dut.clockDomain.forkStimulus(10) + dut.clockDomain.waitSampling(10) + for(i <- 0 until 1000) Random.nextInt(4) match { + case 0 => simWrite() + case 1 => simCheck() + case 2 => dutWrite() + case 3 => dutCheck() + case _ => + } + println(simTime()) + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimRamAccessTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimRamAccessTester.scala deleted file mode 100644 index 60c9860f52..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimRamAccessTester.scala +++ /dev/null @@ -1,145 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.lib._ -import spinal.core.sim._ - -import scala.util.Random - -class SpinalSimRamAccessTester extends SpinalSimFunSuite { - ghdlEnabled = false //TODO - - test("test1") { - SimConfig.compile(new Component{ - val mem = Mem(UInt(16 bits), 32).simPublic() - val write = slave(mem.writePort) - val read = new Area{ - val address = in(mem.addressType()) - val data = out(mem.readAsync(address)) - } - }).doSim{ dut => - val model = Array.fill(32)(Random.nextInt(1024*64)) - for ((v, i) <- model.zipWithIndex) dut.mem.setBigInt(i, v) - - def simWrite() { - val address = Random.nextInt(32) - val data = Random.nextInt(1024*64) - dut.mem.setBigInt(address, data) - model(address) = data - sleep(1) - } - def simCheck() = { - val address = Random.nextInt(32) - val readed = dut.mem.getBigInt(address) - assert(readed == model(address)) - } - - dut.write.valid #= false - def dutWrite() { - dut.clockDomain.waitSampling() - val address = Random.nextInt(32) - val data = Random.nextInt(1024*64) - dut.write.valid #= true - dut.write.address #= address - dut.write.data #= data - dut.clockDomain.waitSampling() - dut.write.valid #= false - dut.clockDomain.waitSampling() - model(address) = data - } - def dutCheck() = { - sleep(1) - val address = Random.nextInt(32) - dut.read.address #= address - sleep(1) - if(Random.nextBoolean()) sleep(1) else dut.clockDomain.waitSampling() - assert(dut.read.data.toInt == model(address)) - } - - - dut.clockDomain.forkStimulus(10) - dut.clockDomain.waitSampling(10) - for(i <- 0 until 1000) Random.nextInt(4) match { - case 0 => simWrite() - case 1 => simCheck() - case 2 => dutWrite() - case 3 => dutCheck() - } - println(simTime()) - } - } - - test("test2") { - SimConfig.compile(new Component{ - val mem = Mem(UInt(16 bits), 32).simPublic() - val write = new Area{ - val valid = in Bool() - val address = in(mem.addressType()) - val data = in(mem.wordType()) - val mask = in Bits(4 bits) - mem.write(address, data, enable = valid, mask = mask) - } - val read = new Area{ - val address = in(mem.addressType()) - val data = out(mem.readAsync(address)) - } - }).doSim{ dut => - val model = Array.fill(32)(Random.nextInt(1024*64)) - for ((v, i) <- model.zipWithIndex) dut.mem.setBigInt(i, v) - - def simWrite() { - val address = Random.nextInt(32) - val data = Random.nextInt(1024*64) - dut.mem.setBigInt(address, data) - model(address) = data - sleep(1) - } - def simCheck() = { - val address = Random.nextInt(32) - assert(dut.mem.getBigInt(address) == model(address)) - } - - dut.write.valid #= false - def dutWrite() { - dut.clockDomain.waitSampling() - val address = Random.nextInt(32) - val data = Random.nextInt(1024*64) - val mask = Random.nextInt(16) - dut.write.valid #= true - dut.write.address #= address - dut.write.data #= data - dut.write.mask #= mask - dut.clockDomain.waitSampling() - dut.write.valid #= false - dut.clockDomain.waitSampling() - var buffer = model(address) - for(i <- 0 until 4 if (mask & (1 << i)) != 0){ - val m = 0xF << 4*i - buffer = (buffer & ~m) | (data & m) - } - model(address) = buffer - } - def dutCheck() = { - sleep(1) - val address = Random.nextInt(32) - dut.read.address #= address - sleep(1) - if(Random.nextBoolean()) sleep(1) else dut.clockDomain.waitSampling() - assert(dut.read.data.toInt == model(address)) - } - - - dut.clockDomain.forkStimulus(10) - dut.clockDomain.waitSampling(10) - for(i <- 0 until 1000) Random.nextInt(4) match { - case 0 => simWrite() - case 1 => simCheck() - case 2 => dutWrite() - case 3 => dutCheck() - case _ => - } - println(simTime()) - } - } -} - From 136f27619c6957f179c1dab2d10c4849fc721627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 19:24:45 +0100 Subject: [PATCH 096/120] refactor: move AvalonSTTester --- .../src/test/scala/spinal/lib/bus/avalon/AvalonST.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimAvalonSTTester.scala => lib/src/test/scala/spinal/lib/bus/avalon/AvalonST.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimAvalonSTTester.scala b/lib/src/test/scala/spinal/lib/bus/avalon/AvalonST.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimAvalonSTTester.scala rename to lib/src/test/scala/spinal/lib/bus/avalon/AvalonST.scala index 6afb9279d0..21778b538b 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimAvalonSTTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/avalon/AvalonST.scala @@ -1,12 +1,12 @@ -package spinal.tester.scalatest +package spinal.lib.bus.avalon import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import spinal.core.sim._ -import spinal.lib.bus.avalon._ import spinal.lib._ import spinal.lib.bus.avalon.sim.{AvalonSTDriver, AvalonSTMonitor} -import spinal.lib.sim.{ScoreboardInOrder, SimData} +import spinal.lib.sim.SimData import scala.collection.mutable From 8f96b81c453a5b40a2f4f87c2a60896eabeb62de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 20:23:45 +0100 Subject: [PATCH 097/120] refactor: move Encoding8b10bTest --- .../test/scala/spinal/lib/com/linecode/Encoding8b10b.scala | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimEncoding8b10b.scala => lib/src/test/scala/spinal/lib/com/linecode/Encoding8b10b.scala (99%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimEncoding8b10b.scala b/lib/src/test/scala/spinal/lib/com/linecode/Encoding8b10b.scala similarity index 99% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimEncoding8b10b.scala rename to lib/src/test/scala/spinal/lib/com/linecode/Encoding8b10b.scala index 86adaefdfa..a30fcb7ab5 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimEncoding8b10b.scala +++ b/lib/src/test/scala/spinal/lib/com/linecode/Encoding8b10b.scala @@ -1,11 +1,8 @@ -package spinal.tester.scalatest +package spinal.lib.com.linecode import org.scalatest.funsuite.AnyFunSuite -import spinal.sim._ -import spinal.core._ import spinal.core.sim._ -import spinal.lib.com.linecode.Encoding8b10b class Encoding8b10bTest extends AnyFunSuite { @@ -480,7 +477,5 @@ class Encoding8b10bTest extends AnyFunSuite { decodeTestCaseError(dut, "00000011", "1001110000", true) } - - } } From 807705771985a32e9baef0d289172aec0fb9dbee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 20:30:40 +0100 Subject: [PATCH 098/120] refactor: move SpinalSimBsbTester --- .../src/test/scala/spinal/lib/bus/bsb/Bsb.scala | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimBsbTester.scala => lib/src/test/scala/spinal/lib/bus/bsb/Bsb.scala (88%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBsbTester.scala b/lib/src/test/scala/spinal/lib/bus/bsb/Bsb.scala similarity index 88% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimBsbTester.scala rename to lib/src/test/scala/spinal/lib/bus/bsb/Bsb.scala index e86f1df8fc..c9869d6f91 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimBsbTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/bsb/Bsb.scala @@ -1,15 +1,11 @@ -package spinal.tester.scalatest +package spinal.lib.bus.bsb import org.scalatest.funsuite.AnyFunSuite -import spinal.core.HardType + import spinal.core._ import spinal.core.sim._ -import spinal.lib.bus.bmb.sim.{BmbDriver, BmbMemoryAgent} -import spinal.lib.bus.bmb.{Bmb, BmbParameter, BmbSlaveFactory} -import spinal.lib.bus.bsb.{Bsb, BsbDownSizerAlignedMultiWidth, BsbDownSizerSparse, BsbParameter, BsbUpSizerDense, BsbUpSizerSparse} -import spinal.lib.bus.bsb.sim.BsbBridgeTester import spinal.lib._ -import spinal.lib.system.dma.sg.{DmaSg, DmaSgTester, SgDmaTestsParameter} +import spinal.lib.bus.bsb.sim.BsbBridgeTester class SpinalSimBsbTester extends AnyFunSuite{ test("upsizerSparse"){ From 16f40f12b979309049ff5babcd9b3b6f9d4ea948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 20:59:07 +0100 Subject: [PATCH 099/120] refactor: move ZeroWidthTester --- .../scala/integration}/ZeroWidthTester.scala | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) rename {tester/src/test/scala/spinal/tester/scalatest => core/src/test/scala/integration}/ZeroWidthTester.scala (98%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/ZeroWidthTester.scala b/core/src/test/scala/integration/ZeroWidthTester.scala similarity index 98% rename from tester/src/test/scala/spinal/tester/scalatest/ZeroWidthTester.scala rename to core/src/test/scala/integration/ZeroWidthTester.scala index b0e6826196..e1ebe0024a 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/ZeroWidthTester.scala +++ b/core/src/test/scala/integration/ZeroWidthTester.scala @@ -16,16 +16,15 @@ * License along with this library. */ -package spinal.tester.scalatest +package integration + +import spinal.tester.SpinalTesterCocotbBase import spinal.core._ -import spinal.lib._ import scala.io.Source object ZeroWidthTester { - - class ZeroWidthTester extends Component { val uint8 = in UInt(8 bits) val sint8 = in SInt(8 bits) @@ -51,8 +50,6 @@ object ZeroWidthTester { val sint08ShiftLeftUint = out(sint0 << uint8) val bits08ShiftLeftUint = out(bits0 << uint8) - - val uint08Equals = out(uint0 === uint8) val uint08NotEquals = out(uint0 =/= uint8) @@ -69,7 +66,6 @@ object ZeroWidthTester { val uint08Bigger = out(uint0 > uint8) val uint08BiggerEquals = out(uint0 >= uint8) - val sint08Equals= out(sint0 === sint8) val sint08NotEquals = out(sint0 =/= sint8) @@ -86,8 +82,6 @@ object ZeroWidthTester { val sint08Bigger = out(sint0 > sint8) val sint08BiggerEquals = out(sint0 >= sint8) - - val bits08Equals= out(0 === bits8) val bits08NotEquals = out(0 =/= bits8) @@ -95,7 +89,6 @@ object ZeroWidthTester { val bits08Or = out(bits0.resized | bits8) val bits08Xor = out(bits0.resized ^ bits8) - val uint80ShiftLeftUint = out(uint8 >> uint0) val sint80ShiftLeftUint = out(sint8 >> uint0) val bits80ShiftLeftUint = out(bits8 >> uint0) @@ -139,14 +132,12 @@ object ZeroWidthTester { val bits80Or = out(bits8 | bits0.resized) val bits80Xor = out(bits8 ^ bits0.resized) - val bitsResizeBigger = out(bits0.resize(16)) val uintResizeBigger = out(uint0.resize(16)) val sintResizeBigger = out(sint0.resize(16)) val bits08Cat = out(bits0 ## bits8) val bits80Cat = out(bits8 ## bits0) - } } @@ -174,4 +165,4 @@ class ZeroWidthTesterCocotbBoot extends SpinalTesterCocotbBase { } } } -} \ No newline at end of file +} From 5219439ac3ab0e7d4d26a34b06f8ccf0e357b5fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 21:04:08 +0100 Subject: [PATCH 100/120] refactor: move SpinalSimPlicTester --- .../test/scala/spinal/lib/misc/plic/PlicMapper.scala | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimPlicTester.scala => lib/src/test/scala/spinal/lib/misc/plic/PlicMapper.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimPlicTester.scala b/lib/src/test/scala/spinal/lib/misc/plic/PlicMapper.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimPlicTester.scala rename to lib/src/test/scala/spinal/lib/misc/plic/PlicMapper.scala index 82dc6c56ef..8396d772a3 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimPlicTester.scala +++ b/lib/src/test/scala/spinal/lib/misc/plic/PlicMapper.scala @@ -1,19 +1,16 @@ -package spinal.tester.scalatest +package spinal.lib.misc.plic + +import spinal.tester.SpinalSimFunSuite -import org.scalatest.funsuite.AnyFunSuite import spinal.core._ import spinal.core.sim._ import spinal.lib._ -import spinal.lib.bus.amba3.apb.sim.Apb3Driver import spinal.lib.bus.amba3.apb.{Apb3, Apb3SlaveFactory} -import spinal.lib.misc.plic.{PlicGatewayActiveHigh, PlicMapper, PlicMapping, PlicTarget} -import spinal.lib.sim._ -import spinal.sim._ +import spinal.lib.bus.amba3.apb.sim.Apb3Driver import scala.collection.mutable.ArrayBuffer import scala.util.Random - class SpinalSimPlicTester extends SpinalSimFunSuite { test("test1") { //Compile the simulator From 3002c11afe4fece3e436b7f11e7fb355039f2c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 21:10:51 +0100 Subject: [PATCH 101/120] refactor: remove SpinalSimPerfTester Running long tests to measure performance without asserting the time spent running the tests is a waste of time and energy. Another fix can be to transform the AnyFunSuite into an App --- .../scalatest/SpinalSimPerfTester.scala | 191 ------------------ 1 file changed, 191 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimPerfTester.scala diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimPerfTester.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimPerfTester.scala deleted file mode 100644 index a3a1b7baab..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimPerfTester.scala +++ /dev/null @@ -1,191 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.sim._ -import spinal.core.sim._ -import spinal.tester.scalatest -import spinal.tester.scalatest.SpinalSimVerilatorIoTest.SpinalSimVerilatorIoTestTop - -import scala.concurrent.{Await, Future} -import scala.util.Random - -object SpinalSimPerfTester { - - class SpinalSimPerfTesterDut extends Component { - val io = new Bundle { - val a, b, c = in UInt (8 bits) - val result = out UInt (8 bits) - } - - io.result := RegNext(io.a + io.b - io.c) init (0) - } - -} - -class SpinalSimPerfTester extends AnyFunSuite { - SpinalSimTester { env => - import env._ - - var compiled: SimCompiled[SpinalSimPerfTester.SpinalSimPerfTesterDut] = null - - test(prefix + "compile") { - compiled = SimConfig - .allOptimisation - // .withGhdl - .compile(new SpinalSimPerfTester.SpinalSimPerfTesterDut()) - } - - - test(prefix + "TestStdSimIntThreadLess") { - compiled.doSim { dut => - dut.clockDomain.forkStimulus(period = 10) - dut.clockDomain.forkSimSpeedPrinter(0.2) - dut.io.a.randomize() - dut.io.b.randomize() - dut.io.c.randomize() - - var model = -1 - var times = 0 - dut.clockDomain.onSamplings { - assert(model == -1 || dut.io.result.toInt == model) - model = ((dut.io.a.toInt + dut.io.b.toInt - dut.io.c.toInt) & 0xFF) - dut.io.a #= Random.nextInt(256) - dut.io.b #= Random.nextInt(256) - dut.io.c #= Random.nextInt(256) - times += 1 - } - - for (repeat <- 0 until 4) { - val startAt = System.nanoTime - waitUntil(times == (2000000*durationFactor).toInt) - times = 0 - val endAt = System.nanoTime - System.out.println((endAt - startAt) * 1e-6 + " ms") - } - } - } - - - test(prefix + "TestStdSimInt") { - compiled.doSim { dut => - dut.clockDomain.forkStimulus(period = 10) - dut.clockDomain.forkSimSpeedPrinter(0.2) - - var model = 0 - for (repeat <- 0 until 4) { - val times = (2000000*durationFactor).toInt - val startAt = System.nanoTime - for (repeat2 <- 0 until times) { - dut.io.a #= Random.nextInt(256) - dut.io.b #= Random.nextInt(256) - dut.io.c #= Random.nextInt(256) - dut.clockDomain.waitActiveEdge() - if (dut.clockDomain.isResetDeasserted) { - assert(dut.io.result.toInt == model) - model = ((dut.io.a.toInt + dut.io.b.toInt - dut.io.c.toInt) & 0xFF) - } - } - val endAt = System.nanoTime - System.out.println((endAt - startAt) * 1e-6 + " ms") - } - } - } - - - test(prefix + "TestStdSimIntx2") { - compiled.doSim { dut => - dut.clockDomain.forkStimulus(period = 10) - - for (repeat <- 0 until 4) { - val times = (80000*durationFactor).toInt - val startAt = System.nanoTime - val t1, t2 = fork { - val rand = new Random(1) - for (repeat2 <- 0 until times) { - val a, b, c = rand.nextInt(256) - dut.io.a #= a - dut.io.b #= b - dut.io.c #= c - dut.clockDomain.waitActiveEdge() - sleep(0) - val dummy = if (dut.clockDomain.isResetDeasserted) - assert(dut.io.result.toInt == ((a + b - c) & 0xFF)) - } - } - t1.join(); t2.join() - val endAt = System.nanoTime - System.out.println((endAt - startAt) * 1e-6 + " ms") - } - } - } - - - test(prefix + "TestStdSimBigInt") { - compiled.doSim { dut => - dut.clockDomain.forkStimulus(period = 10) - - for (repeat <- 0 until 4) { - val times = (80000*durationFactor).toInt - val startAt = System.nanoTime - for (repeat2 <- 0 until times) { - val a, b, c = BigInt(Random.nextInt(256)) - dut.io.a #= a - dut.io.b #= b - dut.io.c #= c - dut.clockDomain.waitActiveEdge(); sleep(0) - if (dut.clockDomain.isResetDeasserted) assert(dut.io.result.toBigInt == ((a + b - c) & 0xFF)) - } - val endAt = System.nanoTime - System.out.println((endAt - startAt) * 1e-6 + " ms") - } - } - } - - test(prefix + "TestSleep0") { - compiled.doSim { dut => - dut.clockDomain.forkStimulus(period = 10) - - for (repeat <- 0 until 4) { - val times = (100000*durationFactor).toInt - val startAt = System.nanoTime - for (repeat2 <- 0 until times) { - sleep(0) - } - val endAt = System.nanoTime - System.out.println((endAt - startAt) * 1e-6 + " ms") - } - } - - } - - - test(prefix + "compilationSpeed") { - val stages = 100 - val states = (100*designFactor).toInt - val operands = 5 - SimConfig.withConfig(SpinalConfig(verbose = true)).allOptimisation.doSim(new Component { - val inputs = Vec(in UInt (8 bits), states) - val outputs = Vec(out UInt (8 bits), states) - var ptr = inputs - for (s <- 0 until stages) { - val result = Vec(Reg(UInt(8 bits)), states).setName("tmp_" + s) - for (elementId <- 0 until states) { - result(elementId) := (0 until operands).map(_ => ptr(Random.nextInt(states))).reduce(_ + _) - } - ptr = result - } - outputs := ptr - }) { dut => - - dut.clockDomain.forkStimulus(10) - for (r <- 0 until (10000*durationFactor).toInt) { - for (input <- dut.inputs) { - input.randomize() - } - dut.clockDomain.waitSampling() - } - } - } - } -} From 2cc091746b0462694f0fe66827786f2acae3e2ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 21:15:13 +0100 Subject: [PATCH 102/120] refactor: move SpinalSimSigmaDeltaTester --- .../spinal/lib/misc/analog/DacSigmaDelta.scala | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimSigmaDeltaTester.scala => lib/src/test/scala/spinal/lib/misc/analog/DacSigmaDelta.scala (76%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimSigmaDeltaTester.scala b/lib/src/test/scala/spinal/lib/misc/analog/DacSigmaDelta.scala similarity index 76% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimSigmaDeltaTester.scala rename to lib/src/test/scala/spinal/lib/misc/analog/DacSigmaDelta.scala index 2d69aad905..7ed6d1fa64 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimSigmaDeltaTester.scala +++ b/lib/src/test/scala/spinal/lib/misc/analog/DacSigmaDelta.scala @@ -1,20 +1,17 @@ -package spinal.tester.scalatest +package spinal.lib.misc.analog import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ + import spinal.core.sim._ -import spinal.lib._ import spinal.lib.bus.bmb.sim.BmbDriver -import spinal.lib.bus.bmb.{BmbAccessCapabilities, BmbParameter} -import spinal.lib.bus.bsb.sim.{BsbBridgeTester, BsbDriver, BsbPacket} -import spinal.lib.bus.bsb.{Bsb, BsbDownSizerSparse, BsbParameter, BsbUpSizerDense, BsbUpSizerSparse} -import spinal.lib.misc.analog.{BmbBsbToDeltaSigma, BsbToDeltaSigmaParameter} +import spinal.lib.bus.bmb.BmbParameter +import spinal.lib.bus.bsb.sim.{BsbDriver, BsbPacket} +import spinal.lib.bus.bsb.{Bsb, BsbParameter} import spinal.lib.sim.StreamDriver -import spinal.lib.system.dma.sg.DmaSg import scala.collection.mutable -class SpinalSimSigmaDeltaTester extends AnyFunSuite{ +class SpinalSimDeltaSigmaTester extends AnyFunSuite{ test("a"){ SimConfig.compile( BmbBsbToDeltaSigma( From c98bc2dc91aba5335c96f7e5b3af6e4ae326e2ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 11 Dec 2022 21:47:23 +0100 Subject: [PATCH 103/120] refactor: move CoreMiscTester --- core/src/test/scala/spinal/core/Area.scala | 34 ++++ core/src/test/scala/spinal/core/Reg.scala | 75 ++++++++ core/src/test/scala/spinal/core/UInt.scala | 44 +++++ lib/src/test/scala/spinal/lib/Utils.scala | 55 ++++++ .../tester/scalatest/CoreMiscTester.scala | 177 ------------------ 5 files changed, 208 insertions(+), 177 deletions(-) create mode 100644 core/src/test/scala/spinal/core/Area.scala create mode 100644 core/src/test/scala/spinal/core/Reg.scala create mode 100644 core/src/test/scala/spinal/core/UInt.scala delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/CoreMiscTester.scala diff --git a/core/src/test/scala/spinal/core/Area.scala b/core/src/test/scala/spinal/core/Area.scala new file mode 100644 index 0000000000..6e94b9b8f4 --- /dev/null +++ b/core/src/test/scala/spinal/core/Area.scala @@ -0,0 +1,34 @@ +package spinal.core + +import org.scalatest.funsuite.AnyFunSuite + +import spinal.core.sim._ + +class AreaTester extends AnyFunSuite { + test("SlowArea") { + SimConfig + .withConfig( + SpinalConfig(defaultClockDomainFrequency = FixedFrequency(4000 Hz)) + ) + .compile(new Component { + val counter = out(RegInit(U"0000")) + counter := counter + 1 + assert(clockDomain.samplingRate.getValue.toInt == 4000) + + val slowArea = new SlowArea(4) { + val counter = out(RegInit(U"0000")) + counter := counter + 1 + assert(clockDomain.samplingRate.getValue.toInt == 1000) + } + }) + .doSim { dut => + dut.clockDomain.forkStimulus(10) + + for (i <- 0 until 1000) { + dut.clockDomain.waitSampling() + assert(dut.counter.toInt == i % 16) + assert(dut.slowArea.counter.toInt == (i - 1) / 4 % 16) + } + } + } +} diff --git a/core/src/test/scala/spinal/core/Reg.scala b/core/src/test/scala/spinal/core/Reg.scala new file mode 100644 index 0000000000..b094b48bc6 --- /dev/null +++ b/core/src/test/scala/spinal/core/Reg.scala @@ -0,0 +1,75 @@ +package spinal.core + +import org.scalatest.funsuite.AnyFunSuite + +import spinal.core.sim._ + +class RegTester extends AnyFunSuite { + test("getAheadValue") { + SimConfig + .compile(new Component { + val conds = in(Vec.fill(8)(Bool())) + val a, b, c, d, e = out(Reg(UInt(8 bits)) init (0)) + + when(conds(0)) { + a := 1 + when(conds(1)) { + a := 2 + b := 11 + } otherwise { + a := 3 + c := 21 + } + } + when(conds(2)) { + a := 4 + b := 12 + c := 22 + d := 31 + } + + val x = out(a.getAheadValue) + val y = out(a.getAheadValue) + val z = out(b.getAheadValue) + + when(d.getAheadValue() === 0) { + e := 1 + } + }) + .doSim(seed = 42) { dut => + var an, bn, cn, a, b, c = 0 + dut.conds.foreach(_ #= false) + dut.clockDomain.forkStimulus(10) + dut.clockDomain.waitSampling() + + for (i <- 0 until 1000) { + if (dut.conds(0).toBoolean) { + an = 1 + if (dut.conds(1).toBoolean) { + an = 2 + bn = 11 + } else { + an = 3 + cn = 21 + } + } + if (dut.conds(2).toBoolean) { + an = 4 + bn = 12 + cn = 22 + } + assert(dut.x.toInt == an) + assert(dut.y.toInt == an) + assert(dut.z.toInt == bn) + assert(dut.a.toInt == a) + assert(dut.b.toInt == b) + assert(dut.c.toInt == c) + a = an + b = bn + c = cn + dut.clockDomain.waitSampling() + dut.conds.foreach(_.randomize()) + } + } + } +} diff --git a/core/src/test/scala/spinal/core/UInt.scala b/core/src/test/scala/spinal/core/UInt.scala new file mode 100644 index 0000000000..c6acb9e488 --- /dev/null +++ b/core/src/test/scala/spinal/core/UInt.scala @@ -0,0 +1,44 @@ +package spinal.core + +import org.scalatest.funsuite.AnyFunSuite + +import spinal.core.sim._ + +import scala.util.Random + +class UIntTester extends AnyFunSuite { + test("wrap_comparison") { + val width = 8 + SimConfig + .compile(new Component { + val x, y = in port UInt(width bits) + val lt, gt = out port Bool() + val le, ge = out port Bool() + + lt := x.wrap < y + gt := x.wrap > y + le := x.wrap <= y + ge := x.wrap >= y + }) + .doSim(seed = 42) { dut => + val quarter = 1 << (width - 2) + for (i <- 0 until 2000) { + val x = dut.x.randomize() + // ensure two datas' distance are not beyond a quarter. + val d = Random.nextInt(2 * quarter) - quarter + val y = (x + d).abs % (4 * quarter) + dut.y #= y + + sleep(1) + + val rev = (x - y).abs > 3 * quarter + assert(dut.lt.toBoolean == (if (rev) x > y else x < y)) + assert(dut.gt.toBoolean == (if (rev) x < y else x > y)) + assert(dut.le.toBoolean == (if (rev) x >= y else x <= y)) + assert(dut.ge.toBoolean == (if (rev) x <= y else x >= y)) + + sleep(1) + } + } + } +} diff --git a/lib/src/test/scala/spinal/lib/Utils.scala b/lib/src/test/scala/spinal/lib/Utils.scala index 67cfd97e8b..188ebb6820 100644 --- a/lib/src/test/scala/spinal/lib/Utils.scala +++ b/lib/src/test/scala/spinal/lib/Utils.scala @@ -134,3 +134,58 @@ class SpinalSimLibTester extends AnyFunSuite { } } } + + +class TraversableOncePimpedTester extends AnyFunSuite { + test("reverse_by_shuffle") { + SimConfig + .compile(new Component { + val data = in port Bits(64 bits) + val outData = out port UInt(64 bits) + + val outSet = data.subdivideIn(8 bits) + + outData := outSet.shuffle(outSet.length - 1 - _).asBits.asUInt + }) + .doSim(seed = 42) { dut => + for (j <- 0 until 1000) { + val data = dut.data.randomize() + + sleep(1) + val outData = dut.outData.toBigInt + + for (i <- 0 until 8) { + val in = (data >> i * 8) & 0xff + val out = (outData >> (7 - i) * 8) & 0xff + assert(in == out) + } + } + } + } + + test("reverse_by_shuffle_with_size") { + SimConfig + .compile(new Component { + val data = in port Bits(64 bits) + val outData = out port UInt(64 bits) + + outData := U( + B(data.subdivideIn(8 bits).shuffleWithSize((n, i) => n - 1 - i)) + ) + }) + .doSim(seed = 42) { dut => + for (j <- 0 until 1000) { + val data = dut.data.randomize() + + sleep(1) + val outData = dut.outData.toBigInt + + for (i <- 0 until 8) { + val in = (data >> i * 8) & 0xff + val out = (outData >> (7 - i) * 8) & 0xff + assert(in == out) + } + } + } + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/CoreMiscTester.scala b/tester/src/test/scala/spinal/tester/scalatest/CoreMiscTester.scala deleted file mode 100644 index 72ede67614..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/CoreMiscTester.scala +++ /dev/null @@ -1,177 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.core.sim._ -import spinal.lib._ -import scala.util.Random -class CoreMiscTester extends AnyFunSuite{ - test("SlowArea"){ - SimConfig.withConfig(SpinalConfig(defaultClockDomainFrequency = FixedFrequency(4000 Hz))).compile(new Component{ - val counter = out(RegInit(U"0000")) - counter := counter + 1 - assert(clockDomain.samplingRate.getValue.toInt == 4000) - - val slowArea = new SlowArea(4){ - val counter = out(RegInit(U"0000")) - counter := counter + 1 - assert(clockDomain.samplingRate.getValue.toInt == 1000) - } - - }).doSim{dut => - dut.clockDomain.forkStimulus(10) - - for(i <- 0 until 1000){ - dut.clockDomain.waitSampling() - assert(dut.counter.toInt == i % 16) - assert(dut.slowArea.counter.toInt == (i-1)/4 % 16) - } - } - } - - test("reg_nextValue"){ - SimConfig.compile(new Component{ - val conds = in(Vec.fill(8)(Bool())) - val a, b, c, d, e = out(Reg(UInt(8 bits)) init(0)) - - when(conds(0)){ - a := 1 - when(conds(1)){ - a := 2 - b := 11 - } otherwise { - a := 3 - c := 21 - } - } - when(conds(2)){ - a := 4 - b := 12 - c := 22 - d := 31 - } - - val x = out(a.getAheadValue) - val y = out(a.getAheadValue) - val z = out(b.getAheadValue) - - when(d.getAheadValue() === 0){ - e := 1 - } - }).doSim(seed = 42){dut => - var an,bn,cn,a,b,c = 0 - dut.conds.foreach(_ #= false) - dut.clockDomain.forkStimulus(10) - dut.clockDomain.waitSampling() - - for(i <- 0 until 1000){ - if(dut.conds(0).toBoolean){ - an = 1 - if(dut.conds(1).toBoolean){ - an = 2 - bn = 11 - } else { - an = 3 - cn = 21 - } - } - if(dut.conds(2).toBoolean){ - an = 4 - bn = 12 - cn = 22 - } - assert(dut.x.toInt == an) - assert(dut.y.toInt == an) - assert(dut.z.toInt == bn) - assert(dut.a.toInt == a) - assert(dut.b.toInt == b) - assert(dut.c.toInt == c) - a = an - b = bn - c = cn - dut.clockDomain.waitSampling() - dut.conds.foreach(_.randomize()) - } - } - } - - test("uint_wrap_comparison"){ - val width = 8 - SimConfig.compile(new Component{ - val smaller, bigger, eq_smaller, eq_bigger = out(Bool()) - val x, y = in(UInt(width bits)) - - smaller := x.wrap < y - bigger := x.wrap > y - eq_smaller := x.wrap <= y - eq_bigger := x.wrap >= y - }).doSim(seed = 42){dut => - val quarter = 1<<(width - 2) - for(i <- 0 until 2000){ - dut.x.randomize() - sleep(1) - var x = dut.x.toInt - var value = x + Random.nextInt(2*quarter) - quarter // ensure two datas' distance are not beyond a quarter. - value = if (value < 0) -value else value - value %= 4*quarter - dut.y #= value - sleep(1) - val y = dut.y.toInt - val needReverse = (x - y).abs > 3* quarter - - assert(dut.smaller.toBoolean == (if(needReverse) x > y else x < y)) - assert(dut.bigger.toBoolean == (if(needReverse) x < y else x > y)) - assert(dut.eq_smaller.toBoolean == (if(needReverse) x >= y else x <= y)) - assert(dut.eq_bigger.toBoolean == (if(needReverse) x <= y else x >= y)) - sleep(1) - } - } - } - - test("reverse_by_shuffle"){ - SimConfig.compile(new Component{ - val data = in(Bits(64 bits)) - val outData = out(UInt(64 bits)) - - val outSet = data.subdivideIn(8 bits) - outData := outSet.shuffle{ (i) => - outSet.length - 1 - i - }.asBits.asUInt - }).doSim(seed = 42){dut => - for(j <- 0 until 1000) { - dut.data.randomize() - sleep(1) - val data = dut.data.toBigInt - val outData = dut.outData.toBigInt - for ( i <- 0 until 8) { - val in = (data >> i * 8) & 0xFF - val out = (outData >> (7-i) *8) & 0xFF - assert(in == out) - } - } - } - } - - test("reverse_by_shuffle_with_size"){ - SimConfig.compile(new Component{ - val data = in(Bits(64 bits)) - val outData = out(UInt(64 bits)) - - outData := data.subdivideIn(8 bits).shuffleWithSize{ (total, i) => - total - 1 - i - }.asBits.asUInt - }).doSim(seed = 42){dut => - for(j <- 0 until 1000) { - dut.data.randomize() - sleep(1) - val data = dut.data.toBigInt - val outData = dut.outData.toBigInt - for ( i <- 0 until 8) { - val in = (data >> i * 8) & 0xFF - val out = (outData >> (7-i) *8) & 0xFF - assert(in == out) - } - } - } - } -} From c0ab09595ffbc0cd07f969d7ba1bfa24956d685d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 12 Dec 2022 08:21:54 +0100 Subject: [PATCH 104/120] refactor: move RegIfAxiLite4Tester --- .../scala/spinal/lib/bus/regif/AxiLite4BusInterface.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/RegIfAxiLite4Tester.scala => lib/src/test/scala/spinal/lib/bus/regif/AxiLite4BusInterface.scala (98%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/RegIfAxiLite4Tester.scala b/lib/src/test/scala/spinal/lib/bus/regif/AxiLite4BusInterface.scala similarity index 98% rename from tester/src/test/scala/spinal/tester/scalatest/RegIfAxiLite4Tester.scala rename to lib/src/test/scala/spinal/lib/bus/regif/AxiLite4BusInterface.scala index bf89a054e7..6f8637184f 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/RegIfAxiLite4Tester.scala +++ b/lib/src/test/scala/spinal/lib/bus/regif/AxiLite4BusInterface.scala @@ -1,15 +1,14 @@ -package spinal.tester.scalatest +package spinal.lib.bus.regif import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import spinal.core.sim._ import spinal.lib._ import spinal.lib.bus.amba4.axilite._ import spinal.lib.bus.amba4.axilite.sim.{AxiLite4Driver, AxiLite4ReadOnlyMonitor, AxiLite4WriteOnlyMonitor} -import spinal.lib.bus.regif.{AccessType, BusInterface} import scala.collection.mutable -import scala.math.{BigInt} import scala.util.Random class RegIfTester extends Component { From ab7264e7072dd521071cc5a08611e4bd73f28952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 12 Dec 2022 08:25:16 +0100 Subject: [PATCH 105/120] refactor: move BusSlaveFactoryDoubleReadTester --- .../scala/spinal/lib/bus/amba3/apb/Apb3SlaveFactory.scala | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/BusSlaveFactoryDoubleRead.scala => lib/src/test/scala/spinal/lib/bus/amba3/apb/Apb3SlaveFactory.scala (93%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/BusSlaveFactoryDoubleRead.scala b/lib/src/test/scala/spinal/lib/bus/amba3/apb/Apb3SlaveFactory.scala similarity index 93% rename from tester/src/test/scala/spinal/tester/scalatest/BusSlaveFactoryDoubleRead.scala rename to lib/src/test/scala/spinal/lib/bus/amba3/apb/Apb3SlaveFactory.scala index 396965329e..662b2673e8 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/BusSlaveFactoryDoubleRead.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba3/apb/Apb3SlaveFactory.scala @@ -1,12 +1,10 @@ -package spinal.tester.scalatest - +package spinal.lib.bus.amba3.apb import org.scalatest.funsuite.AnyFunSuite -import org.scalatest.{Assertions} +import org.scalatest.Assertions + import spinal.core._ import spinal.lib._ -import spinal.lib.bus.amba3.apb._ - object TestTopLevel { From 5e274a753948c5ea44810ae8fcdd349ded1e74db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 12 Dec 2022 09:27:29 +0100 Subject: [PATCH 106/120] refactor: move CommonTester Tbh I don't really understand what is tested here --- .../test/scala/integration/CommonTester.scala | 115 +++++++++++++++ .../tester/scalatest/CommonTester.scala | 138 ------------------ 2 files changed, 115 insertions(+), 138 deletions(-) create mode 100644 core/src/test/scala/integration/CommonTester.scala delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/CommonTester.scala diff --git a/core/src/test/scala/integration/CommonTester.scala b/core/src/test/scala/integration/CommonTester.scala new file mode 100644 index 0000000000..cea301138b --- /dev/null +++ b/core/src/test/scala/integration/CommonTester.scala @@ -0,0 +1,115 @@ +package integration + +import spinal.tester.SpinalTesterCocotbBase + +import spinal.core._ + +object CommonTester { + class BundleA() extends Bundle { + val bod = new Bundle { + val gggg = Bool() + val aosi = UInt(3 bit) + } + val ahe = Bool() + val zwg = Bool() + } + + case class BundleAA() extends BundleA { + val vsw = Bool() + val lwee = UInt(5 bit) + } + + case class CommonTester() extends Component { + val io = new Bundle { + val conds = in port Vec(Bool(), 8) + + val inUIntA = in port UInt(8 bit) + val inUIntB = in port UInt(8 bit) + val outUIntAdder = out port UInt() + + val inAA = in port BundleAA() + val inAABits = in port Bits(BundleAA().getBitsWidth bit) + val outAA = out port BundleAA() + val outAABits = out port Bits(BundleAA().getBitsWidth bit) + + val complexLiteral = out port UInt(16 bit) + + val assign = new Bundle { + val sel = in port Vec(UInt(4 bit), 4) + val bitDemux = out port Bits(16 bit) + + def doIt(): Unit = { + bitDemux := B(0) + bitDemux(sel(0)) := conds(0) + + when(conds(1)) { + bitDemux(sel(1)) := conds(2) + } elsewhen (conds(3)) { + bitDemux(sel(0)) := conds(4) + } + + when(conds(5)) { + bitDemux(sel(1)) := conds(6) + } + + bitDemux(5) := True + } + } + + def doIt(): Unit = { + assign.doIt() + } + } + + io.doIt() + + io.outAA.assignFromBits(io.inAABits) + io.outAABits := io.inAA.asBits + + io.complexLiteral(15 downto 4) := 0x70 + io.complexLiteral(15 downto 12) := (U(2) + U(1)).resized + io.complexLiteral(6) := True + io.complexLiteral(3) := True + io.complexLiteral(5) := True + io.complexLiteral(3 downto 0) := 2 + io.complexLiteral(13) := False + + def combAdderFunc(x: UInt, y: UInt): UInt = { + val ret = UInt(widthOf(x) max widthOf(y) bits) + val size = io.inUIntA.getWidth + + var c = False + for (i <- 0 until size) { + val a = x(i) + val b = y(i) + ret(i) := a ^ b ^ c + c \= (a & b) | (a & c) | (b & c) + } + + ret + } + + io.outUIntAdder := combAdderFunc(io.inUIntA, io.inUIntB) + + // Clone test + case class MyBundle(paramBool: Bool, asd: Int) extends Bundle { + val a = cloneOf(paramBool) + } + + case class MyBundle2() extends Bundle { + val a = Bool() + } + + cloneOf(MyBundle(True, 1)) + cloneOf(MyBundle2()) + } +} + +class CommonTesterCocotbBoot extends SpinalTesterCocotbBase { + override def getName: String = "CommonTester" + + override def createToplevel: Component = new CommonTester.CommonTester + + override def pythonTestLocation: String = + "tester/src/test/python/spinal/CommonTester" +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/CommonTester.scala b/tester/src/test/scala/spinal/tester/scalatest/CommonTester.scala deleted file mode 100644 index 8cead1b9f4..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/CommonTester.scala +++ /dev/null @@ -1,138 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.lib._ - -object CommonTester { - - - class BundleA extends Bundle { - val bod = new Bundle { - val gggg = Bool() - val aosi = UInt(3 bit) - } - val ahe = Bool() - val zwg = Bool() - } - - class BundleAA extends BundleA { - val vsw = Bool() - val lwee = UInt(5 bit) - } - - class CommonTester extends Component { - val io = new Bundle { - val conds = in Vec(Bool(),8) - - val inUIntA = in UInt (8 bit) - val inUIntB = in UInt (8 bit) - val outUIntAdder = out UInt() - - val inAA = in(new BundleAA) - val inAABits = in Bits (new BundleAA().getBitsWidth bit) - val outAA = out(new BundleAA) - val outAABits = out Bits (new BundleAA().getBitsWidth bit) - - val complexLiteral = out UInt (16 bit) - - - val assign = new Bundle{ - val sel = in Vec(UInt(4 bit),4) - val bitDemux = out Bits(16 bit) - - - def doit: Unit ={ - bitDemux := B(0) - bitDemux(sel(0)) := conds(0) - when(conds(1)){ - bitDemux(sel(1)) := conds(2) - }elsewhen(conds(3)){ - bitDemux(sel(0)) := conds(4) - } - when(conds(5)){ - bitDemux(sel(1)) := conds(6) - } - bitDemux(5) := True - } - } - def doit: Unit ={ - assign.doit - } - } - - - io.doit - - val noData = NoData - - io.outAA.assignFromBits(io.inAABits) - io.outAABits := io.inAA.asBits - - io.complexLiteral(15 downto 4) := 0x70 - io.complexLiteral(15 downto 12) := (U(2) + U(1)).resized - io.complexLiteral(6) := True - io.complexLiteral(3) := True - io.complexLiteral(5) := True - io.complexLiteral(3 downto 0) := 2 - io.complexLiteral(13) := False - - def combAdderFunc(x : UInt,y : UInt) = { - val ret = UInt(Math.max(widthOf(x),widthOf(y)) bit) - val size = io.inUIntA.getWidth - var c = False - for (i <- 0 until size) { - val a = x(i) - val b = y(i) - ret(i) := a ^ b ^ c - c \= (a & b) | (a & c) | (b & c) - } - ret - } - - -// val combAdder = new Area { -// val size = io.inUIntA.getWidth -// val out = UInt(size bit) -// -// var c = False -// for (i <- 0 until size) { -// val a = io.inUIntA(i) -// val b = io.inUIntB(i) -// out(i) := a ^ b ^ c -// c = (a & b) | (a & c) | (b & c) -// } -// io.outUIntAdder := out -// } - io.outUIntAdder := combAdderFunc(io.inUIntA,io.inUIntB) - - - - //Clone test - case class MyBundle(paramBool : Bool,asd : Int) extends Bundle{ - val a = cloneOf(paramBool) - } - - class MyBundle2 extends Bundle{ - val a = Bool() - } - - cloneOf(new MyBundle(True,1)) - cloneOf(new MyBundle2) - - - - } - -} - -//class CommonTesterGhdlBoot extends SpinalTesterGhdlBase { -// override def getName: String = "CommonTester" -// -// override def createToplevel: Component = new CommonTester.CommonTester -//} - -class CommonTesterCocotbBoot extends SpinalTesterCocotbBase { - override def getName: String = "CommonTester" - override def createToplevel: Component = new CommonTester.CommonTester - override def pythonTestLocation: String = "tester/src/test/python/spinal/CommonTester" -} \ No newline at end of file From 39e7d8ecd79ff6766e48c2384d246ba7bfe121c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 12 Dec 2022 09:33:42 +0100 Subject: [PATCH 107/120] refactor: move LibTester --- lib/src/test/scala/spinal/lib/Utils.scala | 24 +++++++++++- .../spinal/tester/scalatest/LibTester.scala | 38 ------------------- 2 files changed, 23 insertions(+), 39 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/LibTester.scala diff --git a/lib/src/test/scala/spinal/lib/Utils.scala b/lib/src/test/scala/spinal/lib/Utils.scala index 188ebb6820..7853fc67e9 100644 --- a/lib/src/test/scala/spinal/lib/Utils.scala +++ b/lib/src/test/scala/spinal/lib/Utils.scala @@ -3,9 +3,9 @@ package spinal.lib import spinal.core._ import spinal.core.sim._ import spinal.core.formal._ -import spinal.lib._ import spinal.lib.formal._ +import spinal.tester.SpinalTesterCocotbBase import org.scalatest.funsuite.AnyFunSuite import scala.util.Random @@ -189,3 +189,25 @@ class TraversableOncePimpedTester extends AnyFunSuite { } } } + +object LatencyAnalysisTester{ + import spinal.lib.math.SIntMath + + class LibTester extends Component { + val io = new Bundle { + val inSIntA = in SInt (16 bit) + val inSIntB = in SInt (16 bit) + val outSInt = out SInt (32 bit) + val outSIntRef = out SInt (32 bit) + } + io.outSInt := SIntMath.mul(io.inSIntA, io.inSIntB, 4, 0,1,(s,l) => RegNext(s)) + io.outSIntRef := Delay(io.inSIntA * io.inSIntB, LatencyAnalysis(io.inSIntA, io.outSInt)) + } +} + +class LibTesterCocotbBoot extends SpinalTesterCocotbBase { + override def getName: String = "LibTester" + override def pythonTestLocation: String = "tester/src/test/python/spinal/LibTester" + override def createToplevel: Component = new LatencyAnalysisTester.LibTester + withWaveform = true +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/LibTester.scala b/tester/src/test/scala/spinal/tester/scalatest/LibTester.scala deleted file mode 100644 index efb8a08798..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/LibTester.scala +++ /dev/null @@ -1,38 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.lib.{Delay, LatencyAnalysis} -import spinal.lib.com.uart._ -import spinal.lib.math.SIntMath -import spinal.tester.scalatest.FixedPointTester.FixedPointTester - -object LibTester{ - - - class LibTester extends Component { - val io = new Bundle { - val inSIntA = in SInt (16 bit) - val inSIntB = in SInt (16 bit) - val outSInt = out SInt (32 bit) - val outSIntRef = out SInt (32 bit) - } - io.outSInt := SIntMath.mul(io.inSIntA, io.inSIntB, 4, 0,1,(s,l) => RegNext(s)) - io.outSIntRef := Delay(io.inSIntA * io.inSIntB, LatencyAnalysis(io.inSIntA, io.outSInt)) - } - -} - - -class LibTesterCocotbBoot extends SpinalTesterCocotbBase { - override def getName: String = "LibTester" - override def pythonTestLocation: String = "tester/src/test/python/spinal/LibTester" - override def createToplevel: Component = new LibTester.LibTester - withWaveform = true -} - - -//class LibTesterGhdlBoot extends SpinalTesterGhdlBase { -// override def getName: String = "LibTester" -// override def createToplevel: Component = new LibTester.LibTester -//} From 07a9be2af1f294d9d6b7dda508ca99a6f79d56c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 12 Dec 2022 09:40:32 +0100 Subject: [PATCH 108/120] refactor: move FormalAxi4DownsizerTester --- .../test/scala/spinal/lib/bus/amba4/axi/Axi4Downsizer.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/FormalAxi4DownsizerTester.scala => lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4Downsizer.scala (99%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalAxi4DownsizerTester.scala b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4Downsizer.scala similarity index 99% rename from tester/src/test/scala/spinal/tester/scalatest/FormalAxi4DownsizerTester.scala rename to lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4Downsizer.scala index 8d92b9c419..08864b84fa 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalAxi4DownsizerTester.scala +++ b/lib/src/test/scala/spinal/lib/bus/amba4/axi/Axi4Downsizer.scala @@ -1,10 +1,9 @@ -package spinal.tester.scalatest +package spinal.lib.bus.amba4.axi import spinal.core._ import spinal.core.formal._ import spinal.lib._ import spinal.lib.formal._ -import spinal.lib.bus.amba4.axi._ object Util { def size2Ratio(size: UInt): UInt = { From 45291d7cdfff11e9a7db80c5d74d898a9bda588c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 12 Dec 2022 09:50:55 +0100 Subject: [PATCH 109/120] refactor: move FormalSimpleTester --- .../src/test/scala/spinal/core/formal/FormalBootstraps.scala | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/FormalSimpleTester.scala => core/src/test/scala/spinal/core/formal/FormalBootstraps.scala (92%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/FormalSimpleTester.scala b/core/src/test/scala/spinal/core/formal/FormalBootstraps.scala similarity index 92% rename from tester/src/test/scala/spinal/tester/scalatest/FormalSimpleTester.scala rename to core/src/test/scala/spinal/core/formal/FormalBootstraps.scala index 11a3664acc..dca86a0667 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/FormalSimpleTester.scala +++ b/core/src/test/scala/spinal/core/formal/FormalBootstraps.scala @@ -1,13 +1,10 @@ -package spinal.tester.scalatest +package spinal.core.formal import spinal.core._ import spinal.lib._ import spinal.lib.formal._ class FormalSimpleTester extends SpinalFormalFunSuite { - import spinal.core.formal._ - import spinal.core.GenerationFlags._ - def startDoneTest(maxDelay : Int): Unit ={ class StartDoneDut() extends Component { val start = in(Bool()) From 376c5df9b62904ed7ac8d93bbbb3e3e81f2717ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Mon, 12 Dec 2022 09:59:16 +0100 Subject: [PATCH 110/120] refactor: move InternalClockTester --- .../test/scala/spinal/core/ClockDomain.scala | 64 ++++++++++++++++ .../scalatest/InternalClockTester.scala | 76 ------------------- 2 files changed, 64 insertions(+), 76 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/InternalClockTester.scala diff --git a/core/src/test/scala/spinal/core/ClockDomain.scala b/core/src/test/scala/spinal/core/ClockDomain.scala index ce40b570c0..6bbb6e0f6a 100644 --- a/core/src/test/scala/spinal/core/ClockDomain.scala +++ b/core/src/test/scala/spinal/core/ClockDomain.scala @@ -3,6 +3,7 @@ package spinal.core import scala.util.Random import spinal.core.sim._ +import spinal.lib.{BufferCC, Counter, CounterFreeRun, NoData} import spinal.tester.{SpinalSimFunSuite, SpinalTesterCocotbBase} object ClockDomainConfigTester { @@ -417,3 +418,66 @@ class SpinalSimClockDomainTest extends SpinalSimFunSuite { } } } + +object InternalClockTester{ + class ClockGeneratorSub extends Component{ + val io = NoData + + val internalClock = CounterFreeRun(16)(0) + + val initCounter = RegInit(U(7)) + val srcReset = initCounter =/= U(0) + when(srcReset){ + initCounter := initCounter - U(1) + } + val internalClk = ClockDomain(internalClock) + val internalReset = Bool() + + val resetBuffer = new ClockingArea(internalClk){ + val internalReset = BufferCC(srcReset) + } + internalReset := resetBuffer.internalReset + + val internalClockDomain = ClockDomain(internalClock,internalReset) + } + + class ClockGenerator extends Component{ + val io = NoData + val sub = new ClockGeneratorSub + } + + class CounterComponentSub extends Component{ + val io = new Bundle{ + val counter = out UInt(8 bit) + } + val counter = Counter(256) + counter.increment() + io.counter := counter + } + + class CounterComponent extends Component{ + val io = new Bundle{ + val counter = out UInt(8 bit) + } + val sub = new CounterComponentSub + io <> sub.io + } +} + +class InternalClockTester extends Component { + val io = new Bundle { + val internalClkCounter = out UInt(8 bit) + } + val clockGenerator = new InternalClockTester.ClockGenerator + + val internClockDomain = new ClockingArea(clockGenerator.sub.internalClockDomain){ + val counterComponent = new InternalClockTester.CounterComponent + io.internalClkCounter := counterComponent.io.counter + } +} + +class InternalClockTesterCocotbBoot extends SpinalTesterCocotbBase { + override def getName: String = "InternalClockTester" + override def pythonTestLocation: String = "tester/src/test/python/spinal/InternalClockTester" + override def createToplevel: Component = new InternalClockTester +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/InternalClockTester.scala b/tester/src/test/scala/spinal/tester/scalatest/InternalClockTester.scala deleted file mode 100644 index fc5f998990..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/InternalClockTester.scala +++ /dev/null @@ -1,76 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.lib._ - - -object InternalClockTester{ - class ClockGeneratorSub extends Component{ - val io = NoData - - val internalClock = CounterFreeRun(16)(0) - - val initCounter = RegInit(U(7)) - val srcReset = initCounter =/= U(0) - when(srcReset){ - initCounter := initCounter - U(1) - } - val internalClk = ClockDomain(internalClock) - val internalReset = Bool() - - val resetBuffer = new ClockingArea(internalClk){ - val internalReset = BufferCC(srcReset) - } - internalReset := resetBuffer.internalReset - - val internalClockDomain = ClockDomain(internalClock,internalReset) - } - - class ClockGenerator extends Component{ - val io = NoData - val sub = new ClockGeneratorSub - } - - class CounterComponentSub extends Component{ - val io = new Bundle{ - val counter = out UInt(8 bit) - } - val counter = Counter(256) - counter.increment() - io.counter := counter - } - - class CounterComponent extends Component{ - val io = new Bundle{ - val counter = out UInt(8 bit) - } - val sub = new CounterComponentSub - io <> sub.io - } -} - -import spinal.tester.scalatest.InternalClockTester._ -class InternalClockTester extends Component { - val io = new Bundle { - val internalClkCounter = out UInt(8 bit) - } - val clockGenerator = new ClockGenerator - - val internClockDomain = new ClockingArea(clockGenerator.sub.internalClockDomain){ - val counterComponent = new CounterComponent - io.internalClkCounter := counterComponent.io.counter - } -} - - - -//class InternalClockTesterGhdlBoot extends SpinalTesterGhdlBase { -// override def getName: String = "InternalClockTester" -// override def createToplevel: Component = new InternalClockTester -//} - -class InternalClockTesterCocotbBoot extends SpinalTesterCocotbBase { - override def getName: String = "InternalClockTester" - override def pythonTestLocation: String = "tester/src/test/python/spinal/InternalClockTester" - override def createToplevel: Component = new InternalClockTester -} \ No newline at end of file From 63bad53dfda26efc25fcee88cf00015d65c1b3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 15 Dec 2022 21:43:15 +0100 Subject: [PATCH 111/120] refactor: remove some demo stuff This is only demo stuff. I understand that at the beginning it was easier to put everything at the same place but now it is too big and needs more structuring. So if you are creating a presentation with a demo you want to unit test, please put the demo and its tests into your repository (for instance in the same repository where you put the presentation). --- .../spinal/demo/general/GrayCounter.scala | 21 -- .../scala/spinal/demo/mandelbrot/Common.scala | 33 --- .../demo/mandelbrot/FrameTaskSolver.scala | 192 ----------------- .../demo/mandelbrot/MandelbrotCore.scala | 102 --------- .../demo/mandelbrot/MandelbrotGui.scala | 199 ------------------ .../demo/mandelbrot/MandelbrotSblDemo.scala | 155 -------------- .../test/scala/spinal/tester/code/Play1.scala | 25 --- .../spinal/tester/code/Presentation.scala | 27 --- .../tester/scalatest/MandelbrotTester.scala | 35 --- 9 files changed, 789 deletions(-) delete mode 100644 tester/src/test/scala/spinal/demo/general/GrayCounter.scala delete mode 100644 tester/src/test/scala/spinal/demo/mandelbrot/Common.scala delete mode 100644 tester/src/test/scala/spinal/demo/mandelbrot/FrameTaskSolver.scala delete mode 100644 tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotCore.scala delete mode 100644 tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotGui.scala delete mode 100644 tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotSblDemo.scala delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/MandelbrotTester.scala diff --git a/tester/src/test/scala/spinal/demo/general/GrayCounter.scala b/tester/src/test/scala/spinal/demo/general/GrayCounter.scala deleted file mode 100644 index 07c30dba28..0000000000 --- a/tester/src/test/scala/spinal/demo/general/GrayCounter.scala +++ /dev/null @@ -1,21 +0,0 @@ -package spinal.demo.general -import spinal.core._ - -object GrayCounter { - def apply(n: Int, enable: Bool): UInt = { - val gray = RegInit(U(0, n bit)) - val even = RegInit(True) - val word = Cat(True, gray(n-3 downto 0), even) - when(enable) { - var found = False - for (i <- 0 until n) { - when(word(i) && !found) { - gray(i) := !gray(i) - found \= True - } - } - even := !even - } - return gray - } -} diff --git a/tester/src/test/scala/spinal/demo/mandelbrot/Common.scala b/tester/src/test/scala/spinal/demo/mandelbrot/Common.scala deleted file mode 100644 index 0625fd31e1..0000000000 --- a/tester/src/test/scala/spinal/demo/mandelbrot/Common.scala +++ /dev/null @@ -1,33 +0,0 @@ -package spinal.demo.mandelbrot - -import spinal.core._ - -import scala.util.Random - -//This class is used everywhere into the mandelbrot core as "generic" "construction" parameter -case class MandelbrotCoreParameters(iterationLimit: Int, - pixelTaskSolverCount: Int, - screenResX: Int, - screenResY: Int, - fixExp: Int, - fixWidth: Int) { - def fix = SFix(fixExp exp, fixWidth bit) - def iterationWidth = log2Up(iterationLimit + 1) - - val uid : Int = Random.nextInt() -} - - -case class FrameTask(p: MandelbrotCoreParameters) extends Bundle { - val start = SFix2D(p.fixExp exp, p.fixWidth bit) - val inc = SFix2D(p.fixExp - 4 exp, p.fixWidth + 8 bit) - - def fullRangeSFix = SFix(p.fixExp exp, p.fixWidth + 12 bit) -} - -case class PixelTask(p: MandelbrotCoreParameters) extends Bundle { - val mandelbrotPosition = SFix2D(p.fix) -} -case class PixelResult(p: MandelbrotCoreParameters) extends Bundle { - val iteration = UInt(p.iterationWidth bit) -} \ No newline at end of file diff --git a/tester/src/test/scala/spinal/demo/mandelbrot/FrameTaskSolver.scala b/tester/src/test/scala/spinal/demo/mandelbrot/FrameTaskSolver.scala deleted file mode 100644 index 86c29ab7e7..0000000000 --- a/tester/src/test/scala/spinal/demo/mandelbrot/FrameTaskSolver.scala +++ /dev/null @@ -1,192 +0,0 @@ -package spinal.demo.mandelbrot - -import spinal.core._ -import spinal.lib._ -import spinal.lib.math.SIntMath - - -class FrameTaskSolver(p: MandelbrotCoreParameters) extends Component { - val io = new Bundle { - val frameTask = slave Stream FrameTask(p) - val pixelResult = master Stream Fragment(PixelResult(p)) - } - - val pixelTaskGenerator = new PixelTaskGenerator(p) - val pixelTaskDispatcher = new StreamDispatcherSequencial(Fragment(PixelTask(p)), p.pixelTaskSolverCount) - val pixelTaskSolver = List.fill(p.pixelTaskSolverCount)(new PixelTaskSolver(p)) - val pixelResultArbiter = StreamArbiterFactory.sequentialOrder.build(Fragment(PixelResult(p)), p.pixelTaskSolverCount) - - pixelTaskGenerator.io.frameTask << io.frameTask - pixelTaskDispatcher.io.input <-/< pixelTaskGenerator.io.pixelTask - for (solverId <- 0 until p.pixelTaskSolverCount) { - pixelTaskSolver(solverId).io.pixelTask << pixelTaskDispatcher.io.outputs(solverId) - pixelResultArbiter.io.inputs(solverId) << pixelTaskSolver(solverId).io.pixelResult - } - io.pixelResult <-< pixelResultArbiter.io.output -} - -// The scala-like way to do the FrameTaskSolver stuff is : - -// val pixelTaskGenerator = new PixelTaskGenerator(p) -// pixelTaskGenerator.io.frameTask << io.frameTask -// -// val pixelTaskDispatcher = new DispatcherInOrder(Fragment(PixelTask(p)), p.unitCount) -// pixelTaskDispatcher.io.input <-/< pixelTaskGenerator.io.pixelTask -// -// val pixelTaskSolver = List.fill(p.pixelTaskSolverCount)(new PixelTaskSolver(p)) -// (pixelTaskSolver, pixelTaskDispatcher.io.outputs).zipped.foreach(_.io.pixelTask <-/< _) -// -// val pixelTaskResultArbiter = StreamArbiter.inOrder.build(Fragment(PixelResult(p)), p.unitCount) -// (pixelTaskSolver, pixelTaskResultArbiter.io.inputs).zipped.foreach(_.io.result >/> _) -// -// pixelTaskResultArbiter.io.output >-> io.pixelResult - - -class PixelTaskGenerator(p: MandelbrotCoreParameters) extends Component { - val io = new Bundle { - val frameTask = slave Stream FrameTask(p) - val pixelTask = master Stream Fragment(PixelTask(p)) - } - - val positionOnScreen = Reg(UInt2D(log2Up(p.screenResX) bit, log2Up(p.screenResY) bit)) - val positionOnMandelbrot = Reg(SFix2D(io.frameTask.fullRangeSFix)) - val setup = RegInit(True) - - val solverTask = Stream(Fragment(PixelTask(p))) - - io.frameTask.ready := !io.frameTask.valid - - - when(io.frameTask.ready) { - setup := True - } - - when(io.frameTask.valid && solverTask.ready) { - when(setup) { - setup := False - positionOnScreen.x := 0 - positionOnScreen.y := 0 - positionOnMandelbrot := io.frameTask.start - }otherwise { - when(positionOnScreen.x =/= p.screenResX - 1) { - positionOnScreen.x := positionOnScreen.x + 1 - positionOnMandelbrot.x := positionOnMandelbrot.x + io.frameTask.inc.x - }otherwise { - positionOnScreen.x := 0 - positionOnMandelbrot.x := io.frameTask.start.x - when(positionOnScreen.y =/= p.screenResY - 1) { - positionOnScreen.y := positionOnScreen.y + 1 - positionOnMandelbrot.y := positionOnMandelbrot.y + io.frameTask.inc.y - }otherwise { - positionOnMandelbrot.y := io.frameTask.start.y - io.frameTask.ready := True //Asynchronous acknoledge into synchronous space <3 - } - } - } - } - - solverTask.valid := io.frameTask.valid && !setup; - solverTask.last := io.frameTask.ready - solverTask.fragment.mandelbrotPosition := positionOnMandelbrot.truncated - solverTask >-> io.pixelTask - -} - -class PixelTaskSolver(p: MandelbrotCoreParameters) extends Component { - val io = new Bundle { - val pixelTask = slave Stream Fragment(PixelTask(p)) - val pixelResult = master Stream Fragment(PixelResult(p)) - } - - //It's the context definition used by each stage of the pipeline, Each task are translated to context ("thread") - class Context extends Bundle { - val task = PixelTask(p) - val lastPixel = Bool() - val done = Bool() - val order = UInt(5 bit) - //Used to reorder result in same oder than input task - val iteration = UInt(p.iterationWidth bit) - val z = SFix2D(p.fix) - } - - //Extended context with x*x y*y x*y result - class Stage2Context extends Context { - val zXzX = p.fix - val zYzY = p.fix - val zXzY = p.fix - } - - val insertTaskOrder = Counter(32, io.pixelTask.fire) - - //Task to insert into the pipeline - val taskToInsert: Stream[Context] = io.pixelTask.translateInto(Stream(new Context))((to, from) => { - to.task := from.fragment - to.lastPixel := from.last - to.done := False - to.order := insertTaskOrder - to.iteration := 0 - to.z := from.fragment.mandelbrotPosition - }) - val loopBack = RegFlow(new Context) - //Loop back from end of pipeline - val stage0 = StreamFlowArbiter(taskToInsert, loopBack) //First stage - - - //Stage1 is a routing stage - val stage1 = DelayWithInit(stage0, 2)((reg) => reg.valid.init(False)) - - - - //Stage2 get multiplication result of x*x y*y and x*y - val stage2 = RegFlow(new Stage2Context) - - def fixMul(a: SFix, b: SFix): SFix = { - val ret = SFix(a.maxExp + b.maxExp + 1 exp, a.bitCount + b.bitCount bit) - // SIntMath.mul is a pipelined implementation of the signed multiplication operator - //(leftSigned, rightSigned, number of bit per multiplicator, trunk bits bellow this limit, ...) - ret.raw := SIntMath.mul(a.raw, b.raw, 17, p.fixWidth - p.fixExp, 1, (stage, level) => RegNext(stage)) - ret - - // return a*b - } - - - stage2.zXzX := fixMul(stage1.z.x, stage1.z.x).truncated - stage2.zYzY := fixMul(stage1.z.y, stage1.z.y).truncated - stage2.zXzY := fixMul(stage1.z.x, stage1.z.y).truncated - val stage1ToStage2Latency = LatencyAnalysis(stage1.z.x.raw, stage2.zXzX.raw) - 1 - stage2 assignSomeByName DelayWithInit(stage1, stage1ToStage2Latency)((reg) => reg.valid.init(False)) - - //Stage3 calculate next position of the iteration (zX,zY) - // Increment the iteration count if was not done - // calculate if the "Thread" has rush a end condition (iteration > N, x*x+y*y + 4) - val stage3 = RegFlow(new Context) - stage3 assignAllByName stage2 - stage3.allowOverride - stage3.z.x := stage2.zXzX - stage2.zYzY + stage2.task.mandelbrotPosition.x - stage3.z.y := ((stage2.zXzY << 1) + stage2.task.mandelbrotPosition.y).truncated - when(!stage2.done) { - stage3.iteration := stage2.iteration + 1 - } - when(stage2.iteration >= p.iterationLimit | stage2.zXzX + stage2.zYzY >= 4.0) { - stage3.done := True - } - - - //End Stage put to the output the result if it's finished and in right order - // else put it into the feedback to redo iteration or to waiting - val result = Stream(Fragment(PixelResult(p))) - val resultOrder = Counter(32, result.fire) - val readyForResult = stage3.done && resultOrder === stage3.order - - - result.valid := stage3.valid && readyForResult - result.last := stage3.lastPixel - result.fragment.iteration := stage3.iteration - 1 - - - result >-> io.pixelResult - - loopBack.valid := stage3.valid && ((!readyForResult) || (!result.ready)) - loopBack.payload := stage3.payload -} diff --git a/tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotCore.scala b/tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotCore.scala deleted file mode 100644 index e4aa529da4..0000000000 --- a/tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotCore.scala +++ /dev/null @@ -1,102 +0,0 @@ -package spinal.demo.mandelbrot - -import spinal.core._ -import spinal.lib._ - -case class MandelbrotCoreConfig(p: MandelbrotCoreParameters) extends Bundle { - val frameTaskFilterEnable = Bool() -} - -class CmdInterface(p: MandelbrotCoreParameters) extends Component { - val io = new Bundle { - val cmdPort = slave Flow Fragment(Bits(8 bit)) - val retPort = master Stream Fragment(Bits(8 bit)) - val frameTask = master Flow FrameTask(p) - val coreConfig = out(MandelbrotCoreConfig(p)) - } - - io.frameTask << io.cmdPort.filterHeader(0x01).toFlowOf(FrameTask(p)) - io.coreConfig := io.cmdPort.filterHeader(0x02).toRegOf(MandelbrotCoreConfig(p)) - io.coreConfig.frameTaskFilterEnable init (False) - - val passport = io.cmdPort.eventOn(0xFF).translateWith(S(p.uid, 32 bit)).fragmentTransaction(8) - io.retPort << passport -} - -class FrameTaskFilter(p: MandelbrotCoreParameters) extends Component { - val io = new Bundle { - val input = slave Flow FrameTask(p) - val output = master Flow FrameTask(p) - } - - val filterIn = io.input.toReg - filterIn.start.x init (-1.0) - filterIn.start.y init (-1.0) - filterIn.inc.x init (2.0 / p.screenResX) - filterIn.inc.y init (2.0 / p.screenResY) - - def rcFilter(in: SFix, tao: Double, enable: Bool, enableHz: Double): SFix = { - val shiftRight = log2Up(BigDecimal(enableHz * tao).toBigInt) - val out = Reg(in) init (0) - when(enable) { - out := RegNext(((in - out) >>| shiftRight)) + out - } - out - } - def rcChainFilter(in: SFix, taos: Seq[Double], enable: Bool, enableHz: Double): SFix = { - var ptr = in - for (tao <- taos) { - ptr = rcFilter(ptr, tao, enable, enableHz) - } - ptr - } - - val clkHz = ClockDomain.current.frequency.getValue - val filterTaos = Seq(1.0, 2.0) - val filterHz = 120.0 - - val filterEnable = RegNext(CounterFreeRun((clkHz / filterHz).toInt).willOverflow) //TODO periodic pulse lib - - io.output.valid := True - io.output.start.x := rcChainFilter(filterIn.start.x, filterTaos, filterEnable, filterHz) - io.output.start.y := rcChainFilter(filterIn.start.y, filterTaos, filterEnable, filterHz) - io.output.inc.x := rcChainFilter(filterIn.inc.x, filterTaos, filterEnable, filterHz) - io.output.inc.y := rcChainFilter(filterIn.inc.y, filterTaos, filterEnable, filterHz) -} - - -class MandelbrotCore(p: MandelbrotCoreParameters) extends Component { - val io = new Bundle { - val cmdPort = slave Flow Fragment(Bits(8 bit)) - val retPort = master Stream Fragment(Bits(8 bit)) - - val pixelResult = master Stream Fragment(PixelResult(p)) - } - - val cmdInterface = new CmdInterface(p) - cmdInterface.io.cmdPort << io.cmdPort - cmdInterface.io.retPort >> io.retPort - - val frameTaskFilter = new FrameTaskFilter(p) - frameTaskFilter.io.input << cmdInterface.io.frameTask - - val frameTaskFilterBypass = Mux( - cmdInterface.io.coreConfig.frameTaskFilterEnable, - frameTaskFilter.io.output, - cmdInterface.io.frameTask - ) - - val frameTaskSolver = new FrameTaskSolver(p) - frameTaskSolver.io.frameTask <-< frameTaskFilterBypass.toStream - - // Force a initial frametask into the system. - // By this way, when the system is reseted, it draw directly something - frameTaskSolver.io.frameTask.valid init (True) - frameTaskSolver.io.frameTask.start.x init (-1.0) - frameTaskSolver.io.frameTask.start.y init (-1.0) - frameTaskSolver.io.frameTask.inc.x init (2.0 / p.screenResX) - frameTaskSolver.io.frameTask.inc.y init (2.0 / p.screenResY) - - io.pixelResult << frameTaskSolver.io.pixelResult - -} diff --git a/tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotGui.scala b/tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotGui.scala deleted file mode 100644 index 8eadf46784..0000000000 --- a/tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotGui.scala +++ /dev/null @@ -1,199 +0,0 @@ -//package spinal.demo.mandelbrot -// -//import net.liftweb.json.DefaultFormats -//import net.liftweb.json.JsonAST.JValue -//import spinal.debugger.gui._ -//import spinal.lib.BitAggregator -// -//import scalafx.Includes._ -//import scalafx.application.Platform -//import scalafx.event.ActionEvent -//import scalafx.scene.canvas.Canvas -//import scalafx.scene.control.RadioButton -//import scalafx.scene.input.{MouseButton, MouseEvent} -//import scalafx.scene.layout.VBox -//import scalafx.scene.{Group, Scene} -//import scalafx.stage.Stage -// -// -//class MandelbrotManager(address: Seq[Byte], hal: IBytePacketHal, r: JValue) extends PeripheralManager(address, hal) { -// -// implicit val formats = DefaultFormats // Brings in default date formats etc. -// -// val p = r.\("p").extract[MandelbrotCoreParameters] -// -// sendConfig -// sendCoord(-1.0, -1.0, 1.0, 1.0) -// -// openGui -// // sendCoord(-1.0,-1.0,0.0,1.0) -// // sendCoord(-1.0,-1.0,1.0,1.0) -// implicit def easyByte(i: Int) = i.toByte -// def sendCoord(xStart: Double, yStart: Double, xEnd: Double, yEnd: Double) { -// val aggregator = new BitAggregator -// aggregator.add(0x01, 8) -// aggregator.add(BigDecimal(xStart * Math.pow(2, p.fixWidth - p.fixExp - 1)).toBigInt, p.fixWidth) -// aggregator.add(BigDecimal(yStart * Math.pow(2, p.fixWidth - p.fixExp - 1)).toBigInt, p.fixWidth) -// aggregator.add(BigDecimal((xEnd - xStart) / p.screenResX * Math.pow(2, p.fixWidth + 8 - 1 - (p.fixExp - 4))).toBigInt, p.fixWidth + 8) -// aggregator.add(BigDecimal((yEnd - yStart) / p.screenResY * Math.pow(2, p.fixWidth + 8 - 1 - (p.fixExp - 4))).toBigInt, p.fixWidth + 8) -// tx(aggregator.toBytes) -// } -// -// def sendConfig: Unit = { -// val aggregator = new BitAggregator -// aggregator.add(0x02, 8) -// aggregator.add(frameTaskFilterEnable) -// tx(aggregator.toBytes) -// } -// -// override def rx(packet: Seq[Byte]): Unit = { -// -// } -// -// var xStart = -1.0 -// var yStart = -1.0 -// var xEnd = 1.0 -// var yEnd = 1.0 -// var frameTaskFilterEnable = true -// -// -// def openGui: Unit = { -// Platform.runLater { -// -// val canvasBack = new Canvas(p.screenResX/2,p.screenResY/2) -// val canvasFront = new Canvas(p.screenResX/2,p.screenResY/2) -// def resX = canvasFront.getWidth.toInt -// def resY = canvasFront.getHeight.toInt -// val frameTaskFilterEnableBt = new RadioButton() { -// maxWidth = 200 -// maxHeight = 50 -// text = "Frame task filter" -// -// onAction = { -// e: ActionEvent => { -// frameTaskFilterEnable = delegate.isSelected -// sendConfig -// } -// } -// } -// -// val rootPane = new Group -// rootPane.children = List(canvasBack, canvasFront) -// canvasFront.toFront() -// val backGc = canvasBack.graphicsContext2D -// val frontGc = canvasFront.graphicsContext2D -// -// def drawMandelbrot: Unit = { -// val w = backGc.getPixelWriter -// val incX = (xEnd - xStart) / resX -// val incY = (yEnd - yStart) / resY -// for (y <- 0 until resY) { -// for (x <- 0 until resX) { -// val cx = xStart + incX * x -// val cy = yStart + incY * y -// def getIterCount: Int = { -// var mx = 0.0 -// var my = 0.0 -// val iterMax = 255 -// for (i <- 0 until iterMax) { -// val temp = mx * mx - my * my + cx -// my = 2.0 * mx * my + cy -// mx = temp -// if (mx * mx + my * my > 4) return i -// } -// return iterMax -// } -// w.setArgb(x, y, getIterCount + (0xFF000000)) -// } -// } -// } -// drawMandelbrot -// -// var dragStartX = 0.0 -// var dragStartY = 0.0 -// canvasFront.onMousePressed = (e: MouseEvent) => { -// // if (e.button == MouseButton.PRIMARY) { -// // dragStartX = e.x -// // dragStartY = e.y -// // } -// if (e.button == MouseButton.PRIMARY) { -// val newXStart = xStart + (xEnd - xStart) * (e.x / resX) * 0.5 -// val newYStart = yStart + (yEnd - yStart) * (e.y / resY) * 0.5 -// -// xEnd = xEnd - (xEnd - xStart) * (1 - (e.x / resX)) * 0.5 -// yEnd = yEnd - (yEnd - yStart) * (1 - (e.y / resY)) * 0.5 -// -// xStart = newXStart -// yStart = newYStart -// -// drawMandelbrot -// sendCoord(xStart, yStart, xEnd, yEnd) -// } -// if (e.button == MouseButton.SECONDARY) { -// val newXStart = xStart - (xEnd - xStart) * (e.x / resX) -// val newYStart = yStart - (yEnd - yStart) * (e.y / resY) -// -// xEnd = xEnd + (xEnd - xStart) * (1 - (e.x / resX)) -// yEnd = yEnd + (yEnd - yStart) * (1 - (e.y / resY)) -// -// xStart = newXStart -// yStart = newYStart -// -// drawMandelbrot -// sendCoord(xStart, yStart, xEnd, yEnd) -// } -// } -// -// // canvasFront.onMouseDragged = (e: MouseEvent) => { -// // if (e.button == MouseButton.PRIMARY) { -// // frontGc.clearRect(0, 0, resX, resY) -// // frontGc.setStroke(Color.White); -// // frontGc.strokeRect(dragStartX, dragStartY, -dragStartX + e.x, -dragStartY + e.y) -// // } -// // } -// // -// // canvasFront.onMouseReleased = (e: MouseEvent) => { -// // if (e.button == MouseButton.PRIMARY) { -// // frontGc.clearRect(0, 0, resX, resY) -// // val newXStart = xStart + (xEnd - xStart) * (dragStartX / resX) -// // val newYStart = yStart + (yEnd - yStart) * (dragStartY / resY) -// // -// // xEnd = xStart + (xEnd - xStart) * (e.x / resX) -// // yEnd = yStart + (yEnd - yStart) * (e.y / resY) -// // -// // xStart = newXStart -// // yStart = newYStart -// // -// // drawMandelbrot -// // sendCoord(xStart, yStart, xEnd, yEnd) -// // } -// // } -// -// -// val stage = new Stage { -// title = "Mandelbrot" -// scene = new Scene { -// val vBox = new VBox() { -// children = Seq( -// rootPane, -// frameTaskFilterEnableBt) -// } -// root = vBox -// } -// show() -// } -// } -// } -//} -// -//object MandelbrotGuiMain { -// def main(args: Array[String]) { -// PeripheralManagerFactoryRegistry.peripheralManagerFactories += new IPeripheralManagerFactory { -// override def newPeripheral(address: Seq[Byte], hal: IBytePacketHal, r: JValue): Unit = new MandelbrotManager(address, hal, r) -// override def getPassportKind(): String = "mandelbrotCore" -// } -// -// DebuggerGui.main(args) -// } -//} -// diff --git a/tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotSblDemo.scala b/tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotSblDemo.scala deleted file mode 100644 index 3d2d8e5ee4..0000000000 --- a/tester/src/test/scala/spinal/demo/mandelbrot/MandelbrotSblDemo.scala +++ /dev/null @@ -1,155 +0,0 @@ -package spinal.demo.mandelbrot - - -import java.awt.Color - -import spinal.core._ -import spinal.lib._ -import spinal.lib.experimental.bus.sbl._ -import spinal.lib.com.uart._ -import spinal.lib.graphic.{RgbConfig, Rgb} -import spinal.lib.graphic.vga._ - - -class MandelbrotSblDemo(frameAddressOffset: Int, p: MandelbrotCoreParameters, coreClk: ClockDomain, vgaMemoryClk: ClockDomain, vgaClk: ClockDomain) extends Component { - val memoryBusConfig = SblConfig(30, 32) - val rgbConfig = RgbConfig(8, 8, 8) - - val io = new Bundle { - val uart = master(Uart()) - - val mandelbrotWriteCmd = master Stream SblWriteCmd(memoryBusConfig) - - val vgaReadCmd = master Stream SblReadCmd(memoryBusConfig) - val vgaReadRet = slave Flow SblReadRet(memoryBusConfig) - - val vga = master(Vga(rgbConfig)) - } - val core = new ClockingArea(coreClk) { - val uart = new Area { - val ctrl = new UartCtrl() - ctrl.io.config.clockDivider := BigInt((coreClk.frequency.getValue / 57.6e3 / 8).toLong) - ctrl.io.config.frame.dataLength := 7 - ctrl.io.config.frame.parity := UartParityType.NONE - ctrl.io.config.frame.stop := UartStopType.ONE - ctrl.io.uart <> io.uart - - val (flowFragment, _) = ctrl.io.read.toFlow.toFlowFragmentBitsAndReset() - } - val mandelbrot = new Area { - val core = new MandelbrotCore(p) - core.io.cmdPort << uart.flowFragment - core.io.retPort.toStreamBits() >> uart.ctrl.io.write - - //Mandelbrot iteration to color palette definition - val palette = Seq( - (0/255.0 -> new Color(0,0,0)), - (64/255.0 -> new Color(128,0,255)), - (100/255.0 -> new Color(180,32,0)), - (128/255.0 -> new Color(200,64,0)), - (150/255.0 -> new Color(220,100,0)), - (255/255.0 -> new Color(255,255,0))) - - //Create the rom for the mandelbrot iteration count to color transformation - val paletteRom = Mem((0 to p.iterationLimit).map(iteration => { - val iterationFactor = 1.0 * iteration / (p.iterationLimit) - val rgb = Rgb(rgbConfig) - var palletOffset = Math.max(0, palette.indexWhere(_._1 >= iterationFactor) - 1) - val palletPre = palette(palletOffset) - val palletPost = palette(palletOffset + 1) - val ratio = (iterationFactor - palletPre._1) / (palletPost._1 - palletPre._1) - - - rgb.r := ((palletPre._2.getRed * (1.0 - ratio) + palletPost._2.getRed * ratio) / 255 * ((1 << rgbConfig.rWidth) - 1)).toInt - rgb.g := ((palletPre._2.getGreen * (1.0 - ratio) + palletPost._2.getGreen * ratio) / 255 * ((1 << rgbConfig.gWidth) - 1)).toInt - rgb.b := ((palletPre._2.getBlue * (1.0 - ratio) + palletPost._2.getBlue * ratio) / 255 * ((1 << rgbConfig.bWidth) - 1)).toInt - - rgb - })) - - //Translate the pixelResult stream into a colorResult by using the rom - val colorResult = paletteRom.streamReadSync(core.io.pixelResult.translateWith(core.io.pixelResult.fragment.iteration), core.io.pixelResult.last) - - //Take mandelbrot pixelResults and translate them into simple memory access - val counter = Reg(UInt(memoryBusConfig.addressWidth bit)) init (0) - when(io.mandelbrotWriteCmd.fire) { - counter := counter + 1 - when(colorResult.linked) { - counter := 0 - } - } - io.mandelbrotWriteCmd.translateFrom(colorResult)((to, from) => { - to.address := counter - to.data := (B(from.value)).resized - }) - } - } - val vga = new ClockingArea(vgaClk) { - //Create VGA controller - val ctrl = new VgaCtrl(rgbConfig, 12) - ctrl.io.softReset := False - ctrl.io.timings.setAs_h640_v480_r60 //Static timing for 640*480 pixel at 60HZ - io.vga := ctrl.io.vga - - val newFrameEvent = ctrl.io.frameStart.genEvent - } - val vgaMemory = new ClockingArea(vgaMemoryClk) { - //Create the DMA for this VGA controller - val dma = new SblReadDma(memoryBusConfig) - - //Synchronise the frameStart event from the VGA to the current clock domain - val frameStart = StreamCCByToggle(vga.newFrameEvent, vgaClk, vgaMemoryClk) - //Translate it into a DMA command and send it into the DMA -// dma.io.cmd.translateFrom(frameStart)((to, from) => { -// to.offset := frameAddressOffset -// to.endAt := frameAddressOffset + p.screenResX * p.screenResY - 1 -// }) - - dma.io.cmd.arbitrationFrom(frameStart) - dma.io.cmd.offset := frameAddressOffset - dma.io.cmd.endAt := frameAddressOffset + p.screenResX * p.screenResY - 1 - - - //Count pendings command on the vgaRead bus - val pendingCmd = Reg(UInt(6 bit)) init (0) - when(io.vgaReadCmd.fire =/= io.vgaReadRet.fire) { - when(io.vgaReadCmd.fire) { - pendingCmd := pendingCmd + 1 - } otherwise { - pendingCmd := pendingCmd - 1 - } - } - - //Translate bus memory bus read Flow into a color read flow -// val colorFlow = Flow(rgbType).translateFrom(io.vgaReadRet)((to, from) => { -// to.assignFromBits(from.data) -// }) - - val colorFlow = Flow(Rgb(rgbConfig)) - colorFlow.valid := io.vgaReadRet.valid - colorFlow.payload.assignFromBits(io.vgaReadRet.payload.data) - - //Translate the color Flow ino a Stream and synchronise/bufferise to the VgaClk by using a cross clock fifo - val fifoSize = 512 - val (colorStream, colorStreamOccupancy) = colorFlow.toStream.queueWithPushOccupancy(fifoSize, vgaMemoryClk, vgaClk) - vga.ctrl.io.pixels << colorStream - - //Halt the vga read cmd stream if there is to mutch pending command or if the fifo is near than full - io.vgaReadCmd << dma.io.sblReadCmd.haltWhen(pendingCmd === pendingCmd.maxValue || RegNext(colorStreamOccupancy) > fifoSize - 128) - - } -} - - -object MandelbrotSblDemo { - def main(args: Array[String]) { - for(i <- 0 until 1){ - SpinalVhdl({ - val vgaClock = ClockDomain.external("vga") - val vgaMemoryClock = ClockDomain.external("vgaMemory") - val coreClock = ClockDomain.external("core",frequency=FixedFrequency(100 MHz)) - new MandelbrotSblDemo(0, new MandelbrotCoreParameters(256, 6, 640, 480, 7, 17 * 3), coreClock, vgaMemoryClock, vgaClock) - }) - } - } -} diff --git a/tester/src/test/scala/spinal/tester/code/Play1.scala b/tester/src/test/scala/spinal/tester/code/Play1.scala index 0dbf230607..ab381e787e 100644 --- a/tester/src/test/scala/spinal/tester/code/Play1.scala +++ b/tester/src/test/scala/spinal/tester/code/Play1.scala @@ -5,7 +5,6 @@ import java.io.InputStream import java.util.concurrent.CyclicBarrier import spinal.core._ import spinal.core.fiber._ -import spinal.demo.mandelbrot.{MandelbrotCoreParameters, MandelbrotSblDemo} import spinal.lib._ import spinal.lib.bus.amba3.apb.{Apb3, Apb3Config, Apb3Gpio} import spinal.lib.bus.amba4.axi.{Axi4, Axi4SpecRenamer} @@ -1498,30 +1497,6 @@ object PlayLoop { } } - -// -//import org.scalameter.api._ -// -//object RangeBenchmark extends Bench.LocalTime { -//// val time = measure { -//// for (i <- 0 until 100000) yield i -//// } -//// println(s"Total time: $time") -//// MandelbrotSblDemo.main(null) -//// val sizes = Gen.range("size")(300000, 1500000, 300000) -//// -//// val ranges = for { -//// size <- sizes -//// } yield 0 until size -//// -//// performance of "Range" in { -//// measure method "map" in { -//// using(ranges) in { -//// r => r.map(_ + 1) -//// } -//// } -//// } -//} //object PlayBench { // // diff --git a/tester/src/test/scala/spinal/tester/code/Presentation.scala b/tester/src/test/scala/spinal/tester/code/Presentation.scala index 8720aa482f..35b8118f8f 100644 --- a/tester/src/test/scala/spinal/tester/code/Presentation.scala +++ b/tester/src/test/scala/spinal/tester/code/Presentation.scala @@ -2,7 +2,6 @@ package spinal.tester.code import spinal.core._ -import spinal.demo.mandelbrot._ import spinal.lib._ import spinal.lib.bus.amba3.apb.{Apb3SlaveFactory, Apb3, Apb3Config} import spinal.lib.bus.amba4.axi.{Axi4, Axi4Config} @@ -815,32 +814,6 @@ object t8_B2 { } - -object t9 { - - class FrameTaskSolver(p: MandelbrotCoreParameters) extends Component { - val io = new Bundle { - val frameTask = slave Stream FrameTask(p) - val pixelResult = master Stream Fragment(PixelResult(p)) - } - - val pixelTaskGenerator = new PixelTaskGenerator(p) - val pixelTaskDispatcher = new StreamDispatcherSequencial(Fragment(PixelTask(p)), p.pixelTaskSolverCount) - val pixelTaskSolver = for (i <- 0 until p.pixelTaskSolverCount) yield new PixelTaskSolver(p) - val pixelResultArbiter = StreamArbiterFactory.sequentialOrder.build(Fragment(PixelResult(p)), p.pixelTaskSolverCount) - - pixelTaskGenerator.io.frameTask << io.frameTask - pixelTaskDispatcher.io.input <-/< pixelTaskGenerator.io.pixelTask - for (solverId <- 0 until p.pixelTaskSolverCount) { - pixelTaskSolver(solverId).io.pixelTask <-/< pixelTaskDispatcher.io.outputs(solverId) - pixelResultArbiter.io.inputs(solverId) Date: Thu, 15 Dec 2022 21:45:33 +0100 Subject: [PATCH 112/120] refactor: move OperatorTester --- .../scala/integration}/OperatorTester.scala | 26 +++---------------- 1 file changed, 4 insertions(+), 22 deletions(-) rename {tester/src/test/scala/spinal/tester/scalatest => core/src/test/scala/integration}/OperatorTester.scala (92%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/OperatorTester.scala b/core/src/test/scala/integration/OperatorTester.scala similarity index 92% rename from tester/src/test/scala/spinal/tester/scalatest/OperatorTester.scala rename to core/src/test/scala/integration/OperatorTester.scala index b2002b8d25..e91c69b786 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/OperatorTester.scala +++ b/core/src/test/scala/integration/OperatorTester.scala @@ -1,26 +1,8 @@ -/* - * SpinalHDL - * Copyright (c) Dolu, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ - -package spinal.tester.scalatest +package integration + +import spinal.tester.SpinalTesterCocotbBase import spinal.core._ -import spinal.lib._ -import spinal.tester.scalatest.OperatorTester.OperatorTester object OperatorTester { object State extends SpinalEnum{ @@ -295,7 +277,7 @@ object OperatorTester { class OperatorTesterCocotbBoot extends SpinalTesterCocotbBase { override def getName: String = "OperatorTester" - override def createToplevel: Component = new OperatorTester.OperatorTester + override def createToplevel: Component = new OperatorTester.OperatorTester override def pythonTestLocation: String = "tester/src/test/python/spinal/OperatorTester" } From 11f0df13dba1ae3171b640e1c9f1913b1949855f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 15 Dec 2022 21:57:03 +0100 Subject: [PATCH 113/120] refactor: move PllAAssertSDeassertTester --- .../test/scala/spinal/core/ClockDomain.scala | 39 +++++++++++++- .../scalatest/PllAAssertSDeassertTester.scala | 51 ------------------- 2 files changed, 38 insertions(+), 52 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/PllAAssertSDeassertTester.scala diff --git a/core/src/test/scala/spinal/core/ClockDomain.scala b/core/src/test/scala/spinal/core/ClockDomain.scala index 6bbb6e0f6a..a19568a8a4 100644 --- a/core/src/test/scala/spinal/core/ClockDomain.scala +++ b/core/src/test/scala/spinal/core/ClockDomain.scala @@ -3,7 +3,7 @@ package spinal.core import scala.util.Random import spinal.core.sim._ -import spinal.lib.{BufferCC, Counter, CounterFreeRun, NoData} +import spinal.lib.{BufferCC, Counter, CounterFreeRun, NoData, ResetCtrl} import spinal.tester.{SpinalSimFunSuite, SpinalTesterCocotbBase} object ClockDomainConfigTester { @@ -481,3 +481,40 @@ class InternalClockTesterCocotbBoot extends SpinalTesterCocotbBase { override def pythonTestLocation: String = "tester/src/test/python/spinal/InternalClockTester" override def createToplevel: Component = new InternalClockTester } + +object PllAAssertSDeassertTester{ + class PLL extends BlackBox{ + val io = new Bundle{ + val clk_in = in Bool() + val clk_out = out Bool() + } + + noIoPrefix() + } + + class PllAAssertSDeassertTester extends Component{ + val aReset = in Bool() + val clk_100Mhz = in Bool() + + val pllBB = new PLL + pllBB.io.clk_in := clk_100Mhz + + val coreClockDomain = ClockDomain.internal("core") + coreClockDomain.clock := pllBB.io.clk_out + coreClockDomain.reset := ResetCtrl.asyncAssertSyncDeassert( + input = aReset, + clockDomain = coreClockDomain + ) + + val counter = out(coreClockDomain(CounterFreeRun(10).value)).setName("counter") + } +} + +class PllAAssertSDeassertTesterBoot extends SpinalTesterCocotbBase { + override def getName: String = "PllAAssertSDeassertTester" + override def pythonTestLocation: String = "tester/src/test/python/spinal/PllAAssertSDeassertTester" + override def createToplevel: Component = new PllAAssertSDeassertTester.PllAAssertSDeassertTester + + override def backendConfig(config: SpinalConfig): SpinalConfig = config + .copy(defaultConfigForClockDomains = config.defaultConfigForClockDomains.copy(resetKind = SYNC)) +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/PllAAssertSDeassertTester.scala b/tester/src/test/scala/spinal/tester/scalatest/PllAAssertSDeassertTester.scala deleted file mode 100644 index 3743c4a2d5..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/PllAAssertSDeassertTester.scala +++ /dev/null @@ -1,51 +0,0 @@ -package spinal.tester.scalatest - -import spinal.core._ -import spinal.lib.{ResetCtrl, CounterFreeRun, Counter} -import spinal.lib.com.uart._ - - - -object PllAAssertSDeassertTester{ - class PLL extends BlackBox{ - val io = new Bundle{ - val clk_in = in Bool() - val clk_out = out Bool() - } - - noIoPrefix() - } - - class PllAAssertSDeassertTester extends Component{ - val aReset = in Bool() - val clk_100Mhz = in Bool() - - val pllBB = new PLL - pllBB.io.clk_in := clk_100Mhz - -// val coreClockDomain = ClockDomain( -// clock = pllBB.io.clk_out, -// reset = Bool.setName("coreReset") -// ) - val coreClockDomain = ClockDomain.internal("core") - coreClockDomain.clock := pllBB.io.clk_out - coreClockDomain.reset := ResetCtrl.asyncAssertSyncDeassert( - input = aReset, - clockDomain = coreClockDomain - ) - - val counter = out(coreClockDomain(CounterFreeRun(10).value)).setName("counter") - } -} - - - - -class PllAAssertSDeassertTesterBoot extends SpinalTesterCocotbBase { - override def getName: String = "PllAAssertSDeassertTester" - override def pythonTestLocation: String = "tester/src/test/python/spinal/PllAAssertSDeassertTester" - override def createToplevel: Component = new PllAAssertSDeassertTester.PllAAssertSDeassertTester - - override def backendConfig(config: SpinalConfig): SpinalConfig = config - .copy(defaultConfigForClockDomains = config.defaultConfigForClockDomains.copy(resetKind = SYNC)) -} \ No newline at end of file From 3e391755b7cd017c0b1eb50a593b4a7b8742af89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 15 Dec 2022 22:07:59 +0100 Subject: [PATCH 114/120] refactor: move VerilatorCacheTester --- .../src/test/scala/spinal/core/sim/SimBootstraps.scala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/VerilatorCacheTester.scala => core/src/test/scala/spinal/core/sim/SimBootstraps.scala (99%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/VerilatorCacheTester.scala b/core/src/test/scala/spinal/core/sim/SimBootstraps.scala similarity index 99% rename from tester/src/test/scala/spinal/tester/scalatest/VerilatorCacheTester.scala rename to core/src/test/scala/spinal/core/sim/SimBootstraps.scala index 3fe59413d8..f6e0d49778 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/VerilatorCacheTester.scala +++ b/core/src/test/scala/spinal/core/sim/SimBootstraps.scala @@ -1,16 +1,14 @@ -package spinal.tester.scalatest +package spinal.core.sim import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ -import spinal.core.sim._ import java.io.File import org.apache.commons.io.FileUtils import spinal.lib.Delay - import java.io.PrintStream - object VerilatorCacheTester { case class ComponentA(n: Int, x: BigInt) extends Component { val io = new Bundle { From 1818d5fd3281a133362530d54e225bbbab1cb6e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 15 Dec 2022 22:14:44 +0100 Subject: [PATCH 115/120] refactor: move SpinalSimVerilatorIoTest --- .../scala/spinal/core/sim/SimBootstraps.scala | 232 +++++++++++++++++ .../scalatest/SpinalSimVerilatorIoTest.scala | 239 ------------------ 2 files changed, 232 insertions(+), 239 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimVerilatorIoTest.scala diff --git a/core/src/test/scala/spinal/core/sim/SimBootstraps.scala b/core/src/test/scala/spinal/core/sim/SimBootstraps.scala index f6e0d49778..810c74f47a 100644 --- a/core/src/test/scala/spinal/core/sim/SimBootstraps.scala +++ b/core/src/test/scala/spinal/core/sim/SimBootstraps.scala @@ -1,6 +1,7 @@ package spinal.core.sim import org.scalatest.funsuite.AnyFunSuite +import spinal.tester.SpinalSimTester import spinal.core._ @@ -9,6 +10,9 @@ import org.apache.commons.io.FileUtils import spinal.lib.Delay import java.io.PrintStream +import scala.concurrent.{Await, Future} +import scala.util.Random + object VerilatorCacheTester { case class ComponentA(n: Int, x: BigInt) extends Component { val io = new Bundle { @@ -194,3 +198,231 @@ class VerilatorCacheTester extends AnyFunSuite { } } +object SpinalSimVerilatorIoTest{ + object State extends SpinalEnum{ + val A,B,C,D,E = newElement() + } + + class newEnumTest(encoding : SpinalEnumEncoding) extends Area{ + val stateInput = in(State(encoding)) + val stateOutput = out(State(encoding)) + val stateDecoded = out(Bits(5 bits)) + + stateDecoded := stateInput.mux[Bits]( + State.A -> 1, + State.B -> 2, + State.C -> 4, + State.D -> 8, + State.E -> 16 + ) + stateOutput := stateInput + } + + class SpinalSimVerilatorIoTestTop extends Component { + val io = new Bundle { + val bool = in Bool() + val u1 = in UInt (1 bits) + val u8 = in UInt (8 bits) + val u16 = in UInt (16 bits) + val u31 = in UInt (31 bits) + val u32 = in UInt (32 bits) + val u63 = in UInt (63 bits) + val u64 = in UInt (64 bits) + val u65 = in UInt (65 bits) + val u127 = in UInt (127 bits) + val u128 = in UInt (128 bits) + val s1 = in SInt (1 bits) + val s8 = in SInt (8 bits) + val s16 = in SInt (16 bits) + val s31 = in SInt (31 bits) + val s32 = in SInt (32 bits) + val s63 = in SInt (63 bits) + val s64 = in SInt (64 bits) + val s65 = in SInt (65 bits) + val s127 = in SInt (127 bits) + val s128 = in SInt (128 bits) + val sum = out SInt(32*5 bits) + } + + val signeds = List(io.s1, io.s8, io.s16, io.s31, io.s32, io.s63, io.s64, io.s65, io.s127, io.s128) + val unsigneds = List( io.u1, io.u8, io.u16, io.u31, io.u32, io.u63, io.u64, io.u65, io.u127, io.u128) + io.sum := signeds.map(_.resize(widthOf(io.sum))).reduce(_ + _) + unsigneds.map(_.resize(widthOf(io.sum)).asSInt).reduce(_ + _) + + + val miaou = out(Reg(Bits(128 bits))) + miaou := 42 + val nativeEncoding = new newEnumTest(native) + val binarySequentialEncoding =new newEnumTest(binarySequential) + val binaryOneHotEncoding = new newEnumTest(binaryOneHot) + val graySequentialEncoding = new newEnumTest(graySequential) + } +} + +class SpinalSimVerilatorIoTest extends AnyFunSuite { + import SpinalSimVerilatorIoTest._ + + SpinalSimTester { env => + import env._ + var compiled: SimCompiled[SpinalSimVerilatorIoTestTop] = null + + def doTest: Unit = { + compiled.doSim { dut => + def checkBoolean(value: Boolean, that: Bool): Unit = { + that #= value + sleep(1) + assert(that.toBoolean == value, that.getName() + " " + value) + } + + def checkInt(value: Int, that: BitVector): Unit = { + that #= value + sleep(1) + assert(that.toInt == value, that.getName() + " " + value) + } + + def checkLong(value: Long, that: BitVector): Unit = { + that #= value + sleep(1) + assert(that.toLong == value, that.getName() + " " + value) + } + + def checkBigInt(value: BigInt, that: BitVector): Unit = { + that #= value + sleep(1) + assert(that.toBigInt == value, that.getName() + " " + value) + } + + fork { + dut.signeds.foreach(_ #= 0) + dut.unsigneds.foreach(_ #= 0) + while (true) { + sleep(1) + assert(dut.signeds.map(_.toBigInt).reduce(_ + _) + dut.unsigneds.map(_.toBigInt).reduce(_ + _) == dut.io.sum.toBigInt) + } + } + + + (0 to 19).foreach { e => + List(false, true).foreach(value => checkBoolean(value, dut.io.bool)) + + //checkInt + List(0, 1).foreach(value => checkInt(value, dut.io.u1)) + List(0, 1, 127, 255).foreach(value => checkInt(value, dut.io.u8)) + List(0, 1, 0xFFFF).foreach(value => checkInt(value, dut.io.u16)) + List(0, 1, 0x7FFFFFFF).foreach(value => checkInt(value, dut.io.u31)) + + List(0, -1).foreach(value => checkInt(value, dut.io.s1)) + List(0, 1, -1, 127, -128).foreach(value => checkInt(value, dut.io.s8)) + List(0, 1, -1, Short.MaxValue, Short.MinValue).foreach(value => checkInt(value, dut.io.s16)) + List(0, 1, -1, 0xFFFFFFFF, -1, Int.MaxValue, Int.MinValue).foreach(value => checkInt(value, dut.io.s32)) + + //checkLong + List(0, 1).foreach(value => checkLong(value, dut.io.u1)) + List(0, 1, 127, 255).foreach(value => checkLong(value, dut.io.u8)) + List(0, 1, 0xFFFF).foreach(value => checkLong(value, dut.io.u16)) + List(0, 1, 0x7FFFFFFF).foreach(value => checkLong(value, dut.io.u32)) + List(0l, 1l, 0x7FFFFFFFFFFFFFFFl).foreach(value => checkLong(value, dut.io.u63)) + + List(0, -1).foreach(value => checkLong(value, dut.io.s1)) + List(0, 1, -1, 127, -128).foreach(value => checkLong(value, dut.io.s8)) + List(0, 1, -1, Short.MaxValue, Short.MinValue).foreach(value => checkLong(value, dut.io.s16)) + List(0, 1, -1, 0xFFFFFFFF, -1, Int.MaxValue, Int.MinValue).foreach(value => checkLong(value, dut.io.s32)) + List(0l, 1l, 0xFFFFFFFFFFFFFFFFl, -1l, Long.MaxValue, Long.MinValue).foreach(value => checkLong(value, dut.io.s64)) + + //checkBigInt + List(0, 1).foreach(value => checkBigInt(value, dut.io.u1)) + List(0, 1, 127, 255).foreach(value => checkBigInt(value, dut.io.u8)) + List(0, 1, 0xFFFF).foreach(value => checkBigInt(value, dut.io.u16)) + List(0, 1, 0x7FFFFFFF).foreach(value => checkBigInt(value, dut.io.u32)) + List(0l, 1l, 0x7FFFFFFFFFFFFFFFl).foreach(value => checkBigInt(value, dut.io.u63)) + + List(0, -1).foreach(value => checkBigInt(value, dut.io.s1)) + List(0, 1, -1, 127, -128).foreach(value => checkBigInt(value, dut.io.s8)) + List(0, 1, -1, Short.MaxValue, Short.MinValue).foreach(value => checkBigInt(value, dut.io.s16)) + List(0, 1, -1, 0xFFFFFFFF, -1, Int.MaxValue, Int.MinValue).foreach(value => checkBigInt(value, dut.io.s32)) + List(0l, 1l, 0xFFFFFFFFFFFFFFFFl, -1l, Long.MaxValue, Long.MinValue).foreach(value => checkBigInt(value, dut.io.s64)) + + forkJoin( + () => Random.shuffle((0 to 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u1)), + () => Random.shuffle((0 to 8)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u8)), + () => Random.shuffle((0 to 16)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u16)), + () => Random.shuffle((0 to 31)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u31)), + () => Random.shuffle((0 to 32)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u32)), + () => Random.shuffle((0 to 63)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u63)), + () => Random.shuffle((0 to 64)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u64)), + () => Random.shuffle((0 to 65)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u65)), + () => Random.shuffle((0 to 127)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u127)), + () => Random.shuffle((0 to 128)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u128)), + () => Random.shuffle((0 to 1 - 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s1)), + () => Random.shuffle((0 to 8 - 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s8)), + () => Random.shuffle((0 to 16 - 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s16)), + () => Random.shuffle((0 to 31 - 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s31)), + () => Random.shuffle((0 to 32 - 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s32)), + () => Random.shuffle((0 to 62)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s63)), + () => Random.shuffle((0 to 63)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s64)), + () => Random.shuffle((0 to 64)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s65)), + () => Random.shuffle((0 to 126)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s127)), + () => Random.shuffle((0 to 127)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s128)) + ) + + forkJoin( + () => Random.shuffle((0 to 1 - 1)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s1)), + () => Random.shuffle((0 to 8 - 1)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s8)), + () => Random.shuffle((0 to 16 - 1)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s16)), + () => Random.shuffle((0 to 31 - 1)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s31)), + () => Random.shuffle((0 to 32 - 1)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s32)), + () => Random.shuffle((0 to 62)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s63)), + () => Random.shuffle((0 to 63)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s64)), + () => Random.shuffle((0 to 64)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s65)), + () => Random.shuffle((0 to 126)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s127)), + () => Random.shuffle((0 to 127)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s128)) + ) + + def newEnumTest(test: newEnumTest) = { + for (i <- 0 until 40) { + val e = State.elements(Random.nextInt(State.elements.length)) + test.stateInput #= e + sleep(1) + assert(test.stateOutput.toEnum == e) + assert(test.stateDecoded.toInt == (1 << e.position)) + + } + } + + newEnumTest(dut.nativeEncoding) + newEnumTest(dut.binaryOneHotEncoding) + newEnumTest(dut.binarySequentialEncoding) + newEnumTest(dut.graySequentialEncoding) + } + } + } + + test(prefix + "compile") { + compiled = env.SimConfig.compile(new SpinalSimVerilatorIoTestTop) + } + + test(prefix + "test1") { + doTest + } + test(prefix + "test2") { + doTest + } + test(prefix + "test3") { + doTest + } + + + test(prefix + "testMulticore") { + import scala.concurrent.ExecutionContext.Implicits.global + + val futures = for (i <- 0 to 8) yield { + Future { + doTest + } + } + import scala.concurrent.duration._ + + futures.foreach(f => Await.result(f, 60 seconds)) + } + + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimVerilatorIoTest.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimVerilatorIoTest.scala deleted file mode 100644 index 5d497a8d02..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimVerilatorIoTest.scala +++ /dev/null @@ -1,239 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.core._ -import spinal.sim._ -import spinal.core.sim._ -import spinal.tester.scalatest.SpinalSimVerilatorIoTest.SpinalSimVerilatorIoTestTop - -import scala.concurrent.{Await, Future} -import scala.util.Random - -object SpinalSimVerilatorIoTest{ - object State extends SpinalEnum{ - val A,B,C,D,E = newElement() - } - - class newEnumTest(encoding : SpinalEnumEncoding) extends Area{ - val stateInput = in(State(encoding)) - val stateOutput = out(State(encoding)) - val stateDecoded = out(Bits(5 bits)) - - stateDecoded := stateInput.mux[Bits]( - State.A -> 1, - State.B -> 2, - State.C -> 4, - State.D -> 8, - State.E -> 16 - ) - stateOutput := stateInput - } - - class SpinalSimVerilatorIoTestTop extends Component { - val io = new Bundle { - val bool = in Bool() - val u1 = in UInt (1 bits) - val u8 = in UInt (8 bits) - val u16 = in UInt (16 bits) - val u31 = in UInt (31 bits) - val u32 = in UInt (32 bits) - val u63 = in UInt (63 bits) - val u64 = in UInt (64 bits) - val u65 = in UInt (65 bits) - val u127 = in UInt (127 bits) - val u128 = in UInt (128 bits) - val s1 = in SInt (1 bits) - val s8 = in SInt (8 bits) - val s16 = in SInt (16 bits) - val s31 = in SInt (31 bits) - val s32 = in SInt (32 bits) - val s63 = in SInt (63 bits) - val s64 = in SInt (64 bits) - val s65 = in SInt (65 bits) - val s127 = in SInt (127 bits) - val s128 = in SInt (128 bits) - val sum = out SInt(32*5 bits) - } - - val signeds = List(io.s1, io.s8, io.s16, io.s31, io.s32, io.s63, io.s64, io.s65, io.s127, io.s128) - val unsigneds = List( io.u1, io.u8, io.u16, io.u31, io.u32, io.u63, io.u64, io.u65, io.u127, io.u128) - io.sum := signeds.map(_.resize(widthOf(io.sum))).reduce(_ + _) + unsigneds.map(_.resize(widthOf(io.sum)).asSInt).reduce(_ + _) - - - val miaou = out(Reg(Bits(128 bits))) - miaou := 42 - val nativeEncoding = new newEnumTest(native) - val binarySequentialEncoding =new newEnumTest(binarySequential) - val binaryOneHotEncoding = new newEnumTest(binaryOneHot) - val graySequentialEncoding = new newEnumTest(graySequential) - } -} - -class SpinalSimVerilatorIoTest extends AnyFunSuite { - SpinalSimTester { env => - import env._ - var compiled: SimCompiled[SpinalSimVerilatorIoTestTop] = null - - def doTest: Unit = { - compiled.doSim { dut => - def checkBoolean(value: Boolean, that: Bool): Unit = { - that #= value - sleep(1) - assert(that.toBoolean == value, that.getName() + " " + value) - } - - def checkInt(value: Int, that: BitVector): Unit = { - that #= value - sleep(1) - assert(that.toInt == value, that.getName() + " " + value) - } - - def checkLong(value: Long, that: BitVector): Unit = { - that #= value - sleep(1) - assert(that.toLong == value, that.getName() + " " + value) - } - - def checkBigInt(value: BigInt, that: BitVector): Unit = { - that #= value - sleep(1) - assert(that.toBigInt == value, that.getName() + " " + value) - } - - fork { - dut.signeds.foreach(_ #= 0) - dut.unsigneds.foreach(_ #= 0) - while (true) { - sleep(1) - assert(dut.signeds.map(_.toBigInt).reduce(_ + _) + dut.unsigneds.map(_.toBigInt).reduce(_ + _) == dut.io.sum.toBigInt) - } - } - - - (0 to 19).foreach { e => - List(false, true).foreach(value => checkBoolean(value, dut.io.bool)) - - //checkInt - List(0, 1).foreach(value => checkInt(value, dut.io.u1)) - List(0, 1, 127, 255).foreach(value => checkInt(value, dut.io.u8)) - List(0, 1, 0xFFFF).foreach(value => checkInt(value, dut.io.u16)) - List(0, 1, 0x7FFFFFFF).foreach(value => checkInt(value, dut.io.u31)) - - List(0, -1).foreach(value => checkInt(value, dut.io.s1)) - List(0, 1, -1, 127, -128).foreach(value => checkInt(value, dut.io.s8)) - List(0, 1, -1, Short.MaxValue, Short.MinValue).foreach(value => checkInt(value, dut.io.s16)) - List(0, 1, -1, 0xFFFFFFFF, -1, Int.MaxValue, Int.MinValue).foreach(value => checkInt(value, dut.io.s32)) - - //checkLong - List(0, 1).foreach(value => checkLong(value, dut.io.u1)) - List(0, 1, 127, 255).foreach(value => checkLong(value, dut.io.u8)) - List(0, 1, 0xFFFF).foreach(value => checkLong(value, dut.io.u16)) - List(0, 1, 0x7FFFFFFF).foreach(value => checkLong(value, dut.io.u32)) - List(0l, 1l, 0x7FFFFFFFFFFFFFFFl).foreach(value => checkLong(value, dut.io.u63)) - - List(0, -1).foreach(value => checkLong(value, dut.io.s1)) - List(0, 1, -1, 127, -128).foreach(value => checkLong(value, dut.io.s8)) - List(0, 1, -1, Short.MaxValue, Short.MinValue).foreach(value => checkLong(value, dut.io.s16)) - List(0, 1, -1, 0xFFFFFFFF, -1, Int.MaxValue, Int.MinValue).foreach(value => checkLong(value, dut.io.s32)) - List(0l, 1l, 0xFFFFFFFFFFFFFFFFl, -1l, Long.MaxValue, Long.MinValue).foreach(value => checkLong(value, dut.io.s64)) - - //checkBigInt - List(0, 1).foreach(value => checkBigInt(value, dut.io.u1)) - List(0, 1, 127, 255).foreach(value => checkBigInt(value, dut.io.u8)) - List(0, 1, 0xFFFF).foreach(value => checkBigInt(value, dut.io.u16)) - List(0, 1, 0x7FFFFFFF).foreach(value => checkBigInt(value, dut.io.u32)) - List(0l, 1l, 0x7FFFFFFFFFFFFFFFl).foreach(value => checkBigInt(value, dut.io.u63)) - - List(0, -1).foreach(value => checkBigInt(value, dut.io.s1)) - List(0, 1, -1, 127, -128).foreach(value => checkBigInt(value, dut.io.s8)) - List(0, 1, -1, Short.MaxValue, Short.MinValue).foreach(value => checkBigInt(value, dut.io.s16)) - List(0, 1, -1, 0xFFFFFFFF, -1, Int.MaxValue, Int.MinValue).foreach(value => checkBigInt(value, dut.io.s32)) - List(0l, 1l, 0xFFFFFFFFFFFFFFFFl, -1l, Long.MaxValue, Long.MinValue).foreach(value => checkBigInt(value, dut.io.s64)) - - forkJoin( - () => Random.shuffle((0 to 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u1)), - () => Random.shuffle((0 to 8)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u8)), - () => Random.shuffle((0 to 16)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u16)), - () => Random.shuffle((0 to 31)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u31)), - () => Random.shuffle((0 to 32)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u32)), - () => Random.shuffle((0 to 63)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u63)), - () => Random.shuffle((0 to 64)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u64)), - () => Random.shuffle((0 to 65)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u65)), - () => Random.shuffle((0 to 127)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u127)), - () => Random.shuffle((0 to 128)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.u128)), - () => Random.shuffle((0 to 1 - 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s1)), - () => Random.shuffle((0 to 8 - 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s8)), - () => Random.shuffle((0 to 16 - 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s16)), - () => Random.shuffle((0 to 31 - 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s31)), - () => Random.shuffle((0 to 32 - 1)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s32)), - () => Random.shuffle((0 to 62)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s63)), - () => Random.shuffle((0 to 63)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s64)), - () => Random.shuffle((0 to 64)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s65)), - () => Random.shuffle((0 to 126)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s127)), - () => Random.shuffle((0 to 127)).map(n => BigInt("0" + "1" * n, 2)).foreach(value => checkBigInt(value, dut.io.s128)) - ) - - forkJoin( - () => Random.shuffle((0 to 1 - 1)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s1)), - () => Random.shuffle((0 to 8 - 1)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s8)), - () => Random.shuffle((0 to 16 - 1)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s16)), - () => Random.shuffle((0 to 31 - 1)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s31)), - () => Random.shuffle((0 to 32 - 1)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s32)), - () => Random.shuffle((0 to 62)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s63)), - () => Random.shuffle((0 to 63)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s64)), - () => Random.shuffle((0 to 64)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s65)), - () => Random.shuffle((0 to 126)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s127)), - () => Random.shuffle((0 to 127)).map(n => -BigInt("0" + "1" * n, 2) - 1).foreach(value => checkBigInt(value, dut.io.s128)) - ) - - - import SpinalSimVerilatorIoTest._ - def newEnumTest(test: newEnumTest) = { - for (i <- 0 until 40) { - val e = State.elements(Random.nextInt(State.elements.length)) - test.stateInput #= e - sleep(1) - assert(test.stateOutput.toEnum == e) - assert(test.stateDecoded.toInt == (1 << e.position)) - - } - } - - newEnumTest(dut.nativeEncoding) - newEnumTest(dut.binaryOneHotEncoding) - newEnumTest(dut.binarySequentialEncoding) - newEnumTest(dut.graySequentialEncoding) - } - } - } - - test(prefix + "compile") { - compiled = SimConfig.compile(new SpinalSimVerilatorIoTest.SpinalSimVerilatorIoTestTop) - } - - test(prefix + "test1") { - doTest - } - test(prefix + "test2") { - doTest - } - test(prefix + "test3") { - doTest - } - - - test(prefix + "testMulticore") { - import scala.concurrent.ExecutionContext.Implicits.global - - val futures = for (i <- 0 to 8) yield { - Future { - doTest - } - } - import scala.concurrent.duration._ - - futures.foreach(f => Await.result(f, 60 seconds)) - } - - } -} From 2eab15cda13211a01ac696ef05979bed8b490f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 15 Dec 2022 22:16:48 +0100 Subject: [PATCH 116/120] refactor: move SpinalSimMultiThreadingTest --- .../scala/spinal/core/sim/SimBootstraps.scala | 61 +++++++++++++++- .../SpinalSimMultiThreadingTest.scala | 72 ------------------- 2 files changed, 60 insertions(+), 73 deletions(-) delete mode 100644 tester/src/test/scala/spinal/tester/scalatest/SpinalSimMultiThreadingTest.scala diff --git a/core/src/test/scala/spinal/core/sim/SimBootstraps.scala b/core/src/test/scala/spinal/core/sim/SimBootstraps.scala index 810c74f47a..80ceaed0c0 100644 --- a/core/src/test/scala/spinal/core/sim/SimBootstraps.scala +++ b/core/src/test/scala/spinal/core/sim/SimBootstraps.scala @@ -1,7 +1,7 @@ package spinal.core.sim import org.scalatest.funsuite.AnyFunSuite -import spinal.tester.SpinalSimTester +import spinal.tester.{SpinalSimFunSuite, SpinalSimTester} import spinal.core._ @@ -426,3 +426,62 @@ class SpinalSimVerilatorIoTest extends AnyFunSuite { } } + +class SpinalSimMultiThreadingDut(offset : Int) extends Component { + val io = new Bundle { + val a, b, c = in UInt (8 bits) + val result = out UInt (8 bits) + } + + io.result := RegNext(io.a + io.b - io.c + offset) init (0) +} + +class SpinalSimMultiThreadingTest extends SpinalSimFunSuite { + test("Test1") { + var faild = false + val threads = for (t <- 0 to 3) yield { + new Thread { + override def run() = { + for (i <- 0 to 5) { + try { + SimConfig + .withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = SYNC))) + // .compile() + // .withWave + .doSim(new SpinalSimMultiThreadingDut(i + t).setDefinitionName(s"SpinalSimMultiThreadingDut_${t}_${i}")) { dut => + dut.clockDomain.forkStimulus(period = 10) + + for (repeat <- 0 until (100000*durationFactor).toInt) { + val a, b, c = Random.nextInt(256) + dut.io.a #= a + dut.io.b #= b + dut.io.c #= c + dut.clockDomain.waitSampling(); sleep(0) + if (dut.clockDomain.isResetDeasserted) assert(dut.io.result.toInt == ((a + b - c + i + t) & 0xFF)) + } + } + } catch { + case e: Throwable => { + faild = true + println(e) + println("FAILURE") + throw e + } + } + } + } + } + } + + for (thread <- threads) { + thread.start() + Thread.sleep(1000) + } + + for (thread <- threads) { + thread.join() + } + + assert(!faild) + } +} diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimMultiThreadingTest.scala b/tester/src/test/scala/spinal/tester/scalatest/SpinalSimMultiThreadingTest.scala deleted file mode 100644 index 294d0389c8..0000000000 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimMultiThreadingTest.scala +++ /dev/null @@ -1,72 +0,0 @@ -package spinal.tester.scalatest - -import org.scalatest.funsuite.AnyFunSuite -import spinal.sim._ -import spinal.core._ -import spinal.core.sim._ - -import scala.util.Random - - -class SpinalSimMultiThreadingDut(offset : Int) extends Component { - val io = new Bundle { - val a, b, c = in UInt (8 bits) - val result = out UInt (8 bits) - } - io.result := RegNext(io.a + io.b - io.c + offset) init (0) - // def rec(that : UInt, level : Int) : UInt = if(level != 0) - // rec(RegNext(that), level -1) - // else - // that - // io.result := rec(io.a + io.b - io.c, 1000) -} - -class SpinalSimMultiThreadingTest extends SpinalSimFunSuite { - test("Test1") { - var faild = false - val threads = for (t <- 0 to 3) yield { - new Thread { - override def run() = { - for (i <- 0 to 5) { - try { - SimConfig - .withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = SYNC))) - // .compile() - // .withWave - .doSim(new SpinalSimMultiThreadingDut(i + t).setDefinitionName(s"SpinalSimMultiThreadingDut_${t}_${i}")) { dut => - dut.clockDomain.forkStimulus(period = 10) - - for (repeat <- 0 until (100000*durationFactor).toInt) { - val a, b, c = Random.nextInt(256) - dut.io.a #= a - dut.io.b #= b - dut.io.c #= c - dut.clockDomain.waitSampling(); sleep(0) - if (dut.clockDomain.isResetDeasserted) assert(dut.io.result.toInt == ((a + b - c + i + t) & 0xFF)) - } - } - } catch { - case e: Throwable => { - faild = true - println(e) - println("FAILURE") - throw e - } - } - } - } - } - } - - for (thread <- threads) { - thread.start() - Thread.sleep(1000) - } - - for (thread <- threads) { - thread.join() - } - - assert(!faild) - } -} From f541bd3db82fdbf007b0ebaf060765c0ddbd98e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Fri, 16 Dec 2022 18:48:57 +0100 Subject: [PATCH 117/120] refactor: move SpinalSimSpiXdrMaster Also moves ddr package files to ddr folder --- .../{xdr => ddr}/Apb3SpiXdrMasterCtrl.scala | 0 .../{xdr => ddr}/BmbSpiXdrMasterCtrl.scala | 0 .../spi/{xdr => ddr}/SpiXdrMasterCtrl.scala | 0 .../lib/com/spi/ddr/SpiXdrMasterCtrl.scala | 33 +++---------------- 4 files changed, 4 insertions(+), 29 deletions(-) rename lib/src/main/scala/spinal/lib/com/spi/{xdr => ddr}/Apb3SpiXdrMasterCtrl.scala (100%) rename lib/src/main/scala/spinal/lib/com/spi/{xdr => ddr}/BmbSpiXdrMasterCtrl.scala (100%) rename lib/src/main/scala/spinal/lib/com/spi/{xdr => ddr}/SpiXdrMasterCtrl.scala (100%) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimSpiXdr.scala => lib/src/test/scala/spinal/lib/com/spi/ddr/SpiXdrMasterCtrl.scala (89%) diff --git a/lib/src/main/scala/spinal/lib/com/spi/xdr/Apb3SpiXdrMasterCtrl.scala b/lib/src/main/scala/spinal/lib/com/spi/ddr/Apb3SpiXdrMasterCtrl.scala similarity index 100% rename from lib/src/main/scala/spinal/lib/com/spi/xdr/Apb3SpiXdrMasterCtrl.scala rename to lib/src/main/scala/spinal/lib/com/spi/ddr/Apb3SpiXdrMasterCtrl.scala diff --git a/lib/src/main/scala/spinal/lib/com/spi/xdr/BmbSpiXdrMasterCtrl.scala b/lib/src/main/scala/spinal/lib/com/spi/ddr/BmbSpiXdrMasterCtrl.scala similarity index 100% rename from lib/src/main/scala/spinal/lib/com/spi/xdr/BmbSpiXdrMasterCtrl.scala rename to lib/src/main/scala/spinal/lib/com/spi/ddr/BmbSpiXdrMasterCtrl.scala diff --git a/lib/src/main/scala/spinal/lib/com/spi/xdr/SpiXdrMasterCtrl.scala b/lib/src/main/scala/spinal/lib/com/spi/ddr/SpiXdrMasterCtrl.scala similarity index 100% rename from lib/src/main/scala/spinal/lib/com/spi/xdr/SpiXdrMasterCtrl.scala rename to lib/src/main/scala/spinal/lib/com/spi/ddr/SpiXdrMasterCtrl.scala diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimSpiXdr.scala b/lib/src/test/scala/spinal/lib/com/spi/ddr/SpiXdrMasterCtrl.scala similarity index 89% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimSpiXdr.scala rename to lib/src/test/scala/spinal/lib/com/spi/ddr/SpiXdrMasterCtrl.scala index b5c0254751..704348668f 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimSpiXdr.scala +++ b/lib/src/test/scala/spinal/lib/com/spi/ddr/SpiXdrMasterCtrl.scala @@ -1,40 +1,15 @@ -package spinal.tester.scalatest +package spinal.lib.com.spi.ddr import org.scalatest.funsuite.AnyFunSuite +import spinal.tester.SpinalSimTester + import spinal.core._ import spinal.core.sim._ -import spinal.lib.bus.amba3.apb.Apb3 -import spinal.lib.com.i2c._ -import spinal.sim._ import spinal.lib._ -import spinal.lib.com.spi.ddr._ -import spinal.lib.sim.{FlowMonitor, ScoreboardInOrder, SimData} +import spinal.lib.sim.{FlowMonitor, ScoreboardInOrder} -import scala.collection.mutable.ListBuffer import scala.util.Random - -//case class SpiDdrSlave(spi: SpiDdrMaster) { -// fork{ -// while(true){ -// waitUntil(spi.sclk.) -// } -// } -// def expectWrite(data: Int, mod: ParameterMod): Unit = { -// -// } -// -// def read(data: Int, mod: ParameterMod): Unit = { -// -// } -//} -// -// -//case class SpinalSimSpiDdrCmdData(read: Boolean, write: Boolean, data: Int) -//case class SpinalSimSpiDdrCmdSs(id : Int, enable : Boolean) - - - class SpinalSimSpiXdrMaster extends AnyFunSuite { SpinalSimTester { env => import env._ From 9d9af893073417aa7f092a4694ccbf13e8160e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 18 Dec 2022 15:56:08 +0100 Subject: [PATCH 118/120] refactor: move SpinalSimDmaSgTester --- .../src/test/scala/spinal/lib/system/dma/sg/DmaSg.scala | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SpinalSimDmaSgTester.scala => lib/src/test/scala/spinal/lib/system/dma/sg/DmaSg.scala (54%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimDmaSgTester.scala b/lib/src/test/scala/spinal/lib/system/dma/sg/DmaSg.scala similarity index 54% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimDmaSgTester.scala rename to lib/src/test/scala/spinal/lib/system/dma/sg/DmaSg.scala index 8948fe7674..ed9bb1b099 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimDmaSgTester.scala +++ b/lib/src/test/scala/spinal/lib/system/dma/sg/DmaSg.scala @@ -1,14 +1,8 @@ -package spinal.tester.scalatest +package spinal.lib.system.dma.sg import org.scalatest.funsuite.AnyFunSuite -import spinal.core.HardType -import spinal.lib.bus.bmb.{Bmb, BmbParameter, BmbSlaveFactory} -import spinal.lib.bus.bmb.sim.{BmbDriver, BmbMemoryAgent} -import spinal.lib.system.dma.sg.{DmaSg, DmaSgTester, SgDmaTestsParameter} -import spinal.core.sim._ import scala.util.Random -import org.scalatest.{ParallelTestExecution, BeforeAndAfterAll} class SpinalSimDmaSgTester extends AnyFunSuite { Random.setSeed(42) From 4f36efa1f5579e898590a48e1f0a20cd5401f58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 18 Dec 2022 16:30:03 +0100 Subject: [PATCH 119/120] refactor: move SpinalSimUsbHostTester --- .../lib/com/usb/ohci}/SpinalSimUsbHostTester.scala | 12 +++++------- .../com/usb/ohci}/SpinalSimUsbHostTesterUtils.scala | 13 +++++-------- 2 files changed, 10 insertions(+), 15 deletions(-) rename {tester/src/test/scala/spinal/tester/scalatest => lib/src/test/scala/spinal/lib/com/usb/ohci}/SpinalSimUsbHostTester.scala (99%) rename {tester/src/test/scala/spinal/tester/scalatest => lib/src/test/scala/spinal/lib/com/usb/ohci}/SpinalSimUsbHostTesterUtils.scala (96%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimUsbHostTester.scala b/lib/src/test/scala/spinal/lib/com/usb/ohci/SpinalSimUsbHostTester.scala similarity index 99% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimUsbHostTester.scala rename to lib/src/test/scala/spinal/lib/com/usb/ohci/SpinalSimUsbHostTester.scala index 0e5673e3ac..e867abf28a 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimUsbHostTester.scala +++ b/lib/src/test/scala/spinal/lib/com/usb/ohci/SpinalSimUsbHostTester.scala @@ -1,17 +1,15 @@ -package spinal.tester.scalatest +package spinal.lib.com.usb.ohci import org.scalatest.funsuite.AnyFunSuite + import spinal.core._ import spinal.core.sim._ -import spinal.lib._ + +import spinal.lib.com.usb._ import spinal.lib.bus.bmb.sim.{BmbDriver, BmbMemoryAgent} import spinal.lib.bus.bmb.{BmbAccessParameter, BmbParameter, BmbSourceParameter} -import spinal.lib.com.usb._ -import spinal.lib.com.usb.ohci._ -import spinal.lib.com.usb.phy.{UsbHubLsFs, UsbLsFsPhy} -import spinal.lib.eda.bench.{AlteraStdTargets, Bench, Rtl, XilinxStdTargets} -import spinal.lib.sim._ +import spinal.lib.eda.bench.{Bench, Rtl, XilinxStdTargets} import scala.collection.mutable import scala.collection.mutable.ArrayBuffer diff --git a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimUsbHostTesterUtils.scala b/lib/src/test/scala/spinal/lib/com/usb/ohci/SpinalSimUsbHostTesterUtils.scala similarity index 96% rename from tester/src/test/scala/spinal/tester/scalatest/SpinalSimUsbHostTesterUtils.scala rename to lib/src/test/scala/spinal/lib/com/usb/ohci/SpinalSimUsbHostTesterUtils.scala index fd43edc491..08b6262676 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SpinalSimUsbHostTesterUtils.scala +++ b/lib/src/test/scala/spinal/lib/com/usb/ohci/SpinalSimUsbHostTesterUtils.scala @@ -1,20 +1,17 @@ -package spinal.tester.scalatest +package spinal.lib.com.usb.ohci import spinal.core._ import spinal.core.sim._ + import spinal.lib.bus.bmb._ import spinal.lib.bus.bmb.sim._ -import spinal.lib.bus.misc.SizeMapping -import spinal.lib.com.usb.ohci._ -import spinal.lib.com.usb.phy.UsbHubLsFs.CtrlCc import spinal.lib.com.usb.phy._ -import spinal.lib.com.usb.sim.{UsbDeviceAgent, UsbDeviceAgentListener, UsbLsFsPhyAbstractIoAgent, UsbLsFsPhyAbstractIoListener} +import spinal.lib.com.usb.sim.{UsbDeviceAgent, UsbDeviceAgentListener, UsbLsFsPhyAbstractIoAgent} import spinal.lib.sim._ import scala.collection.mutable -import scala.collection.mutable.ArrayBuffer -import scala.util.Random import scala.collection.Seq +import scala.util.Random class UsbOhciTbTop(val p : UsbOhciParameter) extends Component { val ohci = UsbOhci(p, BmbParameter( @@ -32,7 +29,7 @@ class UsbOhciTbTop(val p : UsbOhciParameter) extends Component { val ctrl = ohci.io.ctrl.toIo val dma = ohci.io.dma.toIo - val phyCc = CtrlCc(p.portCount, ClockDomain.current, phyCd) + val phyCc = UsbHubLsFs.CtrlCc(p.portCount, ClockDomain.current, phyCd) phyCc.input <> ohci.io.phy phyCc.output <> phy.io.ctrl val usb = phy.io.usb.toIo From 62ca9601a41031d1aeaf4c07dff7079b462fa8a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Sun, 18 Dec 2022 16:45:11 +0100 Subject: [PATCH 120/120] refactor: move SdramXdrSdrSpinalSim --- .../lib/memory/sdram/xdr/CtrlWithPhy.scala | 36 ++++--------------- 1 file changed, 7 insertions(+), 29 deletions(-) rename tester/src/test/scala/spinal/tester/scalatest/SdramXdrSdrSpinalSim.scala => lib/src/test/scala/spinal/lib/memory/sdram/xdr/CtrlWithPhy.scala (98%) diff --git a/tester/src/test/scala/spinal/tester/scalatest/SdramXdrSdrSpinalSim.scala b/lib/src/test/scala/spinal/lib/memory/sdram/xdr/CtrlWithPhy.scala similarity index 98% rename from tester/src/test/scala/spinal/tester/scalatest/SdramXdrSdrSpinalSim.scala rename to lib/src/test/scala/spinal/lib/memory/sdram/xdr/CtrlWithPhy.scala index 417a1603de..b1042a868d 100644 --- a/tester/src/test/scala/spinal/tester/scalatest/SdramXdrSdrSpinalSim.scala +++ b/lib/src/test/scala/spinal/lib/memory/sdram/xdr/CtrlWithPhy.scala @@ -1,17 +1,14 @@ -package spinal.tester.scalatest +package spinal.lib.memory.sdram.xdr import spinal.core._ -import spinal.core.sim.SpinalSimConfig -import spinal.lib.bus.bmb._ -import spinal.lib.memory.sdram.sdr.{MT41K128M16JT, MT47H64M16HR, MT48LC16M16A2, SdramInterface} -import spinal.lib.memory.sdram.xdr.{BmbPortParameter, CoreParameter, CtrlParameter, CtrlWithPhy, CtrlWithoutPhy, PhyLayout, SdramTiming, SoftConfig, mt48lc16m16a2_model} import spinal.lib._ + +import spinal.lib.bus.bmb.{Bmb, BmbParameter} +import spinal.lib.memory.sdram.sdr.{MT41K128M16JT, MT47H64M16HR, MT48LC16M16A2} import spinal.lib.bus.amba3.apb.Apb3 import spinal.lib.bus.amba3.apb.sim.Apb3Driver import spinal.lib.bus.bmb.sim.{BmbMemoryMultiPort, BmbMemoryMultiPortTester} import spinal.lib.eda.bench.Rtl -import spinal.lib.memory.sdram.SdramLayout -import spinal.lib.memory.sdram.sdr.sim.SdramModel import spinal.lib.memory.sdram.xdr.phy.{Ecp5Sdrx2Phy, RtlPhy, RtlPhyInterface, SdrInferedPhy, XilinxS7Phy} import spinal.lib.sim.Phase @@ -550,7 +547,6 @@ object SdramXdrTesterHelpers{ } } - object SdramXdrDdr3SpinalSim extends App{ import spinal.core.sim._ @@ -595,9 +591,6 @@ object SdramXdrDdr3SpinalSim extends App{ } } - - - object SdramXdrDdr2SpinalSim extends App{ import spinal.core.sim._ @@ -640,8 +633,6 @@ object SdramXdrDdr2SpinalSim extends App{ } } - - object SdramXdrSdrSpinalSim extends App{ import spinal.core.sim._ @@ -687,15 +678,8 @@ object SdramXdrSdrSpinalSim extends App{ } } - - - - - -import spinal.core._ -import spinal.lib.eda.bench._ - -object SdramSdrSyntBench extends App{ +object SdramSdrSyntBench extends App { + import spinal.lib.eda.bench._ val ports4 = new Rtl { override def getName(): String = "Port4" @@ -773,7 +757,6 @@ object SdramSdrSyntBench extends App{ }) } - val rtls = List(ports4) val targets = XilinxStdTargets( @@ -781,13 +764,8 @@ object SdramSdrSyntBench extends App{ ) Bench(rtls, targets) - - - - } - object SdramSdrGen extends App{ SpinalVerilog({ val sl = MT48LC16M16A2.layout.copy(bankWidth = 3) @@ -860,4 +838,4 @@ object SdramSdrGen extends App{ val c = new CtrlWithoutPhy(cp, SdrInferedPhy.phyLayout(sl)) c }) -} \ No newline at end of file +}