diff options
| author | azidar | 2015-12-12 14:37:41 -0800 |
|---|---|---|
| committer | azidar | 2016-01-16 14:28:17 -0800 |
| commit | 28e4c6a09011cafdd1e3533118f7c3499e0d3dc6 (patch) | |
| tree | 42e8e2ed50a254f7fea61bc0a56d963258463bb5 /src | |
| parent | d9f33f58c94382dfbd22e87e2f85600b9807328f (diff) | |
WIP. Fixed a bunch of tests. Starting on implementing chirrtl, but hit roadblock in assigning clocked ports
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/compilers.stanza | 40 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 20 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 10 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 13 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 93 | ||||
| -rw-r--r-- | src/main/stanza/primop.stanza | 8 |
6 files changed, 142 insertions, 42 deletions
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza index 9e517f10..5cda6325 100644 --- a/src/main/stanza/compilers.stanza +++ b/src/main/stanza/compilers.stanza @@ -46,40 +46,38 @@ public defmethod backend (c:StandardVerilog) -> List<Pass> : public defmethod passes (c:StandardVerilog) -> List<Pass> : to-list $ [ ;RemoveSpecialChars() ;R - ;RemoveScopes() ;R ;CheckHighForm() ;R ;TempElimination() ;R ; Needs to check number of uses ToWorkingIR() ;R -> W ResolveKinds() ;W InferTypes() ;R ResolveGenders() ;W + InferWidths() ;R + Resolve() ;CheckGenders() ;W ;CheckKinds() ;W ;CheckTypes() ;R - ;ExpandAccesses() ;W - ExpandConnects() ;W - RemoveAccesses() - ResolveKinds() ;W - InferTypes() ;R - ResolveGenders() ;W - ;LowerToGround() ;W - ;ExpandIndexedConnects() ;W - ;InferTypes() ;R ;CheckGenders() ;W - ExpandWhens() ;W - ResolveKinds() ;W - InferTypes() ;R - ResolveGenders() ;W - InferWidths() ;R + ExpandConnects() + RemoveAccesses() + ExpandWhens() + ConstProp() + SplitExp() + + ResolveKinds() + InferTypes() + ResolveGenders() + InferWidths() + + LowerTypes() + + ResolveKinds() + InferTypes() + ResolveGenders() + InferWidths() ;ToRealIR() ;W -> R ;CheckWidths() ;R ;Pad() ;R - ConstProp() ;R - SplitExp() ;R - LowerTypes() ;R - ResolveKinds() ;W - InferTypes() ;R - ResolveGenders() ;W ;CheckWidths() ;R ;CheckHighForm() ;R ;CheckLowForm() ;R diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index 7ac72922..8aba5f9c 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -160,6 +160,26 @@ public defstruct Print <: Stmt : ;LOW en: Expression public defstruct Empty <: Stmt ;LOW + +; CHIRRTL Features +public defstruct MPortDir +public val MRead = MPortDir() +public val MWrite = MPortDir() +public val MReadWrite = MPortDir() + +public defstruct CDefMemory <: Stmt : ;LOW + info: FileInfo with: (as-method => true) + name: Symbol + type: Type + seq?: True|False +public defstruct CDefMPort <: Stmt : + info: FileInfo with: (as-method => true) + name: Symbol + mem: Symbol + index: Expression + clk: Expression + direction: MPortDir + public definterface Type public defstruct UIntType <: Type : width: Width diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index 94cc1a6a..28a5d1cb 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -260,6 +260,16 @@ defsyntax firrtl : 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) + stmt = (cmem ?name:#id! #:! ?t:#type!) : CDefMemory(first-info(form),name,t,false) + stmt = (smem ?name:#id! #:! ?t:#type!) : CDefMemory(first-info(form),name,t,true) + + stmt = (read mport ?name:#id! #=! ?mem:#id! (@get ?index:#exp!) ?clk:#exp!) : + CDefMPort(first-info(form),name,mem,index,clk,MRead) + stmt = (write mport ?name:#id! #=! ?mem:#id! (@get ?index:#exp!) ?clk:#exp!) : + CDefMPort(first-info(form),name,mem,index,clk,MWrite) + stmt = (rdwr mport ?name:#id! #=! ?mem:#id! (@get ?index:#exp!) ?clk:#exp!) : + CDefMPort(first-info(form),name,mem,index,clk,MReadWrite) + stmt = (mem ?name:#id! #:! (?ms:#mstat ...)) : defn grab (f:MStat -> True|False) : map(value,to-list(filter(f,ms))) as List diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza index 9c997f39..0ff2669d 100644 --- a/src/main/stanza/ir-utils.stanza +++ b/src/main/stanza/ir-utils.stanza @@ -328,9 +328,22 @@ defmethod print (o:OutputStream, c:Stmt) : print-all(o, ["printf(" clk(c) ", " en(c) ", "]) ;" print-all(o, join(List(escape(string(c)),args(c)), ", ")) print(o, ")") + (c:CDefMemory) : + if seq?(c) : + print-all(o, ["smem " name(c) " : " type(c)]) + else : + print-all(o, ["cmem " name(c) " : " type(c)]) + (c:CDefMPort) : + print-all(o, [direction(c) " mport " name(c) " = " mem(c) "[" index(c) "], " clk(c)]) if not c typeof Conditionally|Begin|Empty: print-debug(o,c) +defmethod print (o:OutputStream, m:MPortDir) : + switch { m == _ } : + MRead : print(o,"read") + MWrite : print(o,"write") + MReadWrite : print(o,"rdwr") + defmethod print (o:OutputStream, t:Type) : match(t) : (t:UnknownType) : diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 14e3e75d..6367b51a 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -13,6 +13,7 @@ public val standard-passes = to-list $ [ CheckHighForm() ;TempElimination() ToWorkingIR() + Resolve() ResolveKinds() ;CheckKinds() InferTypes() @@ -727,11 +728,16 @@ 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)) : - (s:DefWire|DefPoison|DefRegister|DefNode) : + match(s) : + (s:DefRegister) : val t = remove-unknowns(get-type(s)) types[name(s)] = t - set-type(s,t) + map(infer-types-e,set-type(s,t)) + (s:DefWire|DefPoison|DefNode) : + val s* = map(infer-types-e,s) + val t = remove-unknowns(get-type(s*)) + types[name(s*)] = t + set-type(s*,t) (s:DefMemory) : val t = remove-unknowns(get-type(s)) types[name(s)] = t @@ -740,7 +746,7 @@ 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{infer-types-e,_} $ map(infer-types-s,s) for p in ports(m) do : types[name(p)] = type(p) match(m) : @@ -894,6 +900,7 @@ defn get-point (e:Expression) -> Int : (e:WSubAccess) : get-point(exp(e)) defn get-valid-points (t1:Type,t2:Type,flip1:Flip,flip2:Flip) -> List<[Int,Int]> : + println-all(["Inside with t1:" t1 ",t2:" t2 ",f1:" flip1 ",f2:" flip2]) match(t1,t2) : (t1:UIntType,t2:UIntType) : if flip1 == flip2 : list([0, 0]) @@ -907,6 +914,10 @@ defn get-valid-points (t1:Type,t2:Type,flip1:Flip,flip2:Flip) -> List<[Int,Int]> var jlen = 0 for i in 0 to length(fields(t1)) do : for j in 0 to length(fields(t2)) do : + println(i) + println(j) + println(ilen) + println(jlen) val f1 = fields(t1)[i] val f2 = fields(t2)[j] if name(f1) == name(f2) : @@ -914,8 +925,10 @@ defn get-valid-points (t1:Type,t2:Type,flip1:Flip,flip2:Flip) -> List<[Int,Int]> flip2 * flip(f2)) for x in ls do : add(points,[x[0] + ilen, x[1] + jlen]) - ilen = ilen + get-size(type(fields(t1)[i])) + println(points) jlen = jlen + get-size(type(fields(t2)[j])) + ilen = ilen + get-size(type(fields(t1)[i])) + jlen = 0 to-list(points) (t1:VectorType,t2:VectorType) : val points = Vector<[Int,Int]>() @@ -1040,7 +1053,9 @@ defn remove-access (c:Circuit) : (e:UIntValue|SIntValue) : e (e) : val rs = get-locations(e) - if length(rs) == 1 and guard(head(rs)) == one : e + val foo = for x in rs find : + (guard(x)) != one + if foo == false : e else : val temp = create-temp(e) for (x in rs, i in 0 to false) do : @@ -1170,6 +1185,7 @@ defn expand-whens (c:Circuit) -> Circuit : defn create-module (netlist:HashTable<Expression,Expression>,simlist:Vector<Stmt>,m:InModule) -> InModule : val stmts = Vector<Stmt>() + val connections = Vector<Stmt>() defn replace-void (e:Expression,rvalue:Expression) -> Expression : match(rvalue) : (rv:WVoid) : e @@ -1182,7 +1198,7 @@ defn expand-whens (c:Circuit) -> Circuit : val rvalue = if s typeof DefRegister : replace-void(e,netlist[e]) else : netlist[e] - add(stmts,Connect(info(s),e,rvalue)) + add(connections,Connect(info(s),e,rvalue)) (s:DefPoison|DefNode) : add(stmts,s) (s) : map(create,s) @@ -1190,10 +1206,10 @@ defn expand-whens (c:Circuit) -> Circuit : create(body(m)) for p in ports(m) do : for e in get-female-refs(name(p),type(p),get-gender(p)) do : - add(stmts,Connect(info(p),e,netlist[e])) + add(connections,Connect(info(p),e,netlist[e])) for x in simlist do : add(stmts,x) - InModule(info(m),name(m),ports(m),Begin(to-list(stmts))) + InModule(info(m),name(m),ports(m),Begin(list(Begin(to-list(stmts)),Begin(to-list(connections))))) val voided-modules = for m in modules(c) map : @@ -1515,7 +1531,27 @@ defn infer-widths (c:Circuit) -> Circuit : defn get-constraints (s:Stmt) -> Stmt : match(map(get-constraints-e,s)) : (s:Connect) : - constrain(width!(loc(s)),width!(exp(s))) + ;constrain(width!(loc(s)),width!(exp(s))) + ;s + val n = get-size(loc(s)) + for i in 0 to n do : + val loc* = create-exps(loc(s))[i] + val exp* = create-exps(exp(s))[i] + switch { _ == get-flip(type(loc(s)),i,DEFAULT) } : + DEFAULT : constrain(width!(loc*),width!(exp*)) + REVERSE : constrain(width!(exp*),width!(loc*)) + s + (s:BulkConnect) : + val ls = get-valid-points(type(loc(s)),type(exp(s)),DEFAULT,DEFAULT) + for x in ls do : + println(x) + println(create-exps(loc(s))) + println(create-exps(exp(s))) + val loc* = create-exps(loc(s))[x[0]] + val exp* = create-exps(exp(s))[x[1]] + switch { _ == get-flip(type(loc(s)),x[0],DEFAULT) } : + DEFAULT : constrain(width!(loc*),width!(exp*)) + REVERSE : constrain(width!(exp*),width!(loc*)) s (s:DefRegister) : constrain(width!(reset(s)),ONE) @@ -1541,6 +1577,17 @@ defn infer-widths (c:Circuit) -> Circuit : println-debug("====================================") reduce-var-widths(Circuit(info(c),modules(c),main(c)),h) +; ================ All Resolving Passes ================ +public defstruct Resolve <: Pass +public defmethod pass (b:Resolve) -> (Circuit -> Circuit) : resolve +public defmethod name (b:Resolve) -> String : "Resolve" +public defmethod short-name (b:Resolve) -> String : "resolve" + +defn resolve (c:Circuit) -> Circuit : + infer-widths $ + resolve-genders $ + infer-types $ + resolve-kinds $ c ;;================= Inline Instances ======================== ;; Inlines instances. Assumes module with same name as the @@ -1629,7 +1676,7 @@ defn split-exp (m:InModule) -> InModule : if i > 0 : split(e) else : e (e) : e - match(s) : + match(map(split-exp-e{_,0},s)) : (s:Begin) : map(split-exp-s,s) (s) : add(v,s) @@ -2028,8 +2075,11 @@ defn lower-types (m:Module) -> Module : (e:WSubField) : match(kind(e)) : (k:InstanceKind) : - val temp = lowered-name(WRef(name(e),UnknownType(),InstanceKind(),MALE)) - WSubField(root-ref(e),temp,type(e),gender(e)) + val names = expand-name(e) + var n = names[1] + for (x in names,i in 0 to false) do : + if i > 1 : n = symbol-join([n `_ x]) + WSubField(root-ref(e),n,type(e),gender(e)) (k:MemKind) : if not gender(e) == FEMALE : lower-mem(e)[0] @@ -2038,14 +2088,21 @@ defn lower-types (m:Module) -> Module : (e:WSubIndex) : WRef(lowered-name(e),type(e),kind(e),gender(e)) (e:DoPrim) : map(lower-types-e,e) match(map(lower-types-e,s)) : - (s:DefWire|DefRegister|DefPoison) : + (s:DefWire|DefPoison) : if is-ground?(type(s)) : s else : val es = create-exps(name(s),type(s)) - Begin $ for e in es map : + Begin $ for (e in es, i in 0 to false) map : defn replace-type (t:Type) -> Type : type(e) defn replace-name (n:Symbol) -> Symbol : lowered-name(e) map{replace-name,_} $ map(replace-type,s) + (s:DefRegister) : + if is-ground?(type(s)) : s + else : + val es = create-exps(name(s),type(s)) + Begin $ for (e in es, i in 0 to false) map : + val init = lower-types-e(create-exps(init(s))[i]) + DefRegister(info(s),lowered-name(e),type(e),clock(s),reset(s),init) (s:WDefInstance) : val fields* = for f in fields(type(s) as BundleType) map-append : val es = create-exps(WRef(name(f),type(f),ExpKind(),flip(f) * MALE)) @@ -2278,7 +2335,9 @@ defn emit-verilog (m:InModule) -> Module : val initials = Vector<Streamable>() val simulates = Vector<Streamable>() defn declare (b:Symbol,n:Symbol,t:Type) : - add(declares,[b " " t " " n ";"]) + match(t) : + (t:VectorType) : add(declares,[b " " type(t) " " n " [0:" size(t) - 1 "];"]) + (t) : add(declares,[b " " t " " n ";"]) defn assign (e:Expression,value:Expression) : add(assigns,["assign " e " = " value]) defn update-and-reset (e:Expression,clk:Expression,reset?:Expression,init:Expression) : @@ -2503,7 +2562,7 @@ defn emit-verilog (m:InModule) -> Module : for clk-stream in at-clock do : if !empty?(value(clk-stream)) : - emit([tab "always @(posedge " key(clk-stream) " ) begin"]) + emit([tab "always @(posedge " key(clk-stream) ") begin"]) for x in value(clk-stream) do : emit([tab tab x]) emit([tab "end"]) diff --git a/src/main/stanza/primop.stanza b/src/main/stanza/primop.stanza index a31b9c51..8cbae193 100644 --- a/src/main/stanza/primop.stanza +++ b/src/main/stanza/primop.stanza @@ -5,13 +5,13 @@ defpackage firrtl/primops : import firrtl/ir-utils import firrtl/passes -defn PLUS (w1:Width,w2:Width) -> Width : PlusWidth(w1,w2) -defn MAX (w1:Width,w2:Width) -> Width : MaxWidth(list(w1,w2)) -defn MINUS (w1:Width,w2:Width) -> Width : MinusWidth(w1,w2) -defn POW (w1:Width) -> Width : ExpWidth(w1) public defn set-primop-type (e:DoPrim) -> DoPrim : ;println-all(["Inferencing primop type: " e]) + defn PLUS (w1:Width,w2:Width) -> Width : PlusWidth(w1,w2) + defn MAX (w1:Width,w2:Width) -> Width : MaxWidth(list(w1,w2)) + defn MINUS (w1:Width,w2:Width) -> Width : MinusWidth(w1,w2) + defn POW (w1:Width) -> Width : ExpWidth(w1) val o = op(e) val a = args(e) val c = consts(e) |
