initial attempt at upgrade
This commit is contained in:
parent
de313d97de
commit
1a9e43aa11
@ -3,14 +3,14 @@ package rocket
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import uncore._
|
import uncore._
|
||||||
|
|
||||||
class HellaCacheArbiter(n: Int)(implicit conf: RocketConfiguration) extends Component
|
class HellaCacheArbiter(n: Int)(implicit conf: RocketConfiguration) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val requestor = Vec(n) { new HellaCacheIO()(conf.dcache) }.flip
|
val requestor = Vec.fill(n){new HellaCacheIO()(conf.dcache)}.flip
|
||||||
val mem = new HellaCacheIO()(conf.dcache)
|
val mem = new HellaCacheIO()(conf.dcache)
|
||||||
}
|
}
|
||||||
|
|
||||||
val r_valid = io.requestor.map(r => Reg(r.req.valid))
|
val r_valid = io.requestor.map(r => RegUpdate(r.req.valid))
|
||||||
|
|
||||||
io.mem.req.valid := io.requestor.map(_.req.valid).reduce(_||_)
|
io.mem.req.valid := io.requestor.map(_.req.valid).reduce(_||_)
|
||||||
io.requestor(0).req.ready := io.mem.req.ready
|
io.requestor(0).req.ready := io.mem.req.ready
|
||||||
@ -18,7 +18,7 @@ class HellaCacheArbiter(n: Int)(implicit conf: RocketConfiguration) extends Comp
|
|||||||
io.requestor(i).req.ready := io.requestor(i-1).req.ready && !io.requestor(i-1).req.valid
|
io.requestor(i).req.ready := io.requestor(i-1).req.ready && !io.requestor(i-1).req.valid
|
||||||
|
|
||||||
io.mem.req.bits := io.requestor(n-1).req.bits
|
io.mem.req.bits := io.requestor(n-1).req.bits
|
||||||
io.mem.req.bits.tag := Cat(io.requestor(n-1).req.bits.tag, UFix(n-1, log2Up(n)))
|
io.mem.req.bits.tag := Cat(io.requestor(n-1).req.bits.tag, UInt(n-1, log2Up(n)))
|
||||||
for (i <- n-2 to 0 by -1) {
|
for (i <- n-2 to 0 by -1) {
|
||||||
val req = io.requestor(i).req
|
val req = io.requestor(i).req
|
||||||
when (req.valid) {
|
when (req.valid) {
|
||||||
@ -26,7 +26,7 @@ class HellaCacheArbiter(n: Int)(implicit conf: RocketConfiguration) extends Comp
|
|||||||
io.mem.req.bits.typ := req.bits.typ
|
io.mem.req.bits.typ := req.bits.typ
|
||||||
io.mem.req.bits.addr := req.bits.addr
|
io.mem.req.bits.addr := req.bits.addr
|
||||||
io.mem.req.bits.phys := req.bits.phys
|
io.mem.req.bits.phys := req.bits.phys
|
||||||
io.mem.req.bits.tag := Cat(req.bits.tag, UFix(i, log2Up(n)))
|
io.mem.req.bits.tag := Cat(req.bits.tag, UInt(i, log2Up(n)))
|
||||||
}
|
}
|
||||||
when (r_valid(i)) {
|
when (r_valid(i)) {
|
||||||
io.mem.req.bits.kill := req.bits.kill
|
io.mem.req.bits.kill := req.bits.kill
|
||||||
@ -36,11 +36,11 @@ class HellaCacheArbiter(n: Int)(implicit conf: RocketConfiguration) extends Comp
|
|||||||
|
|
||||||
for (i <- 0 until n) {
|
for (i <- 0 until n) {
|
||||||
val resp = io.requestor(i).resp
|
val resp = io.requestor(i).resp
|
||||||
val tag_hit = io.mem.resp.bits.tag(log2Up(n)-1,0) === UFix(i)
|
val tag_hit = io.mem.resp.bits.tag(log2Up(n)-1,0) === UInt(i)
|
||||||
resp.valid := io.mem.resp.valid && tag_hit
|
resp.valid := io.mem.resp.valid && tag_hit
|
||||||
io.requestor(i).xcpt := io.mem.xcpt
|
io.requestor(i).xcpt := io.mem.xcpt
|
||||||
resp.bits := io.mem.resp.bits
|
resp.bits := io.mem.resp.bits
|
||||||
resp.bits.tag := io.mem.resp.bits.tag >> UFix(log2Up(n))
|
resp.bits.tag := io.mem.resp.bits.tag >> UInt(log2Up(n))
|
||||||
resp.bits.nack := io.mem.resp.bits.nack && tag_hit
|
resp.bits.nack := io.mem.resp.bits.nack && tag_hit
|
||||||
resp.bits.replay := io.mem.resp.bits.replay && tag_hit
|
resp.bits.replay := io.mem.resp.bits.replay && tag_hit
|
||||||
}
|
}
|
||||||
|
@ -16,32 +16,32 @@ trait ScalarOpConstants {
|
|||||||
val BR_LTU = Bits(6, 3)
|
val BR_LTU = Bits(6, 3)
|
||||||
val BR_GEU = Bits(7, 3)
|
val BR_GEU = Bits(7, 3)
|
||||||
|
|
||||||
val PC_EX4 = UFix(0, 2)
|
val PC_EX4 = UInt(0, 2)
|
||||||
val PC_EX = UFix(1, 2)
|
val PC_EX = UInt(1, 2)
|
||||||
val PC_WB = UFix(2, 2)
|
val PC_WB = UInt(2, 2)
|
||||||
val PC_PCR = UFix(3, 2)
|
val PC_PCR = UInt(3, 2)
|
||||||
|
|
||||||
val A2_X = Bits("b???", 3)
|
val A2_X = Bits("b???", 3)
|
||||||
val A2_BTYPE = UFix(0, 3);
|
val A2_BTYPE = UInt(0, 3);
|
||||||
val A2_LTYPE = UFix(1, 3);
|
val A2_LTYPE = UInt(1, 3);
|
||||||
val A2_ITYPE = UFix(2, 3);
|
val A2_ITYPE = UInt(2, 3);
|
||||||
val A2_ZERO = UFix(4, 3);
|
val A2_ZERO = UInt(4, 3);
|
||||||
val A2_JTYPE = UFix(5, 3);
|
val A2_JTYPE = UInt(5, 3);
|
||||||
val A2_RTYPE = UFix(6, 3);
|
val A2_RTYPE = UInt(6, 3);
|
||||||
|
|
||||||
val X = Bits("b?", 1)
|
val X = Bits("b?", 1)
|
||||||
val N = Bits(0, 1);
|
val N = Bits(0, 1)
|
||||||
val Y = Bits(1, 1);
|
val Y = Bits(1, 1)
|
||||||
|
|
||||||
val WA_X = X
|
val WA_X = UInt("b?", 1)
|
||||||
val WA_RD = N
|
val WA_RD = UInt(0, 1)
|
||||||
val WA_RA = Y
|
val WA_RA = UInt(1, 1)
|
||||||
|
|
||||||
val WB_X = Bits("b???", 3)
|
val WB_X = UInt("b???", 3)
|
||||||
val WB_PC = UFix(0, 3);
|
val WB_PC = UInt(0, 3);
|
||||||
val WB_ALU = UFix(2, 3);
|
val WB_ALU = UInt(2, 3);
|
||||||
val WB_TSC = UFix(4, 3);
|
val WB_TSC = UInt(4, 3);
|
||||||
val WB_IRT = UFix(5, 3);
|
val WB_IRT = UInt(5, 3);
|
||||||
|
|
||||||
val SZ_DW = 1
|
val SZ_DW = 1
|
||||||
val DW_X = X
|
val DW_X = X
|
||||||
@ -49,7 +49,7 @@ trait ScalarOpConstants {
|
|||||||
val DW_64 = Y
|
val DW_64 = Y
|
||||||
val DW_XPR = Y
|
val DW_XPR = Y
|
||||||
|
|
||||||
val RA = UFix(1, 5);
|
val RA = UInt(1, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
trait InterruptConstants {
|
trait InterruptConstants {
|
||||||
@ -57,26 +57,26 @@ trait InterruptConstants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trait VectorOpConstants {
|
trait VectorOpConstants {
|
||||||
val VEC_X = Bits("b??", 2).toUFix
|
val VEC_X = Bits("b??", 2).toUInt
|
||||||
val VEC_FN_N = UFix(0, 2)
|
val VEC_FN_N = UInt(0, 2)
|
||||||
val VEC_VL = UFix(1, 2)
|
val VEC_VL = UInt(1, 2)
|
||||||
val VEC_CFG = UFix(2, 2)
|
val VEC_CFG = UInt(2, 2)
|
||||||
val VEC_CFGVL = UFix(3, 2)
|
val VEC_CFGVL = UInt(3, 2)
|
||||||
|
|
||||||
val VCMD_I = UFix(0, 3)
|
val VCMD_I = UInt(0, 3)
|
||||||
val VCMD_F = UFix(1, 3)
|
val VCMD_F = UInt(1, 3)
|
||||||
val VCMD_TX = UFix(2, 3)
|
val VCMD_TX = UInt(2, 3)
|
||||||
val VCMD_TF = UFix(3, 3)
|
val VCMD_TF = UInt(3, 3)
|
||||||
val VCMD_MX = UFix(4, 3)
|
val VCMD_MX = UInt(4, 3)
|
||||||
val VCMD_MF = UFix(5, 3)
|
val VCMD_MF = UInt(5, 3)
|
||||||
val VCMD_A = UFix(6, 3)
|
val VCMD_A = UInt(6, 3)
|
||||||
val VCMD_X = UFix(0, 3)
|
val VCMD_X = UInt(0, 3)
|
||||||
|
|
||||||
val VIMM_VLEN = UFix(0, 1)
|
val VIMM_VLEN = UInt(0, 1)
|
||||||
val VIMM_ALU = UFix(1, 1)
|
val VIMM_ALU = UInt(1, 1)
|
||||||
val VIMM_X = UFix(0, 1)
|
val VIMM_X = UInt(0, 1)
|
||||||
|
|
||||||
val VIMM2_RS2 = UFix(0, 1)
|
val VIMM2_RS2 = UInt(0, 1)
|
||||||
val VIMM2_ALU = UFix(1, 1)
|
val VIMM2_ALU = UInt(1, 1)
|
||||||
val VIMM2_X = UFix(0, 1)
|
val VIMM2_X = UInt(0, 1)
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,12 @@ class RocketIO(implicit conf: RocketConfiguration) extends Bundle
|
|||||||
val dmem = new HellaCacheIO()(conf.dcache)
|
val dmem = new HellaCacheIO()(conf.dcache)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Core(implicit conf: RocketConfiguration) extends Component
|
class Core(implicit conf: RocketConfiguration) extends Module
|
||||||
{
|
{
|
||||||
val io = new RocketIO
|
val io = new RocketIO
|
||||||
|
|
||||||
val ctrl = new Control
|
val ctrl = Module(new Control)
|
||||||
val dpath = new Datapath
|
val dpath = Module(new Datapath)
|
||||||
|
|
||||||
ctrl.io.dpath <> dpath.io.ctrl
|
ctrl.io.dpath <> dpath.io.ctrl
|
||||||
dpath.io.host <> io.host
|
dpath.io.host <> io.host
|
||||||
@ -26,7 +26,7 @@ class Core(implicit conf: RocketConfiguration) extends Component
|
|||||||
ctrl.io.imem <> io.imem
|
ctrl.io.imem <> io.imem
|
||||||
dpath.io.imem <> io.imem
|
dpath.io.imem <> io.imem
|
||||||
|
|
||||||
val dmemArb = new HellaCacheArbiter(2 + conf.vec)
|
val dmemArb = Module(new HellaCacheArbiter(2 + conf.vec))
|
||||||
dmemArb.io.mem <> io.dmem
|
dmemArb.io.mem <> io.dmem
|
||||||
val dmem = dmemArb.io.requestor
|
val dmem = dmemArb.io.requestor
|
||||||
dmem(1) <> ctrl.io.dmem
|
dmem(1) <> ctrl.io.dmem
|
||||||
@ -35,20 +35,20 @@ class Core(implicit conf: RocketConfiguration) extends Component
|
|||||||
val ptw = collection.mutable.ArrayBuffer(io.imem.ptw, io.dmem.ptw)
|
val ptw = collection.mutable.ArrayBuffer(io.imem.ptw, io.dmem.ptw)
|
||||||
|
|
||||||
val fpu: FPU = if (conf.fpu) {
|
val fpu: FPU = if (conf.fpu) {
|
||||||
val fpu = new FPU(4,6)
|
val fpu = Module(new FPU(4,6))
|
||||||
dpath.io.fpu <> fpu.io.dpath
|
dpath.io.fpu <> fpu.io.dpath
|
||||||
ctrl.io.fpu <> fpu.io.ctrl
|
ctrl.io.fpu <> fpu.io.ctrl
|
||||||
fpu
|
fpu
|
||||||
} else null
|
} else null
|
||||||
|
|
||||||
if (conf.vec) {
|
if (conf.vec) {
|
||||||
val vu = new vu(Reg(reset))
|
val vu = Module(new vu(RegUpdate(this.getReset)))
|
||||||
|
|
||||||
val vdtlb = new TLB(8)
|
val vdtlb = Module(new TLB(8))
|
||||||
ptw += vdtlb.io.ptw
|
ptw += vdtlb.io.ptw
|
||||||
vdtlb.io <> vu.io.vtlb
|
vdtlb.io <> vu.io.vtlb
|
||||||
|
|
||||||
val pftlb = new TLB(2)
|
val pftlb = Module(new TLB(2))
|
||||||
pftlb.io <> vu.io.vpftlb
|
pftlb.io <> vu.io.vpftlb
|
||||||
ptw += pftlb.io.ptw
|
ptw += pftlb.io.ptw
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ class Core(implicit conf: RocketConfiguration) extends Component
|
|||||||
// exceptions
|
// exceptions
|
||||||
vu.io.xcpt.exception := ctrl.io.vec_iface.exception
|
vu.io.xcpt.exception := ctrl.io.vec_iface.exception
|
||||||
vu.io.xcpt.evac := ctrl.io.vec_iface.evac
|
vu.io.xcpt.evac := ctrl.io.vec_iface.evac
|
||||||
vu.io.xcpt.evac_addr := dpath.io.vec_iface.evac_addr.toUFix
|
vu.io.xcpt.evac_addr := dpath.io.vec_iface.evac_addr.toUInt
|
||||||
vu.io.xcpt.kill := ctrl.io.vec_iface.kill
|
vu.io.xcpt.kill := ctrl.io.vec_iface.kill
|
||||||
vu.io.xcpt.hold := ctrl.io.vec_iface.hold
|
vu.io.xcpt.hold := ctrl.io.vec_iface.hold
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ class Core(implicit conf: RocketConfiguration) extends Component
|
|||||||
fpu.io.dfma.valid := Bool(false)
|
fpu.io.dfma.valid := Bool(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
val thePTW = new PTW(ptw.length)
|
val thePTW = Module(new PTW(ptw.length))
|
||||||
ptw zip thePTW.io.requestor map { case (a, b) => a <> b }
|
ptw zip thePTW.io.requestor map { case (a, b) => a <> b }
|
||||||
thePTW.io.dpath <> dpath.io.ptw
|
thePTW.io.dpath <> dpath.io.ptw
|
||||||
dmem(0) <> thePTW.io.mem
|
dmem(0) <> thePTW.io.mem
|
||||||
|
@ -10,20 +10,20 @@ import Util._
|
|||||||
class CtrlDpathIO extends Bundle()
|
class CtrlDpathIO extends Bundle()
|
||||||
{
|
{
|
||||||
// outputs to datapath
|
// outputs to datapath
|
||||||
val sel_pc = UFix(OUTPUT, 3);
|
val sel_pc = UInt(OUTPUT, 3);
|
||||||
val killd = Bool(OUTPUT);
|
val killd = Bool(OUTPUT);
|
||||||
val ren2 = Bool(OUTPUT);
|
val ren2 = Bool(OUTPUT);
|
||||||
val ren1 = Bool(OUTPUT);
|
val ren1 = Bool(OUTPUT);
|
||||||
val sel_alu2 = UFix(OUTPUT, 3);
|
val sel_alu2 = UInt(OUTPUT, 3);
|
||||||
val fn_dw = Bool(OUTPUT);
|
val fn_dw = Bool(OUTPUT);
|
||||||
val fn_alu = UFix(OUTPUT, SZ_ALU_FN);
|
val fn_alu = UInt(OUTPUT, SZ_ALU_FN);
|
||||||
val div_mul_val = Bool(OUTPUT)
|
val div_mul_val = Bool(OUTPUT)
|
||||||
val div_mul_kill = Bool(OUTPUT)
|
val div_mul_kill = Bool(OUTPUT)
|
||||||
val div_val = Bool(OUTPUT);
|
val div_val = Bool(OUTPUT);
|
||||||
val div_kill = Bool(OUTPUT)
|
val div_kill = Bool(OUTPUT)
|
||||||
val sel_wa = Bool(OUTPUT);
|
val sel_wa = Bool(OUTPUT);
|
||||||
val sel_wb = UFix(OUTPUT, 3);
|
val sel_wb = UInt(OUTPUT, 3);
|
||||||
val pcr = UFix(OUTPUT, 3)
|
val pcr = UInt(OUTPUT, 3)
|
||||||
val eret = Bool(OUTPUT);
|
val eret = Bool(OUTPUT);
|
||||||
val mem_load = Bool(OUTPUT);
|
val mem_load = Bool(OUTPUT);
|
||||||
val wb_load = Bool(OUTPUT)
|
val wb_load = Bool(OUTPUT)
|
||||||
@ -39,7 +39,7 @@ class CtrlDpathIO extends Bundle()
|
|||||||
val mem_rs2_val = Bool(OUTPUT)
|
val mem_rs2_val = Bool(OUTPUT)
|
||||||
// exception handling
|
// exception handling
|
||||||
val exception = Bool(OUTPUT);
|
val exception = Bool(OUTPUT);
|
||||||
val cause = UFix(OUTPUT, 6);
|
val cause = UInt(OUTPUT, 6);
|
||||||
val badvaddr_wen = Bool(OUTPUT); // high for a load/store access fault
|
val badvaddr_wen = Bool(OUTPUT); // high for a load/store access fault
|
||||||
val vec_irq_aux_wen = Bool(OUTPUT)
|
val vec_irq_aux_wen = Bool(OUTPUT)
|
||||||
// inputs from datapath
|
// inputs from datapath
|
||||||
@ -49,13 +49,13 @@ class CtrlDpathIO extends Bundle()
|
|||||||
val ex_br_taken = Bool(INPUT)
|
val ex_br_taken = Bool(INPUT)
|
||||||
val div_mul_rdy = Bool(INPUT)
|
val div_mul_rdy = Bool(INPUT)
|
||||||
val mem_ll_wb = Bool(INPUT)
|
val mem_ll_wb = Bool(INPUT)
|
||||||
val mem_ll_waddr = UFix(INPUT, 5)
|
val mem_ll_waddr = UInt(INPUT, 5)
|
||||||
val ex_waddr = UFix(INPUT, 5); // write addr from execute stage
|
val ex_waddr = UInt(INPUT, 5); // write addr from execute stage
|
||||||
val mem_waddr = UFix(INPUT, 5); // write addr from memory stage
|
val mem_waddr = UInt(INPUT, 5); // write addr from memory stage
|
||||||
val wb_waddr = UFix(INPUT, 5); // write addr from writeback stage
|
val wb_waddr = UInt(INPUT, 5); // write addr from writeback stage
|
||||||
val status = new Status().asInput
|
val status = new Status().asInput
|
||||||
val fp_sboard_clr = Bool(INPUT);
|
val fp_sboard_clr = Bool(INPUT);
|
||||||
val fp_sboard_clra = UFix(INPUT, 5);
|
val fp_sboard_clra = UInt(INPUT, 5);
|
||||||
val pcr_replay = Bool(INPUT)
|
val pcr_replay = Bool(INPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ abstract trait DecodeConstants
|
|||||||
// | | | | | | | | | | | | | | | | | | | | | | | |
|
// | | | | | | | | | | | | | | | | | | | | | | | |
|
||||||
List(N, X,X,BR_X, X,X,X,A2_X, DW_X, FN_X, N,M_X, MT_X, X,X,X,WA_X, WB_X, PCR.X,N,X,X,X,X)
|
List(N, X,X,BR_X, X,X,X,A2_X, DW_X, FN_X, N,M_X, MT_X, X,X,X,WA_X, WB_X, PCR.X,N,X,X,X,X)
|
||||||
|
|
||||||
val table: Array[(Bits, List[Bits])]
|
val table: Array[(UInt, List[UInt])]
|
||||||
}
|
}
|
||||||
|
|
||||||
object XDecode extends DecodeConstants
|
object XDecode extends DecodeConstants
|
||||||
@ -318,7 +318,7 @@ object VDecode extends DecodeConstants
|
|||||||
VXCPTHOLD-> List(Y, N,Y,BR_N, N,N,N,A2_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,WA_X, WB_X, PCR.N,N,N,N,Y,N))
|
VXCPTHOLD-> List(Y, N,Y,BR_N, N,N,N,A2_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,WA_X, WB_X, PCR.N,N,N,N,Y,N))
|
||||||
}
|
}
|
||||||
|
|
||||||
class Control(implicit conf: RocketConfiguration) extends Component
|
class Control(implicit conf: RocketConfiguration) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val dpath = new CtrlDpathIO
|
val dpath = new CtrlDpathIO
|
||||||
@ -339,11 +339,15 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
if (conf.fpu) decode_table ++= FDecode.table
|
if (conf.fpu) decode_table ++= FDecode.table
|
||||||
if (conf.vec) decode_table ++= VDecode.table
|
if (conf.vec) decode_table ++= VDecode.table
|
||||||
|
|
||||||
val cs = DecodeLogic(io.dpath.inst, XDecode.decode_default, decode_table)
|
val logic = DecodeLogic(io.dpath.inst, XDecode.decode_default, decode_table)
|
||||||
|
val cs = logic.map {
|
||||||
|
case b if b.inputs.head.getClass == classOf[Bool] => b.toBool
|
||||||
|
case u => u
|
||||||
|
}
|
||||||
|
|
||||||
val id_int_val :: id_fp_val :: id_vec_val :: id_br_type :: id_jalr :: id_renx2 :: id_renx1 :: id_sel_alu2 :: id_fn_dw :: id_fn_alu :: cs0 = cs
|
val (id_int_val: Bool) :: (id_fp_val: Bool) :: (id_vec_val: Bool) :: id_br_type :: (id_jalr: Bool) :: (id_renx2: Bool) :: (id_renx1: Bool) :: id_sel_alu2 :: (id_fn_dw: Bool) :: id_fn_alu :: cs0 = cs
|
||||||
val id_mem_val :: id_mem_cmd :: id_mem_type :: id_mul_val :: id_div_val :: id_wen :: id_sel_wa :: id_sel_wb :: cs1 = cs0
|
val (id_mem_val: Bool) :: id_mem_cmd :: id_mem_type :: (id_mul_val: Bool) :: (id_div_val: Bool) :: (id_wen: Bool) :: id_sel_wa :: id_sel_wb :: cs1 = cs0
|
||||||
val id_pcr :: id_fence_i :: id_eret :: id_syscall :: id_privileged :: id_replay_next :: Nil = cs1
|
val id_pcr :: (id_fence_i: Bool) :: (id_eret: Bool) :: (id_syscall: Bool) :: (id_privileged: Bool) :: (id_replay_next: Bool) :: Nil = cs1
|
||||||
|
|
||||||
val id_raddr3 = io.dpath.inst(16,12);
|
val id_raddr3 = io.dpath.inst(16,12);
|
||||||
val id_raddr2 = io.dpath.inst(21,17);
|
val id_raddr2 = io.dpath.inst(21,17);
|
||||||
@ -351,70 +355,70 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
val id_waddr = Mux(id_sel_wa === WA_RA, RA, io.dpath.inst(31,27));
|
val id_waddr = Mux(id_sel_wa === WA_RA, RA, io.dpath.inst(31,27));
|
||||||
val id_load_use = Bool();
|
val id_load_use = Bool();
|
||||||
|
|
||||||
val ex_reg_xcpt_interrupt = Reg(resetVal = Bool(false))
|
val ex_reg_xcpt_interrupt = RegReset(Bool(false))
|
||||||
val ex_reg_valid = Reg(resetVal = Bool(false))
|
val ex_reg_valid = RegReset(Bool(false))
|
||||||
val ex_reg_eret = Reg(resetVal = Bool(false))
|
val ex_reg_eret = RegReset(Bool(false))
|
||||||
val ex_reg_wen = Reg(resetVal = Bool(false))
|
val ex_reg_wen = RegReset(Bool(false))
|
||||||
val ex_reg_fp_wen = Reg(resetVal = Bool(false))
|
val ex_reg_fp_wen = RegReset(Bool(false))
|
||||||
val ex_reg_flush_inst = Reg(resetVal = Bool(false))
|
val ex_reg_flush_inst = RegReset(Bool(false))
|
||||||
val ex_reg_jalr = Reg(resetVal = Bool(false))
|
val ex_reg_jalr = RegReset(Bool(false))
|
||||||
val ex_reg_btb_hit = Reg(resetVal = Bool(false))
|
val ex_reg_btb_hit = RegReset(Bool(false))
|
||||||
val ex_reg_div_mul_val = Reg(resetVal = Bool(false))
|
val ex_reg_div_mul_val = RegReset(Bool(false))
|
||||||
val ex_reg_mem_val = Reg(resetVal = Bool(false))
|
val ex_reg_mem_val = RegReset(Bool(false))
|
||||||
val ex_reg_xcpt = Reg(resetVal = Bool(false))
|
val ex_reg_xcpt = RegReset(Bool(false))
|
||||||
val ex_reg_fp_val = Reg(resetVal = Bool(false))
|
val ex_reg_fp_val = RegReset(Bool(false))
|
||||||
val ex_reg_vec_val = Reg(resetVal = Bool(false))
|
val ex_reg_vec_val = RegReset(Bool(false))
|
||||||
val ex_reg_replay_next = Reg(resetVal = Bool(false))
|
val ex_reg_replay_next = RegReset(Bool(false))
|
||||||
val ex_reg_load_use = Reg(resetVal = Bool(false))
|
val ex_reg_load_use = RegReset(Bool(false))
|
||||||
val ex_reg_pcr = Reg(resetVal = PCR.N)
|
val ex_reg_pcr = RegReset(PCR.N)
|
||||||
val ex_reg_br_type = Reg(resetVal = BR_N)
|
val ex_reg_br_type = RegReset(BR_N)
|
||||||
val ex_reg_mem_cmd = Reg(){Bits()}
|
val ex_reg_mem_cmd = Reg(Bits())
|
||||||
val ex_reg_mem_type = Reg(){Bits()}
|
val ex_reg_mem_type = Reg(Bits())
|
||||||
val ex_reg_cause = Reg(){UFix()}
|
val ex_reg_cause = Reg(UInt())
|
||||||
|
|
||||||
val mem_reg_xcpt_interrupt = Reg(resetVal = Bool(false))
|
val mem_reg_xcpt_interrupt = RegReset(Bool(false))
|
||||||
val mem_reg_valid = Reg(resetVal = Bool(false))
|
val mem_reg_valid = RegReset(Bool(false))
|
||||||
val mem_reg_eret = Reg(resetVal = Bool(false))
|
val mem_reg_eret = RegReset(Bool(false))
|
||||||
val mem_reg_wen = Reg(resetVal = Bool(false))
|
val mem_reg_wen = RegReset(Bool(false))
|
||||||
val mem_reg_fp_wen = Reg(resetVal = Bool(false))
|
val mem_reg_fp_wen = RegReset(Bool(false))
|
||||||
val mem_reg_flush_inst = Reg(resetVal = Bool(false))
|
val mem_reg_flush_inst = RegReset(Bool(false))
|
||||||
val mem_reg_div_mul_val = Reg(resetVal = Bool(false))
|
val mem_reg_div_mul_val = RegReset(Bool(false))
|
||||||
val mem_reg_mem_val = Reg(resetVal = Bool(false))
|
val mem_reg_mem_val = RegReset(Bool(false))
|
||||||
val mem_reg_xcpt = Reg(resetVal = Bool(false))
|
val mem_reg_xcpt = RegReset(Bool(false))
|
||||||
val mem_reg_fp_val = Reg(resetVal = Bool(false))
|
val mem_reg_fp_val = RegReset(Bool(false))
|
||||||
val mem_reg_vec_val = Reg(resetVal = Bool(false))
|
val mem_reg_vec_val = RegReset(Bool(false))
|
||||||
val mem_reg_replay = Reg(resetVal = Bool(false))
|
val mem_reg_replay = RegReset(Bool(false))
|
||||||
val mem_reg_replay_next = Reg(resetVal = Bool(false))
|
val mem_reg_replay_next = RegReset(Bool(false))
|
||||||
val mem_reg_pcr = Reg(resetVal = PCR.N)
|
val mem_reg_pcr = RegReset(PCR.N)
|
||||||
val mem_reg_cause = Reg(){UFix()}
|
val mem_reg_cause = Reg(UInt())
|
||||||
val mem_reg_slow_bypass = Reg(){Bool()}
|
val mem_reg_slow_bypass = Reg(Bool())
|
||||||
|
|
||||||
val wb_reg_valid = Reg(resetVal = Bool(false))
|
val wb_reg_valid = RegReset(Bool(false))
|
||||||
val wb_reg_pcr = Reg(resetVal = PCR.N)
|
val wb_reg_pcr = RegReset(PCR.N)
|
||||||
val wb_reg_wen = Reg(resetVal = Bool(false))
|
val wb_reg_wen = RegReset(Bool(false))
|
||||||
val wb_reg_fp_wen = Reg(resetVal = Bool(false))
|
val wb_reg_fp_wen = RegReset(Bool(false))
|
||||||
val wb_reg_flush_inst = Reg(resetVal = Bool(false))
|
val wb_reg_flush_inst = RegReset(Bool(false))
|
||||||
val wb_reg_mem_val = Reg(resetVal = Bool(false))
|
val wb_reg_mem_val = RegReset(Bool(false))
|
||||||
val wb_reg_eret = Reg(resetVal = Bool(false))
|
val wb_reg_eret = RegReset(Bool(false))
|
||||||
val wb_reg_xcpt = Reg(resetVal = Bool(false))
|
val wb_reg_xcpt = RegReset(Bool(false))
|
||||||
val wb_reg_replay = Reg(resetVal = Bool(false))
|
val wb_reg_replay = RegReset(Bool(false))
|
||||||
val wb_reg_cause = Reg(){UFix()}
|
val wb_reg_cause = Reg(UInt())
|
||||||
val wb_reg_fp_val = Reg(resetVal = Bool(false))
|
val wb_reg_fp_val = RegReset(Bool(false))
|
||||||
val wb_reg_div_mul_val = Reg(resetVal = Bool(false))
|
val wb_reg_div_mul_val = RegReset(Bool(false))
|
||||||
|
|
||||||
val take_pc = Bool()
|
val take_pc = Bool()
|
||||||
val pc_taken = Reg(take_pc, resetVal = Bool(false))
|
val pc_taken = Reg(update = take_pc, reset = Bool(false))
|
||||||
val take_pc_wb = Bool()
|
val take_pc_wb = Bool()
|
||||||
val ctrl_killd = Bool()
|
val ctrl_killd = Bool()
|
||||||
val ctrl_killx = Bool()
|
val ctrl_killx = Bool()
|
||||||
val ctrl_killm = Bool()
|
val ctrl_killm = Bool()
|
||||||
|
|
||||||
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), UFix(CAUSE_INTERRUPT+i)))
|
var id_interrupts = (0 until sr.ip.getWidth).map(i => (sr.im(i) && sr.ip(i), UInt(CAUSE_INTERRUPT+i)))
|
||||||
|
|
||||||
val (vec_replay, vec_stalld) = if (conf.vec) {
|
val (vec_replay, vec_stalld) = if (conf.vec) {
|
||||||
// vector control
|
// vector control
|
||||||
val vec = new rocketCtrlVec()
|
val vec = Module(new rocketCtrlVec)
|
||||||
|
|
||||||
io.vec_dpath <> vec.io.dpath
|
io.vec_dpath <> vec.io.dpath
|
||||||
io.vec_iface <> vec.io.iface
|
io.vec_iface <> vec.io.iface
|
||||||
@ -425,7 +429,7 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
vec.io.exception := wb_reg_xcpt
|
vec.io.exception := wb_reg_xcpt
|
||||||
vec.io.eret := wb_reg_eret
|
vec.io.eret := wb_reg_eret
|
||||||
|
|
||||||
val vec_dec = new rocketCtrlVecDecoder()
|
val vec_dec = Module(new rocketCtrlVecDecoder)
|
||||||
vec_dec.io.inst := io.dpath.inst
|
vec_dec.io.inst := io.dpath.inst
|
||||||
|
|
||||||
val s = io.dpath.status.s
|
val s = io.dpath.status.s
|
||||||
@ -452,7 +456,7 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
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.et && id_interrupt_unmasked
|
val id_interrupt = io.dpath.status.et && id_interrupt_unmasked
|
||||||
|
|
||||||
def checkExceptions(x: Seq[(Bits, UFix)]) =
|
def checkExceptions(x: Seq[(Bool, UInt)]) =
|
||||||
(x.map(_._1).reduce(_||_), PriorityMux(x))
|
(x.map(_._1).reduce(_||_), PriorityMux(x))
|
||||||
|
|
||||||
// executing ERET when traps are enabled causes an illegal instruction exception
|
// executing ERET when traps are enabled causes an illegal instruction exception
|
||||||
@ -463,13 +467,13 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
|
|
||||||
val (id_xcpt, id_cause) = checkExceptions(List(
|
val (id_xcpt, id_cause) = checkExceptions(List(
|
||||||
(id_interrupt, id_interrupt_cause),
|
(id_interrupt, id_interrupt_cause),
|
||||||
(io.imem.resp.bits.xcpt_ma, UFix(0)),
|
(io.imem.resp.bits.xcpt_ma, UInt(0)),
|
||||||
(io.imem.resp.bits.xcpt_if, UFix(1)),
|
(io.imem.resp.bits.xcpt_if, UInt(1)),
|
||||||
(illegal_inst, UFix(2)),
|
(illegal_inst, UInt(2)),
|
||||||
(id_privileged && !io.dpath.status.s, UFix(3)),
|
(id_privileged && !io.dpath.status.s, UInt(3)),
|
||||||
(id_fp_val && !io.dpath.status.ef, UFix(4)),
|
(id_fp_val && !io.dpath.status.ef, UInt(4)),
|
||||||
(id_syscall, UFix(6)),
|
(id_syscall, UInt(6)),
|
||||||
(id_vec_val && !io.dpath.status.ev, UFix(12))))
|
(id_vec_val && !io.dpath.status.ev, UInt(12))))
|
||||||
|
|
||||||
ex_reg_xcpt_interrupt := id_interrupt && !take_pc && io.imem.resp.valid
|
ex_reg_xcpt_interrupt := id_interrupt && !take_pc && io.imem.resp.valid
|
||||||
when (id_xcpt) { ex_reg_cause := id_cause }
|
when (id_xcpt) { ex_reg_cause := id_cause }
|
||||||
@ -500,7 +504,7 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
ex_reg_mem_val := id_mem_val.toBool;
|
ex_reg_mem_val := id_mem_val.toBool;
|
||||||
ex_reg_valid := Bool(true)
|
ex_reg_valid := Bool(true)
|
||||||
ex_reg_pcr := id_pcr
|
ex_reg_pcr := id_pcr
|
||||||
ex_reg_wen := id_wen && id_waddr != UFix(0)
|
ex_reg_wen := id_wen && id_waddr != UInt(0)
|
||||||
ex_reg_fp_wen := id_fp_val && io.fpu.dec.wen
|
ex_reg_fp_wen := id_fp_val && io.fpu.dec.wen
|
||||||
ex_reg_eret := id_eret.toBool;
|
ex_reg_eret := id_eret.toBool;
|
||||||
ex_reg_flush_inst := id_fence_i
|
ex_reg_flush_inst := id_fence_i
|
||||||
@ -509,7 +513,7 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
ex_reg_replay_next := id_replay_next || id_pcr_flush
|
ex_reg_replay_next := id_replay_next || id_pcr_flush
|
||||||
ex_reg_load_use := id_load_use;
|
ex_reg_load_use := id_load_use;
|
||||||
ex_reg_mem_cmd := id_mem_cmd
|
ex_reg_mem_cmd := id_mem_cmd
|
||||||
ex_reg_mem_type := id_mem_type.toUFix
|
ex_reg_mem_type := id_mem_type.toUInt
|
||||||
ex_reg_xcpt := id_xcpt
|
ex_reg_xcpt := id_xcpt
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,7 +532,7 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
|
|
||||||
val (ex_xcpt, ex_cause) = checkExceptions(List(
|
val (ex_xcpt, ex_cause) = checkExceptions(List(
|
||||||
(ex_reg_xcpt_interrupt || ex_reg_xcpt, ex_reg_cause),
|
(ex_reg_xcpt_interrupt || ex_reg_xcpt, ex_reg_cause),
|
||||||
(ex_reg_fp_val && io.fpu.illegal_rm, UFix(2))))
|
(ex_reg_fp_val && io.fpu.illegal_rm, UInt(2))))
|
||||||
|
|
||||||
mem_reg_replay := replay_ex && !take_pc_wb;
|
mem_reg_replay := replay_ex && !take_pc_wb;
|
||||||
mem_reg_xcpt_interrupt := ex_reg_xcpt_interrupt && !take_pc_wb && !mem_reg_replay_next
|
mem_reg_xcpt_interrupt := ex_reg_xcpt_interrupt && !take_pc_wb && !mem_reg_replay_next
|
||||||
@ -565,10 +569,10 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
|
|
||||||
val (mem_xcpt, mem_cause) = checkExceptions(List(
|
val (mem_xcpt, mem_cause) = checkExceptions(List(
|
||||||
(mem_reg_xcpt_interrupt || mem_reg_xcpt, mem_reg_cause),
|
(mem_reg_xcpt_interrupt || mem_reg_xcpt, mem_reg_cause),
|
||||||
(mem_reg_mem_val && io.dmem.xcpt.ma.ld, UFix( 8)),
|
(mem_reg_mem_val && io.dmem.xcpt.ma.ld, UInt( 8)),
|
||||||
(mem_reg_mem_val && io.dmem.xcpt.ma.st, UFix( 9)),
|
(mem_reg_mem_val && io.dmem.xcpt.ma.st, UInt( 9)),
|
||||||
(mem_reg_mem_val && io.dmem.xcpt.pf.ld, UFix(10)),
|
(mem_reg_mem_val && io.dmem.xcpt.pf.ld, UInt(10)),
|
||||||
(mem_reg_mem_val && io.dmem.xcpt.pf.st, UFix(11))))
|
(mem_reg_mem_val && io.dmem.xcpt.pf.st, UInt(11))))
|
||||||
|
|
||||||
val fpu_kill_mem = mem_reg_fp_val && io.fpu.nack_mem
|
val fpu_kill_mem = mem_reg_fp_val && io.fpu.nack_mem
|
||||||
val ll_wb_kill_mem = io.dpath.mem_ll_wb && (mem_reg_wen || mem_reg_fp_wen || mem_reg_vec_val || mem_reg_pcr != PCR.N)
|
val ll_wb_kill_mem = io.dpath.mem_ll_wb && (mem_reg_wen || mem_reg_fp_wen || mem_reg_vec_val || mem_reg_pcr != PCR.N)
|
||||||
@ -607,14 +611,14 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
|
|
||||||
class Scoreboard(n: Int)
|
class Scoreboard(n: Int)
|
||||||
{
|
{
|
||||||
val r = Reg(resetVal = Bits(0, n))
|
val r = RegReset(Bits(0, n))
|
||||||
var next = r
|
var next = r
|
||||||
var ens = Bool(false)
|
var ens = Bool(false)
|
||||||
def apply(addr: UFix) = r(addr)
|
def apply(addr: UInt) = r(addr)
|
||||||
def set(en: Bool, addr: UFix): Unit = update(en, next | mask(en, addr))
|
def set(en: Bool, addr: UInt): Unit = update(en, next | mask(en, addr))
|
||||||
def clear(en: Bool, addr: UFix): Unit = update(en, next & ~mask(en, addr))
|
def clear(en: Bool, addr: UInt): Unit = update(en, next & ~mask(en, addr))
|
||||||
private def mask(en: Bool, addr: UFix) = Mux(en, UFix(1) << addr, UFix(0))
|
private def mask(en: Bool, addr: UInt) = Mux(en, UInt(1) << addr, UInt(0))
|
||||||
private def update(en: Bool, update: Bits) = {
|
private def update(en: Bool, update: UInt) = {
|
||||||
next = update
|
next = update
|
||||||
ens = ens || en
|
ens = ens || en
|
||||||
when (ens) { r := next }
|
when (ens) { r := next }
|
||||||
@ -640,8 +644,8 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
// write cause to PCR on an exception
|
// write cause to PCR on an exception
|
||||||
io.dpath.exception := wb_reg_xcpt
|
io.dpath.exception := wb_reg_xcpt
|
||||||
io.dpath.cause := wb_reg_cause
|
io.dpath.cause := wb_reg_cause
|
||||||
io.dpath.badvaddr_wen := wb_reg_xcpt && (wb_reg_cause === UFix(10) || wb_reg_cause === UFix(11))
|
io.dpath.badvaddr_wen := wb_reg_xcpt && (wb_reg_cause === UInt(10) || wb_reg_cause === UInt(11))
|
||||||
io.dpath.vec_irq_aux_wen := wb_reg_xcpt && wb_reg_cause >= UFix(24) && wb_reg_cause < UFix(32)
|
io.dpath.vec_irq_aux_wen := wb_reg_xcpt && wb_reg_cause >= UInt(24) && wb_reg_cause < UInt(32)
|
||||||
|
|
||||||
// control transfer from ex/wb
|
// control transfer from ex/wb
|
||||||
take_pc_wb := replay_wb || wb_reg_xcpt || wb_reg_eret
|
take_pc_wb := replay_wb || wb_reg_xcpt || wb_reg_eret
|
||||||
@ -677,9 +681,9 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
if (conf.fastLoadWord) Bool(!conf.fastLoadByte) && mem_reg_slow_bypass
|
if (conf.fastLoadWord) Bool(!conf.fastLoadByte) && mem_reg_slow_bypass
|
||||||
else Bool(true)
|
else Bool(true)
|
||||||
val data_hazard_mem = mem_reg_wen &&
|
val data_hazard_mem = mem_reg_wen &&
|
||||||
(id_raddr1 != UFix(0) && id_renx1 && id_raddr1 === io.dpath.mem_waddr ||
|
(id_raddr1 != UInt(0) && id_renx1 && id_raddr1 === io.dpath.mem_waddr ||
|
||||||
id_raddr2 != UFix(0) && id_renx2 && id_raddr2 === io.dpath.mem_waddr ||
|
id_raddr2 != UInt(0) && id_renx2 && id_raddr2 === io.dpath.mem_waddr ||
|
||||||
id_waddr != UFix(0) && id_wen && id_waddr === io.dpath.mem_waddr)
|
id_waddr != UInt(0) && id_wen && id_waddr === io.dpath.mem_waddr)
|
||||||
val fp_data_hazard_mem = mem_reg_fp_wen &&
|
val fp_data_hazard_mem = mem_reg_fp_wen &&
|
||||||
(io.fpu.dec.ren1 && id_raddr1 === io.dpath.mem_waddr ||
|
(io.fpu.dec.ren1 && id_raddr1 === io.dpath.mem_waddr ||
|
||||||
io.fpu.dec.ren2 && id_raddr2 === io.dpath.mem_waddr ||
|
io.fpu.dec.ren2 && id_raddr2 === io.dpath.mem_waddr ||
|
||||||
@ -691,9 +695,9 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
|
|
||||||
// stall for RAW/WAW hazards on load/AMO misses and mul/div in writeback.
|
// stall for RAW/WAW hazards on load/AMO misses and mul/div in writeback.
|
||||||
val data_hazard_wb = wb_reg_wen &&
|
val data_hazard_wb = wb_reg_wen &&
|
||||||
(id_raddr1 != UFix(0) && id_renx1 && (id_raddr1 === io.dpath.wb_waddr) ||
|
(id_raddr1 != UInt(0) && id_renx1 && (id_raddr1 === io.dpath.wb_waddr) ||
|
||||||
id_raddr2 != UFix(0) && id_renx2 && (id_raddr2 === io.dpath.wb_waddr) ||
|
id_raddr2 != UInt(0) && id_renx2 && (id_raddr2 === io.dpath.wb_waddr) ||
|
||||||
id_waddr != UFix(0) && id_wen && (id_waddr === io.dpath.wb_waddr))
|
id_waddr != UInt(0) && id_wen && (id_waddr === io.dpath.wb_waddr))
|
||||||
val fp_data_hazard_wb = wb_reg_fp_wen &&
|
val fp_data_hazard_wb = wb_reg_fp_wen &&
|
||||||
(io.fpu.dec.ren1 && id_raddr1 === io.dpath.wb_waddr ||
|
(io.fpu.dec.ren1 && id_raddr1 === io.dpath.wb_waddr ||
|
||||||
io.fpu.dec.ren2 && id_raddr2 === io.dpath.wb_waddr ||
|
io.fpu.dec.ren2 && id_raddr2 === io.dpath.wb_waddr ||
|
||||||
@ -703,9 +707,9 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
fp_data_hazard_wb && (wb_dcache_miss || wb_reg_fp_val)
|
fp_data_hazard_wb && (wb_dcache_miss || wb_reg_fp_val)
|
||||||
|
|
||||||
val id_sboard_hazard =
|
val id_sboard_hazard =
|
||||||
(id_raddr1 != UFix(0) && id_renx1 && sboard(id_raddr1) ||
|
(id_raddr1 != UInt(0) && id_renx1 && sboard(id_raddr1) ||
|
||||||
id_raddr2 != UFix(0) && id_renx2 && sboard(id_raddr2) ||
|
id_raddr2 != UInt(0) && id_renx2 && sboard(id_raddr2) ||
|
||||||
id_waddr != UFix(0) && id_wen && sboard(id_waddr))
|
id_waddr != UInt(0) && id_wen && sboard(id_waddr))
|
||||||
|
|
||||||
val ctrl_stalld =
|
val ctrl_stalld =
|
||||||
id_ex_hazard || id_mem_hazard || id_wb_hazard || id_sboard_hazard ||
|
id_ex_hazard || id_mem_hazard || id_wb_hazard || id_sboard_hazard ||
|
||||||
@ -723,9 +727,9 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.dpath.wb_load := wb_reg_mem_val && wb_reg_wen
|
io.dpath.wb_load := wb_reg_mem_val && wb_reg_wen
|
||||||
io.dpath.ren2 := id_renx2.toBool;
|
io.dpath.ren2 := id_renx2.toBool;
|
||||||
io.dpath.ren1 := id_renx1.toBool;
|
io.dpath.ren1 := id_renx1.toBool;
|
||||||
io.dpath.sel_alu2 := id_sel_alu2.toUFix
|
io.dpath.sel_alu2 := id_sel_alu2.toUInt
|
||||||
io.dpath.fn_dw := id_fn_dw.toBool;
|
io.dpath.fn_dw := id_fn_dw.toBool;
|
||||||
io.dpath.fn_alu := id_fn_alu.toUFix
|
io.dpath.fn_alu := id_fn_alu.toUInt
|
||||||
io.dpath.div_mul_val := ex_reg_div_mul_val
|
io.dpath.div_mul_val := ex_reg_div_mul_val
|
||||||
io.dpath.div_mul_kill := mem_reg_div_mul_val && killm_common
|
io.dpath.div_mul_kill := mem_reg_div_mul_val && killm_common
|
||||||
io.dpath.ex_fp_val:= ex_reg_fp_val;
|
io.dpath.ex_fp_val:= ex_reg_fp_val;
|
||||||
@ -736,8 +740,8 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.dpath.wb_wen := wb_reg_wen && !replay_wb
|
io.dpath.wb_wen := wb_reg_wen && !replay_wb
|
||||||
io.dpath.wb_valid := wb_reg_valid && !replay_wb
|
io.dpath.wb_valid := wb_reg_valid && !replay_wb
|
||||||
io.dpath.sel_wa := id_sel_wa.toBool;
|
io.dpath.sel_wa := id_sel_wa.toBool;
|
||||||
io.dpath.sel_wb := id_sel_wb.toUFix
|
io.dpath.sel_wb := id_sel_wb.toUInt
|
||||||
io.dpath.pcr := wb_reg_pcr.toUFix
|
io.dpath.pcr := wb_reg_pcr.toUInt
|
||||||
io.dpath.eret := wb_reg_eret
|
io.dpath.eret := wb_reg_eret
|
||||||
io.dpath.ex_mem_type := ex_reg_mem_type
|
io.dpath.ex_mem_type := ex_reg_mem_type
|
||||||
io.dpath.ex_br_type := ex_reg_br_type
|
io.dpath.ex_br_type := ex_reg_br_type
|
||||||
|
@ -18,15 +18,15 @@ class CtrlDpathVecIO extends Bundle
|
|||||||
|
|
||||||
class CtrlVecInterfaceIO extends Bundle
|
class CtrlVecInterfaceIO extends Bundle
|
||||||
{
|
{
|
||||||
val vcmdq = new FIFOIO()(Bits(width = SZ_VCMD))
|
val vcmdq = Decoupled(Bits(width = SZ_VCMD))
|
||||||
val vximm1q = new FIFOIO()(Bits(width = SZ_VIMM))
|
val vximm1q = Decoupled(Bits(width = SZ_VIMM))
|
||||||
val vximm2q = new FIFOIO()(Bits(width = SZ_VSTRIDE))
|
val vximm2q = Decoupled(Bits(width = SZ_VSTRIDE))
|
||||||
val vcntq = new FIFOIO()(Bits(width = SZ_VLEN+1))
|
val vcntq = Decoupled(Bits(width = SZ_VLEN+1))
|
||||||
|
|
||||||
val vpfcmdq = new FIFOIO()(Bits(width = SZ_VCMD))
|
val vpfcmdq = Decoupled(Bits(width = SZ_VCMD))
|
||||||
val vpfximm1q = new FIFOIO()(Bits(width = SZ_VIMM))
|
val vpfximm1q = Decoupled(Bits(width = SZ_VIMM))
|
||||||
val vpfximm2q = new FIFOIO()(Bits(width = SZ_VSTRIDE))
|
val vpfximm2q = Decoupled(Bits(width = SZ_VSTRIDE))
|
||||||
val vpfcntq = new FIFOIO()(Bits(width = SZ_VLEN))
|
val vpfcntq = Decoupled(Bits(width = SZ_VLEN))
|
||||||
|
|
||||||
val vcmdq_user_ready = Bool(INPUT)
|
val vcmdq_user_ready = Bool(INPUT)
|
||||||
val vximm1q_user_ready = Bool(INPUT)
|
val vximm1q_user_ready = Bool(INPUT)
|
||||||
@ -34,7 +34,7 @@ class CtrlVecInterfaceIO extends Bundle
|
|||||||
val vfence_ready = Bool(INPUT)
|
val vfence_ready = Bool(INPUT)
|
||||||
|
|
||||||
val irq = Bool(INPUT)
|
val irq = Bool(INPUT)
|
||||||
val irq_cause = UFix(INPUT, 5)
|
val irq_cause = UInt(INPUT, 5)
|
||||||
|
|
||||||
val exception = Bool(OUTPUT)
|
val exception = Bool(OUTPUT)
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ class CtrlVecIO extends Bundle
|
|||||||
val replay = Bool(OUTPUT)
|
val replay = Bool(OUTPUT)
|
||||||
val vfence_ready = Bool(OUTPUT)
|
val vfence_ready = Bool(OUTPUT)
|
||||||
val irq = Bool(OUTPUT)
|
val irq = Bool(OUTPUT)
|
||||||
val irq_cause = UFix(OUTPUT, 5)
|
val irq_cause = UInt(OUTPUT, 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
class rocketCtrlVecSigs extends Bundle
|
class rocketCtrlVecSigs extends Bundle
|
||||||
@ -82,7 +82,7 @@ class rocketCtrlVecSigs extends Bundle
|
|||||||
val xcpthold = Bool()
|
val xcpthold = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class rocketCtrlVecDecoder extends Component
|
class rocketCtrlVecDecoder extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle
|
val io = new Bundle
|
||||||
{
|
{
|
||||||
@ -184,11 +184,11 @@ class rocketCtrlVecDecoder extends Component
|
|||||||
io.sigs.xcpthold := xcpthold.toBool
|
io.sigs.xcpthold := xcpthold.toBool
|
||||||
}
|
}
|
||||||
|
|
||||||
class rocketCtrlVec extends Component
|
class rocketCtrlVec extends Module
|
||||||
{
|
{
|
||||||
val io = new CtrlVecIO
|
val io = new CtrlVecIO
|
||||||
|
|
||||||
val dec = new rocketCtrlVecDecoder()
|
val dec = Module(new rocketCtrlVecDecoder)
|
||||||
dec.io.inst := io.dpath.inst
|
dec.io.inst := io.dpath.inst
|
||||||
|
|
||||||
val valid_common = io.valid && io.sr_ev && dec.io.sigs.valid && !(dec.io.sigs.appvlmask && io.dpath.appvl0)
|
val valid_common = io.valid && io.sr_ev && dec.io.sigs.valid && !(dec.io.sigs.appvlmask && io.dpath.appvl0)
|
||||||
@ -261,7 +261,7 @@ class rocketCtrlVec extends Component
|
|||||||
|
|
||||||
io.iface.exception := io.exception && io.sr_ev
|
io.iface.exception := io.exception && io.sr_ev
|
||||||
|
|
||||||
val reg_hold = Reg(resetVal = Bool(false))
|
val reg_hold = RegReset(Bool(false))
|
||||||
|
|
||||||
when (valid_common && dec.io.sigs.xcpthold) { reg_hold := Bool(true) }
|
when (valid_common && dec.io.sigs.xcpthold) { reg_hold := Bool(true) }
|
||||||
when (io.eret) { reg_hold := Bool(false) }
|
when (io.eret) { reg_hold := Bool(false) }
|
||||||
|
@ -17,7 +17,7 @@ object DecodeLogic
|
|||||||
terms.map { t =>
|
terms.map { t =>
|
||||||
if (!cache.contains(t))
|
if (!cache.contains(t))
|
||||||
cache += t -> ((if (t.mask == 0) addr else addr & Lit(BigInt(2).pow(addr.width)-(t.mask+1), addr.width){Bits()}) === Lit(t.value, addr.width){Bits()})
|
cache += t -> ((if (t.mask == 0) addr else addr & Lit(BigInt(2).pow(addr.width)-(t.mask+1), addr.width){Bits()}) === Lit(t.value, addr.width){Bits()})
|
||||||
cache(t)
|
cache(t).toBool
|
||||||
}.foldLeft(Bool(false))(_||_)
|
}.foldLeft(Bool(false))(_||_)
|
||||||
}
|
}
|
||||||
def apply(addr: Bits, default: Iterable[Bits], mapping: Iterable[(Bits, Iterable[Bits])]) = {
|
def apply(addr: Bits, default: Iterable[Bits], mapping: Iterable[(Bits, Iterable[Bits])]) = {
|
||||||
|
@ -4,20 +4,20 @@ import Chisel._
|
|||||||
import ALU._
|
import ALU._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
class MulDiv(mulUnroll: Int = 1, earlyOut: Boolean = false)(implicit conf: RocketConfiguration) extends Component {
|
class MulDiv(mulUnroll: Int = 1, earlyOut: Boolean = false)(implicit conf: RocketConfiguration) extends Module {
|
||||||
val io = new MultiplierIO
|
val io = new MultiplierIO
|
||||||
val w = io.req.bits.in1.getWidth
|
val w = io.req.bits.in1.getWidth
|
||||||
val mulw = (w+mulUnroll-1)/mulUnroll*mulUnroll
|
val mulw = (w+mulUnroll-1)/mulUnroll*mulUnroll
|
||||||
|
|
||||||
val s_ready :: s_neg_inputs :: s_mul_busy :: s_div_busy :: s_move_rem :: s_neg_output :: s_done :: Nil = Enum(7) { UFix() };
|
val s_ready :: s_neg_inputs :: s_mul_busy :: s_div_busy :: s_move_rem :: s_neg_output :: s_done :: Nil = Enum(7) { UInt() };
|
||||||
val state = Reg(resetVal = s_ready);
|
val state = RegReset(s_ready)
|
||||||
|
|
||||||
val req = Reg{io.req.bits.clone}
|
val req = Reg(io.req.bits.clone)
|
||||||
val count = Reg{UFix(width = log2Up(w+1))}
|
val count = Reg(UInt(width = log2Up(w+1)))
|
||||||
val divby0 = Reg{Bool()}
|
val divby0 = Reg(Bool())
|
||||||
val neg_out = Reg{Bool()}
|
val neg_out = Reg(Bool())
|
||||||
val divisor = Reg{Bits(width = w+1)} // div only needs w bits
|
val divisor = Reg(Bits(width = w+1)) // div only needs w bits
|
||||||
val remainder = Reg{Bits(width = 2*mulw+2)} // div only needs 2*w+1 bits
|
val remainder = Reg(Bits(width = 2*mulw+2)) // div only needs 2*w+1 bits
|
||||||
|
|
||||||
def sext(x: Bits, cmds: Vec[Bits]) = {
|
def sext(x: Bits, cmds: Vec[Bits]) = {
|
||||||
val sign = Mux(io.req.bits.dw === DW_64, x(w-1), x(w/2-1)) && cmds.contains(io.req.bits.fn)
|
val sign = Mux(io.req.bits.dw === DW_64, x(w-1), x(w/2-1)) && cmds.contains(io.req.bits.fn)
|
||||||
@ -51,11 +51,11 @@ class MulDiv(mulUnroll: Int = 1, earlyOut: Boolean = false)(implicit conf: Rocke
|
|||||||
when (state === s_mul_busy) {
|
when (state === s_mul_busy) {
|
||||||
val mulReg = Cat(remainder(2*mulw+1,w+1),remainder(w-1,0))
|
val mulReg = Cat(remainder(2*mulw+1,w+1),remainder(w-1,0))
|
||||||
val mplier = mulReg(mulw-1,0)
|
val mplier = mulReg(mulw-1,0)
|
||||||
val accum = mulReg(2*mulw,mulw).toFix
|
val accum = mulReg(2*mulw,mulw).toSInt
|
||||||
val mpcand = divisor.toFix
|
val mpcand = divisor.toSInt
|
||||||
val prod = mplier(mulUnroll-1,0) * mpcand + accum
|
val prod = mplier(mulUnroll-1,0) * mpcand + accum
|
||||||
val nextMulReg = Cat(prod, mplier(mulw-1,mulUnroll))
|
val nextMulReg = Cat(prod, mplier(mulw-1,mulUnroll)).toUInt
|
||||||
remainder := Cat(nextMulReg >> w, Bool(false), nextMulReg(w-1,0)).toFix
|
remainder := Cat(nextMulReg >> w, Bool(false), nextMulReg(w-1,0)).toSInt
|
||||||
|
|
||||||
count := count + 1
|
count := count + 1
|
||||||
when (count === mulw/mulUnroll-1) {
|
when (count === mulw/mulUnroll-1) {
|
||||||
@ -66,13 +66,13 @@ class MulDiv(mulUnroll: Int = 1, earlyOut: Boolean = false)(implicit conf: Rocke
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
when (state === s_div_busy) {
|
when (state === s_div_busy) {
|
||||||
when (count === UFix(w)) {
|
when (count === UInt(w)) {
|
||||||
state := Mux(neg_out && !divby0, s_neg_output, s_done)
|
state := Mux(neg_out && !divby0, s_neg_output, s_done)
|
||||||
when (AVec(FN_REM, FN_REMU) contains req.fn) {
|
when (AVec(FN_REM, FN_REMU) contains req.fn) {
|
||||||
state := s_move_rem
|
state := s_move_rem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count := count + UFix(1)
|
count := count + UInt(1)
|
||||||
|
|
||||||
val msb = subtractor(w)
|
val msb = subtractor(w)
|
||||||
divby0 := divby0 && !msb
|
divby0 := divby0 && !msb
|
||||||
@ -80,8 +80,8 @@ class MulDiv(mulUnroll: Int = 1, earlyOut: Boolean = false)(implicit conf: Rocke
|
|||||||
|
|
||||||
val divisorMSB = Log2(divisor(w-1,0), w)
|
val divisorMSB = Log2(divisor(w-1,0), w)
|
||||||
val dividendMSB = Log2(remainder(w-1,0), w)
|
val dividendMSB = Log2(remainder(w-1,0), w)
|
||||||
val eOutPos = UFix(w-1, log2Up(2*w)) + divisorMSB - dividendMSB
|
val eOutPos = UInt(w-1, log2Up(2*w)) + divisorMSB - dividendMSB
|
||||||
val eOut = count === UFix(0) && eOutPos > 0 && (divisorMSB != UFix(0) || divisor(0))
|
val eOut = count === UInt(0) && eOutPos > 0 && (divisorMSB != UInt(0) || divisor(0))
|
||||||
when (Bool(earlyOut) && eOut) {
|
when (Bool(earlyOut) && eOut) {
|
||||||
val shift = eOutPos(log2Up(w)-1,0)
|
val shift = eOutPos(log2Up(w)-1,0)
|
||||||
remainder := remainder(w-1,0) << shift
|
remainder := remainder(w-1,0) << shift
|
||||||
@ -101,7 +101,7 @@ class MulDiv(mulUnroll: Int = 1, earlyOut: Boolean = false)(implicit conf: Rocke
|
|||||||
val mulState = Mux(lhs_sign, s_neg_inputs, s_mul_busy)
|
val mulState = Mux(lhs_sign, s_neg_inputs, s_mul_busy)
|
||||||
val divState = Mux(lhs_sign || rhs_sign, s_neg_inputs, s_div_busy)
|
val divState = Mux(lhs_sign || rhs_sign, s_neg_inputs, s_div_busy)
|
||||||
state := Mux(isMul, mulState, divState)
|
state := Mux(isMul, mulState, divState)
|
||||||
count := UFix(0)
|
count := UInt(0)
|
||||||
neg_out := !isMul && Mux(isRem, lhs_sign, lhs_sign != rhs_sign)
|
neg_out := !isMul && Mux(isRem, lhs_sign, lhs_sign != rhs_sign)
|
||||||
divby0 := true
|
divby0 := true
|
||||||
divisor := Cat(rhs_sign, rhs_in)
|
divisor := Cat(rhs_sign, rhs_in)
|
||||||
@ -115,20 +115,20 @@ class MulDiv(mulUnroll: Int = 1, earlyOut: Boolean = false)(implicit conf: Rocke
|
|||||||
io.req.ready := state === s_ready
|
io.req.ready := state === s_ready
|
||||||
}
|
}
|
||||||
|
|
||||||
class Divider(earlyOut: Boolean = false)(implicit conf: RocketConfiguration) extends Component {
|
class Divider(earlyOut: Boolean = false)(implicit conf: RocketConfiguration) extends Module {
|
||||||
val io = new MultiplierIO
|
val io = new MultiplierIO
|
||||||
val w = io.req.bits.in1.getWidth
|
val w = io.req.bits.in1.getWidth
|
||||||
|
|
||||||
val s_ready :: s_neg_inputs :: s_busy :: s_move_rem :: s_neg_output :: s_done :: Nil = Enum(6) { UFix() };
|
val s_ready :: s_neg_inputs :: s_busy :: s_move_rem :: s_neg_output :: s_done :: Nil = Enum(6) { UInt() };
|
||||||
val state = Reg(resetVal = s_ready);
|
val state = RegReset(s_ready)
|
||||||
|
|
||||||
val count = Reg() { UFix(width = log2Up(w+1)) }
|
val count = Reg(UInt(width = log2Up(w+1)))
|
||||||
val divby0 = Reg() { Bool() };
|
val divby0 = Reg(Bool())
|
||||||
val neg_out = Reg() { Bool() };
|
val neg_out = Reg(Bool())
|
||||||
val r_req = Reg{io.req.bits.clone}
|
val r_req = Reg(io.req.bits)
|
||||||
|
|
||||||
val divisor = Reg() { Bits() }
|
val divisor = Reg(Bits())
|
||||||
val remainder = Reg() { Bits(width = 2*w+1) }
|
val remainder = Reg(Bits(width = 2*w+1))
|
||||||
val subtractor = remainder(2*w,w) - divisor
|
val subtractor = remainder(2*w,w) - divisor
|
||||||
|
|
||||||
def sext(x: Bits, cmds: Vec[Bits]) = {
|
def sext(x: Bits, cmds: Vec[Bits]) = {
|
||||||
@ -159,10 +159,10 @@ class Divider(earlyOut: Boolean = false)(implicit conf: RocketConfiguration) ext
|
|||||||
state := Mux(neg_out, s_neg_output, s_done)
|
state := Mux(neg_out, s_neg_output, s_done)
|
||||||
}
|
}
|
||||||
when (state === s_busy) {
|
when (state === s_busy) {
|
||||||
when (count === UFix(w)) {
|
when (count === UInt(w)) {
|
||||||
state := Mux(r_isRem, s_move_rem, Mux(neg_out && !divby0, s_neg_output, s_done))
|
state := Mux(r_isRem, s_move_rem, Mux(neg_out && !divby0, s_neg_output, s_done))
|
||||||
}
|
}
|
||||||
count := count + UFix(1)
|
count := count + UInt(1)
|
||||||
|
|
||||||
val msb = subtractor(w)
|
val msb = subtractor(w)
|
||||||
divby0 := divby0 && !msb
|
divby0 := divby0 && !msb
|
||||||
@ -170,8 +170,8 @@ class Divider(earlyOut: Boolean = false)(implicit conf: RocketConfiguration) ext
|
|||||||
|
|
||||||
val divisorMSB = Log2(divisor, w)
|
val divisorMSB = Log2(divisor, w)
|
||||||
val dividendMSB = Log2(remainder(w-1,0), w)
|
val dividendMSB = Log2(remainder(w-1,0), w)
|
||||||
val eOutPos = UFix(w-1, log2Up(2*w)) + divisorMSB - dividendMSB
|
val eOutPos = UInt(w-1, log2Up(2*w)) + divisorMSB - dividendMSB
|
||||||
val eOut = count === UFix(0) && eOutPos > 0 && (divisorMSB != UFix(0) || divisor(0))
|
val eOut = count === UInt(0) && eOutPos > 0 && (divisorMSB != UInt(0) || divisor(0))
|
||||||
when (Bool(earlyOut) && eOut) {
|
when (Bool(earlyOut) && eOut) {
|
||||||
val shift = eOutPos(log2Up(w)-1,0)
|
val shift = eOutPos(log2Up(w)-1,0)
|
||||||
remainder := remainder(w-1,0) << shift
|
remainder := remainder(w-1,0) << shift
|
||||||
@ -187,7 +187,7 @@ class Divider(earlyOut: Boolean = false)(implicit conf: RocketConfiguration) ext
|
|||||||
}
|
}
|
||||||
when (io.req.fire()) {
|
when (io.req.fire()) {
|
||||||
state := Mux(lhs_sign || rhs_sign, s_neg_inputs, s_busy)
|
state := Mux(lhs_sign || rhs_sign, s_neg_inputs, s_busy)
|
||||||
count := UFix(0)
|
count := UInt(0)
|
||||||
neg_out := Mux(AVec(FN_REM, FN_REMU).contains(io.req.bits.fn), lhs_sign, lhs_sign != rhs_sign)
|
neg_out := Mux(AVec(FN_REM, FN_REMU).contains(io.req.bits.fn), lhs_sign, lhs_sign != rhs_sign)
|
||||||
divby0 := true
|
divby0 := true
|
||||||
divisor := rhs_in
|
divisor := rhs_in
|
||||||
|
@ -6,7 +6,7 @@ import Util._
|
|||||||
import hwacha._
|
import hwacha._
|
||||||
import uncore.constants.AddressConstants._
|
import uncore.constants.AddressConstants._
|
||||||
|
|
||||||
class Datapath(implicit conf: RocketConfiguration) extends Component
|
class Datapath(implicit conf: RocketConfiguration) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val host = new HTIFIO(conf.tl.ln.nClients)
|
val host = new HTIFIO(conf.tl.ln.nClients)
|
||||||
@ -20,71 +20,71 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
// execute definitions
|
// execute definitions
|
||||||
val ex_reg_pc = Reg() { UFix() };
|
val ex_reg_pc = Reg(UInt())
|
||||||
val ex_reg_inst = Reg() { Bits() };
|
val ex_reg_inst = Reg(Bits())
|
||||||
val ex_reg_waddr = Reg() { UFix() };
|
val ex_reg_waddr = Reg(UInt())
|
||||||
val ex_reg_ctrl_fn_dw = Reg() { UFix() };
|
val ex_reg_ctrl_fn_dw = Reg(UInt())
|
||||||
val ex_reg_ctrl_fn_alu = Reg() { UFix() };
|
val ex_reg_ctrl_fn_alu = Reg(UInt())
|
||||||
val ex_reg_sel_alu2 = Reg() { UFix() };
|
val ex_reg_sel_alu2 = Reg(UInt())
|
||||||
val ex_reg_ctrl_sel_wb = Reg() { UFix() };
|
val ex_reg_ctrl_sel_wb = Reg(UInt())
|
||||||
val ex_reg_kill = Reg{Bool()}
|
val ex_reg_kill = Reg(Bool())
|
||||||
val ex_reg_rs1_bypass = Reg{Bool()}
|
val ex_reg_rs1_bypass = Reg(Bool())
|
||||||
val ex_reg_rs1_lsb = Reg{Bits()}
|
val ex_reg_rs1_lsb = Reg(Bits())
|
||||||
val ex_reg_rs1_msb = Reg{Bits()}
|
val ex_reg_rs1_msb = Reg(Bits())
|
||||||
val ex_reg_rs2_bypass = Reg{Bool()}
|
val ex_reg_rs2_bypass = Reg(Bool())
|
||||||
val ex_reg_rs2_lsb = Reg{Bits()}
|
val ex_reg_rs2_lsb = Reg(Bits())
|
||||||
val ex_reg_rs2_msb = Reg{Bits()}
|
val ex_reg_rs2_msb = Reg(Bits())
|
||||||
|
|
||||||
// memory definitions
|
// memory definitions
|
||||||
val mem_reg_pc = Reg() { UFix() };
|
val mem_reg_pc = Reg(UInt())
|
||||||
val mem_reg_inst = Reg() { Bits() };
|
val mem_reg_inst = Reg(Bits())
|
||||||
val mem_reg_waddr = Reg() { UFix() };
|
val mem_reg_waddr = Reg(UInt())
|
||||||
val mem_reg_wdata = Reg() { Bits() };
|
val mem_reg_wdata = Reg(Bits())
|
||||||
val mem_reg_kill = Reg() { Bool() }
|
val mem_reg_kill = Reg(Bool())
|
||||||
val mem_reg_store_data = Reg{Bits()}
|
val mem_reg_store_data = Reg(Bits())
|
||||||
val mem_reg_rs1 = Reg{Bits()}
|
val mem_reg_rs1 = Reg(Bits())
|
||||||
val mem_reg_rs2 = Reg{Bits()}
|
val mem_reg_rs2 = Reg(Bits())
|
||||||
|
|
||||||
// writeback definitions
|
// writeback definitions
|
||||||
val wb_reg_pc = Reg() { UFix() };
|
val wb_reg_pc = Reg(UInt())
|
||||||
val wb_reg_inst = Reg() { Bits() };
|
val wb_reg_inst = Reg(Bits())
|
||||||
val wb_reg_waddr = Reg() { UFix() }
|
val wb_reg_waddr = Reg(UInt())
|
||||||
val wb_reg_wdata = Reg() { Bits() }
|
val wb_reg_wdata = Reg(Bits())
|
||||||
val wb_reg_ll_wb = Reg(resetVal = Bool(false));
|
val wb_reg_ll_wb = RegReset(Bool(false))
|
||||||
val wb_wdata = Bits();
|
val wb_wdata = Bits()
|
||||||
val wb_reg_store_data = Reg{Bits()}
|
val wb_reg_store_data = Reg(Bits())
|
||||||
val wb_reg_rs1 = Reg{Bits()}
|
val wb_reg_rs1 = Reg(Bits())
|
||||||
val wb_reg_rs2 = Reg{Bits()}
|
val wb_reg_rs2 = Reg(Bits())
|
||||||
val wb_wen = io.ctrl.wb_wen && io.ctrl.wb_valid || wb_reg_ll_wb
|
val wb_wen = io.ctrl.wb_wen && io.ctrl.wb_valid || wb_reg_ll_wb
|
||||||
|
|
||||||
// instruction decode stage
|
// instruction decode stage
|
||||||
val id_inst = io.imem.resp.bits.data
|
val id_inst = io.imem.resp.bits.data
|
||||||
val id_pc = io.imem.resp.bits.pc
|
val id_pc = io.imem.resp.bits.pc
|
||||||
|
|
||||||
val regfile_ = Mem(31){Bits(width = 64)}
|
val regfile_ = Mem(Bits(width = 64), 31)
|
||||||
def readRF(a: UFix) = regfile_(~a)
|
def readRF(a: UInt) = regfile_(~a)
|
||||||
def writeRF(a: UFix, d: Bits) = regfile_(~a) := d
|
def writeRF(a: UInt, d: Bits) = regfile_(~a) := d
|
||||||
|
|
||||||
val id_raddr1 = id_inst(26,22).toUFix;
|
val id_raddr1 = id_inst(26,22).toUInt;
|
||||||
val id_raddr2 = id_inst(21,17).toUFix;
|
val id_raddr2 = id_inst(21,17).toUInt;
|
||||||
|
|
||||||
// bypass muxes
|
// bypass muxes
|
||||||
val id_rs1_zero = id_raddr1 === UFix(0)
|
val id_rs1_zero = id_raddr1 === UInt(0)
|
||||||
val id_rs1_ex_bypass = io.ctrl.ex_wen && id_raddr1 === ex_reg_waddr
|
val id_rs1_ex_bypass = io.ctrl.ex_wen && id_raddr1 === ex_reg_waddr
|
||||||
val id_rs1_mem_bypass = io.ctrl.mem_wen && id_raddr1 === mem_reg_waddr
|
val id_rs1_mem_bypass = io.ctrl.mem_wen && id_raddr1 === mem_reg_waddr
|
||||||
val id_rs1_bypass = id_rs1_zero || id_rs1_ex_bypass || id_rs1_mem_bypass
|
val id_rs1_bypass = id_rs1_zero || id_rs1_ex_bypass || id_rs1_mem_bypass
|
||||||
val id_rs1_bypass_src = Mux(id_rs1_zero, UFix(0), Mux(id_rs1_ex_bypass, UFix(1), UFix(2) | io.ctrl.mem_load))
|
val id_rs1_bypass_src = Mux(id_rs1_zero, UInt(0), Mux(id_rs1_ex_bypass, UInt(1), UInt(2) | io.ctrl.mem_load))
|
||||||
val id_rs1 =
|
val id_rs1 =
|
||||||
Mux(id_raddr1 === UFix(0), UFix(0),
|
Mux(id_raddr1 === UInt(0), UInt(0),
|
||||||
Mux(wb_wen && id_raddr1 === wb_reg_waddr, wb_wdata,
|
Mux(wb_wen && id_raddr1 === wb_reg_waddr, wb_wdata,
|
||||||
readRF(id_raddr1)))
|
readRF(id_raddr1)))
|
||||||
|
|
||||||
val id_rs2_zero = id_raddr2 === UFix(0)
|
val id_rs2_zero = id_raddr2 === UInt(0)
|
||||||
val id_rs2_ex_bypass = io.ctrl.ex_wen && id_raddr2 === ex_reg_waddr
|
val id_rs2_ex_bypass = io.ctrl.ex_wen && id_raddr2 === ex_reg_waddr
|
||||||
val id_rs2_mem_bypass = io.ctrl.mem_wen && id_raddr2 === mem_reg_waddr
|
val id_rs2_mem_bypass = io.ctrl.mem_wen && id_raddr2 === mem_reg_waddr
|
||||||
val id_rs2_bypass = id_rs2_zero || id_rs2_ex_bypass || id_rs2_mem_bypass
|
val id_rs2_bypass = id_rs2_zero || id_rs2_ex_bypass || id_rs2_mem_bypass
|
||||||
val id_rs2_bypass_src = Mux(id_rs2_zero, UFix(0), Mux(id_rs2_ex_bypass, UFix(1), UFix(2) | io.ctrl.mem_load))
|
val id_rs2_bypass_src = Mux(id_rs2_zero, UInt(0), Mux(id_rs2_ex_bypass, UInt(1), UInt(2) | io.ctrl.mem_load))
|
||||||
val id_rs2 = Mux(id_raddr2 === UFix(0), UFix(0),
|
val id_rs2 = Mux(id_raddr2 === UInt(0), UInt(0),
|
||||||
Mux(wb_wen && id_raddr2 === wb_reg_waddr, wb_wdata,
|
Mux(wb_wen && id_raddr2 === wb_reg_waddr, wb_wdata,
|
||||||
readRF(id_raddr2)))
|
readRF(id_raddr2)))
|
||||||
|
|
||||||
@ -94,11 +94,11 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
Mux(sel === A2_BTYPE, Cat(inst(31,27), inst(16,10)),
|
Mux(sel === A2_BTYPE, Cat(inst(31,27), inst(16,10)),
|
||||||
Mux(sel === A2_JTYPE, inst(18,7),
|
Mux(sel === A2_JTYPE, inst(18,7),
|
||||||
inst(21,10))))
|
inst(21,10))))
|
||||||
val msbs = Mux(sel === A2_ZERO, Bits(0),
|
val msbs = Mux(sel === A2_ZERO, SInt(0),
|
||||||
Mux(sel === A2_LTYPE, inst(26,7).toFix,
|
Mux(sel === A2_LTYPE, inst(26,7).toSInt,
|
||||||
Mux(sel === A2_JTYPE, inst(31,19).toFix,
|
Mux(sel === A2_JTYPE, inst(31,19).toSInt,
|
||||||
Mux(sel === A2_ITYPE, inst(21), inst(31)).toFix)))
|
Mux(sel === A2_ITYPE, inst(21), inst(31)).toSInt)))
|
||||||
Cat(msbs, lsbs).toFix
|
Cat(msbs, lsbs).toSInt
|
||||||
}
|
}
|
||||||
|
|
||||||
io.ctrl.inst := id_inst
|
io.ctrl.inst := id_inst
|
||||||
@ -109,8 +109,8 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
when (!io.ctrl.killd) {
|
when (!io.ctrl.killd) {
|
||||||
ex_reg_pc := id_pc
|
ex_reg_pc := id_pc
|
||||||
ex_reg_inst := id_inst
|
ex_reg_inst := id_inst
|
||||||
ex_reg_waddr := Mux(io.ctrl.sel_wa === WA_RD, id_inst(31,27).toUFix, RA)
|
ex_reg_waddr := Mux(io.ctrl.sel_wa === WA_RD, id_inst(31,27).toUInt, RA)
|
||||||
ex_reg_ctrl_fn_dw := io.ctrl.fn_dw.toUFix
|
ex_reg_ctrl_fn_dw := io.ctrl.fn_dw.toUInt
|
||||||
ex_reg_ctrl_fn_alu := io.ctrl.fn_alu
|
ex_reg_ctrl_fn_alu := io.ctrl.fn_alu
|
||||||
ex_reg_sel_alu2 := io.ctrl.sel_alu2
|
ex_reg_sel_alu2 := io.ctrl.sel_alu2
|
||||||
ex_reg_ctrl_sel_wb := io.ctrl.sel_wb
|
ex_reg_ctrl_sel_wb := io.ctrl.sel_wb
|
||||||
@ -137,29 +137,29 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
|
|
||||||
val dmem_resp_data = if (conf.fastLoadByte) io.dmem.resp.bits.data_subword else io.dmem.resp.bits.data
|
val dmem_resp_data = if (conf.fastLoadByte) io.dmem.resp.bits.data_subword else io.dmem.resp.bits.data
|
||||||
val ex_rs1 =
|
val ex_rs1 =
|
||||||
Mux(ex_reg_rs1_bypass && ex_reg_rs1_lsb === UFix(3) && Bool(conf.fastLoadWord), dmem_resp_data,
|
Mux(ex_reg_rs1_bypass && ex_reg_rs1_lsb === UInt(3) && Bool(conf.fastLoadWord), dmem_resp_data,
|
||||||
Mux(ex_reg_rs1_bypass && ex_reg_rs1_lsb === UFix(2), wb_reg_wdata,
|
Mux(ex_reg_rs1_bypass && ex_reg_rs1_lsb === UInt(2), wb_reg_wdata,
|
||||||
Mux(ex_reg_rs1_bypass && ex_reg_rs1_lsb === UFix(1), mem_reg_wdata,
|
Mux(ex_reg_rs1_bypass && ex_reg_rs1_lsb === UInt(1), mem_reg_wdata,
|
||||||
Mux(ex_reg_rs1_bypass && ex_reg_rs1_lsb === UFix(0), Bits(0),
|
Mux(ex_reg_rs1_bypass && ex_reg_rs1_lsb === UInt(0), Bits(0),
|
||||||
Cat(ex_reg_rs1_msb, ex_reg_rs1_lsb)))))
|
Cat(ex_reg_rs1_msb, ex_reg_rs1_lsb)))))
|
||||||
val ex_rs2 =
|
val ex_rs2 =
|
||||||
Mux(ex_reg_rs2_bypass && ex_reg_rs2_lsb === UFix(3) && Bool(conf.fastLoadWord), dmem_resp_data,
|
Mux(ex_reg_rs2_bypass && ex_reg_rs2_lsb === UInt(3) && Bool(conf.fastLoadWord), dmem_resp_data,
|
||||||
Mux(ex_reg_rs2_bypass && ex_reg_rs2_lsb === UFix(2), wb_reg_wdata,
|
Mux(ex_reg_rs2_bypass && ex_reg_rs2_lsb === UInt(2), wb_reg_wdata,
|
||||||
Mux(ex_reg_rs2_bypass && ex_reg_rs2_lsb === UFix(1), mem_reg_wdata,
|
Mux(ex_reg_rs2_bypass && ex_reg_rs2_lsb === UInt(1), mem_reg_wdata,
|
||||||
Mux(ex_reg_rs2_bypass && ex_reg_rs2_lsb === UFix(0), Bits(0),
|
Mux(ex_reg_rs2_bypass && ex_reg_rs2_lsb === UInt(0), Bits(0),
|
||||||
Cat(ex_reg_rs2_msb, ex_reg_rs2_lsb)))))
|
Cat(ex_reg_rs2_msb, ex_reg_rs2_lsb)))))
|
||||||
val ex_imm = imm(ex_reg_sel_alu2, ex_reg_inst)
|
val ex_imm = imm(ex_reg_sel_alu2, ex_reg_inst)
|
||||||
val ex_op2 = Mux(ex_reg_sel_alu2 != A2_RTYPE, ex_imm, ex_rs2)
|
val ex_op2 = Mux(ex_reg_sel_alu2 != A2_RTYPE, ex_imm, ex_rs2)
|
||||||
|
|
||||||
val alu = new ALU
|
val alu = Module(new ALU)
|
||||||
alu.io.dw := ex_reg_ctrl_fn_dw;
|
alu.io.dw := ex_reg_ctrl_fn_dw;
|
||||||
alu.io.fn := ex_reg_ctrl_fn_alu;
|
alu.io.fn := ex_reg_ctrl_fn_alu;
|
||||||
alu.io.in2 := ex_op2.toUFix
|
alu.io.in2 := ex_op2.toUInt
|
||||||
alu.io.in1 := ex_rs1.toUFix
|
alu.io.in1 := ex_rs1.toUInt
|
||||||
|
|
||||||
// multiplier and divider
|
// multiplier and divider
|
||||||
val div = new MulDiv(mulUnroll = if (conf.fastMulDiv) 8 else 1,
|
val div = Module(new MulDiv(mulUnroll = if (conf.fastMulDiv) 8 else 1,
|
||||||
earlyOut = conf.fastMulDiv)
|
earlyOut = conf.fastMulDiv))
|
||||||
div.io.req.valid := io.ctrl.div_mul_val
|
div.io.req.valid := io.ctrl.div_mul_val
|
||||||
div.io.req.bits.dw := ex_reg_ctrl_fn_dw
|
div.io.req.bits.dw := ex_reg_ctrl_fn_dw
|
||||||
div.io.req.bits.fn := ex_reg_ctrl_fn_alu
|
div.io.req.bits.fn := ex_reg_ctrl_fn_alu
|
||||||
@ -173,16 +173,16 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.fpu.fromint_data := ex_rs1
|
io.fpu.fromint_data := ex_rs1
|
||||||
io.ctrl.ex_waddr := ex_reg_waddr
|
io.ctrl.ex_waddr := ex_reg_waddr
|
||||||
|
|
||||||
def vaSign(a0: Bits, ea: Bits) = {
|
def vaSign(a0: UInt, ea: Bits) = {
|
||||||
// efficient means to compress 64-bit VA into VADDR_BITS+1 bits
|
// efficient means to compress 64-bit VA into VADDR_BITS+1 bits
|
||||||
// (VA is bad if VA(VADDR_BITS) != VA(VADDR_BITS-1))
|
// (VA is bad if VA(VADDR_BITS) != VA(VADDR_BITS-1))
|
||||||
val a = a0 >> VADDR_BITS-1
|
val a = a0 >> VADDR_BITS-1
|
||||||
val e = ea(VADDR_BITS,VADDR_BITS-1)
|
val e = ea(VADDR_BITS,VADDR_BITS-1)
|
||||||
Mux(a === UFix(0) || a === UFix(1), e != UFix(0),
|
Mux(a === UInt(0) || a === UInt(1), e != UInt(0),
|
||||||
Mux(a === Fix(-1) || a === Fix(-2), e === Fix(-1),
|
Mux(a === SInt(-1) || a === SInt(-2), e === SInt(-1),
|
||||||
e(0)))
|
e(0)))
|
||||||
}
|
}
|
||||||
val ex_effective_address = Cat(vaSign(ex_rs1, alu.io.adder_out), alu.io.adder_out(VADDR_BITS-1,0)).toUFix
|
val ex_effective_address = Cat(vaSign(ex_rs1, alu.io.adder_out), alu.io.adder_out(VADDR_BITS-1,0)).toUInt
|
||||||
|
|
||||||
// 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
|
||||||
@ -192,7 +192,7 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
require(io.dmem.req.bits.tag.getWidth >= 6)
|
require(io.dmem.req.bits.tag.getWidth >= 6)
|
||||||
|
|
||||||
// processor control regfile read
|
// processor control regfile read
|
||||||
val pcr = new PCR
|
val pcr = Module(new PCR)
|
||||||
pcr.io.host <> io.host
|
pcr.io.host <> io.host
|
||||||
pcr.io <> io.ctrl
|
pcr.io <> io.ctrl
|
||||||
pcr.io.pc := wb_reg_pc
|
pcr.io.pc := wb_reg_pc
|
||||||
@ -204,18 +204,18 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.ptw.status := pcr.io.status
|
io.ptw.status := pcr.io.status
|
||||||
|
|
||||||
// branch resolution logic
|
// branch resolution logic
|
||||||
io.ctrl.jalr_eq := ex_rs1 === id_pc.toFix && ex_reg_inst(21,10) === UFix(0)
|
io.ctrl.jalr_eq := ex_rs1 === id_pc.toSInt && ex_reg_inst(21,10) === UInt(0)
|
||||||
io.ctrl.ex_br_taken :=
|
io.ctrl.ex_br_taken :=
|
||||||
Mux(io.ctrl.ex_br_type === BR_EQ, ex_rs1 === ex_rs2,
|
Mux(io.ctrl.ex_br_type === BR_EQ, ex_rs1 === ex_rs2,
|
||||||
Mux(io.ctrl.ex_br_type === BR_NE, ex_rs1 != ex_rs2,
|
Mux(io.ctrl.ex_br_type === BR_NE, ex_rs1 != ex_rs2,
|
||||||
Mux(io.ctrl.ex_br_type === BR_LT, ex_rs1.toFix < ex_rs2.toFix,
|
Mux(io.ctrl.ex_br_type === BR_LT, ex_rs1.toSInt < ex_rs2.toSInt,
|
||||||
Mux(io.ctrl.ex_br_type === BR_GE, ex_rs1.toFix >= ex_rs2.toFix,
|
Mux(io.ctrl.ex_br_type === BR_GE, ex_rs1.toSInt >= ex_rs2.toSInt,
|
||||||
Mux(io.ctrl.ex_br_type === BR_LTU, ex_rs1 < ex_rs2,
|
Mux(io.ctrl.ex_br_type === BR_LTU, ex_rs1 < ex_rs2,
|
||||||
Mux(io.ctrl.ex_br_type === BR_GEU, ex_rs1 >= ex_rs2,
|
Mux(io.ctrl.ex_br_type === BR_GEU, ex_rs1 >= ex_rs2,
|
||||||
io.ctrl.ex_br_type === BR_J))))))
|
io.ctrl.ex_br_type === BR_J))))))
|
||||||
|
|
||||||
val ex_pc_plus4 = ex_reg_pc.toFix + Mux(ex_reg_sel_alu2 === A2_LTYPE, ex_reg_inst(26,7).toFix << 12, Fix(4))
|
val ex_pc_plus4 = ex_reg_pc.toSInt + Mux(ex_reg_sel_alu2 === A2_LTYPE, ex_reg_inst(26,7).toSInt << 12, SInt(4))
|
||||||
val ex_branch_target = ex_reg_pc.toFix + (ex_imm << 1)
|
val ex_branch_target = ex_reg_pc.toSInt + (ex_imm << 1)
|
||||||
|
|
||||||
val tsc_reg = WideCounter(64)
|
val tsc_reg = WideCounter(64)
|
||||||
val irt_reg = WideCounter(64, io.ctrl.wb_valid)
|
val irt_reg = WideCounter(64, io.ctrl.wb_valid)
|
||||||
@ -247,7 +247,7 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
// writeback arbitration
|
// writeback arbitration
|
||||||
val dmem_resp_xpu = !io.dmem.resp.bits.tag(0).toBool
|
val dmem_resp_xpu = !io.dmem.resp.bits.tag(0).toBool
|
||||||
val dmem_resp_fpu = io.dmem.resp.bits.tag(0).toBool
|
val dmem_resp_fpu = io.dmem.resp.bits.tag(0).toBool
|
||||||
val dmem_resp_waddr = io.dmem.resp.bits.tag.toUFix >> UFix(1)
|
val dmem_resp_waddr = io.dmem.resp.bits.tag.toUInt >> UInt(1)
|
||||||
val dmem_resp_replay = io.dmem.resp.bits.replay && dmem_resp_xpu
|
val dmem_resp_replay = io.dmem.resp.bits.replay && dmem_resp_xpu
|
||||||
|
|
||||||
val mem_ll_wdata = Bits()
|
val mem_ll_wdata = Bits()
|
||||||
@ -260,7 +260,7 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.ctrl.mem_ll_waddr := dmem_resp_waddr
|
io.ctrl.mem_ll_waddr := dmem_resp_waddr
|
||||||
io.ctrl.mem_ll_wb := Bool(true)
|
io.ctrl.mem_ll_wb := Bool(true)
|
||||||
}
|
}
|
||||||
when (io.ctrl.mem_ll_waddr === UFix(0)) { io.ctrl.mem_ll_wb := Bool(false) }
|
when (io.ctrl.mem_ll_waddr === UInt(0)) { io.ctrl.mem_ll_wb := Bool(false) }
|
||||||
|
|
||||||
io.fpu.dmem_resp_val := io.dmem.resp.valid && dmem_resp_fpu
|
io.fpu.dmem_resp_val := io.dmem.resp.valid && dmem_resp_fpu
|
||||||
io.fpu.dmem_resp_data := io.dmem.resp.bits.data
|
io.fpu.dmem_resp_data := io.dmem.resp.bits.data
|
||||||
@ -291,7 +291,7 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
if (conf.vec)
|
if (conf.vec)
|
||||||
{
|
{
|
||||||
// vector datapath
|
// vector datapath
|
||||||
val vec = new rocketDpathVec()
|
val vec = Module(new rocketDpathVec)
|
||||||
|
|
||||||
vec.io.ctrl <> io.vec_ctrl
|
vec.io.ctrl <> io.vec_ctrl
|
||||||
io.vec_iface <> vec.io.iface
|
io.vec_iface <> vec.io.iface
|
||||||
@ -319,7 +319,7 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.ctrl.fp_sboard_clra := dmem_resp_waddr
|
io.ctrl.fp_sboard_clra := dmem_resp_waddr
|
||||||
|
|
||||||
// processor control regfile write
|
// processor control regfile write
|
||||||
pcr.io.rw.addr := wb_reg_inst(26,22).toUFix
|
pcr.io.rw.addr := wb_reg_inst(26,22).toUInt
|
||||||
pcr.io.rw.cmd := io.ctrl.pcr
|
pcr.io.rw.cmd := io.ctrl.pcr
|
||||||
pcr.io.rw.wdata := wb_reg_wdata
|
pcr.io.rw.wdata := wb_reg_wdata
|
||||||
|
|
||||||
@ -327,13 +327,13 @@ class Datapath(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.imem.req.bits.currentpc := ex_reg_pc
|
io.imem.req.bits.currentpc := ex_reg_pc
|
||||||
io.imem.req.bits.pc :=
|
io.imem.req.bits.pc :=
|
||||||
Mux(io.ctrl.sel_pc === PC_EX4, ex_pc_plus4,
|
Mux(io.ctrl.sel_pc === PC_EX4, ex_pc_plus4,
|
||||||
Mux(io.ctrl.sel_pc === PC_EX, Mux(io.ctrl.ex_jalr, ex_effective_address, ex_branch_target),
|
Mux(io.ctrl.sel_pc === PC_EX, Mux(io.ctrl.ex_jalr, ex_effective_address.toSInt, ex_branch_target),
|
||||||
Mux(io.ctrl.sel_pc === PC_PCR, Cat(pcr.io.evec(VADDR_BITS-1), pcr.io.evec),
|
Mux(io.ctrl.sel_pc === PC_PCR, Cat(pcr.io.evec(VADDR_BITS-1), pcr.io.evec),
|
||||||
wb_reg_pc))).toUFix // PC_WB
|
wb_reg_pc))).toUInt // PC_WB
|
||||||
|
|
||||||
printf("C: %d [%d] pc=[%x] W[r%d=%x] R[r%d=%x] R[r%d=%x] inst=[%x] %s\n",
|
printf("C: %d [%d] pc=[%x] W[r%d=%x] R[r%d=%x] R[r%d=%x] inst=[%x] %s\n",
|
||||||
tsc_reg(32,0), io.ctrl.wb_valid, wb_reg_pc,
|
tsc_reg(32,0), io.ctrl.wb_valid, wb_reg_pc,
|
||||||
Mux(wb_wen, wb_reg_waddr, UFix(0)), wb_wdata,
|
Mux(wb_wen, wb_reg_waddr, UInt(0)), wb_wdata,
|
||||||
wb_reg_inst(26,22), wb_reg_rs1,
|
wb_reg_inst(26,22), wb_reg_rs1,
|
||||||
wb_reg_inst(21,17), wb_reg_rs2,
|
wb_reg_inst(21,17), wb_reg_rs2,
|
||||||
wb_reg_inst, Disassemble(wb_reg_inst))
|
wb_reg_inst, Disassemble(wb_reg_inst))
|
||||||
|
@ -39,13 +39,13 @@ import ALU._
|
|||||||
class ALUIO(implicit conf: RocketConfiguration) extends Bundle {
|
class ALUIO(implicit conf: RocketConfiguration) extends Bundle {
|
||||||
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 = UFix(INPUT, conf.xprlen)
|
val in2 = UInt(INPUT, conf.xprlen)
|
||||||
val in1 = UFix(INPUT, conf.xprlen)
|
val in1 = UInt(INPUT, conf.xprlen)
|
||||||
val out = UFix(OUTPUT, conf.xprlen)
|
val out = UInt(OUTPUT, conf.xprlen)
|
||||||
val adder_out = UFix(OUTPUT, conf.xprlen)
|
val adder_out = UInt(OUTPUT, conf.xprlen)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ALU(implicit conf: RocketConfiguration) extends Component
|
class ALU(implicit conf: RocketConfiguration) extends Module
|
||||||
{
|
{
|
||||||
val io = new ALUIO
|
val io = new ALUIO
|
||||||
|
|
||||||
@ -57,12 +57,12 @@ class ALU(implicit conf: RocketConfiguration) extends Component
|
|||||||
Mux(isSLTU(io.fn), io.in2(63), io.in1(63)))
|
Mux(isSLTU(io.fn), io.in2(63), io.in1(63)))
|
||||||
|
|
||||||
// SLL, SRL, SRA
|
// SLL, SRL, SRA
|
||||||
val shamt = Cat(io.in2(5) & (io.dw === DW_64), io.in2(4,0)).toUFix
|
val shamt = Cat(io.in2(5) & (io.dw === DW_64), io.in2(4,0)).toUInt
|
||||||
val shin_hi_32 = Mux(isSub(io.fn), Fill(32, io.in1(31)), UFix(0,32))
|
val shin_hi_32 = Mux(isSub(io.fn), Fill(32, io.in1(31)), UInt(0,32))
|
||||||
val shin_hi = Mux(io.dw === DW_64, io.in1(63,32), shin_hi_32)
|
val shin_hi = Mux(io.dw === DW_64, io.in1(63,32), shin_hi_32)
|
||||||
val shin_r = Cat(shin_hi, io.in1(31,0))
|
val shin_r = Cat(shin_hi, io.in1(31,0))
|
||||||
val shin = Mux(io.fn === FN_SR || io.fn === FN_SRA, shin_r, Reverse(shin_r))
|
val shin = Mux(io.fn === FN_SR || io.fn === FN_SRA, shin_r, Reverse(shin_r))
|
||||||
val shout_r = (Cat(isSub(io.fn) & shin(63), shin).toFix >> shamt)(63,0)
|
val shout_r = (Cat(isSub(io.fn) & shin(63), shin).toSInt >> shamt)(63,0)
|
||||||
val shout_l = Reverse(shout_r)
|
val shout_l = Reverse(shout_r)
|
||||||
|
|
||||||
val bitwise_logic =
|
val bitwise_logic =
|
||||||
@ -79,6 +79,6 @@ class ALU(implicit conf: RocketConfiguration) extends Component
|
|||||||
bitwise_logic))))
|
bitwise_logic))))
|
||||||
|
|
||||||
val out_hi = Mux(io.dw === DW_64, out64(63,32), Fill(32, out64(31)))
|
val out_hi = Mux(io.dw === DW_64, out64(63,32), Fill(32, out64(31)))
|
||||||
io.out := Cat(out_hi, out64(31,0)).toUFix
|
io.out := Cat(out_hi, out64(31,0)).toUInt
|
||||||
io.adder_out := sum
|
io.adder_out := sum
|
||||||
}
|
}
|
||||||
|
@ -8,18 +8,18 @@ import scala.math._
|
|||||||
|
|
||||||
class DpathBTBIO extends Bundle
|
class DpathBTBIO extends Bundle
|
||||||
{
|
{
|
||||||
val current_pc = UFix(INPUT, VADDR_BITS);
|
val current_pc = UInt(INPUT, VADDR_BITS);
|
||||||
val hit = Bool(OUTPUT);
|
val hit = Bool(OUTPUT);
|
||||||
val target = UFix(OUTPUT, VADDR_BITS);
|
val target = UInt(OUTPUT, VADDR_BITS);
|
||||||
val wen = Bool(INPUT);
|
val wen = Bool(INPUT);
|
||||||
val clr = Bool(INPUT);
|
val clr = Bool(INPUT);
|
||||||
val invalidate = Bool(INPUT);
|
val invalidate = Bool(INPUT);
|
||||||
val correct_pc = UFix(INPUT, VADDR_BITS);
|
val correct_pc = UInt(INPUT, VADDR_BITS);
|
||||||
val correct_target = UFix(INPUT, VADDR_BITS);
|
val correct_target = UInt(INPUT, VADDR_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fully-associative branch target buffer
|
// fully-associative branch target buffer
|
||||||
class rocketDpathBTB(entries: Int) extends Component
|
class rocketDpathBTB(entries: Int) extends Module
|
||||||
{
|
{
|
||||||
val io = new DpathBTBIO
|
val io = new DpathBTBIO
|
||||||
|
|
||||||
@ -29,18 +29,18 @@ class rocketDpathBTB(entries: Int) extends Component
|
|||||||
val hit = Bool()
|
val hit = Bool()
|
||||||
val update = Bool()
|
val update = Bool()
|
||||||
var update_reduction = Bool(false)
|
var update_reduction = Bool(false)
|
||||||
val hits = Vec(entries) { Bool() }
|
val hits = Vec.fill(entries){Bool()}
|
||||||
val updates = Vec(entries) { Bool() }
|
val updates = Vec.fill(entries){Bool()}
|
||||||
val targets = Vec(entries) { Reg() { UFix() } }
|
val targets = Vec.fill(entries){Reg(UInt())}
|
||||||
val anyUpdate = updates.toBits.orR
|
val anyUpdate = updates.toBits.orR
|
||||||
|
|
||||||
for (i <- 0 until entries) {
|
for (i <- 0 until entries) {
|
||||||
val tag = Reg() { UFix() }
|
val tag = Reg(UInt())
|
||||||
val valid = Reg(resetVal = Bool(false))
|
val valid = RegReset(Bool(false))
|
||||||
hits(i) := valid && tag === io.current_pc
|
hits(i) := valid && tag === io.current_pc
|
||||||
updates(i) := valid && tag === io.correct_pc
|
updates(i) := valid && tag === io.correct_pc
|
||||||
|
|
||||||
when (io.wen && (updates(i) || !anyUpdate && UFix(i) === repl_way)) {
|
when (io.wen && (updates(i) || !anyUpdate && UInt(i) === repl_way)) {
|
||||||
valid := Bool(false)
|
valid := Bool(false)
|
||||||
when (!io.clr) {
|
when (!io.clr) {
|
||||||
valid := Bool(true)
|
valid := Bool(true)
|
||||||
@ -103,26 +103,26 @@ object PCR
|
|||||||
val FROMHOST = 31
|
val FROMHOST = 31
|
||||||
}
|
}
|
||||||
|
|
||||||
class PCR(implicit conf: RocketConfiguration) extends Component
|
class PCR(implicit conf: RocketConfiguration) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val host = new HTIFIO(conf.tl.ln.nClients)
|
val host = new HTIFIO(conf.tl.ln.nClients)
|
||||||
val rw = new Bundle {
|
val rw = new Bundle {
|
||||||
val addr = UFix(INPUT, log2Up(conf.nxpr))
|
val addr = UInt(INPUT, log2Up(conf.nxpr))
|
||||||
val cmd = Bits(INPUT, PCR.SZ)
|
val cmd = Bits(INPUT, PCR.SZ)
|
||||||
val rdata = Bits(OUTPUT, conf.xprlen)
|
val rdata = Bits(OUTPUT, conf.xprlen)
|
||||||
val wdata = Bits(INPUT, conf.xprlen)
|
val wdata = Bits(INPUT, conf.xprlen)
|
||||||
}
|
}
|
||||||
|
|
||||||
val status = new Status().asOutput
|
val status = new Status().asOutput
|
||||||
val ptbr = UFix(OUTPUT, PADDR_BITS)
|
val ptbr = UInt(OUTPUT, PADDR_BITS)
|
||||||
val evec = UFix(OUTPUT, VADDR_BITS)
|
val evec = UInt(OUTPUT, VADDR_BITS)
|
||||||
val exception = Bool(INPUT)
|
val exception = Bool(INPUT)
|
||||||
val cause = UFix(INPUT, 6)
|
val cause = UInt(INPUT, 6)
|
||||||
val badvaddr_wen = Bool(INPUT)
|
val badvaddr_wen = Bool(INPUT)
|
||||||
val vec_irq_aux = Bits(INPUT, conf.xprlen)
|
val vec_irq_aux = Bits(INPUT, conf.xprlen)
|
||||||
val vec_irq_aux_wen = Bool(INPUT)
|
val vec_irq_aux_wen = Bool(INPUT)
|
||||||
val pc = UFix(INPUT, VADDR_BITS+1)
|
val pc = UInt(INPUT, VADDR_BITS+1)
|
||||||
val eret = Bool(INPUT)
|
val eret = Bool(INPUT)
|
||||||
val ei = Bool(INPUT)
|
val ei = Bool(INPUT)
|
||||||
val di = Bool(INPUT)
|
val di = Bool(INPUT)
|
||||||
@ -131,38 +131,38 @@ class PCR(implicit conf: RocketConfiguration) extends Component
|
|||||||
val irq_ipi = Bool(OUTPUT)
|
val irq_ipi = Bool(OUTPUT)
|
||||||
val replay = Bool(OUTPUT)
|
val replay = Bool(OUTPUT)
|
||||||
val vecbank = Bits(OUTPUT, 8)
|
val vecbank = Bits(OUTPUT, 8)
|
||||||
val vecbankcnt = UFix(OUTPUT, 4)
|
val vecbankcnt = UInt(OUTPUT, 4)
|
||||||
val stats = Bool(OUTPUT)
|
val stats = Bool(OUTPUT)
|
||||||
val vec_appvl = UFix(INPUT, 12)
|
val vec_appvl = UInt(INPUT, 12)
|
||||||
val vec_nxregs = UFix(INPUT, 6)
|
val vec_nxregs = UInt(INPUT, 6)
|
||||||
val vec_nfregs = UFix(INPUT, 6)
|
val vec_nfregs = UInt(INPUT, 6)
|
||||||
}
|
}
|
||||||
import PCR._
|
import PCR._
|
||||||
|
|
||||||
val reg_epc = Reg{Bits(width = conf.xprlen)}
|
val reg_epc = Reg(Bits(width = conf.xprlen))
|
||||||
val reg_badvaddr = Reg{Bits(width = conf.xprlen)}
|
val reg_badvaddr = Reg(Bits(width = conf.xprlen))
|
||||||
val reg_ebase = Reg{Bits(width = conf.xprlen)}
|
val reg_ebase = Reg(Bits(width = conf.xprlen))
|
||||||
val reg_count = WideCounter(32)
|
val reg_count = WideCounter(32)
|
||||||
val reg_compare = Reg{Bits(width = 32)}
|
val reg_compare = Reg(Bits(width = 32))
|
||||||
val reg_cause = Reg{Bits(width = io.cause.getWidth)}
|
val reg_cause = Reg(Bits(width = io.cause.getWidth))
|
||||||
val reg_tohost = Reg(resetVal = Bits(0, conf.xprlen))
|
val reg_tohost = RegReset(Bits(0, conf.xprlen))
|
||||||
val reg_fromhost = Reg(resetVal = Bits(0, conf.xprlen))
|
val reg_fromhost = RegReset(Bits(0, conf.xprlen))
|
||||||
val reg_coreid = Reg{Bits(width = 16)}
|
val reg_coreid = Reg(Bits(width = 16))
|
||||||
val reg_k0 = Reg{Bits(width = conf.xprlen)}
|
val reg_k0 = Reg(Bits(width = conf.xprlen))
|
||||||
val reg_k1 = Reg{Bits(width = conf.xprlen)}
|
val reg_k1 = Reg(Bits(width = conf.xprlen))
|
||||||
val reg_ptbr = Reg{UFix(width = PADDR_BITS)}
|
val reg_ptbr = Reg(UInt(width = PADDR_BITS))
|
||||||
val reg_vecbank = Reg(resetVal = Fix(-1,8).toBits)
|
val reg_vecbank = RegReset(SInt(-1,8).toBits)
|
||||||
val reg_stats = Reg(resetVal = Bool(false))
|
val reg_stats = RegReset(Bool(false))
|
||||||
val reg_error_mode = Reg(resetVal = Bool(false))
|
val reg_error_mode = RegReset(Bool(false))
|
||||||
val reg_status = Reg{new Status} // reset down below
|
val reg_status = Reg(new Status) // reset down below
|
||||||
|
|
||||||
val r_irq_timer = Reg(resetVal = Bool(false))
|
val r_irq_timer = RegReset(Bool(false))
|
||||||
val r_irq_ipi = Reg(resetVal = Bool(true))
|
val r_irq_ipi = RegReset(Bool(true))
|
||||||
|
|
||||||
val host_pcr_req_valid = Reg{Bool()} // don't reset
|
val host_pcr_req_valid = Reg(Bool()) // don't reset
|
||||||
val host_pcr_req_fire = host_pcr_req_valid && io.rw.cmd === PCR.N
|
val host_pcr_req_fire = host_pcr_req_valid && io.rw.cmd === PCR.N
|
||||||
val host_pcr_rep_valid = Reg{Bool()} // don't reset
|
val host_pcr_rep_valid = Reg(Bool()) // don't reset
|
||||||
val host_pcr_bits = Reg{io.host.pcr_req.bits.clone}
|
val host_pcr_bits = Reg(io.host.pcr_req.bits)
|
||||||
io.host.pcr_req.ready := !host_pcr_req_valid && !host_pcr_rep_valid
|
io.host.pcr_req.ready := !host_pcr_req_valid && !host_pcr_rep_valid
|
||||||
io.host.pcr_rep.valid := host_pcr_rep_valid
|
io.host.pcr_rep.valid := host_pcr_rep_valid
|
||||||
io.host.pcr_rep.bits := host_pcr_bits.data
|
io.host.pcr_rep.bits := host_pcr_bits.data
|
||||||
@ -186,12 +186,12 @@ class PCR(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.status.ip := Cat(r_irq_timer, reg_fromhost.orR, r_irq_ipi, Bool(false),
|
io.status.ip := Cat(r_irq_timer, reg_fromhost.orR, r_irq_ipi, Bool(false),
|
||||||
Bool(false), Bool(false), Bool(false), Bool(false))
|
Bool(false), Bool(false), Bool(false), Bool(false))
|
||||||
io.ptbr_wen := wen && addr === PTBR
|
io.ptbr_wen := wen && addr === PTBR
|
||||||
io.evec := Mux(io.exception, reg_ebase, reg_epc).toUFix
|
io.evec := Mux(io.exception, reg_ebase, reg_epc).toUInt
|
||||||
io.ptbr := reg_ptbr
|
io.ptbr := reg_ptbr
|
||||||
io.host.debug.error_mode := reg_error_mode
|
io.host.debug.error_mode := reg_error_mode
|
||||||
|
|
||||||
io.vecbank := reg_vecbank
|
io.vecbank := reg_vecbank
|
||||||
var cnt = UFix(0,4)
|
var cnt = UInt(0,4)
|
||||||
for (i <- 0 until 8)
|
for (i <- 0 until 8)
|
||||||
cnt = cnt + reg_vecbank(i)
|
cnt = cnt + reg_vecbank(i)
|
||||||
io.vecbankcnt := cnt(3,0)
|
io.vecbankcnt := cnt(3,0)
|
||||||
@ -201,8 +201,8 @@ class PCR(implicit conf: RocketConfiguration) extends Component
|
|||||||
when (io.badvaddr_wen || io.vec_irq_aux_wen) {
|
when (io.badvaddr_wen || io.vec_irq_aux_wen) {
|
||||||
val wdata = Mux(io.badvaddr_wen, io.rw.wdata, io.vec_irq_aux)
|
val wdata = Mux(io.badvaddr_wen, io.rw.wdata, io.vec_irq_aux)
|
||||||
val (upper, lower) = Split(wdata, VADDR_BITS)
|
val (upper, lower) = Split(wdata, VADDR_BITS)
|
||||||
val sign = Mux(lower.toFix < Fix(0), upper.andR, upper.orR)
|
val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR)
|
||||||
reg_badvaddr := Cat(sign, lower).toFix
|
reg_badvaddr := Cat(sign, lower).toSInt
|
||||||
}
|
}
|
||||||
|
|
||||||
when (io.exception) {
|
when (io.exception) {
|
||||||
@ -212,7 +212,7 @@ class PCR(implicit conf: RocketConfiguration) extends Component
|
|||||||
reg_status.s := true
|
reg_status.s := true
|
||||||
reg_status.ps := reg_status.s
|
reg_status.ps := reg_status.s
|
||||||
reg_status.et := false
|
reg_status.et := false
|
||||||
reg_epc := io.pc.toFix
|
reg_epc := io.pc.toSInt
|
||||||
reg_cause := io.cause
|
reg_cause := io.cause
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ class PCR(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.host.ipi_req.bits := io.rw.wdata
|
io.host.ipi_req.bits := io.rw.wdata
|
||||||
io.replay := io.host.ipi_req.valid && !io.host.ipi_req.ready
|
io.replay := io.host.ipi_req.valid && !io.host.ipi_req.ready
|
||||||
|
|
||||||
when (host_pcr_req_fire && !host_pcr_bits.rw && host_pcr_bits.addr === TOHOST) { reg_tohost := UFix(0) }
|
when (host_pcr_req_fire && !host_pcr_bits.rw && host_pcr_bits.addr === TOHOST) { reg_tohost := UInt(0) }
|
||||||
|
|
||||||
val read_impl = Bits(2)
|
val read_impl = Bits(2)
|
||||||
val read_ptbr = reg_ptbr(PADDR_BITS-1,PGIDX_BITS) << PGIDX_BITS
|
val read_ptbr = reg_ptbr(PADDR_BITS-1,PGIDX_BITS) << PGIDX_BITS
|
||||||
@ -260,17 +260,17 @@ class PCR(implicit conf: RocketConfiguration) extends Component
|
|||||||
if (!conf.fpu) reg_status.ef := false
|
if (!conf.fpu) reg_status.ef := false
|
||||||
if (!conf.rvc) reg_status.ec := false
|
if (!conf.rvc) reg_status.ec := false
|
||||||
}
|
}
|
||||||
when (addr === EPC) { reg_epc := wdata(VADDR_BITS,0).toFix }
|
when (addr === EPC) { reg_epc := wdata(VADDR_BITS,0).toSInt }
|
||||||
when (addr === EVEC) { reg_ebase := wdata(VADDR_BITS-1,0).toFix }
|
when (addr === EVEC) { reg_ebase := wdata(VADDR_BITS-1,0).toSInt }
|
||||||
when (addr === COUNT) { reg_count := wdata.toUFix }
|
when (addr === COUNT) { reg_count := wdata.toUInt }
|
||||||
when (addr === COMPARE) { reg_compare := wdata(31,0).toUFix; r_irq_timer := Bool(false); }
|
when (addr === COMPARE) { reg_compare := wdata(31,0).toUInt; r_irq_timer := Bool(false); }
|
||||||
when (addr === COREID) { reg_coreid := wdata(15,0) }
|
when (addr === COREID) { reg_coreid := wdata(15,0) }
|
||||||
when (addr === FROMHOST) { when (reg_fromhost === UFix(0) || !host_pcr_req_fire) { reg_fromhost := wdata } }
|
when (addr === FROMHOST) { when (reg_fromhost === UInt(0) || !host_pcr_req_fire) { reg_fromhost := wdata } }
|
||||||
when (addr === TOHOST) { when (reg_tohost === UFix(0)) { reg_tohost := wdata } }
|
when (addr === TOHOST) { when (reg_tohost === UInt(0)) { reg_tohost := wdata } }
|
||||||
when (addr === CLR_IPI) { r_irq_ipi := wdata(0) }
|
when (addr === CLR_IPI) { r_irq_ipi := wdata(0) }
|
||||||
when (addr === K0) { reg_k0 := wdata; }
|
when (addr === K0) { reg_k0 := wdata; }
|
||||||
when (addr === K1) { reg_k1 := wdata; }
|
when (addr === K1) { reg_k1 := wdata; }
|
||||||
when (addr === PTBR) { reg_ptbr := Cat(wdata(PADDR_BITS-1, PGIDX_BITS), Bits(0, PGIDX_BITS)).toUFix; }
|
when (addr === PTBR) { reg_ptbr := Cat(wdata(PADDR_BITS-1, PGIDX_BITS), Bits(0, PGIDX_BITS)).toUInt; }
|
||||||
when (addr === VECBANK) { reg_vecbank:= wdata(7,0) }
|
when (addr === VECBANK) { reg_vecbank:= wdata(7,0) }
|
||||||
when (addr === STATS) { reg_stats := wdata(0) }
|
when (addr === STATS) { reg_stats := wdata(0) }
|
||||||
}
|
}
|
||||||
@ -278,7 +278,7 @@ class PCR(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.host.ipi_rep.ready := Bool(true)
|
io.host.ipi_rep.ready := Bool(true)
|
||||||
when (io.host.ipi_rep.valid) { r_irq_ipi := Bool(true) }
|
when (io.host.ipi_rep.valid) { r_irq_ipi := Bool(true) }
|
||||||
|
|
||||||
when (reset) {
|
when(this.getReset) {
|
||||||
reg_status.et := false
|
reg_status.et := false
|
||||||
reg_status.ef := false
|
reg_status.ef := false
|
||||||
reg_status.ev := false
|
reg_status.ev := false
|
||||||
@ -301,7 +301,7 @@ class ioReadPort(d: Int, w: Int) extends Bundle
|
|||||||
|
|
||||||
class ioWritePort(d: Int, w: Int) extends Bundle
|
class ioWritePort(d: Int, w: Int) extends Bundle
|
||||||
{
|
{
|
||||||
val addr = UFix(INPUT, log2Up(d))
|
val addr = UInt(INPUT, log2Up(d))
|
||||||
val en = Bool(INPUT)
|
val en = Bool(INPUT)
|
||||||
val data = Bits(INPUT, w)
|
val data = Bits(INPUT, w)
|
||||||
override def clone = new ioWritePort(d, w).asInstanceOf[this.type]
|
override def clone = new ioWritePort(d, w).asInstanceOf[this.type]
|
||||||
|
@ -7,15 +7,15 @@ import hwacha.Constants._
|
|||||||
|
|
||||||
class DpathVecInterfaceIO extends Bundle
|
class DpathVecInterfaceIO extends Bundle
|
||||||
{
|
{
|
||||||
val vcmdq = new FIFOIO()(Bits(width = SZ_VCMD))
|
val vcmdq = Decoupled(Bits(width = SZ_VCMD))
|
||||||
val vximm1q = new FIFOIO()(Bits(width = SZ_VIMM))
|
val vximm1q = Decoupled(Bits(width = SZ_VIMM))
|
||||||
val vximm2q = new FIFOIO()(Bits(width = SZ_VSTRIDE))
|
val vximm2q = Decoupled(Bits(width = SZ_VSTRIDE))
|
||||||
val vcntq = new FIFOIO()(Bits(width = SZ_VLEN+1))
|
val vcntq = Decoupled(Bits(width = SZ_VLEN+1))
|
||||||
|
|
||||||
val vpfcmdq = new FIFOIO()(Bits(width = SZ_VCMD))
|
val vpfcmdq = Decoupled(Bits(width = SZ_VCMD))
|
||||||
val vpfximm1q = new FIFOIO()(Bits(width = SZ_VIMM))
|
val vpfximm1q = Decoupled(Bits(width = SZ_VIMM))
|
||||||
val vpfximm2q = new FIFOIO()(Bits(width = SZ_VSTRIDE))
|
val vpfximm2q = Decoupled(Bits(width = SZ_VSTRIDE))
|
||||||
val vpfcntq = new FIFOIO()(Bits(width = SZ_VLEN))
|
val vpfcntq = Decoupled(Bits(width = SZ_VLEN))
|
||||||
|
|
||||||
val evac_addr = Bits(OUTPUT, 64)
|
val evac_addr = Bits(OUTPUT, 64)
|
||||||
val irq_aux = Bits(INPUT, 64)
|
val irq_aux = Bits(INPUT, 64)
|
||||||
@ -28,90 +28,90 @@ class DpathVecIO extends Bundle
|
|||||||
val valid = Bool(INPUT)
|
val valid = Bool(INPUT)
|
||||||
val inst = Bits(INPUT, 32)
|
val inst = Bits(INPUT, 32)
|
||||||
val vecbank = Bits(INPUT, 8)
|
val vecbank = Bits(INPUT, 8)
|
||||||
val vecbankcnt = UFix(INPUT, 4)
|
val vecbankcnt = UInt(INPUT, 4)
|
||||||
val wdata = Bits(INPUT, 64)
|
val wdata = Bits(INPUT, 64)
|
||||||
val rs2 = Bits(INPUT, 64)
|
val rs2 = Bits(INPUT, 64)
|
||||||
val wen = Bool(OUTPUT)
|
val wen = Bool(OUTPUT)
|
||||||
val irq_aux = Bits(OUTPUT, 64)
|
val irq_aux = Bits(OUTPUT, 64)
|
||||||
val appvl = UFix(OUTPUT, 12)
|
val appvl = UInt(OUTPUT, 12)
|
||||||
val nxregs = UFix(OUTPUT, 6)
|
val nxregs = UInt(OUTPUT, 6)
|
||||||
val nfregs = UFix(OUTPUT, 6)
|
val nfregs = UInt(OUTPUT, 6)
|
||||||
}
|
}
|
||||||
|
|
||||||
class rocketDpathVec extends Component
|
class rocketDpathVec extends Module
|
||||||
{
|
{
|
||||||
val io = new DpathVecIO
|
val io = new DpathVecIO
|
||||||
|
|
||||||
val nxregs_stage = Mux(io.ctrl.fn === VEC_CFG, io.wdata(5,0), io.inst(15,10))
|
val nxregs_stage = Mux(io.ctrl.fn === VEC_CFG, io.wdata(5,0), io.inst(15,10))
|
||||||
val nfregs_stage = Mux(io.ctrl.fn === VEC_CFG, io.rs2(5,0), io.inst(21,16))
|
val nfregs_stage = Mux(io.ctrl.fn === VEC_CFG, io.rs2(5,0), io.inst(21,16))
|
||||||
val nxregs = Mux(nxregs_stage(5), Bits(32), Mux(nxregs_stage === Bits(0), Bits(1), nxregs_stage)) + UFix(0,7)
|
val nxregs = Mux(nxregs_stage(5), Bits(32), Mux(nxregs_stage === Bits(0), Bits(1), nxregs_stage)) + UInt(0,7)
|
||||||
val nfregs = Mux(nfregs_stage(5), Bits(32), nfregs_stage) + UFix(0,7)
|
val nfregs = Mux(nfregs_stage(5), Bits(32), nfregs_stage) + UInt(0,7)
|
||||||
val nregs = nxregs + nfregs
|
val nregs = nxregs + nfregs
|
||||||
|
|
||||||
//val uts_per_bank = UFix(4,9)
|
//val uts_per_bank = UInt(4,9)
|
||||||
|
|
||||||
val nreg_mod_bank = MuxLookup(
|
val nreg_mod_bank = MuxLookup(
|
||||||
nregs, UFix(4,9), Array(
|
nregs, UInt(4,9), Array(
|
||||||
UFix(0,7) -> UFix(256,9),
|
UInt(0,7) -> UInt(256,9),
|
||||||
UFix(1,7) -> UFix(256,9),
|
UInt(1,7) -> UInt(256,9),
|
||||||
UFix(2,7) -> UFix(256,9),
|
UInt(2,7) -> UInt(256,9),
|
||||||
UFix(3,7) -> UFix(128,9),
|
UInt(3,7) -> UInt(128,9),
|
||||||
UFix(4,7) -> UFix(85,9),
|
UInt(4,7) -> UInt(85,9),
|
||||||
UFix(5,7) -> UFix(64,9),
|
UInt(5,7) -> UInt(64,9),
|
||||||
UFix(6,7) -> UFix(51,9),
|
UInt(6,7) -> UInt(51,9),
|
||||||
UFix(7,7) -> UFix(42,9),
|
UInt(7,7) -> UInt(42,9),
|
||||||
UFix(8,7) -> UFix(36,9),
|
UInt(8,7) -> UInt(36,9),
|
||||||
UFix(9,7) -> UFix(32,9),
|
UInt(9,7) -> UInt(32,9),
|
||||||
UFix(10,7) -> UFix(28,9),
|
UInt(10,7) -> UInt(28,9),
|
||||||
UFix(11,7) -> UFix(25,9),
|
UInt(11,7) -> UInt(25,9),
|
||||||
UFix(12,7) -> UFix(23,9),
|
UInt(12,7) -> UInt(23,9),
|
||||||
UFix(13,7) -> UFix(21,9),
|
UInt(13,7) -> UInt(21,9),
|
||||||
UFix(14,7) -> UFix(19,9),
|
UInt(14,7) -> UInt(19,9),
|
||||||
UFix(15,7) -> UFix(18,9),
|
UInt(15,7) -> UInt(18,9),
|
||||||
UFix(16,7) -> UFix(17,9),
|
UInt(16,7) -> UInt(17,9),
|
||||||
UFix(17,7) -> UFix(16,9),
|
UInt(17,7) -> UInt(16,9),
|
||||||
UFix(18,7) -> UFix(15,9),
|
UInt(18,7) -> UInt(15,9),
|
||||||
UFix(19,7) -> UFix(14,9),
|
UInt(19,7) -> UInt(14,9),
|
||||||
UFix(20,7) -> UFix(13,9),
|
UInt(20,7) -> UInt(13,9),
|
||||||
UFix(21,7) -> UFix(12,9),
|
UInt(21,7) -> UInt(12,9),
|
||||||
UFix(22,7) -> UFix(12,9),
|
UInt(22,7) -> UInt(12,9),
|
||||||
UFix(23,7) -> UFix(11,9),
|
UInt(23,7) -> UInt(11,9),
|
||||||
UFix(24,7) -> UFix(11,9),
|
UInt(24,7) -> UInt(11,9),
|
||||||
UFix(25,7) -> UFix(10,9),
|
UInt(25,7) -> UInt(10,9),
|
||||||
UFix(26,7) -> UFix(10,9),
|
UInt(26,7) -> UInt(10,9),
|
||||||
UFix(27,7) -> UFix(9,9),
|
UInt(27,7) -> UInt(9,9),
|
||||||
UFix(28,7) -> UFix(9,9),
|
UInt(28,7) -> UInt(9,9),
|
||||||
UFix(29,7) -> UFix(9,9),
|
UInt(29,7) -> UInt(9,9),
|
||||||
UFix(30,7) -> UFix(8,9),
|
UInt(30,7) -> UInt(8,9),
|
||||||
UFix(31,7) -> UFix(8,9),
|
UInt(31,7) -> UInt(8,9),
|
||||||
UFix(32,7) -> UFix(8,9),
|
UInt(32,7) -> UInt(8,9),
|
||||||
UFix(33,7) -> UFix(8,9),
|
UInt(33,7) -> UInt(8,9),
|
||||||
UFix(34,7) -> UFix(7,9),
|
UInt(34,7) -> UInt(7,9),
|
||||||
UFix(35,7) -> UFix(7,9),
|
UInt(35,7) -> UInt(7,9),
|
||||||
UFix(36,7) -> UFix(7,9),
|
UInt(36,7) -> UInt(7,9),
|
||||||
UFix(37,7) -> UFix(7,9),
|
UInt(37,7) -> UInt(7,9),
|
||||||
UFix(38,7) -> UFix(6,9),
|
UInt(38,7) -> UInt(6,9),
|
||||||
UFix(39,7) -> UFix(6,9),
|
UInt(39,7) -> UInt(6,9),
|
||||||
UFix(40,7) -> UFix(6,9),
|
UInt(40,7) -> UInt(6,9),
|
||||||
UFix(41,7) -> UFix(6,9),
|
UInt(41,7) -> UInt(6,9),
|
||||||
UFix(42,7) -> UFix(6,9),
|
UInt(42,7) -> UInt(6,9),
|
||||||
UFix(43,7) -> UFix(6,9),
|
UInt(43,7) -> UInt(6,9),
|
||||||
UFix(44,7) -> UFix(5,9),
|
UInt(44,7) -> UInt(5,9),
|
||||||
UFix(45,7) -> UFix(5,9),
|
UInt(45,7) -> UInt(5,9),
|
||||||
UFix(46,7) -> UFix(5,9),
|
UInt(46,7) -> UInt(5,9),
|
||||||
UFix(47,7) -> UFix(5,9),
|
UInt(47,7) -> UInt(5,9),
|
||||||
UFix(48,7) -> UFix(5,9),
|
UInt(48,7) -> UInt(5,9),
|
||||||
UFix(49,7) -> UFix(5,9),
|
UInt(49,7) -> UInt(5,9),
|
||||||
UFix(50,7) -> UFix(5,9),
|
UInt(50,7) -> UInt(5,9),
|
||||||
UFix(51,7) -> UFix(5,9),
|
UInt(51,7) -> UInt(5,9),
|
||||||
UFix(52,7) -> UFix(5,9)
|
UInt(52,7) -> UInt(5,9)
|
||||||
))
|
))
|
||||||
|
|
||||||
val max_threads = UFix(WIDTH_BMASK)
|
val max_threads = UInt(WIDTH_BMASK)
|
||||||
val uts_per_bank = Mux(Bool(HAVE_PVFB) & nreg_mod_bank > max_threads, max_threads, nreg_mod_bank)
|
val uts_per_bank = Mux(Bool(HAVE_PVFB) & nreg_mod_bank > max_threads, max_threads, nreg_mod_bank)
|
||||||
|
|
||||||
val reg_hwvl = Reg(resetVal = UFix(32, 12))
|
val reg_hwvl = RegReset(UInt(32, 12))
|
||||||
val reg_appvl0 = Reg(resetVal = Bool(true))
|
val reg_appvl0 = RegReset(Bool(true))
|
||||||
val hwvl_vcfg = (uts_per_bank * io.vecbankcnt)(11,0)
|
val hwvl_vcfg = (uts_per_bank * io.vecbankcnt)(11,0)
|
||||||
|
|
||||||
val hwvl =
|
val hwvl =
|
||||||
@ -119,13 +119,13 @@ class rocketDpathVec extends Component
|
|||||||
reg_hwvl)
|
reg_hwvl)
|
||||||
|
|
||||||
val appvl =
|
val appvl =
|
||||||
Mux(io.ctrl.fn === VEC_CFG, UFix(0),
|
Mux(io.ctrl.fn === VEC_CFG, UInt(0),
|
||||||
Mux(io.wdata(11,0) < hwvl, io.wdata(11,0).toUFix,
|
Mux(io.wdata(11,0) < hwvl, io.wdata(11,0).toUInt,
|
||||||
hwvl.toUFix))
|
hwvl.toUInt))
|
||||||
|
|
||||||
val reg_nxregs = Reg(resetVal = UFix(32, 6))
|
val reg_nxregs = RegReset(UInt(32, 6))
|
||||||
val reg_nfregs = Reg(resetVal = UFix(32, 6))
|
val reg_nfregs = RegReset(UInt(32, 6))
|
||||||
val reg_appvl = Reg(resetVal = UFix(0, 12))
|
val reg_appvl = RegReset(UInt(0, 12))
|
||||||
|
|
||||||
when (io.valid)
|
when (io.valid)
|
||||||
{
|
{
|
||||||
@ -148,7 +148,7 @@ class rocketDpathVec extends Component
|
|||||||
io.nxregs := reg_nxregs
|
io.nxregs := reg_nxregs
|
||||||
io.nfregs := reg_nfregs
|
io.nfregs := reg_nfregs
|
||||||
|
|
||||||
val appvlm1 = appvl - UFix(1)
|
val appvlm1 = appvl - UInt(1)
|
||||||
val waddr = io.inst(31,27)
|
val waddr = io.inst(31,27)
|
||||||
val raddr1 = io.inst(26,22)
|
val raddr1 = io.inst(26,22)
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ class SECCode extends Code
|
|||||||
} else
|
} else
|
||||||
x(mapping(i))
|
x(mapping(i))
|
||||||
}
|
}
|
||||||
Vec(y){Bool()}.toBits
|
Vec(y).toBits
|
||||||
}
|
}
|
||||||
def decode(y: Bits) = new Decoding {
|
def decode(y: Bits) = new Decoding {
|
||||||
val n = y.getWidth
|
val n = y.getWidth
|
||||||
@ -75,11 +75,11 @@ class SECCode extends Code
|
|||||||
yield y(j-1)
|
yield y(j-1)
|
||||||
r reduce (_^_)
|
r reduce (_^_)
|
||||||
}
|
}
|
||||||
val s = Vec(syndrome){Bool()}.toBits
|
val s = Vec(syndrome).toBits
|
||||||
|
|
||||||
private def swizzle(z: Bits) = Vec((1 to n).filter(i => !isPow2(i)).map(i => z(i-1))){Bool()}.toBits
|
private def swizzle(z: Bits) = Vec((1 to n).filter(i => !isPow2(i)).map(i => z(i-1))).toBits
|
||||||
def uncorrected = swizzle(y)
|
def uncorrected = swizzle(y)
|
||||||
def corrected = swizzle(((y << 1) ^ UFixToOH(s)) >> 1)
|
def corrected = swizzle(((y.toUInt << 1) ^ UIntToOH(s)) >> 1)
|
||||||
def correctable = s.orR
|
def correctable = s.orR
|
||||||
def uncorrectable = Bool(false)
|
def uncorrectable = Bool(false)
|
||||||
}
|
}
|
||||||
@ -109,12 +109,12 @@ object ErrGen
|
|||||||
// generate a 1-bit error with approximate probability 2^-f
|
// generate a 1-bit error with approximate probability 2^-f
|
||||||
def apply(width: Int, f: Int): Bits = {
|
def apply(width: Int, f: Int): Bits = {
|
||||||
require(width > 0 && f >= 0 && log2Up(width) + f <= 16)
|
require(width > 0 && f >= 0 && log2Up(width) + f <= 16)
|
||||||
UFixToOH(LFSR16()(log2Up(width)+f-1,0))(width-1,0)
|
UIntToOH(LFSR16()(log2Up(width)+f-1,0))(width-1,0)
|
||||||
}
|
}
|
||||||
def apply(x: Bits, f: Int): Bits = x ^ apply(x.getWidth, f)
|
def apply(x: Bits, f: Int): Bits = x ^ apply(x.getWidth, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
class SECDEDTest extends Component
|
class SECDEDTest extends Module
|
||||||
{
|
{
|
||||||
val code = new SECDEDCode
|
val code = new SECDEDCode
|
||||||
val k = 4
|
val k = 4
|
||||||
|
@ -63,7 +63,7 @@ class FPUCtrlSigs extends Bundle
|
|||||||
val wrfsr = Bool()
|
val wrfsr = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class FPUDecoder extends Component
|
class FPUDecoder extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val inst = Bits(INPUT, 32)
|
val inst = Bits(INPUT, 32)
|
||||||
@ -160,7 +160,7 @@ class DpathFPUIO extends Bundle {
|
|||||||
|
|
||||||
val dmem_resp_val = Bool(OUTPUT)
|
val dmem_resp_val = Bool(OUTPUT)
|
||||||
val dmem_resp_type = Bits(OUTPUT, 3)
|
val dmem_resp_type = Bits(OUTPUT, 3)
|
||||||
val dmem_resp_tag = UFix(OUTPUT, 5)
|
val dmem_resp_tag = UInt(OUTPUT, 5)
|
||||||
val dmem_resp_data = Bits(OUTPUT, 64)
|
val dmem_resp_data = Bits(OUTPUT, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,24 +173,24 @@ class CtrlFPUIO extends Bundle {
|
|||||||
val dec = new FPUCtrlSigs().asInput
|
val dec = new FPUCtrlSigs().asInput
|
||||||
val sboard_set = Bool(INPUT)
|
val sboard_set = Bool(INPUT)
|
||||||
val sboard_clr = Bool(INPUT)
|
val sboard_clr = Bool(INPUT)
|
||||||
val sboard_clra = UFix(INPUT, 5)
|
val sboard_clra = UInt(INPUT, 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
object RegEn
|
object RegEn
|
||||||
{
|
{
|
||||||
def apply[T <: Data](data: T, en: Bool) = {
|
def apply[T <: Data](data: T, en: Bool) = {
|
||||||
val r = Reg() { data.clone }
|
val r = Reg(data)
|
||||||
when (en) { r := data }
|
when (en) { r := data }
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
def apply[T <: Bits](data: T, en: Bool, resetVal: T) = {
|
def apply[T <: Bits](data: T, en: Bool, resetVal: T) = {
|
||||||
val r = Reg(resetVal = resetVal) { data.clone }
|
val r = RegReset(resetVal)
|
||||||
when (en) { r := data }
|
when (en) { r := data }
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FPToInt extends Component
|
class FPToInt extends Module
|
||||||
{
|
{
|
||||||
class Input extends Bundle {
|
class Input extends Bundle {
|
||||||
val single = Bool()
|
val single = Bool()
|
||||||
@ -202,8 +202,8 @@ class FPToInt extends Component
|
|||||||
override def clone = new Input().asInstanceOf[this.type]
|
override def clone = new Input().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = new PipeIO()(new Input).flip
|
val in = Valid(new Input).flip
|
||||||
val out = new PipeIO()(new Bundle {
|
val out = Valid(new Bundle {
|
||||||
val lt = Bool()
|
val lt = Bool()
|
||||||
val store = Bits(width = 64)
|
val store = Bits(width = 64)
|
||||||
val toint = Bits(width = 64)
|
val toint = Bits(width = 64)
|
||||||
@ -211,10 +211,10 @@ class FPToInt extends Component
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
val in = Reg() { new Input }
|
val in = Reg(new Input)
|
||||||
val valid = Reg(io.in.valid)
|
val valid = RegUpdate(io.in.valid)
|
||||||
when (io.in.valid) {
|
when (io.in.valid) {
|
||||||
def upconvert(x: Bits) = hardfloat.recodedFloatNToRecodedFloatM(x, Bits(0), 23, 9, 52, 12)._1
|
def upconvert(x: UInt) = hardfloat.recodedFloatNToRecodedFloatM(x, Bits(0), 23, 9, 52, 12)._1
|
||||||
when (io.in.bits.cmd === FCMD_STORE) {
|
when (io.in.bits.cmd === FCMD_STORE) {
|
||||||
in.in1 := io.in.bits.in2
|
in.in1 := io.in.bits.in2
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
@ -231,11 +231,11 @@ class FPToInt extends Component
|
|||||||
val unrec_s = hardfloat.recodedFloatNToFloatN(in.in1, 23, 9)
|
val unrec_s = hardfloat.recodedFloatNToFloatN(in.in1, 23, 9)
|
||||||
val unrec_d = hardfloat.recodedFloatNToFloatN(in.in1, 52, 12)
|
val unrec_d = hardfloat.recodedFloatNToFloatN(in.in1, 52, 12)
|
||||||
|
|
||||||
val dcmp = new hardfloat.recodedFloatNCompare(52, 12)
|
val dcmp = Module(new hardfloat.recodedFloatNCompare(52, 12))
|
||||||
dcmp.io.a := in.in1
|
dcmp.io.a := in.in1
|
||||||
dcmp.io.b := in.in2
|
dcmp.io.b := in.in2
|
||||||
val dcmp_out = (in.cmd & Cat(dcmp.io.a_lt_b, dcmp.io.a_eq_b)).orR
|
val dcmp_out = (in.cmd & Cat(dcmp.io.a_lt_b, dcmp.io.a_eq_b)).orR
|
||||||
val dcmp_exc = (in.cmd & Cat(dcmp.io.a_lt_b_invalid, dcmp.io.a_eq_b_invalid)).orR << UFix(4)
|
val dcmp_exc = (in.cmd & Cat(dcmp.io.a_lt_b_invalid, dcmp.io.a_eq_b_invalid)).orR << UInt(4)
|
||||||
|
|
||||||
val d2i = hardfloat.recodedFloatNToAny(in.in1, in.rm, ~in.cmd(1,0), 52, 12, 64)
|
val d2i = hardfloat.recodedFloatNToAny(in.in1, in.rm, ~in.cmd(1,0), 52, 12, 64)
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ class FPResult extends Bundle
|
|||||||
val exc = Bits(width = 5)
|
val exc = Bits(width = 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IntToFP(val latency: Int) extends Component
|
class IntToFP(val latency: Int) extends Module
|
||||||
{
|
{
|
||||||
class Input extends Bundle {
|
class Input extends Bundle {
|
||||||
val single = Bool()
|
val single = Bool()
|
||||||
@ -279,8 +279,8 @@ class IntToFP(val latency: Int) extends Component
|
|||||||
override def clone = new Input().asInstanceOf[this.type]
|
override def clone = new Input().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = new PipeIO()(new Input).flip
|
val in = Valid(new Input).flip
|
||||||
val out = new PipeIO()(new FPResult)
|
val out = Valid(new FPResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
val in = Pipe(io.in)
|
val in = Pipe(io.in)
|
||||||
@ -296,7 +296,7 @@ class IntToFP(val latency: Int) extends Component
|
|||||||
in.bits.cmd === FCMD_CVT_FMT_L || in.bits.cmd === FCMD_CVT_FMT_LU) {
|
in.bits.cmd === FCMD_CVT_FMT_L || in.bits.cmd === FCMD_CVT_FMT_LU) {
|
||||||
when (in.bits.single) {
|
when (in.bits.single) {
|
||||||
val u = hardfloat.anyToRecodedFloatN(in.bits.data, in.bits.rm, ~in.bits.cmd(1,0), 23, 9, 64)
|
val u = hardfloat.anyToRecodedFloatN(in.bits.data, in.bits.rm, ~in.bits.cmd(1,0), 23, 9, 64)
|
||||||
mux.data := Cat(Fix(-1, 32), u._1)
|
mux.data := Cat(SInt(-1, 32), u._1)
|
||||||
mux.exc := u._2
|
mux.exc := u._2
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
val u = hardfloat.anyToRecodedFloatN(in.bits.data, in.bits.rm, ~in.bits.cmd(1,0), 52, 12, 64)
|
val u = hardfloat.anyToRecodedFloatN(in.bits.data, in.bits.rm, ~in.bits.cmd(1,0), 52, 12, 64)
|
||||||
@ -308,7 +308,7 @@ class IntToFP(val latency: Int) extends Component
|
|||||||
io.out <> Pipe(in.valid, mux, latency-1)
|
io.out <> Pipe(in.valid, mux, latency-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FPToFP(val latency: Int) extends Component
|
class FPToFP(val latency: Int) extends Module
|
||||||
{
|
{
|
||||||
class Input extends Bundle {
|
class Input extends Bundle {
|
||||||
val single = Bool()
|
val single = Bool()
|
||||||
@ -319,8 +319,8 @@ class FPToFP(val latency: Int) extends Component
|
|||||||
override def clone = new Input().asInstanceOf[this.type]
|
override def clone = new Input().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = new PipeIO()(new Input).flip
|
val in = Valid(new Input).flip
|
||||||
val out = new PipeIO()(new FPResult)
|
val out = Valid(new FPResult)
|
||||||
val lt = Bool(INPUT) // from FPToInt
|
val lt = Bool(INPUT) // from FPToInt
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,7 +356,7 @@ class FPToFP(val latency: Int) extends Component
|
|||||||
}
|
}
|
||||||
when (in.bits.cmd === FCMD_CVT_FMT_S || in.bits.cmd === FCMD_CVT_FMT_D) {
|
when (in.bits.cmd === FCMD_CVT_FMT_S || in.bits.cmd === FCMD_CVT_FMT_D) {
|
||||||
when (in.bits.single) {
|
when (in.bits.single) {
|
||||||
mux.data := Cat(Fix(-1, 32), d2s._1)
|
mux.data := Cat(SInt(-1, 32), d2s._1)
|
||||||
mux.exc := d2s._2
|
mux.exc := d2s._2
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
mux.data := s2d._1
|
mux.data := s2d._1
|
||||||
@ -378,15 +378,15 @@ class ioFMA(width: Int) extends Bundle {
|
|||||||
val exc = Bits(OUTPUT, 5)
|
val exc = Bits(OUTPUT, 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FPUSFMAPipe(val latency: Int) extends Component
|
class FPUSFMAPipe(val latency: Int) extends Module
|
||||||
{
|
{
|
||||||
val io = new ioFMA(33)
|
val io = new ioFMA(33)
|
||||||
|
|
||||||
val cmd = Reg() { Bits() }
|
val cmd = Reg(Bits())
|
||||||
val rm = Reg() { Bits() }
|
val rm = Reg(Bits())
|
||||||
val in1 = Reg() { Bits() }
|
val in1 = Reg(Bits())
|
||||||
val in2 = Reg() { Bits() }
|
val in2 = Reg(Bits())
|
||||||
val in3 = Reg() { Bits() }
|
val in3 = Reg(Bits())
|
||||||
|
|
||||||
val cmd_fma = io.cmd === FCMD_MADD || io.cmd === FCMD_MSUB ||
|
val cmd_fma = io.cmd === FCMD_MADD || io.cmd === FCMD_MSUB ||
|
||||||
io.cmd === FCMD_NMADD || io.cmd === FCMD_NMSUB
|
io.cmd === FCMD_NMADD || io.cmd === FCMD_NMSUB
|
||||||
@ -395,7 +395,7 @@ class FPUSFMAPipe(val latency: Int) extends Component
|
|||||||
val one = Bits("h80000000")
|
val one = Bits("h80000000")
|
||||||
val zero = Cat(io.in1(32) ^ io.in2(32), Bits(0, 32))
|
val zero = Cat(io.in1(32) ^ io.in2(32), Bits(0, 32))
|
||||||
|
|
||||||
val valid = Reg(io.valid)
|
val valid = RegUpdate(io.valid)
|
||||||
when (io.valid) {
|
when (io.valid) {
|
||||||
cmd := Cat(io.cmd(1) & (cmd_fma || cmd_addsub), io.cmd(0))
|
cmd := Cat(io.cmd(1) & (cmd_fma || cmd_addsub), io.cmd(0))
|
||||||
rm := io.rm
|
rm := io.rm
|
||||||
@ -404,7 +404,7 @@ class FPUSFMAPipe(val latency: Int) extends Component
|
|||||||
in3 := Mux(cmd_fma, io.in3, Mux(cmd_addsub, io.in2, zero))
|
in3 := Mux(cmd_fma, io.in3, Mux(cmd_addsub, io.in2, zero))
|
||||||
}
|
}
|
||||||
|
|
||||||
val fma = new hardfloat.mulAddSubRecodedFloatN(23, 9)
|
val fma = Module(new hardfloat.mulAddSubRecodedFloatN(23, 9))
|
||||||
fma.io.op := cmd
|
fma.io.op := cmd
|
||||||
fma.io.roundingMode := rm
|
fma.io.roundingMode := rm
|
||||||
fma.io.a := in1
|
fma.io.a := in1
|
||||||
@ -415,15 +415,15 @@ class FPUSFMAPipe(val latency: Int) extends Component
|
|||||||
io.exc := Pipe(valid, fma.io.exceptionFlags, latency-1).bits
|
io.exc := Pipe(valid, fma.io.exceptionFlags, latency-1).bits
|
||||||
}
|
}
|
||||||
|
|
||||||
class FPUDFMAPipe(val latency: Int) extends Component
|
class FPUDFMAPipe(val latency: Int) extends Module
|
||||||
{
|
{
|
||||||
val io = new ioFMA(65)
|
val io = new ioFMA(65)
|
||||||
|
|
||||||
val cmd = Reg() { Bits() }
|
val cmd = Reg(Bits())
|
||||||
val rm = Reg() { Bits() }
|
val rm = Reg(Bits())
|
||||||
val in1 = Reg() { Bits() }
|
val in1 = Reg(Bits())
|
||||||
val in2 = Reg() { Bits() }
|
val in2 = Reg(Bits())
|
||||||
val in3 = Reg() { Bits() }
|
val in3 = Reg(Bits())
|
||||||
|
|
||||||
val cmd_fma = io.cmd === FCMD_MADD || io.cmd === FCMD_MSUB ||
|
val cmd_fma = io.cmd === FCMD_MADD || io.cmd === FCMD_MSUB ||
|
||||||
io.cmd === FCMD_NMADD || io.cmd === FCMD_NMSUB
|
io.cmd === FCMD_NMADD || io.cmd === FCMD_NMSUB
|
||||||
@ -432,7 +432,7 @@ class FPUDFMAPipe(val latency: Int) extends Component
|
|||||||
val one = Bits("h8000000000000000")
|
val one = Bits("h8000000000000000")
|
||||||
val zero = Cat(io.in1(64) ^ io.in2(64), Bits(0, 64))
|
val zero = Cat(io.in1(64) ^ io.in2(64), Bits(0, 64))
|
||||||
|
|
||||||
val valid = Reg(io.valid)
|
val valid = RegUpdate(io.valid)
|
||||||
when (io.valid) {
|
when (io.valid) {
|
||||||
cmd := Cat(io.cmd(1) & (cmd_fma || cmd_addsub), io.cmd(0))
|
cmd := Cat(io.cmd(1) & (cmd_fma || cmd_addsub), io.cmd(0))
|
||||||
rm := io.rm
|
rm := io.rm
|
||||||
@ -441,7 +441,7 @@ class FPUDFMAPipe(val latency: Int) extends Component
|
|||||||
in3 := Mux(cmd_fma, io.in3, Mux(cmd_addsub, io.in2, zero))
|
in3 := Mux(cmd_fma, io.in3, Mux(cmd_addsub, io.in2, zero))
|
||||||
}
|
}
|
||||||
|
|
||||||
val fma = new hardfloat.mulAddSubRecodedFloatN(52, 12)
|
val fma = Module(new hardfloat.mulAddSubRecodedFloatN(52, 12))
|
||||||
fma.io.op := cmd
|
fma.io.op := cmd
|
||||||
fma.io.roundingMode := rm
|
fma.io.roundingMode := rm
|
||||||
fma.io.a := in1
|
fma.io.a := in1
|
||||||
@ -452,7 +452,7 @@ class FPUDFMAPipe(val latency: Int) extends Component
|
|||||||
io.exc := Pipe(valid, fma.io.exceptionFlags, latency-1).bits
|
io.exc := Pipe(valid, fma.io.exceptionFlags, latency-1).bits
|
||||||
}
|
}
|
||||||
|
|
||||||
class FPU(sfma_latency: Int, dfma_latency: Int) extends Component
|
class FPU(sfma_latency: Int, dfma_latency: Int) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val ctrl = (new CtrlFPUIO).flip
|
val ctrl = (new CtrlFPUIO).flip
|
||||||
@ -461,16 +461,16 @@ class FPU(sfma_latency: Int, dfma_latency: Int) extends Component
|
|||||||
val dfma = new ioFMA(65)
|
val dfma = new ioFMA(65)
|
||||||
}
|
}
|
||||||
|
|
||||||
val ex_reg_inst = Reg() { Bits() }
|
val ex_reg_inst = Reg(Bits())
|
||||||
when (io.ctrl.valid) {
|
when (io.ctrl.valid) {
|
||||||
ex_reg_inst := io.dpath.inst
|
ex_reg_inst := io.dpath.inst
|
||||||
}
|
}
|
||||||
val ex_reg_valid = Reg(io.ctrl.valid, Bool(false))
|
val ex_reg_valid = Reg(update=io.ctrl.valid, reset=Bool(false))
|
||||||
val mem_reg_valid = Reg(ex_reg_valid && !io.ctrl.killx, resetVal = Bool(false))
|
val mem_reg_valid = Reg(update=ex_reg_valid && !io.ctrl.killx, reset=Bool(false))
|
||||||
val killm = io.ctrl.killm || io.ctrl.nack_mem
|
val killm = io.ctrl.killm || io.ctrl.nack_mem
|
||||||
val wb_reg_valid = Reg(mem_reg_valid && !killm, resetVal = Bool(false))
|
val wb_reg_valid = Reg(update=mem_reg_valid && !killm, reset=Bool(false))
|
||||||
|
|
||||||
val fp_decoder = new FPUDecoder
|
val fp_decoder = Module(new FPUDecoder)
|
||||||
fp_decoder.io.inst := io.dpath.inst
|
fp_decoder.io.inst := io.dpath.inst
|
||||||
|
|
||||||
val ctrl = RegEn(fp_decoder.io.sigs, io.ctrl.valid)
|
val ctrl = RegEn(fp_decoder.io.sigs, io.ctrl.valid)
|
||||||
@ -478,19 +478,19 @@ class FPU(sfma_latency: Int, dfma_latency: Int) extends Component
|
|||||||
val wb_ctrl = RegEn(mem_ctrl, mem_reg_valid)
|
val wb_ctrl = RegEn(mem_ctrl, mem_reg_valid)
|
||||||
|
|
||||||
// load response
|
// load response
|
||||||
val load_wb = Reg(io.dpath.dmem_resp_val)
|
val load_wb = RegUpdate(io.dpath.dmem_resp_val)
|
||||||
val load_wb_single = RegEn(io.dpath.dmem_resp_type === MT_W || io.dpath.dmem_resp_type === MT_WU, io.dpath.dmem_resp_val)
|
val load_wb_single = RegEn(io.dpath.dmem_resp_type === MT_W || io.dpath.dmem_resp_type === MT_WU, io.dpath.dmem_resp_val)
|
||||||
val load_wb_data = RegEn(io.dpath.dmem_resp_data, io.dpath.dmem_resp_val)
|
val load_wb_data = RegEn(io.dpath.dmem_resp_data, io.dpath.dmem_resp_val)
|
||||||
val load_wb_tag = RegEn(io.dpath.dmem_resp_tag, io.dpath.dmem_resp_val)
|
val load_wb_tag = RegEn(io.dpath.dmem_resp_tag, io.dpath.dmem_resp_val)
|
||||||
val rec_s = hardfloat.floatNToRecodedFloatN(load_wb_data, 23, 9)
|
val rec_s = hardfloat.floatNToRecodedFloatN(load_wb_data, 23, 9)
|
||||||
val rec_d = hardfloat.floatNToRecodedFloatN(load_wb_data, 52, 12)
|
val rec_d = hardfloat.floatNToRecodedFloatN(load_wb_data, 52, 12)
|
||||||
val load_wb_data_recoded = Mux(load_wb_single, Cat(Fix(-1), rec_s), rec_d)
|
val load_wb_data_recoded = Mux(load_wb_single, Cat(SInt(-1), rec_s), rec_d)
|
||||||
|
|
||||||
val fsr_rm = Reg() { Bits(width = 3) }
|
val fsr_rm = Reg(Bits(width = 3))
|
||||||
val fsr_exc = Reg() { Bits(width = 5) }
|
val fsr_exc = Reg(Bits(width = 5))
|
||||||
|
|
||||||
// regfile
|
// regfile
|
||||||
val regfile = Mem(32) { Bits(width = 65) }
|
val regfile = Mem(Bits(width = 65), 32)
|
||||||
when (load_wb) { regfile(load_wb_tag) := load_wb_data_recoded }
|
when (load_wb) { regfile(load_wb_tag) := load_wb_data_recoded }
|
||||||
|
|
||||||
val ex_rs1 = regfile(ex_reg_inst(26,22))
|
val ex_rs1 = regfile(ex_reg_inst(26,22))
|
||||||
@ -498,7 +498,7 @@ class FPU(sfma_latency: Int, dfma_latency: Int) extends Component
|
|||||||
val ex_rs3 = regfile(ex_reg_inst(16,12))
|
val ex_rs3 = regfile(ex_reg_inst(16,12))
|
||||||
val ex_rm = Mux(ex_reg_inst(11,9) === Bits(7), fsr_rm, ex_reg_inst(11,9))
|
val ex_rm = Mux(ex_reg_inst(11,9) === Bits(7), fsr_rm, ex_reg_inst(11,9))
|
||||||
|
|
||||||
val fpiu = new FPToInt
|
val fpiu = Module(new FPToInt)
|
||||||
fpiu.io.in.valid := ex_reg_valid && ctrl.toint
|
fpiu.io.in.valid := ex_reg_valid && ctrl.toint
|
||||||
fpiu.io.in.bits := ctrl
|
fpiu.io.in.bits := ctrl
|
||||||
fpiu.io.in.bits.rm := ex_rm
|
fpiu.io.in.bits.rm := ex_rm
|
||||||
@ -509,12 +509,12 @@ class FPU(sfma_latency: Int, dfma_latency: Int) extends Component
|
|||||||
io.dpath.store_data := fpiu.io.out.bits.store
|
io.dpath.store_data := fpiu.io.out.bits.store
|
||||||
io.dpath.toint_data := fpiu.io.out.bits.toint
|
io.dpath.toint_data := fpiu.io.out.bits.toint
|
||||||
|
|
||||||
val ifpu = new IntToFP(3)
|
val ifpu = Module(new IntToFP(3))
|
||||||
ifpu.io.in.valid := ex_reg_valid && ctrl.fromint
|
ifpu.io.in.valid := ex_reg_valid && ctrl.fromint
|
||||||
ifpu.io.in.bits := ctrl
|
ifpu.io.in.bits := ctrl
|
||||||
ifpu.io.in.bits.rm := ex_rm
|
ifpu.io.in.bits.rm := ex_rm
|
||||||
ifpu.io.in.bits.data := io.dpath.fromint_data
|
ifpu.io.in.bits.data := io.dpath.fromint_data
|
||||||
val fpmu = new FPToFP(2)
|
val fpmu = Module(new FPToFP(2))
|
||||||
fpmu.io.in.valid := ex_reg_valid && ctrl.fastpipe
|
fpmu.io.in.valid := ex_reg_valid && ctrl.fastpipe
|
||||||
fpmu.io.in.bits := ctrl
|
fpmu.io.in.bits := ctrl
|
||||||
fpmu.io.in.bits.rm := ex_rm
|
fpmu.io.in.bits.rm := ex_rm
|
||||||
@ -525,7 +525,7 @@ class FPU(sfma_latency: Int, dfma_latency: Int) extends Component
|
|||||||
val cmd_fma = mem_ctrl.cmd === FCMD_MADD || mem_ctrl.cmd === FCMD_MSUB ||
|
val cmd_fma = mem_ctrl.cmd === FCMD_MADD || mem_ctrl.cmd === FCMD_MSUB ||
|
||||||
mem_ctrl.cmd === FCMD_NMADD || mem_ctrl.cmd === FCMD_NMSUB
|
mem_ctrl.cmd === FCMD_NMADD || mem_ctrl.cmd === FCMD_NMSUB
|
||||||
val cmd_addsub = mem_ctrl.cmd === FCMD_ADD || mem_ctrl.cmd === FCMD_SUB
|
val cmd_addsub = mem_ctrl.cmd === FCMD_ADD || mem_ctrl.cmd === FCMD_SUB
|
||||||
val sfma = new FPUSFMAPipe(sfma_latency)
|
val sfma = Module(new FPUSFMAPipe(sfma_latency))
|
||||||
sfma.io.valid := io.sfma.valid || ex_reg_valid && ctrl.fma && ctrl.single
|
sfma.io.valid := io.sfma.valid || ex_reg_valid && ctrl.fma && ctrl.single
|
||||||
sfma.io.in1 := Mux(io.sfma.valid, io.sfma.in1, ex_rs1)
|
sfma.io.in1 := Mux(io.sfma.valid, io.sfma.in1, ex_rs1)
|
||||||
sfma.io.in2 := Mux(io.sfma.valid, io.sfma.in2, ex_rs2)
|
sfma.io.in2 := Mux(io.sfma.valid, io.sfma.in2, ex_rs2)
|
||||||
@ -535,7 +535,7 @@ class FPU(sfma_latency: Int, dfma_latency: Int) extends Component
|
|||||||
io.sfma.out := sfma.io.out
|
io.sfma.out := sfma.io.out
|
||||||
io.sfma.exc := sfma.io.exc
|
io.sfma.exc := sfma.io.exc
|
||||||
|
|
||||||
val dfma = new FPUDFMAPipe(dfma_latency)
|
val dfma = Module(new FPUDFMAPipe(dfma_latency))
|
||||||
dfma.io.valid := io.dfma.valid || ex_reg_valid && ctrl.fma && !ctrl.single
|
dfma.io.valid := io.dfma.valid || ex_reg_valid && ctrl.fma && !ctrl.single
|
||||||
dfma.io.in1 := Mux(io.dfma.valid, io.dfma.in1, ex_rs1)
|
dfma.io.in1 := Mux(io.dfma.valid, io.dfma.in1, ex_rs1)
|
||||||
dfma.io.in2 := Mux(io.dfma.valid, io.dfma.in2, ex_rs2)
|
dfma.io.in2 := Mux(io.dfma.valid, io.dfma.in2, ex_rs2)
|
||||||
@ -546,7 +546,7 @@ class FPU(sfma_latency: Int, dfma_latency: Int) extends Component
|
|||||||
io.dfma.exc := dfma.io.exc
|
io.dfma.exc := dfma.io.exc
|
||||||
|
|
||||||
// writeback arbitration
|
// writeback arbitration
|
||||||
case class Pipe(p: Component, lat: Int, cond: (FPUCtrlSigs) => Bool, wdata: Bits, wexc: Bits)
|
case class Pipe(p: Module, lat: Int, cond: (FPUCtrlSigs) => Bool, wdata: Bits, wexc: Bits)
|
||||||
val pipes = List(
|
val pipes = List(
|
||||||
Pipe(fpmu, fpmu.latency, (c: FPUCtrlSigs) => c.fastpipe, fpmu.io.out.bits.data, fpmu.io.out.bits.exc),
|
Pipe(fpmu, fpmu.latency, (c: FPUCtrlSigs) => c.fastpipe, fpmu.io.out.bits.data, fpmu.io.out.bits.exc),
|
||||||
Pipe(ifpu, ifpu.latency, (c: FPUCtrlSigs) => c.fromint, ifpu.io.out.bits.data, ifpu.io.out.bits.exc),
|
Pipe(ifpu, ifpu.latency, (c: FPUCtrlSigs) => c.fromint, ifpu.io.out.bits.data, ifpu.io.out.bits.exc),
|
||||||
@ -554,16 +554,16 @@ class FPU(sfma_latency: Int, dfma_latency: Int) extends Component
|
|||||||
Pipe(dfma, dfma.latency, (c: FPUCtrlSigs) => c.fma && !c.single, dfma.io.out, dfma.io.exc))
|
Pipe(dfma, dfma.latency, (c: FPUCtrlSigs) => c.fma && !c.single, dfma.io.out, dfma.io.exc))
|
||||||
def latencyMask(c: FPUCtrlSigs, offset: Int) = {
|
def latencyMask(c: FPUCtrlSigs, offset: Int) = {
|
||||||
require(pipes.forall(_.lat >= offset))
|
require(pipes.forall(_.lat >= offset))
|
||||||
pipes.map(p => Mux(p.cond(c), UFix(1 << p.lat-offset), UFix(0))).reduce(_|_)
|
pipes.map(p => Mux(p.cond(c), UInt(1 << p.lat-offset), UInt(0))).reduce(_|_)
|
||||||
}
|
}
|
||||||
def pipeid(c: FPUCtrlSigs) = pipes.zipWithIndex.map(p => Mux(p._1.cond(c), UFix(p._2), UFix(0))).reduce(_|_)
|
def pipeid(c: FPUCtrlSigs) = pipes.zipWithIndex.map(p => Mux(p._1.cond(c), UInt(p._2), UInt(0))).reduce(_|_)
|
||||||
val maxLatency = pipes.map(_.lat).max
|
val maxLatency = pipes.map(_.lat).max
|
||||||
val memLatencyMask = latencyMask(mem_ctrl, 2)
|
val memLatencyMask = latencyMask(mem_ctrl, 2)
|
||||||
|
|
||||||
val wen = Reg(resetVal = Bits(0, maxLatency-1))
|
val wen = RegReset(Bits(0, maxLatency-1))
|
||||||
val winfo = Vec(maxLatency-1) { Reg() { Bits() } }
|
val winfo = Vec.fill(maxLatency-1){Reg(Bits())}
|
||||||
val mem_wen = mem_reg_valid && (mem_ctrl.fma || mem_ctrl.fastpipe || mem_ctrl.fromint)
|
val mem_wen = mem_reg_valid && (mem_ctrl.fma || mem_ctrl.fastpipe || mem_ctrl.fromint)
|
||||||
val (write_port_busy, mem_winfo) = (Reg{Bool()}, Reg{Bits()})
|
val (write_port_busy, mem_winfo) = (Reg(Bool()), Reg(Bits()))
|
||||||
when (ex_reg_valid) {
|
when (ex_reg_valid) {
|
||||||
write_port_busy := mem_wen && (memLatencyMask & latencyMask(ctrl, 1)).orR || (wen & latencyMask(ctrl, 0)).orR
|
write_port_busy := mem_wen && (memLatencyMask & latencyMask(ctrl, 1)).orR || (wen & latencyMask(ctrl, 0)).orR
|
||||||
mem_winfo := Cat(pipeid(ctrl), ex_reg_inst(31,27))
|
mem_winfo := Cat(pipeid(ctrl), ex_reg_inst(31,27))
|
||||||
@ -584,10 +584,10 @@ class FPU(sfma_latency: Int, dfma_latency: Int) extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val waddr = winfo(0)(4,0).toUFix
|
val waddr = winfo(0)(4,0).toUInt
|
||||||
val wsrc = winfo(0) >> waddr.getWidth
|
val wsrc = winfo(0) >> waddr.getWidth
|
||||||
val wdata = (Vec(pipes.map(_.wdata)){Bits()})(wsrc)
|
val wdata = Vec(pipes.map(_.wdata))(wsrc)
|
||||||
val wexc = (Vec(pipes.map(_.wexc)){Bits()})(wsrc)
|
val wexc = Vec(pipes.map(_.wexc))(wsrc)
|
||||||
when (wen(0)) { regfile(waddr(4,0)) := wdata }
|
when (wen(0)) { regfile(waddr(4,0)) := wdata }
|
||||||
|
|
||||||
val wb_toint_exc = RegEn(fpiu.io.out.bits.exc, mem_ctrl.toint)
|
val wb_toint_exc = RegEn(fpiu.io.out.bits.exc, mem_ctrl.toint)
|
||||||
@ -606,12 +606,12 @@ class FPU(sfma_latency: Int, dfma_latency: Int) extends Component
|
|||||||
|
|
||||||
val fp_inflight = wb_reg_valid && wb_ctrl.toint || wen.orR
|
val fp_inflight = wb_reg_valid && wb_ctrl.toint || wen.orR
|
||||||
val fsr_busy = mem_ctrl.rdfsr && fp_inflight || wb_reg_valid && wb_ctrl.wrfsr
|
val fsr_busy = mem_ctrl.rdfsr && fp_inflight || wb_reg_valid && wb_ctrl.wrfsr
|
||||||
val units_busy = mem_reg_valid && mem_ctrl.fma && Reg(Mux(ctrl.single, io.sfma.valid, io.dfma.valid))
|
val units_busy = mem_reg_valid && mem_ctrl.fma && RegUpdate(Mux(ctrl.single, io.sfma.valid, io.dfma.valid))
|
||||||
io.ctrl.nack_mem := fsr_busy || units_busy || write_port_busy
|
io.ctrl.nack_mem := fsr_busy || units_busy || write_port_busy
|
||||||
io.ctrl.dec <> fp_decoder.io.sigs
|
io.ctrl.dec <> fp_decoder.io.sigs
|
||||||
def useScoreboard(f: ((Pipe, Int)) => Bool) = pipes.zipWithIndex.filter(_._1.lat > 3).map(x => f(x)).fold(Bool(false))(_||_)
|
def useScoreboard(f: ((Pipe, Int)) => Bool) = pipes.zipWithIndex.filter(_._1.lat > 3).map(x => f(x)).fold(Bool(false))(_||_)
|
||||||
io.ctrl.sboard_set := wb_reg_valid && Reg(useScoreboard(_._1.cond(mem_ctrl)))
|
io.ctrl.sboard_set := wb_reg_valid && RegUpdate(useScoreboard(_._1.cond(mem_ctrl)))
|
||||||
io.ctrl.sboard_clr := wen(0) && useScoreboard(x => wsrc === UFix(x._2))
|
io.ctrl.sboard_clr := wen(0) && useScoreboard(x => wsrc === UInt(x._2))
|
||||||
io.ctrl.sboard_clra := waddr
|
io.ctrl.sboard_clra := waddr
|
||||||
// we don't currently support round-max-magnitude (rm=4)
|
// we don't currently support round-max-magnitude (rm=4)
|
||||||
io.ctrl.illegal_rm := ex_rm(2) && ctrl.round
|
io.ctrl.illegal_rm := ex_rm(2) && ctrl.round
|
||||||
|
@ -14,8 +14,8 @@ class HostIO(val w: Int) extends Bundle
|
|||||||
{
|
{
|
||||||
val clk = Bool(OUTPUT)
|
val clk = Bool(OUTPUT)
|
||||||
val clk_edge = Bool(OUTPUT)
|
val clk_edge = Bool(OUTPUT)
|
||||||
val in = new FIFOIO()(Bits(width = w)).flip
|
val in = Decoupled(Bits(width = w)).flip
|
||||||
val out = new FIFOIO()(Bits(width = w))
|
val out = Decoupled(Bits(width = w))
|
||||||
}
|
}
|
||||||
|
|
||||||
class PCRReq extends Bundle
|
class PCRReq extends Bundle
|
||||||
@ -29,28 +29,28 @@ class HTIFIO(ntiles: Int) extends Bundle
|
|||||||
{
|
{
|
||||||
val reset = Bool(INPUT)
|
val reset = Bool(INPUT)
|
||||||
val debug = new DebugIO
|
val debug = new DebugIO
|
||||||
val pcr_req = (new FIFOIO) { new PCRReq }.flip
|
val pcr_req = Decoupled(new PCRReq).flip
|
||||||
val pcr_rep = (new FIFOIO) { Bits(width = 64) }
|
val pcr_rep = Decoupled(Bits(width = 64))
|
||||||
val ipi_req = (new FIFOIO) { Bits(width = log2Up(ntiles)) }
|
val ipi_req = Decoupled(Bits(width = log2Up(ntiles)))
|
||||||
val ipi_rep = (new FIFOIO) { Bool() }.flip
|
val ipi_rep = Decoupled(Bool()).flip
|
||||||
}
|
}
|
||||||
|
|
||||||
class SCRIO extends Bundle
|
class SCRIO extends Bundle
|
||||||
{
|
{
|
||||||
val n = 64
|
val n = 64
|
||||||
val rdata = Vec(n) { Bits(INPUT, 64) }
|
val rdata = Vec.fill(n){Bits(INPUT, 64)}
|
||||||
val wen = Bool(OUTPUT)
|
val wen = Bool(OUTPUT)
|
||||||
val waddr = UFix(OUTPUT, log2Up(n))
|
val waddr = UInt(OUTPUT, log2Up(n))
|
||||||
val wdata = Bits(OUTPUT, 64)
|
val wdata = Bits(OUTPUT, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Component with ClientCoherenceAgent
|
class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Module with ClientCoherenceAgent
|
||||||
{
|
{
|
||||||
implicit val (ln, co) = (conf.ln, conf.co)
|
implicit val (ln, co) = (conf.ln, conf.co)
|
||||||
val nTiles = ln.nClients-1 // This HTIF is itself a TileLink client
|
val nTiles = ln.nClients-1 // This HTIF is itself a TileLink client
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val host = new HostIO(w)
|
val host = new HostIO(w)
|
||||||
val cpu = Vec(nTiles) { new HTIFIO(nTiles).flip }
|
val cpu = Vec.fill(nTiles){new HTIFIO(nTiles).flip}
|
||||||
val mem = new TileLinkIO
|
val mem = new TileLinkIO
|
||||||
val scr = new SCRIO
|
val scr = new SCRIO
|
||||||
}
|
}
|
||||||
@ -60,19 +60,19 @@ class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Component
|
|||||||
require(short_request_bits % w == 0)
|
require(short_request_bits % w == 0)
|
||||||
|
|
||||||
val rx_count_w = 13 + log2Up(64) - log2Up(w) // data size field is 12 bits
|
val rx_count_w = 13 + log2Up(64) - log2Up(w) // data size field is 12 bits
|
||||||
val rx_count = Reg(resetVal = UFix(0,rx_count_w))
|
val rx_count = RegReset(UInt(0,rx_count_w))
|
||||||
val rx_shifter = Reg() { Bits(width = short_request_bits) }
|
val rx_shifter = Reg(Bits(width = short_request_bits))
|
||||||
val rx_shifter_in = Cat(io.host.in.bits, rx_shifter(short_request_bits-1,w))
|
val rx_shifter_in = Cat(io.host.in.bits, rx_shifter(short_request_bits-1,w))
|
||||||
val next_cmd = rx_shifter_in(3,0)
|
val next_cmd = rx_shifter_in(3,0)
|
||||||
val cmd = Reg() { Bits() }
|
val cmd = Reg(Bits())
|
||||||
val size = Reg() { Bits() }
|
val size = Reg(Bits())
|
||||||
val pos = Reg() { Bits() }
|
val pos = Reg(Bits())
|
||||||
val seqno = Reg() { Bits() }
|
val seqno = Reg(Bits())
|
||||||
val addr = Reg() { Bits() }
|
val addr = Reg(Bits())
|
||||||
when (io.host.in.valid && io.host.in.ready) {
|
when (io.host.in.valid && io.host.in.ready) {
|
||||||
rx_shifter := rx_shifter_in
|
rx_shifter := rx_shifter_in
|
||||||
rx_count := rx_count + UFix(1)
|
rx_count := rx_count + UInt(1)
|
||||||
when (rx_count === UFix(short_request_bits/w-1)) {
|
when (rx_count === UInt(short_request_bits/w-1)) {
|
||||||
cmd := next_cmd
|
cmd := next_cmd
|
||||||
size := rx_shifter_in(15,4)
|
size := rx_shifter_in(15,4)
|
||||||
pos := rx_shifter_in(15,4+OFFSET_BITS-3)
|
pos := rx_shifter_in(15,4+OFFSET_BITS-3)
|
||||||
@ -81,15 +81,15 @@ class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val rx_word_count = (rx_count >> UFix(log2Up(short_request_bits/w)))
|
val rx_word_count = (rx_count >> UInt(log2Up(short_request_bits/w)))
|
||||||
val rx_word_done = io.host.in.valid && rx_count(log2Up(short_request_bits/w)-1,0).andR
|
val rx_word_done = io.host.in.valid && rx_count(log2Up(short_request_bits/w)-1,0).andR
|
||||||
val packet_ram_depth = long_request_bits/short_request_bits-1
|
val packet_ram_depth = long_request_bits/short_request_bits-1
|
||||||
val packet_ram = Vec(packet_ram_depth) { Reg() { Bits(width = short_request_bits) } }
|
val packet_ram = Vec.fill(packet_ram_depth){Reg(Bits(width = short_request_bits))}
|
||||||
when (rx_word_done && io.host.in.ready) {
|
when (rx_word_done && io.host.in.ready) {
|
||||||
packet_ram(rx_word_count(log2Up(packet_ram_depth)-1,0) - UFix(1)) := rx_shifter_in
|
packet_ram(rx_word_count(log2Up(packet_ram_depth)-1,0) - UInt(1)) := rx_shifter_in
|
||||||
}
|
}
|
||||||
|
|
||||||
val cmd_readmem :: cmd_writemem :: cmd_readcr :: cmd_writecr :: cmd_ack :: cmd_nack :: Nil = Enum(6) { UFix() }
|
val cmd_readmem :: cmd_writemem :: cmd_readcr :: cmd_writecr :: cmd_ack :: cmd_nack :: Nil = Enum(6) { UInt() }
|
||||||
|
|
||||||
val pcr_addr = addr(io.cpu(0).pcr_req.bits.addr.width-1, 0)
|
val pcr_addr = addr(io.cpu(0).pcr_req.bits.addr.width-1, 0)
|
||||||
val pcr_coreid = addr(log2Up(nTiles)-1+20+1,20)
|
val pcr_coreid = addr(log2Up(nTiles)-1+20+1,20)
|
||||||
@ -97,25 +97,25 @@ class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Component
|
|||||||
|
|
||||||
val bad_mem_packet = size(OFFSET_BITS-1-3,0).orR || addr(OFFSET_BITS-1-3,0).orR
|
val bad_mem_packet = size(OFFSET_BITS-1-3,0).orR || addr(OFFSET_BITS-1-3,0).orR
|
||||||
val nack = Mux(cmd === cmd_readmem || cmd === cmd_writemem, bad_mem_packet,
|
val nack = Mux(cmd === cmd_readmem || cmd === cmd_writemem, bad_mem_packet,
|
||||||
Mux(cmd === cmd_readcr || cmd === cmd_writecr, size != UFix(1),
|
Mux(cmd === cmd_readcr || cmd === cmd_writecr, size != UInt(1),
|
||||||
Bool(true)))
|
Bool(true)))
|
||||||
|
|
||||||
val tx_count = Reg(resetVal = UFix(0, rx_count_w))
|
val tx_count = RegReset(UInt(0, rx_count_w))
|
||||||
val tx_subword_count = tx_count(log2Up(short_request_bits/w)-1,0)
|
val tx_subword_count = tx_count(log2Up(short_request_bits/w)-1,0)
|
||||||
val tx_word_count = tx_count(rx_count_w-1, log2Up(short_request_bits/w))
|
val tx_word_count = tx_count(rx_count_w-1, log2Up(short_request_bits/w))
|
||||||
val packet_ram_raddr = tx_word_count(log2Up(packet_ram_depth)-1,0) - UFix(1)
|
val packet_ram_raddr = tx_word_count(log2Up(packet_ram_depth)-1,0) - UInt(1)
|
||||||
when (io.host.out.valid && io.host.out.ready) {
|
when (io.host.out.valid && io.host.out.ready) {
|
||||||
tx_count := tx_count + UFix(1)
|
tx_count := tx_count + UInt(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val rx_done = rx_word_done && Mux(rx_word_count === UFix(0), next_cmd != cmd_writemem && next_cmd != cmd_writecr, rx_word_count === size || rx_word_count(log2Up(packet_ram_depth)-1,0) === UFix(0))
|
val rx_done = rx_word_done && Mux(rx_word_count === UInt(0), next_cmd != cmd_writemem && next_cmd != cmd_writecr, rx_word_count === size || rx_word_count(log2Up(packet_ram_depth)-1,0) === UInt(0))
|
||||||
val tx_size = Mux(!nack && (cmd === cmd_readmem || cmd === cmd_readcr || cmd === cmd_writecr), size, UFix(0))
|
val tx_size = Mux(!nack && (cmd === cmd_readmem || cmd === cmd_readcr || cmd === cmd_writecr), size, UInt(0))
|
||||||
val tx_done = io.host.out.ready && tx_subword_count.andR && (tx_word_count === tx_size || tx_word_count > UFix(0) && packet_ram_raddr.andR)
|
val tx_done = io.host.out.ready && tx_subword_count.andR && (tx_word_count === tx_size || tx_word_count > UInt(0) && packet_ram_raddr.andR)
|
||||||
|
|
||||||
val mem_acked = Reg(resetVal = Bool(false))
|
val mem_acked = RegReset(Bool(false))
|
||||||
val mem_gxid = Reg() { Bits() }
|
val mem_gxid = Reg(Bits())
|
||||||
val mem_gsrc = Reg() { UFix(width = conf.ln.idBits) }
|
val mem_gsrc = Reg(UInt(width = conf.ln.idBits))
|
||||||
val mem_needs_ack = Reg() { Bool() }
|
val mem_needs_ack = Reg(Bool())
|
||||||
when (io.mem.grant.valid) {
|
when (io.mem.grant.valid) {
|
||||||
mem_acked := Bool(true)
|
mem_acked := Bool(true)
|
||||||
mem_gxid := io.mem.grant.bits.payload.master_xact_id
|
mem_gxid := io.mem.grant.bits.payload.master_xact_id
|
||||||
@ -124,18 +124,18 @@ class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Component
|
|||||||
}
|
}
|
||||||
io.mem.grant.ready := Bool(true)
|
io.mem.grant.ready := Bool(true)
|
||||||
|
|
||||||
val state_rx :: state_pcr_req :: state_pcr_resp :: state_mem_req :: state_mem_wdata :: state_mem_wresp :: state_mem_rdata :: state_mem_finish :: state_tx :: Nil = Enum(9) { UFix() }
|
val state_rx :: state_pcr_req :: state_pcr_resp :: state_mem_req :: state_mem_wdata :: state_mem_wresp :: state_mem_rdata :: state_mem_finish :: state_tx :: Nil = Enum(9) { UInt() }
|
||||||
val state = Reg(resetVal = state_rx)
|
val state = RegReset(state_rx)
|
||||||
|
|
||||||
val rx_cmd = Mux(rx_word_count === UFix(0), next_cmd, cmd)
|
val rx_cmd = Mux(rx_word_count === UInt(0), next_cmd, cmd)
|
||||||
when (state === state_rx && rx_done) {
|
when (state === state_rx && rx_done) {
|
||||||
state := Mux(rx_cmd === cmd_readmem || rx_cmd === cmd_writemem, state_mem_req,
|
state := Mux(rx_cmd === cmd_readmem || rx_cmd === cmd_writemem, state_mem_req,
|
||||||
Mux(rx_cmd === cmd_readcr || rx_cmd === cmd_writecr, state_pcr_req,
|
Mux(rx_cmd === cmd_readcr || rx_cmd === cmd_writecr, state_pcr_req,
|
||||||
state_tx))
|
state_tx))
|
||||||
}
|
}
|
||||||
|
|
||||||
val mem_cnt = Reg(resetVal = UFix(0, log2Up(REFILL_CYCLES)))
|
val mem_cnt = RegReset(UInt(0, log2Up(REFILL_CYCLES)))
|
||||||
val x_init = new Queue(1)(new Acquire)
|
val x_init = Module(new Queue(new Acquire, 1))
|
||||||
when (state === state_mem_req && x_init.io.enq.ready) {
|
when (state === state_mem_req && x_init.io.enq.ready) {
|
||||||
state := Mux(cmd === cmd_writemem, state_mem_wdata, state_mem_rdata)
|
state := Mux(cmd === cmd_writemem, state_mem_wdata, state_mem_rdata)
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Component
|
|||||||
when (mem_cnt.andR) {
|
when (mem_cnt.andR) {
|
||||||
state := state_mem_wresp
|
state := state_mem_wresp
|
||||||
}
|
}
|
||||||
mem_cnt := mem_cnt + UFix(1)
|
mem_cnt := mem_cnt + UInt(1)
|
||||||
}
|
}
|
||||||
when (state === state_mem_wresp) {
|
when (state === state_mem_wresp) {
|
||||||
when (mem_acked) {
|
when (mem_acked) {
|
||||||
@ -156,37 +156,37 @@ class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Component
|
|||||||
when (mem_cnt.andR) {
|
when (mem_cnt.andR) {
|
||||||
state := state_mem_finish
|
state := state_mem_finish
|
||||||
}
|
}
|
||||||
mem_cnt := mem_cnt + UFix(1)
|
mem_cnt := mem_cnt + UInt(1)
|
||||||
}
|
}
|
||||||
mem_acked := Bool(false)
|
mem_acked := Bool(false)
|
||||||
}
|
}
|
||||||
when (state === state_mem_finish && io.mem.grant_ack.ready) {
|
when (state === state_mem_finish && io.mem.grant_ack.ready) {
|
||||||
state := Mux(cmd === cmd_readmem || pos === UFix(1), state_tx, state_rx)
|
state := Mux(cmd === cmd_readmem || pos === UInt(1), state_tx, state_rx)
|
||||||
pos := pos - UFix(1)
|
pos := pos - UInt(1)
|
||||||
addr := addr + UFix(1 << OFFSET_BITS-3)
|
addr := addr + UInt(1 << OFFSET_BITS-3)
|
||||||
}
|
}
|
||||||
when (state === state_tx && tx_done) {
|
when (state === state_tx && tx_done) {
|
||||||
when (tx_word_count === tx_size) {
|
when (tx_word_count === tx_size) {
|
||||||
rx_count := UFix(0)
|
rx_count := UInt(0)
|
||||||
tx_count := UFix(0)
|
tx_count := UInt(0)
|
||||||
}
|
}
|
||||||
state := Mux(cmd === cmd_readmem && pos != UFix(0), state_mem_req, state_rx)
|
state := Mux(cmd === cmd_readmem && pos != UInt(0), state_mem_req, state_rx)
|
||||||
}
|
}
|
||||||
|
|
||||||
var mem_req_data: Bits = null
|
var mem_req_data: Bits = null
|
||||||
for (i <- 0 until MEM_DATA_BITS/short_request_bits) {
|
for (i <- 0 until MEM_DATA_BITS/short_request_bits) {
|
||||||
val idx = Cat(mem_cnt, UFix(i, log2Up(MEM_DATA_BITS/short_request_bits)))
|
val idx = Cat(mem_cnt, UInt(i, log2Up(MEM_DATA_BITS/short_request_bits)))
|
||||||
when (state === state_mem_rdata && io.mem.grant.valid) {
|
when (state === state_mem_rdata && io.mem.grant.valid) {
|
||||||
packet_ram(idx) := io.mem.grant.bits.payload.data((i+1)*short_request_bits-1, i*short_request_bits)
|
packet_ram(idx) := io.mem.grant.bits.payload.data((i+1)*short_request_bits-1, i*short_request_bits)
|
||||||
}
|
}
|
||||||
mem_req_data = Cat(packet_ram(idx), mem_req_data)
|
mem_req_data = Cat(packet_ram(idx), mem_req_data)
|
||||||
}
|
}
|
||||||
x_init.io.enq.valid := state === state_mem_req
|
x_init.io.enq.valid := state === state_mem_req
|
||||||
val init_addr = addr.toUFix >> UFix(OFFSET_BITS-3)
|
val init_addr = addr.toUInt >> UInt(OFFSET_BITS-3)
|
||||||
x_init.io.enq.bits := Mux(cmd === cmd_writemem,
|
x_init.io.enq.bits := Mux(cmd === cmd_writemem,
|
||||||
Acquire(co.getUncachedWriteAcquireType, init_addr, UFix(0)),
|
Acquire(co.getUncachedWriteAcquireType, init_addr, UInt(0)),
|
||||||
Acquire(co.getUncachedReadAcquireType, init_addr, UFix(0)))
|
Acquire(co.getUncachedReadAcquireType, init_addr, UInt(0)))
|
||||||
io.mem.acquire.meta <> FIFOedLogicalNetworkIOWrapper(x_init.io.deq, UFix(conf.ln.nClients), UFix(0)) // By convention HTIF is the client with the largest id
|
io.mem.acquire.meta <> FIFOedLogicalNetworkIOWrapper(x_init.io.deq, UInt(conf.ln.nClients), UInt(0)) // By convention HTIF is the client with the largest id
|
||||||
io.mem.acquire.data.valid := state === state_mem_wdata
|
io.mem.acquire.data.valid := state === state_mem_wdata
|
||||||
io.mem.acquire.data.bits.payload.data := mem_req_data
|
io.mem.acquire.data.bits.payload.data := mem_req_data
|
||||||
io.mem.grant_ack.valid := (state === state_mem_finish) && mem_needs_ack
|
io.mem.grant_ack.valid := (state === state_mem_finish) && mem_needs_ack
|
||||||
@ -196,13 +196,13 @@ class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Component
|
|||||||
io.mem.release.meta.valid := Bool(false)
|
io.mem.release.meta.valid := Bool(false)
|
||||||
io.mem.release.data.valid := Bool(false)
|
io.mem.release.data.valid := Bool(false)
|
||||||
|
|
||||||
val pcrReadData = Reg{Bits(width = io.cpu(0).pcr_rep.bits.getWidth)}
|
val pcrReadData = Reg(Bits(width = io.cpu(0).pcr_rep.bits.getWidth))
|
||||||
for (i <- 0 until nTiles) {
|
for (i <- 0 until nTiles) {
|
||||||
val my_reset = Reg(resetVal = Bool(true))
|
val my_reset = RegReset(Bool(true))
|
||||||
val my_ipi = Reg(resetVal = Bool(false))
|
val my_ipi = RegReset(Bool(false))
|
||||||
|
|
||||||
val cpu = io.cpu(i)
|
val cpu = io.cpu(i)
|
||||||
val me = pcr_coreid === UFix(i)
|
val me = pcr_coreid === UInt(i)
|
||||||
cpu.pcr_req.valid := state === state_pcr_req && me && pcr_addr != PCR.RESET
|
cpu.pcr_req.valid := state === state_pcr_req && me && pcr_addr != PCR.RESET
|
||||||
cpu.pcr_req.bits.rw := cmd === cmd_writecr
|
cpu.pcr_req.bits.rw := cmd === cmd_writecr
|
||||||
cpu.pcr_req.bits.addr := pcr_addr
|
cpu.pcr_req.bits.addr := pcr_addr
|
||||||
@ -215,7 +215,7 @@ class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Component
|
|||||||
cpu.ipi_rep.valid := my_ipi
|
cpu.ipi_rep.valid := my_ipi
|
||||||
cpu.ipi_req.ready := Bool(true)
|
cpu.ipi_req.ready := Bool(true)
|
||||||
for (j <- 0 until nTiles) {
|
for (j <- 0 until nTiles) {
|
||||||
when (io.cpu(j).ipi_req.valid && io.cpu(j).ipi_req.bits === UFix(i)) {
|
when (io.cpu(j).ipi_req.valid && io.cpu(j).ipi_req.bits === UInt(i)) {
|
||||||
my_ipi := Bool(true)
|
my_ipi := Bool(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,16 +238,16 @@ class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val scr_rdata = Vec(io.scr.rdata.size){Bits(width = 64)}
|
val scr_rdata = Vec.fill(io.scr.rdata.size){Bits(width = 64)}
|
||||||
for (i <- 0 until scr_rdata.size)
|
for (i <- 0 until scr_rdata.size)
|
||||||
scr_rdata(i) := io.scr.rdata(i)
|
scr_rdata(i) := io.scr.rdata(i)
|
||||||
scr_rdata(0) := nTiles
|
scr_rdata(0) := nTiles
|
||||||
scr_rdata(1) := (UFix(REFILL_CYCLES*MEM_DATA_BITS/8) << x_init.io.enq.bits.addr.getWidth) >> 20
|
scr_rdata(1) := (UInt(REFILL_CYCLES*MEM_DATA_BITS/8) << x_init.io.enq.bits.addr.getWidth) >> 20
|
||||||
|
|
||||||
io.scr.wen := false
|
io.scr.wen := false
|
||||||
io.scr.wdata := pcr_wdata
|
io.scr.wdata := pcr_wdata
|
||||||
io.scr.waddr := pcr_addr.toUFix
|
io.scr.waddr := pcr_addr.toUInt
|
||||||
when (state === state_pcr_req && pcr_coreid === Fix(-1)) {
|
when (state === state_pcr_req && pcr_coreid === SInt(-1)) {
|
||||||
io.scr.wen := cmd === cmd_writecr
|
io.scr.wen := cmd === cmd_writecr
|
||||||
pcrReadData := scr_rdata(pcr_addr)
|
pcrReadData := scr_rdata(pcr_addr)
|
||||||
state := state_tx
|
state := state_tx
|
||||||
@ -256,7 +256,7 @@ class RocketHTIF(w: Int)(implicit conf: TileLinkConfiguration) extends Component
|
|||||||
val tx_cmd = Mux(nack, cmd_nack, cmd_ack)
|
val tx_cmd = Mux(nack, cmd_nack, cmd_ack)
|
||||||
val tx_cmd_ext = Cat(Bits(0, 4-tx_cmd.getWidth), tx_cmd)
|
val tx_cmd_ext = Cat(Bits(0, 4-tx_cmd.getWidth), tx_cmd)
|
||||||
val tx_header = Cat(addr, seqno, tx_size, tx_cmd_ext)
|
val tx_header = Cat(addr, seqno, tx_size, tx_cmd_ext)
|
||||||
val tx_data = Mux(tx_word_count === UFix(0), tx_header,
|
val tx_data = Mux(tx_word_count === UInt(0), tx_header,
|
||||||
Mux(cmd === cmd_readcr || cmd === cmd_writecr, pcrReadData,
|
Mux(cmd === cmd_readcr || cmd === cmd_writecr, pcrReadData,
|
||||||
packet_ram(packet_ram_raddr)))
|
packet_ram(packet_ram_raddr)))
|
||||||
|
|
||||||
|
@ -25,14 +25,14 @@ case class ICacheConfig(sets: Int, assoc: Int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FrontendReq extends Bundle {
|
class FrontendReq extends Bundle {
|
||||||
val pc = UFix(width = VADDR_BITS+1)
|
val pc = UInt(width = VADDR_BITS+1)
|
||||||
val mispredict = Bool()
|
val mispredict = Bool()
|
||||||
val taken = Bool()
|
val taken = Bool()
|
||||||
val currentpc = UFix(width = VADDR_BITS+1)
|
val currentpc = UInt(width = VADDR_BITS+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FrontendResp(implicit conf: ICacheConfig) extends Bundle {
|
class FrontendResp(implicit conf: ICacheConfig) extends Bundle {
|
||||||
val pc = UFix(width = VADDR_BITS+1) // ID stage PC
|
val pc = UInt(width = VADDR_BITS+1) // ID stage PC
|
||||||
val data = Bits(width = conf.ibytes*8)
|
val data = Bits(width = conf.ibytes*8)
|
||||||
val taken = Bool()
|
val taken = Bool()
|
||||||
val xcpt_ma = Bool()
|
val xcpt_ma = Bool()
|
||||||
@ -42,36 +42,36 @@ class FrontendResp(implicit conf: ICacheConfig) extends Bundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CPUFrontendIO(implicit conf: ICacheConfig) extends Bundle {
|
class CPUFrontendIO(implicit conf: ICacheConfig) extends Bundle {
|
||||||
val req = new PipeIO()(new FrontendReq)
|
val req = Valid(new FrontendReq)
|
||||||
val resp = new FIFOIO()(new FrontendResp).flip
|
val resp = Decoupled(new FrontendResp).flip
|
||||||
val ptw = new TLBPTWIO().flip
|
val ptw = new TLBPTWIO().flip
|
||||||
val invalidate = Bool(OUTPUT)
|
val invalidate = Bool(OUTPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Frontend(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Component
|
class Frontend(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val cpu = new CPUFrontendIO()(c).flip
|
val cpu = new CPUFrontendIO()(c).flip
|
||||||
val mem = new UncachedTileLinkIO
|
val mem = new UncachedTileLinkIO
|
||||||
}
|
}
|
||||||
|
|
||||||
val btb = new rocketDpathBTB(c.nbtb)
|
val btb = Module(new rocketDpathBTB(c.nbtb))
|
||||||
val icache = new ICache
|
val icache = Module(new ICache)
|
||||||
val tlb = new TLB(c.ntlb)
|
val tlb = Module(new TLB(c.ntlb))
|
||||||
|
|
||||||
val s1_pc = Reg() { UFix() }
|
val s1_pc = Reg(UInt())
|
||||||
val s1_same_block = Reg() { Bool() }
|
val s1_same_block = Reg(Bool())
|
||||||
val s2_valid = Reg(resetVal = Bool(true))
|
val s2_valid = RegReset(Bool(true))
|
||||||
val s2_pc = Reg(resetVal = UFix(START_ADDR))
|
val s2_pc = RegReset(UInt(START_ADDR))
|
||||||
val s2_btb_hit = Reg(resetVal = Bool(false))
|
val s2_btb_hit = RegReset(Bool(false))
|
||||||
val s2_xcpt_if = Reg(resetVal = Bool(false))
|
val s2_xcpt_if = RegReset(Bool(false))
|
||||||
|
|
||||||
val btbTarget = Cat(btb.io.target(VADDR_BITS-1), btb.io.target)
|
val btbTarget = Cat(btb.io.target(VADDR_BITS-1), btb.io.target)
|
||||||
val pcp4_0 = s1_pc + UFix(c.ibytes)
|
val pcp4_0 = s1_pc + UInt(c.ibytes)
|
||||||
val pcp4 = Cat(s1_pc(VADDR_BITS-1) & pcp4_0(VADDR_BITS-1), pcp4_0(VADDR_BITS-1,0))
|
val pcp4 = Cat(s1_pc(VADDR_BITS-1) & pcp4_0(VADDR_BITS-1), pcp4_0(VADDR_BITS-1,0))
|
||||||
val icmiss = s2_valid && !icache.io.resp.valid
|
val icmiss = s2_valid && !icache.io.resp.valid
|
||||||
val predicted_npc = Mux(btb.io.hit, btbTarget, pcp4)
|
val predicted_npc = Mux(btb.io.hit, btbTarget, pcp4)
|
||||||
val npc = Mux(icmiss, s2_pc, predicted_npc).toUFix
|
val npc = Mux(icmiss, s2_pc, predicted_npc).toUInt
|
||||||
val s0_same_block = !icmiss && !io.cpu.req.valid && (predicted_npc >> log2Up(c.databits/8)) === (s1_pc >> log2Up(c.databits/8))
|
val s0_same_block = !icmiss && !io.cpu.req.valid && (predicted_npc >> log2Up(c.databits/8)) === (s1_pc >> log2Up(c.databits/8))
|
||||||
|
|
||||||
val stall = io.cpu.resp.valid && !io.cpu.resp.ready
|
val stall = io.cpu.resp.valid && !io.cpu.resp.ready
|
||||||
@ -100,8 +100,8 @@ class Frontend(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Comp
|
|||||||
|
|
||||||
tlb.io.ptw <> io.cpu.ptw
|
tlb.io.ptw <> io.cpu.ptw
|
||||||
tlb.io.req.valid := !stall && !icmiss
|
tlb.io.req.valid := !stall && !icmiss
|
||||||
tlb.io.req.bits.vpn := s1_pc >> UFix(PGIDX_BITS)
|
tlb.io.req.bits.vpn := s1_pc >> UInt(PGIDX_BITS)
|
||||||
tlb.io.req.bits.asid := UFix(0)
|
tlb.io.req.bits.asid := UInt(0)
|
||||||
tlb.io.req.bits.passthrough := Bool(false)
|
tlb.io.req.bits.passthrough := Bool(false)
|
||||||
tlb.io.req.bits.instruction := Bool(true)
|
tlb.io.req.bits.instruction := Bool(true)
|
||||||
|
|
||||||
@ -117,40 +117,45 @@ class Frontend(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Comp
|
|||||||
io.cpu.resp.bits.pc := s2_pc
|
io.cpu.resp.bits.pc := s2_pc
|
||||||
io.cpu.resp.bits.data := icache.io.resp.bits.datablock >> (s2_pc(log2Up(c.databits/8)-1,log2Up(c.ibytes)) << log2Up(c.ibytes*8))
|
io.cpu.resp.bits.data := icache.io.resp.bits.datablock >> (s2_pc(log2Up(c.databits/8)-1,log2Up(c.ibytes)) << log2Up(c.ibytes*8))
|
||||||
io.cpu.resp.bits.taken := s2_btb_hit
|
io.cpu.resp.bits.taken := s2_btb_hit
|
||||||
io.cpu.resp.bits.xcpt_ma := s2_pc(log2Up(c.ibytes)-1,0) != UFix(0)
|
io.cpu.resp.bits.xcpt_ma := s2_pc(log2Up(c.ibytes)-1,0) != UInt(0)
|
||||||
io.cpu.resp.bits.xcpt_if := s2_xcpt_if
|
io.cpu.resp.bits.xcpt_if := s2_xcpt_if
|
||||||
}
|
}
|
||||||
|
|
||||||
class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Component
|
class ICacheReq extends Bundle {
|
||||||
|
val idx = UInt(width = PGIDX_BITS)
|
||||||
|
val ppn = UInt(width = PPN_BITS) // delayed one cycle
|
||||||
|
val kill = Bool() // delayed one cycle
|
||||||
|
}
|
||||||
|
|
||||||
|
class ICacheResp(implicit c: ICacheConfig) extends Bundle {
|
||||||
|
val data = Bits(width = c.ibytes*8)
|
||||||
|
val datablock = Bits(width = c.databits)
|
||||||
|
override def clone = new ICacheResp().asInstanceOf[this.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Module
|
||||||
{
|
{
|
||||||
implicit val lnConf = tl.ln
|
implicit val lnConf = tl.ln
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = new PipeIO()(new Bundle {
|
val req = Valid(new ICacheReq).flip
|
||||||
val idx = UFix(width = PGIDX_BITS)
|
val resp = Decoupled(new ICacheResp)
|
||||||
val ppn = UFix(width = PPN_BITS) // delayed one cycle
|
|
||||||
val kill = Bool() // delayed one cycle
|
|
||||||
}).flip
|
|
||||||
val resp = new FIFOIO()(new Bundle {
|
|
||||||
val data = Bits(width = c.ibytes*8)
|
|
||||||
val datablock = Bits(width = c.databits)
|
|
||||||
})
|
|
||||||
val invalidate = Bool(INPUT)
|
val invalidate = Bool(INPUT)
|
||||||
val mem = new UncachedTileLinkIO
|
val mem = new UncachedTileLinkIO
|
||||||
}
|
}
|
||||||
|
|
||||||
val s_ready :: s_request :: s_refill_wait :: s_refill :: Nil = Enum(4) { UFix() }
|
val s_ready :: s_request :: s_refill_wait :: s_refill :: Nil = Enum(4) { UInt() }
|
||||||
val state = Reg(resetVal = s_ready)
|
val state = RegReset(s_ready)
|
||||||
val invalidated = Reg() { Bool() }
|
val invalidated = Reg(Bool())
|
||||||
val stall = !io.resp.ready
|
val stall = !io.resp.ready
|
||||||
val rdy = Bool()
|
val rdy = Bool()
|
||||||
|
|
||||||
val s2_valid = Reg(resetVal = Bool(false))
|
val s2_valid = RegReset(Bool(false))
|
||||||
val s2_addr = Reg { UFix(width = PADDR_BITS) }
|
val s2_addr = Reg(UInt(width = PADDR_BITS))
|
||||||
val s2_any_tag_hit = Bool()
|
val s2_any_tag_hit = Bool()
|
||||||
|
|
||||||
val s1_valid = Reg(resetVal = Bool(false))
|
val s1_valid = RegReset(Bool(false))
|
||||||
val s1_pgoff = Reg() { UFix(width = PGIDX_BITS) }
|
val s1_pgoff = Reg(UInt(width = PGIDX_BITS))
|
||||||
val s1_addr = Cat(io.req.bits.ppn, s1_pgoff).toUFix
|
val s1_addr = Cat(io.req.bits.ppn, s1_pgoff).toUInt
|
||||||
val s1_tag = s1_addr(c.tagbits+c.untagbits-1,c.untagbits)
|
val s1_tag = s1_addr(c.tagbits+c.untagbits-1,c.untagbits)
|
||||||
|
|
||||||
val s0_valid = io.req.valid || s1_valid && stall
|
val s0_valid = io.req.valid || s1_valid && stall
|
||||||
@ -175,14 +180,14 @@ class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Compon
|
|||||||
|
|
||||||
//assert(!co.isVoluntary(io.mem.grant.bits.payload) || !io.mem.grant.valid, "UncachedRequestors shouldn't get voluntary grants.")
|
//assert(!co.isVoluntary(io.mem.grant.bits.payload) || !io.mem.grant.valid, "UncachedRequestors shouldn't get voluntary grants.")
|
||||||
val (rf_cnt, refill_done) = Counter(io.mem.grant.valid, REFILL_CYCLES)
|
val (rf_cnt, refill_done) = Counter(io.mem.grant.valid, REFILL_CYCLES)
|
||||||
val repl_way = if (c.dm) UFix(0) else LFSR16(s2_miss)(log2Up(c.assoc)-1,0)
|
val repl_way = if (c.dm) UInt(0) else LFSR16(s2_miss)(log2Up(c.assoc)-1,0)
|
||||||
|
|
||||||
val enc_tagbits = c.code.width(c.tagbits)
|
val enc_tagbits = c.code.width(c.tagbits)
|
||||||
val tag_array = Mem(c.sets, seqRead = true) { Bits(width = enc_tagbits*c.assoc) }
|
val tag_array = Mem(Bits(width = enc_tagbits*c.assoc), c.sets, seqRead = true)
|
||||||
val tag_raddr = Reg{UFix()}
|
val tag_raddr = Reg(UInt())
|
||||||
when (refill_done) {
|
when (refill_done) {
|
||||||
val wmask = FillInterleaved(enc_tagbits, if (c.dm) Bits(1) else UFixToOH(repl_way))
|
val wmask = FillInterleaved(enc_tagbits, if (c.dm) Bits(1) else UIntToOH(repl_way))
|
||||||
val tag = c.code.encode(s2_tag)
|
val tag = c.code.encode(s2_tag).toUInt
|
||||||
tag_array.write(s2_idx, Fill(c.assoc, tag), wmask)
|
tag_array.write(s2_idx, Fill(c.assoc, tag), wmask)
|
||||||
}
|
}
|
||||||
// /*.else*/when (s0_valid) { // uncomment ".else" to infer 6T SRAM
|
// /*.else*/when (s0_valid) { // uncomment ".else" to infer 6T SRAM
|
||||||
@ -190,7 +195,7 @@ class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Compon
|
|||||||
tag_raddr := s0_pgoff(c.untagbits-1,c.offbits)
|
tag_raddr := s0_pgoff(c.untagbits-1,c.offbits)
|
||||||
}
|
}
|
||||||
|
|
||||||
val vb_array = Reg(resetVal = Bits(0, c.lines))
|
val vb_array = RegReset(Bits(0, c.lines))
|
||||||
when (refill_done && !invalidated) {
|
when (refill_done && !invalidated) {
|
||||||
vb_array := vb_array.bitSet(Cat(repl_way, s2_idx), Bool(true))
|
vb_array := vb_array.bitSet(Cat(repl_way, s2_idx), Bool(true))
|
||||||
}
|
}
|
||||||
@ -198,19 +203,19 @@ class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Compon
|
|||||||
vb_array := Bits(0)
|
vb_array := Bits(0)
|
||||||
invalidated := Bool(true)
|
invalidated := Bool(true)
|
||||||
}
|
}
|
||||||
val s2_disparity = Vec(c.assoc) { Bool() }
|
val s2_disparity = Vec.fill(c.assoc){Bool()}
|
||||||
for (i <- 0 until c.assoc)
|
for (i <- 0 until c.assoc)
|
||||||
when (s2_valid && s2_disparity(i)) { vb_array := vb_array.bitSet(Cat(UFix(i), s2_idx), Bool(false)) }
|
when (s2_valid && s2_disparity(i)) { vb_array := vb_array.bitSet(Cat(UInt(i), s2_idx), Bool(false)) }
|
||||||
|
|
||||||
val s1_tag_match = Vec(c.assoc) { Bool() }
|
val s1_tag_match = Vec.fill(c.assoc){Bool()}
|
||||||
val s2_tag_hit = Vec(c.assoc) { Bool() }
|
val s2_tag_hit = Vec.fill(c.assoc){Bool()}
|
||||||
val s2_dout = Vec(c.assoc){Reg{Bits()}}
|
val s2_dout = Vec.fill(c.assoc){Reg(Bits())}
|
||||||
|
|
||||||
for (i <- 0 until c.assoc) {
|
for (i <- 0 until c.assoc) {
|
||||||
val s1_vb = vb_array(Cat(UFix(i), s1_pgoff(c.untagbits-1,c.offbits))).toBool
|
val s1_vb = vb_array(Cat(UInt(i), s1_pgoff(c.untagbits-1,c.offbits))).toBool
|
||||||
val s2_vb = Reg() { Bool() }
|
val s2_vb = Reg(Bool())
|
||||||
val s2_tag_disparity = Reg() { Bool() }
|
val s2_tag_disparity = Reg(Bool())
|
||||||
val s2_tag_match = Reg() { Bool() }
|
val s2_tag_match = Reg(Bool())
|
||||||
val tag_out = tag_array(tag_raddr)(enc_tagbits*(i+1)-1, enc_tagbits*i)
|
val tag_out = tag_array(tag_raddr)(enc_tagbits*(i+1)-1, enc_tagbits*i)
|
||||||
when (s1_valid && rdy && !stall) {
|
when (s1_valid && rdy && !stall) {
|
||||||
s2_vb := s1_vb
|
s2_vb := s1_vb
|
||||||
@ -224,9 +229,9 @@ class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Compon
|
|||||||
s2_any_tag_hit := s2_tag_hit.reduceLeft(_||_) && !s2_disparity.reduceLeft(_||_)
|
s2_any_tag_hit := s2_tag_hit.reduceLeft(_||_) && !s2_disparity.reduceLeft(_||_)
|
||||||
|
|
||||||
for (i <- 0 until c.assoc) {
|
for (i <- 0 until c.assoc) {
|
||||||
val data_array = Mem(c.sets*REFILL_CYCLES, seqRead = true){ Bits(width = c.code.width(c.databits)) }
|
val data_array = Mem(Bits(width = c.code.width(c.databits)), c.sets*REFILL_CYCLES, seqRead = true)
|
||||||
val s1_raddr = Reg{UFix()}
|
val s1_raddr = Reg(UInt())
|
||||||
when (io.mem.grant.valid && repl_way === UFix(i)) {
|
when (io.mem.grant.valid && repl_way === UInt(i)) {
|
||||||
val d = io.mem.grant.bits.payload.data
|
val d = io.mem.grant.bits.payload.data
|
||||||
data_array(Cat(s2_idx,rf_cnt)) := c.code.encode(d)
|
data_array(Cat(s2_idx,rf_cnt)) := c.code.encode(d)
|
||||||
}
|
}
|
||||||
@ -241,14 +246,14 @@ class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Compon
|
|||||||
io.resp.bits.data := Mux1H(s2_tag_hit, s2_dout_word)
|
io.resp.bits.data := Mux1H(s2_tag_hit, s2_dout_word)
|
||||||
io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout)
|
io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout)
|
||||||
|
|
||||||
val finish_q = (new Queue(1)) { new GrantAck }
|
val finish_q = Module(new Queue(new GrantAck, 1))
|
||||||
finish_q.io.enq.valid := refill_done && tl.co.requiresAck(io.mem.grant.bits.payload)
|
finish_q.io.enq.valid := refill_done && tl.co.requiresAck(io.mem.grant.bits.payload)
|
||||||
finish_q.io.enq.bits.master_xact_id := io.mem.grant.bits.payload.master_xact_id
|
finish_q.io.enq.bits.master_xact_id := io.mem.grant.bits.payload.master_xact_id
|
||||||
|
|
||||||
// output signals
|
// output signals
|
||||||
io.resp.valid := s2_hit
|
io.resp.valid := s2_hit
|
||||||
io.mem.acquire.meta.valid := (state === s_request) && finish_q.io.enq.ready
|
io.mem.acquire.meta.valid := (state === s_request) && finish_q.io.enq.ready
|
||||||
io.mem.acquire.meta.bits.payload := Acquire(tl.co.getUncachedReadAcquireType, s2_addr >> UFix(c.offbits), UFix(0))
|
io.mem.acquire.meta.bits.payload := Acquire(tl.co.getUncachedReadAcquireType, s2_addr >> UInt(c.offbits), UInt(0))
|
||||||
io.mem.acquire.data.valid := Bool(false)
|
io.mem.acquire.data.valid := Bool(false)
|
||||||
io.mem.grant_ack <> FIFOedLogicalNetworkIOWrapper(finish_q.io.deq)
|
io.mem.grant_ack <> FIFOedLogicalNetworkIOWrapper(finish_q.io.deq)
|
||||||
io.mem.grant.ready := Bool(true)
|
io.mem.grant.ready := Bool(true)
|
||||||
|
@ -265,7 +265,7 @@ object Instructions
|
|||||||
|
|
||||||
object Disassemble
|
object Disassemble
|
||||||
{
|
{
|
||||||
def apply(insn: Bits) = {
|
def apply(insn: UInt) = {
|
||||||
val name :: fmt :: Nil = ListLookup(insn, default, table)
|
val name :: fmt :: Nil = ListLookup(insn, default, table)
|
||||||
sprintf("%s %s", name, operands(insn, fmt))
|
sprintf("%s %s", name, operands(insn, fmt))
|
||||||
}
|
}
|
||||||
@ -288,8 +288,8 @@ object Disassemble
|
|||||||
Str(" fa6"), Str(" fa7"), Str(" fa8"), Str(" fa9"),
|
Str(" fa6"), Str(" fa7"), Str(" fa8"), Str(" fa9"),
|
||||||
Str("fa10"), Str("fa11"), Str("fa12"), Str("fa13"))
|
Str("fa10"), Str("fa11"), Str("fa12"), Str("fa13"))
|
||||||
|
|
||||||
def hex(x: Fix, plus: Char = ' ') =
|
def hex(x: SInt, plus: Char = ' ') =
|
||||||
Cat(Mux(x < Fix(0), Str("-0x"), Str(plus + "0x")), Str(x.abs, 16))
|
Cat(Mux(x < SInt(0), Str("-0x"), Str(plus + "0x")), Str(x.abs, 16))
|
||||||
|
|
||||||
val comma = Str(',')
|
val comma = Str(',')
|
||||||
val lparen = Str('(')
|
val lparen = Str('(')
|
||||||
@ -299,14 +299,14 @@ object Disassemble
|
|||||||
val rs1 = insn(26,22)
|
val rs1 = insn(26,22)
|
||||||
val rs2 = insn(21,17)
|
val rs2 = insn(21,17)
|
||||||
val rs3 = insn(16,12)
|
val rs3 = insn(16,12)
|
||||||
val immv = insn(21,10).toFix
|
val immv = insn(21,10).toSInt
|
||||||
val bmmv = Cat(insn(31,27), insn(16,10)).toFix
|
val bmmv = Cat(insn(31,27), insn(16,10)).toSInt
|
||||||
val jmmv = insn(31,7).toFix
|
val jmmv = insn(31,7).toSInt
|
||||||
|
|
||||||
val imm = hex(immv)
|
val imm = hex(immv)
|
||||||
val bmm = hex(bmmv << UFix(1))
|
val bmm = hex(bmmv << UInt(1))
|
||||||
val jmm = hex(jmmv << UFix(1))
|
val jmm = hex(jmmv << UInt(1))
|
||||||
val lmm = Cat(Str("0x"), Str(insn(26,7).toUFix, 16))
|
val lmm = Cat(Str("0x"), Str(insn(26,7).toUInt, 16))
|
||||||
|
|
||||||
val laddr = Cat(Str(immv), lparen, x(rs1), rparen)
|
val laddr = Cat(Str(immv), lparen, x(rs1), rparen)
|
||||||
val saddr = Cat(Str(bmmv), lparen, x(rs1), rparen)
|
val saddr = Cat(Str(bmmv), lparen, x(rs1), rparen)
|
||||||
@ -334,8 +334,8 @@ object Disassemble
|
|||||||
val opts = Seq(r0, r1, r2, f1, f2, f3, fx, xf1, xf2, z, i, b, j, l, ld, st,
|
val opts = Seq(r0, r1, r2, f1, f2, f3, fx, xf1, xf2, z, i, b, j, l, ld, st,
|
||||||
fld, fst, amo)
|
fld, fst, amo)
|
||||||
val maxLen = opts.map(_.getWidth).reduce(_ max _)
|
val maxLen = opts.map(_.getWidth).reduce(_ max _)
|
||||||
val padded = opts.map(x => x << UFix(maxLen - x.getWidth))
|
val padded = opts.map(x => x.toUInt << UInt(maxLen - x.getWidth))
|
||||||
AVec(padded)(fmt)
|
AVec(padded)(fmt.toUInt)
|
||||||
}
|
}
|
||||||
|
|
||||||
private def FMT_R0 = Bits(0, 5)
|
private def FMT_R0 = Bits(0, 5)
|
||||||
|
@ -8,37 +8,37 @@ class MultiplierReq(implicit conf: RocketConfiguration) extends Bundle {
|
|||||||
val dw = Bits(width = SZ_DW)
|
val dw = Bits(width = SZ_DW)
|
||||||
val in1 = Bits(width = conf.xprlen)
|
val in1 = Bits(width = conf.xprlen)
|
||||||
val in2 = Bits(width = conf.xprlen)
|
val in2 = Bits(width = conf.xprlen)
|
||||||
val tag = UFix(width = conf.nxprbits)
|
val tag = UInt(width = conf.nxprbits)
|
||||||
|
|
||||||
override def clone = new MultiplierReq().asInstanceOf[this.type]
|
override def clone = new MultiplierReq().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiplierResp(implicit conf: RocketConfiguration) extends Bundle {
|
class MultiplierResp(implicit conf: RocketConfiguration) extends Bundle {
|
||||||
val data = Bits(width = conf.xprlen)
|
val data = Bits(width = conf.xprlen)
|
||||||
val tag = UFix(width = conf.nxprbits)
|
val tag = UInt(width = conf.nxprbits)
|
||||||
|
|
||||||
override def clone = new MultiplierResp().asInstanceOf[this.type]
|
override def clone = new MultiplierResp().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiplierIO(implicit conf: RocketConfiguration) extends Bundle {
|
class MultiplierIO(implicit conf: RocketConfiguration) extends Bundle {
|
||||||
val req = new FIFOIO()(new MultiplierReq).flip
|
val req = Decoupled(new MultiplierReq).flip
|
||||||
val kill = Bool(INPUT)
|
val kill = Bool(INPUT)
|
||||||
val resp = new FIFOIO()(new MultiplierResp)
|
val resp = Decoupled(new MultiplierResp)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Multiplier(unroll: Int = 1, earlyOut: Boolean = false)(implicit conf: RocketConfiguration) extends Component {
|
class Multiplier(unroll: Int = 1, earlyOut: Boolean = false)(implicit conf: RocketConfiguration) extends Module {
|
||||||
val io = new MultiplierIO
|
val io = new MultiplierIO
|
||||||
|
|
||||||
val w0 = io.req.bits.in1.getWidth
|
val w0 = io.req.bits.in1.getWidth
|
||||||
val w = (w0+1+unroll-1)/unroll*unroll
|
val w = (w0+1+unroll-1)/unroll*unroll
|
||||||
val cycles = w/unroll
|
val cycles = w/unroll
|
||||||
|
|
||||||
val r_val = Reg(resetVal = Bool(false));
|
val r_val = RegReset(Bool(false))
|
||||||
val r_prod= Reg { Bits(width = w*2) }
|
val r_prod = Reg(Bits(width = w*2))
|
||||||
val r_lsb = Reg { Bits() }
|
val r_lsb = Reg(Bits())
|
||||||
val r_cnt = Reg { UFix(width = log2Up(cycles+1)) }
|
val r_cnt = Reg(UInt(width = log2Up(cycles+1)))
|
||||||
val r_req = Reg{new MultiplierReq}
|
val r_req = Reg(new MultiplierReq)
|
||||||
val r_lhs = Reg{Bits(width = w0+1)}
|
val r_lhs = Reg(Bits(width = w0+1))
|
||||||
|
|
||||||
val dw = io.req.bits.dw
|
val dw = io.req.bits.dw
|
||||||
val fn = io.req.bits.fn
|
val fn = io.req.bits.fn
|
||||||
@ -55,7 +55,7 @@ class Multiplier(unroll: Int = 1, earlyOut: Boolean = false)(implicit conf: Rock
|
|||||||
|
|
||||||
when (io.req.fire()) {
|
when (io.req.fire()) {
|
||||||
r_val := Bool(true)
|
r_val := Bool(true)
|
||||||
r_cnt := UFix(0, log2Up(cycles+1))
|
r_cnt := UInt(0, log2Up(cycles+1))
|
||||||
r_req := io.req.bits
|
r_req := io.req.bits
|
||||||
r_lhs := lhs_in
|
r_lhs := lhs_in
|
||||||
r_prod:= rhs_in
|
r_prod:= rhs_in
|
||||||
@ -65,21 +65,21 @@ class Multiplier(unroll: Int = 1, earlyOut: Boolean = false)(implicit conf: Rock
|
|||||||
r_val := Bool(false)
|
r_val := Bool(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
val eOutDist = (UFix(cycles)-r_cnt)*UFix(unroll)
|
val eOutDist = (UInt(cycles)-r_cnt)*UInt(unroll)
|
||||||
val outShift = Mux(isMulFN(r_req.fn, FN_MUL), UFix(0), Mux(r_req.dw === DW_64, UFix(64), UFix(32)))
|
val outShift = Mux(isMulFN(r_req.fn, FN_MUL), UInt(0), Mux(r_req.dw === DW_64, UInt(64), UInt(32)))
|
||||||
val shiftDist = Mux(r_cnt === UFix(cycles), outShift, eOutDist)
|
val shiftDist = Mux(r_cnt === UInt(cycles), outShift, eOutDist)
|
||||||
val eOutMask = (UFix(1) << eOutDist) - UFix(1)
|
val eOutMask = (UInt(1) << eOutDist) - UInt(1)
|
||||||
val eOut = r_cnt != UFix(0) && Bool(earlyOut) && !((r_prod(w-1,0) ^ r_lsb.toFix) & eOutMask).orR
|
val eOut = r_cnt != UInt(0) && Bool(earlyOut) && !((r_prod(w-1,0) ^ r_lsb.toSInt) & eOutMask).orR
|
||||||
val shift = r_prod.toFix >> shiftDist
|
val shift = r_prod.toSInt >> shiftDist
|
||||||
|
|
||||||
val sum = r_prod(2*w-1,w).toFix + r_prod(unroll-1,0).toFix * r_lhs.toFix + Mux(r_lsb, r_lhs.toFix, Fix(0))
|
val sum = r_prod(2*w-1,w).toSInt + r_prod(unroll-1,0).toSInt * r_lhs.toSInt + Mux(r_lsb.toBool, r_lhs.toSInt, SInt(0))
|
||||||
when (r_val && (r_cnt != UFix(cycles))) {
|
when (r_val && (r_cnt != UInt(cycles))) {
|
||||||
r_lsb := r_prod(unroll-1)
|
r_lsb := r_prod(unroll-1)
|
||||||
r_prod := Cat(sum, r_prod(w-1,unroll)).toFix
|
r_prod := Cat(sum, r_prod(w-1,unroll)).toSInt
|
||||||
r_cnt := r_cnt + UFix(1)
|
r_cnt := r_cnt + UInt(1)
|
||||||
when (eOut) {
|
when (eOut) {
|
||||||
r_prod := shift
|
r_prod := shift
|
||||||
r_cnt := UFix(cycles)
|
r_cnt := UInt(cycles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,5 +89,5 @@ class Multiplier(unroll: Int = 1, earlyOut: Boolean = false)(implicit conf: Rock
|
|||||||
io.req.ready := !r_val
|
io.req.ready := !r_val
|
||||||
io.resp.bits := r_req
|
io.resp.bits := r_req
|
||||||
io.resp.bits.data := Mux(r_req.dw === DW_64, out64, out32)
|
io.resp.bits.data := Mux(r_req.dw === DW_64, out64, out32)
|
||||||
io.resp.valid := r_val && (r_cnt === UFix(cycles))
|
io.resp.valid := r_val && (r_cnt === UInt(cycles))
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ case class DCacheConfig(sets: Int, ways: Int,
|
|||||||
|
|
||||||
abstract class ReplacementPolicy
|
abstract class ReplacementPolicy
|
||||||
{
|
{
|
||||||
def way: UFix
|
def way: UInt
|
||||||
def miss: Unit
|
def miss: Unit
|
||||||
def hit: Unit
|
def hit: Unit
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ class RandomReplacement(implicit conf: DCacheConfig) extends ReplacementPolicy
|
|||||||
replace := Bool(false)
|
replace := Bool(false)
|
||||||
val lfsr = LFSR16(replace)
|
val lfsr = LFSR16(replace)
|
||||||
|
|
||||||
def way = if (conf.dm) UFix(0) else lfsr(conf.waybits-1,0)
|
def way = if (conf.dm) UInt(0) else lfsr(conf.waybits-1,0)
|
||||||
def miss = replace := Bool(true)
|
def miss = replace := Bool(true)
|
||||||
def hit = {}
|
def hit = {}
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ class MSHRReq(implicit conf: DCacheConfig) extends HellaCacheReq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Replay(implicit conf: DCacheConfig) extends HellaCacheReq {
|
class Replay(implicit conf: DCacheConfig) extends HellaCacheReq {
|
||||||
val sdq_id = UFix(width = log2Up(conf.nsdq))
|
val sdq_id = UInt(width = log2Up(conf.nsdq))
|
||||||
|
|
||||||
override def clone = new Replay().asInstanceOf[this.type]
|
override def clone = new Replay().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
@ -139,13 +139,13 @@ class WritebackReq(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exten
|
|||||||
val idx = Bits(width = conf.idxbits)
|
val idx = Bits(width = conf.idxbits)
|
||||||
val way_en = Bits(width = conf.ways)
|
val way_en = Bits(width = conf.ways)
|
||||||
val client_xact_id = Bits(width = tl.clientXactIdBits)
|
val client_xact_id = Bits(width = tl.clientXactIdBits)
|
||||||
val r_type = UFix(width = tl.co.releaseTypeBits)
|
val r_type = UInt(width = tl.co.releaseTypeWidth)
|
||||||
|
|
||||||
override def clone = new WritebackReq().asInstanceOf[this.type]
|
override def clone = new WritebackReq().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
object MetaData {
|
object MetaData {
|
||||||
def apply(tag: Bits, state: UFix)(implicit conf: DCacheConfig) = {
|
def apply(tag: Bits, state: UInt)(implicit conf: DCacheConfig) = {
|
||||||
val meta = new MetaData
|
val meta = new MetaData
|
||||||
meta.state := state
|
meta.state := state
|
||||||
meta.tag := tag
|
meta.tag := tag
|
||||||
@ -153,14 +153,14 @@ object MetaData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
class MetaData(implicit conf: DCacheConfig) extends Bundle {
|
class MetaData(implicit conf: DCacheConfig) extends Bundle {
|
||||||
val state = UFix(width = conf.statebits)
|
val state = UInt(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]
|
||||||
}
|
}
|
||||||
|
|
||||||
class MetaReadReq(implicit conf: DCacheConfig) extends Bundle {
|
class MetaReadReq(implicit conf: DCacheConfig) extends Bundle {
|
||||||
val addr = UFix(width = conf.paddrbits)
|
val addr = UInt(width = conf.paddrbits)
|
||||||
|
|
||||||
override def clone = new MetaReadReq().asInstanceOf[this.type]
|
override def clone = new MetaReadReq().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
@ -173,7 +173,7 @@ class MetaWriteReq(implicit conf: DCacheConfig) extends Bundle {
|
|||||||
override def clone = new MetaWriteReq().asInstanceOf[this.type]
|
override def clone = new MetaWriteReq().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Component {
|
class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
||||||
implicit val ln = tl.ln
|
implicit val ln = tl.ln
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req_pri_val = Bool(INPUT)
|
val req_pri_val = Bool(INPUT)
|
||||||
@ -181,41 +181,41 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
val req_sec_val = Bool(INPUT)
|
val req_sec_val = Bool(INPUT)
|
||||||
val req_sec_rdy = Bool(OUTPUT)
|
val req_sec_rdy = Bool(OUTPUT)
|
||||||
val req_bits = new MSHRReq().asInput
|
val req_bits = new MSHRReq().asInput
|
||||||
val req_sdq_id = UFix(INPUT, log2Up(conf.nsdq))
|
val req_sdq_id = UInt(INPUT, log2Up(conf.nsdq))
|
||||||
|
|
||||||
val idx_match = Bool(OUTPUT)
|
val idx_match = Bool(OUTPUT)
|
||||||
val tag = Bits(OUTPUT, conf.tagbits)
|
val tag = Bits(OUTPUT, conf.tagbits)
|
||||||
|
|
||||||
val mem_req = (new FIFOIO) { new Acquire }
|
val mem_req = Decoupled(new Acquire)
|
||||||
val mem_resp = new DataWriteReq().asOutput
|
val mem_resp = new DataWriteReq().asOutput
|
||||||
val meta_read = (new FIFOIO) { new MetaReadReq }
|
val meta_read = Decoupled(new MetaReadReq)
|
||||||
val meta_write = (new FIFOIO) { new MetaWriteReq }
|
val meta_write = Decoupled(new MetaWriteReq)
|
||||||
val replay = (new FIFOIO) { new Replay() }
|
val replay = Decoupled(new Replay())
|
||||||
val mem_grant = (new PipeIO) { (new LogicalNetworkIO) {new Grant} }.flip
|
val mem_grant = Valid((new LogicalNetworkIO) {new Grant} ).flip
|
||||||
val mem_finish = (new FIFOIO) { (new LogicalNetworkIO) {new GrantAck} }
|
val mem_finish = Decoupled((new LogicalNetworkIO) {new GrantAck} )
|
||||||
val wb_req = (new FIFOIO) { new WritebackReq }
|
val wb_req = Decoupled(new WritebackReq)
|
||||||
val probe_rdy = Bool(OUTPUT)
|
val probe_rdy = Bool(OUTPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
val s_invalid :: s_wb_req :: s_wb_resp :: s_meta_clear :: s_refill_req :: s_refill_resp :: s_meta_write_req :: s_meta_write_resp :: s_drain_rpq :: Nil = Enum(9) { UFix() }
|
val s_invalid :: s_wb_req :: s_wb_resp :: s_meta_clear :: s_refill_req :: s_refill_resp :: s_meta_write_req :: s_meta_write_resp :: s_drain_rpq :: Nil = Enum(9) { UInt() }
|
||||||
val state = Reg(resetVal = s_invalid)
|
val state = RegReset(s_invalid)
|
||||||
|
|
||||||
val acquire_type = Reg { UFix() }
|
val acquire_type = Reg(UInt())
|
||||||
val release_type = Reg { UFix() }
|
val release_type = Reg(UInt())
|
||||||
val line_state = Reg { UFix() }
|
val line_state = Reg(UInt())
|
||||||
val refill_count = Reg { UFix(width = log2Up(REFILL_CYCLES)) }
|
val refill_count = Reg(UInt(width = log2Up(REFILL_CYCLES)))
|
||||||
val req = Reg { new MSHRReq() }
|
val req = Reg(new MSHRReq())
|
||||||
|
|
||||||
val req_cmd = io.req_bits.cmd
|
val req_cmd = io.req_bits.cmd
|
||||||
val req_idx = req.addr(conf.untagbits-1,conf.offbits)
|
val req_idx = req.addr(conf.untagbits-1,conf.offbits)
|
||||||
val idx_match = req_idx === io.req_bits.addr(conf.untagbits-1,conf.offbits)
|
val idx_match = req_idx === io.req_bits.addr(conf.untagbits-1,conf.offbits)
|
||||||
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) && !tl.co.needsTransactionOnSecondaryMiss(req_cmd, io.mem_req.bits))
|
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) && !tl.co.needsTransactionOnSecondaryMiss(req_cmd, io.mem_req.bits))
|
||||||
|
|
||||||
val reply = io.mem_grant.valid && io.mem_grant.bits.payload.client_xact_id === UFix(id)
|
val reply = io.mem_grant.valid && io.mem_grant.bits.payload.client_xact_id === UInt(id)
|
||||||
val refill_done = reply && refill_count.andR
|
val refill_done = reply && refill_count.andR
|
||||||
val wb_done = reply && (state === s_wb_resp)
|
val wb_done = reply && (state === s_wb_resp)
|
||||||
|
|
||||||
val rpq = (new Queue(conf.nrpq)) { new Replay }
|
val rpq = Module(new Queue(new Replay, conf.nrpq))
|
||||||
rpq.io.enq.valid := (io.req_pri_val && io.req_pri_rdy || io.req_sec_val && sec_rdy) && !isPrefetch(req_cmd)
|
rpq.io.enq.valid := (io.req_pri_val && io.req_pri_rdy || io.req_sec_val && sec_rdy) && !isPrefetch(req_cmd)
|
||||||
rpq.io.enq.bits := io.req_bits
|
rpq.io.enq.bits := io.req_bits
|
||||||
rpq.io.enq.bits.sdq_id := io.req_sdq_id
|
rpq.io.enq.bits.sdq_id := io.req_sdq_id
|
||||||
@ -234,7 +234,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
when (state === s_refill_resp) {
|
when (state === s_refill_resp) {
|
||||||
when (refill_done) { state := s_meta_write_req }
|
when (refill_done) { state := s_meta_write_req }
|
||||||
when (reply) {
|
when (reply) {
|
||||||
refill_count := refill_count + UFix(1)
|
refill_count := refill_count + UInt(1)
|
||||||
line_state := tl.co.newStateOnGrant(io.mem_grant.bits.payload, io.mem_req.bits)
|
line_state := tl.co.newStateOnGrant(io.mem_grant.bits.payload, io.mem_req.bits)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,7 +256,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
}
|
}
|
||||||
when (io.req_pri_val && io.req_pri_rdy) {
|
when (io.req_pri_val && io.req_pri_rdy) {
|
||||||
line_state := tl.co.newStateOnFlush()
|
line_state := tl.co.newStateOnFlush()
|
||||||
refill_count := UFix(0)
|
refill_count := UInt(0)
|
||||||
acquire_type := tl.co.getAcquireTypeOnPrimaryMiss(req_cmd, tl.co.newStateOnFlush())
|
acquire_type := tl.co.getAcquireTypeOnPrimaryMiss(req_cmd, tl.co.newStateOnFlush())
|
||||||
release_type := tl.co.getReleaseTypeOnVoluntaryWriteback() //TODO downgrades etc
|
release_type := tl.co.getReleaseTypeOnVoluntaryWriteback() //TODO downgrades etc
|
||||||
req := io.req_bits
|
req := io.req_bits
|
||||||
@ -273,7 +273,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val ackq = (new Queue(1)) { (new LogicalNetworkIO){new GrantAck} }
|
val ackq = Module(new Queue((new LogicalNetworkIO){new GrantAck}, 1))
|
||||||
ackq.io.enq.valid := (wb_done || refill_done) && tl.co.requiresAck(io.mem_grant.bits.payload)
|
ackq.io.enq.valid := (wb_done || refill_done) && tl.co.requiresAck(io.mem_grant.bits.payload)
|
||||||
ackq.io.enq.bits.payload.master_xact_id := io.mem_grant.bits.payload.master_xact_id
|
ackq.io.enq.bits.payload.master_xact_id := io.mem_grant.bits.payload.master_xact_id
|
||||||
ackq.io.enq.bits.header.dst := io.mem_grant.bits.header.src
|
ackq.io.enq.bits.header.dst := io.mem_grant.bits.header.src
|
||||||
@ -289,7 +289,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
io.req_pri_rdy := state === s_invalid
|
io.req_pri_rdy := state === s_invalid
|
||||||
io.req_sec_rdy := sec_rdy && rpq.io.enq.ready
|
io.req_sec_rdy := sec_rdy && rpq.io.enq.ready
|
||||||
|
|
||||||
val meta_hazard = Reg(resetVal = UFix(0,2))
|
val meta_hazard = RegReset(UInt(0,2))
|
||||||
when (meta_hazard != 0) { meta_hazard := meta_hazard + 1 }
|
when (meta_hazard != 0) { meta_hazard := meta_hazard + 1 }
|
||||||
when (io.meta_write.fire()) { meta_hazard := 1 }
|
when (io.meta_write.fire()) { meta_hazard := 1 }
|
||||||
io.probe_rdy := !idx_match || (state != s_wb_req && state != s_wb_resp && state != s_meta_clear && meta_hazard === 0)
|
io.probe_rdy := !idx_match || (state != s_wb_req && state != s_wb_resp && state != s_meta_clear && meta_hazard === 0)
|
||||||
@ -309,7 +309,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
|
|
||||||
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.a_type := acquire_type
|
io.mem_req.bits.a_type := acquire_type
|
||||||
io.mem_req.bits.addr := Cat(io.tag, req_idx).toUFix
|
io.mem_req.bits.addr := Cat(io.tag, req_idx).toUInt
|
||||||
io.mem_req.bits.client_xact_id := Bits(id)
|
io.mem_req.bits.client_xact_id := Bits(id)
|
||||||
io.mem_finish <> ackq.io.deq
|
io.mem_finish <> ackq.io.deq
|
||||||
io.mem_req.bits.client_xact_id := Bits(id)
|
io.mem_req.bits.client_xact_id := Bits(id)
|
||||||
@ -320,7 +320,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
io.replay.valid := state === s_drain_rpq && rpq.io.deq.valid
|
io.replay.valid := state === s_drain_rpq && rpq.io.deq.valid
|
||||||
io.replay.bits := rpq.io.deq.bits
|
io.replay.bits := rpq.io.deq.bits
|
||||||
io.replay.bits.phys := Bool(true)
|
io.replay.bits.phys := Bool(true)
|
||||||
io.replay.bits.addr := Cat(io.tag, req_idx, rpq.io.deq.bits.addr(conf.offbits-1,0)).toUFix
|
io.replay.bits.addr := Cat(io.tag, req_idx, rpq.io.deq.bits.addr(conf.offbits-1,0)).toUInt
|
||||||
|
|
||||||
when (!io.meta_read.ready) {
|
when (!io.meta_read.ready) {
|
||||||
rpq.io.deq.ready := Bool(false)
|
rpq.io.deq.ready := Bool(false)
|
||||||
@ -328,45 +328,45 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MSHRFile(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Component {
|
class MSHRFile(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
||||||
implicit val ln = tl.ln
|
implicit val ln = tl.ln
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = (new FIFOIO) { new MSHRReq }.flip
|
val req = Decoupled(new MSHRReq).flip
|
||||||
val secondary_miss = Bool(OUTPUT)
|
val secondary_miss = Bool(OUTPUT)
|
||||||
|
|
||||||
val mem_req = (new FIFOIO) { new Acquire }
|
val mem_req = Decoupled(new Acquire)
|
||||||
val mem_resp = new DataWriteReq().asOutput
|
val mem_resp = new DataWriteReq().asOutput
|
||||||
val meta_read = (new FIFOIO) { new MetaReadReq }
|
val meta_read = Decoupled(new MetaReadReq)
|
||||||
val meta_write = (new FIFOIO) { new MetaWriteReq }
|
val meta_write = Decoupled(new MetaWriteReq)
|
||||||
val replay = (new FIFOIO) { new Replay }
|
val replay = Decoupled(new Replay)
|
||||||
val mem_grant = (new PipeIO) { (new LogicalNetworkIO){new Grant} }.flip
|
val mem_grant = Valid((new LogicalNetworkIO){new Grant}).flip
|
||||||
val mem_finish = (new FIFOIO) { (new LogicalNetworkIO){new GrantAck} }
|
val mem_finish = Decoupled((new LogicalNetworkIO){new GrantAck})
|
||||||
val wb_req = (new FIFOIO) { new WritebackReq }
|
val wb_req = Decoupled(new WritebackReq)
|
||||||
|
|
||||||
val probe_rdy = Bool(OUTPUT)
|
val probe_rdy = Bool(OUTPUT)
|
||||||
val fence_rdy = Bool(OUTPUT)
|
val fence_rdy = Bool(OUTPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sdq_val = Reg(resetVal = Bits(0, conf.nsdq))
|
val sdq_val = RegReset(Bits(0, conf.nsdq))
|
||||||
val sdq_alloc_id = PriorityEncoder(~sdq_val(conf.nsdq-1,0))
|
val sdq_alloc_id = PriorityEncoder(~sdq_val(conf.nsdq-1,0))
|
||||||
val sdq_rdy = !sdq_val.andR
|
val sdq_rdy = !sdq_val.andR
|
||||||
val sdq_enq = io.req.valid && io.req.ready && isWrite(io.req.bits.cmd)
|
val sdq_enq = io.req.valid && io.req.ready && isWrite(io.req.bits.cmd)
|
||||||
val sdq = Mem(conf.nsdq) { io.req.bits.data.clone }
|
val sdq = Mem(io.req.bits.data, conf.nsdq)
|
||||||
when (sdq_enq) { sdq(sdq_alloc_id) := io.req.bits.data }
|
when (sdq_enq) { sdq(sdq_alloc_id) := io.req.bits.data }
|
||||||
|
|
||||||
val idxMatch = Vec(conf.nmshr) { Bool() }
|
val idxMatch = Vec.fill(conf.nmshr){Bool()}
|
||||||
val tagList = Vec(conf.nmshr) { Bits() }
|
val tagList = Vec.fill(conf.nmshr){Bits()}
|
||||||
val tag_match = Mux1H(idxMatch, tagList) === io.req.bits.addr >> conf.untagbits
|
val tag_match = Mux1H(idxMatch, tagList) === io.req.bits.addr >> conf.untagbits
|
||||||
|
|
||||||
val wbTagList = Vec(conf.nmshr) { Bits() }
|
val wbTagList = Vec.fill(conf.nmshr){Bits()}
|
||||||
val memRespMux = Vec(conf.nmshr) { new DataWriteReq }
|
val memRespMux = Vec.fill(conf.nmshr){new DataWriteReq}
|
||||||
val meta_read_arb = (new Arbiter(conf.nmshr)) { new MetaReadReq }
|
val meta_read_arb = Module(new Arbiter(new MetaReadReq, conf.nmshr))
|
||||||
val meta_write_arb = (new Arbiter(conf.nmshr)) { new MetaWriteReq }
|
val meta_write_arb = Module(new Arbiter(new MetaWriteReq, conf.nmshr))
|
||||||
val mem_req_arb = (new Arbiter(conf.nmshr)) { new Acquire }
|
val mem_req_arb = Module(new Arbiter(new Acquire, conf.nmshr))
|
||||||
val mem_finish_arb = (new Arbiter(conf.nmshr)) { (new LogicalNetworkIO){new GrantAck} }
|
val mem_finish_arb = Module(new Arbiter((new LogicalNetworkIO){new GrantAck}, conf.nmshr))
|
||||||
val wb_req_arb = (new Arbiter(conf.nmshr)) { new WritebackReq }
|
val wb_req_arb = Module(new Arbiter(new WritebackReq, conf.nmshr))
|
||||||
val replay_arb = (new Arbiter(conf.nmshr)) { new Replay() }
|
val replay_arb = Module(new Arbiter(new Replay, conf.nmshr))
|
||||||
val alloc_arb = (new Arbiter(conf.nmshr)) { Bool() }
|
val alloc_arb = Module(new Arbiter(Bool(), conf.nmshr))
|
||||||
|
|
||||||
var idx_match = Bool(false)
|
var idx_match = Bool(false)
|
||||||
var pri_rdy = Bool(false)
|
var pri_rdy = Bool(false)
|
||||||
@ -376,7 +376,7 @@ class MSHRFile(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends C
|
|||||||
io.probe_rdy := true
|
io.probe_rdy := true
|
||||||
|
|
||||||
for (i <- 0 to conf.nmshr-1) {
|
for (i <- 0 to conf.nmshr-1) {
|
||||||
val mshr = new MSHR(i)
|
val mshr = Module(new MSHR(i))
|
||||||
|
|
||||||
idxMatch(i) := mshr.io.idx_match
|
idxMatch(i) := mshr.io.idx_match
|
||||||
tagList(i) := mshr.io.tag
|
tagList(i) := mshr.io.tag
|
||||||
@ -424,29 +424,29 @@ class MSHRFile(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends C
|
|||||||
io.replay <> replay_arb.io.out
|
io.replay <> replay_arb.io.out
|
||||||
|
|
||||||
when (io.replay.valid || sdq_enq) {
|
when (io.replay.valid || sdq_enq) {
|
||||||
sdq_val := sdq_val & ~(UFixToOH(io.replay.bits.sdq_id) & Fill(conf.nsdq, free_sdq)) |
|
sdq_val := sdq_val & ~(UIntToOH(io.replay.bits.sdq_id) & Fill(conf.nsdq, free_sdq)) |
|
||||||
PriorityEncoderOH(~sdq_val(conf.nsdq-1,0)) & Fill(conf.nsdq, sdq_enq)
|
PriorityEncoderOH(~sdq_val(conf.nsdq-1,0)) & Fill(conf.nsdq, sdq_enq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class WritebackUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Component {
|
class WritebackUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = (new FIFOIO) { new WritebackReq() }.flip
|
val req = Decoupled(new WritebackReq()).flip
|
||||||
val probe = (new FIFOIO) { new WritebackReq() }.flip
|
val probe = Decoupled(new WritebackReq()).flip
|
||||||
val meta_read = (new FIFOIO) { new MetaReadReq }
|
val meta_read = Decoupled(new MetaReadReq)
|
||||||
val data_req = (new FIFOIO) { new DataReadReq() }
|
val data_req = Decoupled(new DataReadReq())
|
||||||
val data_resp = Bits(INPUT, conf.bitsperrow)
|
val data_resp = Bits(INPUT, conf.bitsperrow)
|
||||||
val release = (new FIFOIO) { new Release }
|
val release = Decoupled(new Release)
|
||||||
val release_data = (new FIFOIO) { new ReleaseData }
|
val release_data = Decoupled(new ReleaseData)
|
||||||
}
|
}
|
||||||
|
|
||||||
val valid = Reg(resetVal = Bool(false))
|
val valid = RegReset(Bool(false))
|
||||||
val r1_data_req_fired = Reg(resetVal = Bool(false))
|
val r1_data_req_fired = RegReset(Bool(false))
|
||||||
val r2_data_req_fired = Reg(resetVal = Bool(false))
|
val r2_data_req_fired = RegReset(Bool(false))
|
||||||
val cmd_sent = Reg{Bool()}
|
val cmd_sent = Reg(Bool())
|
||||||
val cnt = Reg{UFix(width = log2Up(REFILL_CYCLES+1))}
|
val cnt = Reg(UInt(width = log2Up(REFILL_CYCLES+1)))
|
||||||
val req = Reg{new WritebackReq}
|
val req = Reg(new WritebackReq)
|
||||||
|
|
||||||
when (valid) {
|
when (valid) {
|
||||||
r1_data_req_fired := false
|
r1_data_req_fired := false
|
||||||
@ -459,7 +459,7 @@ class WritebackUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
when (r2_data_req_fired && !io.release_data.ready) {
|
when (r2_data_req_fired && !io.release_data.ready) {
|
||||||
r1_data_req_fired := false
|
r1_data_req_fired := false
|
||||||
r2_data_req_fired := false
|
r2_data_req_fired := false
|
||||||
cnt := cnt - Mux[UFix](r1_data_req_fired, 2, 1)
|
cnt := cnt - Mux[UInt](r1_data_req_fired, 2, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
when (!r1_data_req_fired && !r2_data_req_fired && cmd_sent && cnt === REFILL_CYCLES) {
|
when (!r1_data_req_fired && !r2_data_req_fired && cmd_sent && cnt === REFILL_CYCLES) {
|
||||||
@ -483,7 +483,7 @@ class WritebackUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
req := io.req.bits
|
req := io.req.bits
|
||||||
}
|
}
|
||||||
|
|
||||||
val fire = valid && cnt < UFix(REFILL_CYCLES)
|
val fire = valid && cnt < UInt(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.data_req.valid := fire
|
||||||
@ -492,9 +492,9 @@ class WritebackUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
|
|
||||||
io.release.valid := valid && !cmd_sent
|
io.release.valid := valid && !cmd_sent
|
||||||
io.release.bits.r_type := req.r_type
|
io.release.bits.r_type := req.r_type
|
||||||
io.release.bits.addr := Cat(req.tag, req.idx).toUFix
|
io.release.bits.addr := Cat(req.tag, req.idx).toUInt
|
||||||
io.release.bits.client_xact_id := req.client_xact_id
|
io.release.bits.client_xact_id := req.client_xact_id
|
||||||
io.release.bits.master_xact_id := UFix(0)
|
io.release.bits.master_xact_id := UInt(0)
|
||||||
io.release_data.valid := r2_data_req_fired
|
io.release_data.valid := r2_data_req_fired
|
||||||
io.release_data.bits.data := io.data_resp
|
io.release_data.bits.data := io.data_resp
|
||||||
|
|
||||||
@ -502,23 +502,23 @@ class WritebackUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
io.meta_read.bits.addr := io.release.bits.addr << conf.offbits
|
io.meta_read.bits.addr := io.release.bits.addr << conf.offbits
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProbeUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Component {
|
class ProbeUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = (new FIFOIO) { new InternalProbe }.flip
|
val req = Decoupled(new InternalProbe).flip
|
||||||
val rep = (new FIFOIO) { new Release }
|
val rep = Decoupled(new Release)
|
||||||
val meta_read = (new FIFOIO) { new MetaReadReq }
|
val meta_read = Decoupled(new MetaReadReq)
|
||||||
val meta_write = (new FIFOIO) { new MetaWriteReq }
|
val meta_write = Decoupled(new MetaWriteReq)
|
||||||
val wb_req = (new FIFOIO) { new WritebackReq }
|
val wb_req = Decoupled(new WritebackReq)
|
||||||
val way_en = Bits(INPUT, conf.ways)
|
val way_en = Bits(INPUT, conf.ways)
|
||||||
val mshr_rdy = Bool(INPUT)
|
val mshr_rdy = Bool(INPUT)
|
||||||
val line_state = UFix(INPUT, 2)
|
val line_state = UInt(INPUT, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
val s_reset :: s_invalid :: s_meta_read :: s_meta_resp :: s_mshr_req :: s_release :: s_writeback_req :: s_writeback_resp :: s_meta_write :: Nil = Enum(9) { UFix() }
|
val s_reset :: s_invalid :: s_meta_read :: s_meta_resp :: s_mshr_req :: s_release :: s_writeback_req :: s_writeback_resp :: s_meta_write :: Nil = Enum(9) { UInt() }
|
||||||
val state = Reg(resetVal = s_invalid)
|
val state = RegReset(s_invalid)
|
||||||
val line_state = Reg() { UFix() }
|
val line_state = Reg(UInt())
|
||||||
val way_en = Reg() { Bits() }
|
val way_en = Reg(Bits())
|
||||||
val req = Reg() { new InternalProbe }
|
val req = Reg(new InternalProbe)
|
||||||
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) {
|
||||||
@ -561,40 +561,40 @@ class ProbeUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
io.rep.bits := Release(tl.co.getReleaseTypeOnProbe(req, Mux(hit, line_state, tl.co.newStateOnFlush)), req.addr, req.client_xact_id, req.master_xact_id)
|
io.rep.bits := Release(tl.co.getReleaseTypeOnProbe(req, Mux(hit, line_state, tl.co.newStateOnFlush)), req.addr, req.client_xact_id, req.master_xact_id)
|
||||||
|
|
||||||
io.meta_read.valid := state === s_meta_read
|
io.meta_read.valid := state === s_meta_read
|
||||||
io.meta_read.bits.addr := req.addr << UFix(conf.offbits)
|
io.meta_read.bits.addr := req.addr << UInt(conf.offbits)
|
||||||
|
|
||||||
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
|
||||||
io.meta_write.bits.data.state := tl.co.newStateOnProbe(req, line_state)
|
io.meta_write.bits.data.state := tl.co.newStateOnProbe(req, line_state)
|
||||||
io.meta_write.bits.data.tag := req.addr >> UFix(conf.idxbits)
|
io.meta_write.bits.data.tag := req.addr >> UInt(conf.idxbits)
|
||||||
|
|
||||||
io.wb_req.valid := state === s_writeback_req
|
io.wb_req.valid := state === s_writeback_req
|
||||||
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.idx := req.addr
|
||||||
io.wb_req.bits.tag := req.addr >> UFix(conf.idxbits)
|
io.wb_req.bits.tag := req.addr >> UInt(conf.idxbits)
|
||||||
io.wb_req.bits.r_type := UFix(0) // DNC
|
io.wb_req.bits.r_type := UInt(0) // DNC
|
||||||
io.wb_req.bits.client_xact_id := UFix(0) // DNC
|
io.wb_req.bits.client_xact_id := UInt(0) // DNC
|
||||||
}
|
}
|
||||||
|
|
||||||
class MetaDataArray(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Component {
|
class MetaDataArray(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val read = (new FIFOIO) { new MetaReadReq }.flip
|
val read = Decoupled(new MetaReadReq).flip
|
||||||
val write = (new FIFOIO) { new MetaWriteReq }.flip
|
val write = Decoupled(new MetaWriteReq).flip
|
||||||
val resp = Vec(conf.ways){ (new MetaData).asOutput }
|
val resp = Vec.fill(conf.ways){(new MetaData).asOutput}
|
||||||
}
|
}
|
||||||
|
|
||||||
val rst_cnt = Reg(resetVal = UFix(0, log2Up(conf.sets+1)))
|
val rst_cnt = RegReset(UInt(0, log2Up(conf.sets+1)))
|
||||||
val rst = rst_cnt < conf.sets
|
val rst = rst_cnt < conf.sets
|
||||||
when (rst) { rst_cnt := rst_cnt+1 }
|
when (rst) { rst_cnt := rst_cnt+1 }
|
||||||
|
|
||||||
val metabits = io.write.bits.data.state.width + conf.tagbits
|
val metabits = io.write.bits.data.state.width + conf.tagbits
|
||||||
val tags = Mem(conf.sets, seqRead = true) { UFix(width = metabits*conf.ways) }
|
val tags = Mem(UInt(width = metabits*conf.ways), conf.sets, seqRead = true)
|
||||||
|
|
||||||
when (rst || io.write.valid) {
|
when (rst || io.write.valid) {
|
||||||
val addr = Mux(rst, rst_cnt, io.write.bits.idx)
|
val addr = Mux(rst, rst_cnt, io.write.bits.idx)
|
||||||
val data = Cat(Mux(rst, tl.co.newStateOnFlush, io.write.bits.data.state), io.write.bits.data.tag)
|
val data = Cat(Mux(rst, tl.co.newStateOnFlush, io.write.bits.data.state), io.write.bits.data.tag)
|
||||||
val mask = Mux(rst, Fix(-1), io.write.bits.way_en)
|
val mask = Mux(rst, SInt(-1), io.write.bits.way_en)
|
||||||
tags.write(addr, Fill(conf.ways, data), FillInterleaved(metabits, mask))
|
tags.write(addr, Fill(conf.ways, data), FillInterleaved(metabits, mask))
|
||||||
}
|
}
|
||||||
val tag = tags(RegEn(io.read.bits.addr >> conf.offbits, io.read.valid))
|
val tag = tags(RegEn(io.read.bits.addr >> conf.offbits, io.read.valid))
|
||||||
@ -609,11 +609,11 @@ class MetaDataArray(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
io.write.ready := !rst
|
io.write.ready := !rst
|
||||||
}
|
}
|
||||||
|
|
||||||
class DataArray(implicit conf: DCacheConfig) extends Component {
|
class DataArray(implicit conf: DCacheConfig) extends Module {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val read = new FIFOIO()(new DataReadReq).flip
|
val read = Decoupled(new DataReadReq).flip
|
||||||
val write = new FIFOIO()(new DataWriteReq).flip
|
val write = Decoupled(new DataWriteReq).flip
|
||||||
val resp = Vec(conf.ways){ Bits(OUTPUT, conf.bitsperrow) }
|
val resp = Vec.fill(conf.ways){Bits(OUTPUT, conf.bitsperrow)}
|
||||||
}
|
}
|
||||||
|
|
||||||
val waddr = io.write.bits.addr >> conf.ramoffbits
|
val waddr = io.write.bits.addr >> conf.ramoffbits
|
||||||
@ -623,10 +623,10 @@ class DataArray(implicit conf: DCacheConfig) extends Component {
|
|||||||
for (w <- 0 until conf.ways by conf.wordsperrow) {
|
for (w <- 0 until conf.ways by conf.wordsperrow) {
|
||||||
val wway_en = io.write.bits.way_en(w+conf.wordsperrow-1,w)
|
val wway_en = io.write.bits.way_en(w+conf.wordsperrow-1,w)
|
||||||
val rway_en = io.read.bits.way_en(w+conf.wordsperrow-1,w)
|
val rway_en = io.read.bits.way_en(w+conf.wordsperrow-1,w)
|
||||||
val resp = Vec(conf.wordsperrow){Bits(width = conf.bitsperrow)}
|
val resp = Vec.fill(conf.wordsperrow){Bits(width = conf.bitsperrow)}
|
||||||
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=conf.bitsperrow) }
|
val array = Mem(Bits(width=conf.bitsperrow), conf.sets*REFILL_CYCLES, seqRead = true)
|
||||||
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(conf.wordsperrow, io.write.bits.data(conf.encdatabits*(p+1)-1,conf.encdatabits*p))
|
val data = Fill(conf.wordsperrow, io.write.bits.data(conf.encdatabits*(p+1)-1,conf.encdatabits*p))
|
||||||
val mask = FillInterleaved(conf.encdatabits, wway_en)
|
val mask = FillInterleaved(conf.encdatabits, wway_en)
|
||||||
@ -645,7 +645,7 @@ class DataArray(implicit conf: DCacheConfig) extends Component {
|
|||||||
} else {
|
} else {
|
||||||
val wmask = FillInterleaved(conf.encdatabits, 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 array = Mem(conf.sets*REFILL_CYCLES, seqRead = true){ Bits(width=conf.bitsperrow) }
|
val array = Mem(Bits(width=conf.bitsperrow), conf.sets*REFILL_CYCLES, seqRead = true)
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -657,7 +657,7 @@ class DataArray(implicit conf: DCacheConfig) extends Component {
|
|||||||
io.write.ready := Bool(true)
|
io.write.ready := Bool(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
class AMOALU(implicit conf: DCacheConfig) extends Component {
|
class AMOALU(implicit conf: DCacheConfig) extends Module {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val addr = Bits(INPUT, conf.offbits)
|
val addr = Bits(INPUT, conf.offbits)
|
||||||
val cmd = Bits(INPUT, 4)
|
val cmd = Bits(INPUT, 4)
|
||||||
@ -674,8 +674,8 @@ class AMOALU(implicit conf: DCacheConfig) extends Component {
|
|||||||
val min = io.cmd === M_XA_MIN || io.cmd === M_XA_MINU
|
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 word = io.typ === MT_W || io.typ === MT_WU || io.typ === MT_B || io.typ === MT_BU
|
||||||
|
|
||||||
val mask = Fix(-1,64) ^ (io.addr(2) << 31)
|
val mask = SInt(-1,64) ^ (io.addr(2) << 31)
|
||||||
val adder_out = (io.lhs & mask).toUFix + (io.rhs & mask)
|
val adder_out = (io.lhs & mask).toUInt + (io.rhs & mask)
|
||||||
|
|
||||||
val cmp_lhs = Mux(word && !io.addr(2), io.lhs(31), io.lhs(63))
|
val cmp_lhs = Mux(word && !io.addr(2), io.lhs(31), io.lhs(63))
|
||||||
val cmp_rhs = Mux(word && !io.addr(2), io.rhs(31), io.rhs(63))
|
val cmp_rhs = Mux(word && !io.addr(2), io.rhs(31), io.rhs(63))
|
||||||
@ -699,7 +699,7 @@ class HellaCacheReq(implicit conf: DCacheConfig) extends Bundle {
|
|||||||
val kill = Bool()
|
val kill = Bool()
|
||||||
val typ = Bits(width = 3)
|
val typ = Bits(width = 3)
|
||||||
val phys = Bool()
|
val phys = Bool()
|
||||||
val addr = UFix(width = conf.maxaddrbits)
|
val addr = UInt(width = conf.maxaddrbits)
|
||||||
val data = Bits(width = conf.databits)
|
val data = Bits(width = conf.databits)
|
||||||
val tag = Bits(width = conf.reqtagbits)
|
val tag = Bits(width = conf.reqtagbits)
|
||||||
val cmd = Bits(width = 4)
|
val cmd = Bits(width = 4)
|
||||||
@ -715,7 +715,7 @@ class HellaCacheResp(implicit conf: DCacheConfig) extends Bundle {
|
|||||||
val data_subword = Bits(width = conf.databits)
|
val data_subword = Bits(width = conf.databits)
|
||||||
val tag = Bits(width = conf.reqtagbits)
|
val tag = Bits(width = conf.reqtagbits)
|
||||||
val cmd = Bits(width = 4)
|
val cmd = Bits(width = 4)
|
||||||
val addr = UFix(width = conf.maxaddrbits)
|
val addr = UInt(width = conf.maxaddrbits)
|
||||||
val store_data = Bits(width = conf.databits)
|
val store_data = Bits(width = conf.databits)
|
||||||
|
|
||||||
override def clone = new HellaCacheResp().asInstanceOf[this.type]
|
override def clone = new HellaCacheResp().asInstanceOf[this.type]
|
||||||
@ -733,13 +733,13 @@ class HellaCacheExceptions extends Bundle {
|
|||||||
|
|
||||||
// interface between D$ and processor/DTLB
|
// interface between D$ and processor/DTLB
|
||||||
class HellaCacheIO(implicit conf: DCacheConfig) extends Bundle {
|
class HellaCacheIO(implicit conf: DCacheConfig) extends Bundle {
|
||||||
val req = (new FIFOIO){ new HellaCacheReq }
|
val req = Decoupled(new HellaCacheReq)
|
||||||
val resp = (new PipeIO){ new HellaCacheResp }.flip
|
val resp = Valid(new HellaCacheResp).flip
|
||||||
val xcpt = (new HellaCacheExceptions).asInput
|
val xcpt = (new HellaCacheExceptions).asInput
|
||||||
val ptw = (new TLBPTWIO).flip
|
val ptw = (new TLBPTWIO).flip
|
||||||
}
|
}
|
||||||
|
|
||||||
class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Component {
|
class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
||||||
implicit val ln = tl.ln
|
implicit val ln = tl.ln
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val cpu = (new HellaCacheIO).flip
|
val cpu = (new HellaCacheIO).flip
|
||||||
@ -751,37 +751,37 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
val offsetmsb = indexlsb-1
|
val offsetmsb = indexlsb-1
|
||||||
val offsetlsb = log2Up(conf.databytes)
|
val offsetlsb = log2Up(conf.databytes)
|
||||||
|
|
||||||
val wb = new WritebackUnit
|
val wb = Module(new WritebackUnit)
|
||||||
val prober = new ProbeUnit
|
val prober = Module(new ProbeUnit)
|
||||||
val mshrs = new MSHRFile
|
val mshrs = Module(new MSHRFile)
|
||||||
|
|
||||||
io.cpu.req.ready := Bool(true)
|
io.cpu.req.ready := Bool(true)
|
||||||
val s1_valid = Reg(io.cpu.req.fire(), resetVal = Bool(false))
|
val s1_valid = Reg(update=io.cpu.req.fire(), reset=Bool(false))
|
||||||
val s1_req = Reg{io.cpu.req.bits.clone}
|
val s1_req = Reg(io.cpu.req.bits.clone)
|
||||||
val s1_valid_masked = s1_valid && !io.cpu.req.bits.kill
|
val s1_valid_masked = s1_valid && !io.cpu.req.bits.kill
|
||||||
val s1_replay = Reg(resetVal = Bool(false))
|
val s1_replay = RegReset(Bool(false))
|
||||||
val s1_clk_en = Reg{Bool()}
|
val s1_clk_en = Reg(Bool())
|
||||||
|
|
||||||
val s2_valid = Reg(s1_valid_masked, resetVal = Bool(false))
|
val s2_valid = Reg(update=s1_valid_masked, reset=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(update=s1_replay, reset=Bool(false))
|
||||||
val s2_recycle = Bool()
|
val s2_recycle = Bool()
|
||||||
val s2_valid_masked = Bool()
|
val s2_valid_masked = Bool()
|
||||||
|
|
||||||
val s3_valid = Reg(resetVal = Bool(false))
|
val s3_valid = RegReset(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_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)
|
||||||
|
|
||||||
val dtlb = new TLB(8)
|
val dtlb = Module(new TLB(8))
|
||||||
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
|
||||||
dtlb.io.req.bits.asid := UFix(0)
|
dtlb.io.req.bits.asid := UInt(0)
|
||||||
dtlb.io.req.bits.vpn := s1_req.addr >> conf.pgidxbits
|
dtlb.io.req.bits.vpn := s1_req.addr >> conf.pgidxbits
|
||||||
dtlb.io.req.bits.instruction := Bool(false)
|
dtlb.io.req.bits.instruction := Bool(false)
|
||||||
when (!dtlb.io.req.ready && !io.cpu.req.bits.phys) { io.cpu.req.ready := Bool(false) }
|
when (!dtlb.io.req.ready && !io.cpu.req.bits.phys) { io.cpu.req.ready := Bool(false) }
|
||||||
@ -806,14 +806,16 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
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) {
|
||||||
s2_req.addr := s1_addr
|
s2_req.kill := s1_req.kill
|
||||||
s2_req.typ := s1_req.typ
|
s2_req.typ := s1_req.typ
|
||||||
s2_req.cmd := s1_req.cmd
|
s2_req.phys := s1_req.phys
|
||||||
s2_req.tag := s1_req.tag
|
s2_req.addr := s1_addr
|
||||||
when (s1_write) {
|
when (s1_write) {
|
||||||
s2_req.data := Mux(s1_replay, mshrs.io.replay.bits.data, io.cpu.req.bits.data)
|
s2_req.data := Mux(s1_replay, mshrs.io.replay.bits.data, io.cpu.req.bits.data)
|
||||||
}
|
}
|
||||||
when (s1_recycled) { s2_req.data := s1_req.data }
|
when (s1_recycled) { s2_req.data := s1_req.data }
|
||||||
|
s2_req.tag := s1_req.tag
|
||||||
|
s2_req.cmd := s1_req.cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
val misaligned =
|
val misaligned =
|
||||||
@ -827,19 +829,19 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
io.cpu.xcpt.pf.st := s1_write && dtlb.io.resp.xcpt_st
|
io.cpu.xcpt.pf.st := s1_write && dtlb.io.resp.xcpt_st
|
||||||
|
|
||||||
// tags
|
// tags
|
||||||
val meta = new MetaDataArray
|
val meta = Module(new MetaDataArray)
|
||||||
val metaReadArb = (new Arbiter(5)) { new MetaReadReq }
|
val metaReadArb = Module(new Arbiter(new MetaReadReq, 5))
|
||||||
val metaWriteArb = (new Arbiter(2)) { new MetaWriteReq }
|
val metaWriteArb = Module(new Arbiter(new MetaWriteReq, 2))
|
||||||
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 = Module(new DataArray)
|
||||||
val readArb = new Arbiter(4)(new DataReadReq)
|
val readArb = Module(new Arbiter(new DataReadReq, 4))
|
||||||
readArb.io.out.ready := !io.mem.grant.valid || io.mem.grant.ready // insert bubble if refill gets blocked
|
readArb.io.out.ready := !io.mem.grant.valid || io.mem.grant.ready // insert bubble if refill gets blocked
|
||||||
readArb.io.out <> data.io.read
|
readArb.io.out <> data.io.read
|
||||||
|
|
||||||
val writeArb = new Arbiter(2)(new DataWriteReq)
|
val writeArb = Module(new Arbiter(new DataWriteReq, 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
|
||||||
@ -854,7 +856,7 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
// data read for new requests
|
// data read for new requests
|
||||||
readArb.io.in(3).bits.addr := io.cpu.req.bits.addr
|
readArb.io.in(3).bits.addr := io.cpu.req.bits.addr
|
||||||
readArb.io.in(3).valid := io.cpu.req.valid
|
readArb.io.in(3).valid := io.cpu.req.valid
|
||||||
readArb.io.in(3).bits.way_en := Fix(-1)
|
readArb.io.in(3).bits.way_en := SInt(-1)
|
||||||
when (!readArb.io.in(3).ready) { io.cpu.req.ready := Bool(false) }
|
when (!readArb.io.in(3).ready) { io.cpu.req.ready := Bool(false) }
|
||||||
|
|
||||||
// recycled requests
|
// recycled requests
|
||||||
@ -862,23 +864,23 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
metaReadArb.io.in(0).bits.addr := s2_req.addr
|
metaReadArb.io.in(0).bits.addr := s2_req.addr
|
||||||
readArb.io.in(0).valid := s2_recycle
|
readArb.io.in(0).valid := s2_recycle
|
||||||
readArb.io.in(0).bits.addr := s2_req.addr
|
readArb.io.in(0).bits.addr := s2_req.addr
|
||||||
readArb.io.in(0).bits.way_en := Fix(-1)
|
readArb.io.in(0).bits.way_en := SInt(-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(f)){gen}
|
def wayMap[T <: Data](f: Int => T) = Vec((0 until conf.ways).map(f))
|
||||||
val s1_tag_eq_way = wayMap((w: Int) => meta.io.resp(w).tag === (s1_addr >> conf.untagbits)){Bits()}.toBits
|
val s1_tag_eq_way = wayMap((w: Int) => meta.io.resp(w).tag === (s1_addr >> conf.untagbits)).toBits
|
||||||
val s1_tag_match_way = wayMap((w: Int) => s1_tag_eq_way(w) && tl.co.isValid(meta.io.resp(w).state)){Bits()}.toBits
|
val s1_tag_match_way = wayMap((w: Int) => s1_tag_eq_way(w) && tl.co.isValid(meta.io.resp(w).state)).toBits
|
||||||
s1_clk_en := metaReadArb.io.out.valid
|
s1_clk_en := metaReadArb.io.out.valid
|
||||||
val s1_writeback = s1_clk_en && !s1_valid && !s1_replay
|
val s1_writeback = s1_clk_en && !s1_valid && !s1_replay
|
||||||
val s2_tag_match_way = RegEn(s1_tag_match_way, s1_clk_en)
|
val s2_tag_match_way = RegEn(s1_tag_match_way, s1_clk_en)
|
||||||
val s2_tag_match = s2_tag_match_way.orR
|
val s2_tag_match = s2_tag_match_way.orR
|
||||||
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)))
|
||||||
val s2_hit = s2_tag_match && tl.co.isHit(s2_req.cmd, s2_hit_state) && s2_hit_state === tl.co.newStateOnHit(s2_req.cmd, s2_hit_state)
|
val s2_hit = s2_tag_match && tl.co.isHit(s2_req.cmd, s2_hit_state) && s2_hit_state === tl.co.newStateOnHit(s2_req.cmd, s2_hit_state)
|
||||||
|
|
||||||
// load-reserved/store-conditional
|
// load-reserved/store-conditional
|
||||||
val lrsc_count = Reg(resetVal = UFix(0))
|
val lrsc_count = RegReset(UInt(0))
|
||||||
val lrsc_valid = lrsc_count.orR
|
val lrsc_valid = lrsc_count.orR
|
||||||
val lrsc_addr = Reg{UFix()}
|
val lrsc_addr = Reg(UInt())
|
||||||
val (s2_lr, s2_sc) = (s2_req.cmd === M_XLR, s2_req.cmd === M_XSC)
|
val (s2_lr, s2_sc) = (s2_req.cmd === M_XLR, s2_req.cmd === M_XSC)
|
||||||
val s2_lrsc_addr_match = lrsc_valid && lrsc_addr === (s2_req.addr >> conf.offbits)
|
val s2_lrsc_addr_match = lrsc_valid && lrsc_addr === (s2_req.addr >> conf.offbits)
|
||||||
val s2_sc_fail = s2_sc && !s2_lrsc_addr_match
|
val s2_sc_fail = s2_sc && !s2_lrsc_addr_match
|
||||||
@ -894,9 +896,9 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
}
|
}
|
||||||
when (io.cpu.ptw.eret) { lrsc_count := 0 }
|
when (io.cpu.ptw.eret) { lrsc_count := 0 }
|
||||||
|
|
||||||
val s2_data = Vec(conf.ways){Bits(width = conf.bitsperrow)}
|
val s2_data = Vec.fill(conf.ways){Bits(width = conf.bitsperrow)}
|
||||||
for (w <- 0 until conf.ways) {
|
for (w <- 0 until conf.ways) {
|
||||||
val regs = Vec(conf.wordsperrow){Reg{Bits(width = conf.encdatabits)}}
|
val regs = Vec.fill(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)
|
||||||
@ -908,12 +910,12 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
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_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_corrected = AVec(s2_data_decoded.map(_.corrected)).toBits
|
||||||
val s2_data_uncorrected = AVec(s2_data_decoded.map(_.uncorrected)).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_word_idx = if (conf.isNarrowRead) UInt(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)
|
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) && !s2_sc_fail && isWrite(s2_req.cmd)
|
s3_valid := (s2_valid_masked && s2_hit || s2_replay) && !s2_sc_fail && isWrite(s2_req.cmd)
|
||||||
val amoalu = new AMOALU
|
val amoalu = Module(new AMOALU)
|
||||||
when ((s2_valid || s2_replay) && (isWrite(s2_req.cmd) || s2_data_correctable)) {
|
when ((s2_valid || s2_replay) && (isWrite(s2_req.cmd) || s2_data_correctable)) {
|
||||||
s3_req := s2_req
|
s3_req := s2_req
|
||||||
s3_req.data := Mux(s2_data_correctable, s2_data_corrected, amoalu.io.out)
|
s3_req.data := Mux(s2_data_correctable, s2_data_corrected, amoalu.io.out)
|
||||||
@ -921,16 +923,16 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 := UInt(1) << s3_req.addr(conf.ramoffbits-1,offsetlsb).toUInt
|
||||||
writeArb.io.in(0).bits.data := Fill(conf.wordsperrow, 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
|
||||||
|
|
||||||
// replacement policy
|
// replacement policy
|
||||||
val replacer = new RandomReplacement
|
val replacer = new RandomReplacement
|
||||||
val s1_replaced_way_en = UFixToOH(replacer.way)
|
val s1_replaced_way_en = UIntToOH(replacer.way)
|
||||||
val s2_replaced_way_en = UFixToOH(RegEn(replacer.way, s1_clk_en))
|
val s2_replaced_way_en = UIntToOH(RegEn(replacer.way, s1_clk_en))
|
||||||
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_meta = Mux1H(s2_replaced_way_en, wayMap((w: Int) => RegEn(meta.io.resp(w), s1_clk_en && s1_replaced_way_en(w))).toSeq)
|
||||||
|
|
||||||
// miss handling
|
// miss handling
|
||||||
mshrs.io.req.valid := s2_valid_masked && !s2_hit && (isPrefetch(s2_req.cmd) || isRead(s2_req.cmd) || isWrite(s2_req.cmd))
|
mshrs.io.req.valid := s2_valid_masked && !s2_hit && (isPrefetch(s2_req.cmd) || isRead(s2_req.cmd) || isWrite(s2_req.cmd))
|
||||||
@ -948,18 +950,18 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
//TODO io.mem.acquire.data should be connected to uncached store data generator
|
//TODO io.mem.acquire.data should be connected to uncached store data generator
|
||||||
//io.mem.acquire.data <> FIFOedLogicalNetworkIOWrapper(TODO)
|
//io.mem.acquire.data <> FIFOedLogicalNetworkIOWrapper(TODO)
|
||||||
io.mem.acquire.data.valid := Bool(false)
|
io.mem.acquire.data.valid := Bool(false)
|
||||||
io.mem.acquire.data.bits.payload.data := UFix(0)
|
io.mem.acquire.data.bits.payload.data := UInt(0)
|
||||||
|
|
||||||
// replays
|
// replays
|
||||||
readArb.io.in(1).valid := mshrs.io.replay.valid
|
readArb.io.in(1).valid := mshrs.io.replay.valid
|
||||||
readArb.io.in(1).bits := mshrs.io.replay.bits
|
readArb.io.in(1).bits := mshrs.io.replay.bits
|
||||||
readArb.io.in(1).bits.way_en := Fix(-1)
|
readArb.io.in(1).bits.way_en := SInt(-1)
|
||||||
mshrs.io.replay.ready := readArb.io.in(1).ready
|
mshrs.io.replay.ready := readArb.io.in(1).ready
|
||||||
s1_replay := mshrs.io.replay.valid && readArb.io.in(1).ready
|
s1_replay := mshrs.io.replay.valid && readArb.io.in(1).ready
|
||||||
metaReadArb.io.in(1) <> mshrs.io.meta_read
|
metaReadArb.io.in(1) <> mshrs.io.meta_read
|
||||||
metaWriteArb.io.in(0) <> mshrs.io.meta_write
|
metaWriteArb.io.in(0) <> mshrs.io.meta_write
|
||||||
// probes
|
// probes
|
||||||
val releaseArb = (new Arbiter(2)) { new Release }
|
val releaseArb = Module(new Arbiter(new Release, 2))
|
||||||
FIFOedLogicalNetworkIOWrapper(releaseArb.io.out) <> io.mem.release.meta
|
FIFOedLogicalNetworkIOWrapper(releaseArb.io.out) <> io.mem.release.meta
|
||||||
|
|
||||||
val probe = FIFOedLogicalNetworkIOUnwrapper(io.mem.probe)
|
val probe = FIFOedLogicalNetworkIOUnwrapper(io.mem.probe)
|
||||||
@ -979,7 +981,7 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
writeArb.io.in(1).valid := io.mem.grant.valid && refill
|
writeArb.io.in(1).valid := io.mem.grant.valid && refill
|
||||||
io.mem.grant.ready := writeArb.io.in(1).ready || !refill
|
io.mem.grant.ready := writeArb.io.in(1).ready || !refill
|
||||||
writeArb.io.in(1).bits := mshrs.io.mem_resp
|
writeArb.io.in(1).bits := mshrs.io.mem_resp
|
||||||
writeArb.io.in(1).bits.wmask := Fix(-1)
|
writeArb.io.in(1).bits.wmask := SInt(-1)
|
||||||
writeArb.io.in(1).bits.data := io.mem.grant.bits.payload.data
|
writeArb.io.in(1).bits.data := io.mem.grant.bits.payload.data
|
||||||
|
|
||||||
// writebacks
|
// writebacks
|
||||||
@ -991,15 +993,15 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
FIFOedLogicalNetworkIOWrapper(wb.io.release_data) <> io.mem.release.data
|
FIFOedLogicalNetworkIOWrapper(wb.io.release_data) <> io.mem.release.data
|
||||||
|
|
||||||
// store->load bypassing
|
// store->load bypassing
|
||||||
val s4_valid = Reg(s3_valid, resetVal = Bool(false))
|
val s4_valid = Reg(update=s3_valid, reset=Bool(false))
|
||||||
val s4_req = RegEn(s3_req, s3_valid && metaReadArb.io.out.valid)
|
val s4_req = RegEn(s3_req, s3_valid && metaReadArb.io.out.valid)
|
||||||
val bypasses = List(
|
val bypasses = List(
|
||||||
((s2_valid_masked || s2_replay) && !s2_sc_fail, s2_req, amoalu.io.out),
|
((s2_valid_masked || s2_replay) && !s2_sc_fail, s2_req, amoalu.io.out),
|
||||||
(s3_valid, s3_req, s3_req.data),
|
(s3_valid, s3_req, s3_req.data),
|
||||||
(s4_valid, s4_req, s4_req.data)
|
(s4_valid, s4_req, s4_req.data)
|
||||||
).map(r => (r._1 && (s1_addr >> conf.wordoffbits === r._2.addr >> conf.wordoffbits) && isWrite(r._2.cmd), r._3))
|
).map(r => (r._1 && (s1_addr >> conf.wordoffbits === r._2.addr >> conf.wordoffbits) && isWrite(r._2.cmd), r._3))
|
||||||
val s2_store_bypass_data = Reg{Bits(width = conf.databits)}
|
val s2_store_bypass_data = Reg(Bits(width = conf.databits))
|
||||||
val s2_store_bypass = Reg{Bool()}
|
val s2_store_bypass = Reg(Bool())
|
||||||
when (s1_clk_en) {
|
when (s1_clk_en) {
|
||||||
s2_store_bypass := false
|
s2_store_bypass := false
|
||||||
when (bypasses.map(_._1).reduce(_||_)) {
|
when (bypasses.map(_._1).reduce(_||_)) {
|
||||||
@ -1029,14 +1031,14 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
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_ecc = (s2_valid || s2_replay) && s2_hit && s2_data_correctable
|
||||||
val s2_recycle_next = Reg(resetVal = Bool(false))
|
val s2_recycle_next = RegReset(Bool(false))
|
||||||
when (s1_valid || s1_replay) { s2_recycle_next := (s1_valid || s1_replay) && s2_recycle_ecc }
|
when (s1_valid || s1_replay) { s2_recycle_next := (s1_valid || s1_replay) && s2_recycle_ecc }
|
||||||
s2_recycle := s2_recycle_ecc || s2_recycle_next
|
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 = RegReset(Bool(false))
|
||||||
block_fence := (s2_valid && s2_req.cmd === M_FENCE || block_fence) && !mshrs.io.fence_rdy
|
block_fence := (s2_valid && s2_req.cmd === M_FENCE || block_fence) && !mshrs.io.fence_rdy
|
||||||
val block_miss = Reg(resetVal = Bool(false))
|
val block_miss = RegReset(Bool(false))
|
||||||
block_miss := (s2_valid || block_miss) && s2_nack_miss
|
block_miss := (s2_valid || block_miss) && s2_nack_miss
|
||||||
when (block_fence || block_miss) {
|
when (block_fence || block_miss) {
|
||||||
io.cpu.req.ready := Bool(false)
|
io.cpu.req.ready := Bool(false)
|
||||||
|
@ -5,13 +5,15 @@ import uncore.constants.AddressConstants._
|
|||||||
import uncore.constants.MemoryOpConstants._
|
import uncore.constants.MemoryOpConstants._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
class TLBPTWIO extends Bundle {
|
class PTWResp extends Bundle {
|
||||||
val req = new FIFOIO()(UFix(width = VPN_BITS))
|
|
||||||
val resp = new PipeIO()(new Bundle {
|
|
||||||
val error = Bool()
|
val error = Bool()
|
||||||
val ppn = UFix(width = PPN_BITS)
|
val ppn = UInt(width = PPN_BITS)
|
||||||
val perm = Bits(width = PERM_BITS)
|
val perm = Bits(width = PERM_BITS)
|
||||||
}).flip
|
}
|
||||||
|
|
||||||
|
class TLBPTWIO extends Bundle {
|
||||||
|
val req = Decoupled(UInt(width = VPN_BITS))
|
||||||
|
val resp = Valid(new PTWResp).flip
|
||||||
|
|
||||||
val status = new Status().asInput
|
val status = new Status().asInput
|
||||||
val invalidate = Bool(INPUT)
|
val invalidate = Bool(INPUT)
|
||||||
@ -19,16 +21,16 @@ class TLBPTWIO extends Bundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DatapathPTWIO extends Bundle {
|
class DatapathPTWIO extends Bundle {
|
||||||
val ptbr = UFix(INPUT, PADDR_BITS)
|
val ptbr = UInt(INPUT, PADDR_BITS)
|
||||||
val invalidate = Bool(INPUT)
|
val invalidate = Bool(INPUT)
|
||||||
val eret = Bool(INPUT)
|
val eret = Bool(INPUT)
|
||||||
val status = new Status().asInput
|
val status = new Status().asInput
|
||||||
}
|
}
|
||||||
|
|
||||||
class PTW(n: Int)(implicit conf: RocketConfiguration) extends Component
|
class PTW(n: Int)(implicit conf: RocketConfiguration) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val requestor = Vec(n) { new TLBPTWIO }.flip
|
val requestor = Vec.fill(n){new TLBPTWIO}.flip
|
||||||
val mem = new HellaCacheIO()(conf.dcache)
|
val mem = new HellaCacheIO()(conf.dcache)
|
||||||
val dpath = new DatapathPTWIO
|
val dpath = new DatapathPTWIO
|
||||||
}
|
}
|
||||||
@ -37,17 +39,17 @@ class PTW(n: Int)(implicit conf: RocketConfiguration) extends Component
|
|||||||
val bitsPerLevel = VPN_BITS/levels
|
val bitsPerLevel = VPN_BITS/levels
|
||||||
require(VPN_BITS == levels * bitsPerLevel)
|
require(VPN_BITS == levels * bitsPerLevel)
|
||||||
|
|
||||||
val s_ready :: s_req :: s_wait :: s_done :: s_error :: Nil = Enum(5) { UFix() };
|
val s_ready :: s_req :: s_wait :: s_done :: s_error :: Nil = Enum(5) { UInt() };
|
||||||
val state = Reg(resetVal = s_ready)
|
val state = RegReset(s_ready)
|
||||||
val count = Reg{UFix(width = log2Up(levels))}
|
val count = Reg(UInt(width = log2Up(levels)))
|
||||||
|
|
||||||
val r_req_vpn = Reg{Bits()}
|
val r_req_vpn = Reg(Bits())
|
||||||
val r_req_dest = Reg{Bits()}
|
val r_req_dest = Reg(Bits())
|
||||||
val r_pte = Reg{Bits()}
|
val r_pte = Reg(Bits())
|
||||||
|
|
||||||
val vpn_idx = AVec((0 until levels).map(i => (r_req_vpn >> (levels-i-1)*bitsPerLevel)(bitsPerLevel-1,0)))(count)
|
val vpn_idx = AVec((0 until levels).map(i => (r_req_vpn >> (levels-i-1)*bitsPerLevel)(bitsPerLevel-1,0)))(count)
|
||||||
|
|
||||||
val arb = new RRArbiter(n)(UFix(width = VPN_BITS))
|
val arb = Module(new RRArbiter(UInt(width = VPN_BITS), 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
|
||||||
|
|
||||||
@ -65,7 +67,7 @@ class PTW(n: Int)(implicit conf: RocketConfiguration) extends Component
|
|||||||
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(PADDR_BITS-1,PGIDX_BITS), vpn_idx).toUFix << log2Up(conf.xprlen/8)
|
io.mem.req.bits.addr := Cat(r_pte(PADDR_BITS-1,PGIDX_BITS), vpn_idx).toUInt << log2Up(conf.xprlen/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
|
||||||
@ -78,11 +80,11 @@ class PTW(n: Int)(implicit conf: RocketConfiguration) extends Component
|
|||||||
val resp_ppn = AVec((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 = AVec((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) {
|
||||||
val me = r_req_dest === UFix(i)
|
val me = r_req_dest === UInt(i)
|
||||||
io.requestor(i).resp.valid := resp_val && me
|
io.requestor(i).resp.valid := resp_val && me
|
||||||
io.requestor(i).resp.bits.error := resp_err
|
io.requestor(i).resp.bits.error := resp_err
|
||||||
io.requestor(i).resp.bits.perm := r_pte(9,4)
|
io.requestor(i).resp.bits.perm := r_pte(9,4)
|
||||||
io.requestor(i).resp.bits.ppn := resp_ppn.toUFix
|
io.requestor(i).resp.bits.ppn := resp_ppn.toUInt
|
||||||
io.requestor(i).invalidate := io.dpath.invalidate
|
io.requestor(i).invalidate := io.dpath.invalidate
|
||||||
io.requestor(i).eret := io.dpath.eret
|
io.requestor(i).eret := io.dpath.eret
|
||||||
io.requestor(i).status := io.dpath.status
|
io.requestor(i).status := io.dpath.status
|
||||||
@ -94,7 +96,7 @@ class PTW(n: Int)(implicit conf: RocketConfiguration) extends Component
|
|||||||
when (arb.io.out.valid) {
|
when (arb.io.out.valid) {
|
||||||
state := s_req;
|
state := s_req;
|
||||||
}
|
}
|
||||||
count := UFix(0)
|
count := UInt(0)
|
||||||
}
|
}
|
||||||
is (s_req) {
|
is (s_req) {
|
||||||
when (io.mem.req.ready) {
|
when (io.mem.req.ready) {
|
||||||
@ -110,8 +112,8 @@ class PTW(n: Int)(implicit conf: RocketConfiguration) extends Component
|
|||||||
state := s_done
|
state := s_done
|
||||||
}
|
}
|
||||||
.otherwise {
|
.otherwise {
|
||||||
count := count + UFix(1)
|
count := count + UInt(1)
|
||||||
when (resp_ptd && count < UFix(levels-1)) {
|
when (resp_ptd && count < UInt(levels-1)) {
|
||||||
state := s_req
|
state := s_req
|
||||||
}
|
}
|
||||||
.otherwise {
|
.otherwise {
|
||||||
|
@ -19,16 +19,16 @@ case class RocketConfiguration(tl: TileLinkConfiguration,
|
|||||||
if (fastLoadByte) require(fastLoadWord)
|
if (fastLoadByte) require(fastLoadWord)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Tile(resetSignal: Bool = null)(confIn: RocketConfiguration) extends Component(resetSignal) with ClientCoherenceAgent
|
class Tile(resetSignal: Bool = null)(confIn: RocketConfiguration) extends Module(reset = resetSignal) with ClientCoherenceAgent
|
||||||
{
|
{
|
||||||
val memPorts = 2 + confIn.vec
|
val memPorts = 2 + confIn.vec
|
||||||
val dcachePortId = 0
|
val dcachePortId = 0
|
||||||
val icachePortId = 1
|
val icachePortId = 1
|
||||||
val vicachePortId = 2
|
val vicachePortId = 2
|
||||||
implicit val dcConf = confIn.dcache.copy(reqtagbits = confIn.dcacheReqTagBits + log2Up(memPorts), databits = confIn.xprlen)
|
|
||||||
implicit val icConf = confIn.icache
|
|
||||||
implicit val tlConf = confIn.tl
|
implicit val tlConf = confIn.tl
|
||||||
implicit val lnConf = confIn.tl.ln
|
implicit val lnConf = confIn.tl.ln
|
||||||
|
implicit val icConf = confIn.icache
|
||||||
|
implicit val dcConf = confIn.dcache.copy(reqtagbits = confIn.dcacheReqTagBits + log2Up(memPorts), databits = confIn.xprlen)
|
||||||
implicit val conf = confIn.copy(dcache = dcConf)
|
implicit val conf = confIn.copy(dcache = dcConf)
|
||||||
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
@ -36,11 +36,11 @@ class Tile(resetSignal: Bool = null)(confIn: RocketConfiguration) extends Compon
|
|||||||
val host = new HTIFIO(lnConf.nClients)
|
val host = new HTIFIO(lnConf.nClients)
|
||||||
}
|
}
|
||||||
|
|
||||||
val core = new Core
|
val core = Module(new Core)
|
||||||
val icache = new Frontend
|
val icache = Module(new Frontend)
|
||||||
val dcache = new HellaCache
|
val dcache = Module(new HellaCache)
|
||||||
|
|
||||||
val arbiter = new UncachedTileLinkIOArbiterThatAppendsArbiterId(memPorts)
|
val arbiter = Module(new UncachedTileLinkIOArbiterThatAppendsArbiterId(memPorts))
|
||||||
arbiter.io.in(dcachePortId) <> dcache.io.mem
|
arbiter.io.in(dcachePortId) <> dcache.io.mem
|
||||||
arbiter.io.in(icachePortId) <> icache.io.mem
|
arbiter.io.in(icachePortId) <> icache.io.mem
|
||||||
|
|
||||||
@ -52,18 +52,18 @@ class Tile(resetSignal: Bool = null)(confIn: RocketConfiguration) extends Compon
|
|||||||
io.tilelink.release.meta.valid := dcache.io.mem.release.meta.valid
|
io.tilelink.release.meta.valid := dcache.io.mem.release.meta.valid
|
||||||
dcache.io.mem.release.meta.ready := io.tilelink.release.meta.ready
|
dcache.io.mem.release.meta.ready := io.tilelink.release.meta.ready
|
||||||
io.tilelink.release.meta.bits := dcache.io.mem.release.meta.bits
|
io.tilelink.release.meta.bits := dcache.io.mem.release.meta.bits
|
||||||
io.tilelink.release.meta.bits.payload.client_xact_id := Cat(dcache.io.mem.release.meta.bits.payload.client_xact_id, UFix(dcachePortId, log2Up(memPorts))) // Mimic client id extension done by UncachedTileLinkIOArbiter for Acquires from either client)
|
io.tilelink.release.meta.bits.payload.client_xact_id := Cat(dcache.io.mem.release.meta.bits.payload.client_xact_id, UInt(dcachePortId, log2Up(memPorts))) // Mimic client id extension done by UncachedTileLinkIOArbiter for Acquires from either client)
|
||||||
|
|
||||||
/*val ioSubBundles = io.tilelink.getClass.getMethods.filter( x =>
|
/*val ioSubBundles = io.tilelink.getClass.getMethods.filter( x =>
|
||||||
classOf[ClientSourcedIO[Data]].isAssignableFrom(x.getReturnType)).map{ m =>
|
classOf[ClientSourcedIO[Data]].isAssignableFrom(x.getReturnType)).map{ m =>
|
||||||
m.invoke(io.tilelink).asInstanceOf[ClientSourcedIO[LogicalNetworkIO[Data]]] }
|
m.invoke(io.tilelink).asInstanceOf[ClientSourcedIO[LogicalNetworkIO[Data]]] }
|
||||||
ioSubBundles.foreach{ m =>
|
ioSubBundles.foreach{ m =>
|
||||||
m.bits.header.dst := UFix(0)
|
m.bits.header.dst := UInt(0)
|
||||||
m.bits.header.src := UFix(0)
|
m.bits.header.src := UInt(0)
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (conf.vec) {
|
if (conf.vec) {
|
||||||
val vicache = new Frontend()(ICacheConfig(128, 1), tlConf) // 128 sets x 1 ways (8KB)
|
val vicache = Module(new Frontend()(ICacheConfig(128, 1), tlConf)) // 128 sets x 1 ways (8KB)
|
||||||
arbiter.io.in(vicachePortId) <> vicache.io.mem
|
arbiter.io.in(vicachePortId) <> vicache.io.mem
|
||||||
core.io.vimem <> vicache.io.cpu
|
core.io.vimem <> vicache.io.cpu
|
||||||
}
|
}
|
||||||
|
@ -4,25 +4,25 @@ import Chisel._
|
|||||||
import uncore.constants.AddressConstants._
|
import uncore.constants.AddressConstants._
|
||||||
import scala.math._
|
import scala.math._
|
||||||
|
|
||||||
class ioCAM(entries: Int, addr_bits: Int, tag_bits: Int) extends Bundle {
|
class CAMIO(entries: Int, addr_bits: Int, tag_bits: Int) extends Bundle {
|
||||||
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, tag_bits);
|
||||||
val hit = Bool(OUTPUT);
|
val hit = Bool(OUTPUT);
|
||||||
val hits = UFix(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, tag_bits);
|
||||||
val write_addr = UFix(INPUT, addr_bits);
|
val write_addr = UInt(INPUT, addr_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
class rocketCAM(entries: Int, tag_bits: Int) extends Component {
|
class RocketCAM(entries: Int, tag_bits: Int) extends Module {
|
||||||
val addr_bits = ceil(log(entries)/log(2)).toInt;
|
val addr_bits = ceil(log(entries)/log(2)).toInt;
|
||||||
val io = new ioCAM(entries, addr_bits, tag_bits);
|
val io = new CAMIO(entries, addr_bits, tag_bits);
|
||||||
val cam_tags = Vec(entries) { Reg() { Bits(width = tag_bits) } }
|
val cam_tags = Vec.fill(entries){Reg(Bits(width = tag_bits))}
|
||||||
|
|
||||||
val vb_array = Reg(resetVal = Bits(0, entries));
|
val vb_array = RegReset(Bits(0, entries))
|
||||||
when (io.write) {
|
when (io.write) {
|
||||||
vb_array := vb_array.bitSet(io.write_addr, Bool(true));
|
vb_array := vb_array.bitSet(io.write_addr, Bool(true));
|
||||||
cam_tags(io.write_addr) := io.write_tag
|
cam_tags(io.write_addr) := io.write_tag
|
||||||
@ -37,27 +37,27 @@ class rocketCAM(entries: Int, tag_bits: Int) extends Component {
|
|||||||
val hits = (0 until entries).map(i => vb_array(i) && cam_tags(i) === io.tag)
|
val hits = (0 until entries).map(i => vb_array(i) && cam_tags(i) === io.tag)
|
||||||
|
|
||||||
io.valid_bits := vb_array;
|
io.valid_bits := vb_array;
|
||||||
io.hits := Vec(hits){Bool()}.toBits.toUFix
|
io.hits := Vec(hits).toBits
|
||||||
io.hit := io.hits.orR
|
io.hit := io.hits.orR
|
||||||
}
|
}
|
||||||
|
|
||||||
class PseudoLRU(n: Int)
|
class PseudoLRU(n: Int)
|
||||||
{
|
{
|
||||||
val state = Reg() { Bits(width = n) }
|
val state = Reg(Bits(width = n))
|
||||||
def access(way: UFix) = {
|
def access(way: UInt) = {
|
||||||
var next_state = state
|
var next_state = state
|
||||||
var idx = UFix(1,1)
|
var idx = UInt(1,1)
|
||||||
for (i <- log2Up(n)-1 to 0 by -1) {
|
for (i <- log2Up(n)-1 to 0 by -1) {
|
||||||
val bit = way(i)
|
val bit = way(i)
|
||||||
val mask = (UFix(1,n) << idx)(n-1,0)
|
val mask = (UInt(1,n) << idx)(n-1,0)
|
||||||
next_state = next_state & ~mask | Mux(bit, UFix(0), mask)
|
next_state = next_state & ~mask | Mux(bit, UInt(0), mask)
|
||||||
//next_state.bitSet(idx, !bit)
|
//next_state.bitSet(idx, !bit)
|
||||||
idx = Cat(idx, bit)
|
idx = Cat(idx, bit)
|
||||||
}
|
}
|
||||||
state := next_state
|
state := next_state
|
||||||
}
|
}
|
||||||
def replace = {
|
def replace = {
|
||||||
var idx = UFix(1,1)
|
var idx = UInt(1,1)
|
||||||
for (i <- 0 until log2Up(n))
|
for (i <- 0 until log2Up(n))
|
||||||
idx = Cat(idx, state(idx))
|
idx = Cat(idx, state(idx))
|
||||||
idx(log2Up(n)-1,0)
|
idx(log2Up(n)-1,0)
|
||||||
@ -66,8 +66,8 @@ class PseudoLRU(n: Int)
|
|||||||
|
|
||||||
class TLBReq extends Bundle
|
class TLBReq extends Bundle
|
||||||
{
|
{
|
||||||
val asid = UFix(width = ASID_BITS)
|
val asid = UInt(width = ASID_BITS)
|
||||||
val vpn = UFix(width = VPN_BITS+1)
|
val vpn = UInt(width = VPN_BITS+1)
|
||||||
val passthrough = Bool()
|
val passthrough = Bool()
|
||||||
val instruction = Bool()
|
val instruction = Bool()
|
||||||
}
|
}
|
||||||
@ -76,8 +76,8 @@ class TLBResp(entries: Int) extends Bundle
|
|||||||
{
|
{
|
||||||
// lookup responses
|
// lookup responses
|
||||||
val miss = Bool(OUTPUT)
|
val miss = Bool(OUTPUT)
|
||||||
val hit_idx = UFix(OUTPUT, entries)
|
val hit_idx = UInt(OUTPUT, entries)
|
||||||
val ppn = UFix(OUTPUT, PPN_BITS)
|
val ppn = UInt(OUTPUT, PPN_BITS)
|
||||||
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)
|
||||||
@ -85,23 +85,23 @@ class TLBResp(entries: Int) extends Bundle
|
|||||||
override def clone = new TLBResp(entries).asInstanceOf[this.type]
|
override def clone = new TLBResp(entries).asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLB(entries: Int) extends Component
|
class TLB(entries: Int) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = new FIFOIO()(new TLBReq).flip
|
val req = Decoupled(new TLBReq).flip
|
||||||
val resp = new TLBResp(entries)
|
val resp = new TLBResp(entries)
|
||||||
val ptw = new TLBPTWIO
|
val ptw = new TLBPTWIO
|
||||||
}
|
}
|
||||||
|
|
||||||
val s_ready :: s_request :: s_wait :: s_wait_invalidate :: Nil = Enum(4) { UFix() }
|
val s_ready :: s_request :: s_wait :: s_wait_invalidate :: Nil = Enum(4) { UInt() }
|
||||||
val state = Reg(resetVal = s_ready)
|
val state = RegReset(s_ready)
|
||||||
val r_refill_tag = Reg() { UFix() }
|
val r_refill_tag = Reg(UInt())
|
||||||
val r_refill_waddr = Reg() { UFix() }
|
val r_refill_waddr = Reg(UInt())
|
||||||
|
|
||||||
val tag_cam = new rocketCAM(entries, ASID_BITS+VPN_BITS);
|
val tag_cam = Module(new RocketCAM(entries, ASID_BITS+VPN_BITS))
|
||||||
val tag_ram = Vec(entries) { Reg() { io.ptw.resp.bits.ppn.clone } }
|
val tag_ram = Vec.fill(entries){Reg(io.ptw.resp.bits.ppn.clone)}
|
||||||
|
|
||||||
val lookup_tag = Cat(io.req.bits.asid, io.req.bits.vpn).toUFix
|
val lookup_tag = Cat(io.req.bits.asid, io.req.bits.vpn).toUInt
|
||||||
tag_cam.io.clear := io.ptw.invalidate
|
tag_cam.io.clear := io.ptw.invalidate
|
||||||
tag_cam.io.clear_hit := io.req.fire() && Mux(io.req.bits.instruction, io.resp.xcpt_if, io.resp.xcpt_ld && io.resp.xcpt_st)
|
tag_cam.io.clear_hit := io.req.fire() && Mux(io.req.bits.instruction, io.resp.xcpt_if, io.resp.xcpt_ld && io.resp.xcpt_st)
|
||||||
tag_cam.io.tag := lookup_tag
|
tag_cam.io.tag := lookup_tag
|
||||||
@ -109,18 +109,18 @@ class TLB(entries: Int) extends Component
|
|||||||
tag_cam.io.write_tag := r_refill_tag
|
tag_cam.io.write_tag := r_refill_tag
|
||||||
tag_cam.io.write_addr := r_refill_waddr
|
tag_cam.io.write_addr := r_refill_waddr
|
||||||
val tag_hit = tag_cam.io.hit
|
val tag_hit = tag_cam.io.hit
|
||||||
val tag_hit_addr = OHToUFix(tag_cam.io.hits)
|
val tag_hit_addr = OHToUInt(tag_cam.io.hits)
|
||||||
|
|
||||||
// permission bit arrays
|
// permission bit arrays
|
||||||
val ur_array = Reg{Bits()} // user read permission
|
val ur_array = Reg(Bits()) // user read permission
|
||||||
val uw_array = Reg{Bits()} // user write permission
|
val uw_array = Reg(Bits()) // user write permission
|
||||||
val ux_array = Reg{Bits()} // user execute permission
|
val ux_array = Reg(Bits()) // user execute permission
|
||||||
val sr_array = Reg{Bits()} // supervisor read permission
|
val sr_array = Reg(Bits()) // supervisor read permission
|
||||||
val sw_array = Reg{Bits()} // supervisor write permission
|
val sw_array = Reg(Bits()) // supervisor write permission
|
||||||
val sx_array = Reg{Bits()} // supervisor execute permission
|
val sx_array = Reg(Bits()) // supervisor execute permission
|
||||||
when (io.ptw.resp.valid) {
|
when (io.ptw.resp.valid) {
|
||||||
tag_ram(r_refill_waddr) := io.ptw.resp.bits.ppn
|
tag_ram(r_refill_waddr) := io.ptw.resp.bits.ppn
|
||||||
val perm = (!io.ptw.resp.bits.error).toFix & io.ptw.resp.bits.perm(5,0)
|
val perm = (!io.ptw.resp.bits.error).toSInt & io.ptw.resp.bits.perm(5,0)
|
||||||
ur_array := ur_array.bitSet(r_refill_waddr, perm(2))
|
ur_array := ur_array.bitSet(r_refill_waddr, perm(2))
|
||||||
uw_array := uw_array.bitSet(r_refill_waddr, perm(1))
|
uw_array := uw_array.bitSet(r_refill_waddr, perm(1))
|
||||||
ux_array := ux_array.bitSet(r_refill_waddr, perm(0))
|
ux_array := ux_array.bitSet(r_refill_waddr, perm(0))
|
||||||
@ -140,7 +140,7 @@ class TLB(entries: Int) extends Component
|
|||||||
val tlb_miss = io.ptw.status.vm && !tag_hit && !bad_va
|
val tlb_miss = io.ptw.status.vm && !tag_hit && !bad_va
|
||||||
|
|
||||||
when (io.req.valid && tlb_hit) {
|
when (io.req.valid && tlb_hit) {
|
||||||
plru.access(OHToUFix(tag_cam.io.hits))
|
plru.access(OHToUInt(tag_cam.io.hits))
|
||||||
}
|
}
|
||||||
|
|
||||||
io.req.ready := state === s_ready
|
io.req.ready := state === s_ready
|
||||||
|
@ -5,17 +5,17 @@ import scala.math._
|
|||||||
|
|
||||||
object Util
|
object Util
|
||||||
{
|
{
|
||||||
implicit def intToUFix(x: Int): UFix = UFix(x)
|
implicit def intToUInt(x: Int): UInt = UInt(x)
|
||||||
implicit def intToBoolean(x: Int): Boolean = if (x != 0) true else false
|
implicit def intToBoolean(x: Int): Boolean = if (x != 0) true else false
|
||||||
implicit def booleanToInt(x: Boolean): Int = if (x) 1 else 0
|
implicit def booleanToInt(x: Boolean): Int = if (x) 1 else 0
|
||||||
implicit def booleanToBool(x: Boolean): Bits = Bool(x)
|
implicit def booleanToBool(x: Boolean): Bits = Bool(x)
|
||||||
|
|
||||||
implicit def wcToUFix(c: WideCounter): UFix = c.value
|
implicit def wcToUInt(c: WideCounter): UInt = c.value
|
||||||
}
|
}
|
||||||
|
|
||||||
object AVec
|
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)
|
||||||
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)
|
||||||
|
|
||||||
@ -38,9 +38,9 @@ object Str
|
|||||||
require(validChar(x))
|
require(validChar(x))
|
||||||
Lit(x, 8){Bits()}
|
Lit(x, 8){Bits()}
|
||||||
}
|
}
|
||||||
def apply(x: UFix): Bits = apply(x, 10)
|
def apply(x: UInt): Bits = apply(x, 10)
|
||||||
def apply(x: UFix, radix: Int): Bits = {
|
def apply(x: UInt, radix: Int): Bits = {
|
||||||
val rad = UFix(radix)
|
val rad = UInt(radix)
|
||||||
val digs = digits(radix)
|
val digs = digits(radix)
|
||||||
val w = x.getWidth
|
val w = x.getWidth
|
||||||
require(w > 0)
|
require(w > 0)
|
||||||
@ -49,18 +49,18 @@ object Str
|
|||||||
var s = digs(q % rad)
|
var s = digs(q % rad)
|
||||||
for (i <- 1 until ceil(log(2)/log(radix)*w).toInt) {
|
for (i <- 1 until ceil(log(2)/log(radix)*w).toInt) {
|
||||||
q = q / rad
|
q = q / rad
|
||||||
s = Cat(Mux(Bool(radix == 10) && q === UFix(0), Str(' '), digs(q % rad)), s)
|
s = Cat(Mux(Bool(radix == 10) && q === UInt(0), Str(' '), digs(q % rad)), s)
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
def apply(x: Fix): Bits = apply(x, 10)
|
def apply(x: SInt): Bits = apply(x, 10)
|
||||||
def apply(x: Fix, radix: Int): Bits = {
|
def apply(x: SInt, radix: Int): Bits = {
|
||||||
val neg = x < Fix(0)
|
val neg = x < SInt(0)
|
||||||
val abs = x.abs
|
val abs = x.abs
|
||||||
if (radix != 10) {
|
if (radix != 10) {
|
||||||
Cat(Mux(neg, Str('-'), Str(' ')), Str(abs, radix))
|
Cat(Mux(neg, Str('-'), Str(' ')), Str(abs, radix))
|
||||||
} else {
|
} else {
|
||||||
val rad = UFix(radix)
|
val rad = UInt(radix)
|
||||||
val digs = digits(radix)
|
val digs = digits(radix)
|
||||||
val w = abs.getWidth
|
val w = abs.getWidth
|
||||||
require(w > 0)
|
require(w > 0)
|
||||||
@ -70,7 +70,7 @@ object Str
|
|||||||
var needSign = neg
|
var needSign = neg
|
||||||
for (i <- 1 until ceil(log(2)/log(radix)*w).toInt) {
|
for (i <- 1 until ceil(log(2)/log(radix)*w).toInt) {
|
||||||
q = q / rad
|
q = q / rad
|
||||||
val placeSpace = q === UFix(0)
|
val placeSpace = q === UInt(0)
|
||||||
val space = Mux(needSign, Str('-'), Str(' '))
|
val space = Mux(needSign, Str('-'), Str(' '))
|
||||||
needSign = needSign && !placeSpace
|
needSign = needSign && !placeSpace
|
||||||
s = Cat(Mux(placeSpace, space, digs(q % rad)), s)
|
s = Cat(Mux(placeSpace, space, digs(q % rad)), s)
|
||||||
@ -117,21 +117,21 @@ case class WideCounter(width: Int, inc: Bool = Bool(true))
|
|||||||
{
|
{
|
||||||
private val isWide = width >= 4
|
private val isWide = width >= 4
|
||||||
private val smallWidth = if (isWide) log2Up(width) else width
|
private val smallWidth = if (isWide) log2Up(width) else width
|
||||||
private val small = Reg(resetVal = UFix(0, smallWidth))
|
private val small = RegReset(UInt(0, smallWidth))
|
||||||
private val nextSmall = small + UFix(1, smallWidth+1)
|
private val nextSmall = small + UInt(1, smallWidth+1)
|
||||||
when (inc) { small := nextSmall(smallWidth-1,0) }
|
when (inc) { small := nextSmall(smallWidth-1,0) }
|
||||||
|
|
||||||
private val large = if (isWide) {
|
private val large = if (isWide) {
|
||||||
val r = Reg(resetVal = UFix(0, width - smallWidth))
|
val r = RegReset(UInt(0, width - smallWidth))
|
||||||
when (inc && nextSmall(smallWidth)) { r := r + UFix(1) }
|
when (inc && nextSmall(smallWidth)) { r := r + UInt(1) }
|
||||||
r
|
r
|
||||||
} else null
|
} else null
|
||||||
|
|
||||||
val value = Cat(large, small)
|
val value = Cat(large, small)
|
||||||
|
|
||||||
def := (x: UFix) = {
|
def := (x: UInt) = {
|
||||||
val w = x.getWidth
|
val w = x.getWidth
|
||||||
small := x(w.min(smallWidth)-1,0)
|
small := x(w.min(smallWidth)-1,0)
|
||||||
if (isWide) large := (if (w < smallWidth) UFix(0) else x(w.min(width)-1,smallWidth))
|
if (isWide) large := (if (w < smallWidth) UInt(0) else x(w.min(width)-1,smallWidth))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user