1
0

add ecc support to d$ data rams

i haven't injected errors yet; it may well be incorrect.
This commit is contained in:
Andrew Waterman 2012-12-11 15:58:53 -08:00
parent 3f59e439ef
commit f5c53ce35d
3 changed files with 95 additions and 62 deletions

View File

@ -51,9 +51,7 @@ class ALU(implicit conf: RocketConfiguration) extends Component
val io = new ALUIO val io = new ALUIO
// ADD, SUB // ADD, SUB
val sub = isSub(io.fn) val sum = io.in1 + Mux(isSub(io.fn), -io.in2, io.in2)
val adder_rhs = Mux(sub, ~io.in2, io.in2)
val sum = (io.in1 + adder_rhs + sub.toUFix)(63,0)
// SLT, SLTU // SLT, SLTU
val less = Mux(io.in1(63) === io.in2(63), sum(63), val less = Mux(io.in1(63) === io.in2(63), sum(63),

View File

@ -8,8 +8,9 @@ import Util._
case class DCacheConfig(sets: Int, ways: Int, co: CoherencePolicy, case class DCacheConfig(sets: Int, ways: Int, co: CoherencePolicy,
nmshr: Int, nrpq: Int, nsdq: Int, ntlb: Int, nmshr: Int, nrpq: Int, nsdq: Int, ntlb: Int,
reqtagbits: Int = -1, databits: Int = -1, code: Code = new IdentityCode,
narrowRead: Boolean = true) narrowRead: Boolean = true,
reqtagbits: Int = -1, databits: Int = -1)
{ {
require(isPow2(sets)) require(isPow2(sets))
require(isPow2(ways)) // TODO: relax this require(isPow2(ways)) // TODO: relax this
@ -29,6 +30,12 @@ case class DCacheConfig(sets: Int, ways: Int, co: CoherencePolicy,
def databytes = databits/8 def databytes = databits/8
def wordoffbits = log2Up(databytes) def wordoffbits = log2Up(databytes)
def isNarrowRead = narrowRead && databits*ways % MEM_DATA_BITS == 0 def isNarrowRead = narrowRead && databits*ways % MEM_DATA_BITS == 0
val statebits = 2 // TODO: obtain from coherence policy
val metabits = statebits + tagbits
val encdatabits = code.width(databits)
val encmetabits = code.width(metabits)
val wordsperrow = MEM_DATA_BITS/databits
val bitsperrow = wordsperrow*encdatabits
} }
abstract class ReplacementPolicy abstract class ReplacementPolicy
@ -110,8 +117,8 @@ class DataReadReq(implicit conf: DCacheConfig) extends Bundle {
class DataWriteReq(implicit conf: DCacheConfig) extends Bundle { class DataWriteReq(implicit conf: DCacheConfig) extends Bundle {
val way_en = Bits(width = conf.ways) val way_en = Bits(width = conf.ways)
val addr = Bits(width = conf.untagbits) val addr = Bits(width = conf.untagbits)
val wmask = Bits(width = MEM_DATA_BITS/conf.databits) val wmask = Bits(width = conf.wordsperrow)
val data = Bits(width = MEM_DATA_BITS) val data = Bits(width = conf.bitsperrow)
override def clone = new DataWriteReq().asInstanceOf[this.type] override def clone = new DataWriteReq().asInstanceOf[this.type]
} }
@ -126,7 +133,7 @@ class WritebackReq(implicit conf: DCacheConfig) extends Bundle {
} }
class MetaData(implicit conf: DCacheConfig) extends Bundle { class MetaData(implicit conf: DCacheConfig) extends Bundle {
val state = UFix(width = 2) val state = UFix(width = conf.statebits)
val tag = Bits(width = conf.tagbits) val tag = Bits(width = conf.tagbits)
override def clone = new MetaData().asInstanceOf[this.type] override def clone = new MetaData().asInstanceOf[this.type]
@ -413,7 +420,7 @@ class WritebackUnit(implicit conf: DCacheConfig) extends Component {
val probe = (new FIFOIO) { new WritebackReq() }.flip val probe = (new FIFOIO) { new WritebackReq() }.flip
val meta_read = (new FIFOIO) { new MetaReadReq } val meta_read = (new FIFOIO) { new MetaReadReq }
val data_req = (new FIFOIO) { new DataReadReq() } val data_req = (new FIFOIO) { new DataReadReq() }
val data_resp = Bits(INPUT, MEM_DATA_BITS) val data_resp = Bits(INPUT, conf.bitsperrow)
val mem_req = (new FIFOIO) { new TransactionInit } val mem_req = (new FIFOIO) { new TransactionInit }
val mem_req_data = (new FIFOIO) { new TransactionInitData } val mem_req_data = (new FIFOIO) { new TransactionInitData }
val probe_rep_data = (new FIFOIO) { new ProbeReplyData } val probe_rep_data = (new FIFOIO) { new ProbeReplyData }
@ -430,7 +437,7 @@ class WritebackUnit(implicit conf: DCacheConfig) extends Component {
when (valid) { when (valid) {
r1_data_req_fired := false r1_data_req_fired := false
r2_data_req_fired := r1_data_req_fired r2_data_req_fired := r1_data_req_fired
when (io.data_req.fire()) { when (io.data_req.fire() && io.meta_read.fire()) {
r1_data_req_fired := true r1_data_req_fired := true
cnt := cnt + 1 cnt := cnt + 1
} }
@ -467,7 +474,7 @@ class WritebackUnit(implicit conf: DCacheConfig) extends Component {
val fire = valid && cnt < UFix(REFILL_CYCLES) val fire = valid && cnt < UFix(REFILL_CYCLES)
io.req.ready := !valid && !io.probe.valid io.req.ready := !valid && !io.probe.valid
io.probe.ready := !valid io.probe.ready := !valid
io.data_req.valid := fire && io.meta_read.ready io.data_req.valid := fire
io.data_req.bits.way_en := req.way_en io.data_req.bits.way_en := req.way_en
io.data_req.bits.addr := Cat(req.idx, cnt(log2Up(REFILL_CYCLES)-1,0)) << conf.ramoffbits io.data_req.bits.addr := Cat(req.idx, cnt(log2Up(REFILL_CYCLES)-1,0)) << conf.ramoffbits
@ -480,7 +487,7 @@ class WritebackUnit(implicit conf: DCacheConfig) extends Component {
io.probe_rep_data.valid := r2_data_req_fired && is_probe io.probe_rep_data.valid := r2_data_req_fired && is_probe
io.probe_rep_data.bits.data := io.data_resp io.probe_rep_data.bits.data := io.data_resp
io.meta_read.valid := fire && io.data_req.ready io.meta_read.valid := fire
io.meta_read.bits.addr := io.mem_req.bits.addr << conf.offbits io.meta_read.bits.addr := io.mem_req.bits.addr << conf.offbits
} }
@ -594,32 +601,31 @@ class DataArray(implicit conf: DCacheConfig) extends Component {
val io = new Bundle { val io = new Bundle {
val read = new FIFOIO()(new DataReadReq).flip val read = new FIFOIO()(new DataReadReq).flip
val write = new FIFOIO()(new DataWriteReq).flip val write = new FIFOIO()(new DataWriteReq).flip
val resp = Vec(conf.ways){ Bits(OUTPUT, MEM_DATA_BITS) } val resp = Vec(conf.ways){ Bits(OUTPUT, conf.bitsperrow) }
} }
val waddr = io.write.bits.addr >> conf.ramoffbits val waddr = io.write.bits.addr >> conf.ramoffbits
val raddr = io.read.bits.addr >> conf.ramoffbits val raddr = io.read.bits.addr >> conf.ramoffbits
if (conf.isNarrowRead) { if (conf.isNarrowRead) {
val waysPerMem = MEM_DATA_BITS/conf.databits for (w <- 0 until conf.ways by conf.wordsperrow) {
for (w <- 0 until conf.ways by waysPerMem) { val wway_en = io.write.bits.way_en(w+conf.wordsperrow-1,w)
val wway_en = io.write.bits.way_en(w+waysPerMem-1,w) val rway_en = io.read.bits.way_en(w+conf.wordsperrow-1,w)
val rway_en = io.read.bits.way_en(w+waysPerMem-1,w) val resp = Vec(conf.wordsperrow){Reg{Bits(width = conf.bitsperrow)}}
val resp = Vec(MEM_DATA_BITS/conf.databits){Reg{Bits(width = MEM_DATA_BITS)}}
val r_raddr = RegEn(io.read.bits.addr, io.read.valid) val r_raddr = RegEn(io.read.bits.addr, io.read.valid)
for (p <- 0 until resp.size) { for (p <- 0 until resp.size) {
val array = Mem(conf.sets*REFILL_CYCLES, seqRead = true){ Bits(width=MEM_DATA_BITS) } val array = Mem(conf.sets*REFILL_CYCLES, seqRead = true){ Bits(width=conf.bitsperrow) }
when (wway_en.orR && io.write.valid && io.write.bits.wmask(p)) { when (wway_en.orR && io.write.valid && io.write.bits.wmask(p)) {
val data = Fill(waysPerMem, io.write.bits.data(conf.databits*(p+1)-1,conf.databits*p)) val data = Fill(conf.wordsperrow, io.write.bits.data(conf.encdatabits*(p+1)-1,conf.encdatabits*p))
val mask = FillInterleaved(conf.databits, wway_en) val mask = FillInterleaved(conf.encdatabits, wway_en)
array.write(waddr, data, mask) array.write(waddr, data, mask)
} }
when (rway_en.orR && io.read.valid) { when (rway_en.orR && io.read.valid) {
resp(p) := array(raddr) resp(p) := array(raddr)
} }
} }
for (dw <- 0 until waysPerMem) { for (dw <- 0 until conf.wordsperrow) {
val r = AVec(resp.map(_(conf.databits*(dw+1)-1,conf.databits*dw))) val r = AVec(resp.map(_(conf.encdatabits*(dw+1)-1,conf.encdatabits*dw)))
val resp_mux = val resp_mux =
if (r.size == 1) r if (r.size == 1) r
else AVec(r(r_raddr(conf.ramoffbits-1,conf.wordoffbits)), r.tail:_*) else AVec(r(r_raddr(conf.ramoffbits-1,conf.wordoffbits)), r.tail:_*)
@ -627,10 +633,10 @@ class DataArray(implicit conf: DCacheConfig) extends Component {
} }
} }
} else { } else {
val wmask = FillInterleaved(conf.databits, io.write.bits.wmask) val wmask = FillInterleaved(conf.encdatabits, io.write.bits.wmask)
for (w <- 0 until conf.ways) { for (w <- 0 until conf.ways) {
val rdata = Reg() { Bits() } val rdata = Reg() { Bits() }
val array = Mem(conf.sets*REFILL_CYCLES, seqRead = true){ Bits(width=MEM_DATA_BITS) } val array = Mem(conf.sets*REFILL_CYCLES, seqRead = true){ Bits(width=conf.bitsperrow) }
when (io.write.bits.way_en(w) && io.write.valid) { when (io.write.bits.way_en(w) && io.write.valid) {
array.write(waddr, io.write.bits.data, wmask) array.write(waddr, io.write.bits.data, wmask)
} }
@ -752,12 +758,14 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
val s2_valid = Reg(s1_valid_masked, resetVal = Bool(false)) val s2_valid = Reg(s1_valid_masked, resetVal = Bool(false))
val s2_req = Reg{io.cpu.req.bits.clone} val s2_req = Reg{io.cpu.req.bits.clone}
val s2_replay = Reg(s1_replay, resetVal = Bool(false)) val s2_replay = Reg(s1_replay, resetVal = Bool(false))
val s2_recycle = Bool()
val s2_valid_masked = Bool() val s2_valid_masked = Bool()
val s3_valid = Reg(resetVal = Bool(false)) val s3_valid = Reg(resetVal = Bool(false))
val s3_req = Reg{io.cpu.req.bits.clone} val s3_req = Reg{io.cpu.req.bits.clone}
val s3_way = Reg{Bits()} val s3_way = Reg{Bits()}
val s1_recycled = RegEn(s2_recycle, s1_clk_en)
val s1_read = isRead(s1_req.cmd) val s1_read = isRead(s1_req.cmd)
val s1_write = isWrite(s1_req.cmd) val s1_write = isWrite(s1_req.cmd)
val s1_readwrite = s1_read || s1_write || isPrefetch(s1_req.cmd) val s1_readwrite = s1_read || s1_write || isPrefetch(s1_req.cmd)
@ -785,6 +793,9 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
when (mshr.io.replay.valid) { when (mshr.io.replay.valid) {
s1_req := mshr.io.replay.bits s1_req := mshr.io.replay.bits
} }
when (s2_recycle) {
s1_req := s2_req
}
val s1_addr = Cat(dtlb.io.resp.ppn, s1_req.addr(conf.pgidxbits-1,0)) val s1_addr = Cat(dtlb.io.resp.ppn, s1_req.addr(conf.pgidxbits-1,0))
when (s1_clk_en) { when (s1_clk_en) {
@ -795,6 +806,7 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
when (s1_write) { when (s1_write) {
s2_req.data := Mux(s1_replay, mshr.io.replay.bits.data, io.cpu.req.bits.data) s2_req.data := Mux(s1_replay, mshr.io.replay.bits.data, io.cpu.req.bits.data)
} }
when (s1_recycled) { s2_req.data := s1_req.data }
} }
val misaligned = val misaligned =
@ -809,29 +821,41 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
// tags // tags
val meta = new MetaDataArray val meta = new MetaDataArray
val metaReadArb = (new Arbiter(4)) { new MetaReadReq } val metaReadArb = (new Arbiter(5)) { new MetaReadReq }
val metaWriteArb = (new Arbiter(2)) { new MetaWriteReq } val metaWriteArb = (new Arbiter(2)) { new MetaWriteReq }
metaReadArb.io.out <> meta.io.read metaReadArb.io.out <> meta.io.read
metaWriteArb.io.out <> meta.io.write metaWriteArb.io.out <> meta.io.write
// data // data
val data = new DataArray val data = new DataArray
val readArb = new Arbiter(3)(new DataReadReq) val readArb = new Arbiter(4)(new DataReadReq)
val writeArb = new Arbiter(2)(new DataWriteReq)
readArb.io.out.ready := !io.mem.xact_rep.valid || io.mem.xact_rep.ready // insert bubble if refill gets blocked readArb.io.out.ready := !io.mem.xact_rep.valid || io.mem.xact_rep.ready // insert bubble if refill gets blocked
readArb.io.out <> data.io.read readArb.io.out <> data.io.read
writeArb.io.out <> data.io.write
val writeArb = new Arbiter(2)(new DataWriteReq)
data.io.write.valid := writeArb.io.out.valid
writeArb.io.out.ready := data.io.write.ready
data.io.write.bits := writeArb.io.out.bits
val wdata_encoded = (0 until conf.wordsperrow).map(i => conf.code.encode(writeArb.io.out.bits.data(conf.databits*(i+1)-1,conf.databits*i)))
data.io.write.bits.data := AVec(wdata_encoded).toBits
// tag read for new requests // tag read for new requests
metaReadArb.io.in(3).valid := io.cpu.req.valid metaReadArb.io.in(4).valid := io.cpu.req.valid
metaReadArb.io.in(3).bits.addr := io.cpu.req.bits.addr metaReadArb.io.in(4).bits.addr := io.cpu.req.bits.addr
when (!metaReadArb.io.in(3).ready) { io.cpu.req.ready := Bool(false) } when (!metaReadArb.io.in(4).ready) { io.cpu.req.ready := Bool(false) }
// data read for new requests // data read for new requests
readArb.io.in(2).bits.addr := io.cpu.req.bits.addr readArb.io.in(3).bits.addr := io.cpu.req.bits.addr
readArb.io.in(2).valid := io.cpu.req.valid readArb.io.in(3).valid := io.cpu.req.valid
readArb.io.in(2).bits.way_en := Fix(-1) readArb.io.in(3).bits.way_en := Fix(-1)
when (!readArb.io.in(2).ready) { io.cpu.req.ready := Bool(false) } when (!readArb.io.in(3).ready) { io.cpu.req.ready := Bool(false) }
// recycled requests
metaReadArb.io.in(0).valid := s2_recycle
metaReadArb.io.in(0).bits.addr := s2_req.addr
readArb.io.in(0).valid := s2_recycle
readArb.io.in(0).bits.addr := s2_req.addr
readArb.io.in(0).bits.way_en := Fix(-1)
// tag check and way muxing // tag check and way muxing
def wayMap[T <: Data](f: Int => T)(gen: => T) = Vec((0 until conf.ways).map(i => f(i))){gen} def wayMap[T <: Data](f: Int => T)(gen: => T) = Vec((0 until conf.ways).map(i => f(i))){gen}
@ -844,30 +868,35 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
val s2_hit_state = Mux1H(s2_tag_match_way, wayMap((w: Int) => RegEn(meta.io.resp(w).state, s1_clk_en)){Bits()}) val s2_hit_state = Mux1H(s2_tag_match_way, wayMap((w: Int) => RegEn(meta.io.resp(w).state, s1_clk_en)){Bits()})
val s2_hit = s2_tag_match && conf.co.isHit(s2_req.cmd, s2_hit_state) && s2_hit_state === conf.co.newStateOnHit(s2_req.cmd, s2_hit_state) val s2_hit = s2_tag_match && conf.co.isHit(s2_req.cmd, s2_hit_state) && s2_hit_state === conf.co.newStateOnHit(s2_req.cmd, s2_hit_state)
val s2_data = Vec(conf.ways){Bits(width = MEM_DATA_BITS)} val s2_data = Vec(conf.ways){Bits(width = conf.bitsperrow)}
for (w <- 0 until conf.ways) { for (w <- 0 until conf.ways) {
val regs = Vec(MEM_DATA_BITS/conf.databits){Reg{Bits(width = conf.databits)}} val regs = Vec(conf.wordsperrow){Reg{Bits(width = conf.encdatabits)}}
val en1 = s1_clk_en && s1_tag_eq_way(w) val en1 = s1_clk_en && s1_tag_eq_way(w)
for (i <- 0 until regs.size) { for (i <- 0 until regs.size) {
val en = en1 && (Bool(i == 0 || !conf.isNarrowRead) || s1_writeback) val en = en1 && (Bool(i == 0 || !conf.isNarrowRead) || s1_writeback)
when (en) { regs(i) := data.io.resp(w) >> conf.databits*i } when (en) { regs(i) := data.io.resp(w) >> conf.encdatabits*i }
} }
s2_data(w) := Cat(regs.last, regs.init.reverse:_*) s2_data(w) := regs.toBits
} }
val data_resp_mux = Mux1H(s2_tag_match_way, s2_data) val s2_data_muxed = Mux1H(s2_tag_match_way, s2_data)
val s2_data_decoded = (0 until conf.wordsperrow).map(i => conf.code.decode(s2_data_muxed(conf.encdatabits*(i+1)-1,conf.encdatabits*i)))
val s2_data_corrected = AVec(s2_data_decoded.map(_.corrected)).toBits
val s2_data_uncorrected = AVec(s2_data_decoded.map(_.uncorrected)).toBits
val s2_word_idx = if (conf.isNarrowRead) UFix(0) else s2_req.addr(log2Up(conf.wordsperrow*conf.databytes)-1,3)
val s2_data_correctable = AVec(s2_data_decoded.map(_.correctable)).toBits()(s2_word_idx)
// store/amo hits // store/amo hits
s3_valid := (s2_valid_masked && s2_hit || s2_replay) && isWrite(s2_req.cmd) s3_valid := (s2_valid_masked && s2_hit || s2_replay) && isWrite(s2_req.cmd)
val amoalu = new AMOALU val amoalu = new AMOALU
when ((s2_valid || s2_replay) && isWrite(s2_req.cmd)) { when ((s2_valid || s2_replay) && (isWrite(s2_req.cmd) || s2_data_correctable)) {
s3_req := s2_req s3_req := s2_req
s3_req.data := amoalu.io.out s3_req.data := Mux(s2_data_correctable, s2_data_corrected, amoalu.io.out)
s3_way := s2_tag_match_way s3_way := s2_tag_match_way
} }
writeArb.io.in(0).bits.addr := s3_req.addr writeArb.io.in(0).bits.addr := s3_req.addr
writeArb.io.in(0).bits.wmask := UFix(1) << s3_req.addr(conf.ramoffbits-1,offsetlsb).toUFix writeArb.io.in(0).bits.wmask := UFix(1) << s3_req.addr(conf.ramoffbits-1,offsetlsb).toUFix
writeArb.io.in(0).bits.data := Fill(MEM_DATA_BITS/conf.databits, s3_req.data) writeArb.io.in(0).bits.data := Fill(conf.wordsperrow, s3_req.data)
writeArb.io.in(0).valid := s3_valid writeArb.io.in(0).valid := s3_valid
writeArb.io.in(0).bits.way_en := s3_way writeArb.io.in(0).bits.way_en := s3_way
@ -875,15 +904,13 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
val replacer = new RandomReplacement val replacer = new RandomReplacement
val s1_replaced_way_en = UFixToOH(replacer.way) val s1_replaced_way_en = UFixToOH(replacer.way)
val s2_replaced_way_en = UFixToOH(RegEn(replacer.way, s1_clk_en)) val s2_replaced_way_en = UFixToOH(RegEn(replacer.way, s1_clk_en))
val s2_repl_state = Mux1H(s2_replaced_way_en, wayMap((w: Int) => RegEn(meta.io.resp(w).state, s1_clk_en && s1_replaced_way_en(w))){Bits()}) val s2_repl_meta = Mux1H(s2_replaced_way_en, wayMap((w: Int) => RegEn(meta.io.resp(w), s1_clk_en && s1_replaced_way_en(w))){new MetaData})
val s2_repl_tag = Mux1H(s2_replaced_way_en, wayMap((w: Int) => RegEn(meta.io.resp(w).tag, s1_clk_en && s1_replaced_way_en(w))){Bits()})
// miss handling // miss handling
mshr.io.req.valid := s2_valid_masked && !s2_hit && (isPrefetch(s2_req.cmd) || isRead(s2_req.cmd) || isWrite(s2_req.cmd)) mshr.io.req.valid := s2_valid_masked && !s2_hit && (isPrefetch(s2_req.cmd) || isRead(s2_req.cmd) || isWrite(s2_req.cmd))
mshr.io.req.bits := s2_req mshr.io.req.bits := s2_req
mshr.io.req.bits.tag_match := s2_tag_match mshr.io.req.bits.tag_match := s2_tag_match
mshr.io.req.bits.old_meta.state := s2_repl_state mshr.io.req.bits.old_meta := s2_repl_meta
mshr.io.req.bits.old_meta.tag := s2_repl_tag
mshr.io.req.bits.way_en := Mux(s2_tag_match, s2_tag_match_way, s2_replaced_way_en) mshr.io.req.bits.way_en := Mux(s2_tag_match, s2_tag_match_way, s2_replaced_way_en)
mshr.io.req.bits.data := s2_req.data mshr.io.req.bits.data := s2_req.data
@ -895,12 +922,12 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
when (mshr.io.req.fire()) { replacer.miss } when (mshr.io.req.fire()) { replacer.miss }
// replays // replays
readArb.io.in(0).valid := mshr.io.replay.valid readArb.io.in(1).valid := mshr.io.replay.valid
readArb.io.in(0).bits := mshr.io.replay.bits readArb.io.in(1).bits := mshr.io.replay.bits
readArb.io.in(0).bits.way_en := Fix(-1) readArb.io.in(1).bits.way_en := Fix(-1)
mshr.io.replay.ready := Bool(true) mshr.io.replay.ready := readArb.io.in(1).ready
s1_replay := mshr.io.replay.fire() s1_replay := mshr.io.replay.valid && readArb.io.in(1).ready
metaReadArb.io.in(0) <> mshr.io.meta_read metaReadArb.io.in(1) <> mshr.io.meta_read
metaWriteArb.io.in(0) <> mshr.io.meta_write metaWriteArb.io.in(0) <> mshr.io.meta_write
// probes // probes
@ -910,7 +937,7 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
prober.io.wb_req <> wb.io.probe prober.io.wb_req <> wb.io.probe
prober.io.way_en := s2_tag_match_way prober.io.way_en := s2_tag_match_way
prober.io.line_state := s2_hit_state prober.io.line_state := s2_hit_state
prober.io.meta_read <> metaReadArb.io.in(1) prober.io.meta_read <> metaReadArb.io.in(2)
prober.io.meta_write <> metaWriteArb.io.in(1) prober.io.meta_write <> metaWriteArb.io.in(1)
// refills // refills
@ -923,9 +950,9 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
// writebacks // writebacks
wb.io.req <> mshr.io.wb_req wb.io.req <> mshr.io.wb_req
wb.io.meta_read <> metaReadArb.io.in(2) wb.io.meta_read <> metaReadArb.io.in(3)
wb.io.data_req <> readArb.io.in(1) wb.io.data_req <> readArb.io.in(2)
wb.io.data_resp := data_resp_mux wb.io.data_resp := s2_data_corrected
wb.io.probe_rep_data <> io.mem.probe_rep_data wb.io.probe_rep_data <> io.mem.probe_rep_data
// store->load bypassing // store->load bypassing
@ -947,9 +974,7 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
} }
// load data subword mux/sign extension // load data subword mux/sign extension
val s2_data_word_prebypass = val s2_data_word_prebypass = s2_data_uncorrected >> Cat(s2_word_idx, Bits(0,log2Up(conf.databits)))
if (conf.isNarrowRead) data_resp_mux(conf.databits-1,0)
else data_resp_mux >> Cat(s2_req.addr(log2Up(MEM_DATA_BITS/8)-1,3), Bits(0,log2Up(conf.databits)))
val s2_data_word = Mux(s2_store_bypass, s2_store_bypass_data, s2_data_word_prebypass) val s2_data_word = Mux(s2_store_bypass, s2_store_bypass_data, s2_data_word_prebypass)
val loadgen = new LoadGen(s2_req.typ, s2_req.addr, s2_data_word) val loadgen = new LoadGen(s2_req.typ, s2_req.addr, s2_data_word)
@ -968,6 +993,11 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
val s2_nack = s2_nack_hit || s2_nack_victim || s2_nack_miss || s2_nack_fence val s2_nack = s2_nack_hit || s2_nack_victim || s2_nack_miss || s2_nack_fence
s2_valid_masked := s2_valid && !s2_nack s2_valid_masked := s2_valid && !s2_nack
val s2_recycle_ecc = (s2_valid || s2_replay) && s2_hit && s2_data_correctable
val s2_recycle_next = Reg(resetVal = Bool(false))
when (s1_valid || s1_replay) { s2_recycle_next := (s1_valid || s1_replay) && s2_recycle_ecc }
s2_recycle := s2_recycle_ecc || s2_recycle_next
// after a nack, block until nack condition resolves to save energy // after a nack, block until nack condition resolves to save energy
val block_fence = Reg(resetVal = Bool(false)) val block_fence = Reg(resetVal = Bool(false))
block_fence := (s2_valid && s2_req.cmd === M_FENCE || block_fence) && !mshr.io.fence_rdy block_fence := (s2_valid && s2_req.cmd === M_FENCE || block_fence) && !mshr.io.fence_rdy
@ -978,7 +1008,7 @@ class HellaCache(implicit conf: DCacheConfig) extends Component {
} }
val s2_read = isRead(s2_req.cmd) val s2_read = isRead(s2_req.cmd)
io.cpu.resp.valid := s2_read && (s2_replay || s2_valid_masked && s2_hit) io.cpu.resp.valid := s2_read && (s2_replay || s2_valid_masked && s2_hit) && !s2_data_correctable
io.cpu.resp.bits.nack := s2_valid && s2_nack io.cpu.resp.bits.nack := s2_valid && s2_nack
io.cpu.resp.bits := s2_req io.cpu.resp.bits := s2_req
io.cpu.resp.bits.replay := s2_replay && s2_read io.cpu.resp.bits.replay := s2_replay && s2_read

View File

@ -17,6 +17,11 @@ object AVec
def apply[T <: Data](elts: Seq[T]): Vec[T] = Vec(elts) { elts.head.clone } def apply[T <: Data](elts: Seq[T]): Vec[T] = Vec(elts) { elts.head.clone }
def apply[T <: Data](elts: Vec[T]): Vec[T] = apply(elts.toSeq) def apply[T <: Data](elts: Vec[T]): Vec[T] = apply(elts.toSeq)
def apply[T <: Data](elt0: T, elts: T*): Vec[T] = apply(elt0 :: elts.toList) def apply[T <: Data](elt0: T, elts: T*): Vec[T] = apply(elt0 :: elts.toList)
def tabulate[T <: Data](n: Int)(f: Int => T): Vec[T] =
apply((0 until n).map(i => f(i)))
def tabulate[T <: Data](n1: Int, n2: Int)(f: (Int, Int) => T): Vec[Vec[T]] =
tabulate(n1)(i1 => tabulate(n2)(f(i1, _)))
} }
// a counter that clock gates most of its MSBs using the LSB carry-out // a counter that clock gates most of its MSBs using the LSB carry-out