Merge branch 'master' into rocc-fpu-port
This commit is contained in:
		@@ -52,27 +52,3 @@ class HellaCacheArbiter(n: Int) extends Module
 | 
			
		||||
    io.requestor(i).replay_next.bits := io.mem.replay_next.bits >> UInt(log2Up(n))
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class RocketUncachedTileLinkIOArbiter(n: Int) extends TileLinkArbiterLike(n) 
 | 
			
		||||
    with AppendsArbiterId {
 | 
			
		||||
  val io = new Bundle {
 | 
			
		||||
    val in = Vec.fill(n){new HeaderlessUncachedTileLinkIO}.flip
 | 
			
		||||
    val out = new HeaderlessUncachedTileLinkIO
 | 
			
		||||
  }
 | 
			
		||||
  hookupClientSourceHeaderless(io.in.map(_.acquire), io.out.acquire)
 | 
			
		||||
  hookupFinish(io.in.map(_.finish), io.out.finish)
 | 
			
		||||
  hookupManagerSourceWithId(io.in.map(_.grant), io.out.grant)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class RocketTileLinkIOArbiter(n: Int) extends TileLinkArbiterLike(n) 
 | 
			
		||||
    with AppendsArbiterId {
 | 
			
		||||
  val io = new Bundle {
 | 
			
		||||
    val in = Vec.fill(n){new HeaderlessTileLinkIO}.flip
 | 
			
		||||
    val out = new HeaderlessTileLinkIO
 | 
			
		||||
  }
 | 
			
		||||
  hookupClientSourceHeaderless(io.in.map(_.acquire), io.out.acquire)
 | 
			
		||||
  hookupClientSourceHeaderless(io.in.map(_.release), io.out.release)
 | 
			
		||||
  hookupFinish(io.in.map(_.finish), io.out.finish)
 | 
			
		||||
  hookupManagerSourceBroadcast(io.in.map(_.probe), io.out.probe)
 | 
			
		||||
  hookupManagerSourceWithId(io.in.map(_.grant), io.out.grant)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,148 +0,0 @@
 | 
			
		||||
// See LICENSE for license details.
 | 
			
		||||
 | 
			
		||||
package rocket
 | 
			
		||||
 | 
			
		||||
import Chisel._
 | 
			
		||||
import uncore._
 | 
			
		||||
import Util._
 | 
			
		||||
 | 
			
		||||
abstract class Decoding
 | 
			
		||||
{
 | 
			
		||||
  def uncorrected: Bits
 | 
			
		||||
  def corrected: Bits
 | 
			
		||||
  def correctable: Bool
 | 
			
		||||
  def uncorrectable: Bool
 | 
			
		||||
  def error = correctable || uncorrectable
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
abstract class Code
 | 
			
		||||
{
 | 
			
		||||
  def width(w0: Int): Int
 | 
			
		||||
  def encode(x: Bits): Bits
 | 
			
		||||
  def decode(x: Bits): Decoding
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class IdentityCode extends Code
 | 
			
		||||
{
 | 
			
		||||
  def width(w0: Int) = w0
 | 
			
		||||
  def encode(x: Bits) = x
 | 
			
		||||
  def decode(y: Bits) = new Decoding {
 | 
			
		||||
    def uncorrected = y
 | 
			
		||||
    def corrected = y
 | 
			
		||||
    def correctable = Bool(false)
 | 
			
		||||
    def uncorrectable = Bool(false)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ParityCode extends Code
 | 
			
		||||
{
 | 
			
		||||
  def width(w0: Int) = w0+1
 | 
			
		||||
  def encode(x: Bits) = Cat(x.xorR, x)
 | 
			
		||||
  def decode(y: Bits) = new Decoding {
 | 
			
		||||
    def uncorrected = y(y.getWidth-2,0)
 | 
			
		||||
    def corrected = uncorrected
 | 
			
		||||
    def correctable = Bool(false)
 | 
			
		||||
    def uncorrectable = y.xorR
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class SECCode extends Code
 | 
			
		||||
{
 | 
			
		||||
  def width(k: Int) = {
 | 
			
		||||
    val m = k.log2 + 1
 | 
			
		||||
    k + m + ((1 << m) < m+k+1).toInt
 | 
			
		||||
  }
 | 
			
		||||
  def encode(x: Bits) = {
 | 
			
		||||
    val k = x.getWidth
 | 
			
		||||
    require(k > 0)
 | 
			
		||||
    val n = width(k)
 | 
			
		||||
 | 
			
		||||
    val y = for (i <- 1 to n) yield {
 | 
			
		||||
      if (isPow2(i)) {
 | 
			
		||||
        val r = for (j <- 1 to n; if j != i && (j & i) != 0)
 | 
			
		||||
          yield x(mapping(j))
 | 
			
		||||
        r reduce (_^_)
 | 
			
		||||
      } else
 | 
			
		||||
        x(mapping(i))
 | 
			
		||||
    }
 | 
			
		||||
    Vec(y).toBits
 | 
			
		||||
  }
 | 
			
		||||
  def decode(y: Bits) = new Decoding {
 | 
			
		||||
    val n = y.getWidth
 | 
			
		||||
    require(n > 0 && !isPow2(n))
 | 
			
		||||
 | 
			
		||||
    val p2 = for (i <- 0 until log2Up(n)) yield 1 << i
 | 
			
		||||
    val syndrome = p2 map { i =>
 | 
			
		||||
      val r = for (j <- 1 to n; if (j & i) != 0)
 | 
			
		||||
        yield y(j-1)
 | 
			
		||||
      r reduce (_^_)
 | 
			
		||||
    }
 | 
			
		||||
    val s = Vec(syndrome).toBits
 | 
			
		||||
 | 
			
		||||
    private def swizzle(z: Bits) = Vec((1 to n).filter(i => !isPow2(i)).map(i => z(i-1))).toBits
 | 
			
		||||
    def uncorrected = swizzle(y)
 | 
			
		||||
    def corrected = swizzle(((y.toUInt << 1) ^ UIntToOH(s)) >> 1)
 | 
			
		||||
    def correctable = s.orR
 | 
			
		||||
    def uncorrectable = Bool(false)
 | 
			
		||||
  }
 | 
			
		||||
  private def mapping(i: Int) = i-1-log2Up(i)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class SECDEDCode extends Code
 | 
			
		||||
{
 | 
			
		||||
  private val sec = new SECCode
 | 
			
		||||
  private val par = new ParityCode
 | 
			
		||||
 | 
			
		||||
  def width(k: Int) = sec.width(k)+1
 | 
			
		||||
  def encode(x: Bits) = par.encode(sec.encode(x))
 | 
			
		||||
  def decode(x: Bits) = new Decoding {
 | 
			
		||||
    val secdec = sec.decode(x(x.getWidth-2,0))
 | 
			
		||||
    val pardec = par.decode(x)
 | 
			
		||||
 | 
			
		||||
    def uncorrected = secdec.uncorrected
 | 
			
		||||
    def corrected = secdec.corrected
 | 
			
		||||
    def correctable = pardec.uncorrectable
 | 
			
		||||
    def uncorrectable = !pardec.uncorrectable && secdec.correctable
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object ErrGen
 | 
			
		||||
{
 | 
			
		||||
  // generate a 1-bit error with approximate probability 2^-f
 | 
			
		||||
  def apply(width: Int, f: Int): Bits = {
 | 
			
		||||
    require(width > 0 && f >= 0 && log2Up(width) + f <= 16)
 | 
			
		||||
    UIntToOH(LFSR16()(log2Up(width)+f-1,0))(width-1,0)
 | 
			
		||||
  }
 | 
			
		||||
  def apply(x: Bits, f: Int): Bits = x ^ apply(x.getWidth, f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class SECDEDTest extends Module
 | 
			
		||||
{
 | 
			
		||||
  val code = new SECDEDCode
 | 
			
		||||
  val k = 4
 | 
			
		||||
  val n = code.width(k)
 | 
			
		||||
 | 
			
		||||
  val io = new Bundle {
 | 
			
		||||
    val original = Bits(OUTPUT, k)
 | 
			
		||||
    val encoded = Bits(OUTPUT, n)
 | 
			
		||||
    val injected = Bits(OUTPUT, n)
 | 
			
		||||
    val uncorrected = Bits(OUTPUT, k)
 | 
			
		||||
    val corrected = Bits(OUTPUT, k)
 | 
			
		||||
    val correctable = Bool(OUTPUT)
 | 
			
		||||
    val uncorrectable = Bool(OUTPUT)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  val c = Counter(Bool(true), 1 << k)
 | 
			
		||||
  val numErrors = Counter(c._2, 3)._1
 | 
			
		||||
  val e = code.encode(c._1)
 | 
			
		||||
  val i = e ^ Mux(numErrors < 1, 0, ErrGen(n, 1)) ^ Mux(numErrors < 2, 0, ErrGen(n, 1))
 | 
			
		||||
  val d = code.decode(i)
 | 
			
		||||
 | 
			
		||||
  io.original := c._1
 | 
			
		||||
  io.encoded := e
 | 
			
		||||
  io.injected := i
 | 
			
		||||
  io.uncorrected := d.uncorrected
 | 
			
		||||
  io.corrected := d.corrected
 | 
			
		||||
  io.correctable := d.correctable
 | 
			
		||||
  io.uncorrectable := d.uncorrectable
 | 
			
		||||
}
 | 
			
		||||
@@ -4,12 +4,9 @@ import Chisel._
 | 
			
		||||
import uncore._
 | 
			
		||||
import Util._
 | 
			
		||||
 | 
			
		||||
case object ECCCode extends Field[Option[Code]]
 | 
			
		||||
 | 
			
		||||
abstract trait L1CacheParameters extends CacheParameters with CoreParameters {
 | 
			
		||||
  val outerDataBeats = params(TLDataBeats)
 | 
			
		||||
  val outerDataBits = params(TLDataBits)
 | 
			
		||||
  val code = params(ECCCode).getOrElse(new IdentityCode)
 | 
			
		||||
  val refillCyclesPerBeat = outerDataBits/rowBits
 | 
			
		||||
  val refillCycles = refillCyclesPerBeat*outerDataBeats
 | 
			
		||||
}
 | 
			
		||||
@@ -44,7 +41,7 @@ class Frontend(btb_updates_out_of_order: Boolean = false) extends FrontendModule
 | 
			
		||||
  val io = new Bundle {
 | 
			
		||||
    val cpu = new CPUFrontendIO().flip
 | 
			
		||||
    val ptw = new TLBPTWIO()
 | 
			
		||||
    val mem = new HeaderlessUncachedTileLinkIO
 | 
			
		||||
    val mem = new ClientUncachedTileLinkIO
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  val btb = Module(new BTB(btb_updates_out_of_order))
 | 
			
		||||
@@ -149,7 +146,7 @@ class ICache extends FrontendModule
 | 
			
		||||
    val req = Valid(new ICacheReq).flip
 | 
			
		||||
    val resp = Decoupled(new ICacheResp)
 | 
			
		||||
    val invalidate = Bool(INPUT)
 | 
			
		||||
    val mem = new HeaderlessUncachedTileLinkIO
 | 
			
		||||
    val mem = new ClientUncachedTileLinkIO
 | 
			
		||||
  }
 | 
			
		||||
  require(isPow2(nSets) && isPow2(nWays))
 | 
			
		||||
  require(isPow2(coreInstBytes))
 | 
			
		||||
@@ -190,15 +187,10 @@ class ICache extends FrontendModule
 | 
			
		||||
  val s2_miss = s2_valid && !s2_any_tag_hit
 | 
			
		||||
  rdy := state === s_ready && !s2_miss
 | 
			
		||||
 | 
			
		||||
  val ser = Module(new FlowThroughSerializer(
 | 
			
		||||
                          io.mem.grant.bits,
 | 
			
		||||
                          refillCyclesPerBeat))
 | 
			
		||||
  ser.io.in <> io.mem.grant
 | 
			
		||||
  val (refill_cnt, refill_wrap) = Counter(ser.io.out.fire(), refillCycles) //TODO Zero width wire
 | 
			
		||||
  val narrow_grant = FlowThroughSerializer(io.mem.grant, refillCyclesPerBeat)
 | 
			
		||||
  val (refill_cnt, refill_wrap) = Counter(narrow_grant.fire(), refillCycles) //TODO Zero width wire
 | 
			
		||||
  val refill_done = state === s_refill && refill_wrap
 | 
			
		||||
  val refill_valid = ser.io.out.valid
 | 
			
		||||
  val refill_bits = ser.io.out.bits
 | 
			
		||||
  ser.io.out.ready := Bool(true)
 | 
			
		||||
  narrow_grant.ready := Bool(true)
 | 
			
		||||
 | 
			
		||||
  val repl_way = if (isDM) UInt(0) else LFSR16(s2_miss)(log2Up(nWays)-1,0)
 | 
			
		||||
  val entagbits = code.width(tagBits)
 | 
			
		||||
@@ -250,9 +242,9 @@ class ICache extends FrontendModule
 | 
			
		||||
  for (i <- 0 until nWays) {
 | 
			
		||||
    val data_array = Mem(Bits(width = code.width(rowBits)), nSets*refillCycles, seqRead = true)
 | 
			
		||||
    val s1_raddr = Reg(UInt())
 | 
			
		||||
    when (refill_valid && repl_way === UInt(i)) {
 | 
			
		||||
      val e_d = code.encode(refill_bits.payload.data)
 | 
			
		||||
      if(refillCycles > 1) data_array(Cat(s2_idx, refill_bits.payload.addr_beat)) := e_d
 | 
			
		||||
    when (narrow_grant.valid && repl_way === UInt(i)) {
 | 
			
		||||
      val e_d = code.encode(narrow_grant.bits.data)
 | 
			
		||||
      if(refillCycles > 1) data_array(Cat(s2_idx, refill_cnt)) := e_d
 | 
			
		||||
      else data_array(s2_idx) := e_d
 | 
			
		||||
    }
 | 
			
		||||
//    /*.else*/when (s0_valid) { // uncomment ".else" to infer 6T SRAM
 | 
			
		||||
@@ -266,16 +258,10 @@ class ICache extends FrontendModule
 | 
			
		||||
  io.resp.bits.data := Mux1H(s2_tag_hit, s2_dout_word)
 | 
			
		||||
  io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout)
 | 
			
		||||
 | 
			
		||||
  val ack_q = Module(new Queue(new LogicalNetworkIO(new Finish), 1))
 | 
			
		||||
  ack_q.io.enq.valid := refill_done && refill_bits.payload.requiresAck()
 | 
			
		||||
  ack_q.io.enq.bits.payload := refill_bits.payload.makeFinish()
 | 
			
		||||
  ack_q.io.enq.bits.header.dst := refill_bits.header.src
 | 
			
		||||
 | 
			
		||||
  // output signals
 | 
			
		||||
  io.resp.valid := s2_hit
 | 
			
		||||
  io.mem.acquire.valid := (state === s_request) && ack_q.io.enq.ready
 | 
			
		||||
  io.mem.acquire.valid := (state === s_request)
 | 
			
		||||
  io.mem.acquire.bits := GetBlock(addr_block = s2_addr >> UInt(blockOffBits))
 | 
			
		||||
  io.mem.finish <> ack_q.io.deq
 | 
			
		||||
 | 
			
		||||
  // control state machine
 | 
			
		||||
  switch (state) {
 | 
			
		||||
@@ -284,7 +270,7 @@ class ICache extends FrontendModule
 | 
			
		||||
      invalidated := Bool(false)
 | 
			
		||||
    }
 | 
			
		||||
    is (s_request) {
 | 
			
		||||
      when (io.mem.acquire.ready && ack_q.io.enq.ready) { state := s_refill_wait }
 | 
			
		||||
      when (io.mem.acquire.ready) { state := s_refill_wait }
 | 
			
		||||
    }
 | 
			
		||||
    is (s_refill_wait) {
 | 
			
		||||
      when (io.mem.grant.valid) { state := s_refill }
 | 
			
		||||
 
 | 
			
		||||
@@ -97,6 +97,8 @@ class L1DataWriteReq extends L1DataReadReq {
 | 
			
		||||
  val data   = Bits(width = encRowBits)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class L1RefillReq extends L1DataReadReq
 | 
			
		||||
 | 
			
		||||
class L1MetaReadReq extends MetaReadReq {
 | 
			
		||||
  val tag = Bits(width = tagBits)
 | 
			
		||||
}
 | 
			
		||||
@@ -140,12 +142,11 @@ class MSHR(id: Int) extends L1HellaCacheModule {
 | 
			
		||||
    val tag             = Bits(OUTPUT, tagBits)
 | 
			
		||||
 | 
			
		||||
    val mem_req  = Decoupled(new Acquire)
 | 
			
		||||
    val mem_resp = new L1DataWriteReq().asOutput
 | 
			
		||||
    val refill = new L1RefillReq().asOutput // Data is bypassed
 | 
			
		||||
    val meta_read = Decoupled(new L1MetaReadReq)
 | 
			
		||||
    val meta_write = Decoupled(new L1MetaWriteReq)
 | 
			
		||||
    val replay = Decoupled(new ReplayInternal)
 | 
			
		||||
    val mem_grant = Valid(new LogicalNetworkIO(new Grant)).flip
 | 
			
		||||
    val mem_finish = Decoupled(new LogicalNetworkIO(new Finish))
 | 
			
		||||
    val mem_grant = Valid(new Grant).flip
 | 
			
		||||
    val wb_req = Decoupled(new WritebackReq)
 | 
			
		||||
    val probe_rdy = Bool(OUTPUT)
 | 
			
		||||
  }
 | 
			
		||||
@@ -168,11 +169,9 @@ class MSHR(id: Int) extends L1HellaCacheModule {
 | 
			
		||||
                  (states_before_refill.contains(state) ||
 | 
			
		||||
                    (Vec(s_refill_req, s_refill_resp).contains(state) &&
 | 
			
		||||
                      !cmd_requires_second_acquire))
 | 
			
		||||
  val reply = io.mem_grant.valid && io.mem_grant.bits.payload.client_xact_id === UInt(id)
 | 
			
		||||
  val gnt_multi_data = io.mem_grant.bits.payload.hasMultibeatData()
 | 
			
		||||
  val (refill_cnt, refill_count_done) = Counter(reply && gnt_multi_data, refillCycles) // TODO: Zero width?
 | 
			
		||||
  val refill_done = reply && (!gnt_multi_data || refill_count_done)
 | 
			
		||||
  val wb_done = reply && (state === s_wb_resp)
 | 
			
		||||
  val gnt_multi_data = io.mem_grant.bits.hasMultibeatData()
 | 
			
		||||
  val (refill_cnt, refill_count_done) = Counter(io.mem_grant.valid && gnt_multi_data, refillCycles) // TODO: Zero width?
 | 
			
		||||
  val refill_done = io.mem_grant.valid && (!gnt_multi_data || refill_count_done)
 | 
			
		||||
 | 
			
		||||
  val rpq = Module(new Queue(new ReplayInternal, params(ReplayQueueDepth)))
 | 
			
		||||
  rpq.io.enq.valid := (io.req_pri_val && io.req_pri_rdy || io.req_sec_val && sec_rdy) && !isPrefetch(io.req_bits.cmd)
 | 
			
		||||
@@ -180,7 +179,7 @@ class MSHR(id: Int) extends L1HellaCacheModule {
 | 
			
		||||
  rpq.io.deq.ready := io.replay.ready && state === s_drain_rpq || state === s_invalid
 | 
			
		||||
 | 
			
		||||
  val coh_on_grant = req.old_meta.coh.onGrant(
 | 
			
		||||
                          incoming = io.mem_grant.bits.payload,
 | 
			
		||||
                          incoming = io.mem_grant.bits,
 | 
			
		||||
                          pending = req.cmd)
 | 
			
		||||
  val coh_on_hit =  io.req_bits.old_meta.coh.onHit(io.req_bits.cmd)
 | 
			
		||||
 | 
			
		||||
@@ -195,7 +194,7 @@ class MSHR(id: Int) extends L1HellaCacheModule {
 | 
			
		||||
    state := s_meta_write_resp
 | 
			
		||||
  }
 | 
			
		||||
  when (state === s_refill_resp) {
 | 
			
		||||
    when (reply) { new_coh_state := coh_on_grant }
 | 
			
		||||
    when (io.mem_grant.valid) { new_coh_state := coh_on_grant }
 | 
			
		||||
    when (refill_done) { state := s_meta_write_req }
 | 
			
		||||
  }
 | 
			
		||||
  when (io.mem_req.fire()) { // s_refill_req
 | 
			
		||||
@@ -204,7 +203,7 @@ class MSHR(id: Int) extends L1HellaCacheModule {
 | 
			
		||||
  when (state === s_meta_clear && io.meta_write.ready) {
 | 
			
		||||
    state := s_refill_req
 | 
			
		||||
  }
 | 
			
		||||
  when (state === s_wb_resp && reply) {
 | 
			
		||||
  when (state === s_wb_resp && io.mem_grant.valid) {
 | 
			
		||||
    state := s_meta_clear
 | 
			
		||||
  }
 | 
			
		||||
  when (io.wb_req.fire()) { // s_wb_req
 | 
			
		||||
@@ -233,18 +232,9 @@ class MSHR(id: Int) extends L1HellaCacheModule {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  val ackq = Module(new Queue(new LogicalNetworkIO(new Finish), 1))
 | 
			
		||||
  ackq.io.enq.valid := (wb_done || refill_done) && io.mem_grant.bits.payload.requiresAck()
 | 
			
		||||
  ackq.io.enq.bits.payload := io.mem_grant.bits.payload.makeFinish()
 | 
			
		||||
  ackq.io.enq.bits.header.dst := io.mem_grant.bits.header.src
 | 
			
		||||
  val can_finish = state === s_invalid || state === s_refill_req || state === s_refill_resp
 | 
			
		||||
  io.mem_finish.valid := ackq.io.deq.valid && can_finish
 | 
			
		||||
  ackq.io.deq.ready := io.mem_finish.ready && can_finish
 | 
			
		||||
  io.mem_finish.bits := ackq.io.deq.bits
 | 
			
		||||
 | 
			
		||||
  io.idx_match := (state != s_invalid) && idx_match
 | 
			
		||||
  io.mem_resp := req
 | 
			
		||||
  io.mem_resp.addr := (if(refillCycles > 1) Cat(req_idx, refill_cnt) else req_idx) << rowOffBits
 | 
			
		||||
  io.refill.way_en := req.way_en
 | 
			
		||||
  io.refill.addr := (if(refillCycles > 1) Cat(req_idx, refill_cnt) else req_idx) << rowOffBits
 | 
			
		||||
  io.tag := req.addr >> untagBits
 | 
			
		||||
  io.req_pri_rdy := state === s_invalid
 | 
			
		||||
  io.req_sec_rdy := sec_rdy && rpq.io.enq.ready
 | 
			
		||||
@@ -262,18 +252,17 @@ class MSHR(id: Int) extends L1HellaCacheModule {
 | 
			
		||||
  io.meta_write.bits.data.tag := io.tag
 | 
			
		||||
  io.meta_write.bits.way_en := req.way_en
 | 
			
		||||
 | 
			
		||||
  io.wb_req.valid := state === s_wb_req && ackq.io.enq.ready
 | 
			
		||||
  io.wb_req.valid := state === s_wb_req
 | 
			
		||||
  io.wb_req.bits := req.old_meta.coh.makeVoluntaryWriteback(
 | 
			
		||||
                      client_xact_id = UInt(id),
 | 
			
		||||
                      addr_block = Cat(req.old_meta.tag, req_idx))
 | 
			
		||||
  io.wb_req.bits.way_en := req.way_en
 | 
			
		||||
 | 
			
		||||
  io.mem_req.valid := state === s_refill_req && ackq.io.enq.ready
 | 
			
		||||
  io.mem_req.valid := state === s_refill_req
 | 
			
		||||
  io.mem_req.bits := req.old_meta.coh.makeAcquire(
 | 
			
		||||
                       addr_block = Cat(io.tag, req_idx).toUInt,
 | 
			
		||||
                       client_xact_id = Bits(id),
 | 
			
		||||
                       op_code = req.cmd)
 | 
			
		||||
  io.mem_finish <> ackq.io.deq
 | 
			
		||||
 | 
			
		||||
  io.meta_read.valid := state === s_drain_rpq
 | 
			
		||||
  io.meta_read.bits.idx := req_idx
 | 
			
		||||
@@ -295,13 +284,12 @@ class MSHRFile extends L1HellaCacheModule {
 | 
			
		||||
    val req = Decoupled(new MSHRReq).flip
 | 
			
		||||
    val secondary_miss = Bool(OUTPUT)
 | 
			
		||||
 | 
			
		||||
    val mem_req  = Decoupled(new Acquire) //TODO make sure TLParameters are correct ?????
 | 
			
		||||
    val mem_resp = new L1DataWriteReq().asOutput
 | 
			
		||||
    val mem_req  = Decoupled(new Acquire)
 | 
			
		||||
    val refill = new L1RefillReq().asOutput
 | 
			
		||||
    val meta_read = Decoupled(new L1MetaReadReq)
 | 
			
		||||
    val meta_write = Decoupled(new L1MetaWriteReq)
 | 
			
		||||
    val replay = Decoupled(new Replay)
 | 
			
		||||
    val mem_grant = Valid(new LogicalNetworkIO(new Grant)).flip
 | 
			
		||||
    val mem_finish = Decoupled(new LogicalNetworkIO(new Finish))
 | 
			
		||||
    val mem_grant = Valid(new Grant).flip
 | 
			
		||||
    val wb_req = Decoupled(new WritebackReq)
 | 
			
		||||
 | 
			
		||||
    val probe_rdy = Bool(OUTPUT)
 | 
			
		||||
@@ -320,7 +308,7 @@ class MSHRFile extends L1HellaCacheModule {
 | 
			
		||||
  val tag_match = Mux1H(idxMatch, tagList) === io.req.bits.addr >> untagBits
 | 
			
		||||
 | 
			
		||||
  val wbTagList = Vec.fill(nMSHRs){Bits()}
 | 
			
		||||
  val memRespMux = Vec.fill(nMSHRs){new L1DataWriteReq}
 | 
			
		||||
  val refillMux = Vec.fill(nMSHRs){new L1RefillReq}
 | 
			
		||||
  val meta_read_arb = Module(new Arbiter(new L1MetaReadReq, nMSHRs))
 | 
			
		||||
  val meta_write_arb = Module(new Arbiter(new L1MetaWriteReq, nMSHRs))
 | 
			
		||||
  val mem_req_arb = Module(new LockingArbiter(
 | 
			
		||||
@@ -328,7 +316,6 @@ class MSHRFile extends L1HellaCacheModule {
 | 
			
		||||
                                  nMSHRs,
 | 
			
		||||
                                  outerDataBeats,
 | 
			
		||||
                                  (a: Acquire) => a.hasMultibeatData()))
 | 
			
		||||
  val mem_finish_arb = Module(new Arbiter(new LogicalNetworkIO(new Finish), nMSHRs))
 | 
			
		||||
  val wb_req_arb = Module(new Arbiter(new WritebackReq, nMSHRs))
 | 
			
		||||
  val replay_arb = Module(new Arbiter(new ReplayInternal, nMSHRs))
 | 
			
		||||
  val alloc_arb = Module(new Arbiter(Bool(), nMSHRs))
 | 
			
		||||
@@ -357,12 +344,13 @@ class MSHRFile extends L1HellaCacheModule {
 | 
			
		||||
    mshr.io.meta_read <> meta_read_arb.io.in(i)
 | 
			
		||||
    mshr.io.meta_write <> meta_write_arb.io.in(i)
 | 
			
		||||
    mshr.io.mem_req <> mem_req_arb.io.in(i)
 | 
			
		||||
    mshr.io.mem_finish <> mem_finish_arb.io.in(i)
 | 
			
		||||
    mshr.io.wb_req <> wb_req_arb.io.in(i)
 | 
			
		||||
    mshr.io.replay <> replay_arb.io.in(i)
 | 
			
		||||
 | 
			
		||||
    mshr.io.mem_grant <> io.mem_grant
 | 
			
		||||
    memRespMux(i) := mshr.io.mem_resp
 | 
			
		||||
    mshr.io.mem_grant.valid := io.mem_grant.valid &&
 | 
			
		||||
                                 io.mem_grant.bits.client_xact_id === UInt(i)
 | 
			
		||||
    mshr.io.mem_grant.bits := io.mem_grant.bits
 | 
			
		||||
    refillMux(i) := mshr.io.refill
 | 
			
		||||
 | 
			
		||||
    pri_rdy = pri_rdy || mshr.io.req_pri_rdy
 | 
			
		||||
    sec_rdy = sec_rdy || mshr.io.req_sec_rdy
 | 
			
		||||
@@ -377,12 +365,11 @@ class MSHRFile extends L1HellaCacheModule {
 | 
			
		||||
  meta_read_arb.io.out <> io.meta_read
 | 
			
		||||
  meta_write_arb.io.out <> io.meta_write
 | 
			
		||||
  mem_req_arb.io.out <> io.mem_req
 | 
			
		||||
  mem_finish_arb.io.out <> io.mem_finish
 | 
			
		||||
  wb_req_arb.io.out <> io.wb_req
 | 
			
		||||
 | 
			
		||||
  io.req.ready := Mux(idx_match, tag_match && sec_rdy, pri_rdy) && sdq_rdy
 | 
			
		||||
  io.secondary_miss := idx_match
 | 
			
		||||
  io.mem_resp := memRespMux(io.mem_grant.bits.payload.client_xact_id)
 | 
			
		||||
  io.refill := refillMux(io.mem_grant.bits.client_xact_id)
 | 
			
		||||
 | 
			
		||||
  val free_sdq = io.replay.fire() && isWrite(io.replay.bits.cmd)
 | 
			
		||||
  io.replay.bits.data := sdq(RegEnable(replay_arb.io.out.bits.sdq_id, free_sdq))
 | 
			
		||||
@@ -597,7 +584,7 @@ class HellaCache extends L1HellaCacheModule {
 | 
			
		||||
  val io = new Bundle {
 | 
			
		||||
    val cpu = (new HellaCacheIO).flip
 | 
			
		||||
    val ptw = new TLBPTWIO()
 | 
			
		||||
    val mem = new HeaderlessTileLinkIO
 | 
			
		||||
    val mem = new ClientTileLinkIO
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
  require(params(LRSCCycles) >= 32) // ISA requires 16-insn LRSC sequences to succeed
 | 
			
		||||
@@ -806,7 +793,6 @@ class HellaCache extends L1HellaCacheModule {
 | 
			
		||||
  mshrs.io.req.bits.way_en := Mux(s2_tag_match, s2_tag_match_way, s2_replaced_way_en)
 | 
			
		||||
  mshrs.io.req.bits.data := s2_req.data
 | 
			
		||||
  when (mshrs.io.req.fire()) { replacer.miss }
 | 
			
		||||
 | 
			
		||||
  io.mem.acquire <> mshrs.io.mem_req
 | 
			
		||||
 | 
			
		||||
  // replays
 | 
			
		||||
@@ -822,10 +808,9 @@ class HellaCache extends L1HellaCacheModule {
 | 
			
		||||
  val releaseArb = Module(new LockingArbiter(new Release, 2, outerDataBeats, (r: Release) => r.hasMultibeatData()))
 | 
			
		||||
  releaseArb.io.out <> io.mem.release
 | 
			
		||||
 | 
			
		||||
  val probe = DecoupledLogicalNetworkIOUnwrapper(io.mem.probe)
 | 
			
		||||
  prober.io.req.valid := probe.valid && !lrsc_valid
 | 
			
		||||
  probe.ready := prober.io.req.ready && !lrsc_valid
 | 
			
		||||
  prober.io.req.bits := probe.bits
 | 
			
		||||
  prober.io.req.valid := io.mem.probe.valid && !lrsc_valid
 | 
			
		||||
  io.mem.probe.ready := prober.io.req.ready && !lrsc_valid
 | 
			
		||||
  prober.io.req.bits := io.mem.probe.bits
 | 
			
		||||
  prober.io.rep <> releaseArb.io.in(1)
 | 
			
		||||
  prober.io.way_en := s2_tag_match_way
 | 
			
		||||
  prober.io.block_state := s2_hit_state
 | 
			
		||||
@@ -834,19 +819,16 @@ class HellaCache extends L1HellaCacheModule {
 | 
			
		||||
  prober.io.mshr_rdy := mshrs.io.probe_rdy
 | 
			
		||||
 | 
			
		||||
  // refills
 | 
			
		||||
  val ser = Module(new FlowThroughSerializer(
 | 
			
		||||
                          io.mem.grant.bits,
 | 
			
		||||
                          refillCyclesPerBeat))
 | 
			
		||||
  ser.io.in <> io.mem.grant
 | 
			
		||||
  val refill = ser.io.out
 | 
			
		||||
  mshrs.io.mem_grant.valid := refill.fire()
 | 
			
		||||
  mshrs.io.mem_grant.bits := refill.bits
 | 
			
		||||
  refill.ready := writeArb.io.in(1).ready || !refill.bits.payload.hasData()
 | 
			
		||||
  writeArb.io.in(1).valid := refill.valid && refill.bits.payload.hasData()
 | 
			
		||||
  writeArb.io.in(1).bits := mshrs.io.mem_resp
 | 
			
		||||
  val narrow_grant = FlowThroughSerializer(io.mem.grant, refillCyclesPerBeat)
 | 
			
		||||
  mshrs.io.mem_grant.valid := narrow_grant.fire()
 | 
			
		||||
  mshrs.io.mem_grant.bits := narrow_grant.bits
 | 
			
		||||
  narrow_grant.ready := writeArb.io.in(1).ready || !narrow_grant.bits.hasData()
 | 
			
		||||
  writeArb.io.in(1).valid := narrow_grant.valid && narrow_grant.bits.hasData()
 | 
			
		||||
  writeArb.io.in(1).bits.addr := mshrs.io.refill.addr
 | 
			
		||||
  writeArb.io.in(1).bits.way_en := mshrs.io.refill.way_en
 | 
			
		||||
  writeArb.io.in(1).bits.wmask := SInt(-1)
 | 
			
		||||
  writeArb.io.in(1).bits.data := refill.bits.payload.data(encRowBits-1,0)
 | 
			
		||||
  readArb.io.out.ready := !refill.valid || refill.ready // insert bubble if refill gets blocked
 | 
			
		||||
  writeArb.io.in(1).bits.data := narrow_grant.bits.data(encRowBits-1,0)
 | 
			
		||||
  readArb.io.out.ready := !narrow_grant.valid || narrow_grant.ready // insert bubble if refill gets blocked
 | 
			
		||||
  readArb.io.out <> data.io.read
 | 
			
		||||
 | 
			
		||||
  // writebacks
 | 
			
		||||
@@ -920,8 +902,6 @@ class HellaCache extends L1HellaCacheModule {
 | 
			
		||||
 | 
			
		||||
  io.cpu.replay_next.valid := s1_replay && (s1_read || s1_sc)
 | 
			
		||||
  io.cpu.replay_next.bits := s1_req.tag
 | 
			
		||||
 | 
			
		||||
  io.mem.finish <> mshrs.io.mem_finish
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// exposes a sane decoupled request interface
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ import Node._
 | 
			
		||||
import uncore._
 | 
			
		||||
import Util._
 | 
			
		||||
 | 
			
		||||
case object RoCCMemTagBits extends Field[Int]
 | 
			
		||||
case object RoCCMaxTaggedMemXacts extends Field[Int]
 | 
			
		||||
 | 
			
		||||
class RoCCInstruction extends Bundle
 | 
			
		||||
{
 | 
			
		||||
@@ -44,8 +44,8 @@ class RoCCInterface extends Bundle
 | 
			
		||||
  val interrupt = Bool(OUTPUT)
 | 
			
		||||
  
 | 
			
		||||
  // These should be handled differently, eventually
 | 
			
		||||
  val imem = new HeaderlessUncachedTileLinkIO
 | 
			
		||||
  val dmem = new HeaderlessUncachedTileLinkIO
 | 
			
		||||
  val imem = new ClientUncachedTileLinkIO
 | 
			
		||||
  val dmem = new ClientUncachedTileLinkIO
 | 
			
		||||
  val iptw = new TLBPTWIO
 | 
			
		||||
  val dptw = new TLBPTWIO
 | 
			
		||||
  val pptw = new TLBPTWIO
 | 
			
		||||
@@ -129,10 +129,8 @@ class AccumulatorExample extends RoCC
 | 
			
		||||
 | 
			
		||||
  io.imem.acquire.valid := false
 | 
			
		||||
  io.imem.grant.ready := false
 | 
			
		||||
  io.imem.finish.valid := false
 | 
			
		||||
  io.dmem.acquire.valid := false
 | 
			
		||||
  io.dmem.grant.ready := false
 | 
			
		||||
  io.dmem.finish.valid := false
 | 
			
		||||
  io.iptw.req.valid := false
 | 
			
		||||
  io.dptw.req.valid := false
 | 
			
		||||
  io.pptw.req.valid := false
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,8 @@ case object BuildRoCC extends Field[Option[() => RoCC]]
 | 
			
		||||
 | 
			
		||||
abstract class Tile(resetSignal: Bool = null) extends Module(_reset = resetSignal) {
 | 
			
		||||
  val io = new Bundle {
 | 
			
		||||
    val cached = new HeaderlessTileLinkIO
 | 
			
		||||
    val uncached = new HeaderlessUncachedTileLinkIO
 | 
			
		||||
    val cached = new ClientTileLinkIO
 | 
			
		||||
    val uncached = new ClientUncachedTileLinkIO
 | 
			
		||||
    val host = new HTIFIO
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -44,7 +44,7 @@ class RocketTile(resetSignal: Bool = null) extends Tile(resetSignal) {
 | 
			
		||||
  // otherwise, just hookup the icache
 | 
			
		||||
  io.uncached <> params(BuildRoCC).map { buildItHere =>
 | 
			
		||||
    val rocc = buildItHere()
 | 
			
		||||
    val memArb = Module(new RocketUncachedTileLinkIOArbiter(3))
 | 
			
		||||
    val memArb = Module(new ClientTileLinkIOArbiter(3))
 | 
			
		||||
    val dcIF = Module(new SimpleHellaCacheIF)
 | 
			
		||||
    core.io.rocc <> rocc.io
 | 
			
		||||
    dcIF.io.requestor <> rocc.io.mem
 | 
			
		||||
 
 | 
			
		||||
@@ -6,14 +6,6 @@ import Chisel._
 | 
			
		||||
import uncore._
 | 
			
		||||
import scala.math._
 | 
			
		||||
 | 
			
		||||
class Unsigned(x: Int) {
 | 
			
		||||
  require(x >= 0)
 | 
			
		||||
  def clog2: Int = { require(x > 0); ceil(log(x)/log(2)).toInt }
 | 
			
		||||
  def log2: Int = { require(x > 0); floor(log(x)/log(2)).toInt }
 | 
			
		||||
  def isPow2: Boolean = x > 0 && (x & (x-1)) == 0
 | 
			
		||||
  def nextPow2: Int = if (x == 0) 1 else 1 << clog2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object Util {
 | 
			
		||||
  implicit def intToUInt(x: Int): UInt = UInt(x)
 | 
			
		||||
  implicit def booleanToBool(x: Boolean): Bits = Bool(x)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user