diff options
| author | jackkoenig | 2015-12-03 23:32:36 -0800 |
|---|---|---|
| committer | jackkoenig | 2015-12-03 23:32:36 -0800 |
| commit | 4d88455c66bd3aa7fd549cdec4f1d05ede83fea2 (patch) | |
| tree | 685ed86355c75830881b49d0356b6674a338a275 /src/main/scala | |
| parent | 6b484c5373e9ed162b56e6db245c8dc34ac80957 (diff) | |
Some stylistic changes and a couple bugfixes to simulation wrapper generation
Diffstat (limited to 'src/main/scala')
| -rw-r--r-- | src/main/scala/midas/Fame.scala | 47 | ||||
| -rw-r--r-- | src/main/scala/midas/Utils.scala | 67 |
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 + */ + } |
