diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | src/main/stanza/compilers.stanza | 2 | ||||
| -rw-r--r-- | src/main/stanza/custom-passes.stanza | 117 | ||||
| -rw-r--r-- | src/main/stanza/verilog.stanza | 137 | ||||
| -rw-r--r-- | test/chisel3/ALUTop.fir | 26 | ||||
| -rw-r--r-- | test/chisel3/Core.fir | 10 | ||||
| -rw-r--r-- | test/chisel3/Datapath.fir | 8 | ||||
| -rw-r--r-- | test/chisel3/Tile.fir | 8 | ||||
| -rw-r--r-- | test/riscv-mini/Core.fir | 2 |
9 files changed, 225 insertions, 87 deletions
@@ -46,7 +46,7 @@ riscv: cd $(test_dir)/riscv-mini && lit -v . --path=$(root_dir)/utils/bin/ push: - scp test/riscv-mini/*.v adamiz@a5:/scratch/adamiz/firrtl-all/riscv-mini/generated-src + scp test/chisel3/*.v adamiz@a5:/scratch/adamiz/firrtl-all/riscv-mini/generated-fir-src done: say "done" diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza index f86493a2..7b5f126c 100644 --- a/src/main/stanza/compilers.stanza +++ b/src/main/stanza/compilers.stanza @@ -43,7 +43,7 @@ public defstruct StandardVerilog <: Compiler : public defmethod passes (c:StandardVerilog) -> List<Pass> : to-list $ [ CheckHighForm(expand-delin) - ;; TempElimination() + TempElimination() ToWorkingIR() MakeExplicitReset() ResolveKinds() diff --git a/src/main/stanza/custom-passes.stanza b/src/main/stanza/custom-passes.stanza index 3b6c28ff..6c1e58f6 100644 --- a/src/main/stanza/custom-passes.stanza +++ b/src/main/stanza/custom-passes.stanza @@ -4,6 +4,7 @@ defpackage firrtl/custom-passes : import firrtl/ir-utils import firrtl/ir2 +;============ When Coverage ============= public defstruct WhenCoverage <: Pass : port-name : String reg-name : String @@ -104,3 +105,119 @@ public defn when-coverage (port-name:String, reg-name:String, c:Circuit) : (m:ExModule) : m Circuit(info(c),modules*,main(c)) +;;============ Temporal Check ============= +;public defstruct TemporalAssert : +; module : String +; name : String +; value : Int +; cycle : Int +;public defstruct InsertTemporalAsserts <: Pass : +; asserts : List<TemporalAssert> +;public defmethod pass (b:InsertTemporalAsserts) -> (Circuit -> Circuit) : insert-temporal-assert{asserts(b),_} +;public defmethod name (b:InsertTemporalAsserts) -> String : "Insert Temporal Assert" +;public defmethod short-name (b:InsertTemporalAsserts) -> String : "insert-temporal-assert" +; +;;============ Utilz ============= +;defn concat-all (ls:List<Expression>) -> Expression : +; if length(ls) == 0 : error("Shouldn't be here") +; if length(ls) == 1 : head(ls) +; else : DoPrim( CONCAT-OP, +; list(head(ls),concat-all(tail(ls))), +; list(), +; UIntType(UnknownWidth())) +; +;;============ Insert Temporal Asserts Pass ============= +; +; +;public defn insert-temporal-assert (asserts:List<TemporalAssert>,m:Module) -> Module : +; +; for statement in body(m) do : +; +; for a in asserts do : +; val mod* = for m in modules(c) find : name(m) == module(a) +; match(mod*) : +; (m:False) : error("Module not found") +; (m:Module) : +; +; +;defn needs-ita-instrumentation (m:Module,ms:List<Module>,instrument?:HashTable<Symbol,True|False>,asserts:List<TemporalAssert>) -> False : +; defn needs-instrumentation-s (s:Stmt) -> False : +; match(s) : +; (s:DefWire|DefRegister) : instrument?[name(m)] = contains?(name(s),map(name,asserts)) +; (s:DefInstance) : +; val module-of-inst = for x in ms find : name(x) == name(module(s) as Ref) +; if module-of-inst != false : +; needs-ita-instrumentation(module-of-inst as Module,ms,instrument?,asserts) +; instrument?[name(m)] = instrument?[name(module-of-inst as Module)] +; (s) : false +; do(needs-instrumentation-s,s) +; +; match(m) : +; (m:InModule) : do(needs-instrumentation-s,body(m)) +; (m:ExModule) : false +; +;defn insert-temporal-asserts (port-name:Symbol,assert-name:Symbol,asserts:List<TemporalAssert>,instrument?:HashTable<Symbol,True|False>, m:InModule) -> InModule : +; val when-bits = Vector<Ref>() +; val inst-bits = Vector<Ref>() +; val sym = HashTable<Symbol,Int>(symbol-hash) +; val w1 = IntWidth(1) +; val t1 = UIntType(w1) +; val u1 = UIntValue(to-long $ 1,w1) +; defn insert-temporal-asserts (s:Stmt) -> Stmt : +; match(s) : +; (s:DefWire|DefRegister) : +; val ref = Ref(firrtl-gensym(name(s),sym),t1) +; add(when-bits,ref) +; val conseq* = Begin(list(Connect(FileInfo()ref,u1),conseq(s))) +; map(when-coverage,Conditionally(info(s),pred(s),conseq*,alt(s))) +; (s:DefInstance) : +; if instrument?[name(module(s) as Ref)] : +; val ref = Ref(firrtl-gensym(port-name,sym),UIntType(UnknownWidth())) +; add(inst-bits,ref) +; val sfld = Subfield(Ref(name(s),UnknownType()),port-name,UnknownType()) +; Begin(list(s,Connect(FileInfo(),ref,sfld))) +; else : s +; (s) : map(when-coverage,s) +; +; val body* = when-coverage(body(m)) +; val logic = Vector<Stmt>() +; val port-ref = Ref(port-name,UIntType(UnknownWidth())) +; +; val w-ls = to-list $ when-bits +; if length(w-ls) != 0 : +; val reg-ref = Ref(reg-name,UIntType(IntWidth(length(w-ls)))) +; add{logic,_} $ DefRegister(FileInfo(),name(reg-ref),type(reg-ref)) +; add{logic,_} $ OnReset(FileInfo(),reg-ref,UIntValue(to-long $ 0,IntWidth(length(w-ls)))) +; for (x in w-ls, i in 0 to false) do : +; add{logic,_} $ DefWire(FileInfo(),name(x),type(x)) +; add{logic,_} $ Connect(FileInfo(),x,DoPrim(BIT-SELECT-OP,list(reg-ref),list(i),UIntType(w1))) +; add{logic,_} $ Connect(FileInfo(),reg-ref,concat-all(w-ls)) +; +; val i-ls = to-list $ inst-bits +; if length(i-ls) != 0 : +; for (x in i-ls, i in 0 to false) do : +; add{logic,_} $ DefWire(FileInfo(),name(x),type(x)) +; add{logic,_} $ Connect(FileInfo(),x,UIntValue(to-long $ 0,UnknownWidth())) +; +; if instrument?[name(m)] : add{logic,_} $ Connect(FileInfo(),port-ref,concat-all(append(w-ls,i-ls))) +; +; if length(logic) != 0 : +; val ports* = List(Port(FileInfo(),port-name,OUTPUT,UIntType(UnknownWidth())),ports(m)) +; val body** = Begin(list(Begin(to-list $ logic),body*)) +; InModule(info(m),name(m),ports*,body**) +; else : m +; +;public defn when-coverage (port-name:String, reg-name:String, c:Circuit) : +; val instrument? = HashTable<Symbol,True|False>(symbol-hash) +; for m in modules(c) do : +; instrument?[name(m)] = false +; val top = for m in modules(c) find : name(m) == main(c) +; if top != false : needs-instrumentation(top as Module,modules(c),instrument?) +; +; val modules* = for m in modules(c) map : +; match(m) : +; (m:InModule) : +; when-coverage(to-symbol $ port-name,to-symbol $ reg-name,instrument?,m) +; (m:ExModule) : m +; Circuit(info(c),modules*,main(c)) +; diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza index 96778469..708430f2 100644 --- a/src/main/stanza/verilog.stanza +++ b/src/main/stanza/verilog.stanza @@ -49,6 +49,18 @@ defstruct ComMemKind <: VKind ;============ 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 : string-join(["$signed(" emit(e) ")"]) + defn emit (e:Expression) -> String : match(e) : (e:Ref) : to-string $ name(e) @@ -59,64 +71,73 @@ defn emit (e:Expression) -> String : (e:Register) : error("Non-supported expression") (e:ReadPort) : error("Non-supported expression") (e:WritePort) : error("Non-supported expression") - (e:DoPrim) : string-join $ switch {_ == op(e)} : - ADD-OP : [emit(args(e)[0]) " + " emit(args(e)[1])] - SUB-OP : [emit(args(e)[0]) " - " emit(args(e)[1])] - MUL-OP : [emit(args(e)[0]) " * " emit(args(e)[1])] - DIV-OP : [emit(args(e)[0]) " / " emit(args(e)[1])] - MOD-OP : [emit(args(e)[0]) " % " emit(args(e)[1])] - QUO-OP : [emit(args(e)[0]) " / " emit(args(e)[1])] - REM-OP : [emit(args(e)[0]) " % " emit(args(e)[1])] - ADD-WRAP-OP : [emit(args(e)[0]) " + " emit(args(e)[1])] - SUB-WRAP-OP : [emit(args(e)[0]) " - " emit(args(e)[1])] - LESS-OP : [emit(args(e)[0]) " < " emit(args(e)[1])] - LESS-EQ-OP : [emit(args(e)[0]) " <= " emit(args(e)[1])] - GREATER-OP : [emit(args(e)[0]) " > " emit(args(e)[1])] - GREATER-EQ-OP : [emit(args(e)[0]) " >= " emit(args(e)[1])] - NEQUAL-OP : [emit(args(e)[0]) " != " emit(args(e)[1])] - EQUAL-OP : [emit(args(e)[0]) " == " emit(args(e)[1])] - MUX-OP : [emit(args(e)[0]) " ? " emit(args(e)[1]) " : " emit(args(e)[2])] - PAD-OP : - val x = args(e)[0] - val w = width!(type(x)) - val diff = consts(e)[0] - w - if w == 0 : [ emit(x) ] - else : ["{{" diff "{" emit(x) "[" w - 1 "]}}, " emit(x) " }"] - AS-UINT-OP : - ["$unsigned(" emit(args(e)[0]) ")"] - AS-SINT-OP : - ["$signed(" emit(args(e)[0]) ")"] - DYN-SHIFT-LEFT-OP : [emit(args(e)[0]) " << " emit(args(e)[1])] - DYN-SHIFT-RIGHT-OP : [emit(args(e)[0]) " >> " emit(args(e)[1])] - SHIFT-LEFT-OP : [emit(args(e)[0]) " << " consts(e)[0]] - SHIFT-RIGHT-OP : [emit(args(e)[0]) " >> " consts(e)[0]] - NEG-OP : ["-{" emit(args(e)[0]) "}"] - CONVERT-OP : - match(type(args(e)[0])) : - (t:UIntType) : ["{1'b0," emit(args(e)[0]) "}"] - (t:SIntType) : [emit(args(e)[0])] - BIT-NOT-OP : ["!" emit(args(e)[0])] - BIT-AND-OP : [emit(args(e)[0]) " & " emit(args(e)[1])] - BIT-OR-OP : [emit(args(e)[0]) " | " emit(args(e)[1])] - BIT-XOR-OP : [emit(args(e)[0]) " ^ " emit(args(e)[1])] - CONCAT-OP : ["{" emit(args(e)[0]) "," emit(args(e)[1]) "}"] - 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(args(e)[0]) - for x in tail(args(e)) do : - v = concat(v, [" & " emit(x)]) - v - BIT-OR-REDUCE-OP : - var v = emit(args(e)[0]) - for x in tail(args(e)) do : - v = concat(v, [" | " emit(x)]) - v - BIT-XOR-REDUCE-OP : - var v = emit(args(e)[0]) - for x in tail(args(e)) do : - v = concat(v, [" ^ " emit(x)]) - v + (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 : [sargs[0] " + " sargs[1]] + SUB-OP : [sargs[0] " - " sargs[1]] + MUL-OP : [sargs[0] " * " sargs[1] ] + DIV-OP : [sargs[0] " / " sargs[1] ] + MOD-OP : [sargs[0] " % " sargs[1] ] + QUO-OP : [sargs[0] " / " sargs[1] ] + REM-OP : [sargs[0] " % " sargs[1] ] + ADD-WRAP-OP : [sargs[0], " + " sargs[1]] + SUB-WRAP-OP : [sargs[0], " - " sargs[1]] + LESS-OP : [xargs[0] " < " xargs[1]] + LESS-EQ-OP : [xargs[0] " <= " xargs[1]] + GREATER-OP : [xargs[0] " > " xargs[1]] + GREATER-EQ-OP : [xargs[0] " >= " xargs[1]] + NEQUAL-OP : [xargs[0] " != " xargs[1]] + EQUAL-OP : [xargs[0] " == " xargs[1]] + MUX-OP : [emit(args(e)[0]) " ? " sargs[1] " : " sargs[2]] + PAD-OP : + val x = args(e)[0] + val w = width!(type(x)) + val diff = consts(e)[0] - w + if w == 0 : [ emit(x) ] + else : + if type(e) typeof SIntType : ["{{" diff "{" emit(x) "[" w - 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 : [sargs[0] " << " emit(args(e)[1])] + DYN-SHIFT-RIGHT-OP : + if type(e) typeof SIntType : [sargs[0] " >>> " emit(args(e)[1])] + else : [sargs[0] " >> " emit(args(e)[1])] + SHIFT-LEFT-OP : [sargs[0] " << " consts(e)[0]] + SHIFT-RIGHT-OP : + if type(e) typeof SIntType : [sargs[0] " >>> " consts(e)[0]] + else : [sargs[0] " >> " consts(e)[0]] + NEG-OP : ["-{" sargs[0] "}"] + CONVERT-OP : + match(type(args(e)[0])) : + (t:UIntType) : ["{1'b0," sargs[0] "}"] + (t:SIntType) : [sargs[0]] + BIT-NOT-OP : ["!" sargs[0]] + BIT-AND-OP : [sargs[0] " & " sargs[1]] + BIT-OR-OP : [sargs[0] " | " sargs[1]] + BIT-XOR-OP : [sargs[0] " ^ " sargs[1]] + CONCAT-OP : ["{" sargs[0] "," sargs[1] "}"] + BIT-SELECT-OP : [sargs[0] "[" consts(e)[0] "]"] + BITS-SELECT-OP : [sargs[0] "[" consts(e)[0] ":" consts(e)[1] "]"] + BIT-AND-REDUCE-OP : + var v = sargs[0] + for x in tail(args(e)) do : + v = concat(v, [" & " emit(x)]) + v + BIT-OR-REDUCE-OP : + var v = sargs[0] + for x in tail(args(e)) do : + v = concat(v, [" | " emit(x)]) + v + BIT-XOR-REDUCE-OP : + var v = sargs[0] + for x in tail(args(e)) do : + v = concat(v, [" ^ " emit(x)]) + v defn emit-module (m:InModule) : val h = HashTable<Symbol,VKind>(symbol-hash) diff --git a/test/chisel3/ALUTop.fir b/test/chisel3/ALUTop.fir index 5ebcbccc..2cb4c32e 100644 --- a/test/chisel3/ALUTop.fir +++ b/test/chisel3/ALUTop.fir @@ -12,7 +12,7 @@ circuit ALUTop : node shamt = bits(B, 4, 0) node T_157 = add-wrap(A, B) node T_158 = sub-wrap(A, B) - node T_159 = convert(A) + node T_159 = as-SInt(A) node T_160 = dshr(T_159, shamt) node T_161 = as-UInt(T_160) node T_162 = dshr(A, shamt) @@ -100,19 +100,19 @@ circuit ALUTop : node alu_op2 = mux(T_233, UInt<4>(11), T_232) alu_op := alu_op2 module ALUTop : - input B : UInt<32> - output out : UInt<32> - input A : UInt<32> - input opcode : UInt<7> - input funct : UInt<3> - input add_rshift_type : UInt<1> + input io_B : UInt<32> + output io_out : UInt<32> + input io_A : UInt<32> + input io_opcode : UInt<7> + input io_funct : UInt<3> + input io_add_rshift_type : UInt<1> inst alu of ALU inst alu_dec of ALUdec - alu_dec.opcode := opcode - alu_dec.funct := funct - alu_dec.add_rshift_type := add_rshift_type - alu.A := A - alu.B := B - out := alu.out + alu_dec.opcode := io_opcode + alu_dec.funct := io_funct + alu_dec.add_rshift_type := io_add_rshift_type + alu.A := io_A + alu.B := io_B + io_out := alu.out alu.alu_op := alu_dec.alu_op diff --git a/test/chisel3/Core.fir b/test/chisel3/Core.fir index 06010573..b2062c1d 100644 --- a/test/chisel3/Core.fir +++ b/test/chisel3/Core.fir @@ -12,7 +12,7 @@ circuit Core : node shamt = bits(B, 4, 0) node T_1224 = add-wrap(A, B) node T_1225 = sub-wrap(A, B) - node T_1226 = convert(A) + node T_1226 = as-SInt(A) node T_1227 = dshr(T_1226, shamt) node T_1228 = as-UInt(T_1227) node T_1229 = dshr(A, shamt) @@ -195,12 +195,12 @@ circuit Core : when T_1346 : node T_1347 = eq(addr, UInt<12>(1310)) when T_1347 : - node T_1348 = dshl(UInt<1>(1), src) + node T_1348 = dshl(UInt<1>(1), bits(src,5,0)) node T_1349 = bit-or(data, T_1348) reg_tohost := T_1349 node T_1350 = eq(addr, UInt<12>(1290)) when T_1350 : - node T_1351 = dshl(UInt<1>(1), src) + node T_1351 = dshl(UInt<1>(1), bits(src,5,0)) node T_1352 = bit-or(data, T_1351) reg_status := T_1352 node T_1353 = eq(cmd, UInt<2>(3)) @@ -209,12 +209,12 @@ circuit Core : when T_1355 : node T_1356 = eq(addr, UInt<12>(1310)) when T_1356 : - node T_1357 = dshl(UInt<1>(0), src) + node T_1357 = dshl(UInt<1>(0), bits(src,5,0)) node T_1358 = bit-and(data, T_1357) reg_tohost := T_1358 node T_1359 = eq(addr, UInt<12>(1290)) when T_1359 : - node T_1360 = dshl(UInt<1>(0), src) + node T_1360 = dshl(UInt<1>(0), bits(src,5,0)) node T_1361 = bit-and(data, T_1360) reg_status := T_1361 module Datapath : diff --git a/test/chisel3/Datapath.fir b/test/chisel3/Datapath.fir index 10643549..c02eeae6 100644 --- a/test/chisel3/Datapath.fir +++ b/test/chisel3/Datapath.fir @@ -195,12 +195,12 @@ circuit Datapath : when T_555 : node T_556 = eq(addr, UInt<12>(1310)) when T_556 : - node T_557 = dshl(UInt<1>(1), src) + node T_557 = dshl(UInt<1>(1), bits(src,5,0)) node T_558 = bit-or(data, T_557) reg_tohost := T_558 node T_559 = eq(addr, UInt<12>(1290)) when T_559 : - node T_560 = dshl(UInt<1>(1), src) + node T_560 = dshl(UInt<1>(1), bits(src,5,0)) node T_561 = bit-or(data, T_560) reg_status := T_561 node T_562 = eq(cmd, UInt<2>(3)) @@ -209,12 +209,12 @@ circuit Datapath : when T_564 : node T_565 = eq(addr, UInt<12>(1310)) when T_565 : - node T_566 = dshl(UInt<1>(0), src) + node T_566 = dshl(UInt<1>(0), bits(src,5,0)) node T_567 = bit-and(data, T_566) reg_tohost := T_567 node T_568 = eq(addr, UInt<12>(1290)) when T_568 : - node T_569 = dshl(UInt<1>(0), src) + node T_569 = dshl(UInt<1>(0), bits(src,5,0)) node T_570 = bit-and(data, T_569) reg_status := T_570 module Datapath : diff --git a/test/chisel3/Tile.fir b/test/chisel3/Tile.fir index 01d78cd0..e85bd56b 100644 --- a/test/chisel3/Tile.fir +++ b/test/chisel3/Tile.fir @@ -195,12 +195,12 @@ circuit Tile : when T_1676 : node T_1677 = eq(addr, UInt<12>(1310)) when T_1677 : - node T_1678 = dshl(UInt<1>(1), src) + node T_1678 = dshl(UInt<1>(1), bits(src,5,0)) node T_1679 = bit-or(data, T_1678) reg_tohost := T_1679 node T_1680 = eq(addr, UInt<12>(1290)) when T_1680 : - node T_1681 = dshl(UInt<1>(1), src) + node T_1681 = dshl(UInt<1>(1), bits(src,5,0)) node T_1682 = bit-or(data, T_1681) reg_status := T_1682 node T_1683 = eq(cmd, UInt<2>(3)) @@ -209,12 +209,12 @@ circuit Tile : when T_1685 : node T_1686 = eq(addr, UInt<12>(1310)) when T_1686 : - node T_1687 = dshl(UInt<1>(0), src) + node T_1687 = dshl(UInt<1>(0), bits(src,5,0)) node T_1688 = bit-and(data, T_1687) reg_tohost := T_1688 node T_1689 = eq(addr, UInt<12>(1290)) when T_1689 : - node T_1690 = dshl(UInt<1>(0), src) + node T_1690 = dshl(UInt<1>(0), bits(src,5,0)) node T_1691 = bit-and(data, T_1690) reg_status := T_1691 module Datapath : diff --git a/test/riscv-mini/Core.fir b/test/riscv-mini/Core.fir index eaa5697e..aea05940 100644 --- a/test/riscv-mini/Core.fir +++ b/test/riscv-mini/Core.fir @@ -12,7 +12,7 @@ circuit Core : node shamt = bits(B, 4, 0) node T_1224 = add-wrap(A, B) node T_1225 = sub-wrap(A, B) - node T_1226 = convert(A) + node T_1226 = as-SInt(A) node T_1227 = dshr(T_1226, shamt) node T_1228 = as-UInt(T_1227) node T_1229 = dshr(A, shamt) |
