aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/stanza/compilers.stanza4
-rw-r--r--src/main/stanza/custom-passes.stanza6
-rw-r--r--src/main/stanza/errors.stanza141
-rw-r--r--src/main/stanza/firrtl-ir.stanza4
-rw-r--r--src/main/stanza/ir-parser.stanza10
-rw-r--r--src/main/stanza/ir-utils.stanza19
-rw-r--r--src/main/stanza/passes.stanza28
-rw-r--r--src/main/stanza/verilog.stanza24
8 files changed, 201 insertions, 35 deletions
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza
index efa8c992..5a2e2278 100644
--- a/src/main/stanza/compilers.stanza
+++ b/src/main/stanza/compilers.stanza
@@ -56,9 +56,11 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> :
ExpandIndexedConnects()
ExpandWhens()
InferWidths()
+ Pad()
SplitExp()
ToRealIR()
- SpecialRename(`#,`_)
+ SpecialRename(`#,`__)
+ SpecialRename(`$,`_)
Verilog(file(c))
]
diff --git a/src/main/stanza/custom-passes.stanza b/src/main/stanza/custom-passes.stanza
index e4c3d9d3..3b6c28ff 100644
--- a/src/main/stanza/custom-passes.stanza
+++ b/src/main/stanza/custom-passes.stanza
@@ -45,7 +45,7 @@ defn when-coverage (port-name:Symbol, reg-name:Symbol, instrument?:HashTable<Sym
val sym = HashTable<Symbol,Int>(symbol-hash)
val w1 = IntWidth(1)
val t1 = UIntType(w1)
- val u1 = UIntValue(1,w1)
+ val u1 = UIntValue(to-long $ 1,w1)
defn when-coverage (s:Stmt) -> Stmt :
match(s) :
(s:Conditionally) :
@@ -70,7 +70,7 @@ defn when-coverage (port-name:Symbol, reg-name:Symbol, instrument?:HashTable<Sym
if length(w-ls) != 0 :
val reg-ref = Ref(reg-name,UIntType(IntWidth(length(w-ls))))
add{logic,_} $ DefRegister(FileInfo(),name(reg-ref),type(reg-ref))
- add{logic,_} $ OnReset(FileInfo(),reg-ref,UIntValue(0,IntWidth(length(w-ls))))
+ add{logic,_} $ OnReset(FileInfo(),reg-ref,UIntValue(to-long $ 0,IntWidth(length(w-ls))))
for (x in w-ls, i in 0 to false) do :
add{logic,_} $ DefWire(FileInfo(),name(x),type(x))
add{logic,_} $ Connect(FileInfo(),x,DoPrim(BIT-SELECT-OP,list(reg-ref),list(i),UIntType(w1)))
@@ -80,7 +80,7 @@ defn when-coverage (port-name:Symbol, reg-name:Symbol, instrument?:HashTable<Sym
if length(i-ls) != 0 :
for (x in i-ls, i in 0 to false) do :
add{logic,_} $ DefWire(FileInfo(),name(x),type(x))
- add{logic,_} $ Connect(FileInfo(),x,UIntValue(0,UnknownWidth()))
+ add{logic,_} $ Connect(FileInfo(),x,UIntValue(to-long $ 0,UnknownWidth()))
if instrument?[name(m)] : add{logic,_} $ Connect(FileInfo(),port-ref,concat-all(append(w-ls,i-ls)))
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index 0795a2a9..aff22460 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -22,11 +22,6 @@ defpackage firrtl/errors :
; o pad's width is greater than value's width
; o widths are large enough to contain value
-;AFTER LOWERING
-; o All things connect to once
-; o no reg
-; o no accessors
-
;AFTER ??????
; o No combinational loops
; o cannot connect to a pad, or a register. only connct to a reference
@@ -233,9 +228,8 @@ public defn check-high-form (c:Circuit,sym:Symbol) -> Circuit :
(e:Ref|Subfield|Index) : false
(e) : add(errors,InvalidIndex(info))
(e:DoPrim) : check-high-form-primop(e,errors,info)
- ;; (e:UIntValue) :
- ;; if value(e) < 0 :
- ;; add(errors,NegUInt(info))
+ (e:UIntValue) :
+ if value(e) < to-long $ 0 : add(errors,NegUInt(info))
(e) : false
map(check-high-form-w{info,_:Width},e)
map(check-high-form-t{info,_:Type},e)
@@ -694,3 +688,134 @@ public defn check-genders (c:Circuit) -> Circuit :
throw(PassExceptions(errors)) when not empty?(errors)
c
+;================= High Form Check ==========================
+;AFTER LOWERING
+; o All things connect to once
+; o no reg
+; o no accessors
+; o only vecs are for memories
+; o no bundles (future, will have them for mems)
+; o
+;
+;public defstruct CheckLowForm <: Pass :
+; sym : Symbol
+;public defmethod pass (b:CheckLowForm) -> (Circuit -> Circuit) : check-low-form{_,sym(b)}
+;public defmethod name (b:CheckLowForm) -> String : "Low Form Check"
+;public defmethod short-name (b:CheckLowForm) -> String : "low-form-check"
+;
+;;----------------- Errors ------------------------
+;defn NotUnique (info:FileInfo, name:Symbol) :
+; PassException $ string-join $
+; [info ": Reference " name " does not have a unique name."]
+;
+;
+;;---------------- Helper Functions --------------
+;
+;;--------------- Check Low Form Pass -------------------
+;public defn check-low-form (c:Circuit,sym:Symbol) -> Circuit :
+; val errors = Vector<PassException>()
+;
+; defn check-high-form-w (info:FileInfo,w:Width) -> Width :
+; match(w) :
+; (w:IntWidth) :
+; if width(w) < 0 : add(errors,NegWidth(info))
+; w
+; (w) : w
+;
+; defn check-high-form-t (info:FileInfo,t:Type) -> Type :
+; match(map(check-high-form-t{info,_},t)) :
+; (t:VectorType) :
+; if size(t) < 0 : add(errors,NegVecSize(info))
+; (t) : false
+; map(check-high-form-w{info,_:Width},t)
+;
+; defn check-high-form-e (info:FileInfo,e:Expression,names:Vector<Symbol>) -> Expression :
+; match(map(check-high-form-e{info,_,names},e)) :
+; (e:Ref) :
+; if not contains?(name(e),names) :
+; add(errors,UndeclaredReference(info,name(e)))
+; (e:Subfield) :
+; match(exp(e)) :
+; (e:Ref|Subfield|Index) : false
+; (e) : add(errors,InvalidSubfield(info))
+; (e:Index) :
+; match(exp(e)) :
+; (e:Ref|Subfield|Index) : false
+; (e) : add(errors,InvalidIndex(info))
+; (e:DoPrim) : check-high-form-primop(e,errors,info)
+; (e:UIntValue) :
+; if value(e) < to-long $ 0 : add(errors,NegUInt(info))
+; (e) : false
+; map(check-high-form-w{info,_:Width},e)
+; map(check-high-form-t{info,_:Type},e)
+; e
+;
+; defn check-high-form-s (s:Stmt,names:Vector<Symbol>) -> Stmt :
+; defn check-name (info:FileInfo,name:Symbol) -> False :
+; if contains?(name,names) : add(errors,NotUnique(info,name))
+; val prefix = is-prefix?(name,names,sym)
+; if prefix typeof Symbol : add(errors,IsPrefix(info,name,prefix as Symbol))
+;
+; map(check-high-form-t{info(s),_:Type},s)
+;
+; map{check-high-form-s{_,names},_} $ {
+; match(map(check-high-form-e{info(s),_,names},s)) :
+; (s:DefWire|DefRegister) :
+; check-name(info(s),name(s))
+; add(names,name(s))
+; (s:DefMemory) :
+; check-name(info(s),name(s))
+; add(names,name(s))
+; if has-flip?(type(s)) : add(errors, MemWithFlip(info(s), name(s)))
+; (s:DefInstance) :
+; if not contains?(name(module(s) as Ref),map(name,modules(c))) :
+; add(errors, ModuleNotDefined(info(s),name(module(s) as Ref)))
+; check-name(info(s),name(s))
+; add(names,name(s))
+; (s:DefNode) :
+; check-name(info(s),name(s))
+; add(names,name(s))
+; (s:DefAccessor) :
+; check-name(info(s),name(s))
+; add(names,name(s))
+; (s:Connect) :
+; check-valid-loc(info(s),loc(s))
+; (s:BulkConnect) :
+; check-valid-loc(info(s),loc(s))
+; (s) : false
+; s }()
+;
+; defn check-high-form-m (m:Module) -> False :
+; val names = Vector<Symbol>()
+; for m in modules(c) do :
+; add(names,name(m))
+; for p in ports(m) do :
+; add(names,name(p))
+; if name(p) == `reset :
+; if direction(p) == OUTPUT :
+; add(errors,WrongReset(info!(m),name(m)))
+; else :
+; if type(p) typeof UIntType :
+; if width(type(p) as UIntType) != IntWidth(1) :
+; add(errors,WrongReset(info!(m),name(m)))
+; else :
+; add(errors,WrongReset(info!(m),name(m)))
+; map(check-high-form-t{info(p),_},type(p))
+; map(check-high-form-w{info(p),_},type(p))
+;
+;
+;
+; add(names,`reset)
+; match(m) :
+; (m:ExModule) : false
+; (m:InModule) : check-high-form-s(body(m),names)
+; false
+;
+; var number-top-m = 0
+; for m in modules(c) do :
+; if name(m) == main(c) : number-top-m = number-top-m + 1
+; check-high-form-m(m)
+; if number-top-m != 1 : add(errors,NoTopModule(info!(c),main(c)))
+; throw(PassExceptions(errors)) when not empty?(errors)
+; c
+;
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index 18e069b4..aeaecf47 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -73,10 +73,10 @@ public defstruct Index <: Expression :
value: Int
type: Type with: (as-method => true)
public defstruct UIntValue <: Expression :
- value: Int
+ value: Long
width: Width
public defstruct SIntValue <: Expression :
- value: Int
+ value: Long
width: Width
public defstruct DoPrim <: Expression :
op: PrimOp
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index cbfe106e..588efeac 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -81,6 +81,10 @@ defsyntax firrtl :
int = (?x) when unwrap-token(x) typeof Int :
unwrap-token(x)
+ ;Parses next form if long literal
+ intorlong = (?x) when unwrap-token(x) typeof Int|Long :
+ unwrap-token(x)
+
;Parses next form if symbol
sym = (?x) when unwrap-token(x) typeof Symbol :
unwrap-token(x)
@@ -107,6 +111,10 @@ defsyntax firrtl :
int$ = (?i:#int ?rest ...) when empty?(rest) : i
int$ != () : FPE(form, "Expected a single integer literal here.")
+ ;Error if not a single long integer
+ long$ = (?i:#intorlong ?rest ...) when empty?(rest) : to-long(i)
+ long$ != () : FPE(form, "Expected a single long integer literal here.")
+
;Error if not a single width
width$ = (?w:#width ?rest ...) when empty?(rest) : w
width$ != () : FPE(form, "Expected a single width specifier here.")
@@ -227,7 +235,7 @@ defsyntax firrtl :
expop = (. ?f:#id!) : (fn (x) : Subfield(x, f, UnknownType()))
;Prefix Operators
- expterm = (?t:#inttype(?v:#int$)) :
+ expterm = (?t:#inttype(?v:#long$)) :
match(t) :
(t:UIntType) : UIntValue(v, width(t))
(t:SIntType) : SIntValue(v, width(t))
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index c39a1ad1..1d209622 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -69,7 +69,26 @@ public defmulti name (p:Pass) -> String
public defmulti short-name (p:Pass) -> String
public defmethod print (o:OutputStream, p:Pass) :
print(o,name(p))
+
+;============== Various Useful Functions ==============
+
+public defn ceil-log2 (i:Long) -> Long :
+ defn* loop (n:Long, l:Long) :
+ if n < i :
+ if l == 30 : to-long(31)
+ else : loop(n * to-long(2), l + to-long(1))
+ else : l
+ error("Log of negative number!") when i < to-long(0)
+ loop(to-long $ 1, to-long $ 0)
+
+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
;============== PRINTERS ===================================
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index 80035325..fb889cf4 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -999,7 +999,7 @@ defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable<Symbol,Int>) -> Stmt :
to-list $
for (i in 0 to false, l in locs(s)) stream : Conditionally(
info(s),
- equality(ref,UIntValue(i,UnknownWidth())),
+ equality(ref,UIntValue(to-long $ i,UnknownWidth())),
Connect(info(s),l,exp(s)),
EmptyStmt()
)
@@ -1013,7 +1013,7 @@ defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable<Symbol,Int>) -> Stmt :
to-list $
for (i in 1 to false, e in tail(exps(s))) stream : Conditionally(
info(s),
- equality(ref,UIntValue(i,UnknownWidth())),
+ equality(ref,UIntValue(to-long $ i,UnknownWidth())),
Connect(info(s),loc(s),e),
EmptyStmt()
)
@@ -1059,8 +1059,8 @@ public defmethod short-name (b:ExpandWhens) -> String : "expand-whens"
; ======== Expression Computation Library ===========
-val zero = UIntValue(0,IntWidth(1))
-val one = UIntValue(1,IntWidth(1))
+val zero = UIntValue(to-long $ 0,IntWidth(1))
+val one = UIntValue(to-long $ 1,IntWidth(1))
defmethod equal? (e1:Expression,e2:Expression) -> True|False :
match(e1,e2) :
@@ -1501,7 +1501,6 @@ defmethod equal? (w1:Width,w2:Width) -> True|False :
defn apply (a:Int|False,b:Int|False, f: (Int,Int) -> Int) -> Int|False :
if a typeof Int and b typeof Int : f(a as Int, b as Int)
else : false
-
defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Width> :
defn contains? (n:Symbol,h:HashTable<Symbol,?>) -> True|False : key?(h,n)
@@ -1682,14 +1681,14 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod
match(width(e)) :
(w:UnknownWidth) :
val w* = VarWidth(firrtl-gensym(`w,width-name-hash))
- add(v,WGeq(w*,IntWidth(ceil-log2(value(e)))))
+ add(v,WGeq(w*,IntWidth(to-int $ to-string $ ceil-log2(value(e)))))
UIntValue(value(e),w*)
(w) : e
(e:SIntValue) :
match(width(e)) :
(w:UnknownWidth) :
val w* = VarWidth(firrtl-gensym(`w,width-name-hash))
- add(v,WGeq(w*,IntWidth(1 + ceil-log2(abs(value(e))))))
+ add(v,WGeq(w*,IntWidth(1 + to-int $ to-string $ ceil-log2(abs(value(e))))))
SIntValue(value(e),w*)
(w) : e
(e) : e
@@ -1869,10 +1868,10 @@ public defmethod pass (b:SplitExp) -> (Circuit -> Circuit) : split-exp
public defmethod name (b:SplitExp) -> String : "Split Expressions"
public defmethod short-name (b:SplitExp) -> String : "split-expressions"
-defn full-name (e:Expression) -> Symbol :
+defn full-name (e:Expression) -> Symbol|False :
match(e) :
(e:WRef) : name(e)
- (e:WSubfield) : to-symbol $ string-join([full-name(exp(e)) "." name(e)])
+ (e:WSubfield) : false
(e) : error("Non-supported expression.")
defn split-exp (c:Circuit) :
@@ -1959,19 +1958,26 @@ public defn special-rename (original-sym:Symbol,new-sym:Symbol,c:Circuit) :
else :
if substring(st,0,length(os)) == os :
add(y,ns)
+ println(st)
+ println(substring(st,length(os),length(st)))
rename(substring(st,length(os),length(st)))
else :
add(y,substring(st,0,1))
rename(substring(st,1,length(st)))
rename(to-string(s))
to-symbol $ string-join $ to-list(y)
+ defn to-type (t:Type) -> Type :
+ match(map(to-type,t)) :
+ (t:BundleType) : BundleType $
+ for f in fields(t) map : Field(rename(name(f)),flip(f),type(f))
+ (t) : t
defn to-exp (e:Expression) -> Expression :
- match(map(to-exp,e)) :
+ map{to-type,_} $ match(map(to-exp,e)) :
(e:Ref) : Ref(rename(name(e)), type(e))
(e:Subfield) : Subfield(exp(e),rename(name(e)),type(e))
(e) : e
defn to-stmt (s:Stmt) -> Stmt :
- match(map(to-exp,s)) :
+ map{to-type,_} $ match(map(to-exp,s)) :
(s:DefWire) : DefWire(info(s),rename(name(s)),type(s))
(s:DefRegister) : DefRegister(info(s),rename(name(s)),type(s))
(s:DefInstance) : DefInstance(info(s),rename(name(s)),module(s))
diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza
index bee10177..50ea1fc1 100644
--- a/src/main/stanza/verilog.stanza
+++ b/src/main/stanza/verilog.stanza
@@ -24,7 +24,10 @@ defn width! (t:Type) -> Int :
defn emit (w:Width) -> String :
match(w) :
- (w:IntWidth) : string-join $ ["[" width(w) ":0]"] ;TODO check if need to special case 0 or 1 width wires
+ (w:IntWidth) :
+ if width(w) >= 1 : string-join $ ["[" width(w) - 1 ":0]"] ;TODO check if need to special case 0 or 1 width wires
+ else : ""
+
(w) : error("Non-supported width type.")
defn get-width (t:Type) -> String :
@@ -77,15 +80,15 @@ defn emit (e:Expression) -> String :
val x = args(e)[0]
val w = width!(type(x))
val diff = consts(e)[0] - w
- ["{" diff "{" x "[" w - 1 "]}," emit(x)]
+ ["{{" diff "{" emit(x) "[" w - 1 "]}}, " emit(x) " }"]
AS-UINT-OP :
- ["$unsigned(" emit(args(e)[0]) " "]
+ ["$unsigned(" emit(args(e)[0]) ")"]
AS-SINT-OP :
- ["$signed(" emit(args(e)[0]) " "]
+ ["$signed(" emit(args(e)[0]) ")"]
DYN-SHIFT-LEFT-OP : [emit(args(e)[0]) " << " emit(args(e)[1])]
DYN-SHIFT-RIGHT-OP : [emit(args(e)[0]) " >> " emit(args(e)[1])]
- SHIFT-LEFT-OP : [emit(args(e)[0]) " << " emit(args(e)[1])]
- SHIFT-RIGHT-OP : [emit(args(e)[0]) " >> " emit(args(e)[1])]
+ SHIFT-LEFT-OP : [emit(args(e)[0]) " << " consts(e)[0]]
+ SHIFT-RIGHT-OP : [emit(args(e)[0]) " >> " consts(e)[0]]
NEG-OP : ["-{" emit(args(e)[0]) "}"]
CONVERT-OP :
match(type(args(e)[0])) :
@@ -239,12 +242,15 @@ defn emit-module (m:InModule) :
println-all(a)
for x in insts do :
- println-all([" " value(x) " " key(x) ".clk(clk),"])
+ println-all([" " value(x) " " key(x) " ("])
+ print(" ")
+ print-all([".clk( clk )"])
for (y in inst-ports[key(x)],i in 1 to false) do :
+ print(",\n")
print(" ")
print-all(y)
- if length(inst-ports[key(x)]) != i :
- print(",\n")
+ ;if length(inst-ports[key(x)]) != i :
+ ;print(",\n")
println("\n );")
if length(updates) != 0 :