Advertisement
Guest User

Untitled

a guest
Dec 7th, 2019
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.02 KB | None | 0 0
  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 TwoWayCache
  24. // NOTE: Implementing this module requires about 20 new lines of code from DirectMappedCache
  25. module TwoWayCache(MainMemory mainMem);
  26. // SRAM arrays, one element per way (e.g., dataArrays[0] is the data array of way 0).
  27. Vector#(2, SRAM#(logCacheSets, Line)) dataArrays;
  28. Vector#(2, SRAM#(logCacheSets, CacheTag)) tagArrays;
  29. Vector#(2, SRAM#(logCacheSets, CacheStatus)) statusArrays;
  30.  
  31. // LRU bits, one per set. We implement it as registers instead of an SRAM
  32. // array, because with small caches this is just a few bits (e.g., 64), and
  33. // SRAMs make sense only for larger memories. This also makes the code
  34. // simpler, and will make the cache easier to pipeline in the future.
  35. Vector#(cacheSets, RegU#(Bit#(1))) lru;
  36.  
  37. // Registers for holding the current state of the cache and how far along
  38. // it is in processing a request.
  39. RegU#(MemReq) curReq;
  40. Reg#(ReqStatus) state(Ready);
  41.  
  42. // Hit/miss counters
  43. Reg#(Word) hits(0);
  44. Reg#(Word) misses(0);
  45.  
  46. input Maybe#(MemReq) req default = Invalid;
  47.  
  48. //TODO return True if the cache can accept a new request
  49. method Bool reqEnabled = (state == Ready) ? True : False;
  50.  
  51. rule tick;
  52. if (state == Ready && isValid(req)) begin
  53. //TODO Your code here
  54. let request = fromMaybe(?, req);
  55. tagArrays[0].req = Valid(TagReq {write: False, addr: getIndex(request.addr), data:?});
  56. tagArrays[1].req = Valid(TagReq {write: False, addr: getIndex(request.addr), data:?});
  57. statusArrays[0].req = Valid(StatusReq {write: False, addr: getIndex(request.addr), data:?});
  58. statusArrays[1].req = Valid(StatusReq {write: False, addr: getIndex(request.addr), data:?});
  59. dataArrays[0].req = Valid(DataReq {write: False, addr: getIndex(request.addr), data:?});
  60. dataArrays[1].req = Valid(DataReq {write: False, addr: getIndex(request.addr), data:?});
  61. state <= Lookup;
  62. curReq <= request;
  63.  
  64. end else if (state == Lookup) begin
  65. //TODO Your code here
  66. let status0 = fromMaybe(?, statusArrays[0].data);
  67. let status1 = fromMaybe(?, statusArrays[1].data);
  68. let tag0 = fromMaybe(?, tagArrays[0].data);
  69. let tag1 = fromMaybe(?, tagArrays[1].data);
  70. let data0 = fromMaybe(?, dataArrays[0].data);
  71. let data1 = fromMaybe(?, dataArrays[1].data);
  72.  
  73. //HIT on Way 1
  74. if (tag0 == getTag(curReq.addr) && status0 != Invalid) begin
  75. if (curReq.op == St) begin
  76. data0[getWordOffset(curReq.addr)] = curReq.data;
  77. statusArrays[0].req = Valid(StatusReq {write: True, addr: getIndex(curReq.addr), data: Dirty});
  78. dataArrays[0].req = Valid(DataReq {write: True, addr: getIndex(curReq.addr), data:data0});
  79. end
  80. state <= Ready;
  81. hits <= hits + 1;
  82. lru[getIndex(curReq.addr)] <= 1;
  83. end
  84. //HIT on Way 2
  85. else if (tag1 == getTag(curReq.addr) && status1 != Invalid) begin
  86. if (curReq.op == St) begin
  87. data1[getWordOffset(curReq.addr)] = curReq.data;
  88. statusArrays[1].req = Valid(StatusReq {write: True, addr: getIndex(curReq.addr), data: Dirty});
  89. dataArrays[1].req = Valid(DataReq {write: True, addr: getIndex(curReq.addr), data:data1});
  90. end
  91. state <= Ready;
  92. hits <= hits + 1;
  93. lru[getIndex(curReq.addr)] <= 0;
  94. end
  95.  
  96. //MISS
  97. else begin
  98. misses <= misses +1;
  99. let i = lru[getIndex(curReq.addr)];
  100. //Clean
  101. let status = fromMaybe(?, statusArrays[i].data);
  102. if (status == Clean || status == Invalid) begin
  103. mainMem.req = Valid(LineReq {op: Ld, lineAddr: {getTag(curReq.addr), getIndex(curReq.addr)}, data:?});
  104. state <= Fill;
  105. end
  106. //Dirty
  107. else begin
  108. let tag = fromMaybe(?, tagArrays[i].data);
  109. mainMem.req = Valid(LineReq {op: St, lineAddr: {tag, getIndex(curReq.addr)}, data:fromMaybe(?, dataArrays[i].data)});
  110. state <= Writeback;
  111. end
  112. //lru[getIndex(curReq.addr)] <= ~i;
  113. end
  114.  
  115.  
  116. end else if (state == Writeback && mainMem.reqEnabled) begin
  117. //TODO Your code here
  118. LineReq memReq = LineReq {op: Ld, lineAddr: getLineAddr(curReq.addr), data:?};
  119. mainMem.req = Valid(memReq);
  120. state <= Fill;
  121.  
  122. end else if (state == Fill && isValid(mainMem.data)) begin
  123. //TODO Your code here
  124. let data = fromMaybe(?, mainMem.data);
  125. let i = lru[getIndex(curReq.addr)];
  126. StatusReq statusReq = StatusReq {write: True, addr: getIndex(curReq.addr), data: Clean};
  127. if (curReq.op == St) begin
  128. data[getWordOffset(curReq.addr)] = curReq.data;
  129. statusReq.data = Dirty;
  130. end
  131. statusArrays[i].req = Valid(statusReq);
  132. tagArrays[i].req = Valid(TagReq {write: True, addr: getIndex(curReq.addr), data: getTag(curReq.addr)});
  133. dataArrays[i].req = Valid(DataReq {write: True, addr: getIndex(curReq.addr), data: data});
  134. state <= Ready;
  135. lru[getIndex(curReq.addr)] <= ~i;
  136. end
  137.  
  138. endrule
  139.  
  140. method Maybe#(Word) data;
  141. // This method should return a Valid output in only two cases:
  142. // 1. On a load hit (we're in the Lookup state, there's a hit, and
  143. // curReq.op == Ld).
  144. // 2. On a fill for a load request (we're in the Fill state,
  145. // mainMem.data is valid, and curReq.op == Ld).
  146. // In all other cases, the output should be Invalid
  147. //
  148.  
  149. //TODO Your code here
  150. let status0 = fromMaybe(?, statusArrays[0].data);
  151. let status1 = fromMaybe(?, statusArrays[1].data);
  152. let tag0 = fromMaybe(?, tagArrays[0].data);
  153. let tag1 = fromMaybe(?, tagArrays[1].data);
  154.  
  155. if (state == Fill && curReq.op == Ld && isValid(mainMem.data)) begin
  156. let line = fromMaybe(?, mainMem.data);
  157. return Valid(line[getWordOffset(curReq.addr)]);
  158. end
  159. else if (state == Lookup && curReq.op == Ld) begin
  160. if (status0 != Invalid && tag0 == getTag(curReq.addr)) begin
  161. let line = fromMaybe(?, dataArrays[0].data);
  162. return Valid(line[getWordOffset(curReq.addr)]);
  163. end
  164. else if (status1 != Invalid && tag1 == getTag(curReq.addr)) begin
  165. let line = fromMaybe(?, dataArrays[1].data);
  166. return Valid(line[getWordOffset(curReq.addr)]);
  167. end
  168. else return Invalid;
  169. end
  170. else return Invalid;
  171. endmethod
  172. method Bit#(32) getHits = hits;
  173. method Bit#(32) getMisses = misses;
  174. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement