aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorjackkoenig2015-12-03 23:32:36 -0800
committerjackkoenig2015-12-03 23:32:36 -0800
commit4d88455c66bd3aa7fd549cdec4f1d05ede83fea2 (patch)
tree685ed86355c75830881b49d0356b6674a338a275 /src/main
parent6b484c5373e9ed162b56e6db245c8dc34ac80957 (diff)
Some stylistic changes and a couple bugfixes to simulation wrapper generation
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/midas/Fame.scala47
-rw-r--r--src/main/scala/midas/Utils.scala67
2 files changed, 91 insertions, 23 deletions
diff --git a/src/main/scala/midas/Fame.scala b/src/main/scala/midas/Fame.scala
index f7299f07..84373aa2 100644
--- a/src/main/scala/midas/Fame.scala
+++ b/src/main/scala/midas/Fame.scala
@@ -153,21 +153,29 @@ object Fame1 {
val instIO = getDefInstType(inst)
val nameToField = (instIO.fields map (f => f.name -> f)).toMap
- val connections = (portMap map(_._2)).toSeq.distinct // modules we connect to
+ val connections = (portMap map(_._2)).toSeq.distinct // modules this inst connects to
// Build simPort for each connecting module
+ // TODO This whole chunk really ought to be rewritten or made a function
val connPorts = connections map { c =>
// Get ports that connect to this particular module as fields
val fields = (portMap filter (_._2 == c)).keySet.toSeq.sorted map (nameToField(_))
val noClock = fields filter (_.tpe != ClockType) // Remove clock
val inputSet = noClock filter (_.dir == Reverse) map (f => Field(f.name, Default, f.tpe))
val outputSet = noClock filter (_.dir == Default)
- Port(inst.info, c, Output, BundleType(Seq(
- Field("hostIn", Reverse, BundleType(Seq(hostReady, hostValid) :+
- Field("hostData", Default, BundleType(inputSet)))),
- Field("hostOut", Default, BundleType(Seq(hostReady, hostValid) ++ outputSet))
- )))
+ Port(inst.info, c, Output, BundleType(
+ (if (inputSet.isEmpty) Seq()
+ else
+ Seq(Field("hostIn", Reverse, BundleType(Seq(hostReady, hostValid) :+
+ Field("hostBits", Default, BundleType(inputSet)))))
+ ) ++
+ (if (outputSet.isEmpty) Seq()
+ else
+ Seq(Field("hostOut", Reverse, BundleType(Seq(hostReady, hostValid) :+
+ Field("hostBits", Default, BundleType(outputSet)))))
+ )
+ ))
}
- val ports = hostClock +: connPorts // Add clock back
+ val ports = hostClock +: connPorts // Add host Clock
// targetFire is signal to indicate when a simulation module can execute, this is indicated by all of its inputs
// being valid and all of its outputs being ready
@@ -179,34 +187,29 @@ object Fame1 {
}
}
}).flatten
+
val targetFire = DefNode(inst.info, "targetFire", genPrimopReduce(And, targetFireInputs))
// targetClock is the simple AND of targetFire and the hostClock so that the rtl module only executes when data
// is available and outputs are ready
val targetClock = DefNode(inst.info, "targetClock", DoPrimop(And,
Seq(buildExp(targetFire.name), buildExp(hostClock.name)), Seq(), UnknownType))
+
// As a simple RTL module, we're always ready
val inputsReady = (connPorts map { port =>
getFields(port) filter (_.dir == Reverse) map { field =>
Connect(inst.info, buildExp(Seq(port.name, field.name, hostReady.name)), UIntValue(1, IntWidth(1)))
}
}).flatten
+
// Outputs are valid on cycles where we fire
val outputsValid = (connPorts map { port =>
getFields(port) filter (_.dir == Default) map { field =>
Connect(inst.info, buildExp(Seq(port.name, field.name, hostValid.name)), buildExp(targetFire.name))
}
}).flatten
- //// Connect up all of the IO of the RTL module to sim module IO, except clock which should be connected
- //// to simClock
- //val instIOConnect = instIO.fields.map{ io =>
- // io.tpe match {
- // case ClockType => Connect(inst.info, Ref(io.name, io.tpe), Ref(simClock.name, UnknownType))
- // case _ =>
- // io.dir match {
- // case Default => Connect(inst.info, Ref(io.name, io.tpe), buildExp(Seq(inst.name, io.name)))
- // case Reverse => Connect(inst.info, buildExp(Seq(inst.name, io.name)), Ref(io.name, io.tpe))
- // } } }
- //// TODO this doesn't actually work yet : portMap
+
+ // Connect up all of the IO of the RTL module to sim module IO, except clock which should be connected
+ // This currently assumes naming things that are also done above when generating connPorts
val instIOConnect = instIO.fields map { field =>
field.tpe match {
case ClockType => Connect(inst.info, Ref(field.name, field.tpe), Ref(targetClock.name, ClockType))
@@ -219,7 +222,7 @@ object Fame1 {
}
}
//val stmts = Block(Seq(simFire, simClock, inst) ++ inputsReady ++ outputsValid ++ instIOConnect)
- val stmts = Block(Seq(targetFire, targetClock) ++ inputsReady ++ outputsValid ++ instIOConnect)
+ val stmts = Block(Seq(targetFire, targetClock) ++ inputsReady ++ outputsValid ++ Seq(inst) ++ instIOConnect)
Module(inst.info, s"SimWrap_${inst.name}", ports, stmts)
}
@@ -227,16 +230,14 @@ object Fame1 {
// ***** transform *****
// Perform FAME-1 Transformation for MIDAS
def transform(c: Circuit): Circuit = {
- // We should do a check low firrtl
+ // We should check that the invariants mentioned above are true
val nameToModule = (c.modules map (m => m.name -> m))(collection.breakOut): Map[String, Module]
val top = nameToModule(c.name)
- println("Top Module:")
- println(top.serialize)
-
val insts = getDefInsts(top)
val portConn = findPortConn(top, insts)
+ // Check that port Connections include all ports for each instance?
val wrappers = insts map (inst => genWrapperModule(inst, portConn(inst.name)))
diff --git a/src/main/scala/midas/Utils.scala b/src/main/scala/midas/Utils.scala
index 71813a10..e9c68201 100644
--- a/src/main/scala/midas/Utils.scala
+++ b/src/main/scala/midas/Utils.scala
@@ -44,4 +44,71 @@ 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
+ */
+
}