diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/stanza-linux.zip | bin | 0 -> 3853588 bytes | |||
| -rw-r--r-- | src/lib/stanza-mac.zip (renamed from src/lib/stanza.zip) | bin | 3684669 -> 3684669 bytes | |||
| -rw-r--r-- | src/main/stanza/bigint.stanza | 68 | ||||
| -rw-r--r-- | src/main/stanza/compilers.stanza | 25 | ||||
| -rw-r--r-- | src/main/stanza/custom-compiler.stanza | 4 | ||||
| -rw-r--r-- | src/main/stanza/errors.stanza | 109 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 2 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-test-main.stanza | 76 | ||||
| -rw-r--r-- | src/main/stanza/flo.stanza | 16 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 15 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 14 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 16 | ||||
| -rw-r--r-- | src/main/stanza/primop.stanza | 4 | ||||
| -rw-r--r-- | src/main/stanza/verilog.stanza | 16 |
14 files changed, 242 insertions, 123 deletions
diff --git a/src/lib/stanza-linux.zip b/src/lib/stanza-linux.zip Binary files differnew file mode 100644 index 00000000..95f1b10b --- /dev/null +++ b/src/lib/stanza-linux.zip diff --git a/src/lib/stanza.zip b/src/lib/stanza-mac.zip Binary files differindex a902edd8..a902edd8 100644 --- a/src/lib/stanza.zip +++ b/src/lib/stanza-mac.zip 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 |
