aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/errors.stanza504
-rw-r--r--src/main/stanza/firrtl-ir.stanza20
-rw-r--r--src/main/stanza/firrtl-test-main.stanza1
-rw-r--r--src/main/stanza/ir-parser.stanza30
-rw-r--r--src/main/stanza/ir-utils.stanza38
-rw-r--r--src/main/stanza/passes.stanza324
6 files changed, 649 insertions, 268 deletions
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index b0dbca68..30414afd 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -7,100 +7,95 @@ defpackage firrtl/errors :
import firrtl/passes
import firrtl-main
+; TODO
+; make sure it compiles, write tests, look over code to make sure its right
;========== ALL CHECKS =================
-;CAUGHT IN PARSER
-; No nested modules <- parser
-; Only modules in circuit (no statements or expressions) <- parser
-
-;CAUGHT in HIGH FORM CHECK
-; Unique names per module
-; No name can be a prefix of any other name.
-; Can only connect to a Ref or Subfield or Index
-; UInt only has positive ints
-; all references are declared
-; mems cannot be a bundle with flips
-; cannot connect to Register or ReadPort
-
-;AFTER KIND RESOLUTION
-; Cannot connect directly to a mem ever
-; onreset can only handle a register
-
-;AFTER TYPE INFERENCE
-; expression in pad must be a ground type
-; Subfields are only on bundles, before type inference <- need to not error, just do unknown-type
-; node's value cannot be a bundle with a flip in it
-; 2nd arg in dshr/l must be UInt
-; pred in conditionally must be of type UInt
-; Type checking
+;PARSER CHECK
+; * No nested modules <- parser
+; * Only modules in circuit (no statements or expressions) <- parser
+; * Module must be a reference in inst declaration
+
+;AFTER GENDER INFERENCE
+; o Nodes always male
+; o Accessors only have one gender, unless rdwr
+; o output/input only one gender
+; o correctly check for the base bundle
;AFTER WIDTH INFERENCE
-; No names
-; No Unknowns
-; All widths are positive
-; Pad's width is greater than value's width
-; pad's width is greater than value's width
+; o No names
+; o No Unknowns
+; o All widths are positive
+; o Pad's width is greater than value's width
+; o pad's width is greater than value's width
+; o widths are large enough to contain value
;AFTER LOWERING
-; All things connect to once
-
-; ??
-; No combinational loops
-; cannot connect to a pad, or a register. only connct to a reference
+; o All things connect to once
+; o no reg
+; o no accessors
-definterface HighFormException <: Exception
-defn HighFormException (s:String) :
- new HighFormException :
- defmethod print (o:OutputStream, this) :
- print(o, s)
+;AFTER ??????
+; o No combinational loops
+; o cannot connect to a pad, or a register. only connct to a reference
-defn HighFormExceptions (xs:Streamable<HighFormException>) :
- HighFormException(string-join(xs, "\n"))
+;================= High Form Check ==========================
+; * Subexps of Subfield and Index can only be subfields, index, or refs
+; * Can only connect to a Ref or Subfield or Index or WritePort
+; * A module has the same name as main of circuit
+; * mems cannot be a bundle with flips
+; * instance module must have the same name as a defined module
+; * reset must be UInt<1>
+; * Unique names per module
+; * No name can be a prefix of any other name.
+; * all references are declared
+; * UInt only has positive ints
-defn NotUnique (info:FileInfo|False, name:Symbol) :
- HighFormException $ string-join $
+;----------------- Errors ------------------------
+defn NotUnique (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
[info ": Reference " name " does not have a unique name."]
-defn IsPrefix (info:FileInfo|False, name1:Symbol, name2:Symbol) :
- HighFormException $ string-join $
+defn IsPrefix (info:FileInfo, name1:Symbol, name2:Symbol) :
+ PassException $ string-join $
[info ": Reference " name1 " and " name2 " share a prefix."]
-defn InvalidLOC (info:FileInfo|False) :
- HighFormException $ string-join $
+defn InvalidLOC (info:FileInfo) :
+ PassException $ string-join $
[info ": Invalid connect to an expression that is not a reference or a WritePort."]
-defn NegUInt (info:FileInfo|False) :
- HighFormException $ string-join $
- [info ": UInt has a negative value."]
+defn NegUInt (info:FileInfo) :
+ PassException $ string-join $
+ [info ": UIntValue cannot be negative."]
-defn UndeclaredReference (info:FileInfo|False, name:Symbol) :
- HighFormException $ string-join $
+defn UndeclaredReference (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
[info ": Reference " name " is not declared."]
-defn MemWithFlip (info:FileInfo|False, name:Symbol) :
- HighFormException $ string-join $
+defn MemWithFlip (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
[info ": Memory " name " cannot be a bundle type with flips."]
-defn InvalidSubfield (info:FileInfo|False, name:Symbol) :
- HighFormException $ string-join $
+defn InvalidSubfield (info:FileInfo) :
+ PassException $ string-join $
[info ": Invalid subfield access to non-reference."]
-defn InvalidIndex (info:FileInfo|False, name:Symbol) :
- HighFormException $ string-join $
+defn InvalidIndex (info:FileInfo) :
+ PassException $ string-join $
[info ": Invalid index access to non-reference."]
-defn NoTopModule (info:FileInfo|False, name:Symbol) :
- HighFormException $ string-join $
+defn NoTopModule (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
[info ": A single module must be named " name "."]
-defn InstNotModule (info:FileInfo|False, name:Symbol) :
- HighFormException $ string-join $
- [info ": The referenced module in the instance declaration, " name ", is not a reference."]
+defn ModuleNotDefined (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": Module " name " is not defined."]
-defn ModuleNotDefined (info:FileInfo|False, name:Symbol) :
- HighFormException $ string-join $
- [info ": The referenced module in the instance declaration, " name ", is not defined."]
+defn WrongReset (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": Module " name " has a reset that is not of type UInt<1>."]
-;================ Check Helper Functions ==============
+;---------------- Helper Functions --------------
defn has-flip? (t:Type) -> True|False :
var has? = false
defn find-flip (t:Type) -> Type :
@@ -136,46 +131,85 @@ defn is-prefix? (s1:Symbol,s2:Symbol) -> True|False :
if s1*[length(s2*)] != '$' : is? = false
if length(s1*) < length(s2*) :
if s2*[length(s1*)] != '$' : is? = false
+ if length(s1*) == length(s2*) :
+ is? = false
is?
-;================= High Form Check ==========================
-;CAUGHT in HIGH FORM CHECK
-; o Unique names per module
-; o No name can be a prefix of any other name.
-; o Can only connect to a Ref or Subfield or Index
-; o UInt only has positive ints
-; o all references are declared
-; o cannot connect to Register or ReadPort
-; * A module has the same name as main of circuit
-; * mems cannot be a bundle with flips
-; o instance module must be a reference with same name as defined module
-; o reset must be UInt<1>
-
+;--------------- Check High Form Pass -------------------
public defn check-high-form (c:Circuit) -> Circuit :
- val errors = Vector<HighFormException>()
+ val errors = Vector<PassException>()
+
+ defn check-valid-loc (info:FileInfo,e:Expression) -> False :
+ match(e) :
+ (e:UIntValue|SIntValue|DoPrim|ReadPort|Register|Pad) :
+ add(errors,InvalidLOC(info))
+ (e) : false
+
+ defn check-high-form-e (info:FileInfo,e:Expression,names:Vector<Symbol>) -> Expression :
+ match(map(check-high-form-e{info,_,names},e)) :
+ (e:Ref) :
+ if not contains?(name(e),names) :
+ add(errors,UndeclaredReference(info,name(e)))
+ (e:Subfield) :
+ match(exp(e)) :
+ (e:Ref|Subfield|Index) : false
+ (e) : add(errors,InvalidSubfield(info))
+ (e:Index) :
+ match(exp(e)) :
+ (e:Ref|Subfield|Index) : false
+ (e) : add(errors,InvalidIndex(info))
+ (e:UIntValue) :
+ if value(e) < 0 :
+ add(errors,NegUInt(info))
+ (e) : false
+ e
defn check-high-form-s (s:Stmt,names:Vector<Symbol>) -> Stmt :
- defn check-name (info:FileInfo|False,name:Symbol) -> False :
+ defn check-name (info:FileInfo,name:Symbol) -> False :
if contains?(name,names) : add(errors,NotUnique(info,name))
val prefix = is-prefix?(name,names)
if prefix typeof Symbol : add(errors,IsPrefix(info,name,prefix as Symbol))
map{check-high-form-s{_,names},_} $ {
- match(s) :
- (s:DefWire|DefRegister) : check-name(info!(s),name(s))
+ match(map(check-high-form-e{info(s),_,names},s)) :
+ (s:DefWire|DefRegister) :
+ check-name(info(s),name(s))
+ add(names,name(s))
(s:DefMemory) :
- check-name(info!(s),name(s))
- if has-flip?(type(s)) : add(errors, MemWithFlip(info!(s), name(s)))
+ check-name(info(s),name(s))
+ add(names,name(s))
+ if has-flip?(type(s)) : add(errors, MemWithFlip(info(s), name(s)))
(s:DefInstance) :
- if not (module(s) typeof Ref) : add(errors, InstNotModule(info!(s),name(s)))
- else :
- if not contains?(name(module(s) as Ref),map(name,modules(c))) :
- add(errors, ModuleNotDefined(info!(s),name(s)))
+ if not contains?(name(module(s) as Ref),map(name,modules(c))) :
+ add(errors, ModuleNotDefined(info(s),name(module(s) as Ref)))
+ add(names,name(s))
+ (s:DefNode) :
+ add(names,name(s))
+ (s:DefAccessor) :
+ add(names,name(s))
+ (s:Connect) :
+ check-valid-loc(info(s),loc(s))
(s) : false
s }()
defn check-high-form-m (m:Module) -> False :
val names = Vector<Symbol>()
+ for m in modules(c) do :
+ add(names,name(m))
+ for p in ports(m) do :
+ add(names,name(p))
+ if name(p) == `reset :
+ if direction(p) == OUTPUT :
+ add(errors,WrongReset(info!(m),name(m)))
+ else :
+ if type(p) typeof UIntType :
+ if width(type(p) as UIntType) != IntWidth(1) :
+ add(errors,WrongReset(info!(m),name(m)))
+ else :
+ add(errors,WrongReset(info!(m),name(m)))
+
+
+ add(names,`reset)
check-high-form-s(body(m),names)
false
@@ -184,7 +218,295 @@ public defn check-high-form (c:Circuit) -> Circuit :
if name(m) == main(c) : number-top-m = number-top-m + 1
check-high-form-m(m)
if number-top-m != 1 : add(errors,NoTopModule(info!(c),main(c)))
- throw(HighFormExceptions(errors)) when not empty?(errors)
+ throw(PassExceptions(errors)) when not empty?(errors)
+ c
+
+;================= KIND CHECK ==========================
+; o Cannot connect directly to a mem ever
+; o onreset can only handle a register
+; o Cannot use a mem in anything except an accessor, Readport, or Writeport
+
+;----------------- Errors ---------------------
+defn NotMem (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": Reference " name " must be a mem."]
+
+defn IsMem (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": Reference " name " cannot be a mem."]
+
+defn OnResetNotReg (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": Illegal on-reset to non-reg reference " name "."]
+
+;----------------- Check Kinds Pass ---------------------
+; I may have been overeager in looking for places where mems can't be, as mems are guaranteed to have a vector
+; type, and this will get caught in the type check pass
+public defn check-kinds (c:Circuit) -> Circuit :
+ val errors = Vector<PassException>()
+ defn check-not-mem (info:FileInfo,e:Expression) -> False :
+ do(check-not-mem{info,_},e)
+ match(e) :
+ (e:WRef) : if kind(e) == MemKind() : add(errors,IsMem(info,name(e)))
+ (e:WSubfield) : check-not-mem(info,exp(e))
+ (e:WIndex) : check-not-mem(info,exp(e))
+ (e) : false
+ defn check-is-reg (info:FileInfo,e:Expression) -> False :
+ do(check-is-reg{info,_},e)
+ match(e) :
+ (e:WRef) : if kind(e) != RegKind() : add(errors,OnResetNotReg(info,name(e)))
+ (e:WSubfield) : check-is-reg(info,exp(e))
+ (e:WIndex) : check-is-reg(info,exp(e))
+ (e) : false
+ defn check-is-mem (info:FileInfo,e:Expression) -> False :
+ do(check-is-mem{info,_},e)
+ match(e) :
+ (e:WRef) : if kind(e) != MemKind() : add(errors,NotMem(info,name(e)))
+ (e:WSubfield) : check-is-mem(info,exp(e))
+ (e:WIndex) : check-is-mem(info,exp(e))
+ (e) : false
+
+ defn check-kinds-e (info:FileInfo,e:Expression) -> False :
+ do(check-kinds-e{info,_},e)
+ match(e) :
+ (e:ReadPort) :
+ check-is-mem(info,mem(e))
+ check-not-mem(info,index(e))
+ check-not-mem(info,enable(e))
+ (e:WritePort) :
+ check-is-mem(info,mem(e))
+ check-not-mem(info,index(e))
+ check-not-mem(info,enable(e))
+ (e:Pad) :
+ check-not-mem(info,value(e))
+ (e) : do(check-not-mem{info,_},e)
+ defn check-kinds-s (s:Stmt) -> False :
+ do(check-kinds-e{info(s),_:Expression},s)
+ match(s) :
+ (s:DefNode) : check-not-mem(info(s),value(s))
+ (s:DefAccessor) : check-not-mem(info(s),index(s))
+ (s:Conditionally) : check-not-mem(info(s),pred(s))
+ (s:Connect) :
+ check-not-mem(info(s),loc(s))
+ check-not-mem(info(s),exp(s))
+ (s:OnReset) :
+ check-is-reg(info(s),loc(s))
+ check-not-mem(info(s),exp(s))
+ (s) : false
+ do(check-kinds-s,s)
+
+ for m in modules(c) do :
+ check-kinds-s(body(m))
+ throw(PassExceptions(errors)) when not empty?(errors)
c
+;==================== CHECK TYPES =====================
+; o expression in pad must be a ground type
+; o Subfields are only on bundles, before type inference <- need to not error, just do unknown-type
+; o Indexes are only on vectors
+; o pred in conditionally must be of type UInt
+; o enable/index in read/writeports must be UInt
+; o node's value cannot be a bundle with a flip in it
+; o := has same types
+; o 2nd arg in dshr/l must be UInt, in general do primops
+
+;----------------- Errors ---------------------
+defn SubfieldNotInBundle (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": Subfield " name " is not in bundle."]
+
+defn SubfieldOnNonBundle (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": Subfield " name " is accessed on a non-bundle."]
+
+defn IndexTooLarge (info:FileInfo, value:Int) :
+ PassException $ string-join $
+ [info ": Index with value " value " is too large."]
+
+defn IndexOnNonVector (info:FileInfo) :
+ PassException $ string-join $
+ [info ": Index illegal on non-vector type."]
+
+defn IndexNotUInt (info:FileInfo) :
+ PassException $ string-join $
+ [info ": Index is not of UIntType."]
+
+defn EnableNotUInt (info:FileInfo) :
+ PassException $ string-join $
+ [info ": Enable is not of UIntType."]
+
+defn PadNotGround (info:FileInfo) :
+ PassException $ string-join $
+ [info ": Illegal Pad on non-ground type."]
+
+defn InvalidConnect (info:FileInfo) :
+ PassException $ string-join $
+ [info ": Type mismatch."]
+
+defn PredNotUInt (info:FileInfo) :
+ PassException $ string-join $
+ [info ": Predicate not a UIntType."]
+
+;---------------- Helper Functions --------------
+defmethod equal? (t1:Type,t2:Type) -> True|False :
+ match(t1,t2) :
+ (t1:UIntType,t2:UIntType) : true
+ (t1:SIntType,t2:SIntType) : true
+ (t1:BundleType,t2:BundleType) :
+ var same? = true
+ for (f1 in fields(t1),f2 in fields(t2)) do :
+ if flip(f1) != flip(f2) : same? = false
+ if name(f1) != name(f2) : same? = false
+ if type(f1) != type(f2) : same? = false
+ same?
+ (t1:VectorType,t2:VectorType) :
+ if type(t1) == type(t2) and size(t1) == size(t2) : true
+ else : false
+ (t1,t2) : false
+
+defn u () -> UIntType : UIntType(UnknownWidth())
+defn s () -> SIntType : SIntType(UnknownWidth())
+
+;----------------- Check Types Pass ---------------------
+public defn check-types (c:Circuit) -> Circuit :
+ val errors = Vector<PassException>()
+ defn check-types-e (info:FileInfo,e:Expression) -> Expression :
+ match(map(check-types-e{info,_},e)) :
+ (e:WRef) : e
+ (e:WSubfield) :
+ match(type(exp(e))) :
+ (t:BundleType) :
+ val ft = for p in fields(t) find : name(p) == name(e)
+ if ft == false : add(errors,SubfieldNotInBundle(info,name(e)))
+ (t) : add(errors,SubfieldOnNonBundle(info,name(e)))
+ (e:WIndex) :
+ match(type(exp(e))) :
+ (t:VectorType) :
+ if value(e) >= size(t) : add(errors,IndexTooLarge(info,value(e)))
+ (t) : add(errors,IndexOnNonVector(info))
+ (e:DoPrim) : false ;check-types-primop(e)
+ (e:ReadPort|WritePort) :
+ if type(index(e)) != u() : add(errors,IndexNotUInt(info))
+ if type(enable(e)) != u() : add(errors,EnableNotUInt(info))
+ (e:Register) :
+ if type(enable(e)) != u() : add(errors,EnableNotUInt(info))
+ (e:Pad) :
+ val t = type(value(e))
+ if not (t == u() or t == s()) : add(errors,PadNotGround(info))
+ (e:UIntValue|SIntValue) : false
+ e
+ defn check-types-s (s:Stmt) -> Stmt :
+ map{check-types-s,_} $
+ match(map(check-types-e{info(s),_},s)) :
+ (s:Connect) :
+ if type(loc(s)) != type(exp(s)) : add(errors,InvalidConnect(info(s)))
+ s
+ (s:OnReset) :
+ if type(loc(s)) != type(exp(s)) : add(errors,InvalidConnect(info(s)))
+ s
+ (s:Conditionally) :
+ if type(pred(s)) != u() : add(errors,PredNotUInt(info(s)))
+ s
+ (s) : s
+
+ for m in modules(c) do :
+ check-types-s(body(m))
+ throw(PassExceptions(errors)) when not empty?(errors)
+ c
+
+;================= GENDER CHECK ==========================
+; o Nodes always male
+; o Accessors only have one gender, unless rdwr
+; o output/input only one gender
+; o correctly check for the base bundle
+
+;----------------- Errors ---------------------
+defn WrongGender (info:FileInfo,expr:Symbol,wrong:Symbol,right:Symbol) :
+ PassException $ string-join $
+ [info ": Expression " expr "has gender " wrong " but requires gender " right "."]
+
+defn UnknownGenders (info:FileInfo,name:Symbol) :
+ PassException $ string-join $
+ [info ": Accessor " name " has an unknown gender."]
+
+;---------------- Helper Functions --------------
+defn dir-to-gender (d:Direction) -> Gender :
+ switch {_ == d} :
+ INPUT : MALE
+ OUTPUT : FEMALE
+
+;----------------- Check Genders Pass ---------------------
+
+public defn check-genders (c:Circuit) -> Circuit :
+ val errors = Vector<PassException>()
+ defn check-gender (info:FileInfo,genders:HashTable<Symbol,Gender>,e:Expression,right:Gender) -> False :
+ val gender = get-gender(e,genders)
+ if gender != right and gender != BI-GENDER:
+ add(errors,WrongGender(info,to-symbol(e),to-symbol(gender),to-symbol(right)))
+
+ defn get-gender (e:Expression,genders:HashTable<Symbol,Gender>) -> Gender :
+ match(e) :
+ (e:WRef) : genders[name(e)]
+ (e:WSubfield) :
+ val f = {_ as Field} $ for f in fields(type(exp(e)) as BundleType) find : name(f) == name(e)
+ get-gender(exp(e),genders) * flip(f)
+ (e:WIndex) : get-gender(exp(e),genders)
+ (e:Pad) : MALE
+ (e:DoPrim) : MALE
+ (e:UIntValue) : MALE
+ (e:SIntValue) : MALE
+ (e:ReadPort) : MALE
+ (e:WritePort) : FEMALE
+ (e:Register) : MALE
+
+ defn check-genders-e (info:FileInfo,e:Expression,genders:HashTable<Symbol,Gender>) -> False :
+ do(check-genders-e{info,_,genders},e)
+ match(e) :
+ (e:WRef) : false
+ (e:WSubfield) : false
+ (e:WIndex) : false
+ (e:Pad) : check-gender(info,genders,value(e),MALE)
+ (e:DoPrim) :
+ for e in args(e) do :
+ check-gender(info,genders,e,MALE)
+ (e:UIntValue) : false
+ (e:SIntValue) : false
+ (e:ReadPort) : do(check-gender{info,genders,_,MALE},e)
+ (e:WritePort) : do(check-gender{info,genders,_,MALE},e)
+ (e:Register) : do(check-gender{info,genders,_,MALE},e)
+
+ defn check-genders-s (s:Stmt,genders:HashTable<Symbol,Gender>) -> False :
+ do(check-genders-e{info(s),_:Expression,genders},s)
+ match(s) :
+ (s:DefWire) : genders[name(s)] = BI-GENDER
+ (s:DefRegister) : genders[name(s)] = BI-GENDER
+ (s:DefNode) :
+ check-gender(info(s),genders,value(s),MALE)
+ genders[name(s)] = MALE
+ (s:DefMemory) : genders[name(s)] = BI-GENDER
+ (s:DefInstance) : genders[name(s)] = MALE
+ (s:WDefAccessor) :
+ if gender(s) == UNKNOWN-GENDER : add(errors,UnknownGenders(info(s),name(s)))
+ check-gender(info(s),genders,index(s),MALE)
+ check-gender(info(s),genders,source(s),gender(s))
+ genders[name(s)] = gender(s)
+ (s:Connect) :
+ check-gender(info(s),genders,loc(s),FEMALE)
+ check-gender(info(s),genders,exp(s),MALE)
+ (s:OnReset) :
+ check-gender(info(s),genders,loc(s),FEMALE)
+ check-gender(info(s),genders,exp(s),MALE)
+ (s:Conditionally) :
+ check-gender(info(s),genders,pred(s),MALE)
+ (s:EmptyStmt) : false
+ (s:Begin) : false
+
+
+ for m in modules(c) do :
+ val genders = HashTable<Symbol,Gender>(symbol-hash)
+ for p in ports(m) do :
+ genders[name(p)] = dir-to-gender(direction(p))
+ check-genders-s(body(m),genders)
+ throw(PassExceptions(errors)) when not empty?(errors)
+ c
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index 67d2c2d9..02145678 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -2,8 +2,8 @@ defpackage firrtl/ir2 :
import core
import verse
-public defmulti info! (x:?) -> False
-public defmethod info! (x:?) : false
+public defmulti info! (x:?) -> FileInfo
+public defmethod info! (x:?) : FileInfo()
public definterface Direction
public val INPUT = new Direction
@@ -176,35 +176,46 @@ public defstruct Pad <: Expression :
type: Type with: (as-method => true)
public definterface Stmt
+public defmulti info (s:Stmt) -> FileInfo
+
public defstruct DefWire <: Stmt : ;LOW
+ info: FileInfo with: (as-method => true)
name: Symbol
type: Type
public defstruct DefRegister <: Stmt :
+ info: FileInfo with: (as-method => true)
name: Symbol
type: Type
public defstruct DefInstance <: Stmt : ;LOW
+ info: FileInfo with: (as-method => true)
name: Symbol
module: Expression
public defstruct DefMemory <: Stmt : ;LOW
+ info: FileInfo with: (as-method => true)
name: Symbol
type: VectorType
public defstruct DefNode <: Stmt : ;LOW
+ info: FileInfo with: (as-method => true)
name: Symbol
value: Expression
public defstruct DefAccessor <: Stmt :
+ info: FileInfo with: (as-method => true)
name: Symbol
source: Expression
index: Expression
public defstruct Conditionally <: Stmt :
+ info: FileInfo with: (as-method => true)
pred: Expression
conseq: Stmt
alt: Stmt
public defstruct Begin <: Stmt : ;LOW
body: List<Stmt>
public defstruct OnReset <: Stmt : ;LOW
+ info: FileInfo with: (as-method => true)
loc: Expression
exp: Expression
public defstruct Connect <: Stmt : ;LOW
+ info: FileInfo with: (as-method => true)
loc: Expression
exp: Expression
public defstruct EmptyStmt <: Stmt ;LOW
@@ -227,17 +238,18 @@ public defstruct Field :
type: Type
public defstruct Port :
+ info: FileInfo
name: Symbol
direction: Direction
type: Type
public defstruct Module :
+ info: FileInfo
name: Symbol
ports: List<Port>
body: Stmt
public defstruct Circuit :
+ info: FileInfo
modules: List<Module>
main: Symbol
-
-
diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza
index ca9bfa33..0f977ebe 100644
--- a/src/main/stanza/firrtl-test-main.stanza
+++ b/src/main/stanza/firrtl-test-main.stanza
@@ -27,6 +27,7 @@ defn set-printvars! (p:List<Char>) :
if contains(p,'g') : PRINT-GENDERS = true
if contains(p,'c') : PRINT-CIRCUITS = true
if contains(p,'d') : PRINT-DEBUG = true
+ if contains(p,'i') : PRINT-INFO = true
;firrtl -i gcd.fir -o gcd.flo -x qabcefghipjklmno -p c
defn main () :
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index 0e339cf3..15cc497a 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -218,7 +218,7 @@ defsyntax firrtl :
circuit = (circuit ?name:#id! #:! (?ms:#module ... ?rest ...)) :
if not empty?(rest) :
FPE(rest, "Expected a module declaration here.")
- Circuit(ms, name)
+ Circuit(first-info(form),ms, name)
circuit != (circuit) :
FPE(form, "Invalid syntax for circuit definition.")
@@ -227,13 +227,13 @@ defsyntax firrtl :
module = (module ?name:#id! #:! (?ps:#port ... ?cs:#stmt ... ?rest ...)) :
if not empty?(rest) :
FPE(rest, "Expected a statement here.")
- Module(name, ps, Begin(cs))
+ Module(first-info(form),name, ps, Begin(cs))
module != (module) :
FPE(form, "Invalid syntax for module definition.")
defrule port :
- port = (input ?name:#id! #:! ?type:#type!) : Port(name, INPUT, type)
- port = (output ?name:#id! #:! ?type:#type!) : Port(name, OUTPUT, type)
+ port = (input ?name:#id! #:! ?type:#type!) : Port(first-info(form),name, INPUT, type)
+ port = (output ?name:#id! #:! ?type:#type!) : Port(first-info(form),name, OUTPUT, type)
;Main Type Productions
defrule type :
@@ -261,16 +261,16 @@ defsyntax firrtl :
;Main Statement Productions
defrule statements :
- stmt = (wire ?name:#id! #:! ?t:#type!) : DefWire(name, t)
- stmt = (reg ?name:#id! #:! ?t:#type!) : DefRegister(name, t)
- stmt = (mem ?name:#id! #:! ?t:#vectype!) : DefMemory(name, t)
- stmt = (inst ?name:#id! #of! ?m:#ref!) : DefInstance(name, m)
- stmt = (node ?name:#id! #=! ?e:#exp!) : DefNode(name, e)
- stmt = (accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(name, s, i)
+ stmt = (wire ?name:#id! #:! ?t:#type!) : DefWire(first-info(form),name, t)
+ stmt = (reg ?name:#id! #:! ?t:#type!) : DefRegister(first-info(form),name, t)
+ stmt = (mem ?name:#id! #:! ?t:#vectype!) : DefMemory(first-info(form),name, t)
+ stmt = (inst ?name:#id! #of! ?m:#ref!) : DefInstance(first-info(form),name, m)
+ stmt = (node ?name:#id! #=! ?e:#exp!) : DefNode(first-info(form),name, e)
+ stmt = (accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name, s, i)
stmt = (?s:#stmt/when) : s
- stmt = (?x:#exp := ?y:#exp!) : Connect(x, y)
- stmt = (on-reset ?x:#exp := ?y:#exp!) : OnReset(x, y)
+ stmt = (?x:#exp := ?y:#exp!) : Connect(first-info(form),x, y)
+ stmt = (on-reset ?x:#exp := ?y:#exp!) : OnReset(first-info(form),x, y)
stmt = ((?s:#stmt ?ss:#stmt ... ?rest ...)) :
if not empty?(rest) :
@@ -281,11 +281,11 @@ defsyntax firrtl :
defrule stmt/when :
stmt/when = (when ?pred:#exp! #:! ?conseq:#stmt! else ?alt:#stmt/when) :
- Conditionally(pred, conseq, alt)
+ Conditionally(first-info(form),pred, conseq, alt)
stmt/when = (when ?pred:#exp! #:! ?conseq:#stmt! else #:! ?alt:#stmt!) :
- Conditionally(pred, conseq, alt)
+ Conditionally(first-info(form),pred, conseq, alt)
stmt/when = (when ?pred:#exp! #:! ?conseq:#stmt!) :
- Conditionally(pred, conseq, EmptyStmt())
+ Conditionally(first-info(form),pred, conseq, EmptyStmt())
;Main Expressions
defrule exp :
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index 6754a8bd..190ad09a 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -5,7 +5,7 @@ defpackage firrtl/ir-utils :
;============== DEBUG STUFF =============================
-public defmulti print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field) -> False
+public defmulti print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field|Module|Circuit) -> False
;============== PRINTERS ===================================
@@ -171,11 +171,13 @@ defmethod print (o:OutputStream, c:Stmt) :
(c:DefInstance) :
print-all(o,["inst " name(c) " of " module(c)])
(c:DefNode) :
- print-all(o,["node " name(c) " = " value(c)])
+ print-all(o,["node " name(c) " = " value(c)])
(c:DefAccessor) :
print-all(o,["accessor " name(c) " = " source(c) "[" index(c) "]"])
(c:Conditionally) :
- println-all(o, ["when " pred(c) " :"])
+ print-all(o, ["when " pred(c) " :"])
+ print-debug(o,c)
+ print(o,"\n")
print(io,conseq(c))
if alt(c) not-typeof EmptyStmt :
print(o, "\nelse :")
@@ -189,7 +191,7 @@ defmethod print (o:OutputStream, c:Stmt) :
print-all(o, ["on-reset " loc(c) " := " exp(c)])
(c:EmptyStmt) :
print(o, "skip")
- print-debug(o,c)
+ if not c typeof Conditionally|Begin|EmptyStmt : print-debug(o,c)
defmethod print (o:OutputStream, t:Type) :
match(t) :
@@ -220,14 +222,18 @@ defmethod print (o:OutputStream, p:Port) :
print-debug(o,p)
defmethod print (o:OutputStream, m:Module) :
- println-all(o, ["module " name(m) " :"])
+ print-all(o, ["module " name(m) " :"])
+ print-debug(o,m)
+ print(o,"\n")
val io = IndentedStream(o, 3)
for p in ports(m) do :
println(io,p)
print(io,body(m))
defmethod print (o:OutputStream, c:Circuit) :
- println-all(o, ["circuit " main(c) " :"])
+ print-all(o, ["circuit " main(c) " :"])
+ print-debug(o,c)
+ print(o,"\n")
val io = IndentedStream(o, 3)
for m in modules(c) do :
println(io, m)
@@ -261,18 +267,18 @@ defmethod map (f: Expression -> Expression, e:Expression) -> Expression :
public defmulti map<?T> (f: Expression -> Expression, c:?T&Stmt) -> T
defmethod map (f: Expression -> Expression, c:Stmt) -> Stmt :
match(c) :
- (c:DefAccessor) : DefAccessor(name(c), f(source(c)), f(index(c)))
- (c:DefNode) : DefNode(name(c), f(value(c)))
- (c:DefInstance) : DefInstance(name(c), f(module(c)))
- (c:Conditionally) : Conditionally(f(pred(c)), conseq(c), alt(c))
- (c:Connect) : Connect(f(loc(c)), f(exp(c)))
- (c:OnReset) : OnReset(f(loc(c)),f(exp(c)))
+ (c:DefAccessor) : DefAccessor(info(c),name(c), f(source(c)), f(index(c)))
+ (c:DefNode) : DefNode(info(c),name(c), f(value(c)))
+ (c:DefInstance) : DefInstance(info(c),name(c), f(module(c)))
+ (c:Conditionally) : Conditionally(info(c),f(pred(c)), conseq(c), alt(c))
+ (c:Connect) : Connect(info(c),f(loc(c)), f(exp(c)))
+ (c:OnReset) : OnReset(info(c),f(loc(c)),f(exp(c)))
(c) : c
public defmulti map<?T> (f: Stmt -> Stmt, c:?T&Stmt) -> T
defmethod map (f: Stmt -> Stmt, c:Stmt) -> Stmt :
match(c) :
- (c:Conditionally) : Conditionally(pred(c), f(conseq(c)), f(alt(c)))
+ (c:Conditionally) : Conditionally(info(c),pred(c), f(conseq(c)), f(alt(c)))
(c:Begin) : Begin(map(f, body(c)))
(c) : c
@@ -307,9 +313,9 @@ defmethod map (f: Type -> Type, c:Expression) -> Expression :
public defmulti map<?T> (f: Type -> Type, c:?T&Stmt) -> T
defmethod map (f: Type -> Type, c:Stmt) -> Stmt :
match(c) :
- (c:DefWire) : DefWire(name(c),f(type(c)))
- (c:DefRegister) : DefRegister(name(c),f(type(c)))
- (c:DefMemory) : DefMemory(name(c),f(type(c)) as VectorType)
+ (c:DefWire) : DefWire(info(c),name(c),f(type(c)))
+ (c:DefRegister) : DefRegister(info(c),name(c),f(type(c)))
+ (c:DefMemory) : DefMemory(info(c),name(c),f(type(c)) as VectorType)
(c) : c
public defmulti mapr<?T> (f: Width -> Width, t:?T&Type) -> T
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index d04f7366..131f0a7b 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -7,27 +7,28 @@ defpackage firrtl/passes :
import firrtl-main
import firrtl/errors
-;============== EXCEPTIONS =================================
-defclass PassException <: Exception
-defn PassException (msg:String) :
- new PassException :
- defmethod print (o:OutputStream, this) :
- print(o, msg)
+;============== Exceptions =====================
+public definterface PassException <: Exception
+public defn PassException (s:String) :
+ new PassException :
+ defmethod print (o:OutputStream, this) :
+ print(o, s)
+
+public defn PassExceptions (xs:Streamable<PassException>) :
+ PassException(string-join(xs, "\n"))
;=============== WORKING IR ================================
-definterface Kind
-defstruct WireKind <: Kind
-defstruct RegKind <: Kind
-defstruct InstanceKind <: Kind
-defstruct ReadAccessorKind <: Kind
-defstruct WriteAccessorKind <: Kind
-defstruct PortKind <: Kind
-defstruct NodeKind <: Kind ; All elems except structural memory, wires
-
-defstruct MemKind <: Kind
-defstruct ModuleKind <: Kind
-defstruct StructuralMemKind <: Kind ; Separate kind because need special treatment
-defstruct AccessorKind <: Kind
+public definterface Kind
+public defstruct WireKind <: Kind
+public defstruct RegKind <: Kind
+public defstruct InstanceKind <: Kind
+public defstruct ReadAccessorKind <: Kind
+public defstruct WriteAccessorKind <: Kind
+public defstruct PortKind <: Kind
+public defstruct NodeKind <: Kind ; All elems except structural memory, wires
+public defstruct MemKind <: Kind
+public defstruct ModuleKind <: Kind
+public defstruct AccessorKind <: Kind
public definterface Gender
public val MALE = new Gender
@@ -35,36 +36,39 @@ public val FEMALE = new Gender
public val UNKNOWN-GENDER = new Gender
public val BI-GENDER = new Gender
-defstruct WRef <: Expression :
+public defstruct WRef <: Expression :
name: Symbol
type: Type with: (as-method => true)
kind: Kind
gender: Gender with: (as-method => true)
-defstruct WSubfield <: Expression :
+public defstruct WSubfield <: Expression :
exp: Expression
name: Symbol
type: Type with: (as-method => true)
gender: Gender with: (as-method => true)
-defstruct WIndex <: Expression :
+public defstruct WIndex <: Expression :
exp: Expression
value: Int
type: Type with: (as-method => true)
gender: Gender with: (as-method => true)
-defstruct WDefAccessor <: Stmt :
+public defstruct WDefAccessor <: Stmt :
+ info: FileInfo with: (as-method => true)
name: Symbol
source: Expression
index: Expression
gender: Gender
defstruct ConnectToIndexed <: Stmt :
+ info: FileInfo with: (as-method => true)
index: Expression
locs: List<Expression>
exp: Expression
defstruct ConnectFromIndexed <: Stmt :
+ info: FileInfo with: (as-method => true)
index: Expression
loc: Expression
exps: List<Expression>
@@ -100,19 +104,19 @@ defn swap (d:Direction) -> Direction :
OUTPUT : INPUT
INPUT : OUTPUT
-defn times (flip:Flip,d:Direction) -> Direction : flip * d
-defn times (d:Direction,flip:Flip) -> Direction :
+public defn times (flip:Flip,d:Direction) -> Direction : flip * d
+public defn times (d:Direction,flip:Flip) -> Direction :
switch {_ == flip} :
DEFAULT : d
REVERSE : swap(d)
-defn times (g:Gender,flip:Flip) -> Gender : flip * g
-defn times (flip:Flip,g:Gender) -> Gender :
+public defn times (g:Gender,flip:Flip) -> Gender : flip * g
+public defn times (flip:Flip,g:Gender) -> Gender :
switch {_ == flip} :
DEFAULT : g
REVERSE : swap(g)
-defn times (f1:Flip,f2:Flip) -> Flip :
+public defn times (f1:Flip,f2:Flip) -> Flip :
switch {_ == f2} :
DEFAULT : f1
REVERSE : swap(f1)
@@ -139,6 +143,9 @@ defmethod print (o:OutputStream, g:Gender) :
BI-GENDER : "b"
UNKNOWN-GENDER: "u"
+defmethod info (stmt:Begin) -> FileInfo : FileInfo()
+defmethod info (stmt:EmptyStmt) -> FileInfo : FileInfo()
+
defmethod type (exp:UIntValue) -> Type : UIntType(width(exp))
defmethod type (exp:SIntValue) -> Type : SIntType(width(exp))
@@ -162,6 +169,7 @@ public var PRINT-TWIDTHS : True|False = false
public var PRINT-GENDERS : True|False = false
public var PRINT-CIRCUITS : True|False = false
public var PRINT-DEBUG : True|False = false
+public var PRINT-INFO : True|False = false
;=== Printers ===
public defn println-all-debug (l:?) -> False :
@@ -183,31 +191,34 @@ defmethod print (o:OutputStream, k:Kind) :
(k:NodeKind) : "n"
(k:ModuleKind) : "module"
(k:InstanceKind) : "inst"
- (k:StructuralMemKind) : "smem"
(k:ReadAccessorKind) : "racc"
(k:WriteAccessorKind) : "wacc"
-defn hasGender (e:Expression|Stmt|Type|Port|Field) :
+defn hasGender (e:?) :
e typeof WRef|WSubfield|WIndex|WDefAccessor
-defn hasWidth (e:Expression|Stmt|Type|Port|Field) :
+defn hasWidth (e:?) :
e typeof UIntType|SIntType|UIntValue|SIntValue|Pad
-defn hasType (e:Expression|Stmt|Type|Port|Field) :
+defn hasType (e:?) :
e typeof Ref|Subfield|Index|DoPrim|WritePort|ReadPort|WRef|WSubfield
|WIndex|DefWire|DefRegister|DefMemory|Register
|VectorType|Port|Field|Pad
-defn hasKind (e:Expression|Stmt|Type|Port|Field) :
+defn hasKind (e:?) :
e typeof WRef
-defn any-debug? (e:Expression|Stmt|Type|Port|Field) :
+defn hasInfo (e:?) :
+ e typeof Stmt|Port|Circuit|Module
+
+defn any-debug? (e:?) :
(hasGender(e) and PRINT-GENDERS) or
(hasType(e) and PRINT-TYPES) or
(hasWidth(e) and PRINT-WIDTHS) or
- (hasKind(e) and PRINT-KINDS)
+ (hasKind(e) and PRINT-KINDS) or
+ (hasInfo(e) and PRINT-INFO)
-defmethod print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field) :
+defmethod print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field|Module|Circuit) :
defn wipe-width (t:Type) -> Type :
match(t) :
(t:UIntType) : UIntType(UnknownWidth())
@@ -220,6 +231,7 @@ defmethod print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field) :
if PRINT-TWIDTHS and hasType(e): print-all(o,["<t:" type(e as ?) ">"])
if PRINT-WIDTHS and hasWidth(e): print-all(o,["<w:" width(e as ?) ">"])
if PRINT-GENDERS and hasGender(e): print-all(o,["<g:" gender(e as ?) ">"])
+ if PRINT-INFO and hasInfo(e): print-all(o,["<i:" info(e as ?) ">"])
defmethod print (o:OutputStream, e:WRef) :
print(o,name(e))
@@ -234,15 +246,15 @@ defmethod print (o:OutputStream, e:WIndex) :
print-debug(o,e as ?)
defmethod print (o:OutputStream, s:WDefAccessor) :
- print-all(o,["accessor " name(s) " = " source(s) "[" index(s) "]"])
+ print-all(o,["accessor " name(s) " = " source(s) "[" index(s) "] @[" info(s) "]"])
print-debug(o,s)
defmethod print (o:OutputStream, c:ConnectToIndexed) :
- print-all(o, [locs(c) "[" index(c) "] := " exp(c)])
+ print-all(o, [locs(c) "[" index(c) "] := " exp(c) " @[" info(c) "]"])
print-debug(o,c as ?)
defmethod print (o:OutputStream, c:ConnectFromIndexed) :
- print-all(o, [loc(c) " := " exps(c) "[" index(c) "]"])
+ print-all(o, [loc(c) " := " exps(c) "[" index(c) "] @[" info(c) "]"])
print-debug(o,c as ?)
defmethod map (f: Expression -> Expression, e: WSubfield) :
@@ -251,11 +263,11 @@ defmethod map (f: Expression -> Expression, e: WIndex) :
WIndex(f(exp(e)), value(e), type(e), gender(e))
defmethod map (f: Expression -> Expression, c:WDefAccessor) :
- WDefAccessor(name(c), f(source(c)), f(index(c)), gender(c))
+ WDefAccessor(info(c),name(c), f(source(c)), f(index(c)), gender(c))
defmethod map (f: Expression -> Expression, c:ConnectToIndexed) :
- ConnectToIndexed(f(index(c)), map(f, locs(c)), f(exp(c)))
+ ConnectToIndexed(info(c),f(index(c)), map(f, locs(c)), f(exp(c)))
defmethod map (f: Expression -> Expression, c:ConnectFromIndexed) :
- ConnectFromIndexed(f(index(c)), f(loc(c)), map(f, exps(c)))
+ ConnectFromIndexed(info(c),f(index(c)), f(loc(c)), map(f, exps(c)))
defmethod map (f: Type -> Type, e: WRef) :
WRef(name(e), f(type(e)), kind(e), gender(e))
@@ -287,10 +299,10 @@ defn temp-elimination (c:Circuit) :
else : s
(s) : map(temp-elim-s,s)
- Circuit(modules*, main(c)) where :
+ Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
- Module(name(m), ports(m), temp-elim-s(body(m)))
+ Module(info(m),name(m), ports(m), temp-elim-s(body(m)))
;================= Bring to Working IR ========================
; Returns a new Circuit with Refs, Subfields, Indexes and DefAccessors
@@ -306,13 +318,13 @@ defn to-working-ir (c:Circuit) :
(e) : e
defn to-stmt (s:Stmt) :
match(map(to-exp,s)) :
- (s:DefAccessor) : WDefAccessor(name(s),source(s),index(s), UNKNOWN-GENDER)
+ (s:DefAccessor) : WDefAccessor(info(s),name(s),source(s),index(s), UNKNOWN-GENDER)
(s) : map(to-stmt,s)
- Circuit(modules*, main(c)) where :
+ Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
- Module(name(m), ports(m), to-stmt(body(m)))
+ Module(info(m),name(m), ports(m), to-stmt(body(m)))
;=============== MAKE EXPLICIT RESET =======================
; All modules have an implicit reset signal - however, the
@@ -339,20 +351,20 @@ defn make-explicit-reset (c:Circuit) :
(s:DefInstance) :
val iref = WSubfield(WRef(name(s), UnknownType(), InstanceKind(), UNKNOWN-GENDER),`reset,UnknownType(),UNKNOWN-GENDER)
val pref = WRef(`reset, UnknownType(), PortKind(), MALE)
- Begin(to-list([s,Connect(iref,pref)]))
+ Begin(to-list([s,Connect(info(s),iref,pref)]))
(s) : map(route-reset,s)
var ports! = ports(m)
if not contains?(explicit-reset,name(m)) :
- ports! = append(ports(m),list(Port(`reset,INPUT,UIntType(IntWidth(1)))))
+ ports! = append(ports(m),list(Port(FileInfo(),`reset,INPUT,UIntType(IntWidth(1)))))
val body! = route-reset(body(m))
- Module(name(m),ports!,body!)
+ Module(info(m),name(m),ports!,body!)
defn make-explicit-reset (m:Module, c:Circuit) -> Module :
val explicit-reset = find-explicit(c)
make-explicit(m,explicit-reset)
- Circuit(modules*, main(c)) where :
+ Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
make-explicit-reset(m,c)
@@ -399,9 +411,9 @@ defn resolve-kinds (c:Circuit) :
kinds[name(m)] = ModuleKind()
find(m,kinds)
val body! = resolve(body(m),kinds)
- Module(name(m),ports(m),body!)
+ Module(info(m),name(m),ports(m),body!)
- Circuit(modules*, main(c)) where :
+ Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
resolve-kinds(m,c)
@@ -434,7 +446,7 @@ defn bundle-field-type (v:Type,s:Symbol) -> Type :
val ft = for p in fields(v) find : name(p) == s
if ft != false : type(ft as Field)
else : UnknownType()
- (v) : error(string-join(["Accessing subfield " s " on a non-Bundle type."]))
+ (v) : UnknownType()
defn get-vector-subtype (v:Type) -> Type :
match(v) :
@@ -474,7 +486,7 @@ defn infer-types (s:Stmt, l:List<KeyValue<Symbol,Type>>) -> [Stmt List<KeyValue<
(s:Conditionally) :
val [s*,l*] = infer-types(conseq(s),l)
val [s**,l**] = infer-types(alt(s),l)
- [Conditionally(pred(s),s*,s**),l]
+ [Conditionally(info(s),pred(s),s*,s**),l]
(s:Connect|OnReset|EmptyStmt) : [s,l]
defn infer-types (m:Module, l:List<KeyValue<Symbol,Type>>) -> Module :
@@ -483,14 +495,14 @@ defn infer-types (m:Module, l:List<KeyValue<Symbol,Type>>) -> Module :
name(p) => type(p)
println-all-debug(append(ptypes,l))
val [s,l*] = infer-types(body(m),append(ptypes, l))
- Module(name(m),ports(m),s)
+ Module(info(m),name(m),ports(m),s)
defn infer-types (c:Circuit) -> Circuit :
val l =
for m in modules(c) map :
name(m) => BundleType(map(to-field,ports(m)))
println-all-debug(l)
- Circuit{ _, main(c) } $
+ Circuit{info(c), _, main(c) } $
for m in modules(c) map :
infer-types(m,l)
@@ -506,6 +518,18 @@ defn infer-types (c:Circuit) -> Circuit :
; Because accessor gender is not known during declaration,
; this pass requires iterating until a fixed point is reached.
+; Notes
+; Is there a case where an incorrect gender would cause a weird result in resolving an accessor gender, such that a following gender check is wrong/right which it shouldn't be?
+
+; I don't think so, because there is no way for resolving an accessor gender to change something from wrong -> right, so it will always fail in the gender check.
+; As such, it doesn't matter what the accessor gender gets resolved to, as it will fail anyways
+
+; In the example below, FIRRTL will say accessor gender could not be resolved. Once this is fixed, then we will error "Cannot connect from an output, out"
+; output out : UInt
+; accessor x = m[i]
+; x := out
+; out := x
+
defn bundle-field-flip (n:Symbol,t:Type) -> Flip :
match(t) :
(b:BundleType) :
@@ -521,7 +545,7 @@ defn resolve-genders (c:Circuit) :
defn resolve-iter (m:Module) -> Module :
val body* = resolve-stmt(body(m))
- Module(name(m),ports(m),body*)
+ Module(info(m),name(m),ports(m),body*)
defn get-gender (n:Symbol,g:Gender) -> Gender :
defn force-gender (n:Symbol,g:Gender) -> Gender :
@@ -551,24 +575,24 @@ defn resolve-genders (c:Circuit) :
get-gender(name(s),BI-GENDER)
s
(s:DefNode) :
- DefNode(name(s),resolve-expr(value(s),get-gender(name(s),MALE)))
+ DefNode(info(s),name(s),resolve-expr(value(s),get-gender(name(s),MALE)))
(s:DefInstance) :
get-gender(name(s),MALE)
- DefInstance(name(s),resolve-expr(module(s),MALE))
+ DefInstance(info(s),name(s),resolve-expr(module(s),MALE))
(s:WDefAccessor) :
val gender* = get-gender(name(s),UNKNOWN-GENDER)
val index* = resolve-expr(index(s),MALE)
val source* = resolve-expr(source(s),gender*)
- WDefAccessor(name(s),source*,index*,gender*)
+ WDefAccessor(info(s),name(s),source*,index*,gender*)
(s:Connect) :
- Connect(resolve-expr(loc(s),FEMALE),resolve-expr(exp(s),MALE))
+ Connect(info(s),resolve-expr(loc(s),FEMALE),resolve-expr(exp(s),MALE))
(s:OnReset) :
- OnReset(resolve-expr(loc(s),FEMALE),resolve-expr(exp(s),MALE))
+ OnReset(info(s),resolve-expr(loc(s),FEMALE),resolve-expr(exp(s),MALE))
(s:Conditionally) :
val pred* = resolve-expr(pred(s),MALE)
val conseq* = resolve-stmt(conseq(s))
val alt* = resolve-stmt(alt(s))
- Conditionally(pred*,conseq*,alt*)
+ Conditionally(info(s),pred*,conseq*,alt*)
(s) : map(resolve-stmt,s)
defn resolve-expr (e:Expression,desired:Gender) -> Expression :
@@ -601,7 +625,7 @@ defn resolve-genders (c:Circuit) :
val genders = HashTable<Symbol,Gender>(symbol-hash)
resolve-module(m,genders)
- Circuit(modules*, main(c)) where :
+ Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
resolve-genders(m,c)
@@ -629,23 +653,25 @@ defn expand-stmt (s:Stmt) -> Stmt :
if mem? : s
else :
val vtype = type(type(source(s)) as VectorType)
- val wire = DefWire(name(s),vtype)
+ val wire = DefWire(info(s),name(s),vtype)
switch {gender(s) == _} :
MALE : Begin{list(wire,_)} $ ConnectFromIndexed(
+ info(s),
index(s),
WRef(name(wire),vtype,NodeKind(),FEMALE),
expand-vector(source(s)))
FEMALE: Begin{list(wire,_)} $ ConnectToIndexed(
+ info(s),
index(s),
expand-vector(source(s)),
WRef(name(wire),vtype,NodeKind(),MALE))
(s) : map(expand-stmt,s)
defn expand-accessors (c:Circuit) :
- Circuit(modules*, main(c)) where :
+ Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
- Module(name(m),ports(m),expand-stmt(body(m)))
+ Module(info(m),name(m),ports(m),expand-stmt(body(m)))
;;=============== LOWERING TO GROUND TYPES =============================
; All non-ground (elevated) types (Vectors, Bundles) are expanded out to
@@ -718,18 +744,18 @@ defn expand-expr (e:Expression) -> List<EF> :
for x in generate-entry(name(e),type(e)) map :
EF(WRef(name(x),type(x),kind(e),gender(e)), flip(x))
(e:WSubfield) :
+ val f = {_ as Field} $
+ for f in fields(type(exp(e)) as BundleType) find : name(f) == name(e)
if inst?(exp(e)) :
- val i = exp(e)
- val f = {_ as Field} $
- for f in fields(type(i) as BundleType) find : name(f) == name(e)
+ println-all(["here with " exp(e)])
for x in generate-entry(name(f),type(f)) map :
- EF(WSubfield(i,name(x),type(x),gender(e)),flip(x))
+ EF(WSubfield(exp(e),name(x),type(x),gender(e)),flip(x))
else :
val exps = expand-expr(exp(e))
val begin = index-of-elem(type(exp(e)) as BundleType,name(e))
val len = num-elems(type(e))
val ret = headn(tailn(exps,begin),len)
- for r in ret map : EF(exp(r),DEFAULT)
+ for r in ret map : EF(exp(r),flip(r) * flip(f))
(e:WIndex) :
val exps = expand-expr(exp(e))
val len = num-elems(type(e))
@@ -745,7 +771,7 @@ defn expand-expr (e:Expression) -> List<EF> :
defn lower-ports (ports:List<Port>) -> List<Port> :
for p in ports map-append :
for x in generate-entry(name(p),type(p)) map :
- Port(name(x),direction(p) * flip(x),type(x))
+ Port(info(p),name(x),direction(p) * flip(x),type(x))
defn type (s:WDefAccessor) -> Type : type(type(source(s)) as VectorType)
defn size (s:DefMemory) -> Int : size(type(s))
@@ -768,10 +794,10 @@ defn lower (body:Stmt) -> Stmt :
match(s) :
(s:DefWire) : Begin $
for x in generate-entry(name(s),type(s)) map :
- DefWire(name(x),type(x))
+ DefWire(info(s),name(x),type(x))
(s:DefRegister) : Begin{_} $
for x in generate-entry(name(s),type(s)) map :
- DefRegister(name(x),type(x))
+ DefRegister(info(s),name(x),type(x))
(s:DefInstance) :
val fields =
for f in fields(type(module(s)) as BundleType) map-append :
@@ -779,20 +805,20 @@ defn lower (body:Stmt) -> Stmt :
for etf in etfs map :
Field(name(etf),flip(etf) * flip(f),type(etf))
val m = module(s) as WRef
- DefInstance(name(s),WRef(name(m),BundleType(fields),kind(m),gender(m)))
+ DefInstance(info(s),name(s),WRef(name(m),BundleType(fields),kind(m),gender(m)))
(s:DefNode) : Begin $
for x in expand-expr(value(s)) map :
- DefNode(name(s),exp(x))
+ DefNode(info(s),name(s),exp(x))
(s:DefMemory) : Begin $
for x in generate-entry(name(s),type(type(s))) map :
- DefMemory(name(x),VectorType(type(x),size(s)))
+ DefMemory(info(s),name(x),VectorType(type(x),size(s)))
(s:WDefAccessor) :
val ls = generate-entry(name(s),type(s))
val rs = generate-entry(name(source(s) as WRef),type(s))
Begin $ for (l in ls, r in rs) map:
if flip(r) == REVERSE : error("Shouldn't be here")
val memref = WRef(name(r),VectorType(type(r),size(s)),MemKind(),gender(s))
- WDefAccessor(name(l),memref,index(s),gender(s))
+ WDefAccessor(info(s),name(l),memref,index(s),gender(s))
(s:OnReset|Connect) : Begin $
for (l in expand-expr(loc(s)), r in expand-expr(exp(s))) map :
val lgender = FEMALE * flip(l)
@@ -803,11 +829,11 @@ defn lower (body:Stmt) -> Stmt :
println-all-debug(["Right: " r " with Gender: " rgender])
switch fn ([x,y]) : lgender == x and rgender == y :
[FEMALE,MALE] :
- if s typeof Connect : Connect(l*,r*)
- else : OnReset(l*,r*)
+ if s typeof Connect : Connect(info(s),l*,r*)
+ else : OnReset(info(s),l*,r*)
[MALE,FEMALE] :
- if s typeof Connect : Connect(r*,l*)
- else : OnReset(r*,l*)
+ if s typeof Connect : Connect(info(s),r*,l*)
+ else : OnReset(info(s),r*,l*)
(s:ConnectFromIndexed) : Begin(ls) where :
val ctable = HashTable<Symbol,Vector<EF>>(symbol-hash)
for e in exps(s) do :
@@ -825,8 +851,8 @@ defn lower (body:Stmt) -> Stmt :
val l* = set-gender(exp(l),lgender,flip(l))
val exps = to-list $ for e in ctable[n] map : set-gender(exp(e),rgender,flip(e))
switch fn ([x,y]) : lgender == x and rgender == y :
- [FEMALE,MALE] : ConnectFromIndexed(index(s),l*,exps)
- [MALE,FEMALE] : ConnectToIndexed(index(s),exps,l*)
+ [FEMALE,MALE] : ConnectFromIndexed(info(s),index(s),l*,exps)
+ [MALE,FEMALE] : ConnectToIndexed(info(s),index(s),exps,l*)
(s:ConnectToIndexed) : Begin(ls) where :
val ctable = HashTable<Symbol,Vector<EF>>(symbol-hash)
for e in locs(s) do :
@@ -844,21 +870,21 @@ defn lower (body:Stmt) -> Stmt :
val r* = set-gender(exp(r),rgender,flip(r))
val locs = to-list $ for e in ctable[n] map : set-gender(exp(e),lgender,flip(e))
switch fn ([x,y]) : lgender == x and rgender == y :
- [FEMALE,MALE] : ConnectToIndexed(index(s),locs,r*)
- [MALE,FEMALE] : ConnectFromIndexed(index(s),r*,locs)
+ [FEMALE,MALE] : ConnectToIndexed(info(s),index(s),locs,r*)
+ [MALE,FEMALE] : ConnectFromIndexed(info(s),index(s),r*,locs)
(s:Conditionally) :
- Conditionally(exp(head $ expand-expr(pred(s))),lower-stmt(conseq(s)),lower-stmt(alt(s)))
+ Conditionally(info(s),exp(head $ expand-expr(pred(s))),lower-stmt(conseq(s)),lower-stmt(alt(s)))
(s:Begin|EmptyStmt) : map(lower-stmt,s)
lower-stmt(body)
defn lower-module (c:Circuit,m:Module) -> Module :
- Module(name(m),ports*,body*) where :
+ Module(info(m),name(m),ports*,body*) where :
val body* = lower(body(m))
val ports* = lower-ports(ports(m))
defn lower-to-ground (c:Circuit) -> Circuit :
- Circuit(modules*, main(c)) where :
+ Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
lower-module(c,m)
@@ -884,11 +910,12 @@ defn expand-connect-indexed-stmt (s: Stmt) -> Stmt :
else :
val ref = WRef(firrtl-gensym(get-name(exp(s))),type(index(s)),NodeKind(),UNKNOWN-GENDER)
append(
- list(Connect(head(locs(s)),exp(s)),DefNode(name(ref),index(s)))
+ list(Connect(info(s),head(locs(s)),exp(s)),DefNode(info(s),name(ref),index(s)))
to-list $
for (i in 1 to false, l in tail(locs(s))) stream : Conditionally(
+ info(s),
equality(ref,UIntValue(i,UnknownWidth())),
- Connect(l,exp(s)),
+ Connect(info(s),l,exp(s)),
EmptyStmt()
)
)
@@ -897,21 +924,22 @@ defn expand-connect-indexed-stmt (s: Stmt) -> Stmt :
else :
val ref = WRef(firrtl-gensym(get-name(loc(s))),type(index(s)),NodeKind(),UNKNOWN-GENDER)
append(
- list(Connect(loc(s),head(exps(s))),DefNode(name(ref),index(s)))
+ list(Connect(info(s),loc(s),head(exps(s))),DefNode(info(s),name(ref),index(s)))
to-list $
for (i in 1 to false, e in tail(exps(s))) stream : Conditionally(
+ info(s),
equality(ref,UIntValue(i,UnknownWidth())),
- Connect(loc(s),e),
+ Connect(info(s),loc(s),e),
EmptyStmt()
)
)
(s) : map(expand-connect-indexed-stmt,s)
defn expand-connect-indexed (m: Module) -> Module :
- Module(name(m),ports(m),expand-connect-indexed-stmt(body(m)))
+ Module(info(m),name(m),ports(m),expand-connect-indexed-stmt(body(m)))
defn expand-connect-indexed (c: Circuit) -> Circuit :
- Circuit(modules*, main(c)) where :
+ Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
expand-connect-indexed(m)
@@ -1113,7 +1141,7 @@ defn expand-whens (ports:List<Port>, table:HashTable<Symbol,SymbolicValue>,cons:
if has-nul?(table[name(p)]) :
println("Uninitialized: ~" % [to-string(name(p))]);TODO actually collect error
EmptyStmt()
- else : Connect(ref,to-exp(table[name(p)]) as Expression)
+ else : Connect(FileInfo(),ref,to-exp(table[name(p)]) as Expression)
defn expand-whens (s:Stmt, table:HashTable<Symbol,SymbolicValue>,decs:Vector<Stmt>,cons:Vector<Stmt>) -> Stmt :
match(map(expand-whens{_,table,decs,cons},s)) :
@@ -1125,26 +1153,26 @@ defn expand-whens (s:Stmt, table:HashTable<Symbol,SymbolicValue>,decs:Vector<Stm
if has-nul?(table[name(s)]) :
println("Uninitialized: ~" % [to-string(name(s))]);TODO actually collect error
EmptyStmt()
- else : Connect(ref,to-exp(table[name(s)]) as Expression)
+ else : Connect(info(s),ref,to-exp(table[name(s)]) as Expression)
}()
(s:DefRegister) :
- add(decs,DefWire(name(s),type(s)))
+ add(decs,DefWire(info(s),name(s),type(s)))
add{cons,_} $ {
val ref = WRef(name(s),type(s),RegKind(),FEMALE)
val e = to-exp(table[name(s)])
match(e) :
(e:False) : EmptyStmt()
- (e:Expression) : Connect(ref,Register(type(s),e, to-exp(optimize $ get-write-enable(table[name(s)])) as Expression))
+ (e:Expression) : Connect(info(s),ref,Register(type(s),e, to-exp(optimize $ get-write-enable(table[name(s)])) as Expression))
}()
(s:WDefAccessor) :
val t = type(type(source(s)) as VectorType)
val n = name(s)
- add(decs,DefWire(n,t))
+ add(decs,DefWire(info(s),n,t))
add{cons,_} $ {
switch {_ == gender(s)} :
MALE :
val ref = WRef(n,t,ReadAccessorKind(),FEMALE)
- Begin $ list $ Connect(ref,ReadPort(source(s),index(s),t,get-read-enable(n,table)))
+ Begin $ list $ Connect(info(s),ref,ReadPort(source(s),index(s),t,get-read-enable(n,table)))
FEMALE :
val ref = WRef(n,t,WriteAccessorKind(),FEMALE)
val e = to-exp(table[n])
@@ -1153,10 +1181,10 @@ defn expand-whens (s:Stmt, table:HashTable<Symbol,SymbolicValue>,decs:Vector<Stm
println("Uninitialized: ~" % [to-string(n)]) ;TODO actually collect error
EmptyStmt()
(e:Expression) :
- Connect(ref,e)
+ Connect(info(s),ref,e)
val enable = (to-exp $ optimize $ get-write-enable(table[n])) as Expression
val wp = WritePort(source(s),index(s),t,enable as Expression)
- Begin $ list(Connect(wp,ref),s*)
+ Begin $ list(Connect(info(s),wp,ref),s*)
}()
(s:DefInstance) :
add(decs,s)
@@ -1171,7 +1199,7 @@ defn expand-whens (s:Stmt, table:HashTable<Symbol,SymbolicValue>,decs:Vector<Stm
if has-nul?(table[n]) :
println("Uninitialized: ~" % [to-string(n)]);TODO actually collect error
EmptyStmt()
- else : Connect(sref,to-exp(table[n]) as Expression)
+ else : Connect(info(s),sref,to-exp(table[n]) as Expression)
else : EmptyStmt()
(s:Connect|Conditionally|OnReset|Begin|EmptyStmt) : false
s
@@ -1305,10 +1333,10 @@ defn expand-whens (m:Module) -> Module :
val cons = Vector<Stmt>()
expand-whens(ports(m),table,cons)
expand-whens(body(m),table,decs,cons)
- Module(name(m),ports(m),Begin(append(to-list(decs),to-list(cons))))
+ Module(info(m),name(m),ports(m),Begin(append(to-list(decs),to-list(cons))))
defn expand-whens (c:Circuit) -> Circuit :
- Circuit(modules*, main(c)) where :
+ Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
expand-whens(m)
@@ -1560,21 +1588,21 @@ public defn width! (e:Expression) -> Width : width!(type(e))
defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Module:
defn gen-constraints-s (s:Stmt) -> Stmt :
match(map(gen-constraints-s,s)) :
- (s:DefWire) : DefWire(name(s),h[name(s)])
- (s:DefInstance) : DefInstance(name(s),gen-constraints(module(s)))
- (s:DefMemory) : DefMemory(name(s),h[name(s)] as VectorType)
+ (s:DefWire) : DefWire(info(s),name(s),h[name(s)])
+ (s:DefInstance) : DefInstance(info(s),name(s),gen-constraints(module(s)))
+ (s:DefMemory) : DefMemory(info(s),name(s),h[name(s)] as VectorType)
(s:DefNode) :
val l = h[name(s)]
val r = gen-constraints(value(s))
add(v,WGeq(width!(l),width!(type(r))))
add(v,WGeq(width!(type(r)),width!(l)))
- DefNode(name(s),r)
+ DefNode(info(s),name(s),r)
(s:Connect) :
val l = gen-constraints(loc(s))
val e = gen-constraints(exp(s))
add(v,WGeq(width!(type(l)),width!(type(e))))
add(v,WGeq(width!(type(e)),width!(type(l))))
- Connect(l,e)
+ Connect(info(s),l,e)
(s) : s
defn gen-constraints (e:Expression) -> Expression :
@@ -1612,9 +1640,9 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod
(e) : e
val ports* =
- for p in ports(m) map : Port(name(p),direction(p),h[name(p)])
+ for p in ports(m) map : Port(info(p),name(p),direction(p),h[name(p)])
- Module(name(m),ports*,gen-constraints-s(body(m)))
+ Module(info(m),name(m),ports*,gen-constraints-s(body(m)))
defn build-environment (c:Circuit,m:Module,h:HashTable<Symbol,Type>) -> HashTable<Symbol,Type> :
defn build-environment (s:Stmt) -> False :
@@ -1642,11 +1670,11 @@ defn replace-var-widths (c:Circuit,h:HashTable<Symbol,Int>) -> Circuit :
w*
val modules* = for m in modules(c) map :
- Module{name(m),_,mapr(replace-var-widths-w,body(m))} $
+ Module{info(m),name(m),_,mapr(replace-var-widths-w,body(m))} $
for p in ports(m) map :
- Port(name(p),direction(p),mapr(replace-var-widths-w,type(p)))
+ Port(info(p),name(p),direction(p),mapr(replace-var-widths-w,type(p)))
- Circuit(modules*,main(c))
+ Circuit(info(c),modules*,main(c))
defn remove-unknowns-w (w:Width) -> Width :
match(w) :
@@ -1682,7 +1710,7 @@ defn infer-widths (c:Circuit) -> Circuit :
println-debug("======== SOLVED CONSTRAINTS ========")
for x in h do : println-debug(x)
println-debug("====================================")
- replace-var-widths(Circuit(modules*,main(c)),h)
+ replace-var-widths(Circuit(info(c),modules*,main(c)),h)
;================= Inline Instances ========================
@@ -1702,7 +1730,7 @@ defn inline-instances (c:Circuit) :
else :
val v = Vector<Stmt>()
for p in ports(m) do :
- add(v,DefWire(name(p),type(p)))
+ add(v,DefWire(info(s),name(p),type(p)))
add(v,inline-inst(body(m)))
Begin(to-list(v))
h-s[n] = body*
@@ -1728,15 +1756,15 @@ defn inline-instances (c:Circuit) :
(e) : e
defn rename-s (s:Stmt,n:Symbol) -> Stmt :
map{rename-e{_,n},_} $ match(map(rename-s{_,n},s)) :
- (s:DefWire) : DefWire(rename(name(s),n),type(s))
+ (s:DefWire) : DefWire(info(s),rename(name(s),n),type(s))
(s:DefInstance) : error("Shouldn't be here")
- (s:DefMemory) : DefMemory(rename(name(s),n),type(s))
- (s:DefNode) : DefNode(rename(name(s),n),value(s))
+ (s:DefMemory) : DefMemory(info(s),rename(name(s),n),type(s))
+ (s:DefNode) : DefNode(info(s),rename(name(s),n),value(s))
(s) : s
for m in modules(c) do :
h[name(m)] = m
val top = (for m in modules(c) find : name(m) == main(c)) as Module
- Circuit(list(Module(name(top),ports(top),inline-inst(body(top)))),main(c))
+ Circuit(info(c),list(Module(info(top),name(top),ports(top),inline-inst(body(top)))),main(c))
;================= Split Expressions ========================
@@ -1751,27 +1779,27 @@ defn split-exp (c:Circuit) :
(s:Conditionally) : error("Shouldn't be here")
(s:Connect) :
match(loc(s)) :
- (e:WritePort) : add(v,map(split-exp-e{_,v,name(exp(s) as WRef)},s))
- (e) : add(v,map(split-exp-e{_,v,name(loc(s) as WRef)},s))
- (s:DefNode) : add(v,map(split-exp-e{_,v,name(s)},s))
- (s) : add(v,map(split-exp-e{_,v,false},s))
+ (e:WritePort) : add(v,map(split-exp-e{_,v,name(exp(s) as WRef),info(s)},s))
+ (e) : add(v,map(split-exp-e{_,v,name(loc(s) as WRef),info(s)},s))
+ (s:DefNode) : add(v,map(split-exp-e{_,v,name(s),info(s)},s))
+ (s) : add(v,map(split-exp-e{_,v,false,info(s)},s))
false
- defn split-exp-e (e:Expression,v:Vector<Stmt>,n:Symbol|False) -> Expression :
- match(map(split-exp-e{_,v,n},e)):
+ defn split-exp-e (e:Expression,v:Vector<Stmt>,n:Symbol|False,info:FileInfo) -> Expression :
+ match(map(split-exp-e{_,v,n,info},e)):
(e:Subfield|DoPrim|Pad|ReadPort|Register|WritePort) :
val n* =
if n typeof False : firrtl-gensym(`T)
else : firrtl-gensym(symbol-join([n as Symbol `#]))
;to-symbol $ string-join $ [n as Symbol firrtl-gensym(`#)]
- add(v,DefNode(n*,e))
+ add(v,DefNode(info,n*,e))
WRef(n*,type(e),NodeKind(),UNKNOWN-GENDER)
(e) : e
- Circuit{_,main(c)} $
+ Circuit{info(c),_,main(c)} $
for m in modules(c) map :
val v = Vector<Stmt>()
split-exp-s(body(m),v)
- Module(name(m),ports(m),Begin(to-list(v)))
+ Module(info(m),name(m),ports(m),Begin(to-list(v)))
;================= Bring to Real IR ========================
; Returns a new Circuit with only real IR nodes.
@@ -1790,10 +1818,10 @@ defn to-real-ir (c:Circuit) :
(e:ConnectFromIndexed) : error("Shouldn't be here")
(e) : map(to-stmt,e)
- Circuit(modules*, main(c)) where :
+ Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
- Module(name(m), ports(m), to-stmt(body(m)))
+ Module(info(m),name(m), ports(m), to-stmt(body(m)))
;============= FLO PRINTER ======================================
; Emit
@@ -2024,22 +2052,34 @@ public defn run-passes (c: Circuit, p: List<Char>,file:String) :
if PRINT-CIRCUITS : print(c*)
if PRINT-CIRCUITS : println-all(["Finished " name "\n"])
- ; Early passes:
- ; If modules have a reset defined, must be an INPUT and UInt(1)
if contains(p,'X') or contains(p,'A') : do-stage("High Form Check", check-high-form)
if contains(p,'X') or contains(p,'a') : do-stage("Temp Elimination", temp-elimination)
if contains(p,'X') or contains(p,'b') : do-stage("Working IR", to-working-ir)
+
if contains(p,'X') or contains(p,'c') : do-stage("Make Explicit Reset", make-explicit-reset)
+
if contains(p,'X') or contains(p,'d') : do-stage("Resolve Kinds", resolve-kinds)
+ if contains(p,'X') or contains(p,'D') : do-stage("Check Kinds", check-kinds)
+
if contains(p,'X') or contains(p,'e') : do-stage("Infer Types", infer-types)
+ if contains(p,'X') or contains(p,'E') : do-stage("Check Types", check-types)
+
if contains(p,'X') or contains(p,'f') : do-stage("Resolve Genders", resolve-genders)
- if contains(p,'X') or contains(p,'g') : do-stage("Expand Accessors", expand-accessors)
- if contains(p,'X') or contains(p,'h') : do-stage("Lower To Ground", lower-to-ground)
+ if contains(p,'X') or contains(p,'F') : do-stage("Check Genders", check-genders)
+
+ if contains(p,'X') or contains(p,'g') : do-stage("Expand Accessors", expand-accessors) ;mem kind
+ if contains(p,'X') or contains(p,'h') : do-stage("Lower To Ground", lower-to-ground) ;inst kind
if contains(p,'X') or contains(p,'i') : do-stage("Expand Indexed Connects", expand-connect-indexed)
- if contains(p,'X') or contains(p,'k') : do-stage("Expand Whens", expand-whens)
- if contains(p,'X') or contains(p,'l') : do-stage("Infer Widths", infer-widths)
- if contains(p,'X') or contains(p,'m') : do-stage("Inline Instances", inline-instances)
+
+; make sure no bundle types
+ if contains(p,'X') or contains(p,'k') : do-stage("Expand Whens", expand-whens) ; requires types, lowering
+
+ if contains(p,'X') or contains(p,'l') : do-stage("Infer Widths", infer-widths) ; requires lowering, expand whens
+
+ if contains(p,'X') or contains(p,'m') : do-stage("Inline Instances", inline-instances) ;inst kind
+
if contains(p,'X') or contains(p,'n') : do-stage("Split Expressions", split-exp)
+
if contains(p,'X') or contains(p,'o') : do-stage("Real IR", to-real-ir)
if contains(p,'X') or contains(p,'F') : do-stage("To Flo", emit-flo{file,_})
println("Done!")