added misaligned instruction check, cleaned up badvaddr handling
This commit is contained in:
parent
603ede8bfe
commit
4bd0263a4a
@ -168,7 +168,8 @@ object Constants
|
|||||||
|
|
||||||
// physical memory size (# 4K pages - for proxy kernel at least)
|
// physical memory size (# 4K pages - for proxy kernel at least)
|
||||||
// if you change this value, make sure to also change MEMORY_SIZE variable in memif.h
|
// if you change this value, make sure to also change MEMORY_SIZE variable in memif.h
|
||||||
val MEMSIZE = Bits("h2000", 64); // 32 megs
|
val MEMSIZE_PAGES = 8192; // 32 megs
|
||||||
|
val MEMSIZE = MEMSIZE_PAGES*4096;
|
||||||
|
|
||||||
val HAVE_FPU = Bool(false);
|
val HAVE_FPU = Bool(false);
|
||||||
val HAVE_VEC = Bool(false);
|
val HAVE_VEC = Bool(false);
|
||||||
|
@ -39,9 +39,9 @@ class ioCtrlDpath extends Bundle()
|
|||||||
// exception handling
|
// exception handling
|
||||||
val exception = Bool('output);
|
val exception = Bool('output);
|
||||||
val cause = UFix(5,'output);
|
val cause = UFix(5,'output);
|
||||||
val badvaddr_wen = Bool('output); // high for any access fault
|
val badvaddr_wen = Bool('output); // high for a load/store access fault
|
||||||
val badvaddr_sel = Bool('output); // select between instruction PC or load/store addr
|
|
||||||
// inputs from datapath
|
// inputs from datapath
|
||||||
|
val xcpt_ma_inst = Bool('input); // high on a misaligned/illegal virtual PC
|
||||||
val btb_hit = Bool('input);
|
val btb_hit = Bool('input);
|
||||||
val inst = Bits(32, 'input);
|
val inst = Bits(32, 'input);
|
||||||
val br_eq = Bool('input);
|
val br_eq = Bool('input);
|
||||||
@ -191,6 +191,11 @@ class rocketCtrl extends Component
|
|||||||
*/
|
*/
|
||||||
));
|
));
|
||||||
|
|
||||||
|
val if_reg_xcpt_ma_inst = Reg(io.dpath.xcpt_ma_inst);
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
io.imem.req_val := io.host.start && !io.dpath.xcpt_ma_inst;
|
||||||
|
|
||||||
val id_int_val :: id_br_type :: id_renx2 :: id_renx1 :: id_sel_alu2 :: id_sel_alu1 :: id_fn_dw :: id_fn_alu :: csremainder = cs;
|
val id_int_val :: id_br_type :: id_renx2 :: id_renx1 :: id_sel_alu2 :: id_sel_alu1 :: id_fn_dw :: id_fn_alu :: csremainder = cs;
|
||||||
val id_mem_val :: id_mem_cmd :: id_mem_type :: id_mul_val :: id_mul_fn :: id_div_val :: id_div_fn :: id_wen :: id_sel_wa :: id_sel_wb :: id_ren_pcr :: id_wen_pcr :: id_sync :: id_eret :: id_syscall :: id_privileged :: Nil = csremainder;
|
val id_mem_val :: id_mem_cmd :: id_mem_type :: id_mul_val :: id_mul_fn :: id_div_val :: id_div_fn :: id_wen :: id_sel_wa :: id_sel_wb :: id_ren_pcr :: id_wen_pcr :: id_sync :: id_eret :: id_syscall :: id_privileged :: Nil = csremainder;
|
||||||
|
|
||||||
@ -227,8 +232,9 @@ class rocketCtrl extends Component
|
|||||||
val id_stall_waddr = sboard.io.stallc;
|
val id_stall_waddr = sboard.io.stallc;
|
||||||
val id_stall_ra = sboard.io.stallra;
|
val id_stall_ra = sboard.io.stallra;
|
||||||
|
|
||||||
val id_reg_btb_hit = Reg(resetVal = Bool(false));
|
val id_reg_btb_hit = Reg(resetVal = Bool(false));
|
||||||
val id_reg_xcpt_itlb = Reg(resetVal = Bool(false));
|
val id_reg_xcpt_itlb = Reg(resetVal = Bool(false));
|
||||||
|
val id_reg_xcpt_ma_inst = Reg(resetVal = Bool(false));
|
||||||
|
|
||||||
val ex_reg_br_type = Reg(){UFix(width = 4)};
|
val ex_reg_br_type = Reg(){UFix(width = 4)};
|
||||||
val ex_reg_btb_hit = Reg(){Bool()};
|
val ex_reg_btb_hit = Reg(){Bool()};
|
||||||
@ -239,12 +245,14 @@ class rocketCtrl extends Component
|
|||||||
val ex_reg_eret = Reg(resetVal = Bool(false));
|
val ex_reg_eret = Reg(resetVal = Bool(false));
|
||||||
val ex_reg_privileged = Reg(resetVal = Bool(false));
|
val ex_reg_privileged = Reg(resetVal = Bool(false));
|
||||||
|
|
||||||
|
val ex_reg_xcpt_ma_inst = Reg(resetVal = Bool(false));
|
||||||
val ex_reg_xcpt_itlb = Reg(resetVal = Bool(false));
|
val ex_reg_xcpt_itlb = Reg(resetVal = Bool(false));
|
||||||
val ex_reg_xcpt_illegal = Reg(resetVal = Bool(false));
|
val ex_reg_xcpt_illegal = Reg(resetVal = Bool(false));
|
||||||
val ex_reg_xcpt_privileged = Reg(resetVal = Bool(false));
|
val ex_reg_xcpt_privileged = Reg(resetVal = Bool(false));
|
||||||
// val ex_reg_xcpt_fpu = Reg(resetVal = Bool(false));
|
// val ex_reg_xcpt_fpu = Reg(resetVal = Bool(false));
|
||||||
val ex_reg_xcpt_syscall = Reg(resetVal = Bool(false));
|
val ex_reg_xcpt_syscall = Reg(resetVal = Bool(false));
|
||||||
|
|
||||||
|
val mem_reg_xcpt_ma_inst = Reg(resetVal = Bool(false));
|
||||||
val mem_reg_xcpt_itlb = Reg(resetVal = Bool(false));
|
val mem_reg_xcpt_itlb = Reg(resetVal = Bool(false));
|
||||||
val mem_reg_xcpt_illegal = Reg(resetVal = Bool(false));
|
val mem_reg_xcpt_illegal = Reg(resetVal = Bool(false));
|
||||||
val mem_reg_xcpt_privileged = Reg(resetVal = Bool(false));
|
val mem_reg_xcpt_privileged = Reg(resetVal = Bool(false));
|
||||||
@ -254,10 +262,12 @@ class rocketCtrl extends Component
|
|||||||
|
|
||||||
when (!io.dpath.stalld) {
|
when (!io.dpath.stalld) {
|
||||||
when (io.dpath.killf) {
|
when (io.dpath.killf) {
|
||||||
|
id_reg_xcpt_ma_inst <== Bool(false);
|
||||||
id_reg_xcpt_itlb <== Bool(false);
|
id_reg_xcpt_itlb <== Bool(false);
|
||||||
id_reg_btb_hit <== Bool(false);
|
id_reg_btb_hit <== Bool(false);
|
||||||
}
|
}
|
||||||
otherwise{
|
otherwise{
|
||||||
|
id_reg_xcpt_ma_inst <== if_reg_xcpt_ma_inst;
|
||||||
id_reg_xcpt_itlb <== io.xcpt_itlb;
|
id_reg_xcpt_itlb <== io.xcpt_itlb;
|
||||||
id_reg_btb_hit <== io.dpath.btb_hit;
|
id_reg_btb_hit <== io.dpath.btb_hit;
|
||||||
}
|
}
|
||||||
@ -273,6 +283,7 @@ class rocketCtrl extends Component
|
|||||||
ex_reg_eret <== Bool(false);
|
ex_reg_eret <== Bool(false);
|
||||||
ex_reg_privileged <== Bool(false);
|
ex_reg_privileged <== Bool(false);
|
||||||
|
|
||||||
|
ex_reg_xcpt_ma_inst <== Bool(false);
|
||||||
ex_reg_xcpt_itlb <== Bool(false);
|
ex_reg_xcpt_itlb <== Bool(false);
|
||||||
ex_reg_xcpt_illegal <== Bool(false);
|
ex_reg_xcpt_illegal <== Bool(false);
|
||||||
ex_reg_xcpt_privileged <== Bool(false);
|
ex_reg_xcpt_privileged <== Bool(false);
|
||||||
@ -289,6 +300,7 @@ class rocketCtrl extends Component
|
|||||||
ex_reg_eret <== id_eret.toBool;
|
ex_reg_eret <== id_eret.toBool;
|
||||||
ex_reg_privileged <== id_privileged.toBool;
|
ex_reg_privileged <== id_privileged.toBool;
|
||||||
|
|
||||||
|
ex_reg_xcpt_ma_inst <== id_reg_xcpt_ma_inst;
|
||||||
ex_reg_xcpt_itlb <== id_reg_xcpt_itlb;
|
ex_reg_xcpt_itlb <== id_reg_xcpt_itlb;
|
||||||
ex_reg_xcpt_illegal <== ~id_int_val.toBool;
|
ex_reg_xcpt_illegal <== ~id_int_val.toBool;
|
||||||
ex_reg_xcpt_privileged <== (id_privileged & ~io.dpath.status(5)).toBool;
|
ex_reg_xcpt_privileged <== (id_privileged & ~io.dpath.status(5)).toBool;
|
||||||
@ -314,9 +326,6 @@ class rocketCtrl extends Component
|
|||||||
val jr_taken = (ex_reg_br_type === BR_JR);
|
val jr_taken = (ex_reg_br_type === BR_JR);
|
||||||
val j_taken = (ex_reg_br_type === BR_J);
|
val j_taken = (ex_reg_br_type === BR_J);
|
||||||
|
|
||||||
io.imem.req_val := io.host.start; // FIXME
|
|
||||||
// io.imem.req_val := Bool(true);
|
|
||||||
|
|
||||||
io.dmem.req_val := ex_reg_mem_val && ~io.dpath.killx;
|
io.dmem.req_val := ex_reg_mem_val && ~io.dpath.killx;
|
||||||
io.dmem.req_cmd := ex_reg_mem_cmd;
|
io.dmem.req_cmd := ex_reg_mem_cmd;
|
||||||
io.dmem.req_type := ex_reg_mem_type;
|
io.dmem.req_type := ex_reg_mem_type;
|
||||||
@ -336,6 +345,7 @@ class rocketCtrl extends Component
|
|||||||
mem_reg_mem_type <== UFix(0, 3);
|
mem_reg_mem_type <== UFix(0, 3);
|
||||||
mem_reg_privileged <== Bool(false);
|
mem_reg_privileged <== Bool(false);
|
||||||
|
|
||||||
|
mem_reg_xcpt_ma_inst <== Bool(false);
|
||||||
mem_reg_xcpt_itlb <== Bool(false);
|
mem_reg_xcpt_itlb <== Bool(false);
|
||||||
mem_reg_xcpt_illegal <== Bool(false);
|
mem_reg_xcpt_illegal <== Bool(false);
|
||||||
mem_reg_xcpt_privileged <== Bool(false);
|
mem_reg_xcpt_privileged <== Bool(false);
|
||||||
@ -350,6 +360,7 @@ class rocketCtrl extends Component
|
|||||||
mem_reg_mem_type <== ex_reg_mem_type;
|
mem_reg_mem_type <== ex_reg_mem_type;
|
||||||
mem_reg_privileged <== ex_reg_privileged;
|
mem_reg_privileged <== ex_reg_privileged;
|
||||||
|
|
||||||
|
mem_reg_xcpt_ma_inst <== ex_reg_xcpt_ma_inst;
|
||||||
mem_reg_xcpt_itlb <== ex_reg_xcpt_itlb;
|
mem_reg_xcpt_itlb <== ex_reg_xcpt_itlb;
|
||||||
mem_reg_xcpt_illegal <== mem_reg_xcpt_illegal;
|
mem_reg_xcpt_illegal <== mem_reg_xcpt_illegal;
|
||||||
mem_reg_xcpt_privileged <== ex_reg_xcpt_privileged;
|
mem_reg_xcpt_privileged <== ex_reg_xcpt_privileged;
|
||||||
@ -372,10 +383,10 @@ class rocketCtrl extends Component
|
|||||||
mem_reg_xcpt_privileged ||
|
mem_reg_xcpt_privileged ||
|
||||||
mem_reg_xcpt_fpu ||
|
mem_reg_xcpt_fpu ||
|
||||||
mem_reg_xcpt_syscall ||
|
mem_reg_xcpt_syscall ||
|
||||||
mem_reg_xcpt_itlb;
|
mem_reg_xcpt_itlb ||
|
||||||
|
mem_reg_xcpt_ma_inst;
|
||||||
|
|
||||||
val mem_cause =
|
val mem_cause =
|
||||||
// instruction address misaligned
|
|
||||||
Mux(mem_reg_xcpt_itlb, UFix(1,5), // instruction access fault
|
Mux(mem_reg_xcpt_itlb, UFix(1,5), // instruction access fault
|
||||||
Mux(mem_reg_xcpt_illegal, UFix(2,5), // illegal instruction
|
Mux(mem_reg_xcpt_illegal, UFix(2,5), // illegal instruction
|
||||||
Mux(mem_reg_xcpt_privileged, UFix(3,5), // privileged instruction
|
Mux(mem_reg_xcpt_privileged, UFix(3,5), // privileged instruction
|
||||||
@ -387,13 +398,12 @@ class rocketCtrl extends Component
|
|||||||
// misaligned store
|
// misaligned store
|
||||||
Mux(io.xcpt_dtlb_ld, UFix(8,5), // load fault
|
Mux(io.xcpt_dtlb_ld, UFix(8,5), // load fault
|
||||||
Mux(io.xcpt_dtlb_st, UFix(9,5), // store fault
|
Mux(io.xcpt_dtlb_st, UFix(9,5), // store fault
|
||||||
UFix(0,5))))))));
|
UFix(0,5)))))))); // instruction address misaligned
|
||||||
|
|
||||||
// write cause to PCR on an exception
|
// write cause to PCR on an exception
|
||||||
io.dpath.exception := mem_exception;
|
io.dpath.exception := mem_exception;
|
||||||
io.dpath.cause := mem_cause;
|
io.dpath.cause := mem_cause;
|
||||||
io.dpath.badvaddr_wen := io.xcpt_dtlb_ld || io.xcpt_dtlb_st || mem_reg_xcpt_itlb;
|
io.dpath.badvaddr_wen := io.xcpt_dtlb_ld || io.xcpt_dtlb_st;
|
||||||
io.dpath.badvaddr_sel := mem_reg_xcpt_itlb;
|
|
||||||
|
|
||||||
// replay execute stage PC when the D$ is blocked, when the D$ misses, and for privileged instructions
|
// replay execute stage PC when the D$ is blocked, when the D$ misses, and for privileged instructions
|
||||||
val replay_ex = (ex_reg_mem_val && !io.dmem.req_rdy) || io.dmem.resp_miss || mem_reg_privileged;
|
val replay_ex = (ex_reg_mem_val && !io.dmem.req_rdy) || io.dmem.resp_miss || mem_reg_privileged;
|
||||||
|
@ -118,7 +118,6 @@ class rocketDpath extends Component
|
|||||||
val wb_reg_ctrl_exception = Reg(resetVal = Bool(false));
|
val wb_reg_ctrl_exception = Reg(resetVal = Bool(false));
|
||||||
val wb_reg_ctrl_wen = Reg(resetVal = Bool(false));
|
val wb_reg_ctrl_wen = Reg(resetVal = Bool(false));
|
||||||
val wb_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
|
val wb_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
|
||||||
val wb_reg_badvaddr_sel = Reg(resetVal = Bool(false));
|
|
||||||
val wb_reg_badvaddr_wen = Reg(resetVal = Bool(false));
|
val wb_reg_badvaddr_wen = Reg(resetVal = Bool(false));
|
||||||
|
|
||||||
val r_dmem_resp_val = Reg(resetVal = Bool(false));
|
val r_dmem_resp_val = Reg(resetVal = Bool(false));
|
||||||
@ -164,6 +163,8 @@ class rocketDpath extends Component
|
|||||||
if_reg_pc <== if_next_pc;
|
if_reg_pc <== if_next_pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
if_next_pc);
|
if_next_pc);
|
||||||
@ -417,7 +418,6 @@ class rocketDpath extends Component
|
|||||||
wb_reg_ctrl_cause <== io.ctrl.cause;
|
wb_reg_ctrl_cause <== io.ctrl.cause;
|
||||||
wb_reg_mem_req_addr <== io.dmem.req_addr;
|
wb_reg_mem_req_addr <== io.dmem.req_addr;
|
||||||
wb_reg_badvaddr_wen <== io.ctrl.badvaddr_wen;
|
wb_reg_badvaddr_wen <== io.ctrl.badvaddr_wen;
|
||||||
wb_reg_badvaddr_sel <== io.ctrl.badvaddr_sel;
|
|
||||||
|
|
||||||
when (io.ctrl.killm) {
|
when (io.ctrl.killm) {
|
||||||
wb_reg_valid <== Bool(false);
|
wb_reg_valid <== Bool(false);
|
||||||
@ -458,9 +458,8 @@ class rocketDpath extends Component
|
|||||||
pcr.io.exception := wb_reg_ctrl_exception;
|
pcr.io.exception := wb_reg_ctrl_exception;
|
||||||
pcr.io.cause := wb_reg_ctrl_cause;
|
pcr.io.cause := wb_reg_ctrl_cause;
|
||||||
pcr.io.pc := wb_reg_pc;
|
pcr.io.pc := wb_reg_pc;
|
||||||
pcr.io.ldst_addr := wb_reg_mem_req_addr;
|
pcr.io.badvaddr := wb_reg_mem_req_addr;
|
||||||
pcr.io.badvaddr_wen := wb_reg_badvaddr_wen;
|
pcr.io.badvaddr_wen := wb_reg_badvaddr_wen;
|
||||||
pcr.io.badvaddr_sel := wb_reg_badvaddr_sel;
|
|
||||||
|
|
||||||
// temporary debug outputs so things don't get optimized away
|
// temporary debug outputs so things don't get optimized away
|
||||||
io.debug.id_valid := id_reg_valid;
|
io.debug.id_valid := id_reg_valid;
|
||||||
|
@ -41,9 +41,8 @@ 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 badvaddr_sel = Bool('input);
|
|
||||||
val pc = UFix(VADDR_BITS, 'input);
|
val pc = UFix(VADDR_BITS, 'input);
|
||||||
val ldst_addr = UFix(VADDR_BITS, 'input);
|
val badvaddr = UFix(VADDR_BITS, 'input);
|
||||||
val eret = Bool('input);
|
val eret = Bool('input);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +98,7 @@ class rocketDpathPCR extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (io.badvaddr_wen) {
|
when (io.badvaddr_wen) {
|
||||||
reg_badvaddr <== Mux(io.badvaddr_sel, io.pc, io.ldst_addr);
|
reg_badvaddr <== io.badvaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
when (io.exception && !reg_status_et) {
|
when (io.exception && !reg_status_et) {
|
||||||
@ -153,7 +152,7 @@ class rocketDpathPCR extends Component
|
|||||||
is (PCR_COUNT) { rdata <== Cat(Fill(w, reg_count(w-1)), reg_count); }
|
is (PCR_COUNT) { rdata <== Cat(Fill(w, reg_count(w-1)), reg_count); }
|
||||||
is (PCR_COMPARE) { rdata <== Cat(Fill(w, reg_compare(w-1)), reg_compare); }
|
is (PCR_COMPARE) { rdata <== Cat(Fill(w, reg_compare(w-1)), reg_compare); }
|
||||||
is (PCR_CAUSE) { rdata <== Cat(Bits(0,w+27), reg_cause); }
|
is (PCR_CAUSE) { rdata <== Cat(Bits(0,w+27), reg_cause); }
|
||||||
is (PCR_MEMSIZE) { rdata <== MEMSIZE; }
|
is (PCR_MEMSIZE) { rdata <== Bits(MEMSIZE_PAGES, 64); }
|
||||||
is (PCR_LOG) { rdata <== Cat(Bits(0,63), reg_log_control); }
|
is (PCR_LOG) { rdata <== Cat(Bits(0,63), reg_log_control); }
|
||||||
is (PCR_FROMHOST) { rdata <== Cat(Fill(w, reg_fromhost(w-1)), reg_fromhost); }
|
is (PCR_FROMHOST) { rdata <== Cat(Fill(w, reg_fromhost(w-1)), reg_fromhost); }
|
||||||
is (PCR_TOHOST) { rdata <== Cat(Fill(w, reg_tohost(w-1)), reg_tohost); }
|
is (PCR_TOHOST) { rdata <== Cat(Fill(w, reg_tohost(w-1)), reg_tohost); }
|
||||||
|
@ -155,7 +155,8 @@ class rocketITLB(entries: Int) extends Component
|
|||||||
val itlb_exception =
|
val itlb_exception =
|
||||||
io.cpu.req_val && tag_hit &&
|
io.cpu.req_val && tag_hit &&
|
||||||
((status_mode && !sx_array(tag_hit_addr).toBool) ||
|
((status_mode && !sx_array(tag_hit_addr).toBool) ||
|
||||||
(!status_mode && !ux_array(tag_hit_addr).toBool));
|
(!status_mode && !ux_array(tag_hit_addr).toBool) ||
|
||||||
|
(io.cpu.resp_addr >= MEMSIZE));
|
||||||
|
|
||||||
io.cpu.req_rdy := (state === s_ready);
|
io.cpu.req_rdy := (state === s_ready);
|
||||||
io.cpu.resp_val := Mux(status_vm, tag_hit, io.cpu.req_val);
|
io.cpu.resp_val := Mux(status_vm, tag_hit, io.cpu.req_val);
|
||||||
|
Loading…
Reference in New Issue
Block a user