aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorazidar2016-01-31 13:01:07 -0800
committerazidar2016-02-09 18:57:06 -0800
commit42bdd6fa53e0b73439bbab288e537371e57d2f43 (patch)
tree5cdd0aa06d5a1ef74bad903812204cb8e38bf121 /src
parentb1a62e54386aa7d6d67cd795cb7ba179de412c82 (diff)
Moved passes to new package
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/Compiler.scala25
-rw-r--r--src/main/scala/firrtl/Passes.scala674
-rw-r--r--src/main/scala/firrtl/Utils.scala76
-rw-r--r--src/main/scala/firrtl/passes/Passes.scala570
4 files changed, 652 insertions, 693 deletions
diff --git a/src/main/scala/firrtl/Compiler.scala b/src/main/scala/firrtl/Compiler.scala
index 18bec9dc..8facc27d 100644
--- a/src/main/scala/firrtl/Compiler.scala
+++ b/src/main/scala/firrtl/Compiler.scala
@@ -22,38 +22,19 @@ object VerilogCompiler extends Compiler {
// Copied from Stanza implementation
val passes = Seq(
CheckHighForm,
+ Resolve,
ToWorkingIR,
ResolveKinds,
InferTypes,
- CheckTypes,
ResolveGenders,
- CheckGenders,
- InferWidths,
- CheckWidths,
PullMuxes,
ExpandConnects,
RemoveAccesses,
ExpandWhens,
CheckInitialization,
ConstProp,
- ResolveKinds,
- InferTypes,
- CheckTypes,
- ResolveGenders,
- CheckGenders,
- InferWidths,
- CheckWidths,
- LowerTypes,
- ResolveKinds,
- InferTypes,
- CheckTypes,
- ResolveGenders,
- CheckGenders,
- InferWidths,
- CheckWidths,
- VerilogWrap,
- SplitExp,
- VerilogRename
+ Resolve,
+ LowerTypes
)
def run(c: Circuit, w: Writer)
{
diff --git a/src/main/scala/firrtl/Passes.scala b/src/main/scala/firrtl/Passes.scala
index 67fefde6..28ad876c 100644
--- a/src/main/scala/firrtl/Passes.scala
+++ b/src/main/scala/firrtl/Passes.scala
@@ -9,7 +9,6 @@ import Utils._
import DebugUtils._
import PrimOps._
-case class Location(base:Expression,guard:Expression)
@deprecated("This object will be replaced with package firrtl.passes")
object Passes extends LazyLogging {
@@ -21,15 +20,15 @@ object Passes extends LazyLogging {
// "infer-types" -> inferTypes
//)
var mname = ""
- def nameToPass(name: String): Circuit => Circuit = {
+ //def nameToPass(name: String): Circuit => Circuit = {
//mapNameToPass.getOrElse(name, throw new Exception("No Standard FIRRTL Pass of name " + name))
- name match {
- case "to-working-ir" => toWorkingIr
+ //name match {
+ //case "to-working-ir" => toWorkingIr
//case "infer-types" => inferTypes
// errrrrrrrrrr...
//case "renameall" => renameall(Map())
- }
- }
+ //}
+ //}
private def toField(p: Port): Field = {
logger.debug(s"toField called on port ${p.serialize}")
@@ -39,520 +38,58 @@ object Passes extends LazyLogging {
}
}
// ============== RESOLVE ALL ===================
- def resolve (c:Circuit) = {
- val passes = Seq(
- toWorkingIr _,
- resolveKinds _,
- inferTypes _,
- resolveGenders _,
- pullMuxes _,
- expandConnects _,
- removeAccesses _)
- val names = Seq(
- "To Working IR",
- "Resolve Kinds",
- "Infer Types",
- "Resolve Genders",
- "Pull Muxes",
- "Expand Connects",
- "Remove Accesses")
- var c_BANG = c
- (names, passes).zipped.foreach {
- (n,p) => {
- println("Starting " + n)
- c_BANG = p(c_BANG)
- println(c_BANG.serialize())
- println("Finished " + n)
- }
- }
- c_BANG
+ def resolve (c:Circuit) = {c
+ //val passes = Seq(
+ // toWorkingIr _,
+ // resolveKinds _,
+ // inferTypes _,
+ // resolveGenders _,
+ // pullMuxes _,
+ // expandConnects _,
+ // removeAccesses _)
+ //val names = Seq(
+ // "To Working IR",
+ // "Resolve Kinds",
+ // "Infer Types",
+ // "Resolve Genders",
+ // "Pull Muxes",
+ // "Expand Connects",
+ // "Remove Accesses")
+ //var c_BANG = c
+ //(names, passes).zipped.foreach {
+ // (n,p) => {
+ // println("Starting " + n)
+ // c_BANG = p(c_BANG)
+ // println(c_BANG.serialize())
+ // println("Finished " + n)
+ // }
+ //}
+ //c_BANG
}
- // ============== TO WORKING IR ==================
- def toWorkingIr (c:Circuit) = {
- def toExp (e:Expression) : Expression = {
- eMap(toExp _,e) match {
- case e:Ref => WRef(e.name, e.tpe, NodeKind(), UNKNOWNGENDER)
- case e:SubField => WSubField(e.exp, e.name, e.tpe, UNKNOWNGENDER)
- case e:SubIndex => WSubIndex(e.exp, e.value, e.tpe, UNKNOWNGENDER)
- case e:SubAccess => WSubAccess(e.exp, e.index, e.tpe, UNKNOWNGENDER)
- case e => e
- }
- }
- def toStmt (s:Stmt) : Stmt = {
- eMap(toExp _,s) match {
- case s:DefInstance => WDefInstance(s.info,s.name,s.module,UnknownType())
- case s => sMap(toStmt _,s)
- }
- }
- val modulesx = c.modules.map { m =>
- mname = m.name
- m match {
- case m:InModule => InModule(m.info,m.name, m.ports, toStmt(m.body))
- case m:ExModule => m
- }
- }
- Circuit(c.info,modulesx,c.main)
- }
- // ===============================================
// ============== RESOLVE KINDS ==================
- def resolveKinds (c:Circuit) = {
- def resolve_kinds (m:Module, c:Circuit):Module = {
- val kinds = HashMap[String,Kind]()
- def resolve (body:Stmt) = {
- def resolve_expr (e:Expression):Expression = {
- e match {
- case e:WRef => WRef(e.name,tpe(e),kinds(e.name),e.gender)
- case e => eMap(resolve_expr,e)
- }
- }
- def resolve_stmt (s:Stmt):Stmt = eMap(resolve_expr,sMap(resolve_stmt,s))
- resolve_stmt(body)
- }
-
- def find (m:Module) = {
- def find_stmt (s:Stmt):Stmt = {
- s match {
- case s:DefWire => kinds += (s.name -> WireKind())
- case s:DefPoison => kinds += (s.name -> PoisonKind())
- case s:DefNode => kinds += (s.name -> NodeKind())
- case s:DefRegister => kinds += (s.name -> RegKind())
- case s:WDefInstance => kinds += (s.name -> InstanceKind())
- case s:DefMemory => kinds += (s.name -> MemKind(s.readers ++ s.writers ++ s.readwriters))
- case s => false
- }
- sMap(find_stmt,s)
- }
- m.ports.foreach { p => kinds += (p.name -> PortKind()) }
- m match {
- case m:InModule => find_stmt(m.body)
- case m:ExModule => false
- }
- }
-
- mname = m.name
- find(m)
- m match {
- case m:InModule => {
- val bodyx = resolve(m.body)
- InModule(m.info,m.name,m.ports,bodyx)
- }
- case m:ExModule => ExModule(m.info,m.name,m.ports)
- }
- }
- val modulesx = c.modules.map(m => resolve_kinds(m,c))
- Circuit(c.info,modulesx,c.main)
- }
// ===============================================
// ============== INFER TYPES ==================
// ------------------ Utils -------------------------
- val width_name_hash = HashMap[String,Int]()
- def set_type (s:Stmt,t:Type) : Stmt = {
- s match {
- case s:DefWire => DefWire(s.info,s.name,t)
- case s:DefRegister => DefRegister(s.info,s.name,t,s.clock,s.reset,s.init)
- case s:DefMemory => DefMemory(s.info,s.name,t,s.depth,s.write_latency,s.read_latency,s.readers,s.writers,s.readwriters)
- case s:DefNode => s
- case s:DefPoison => DefPoison(s.info,s.name,t)
- }
- }
- def remove_unknowns_w (w:Width):Width = {
- w match {
- case w:UnknownWidth => VarWidth(firrtl_gensym("w",width_name_hash))
- case w => w
- }
- }
- def remove_unknowns (t:Type): Type = mapr(remove_unknowns_w _,t)
- def mapr (f: Width => Width, t:Type) : Type = {
- def apply_t (t:Type) : Type = {
- wMap(f,tMap(apply_t _,t))
- }
- apply_t(t)
- }
-
-
-
- // ------------------ Pass -------------------------
-
- def inferTypes (c:Circuit) : Circuit = {
- val module_types = HashMap[String,Type]()
- def infer_types (m:Module) : Module = {
- val types = HashMap[String,Type]()
- def infer_types_e (e:Expression) : Expression = {
- eMap(infer_types_e _,e) match {
- case e:ValidIf => ValidIf(e.cond,e.value,tpe(e.value))
- case e:WRef => WRef(e.name, types(e.name),e.kind,e.gender)
- case e:WSubField => WSubField(e.exp,e.name,field_type(tpe(e.exp),e.name),e.gender)
- case e:WSubIndex => WSubIndex(e.exp,e.value,sub_type(tpe(e.exp)),e.gender)
- case e:WSubAccess => WSubAccess(e.exp,e.index,sub_type(tpe(e.exp)),e.gender)
- case e:DoPrim => set_primop_type(e)
- case e:Mux => Mux(e.cond,e.tval,e.fval,mux_type_and_widths(e.tval,e.fval))
- case e:UIntValue => e
- case e:SIntValue => e
- }
- }
- def infer_types_s (s:Stmt) : Stmt = {
- s match {
- case s:DefRegister => {
- val t = remove_unknowns(get_type(s))
- types += (s.name -> t)
- eMap(infer_types_e _,set_type(s,t))
- }
- case s:DefWire => {
- val sx = eMap(infer_types_e _,s)
- val t = remove_unknowns(get_type(sx))
- types += (s.name -> t)
- set_type(sx,t)
- }
- case s:DefPoison => {
- val sx = eMap(infer_types_e _,s)
- val t = remove_unknowns(get_type(sx))
- types += (s.name -> t)
- set_type(sx,t)
- }
- case s:DefNode => {
- val sx = eMap(infer_types_e _,s)
- val t = remove_unknowns(get_type(sx))
- types += (s.name -> t)
- set_type(sx,t)
- }
- case s:DefMemory => {
- val t = remove_unknowns(get_type(s))
- types += (s.name -> t)
- val dt = remove_unknowns(s.data_type)
- set_type(s,dt)
- }
- case s:WDefInstance => {
- types += (s.name -> module_types(s.module))
- WDefInstance(s.info,s.name,s.module,module_types(s.module))
- }
- case s => eMap(infer_types_e _,sMap(infer_types_s,s))
- }
- }
-
- mname = m.name
- m.ports.foreach(p => types += (p.name -> p.tpe))
- m match {
- case m:InModule => InModule(m.info,m.name,m.ports,infer_types_s(m.body))
- case m:ExModule => m
- }
- }
-
- val modulesx = c.modules.map {
- m => {
- mname = m.name
- val portsx = m.ports.map(p => Port(p.info,p.name,p.direction,remove_unknowns(p.tpe)))
- m match {
- case m:InModule => InModule(m.info,m.name,portsx,m.body)
- case m:ExModule => ExModule(m.info,m.name,portsx)
- }
- }
- }
- modulesx.foreach(m => module_types += (m.name -> module_type(m)))
- Circuit(c.info,modulesx.map({m => mname = m.name; infer_types(m)}) , c.main )
- }
// =================== RESOLVE GENDERS =======================
- def resolveGenders (c:Circuit) = {
- def resolve_e (g:Gender)(e:Expression) : Expression = {
- e match {
- case e:WRef => WRef(e.name,e.tpe,e.kind,g)
- case e:WSubField => {
- val expx =
- field_flip(tpe(e.exp),e.name) match {
- case DEFAULT => resolve_e(g)(e.exp)
- case REVERSE => resolve_e(swap(g))(e.exp)
- }
- WSubField(expx,e.name,e.tpe,g)
- }
- case e:WSubIndex => {
- val expx = resolve_e(g)(e.exp)
- WSubIndex(expx,e.value,e.tpe,g)
- }
- case e:WSubAccess => {
- val expx = resolve_e(g)(e.exp)
- val indexx = resolve_e(MALE)(e.index)
- WSubAccess(expx,indexx,e.tpe,g)
- }
- case e => eMap(resolve_e(g) _,e)
- }
- }
-
- def resolve_s (s:Stmt) : Stmt = {
- s match {
- case s:IsInvalid => {
- val expx = resolve_e(FEMALE)(s.exp)
- IsInvalid(s.info,expx)
- }
- case s:Connect => {
- val locx = resolve_e(FEMALE)(s.loc)
- val expx = resolve_e(MALE)(s.exp)
- Connect(s.info,locx,expx)
- }
- case s:BulkConnect => {
- val locx = resolve_e(FEMALE)(s.loc)
- val expx = resolve_e(MALE)(s.exp)
- BulkConnect(s.info,locx,expx)
- }
- case s => sMap(resolve_s,eMap(resolve_e(MALE) _,s))
- }
- }
- val modulesx = c.modules.map {
- m => {
- mname = m.name
- m match {
- case m:InModule => {
- val bodyx = resolve_s(m.body)
- InModule(m.info,m.name,m.ports,bodyx)
- }
- case m:ExModule => m
- }
- }
- }
- Circuit(c.info,modulesx,c.main)
- }
// ===============================================
// =============== PULL MUXES ====================
- def pullMuxes (c:Circuit) : Circuit = {
- def pull_muxes_e (e:Expression) : Expression = {
- val ex = eMap(pull_muxes_e _,e) match {
- case (e:WRef) => e
- case (e:WSubField) => {
- e.exp match {
- case (ex:Mux) => Mux(ex.cond,WSubField(ex.tval,e.name,e.tpe,e.gender),WSubField(ex.fval,e.name,e.tpe,e.gender),e.tpe)
- case (ex:ValidIf) => ValidIf(ex.cond,WSubField(ex.value,e.name,e.tpe,e.gender),e.tpe)
- case (ex) => e
- }
- }
- case (e:WSubIndex) => {
- e.exp match {
- case (ex:Mux) => Mux(ex.cond,WSubIndex(ex.tval,e.value,e.tpe,e.gender),WSubIndex(ex.fval,e.value,e.tpe,e.gender),e.tpe)
- case (ex:ValidIf) => ValidIf(ex.cond,WSubIndex(ex.value,e.value,e.tpe,e.gender),e.tpe)
- case (ex) => e
- }
- }
- case (e:WSubAccess) => {
- e.exp match {
- case (ex:Mux) => Mux(ex.cond,WSubAccess(ex.tval,e.index,e.tpe,e.gender),WSubAccess(ex.fval,e.index,e.tpe,e.gender),e.tpe)
- case (ex:ValidIf) => ValidIf(ex.cond,WSubAccess(ex.value,e.index,e.tpe,e.gender),e.tpe)
- case (ex) => e
- }
- }
- case (e:Mux) => e
- case (e:ValidIf) => e
- case (e) => e
- }
- eMap(pull_muxes_e _,ex)
- }
-
- def pull_muxes (s:Stmt) : Stmt = eMap(pull_muxes_e _,sMap(pull_muxes _,s))
-
- val modulesx = c.modules.map {
- m => {
- mname = m.name
- m match {
- case (m:InModule) => InModule(m.info,m.name,m.ports,pull_muxes(m.body))
- case (m:ExModule) => m
- }
- }
- }
- Circuit(c.info,modulesx,c.main)
- }
// ===============================================
// ============ EXPAND CONNECTS ==================
// ---------------- UTILS ------------------
- def get_flip (t:Type, i:Int, f:Flip) : Flip = {
- if (i >= get_size(t)) error("Shouldn't be here")
- val x = t match {
- case (t:UIntType) => f
- case (t:SIntType) => f
- case (t:ClockType) => f
- case (t:BundleType) => {
- var n = i
- var ret:Option[Flip] = None
- t.fields.foreach { x => {
- if (n < get_size(x.tpe)) {
- ret match {
- case None => ret = Some(get_flip(x.tpe,n,times(x.flip,f)))
- case ret => {}
- }
- } else { n = n - get_size(x.tpe) }
- }}
- ret.asInstanceOf[Some[Flip]].get
- }
- case (t:VectorType) => {
- var n = i
- var ret:Option[Flip] = None
- for (j <- 0 until t.size) {
- if (n < get_size(t.tpe)) {
- ret = Some(get_flip(t.tpe,n,f))
- } else {
- n = n - get_size(t.tpe)
- }
- }
- ret.asInstanceOf[Some[Flip]].get
- }
- }
- x
- }
- def get_point (e:Expression) : Int = {
- e match {
- case (e:WRef) => 0
- case (e:WSubField) => {
- var i = 0
- tpe(e.exp).asInstanceOf[BundleType].fields.find { f => {
- val b = f.name == e.name
- if (!b) { i = i + get_size(f.tpe)}
- b
- }}
- i
- }
- case (e:WSubIndex) => e.value * get_size(e.tpe)
- case (e:WSubAccess) => get_point(e.exp)
- }
- }
-
- def create_exps (n:String, t:Type) : Seq[Expression] =
- create_exps(WRef(n,t,ExpKind(),UNKNOWNGENDER))
- def create_exps (e:Expression) : Seq[Expression] = {
- e match {
- case (e:Mux) => {
- val e1s = create_exps(e.tval)
- val e2s = create_exps(e.fval)
- (e1s, e2s).zipped.map {
- (e1,e2) => Mux(e.cond,e1,e2,mux_type_and_widths(e1,e2))
- }
- }
- case (e:ValidIf) => {
- create_exps(e.value).map {
- e1 => ValidIf(e.cond,e1,tpe(e1))
- }
- }
- case (e) => {
- tpe(e) match {
- case (t:UIntType) => Seq(e)
- case (t:SIntType) => Seq(e)
- case (t:ClockType) => Seq(e)
- case (t:BundleType) => {
- t.fields.flatMap {
- f => create_exps(WSubField(e,f.name,f.tpe,times(gender(e), f.flip)))
- }
- }
- case (t:VectorType) => {
- (0 until t.size).flatMap {
- i => create_exps(WSubIndex(e,i,t.tpe,gender(e)))
- }
- }
- }
- }
- }
- }
//---------------- Pass ---------------------
- def expandConnects (c:Circuit) : Circuit = {
- def expand_connects (m:InModule) : InModule = {
- mname = m.name
- val genders = HashMap[String,Gender]()
- def expand_s (s:Stmt) : Stmt = {
- def set_gender (e:Expression) : Expression = {
- eMap(set_gender _,e) match {
- case (e:WRef) => WRef(e.name,e.tpe,e.kind,genders(e.name))
- case (e:WSubField) => {
- val f = get_field(tpe(e.exp),e.name)
- val genderx = times(gender(e.exp),f.flip)
- WSubField(e.exp,e.name,e.tpe,genderx)
- }
- case (e:WSubIndex) => WSubIndex(e.exp,e.value,e.tpe,gender(e.exp))
- case (e:WSubAccess) => WSubAccess(e.exp,e.index,e.tpe,gender(e.exp))
- case (e) => e
- }
- }
- s match {
- case (s:DefWire) => { genders += (s.name -> BIGENDER); s }
- case (s:DefRegister) => { genders += (s.name -> BIGENDER); s }
- case (s:WDefInstance) => { genders += (s.name -> MALE); s }
- case (s:DefMemory) => { genders += (s.name -> MALE); s }
- case (s:DefPoison) => { genders += (s.name -> MALE); s }
- case (s:DefNode) => { genders += (s.name -> MALE); s }
- case (s:IsInvalid) => {
- val n = get_size(tpe(s.exp))
- val invalids = ArrayBuffer[Stmt]()
- val exps = create_exps(s.exp)
- for (i <- 0 until n) {
- val expx = exps(i)
- val gexpx = set_gender(expx)
- gender(gexpx) match {
- case BIGENDER => invalids += IsInvalid(s.info,expx)
- case FEMALE => invalids += IsInvalid(s.info,expx)
- case _ => {}
- }
- }
- if (invalids.length == 0) {
- Empty()
- } else if (invalids.length == 1) {
- invalids(0)
- } else Begin(invalids)
- }
- case (s:Connect) => {
- val n = get_size(tpe(s.loc))
- val connects = ArrayBuffer[Stmt]()
- val locs = create_exps(s.loc)
- val exps = create_exps(s.exp)
- for (i <- 0 until n) {
- val locx = locs(i)
- val expx = exps(i)
- val sx = get_flip(tpe(s.loc),i,DEFAULT) match {
- case DEFAULT => Connect(s.info,locx,expx)
- case REVERSE => Connect(s.info,expx,locx)
- }
- connects += sx
- }
- Begin(connects)
- }
- case (s:BulkConnect) => {
- val ls = get_valid_points(tpe(s.loc),tpe(s.exp),DEFAULT,DEFAULT)
- val connects = ArrayBuffer[Stmt]()
- val locs = create_exps(s.loc)
- val exps = create_exps(s.exp)
- ls.foreach { x => {
- val locx = locs(x._1)
- val expx = exps(x._2)
- val sx = get_flip(tpe(s.loc),x._1,DEFAULT) match {
- case DEFAULT => Connect(s.info,locx,expx)
- case REVERSE => Connect(s.info,expx,locx)
- }
- connects += sx
- }}
- Begin(connects)
- }
- case (s) => sMap(expand_s _,s)
- }
- }
-
- m.ports.foreach { p => genders += (p.name -> to_gender(p.direction)) }
- InModule(m.info,m.name,m.ports,expand_s(m.body))
- }
-
- val modulesx = c.modules.map {
- m => {
- m match {
- case (m:ExModule) => m
- case (m:InModule) => expand_connects(m)
- }
- }
- }
- Circuit(c.info,modulesx,c.main)
- }
// ===============================================
@@ -560,153 +97,6 @@ object Passes extends LazyLogging {
// ============ REMOVE ACCESSES ==================
// ---------------- UTILS ------------------
- def get_locations (e:Expression) : Seq[Location] = {
- e match {
- case (e:WRef) => create_exps(e).map(Location(_,one))
- case (e:WSubIndex) => {
- val ls = get_locations(e.exp)
- val start = get_point(e)
- val end = start + get_size(tpe(e))
- val stride = get_size(tpe(e.exp))
- val lsx = ArrayBuffer[Location]()
- var c = 0
- for (i <- 0 until ls.size) {
- if (((i % stride) >= start) & ((i % stride) < end)) {
- lsx += ls(i)
- }
- }
- lsx
- }
- case (e:WSubField) => {
- val ls = get_locations(e.exp)
- val start = get_point(e)
- val end = start + get_size(tpe(e))
- val stride = get_size(tpe(e.exp))
- val lsx = ArrayBuffer[Location]()
- var c = 0
- for (i <- 0 until ls.size) {
- if (((i % stride) >= start) & ((i % stride) < end)) {
- lsx += ls(i)
- }
- }
- lsx
- }
- case (e:WSubAccess) => {
- val ls = get_locations(e.exp)
- val stride = get_size(tpe(e))
- val wrap = tpe(e.exp).asInstanceOf[VectorType].size
- val lsx = ArrayBuffer[Location]()
- var c = 0
- for (i <- 0 until ls.size) {
- if ((c % wrap) == 0) { c = 0 }
- val basex = ls(i).base
- val guardx = AND(ls(i).guard,EQV(uint(c),e.index))
- lsx += Location(basex,guardx)
- if ((i + 1) % stride == 0) {
- c = c + 1
- }
- }
- lsx
- }
- }
- }
-
- def has_access (e:Expression) : Boolean = {
- var ret:Boolean = false
- def rec_has_access (e:Expression) : Expression = {
- e match {
- case (e:WSubAccess) => {
- ret = true
- e
- }
- case (e) => eMap(rec_has_access _,e)
- }
- }
- rec_has_access(e)
- ret
- }
-
- def removeAccesses (c:Circuit) = {
- def remove_m (m:InModule) : InModule = {
- val sh = sym_hash
- mname = m.name
- def remove_s (s:Stmt) : Stmt = {
- val stmts = ArrayBuffer[Stmt]()
- def create_temp (e:Expression) : Expression = {
- val n = firrtl_gensym("GEN",sh)
- stmts += DefWire(info(s),n,tpe(e))
- WRef(n,tpe(e),kind(e),gender(e))
- }
- def remove_e (e:Expression) : Expression = { //NOT RECURSIVE (except primops) INTENTIONALLY!
- e match {
- case (e:DoPrim) => eMap(remove_e,e)
- case (e:Mux) => eMap(remove_e,e)
- case (e:ValidIf) => eMap(remove_e,e)
- case (e:SIntValue) => e
- case (e:UIntValue) => e
- case e => {
- if (has_access(e)) {
- val rs = get_locations(e)
- val foo = rs.find(x => {x.guard != one})
- foo match {
- case None => error("Shouldn't be here")
- case foo:Some[Location] => {
- val temp = create_temp(e)
- val temps = create_exps(temp)
- def get_temp (i:Int) = temps(i % temps.size)
- (rs,0 until rs.size).zipped.foreach {
- (x,i) => {
- if (i < temps.size) {
- stmts += Connect(info(s),get_temp(i),x.base)
- } else {
- stmts += Conditionally(info(s),x.guard,Connect(info(s),get_temp(i),x.base),Empty())
- }
- }
- }
- temp
- }
- }
- } else { e}
- }
- }
- }
-
- val sx = s match {
- case (s:Connect) => {
- if (has_access(s.loc)) {
- val ls = get_locations(s.loc)
- val locx =
- if (ls.size == 1 & ls(0).guard == one) s.loc
- else {
- val temp = create_temp(s.loc)
- for (x <- ls) {
- stmts += Conditionally(s.info,x.guard,Connect(s.info,x.base,temp),Empty())
- }
- temp
- }
- Connect(s.info,locx,remove_e(s.exp))
- } else {
- Connect(s.info,s.loc,remove_e(s.exp))
- }
- }
- case (s) => sMap(remove_s,eMap(remove_e,s))
- }
- stmts += sx
- if (stmts.size != 1) Begin(stmts) else stmts(0)
- }
- InModule(m.info,m.name,m.ports,remove_s(m.body))
- }
-
- val modulesx = c.modules.map{
- m => {
- m match {
- case (m:ExModule) => m
- case (m:InModule) => remove_m(m)
- }
- }
- }
- Circuit(c.info,modulesx,c.main)
- }
/** INFER TYPES
*
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala
index 4625ec63..5c8fa2bb 100644
--- a/src/main/scala/firrtl/Utils.scala
+++ b/src/main/scala/firrtl/Utils.scala
@@ -88,6 +88,82 @@ object Utils {
case t:SIntType => BoolType()
}
}
+ def create_exps (n:String, t:Type) : Seq[Expression] =
+ create_exps(WRef(n,t,ExpKind(),UNKNOWNGENDER))
+ def create_exps (e:Expression) : Seq[Expression] = {
+ e match {
+ case (e:Mux) => {
+ val e1s = create_exps(e.tval)
+ val e2s = create_exps(e.fval)
+ (e1s, e2s).zipped.map { (e1,e2) => Mux(e.cond,e1,e2,mux_type_and_widths(e1,e2)) }
+ }
+ case (e:ValidIf) => create_exps(e.value).map { e1 => ValidIf(e.cond,e1,tpe(e1)) }
+ case (e) => {
+ tpe(e) match {
+ case (t:UIntType) => Seq(e)
+ case (t:SIntType) => Seq(e)
+ case (t:ClockType) => Seq(e)
+ case (t:BundleType) => {
+ t.fields.flatMap { f => create_exps(WSubField(e,f.name,f.tpe,times(gender(e), f.flip))) }
+ }
+ case (t:VectorType) => {
+ (0 until t.size).flatMap { i => create_exps(WSubIndex(e,i,t.tpe,gender(e))) }
+ }
+ }
+ }
+ }
+ }
+ def get_flip (t:Type, i:Int, f:Flip) : Flip = {
+ if (i >= get_size(t)) error("Shouldn't be here")
+ val x = t match {
+ case (t:UIntType) => f
+ case (t:SIntType) => f
+ case (t:ClockType) => f
+ case (t:BundleType) => {
+ var n = i
+ var ret:Option[Flip] = None
+ t.fields.foreach { x => {
+ if (n < get_size(x.tpe)) {
+ ret match {
+ case None => ret = Some(get_flip(x.tpe,n,times(x.flip,f)))
+ case ret => {}
+ }
+ } else { n = n - get_size(x.tpe) }
+ }}
+ ret.asInstanceOf[Some[Flip]].get
+ }
+ case (t:VectorType) => {
+ var n = i
+ var ret:Option[Flip] = None
+ for (j <- 0 until t.size) {
+ if (n < get_size(t.tpe)) {
+ ret = Some(get_flip(t.tpe,n,f))
+ } else {
+ n = n - get_size(t.tpe)
+ }
+ }
+ ret.asInstanceOf[Some[Flip]].get
+ }
+ }
+ x
+ }
+
+ def get_point (e:Expression) : Int = {
+ e match {
+ case (e:WRef) => 0
+ case (e:WSubField) => {
+ var i = 0
+ tpe(e.exp).asInstanceOf[BundleType].fields.find { f => {
+ val b = f.name == e.name
+ if (!b) { i = i + get_size(f.tpe)}
+ b
+ }}
+ i
+ }
+ case (e:WSubIndex) => e.value * get_size(e.tpe)
+ case (e:WSubAccess) => get_point(e.exp)
+ }
+ }
//============== TYPES ================
def mux_type_and_widths (e1:Expression,e2:Expression) : Type = mux_type_and_widths(tpe(e1),tpe(e2))
diff --git a/src/main/scala/firrtl/passes/Passes.scala b/src/main/scala/firrtl/passes/Passes.scala
index 7c1c7bc3..591f4c99 100644
--- a/src/main/scala/firrtl/passes/Passes.scala
+++ b/src/main/scala/firrtl/passes/Passes.scala
@@ -8,6 +8,10 @@ import java.nio.file.{Paths, Files}
import scala.sys.process._
import scala.io.Source
+// Datastructures
+import scala.collection.mutable.HashMap
+import scala.collection.mutable.ArrayBuffer
+
import firrtl._
import firrtl.Utils._
import firrtl.PrimOps._
@@ -40,7 +44,7 @@ trait StanzaPass extends LazyLogging {
}
object PassUtils extends LazyLogging {
- val listOfPasses: Seq[Pass] = Seq(ToWorkingIR)
+ val listOfPasses: Seq[Pass] = Seq(ToWorkingIR,ResolveKinds,ResolveGenders,PullMuxes,ExpandConnects,RemoveAccesses)
lazy val mapNameToPass: Map[String, Pass] = listOfPasses.map(p => p.name -> p).toMap
def executePasses(c: Circuit, passes: Seq[Pass]): Circuit = {
@@ -55,9 +59,34 @@ object CheckHighForm extends Pass with StanzaPass {
def run (c:Circuit): Circuit = stanzaPass(c, "high-form-check")
}
-object ToWorkingIR extends Pass with StanzaPass {
- def name = "Working IR"
- def run (c:Circuit): Circuit = stanzaPass(c, "to-working-ir")
+object ToWorkingIR extends Pass {
+ private var mname = ""
+ def name = "Working IR"
+ def run (c:Circuit): Circuit = {
+ def toExp (e:Expression) : Expression = {
+ eMap(toExp _,e) match {
+ case e:Ref => WRef(e.name, e.tpe, NodeKind(), UNKNOWNGENDER)
+ case e:SubField => WSubField(e.exp, e.name, e.tpe, UNKNOWNGENDER)
+ case e:SubIndex => WSubIndex(e.exp, e.value, e.tpe, UNKNOWNGENDER)
+ case e:SubAccess => WSubAccess(e.exp, e.index, e.tpe, UNKNOWNGENDER)
+ case e => e
+ }
+ }
+ def toStmt (s:Stmt) : Stmt = {
+ eMap(toExp _,s) match {
+ case s:DefInstance => WDefInstance(s.info,s.name,s.module,UnknownType())
+ case s => sMap(toStmt _,s)
+ }
+ }
+ val modulesx = c.modules.map { m =>
+ mname = m.name
+ m match {
+ case m:InModule => InModule(m.info,m.name, m.ports, toStmt(m.body))
+ case m:ExModule => m
+ }
+ }
+ Circuit(c.info,modulesx,c.main)
+ }
}
object Resolve extends Pass with StanzaPass {
@@ -65,54 +94,532 @@ object Resolve extends Pass with StanzaPass {
def run (c:Circuit): Circuit = stanzaPass(c, "resolve")
}
-object ResolveKinds extends Pass with StanzaPass {
- def name = "Resolve Kinds"
- def run (c:Circuit): Circuit = stanzaPass(c, "resolve-kinds")
+object ResolveKinds extends Pass {
+ private var mname = ""
+ def name = "Resolve Kinds"
+ def run (c:Circuit): Circuit = {
+ def resolve_kinds (m:Module, c:Circuit):Module = {
+ val kinds = HashMap[String,Kind]()
+ def resolve (body:Stmt) = {
+ def resolve_expr (e:Expression):Expression = {
+ e match {
+ case e:WRef => WRef(e.name,tpe(e),kinds(e.name),e.gender)
+ case e => eMap(resolve_expr,e)
+ }
+ }
+ def resolve_stmt (s:Stmt):Stmt = eMap(resolve_expr,sMap(resolve_stmt,s))
+ resolve_stmt(body)
+ }
+
+ def find (m:Module) = {
+ def find_stmt (s:Stmt):Stmt = {
+ s match {
+ case s:DefWire => kinds += (s.name -> WireKind())
+ case s:DefPoison => kinds += (s.name -> PoisonKind())
+ case s:DefNode => kinds += (s.name -> NodeKind())
+ case s:DefRegister => kinds += (s.name -> RegKind())
+ case s:WDefInstance => kinds += (s.name -> InstanceKind())
+ case s:DefMemory => kinds += (s.name -> MemKind(s.readers ++ s.writers ++ s.readwriters))
+ case s => false
+ }
+ sMap(find_stmt,s)
+ }
+ m.ports.foreach { p => kinds += (p.name -> PortKind()) }
+ m match {
+ case m:InModule => find_stmt(m.body)
+ case m:ExModule => false
+ }
+ }
+
+ mname = m.name
+ find(m)
+ m match {
+ case m:InModule => {
+ val bodyx = resolve(m.body)
+ InModule(m.info,m.name,m.ports,bodyx)
+ }
+ case m:ExModule => ExModule(m.info,m.name,m.ports)
+ }
+ }
+ val modulesx = c.modules.map(m => resolve_kinds(m,c))
+ Circuit(c.info,modulesx,c.main)
+ }
}
-object InferTypes extends Pass with StanzaPass {
- def name = "Infer Types"
- def run (c:Circuit): Circuit = stanzaPass(c, "infer-types")
+object InferTypes extends Pass {
+ private var mname = ""
+ def name = "Infer Types"
+ val width_name_hash = HashMap[String,Int]()
+ def set_type (s:Stmt,t:Type) : Stmt = {
+ s match {
+ case s:DefWire => DefWire(s.info,s.name,t)
+ case s:DefRegister => DefRegister(s.info,s.name,t,s.clock,s.reset,s.init)
+ case s:DefMemory => DefMemory(s.info,s.name,t,s.depth,s.write_latency,s.read_latency,s.readers,s.writers,s.readwriters)
+ case s:DefNode => s
+ case s:DefPoison => DefPoison(s.info,s.name,t)
+ }
+ }
+ def remove_unknowns_w (w:Width):Width = {
+ w match {
+ case w:UnknownWidth => VarWidth(firrtl_gensym("w",width_name_hash))
+ case w => w
+ }
+ }
+ def remove_unknowns (t:Type): Type = mapr(remove_unknowns_w _,t)
+ def mapr (f: Width => Width, t:Type) : Type = {
+ def apply_t (t:Type) : Type = {
+ wMap(f,tMap(apply_t _,t))
+ }
+ apply_t(t)
+ }
+ def run (c:Circuit): Circuit = {
+ val module_types = HashMap[String,Type]()
+ def infer_types (m:Module) : Module = {
+ val types = HashMap[String,Type]()
+ def infer_types_e (e:Expression) : Expression = {
+ eMap(infer_types_e _,e) match {
+ case e:ValidIf => ValidIf(e.cond,e.value,tpe(e.value))
+ case e:WRef => WRef(e.name, types(e.name),e.kind,e.gender)
+ case e:WSubField => WSubField(e.exp,e.name,field_type(tpe(e.exp),e.name),e.gender)
+ case e:WSubIndex => WSubIndex(e.exp,e.value,sub_type(tpe(e.exp)),e.gender)
+ case e:WSubAccess => WSubAccess(e.exp,e.index,sub_type(tpe(e.exp)),e.gender)
+ case e:DoPrim => set_primop_type(e)
+ case e:Mux => Mux(e.cond,e.tval,e.fval,mux_type_and_widths(e.tval,e.fval))
+ case e:UIntValue => e
+ case e:SIntValue => e
+ }
+ }
+ def infer_types_s (s:Stmt) : Stmt = {
+ s match {
+ case s:DefRegister => {
+ val t = remove_unknowns(get_type(s))
+ types += (s.name -> t)
+ eMap(infer_types_e _,set_type(s,t))
+ }
+ case s:DefWire => {
+ val sx = eMap(infer_types_e _,s)
+ val t = remove_unknowns(get_type(sx))
+ types += (s.name -> t)
+ set_type(sx,t)
+ }
+ case s:DefPoison => {
+ val sx = eMap(infer_types_e _,s)
+ val t = remove_unknowns(get_type(sx))
+ types += (s.name -> t)
+ set_type(sx,t)
+ }
+ case s:DefNode => {
+ val sx = eMap(infer_types_e _,s)
+ val t = remove_unknowns(get_type(sx))
+ types += (s.name -> t)
+ set_type(sx,t)
+ }
+ case s:DefMemory => {
+ val t = remove_unknowns(get_type(s))
+ types += (s.name -> t)
+ val dt = remove_unknowns(s.data_type)
+ set_type(s,dt)
+ }
+ case s:WDefInstance => {
+ types += (s.name -> module_types(s.module))
+ WDefInstance(s.info,s.name,s.module,module_types(s.module))
+ }
+ case s => eMap(infer_types_e _,sMap(infer_types_s,s))
+ }
+ }
+
+ mname = m.name
+ m.ports.foreach(p => types += (p.name -> p.tpe))
+ m match {
+ case m:InModule => InModule(m.info,m.name,m.ports,infer_types_s(m.body))
+ case m:ExModule => m
+ }
+ }
+
+ val modulesx = c.modules.map {
+ m => {
+ mname = m.name
+ val portsx = m.ports.map(p => Port(p.info,p.name,p.direction,remove_unknowns(p.tpe)))
+ m match {
+ case m:InModule => InModule(m.info,m.name,portsx,m.body)
+ case m:ExModule => ExModule(m.info,m.name,portsx)
+ }
+ }
+ }
+ modulesx.foreach(m => module_types += (m.name -> module_type(m)))
+ Circuit(c.info,modulesx.map({m => mname = m.name; infer_types(m)}) , c.main )
+ }
}
-
object CheckTypes extends Pass with StanzaPass {
def name = "Check Types"
def run (c:Circuit): Circuit = stanzaPass(c, "check-types")
}
-object ResolveGenders extends Pass with StanzaPass {
- def name = "Resolve Genders"
- def run (c:Circuit): Circuit = stanzaPass(c, "resolve-genders")
+object ResolveGenders extends Pass {
+ private var mname = ""
+ def name = "Resolve Genders"
+ def run (c:Circuit): Circuit = {
+ def resolve_e (g:Gender)(e:Expression) : Expression = {
+ e match {
+ case e:WRef => WRef(e.name,e.tpe,e.kind,g)
+ case e:WSubField => {
+ val expx =
+ field_flip(tpe(e.exp),e.name) match {
+ case DEFAULT => resolve_e(g)(e.exp)
+ case REVERSE => resolve_e(swap(g))(e.exp)
+ }
+ WSubField(expx,e.name,e.tpe,g)
+ }
+ case e:WSubIndex => {
+ val expx = resolve_e(g)(e.exp)
+ WSubIndex(expx,e.value,e.tpe,g)
+ }
+ case e:WSubAccess => {
+ val expx = resolve_e(g)(e.exp)
+ val indexx = resolve_e(MALE)(e.index)
+ WSubAccess(expx,indexx,e.tpe,g)
+ }
+ case e => eMap(resolve_e(g) _,e)
+ }
+ }
+
+ def resolve_s (s:Stmt) : Stmt = {
+ s match {
+ case s:IsInvalid => {
+ val expx = resolve_e(FEMALE)(s.exp)
+ IsInvalid(s.info,expx)
+ }
+ case s:Connect => {
+ val locx = resolve_e(FEMALE)(s.loc)
+ val expx = resolve_e(MALE)(s.exp)
+ Connect(s.info,locx,expx)
+ }
+ case s:BulkConnect => {
+ val locx = resolve_e(FEMALE)(s.loc)
+ val expx = resolve_e(MALE)(s.exp)
+ BulkConnect(s.info,locx,expx)
+ }
+ case s => sMap(resolve_s,eMap(resolve_e(MALE) _,s))
+ }
+ }
+ val modulesx = c.modules.map {
+ m => {
+ mname = m.name
+ m match {
+ case m:InModule => {
+ val bodyx = resolve_s(m.body)
+ InModule(m.info,m.name,m.ports,bodyx)
+ }
+ case m:ExModule => m
+ }
+ }
+ }
+ Circuit(c.info,modulesx,c.main)
+ }
}
object CheckGenders extends Pass with StanzaPass {
- def name = "Check Genders"
- def run (c:Circuit): Circuit = stanzaPass(c, "check-genders")
+ def name = "Check Genders"
+ def run (c:Circuit): Circuit = stanzaPass(c, "check-genders")
}
object InferWidths extends Pass with StanzaPass {
- def name = "Infer Widths"
- def run (c:Circuit): Circuit = stanzaPass(c, "infer-widths")
+ def name = "Infer Widths"
+ def run (c:Circuit): Circuit = stanzaPass(c, "infer-widths")
}
object CheckWidths extends Pass with StanzaPass {
- def name = "Width Check"
- def run (c:Circuit): Circuit = stanzaPass(c, "width-check")
+ def name = "Width Check"
+ def run (c:Circuit): Circuit = stanzaPass(c, "width-check")
}
-object PullMuxes extends Pass with StanzaPass {
- def name = "Pull Muxes"
- def run (c:Circuit): Circuit = stanzaPass(c, "pull-muxes")
+object PullMuxes extends Pass {
+ private var mname = ""
+ def name = "Pull Muxes"
+ def run (c:Circuit): Circuit = {
+ def pull_muxes_e (e:Expression) : Expression = {
+ val ex = eMap(pull_muxes_e _,e) match {
+ case (e:WRef) => e
+ case (e:WSubField) => {
+ e.exp match {
+ case (ex:Mux) => Mux(ex.cond,WSubField(ex.tval,e.name,e.tpe,e.gender),WSubField(ex.fval,e.name,e.tpe,e.gender),e.tpe)
+ case (ex:ValidIf) => ValidIf(ex.cond,WSubField(ex.value,e.name,e.tpe,e.gender),e.tpe)
+ case (ex) => e
+ }
+ }
+ case (e:WSubIndex) => {
+ e.exp match {
+ case (ex:Mux) => Mux(ex.cond,WSubIndex(ex.tval,e.value,e.tpe,e.gender),WSubIndex(ex.fval,e.value,e.tpe,e.gender),e.tpe)
+ case (ex:ValidIf) => ValidIf(ex.cond,WSubIndex(ex.value,e.value,e.tpe,e.gender),e.tpe)
+ case (ex) => e
+ }
+ }
+ case (e:WSubAccess) => {
+ e.exp match {
+ case (ex:Mux) => Mux(ex.cond,WSubAccess(ex.tval,e.index,e.tpe,e.gender),WSubAccess(ex.fval,e.index,e.tpe,e.gender),e.tpe)
+ case (ex:ValidIf) => ValidIf(ex.cond,WSubAccess(ex.value,e.index,e.tpe,e.gender),e.tpe)
+ case (ex) => e
+ }
+ }
+ case (e:Mux) => e
+ case (e:ValidIf) => e
+ case (e) => e
+ }
+ eMap(pull_muxes_e _,ex)
+ }
+ def pull_muxes (s:Stmt) : Stmt = eMap(pull_muxes_e _,sMap(pull_muxes _,s))
+ val modulesx = c.modules.map {
+ m => {
+ mname = m.name
+ m match {
+ case (m:InModule) => InModule(m.info,m.name,m.ports,pull_muxes(m.body))
+ case (m:ExModule) => m
+ }
+ }
+ }
+ Circuit(c.info,modulesx,c.main)
+ }
}
-object ExpandConnects extends Pass with StanzaPass {
- def name = "Expand Connects"
- def run (c:Circuit): Circuit = stanzaPass(c, "expand-connects")
+object ExpandConnects extends Pass {
+ private var mname = ""
+ def name = "Expand Connects"
+ def run (c:Circuit): Circuit = {
+ def expand_connects (m:InModule) : InModule = {
+ mname = m.name
+ val genders = HashMap[String,Gender]()
+ def expand_s (s:Stmt) : Stmt = {
+ def set_gender (e:Expression) : Expression = {
+ eMap(set_gender _,e) match {
+ case (e:WRef) => WRef(e.name,e.tpe,e.kind,genders(e.name))
+ case (e:WSubField) => {
+ val f = get_field(tpe(e.exp),e.name)
+ val genderx = times(gender(e.exp),f.flip)
+ WSubField(e.exp,e.name,e.tpe,genderx)
+ }
+ case (e:WSubIndex) => WSubIndex(e.exp,e.value,e.tpe,gender(e.exp))
+ case (e:WSubAccess) => WSubAccess(e.exp,e.index,e.tpe,gender(e.exp))
+ case (e) => e
+ }
+ }
+ s match {
+ case (s:DefWire) => { genders += (s.name -> BIGENDER); s }
+ case (s:DefRegister) => { genders += (s.name -> BIGENDER); s }
+ case (s:WDefInstance) => { genders += (s.name -> MALE); s }
+ case (s:DefMemory) => { genders += (s.name -> MALE); s }
+ case (s:DefPoison) => { genders += (s.name -> MALE); s }
+ case (s:DefNode) => { genders += (s.name -> MALE); s }
+ case (s:IsInvalid) => {
+ val n = get_size(tpe(s.exp))
+ val invalids = ArrayBuffer[Stmt]()
+ val exps = create_exps(s.exp)
+ for (i <- 0 until n) {
+ val expx = exps(i)
+ val gexpx = set_gender(expx)
+ gender(gexpx) match {
+ case BIGENDER => invalids += IsInvalid(s.info,expx)
+ case FEMALE => invalids += IsInvalid(s.info,expx)
+ case _ => {}
+ }
+ }
+ if (invalids.length == 0) {
+ Empty()
+ } else if (invalids.length == 1) {
+ invalids(0)
+ } else Begin(invalids)
+ }
+ case (s:Connect) => {
+ val n = get_size(tpe(s.loc))
+ val connects = ArrayBuffer[Stmt]()
+ val locs = create_exps(s.loc)
+ val exps = create_exps(s.exp)
+ for (i <- 0 until n) {
+ val locx = locs(i)
+ val expx = exps(i)
+ val sx = get_flip(tpe(s.loc),i,DEFAULT) match {
+ case DEFAULT => Connect(s.info,locx,expx)
+ case REVERSE => Connect(s.info,expx,locx)
+ }
+ connects += sx
+ }
+ Begin(connects)
+ }
+ case (s:BulkConnect) => {
+ val ls = get_valid_points(tpe(s.loc),tpe(s.exp),DEFAULT,DEFAULT)
+ val connects = ArrayBuffer[Stmt]()
+ val locs = create_exps(s.loc)
+ val exps = create_exps(s.exp)
+ ls.foreach { x => {
+ val locx = locs(x._1)
+ val expx = exps(x._2)
+ val sx = get_flip(tpe(s.loc),x._1,DEFAULT) match {
+ case DEFAULT => Connect(s.info,locx,expx)
+ case REVERSE => Connect(s.info,expx,locx)
+ }
+ connects += sx
+ }}
+ Begin(connects)
+ }
+ case (s) => sMap(expand_s _,s)
+ }
+ }
+
+ m.ports.foreach { p => genders += (p.name -> to_gender(p.direction)) }
+ InModule(m.info,m.name,m.ports,expand_s(m.body))
+ }
+
+ val modulesx = c.modules.map {
+ m => {
+ m match {
+ case (m:ExModule) => m
+ case (m:InModule) => expand_connects(m)
+ }
+ }
+ }
+ Circuit(c.info,modulesx,c.main)
+ }
}
-object RemoveAccesses extends Pass with StanzaPass {
- def name = "Remove Accesses"
- def run (c:Circuit): Circuit = stanzaPass(c, "remove-accesses")
+case class Location(base:Expression,guard:Expression)
+object RemoveAccesses extends Pass {
+ private var mname = ""
+ def name = "Remove Accesses"
+ def get_locations (e:Expression) : Seq[Location] = {
+ e match {
+ case (e:WRef) => create_exps(e).map(Location(_,one))
+ case (e:WSubIndex) => {
+ val ls = get_locations(e.exp)
+ val start = get_point(e)
+ val end = start + get_size(tpe(e))
+ val stride = get_size(tpe(e.exp))
+ val lsx = ArrayBuffer[Location]()
+ var c = 0
+ for (i <- 0 until ls.size) {
+ if (((i % stride) >= start) & ((i % stride) < end)) {
+ lsx += ls(i)
+ }
+ }
+ lsx
+ }
+ case (e:WSubField) => {
+ val ls = get_locations(e.exp)
+ val start = get_point(e)
+ val end = start + get_size(tpe(e))
+ val stride = get_size(tpe(e.exp))
+ val lsx = ArrayBuffer[Location]()
+ var c = 0
+ for (i <- 0 until ls.size) {
+ if (((i % stride) >= start) & ((i % stride) < end)) { lsx += ls(i) }
+ }
+ lsx
+ }
+ case (e:WSubAccess) => {
+ val ls = get_locations(e.exp)
+ val stride = get_size(tpe(e))
+ val wrap = tpe(e.exp).asInstanceOf[VectorType].size
+ val lsx = ArrayBuffer[Location]()
+ var c = 0
+ for (i <- 0 until ls.size) {
+ if ((c % wrap) == 0) { c = 0 }
+ val basex = ls(i).base
+ val guardx = AND(ls(i).guard,EQV(uint(c),e.index))
+ lsx += Location(basex,guardx)
+ if ((i + 1) % stride == 0) {
+ c = c + 1
+ }
+ }
+ lsx
+ }
+ }
+ }
+ def has_access (e:Expression) : Boolean = {
+ var ret:Boolean = false
+ def rec_has_access (e:Expression) : Expression = {
+ e match {
+ case (e:WSubAccess) => { ret = true; e }
+ case (e) => eMap(rec_has_access _,e)
+ }
+ }
+ rec_has_access(e)
+ ret
+ }
+ def run (c:Circuit): Circuit = {
+ def remove_m (m:InModule) : InModule = {
+ val sh = sym_hash
+ mname = m.name
+ def remove_s (s:Stmt) : Stmt = {
+ val stmts = ArrayBuffer[Stmt]()
+ def create_temp (e:Expression) : Expression = {
+ val n = firrtl_gensym("GEN",sh)
+ stmts += DefWire(info(s),n,tpe(e))
+ WRef(n,tpe(e),kind(e),gender(e))
+ }
+ def remove_e (e:Expression) : Expression = { //NOT RECURSIVE (except primops) INTENTIONALLY!
+ e match {
+ case (e:DoPrim) => eMap(remove_e,e)
+ case (e:Mux) => eMap(remove_e,e)
+ case (e:ValidIf) => eMap(remove_e,e)
+ case (e:SIntValue) => e
+ case (e:UIntValue) => e
+ case e => {
+ if (has_access(e)) {
+ val rs = get_locations(e)
+ val foo = rs.find(x => {x.guard != one})
+ foo match {
+ case None => error("Shouldn't be here")
+ case foo:Some[Location] => {
+ val temp = create_temp(e)
+ val temps = create_exps(temp)
+ def get_temp (i:Int) = temps(i % temps.size)
+ (rs,0 until rs.size).zipped.foreach {
+ (x,i) => {
+ if (i < temps.size) {
+ stmts += Connect(info(s),get_temp(i),x.base)
+ } else {
+ stmts += Conditionally(info(s),x.guard,Connect(info(s),get_temp(i),x.base),Empty())
+ }
+ }
+ }
+ temp
+ }
+ }
+ } else { e}
+ }
+ }
+ }
+
+ val sx = s match {
+ case (s:Connect) => {
+ if (has_access(s.loc)) {
+ val ls = get_locations(s.loc)
+ val locx =
+ if (ls.size == 1 & ls(0).guard == one) s.loc
+ else {
+ val temp = create_temp(s.loc)
+ for (x <- ls) { stmts += Conditionally(s.info,x.guard,Connect(s.info,x.base,temp),Empty()) }
+ temp
+ }
+ Connect(s.info,locx,remove_e(s.exp))
+ } else { Connect(s.info,s.loc,remove_e(s.exp)) }
+ }
+ case (s) => sMap(remove_s,eMap(remove_e,s))
+ }
+ stmts += sx
+ if (stmts.size != 1) Begin(stmts) else stmts(0)
+ }
+ InModule(m.info,m.name,m.ports,remove_s(m.body))
+ }
+
+ val modulesx = c.modules.map{
+ m => {
+ m match {
+ case (m:ExModule) => m
+ case (m:InModule) => remove_m(m)
+ }
+ }
+ }
+ Circuit(c.info,modulesx,c.main)
+ }
}
object ExpandWhens extends Pass with StanzaPass {
@@ -130,6 +637,11 @@ object ConstProp extends Pass with StanzaPass {
def run (c:Circuit): Circuit = stanzaPass(c, "const-prop")
}
+object LoToVerilog extends Pass with StanzaPass {
+ def name = "Lo To Verilog"
+ def run (c:Circuit): Circuit = stanzaPass(c, "lo-to-verilog")
+}
+
object VerilogWrap extends Pass with StanzaPass {
def name = "Verilog Wrap"
def run (c:Circuit): Circuit = stanzaPass(c, "verilog-wrap")