aboutsummaryrefslogtreecommitdiff
path: root/src/main/stanza/verilog.stanza
diff options
context:
space:
mode:
authorazidar2016-02-09 18:53:28 -0800
committerazidar2016-02-09 18:57:08 -0800
commit4160ffa5c86ff7f4d5534dec3624b7127263b782 (patch)
treed69dfe008857f7c9d66f8c7647a4f1eaeb02fe76 /src/main/stanza/verilog.stanza
parentbb5f68948c6d75d1f02c614f3e0ae4ef9bc6e689 (diff)
Added license to FIRRTL files
Diffstat (limited to 'src/main/stanza/verilog.stanza')
-rw-r--r--src/main/stanza/verilog.stanza402
1 files changed, 0 insertions, 402 deletions
diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza
deleted file mode 100644
index 9040a8bd..00000000
--- a/src/main/stanza/verilog.stanza
+++ /dev/null
@@ -1,402 +0,0 @@
-defpackage firrtl/verilog :
- import core
- import verse
- import firrtl/ir-utils
- import firrtl/ir2
-
-defn width! (w:Width) -> Long :
- match(w) :
- (w:IntWidth) : width(w)
- (w) : error("Non-supported width type.")
-
-defn width! (t:Type) -> Long :
- match(t) :
- (t:UIntType) : width!(width(t))
- (t:SIntType) : width!(width(t))
- (t) : error("Non-supported type.")
-
-defn emit (w:Width) -> String :
- match(w) :
- (w:IntWidth) :
- if width(w) >= to-long(1) : string-join $ ["[" width(w) - to-long(1) ":0]"] ;TODO check if need to special case 0 or 1 width wires
- else : ""
-
- (w) : error("Non-supported width type.")
-
-defn remove-subfield-s (s:Stmt) -> Stmt :
- defn remove-subfield-e (e:Expression) -> Expression :
- match(map(remove-subfield-e,e)) :
- (e:SubField) :
- Ref(to-symbol $ string-join $ [emit(exp(e)) bundle-expand-delin name(e)],type(e))
- (e) : e
- map{remove-subfield-e,_ } $ map(remove-subfield-s,s)
-
-defn get-width (t:Type) -> String :
- match(t) :
- (t:UIntType) : emit(width(t))
- (t:SIntType) : emit(width(t))
- (t:ClockType) : emit(IntWidth(1))
- (t) : error("Non-supported type.")
-
-defn get-name (e:Expression) -> Symbol :
- match(e) :
- (e:Ref) : name(e)
- (e:SubField) : error("Shouldn't be here")
- (e) : error("Shouldn't be here")
-
-defn escape (s:String) -> String :
- val s* = Vector<String>()
- add(s*,"\"");"
- var percent = false
- for c in s do :
- if c == '\n' :
- add(s*,"\\n")
- else :
- if c == 'x' and percent :
- add(s*,"h")
- else : add(s*,to-string(c))
- percent = c == '%'
- add(s*,"\"");"
- string-join(s*)
-;============ Verilog Backend =============
-
-defn emit-as-type (e:Expression,t:Type) -> String :
- match(t) :
- (t:UIntType) : emit(e)
- (t:SIntType) : string-join(["$signed(" emit(e) ")"])
-
-defn emit-signed-if-any (e:Expression,ls:List<Expression>) -> String :
- var signed? = false
- for x in ls do :
- if type(x) typeof SIntType : signed? = true
- if not signed? : emit(e)
- else :
- match(type(e)) :
- (t:SIntType) : string-join(["$signed(" emit(e) ")"])
- (t:UIntType) : string-join(["$signed({1'b0," emit(e) "})"])
-
-defn emit (e:Expression) -> String :
- match(e) :
- (e:Ref) : to-string $ name(e)
- (e:UIntValue) :
- val str = to-string(value(e))
- val out = substring(str,1,length(str) - 1)
- string-join $ [width!(type(e)) "'" out]
- (e:SIntValue) : ;string-join $ [width!(type(e)) "'s" value(e)]
- val str = to-string(value(e))
- val out = substring(str,1,length(str) - 1)
- string-join $ [width!(type(e)) "'s" out]
- (e:SubField) : error(string-join(["Non-supported expression: " to-string(e)]))
- (e:SubIndex) : error(string-join(["Non-supported expression: " to-string(e)]))
- (e:DoPrim) :
- ;val sargs = map(emit-as-type{_,type(e)},args(e))
- ;val xargs = map(emit-signed-if-any{_,args(e)},args(e))
- string-join $ switch {_ == op(e)} :
- ADD-OP : [emit-signed-if-any(args(e)[0],args(e)) " + " emit-signed-if-any(args(e)[1],args(e))]
- 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)) ]
- 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))]
- SUB-WRAP-OP : [emit-signed-if-any(args(e)[0],args(e)), " - " emit-signed-if-any(args(e)[1],args(e))]
- LESS-OP : [emit-signed-if-any(args(e)[0],args(e)) " < " emit-signed-if-any(args(e)[1],args(e))]
- LESS-EQ-OP : [emit-signed-if-any(args(e)[0],args(e)) " <= " emit-signed-if-any(args(e)[1],args(e))]
- GREATER-OP : [emit-signed-if-any(args(e)[0],args(e)) " > " emit-signed-if-any(args(e)[1],args(e))]
- GREATER-EQ-OP : [emit-signed-if-any(args(e)[0],args(e)) " >= " emit-signed-if-any(args(e)[1],args(e))]
- NEQUIV-OP : [emit-signed-if-any(args(e)[0],args(e)) " != " emit-signed-if-any(args(e)[1],args(e))]
- EQUIV-OP : [emit-signed-if-any(args(e)[0],args(e)) " == " emit-signed-if-any(args(e)[1],args(e))]
- NEQUAL-OP : [emit-signed-if-any(args(e)[0],args(e)) " != " emit-signed-if-any(args(e)[1],args(e))]
- EQUAL-OP : [emit-signed-if-any(args(e)[0],args(e)) " == " emit-signed-if-any(args(e)[1],args(e))]
- MUX-OP :
- val en = emit(args(e)[0])
- [en " ? " emit-as-type(args(e)[1],type(e)) " : " emit-as-type(args(e)[2],type(e))]
- PAD-OP :
- val x = args(e)[0]
- val w = width!(type(x))
- val diff = (to-long(consts(e)[0]) - w)
- if w == to-long(0) : [ emit(x) ]
- else :
- if type(e) typeof SIntType : ["{{" diff "{" emit(x) "[" w - to-long(1) "]}}, " emit(x) " }"]
- else : ["{{" diff "'d0 }, " emit(x) " }"]
- AS-UINT-OP :
- ["$unsigned(" emit(args(e)[0]) ")"]
- AS-SINT-OP :
- ["$signed(" emit(args(e)[0]) ")"]
- DYN-SHIFT-LEFT-OP : [emit-as-type(args(e)[0],type(e)) " << " emit(args(e)[1])]
- DYN-SHIFT-RIGHT-OP :
- if type(e) typeof SIntType : [emit-as-type(args(e)[0],type(e)) " >>> " emit(args(e)[1])]
- else : [emit-as-type(args(e)[0],type(e)) " >> " emit(args(e)[1])]
- SHIFT-LEFT-OP : [emit-as-type(args(e)[0],type(e)) " << " consts(e)[0]]
- SHIFT-RIGHT-OP : [emit(args(e)[0]) "[" width!(type(args(e)[0])) - to-long(1) ":" consts(e)[0] "]"]
- ;if type(e) typeof SIntType : [emit-as-type(args(e)[0],type(e)) " >>> " consts(e)[0]]
- ;else : [emit-as-type(args(e)[0],type(e)) " >> " consts(e)[0]]
- NEG-OP : ["-{" emit-as-type(args(e)[0],type(e)) "}"]
- CONVERT-OP :
- match(type(args(e)[0])) :
- (t:UIntType) : ["{1'b0," emit-as-type(args(e)[0],type(e)) "}"]
- (t:SIntType) : [emit-as-type(args(e)[0],type(e))]
- BIT-NOT-OP : ["~ " emit-as-type(args(e)[0],type(e))]
- BIT-AND-OP : [emit-as-type(args(e)[0],type(e)) " & " emit-as-type(args(e)[1],type(e))]
- BIT-OR-OP : [emit-as-type(args(e)[0],type(e)) " | " emit-as-type(args(e)[1],type(e))]
- BIT-XOR-OP : [emit-as-type(args(e)[0],type(e)) " ^ " emit-as-type(args(e)[1],type(e))]
- CONCAT-OP : ["{" emit-as-type(args(e)[0],type(e)) "," emit-as-type(args(e)[1],type(e)) "}"]
- BIT-SELECT-OP : [emit(args(e)[0]) "[" consts(e)[0] "]"]
- BITS-SELECT-OP : [emit(args(e)[0]) "[" consts(e)[0] ":" consts(e)[1] "]"]
- BIT-AND-REDUCE-OP :
- var v = emit-as-type(args(e)[0],type(e))
- for x in tail(args(e)) do :
- v = concat(v, [" & " emit(x)])
- v
- BIT-OR-REDUCE-OP :
- var v = emit-as-type(args(e)[0],type(e))
- for x in tail(args(e)) do :
- v = concat(v, [" | " emit(x)])
- v
- BIT-XOR-REDUCE-OP :
- var v = emit-as-type(args(e)[0],type(e))
- for x in tail(args(e)) do :
- v = concat(v, [" ^ " emit(x)])
- v
- (e) :
- println(["Expression:" e])
- error("Unknown expression")
-
-
-defn emit-module (m:InModule) :
-
- val body* = remove-subfield-s(body(m))
-
- val vdecs = Vector<KeyValue<Symbol,Stmt>>() ; all declarations in order, to preserve ordering
- val decs = HashTable<Symbol,Stmt>(symbol-hash) ; all declarations, for fast lookups
- val cons = HashTable<Symbol,Expression>(symbol-hash) ; all connections
- val ens = HashTable<Symbol,Expression>(symbol-hash) ; all enables
- val simuls = HashTable<Symbol,Vector<Streamable>>(symbol-hash)
- defn build-table (s:Stmt) -> False :
- match(s) :
- (s:DefWire|DefPoison|DefRegister|DefMemory|DefNode|DefInstance) :
- add(vdecs,name(s) => s)
- decs[name(s)] = s
- (s:Conditionally) :
- match(conseq(s)) :
- (c:Connect) :
- val n = get-name(loc(c))
- ens[n] = pred(s)
- cons[n] = exp(conseq(s) as Connect)
- (c:PrintfStmt) :
- val my-clk-simuls = get?(simuls,get-name(clk(c)),Vector<Streamable>())
- add(my-clk-simuls,["if(" emit(pred(s)) ") begin"])
- add(my-clk-simuls,[" $fwrite(STDERR," string-join(List(escape(string(c)),map(emit,args(c))), ", ") ");"])
- add(my-clk-simuls,["end"])
- simuls[get-name(clk(c))] = my-clk-simuls
- (c:StopStmt) :
- val my-clk-simuls = get?(simuls,get-name(clk(c)),Vector<Streamable>())
- add(my-clk-simuls,["if(" emit(pred(s)) ") begin"])
- add(my-clk-simuls,[" $fdisplay(STDERR,\"" ret(c) "\");"])
- add(my-clk-simuls,[" $finish;"])
- add(my-clk-simuls,["end"])
- simuls[get-name(clk(c))] = my-clk-simuls
- (s:PrintfStmt) :
- val my-clk-simuls = get?(simuls,get-name(clk(s)),Vector<Streamable>())
- add(my-clk-simuls,["$fwrite(STDERR," string-join(List(escape(string(s)),map(emit,args(s))), ", ") ");"])
- simuls[get-name(clk(s))] = my-clk-simuls
- (c:StopStmt) :
- val my-clk-simuls = get?(simuls,get-name(clk(c)),Vector<Streamable>())
- add(my-clk-simuls,["$fdisplay(STDERR,\"" ret(c) "\");"])
- add(my-clk-simuls,["$finish;"])
- simuls[get-name(clk(c))] = my-clk-simuls
- (s:Connect) :
- val n = get-name(loc(s))
- cons[n] = exp(s)
- (s:Begin) : do(build-table,s)
- (s) : false
-
- build-table(body*)
-
- val wires = Vector<Streamable>()
- val regs = Vector<Streamable>()
- val inits = Vector<Streamable>()
- val assigns = Vector<Streamable>()
- val updates = HashTable<Symbol,Vector<Streamable>>(symbol-hash)
- val insts = HashTable<Symbol,Symbol>(symbol-hash) ; inst -> module
- val inst-ports = HashTable<Symbol,Vector<Streamable>>(symbol-hash)
-
- val sh = get-sym-hash(m)
- val rand-value = "$random" ;"0"
- defn rand-string (w:Long) -> String : string-join(["{" ((w + to-long(31)) / to-long(32)) "{" rand-value "}};"])
-
- for x in vdecs do :
- val sym = key(x)
- match(value(x)) :
- (s:DefPoison) :
- add(regs,["reg " get-width(type(s)) " " sym ";"])
- add(inits,[sym " = " rand-string(width!(type(s)))])
- (s:DefWire) :
- add(wires,["wire " get-width(type(s)) " " sym ";"])
- add(assigns,["assign " sym " = " emit(cons[sym]) ";"])
- (s:DefRegister) :
- add(regs,["reg " get-width(type(s)) " " sym ";"])
- val my-clk-update = get?(updates,get-name(clock(s)),Vector<Streamable>())
- if key?(ens,sym) :
- add(my-clk-update,["if(" emit(ens[sym]) ") begin"])
- val x = cons[sym]
- val y = emit(x)
- add(my-clk-update,[" " sym " <= " y ";"])
- add(my-clk-update,["end"])
- else :
- add(my-clk-update,[sym " <= " emit(cons[sym]) ";"])
- updates[get-name(clock(s))] = my-clk-update
- val w = width!(type(s))
- add(inits,[sym " = " rand-string(w)])
- (s:DefMemory) :
- add(regs,["reg " get-width(type(s)) " " sym " [0:" size(s) - 1 "];"])
- add(inits,["for (initvar = 0; initvar < " size(s) "; initvar = initvar+1)"])
- add(inits,[" " sym "[initvar] = " rand-string(width!(type(s))) ])
- (s:DefNode) :
- add(wires,["wire " get-width(type(value(s))) " " sym ";"])
- add(assigns,["assign " sym " = " emit(value(s)) ";"])
- (s:DefInstance) :
- inst-ports[sym] = Vector<Streamable>()
- insts[sym] = name(module(s) as Ref)
- for f in fields(type(module(s)) as BundleType) do :
- val n* = to-symbol $ string-join $ [sym bundle-expand-delin name(f)]
- add(wires,["wire " get-width(type(f)) " " n* ";"])
- add(inst-ports[sym], ["." name(f) "( " n* " )"])
- if flip(f) == REVERSE :
- add(assigns,["assign " n* " = " emit(cons[n*]) ";"])
- ;(s:DefAccessor) :
- ; val mem-declaration = decs[name(source(s) as Ref)] as DefMemory
- ; switch {_ == acc-dir(s)} :
- ; READ :
- ; if seq?(mem-declaration) :
- ; val index* = Ref(firrtl-gensym(name(index(s) as Ref),sh),type(index(s)))
- ; add(regs,[ "reg " get-width(type(index*)) " " name(index*) ";"]) ; register index for an additional cycle
-
- ; val w = width!(type(index*))
- ; add(inits,[name(index*) " = " rand-string(w)]) ; initialize registered index
-
- ; val my-clk-update = get?(updates,get-name(clock(mem-declaration)),Vector<Streamable>())
- ; add(my-clk-update,[name(index*) " <= " emit(index(s)) ";"]) ; register index
- ; updates[get-name(clock(mem-declaration))] = my-clk-update
-
- ; ; emit read accessor
- ; add(wires,["wire " get-width(type(source(s))) " " sym ";"])
- ; add(assigns,["assign " sym " = " emit(source(s)) "[" emit(index*) "];"])
- ; else :
- ; ; emit read accessor
- ; add(wires,["wire " get-width(type(source(s))) " " sym ";"])
- ; add(assigns,["assign " sym " = " emit(source(s)) "[" emit(index(s)) "];"])
- ; WRITE :
- ; val my-clk-update = get?(updates,get-name(clock(mem-declaration)),Vector<Streamable>())
- ; if key?(ens,sym) :
- ; add(my-clk-update,["if(" emit(ens[sym]) ") begin"])
- ; add(my-clk-update,[" " emit(source(s)) "[" emit(index(s)) "] <= " emit(cons[sym]) ";"])
- ; add(my-clk-update,["end"])
- ; else :
- ; add(my-clk-update,[emit(source(s)) "[" emit(index(s)) "] <= " emit(cons[sym]) ";"])
- ; updates[get-name(clock(mem-declaration))] = my-clk-update
- ; RDWR :
- ; if seq?(mem-declaration) :
- ; ; to make it sequential, register the index for an additional cycle
- ; val index* = Ref(firrtl-gensym(name(index(s) as Ref),sh),type(index(s)))
- ; add(regs,[ "reg " get-width(type(index*)) " " name(index*) ";"])
- ; val w = width!(type(index*))
- ; add(inits,[name(index*) " = " rand-string(w)])
- ; val my-clk-update = get?(updates,get-name(clock(mem-declaration)),Vector<Streamable>())
- ; add(my-clk-update,[name(index*) " <= " emit(index(s)) ";"])
- ; updates[get-name(clock(mem-declaration))] = my-clk-update
-
- ; ; emit read accessor
- ; add(wires,["wire " get-width(type(source(s))) " " sym ";"])
- ; add(assigns,["assign " sym " = " emit(source(s)) "[" emit(index*) "];"])
- ; else :
- ; ; emit read accessor
- ; add(wires,["wire " get-width(type(source(s))) " " sym ";"])
- ; add(assigns,["assign " sym " = " emit(source(s)) "[" emit(index(s)) "];"])
- ; val my-clk-update = get?(updates,get-name(clock(mem-declaration)),Vector<Streamable>())
- ; if key?(ens,sym) :
- ; add(my-clk-update,["if(" emit(ens[sym]) ") begin"])
- ; add(my-clk-update,[" " emit(source(s)) "[" emit(index(s)) "] <= " emit(cons[sym]) ";"])
- ; add(my-clk-update,["end"])
- ; else :
- ; add(my-clk-update,[emit(source(s)) "[" emit(index(s)) "] <= " emit(cons[sym]) ";"])
- ; updates[get-name(clock(mem-declaration))] = my-clk-update
-
- ;==== Actually printing module =====
- val port-indent = " "
- print-all(["module " name(m) "(\n"])
- for (p in ports(m),i in 1 to false) do :
- var end = ",\n"
- if length(ports(m)) == i :
- end = "\n);\n"
- switch {_ == direction(p)} :
- INPUT :
- print-all([port-indent "input " get-width(type(p)) " " name(p) end])
- OUTPUT :
- print-all([port-indent "output " get-width(type(p)) " " name(p) end])
- add(assigns,["assign " name(p) " = " emit(cons[name(p)]) ";"])
- if length(ports(m)) == 0 : print(");\n")
-
- if length(simuls) != 0 : print-all([" integer STDERR = 32'h80000002;\n"])
-
- for w in wires do :
- print(" ")
- println-all(w)
- for r in regs do :
- print(" ")
- println-all(r)
-
- if length(inits) != 0 :
- println("`ifndef SYNTHESIS")
- println(" integer initvar;")
- println(" initial begin")
- println(" #0.002;")
- for i in inits do :
- print-all(" ")
- println-all(i)
- println(" end")
- println("`endif")
-
- for a in assigns do :
- print(" ")
- println-all(a)
-
- for x in insts do :
- println-all([" " value(x) " " key(x) " ("])
- ;print-all([".clk( clk )"])
- for (y in inst-ports[key(x)],i in 1 to false) do :
- print(" ")
- print-all(y)
- if length(inst-ports[key(x)]) != i :
- print(",\n")
- println("\n );")
-
- for x in updates do :
- if length(value(x)) != 0 :
- println-all([" always @(posedge " key(x) ") begin"])
- for u in value(x) do :
- print(" ")
- println-all(u)
- println(" end")
-
- for x in simuls do :
- if length(value(x)) != 0 :
- println("`ifndef SYNTHESIS")
- println-all([" always @(posedge " key(x) ") begin"])
- for u in value(x) do :
- print(" ")
- println-all(u)
- println(" end")
- println("`endif")
-
- println("endmodule")
-
-
-public defn emit-verilog (with-output:(() -> False) -> False, c:Circuit) :
- with-output $ fn () :
- for m in modules(c) do :
- match(m) :
- (m:InModule) : emit-module(m)
- (m:ExModule) : false
- c