aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/compilers.stanza25
-rw-r--r--src/main/stanza/custom-compiler.stanza4
-rw-r--r--src/main/stanza/errors.stanza84
-rw-r--r--src/main/stanza/firrtl-test-main.stanza32
-rw-r--r--src/main/stanza/flo.stanza9
-rw-r--r--src/main/stanza/ir-utils.stanza2
-rw-r--r--src/main/stanza/passes.stanza5
-rw-r--r--src/main/stanza/verilog.stanza9
8 files changed, 100 insertions, 70 deletions
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza
index c087e66e..1ca84035 100644
--- a/src/main/stanza/compilers.stanza
+++ b/src/main/stanza/compilers.stanza
@@ -9,7 +9,7 @@ defpackage firrtl/compiler :
import firrtl/ir-utils
public defstruct StandardFlo <: Compiler :
- file: String with: (as-method => true)
+ with-output : (() -> False) -> False with: (as-method => true)
public defmethod passes (c:StandardFlo) -> List<Pass> :
to-list $ [
RemoveSpecialChars()
@@ -35,11 +35,11 @@ public defmethod passes (c:StandardFlo) -> List<Pass> :
RemoveSpecialChars()
CheckHighForm()
CheckLowForm()
- Flo(file(c))
+ Flo(with-output(c))
]
public defstruct StandardVerilog <: Compiler :
- file: String with: (as-method => true)
+ with-output : (() -> False) -> False with: (as-method => true)
public defmethod passes (c:StandardVerilog) -> List<Pass> :
to-list $ [
RemoveSpecialChars()
@@ -66,9 +66,10 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> :
CheckHighForm()
CheckLowForm()
CheckInitialization()
- Verilog(file(c))
+ Verilog(with-output(c))
]
+
;============= DRIVER ======================================
public defn run-passes (c:Circuit,comp:Compiler) :
run-passes(c,passes(comp))
@@ -82,20 +83,20 @@ public defn run-passes (c:Circuit,ls:List<Pass>) :
var t = start-time
val time-table = Vector<[String,Int]>()
for p in ls do :
- println-all(STANDARD-OUTPUT,["Starting " name(p)])
+ println-all(["Starting " name(p)])
if PRINT-CIRCUITS : println(name(p))
c* = pass(p)(c*)
if PRINT-CIRCUITS : print(c*)
val current-time = to-int(to-string(current-time-us() / to-long(1000)))
- println-all(STANDARD-OUTPUT,["Finished " name(p)])
- println-all(STANDARD-ERROR,["Milliseconds since start: " current-time - start-time])
- println-all(STANDARD-ERROR,["Milliseconds for this pass: " current-time - t])
- println-all(STANDARD-ERROR,["\n"])
+ println-all(["Finished " name(p)])
+ println-all(["Milliseconds since start: " current-time - start-time])
+ println-all(["Milliseconds for this pass: " current-time - t])
+ println-all(["\n"])
add(time-table,[name(p), current-time - t])
t = current-time
- println(STANDARD-ERROR,"===== Time Breakdown =====")
+ println("===== Time Breakdown =====")
for x in time-table do :
- println-all(STANDARD-ERROR,[x[0] " --- " to-float(x[1] as Int * 100) / to-float(t - start-time) "%"])
- println(STANDARD-ERROR,"==========================")
+ println-all([x[0] " --- " to-float(x[1] as Int * 100) / to-float(t - start-time) "%"])
+ println("==========================")
println("Done!")
diff --git a/src/main/stanza/custom-compiler.stanza b/src/main/stanza/custom-compiler.stanza
index 4d63a173..85275c94 100644
--- a/src/main/stanza/custom-compiler.stanza
+++ b/src/main/stanza/custom-compiler.stanza
@@ -9,7 +9,7 @@ defpackage firrtl/custom-compiler :
import firrtl/custom-passes
public defstruct InstrumentedVerilog <: Compiler :
- file: String with: (as-method => true)
+ with-output: (() -> False) -> False with: (as-method => true)
args: List<String>
public defmethod passes (c:InstrumentedVerilog) -> List<Pass> :
to-list $ [
@@ -36,7 +36,7 @@ public defmethod passes (c:InstrumentedVerilog) -> List<Pass> :
RemoveSpecialChars()
CheckHighForm()
CheckLowForm()
- Verilog(file(c))
+ Verilog(with-output(c))
]
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index 5451b632..8727f762 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -45,38 +45,40 @@ public defmethod pass (b:CheckHighForm) -> (Circuit -> Circuit) : check-high-for
public defmethod name (b:CheckHighForm) -> String : "High Form Check"
public defmethod short-name (b:CheckHighForm) -> String : "high-form-check"
+var mname = ""
+
;----------------- Errors ------------------------
defn NotUnique (info:FileInfo, name:Symbol) :
PassException $ string-join $
- [info ": Reference " name " does not have a unique name."]
+ [info ": [module " mname "] Reference " name " does not have a unique name."]
defn IsPrefix (info:FileInfo, prefix:Symbol) :
PassException $ string-join $
- [info ": Symbol " prefix " is a prefix."]
-
+ [info ": [module " mname "] Symbol " prefix " is a prefix."]
+
defn InvalidLOC (info:FileInfo) :
PassException $ string-join $
- [info ": Invalid connect to an expression that is not a reference or a WritePort."]
+ [info ": [module " mname "] Invalid connect to an expression that is not a reference or a WritePort."]
defn NegUInt (info:FileInfo) :
PassException $ string-join $
- [info ": UIntValue cannot be negative."]
+ [info ": [module " mname "] UIntValue cannot be negative."]
defn UndeclaredReference (info:FileInfo, name:Symbol) :
PassException $ string-join $
- [info ": Reference " name " is not declared."]
+ [info ": [module " mname "] Reference " name " is not declared."]
defn MemWithFlip (info:FileInfo, name:Symbol) :
PassException $ string-join $
- [info ": Memory " name " cannot be a bundle type with flips."]
+ [info ": [module " mname "] Memory " name " cannot be a bundle type with flips."]
defn InvalidSubfield (info:FileInfo) :
PassException $ string-join $
- [info ": Invalid subfield access to non-reference."]
+ [info ": [module " mname "] Invalid subfield access to non-reference."]
defn InvalidIndex (info:FileInfo) :
PassException $ string-join $
- [info ": Invalid index access to non-reference."]
+ [info ": [module " mname "] Invalid index access to non-reference."]
defn NoTopModule (info:FileInfo, name:Symbol) :
PassException $ string-join $
@@ -92,19 +94,19 @@ defn ModuleNotDefined (info:FileInfo, name:Symbol) :
defn IncorrectNumArgs (info:FileInfo, op:Symbol, n:Int) :
PassException $ string-join $
- [info ": Primop " op " requires " n " expression arguments."]
+ [info ": [module " mname "] Primop " op " requires " n " expression arguments."]
defn IncorrectNumConsts (info:FileInfo, op:Symbol, n:Int) :
PassException $ string-join $
- [info ": Primop " op " requires " n " integer arguments."]
+ [info ": [module " mname "] Primop " op " requires " n " integer arguments."]
defn NegWidth (info:FileInfo) :
PassException $ string-join $
- [info ": Width cannot be negative."]
+ [info ": [module " mname "] Width cannot be negative."]
defn NegVecSize (info:FileInfo) :
PassException $ string-join $
- [info ": Vector type size cannot be negative."]
+ [info ": [module " mname "] Vector type size cannot be negative."]
;---------------- Helper Functions --------------
defn has-flip? (t:Type) -> True|False :
@@ -337,6 +339,7 @@ public defn check-high-form (c:Circuit) -> Circuit :
s }()
defn check-high-form-m (m:Module) -> False :
+ mname = name(m)
val names = HashTable<Symbol,True>(symbol-hash)
val mnames = HashTable<Symbol,True>(symbol-hash)
for m in modules(c) do :
@@ -384,15 +387,15 @@ public defmethod short-name (b:CheckKinds) -> String : "check-kinds"
;----------------- Errors ---------------------
defn NotMem (info:FileInfo, name:Symbol) :
PassException $ string-join $
- [info ": Reference " name " must be a mem."]
+ [info ": [module " mname "] Reference " name " must be a mem."]
defn IsMem (info:FileInfo, name:Symbol) :
PassException $ string-join $
- [info ": Reference " name " cannot be a mem."]
+ [info ": [module " mname "] Reference " name " cannot be a mem."]
defn OnResetNotReg (info:FileInfo, name:Symbol) :
PassException $ string-join $
- [info ": Illegal on-reset to non-reg reference " name "."]
+ [info ": [module " mname "] 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
@@ -439,6 +442,7 @@ public defn check-kinds (c:Circuit) -> Circuit :
do(check-kinds-s,s)
for m in modules(c) do :
+ mname = name(m)
match(m) :
(m:ExModule) : false
(m:InModule) : check-kinds-s(body(m))
@@ -465,55 +469,55 @@ public defmethod short-name (b:CheckTypes) -> String : "check-types"
;----------------- Errors ---------------------
defn SubfieldNotInBundle (info:FileInfo, name:Symbol) :
PassException $ string-join $
- [info ": Subfield " name " is not in bundle."]
+ [info ": [module " mname "] Subfield " name " is not in bundle."]
defn SubfieldOnNonBundle (info:FileInfo, name:Symbol) :
PassException $ string-join $
- [info ": Subfield " name " is accessed on a non-bundle."]
+ [info ": [module " mname "] 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."]
+ [info ": [module " mname "] Index with value " value " is too large."]
defn IndexOnNonVector (info:FileInfo) :
PassException $ string-join $
- [info ": Index illegal on non-vector type."]
+ [info ": [module " mname "] Index illegal on non-vector type."]
defn IndexNotUInt (info:FileInfo) :
PassException $ string-join $
- [info ": Index is not of UIntType."]
+ [info ": [module " mname "] Index is not of UIntType."]
defn EnableNotUInt (info:FileInfo) :
PassException $ string-join $
- [info ": Enable is not of UIntType."]
+ [info ": [module " mname "] Enable is not of UIntType."]
defn InvalidConnect (info:FileInfo) :
PassException $ string-join $
- [info ": Type mismatch."]
+ [info ": [module " mname "] Type mismatch."]
defn PredNotUInt (info:FileInfo) :
PassException $ string-join $
- [info ": Predicate not a UIntType."]
+ [info ": [module " mname "] Predicate not a UIntType."]
defn OpNotGround (info:FileInfo, op:Symbol) :
PassException $ string-join $
- [info ": Primop " op " cannot operate on non-ground types."]
+ [info ": [module " mname "] Primop " op " cannot operate on non-ground types."]
defn OpNotUInt (info:FileInfo, op:Symbol,e:Symbol) :
PassException $ string-join $
- [info ": Primop " op " requires argument " e " to be a UInt type."]
+ [info ": [module " mname "] Primop " op " requires argument " e " to be a UInt type."]
defn OpNotAllUInt (info:FileInfo, op:Symbol) :
PassException $ string-join $
- [info ": Primop " op " requires all arguments to be UInt type."]
+ [info ": [module " mname "] Primop " op " requires all arguments to be UInt type."]
defn OpNotAllSameType (info:FileInfo, op:Symbol) :
PassException $ string-join $
- [info ": Primop " op " requires all operands to have the same type."]
+ [info ": [module " mname "] Primop " op " requires all operands to have the same type."]
defn NodeWithFlips (info:FileInfo) :
PassException $ string-join $
- [info ": Node cannot be a bundle type with flips."]
+ [info ": [module " mname "] Node cannot be a bundle type with flips."]
;---------------- Helper Functions --------------
@@ -634,6 +638,7 @@ public defn check-types (c:Circuit) -> Circuit :
s }()
for m in modules(c) do :
+ mname = name(m)
match(m) :
(m:ExModule) : false
(m:InModule) : check-types-s(body(m))
@@ -654,11 +659,11 @@ public defmethod short-name (b:CheckGenders) -> String : "check-genders"
;----------------- Errors ---------------------
defn WrongGender (info:FileInfo,expr:Symbol,wrong:Symbol,right:Symbol) :
PassException $ string-join $
- [info ": Expression " expr " is used as a " wrong " but can only be used as a " right "."]
+ [info ": [module " mname "] Expression " expr " is used as a " wrong " but can only be used as a " right "."]
defn InferDirection (info:FileInfo,name:Symbol) :
PassException $ string-join $
- [info ": Accessor " name " has a direction that requires inference."]
+ [info ": [module " mname "] Accessor " name " has a direction that requires inference."]
;---------------- Helper Functions --------------
defn dir-to-gender (d:PortDirection) -> Gender :
@@ -747,6 +752,7 @@ public defn check-genders (c:Circuit) -> Circuit :
for m in modules(c) do :
+ mname = name(m)
val genders = HashTable<Symbol,Gender>(symbol-hash)
for p in ports(m) do :
genders[name(p)] = dir-to-gender(direction(p))
@@ -773,27 +779,27 @@ public defmethod short-name (b:CheckLowForm) -> String : "low-form-check"
;----------------- Errors ------------------------
defn InvalidVec (info:FileInfo,name:Symbol) :
PassException $ string-join $
- [info ": Expression " name " has an illegal vector type."]
+ [info ": [module " mname "] Expression " name " has an illegal vector type."]
defn InvalidBundle (info:FileInfo,name:Symbol) :
PassException $ string-join $
- [info ": Expression " name " has an illegal bundle type."]
+ [info ": [module " mname "] Expression " name " has an illegal bundle type."]
defn NoWhen (info:FileInfo) :
PassException $ string-join $
- [info ": Illegal when statement. No when statements with multiple statements are allowed in low firrtl."]
+ [info ": [module " mname "] Illegal when statement. No when statements with multiple statements are allowed in low firrtl."]
defn SingleAssignment (info:FileInfo,name:Symbol) :
PassException $ string-join $
- [info ": Illegal assignment to " name ". Wires can only be assigned to once."]
+ [info ": [module " mname "] Illegal assignment to " name ". Wires can only be assigned to once."]
defn NoOnReset (info:FileInfo) :
PassException $ string-join $
- [info ": Invalid use of on-reset. No on-resets are allowed in low firrtl."]
+ [info ": [module " mname "] Invalid use of on-reset. No on-resets are allowed in low firrtl."]
defn NoBulkConnect (info:FileInfo) :
PassException $ string-join $
- [info ": Invalid use of <>. No <>'s are allowed in low firrtl."]
+ [info ": [module " mname "] Invalid use of <>. No <>'s are allowed in low firrtl."]
;---------------- Helper Functions --------------
@@ -860,6 +866,7 @@ public defn check-low-form (c:Circuit) -> Circuit :
false
for m in modules(c) do :
+ mname = name(m)
check-low-form-m(m)
throw(PassExceptions(errors)) when not empty?(errors)
c
@@ -877,7 +884,7 @@ public defmethod short-name (b:CheckInitialization) -> String : "check-init"
defn RefNotInitialized (info:FileInfo, name:Symbol) :
PassException $ string-join $
- [info ": Reference " name " is not fully initialized."]
+ [info ": [module " mname "] Reference " name " is not fully initialized."]
;------------ Helper Functions -------------
@@ -920,6 +927,7 @@ public defn check-init (c:Circuit) :
(v) : false
for m in modules(c) do :
+ mname = name(m)
match(m) :
(m:InModule) : check-init-m(m)
(m) : false
diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza
index 315033c7..e5aad984 100644
--- a/src/main/stanza/firrtl-test-main.stanza
+++ b/src/main/stanza/firrtl-test-main.stanza
@@ -61,6 +61,11 @@ defn main () :
val pass-args = Vector<String>()
var printvars = ""
var last-s = ""
+
+ val prev-out = CURRENT-OUTPUT-STREAM
+ CURRENT-OUTPUT-STREAM = STANDARD-ERROR
+
+
for (s in args, i in 0 to false) do :
if s == "-i" : last-s = s
else if s == "-o" : last-s = s
@@ -78,10 +83,25 @@ defn main () :
if last-s == "-s" : add(pass-args,args[i])
if last-s == "-m" : add(firms,args[i])
+ var with-output =
+ fn (f:()->False) :
+ val prev-stream = CURRENT-OUTPUT-STREAM
+ CURRENT-OUTPUT-STREAM = STANDARD-OUTPUT
+ f()
+ CURRENT-OUTPUT-STREAM = prev-stream
+
if input == false :
error("No input file provided. Use -i flag.")
- if output == false :
- error("No output file provided. Use -o flag.")
+ if output != false and output != "-":
+ with-output =
+ fn (f:()->False) :
+ val prev-stream = CURRENT-OUTPUT-STREAM
+ val out-stream = FileOutputStream(output as String)
+ CURRENT-OUTPUT-STREAM = out-stream
+ f()
+ CURRENT-OUTPUT-STREAM = prev-stream
+ close(out-stream)
+
if compiler == false and length(pass-names) == 0 :
error("Must specify a compiler. Use -X flag.")
@@ -109,10 +129,12 @@ defn main () :
run-passes(circuit*,get-passes(to-list(pass-names)))
else :
switch {_ == compiler} :
- "flo" : run-passes(circuit*,StandardFlo(output as String))
- "verilog" : run-passes(circuit*,StandardVerilog(output as String))
- "verilute" : run-passes(circuit*,InstrumentedVerilog(output as String,to-list $ pass-args))
+ "flo" : run-passes(circuit*,StandardFlo(with-output))
+ "verilog" : run-passes(circuit*,StandardVerilog(with-output))
+ "verilute" : run-passes(circuit*,InstrumentedVerilog(with-output,to-list $ pass-args))
else : error("Invalid compiler flag")
+ CURRENT-OUTPUT-STREAM = prev-out
+
main()
diff --git a/src/main/stanza/flo.stanza b/src/main/stanza/flo.stanza
index f6e75383..7ef942f2 100644
--- a/src/main/stanza/flo.stanza
+++ b/src/main/stanza/flo.stanza
@@ -9,8 +9,8 @@ defpackage firrtl/flo :
;============= Flo Backend ================
public defstruct Flo <: Pass :
- file : String
-public defmethod pass (b:Flo) -> (Circuit -> Circuit) : emit-flo{file(b),_}
+ with-output: (() -> False) -> False
+public defmethod pass (b:Flo) -> (Circuit -> Circuit) : emit-flo{with-output(b),_}
public defmethod name (b:Flo) -> String : "To Flo"
definterface FloKind
@@ -196,8 +196,9 @@ defn emit-module (m:InModule,sh:HashTable<Symbol,Int>) :
OUTPUT : flokinds[name(port)] = FOutputPortKind()
emit-s(body(m), flokinds, name(m),sh)
-public defn emit-flo (file:String, c:Circuit) :
- with-output-file{file, _} $ fn () :
+public defn emit-flo (with-output:(() -> False) -> False, c:Circuit) :
+ with-output $ {
emit-module(modules(c)[0] as InModule,get-sym-hash(modules(c)[0] as InModule))
false
+ }
c
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index 6e34a1e5..7bb7ff01 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -61,7 +61,7 @@ public defn PassExceptions (xs:Streamable<PassException>) :
public definterface Compiler
public defmulti passes (c:Compiler) -> List<Pass>
-public defmulti file (c:Compiler) -> String
+public defmulti with-output (c:Compiler) -> ((() -> False) -> False)
public definterface Pass
public defmulti pass (p:Pass) -> (Circuit -> Circuit)
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index d84b08a5..d5034f8a 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -1611,8 +1611,8 @@ public defn expand-whens (c:Circuit) -> Circuit :
;for x in resets do : println-debug(x)
val table = merge-resets(assign,resets,rsignals)
- println("====== Table ======")
- for x in table do : println(x)
+ ;println-debug("====== Table ======")
+ ;for x in table do : println-debug(x)
val decs = Vector<Stmt>()
val cons = Vector<Stmt>()
@@ -1626,7 +1626,6 @@ public defn expand-whens (c:Circuit) -> Circuit :
referenced?[key(x)] = true
for x in decs do :
mark-referenced(referenced?,x)
- println-all(["Referenced \n" referenced?])
val decs* = Vector<Stmt>()
for x in decs do :
if is-referenced?(referenced?,x) : add(decs*,x)
diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza
index d8810622..cbfd6d8b 100644
--- a/src/main/stanza/verilog.stanza
+++ b/src/main/stanza/verilog.stanza
@@ -7,8 +7,8 @@ defpackage firrtl/verilog :
;============ VERILOG ==============
public defstruct Verilog <: Pass :
- file : String
-public defmethod pass (b:Verilog) -> (Circuit -> Circuit) : emit-verilog{file(b),_}
+ with-output: (() -> False) -> False
+public defmethod pass (b:Verilog) -> (Circuit -> Circuit) : emit-verilog{with-output(b),_}
public defmethod name (b:Verilog) -> String : "To Verilog"
public defmethod short-name (b:Verilog) -> String : "To Verilog"
@@ -314,11 +314,10 @@ defn emit-module (m:InModule) :
println("endmodule")
-public defn emit-verilog (file:String, c:Circuit) :
- with-output-file{file, _} $ fn () :
+public defn emit-verilog (with-output:(() -> False) -> False, c:Circuit) :
+ with-output $ fn () :
for m in modules(c) do :
match(m) :
(m:InModule) : emit-module(m)
(m:ExModule) : false
-
c