1
0

check pc/effective address sign extension

This commit is contained in:
Andrew Waterman 2012-01-24 00:15:17 -08:00
parent a5a020f97b
commit f1c355e3cd
5 changed files with 43 additions and 40 deletions

View File

@ -55,7 +55,7 @@ class rocketProc extends Component
itlb.io.cpu.status := dpath.io.ctrl.status; itlb.io.cpu.status := dpath.io.ctrl.status;
itlb.io.cpu.req_val := ctrl.io.imem.req_val; 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_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_idx := dpath.io.imem.req_addr(PGIDX_BITS-1,0);
io.imem.req_ppn := itlb.io.cpu.resp_ppn; io.imem.req_ppn := itlb.io.cpu.resp_ppn;
io.imem.req_val := ctrl.io.imem.req_val; 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_kill := ctrl.io.dtlb_kill;
dtlb.io.cpu.req_cmd := ctrl.io.dmem.req_cmd; 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_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_ld := dtlb.io.cpu.xcpt_ld;
ctrl.io.xcpt_dtlb_st := dtlb.io.cpu.xcpt_st; ctrl.io.xcpt_dtlb_st := dtlb.io.cpu.xcpt_st;
ctrl.io.dtlb_rdy := dtlb.io.cpu.req_rdy; ctrl.io.dtlb_rdy := dtlb.io.cpu.req_rdy;

View File

