ruby: slicc: have a static MachineType
[gem5.git] / src / mem / protocol / MI_example-cache.sm
index 9b0c18bc82e7618f464b07c55eb8f19725f38c7d..0e3e6e1eb4b1c3f5ec3994e480b57906dc413160 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-machine(L1Cache, "MI Example L1 Cache")
-: Sequencer * sequencer;
-  CacheMemory * cacheMemory;
-  Cycles cache_response_latency := 12;
-  Cycles issue_latency := 2;
-  bool send_evictions;
+machine(MachineType:L1Cache, "MI Example L1 Cache")
+    : Sequencer * sequencer;
+      CacheMemory * cacheMemory;
+      Cycles cache_response_latency := 12;
+      Cycles issue_latency := 2;
+      bool send_evictions;
+
+      // NETWORK BUFFERS
+      MessageBuffer * requestFromCache, network="To", virtual_network="2",
+            vnet_type="request";
+      MessageBuffer * responseFromCache, network="To", virtual_network="4",
+            vnet_type="response";
+
+      MessageBuffer * forwardToCache, network="From", virtual_network="3",
+            vnet_type="forward";
+      MessageBuffer * responseToCache, network="From", virtual_network="4",
+            vnet_type="response";
+
+      MessageBuffer * mandatoryQueue;
 {
-
-  // NETWORK BUFFERS
-  MessageBuffer requestFromCache, network="To", virtual_network="2", ordered="true", vnet_type="request";
-  MessageBuffer responseFromCache, network="To", virtual_network="4", ordered="true", vnet_type="response";
-
-  MessageBuffer forwardToCache, network="From", virtual_network="3", ordered="true", vnet_type="forward";
-  MessageBuffer responseToCache, network="From", virtual_network="4", ordered="true", vnet_type="response";
-
   // STATES
   state_declaration(State, desc="Cache states") {
     I, AccessPermission:Invalid, desc="Not Present/Invalid";
@@ -73,9 +78,6 @@ machine(L1Cache, "MI Example L1 Cache")
   }
 
   // STRUCTURE DEFINITIONS
-
-  MessageBuffer mandatoryQueue, ordered="false";
-
   // CacheEntry
   structure(Entry, desc="...", interface="AbstractCacheEntry") {
     State CacheState,        desc="cache state";
@@ -90,10 +92,10 @@ machine(L1Cache, "MI Example L1 Cache")
   }
 
   structure(TBETable, external="yes") {
-    TBE lookup(Address);
-    void allocate(Address);
-    void deallocate(Address);
-    bool isPresent(Address);
+    TBE lookup(Addr);
+    void allocate(Addr);
+    void deallocate(Addr);
+    bool isPresent(Addr);
   }
 
 
@@ -101,13 +103,15 @@ machine(L1Cache, "MI Example L1 Cache")
   TBETable TBEs, template="<L1Cache_TBE>", constructor="m_number_of_TBEs";
 
   // PROTOTYPES
+  Tick clockEdge();
+  Cycles ticksToCycles(Tick t);
   void set_cache_entry(AbstractCacheEntry a);
   void unset_cache_entry();
   void set_tbe(TBE b);
   void unset_tbe();
   void profileMsgDelay(int virtualNetworkType, Cycles b);
 
-  Entry getCacheEntry(Address address), return_by_pointer="yes" {
+  Entry getCacheEntry(Addr address), return_by_pointer="yes" {
     return static_cast(Entry, "pointer", cacheMemory.lookup(address));
   }
 
@@ -124,7 +128,7 @@ machine(L1Cache, "MI Example L1 Cache")
     }
   }
 
