From 9d63087eb2e581f608856ca0a8ff6b3aa04d35cc Mon Sep 17 00:00:00 2001 From: Rimas Avizienis Date: Mon, 7 Nov 2011 00:58:25 -0800 Subject: [PATCH] changed caches to use separate sram modules for tag and data arrays --- rocket/src/main/scala/dcache.scala | 222 +++++------------------------ rocket/src/main/scala/icache.scala | 64 ++++++--- 2 files changed, 78 insertions(+), 208 deletions(-) diff --git a/rocket/src/main/scala/dcache.scala b/rocket/src/main/scala/dcache.scala index bb22f12b..91a90ea3 100644 --- a/rocket/src/main/scala/dcache.scala +++ b/rocket/src/main/scala/dcache.scala @@ -41,8 +41,7 @@ class ioDCacheDM extends Bundle() { // state machine to flush (write back dirty lines, invalidate clean ones) the D$ class rocketDCacheDM_flush(lines: Int, addrbits: Int) extends Component { val io = new ioDCacheDM(); -// val dcache = new rocketDCacheDM(lines, addrbits); - val dcache = new rocketDCacheDM_1C(lines, addrbits); + val dcache = new rocketDCacheDM(lines, addrbits); val indexbits = ceil(log10(lines)/log10(2)).toInt; val offsetbits = 6; @@ -93,7 +92,7 @@ class rocketDCacheDM_flush(lines: Int, addrbits: Int) extends Component { } -class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component { +class rocketDCacheDM(lines: Int, addrbits: Int) extends Component { val io = new ioDCacheDM(); val indexbits = ceil(log10(lines)/log10(2)).toInt; @@ -153,17 +152,21 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component { } // tag array - val tag_we = + val tagbits = addrbits-(indexbits+offsetbits); + val tag_we = ((state === s_refill) && io.mem.req_rdy && (rr_count === UFix(3,2))) || ((state === s_resolve_miss) && req_flush); - val tag_waddr = r_cpu_req_addr(indexmsb, indexlsb).toUFix; - val tag_wdata = r_cpu_req_addr(tagmsb, taglsb); - val tag_array = Mem(lines, tag_we, tag_waddr, tag_wdata); + val tag_array = new rocketSRAMsp(lines, tagbits); val tag_raddr = Mux((state === s_ready), io.cpu.req_addr(indexmsb, indexlsb).toUFix, - r_cpu_req_addr(indexmsb, indexlsb).toUFix); - val tag_rdata = Reg(tag_array.read(tag_raddr)); - + r_cpu_req_addr(indexmsb, indexlsb).toUFix); + tag_array.io.a := tag_raddr; + tag_array.io.d := r_cpu_req_addr(tagmsb, taglsb); + tag_array.io.we := tag_we; + tag_array.io.bweb := ~Bits(0,tagbits); + tag_array.io.ce := Bool(true); // FIXME + val tag_rdata = tag_array.io.q; + // valid bit array val vb_array = Reg(resetVal = Bits(0, lines)); val vb_rdata = Reg(vb_array(tag_raddr)); @@ -242,15 +245,7 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component { } // data array - val data_array_we = ((state === s_refill) && io.mem.resp_val) || do_store; - val data_array_waddr = - Mux((state === s_refill), Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count).toUFix, - p_store_addr(indexmsb, offsetmsb-1).toUFix); - - val data_array_wdata = - Mux((state === s_refill), io.mem.resp_data, - Cat(store_data, store_data)); - + val data_array = new rocketSRAMsp(lines*4, 128); val store_wmask_expand = Cat(Fill(8, store_wmask(7)), Fill(8, store_wmask(6)), @@ -264,18 +259,25 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component { val da_store_wmask = Mux(p_store_addr(offsetlsb).toBool, Cat(store_wmask_expand, Bits(0,64)), - Cat(Bits(0,64), store_wmask_expand)); - - val data_array_wmask = - Mux((state === s_refill), ~Bits(0,128), - 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_raddr = - Mux((state === s_writeback) && io.mem.req_rdy, Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count_next).toUFix, - Mux((state === s_start_writeback) || (state === s_writeback), Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count).toUFix, + Cat(Bits(0,64), store_wmask_expand)); + + data_array.io.a := + Mux(do_store, p_store_addr(indexmsb, offsetmsb-1), + Mux((state === s_writeback) && io.mem.req_rdy, Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count_next), + Mux((state === s_start_writeback) || (state === s_writeback) || (state === s_refill), Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count), Mux((state === s_resolve_miss) || (state === s_replay_load), r_cpu_req_addr(indexmsb, offsetmsb-1), - io.cpu.req_addr(indexmsb, offsetmsb-1)))); - val data_array_rdata = Reg(data_array.read(data_array_raddr)); + io.cpu.req_addr(indexmsb, offsetmsb-1))))).toUFix; + + data_array.io.d := + Mux((state === s_refill), io.mem.resp_data, + Cat(store_data, store_data)); + + data_array.io.we := ((state === s_refill) && io.mem.resp_val) || do_store; + data_array.io.bweb := + Mux((state === s_refill), ~Bits(0,128), + da_store_wmask); + data_array.io.ce := Bool(true); // FIXME + val data_array_rdata = data_array.io.q; val miss = (state === s_ready) && r_cpu_req_val && req_load && (!tag_match || (p_store_valid && addr_match)); @@ -346,164 +348,4 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component { } } -// basic direct mapped data cache, 2 cycle read latency -// parameters : -// lines = # of cache lines -// addr_bits = address width (word addressable) bits -// 64 bit wide cpu port, 128 bit wide memory port, 64 byte cachelines -/* -class rocketDCacheDM(lines: Int, addrbits: Int) extends Component { - val io = new ioDCacheDM(); - - val indexbits = ceil(log10(lines)/log10(2)).toInt; - val offsetbits = 6; - val tagmsb = addrbits - 1; - val taglsb = indexbits+offsetbits; - val indexmsb = taglsb-1; - val indexlsb = offsetbits; - val offsetmsb = indexlsb-1; - val offsetlsb = 3; - - val s_reset :: s_ready :: s_start_writeback :: s_writeback :: s_req_refill :: s_refill :: s_resolve_miss :: Nil = Enum(7) { UFix() }; - val state = Reg(resetVal = s_reset); - - val r_cpu_req_addr = Reg(Bits(0, addrbits)); - val r_r_cpu_req_addr = Reg(r_cpu_req_addr); - val r_cpu_req_val = Reg(Bool(false)); - val r_cpu_req_data = Reg(Bits(0,64)); - val r_cpu_req_cmd = Reg(Bits(0,4)); - val r_cpu_req_wmask = Reg(Bits(0,8)); - val r_cpu_req_tag = Reg(Bits(0,12)); - val r_cpu_resp_tag = Reg(r_cpu_req_tag); - val r_cpu_resp_val = Reg(Bool(false)); - - when (io.cpu.req_val && io.cpu.req_rdy) { - r_cpu_req_addr <== io.cpu.req_addr; - r_cpu_req_data <== io.cpu.req_data; - r_cpu_req_cmd <== io.cpu.req_cmd; - r_cpu_req_wmask <== io.cpu.req_wmask; - r_cpu_req_tag <== io.cpu.req_tag; } - - val req_load = (r_cpu_req_cmd === M_XRD); - val req_store = (r_cpu_req_cmd === M_XWR); - val req_flush = (r_cpu_req_cmd === M_FLA); - - when (io.cpu.req_rdy) { r_cpu_req_val <== io.cpu.req_val; } - otherwise { r_cpu_req_val <== Bool(false); } - - // counter - val rr_count = Reg(resetVal = UFix(0,2)); - val rr_count_next = rr_count + UFix(1); - when (((state === s_refill) && io.mem.resp_val) || ((state === s_writeback) && io.mem.req_rdy)) - { rr_count <== rr_count_next; } - - // tag array - val tag_we = (state === s_resolve_miss); - val tag_waddr = r_cpu_req_addr(indexmsb, indexlsb).toUFix; - val tag_wdata = r_cpu_req_addr(tagmsb, taglsb); - val tag_array = Mem(lines, tag_we, tag_waddr, tag_wdata); - val tag_raddr = Mux((state === s_ready), io.cpu.req_addr(indexmsb, indexlsb).toUFix, r_cpu_req_addr(indexmsb, indexlsb).toUFix); - val tag_rdata = Reg(tag_array.read(tag_raddr)); - - // valid bit array - val vb_array = Reg(resetVal = Bits(0, lines)); - val vb_rdata = Reg(vb_array(tag_raddr)); - when (tag_we && !req_flush) { vb_array <== vb_array.bitSet(r_cpu_req_addr(indexmsb, indexlsb).toUFix, UFix(1,1)); } - when (tag_we && req_flush) { vb_array <== vb_array.bitSet(r_cpu_req_addr(indexmsb, indexlsb).toUFix, UFix(0,1)); } - - val tag_valid = vb_rdata.toBool; - val tag_match = tag_valid && !req_flush && (tag_rdata === r_cpu_req_addr(tagmsb, taglsb)); - val store = ((state === s_ready) && r_cpu_req_val && req_store && tag_match ) || - ((state === s_resolve_miss) && req_store); - - // dirty bit array - val db_array = Reg(resetVal = Bits(0, lines)); - val db_rdata = Reg(db_array(tag_raddr)); - val tag_dirty = db_rdata.toBool; - when (store) { db_array <== db_array.bitSet(r_cpu_req_addr(indexmsb, indexlsb).toUFix, UFix(1,1)); } - when (tag_we) { db_array <== db_array.bitSet(r_cpu_req_addr(indexmsb, indexlsb).toUFix, UFix(0,1)); } - - // data array - val data_array_we = ((state === s_refill) && io.mem.resp_val) || store; - val data_array_waddr = Mux((state === s_refill), - Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count).toUFix, - r_cpu_req_addr(indexmsb, offsetmsb-1).toUFix); - - val data_array_wdata = Mux((state === s_refill), io.mem.resp_data, Cat(r_cpu_req_data, r_cpu_req_data)); - - val req_wmask_expand = Cat(Fill(8, r_cpu_req_wmask(7)), - Fill(8, r_cpu_req_wmask(6)), - Fill(8, r_cpu_req_wmask(5)), - Fill(8, r_cpu_req_wmask(4)), - Fill(8, r_cpu_req_wmask(3)), - Fill(8, r_cpu_req_wmask(2)), - Fill(8, r_cpu_req_wmask(1)), - Fill(8, r_cpu_req_wmask(0))); - - val store_wmask = Mux(r_cpu_req_addr(offsetlsb).toBool, - Cat(req_wmask_expand, Bits(0,64)), - Cat(Bits(0,64), req_wmask_expand)); - - val data_array_wmask = Mux((state === s_refill), ~Bits(0,128), 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_raddr = Mux((state === s_writeback) && io.mem.req_rdy, Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count_next).toUFix, - Mux((state === s_start_writeback) || (state === s_writeback), Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count).toUFix, - r_cpu_req_addr(indexmsb, offsetmsb-1))); - val data_array_rdata = Reg(data_array.read(data_array_raddr)); - - // output signals - io.cpu.req_rdy := (state === s_ready) && (!r_cpu_req_val || tag_match); - - when ((((state === s_ready) && r_cpu_req_val && tag_match) || (state === s_resolve_miss)) && !req_store) - { r_cpu_resp_val <== Bool(true); } - otherwise { r_cpu_resp_val <== Bool(false); } - - io.cpu.resp_val := r_cpu_resp_val; - io.cpu.resp_data := Mux(r_r_cpu_req_addr(offsetlsb).toBool, data_array_rdata(127, 64), data_array_rdata(63,0)); - io.cpu.resp_tag := r_cpu_resp_tag; - - io.mem.req_val := (state === s_req_refill) || (state === s_writeback); - io.mem.req_rw := (state === s_writeback); - io.mem.req_wdata := data_array_rdata; - io.mem.req_tag := UFix(0); - io.mem.req_addr := Mux(state === s_writeback, - Cat(tag_rdata, r_cpu_req_addr(indexmsb, indexlsb), rr_count).toUFix, - Cat(r_cpu_req_addr(tagmsb, indexlsb), Bits(0,2)).toUFix); - - // control state machine - switch (state) { - is (s_reset) { - state <== s_ready; - } - is (s_ready) { - when (~r_cpu_req_val) { state <== s_ready; } - when (r_cpu_req_val & tag_match) { state <== s_ready; } - when (tag_valid & tag_dirty) { state <== s_start_writeback; } - when (req_flush) { state <== s_resolve_miss; } - otherwise { state <== s_req_refill; } - } - is (s_start_writeback) { - state <== s_writeback; - } - is (s_writeback) { - when (io.mem.req_rdy && (rr_count === UFix(3,2))) { - when (req_flush) { state <== s_resolve_miss; } - otherwise { state <== s_req_refill; } - } - } - is (s_req_refill) - { - when (io.mem.req_rdy) { state <== s_refill; } - } - is (s_refill) { - when (io.mem.resp_val && (rr_count === UFix(3,2))) { state <== s_resolve_miss; } - } - is (s_resolve_miss) { - state <== s_ready; - } - } -} -*/ - - } diff --git a/rocket/src/main/scala/icache.scala b/rocket/src/main/scala/icache.scala index 329be695..30e4fc17 100644 --- a/rocket/src/main/scala/icache.scala +++ b/rocket/src/main/scala/icache.scala @@ -30,6 +30,25 @@ class ioICacheDM extends Bundle() val mem = new ioIcache().flip(); } +// single port SRAM i/o +class ioSRAMsp (width: Int, addrbits: Int) extends Bundle { + val a = UFix(addrbits, 'input); // address + val d = Bits(width, 'input); // data input + val bweb = Bits(width, 'input); // bit write enable mask + val ce = Bool('input); // chip enable + val we = Bool('input); // write enable + val q = Bits(width, 'output); // data out +} + +// single ported SRAM +class rocketSRAMsp(entries: Int, width: Int) extends Component { + val addrbits = ceil(log10(entries)/log10(2)).toInt; + val io = new ioSRAMsp(width, addrbits); + val sram = Mem(entries, io.we && io.ce, io.a, io.d, wrMask = io.bweb, resetVal = null); + val rdata = Reg(sram.read(io.a)); + io.q := rdata; +} + // basic direct mapped instruction cache // parameters : // lines = # cache lines @@ -38,7 +57,7 @@ class ioICacheDM extends Bundle() class rocketICacheDM(lines: Int, addrbits : Int) extends Component { val io = new ioICacheDM(); - + val indexbits = ceil(log10(lines)/log10(2)).toInt; val offsetbits = 6; val tagmsb = addrbits - 1; @@ -47,6 +66,7 @@ class rocketICacheDM(lines: Int, addrbits : Int) extends Component { val indexlsb = offsetbits; val offsetmsb = indexlsb-1; val offsetlsb = 2; + val databits = 32; val s_reset :: s_ready :: s_request :: s_refill_wait :: s_refill :: s_resolve_miss :: Nil = Enum(6) { UFix() }; val state = Reg(resetVal = s_reset); @@ -70,17 +90,19 @@ class rocketICacheDM(lines: Int, addrbits : Int) extends Component { } // tag array - val tag_wdata = r_cpu_req_addr(tagmsb, taglsb); - val tag_waddr = r_cpu_req_addr(indexmsb, indexlsb).toUFix; - val tag_we = (state === s_refill_wait) && io.mem.resp_val; - val tag_array = Mem(lines, tag_we, tag_waddr, tag_wdata); - val tag_raddr = io.cpu.req_addr(indexmsb, indexlsb);; - val tag_lookup = Reg(tag_array.read(tag_raddr)); + val tagbits = addrbits-(indexbits+offsetbits); + val tag_array = new rocketSRAMsp(lines, tagbits); + tag_array.io.a := + Mux((state === s_refill_wait), r_cpu_req_addr(indexmsb, indexlsb).toUFix, io.cpu.req_addr(indexmsb, indexlsb)); + tag_array.io.d := r_cpu_req_addr(tagmsb, taglsb); + tag_array.io.we := (state === s_refill_wait) && io.mem.resp_val; + tag_array.io.bweb := ~Bits(0,tagbits); + tag_array.io.ce := Bool(true); // FIXME + val tag_lookup = tag_array.io.q; // valid bit array val vb_array = Reg(resetVal = Bits(0, lines)); val vb_rdata = Reg(vb_array(io.cpu.req_addr(indexmsb, indexlsb))); - when ((state === s_refill_wait) && io.mem.resp_val) { vb_array <== vb_array.bitSet(r_cpu_req_addr(indexmsb, indexlsb).toUFix, UFix(1,1)); } @@ -88,18 +110,24 @@ class rocketICacheDM(lines: Int, addrbits : Int) extends Component { val tag_match = vb_rdata.toBool && (tag_lookup === r_cpu_req_addr(tagmsb, taglsb)); // data array - val data_array_waddr = Cat(r_cpu_req_addr(indexmsb, indexlsb), refill_count).toUFix; - val data_array = Mem(lines*4, io.mem.resp_val, data_array_waddr, io.mem.resp_data); - val data_array_raddr = Cat(io.cpu.req_addr(indexmsb, indexlsb), io.cpu.req_addr(offsetmsb, offsetmsb-1)); - val data_array_read = data_array(data_array_raddr); - val data_array_rdata = Reg(data_array_read); - + val data_array = new rocketSRAMsp(lines*4, 128); + data_array.io.a := + Mux((state === s_refill_wait) || (state === s_refill), Cat(r_cpu_req_addr(indexmsb, indexlsb), refill_count), + io.cpu.req_addr(indexmsb, offsetmsb-1)).toUFix; + data_array.io.d := io.mem.resp_data; + data_array.io.we := io.mem.resp_val; + data_array.io.bweb := ~Bits(0,128); + data_array.io.ce := Bool(true); // FIXME + val data_array_rdata = data_array.io.q; + + // output signals io.cpu.resp_val := (r_cpu_req_val && tag_match && (state === s_ready)); // || (state === s_resolve_miss); io.cpu.req_rdy := ((state === s_ready) && (!r_cpu_req_val || (r_cpu_req_val && tag_match))); // || (state === s_resolve_miss); - io.cpu.resp_data := MuxLookup(r_cpu_req_addr(offsetmsb-2, offsetlsb).toUFix, data_array_rdata(127, 96), - Array(UFix(2) -> data_array_rdata(95,64), - UFix(1) -> data_array_rdata(63,32), - UFix(0) -> data_array_rdata(31,0))); + io.cpu.resp_data := + MuxLookup(r_cpu_req_addr(offsetmsb-2, offsetlsb).toUFix, data_array_rdata(127, 96), + Array(UFix(2) -> data_array_rdata(95,64), + UFix(1) -> data_array_rdata(63,32), + UFix(0) -> data_array_rdata(31,0))); io.mem.req_val := (state === s_request); io.mem.req_addr := Cat(r_cpu_req_addr(tagmsb, indexlsb), Bits(0,2)).toUFix;