moved PCR writeback to end of MEM stage, cleanup of dcache/dpath/ctrl
This commit is contained in:
parent
5a322ff00c
commit
c42d8149b7
@ -10,7 +10,6 @@ class ioDebug(view: List[String] = null) extends Bundle(view)
|
|||||||
val id_valid = Bool('output);
|
val id_valid = Bool('output);
|
||||||
val ex_valid = Bool('output);
|
val ex_valid = Bool('output);
|
||||||
val mem_valid = Bool('output);
|
val mem_valid = Bool('output);
|
||||||
val wb_valid = Bool('output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ioHost(view: List[String] = null) extends Bundle(view)
|
class ioHost(view: List[String] = null) extends Bundle(view)
|
||||||
@ -73,7 +72,6 @@ class rocketProc extends Component
|
|||||||
// ctrl.io.itlb_miss := itlb.io.cpu.resp_miss;
|
// ctrl.io.itlb_miss := itlb.io.cpu.resp_miss;
|
||||||
io.imem.itlb_miss := itlb.io.cpu.resp_miss;
|
io.imem.itlb_miss := itlb.io.cpu.resp_miss;
|
||||||
|
|
||||||
|
|
||||||
// connect DTLB to D$ arbiter, ctrl+dpath
|
// connect DTLB to D$ arbiter, ctrl+dpath
|
||||||
dtlb.io.cpu.invalidate := dpath.io.ptbr_wen;
|
dtlb.io.cpu.invalidate := dpath.io.ptbr_wen;
|
||||||
dtlb.io.cpu.status := dpath.io.ctrl.status;
|
dtlb.io.cpu.status := dpath.io.ctrl.status;
|
||||||
|
@ -33,7 +33,8 @@ class ioCtrlDpath extends Bundle()
|
|||||||
val sel_wb = UFix(3, 'output);
|
val sel_wb = UFix(3, 'output);
|
||||||
val ren_pcr = Bool('output);
|
val ren_pcr = Bool('output);
|
||||||
val wen_pcr = Bool('output);
|
val wen_pcr = Bool('output);
|
||||||
val eret = Bool('output);
|
val id_eret = Bool('output);
|
||||||
|
val mem_eret = Bool('output);
|
||||||
val mem_load = Bool('output);
|
val mem_load = Bool('output);
|
||||||
val wen = Bool('output);
|
val wen = Bool('output);
|
||||||
// enable/disable interrupts
|
// enable/disable interrupts
|
||||||
@ -247,7 +248,7 @@ class rocketCtrl extends Component
|
|||||||
SYSCALL-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,Y,N),
|
SYSCALL-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,Y,N),
|
||||||
EI-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_EI,SYNC_N,N,N,Y),
|
EI-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_EI,SYNC_N,N,N,Y),
|
||||||
DI-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_DI,SYNC_N,N,N,Y),
|
DI-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_DI,SYNC_N,N,N,Y),
|
||||||
ERET-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_N,Y,N,Y),
|
ERET-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_PCR,REN_N,WEN_N,I_X ,SYNC_N,Y,N,Y),
|
||||||
FENCE-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_D,N,N,N),
|
FENCE-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_D,N,N,N),
|
||||||
FENCE_I-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_I,N,N,N),
|
FENCE_I-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_I,N,N,N),
|
||||||
CFLUSH-> List(Y, BR_N, REN_Y,REN_N,A2_X, A1_X, DW_X, FN_X, M_Y,M_FLA, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,Y),
|
CFLUSH-> List(Y, BR_N, REN_Y,REN_N,A2_X, A1_X, DW_X, FN_X, M_Y,M_FLA, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,Y),
|
||||||
@ -355,10 +356,6 @@ class rocketCtrl extends Component
|
|||||||
val mem_reg_xcpt_fpu = Reg(resetVal = Bool(false));
|
val mem_reg_xcpt_fpu = Reg(resetVal = Bool(false));
|
||||||
val mem_reg_xcpt_syscall = Reg(resetVal = Bool(false));
|
val mem_reg_xcpt_syscall = Reg(resetVal = Bool(false));
|
||||||
|
|
||||||
val wb_reg_inst_di = Reg(resetVal = Bool(false));
|
|
||||||
val wb_reg_inst_ei = Reg(resetVal = Bool(false));
|
|
||||||
val wb_reg_flush_inst = Reg(resetVal = Bool(false));
|
|
||||||
|
|
||||||
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_ma_inst <== Bool(false);
|
||||||
@ -480,18 +477,7 @@ class rocketCtrl extends Component
|
|||||||
mem_reg_xcpt_syscall <== ex_reg_xcpt_syscall;
|
mem_reg_xcpt_syscall <== ex_reg_xcpt_syscall;
|
||||||
}
|
}
|
||||||
|
|
||||||
when (reset.toBool || io.dpath.killm) {
|
wb_reg_div_mul_val <== mem_reg_div_mul_val;
|
||||||
wb_reg_div_mul_val <== Bool(false);
|
|
||||||
wb_reg_inst_di <== Bool(false);
|
|
||||||
wb_reg_inst_ei <== Bool(false);
|
|
||||||
wb_reg_flush_inst <== Bool(false);
|
|
||||||
}
|
|
||||||
otherwise {
|
|
||||||
wb_reg_div_mul_val <== mem_reg_div_mul_val;
|
|
||||||
wb_reg_inst_di <== mem_reg_inst_di;
|
|
||||||
wb_reg_inst_ei <== mem_reg_inst_ei;
|
|
||||||
wb_reg_flush_inst <== mem_reg_flush_inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
// exception handling
|
// exception handling
|
||||||
// FIXME: verify PC in MEM stage points to valid, restartable instruction
|
// FIXME: verify PC in MEM stage points to valid, restartable instruction
|
||||||
@ -645,8 +631,7 @@ class rocketCtrl extends Component
|
|||||||
val mul_wb = io.dpath.mul_result_val;
|
val mul_wb = io.dpath.mul_result_val;
|
||||||
val div_wb = io.dpath.div_result_val & !mul_wb;
|
val div_wb = io.dpath.div_result_val & !mul_wb;
|
||||||
|
|
||||||
|
io.flush_inst := mem_reg_flush_inst;
|
||||||
io.flush_inst := wb_reg_flush_inst;
|
|
||||||
|
|
||||||
io.dpath.stalld := ctrl_stalld.toBool;
|
io.dpath.stalld := ctrl_stalld.toBool;
|
||||||
io.dpath.killf := take_pc | ~io.imem.resp_val;
|
io.dpath.killf := take_pc | ~io.imem.resp_val;
|
||||||
@ -672,9 +657,10 @@ class rocketCtrl extends Component
|
|||||||
io.dpath.sel_wb := id_sel_wb;
|
io.dpath.sel_wb := id_sel_wb;
|
||||||
io.dpath.ren_pcr := id_ren_pcr.toBool;
|
io.dpath.ren_pcr := id_ren_pcr.toBool;
|
||||||
io.dpath.wen_pcr := id_wen_pcr.toBool;
|
io.dpath.wen_pcr := id_wen_pcr.toBool;
|
||||||
io.dpath.eret := id_eret.toBool;
|
io.dpath.id_eret := id_eret.toBool;
|
||||||
io.dpath.irq_disable := wb_reg_inst_di;
|
io.dpath.mem_eret := mem_reg_eret;
|
||||||
io.dpath.irq_enable := wb_reg_inst_ei;
|
io.dpath.irq_disable := mem_reg_inst_di && !kill_mem;
|
||||||
|
io.dpath.irq_enable := mem_reg_inst_ei && !kill_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import scala.math._;
|
|||||||
|
|
||||||
// interface between D$ and processor/DTLB
|
// interface between D$ and processor/DTLB
|
||||||
class ioDmem(view: List[String] = null) extends Bundle(view) {
|
class ioDmem(view: List[String] = null) extends Bundle(view) {
|
||||||
// val dtlb_busy = Bool('input);
|
|
||||||
val dtlb_miss = Bool('input);
|
val dtlb_miss = Bool('input);
|
||||||
val req_val = Bool('input);
|
val req_val = Bool('input);
|
||||||
val req_rdy = Bool('output);
|
val req_rdy = Bool('output);
|
||||||
@ -48,7 +47,7 @@ class rocketDCacheStoreGen extends Component {
|
|||||||
val req_type = Bits(3, 'input);
|
val req_type = Bits(3, 'input);
|
||||||
val req_addr_lsb = Bits(3, 'input);
|
val req_addr_lsb = Bits(3, 'input);
|
||||||
val req_data = Bits(64, 'input);
|
val req_data = Bits(64, 'input);
|
||||||
val store_wmask = Bits(8, 'output);
|
val store_wmask = Bits(64, 'output);
|
||||||
val store_data = Bits(64, 'output);
|
val store_data = Bits(64, 'output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +85,16 @@ class rocketDCacheStoreGen extends Component {
|
|||||||
Mux(io.req_type === MT_D, wmask_d,
|
Mux(io.req_type === MT_D, wmask_d,
|
||||||
UFix(0, 8)))));
|
UFix(0, 8)))));
|
||||||
|
|
||||||
io.store_wmask := store_wmask_byte;
|
val store_wmask_d = Cat(Fill(8, store_wmask_byte(7)),
|
||||||
|
Fill(8, store_wmask_byte(6)),
|
||||||
|
Fill(8, store_wmask_byte(5)),
|
||||||
|
Fill(8, store_wmask_byte(4)),
|
||||||
|
Fill(8, store_wmask_byte(3)),
|
||||||
|
Fill(8, store_wmask_byte(2)),
|
||||||
|
Fill(8, store_wmask_byte(1)),
|
||||||
|
Fill(8, store_wmask_byte(0)));
|
||||||
|
|
||||||
|
io.store_wmask := store_wmask_d;
|
||||||
|
|
||||||
io.store_data :=
|
io.store_data :=
|
||||||
Mux(io.req_type === MT_B, Fill(8, io.req_data( 7,0)),
|
Mux(io.req_type === MT_B, Fill(8, io.req_data( 7,0)),
|
||||||
@ -260,7 +268,7 @@ class rocketDCacheDM(lines: Int) extends Component {
|
|||||||
when (tag_we && r_req_flush) {
|
when (tag_we && r_req_flush) {
|
||||||
vb_array <== vb_array.bitSet(r_cpu_req_idx(PGIDX_BITS-1,offsetbits).toUFix, UFix(0,1));
|
vb_array <== vb_array.bitSet(r_cpu_req_idx(PGIDX_BITS-1,offsetbits).toUFix, UFix(0,1));
|
||||||
}
|
}
|
||||||
val vb_rdata = Reg(vb_array(tag_addr).toBool);
|
val vb_rdata = vb_array(r_cpu_req_idx(PGIDX_BITS-1,offsetbits).toUFix).toBool;
|
||||||
val tag_valid = r_cpu_req_val && vb_rdata;
|
val tag_valid = r_cpu_req_val && vb_rdata;
|
||||||
val tag_match = (tag_rdata === io.cpu.req_ppn);
|
val tag_match = (tag_rdata === io.cpu.req_ppn);
|
||||||
val tag_hit = tag_valid && tag_match;
|
val tag_hit = tag_valid && tag_match;
|
||||||
@ -282,28 +290,28 @@ class rocketDCacheDM(lines: Int) extends Component {
|
|||||||
// after the cache line refill has completed
|
// after the cache line refill has completed
|
||||||
val resolve_store = (state === s_resolve_miss) && r_req_store;
|
val resolve_store = (state === s_resolve_miss) && r_req_store;
|
||||||
|
|
||||||
// dirty bit array
|
// pending store data
|
||||||
val db_array = Reg(resetVal = Bits(0, lines));
|
|
||||||
val tag_dirty = Reg(db_array(tag_addr)).toBool;
|
|
||||||
|
|
||||||
when (io.cpu.req_val && io.cpu.req_rdy && req_store) {
|
when (io.cpu.req_val && io.cpu.req_rdy && req_store) {
|
||||||
p_store_idx <== io.cpu.req_idx;
|
p_store_idx <== io.cpu.req_idx;
|
||||||
p_store_data <== io.cpu.req_data;
|
p_store_data <== io.cpu.req_data;
|
||||||
p_store_type <== io.cpu.req_type;
|
p_store_type <== io.cpu.req_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
when (io.cpu.req_val && io.cpu.req_rdy && req_amo) {
|
|
||||||
r_amo_data <== io.cpu.req_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
when (store_hit && !drain_store) {
|
when (store_hit && !drain_store) {
|
||||||
p_store_valid <== Bool(true);
|
p_store_valid <== Bool(true);
|
||||||
}
|
}
|
||||||
when (drain_store) {
|
when (drain_store) {
|
||||||
p_store_valid <== Bool(false);
|
p_store_valid <== Bool(false);
|
||||||
db_array <== db_array.bitSet(p_store_idx(PGIDX_BITS-1,offsetbits).toUFix, UFix(1,1));
|
|
||||||
}
|
}
|
||||||
when (resolve_store) {
|
|
||||||
|
// AMO operand
|
||||||
|
when (io.cpu.req_val && io.cpu.req_rdy && req_amo) {
|
||||||
|
r_amo_data <== io.cpu.req_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dirty bit array
|
||||||
|
val db_array = Reg(resetVal = Bits(0, lines));
|
||||||
|
val tag_dirty = db_array(r_cpu_req_idx(PGIDX_BITS-1,offsetbits).toUFix).toBool;
|
||||||
|
when ((r_cpu_req_val && !io.cpu.dtlb_miss && tag_hit && r_req_store) || resolve_store) {
|
||||||
db_array <== db_array.bitSet(p_store_idx(PGIDX_BITS-1,offsetbits).toUFix, UFix(1,1));
|
db_array <== db_array.bitSet(p_store_idx(PGIDX_BITS-1,offsetbits).toUFix, UFix(1,1));
|
||||||
}
|
}
|
||||||
when (state === s_write_amo) {
|
when (state === s_write_amo) {
|
||||||
@ -319,17 +327,8 @@ class rocketDCacheDM(lines: Int) extends Component {
|
|||||||
storegen.io.req_data := p_store_data;
|
storegen.io.req_data := p_store_data;
|
||||||
storegen.io.req_type := p_store_type;
|
storegen.io.req_type := p_store_type;
|
||||||
val store_data = Fill(2, storegen.io.store_data);
|
val store_data = Fill(2, storegen.io.store_data);
|
||||||
val store_wmask_b = storegen.io.store_wmask;
|
val store_wmask_d = storegen.io.store_wmask;
|
||||||
val store_wmask_d = Cat(Fill(8, store_wmask_b(7)),
|
val store_wmask = Mux(p_store_idx(offsetlsb).toBool, Cat(store_wmask_d, Bits(0,64)), Cat(Bits(0,64), store_wmask_d));
|
||||||
Fill(8, store_wmask_b(6)),
|
|
||||||
Fill(8, store_wmask_b(5)),
|
|
||||||
Fill(8, store_wmask_b(4)),
|
|
||||||
Fill(8, store_wmask_b(3)),
|
|
||||||
Fill(8, store_wmask_b(2)),
|
|
||||||
Fill(8, store_wmask_b(1)),
|
|
||||||
Fill(8, store_wmask_b(0)));
|
|
||||||
val store_idx_sel = p_store_idx(offsetlsb).toBool;
|
|
||||||
val store_wmask = Mux(store_idx_sel, Cat(store_wmask_d, Bits(0,64)), Cat(Bits(0,64), store_wmask_d));
|
|
||||||
|
|
||||||
// data array
|
// data array
|
||||||
val data_array = new rocketSRAMsp(lines*4, 128);
|
val data_array = new rocketSRAMsp(lines*4, 128);
|
||||||
@ -352,8 +351,7 @@ class rocketDCacheDM(lines: Int) extends Component {
|
|||||||
Fill(8, amo_wmask(1)),
|
Fill(8, amo_wmask(1)),
|
||||||
Fill(8, amo_wmask(0)));
|
Fill(8, amo_wmask(0)));
|
||||||
|
|
||||||
val amo_store_idx_sel = r_cpu_req_idx(offsetlsb).toBool;
|
val amo_store_wmask = Mux(r_cpu_req_idx(offsetlsb).toBool, Cat(amo_store_wmask_d, Bits(0,64)), Cat(Bits(0,64), amo_store_wmask_d));
|
||||||
val amo_store_wmask = Mux(amo_store_idx_sel, Cat(amo_store_wmask_d, Bits(0,64)), Cat(Bits(0,64), amo_store_wmask_d));
|
|
||||||
|
|
||||||
val amo_alu = new rocketDCacheAmoALU();
|
val amo_alu = new rocketDCacheAmoALU();
|
||||||
amo_alu.io.cmd := r_cpu_req_cmd;
|
amo_alu.io.cmd := r_cpu_req_cmd;
|
||||||
@ -373,6 +371,7 @@ class rocketDCacheDM(lines: Int) extends Component {
|
|||||||
Mux((state === s_refill), io.mem.resp_data,
|
Mux((state === s_refill), io.mem.resp_data,
|
||||||
Mux((state === s_write_amo), amo_alu_out,
|
Mux((state === s_write_amo), amo_alu_out,
|
||||||
store_data));
|
store_data));
|
||||||
|
|
||||||
data_array.io.we :=
|
data_array.io.we :=
|
||||||
((state === s_refill) && io.mem.resp_val) ||
|
((state === s_refill) && io.mem.resp_val) ||
|
||||||
(state === s_write_amo) ||
|
(state === s_write_amo) ||
|
||||||
|
@ -60,7 +60,7 @@ 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(0,VADDR_BITS));
|
val if_reg_pc = Reg(resetVal = UFix(0,VADDR_BITS));
|
||||||
|
|
||||||
// instruction decode definitions
|
// instruction decode definitions
|
||||||
val id_reg_valid = Reg(resetVal = Bool(false));
|
val id_reg_valid = Reg(resetVal = Bool(false));
|
||||||
@ -80,6 +80,7 @@ class rocketDpath extends Component
|
|||||||
val ex_reg_waddr = Reg(resetVal = UFix(0,5));
|
val ex_reg_waddr = Reg(resetVal = UFix(0,5));
|
||||||
val ex_reg_ctrl_sel_alu2 = Reg(resetVal = A2_X);
|
val ex_reg_ctrl_sel_alu2 = Reg(resetVal = A2_X);
|
||||||
val ex_reg_ctrl_sel_alu1 = Reg(resetVal = A1_X);
|
val ex_reg_ctrl_sel_alu1 = Reg(resetVal = A1_X);
|
||||||
|
val ex_reg_ctrl_eret = Reg(resetVal = Bool(false));
|
||||||
val ex_reg_ctrl_fn_dw = Reg(resetVal = DW_X);
|
val ex_reg_ctrl_fn_dw = Reg(resetVal = DW_X);
|
||||||
val ex_reg_ctrl_fn_alu = Reg(resetVal = FN_X);
|
val ex_reg_ctrl_fn_alu = Reg(resetVal = FN_X);
|
||||||
val ex_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
|
val ex_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
|
||||||
@ -91,36 +92,23 @@ class rocketDpath extends Component
|
|||||||
val ex_reg_ctrl_wen = Reg(resetVal = Bool(false));
|
val ex_reg_ctrl_wen = Reg(resetVal = Bool(false));
|
||||||
val ex_reg_ctrl_ren_pcr = Reg(resetVal = Bool(false));
|
val ex_reg_ctrl_ren_pcr = Reg(resetVal = Bool(false));
|
||||||
val ex_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
|
val ex_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
|
||||||
val ex_reg_ctrl_eret = Reg(resetVal = Bool(false));
|
|
||||||
val ex_wdata = Wire() { Bits() };
|
val ex_wdata = Wire() { Bits() };
|
||||||
|
|
||||||
// memory definitions
|
// memory definitions
|
||||||
val mem_reg_valid = Reg(resetVal = Bool(false));
|
val mem_reg_valid = Reg(resetVal = Bool(false));
|
||||||
val mem_reg_pc = Reg(resetVal = UFix(0,VADDR_BITS));
|
val mem_reg_pc = Reg(resetVal = UFix(0,VADDR_BITS));
|
||||||
val mem_reg_pc_plus4 = Reg(resetVal = UFix(0,VADDR_BITS));
|
|
||||||
val mem_reg_waddr = Reg(resetVal = UFix(0,5));
|
val mem_reg_waddr = Reg(resetVal = UFix(0,5));
|
||||||
val mem_reg_wdata = Reg(resetVal = Bits(0,64));
|
val mem_reg_wdata = Reg(resetVal = Bits(0,64));
|
||||||
val mem_reg_raddr2 = Reg(resetVal = UFix(0,5));
|
val mem_reg_raddr2 = Reg(resetVal = UFix(0,5));
|
||||||
val mem_reg_pcr = Reg(resetVal = Bits(0,64));
|
|
||||||
val mem_reg_ctrl_eret = Reg(resetVal = Bool(false));
|
|
||||||
val mem_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
|
val mem_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
|
||||||
val mem_reg_ctrl_wen = Reg(resetVal = Bool(false));
|
val mem_reg_ctrl_wen = Reg(resetVal = Bool(false));
|
||||||
val mem_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
|
val mem_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
|
||||||
|
|
||||||
// writeback definitions
|
// writeback definitions
|
||||||
val wb_reg_valid = Reg(resetVal = Bool(false));
|
|
||||||
val wb_reg_pc = Reg(resetVal = UFix(0,VADDR_BITS));
|
|
||||||
val wb_reg_mem_req_addr = Reg(resetVal = UFix(0,VADDR_BITS));
|
|
||||||
val wb_reg_waddr = Reg(resetVal = UFix(0,5));
|
val wb_reg_waddr = Reg(resetVal = UFix(0,5));
|
||||||
val wb_reg_wdata = Reg(resetVal = Bits(0,64));
|
val wb_reg_wdata = Reg(resetVal = Bits(0,64));
|
||||||
val wb_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
|
val wb_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
|
||||||
val wb_reg_raddr2 = Reg(resetVal = UFix(0,5));
|
|
||||||
val wb_reg_ctrl_cause = Reg(resetVal = UFix(0,5));
|
|
||||||
val wb_reg_ctrl_eret = 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_badvaddr_wen = Reg(resetVal = Bool(false));
|
|
||||||
|
|
||||||
val r_dmem_resp_val = Reg(resetVal = Bool(false));
|
val r_dmem_resp_val = Reg(resetVal = Bool(false));
|
||||||
val r_dmem_resp_waddr = Reg(resetVal = UFix(0,5));
|
val r_dmem_resp_waddr = Reg(resetVal = UFix(0,5));
|
||||||
@ -153,7 +141,7 @@ class rocketDpath extends Component
|
|||||||
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_J, ex_branch_target,
|
Mux(io.ctrl.sel_pc === PC_J, ex_branch_target,
|
||||||
Mux(io.ctrl.sel_pc === PC_JR, ex_jr_target.toUFix,
|
Mux(io.ctrl.sel_pc === PC_JR, ex_jr_target.toUFix,
|
||||||
Mux(io.ctrl.sel_pc === PC_PCR, mem_reg_pcr(VADDR_BITS-1,0).toUFix, // only used for ERET
|
Mux(io.ctrl.sel_pc === PC_PCR, mem_reg_wdata, // only used for ERET
|
||||||
Mux(io.ctrl.sel_pc === PC_EVEC, pcr.io.evec,
|
Mux(io.ctrl.sel_pc === PC_EVEC, pcr.io.evec,
|
||||||
Mux(io.ctrl.sel_pc === PC_MEM, mem_reg_pc,
|
Mux(io.ctrl.sel_pc === PC_MEM, mem_reg_pc,
|
||||||
UFix(0, VADDR_BITS)))))))))));
|
UFix(0, VADDR_BITS)))))))))));
|
||||||
@ -162,14 +150,15 @@ class rocketDpath extends Component
|
|||||||
if_reg_pc <== UFix(START_ADDR, VADDR_BITS);
|
if_reg_pc <== UFix(START_ADDR, VADDR_BITS);
|
||||||
}
|
}
|
||||||
when (!io.ctrl.stallf) {
|
when (!io.ctrl.stallf) {
|
||||||
if_reg_pc <== if_next_pc;
|
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,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.toUFix);
|
||||||
|
|
||||||
btb.io.current_pc4 := if_pc_plus4;
|
btb.io.current_pc4 := if_pc_plus4;
|
||||||
btb.io.hit ^^ io.ctrl.btb_hit;
|
btb.io.hit ^^ io.ctrl.btb_hit;
|
||||||
@ -294,7 +283,7 @@ class rocketDpath extends Component
|
|||||||
ex_reg_ctrl_mul_val <== io.ctrl.mul_val;
|
ex_reg_ctrl_mul_val <== io.ctrl.mul_val;
|
||||||
ex_reg_ctrl_wen <== io.ctrl.wen;
|
ex_reg_ctrl_wen <== io.ctrl.wen;
|
||||||
ex_reg_ctrl_wen_pcr <== io.ctrl.wen_pcr;
|
ex_reg_ctrl_wen_pcr <== io.ctrl.wen_pcr;
|
||||||
ex_reg_ctrl_eret <== io.ctrl.eret;
|
ex_reg_ctrl_eret <== io.ctrl.id_eret;
|
||||||
}
|
}
|
||||||
|
|
||||||
val ex_alu_in2 =
|
val ex_alu_in2 =
|
||||||
@ -338,7 +327,7 @@ class rocketDpath extends Component
|
|||||||
|
|
||||||
io.ctrl.mul_result_val := mul.io.result_val;
|
io.ctrl.mul_result_val := mul.io.result_val;
|
||||||
|
|
||||||
io.ctrl.ex_waddr := ex_reg_waddr; // for load/use hazard detection
|
io.ctrl.ex_waddr := ex_reg_waddr; // for load/use hazard detection & bypass control
|
||||||
|
|
||||||
// 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
|
||||||
@ -385,8 +374,6 @@ class rocketDpath extends Component
|
|||||||
|
|
||||||
// memory stage
|
// memory stage
|
||||||
mem_reg_pc <== ex_reg_pc;
|
mem_reg_pc <== ex_reg_pc;
|
||||||
mem_reg_pc_plus4 <== ex_reg_pc_plus4;
|
|
||||||
mem_reg_pcr <== ex_pcr;
|
|
||||||
mem_reg_waddr <== ex_reg_waddr;
|
mem_reg_waddr <== ex_reg_waddr;
|
||||||
mem_reg_wdata <== ex_wdata;
|
mem_reg_wdata <== ex_wdata;
|
||||||
mem_reg_ctrl_ll_wb <== ex_reg_ctrl_ll_wb;
|
mem_reg_ctrl_ll_wb <== ex_reg_ctrl_ll_wb;
|
||||||
@ -394,13 +381,11 @@ class rocketDpath extends Component
|
|||||||
|
|
||||||
when (io.ctrl.killx) {
|
when (io.ctrl.killx) {
|
||||||
mem_reg_valid <== Bool(false);
|
mem_reg_valid <== Bool(false);
|
||||||
mem_reg_ctrl_eret <== Bool(false);
|
|
||||||
mem_reg_ctrl_wen <== Bool(false);
|
mem_reg_ctrl_wen <== Bool(false);
|
||||||
mem_reg_ctrl_wen_pcr <== Bool(false);
|
mem_reg_ctrl_wen_pcr <== Bool(false);
|
||||||
}
|
}
|
||||||
otherwise {
|
otherwise {
|
||||||
mem_reg_valid <== ex_reg_valid;
|
mem_reg_valid <== ex_reg_valid;
|
||||||
mem_reg_ctrl_eret <== ex_reg_ctrl_eret;
|
|
||||||
mem_reg_ctrl_wen <== ex_reg_ctrl_wen;
|
mem_reg_ctrl_wen <== ex_reg_ctrl_wen;
|
||||||
mem_reg_ctrl_wen_pcr <== ex_reg_ctrl_wen_pcr;
|
mem_reg_ctrl_wen_pcr <== ex_reg_ctrl_wen_pcr;
|
||||||
}
|
}
|
||||||
@ -418,26 +403,15 @@ class rocketDpath extends Component
|
|||||||
r_dmem_resp_type <== dmem_resp_type;
|
r_dmem_resp_type <== dmem_resp_type;
|
||||||
r_dmem_resp_data <== mem_dmem_resp_data;
|
r_dmem_resp_data <== mem_dmem_resp_data;
|
||||||
|
|
||||||
wb_reg_pc <== mem_reg_pc;
|
|
||||||
wb_reg_waddr <== mem_reg_waddr;
|
wb_reg_waddr <== mem_reg_waddr;
|
||||||
wb_reg_wdata <== mem_reg_wdata;
|
wb_reg_wdata <== mem_reg_wdata;
|
||||||
wb_reg_ctrl_ll_wb <== mem_reg_ctrl_ll_wb;
|
wb_reg_ctrl_ll_wb <== mem_reg_ctrl_ll_wb;
|
||||||
wb_reg_raddr2 <== mem_reg_raddr2;
|
|
||||||
wb_reg_ctrl_eret <== mem_reg_ctrl_eret;
|
|
||||||
wb_reg_ctrl_exception <== io.ctrl.exception;
|
|
||||||
wb_reg_ctrl_cause <== io.ctrl.cause;
|
|
||||||
wb_reg_mem_req_addr <== io.dmem.req_addr;
|
|
||||||
wb_reg_badvaddr_wen <== io.ctrl.badvaddr_wen;
|
|
||||||
|
|
||||||
when (io.ctrl.killm) {
|
when (io.ctrl.killm) {
|
||||||
wb_reg_valid <== Bool(false);
|
|
||||||
wb_reg_ctrl_wen <== Bool(false);
|
wb_reg_ctrl_wen <== Bool(false);
|
||||||
wb_reg_ctrl_wen_pcr <== Bool(false);
|
|
||||||
}
|
}
|
||||||
otherwise {
|
otherwise {
|
||||||
wb_reg_valid <== mem_reg_valid;
|
|
||||||
wb_reg_ctrl_wen <== mem_reg_ctrl_wen;
|
wb_reg_ctrl_wen <== mem_reg_ctrl_wen;
|
||||||
wb_reg_ctrl_wen_pcr <== mem_reg_ctrl_wen_pcr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// crossbar/sign extension for 8/16 bit loads (moved to earlier in file)
|
// crossbar/sign extension for 8/16 bit loads (moved to earlier in file)
|
||||||
@ -460,24 +434,22 @@ class rocketDpath extends Component
|
|||||||
io.ctrl.sboard_clr1a := r_dmem_resp_waddr;
|
io.ctrl.sboard_clr1a := r_dmem_resp_waddr;
|
||||||
|
|
||||||
// processor control regfile write
|
// processor control regfile write
|
||||||
pcr.io.w.addr := wb_reg_raddr2;
|
pcr.io.w.addr := mem_reg_raddr2;
|
||||||
pcr.io.w.en := wb_reg_ctrl_wen_pcr;
|
pcr.io.w.en := mem_reg_ctrl_wen_pcr && !io.ctrl.killm;
|
||||||
pcr.io.w.data := wb_reg_wdata;
|
pcr.io.w.data := mem_reg_wdata;
|
||||||
|
|
||||||
pcr.io.di := io.ctrl.irq_disable;
|
pcr.io.di := io.ctrl.irq_disable;
|
||||||
pcr.io.ei := io.ctrl.irq_enable;
|
pcr.io.ei := io.ctrl.irq_enable;
|
||||||
pcr.io.eret := wb_reg_ctrl_eret;
|
pcr.io.eret := io.ctrl.mem_eret;
|
||||||
pcr.io.exception := wb_reg_ctrl_exception;
|
pcr.io.exception := io.ctrl.exception;
|
||||||
pcr.io.cause := wb_reg_ctrl_cause;
|
pcr.io.cause := io.ctrl.cause;
|
||||||
pcr.io.pc := wb_reg_pc;
|
pcr.io.pc := mem_reg_pc;
|
||||||
pcr.io.badvaddr := wb_reg_mem_req_addr;
|
pcr.io.badvaddr_wen := io.ctrl.badvaddr_wen;
|
||||||
pcr.io.badvaddr_wen := wb_reg_badvaddr_wen;
|
|
||||||
|
|
||||||
// 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;
|
||||||
io.debug.ex_valid := ex_reg_valid;
|
io.debug.ex_valid := ex_reg_valid;
|
||||||
io.debug.mem_valid := mem_reg_valid;
|
io.debug.mem_valid := mem_reg_valid;
|
||||||
io.debug.wb_valid := wb_reg_valid;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@ class ioDpathPCR extends Bundle()
|
|||||||
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, 'input);
|
||||||
val badvaddr = UFix(VADDR_BITS, '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);
|
||||||
@ -114,7 +113,7 @@ class rocketDpathPCR extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (io.badvaddr_wen) {
|
when (io.badvaddr_wen) {
|
||||||
reg_badvaddr <== io.badvaddr;
|
reg_badvaddr <== io.w.data.toUFix;
|
||||||
}
|
}
|
||||||
|
|
||||||
when (io.exception && !reg_status_et) {
|
when (io.exception && !reg_status_et) {
|
||||||
|
Loading…
Reference in New Issue
Block a user