Rename some params, use refactored TileLink
This commit is contained in:
		| @@ -10,8 +10,7 @@ import uncore._ | |||||||
| case object NBTBEntries extends Field[Int] | case object NBTBEntries extends Field[Int] | ||||||
| case object NRAS extends Field[Int] | case object NRAS extends Field[Int] | ||||||
|  |  | ||||||
| abstract trait BTBParameters extends UsesParameters { | abstract trait BTBParameters extends CoreParameters { | ||||||
|   val vaddrBits = params(VAddrBits) |  | ||||||
|   val matchBits = params(PgIdxBits) |   val matchBits = params(PgIdxBits) | ||||||
|   val entries = params(NBTBEntries) |   val entries = params(NBTBEntries) | ||||||
|   val nRAS = params(NRAS) |   val nRAS = params(NRAS) | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import Util._ | |||||||
| import uncore._ | import uncore._ | ||||||
|  |  | ||||||
| case object BuildFPU extends Field[Option[() => FPU]] | case object BuildFPU extends Field[Option[() => FPU]] | ||||||
| case object XprLen extends Field[Int] | case object XLen extends Field[Int] | ||||||
| case object NMultXpr extends Field[Int] | case object NMultXpr extends Field[Int] | ||||||
| case object FetchWidth extends Field[Int] | case object FetchWidth extends Field[Int] | ||||||
| case object RetireWidth extends Field[Int] | case object RetireWidth extends Field[Int] | ||||||
| @@ -20,14 +20,23 @@ case object CoreDataBits extends Field[Int] | |||||||
| case object CoreDCacheReqTagBits extends Field[Int] | case object CoreDCacheReqTagBits extends Field[Int] | ||||||
|  |  | ||||||
| abstract trait CoreParameters extends UsesParameters { | abstract trait CoreParameters extends UsesParameters { | ||||||
|   val xprLen = params(XprLen) |   val xLen = params(XLen) | ||||||
|  |   val paddrBits = params(PAddrBits) | ||||||
|  |   val vaddrBits = params(VAddrBits) | ||||||
|  |   val pgIdxBits = params(PgIdxBits) | ||||||
|  |   val ppnBits = params(PPNBits) | ||||||
|  |   val vpnBits = params(VPNBits) | ||||||
|  |   val permBits = params(PermBits) | ||||||
|  |   val asIdBits = params(ASIdBits) | ||||||
|  |  | ||||||
|  |   val retireWidth = params(RetireWidth) | ||||||
|   val coreFetchWidth = params(FetchWidth) |   val coreFetchWidth = params(FetchWidth) | ||||||
|   val coreInstBits = params(CoreInstBits) |   val coreInstBits = params(CoreInstBits) | ||||||
|   val coreInstBytes = coreInstBits/8 |   val coreInstBytes = coreInstBits/8 | ||||||
|   val coreDataBits = xprLen |   val coreDataBits = xLen | ||||||
|   val coreDataBytes = coreDataBits/8 |   val coreDataBytes = coreDataBits/8 | ||||||
|   val coreDCacheReqTagBits = params(CoreDCacheReqTagBits) |   val coreDCacheReqTagBits = params(CoreDCacheReqTagBits) | ||||||
|   val coreMaxAddrBits = math.max(params(PPNBits),params(VPNBits)+1) + params(PgIdxBits) |   val coreMaxAddrBits = math.max(ppnBits,vpnBits+1) + pgIdxBits | ||||||
|  |  | ||||||
|   if(params(FastLoadByte)) require(params(FastLoadWord)) |   if(params(FastLoadByte)) require(params(FastLoadWord)) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -34,52 +34,52 @@ object CSR | |||||||
|   val C =  Bits(3,2) |   val C =  Bits(3,2) | ||||||
| } | } | ||||||
|  |  | ||||||
| class CSRFileIO extends Bundle { | class CSRFileIO extends CoreBundle { | ||||||
|   val host = new HTIFIO |   val host = new HTIFIO | ||||||
|   val rw = new Bundle { |   val rw = new Bundle { | ||||||
|     val addr = UInt(INPUT, 12) |     val addr = UInt(INPUT, 12) | ||||||
|     val cmd = Bits(INPUT, CSR.SZ) |     val cmd = Bits(INPUT, CSR.SZ) | ||||||
|     val rdata = Bits(OUTPUT, params(XprLen)) |     val rdata = Bits(OUTPUT, xLen) | ||||||
|     val wdata = Bits(INPUT, params(XprLen)) |     val wdata = Bits(INPUT, xLen) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   val status = new Status().asOutput |   val status = new Status().asOutput | ||||||
|   val ptbr = UInt(OUTPUT, params(PAddrBits)) |   val ptbr = UInt(OUTPUT, paddrBits) | ||||||
|   val evec = UInt(OUTPUT, params(VAddrBits)+1) |   val evec = UInt(OUTPUT, vaddrBits+1) | ||||||
|   val exception = Bool(INPUT) |   val exception = Bool(INPUT) | ||||||
|   val retire = UInt(INPUT, log2Up(1+params(RetireWidth))) |   val retire = UInt(INPUT, log2Up(1+retireWidth)) | ||||||
|   val uarch_counters = Vec.fill(16)(UInt(INPUT, log2Up(1+params(RetireWidth)))) |   val uarch_counters = Vec.fill(16)(UInt(INPUT, log2Up(1+retireWidth))) | ||||||
|   val cause = UInt(INPUT, params(XprLen)) |   val cause = UInt(INPUT, xLen) | ||||||
|   val badvaddr_wen = Bool(INPUT) |   val badvaddr_wen = Bool(INPUT) | ||||||
|   val pc = UInt(INPUT, params(VAddrBits)+1) |   val pc = UInt(INPUT, vaddrBits+1) | ||||||
|   val sret = Bool(INPUT) |   val sret = Bool(INPUT) | ||||||
|   val fatc = Bool(OUTPUT) |   val fatc = Bool(OUTPUT) | ||||||
|   val replay = Bool(OUTPUT) |   val replay = Bool(OUTPUT) | ||||||
|   val time = UInt(OUTPUT, params(XprLen)) |   val time = UInt(OUTPUT, xLen) | ||||||
|   val fcsr_rm = Bits(OUTPUT, FPConstants.RM_SZ) |   val fcsr_rm = Bits(OUTPUT, FPConstants.RM_SZ) | ||||||
|   val fcsr_flags = Valid(Bits(width = FPConstants.FLAGS_SZ)).flip |   val fcsr_flags = Valid(Bits(width = FPConstants.FLAGS_SZ)).flip | ||||||
|   val rocc = new RoCCInterface().flip |   val rocc = new RoCCInterface().flip | ||||||
| } | } | ||||||
|  |  | ||||||
| class CSRFile extends Module | class CSRFile extends CoreModule | ||||||
| { | { | ||||||
|   val io = new CSRFileIO |   val io = new CSRFileIO | ||||||
|   |   | ||||||
|   val reg_epc = Reg(Bits(width = params(VAddrBits)+1)) |   val reg_epc = Reg(Bits(width = vaddrBits+1)) | ||||||
|   val reg_badvaddr = Reg(Bits(width = params(VAddrBits))) |   val reg_badvaddr = Reg(Bits(width = vaddrBits)) | ||||||
|   val reg_evec = Reg(Bits(width = params(VAddrBits))) |   val reg_evec = Reg(Bits(width = vaddrBits)) | ||||||
|   val reg_compare = Reg(Bits(width = 32)) |   val reg_compare = Reg(Bits(width = 32)) | ||||||
|   val reg_cause = Reg(Bits(width = params(XprLen))) |   val reg_cause = Reg(Bits(width = xLen)) | ||||||
|   val reg_tohost = Reg(init=Bits(0, params(XprLen))) |   val reg_tohost = Reg(init=Bits(0, xLen)) | ||||||
|   val reg_fromhost = Reg(init=Bits(0, params(XprLen))) |   val reg_fromhost = Reg(init=Bits(0, xLen)) | ||||||
|   val reg_sup0 = Reg(Bits(width = params(XprLen))) |   val reg_sup0 = Reg(Bits(width = xLen)) | ||||||
|   val reg_sup1 = Reg(Bits(width = params(XprLen))) |   val reg_sup1 = Reg(Bits(width = xLen)) | ||||||
|   val reg_ptbr = Reg(UInt(width = params(PAddrBits))) |   val reg_ptbr = Reg(UInt(width = paddrBits)) | ||||||
|   val reg_stats = Reg(init=Bool(false)) |   val reg_stats = Reg(init=Bool(false)) | ||||||
|   val reg_status = Reg(new Status) // reset down below |   val reg_status = Reg(new Status) // reset down below | ||||||
|   val reg_time = WideCounter(params(XprLen)) |   val reg_time = WideCounter(xLen) | ||||||
|   val reg_instret = WideCounter(params(XprLen), io.retire) |   val reg_instret = WideCounter(xLen, io.retire) | ||||||
|   val reg_uarch_counters = io.uarch_counters.map(WideCounter(params(XprLen), _)) |   val reg_uarch_counters = io.uarch_counters.map(WideCounter(xLen, _)) | ||||||
|   val reg_fflags = Reg(UInt(width = 5)) |   val reg_fflags = Reg(UInt(width = 5)) | ||||||
|   val reg_frm = Reg(UInt(width = 3)) |   val reg_frm = Reg(UInt(width = 3)) | ||||||
|  |  | ||||||
| @@ -128,7 +128,7 @@ class CSRFile extends Module | |||||||
|  |  | ||||||
|   when (io.badvaddr_wen) { |   when (io.badvaddr_wen) { | ||||||
|     val wdata = io.rw.wdata |     val wdata = io.rw.wdata | ||||||
|     val (upper, lower) = Split(wdata, params(VAddrBits)) |     val (upper, lower) = Split(wdata, vaddrBits) | ||||||
|     val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR) |     val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR) | ||||||
|     reg_badvaddr := Cat(sign, lower).toSInt |     reg_badvaddr := Cat(sign, lower).toSInt | ||||||
|   } |   } | ||||||
| @@ -159,7 +159,7 @@ class CSRFile extends Module | |||||||
|   when (host_pcr_req_fire && !host_pcr_bits.rw && decoded_addr(CSRs.tohost)) { reg_tohost := UInt(0) } |   when (host_pcr_req_fire && !host_pcr_bits.rw && decoded_addr(CSRs.tohost)) { reg_tohost := UInt(0) } | ||||||
|  |  | ||||||
|   val read_impl = Bits(2) |   val read_impl = Bits(2) | ||||||
|   val read_ptbr = reg_ptbr(params(PAddrBits)-1, params(PgIdxBits)) << UInt(params(PgIdxBits)) |   val read_ptbr = reg_ptbr(paddrBits-1, pgIdxBits) << UInt(pgIdxBits) | ||||||
|  |  | ||||||
|   val read_mapping = collection.mutable.LinkedHashMap[Int,Bits]( |   val read_mapping = collection.mutable.LinkedHashMap[Int,Bits]( | ||||||
|     CSRs.fflags -> (if (!params(BuildFPU).isEmpty) reg_fflags else UInt(0)), |     CSRs.fflags -> (if (!params(BuildFPU).isEmpty) reg_fflags else UInt(0)), | ||||||
| @@ -211,8 +211,8 @@ class CSRFile extends Module | |||||||
|     when (decoded_addr(CSRs.fflags))   { reg_fflags := wdata } |     when (decoded_addr(CSRs.fflags))   { reg_fflags := wdata } | ||||||
|     when (decoded_addr(CSRs.frm))      { reg_frm := wdata } |     when (decoded_addr(CSRs.frm))      { reg_frm := wdata } | ||||||
|     when (decoded_addr(CSRs.fcsr))     { reg_fflags := wdata; reg_frm := wdata >> reg_fflags.getWidth } |     when (decoded_addr(CSRs.fcsr))     { reg_fflags := wdata; reg_frm := wdata >> reg_fflags.getWidth } | ||||||
|     when (decoded_addr(CSRs.epc))      { reg_epc := wdata(params(VAddrBits),0).toSInt } |     when (decoded_addr(CSRs.epc))      { reg_epc := wdata(vaddrBits,0).toSInt } | ||||||
|     when (decoded_addr(CSRs.evec))     { reg_evec := wdata(params(VAddrBits)-1,0).toSInt } |     when (decoded_addr(CSRs.evec))     { reg_evec := wdata(vaddrBits-1,0).toSInt } | ||||||
|     when (decoded_addr(CSRs.count))    { reg_time := wdata.toUInt } |     when (decoded_addr(CSRs.count))    { reg_time := wdata.toUInt } | ||||||
|     when (decoded_addr(CSRs.compare))  { reg_compare := wdata(31,0).toUInt; r_irq_timer := Bool(false) } |     when (decoded_addr(CSRs.compare))  { reg_compare := wdata(31,0).toUInt; r_irq_timer := Bool(false) } | ||||||
|     when (decoded_addr(CSRs.fromhost)) { when (reg_fromhost === UInt(0) || !host_pcr_req_fire) { reg_fromhost := wdata } } |     when (decoded_addr(CSRs.fromhost)) { when (reg_fromhost === UInt(0) || !host_pcr_req_fire) { reg_fromhost := wdata } } | ||||||
| @@ -220,7 +220,7 @@ class CSRFile extends Module | |||||||
|     when (decoded_addr(CSRs.clear_ipi)){ r_irq_ipi := wdata(0) } |     when (decoded_addr(CSRs.clear_ipi)){ r_irq_ipi := wdata(0) } | ||||||
|     when (decoded_addr(CSRs.sup0))     { reg_sup0 := wdata } |     when (decoded_addr(CSRs.sup0))     { reg_sup0 := wdata } | ||||||
|     when (decoded_addr(CSRs.sup1))     { reg_sup1 := wdata } |     when (decoded_addr(CSRs.sup1))     { reg_sup1 := wdata } | ||||||
|     when (decoded_addr(CSRs.ptbr))     { reg_ptbr := Cat(wdata(params(PAddrBits)-1, params(PgIdxBits)), Bits(0, params(PgIdxBits))).toUInt } |     when (decoded_addr(CSRs.ptbr))     { reg_ptbr := Cat(wdata(paddrBits-1, pgIdxBits), Bits(0, pgIdxBits)).toUInt } | ||||||
|     when (decoded_addr(CSRs.stats))    { reg_stats := wdata(0) } |     when (decoded_addr(CSRs.stats))    { reg_stats := wdata(0) } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import uncore.constants.MemoryOpConstants._ | |||||||
| import ALU._ | import ALU._ | ||||||
| import Util._ | import Util._ | ||||||
|  |  | ||||||
| class CtrlDpathIO extends Bundle | class CtrlDpathIO extends CoreBundle | ||||||
| { | { | ||||||
|   // outputs to datapath |   // outputs to datapath | ||||||
|   val sel_pc   = UInt(OUTPUT, 3) |   val sel_pc   = UInt(OUTPUT, 3) | ||||||
| @@ -27,7 +27,7 @@ class CtrlDpathIO extends Bundle | |||||||
|   // exception handling |   // exception handling | ||||||
|   val retire = Bool(OUTPUT) |   val retire = Bool(OUTPUT) | ||||||
|   val exception = Bool(OUTPUT) |   val exception = Bool(OUTPUT) | ||||||
|   val cause    = UInt(OUTPUT, params(XprLen)) |   val cause    = UInt(OUTPUT, xLen) | ||||||
|   val badvaddr_wen = Bool(OUTPUT) // high for a load/store access fault |   val badvaddr_wen = Bool(OUTPUT) // high for a load/store access fault | ||||||
|   // inputs from datapath |   // inputs from datapath | ||||||
|   val inst    = Bits(INPUT, 32) |   val inst    = Bits(INPUT, 32) | ||||||
| @@ -328,7 +328,7 @@ object RoCCDecode extends DecodeConstants | |||||||
|     CUSTOM3_RD_RS1_RS2->List(Y,    N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,      MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N)) |     CUSTOM3_RD_RS1_RS2->List(Y,    N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,      MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N)) | ||||||
| } | } | ||||||
|  |  | ||||||
| class Control extends Module | class Control extends CoreModule | ||||||
| { | { | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val dpath   = new CtrlDpathIO |     val dpath   = new CtrlDpathIO | ||||||
| @@ -388,7 +388,7 @@ class Control extends Module | |||||||
|   val id_reg_fence = Reg(init=Bool(false)) |   val id_reg_fence = Reg(init=Bool(false)) | ||||||
|  |  | ||||||
|   val sr = io.dpath.status |   val sr = io.dpath.status | ||||||
|   var id_interrupts = (0 until sr.ip.getWidth).map(i => (sr.im(i) && sr.ip(i), UInt(BigInt(1) << (params(XprLen)-1) | i))) |   var id_interrupts = (0 until sr.ip.getWidth).map(i => (sr.im(i) && sr.ip(i), UInt(BigInt(1) << (xLen-1) | i))) | ||||||
|  |  | ||||||
|   val (id_interrupt_unmasked, id_interrupt_cause) = checkExceptions(id_interrupts) |   val (id_interrupt_unmasked, id_interrupt_cause) = checkExceptions(id_interrupts) | ||||||
|   val id_interrupt = io.dpath.status.ei && id_interrupt_unmasked |   val id_interrupt = io.dpath.status.ei && id_interrupt_unmasked | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import Instructions._ | |||||||
| import Util._ | import Util._ | ||||||
| import uncore._ | import uncore._ | ||||||
|  |  | ||||||
| class Datapath extends Module | class Datapath extends CoreModule | ||||||
| { | { | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val host  = new HTIFIO |     val host  = new HTIFIO | ||||||
| @@ -149,10 +149,10 @@ class Datapath extends Module | |||||||
|   io.fpu.fromint_data := ex_rs(0) |   io.fpu.fromint_data := ex_rs(0) | ||||||
|  |  | ||||||
|   def vaSign(a0: UInt, ea: Bits) = { |   def vaSign(a0: UInt, ea: Bits) = { | ||||||
|     // efficient means to compress 64-bit VA into params(VAddrBits)+1 bits |     // efficient means to compress 64-bit VA into vaddrBits+1 bits | ||||||
|     // (VA is bad if VA(params(VAddrBits)) != VA(params(VAddrBits)-1)) |     // (VA is bad if VA(vaddrBits) != VA(vaddrBits-1)) | ||||||
|     val a = a0 >> params(VAddrBits)-1 |     val a = a0 >> vaddrBits-1 | ||||||
|     val e = ea(params(VAddrBits),params(VAddrBits)-1) |     val e = ea(vaddrBits,vaddrBits-1) | ||||||
|     Mux(a === UInt(0) || a === UInt(1), e != UInt(0), |     Mux(a === UInt(0) || a === UInt(1), e != UInt(0), | ||||||
|     Mux(a === SInt(-1) || a === SInt(-2), e === SInt(-1), |     Mux(a === SInt(-1) || a === SInt(-2), e === SInt(-1), | ||||||
|     e(0))) |     e(0))) | ||||||
| @@ -160,7 +160,7 @@ class Datapath extends Module | |||||||
|  |  | ||||||
|   // D$ request interface (registered inside D$ module) |   // D$ request interface (registered inside D$ module) | ||||||
|   // other signals (req_val, req_rdy) connect to control module   |   // other signals (req_val, req_rdy) connect to control module   | ||||||
|   io.dmem.req.bits.addr := Cat(vaSign(ex_rs(0), alu.io.adder_out), alu.io.adder_out(params(VAddrBits)-1,0)).toUInt |   io.dmem.req.bits.addr := Cat(vaSign(ex_rs(0), alu.io.adder_out), alu.io.adder_out(vaddrBits-1,0)).toUInt | ||||||
|   io.dmem.req.bits.tag := Cat(io.ctrl.ex_waddr, io.ctrl.ex_ctrl.fp) |   io.dmem.req.bits.tag := Cat(io.ctrl.ex_waddr, io.ctrl.ex_ctrl.fp) | ||||||
|   require(io.dmem.req.bits.tag.getWidth >= 6) |   require(io.dmem.req.bits.tag.getWidth >= 6) | ||||||
|   require(params(CoreDCacheReqTagBits) >= 6) |   require(params(CoreDCacheReqTagBits) >= 6) | ||||||
| @@ -231,7 +231,7 @@ class Datapath extends Module | |||||||
|   val mem_br_target = mem_reg_pc + |   val mem_br_target = mem_reg_pc + | ||||||
|     Mux(io.ctrl.mem_ctrl.branch && io.ctrl.mem_br_taken, imm(IMM_SB, mem_reg_inst), |     Mux(io.ctrl.mem_ctrl.branch && io.ctrl.mem_br_taken, imm(IMM_SB, mem_reg_inst), | ||||||
|     Mux(io.ctrl.mem_ctrl.jal, imm(IMM_UJ, mem_reg_inst), SInt(4))) |     Mux(io.ctrl.mem_ctrl.jal, imm(IMM_UJ, mem_reg_inst), SInt(4))) | ||||||
|   val mem_npc = Mux(io.ctrl.mem_ctrl.jalr, Cat(vaSign(mem_reg_wdata, mem_reg_wdata), mem_reg_wdata(params(VAddrBits)-1,0)), mem_br_target) |   val mem_npc = Mux(io.ctrl.mem_ctrl.jalr, Cat(vaSign(mem_reg_wdata, mem_reg_wdata), mem_reg_wdata(vaddrBits-1,0)), mem_br_target) | ||||||
|   io.ctrl.mem_misprediction := mem_npc != ex_reg_pc || !io.ctrl.ex_valid |   io.ctrl.mem_misprediction := mem_npc != ex_reg_pc || !io.ctrl.ex_valid | ||||||
|   io.ctrl.mem_rs1_ra := mem_reg_inst(19,15) === 1 |   io.ctrl.mem_rs1_ra := mem_reg_inst(19,15) === 1 | ||||||
|   val mem_int_wdata = Mux(io.ctrl.mem_ctrl.jalr, mem_br_target, mem_reg_wdata) |   val mem_int_wdata = Mux(io.ctrl.mem_ctrl.jalr, mem_br_target, mem_reg_wdata) | ||||||
|   | |||||||
| @@ -43,13 +43,13 @@ object ALU | |||||||
| } | } | ||||||
| import ALU._ | import ALU._ | ||||||
|  |  | ||||||
| class ALUIO extends Bundle { | class ALUIO extends CoreBundle { | ||||||
|   val dw = Bits(INPUT, SZ_DW) |   val dw = Bits(INPUT, SZ_DW) | ||||||
|   val fn = Bits(INPUT, SZ_ALU_FN) |   val fn = Bits(INPUT, SZ_ALU_FN) | ||||||
|   val in2 = UInt(INPUT, params(XprLen)) |   val in2 = UInt(INPUT, xLen) | ||||||
|   val in1 = UInt(INPUT, params(XprLen)) |   val in1 = UInt(INPUT, xLen) | ||||||
|   val out = UInt(OUTPUT, params(XprLen)) |   val out = UInt(OUTPUT, xLen) | ||||||
|   val adder_out = UInt(OUTPUT, params(XprLen)) |   val adder_out = UInt(OUTPUT, xLen) | ||||||
| } | } | ||||||
|  |  | ||||||
| class ALU extends Module | class ALU extends Module | ||||||
|   | |||||||
| @@ -4,7 +4,6 @@ import Chisel._ | |||||||
| import uncore._ | import uncore._ | ||||||
| import Util._ | import Util._ | ||||||
|  |  | ||||||
| case object NITLBEntries extends Field[Int] |  | ||||||
| case object ECCCode extends Field[Option[Code]] | case object ECCCode extends Field[Option[Code]] | ||||||
|  |  | ||||||
| abstract trait L1CacheParameters extends CacheParameters with CoreParameters { | abstract trait L1CacheParameters extends CacheParameters with CoreParameters { | ||||||
| @@ -20,18 +19,18 @@ abstract class FrontendBundle extends Bundle with FrontendParameters | |||||||
| abstract class FrontendModule extends Module with FrontendParameters | abstract class FrontendModule extends Module with FrontendParameters | ||||||
|  |  | ||||||
| class FrontendReq extends CoreBundle { | class FrontendReq extends CoreBundle { | ||||||
|   val pc = UInt(width = params(VAddrBits)+1) |   val pc = UInt(width = vaddrBits+1) | ||||||
| } | } | ||||||
|  |  | ||||||
| class FrontendResp extends CoreBundle { | class FrontendResp extends CoreBundle { | ||||||
|   val pc = UInt(width = params(VAddrBits)+1)  // ID stage PC |   val pc = UInt(width = vaddrBits+1)  // ID stage PC | ||||||
|   val data = Vec.fill(coreFetchWidth) (Bits(width = coreInstBits)) |   val data = Vec.fill(coreFetchWidth) (Bits(width = coreInstBits)) | ||||||
|   val mask = Bits(width = coreFetchWidth) |   val mask = Bits(width = coreFetchWidth) | ||||||
|   val xcpt_ma = Bool() |   val xcpt_ma = Bool() | ||||||
|   val xcpt_if = Bool() |   val xcpt_if = Bool() | ||||||
| } | } | ||||||
|  |  | ||||||
| class CPUFrontendIO extends CoreBundle { | class CPUFrontendIO extends Bundle { | ||||||
|   val req = Valid(new FrontendReq) |   val req = Valid(new FrontendReq) | ||||||
|   val resp = Decoupled(new FrontendResp).flip |   val resp = Decoupled(new FrontendResp).flip | ||||||
|   val btb_resp = Valid(new BTBResp).flip |   val btb_resp = Valid(new BTBResp).flip | ||||||
| @@ -51,7 +50,7 @@ class Frontend(btb_updates_out_of_order: Boolean = false) extends FrontendModule | |||||||
|  |  | ||||||
|   val btb = Module(new BTB(btb_updates_out_of_order)) |   val btb = Module(new BTB(btb_updates_out_of_order)) | ||||||
|   val icache = Module(new ICache) |   val icache = Module(new ICache) | ||||||
|   val tlb = Module(new TLB(params(NITLBEntries))) |   val tlb = Module(new TLB) | ||||||
|  |  | ||||||
|   val s1_pc_ = Reg(UInt()) |   val s1_pc_ = Reg(UInt()) | ||||||
|   val s1_pc = s1_pc_ & SInt(-2) // discard LSB of PC (throughout the pipeline) |   val s1_pc = s1_pc_ & SInt(-2) // discard LSB of PC (throughout the pipeline) | ||||||
| @@ -134,7 +133,7 @@ class Frontend(btb_updates_out_of_order: Boolean = false) extends FrontendModule | |||||||
|  |  | ||||||
| class ICacheReq extends FrontendBundle { | class ICacheReq extends FrontendBundle { | ||||||
|   val idx = UInt(width = pgIdxBits) |   val idx = UInt(width = pgIdxBits) | ||||||
|   val ppn = UInt(width = params(PPNBits)) // delayed one cycle |   val ppn = UInt(width = ppnBits) // delayed one cycle | ||||||
|   val kill = Bool() // delayed one cycle |   val kill = Bool() // delayed one cycle | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -190,14 +189,15 @@ class ICache extends FrontendModule | |||||||
|   val s2_miss = s2_valid && !s2_any_tag_hit |   val s2_miss = s2_valid && !s2_any_tag_hit | ||||||
|   rdy := state === s_ready && !s2_miss |   rdy := state === s_ready && !s2_miss | ||||||
|  |  | ||||||
|   val ser = Module(new FlowThroughSerializer(io.mem.grant.bits, refillCyclesPerBeat, (g: Grant) => co.messageUpdatesDataArray(g))) |   val ser = Module(new FlowThroughSerializer( | ||||||
|  |                           io.mem.grant.bits, | ||||||
|  |                           refillCyclesPerBeat)) | ||||||
|   ser.io.in <> io.mem.grant |   ser.io.in <> io.mem.grant | ||||||
|   val (refill_cnt, refill_wrap) = Counter(ser.io.out.fire(), refillCycles) //TODO Zero width wire |   val (refill_cnt, refill_wrap) = Counter(ser.io.out.fire(), refillCycles) //TODO Zero width wire | ||||||
|   val refill_done = state === s_refill && refill_wrap |   val refill_done = state === s_refill && refill_wrap | ||||||
|   val refill_valid = ser.io.out.valid |   val refill_valid = ser.io.out.valid | ||||||
|   val refill_bits = ser.io.out.bits |   val refill_bits = ser.io.out.bits | ||||||
|   ser.io.out.ready := Bool(true) |   ser.io.out.ready := Bool(true) | ||||||
|   //assert(!c.tlco.isVoluntary(refill_bits.payload) || !refill_valid, "UncachedRequestors shouldn't get voluntary grants.") |  | ||||||
|  |  | ||||||
|   val repl_way = if (isDM) UInt(0) else LFSR16(s2_miss)(log2Up(nWays)-1,0) |   val repl_way = if (isDM) UInt(0) else LFSR16(s2_miss)(log2Up(nWays)-1,0) | ||||||
|   val entagbits = code.width(tagBits) |   val entagbits = code.width(tagBits) | ||||||
| @@ -251,7 +251,7 @@ class ICache extends FrontendModule | |||||||
|     val s1_raddr = Reg(UInt()) |     val s1_raddr = Reg(UInt()) | ||||||
|     when (refill_valid && repl_way === UInt(i)) { |     when (refill_valid && repl_way === UInt(i)) { | ||||||
|       val e_d = code.encode(refill_bits.payload.data) |       val e_d = code.encode(refill_bits.payload.data) | ||||||
|       if(refillCycles > 1) data_array(Cat(s2_idx, refill_cnt)) := e_d |       if(refillCycles > 1) data_array(Cat(s2_idx, refill_bits.payload.addr_beat)) := e_d | ||||||
|       else data_array(s2_idx) := e_d |       else data_array(s2_idx) := e_d | ||||||
|     } |     } | ||||||
| //    /*.else*/when (s0_valid) { // uncomment ".else" to infer 6T SRAM | //    /*.else*/when (s0_valid) { // uncomment ".else" to infer 6T SRAM | ||||||
| @@ -266,14 +266,14 @@ class ICache extends FrontendModule | |||||||
|   io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout) |   io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout) | ||||||
|  |  | ||||||
|   val ack_q = Module(new Queue(new LogicalNetworkIO(new Finish), 1)) |   val ack_q = Module(new Queue(new LogicalNetworkIO(new Finish), 1)) | ||||||
|   ack_q.io.enq.valid := refill_done && co.requiresAckForGrant(refill_bits.payload) |   ack_q.io.enq.valid := refill_done && refill_bits.payload.requiresAck() | ||||||
|   ack_q.io.enq.bits.payload.manager_xact_id := refill_bits.payload.manager_xact_id |   ack_q.io.enq.bits.payload := refill_bits.payload.makeFinish() | ||||||
|   ack_q.io.enq.bits.header.dst := refill_bits.header.src |   ack_q.io.enq.bits.header.dst := refill_bits.header.src | ||||||
|  |  | ||||||
|   // output signals |   // output signals | ||||||
|   io.resp.valid := s2_hit |   io.resp.valid := s2_hit | ||||||
|   io.mem.acquire.valid := (state === s_request) && ack_q.io.enq.ready |   io.mem.acquire.valid := (state === s_request) && ack_q.io.enq.ready | ||||||
|   io.mem.acquire.bits.payload := UncachedRead(s2_addr >> UInt(blockOffBits)) |   io.mem.acquire.bits.payload := UncachedReadBlock(addr_block = s2_addr >> UInt(blockOffBits)) | ||||||
|   io.mem.finish <> ack_q.io.deq |   io.mem.finish <> ack_q.io.deq | ||||||
|  |  | ||||||
|   // control state machine |   // control state machine | ||||||
|   | |||||||
| @@ -6,16 +6,16 @@ import Chisel._ | |||||||
| import ALU._ | import ALU._ | ||||||
| import Util._ | import Util._ | ||||||
|  |  | ||||||
| class MultiplierReq extends Bundle { | class MultiplierReq extends CoreBundle { | ||||||
|   val fn = Bits(width = SZ_ALU_FN) |   val fn = Bits(width = SZ_ALU_FN) | ||||||
|   val dw = Bits(width = SZ_DW) |   val dw = Bits(width = SZ_DW) | ||||||
|   val in1 = Bits(width = params(XprLen)) |   val in1 = Bits(width = xLen) | ||||||
|   val in2 = Bits(width = params(XprLen)) |   val in2 = Bits(width = xLen) | ||||||
|   val tag = UInt(width = log2Up(params(NMultXpr))) |   val tag = UInt(width = log2Up(params(NMultXpr))) | ||||||
| } | } | ||||||
|  |  | ||||||
| class MultiplierResp extends Bundle { | class MultiplierResp extends CoreBundle { | ||||||
|   val data = Bits(width = params(XprLen)) |   val data = Bits(width = xLen) | ||||||
|   val tag = UInt(width = log2Up(params(NMultXpr))) |   val tag = UInt(width = log2Up(params(NMultXpr))) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,17 +6,21 @@ import Chisel._ | |||||||
| import uncore._ | import uncore._ | ||||||
| import Util._ | import Util._ | ||||||
|  |  | ||||||
|  | case object WordBits extends Field[Int] | ||||||
| case object StoreDataQueueDepth extends Field[Int] | case object StoreDataQueueDepth extends Field[Int] | ||||||
| case object ReplayQueueDepth extends Field[Int] | case object ReplayQueueDepth extends Field[Int] | ||||||
| case object NMSHRs extends Field[Int] | case object NMSHRs extends Field[Int] | ||||||
| case object LRSCCycles extends Field[Int] | case object LRSCCycles extends Field[Int] | ||||||
| case object NDTLBEntries extends Field[Int] |  | ||||||
|  |  | ||||||
| abstract trait L1HellaCacheParameters extends L1CacheParameters { | abstract trait L1HellaCacheParameters extends L1CacheParameters { | ||||||
|  |   val wordBits = params(WordBits) | ||||||
|  |   val wordBytes = wordBits/8 | ||||||
|  |   val wordOffBits = log2Up(wordBytes) | ||||||
|   val idxMSB = untagBits-1 |   val idxMSB = untagBits-1 | ||||||
|   val idxLSB = blockOffBits |   val idxLSB = blockOffBits | ||||||
|   val offsetmsb = idxLSB-1 |   val offsetmsb = idxLSB-1 | ||||||
|   val offsetlsb = wordOffBits |   val offsetlsb = wordOffBits | ||||||
|  |   val rowWords = rowBits/wordBits  | ||||||
|   val doNarrowRead = coreDataBits * nWays % rowBits == 0 |   val doNarrowRead = coreDataBits * nWays % rowBits == 0 | ||||||
|   val encDataBits = code.width(coreDataBits) |   val encDataBits = code.width(coreDataBits) | ||||||
|   val encRowBits = encDataBits*rowWords |   val encRowBits = encDataBits*rowWords | ||||||
| @@ -27,64 +31,39 @@ abstract trait L1HellaCacheParameters extends L1CacheParameters { | |||||||
| abstract class L1HellaCacheBundle extends Bundle with L1HellaCacheParameters | abstract class L1HellaCacheBundle extends Bundle with L1HellaCacheParameters | ||||||
| abstract class L1HellaCacheModule extends Module with L1HellaCacheParameters | abstract class L1HellaCacheModule extends Module with L1HellaCacheParameters | ||||||
|  |  | ||||||
| class StoreGen(typ: Bits, addr: Bits, dat: Bits) | trait HasCoreMemOp extends CoreBundle { | ||||||
| { |   val addr = UInt(width = coreMaxAddrBits) | ||||||
|   val byte = typ === MT_B || typ === MT_BU |   val tag  = Bits(width = coreDCacheReqTagBits) | ||||||
|   val half = typ === MT_H || typ === MT_HU |   val cmd  = Bits(width = M_SZ) | ||||||
|   val word = typ === MT_W || typ === MT_WU |   val typ  = Bits(width = MT_SZ) | ||||||
|   def mask = |  | ||||||
|     Mux(byte, Bits(  1) <<     addr(2,0), |  | ||||||
|     Mux(half, Bits(  3) << Cat(addr(2,1), Bits(0,1)), |  | ||||||
|     Mux(word, Bits( 15) << Cat(addr(2),   Bits(0,2)), |  | ||||||
|               Bits(255)))) |  | ||||||
|   def data = |  | ||||||
|     Mux(byte, Fill(8, dat( 7,0)), |  | ||||||
|     Mux(half, Fill(4, dat(15,0)), |  | ||||||
|                       wordData)) |  | ||||||
|   lazy val wordData = |  | ||||||
|     Mux(word, Fill(2, dat(31,0)), |  | ||||||
|                       dat) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| class LoadGen(typ: Bits, addr: Bits, dat: Bits, zero: Bool) |  | ||||||
| { |  | ||||||
|   val t = new StoreGen(typ, addr, dat) |  | ||||||
|   val sign = typ === MT_B || typ === MT_H || typ === MT_W || typ === MT_D |  | ||||||
|  |  | ||||||
|   val wordShift = Mux(addr(2), dat(63,32), dat(31,0)) |  | ||||||
|   val word = Cat(Mux(t.word, Fill(32, sign && wordShift(31)), dat(63,32)), wordShift) |  | ||||||
|   val halfShift = Mux(addr(1), word(31,16), word(15,0)) |  | ||||||
|   val half = Cat(Mux(t.half, Fill(48, sign && halfShift(15)), word(63,16)), halfShift) |  | ||||||
|   val byteShift = Mux(zero, UInt(0), Mux(addr(0), half(15,8), half(7,0))) |  | ||||||
|   val byte = Cat(Mux(zero || t.byte, Fill(56, sign && byteShift(7)), half(63,8)), byteShift) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| trait HasCoreData extends CoreBundle { | trait HasCoreData extends CoreBundle { | ||||||
|   val data = Bits(width = coreDataBits) |   val data = Bits(width = coreDataBits) | ||||||
| } | } | ||||||
|  |  | ||||||
| class HellaCacheReqInternal extends CoreBundle { | trait HasSDQId extends CoreBundle with L1HellaCacheParameters { | ||||||
|   val kill = Bool() |   val sdq_id = UInt(width = log2Up(sdqDepth)) | ||||||
|   val typ  = Bits(width = MT_SZ) |  | ||||||
|   val phys = Bool() |  | ||||||
|   val addr = UInt(width = coreMaxAddrBits) |  | ||||||
|   val tag  = Bits(width = coreDCacheReqTagBits) |  | ||||||
|   val cmd  = Bits(width = M_SZ) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| class HellaCacheReq extends HellaCacheReqInternal | trait HasMissInfo extends CoreBundle with L1HellaCacheParameters { | ||||||
|     with HasCoreData |   val tag_match = Bool() | ||||||
|  |   val old_meta = new L1Metadata | ||||||
|  |   val way_en = Bits(width = nWays) | ||||||
|  | } | ||||||
|  |  | ||||||
| class HellaCacheResp extends CoreBundle | class HellaCacheReqInternal extends HasCoreMemOp { | ||||||
|     with HasCoreData { |   val kill = Bool() | ||||||
|  |   val phys = Bool() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class HellaCacheReq extends HellaCacheReqInternal with HasCoreData | ||||||
|  |  | ||||||
|  | class HellaCacheResp extends HasCoreMemOp with HasCoreData { | ||||||
|   val nack = Bool() // comes 2 cycles after req.fire |   val nack = Bool() // comes 2 cycles after req.fire | ||||||
|   val replay = Bool() |   val replay = Bool() | ||||||
|   val typ = Bits(width = 3) |  | ||||||
|   val has_data = Bool() |   val has_data = Bool() | ||||||
|   val data_subword = Bits(width = coreDataBits) |   val data_subword = Bits(width = coreDataBits) | ||||||
|   val tag = Bits(width = coreDCacheReqTagBits) |  | ||||||
|   val cmd  = Bits(width = 4) |  | ||||||
|   val addr = UInt(width = coreMaxAddrBits) |  | ||||||
|   val store_data = Bits(width = coreDataBits) |   val store_data = Bits(width = coreDataBits) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -108,27 +87,12 @@ class HellaCacheIO extends CoreBundle { | |||||||
|   val ordered = Bool(INPUT) |   val ordered = Bool(INPUT) | ||||||
| } | } | ||||||
|  |  | ||||||
| trait HasSDQId extends CoreBundle with L1HellaCacheParameters { | class L1DataReadReq extends L1HellaCacheBundle { | ||||||
|   val sdq_id = UInt(width = log2Up(sdqDepth)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| trait HasMissInfo extends CoreBundle with L1HellaCacheParameters { |  | ||||||
|   val tag_match = Bool() |  | ||||||
|   val old_meta = new L1Metadata |  | ||||||
|   val way_en = Bits(width = nWays) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| class Replay extends HellaCacheReqInternal with HasCoreData |  | ||||||
| class ReplayInternal extends HellaCacheReqInternal with HasSDQId |  | ||||||
| class MSHRReq extends Replay with HasMissInfo |  | ||||||
| class MSHRReqInternal extends ReplayInternal with HasMissInfo |  | ||||||
|  |  | ||||||
| class DataReadReq extends L1HellaCacheBundle { |  | ||||||
|   val way_en = Bits(width = nWays) |   val way_en = Bits(width = nWays) | ||||||
|   val addr   = Bits(width = untagBits) |   val addr   = Bits(width = untagBits) | ||||||
| } | } | ||||||
|  |  | ||||||
| class DataWriteReq extends DataReadReq { | class L1DataWriteReq extends L1DataReadReq { | ||||||
|   val wmask  = Bits(width = rowWords) |   val wmask  = Bits(width = rowWords) | ||||||
|   val data   = Bits(width = encRowBits) |   val data   = Bits(width = encRowBits) | ||||||
| } | } | ||||||
| @@ -152,14 +116,16 @@ class L1Metadata extends Metadata with L1HellaCacheParameters { | |||||||
|   val coh = co.clientMetadataOnFlush.clone |   val coh = co.clientMetadataOnFlush.clone | ||||||
| } | } | ||||||
|  |  | ||||||
| class InternalProbe extends Probe with HasClientTransactionId | class Replay extends HellaCacheReqInternal with HasCoreData | ||||||
|  | class ReplayInternal extends HellaCacheReqInternal with HasSDQId | ||||||
|  |  | ||||||
| class WritebackReq extends L1HellaCacheBundle { | class MSHRReq extends Replay with HasMissInfo | ||||||
|   val tag = Bits(width = tagBits) | class MSHRReqInternal extends ReplayInternal with HasMissInfo | ||||||
|   val idx = Bits(width = idxBits) |  | ||||||
|  | class ProbeInternal extends Probe with HasClientTransactionId | ||||||
|  |  | ||||||
|  | class WritebackReq extends Release with CacheParameters { | ||||||
|   val way_en = Bits(width = nWays) |   val way_en = Bits(width = nWays) | ||||||
|   val client_xact_id = Bits(width = params(TLClientXactIdBits)) |  | ||||||
|   val r_type = UInt(width = co.releaseTypeWidth)  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| class MSHR(id: Int) extends L1HellaCacheModule { | class MSHR(id: Int) extends L1HellaCacheModule { | ||||||
| @@ -174,7 +140,7 @@ class MSHR(id: Int) extends L1HellaCacheModule { | |||||||
|     val tag             = Bits(OUTPUT, tagBits) |     val tag             = Bits(OUTPUT, tagBits) | ||||||
|  |  | ||||||
|     val mem_req  = Decoupled(new Acquire) |     val mem_req  = Decoupled(new Acquire) | ||||||
|     val mem_resp = new DataWriteReq().asOutput |     val mem_resp = new L1DataWriteReq().asOutput | ||||||
|     val meta_read = Decoupled(new L1MetaReadReq) |     val meta_read = Decoupled(new L1MetaReadReq) | ||||||
|     val meta_write = Decoupled(new L1MetaWriteReq) |     val meta_write = Decoupled(new L1MetaWriteReq) | ||||||
|     val replay = Decoupled(new ReplayInternal) |     val replay = Decoupled(new ReplayInternal) | ||||||
| @@ -188,17 +154,19 @@ class MSHR(id: Int) extends L1HellaCacheModule { | |||||||
|   val state = Reg(init=s_invalid) |   val state = Reg(init=s_invalid) | ||||||
|  |  | ||||||
|   val acquire_type = Reg(UInt()) |   val acquire_type = Reg(UInt()) | ||||||
|   val release_type = Reg(UInt()) |  | ||||||
|   val line_state = Reg(new ClientMetadata) |   val line_state = Reg(new ClientMetadata) | ||||||
|   val req = Reg(new MSHRReqInternal()) |   val req = Reg(new MSHRReqInternal()) | ||||||
|  |  | ||||||
|   val req_cmd = io.req_bits.cmd |   val req_cmd = io.req_bits.cmd | ||||||
|   val req_idx = req.addr(untagBits-1,blockOffBits) |   val req_idx = req.addr(untagBits-1,blockOffBits) | ||||||
|   val idx_match = req_idx === io.req_bits.addr(untagBits-1,blockOffBits) |   val idx_match = req_idx === io.req_bits.addr(untagBits-1,blockOffBits) | ||||||
|   val sec_rdy = idx_match && (state === s_wb_req || state === s_wb_resp || state === s_meta_clear || (state === s_refill_req || state === s_refill_resp) && !co.needsTransactionOnSecondaryMiss(req_cmd, io.mem_req.bits)) |   val sec_rdy = idx_match && !co.needsTransactionOnSecondaryMiss(req_cmd, io.mem_req.bits) && | ||||||
|  |                   Vec(s_wb_req, s_wb_resp, s_meta_clear, s_refill_req, s_refill_resp).contains(state) | ||||||
|  |  | ||||||
|   val reply = io.mem_grant.valid && io.mem_grant.bits.payload.client_xact_id === UInt(id) |   val reply = io.mem_grant.valid && io.mem_grant.bits.payload.client_xact_id === UInt(id) | ||||||
|   val (refill_cnt, refill_done) = Counter(reply && co.messageUpdatesDataArray(io.mem_grant.bits.payload), refillCycles) // TODO: Zero width? |   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 wb_done = reply && (state === s_wb_resp) | ||||||
|  |  | ||||||
|   val meta_on_flush = co.clientMetadataOnFlush |   val meta_on_flush = co.clientMetadataOnFlush | ||||||
| @@ -234,16 +202,14 @@ class MSHR(id: Int) extends L1HellaCacheModule { | |||||||
|     state := s_meta_clear |     state := s_meta_clear | ||||||
|   } |   } | ||||||
|   when (io.wb_req.fire()) { // s_wb_req |   when (io.wb_req.fire()) { // s_wb_req | ||||||
|     state := s_wb_resp  |     state := Mux(io.wb_req.bits.requiresAck(), s_wb_resp, s_meta_clear) | ||||||
|   } |   } | ||||||
|   when (io.req_sec_val && io.req_sec_rdy) { // s_wb_req, s_wb_resp, s_refill_req |   when (io.req_sec_val && io.req_sec_rdy) { // s_wb_req, s_wb_resp, s_refill_req | ||||||
|     acquire_type := co.getAcquireTypeOnSecondaryMiss(req_cmd, meta_on_flush, io.mem_req.bits) |     acquire_type := co.getAcquireTypeOnSecondaryMiss(req_cmd, meta_on_flush, io.mem_req.bits) | ||||||
|   } |   } | ||||||
|   when (io.req_pri_val && io.req_pri_rdy) { |   when (io.req_pri_val && io.req_pri_rdy) { | ||||||
|     line_state := meta_on_flush |     line_state := meta_on_flush | ||||||
|     refill_cnt := UInt(0) |  | ||||||
|     acquire_type := co.getAcquireTypeOnPrimaryMiss(req_cmd, meta_on_flush) |     acquire_type := co.getAcquireTypeOnPrimaryMiss(req_cmd, meta_on_flush) | ||||||
|     release_type := co.getReleaseTypeOnVoluntaryWriteback() //TODO downgrades etc  |  | ||||||
|     req := io.req_bits |     req := io.req_bits | ||||||
|  |  | ||||||
|     when (io.req_bits.tag_match) { |     when (io.req_bits.tag_match) { | ||||||
| @@ -259,8 +225,8 @@ class MSHR(id: Int) extends L1HellaCacheModule { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   val ackq = Module(new Queue(new LogicalNetworkIO(new Finish), 1)) |   val ackq = Module(new Queue(new LogicalNetworkIO(new Finish), 1)) | ||||||
|   ackq.io.enq.valid := (wb_done || refill_done) && co.requiresAckForGrant(io.mem_grant.bits.payload) |   ackq.io.enq.valid := (wb_done || refill_done) && io.mem_grant.bits.payload.requiresAck() | ||||||
|   ackq.io.enq.bits.payload.manager_xact_id := io.mem_grant.bits.payload.manager_xact_id |   ackq.io.enq.bits.payload := io.mem_grant.bits.payload.makeFinish() | ||||||
|   ackq.io.enq.bits.header.dst := io.mem_grant.bits.header.src |   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 |   val can_finish = state === s_invalid || state === s_refill_req || state === s_refill_resp | ||||||
|   io.mem_finish.valid := ackq.io.deq.valid && can_finish |   io.mem_finish.valid := ackq.io.deq.valid && can_finish | ||||||
| @@ -286,14 +252,17 @@ class MSHR(id: Int) extends L1HellaCacheModule { | |||||||
|   io.meta_write.bits.way_en := req.way_en |   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 && ackq.io.enq.ready | ||||||
|   io.wb_req.bits.tag := req.old_meta.tag |   io.wb_req.bits := Release.makeVoluntaryWriteback( | ||||||
|   io.wb_req.bits.idx := req_idx |                       meta = req.old_meta.coh, | ||||||
|  |                       client_xact_id = UInt(id), | ||||||
|  |                       addr_block = Cat(req.old_meta.tag, req_idx)) | ||||||
|   io.wb_req.bits.way_en := req.way_en |   io.wb_req.bits.way_en := req.way_en | ||||||
|   io.wb_req.bits.client_xact_id := Bits(id) |  | ||||||
|   io.wb_req.bits.r_type := co.getReleaseTypeOnVoluntaryWriteback() |  | ||||||
|  |  | ||||||
|   io.mem_req.valid := state === s_refill_req && ackq.io.enq.ready |   io.mem_req.valid := state === s_refill_req && ackq.io.enq.ready | ||||||
|   io.mem_req.bits := Acquire(acquire_type, Cat(io.tag, req_idx).toUInt, Bits(id)) |   io.mem_req.bits := Acquire( | ||||||
|  |                        a_type = acquire_type, | ||||||
|  |                        addr_block = Cat(io.tag, req_idx).toUInt, | ||||||
|  |                        client_xact_id = Bits(id)) | ||||||
|   io.mem_finish <> ackq.io.deq |   io.mem_finish <> ackq.io.deq | ||||||
|  |  | ||||||
|   io.meta_read.valid := state === s_drain_rpq |   io.meta_read.valid := state === s_drain_rpq | ||||||
| @@ -317,7 +286,7 @@ class MSHRFile extends L1HellaCacheModule { | |||||||
|     val secondary_miss = Bool(OUTPUT) |     val secondary_miss = Bool(OUTPUT) | ||||||
|  |  | ||||||
|     val mem_req  = Decoupled(new Acquire) |     val mem_req  = Decoupled(new Acquire) | ||||||
|     val mem_resp = new DataWriteReq().asOutput |     val mem_resp = new L1DataWriteReq().asOutput | ||||||
|     val meta_read = Decoupled(new L1MetaReadReq) |     val meta_read = Decoupled(new L1MetaReadReq) | ||||||
|     val meta_write = Decoupled(new L1MetaWriteReq) |     val meta_write = Decoupled(new L1MetaWriteReq) | ||||||
|     val replay = Decoupled(new Replay) |     val replay = Decoupled(new Replay) | ||||||
| @@ -341,10 +310,14 @@ class MSHRFile extends L1HellaCacheModule { | |||||||
|   val tag_match = Mux1H(idxMatch, tagList) === io.req.bits.addr >> untagBits |   val tag_match = Mux1H(idxMatch, tagList) === io.req.bits.addr >> untagBits | ||||||
|  |  | ||||||
|   val wbTagList = Vec.fill(nMSHRs){Bits()} |   val wbTagList = Vec.fill(nMSHRs){Bits()} | ||||||
|   val memRespMux = Vec.fill(nMSHRs){new DataWriteReq} |   val memRespMux = Vec.fill(nMSHRs){new L1DataWriteReq} | ||||||
|   val meta_read_arb = Module(new Arbiter(new L1MetaReadReq, nMSHRs)) |   val meta_read_arb = Module(new Arbiter(new L1MetaReadReq, nMSHRs)) | ||||||
|   val meta_write_arb = Module(new Arbiter(new L1MetaWriteReq, nMSHRs)) |   val meta_write_arb = Module(new Arbiter(new L1MetaWriteReq, nMSHRs)) | ||||||
|   val mem_req_arb = Module(new LockingArbiter(new Acquire, nMSHRs, outerDataBeats, co.messageHasData _)) |   val mem_req_arb = Module(new LockingArbiter( | ||||||
|  |                                   new Acquire, | ||||||
|  |                                   nMSHRs, | ||||||
|  |                                   outerDataBeats, | ||||||
|  |                                   (a: Acquire) => a.hasMultibeatData())) | ||||||
|   val mem_finish_arb = Module(new Arbiter(new LogicalNetworkIO(new Finish), nMSHRs)) |   val mem_finish_arb = Module(new Arbiter(new LogicalNetworkIO(new Finish), nMSHRs)) | ||||||
|   val wb_req_arb = Module(new Arbiter(new WritebackReq, nMSHRs)) |   val wb_req_arb = Module(new Arbiter(new WritebackReq, nMSHRs)) | ||||||
|   val replay_arb = Module(new Arbiter(new ReplayInternal, nMSHRs)) |   val replay_arb = Module(new Arbiter(new ReplayInternal, nMSHRs)) | ||||||
| @@ -362,7 +335,7 @@ class MSHRFile extends L1HellaCacheModule { | |||||||
|  |  | ||||||
|     idxMatch(i) := mshr.io.idx_match |     idxMatch(i) := mshr.io.idx_match | ||||||
|     tagList(i) := mshr.io.tag |     tagList(i) := mshr.io.tag | ||||||
|     wbTagList(i) := mshr.io.wb_req.bits.tag |     wbTagList(i) := mshr.io.wb_req.bits.addr_block >> UInt(idxBits) | ||||||
|  |  | ||||||
|     alloc_arb.io.in(i).valid := mshr.io.req_pri_rdy |     alloc_arb.io.in(i).valid := mshr.io.req_pri_rdy | ||||||
|     mshr.io.req_pri_val := alloc_arb.io.in(i).ready |     mshr.io.req_pri_val := alloc_arb.io.in(i).ready | ||||||
| @@ -413,9 +386,9 @@ class MSHRFile extends L1HellaCacheModule { | |||||||
|  |  | ||||||
| class WritebackUnit extends L1HellaCacheModule { | class WritebackUnit extends L1HellaCacheModule { | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val req = Decoupled(new WritebackReq()).flip |     val req = Decoupled(new WritebackReq).flip | ||||||
|     val meta_read = Decoupled(new L1MetaReadReq) |     val meta_read = Decoupled(new L1MetaReadReq) | ||||||
|     val data_req = Decoupled(new DataReadReq()) |     val data_req = Decoupled(new L1DataReadReq) | ||||||
|     val data_resp = Bits(INPUT, encRowBits) |     val data_resp = Bits(INPUT, encRowBits) | ||||||
|     val release = Decoupled(new Release) |     val release = Decoupled(new Release) | ||||||
|   } |   } | ||||||
| @@ -423,9 +396,10 @@ class WritebackUnit extends L1HellaCacheModule { | |||||||
|   val active = Reg(init=Bool(false)) |   val active = Reg(init=Bool(false)) | ||||||
|   val r1_data_req_fired = Reg(init=Bool(false)) |   val r1_data_req_fired = Reg(init=Bool(false)) | ||||||
|   val r2_data_req_fired = Reg(init=Bool(false)) |   val r2_data_req_fired = Reg(init=Bool(false)) | ||||||
|   val cnt = Reg(init = UInt(0, width = log2Up(refillCycles+1))) //TODO Zero width |   val data_req_cnt = Reg(init = UInt(0, width = log2Up(refillCycles+1))) //TODO Zero width | ||||||
|   val buf_v = (if(refillCyclesPerBeat > 1) Reg(init=Bits(0, width = refillCyclesPerBeat-1)) else Bits(1)) |   val buf_v = (if(refillCyclesPerBeat > 1) Reg(init=Bits(0, width = refillCyclesPerBeat-1)) else Bits(1)) | ||||||
|   val beat_done = buf_v.andR |   val beat_done = buf_v.andR | ||||||
|  |   val (beat_cnt, all_beats_done) = Counter(io.release.fire(), outerDataBeats) | ||||||
|   val req = Reg(new WritebackReq) |   val req = Reg(new WritebackReq) | ||||||
|  |  | ||||||
|   io.release.valid := false |   io.release.valid := false | ||||||
| @@ -434,59 +408,62 @@ class WritebackUnit extends L1HellaCacheModule { | |||||||
|     r2_data_req_fired := r1_data_req_fired |     r2_data_req_fired := r1_data_req_fired | ||||||
|     when (io.data_req.fire() && io.meta_read.fire()) { |     when (io.data_req.fire() && io.meta_read.fire()) { | ||||||
|       r1_data_req_fired := true |       r1_data_req_fired := true | ||||||
|       cnt := cnt + 1 |       data_req_cnt := data_req_cnt + 1 | ||||||
|     } |     } | ||||||
|     when (r2_data_req_fired) { |     when (r2_data_req_fired) { | ||||||
|       io.release.valid := beat_done |       io.release.valid := beat_done | ||||||
|       when(!io.release.ready) { |       when(!io.release.ready) { | ||||||
|         r1_data_req_fired := false |         r1_data_req_fired := false | ||||||
|         r2_data_req_fired := false |         r2_data_req_fired := false | ||||||
|         cnt := cnt - Mux[UInt](Bool(refillCycles > 1) && r1_data_req_fired, 2, 1) |         data_req_cnt := data_req_cnt - Mux[UInt](Bool(refillCycles > 1) && r1_data_req_fired, 2, 1) | ||||||
|       } .elsewhen(beat_done) { if(refillCyclesPerBeat > 1) buf_v := 0 } |       } .elsewhen(beat_done) { if(refillCyclesPerBeat > 1) buf_v := 0 } | ||||||
|       when(!r1_data_req_fired) { |       when(!r1_data_req_fired) { | ||||||
|         active := cnt < UInt(refillCycles) |         active := data_req_cnt < UInt(refillCycles) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   when (io.req.fire()) { |   when (io.req.fire()) { | ||||||
|     active := true |     active := true | ||||||
|     cnt := 0 |     data_req_cnt := 0 | ||||||
|     if(refillCyclesPerBeat > 1) buf_v := 0 |     if(refillCyclesPerBeat > 1) buf_v := 0 | ||||||
|     req := io.req.bits |     req := io.req.bits | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   val fire = active && cnt < UInt(refillCycles) |  | ||||||
|   io.req.ready := !active |   io.req.ready := !active | ||||||
|  |  | ||||||
|   // We reissue the meta read as it sets up the muxing for s2_data_muxed |   val req_idx = req.addr_block(idxBits-1, 0) | ||||||
|  |   val fire = active && data_req_cnt < UInt(refillCycles) | ||||||
|  |  | ||||||
|  |   // We reissue the meta read as it sets up the mux ctrl for s2_data_muxed | ||||||
|   io.meta_read.valid := fire |   io.meta_read.valid := fire | ||||||
|   io.meta_read.bits.idx := req.idx |   io.meta_read.bits.idx := req_idx | ||||||
|   io.meta_read.bits.tag := req.tag |   io.meta_read.bits.tag := req.addr_block >> UInt(idxBits) | ||||||
|  |  | ||||||
|   io.data_req.valid := fire |   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 := (if(refillCycles > 1) Cat(req.idx, cnt(log2Up(refillCycles)-1,0)) |   io.data_req.bits.addr := (if(refillCycles > 1)  | ||||||
|                             else req.idx) << rowOffBits |                               Cat(req_idx, data_req_cnt(log2Up(refillCycles)-1,0)) | ||||||
|  |                             else req_idx) << rowOffBits | ||||||
|  |  | ||||||
|   io.release.bits.r_type := req.r_type |   io.release.bits := req | ||||||
|   io.release.bits.addr := Cat(req.tag, req.idx).toUInt |   io.release.bits.addr_beat := beat_cnt | ||||||
|   io.release.bits.client_xact_id := req.client_xact_id |   io.release.bits.data := (if(refillCyclesPerBeat > 1) { | ||||||
|   io.release.bits.data :=  |     // If the cache rows are narrower than a TLDataBeat,  | ||||||
|     (if(refillCyclesPerBeat > 1) { |     //   then buffer enough data_resps to make a whole beat | ||||||
|       val data_buf = Reg(Bits()) |     val data_buf = Reg(Bits()) | ||||||
|       when(active && r2_data_req_fired && !beat_done) { |     when(active && r2_data_req_fired && !beat_done) { | ||||||
|         data_buf := Cat(io.data_resp, data_buf((refillCyclesPerBeat-1)*encRowBits-1, encRowBits)) |       data_buf := Cat(io.data_resp, data_buf((refillCyclesPerBeat-1)*encRowBits-1, encRowBits)) | ||||||
|         buf_v := (if(refillCyclesPerBeat > 2) |       buf_v := (if(refillCyclesPerBeat > 2) | ||||||
|                     Cat(UInt(1), buf_v(refillCyclesPerBeat-2,1)) |                   Cat(UInt(1), buf_v(refillCyclesPerBeat-2,1)) | ||||||
|                   else UInt(1)) |                 else UInt(1)) | ||||||
|       } |     } | ||||||
|       Cat(io.data_resp, data_buf) |     Cat(io.data_resp, data_buf) | ||||||
|     } else { io.data_resp }) |   } else { io.data_resp }) | ||||||
| } | } | ||||||
|  |  | ||||||
| class ProbeUnit extends L1HellaCacheModule { | class ProbeUnit extends L1HellaCacheModule { | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val req = Decoupled(new InternalProbe).flip |     val req = Decoupled(new ProbeInternal).flip | ||||||
|     val rep = Decoupled(new Release) |     val rep = Decoupled(new Release) | ||||||
|     val meta_read = Decoupled(new L1MetaReadReq) |     val meta_read = Decoupled(new L1MetaReadReq) | ||||||
|     val meta_write = Decoupled(new L1MetaWriteReq) |     val meta_write = Decoupled(new L1MetaWriteReq) | ||||||
| @@ -500,7 +477,7 @@ class ProbeUnit extends L1HellaCacheModule { | |||||||
|   val state = Reg(init=s_invalid) |   val state = Reg(init=s_invalid) | ||||||
|   val line_state = Reg(co.clientMetadataOnFlush.clone) |   val line_state = Reg(co.clientMetadataOnFlush.clone) | ||||||
|   val way_en = Reg(Bits()) |   val way_en = Reg(Bits()) | ||||||
|   val req = Reg(new InternalProbe) |   val req = Reg(new ProbeInternal) | ||||||
|   val hit = way_en.orR |   val hit = way_en.orR | ||||||
|  |  | ||||||
|   when (state === s_meta_write && io.meta_write.ready) { |   when (state === s_meta_write && io.meta_write.ready) { | ||||||
| @@ -538,36 +515,32 @@ class ProbeUnit extends L1HellaCacheModule { | |||||||
|     state := s_invalid |     state := s_invalid | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   val reply = Mux(hit, req.makeRelease(req.client_xact_id, line_state), | ||||||
|  |                        req.makeRelease(req.client_xact_id)) | ||||||
|   io.req.ready := state === s_invalid |   io.req.ready := state === s_invalid | ||||||
|   io.rep.valid := state === s_release && |   io.rep.valid := state === s_release && | ||||||
|                   !(hit && co.needsWriteback(line_state)) // Otherwise WBU will issue release |                   !(hit && co.needsWriteback(line_state)) // Otherwise WBU will issue release | ||||||
|   io.rep.bits := Release(co.getReleaseTypeOnProbe(req, |   io.rep.bits := reply | ||||||
|                                                   Mux(hit, line_state, co.clientMetadataOnFlush)), |  | ||||||
|                                                   req.addr,  |  | ||||||
|                                                   req.client_xact_id) |  | ||||||
|  |  | ||||||
|   io.meta_read.valid := state === s_meta_read |   io.meta_read.valid := state === s_meta_read | ||||||
|   io.meta_read.bits.idx := req.addr |   io.meta_read.bits.idx := req.addr_block | ||||||
|   io.meta_read.bits.tag := req.addr >> idxBits |   io.meta_read.bits.tag := req.addr_block >> idxBits | ||||||
|  |  | ||||||
|   io.meta_write.valid := state === s_meta_write |   io.meta_write.valid := state === s_meta_write | ||||||
|   io.meta_write.bits.way_en := way_en |   io.meta_write.bits.way_en := way_en | ||||||
|   io.meta_write.bits.idx := req.addr |   io.meta_write.bits.idx := req.addr_block | ||||||
|  |   io.meta_write.bits.data.tag := req.addr_block >> idxBits | ||||||
|   io.meta_write.bits.data.coh := co.clientMetadataOnProbe(req, line_state) |   io.meta_write.bits.data.coh := co.clientMetadataOnProbe(req, line_state) | ||||||
|   io.meta_write.bits.data.tag := req.addr >> UInt(idxBits) |  | ||||||
|  |  | ||||||
|   io.wb_req.valid := state === s_writeback_req |   io.wb_req.valid := state === s_writeback_req | ||||||
|  |   io.wb_req.bits := reply | ||||||
|   io.wb_req.bits.way_en := way_en |   io.wb_req.bits.way_en := way_en | ||||||
|   io.wb_req.bits.idx := req.addr |  | ||||||
|   io.wb_req.bits.tag := req.addr >> UInt(idxBits) |  | ||||||
|   io.wb_req.bits.r_type := co.getReleaseTypeOnProbe(req, Mux(hit, line_state, co.clientMetadataOnFlush)) |  | ||||||
|   io.wb_req.bits.client_xact_id := req.client_xact_id |  | ||||||
| } | } | ||||||
|  |  | ||||||
| class DataArray extends L1HellaCacheModule { | class DataArray extends L1HellaCacheModule { | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val read = Decoupled(new DataReadReq).flip |     val read = Decoupled(new L1DataReadReq).flip | ||||||
|     val write = Decoupled(new DataWriteReq).flip |     val write = Decoupled(new L1DataWriteReq).flip | ||||||
|     val resp = Vec.fill(nWays){Bits(OUTPUT, encRowBits)} |     val resp = Vec.fill(nWays){Bits(OUTPUT, encRowBits)} | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -612,47 +585,6 @@ class DataArray extends L1HellaCacheModule { | |||||||
|   io.write.ready := Bool(true) |   io.write.ready := Bool(true) | ||||||
| } | } | ||||||
|  |  | ||||||
| class AMOALU extends L1HellaCacheModule { |  | ||||||
|   val io = new Bundle { |  | ||||||
|     val addr = Bits(INPUT, blockOffBits) |  | ||||||
|     val cmd = Bits(INPUT, 4) |  | ||||||
|     val typ = Bits(INPUT, 3) |  | ||||||
|     val lhs = Bits(INPUT, coreDataBits) |  | ||||||
|     val rhs = Bits(INPUT, coreDataBits) |  | ||||||
|     val out = Bits(OUTPUT, coreDataBits) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   require(coreDataBits == 64) |  | ||||||
|   val storegen = new StoreGen(io.typ, io.addr, io.rhs) |  | ||||||
|   val rhs = storegen.wordData |  | ||||||
|    |  | ||||||
|   val sgned = io.cmd === M_XA_MIN || io.cmd === M_XA_MAX |  | ||||||
|   val max = io.cmd === M_XA_MAX || io.cmd === M_XA_MAXU |  | ||||||
|   val min = io.cmd === M_XA_MIN || io.cmd === M_XA_MINU |  | ||||||
|   val word = io.typ === MT_W || io.typ === MT_WU || io.typ === MT_B || io.typ === MT_BU |  | ||||||
|  |  | ||||||
|   val mask = SInt(-1,64) ^ (io.addr(2) << 31) |  | ||||||
|   val adder_out = (io.lhs & mask).toUInt + (rhs & mask) |  | ||||||
|  |  | ||||||
|   val cmp_lhs  = Mux(word && !io.addr(2), io.lhs(31), io.lhs(63)) |  | ||||||
|   val cmp_rhs  = Mux(word && !io.addr(2), rhs(31), rhs(63)) |  | ||||||
|   val lt_lo = io.lhs(31,0) < rhs(31,0) |  | ||||||
|   val lt_hi = io.lhs(63,32) < rhs(63,32) |  | ||||||
|   val eq_hi = io.lhs(63,32) === rhs(63,32) |  | ||||||
|   val lt = Mux(word, Mux(io.addr(2), lt_hi, lt_lo), lt_hi || eq_hi && lt_lo) |  | ||||||
|   val less = Mux(cmp_lhs === cmp_rhs, lt, Mux(sgned, cmp_lhs, cmp_rhs)) |  | ||||||
|  |  | ||||||
|   val out = Mux(io.cmd === M_XA_ADD, adder_out, |  | ||||||
|             Mux(io.cmd === M_XA_AND, io.lhs & rhs, |  | ||||||
|             Mux(io.cmd === M_XA_OR,  io.lhs | rhs, |  | ||||||
|             Mux(io.cmd === M_XA_XOR, io.lhs ^ rhs, |  | ||||||
|             Mux(Mux(less, min, max), io.lhs, |  | ||||||
|             storegen.data))))) |  | ||||||
|  |  | ||||||
|   val wmask = FillInterleaved(8, storegen.mask) |  | ||||||
|   io.out := wmask & out | ~wmask & io.lhs |  | ||||||
| } |  | ||||||
|  |  | ||||||
| class HellaCache extends L1HellaCacheModule { | class HellaCache extends L1HellaCacheModule { | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val cpu = (new HellaCacheIO).flip |     val cpu = (new HellaCacheIO).flip | ||||||
| @@ -693,7 +625,7 @@ class HellaCache extends L1HellaCacheModule { | |||||||
|   val s1_sc = s1_req.cmd === M_XSC |   val s1_sc = s1_req.cmd === M_XSC | ||||||
|   val s1_readwrite = s1_read || s1_write || isPrefetch(s1_req.cmd) |   val s1_readwrite = s1_read || s1_write || isPrefetch(s1_req.cmd) | ||||||
|  |  | ||||||
|   val dtlb = Module(new TLB(params(NDTLBEntries))) |   val dtlb = Module(new TLB) | ||||||
|   dtlb.io.ptw <> io.cpu.ptw |   dtlb.io.ptw <> io.cpu.ptw | ||||||
|   dtlb.io.req.valid := s1_valid_masked && s1_readwrite && !s1_req.phys |   dtlb.io.req.valid := s1_valid_masked && s1_readwrite && !s1_req.phys | ||||||
|   dtlb.io.req.bits.passthrough := s1_req.phys |   dtlb.io.req.bits.passthrough := s1_req.phys | ||||||
| @@ -754,8 +686,8 @@ class HellaCache extends L1HellaCacheModule { | |||||||
|  |  | ||||||
|   // data |   // data | ||||||
|   val data = Module(new DataArray) |   val data = Module(new DataArray) | ||||||
|   val readArb = Module(new Arbiter(new DataReadReq, 4)) |   val readArb = Module(new Arbiter(new L1DataReadReq, 4)) | ||||||
|   val writeArb = Module(new Arbiter(new DataWriteReq, 2)) |   val writeArb = Module(new Arbiter(new L1DataWriteReq, 2)) | ||||||
|   data.io.write.valid := writeArb.io.out.valid |   data.io.write.valid := writeArb.io.out.valid | ||||||
|   writeArb.io.out.ready := data.io.write.ready |   writeArb.io.out.ready := data.io.write.ready | ||||||
|   data.io.write.bits := writeArb.io.out.bits |   data.io.write.bits := writeArb.io.out.bits | ||||||
| @@ -837,9 +769,9 @@ class HellaCache extends L1HellaCacheModule { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   writeArb.io.in(0).bits.addr := s3_req.addr |   writeArb.io.in(0).bits.addr := s3_req.addr | ||||||
|   writeArb.io.in(0).bits.wmask := UInt(1) << (if(rowOffBits > offsetlsb)  |   val rowIdx = s3_req.addr(rowOffBits-1,offsetlsb).toUInt | ||||||
|                                                 s3_req.addr(rowOffBits-1,offsetlsb).toUInt |   val rowWMask = UInt(1) << (if(rowOffBits > offsetlsb) rowIdx else UInt(0)) | ||||||
|                                               else UInt(0)) |   writeArb.io.in(0).bits.wmask := rowWMask | ||||||
|   writeArb.io.in(0).bits.data := Fill(rowWords, s3_req.data) |   writeArb.io.in(0).bits.data := Fill(rowWords, 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 | ||||||
| @@ -871,7 +803,7 @@ class HellaCache extends L1HellaCacheModule { | |||||||
|   metaWriteArb.io.in(0) <> mshrs.io.meta_write |   metaWriteArb.io.in(0) <> mshrs.io.meta_write | ||||||
|  |  | ||||||
|   // probes and releases |   // probes and releases | ||||||
|   val releaseArb = Module(new LockingArbiter(new Release, 2, outerDataBeats, co.messageHasData _)) |   val releaseArb = Module(new LockingArbiter(new Release, 2, outerDataBeats, (r: Release) => r.hasMultibeatData())) | ||||||
|   DecoupledLogicalNetworkIOWrapper(releaseArb.io.out) <> io.mem.release |   DecoupledLogicalNetworkIOWrapper(releaseArb.io.out) <> io.mem.release | ||||||
|  |  | ||||||
|   val probe = DecoupledLogicalNetworkIOUnwrapper(io.mem.probe) |   val probe = DecoupledLogicalNetworkIOUnwrapper(io.mem.probe) | ||||||
| @@ -886,14 +818,15 @@ class HellaCache extends L1HellaCacheModule { | |||||||
|   prober.io.mshr_rdy := mshrs.io.probe_rdy |   prober.io.mshr_rdy := mshrs.io.probe_rdy | ||||||
|  |  | ||||||
|   // refills |   // refills | ||||||
|   def doRefill(g: Grant): Bool = co.messageUpdatesDataArray(g) |   val ser = Module(new FlowThroughSerializer( | ||||||
|   val ser = Module(new FlowThroughSerializer(io.mem.grant.bits, refillCyclesPerBeat, doRefill)) |                           io.mem.grant.bits, | ||||||
|  |                           refillCyclesPerBeat)) | ||||||
|   ser.io.in <> io.mem.grant |   ser.io.in <> io.mem.grant | ||||||
|   val refill = ser.io.out |   val refill = ser.io.out | ||||||
|   mshrs.io.mem_grant.valid := refill.fire() |   mshrs.io.mem_grant.valid := refill.fire() | ||||||
|   mshrs.io.mem_grant.bits := refill.bits |   mshrs.io.mem_grant.bits := refill.bits | ||||||
|   refill.ready := writeArb.io.in(1).ready || !doRefill(refill.bits.payload) |   refill.ready := writeArb.io.in(1).ready || !refill.bits.payload.hasData() | ||||||
|   writeArb.io.in(1).valid := refill.valid && doRefill(refill.bits.payload) |   writeArb.io.in(1).valid := refill.valid && refill.bits.payload.hasData() | ||||||
|   writeArb.io.in(1).bits := mshrs.io.mem_resp |   writeArb.io.in(1).bits := mshrs.io.mem_resp | ||||||
|   writeArb.io.in(1).bits.wmask := SInt(-1) |   writeArb.io.in(1).bits.wmask := SInt(-1) | ||||||
|   writeArb.io.in(1).bits.data := refill.bits.payload.data(encRowBits-1,0) |   writeArb.io.in(1).bits.data := refill.bits.payload.data(encRowBits-1,0) | ||||||
| @@ -1008,15 +941,15 @@ class SimpleHellaCacheIF extends Module | |||||||
|   io.cache.req.bits.data := RegEnable(req_arb.io.out.bits.data, s0_req_fire) |   io.cache.req.bits.data := RegEnable(req_arb.io.out.bits.data, s0_req_fire) | ||||||
|   io.cache.req <> req_arb.io.out |   io.cache.req <> req_arb.io.out | ||||||
|  |  | ||||||
|   // replay queues | /* replay queues: | ||||||
|   // replayq1 holds the older request |      replayq1 holds the older request. | ||||||
|   // replayq2 holds the newer request (for the first nack) |      replayq2 holds the newer request (for the first nack). | ||||||
|   // we need to split the queues like this for the case where the older request |      We need to split the queues like this for the case where the older request | ||||||
|   // goes through but gets nacked, while the newer request stalls |      goes through but gets nacked, while the newer request stalls. | ||||||
|   // if this happens, the newer request will go through before the older |      If this happens, the newer request will go through before the older one. | ||||||
|   // request |      We don't need to check replayq1.io.enq.ready and replayq2.io.enq.ready as | ||||||
|   // we don't need to check replayq1.io.enq.ready and replayq2.io.enq.ready as |      there will only be two requests going through at most. | ||||||
|   // there will only be two requests going through at most | */ | ||||||
|  |  | ||||||
|   // stash d$ request in stage 2 if nacked (older request) |   // stash d$ request in stage 2 if nacked (older request) | ||||||
|   replayq1.io.enq.valid := Bool(false) |   replayq1.io.enq.valid := Bool(false) | ||||||
|   | |||||||
| @@ -6,28 +6,28 @@ import Chisel._ | |||||||
| import uncore._ | import uncore._ | ||||||
| import Util._ | import Util._ | ||||||
|  |  | ||||||
| class PTWResp extends Bundle { | class PTWResp extends CoreBundle { | ||||||
|   val error = Bool() |   val error = Bool() | ||||||
|   val ppn = UInt(width = params(PPNBits)) |   val ppn = UInt(width = ppnBits) | ||||||
|   val perm = Bits(width = params(PermBits)) |   val perm = Bits(width = permBits) | ||||||
| } | } | ||||||
|  |  | ||||||
| class TLBPTWIO extends Bundle { | class TLBPTWIO extends CoreBundle { | ||||||
|   val req = Decoupled(UInt(width = params(VPNBits))) |   val req = Decoupled(UInt(width = vpnBits)) | ||||||
|   val resp = Valid(new PTWResp).flip |   val resp = Valid(new PTWResp).flip | ||||||
|   val status = new Status().asInput |   val status = new Status().asInput | ||||||
|   val invalidate = Bool(INPUT) |   val invalidate = Bool(INPUT) | ||||||
|   val sret = Bool(INPUT) |   val sret = Bool(INPUT) | ||||||
| } | } | ||||||
|  |  | ||||||
| class DatapathPTWIO extends Bundle { | class DatapathPTWIO extends CoreBundle { | ||||||
|   val ptbr = UInt(INPUT, params(PAddrBits)) |   val ptbr = UInt(INPUT, paddrBits) | ||||||
|   val invalidate = Bool(INPUT) |   val invalidate = Bool(INPUT) | ||||||
|   val sret = Bool(INPUT) |   val sret = Bool(INPUT) | ||||||
|   val status = new Status().asInput |   val status = new Status().asInput | ||||||
| } | } | ||||||
|  |  | ||||||
| class PTW(n: Int) extends Module | class PTW(n: Int) extends CoreModule | ||||||
| { | { | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val requestor = Vec.fill(n){new TLBPTWIO}.flip |     val requestor = Vec.fill(n){new TLBPTWIO}.flip | ||||||
| @@ -36,8 +36,8 @@ class PTW(n: Int) extends Module | |||||||
|   } |   } | ||||||
|    |    | ||||||
|   val levels = 3 |   val levels = 3 | ||||||
|   val bitsPerLevel = params(VPNBits)/levels |   val bitsPerLevel = vpnBits/levels | ||||||
|   require(params(VPNBits) == levels * bitsPerLevel) |   require(vpnBits == levels * bitsPerLevel) | ||||||
|  |  | ||||||
|   val s_ready :: s_req :: s_wait :: s_done :: s_error :: Nil = Enum(UInt(), 5) |   val s_ready :: s_req :: s_wait :: s_done :: s_error :: Nil = Enum(UInt(), 5) | ||||||
|   val state = Reg(init=s_ready) |   val state = Reg(init=s_ready) | ||||||
| @@ -49,14 +49,14 @@ class PTW(n: Int) extends Module | |||||||
|    |    | ||||||
|   val vpn_idx = Vec((0 until levels).map(i => (r_req_vpn >> (levels-i-1)*bitsPerLevel)(bitsPerLevel-1,0)))(count) |   val vpn_idx = Vec((0 until levels).map(i => (r_req_vpn >> (levels-i-1)*bitsPerLevel)(bitsPerLevel-1,0)))(count) | ||||||
|  |  | ||||||
|   val arb = Module(new RRArbiter(UInt(width = params(VPNBits)), n)) |   val arb = Module(new RRArbiter(UInt(width = vpnBits), n)) | ||||||
|   arb.io.in <> io.requestor.map(_.req) |   arb.io.in <> io.requestor.map(_.req) | ||||||
|   arb.io.out.ready := state === s_ready |   arb.io.out.ready := state === s_ready | ||||||
|  |  | ||||||
|   when (arb.io.out.fire()) { |   when (arb.io.out.fire()) { | ||||||
|     r_req_vpn := arb.io.out.bits |     r_req_vpn := arb.io.out.bits | ||||||
|     r_req_dest := arb.io.chosen |     r_req_dest := arb.io.chosen | ||||||
|     r_pte := Cat(io.dpath.ptbr(params(PAddrBits)-1,params(PgIdxBits)), io.mem.resp.bits.data(params(PgIdxBits)-1,0)) |     r_pte := Cat(io.dpath.ptbr(paddrBits-1,pgIdxBits), io.mem.resp.bits.data(pgIdxBits-1,0)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   when (io.mem.resp.valid) { |   when (io.mem.resp.valid) { | ||||||
| @@ -67,13 +67,13 @@ class PTW(n: Int) extends Module | |||||||
|   io.mem.req.bits.phys := Bool(true) |   io.mem.req.bits.phys := Bool(true) | ||||||
|   io.mem.req.bits.cmd  := M_XRD |   io.mem.req.bits.cmd  := M_XRD | ||||||
|   io.mem.req.bits.typ  := MT_D |   io.mem.req.bits.typ  := MT_D | ||||||
|   io.mem.req.bits.addr := Cat(r_pte(params(PAddrBits)-1,params(PgIdxBits)), vpn_idx).toUInt << log2Up(params(XprLen)/8) |   io.mem.req.bits.addr := Cat(r_pte(paddrBits-1,pgIdxBits), vpn_idx).toUInt << log2Up(xLen/8) | ||||||
|   io.mem.req.bits.kill := Bool(false) |   io.mem.req.bits.kill := Bool(false) | ||||||
|    |    | ||||||
|   val resp_val = state === s_done || state === s_error |   val resp_val = state === s_done || state === s_error | ||||||
|   val resp_err = state === s_error || state === s_wait |   val resp_err = state === s_error || state === s_wait | ||||||
|  |  | ||||||
|   val r_resp_ppn = io.mem.req.bits.addr >> UInt(params(PgIdxBits)) |   val r_resp_ppn = io.mem.req.bits.addr >> UInt(pgIdxBits) | ||||||
|   val resp_ppn = Vec((0 until levels-1).map(i => Cat(r_resp_ppn >> bitsPerLevel*(levels-i-1), r_req_vpn(bitsPerLevel*(levels-i-1)-1,0))) :+ r_resp_ppn)(count) |   val resp_ppn = Vec((0 until levels-1).map(i => Cat(r_resp_ppn >> bitsPerLevel*(levels-i-1), r_req_vpn(bitsPerLevel*(levels-i-1)-1,0))) :+ r_resp_ppn)(count) | ||||||
|  |  | ||||||
|   for (i <- 0 until io.requestor.size) { |   for (i <- 0 until io.requestor.size) { | ||||||
|   | |||||||
| @@ -19,17 +19,17 @@ class RoCCInstruction extends Bundle | |||||||
|   val opcode = Bits(width = 7) |   val opcode = Bits(width = 7) | ||||||
| } | } | ||||||
|  |  | ||||||
| class RoCCCommand extends Bundle | class RoCCCommand extends CoreBundle | ||||||
| { | { | ||||||
|   val inst = new RoCCInstruction |   val inst = new RoCCInstruction | ||||||
|   val rs1 = Bits(width = params(XprLen)) |   val rs1 = Bits(width = xLen) | ||||||
|   val rs2 = Bits(width = params(XprLen)) |   val rs2 = Bits(width = xLen) | ||||||
| } | } | ||||||
|  |  | ||||||
| class RoCCResponse extends Bundle | class RoCCResponse extends CoreBundle | ||||||
| { | { | ||||||
|   val rd = Bits(width = 5) |   val rd = Bits(width = 5) | ||||||
|   val data = Bits(width = params(XprLen)) |   val data = Bits(width = xLen) | ||||||
| } | } | ||||||
|  |  | ||||||
| class RoCCInterface extends Bundle | class RoCCInterface extends Bundle | ||||||
| @@ -50,7 +50,7 @@ class RoCCInterface extends Bundle | |||||||
|   val exception = Bool(INPUT) |   val exception = Bool(INPUT) | ||||||
| } | } | ||||||
|  |  | ||||||
| abstract class RoCC extends Module | abstract class RoCC extends CoreModule | ||||||
| { | { | ||||||
|   val io = new RoCCInterface |   val io = new RoCCInterface | ||||||
|   io.mem.req.bits.phys := Bool(true) // don't perform address translation |   io.mem.req.bits.phys := Bool(true) // don't perform address translation | ||||||
| @@ -59,7 +59,7 @@ abstract class RoCC extends Module | |||||||
| class AccumulatorExample extends RoCC | class AccumulatorExample extends RoCC | ||||||
| { | { | ||||||
|   val n = 4 |   val n = 4 | ||||||
|   val regfile = Mem(UInt(width = params(XprLen)), n) |   val regfile = Mem(UInt(width = xLen), n) | ||||||
|   val busy = Vec.fill(n){Reg(init=Bool(false))} |   val busy = Vec.fill(n){Reg(init=Bool(false))} | ||||||
|  |  | ||||||
|   val cmd = Queue(io.cmd) |   val cmd = Queue(io.cmd) | ||||||
|   | |||||||
| @@ -6,23 +6,33 @@ import Chisel._ | |||||||
| import uncore._ | import uncore._ | ||||||
| import scala.math._ | import scala.math._ | ||||||
|  |  | ||||||
| class CAMIO(entries: Int, addr_bits: Int, tag_bits: Int) extends Bundle { | case object NTLBEntries extends Field[Int] | ||||||
|  |  | ||||||
|  | abstract trait TLBParameters extends CoreParameters { | ||||||
|  |   val entries = params(NTLBEntries) | ||||||
|  |   val camAddrBits = ceil(log(entries)/log(2)).toInt | ||||||
|  |   val camTagBits = asIdBits + vpnBits | ||||||
|  | } | ||||||
|  |  | ||||||
|  | abstract class TLBBundle extends Bundle with TLBParameters | ||||||
|  | abstract class TLBModule extends Module with TLBParameters | ||||||
|  |  | ||||||
|  | class CAMIO extends TLBBundle { | ||||||
|     val clear        = Bool(INPUT) |     val clear        = Bool(INPUT) | ||||||
|     val clear_hit    = Bool(INPUT) |     val clear_hit    = Bool(INPUT) | ||||||
|     val tag          = Bits(INPUT, tag_bits) |     val tag          = Bits(INPUT, camTagBits) | ||||||
|     val hit          = Bool(OUTPUT) |     val hit          = Bool(OUTPUT) | ||||||
|     val hits         = UInt(OUTPUT, entries) |     val hits         = UInt(OUTPUT, entries) | ||||||
|     val valid_bits   = Bits(OUTPUT, entries) |     val valid_bits   = Bits(OUTPUT, entries) | ||||||
|      |      | ||||||
|     val write        = Bool(INPUT) |     val write        = Bool(INPUT) | ||||||
|     val write_tag    = Bits(INPUT, tag_bits) |     val write_tag    = Bits(INPUT, camTagBits) | ||||||
|     val write_addr    = UInt(INPUT, addr_bits) |     val write_addr    = UInt(INPUT, camAddrBits) | ||||||
| } | } | ||||||
|  |  | ||||||
| class RocketCAM(entries: Int, tag_bits: Int) extends Module { | class RocketCAM extends TLBModule { | ||||||
|   val addr_bits = ceil(log(entries)/log(2)).toInt |   val io = new CAMIO | ||||||
|   val io = new CAMIO(entries, addr_bits, tag_bits) |   val cam_tags = Mem(Bits(width = camTagBits), entries) | ||||||
|   val cam_tags = Mem(Bits(width = tag_bits), entries) |  | ||||||
|  |  | ||||||
|   val vb_array = Reg(init=Bits(0, entries)) |   val vb_array = Reg(init=Bits(0, entries)) | ||||||
|   when (io.write) { |   when (io.write) { | ||||||
| @@ -66,30 +76,27 @@ class PseudoLRU(n: Int) | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| class TLBReq extends Bundle | class TLBReq extends TLBBundle { | ||||||
| { |   val asid = UInt(width = asIdBits) | ||||||
|   val asid = UInt(width = params(ASIdBits)) |   val vpn = UInt(width = vpnBits+1) | ||||||
|   val vpn = UInt(width = params(VPNBits)+1) |  | ||||||
|   val passthrough = Bool() |   val passthrough = Bool() | ||||||
|   val instruction = Bool() |   val instruction = Bool() | ||||||
| } | } | ||||||
|  |  | ||||||
| class TLBResp(entries: Int) extends Bundle | class TLBResp(cnt: Option[Int] = None) extends TLBBundle { | ||||||
| { |  | ||||||
|   // lookup responses |   // lookup responses | ||||||
|   val miss = Bool(OUTPUT) |   val miss = Bool(OUTPUT) | ||||||
|   val hit_idx = UInt(OUTPUT, entries) |   val hit_idx = UInt(OUTPUT, cnt.getOrElse(entries)) | ||||||
|   val ppn = UInt(OUTPUT, params(PPNBits)) |   val ppn = UInt(OUTPUT, ppnBits) | ||||||
|   val xcpt_ld = Bool(OUTPUT) |   val xcpt_ld = Bool(OUTPUT) | ||||||
|   val xcpt_st = Bool(OUTPUT) |   val xcpt_st = Bool(OUTPUT) | ||||||
|   val xcpt_if = Bool(OUTPUT) |   val xcpt_if = Bool(OUTPUT) | ||||||
| } | } | ||||||
|  |  | ||||||
| class TLB(entries: Int) extends Module | class TLB extends TLBModule { | ||||||
| { |  | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val req = Decoupled(new TLBReq).flip |     val req = Decoupled(new TLBReq).flip | ||||||
|     val resp = new TLBResp(entries) |     val resp = new TLBResp | ||||||
|     val ptw = new TLBPTWIO |     val ptw = new TLBPTWIO | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -98,7 +105,7 @@ class TLB(entries: Int) extends Module | |||||||
|   val r_refill_tag = Reg(UInt()) |   val r_refill_tag = Reg(UInt()) | ||||||
|   val r_refill_waddr = Reg(UInt()) |   val r_refill_waddr = Reg(UInt()) | ||||||
|  |  | ||||||
|   val tag_cam = Module(new RocketCAM(entries, params(ASIdBits)+params(VPNBits))) |   val tag_cam = Module(new RocketCAM) | ||||||
|   val tag_ram = Mem(io.ptw.resp.bits.ppn.clone, entries) |   val tag_ram = Mem(io.ptw.resp.bits.ppn.clone, entries) | ||||||
|    |    | ||||||
|   val lookup_tag = Cat(io.req.bits.asid, io.req.bits.vpn).toUInt |   val lookup_tag = Cat(io.req.bits.asid, io.req.bits.vpn).toUInt | ||||||
| @@ -135,7 +142,7 @@ class TLB(entries: Int) extends Module | |||||||
|   val plru = new PseudoLRU(entries) |   val plru = new PseudoLRU(entries) | ||||||
|   val repl_waddr = Mux(has_invalid_entry, invalid_entry, plru.replace) |   val repl_waddr = Mux(has_invalid_entry, invalid_entry, plru.replace) | ||||||
|    |    | ||||||
|   val bad_va = io.req.bits.vpn(params(VPNBits)) != io.req.bits.vpn(params(VPNBits)-1) |   val bad_va = io.req.bits.vpn(vpnBits) != io.req.bits.vpn(vpnBits-1) | ||||||
|   val tlb_hit  = io.ptw.status.vm && tag_hit |   val tlb_hit  = io.ptw.status.vm && tag_hit | ||||||
|   val tlb_miss = io.ptw.status.vm && !tag_hit && !bad_va |   val tlb_miss = io.ptw.status.vm && !tag_hit && !bad_va | ||||||
|    |    | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user