-  State getState(TBE tbe, Entry cache_entry, Address addr) {
+  State getState(TBE tbe, Entry cache_entry, Addr addr) {
 
     if (is_valid(tbe)) {
       return tbe.TBEState;
@@ -137,7 +141,7 @@ machine(L1Cache, "MI Example L1 Cache")
     }
   }
 
-  void setState(TBE tbe, Entry cache_entry, Address addr, State state) {
+  void setState(TBE tbe, Entry cache_entry, Addr addr, State state) {
 
     if (is_valid(tbe)) {
       tbe.TBEState := state;
@@ -148,7 +152,7 @@ machine(L1Cache, "MI Example L1 Cache")
     }
   }
 
-  AccessPermission getAccessPermission(Address addr) {
+  AccessPermission getAccessPermission(Addr addr) {
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
       return L1Cache_State_to_permission(tbe.TBEState);
@@ -162,19 +166,34 @@ machine(L1Cache, "MI Example L1 Cache")
     return AccessPermission:NotPresent;
   }
 
-  void setAccessPermission(Entry cache_entry, Address addr, State state) {
+  void setAccessPermission(Entry cache_entry, Addr addr, State state) {
     if (is_valid(cache_entry)) {
       cache_entry.changePermission(L1Cache_State_to_permission(state));
     }
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+  void functionalRead(Addr addr, Packet *pkt) {
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      testAndRead(addr, tbe.DataBlk, pkt);
+    } else {
+      testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
+    }
+  }
+
+  int functionalWrite(Addr addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-      return tbe.DataBlk;
+      num_functional_writes := num_functional_writes +
+        testAndWrite(addr, tbe.DataBlk, pkt);
+      return num_functional_writes;
     }
 
-    return getCacheEntry(addr).DataBlk;
+    num_functional_writes := num_functional_writes +
+        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
+    return num_functional_writes;
   }
 
   // NETWORK PORTS
@@ -183,23 +202,23 @@ machine(L1Cache, "MI Example L1 Cache")
   out_port(responseNetwork_out, ResponseMsg, responseFromCache);
 
   in_port(forwardRequestNetwork_in, RequestMsg, forwardToCache) {
-    if (forwardRequestNetwork_in.isReady()) {
-      peek(forwardRequestNetwork_in, RequestMsg, block_on="Addr") {
+    if (forwardRequestNetwork_in.isReady(clockEdge())) {
+      peek(forwardRequestNetwork_in, RequestMsg, block_on="addr") {
 
-        Entry cache_entry := getCacheEntry(in_msg.Addr);
-        TBE tbe := TBEs[in_msg.Addr];
+        Entry cache_entry := getCacheEntry(in_msg.addr);
+        TBE tbe := TBEs[in_msg.addr];
 
         if (in_msg.Type == CoherenceRequestType:GETX) {
-          trigger(Event:Fwd_GETX, in_msg.Addr, cache_entry, tbe);
+          trigger(Event:Fwd_GETX, in_msg.addr, cache_entry, tbe);
         }
         else if (in_msg.Type == CoherenceRequestType:WB_ACK) {
-          trigger(Event:Writeback_Ack, in_msg.Addr, cache_entry, tbe);
+          trigger(Event:Writeback_Ack, in_msg.addr, cache_entry, tbe);
         }
         else if (in_msg.Type == CoherenceRequestType:WB_NACK) {
-          trigger(Event:Writeback_Nack, in_msg.Addr, cache_entry, tbe);
+          trigger(Event:Writeback_Nack, in_msg.addr, cache_entry, tbe);
         }
         else if (in_msg.Type == CoherenceRequestType:INV) {
-          trigger(Event:Inv, in_msg.Addr, cache_entry, tbe);
+          trigger(Event:Inv, in_msg.addr, cache_entry, tbe);
         }
         else {
           error("Unexpected message");
@@ -209,14 +228,14 @@ machine(L1Cache, "MI Example L1 Cache")
   }
 
   in_port(responseNetwork_in, ResponseMsg, responseToCache) {
-    if (responseNetwork_in.isReady()) {
-      peek(responseNetwork_in, ResponseMsg, block_on="Addr") {
+    if (responseNetwork_in.isReady(clockEdge())) {
+      peek(responseNetwork_in, ResponseMsg, block_on="addr") {
 
-        Entry cache_entry := getCacheEntry(in_msg.Addr);
-        TBE tbe := TBEs[in_msg.Addr];
+        Entry cache_entry := getCacheEntry(in_msg.addr);
+        TBE tbe := TBEs[in_msg.addr];
 
         if (in_msg.Type == CoherenceResponseType:DATA) {
-          trigger(Event:Data, in_msg.Addr, cache_entry, tbe);
+          trigger(Event:Data, in_msg.addr, cache_entry, tbe);
         }
         else {
           error("Unexpected message");
@@ -227,7 +246,7 @@ machine(L1Cache, "MI Example L1 Cache")
 
     // Mandatory Queue
   in_port(mandatoryQueue_in, RubyRequest, mandatoryQueue, desc="...") {
-    if (mandatoryQueue_in.isReady()) {
+    if (mandatoryQueue_in.isReady(clockEdge())) {
       peek(mandatoryQueue_in, RubyRequest, block_on="LineAddress") {
 
         Entry cache_entry := getCacheEntry(in_msg.LineAddress);
@@ -250,7 +269,7 @@ machine(L1Cache, "MI Example L1 Cache")
 
   action(a_issueRequest, "a", desc="Issue a request") {
     enqueue(requestNetwork_out, RequestMsg, issue_latency) {
-    out_msg.Addr := address;
+    out_msg.addr := address;
       out_msg.Type := CoherenceRequestType:GETX;
       out_msg.Requestor := machineID;
       out_msg.Destination.add(map_Address_to_Directory(address));
@@ -261,7 +280,7 @@ machine(L1Cache, "MI Example L1 Cache")
   action(b_issuePUT, "b", desc="Issue a PUT request") {
     enqueue(requestNetwork_out, RequestMsg, issue_latency) {
       assert(is_valid(cache_entry));
-      out_msg.Addr := address;
+      out_msg.addr := address;
       out_msg.Type := CoherenceRequestType:PUTX;
       out_msg.Requestor := machineID;
       out_msg.Destination.add(map_Address_to_Directory(address));
@@ -274,7 +293,7 @@ machine(L1Cache, "MI Example L1 Cache")
     peek(forwardRequestNetwork_in, RequestMsg) {
       enqueue(responseNetwork_out, ResponseMsg, cache_response_latency) {
         assert(is_valid(cache_entry));
-        out_msg.Addr := address;
+        out_msg.addr := address;
         out_msg.Type := CoherenceResponseType:DATA;
         out_msg.Sender := machineID;
         out_msg.Destination.add(in_msg.Requestor);
@@ -288,7 +307,7 @@ machine(L1Cache, "MI Example L1 Cache")
     peek(forwardRequestNetwork_in, RequestMsg) {
       enqueue(responseNetwork_out, ResponseMsg, cache_response_latency) {
         assert(is_valid(tbe));
-        out_msg.Addr := address;
+        out_msg.addr := address;
         out_msg.Type := CoherenceResponseType:DATA;
         out_msg.Sender := machineID;
         out_msg.Destination.add(in_msg.Requestor);
@@ -313,15 +332,17 @@ machine(L1Cache, "MI Example L1 Cache")
   }
 
   action(m_popMandatoryQueue, "m", desc="Pop the mandatory request queue") {
-    mandatoryQueue_in.dequeue();
+    mandatoryQueue_in.dequeue(clockEdge());
   }
 
   action(n_popResponseQueue, "n", desc="Pop the response queue") {
-    profileMsgDelay(1, responseNetwork_in.dequeue());
+    Tick delay := responseNetwork_in.dequeue(clockEdge());
+    profileMsgDelay(1, ticksToCycles(delay));
   }
 
   action(o_popForwardedRequestQueue, "o", desc="Pop the forwarded request queue") {
-    profileMsgDelay(2, forwardRequestNetwork_in.dequeue());
+    Tick delay := forwardRequestNetwork_in.dequeue(clockEdge());
+    profileMsgDelay(2, ticksToCycles(delay));
   }
 
   action(p_profileMiss, "pi", desc="Profile cache miss") {
@@ -335,6 +356,7 @@ machine(L1Cache, "MI Example L1 Cache")
   action(r_load_hit, "r", desc="Notify sequencer the load completed.") {
     assert(is_valid(cache_entry));
     DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
+    cacheMemory.setMRU(cache_entry);
     sequencer.readCallback(address, cache_entry.DataBlk, false);
   }
 
@@ -342,6 +364,7 @@ machine(L1Cache, "MI Example L1 Cache")
     peek(responseNetwork_in, ResponseMsg) {
       assert(is_valid(cache_entry));
       DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
+      cacheMemory.setMRU(cache_entry);
       sequencer.readCallback(address, cache_entry.DataBlk, true,
                              machineIDToMachineType(in_msg.Sender));
     }
@@ -350,6 +373,7 @@ machine(L1Cache, "MI Example L1 Cache")
   action(s_store_hit, "s", desc="Notify sequencer that store completed.") {
     assert(is_valid(cache_entry));
     DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
+    cacheMemory.setMRU(cache_entry);
     sequencer.writeCallback(address, cache_entry.DataBlk, false);
   }
 
@@ -357,6 +381,7 @@ machine(L1Cache, "MI Example L1 Cache")
     peek(responseNetwork_in, ResponseMsg) {
       assert(is_valid(cache_entry));
       DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk);
+      cacheMemory.setMRU(cache_entry);
       sequencer.writeCallback(address, cache_entry.DataBlk, true,
                               machineIDToMachineType(in_msg.Sender));
     }
@@ -371,7 +396,7 @@ machine(L1Cache, "MI Example L1 Cache")
 
   action(forward_eviction_to_cpu, "\cc", desc="sends eviction information to the processor") {
     if (send_evictions) {
-      DPRINTF(RubySlicc, "Sending invalidation for %s to the CPU\n", address);
+      DPRINTF(RubySlicc, "Sending invalidation for %#x to the CPU\n", address);
       sequencer.evictionCallback(address);
     }
   }