From 1761d500f3238e44ce8a0c395e80ecd2861baf98 Mon Sep 17 00:00:00 2001 From: chick Date: Mon, 1 Feb 2021 10:00:52 -0800 Subject: [PATCH 1/8] Get rid of scalastyle checkers. These are outdated and not used by the rest of the chisel family. Add the scalafmt file that is used to fix code formatting. This will be used to regularize the code. That work will be done by attrition. --- .scalafmt.conf | 4 +- scalastyle-config.xml | 110 ------------------------------------- scalastyle-test-config.xml | 109 ------------------------------------ 3 files changed, 2 insertions(+), 221 deletions(-) delete mode 100644 scalastyle-config.xml delete mode 100644 scalastyle-test-config.xml diff --git a/.scalafmt.conf b/.scalafmt.conf index f74e5504..c53cb608 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = 2.6.4 +version = 2.7.5 maxColumn = 120 align = most @@ -23,4 +23,4 @@ verticalMultiline.atDefnSite = true optIn.annotationNewlines = true -rewrite.rules = [SortImports, PreferCurlyFors, AvoidInfix] +rewrite.rules = [SortImports, PreferCurlyFors, AvoidInfix] \ No newline at end of file diff --git a/scalastyle-config.xml b/scalastyle-config.xml deleted file mode 100644 index 57ef60a2..00000000 --- a/scalastyle-config.xml +++ /dev/null @@ -1,110 +0,0 @@ - - Scalastyle standard configuration - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - No lines ending with a ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\|\||&&|:=|<>|<=|>=|!=|===|<<|>>|##|unary_(~|\-%?|!))$]]> - - - - - - - - - - - diff --git a/scalastyle-test-config.xml b/scalastyle-test-config.xml deleted file mode 100644 index bf32aacd..00000000 --- a/scalastyle-test-config.xml +++ /dev/null @@ -1,109 +0,0 @@ - - Scalastyle configuration for Chisel3 unit tests - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - No lines ending with a ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\|\||&&|:=|<>|<=|>=|!=|===|<<|>>|##|unary_(~|\-%?|!))$]]> - - - - - - - - - - - From 19e51f3df507efa9371ab44f49ef6637123f30bc Mon Sep 17 00:00:00 2001 From: chick Date: Wed, 3 Feb 2021 17:46:12 -0800 Subject: [PATCH 2/8] Make the directory structure match the packages All tests run as they did prior to the changes --- .../Analog.scala | 0 .../IOCell.scala | 0 .../{ => barstools/macros}/CostMetric.scala | 3 ++- .../{ => barstools/macros}/MacroCompiler.scala | 17 ++++++++--------- .../scala/{ => barstools/macros}/SynFlops.scala | 6 +++--- .../scala/{ => barstools/macros}/Utils.scala | 12 +++++------- .../{ => barstools/macros}/CostFunction.scala | 0 .../{ => barstools/macros}/Functional.scala | 0 .../macros}/MacroCompilerSpec.scala | 8 ++++---- .../scala/{ => barstools/macros}/Masks.scala | 2 -- .../{ => barstools/macros}/MultiPort.scala | 0 .../{ => barstools/macros}/SRAMCompiler.scala | 2 -- .../macros}/SimpleSplitDepth.scala | 2 -- .../macros}/SimpleSplitWidth.scala | 0 .../macros}/SpecificExamples.scala | 0 .../scala/{ => barstools/macros}/SynFlops.scala | 0 .../transforms/AddSuffixToModuleNames.scala | 10 +++++----- .../transforms/AvoidExtModuleCollisions.scala | 10 +++++----- .../transforms/ConvertToExtModPass.scala | 10 +++++----- .../tapeout}/transforms/EnumerateModules.scala | 0 .../tapeout}/transforms/Generate.scala | 2 +- .../tapeout}/transforms/ReParentCircuit.scala | 7 +++---- .../transforms/RemoveUnusedModules.scala | 10 +++++----- .../tapeout}/transforms/ResetInverter.scala | 0 .../tapeout}/transforms/retime/Retime.scala | 0 .../tapeout}/transforms/utils/FileUtils.scala | 0 .../transforms/utils/LowerAnnotations.scala | 0 .../transforms/utils/ProgrammaticBundle.scala | 0 .../tapeout}/transforms/utils/YamlHelpers.scala | 0 .../tapeout}/transforms/ResetInverterSpec.scala | 2 +- .../tapeout}/transforms/retime/RetimeSpec.scala | 8 +++----- 31 files changed, 50 insertions(+), 61 deletions(-) rename iocell/src/main/scala/{chisel => barstools.iocell.chisel}/Analog.scala (100%) rename iocell/src/main/scala/{chisel => barstools.iocell.chisel}/IOCell.scala (100%) rename macros/src/main/scala/{ => barstools/macros}/CostMetric.scala (99%) rename macros/src/main/scala/{ => barstools/macros}/MacroCompiler.scala (99%) rename macros/src/main/scala/{ => barstools/macros}/SynFlops.scala (98%) rename macros/src/main/scala/{ => barstools/macros}/Utils.scala (96%) rename macros/src/test/scala/{ => barstools/macros}/CostFunction.scala (100%) rename macros/src/test/scala/{ => barstools/macros}/Functional.scala (100%) rename macros/src/test/scala/{ => barstools/macros}/MacroCompilerSpec.scala (99%) rename macros/src/test/scala/{ => barstools/macros}/Masks.scala (99%) rename macros/src/test/scala/{ => barstools/macros}/MultiPort.scala (100%) rename macros/src/test/scala/{ => barstools/macros}/SRAMCompiler.scala (96%) rename macros/src/test/scala/{ => barstools/macros}/SimpleSplitDepth.scala (99%) rename macros/src/test/scala/{ => barstools/macros}/SimpleSplitWidth.scala (100%) rename macros/src/test/scala/{ => barstools/macros}/SpecificExamples.scala (100%) rename macros/src/test/scala/{ => barstools/macros}/SynFlops.scala (100%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/AddSuffixToModuleNames.scala (94%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/AvoidExtModuleCollisions.scala (83%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/ConvertToExtModPass.scala (89%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/EnumerateModules.scala (100%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/Generate.scala (99%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/ReParentCircuit.scala (89%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/RemoveUnusedModules.scala (91%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/ResetInverter.scala (100%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/retime/Retime.scala (100%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/utils/FileUtils.scala (100%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/utils/LowerAnnotations.scala (100%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/utils/ProgrammaticBundle.scala (100%) rename tapeout/src/main/scala/{ => barstools/tapeout}/transforms/utils/YamlHelpers.scala (100%) rename tapeout/src/test/scala/{ => barstools/tapeout}/transforms/ResetInverterSpec.scala (95%) rename tapeout/src/test/scala/{ => barstools/tapeout}/transforms/retime/RetimeSpec.scala (94%) diff --git a/iocell/src/main/scala/chisel/Analog.scala b/iocell/src/main/scala/barstools.iocell.chisel/Analog.scala similarity index 100% rename from iocell/src/main/scala/chisel/Analog.scala rename to iocell/src/main/scala/barstools.iocell.chisel/Analog.scala diff --git a/iocell/src/main/scala/chisel/IOCell.scala b/iocell/src/main/scala/barstools.iocell.chisel/IOCell.scala similarity index 100% rename from iocell/src/main/scala/chisel/IOCell.scala rename to iocell/src/main/scala/barstools.iocell.chisel/IOCell.scala diff --git a/macros/src/main/scala/CostMetric.scala b/macros/src/main/scala/barstools/macros/CostMetric.scala similarity index 99% rename from macros/src/main/scala/CostMetric.scala rename to macros/src/main/scala/barstools/macros/CostMetric.scala index b80324aa..45020163 100644 --- a/macros/src/main/scala/CostMetric.scala +++ b/macros/src/main/scala/barstools/macros/CostMetric.scala @@ -67,8 +67,9 @@ object OldMetric extends CostMetric with CostMetricCompanion { */ class ExternalMetric(path: String) extends CostMetric { import mdf.macrolib.Utils.writeMacroToPath + import java.io._ - import scala.language.postfixOps // for !! postfix op + import scala.language.postfixOps import sys.process._ override def cost(mem: Macro, lib: Macro): Option[Double] = { diff --git a/macros/src/main/scala/MacroCompiler.scala b/macros/src/main/scala/barstools/macros/MacroCompiler.scala similarity index 99% rename from macros/src/main/scala/MacroCompiler.scala rename to macros/src/main/scala/barstools/macros/MacroCompiler.scala index c057baa6..416f2d2c 100644 --- a/macros/src/main/scala/MacroCompiler.scala +++ b/macros/src/main/scala/barstools/macros/MacroCompiler.scala @@ -8,18 +8,17 @@ package barstools.macros -import firrtl._ -import firrtl.ir._ -import firrtl.PrimOps +import barstools.macros.Utils._ +import firrtl.CompilerUtils.getLoweringTransforms import firrtl.Utils._ import firrtl.annotations._ -import firrtl.transforms.{NoDCEAnnotation} -import firrtl.CompilerUtils.getLoweringTransforms -import mdf.macrolib.{PolarizedPort, PortPolarity, SRAMMacro, SRAMGroup, SRAMCompiler} -import scala.collection.mutable.{ArrayBuffer, HashMap} +import firrtl.ir._ +import firrtl.{PrimOps, _} +import mdf.macrolib._ + import java.io.{File, FileWriter} -import scala.io.{Source} -import Utils._ +import scala.collection.mutable.{ArrayBuffer, HashMap} +import scala.io.Source case class MacroCompilerException(msg: String) extends Exception(msg) diff --git a/macros/src/main/scala/SynFlops.scala b/macros/src/main/scala/barstools/macros/SynFlops.scala similarity index 98% rename from macros/src/main/scala/SynFlops.scala rename to macros/src/main/scala/barstools/macros/SynFlops.scala index f815b4cb..df7390d0 100644 --- a/macros/src/main/scala/SynFlops.scala +++ b/macros/src/main/scala/barstools/macros/SynFlops.scala @@ -2,11 +2,11 @@ package barstools.macros +import barstools.macros.Utils._ +import firrtl.Utils._ import firrtl._ import firrtl.ir._ -import firrtl.Utils._ -import firrtl.passes.MemPortUtils.{memPortField, memType} -import Utils._ +import firrtl.passes.MemPortUtils.memPortField class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pass { val extraMods = scala.collection.mutable.ArrayBuffer.empty[Module] diff --git a/macros/src/main/scala/Utils.scala b/macros/src/main/scala/barstools/macros/Utils.scala similarity index 96% rename from macros/src/main/scala/Utils.scala rename to macros/src/main/scala/barstools/macros/Utils.scala index c416ca6a..a65e3a8a 100644 --- a/macros/src/main/scala/Utils.scala +++ b/macros/src/main/scala/barstools/macros/Utils.scala @@ -2,14 +2,12 @@ package barstools.macros -import firrtl._ -import firrtl.ir._ -import firrtl.PrimOps -import firrtl.passes.memlib.{MemConf, MemPort, ReadPort, WritePort, ReadWritePort, MaskedWritePort, MaskedReadWritePort} import firrtl.Utils.BoolType -import mdf.macrolib.{Constant, MacroPort, SRAMMacro} -import mdf.macrolib.{PolarizedPort, PortPolarity, ActiveLow, ActiveHigh, NegativeEdge, PositiveEdge, MacroExtraPort} -import java.io.File +import firrtl.ir._ +import firrtl.passes.memlib._ +import firrtl.{PrimOps, _} +import mdf.macrolib.{Input => _, Output => _, _} + import scala.language.implicitConversions object MacroCompilerMath { diff --git a/macros/src/test/scala/CostFunction.scala b/macros/src/test/scala/barstools/macros/CostFunction.scala similarity index 100% rename from macros/src/test/scala/CostFunction.scala rename to macros/src/test/scala/barstools/macros/CostFunction.scala diff --git a/macros/src/test/scala/Functional.scala b/macros/src/test/scala/barstools/macros/Functional.scala similarity index 100% rename from macros/src/test/scala/Functional.scala rename to macros/src/test/scala/barstools/macros/Functional.scala diff --git a/macros/src/test/scala/MacroCompilerSpec.scala b/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala similarity index 99% rename from macros/src/test/scala/MacroCompilerSpec.scala rename to macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala index 8cdcf354..cf84e500 100644 --- a/macros/src/test/scala/MacroCompilerSpec.scala +++ b/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala @@ -2,14 +2,13 @@ package barstools.macros +import firrtl.Parser.parse import firrtl.ir.{Circuit, NoInfo} import firrtl.passes.RemoveEmpty -import firrtl.Parser.parse - -import java.io.{File, StringWriter} - import mdf.macrolib.SRAMMacro +import java.io.File + abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalatest.Matchers { import scala.language.implicitConversions implicit def String2SomeString(i: String): Option[String] = Some(i) @@ -122,6 +121,7 @@ abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalate // A collection of standard SRAM generators. trait HasSRAMGenerator { import mdf.macrolib._ + import scala.language.implicitConversions implicit def Int2SomeInt(i: Int): Option[Int] = Some(i) implicit def BigInt2SomeBigInt(i: BigInt): Option[BigInt] = Some(i) diff --git a/macros/src/test/scala/Masks.scala b/macros/src/test/scala/barstools/macros/Masks.scala similarity index 99% rename from macros/src/test/scala/Masks.scala rename to macros/src/test/scala/barstools/macros/Masks.scala index a091a42a..f104c8f2 100644 --- a/macros/src/test/scala/Masks.scala +++ b/macros/src/test/scala/barstools/macros/Masks.scala @@ -1,7 +1,5 @@ package barstools.macros -import mdf.macrolib._ - // Test the ability of the compiler to deal with various mask combinations. trait MasksTestSettings { diff --git a/macros/src/test/scala/MultiPort.scala b/macros/src/test/scala/barstools/macros/MultiPort.scala similarity index 100% rename from macros/src/test/scala/MultiPort.scala rename to macros/src/test/scala/barstools/macros/MultiPort.scala diff --git a/macros/src/test/scala/SRAMCompiler.scala b/macros/src/test/scala/barstools/macros/SRAMCompiler.scala similarity index 96% rename from macros/src/test/scala/SRAMCompiler.scala rename to macros/src/test/scala/barstools/macros/SRAMCompiler.scala index 5cae4745..e4e62de7 100644 --- a/macros/src/test/scala/SRAMCompiler.scala +++ b/macros/src/test/scala/barstools/macros/SRAMCompiler.scala @@ -1,7 +1,5 @@ package barstools.macros -import mdf.macrolib._ - class SRAMCompiler extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { val compiler = generateSRAMCompiler("awesome", "A") val verilog = s"v-SRAMCompiler.v" diff --git a/macros/src/test/scala/SimpleSplitDepth.scala b/macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala similarity index 99% rename from macros/src/test/scala/SimpleSplitDepth.scala rename to macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala index e3560f9a..f016dbc7 100644 --- a/macros/src/test/scala/SimpleSplitDepth.scala +++ b/macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala @@ -1,7 +1,5 @@ package barstools.macros -import mdf.macrolib._ - // Test the depth splitting aspect of the memory compiler. // This file is for simple tests: one read-write port, powers of two sizes, etc. // For example, implementing a 4096x32 memory using four 1024x32 memories. diff --git a/macros/src/test/scala/SimpleSplitWidth.scala b/macros/src/test/scala/barstools/macros/SimpleSplitWidth.scala similarity index 100% rename from macros/src/test/scala/SimpleSplitWidth.scala rename to macros/src/test/scala/barstools/macros/SimpleSplitWidth.scala diff --git a/macros/src/test/scala/SpecificExamples.scala b/macros/src/test/scala/barstools/macros/SpecificExamples.scala similarity index 100% rename from macros/src/test/scala/SpecificExamples.scala rename to macros/src/test/scala/barstools/macros/SpecificExamples.scala diff --git a/macros/src/test/scala/SynFlops.scala b/macros/src/test/scala/barstools/macros/SynFlops.scala similarity index 100% rename from macros/src/test/scala/SynFlops.scala rename to macros/src/test/scala/barstools/macros/SynFlops.scala diff --git a/tapeout/src/main/scala/transforms/AddSuffixToModuleNames.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala similarity index 94% rename from tapeout/src/main/scala/transforms/AddSuffixToModuleNames.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala index 26de5425..1e7eaa26 100644 --- a/tapeout/src/main/scala/transforms/AddSuffixToModuleNames.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala @@ -2,12 +2,12 @@ package barstools.tapeout.transforms -import firrtl._ -import firrtl.ir._ import firrtl.Mappers._ -import firrtl.annotations.{ModuleTarget, SingleTargetAnnotation, CircuitTarget} -import firrtl.stage.TransformManager.{TransformDependency} -import firrtl.stage.{Forms} +import firrtl._ +import firrtl.annotations.{CircuitTarget, ModuleTarget, SingleTargetAnnotation} +import firrtl.ir._ +import firrtl.stage.Forms +import firrtl.stage.TransformManager.TransformDependency case class KeepNameAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] { diff --git a/tapeout/src/main/scala/transforms/AvoidExtModuleCollisions.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala similarity index 83% rename from tapeout/src/main/scala/transforms/AvoidExtModuleCollisions.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala index 76ca1006..43aea6c1 100644 --- a/tapeout/src/main/scala/transforms/AvoidExtModuleCollisions.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala @@ -3,12 +3,12 @@ package barstools.tapeout.transforms import firrtl._ +import firrtl.annotations.NoTargetAnnotation import firrtl.ir._ -import firrtl.annotations.{NoTargetAnnotation} -import firrtl.options.{Dependency} -import firrtl.stage.TransformManager.{TransformDependency} -import firrtl.stage.{Forms} -import firrtl.passes.memlib.{ReplSeqMem} +import firrtl.options.Dependency +import firrtl.passes.memlib.ReplSeqMem +import firrtl.stage.Forms +import firrtl.stage.TransformManager.TransformDependency case class LinkExtModulesAnnotation(mustLink: Seq[ExtModule]) extends NoTargetAnnotation diff --git a/tapeout/src/main/scala/transforms/ConvertToExtModPass.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala similarity index 89% rename from tapeout/src/main/scala/transforms/ConvertToExtModPass.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala index 04e645fd..e6d2272a 100644 --- a/tapeout/src/main/scala/transforms/ConvertToExtModPass.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala @@ -3,12 +3,12 @@ package barstools.tapeout.transforms import firrtl._ +import firrtl.annotations.{ModuleTarget, ReferenceTarget, SingleTargetAnnotation} import firrtl.ir._ -import firrtl.annotations.{ModuleTarget, SingleTargetAnnotation, ReferenceTarget} -import firrtl.stage.TransformManager.{TransformDependency} -import firrtl.stage.{Forms} -import firrtl.options.{Dependency} -import firrtl.passes.memlib.{ReplSeqMem} +import firrtl.options.Dependency +import firrtl.passes.memlib.ReplSeqMem +import firrtl.stage.Forms +import firrtl.stage.TransformManager.TransformDependency case class ConvertToExtModAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] { diff --git a/tapeout/src/main/scala/transforms/EnumerateModules.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala similarity index 100% rename from tapeout/src/main/scala/transforms/EnumerateModules.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala diff --git a/tapeout/src/main/scala/transforms/Generate.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala similarity index 99% rename from tapeout/src/main/scala/transforms/Generate.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala index 17b8781d..5abb71c1 100644 --- a/tapeout/src/main/scala/transforms/Generate.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala @@ -5,7 +5,7 @@ import firrtl.annotations._ import firrtl.ir._ import firrtl.passes.memlib.ReplSeqMemAnnotation import firrtl.stage.FirrtlCircuitAnnotation -import firrtl.transforms.{BlackBoxResourceFileNameAnno, DedupModules} +import firrtl.transforms.BlackBoxResourceFileNameAnno import logger.LazyLogging trait HasTapeoutOptions { self: ExecutionOptionsManager with HasFirrtlOptions => diff --git a/tapeout/src/main/scala/transforms/ReParentCircuit.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala similarity index 89% rename from tapeout/src/main/scala/transforms/ReParentCircuit.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala index cbf4d2f8..f7929ee6 100644 --- a/tapeout/src/main/scala/transforms/ReParentCircuit.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala @@ -3,11 +3,10 @@ package barstools.tapeout.transforms import firrtl._ -import firrtl.ir._ import firrtl.annotations._ -import firrtl.options.{Dependency} -import firrtl.stage.TransformManager.{TransformDependency} -import firrtl.stage.{Forms} +import firrtl.options.Dependency +import firrtl.stage.Forms +import firrtl.stage.TransformManager.TransformDependency case class ReParentCircuitAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] { diff --git a/tapeout/src/main/scala/transforms/RemoveUnusedModules.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala similarity index 91% rename from tapeout/src/main/scala/transforms/RemoveUnusedModules.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala index 3feb6736..7aac8978 100644 --- a/tapeout/src/main/scala/transforms/RemoveUnusedModules.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala @@ -3,12 +3,12 @@ package barstools.tapeout.transforms import firrtl._ +import firrtl.annotations.ModuleTarget import firrtl.ir._ -import firrtl.annotations.{ModuleTarget} -import firrtl.stage.TransformManager.{TransformDependency} -import firrtl.options.{Dependency} -import firrtl.stage.{Forms} -import firrtl.passes.memlib.{ReplSeqMem} +import firrtl.options.Dependency +import firrtl.passes.memlib.ReplSeqMem +import firrtl.stage.Forms +import firrtl.stage.TransformManager.TransformDependency // Removes all the unused modules in a circuit by recursing through every // instance (starting at the main module) diff --git a/tapeout/src/main/scala/transforms/ResetInverter.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala similarity index 100% rename from tapeout/src/main/scala/transforms/ResetInverter.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala diff --git a/tapeout/src/main/scala/transforms/retime/Retime.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala similarity index 100% rename from tapeout/src/main/scala/transforms/retime/Retime.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala diff --git a/tapeout/src/main/scala/transforms/utils/FileUtils.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala similarity index 100% rename from tapeout/src/main/scala/transforms/utils/FileUtils.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala diff --git a/tapeout/src/main/scala/transforms/utils/LowerAnnotations.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala similarity index 100% rename from tapeout/src/main/scala/transforms/utils/LowerAnnotations.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala diff --git a/tapeout/src/main/scala/transforms/utils/ProgrammaticBundle.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala similarity index 100% rename from tapeout/src/main/scala/transforms/utils/ProgrammaticBundle.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala diff --git a/tapeout/src/main/scala/transforms/utils/YamlHelpers.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala similarity index 100% rename from tapeout/src/main/scala/transforms/utils/YamlHelpers.scala rename to tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala diff --git a/tapeout/src/test/scala/transforms/ResetInverterSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala similarity index 95% rename from tapeout/src/test/scala/transforms/ResetInverterSpec.scala rename to tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala index 9f23c3a8..9a0a1f6d 100644 --- a/tapeout/src/test/scala/transforms/ResetInverterSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala @@ -3,7 +3,7 @@ package barstools.tapeout.transforms import chisel3._ -import chisel3.stage.{ChiselStage, ChiselGeneratorAnnotation} +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import firrtl.{EmittedFirrtlCircuitAnnotation, EmittedFirrtlModuleAnnotation} import org.scalatest.{FreeSpec, Matchers} diff --git a/tapeout/src/test/scala/transforms/retime/RetimeSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala similarity index 94% rename from tapeout/src/test/scala/transforms/retime/RetimeSpec.scala rename to tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala index 35678991..d5168292 100644 --- a/tapeout/src/test/scala/transforms/retime/RetimeSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala @@ -1,12 +1,10 @@ // See LICENSE for license details. -package barstools.tapeout.transforms.retime.test +package barstools.tapeout.transforms.retime import chisel3._ -import chisel3.stage.{ChiselStage, ChiselGeneratorAnnotation} -import firrtl.{EmittedFirrtlCircuitAnnotation, EmittedFirrtlModuleAnnotation} -import barstools.tapeout.transforms.retime.RetimeLib -import firrtl.FileUtils +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} +import firrtl.{EmittedFirrtlCircuitAnnotation, EmittedFirrtlModuleAnnotation, FileUtils} import logger.Logger import org.scalatest.{FlatSpec, Matchers} From 93f86a5bc67ccc87f72cc1cb71204a718c1f516c Mon Sep 17 00:00:00 2001 From: chick Date: Wed, 3 Feb 2021 17:49:14 -0800 Subject: [PATCH 3/8] Reformat all scala files in iocells - Mostly this reformat comments and large argument lists to classes and methods --- .../barstools.iocell.chisel/Analog.scala | 6 +- .../barstools.iocell.chisel/IOCell.scala | 130 +++++++++--------- 2 files changed, 69 insertions(+), 67 deletions(-) diff --git a/iocell/src/main/scala/barstools.iocell.chisel/Analog.scala b/iocell/src/main/scala/barstools.iocell.chisel/Analog.scala index e1b4fc78..0cdfc493 100644 --- a/iocell/src/main/scala/barstools.iocell.chisel/Analog.scala +++ b/iocell/src/main/scala/barstools.iocell.chisel/Analog.scala @@ -6,8 +6,10 @@ import chisel3._ import chisel3.util.{HasBlackBoxResource} import chisel3.experimental.{Analog, IntParam} -class AnalogConst(value: Int, width: Int = 1) extends BlackBox(Map("CONST" -> IntParam(value), "WIDTH" -> IntParam(width))) with HasBlackBoxResource{ - val io = IO(new Bundle {val io = Analog(width.W) } ) +class AnalogConst(value: Int, width: Int = 1) + extends BlackBox(Map("CONST" -> IntParam(value), "WIDTH" -> IntParam(width))) + with HasBlackBoxResource { + val io = IO(new Bundle { val io = Analog(width.W) }) addResource("/barstools/iocell/vsrc/Analog.v") } diff --git a/iocell/src/main/scala/barstools.iocell.chisel/IOCell.scala b/iocell/src/main/scala/barstools.iocell.chisel/IOCell.scala index a5926030..d244d298 100644 --- a/iocell/src/main/scala/barstools.iocell.chisel/IOCell.scala +++ b/iocell/src/main/scala/barstools.iocell.chisel/IOCell.scala @@ -4,7 +4,7 @@ package barstools.iocell.chisel import chisel3._ import chisel3.util.{Cat, HasBlackBoxResource} -import chisel3.experimental.{Analog, DataMirror, IO, BaseModule} +import chisel3.experimental.{Analog, BaseModule, DataMirror, IO} // The following four IO cell bundle types are bare-minimum functional connections // for modeling 4 different IO cell scenarios. The intention is that the user @@ -13,24 +13,22 @@ import chisel3.experimental.{Analog, DataMirror, IO, BaseModule} // (https://github.com/sifive/sifive-blocks/blob/master/src/main/scala/devices/pinctrl/PinCtrl.scala), // but we want to avoid a dependency on an external libraries. -/** - * The base IO bundle for an analog signal (typically something with no digital buffers inside) - * pad: off-chip (external) connection - * core: internal connection - */ +/** The base IO bundle for an analog signal (typically something with no digital buffers inside) + * pad: off-chip (external) connection + * core: internal connection + */ class AnalogIOCellBundle extends Bundle { - val pad = Analog(1.W) // Pad/bump signal (off-chip) - val core = Analog(1.W) // core signal (on-chip) + val pad = Analog(1.W) // Pad/bump signal (off-chip) + val core = Analog(1.W) // core signal (on-chip) } -/** - * The base IO bundle for a signal with runtime-controllable direction - * pad: off-chip (external) connection - * i: input to chip logic (output from IO cell) - * ie: enable signal for i - * o: output from chip logic (input to IO cell) - * oe: enable signal for o - */ +/** The base IO bundle for a signal with runtime-controllable direction + * pad: off-chip (external) connection + * i: input to chip logic (output from IO cell) + * ie: enable signal for i + * o: output from chip logic (input to IO cell) + * oe: enable signal for o + */ class DigitalGPIOCellBundle extends Bundle { val pad = Analog(1.W) val i = Output(Bool()) @@ -39,24 +37,22 @@ class DigitalGPIOCellBundle extends Bundle { val oe = Input(Bool()) } -/** - * The base IO bundle for a digital output signal - * pad: off-chip (external) connection - * o: output from chip logic (input to IO cell) - * oe: enable signal for o - */ +/** The base IO bundle for a digital output signal + * pad: off-chip (external) connection + * o: output from chip logic (input to IO cell) + * oe: enable signal for o + */ class DigitalOutIOCellBundle extends Bundle { val pad = Output(Bool()) val o = Input(Bool()) val oe = Input(Bool()) } -/** - * The base IO bundle for a digital input signal - * pad: off-chip (external) connection - * i: input to chip logic (output from IO cell) - * ie: enable signal for i - */ +/** The base IO bundle for a digital input signal + * pad: off-chip (external) connection + * i: input to chip logic (output from IO cell) + * ie: enable signal for i + */ class DigitalInIOCellBundle extends Bundle { val pad = Input(Bool()) val i = Output(Bool()) @@ -102,11 +98,10 @@ class GenericDigitalOutIOCell extends GenericIOCell with DigitalOutIOCell { val io = IO(new DigitalOutIOCellBundle) } - trait IOCellTypeParams { def analog(): AnalogIOCell - def gpio(): DigitalGPIOCell - def input(): DigitalInIOCell + def gpio(): DigitalGPIOCell + def input(): DigitalInIOCell def output(): DigitalOutIOCell } @@ -118,47 +113,49 @@ case class GenericIOCellParams() extends IOCellTypeParams { } object IOCell { - /** - * From within a RawModule or MultiIOModule context, generate new module IOs from a given - * signal and return the new IO and a Seq containing all generated IO cells. - * @param coreSignal The signal onto which to add IO cells - * @param name An optional name or name prefix to use for naming IO cells - * @param abstractResetAsAsync When set, will coerce abstract resets to - * AsyncReset, and otherwise to Bool (sync reset) - * @return A tuple of (the generated IO data node, a Seq of all generated IO cell instances) - */ - def generateIOFromSignal[T <: Data](coreSignal: T, name: String, - typeParams: IOCellTypeParams = GenericIOCellParams(), - abstractResetAsAsync: Boolean = false): (T, Seq[IOCell]) = - { + + /** From within a RawModule or MultiIOModule context, generate new module IOs from a given + * signal and return the new IO and a Seq containing all generated IO cells. + * @param coreSignal The signal onto which to add IO cells + * @param name An optional name or name prefix to use for naming IO cells + * @param abstractResetAsAsync When set, will coerce abstract resets to + * AsyncReset, and otherwise to Bool (sync reset) + * @return A tuple of (the generated IO data node, a Seq of all generated IO cell instances) + */ + def generateIOFromSignal[T <: Data]( + coreSignal: T, + name: String, + typeParams: IOCellTypeParams = GenericIOCellParams(), + abstractResetAsAsync: Boolean = false + ): (T, Seq[IOCell]) = { val padSignal = IO(DataMirror.internal.chiselTypeClone[T](coreSignal)).suggestName(name) val resetFn = if (abstractResetAsAsync) toAsyncReset else toSyncReset val iocells = IOCell.generateFromSignal(coreSignal, padSignal, Some(s"iocell_$name"), typeParams, resetFn) (padSignal, iocells) } - /** - * Connect two identical signals together by adding IO cells between them and return a Seq - * containing all generated IO cells. - * @param coreSignal The core-side (internal) signal onto which to connect/add IO cells - * @param padSignal The pad-side (external) signal onto which to connect IO cells - * @param name An optional name or name prefix to use for naming IO cells - * @return A Seq of all generated IO cell instances - */ - val toSyncReset: (Reset) => Bool = _.toBool + /** Connect two identical signals together by adding IO cells between them and return a Seq + * containing all generated IO cells. + * @param coreSignal The core-side (internal) signal onto which to connect/add IO cells + * @param padSignal The pad-side (external) signal onto which to connect IO cells + * @param name An optional name or name prefix to use for naming IO cells + * @return A Seq of all generated IO cell instances + */ + val toSyncReset: (Reset) => Bool = _.toBool val toAsyncReset: (Reset) => AsyncReset = _.asAsyncReset def generateFromSignal[T <: Data, R <: Reset]( - coreSignal: T, - padSignal: T, - name: Option[String] = None, - typeParams: IOCellTypeParams = GenericIOCellParams(), - concretizeResetFn : (Reset) => R = toSyncReset): Seq[IOCell] = - { + coreSignal: T, + padSignal: T, + name: Option[String] = None, + typeParams: IOCellTypeParams = GenericIOCellParams(), + concretizeResetFn: (Reset) => R = toSyncReset + ): Seq[IOCell] = { def genCell[T <: Data]( - castToBool: (T) => Bool, - castFromBool: (Bool) => T)( - coreSignal: T, - padSignal: T): Seq[IOCell] = { + castToBool: (T) => Bool, + castFromBool: (Bool) => T + )(coreSignal: T, + padSignal: T + ): Seq[IOCell] = { DataMirror.directionOf(coreSignal) match { case ActualDirection.Input => { val iocell = typeParams.input() @@ -188,7 +185,10 @@ object IOCell { if (coreSignal.getWidth == 0) { Seq() } else { - require(coreSignal.getWidth == 1, "Analogs wider than 1 bit are not supported because we can't bit-select Analogs (https://github.com/freechipsproject/chisel3/issues/536)") + require( + coreSignal.getWidth == 1, + "Analogs wider than 1 bit are not supported because we can't bit-select Analogs (https://github.com/freechipsproject/chisel3/issues/536)" + ) val iocell = typeParams.analog() name.foreach(n => iocell.suggestName(n)) iocell.io.core <> coreSignal @@ -204,7 +204,7 @@ object IOCell { // This dummy assignment will prevent invalid firrtl from being emitted DataMirror.directionOf(coreSignal) match { case ActualDirection.Input => coreSignal := 0.U - case _ => {} + case _ => {} } Seq() } else { From 68c3425493501b17fac5af62fbf2432263784292 Mon Sep 17 00:00:00 2001 From: chick Date: Wed, 3 Feb 2021 17:50:36 -0800 Subject: [PATCH 4/8] Reformat all scala files in macros - Mostly this reformat comments and large argument lists to classes and methods --- .../scala/barstools/macros/CostMetric.scala | 84 +-- .../barstools/macros/MacroCompiler.scala | 529 +++++++++------- .../scala/barstools/macros/SynFlops.scala | 240 ++++---- .../main/scala/barstools/macros/Utils.scala | 266 +++++---- .../src/test/resources/lib-MaskPortTest.json | 48 +- .../test/resources/lib-WriteEnableTest.json | 42 +- .../scala/barstools/macros/CostFunction.scala | 39 +- .../barstools/macros/MacroCompilerSpec.scala | 565 +++++++++++------- .../test/scala/barstools/macros/Masks.scala | 163 +++-- .../scala/barstools/macros/MultiPort.scala | 294 ++++++--- .../scala/barstools/macros/SRAMCompiler.scala | 3 +- .../barstools/macros/SimpleSplitDepth.scala | 188 +++--- .../barstools/macros/SimpleSplitWidth.scala | 251 +++++--- .../barstools/macros/SpecificExamples.scala | 106 ++-- .../scala/barstools/macros/SynFlops.scala | 129 ++-- 15 files changed, 1743 insertions(+), 1204 deletions(-) diff --git a/macros/src/main/scala/barstools/macros/CostMetric.scala b/macros/src/main/scala/barstools/macros/CostMetric.scala index 45020163..f39303d3 100644 --- a/macros/src/main/scala/barstools/macros/CostMetric.scala +++ b/macros/src/main/scala/barstools/macros/CostMetric.scala @@ -2,27 +2,25 @@ package barstools.macros -/** - * Trait which can calculate the cost of compiling a memory against a certain - * library memory macro using a cost function. - */ +/** Trait which can calculate the cost of compiling a memory against a certain + * library memory macro using a cost function. + */ // TODO: eventually explore compiling a single target memory using multiple // different kinds of target memory. trait CostMetric extends Serializable { - /** - * Cost function that returns the cost of compiling a memory using a certain - * macro. - * - * @param mem Memory macro to compile (target memory) - * @param lib Library memory macro to use (library memory) - * @return The cost of this compile, defined by this cost metric, or None if - * it cannot be compiled. - */ + + /** Cost function that returns the cost of compiling a memory using a certain + * macro. + * + * @param mem Memory macro to compile (target memory) + * @param lib Library memory macro to use (library memory) + * @return The cost of this compile, defined by this cost metric, or None if + * it cannot be compiled. + */ def cost(mem: Macro, lib: Macro): Option[Double] - /** - * Helper function to return the map of arguments (or an empty map if there are none). - */ + /** Helper function to return the map of arguments (or an empty map if there are none). + */ def commandLineParams(): Map[String, String] // We also want this to show up for the class itself. @@ -40,8 +38,9 @@ trait CostMetricCompanion { // Some default cost functions. /** Palmer's old metric. - * TODO: figure out what is the difference between this metric and the current - * default metric and either revive or delete this metric. */ + * TODO: figure out what is the difference between this metric and the current + * default metric and either revive or delete this metric. + */ object OldMetric extends CostMetric with CostMetricCompanion { override def cost(mem: Macro, lib: Macro): Option[Double] = { /* Palmer: A quick cost function (that must be kept in sync with @@ -58,13 +57,12 @@ object OldMetric extends CostMetric with CostMetricCompanion { override def construct(m: Map[String, String]) = OldMetric } -/** - * An external cost function. - * Calls the specified path with paths to the JSON MDF representation of the mem - * and lib macros. The external executable should print a Double. - * None will be returned if the external executable does not print a valid - * Double. - */ +/** An external cost function. + * Calls the specified path with paths to the JSON MDF representation of the mem + * and lib macros. The external executable should print a Double. + * None will be returned if the external executable does not print a valid + * Double. + */ class ExternalMetric(path: String) extends CostMetric { import mdf.macrolib.Utils.writeMacroToPath @@ -105,7 +103,7 @@ object ExternalMetric extends CostMetricCompanion { override def construct(m: Map[String, String]) = { val pathOption = m.get("path") pathOption match { - case Some(path:String) => new ExternalMetric(path) + case Some(path: String) => new ExternalMetric(path) case _ => throw new IllegalArgumentException("ExternalMetric missing option 'path'") } } @@ -115,14 +113,17 @@ object ExternalMetric extends CostMetricCompanion { // TODO: write tests for this function to make sure it selects the right things object DefaultMetric extends CostMetric with CostMetricCompanion { override def cost(mem: Macro, lib: Macro): Option[Double] = { - val memMask = mem.src.ports map (_.maskGran) find (_.isDefined) map (_.get) - val libMask = lib.src.ports map (_.maskGran) find (_.isDefined) map (_.get) + val memMask = mem.src.ports.map(_.maskGran).find(_.isDefined).map(_.get) + val libMask = lib.src.ports.map(_.maskGran).find(_.isDefined).map(_.get) val memWidth = (memMask, libMask) match { case (None, _) => mem.src.width - case (Some(p), None) => (mem.src.width/p)*math.ceil(p.toDouble/lib.src.width)*lib.src.width //We map the mask to distinct memories + case (Some(p), None) => + (mem.src.width / p) * math.ceil( + p.toDouble / lib.src.width + ) * lib.src.width //We map the mask to distinct memories case (Some(p), Some(m)) => { - if(m <= p) (mem.src.width/p)*math.ceil(p.toDouble/m)*m //Using multiple m's to create a p (integeraly) - else (mem.src.width/p)*m //Waste the extra maskbits + if (m <= p) (mem.src.width / p) * math.ceil(p.toDouble / m) * m //Using multiple m's to create a p (integeraly) + else (mem.src.width / p) * m //Waste the extra maskbits } } val depthCost = math.ceil(mem.src.depth.toDouble / lib.src.depth.toDouble) @@ -130,10 +131,10 @@ object DefaultMetric extends CostMetric with CostMetricCompanion { val bitsCost = (lib.src.depth * lib.src.width).toDouble // Fraction of wasted bits plus const per mem val requestedBits = (mem.src.depth * mem.src.width).toDouble - val bitsWasted = depthCost*widthCost*bitsCost - requestedBits + val bitsWasted = depthCost * widthCost * bitsCost - requestedBits val wastedConst = 0.05 // 0 means waste as few bits with no regard for instance count - val costPerInst = wastedConst*depthCost*widthCost - Some(1.0*bitsWasted/requestedBits+costPerInst) + val costPerInst = wastedConst * depthCost * widthCost + Some(1.0 * bitsWasted / requestedBits + costPerInst) } override def commandLineParams = Map() @@ -148,10 +149,11 @@ object MacroCompilerUtil { // Adapted from https://stackoverflow.com/a/134918 /** Serialize an arbitrary object to String. - * Used to pass structured values through as an annotation. */ + * Used to pass structured values through as an annotation. + */ def objToString(o: Serializable): String = { val baos: ByteArrayOutputStream = new ByteArrayOutputStream - val oos: ObjectOutputStream = new ObjectOutputStream(baos) + val oos: ObjectOutputStream = new ObjectOutputStream(baos) oos.writeObject(o) oos.close() return Base64.getEncoder.encodeToString(baos.toByteArray) @@ -168,6 +170,7 @@ object MacroCompilerUtil { } object CostMetric { + /** Define some default metric. */ val default: CostMetric = DefaultMetric @@ -178,11 +181,10 @@ object CostMetric { registerCostMetric(ExternalMetric) registerCostMetric(DefaultMetric) - /** - * Register a cost metric. - * @param createFuncHelper Companion object to fetch the name and construct - * the metric. - */ + /** Register a cost metric. + * @param createFuncHelper Companion object to fetch the name and construct + * the metric. + */ def registerCostMetric(createFuncHelper: CostMetricCompanion): Unit = { costMetricCreators.update(createFuncHelper.name, createFuncHelper) } diff --git a/macros/src/main/scala/barstools/macros/MacroCompiler.scala b/macros/src/main/scala/barstools/macros/MacroCompiler.scala index 416f2d2c..5ecfea8f 100644 --- a/macros/src/main/scala/barstools/macros/MacroCompiler.scala +++ b/macros/src/main/scala/barstools/macros/MacroCompiler.scala @@ -1,10 +1,9 @@ // See LICENSE for license details. -/** - * Terminology note: - * mem - target memory to compile, in design (e.g. Mem() in rocket) - * lib - technology SRAM(s) to use to compile mem - */ +/** Terminology note: + * mem - target memory to compile, in design (e.g. Mem() in rocket) + * lib - technology SRAM(s) to use to compile mem + */ package barstools.macros @@ -29,56 +28,75 @@ case class MacroCompilerAnnotation(content: String) extends NoTargetAnnotation { def params: Params = MacroCompilerUtil.objFromString(content).asInstanceOf[Params] } - -/** - * The MacroCompilerAnnotation to trigger the macro compiler. - * Note that this annotation does NOT actually target any modules for - * compilation. It simply holds all the settings for the memory compiler. The - * actual selection of which memories to compile is set in the Params. - * - * To use, simply annotate the entire circuit itself with this annotation and - * include [[MacroCompilerTransform]]. - * - */ +/** The MacroCompilerAnnotation to trigger the macro compiler. + * Note that this annotation does NOT actually target any modules for + * compilation. It simply holds all the settings for the memory compiler. The + * actual selection of which memories to compile is set in the Params. + * + * To use, simply annotate the entire circuit itself with this annotation and + * include [[MacroCompilerTransform]]. + */ object MacroCompilerAnnotation { + /** Macro compiler mode. */ sealed trait CompilerMode + /** Strict mode - must compile all memories or error out. */ case object Strict extends CompilerMode + /** Synflops mode - compile all memories with synflops (do not map to lib at all). */ case object Synflops extends CompilerMode + /** CompileAndSynflops mode - compile all memories and create mock versions of the target libs with synflops. */ case object CompileAndSynflops extends CompilerMode - /** FallbackSynflops - compile all memories to SRAM when possible and fall back to synflops if a memory fails. **/ + + /** FallbackSynflops - compile all memories to SRAM when possible and fall back to synflops if a memory fails. * */ case object FallbackSynflops extends CompilerMode - /** CompileAvailable - compile what is possible and do nothing with uncompiled memories. **/ + + /** CompileAvailable - compile what is possible and do nothing with uncompiled memories. * */ case object CompileAvailable extends CompilerMode - /** - * The default mode for the macro compiler. - * TODO: Maybe set the default to FallbackSynflops (typical for - * vlsi_mem_gen-like scripts) once it's implemented? - */ + /** The default mode for the macro compiler. + * TODO: Maybe set the default to FallbackSynflops (typical for + * vlsi_mem_gen-like scripts) once it's implemented? + */ val Default = CompileAvailable // Options as list of (CompilerMode, command-line name, description) val options: Seq[(CompilerMode, String, String)] = Seq( (Default, "default", "Select the default option from below."), (Strict, "strict", "Compile all memories to library or return an error."), - (Synflops, "synflops", "Produces synthesizable flop-based memories for all memories (do not map to lib at all); likely useful for simulation purposes."), - (CompileAndSynflops, "compileandsynflops", "Compile all memories and create mock versions of the target libs with synflops; likely also useful for simulation purposes."), - (FallbackSynflops, "fallbacksynflops", "Compile all memories to library when possible and fall back to synthesizable flop-based memories when library synth is not possible."), - (CompileAvailable, "compileavailable", "Compile all memories to library when possible and do nothing in case of errors. (default)") + ( + Synflops, + "synflops", + "Produces synthesizable flop-based memories for all memories (do not map to lib at all); likely useful for simulation purposes." + ), + ( + CompileAndSynflops, + "compileandsynflops", + "Compile all memories and create mock versions of the target libs with synflops; likely also useful for simulation purposes." + ), + ( + FallbackSynflops, + "fallbacksynflops", + "Compile all memories to library when possible and fall back to synthesizable flop-based memories when library synth is not possible." + ), + ( + CompileAvailable, + "compileavailable", + "Compile all memories to library when possible and do nothing in case of errors. (default)" + ) ) /** Helper function to select a compiler mode. */ - def stringToCompilerMode(str: String): CompilerMode = options.collectFirst { case (mode, cmd, _) if cmd == str => mode } match { + def stringToCompilerMode(str: String): CompilerMode = options.collectFirst { + case (mode, cmd, _) if cmd == str => mode + } match { case Some(x) => x - case None => throw new IllegalArgumentException("No such compiler mode " + str) + case None => throw new IllegalArgumentException("No such compiler mode " + str) } - /** - * Parameters associated to this MacroCompilerAnnotation. + /** Parameters associated to this MacroCompilerAnnotation. * * @param mem Path to memory lib * @param memFormat Type of memory lib (Some("conf"), Some("mdf"), or None (defaults to mdf)) @@ -89,26 +107,34 @@ object MacroCompilerAnnotation { * @param forceCompile Set of memories to force compiling to lib regardless of the mode * @param forceSynflops Set of memories to force compiling as flops regardless of the mode */ - case class Params(mem: String, memFormat: Option[String], lib: Option[String], hammerIR: Option[String], - costMetric: CostMetric, mode: CompilerMode, useCompiler: Boolean, - forceCompile: Set[String], forceSynflops: Set[String]) + case class Params( + mem: String, + memFormat: Option[String], + lib: Option[String], + hammerIR: Option[String], + costMetric: CostMetric, + mode: CompilerMode, + useCompiler: Boolean, + forceCompile: Set[String], + forceSynflops: Set[String]) - /** - * Create a MacroCompilerAnnotation. - * @param c Top-level circuit name (see class description) - * @param p Parameters (see above). - */ + /** Create a MacroCompilerAnnotation. + * @param c Top-level circuit name (see class description) + * @param p Parameters (see above). + */ def apply(c: String, p: Params): MacroCompilerAnnotation = MacroCompilerAnnotation(MacroCompilerUtil.objToString(p)) } -class MacroCompilerPass(mems: Option[Seq[Macro]], - libs: Option[Seq[Macro]], - compilers: Option[SRAMCompiler], - hammerIR: Option[String], - costMetric: CostMetric = CostMetric.default, - mode: MacroCompilerAnnotation.CompilerMode = MacroCompilerAnnotation.Default) extends firrtl.passes.Pass { +class MacroCompilerPass( + mems: Option[Seq[Macro]], + libs: Option[Seq[Macro]], + compilers: Option[SRAMCompiler], + hammerIR: Option[String], + costMetric: CostMetric = CostMetric.default, + mode: MacroCompilerAnnotation.CompilerMode = MacroCompilerAnnotation.Default) + extends firrtl.passes.Pass { // Helper function to check the legality of bitPairs. // e.g. ((0,21), (22,43)) is legal // ((0,21), (22,21)) is illegal and will throw an assert @@ -120,8 +146,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], }) } - /** - * Calculate bit pairs. + /** Calculate bit pairs. * This is a list of submemories by width. * The tuples are (lsb, msb) inclusive. * Example: (0, 7) and (8, 15) might be a split for a width=16 memory into two width=8 target memories. @@ -132,7 +157,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], * @return Bit pairs or empty list if there was an error. */ private def calculateBitPairs(mem: Macro, lib: Macro): Seq[(BigInt, BigInt)] = { - val pairedPorts = mem.sortedPorts zip lib.sortedPorts + val pairedPorts = mem.sortedPorts.zip(lib.sortedPorts) val bitPairs = ArrayBuffer[(BigInt, BigInt)]() var currentLSB: BigInt = 0 @@ -203,7 +228,9 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], splitMemory(memMask.get) } else { // e.g. mem mask = 13, lib width = 8 - System.err.println(s"Unmasked target memory: unaligned mem maskGran $p with lib (${lib.src.name}) width ${libPort.src.width.get} not supported") + System.err.println( + s"Unmasked target memory: unaligned mem maskGran $p with lib (${lib.src.name}) width ${libPort.src.width.get} not supported" + ) return Seq() } } @@ -266,9 +293,11 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], } def compile(mem: Macro, lib: Macro): Option[(Module, Macro)] = { - assert(mem.sortedPorts.lengthCompare(lib.sortedPorts.length) == 0, - "mem and lib should have an equal number of ports") - val pairedPorts = mem.sortedPorts zip lib.sortedPorts + assert( + mem.sortedPorts.lengthCompare(lib.sortedPorts.length) == 0, + "mem and lib should have an equal number of ports" + ) + val pairedPorts = mem.sortedPorts.zip(lib.sortedPorts) // Width mapping. See calculateBitPairs. val bitPairs: Seq[(BigInt, BigInt)] = calculateBitPairs(mem, lib) @@ -287,14 +316,14 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], /* Palmer: If we've got a parallel memory then we've got to take the * address bits into account. */ if (mem.src.depth > lib.src.depth) { - mem.src.ports foreach { port => + mem.src.ports.foreach { port => val high = MacroCompilerMath.ceilLog2(mem.src.depth) val low = MacroCompilerMath.ceilLog2(lib.src.depth) val ref = WRef(port.address.name) val nodeName = s"${ref.name}_sel" - val tpe = UIntType(IntWidth(high-low)) + val tpe = UIntType(IntWidth(high - low)) selects(ref.name) = WRef(nodeName, tpe) - stmts += DefNode(NoInfo, nodeName, bits(ref, high-1, low)) + stmts += DefNode(NoInfo, nodeName, bits(ref, high - 1, low)) // Donggyu: output selection should be piped if (port.output.isDefined) { val regName = s"${ref.name}_sel_reg" @@ -303,7 +332,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], and(WRef(ce.name, BoolType), WRef(re.name, BoolType)) case (Some(ce), None) => WRef(ce.name, BoolType) case (None, Some(re)) => WRef(re.name, BoolType) - case (None, None) => one + case (None, None) => one } selectRegs(ref.name) = WRef(regName, tpe) stmts += DefRegister(NoInfo, regName, tpe, WRef(port.clock.get.name), zero, WRef(regName)) @@ -317,18 +346,18 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], // Create the instance. stmts += WDefInstance(NoInfo, name, lib.src.name, lib.tpe) // Connect extra ports of the lib. - stmts ++= lib.extraPorts map { case (portName, portValue) => + stmts ++= lib.extraPorts.map { case (portName, portValue) => Connect(NoInfo, WSubField(WRef(name), portName), portValue) } } for ((memPort, libPort) <- pairedPorts) { - val addrMatch = selects get memPort.src.address.name match { + val addrMatch = selects.get(memPort.src.address.name) match { case None => one case Some(addr) => val index = UIntLiteral(i, IntWidth(bitWidth(addr.tpe))) DoPrim(PrimOps.Eq, Seq(addr, index), Nil, index.tpe) } - val addrMatchReg = selectRegs get memPort.src.address.name match { + val addrMatchReg = selectRegs.get(memPort.src.address.name) match { case None => one case Some(reg) => val index = UIntLiteral(i, IntWidth(bitWidth(reg.tpe))) @@ -341,29 +370,22 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], for (((low, high), j) <- bitPairs.zipWithIndex) { val inst = WRef(s"mem_${i}_${j}", lib.tpe) - def connectPorts2(mem: Expression, - lib: String, - polarity: Option[PortPolarity]): Statement = + def connectPorts2(mem: Expression, lib: String, polarity: Option[PortPolarity]): Statement = Connect(NoInfo, WSubField(inst, lib), portToExpression(mem, polarity)) - def connectPorts(mem: Expression, - lib: String, - polarity: PortPolarity): Statement = + def connectPorts(mem: Expression, lib: String, polarity: PortPolarity): Statement = connectPorts2(mem, lib, Some(polarity)) // Clock port mapping /* Palmer: FIXME: I don't handle memories with read/write clocks yet. */ /* Colin not all libPorts have clocks but all memPorts do*/ libPort.src.clock.foreach { cPort => - stmts += connectPorts(WRef(memPort.src.clock.get.name), - cPort.name, - cPort.polarity) } + stmts += connectPorts(WRef(memPort.src.clock.get.name), cPort.name, cPort.polarity) + } // Adress port mapping /* Palmer: The address port to a memory is just the low-order bits of * the top address. */ - stmts += connectPorts(WRef(memPort.src.address.name), - libPort.src.address.name, - libPort.src.address.polarity) + stmts += connectPorts(WRef(memPort.src.address.name), libPort.src.address.name, libPort.src.address.polarity) // Output port mapping (memPort.src.output, libPort.src.output) match { @@ -373,20 +395,20 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], * done after generating all the memories. This saves up the * output statements for later. */ val name = s"${mem}_${i}_${j}" // This name is the output from the instance (mem vs ${mem}). - val exp = portToExpression(bits(WSubField(inst, lib), high-low, 0), Some(lib_polarity)) + val exp = portToExpression(bits(WSubField(inst, lib), high - low, 0), Some(lib_polarity)) stmts += DefNode(NoInfo, name, exp) cats += WRef(name) case (None, Some(lib)) => - /* Palmer: If the inner memory has an output port but the outer - * one doesn't then it's safe to just leave the outer - * port floating. */ + /* Palmer: If the inner memory has an output port but the outer + * one doesn't then it's safe to just leave the outer + * port floating. */ case (None, None) => - /* Palmer: If there's no output ports at all (ie, read-only - * port on the memory) then just don't worry about it, - * there's nothing to do. */ + /* Palmer: If there's no output ports at all (ie, read-only + * port on the memory) then just don't worry about it, + * there's nothing to do. */ case (Some(PolarizedPort(mem, _)), None) => - System.err println "WARNING: Unable to match output ports on memory" - System.err println s" outer output port: ${mem}" + System.err.println("WARNING: Unable to match output ports on memory") + System.err.println(s" outer output port: ${mem}") return None } @@ -396,7 +418,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], /* Palmer: The input port to a memory just needs to happen in parallel, * this does a part select to narrow the memory down. */ stmts += connectPorts(bits(WRef(mem), high, low), lib, lib_polarity) - case (None, Some(lib)) => + case (None, Some(lib)) => /* Palmer: If the inner memory has an input port but the other * one doesn't then it's safe to just leave the inner * port floating. This should be handled by the @@ -405,12 +427,12 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], //Firrtl cares about dangling inputs now tie it off stmts += IsInvalid(NoInfo, WSubField(inst, lib.name)) case (None, None) => - /* Palmer: If there's no input ports at all (ie, read-only - * port on the memory) then just don't worry about it, - * there's nothing to do. */ + /* Palmer: If there's no input ports at all (ie, read-only + * port on the memory) then just don't worry about it, + * there's nothing to do. */ case (Some(PolarizedPort(mem, _)), None) => - System.err println "WARNING: Unable to match input ports on memory" - System.err println s" outer input port: ${mem}" + System.err.println("WARNING: Unable to match input ports on memory") + System.err.println(s" outer input port: ${mem}") return None } @@ -429,26 +451,33 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], // Example: if we have a lib whose maskGran is 8 but our mem's maskGran is 4. // The other case is if we're using a larger lib than mem. val usingLessThanLibMaskGran = (memPort.src.maskGran.get < libPort.src.effectiveMaskGran) - val effectiveLibWidth = if (usingLessThanLibMaskGran) - memPort.src.maskGran.get - else - libPort.src.width.get + val effectiveLibWidth = + if (usingLessThanLibMaskGran) + memPort.src.maskGran.get + else + libPort.src.width.get - cat(((0 until libPort.src.width.get by libPort.src.effectiveMaskGran) map (i => { - if (usingLessThanLibMaskGran && i >= effectiveLibWidth) { - // If the memMaskGran is smaller than the lib's gran, then - // zero out the upper bits. - zero - } else { - if ((low + i) >= memPort.src.width.get) { - // If our bit is larger than the whole width of the mem, just zero out the upper bits. - zero - } else { - // Pick the appropriate bit from the mem mask. - bits(WRef(mem), (low + i) / memPort.src.effectiveMaskGran) - } - } - })).reverse) + cat( + ( + (0 until libPort.src.width.get by libPort.src.effectiveMaskGran) + .map(i => { + if (usingLessThanLibMaskGran && i >= effectiveLibWidth) { + // If the memMaskGran is smaller than the lib's gran, then + // zero out the upper bits. + zero + } else { + if ((low + i) >= memPort.src.width.get) { + // If our bit is larger than the whole width of the mem, just zero out the upper bits. + zero + } else { + // Pick the appropriate bit from the mem mask. + bits(WRef(mem), (low + i) / memPort.src.effectiveMaskGran) + } + } + }) + ) + .reverse + ) } case None => /* If there is a lib mask port but no mem mask port, just turn on @@ -482,7 +511,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], // Chip enable port mapping val memChipEnable = memPort.src.chipEnable match { case Some(PolarizedPort(mem, _)) => WRef(mem) - case None => one + case None => one } // Read enable port mapping @@ -501,7 +530,11 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], * implement the outer memory's collection of ports using what * the inner memory has availiable. */ ((libPort.src.maskPort, libPort.src.writeEnable, libPort.src.chipEnable): @unchecked) match { - case (Some(PolarizedPort(mask, mask_polarity)), Some(PolarizedPort(we, we_polarity)), Some(PolarizedPort(en, en_polarity))) => + case ( + Some(PolarizedPort(mask, mask_polarity)), + Some(PolarizedPort(we, we_polarity)), + Some(PolarizedPort(en, en_polarity)) + ) => /* Palmer: This is the simple option: every port exists. */ stmts += connectPorts(memMask, mask, mask_polarity) stmts += connectPorts(andAddrMatch(memWriteEnable), we, we_polarity) @@ -509,8 +542,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], case (Some(PolarizedPort(mask, mask_polarity)), Some(PolarizedPort(we, we_polarity)), None) => /* Palmer: If we don't have a chip enable but do have mask ports. */ stmts += connectPorts(memMask, mask, mask_polarity) - stmts += connectPorts(andAddrMatch(and(memWriteEnable, memChipEnable)), - we, we_polarity) + stmts += connectPorts(andAddrMatch(and(memWriteEnable, memChipEnable)), we, we_polarity) case (None, Some(PolarizedPort(we, we_polarity)), chipEnable) => if (bitWidth(memMask.tpe) == 1) { /* Palmer: If we're expected to provide mask ports without a @@ -518,13 +550,15 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], * write enable port instead of the mask port. */ chipEnable match { case Some(PolarizedPort(en, en_polarity)) => { - stmts += connectPorts(andAddrMatch(and(memWriteEnable, memMask)), - we, we_polarity) + stmts += connectPorts(andAddrMatch(and(memWriteEnable, memMask)), we, we_polarity) stmts += connectPorts(andAddrMatch(memChipEnable), en, en_polarity) } case _ => { - stmts += connectPorts(andAddrMatch(and(and(memWriteEnable, memChipEnable), memMask)), - we, we_polarity) + stmts += connectPorts( + andAddrMatch(and(and(memWriteEnable, memChipEnable), memMask)), + we, + we_polarity + ) } } } else { @@ -532,8 +566,8 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], return None } case (None, None, None) => - // No write ports to match up (this may be a read-only port). - // This isn't necessarily an error condition. + // No write ports to match up (this may be a read-only port). + // This isn't necessarily an error condition. } } // Cat macro outputs for selection @@ -541,7 +575,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], case Some(PolarizedPort(mem, _)) if cats.nonEmpty => val name = s"${mem}_${i}" stmts += DefNode(NoInfo, name, cat(cats.toSeq.reverse)) - (outputs getOrElseUpdate (mem, ArrayBuffer[(Expression, Expression)]())) += + (outputs.getOrElseUpdate(mem, ArrayBuffer[(Expression, Expression)]())) += (addrMatchReg -> WRef(name)) case _ => } @@ -549,15 +583,17 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], } // Connect mem outputs val zeroOutputValue: Expression = UIntLiteral(0, IntWidth(mem.src.width)) - mem.src.ports foreach { port => + mem.src.ports.foreach { port => port.output match { - case Some(PolarizedPort(mem, _)) => outputs get mem match { - case Some(select) => - val output = (select foldRight (zeroOutputValue)) { - case ((cond, tval), fval) => Mux(cond, tval, fval, fval.tpe) } - stmts += Connect(NoInfo, WRef(mem), output) - case None => - } + case Some(PolarizedPort(mem, _)) => + outputs.get(mem) match { + case Some(select) => + val output = (select.foldRight(zeroOutputValue)) { case ((cond, tval), fval) => + Mux(cond, tval, fval, fval.tpe) + } + stmts += Connect(NoInfo, WRef(mem), output) + case None => + } case None => } } @@ -572,79 +608,84 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], // Try to compile each of the memories in mems. // The 'state' is c.modules, which is a list of all the firrtl modules // in the 'circuit'. - (mems foldLeft c.modules){ (modules, mem) => - - val sram = mem.src - def groupMatchesMask(group: SRAMGroup, mem:SRAMMacro): Boolean = { - val memMask = mem.ports map (_.maskGran) find (_.isDefined) map (_.get) - val libMask = group.ports map (_.maskGran) find (_.isDefined) map (_.get) - (memMask, libMask) match { - case (None, _) => true - case (Some(_), None) => false - case (Some(m), Some(l)) => l <= m //Ignore memories that don't have nice mask + (mems.foldLeft(c.modules)) { (modules, mem) => + val sram = mem.src + def groupMatchesMask(group: SRAMGroup, mem: SRAMMacro): Boolean = { + val memMask = mem.ports.map(_.maskGran).find(_.isDefined).map(_.get) + val libMask = group.ports.map(_.maskGran).find(_.isDefined).map(_.get) + (memMask, libMask) match { + case (None, _) => true + case (Some(_), None) => false + case (Some(m), Some(l)) => l <= m //Ignore memories that don't have nice mask + } } - } - // Add compiler memories that might map well to libs - val compLibs = compilers match { - case Some(SRAMCompiler(_, groups)) => { - groups.filter(g => g.family == sram.family && groupMatchesMask(g, sram)).map( g => { - for(w <- g.width; d <- g.depth if((sram.width % w == 0) && (sram.depth % d == 0))) - yield Seq(new Macro(buildSRAMMacro(g, d, w, g.vt.head))) - } ) + // Add compiler memories that might map well to libs + val compLibs = compilers match { + case Some(SRAMCompiler(_, groups)) => { + groups + .filter(g => g.family == sram.family && groupMatchesMask(g, sram)) + .map(g => { + for { + w <- g.width + d <- g.depth if ((sram.width % w == 0) && (sram.depth % d == 0)) + } yield Seq(new Macro(buildSRAMMacro(g, d, w, g.vt.head))) + }) + } + case None => Seq() } - case None => Seq() - } - val fullLibs = libs ++ compLibs.flatten.flatten + val fullLibs = libs ++ compLibs.flatten.flatten - // Try to compile mem against each lib in libs, keeping track of the - // best compiled version, external lib used, and cost. - val (best, cost) = (fullLibs foldLeft (None: Option[(Module, Macro)], Double.MaxValue)){ - case ((best, cost), lib) if mem.src.ports.size != lib.src.ports.size => - /* Palmer: FIXME: This just assumes the Chisel and vendor ports are in the same - * order, but I'm starting with what actually gets generated. */ - System.err println s"INFO: unable to compile ${mem.src.name} using ${lib.src.name} port count must match" - (best, cost) - case ((best, cost), lib) => - // Run the cost function to evaluate this potential compile. - costMetric.cost(mem, lib) match { - case Some(newCost) => { - //System.err.println(s"Cost of ${lib.src.name} for ${mem.src.name}: ${newCost}") - // Try compiling - compile(mem, lib) match { - // If it was successful and the new cost is lower - case Some(p) if (newCost < cost) => (Some(p), newCost) - case _ => (best, cost) + // Try to compile mem against each lib in libs, keeping track of the + // best compiled version, external lib used, and cost. + val (best, cost) = (fullLibs.foldLeft(None: Option[(Module, Macro)], Double.MaxValue)) { + case ((best, cost), lib) if mem.src.ports.size != lib.src.ports.size => + /* Palmer: FIXME: This just assumes the Chisel and vendor ports are in the same + * order, but I'm starting with what actually gets generated. */ + System.err.println(s"INFO: unable to compile ${mem.src.name} using ${lib.src.name} port count must match") + (best, cost) + case ((best, cost), lib) => + // Run the cost function to evaluate this potential compile. + costMetric.cost(mem, lib) match { + case Some(newCost) => { + //System.err.println(s"Cost of ${lib.src.name} for ${mem.src.name}: ${newCost}") + // Try compiling + compile(mem, lib) match { + // If it was successful and the new cost is lower + case Some(p) if (newCost < cost) => (Some(p), newCost) + case _ => (best, cost) + } } + case _ => (best, cost) // Cost function rejected this combination. } - case _ => (best, cost) // Cost function rejected this combination. - } - } - - // If we were able to compile anything, then replace the original module - // in the modules list with a compiled version, as well as the extmodule - // stub for the lib. - best match { - case None => { - if (mode == MacroCompilerAnnotation.Strict) - throw new MacroCompilerException(s"Target memory ${mem.src.name} could not be compiled and strict mode is activated - aborting.") - else - modules } - case Some((mod, bb)) => - hammerIR match { - case Some(f) => { - val hammerIRWriter = new FileWriter(new File(f), !firstLib) - if(firstLib) hammerIRWriter.write("[\n") - hammerIRWriter.write(bb.src.toJSON().toString()) - hammerIRWriter.write("\n,\n") - hammerIRWriter.close() - firstLib = false - } - case None => + + // If we were able to compile anything, then replace the original module + // in the modules list with a compiled version, as well as the extmodule + // stub for the lib. + best match { + case None => { + if (mode == MacroCompilerAnnotation.Strict) + throw new MacroCompilerException( + s"Target memory ${mem.src.name} could not be compiled and strict mode is activated - aborting." + ) + else + modules } - (modules filterNot (m => m.name == mod.name || m.name == bb.blackbox.name)) ++ Seq(mod, bb.blackbox) + case Some((mod, bb)) => + hammerIR match { + case Some(f) => { + val hammerIRWriter = new FileWriter(new File(f), !firstLib) + if (firstLib) hammerIRWriter.write("[\n") + hammerIRWriter.write(bb.src.toJSON().toString()) + hammerIRWriter.write("\n,\n") + hammerIRWriter.close() + firstLib = false + } + case None => + } + (modules.filterNot(m => m.name == mod.name || m.name == bb.blackbox.name)) ++ Seq(mod, bb.blackbox) + } } - } case _ => c.modules } c.copy(modules = modules) @@ -657,38 +698,46 @@ class MacroCompilerTransform extends Transform { def execute(state: CircuitState) = state.annotations.collect { case a: MacroCompilerAnnotation => a } match { case Seq(anno: MacroCompilerAnnotation) => - val MacroCompilerAnnotation.Params(memFile, memFileFormat, libFile, hammerIR, costMetric, mode, useCompiler, forceCompile, forceSynflops) = anno.params + val MacroCompilerAnnotation.Params( + memFile, + memFileFormat, + libFile, + hammerIR, + costMetric, + mode, + useCompiler, + forceCompile, + forceSynflops + ) = anno.params if (mode == MacroCompilerAnnotation.FallbackSynflops) { throw new UnsupportedOperationException("Not implemented yet") } // Check that we don't have any modules both forced to compile and synflops. - assert((forceCompile intersect forceSynflops).isEmpty, "Cannot have modules both forced to compile and synflops") + assert((forceCompile.intersect(forceSynflops)).isEmpty, "Cannot have modules both forced to compile and synflops") // Read, eliminate None, get only SRAM, make firrtl macro val mems: Option[Seq[Macro]] = (memFileFormat match { case Some("conf") => Utils.readConfFromPath(Some(memFile)) - case _ => mdf.macrolib.Utils.readMDFFromPath(Some(memFile)) + case _ => mdf.macrolib.Utils.readMDFFromPath(Some(memFile)) }) match { - case Some(x:Seq[mdf.macrolib.Macro]) => - Some(Utils.filterForSRAM(Some(x)) getOrElse(List()) map {new Macro(_)}) + case Some(x: Seq[mdf.macrolib.Macro]) => + Some(Utils.filterForSRAM(Some(x)).getOrElse(List()).map { new Macro(_) }) case _ => None } val libs: Option[Seq[Macro]] = mdf.macrolib.Utils.readMDFFromPath(libFile) match { - case Some(x:Seq[mdf.macrolib.Macro]) => - Some(Utils.filterForSRAM(Some(x)) getOrElse(List()) map {new Macro(_)}) + case Some(x: Seq[mdf.macrolib.Macro]) => + Some(Utils.filterForSRAM(Some(x)).getOrElse(List()).map { new Macro(_) }) case _ => None } val compilers: Option[mdf.macrolib.SRAMCompiler] = mdf.macrolib.Utils.readMDFFromPath(libFile) match { - case Some(x:Seq[mdf.macrolib.Macro]) => - if(useCompiler){ + case Some(x: Seq[mdf.macrolib.Macro]) => + if (useCompiler) { findSRAMCompiler(Some(x)) - } - else None + } else None case _ => None } - // Helper function to turn a set of mem names into a Seq[Macro]. def setToSeqMacro(names: Set[String]): Seq[Macro] = { names.toSeq.map(memName => mems.get.collectFirst { case m if m.src.name == memName => m }.get) @@ -706,12 +755,16 @@ class MacroCompilerTransform extends Transform { val transforms = Seq( new MacroCompilerPass(memCompile, libs, compilers, hammerIR, costMetric, mode), - new SynFlopsPass(true, memSynflops ++ (if (mode == MacroCompilerAnnotation.CompileAndSynflops) { - libs.get - } else { - Seq.empty - }))) - (transforms foldLeft state) ((s, xform) => xform runTransform s).copy(form = outputForm) + new SynFlopsPass( + true, + memSynflops ++ (if (mode == MacroCompilerAnnotation.CompileAndSynflops) { + libs.get + } else { + Seq.empty + }) + ) + ) + (transforms.foldLeft(state))((s, xform) => xform.runTransform(s)).copy(form = outputForm) case _ => state } } @@ -729,7 +782,8 @@ class MacroCompilerOptimizations extends SeqTransform { new firrtl.transforms.ConstantPropagation, passes.Legalize, passes.SplitExpressions, - passes.CommonSubexpressionElimination) + passes.CommonSubexpressionElimination + ) } class MacroCompiler extends Compiler { @@ -756,8 +810,9 @@ object MacroCompiler extends App { type MacroParamMap = Map[MacroParam, String] type CostParamMap = Map[String, String] type ForcedMemories = (Set[String], Set[String]) - val modeOptions: Seq[String] = MacroCompilerAnnotation.options - .map { case (_, cmd, description) => s" $cmd: $description" } + val modeOptions: Seq[String] = MacroCompilerAnnotation.options.map { case (_, cmd, description) => + s" $cmd: $description" + } val usage: String = (Seq( "Options:", " -n, --macro-conf: The set of macros to compile in firrtl-generated conf format (exclusive with -m)", @@ -772,16 +827,20 @@ object MacroCompiler extends App { " --force-compile [mem]: Force the given memory to be compiled to target libs regardless of the mode", " --force-synflops [mem]: Force the given memory to be compiled via synflops regardless of the mode", " --mode:" - ) ++ modeOptions) mkString "\n" + ) ++ modeOptions).mkString("\n") - def parseArgs(map: MacroParamMap, costMap: CostParamMap, forcedMemories: ForcedMemories, - args: List[String]): (MacroParamMap, CostParamMap, ForcedMemories) = + def parseArgs( + map: MacroParamMap, + costMap: CostParamMap, + forcedMemories: ForcedMemories, + args: List[String] + ): (MacroParamMap, CostParamMap, ForcedMemories) = args match { case Nil => (map, costMap, forcedMemories) case ("-n" | "--macro-conf") :: value :: tail => - parseArgs(map + (Macros -> value) + (MacrosFormat -> "conf"), costMap, forcedMemories, tail) + parseArgs(map + (Macros -> value) + (MacrosFormat -> "conf"), costMap, forcedMemories, tail) case ("-m" | "--macro-mdf") :: value :: tail => - parseArgs(map + (Macros -> value) + (MacrosFormat -> "mdf"), costMap, forcedMemories, tail) + parseArgs(map + (Macros -> value) + (MacrosFormat -> "mdf"), costMap, forcedMemories, tail) case ("-l" | "--library") :: value :: tail => parseArgs(map + (Library -> value), costMap, forcedMemories, tail) case ("-u" | "--use-compiler") :: tail => @@ -809,11 +868,17 @@ object MacroCompiler extends App { } def run(args: List[String]) { - val (params, costParams, forcedMemories) = parseArgs(Map[MacroParam, String](), Map[String, String](), (Set.empty, Set.empty), args) + val (params, costParams, forcedMemories) = + parseArgs(Map[MacroParam, String](), Map[String, String](), (Set.empty, Set.empty), args) try { val macros = params.get(MacrosFormat) match { - case Some("conf") => Utils.filterForSRAM(Utils.readConfFromPath(params.get(Macros))).get map (x => (new Macro(x)).blackbox) - case _ => Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(params.get(Macros))).get map (x => (new Macro(x)).blackbox) + case Some("conf") => + Utils.filterForSRAM(Utils.readConfFromPath(params.get(Macros))).get.map(x => (new Macro(x)).blackbox) + case _ => + Utils + .filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(params.get(Macros))) + .get + .map(x => (new Macro(x)).blackbox) } if (macros.nonEmpty) { @@ -821,24 +886,28 @@ object MacroCompiler extends App { // determined as the firrtl "top-level module". val circuit = Circuit(NoInfo, macros, macros.last.name) val annotations = AnnotationSeq( - Seq(MacroCompilerAnnotation( - circuit.main, - MacroCompilerAnnotation.Params( - params.get(Macros).get, params.get(MacrosFormat), params.get(Library), - params.get(HammerIR), - CostMetric.getCostMetric(params.getOrElse(CostFunc, "default"), costParams), - MacroCompilerAnnotation.stringToCompilerMode(params.getOrElse(Mode, "default")), - params.contains(UseCompiler), - forceCompile = forcedMemories._1, forceSynflops = forcedMemories._2 + Seq( + MacroCompilerAnnotation( + circuit.main, + MacroCompilerAnnotation.Params( + params.get(Macros).get, + params.get(MacrosFormat), + params.get(Library), + params.get(HammerIR), + CostMetric.getCostMetric(params.getOrElse(CostFunc, "default"), costParams), + MacroCompilerAnnotation.stringToCompilerMode(params.getOrElse(Mode, "default")), + params.contains(UseCompiler), + forceCompile = forcedMemories._1, + forceSynflops = forcedMemories._2 + ) ) - )) + ) ) // The actual MacroCompilerTransform basically just generates an input circuit val macroCompilerInput = CircuitState(circuit, MidForm, annotations) val macroCompiled = (new MacroCompilerTransform).execute(macroCompilerInput) - // Since the MacroCompiler defines its own CLI, reconcile this with FIRRTL options val firOptions = new ExecutionOptionsManager("macrocompiler") with HasFirrtlOptions { firrtlOptions = FirrtlExecutionOptions( @@ -864,7 +933,7 @@ object MacroCompiler extends App { } } else { // Warn user - System.err println "WARNING: Empty *.mems.conf file. No memories generated." + System.err.println("WARNING: Empty *.mems.conf file. No memories generated.") // Emit empty verilog file if no macros found params.get(Verilog) match { diff --git a/macros/src/main/scala/barstools/macros/SynFlops.scala b/macros/src/main/scala/barstools/macros/SynFlops.scala index df7390d0..77ea4c96 100644 --- a/macros/src/main/scala/barstools/macros/SynFlops.scala +++ b/macros/src/main/scala/barstools/macros/SynFlops.scala @@ -10,132 +10,142 @@ import firrtl.passes.MemPortUtils.memPortField class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pass { val extraMods = scala.collection.mutable.ArrayBuffer.empty[Module] - lazy val libMods = (libs map { lib => lib.src.name -> { - val (dataType, dataWidth) = (lib.src.ports foldLeft (None: Option[BigInt]))((res, port) => - (res, port.maskPort) match { - case (_, None) => - res - case (None, Some(_)) => - Some(port.effectiveMaskGran) - case (Some(x), Some(_)) => - assert(x == port.effectiveMaskGran) - res + lazy val libMods = (libs.map { lib => + lib.src.name -> { + val (dataType, dataWidth) = (lib.src.ports.foldLeft(None: Option[BigInt]))((res, port) => + (res, port.maskPort) match { + case (_, None) => + res + case (None, Some(_)) => + Some(port.effectiveMaskGran) + case (Some(x), Some(_)) => + assert(x == port.effectiveMaskGran) + res + } + ) match { + case None => (UIntType(IntWidth(lib.src.width)), lib.src.width) + case Some(gran) => (UIntType(IntWidth(gran)), gran.intValue) } - ) match { - case None => (UIntType(IntWidth(lib.src.width)), lib.src.width) - case Some(gran) => (UIntType(IntWidth(gran)), gran.intValue) - } - val maxDepth = min(lib.src.depth, 1<<26) - val numMems = lib.src.depth / maxDepth + val maxDepth = min(lib.src.depth, 1 << 26) + val numMems = lib.src.depth / maxDepth - // Change macro to be mapped onto to look like the below mem - // by changing its depth, and width - val lib_macro = new Macro(lib.src.copy(name="split_"+lib.src.name, - depth = maxDepth, width = dataWidth, ports = lib.src.ports.map(p => - p.copy(width = p.width.map(_ => dataWidth), depth = p.depth.map(_ => maxDepth), - maskGran = p.maskGran.map(_ => dataWidth))))) - val mod_macro = (new MacroCompilerPass(None,None,None,None)).compile(lib, lib_macro) - val (real_mod, real_macro) = mod_macro.get - - val mem = DefMemory( - NoInfo, - "ram", - dataType, - maxDepth, - 1, // writeLatency - 1, // readLatency. This is possible because of VerilogMemDelays - real_macro.readers.indices map (i => s"R_$i"), - real_macro.writers.indices map (i => s"W_$i"), - real_macro.readwriters.indices map (i => s"RW_$i") - ) - - val readConnects = real_macro.readers.zipWithIndex flatMap { case (r, i) => - val clock = portToExpression(r.src.clock.get) - val address = portToExpression(r.src.address) - val enable = (r.src chipEnable, r.src readEnable) match { - case (Some(en_port), Some(re_port)) => - and(portToExpression(en_port), - portToExpression(re_port)) - case (Some(en_port), None) => portToExpression(en_port) - case (None, Some(re_port)) => portToExpression(re_port) - case (None, None) => one - } - val data = memPortField(mem, s"R_$i", "data") - val read = data - Seq( - Connect(NoInfo, memPortField(mem, s"R_$i", "clk"), clock), - Connect(NoInfo, memPortField(mem, s"R_$i", "addr"), address), - Connect(NoInfo, memPortField(mem, s"R_$i", "en"), enable), - Connect(NoInfo, WRef(r.src.output.get.name), read) + // Change macro to be mapped onto to look like the below mem + // by changing its depth, and width + val lib_macro = new Macro( + lib.src.copy( + name = "split_" + lib.src.name, + depth = maxDepth, + width = dataWidth, + ports = lib.src.ports.map(p => + p.copy( + width = p.width.map(_ => dataWidth), + depth = p.depth.map(_ => maxDepth), + maskGran = p.maskGran.map(_ => dataWidth) + ) + ) + ) ) - } + val mod_macro = (new MacroCompilerPass(None, None, None, None)).compile(lib, lib_macro) + val (real_mod, real_macro) = mod_macro.get - val writeConnects = real_macro.writers.zipWithIndex flatMap { case (w, i) => - val clock = portToExpression(w.src.clock.get) - val address = portToExpression(w.src.address) - val enable = (w.src.chipEnable, w.src.writeEnable) match { - case (Some(en), Some(we)) => - and(portToExpression(en), - portToExpression(we)) - case (Some(en), None) => portToExpression(en) - case (None, Some(we)) => portToExpression(we) - case (None, None) => zero // is it possible? - } - val mask = w.src.maskPort match { - case Some(m) => portToExpression(m) - case None => one - } - val data = memPortField(mem, s"W_$i", "data") - val write = portToExpression(w.src.input.get) - Seq( - Connect(NoInfo, memPortField(mem, s"W_$i", "clk"), clock), - Connect(NoInfo, memPortField(mem, s"W_$i", "addr"), address), - Connect(NoInfo, memPortField(mem, s"W_$i", "en"), enable), - Connect(NoInfo, memPortField(mem, s"W_$i", "mask"), mask), - Connect(NoInfo, data, write) + val mem = DefMemory( + NoInfo, + "ram", + dataType, + maxDepth, + 1, // writeLatency + 1, // readLatency. This is possible because of VerilogMemDelays + real_macro.readers.indices.map(i => s"R_$i"), + real_macro.writers.indices.map(i => s"W_$i"), + real_macro.readwriters.indices.map(i => s"RW_$i") ) - } - val readwriteConnects = real_macro.readwriters.zipWithIndex flatMap { case (rw, i) => - val clock = portToExpression(rw.src.clock.get) - val address = portToExpression(rw.src.address) - val wmode = rw.src.writeEnable match { - case Some(we) => portToExpression(we) - case None => zero // is it possible? + val readConnects = real_macro.readers.zipWithIndex.flatMap { case (r, i) => + val clock = portToExpression(r.src.clock.get) + val address = portToExpression(r.src.address) + val enable = (r.src chipEnable, r.src readEnable) match { + case (Some(en_port), Some(re_port)) => + and(portToExpression(en_port), portToExpression(re_port)) + case (Some(en_port), None) => portToExpression(en_port) + case (None, Some(re_port)) => portToExpression(re_port) + case (None, None) => one + } + val data = memPortField(mem, s"R_$i", "data") + val read = data + Seq( + Connect(NoInfo, memPortField(mem, s"R_$i", "clk"), clock), + Connect(NoInfo, memPortField(mem, s"R_$i", "addr"), address), + Connect(NoInfo, memPortField(mem, s"R_$i", "en"), enable), + Connect(NoInfo, WRef(r.src.output.get.name), read) + ) } - val wmask = rw.src.maskPort match { - case Some(wm) => portToExpression(wm) - case None => one - } - val enable = (rw.src.chipEnable, rw.src.readEnable) match { - case (Some(en), Some(re)) => - and(portToExpression(en), or(portToExpression(re), wmode)) - case (Some(en), None) => portToExpression(en) - case (None, Some(re)) => or(portToExpression(re), wmode) - case (None, None) => one - } - val wdata = memPortField(mem, s"RW_$i", "wdata") - val rdata = memPortField(mem, s"RW_$i", "rdata") - val write = portToExpression(rw.src.input.get) - val read = rdata - Seq( - Connect(NoInfo, memPortField(mem, s"RW_$i", "clk"), clock), - Connect(NoInfo, memPortField(mem, s"RW_$i", "addr"), address), - Connect(NoInfo, memPortField(mem, s"RW_$i", "en"), enable), - Connect(NoInfo, memPortField(mem, s"RW_$i", "wmode"), wmode), - Connect(NoInfo, memPortField(mem, s"RW_$i", "wmask"), wmask), - Connect(NoInfo, WRef(rw.src.output.get.name), read), - Connect(NoInfo, wdata, write) - ) - } - extraMods.append(real_macro.module(Block(mem +: (readConnects ++ writeConnects ++ readwriteConnects)))) - real_mod - }}).toMap + val writeConnects = real_macro.writers.zipWithIndex.flatMap { case (w, i) => + val clock = portToExpression(w.src.clock.get) + val address = portToExpression(w.src.address) + val enable = (w.src.chipEnable, w.src.writeEnable) match { + case (Some(en), Some(we)) => + and(portToExpression(en), portToExpression(we)) + case (Some(en), None) => portToExpression(en) + case (None, Some(we)) => portToExpression(we) + case (None, None) => zero // is it possible? + } + val mask = w.src.maskPort match { + case Some(m) => portToExpression(m) + case None => one + } + val data = memPortField(mem, s"W_$i", "data") + val write = portToExpression(w.src.input.get) + Seq( + Connect(NoInfo, memPortField(mem, s"W_$i", "clk"), clock), + Connect(NoInfo, memPortField(mem, s"W_$i", "addr"), address), + Connect(NoInfo, memPortField(mem, s"W_$i", "en"), enable), + Connect(NoInfo, memPortField(mem, s"W_$i", "mask"), mask), + Connect(NoInfo, data, write) + ) + } + + val readwriteConnects = real_macro.readwriters.zipWithIndex.flatMap { case (rw, i) => + val clock = portToExpression(rw.src.clock.get) + val address = portToExpression(rw.src.address) + val wmode = rw.src.writeEnable match { + case Some(we) => portToExpression(we) + case None => zero // is it possible? + } + val wmask = rw.src.maskPort match { + case Some(wm) => portToExpression(wm) + case None => one + } + val enable = (rw.src.chipEnable, rw.src.readEnable) match { + case (Some(en), Some(re)) => + and(portToExpression(en), or(portToExpression(re), wmode)) + case (Some(en), None) => portToExpression(en) + case (None, Some(re)) => or(portToExpression(re), wmode) + case (None, None) => one + } + val wdata = memPortField(mem, s"RW_$i", "wdata") + val rdata = memPortField(mem, s"RW_$i", "rdata") + val write = portToExpression(rw.src.input.get) + val read = rdata + Seq( + Connect(NoInfo, memPortField(mem, s"RW_$i", "clk"), clock), + Connect(NoInfo, memPortField(mem, s"RW_$i", "addr"), address), + Connect(NoInfo, memPortField(mem, s"RW_$i", "en"), enable), + Connect(NoInfo, memPortField(mem, s"RW_$i", "wmode"), wmode), + Connect(NoInfo, memPortField(mem, s"RW_$i", "wmask"), wmask), + Connect(NoInfo, WRef(rw.src.output.get.name), read), + Connect(NoInfo, wdata, write) + ) + } + + extraMods.append(real_macro.module(Block(mem +: (readConnects ++ writeConnects ++ readwriteConnects)))) + real_mod + } + }).toMap def run(c: Circuit): Circuit = { if (!synflops) c - else c.copy(modules = (c.modules map (m => libMods.getOrElse(m.name, m))) ++ extraMods) + else c.copy(modules = (c.modules.map(m => libMods.getOrElse(m.name, m))) ++ extraMods) } } diff --git a/macros/src/main/scala/barstools/macros/Utils.scala b/macros/src/main/scala/barstools/macros/Utils.scala index a65e3a8a..9afa51f3 100644 --- a/macros/src/main/scala/barstools/macros/Utils.scala +++ b/macros/src/main/scala/barstools/macros/Utils.scala @@ -11,7 +11,7 @@ import mdf.macrolib.{Input => _, Output => _, _} import scala.language.implicitConversions object MacroCompilerMath { - def ceilLog2(x: BigInt): Int = (x-1).bitLength + def ceilLog2(x: BigInt): Int = (x - 1).bitLength } class FirrtlMacroPort(port: MacroPort) { @@ -21,37 +21,46 @@ class FirrtlMacroPort(port: MacroPort) { val isWriter = port.input.nonEmpty && port.output.isEmpty val isReadWriter = port.input.nonEmpty && port.output.nonEmpty - val addrType = UIntType(IntWidth(MacroCompilerMath.ceilLog2(port.depth.get) max 1)) + val addrType = UIntType(IntWidth(MacroCompilerMath.ceilLog2(port.depth.get).max(1))) val dataType = UIntType(IntWidth(port.width.get)) val maskType = UIntType(IntWidth(port.width.get / port.effectiveMaskGran)) // Bundle representing this macro port. - val tpe = BundleType(Seq( - Field(port.address.name, Flip, addrType)) ++ - (port.clock map (p => Field(p.name, Flip, ClockType))) ++ - (port.input map (p => Field(p.name, Flip, dataType))) ++ - (port.output map (p => Field(p.name, Default, dataType))) ++ - (port.chipEnable map (p => Field(p.name, Flip, BoolType))) ++ - (port.readEnable map (p => Field(p.name, Flip, BoolType))) ++ - (port.writeEnable map (p => Field(p.name, Flip, BoolType))) ++ - (port.maskPort map (p => Field(p.name, Flip, maskType))) + val tpe = BundleType( + Seq(Field(port.address.name, Flip, addrType)) ++ + (port.clock.map(p => Field(p.name, Flip, ClockType))) ++ + (port.input.map(p => Field(p.name, Flip, dataType))) ++ + (port.output.map(p => Field(p.name, Default, dataType))) ++ + (port.chipEnable.map(p => Field(p.name, Flip, BoolType))) ++ + (port.readEnable.map(p => Field(p.name, Flip, BoolType))) ++ + (port.writeEnable.map(p => Field(p.name, Flip, BoolType))) ++ + (port.maskPort.map(p => Field(p.name, Flip, maskType))) + ) + val ports = tpe.fields.map(f => + Port( + NoInfo, + f.name, + f.flip match { + case Default => Output + case Flip => Input + }, + f.tpe + ) ) - val ports = tpe.fields map (f => Port( - NoInfo, f.name, f.flip match { case Default => Output case Flip => Input }, f.tpe)) } // Reads an SRAMMacro and generates firrtl blackboxes. class Macro(srcMacro: SRAMMacro) { val src = srcMacro - val firrtlPorts = srcMacro.ports map { new FirrtlMacroPort(_) } + val firrtlPorts = srcMacro.ports.map { new FirrtlMacroPort(_) } - val writers = firrtlPorts filter (p => p.isWriter) - val readers = firrtlPorts filter (p => p.isReader) - val readwriters = firrtlPorts filter (p => p.isReadWriter) + val writers = firrtlPorts.filter(p => p.isWriter) + val readers = firrtlPorts.filter(p => p.isReader) + val readwriters = firrtlPorts.filter(p => p.isReadWriter) val sortedPorts = writers ++ readers ++ readwriters - val extraPorts = srcMacro.extraPorts map { p => + val extraPorts = srcMacro.extraPorts.map { p => assert(p.portType == Constant) // TODO: release it? val name = p.name val width = BigInt(p.width.toLong) @@ -60,10 +69,10 @@ class Macro(srcMacro: SRAMMacro) { } // Bundle representing this memory blackbox - val tpe = BundleType(firrtlPorts flatMap (_.tpe.fields)) + val tpe = BundleType(firrtlPorts.flatMap(_.tpe.fields)) - private val modPorts = (firrtlPorts flatMap (_.ports)) ++ - (extraPorts map { case (name, value) => Port(NoInfo, name, Input, value.tpe) }) + private val modPorts = (firrtlPorts.flatMap(_.ports)) ++ + (extraPorts.map { case (name, value) => Port(NoInfo, name, Input, value.tpe) }) val blackbox = ExtModule(NoInfo, srcMacro.name, modPorts, srcMacro.name, Nil) def module(body: Statement) = Module(NoInfo, srcMacro.name, modPorts, body) } @@ -71,7 +80,8 @@ class Macro(srcMacro: SRAMMacro) { object Utils { def filterForSRAM(s: Option[Seq[mdf.macrolib.Macro]]): Option[Seq[mdf.macrolib.SRAMMacro]] = { s match { - case Some(l:Seq[mdf.macrolib.Macro]) => Some(l filter { _.isInstanceOf[mdf.macrolib.SRAMMacro] } map { m => m.asInstanceOf[mdf.macrolib.SRAMMacro] }) + case Some(l: Seq[mdf.macrolib.Macro]) => + Some(l.filter { _.isInstanceOf[mdf.macrolib.SRAMMacro] }.map { m => m.asInstanceOf[mdf.macrolib.SRAMMacro] }) case _ => None } } @@ -80,18 +90,24 @@ object Utils { path.map((p) => Utils.readConfFromString(scala.io.Source.fromFile(p).mkString)) } def readConfFromString(str: String): Seq[mdf.macrolib.Macro] = { - MemConf.fromString(str).map { m:MemConf => - val ports = m.ports.map { case (port, num) => Seq.fill(num)(port) } reduce (_ ++ _) - SRAMMacro(m.name, m.width, m.depth, Utils.portSpecToFamily(ports), Utils.portSpecToMacroPort(m.width, m.depth, m.maskGranularity, ports)) + MemConf.fromString(str).map { m: MemConf => + val ports = m.ports.map { case (port, num) => Seq.fill(num)(port) }.reduce(_ ++ _) + SRAMMacro( + m.name, + m.width, + m.depth, + Utils.portSpecToFamily(ports), + Utils.portSpecToMacroPort(m.width, m.depth, m.maskGranularity, ports) + ) } } def portSpecToFamily(ports: Seq[MemPort]): String = { - val numR = ports.count(_ match { case ReadPort => true; case _ => false}) - val numW = ports.count(_ match { case WritePort|MaskedWritePort => true; case _ => false}) - val numRW = ports.count(_ match { case ReadWritePort|MaskedReadWritePort => true; case _ => false}) - val numRStr = if(numR > 0) s"${numR}r" else "" - val numWStr = if(numW > 0) s"${numW}w" else "" - val numRWStr = if(numRW > 0) s"${numRW}rw" else "" + val numR = ports.count(_ match { case ReadPort => true; case _ => false }) + val numW = ports.count(_ match { case WritePort | MaskedWritePort => true; case _ => false }) + val numRW = ports.count(_ match { case ReadWritePort | MaskedReadWritePort => true; case _ => false }) + val numRStr = if (numR > 0) s"${numR}r" else "" + val numWStr = if (numW > 0) s"${numW}w" else "" + val numRWStr = if (numRW > 0) s"${numRW}rw" else "" return numRStr + numWStr + numRWStr } // This translates between two represenations of ports @@ -99,94 +115,128 @@ object Utils { var numR = 0 var numW = 0 var numRW = 0 - ports.map { _ match { - case ReadPort => { - val portName = s"R${numR}" - numR += 1 - MacroPort( - width=Some(width), depth=Some(depth), - address=PolarizedPort(s"${portName}_addr", ActiveHigh), - clock=Some(PolarizedPort(s"${portName}_clk", PositiveEdge)), - readEnable=Some(PolarizedPort(s"${portName}_en", ActiveHigh)), - output=Some(PolarizedPort(s"${portName}_data", ActiveHigh)) - ) } - case WritePort => { - val portName = s"W${numW}" - numW += 1 - MacroPort( - width=Some(width), depth=Some(depth), - address=PolarizedPort(s"${portName}_addr", ActiveHigh), - clock=Some(PolarizedPort(s"${portName}_clk", PositiveEdge)), - writeEnable=Some(PolarizedPort(s"${portName}_en", ActiveHigh)), - input=Some(PolarizedPort(s"${portName}_data", ActiveHigh)) - ) } - case MaskedWritePort => { - val portName = s"W${numW}" - numW += 1 - MacroPort( - width=Some(width), depth=Some(depth), - address=PolarizedPort(s"${portName}_addr", ActiveHigh), - clock=Some(PolarizedPort(s"${portName}_clk", PositiveEdge)), - writeEnable=Some(PolarizedPort(s"${portName}_en", ActiveHigh)), - maskPort=Some(PolarizedPort(s"${portName}_mask", ActiveHigh)), - maskGran=maskGran, - input=Some(PolarizedPort(s"${portName}_data", ActiveHigh)) - ) } - case ReadWritePort => { - val portName = s"RW${numRW}" - numRW += 1 - MacroPort( - width=Some(width), depth=Some(depth), - address=PolarizedPort(s"${portName}_addr", ActiveHigh), - clock=Some(PolarizedPort(s"${portName}_clk", PositiveEdge)), - chipEnable=Some(PolarizedPort(s"${portName}_en", ActiveHigh)), - writeEnable=Some(PolarizedPort(s"${portName}_wmode", ActiveHigh)), - input=Some(PolarizedPort(s"${portName}_wdata", ActiveHigh)), - output=Some(PolarizedPort(s"${portName}_rdata", ActiveHigh)) - ) } - case MaskedReadWritePort => { - val portName = s"RW${numRW}" - numRW += 1 - MacroPort( - width=Some(width), depth=Some(depth), - address=PolarizedPort(s"${portName}_addr", ActiveHigh), - clock=Some(PolarizedPort(s"${portName}_clk", PositiveEdge)), - chipEnable=Some(PolarizedPort(s"${portName}_en", ActiveHigh)), - writeEnable=Some(PolarizedPort(s"${portName}_wmode", ActiveHigh)), - maskPort=Some(PolarizedPort(s"${portName}_wmask", ActiveHigh)), - maskGran=maskGran, - input=Some(PolarizedPort(s"${portName}_wdata", ActiveHigh)), - output=Some(PolarizedPort(s"${portName}_rdata", ActiveHigh)) - ) } - }} + ports.map { + _ match { + case ReadPort => { + val portName = s"R${numR}" + numR += 1 + MacroPort( + width = Some(width), + depth = Some(depth), + address = PolarizedPort(s"${portName}_addr", ActiveHigh), + clock = Some(PolarizedPort(s"${portName}_clk", PositiveEdge)), + readEnable = Some(PolarizedPort(s"${portName}_en", ActiveHigh)), + output = Some(PolarizedPort(s"${portName}_data", ActiveHigh)) + ) + } + case WritePort => { + val portName = s"W${numW}" + numW += 1 + MacroPort( + width = Some(width), + depth = Some(depth), + address = PolarizedPort(s"${portName}_addr", ActiveHigh), + clock = Some(PolarizedPort(s"${portName}_clk", PositiveEdge)), + writeEnable = Some(PolarizedPort(s"${portName}_en", ActiveHigh)), + input = Some(PolarizedPort(s"${portName}_data", ActiveHigh)) + ) + } + case MaskedWritePort => { + val portName = s"W${numW}" + numW += 1 + MacroPort( + width = Some(width), + depth = Some(depth), + address = PolarizedPort(s"${portName}_addr", ActiveHigh), + clock = Some(PolarizedPort(s"${portName}_clk", PositiveEdge)), + writeEnable = Some(PolarizedPort(s"${portName}_en", ActiveHigh)), + maskPort = Some(PolarizedPort(s"${portName}_mask", ActiveHigh)), + maskGran = maskGran, + input = Some(PolarizedPort(s"${portName}_data", ActiveHigh)) + ) + } + case ReadWritePort => { + val portName = s"RW${numRW}" + numRW += 1 + MacroPort( + width = Some(width), + depth = Some(depth), + address = PolarizedPort(s"${portName}_addr", ActiveHigh), + clock = Some(PolarizedPort(s"${portName}_clk", PositiveEdge)), + chipEnable = Some(PolarizedPort(s"${portName}_en", ActiveHigh)), + writeEnable = Some(PolarizedPort(s"${portName}_wmode", ActiveHigh)), + input = Some(PolarizedPort(s"${portName}_wdata", ActiveHigh)), + output = Some(PolarizedPort(s"${portName}_rdata", ActiveHigh)) + ) + } + case MaskedReadWritePort => { + val portName = s"RW${numRW}" + numRW += 1 + MacroPort( + width = Some(width), + depth = Some(depth), + address = PolarizedPort(s"${portName}_addr", ActiveHigh), + clock = Some(PolarizedPort(s"${portName}_clk", PositiveEdge)), + chipEnable = Some(PolarizedPort(s"${portName}_en", ActiveHigh)), + writeEnable = Some(PolarizedPort(s"${portName}_wmode", ActiveHigh)), + maskPort = Some(PolarizedPort(s"${portName}_wmask", ActiveHigh)), + maskGran = maskGran, + input = Some(PolarizedPort(s"${portName}_wdata", ActiveHigh)), + output = Some(PolarizedPort(s"${portName}_rdata", ActiveHigh)) + ) + } + } + } } def findSRAMCompiler(s: Option[Seq[mdf.macrolib.Macro]]): Option[mdf.macrolib.SRAMCompiler] = { s match { - case Some(l:Seq[mdf.macrolib.Macro]) => - l collectFirst { - case x: mdf.macrolib.SRAMCompiler => x + case Some(l: Seq[mdf.macrolib.Macro]) => + l.collectFirst { case x: mdf.macrolib.SRAMCompiler => + x } case _ => None } } def buildSRAMMacros(s: mdf.macrolib.SRAMCompiler): Seq[mdf.macrolib.SRAMMacro] = { - for (g <- s.groups; d <- g.depth; w <- g.width; vt <- g.vt) - yield mdf.macrolib.SRAMMacro(makeName(g, d, w, vt), w, d, g.family, g.ports.map(_.copy(width=Some(w), depth=Some(d))), vt, g.mux, g.extraPorts) + for { + g <- s.groups + d <- g.depth + w <- g.width + vt <- g.vt + } yield mdf.macrolib.SRAMMacro( + makeName(g, d, w, vt), + w, + d, + g.family, + g.ports.map(_.copy(width = Some(w), depth = Some(d))), + vt, + g.mux, + g.extraPorts + ) } def buildSRAMMacro(g: mdf.macrolib.SRAMGroup, d: Int, w: Int, vt: String): mdf.macrolib.SRAMMacro = { - return mdf.macrolib.SRAMMacro(makeName(g, d, w, vt), w, d, g.family, g.ports.map(_.copy(width=Some(w), depth=Some(d))), vt, g.mux, g.extraPorts) + return mdf.macrolib.SRAMMacro( + makeName(g, d, w, vt), + w, + d, + g.family, + g.ports.map(_.copy(width = Some(w), depth = Some(d))), + vt, + g.mux, + g.extraPorts + ) } def makeName(g: mdf.macrolib.SRAMGroup, depth: Int, width: Int, vt: String): String = { - g.name.foldLeft(""){ (builder, next) => + g.name.foldLeft("") { (builder, next) => next match { - case "depth"|"DEPTH" => builder + depth - case "width"|"WIDTH" => builder + width - case "vt" => builder + vt.toLowerCase - case "VT" => builder + vt.toUpperCase - case "family" => builder + g.family.toLowerCase - case "FAMILY" => builder + g.family.toUpperCase - case "mux"|"MUX" => builder + g.mux - case other => builder + other + case "depth" | "DEPTH" => builder + depth + case "width" | "WIDTH" => builder + width + case "vt" => builder + vt.toLowerCase + case "VT" => builder + vt.toUpperCase + case "family" => builder + g.family.toLowerCase + case "FAMILY" => builder + g.family.toUpperCase + case "mux" | "MUX" => builder + g.mux + case other => builder + other } } } @@ -196,7 +246,7 @@ object Utils { def or(e1: Expression, e2: Expression) = DoPrim(PrimOps.Or, Seq(e1, e2), Nil, e1.tpe) def bits(e: Expression, high: BigInt, low: BigInt): Expression = - DoPrim(PrimOps.Bits, Seq(e), Seq(high, low), UIntType(IntWidth(high-low+1))) + DoPrim(PrimOps.Bits, Seq(e), Seq(high, low), UIntType(IntWidth(high - low + 1))) def bits(e: Expression, idx: BigInt): Expression = bits(e, idx, idx) def cat(es: Seq[Expression]): Expression = if (es.size == 1) es.head @@ -211,7 +261,7 @@ object Utils { def portToExpression(exp: Expression, polarity: Option[PortPolarity]): Expression = polarity match { case Some(ActiveLow) | Some(NegativeEdge) => not(exp) - case _ => exp + case _ => exp } // Check if a number is a power of two diff --git a/macros/src/test/resources/lib-MaskPortTest.json b/macros/src/test/resources/lib-MaskPortTest.json index 72df7947..784aeafb 100644 --- a/macros/src/test/resources/lib-MaskPortTest.json +++ b/macros/src/test/resources/lib-MaskPortTest.json @@ -1,27 +1,29 @@ [ { - "type" : "sram", - "name" : "fake_mem", - "width" : 64, - "depth" : "512", - "mux" : 4, - "family" : "1rw", - "ports" : [ { - "address port name" : "addr", - "address port polarity" : "active high", - "clock port name" : "clk", - "clock port polarity" : "positive edge", - "write enable port name" : "wen", - "write enable port polarity" : "active high", - "read enable port name" : "ren", - "read enable port polarity" : "active high", - "output port name" : "dataout", - "output port polarity" : "active high", - "input port name" : "datain", - "input port polarity" : "active high", - "mask port name" : "mport", - "mask port polarity" : "active low", - "mask granularity" : 1 - } ] + "type": "sram", + "name": "fake_mem", + "width": 64, + "depth": "512", + "mux": 4, + "family": "1rw", + "ports": [ + { + "address port name": "addr", + "address port polarity": "active high", + "clock port name": "clk", + "clock port polarity": "positive edge", + "write enable port name": "wen", + "write enable port polarity": "active high", + "read enable port name": "ren", + "read enable port polarity": "active high", + "output port name": "dataout", + "output port polarity": "active high", + "input port name": "datain", + "input port polarity": "active high", + "mask port name": "mport", + "mask port polarity": "active low", + "mask granularity": 1 + } + ] } ] diff --git a/macros/src/test/resources/lib-WriteEnableTest.json b/macros/src/test/resources/lib-WriteEnableTest.json index be7852a6..50acef41 100644 --- a/macros/src/test/resources/lib-WriteEnableTest.json +++ b/macros/src/test/resources/lib-WriteEnableTest.json @@ -1,24 +1,26 @@ [ { - "type" : "sram", - "name" : "fake_mem", - "width" : 64, - "depth" : "4096", - "mux" : 4, - "family" : "1rw", - "ports" : [ { - "address port name" : "addr", - "address port polarity" : "active high", - "clock port name" : "clk", - "clock port polarity" : "positive edge", - "write enable port name" : "wen", - "write enable port polarity" : "active high", - "read enable port name" : "ren", - "read enable port polarity" : "active high", - "output port name" : "dataout", - "output port polarity" : "active high", - "input port name" : "datain", - "input port polarity" : "active high" - } ] + "type": "sram", + "name": "fake_mem", + "width": 64, + "depth": "4096", + "mux": 4, + "family": "1rw", + "ports": [ + { + "address port name": "addr", + "address port polarity": "active high", + "clock port name": "clk", + "clock port polarity": "positive edge", + "write enable port name": "wen", + "write enable port polarity": "active high", + "read enable port name": "ren", + "read enable port polarity": "active high", + "output port name": "dataout", + "output port polarity": "active high", + "input port name": "datain", + "input port polarity": "active high" + } + ] } ] diff --git a/macros/src/test/scala/barstools/macros/CostFunction.scala b/macros/src/test/scala/barstools/macros/CostFunction.scala index b8a27f7f..ceb7a61a 100644 --- a/macros/src/test/scala/barstools/macros/CostFunction.scala +++ b/macros/src/test/scala/barstools/macros/CostFunction.scala @@ -4,10 +4,9 @@ import mdf.macrolib._ /** Tests to check that the cost function mechanism is working properly. */ -/** - * A test metric that simply favours memories with smaller widths, to test that - * the metric is chosen properly. - */ +/** A test metric that simply favours memories with smaller widths, to test that + * the metric is chosen properly. + */ object TestMinWidthMetric extends CostMetric with CostMetricCompanion { // Smaller width = lower cost = favoured override def cost(mem: Macro, lib: Macro): Option[Double] = Some(lib.src.width) @@ -30,29 +29,29 @@ class SelectCostMetric extends MacroCompilerSpec with HasSRAMGenerator { val libSRAMs = Seq( SRAMMacro( - name="SRAM_WIDTH_128", - depth=BigInt(1024), - width=128, - family="1rw", - ports=Seq( + name = "SRAM_WIDTH_128", + depth = BigInt(1024), + width = 128, + family = "1rw", + ports = Seq( generateReadWritePort("", 128, BigInt(1024)) ) ), SRAMMacro( - name="SRAM_WIDTH_64", - depth=BigInt(1024), - width=64, - family="1rw", - ports=Seq( + name = "SRAM_WIDTH_64", + depth = BigInt(1024), + width = 64, + family = "1rw", + ports = Seq( generateReadWritePort("", 64, BigInt(1024)) ) ), SRAMMacro( - name="SRAM_WIDTH_32", - depth=BigInt(1024), - width=32, - family="1rw", - ports=Seq( + name = "SRAM_WIDTH_32", + depth = BigInt(1024), + width = 32, + family = "1rw", + ports = Seq( generateReadWritePort("", 32, BigInt(1024)) ) ) @@ -65,7 +64,7 @@ class SelectCostMetric extends MacroCompilerSpec with HasSRAMGenerator { // Check that the min width SRAM was chosen, even though it is less efficient. val output = -""" + """ circuit target_memory : module target_memory : input addr : UInt<10> diff --git a/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala b/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala index cf84e500..9140ce24 100644 --- a/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala +++ b/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala @@ -18,12 +18,12 @@ abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalate // Override these to change the prefixing of macroDir and testDir val memPrefix: String = testDir val libPrefix: String = testDir - val vPrefix: String = testDir + val vPrefix: String = testDir // Override this to use a different cost metric. // If this is None, the compile() call will not have any -c/-cp arguments, and // execute() will use CostMetric.default. - val costMetric: Option[CostMetric] = None + val costMetric: Option[CostMetric] = None private def getCostMetric: CostMetric = costMetric.getOrElse(CostMetric.default) private def costMetricCmdLine = { @@ -32,17 +32,20 @@ abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalate case Some(m) => { val name = m.name val params = m.commandLineParams - List("-c", name) ++ params.flatMap{ case (key, value) => List("-cp", key, value) } + List("-c", name) ++ params.flatMap { case (key, value) => List("-cp", key, value) } } } } private def args(mem: String, lib: Option[String], v: String, synflops: Boolean, useCompiler: Boolean) = List("-m", mem.toString, "-v", v) ++ - (lib match { case None => Nil case Some(l) => List("-l", l.toString) }) ++ - costMetricCmdLine ++ - (if (synflops) List("--mode", "synflops") else Nil) ++ - (if (useCompiler) List("--use-compiler") else Nil) + (lib match { + case None => Nil + case Some(l) => List("-l", l.toString) + }) ++ + costMetricCmdLine ++ + (if (synflops) List("--mode", "synflops") else Nil) ++ + (if (useCompiler) List("--use-compiler") else Nil) // Run the full compiler as if from the command line interface. // Generates the Verilog; useful in testing since an error will throw an @@ -68,7 +71,14 @@ abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalate } // Convenience function for running both compile, execute, and test at once. - def compileExecuteAndTest(mem: String, lib: Option[String], v: String, output: String, synflops: Boolean = false, useCompiler: Boolean = false): Unit = { + def compileExecuteAndTest( + mem: String, + lib: Option[String], + v: String, + output: String, + synflops: Boolean = false, + useCompiler: Boolean = false + ): Unit = { compile(mem, lib, v, synflops, useCompiler) val result = execute(mem, lib, synflops, useCompiler) test(result, output) @@ -76,43 +86,53 @@ abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalate // Compare FIRRTL outputs after reparsing output with ScalaTest ("should be"). def test(result: Circuit, output: String): Unit = { - val gold = RemoveEmpty run parse(output) - (result.serialize) should be (gold.serialize) + val gold = RemoveEmpty.run(parse(output)) + (result.serialize) should be(gold.serialize) } // Execute the macro compiler and returns a Circuit containing the output of // the memory compiler. - def execute(memFile: Option[String], libFile: Option[String], synflops: Boolean): Circuit = execute(memFile, libFile, synflops, false) + def execute(memFile: Option[String], libFile: Option[String], synflops: Boolean): Circuit = + execute(memFile, libFile, synflops, false) def execute(memFile: Option[String], libFile: Option[String], synflops: Boolean, useCompiler: Boolean): Circuit = { var mem_full = concat(memPrefix, memFile) var lib_full = concat(libPrefix, libFile) require(memFile.isDefined) - val mems: Seq[Macro] = Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(mem_full)).get map (new Macro(_)) - val libs: Option[Seq[Macro]] = if(useCompiler) { - Utils.findSRAMCompiler(mdf.macrolib.Utils.readMDFFromPath(lib_full)).map{x => Utils.buildSRAMMacros(x).map(new Macro(_)) } + val mems: Seq[Macro] = Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(mem_full)).get.map(new Macro(_)) + val libs: Option[Seq[Macro]] = if (useCompiler) { + Utils.findSRAMCompiler(mdf.macrolib.Utils.readMDFFromPath(lib_full)).map { x => + Utils.buildSRAMMacros(x).map(new Macro(_)) + } } else { Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(lib_full)) match { - case Some(x) => Some(x map (new Macro(_))) - case None => None + case Some(x) => Some(x.map(new Macro(_))) + case None => None } } - val macros = mems map (_.blackbox) + val macros = mems.map(_.blackbox) val circuit = Circuit(NoInfo, macros, macros.last.name) val passes = Seq( - new MacroCompilerPass(Some(mems), libs, None, None, getCostMetric, if (synflops) MacroCompilerAnnotation.Synflops else MacroCompilerAnnotation.Default), - new SynFlopsPass(synflops, libs getOrElse mems), - RemoveEmpty) - val result: Circuit = (passes foldLeft circuit)((c, pass) => pass run c) + new MacroCompilerPass( + Some(mems), + libs, + None, + None, + getCostMetric, + if (synflops) MacroCompilerAnnotation.Synflops else MacroCompilerAnnotation.Default + ), + new SynFlopsPass(synflops, libs.getOrElse(mems)), + RemoveEmpty + ) + val result: Circuit = (passes.foldLeft(circuit))((c, pass) => pass.run(c)) result } - // Helper method to deal with String + Option[String] - private def concat(a: String, b: String): String = {a + "/" + b} + private def concat(a: String, b: String): String = { a + "/" + b } private def concat(a: String, b: Option[String]): Option[String] = { b match { - case Some(b2:String) => Some(a + "/" + b2) + case Some(b2: String) => Some(a + "/" + b2) case _ => None } } @@ -123,20 +143,19 @@ trait HasSRAMGenerator { import mdf.macrolib._ import scala.language.implicitConversions - implicit def Int2SomeInt(i: Int): Option[Int] = Some(i) + implicit def Int2SomeInt(i: Int): Option[Int] = Some(i) implicit def BigInt2SomeBigInt(i: BigInt): Option[BigInt] = Some(i) - // Generate a standard (read/write/combo) port for testing. // Helper methods for optional width argument def generateTestPort( - prefix: String, - width: Option[Int], - depth: Option[BigInt], - maskGran: Option[Int] = None, - read: Boolean, - readEnable: Boolean = false, - write: Boolean, + prefix: String, + width: Option[Int], + depth: Option[BigInt], + maskGran: Option[Int] = None, + read: Boolean, + readEnable: Boolean = false, + write: Boolean, writeEnable: Boolean = false ): MacroPort = { val realPrefix = if (prefix == "") "" else prefix + "_" @@ -144,44 +163,70 @@ trait HasSRAMGenerator { MacroPort( address = PolarizedPort(name = realPrefix + "addr", polarity = ActiveHigh), clock = Some(PolarizedPort(name = realPrefix + "clk", polarity = PositiveEdge)), - readEnable = if (readEnable) Some(PolarizedPort(name = realPrefix + "read_en", polarity = ActiveHigh)) else None, - writeEnable = if (writeEnable) Some(PolarizedPort(name = realPrefix + "write_en", polarity = ActiveHigh)) else None, - + writeEnable = + if (writeEnable) Some(PolarizedPort(name = realPrefix + "write_en", polarity = ActiveHigh)) else None, output = if (read) Some(PolarizedPort(name = realPrefix + "dout", polarity = ActiveHigh)) else None, input = if (write) Some(PolarizedPort(name = realPrefix + "din", polarity = ActiveHigh)) else None, - maskPort = maskGran match { case Some(x: Int) => Some(PolarizedPort(name = realPrefix + "mask", polarity = ActiveHigh)) case _ => None }, maskGran = maskGran, - - width = width, depth = depth // These numbers don't matter here. + width = width, + depth = depth // These numbers don't matter here. ) } // Generate a read port for testing. - def generateReadPort(prefix: String, width: Option[Int], depth: Option[BigInt], readEnable: Boolean = false): MacroPort = { + def generateReadPort( + prefix: String, + width: Option[Int], + depth: Option[BigInt], + readEnable: Boolean = false + ): MacroPort = { generateTestPort(prefix, width, depth, write = false, read = true, readEnable = readEnable) } // Generate a write port for testing. - def generateWritePort(prefix: String, width: Option[Int], depth: Option[BigInt], maskGran: Option[Int] = None, writeEnable: Boolean = true): MacroPort = { + def generateWritePort( + prefix: String, + width: Option[Int], + depth: Option[BigInt], + maskGran: Option[Int] = None, + writeEnable: Boolean = true + ): MacroPort = { generateTestPort(prefix, width, depth, maskGran = maskGran, write = true, read = false, writeEnable = writeEnable) } // Generate a simple read-write port for testing. - def generateReadWritePort(prefix: String, width: Option[Int], depth: Option[BigInt], maskGran: Option[Int] = None): MacroPort = { + def generateReadWritePort( + prefix: String, + width: Option[Int], + depth: Option[BigInt], + maskGran: Option[Int] = None + ): MacroPort = { generateTestPort( - prefix, width, depth, maskGran = maskGran, - write = true, writeEnable = true, - read = true, readEnable = false + prefix, + width, + depth, + maskGran = maskGran, + write = true, + writeEnable = true, + read = true, + readEnable = false ) } // Generate a "simple" SRAM (active high/positive edge, 1 read-write port). - def generateSRAM(name: String, prefix: String, width: Int, depth: BigInt, maskGran: Option[Int] = None, extraPorts: Seq[MacroExtraPort] = List()): SRAMMacro = { + def generateSRAM( + name: String, + prefix: String, + width: Int, + depth: BigInt, + maskGran: Option[Int] = None, + extraPorts: Seq[MacroExtraPort] = List() + ): SRAMMacro = { SRAMMacro( name = name, width = width, @@ -193,17 +238,35 @@ trait HasSRAMGenerator { } // Generate a "simple" SRAM group (active high/positive edge, 1 read-write port). - def generateSimpleSRAMGroup(prefix: String, mux: Int, depth: Range, width: Range, maskGran: Option[Int] = None, extraPorts: Seq[MacroExtraPort] = List()): SRAMGroup = { - SRAMGroup(Seq("mygroup_", "width", "x", "depth", "_", "VT"), "1rw", Seq("svt", "lvt", "ulvt"), mux, depth, width, Seq(generateReadWritePort(prefix, None, None, maskGran))) + def generateSimpleSRAMGroup( + prefix: String, + mux: Int, + depth: Range, + width: Range, + maskGran: Option[Int] = None, + extraPorts: Seq[MacroExtraPort] = List() + ): SRAMGroup = { + SRAMGroup( + Seq("mygroup_", "width", "x", "depth", "_", "VT"), + "1rw", + Seq("svt", "lvt", "ulvt"), + mux, + depth, + width, + Seq(generateReadWritePort(prefix, None, None, maskGran)) + ) } // 'vt': ('svt','lvt','ulvt'), 'mux': 2, 'depth': range(16,513,8), 'width': range(8,289,2), 'ports': 1 // 'vt': ('svt','lvt','ulvt'), 'mux': 4, 'depth': range(32,1025,16), 'width': range(4,145), 'ports': 1} def generateSRAMCompiler(name: String, prefix: String): mdf.macrolib.SRAMCompiler = { - SRAMCompiler(name, Seq( - generateSimpleSRAMGroup(prefix, 2, Range(16, 512, 8), Range(8, 288, 2)), - generateSimpleSRAMGroup(prefix, 4, Range(32, 1024, 16), Range(4, 144, 1)) - )) + SRAMCompiler( + name, + Seq( + generateSimpleSRAMGroup(prefix, 2, Range(16, 512, 8), Range(8, 288, 2)), + generateSimpleSRAMGroup(prefix, 4, Range(32, 1024, 16), Range(4, 144, 1)) + ) + ) } } @@ -212,147 +275,156 @@ trait HasSRAMGenerator { // Override this generator to specify the expected FIRRTL output. trait HasSimpleTestGenerator { this: MacroCompilerSpec with HasSRAMGenerator => - // Override these with "override lazy val". - // Why lazy? These are used in the constructor here so overriding non-lazily - // would be too late. - def useCompiler: Boolean = false - def memWidth: Int - def libWidth: Int - def memDepth: BigInt - def libDepth: BigInt - def memMaskGran: Option[Int] = None - def libMaskGran: Option[Int] = None - def extraPorts: Seq[mdf.macrolib.MacroExtraPort] = List() - def extraTag: String = "" + // Override these with "override lazy val". + // Why lazy? These are used in the constructor here so overriding non-lazily + // would be too late. + def useCompiler: Boolean = false + def memWidth: Int + def libWidth: Int + def memDepth: BigInt + def libDepth: BigInt + def memMaskGran: Option[Int] = None + def libMaskGran: Option[Int] = None + def extraPorts: Seq[mdf.macrolib.MacroExtraPort] = List() + def extraTag: String = "" - // "Effective" libMaskGran by considering write_enable. - val effectiveLibMaskGran = libMaskGran.getOrElse(libWidth) + // "Effective" libMaskGran by considering write_enable. + val effectiveLibMaskGran = libMaskGran.getOrElse(libWidth) - // Override this in the sub-generator if you need a more specific name. - // Defaults to using reflection to pull the name of the test using this - // generator. - def generatorType: String = this.getClass.getSimpleName + // Override this in the sub-generator if you need a more specific name. + // Defaults to using reflection to pull the name of the test using this + // generator. + def generatorType: String = this.getClass.getSimpleName - //require (memDepth >= libDepth) + //require (memDepth >= libDepth) - // Convenience variables to check if a mask exists. - val memHasMask = memMaskGran != None - val libHasMask = libMaskGran != None - // We need to figure out how many mask bits there are in the mem. - val memMaskBits = if (memHasMask) memWidth / memMaskGran.get else 0 - val libMaskBits = if (libHasMask) libWidth / libMaskGran.get else 0 + // Convenience variables to check if a mask exists. + val memHasMask = memMaskGran != None + val libHasMask = libMaskGran != None + // We need to figure out how many mask bits there are in the mem. + val memMaskBits = if (memHasMask) memWidth / memMaskGran.get else 0 + val libMaskBits = if (libHasMask) libWidth / libMaskGran.get else 0 - val extraTagPrefixed = if (extraTag == "") "" else ("-" + extraTag) + val extraTagPrefixed = if (extraTag == "") "" else ("-" + extraTag) - val mem = s"mem-${generatorType}${extraTagPrefixed}.json" - val lib = s"lib-${generatorType}${extraTagPrefixed}.json" - val v = s"${generatorType}${extraTagPrefixed}.v" + val mem = s"mem-${generatorType}${extraTagPrefixed}.json" + val lib = s"lib-${generatorType}${extraTagPrefixed}.json" + val v = s"${generatorType}${extraTagPrefixed}.v" - lazy val mem_name = "target_memory" - val mem_addr_width = MacroCompilerMath.ceilLog2(memDepth) + lazy val mem_name = "target_memory" + val mem_addr_width = MacroCompilerMath.ceilLog2(memDepth) - lazy val lib_name = "awesome_lib_mem" - val lib_addr_width = MacroCompilerMath.ceilLog2(libDepth) + lazy val lib_name = "awesome_lib_mem" + val lib_addr_width = MacroCompilerMath.ceilLog2(libDepth) - // Override these to change the port prefixes if needed. - def libPortPrefix: String = "lib" - def memPortPrefix: String = "outer" + // Override these to change the port prefixes if needed. + def libPortPrefix: String = "lib" + def memPortPrefix: String = "outer" - // These generate "simple" SRAMs (1 masked read-write port) by default, - // but can be overridden if need be. - def generateLibSRAM() = generateSRAM(lib_name, libPortPrefix, libWidth, libDepth, libMaskGran, extraPorts) - def generateMemSRAM() = generateSRAM(mem_name, memPortPrefix, memWidth, memDepth, memMaskGran) + // These generate "simple" SRAMs (1 masked read-write port) by default, + // but can be overridden if need be. + def generateLibSRAM() = generateSRAM(lib_name, libPortPrefix, libWidth, libDepth, libMaskGran, extraPorts) + def generateMemSRAM() = generateSRAM(mem_name, memPortPrefix, memWidth, memDepth, memMaskGran) - def libSRAM = generateLibSRAM - def memSRAM = generateMemSRAM + def libSRAM = generateLibSRAM + def memSRAM = generateMemSRAM - def libSRAMs: Seq[SRAMMacro] = Seq(libSRAM) - def memSRAMs: Seq[SRAMMacro] = Seq(memSRAM) + def libSRAMs: Seq[SRAMMacro] = Seq(libSRAM) + def memSRAMs: Seq[SRAMMacro] = Seq(memSRAM) - writeToLib(lib, libSRAMs) - writeToMem(mem, memSRAMs) + writeToLib(lib, libSRAMs) + writeToMem(mem, memSRAMs) - // For masks, width it's a bit tricky since we have to consider cases like - // memMaskGran = 4 and libMaskGran = 8. - // Consider the actually usable libWidth in cases like the above. - val usableLibWidth = if (memMaskGran.getOrElse(Int.MaxValue) < effectiveLibMaskGran) memMaskGran.get else libWidth + // For masks, width it's a bit tricky since we have to consider cases like + // memMaskGran = 4 and libMaskGran = 8. + // Consider the actually usable libWidth in cases like the above. + val usableLibWidth = if (memMaskGran.getOrElse(Int.MaxValue) < effectiveLibMaskGran) memMaskGran.get else libWidth - // Number of lib instances needed to hold the mem, in both directions. - // Round up (e.g. 1.5 instances = effectively 2 instances) - val depthInstances = math.ceil(memDepth.toFloat / libDepth.toFloat).toInt - val widthInstances = math.ceil(memWidth.toFloat / usableLibWidth).toInt + // Number of lib instances needed to hold the mem, in both directions. + // Round up (e.g. 1.5 instances = effectively 2 instances) + val depthInstances = math.ceil(memDepth.toFloat / libDepth.toFloat).toInt + val widthInstances = math.ceil(memWidth.toFloat / usableLibWidth).toInt - // Number of width bits in the last width-direction memory. - // e.g. if memWidth = 16 and libWidth = 8, this would be 8 since the last memory 0_1 has 8 bits of input width. - // e.g. if memWidth = 9 and libWidth = 8, this would be 1 since the last memory 0_1 has 1 bit of input width. - lazy val lastWidthBits = if (memWidth % usableLibWidth == 0) usableLibWidth else (memWidth % usableLibWidth) - lazy val selectBits = mem_addr_width - lib_addr_width + // Number of width bits in the last width-direction memory. + // e.g. if memWidth = 16 and libWidth = 8, this would be 8 since the last memory 0_1 has 8 bits of input width. + // e.g. if memWidth = 9 and libWidth = 8, this would be 1 since the last memory 0_1 has 1 bit of input width. + lazy val lastWidthBits = if (memWidth % usableLibWidth == 0) usableLibWidth else (memWidth % usableLibWidth) + lazy val selectBits = mem_addr_width - lib_addr_width - /** - * Convenience function to generate a mask statement. - * @param widthInst Width instance (mem_0_x) - * @param depthInst Depth instance (mem_x_0) - */ - def generateMaskStatement(widthInst: Int, depthInst: Int): String = { - // Width of this submemory. - val myMemWidth = if (widthInst == widthInstances - 1) lastWidthBits else usableLibWidth - // Base bit of this submemory. - // e.g. if libWidth is 8 and this is submemory 2 (0-indexed), then this - // would be 16. - val myBaseBit = usableLibWidth*widthInst + /** Convenience function to generate a mask statement. + * @param widthInst Width instance (mem_0_x) + * @param depthInst Depth instance (mem_x_0) + */ + def generateMaskStatement(widthInst: Int, depthInst: Int): String = { + // Width of this submemory. + val myMemWidth = if (widthInst == widthInstances - 1) lastWidthBits else usableLibWidth + // Base bit of this submemory. + // e.g. if libWidth is 8 and this is submemory 2 (0-indexed), then this + // would be 16. + val myBaseBit = usableLibWidth * widthInst - if (libMaskGran.isDefined) { - if (memMaskGran.isEmpty) { - // If there is no memory mask, we should just turn all the lib mask - // bits high. - s"""mem_${depthInst}_${widthInst}.lib_mask <= UInt<${libMaskBits}>("h${((1 << libMaskBits) - 1).toHexString}")""" - } else { - // Calculate which bit of outer_mask contains the given bit. - // e.g. if memMaskGran = 2, libMaskGran = 1 and libWidth = 4, then - // calculateMaskBit({0, 1}) = 0 and calculateMaskBit({1, 2}) = 1 - def calculateMaskBit(bit:Int): Int = bit / memMaskGran.getOrElse(memWidth) + if (libMaskGran.isDefined) { + if (memMaskGran.isEmpty) { + // If there is no memory mask, we should just turn all the lib mask + // bits high. + s"""mem_${depthInst}_${widthInst}.lib_mask <= UInt<${libMaskBits}>("h${((1 << libMaskBits) - 1).toHexString}")""" + } else { + // Calculate which bit of outer_mask contains the given bit. + // e.g. if memMaskGran = 2, libMaskGran = 1 and libWidth = 4, then + // calculateMaskBit({0, 1}) = 0 and calculateMaskBit({1, 2}) = 1 + def calculateMaskBit(bit: Int): Int = bit / memMaskGran.getOrElse(memWidth) - val bitsArr = ((libMaskBits - 1 to 0 by -1) map (x => { - if (x*libMaskGran.get > myMemWidth) { - // If we have extra mask bits leftover after the effective width, - // disable those bits. - """UInt<1>("h0")""" - } else { - val outerMaskBit = calculateMaskBit(x*libMaskGran.get + myBaseBit) - s"bits(outer_mask, ${outerMaskBit}, ${outerMaskBit})" - } - })) - val maskVal = bitsArr.reduceRight((bit, rest) => s"cat($bit, $rest)") - s"mem_${depthInst}_${widthInst}.lib_mask <= ${maskVal}" - } - } else "" - } - - /** Helper function to generate a port. - * - * @param prefix Memory port prefix (e.g. "x" for ports like "x_clk") - * @param addrWidth Address port width - * @param width data width - * @param write Has a write port? - * @param writeEnable Has a write enable port? - * @param read Has a read port? - * @param readEnable Has a read enable port? - * @param mask Mask granularity (# bits) of the port or None. - * @param extraPorts Extra ports (name, # bits) - */ - def generatePort(prefix: String, addrWidth: Int, width: Int, write: Boolean, writeEnable: Boolean, read: Boolean, readEnable: Boolean, mask: Option[Int], extraPorts: Seq[(String, Int)] = Seq()): String = { - val realPrefix = if (prefix == "") "" else prefix + "_" - - val readStr = if (read) s"output ${realPrefix}dout : UInt<$width>" else "" - val writeStr = if (write) s"input ${realPrefix}din : UInt<$width>" else "" - val readEnableStr = if (readEnable) s"input ${realPrefix}read_en : UInt<1>" else "" - val writeEnableStr = if (writeEnable) s"input ${realPrefix}write_en : UInt<1>" else "" - val maskStr = mask match { - case Some(maskBits: Int) => s"input ${realPrefix}mask : UInt<$maskBits>" - case _ => "" + val bitsArr = ((libMaskBits - 1 to 0 by -1).map(x => { + if (x * libMaskGran.get > myMemWidth) { + // If we have extra mask bits leftover after the effective width, + // disable those bits. + """UInt<1>("h0")""" + } else { + val outerMaskBit = calculateMaskBit(x * libMaskGran.get + myBaseBit) + s"bits(outer_mask, ${outerMaskBit}, ${outerMaskBit})" + } + })) + val maskVal = bitsArr.reduceRight((bit, rest) => s"cat($bit, $rest)") + s"mem_${depthInst}_${widthInst}.lib_mask <= ${maskVal}" } - val extraPortsStr = extraPorts.map { case (name, bits) => s" input $name : UInt<$bits>" }.mkString("\n") - s""" + } else "" + } + + /** Helper function to generate a port. + * + * @param prefix Memory port prefix (e.g. "x" for ports like "x_clk") + * @param addrWidth Address port width + * @param width data width + * @param write Has a write port? + * @param writeEnable Has a write enable port? + * @param read Has a read port? + * @param readEnable Has a read enable port? + * @param mask Mask granularity (# bits) of the port or None. + * @param extraPorts Extra ports (name, # bits) + */ + def generatePort( + prefix: String, + addrWidth: Int, + width: Int, + write: Boolean, + writeEnable: Boolean, + read: Boolean, + readEnable: Boolean, + mask: Option[Int], + extraPorts: Seq[(String, Int)] = Seq() + ): String = { + val realPrefix = if (prefix == "") "" else prefix + "_" + + val readStr = if (read) s"output ${realPrefix}dout : UInt<$width>" else "" + val writeStr = if (write) s"input ${realPrefix}din : UInt<$width>" else "" + val readEnableStr = if (readEnable) s"input ${realPrefix}read_en : UInt<1>" else "" + val writeEnableStr = if (writeEnable) s"input ${realPrefix}write_en : UInt<1>" else "" + val maskStr = mask match { + case Some(maskBits: Int) => s"input ${realPrefix}mask : UInt<$maskBits>" + case _ => "" + } + val extraPortsStr = extraPorts.map { case (name, bits) => s" input $name : UInt<$bits>" }.mkString("\n") + s""" input ${realPrefix}addr : UInt<$addrWidth> input ${realPrefix}clk : Clock $writeStr @@ -362,92 +434,121 @@ trait HasSimpleTestGenerator { $maskStr $extraPortsStr """ - } + } - /** - * Helper function to generate a RW footer port. - * - * @param prefix Memory port prefix (e.g. "x" for ports like "x_clk") - * @param readEnable Has a read enable port? - * @param mask Mask granularity (# bits) of the port or None. - * @param extraPorts Extra ports (name, # bits) - */ - def generateReadWriteFooterPort(prefix: String, readEnable: Boolean, mask: Option[Int], extraPorts: Seq[(String, Int)] = Seq()): String = { - generatePort(prefix, lib_addr_width, libWidth, - write = true, writeEnable = true, read = true, readEnable = readEnable, mask = mask, extraPorts = extraPorts) - } + /** Helper function to generate a RW footer port. + * + * @param prefix Memory port prefix (e.g. "x" for ports like "x_clk") + * @param readEnable Has a read enable port? + * @param mask Mask granularity (# bits) of the port or None. + * @param extraPorts Extra ports (name, # bits) + */ + def generateReadWriteFooterPort( + prefix: String, + readEnable: Boolean, + mask: Option[Int], + extraPorts: Seq[(String, Int)] = Seq() + ): String = { + generatePort( + prefix, + lib_addr_width, + libWidth, + write = true, + writeEnable = true, + read = true, + readEnable = readEnable, + mask = mask, + extraPorts = extraPorts + ) + } - /** Helper function to generate a RW header port. - * @param prefix Memory port prefix (e.g. "x" for ports like "x_clk") - * @param readEnable Has a read enable port? - * @param mask Mask granularity (# bits) of the port or None. */ - def generateReadWriteHeaderPort(prefix: String, readEnable: Boolean, mask: Option[Int]): String = { - generatePort(prefix, mem_addr_width, memWidth, - write=true, writeEnable=true, read=true, readEnable=readEnable, mask) - } + /** Helper function to generate a RW header port. + * @param prefix Memory port prefix (e.g. "x" for ports like "x_clk") + * @param readEnable Has a read enable port? + * @param mask Mask granularity (# bits) of the port or None. + */ + def generateReadWriteHeaderPort(prefix: String, readEnable: Boolean, mask: Option[Int]): String = { + generatePort( + prefix, + mem_addr_width, + memWidth, + write = true, + writeEnable = true, + read = true, + readEnable = readEnable, + mask + ) + } - // Generate the header memory ports. - def generateHeaderPorts(): String = { - require (memSRAM.ports.size == 1, "Header generator only supports single RW port mem") - generateReadWriteHeaderPort(memPortPrefix, memSRAM.ports(0).readEnable.isDefined, if (memHasMask) Some(memMaskBits) else None) - } + // Generate the header memory ports. + def generateHeaderPorts(): String = { + require(memSRAM.ports.size == 1, "Header generator only supports single RW port mem") + generateReadWriteHeaderPort( + memPortPrefix, + memSRAM.ports(0).readEnable.isDefined, + if (memHasMask) Some(memMaskBits) else None + ) + } - // Generate the header (contains the circuit statement and the target memory - // module. - def generateHeader(): String = { - s""" + // Generate the header (contains the circuit statement and the target memory + // module. + def generateHeader(): String = { + s""" circuit $mem_name : module $mem_name : ${generateHeaderPorts} """ - } + } - // Generate the target memory ports. - def generateFooterPorts(): String = { - require(libSRAM.ports.size == 1, "Footer generator only supports single RW port mem") - generateReadWriteFooterPort(libPortPrefix, libSRAM.ports(0).readEnable.isDefined, - if (libHasMask) Some(libMaskBits) else None, extraPorts.map(p => (p.name, p.width))) - } + // Generate the target memory ports. + def generateFooterPorts(): String = { + require(libSRAM.ports.size == 1, "Footer generator only supports single RW port mem") + generateReadWriteFooterPort( + libPortPrefix, + libSRAM.ports(0).readEnable.isDefined, + if (libHasMask) Some(libMaskBits) else None, + extraPorts.map(p => (p.name, p.width)) + ) + } - // Generate the footer (contains the target memory extmodule declaration by default). - def generateFooter(): String = { - s""" + // Generate the footer (contains the target memory extmodule declaration by default). + def generateFooter(): String = { + s""" extmodule $lib_name : ${generateFooterPorts} defname = $lib_name """ - } + } - // Abstract method to generate body; to be overridden by specific generator type. - def generateBody(): String + // Abstract method to generate body; to be overridden by specific generator type. + def generateBody(): String - // Generate the entire output from header, body, and footer. - def generateOutput(): String = { - s""" + // Generate the entire output from header, body, and footer. + def generateOutput(): String = { + s""" ${generateHeader} ${generateBody} ${generateFooter} """ - } + } - val output = generateOutput() + val output = generateOutput() } // Use this trait for tests that invoke the memory compiler without lib. trait HasNoLibTestGenerator extends HasSimpleTestGenerator { this: MacroCompilerSpec with HasSRAMGenerator => - // If there isn't a lib, then the "lib" will become a FIRRTL "mem", which - // in turn becomes synthesized flops. - // Therefore, make "lib" width/depth equal to the mem. - override lazy val libDepth = memDepth - override lazy val libWidth = memWidth - override lazy val lib_name = mem_name - // Do the same for port names. - override lazy val libPortPrefix = memPortPrefix + // If there isn't a lib, then the "lib" will become a FIRRTL "mem", which + // in turn becomes synthesized flops. + // Therefore, make "lib" width/depth equal to the mem. + override lazy val libDepth = memDepth + override lazy val libWidth = memWidth + override lazy val lib_name = mem_name + // Do the same for port names. + override lazy val libPortPrefix = memPortPrefix - // If there is no lib, don't generate a body. - override def generateBody = "" + // If there is no lib, don't generate a body. + override def generateBody = "" } - diff --git a/macros/src/test/scala/barstools/macros/Masks.scala b/macros/src/test/scala/barstools/macros/Masks.scala index f104c8f2..c472669a 100644 --- a/macros/src/test/scala/barstools/macros/Masks.scala +++ b/macros/src/test/scala/barstools/macros/Masks.scala @@ -4,32 +4,36 @@ package barstools.macros trait MasksTestSettings { this: MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator => - override lazy val memDepth = BigInt(2048) - override lazy val libDepth = BigInt(1024) + override lazy val memDepth = BigInt(2048) + override lazy val libDepth = BigInt(1024) } // Try all four different kinds of mask config: -/** - * - * Non-masked mem Masked mem - * --------------------------------- - * Non-masked lib | | | - * --------------------------------- - * Masked lib | | | - * --------------------------------- - */ +/** Non-masked mem Masked mem + * --------------------------------- + * Non-masked lib | | | + * --------------------------------- + * Masked lib | | | + * --------------------------------- + */ -class Masks_FourTypes_NonMaskedMem_NonMaskedLib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class Masks_FourTypes_NonMaskedMem_NonMaskedLib + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 32 override lazy val memMaskGran = None - override lazy val libWidth = 8 + override lazy val libWidth = 8 override lazy val libMaskGran = None compileExecuteAndTest(mem, lib, v, output) } -class Masks_FourTypes_NonMaskedMem_MaskedLib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class Masks_FourTypes_NonMaskedMem_MaskedLib + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 32 override lazy val memMaskGran = None @@ -39,7 +43,10 @@ class Masks_FourTypes_NonMaskedMem_MaskedLib extends MacroCompilerSpec with HasS compileExecuteAndTest(mem, lib, v, output) } -class Masks_FourTypes_MaskedMem_NonMaskedLib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class Masks_FourTypes_MaskedMem_NonMaskedLib + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 32 override lazy val memMaskGran = Some(8) @@ -49,7 +56,10 @@ class Masks_FourTypes_MaskedMem_NonMaskedLib extends MacroCompilerSpec with HasS compileExecuteAndTest(mem, lib, v, output) } -class Masks_FourTypes_MaskedMem_NonMaskedLib_SmallerMaskGran extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class Masks_FourTypes_MaskedMem_NonMaskedLib_SmallerMaskGran + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 32 override lazy val memMaskGran = Some(4) @@ -59,7 +69,10 @@ class Masks_FourTypes_MaskedMem_NonMaskedLib_SmallerMaskGran extends MacroCompil compileExecuteAndTest(mem, lib, v, output) } -class Masks_FourTypes_MaskedMem_MaskedLib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class Masks_FourTypes_MaskedMem_MaskedLib + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 32 override lazy val memMaskGran = Some(8) @@ -69,7 +82,10 @@ class Masks_FourTypes_MaskedMem_MaskedLib extends MacroCompilerSpec with HasSRAM compileExecuteAndTest(mem, lib, v, output) } -class Masks_FourTypes_MaskedMem_MaskedLib_SameMaskGran extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class Masks_FourTypes_MaskedMem_MaskedLib_SameMaskGran + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 32 override lazy val memMaskGran = Some(8) @@ -79,7 +95,10 @@ class Masks_FourTypes_MaskedMem_MaskedLib_SameMaskGran extends MacroCompilerSpec compileExecuteAndTest(mem, lib, v, output) } -class Masks_FourTypes_MaskedMem_MaskedLib_SmallerMaskGran extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class Masks_FourTypes_MaskedMem_MaskedLib_SmallerMaskGran + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 64 override lazy val memMaskGran = Some(4) @@ -103,7 +122,11 @@ class Masks_BitMaskedMem_NonMaskedLib extends MacroCompilerSpec with HasSRAMGene // FPGA-style byte-masked memories. -class Masks_FPGAStyle_32_8 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_FPGAStyle_32_8 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 32 override lazy val memMaskGran = Some(32) override lazy val libMaskGran = Some(8) @@ -113,7 +136,11 @@ class Masks_FPGAStyle_32_8 extends MacroCompilerSpec with HasSRAMGenerator with // Simple powers of two with bit-masked lib. -class Masks_PowersOfTwo_8_1 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_PowersOfTwo_8_1 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 64 override lazy val memMaskGran = Some(8) override lazy val libMaskGran = Some(1) @@ -121,7 +148,11 @@ class Masks_PowersOfTwo_8_1 extends MacroCompilerSpec with HasSRAMGenerator with compileExecuteAndTest(mem, lib, v, output) } -class Masks_PowersOfTwo_16_1 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_PowersOfTwo_16_1 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 64 override lazy val memMaskGran = Some(16) override lazy val libMaskGran = Some(1) @@ -129,7 +160,11 @@ class Masks_PowersOfTwo_16_1 extends MacroCompilerSpec with HasSRAMGenerator wit compileExecuteAndTest(mem, lib, v, output) } -class Masks_PowersOfTwo_32_1 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_PowersOfTwo_32_1 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 64 override lazy val memMaskGran = Some(32) override lazy val libMaskGran = Some(1) @@ -137,7 +172,11 @@ class Masks_PowersOfTwo_32_1 extends MacroCompilerSpec with HasSRAMGenerator wit compileExecuteAndTest(mem, lib, v, output) } -class Masks_PowersOfTwo_64_1 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_PowersOfTwo_64_1 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 64 override lazy val memMaskGran = Some(64) override lazy val libMaskGran = Some(1) @@ -147,7 +186,11 @@ class Masks_PowersOfTwo_64_1 extends MacroCompilerSpec with HasSRAMGenerator wit // Simple powers of two with non bit-masked lib. -class Masks_PowersOfTwo_32_4 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_PowersOfTwo_32_4 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 128 override lazy val memMaskGran = Some(32) override lazy val libMaskGran = Some(4) @@ -155,7 +198,11 @@ class Masks_PowersOfTwo_32_4 extends MacroCompilerSpec with HasSRAMGenerator wit compileExecuteAndTest(mem, lib, v, output) } -class Masks_PowersOfTwo_32_8 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_PowersOfTwo_32_8 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 128 override lazy val memMaskGran = Some(32) override lazy val libMaskGran = Some(8) @@ -163,7 +210,11 @@ class Masks_PowersOfTwo_32_8 extends MacroCompilerSpec with HasSRAMGenerator wit compileExecuteAndTest(mem, lib, v, output) } -class Masks_PowersOfTwo_8_8 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_PowersOfTwo_8_8 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 128 override lazy val memMaskGran = Some(8) override lazy val libMaskGran = Some(8) @@ -173,7 +224,11 @@ class Masks_PowersOfTwo_8_8 extends MacroCompilerSpec with HasSRAMGenerator with // Width as a multiple of the mask, bit-masked lib -class Masks_IntegerMaskMultiple_20_10 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_IntegerMaskMultiple_20_10 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 20 override lazy val memMaskGran = Some(10) override lazy val libMaskGran = Some(1) @@ -181,16 +236,24 @@ class Masks_IntegerMaskMultiple_20_10 extends MacroCompilerSpec with HasSRAMGene compileExecuteAndTest(mem, lib, v, output) } -class Masks_IntegerMaskMultiple_21_7 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_IntegerMaskMultiple_21_7 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 21 override lazy val memMaskGran = Some(21) override lazy val libMaskGran = Some(7) - it should "be enabled when non-power of two masks are supported" is (pending) + (it should "be enabled when non-power of two masks are supported").is(pending) //~ compileExecuteAndTest(mem, lib, v, output) } -class Masks_IntegerMaskMultiple_21_21 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_IntegerMaskMultiple_21_21 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 21 override lazy val memMaskGran = Some(21) override lazy val libMaskGran = Some(1) @@ -198,7 +261,11 @@ class Masks_IntegerMaskMultiple_21_21 extends MacroCompilerSpec with HasSRAMGene compileExecuteAndTest(mem, lib, v, output) } -class Masks_IntegerMaskMultiple_84_21 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_IntegerMaskMultiple_84_21 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 84 override lazy val memMaskGran = Some(21) override lazy val libMaskGran = Some(1) @@ -206,7 +273,11 @@ class Masks_IntegerMaskMultiple_84_21 extends MacroCompilerSpec with HasSRAMGene compileExecuteAndTest(mem, lib, v, output) } -class Masks_IntegerMaskMultiple_92_23 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_IntegerMaskMultiple_92_23 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 92 override lazy val memMaskGran = Some(23) override lazy val libMaskGran = Some(1) @@ -214,7 +285,11 @@ class Masks_IntegerMaskMultiple_92_23 extends MacroCompilerSpec with HasSRAMGene compileExecuteAndTest(mem, lib, v, output) } -class Masks_IntegerMaskMultiple_117_13 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_IntegerMaskMultiple_117_13 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 117 override lazy val memMaskGran = Some(13) override lazy val libMaskGran = Some(1) @@ -222,7 +297,11 @@ class Masks_IntegerMaskMultiple_117_13 extends MacroCompilerSpec with HasSRAMGen compileExecuteAndTest(mem, lib, v, output) } -class Masks_IntegerMaskMultiple_160_20 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_IntegerMaskMultiple_160_20 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 160 override lazy val memMaskGran = Some(20) override lazy val libMaskGran = Some(1) @@ -230,7 +309,11 @@ class Masks_IntegerMaskMultiple_160_20 extends MacroCompilerSpec with HasSRAMGen compileExecuteAndTest(mem, lib, v, output) } -class Masks_IntegerMaskMultiple_184_23 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_IntegerMaskMultiple_184_23 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 184 override lazy val memMaskGran = Some(23) override lazy val libMaskGran = Some(1) @@ -240,11 +323,15 @@ class Masks_IntegerMaskMultiple_184_23 extends MacroCompilerSpec with HasSRAMGen // Width as an non-integer multiple of the mask, bit-masked lib -class Masks_NonIntegerMaskMultiple_32_3 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings { +class Masks_NonIntegerMaskMultiple_32_3 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with MasksTestSettings { override lazy val width = 32 override lazy val memMaskGran = Some(3) override lazy val libMaskGran = Some(1) - it should "be enabled when non-power of two masks are supported" is (pending) + (it should "be enabled when non-power of two masks are supported").is(pending) //~ compileExecuteAndTest(mem, lib, v, output) } diff --git a/macros/src/test/scala/barstools/macros/MultiPort.scala b/macros/src/test/scala/barstools/macros/MultiPort.scala index 3899f835..1968f6aa 100644 --- a/macros/src/test/scala/barstools/macros/MultiPort.scala +++ b/macros/src/test/scala/barstools/macros/MultiPort.scala @@ -13,42 +13,70 @@ class SplitWidth_2rw extends MacroCompilerSpec with HasSRAMGenerator with HasSim override def generateMemSRAM() = { SRAMMacro( - name=mem_name, - width=memWidth, - depth=memDepth, - family="2rw", - ports=Seq(generateTestPort( - "portA", memWidth, Some(memDepth), maskGran=memMaskGran, - write=true, writeEnable=true, - read=true, readEnable=true - ), generateTestPort( - "portB", memWidth, Some(memDepth), maskGran=memMaskGran, - write=true, writeEnable=true, - read=true, readEnable=true - )) + name = mem_name, + width = memWidth, + depth = memDepth, + family = "2rw", + ports = Seq( + generateTestPort( + "portA", + memWidth, + Some(memDepth), + maskGran = memMaskGran, + write = true, + writeEnable = true, + read = true, + readEnable = true + ), + generateTestPort( + "portB", + memWidth, + Some(memDepth), + maskGran = memMaskGran, + write = true, + writeEnable = true, + read = true, + readEnable = true + ) + ) ) } override def generateLibSRAM() = { SRAMMacro( - name=lib_name, - width=libWidth, - depth=libDepth, - family="2rw", - ports=Seq(generateTestPort( - "portA", libWidth, libDepth, - write=true, writeEnable=true, - read=true, readEnable=true - ), generateTestPort( - "portB", libWidth, libDepth, - write=true, writeEnable=true, - read=true, readEnable=true - )) + name = lib_name, + width = libWidth, + depth = libDepth, + family = "2rw", + ports = Seq( + generateTestPort( + "portA", + libWidth, + libDepth, + write = true, + writeEnable = true, + read = true, + readEnable = true + ), + generateTestPort( + "portB", + libWidth, + libDepth, + write = true, + writeEnable = true, + read = true, + readEnable = true + ) + ) ) } override def generateHeaderPorts() = { - generateReadWriteHeaderPort("portA", true, Some(memMaskBits)) + "\n" + generateReadWriteHeaderPort("portB", true, Some(memMaskBits)) + generateReadWriteHeaderPort("portA", true, Some(memMaskBits)) + "\n" + generateReadWriteHeaderPort( + "portB", + true, + Some(memMaskBits) + ) } override def generateFooterPorts() = { @@ -56,7 +84,7 @@ class SplitWidth_2rw extends MacroCompilerSpec with HasSRAMGenerator with HasSim } override def generateBody() = -""" + """ inst mem_0_0 of awesome_lib_mem inst mem_0_1 of awesome_lib_mem inst mem_0_2 of awesome_lib_mem @@ -128,56 +156,112 @@ class SplitWidth_1r_1w extends MacroCompilerSpec with HasSRAMGenerator with HasS override def generateMemSRAM() = { SRAMMacro( - name=mem_name, - width=memWidth, - depth=memDepth, - family="1r1w", - ports=Seq(generateTestPort( - "portA", memWidth, Some(memDepth), maskGran=memMaskGran, - write=false, writeEnable=false, - read=true, readEnable=true - ), generateTestPort( - "portB", memWidth, Some(memDepth), maskGran=memMaskGran, - write=true, writeEnable=true, - read=false, readEnable=false - )) + name = mem_name, + width = memWidth, + depth = memDepth, + family = "1r1w", + ports = Seq( + generateTestPort( + "portA", + memWidth, + Some(memDepth), + maskGran = memMaskGran, + write = false, + writeEnable = false, + read = true, + readEnable = true + ), + generateTestPort( + "portB", + memWidth, + Some(memDepth), + maskGran = memMaskGran, + write = true, + writeEnable = true, + read = false, + readEnable = false + ) + ) ) } override def generateLibSRAM() = { SRAMMacro( - name=lib_name, - width=libWidth, - depth=libDepth, - family="1r1w", - ports=Seq(generateTestPort( - "portA", libWidth, libDepth, - write=false, writeEnable=false, - read=true, readEnable=true - ), generateTestPort( - "portB", libWidth, libDepth, - write=true, writeEnable=true, - read=false, readEnable=false - )) + name = lib_name, + width = libWidth, + depth = libDepth, + family = "1r1w", + ports = Seq( + generateTestPort( + "portA", + libWidth, + libDepth, + write = false, + writeEnable = false, + read = true, + readEnable = true + ), + generateTestPort( + "portB", + libWidth, + libDepth, + write = true, + writeEnable = true, + read = false, + readEnable = false + ) + ) ) } override def generateHeaderPorts() = { - generatePort("portA", mem_addr_width, memWidth, - write=false, writeEnable=false, read=true, readEnable=true, Some(memMaskBits)) + "\n" + - generatePort("portB", mem_addr_width, memWidth, - write=true, writeEnable=true, read=false, readEnable=false, Some(memMaskBits)) + generatePort( + "portA", + mem_addr_width, + memWidth, + write = false, + writeEnable = false, + read = true, + readEnable = true, + Some(memMaskBits) + ) + "\n" + + generatePort( + "portB", + mem_addr_width, + memWidth, + write = true, + writeEnable = true, + read = false, + readEnable = false, + Some(memMaskBits) + ) } override def generateFooterPorts() = { - generatePort("portA", lib_addr_width, libWidth, - write=false, writeEnable=false, read=true, readEnable=true, None) + "\n" + - generatePort("portB", lib_addr_width, libWidth, - write=true, writeEnable=true, read=false, readEnable=false, None) + generatePort( + "portA", + lib_addr_width, + libWidth, + write = false, + writeEnable = false, + read = true, + readEnable = true, + None + ) + "\n" + + generatePort( + "portB", + lib_addr_width, + libWidth, + write = true, + writeEnable = true, + read = false, + readEnable = false, + None + ) } override def generateBody() = -""" + """ inst mem_0_0 of awesome_lib_mem inst mem_0_1 of awesome_lib_mem inst mem_0_2 of awesome_lib_mem @@ -234,42 +318,70 @@ class SplitWidth_2rw_differentMasks extends MacroCompilerSpec with HasSRAMGenera override def generateMemSRAM() = { println(memMaskGranB) SRAMMacro( - name=mem_name, - width=memWidth, - depth=memDepth, - family="2rw", - ports=Seq(generateTestPort( - "portA", memWidth, Some(memDepth), maskGran=memMaskGran, - write=true, writeEnable=true, - read=true, readEnable=true - ), generateTestPort( - "portB", memWidth, Some(memDepth), maskGran=Some(memMaskGranB), - write=true, writeEnable=true, - read=true, readEnable=true - )) + name = mem_name, + width = memWidth, + depth = memDepth, + family = "2rw", + ports = Seq( + generateTestPort( + "portA", + memWidth, + Some(memDepth), + maskGran = memMaskGran, + write = true, + writeEnable = true, + read = true, + readEnable = true + ), + generateTestPort( + "portB", + memWidth, + Some(memDepth), + maskGran = Some(memMaskGranB), + write = true, + writeEnable = true, + read = true, + readEnable = true + ) + ) ) } override def generateLibSRAM() = { SRAMMacro( - name=lib_name, - width=libWidth, - depth=libDepth, - family="2rw", - ports=Seq(generateTestPort( - "portA", libWidth, libDepth, - write=true, writeEnable=true, - read=true, readEnable=true - ), generateTestPort( - "portB", libWidth, libDepth, - write=true, writeEnable=true, - read=true, readEnable=true - )) + name = lib_name, + width = libWidth, + depth = libDepth, + family = "2rw", + ports = Seq( + generateTestPort( + "portA", + libWidth, + libDepth, + write = true, + writeEnable = true, + read = true, + readEnable = true + ), + generateTestPort( + "portB", + libWidth, + libDepth, + write = true, + writeEnable = true, + read = true, + readEnable = true + ) + ) ) } override def generateHeaderPorts() = { - generateReadWriteHeaderPort("portA", true, Some(memMaskBits)) + "\n" + generateReadWriteHeaderPort("portB", true, Some(memWidth / memMaskGranB)) + generateReadWriteHeaderPort("portA", true, Some(memMaskBits)) + "\n" + generateReadWriteHeaderPort( + "portB", + true, + Some(memWidth / memMaskGranB) + ) } override def generateFooterPorts() = { @@ -277,7 +389,7 @@ class SplitWidth_2rw_differentMasks extends MacroCompilerSpec with HasSRAMGenera } override def generateBody() = -""" + """ inst mem_0_0 of awesome_lib_mem inst mem_0_1 of awesome_lib_mem inst mem_0_2 of awesome_lib_mem diff --git a/macros/src/test/scala/barstools/macros/SRAMCompiler.scala b/macros/src/test/scala/barstools/macros/SRAMCompiler.scala index e4e62de7..17f49601 100644 --- a/macros/src/test/scala/barstools/macros/SRAMCompiler.scala +++ b/macros/src/test/scala/barstools/macros/SRAMCompiler.scala @@ -13,8 +13,7 @@ class SRAMCompiler extends MacroCompilerSpec with HasSRAMGenerator with HasSimpl writeToLib(lib, Seq(compiler)) - writeToMem(mem, Seq(generateSRAM("mymem", "X", 8, 16))) - compileExecuteAndTest(mem, Some(lib), verilog, output=output, false, true) + compileExecuteAndTest(mem, Some(lib), verilog, output = output, false, true) } diff --git a/macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala b/macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala index f016dbc7..5a7fc77d 100644 --- a/macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala +++ b/macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala @@ -6,33 +6,36 @@ package barstools.macros trait HasSimpleDepthTestGenerator extends HasSimpleTestGenerator { this: MacroCompilerSpec with HasSRAMGenerator => - def width: Int + def width: Int - override lazy val memWidth = width - override lazy val libWidth = width + override lazy val memWidth = width + override lazy val libWidth = width - // Generate a depth-splitting body. - override def generateBody(): String = { - val output = new StringBuilder + // Generate a depth-splitting body. + override def generateBody(): String = { + val output = new StringBuilder - if (selectBits > 0) { - output.append ( -s""" + if (selectBits > 0) { + output.append( + s""" node ${memPortPrefix}_addr_sel = bits(${memPortPrefix}_addr, ${mem_addr_width - 1}, $lib_addr_width) reg ${memPortPrefix}_addr_sel_reg : UInt<${selectBits}>, ${memPortPrefix}_clk with : reset => (UInt<1>("h0"), ${memPortPrefix}_addr_sel_reg) ${memPortPrefix}_addr_sel_reg <= mux(UInt<1>("h1"), ${memPortPrefix}_addr_sel, ${memPortPrefix}_addr_sel_reg) """ - ) - } + ) + } - for (i <- 0 to depthInstances - 1) { - val maskStatement = generateMaskStatement(0, i) - val enableIdentifier = if (selectBits > 0) s"""eq(${memPortPrefix}_addr_sel, UInt<${selectBits}>("h${i.toHexString}"))""" else "UInt<1>(\"h1\")" - val chipEnable = s"""UInt<1>("h1")""" - val writeEnable = if (memMaskGran.isEmpty) s"and(${memPortPrefix}_write_en, ${chipEnable})" else s"${memPortPrefix}_write_en" - output.append( - s""" + for (i <- 0 to depthInstances - 1) { + val maskStatement = generateMaskStatement(0, i) + val enableIdentifier = + if (selectBits > 0) s"""eq(${memPortPrefix}_addr_sel, UInt<${selectBits}>("h${i.toHexString}"))""" + else "UInt<1>(\"h1\")" + val chipEnable = s"""UInt<1>("h1")""" + val writeEnable = + if (memMaskGran.isEmpty) s"and(${memPortPrefix}_write_en, ${chipEnable})" else s"${memPortPrefix}_write_en" + output.append( + s""" inst mem_${i}_0 of ${lib_name} mem_${i}_0.${libPortPrefix}_clk <= ${memPortPrefix}_clk mem_${i}_0.${libPortPrefix}_addr <= ${memPortPrefix}_addr @@ -42,26 +45,29 @@ s""" mem_${i}_0.${libPortPrefix}_write_en <= and(and(${writeEnable}, UInt<1>("h1")), ${enableIdentifier}) node ${memPortPrefix}_dout_${i} = ${memPortPrefix}_dout_${i}_0 """ + ) + } + def generate_outer_dout_tree(i: Int, depthInstances: Int): String = { + if (i > depthInstances - 1) { + s"""UInt<${libWidth}>("h0")""" + } else { + s"""mux(eq(${memPortPrefix}_addr_sel_reg, UInt<%d>("h%s")), ${memPortPrefix}_dout_%d, %s)""".format( + selectBits, + i.toHexString, + i, + generate_outer_dout_tree(i + 1, depthInstances) ) } - def generate_outer_dout_tree(i:Int, depthInstances: Int): String = { - if (i > depthInstances - 1) { - s"""UInt<${libWidth}>("h0")""" - } else { - s"""mux(eq(${memPortPrefix}_addr_sel_reg, UInt<%d>("h%s")), ${memPortPrefix}_dout_%d, %s)""".format( - selectBits, i.toHexString, i, generate_outer_dout_tree(i + 1, depthInstances) - ) - } - } - output append s" ${memPortPrefix}_dout <= " - if (selectBits > 0) { - output append generate_outer_dout_tree(0, depthInstances) - } else { - output append s"""mux(UInt<1>("h1"), ${memPortPrefix}_dout_0, UInt<${libWidth}>("h0"))""" - } - - output.toString } + output.append(s" ${memPortPrefix}_dout <= ") + if (selectBits > 0) { + output.append(generate_outer_dout_tree(0, depthInstances)) + } else { + output.append(s"""mux(UInt<1>("h1"), ${memPortPrefix}_dout_0, UInt<${libWidth}>("h0"))""") + } + + output.toString + } } // Try different widths @@ -154,7 +160,10 @@ class SplitDepth2048x8_mrw_lib8 extends MacroCompilerSpec with HasSRAMGenerator } // Non-bit level mask -class SplitDepth2048x64_mrw_mem32_lib8 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator { +class SplitDepth2048x64_mrw_mem32_lib8 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator { override lazy val width = 64 override lazy val memDepth = BigInt(2048) override lazy val libDepth = BigInt(1024) @@ -165,7 +174,10 @@ class SplitDepth2048x64_mrw_mem32_lib8 extends MacroCompilerSpec with HasSRAMGen } // Bit level mask -class SplitDepth2048x32_mrw_mem16_lib1 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator { +class SplitDepth2048x32_mrw_mem16_lib1 + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator { override lazy val width = 32 override lazy val memDepth = BigInt(2048) override lazy val libDepth = BigInt(1024) @@ -213,7 +225,7 @@ class SplitDepth2048x32_mrw_mem3_lib1 extends MacroCompilerSpec with HasSRAMGene override lazy val memMaskGran = Some(3) override lazy val libMaskGran = Some(1) - it should "be enabled when non-power of two masks are supported" is (pending) + (it should "be enabled when non-power of two masks are supported").is(pending) //compileExecuteAndTest(mem, lib, v, output) } @@ -224,7 +236,7 @@ class SplitDepth2048x32_mrw_mem7_lib1 extends MacroCompilerSpec with HasSRAMGene override lazy val memMaskGran = Some(7) override lazy val libMaskGran = Some(1) - it should "be enabled when non-power of two masks are supported" is (pending) + (it should "be enabled when non-power of two masks are supported").is(pending) //compileExecuteAndTest(mem, lib, v, output) } @@ -235,7 +247,7 @@ class SplitDepth2048x32_mrw_mem9_lib1 extends MacroCompilerSpec with HasSRAMGene override lazy val memMaskGran = Some(9) override lazy val libMaskGran = Some(1) - it should "be enabled when non-power of two masks are supported" is (pending) + (it should "be enabled when non-power of two masks are supported").is(pending) //compileExecuteAndTest(mem, lib, v, output) } @@ -247,12 +259,12 @@ class SplitDepth2048x8_extraPort extends MacroCompilerSpec with HasSRAMGenerator override lazy val memDepth = BigInt(2048) override lazy val libDepth = BigInt(1024) override lazy val extraPorts = List( - MacroExtraPort(name="extra_port", width=8, portType=Constant, value=0xff) + MacroExtraPort(name = "extra_port", width = 8, portType = Constant, value = 0xff) ) override lazy val extraTag = "extraPort" override def generateOutput(): String = -""" + """ circuit target_memory : module target_memory : input outer_addr : UInt<11> @@ -317,22 +329,22 @@ class SplitDepth_SplitPortsNonMasked extends MacroCompilerSpec with HasSRAMGener val v = "split_depth-r-w-split-lib-split-mem.v" val libMacro = SRAMMacro( - name="awesome_lib_mem", - width=width, - depth=libDepth, - family="1r1w", - ports=Seq( + name = "awesome_lib_mem", + width = width, + depth = libDepth, + family = "1r1w", + ports = Seq( generateReadPort("innerA", width, libDepth), generateWritePort("innerB", width, libDepth) ) ) val memMacro = SRAMMacro( - name="target_memory", - width=width, - depth=memDepth, - family="1r1w", - ports=Seq( + name = "target_memory", + width = width, + depth = memDepth, + family = "1r1w", + ports = Seq( generateReadPort("outerB", width, memDepth), generateWritePort("outerA", width, memDepth) ) @@ -342,7 +354,7 @@ class SplitDepth_SplitPortsNonMasked extends MacroCompilerSpec with HasSRAMGener writeToLib(lib, Seq(libMacro)) val output = -""" + """ circuit target_memory : module target_memory : input outerB_addr : UInt<11> @@ -404,11 +416,11 @@ circuit target_memory : val v = "split_depth-r-w-regular-lib-split-mem.v" val memMacro = SRAMMacro( - name="target_memory", - width=width, - depth=memDepth, - family="1r1w", - ports=Seq( + name = "target_memory", + width = width, + depth = memDepth, + family = "1r1w", + ports = Seq( generateReadPort("outerB", width, memDepth), generateWritePort("outerA", width, memDepth) ) @@ -418,7 +430,7 @@ circuit target_memory : writeToLib(lib, Seq(generateSRAM("awesome_lib_mem", "lib", width, libDepth))) val output = -""" + """ TODO """ @@ -437,11 +449,11 @@ TODO val v = "split_depth-r-w-split-lib-regular-mem.v" val libMacro = SRAMMacro( - name="awesome_lib_mem", - width=width, - depth=libDepth, - family="1rw", - ports=Seq( + name = "awesome_lib_mem", + width = width, + depth = libDepth, + family = "1rw", + ports = Seq( generateReadPort("innerA", width, libDepth), generateWritePort("innerB", width, libDepth) ) @@ -451,7 +463,7 @@ TODO writeToLib(lib, Seq(libMacro)) val output = -""" + """ TODO """ @@ -478,22 +490,22 @@ class SplitDepth_SplitPortsMasked extends MacroCompilerSpec with HasSRAMGenerato val v = "split_depth-r-mw-split-lib-split-mem.v" val libMacro = SRAMMacro( - name="awesome_lib_mem", - width=width, - depth=libDepth, - family="1r1w", - ports=Seq( + name = "awesome_lib_mem", + width = width, + depth = libDepth, + family = "1r1w", + ports = Seq( generateReadPort("innerA", width, libDepth), generateWritePort("innerB", width, libDepth, libMaskGran) ) ) val memMacro = SRAMMacro( - name="target_memory", - width=width, - depth=memDepth, - family="1r1w", - ports=Seq( + name = "target_memory", + width = width, + depth = memDepth, + family = "1r1w", + ports = Seq( generateReadPort("outerB", width, memDepth), generateWritePort("outerA", width, memDepth, memMaskGran) ) @@ -503,7 +515,7 @@ class SplitDepth_SplitPortsMasked extends MacroCompilerSpec with HasSRAMGenerato writeToLib(lib, Seq(libMacro)) val output = -""" + """ circuit target_memory : module target_memory : input outerB_addr : UInt<11> @@ -569,11 +581,11 @@ circuit target_memory : val v = "split_depth-r-mw-regular-lib-split-mem.v" val memMacro = SRAMMacro( - name="target_memory", - width=width, - depth=memDepth, - family="1r1w", - ports=Seq( + name = "target_memory", + width = width, + depth = memDepth, + family = "1r1w", + ports = Seq( generateReadPort("outerB", width, memDepth), generateWritePort("outerA", width, memDepth, memMaskGran) ) @@ -583,7 +595,7 @@ circuit target_memory : writeToLib(lib, Seq(generateSRAM("awesome_lib_mem", "lib", width, libDepth, libMaskGran))) val output = -""" + """ TODO """ @@ -602,11 +614,11 @@ TODO val v = "split_depth-r-mw-split-lib-regular-mem.v" val libMacro = SRAMMacro( - name="awesome_lib_mem", - width=width, - depth=libDepth, - family="1rw", - ports=Seq( + name = "awesome_lib_mem", + width = width, + depth = libDepth, + family = "1rw", + ports = Seq( generateReadPort("innerA", width, libDepth), generateWritePort("innerB", width, libDepth, libMaskGran) ) @@ -616,7 +628,7 @@ TODO writeToLib(lib, Seq(libMacro)) val output = -""" + """ TODO """ diff --git a/macros/src/test/scala/barstools/macros/SimpleSplitWidth.scala b/macros/src/test/scala/barstools/macros/SimpleSplitWidth.scala index 843eed49..3cd0a6df 100644 --- a/macros/src/test/scala/barstools/macros/SimpleSplitWidth.scala +++ b/macros/src/test/scala/barstools/macros/SimpleSplitWidth.scala @@ -5,43 +5,45 @@ package barstools.macros trait HasSimpleWidthTestGenerator extends HasSimpleTestGenerator { this: MacroCompilerSpec with HasSRAMGenerator => - def depth: BigInt + def depth: BigInt - override lazy val memDepth = depth - override lazy val libDepth = depth + override lazy val memDepth = depth + override lazy val libDepth = depth - override def generateBody(): String = { - val output = new StringBuilder + override def generateBody(): String = { + val output = new StringBuilder - // Generate mem_0_ lines for number of width instances. - output.append( - ((0 to widthInstances - 1) map {i:Int => s""" + // Generate mem_0_ lines for number of width instances. + output.append( + ((0 to widthInstances - 1).map { i: Int => + s""" inst mem_0_${i} of ${lib_name} """ - }).reduceLeft(_ + _) - ) + }).reduceLeft(_ + _) + ) - // Generate submemory connection blocks. - output append (for (i <- 0 to widthInstances - 1) yield { - // Width of this submemory. - val myMemWidth = if (i == widthInstances - 1) lastWidthBits else usableLibWidth - // Base bit of this submemory. - // e.g. if libWidth is 8 and this is submemory 2 (0-indexed), then this - // would be 16. - val myBaseBit = usableLibWidth*i + // Generate submemory connection blocks. + output.append((for (i <- 0 to widthInstances - 1) yield { + // Width of this submemory. + val myMemWidth = if (i == widthInstances - 1) lastWidthBits else usableLibWidth + // Base bit of this submemory. + // e.g. if libWidth is 8 and this is submemory 2 (0-indexed), then this + // would be 16. + val myBaseBit = usableLibWidth * i - val maskStatement = generateMaskStatement(i, 0) + val maskStatement = generateMaskStatement(i, 0) - // We need to use writeEnable as a crude "mask" if mem has a mask but - // lib does not. - val writeEnableBit = if (libMaskGran.isEmpty && memMaskGran.isDefined) { - val outerMaskBit = myBaseBit / memMaskGran.get - s"bits(outer_mask, ${outerMaskBit}, ${outerMaskBit})" - } else """UInt<1>("h1")""" - val chipEnable = s"""UInt<1>("h1")""" - val writeEnableExpr = if (libMaskGran.isEmpty) s"and(${memPortPrefix}_write_en, ${chipEnable})" else s"${memPortPrefix}_write_en" + // We need to use writeEnable as a crude "mask" if mem has a mask but + // lib does not. + val writeEnableBit = if (libMaskGran.isEmpty && memMaskGran.isDefined) { + val outerMaskBit = myBaseBit / memMaskGran.get + s"bits(outer_mask, ${outerMaskBit}, ${outerMaskBit})" + } else """UInt<1>("h1")""" + val chipEnable = s"""UInt<1>("h1")""" + val writeEnableExpr = + if (libMaskGran.isEmpty) s"and(${memPortPrefix}_write_en, ${chipEnable})" else s"${memPortPrefix}_write_en" -s""" + s""" mem_0_${i}.${libPortPrefix}_clk <= ${memPortPrefix}_clk mem_0_${i}.${libPortPrefix}_addr <= ${memPortPrefix}_addr node ${memPortPrefix}_dout_0_${i} = bits(mem_0_${i}.${libPortPrefix}_dout, ${myMemWidth - 1}, 0) @@ -49,24 +51,23 @@ s""" ${maskStatement} mem_0_${i}.${libPortPrefix}_write_en <= and(and(${writeEnableExpr}, ${writeEnableBit}), UInt<1>("h1")) """ - }).reduceLeft(_ + _) + }).reduceLeft(_ + _)) - // Generate final output that concats together the sub-memories. - // e.g. cat(outer_dout_0_2, cat(outer_dout_0_1, outer_dout_0_0)) - output append { - val doutStatements = ((widthInstances - 1 to 0 by -1) map (i => s"${memPortPrefix}_dout_0_${i}")) - val catStmt = doutStatements.init.foldRight(doutStatements.last)((l: String, r: String) => s"cat($l, $r)") -s""" + // Generate final output that concats together the sub-memories. + // e.g. cat(outer_dout_0_2, cat(outer_dout_0_1, outer_dout_0_0)) + output.append { + val doutStatements = ((widthInstances - 1 to 0 by -1).map(i => s"${memPortPrefix}_dout_0_${i}")) + val catStmt = doutStatements.init.foldRight(doutStatements.last)((l: String, r: String) => s"cat($l, $r)") + s""" node ${memPortPrefix}_dout_0 = ${catStmt} """ - } - - output append -s""" - ${memPortPrefix}_dout <= mux(UInt<1>("h1"), ${memPortPrefix}_dout_0, UInt<${memWidth}>("h0")) -""" - output.toString } + + output.append(s""" + ${memPortPrefix}_dout <= mux(UInt<1>("h1"), ${memPortPrefix}_dout_0, UInt<${memWidth}>("h0")) +""") + output.toString + } } // Try different widths against a base memory width of 8. @@ -268,7 +269,10 @@ class SplitWidth1024x16_mem11_rw extends MacroCompilerSpec with HasSRAMGenerator // Masked RAM -class SplitWidth1024x8_memGran_8_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x8_memGran_8_libGran_1_rw + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 8 override lazy val libWidth = 8 @@ -278,7 +282,10 @@ class SplitWidth1024x8_memGran_8_libGran_1_rw extends MacroCompilerSpec with Has compileExecuteAndTest(mem, lib, v, output) } -class SplitWidth1024x16_memGran_8_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x16_memGran_8_libGran_1_rw + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 16 override lazy val libWidth = 8 @@ -288,7 +295,10 @@ class SplitWidth1024x16_memGran_8_libGran_1_rw extends MacroCompilerSpec with Ha compileExecuteAndTest(mem, lib, v, output) } -class SplitWidth1024x16_memGran_8_libGran_8_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x16_memGran_8_libGran_8_rw + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 16 override lazy val libWidth = 8 @@ -298,7 +308,10 @@ class SplitWidth1024x16_memGran_8_libGran_8_rw extends MacroCompilerSpec with Ha compileExecuteAndTest(mem, lib, v, output) } -class SplitWidth1024x128_memGran_8_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x128_memGran_8_libGran_1_rw + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 128 override lazy val libWidth = 32 @@ -308,7 +321,10 @@ class SplitWidth1024x128_memGran_8_libGran_1_rw extends MacroCompilerSpec with H compileExecuteAndTest(mem, lib, v, output) } -class SplitWidth1024x16_memGran_4_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x16_memGran_4_libGran_1_rw + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 16 override lazy val libWidth = 8 @@ -318,7 +334,10 @@ class SplitWidth1024x16_memGran_4_libGran_1_rw extends MacroCompilerSpec with Ha compileExecuteAndTest(mem, lib, v, output) } -class SplitWidth1024x16_memGran_2_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x16_memGran_2_libGran_1_rw + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 16 override lazy val libWidth = 8 @@ -328,7 +347,10 @@ class SplitWidth1024x16_memGran_2_libGran_1_rw extends MacroCompilerSpec with Ha compileExecuteAndTest(mem, lib, v, output) } -class SplitWidth1024x16_memGran_16_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x16_memGran_16_libGran_1_rw + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 16 override lazy val libWidth = 8 @@ -360,7 +382,10 @@ class SplitWidth1024x16_libGran_1_rw extends MacroCompilerSpec with HasSRAMGener // Non-memMask and non-1 libMask -class SplitWidth1024x16_memGran_8_libGran_2_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x16_memGran_8_libGran_2_rw + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 16 override lazy val libWidth = 8 @@ -372,21 +397,27 @@ class SplitWidth1024x16_memGran_8_libGran_2_rw extends MacroCompilerSpec with Ha // Non-power of two memGran -class SplitWidth1024x16_memGran_9_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x16_memGran_9_libGran_1_rw + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { override lazy val depth = BigInt(1024) override lazy val memWidth = 16 override lazy val libWidth = 8 override lazy val memMaskGran = Some(9) override lazy val libMaskGran = Some(1) - it should "be enabled when non-power of two masks are supported" is (pending) + (it should "be enabled when non-power of two masks are supported").is(pending) //~ compile(mem, lib, v, false) //~ execute(mem, lib, false, output) } // Read enable -class SplitWidth1024x32_readEnable_Lib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x32_readEnable_Lib + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { import mdf.macrolib._ override lazy val depth = BigInt(1024) @@ -395,20 +426,27 @@ class SplitWidth1024x32_readEnable_Lib extends MacroCompilerSpec with HasSRAMGen override def generateLibSRAM() = { SRAMMacro( - name=lib_name, - width=libWidth, - depth=libDepth, - family="1rw", - ports=Seq(generateTestPort( - "lib", Some(libWidth), Some(libDepth), maskGran=libMaskGran, - write=true, writeEnable=true, - read=true, readEnable=true - )) + name = lib_name, + width = libWidth, + depth = libDepth, + family = "1rw", + ports = Seq( + generateTestPort( + "lib", + Some(libWidth), + Some(libDepth), + maskGran = libMaskGran, + write = true, + writeEnable = true, + read = true, + readEnable = true + ) + ) ) } override def generateBody() = -""" + """ inst mem_0_0 of awesome_lib_mem inst mem_0_1 of awesome_lib_mem inst mem_0_2 of awesome_lib_mem @@ -444,7 +482,10 @@ class SplitWidth1024x32_readEnable_Lib extends MacroCompilerSpec with HasSRAMGen compileExecuteAndTest(mem, lib, v, output) } -class SplitWidth1024x32_readEnable_Mem extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x32_readEnable_Mem + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { import mdf.macrolib._ override lazy val depth = BigInt(1024) @@ -453,15 +494,22 @@ class SplitWidth1024x32_readEnable_Mem extends MacroCompilerSpec with HasSRAMGen override def generateMemSRAM() = { SRAMMacro( - name=mem_name, - width=memWidth, - depth=memDepth, - family="1rw", - ports=Seq(generateTestPort( - "outer", Some(memWidth), Some(memDepth), maskGran=memMaskGran, - write=true, writeEnable=true, - read=true, readEnable=true - )) + name = mem_name, + width = memWidth, + depth = memDepth, + family = "1rw", + ports = Seq( + generateTestPort( + "outer", + Some(memWidth), + Some(memDepth), + maskGran = memMaskGran, + write = true, + writeEnable = true, + read = true, + readEnable = true + ) + ) ) } @@ -470,7 +518,10 @@ class SplitWidth1024x32_readEnable_Mem extends MacroCompilerSpec with HasSRAMGen compileExecuteAndTest(mem, lib, v, output) } -class SplitWidth1024x32_readEnable_LibMem extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator { +class SplitWidth1024x32_readEnable_LibMem + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator { import mdf.macrolib._ override lazy val depth = BigInt(1024) @@ -479,34 +530,48 @@ class SplitWidth1024x32_readEnable_LibMem extends MacroCompilerSpec with HasSRAM override def generateLibSRAM() = { SRAMMacro( - name=lib_name, - width=libWidth, - depth=libDepth, - family="1rw", - ports=Seq(generateTestPort( - "lib", Some(libWidth), Some(libDepth), maskGran=libMaskGran, - write=true, writeEnable=true, - read=true, readEnable=true - )) + name = lib_name, + width = libWidth, + depth = libDepth, + family = "1rw", + ports = Seq( + generateTestPort( + "lib", + Some(libWidth), + Some(libDepth), + maskGran = libMaskGran, + write = true, + writeEnable = true, + read = true, + readEnable = true + ) + ) ) } override def generateMemSRAM() = { SRAMMacro( - name=mem_name, - width=memWidth, - depth=memDepth, - family="1rw", - ports=Seq(generateTestPort( - "outer", Some(memWidth), Some(memDepth), maskGran=memMaskGran, - write=true, writeEnable=true, - read=true, readEnable=true - )) + name = mem_name, + width = memWidth, + depth = memDepth, + family = "1rw", + ports = Seq( + generateTestPort( + "outer", + Some(memWidth), + Some(memDepth), + maskGran = memMaskGran, + write = true, + writeEnable = true, + read = true, + readEnable = true + ) + ) ) } override def generateBody() = -""" + """ inst mem_0_0 of awesome_lib_mem inst mem_0_1 of awesome_lib_mem inst mem_0_2 of awesome_lib_mem diff --git a/macros/src/test/scala/barstools/macros/SpecificExamples.scala b/macros/src/test/scala/barstools/macros/SpecificExamples.scala index e41932bb..334e3a73 100644 --- a/macros/src/test/scala/barstools/macros/SpecificExamples.scala +++ b/macros/src/test/scala/barstools/macros/SpecificExamples.scala @@ -29,8 +29,8 @@ class WriteEnableTest extends MacroCompilerSpec with HasSRAMGenerator { override val libPrefix = "macros/src/test/resources" - val memSRAMs = mdf.macrolib.Utils.readMDFFromString( -""" + val memSRAMs = mdf.macrolib.Utils + .readMDFFromString(""" [ { "type" : "sram", "name" : "cc_banks_0_ext", @@ -58,7 +58,7 @@ class WriteEnableTest extends MacroCompilerSpec with HasSRAMGenerator { writeToMem(mem, memSRAMs) val output = -""" + """ circuit cc_banks_0_ext : module cc_banks_0_ext : input RW0_addr : UInt<12> @@ -99,8 +99,8 @@ class MaskPortTest extends MacroCompilerSpec with HasSRAMGenerator { override val libPrefix = "macros/src/test/resources" - val memSRAMs = mdf.macrolib.Utils.readMDFFromString( -""" + val memSRAMs = mdf.macrolib.Utils + .readMDFFromString(""" [ { "type" : "sram", "name" : "cc_dir_ext", @@ -131,7 +131,7 @@ class MaskPortTest extends MacroCompilerSpec with HasSRAMGenerator { writeToMem(mem, memSRAMs) val output = -""" + """ circuit cc_dir_ext : module cc_dir_ext : input RW0_addr : UInt<9> @@ -183,8 +183,8 @@ class BOOMTest extends MacroCompilerSpec with HasSRAMGenerator { override val libPrefix = "macros/src/test/resources" - val memSRAMs = mdf.macrolib.Utils.readMDFFromString( -""" + val memSRAMs = mdf.macrolib.Utils + .readMDFFromString(""" [ { "type" : "sram", "name" : "_T_182_ext", @@ -354,7 +354,7 @@ class BOOMTest extends MacroCompilerSpec with HasSRAMGenerator { writeToMem(mem, memSRAMs) val output = // TODO: check correctness... -""" + """ circuit smem_0_ext : module _T_182_ext : input R0_addr : UInt<6> @@ -1350,14 +1350,14 @@ circuit smem_0_ext : class SmallTagArrayTest extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleTestGenerator { // Test that mapping a smaller memory using a larger lib can still work. - override def memWidth: Int = 26 - override def memDepth: BigInt = BigInt(2) - override def memMaskGran: Option[Int] = Some(26) + override def memWidth: Int = 26 + override def memDepth: BigInt = BigInt(2) + override def memMaskGran: Option[Int] = Some(26) override def memPortPrefix: String = "" - override def libWidth: Int = 32 - override def libDepth: BigInt = BigInt(64) - override def libMaskGran: Option[Int] = Some(1) + override def libWidth: Int = 32 + override def libDepth: BigInt = BigInt(64) + override def libMaskGran: Option[Int] = Some(1) override def libPortPrefix: String = "" override def extraPorts: Seq[MacroExtraPort] = Seq( @@ -1388,73 +1388,73 @@ class RocketChipTest extends MacroCompilerSpec with HasSRAMGenerator { val libSRAMs = Seq( SRAMMacro( - name="SRAM1RW1024x8", - depth=1024, - width=8, - family="1rw", - ports=Seq( + name = "SRAM1RW1024x8", + depth = 1024, + width = 8, + family = "1rw", + ports = Seq( generateReadWritePort("", 8, BigInt(1024)) ) ), SRAMMacro( - name="SRAM1RW512x32", - depth=512, - width=32, - family="1rw", - ports=Seq( + name = "SRAM1RW512x32", + depth = 512, + width = 32, + family = "1rw", + ports = Seq( generateReadWritePort("", 32, BigInt(512)) ) ), SRAMMacro( - name="SRAM1RW64x128", - depth=64, - width=128, - family="1rw", - ports=Seq( + name = "SRAM1RW64x128", + depth = 64, + width = 128, + family = "1rw", + ports = Seq( generateReadWritePort("", 128, BigInt(64)) ) ), SRAMMacro( - name="SRAM1RW64x32", - depth=64, - width=32, - family="1rw", - ports=Seq( + name = "SRAM1RW64x32", + depth = 64, + width = 32, + family = "1rw", + ports = Seq( generateReadWritePort("", 32, BigInt(64)) ) ), SRAMMacro( - name="SRAM1RW64x8", - depth=64, - width=8, - family="1rw", - ports=Seq( + name = "SRAM1RW64x8", + depth = 64, + width = 8, + family = "1rw", + ports = Seq( generateReadWritePort("", 8, BigInt(64)) ) ), SRAMMacro( - name="SRAM1RW512x8", - depth=512, - width=8, - family="1rw", - ports=Seq( + name = "SRAM1RW512x8", + depth = 512, + width = 8, + family = "1rw", + ports = Seq( generateReadWritePort("", 8, BigInt(512)) ) ), SRAMMacro( - name="SRAM2RW64x32", - depth=64, - width=32, - family="1r1w", - ports=Seq( + name = "SRAM2RW64x32", + depth = 64, + width = 32, + family = "1r1w", + ports = Seq( generateReadPort("portA", 32, BigInt(64)), generateWritePort("portB", 32, BigInt(64)) ) ) ) - val memSRAMs = mdf.macrolib.Utils.readMDFFromString( -""" + val memSRAMs = mdf.macrolib.Utils + .readMDFFromString(""" [ { "type": "sram", @@ -1537,7 +1537,7 @@ class RocketChipTest extends MacroCompilerSpec with HasSRAMGenerator { writeToMem(mem, memSRAMs) val output = // TODO: check correctness... -""" + """ circuit T_2172_ext : module tag_array_ext : input RW0_addr : UInt<6> diff --git a/macros/src/test/scala/barstools/macros/SynFlops.scala b/macros/src/test/scala/barstools/macros/SynFlops.scala index f12161a1..0d39220e 100644 --- a/macros/src/test/scala/barstools/macros/SynFlops.scala +++ b/macros/src/test/scala/barstools/macros/SynFlops.scala @@ -4,13 +4,13 @@ package barstools.macros trait HasSynFlopsTestGenerator extends HasSimpleTestGenerator { this: MacroCompilerSpec with HasSRAMGenerator => - def generateFlops: String = { -s""" + def generateFlops: String = { + s""" inst mem_0_0 of split_${lib_name} mem_0_0.${libPortPrefix}_clk <= ${libPortPrefix}_clk mem_0_0.${libPortPrefix}_addr <= ${libPortPrefix}_addr - node ${libPortPrefix}_dout_0_0 = bits(mem_0_0.${libPortPrefix}_dout, ${libWidth-1}, 0) - mem_0_0.${libPortPrefix}_din <= bits(${libPortPrefix}_din, ${libWidth-1}, 0) + node ${libPortPrefix}_dout_0_0 = bits(mem_0_0.${libPortPrefix}_dout, ${libWidth - 1}, 0) + mem_0_0.${libPortPrefix}_din <= bits(${libPortPrefix}_din, ${libWidth - 1}, 0) mem_0_0.${libPortPrefix}_write_en <= and(and(and(${libPortPrefix}_write_en, UInt<1>("h1")), UInt<1>("h1")), UInt<1>("h1")) node ${libPortPrefix}_dout_0 = ${libPortPrefix}_dout_0_0 ${libPortPrefix}_dout <= mux(UInt<1>("h1"), ${libPortPrefix}_dout_0, UInt<${libWidth}>("h0")) @@ -37,49 +37,66 @@ s""" ${libPortPrefix}_dout <= ram.RW_0.rdata ram.RW_0.wdata <= ${libPortPrefix}_din """ - } + } - // If there is no lib, put the flops definition into the body. - abstract override def generateBody = { - if (this.isInstanceOf[HasNoLibTestGenerator]) generateFlops else super.generateBody - } + // If there is no lib, put the flops definition into the body. + abstract override def generateBody = { + if (this.isInstanceOf[HasNoLibTestGenerator]) generateFlops else super.generateBody + } - // If there is no lib, don't generate a footer, since the flops definition - // will be in the body. - override def generateFooter = { - if (this.isInstanceOf[HasNoLibTestGenerator]) "" else -s""" + // If there is no lib, don't generate a footer, since the flops definition + // will be in the body. + override def generateFooter = { + if (this.isInstanceOf[HasNoLibTestGenerator]) "" + else + s""" module ${lib_name} : ${generateFooterPorts} ${generateFlops} """ - } + } } -class Synflops2048x8_noLib extends MacroCompilerSpec with HasSRAMGenerator with HasNoLibTestGenerator with HasSynFlopsTestGenerator { +class Synflops2048x8_noLib + extends MacroCompilerSpec + with HasSRAMGenerator + with HasNoLibTestGenerator + with HasSynFlopsTestGenerator { override lazy val memDepth = BigInt(2048) override lazy val memWidth = 8 compileExecuteAndTest(mem, None, v, output, true) } -class Synflops2048x16_noLib extends MacroCompilerSpec with HasSRAMGenerator with HasNoLibTestGenerator with HasSynFlopsTestGenerator { +class Synflops2048x16_noLib + extends MacroCompilerSpec + with HasSRAMGenerator + with HasNoLibTestGenerator + with HasSynFlopsTestGenerator { override lazy val memDepth = BigInt(2048) override lazy val memWidth = 16 compileExecuteAndTest(mem, None, v, output, true) } -class Synflops8192x16_noLib extends MacroCompilerSpec with HasSRAMGenerator with HasNoLibTestGenerator with HasSynFlopsTestGenerator { +class Synflops8192x16_noLib + extends MacroCompilerSpec + with HasSRAMGenerator + with HasNoLibTestGenerator + with HasSynFlopsTestGenerator { override lazy val memDepth = BigInt(8192) override lazy val memWidth = 16 compileExecuteAndTest(mem, None, v, output, true) } -class Synflops2048x16_depth_Lib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with HasSynFlopsTestGenerator { +class Synflops2048x16_depth_Lib + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with HasSynFlopsTestGenerator { override lazy val memDepth = BigInt(2048) override lazy val libDepth = BigInt(1024) override lazy val width = 16 @@ -87,7 +104,11 @@ class Synflops2048x16_depth_Lib extends MacroCompilerSpec with HasSRAMGenerator compileExecuteAndTest(mem, lib, v, output, true) } -class Synflops2048x64_width_Lib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator with HasSynFlopsTestGenerator { +class Synflops2048x64_width_Lib + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleWidthTestGenerator + with HasSynFlopsTestGenerator { override lazy val memWidth = 64 override lazy val libWidth = 8 override lazy val depth = BigInt(1024) @@ -95,7 +116,11 @@ class Synflops2048x64_width_Lib extends MacroCompilerSpec with HasSRAMGenerator compileExecuteAndTest(mem, lib, v, output, true) } -class Synflops_SplitPorts_Read_Write extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with HasSynFlopsTestGenerator { +class Synflops_SplitPorts_Read_Write + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with HasSynFlopsTestGenerator { import mdf.macrolib._ override lazy val memDepth = BigInt(2048) @@ -103,29 +128,29 @@ class Synflops_SplitPorts_Read_Write extends MacroCompilerSpec with HasSRAMGener override lazy val width = 8 override def generateLibSRAM = SRAMMacro( - name=lib_name, - width=width, - depth=libDepth, - family="1r1w", - ports=Seq( + name = lib_name, + width = width, + depth = libDepth, + family = "1r1w", + ports = Seq( generateReadPort("innerA", width, libDepth), generateWritePort("innerB", width, libDepth) ) ) override def generateMemSRAM = SRAMMacro( - name=mem_name, - width=width, - depth=memDepth, - family="1r1w", - ports=Seq( + name = mem_name, + width = width, + depth = memDepth, + family = "1r1w", + ports = Seq( generateReadPort("outerB", width, memDepth), generateWritePort("outerA", width, memDepth) ) ) override def generateHeader = -""" + """ circuit target_memory : module target_memory : input outerB_addr : UInt<11> @@ -138,7 +163,7 @@ circuit target_memory : """ override def generateBody = -""" + """ node outerB_addr_sel = bits(outerB_addr, 10, 10) reg outerB_addr_sel_reg : UInt<1>, outerB_clk with : reset => (UInt<1>("h0"), outerB_addr_sel_reg) @@ -166,7 +191,7 @@ circuit target_memory : """ override def generateFooterPorts = -""" + """ input innerA_addr : UInt<10> input innerA_clk : Clock output innerA_dout : UInt<8> @@ -177,7 +202,7 @@ circuit target_memory : """ override def generateFlops = -""" + """ inst mem_0_0 of split_awesome_lib_mem mem_0_0.innerB_clk <= innerB_clk mem_0_0.innerB_addr <= innerB_addr @@ -222,7 +247,11 @@ circuit target_memory : } } -class Synflops_SplitPorts_MaskedMem_Read_MaskedWrite extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with HasSynFlopsTestGenerator { +class Synflops_SplitPorts_MaskedMem_Read_MaskedWrite + extends MacroCompilerSpec + with HasSRAMGenerator + with HasSimpleDepthTestGenerator + with HasSynFlopsTestGenerator { import mdf.macrolib._ override lazy val memDepth = BigInt(2048) @@ -232,29 +261,29 @@ class Synflops_SplitPorts_MaskedMem_Read_MaskedWrite extends MacroCompilerSpec w override lazy val libMaskGran = Some(1) override def generateLibSRAM = SRAMMacro( - name=lib_name, - width=width, - depth=libDepth, - family="1r1w", - ports=Seq( + name = lib_name, + width = width, + depth = libDepth, + family = "1r1w", + ports = Seq( generateReadPort("innerA", width, libDepth), generateWritePort("innerB", width, libDepth, libMaskGran) ) ) override def generateMemSRAM = SRAMMacro( - name=mem_name, - width=width, - depth=memDepth, - family="1r1w", - ports=Seq( + name = mem_name, + width = width, + depth = memDepth, + family = "1r1w", + ports = Seq( generateReadPort("outerB", width, memDepth), generateWritePort("outerA", width, memDepth, memMaskGran) ) ) override def generateHeader = -""" + """ circuit target_memory : module target_memory : input outerB_addr : UInt<11> @@ -268,7 +297,7 @@ circuit target_memory : """ override def generateBody = -""" + """ node outerB_addr_sel = bits(outerB_addr, 10, 10) reg outerB_addr_sel_reg : UInt<1>, outerB_clk with : reset => (UInt<1>("h0"), outerB_addr_sel_reg) @@ -298,7 +327,7 @@ circuit target_memory : """ override def generateFooterPorts = -""" + """ input innerA_addr : UInt<10> input innerA_clk : Clock output innerA_dout : UInt<8> @@ -310,7 +339,7 @@ circuit target_memory : """ override def generateFlops = -""" + """ inst mem_0_0 of split_awesome_lib_mem inst mem_0_1 of split_awesome_lib_mem inst mem_0_2 of split_awesome_lib_mem From caa1467d8718e530d81b0747539d4280437205ec Mon Sep 17 00:00:00 2001 From: chick Date: Wed, 3 Feb 2021 17:51:30 -0800 Subject: [PATCH 5/8] Reformat all scala files in tapeout - Mostly this reformat comments and large argument lists to classes and methods --- .../transforms/AddSuffixToModuleNames.scala | 9 +- .../transforms/AvoidExtModuleCollisions.scala | 5 +- .../transforms/ConvertToExtModPass.scala | 5 +- .../tapeout/transforms/EnumerateModules.scala | 8 +- .../tapeout/transforms/Generate.scala | 96 +++++++++++-------- .../tapeout/transforms/ReParentCircuit.scala | 9 +- .../transforms/RemoveUnusedModules.scala | 20 ++-- .../tapeout/transforms/ResetInverter.scala | 13 ++- .../tapeout/transforms/retime/Retime.scala | 25 ++--- .../tapeout/transforms/utils/FileUtils.scala | 19 ++-- .../transforms/utils/LowerAnnotations.scala | 4 +- .../transforms/utils/ProgrammaticBundle.scala | 12 ++- .../transforms/utils/YamlHelpers.scala | 10 +- .../transforms/ResetInverterSpec.scala | 19 ++-- .../transforms/retime/RetimeSpec.scala | 44 +++++---- 15 files changed, 163 insertions(+), 135 deletions(-) diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala index 1e7eaa26..e2c5620d 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala @@ -9,8 +9,7 @@ import firrtl.ir._ import firrtl.stage.Forms import firrtl.stage.TransformManager.TransformDependency -case class KeepNameAnnotation(target: ModuleTarget) - extends SingleTargetAnnotation[ModuleTarget] { +case class KeepNameAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] { def duplicate(n: ModuleTarget) = this.copy(n) } @@ -21,8 +20,8 @@ case class ModuleNameSuffixAnnotation(target: CircuitTarget, suffix: String) class AddSuffixToModuleNames extends Transform with DependencyAPIMigration { - override def prerequisites: Seq[TransformDependency] = Forms.LowForm - override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized + override def prerequisites: Seq[TransformDependency] = Forms.LowForm + override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters override def invalidates(a: Transform): Boolean = false @@ -37,7 +36,7 @@ class AddSuffixToModuleNames extends Transform with DependencyAPIMigration { val excludeSet = state.circuit.modules.flatMap { case e: ExtModule => Some(e.name) case m if (m.name == state.circuit.main) => Some(m.name) - case _ => None + case _ => None }.toSet val renamer = { (name: String) => if (excludeSet(name)) name else name + suffix } diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala index 43aea6c1..127a37fa 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala @@ -14,7 +14,7 @@ case class LinkExtModulesAnnotation(mustLink: Seq[ExtModule]) extends NoTargetAn class AvoidExtModuleCollisions extends Transform with DependencyAPIMigration { - override def prerequisites: Seq[TransformDependency] = Forms.HighForm + override def prerequisites: Seq[TransformDependency] = Forms.HighForm override def optionalPrerequisites: Seq[TransformDependency] = Seq(Dependency[RemoveUnusedModules]) override def optionalPrerequisiteOf: Seq[TransformDependency] = { Forms.HighEmitters :+ Dependency[ReplSeqMem] @@ -24,10 +24,9 @@ class AvoidExtModuleCollisions extends Transform with DependencyAPIMigration { def execute(state: CircuitState): CircuitState = { val mustLink = state.annotations.flatMap { case LinkExtModulesAnnotation(mustLink) => mustLink - case _ => Nil + case _ => Nil } val newAnnos = state.annotations.filterNot(_.isInstanceOf[LinkExtModulesAnnotation]) state.copy(circuit = state.circuit.copy(modules = state.circuit.modules ++ mustLink), annotations = newAnnos) } } - diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala index e6d2272a..a81937a3 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala @@ -10,8 +10,7 @@ import firrtl.passes.memlib.ReplSeqMem import firrtl.stage.Forms import firrtl.stage.TransformManager.TransformDependency -case class ConvertToExtModAnnotation(target: ModuleTarget) - extends SingleTargetAnnotation[ModuleTarget] { +case class ConvertToExtModAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] { def duplicate(n: ModuleTarget) = this.copy(n) } @@ -20,7 +19,7 @@ case class ConvertToExtModAnnotation(target: ModuleTarget) // otherwise it's left alone. class ConvertToExtMod extends Transform with DependencyAPIMigration { - override def prerequisites: Seq[TransformDependency] = Forms.HighForm + override def prerequisites: Seq[TransformDependency] = Forms.HighForm override def optionalPrerequisites: Seq[TransformDependency] = Seq.empty override def optionalPrerequisiteOf: Seq[TransformDependency] = { Forms.HighEmitters ++ Seq(Dependency[RemoveUnusedModules], Dependency[ReplSeqMem]) diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala index 6a732d75..182b0071 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala @@ -23,10 +23,12 @@ class EnumerateModulesPass(enumerate: (Module) => Unit) extends Pass { } class EnumerateModules(enumerate: (Module) => Unit) - extends Transform with SeqTransformBased with DependencyAPIMigration { + extends Transform + with SeqTransformBased + with DependencyAPIMigration { - override def prerequisites: Seq[TransformDependency] = Forms.LowForm - override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized + override def prerequisites: Seq[TransformDependency] = Forms.LowForm + override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters override def invalidates(a: Transform): Boolean = false diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala index 5abb71c1..01ea56e0 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala @@ -13,130 +13,150 @@ trait HasTapeoutOptions { self: ExecutionOptionsManager with HasFirrtlOptions => parser.note("tapeout options") - parser.opt[String]("harness-o") + parser + .opt[String]("harness-o") .abbr("tho") .valueName("") .foreach { x => tapeoutOptions = tapeoutOptions.copy( harnessOutput = Some(x) ) - }.text { + } + .text { "use this to generate a harness at " } - parser.opt[String]("syn-top") + parser + .opt[String]("syn-top") .abbr("tst") .valueName("") .foreach { x => tapeoutOptions = tapeoutOptions.copy( synTop = Some(x) ) - }.text { + } + .text { "use this to set synTop" } - parser.opt[String]("top-fir") + parser + .opt[String]("top-fir") .abbr("tsf") .valueName("") .foreach { x => tapeoutOptions = tapeoutOptions.copy( topFir = Some(x) ) - }.text { + } + .text { "use this to set topFir" } - parser.opt[String]("top-anno-out") + parser + .opt[String]("top-anno-out") .abbr("tsaof") .valueName("") .foreach { x => tapeoutOptions = tapeoutOptions.copy( topAnnoOut = Some(x) ) - }.text { + } + .text { "use this to set topAnnoOut" } - parser.opt[String]("top-dotf-out") + parser + .opt[String]("top-dotf-out") .abbr("tdf") .valueName("") .foreach { x => tapeoutOptions = tapeoutOptions.copy( topDotfOut = Some(x) ) - }.text { + } + .text { "use this to set the filename for the top resource .f file" } - parser.opt[String]("harness-top") + parser + .opt[String]("harness-top") .abbr("tht") .valueName("") .foreach { x => tapeoutOptions = tapeoutOptions.copy( harnessTop = Some(x) ) - }.text { + } + .text { "use this to set harnessTop" } - parser.opt[String]("harness-fir") + parser + .opt[String]("harness-fir") .abbr("thf") .valueName("") .foreach { x => tapeoutOptions = tapeoutOptions.copy( harnessFir = Some(x) ) - }.text { + } + .text { "use this to set harnessFir" } - parser.opt[String]("harness-anno-out") + parser + .opt[String]("harness-anno-out") .abbr("thaof") .valueName("") .foreach { x => tapeoutOptions = tapeoutOptions.copy( harnessAnnoOut = Some(x) ) - }.text { + } + .text { "use this to set harnessAnnoOut" } - parser.opt[String]("harness-dotf-out") + parser + .opt[String]("harness-dotf-out") .abbr("hdf") .valueName("") .foreach { x => tapeoutOptions = tapeoutOptions.copy( harnessDotfOut = Some(x) ) - }.text { + } + .text { "use this to set the filename for the harness resource .f file" } - parser.opt[String]("harness-conf") + parser + .opt[String]("harness-conf") .abbr("thconf") - .valueName ("") + .valueName("") .foreach { x => tapeoutOptions = tapeoutOptions.copy( harnessConf = Some(x) ) - }.text { + } + .text { "use this to set the harness conf file location" } } case class TapeoutOptions( - harnessOutput: Option[String] = None, - synTop: Option[String] = None, - topFir: Option[String] = None, - topAnnoOut: Option[String] = None, - topDotfOut: Option[String] = None, - harnessTop: Option[String] = None, - harnessFir: Option[String] = None, + harnessOutput: Option[String] = None, + synTop: Option[String] = None, + topFir: Option[String] = None, + topAnnoOut: Option[String] = None, + topDotfOut: Option[String] = None, + harnessTop: Option[String] = None, + harnessFir: Option[String] = None, harnessAnnoOut: Option[String] = None, harnessDotfOut: Option[String] = None, - harnessConf: Option[String] = None -) extends LazyLogging + harnessConf: Option[String] = None) + extends LazyLogging // Requires two phases, one to collect modules below synTop in the hierarchy // and a second to remove those modules to generate the test harness @@ -190,9 +210,9 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App => annoFile.foreach { annoPath => val outputFile = new java.io.PrintWriter(annoPath) outputFile.write(JsonProtocol.serialize(res.circuitState.annotations.filter(_ match { - case da: DeletedAnnotation => false - case ec: EmittedComponent => false - case ea: EmittedAnnotation[_] => false + case da: DeletedAnnotation => false + case ec: EmittedComponent => false + case ea: EmittedAnnotation[_] => false case fca: FirrtlCircuitAnnotation => false case _ => true }))) @@ -207,7 +227,7 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App => result match { case x: FirrtlExecutionSuccess => dump(x, tapeoutOptions.topFir, tapeoutOptions.topAnnoOut) - x.circuitState.circuit.modules.collect{ case e: ExtModule => e } + x.circuitState.circuit.modules.collect { case e: ExtModule => e } case x => throw new Exception(s"executeTop failed while executing FIRRTL!\n${x}") } @@ -220,9 +240,9 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App => val harnessAnnos = tapeoutOptions.harnessDotfOut.map(BlackBoxResourceFileNameAnno(_)).toSeq ++ - harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++ - synTop.map(st => ConvertToExtModAnnotation(rootCircuitTarget.module(st))) :+ - LinkExtModulesAnnotation(topExtModules) + harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++ + synTop.map(st => ConvertToExtModAnnotation(rootCircuitTarget.module(st))) :+ + LinkExtModulesAnnotation(topExtModules) // For harness run, change some firrtlOptions (below) for harness phase // customTransforms: setup harness transforms, add AvoidExtModuleCollisions @@ -233,7 +253,7 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App => outputFileNameOverride = tapeoutOptions.harnessOutput.get, annotations = firrtlOptions.annotations.map({ case ReplSeqMemAnnotation(i, o) => ReplSeqMemAnnotation(i, tapeoutOptions.harnessConf.get) - case a => a + case a => a }) ++ harnessAnnos ) val harnessResult = firrtl.Driver.execute(optionsManager) diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala index f7929ee6..10356176 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala @@ -8,14 +8,13 @@ import firrtl.options.Dependency import firrtl.stage.Forms import firrtl.stage.TransformManager.TransformDependency -case class ReParentCircuitAnnotation(target: ModuleTarget) - extends SingleTargetAnnotation[ModuleTarget] { +case class ReParentCircuitAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] { def duplicate(n: ModuleTarget) = this.copy(n) } class ReParentCircuit extends Transform with DependencyAPIMigration { - override def prerequisites: Seq[TransformDependency] = Forms.HighForm + override def prerequisites: Seq[TransformDependency] = Forms.HighForm override def optionalPrerequisites: Seq[TransformDependency] = Seq.empty override def optionalPrerequisiteOf: Seq[TransformDependency] = { Forms.HighEmitters :+ Dependency[RemoveUnusedModules] @@ -24,8 +23,8 @@ class ReParentCircuit extends Transform with DependencyAPIMigration { def execute(state: CircuitState): CircuitState = { val c = state.circuit - val newTopName = state.annotations.collectFirst { - case ReParentCircuitAnnotation(tgt) => tgt.module + val newTopName = state.annotations.collectFirst { case ReParentCircuitAnnotation(tgt) => + tgt.module } val newCircuit = c.copy(main = newTopName.getOrElse(c.main)) val mainRename = newTopName.map { s => diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala index 7aac8978..5d1cbc6c 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala @@ -14,7 +14,7 @@ import firrtl.stage.TransformManager.TransformDependency // instance (starting at the main module) class RemoveUnusedModules extends Transform with DependencyAPIMigration { - override def prerequisites: Seq[TransformDependency] = Forms.HighForm + override def prerequisites: Seq[TransformDependency] = Forms.HighForm override def optionalPrerequisites: Seq[TransformDependency] = Seq.empty override def optionalPrerequisiteOf: Seq[TransformDependency] = { Forms.HighEmitters :+ Dependency[ReplSeqMem] @@ -22,8 +22,8 @@ class RemoveUnusedModules extends Transform with DependencyAPIMigration { override def invalidates(a: Transform): Boolean = false def execute(state: CircuitState): CircuitState = { - val modulesByName = state.circuit.modules.map{ - case m: Module => (m.name, Some(m)) + val modulesByName = state.circuit.modules.map { + case m: Module => (m.name, Some(m)) case m: ExtModule => (m.name, None) }.toMap @@ -33,7 +33,7 @@ class RemoveUnusedModules extends Transform with DependencyAPIMigration { def someStatements(statement: Statement): Seq[Statement] = statement match { case b: Block => - b.stmts.map{ someStatements(_) } + b.stmts.map { someStatements(_) } .foldLeft(Seq[Statement]())(_ ++ _) case when: Conditionally => someStatements(when.conseq) ++ someStatements(when.alt) @@ -41,11 +41,11 @@ class RemoveUnusedModules extends Transform with DependencyAPIMigration { case _ => Seq() } - someStatements(m.body).map{ - case s: DefInstance => Set(s.module) | getUsedModules(modulesByName(s.module)) - case _ => Set[String]() - }.foldLeft(Set(m.name))(_ | _) - } + someStatements(m.body).map { + case s: DefInstance => Set(s.module) | getUsedModules(modulesByName(s.module)) + case _ => Set[String]() + }.foldLeft(Set(m.name))(_ | _) + } case None => Set.empty[String] } @@ -57,7 +57,7 @@ class RemoveUnusedModules extends Transform with DependencyAPIMigration { val renames = state.renames.getOrElse(RenameMap()) - state.circuit.modules.filterNot { usedModuleSet contains _.name } foreach { x => + state.circuit.modules.filterNot { usedModuleSet contains _.name }.foreach { x => renames.record(ModuleTarget(state.circuit.main, x.name), Nil) } diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala index 1ccb1888..33d2f78a 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala @@ -20,10 +20,9 @@ object ResetN extends Pass { // Only works on Modules with a Bool port named reset def invertReset(mod: Module): Module = { // Check that it actually has reset - require(mod.ports.exists(p => p.name == "reset" && p.tpe == Bool), - "Can only invert reset on a module with reset!") + require(mod.ports.exists(p => p.name == "reset" && p.tpe == Bool), "Can only invert reset on a module with reset!") // Rename "reset" to "reset_n" - val portsx = mod.ports map { + val portsx = mod.ports.map { case Port(info, "reset", Input, Bool) => Port(info, "reset_n", Input, Bool) case other => other @@ -34,7 +33,7 @@ object ResetN extends Pass { } def run(c: Circuit): Circuit = { - c.copy(modules = c.modules map { + c.copy(modules = c.modules.map { case mod: Module if mod.name == c.main => invertReset(mod) case other => other }) @@ -43,8 +42,8 @@ object ResetN extends Pass { class ResetInverterTransform extends Transform with DependencyAPIMigration { - override def prerequisites: Seq[TransformDependency] = Forms.LowForm - override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized + override def prerequisites: Seq[TransformDependency] = Forms.LowForm + override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters override def invalidates(a: Transform): Boolean = false @@ -64,7 +63,7 @@ trait ResetInverter { def invert[T <: chisel3.internal.LegacyModule](module: T): Unit = { chisel3.experimental.annotate(new chisel3.experimental.ChiselAnnotation with RunFirrtlTransform { def transformClass: Class[_ <: Transform] = classOf[ResetInverterTransform] - def toFirrtl: Annotation = ResetInverterAnnotation(module.toNamed) + def toFirrtl: Annotation = ResetInverterAnnotation(module.toNamed) }) } } diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala index 010ef40b..931af88d 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala @@ -14,23 +14,24 @@ case class RetimeAnnotation(target: Named) extends SingleTargetAnnotation[Named] class RetimeTransform extends Transform with DependencyAPIMigration { - override def prerequisites: Seq[TransformDependency] = Forms.LowForm - override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized + override def prerequisites: Seq[TransformDependency] = Forms.LowForm + override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters override def invalidates(a: Transform): Boolean = false override def execute(state: CircuitState): CircuitState = { state.annotations.filter(_.isInstanceOf[RetimeAnnotation]) match { case Nil => state - case seq => seq.foreach { - case RetimeAnnotation(ModuleName(module, CircuitName(_))) => - logger.info(s"Retiming module $module") - case RetimeAnnotation(ComponentName(name, ModuleName(module, CircuitName(_)))) => - logger.info(s"Retiming instance $module.$name") - case _ => - throw new Exception(s"There should be RetimeAnnotations, got ${seq.mkString(" -- ")}") - } - state + case seq => + seq.foreach { + case RetimeAnnotation(ModuleName(module, CircuitName(_))) => + logger.info(s"Retiming module $module") + case RetimeAnnotation(ComponentName(name, ModuleName(module, CircuitName(_)))) => + logger.info(s"Retiming instance $module.$name") + case _ => + throw new Exception(s"There should be RetimeAnnotations, got ${seq.mkString(" -- ")}") + } + state } } } @@ -41,7 +42,7 @@ trait RetimeLib { def retime[T <: chisel3.internal.LegacyModule](module: T): Unit = { chisel3.experimental.annotate(new chisel3.experimental.ChiselAnnotation with RunFirrtlTransform { def transformClass: Class[_ <: Transform] = classOf[RetimeTransform] - def toFirrtl: Annotation = RetimeAnnotation(module.toNamed) + def toFirrtl: Annotation = RetimeAnnotation(module.toNamed) }) } } diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala index ded0474d..6e79b7e5 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala @@ -2,7 +2,7 @@ package barstools.tapeout.transforms -import chisel3.experimental.{ChiselAnnotation, annotate} +import chisel3.experimental.{annotate, ChiselAnnotation} import firrtl._ import firrtl.annotations._ import firrtl.stage.Forms @@ -12,7 +12,7 @@ import firrtl.transforms.BlackBoxTargetDirAnno object WriteConfig { def apply(dir: String, file: String, contents: String): Unit = { val writer = new java.io.PrintWriter(new java.io.File(s"$dir/$file")) - writer write contents + writer.write(contents) writer.close() } } @@ -22,14 +22,14 @@ object GetTargetDir { val annos = state.annotations val destDir = annos.map { case BlackBoxTargetDirAnno(s) => Some(s) - case _ => None + case _ => None }.flatten val loc = { if (destDir.isEmpty) "." else destDir.head } val targetDir = new java.io.File(loc) - if(!targetDir.exists()) FileUtils.makeDirectory(targetDir.getAbsolutePath) + if (!targetDir.exists()) FileUtils.makeDirectory(targetDir.getAbsolutePath) loc } } @@ -53,8 +53,8 @@ case class TechnologyLocationAnnotation(dir: String) extends SingleTargetAnnotat class TechnologyLocation extends Transform with DependencyAPIMigration { - override def prerequisites: Seq[TransformDependency] = Forms.LowForm - override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized + override def prerequisites: Seq[TransformDependency] = Forms.LowForm + override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters def execute(state: CircuitState): CircuitState = { @@ -65,18 +65,15 @@ class TechnologyLocation extends Transform with DependencyAPIMigration { val annos = state.annotations val dir = annos.flatMap { case TechnologyLocationAnnotation(dir) => Some(dir) - case _ => None + case _ => None } dir.length match { case 0 => "" case 1 => val targetDir = new java.io.File(dir.head) - if(!targetDir.exists()) throw new Exception(s"Technology yaml directory $targetDir doesn't exist!") + if (!targetDir.exists()) throw new Exception(s"Technology yaml directory $targetDir doesn't exist!") dir.head case _ => throw new Exception("Only 1 tech directory annotation allowed!") } } } - - - diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala index a11bfa19..1f628900 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala @@ -1,5 +1,5 @@ package barstools.tapeout.transforms object LowerName { - def apply(s: String): String = s.replace(".", "_").replace("[", "_")replace("]", "") -} \ No newline at end of file + def apply(s: String): String = s.replace(".", "_").replace("[", "_").replace("]", "") +} diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala index d73d05db..8025439c 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala @@ -4,17 +4,17 @@ import chisel3._ import scala.collection.immutable.ListMap class CustomBundle[T <: Data](elts: (String, T)*) extends Record { - val elements = ListMap(elts map { case (field, elt) => field -> chiselTypeOf(elt) }: _*) + val elements = ListMap(elts.map { case (field, elt) => field -> chiselTypeOf(elt) }: _*) def apply(elt: String): T = elements(elt) - def apply(elt: Int): T = elements(elt.toString) + def apply(elt: Int): T = elements(elt.toString) override def cloneType = (new CustomBundle(elements.toList: _*)).asInstanceOf[this.type] } class CustomIndexedBundle[T <: Data](elts: (Int, T)*) extends Record { // Must be String, Data - val elements = ListMap(elts map { case (field, elt) => field.toString -> chiselTypeOf(elt) }: _*) + val elements = ListMap(elts.map { case (field, elt) => field.toString -> chiselTypeOf(elt) }: _*) // TODO: Make an equivalent to the below work publicly (or only on subclasses?) - def indexedElements = ListMap(elts map { case (field, elt) => field -> chiselTypeOf(elt) }: _*) + def indexedElements = ListMap(elts.map { case (field, elt) => field -> chiselTypeOf(elt) }: _*) def apply(elt: Int): T = elements(elt.toString) override def cloneType = (new CustomIndexedBundle(indexedElements.toList: _*)).asInstanceOf[this.type] } @@ -22,5 +22,7 @@ class CustomIndexedBundle[T <: Data](elts: (Int, T)*) extends Record { object CustomIndexedBundle { def apply[T <: Data](gen: T, idxs: Seq[Int]) = new CustomIndexedBundle(idxs.map(_ -> gen): _*) // Allows Vecs of elements of different types/widths - def apply[T <: Data](gen: Seq[T]) = new CustomIndexedBundle(gen.zipWithIndex.map{ case (elt, field) => field -> elt }: _*) + def apply[T <: Data](gen: Seq[T]) = new CustomIndexedBundle(gen.zipWithIndex.map { case (elt, field) => + field -> elt + }: _*) } diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala index 6754136d..75b0c330 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala @@ -4,18 +4,18 @@ import net.jcazevedo.moultingyaml._ import java.io.File class YamlFileReader(resource: String) { - def parse[A](file: String = "")(implicit reader: YamlReader[A]) : Seq[A] = { + def parse[A](file: String = "")(implicit reader: YamlReader[A]): Seq[A] = { // If the user doesn't provide a Yaml file name, use defaults val yamlString = file match { - case f if f.isEmpty => + case f if f.isEmpty => // Use example config if no file is provided val stream = getClass.getResourceAsStream(resource) io.Source.fromInputStream(stream).mkString - case f if new File(f).exists => + case f if new File(f).exists => scala.io.Source.fromFile(f).getLines.mkString("\n") - case _ => + case _ => throw new Exception("No valid Yaml file found!") } yamlString.parseYamls.map(x => reader.read(x)) } -} \ No newline at end of file +} diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala index 9a0a1f6d..d74360b7 100644 --- a/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala @@ -29,14 +29,17 @@ class ResetNSpec extends FreeSpec with Matchers { "Inverting reset needs to be done throughout module when generating firrtl" in { // generate low-firrtl - val firrtl = (new ChiselStage).execute( - Array("-X", "low"), - Seq(ChiselGeneratorAnnotation(() => new ExampleModuleNeedsResetInverted)) - ).collect { - case EmittedFirrtlCircuitAnnotation(a) => a - case EmittedFirrtlModuleAnnotation(a) => a - }.map(_.value) - .mkString("") + val firrtl = (new ChiselStage) + .execute( + Array("-X", "low"), + Seq(ChiselGeneratorAnnotation(() => new ExampleModuleNeedsResetInverted)) + ) + .collect { + case EmittedFirrtlCircuitAnnotation(a) => a + case EmittedFirrtlModuleAnnotation(a) => a + } + .map(_.value) + .mkString("") firrtl should include("input reset_n :") firrtl should include("node reset = not(reset_n)") diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala index d5168292..0e164521 100644 --- a/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala @@ -19,18 +19,20 @@ class RetimeSpec extends FlatSpec with Matchers { } def getLowFirrtl[T <: RawModule](gen: () => T, extraArgs: Array[String] = Array.empty): String = { // generate low firrtl - (new ChiselStage).execute( - Array("-X", "low") ++ extraArgs, - Seq(ChiselGeneratorAnnotation(gen)) - ).collect { - case EmittedFirrtlCircuitAnnotation(a) => a - case EmittedFirrtlModuleAnnotation(a) => a - }.map(_.value) - .mkString("") + (new ChiselStage) + .execute( + Array("-X", "low") ++ extraArgs, + Seq(ChiselGeneratorAnnotation(gen)) + ) + .collect { + case EmittedFirrtlCircuitAnnotation(a) => a + case EmittedFirrtlModuleAnnotation(a) => a + } + .map(_.value) + .mkString("") } - - behavior of "retime library" + behavior.of("retime library") it should "pass simple retime module annotation" in { val gen = () => new RetimeModule @@ -41,15 +43,18 @@ class RetimeSpec extends FlatSpec with Matchers { Logger.setOutput(captor.printStream) // generate low firrtl - val firrtl = getLowFirrtl(gen, - Array("-td", s"test_run_dir/$dir", "-foaf", s"test_run_dir/$dir/final", "--log-level", "info")) + val firrtl = getLowFirrtl( + gen, + Array("-td", s"test_run_dir/$dir", "-foaf", s"test_run_dir/$dir/final", "--log-level", "info") + ) firrtl.nonEmpty should be(true) //Make sure we got the RetimeTransform scheduled - captor.getOutputAsString should include ("barstools.tapeout.transforms.retime.RetimeTransform") + captor.getOutputAsString should include("barstools.tapeout.transforms.retime.RetimeTransform") } - val lines = FileUtils.getLines(s"test_run_dir/$dir/test_run_dir/$dir/final.anno.json") + val lines = FileUtils + .getLines(s"test_run_dir/$dir/test_run_dir/$dir/final.anno.json") .map(normalized) .mkString("\n") lines should include("barstools.tapeout.transforms.retime.RetimeAnnotation") @@ -65,15 +70,18 @@ class RetimeSpec extends FlatSpec with Matchers { Logger.setOutput(captor.printStream) // generate low firrtl - val firrtl = getLowFirrtl(gen, - Array("-td", s"test_run_dir/$dir", "-foaf", s"test_run_dir/$dir/final", "--log-level", "info")) + val firrtl = getLowFirrtl( + gen, + Array("-td", s"test_run_dir/$dir", "-foaf", s"test_run_dir/$dir/final", "--log-level", "info") + ) firrtl.nonEmpty should be(true) //Make sure we got the RetimeTransform scheduled - captor.getOutputAsString should include ("barstools.tapeout.transforms.retime.RetimeTransform") + captor.getOutputAsString should include("barstools.tapeout.transforms.retime.RetimeTransform") } - val lines = FileUtils.getLines(s"test_run_dir/$dir/test_run_dir/$dir/final.anno.json") + val lines = FileUtils + .getLines(s"test_run_dir/$dir/test_run_dir/$dir/final.anno.json") .map(normalized) .mkString("\n") lines should include("barstools.tapeout.transforms.retime.RetimeAnnotation") From d9d9d0fbb520c53f8be06dba33fd942de7ce0e57 Mon Sep 17 00:00:00 2001 From: chick Date: Wed, 3 Feb 2021 21:03:22 -0800 Subject: [PATCH 6/8] Move to scalatest 3.2 Requires updating to AnyFlatSpec where used And different import for Matchers --- build.sbt | 8 ++------ .../test/scala/barstools/macros/MacroCompilerSpec.scala | 4 +++- .../barstools/tapeout/transforms/ResetInverterSpec.scala | 5 +++-- .../barstools/tapeout/transforms/retime/RetimeSpec.scala | 5 +++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/build.sbt b/build.sbt index fd9638b1..83a5f93f 100644 --- a/build.sbt +++ b/build.sbt @@ -13,9 +13,8 @@ lazy val commonSettings = Seq( libraryDependencies ++= Seq("chisel3","chisel-iotesters").map { dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) }, - libraryDependencies in Test ++= Seq( - "org.scalatest" %% "scalatest" % "2.2.5" % "test", - "org.scalacheck" %% "scalacheck" % "1.12.4" % "test" + libraryDependencies ++= Seq( + "org.scalatest" %% "scalatest" % "3.2.2" % "test", ), resolvers ++= Seq( Resolver.sonatypeRepo("snapshots"), @@ -31,9 +30,6 @@ lazy val macros = (project in file("macros")) .dependsOn(mdf) .settings(commonSettings) .settings( - libraryDependencies ++= Seq( - "edu.berkeley.cs" %% "firrtl-interpreter" % "1.4.+" % Test - ), mainClass := Some("barstools.macros.MacroCompiler") ) .enablePlugins(sbtassembly.AssemblyPlugin) diff --git a/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala b/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala index 9140ce24..2b239227 100644 --- a/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala +++ b/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala @@ -6,10 +6,12 @@ import firrtl.Parser.parse import firrtl.ir.{Circuit, NoInfo} import firrtl.passes.RemoveEmpty import mdf.macrolib.SRAMMacro +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers import java.io.File -abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalatest.Matchers { +abstract class MacroCompilerSpec extends AnyFlatSpec with Matchers { import scala.language.implicitConversions implicit def String2SomeString(i: String): Option[String] = Some(i) val testDir: String = "test_run_dir/macros" diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala index d74360b7..701c7845 100644 --- a/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala @@ -5,7 +5,8 @@ package barstools.tapeout.transforms import chisel3._ import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import firrtl.{EmittedFirrtlCircuitAnnotation, EmittedFirrtlModuleAnnotation} -import org.scalatest.{FreeSpec, Matchers} +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers class ExampleModuleNeedsResetInverted extends Module with ResetInverter { val io = IO(new Bundle { @@ -19,7 +20,7 @@ class ExampleModuleNeedsResetInverted extends Module with ResetInverter { invert(this) } -class ResetNSpec extends FreeSpec with Matchers { +class ResetNSpec extends AnyFreeSpec with Matchers { "Inverting reset needs to be done throughout module in Chirrtl" in { val chirrtl = (new ChiselStage).emitChirrtl(new ExampleModuleNeedsResetInverted) chirrtl should include("input reset :") diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala index 0e164521..a086b0b9 100644 --- a/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala @@ -6,9 +6,10 @@ import chisel3._ import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import firrtl.{EmittedFirrtlCircuitAnnotation, EmittedFirrtlModuleAnnotation, FileUtils} import logger.Logger -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class RetimeSpec extends FlatSpec with Matchers { +class RetimeSpec extends AnyFlatSpec with Matchers { def normalized(s: String): String = { require(!s.contains("\n")) s.replaceAll("\\s+", " ").trim From ca4013b830bee30041a81b3916d7785180fb0b82 Mon Sep 17 00:00:00 2001 From: chick Date: Mon, 8 Feb 2021 09:09:19 -0800 Subject: [PATCH 7/8] Remove deprecated Driver stuff macros package - Fix name reference and weird .get.get in CostMetric - Update to DependencyAPIMigration - MacroCompilerTransform - MacroCompilerOptimizations - Delete unused class MacroCompiler - Remove use of ExecutionOptionsManager in object MacroCompiler - Removed stack trace when no arguments from CLI, just give message requiring args - Update version to 0.4-SNAPSHOT --- build.sbt | 2 +- .../scala/barstools/macros/CostMetric.scala | 4 +- .../barstools/macros/MacroCompiler.scala | 63 +++++++++---------- 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/build.sbt b/build.sbt index 83a5f93f..d8840865 100644 --- a/build.sbt +++ b/build.sbt @@ -7,7 +7,7 @@ val defaultVersions = Map( lazy val commonSettings = Seq( organization := "edu.berkeley.cs", - version := "0.1-SNAPSHOT", + version := "0.4-SNAPSHOT", scalaVersion := "2.12.10", scalacOptions := Seq("-deprecation", "-feature", "-language:reflectiveCalls", "-Xsource:2.11"), libraryDependencies ++= Seq("chisel3","chisel-iotesters").map { diff --git a/macros/src/main/scala/barstools/macros/CostMetric.scala b/macros/src/main/scala/barstools/macros/CostMetric.scala index f39303d3..3b9de124 100644 --- a/macros/src/main/scala/barstools/macros/CostMetric.scala +++ b/macros/src/main/scala/barstools/macros/CostMetric.scala @@ -186,7 +186,7 @@ object CostMetric { * the metric. */ def registerCostMetric(createFuncHelper: CostMetricCompanion): Unit = { - costMetricCreators.update(createFuncHelper.name, createFuncHelper) + costMetricCreators.update(createFuncHelper.name(), createFuncHelper) } /** Select a cost metric from string. */ @@ -196,7 +196,7 @@ object CostMetric { } else if (!costMetricCreators.contains(m)) { throw new IllegalArgumentException("Invalid cost metric " + m) } else { - costMetricCreators.get(m).get.construct(params) + costMetricCreators(m).construct(params) } } } diff --git a/macros/src/main/scala/barstools/macros/MacroCompiler.scala b/macros/src/main/scala/barstools/macros/MacroCompiler.scala index 5ecfea8f..bfcf78da 100644 --- a/macros/src/main/scala/barstools/macros/MacroCompiler.scala +++ b/macros/src/main/scala/barstools/macros/MacroCompiler.scala @@ -8,10 +8,11 @@ package barstools.macros import barstools.macros.Utils._ -import firrtl.CompilerUtils.getLoweringTransforms import firrtl.Utils._ import firrtl.annotations._ import firrtl.ir._ +import firrtl.stage.{FirrtlSourceAnnotation, FirrtlStage, Forms, OutputFileAnnotation, RunFirrtlTransformAnnotation} +import firrtl.transforms.NoDCEAnnotation import firrtl.{PrimOps, _} import mdf.macrolib._ @@ -692,9 +693,11 @@ class MacroCompilerPass( } } -class MacroCompilerTransform extends Transform { - def inputForm = MidForm - def outputForm = MidForm +class MacroCompilerTransform extends Transform with DependencyAPIMigration { + override def prerequisites = Forms.LowForm + override def optionalPrerequisites = Forms.LowFormOptimized + override def optionalPrerequisiteOf = Forms.LowEmitters + override def invalidates(a: Transform) = false def execute(state: CircuitState) = state.annotations.collect { case a: MacroCompilerAnnotation => a } match { case Seq(anno: MacroCompilerAnnotation) => @@ -764,16 +767,16 @@ class MacroCompilerTransform extends Transform { }) ) ) - (transforms.foldLeft(state))((s, xform) => xform.runTransform(s)).copy(form = outputForm) + (transforms.foldLeft(state))((s, xform) => xform.runTransform(s)) case _ => state } } -// FIXME: Use firrtl.LowerFirrtlOptimizations -class MacroCompilerOptimizations extends SeqTransform { - def inputForm: CircuitForm = LowForm - - def outputForm: CircuitForm = LowForm +class MacroCompilerOptimizations extends SeqTransform with DependencyAPIMigration { + override def prerequisites = Forms.LowForm + override def optionalPrerequisites = Forms.LowFormOptimized + override def optionalPrerequisiteOf = Forms.LowEmitters + override def invalidates(a: Transform) = false def transforms: Seq[Transform] = Seq( passes.RemoveValidIf, @@ -786,15 +789,6 @@ class MacroCompilerOptimizations extends SeqTransform { ) } -class MacroCompiler extends Compiler { - def emitter: Emitter = new VerilogEmitter - - def transforms: Seq[Transform] = - Seq(new MacroCompilerTransform) ++ - getLoweringTransforms(firrtl.ChirrtlForm, firrtl.LowForm) ++ - Seq(new MacroCompilerOptimizations) -} - object MacroCompiler extends App { sealed trait MacroParam case object Macros extends MacroParam @@ -890,7 +884,7 @@ object MacroCompiler extends App { MacroCompilerAnnotation( circuit.main, MacroCompilerAnnotation.Params( - params.get(Macros).get, + params(Macros), params.get(MacrosFormat), params.get(Library), params.get(HammerIR), @@ -905,20 +899,20 @@ object MacroCompiler extends App { ) // The actual MacroCompilerTransform basically just generates an input circuit - val macroCompilerInput = CircuitState(circuit, MidForm, annotations) + val macroCompilerInput = CircuitState(circuit, annotations) val macroCompiled = (new MacroCompilerTransform).execute(macroCompilerInput) - // Since the MacroCompiler defines its own CLI, reconcile this with FIRRTL options - val firOptions = new ExecutionOptionsManager("macrocompiler") with HasFirrtlOptions { - firrtlOptions = FirrtlExecutionOptions( - outputFileNameOverride = params.get(Verilog).getOrElse(""), - noDCE = true, - firrtlSource = Some(macroCompiled.circuit.serialize) - ) - } - // Run FIRRTL compiler - Driver.execute(firOptions) + (new FirrtlStage).execute( + Array.empty, + Seq( + OutputFileAnnotation(params.getOrElse(Verilog, "")), + RunFirrtlTransformAnnotation(new VerilogEmitter), + EmitCircuitAnnotation(classOf[VerilogEmitter]), + NoDCEAnnotation, + FirrtlSourceAnnotation(macroCompiled.circuit.serialize) + ) + ) params.get(HammerIR) match { case Some(hammerIRFile: String) => { @@ -947,8 +941,11 @@ object MacroCompiler extends App { } } catch { case e: java.util.NoSuchElementException => - e.printStackTrace() - println(usage) + if (args.isEmpty) { + println("Command line arguments must be specified") + } else { + e.printStackTrace() + } e.printStackTrace() sys.exit(1) case e: MacroCompilerException => From e650d5ba22676cde57ff99239b57f96330950b99 Mon Sep 17 00:00:00 2001 From: chick Date: Tue, 9 Feb 2021 14:12:57 -0800 Subject: [PATCH 8/8] - changed directory path to iocells to use directories rather than dotted name - Changed packages in tapeout/transforms/utils/*.scala to be in their own package `utils` --- .../iocell/chisel}/Analog.scala | 0 .../iocell/chisel}/IOCell.scala | 0 .../scala/barstools/tapeout/transforms/utils/FileUtils.scala | 4 ++-- .../barstools/tapeout/transforms/utils/LowerAnnotations.scala | 2 +- .../tapeout/transforms/utils/ProgrammaticBundle.scala | 3 ++- .../barstools/tapeout/transforms/utils/YamlHelpers.scala | 3 ++- 6 files changed, 7 insertions(+), 5 deletions(-) rename iocell/src/main/scala/{barstools.iocell.chisel => barstools/iocell/chisel}/Analog.scala (100%) rename iocell/src/main/scala/{barstools.iocell.chisel => barstools/iocell/chisel}/IOCell.scala (100%) diff --git a/iocell/src/main/scala/barstools.iocell.chisel/Analog.scala b/iocell/src/main/scala/barstools/iocell/chisel/Analog.scala similarity index 100% rename from iocell/src/main/scala/barstools.iocell.chisel/Analog.scala rename to iocell/src/main/scala/barstools/iocell/chisel/Analog.scala diff --git a/iocell/src/main/scala/barstools.iocell.chisel/IOCell.scala b/iocell/src/main/scala/barstools/iocell/chisel/IOCell.scala similarity index 100% rename from iocell/src/main/scala/barstools.iocell.chisel/IOCell.scala rename to iocell/src/main/scala/barstools/iocell/chisel/IOCell.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala index 6e79b7e5..86bf43de 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala @@ -1,8 +1,8 @@ // See LICENSE for license details. -package barstools.tapeout.transforms +package barstools.tapeout.transforms.utils -import chisel3.experimental.{annotate, ChiselAnnotation} +import chisel3.experimental.{ChiselAnnotation, annotate} import firrtl._ import firrtl.annotations._ import firrtl.stage.Forms diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala index 1f628900..45502d6d 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala @@ -1,4 +1,4 @@ -package barstools.tapeout.transforms +package barstools.tapeout.transforms.utils object LowerName { def apply(s: String): String = s.replace(".", "_").replace("[", "_").replace("]", "") diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala index 8025439c..66200e61 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala @@ -1,6 +1,7 @@ -package barstools.tapeout.transforms +package barstools.tapeout.transforms.utils import chisel3._ + import scala.collection.immutable.ListMap class CustomBundle[T <: Data](elts: (String, T)*) extends Record { diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala index 75b0c330..9a226de5 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala @@ -1,6 +1,7 @@ -package barstools.tapeout.transforms +package barstools.tapeout.transforms.utils import net.jcazevedo.moultingyaml._ + import java.io.File class YamlFileReader(resource: String) {