diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/compilers.stanza | 5 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 98 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 8 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 65 |
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)) |
