DCache.bsv


Todones

CacheDataIfc
- put() -> rule doPut() // 
- getResponse() // done.


Q&A

  • Who calls this module and what is the input?

    • called from Memory.bsv: interface DataMemory:startMem, after TLB translation. dCache.put(req);
    • The input is the physical memory access request req of type CacheRequestDataT.
    • see Memory.bsv.
  • Where does it go?

    • it send a memory request to CacheCore, see CacheCore.
    • it returns the response back to Memory.bsv: interface DataMemory:getResponse. CacheResponseDataT cr <- dCache.getResponse();
  • Given the tlb response, how does the tagged memory being accessed? How this is connected with tag controller?


mkDCache 1

States

FIFOF#(CacheResponseDataT)         preRsp_fifo <- mkLFIFOF;
Reg#(CacheRequestDataT)              reqInWire <- mkWire;
FF#(CheriMemRequest,1)                 coreReq <- mkFFBypass1;
Reg#(CheriTransactionID)        transactionNum <- mkReg(0);
Reg#(CacheState)                         state <- mkReg(Serving);
  
FIFOF#(CheriMemResponse)               memRsps <- mkUGFIFOF();

CacheCore#(4, TSub#(Indices,1), 1)        core <- mkCacheCore(cacheId, 
                                                   wmb, 
                                                   RespondAll, 
                                                   InOrder, 
                                                   DCache, 
                                                   zeroExtend(memReqs.remaining()), 
                                                   ff2fifof(memReqs), 
                                                   memRsps
                                                   );

Interface: CacheDataIfc

// cheri/trunk/MIPS.bsv

interface CacheDataIfc;
  method Action put(CacheRequestDataT reqIn);
  method ActionValue#(CacheResponseDataT) getResponse();
  method Action invalidate(PhyAddress addr);
  method ActionValue#(Bool) getInvalidateDone;
  method Action nextWillCommit(Bool committing);
  method L1ChCfg getConfig();
  interface Master#(CheriMemRequest, CheriMemResponse) memory;
  `ifdef STATCOUNTERS
  interface Get#(ModuleEvents) cacheEvents;
  `endif
endinterface: CacheDataIfc

method ActionValue#(CacheResponseDataT) getResponse()

parse the CheriMemResponse and construct CacheResponseDataT to return.

method put(CacheRequestDataT reqIn)

Condition: if (putReady) // putReady is on only if coreReq preRsp_fifo not full and state==Serving, and writebacks.notFull if writeback DCache enabled.

reqInWire <= reqIn

See rule doPut

rule doPut(putReady)

Overview: prepare a memory request in coreReq and hand it over to CacheCore core. See rule feedCore.

Data path: physical addr reqIn.tr.addr -> {CheriPhyAddr addr, CheriMemRequest mem_req, CacheResponseDataT resp} -> { coreReq.enq(mem_req), preRsp_fifo.enq(resp)}

  • input reqInWire/reqIn
  • get physical address, store to
    • CheriPhyAddr: CheriPhyAddr addr = unpack(reqIn.tr.addr), and
    • CheriMemRequest: CheriMemRequest mem_req = next_mem_req; mem_req.addr = addr;
    • CacheResponseDataT: resp = {isCap, ..., data: {?,pack(addr)}, ...}
  • check cache operation case(cop.inst), then update mem_req.operation, resp.exception , and flags state, willPutToCore.

    • if CacheNop
    • if CachePrefetch
    • if Read
    • if Write, StoreConditional
    • if CacheSync
    • mem_req.operation defined in MemTypes.bsv
  • put request and response struct into FIFO: coreReq.enq(mem_req); preRsp_fifo.enq(resp)

    • coreReq is a one size fifo contain one ele of type CheriMemRequest
    • preRsp_fifo is fifof# of type CacheResponseDataT
  • increase the transactionNum: transactionNum <= transactionNum + 1;

rule feedCore(core.canPut)

pick the request from fifo coreReq and put it into fifo core


  1. github/beri. ↩
Created May 3, 2020 // Last Updated May 27, 2020

If you could revise
the fundmental principles of
computer system design
to improve security...

... what would you change?