@ -7,7 +7,7 @@ import Instructions._
class ioDpathDmem extends Bundle() 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_tag = UFix(CPU_TAG_BITS, OUTPUT);
val req_data = Bits(64, OUTPUT); val req_data = Bits(64, OUTPUT);
val resp_val = Bool(INPUT); val resp_val = Bool(INPUT);
@ -20,7 +20,7 @@ class ioDpathDmem extends Bundle()
class ioDpathImem 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); val resp_data = Bits(32, INPUT);
} }
@ -50,7 +50,6 @@ class rocketDpath extends Component
val alu = new rocketDpathALU(); val alu = new rocketDpathALU();
val ex_alu_out = alu.io.out; val ex_alu_out = alu.io.out;
val ex_alu_adder_out = alu.io.adder_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 = new rocketDivider(64);
val div_result = div.io.div_result_bits; val div_result = div.io.div_result_bits;
@ -65,13 +64,13 @@ class rocketDpath extends Component
val rfile = new rocketDpathRegfile(); val rfile = new rocketDpathRegfile();
// instruction fetch definitions // 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 // instruction decode definitions
val id_reg_valid = Reg(resetVal = Bool(false)); val id_reg_valid = Reg(resetVal = Bool(false));
val id_reg_inst = Reg(resetVal = NOP); val id_reg_inst = Reg(resetVal = NOP);
val id_reg_pc = Reg() { UFix() }; val id_reg_pc = Reg() { UFix(width = VADDR_BITS+1) };
val id_reg_pc_plus4 = Reg() { UFix() }; val id_reg_pc_plus4 = Reg() { UFix(width = VADDR_BITS+1) };
// execute definitions // execute definitions
val ex_reg_valid = Reg(resetVal = Bool(false)); 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)); Cat(Fill(52, ex_reg_inst(31)), ex_reg_inst(31,27), ex_reg_inst(16,10));
val branch_adder_rhs = 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)), 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-2,0), 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 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 btb.io.correct_target := jr_br_target
val if_next_pc = 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_EX4, ex_reg_pc_plus4,
Mux(io.ctrl.sel_pc === PC_BR, ex_branch_target, 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_JR, ex_jr_target_extended,
Mux(io.ctrl.sel_pc === PC_PCR, wb_reg_wdata(VADDR_BITS-1,0), // only used for ERET Mux(io.ctrl.sel_pc === PC_PCR, wb_reg_wdata(VADDR_BITS,0), // only used for ERET
Mux(io.ctrl.sel_pc === PC_EVEC, pcr.io.evec, 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, Mux(io.ctrl.sel_pc === PC_WB, wb_reg_pc,
if_pc_plus4))))))); // PC_4 if_pc_plus4))))))); // PC_4
@ -155,8 +156,7 @@ class rocketDpath extends Component
if_reg_pc <== if_next_pc.toUFix; 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)
io.ctrl.xcpt_ma_inst := if_next_pc(1,0) != Bits(0,2)
io.imem.req_addr := io.imem.req_addr :=
Mux(io.ctrl.stallf, if_reg_pc, Mux(io.ctrl.stallf, if_reg_pc,
@ -172,7 +172,7 @@ class rocketDpath extends Component
// instruction decode stage // instruction decode stage
when (!io.ctrl.stalld) { when (!io.ctrl.stalld) {
id_reg_pc <== if_reg_pc; id_reg_pc <== if_reg_pc;
id_reg_pc_plus4 <== if_pc_plus4; id_reg_pc_plus4 <== if_pc_plus4;
when(io.ctrl.killf) { when(io.ctrl.killf) {
id_reg_inst <== NOP; id_reg_inst <== NOP;
id_reg_valid <== Bool(false); id_reg_valid <== Bool(false);
@ -314,7 +314,7 @@ class rocketDpath extends Component
// D$ request interface (registered inside D$ module) // D$ request interface (registered inside D$ module)
// other signals (req_val, req_rdy) connect to control module // other signals (req_val, req_rdy) connect to control module
io.dmem.req_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_data := ex_reg_rs2;
io.dmem.req_tag := ex_reg_waddr; io.dmem.req_tag := ex_reg_waddr;

View File

@ -53,7 +53,7 @@ class ioDpathPCR extends Bundle()
val exception = Bool(INPUT); val exception = Bool(INPUT);
val cause = UFix(5, INPUT); val cause = UFix(5, INPUT);
val badvaddr_wen = Bool(INPUT); val badvaddr_wen = Bool(INPUT);
val pc = UFix(VADDR_BITS, INPUT); val pc = UFix(VADDR_BITS+1, INPUT);
val eret = Bool(INPUT); val eret = Bool(INPUT);
val ei = Bool(INPUT); val ei = Bool(INPUT);
val di = 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) { 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) { 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_ec <== HAVE_RVC && io.w.data(SR_EC).toBool;
reg_status_et <== io.w.data(SR_ET).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_EPC) { reg_epc <== io.w.data(VADDR_BITS,0).toUFix; }
when (io.w.addr === PCR_BADVADDR) { reg_badvaddr <== io.w.data(VADDR_BITS-1,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_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_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); } 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); } when (!io.r.en) { rdata <== Bits(0,64); }
switch (io.r.addr) { switch (io.r.addr) {
is (PCR_STATUS) { rdata <== Cat(Bits(0,47), reg_status_vm, reg_status_im, reg_status); } 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_EPC) { rdata <== Cat(Fill(64-VADDR_BITS-1, reg_epc(VADDR_BITS)), reg_epc); }
is (PCR_BADVADDR) { rdata <== Cat(Fill(64-VADDR_BITS, reg_badvaddr(VADDR_BITS-1)), reg_badvaddr); } 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_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_COUNT) { rdata <== Cat(Fill(32, reg_count(31)), reg_count); }
is (PCR_COMPARE) { rdata <== Cat(Fill(32, reg_compare(31)), reg_compare); } is (PCR_COMPARE) { rdata <== Cat(Fill(32, reg_compare(31)), reg_compare); }

View File

@ -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_cmd = Bits(4, INPUT); // load/store/amo
val req_rdy = Bool(OUTPUT); val req_rdy = Bool(OUTPUT);
val req_asid = Bits(ASID_BITS, INPUT); val req_asid = Bits(ASID_BITS, INPUT);
val req_vpn = UFix(VPN_BITS, INPUT); val req_vpn = UFix(VPN_BITS+1, INPUT);
// lookup responses // lookup responses
val resp_miss = Bool(OUTPUT); val resp_miss = Bool(OUTPUT);
// val resp_val = 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_store = (r_cpu_req_cmd === M_XWR);
val req_amo = r_cpu_req_cmd(3).toBool; 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_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 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.clear := io.cpu.invalidate;
tag_cam.io.tag := lookup_tag; tag_cam.io.tag := lookup_tag;
tag_cam.io.write := io.ptw.resp_val || io.ptw.resp_err; tag_cam.io.write := io.ptw.resp_val || io.ptw.resp_err;
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 || bad_va;
val tag_hit_addr = tag_cam.io.hit_addr; val tag_hit_addr = tag_cam.io.hit_addr;
// extract fields from status register // extract fields from status register
@ -140,14 +141,16 @@ class rocketDTLB(entries: Int) extends Component
val access_fault_ld = val access_fault_ld =
tlb_hit && (req_load || req_amo) && tlb_hit && (req_load || req_amo) &&
((status_s && !sr_array(tag_hit_addr).toBool) || ((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; io.cpu.xcpt_ld := access_fault_ld;
val access_fault_st = val access_fault_st =
tlb_hit && (req_store || req_amo) && tlb_hit && (req_store || req_amo) &&
((status_s && !sw_array(tag_hit_addr).toBool) || ((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; io.cpu.xcpt_st := access_fault_st;

View File

@ -74,7 +74,7 @@ class ioITLB_CPU(view: List[String] = null) extends Bundle(view)
val req_val = Bool(INPUT); val req_val = Bool(INPUT);
val req_rdy = Bool(OUTPUT); val req_rdy = Bool(OUTPUT);
val req_asid = Bits(ASID_BITS, INPUT); val req_asid = Bits(ASID_BITS, INPUT);
val req_vpn = UFix(VPN_BITS, INPUT); val req_vpn = UFix(VPN_BITS+1, INPUT);
// lookup responses // lookup responses
val resp_miss = Bool(OUTPUT); val resp_miss = Bool(OUTPUT);
// val resp_val = Bool(OUTPUT); // val resp_val = Bool(OUTPUT);
@ -111,18 +111,19 @@ class rocketITLB(entries: Int) extends Component
otherwise { otherwise {
r_cpu_req_val <== Bool(false); 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_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 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.clear := io.cpu.invalidate;
tag_cam.io.tag := lookup_tag; tag_cam.io.tag := lookup_tag;
tag_cam.io.write := io.ptw.resp_val || io.ptw.resp_err; tag_cam.io.write := io.ptw.resp_val || io.ptw.resp_err;
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 || bad_va;
val tag_hit_addr = tag_cam.io.hit_addr; val tag_hit_addr = tag_cam.io.hit_addr;
// extract fields from status register // 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 = val access_fault =
tlb_hit && tlb_hit &&
((status_s && !sx_array(tag_hit_addr).toBool) || ((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.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_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; io.cpu.resp_ppn := Mux(status_vm, tag_ram(tag_hit_addr), r_cpu_req_vpn(PPN_BITS-1,0)).toUFix;