Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rearchitecting the tool flow (Not ready to merge) #1

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ channel_info

.project

# Metals Stuff
.bloop
.metals

# sbt specific
.cache
.history
Expand All @@ -59,13 +63,14 @@ lib_managed/
src_managed/
project/boot/
project/plugins/project/
project/metals.sbt
.idea/
gen/
project/project/
/bin/

# include FIRRTL examples
!src/main/scala/chiselucl/examples/firrtl/*
!examples/firrtl/*


*~
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
organization := "edu.berkeley.cs"
name := "chiselucl"
version := "0.2-SNAPSHOT"
scalaVersion := "2.12.7"
scalaVersion := "2.12.11"
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full)
//crossScalaVersions := Nil

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ class Adder extends Module {
val sum = Output(UInt(4.W))
})

val revert = io.sum - io.b

io.sum := io.a + io.b
Assume(io.a > 1.U, "a_bigger_than_one")
Assert(io.sum > io.b, "output_bigger")
Assert(revert =/= 0.U, "nonsense")
}

object AdderModel extends App {
Expand Down
Binary file added examples/firrtl/.RocketCore.fir.swp
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
23 changes: 23 additions & 0 deletions src/main/scala/chiselucl/analysis/CollectCircuitInfo.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// See LICENSE for license details.


package chiselucl
package analysis

import chiselucl.annotations.CircuitInfoAnnotation

import firrtl._
import firrtl.analyses.InstanceGraph


class CollectCircuitInfo extends Transform {
def inputForm = LowForm
def outputForm = LowForm

override def execute(cs: CircuitState): CircuitState = {
val circuitInfoAnno = Seq(CircuitInfoAnnotation(cs.circuit.main, new InstanceGraph(cs.circuit)))
cs.copy(annotations = circuitInfoAnno ++ cs.annotations)
}
}


116 changes: 116 additions & 0 deletions src/main/scala/chiselucl/analysis/CollectModuleInfo.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// See LICENSE for license details.

package chiselucl
package analysis

import chiselucl.annotations._
import chiselucl.verification.lang._

import firrtl._
import firrtl.ir._
import firrtl.Utils._
import firrtl.Mappers._

import scala.collection.mutable.{ListBuffer, HashSet}

object CollectModuleInfo {

def createModuleInfoAnnotation(m: Module): ModuleInfoAnnotation = {
val nodes = ListBuffer[DefNode]()
val wireDecls = ListBuffer[DefWire]()
val instDecls = ListBuffer[WDefInstance]()
val clocks = HashSet[Expression]()
val regResets = HashSet[String]()
val regDecls = HashSet[DefRegister]()
val memDecls = HashSet[DefMemory]()
val regAssigns = ListBuffer[Connect]()
val combAssigns = ListBuffer[Connect]()
val wireAssigns = ListBuffer[Connect]()
val properties = ListBuffer[VerificationFormula]()

//TODO: Need to revisit this correctness of the collection
def processStatements(s: Statement): Statement = s map processStatements match {
case sx: DefNode =>
nodes += sx
sx
case sx: DefRegister =>
clocks += sx.clock
sx.reset match {
case wr: WRef =>
regResets += wr.name
case UIntLiteral(v: BigInt, _) if (v == 0) =>
case _ =>
throwInternalError(s"Illegal reset signal ${sx.reset}")
}
regDecls += sx
sx
case sx @ Connect(_, lhs, rhs) => kind(lhs) match {
case RegKind =>
regAssigns += sx
case PortKind =>
combAssigns += sx
case MemKind => rhs.tpe match {
case ClockType =>
clocks += rhs
case _ =>
combAssigns += sx
}
case InstanceKind => lhs match {
case WSubField(WRef(instName,_,_,_), field, tpe, flow) =>
combAssigns += sx
case _ =>
throwInternalError(s"Only subfields of an instance may be on the lhs of a Connect involving an instance")
}
case _ =>
throwInternalError(s"Only outputs, registers, mem fields, and inst subfields may be on the lhs of a Connect")
}
sx
case sx @ DefMemory(_, n, dt, _, wlat, rlat, rs, ws, rws, _) =>
require(wlat == 1 && rlat == 0 && rws.size == 0, "This pass must run after VerilogMemDelays!")
require(dt.isInstanceOf[GroundType], "This pass must run after LowerTypes!")
memDecls += sx
sx
case sx @ WDefInstance(_,name,module,_) =>
instDecls += sx
sx
case DefWire(_,_,_) =>
// These are illegal for now
throw EmitterException("Using illegal statement!")
case sx =>
sx
}

processStatements(m.body)

ModuleInfoAnnotation(
m.name,
nodes.toSeq,
wireDecls.toSeq,
instDecls.toSeq,
regResets.toSet,
regDecls.toSet,
memDecls.toSet,
regAssigns.toSeq,
combAssigns.toSeq,
wireAssigns.toSeq,
properties.toSeq,
clocks.toSet,
None
)
}
}


class CollectModuleInfo extends Transform {
def inputForm = LowForm
def outputForm = LowForm


def execute(state: CircuitState): CircuitState = {
val moduleInfoAnnos = state.circuit.modules.flatMap {
case mod: Module => Some(CollectModuleInfo.createModuleInfoAnnotation(mod))
case extMod: ExtModule => None
}
state.copy(annotations = moduleInfoAnnos ++ state.annotations)
}
}
84 changes: 84 additions & 0 deletions src/main/scala/chiselucl/analysis/ComputeClockDomain.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// See LICENSE for license details.

package chiselucl
package analysis

import chiselucl.annotations._

import firrtl._
import firrtl.ir._
import firrtl.Utils._

import scala.collection.mutable.{LinkedHashMap, HashSet}

object ComputeClockDomain {


// TODO: We have two possible approaches to computing equal clocks
// 1. Change this implementation to use disjoint sets with a peek
// 2. Analyze the actual collected clocks (this seems promising)
//
def addClockInfo(modInfo: ModuleInfoAnnotation): ModuleInfoAnnotation = {
val eqClocks = LinkedHashMap[Expression, HashSet[Expression]]()

for (node<-modInfo.nodes) {
if (node.value.tpe == ClockType) {
node.value match {
case wr: WRef =>
val clockSet = eqClocks.getOrElseUpdate(wr, new HashSet[Expression]())
clockSet.add(WRef(node))
case _ => throwInternalError(s"Cannot handle complex clock NodeDef")
}
}
}

// Join equal clock sets
eqClocks.foreach({
case (k1, set1) =>
eqClocks.foreach({
case (k2, set2) =>
if (set1.contains(k2)) {
eqClocks.put(k1, set1.union(set2))
eqClocks.remove(k2)
}
})
})

val clockSets = new HashSet[Set[Expression]]()
eqClocks.foreach({
case (k, set) =>
set += k
clockSets += set.toSet
})

ModuleInfoAnnotation(
modInfo.name,
modInfo.nodes,
modInfo.wireDecls,
modInfo.instDecls,
modInfo.regResets,
modInfo.regDecls,
modInfo.memDecls,
modInfo.regAssigns,
modInfo.combAssigns,
modInfo.wireAssigns,
modInfo.properties,
modInfo.clocks,
Some(clockSets.toSet)
)
}
}


class ComputeClockDomain extends Transform {
def inputForm = LowForm
def outputForm = LowForm

def execute(state: CircuitState): CircuitState = {
val annos = state.annotations.map {
case modInfo: ModuleInfoAnnotation => ComputeClockDomain.addClockInfo(modInfo)
case other => other
}
state.copy(annotations = annos)
}
}
78 changes: 78 additions & 0 deletions src/main/scala/chiselucl/analysis/ExpandMemoryWires.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// See LICENSE for license details.

package chiselucl
package analysis

import chiselucl.annotations._

import firrtl._
import firrtl.ir._
import firrtl.passes._
import MemPortUtils.{memPortField}


import scala.collection.mutable.ListBuffer

object ExpandMemoryWires {

def expandWires(modInfo : ModuleInfoAnnotation) : ModuleInfoAnnotation = {
val newWires = ListBuffer[DefWire]()

for (decl <- modInfo.memDecls) {
decl match {
case sx @ DefMemory(_, n, dt, _, wlat, rlat, rs, ws, rws, _) =>
newWires += DefWire(NoInfo, s"havoc_$n", dt)
for (r <- rs) {
val data = memPortField(sx, r, "data")
val addr = memPortField(sx, r, "addr")
val en = memPortField(sx, r, "en")
newWires += DefWire(NoInfo, LowerTypes.loweredName(data), data.tpe)
newWires += DefWire(NoInfo, LowerTypes.loweredName(addr), addr.tpe)
newWires += DefWire(NoInfo, LowerTypes.loweredName(en), en.tpe)
}
for (w <- ws) {
val data = memPortField(sx, w, "data")
val addr = memPortField(sx, w, "addr")
val en = memPortField(sx, w, "en")
val mask = memPortField(sx, w, "mask")
newWires += DefWire(NoInfo, LowerTypes.loweredName(data), data.tpe)
newWires += DefWire(NoInfo, LowerTypes.loweredName(addr), addr.tpe)
newWires += DefWire(NoInfo, LowerTypes.loweredName(en), en.tpe)
newWires += DefWire(NoInfo, LowerTypes.loweredName(mask), mask.tpe)
}
case _ => // Do nothing
}
}

ModuleInfoAnnotation(
modInfo.name,
modInfo.nodes,
newWires.toSeq ++ modInfo.wireDecls,
modInfo.instDecls,
modInfo.regResets,
modInfo.regDecls,
modInfo.memDecls,
modInfo.regAssigns,
modInfo.combAssigns,
modInfo.wireAssigns,
modInfo.properties,
modInfo.clocks,
None
)
}

}


class ExpandMemoryWires extends Transform {
def inputForm = LowForm
def outputForm = LowForm

def execute(state: CircuitState): CircuitState = {
val annos = state.annotations.map {
case modInfo: ModuleInfoAnnotation => ExpandMemoryWires.expandWires(modInfo)
case other => other
}
state.copy(annotations = annos)
}
}
Loading