From 2353d640907a7b04477b06a5b3da6b7bbafc448d Mon Sep 17 00:00:00 2001 From: azidar Date: Tue, 24 Feb 2015 09:40:02 -0800 Subject: Updated tests, and included a check for the name of the pass, which allows the compiler to print after each pass to ease debugging --- .gitignore | 6 ++- README.md | 13 ++++++ TODO | 4 ++ notes/notes.02.23.15.txt | 10 +++++ src/main/stanza/passes.stanza | 64 +++++++++++++++++---------- test/passes/infer-types/gcd.fir | 46 +++++++++++++++++++ test/passes/infer-types/primops.fir | 8 ++++ test/passes/initialize-register/begin.fir | 2 + test/passes/initialize-register/when.fir | 3 +- test/passes/make-explicit-reset/abc.fir | 27 ----------- test/passes/make-explicit-reset/mix-reset.fir | 28 ++++++++++++ test/passes/resolve-kinds/ab.fir | 48 -------------------- test/passes/resolve-kinds/gcd.fir | 49 ++++++++++++++++++++ 13 files changed, 206 insertions(+), 102 deletions(-) create mode 100644 notes/notes.02.23.15.txt create mode 100644 test/passes/infer-types/gcd.fir create mode 100644 test/passes/infer-types/primops.fir delete mode 100644 test/passes/make-explicit-reset/abc.fir create mode 100644 test/passes/make-explicit-reset/mix-reset.fir delete mode 100644 test/passes/resolve-kinds/ab.fir create mode 100644 test/passes/resolve-kinds/gcd.fir diff --git a/.gitignore b/.gitignore index 7b79b1f7..f33036d1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,10 @@ src/lib/stanzam src/*/__MACOSX src/main/stanza/firrtl-main utils/bin/firrtl -test/unit/Output -test/unit/*.out +test/passes/Output +test/passes/*/Output +test/passes/*.out +test/passes/*/*.out spec/spec.aux spec/spec.log spec/spec.pdf diff --git a/README.md b/README.md index 5db5bc8f..ef050aae 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,16 @@ Secondary TODO: Install lit: pip install lit + + +Stanza Installation: + git clone https://github.com/ucb-bar/firrtl + cd src/lib + unzip stanzam.zip + cd stanzam + sudo ./stanzam -platform os-x -install /usr/local/bin/stanzam + + + + + diff --git a/TODO b/TODO index 6349628e..722f395f 100644 --- a/TODO +++ b/TODO @@ -3,3 +3,7 @@ Make stanza a git repo Write installation instructions for stanza Need 2 different prints, one with IR-internal information, and another that matches correct FIRRTL +Tests: + Error if declare anything other than module in circuit + Error if incorrectly assign stuff, like use = instead of := + diff --git a/notes/notes.02.23.15.txt b/notes/notes.02.23.15.txt new file mode 100644 index 00000000..1f58ddaf --- /dev/null +++ b/notes/notes.02.23.15.txt @@ -0,0 +1,10 @@ +TODO: rename ! to *. + +when declare a var, give it a type because compiler assumes it is ? + +if costantantly adding to end of a list, should use a vector type instead of a list, because add is much faster than append (depends on length of left operand) + +TODO: test case + inst a of mywire + + diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index eb9151ab..f1c9b248 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -62,7 +62,11 @@ defmethod print (o:OutputStream, k:Kind) : (k:StructuralMemKind) : "smem:" defmethod print (o:OutputStream, e:WRef) : - print-all(o,[kind(e) name(e)]) + match(type(e)) : + (t:UnknownType) : + print-all(o,[kind(e) name(e)]) + (t) : + print-all(o,[kind(e) name(e) ":" type(e)]) defmethod print (o:OutputStream, e:WField) : print-all(o,[exp(e) "." name(e)]) @@ -212,7 +216,8 @@ defn make-explicit-reset (c:Circuit) : ; This pass replaces the reg.init construct by creating a new ; wire that holds the value at initialization. This wire ; is then connected to the register conditionally on reset, -; at the end of that register's scope. +; at the end of the scope containing the register +; declaration ; If a register has no inital value, the wire is connected to ; a NULL node. Later passes will remove these with the base ; case Mux(reset,NULL,a) -> a, and Mux(reset,a,NULL) -> a. @@ -221,15 +226,19 @@ defn make-explicit-reset (c:Circuit) : defn initialize-registers (c:Circuit) : defn add-when (s:Stmt,renames:HashTable) -> Stmt : - Begin(list(s,when-reset)) where : - var inits = List() - for kv in renames do : - val refreg = WRef(key(kv),UnknownType(),RegKind(),UNKNOWN-DIR) - val refwire = WRef(value(kv),UnknownType(),NodeKind(),UNKNOWN-DIR) - val connect = Connect(refreg,refwire) - inits = append(inits,list(connect)) + var inits = List() + for kv in renames do : + val refreg = WRef(key(kv),UnknownType(),RegKind(),UNKNOWN-DIR) + val refwire = WRef(value(kv),UnknownType(),NodeKind(),UNKNOWN-DIR) + val connect = Connect(refreg,refwire) + inits = append(inits,list(connect)) + if empty?(inits) : + s + else : val pred = WRef(`reset, UnknownType(), PortKind(), UNKNOWN-DIR) val when-reset = Conditionally(pred,Begin(inits),Begin(List())) + Begin(list(s,when-reset)) + defn rename (s:Stmt,l:HashTable) -> Stmt : defn rename-stmt (s:Stmt) -> Stmt : map{rename-expr,_} $ @@ -268,38 +277,43 @@ defn initialize-registers (c:Circuit) : [Begin(body!),renames] where : val defreg = s val defwire = DefWire(wire-name,type(s)) - val conwire = Connect(WRef(wire-name,type(s),NodeKind(),UNKNOWN-DIR),Null()) + val conwire = Connect(WRef(wire-name,UnknownType(),NodeKind(),UNKNOWN-DIR),Null()) val body! = list(defreg,defwire,conwire) (s:Conditionally) : [Conditionally(pred(s),initialize-scope(conseq(s)),initialize-scope(alt(s))),empty-hash] + (s:LetRec) : + [LetRec(entries(s),initialize-scope(body(s))),empty-hash] ;TODO Add Letrec (s) : [s,empty-hash] defn initialize-scope (s:Stmt) -> Stmt : - defn run-initialize (s:Stmt) -> Stmt : - val [s!,renames] = initialize-registers(s) - val s!! = rename(s!,renames) - val s!!! = add-when(s!!,renames) - s!!! - match(s) : - (s:Begin) : run-initialize(s) - (s:DefRegister) : run-initialize(s) - (s:Conditionally) : run-initialize(s) - ;TODO Add Letrec - (s) : s + val [s!,renames] = initialize-registers(s) + val s!! = rename(s!,renames) + val s!!! = add-when(s!!,renames) + s!!! - defn initialize-scope (m:Module) -> Module : + defn initialize-module (m:Module) -> Module : Module(name(m), ports(m), body!) where : val body! = initialize-scope(body(m)) Circuit(modules*, main(c)) where : val modules* = for m in modules(c) map : - initialize-scope(m) + initialize-module(m) ;============== INFER TYPES ================================ +; This pass infers the type field in all IR nodes by updating +; and passing an environment to all statements in pre-order +; traversal, and resolving types in expressions in post- +; order traversal. +; Type propagation for primary ops are defined here. +; Notable cases: LetRec requires updating environment before +; resolving the subexpressions in its elements. +; Type errors are not checked in this pass, as this is +; postponed for a later/earlier pass. + defmethod type (v:UIntValue) : UIntType(width(v)) @@ -327,6 +341,7 @@ defn infer (op:PrimOp, arg-types: List) -> Type : defn arg0 () : wipe-width(arg-types[0]) defn arg1 () : wipe-width(arg-types[1]) + ; TODO subtle, not entirely figured out switch {op == _} : ADD-OP : arg0() ADD-MOD-OP : arg0() @@ -380,6 +395,7 @@ defn infer (c:Stmt, e:List>) -> [Stmt, List>) : match(e) : @@ -1883,6 +1899,7 @@ public defn run-passes (c: Circuit, p: List) : defn do-stage (name:String, f: Circuit -> Circuit) : println(name) c* = f(c*) + println(c*) ; Early passes: ; If modules have a reset defined, must be an INPUT and UInt(1) @@ -1902,7 +1919,6 @@ public defn run-passes (c: Circuit, p: List) : if contains(p,'n') : do-stage("Pad Widths", pad-widths) if contains(p,'o') : do-stage("Inline Instances", inline-instances) - println(c*) println("\n\n\n\n") diff --git a/test/passes/infer-types/gcd.fir b/test/passes/infer-types/gcd.fir new file mode 100644 index 00000000..b261f0d1 --- /dev/null +++ b/test/passes/infer-types/gcd.fir @@ -0,0 +1,46 @@ +; RUN: firrtl %s abcde | tee %s.out | FileCheck %s + +;CHECK: Infer Types +circuit top : + module subtracter : + input x : UInt + input y : UInt + output z : UInt + z := sub-mod(x, y) + module gcd : + input a : UInt(16) + input b : UInt(16) + input e : UInt(1) + output z : UInt(16) + output v : UInt(1) + reg x : UInt + reg y : UInt +; CHECK: reg x : UInt + x.init := UInt(0) + y.init := UInt(42) + when greater(x, y) : + inst s of subtracter + s.x := x + s.y := y + x := s.z + else : + inst s2 of subtracter + s2.x := x + s2.y := y + y := s2.z + when e : + x := a + y := b + v := equal(v, UInt(0)) + z := x + module top : + input a : UInt(16) + input b : UInt(16) + output z : UInt + inst i of gcd + i.a := a + i.b := b + i.e := UInt(1) + z := i.z + + diff --git a/test/passes/infer-types/primops.fir b/test/passes/infer-types/primops.fir new file mode 100644 index 00000000..fa0f0c90 --- /dev/null +++ b/test/passes/infer-types/primops.fir @@ -0,0 +1,8 @@ +; RUN: firrtl %s abcde | tee %s.out | FileCheck %s + +;CHECK: Infer Types +circuit top : + module top : + wire io : {input x : UInt, output y : UInt} + io.x := add(io.x,io.y) +;CHECK: n:io:{input x : UInt, output y : UInt}.x := add(n:io:{input x : UInt, output y : UInt}.x, n:io:{input x : UInt, output y : UInt}.y) diff --git a/test/passes/initialize-register/begin.fir b/test/passes/initialize-register/begin.fir index 9d4de49e..4f64b071 100644 --- a/test/passes/initialize-register/begin.fir +++ b/test/passes/initialize-register/begin.fir @@ -1,5 +1,6 @@ ; RUN: firrtl %s abcd | tee %s.out | FileCheck %s +; CHECK: Initialize Registers circuit top : module top : input a : UInt(16) @@ -12,6 +13,7 @@ reg r2 : UInt r2.init := UInt(0) +; CHECK-NOT: r2.init := UInt(0) ; CHECK: wire [[R2:gen[0-9]*]] : UInt ; CHECK-NOT: reg:r2 := n:[[R2]] ; CHECK: n:[[R2]] := Null diff --git a/test/passes/initialize-register/when.fir b/test/passes/initialize-register/when.fir index e4749abe..c563d639 100644 --- a/test/passes/initialize-register/when.fir +++ b/test/passes/initialize-register/when.fir @@ -1,5 +1,6 @@ ; RUN: firrtl %s abcd | tee %s.out | FileCheck %s -; CHECK: circuit top : + +; CHECK: Initialize Registers circuit top : module top : input a : UInt(16) diff --git a/test/passes/make-explicit-reset/abc.fir b/test/passes/make-explicit-reset/abc.fir deleted file mode 100644 index caed07ab..00000000 --- a/test/passes/make-explicit-reset/abc.fir +++ /dev/null @@ -1,27 +0,0 @@ -; RUN: firrtl %s abc | tee %s.out | FileCheck %s - -circuit top : - module A : - ;CHECK: input reset : UInt(1) - input x : UInt(16) - output y : UInt(16) - inst b of B - ;CHECK: inst:b.reset := port:reset - module B : - input reset : UInt(1) - ;CHECK: input reset : UInt(1) - input x : UInt(16) - output y : UInt(16) - inst c of C - ;CHECK: inst:c.reset := port:reset - module C : - ;CHECK: input reset : UInt(1) - input a : UInt(16) - input b : UInt(16) - module top : - ;CHECK: input reset : UInt(1) - input a : UInt(16) - input b : UInt(16) - output z : UInt - inst a of A - ;CHECK: inst:a.reset := port:reset diff --git a/test/passes/make-explicit-reset/mix-reset.fir b/test/passes/make-explicit-reset/mix-reset.fir new file mode 100644 index 00000000..23a1232a --- /dev/null +++ b/test/passes/make-explicit-reset/mix-reset.fir @@ -0,0 +1,28 @@ +; RUN: firrtl %s abc | tee %s.out | FileCheck %s + +; CHECK: Make Explicit Reset +circuit top : + module A : + ;CHECK: input reset : UInt(1) + input x : UInt(16) + output y : UInt(16) + inst b of B + ;CHECK: inst:b.reset := port:reset + module B : + input reset : UInt(1) + ;CHECK: input reset : UInt(1) + input x : UInt(16) + output y : UInt(16) + inst c of C + ;CHECK: inst:c.reset := port:reset + module C : + ;CHECK: input reset : UInt(1) + input a : UInt(16) + input b : UInt(16) + module top : + ;CHECK: input reset : UInt(1) + input a : UInt(16) + input b : UInt(16) + output z : UInt + inst a of A + ;CHECK: inst:a.reset := port:reset diff --git a/test/passes/resolve-kinds/ab.fir b/test/passes/resolve-kinds/ab.fir deleted file mode 100644 index e6f28c21..00000000 --- a/test/passes/resolve-kinds/ab.fir +++ /dev/null @@ -1,48 +0,0 @@ -; RUN: firrtl %s ab | tee %s.out | FileCheck %s - -circuit top : - module subtracter : - input x : UInt - input y : UInt - output z : UInt - z := sub-mod(x, y) -; CHECK: port:z := sub-mod(port:x, port:y) - module gcd : - input a : UInt(16) - input b : UInt(16) - input e : UInt(1) - output z : UInt(16) - output v : UInt(1) - reg x : UInt - reg y : UInt - x.init := UInt(0) - y.init := UInt(42) - when greater(x, y) : - inst s of subtracter - s.x := x -; CHECK: inst:s.x := reg:x - s.y := y - x := s.z - else : - inst s2 of subtracter - s2.x := x - s2.y := y - y := s2.z - when e : - x := a - y := b - v := equal(v, UInt(0)) - z := x - module top : - input a : UInt(16) - input b : UInt(16) - output z : UInt - inst i of gcd -; CHECK: inst i of module:gcd - i.a := a - i.b := b - i.e := UInt(1) - z := i.z -; CHECK: port:z := inst:i.z - - diff --git a/test/passes/resolve-kinds/gcd.fir b/test/passes/resolve-kinds/gcd.fir new file mode 100644 index 00000000..83091f67 --- /dev/null +++ b/test/passes/resolve-kinds/gcd.fir @@ -0,0 +1,49 @@ +; RUN: firrtl %s ab | tee %s.out | FileCheck %s + +; CHECK: Resolve Kinds +circuit top : + module subtracter : + input x : UInt + input y : UInt + output z : UInt + z := sub-mod(x, y) +; CHECK: port:z := sub-mod(port:x, port:y) + module gcd : + input a : UInt(16) + input b : UInt(16) + input e : UInt(1) + output z : UInt(16) + output v : UInt(1) + reg x : UInt + reg y : UInt + x.init := UInt(0) + y.init := UInt(42) + when greater(x, y) : + inst s of subtracter + s.x := x +; CHECK: inst:s.x := reg:x + s.y := y + x := s.z + else : + inst s2 of subtracter + s2.x := x + s2.y := y + y := s2.z + when e : + x := a + y := b + v := equal(v, UInt(0)) + z := x + module top : + input a : UInt(16) + input b : UInt(16) + output z : UInt + inst i of gcd +; CHECK: inst i of module:gcd + i.a := a + i.b := b + i.e := UInt(1) + z := i.z +; CHECK: port:z := inst:i.z + + -- cgit v1.2.3