1
0

interface cleanup, major pipeline changes

This commit is contained in:
Rimas Avizienis 2011-11-01 17:59:27 -07:00
parent ace4c9d13c
commit 08b89e7710
7 changed files with 426 additions and 475 deletions

View File

@ -21,6 +21,7 @@ object Constants
val PC_J = UFix(4, 3); val PC_J = UFix(4, 3);
val PC_JR = UFix(5, 3); val PC_JR = UFix(5, 3);
val PC_PCR = UFix(6, 3); val PC_PCR = UFix(6, 3);
val PC_MEM = UFix(7, 3);
val KF_Y = UFix(1, 1); val KF_Y = UFix(1, 1);
val KF_N = UFix(0, 1); val KF_N = UFix(0, 1);

View File

@ -40,56 +40,63 @@ class rocketProc extends Component
val ctrl = new rocketCtrl(); val ctrl = new rocketCtrl();
val dpath = new rocketDpath(); val dpath = new rocketDpath();
val mem = new rocketMemory(); // val mem = new rocketMemory();
val wb = new rocketWriteback(); // val wb = new rocketWriteback();
dpath.io.host ^^ io.host; ctrl.io.dpath <> dpath.io.ctrl;
dpath.io.debug ^^ io.debug;
// dpath.io.wb <> wb.io;
dpath.io.wb.wen <> wb.io.wb_wen;
dpath.io.wb.waddr <> wb.io.wb_waddr;
dpath.io.wb.wdata <> wb.io.wb_wdata;
dpath.io.imem.req_addr ^^ io.imem.req_addr;
dpath.io.imem.resp_data ^^ io.imem.resp_data;
ctrl.io.ctrl <> dpath.io.ctrl;
ctrl.io.dpath <> dpath.io.dpath;
// ctrl.io.mem <> mem.io;
ctrl.io.mem.mrq_val <> mem.io.mem_mrq_val;
ctrl.io.mem.mrq_cmd <> mem.io.mem_mrq_cmd;
ctrl.io.mem.mrq_type <> mem.io.mem_mrq_type;
ctrl.io.mem.mrq_deq <> mem.io.mem_mrq_deq;
ctrl.io.mem.xsdq_rdy <> mem.io.mem_xsdq_rdy;
ctrl.io.mem.xsdq_val <> mem.io.mem_xsdq_val;
ctrl.io.mem.dc_busy := !io.dmem.req_rdy;
ctrl.io.host.start ^^ io.host.start; ctrl.io.host.start ^^ io.host.start;
ctrl.io.imem ^^ io.imem; ctrl.io.imem ^^ io.imem;
dpath.io.imem.req_addr ^^ io.imem.req_addr;
dpath.io.imem.resp_data ^^ io.imem.resp_data;
dpath.io.host ^^ io.host;
dpath.io.debug ^^ io.debug;
ctrl.io.dmem ^^ io.dmem;
dpath.io.dmem ^^ io.dmem;
// FIXME
// io.console.bits := dpath.io.dpath.rs1(7,0);
io.console.bits := Bits(0,8);
io.console.valid := ctrl.io.console.valid;
ctrl.io.console.rdy := io.console.rdy;
// dpath.io.wb <> wb.io;
// dpath.io.wb.wen <> wb.io.wb_wen;
// dpath.io.wb.waddr <> wb.io.wb_waddr;
// dpath.io.wb.wdata <> wb.io.wb_wdata;
// ctrl.io.mem.mrq_val <> mem.io.mem_mrq_val;
// ctrl.io.mem.mrq_cmd <> mem.io.mem_mrq_cmd;
// ctrl.io.mem.mrq_type <> mem.io.mem_mrq_type;
// ctrl.io.mem.mrq_deq <> mem.io.mem_mrq_deq;
// ctrl.io.mem.xsdq_rdy <> mem.io.mem_xsdq_rdy;
// ctrl.io.mem.xsdq_val <> mem.io.mem_xsdq_val;
// ctrl.io.mem.dc_busy := !io.dmem.req_rdy;
// ctrl.io.console ^^ io.console; // ctrl.io.console ^^ io.console;
ctrl.io.wb.waddr <> wb.io.wb_waddr; // ctrl.io.wb.waddr <> wb.io.wb_waddr;
ctrl.io.wb.wen <> wb.io.wb_wen; // ctrl.io.wb.wen <> wb.io.wb_wen;
// TODO: SHOULD BE THE FOLLOWING BUT NEED BETTER INTERFACE CHUNKS // TODO: SHOULD BE THE FOLLOWING BUT NEED BETTER INTERFACE CHUNKS
// mem.io.dmem >< io.dmem; // mem.io.dmem >< io.dmem;
mem.io.dmem_req_val ^^ io.dmem.req_val; // mem.io.dmem_req_val ^^ io.dmem.req_val;
mem.io.dmem_req_rdy ^^ io.dmem.req_rdy; // mem.io.dmem_req_rdy ^^ io.dmem.req_rdy;
mem.io.dmem_req_op ^^ io.dmem.req_op; // mem.io.dmem_req_op ^^ io.dmem.req_op;
mem.io.dmem_req_addr ^^ io.dmem.req_addr; // mem.io.dmem_req_addr ^^ io.dmem.req_addr;
mem.io.dmem_req_data ^^ io.dmem.req_data; // mem.io.dmem_req_data ^^ io.dmem.req_data;
mem.io.dmem_req_wmask ^^ io.dmem.req_wmask; // mem.io.dmem_req_wmask ^^ io.dmem.req_wmask;
mem.io.dmem_req_tag ^^ io.dmem.req_tag; // mem.io.dmem_req_tag ^^ io.dmem.req_tag;
mem.io.dpath_rs2 <> dpath.io.dpath.rs2; //
mem.io.dpath_waddr <> dpath.io.dpath.waddr; // mem.io.dpath_rs2 <> dpath.io.dpath.rs2;
mem.io.dpath_alu_out <> dpath.io.dpath.alu_out; // mem.io.dpath_waddr <> dpath.io.dpath.waddr;
// mem.io.dpath_alu_out <> dpath.io.dpath.alu_out;
wb.io.dmem_resp_val ^^ io.dmem.resp_val; // wb.io.dmem_resp_val ^^ io.dmem.resp_val;
wb.io.dmem_resp_data ^^ io.dmem.resp_data; // wb.io.dmem_resp_data ^^ io.dmem.resp_data;
wb.io.dmem_resp_tag ^^ io.dmem.resp_tag; // wb.io.dmem_resp_tag ^^ io.dmem.resp_tag;
io.console.bits := dpath.io.dpath.rs1(7,0);
io.console.valid := ctrl.io.console.valid;
ctrl.io.console.rdy := io.console.rdy;
} }
} }

View File

