diff options
Diffstat (limited to 'src/main/scala/midas/Utils.scala')
| -rw-r--r-- | src/main/scala/midas/Utils.scala | 187 |
1 files changed, 121 insertions, 66 deletions
diff --git a/src/main/scala/midas/Utils.scala b/src/main/scala/midas/Utils.scala index e9c68201..d2c61c1b 100644 --- a/src/main/scala/midas/Utils.scala +++ b/src/main/scala/midas/Utils.scala @@ -2,6 +2,7 @@ package midas import firrtl._ +import firrtl.Utils._ object Utils { @@ -22,7 +23,7 @@ object Utils { else Index(rec(names.tail), head, UnknownType) // String -> Ref/Subfield case head: String => - if( names.tail.isEmpty ) Ref(head, UnknownType) + if( names.tail.isEmpty ) Ref("head", UnknownType) else Subfield(rec(names.tail), head, UnknownType) case _ => throw new Exception("Invalid argument type to buildExp! " + names) } @@ -36,6 +37,42 @@ object Utils { else DoPrimop(op, Seq(args.head, genPrimopReduce(op, args.tail)), Seq(), UnknownType) } + // Checks if a firrtl.Port matches the MIDAS SimPort pattern + // This currently just checks that the port is of type bundle with ONLY the members + // hostIn and/or hostOut with correct directions + def isSimPort(port: Port): Boolean = { + //println("isSimPort called on port " + port.serialize) + port.tpe match { + case b: BundleType => { + b.fields map { field => + if( field.name == "hostIn" ) field.dir == Reverse + else if( field.name == "hostOut" ) field.dir == Default + else false + } reduce ( _ & _ ) + } + case _ => false + } + } + + def splitSimPort(port: Port): Seq[Field] = { + try { + val b = port.tpe.asInstanceOf[BundleType] + Seq(b.fields.find(_.name == "hostIn"), b.fields.find(_.name == "hostOut")).flatten + } catch { + case e: Exception => throw new Exception("Invalid SimPort " + port.serialize) + } + } + + // From simulation host decoupled, return hostbits field + def getHostBits(field: Field): Field = { + try { + val b = field.tpe.asInstanceOf[BundleType] + b.fields.find(_.name == "hostBits").get + } catch { + case e: Exception => throw new Exception("Invalid SimField " + field.serialize) + } + } + // For a port that is known to be of type BundleType, return the fields of that bundle def getFields(port: Port): Seq[Field] = { port.tpe match { @@ -45,70 +82,88 @@ object Utils { } // Queue - /* - module Queue : - input clock : Clock - input reset : UInt<1> - output io : {flip enq : {flip ready : UInt<1>, valid : UInt<1>, bits : UInt<32>}, deq : {flip ready : UInt<1>, valid : UInt<1>, bits : UInt<32>}, count : UInt<3>} - - io.count := UInt<1>("h00") - io.deq.bits := UInt<1>("h00") - io.deq.valid := UInt<1>("h00") - io.enq.ready := UInt<1>("h00") - cmem ram : UInt<32>[4], clock - reg T_26 : UInt<2>, clock, reset - onreset T_26 := UInt<2>("h00") - reg T_28 : UInt<2>, clock, reset - onreset T_28 := UInt<2>("h00") - reg maybe_full : UInt<1>, clock, reset - onreset maybe_full := UInt<1>("h00") - node ptr_match = eq(T_26, T_28) - node T_33 = eq(maybe_full, UInt<1>("h00")) - node empty = and(ptr_match, T_33) - node full = and(ptr_match, maybe_full) - node maybe_flow = and(UInt<1>("h00"), empty) - node do_flow = and(maybe_flow, io.deq.ready) - node T_39 = and(io.enq.ready, io.enq.valid) - node T_41 = eq(do_flow, UInt<1>("h00")) - node do_enq = and(T_39, T_41) - node T_43 = and(io.deq.ready, io.deq.valid) - node T_45 = eq(do_flow, UInt<1>("h00")) - node do_deq = and(T_43, T_45) - when do_enq : - infer accessor T_47 = ram[T_26] - T_47 := io.enq.bits - node T_49 = eq(T_26, UInt<2>("h03")) - node T_51 = and(UInt<1>("h00"), T_49) - node T_54 = addw(T_26, UInt<1>("h01")) - node T_55 = mux(T_51, UInt<1>("h00"), T_54) - T_26 := T_55 - skip - when do_deq : - node T_57 = eq(T_28, UInt<2>("h03")) - node T_59 = and(UInt<1>("h00"), T_57) - node T_62 = addw(T_28, UInt<1>("h01")) - node T_63 = mux(T_59, UInt<1>("h00"), T_62) - T_28 := T_63 - skip - node T_64 = neq(do_enq, do_deq) - when T_64 : - maybe_full := do_enq - skip - node T_66 = eq(empty, UInt<1>("h00")) - node T_68 = and(UInt<1>("h00"), io.enq.valid) - node T_69 = or(T_66, T_68) - io.deq.valid := T_69 - node T_71 = eq(full, UInt<1>("h00")) - node T_73 = and(UInt<1>("h00"), io.deq.ready) - node T_74 = or(T_71, T_73) - io.enq.ready := T_74 - infer accessor T_75 = ram[T_28] - node T_76 = mux(maybe_flow, io.enq.bits, T_75) - io.deq.bits := T_76 - node ptr_diff = subw(T_26, T_28) - node T_78 = and(maybe_full, ptr_match) - node T_79 = cat(T_78, ptr_diff) - io.count := T_79 - */ + def buildSimQueue(name: String, tpe: Type): Module = { + val templatedQueue = + """ + module `NAME : + input clock : Clock + input reset : UInt<1> + output io : {flip enq : {flip ready : UInt<1>, valid : UInt<1>, bits : `TYPE}, deq : {flip ready : UInt<1>, valid : UInt<1>, bits : `TYPE}, count : UInt<3>} + + io.count := UInt<1>("h00") + io.deq.bits.surprise.no := UInt<1>("h00") + io.deq.bits.surprise.yes := UInt<1>("h00") + io.deq.bits.store := UInt<1>("h00") + io.deq.bits.data := UInt<1>("h00") + io.deq.bits.addr := UInt<1>("h00") + io.deq.valid := UInt<1>("h00") + io.enq.ready := UInt<1>("h00") + cmem ram : `TYPE[4], clock + reg T_80 : UInt<2>, clock, reset + onreset T_80 := UInt<2>("h00") + reg T_82 : UInt<2>, clock, reset + onreset T_82 := UInt<2>("h00") + reg maybe_full : UInt<1>, clock, reset + onreset maybe_full := UInt<1>("h00") + node ptr_match = eq(T_80, T_82) + node T_87 = eq(maybe_full, UInt<1>("h00")) + node empty = and(ptr_match, T_87) + node full = and(ptr_match, maybe_full) + node maybe_flow = and(UInt<1>("h00"), empty) + node do_flow = and(maybe_flow, io.deq.ready) + node T_93 = and(io.enq.ready, io.enq.valid) + node T_95 = eq(do_flow, UInt<1>("h00")) + node do_enq = and(T_93, T_95) + node T_97 = and(io.deq.ready, io.deq.valid) + node T_99 = eq(do_flow, UInt<1>("h00")) + node do_deq = and(T_97, T_99) + when do_enq : + infer accessor T_101 = ram[T_80] + T_101 <> io.enq.bits + node T_109 = eq(T_80, UInt<2>("h03")) + node T_111 = and(UInt<1>("h00"), T_109) + node T_114 = addw(T_80, UInt<1>("h01")) + node T_115 = mux(T_111, UInt<1>("h00"), T_114) + T_80 := T_115 + skip + when do_deq : + node T_117 = eq(T_82, UInt<2>("h03")) + node T_119 = and(UInt<1>("h00"), T_117) + node T_122 = addw(T_82, UInt<1>("h01")) + node T_123 = mux(T_119, UInt<1>("h00"), T_122) + T_82 := T_123 + skip + node T_124 = neq(do_enq, do_deq) + when T_124 : + maybe_full := do_enq + skip + node T_126 = eq(empty, UInt<1>("h00")) + node T_128 = and(UInt<1>("h00"), io.enq.valid) + node T_129 = or(T_126, T_128) + io.deq.valid := T_129 + node T_131 = eq(full, UInt<1>("h00")) + node T_133 = and(UInt<1>("h00"), io.deq.ready) + node T_134 = or(T_131, T_133) + io.enq.ready := T_134 + infer accessor T_135 = ram[T_82] + wire T_149 : `TYPE + T_149 <> T_135 + when maybe_flow : + T_149 <> io.enq.bits + skip + io.deq.bits <> T_149 + node ptr_diff = subw(T_80, T_82) + node T_157 = and(maybe_full, ptr_match) + node T_158 = cat(T_157, ptr_diff) + io.count := T_158 + """ + //def buildQueue(name: String, tpe: Type): Module = { + val concreteQueue = templatedQueue.replaceAllLiterally("`NAME", name). + replaceAllLiterally("`TYPE", tpe.serialize) + // Generate initial values + //val bitsField = Field("bits", Default, tpe) + println(concreteQueue.stripMargin) + firrtl.Parser.parseModule(concreteQueue) + } } |
