Guest User

Untitled

a guest
Dec 7th, 2019
105
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import CacheTypes;
  2. import CacheHelpers;
  3. import MainMemory;
  4.  
  5. // ReqStatus (defined in CacheTypes.ms) is used to keep track of the state of the current request
  6. //typedef enum {
  7. // Ready, // The cache is ready for a new request
  8. // Lookup, // Issued a lookup to tag/data arrays
  9. // Writeback, // In main memory access for dirty writeback
  10. // Fill // In main memory access for requested data
  11. //} ReqStatus;
  12. //
  13. // Possible flows:
  14. // HIT: Ready -> Lookup -> Ready
  15. // MISS, line is clean: Ready -> Lookup -> Fill
  16. // MISS, line is dirty: Ready -> Lookup -> Writeback -> Fill
  17.  
  18. // You may find the following type synonyms helpful to access the tag/data/status arrays
  19. typedef SRAMReq#(logCacheSets, CacheTag) TagReq;
  20. typedef SRAMReq#(logCacheSets, Line) DataReq;
  21. typedef SRAMReq#(logCacheSets, CacheStatus) StatusReq;
  22.  
  23. // TODO: Complete the implementation of DirectMappedCache
  24. // NOTE: Implementing this module requires about 50 lines of additional code
  25. // (~40 lines in the rule, ~5-10 lines in the data method, and 1 line in the reqEnabled method)
  26. module DirectMappedCache(MainMemory mainMem);
  27. // SRAM arrays. Note that, for a direct-mapped cache,
  28. // number of cache sets == number of cache lines
  29. SRAM#(logCacheSets, Line) dataArray;
  30. SRAM#(logCacheSets, CacheTag) tagArray;
  31. SRAM#(logCacheSets, CacheStatus) statusArray;
  32.  
  33. // Registers for holding the current state of the cache and how far along
  34. // it is in processing a request.
  35. RegU#(MemReq) curReq;
  36. Reg#(ReqStatus) state(Ready);
  37.  
  38. // Hit/miss counters
  39. Reg#(Word) hits(0);
  40. Reg#(Word) misses(0);
  41.  
  42. input Maybe#(MemReq) req default = Invalid;
  43.  
  44. // TODO return True if the cache can accept a new request
  45. method Bool reqEnabled = (state == Ready) ? True : False;
  46.  
  47. rule tick;
  48. if (state == Ready && isValid(req)) begin
  49. //TODO Your code here
  50. let request = fromMaybe(?, req);
  51. tagArray.req = Valid(TagReq {write: False,addr: getIndex(request.addr), data: ?});
  52. statusArray.req = Valid(StatusReq {addr: getIndex(request.addr), write: False, data: ?});
  53. dataArray.req = Valid(DataReq {write: False, addr: getIndex(request.addr), data: ?});
  54.  
  55. state <= Lookup;
  56. curReq <= request;
  57.  
  58.  
  59. end else if (state == Lookup) begin
  60. //TODO Your code here
  61. // HIT: Tag matches, not Invalid
  62. let status = fromMaybe(?, statusArray.data);
  63. let tag = fromMaybe(?, tagArray.data);
  64. let data = fromMaybe(?, dataArray.data);
  65.  
  66. //HIT
  67. if (tag == getTag(curReq.addr) && status != Invalid) begin
  68. if (curReq.op == St) begin
  69. data[getWordOffset(curReq.addr)] = curReq.data;
  70. statusArray.req = Valid(StatusReq {write: True, addr: getIndex(curReq.addr), data: Dirty});
  71. dataArray.req = Valid(DataReq {write: True, addr: getIndex(curReq.addr), data: data});
  72. end
  73. state <= Ready;
  74. hits <= hits + 1;
  75. end
  76. //MISS
  77. else begin
  78. misses <= misses + 1;
  79. //Clean
  80. if (status == Clean || status == Invalid) begin
  81. mainMem.req = Valid(LineReq {op: Ld, lineAddr:{getTag(curReq.addr), getIndex(curReq.addr)}, data:?} );
  82. state <= Fill;
  83. end
  84. //Dirty
  85. else begin
  86. mainMem.req = Valid(LineReq {op: St, lineAddr: {tag, getIndex(curReq.addr)}, data:data} );
  87. state <= Writeback;
  88. end
  89.  
  90. end
  91.  
  92.  
  93. end else if (state == Writeback && mainMem.reqEnabled) begin
  94. //TODO Your code here
  95. LineReq memReq = LineReq {op: Ld, lineAddr: getLineAddr(curReq.addr), data: ?};
  96. mainMem.req = Valid(memReq);
  97. state <= Fill;
  98.  
  99. end else if (state == Fill && isValid(mainMem.data)) begin
  100. //TODO Your code here
  101. let data = fromMaybe(?, mainMem.data);
  102. StatusReq statusReq = StatusReq {write: True, addr: getIndex(curReq.addr), data: Clean};
  103. if (curReq.op == St) begin
  104. data[getWordOffset(curReq.addr)] = curReq.data;
  105. statusReq.data = Dirty;
  106. end
  107. statusArray.req = Valid(statusReq);
  108. tagArray.req = Valid(TagReq {write: True, addr: getIndex(curReq.addr), data: getTag(curReq.addr)});
  109. dataArray.req = Valid(DataReq {write: True, addr: getIndex(curReq.addr), data: data});
  110.  
  111. state <= Ready;
  112. end
  113. endrule
  114.  
  115. method Maybe#(Word) data;
  116. // This method should return a Valid output in only two cases:
  117. // 1. On a load hit (we're in the Lookup state, there's a hit, and
  118. // curReq.op == Ld).
  119. // 2. On a fill for a load request (we're in the Fill state,
  120. // mainMem.data is valid, and curReq.op == Ld).
  121. // In all other cases, the output should be Invalid
  122. //
  123. // TODO Your code here.
  124. let status = fromMaybe(?, statusArray.data);
  125. let tag = fromMaybe(?, tagArray.data);
  126. if (state == Fill && curReq.op == Ld && isValid(mainMem.data)) begin
  127. let line = fromMaybe(?, mainMem.data);
  128. return Valid(line[getWordOffset(curReq.addr)]);
  129. end
  130. else if (state == Lookup && curReq.op == Ld && status != Invalid && tag == getTag(curReq.addr)) begin
  131. let line = fromMaybe(?, dataArray.data);
  132. return Valid(line[getWordOffset(curReq.addr)]);
  133. end
  134. else return Invalid;
  135. endmethod
  136. method Bit#(32) getHits = hits;
  137. method Bit#(32) getMisses = misses;
  138. endmodule
RAW Paste Data