1
0
Fork 0
rocket-chip/rocket/src/main/scala/memory.scala

125 lines
4.2 KiB
Scala

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);
}
}