map macros to sequential memeory
This commit is contained in:
@@ -31,13 +31,13 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa
|
||||
dataType,
|
||||
lib.src.depth,
|
||||
1, // writeLatency
|
||||
0, // readLatency
|
||||
(lib.readers ++ lib.readwriters).indices map (i => s"R_$i"),
|
||||
(lib.writers ++ lib.readwriters).indices map (i => s"W_$i"),
|
||||
Nil
|
||||
1, // readLatency
|
||||
lib.readers.indices map (i => s"R_$i"),
|
||||
lib.writers.indices map (i => s"W_$i"),
|
||||
lib.readwriters.indices map (i => s"RW_$i")
|
||||
)
|
||||
|
||||
val readConnects = (lib.readers ++ lib.readwriters).zipWithIndex flatMap { case (r, i) =>
|
||||
val readConnects = lib.readers.zipWithIndex flatMap { case (r, i) =>
|
||||
val clock = portToExpression(r.src.clock)
|
||||
val address = portToExpression(r.src.address)
|
||||
val enable = (r.src chipEnable, r.src readEnable) match {
|
||||
@@ -54,18 +54,15 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa
|
||||
WSubIndex(data, k, tpe, UNKNOWNGENDER))).reverse)
|
||||
case _: UIntType => data
|
||||
}
|
||||
val addrReg = WRef(s"R_${i}_addr_reg", r.addrType, RegKind)
|
||||
Seq(
|
||||
DefRegister(NoInfo, addrReg.name, r.addrType, clock, zero, addrReg),
|
||||
Connect(NoInfo, memPortField(mem, s"R_$i", "clk"), clock),
|
||||
Connect(NoInfo, memPortField(mem, s"R_$i", "addr"), addrReg),
|
||||
Connect(NoInfo, memPortField(mem, s"R_$i", "addr"), address),
|
||||
Connect(NoInfo, memPortField(mem, s"R_$i", "en"), enable),
|
||||
Connect(NoInfo, WRef(r.src.output.get.name), read),
|
||||
Connect(NoInfo, addrReg, Mux(enable, address, addrReg, UnknownType))
|
||||
Connect(NoInfo, WRef(r.src.output.get.name), read)
|
||||
)
|
||||
}
|
||||
|
||||
val writeConnects = (lib.writers ++ lib.readwriters).zipWithIndex flatMap { case (w, i) =>
|
||||
val writeConnects = lib.writers.zipWithIndex flatMap { case (w, i) =>
|
||||
val clock = portToExpression(w.src.clock)
|
||||
val address = portToExpression(w.src.address)
|
||||
val enable = (w.src.chipEnable, w.src.writeEnable) match {
|
||||
@@ -96,15 +93,55 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa
|
||||
Seq(Connect(NoInfo, data, write), Connect(NoInfo, mask, one))
|
||||
})
|
||||
}
|
||||
lib.module(Block(mem +: (readConnects ++ writeConnects)))
|
||||
|
||||
val readwriteConnects = lib.readwriters.zipWithIndex flatMap { case (rw, i) =>
|
||||
val clock = portToExpression(rw.src.clock)
|
||||
val address = portToExpression(rw.src.address)
|
||||
val wmode = rw.src.writeEnable match {
|
||||
case Some(we) => portToExpression(we)
|
||||
case None => zero // is it possible?
|
||||
}
|
||||
val enable = (rw.src.chipEnable, rw.src.readEnable) match {
|
||||
case (Some(en), Some(re)) =>
|
||||
and(portToExpression(en), or(portToExpression(re), wmode))
|
||||
case (Some(en), None) => portToExpression(en)
|
||||
case (None, Some(re)) => or(portToExpression(re), wmode)
|
||||
case (None, None) => one
|
||||
}
|
||||
val wmask = memPortField(mem, s"RW_$i", "wmask")
|
||||
val wdata = memPortField(mem, s"RW_$i", "wdata")
|
||||
val rdata = memPortField(mem, s"RW_$i", "rdata")
|
||||
val write = portToExpression(rw.src.input.get)
|
||||
val read = (dataType: @unchecked) match {
|
||||
case VectorType(tpe, size) => cat(((0 until size) map (k =>
|
||||
WSubIndex(rdata, k, tpe, UNKNOWNGENDER))).reverse)
|
||||
case _: UIntType => rdata
|
||||
}
|
||||
Seq(
|
||||
Connect(NoInfo, memPortField(mem, s"RW_$i", "clk"), clock),
|
||||
Connect(NoInfo, memPortField(mem, s"RW_$i", "addr"), address),
|
||||
Connect(NoInfo, memPortField(mem, s"RW_$i", "en"), enable),
|
||||
Connect(NoInfo, memPortField(mem, s"RW_$i", "wmode"), wmode),
|
||||
Connect(NoInfo, WRef(rw.src.output.get.name), read)
|
||||
) ++ (dataType match {
|
||||
case VectorType(tpe, size) =>
|
||||
val width = bitWidth(tpe).toInt
|
||||
((0 until size) map (k =>
|
||||
Connect(NoInfo, WSubIndex(wdata, k, tpe, UNKNOWNGENDER),
|
||||
bits(write, (k + 1) * width - 1, k * width)))) ++
|
||||
((0 until size) map (k =>
|
||||
Connect(NoInfo, WSubIndex(wmask, k, BoolType, UNKNOWNGENDER),
|
||||
bits(WRef(rw.src.maskPort.get.name), k))))
|
||||
case _: UIntType =>
|
||||
Seq(Connect(NoInfo, wdata, write), Connect(NoInfo, wmask, one))
|
||||
})
|
||||
}
|
||||
|
||||
lib.module(Block(mem +: (readConnects ++ writeConnects ++ readwriteConnects)))
|
||||
}}).toMap
|
||||
|
||||
def run(c: Circuit): Circuit = {
|
||||
if (!synflops) c
|
||||
else {
|
||||
val circuit = c.copy(modules = (c.modules map (m => libMods getOrElse (m.name, m))))
|
||||
// print(circuit.serialize)
|
||||
circuit
|
||||
}
|
||||
else c.copy(modules = (c.modules map (m => libMods getOrElse (m.name, m))))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,8 @@ object Utils {
|
||||
|
||||
def and(e1: Expression, e2: Expression) =
|
||||
DoPrim(PrimOps.And, Seq(e1, e2), Nil, e1.tpe)
|
||||
def or(e1: Expression, e2: Expression) =
|
||||
DoPrim(PrimOps.Or, Seq(e1, e2), Nil, e1.tpe)
|
||||
def bits(e: Expression, high: BigInt, low: BigInt): Expression =
|
||||
DoPrim(PrimOps.Bits, Seq(e), Seq(high, low), UIntType(IntWidth(high-low+1)))
|
||||
def bits(e: Expression, idx: BigInt): Expression = bits(e, idx, idx)
|
||||
|
||||
Reference in New Issue
Block a user