From ed51a9211608ab1274758ee05c920fb29b675803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Wed, 16 Nov 2022 18:32:24 +0100 Subject: [PATCH 1/5] big update - remove not supported anymore procedural syntax for main functions - use App instead of main - auto format - move comments to have more user-friendly access to "run" and "debug" button for Apps - move generators to dedicated new file --- .gitignore | 3 + src/main/scala/mylib/MyTopLevel.scala | 63 +++------------------ src/main/scala/mylib/MyTopLevelFormal.scala | 8 +-- src/main/scala/mylib/MyTopLevelGen.scala | 25 ++++++++ src/main/scala/mylib/MyTopLevelSim.scala | 43 ++++++-------- 5 files changed, 59 insertions(+), 83 deletions(-) create mode 100644 src/main/scala/mylib/MyTopLevelGen.scala diff --git a/.gitignore b/.gitignore index 5ca560e..8f0efb0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,17 +11,20 @@ target lib_managed/ src_managed/ project/boot/ +project/project project/plugins/project/ # Scala-IDE specific .scala_dependencies .worksheet +.bloop .idea out # Metals .metals +project/metals.sbt # Eclipse bin/ diff --git a/src/main/scala/mylib/MyTopLevel.scala b/src/main/scala/mylib/MyTopLevel.scala index 363884f..19a8f22 100644 --- a/src/main/scala/mylib/MyTopLevel.scala +++ b/src/main/scala/mylib/MyTopLevel.scala @@ -1,67 +1,22 @@ -/* - * 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 mylib import spinal.core._ -import spinal.lib._ -import scala.util.Random - -//Hardware definition +// Hardware definition class MyTopLevel extends Component { val io = new Bundle { - val cond0 = in Bool() - val cond1 = in Bool() - val flag = out Bool() - val state = out UInt(8 bits) + val cond0 = in Bool () + val cond1 = in Bool () + val flag = out Bool () + val state = out UInt (8 bits) } - val counter = Reg(UInt(8 bits)) init(0) - when(io.cond0){ + val counter = Reg(UInt(8 bits)) init 0 + + when(io.cond0) { counter := counter + 1 } io.state := counter - io.flag := (counter === 0) | io.cond1 + io.flag := (counter === 0) | io.cond1 } - -//Generate the MyTopLevel's Verilog -object MyTopLevelVerilog { - def main(args: Array[String]) { - SpinalVerilog(new MyTopLevel) - } -} - -//Generate the MyTopLevel's VHDL -object MyTopLevelVhdl { - def main(args: Array[String]) { - SpinalVhdl(new MyTopLevel) - } -} - - -//Define a custom SpinalHDL configuration with synchronous reset instead of the default asynchronous one. This configuration can be resued everywhere -object MySpinalConfig extends SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = SYNC)) - -//Generate the MyTopLevel's Verilog using the above custom configuration. -object MyTopLevelVerilogWithCustomConfig { - def main(args: Array[String]) { - MySpinalConfig.generateVerilog(new MyTopLevel) - } -} \ No newline at end of file diff --git a/src/main/scala/mylib/MyTopLevelFormal.scala b/src/main/scala/mylib/MyTopLevelFormal.scala index 21b48cd..7980bf4 100644 --- a/src/main/scala/mylib/MyTopLevelFormal.scala +++ b/src/main/scala/mylib/MyTopLevelFormal.scala @@ -5,9 +5,10 @@ import spinal.core.formal._ // You need SymbiYosys to be installed. // See https://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Formal%20verification/index.html#installing-requirements -object MyTopLevelFormal { - def main(args: Array[String]) { - FormalConfig.withBMC(10).doVerify(new Component { +object MyTopLevelFormal extends App { + FormalConfig + .withBMC(10) + .doVerify(new Component { val dut = FormalDut(new MyTopLevel) // Ensure the formal test start with a reset @@ -20,5 +21,4 @@ object MyTopLevelFormal { // Check the state initial value and increment assert(dut.io.state === past(dut.io.state + U(dut.io.cond0)).init(0)) }) - } } diff --git a/src/main/scala/mylib/MyTopLevelGen.scala b/src/main/scala/mylib/MyTopLevelGen.scala new file mode 100644 index 0000000..c823530 --- /dev/null +++ b/src/main/scala/mylib/MyTopLevelGen.scala @@ -0,0 +1,25 @@ +package mylib + +import spinal.core._ + +object MyTopLevelVerilog extends App { + // Generate the MyTopLevel's Verilog + SpinalVerilog(new MyTopLevel) +} + +object MyTopLevelVhdl extends App { + // Generate the MyTopLevel's VHDL + SpinalVhdl(new MyTopLevel) +} + +// Custom SpinalHDL configuration with synchronous reset instead of the default asynchronous one +// This configuration can be resued everywhere +object MySpinalConfig + extends SpinalConfig( + defaultConfigForClockDomains = ClockDomainConfig(resetKind = SYNC) + ) + +object MyTopLevelVerilogWithCustomConfig extends App { + // Generate the MyTopLevel's Verilog using the above custom configuration. + MySpinalConfig.generateVerilog(new MyTopLevel) +} diff --git a/src/main/scala/mylib/MyTopLevelSim.scala b/src/main/scala/mylib/MyTopLevelSim.scala index 122c04e..7d19427 100644 --- a/src/main/scala/mylib/MyTopLevelSim.scala +++ b/src/main/scala/mylib/MyTopLevelSim.scala @@ -1,37 +1,30 @@ package mylib import spinal.core._ -import spinal.sim._ import spinal.core.sim._ -import scala.util.Random +object MyTopLevelSim extends App { + SimConfig.withWave.doSim(new MyTopLevel) { dut => + // Fork a process to generate the reset and the clock on the dut + dut.clockDomain.forkStimulus(period = 10) + var modelState = 0 + for (idx <- 0 to 99) { + // Drive the dut inputs with random values + dut.io.cond0.randomize() + dut.io.cond1.randomize() -//MyTopLevel's testbench -object MyTopLevelSim { - def main(args: Array[String]) { - SimConfig.withWave.doSim(new MyTopLevel){dut => - //Fork a process to generate the reset and the clock on the dut - dut.clockDomain.forkStimulus(period = 10) + // Wait a rising edge on the clock + dut.clockDomain.waitRisingEdge() - var modelState = 0 - for(idx <- 0 to 99){ - //Drive the dut inputs with random values - dut.io.cond0 #= Random.nextBoolean() - dut.io.cond1 #= Random.nextBoolean() + // Check that the dut values match with the reference model ones + val modelFlag = modelState == 0 || dut.io.cond1.toBoolean + assert(dut.io.state.toInt == modelState) + assert(dut.io.flag.toBoolean == modelFlag) - //Wait a rising edge on the clock - dut.clockDomain.waitRisingEdge() - - //Check that the dut values match with the reference model ones - val modelFlag = modelState == 0 || dut.io.cond1.toBoolean - assert(dut.io.state.toInt == modelState) - assert(dut.io.flag.toBoolean == modelFlag) - - //Update the reference model value - if(dut.io.cond0.toBoolean) { - modelState = (modelState + 1) & 0xFF - } + // Update the reference model value + if (dut.io.cond0.toBoolean) { + modelState = (modelState + 1) & 0xff } } } From a53d219051efbf76ea072aa955335402dabb59b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Wed, 16 Nov 2022 18:36:01 +0100 Subject: [PATCH 2/5] add support of scalafmt --- .scalafmt.conf | 5 +++++ project/plugins.sbt | 1 + 2 files changed, 6 insertions(+) create mode 100644 .scalafmt.conf diff --git a/.scalafmt.conf b/.scalafmt.conf new file mode 100644 index 0000000..92dc1fc --- /dev/null +++ b/.scalafmt.conf @@ -0,0 +1,5 @@ +version = 3.6.0 +runner.dialect = scala212 +align.preset = some +maxColumn = 120 +docstrings.wrap = no diff --git a/project/plugins.sbt b/project/plugins.sbt index e69de29..83adafa 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") From 09e7cac187b8bcf53566cc0b5848bf7c5a42dfbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Wed, 16 Nov 2022 21:16:23 +0100 Subject: [PATCH 3/5] restore fancy formatting in io --- src/main/scala/mylib/MyTopLevel.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/mylib/MyTopLevel.scala b/src/main/scala/mylib/MyTopLevel.scala index 19a8f22..a1c3a71 100644 --- a/src/main/scala/mylib/MyTopLevel.scala +++ b/src/main/scala/mylib/MyTopLevel.scala @@ -5,10 +5,10 @@ import spinal.core._ // Hardware definition class MyTopLevel extends Component { val io = new Bundle { - val cond0 = in Bool () - val cond1 = in Bool () - val flag = out Bool () - val state = out UInt (8 bits) + val cond0 = in Bool() + val cond1 = in Bool() + val flag = out Bool() + val state = out UInt(8 bits) } val counter = Reg(UInt(8 bits)) init 0 From d40940a924cdf7be40b48cffc528eb2716cde9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Thu, 17 Nov 2022 23:18:31 +0100 Subject: [PATCH 4/5] use case class for Component --- src/main/scala/mylib/MyTopLevel.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/mylib/MyTopLevel.scala b/src/main/scala/mylib/MyTopLevel.scala index a1c3a71..bda00e5 100644 --- a/src/main/scala/mylib/MyTopLevel.scala +++ b/src/main/scala/mylib/MyTopLevel.scala @@ -3,7 +3,7 @@ package mylib import spinal.core._ // Hardware definition -class MyTopLevel extends Component { +case class MyTopLevel() extends Component { val io = new Bundle { val cond0 = in Bool() val cond1 = in Bool() From bbbac09f8fa464ca3734936c3d7e984e8fe73016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20ALLART?= Date: Fri, 18 Nov 2022 00:37:28 +0100 Subject: [PATCH 5/5] new MyTopLevel -> MyTopLevel() --- src/main/scala/mylib/MyTopLevelFormal.scala | 2 +- src/main/scala/mylib/MyTopLevelGen.scala | 6 +++--- src/main/scala/mylib/MyTopLevelSim.scala | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/scala/mylib/MyTopLevelFormal.scala b/src/main/scala/mylib/MyTopLevelFormal.scala index 7980bf4..7047665 100644 --- a/src/main/scala/mylib/MyTopLevelFormal.scala +++ b/src/main/scala/mylib/MyTopLevelFormal.scala @@ -9,7 +9,7 @@ object MyTopLevelFormal extends App { FormalConfig .withBMC(10) .doVerify(new Component { - val dut = FormalDut(new MyTopLevel) + val dut = FormalDut(MyTopLevel()) // Ensure the formal test start with a reset assumeInitial(clockDomain.isResetActive) diff --git a/src/main/scala/mylib/MyTopLevelGen.scala b/src/main/scala/mylib/MyTopLevelGen.scala index c823530..cbcaa0b 100644 --- a/src/main/scala/mylib/MyTopLevelGen.scala +++ b/src/main/scala/mylib/MyTopLevelGen.scala @@ -4,12 +4,12 @@ import spinal.core._ object MyTopLevelVerilog extends App { // Generate the MyTopLevel's Verilog - SpinalVerilog(new MyTopLevel) + SpinalVerilog(MyTopLevel()) } object MyTopLevelVhdl extends App { // Generate the MyTopLevel's VHDL - SpinalVhdl(new MyTopLevel) + SpinalVhdl(MyTopLevel()) } // Custom SpinalHDL configuration with synchronous reset instead of the default asynchronous one @@ -21,5 +21,5 @@ object MySpinalConfig object MyTopLevelVerilogWithCustomConfig extends App { // Generate the MyTopLevel's Verilog using the above custom configuration. - MySpinalConfig.generateVerilog(new MyTopLevel) + MySpinalConfig.generateVerilog(MyTopLevel()) } diff --git a/src/main/scala/mylib/MyTopLevelSim.scala b/src/main/scala/mylib/MyTopLevelSim.scala index 7d19427..1442a16 100644 --- a/src/main/scala/mylib/MyTopLevelSim.scala +++ b/src/main/scala/mylib/MyTopLevelSim.scala @@ -4,7 +4,7 @@ import spinal.core._ import spinal.core.sim._ object MyTopLevelSim extends App { - SimConfig.withWave.doSim(new MyTopLevel) { dut => + SimConfig.withWave.doSim(MyTopLevel()) { dut => // Fork a process to generate the reset and the clock on the dut dut.clockDomain.forkStimulus(period = 10)