aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/stanza-linux.zipbin0 -> 3853588 bytes
-rw-r--r--src/lib/stanza-mac.zip (renamed from src/lib/stanza.zip)bin3684669 -> 3684669 bytes
-rw-r--r--src/main/stanza/bigint.stanza68
-rw-r--r--src/main/stanza/compilers.stanza25
-rw-r--r--src/main/stanza/custom-compiler.stanza4
-rw-r--r--src/main/stanza/errors.stanza109
-rw-r--r--src/main/stanza/firrtl-ir.stanza2
-rw-r--r--src/main/stanza/firrtl-test-main.stanza76
-rw-r--r--src/main/stanza/flo.stanza16
-rw-r--r--src/main/stanza/ir-parser.stanza15
-rw-r--r--src/main/stanza/ir-utils.stanza14
-rw-r--r--src/main/stanza/passes.stanza16
-rw-r--r--src/main/stanza/primop.stanza4
-rw-r--r--src/main/stanza/verilog.stanza16
14 files changed, 242 insertions, 123 deletions
diff --git a/src/lib/stanza-linux.zip b/src/lib/stanza-linux.zip
new file mode 100644
index 00000000..95f1b10b
--- /dev/null
+++ b/src/lib/stanza-linux.zip
Binary files differ
diff --git a/src/lib/stanza.zip b/src/lib/stanza-mac.zip
index a902edd8..a902edd8 100644
--- a/src/lib/stanza.zip
+++ b/src/lib/stanza-mac.zip
Binary files differ
diff --git a/src/main/stanza/bigint.stanza b/src/main/stanza/bigint.stanza
index 427ad7ff..ad4a5bde 100644
--- a/src/main/stanza/bigint.stanza
+++ b/src/main/stanza/bigint.stanza
@@ -239,6 +239,12 @@ public defn neg! (d: BigInt, s0: BigInt) -> BigInt :
public defn neg (x:BigInt) -> BigInt : op(neg!, x)
+public defn neg? (x:BigInt) -> True|False :
+ val nw = num-words(x)
+ val msb = x[nw - 1] >> (length(x) - nw * 32 - 1)
+ if msb == 0 : false
+ else : true
+
public defn rsha! (d:BigInt, s0:BigInt, amount:Int) -> BigInt :
val w = length(s0)
val nw = num-words(d)
@@ -362,34 +368,34 @@ defn check (msg:String, x:BigInt, e:BigInt) :
defn check (msg:String, x:BigInt) :
println-all([msg " " x])
-;; check("Ba ", BigIntLit({ _ }, 1))
-;; check("Bb ", BigIntLit({ _ }, 16))
-;; check("Bc ", BigIntLit({ _ }, 32))
-;; check("Bd ", BigIntLit({ _ }, 48))
-;; check("Be ", BigIntLit({ _ }, 64))
-;; check("Bf ", BigIntLit({ _ }, 65))
-;; check("B1 ", BigIntLit(1, 8))
-;; check("B2 ", BigIntLit(2, 8))
-;; check("B+ ", BigIntLit(3, 8) + BigIntLit(5, 8), BigIntLit(3 + 5, 8))
-;; check("B- ", BigIntLit(5, 8) + BigIntLit(3, 8), BigIntLit(5 + 3, 8))
-;; check("B| ", BigIntLit(5, 8) | BigIntLit(9, 8), BigIntLit(5 | 9, 8))
-;; check("B& ", BigIntLit(5, 8) & BigIntLit(9, 8), BigIntLit(5 & 9, 8))
-;; check("B^ ", BigIntLit(5, 8) ^ BigIntLit(9, 8), BigIntLit(5 ^ 9, 8))
-;; check("B< ", BigIntLit(5, 8) << 1, BigIntLit(5 << 1, 9))
-;; check("B< ", BigIntLit(5, 3) << 10, BigIntLit(5 << 1, 13))
-;; check("B< ", BigIntLit(5, 3) << 32, BigIntLit(5 << 1, 38))
-;; check("B< ", BigIntLit("b1010") << 1, BigIntLit(10 << 1, 5))
-check("S1 ", BigIntLit("hfafa") << 16, BigIntLit("hfafa0000", 32))
-check("S1 ", BigIntLit(1,32) , BigIntLit(1,32))
-check("S1 ", BigIntLit(0,32) , BigIntLit(0,32))
-;; check("B< ", BigIntLit(5, 3) << 64, BigIntLit(5 << 1, 67))
-;; check("BN ", neg(BigIntLit(2, 8)), BigIntLit(-2, 8))
-check("S2 ", BigIntLit("b11111010") << 8, BigIntLit("b1111101000000000", 16))
-check("C1 ", cat(BigIntLit("b11111010", 8), BigIntLit("b10111100", 8)), BigIntLit("b1111101010111100", 16))
-check("C3 ", cat(cat(BigIntLit("b1111"), BigIntLit("b1010")), cat(BigIntLit("b1011"), BigIntLit("b1100"))), BigIntLit("b1111101010111100", 16))
-check("C4 ", cat([BigIntLit("b1111"), BigIntLit("b1010"), BigIntLit("b1011"), BigIntLit("b1100")]), BigIntLit("b1111101010111100", 16))
-check("C5 ", BigIntLit("b101111001"), BigIntLit("b101111001"))
-check("C6 ", cat(BigIntLit("b1"), BigIntLit("b01111001")), BigIntLit("b101111001"))
-check("C7 ", cat(BigIntLit("b11101"), BigIntLit("b101111001")), BigIntLit("b11101101111001"))
-check("C8 ", cat([BigIntLit("b11"), BigIntLit("b101"), BigIntLit("b1011"), BigIntLit("b11001")]), BigIntLit("b11101101111001"))
-check("C0 ", bits(BigIntLit("b11101101111001"), 10, 1), BigIntLit("b0110111100"))
+;;; check("Ba ", BigIntLit({ _ }, 1))
+;;; check("Bb ", BigIntLit({ _ }, 16))
+;;; check("Bc ", BigIntLit({ _ }, 32))
+;;; check("Bd ", BigIntLit({ _ }, 48))
+;;; check("Be ", BigIntLit({ _ }, 64))
+;;; check("Bf ", BigIntLit({ _ }, 65))
+;;; check("B1 ", BigIntLit(1, 8))
+;;; check("B2 ", BigIntLit(2, 8))
+;;; check("B+ ", BigIntLit(3, 8) + BigIntLit(5, 8), BigIntLit(3 + 5, 8))
+;;; check("B- ", BigIntLit(5, 8) + BigIntLit(3, 8), BigIntLit(5 + 3, 8))
+;;; check("B| ", BigIntLit(5, 8) | BigIntLit(9, 8), BigIntLit(5 | 9, 8))
+;;; check("B& ", BigIntLit(5, 8) & BigIntLit(9, 8), BigIntLit(5 & 9, 8))
+;;; check("B^ ", BigIntLit(5, 8) ^ BigIntLit(9, 8), BigIntLit(5 ^ 9, 8))
+;;; check("B< ", BigIntLit(5, 8) << 1, BigIntLit(5 << 1, 9))
+;;; check("B< ", BigIntLit(5, 3) << 10, BigIntLit(5 << 1, 13))
+;;; check("B< ", BigIntLit(5, 3) << 32, BigIntLit(5 << 1, 38))
+;;; check("B< ", BigIntLit("b1010") << 1, BigIntLit(10 << 1, 5))
+;check("S1 ", BigIntLit("hfafa") << 16, BigIntLit("hfafa0000", 32))
+;check("S1 ", BigIntLit(1,32) , BigIntLit(1,32))
+;check("S1 ", BigIntLit(0,32) , BigIntLit(0,32))
+;;; check("B< ", BigIntLit(5, 3) << 64, BigIntLit(5 << 1, 67))
+;;; check("BN ", neg(BigIntLit(2, 8)), BigIntLit(-2, 8))
+;check("S2 ", BigIntLit("b11111010") << 8, BigIntLit("b1111101000000000", 16))
+;check("C1 ", cat(BigIntLit("b11111010", 8), BigIntLit("b10111100", 8)), BigIntLit("b1111101010111100", 16))
+;check("C3 ", cat(cat(BigIntLit("b1111"), BigIntLit("b1010")), cat(BigIntLit("b1011"), BigIntLit("b1100"))), BigIntLit("b1111101010111100", 16))
+;check("C4 ", cat([BigIntLit("b1111"), BigIntLit("b1010"), BigIntLit("b1011"), BigIntLit("b1100")]), BigIntLit("b1111101010111100", 16))
+;check("C5 ", BigIntLit("b101111001"), BigIntLit("b101111001"))
+;check("C6 ", cat(BigIntLit("b1"), BigIntLit("b01111001")), BigIntLit("b101111001"))
+;check("C7 ", cat(BigIntLit("b11101"), BigIntLit("b101111001")), BigIntLit("b11101101111001"))
+;check("C8 ", cat([BigIntLit("b11"), BigIntLit("b101"), BigIntLit("b1011"), BigIntLit("b11001")]), BigIntLit("b11101101111001"))
+;check("C0 ", bits(BigIntLit("b11101101111001"), 10, 1), BigIntLit("b0110111100"))
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 6cdd1dca..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 :
@@ -218,6 +220,8 @@ defn check-high-form-primop (e:DoPrim, errors:Vector<PassException>,info:FileInf
GREATER-EQ-OP : correct-num(2,0)
EQUAL-OP : correct-num(2,0)
NEQUAL-OP : correct-num(2,0)
+ EQUIV-OP : correct-num(2,0)
+ NEQUIV-OP : correct-num(2,0)
MUX-OP : correct-num(3,0)
PAD-OP : correct-num(1,1)
AS-UINT-OP : correct-num(1,0)
@@ -278,7 +282,7 @@ public defn check-high-form (c:Circuit) -> Circuit :
(e) : add(errors,InvalidIndex(info))
(e:DoPrim) : check-high-form-primop(e,errors,info)
(e:UIntValue) :
- if value(e) < BigIntLit("h0",length(value(e))) : add(errors,NegUInt(info))
+ if neg?(value(e)) : add(errors,NegUInt(info))
(e) : false
map(check-high-form-w{info,_:Width},e)
map(check-high-form-t{info,_:Type},e)
@@ -335,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 :
@@ -382,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
@@ -437,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))
@@ -463,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 --------------
@@ -568,8 +574,10 @@ defn check-types-primop (e:DoPrim, errors:Vector<PassException>,info:FileInfo) -
LESS-EQ-OP : false
GREATER-OP : false
GREATER-EQ-OP : false
- EQUAL-OP : all-same-type(args(e))
- NEQUAL-OP : all-same-type(args(e))
+ EQUAL-OP : false
+ NEQUAL-OP : false
+ EQUIV-OP : all-same-type(args(e))
+ NEQUIV-OP : all-same-type(args(e))
MUX-OP :
all-same-type(tail(args(e)))
is-uint(head(args(e)))
@@ -618,6 +626,8 @@ public defn check-types (c:Circuit) -> Circuit :
match(map(check-types-e{info(s),_},s)) :
(s:Connect) :
if type(loc(s)) != type(exp(s)) : add(errors,InvalidConnect(info(s)))
+ (s:Connect) :
+ if type(loc(s)) != type(exp(s)) : add(errors,InvalidConnect(info(s)))
(s:OnReset) :
if type(loc(s)) != type(exp(s)) : add(errors,InvalidConnect(info(s)))
(s:Conditionally) :
@@ -628,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))
@@ -648,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 "has gender " wrong " but requires gender " 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 :
@@ -667,14 +678,24 @@ defn gender (s:DefAccessor) -> Gender :
INFER : UNKNOWN-GENDER
RDWR : BI-GENDER
+defn as-srcsnk (g:Gender) -> Symbol :
+ switch {_ == g} :
+ MALE : `source
+ FEMALE : `sink
+ UNKNOWN-GENDER : `unknown
+ BI-GENDER : `sourceOrSink
+
;----------------- 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)
+ ;println(gender)
+ ;println(right)
+ ;println(right == gender)
if gender != right and gender != BI-GENDER:
- add(errors,WrongGender(info,to-symbol(e),to-symbol(gender),to-symbol(right)))
+ add(errors,WrongGender(info,to-symbol(e),as-srcsnk(right),as-srcsnk(gender)))
defn get-gender (e:Expression,genders:HashTable<Symbol,Gender>) -> Gender :
match(e) :
@@ -701,6 +722,7 @@ public defn check-genders (c:Circuit) -> Circuit :
defn check-genders-s (s:Stmt,genders:HashTable<Symbol,Gender>) -> False :
do(check-genders-e{info(s),_:Expression,genders},s)
+ do(check-genders-s{_:Stmt,genders},s)
match(s) :
(s:DefWire) : genders[name(s)] = BI-GENDER
(s:DefRegister) : genders[name(s)] = BI-GENDER
@@ -730,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))
@@ -756,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 --------------
@@ -843,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
@@ -860,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 -------------
@@ -903,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-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index 822b8610..8de688d7 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -50,6 +50,8 @@ public val GREATER-OP = new PrimOp
public val GREATER-EQ-OP = new PrimOp
public val NEQUAL-OP = new PrimOp
public val EQUAL-OP = new PrimOp
+public val NEQUIV-OP = new PrimOp
+public val EQUIV-OP = new PrimOp
public val MUX-OP = new PrimOp
public val PAD-OP = new PrimOp
public val AS-UINT-OP = new PrimOp
diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza
index 9762966b..e5aad984 100644
--- a/src/main/stanza/firrtl-test-main.stanza
+++ b/src/main/stanza/firrtl-test-main.stanza
@@ -24,6 +24,7 @@ defpackage firrtl-main :
import verse
import firrtl/parser
import firrtl/passes
+ import firrtl/ir2
import firrtl/lexer
import stz/parser
import firrtl/ir-utils
@@ -54,37 +55,86 @@ defn main () :
val args = commandline-arguments()
var input = false
var output = false
+ var firms = Vector<String>()
var compiler = false
val pass-names = Vector<String>()
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" : input = args[i + 1]
- if s == "-o" : output = args[i + 1]
- if s == "-x" : add(pass-names,args[i + 1])
- if s == "-X" : compiler = args[i + 1]
- if s == "-p" : printvars = args[i + 1]
- if s == "-s" : add(pass-args,args[i + 1])
+ if s == "-i" : last-s = s
+ else if s == "-o" : last-s = s
+ else if s == "-x" : last-s = s
+ else if s == "-X" : last-s = s
+ else if s == "-p" : last-s = s
+ else if s == "-s" : last-s = s
+ else if s == "-m" : last-s = s
+ else :
+ if last-s == "-i" : input = args[i]
+ if last-s == "-o" : output = args[i]
+ if last-s == "-x" : add(pass-names,args[i])
+ if last-s == "-X" : compiler = args[i]
+ if last-s == "-p" : printvars = args[i]
+ 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.")
val lexed = lex-file(input as String)
- val c = parse-firrtl(lexed)
+ val circuit = parse-firrtl(lexed)
+
+ val modules* = Vector<Module>()
+ for m in modules(circuit) do :
+ add(modules*,m)
+
+ val included-c =
+ for m in firms map :
+ val lexed = lex-file(m as String)
+ parse-firrtl(lexed)
+
+ for c in included-c do :
+ for m in modules(c) do :
+ add(modules*,m)
+
+ val circuit* = Circuit(info(circuit),to-list(modules*),main(circuit))
+
set-printvars!(to-list(printvars))
if compiler == false :
- run-passes(c,get-passes(to-list(pass-names)))
+ run-passes(circuit*,get-passes(to-list(pass-names)))
else :
switch {_ == compiler} :
- "flo" : run-passes(c,StandardFlo(output as String))
- "verilog" : run-passes(c,StandardVerilog(output as String))
- "verilute" : run-passes(c,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 f4b453ba..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
@@ -38,6 +38,8 @@ defn flo-op-name (op:PrimOp, args:List<Expression>) -> String :
LESS-EQ-OP : "lte" ;; todo: swap args
GREATER-OP : "lt" ;; todo: swap args
GREATER-EQ-OP : "lte" ;; todo: signed version
+ NEQUIV-OP : "neq"
+ EQUIV-OP : "eq"
NEQUAL-OP : "neq"
EQUAL-OP : "eq"
MUX-OP : "mux"
@@ -61,12 +63,13 @@ defn flo-op-name (op:PrimOp, args:List<Expression>) -> String :
else :
error $ string-join $ ["Unable to print Primop: " op]
-defn sane-width (wd:Width) -> Int :
+defn sane-width (wd:Width) -> Int|Long :
match(wd) :
(w:IntWidth) : max(1, width(w))
+ (w:LongWidth) : max(to-long(1), width(w))
(w) : error(string-join(["Unknown width: " w]))
-defn prim-width (type:Type) -> Int :
+defn prim-width (type:Type) -> Int|Long :
match(type) :
(t:UIntType) : sane-width(width(t))
(t:SIntType) : sane-width(width(t))
@@ -193,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-parser.stanza b/src/main/stanza/ir-parser.stanza
index fdf4c383..34d9ef57 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -27,6 +27,15 @@ defn* apply-suffix-ops (x, fs:List) :
if empty?(fs) : x
else : apply-suffix-ops(head(fs)(x), tail(fs))
+defn parse-stmts (forms:List) :
+ val cs = Vector<Stmt>()
+ defn* loop (forms:List) :
+ match-syntax(forms) :
+ () : to-list(cs)
+ (?s:#stmt ?rest ...) : (add(cs, s), loop(rest))
+ (?rest ...) : FPE(rest, "Expected a statement here.")
+ loop(forms)
+
;======== Parser Utilities ==============
defn atom? (x) : unwrap-token(x) not-typeof List
@@ -47,6 +56,8 @@ OPERATORS[`gt] = GREATER-OP
OPERATORS[`geq] = GREATER-EQ-OP
OPERATORS[`eq] = EQUAL-OP
OPERATORS[`neq] = NEQUAL-OP
+OPERATORS[`eqv] = EQUIV-OP
+OPERATORS[`neqv] = NEQUIV-OP
OPERATORS[`mux] = MUX-OP
OPERATORS[`pad] = PAD-OP
OPERATORS[`neg] = NEG-OP
@@ -167,6 +178,8 @@ defsyntax firrtl :
;Main Module Production
defrule module :
+ ;module = (module ?name:#id! #:! (?ps:#port ... ?rest ...)) :
+ ; InModule(first-info(form), name, ps, Begin(parse-stmts(rest)))
module = (module ?name:#id! #:! (?ps:#port ... ?cs:#stmt ... ?rest ...)) :
if not empty?(rest) :
FPE(rest, "Expected a statement here.")
@@ -235,6 +248,8 @@ defsyntax firrtl :
stmt = (?x:#exp := ?y:#exp!) : Connect(first-info(form),x, y)
stmt = (?x:#exp <> ?y:#exp!) : BulkConnect(first-info(form),x, y)
+ ;stmt = ((?s:#stmt ?rest ...)) :
+ ; Begin(List(s, parse-stmts(rest)))
stmt = ((?s:#stmt ?ss:#stmt ... ?rest ...)) :
if not empty?(rest) :
FPE(rest, "Expected a statement here.")
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index 0118c73b..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)
@@ -86,9 +86,13 @@ public defn abs (x:Long) -> Long :
if x < to-long(0) : to-long(0) - x
else : x
-;public defn to-int (x:Long) -> Int :
- ;if x > to-long(2147483647) or x < to-long(–2147483648) : error("Long too big to convert to Int")
- ;else : x + 0
+public defn max (x:Long,y:Long) -> Long :
+ if x < y : y
+ else : x
+
+public defn to-int (x:Long) -> Int :
+ if x > to-long(2147483647) or x < to-long(-2147483648) : error("Long too big to convert to Int")
+ else : to-int(to-string(x))
;============== PRINTERS ===================================
@@ -135,6 +139,8 @@ defmethod print (o:OutputStream, op:PrimOp) :
LESS-EQ-OP : "leq"
GREATER-OP : "gt"
GREATER-EQ-OP : "geq"
+ EQUIV-OP : "eqv"
+ NEQUIV-OP : "neqv"
EQUAL-OP : "eq"
NEQUAL-OP : "neq"
MUX-OP : "mux"
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index db1a056e..d5034f8a 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -815,6 +815,9 @@ defn resolve-genders (c:Circuit) :
defn resolve-genders (m:Module, c:Circuit) -> Module :
val genders = HashTable<Symbol,Gender>(symbol-hash)
+ ;for p in ports(m) do :
+ ;if direction(p) == INPUT : genders[name(p)] = MALE
+ ;else : genders[name(p)] = FEMALE
resolve-module(m,genders)
Circuit(info(c),modules*, main(c)) where :
@@ -1134,7 +1137,7 @@ public defmethod short-name (b:ExpandIndexedConnects) -> String : "expand-indexe
defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable<Symbol,Int>) -> Stmt :
defn equality (e1:Expression,e2:Expression) -> Expression :
- DoPrim(EQUAL-OP,list(e1,e2),List(),UIntType(UnknownWidth()))
+ DoPrim(EQUIV-OP,list(e1,e2),List(),UIntType(UnknownWidth()))
defn get-name (e:Expression) -> Symbol :
match(e) :
(e:WRef) : symbol-join([name(e) temp-delin])
@@ -1254,7 +1257,7 @@ defn OR (e1:Expression,e2:Expression) -> Expression :
defn NOT (e1:Expression) -> Expression :
if e1 == one : zero
else if e1 == zero : one
- else : DoPrim(EQUAL-OP,list(e1,zero),list(),UIntType(IntWidth(1)))
+ else : DoPrim(EQUIV-OP,list(e1,zero),list(),UIntType(IntWidth(1)))
defn children (e:Expression) -> List<Expression> :
val es = Vector<Expression>()
@@ -1504,15 +1507,14 @@ defn mark-referenced (referenced?:HashTable<Symbol,True>, s:Stmt) -> False :
map(mark-referenced-e,s)
false
-defn mark-referenced (referenced?:HashTable<Symbol,True>, sv:SymbolicValue) -> False :
+defn mark-referenced (referenced?:HashTable<Symbol,True>, sv:SymbolicValue) -> SymbolicValue :
defn mark-referenced-e (e:Expression) -> Expression :
match(map(mark-referenced-e,e)) :
(e:WRef) :
referenced?[name(e)] = true
e
(e) : e
- map(mark-referenced-e,sv)
- false
+ map{mark-referenced-e,_} $ map(mark-referenced{referenced?,_:SymbolicValue},sv)
defn is-referenced? (referenced?:HashTable<Symbol,True>, s:Stmt) -> True|False :
match(s) :
@@ -1814,8 +1816,8 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Width> :
(w1,w2) : w
(w:ExpWidth) :
match(arg1(w)) :
- (w1:IntWidth) : LongWidth(pow(to-long(2),to-long(width(w1) - 1)))
- (w1:LongWidth) : LongWidth(pow(to-long(2),minus(width(w1), to-long(1))))
+ (w1:IntWidth) : LongWidth(pow(to-long(2),to-long(width(w1))) - to-long(1))
+ (w1:LongWidth) : LongWidth(pow(to-long(2),width(w1)) - to-long(1))
(w1) : w
(w) : w
defn substitute (w:Width,h:HashTable<Symbol,Width>) -> Width :
diff --git a/src/main/stanza/primop.stanza b/src/main/stanza/primop.stanza
index 0e343d74..f7eb6d04 100644
--- a/src/main/stanza/primop.stanza
+++ b/src/main/stanza/primop.stanza
@@ -39,6 +39,8 @@ public defn lower-and-type-primop (e:DoPrim) -> DoPrim :
GREATER-EQ-OP : DoPrim(GREATER-EQ-OP,args(e),consts(e),u())
EQUAL-OP : DoPrim(EQUAL-OP,args(e),consts(e),u())
NEQUAL-OP : DoPrim(NEQUAL-OP,args(e),consts(e),u())
+ EQUIV-OP : DoPrim(EQUIV-OP,args(e),consts(e),u())
+ NEQUIV-OP : DoPrim(NEQUIV-OP,args(e),consts(e),u())
MUX-OP : DoPrim(MUX-OP,args(e),consts(e),of-type(args(e)[1]))
PAD-OP : DoPrim(PAD-OP,args(e),consts(e),of-type(args(e)[0]))
AS-UINT-OP : DoPrim(AS-UINT-OP,args(e),consts(e),u())
@@ -98,6 +100,8 @@ public defn primop-gen-constraints (e:DoPrim,v:Vector<WGeq>) -> Type :
GREATER-EQ-OP : IntWidth(1)
EQUAL-OP : IntWidth(1)
NEQUAL-OP : IntWidth(1)
+ EQUIV-OP : IntWidth(1)
+ NEQUIV-OP : IntWidth(1)
MUX-OP :
add(v,WGeq(IntWidth(1),width!(args(e)[0])))
add(v,WGeq(width!(args(e)[0]),IntWidth(1)))
diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza
index ca47170b..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"
@@ -60,7 +60,10 @@ defn emit-signed-if-any (e:Expression,ls:List<Expression>) -> String :
for x in ls do :
if type(x) typeof SIntType : signed? = true
if not signed? : emit(e)
- else : string-join(["$signed(" emit(e) ")"])
+ else :
+ match(type(e)) :
+ (t:SIntType) : string-join(["$signed(" emit(e) ")"])
+ (t:UIntType) : string-join(["$signed({1'b0," emit(e) "})"])
defn emit (e:Expression) -> String :
match(e) :
@@ -92,6 +95,8 @@ defn emit (e:Expression) -> String :
LESS-EQ-OP : [emit-signed-if-any(args(e)[0],args(e)) " <= " emit-signed-if-any(args(e)[1],args(e))]
GREATER-OP : [emit-signed-if-any(args(e)[0],args(e)) " > " emit-signed-if-any(args(e)[1],args(e))]
GREATER-EQ-OP : [emit-signed-if-any(args(e)[0],args(e)) " >= " emit-signed-if-any(args(e)[1],args(e))]
+ NEQUIV-OP : [emit-signed-if-any(args(e)[0],args(e)) " != " emit-signed-if-any(args(e)[1],args(e))]
+ EQUIV-OP : [emit-signed-if-any(args(e)[0],args(e)) " == " emit-signed-if-any(args(e)[1],args(e))]
NEQUAL-OP : [emit-signed-if-any(args(e)[0],args(e)) " != " emit-signed-if-any(args(e)[1],args(e))]
EQUAL-OP : [emit-signed-if-any(args(e)[0],args(e)) " == " emit-signed-if-any(args(e)[1],args(e))]
MUX-OP :
@@ -309,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