aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/compilers.stanza5
-rw-r--r--src/main/stanza/ir-parser.stanza98
-rw-r--r--src/main/stanza/ir-utils.stanza8
-rw-r--r--src/main/stanza/passes.stanza65
4 files changed, 113 insertions, 63 deletions
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza
index 9dda33fe..cfe5bbaf 100644
--- a/src/main/stanza/compilers.stanza
+++ b/src/main/stanza/compilers.stanza
@@ -58,6 +58,8 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> :
;CheckTypes() ;R
ExpandAccesses() ;W
ExpandConnects() ;W
+ ResolveKinds() ;W
+ InferTypes() ;R
ResolveGenders() ;W
;LowerToGround() ;W
;ExpandIndexedConnects() ;W
@@ -65,6 +67,9 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> :
;InferTypes() ;R
;CheckGenders() ;W
ExpandWhens() ;W
+ ResolveKinds() ;W
+ InferTypes() ;R
+ ResolveGenders() ;W
InferWidths() ;R
;ToRealIR() ;W -> R
;CheckWidths() ;R
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index fe8af96f..e8dd3306 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -8,21 +8,21 @@ defpackage firrtl/parser :
import firrtl/ir-utils
;======= Convenience Types ===========
-;definterface MStat
-;defstruct Reader <: MStat :
-; value: Symbol
-;defstruct Writer <: MStat :
-; value: Symbol
-;defstruct ReadWriter <: MStat :
-; value: Symbol
-;defstruct ReadLatency <: MStat :
-; value: Int
-;defstruct WriteLatency <: MStat :
-; value: Int
-;defstruct DataType <: MStat :
-; value: Type
-;defstruct Depth <: MStat :
-; value: Int
+definterface MStat
+defstruct Reader <: MStat :
+ value: Symbol
+defstruct Writer <: MStat :
+ value: Symbol
+defstruct ReadWriter <: MStat :
+ value: Symbol
+defstruct ReadLatency <: MStat :
+ value: Int
+defstruct WriteLatency <: MStat :
+ value: Int
+defstruct DataType <: MStat :
+ value: Type
+defstruct Depth <: MStat :
+ value: Int
;======= Convenience Functions ========
defn first-info? (form) -> FileInfo|False :
match(form) :
@@ -127,6 +127,10 @@ defsyntax firrtl :
id! = (?x:#id) : x
id! != () : FPE(form, "Expected an identifier here.")
+ ;Error if not =>
+ =>! = (=>) : (`=>)
+ =>! != () : FPE(form, "Expected => here.")
+
;Error if not a colon
:! = (:) : (`:)
:! != () : FPE(form, "Expected a colon here.")
@@ -143,6 +147,10 @@ defsyntax firrtl :
int$ = (?i:#int ?rest ...) when empty?(rest) : i
int$ != () : FPE(form, "Expected a single integer literal here.")
+ ;Error if not an integer
+ int! = (?i:#int) : i
+ int! != () : FPE(form, "Expected an integer literal here.")
+
;Error if not a single long integer
long$ = (?i:#intorlong ?rest ...) when empty?(rest) :
match(i) :
@@ -238,41 +246,35 @@ defsyntax firrtl :
width = (?) : UnknownWidth()
;Main Statement Productions
- ;defrule mstat :
- ; mstat = (reader ?name:#id!) : Reader(name)
- ; mstat = (writer ?name:#id!) : Writer(name)
- ; mstat = (read-writer ?name:#id!) : ReadWriter(name)
- ; mstat = (read-latency #:! ?i:#int!) : ReadLatency(i)
- ; mstat = (write-latency #:! ?i:#int!) : WriteLatency(i)
- ; mstat = (data-type #:! ?t:#type!) : DataType(t)
- ; mstat = (depth #:! ?i:#int!) : Depth(i)
+ defrule mstat :
+ mstat = (reader #=>! ?name:#id!) : Reader(name)
+ mstat = (writer #=>! ?name:#id!) : Writer(name)
+ mstat = (read-writer #=>! ?name:#id!) : ReadWriter(name)
+ mstat = (read-latency #=>! ?i:#int!) : ReadLatency(i)
+ mstat = (write-latency #=>! ?i:#int!) : WriteLatency(i)
+ mstat = (data-type #=>! ?t:#type!) : DataType(t)
+ mstat = (depth #=>! ?i:#int!) : Depth(i)
defrule statements :
stmt = (skip) : Empty()
stmt = (wire ?name:#id! #:! ?t:#type!) : DefWire(first-info(form),name, t)
stmt = (reg ?name:#id! #:! ?t:#type! ?clk:#exp! ?reset:#exp! ?init:#exp!) : DefRegister(first-info(form),name, t,clk,reset,init)
- stmt = (mem ?name:#id! #:! ?data-type:#type! ?depth:#int ?writers:#id! ... ?wl:#int ?readers:#id! ... ?rl:#int ?readwriters:#id! ...) :
- DefMemory(first-info(form),name,data-type,depth,wl,rl,readers,writers,readwriters)
- ;val rl = Vector<Int>()
- ;var wl = Vector<Int>()
- ;var de = Vector<Int>()
- ;var dt = Vector<Type>()
- ;val rs = Vector<Symbol>()
- ;val ws = Vector<Symbol>()
- ;val rws = Vector<Symbol>()
- ;for x in stats do :
- ; match(x as MStat) :
- ; (x:Reader) : add(rs,value(x))
- ; (x:Writer) : add(ws,value(x))
- ; (x:ReadWriter) : add(rws,value(x))
- ; (x:ReadLatency) : add(rl,value(x))
- ; (x:WriteLatency) : add(wl,value(x))
- ; (x:DataType) : add(dt,value(x))
- ; (x:Depth) : add(de,value(x))
- ;if length(rl) != 1 : FPE(stats, "Can only specify one read-latency.")
- ;if length(wl) != 1 : FPE(stats, "Can only specify one write-latency.")
- ;if length(de) != 1 : FPE(stats, "Can only specify one depth.")
- ;if length(dt) != 1 : FPE(stats, "Can only specify one data-type.")
- ;DefMemory(first-info(form),name,dt[0],de[0],wl[0],rl[0],to-list(rs),to-list(ws),to-list(rws))
+ ;stmt = (mem ?name:#id! #:! ?data-type:#type! ?depth:#int ?writers:#id! ... ?wl:#int ?readers:#id! ... ?rl:#int ?readwriters:#id! ...) :
+ ; DefMemory(first-info(form),name,data-type,depth,wl,rl,readers,writers,readwriters)
+ stmt = (mem ?name:#id! #:! (?ms:#mstat ...)) :
+ defn grab (f:MStat -> True|False) :
+ map(value,to-list(filter(f,ms))) as List
+ defn grab1 (f:MStat -> True|False,s:String) :
+ val ls = grab(f)
+ if length(ls) != 1 : FPE(form,"Must declare one ~." << [s])
+ head(ls)
+ val readers = grab({_ typeof Reader})
+ val writers = grab({_ typeof Writer})
+ val readwriters = grab({_ typeof ReadWriter})
+ val write-latency = grab1({_ typeof WriteLatency},"write-latency")
+ val read-latency = grab1({_ typeof ReadLatency},"read-latency")
+ val depth = grab1({_ typeof Depth},"depth")
+ val data-type = grab1({_ typeof DataType},"data type")
+ DefMemory(first-info(form),name,data-type,depth,write-latency,read-latency,readers,writers,readwriters)
stmt = (inst ?name:#id! #of! ?m:#id!) : DefInstance(first-info(form),name,m)
stmt = (node ?name:#id! #=! ?e:#exp!) : DefNode(first-info(form),name,e)
stmt = (poison ?name:#id! #:! ?t:#type!) : DefPoison(first-info(form),name, t)
@@ -280,8 +282,8 @@ defsyntax firrtl :
stmt = (printf(?clk:#exp ?str:#string ?es:#exp ...)) : Print(first-info(form),str,es,clk)
stmt = (?s:#stmt/when) : s
- stmt = (?x:#exp := ?y:#exp!) : Connect(first-info(form),x, y)
- stmt = (?x:#exp <> ?y:#exp!) : BulkConnect(first-info(form),x, y)
+ 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)))
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index ba0e2423..4b70175a 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -9,9 +9,9 @@ defpackage firrtl/ir-utils :
public defmulti print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field|Module|Circuit) -> False
public defmethod print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field|Module|Circuit) -> False : false
public defmulti turn-off-debug (x:False) -> False
-public defmethod turn-off-debug (x:False) : false
+;public defmethod turn-off-debug (x:False) : false
public defmulti turn-on-debug (x:False)
-public defmethod turn-on-debug (x:False) : false
+;public defmethod turn-on-debug (x:False) : false
;============== GENSYM STUFF ======================
@@ -314,9 +314,9 @@ defmethod print (o:OutputStream, c:Stmt) :
(c:Begin) :
do(print{o,_}, join(body(c), "\n"))
(c:Connect) :
- print-all(o, [loc(c) " := " exp(c)])
+ print-all(o, [loc(c) " <= " exp(c)])
(c:BulkConnect) :
- print-all(o, [loc(c) " <> " exp(c)])
+ print-all(o, [loc(c) " <- " exp(c)])
(c:Empty) :
print(o, "skip")
(c:Stop) :
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index 4dbd55d8..2621b408 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -96,7 +96,17 @@ defn get-gender (s:Stmt|Port) -> Gender :
OUTPUT : FEMALE
defmulti kind (e:Expression) -> Kind
-defmethod kind (e:Expression) : ExpKind()
+defmethod kind (e:Expression) :
+ match(e) :
+ (e:WRef) : kind(e)
+ (e:WSubField) : kind(exp(e))
+ (e:WSubIndex) : kind(exp(e))
+ (e:WIndexer) :
+ val k = kind(exps(e)[0])
+ for x in exps(e) do :
+ if k != kind(x) : error("All kinds of exps of WIndexer must be the same")
+ k
+ (e) : ExpKind()
defmethod info (stmt:Begin) -> FileInfo : FileInfo()
defmethod info (stmt:Empty) -> FileInfo : FileInfo()
@@ -213,6 +223,15 @@ defmethod turn-off-debug (x:False) :
old-PRINT-CIRCUITS = PRINT-CIRCUITS
old-PRINT-DEBUG = PRINT-DEBUG
old-PRINT-INFO = PRINT-INFO
+
+ PRINT-TYPES = false
+ PRINT-KINDS = false
+ PRINT-WIDTHS = false
+ PRINT-TWIDTHS = false
+ PRINT-GENDERS = false
+ PRINT-CIRCUITS = false
+ PRINT-DEBUG = false
+ PRINT-INFO = false
defmethod turn-on-debug (x:False) :
PRINT-TYPES = old-PRINT-TYPES
PRINT-KINDS = old-PRINT-KINDS
@@ -713,7 +732,9 @@ defn infer-types (c:Circuit) -> Circuit :
(e:DoPrim) : set-primop-type(e)
(e:UIntValue|SIntValue) : e
defn infer-types-s (s:Stmt) -> Stmt :
- match(map(infer-types-e,s)) :
+ map{infer-types-e,_} $ map(infer-types-s,s)
+ defn build-types (s:Stmt) -> Stmt :
+ match(s) :
(s:DefWire|DefPoison|DefRegister|DefMemory|DefNode) :
val t = remove-unknowns(get-type(s))
types[name(s)] = t
@@ -721,13 +742,13 @@ defn infer-types (c:Circuit) -> Circuit :
(s:WDefInstance) :
types[name(s)] = module-types[module(s)]
WDefInstance(info(s),name(s),module(s),module-types[module(s)])
- (s) : map(infer-types-s,s)
+ (s) : map(build-types,s)
for p in ports(m) do :
types[name(p)] = type(p)
match(m) :
(m:InModule) :
- val s* = infer-types-s(body(m))
- InModule(info(m),name(m),ports(m),s*)
+ val s* = build-types(body(m))
+ InModule(info(m),name(m),ports(m),infer-types-s(s*))
(m:ExModule) : m
; MAIN
@@ -1965,7 +1986,11 @@ defn split-exp (m:InModule) -> InModule :
if i > 0 : split(e)
else : e
(e) : e
- map{split-exp-e{_,0},_} $ map(split-exp-s,s)
+ match(s) :
+ (s:Begin) : map(split-exp-s,s)
+ (s) :
+ add(v,map{split-exp-e{_,0},_} $ map(split-exp-s,s))
+ s
split-exp-s(body(m))
InModule(info(m),name(m),ports(m),Begin(to-list(v)))
@@ -2391,7 +2416,7 @@ defn lowered-name (e:Expression) -> Symbol :
defn root-ref (e:Expression) -> Expression :
match(e) :
(e:WRef) : e
- (e:WSubField|WSubIndex) : root-ref(e)
+ (e:WSubField|WSubIndex) : root-ref(exp(e))
;------------- Pass ------------------
@@ -2500,7 +2525,7 @@ defn emit (x:?, top:Int) :
match(e) :
(e:DoPrim) : op-print(e)
(e:WRef) : print(e)
- ;(e:WSubField) : print-all([exp(e) `_ name(f)])
+ (e:WSubField) : print(lowered-name(e))
(e:WSubAccess) : print(e)
(e:WSubIndex) : print(e)
(e:UIntValue|SIntValue) : v-print(e)
@@ -2513,6 +2538,7 @@ defn emit (x:?, top:Int) :
else : ""
(s:Symbol) : print(s)
(i:Int) : print(i)
+ (i:Long) : print(i)
(s:String) : print(s)
(t:VIndent) : print(" ")
(r:VRandom) : print("$random")
@@ -2623,20 +2649,25 @@ defn emit-verilog (m:InModule) -> Module :
s
val declares = Vector<Streamable>()
+ val assigns = Vector<Streamable>()
val at-clock = HashTable<Expression,Vector<Streamable>>(exp-hash)
val initials = Vector<Streamable>()
val simulates = Vector<Streamable>()
defn declare (b:Symbol,n:Symbol,t:Type) :
add(declares,[b t n ";"])
defn assign (e:Expression,value:Expression) :
- add(declares,["assign " e " = " value])
+ add(assigns,["assign " e " = " value])
defn update-reset (e:Expression,clk:Expression,reset?:Expression,init:Expression) :
+ if not key?(at-clock,clk) :
+ at-clock[clk] = Vector<Streamable>()
add(at-clock[clk],["if(" reset? ") begin"])
add(at-clock[clk],[tab e " <= " init])
add(at-clock[clk],["end else"])
add(at-clock[clk],[tab e " <= " netlist[e]])
add(at-clock[clk],["end"])
defn update (e:Expression,clk:Expression,en:Expression) :
+ if not key?(at-clock,clk) :
+ at-clock[clk] = Vector<Streamable>()
add(at-clock[clk],["if(" en ") begin"])
add(at-clock[clk],[tab e " <= " netlist[e]])
add(at-clock[clk],["end"])
@@ -2649,11 +2680,16 @@ defn emit-verilog (m:InModule) -> Module :
defn instantiate (n:Symbol,m:Symbol,es:List<Expression>) :
add(declares,[m " " n " ("])
for (e in es,i in 1 to false) do :
- val s = [tab "." remove-root(e) "(" netlist[e] ")"]
+ val s = [tab "." remove-root(e) "(" lowered-name(e) ")"]
if i == length(es) : add(declares,[s ","])
else : add(declares,s)
add(declares,[");"])
+ for e in es do :
+ val e* = WRef(lowered-name(e),type(e),kind(e),gender(e))
+ if (gender(e) == FEMALE) : assign(e*,netlist[e])
defn simulate (clk:Expression,en:Expression,s:Streamable) :
+ if not key?(at-clock,clk) :
+ at-clock[clk] = Vector<Streamable>()
add(at-clock[clk],["`ifndef SYNTHESIS"])
add(at-clock[clk],[tab "if(" en ") begin"])
add(at-clock[clk],[tab tab s])
@@ -2676,6 +2712,7 @@ defn emit-verilog (m:InModule) -> Module :
defn build-streams (s:Stmt) -> Stmt :
match(s) :
+ (s:Connect) : s
(s:DefWire) :
val es = create-exps(WRef(name(s),type(s),WireKind(),BI-GENDER))
for e in es do :
@@ -2690,7 +2727,7 @@ defn emit-verilog (m:InModule) -> Module :
(s:DefPoison) :
val es = create-exps(WRef(name(s),type(s),PoisonKind(),MALE))
for e in es do :
- declare(`wire,lowered-name(e),type(e))
+ declare(`reg,lowered-name(e),type(e))
initialize(e)
(s:DefNode) :
declare(`wire,name(s),type(value(s)))
@@ -2748,9 +2785,14 @@ defn emit-verilog (m:InModule) -> Module :
s
defn emit-streams () :
+ emit(["module " name(m) "("])
if !empty?(declares) :
for x in declares do :
emit(x)
+
+ if !empty?(assigns) :
+ for x in assigns do :
+ emit(x)
if !empty?(initials) :
emit(["`ifndef SYNTHESIS"])
@@ -2768,6 +2810,7 @@ defn emit-verilog (m:InModule) -> Module :
for x in value(clk-stream) do :
emit([tab x])
emit(["end"])
+ emit(["endmodule"])
build-netlist(body(m))
build-streams(body(m))