From 7034c9be65771e79b196a61eec9fe81c5caf912d Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sun, 19 Feb 2012 23:15:45 -0800 Subject: [PATCH] new htif protocol and implementation You must update your fesvr and isasim! --- rocket/src/main/scala/arbiter.scala | 29 +++-- rocket/src/main/scala/consts.scala | 1 - rocket/src/main/scala/cpu.scala | 22 +--- rocket/src/main/scala/ctrl.scala | 9 +- rocket/src/main/scala/dpath.scala | 9 +- rocket/src/main/scala/dpath_util.scala | 84 ++++++------- rocket/src/main/scala/htif.scala | 168 +++++++++++++++++++++++++ rocket/src/main/scala/top.scala | 15 ++- 8 files changed, 242 insertions(+), 95 deletions(-) create mode 100644 rocket/src/main/scala/htif.scala diff --git a/rocket/src/main/scala/arbiter.scala b/rocket/src/main/scala/arbiter.scala index 4a60eb10..da5495e6 100644 --- a/rocket/src/main/scala/arbiter.scala +++ b/rocket/src/main/scala/arbiter.scala @@ -24,6 +24,7 @@ class ioMemArbiter extends Bundle() { // val icache = new ioICache(); val icache = new ioIPrefetcherMem().flip(); val vicache = new ioICache(); + val htif = new ioDCache(); } 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 - 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 - io.mem.req_rw := Mux(io.dcache.req_val, io.dcache.req_rw, Bool(false)); + // Set read/write bit. I$ always reads + 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 := Mux(io.dcache.req_val, io.dcache.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$ - 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 := Mux(io.dcache.req_val, Cat(io.dcache.req_tag, t_dcache), Mux(io.icache.req_val, Cat(io.icache.req_tag, t_icache), - Cat(Bits(0, MEM_TAG_BITS-2), t_vicache))) - - // Just pass through write data (only D$ will write) - io.mem.req_wdata := io.dcache.req_wdata; + Mux(io.vicache.req_val, t_vicache, + t_htif))) // ***************************** // Interface to caches @@ -64,16 +70,19 @@ class rocketMemArbiter extends Component { io.dcache.req_rdy := io.mem.req_rdy; 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.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 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.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 io.dcache.resp_data := io.mem.resp_data; io.icache.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.icache.resp_tag := io.mem.resp_tag >> UFix(2) diff --git a/rocket/src/main/scala/consts.scala b/rocket/src/main/scala/consts.scala index 34d3a70c..e00e51cb 100644 --- a/rocket/src/main/scala/consts.scala +++ b/rocket/src/main/scala/consts.scala @@ -138,7 +138,6 @@ object Constants val PCR_TOHOST = UFix(16, 5); val PCR_FROMHOST = UFix(17, 5); val PCR_VECBANK = UFix(18, 5); - val PCR_CONSOLE = UFix(19, 5); // definition of bits in PCR status reg val SR_ET = 0; // enable traps diff --git a/rocket/src/main/scala/cpu.scala b/rocket/src/main/scala/cpu.scala index 96b33035..c8ac9643 100644 --- a/rocket/src/main/scala/cpu.scala +++ b/rocket/src/main/scala/cpu.scala @@ -10,25 +10,10 @@ class ioDebug(view: List[String] = null) extends Bundle(view) 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() { val debug = new ioDebug(); - val console = new ioConsole(); - val host = new ioHost(); + val host = new ioHTIF(); val imem = new ioImem().flip(); val vimem = new ioImem().flip(); val dmem = new ioDmem().flip(); @@ -47,6 +32,7 @@ class rocketProc extends Component val ptw = new rocketPTW(); val arb = new rocketDmemArbiter(); + ctrl.io.htif_reset := io.host.reset ctrl.io.dpath <> dpath.io.ctrl; dpath.io.host <> io.host; 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_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) { val fpu = new rocketFPU(4,6) diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index 12228da9..4bf8f4cc 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -77,8 +77,8 @@ class ioCtrlDpath extends Bundle() class ioCtrlAll extends Bundle() { + val htif_reset = Bool(INPUT) val dpath = new ioCtrlDpath(); - val console = new ioConsole(List("rdy")); 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 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_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_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.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. 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_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 || - vec_cpfence || - id_console_out_val && !io.console.rdy + vec_cpfence ); val ctrl_stallf = ctrl_stalld; diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index 2d5a7c85..9b167c5e 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -29,9 +29,8 @@ class ioDpathImem extends Bundle() class ioDpathAll extends Bundle() { - val host = new ioHost(); + val host = new ioHTIF(); val ctrl = new ioCtrlDpath().flip(); - val console = new ioConsole(List("valid","bits")); val debug = new ioDebug(); 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")) @@ -313,9 +312,7 @@ class rocketDpath extends Component Mux(ex_reg_ctrl_eret, PCR_EPC, ex_reg_raddr2); - pcr.io.host.from_wen <> io.host.from_wen; - pcr.io.host.from <> io.host.from; - pcr.io.host.to <> io.host.to; + pcr.io.host <> io.host io.ctrl.irq_timer := pcr.io.irq_timer; io.ctrl.irq_ipi := pcr.io.irq_ipi; @@ -483,8 +480,6 @@ class rocketDpath extends Component pcr.io.cause := io.ctrl.cause; pcr.io.pc := wb_reg_pc; pcr.io.badvaddr_wen := io.ctrl.badvaddr_wen; - io.console.bits := pcr.io.console_data; - io.console.valid := pcr.io.console_val; } } diff --git a/rocket/src/main/scala/dpath_util.scala b/rocket/src/main/scala/dpath_util.scala index cc89def5..62aab094 100644 --- a/rocket/src/main/scala/dpath_util.scala +++ b/rocket/src/main/scala/dpath_util.scala @@ -60,7 +60,7 @@ class rocketDpathBTB(entries: Int) extends Component 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 r = new ioReadPort(); val w = new ioWritePort(); @@ -78,8 +78,6 @@ class ioDpathPCR extends Bundle() val ptbr_wen = Bool(OUTPUT); val irq_timer = Bool(OUTPUT); val irq_ipi = Bool(OUTPUT); - val console_data = Bits(8, OUTPUT); - val console_val = Bool(OUTPUT); val vecbank = Bits(8, 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 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.evec := reg_ebase; io.ptbr := reg_ptbr; - io.host.to := Mux(io.host.from_wen, Bits(0), reg_tohost); io.debug.error_mode := reg_error_mode; io.r.data := rdata; @@ -133,19 +139,6 @@ class rocketDpathPCR extends Component cnt = cnt + reg_vecbank(i) 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)) when (io.badvaddr_wen) { 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_ipi := r_irq_ipi; - when (io.w.en) { - when (io.w.addr === PCR_STATUS) { - reg_status_vm := io.w.data(SR_VM).toBool; - reg_status_im := io.w.data(15,8); - reg_status_sx := io.w.data(SR_SX).toBool; - reg_status_ux := io.w.data(SR_UX).toBool; - reg_status_s := io.w.data(SR_S).toBool; - reg_status_ps := io.w.data(SR_PS).toBool; - reg_status_ev := Bool(HAVE_VEC) && io.w.data(SR_EV).toBool; - reg_status_ef := Bool(HAVE_FPU) && io.w.data(SR_EF).toBool; - reg_status_ec := Bool(HAVE_RVC) && io.w.data(SR_EC).toBool; - reg_status_et := io.w.data(SR_ET).toBool; + when (wen) { + when (waddr === PCR_STATUS) { + reg_status_vm := wdata(SR_VM).toBool; + reg_status_im := wdata(15,8); + reg_status_sx := wdata(SR_SX).toBool; + reg_status_ux := wdata(SR_UX).toBool; + reg_status_s := wdata(SR_S).toBool; + reg_status_ps := wdata(SR_PS).toBool; + reg_status_ev := Bool(HAVE_VEC) && wdata(SR_EV).toBool; + reg_status_ef := Bool(HAVE_FPU) && wdata(SR_EF).toBool; + reg_status_ec := Bool(HAVE_RVC) && wdata(SR_EC).toBool; + reg_status_et := wdata(SR_ET).toBool; } - when (io.w.addr === PCR_EPC) { reg_epc := io.w.data(VADDR_BITS,0).toUFix; } - when (io.w.addr === PCR_BADVADDR) { reg_badvaddr := io.w.data(VADDR_BITS,0).toUFix; } - when (io.w.addr === PCR_EVEC) { reg_ebase := io.w.data(VADDR_BITS-1,0).toUFix; } - when (io.w.addr === PCR_COUNT) { reg_count := io.w.data(31,0).toUFix; } - when (io.w.addr === PCR_COMPARE) { reg_compare := io.w.data(31,0).toUFix; r_irq_timer := Bool(false); } - when (io.w.addr === PCR_CAUSE) { reg_cause := io.w.data(4,0); } - when (io.w.addr === PCR_FROMHOST) { reg_fromhost := io.w.data; } - when (io.w.addr === PCR_SEND_IPI) { r_irq_ipi := Bool(true); } - when (io.w.addr === PCR_CLR_IPI) { r_irq_ipi := Bool(false); } - when (io.w.addr === PCR_K0) { reg_k0 := io.w.data; } - when (io.w.addr === PCR_K1) { reg_k1 := io.w.data; } - when (io.w.addr === PCR_PTBR) { reg_ptbr := Cat(io.w.data(PADDR_BITS-1, PGIDX_BITS), Bits(0, PGIDX_BITS)).toUFix; } - when (io.w.addr === PCR_VECBANK) { reg_vecbank := io.w.data(7,0) } + when (waddr === PCR_EPC) { reg_epc := wdata(VADDR_BITS,0).toUFix; } + when (waddr === PCR_BADVADDR) { reg_badvaddr := wdata(VADDR_BITS,0).toUFix; } + when (waddr === PCR_EVEC) { reg_ebase := wdata(VADDR_BITS-1,0).toUFix; } + when (waddr === PCR_COUNT) { reg_count := wdata(31,0).toUFix; } + when (waddr === PCR_COMPARE) { reg_compare := wdata(31,0).toUFix; r_irq_timer := Bool(false); } + when (waddr === PCR_CAUSE) { reg_cause := wdata(4,0); } + when (waddr === PCR_TOHOST) { reg_tohost := wdata; reg_fromhost := Bits(0) } + when (waddr === PCR_FROMHOST) { reg_fromhost := wdata; reg_tohost := Bits(0) } + when (waddr === PCR_SEND_IPI) { r_irq_ipi := Bool(true); } + when (waddr === PCR_CLR_IPI) { r_irq_ipi := Bool(false); } + when (waddr === PCR_K0) { reg_k0 := wdata; } + when (waddr === PCR_K1) { reg_k1 := wdata; } + 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) - when (io.r.en) { - switch (io.r.addr) { + when (ren) { + switch (raddr) { 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_BADVADDR) { rdata := Cat(Fill(64-VADDR_BITS-1, reg_badvaddr(VADDR_BITS)), reg_badvaddr); } diff --git a/rocket/src/main/scala/htif.scala b/rocket/src/main/scala/htif.scala new file mode 100644 index 00000000..39cbdc90 --- /dev/null +++ b/rocket/src/main/scala/htif.scala @@ -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))) +} diff --git a/rocket/src/main/scala/top.scala b/rocket/src/main/scala/top.scala index a3b1f5c5..293fc9f2 100644 --- a/rocket/src/main/scala/top.scala +++ b/rocket/src/main/scala/top.scala @@ -4,15 +4,17 @@ import Chisel._ import Node._; import Constants._; -class ioTop extends Bundle { +class ioTop(htif_width: Int) extends Bundle { val debug = new ioDebug(); - val console = new ioConsole(); - val host = new ioHost(); + val host = new ioHost(htif_width); val mem = new ioMem(); } 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 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.icache <> icache_pf.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.console <> io.console; icache_pf.io.invalidate := cpu.io.imem.invalidate icache.io.mem <> icache_pf.io.icache;