Skip to content
This repository has been archived by the owner on Aug 20, 2024. It is now read-only.

Commit

Permalink
Merge branch '1.0.1' into 1.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
ucbjrl committed Dec 21, 2017
2 parents d4df890 + b549234 commit 2f29ffb
Show file tree
Hide file tree
Showing 33 changed files with 14,396 additions and 74 deletions.
29 changes: 29 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
This repository's issues are reserved for feature requests and bug reports.

* **Type of issue**
- [ ] Bug report
- [ ] Feature request
- [ ] Other enhancement

* **If the current behavior is a bug, please provide the steps to reproduce the problem:**
* **What is the current behavior?**
* **What is the expected behavior?**
* **Please tell us about your environment:**
(examples)
- version: `3.0-SNAPSHOT`
- OS: `Linux knight 4.4.0-92-generic #115-Ubuntu SMP Thu Aug 10 09:04:33 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux`
- verilator version (if relevant)

* **What is the use case for changing the behavior?**

* **Impact**
- [ ] no functional change
- [ ] API addition (no impact on existing code)
- [ ] API modification
- [ ] unknown

* **Development Phase**
- [ ] request
- [ ] proposal

* **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. Stack Overflow, gitter, etc)
12 changes: 11 additions & 1 deletion .run_formal_checks.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
#!/usr/bin/env bash
set -e

