ruby: declare all protocol message buffers as parameters
authorNilay Vaish <nilay@cs.wisc.edu>
Sat, 5 Sep 2015 14:34:24 +0000 (09:34 -0500)
committerNilay Vaish <nilay@cs.wisc.edu>
Sat, 5 Sep 2015 14:34:24 +0000 (09:34 -0500)
MessageBuffer is a SimObject now.  There were protocols that still declared
some of the message buffers are variables of the controller, but not as input
parameters.  Special handling was required for these variables in the SLICC
compiler.  This patch changes this.  Now all message buffers are declared as
input parameters.

19 files changed:
src/mem/protocol/MESI_Three_Level-L0cache.sm
src/mem/protocol/MESI_Two_Level-L1cache.sm
src/mem/protocol/MESI_Two_Level-dir.sm
src/mem/protocol/MESI_Two_Level-dma.sm
src/mem/protocol/MI_example-cache.sm
src/mem/protocol/MI_example-dir.sm
src/mem/protocol/MI_example-dma.sm
src/mem/protocol/MOESI_CMP_directory-L1cache.sm
src/mem/protocol/MOESI_CMP_directory-L2cache.sm
src/mem/protocol/MOESI_CMP_directory-dir.sm
src/mem/protocol/MOESI_CMP_directory-dma.sm
src/mem/protocol/MOESI_CMP_token-L1cache.sm
src/mem/protocol/MOESI_CMP_token-dir.sm
src/mem/protocol/MOESI_CMP_token-dma.sm
src/mem/protocol/MOESI_hammer-cache.sm
src/mem/protocol/MOESI_hammer-dir.sm
src/mem/protocol/MOESI_hammer-dma.sm
src/mem/protocol/Network_test-cache.sm
src/mem/slicc/symbols/StateMachine.py

index 8e44766ea052c352426b3fc7e50d4ea6b56a99f7..4a0766ce82ee33d0cf9c8940d51754dae07cb231 100644 (file)
@@ -39,10 +39,10 @@ machine(L0Cache, "MESI Directory L0 Cache")
 
    // To this node's L0 cache FROM the network
    MessageBuffer * bufferFromL1, network="From";
