1
0

new htif protocol and implementation

You must update your fesvr and isasim!
This commit is contained in:
Andrew Waterman 2012-02-19 23:15:45 -08:00
parent 9af86633d7
commit 7034c9be65
8 changed files with 242 additions and 95 deletions

View File

@ -24,6 +24,7 @@ class ioMemArbiter extends Bundle() {
// val icache = new ioICache(); // val icache = new ioICache();
val icache = new ioIPrefetcherMem().flip(); val icache = new ioIPrefetcherMem().flip();
val vicache = new ioICache(); val vicache = new ioICache();
val htif = new ioDCache();
} }
class rocketMemArbiter extends Component { class rocketMemArbiter extends Component {
@ -34,26 +35,31 @@ class rocketMemArbiter extends Component {
// ***************************** // *****************************
// Memory request is valid if either icache or dcache have a valid request // Memory request is valid if either icache or dcache have a valid request
io.mem.req_val := (io.icache.req_val || io.vicache.req_val || io.dcache.req_val); io.mem.req_val := io.icache.req_val || io.vicache.req_val || io.dcache.req_val || io.htif.req_val
// Set read/write bit. ICache always reads // Set read/write bit. I$ always reads
io.mem.req_rw := Mux(io.dcache.req_val, io.dcache.req_rw, Bool(false)); io.mem.req_rw :=
Mux(io.dcache.req_val, io.dcache.req_rw,
Mux(io.icache.req_val, Bool(false),
Mux(io.vicache.req_val, Bool(false),
io.htif.req_rw)))
// Give priority to ICache // Give priority to D$
io.mem.req_addr := io.mem.req_addr :=
Mux(io.dcache.req_val, io.dcache.req_addr, Mux(io.dcache.req_val, io.dcache.req_addr,
Mux(io.icache.req_val, io.icache.req_addr, Mux(io.icache.req_val, io.icache.req_addr,
io.vicache.req_addr)) Mux(io.vicache.req_val, io.vicache.req_addr,
io.htif.req_addr)))
io.mem.req_wdata := Mux(io.dcache.req_val, io.dcache.req_wdata, io.htif.req_wdata)
// low bit of tag to indicate D$, I$, and VI$ // low bit of tag to indicate D$, I$, and VI$
val t_dcache :: t_icache :: t_vicache :: Nil = Enum(3){ UFix() } val t_dcache :: t_icache :: t_vicache :: t_htif :: Nil = Enum(4){ UFix() }
io.mem.req_tag := io.mem.req_tag :=
Mux(io.dcache.req_val, Cat(io.dcache.req_tag, t_dcache), Mux(io.dcache.req_val, Cat(io.dcache.req_tag, t_dcache),
Mux(io.icache.req_val, Cat(io.icache.req_tag, t_icache), Mux(io.icache.req_val, Cat(io.icache.req_tag, t_icache),
Cat(Bits(0, MEM_TAG_BITS-2), t_vicache))) Mux(io.vicache.req_val, t_vicache,
t_htif)))
// Just pass through write data (only D$ will write)
io.mem.req_wdata := io.dcache.req_wdata;
// ***************************** // *****************************
// Interface to caches // Interface to caches
@ -64,16 +70,19 @@ class rocketMemArbiter extends Component {
io.dcache.req_rdy := io.mem.req_rdy; io.dcache.req_rdy := io.mem.req_rdy;
io.icache.req_rdy := io.mem.req_rdy && !io.dcache.req_val; io.icache.req_rdy := io.mem.req_rdy && !io.dcache.req_val;
io.vicache.req_rdy := io.mem.req_rdy && !io.dcache.req_val && !io.icache.req_val io.vicache.req_rdy := io.mem.req_rdy && !io.dcache.req_val && !io.icache.req_val
io.htif.req_rdy := io.mem.req_rdy && !io.dcache.req_val && !io.icache.req_val && !io.vicache.req_val
// Response will only be valid for D$ or I$ not both because of tag bits // Response will only be valid for D$ or I$ not both because of tag bits
io.dcache.resp_val := io.mem.resp_val && (io.mem.resp_tag(1,0) === t_dcache) io.dcache.resp_val := io.mem.resp_val && (io.mem.resp_tag(1,0) === t_dcache)
io.icache.resp_val := io.mem.resp_val && (io.mem.resp_tag(1,0) === t_icache) io.icache.resp_val := io.mem.resp_val && (io.mem.resp_tag(1,0) === t_icache)
io.vicache.resp_val := io.mem.resp_val && (io.mem.resp_tag(1,0) === t_vicache) io.vicache.resp_val := io.mem.resp_val && (io.mem.resp_tag(1,0) === t_vicache)
io.htif.resp_val := io.mem.resp_val && (io.mem.resp_tag(1,0) === t_htif)
// Feed through data to both // Feed through data to both
io.dcache.resp_data := io.mem.resp_data; io.dcache.resp_data := io.mem.resp_data;
io.icache.resp_data := io.mem.resp_data; io.icache.resp_data := io.mem.resp_data;
io.vicache.resp_data := io.mem.resp_data io.vicache.resp_data := io.mem.resp_data
io.htif.resp_data := io.mem.resp_data
io.dcache.resp_tag := io.mem.resp_tag >> UFix(2) io.dcache.resp_tag := io.mem.resp_tag >> UFix(2)
io.icache.resp_tag := io.mem.resp_tag >> UFix(2) io.icache.resp_tag := io.mem.resp_tag >> UFix(2)

View File

@ -138,7 +138,6 @@ object Constants
val PCR_TOHOST = UFix(16, 5); val PCR_TOHOST = UFix(16, 5);
val PCR_FROMHOST = UFix(17, 5); val PCR_FROMHOST = UFix(17, 5);
val PCR_VECBANK = UFix(18, 5); val PCR_VECBANK = UFix(18, 5);
val PCR_CONSOLE = UFix(19, 5);
// definition of bits in PCR status reg // definition of bits in PCR status reg
val SR_ET = 0; // enable traps val SR_ET = 0; // enable traps

View File

@ -10,25 +10,10 @@ class ioDebug(view: List[String] = null) extends Bundle(view)
val error_mode = Bool(OUTPUT); val error_mode = Bool(OUTPUT);
} }
class ioHost(view: List[String] = null) extends Bundle(view)
{
val from_wen = Bool(INPUT);
val from = Bits(64, INPUT);
val to = Bits(64, OUTPUT);
}
class ioConsole(view: List[String] = null) extends Bundle(view)
{
val rdy = Bool(INPUT);
val valid = Bool(OUTPUT);
val bits = Bits(8, OUTPUT);
}
class ioRocket extends Bundle() class ioRocket extends Bundle()
{ {
val debug = new ioDebug(); val debug = new ioDebug();
val console = new ioConsole(); val host = new ioHTIF();
val host = new ioHost();
val imem = new ioImem().flip(); val imem = new ioImem().flip();
val vimem = new ioImem().flip(); val vimem = new ioImem().flip();
val dmem = new ioDmem().flip(); val dmem = new ioDmem().flip();
@ -47,6 +32,7 @@ class rocketProc extends Component
val ptw = new rocketPTW(); val ptw = new rocketPTW();
val arb = new rocketDmemArbiter(); val arb = new rocketDmemArbiter();
ctrl.io.htif_reset := io.host.reset
ctrl.io.dpath <> dpath.io.ctrl; ctrl.io.dpath <> dpath.io.ctrl;
dpath.io.host <> io.host; dpath.io.host <> io.host;
dpath.io.debug <> io.debug; dpath.io.debug <> io.debug;
@ -112,10 +98,6 @@ class rocketProc extends Component
dpath.io.dmem.resp_data := arb.io.cpu.resp_data; dpath.io.dmem.resp_data := arb.io.cpu.resp_data;
dpath.io.dmem.resp_data_subword := io.dmem.resp_data_subword; dpath.io.dmem.resp_data_subword := io.dmem.resp_data_subword;
io.console.bits := dpath.io.console.bits;
io.console.valid := dpath.io.console.valid;
ctrl.io.console.rdy := io.console.rdy;
if (HAVE_FPU) if (HAVE_FPU)
{ {
val fpu = new rocketFPU(4,6) val fpu = new rocketFPU(4,6)

View File

@ -77,8 +77,8 @@ class ioCtrlDpath extends Bundle()
class ioCtrlAll extends Bundle() class ioCtrlAll extends Bundle()
{ {
val htif_reset = Bool(INPUT)
val dpath = new ioCtrlDpath(); val dpath = new ioCtrlDpath();
val console = new ioConsole(List("rdy"));
val imem = new ioImem(List("req_val", "resp_val")).flip(); val imem = new ioImem(List("req_val", "resp_val")).flip();
val dmem = new ioDmem(List("req_val", "req_kill", "req_rdy", "req_cmd", "req_type", "resp_miss", "resp_nack")).flip(); val dmem = new ioDmem(List("req_val", "req_kill", "req_rdy", "req_cmd", "req_type", "resp_miss", "resp_nack")).flip();
val ext_mem = new ioDmem(List("req_val", "req_cmd", "req_type", "resp_nack")) val ext_mem = new ioDmem(List("req_val", "req_cmd", "req_type", "resp_nack"))
@ -298,8 +298,6 @@ class rocketCtrl extends Component
val id_raddr1 = io.dpath.inst(26,22); val id_raddr1 = io.dpath.inst(26,22);
val id_waddr = Mux(id_sel_wa === WA_RA, RA, io.dpath.inst(31,27)); val id_waddr = Mux(id_sel_wa === WA_RA, RA, io.dpath.inst(31,27));
val id_console_out_val = id_wen_pcr.toBool && (id_raddr2 === PCR_CONSOLE);
val wb_reg_div_mul_val = Reg(resetVal = Bool(false)) val wb_reg_div_mul_val = Reg(resetVal = Bool(false))
val wb_reg_dcache_miss = Reg(io.dmem.resp_miss, resetVal = Bool(false)); val wb_reg_dcache_miss = Reg(io.dmem.resp_miss, resetVal = Bool(false));
@ -699,7 +697,7 @@ class rocketCtrl extends Component
io.dpath.wen_btb := !ex_reg_btb_hit && br_taken io.dpath.wen_btb := !ex_reg_btb_hit && br_taken
io.dpath.clr_btb := ex_reg_btb_hit && !br_taken || id_reg_icmiss; io.dpath.clr_btb := ex_reg_btb_hit && !br_taken || id_reg_icmiss;
io.imem.req_val := take_pc_wb || !mem_reg_replay && !ex_reg_replay && (take_pc_ex || !id_reg_replay) io.imem.req_val := !io.htif_reset && (take_pc_wb || !mem_reg_replay && !ex_reg_replay && (take_pc_ex || !id_reg_replay))
// stall for RAW/WAW hazards on loads, AMOs, and mul/div in execute stage. // stall for RAW/WAW hazards on loads, AMOs, and mul/div in execute stage.
val data_hazard_ex = ex_reg_wen && val data_hazard_ex = ex_reg_wen &&
@ -753,8 +751,7 @@ class rocketCtrl extends Component
id_mem_val.toBool && !(io.dmem.req_rdy && io.dtlb_rdy) || id_mem_val.toBool && !(io.dmem.req_rdy && io.dtlb_rdy) ||
id_vec_val.toBool && !(io.vec_iface.vcmdq_ready && io.vec_iface.vximm1q_ready && io.vec_iface.vximm2q_ready) || // being conservative id_vec_val.toBool && !(io.vec_iface.vcmdq_ready && io.vec_iface.vximm1q_ready && io.vec_iface.vximm2q_ready) || // being conservative
((id_sync === SYNC_D) || (id_sync === SYNC_I)) && !io.dmem.req_rdy || ((id_sync === SYNC_D) || (id_sync === SYNC_I)) && !io.dmem.req_rdy ||
vec_cpfence || vec_cpfence
id_console_out_val && !io.console.rdy
); );
val ctrl_stallf = ctrl_stalld; val ctrl_stallf = ctrl_stalld;

View File

@ -29,9 +29,8 @@ class ioDpathImem extends Bundle()
class ioDpathAll extends Bundle() class ioDpathAll extends Bundle()
{ {
val host = new ioHost(); val host = new ioHTIF();
val ctrl = new ioCtrlDpath().flip(); val ctrl = new ioCtrlDpath().flip();
val console = new ioConsole(List("valid","bits"));
val debug = new ioDebug(); val debug = new ioDebug();
val dmem = new ioDpathDmem(); val dmem = new ioDpathDmem();
val ext_mem = new ioDmem(List("req_val", "req_idx", "req_ppn", "req_data", "req_tag", "resp_val", "resp_data", "resp_tag")) val ext_mem = new ioDmem(List("req_val", "req_idx", "req_ppn", "req_data", "req_tag", "resp_val", "resp_data", "resp_tag"))
@ -313,9 +312,7 @@ class rocketDpath extends Component
Mux(ex_reg_ctrl_eret, PCR_EPC, Mux(ex_reg_ctrl_eret, PCR_EPC,
ex_reg_raddr2); ex_reg_raddr2);
pcr.io.host.from_wen <> io.host.from_wen; pcr.io.host <> io.host
pcr.io.host.from <> io.host.from;
pcr.io.host.to <> io.host.to;
io.ctrl.irq_timer := pcr.io.irq_timer; io.ctrl.irq_timer := pcr.io.irq_timer;
io.ctrl.irq_ipi := pcr.io.irq_ipi; io.ctrl.irq_ipi := pcr.io.irq_ipi;
@ -483,8 +480,6 @@ class rocketDpath extends Component
pcr.io.cause := io.ctrl.cause; pcr.io.cause := io.ctrl.cause;
pcr.io.pc := wb_reg_pc; pcr.io.pc := wb_reg_pc;
pcr.io.badvaddr_wen := io.ctrl.badvaddr_wen; pcr.io.badvaddr_wen := io.ctrl.badvaddr_wen;
io.console.bits := pcr.io.console_data;
io.console.valid := pcr.io.console_val;
} }
} }

View File

@ -60,7 +60,7 @@ class rocketDpathBTB(entries: Int) extends Component
class ioDpathPCR extends Bundle() class ioDpathPCR extends Bundle()
{ {
val host = new ioHost(List("from", "from_wen", "to")); val host = new ioHTIF()
val debug = new ioDebug(List("error_mode", "log_control")); val debug = new ioDebug(List("error_mode", "log_control"));
val r = new ioReadPort(); val r = new ioReadPort();
val w = new ioWritePort(); val w = new ioWritePort();
@ -78,8 +78,6 @@ class ioDpathPCR extends Bundle()
val ptbr_wen = Bool(OUTPUT); val ptbr_wen = Bool(OUTPUT);
val irq_timer = Bool(OUTPUT); val irq_timer = Bool(OUTPUT);
val irq_ipi = Bool(OUTPUT); val irq_ipi = Bool(OUTPUT);
val console_data = Bits(8, OUTPUT);
val console_val = Bool(OUTPUT);
val vecbank = Bits(8, OUTPUT) val vecbank = Bits(8, OUTPUT)
val vecbankcnt = UFix(4, OUTPUT) val vecbankcnt = UFix(4, OUTPUT)
} }
@ -119,11 +117,19 @@ class rocketDpathPCR extends Component
val reg_status = Cat(reg_status_sx, reg_status_ux, reg_status_s, reg_status_ps, reg_status_ec, reg_status_ev, reg_status_ef, reg_status_et); val reg_status = Cat(reg_status_sx, reg_status_ux, reg_status_s, reg_status_ps, reg_status_ec, reg_status_ev, reg_status_ef, reg_status_et);
val rdata = Wire() { Bits() }; val rdata = Wire() { Bits() };
io.ptbr_wen := reg_status_vm.toBool && io.w.en && (io.w.addr === PCR_PTBR); val ren = io.r.en || io.host.pcr_ren
val raddr = Mux(io.r.en, io.r.addr, io.host.pcr_addr)
io.host.pcr_rdata := rdata
val wen = io.w.en || io.host.pcr_wen
val waddr = Mux(io.w.en, io.w.addr, io.host.pcr_addr)
val wdata = Mux(io.w.en, io.w.data, io.host.pcr_wdata)
io.host.pcr_rdy := Mux(io.host.pcr_wen, !io.w.en, !io.r.en)
io.ptbr_wen := reg_status_vm.toBool && wen && (waddr === PCR_PTBR);
io.status := Cat(reg_status_vm, reg_status_im, reg_status); io.status := Cat(reg_status_vm, reg_status_im, reg_status);
io.evec := reg_ebase; io.evec := reg_ebase;
io.ptbr := reg_ptbr; io.ptbr := reg_ptbr;
io.host.to := Mux(io.host.from_wen, Bits(0), reg_tohost);
io.debug.error_mode := reg_error_mode; io.debug.error_mode := reg_error_mode;
io.r.data := rdata; io.r.data := rdata;
@ -133,19 +139,6 @@ class rocketDpathPCR extends Component
cnt = cnt + reg_vecbank(i) cnt = cnt + reg_vecbank(i)
io.vecbankcnt := cnt(3,0) io.vecbankcnt := cnt(3,0)
val console_wen = !io.exception && io.w.en && (io.w.addr === PCR_CONSOLE);
io.console_data := Mux(console_wen, io.w.data(7,0), Bits(0,8));
io.console_val := console_wen;
when (io.host.from_wen) {
reg_tohost := Bits(0);
reg_fromhost := io.host.from;
}
.elsewhen (io.w.en && (io.w.addr === PCR_TOHOST)) {
reg_tohost := io.w.data;
reg_fromhost := Bits(0);
}
val badvaddr_sign = Mux(io.w.data(VADDR_BITS-1), ~io.w.data(63,VADDR_BITS) === UFix(0), io.w.data(63,VADDR_BITS) != UFix(0)) val badvaddr_sign = Mux(io.w.data(VADDR_BITS-1), ~io.w.data(63,VADDR_BITS) === UFix(0), io.w.data(63,VADDR_BITS) != UFix(0))
when (io.badvaddr_wen) { when (io.badvaddr_wen) {
reg_badvaddr := Cat(badvaddr_sign, io.w.data(VADDR_BITS-1,0)).toUFix; reg_badvaddr := Cat(badvaddr_sign, io.w.data(VADDR_BITS-1,0)).toUFix;
@ -185,37 +178,38 @@ class rocketDpathPCR extends Component
io.irq_timer := r_irq_timer; io.irq_timer := r_irq_timer;
io.irq_ipi := r_irq_ipi; io.irq_ipi := r_irq_ipi;
when (io.w.en) { when (wen) {
when (io.w.addr === PCR_STATUS) { when (waddr === PCR_STATUS) {
reg_status_vm := io.w.data(SR_VM).toBool; reg_status_vm := wdata(SR_VM).toBool;
reg_status_im := io.w.data(15,8); reg_status_im := wdata(15,8);
reg_status_sx := io.w.data(SR_SX).toBool; reg_status_sx := wdata(SR_SX).toBool;
reg_status_ux := io.w.data(SR_UX).toBool; reg_status_ux := wdata(SR_UX).toBool;
reg_status_s := io.w.data(SR_S).toBool; reg_status_s := wdata(SR_S).toBool;
reg_status_ps := io.w.data(SR_PS).toBool; reg_status_ps := wdata(SR_PS).toBool;
reg_status_ev := Bool(HAVE_VEC) && io.w.data(SR_EV).toBool; reg_status_ev := Bool(HAVE_VEC) && wdata(SR_EV).toBool;
reg_status_ef := Bool(HAVE_FPU) && io.w.data(SR_EF).toBool; reg_status_ef := Bool(HAVE_FPU) && wdata(SR_EF).toBool;
reg_status_ec := Bool(HAVE_RVC) && io.w.data(SR_EC).toBool; reg_status_ec := Bool(HAVE_RVC) && wdata(SR_EC).toBool;
reg_status_et := io.w.data(SR_ET).toBool; reg_status_et := wdata(SR_ET).toBool;
} }
when (io.w.addr === PCR_EPC) { reg_epc := io.w.data(VADDR_BITS,0).toUFix; } when (waddr === PCR_EPC) { reg_epc := wdata(VADDR_BITS,0).toUFix; }
when (io.w.addr === PCR_BADVADDR) { reg_badvaddr := io.w.data(VADDR_BITS,0).toUFix; } when (waddr === PCR_BADVADDR) { reg_badvaddr := wdata(VADDR_BITS,0).toUFix; }
when (io.w.addr === PCR_EVEC) { reg_ebase := io.w.data(VADDR_BITS-1,0).toUFix; } when (waddr === PCR_EVEC) { reg_ebase := wdata(VADDR_BITS-1,0).toUFix; }
when (io.w.addr === PCR_COUNT) { reg_count := io.w.data(31,0).toUFix; } when (waddr === PCR_COUNT) { reg_count := wdata(31,0).toUFix; }
when (io.w.addr === PCR_COMPARE) { reg_compare := io.w.data(31,0).toUFix; r_irq_timer := Bool(false); } when (waddr === PCR_COMPARE) { reg_compare := wdata(31,0).toUFix; r_irq_timer := Bool(false); }
when (io.w.addr === PCR_CAUSE) { reg_cause := io.w.data(4,0); } when (waddr === PCR_CAUSE) { reg_cause := wdata(4,0); }
when (io.w.addr === PCR_FROMHOST) { reg_fromhost := io.w.data; } when (waddr === PCR_TOHOST) { reg_tohost := wdata; reg_fromhost := Bits(0) }
when (io.w.addr === PCR_SEND_IPI) { r_irq_ipi := Bool(true); } when (waddr === PCR_FROMHOST) { reg_fromhost := wdata; reg_tohost := Bits(0) }
when (io.w.addr === PCR_CLR_IPI) { r_irq_ipi := Bool(false); } when (waddr === PCR_SEND_IPI) { r_irq_ipi := Bool(true); }
when (io.w.addr === PCR_K0) { reg_k0 := io.w.data; } when (waddr === PCR_CLR_IPI) { r_irq_ipi := Bool(false); }
when (io.w.addr === PCR_K1) { reg_k1 := io.w.data; } when (waddr === PCR_K0) { reg_k0 := wdata; }
when (io.w.addr === PCR_PTBR) { reg_ptbr := Cat(io.w.data(PADDR_BITS-1, PGIDX_BITS), Bits(0, PGIDX_BITS)).toUFix; } when (waddr === PCR_K1) { reg_k1 := wdata; }
when (io.w.addr === PCR_VECBANK) { reg_vecbank := io.w.data(7,0) } when (waddr === PCR_PTBR) { reg_ptbr := Cat(wdata(PADDR_BITS-1, PGIDX_BITS), Bits(0, PGIDX_BITS)).toUFix; }
when (waddr === PCR_VECBANK) { reg_vecbank := wdata(7,0) }
} }
rdata := Bits(0, 64) rdata := Bits(0, 64)
when (io.r.en) { when (ren) {
switch (io.r.addr) { switch (raddr) {
is (PCR_STATUS) { rdata := Cat(Bits(0,47), reg_status_vm, reg_status_im, reg_status); } is (PCR_STATUS) { rdata := Cat(Bits(0,47), reg_status_vm, reg_status_im, reg_status); }
is (PCR_EPC) { rdata := Cat(Fill(64-VADDR_BITS-1, reg_epc(VADDR_BITS)), reg_epc); } is (PCR_EPC) { rdata := Cat(Fill(64-VADDR_BITS-1, reg_epc(VADDR_BITS)), reg_epc); }
is (PCR_BADVADDR) { rdata := Cat(Fill(64-VADDR_BITS-1, reg_badvaddr(VADDR_BITS)), reg_badvaddr); } is (PCR_BADVADDR) { rdata := Cat(Fill(64-VADDR_BITS-1, reg_badvaddr(VADDR_BITS)), reg_badvaddr); }

View File

@ -0,0 +1,168 @@
package Top
import Chisel._
import Node._;
import Constants._;
class ioHost(w: Int, view: List[String] = null) extends Bundle(view)
{
val in = new ioDecoupled()(Bits(width = w))
val out = new ioDecoupled()(Bits(width = w)).flip()
}
class ioHTIF extends Bundle
{
val reset = Bool(INPUT)
val pcr_wen = Bool(INPUT)
val pcr_ren = Bool(INPUT)
val pcr_rdy = Bool(OUTPUT)
val pcr_addr = Bits(5, INPUT)
val pcr_wdata = Bits(64, INPUT)
val pcr_rdata = Bits(64, OUTPUT)
}
class rocketHTIF(w: Int, ncores: Int) extends Component
{
val io = new Bundle {
val host = new ioHost(w)
val cpu = Vec(ncores) { new ioHTIF().flip() }
val mem = new ioDCache().flip()
}
val short_request_bits = 64
val long_request_bits = 576
require(short_request_bits % w == 0)
val rx_count_w = 13 + log2up(8) - log2up(w) // data size field is 12 bits
val rx_count = Reg(resetVal = UFix(0,rx_count_w))
val rx_shifter = Reg() { Bits(width = short_request_bits) }
val header = Reg() { Bits() }
val rx_shifter_in = Cat(io.host.in.bits, rx_shifter(short_request_bits-1,w))
when (io.host.in.valid && io.host.in.ready) {
rx_shifter := rx_shifter_in
rx_count := rx_count + UFix(1)
when (rx_count === UFix(short_request_bits/w-1)) {
header := rx_shifter_in
}
}
val rx_count_words = rx_count >> UFix(log2up(short_request_bits/w))
val packet_ram_wen = rx_count(log2up(short_request_bits/w)-1,0).andR &&
io.host.in.valid && io.host.in.ready
val packet_ram = Mem(long_request_bits/short_request_bits-1,
packet_ram_wen, rx_count_words - UFix(1), rx_shifter_in)
val cmd_readmem :: cmd_writemem :: cmd_readcr :: cmd_writecr :: cmd_ack :: cmd_nack :: Nil = Enum(6) { UFix() }
val cmd = header(3,0)
val size = header(15,4)
val seqno = header(23,16)
val addr = header(63,24).toUFix
val pcr_addr = addr(19,0)
val pcr_coreid = addr(39,20)
val pcr_wdata = packet_ram(UFix(0))
val nack = Mux(cmd === cmd_readmem || cmd === cmd_writemem, size != UFix((1 << OFFSET_BITS)/8),
Mux(cmd === cmd_readcr || cmd === cmd_writecr, size != UFix(1),
Bool(true)))
val tx_count = Reg(resetVal = UFix(0, log2up(long_request_bits/w+1)))
val packet_ram_raddr = (tx_count >> UFix(log2up(short_request_bits/w)))
when (io.host.out.valid && io.host.out.ready) {
tx_count := tx_count + UFix(1)
}
val rx_size = Mux(cmd === cmd_writemem || cmd === cmd_writecr, size, UFix(0))
val rx_done = rx_count >= UFix(short_request_bits/w) && rx_count_words-UFix(1) === rx_size
val tx_size = Mux(!nack && cmd === cmd_readmem, UFix((1 << OFFSET_BITS)/8),
Mux(!nack && cmd === cmd_readcr, UFix(1), UFix(0)))
val tx_done = packet_ram_raddr - UFix(1) === tx_size
val state_rx :: state_pcr :: state_mem_req :: state_mem_resp :: state_tx :: Nil = Enum(5) { UFix() }
val state = Reg(resetVal = state_rx)
when (state === state_rx && rx_done) {
state := Mux(cmd === cmd_readmem || cmd === cmd_writemem, state_mem_req,
Mux(cmd === cmd_readcr || cmd === cmd_writecr, state_pcr,
state_tx))
}
val pcr_done = Reg() { Bool() }
when (state === state_pcr && pcr_done) {
state := state_tx
}
val mem_cnt = Reg(resetVal = UFix(0, log2up(REFILL_CYCLES)))
when (state === state_mem_req && io.mem.req_rdy) {
when (cmd === cmd_writemem) {
when (mem_cnt.andR) {
state := state_tx
}
mem_cnt := mem_cnt + UFix(1)
}
.otherwise {
state := state_mem_resp
}
}
when (state === state_mem_resp && io.mem.resp_val) {
when (mem_cnt.andR) {
state := state_tx
}
mem_cnt := mem_cnt + UFix(1)
}
when (state === state_tx && tx_done) {
rx_count := UFix(0)
tx_count := UFix(0)
state := state_rx
}
var mem_req_data: Bits = null
for (i <- 0 until MEM_DATA_BITS/short_request_bits) {
val idx = Cat(mem_cnt, UFix(i, log2up(MEM_DATA_BITS/short_request_bits)))
packet_ram.write(idx, io.mem.resp_data((i+1)*short_request_bits-1, i*short_request_bits),
state === state_mem_resp && io.mem.resp_val)
mem_req_data = Cat(packet_ram.read(idx), mem_req_data)
}
io.mem.req_val := state === state_mem_req
io.mem.req_rw := cmd === cmd_writemem
io.mem.req_addr := addr >> UFix(3)
io.mem.req_wdata := mem_req_data
pcr_done := Bool(false)
val pcr_mux = (new Mux1H(ncores)) { Bits(width = 64) }
for (i <- 0 until ncores) {
val me = pcr_coreid === UFix(i)
io.cpu(i).pcr_wen := Reg(state === state_pcr && cmd === cmd_writecr && me, resetVal = Bool(false))
io.cpu(i).pcr_addr := Reg(pcr_addr)
io.cpu(i).pcr_wdata := Reg(pcr_wdata)
val my_reset = Reg(resetVal = Bool(true))
when (io.cpu(i).pcr_wen && io.cpu(i).pcr_rdy) {
when (io.cpu(i).pcr_addr === UFix(15)) { my_reset := io.cpu(i).pcr_wdata(0) }
pcr_done := Bool(true)
}
io.cpu(i).reset := my_reset
io.cpu(i).pcr_ren := Reg(state === state_pcr && cmd === cmd_readcr && me, resetVal = Bool(false))
val rdata = Reg() { Bits() }
when (io.cpu(i).pcr_ren && io.cpu(i).pcr_rdy) {
rdata := io.cpu(i).pcr_rdata
when (io.cpu(i).pcr_addr === UFix(15)) { rdata := my_reset }
pcr_done := Bool(true)
}
pcr_mux.io.sel(i) := Reg(me)
pcr_mux.io.in(i) := rdata
}
val tx_cmd = Mux(nack, cmd_nack, cmd_ack)
val tx_cmd_ext = Cat(Bits(0, 4-tx_cmd.getWidth), tx_cmd)
val tx_size_ext = Cat(Bits(0, 12-tx_size.getWidth), tx_size)
val tx_header = Cat(addr, seqno, tx_size_ext, tx_cmd_ext)
val tx_data = Mux(packet_ram_raddr === UFix(0), tx_header,
Mux(packet_ram_raddr === UFix(1) && cmd === cmd_readcr, pcr_mux.io.out,
packet_ram(packet_ram_raddr - UFix(1))))
io.host.in.ready := state === state_rx && !rx_done
io.host.out.valid := state === state_tx && !tx_done
io.host.out.bits := tx_data >> Cat(tx_count(log2up(short_request_bits/w)-1,0), Bits(0, log2up(w)))
}

View File

@ -4,15 +4,17 @@ import Chisel._
import Node._; import Node._;
import Constants._; import Constants._;
class ioTop extends Bundle { class ioTop(htif_width: Int) extends Bundle {
val debug = new ioDebug(); val debug = new ioDebug();
val console = new ioConsole(); val host = new ioHost(htif_width);
val host = new ioHost();
val mem = new ioMem(); val mem = new ioMem();
} }
class Top() extends Component { class Top() extends Component {
val io = new ioTop();
val htif_width = 16
val io = new ioTop(htif_width);
val htif = new rocketHTIF(htif_width, 1)
val cpu = new rocketProc(); val cpu = new rocketProc();
val icache = new rocketICache(128, 2); // 128 sets x 2 ways val icache = new rocketICache(128, 2); // 128 sets x 2 ways
@ -25,10 +27,11 @@ class Top() extends Component {
arbiter.io.dcache <> dcache.io.mem; arbiter.io.dcache <> dcache.io.mem;
arbiter.io.icache <> icache_pf.io.mem; arbiter.io.icache <> icache_pf.io.mem;
arbiter.io.vicache <> vicache.io.mem arbiter.io.vicache <> vicache.io.mem
arbiter.io.htif <> htif.io.mem
cpu.io.host <> io.host; htif.io.host <> io.host
cpu.io.host <> htif.io.cpu(0);
cpu.io.debug <> io.debug; cpu.io.debug <> io.debug;
cpu.io.console <> io.console;
icache_pf.io.invalidate := cpu.io.imem.invalidate icache_pf.io.invalidate := cpu.io.imem.invalidate
icache.io.mem <> icache_pf.io.icache; icache.io.mem <> icache_pf.io.icache;