if [ $# -ne 1 ]; then
echo "There must be exactly one argument!"
exit -1
fi

DUT=$1

# Run formal check only for PRs
if [ $TRAVIS_PULL_REQUEST = "false" ]; then
echo "Not a pull request, no formal check"
Expand All @@ -13,5 +22,6 @@ else
git remote set-branches origin $TRAVIS_BRANCH && git fetch
git checkout $TRAVIS_BRANCH
git checkout -
bash ./scripts/formal_equiv.sh HEAD $TRAVIS_BRANCH
cp regress/$DUT.fir $DUT.fir
./scripts/formal_equiv.sh HEAD $TRAVIS_BRANCH $DUT
fi
8 changes: 7 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,10 @@ jobs:
- bash .run_chisel_tests.sh
- stage: test
script:
- travis_wait 90 bash .run_formal_checks.sh
- ./.run_formal_checks.sh RocketCore
- stage: test
script:
- ./.run_formal_checks.sh FPU
- stage: test
script:
- ./.run_formal_checks.sh ICache
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ organization := "edu.berkeley.cs"

name := "firrtl"

version := "1.0.0"
version := "1.0.1"

scalaVersion := "2.11.11"

Expand Down
6,827 changes: 6,827 additions & 0 deletions regress/FPU.fir

Large diffs are not rendered by default.

569 changes: 569 additions & 0 deletions regress/ICache.fir

Large diffs are not rendered by default.

6,154 changes: 6,154 additions & 0 deletions regress/RocketCore.fir

Large diffs are not rendered by default.

24 changes: 17 additions & 7 deletions scripts/formal_equiv.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
#!/usr/bin/env bash
# This script is for formally comparing the Verilog emitted by different git revisions
# There must be two valid git revision arguments
set -e

if [ $# -ne 2 ]; then
echo "There must be exactly two arguments!"
if [ $# -ne 3 ]; then
echo "There must be exactly three arguments!"
exit -1
fi

HASH1=`git rev-parse $1`
HASH2=`git rev-parse $2`

echo "Comparing git revisions $HASH1 and $HASH2"
DUT=$3

echo "Comparing git revisions $HASH1 and $HASH2 on $DUT"

if [ $HASH1 = $HASH2 ]; then
echo "Both git revisions are the same! Nothing to do!"
Expand All @@ -20,10 +23,10 @@ fi
RET=""
make_verilog () {
git checkout $1
local filename="rob.$1.v"
local filename="$DUT.$1.v"

sbt clean
sbt "run-main firrtl.Driver -i regress/Rob.fir -o $filename -X verilog"
sbt "run-main firrtl.Driver -i $DUT.fir -o $filename -X verilog"
RET=$filename
}

Expand All @@ -43,11 +46,18 @@ else
echo "Running equivalence check using Yosys"
yosys -q -p "
read_verilog $FILE1
rename Rob top1
rename $DUT top1
proc
memory
flatten top1
hierarchy -top top1
read_verilog $FILE2
rename Rob top2
rename $DUT top2
proc
memory
flatten top2
equiv_make top1 top2 equiv
hierarchy -top equiv
clean -purge
Expand Down
71 changes: 56 additions & 15 deletions src/main/scala/firrtl/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ import scala.collection.mutable
import firrtl.annotations._ // Note that wildcard imports are not great....
import firrtl.ir.Circuit
import firrtl.Utils.{error, throwInternalError}
/**
* RenameMap maps old names to modified names. Generated by transformations
* that modify names
*/

object RenameMap {
def apply(map: Map[Named, Seq[Named]]) = {
val rm = new RenameMap
Expand All @@ -22,8 +19,52 @@ object RenameMap {
}
def apply() = new RenameMap
}
class RenameMap {
val renameMap = new mutable.HashMap[Named, Seq[Named]]()
/** Map old names to new names
*
* Transforms that modify names should return a [[RenameMap]] with the [[CircuitState]]
* These are mutable datastructures for convenience
*/
// TODO This should probably be refactored into immutable and mutable versions
final class RenameMap private () {
private val underlying = mutable.HashMap[Named, Seq[Named]]()
/** Get new names for an old name
*
* This is analogous to get on standard Scala collection Maps
* None indicates the key was not renamed
* Empty indicates the name was deleted
*/
// TODO Is there a better way to express this?
def get(key: Named): Option[Seq[Named]] = {
underlying.get(key) match {
// If the key was renamed, check if anything it renamed to is a component
// If so, check if nested modules were renamed
case Some(names) => Some(names.flatMap {
case comp @ ComponentName(cname, mod) =>
underlying.get(mod) match {
case Some(mods) => mods.map {
case modx: ModuleName =>
ComponentName(cname, modx)
case _ => error("Unexpected rename of Module to non-Module!")
}
case None => List(comp)
}
case other => List(other)
})
// If key wans't renamed, still check if it's a component
// If so, check if nexted modules were renamed
case None => key match {
case ComponentName(cname, mod) =>
underlying.get(mod).map(_.map {
case modx: ModuleName =>
ComponentName(cname, modx)
case _ => error("Unexpected rename of Module to non-Module!")
})
case other => None
}
}
}

// Mutable helpers
private var circuitName: String = ""
private var moduleName: String = ""
def setModule(s: String) =
Expand All @@ -40,18 +81,18 @@ class RenameMap {
}
def rename(from: Named, to: Named): Unit = rename(from, Seq(to))
def rename(from: Named, tos: Seq[Named]): Unit = (from, tos) match {
case (x, Seq(y)) if x == y =>
case (x, Seq(y)) if x == y => // TODO is this check expensive in common case?
case _ =>
renameMap(from) = renameMap.getOrElse(from, Seq.empty) ++ tos
underlying(from) = underlying.getOrElse(from, Seq.empty) ++ tos
}
def delete(names: Seq[String]): Unit = names.foreach(delete(_))
def delete(name: String): Unit =
delete(ComponentName(name, ModuleName(moduleName, CircuitName(circuitName))))
def delete(name: Named): Unit =
renameMap(name) = Seq.empty
def delete(name: Named): Unit =
underlying(name) = Seq.empty
def addMap(map: Map[Named, Seq[Named]]) =
renameMap ++= map
def serialize: String = renameMap.map { case (k, v) =>
underlying ++= map
def serialize: String = underlying.map { case (k, v) =>
k.serialize + "=>" + v.map(_.serialize).mkString(", ")
}.mkString("\n")
}
Expand Down Expand Up @@ -151,7 +192,7 @@ final case object MidForm extends CircuitForm(1)
*/
final case object LowForm extends CircuitForm(0)
/** Unknown Form
*
*
* Often passes may modify a circuit (e.g. InferTypes), but return
* a circuit in the same form it was given.
*
Expand Down Expand Up @@ -239,10 +280,10 @@ abstract class Transform extends LazyLogging {
}

// For each annotation, rename all annotations.
val renames = renameOpt.getOrElse(RenameMap()).renameMap
val renames = renameOpt.getOrElse(RenameMap())
for {
anno <- newAnnotations.toSeq
newAnno <- anno.update(renames.getOrElse(anno.target, Seq(anno.target)))
newAnno <- anno.update(renames.get(anno.target).getOrElse(Seq(anno.target)))
} yield newAnno
}
}
Expand Down
12 changes: 8 additions & 4 deletions src/main/scala/firrtl/ExecutionOptionsManager.scala
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,14 @@ case class FirrtlExecutionOptions(
case "low" => new LowFirrtlCompiler()
case "middle" => new MiddleFirrtlCompiler()
case "verilog" => new VerilogCompiler()
case "sverilog" => new VerilogCompiler()
}
}

def outputSuffix: String = {
compilerName match {
case "verilog" => "v"
case "sverilog" => "sv"
case "low" => "lo.fir"
case "high" => "hi.fir"
case "middle" => "mid.fir"
Expand Down Expand Up @@ -259,6 +261,7 @@ case class FirrtlExecutionOptions(
case "middle" => classOf[MiddleFirrtlEmitter]
case "low" => classOf[LowFirrtlEmitter]
case "verilog" => classOf[VerilogEmitter]
case "sverilog" => classOf[VerilogEmitter]
}
getOutputConfig(optionsManager) match {
case SingleFile(_) => Seq(EmitCircuitAnnotation(emitter))
Expand Down Expand Up @@ -333,12 +336,12 @@ trait HasFirrtlOptions {

parser.opt[String]("compiler")
.abbr("X")
.valueName ("<high|middle|low|verilog>")
.valueName ("<high|middle|low|verilog|sverilog>")
.foreach { x =>
firrtlOptions = firrtlOptions.copy(compilerName = x)
}
.validate { x =>
if (Array("high", "middle", "low", "verilog").contains(x.toLowerCase)) parser.success
if (Array("high", "middle", "low", "verilog", "sverilog").contains(x.toLowerCase)) parser.success
else parser.failure(s"$x not a legal compiler")
}.text {
s"compiler to use, default is ${firrtlOptions.compilerName}"
Expand Down Expand Up @@ -470,7 +473,7 @@ sealed trait FirrtlExecutionResult
* Indicates a successful execution of the firrtl compiler, returning the compiled result and
* the type of compile
*
* @param emitType The name of the compiler used, currently "high", "middle", "low", or "verilog"
* @param emitType The name of the compiler used, currently "high", "middle", "low", "verilog", or "sverilog"
* @param emitted The emitted result of compilation
*/
case class FirrtlExecutionSuccess(emitType: String, emitted: String) extends FirrtlExecutionResult
Expand Down Expand Up @@ -554,7 +557,8 @@ class ExecutionOptionsManager(val applicationName: String) extends HasParser(app
val dottedSuffix = if(suffix.startsWith(".")) suffix else s".$suffix"
if(baseName.endsWith(dottedSuffix)) "" else dottedSuffix
}

val path = directoryName + baseName.split("/").dropRight(1).mkString("/")
FileUtils.makeDirectory(path)
s"$directoryName$baseName$normalizedSuffix"
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/firrtl/LoweringCompilers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ class MiddleFirrtlToLowFirrtl extends CoreTransform {
passes.InferWidths,
passes.Legalize,
new firrtl.transforms.RemoveReset,
new firrtl.transforms.CheckCombLoops)
new firrtl.transforms.CheckCombLoops,
new firrtl.transforms.RemoveWires)
}

/** Runs a series of optimization passes on LowFirrtl
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/firrtl/Utils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ object Utils extends LazyLogging {
"before", "begin", "bind", "bins", "binsof", "bit", "break",
"buf", "bufif0", "bufif1", "byte",

"case", "casex", "casez", "cell", "chandle", "class", "clocking",
"case", "casex", "casez", "cell", "chandle", "checker", "class", "clocking",
"cmos", "config", "const", "constraint", "context", "continue",
"cover", "covergroup", "coverpoint", "cross",

Expand Down
Loading

0 comments on commit 2f29ffb

Please sign in to comment.