2011-10-26 08:02:47 +02:00
|
|
|
package Top {
|
|
|
|
|
|
|
|
import Chisel._;
|
|
|
|
import Node._;
|
|
|
|
import Constants._;
|
|
|
|
|
|
|
|
class ioMem() extends Bundle
|
|
|
|
{
|
2012-01-18 19:28:48 +01:00
|
|
|
val req_val = Bool(OUTPUT);
|
|
|
|
val req_rdy = Bool(INPUT);
|
|
|
|
val req_rw = Bool(OUTPUT);
|
|
|
|
val req_addr = UFix(PADDR_BITS - OFFSET_BITS, OUTPUT);
|
|
|
|
val req_wdata = Bits(MEM_DATA_BITS, OUTPUT);
|
|
|
|
val req_tag = Bits(MEM_TAG_BITS, OUTPUT);
|
2011-10-26 08:02:47 +02:00
|
|
|
|
2012-01-18 19:28:48 +01:00
|
|
|
val resp_val = Bool(INPUT);
|
|
|
|
val resp_tag = Bits(MEM_TAG_BITS, INPUT);
|
|
|
|
val resp_data = Bits(MEM_DATA_BITS, INPUT);
|
2011-10-26 08:02:47 +02:00
|
|
|
}
|
|
|
|
|
2011-12-09 09:42:43 +01:00
|
|
|
class ioMemArbiter extends Bundle() {
|
2011-10-26 08:02:47 +02:00
|
|
|
val mem = new ioMem();
|
2012-02-07 23:07:42 +01:00
|
|
|
val dcache = new ioDCache();
|
|
|
|
// val icache = new ioICache();
|
2011-10-26 08:02:47 +02:00
|
|
|
val icache = new ioIPrefetcherMem().flip();
|
2012-02-15 08:34:57 +01:00
|
|
|
val vicache = new ioICache();
|
2012-02-20 08:15:45 +01:00
|
|
|
val htif = new ioDCache();
|
2011-10-26 08:02:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class rocketMemArbiter extends Component {
|
2011-12-09 09:42:43 +01:00
|
|
|
val io = new ioMemArbiter();
|
2011-10-26 08:02:47 +02:00
|
|
|
|
|
|
|
// *****************************
|
|
|
|
// Interface to memory
|
|
|
|
// *****************************
|
|
|
|
|
|
|
|
// Memory request is valid if either icache or dcache have a valid request
|
2012-02-20 08:15:45 +01:00
|
|
|
io.mem.req_val := io.icache.req_val || io.vicache.req_val || io.dcache.req_val || io.htif.req_val
|
2011-10-26 08:02:47 +02:00
|
|
|
|
2012-02-20 08:15:45 +01:00
|
|
|
// 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)))
|
2011-10-26 08:02:47 +02:00
|
|
|
|
2012-02-20 08:15:45 +01:00
|
|
|
// Give priority to D$
|
2012-02-15 08:34:57 +01:00
|
|
|
io.mem.req_addr :=
|
|
|
|
Mux(io.dcache.req_val, io.dcache.req_addr,
|
|
|
|
Mux(io.icache.req_val, io.icache.req_addr,
|
2012-02-20 08:15:45 +01:00
|
|
|
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)
|
2012-02-15 08:34:57 +01:00
|
|
|
|
|
|
|
// low bit of tag to indicate D$, I$, and VI$
|
2012-02-20 08:15:45 +01:00
|
|
|
val t_dcache :: t_icache :: t_vicache :: t_htif :: Nil = Enum(4){ UFix() }
|
2012-02-15 08:34:57 +01:00
|
|
|
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),
|
2012-02-20 08:15:45 +01:00
|
|
|
Mux(io.vicache.req_val, t_vicache,
|
|
|
|
t_htif)))
|
2011-10-26 08:02:47 +02:00
|
|
|
|
|
|
|
// *****************************
|
|
|
|
// Interface to caches
|
|
|
|
// *****************************
|
|
|
|
|
2012-01-04 03:41:53 +01:00
|
|
|
// Read for request from cache if the memory is ready. Give priority to D$.
|
|
|
|
// This way, writebacks will never be interrupted by I$ refills.
|
|
|
|
io.dcache.req_rdy := io.mem.req_rdy;
|
|
|
|
io.icache.req_rdy := io.mem.req_rdy && !io.dcache.req_val;
|
2012-02-15 08:34:57 +01:00
|
|
|
io.vicache.req_rdy := io.mem.req_rdy && !io.dcache.req_val && !io.icache.req_val
|
2012-02-20 08:15:45 +01:00
|
|
|
io.htif.req_rdy := io.mem.req_rdy && !io.dcache.req_val && !io.icache.req_val && !io.vicache.req_val
|
2011-10-26 08:02:47 +02:00
|
|
|
|
|
|
|
// Response will only be valid for D$ or I$ not both because of tag bits
|
2012-02-15 08:34:57 +01:00
|
|
|
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)
|
2012-02-20 08:15:45 +01:00
|
|
|
io.htif.resp_val := io.mem.resp_val && (io.mem.resp_tag(1,0) === t_htif)
|
2011-10-26 08:02:47 +02:00
|
|
|
|
|
|
|
// Feed through data to both
|
|
|
|
io.dcache.resp_data := io.mem.resp_data;
|
2012-02-15 08:34:57 +01:00
|
|
|
io.icache.resp_data := io.mem.resp_data;
|
|
|
|
io.vicache.resp_data := io.mem.resp_data
|
2012-02-20 08:15:45 +01:00
|
|
|
io.htif.resp_data := io.mem.resp_data
|
2011-10-26 08:02:47 +02:00
|
|
|
|
2012-02-15 08:34:57 +01:00
|
|
|
io.dcache.resp_tag := io.mem.resp_tag >> UFix(2)
|
|
|
|
io.icache.resp_tag := io.mem.resp_tag >> UFix(2)
|
2011-10-26 08:02:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|