diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/chirrtl.stanza | 45 | ||||
| -rw-r--r-- | src/main/stanza/compilers.stanza | 8 | ||||
| -rw-r--r-- | src/main/stanza/errors.stanza | 98 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 29 | ||||
| -rw-r--r-- | src/main/stanza/flo.stanza | 2 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 37 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 58 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 143 | ||||
| -rw-r--r-- | src/main/stanza/primop.stanza | 142 | ||||
| -rw-r--r-- | src/main/stanza/verilog.stanza | 2 |
10 files changed, 319 insertions, 245 deletions
diff --git a/src/main/stanza/chirrtl.stanza b/src/main/stanza/chirrtl.stanza index 9b3b90ab..6bce8ce4 100644 --- a/src/main/stanza/chirrtl.stanza +++ b/src/main/stanza/chirrtl.stanza @@ -223,6 +223,7 @@ defstruct DataRef : male : Symbol female : Symbol mask : Symbol + rdwrite? : True|False public definterface Gender public val MALE = new Gender @@ -272,26 +273,26 @@ defn remove-chirrtl (c:Circuit) : (s:CDefMemory) : mport-types[name(s)] = type(s) val stmts = Vector<Stmt>() - val naddr = firrtl-gensym(`GEN,sh) + ;val naddr = firrtl-gensym(`GEN,sh) val taddr = UIntType(IntWidth(max(1,ceil-log2(size(s))))) - add(stmts,DefPoison(info(s),naddr,taddr)) - val ndata = firrtl-gensym(`GEN,sh) + ;add(stmts,DefPoison(info(s),naddr,taddr)) + ;val ndata = firrtl-gensym(`GEN,sh) val tdata = type(s) - add(stmts,DefPoison(info(s),ndata,tdata)) + ;add(stmts,DefPoison(info(s),ndata,tdata)) defn set-poison (vec:List<MPort>,addr:Symbol) -> False : for r in vec do : - add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),addr,taddr),Ref(naddr,taddr))) + add(stmts,IsInvalid(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),addr,taddr))) add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),`clk,taddr),clk(r))) defn set-enable (vec:List<MPort>,en:Symbol) -> False: for r in vec do : add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),en,taddr),zero)) - defn set-rmode (vec:List<MPort>,rmode:Symbol) -> False: + defn set-wmode (vec:List<MPort>,wmode:Symbol) -> False: for r in vec do : - add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),rmode,taddr),one)) + add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),wmode,taddr),zero)) defn set-write (vec:List<MPort>,data:Symbol,mask:Symbol) -> False : val tmask = create-mask(type(s)) for r in vec do : - add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),data,tdata),Ref(ndata,tdata))) + add(stmts,IsInvalid(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),data,tdata))) for x in create-exps(SubField(SubField(Ref(name(s),ut),name(r),ut),mask,tmask)) do : add(stmts,Connect(info(s),x,zero)) @@ -304,7 +305,7 @@ defn remove-chirrtl (c:Circuit) : set-write(wrs,`data,`mask) val rws = to-list $ readwriters $ get?(hash,name(s),EMPs()) set-poison(rws,`addr) - set-rmode(rws,`rmode) + set-wmode(rws,`wmode) set-enable(rws,`en) set-write(rws,`data,`mask) val read-l = @@ -317,21 +318,19 @@ defn remove-chirrtl (c:Circuit) : val addrs = Vector<Symbol>() val ens = Vector<Symbol>() val masks = Vector<Symbol>() - val rmodes = Vector<Symbol>() switch { _ == direction(s) } : MReadWrite : - repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`rdata,`data,`mask) + repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`rdata,`data,`mask,true) add(addrs,`addr) add(ens,`en) - add(rmodes,`rmode) add(masks,`mask) MWrite : - repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`data,`data,`mask) + repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`data,`data,`mask,false) add(addrs,`addr) add(ens,`en) add(masks,`mask) else : - repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`data,`data,`blah) + repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`data,`data,`blah,false) add(addrs,`addr) add(ens,`en) @@ -340,14 +339,13 @@ defn remove-chirrtl (c:Circuit) : add(stmts,Connect(info(s),SubField(SubField(Ref(mem(s),ut),name(s),ut),x,ut),exps(s)[0])) for x in ens do : add(stmts,Connect(info(s),SubField(SubField(Ref(mem(s),ut),name(s),ut),x,ut),one)) - for x in rmodes do : - add(stmts,Connect(info(s),SubField(SubField(Ref(mem(s),ut),name(s),ut),x,ut),zero)) Begin $ to-list $ stmts (s) : map(collect-refs,s) defn remove-chirrtl-s (s:Stmt) -> Stmt : var has-write-mport? = false + var has-readwrite-mport? = false defn remove-chirrtl-e (e:Expression,g:Gender) -> Expression : - match(map(remove-chirrtl-e{_,g},e)) : + match(e) : (e:Ref) : if key?(repl,name(e)) : val vt = repl[name(e)] @@ -355,9 +353,12 @@ defn remove-chirrtl (c:Circuit) : MALE : SubField(exp(vt),male(vt),type(e)) FEMALE : has-write-mport? = true + if rdwrite?(vt) == true : + has-readwrite-mport? = SubField(exp(vt),`wmode,UIntType(IntWidth(1))) SubField(exp(vt),female(vt),type(e)) else : e - (e) : e + (e:SubAccess) : SubAccess(remove-chirrtl-e(exp(e),g),remove-chirrtl-e(index(e),MALE),type(e)) + (e) : map(remove-chirrtl-e{_,g},e) defn get-mask (e:Expression) -> Expression : match(map(get-mask,e)) : (e:Ref) : @@ -377,6 +378,9 @@ defn remove-chirrtl (c:Circuit) : val e = get-mask(loc(s)) for x in create-exps(e) do : add(stmts,Connect(info(s),x,one)) + if has-readwrite-mport? != false : + val wmode = has-readwrite-mport? as Expression + add(stmts,Connect(info(s),wmode,one)) if length(stmts) > 1 : Begin(to-list(stmts)) else : stmts[0] (s:BulkConnect) : @@ -384,12 +388,15 @@ defn remove-chirrtl (c:Circuit) : val loc* = remove-chirrtl-e(loc(s),FEMALE) val roc* = remove-chirrtl-e(exp(s),MALE) add(stmts,BulkConnect(info(s),loc*,roc*)) - if has-write-mport? : + if has-write-mport? != false : val ls = get-valid-points(type(loc(s)),type(exp(s)),DEFAULT,DEFAULT) val locs = create-exps(get-mask(loc(s))) for x in ls do : val loc* = locs[x[0]] add(stmts,Connect(info(s),loc*,one)) + if has-readwrite-mport? != false : + val wmode = has-readwrite-mport? as Expression + add(stmts,Connect(info(s),wmode,one)) if length(stmts) > 1 : Begin(to-list(stmts)) else : stmts[0] (s) : map(remove-chirrtl-e{_,MALE}, map(remove-chirrtl-s,s)) diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza index 3ca4f8da..0d0191bf 100644 --- a/src/main/stanza/compilers.stanza +++ b/src/main/stanza/compilers.stanza @@ -78,8 +78,6 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> : ;=============== ConstProp() ;=============== - SplitExp() - ;=============== ResolveKinds() InferTypes() CheckTypes() @@ -98,6 +96,8 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> : InferWidths() CheckWidths() ;=============== + VerilogWrap() + SplitExp() VerilogRename() Verilog(with-output(c)) ;=============== @@ -152,8 +152,6 @@ public defmethod passes (c:StandardLoFIRRTL) -> List<Pass> : ;=============== ConstProp() ;=============== - SplitExp() - ;=============== ResolveKinds() InferTypes() CheckTypes() @@ -172,6 +170,8 @@ public defmethod passes (c:StandardLoFIRRTL) -> List<Pass> : InferWidths() CheckWidths() ;=============== + SplitExp() + ;=============== FIRRTL(with-output(c)) ] diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza index 3e388a42..a0c48dc8 100644 --- a/src/main/stanza/errors.stanza +++ b/src/main/stanza/errors.stanza @@ -191,39 +191,34 @@ public defn check-high-form (c:Circuit) -> Circuit : SUB-OP : correct-num(2,0) MUL-OP : correct-num(2,0) DIV-OP : correct-num(2,0) - MOD-OP : correct-num(2,0) - QUO-OP : correct-num(2,0) REM-OP : correct-num(2,0) - ADD-WRAP-OP : correct-num(2,0) - SUB-WRAP-OP : correct-num(2,0) LESS-OP : correct-num(2,0) LESS-EQ-OP : correct-num(2,0) GREATER-OP : correct-num(2,0) 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) AS-SINT-OP : correct-num(1,0) - DYN-SHIFT-LEFT-OP : correct-num(2,0) - DYN-SHIFT-RIGHT-OP : correct-num(2,0) + AS-CLOCK-OP : correct-num(1,0) SHIFT-LEFT-OP : correct-num(1,1) SHIFT-RIGHT-OP : correct-num(1,1) + DYN-SHIFT-LEFT-OP : correct-num(2,0) + DYN-SHIFT-RIGHT-OP : correct-num(2,0) CONVERT-OP : correct-num(1,0) NEG-OP : correct-num(1,0) - BIT-NOT-OP : correct-num(1,0) - BIT-AND-OP : correct-num(2,0) - BIT-OR-OP : correct-num(2,0) - BIT-XOR-OP : correct-num(2,0) - BIT-AND-REDUCE-OP : correct-num(false,0) - BIT-OR-REDUCE-OP : correct-num(false,0) - BIT-XOR-REDUCE-OP : correct-num(false,0) + NOT-OP : correct-num(1,0) + AND-OP : correct-num(2,0) + OR-OP : correct-num(2,0) + XOR-OP : correct-num(2,0) + AND-REDUCE-OP : correct-num(false,0) + OR-REDUCE-OP : correct-num(false,0) + XOR-REDUCE-OP : correct-num(false,0) CONCAT-OP : correct-num(2,0) - BIT-SELECT-OP : correct-num(1,1) BITS-SELECT-OP : correct-num(1,2) + HEAD-OP : correct-num(1,1) + TAIL-OP : correct-num(1,1) defn check-fstring (s:String,i:Int) -> False : val valid-formats = "bedxs" @@ -481,48 +476,39 @@ defn check-types-primop (e:DoPrim, errors:Vector<PassException>,info:FileInfo) - error? = true if error? : add(errors,OpNotUInt(info,to-symbol $ op(e),to-symbol(x))) - all-ground(args(e)) - switch {op(e) == _} : - ADD-OP : false - SUB-OP : false - MUL-OP : false - DIV-OP : false - MOD-OP : false - QUO-OP : false - REM-OP : false - ADD-WRAP-OP : false - SUB-WRAP-OP : false - LESS-OP : false - LESS-EQ-OP : false - GREATER-OP : false - GREATER-EQ-OP : false - 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))) - PAD-OP : false AS-UINT-OP : false AS-SINT-OP : false - DYN-SHIFT-LEFT-OP : is-uint(args(e)[1]) - DYN-SHIFT-RIGHT-OP : is-uint(args(e)[1]) - SHIFT-LEFT-OP : false - SHIFT-RIGHT-OP : false - CONVERT-OP : false - NEG-OP : false - BIT-NOT-OP : all-same-type(args(e)) ;can be either uint or sint - BIT-AND-OP : all-same-type(args(e)) ;can be either uint or sint - BIT-OR-OP : all-same-type(args(e)) ;can be either uint or sint - BIT-XOR-OP : all-same-type(args(e)) ;can be either uint or sint - BIT-SELECT-OP : false ;can be either uint or sint - BITS-SELECT-OP : false ;can be either uint or sint - BIT-AND-REDUCE-OP : false ;can be either uint or sint - BIT-OR-REDUCE-OP : false ;can be either uint or sint - BIT-XOR-REDUCE-OP : false ;can be either uint or sint - CONCAT-OP : false ;can be either uint or sint + AS-CLOCK-OP : false + DYN-SHIFT-LEFT-OP : (is-uint(args(e)[1]) all-ground(args(e))) + DYN-SHIFT-RIGHT-OP : (is-uint(args(e)[1]) all-ground(args(e))) + ADD-OP : all-ground(args(e)) + SUB-OP : all-ground(args(e)) + MUL-OP : all-ground(args(e)) + DIV-OP : all-ground(args(e)) + REM-OP : all-ground(args(e)) + LESS-OP : all-ground(args(e)) + LESS-EQ-OP : all-ground(args(e)) + GREATER-OP : all-ground(args(e)) + GREATER-EQ-OP : all-ground(args(e)) + EQUAL-OP : all-ground(args(e)) + NEQUAL-OP : all-ground(args(e)) + PAD-OP : all-ground(args(e)) + SHIFT-LEFT-OP : all-ground(args(e)) + SHIFT-RIGHT-OP : all-ground(args(e)) + CONVERT-OP : all-ground(args(e)) + NEG-OP : all-ground(args(e)) + NOT-OP : all-ground(args(e)) + AND-OP : all-ground(args(e)) + OR-OP : all-ground(args(e)) + XOR-OP : all-ground(args(e)) + AND-REDUCE-OP : all-ground(args(e)) + OR-REDUCE-OP : all-ground(args(e)) + XOR-REDUCE-OP : all-ground(args(e)) + CONCAT-OP : all-ground(args(e)) + BITS-SELECT-OP : all-ground(args(e)) + HEAD-OP : all-ground(args(e)) + TAIL-OP : all-ground(args(e)) ;----------------- Check Types Pass --------------------- public defn check-types (c:Circuit) -> Circuit : diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index 4d906c70..e6c242bf 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -32,39 +32,34 @@ public val ADD-OP = new PrimOp public val SUB-OP = new PrimOp public val MUL-OP = new PrimOp public val DIV-OP = new PrimOp -public val MOD-OP = new PrimOp -public val QUO-OP = new PrimOp public val REM-OP = new PrimOp -public val ADD-WRAP-OP = new PrimOp -public val SUB-WRAP-OP = new PrimOp public val LESS-OP = new PrimOp public val LESS-EQ-OP = new PrimOp 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 public val AS-SINT-OP = new PrimOp -public val DYN-SHIFT-LEFT-OP = new PrimOp -public val DYN-SHIFT-RIGHT-OP = new PrimOp +public val AS-CLOCK-OP = new PrimOp public val SHIFT-LEFT-OP = new PrimOp public val SHIFT-RIGHT-OP = new PrimOp +public val DYN-SHIFT-LEFT-OP = new PrimOp +public val DYN-SHIFT-RIGHT-OP = new PrimOp public val NEG-OP = new PrimOp public val CONVERT-OP = new PrimOp -public val BIT-NOT-OP = new PrimOp -public val BIT-AND-OP = new PrimOp -public val BIT-OR-OP = new PrimOp -public val BIT-XOR-OP = new PrimOp +public val NOT-OP = new PrimOp +public val AND-OP = new PrimOp +public val OR-OP = new PrimOp +public val XOR-OP = new PrimOp +public val AND-REDUCE-OP = new PrimOp +public val OR-REDUCE-OP = new PrimOp +public val XOR-REDUCE-OP = new PrimOp public val CONCAT-OP = new PrimOp -public val BIT-SELECT-OP = new PrimOp public val BITS-SELECT-OP = new PrimOp -public val BIT-AND-REDUCE-OP = new PrimOp -public val BIT-OR-REDUCE-OP = new PrimOp -public val BIT-XOR-REDUCE-OP = new PrimOp +public val HEAD-OP = new PrimOp +public val TAIL-OP = new PrimOp public definterface Expression public defmulti type (e:Expression) -> Type diff --git a/src/main/stanza/flo.stanza b/src/main/stanza/flo.stanza index 3b1dbf76..015da39a 100644 --- a/src/main/stanza/flo.stanza +++ b/src/main/stanza/flo.stanza @@ -31,7 +31,7 @@ defn flo-op-name (op:PrimOp, args:List<Expression>) -> String : SUB-WRAP-OP : "sub" MUL-OP : "mul" ;; todo: signed version DIV-OP : "div" ;; todo: signed version - MOD-OP : "mod" ;; todo: signed version + REM-OP : "mod" ;; todo: signed version QUO-OP : "div" ;; todo: signed version REM-OP : "mod" ;; todo: signed version LESS-OP : "lt" ;; todo: signed version diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index e1083d50..139216c3 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -63,39 +63,35 @@ OPERATORS[`add] = ADD-OP OPERATORS[`sub] = SUB-OP OPERATORS[`mul] = MUL-OP OPERATORS[`div] = DIV-OP -OPERATORS[`mod] = MOD-OP -OPERATORS[`quo] = QUO-OP OPERATORS[`rem] = REM-OP -OPERATORS[`addw] = ADD-WRAP-OP -OPERATORS[`subw] = SUB-WRAP-OP OPERATORS[`lt] = LESS-OP OPERATORS[`leq] = LESS-EQ-OP 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 OPERATORS[`asUInt] = AS-UINT-OP OPERATORS[`asSInt] = AS-SINT-OP -OPERATORS[`dshl] = DYN-SHIFT-LEFT-OP -OPERATORS[`dshr] = DYN-SHIFT-RIGHT-OP +OPERATORS[`asClock] = AS-CLOCK-OP OPERATORS[`shl] = SHIFT-LEFT-OP OPERATORS[`shr] = SHIFT-RIGHT-OP +OPERATORS[`dshl] = DYN-SHIFT-LEFT-OP +OPERATORS[`dshr] = DYN-SHIFT-RIGHT-OP OPERATORS[`cvt] = CONVERT-OP -OPERATORS[`andr] = BIT-AND-REDUCE-OP -OPERATORS[`orr] = BIT-OR-REDUCE-OP -OPERATORS[`xorr] = BIT-XOR-REDUCE-OP -OPERATORS[`not] = BIT-NOT-OP -OPERATORS[`and] = BIT-AND-OP -OPERATORS[`or] = BIT-OR-OP -OPERATORS[`xor] = BIT-XOR-OP +OPERATORS[`neg] = NEG-OP +OPERATORS[`not] = NOT-OP +OPERATORS[`and] = AND-OP +OPERATORS[`or] = OR-OP +OPERATORS[`xor] = XOR-OP +OPERATORS[`andr] = AND-REDUCE-OP +OPERATORS[`orr] = OR-REDUCE-OP +OPERATORS[`xorr] = XOR-REDUCE-OP OPERATORS[`cat] = CONCAT-OP -OPERATORS[`bit] = BIT-SELECT-OP OPERATORS[`bits] = BITS-SELECT-OP +OPERATORS[`head] = HEAD-OP +OPERATORS[`tail] = TAIL-OP ;======== Parser Rules ================== defsyntax firrtl : @@ -250,7 +246,7 @@ defsyntax firrtl : defrule mstat : mstat = (reader #=>! ?name:#id!) : Reader(name) mstat = (writer #=>! ?name:#id!) : Writer(name) - mstat = (read-writer #=>! ?name:#id!) : ReadWriter(name) + mstat = (readwriter #=>! ?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) @@ -258,9 +254,8 @@ defsyntax firrtl : 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) + stmt = (reg ?name:#id! #:! ?t:#type! ?clk:#exp! with #:! ( reset => (?reset:#exp! ?init:#exp!))) : DefRegister(first-info(form),name,t,clk,reset,init) + stmt = (reg ?name:#id! #:! ?t:#type! ?clk:#exp!) : DefRegister(first-info(form),name,t,clk,zero,Ref(name,UnknownType())) stmt = (cmem ?name:#id! #:! ?t:#vectype! ) : CDefMemory(first-info(form),name,type(t),size(t),false) stmt = (smem ?name:#id! #:! ?t:#vectype! ) : CDefMemory(first-info(form),name,type(t),size(t),true) diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza index cf9e03e2..24149649 100644 --- a/src/main/stanza/ir-utils.stanza +++ b/src/main/stanza/ir-utils.stanza @@ -100,17 +100,17 @@ public defn AND (e1:Expression,e2:Expression) -> Expression : else if e1 == zero or e2 == zero : zero else if e1 == one : e2 else if e2 == one : e1 - else : DoPrim(BIT-AND-OP,list(e1,e2),list(),UIntType(IntWidth(1))) + else : DoPrim(AND-OP,list(e1,e2),list(),UIntType(IntWidth(1))) public defn OR (e1:Expression,e2:Expression) -> Expression : if e1 == e2 : e1 else if e1 == one or e2 == one : one else if e1 == zero : e2 else if e2 == zero : e1 - else : DoPrim(BIT-OR-OP,list(e1,e2),list(),UIntType(IntWidth(1))) + else : DoPrim(OR-OP,list(e1,e2),list(),UIntType(IntWidth(1))) public defn EQV (e1:Expression,e2:Expression) -> Expression : - DoPrim(EQUIV-OP,list(e1,e2),list(),type(e1)) + DoPrim(EQUAL-OP,list(e1,e2),list(),type(e1)) public defn MUX (p:Expression,e1:Expression,e2:Expression) -> Expression : Mux(p,e1,e2,mux-type(type(e1),type(e2))) @@ -134,7 +134,7 @@ public defn CAT (e1:Expression,e2:Expression) -> Expression : public defn NOT (e1:Expression) -> Expression : if e1 == one : zero else if e1 == zero : one - else : DoPrim(EQUIV-OP,list(e1,zero),list(),UIntType(IntWidth(1))) + else : DoPrim(EQUAL-OP,list(e1,zero),list(),UIntType(IntWidth(1))) public defn children (e:Expression) -> List<Expression> : val es = Vector<Expression>() @@ -185,12 +185,12 @@ public defmethod get-type (s:Stmt) -> Type : val def-data = Field(`data,DEFAULT,data-type(s)) val rev-data = Field(`data,REVERSE,data-type(s)) val mask = Field(`mask,DEFAULT,create-mask(data-type(s))) - val rmode = Field(`rmode,DEFAULT,UIntType(IntWidth(1))) + val wmode = Field(`wmode,DEFAULT,UIntType(IntWidth(1))) val rdata = Field(`rdata,REVERSE,data-type(s)) val read-type = BundleType(to-list([rev-data,addr,en,clk])) val write-type = BundleType(to-list([def-data,mask,addr,en,clk])) - val readwrite-type = BundleType(to-list([rmode,rdata,def-data,mask,addr,en,clk])) + val readwrite-type = BundleType(to-list([wmode,rdata,def-data,mask,addr,en,clk])) val mem-fields = Vector<Field>() for x in readers(s) do : @@ -360,39 +360,34 @@ defmethod print (o:OutputStream, op:PrimOp) : SUB-OP : "sub" MUL-OP : "mul" DIV-OP : "div" - MOD-OP : "mod" - QUO-OP : "quo" REM-OP : "rem" - ADD-WRAP-OP : "addw" - SUB-WRAP-OP : "subw" LESS-OP : "lt" 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" PAD-OP : "pad" AS-UINT-OP : "asUInt" AS-SINT-OP : "asSInt" - DYN-SHIFT-LEFT-OP : "dshl" - DYN-SHIFT-RIGHT-OP : "dshr" + AS-CLOCK-OP : "asClock" SHIFT-LEFT-OP : "shl" SHIFT-RIGHT-OP : "shr" + DYN-SHIFT-LEFT-OP : "dshl" + DYN-SHIFT-RIGHT-OP : "dshr" CONVERT-OP : "cvt" NEG-OP : "neg" - BIT-NOT-OP : "not" - BIT-AND-OP : "and" - BIT-OR-OP : "or" - BIT-XOR-OP : "xor" - BIT-AND-REDUCE-OP : "andr" - BIT-OR-REDUCE-OP : "orr" - BIT-XOR-REDUCE-OP : "xorr" + NOT-OP : "not" + AND-OP : "and" + OR-OP : "or" + XOR-OP : "xor" + AND-REDUCE-OP : "andr" + OR-REDUCE-OP : "orr" + XOR-REDUCE-OP : "xorr" CONCAT-OP : "cat" - BIT-SELECT-OP : "bit" BITS-SELECT-OP : "bits" + HEAD-OP : "head" + TAIL-OP : "tail" defmethod print (o:OutputStream, e:Expression) : match(e) : @@ -420,17 +415,18 @@ defmethod print (o:OutputStream, c:Stmt) : (c:DefWire) : print-all(o,["wire " name(c) " : " type(c)]) (c:DefRegister) : - print-all(o,["reg " name(c) " : " type(c) ", " clock(c) ", " reset(c) ", " init(c)]) + print-all(o,["reg " name(c) " : " type(c) ", " clock(c) " with :"]) + print-all(io,["\nreset => (" reset(c) ", " init(c) ")"]) (c:DefMemory) : print-all(o,["mem " name(c) " : "]) print-debug(o,c) - print-all(io,["\ndata-type: " data-type(c)]) - print-all(io,["\ndepth: " depth(c)]) - print-all(io,["\nwrite-latency: " write-latency(c)]) - print-all(io,["\nread-latency: " read-latency(c)]) - for r in readers(c) do : print-all(io,["\nreader: " r]) - for w in writers(c) do : print-all(io,["\nwriter: " w]) - for rw in readwriters(c) do : print-all(io,["\nread-writer: " rw]) + print-all(io,["\ndata-type => " data-type(c)]) + print-all(io,["\ndepth => " depth(c)]) + print-all(io,["\nwrite-latency => " write-latency(c)]) + print-all(io,["\nread-latency => " read-latency(c)]) + for r in readers(c) do : print-all(io,["\nreader => " r]) + for w in writers(c) do : print-all(io,["\nwriter => " w]) + for rw in readwriters(c) do : print-all(io,["\nreadwriter => " rw]) (c:DefInstance) : print-all(o,["inst " name(c) " of " module(c)]) (c:DefNode) : diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 68922044..503e16c4 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -322,6 +322,8 @@ defmethod map (f: Type -> Type, e: WSubAccess) : defmethod map (f: Type -> Type, s: WDefInstance) : WDefInstance(info(s),name(s),module(s),f(type(s))) +defmethod map (f: Symbol -> Symbol, s: WDefInstance) : + WDefInstance(info(s),f(name(s)),module(s),type(s)) ;================ WIDTH LIBRARY ==================== @@ -336,6 +338,8 @@ public defstruct MinusWidth <: Width : arg2 : Width public defstruct MaxWidth <: Width : args : List<Width> +public defstruct MinWidth <: Width : + args : List<Width> public defstruct ExpWidth <: Width : arg1 : Width val width-name-hash = HashTable<Symbol,Int>(symbol-hash) @@ -344,6 +348,7 @@ public defmulti map<?T> (f: Width -> Width, w:?T&Width) -> T defmethod map (f: Width -> Width, w:Width) -> Width : match(w) : (w:MaxWidth) : MaxWidth(map(f,args(w))) + (w:MinWidth) : MinWidth(map(f,args(w))) (w:PlusWidth) : PlusWidth(f(arg1(w)),f(arg2(w))) (w:MinusWidth) : MinusWidth(f(arg1(w)),f(arg2(w))) (w:ExpWidth) : ExpWidth(f(arg1(w))) @@ -353,6 +358,8 @@ public defmethod print (o:OutputStream, w:VarWidth) : print(o,name(w)) public defmethod print (o:OutputStream, w:MaxWidth) : print-all(o,["max" args(w)]) +public defmethod print (o:OutputStream, w:MinWidth) : + print-all(o,["min" args(w)]) public defmethod print (o:OutputStream, w:PlusWidth) : print-all(o,[ "(" arg1(w) " + " arg2(w) ")"]) public defmethod print (o:OutputStream, w:MinusWidth) : @@ -376,6 +383,13 @@ defmethod equal? (w1:Width,w2:Width) -> True|False : for w in args(w1) do : if not contains?(args(w2),w) : ret(false) ret(true) + (w1:MinWidth,w2:MinWidth) : + label<True|False> ret : + if not length(args(w1)) == length(args(w2)) : ret(false) + else : + for w in args(w1) do : + if not contains?(args(w2),w) : ret(false) + ret(true) (w1:IntWidth,w2:IntWidth) : width(w1) == width(w2) (w1:PlusWidth,w2:PlusWidth) : (arg1(w1) == arg1(w2) and arg2(w1) == arg2(w2)) or (arg1(w1) == arg2(w2) and arg2(w1) == arg1(w2)) @@ -1408,6 +1422,14 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Width> : h defn simplify (w:Width) -> Width : match(map(simplify,w)) : + (w:MinWidth) : + val v = Vector<Width>() + for w* in args(w) do : + match(w*) : + (w*:MinWidth) : + for x in args(w*) do : add(v,x) + (w*) : add(v,w*) + MinWidth(unique(v)) (w:MaxWidth) : val v = Vector<Width>() for w* in args(w) do : @@ -1549,6 +1571,9 @@ defn reduce-var-widths (c:Circuit,h:HashTable<Symbol,Width>) -> Circuit : defn max (a:Long,b:Long) -> Long : if a >= b : a else : b + defn min (a:Long,b:Long) -> Long : + if a >= b : b + else : a defn solve (w:Width) -> False|Long : match(w) : (w:VarWidth) : @@ -1558,6 +1583,7 @@ defn reduce-var-widths (c:Circuit,h:HashTable<Symbol,Width>) -> Circuit : (w:False) : false (w) : solve(w as Width) (w:MaxWidth) : apply-l(map(solve,args(w)),max) + (w:MinWidth) : apply-l(map(solve,args(w)),min) (w:PlusWidth) : apply(solve(arg1(w)),solve(arg2(w)),{plus(_,_)}) (w:MinusWidth) : apply(solve(arg1(w)),solve(arg2(w)),{minus(_,_)}) (w:ExpWidth) : apply(to-long(2),solve(arg1(w)),{minus(pow(_,_),to-long(1))}) @@ -1741,7 +1767,54 @@ defn resolve (c:Circuit) -> Circuit : ; val top = (for m in modules(c) find : name(m) == main(c)) as InModule ; Circuit(info(c),list(InModule(info(top),name(top),ports(top),inline-inst(body(top)))),main(c)) +;;================= Verilog Wrap ======================== + +; --------- Utils -------------- + +;---------- Pass --------------- +;; Intended to only work on low firrtl +public defstruct VerilogWrap <: Pass +public defmethod pass (b:VerilogWrap) -> (Circuit -> Circuit) : v-wrap +public defmethod name (b:VerilogWrap) -> String : "Verilog Wrap" +public defmethod short-name (b:VerilogWrap) -> String : "v-wrap" + +public definterface WPrimOp <: PrimOp +val ADDW-OP = new WPrimOp +val SUBW-OP = new WPrimOp + +defmethod print (o:OutputStream,op:WPrimOp) : + print{o, _} $ switch {op == _} : + ADDW-OP : "addw" + SUBW-OP : "subw" + +defn v-wrap-e (e:Expression) -> Expression : + match(map(v-wrap-e,e)) : + (e:DoPrim) : + defn a0 () : args(e)[0] + if op(e) == TAIL-OP : + match(a0()) : + (e0:DoPrim) : + if op(e0) == ADD-OP : + DoPrim(ADDW-OP,args(e0),list(),type(e)) + else if op(e0) == SUB-OP : + DoPrim(SUBW-OP,args(e0),list(),type(e)) + else : e + (e0) : e + else : e + (e) : e +defn v-wrap-s (s:Stmt) -> Stmt : + map{v-wrap-e,_} $ map(v-wrap-s,s) +defn v-wrap (c:Circuit) -> Circuit : + val modules* = for m in modules(c) map : + match(m) : + (m:InModule) : + mname = name(m) + InModule(info(m),name(m),ports(m),v-wrap-s(body(m))) + (m:ExModule) : m + Circuit(info(c),modules*,main(c)) + ;;================= Split Expressions ======================== + ;; Intended to only work on low firrtl public defstruct SplitExp <: Pass public defmethod pass (b:SplitExp) -> (Circuit -> Circuit) : split-exp @@ -1763,7 +1836,7 @@ defn split-exp (m:InModule) -> InModule : add(v,DefNode(info(s),n,e)) WRef(n,type(e),kind(e),gender(e)) defn split-exp-e (e:Expression,i:Int) -> Expression : - match(map(split-exp-e{_,i + 1},e)) : + match(map(split-exp-e{_,i + 1},e)) : (e:DoPrim) : if i > 0 : split(e) else : e @@ -2015,13 +2088,11 @@ defn const-prop-e (e:Expression) -> Expression : (x:UIntValue) : val b = bits(value(x),consts(e)[0] + 1,consts(e)[1]) UIntValue(b,width(type(e) as UIntType)) - (x) : e - BIT-SELECT-OP : - match(args(e)[0]) : - (x:UIntValue) : - val i = bit(value(x),consts(e)[0]) - UIntValue(i,width(type(e) as UIntType)) - (x) : e + (x) : + if long!(type(e)) == long!(type(x)) : + if type(x) typeof UIntType : x + else : DoPrim(AS-UINT-OP,list(x),list(),type(e)) + else : e else : e (e) : e @@ -2457,6 +2528,10 @@ defn op-stream (doprim:DoPrim) -> Streamable : match(type(doprim)) : (t:UIntType) : e (t:SIntType) : ["$signed(" e ")"] + defn cast-as (e:Expression) -> ? : + match(type(e)) : + (t:UIntType) : e + (t:SIntType) : ["$signed(" e ")"] defn a0 () -> Expression : args(doprim)[0] defn a1 () -> Expression : args(doprim)[1] defn a2 () -> Expression : args(doprim)[2] @@ -2465,23 +2540,18 @@ defn op-stream (doprim:DoPrim) -> Streamable : switch {_ == op(doprim)} : ADD-OP : [cast-if(a0()) " + " cast-if(a1())] + ADDW-OP : [cast-if(a0()) " + " cast-if(a1())] SUB-OP : [cast-if(a0()) " - " cast-if(a1())] + SUBW-OP : [cast-if(a0()) " - " cast-if(a1())] MUL-OP : [cast-if(a0()) " * " cast-if(a1()) ] DIV-OP : [cast-if(a0()) " / " cast-if(a1()) ] - MOD-OP : [cast-if(a0()) " % " cast-if(a1()) ] - QUO-OP : [cast-if(a0()) " / " cast-if(a1()) ] REM-OP : [cast-if(a0()) " % " cast-if(a1()) ] - ADD-WRAP-OP : [cast-if(a0()), " + " cast-if(a1())] - SUB-WRAP-OP : [cast-if(a0()), " - " cast-if(a1())] LESS-OP : [cast-if(a0()) " < " cast-if(a1())] LESS-EQ-OP : [cast-if(a0()) " <= " cast-if(a1())] GREATER-OP : [cast-if(a0()) " > " cast-if(a1())] GREATER-EQ-OP : [cast-if(a0()) " >= " cast-if(a1())] - NEQUIV-OP : [cast-if(a0()) " != " cast-if(a1())] - EQUIV-OP : [cast-if(a0()) " == " cast-if(a1())] - NEQUAL-OP : [cast-if(a0()) " != " cast-if(a1())] EQUAL-OP : [cast-if(a0()) " == " cast-if(a1())] - ;MUX-OP : [a0() " ? " cast(a1()) " : " cast(a2())] + NEQUAL-OP : [cast-if(a0()) " != " cast-if(a1())] PAD-OP : val w = long!(type(a0())) val diff = (to-long(c0()) - w) @@ -2491,6 +2561,7 @@ defn op-stream (doprim:DoPrim) -> Streamable : (t) : ["{{" diff "'d0 }, " a0() " }"] AS-UINT-OP : ["$unsigned(" a0() ")"] AS-SINT-OP : ["$signed(" a0() ")"] + AS-CLOCK-OP : ["$unsigned(" a0() ")"] DYN-SHIFT-LEFT-OP : [cast(a0()) " << " a1()] DYN-SHIFT-RIGHT-OP : match(type(doprim)) : @@ -2503,28 +2574,38 @@ defn op-stream (doprim:DoPrim) -> Streamable : match(type(a0())) : (t:UIntType) : ["{1'b0," cast(a0()) "}"] (t:SIntType) : [cast(a0())] - BIT-NOT-OP : ["~ " cast(a0())] - BIT-AND-OP : [cast(a0()) " & " cast(a1())] - BIT-OR-OP : [cast(a0()) " | " cast(a1())] - BIT-XOR-OP : [cast(a0()) " ^ " cast(a1())] - CONCAT-OP : ["{" cast(a0()) "," cast(a1()) "}"] - BIT-SELECT-OP : [a0() "[" c0() "]"] - BITS-SELECT-OP : [a0() "[" c0() ":" c1() "]"] - BIT-AND-REDUCE-OP : + NOT-OP : ["~ " a0()] + AND-OP : [cast-as(a0()) " & " cast-as(a1())] + OR-OP : [cast-as(a0()) " | " cast-as(a1())] + XOR-OP : [cast-as(a0()) " ^ " cast-as(a1())] + AND-REDUCE-OP : val v = Vector<Streamable>() for b in 0 to to-int(long!(type(doprim))) do : add(v,[cast(a0()) "[" b "]"]) join(v," & ") - BIT-OR-REDUCE-OP : + OR-REDUCE-OP : val v = Vector<Streamable>() for b in 0 to to-int(long!(type(doprim))) do : add(v,[cast(a0() ) "[" b "]"]) join(v," | ") - BIT-XOR-REDUCE-OP : + XOR-REDUCE-OP : val v = Vector<Streamable>() for b in 0 to to-int(long!(type(doprim))) do : add(v,[cast(a0() ) "[" b "]"]) join(v," ^ ") + CONCAT-OP : ["{" cast(a0()) "," cast(a1()) "}"] + BITS-SELECT-OP : + if c0() == c1() : [a0() "[" c0() "]"] + else : [a0() "[" c0() ":" c1() "]"] + HEAD-OP : + val w = long!(type(a0())) + val high = w - to-long(1) + val low = w - to-long(c0()) + [a0() "[" high ":" low "]"] + TAIL-OP : + val w = long!(type(a0())) + val low = w - to-long(c0()) - to-long(1) + [a0() "[" low ":" 0 "]"] defn emit-verilog (m:InModule) -> Module : mname = name(m) @@ -2723,7 +2804,7 @@ defn emit-verilog (m:InModule) -> Module : update(mem-port,data*,clk,AND(en*,mask*)) for rw in readwriters(s) do : - val rmode = mem-exp(rw,`rmode) + val wmode = mem-exp(rw,`wmode) val rdata = mem-exp(rw,`rdata) val data = mem-exp(rw,`data) val mask = mem-exp(rw,`mask) @@ -2731,7 +2812,7 @@ defn emit-verilog (m:InModule) -> Module : val en = mem-exp(rw,`en) val clk = mem-exp(rw,`clk) - declare(`wire,lowered-name(rmode),type(rmode)) + declare(`wire,lowered-name(wmode),type(wmode)) declare(`wire,lowered-name(rdata),type(rdata)) declare(`wire,lowered-name(data),type(data)) declare(`wire,lowered-name(mask),type(mask)) @@ -2746,13 +2827,13 @@ defn emit-verilog (m:InModule) -> Module : assign(addr,netlist[addr]) assign(mask,netlist[mask]) assign(en,netlist[en]) - assign(rmode,netlist[rmode]) + assign(wmode,netlist[wmode]) ; Delay new signals by latency val raddr* = delay(addr,read-latency(s),clk) val waddr* = delay(addr,write-latency(s) - 1,clk) val en* = delay(en,write-latency(s) - 1,clk) - val rmod* = delay(rmode,write-latency(s) - 1,clk) + val rmod* = delay(wmode,write-latency(s) - 1,clk) val data* = delay(data,write-latency(s) - 1,clk) val mask* = delay(mask,write-latency(s) - 1,clk) @@ -2761,7 +2842,7 @@ defn emit-verilog (m:InModule) -> Module : val rmem-port = WSubAccess(mem,raddr*,UnknownType(),UNKNOWN-GENDER) assign(rdata,rmem-port) val wmem-port = WSubAccess(mem,waddr*,UnknownType(),UNKNOWN-GENDER) - update(wmem-port,data*,clk,AND(AND(en*,mask*),NOT(rmode))) + update(wmem-port,data*,clk,AND(AND(en*,mask*),wmode)) (s:Begin) : map(build-streams,s) s diff --git a/src/main/stanza/primop.stanza b/src/main/stanza/primop.stanza index 4b8d0cbc..3d0b06a4 100644 --- a/src/main/stanza/primop.stanza +++ b/src/main/stanza/primop.stanza @@ -12,6 +12,7 @@ public defn set-primop-type (e:DoPrim) -> DoPrim : 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) + defn MIN (w1:Width,w2:Width) -> Width : MinWidth(list(w1,w2)) val o = op(e) val a = args(e) val c = consts(e) @@ -38,20 +39,6 @@ public defn set-primop-type (e:DoPrim) -> DoPrim : (t1:SIntType, t2:UIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE)) (t1:SIntType, t2:SIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE)) (t1, t2) : UnknownType() - ADD-WRAP-OP : DoPrim{o,a,c,_} $ - match(t1(),t2()) : - (t1:UIntType, t2:UIntType) : UIntType(MAX(w1(),w2())) - (t1:UIntType, t2:SIntType) : SIntType(MAX(w1(),w2())) - (t1:SIntType, t2:UIntType) : SIntType(MAX(w1(),w2())) - (t1:SIntType, t2:SIntType) : SIntType(MAX(w1(),w2())) - (t1, t2) : UnknownType() - SUB-WRAP-OP : DoPrim{o,a,c,_} $ - match(t1(),t2()) : - (t1:UIntType, t2:UIntType) : UIntType(MAX(w1(),w2())) - (t1:UIntType, t2:SIntType) : SIntType(MAX(w1(),w2())) - (t1:SIntType, t2:UIntType) : SIntType(MAX(w1(),w2())) - (t1:SIntType, t2:SIntType) : SIntType(MAX(w1(),w2())) - (t1, t2) : UnknownType() MUL-OP : DoPrim{o,a,c,_} $ match(t1(),t2()) : (t1:UIntType, t2:UIntType) : UIntType(PLUS(w1(),w2())) @@ -62,58 +49,63 @@ public defn set-primop-type (e:DoPrim) -> DoPrim : DIV-OP : DoPrim{o,a,c,_} $ match(t1(),t2()) : (t1:UIntType, t2:UIntType) : UIntType(w1()) - (t1:UIntType, t2:SIntType) : SIntType(PLUS(w1(),w2())) + (t1:UIntType, t2:SIntType) : SIntType(PLUS(w1(),ONE)) (t1:SIntType, t2:UIntType) : SIntType(w1()) - (t1:SIntType, t2:SIntType) : SIntType(PLUS(w1(),w2())) + (t1:SIntType, t2:SIntType) : SIntType(PLUS(w1(),ONE)) (t1, t2) : UnknownType() - MOD-OP : DoPrim{o,a,c,_} $ + REM-OP : DoPrim{o,a,c,_} $ match(t1(),t2()) : - (t1:UIntType, t2:UIntType) : UIntType(w2()) - (t1:UIntType, t2:SIntType) : UIntType(w2()) - (t1:SIntType, t2:UIntType) : SIntType(PLUS(w2(),ONE)) - (t1:SIntType, t2:SIntType) : SIntType(w2()) + (t1:UIntType, t2:UIntType) : UIntType(MIN(w1(),w2())) + (t1:UIntType, t2:SIntType) : UIntType(MIN(w1(),w2())) + (t1:SIntType, t2:UIntType) : SIntType(MIN(w1(),PLUS(w2(),ONE))) + (t1:SIntType, t2:SIntType) : SIntType(MIN(w1(),w2())) (t1, t2) : UnknownType() - QUO-OP : DoPrim{o,a,c,_} $ + LESS-OP : DoPrim{o,a,c,_} $ match(t1(),t2()) : - (t1:UIntType, t2:UIntType) : UIntType(PLUS(w1(),ONE)) - (t1:UIntType, t2:SIntType) : SIntType(w1()) - (t1:SIntType, t2:UIntType) : SIntType(PLUS(w1(),ONE)) - (t1:SIntType, t2:SIntType) : SIntType(w1()) + (t1:UIntType|SIntType, t2:UIntType|SIntType) : BoolType() (t1, t2) : UnknownType() - REM-OP : DoPrim{o,a,c,_} $ + LESS-EQ-OP : DoPrim{o,a,c,_} $ match(t1(),t2()) : - (t1:UIntType, t2:UIntType) : UIntType(w2()) - (t1:UIntType, t2:SIntType) : SIntType(w2()) - (t1:SIntType, t2:UIntType) : UIntType(PLUS(w2(),ONE)) - (t1:SIntType, t2:SIntType) : SIntType(w2()) + (t1:UIntType|SIntType, t2:UIntType|SIntType) : BoolType() + (t1, t2) : UnknownType() + GREATER-OP : DoPrim{o,a,c,_} $ + match(t1(),t2()) : + (t1:UIntType|SIntType, t2:UIntType|SIntType) : BoolType() + (t1, t2) : UnknownType() + GREATER-EQ-OP : DoPrim{o,a,c,_} $ + match(t1(),t2()) : + (t1:UIntType|SIntType, t2:UIntType|SIntType) : BoolType() + (t1, t2) : UnknownType() + EQUAL-OP : DoPrim{o,a,c,_} $ + match(t1(),t2()) : + (t1:UIntType|SIntType, t2:UIntType|SIntType) : BoolType() + (t1, t2) : UnknownType() + NEQUAL-OP : DoPrim{o,a,c,_} $ + match(t1(),t2()) : + (t1:UIntType|SIntType, t2:UIntType|SIntType) : BoolType() (t1, t2) : UnknownType() - LESS-OP : DoPrim(o,a,c,BoolType()) - LESS-EQ-OP : DoPrim(o,a,c,BoolType()) - GREATER-OP : DoPrim(o,a,c,BoolType()) - GREATER-EQ-OP : DoPrim(o,a,c,BoolType()) - EQUAL-OP : DoPrim(o,a,c,BoolType()) - NEQUAL-OP : DoPrim(o,a,c,BoolType()) - EQUIV-OP : DoPrim(o,a,c,BoolType()) - NEQUIV-OP : DoPrim(o,a,c,BoolType()) - ;MUX-OP : DoPrim{o,a,c,_} $ - ; match(t2(),t3()) : - ; (t2:UIntType, t3:UIntType) : UIntType(MAX(w2(),w3())) - ; (t2:SIntType, t3:SIntType) : SIntType(MAX(w2(),w3())) - ; (t2, t3) : UnknownType() PAD-OP : DoPrim{o,a,c,_} $ match(t1()) : - (t1:UIntType) : UIntType(c1()) - (t1:SIntType) : SIntType(c1()) + (t1:UIntType) : UIntType(MAX(w1(),c1())) + (t1:SIntType) : SIntType(MAX(w1(),c1())) (t1) : UnknownType() AS-UINT-OP : DoPrim{o,a,c,_} $ match(t1()) : (t1:UIntType) : UIntType(w1()) (t1:SIntType) : UIntType(w1()) + (t1:ClockType) : UIntType(ONE) (t1) : UnknownType() AS-SINT-OP : DoPrim{o,a,c,_} $ match(t1()) : (t1:UIntType) : SIntType(w1()) (t1:SIntType) : SIntType(w1()) + (t1:ClockType) : SIntType(ONE) + (t1) : UnknownType() + AS-CLOCK-OP : DoPrim{o,a,c,_} $ + match(t1()) : + (t1:UIntType) : ClockType() + (t1:SIntType) : ClockType() + (t1:ClockType) : ClockType() (t1) : UnknownType() SHIFT-LEFT-OP : DoPrim{o,a,c,_} $ match(t1()) : @@ -143,30 +135,52 @@ public defn set-primop-type (e:DoPrim) -> DoPrim : NEG-OP : DoPrim{o,a,c,_} $ match(t1()) : (t1:UIntType) : SIntType(PLUS(w1(),ONE)) - (t1:SIntType) : SIntType(w1()) + (t1:SIntType) : SIntType(PLUS(w1(),ONE)) + (t1) : UnknownType() + NOT-OP : DoPrim{o,a,c,_} $ + match(t1()) : + (t1:UIntType|SIntType) : UIntType(w1()) + (t1) : UnknownType() + AND-OP : DoPrim{o,a,c,_} $ + match(t1(),t2()) : + (t1:UIntType|SIntType, t2:UIntType|SIntType) : UIntType(MAX(w1(),w2())) + (t1,t2) : UnknownType() + OR-OP : DoPrim{o,a,c,_} $ + match(t1(),t2()) : + (t1:UIntType|SIntType, t2:UIntType|SIntType) : UIntType(MAX(w1(),w2())) + (t1,t2) : UnknownType() + XOR-OP : DoPrim{o,a,c,_} $ + match(t1(),t2()) : + (t1:UIntType|SIntType, t2:UIntType|SIntType) : UIntType(MAX(w1(),w2())) + (t1,t2) : UnknownType() + AND-REDUCE-OP : DoPrim{o,a,c,_} $ + match(t1()) : + (t1:UIntType|SIntType) : BoolType() + (t1) : UnknownType() + OR-REDUCE-OP : DoPrim{o,a,c,_} $ + match(t1()) : + (t1:UIntType|SIntType) : BoolType() + (t1) : UnknownType() + XOR-REDUCE-OP : DoPrim{o,a,c,_} $ + match(t1()) : + (t1:UIntType|SIntType) : BoolType() (t1) : UnknownType() - BIT-NOT-OP : DoPrim(o,a,c,t1()) - BIT-AND-OP : DoPrim{o,a,c,_} $ + CONCAT-OP : DoPrim{o,a,c,_} $ + match(t1(),t2()) : + (t1:UIntType|SIntType, t2:UIntType|SIntType) : UIntType(PLUS(w1(),w2())) + (t1, t2) : UnknownType() + BITS-SELECT-OP : DoPrim{o,a,c,_} $ match(t1()) : - (t1:UIntType) : UIntType(MAX(w1(),w2())) - (t1:SIntType) : SIntType(MAX(w1(),w2())) + (t1:UIntType|SIntType) : UIntType(PLUS(MINUS(c1(),c2()),ONE)) (t1) : UnknownType() - BIT-OR-OP : DoPrim{o,a,c,_} $ + HEAD-OP : DoPrim{o,a,c,_} $ match(t1()) : - (t1:UIntType) : UIntType(MAX(w1(),w2())) - (t1:SIntType) : SIntType(MAX(w1(),w2())) + (t1:UIntType|SIntType) : UIntType(c1()) (t1) : UnknownType() - BIT-XOR-OP : DoPrim{o,a,c,_} $ + TAIL-OP : DoPrim{o,a,c,_} $ match(t1()) : - (t1:UIntType) : UIntType(MAX(w1(),w2())) - (t1:SIntType) : SIntType(MAX(w1(),w2())) + (t1:UIntType|SIntType) : UIntType(MINUS(w1(),c1())) (t1) : UnknownType() - BIT-AND-REDUCE-OP : DoPrim(o,a,c,BoolType()) - BIT-OR-REDUCE-OP : DoPrim(o,a,c,BoolType()) - BIT-XOR-REDUCE-OP : DoPrim(o,a,c,BoolType()) - CONCAT-OP : DoPrim(o,a,c,UIntType(PLUS(w1(),w2()))) - BIT-SELECT-OP : DoPrim(o,a,c,BoolType()) - BITS-SELECT-OP : DoPrim(o,a,c,UIntType(PLUS(MINUS(c1(),c2()),ONE))) ;public defn primop-gen-constraints (e:DoPrim,v:Vector<WGeq>) -> Type : ; defn get-max (i0:Int,i1:Int) -> Width : get-max(list(i0,i1)) @@ -185,7 +199,7 @@ public defn set-primop-type (e:DoPrim) -> DoPrim : ; (t0:UIntType,t1:SIntType) : PlusWidth(width!(args(e)[0]),IntWidth(1)) ; (t0:SIntType,t1:SIntType) : PlusWidth(width!(args(e)[0]),IntWidth(1)) ; (t0,t1) : width!(args(e)[0]) -; MOD-OP : +; REM-OP : ; match(type(args(e)[0]),type(args(e)[1])) : ; (t0:SIntType,t1:UIntType) : PlusWidth(width!(args(e)[1]),IntWidth(1)) ; (t0,t1) : width!(args(e)[1]) diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza index 21931dd9..9040a8bd 100644 --- a/src/main/stanza/verilog.stanza +++ b/src/main/stanza/verilog.stanza @@ -96,7 +96,7 @@ defn emit (e:Expression) -> String : SUB-OP : [emit-signed-if-any(args(e)[0],args(e)) " - " emit-signed-if-any(args(e)[1],args(e))] MUL-OP : [emit-signed-if-any(args(e)[0],args(e)) " * " emit-signed-if-any(args(e)[1],args(e)) ] DIV-OP : [emit-signed-if-any(args(e)[0],args(e)) " / " emit-signed-if-any(args(e)[1],args(e)) ] - MOD-OP : [emit-signed-if-any(args(e)[0],args(e)) " % " emit-signed-if-any(args(e)[1],args(e)) ] + REM-OP : [emit-signed-if-any(args(e)[0],args(e)) " % " emit-signed-if-any(args(e)[1],args(e)) ] QUO-OP : [emit-signed-if-any(args(e)[0],args(e)) " / " emit-signed-if-any(args(e)[1],args(e)) ] REM-OP : [emit-signed-if-any(args(e)[0],args(e)) " % " emit-signed-if-any(args(e)[1],args(e)) ] ADD-WRAP-OP : [emit-signed-if-any(args(e)[0],args(e)), " + " emit-signed-if-any(args(e)[1],args(e))] |
