SHARE
TWEET

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 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
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top