1
0
Fork 0

Get rid of remaining MemIO code

The only thing we were still using it for was for the MIFDataBits
and MIFTagBits parameters. We replace these with EdgeDataBits and
EdgeIDBits.
This commit is contained in:
Howard Mao 2016-09-27 15:11:31 -07:00
parent 18e7ea89f2
commit c45cc76cef
6 changed files with 33 additions and 407 deletions

View File

@ -111,7 +111,6 @@ abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle](
l1tol2net.io.clients_uncached <> uncoreTileIOs.map(_.uncached).flatten ++ io.slave
l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner
// Create a converter between TileLinkIO and MemIO for each channel
val mem_ic = Module(new TileLinkMemoryInterconnect(nBanksPerMemChannel, c.nMemChannels)(outerMemParams))
val backendBuffering = TileLinkDepths(0,0,0,0,0)

View File

@ -58,15 +58,15 @@ class TraceGenL2Config extends Config(
new WithNL2Ways(1) ++ new WithL2Capacity(32 * 64 / 1024) ++
new WithL2Cache ++ new TraceGenConfig)
class MIF128BitComparatorConfig extends Config(
new WithMIFDataBits(128) ++ new ComparatorConfig)
class MIF128BitMemtestConfig extends Config(
new WithMIFDataBits(128) ++ new MemtestConfig)
class Edge128BitComparatorConfig extends Config(
new WithEdgeDataBits(128) ++ new ComparatorConfig)
class Edge128BitMemtestConfig extends Config(
new WithEdgeDataBits(128) ++ new MemtestConfig)
class MIF32BitComparatorConfig extends Config(
new WithMIFDataBits(32) ++ new ComparatorConfig)
class MIF32BitMemtestConfig extends Config(
new WithMIFDataBits(32) ++ new MemtestConfig)
class Edge32BitComparatorConfig extends Config(
new WithEdgeDataBits(32) ++ new ComparatorL2Config)
class Edge32BitMemtestConfig extends Config(
new WithEdgeDataBits(32) ++ new MemtestConfig)
/* Composable Configs to set individual parameters */
class WithGroundTest extends Config(
@ -75,6 +75,7 @@ class WithGroundTest extends Config(
(c: CoreplexConfig, p: Parameters) => uncore.tilelink2.LazyModule(new GroundTestCoreplex(c)(p)).module
case TLKey("L1toL2") => {
val useMEI = site(NTiles) <= 1 && site(NCachedTileLinkPorts) <= 1
val dataBeats = (8 * site(CacheBlockBytes)) / site(XLen)
TileLinkParameters(
coherencePolicy = (
if (useMEI) new MEICoherence(site(L2DirectoryRepresentation))
@ -87,7 +88,7 @@ class WithGroundTest extends Config(
.reduce(max(_, _)),
maxClientsPerPort = 1,
maxManagerXacts = site(NAcquireTransactors) + 2,
dataBeats = 8,
dataBeats = dataBeats,
dataBits = site(CacheBlockBytes)*8)
}
case BuildTiles => {
@ -217,7 +218,7 @@ class WithTraceGen extends Config(
val nSets = 32 // L2 NSets
val nWays = 1
val blockOffset = site(CacheBlockOffsetBits)
val nBeats = site(MIFDataBeats)
val nBeats = site(TLKey("L1toL2")).dataBeats
List.tabulate(4 * nWays) { i =>
Seq.tabulate(nBeats) { j => BigInt((j * 8) + ((i * nSets) << blockOffset)) }
}.flatten

View File

@ -1,318 +0,0 @@
// See LICENSE for license details.
package junctions
import Chisel._
import scala.math._
import util.{HellaQueue, ParameterizedBundle}
import cde.{Parameters, Field}
case object MIFAddrBits extends Field[Int]
case object MIFDataBits extends Field[Int]
case object MIFTagBits extends Field[Int]
case object MIFDataBeats extends Field[Int]
trait HasMIFParameters {
implicit val p: Parameters
val mifTagBits = p(MIFTagBits)
val mifAddrBits = p(MIFAddrBits)
val mifDataBits = p(MIFDataBits)
val mifDataBeats = p(MIFDataBeats)
}
abstract class MIFModule(implicit val p: Parameters) extends Module with HasMIFParameters
abstract class MIFBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
with HasMIFParameters
trait HasMemData extends HasMIFParameters {
val data = Bits(width = mifDataBits)
}
trait HasMemAddr extends HasMIFParameters {
val addr = UInt(width = mifAddrBits)
}
trait HasMemTag extends HasMIFParameters {
val tag = UInt(width = mifTagBits)
}
class MemReqCmd(implicit p: Parameters) extends MIFBundle()(p) with HasMemAddr with HasMemTag {
val rw = Bool()
}
class MemTag(implicit p: Parameters) extends MIFBundle()(p) with HasMemTag
class MemData(implicit p: Parameters) extends MIFBundle()(p) with HasMemData
class MemResp(implicit p: Parameters) extends MIFBundle()(p) with HasMemData with HasMemTag
class MemIO(implicit p: Parameters) extends ParameterizedBundle()(p) {
val req_cmd = Decoupled(new MemReqCmd)
val req_data = Decoupled(new MemData)
val resp = Decoupled(new MemResp).flip
}
class MemPipeIO(implicit p: Parameters) extends ParameterizedBundle()(p) {
val req_cmd = Decoupled(new MemReqCmd)
val req_data = Decoupled(new MemData)
val resp = Valid(new MemResp).flip
}
class MemSerializedIO(w: Int)(implicit p: Parameters) extends ParameterizedBundle()(p) {
val req = Decoupled(Bits(width = w))
val resp = Valid(Bits(width = w)).flip
override def cloneType = new MemSerializedIO(w)(p).asInstanceOf[this.type]
}
class MemSerdes(w: Int)(implicit p: Parameters) extends MIFModule
{
val io = new Bundle {
val wide = new MemIO().flip
val narrow = new MemSerializedIO(w)
}
val abits = io.wide.req_cmd.bits.asUInt.getWidth
val dbits = io.wide.req_data.bits.asUInt.getWidth
val rbits = io.wide.resp.bits.getWidth
val out_buf = Reg(Bits())
val in_buf = Reg(Bits())
val s_idle :: s_read_addr :: s_write_addr :: s_write_idle :: s_write_data :: Nil = Enum(UInt(), 5)
val state = Reg(init=s_idle)
val send_cnt = Reg(init=UInt(0, log2Up((max(abits, dbits)+w-1)/w)))
val data_send_cnt = Reg(init=UInt(0, log2Up(mifDataBeats)))
val adone = io.narrow.req.ready && send_cnt === UInt((abits-1)/w)
val ddone = io.narrow.req.ready && send_cnt === UInt((dbits-1)/w)
when (io.narrow.req.valid && io.narrow.req.ready) {
send_cnt := send_cnt + UInt(1)
out_buf := out_buf >> UInt(w)
}
when (io.wide.req_cmd.valid && io.wide.req_cmd.ready) {
out_buf := io.wide.req_cmd.bits.asUInt
}
when (io.wide.req_data.valid && io.wide.req_data.ready) {
out_buf := io.wide.req_data.bits.asUInt
}
io.wide.req_cmd.ready := state === s_idle
io.wide.req_data.ready := state === s_write_idle
io.narrow.req.valid := state === s_read_addr || state === s_write_addr || state === s_write_data
io.narrow.req.bits := out_buf
when (state === s_idle && io.wide.req_cmd.valid) {
state := Mux(io.wide.req_cmd.bits.rw, s_write_addr, s_read_addr)
}
when (state === s_read_addr && adone) {
state := s_idle
send_cnt := UInt(0)
}
when (state === s_write_addr && adone) {
state := s_write_idle
send_cnt := UInt(0)
}
when (state === s_write_idle && io.wide.req_data.valid) {
state := s_write_data
}
when (state === s_write_data && ddone) {
data_send_cnt := data_send_cnt + UInt(1)
state := Mux(data_send_cnt === UInt(mifDataBeats-1), s_idle, s_write_idle)
send_cnt := UInt(0)
}
val recv_cnt = Reg(init=UInt(0, log2Up((rbits+w-1)/w)))
val data_recv_cnt = Reg(init=UInt(0, log2Up(mifDataBeats)))
val resp_val = Reg(init=Bool(false))
resp_val := Bool(false)
when (io.narrow.resp.valid) {
recv_cnt := recv_cnt + UInt(1)
when (recv_cnt === UInt((rbits-1)/w)) {
recv_cnt := UInt(0)
data_recv_cnt := data_recv_cnt + UInt(1)
resp_val := Bool(true)
}
in_buf := Cat(io.narrow.resp.bits, in_buf((rbits+w-1)/w*w-1,w))
}
io.wide.resp.valid := resp_val
io.wide.resp.bits := io.wide.resp.bits.fromBits(in_buf)
}
class MemDesserIO(w: Int)(implicit p: Parameters) extends ParameterizedBundle()(p) {
val narrow = new MemSerializedIO(w).flip
val wide = new MemIO
}
class MemDesser(w: Int)(implicit p: Parameters) extends Module // test rig side
{
val io = new MemDesserIO(w)
val abits = io.wide.req_cmd.bits.asUInt.getWidth
val dbits = io.wide.req_data.bits.asUInt.getWidth
val rbits = io.wide.resp.bits.getWidth
val mifDataBeats = p(MIFDataBeats)
require(dbits >= abits && rbits >= dbits)
val recv_cnt = Reg(init=UInt(0, log2Up((rbits+w-1)/w)))
val data_recv_cnt = Reg(init=UInt(0, log2Up(mifDataBeats)))
val adone = io.narrow.req.valid && recv_cnt === UInt((abits-1)/w)
val ddone = io.narrow.req.valid && recv_cnt === UInt((dbits-1)/w)
val rdone = io.narrow.resp.valid && recv_cnt === UInt((rbits-1)/w)
val s_cmd_recv :: s_cmd :: s_data_recv :: s_data :: s_reply :: Nil = Enum(UInt(), 5)
val state = Reg(init=s_cmd_recv)
val in_buf = Reg(Bits())
when (io.narrow.req.valid && io.narrow.req.ready || io.narrow.resp.valid) {
recv_cnt := recv_cnt + UInt(1)
in_buf := Cat(io.narrow.req.bits, in_buf((rbits+w-1)/w*w-1,w))
}
io.narrow.req.ready := state === s_cmd_recv || state === s_data_recv
when (state === s_cmd_recv && adone) {
state := s_cmd
recv_cnt := UInt(0)
}
when (state === s_cmd && io.wide.req_cmd.ready) {
state := Mux(io.wide.req_cmd.bits.rw, s_data_recv, s_reply)
}
when (state === s_data_recv && ddone) {
state := s_data
recv_cnt := UInt(0)
}
when (state === s_data && io.wide.req_data.ready) {
state := s_data_recv
when (data_recv_cnt === UInt(mifDataBeats-1)) {
state := s_cmd_recv
}
data_recv_cnt := data_recv_cnt + UInt(1)
}
when (rdone) { // state === s_reply
when (data_recv_cnt === UInt(mifDataBeats-1)) {
state := s_cmd_recv
}
recv_cnt := UInt(0)
data_recv_cnt := data_recv_cnt + UInt(1)
}
val req_cmd = in_buf >> UInt(((rbits+w-1)/w - (abits+w-1)/w)*w)
io.wide.req_cmd.valid := state === s_cmd
io.wide.req_cmd.bits := io.wide.req_cmd.bits.fromBits(req_cmd)
io.wide.req_data.valid := state === s_data
io.wide.req_data.bits.data := in_buf >> UInt(((rbits+w-1)/w - (dbits+w-1)/w)*w)
val dataq = Module(new Queue(new MemResp, mifDataBeats))
dataq.io.enq <> io.wide.resp
dataq.io.deq.ready := recv_cnt === UInt((rbits-1)/w)
io.narrow.resp.valid := dataq.io.deq.valid
io.narrow.resp.bits := dataq.io.deq.bits.asUInt >> (recv_cnt * UInt(w))
}
class MemIOArbiter(val arbN: Int)(implicit p: Parameters) extends MIFModule {
val io = new Bundle {
val inner = Vec(arbN, new MemIO).flip
val outer = new MemIO
}
if(arbN > 1) {
val cmd_arb = Module(new RRArbiter(new MemReqCmd, arbN))
val choice_q = Module(new Queue(cmd_arb.io.chosen, 4))
val (data_cnt, data_done) = Counter(io.outer.req_data.fire(), mifDataBeats)
io.inner.map(_.req_cmd).zipWithIndex.zip(cmd_arb.io.in).map{ case ((req, id), arb) => {
arb.valid := req.valid
arb.bits := req.bits
arb.bits.tag := Cat(req.bits.tag, UInt(id))
req.ready := arb.ready
}}
io.outer.req_cmd.bits := cmd_arb.io.out.bits
io.outer.req_cmd.valid := cmd_arb.io.out.valid && choice_q.io.enq.ready
cmd_arb.io.out.ready := io.outer.req_cmd.ready && choice_q.io.enq.ready
choice_q.io.enq.bits := cmd_arb.io.chosen
choice_q.io.enq.valid := cmd_arb.io.out.fire() && cmd_arb.io.out.bits.rw
io.outer.req_data.bits := io.inner(choice_q.io.deq.bits).req_data.bits
io.outer.req_data.valid := io.inner(choice_q.io.deq.bits).req_data.valid && choice_q.io.deq.valid
io.inner.map(_.req_data.ready).zipWithIndex.foreach {
case(r, i) => r := UInt(i) === choice_q.io.deq.bits && choice_q.io.deq.valid
}
choice_q.io.deq.ready := data_done
io.outer.resp.ready := Bool(false)
for (i <- 0 until arbN) {
io.inner(i).resp.valid := Bool(false)
when(io.outer.resp.bits.tag(log2Up(arbN)-1,0) === UInt(i)) {
io.inner(i).resp.valid := io.outer.resp.valid
io.outer.resp.ready := io.inner(i).resp.ready
}
io.inner(i).resp.bits := io.outer.resp.bits
io.inner(i).resp.bits.tag := io.outer.resp.bits.tag >> UInt(log2Up(arbN))
}
} else { io.outer <> io.inner.head }
}
object MemIOMemPipeIOConverter {
def apply(in: MemPipeIO)(implicit p: Parameters): MemIO = {
val out = Wire(new MemIO())
in.resp.valid := out.resp.valid
in.resp.bits := out.resp.bits
out.resp.ready := Bool(true)
out.req_cmd.valid := in.req_cmd.valid
out.req_cmd.bits := in.req_cmd.bits
in.req_cmd.ready := out.req_cmd.ready
out.req_data.valid := in.req_data.valid
out.req_data.bits := in.req_data.bits
in.req_data.ready := out.req_data.ready
out
}
}
class MemPipeIOMemIOConverter(numRequests: Int)(implicit p: Parameters) extends MIFModule {
val io = new Bundle {
val cpu = new MemIO().flip
val mem = new MemPipeIO
}
val numEntries = numRequests * mifDataBeats
val size = log2Down(numEntries) + 1
val inc = Wire(Bool())
val dec = Wire(Bool())
val count = Reg(init=UInt(numEntries, size))
val watermark = count >= UInt(mifDataBeats)
when (inc && !dec) {
count := count + UInt(1)
}
when (!inc && dec) {
count := count - UInt(mifDataBeats)
}
when (inc && dec) {
count := count - UInt(mifDataBeats-1)
}
val cmdq_mask = io.cpu.req_cmd.bits.rw || watermark
io.mem.req_cmd.valid := io.cpu.req_cmd.valid && cmdq_mask
io.cpu.req_cmd.ready := io.mem.req_cmd.ready && cmdq_mask
io.mem.req_cmd.bits := io.cpu.req_cmd.bits
io.mem.req_data <> io.cpu.req_data
// Have separate queues to allow for different mem implementations
val resp_data_q = Module((new HellaQueue(numEntries)) { new MemData })
resp_data_q.io.enq.valid := io.mem.resp.valid
resp_data_q.io.enq.bits.data := io.mem.resp.bits.data
val resp_tag_q = Module((new HellaQueue(numEntries)) { new MemTag })
resp_tag_q.io.enq.valid := io.mem.resp.valid
resp_tag_q.io.enq.bits.tag := io.mem.resp.bits.tag
io.cpu.resp.valid := resp_data_q.io.deq.valid && resp_tag_q.io.deq.valid
io.cpu.resp.bits.data := resp_data_q.io.deq.bits.data
io.cpu.resp.bits.tag := resp_tag_q.io.deq.bits.tag
resp_data_q.io.deq.ready := io.cpu.resp.ready
resp_tag_q.io.deq.ready := io.cpu.resp.ready
inc := resp_data_q.io.deq.fire() && resp_tag_q.io.deq.fire()
dec := io.mem.req_cmd.fire() && !io.mem.req_cmd.bits.rw
}

View File

@ -227,60 +227,6 @@ object NastiWriteResponseChannel {
}
}
class MemIONastiIOConverter(cacheBlockOffsetBits: Int)(implicit p: Parameters) extends MIFModule
with HasNastiParameters {
val io = new Bundle {
val nasti = (new NastiIO).flip
val mem = new MemIO
}
require(mifDataBits == nastiXDataBits, "Data sizes between LLC and MC don't agree")
val (mif_cnt_out, mif_wrap_out) = Counter(io.mem.resp.fire(), mifDataBeats)
assert(!io.nasti.aw.valid || io.nasti.aw.bits.size === UInt(log2Up(mifDataBits/8)),
"Nasti data size does not match MemIO data size")
assert(!io.nasti.ar.valid || io.nasti.ar.bits.size === UInt(log2Up(mifDataBits/8)),
"Nasti data size does not match MemIO data size")
assert(!io.nasti.aw.valid || io.nasti.aw.bits.len === UInt(mifDataBeats - 1),
"Nasti length does not match number of MemIO beats")
assert(!io.nasti.ar.valid || io.nasti.ar.bits.len === UInt(mifDataBeats - 1),
"Nasti length does not match number of MemIO beats")
// according to the spec, we can't send b until the last transfer on w
val b_ok = Reg(init = Bool(true))
when (io.nasti.aw.fire()) { b_ok := Bool(false) }
when (io.nasti.w.fire() && io.nasti.w.bits.last) { b_ok := Bool(true) }
val id_q = Module(new Queue(UInt(width = nastiWIdBits), 2))
id_q.io.enq.valid := io.nasti.aw.valid && io.mem.req_cmd.ready
id_q.io.enq.bits := io.nasti.aw.bits.id
id_q.io.deq.ready := io.nasti.b.ready && b_ok
io.mem.req_cmd.bits.addr := Mux(io.nasti.aw.valid, io.nasti.aw.bits.addr, io.nasti.ar.bits.addr) >>
UInt(cacheBlockOffsetBits)
io.mem.req_cmd.bits.tag := Mux(io.nasti.aw.valid, io.nasti.aw.bits.id, io.nasti.ar.bits.id)
io.mem.req_cmd.bits.rw := io.nasti.aw.valid
io.mem.req_cmd.valid := (io.nasti.aw.valid && id_q.io.enq.ready) || io.nasti.ar.valid
io.nasti.ar.ready := io.mem.req_cmd.ready && !io.nasti.aw.valid
io.nasti.aw.ready := io.mem.req_cmd.ready && id_q.io.enq.ready
io.nasti.b.valid := id_q.io.deq.valid && b_ok
io.nasti.b.bits.id := id_q.io.deq.bits
io.nasti.b.bits.resp := RESP_OKAY
io.nasti.w.ready := io.mem.req_data.ready
io.mem.req_data.valid := io.nasti.w.valid
io.mem.req_data.bits.data := io.nasti.w.bits.data
assert(!io.nasti.w.valid || io.nasti.w.bits.strb.andR, "MemIO must write full cache line")
io.nasti.r.valid := io.mem.resp.valid
io.nasti.r.bits.data := io.mem.resp.bits.data
io.nasti.r.bits.last := mif_wrap_out
io.nasti.r.bits.id := io.mem.resp.bits.tag
io.nasti.r.bits.resp := RESP_OKAY
io.mem.resp.ready := io.nasti.r.ready
}
class NastiArbiterIO(arbN: Int)(implicit p: Parameters) extends Bundle {
val master = Vec(arbN, new NastiIO).flip
val slave = new NastiIO

View File

@ -23,28 +23,22 @@ class BasePlatformConfig extends Config(
(pname,site,here) => {
type PF = PartialFunction[Any,Any]
def findBy(sname:Any):Any = here[PF](site[Any](sname))(pname)
lazy val innerDataBits = 64
lazy val innerDataBeats = (8 * site(CacheBlockBytes)) / innerDataBits
lazy val edgeDataBits = site(EdgeDataBits)
lazy val edgeDataBeats = (8 * site(CacheBlockBytes)) / edgeDataBits
pname match {
//Memory Parameters
case MIFTagBits => Dump("MIF_TAG_BITS", 5)
case MIFDataBits => Dump("MIF_DATA_BITS", 64)
case MIFAddrBits => Dump("MIF_ADDR_BITS",
site(PAddrBits) - site(CacheBlockOffsetBits))
case MIFDataBeats => site(CacheBlockBytes) * 8 / site(MIFDataBits)
case NastiKey => {
Dump("MEM_STRB_BITS", site(MIFDataBits) / 8)
NastiParameters(
dataBits = Dump("MEM_DATA_BITS", site(MIFDataBits)),
addrBits = Dump("MEM_ADDR_BITS", site(PAddrBits)),
idBits = Dump("MEM_ID_BITS", site(MIFTagBits)))
}
case EdgeDataBits => 64
case EdgeIDBits => 5
case NastiKey => NastiParameters(
dataBits = edgeDataBits,
addrBits = site(PAddrBits),
idBits = site(EdgeIDBits))
case TLKey("EdgetoSlave") =>
site(TLKey("L1toL2")).copy(dataBeats = site(MIFDataBeats))
site(TLKey("L1toL2")).copy(dataBeats = edgeDataBeats)
case TLKey("MCtoEdge") =>
site(TLKey("L2toMC")).copy(dataBeats = site(MIFDataBeats))
site(TLKey("L2toMC")).copy(dataBeats = edgeDataBeats)
case TLKey("MMIOtoEdge") =>
site(TLKey("L2toMMIO")).copy(dataBeats = site(MIFDataBeats))
site(TLKey("L2toMMIO")).copy(dataBeats = edgeDataBeats)
case BuildCoreplex =>
(c: CoreplexConfig, p: Parameters) => uncore.tilelink2.LazyModule(new DefaultCoreplex(c)(p)).module
case NExtTopInterrupts => 2
@ -67,7 +61,7 @@ class BasePlatformConfig extends Config(
case HastiKey("Ext") =>
HastiParameters(
addrBits = site(PAddrBits),
dataBits = site(XLen))
dataBits = edgeDataBits)
case AsyncMemChannels => false
case NMemoryChannels => Dump("N_MEM_CHANNELS", 1)
case TMemoryChannels => BusType.AXI
@ -150,16 +144,16 @@ class DualChannelDualBankL2Config extends Config(
class RoccExampleConfig extends Config(new WithRoccExample ++ new BaseConfig)
class WithMIFDataBits(n: Int) extends Config(
class WithEdgeDataBits(dataBits: Int) extends Config(
(pname, site, here) => pname match {
case MIFDataBits => Dump("MIF_DATA_BITS", n)
case EdgeDataBits => dataBits
case _ => throw new CDEMatchError
})
class MIF128BitConfig extends Config(
new WithMIFDataBits(128) ++ new BaseConfig)
class MIF32BitConfig extends Config(
new WithMIFDataBits(32) ++ new BaseConfig)
class Edge128BitConfig extends Config(
new WithEdgeDataBits(128) ++ new BaseConfig)
class Edge32BitConfig extends Config(
new WithEdgeDataBits(32) ++ new BaseConfig)
class SmallL2Config extends Config(
new WithNMemoryChannels(2) ++ new WithNBanksPerMemChannel(4) ++

View File

@ -51,6 +51,10 @@ case object RTCPeriod extends Field[Int]
case class PeripheryBusConfig(arithAMO: Boolean, beatBytes: Int = 4)
case object PeripheryBusKey extends Field[PeripheryBusConfig]
/* Specifies the data and id width at the chip boundary */
case object EdgeDataBits extends Field[Int]
case object EdgeIDBits extends Field[Int]
object PeripheryUtils {
def addQueueAXI(source: NastiIO) = {
val sink = Wire(source)