check pc/effective address sign extension
This commit is contained in:
parent
a5a020f97b
commit
f1c355e3cd
@ -55,7 +55,7 @@ class rocketProc extends Component
|
||||
itlb.io.cpu.status := dpath.io.ctrl.status;
|
||||
itlb.io.cpu.req_val := ctrl.io.imem.req_val;
|
||||
itlb.io.cpu.req_asid := Bits(0,ASID_BITS); // FIXME: connect to PCR
|
||||
itlb.io.cpu.req_vpn := dpath.io.imem.req_addr(VADDR_BITS-1,PGIDX_BITS);
|
||||
itlb.io.cpu.req_vpn := dpath.io.imem.req_addr(VADDR_BITS,PGIDX_BITS);
|
||||
io.imem.req_idx := dpath.io.imem.req_addr(PGIDX_BITS-1,0);
|
||||
io.imem.req_ppn := itlb.io.cpu.resp_ppn;
|
||||
io.imem.req_val := ctrl.io.imem.req_val;
|
||||
@ -72,7 +72,7 @@ class rocketProc extends Component
|
||||
dtlb.io.cpu.req_kill := ctrl.io.dtlb_kill;
|
||||
dtlb.io.cpu.req_cmd := ctrl.io.dmem.req_cmd;
|
||||
dtlb.io.cpu.req_asid := Bits(0,ASID_BITS); // FIXME: connect to PCR
|
||||
dtlb.io.cpu.req_vpn := dpath.io.dmem.req_addr(VADDR_BITS-1,PGIDX_BITS);
|
||||
dtlb.io.cpu.req_vpn := dpath.io.dmem.req_addr(VADDR_BITS,PGIDX_BITS);
|
||||
ctrl.io.xcpt_dtlb_ld := dtlb.io.cpu.xcpt_ld;
|
||||
ctrl.io.xcpt_dtlb_st := dtlb.io.cpu.xcpt_st;
|
||||
ctrl.io.dtlb_rdy := dtlb.io.cpu.req_rdy;
|
||||
|
@ -7,7 +7,7 @@ import Instructions._
|
||||
|
||||
class ioDpathDmem extends Bundle()
|
||||
{
|
||||
val req_addr = UFix(VADDR_BITS, OUTPUT);
|
||||
val req_addr = UFix(VADDR_BITS+1, OUTPUT);
|
||||
val req_tag = UFix(CPU_TAG_BITS, OUTPUT);
|
||||
val req_data = Bits(64, OUTPUT);
|
||||
val resp_val = Bool(INPUT);
|
||||
@ -20,7 +20,7 @@ class ioDpathDmem extends Bundle()
|
||||
|
||||
class ioDpathImem extends Bundle()
|
||||
{
|
||||
val req_addr = UFix(VADDR_BITS, OUTPUT);
|
||||
val req_addr = UFix(VADDR_BITS+1, OUTPUT);
|
||||
val resp_data = Bits(32, INPUT);
|
||||
}
|
||||
|
||||
@ -50,7 +50,6 @@ class rocketDpath extends Component
|
||||
val alu = new rocketDpathALU();
|
||||
val ex_alu_out = alu.io.out;
|
||||
val ex_alu_adder_out = alu.io.adder_out;
|
||||
val ex_jr_target = ex_alu_adder_out(VADDR_BITS-1,0);
|
||||
|
||||
val div = new rocketDivider(64);
|
||||
val div_result = div.io.div_result_bits;
|
||||
@ -65,13 +64,13 @@ class rocketDpath extends Component
|
||||
val rfile = new rocketDpathRegfile();
|
||||
|
||||
// instruction fetch definitions
|
||||
val if_reg_pc = Reg(resetVal = UFix(START_ADDR,VADDR_BITS));
|
||||
val if_reg_pc = Reg(resetVal = UFix(START_ADDR,VADDR_BITS+1));
|
||||
|
||||
// instruction decode definitions
|
||||
val id_reg_valid = Reg(resetVal = Bool(false));
|
||||
val id_reg_inst = Reg(resetVal = NOP);
|
||||
val id_reg_pc = Reg() { UFix() };
|
||||
val id_reg_pc_plus4 = Reg() { UFix() };
|
||||
val id_reg_pc = Reg() { UFix(width = VADDR_BITS+1) };
|
||||
val id_reg_pc_plus4 = Reg() { UFix(width = VADDR_BITS+1) };
|
||||
|
||||
// execute definitions
|
||||
val ex_reg_valid = Reg(resetVal = Bool(false));
|
||||
@ -133,21 +132,23 @@ class rocketDpath extends Component
|
||||
Cat(Fill(52, ex_reg_inst(31)), ex_reg_inst(31,27), ex_reg_inst(16,10));
|
||||
|
||||
val branch_adder_rhs =
|
||||
Mux(io.ctrl.ex_jmp, Cat(Fill(VADDR_BITS-26, ex_reg_inst(31)), ex_reg_inst(31,7), UFix(0,1)),
|
||||
Cat(ex_sign_extend_split(VADDR_BITS-2,0), UFix(0, 1)));
|
||||
|
||||
Mux(io.ctrl.ex_jmp, Cat(Fill(VADDR_BITS-25, ex_reg_inst(31)), ex_reg_inst(31,7), UFix(0,1)),
|
||||
Cat(ex_sign_extend_split(VADDR_BITS-1,0), UFix(0, 1)));
|
||||
val ex_branch_target = ex_reg_pc + branch_adder_rhs.toUFix;
|
||||
|
||||
val jr_br_target = Mux(io.ctrl.ex_jr, ex_jr_target, ex_branch_target);
|
||||
val ex_jr_target_sign = Mux(ex_alu_adder_out(VADDR_BITS-1), ~ex_alu_adder_out(63,VADDR_BITS) === UFix(0), ex_alu_adder_out(63,VADDR_BITS) != UFix(0))
|
||||
val ex_jr_target_extended = Cat(ex_jr_target_sign, ex_alu_adder_out(VADDR_BITS-1,0)).toUFix
|
||||
|
||||
val jr_br_target = Mux(io.ctrl.ex_jr, ex_jr_target_extended, ex_branch_target);
|
||||
btb.io.correct_target := jr_br_target
|
||||
|
||||
val if_next_pc =
|
||||
Mux(io.ctrl.sel_pc === PC_BTB, if_btb_target,
|
||||
Mux(io.ctrl.sel_pc === PC_BTB, Cat(if_btb_target(VADDR_BITS-1), if_btb_target),
|
||||
Mux(io.ctrl.sel_pc === PC_EX4, ex_reg_pc_plus4,
|
||||
Mux(io.ctrl.sel_pc === PC_BR, ex_branch_target,
|
||||
Mux(io.ctrl.sel_pc === PC_JR, ex_jr_target.toUFix,
|
||||
Mux(io.ctrl.sel_pc === PC_PCR, wb_reg_wdata(VADDR_BITS-1,0), // only used for ERET
|
||||
Mux(io.ctrl.sel_pc === PC_EVEC, pcr.io.evec,
|
||||
Mux(io.ctrl.sel_pc === PC_JR, ex_jr_target_extended,
|
||||
Mux(io.ctrl.sel_pc === PC_PCR, wb_reg_wdata(VADDR_BITS,0), // only used for ERET
|
||||
Mux(io.ctrl.sel_pc === PC_EVEC, Cat(pcr.io.evec(VADDR_BITS-1), pcr.io.evec),
|
||||
Mux(io.ctrl.sel_pc === PC_WB, wb_reg_pc,
|
||||
if_pc_plus4))))))); // PC_4
|
||||
|
||||
@ -155,8 +156,7 @@ class rocketDpath extends Component
|
||||
if_reg_pc <== if_next_pc.toUFix;
|
||||
}
|
||||
|
||||
// FIXME: make sure PCs are properly sign extended
|
||||
io.ctrl.xcpt_ma_inst := if_next_pc(1,0) != Bits(0,2)
|
||||
io.ctrl.xcpt_ma_inst := if_next_pc(1,0) != Bits(0)
|
||||
|
||||
io.imem.req_addr :=
|
||||
Mux(io.ctrl.stallf, if_reg_pc,
|
||||
@ -314,7 +314,7 @@ class rocketDpath extends Component
|
||||
|
||||
// D$ request interface (registered inside D$ module)
|
||||
// other signals (req_val, req_rdy) connect to control module
|
||||
io.dmem.req_addr := ex_alu_adder_out(VADDR_BITS-1,0);
|
||||
io.dmem.req_addr := ex_jr_target_extended.toUFix;
|
||||
io.dmem.req_data := ex_reg_rs2;
|
||||
io.dmem.req_tag := ex_reg_waddr;
|
||||
|
||||
|
@ -53,7 +53,7 @@ class ioDpathPCR extends Bundle()
|
||||
val exception = Bool(INPUT);
|
||||
val cause = UFix(5, INPUT);
|
||||
val badvaddr_wen = Bool(INPUT);
|
||||
val pc = UFix(VADDR_BITS, INPUT);
|
||||
val pc = UFix(VADDR_BITS+1, INPUT);
|
||||
val eret = Bool(INPUT);
|
||||
val ei = Bool(INPUT);
|
||||
val di = Bool(INPUT);
|
||||
@ -121,8 +121,9 @@ class rocketDpathPCR extends Component
|
||||
}
|
||||
}
|
||||
|
||||
val badvaddr_sign = Mux(io.w.data(VADDR_BITS-1), ~io.w.data(63,VADDR_BITS) === UFix(0), io.w.data(63,VADDR_BITS) != UFix(0))
|
||||
when (io.badvaddr_wen) {
|
||||
reg_badvaddr <== io.w.data.toUFix;
|
||||
reg_badvaddr <== Cat(badvaddr_sign, io.w.data(VADDR_BITS-1,0)).toUFix;
|
||||
}
|
||||
|
||||
when (io.exception && !reg_status_et) {
|
||||
@ -163,8 +164,8 @@ class rocketDpathPCR extends Component
|
||||
reg_status_ec <== HAVE_RVC && io.w.data(SR_EC).toBool;
|
||||
reg_status_et <== io.w.data(SR_ET).toBool;
|
||||
}
|
||||
when (io.w.addr === PCR_EPC) { reg_epc <== io.w.data(VADDR_BITS-1,0).toUFix; }
|
||||
when (io.w.addr === PCR_BADVADDR) { reg_badvaddr <== io.w.data(VADDR_BITS-1,0).toUFix; }
|
||||
when (io.w.addr === PCR_EPC) { reg_epc <== io.w.data(VADDR_BITS,0).toUFix; }
|
||||
when (io.w.addr === PCR_BADVADDR) { reg_badvaddr <== io.w.data(VADDR_BITS,0).toUFix; }
|
||||
when (io.w.addr === PCR_EVEC) { reg_ebase <== io.w.data(VADDR_BITS-1,0).toUFix; }
|
||||
when (io.w.addr === PCR_COUNT) { reg_count <== io.w.data(31,0).toUFix; }
|
||||
when (io.w.addr === PCR_COMPARE) { reg_compare <== io.w.data(31,0).toUFix; r_irq_timer <== Bool(false); }
|
||||
@ -187,8 +188,8 @@ class rocketDpathPCR extends Component
|
||||
when (!io.r.en) { rdata <== Bits(0,64); }
|
||||
switch (io.r.addr) {
|
||||
is (PCR_STATUS) { rdata <== Cat(Bits(0,47), reg_status_vm, reg_status_im, reg_status); }
|
||||
is (PCR_EPC) { rdata <== Cat(Fill(64-VADDR_BITS, reg_epc(VADDR_BITS-1)), reg_epc); }
|
||||
is (PCR_BADVADDR) { rdata <== Cat(Fill(64-VADDR_BITS, reg_badvaddr(VADDR_BITS-1)), reg_badvaddr); }
|
||||
is (PCR_EPC) { rdata <== Cat(Fill(64-VADDR_BITS-1, reg_epc(VADDR_BITS)), reg_epc); }
|
||||
is (PCR_BADVADDR) { rdata <== Cat(Fill(64-VADDR_BITS-1, reg_badvaddr(VADDR_BITS)), reg_badvaddr); }
|
||||
is (PCR_EVEC) { rdata <== Cat(Fill(64-VADDR_BITS, reg_ebase(VADDR_BITS-1)), reg_ebase); }
|
||||
is (PCR_COUNT) { rdata <== Cat(Fill(32, reg_count(31)), reg_count); }
|
||||
is (PCR_COMPARE) { rdata <== Cat(Fill(32, reg_compare(31)), reg_compare); }
|
||||
|
@ -19,7 +19,7 @@ class ioDTLB_CPU(view: List[String] = null) extends Bundle(view)
|
||||
val req_cmd = Bits(4, INPUT); // load/store/amo
|
||||
val req_rdy = Bool(OUTPUT);
|
||||
val req_asid = Bits(ASID_BITS, INPUT);
|
||||
val req_vpn = UFix(VPN_BITS, INPUT);
|
||||
val req_vpn = UFix(VPN_BITS+1, INPUT);
|
||||
// lookup responses
|
||||
val resp_miss = Bool(OUTPUT);
|
||||
// val resp_val = Bool(OUTPUT);
|
||||
@ -65,17 +65,18 @@ class rocketDTLB(entries: Int) extends Component
|
||||
val req_store = (r_cpu_req_cmd === M_XWR);
|
||||
val req_amo = r_cpu_req_cmd(3).toBool;
|
||||
|
||||
val lookup_tag = Cat(r_cpu_req_asid, r_cpu_req_vpn);
|
||||
val bad_va = r_cpu_req_vpn(VPN_BITS) != r_cpu_req_vpn(VPN_BITS-1);
|
||||
|
||||
val tag_cam = new rocketCAM(entries, ASID_BITS+VPN_BITS);
|
||||
val tag_ram = Mem(entries, io.ptw.resp_val, r_refill_waddr.toUFix, io.ptw.resp_ppn);
|
||||
|
||||
val lookup_tag = Cat(r_cpu_req_asid, r_cpu_req_vpn);
|
||||
tag_cam.io.clear := io.cpu.invalidate;
|
||||
tag_cam.io.tag := lookup_tag;
|
||||
tag_cam.io.write := io.ptw.resp_val || io.ptw.resp_err;
|
||||
tag_cam.io.write_tag := r_refill_tag;
|
||||
tag_cam.io.write_addr := r_refill_waddr;
|
||||
val tag_hit = tag_cam.io.hit;
|
||||
val tag_hit = tag_cam.io.hit || bad_va;
|
||||
val tag_hit_addr = tag_cam.io.hit_addr;
|
||||
|
||||
// extract fields from status register
|
||||
@ -140,14 +141,16 @@ class rocketDTLB(entries: Int) extends Component
|
||||
val access_fault_ld =
|
||||
tlb_hit && (req_load || req_amo) &&
|
||||
((status_s && !sr_array(tag_hit_addr).toBool) ||
|
||||
(status_u && !ur_array(tag_hit_addr).toBool));
|
||||
(status_u && !ur_array(tag_hit_addr).toBool) ||
|
||||
bad_va);
|
||||
|
||||
io.cpu.xcpt_ld := access_fault_ld;
|
||||
|
||||
val access_fault_st =
|
||||
tlb_hit && (req_store || req_amo) &&
|
||||
((status_s && !sw_array(tag_hit_addr).toBool) ||
|
||||
(status_u && !uw_array(tag_hit_addr).toBool));
|
||||
(status_u && !uw_array(tag_hit_addr).toBool) ||
|
||||
bad_va);
|
||||
|
||||
io.cpu.xcpt_st := access_fault_st;
|
||||
|
||||
|
@ -74,7 +74,7 @@ class ioITLB_CPU(view: List[String] = null) extends Bundle(view)
|
||||
val req_val = Bool(INPUT);
|
||||
val req_rdy = Bool(OUTPUT);
|
||||
val req_asid = Bits(ASID_BITS, INPUT);
|
||||
val req_vpn = UFix(VPN_BITS, INPUT);
|
||||
val req_vpn = UFix(VPN_BITS+1, INPUT);
|
||||
// lookup responses
|
||||
val resp_miss = Bool(OUTPUT);
|
||||
// val resp_val = Bool(OUTPUT);
|
||||
@ -112,17 +112,18 @@ class rocketITLB(entries: Int) extends Component
|
||||
r_cpu_req_val <== Bool(false);
|
||||
}
|
||||
|
||||
val lookup_tag = Cat(r_cpu_req_asid, r_cpu_req_vpn);
|
||||
val bad_va = r_cpu_req_vpn(VPN_BITS) != r_cpu_req_vpn(VPN_BITS-1);
|
||||
|
||||
val tag_cam = new rocketCAM(entries, ASID_BITS+VPN_BITS);
|
||||
val tag_ram = Mem(entries, io.ptw.resp_val, r_refill_waddr.toUFix, io.ptw.resp_ppn);
|
||||
|
||||
val lookup_tag = Cat(r_cpu_req_asid, r_cpu_req_vpn);
|
||||
tag_cam.io.clear := io.cpu.invalidate;
|
||||
tag_cam.io.tag := lookup_tag;
|
||||
tag_cam.io.write := io.ptw.resp_val || io.ptw.resp_err;
|
||||
tag_cam.io.write_tag := r_refill_tag;
|
||||
tag_cam.io.write_addr := r_refill_waddr;
|
||||
val tag_hit = tag_cam.io.hit;
|
||||
val tag_hit = tag_cam.io.hit || bad_va;
|
||||
val tag_hit_addr = tag_cam.io.hit_addr;
|
||||
|
||||
// extract fields from status register
|
||||
@ -171,15 +172,13 @@ class rocketITLB(entries: Int) extends Component
|
||||
}
|
||||
}
|
||||
|
||||
// exception check
|
||||
val outofrange = !tlb_miss && (io.cpu.resp_ppn > UFix(MEMSIZE_PAGES, PPN_BITS));
|
||||
|
||||
val access_fault =
|
||||
tlb_hit &&
|
||||
((status_s && !sx_array(tag_hit_addr).toBool) ||
|
||||
(status_u && !ux_array(tag_hit_addr).toBool));
|
||||
(status_u && !ux_array(tag_hit_addr).toBool) ||
|
||||
bad_va);
|
||||
|
||||
io.cpu.exception := access_fault; //|| outofrange;
|
||||
io.cpu.exception := access_fault;
|
||||
io.cpu.req_rdy := Mux(status_vm, (state === s_ready) && (!r_cpu_req_val || tag_hit), Bool(true));
|
||||
io.cpu.resp_miss := tlb_miss || (state != s_ready);
|
||||
io.cpu.resp_ppn := Mux(status_vm, tag_ram(tag_hit_addr), r_cpu_req_vpn(PPN_BITS-1,0)).toUFix;
|
||||
|
Loading…
Reference in New Issue
Block a user