Merge branch 'master' of github.com:ucb-bar/riscv-rocket
This commit is contained in:
commit
4939b72ba5
@ -118,12 +118,9 @@ class rocketDTLB(entries: Int) extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
// high if there are any unused (invalid) entries in the TLB
|
// high if there are any unused (invalid) entries in the TLB
|
||||||
val invalid_entry = (tag_cam.io.valid_bits != ~Bits(0,entries));
|
val has_invalid_entry = !tag_cam.io.valid_bits.andR
|
||||||
val ie_enc = new priorityEncoder(entries);
|
val invalid_entry = PriorityEncoder(~tag_cam.io.valid_bits)
|
||||||
ie_enc.io.in := ~tag_cam.io.valid_bits.toUFix;
|
val repl_waddr = Mux(has_invalid_entry, invalid_entry, repl_count).toUFix;
|
||||||
val ie_addr = ie_enc.io.out;
|
|
||||||
|
|
||||||
val repl_waddr = Mux(invalid_entry, ie_addr, repl_count).toUFix;
|
|
||||||
|
|
||||||
val lookup = (state === s_ready) && r_cpu_req_val && !io.cpu_req.bits.kill && (req_load || req_store || req_amo || req_pf);
|
val lookup = (state === s_ready) && r_cpu_req_val && !io.cpu_req.bits.kill && (req_load || req_store || req_amo || req_pf);
|
||||||
val lookup_hit = lookup && tag_hit;
|
val lookup_hit = lookup && tag_hit;
|
||||||
@ -136,7 +133,7 @@ class rocketDTLB(entries: Int) extends Component
|
|||||||
when (tlb_miss) {
|
when (tlb_miss) {
|
||||||
r_refill_tag := lookup_tag;
|
r_refill_tag := lookup_tag;
|
||||||
r_refill_waddr := repl_waddr;
|
r_refill_waddr := repl_waddr;
|
||||||
when (!invalid_entry) {
|
when (!has_invalid_entry) {
|
||||||
repl_count := repl_count + UFix(1);
|
repl_count := repl_count + UFix(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,12 +146,9 @@ class rocketITLB(entries: Int) extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
// high if there are any unused entries in the ITLB
|
// high if there are any unused entries in the ITLB
|
||||||
val invalid_entry = (tag_cam.io.valid_bits != ~Bits(0,entries));
|
val has_invalid_entry = !tag_cam.io.valid_bits.andR
|
||||||
val ie_enc = new priorityEncoder(entries);
|
val invalid_entry = PriorityEncoder(~tag_cam.io.valid_bits)
|
||||||
ie_enc.io.in := ~tag_cam.io.valid_bits.toUFix;
|
val repl_waddr = Mux(has_invalid_entry, invalid_entry, repl_count).toUFix;
|
||||||
val ie_addr = ie_enc.io.out;
|
|
||||||
|
|
||||||
val repl_waddr = Mux(invalid_entry, ie_addr, repl_count).toUFix;
|
|
||||||
|
|
||||||
val lookup = (state === s_ready) && r_cpu_req_val;
|
val lookup = (state === s_ready) && r_cpu_req_val;
|
||||||
val lookup_hit = lookup && tag_hit;
|
val lookup_hit = lookup && tag_hit;
|
||||||
@ -162,7 +159,7 @@ class rocketITLB(entries: Int) extends Component
|
|||||||
when (tlb_miss) {
|
when (tlb_miss) {
|
||||||
r_refill_tag := lookup_tag;
|
r_refill_tag := lookup_tag;
|
||||||
r_refill_waddr := repl_waddr;
|
r_refill_waddr := repl_waddr;
|
||||||
when (!invalid_entry) {
|
when (!has_invalid_entry) {
|
||||||
repl_count := repl_count + UFix(1);
|
repl_count := repl_count + UFix(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,10 +361,8 @@ class ReplayUnit extends Component {
|
|||||||
val cpu_resp_tag = Bits(DCACHE_TAG_BITS, OUTPUT)
|
val cpu_resp_tag = Bits(DCACHE_TAG_BITS, OUTPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sdq_val = Reg(resetVal = UFix(0, NSDQ))
|
val sdq_val = Reg(resetVal = UFix(0))
|
||||||
val sdq_allocator = new priorityEncoder(NSDQ)
|
val sdq_alloc_id = PriorityEncoder(~sdq_val(NSDQ-1,0))
|
||||||
sdq_allocator.io.in := ~sdq_val
|
|
||||||
val sdq_alloc_id = sdq_allocator.io.out.toUFix
|
|
||||||
|
|
||||||
val replay_val = Reg(resetVal = Bool(false))
|
val replay_val = Reg(resetVal = Bool(false))
|
||||||
val replay_retry = replay_val && !io.data_req.ready
|
val replay_retry = replay_val && !io.data_req.ready
|
||||||
|
@ -53,3 +53,37 @@ class queue[T <: Data](entries: Int, pipe: Boolean = false, flushable: Boolean =
|
|||||||
io.enq.ready := !maybe_full || enq_ptr != deq_ptr || (if (pipe) io.deq.ready else Bool(false))
|
io.enq.ready := !maybe_full || enq_ptr != deq_ptr || (if (pipe) io.deq.ready else Bool(false))
|
||||||
io.deq.bits <> Mem(entries, do_enq, enq_ptr, io.enq.bits).read(deq_ptr)
|
io.deq.bits <> Mem(entries, do_enq, enq_ptr, io.enq.bits).read(deq_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Queue
|
||||||
|
{
|
||||||
|
def apply[T <: Data](enq: ioDecoupled[T], entries: Int = 2, pipe: Boolean = false) = {
|
||||||
|
val q = (new queue(entries, pipe)) { enq.bits.clone }
|
||||||
|
q.io.enq <> enq
|
||||||
|
q.io.deq
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class pipereg[T <: Data]()(data: => T) extends Component
|
||||||
|
{
|
||||||
|
val io = new Bundle {
|
||||||
|
val enq = new ioValid()(data)
|
||||||
|
val deq = new ioValid()(data).flip
|
||||||
|
}
|
||||||
|
|
||||||
|
//val bits = Reg() { io.enq.bits.clone }
|
||||||
|
//when (io.enq.valid) {
|
||||||
|
// bits := io.enq.bits
|
||||||
|
//}
|
||||||
|
|
||||||
|
io.deq.valid := Reg(io.enq.valid, resetVal = Bool(false))
|
||||||
|
io.deq.bits <> Mem(1, io.enq.valid, UFix(0), io.enq.bits).read(UFix(0))
|
||||||
|
}
|
||||||
|
|
||||||
|
object PipeReg
|
||||||
|
{
|
||||||
|
def apply[T <: Data](enq: ioValid[T]) = {
|
||||||
|
val q = (new pipereg) { enq.bits.clone }
|
||||||
|
q.io.enq <> enq
|
||||||
|
q.io.deq
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -27,25 +27,14 @@ class Top() extends Component {
|
|||||||
arbiter.io.requestor(2) <> htif.io.mem
|
arbiter.io.requestor(2) <> htif.io.mem
|
||||||
|
|
||||||
val hub = new CoherenceHubNull
|
val hub = new CoherenceHubNull
|
||||||
// connect tile to hub (figure out how to do this more compactly)
|
// connect tile to hub
|
||||||
val xact_init_q = (new queue(2)) { new TransactionInit }
|
hub.io.tile.xact_init <> Queue(arbiter.io.mem.xact_init)
|
||||||
xact_init_q.io.enq <> arbiter.io.mem.xact_init
|
hub.io.tile.xact_init_data <> Queue(arbiter.io.mem.xact_init_data)
|
||||||
xact_init_q.io.deq <> hub.io.tile.xact_init
|
arbiter.io.mem.xact_rep <> Queue(hub.io.tile.xact_rep, 1, pipe = true)
|
||||||
val xact_init_data_q = (new queue(2)) { new TransactionInitData }
|
|
||||||
xact_init_data_q.io.enq <> arbiter.io.mem.xact_init_data
|
|
||||||
xact_init_data_q.io.deq <> hub.io.tile.xact_init_data
|
|
||||||
val xact_rep_q = (new queue(1, pipe = true)) { new TransactionReply }
|
|
||||||
xact_rep_q.io.enq <> hub.io.tile.xact_rep
|
|
||||||
xact_rep_q.io.deq <> arbiter.io.mem.xact_rep
|
|
||||||
// connect hub to memory
|
// connect hub to memory
|
||||||
val mem_req_q = (new queue(2)) { new MemReqCmd }
|
io.mem.req_cmd <> Queue(hub.io.mem.req_cmd)
|
||||||
mem_req_q.io.enq <> hub.io.mem.req_cmd
|
io.mem.req_data <> Queue(hub.io.mem.req_data)
|
||||||
mem_req_q.io.deq <> io.mem.req_cmd
|
hub.io.mem.resp <> PipeReg(io.mem.resp)
|
||||||
val mem_req_data_q = (new queue(2)) { new MemData }
|
|
||||||
mem_req_data_q.io.enq <> hub.io.mem.req_data
|
|
||||||
mem_req_data_q.io.deq <> io.mem.req_data
|
|
||||||
hub.io.mem.resp.valid := Reg(io.mem.resp.valid, resetVal = Bool(false))
|
|
||||||
hub.io.mem.resp.bits := Reg(io.mem.resp.bits)
|
|
||||||
|
|
||||||
|
|
||||||
if (HAVE_VEC)
|
if (HAVE_VEC)
|
||||||
|
@ -166,14 +166,7 @@ class Mux1H [T <: Data](n: Int)(gen: => T) extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ioDecoupled[+T <: Data]()(data: => T) extends Bundle
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ioDecoupled[T <: Data]()(data: => T) extends Bundle
|
|
||||||
{
|
{
|
||||||
val valid = Bool(INPUT)
|
val valid = Bool(INPUT)
|
||||||
val ready = Bool(OUTPUT)
|
val ready = Bool(OUTPUT)
|
||||||
@ -211,46 +204,51 @@ class Arbiter[T <: Data](n: Int)(data: => T) extends Component {
|
|||||||
dout <> io.out.bits
|
dout <> io.out.bits
|
||||||
}
|
}
|
||||||
|
|
||||||
class ioPriorityDecoder(in_width: Int, out_width: Int) extends Bundle
|
class ioLockingArbiter[T <: Data](n: Int)(data: => T) extends Bundle {
|
||||||
{
|
val in = Vec(n) { (new ioDecoupled()) { data } }
|
||||||
val in = UFix(in_width, INPUT);
|
val lock = Vec(n) { Bool() }
|
||||||
val out = Bits(out_width, OUTPUT);
|
val out = (new ioDecoupled()) { data }.flip()
|
||||||
}
|
}
|
||||||
|
|
||||||
class priorityDecoder(width: Int) extends Component
|
class LockingArbiter[T <: Data](n: Int)(data: => T) extends Component {
|
||||||
{
|
val io = new ioLockingArbiter(n)(data)
|
||||||
val in_width = ceil(log10(width)/log10(2)).toInt;
|
val locked = Reg(){ Bits(n) }
|
||||||
val io = new ioPriorityEncoder(in_width, width);
|
var dout = Wire(){ data }
|
||||||
val l_out = Wire() { Bits() };
|
var vout = Wire(){ Bool() }
|
||||||
|
|
||||||
l_out := Bits(0, width);
|
when((locked && io.lock.toBits).orR) {
|
||||||
for (i <- width-1 to 0 by -1) {
|
dout := io.in(0).bits
|
||||||
when (io.in === UFix(i, in_width)) {
|
for (i <- 0 until n) {
|
||||||
l_out := Bits(1,1) << UFix(i);
|
io.in(i).ready := io.out.ready && locked(i)
|
||||||
|
vout := io.in(i).valid && locked(i)
|
||||||
|
dout := Mux(locked(i), io.in(i).bits, dout)
|
||||||
}
|
}
|
||||||
}
|
} .otherwise {
|
||||||
|
io.in(0).ready := io.out.ready
|
||||||
io.out := l_out;
|
for (i <- 1 until n) {
|
||||||
}
|
io.in(i).ready := !io.in(i-1).valid && io.in(i-1).ready
|
||||||
|
locked(i) := !io.in(i-1).valid && io.in(i-1).ready && io.lock(i)
|
||||||
class ioPriorityEncoder(in_width: Int, out_width: Int) extends Bundle
|
|
||||||
{
|
|
||||||
val in = Bits(in_width, INPUT);
|
|
||||||
val out = UFix(out_width, OUTPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
class priorityEncoder(width: Int) extends Component
|
|
||||||
{
|
|
||||||
val out_width = ceil(log10(width)/log10(2)).toInt;
|
|
||||||
val io = new ioPriorityDecoder(width, out_width);
|
|
||||||
val l_out = Wire() { UFix() };
|
|
||||||
|
|
||||||
l_out := UFix(0, out_width);
|
|
||||||
for (i <- width-1 to 1 by -1) {
|
|
||||||
when (io.in(i).toBool) {
|
|
||||||
l_out := UFix(i, out_width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dout := io.in(n-1).bits
|
||||||
|
for (i <- 1 until n)
|
||||||
|
dout = Mux(io.in(n-1-i).valid, io.in(n-1-i).bits, dout)
|
||||||
|
|
||||||
|
vout := io.in(0).valid
|
||||||
|
for (i <- 1 until n)
|
||||||
|
vout = vout || io.in(i).valid
|
||||||
|
}
|
||||||
|
|
||||||
|
vout <> io.out.valid
|
||||||
|
dout <> io.out.bits
|
||||||
|
}
|
||||||
|
|
||||||
|
object PriorityEncoder
|
||||||
|
{
|
||||||
|
def apply(in: Bits, n: Int = 0): UFix = {
|
||||||
|
if (n >= in.getWidth-1)
|
||||||
|
UFix(n)
|
||||||
|
else
|
||||||
|
Mux(in(n), UFix(n), PriorityEncoder(in, n+1))
|
||||||
}
|
}
|
||||||
|
|
||||||
io.out := l_out;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user