aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/chirrtl.stanza45
-rw-r--r--src/main/stanza/compilers.stanza8
-rw-r--r--src/main/stanza/errors.stanza98
-rw-r--r--src/main/stanza/firrtl-ir.stanza29
-rw-r--r--src/main/stanza/flo.stanza2
-rw-r--r--src/main/stanza/ir-parser.stanza37
-rw-r--r--src/main/stanza/ir-utils.stanza58
-rw-r--r--src/main/stanza/passes.stanza143
-rw-r--r--src/main/stanza/primop.stanza142
-rw-r--r--src/main/stanza/verilog.stanza2
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))]