diff options
| author | Jack Koenig | 2017-06-12 13:58:26 -0700 |
|---|---|---|
| committer | Jack Koenig | 2017-06-12 18:52:46 -0700 |
| commit | 541003c59c73ecce6d38020ecc3cf537dd214fd9 (patch) | |
| tree | 22e8518a40673c408ec06c907c3f61c6449cdfab /src | |
| parent | 317115b7a0ce21d5848e985988c777f9931af241 (diff) | |
Add option to disable combinational loop detection
Resolves #600
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/Driver.scala | 5 | ||||
| -rw-r--r-- | src/main/scala/firrtl/ExecutionOptionsManager.scala | 10 | ||||
| -rw-r--r-- | src/main/scala/firrtl/transforms/CheckCombLoops.scala | 26 | ||||
| -rw-r--r-- | src/test/resources/features/HasLoops.fir | 9 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/CheckCombLoopsSpec.scala | 19 |
5 files changed, 62 insertions, 7 deletions
diff --git a/src/main/scala/firrtl/Driver.scala b/src/main/scala/firrtl/Driver.scala index 5e3d046a..6c4c450b 100644 --- a/src/main/scala/firrtl/Driver.scala +++ b/src/main/scala/firrtl/Driver.scala @@ -12,7 +12,7 @@ import logger.Logger import Parser.{IgnoreInfo, InfoMode} import annotations._ import firrtl.annotations.AnnotationYamlProtocol._ -import firrtl.transforms.{BlackBoxSourceHelper, BlackBoxTargetDir} +import firrtl.transforms.{BlackBoxSourceHelper, BlackBoxTargetDir, DontCheckCombLoopsAnnotation} import Utils.throwInternalError @@ -166,7 +166,8 @@ object Driver { val outputAnnos = firrtlConfig.getEmitterAnnos(optionsManager) // Should these and outputAnnos be moved to loadAnnotations? - val globalAnnos = Seq(TargetDirAnnotation(optionsManager.targetDirName)) + val globalAnnos = Seq(TargetDirAnnotation(optionsManager.targetDirName)) ++ + (if (firrtlConfig.dontCheckCombLoops) Seq(DontCheckCombLoopsAnnotation()) else Seq()) val finalState = firrtlConfig.compiler.compile( CircuitState(parsedInput, diff --git a/src/main/scala/firrtl/ExecutionOptionsManager.scala b/src/main/scala/firrtl/ExecutionOptionsManager.scala index 76b497ec..ebe27a7d 100644 --- a/src/main/scala/firrtl/ExecutionOptionsManager.scala +++ b/src/main/scala/firrtl/ExecutionOptionsManager.scala @@ -156,7 +156,8 @@ case class FirrtlExecutionOptions( annotations: List[Annotation] = List.empty, annotationFileNameOverride: String = "", forceAppendAnnoFile: Boolean = false, - emitOneFilePerModule: Boolean = false) + emitOneFilePerModule: Boolean = false, + dontCheckCombLoops: Boolean = false) extends ComposableOptions { require(!(emitOneFilePerModule && outputFileNameOverride.nonEmpty), @@ -412,6 +413,13 @@ trait HasFirrtlOptions { "Emit each module to its own file in the target directory." } + parser.opt[Unit]("no-check-comb-loops") + .foreach { _ => + firrtlOptions = firrtlOptions.copy(dontCheckCombLoops = true) + }.text { + "Do NOT check for combinational loops (not recommended)" + } + parser.note("") } diff --git a/src/main/scala/firrtl/transforms/CheckCombLoops.scala b/src/main/scala/firrtl/transforms/CheckCombLoops.scala index d0eec02c..d2d8b449 100644 --- a/src/main/scala/firrtl/transforms/CheckCombLoops.scala +++ b/src/main/scala/firrtl/transforms/CheckCombLoops.scala @@ -11,6 +11,7 @@ import firrtl._ import firrtl.ir._ import firrtl.passes.{Errors, PassException} import firrtl.Mappers._ +import firrtl.annotations._ import firrtl.Utils.throwInternalError import firrtl.graph.{MutableDiGraph,DiGraph} import firrtl.analyses.InstanceGraph @@ -21,6 +22,16 @@ object CheckCombLoops { } +object DontCheckCombLoopsAnnotation { + private val marker = "DontCheckCombLoops!" + private val transform = classOf[CheckCombLoops] + def apply(): Annotation = Annotation(CircuitTopName, transform, marker) + def unapply(a: Annotation): Boolean = a match { + case Annotation(_, targetXform, value) if targetXform == transform && value == marker => true + case _ => false + } +} + /** Finds and detects combinational logic loops in a circuit, if any * exist. Returns the input circuit with no modifications. * @@ -179,7 +190,7 @@ class CheckCombLoops extends Transform { * and only if it combinationally depends on input Y. Associate this * reduced graph with the module for future use. */ - def run(c: Circuit): Circuit = { + private def run(c: Circuit): Circuit = { val errors = new Errors() /* TODO(magyar): deal with exmodules! No pass warnings currently * exist. Maybe warn when iterating through modules. @@ -210,8 +221,15 @@ class CheckCombLoops extends Transform { } def execute(state: CircuitState): CircuitState = { - val result = run(state.circuit) - CircuitState(result, outputForm, state.annotations, state.renames) + val dontRun = getMyAnnotations(state).collectFirst { + case DontCheckCombLoopsAnnotation() => true + }.getOrElse(false) + if (dontRun) { + logger.warn("Skipping Combinational Loop Detection") + state + } else { + val result = run(state.circuit) + CircuitState(result, outputForm, state.annotations, state.renames) + } } - } diff --git a/src/test/resources/features/HasLoops.fir b/src/test/resources/features/HasLoops.fir new file mode 100644 index 00000000..e238761d --- /dev/null +++ b/src/test/resources/features/HasLoops.fir @@ -0,0 +1,9 @@ +circuit HasLoops : + module HasLoops : + input i : UInt<1> + output o : UInt<1> + wire a : UInt<1> + wire b : UInt<1> + a <= and(b,i) + b <= not(a) + o <= add(a, UInt(1)) diff --git a/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala b/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala index dfb61843..2c12d4ca 100644 --- a/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala +++ b/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala @@ -8,6 +8,8 @@ import firrtl.passes._ import firrtl.transforms._ import firrtl.Mappers._ import annotations._ +import java.io.File +import java.nio.file.Paths class CheckCombLoopsSpec extends SimpleTransformSpec { @@ -147,5 +149,22 @@ class CheckCombLoopsSpec extends SimpleTransformSpec { compile(CircuitState(parse(input), ChirrtlForm, None), writer) } } +} + +class CheckCombLoopsCommandLineSpec extends FirrtlFlatSpec { + val testDir = createTestDirectory("CombLoopChecker") + val inputFile = Paths.get(getClass.getResource("/features/HasLoops.fir").toURI()).toFile() + val outFile = new File(testDir, "HasLoops.v") + val args = Array("-i", inputFile.getAbsolutePath, "-o", outFile.getAbsolutePath, "-X", "verilog") + + "Combinational loops detection" should "run by default" in { + a [CheckCombLoops.CombLoopException] should be thrownBy { + firrtl.Driver.execute(args) + } + } + + it should "not run when given --no-check-comb-loops option" in { + firrtl.Driver.execute(args :+ "--no-check-comb-loops") + } } |