@ -6,14 +6,17 @@ import Node._;
import Constants._ import Constants._
import Instructions._ import Instructions._
class ioCtrl extends Bundle() class ioCtrlDpath extends Bundle()
{ {
// outputs to datapath
val sel_pc = UFix(3, 'output); val sel_pc = UFix(3, 'output);
val wen_btb = Bool('output); val wen_btb = Bool('output);
val stallf = Bool('output); val stallf = Bool('output);
val stalld = Bool('output); val stalld = Bool('output);
val killf = Bool('output); val killf = Bool('output);
val killd = Bool('output); val killd = Bool('output);
val killx = Bool('output);
val killm = Bool('output);
val ren2 = Bool('output); val ren2 = Bool('output);
val ren1 = Bool('output); val ren1 = Bool('output);
val sel_alu2 = UFix(2, 'output); val sel_alu2 = UFix(2, 'output);
@ -26,7 +29,6 @@ class ioCtrl extends Bundle()
val div_val = Bool('output); val div_val = Bool('output);
val div_fn = UFix(4, 'output); val div_fn = UFix(4, 'output);
val div_wb = Bool('output); val div_wb = Bool('output);
val wen = Bool('output);
val sel_wa = Bool('output); val sel_wa = Bool('output);
val sel_wb = UFix(3, 'output); val sel_wb = UFix(3, 'output);
val ren_pcr = Bool('output); val ren_pcr = Bool('output);
@ -36,56 +38,34 @@ class ioCtrl extends Bundle()
val xcpt_fpu = Bool('output); val xcpt_fpu = Bool('output);
val xcpt_syscall = Bool('output); val xcpt_syscall = Bool('output);
val eret = Bool('output); val eret = Bool('output);
} val dcache_miss = Bool('output);
val wen = Bool('output);
class ioCtrlDpath extends Bundle() // inputs from datapath
{
val btb_hit = Bool('input); val btb_hit = Bool('input);
val inst = UFix(32, 'input); val inst = Bits(32, 'input);
val br_eq = Bool('input); val br_eq = Bool('input);
val br_lt = Bool('input); val br_lt = Bool('input);
val br_ltu = Bool('input); val br_ltu = Bool('input);
val div_rdy = Bool('input); val div_rdy = Bool('input);
val div_result_val = Bool('input); val div_result_val = Bool('input);
val mul_result_val = Bool('input); val mul_result_val = Bool('input);
val wen = Bool('input); val ex_waddr = UFix(5,'input); // write addr from execute stage
val waddr = UFix(5, 'input);
val exception = Bool('input); val exception = Bool('input);
val status = Bits(8, 'input); val status = Bits(8, 'input);
} val sboard_set = Bool('input);
val sboard_seta = UFix(5, 'input);
class ioCtrlMem extends Bundle() val sboard_clr0 = Bool('input);
{ val sboard_clr0a = UFix(5, 'input);
val mrq_val = Bool('output); val sboard_clr1 = Bool('input);
val mrq_cmd = UFix(4, 'output); val sboard_clr1a = UFix(5, 'input);
val mrq_type = UFix(3, 'output);
val mrq_deq = Bool('input);
val xsdq_rdy = Bool('input);
val xsdq_val = Bool('output);
val dc_busy = Bool('input);
}
class ioCtrlImem extends Bundle()
{
val req_val = Bool('output);
val req_rdy = Bool('input);
val resp_val = Bool('input);
}
class ioCtrlWB extends Bundle()
{
val waddr = UFix(5, 'input);
val wen = Bool('input);
} }
class ioCtrlAll extends Bundle() class ioCtrlAll extends Bundle()
{ {
val ctrl = new ioCtrl();
val console = new ioConsole(List("rdy", "valid"));
val dpath = new ioCtrlDpath(); val dpath = new ioCtrlDpath();
val imem = new ioCtrlImem(); val console = new ioConsole(List("rdy", "valid"));
val mem = new ioCtrlMem(); val imem = new ioImem(List("req_val", "req_rdy", "resp_val")).flip();
val wb = new ioCtrlWB(); val dmem = new ioDmem(List("req_val", "req_rdy", "req_cmd", "req_type", "resp_val")).flip();
val host = new ioHost(List("start")); val host = new ioHost(List("start"));
} }
@ -219,47 +199,27 @@ class rocketCtrl extends Component
val id_ren2 = id_renx2; val id_ren2 = id_renx2;
val id_ren1 = id_renx1; val id_ren1 = id_renx1;
val id_console_out_val = id_wen_pcr & (id_raddr2 === PCR_CONSOLE); val id_console_out_val = id_wen_pcr & (id_raddr2 === PCR_CONSOLE);
val console_out_fire = id_console_out_val & ~io.dpath.killd;
val id_mem_val_masked = id_mem_val; io.console.valid := console_out_fire.toBool;
val mem_xload_val = id_mem_val_masked & (id_mem_cmd === M_XRD);
val mem_xstore_val = id_mem_val_masked & (id_mem_cmd === M_XWR);
val mem_fire = id_mem_val_masked & ~io.ctrl.killd;
val mem_xload_fire = mem_xload_val & ~io.ctrl.killd;
val mem_xstore_fire = mem_xstore_val & ~io.ctrl.killd;
val console_out_fire = id_console_out_val & ~io.ctrl.killd;
val div_fire = id_div_val & ~io.ctrl.killd;
val mul_fire = id_mul_val & ~io.ctrl.killd;
val sboard_wen = mem_xload_fire | div_fire | mul_fire;
val sboard_waddr = id_waddr;
val sboard = new rocketCtrlSboard(); val sboard = new rocketCtrlSboard();
sboard.io.raddra := id_raddr2; sboard.io.raddra := id_raddr2.toUFix;
sboard.io.raddrb := id_raddr1; sboard.io.raddrb := id_raddr1.toUFix;
sboard.io.raddrc := id_waddr; sboard.io.raddrc := id_waddr.toUFix;
sboard.io.set := sboard_wen.toBool;
sboard.io.seta := sboard_waddr; sboard.io.set := io.dpath.sboard_set;
sboard.io.clr0 := io.wb.wen.toBool; sboard.io.seta := io.dpath.sboard_seta;
sboard.io.clr0a ^^ io.wb.waddr; sboard.io.clr0 := io.dpath.sboard_clr0;
sboard.io.clr1 := io.dpath.wen.toBool; sboard.io.clr0a := io.dpath.sboard_clr0a;
sboard.io.clr1a := io.dpath.waddr; sboard.io.clr1 := io.dpath.sboard_clr1;
sboard.io.clr1a := io.dpath.sboard_clr1a;
val id_stall_raddr2 = sboard.io.stalla; val id_stall_raddr2 = sboard.io.stalla;
val id_stall_raddr1 = sboard.io.stallb; val id_stall_raddr1 = sboard.io.stallb;
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 mrq = new rocketCtrlCnt(3, 4);
mrq.io.enq := mem_fire.toBool;
mrq.io.deq ^^ io.mem.mrq_deq;
val id_empty_mrq = mrq.io.empty;
val id_full_mrq = mrq.io.full;
val id_reg_btb_hit = Reg(width = 1, resetVal = Bool(false)); val id_reg_btb_hit = Reg(width = 1, 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()};
@ -269,15 +229,16 @@ 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));
when (!io.ctrl.stalld) { when (!io.dpath.stalld) {
when (io.ctrl.killf) { when (io.dpath.killf) {
id_reg_btb_hit <== Bool(false); id_reg_btb_hit <== Bool(false);
} }
otherwise{ otherwise{
id_reg_btb_hit <== io.dpath.btb_hit; id_reg_btb_hit <== io.dpath.btb_hit;
} }
} }
when (reset.toBool || io.ctrl.killd) {
when (reset.toBool || io.dpath.killd) {
ex_reg_br_type <== BR_N; ex_reg_br_type <== BR_N;
ex_reg_btb_hit <== Bool(false); ex_reg_btb_hit <== Bool(false);
ex_reg_mem_val <== Bool(false); ex_reg_mem_val <== Bool(false);
@ -289,7 +250,7 @@ class rocketCtrl extends Component
otherwise { otherwise {
ex_reg_br_type <== id_br_type; ex_reg_br_type <== id_br_type;
ex_reg_btb_hit <== id_reg_btb_hit; ex_reg_btb_hit <== id_reg_btb_hit;
ex_reg_mem_val <== id_mem_val_masked.toBool; ex_reg_mem_val <== id_mem_val.toBool;
ex_reg_mem_cmd <== id_mem_cmd; ex_reg_mem_cmd <== id_mem_cmd;
ex_reg_mem_type <== id_mem_type; ex_reg_mem_type <== id_mem_type;
ex_reg_eret <== id_eret.toBool; ex_reg_eret <== id_eret.toBool;
@ -317,22 +278,42 @@ class rocketCtrl extends Component
io.imem.req_val := io.host.start; io.imem.req_val := io.host.start;
// io.imem.req_val := Bool(true); // io.imem.req_val := Bool(true);
io.mem.mrq_val := ex_reg_mem_val; io.dmem.req_val := ex_reg_mem_val && ~io.dpath.killx;
io.mem.mrq_cmd := ex_reg_mem_cmd; io.dmem.req_cmd := ex_reg_mem_cmd;
io.mem.mrq_type := ex_reg_mem_type; io.dmem.req_type := ex_reg_mem_type;
io.mem.xsdq_val := mem_xstore_fire.toBool;
io.console.valid := console_out_fire.toBool;
io.ctrl.sel_pc := val mem_reg_mem_val = Reg(){Bool()};
val mem_reg_mem_cmd = Reg(){UFix(width = 4)};
val mem_reg_mem_type = Reg(){UFix(width = 3)};
when (reset.toBool || io.dpath.killx) {
mem_reg_mem_val <== Bool(false);
mem_reg_mem_cmd <== UFix(0, 4);
mem_reg_mem_type <== UFix(0, 3);
}
otherwise {
mem_reg_mem_val <== ex_reg_mem_val;
mem_reg_mem_cmd <== ex_reg_mem_cmd;
mem_reg_mem_type <== ex_reg_mem_type;
}
// replay on a D$ load miss : FIXME - add a miss signal to D$
val replay_mem = mem_reg_mem_val && (mem_reg_mem_cmd === M_XRD) && !io.dmem.resp_val;
val dcache_miss = Reg(replay_mem);
io.dpath.dcache_miss := dcache_miss;
io.dpath.sel_pc :=
Mux(replay_mem, PC_MEM,
Mux(io.dpath.exception || ex_reg_eret, PC_PCR, Mux(io.dpath.exception || ex_reg_eret, PC_PCR,
Mux(!ex_reg_btb_hit && br_taken, PC_BR, Mux(!ex_reg_btb_hit && br_taken, PC_BR,
Mux(ex_reg_btb_hit && !br_taken || ex_reg_privileged, PC_EX4, Mux(ex_reg_btb_hit && !br_taken || ex_reg_privileged, PC_EX4,
Mux(jr_taken, PC_JR, Mux(jr_taken, PC_JR,
Mux(j_taken, PC_J, Mux(j_taken, PC_J,
Mux(io.dpath.btb_hit, PC_BTB, Mux(io.dpath.btb_hit, PC_BTB,
PC_4)))))); PC_4)))))));
io.ctrl.wen_btb := ~ex_reg_btb_hit & br_taken; io.dpath.wen_btb := ~ex_reg_btb_hit & br_taken;
val take_pc = val take_pc =
~ex_reg_btb_hit & br_taken | ~ex_reg_btb_hit & br_taken |
@ -341,65 +322,86 @@ class rocketCtrl extends Component
j_taken | j_taken |
io.dpath.exception | io.dpath.exception |
ex_reg_privileged | ex_reg_privileged |
ex_reg_eret; ex_reg_eret |
replay_mem;
io.ctrl.stallf := io.dpath.stallf :=
~take_pc & ~take_pc &
( (
~io.imem.req_rdy | ~io.imem.req_rdy |
~io.imem.resp_val | ~io.imem.resp_val |
io.ctrl.stalld io.dpath.stalld
); );
val ctrl_stalld_wo_fpu_rdy = // check for loads in execute stage to detect load/use hazards
val lu_stall_raddr1 =
ex_reg_mem_val &&
(ex_reg_mem_cmd === M_XRD) &&
id_ren1.toBool &&
(id_raddr1 === io.dpath.ex_waddr);
val lu_stall_raddr2 =
ex_reg_mem_val &&
(ex_reg_mem_cmd === M_XRD) &&
id_ren2.toBool &&
(id_raddr2 === io.dpath.ex_waddr);
val ctrl_stalld =
~take_pc & ~take_pc &
( (
id_ren2 & id_stall_raddr2 | lu_stall_raddr1 |
id_ren1 & id_stall_raddr1 | lu_stall_raddr2 |
(id_sel_wa === WA_RD) & id_stall_waddr | id_ren2 & id_stall_raddr2 |
id_ren1 & id_stall_raddr1 |
(id_sel_wa === WA_RD) && id_stall_waddr |
(id_sel_wa === WA_RA) & id_stall_ra | (id_sel_wa === WA_RA) & id_stall_ra |
id_mem_val_masked & id_full_mrq | id_mem_val & ~io.dmem.req_rdy |
id_sync & (~id_empty_mrq | io.mem.dc_busy) | id_sync & ~io.dmem.req_rdy |
mem_xstore_val & ~io.mem.xsdq_rdy | // id_mem_val_masked & id_full_mrq |
// id_sync & (~id_empty_mrq | io.mem.dc_busy) |
// mem_xstore_val & ~io.mem.xsdq_rdy |
id_console_out_val & ~io.console.rdy | id_console_out_val & ~io.console.rdy |
id_div_val & ~io.dpath.div_rdy | id_div_val & ~io.dpath.div_rdy |
io.dpath.div_result_val | io.dpath.div_result_val |
io.dpath.mul_result_val io.dpath.mul_result_val
); );
val ctrl_killd = take_pc | ctrl_stalld;
// for divider, multiplier writeback // for divider, multiplier writeback
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.ctrl.stalld := ctrl_stalld_wo_fpu_rdy.toBool; io.dpath.stalld := ctrl_stalld.toBool;
io.ctrl.killf := take_pc | ~io.imem.resp_val; io.dpath.killf := take_pc | ~io.imem.resp_val;
val ctrl_killd_wo_fpu_rdy = take_pc | ctrl_stalld_wo_fpu_rdy; io.dpath.killd := ctrl_killd.toBool;
io.ctrl.killd := ctrl_killd_wo_fpu_rdy.toBool; io.dpath.killx := replay_mem.toBool;
io.dpath.killm := replay_mem.toBool;
io.ctrl.ren2 := id_ren2.toBool; io.dpath.ren2 := id_ren2.toBool;
io.ctrl.ren1 := id_ren1.toBool; io.dpath.ren1 := id_ren1.toBool;
io.ctrl.sel_alu2 := id_sel_alu2; io.dpath.sel_alu2 := id_sel_alu2;
io.ctrl.sel_alu1 := id_sel_alu1.toBool; io.dpath.sel_alu1 := id_sel_alu1.toBool;
io.ctrl.fn_dw := id_fn_dw.toBool; io.dpath.fn_dw := id_fn_dw.toBool;
io.ctrl.fn_alu := id_fn_alu; io.dpath.fn_alu := id_fn_alu;
io.ctrl.div_fn := id_div_fn; io.dpath.div_fn := id_div_fn;
io.ctrl.div_val := id_div_val.toBool; io.dpath.div_val := id_div_val.toBool;
io.ctrl.div_wb := div_wb; io.dpath.div_wb := div_wb;
io.ctrl.mul_fn := id_mul_fn; io.dpath.mul_fn := id_mul_fn;
io.ctrl.mul_val := id_mul_val.toBool; io.dpath.mul_val := id_mul_val.toBool;
io.ctrl.mul_wb := mul_wb; io.dpath.mul_wb := mul_wb;
io.ctrl.wen := id_wen.toBool; io.dpath.wen := id_wen.toBool;
io.ctrl.sel_wa := id_sel_wa.toBool; io.dpath.sel_wa := id_sel_wa.toBool;
io.ctrl.sel_wb := id_sel_wb; io.dpath.sel_wb := id_sel_wb;
io.ctrl.ren_pcr := id_ren_pcr.toBool; io.dpath.ren_pcr := id_ren_pcr.toBool;
io.ctrl.wen_pcr := id_wen_pcr.toBool; io.dpath.wen_pcr := id_wen_pcr.toBool;
io.ctrl.eret := id_eret.toBool; io.dpath.eret := id_eret.toBool;
io.ctrl.xcpt_illegal := ~id_int_val.toBool; io.dpath.xcpt_illegal := ~id_int_val.toBool;
io.ctrl.xcpt_privileged := (id_privileged & ~io.dpath.status(5)).toBool; io.dpath.xcpt_privileged := (id_privileged & ~io.dpath.status(5)).toBool;
io.ctrl.xcpt_fpu := Bool(false); io.dpath.xcpt_fpu := Bool(false);
io.ctrl.xcpt_syscall := id_syscall.toBool; io.dpath.xcpt_syscall := id_syscall.toBool;
} }
} }

View File

@ -9,10 +9,10 @@ import scala.math._;
class ioDmem(view: List[String] = null) extends Bundle(view) { class ioDmem(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_op = Bits(4, 'input); val req_cmd = Bits(4, 'input);
val req_type = Bits(3, 'input);
val req_addr = UFix(32, 'input); val req_addr = UFix(32, 'input);
val req_data = Bits(64, 'input); val req_data = Bits(64, 'input);
val req_wmask = Bits(8, 'input);
val req_tag = Bits(12, 'input); val req_tag = Bits(12, 'input);
val resp_val = Bool('output); val resp_val = Bool('output);
val resp_data = Bits(64, 'output); val resp_data = Bits(64, 'output);
@ -58,7 +58,7 @@ class rocketDCacheDM_flush(lines: Int, addrbits: Int) extends Component {
val flush_waiting = Reg(resetVal = Bool(false)); val flush_waiting = Reg(resetVal = Bool(false));
val r_cpu_req_tag = Reg(resetVal = Bits(0, 12)); val r_cpu_req_tag = Reg(resetVal = Bits(0, 12));
when (io.cpu.req_val && io.cpu.req_rdy && (io.cpu.req_op === M_FLA)) when (io.cpu.req_val && io.cpu.req_rdy && (io.cpu.req_cmd === M_FLA))
{ {
r_cpu_req_tag <== io.cpu.req_tag; r_cpu_req_tag <== io.cpu.req_tag;
flushing <== Bool(true); flushing <== Bool(true);
@ -75,12 +75,12 @@ class rocketDCacheDM_flush(lines: Int, addrbits: Int) extends Component {
when (flush_waiting && dcache.io.cpu.resp_val && (dcache.io.cpu.resp_tag === r_cpu_req_tag)) when (flush_waiting && dcache.io.cpu.resp_val && (dcache.io.cpu.resp_tag === r_cpu_req_tag))
{ flush_resp_count <== flush_resp_count + UFix(1,1); } { flush_resp_count <== flush_resp_count + UFix(1,1); }
dcache.io.cpu.req_val := (io.cpu.req_val && (io.cpu.req_op != M_FLA) && !flush_waiting) || flushing; dcache.io.cpu.req_val := (io.cpu.req_val && (io.cpu.req_cmd != M_FLA) && !flush_waiting) || flushing;
dcache.io.cpu.req_op := Mux(flushing, M_FLA, io.cpu.req_op); dcache.io.cpu.req_cmd := Mux(flushing, M_FLA, io.cpu.req_cmd);
dcache.io.cpu.req_addr := Mux(flushing, Cat(Bits(0,tagmsb-taglsb+1), flush_count, Bits(0,offsetbits)).toUFix, io.cpu.req_addr); dcache.io.cpu.req_addr := Mux(flushing, Cat(Bits(0,tagmsb-taglsb+1), flush_count, Bits(0,offsetbits)).toUFix, io.cpu.req_addr);
dcache.io.cpu.req_tag := Mux(flushing, r_cpu_req_tag, io.cpu.req_tag); dcache.io.cpu.req_tag := Mux(flushing, r_cpu_req_tag, io.cpu.req_tag);
dcache.io.cpu.req_type := io.cpu.req_type;
dcache.io.cpu.req_data ^^ io.cpu.req_data; dcache.io.cpu.req_data ^^ io.cpu.req_data;
dcache.io.cpu.req_wmask ^^ io.cpu.req_wmask;
dcache.io.mem ^^ io.mem; dcache.io.mem ^^ io.mem;
io.cpu.req_rdy := dcache.io.cpu.req_rdy && !flush_waiting; io.cpu.req_rdy := dcache.io.cpu.req_rdy && !flush_waiting;
@ -96,7 +96,7 @@ class rocketDCacheDM_flush(lines: Int, addrbits: Int) extends Component {
// lines = # of cache lines // lines = # of cache lines
// addr_bits = address width (word addressable) bits // addr_bits = address width (word addressable) bits
// 64 bit wide cpu port, 128 bit wide memory port, 64 byte cachelines // 64 bit wide cpu port, 128 bit wide memory port, 64 byte cachelines
/*
class rocketDCacheDM(lines: Int, addrbits: Int) extends Component { class rocketDCacheDM(lines: Int, addrbits: Int) extends Component {
val io = new ioDCacheDM(); val io = new ioDCacheDM();
@ -116,7 +116,7 @@ class rocketDCacheDM(lines: Int, addrbits: Int) extends Component {
val r_r_cpu_req_addr = Reg(r_cpu_req_addr); val r_r_cpu_req_addr = Reg(r_cpu_req_addr);
val r_cpu_req_val = Reg(Bool(false)); val r_cpu_req_val = Reg(Bool(false));
val r_cpu_req_data = Reg(Bits(0,64)); val r_cpu_req_data = Reg(Bits(0,64));
val r_cpu_req_op = Reg(Bits(0,4)); val r_cpu_req_cmd = Reg(Bits(0,4));
val r_cpu_req_wmask = Reg(Bits(0,8)); val r_cpu_req_wmask = Reg(Bits(0,8));
val r_cpu_req_tag = Reg(Bits(0,12)); val r_cpu_req_tag = Reg(Bits(0,12));
val r_cpu_resp_tag = Reg(r_cpu_req_tag); val r_cpu_resp_tag = Reg(r_cpu_req_tag);
@ -125,13 +125,13 @@ class rocketDCacheDM(lines: Int, addrbits: Int) extends Component {
when (io.cpu.req_val && io.cpu.req_rdy) { when (io.cpu.req_val && io.cpu.req_rdy) {
r_cpu_req_addr <== io.cpu.req_addr; r_cpu_req_addr <== io.cpu.req_addr;
r_cpu_req_data <== io.cpu.req_data; r_cpu_req_data <== io.cpu.req_data;
r_cpu_req_op <== io.cpu.req_op; r_cpu_req_cmd <== io.cpu.req_cmd;
r_cpu_req_wmask <== io.cpu.req_wmask; r_cpu_req_wmask <== io.cpu.req_wmask;
r_cpu_req_tag <== io.cpu.req_tag; } r_cpu_req_tag <== io.cpu.req_tag; }
val req_load = (r_cpu_req_op === M_XRD); val req_load = (r_cpu_req_cmd === M_XRD);
val req_store = (r_cpu_req_op === M_XWR); val req_store = (r_cpu_req_cmd === M_XWR);
val req_flush = (r_cpu_req_op === M_FLA); val req_flush = (r_cpu_req_cmd === M_FLA);
when (io.cpu.req_rdy) { r_cpu_req_val <== io.cpu.req_val; } when (io.cpu.req_rdy) { r_cpu_req_val <== io.cpu.req_val; }
otherwise { r_cpu_req_val <== Bool(false); } otherwise { r_cpu_req_val <== Bool(false); }
@ -248,6 +248,7 @@ class rocketDCacheDM(lines: Int, addrbits: Int) extends Component {
} }
} }
} }
*/
class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component { class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component {
val io = new ioDCacheDM(); val io = new ioDCacheDM();
@ -267,24 +268,26 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component {
val r_cpu_req_addr = Reg(resetVal = Bits(0, addrbits)); val r_cpu_req_addr = Reg(resetVal = Bits(0, addrbits));
val r_cpu_req_val = Reg(resetVal = Bool(false)); val r_cpu_req_val = Reg(resetVal = Bool(false));
val r_cpu_req_data = Reg(resetVal = Bits(0,64)); val r_cpu_req_data = Reg(resetVal = Bits(0,64));
val r_cpu_req_op = Reg(resetVal = Bits(0,4)); val r_cpu_req_cmd = Reg(resetVal = Bits(0,4));
val r_cpu_req_wmask = Reg(resetVal = Bits(0,8)); val r_cpu_req_type = Reg(resetVal = Bits(0,3));
val r_cpu_req_tag = Reg(resetVal = Bits(0,12)); // val r_cpu_req_wmask = Reg(resetVal = Bits(0,8));
val r_cpu_req_tag = Reg(resetVal = Bits(0,5));
val p_store_data = Reg(resetVal = Bits(0,64)); val p_store_data = Reg(resetVal = Bits(0,64));
val p_store_addr = Reg(resetVal = Bits(0,64)); val p_store_addr = Reg(resetVal = Bits(0,64));
val p_store_wmask = Reg(resetVal = Bits(0,64)); val p_store_wmask = Reg(resetVal = Bits(0,64));
val p_store_valid = Reg(resetVal = Bool(false)); val p_store_valid = Reg(resetVal = Bool(false));
val req_load = (r_cpu_req_op === M_XRD); val req_load = (r_cpu_req_cmd === M_XRD);
val req_store = (r_cpu_req_op === M_XWR); val req_store = (r_cpu_req_cmd === M_XWR);
val req_flush = (r_cpu_req_op === M_FLA); val req_flush = (r_cpu_req_cmd === M_FLA);
when (io.cpu.req_val && io.cpu.req_rdy) { when (io.cpu.req_val && io.cpu.req_rdy) {
r_cpu_req_addr <== io.cpu.req_addr; r_cpu_req_addr <== io.cpu.req_addr;
r_cpu_req_data <== io.cpu.req_data; r_cpu_req_data <== io.cpu.req_data;
r_cpu_req_op <== io.cpu.req_op; r_cpu_req_cmd <== io.cpu.req_cmd;
r_cpu_req_wmask <== io.cpu.req_wmask; r_cpu_req_type <== io.cpu.req_type;
// r_cpu_req_wmask <== io.cpu.req_wmask;
r_cpu_req_tag <== io.cpu.req_tag; r_cpu_req_tag <== io.cpu.req_tag;
} }
@ -325,10 +328,51 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component {
val tag_valid = vb_rdata.toBool; val tag_valid = vb_rdata.toBool;
val tag_match = tag_valid && (tag_rdata === r_cpu_req_addr(tagmsb, taglsb)); val tag_match = tag_valid && (tag_rdata === r_cpu_req_addr(tagmsb, taglsb));
// generate write mask and store data signals based on store type and address LSBs
val wmask_b =
Mux(r_cpu_req_addr(2,0) === UFix(0, 3), Bits("b0000_0001", 8),
Mux(r_cpu_req_addr(2,0) === UFix(1, 3), Bits("b0000_0010", 8),
Mux(r_cpu_req_addr(2,0) === UFix(2, 3), Bits("b0000_0100", 8),
Mux(r_cpu_req_addr(2,0) === UFix(3, 3), Bits("b0000_1000", 8),
Mux(r_cpu_req_addr(2,0) === UFix(4, 3), Bits("b0001_0000", 8),
Mux(r_cpu_req_addr(2,0) === UFix(5, 3), Bits("b0010_0000", 8),
Mux(r_cpu_req_addr(2,0) === UFix(6, 3), Bits("b0100_0000", 8),
Mux(r_cpu_req_addr(2,0) === UFix(7, 3), Bits("b1000_0000", 8),
UFix(0, 8)))))))));
val wmask_h =
Mux(r_cpu_req_addr(2,1) === UFix(0, 2), Bits("b0000_0011", 8),
Mux(r_cpu_req_addr(2,1) === UFix(1, 2), Bits("b0000_1100", 8),
Mux(r_cpu_req_addr(2,1) === UFix(2, 2), Bits("b0011_0000", 8),
Mux(r_cpu_req_addr(2,1) === UFix(3, 2), Bits("b1100_0000", 8),
UFix(0, 8)))));
val wmask_w =
Mux(r_cpu_req_addr(2) === UFix(0, 1), Bits("b0000_1111", 8),
Mux(r_cpu_req_addr(2) === UFix(1, 1), Bits("b1111_0000", 8),
UFix(0, 8)));
val wmask_d =
Bits("b1111_1111", 8);
val store_wmask =
Mux(r_cpu_req_type === MT_B, wmask_b,
Mux(r_cpu_req_type === MT_H, wmask_h,
Mux(r_cpu_req_type === MT_W, wmask_w,
Mux(r_cpu_req_type === MT_D, wmask_d,
UFix(0, 8)))));
val store_data =
Mux(r_cpu_req_type === MT_B, Fill(8, r_cpu_req_data( 7,0)),
Mux(r_cpu_req_type === MT_H, Fill(4, r_cpu_req_data(15,0)),
Mux(r_cpu_req_type === MT_W, Fill(2, r_cpu_req_data(31,0)),
Mux(r_cpu_req_type === MT_D, r_cpu_req_data,
UFix(0, 64)))));
when ((state === s_ready) && r_cpu_req_val && req_store) { when ((state === s_ready) && r_cpu_req_val && req_store) {
p_store_data <== r_cpu_req_data; p_store_data <== store_data;
p_store_addr <== r_cpu_req_addr; p_store_addr <== r_cpu_req_addr;
p_store_wmask <== r_cpu_req_wmask; p_store_wmask <== store_wmask;
p_store_valid <== Bool(true); p_store_valid <== Bool(true);
} }
@ -370,14 +414,14 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component {
Fill(8, p_store_wmask(1)), Fill(8, p_store_wmask(1)),
Fill(8, p_store_wmask(0))); Fill(8, p_store_wmask(0)));
val store_wmask = val da_store_wmask =
Mux(p_store_addr(offsetlsb).toBool, Mux(p_store_addr(offsetlsb).toBool,
Cat(p_wmask_expand, Bits(0,64)), Cat(p_wmask_expand, Bits(0,64)),
Cat(Bits(0,64), p_wmask_expand)); Cat(Bits(0,64), p_wmask_expand));
val data_array_wmask = val data_array_wmask =
Mux((state === s_refill), ~Bits(0,128), Mux((state === s_refill), ~Bits(0,128),
store_wmask); da_store_wmask);
val data_array = Mem(lines*4, data_array_we, data_array_waddr, data_array_wdata, wrMask = data_array_wmask, resetVal = null); val data_array = Mem(lines*4, data_array_we, data_array_waddr, data_array_wdata, wrMask = data_array_wmask, resetVal = null);
val data_array_raddr = val data_array_raddr =
Mux((state === s_writeback) && io.mem.req_rdy, Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count_next).toUFix, Mux((state === s_writeback) && io.mem.req_rdy, Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count_next).toUFix,
@ -394,7 +438,7 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component {
io.cpu.resp_val := ((state === s_ready) && r_cpu_req_val && tag_match && req_load && !(p_store_valid && addr_match)) || io.cpu.resp_val := ((state === s_ready) && r_cpu_req_val && tag_match && req_load && !(p_store_valid && addr_match)) ||
((state === s_resolve_miss) && req_flush); ((state === s_resolve_miss) && req_flush);
io.cpu.resp_tag := r_cpu_req_tag; io.cpu.resp_tag := Cat(Bits(0,1), r_cpu_req_type, r_cpu_req_addr(2,0), r_cpu_req_tag);
io.cpu.resp_data := io.cpu.resp_data :=
Mux(r_cpu_req_addr(offsetlsb).toBool, data_array_rdata(127, 64), Mux(r_cpu_req_addr(offsetlsb).toBool, data_array_rdata(127, 64),

View File

@ -5,46 +5,13 @@ import Node._;
import Constants._ import Constants._
import Instructions._ import Instructions._
class ioDpath extends Bundle()
{
val btb_hit = Bool('output);
val inst = Bits(32, 'output);
val rs2 = Bits(64, 'output);
val rs1 = Bits(64, 'output);
val br_eq = Bool('output);
val br_lt = Bool('output);
val br_ltu = Bool('output);
val div_result_val = Bool('output);
val div_rdy = Bool('output);
val mul_result_val = Bool('output);
val wen = Bool('output);
val waddr = UFix(5, 'output);
val alu_out = UFix(64, 'output);
val exception = Bool('output);
val status = Bits(8, 'output);
}
class ioDpathImem extends Bundle()
{
val req_addr = UFix(32, 'output);
val resp_data = Bits(32, 'input);
}
class ioDpathWB extends Bundle()
{
val waddr = UFix(5, 'input);
val wen = Bool('input);
val wdata = Bits(64, 'input);
}
class ioDpathAll extends Bundle() class ioDpathAll extends Bundle()
{ {
val dpath = new ioDpath();
val host = new ioHost(); val host = new ioHost();
val ctrl = new ioCtrl().flip(); val ctrl = new ioCtrlDpath().flip();
val debug = new ioDebug(); val debug = new ioDebug();
val wb = new ioDpathWB(); val dmem = new ioDmem(List("req_addr", "req_data", "req_tag", "resp_val", "resp_tag", "resp_data")).flip();
val imem = new ioDpathImem(); val imem = new ioImem(List("req_addr", "resp_data")).flip();
} }
class rocketDpath extends Component class rocketDpath extends Component
@ -77,36 +44,59 @@ class rocketDpath extends Component
val if_reg_pc = Reg(width = 32, resetVal = UFix(0, 32)); val if_reg_pc = Reg(width = 32, resetVal = UFix(0, 32));
// instruction decode definitions // instruction decode definitions
val id_reg_pc = Reg(){UFix(width = 32)}; val id_reg_pc = Reg(resetVal = UFix(0,32));
val id_reg_pc_plus4 = Reg(){UFix(width = 32)}; val id_reg_pc_plus4 = Reg(resetVal = UFix(0,32));
val id_reg_inst = Reg(width = 32, resetVal = NOP); val id_reg_inst = Reg(resetVal = NOP);
// execute definitions // execute definitions
val ex_reg_pc = Reg(width = 32, resetVal = UFix(0, 32)); val ex_reg_pc = Reg(resetVal = UFix(0,32));
val ex_reg_pc_plus4 = Reg(width = 32, resetVal = UFix(0, 32)); val ex_reg_pc_plus4 = Reg(resetVal = UFix(0,32));
val ex_reg_inst = Reg(width = 32, resetVal = Bits(0, 32)); val ex_reg_inst = Reg(resetVal = Bits(0,32));
val ex_reg_raddr2 = Reg(width = 5, resetVal = UFix(0, 5)); val ex_reg_raddr2 = Reg(resetVal = UFix(0,5));
val ex_reg_raddr1 = Reg(width = 5, resetVal = UFix(0, 5)); val ex_reg_raddr1 = Reg(resetVal = UFix(0,5));
val ex_reg_rs2 = Reg(width = 64, resetVal = Bits(0, 64)); val ex_reg_rs2 = Reg(resetVal = Bits(0,64));
val ex_reg_rs1 = Reg(width = 64, resetVal = Bits(0, 64)); val ex_reg_rs1 = Reg(resetVal = Bits(0,64));
val ex_reg_waddr = Reg(width = 5, resetVal = UFix(0, 5)); val ex_reg_waddr = Reg(resetVal = UFix(0,5));
val ex_reg_ctrl_sel_alu2 = Reg(width = 2, resetVal = A2_X); val ex_reg_ctrl_sel_alu2 = Reg(resetVal = A2_X);
val ex_reg_ctrl_sel_alu1 = Reg(width = 1, resetVal = A1_X); val ex_reg_ctrl_sel_alu1 = Reg(resetVal = A1_X);
val ex_reg_ctrl_fn_dw = Reg(width = 1, resetVal = DW_X); val ex_reg_ctrl_fn_dw = Reg(resetVal = DW_X);
val ex_reg_ctrl_fn_alu = Reg(width = 4, resetVal = FN_X); val ex_reg_ctrl_fn_alu = Reg(resetVal = FN_X);
val ex_reg_ctrl_ll_wb = Reg(width = 1, resetVal = Bool(false)); val ex_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
val ex_reg_ctrl_mul_val = Reg(width = 1, resetVal = Bool(false)); val ex_reg_ctrl_mul_val = Reg(resetVal = Bool(false));
val ex_reg_ctrl_mul_fn = Reg(width = 3, resetVal = MUL_X); val ex_reg_ctrl_mul_fn = Reg(resetVal = MUL_X);
val ex_reg_ctrl_div_val = Reg(width = 1, resetVal = Bool(false)); val ex_reg_ctrl_div_val = Reg(resetVal = Bool(false));
val ex_reg_ctrl_div_fn = Reg(width = 4, resetVal = DIV_X); val ex_reg_ctrl_div_fn = Reg(resetVal = DIV_X);
val ex_reg_ctrl_sel_wb = Reg(width = 3, resetVal = WB_X); val ex_reg_ctrl_sel_wb = Reg(resetVal = WB_X);
val ex_reg_ctrl_wen = Reg(width = 1, resetVal = Bool(false)); val ex_reg_ctrl_wen = Reg(resetVal = Bool(false));
val ex_reg_ctrl_ren_pcr = Reg(width = 1, resetVal = Bool(false)); val ex_reg_ctrl_ren_pcr = Reg(resetVal = Bool(false));
val ex_reg_ctrl_wen_pcr = Reg(width = 1, resetVal = Bool(false)); val ex_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
val ex_reg_ctrl_eret = Reg(width = 1, resetVal = Bool(false)); val ex_reg_ctrl_eret = Reg(resetVal = Bool(false));
val ex_reg_ctrl_exception = Reg(width = 1, resetVal = Bool(false)); val ex_reg_ctrl_exception = Reg(resetVal = Bool(false));
val ex_reg_ctrl_cause = Reg(width = 5, resetVal = UFix(0,5)); val ex_reg_ctrl_cause = Reg(resetVal = UFix(0,5));
val ex_wdata = Wire() { Bits() }; val ex_wdata = Wire() { Bits() };
val mem_reg_pc = Reg(resetVal = UFix(0,32));
val mem_reg_pc_plus4 = Reg(resetVal = UFix(0,32));
val mem_reg_waddr = Reg(resetVal = UFix(0,5));
val mem_reg_wdata = Reg(resetVal = Bits(0,64));
val mem_reg_raddr2 = Reg(resetVal = UFix(0,5));
val mem_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
val mem_reg_ctrl_div_val = Reg(resetVal = Bool(false));
val mem_reg_ctrl_mul_val = 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_exception = Reg(resetVal = Bool(false));
val wb_reg_pc = Reg(resetVal = UFix(0,32));
val wb_reg_pc_plus4 = Reg(resetVal = UFix(0,32));
val wb_reg_waddr = Reg(resetVal = UFix(0,5));
val wb_reg_wdata = Reg(resetVal = Bits(0,64));
val wb_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
val wb_reg_raddr2 = Reg(resetVal = UFix(0,5));
val wb_reg_ctrl_div_val = Reg(resetVal = Bool(false));
val wb_reg_ctrl_mul_val = Reg(resetVal = Bool(false));
val wb_reg_ctrl_wen = Reg(resetVal = Bool(false));
val wb_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
// instruction fetch stage // instruction fetch stage
val if_pc_plus4 = if_reg_pc + UFix(4, 32); val if_pc_plus4 = if_reg_pc + UFix(4, 32);
@ -132,7 +122,8 @@ class rocketDpath extends Component
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, ex_pcr(31,0).toUFix, Mux(io.ctrl.sel_pc === PC_PCR, ex_pcr(31,0).toUFix,
UFix(0, 32)))))))); Mux(io.ctrl.sel_pc === PC_MEM, mem_reg_pc,
UFix(0, 32)))))))));
when (!io.host.start){ when (!io.host.start){
if_reg_pc <== UFix(0, 32); //32'hFFFF_FFFC; if_reg_pc <== UFix(0, 32); //32'hFFFF_FFFC;
@ -146,7 +137,7 @@ class rocketDpath extends Component
if_next_pc); if_next_pc);
btb.io.current_pc4 := if_pc_plus4; btb.io.current_pc4 := if_pc_plus4;
btb.io.hit ^^ io.dpath.btb_hit; btb.io.hit ^^ io.ctrl.btb_hit;
btb.io.wen ^^ io.ctrl.wen_btb; btb.io.wen ^^ io.ctrl.wen_btb;
btb.io.correct_pc4 := ex_reg_pc_plus4; btb.io.correct_pc4 := ex_reg_pc_plus4;
@ -174,6 +165,7 @@ class rocketDpath extends Component
rfile.io.r1.addr := id_raddr1; rfile.io.r1.addr := id_raddr1;
val id_rdata1 = rfile.io.r1.data; val id_rdata1 = rfile.io.r1.data;
// destination register selection
val id_waddr = val id_waddr =
Mux(io.ctrl.div_wb, div_result_tag, Mux(io.ctrl.div_wb, div_result_tag,
Mux(io.ctrl.mul_wb, mul_result_tag, Mux(io.ctrl.mul_wb, mul_result_tag,
@ -181,16 +173,22 @@ class rocketDpath extends Component
Mux(io.ctrl.sel_wa === WA_RA, RA, Mux(io.ctrl.sel_wa === WA_RA, RA,
UFix(0, 5))))); UFix(0, 5)))));
// bypass muxes
val id_rs1 = val id_rs1 =
Mux(io.ctrl.div_wb, div_result, Mux(io.ctrl.div_wb, div_result,
Mux(io.ctrl.mul_wb, mul_result, Mux(io.ctrl.mul_wb, mul_result,
Mux(id_raddr1 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr1 === ex_reg_waddr, ex_wdata, Mux(id_raddr1 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr1 === ex_reg_waddr, ex_wdata,
id_rdata1))); Mux(id_raddr1 != UFix(0, 5) && mem_reg_ctrl_wen && id_raddr1 === mem_reg_waddr, mem_reg_wdata,
Mux(id_raddr1 != UFix(0, 5) && wb_reg_ctrl_wen && id_raddr1 === wb_reg_waddr, wb_reg_wdata,
id_rdata1)))));
val id_rs2 = val id_rs2 =
Mux(id_raddr2 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr2 === ex_reg_waddr, ex_wdata, Mux(id_raddr2 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr2 === ex_reg_waddr, ex_wdata,
id_rdata2); Mux(id_raddr2 != UFix(0, 5) && mem_reg_ctrl_wen && id_raddr2 === mem_reg_waddr, mem_reg_wdata,
Mux(id_raddr2 != UFix(0, 5) && wb_reg_ctrl_wen && id_raddr2 === wb_reg_waddr, wb_reg_wdata,
id_rdata2)));
// write value to cause register based on exception type
val id_exception = io.ctrl.xcpt_illegal || io.ctrl.xcpt_privileged || io.ctrl.xcpt_fpu || io.ctrl.xcpt_syscall; val id_exception = io.ctrl.xcpt_illegal || io.ctrl.xcpt_privileged || io.ctrl.xcpt_fpu || io.ctrl.xcpt_syscall;
val id_cause = val id_cause =
Mux(io.ctrl.xcpt_illegal, UFix(2,5), Mux(io.ctrl.xcpt_illegal, UFix(2,5),
@ -199,9 +197,9 @@ class rocketDpath extends Component
Mux(io.ctrl.xcpt_syscall, UFix(6,5), Mux(io.ctrl.xcpt_syscall, UFix(6,5),
UFix(0,5))))); UFix(0,5)))));
io.dpath.inst := id_reg_inst; io.ctrl.inst := id_reg_inst;
io.dpath.rs1 := id_rs1; // io.ctrl.rs1 := id_rs1;
io.dpath.rs2 := id_rs2; // io.ctrl.rs2 := id_rs2;
// execute stage // execute stage
ex_reg_pc <== id_reg_pc; ex_reg_pc <== id_reg_pc;
@ -269,8 +267,8 @@ class rocketDpath extends Component
div.io.dpath_rs2 := ex_reg_rs2; div.io.dpath_rs2 := ex_reg_rs2;
div.io.div_result_rdy := io.ctrl.div_wb; div.io.div_result_rdy := io.ctrl.div_wb;
io.dpath.div_rdy := div.io.div_rdy; io.ctrl.div_rdy := div.io.div_rdy;
io.dpath.div_result_val := div.io.div_result_val; io.ctrl.div_result_val := div.io.div_result_val;
// multiplier // multiplier
mul.io.mul_val := ex_reg_ctrl_mul_val; mul.io.mul_val := ex_reg_ctrl_mul_val;
@ -279,66 +277,145 @@ class rocketDpath extends Component
mul.io.in0 := ex_reg_rs1; mul.io.in0 := ex_reg_rs1;
mul.io.in1 := ex_reg_rs2; mul.io.in1 := ex_reg_rs2;
io.dpath.mul_result_val := mul.io.result_val; io.ctrl.mul_result_val := mul.io.result_val;
// processor control register i/o io.ctrl.ex_waddr := ex_reg_waddr; // for load/use hazard detection
pcr.io.host.from_wen ^^ io.host.from_wen;
pcr.io.host.from ^^ io.host.from;
pcr.io.host.to ^^ io.host.to;
// D$ request interface (registered inside D$ module)
// other signals (req_val, req_rdy) connect to control module
io.dmem.req_addr := ex_alu_out;
io.dmem.req_data := ex_reg_rs2;
io.dmem.req_tag := ex_reg_waddr;
// processor control regfile read
pcr.io.r.en := ex_reg_ctrl_ren_pcr | ex_reg_ctrl_exception | ex_reg_ctrl_eret; pcr.io.r.en := ex_reg_ctrl_ren_pcr | ex_reg_ctrl_exception | ex_reg_ctrl_eret;
pcr.io.r.addr := pcr.io.r.addr :=
Mux(ex_reg_ctrl_exception, PCR_EVEC, Mux(ex_reg_ctrl_exception, PCR_EVEC,
Mux(ex_reg_ctrl_eret, PCR_EPC, Mux(ex_reg_ctrl_eret, PCR_EPC,
ex_reg_raddr2)); ex_reg_raddr2));
pcr.io.w.addr := ex_reg_raddr2; pcr.io.host.from_wen ^^ io.host.from_wen;
pcr.io.w.en := ex_reg_ctrl_wen_pcr; pcr.io.host.from ^^ io.host.from;
pcr.io.w.data := ex_reg_rs1; pcr.io.host.to ^^ io.host.to;
pcr.io.eret := ex_reg_ctrl_eret; pcr.io.eret := ex_reg_ctrl_eret;
pcr.io.exception := ex_reg_ctrl_exception; pcr.io.exception := ex_reg_ctrl_exception;
pcr.io.cause := ex_reg_ctrl_cause; pcr.io.cause := ex_reg_ctrl_cause;
pcr.io.pc := ex_reg_pc; pcr.io.pc := ex_reg_pc;
io.dpath.status := pcr.io.status; io.ctrl.status := pcr.io.status;
// io.debug ^^ pcr.io.debug;
io.debug.error_mode := pcr.io.debug.error_mode; io.debug.error_mode := pcr.io.debug.error_mode;
io.debug.log_control := pcr.io.debug.log_control; io.debug.log_control := pcr.io.debug.log_control;
// branch resolution logic // branch resolution logic
io.dpath.br_eq := (ex_reg_rs1 === ex_reg_rs2); io.ctrl.br_eq := (ex_reg_rs1 === ex_reg_rs2);
io.dpath.br_ltu := (ex_reg_rs1.toUFix < ex_reg_rs2.toUFix); io.ctrl.br_ltu := (ex_reg_rs1.toUFix < ex_reg_rs2.toUFix);
io.dpath.br_lt := io.ctrl.br_lt :=
(~(ex_reg_rs1(63) ^ ex_reg_rs2(63)) & io.dpath.br_ltu | (~(ex_reg_rs1(63) ^ ex_reg_rs2(63)) & io.ctrl.br_ltu |
ex_reg_rs1(63) & ~ex_reg_rs2(63)).toBool; ex_reg_rs1(63) & ~ex_reg_rs2(63)).toBool;
io.dpath.alu_out := ex_alu_out;
// writeback select mux // writeback select mux
ex_wdata := ex_wdata :=
Mux(ex_reg_ctrl_ll_wb, ex_reg_rs1, Mux(ex_reg_ctrl_ll_wb || ex_reg_ctrl_wen_pcr, ex_reg_rs1,
Mux(ex_reg_ctrl_sel_wb === WB_PC, ex_reg_pc_plus4, Mux(ex_reg_ctrl_sel_wb === WB_PC, ex_reg_pc_plus4,
Mux(ex_reg_ctrl_sel_wb === WB_ALU, ex_alu_out, Mux(ex_reg_ctrl_sel_wb === WB_ALU, ex_alu_out,
Mux(ex_reg_ctrl_sel_wb === WB_PCR, ex_pcr, Mux(ex_reg_ctrl_sel_wb === WB_PCR, ex_pcr,
Bits(0, 64))))).toBits; Bits(0, 64))))).toBits;
// regfile write // memory stage
rfile.io.w0.addr := ex_reg_waddr; mem_reg_pc <== ex_reg_pc;
rfile.io.w0.en := ex_reg_ctrl_wen | ex_reg_ctrl_ll_wb; mem_reg_pc_plus4 <== ex_reg_pc_plus4;
rfile.io.w0.data := ex_wdata; mem_reg_waddr <== ex_reg_waddr;
mem_reg_wdata <== ex_wdata;
mem_reg_ctrl_ll_wb <== ex_reg_ctrl_ll_wb;
mem_reg_raddr2 <== ex_reg_raddr2;
rfile.io.w1.addr ^^ io.wb.waddr; when (io.ctrl.killx) {
rfile.io.w1.en ^^ io.wb.wen; mem_reg_ctrl_div_val <== Bool(false);
rfile.io.w1.data ^^ io.wb.wdata; mem_reg_ctrl_mul_val <== Bool(false);
mem_reg_ctrl_wen <== Bool(false);
// clear scoreboard for "long latency" writebacks mem_reg_ctrl_wen_pcr <== Bool(false);
io.dpath.wen := ex_reg_ctrl_ll_wb; mem_reg_ctrl_exception <== Bool(false);
io.dpath.waddr := ex_reg_waddr; }
otherwise {
mem_reg_ctrl_div_val <== ex_reg_ctrl_div_val;
mem_reg_ctrl_mul_val <== ex_reg_ctrl_mul_val;
mem_reg_ctrl_wen <== ex_reg_ctrl_wen;
mem_reg_ctrl_wen_pcr <== ex_reg_ctrl_wen_pcr;
mem_reg_ctrl_exception <== ex_reg_ctrl_exception;
}
// exception signal to control (for NPC select) // exception signal to control (for NPC select)
io.dpath.exception := ex_reg_ctrl_exception; io.ctrl.exception := mem_reg_ctrl_exception;
// writeback stage
val r_dmem_resp_val = Reg(io.dmem.resp_val);
val r_dmem_resp_waddr = Reg(io.dmem.resp_tag(4,0).toUFix);
val r_dmem_resp_pos = Reg(io.dmem.resp_tag(7,5));
val r_dmem_resp_type = Reg(io.dmem.resp_tag(9,8));
val r_dmem_resp_data = Reg(io.dmem.resp_data);
wb_reg_pc <== mem_reg_pc;
wb_reg_pc_plus4 <== mem_reg_pc_plus4;
wb_reg_waddr <== mem_reg_waddr;
wb_reg_wdata <== mem_reg_wdata;
wb_reg_ctrl_ll_wb <== mem_reg_ctrl_ll_wb;
wb_reg_raddr2 <== mem_reg_raddr2;
when (io.ctrl.killm) {
wb_reg_ctrl_div_val <== Bool(false);
wb_reg_ctrl_mul_val <== Bool(false);
wb_reg_ctrl_wen <== Bool(false);
wb_reg_ctrl_wen_pcr <== Bool(false);
}
otherwise {
wb_reg_ctrl_div_val <== mem_reg_ctrl_div_val;
wb_reg_ctrl_mul_val <== mem_reg_ctrl_mul_val;
wb_reg_ctrl_wen <== mem_reg_ctrl_wen;
wb_reg_ctrl_wen_pcr <== mem_reg_ctrl_wen_pcr;
}
// crossbar/sign extension for 8/16/32 bit loads
val dmem_resp_data_w =
Mux(r_dmem_resp_pos(2).toBool, r_dmem_resp_data(63, 32), r_dmem_resp_data(31, 0));
val dmem_resp_data_h =
Mux(r_dmem_resp_pos(1).toBool, dmem_resp_data_w(31, 16), dmem_resp_data_w(15, 0));
val dmem_resp_data_b =
Mux(r_dmem_resp_pos(0).toBool, dmem_resp_data_h(15, 8), dmem_resp_data_h(7, 0));
val dmem_resp_data_final =
Mux(r_dmem_resp_type === MT_B, Cat(Fill(56, dmem_resp_data_b(7)), dmem_resp_data_b),
Mux(r_dmem_resp_type === MT_BU, Cat(UFix(0, 56), dmem_resp_data_b),
Mux(r_dmem_resp_type === MT_H, Cat(Fill(48, dmem_resp_data_h(15)), dmem_resp_data_h),
Mux(r_dmem_resp_type === MT_HU, Cat(UFix(0, 48), dmem_resp_data_h),
Mux(r_dmem_resp_type === MT_W, Cat(Fill(32, dmem_resp_data_w(31)), dmem_resp_data_w),
Mux(r_dmem_resp_type === MT_WU, Cat(UFix(0, 32), dmem_resp_data_w),
Mux(r_dmem_resp_type === MT_D, r_dmem_resp_data,
UFix(0, 64))))))));
// regfile write
rfile.io.w0.addr := wb_reg_waddr;
rfile.io.w0.en := wb_reg_ctrl_wen | wb_reg_ctrl_ll_wb;
rfile.io.w0.data := wb_reg_wdata;
rfile.io.w1.addr := r_dmem_resp_waddr;
rfile.io.w1.en := r_dmem_resp_val;
rfile.io.w1.data := dmem_resp_data_final;
// scoreboard set (for D$ misses, div, mul)
io.ctrl.sboard_set := wb_reg_ctrl_div_val | wb_reg_ctrl_mul_val | io.ctrl.dcache_miss;
io.ctrl.sboard_seta := wb_reg_waddr;
// scoreboard clear (for div/mul and D$ load miss writebacks)
io.ctrl.sboard_clr0 := wb_reg_ctrl_ll_wb;
io.ctrl.sboard_clr0a := wb_reg_waddr;
io.ctrl.sboard_clr1 := r_dmem_resp_val;
io.ctrl.sboard_clr1a := r_dmem_resp_waddr;
// processor control regfile write
pcr.io.w.addr := wb_reg_raddr2;
pcr.io.w.en := wb_reg_ctrl_wen_pcr;
pcr.io.w.data := wb_reg_wdata;
} }

View File

@ -1,124 +0,0 @@
package Top
{
import Chisel._
import Node._;
import queues._;
import Constants._;
class ioMemory extends Bundle()
{
val mem_mrq_val = Bool('input);
val mem_mrq_cmd = Bits(4, 'input);
val mem_mrq_type = Bits(3, 'input);
val mem_xsdq_rdy = Bool('output);
val mem_xsdq_val = Bool('input);
val mem_mrq_deq = Bool('output);
val dpath_rs2 = Bits(64, 'input);
val dpath_waddr = UFix(5, 'input);
val dpath_alu_out = UFix(64, 'input);
val dmem_req_val = Bool('output);
val dmem_req_rdy = Bool('input);
val dmem_req_op = Bits(4, 'output);
val dmem_req_addr = UFix(32, 'output);
val dmem_req_data = Bits(64, 'output);
val dmem_req_wmask = Bits(8, 'output);
val dmem_req_tag = Bits(12, 'output);
}
class rocketMemory extends Component
{
override val io = new ioMemory();
val mrq_enq_xf
= (io.mem_mrq_cmd === M_FRD || io.mem_mrq_cmd === M_FWR);
val mrq_enq_op
= Mux(io.mem_mrq_cmd === M_FRD, M_XRD,
Mux(io.mem_mrq_cmd === M_FWR, M_XWR,
io.mem_mrq_cmd));
val mrq_enq_type = io.mem_mrq_type;
val mrq = new queueSimplePF(45, 4, 2);
val xsdq = new queueSimplePF(64, 4, 2);
mrq.io.q_reset := Bool(false);
mrq.io.enq_bits := Cat(mrq_enq_xf,mrq_enq_op,mrq_enq_type,io.dpath_waddr,io.dpath_alu_out(31,0));
mrq.io.enq_val ^^ io.mem_mrq_val;
// mrq.io.enq_rdy <> (); issue logic takes care of this
val mrq_deq_xf = Wire(){Bits(width = 1)};
val mrq_deq_op = Wire(){Bits(width = 4)};
val mrq_deq_type = Wire(){Bits(width = 3)};
val mrq_deq_waddr = Wire(){Bits(width = 5)};
val mrq_deq_addr = Wire(){Bits(width = 32)};
val mrq_deq_bits = mrq.io.deq_bits;
mrq_deq_bits.Match(Array(mrq_deq_xf, mrq_deq_op, mrq_deq_type, mrq_deq_waddr, mrq_deq_addr));
val mrq_deq_val = mrq.io.deq_val;
xsdq.io.q_reset := Bool(false);
xsdq.io.enq_bits ^^ io.dpath_rs2;
xsdq.io.enq_val ^^ io.mem_xsdq_val;
xsdq.io.enq_rdy ^^ io.mem_xsdq_rdy;
val mrq_deq_flush = mrq_deq_op === M_FLA;
val mrq_deq_load = mrq_deq_op === M_XRD;
val mrq_deq_xstore = mrq_deq_op === M_XWR & ~mrq_deq_xf & xsdq.io.deq_val;
val mrq_deq_rdy = io.dmem_req_rdy & (mrq_deq_load | mrq_deq_xstore | mrq_deq_flush);
io.mem_mrq_deq := (mrq_deq_val & mrq_deq_rdy).toBool;
mrq.io.deq_rdy := mrq_deq_rdy.toBool;
val xsdq_deq_rdy = io.dmem_req_rdy & mrq_deq_val & mrq_deq_op === M_XWR & ~mrq_deq_xf;
xsdq.io.deq_rdy := xsdq_deq_rdy.toBool;
val wdata = xsdq.io.deq_bits;
val wmask_b =
Mux(mrq_deq_addr(2,0) === UFix(0, 3), Bits("b0000_0001", 8),
Mux(mrq_deq_addr(2,0) === UFix(1, 3), Bits("b0000_0010", 8),
Mux(mrq_deq_addr(2,0) === UFix(2, 3), Bits("b0000_0100", 8),
Mux(mrq_deq_addr(2,0) === UFix(3, 3), Bits("b0000_1000", 8),
Mux(mrq_deq_addr(2,0) === UFix(4, 3), Bits("b0001_0000", 8),
Mux(mrq_deq_addr(2,0) === UFix(5, 3), Bits("b0010_0000", 8),
Mux(mrq_deq_addr(2,0) === UFix(6, 3), Bits("b0100_0000", 8),
Mux(mrq_deq_addr(2,0) === UFix(7, 3), Bits("b1000_0000", 8),
UFix(0, 8)))))))));
val wmask_h =
Mux(mrq_deq_addr(2,1) === UFix(0, 2), Bits("b0000_0011", 8),
Mux(mrq_deq_addr(2,1) === UFix(1, 2), Bits("b0000_1100", 8),
Mux(mrq_deq_addr(2,1) === UFix(2, 2), Bits("b0011_0000", 8),
Mux(mrq_deq_addr(2,1) === UFix(3, 2), Bits("b1100_0000", 8),
UFix(0, 8)))));
val wmask_w =
Mux(mrq_deq_addr(2) === UFix(0, 1), Bits("b0000_1111", 8),
Mux(mrq_deq_addr(2) === UFix(1, 1), Bits("b1111_0000", 8),
UFix(0, 8)));
val wmask_d =
Bits("b1111_1111", 8);
io.dmem_req_val := (mrq_deq_val & (mrq_deq_load | mrq_deq_xstore | mrq_deq_flush)).toBool;
io.dmem_req_op := mrq_deq_op;
io.dmem_req_addr := Cat(mrq_deq_addr(31,3), UFix(0, 3)).toUFix;
io.dmem_req_data :=
Mux(mrq_deq_type === MT_B, Fill(8, wdata( 7,0)),
Mux(mrq_deq_type === MT_H, Fill(4, wdata(15,0)),
Mux(mrq_deq_type === MT_W, Fill(2, wdata(31,0)),
Mux(mrq_deq_type === MT_D, wdata,
UFix(0, 64)))));
io.dmem_req_wmask :=
Mux(mrq_deq_type === MT_B, wmask_b,
Mux(mrq_deq_type === MT_H, wmask_h,
Mux(mrq_deq_type === MT_W, wmask_w,
Mux(mrq_deq_type === MT_D, wmask_d,
UFix(0, 8)))));
io.dmem_req_tag := Cat(mrq_deq_xf,mrq_deq_type,mrq_deq_addr(2,0),mrq_deq_waddr);
}
}

View File

@ -1,56 +0,0 @@
package Top
{
import Chisel._
import Node._;
import Constants._;
class ioWriteback extends Bundle()
{
val dmem_resp_val = Bool('input);
val dmem_resp_data = UFix(64, 'input);
val dmem_resp_tag = UFix(12, 'input);
val wb_waddr = UFix(5, 'output);
val wb_wen = Bool('output);
val wb_wdata = Bits(64, 'output);
}
class rocketWriteback extends Component
{
override val io = new ioWriteback();
val r_dmem_resp_val = Reg(io.dmem_resp_val);
val r_dmem_resp_data = Reg(io.dmem_resp_data);
val r_dmem_resp_tag = Reg(io.dmem_resp_tag);
val dmem_resp_xf = r_dmem_resp_tag(11);
val dmem_resp_type = r_dmem_resp_tag(10, 8);
val dmem_resp_pos = r_dmem_resp_tag(7, 5);
val dmem_resp_waddr = r_dmem_resp_tag(4, 0);
val dmem_resp_xval = r_dmem_resp_val & ~dmem_resp_xf;
val dmem_resp_fval = r_dmem_resp_val & dmem_resp_xf;
val dmem_resp_data_w =
Mux(dmem_resp_pos(2).toBool, r_dmem_resp_data(63, 32), r_dmem_resp_data(31, 0));
val dmem_resp_data_h =
Mux(dmem_resp_pos(1).toBool, dmem_resp_data_w(31, 16), dmem_resp_data_w(15, 0));
val dmem_resp_data_b =
Mux(dmem_resp_pos(0).toBool, dmem_resp_data_h(15, 8), dmem_resp_data_h(7, 0));
val dmem_resp_data_final =
Mux(dmem_resp_type === MT_B, Cat(Fill(56, dmem_resp_data_b(7)), dmem_resp_data_b),
Mux(dmem_resp_type === MT_BU, Cat(UFix(0, 56), dmem_resp_data_b),
Mux(dmem_resp_type === MT_H, Cat(Fill(48, dmem_resp_data_h(15)), dmem_resp_data_h),
Mux(dmem_resp_type === MT_HU, Cat(UFix(0, 48), dmem_resp_data_h),
Mux(dmem_resp_type === MT_W, Cat(Fill(32, dmem_resp_data_w(31)), dmem_resp_data_w),
Mux(dmem_resp_type === MT_WU, Cat(UFix(0, 32), dmem_resp_data_w),
Mux(dmem_resp_type === MT_D, r_dmem_resp_data,
UFix(0, 64))))))));
io.wb_wen := dmem_resp_xval.toBool;
io.wb_waddr := dmem_resp_waddr;
io.wb_wdata := dmem_resp_data_final;
}
}