aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/stanza/firrtl-ir.stanza11
-rw-r--r--src/main/stanza/ir-parser.stanza8
-rw-r--r--src/main/stanza/ir-utils.stanza16
-rw-r--r--src/main/stanza/passes.stanza132
-rw-r--r--test/passes/infer-types/bundle.fir6
-rw-r--r--test/passes/infer-types/gcd.fir10
-rw-r--r--test/passes/resolve-genders/ports.fir2
7 files changed, 117 insertions, 68 deletions
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index 16e7096b..d6733263 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -6,12 +6,9 @@ public definterface Direction
public val INPUT = new Direction
public val OUTPUT = new Direction
-public definterface Gender
-public val MALE = new Gender
-public val FEMALE = new Gender
-public val UNKNOWN-GENDER = new Gender
-public val BI-GENDER = new Gender
-
+public definterface Flip
+public val DEFAULT = new Flip
+public val REVERSE = new Flip
public definterface Width
public defstruct UnknownWidth <: Width
@@ -218,7 +215,7 @@ public defstruct UnknownType <: Type
public defstruct Field :
name: Symbol
- gender: Gender
+ flip: Flip
type: Type
public defstruct Port :
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index a9ea7c30..46b62162 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -88,10 +88,10 @@ rd.defsyntax firrtl :
Module(ut(name), ports, Begin(body))
defrule field :
- (male ?name:#symbol : ?type:#type) :
- Field(ut(name), MALE, type)
- (female ?name:#symbol : ?type:#type) :
- Field(ut(name), FEMALE, type)
+ (?name:#symbol : ?type:#type) :
+ Field(ut(name), DEFAULT, type)
+ (flip ?name:#symbol : ?type:#type) :
+ Field(ut(name), REVERSE, type)
defrule port :
(input ?name:#symbol : ?type:#type) :
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index 47f6154b..546fd6e7 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -8,20 +8,18 @@ defpackage firrtl.ir-utils :
public defmulti print-debug (o:OutputStream, e:Expression|Stmt|Type|Element|Port|Field) -> False
;============== PRINTERS ===================================
-defmethod print (o:OutputStream, g:Gender) :
+
+defmethod print (o:OutputStream, d:Flip) :
print{o, _} $
- switch {g == _} :
- MALE : "male"
- FEMALE: "female"
- BI-GENDER : "bi"
- UNKNOWN-GENDER: "unknown"
+ switch {d == _} :
+ DEFAULT : ""
+ REVERSE: "flip"
defmethod print (o:OutputStream, d:Direction) :
print{o, _} $
switch {d == _} :
INPUT : "input"
OUTPUT: "output"
- ;UNKNOWN-DIR : "unknown"
defmethod print (o:OutputStream, w:Width) :
print{o, _} $
@@ -216,7 +214,7 @@ defmethod print (o:OutputStream, t:Type) :
print-debug(o,t)
defmethod print (o:OutputStream, f:Field) :
- print-all(o, [gender(f) " " name(f) " : " type(f)])
+ print-all(o, [flip(f) " " name(f) " : " type(f)])
print-debug(o,f)
defmethod print (o:OutputStream, p:Port) :
@@ -263,7 +261,7 @@ public defn map<?T> (f: Type -> Type, t:?T&Type) -> T :
(t:T&BundleType) :
BundleType $
for p in fields(t) map :
- Field(name(p), gender(p), f(type(p)))
+ Field(name(p), flip(p), f(type(p)))
(t:T&VectorType) :
VectorType(f(type(t)), size(t))
(t) :
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index 51176ff6..ece7287e 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -24,7 +24,11 @@ defstruct ModuleKind <: Kind
defstruct InstanceKind <: Kind
defstruct StructuralMemKind <: Kind ; Separate kind because need special treatment
-;val UNKNOWN-DIR = new Direction
+public definterface Gender
+public val MALE = new Gender
+public val FEMALE = new Gender
+public val UNKNOWN-GENDER = new Gender
+public val BI-GENDER = new Gender
defstruct WRef <: Expression :
name: Symbol
@@ -52,25 +56,41 @@ defstruct WDefAccessor <: Stmt :
;================ WORKING IR UTILS =========================
-defn times (f1:Gender,f2:Gender) -> Gender :
- if (f1 == UNKNOWN-GENDER) : UNKNOWN-GENDER
- else if (f2 == UNKNOWN-GENDER) : UNKNOWN-GENDER
- else if (f1 == MALE) : f2
- else if (f2 == MALE) : f1
- else if (f1 == FEMALE and f2 == FEMALE) : MALE
- else if (f1 == BI-GENDER) : f2
- else if (f2 == BI-GENDER) : f1
- else : UNKNOWN-GENDER
+defn swap (g:Gender) -> Gender :
+ switch {_ == g} :
+ UNKNOWN-GENDER : UNKNOWN-GENDER
+ MALE : FEMALE
+ FEMALE : MALE
+ BI-GENDER : BI-GENDER
+
+defn times (g:Gender,flip:Flip) -> Gender :
+ switch {_ == flip} :
+ DEFAULT : g
+ REVERSE : swap(g)
+
+defn times (flip:Flip,g:Gender) -> Gender :
+ switch {_ == flip} :
+ DEFAULT : g
+ REVERSE : swap(g)
defn to-field (p:Port) -> Field :
- if direction(p) == OUTPUT : Field(name(p),FEMALE,type(p))
- else if direction(p) == INPUT : Field(name(p),MALE,type(p))
- else : Field(name(p),UNKNOWN-GENDER,type(p))
+ Field(name(p),REVERSE,type(p))
+ if direction(p) == OUTPUT : Field(name(p),REVERSE,type(p))
+ else if direction(p) == INPUT : Field(name(p),DEFAULT,type(p))
+ else : error("Shouldn't be here")
defmulti gender (e:Expression) -> Gender
defmethod gender (e:Expression) :
MALE ; TODO, why was this OUTPUT before? It makes sense as male, not female
+defmethod print (o:OutputStream, g:Gender) :
+ print{o, _} $
+ switch {g == _} :
+ MALE : "male"
+ FEMALE: "female"
+ BI-GENDER : "bi"
+ UNKNOWN-GENDER: "unknown"
+
;============== DEBUG STUFF =============================
public var PRINT-TYPES : True|False = false
public var PRINT-KINDS : True|False = false
@@ -91,7 +111,7 @@ defmethod print (o:OutputStream, k:Kind) :
(k:StructuralMemKind) : "smem"
defn hasGender (e:Expression|Stmt|Type|Element|Port|Field) :
- e typeof Field|WRef|WSubfield|WIndex|WDefAccessor
+ e typeof WRef|WSubfield|WIndex|WDefAccessor
defn hasWidth (e:Expression|Stmt|Type|Element|Port|Field) :
e typeof UIntType|SIntType|UIntValue|SIntValue
@@ -148,11 +168,6 @@ defmethod map (f: Expression -> Expression, e: WIndex) :
defmethod map (f: Expression -> Expression, c:WDefAccessor) :
WDefAccessor(name(c), f(source(c)), f(index(c)), gender(c))
-;================= DIRECTION ===============================
-;defmulti gender (e:Expression) -> Gender
-;defmethod gender (e:Expression) :
- ;MALE
-
;================= Bring to Working IR ========================
; Returns a new Circuit with Refs, Subfields, Indexes and DefAccessors
; replaced with IR-internal nodes that contain additional
@@ -201,6 +216,7 @@ defn resolve-kinds (c:Circuit) :
for e in entries(s) do :
kinds[key(e)] = get-elem-kind(value(e))
(s:DefWire) : kinds[name(s)] = NodeKind()
+ ;TODO add DefNode
(s:DefRegister) : kinds[name(s)] = RegKind()
(s:DefInstance) : kinds[name(s)] = InstanceKind()
(s:DefMemory) : kinds[name(s)] = MemKind()
@@ -634,13 +650,13 @@ defn resolve-genders (c:Circuit) :
(s) : map(resolve-stmt,s)
defn resolve-expr (e:Expression,desired:Gender) -> Expression :
- defn bundle-field-gender (n:Symbol,t:Type) -> Gender :
+ defn bundle-field-flip (n:Symbol,t:Type) -> Flip :
match(t) :
(b:BundleType) :
val field = for f in fields(b) find :
name(f) == n
match(field):
- (f:Field) : gender(f)
+ (f:Field) : flip(f)
(f) : error(string-join(["Could not find " n " in bundle "]))
(b) : error(string-join(["Accessing subfield " n " on a non-Bundle type."]))
@@ -651,9 +667,9 @@ defn resolve-genders (c:Circuit) :
if gender == BI-GENDER : desired
else : gender
(e:WSubfield) :
- val field-gender = bundle-field-gender(name(e),type(exp(e)))
- val exp* = resolve-expr(exp(e),field-gender * desired)
- val gender* = field-gender * gender(exp*)
+ val field-flip = bundle-field-flip(name(e),type(exp(e)))
+ val exp* = resolve-expr(exp(e),field-flip * desired)
+ val gender* = field-flip * gender(exp*)
WSubfield(exp*,name(e),type(e),gender*)
(e:WIndex) :
val exp* = resolve-expr(exp(e),desired)
@@ -669,8 +685,8 @@ defn resolve-genders (c:Circuit) :
defn resolve-genders (m:Module, c:Circuit) -> Module :
val genders = HashTable<Symbol,Gender>(symbol-hash)
- for m in modules(c) do :
- genders[name(m)] = FEMALE
+ ;for m in modules(c) do :
+ ;genders[name(m)] = FEMALE
resolve-module(m,genders)
@@ -688,28 +704,28 @@ defn resolve-genders (c:Circuit) :
; at the sight of the accessor declaration
; If not accessing a memory, all elements of the vector are
; explicitly written out, then indexed. Depending on the gender
-; of the accessor, it is transformed into ManyConnect (male) or
-; ConnectMany (female)
+; of the accessor, it is transformed into ConnectToIndexed (male) or
+; ConnectFromIndexed (female)
-defstruct ManyConnect <: Stmt :
+defstruct ConnectToIndexed <: Stmt :
index: Expression
locs: List<Expression>
exp: Expression
-defstruct ConnectMany <: Stmt :
+defstruct ConnectFromIndexed <: Stmt :
index: Expression
loc: Expression
exps: List<Expression>
-defmethod print (o:OutputStream, c:ManyConnect) :
+defmethod print (o:OutputStream, c:ConnectToIndexed) :
print-all(o, [locs(c) "[" index(c) "] := " exp(c)])
-defmethod print (o:OutputStream, c:ConnectMany) :
+defmethod print (o:OutputStream, c:ConnectFromIndexed) :
print-all(o, [loc(c) " := " exps(c) "[" index(c) "]"])
-defmethod map (f: Expression -> Expression, c:ManyConnect) :
- ManyConnect(f(index(c)), map(f, locs(c)), f(exp(c)))
-defmethod map (f: Expression -> Expression, c:ConnectMany) :
- ConnectMany(f(index(c)), f(loc(c)), map(f, exps(c)))
+defmethod map (f: Expression -> Expression, c:ConnectToIndexed) :
+ ConnectToIndexed(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)))
defn expand-vector (e:Expression) -> List<Expression> :
match(e) :
@@ -761,10 +777,10 @@ defn expand-stmt (s:Stmt,preds:List<Expression>) -> Stmt :
switch {gender(s) == _} :
MALE : Begin(list(wire,connectmany)) where :
val exps = expand-vector(source(s))
- val connectmany = ConnectMany(index(s),WRef(name(s),value-type,NodeKind(),FEMALE),exps)
+ val connectmany = ConnectFromIndexed(index(s),WRef(name(s),value-type,NodeKind(),FEMALE),exps)
FEMALE: Begin(list(wire,manyconnect)) where :
val locs = expand-vector(source(s))
- val manyconnect = ManyConnect(index(s),locs,WRef(name(s),value-type,NodeKind(),MALE))
+ val manyconnect = ConnectToIndexed(index(s),locs,WRef(name(s),value-type,NodeKind(),MALE))
(s:Conditionally) :
val conseq* = expand-stmt(conseq(s),List(pred(s),preds))
val alt-pred = DoPrim(EQUAL-UU-OP,list(UIntValue(0,IntWidth(1)),pred(s)),list(),UIntType(IntWidth(1)))
@@ -779,7 +795,45 @@ defn expand-accessors (c:Circuit) :
Module(name(m),ports(m),expand-stmt(body(m),list()))
-;;=============== BUNDLE FLATTENING =========================
+;;=============== LOWERING TO GROUND TYPES =============================
+; All non-ground (elevated) types (Vectors, Bundles) are expanded out to
+; individual ground types.
+; This pass involves filling a table mapping the name of elevated types
+; to the lowered ground expression names and genders. This allows
+; references to be resolved.
+
+;defn build-table (t:Type,f:Flip,l:List<KeyValue<Symbol,Flip>>) -> List<KeyValue<Symbol,Flip>> :
+; match (t) :
+; (t:BundleType) :
+; for field in fields(t) map :
+; match(type(field)) :
+; (t:BundleType) : append(l,lower-type(t,f * flip(field),l))
+; (t:VectorType) : append(l,lower-type(t,f * flip(field),l))
+; (t) : List(KeyValue(gensym(),f * flip(field)))
+; (t:VectorType) :
+; match(type(f)) :
+; (t:BundleType) : append(l,lower-type(t,f,l))
+; (t:VectorType) : append(l,lower-type(t,f,l))
+; (t) :
+; for i in size(t) map :
+; List(KeyValue(gensym(),f))
+; (t) : l
+;
+;defn build-table (ports:List<Port>) -> HashMap<Symbol,List<[Symbol,Gender]>> :
+; for p in ports do :
+; match(type(p)) :
+; (t:BundleType) :
+;
+;defn lower-module (m:Module,c:Circuit) -> Module :
+;
+;
+;defn lower-to-ground (c:Circuit) :
+; Circuit(modules*, main(c)) where :
+; val modules* =
+; for m in modules(c) map :
+; lower-module(m,c)
+
+
;defn prefix (prefix, suffix) :
; symbol-join([prefix "/" suffix])
;
diff --git a/test/passes/infer-types/bundle.fir b/test/passes/infer-types/bundle.fir
index 0c4fa760..d9b86115 100644
--- a/test/passes/infer-types/bundle.fir
+++ b/test/passes/infer-types/bundle.fir
@@ -3,9 +3,9 @@
;CHECK: Infer Types
circuit top :
module subtracter :
- wire z : {male x : UInt, female y: SInt}
- node x = z.x ;CHECK: node x = z@<t:{male x : UInt@<t:UInt>, female y : SInt@<t:SInt>}>.x@<t:UInt>
- node y = z.y ;CHECK: node y = z@<t:{male x : UInt@<t:UInt>, female y : SInt@<t:SInt>}>.y@<t:SInt>
+ wire z : { x : UInt, flip y: SInt}
+ node x = z.x ;CHECK: node x = z@<t:{ x : UInt@<t:UInt>, flip y : SInt@<t:SInt>}>.x@<t:UInt>
+ node y = z.y ;CHECK: node y = z@<t:{ x : UInt@<t:UInt>, flip y : SInt@<t:SInt>}>.y@<t:SInt>
wire a : UInt(3)[10] ;CHECK: wire a : UInt(3)[10]@<t:UInt>@<t:UInt(3)[10]@<t:UInt>>
node b = a.2 ;CHECK: node b = a@<t:UInt(3)[10]@<t:UInt>>.2@<t:UInt>
diff --git a/test/passes/infer-types/gcd.fir b/test/passes/infer-types/gcd.fir
index b4d92269..ea134c2f 100644
--- a/test/passes/infer-types/gcd.fir
+++ b/test/passes/infer-types/gcd.fir
@@ -22,14 +22,14 @@ circuit top :
when gt(x, y) :
;CHECK: when gt(x@<t:UInt>, y@<t:UInt>)@<t:UInt> :
inst s of subtracter
- ;CHECK: inst s of subtracter@<t:{male x : UInt@<t:UInt>, male y : UInt@<t:UInt>, female z : UInt@<t:UInt>, male reset : UInt(1)@<t:UInt>}>
+ ;CHECK: inst s of subtracter@<t:{ x : UInt@<t:UInt>, y : UInt@<t:UInt>, flip z : UInt@<t:UInt>, reset : UInt(1)@<t:UInt>}>
s.x := x
s.y := y
x := s.z
- ;CHECK: s@<t:{male x : UInt@<t:UInt>, male y : UInt@<t:UInt>, female z : UInt@<t:UInt>, male reset : UInt(1)@<t:UInt>}>.reset@<t:UInt> := reset@<t:UInt>
- ;CHECK: s@<t:{male x : UInt@<t:UInt>, male y : UInt@<t:UInt>, female z : UInt@<t:UInt>, male reset : UInt(1)@<t:UInt>}>.x@<t:UInt> := x@<t:UInt>
- ;CHECK: s@<t:{male x : UInt@<t:UInt>, male y : UInt@<t:UInt>, female z : UInt@<t:UInt>, male reset : UInt(1)@<t:UInt>}>.y@<t:UInt> := y@<t:UInt>
- ;CHECK: x@<t:UInt> := s@<t:{male x : UInt@<t:UInt>, male y : UInt@<t:UInt>, female z : UInt@<t:UInt>, male reset : UInt(1)@<t:UInt>}>.z@<t:UInt>
+ ;CHECK: s@<t:{ x : UInt@<t:UInt>, y : UInt@<t:UInt>, flip z : UInt@<t:UInt>, reset : UInt(1)@<t:UInt>}>.reset@<t:UInt> := reset@<t:UInt>
+ ;CHECK: s@<t:{ x : UInt@<t:UInt>, y : UInt@<t:UInt>, flip z : UInt@<t:UInt>, reset : UInt(1)@<t:UInt>}>.x@<t:UInt> := x@<t:UInt>
+ ;CHECK: s@<t:{ x : UInt@<t:UInt>, y : UInt@<t:UInt>, flip z : UInt@<t:UInt>, reset : UInt(1)@<t:UInt>}>.y@<t:UInt> := y@<t:UInt>
+ ;CHECK: x@<t:UInt> := s@<t:{ x : UInt@<t:UInt>, y : UInt@<t:UInt>, flip z : UInt@<t:UInt>, reset : UInt(1)@<t:UInt>}>.z@<t:UInt>
else :
inst s2 of subtracter
s2.x := x
diff --git a/test/passes/resolve-genders/ports.fir b/test/passes/resolve-genders/ports.fir
index ea92cd24..d790272c 100644
--- a/test/passes/resolve-genders/ports.fir
+++ b/test/passes/resolve-genders/ports.fir
@@ -10,7 +10,7 @@ circuit top :
input data : UInt(16)
output ready : UInt(1)
module top:
- wire connect : { male data : UInt(16), female ready: UInt(1) }
+ wire connect : { data : UInt(16), flip ready: UInt(1) }
inst src of source ;CHECK: inst src of source@<g:female>
inst snk of sink ;CHECK: inst snk of sink@<g:female>
connect.data := src.data ;CHECK: connect@<g:female>.data@<g:female> := src@<g:female>.data@<g:male>