Refactored cpu/cache interface to use nested bundles
This commit is contained in:
@ -5,81 +5,84 @@ import Node._;
|
||||
import Constants._;
|
||||
import scala.math._;
|
||||
|
||||
class ioDmemArbiter(n: Int) extends Bundle
|
||||
class ioHellaCacheArbiter(n: Int) extends Bundle
|
||||
{
|
||||
val dmem = new ioDmem().flip
|
||||
val requestor = Vec(n) { new ioDmem() }
|
||||
val requestor = Vec(n) { new ioHellaCache() }.flip
|
||||
val mem = new ioHellaCache
|
||||
}
|
||||
|
||||
class rocketDmemArbiter(n: Int) extends Component
|
||||
class rocketHellaCacheArbiter(n: Int) extends Component
|
||||
{
|
||||
val io = new ioDmemArbiter(n)
|
||||
val io = new ioHellaCacheArbiter(n)
|
||||
require(DCACHE_TAG_BITS >= log2up(n) + CPU_TAG_BITS)
|
||||
|
||||
var req_val = Bool(false)
|
||||
var req_rdy = io.dmem.req_rdy
|
||||
var req_rdy = io.mem.req.ready
|
||||
for (i <- 0 until n)
|
||||
{
|
||||
io.requestor(i).req_rdy := req_rdy
|
||||
req_val = req_val || io.requestor(i).req_val
|
||||
req_rdy = req_rdy && !io.requestor(i).req_val
|
||||
io.requestor(i).req.ready := req_rdy
|
||||
req_val = req_val || io.requestor(i).req.valid
|
||||
req_rdy = req_rdy && !io.requestor(i).req.valid
|
||||
}
|
||||
|
||||
var req_cmd = io.requestor(n-1).req_cmd
|
||||
var req_type = io.requestor(n-1).req_type
|
||||
var req_idx = io.requestor(n-1).req_idx
|
||||
var req_ppn = io.requestor(n-1).req_ppn
|
||||
var req_data = io.requestor(n-1).req_data
|
||||
var req_tag = io.requestor(n-1).req_tag
|
||||
var req_kill = io.requestor(n-1).req_kill
|
||||
var req_cmd = io.requestor(n-1).req.bits.cmd
|
||||
var req_type = io.requestor(n-1).req.bits.typ
|
||||
var req_idx = io.requestor(n-1).req.bits.idx
|
||||
var req_ppn = io.requestor(n-1).req.bits.ppn
|
||||
var req_data = io.requestor(n-1).req.bits.data
|
||||
var req_kill = io.requestor(n-1).req.bits.kill
|
||||
var req_tag = io.requestor(n-1).req.bits.tag
|
||||
for (i <- n-1 to 0 by -1)
|
||||
{
|
||||
req_cmd = Mux(io.requestor(i).req_val, io.requestor(i).req_cmd, req_cmd)
|
||||
req_type = Mux(io.requestor(i).req_val, io.requestor(i).req_type, req_type)
|
||||
req_idx = Mux(io.requestor(i).req_val, io.requestor(i).req_idx, req_idx)
|
||||
req_ppn = Mux(Reg(io.requestor(i).req_val), io.requestor(i).req_ppn, req_ppn)
|
||||
req_data = Mux(Reg(io.requestor(i).req_val), io.requestor(i).req_data, req_data)
|
||||
req_tag = Mux(io.requestor(i).req_val, Cat(io.requestor(i).req_tag, UFix(i, log2up(n))), req_tag)
|
||||
req_kill = Mux(Reg(io.requestor(i).req_val), io.requestor(i).req_kill, req_kill)
|
||||
val r = io.requestor(i).req
|
||||
req_cmd = Mux(r.valid, r.bits.cmd, req_cmd)
|
||||
req_type = Mux(r.valid, r.bits.typ, req_type)
|
||||
req_idx = Mux(r.valid, r.bits.idx, req_idx)
|
||||
req_ppn = Mux(Reg(r.valid), r.bits.ppn, req_ppn)
|
||||
req_data = Mux(Reg(r.valid), r.bits.data, req_data)
|
||||
req_kill = Mux(Reg(r.valid), r.bits.kill, req_kill)
|
||||
req_tag = Mux(r.valid, Cat(r.bits.tag, UFix(i, log2up(n))), req_tag)
|
||||
}
|
||||
|
||||
io.dmem.req_val := req_val
|
||||
io.dmem.req_cmd := req_cmd
|
||||
io.dmem.req_type := req_type
|
||||
io.dmem.req_idx := req_idx
|
||||
io.dmem.req_ppn := req_ppn
|
||||
io.dmem.req_data := req_data
|
||||
io.dmem.req_tag := req_tag
|
||||
io.dmem.req_kill := req_kill
|
||||
io.mem.req.valid := req_val
|
||||
io.mem.req.bits.cmd := req_cmd
|
||||
io.mem.req.bits.typ := req_type
|
||||
io.mem.req.bits.idx := req_idx
|
||||
io.mem.req.bits.ppn := req_ppn
|
||||
io.mem.req.bits.data := req_data
|
||||
io.mem.req.bits.kill := req_kill
|
||||
io.mem.req.bits.tag := req_tag
|
||||
|
||||
for (i <- 0 until n)
|
||||
{
|
||||
val tag_hit = io.dmem.resp_tag(log2up(n)-1,0) === UFix(i)
|
||||
io.requestor(i).xcpt_ma_ld := io.dmem.xcpt_ma_ld && Reg(io.requestor(i).req_val)
|
||||
io.requestor(i).xcpt_ma_st := io.dmem.xcpt_ma_st && Reg(io.requestor(i).req_val)
|
||||
io.requestor(i).resp_nack := io.dmem.resp_nack && Reg(io.requestor(i).req_val)
|
||||
io.requestor(i).resp_miss := io.dmem.resp_miss && tag_hit
|
||||
io.requestor(i).resp_val := io.dmem.resp_val && tag_hit
|
||||
io.requestor(i).resp_replay := io.dmem.resp_replay && tag_hit
|
||||
io.requestor(i).resp_data := io.dmem.resp_data
|
||||
io.requestor(i).resp_data_subword := io.dmem.resp_data_subword
|
||||
io.requestor(i).resp_type := io.dmem.resp_type
|
||||
io.requestor(i).resp_tag := io.dmem.resp_tag >> UFix(log2up(n))
|
||||
val r = io.requestor(i).resp
|
||||
val x = io.requestor(i).xcpt
|
||||
val tag_hit = io.mem.resp.bits.tag(log2up(n)-1,0) === UFix(i)
|
||||
x.ma.ld := io.mem.xcpt.ma.ld && Reg(io.requestor(i).req.valid)
|
||||
x.ma.st := io.mem.xcpt.ma.st && Reg(io.requestor(i).req.valid)
|
||||
r.valid := io.mem.resp.valid && tag_hit
|
||||
r.bits.miss := io.mem.resp.bits.miss && tag_hit
|
||||
r.bits.nack := io.mem.resp.bits.nack && Reg(io.requestor(i).req.valid)
|
||||
r.bits.replay := io.mem.resp.bits.replay && tag_hit
|
||||
r.bits.data := io.mem.resp.bits.data
|
||||
r.bits.data_subword := io.mem.resp.bits.data_subword
|
||||
r.bits.typ := io.mem.resp.bits.typ
|
||||
r.bits.tag := io.mem.resp.bits.tag >> UFix(log2up(n))
|
||||
}
|
||||
}
|
||||
|
||||
class ioPTW extends Bundle
|
||||
{
|
||||
val itlb = new ioTLB_PTW().flip
|
||||
val dtlb = new ioTLB_PTW().flip
|
||||
val vitlb = new ioTLB_PTW().flip
|
||||
val dmem = new ioDmem().flip
|
||||
val ptbr = UFix(PADDR_BITS, INPUT);
|
||||
val itlb = (new ioTLB_PTW).flip
|
||||
val dtlb = (new ioTLB_PTW).flip
|
||||
val vitlb = (new ioTLB_PTW).flip
|
||||
val mem = new ioHellaCache
|
||||
val ptbr = UFix(PADDR_BITS, INPUT)
|
||||
}
|
||||
|
||||
class rocketPTW extends Component
|
||||
{
|
||||
val io = new ioPTW();
|
||||
val io = new ioPTW
|
||||
|
||||
val levels = 3
|
||||
val bitsPerLevel = VPN_BITS/levels
|
||||
@ -123,25 +126,25 @@ class rocketPTW extends Component
|
||||
req_addr := Cat(io.ptbr(PADDR_BITS-1,PGIDX_BITS), io.vitlb.req_vpn(VPN_BITS-1,VPN_BITS-bitsPerLevel), Bits(0,3))
|
||||
}
|
||||
|
||||
val dmem_resp_val = Reg(io.dmem.resp_val, resetVal = Bool(false))
|
||||
val dmem_resp_val = Reg(io.mem.resp.valid, resetVal = Bool(false))
|
||||
when (dmem_resp_val) {
|
||||
req_addr := Cat(io.dmem.resp_data_subword(PADDR_BITS-1, PGIDX_BITS), vpn_idx, Bits(0,3))
|
||||
r_resp_perm := io.dmem.resp_data_subword(9,4);
|
||||
r_resp_ppn := io.dmem.resp_data_subword(PADDR_BITS-1, PGIDX_BITS);
|
||||
req_addr := Cat(io.mem.resp.bits.data_subword(PADDR_BITS-1, PGIDX_BITS), vpn_idx, Bits(0,3))
|
||||
r_resp_perm := io.mem.resp.bits.data_subword(9,4);
|
||||
r_resp_ppn := io.mem.resp.bits.data_subword(PADDR_BITS-1, PGIDX_BITS);
|
||||
}
|
||||
|
||||
io.dmem.req_val := state === s_req
|
||||
io.dmem.req_cmd := M_XRD;
|
||||
io.dmem.req_type := MT_D;
|
||||
io.dmem.req_idx := req_addr(PGIDX_BITS-1,0);
|
||||
io.dmem.req_ppn := Reg(req_addr(PADDR_BITS-1,PGIDX_BITS))
|
||||
io.dmem.req_kill := Bool(false)
|
||||
io.mem.req.valid := state === s_req
|
||||
io.mem.req.bits.cmd := M_XRD
|
||||
io.mem.req.bits.typ := MT_D
|
||||
io.mem.req.bits.idx := req_addr(PGIDX_BITS-1,0)
|
||||
io.mem.req.bits.ppn := Reg(req_addr(PADDR_BITS-1,PGIDX_BITS))
|
||||
io.mem.req.bits.kill := Bool(false)
|
||||
|
||||
val resp_val = state === s_done
|
||||
val resp_err = state === s_error
|
||||
|
||||
val resp_ptd = io.dmem.resp_data_subword(1,0) === Bits(1)
|
||||
val resp_pte = io.dmem.resp_data_subword(1,0) === Bits(2)
|
||||
val resp_ptd = io.mem.resp.bits.data_subword(1,0) === Bits(1)
|
||||
val resp_pte = io.mem.resp.bits.data_subword(1,0) === Bits(2)
|
||||
|
||||
io.itlb.req_rdy := (state === s_ready)
|
||||
io.dtlb.req_rdy := (state === s_ready) && !io.itlb.req_val
|
||||
@ -172,12 +175,12 @@ class rocketPTW extends Component
|
||||
count := UFix(0)
|
||||
}
|
||||
is (s_req) {
|
||||
when (io.dmem.req_rdy) {
|
||||
when (io.mem.req.ready) {
|
||||
state := s_wait;
|
||||
}
|
||||
}
|
||||
is (s_wait) {
|
||||
when (io.dmem.resp_nack) {
|
||||
when (io.mem.resp.bits.nack) {
|
||||
state := s_req
|
||||
}
|
||||
when (dmem_resp_val) {
|
||||
|
Reference in New Issue
Block a user