diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/Passes.scala | 165 | ||||
| -rw-r--r-- | src/main/scala/firrtl/Utils.scala | 346 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 2 |
3 files changed, 501 insertions, 12 deletions
diff --git a/src/main/scala/firrtl/Passes.scala b/src/main/scala/firrtl/Passes.scala index b0b93db9..67fefde6 100644 --- a/src/main/scala/firrtl/Passes.scala +++ b/src/main/scala/firrtl/Passes.scala @@ -9,9 +9,12 @@ 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 { + // TODO Perhaps we should get rid of Logger since this map would be nice ////private val defaultLogger = Logger() //private def mapNameToPass = Map[String, Circuit => Circuit] ( @@ -43,14 +46,16 @@ object Passes extends LazyLogging { inferTypes _, resolveGenders _, pullMuxes _, - expandConnects _) + expandConnects _, + removeAccesses _) val names = Seq( "To Working IR", "Resolve Kinds", "Infer Types", "Resolve Genders", "Pull Muxes", - "Expand Connects") + "Expand Connects", + "Remove Accesses") var c_BANG = c (names, passes).zipped.foreach { (n,p) => { @@ -145,7 +150,7 @@ object Passes extends LazyLogging { // ------------------ Utils ------------------------- - val width_name_hash = Map[String,Int]() + 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) @@ -548,6 +553,160 @@ object Passes extends LazyLogging { } Circuit(c.info,modulesx,c.main) } + // =============================================== + + + + // ============ 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 3fdc9b63..4625ec63 100644 --- a/src/main/scala/firrtl/Utils.scala +++ b/src/main/scala/firrtl/Utils.scala @@ -15,6 +15,7 @@ import scala.collection.mutable.StringBuilder import java.io.PrintWriter import PrimOps._ import scala.collection.mutable.ArrayBuffer +import scala.collection.mutable.HashMap //import scala.reflect.runtime.universe._ object Utils { @@ -23,27 +24,58 @@ object Utils { private type FlagMap = Map[String, Boolean] private val FlagMap = Map[String, Boolean]().withDefaultValue(false) - val lnOf2 = scala.math.log(2) // natural log of 2 def ceil_log2(x: BigInt): BigInt = (x-1).bitLength + def ceil_log2(x: Int): Int = scala.math.ceil(scala.math.log(x) / scala.math.log(2)).toInt val gen_names = Map[String,Int]() val delin = "_" + val sym_hash = HashMap[String,Int]() def BoolType () = { UIntType(IntWidth(1)) } - def firrtl_gensym (s:String):String = { - firrtl_gensym(s,Map[String,Int]()) + val one = UIntValue(BigInt(1),IntWidth(1)) + val zero = UIntValue(BigInt(0),IntWidth(1)) + def uint (i:Int) : UIntValue = { + val num_bits = req_num_bits(i) + val w = IntWidth(scala.math.max(1,num_bits - 1)) + UIntValue(BigInt(i),w) } - def firrtl_gensym (sym_hash:Map[String,Int]):String = { - firrtl_gensym("gen",sym_hash) + def req_num_bits (i: Int) : Int = { + val ix = if (i < 0) ((-1 * i) - 1) else i + ceil_log2(ix + 1) + 1 } - def firrtl_gensym (s:String,sym_hash:Map[String,Int]):String = { + def firrtl_gensym (s:String):String = { firrtl_gensym(s,HashMap[String,Int]()) } + def firrtl_gensym (sym_hash:HashMap[String,Int]):String = { firrtl_gensym("gen",sym_hash) } + def firrtl_gensym (s:String,sym_hash:HashMap[String,Int]):String = { if (sym_hash contains s) { val num = sym_hash(s) + 1 - sym_hash + (s -> num) + sym_hash += (s -> num) (s + delin + num) } else { - sym_hash + (s -> 0) + sym_hash += (s -> 0) (s + delin + 0) } } + def AND (e1:Expression,e2:Expression) : Expression = { + if (e1 == e2) e1 + else if ((e1 == zero) | (e2 == zero)) zero + else if (e1 == one) e2 + else if (e2 == one) e1 + else DoPrim(AND_OP,Seq(e1,e2),Seq(),UIntType(IntWidth(1))) + } + + def OR (e1:Expression,e2:Expression) : Expression = { + if (e1 == e2) e1 + else if ((e1 == one) | (e2 == one)) one + else if (e1 == zero) e2 + else if (e2 == zero) e1 + else DoPrim(OR_OP,Seq(e1,e2),Seq(),UIntType(IntWidth(1))) + } + + def EQV (e1:Expression,e2:Expression) : Expression = { + DoPrim(EQUAL_OP,Seq(e1,e2),Seq(),tpe(e1)) + } + + //def MUX (p:Expression,e1:Expression,e2:Expression) : Expression = { + // Mux(p,e1,e2,mux_type(tpe(e1),tpe(e2))) + //} def create_mask (dt:Type) : Type = { dt match { @@ -276,6 +308,25 @@ object Utils { // =========== ACCESSORS ========= + def info (s:Stmt) : Info = { + s match { + case s:DefWire => s.info + case s:DefPoison => s.info + case s:DefRegister => s.info + case s:DefInstance => s.info + case s:WDefInstance => s.info + case s:DefMemory => s.info + case s:DefNode => s.info + case s:Conditionally => s.info + case s:BulkConnect => s.info + case s:Connect => s.info + case s:IsInvalid => s.info + case s:Stop => s.info + case s:Print => s.info + case s:Begin => NoInfo + case s:Empty => NoInfo + } + } def gender (e:Expression) : Gender = { e match { case e:WRef => gender(e) @@ -444,6 +495,56 @@ object Utils { } } val ONE = IntWidth(1) + //def digits (s:String) : Boolean { + // val digits = "0123456789" + // var yes:Boolean = true + // for (c <- s) { + // if !digits.contains(c) : yes = false + // } + // yes + //} + //def generated (s:String) : Option[Int] = { + // (1 until s.length() - 1).find{ + // i => { + // val sub = s.substring(i + 1) + // s.substring(i,i).equals("_") & digits(sub) & !s.substring(i - 1,i-1).equals("_") + // } + // } + //} + //def get-sym-hash (m:InModule) : HashMap[String,Int] = { get-sym-hash(m,Seq()) } + //def get-sym-hash (m:InModule,keywords:Seq[String]) : HashMap[String,Int] = { + // val sym-hash = HashMap[String,Int]() + // for (k <- keywords) { sym-hash += (k -> 0) } + // def add-name (s:String) : String = { + // val sx = to-string(s) + // val ix = generated(sx) + // ix match { + // case (i:False) => { + // if (sym_hash.contains(s)) { + // val num = sym-hash(s) + // sym-hash += (s -> max(num,0)) + // } else { + // sym-hash += (s -> 0) + // } + // } + // case (i:Int) => { + // val name = sx.substring(0,i) + // val digit = to-int(substring(sx,i + 1)) + // if key?(sym-hash,name) : + // val num = sym-hash[name] + // sym-hash[name] = max(num,digit) + // else : + // sym-hash[name] = digit + // } + // s + // + // defn to-port (p:Port) : add-name(name(p)) + // defn to-stmt (s:Stmt) -> Stmt : + // map{to-stmt,_} $ map(add-name,s) + // + // to-stmt(body(m)) + // map(to-port,ports(m)) + // sym-hash //private trait StmtMagnet { // def map(stmt: Stmt): Stmt //} @@ -708,4 +809,233 @@ object Utils { private def unindent() { require(indentLevel > 0); indentLevel -= 1 } private def withIndent(f: => Unit) { indent(); f; unindent() } + val v_keywords = Map[String,Boolean]() + + ("alias" -> true) + + ("always" -> true) + + ("always_comb" -> true) + + ("always_ff" -> true) + + ("always_latch" -> true) + + ("and" -> true) + + ("assert" -> true) + + ("assign" -> true) + + ("assume" -> true) + + ("attribute" -> true) + + ("automatic" -> true) + + ("before" -> true) + + ("begin" -> true) + + ("bind" -> true) + + ("bins" -> true) + + ("binsof" -> true) + + ("bit" -> true) + + ("break" -> true) + + ("buf" -> true) + + ("bufif0" -> true) + + ("bufif1" -> true) + + ("byte" -> true) + + ("case" -> true) + + ("casex" -> true) + + ("casez" -> true) + + ("cell" -> true) + + ("chandle" -> true) + + ("class" -> true) + + ("clocking" -> true) + + ("cmos" -> true) + + ("config" -> true) + + ("const" -> true) + + ("constraint" -> true) + + ("context" -> true) + + ("continue" -> true) + + ("cover" -> true) + + ("covergroup" -> true) + + ("coverpoint" -> true) + + ("cross" -> true) + + ("deassign" -> true) + + ("default" -> true) + + ("defparam" -> true) + + ("design" -> true) + + ("disable" -> true) + + ("dist" -> true) + + ("do" -> true) + + ("edge" -> true) + + ("else" -> true) + + ("end" -> true) + + ("endattribute" -> true) + + ("endcase" -> true) + + ("endclass" -> true) + + ("endclocking" -> true) + + ("endconfig" -> true) + + ("endfunction" -> true) + + ("endgenerate" -> true) + + ("endgroup" -> true) + + ("endinterface" -> true) + + ("endmodule" -> true) + + ("endpackage" -> true) + + ("endprimitive" -> true) + + ("endprogram" -> true) + + ("endproperty" -> true) + + ("endspecify" -> true) + + ("endsequence" -> true) + + ("endtable" -> true) + + ("endtask" -> true) + + ("enum" -> true) + + ("event" -> true) + + ("expect" -> true) + + ("export" -> true) + + ("extends" -> true) + + ("extern" -> true) + + ("final" -> true) + + ("first_match" -> true) + + ("for" -> true) + + ("force" -> true) + + ("foreach" -> true) + + ("forever" -> true) + + ("fork" -> true) + + ("forkjoin" -> true) + + ("function" -> true) + + ("generate" -> true) + + ("genvar" -> true) + + ("highz0" -> true) + + ("highz1" -> true) + + ("if" -> true) + + ("iff" -> true) + + ("ifnone" -> true) + + ("ignore_bins" -> true) + + ("illegal_bins" -> true) + + ("import" -> true) + + ("incdir" -> true) + + ("include" -> true) + + ("initial" -> true) + + ("initvar" -> true) + + ("inout" -> true) + + ("input" -> true) + + ("inside" -> true) + + ("instance" -> true) + + ("int" -> true) + + ("integer" -> true) + + ("interconnect" -> true) + + ("interface" -> true) + + ("intersect" -> true) + + ("join" -> true) + + ("join_any" -> true) + + ("join_none" -> true) + + ("large" -> true) + + ("liblist" -> true) + + ("library" -> true) + + ("local" -> true) + + ("localparam" -> true) + + ("logic" -> true) + + ("longint" -> true) + + ("macromodule" -> true) + + ("matches" -> true) + + ("medium" -> true) + + ("modport" -> true) + + ("module" -> true) + + ("nand" -> true) + + ("negedge" -> true) + + ("new" -> true) + + ("nmos" -> true) + + ("nor" -> true) + + ("noshowcancelled" -> true) + + ("not" -> true) + + ("notif0" -> true) + + ("notif1" -> true) + + ("null" -> true) + + ("or" -> true) + + ("output" -> true) + + ("package" -> true) + + ("packed" -> true) + + ("parameter" -> true) + + ("pmos" -> true) + + ("posedge" -> true) + + ("primitive" -> true) + + ("priority" -> true) + + ("program" -> true) + + ("property" -> true) + + ("protected" -> true) + + ("pull0" -> true) + + ("pull1" -> true) + + ("pulldown" -> true) + + ("pullup" -> true) + + ("pulsestyle_onevent" -> true) + + ("pulsestyle_ondetect" -> true) + + ("pure" -> true) + + ("rand" -> true) + + ("randc" -> true) + + ("randcase" -> true) + + ("randsequence" -> true) + + ("rcmos" -> true) + + ("real" -> true) + + ("realtime" -> true) + + ("ref" -> true) + + ("reg" -> true) + + ("release" -> true) + + ("repeat" -> true) + + ("return" -> true) + + ("rnmos" -> true) + + ("rpmos" -> true) + + ("rtran" -> true) + + ("rtranif0" -> true) + + ("rtranif1" -> true) + + ("scalared" -> true) + + ("sequence" -> true) + + ("shortint" -> true) + + ("shortreal" -> true) + + ("showcancelled" -> true) + + ("signed" -> true) + + ("small" -> true) + + ("solve" -> true) + + ("specify" -> true) + + ("specparam" -> true) + + ("static" -> true) + + ("strength" -> true) + + ("string" -> true) + + ("strong0" -> true) + + ("strong1" -> true) + + ("struct" -> true) + + ("super" -> true) + + ("supply0" -> true) + + ("supply1" -> true) + + ("table" -> true) + + ("tagged" -> true) + + ("task" -> true) + + ("this" -> true) + + ("throughout" -> true) + + ("time" -> true) + + ("timeprecision" -> true) + + ("timeunit" -> true) + + ("tran" -> true) + + ("tranif0" -> true) + + ("tranif1" -> true) + + ("tri" -> true) + + ("tri0" -> true) + + ("tri1" -> true) + + ("triand" -> true) + + ("trior" -> true) + + ("trireg" -> true) + + ("type" -> true) + + ("typedef" -> true) + + ("union" -> true) + + ("unique" -> true) + + ("unsigned" -> true) + + ("use" -> true) + + ("var" -> true) + + ("vectored" -> true) + + ("virtual" -> true) + + ("void" -> true) + + ("wait" -> true) + + ("wait_order" -> true) + + ("wand" -> true) + + ("weak0" -> true) + + ("weak1" -> true) + + ("while" -> true) + + ("wildcard" -> true) + + ("wire" -> true) + + ("with" -> true) + + ("within" -> true) + + ("wor" -> true) + + ("xnor" -> true) + + ("xor" -> true) + + ("SYNTHESIS" -> true) + + ("PRINTF_COND" -> true) + + ("VCS" -> true) } diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index a39c1287..3e90b502 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -1682,7 +1682,7 @@ defn resolve (c:Circuit) -> Circuit : check-types $ infer-types $ resolve-kinds $ - to-working-ir $ c + to-working-ir(c) ;;================= Inline Instances ======================== ;; Inlines instances. Assumes module with same name as the |