-{
-  // Message queue between this controller and the processor
-  MessageBuffer mandatoryQueue;
 
+   // Message queue between this controller and the processor
+   MessageBuffer * mandatoryQueue;
+{
   // STATES
   state_declaration(State, desc="Cache states", default="L0Cache_State_I") {
     // Base states
index 184f735c7dc4526dee53105fbcfcdfb6fca8b36a..8033e5983d2f3d66400a35782609ce636d5b0670 100644 (file)
@@ -61,10 +61,13 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
    // a L2 bank -> this L1
    MessageBuffer * responseToL1Cache, network="From", virtual_network="1",
         vnet_type="response";
-{
+
   // Request Buffer for prefetches
-  MessageBuffer optionalQueue;
+  MessageBuffer optionalQueue;
 
+  // Buffer for requests generated by the processor core.
+  MessageBuffer * mandatoryQueue;
+{
   // STATES
   state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
     // Base states
@@ -151,8 +154,6 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
 
   TBETable TBEs, template="<L1Cache_TBE>", constructor="m_number_of_TBEs";
 
-  MessageBuffer mandatoryQueue;
-
   int l2_select_low_bit, default="RubySystem::getBlockSizeBits()";
 
   void set_cache_entry(AbstractCacheEntry a);
index 22aabee4ea27a21b905ca63db66f2c5ab3bf5d92..7484d001c594d8c070e1e8a2bf595fd4d3db9c0c 100644 (file)
@@ -37,6 +37,8 @@ machine(Directory, "MESI Two Level directory protocol")
         vnet_type="response";
    MessageBuffer * responseFromDir, network="To", virtual_network="1",
         vnet_type="response";
+
+   MessageBuffer * responseFromMemory;
 {
   // STATES
   state_declaration(State, desc="Directory states", default="Directory_State_I") {
@@ -182,8 +184,6 @@ machine(Directory, "MESI Two Level directory protocol")
       (type == CoherenceRequestType:GETX);
   }
 
-  MessageBuffer responseFromMemory;
-
   // ** OUT_PORTS **
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
 
index 0caff177d8fc791c986a1c689b0f5247e393f653..cbd32cd44fefa141cf317a75b8bd0eda892b78f0 100644 (file)
@@ -35,6 +35,7 @@ machine(DMA, "DMA Controller")
         vnet_type="response";
   MessageBuffer * requestToDir, network="To", virtual_network="0",
         vnet_type="request";
+  MessageBuffer * mandatoryQueue;
 {
   state_declaration(State, desc="DMA states", default="DMA_State_READY") {
     READY, AccessPermission:Invalid, desc="Ready to accept a new request";
@@ -49,7 +50,6 @@ machine(DMA, "DMA Controller")
     Ack,          desc="DMA write to memory completed";
   }
 
-  MessageBuffer mandatoryQueue;
   State cur_state;
 
   State getState(Addr addr) {
index 3380cd7e6476210aa8bd7cb33a9989a83db02f75..f3b1600f913c0013fa9007ba3604759d09bacb9b 100644 (file)
@@ -44,6 +44,8 @@ machine(L1Cache, "MI Example L1 Cache")
             vnet_type="forward";
       MessageBuffer * responseToCache, network="From", virtual_network="4",
             vnet_type="response";
+
+      MessageBuffer * mandatoryQueue;
 {
   // STATES
   state_declaration(State, desc="Cache states") {
@@ -76,9 +78,6 @@ machine(L1Cache, "MI Example L1 Cache")
   }
 
   // STRUCTURE DEFINITIONS
-
-  MessageBuffer mandatoryQueue;
-
   // CacheEntry
   structure(Entry, desc="...", interface="AbstractCacheEntry") {
     State CacheState,        desc="cache state";
index a22691bda56b85a1c964fa4bfbe9283060869bf4..bb437390172da76f36fe7992577239cd8de56483 100644 (file)
@@ -43,6 +43,7 @@ machine(Directory, "Directory protocol")
             vnet_type="request";
       MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
             vnet_type="request";
+      MessageBuffer * responseFromMemory;
 {
   // STATES
   state_declaration(State, desc="Directory states", default="Directory_State_I") {
@@ -195,8 +196,6 @@ machine(Directory, "Directory protocol")
     return num_functional_writes;
   }
 
-  MessageBuffer responseFromMemory;
-
   // ** OUT_PORTS **
   out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
index 4ae546d64ae5c207dc6384cab571cfbce13dbefc..ce7b446305ab439fcdbecbba34516c75cdeb1fde 100644 (file)
@@ -35,6 +35,7 @@ machine(DMA, "DMA Controller")
             vnet_type="response";
       MessageBuffer * requestToDir, network="To", virtual_network="0",
             vnet_type="request";
+      MessageBuffer * mandatoryQueue;
 {
   state_declaration(State, desc="DMA states", default="DMA_State_READY") {
     READY, AccessPermission:Invalid, desc="Ready to accept a new request";
@@ -49,14 +50,14 @@ machine(DMA, "DMA Controller")
     Ack,          desc="DMA write to memory completed";
   }
 
-  MessageBuffer mandatoryQueue;
   State cur_state;
 
   State getState(Addr addr) {
     return cur_state;
   }
+
   void setState(Addr addr, State state) {
-  cur_state := state;
+    cur_state := state;
   }
 
   AccessPermission getAccessPermission(Addr addr) {
index 8a2eee1e29875562d446ab719a5970f58d7da070..6c5d3a20f07bf764658eea5f1aed3e0ee83572ce 100644 (file)
@@ -51,6 +51,10 @@ machine(L1Cache, "Directory protocol")
    // a L2 bank -> this L1
    MessageBuffer * responseToL1Cache, network="From", virtual_network="2",
         vnet_type="response";
+
+   MessageBuffer * triggerQueue;
+
+   MessageBuffer * mandatoryQueue;
 {
   // STATES
   state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
@@ -134,8 +138,6 @@ machine(L1Cache, "Directory protocol")
   void set_tbe(TBE b);
   void unset_tbe();
 
-  MessageBuffer mandatoryQueue, abstract_chip_ptr="true";
-
   TBETable TBEs, template="<L1Cache_TBE>", constructor="m_number_of_TBEs";
   TimerTable useTimerTable;
   int l2_select_low_bit, default="RubySystem::getBlockSizeBits()";
@@ -254,8 +256,6 @@ machine(L1Cache, "Directory protocol")
     }
   }
 
-  MessageBuffer triggerQueue;
-
   // ** OUT_PORTS **
 
   out_port(requestNetwork_out, RequestMsg, requestFromL1Cache);
index 38c6e9f9be1fc3315e2bfdebfd875f27bcd981ef..0b288709ef9218d456eae8903c30a651c46bf9c9 100644 (file)
@@ -48,6 +48,7 @@ machine(L2Cache, "Token protocol")
   MessageBuffer * responseToL2Cache, network="From", virtual_network="2",
         vnet_type="response";  // a local L1 || mod-directory -> this L2 bank
 
+  MessageBuffer * triggerQueue;
 {
   // STATES
   state_declaration(State, desc="L2 Cache states", default="L2Cache_State_I") {
@@ -565,8 +566,6 @@ machine(L2Cache, "Token protocol")
     return num_functional_writes;
   }
 
-  MessageBuffer triggerQueue;
-
   out_port(globalRequestNetwork_out, RequestMsg, GlobalRequestFromL2Cache);
   out_port(localRequestNetwork_out, RequestMsg, L1RequestFromL2Cache);
   out_port(responseNetwork_out, ResponseMsg, responseFromL2Cache);
index dcd37cc33ef17e8acb8d616a94a1cf7453932efc..6ee7cd2605db0705eb022bd716219e851a608997 100644 (file)
@@ -42,6 +42,7 @@ machine(Directory, "Directory protocol")
    MessageBuffer * responseFromDir, network="To", virtual_network="2",
         vnet_type="response";  // Dir -> mod-L2 bank
 
+   MessageBuffer * responseFromMemory;
 {
   // STATES
   state_declaration(State, desc="Directory states", default="Directory_State_I") {
@@ -220,8 +221,6 @@ machine(Directory, "Directory protocol")
     return false;
   }
 
-  MessageBuffer responseFromMemory;
-
   // ** OUT_PORTS **
   out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
index e9931f25baa97957e37f00120679ec5aef25d256..10fc94abe486878b09f329a2b61dd2474b56a8c3 100644 (file)
@@ -40,6 +40,8 @@ machine(DMA, "DMA Controller")
       MessageBuffer * respToDir, network="To", virtual_network="2",
             vnet_type="dmaresponse";
 
+      MessageBuffer * mandatoryQueue;
+      MessageBuffer * triggerQueue;
 {
   state_declaration(State, desc="DMA states", default="DMA_State_READY") {
     READY, AccessPermission:Invalid, desc="Ready to accept a new request";
@@ -69,8 +71,6 @@ machine(DMA, "DMA Controller")
     bool isPresent(Addr);
   }
 
-  MessageBuffer mandatoryQueue;
-  MessageBuffer triggerQueue;
   TBETable TBEs, template="<DMA_TBE>", constructor="m_number_of_TBEs";
   State cur_state;
 
index af6e4c0d5a7050f84a934d94319001150ffe3f18..c5a7cd940bba13df205b696a75a96bce48ac4792 100644 (file)
@@ -61,7 +61,6 @@ machine(L1Cache, "Token protocol")
    MessageBuffer * requestFromL1Cache, network="To", virtual_network="1",
         vnet_type="request";
  
    // To this node's L1 cache FROM the network
 
    // a L2 bank -> this L1
@@ -73,6 +72,7 @@ machine(L1Cache, "Token protocol")
    MessageBuffer * requestToL1Cache, network="From", virtual_network="1",
         vnet_type="request";
 
+   MessageBuffer * mandatoryQueue;
 {
   // STATES
   state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
@@ -194,8 +194,6 @@ machine(L1Cache, "Token protocol")
 
   TBETable L1_TBEs, template="<L1Cache_TBE>", constructor="m_number_of_TBEs";
 
-  MessageBuffer mandatoryQueue, abstract_chip_ptr="true";
-
   bool starving, default="false";
   int l2_select_low_bit, default="RubySystem::getBlockSizeBits()";
 
index fdef75181f25c4ae9b48dd0c76f881d2e61b2d96..ffef01eb07056d6b37fbb22eebb89a2bbb4ae9f1 100644 (file)
@@ -61,6 +61,7 @@ machine(Directory, "Token protocol")
    MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
         vnet_type="request";
 
+   MessageBuffer * responseFromMemory;
 {
   // STATES
   state_declaration(State, desc="Directory states", default="Directory_State_O") {
@@ -266,8 +267,6 @@ machine(Directory, "Token protocol")
     return num_functional_writes;
   }
 
-  MessageBuffer responseFromMemory;
-
   // ** OUT_PORTS **
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
   out_port(persistentNetwork_out, PersistentMsg, persistentFromDir);
index 56cfb201274a7c479bb7f7c0ebda5e597089fbe0..4bb80d4bafc145602d36733916fbd7f74e9b874f 100644 (file)
@@ -37,6 +37,7 @@ machine(DMA, "DMA Controller")
       MessageBuffer * reqToDirectory, network="To", virtual_network="0",
             vnet_type="request";
 
+      MessageBuffer * mandatoryQueue;
 {
   state_declaration(State, desc="DMA states", default="DMA_State_READY") {
     READY, AccessPermission:Invalid, desc="Ready to accept a new request";
@@ -51,14 +52,14 @@ machine(DMA, "DMA Controller")
     Ack,          desc="DMA write to memory completed";
   }
 
-  MessageBuffer mandatoryQueue;
   State cur_state;
 
   State getState(Addr addr) {
     return cur_state;
   }
+
   void setState(Addr addr, State state) {
-  cur_state := state;
+    cur_state := state;
   }
 
   AccessPermission getAccessPermission(Addr addr) {
index d5539e02139e5ed87a2974fae2ecb36d86c6c384..303bf178417c48580d723ac131a0bcf77905fa68 100644 (file)
@@ -56,6 +56,10 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
             vnet_type="forward";
       MessageBuffer * responseToCache, network="From", virtual_network="4",
             vnet_type="response";
+
+      MessageBuffer * mandatoryQueue;
+
+      MessageBuffer * triggerQueue;
 {
   // STATES
   state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
@@ -139,12 +143,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
     Block_Ack,                   desc="the directory is blocked and ready for the flush";
   }
 
-  // TYPES
-
   // STRUCTURE DEFINITIONS
-
-  MessageBuffer mandatoryQueue;
-
   // CacheEntry
   structure(Entry, desc="...", interface="AbstractCacheEntry") {
     State CacheState,        desc="cache state";
@@ -320,10 +319,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
     return cache_entry.AtomicAccessed;
   }
 
-  MessageBuffer triggerQueue;
-
   // ** OUT_PORTS **
-
   out_port(requestNetwork_out, RequestMsg, requestFromCache);
   out_port(responseNetwork_out, ResponseMsg, responseFromCache);
   out_port(unblockNetwork_out, ResponseMsg, unblockFromCache);
index 27794a3bda8b1cbf42e566b3d07a8cf677ad3383..4948a8108822d3504d11694d126df40f2eede5ce 100644 (file)
@@ -64,6 +64,9 @@ machine(Directory, "AMD Hammer-like protocol")
 
       MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
             vnet_type="request";
+
+      MessageBuffer * triggerQueue;
+      MessageBuffer * responseFromMemory;
 {
   // STATES
   state_declaration(State, desc="Directory states", default="Directory_State_E") {
@@ -300,9 +303,6 @@ machine(Directory, "AMD Hammer-like protocol")
     }
   }
 
-  MessageBuffer triggerQueue;
-  MessageBuffer responseFromMemory;
-
   // ** OUT_PORTS **
   out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
   out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
index 72125d157ed32d4ad970be8adc9c299f8f6d0cba..4691e2490b647f6f2e9d1c1000fb19f634e0bdd0 100644 (file)
@@ -35,6 +35,7 @@ machine(DMA, "DMA Controller")
             vnet_type="response";
       MessageBuffer * requestToDir, network="To", virtual_network="0",
             vnet_type="request";
+      MessageBuffer * mandatoryQueue;
 {
   state_declaration(State, desc="DMA states", default="DMA_State_READY") {
     READY, AccessPermission:Invalid, desc="Ready to accept a new request";
@@ -49,7 +50,6 @@ machine(DMA, "DMA Controller")
     Ack,          desc="DMA write to memory completed";
   }
 
-  MessageBuffer mandatoryQueue;
   State cur_state;
 
   State getState(Addr addr) {
index 43331d8f2ec7d66beaf6146e7eec796092e0b665..82829a6eaaf5900c2d3312ba2c2088e400a41b9f 100644 (file)
@@ -42,6 +42,8 @@ machine(L1Cache, "Network_test L1 Cache")
             vnet_type = "forward";
       MessageBuffer * responseFromCache, network="To", virtual_network="2",
             vnet_type = "response";
+
+      MessageBuffer * mandatoryQueue;
 {
   // STATES
   state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
@@ -57,11 +59,8 @@ machine(L1Cache, "Network_test L1 Cache")
   }
 
   // STRUCTURE DEFINITIONS
-
-  MessageBuffer mandatoryQueue;
   DataBlock dummyData;
 
-
   // CacheEntry
   structure(Entry, desc="...", interface="AbstractCacheEntry") {
     State CacheState,        desc="cache state";
index e22c53fe842ffa6c38310af8d40d0636d99b93f4..3e6a93fa7ea56cf4a64e8c64a33d14ed7cf78205 100644 (file)
@@ -43,6 +43,7 @@ python_class_map = {
                     "Sequencer": "RubySequencer",
                     "DirectoryMemory": "RubyDirectoryMemory",
                     "MemoryControl": "MemoryControl",
+                    "MessageBuffer": "MessageBuffer",
                     "DMASequencer": "DMASequencer",
                     "Prefetcher":"Prefetcher",
                     "Cycles":"Cycles",
@@ -234,11 +235,7 @@ class $py_ident(RubyController):
             if param.rvalue is not None:
                 dflt_str = str(param.rvalue.inline()) + ', '
 
-            if param.type_ast.type.c_ident == "MessageBuffer":
-                # The MessageBuffer MUST be instantiated in the protocol config
-                code('${{param.ident}} = Param.MessageBuffer("")')
-
-            elif python_class_map.has_key(param.type_ast.type.c_ident):
+            if python_class_map.has_key(param.type_ast.type.c_ident):
                 python_type = python_class_map[param.type_ast.type.c_ident]
                 code('${{param.ident}} = Param.${{python_type}}(${dflt_str}"")')
 
@@ -247,12 +244,6 @@ class $py_ident(RubyController):
                            "type: '%s'. Please update the python_class_map " \
                            "in StateMachine.py", param.type_ast.type.c_ident)
 
-        # Also add any MessageBuffers declared internally to the controller
-        # Note: This includes mandatory and memory queues
-        for var in self.objects:
-            if var.type.c_ident == "MessageBuffer":
-                code('${{var.ident}} = Param.MessageBuffer("")')
-
         code.dedent()
         code.write(path, '%s.py' % py_ident)
 
@@ -303,8 +294,8 @@ class $c_ident : public AbstractController
     static int getNumControllers();
     void init();
 
-    MessageBuffergetMandatoryQueue() const;
-    MessageBuffergetMemoryQueue() const;
+    MessageBuffer *getMandatoryQueue() const;
+    MessageBuffer *getMemoryQueue() const;
     void initNetQueues();
 
     void print(std::ostream& out) const;
@@ -539,17 +530,6 @@ $c_ident::$c_ident(const Params *p)
             if re.compile("sequencer").search(param.ident):
                 code('m_${{param.ident}}_ptr->setController(this);')
 
-        for var in self.objects:
-            # Some MessageBuffers (e.g. mandatory and memory queues) are
-            # instantiated internally to StateMachines but exposed to
-            # components outside SLICC, so make sure to set up this
-            # controller as their receivers
-            if var.type.c_ident == "MessageBuffer":
-                code('''
-m_${{var.ident}}_ptr = p->${{var.ident}};
-m_${{var.ident}}_ptr->setReceiver(this);
-''')
-
         code('''
 
 for (int state = 0; state < ${ident}_State_NUM; state++) {
@@ -581,10 +561,9 @@ $c_ident::initNetQueues()
         vnet_dir_set = set()
 
         for var in self.config_parameters:
+            vid = "m_%s_ptr" % var.ident
             if "network" in var:
                 vtype = var.type_ast.type
-                vid = "m_%s_ptr" % var.ident
-
                 code('assert($vid != NULL);')
 
                 # Network port object
@@ -611,6 +590,14 @@ m_net_ptr->set${network}NetQueue(m_version + base, $vid->getOrdered(), $vnet,
                 if "rank" in var:
                     code('$vid->setPriority(${{var["rank"]}})')
 
+            else:
+                if var.type_ast.type.c_ident == "MessageBuffer":
+                    code('$vid->setReceiver(this);')
+                if var.ident.find("triggerQueue") >= 0:
+                    code('$vid->setSender(this);')
+                elif var.ident.find("optionalQueue") >= 0:
+                    code('$vid->setSender(this);')
+
         code.dedent()
         code('''
 }
@@ -635,14 +622,13 @@ $c_ident::init()
                         code('(*$vid) = ${{var["default"]}};')
                 else:
                     # Normal Object
-                    if var.type.c_ident != "MessageBuffer":
-                        th = var.get("template", "")
-                        expr = "%s  = new %s%s" % (vid, vtype.c_ident, th)
-                        args = ""
-                        if "non_obj" not in vtype and not vtype.isEnumeration:
-                            args = var.get("constructor", "")
-                        code('$expr($args);')
+                    th = var.get("template", "")
+                    expr = "%s  = new %s%s" % (vid, vtype.c_ident, th)
+                    args = ""
+                    if "non_obj" not in vtype and not vtype.isEnumeration:
+                        args = var.get("constructor", "")
 
+                    code('$expr($args);')
                     code('assert($vid != NULL);')
 
                     if "default" in var:
@@ -651,19 +637,8 @@ $c_ident::init()
                         comment = "Type %s default" % vtype.ident
                         code('*$vid = ${{vtype["default"]}}; // $comment')
 
-                    # Set Priority
-                    if vtype.isBuffer and "rank" in var:
-                        code('$vid->setPriority(${{var["rank"]}});')
-
-                    # Set sender and receiver for trigger queue
-                    if var.ident.find("triggerQueue") >= 0:
-                        code('$vid->setSender(this);')
-                        code('$vid->setReceiver(this);')
-                    elif vtype.c_ident == "TimerTable":
+                    if vtype.c_ident == "TimerTable":
                         code('$vid->setClockObj(this);')
-                    elif var.ident.find("optionalQueue") >= 0:
-                        code('$vid->setSender(this);')
-                        code('$vid->setReceiver(this);')
 
         # Set the prefetchers
         code()