diff options
| author | azidar | 2016-02-09 18:53:28 -0800 |
|---|---|---|
| committer | azidar | 2016-02-09 18:57:08 -0800 |
| commit | 4160ffa5c86ff7f4d5534dec3624b7127263b782 (patch) | |
| tree | d69dfe008857f7c9d66f8c7647a4f1eaeb02fe76 /src/main/stanza/verilog.stanza | |
| parent | bb5f68948c6d75d1f02c614f3e0ae4ef9bc6e689 (diff) | |
Added license to FIRRTL files
Diffstat (limited to 'src/main/stanza/verilog.stanza')
| -rw-r--r-- | src/main/stanza/verilog.stanza | 402 |
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 |
