aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/midas/Utils.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/midas/Utils.scala')
-rw-r--r--src/main/scala/midas/Utils.scala187
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)
+ }
}