slicc: added MOESI_CMP_directory, DMA SequencerMsg, parameterized controllers
authorDerek Hower <drh5@cs.wisc.edu>
Tue, 4 Aug 2009 17:52:52 +0000 (12:52 -0500)
committerDerek Hower <drh5@cs.wisc.edu>
Tue, 4 Aug 2009 17:52:52 +0000 (12:52 -0500)
This changeset contains a lot of different changes that are too
mingled to separate.  They are:

1.  Added MOESI_CMP_directory

I made the changes necessary to bring back MOESI_CMP_directory,
including adding a DMA controller.  I got rid of MOESI_CMP_directory_m
and made MOESI_CMP_directory use a memory controller. Added a new
configuration for two level protocols in general, and
MOESI_CMP_directory in particular.

2.  DMA Sequencer uses a generic SequencerMsg

I will eventually make the cache Sequencer use this type as well.  It
doesn't contain an offset field, just a physical address and a length.
MI_example has been updated to deal with this.

3. Parameterized Controllers

SLICC controllers can now take custom parameters to use for mapping,
latencies, etc.  Currently, only int parameters are supported.

47 files changed:
src/mem/gems_common/Map.hh
src/mem/protocol/MI_example-cache.sm
src/mem/protocol/MI_example-dir.sm
src/mem/protocol/MI_example-dma.sm
src/mem/protocol/MI_example-msg.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 [new file with mode: 0644]
src/mem/protocol/MOESI_CMP_directory-msg.sm
src/mem/protocol/MOESI_CMP_directory.slicc
src/mem/protocol/MOESI_CMP_directory_m-dir.sm [deleted file]
src/mem/protocol/MOESI_CMP_directory_m.slicc [deleted file]
src/mem/protocol/RubySlicc_ComponentMapping.sm
src/mem/protocol/RubySlicc_Exports.sm
src/mem/protocol/RubySlicc_Profiler.sm
src/mem/protocol/RubySlicc_Types.sm
src/mem/protocol/RubySlicc_Util.sm
src/mem/ruby/config/MI_example-homogeneous.rb
src/mem/ruby/config/MI_example.rb [new file with mode: 0644]
src/mem/ruby/config/MOESI_CMP_directory.rb [new file with mode: 0644]
src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb [new file with mode: 0644]
src/mem/ruby/config/cfg.rb
src/mem/ruby/config/defaults.rb
src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh
src/mem/ruby/slicc_interface/RubySlicc_Util.hh
src/mem/ruby/system/DMASequencer.cc
src/mem/ruby/system/DirectoryMemory.cc
src/mem/ruby/system/DirectoryMemory.hh
src/mem/ruby/system/PerfectCacheMemory.hh
src/mem/ruby/system/System.hh
src/mem/ruby/system/TimerTable.cc
src/mem/ruby/system/TimerTable.hh
src/mem/slicc/ast/AST.hh
src/mem/slicc/ast/ActionDeclAST.cc
src/mem/slicc/ast/ActionDeclAST.hh
src/mem/slicc/ast/EnqueueStatementAST.cc
src/mem/slicc/ast/FormalParamAST.cc
src/mem/slicc/ast/FormalParamAST.hh
src/mem/slicc/ast/FuncDeclAST.cc
src/mem/slicc/ast/FuncDeclAST.hh
src/mem/slicc/ast/MachineAST.cc
src/mem/slicc/ast/MachineAST.hh
src/mem/slicc/parser/parser.py
src/mem/slicc/parser/parser.yy
src/mem/slicc/symbols/StateMachine.cc
src/mem/slicc/symbols/StateMachine.hh

index 5128a0feecb756817fbcda5a56ae7a9241ea071c..6e581d3758ba344e00485ff15723f630e34978ba 100644 (file)
@@ -93,6 +93,8 @@ bool Map<KEY_TYPE, VALUE_TYPE>::exist(const KEY_TYPE& key) const
 template <class KEY_TYPE, class VALUE_TYPE>
 VALUE_TYPE& Map<KEY_TYPE, VALUE_TYPE>::lookup(const KEY_TYPE& key) const
 {
+  if (!exist(key))
+    cerr << *this << " is looking for " << key << endl;
   assert(exist(key));
   return m_map[key];
 }
index 16a158f0d13db69ab03b79606f25715b2b8ce846..915a0eb999114ff891faffd1aa512ab02baf2db5 100644 (file)
@@ -1,5 +1,8 @@
 
-machine(L1Cache, "MI Example L1 Cache"): LATENCY_CACHE_RESPONSE_LATENCY  LATENCY_ISSUE_LATENCY {
+machine(L1Cache, "MI Example L1 Cache")
+: int cache_response_latency,
+  int issue_latency
+{
 
   // NETWORK BUFFERS
   MessageBuffer requestFromCache, network="To", virtual_network="0", ordered="true";
@@ -188,8 +191,8 @@ machine(L1Cache, "MI Example L1 Cache"): LATENCY_CACHE_RESPONSE_LATENCY  LATENCY
   // ACTIONS
 
   action(a_issueRequest, "a", desc="Issue a request") {
-    enqueue(requestNetwork_out, RequestMsg, latency="ISSUE_LATENCY") {
-      out_msg.Address := address;
+    enqueue(requestNetwork_out, RequestMsg, latency=issue_latency) {
+    out_msg.Address := address;
       out_msg.Type := CoherenceRequestType:GETX;
       out_msg.Requestor := machineID;
       out_msg.Destination.add(map_Address_to_Directory(address));
@@ -198,7 +201,7 @@ machine(L1Cache, "MI Example L1 Cache"): LATENCY_CACHE_RESPONSE_LATENCY  LATENCY
   }
 
   action(b_issuePUT, "b", desc="Issue a PUT request") {
-    enqueue(requestNetwork_out, RequestMsg, latency="ISSUE_LATENCY") {
+    enqueue(requestNetwork_out, RequestMsg, latency=issue_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceRequestType:PUTX;
       out_msg.Requestor := machineID;
@@ -211,7 +214,7 @@ machine(L1Cache, "MI Example L1 Cache"): LATENCY_CACHE_RESPONSE_LATENCY  LATENCY
 
   action(e_sendData, "e", desc="Send data from cache to requestor") {
     peek(forwardRequestNetwork_in, RequestMsg) {
-      enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_RESPONSE_LATENCY") {
+      enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceResponseType:DATA;
         out_msg.Sender := machineID;
@@ -224,7 +227,7 @@ machine(L1Cache, "MI Example L1 Cache"): LATENCY_CACHE_RESPONSE_LATENCY  LATENCY
 
   action(ee_sendDataFromTBE, "\e", desc="Send data from TBE to requestor") {
     peek(forwardRequestNetwork_in, RequestMsg) {
-      enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_RESPONSE_LATENCY") {
+      enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceResponseType:DATA;
         out_msg.Sender := machineID;
index fa8903d47df19eb7425e3a0dde1201c108adbe36..c764634ecd939432f29b80e1877393761995b5ab 100644 (file)
@@ -1,5 +1,7 @@
 
-machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_DIRECTORY_LATENCY LATENCY_MEMORY_LATENCY {
+machine(Directory, "Directory protocol") 
+: int directory_latency
+{
 
   MessageBuffer forwardFromDir, network="To", virtual_network="2", ordered="false";
   MessageBuffer responseFromDir, network="To", virtual_network="1", ordered="false";
@@ -65,9 +67,9 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   // TBE entries for DMA requests
   structure(TBE, desc="TBE entries for outstanding DMA requests") {
+    Address PhysicalAddress, desc="physical address";
     State TBEState,        desc="Transient State";
     DataBlock DataBlk,     desc="Data to be written (DMA write only)";
-    int Offset,            desc="...";
     int Len,               desc="...";
   }
 
@@ -180,7 +182,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
+      enqueue(forwardNetwork_out, RequestMsg, latency=directory_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceRequestType:WB_ACK;
         out_msg.Requestor := in_msg.Requestor;
@@ -192,7 +194,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(l_sendWriteBackAck, "la", desc="Send writeback ack to requestor") {
     peek(memQueue_in, MemoryMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, latency="TO_MEM_CTRL_LATENCY") {
+      enqueue(forwardNetwork_out, RequestMsg, latency="1") {
         out_msg.Address := address;
         out_msg.Type := CoherenceRequestType:WB_ACK;
         out_msg.Requestor := in_msg.OriginalRequestorMachId;
@@ -204,7 +206,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(b_sendWriteBackNack, "b", desc="Send writeback nack to requestor") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
+      enqueue(forwardNetwork_out, RequestMsg, latency=directory_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceRequestType:WB_NACK;
         out_msg.Requestor := in_msg.Requestor;
@@ -240,7 +242,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(d_sendData, "d", desc="Send data to requestor") {
     peek(memQueue_in, MemoryMsg) {
-      enqueue(responseNetwork_out, ResponseMsg, latency="TO_MEM_CTRL_LATENCY") {
+      enqueue(responseNetwork_out, ResponseMsg, latency="1") {
         out_msg.Address := address;
         out_msg.Type := CoherenceResponseType:DATA;
         out_msg.Sender := machineID;
@@ -265,7 +267,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(dr_sendDMAData, "dr", desc="Send Data to DMA controller from directory") {
     peek(memQueue_in, MemoryMsg) {
-      enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="MEMORY_LATENCY") {
+      enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
         out_msg.PhysicalAddress := address;
         out_msg.LineAddress := address;
         out_msg.Type := DMAResponseType:DATA;
@@ -280,7 +282,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(drp_sendDMAData, "drp", desc="Send Data to DMA controller from incoming PUTX") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="MEMORY_LATENCY") {
+      enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
         out_msg.PhysicalAddress := address;
         out_msg.LineAddress := address;
         out_msg.Type := DMAResponseType:DATA;
@@ -292,7 +294,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
   }
 
   action(da_sendDMAAck, "da", desc="Send Ack to DMA controller") {
-      enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="MEMORY_LATENCY") {
+      enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
         out_msg.PhysicalAddress := address;
         out_msg.LineAddress := address;
         out_msg.Type := DMAResponseType:ACK;
@@ -318,7 +320,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
       APPEND_TRANSITION_COMMENT(directory[in_msg.Address].Owner);
       APPEND_TRANSITION_COMMENT("Req: ");
       APPEND_TRANSITION_COMMENT(in_msg.Requestor);
-      enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
+      enqueue(forwardNetwork_out, RequestMsg, latency=directory_latency) {
         out_msg.Address := address;
         out_msg.Type := in_msg.Type;
         out_msg.Requestor := in_msg.Requestor;
@@ -330,7 +332,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(inv_sendCacheInvalidate, "inv", desc="Invalidate a cache block") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
+      enqueue(forwardNetwork_out, RequestMsg, latency=directory_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceRequestType:INV;
       out_msg.Requestor := machineID;
@@ -359,14 +361,14 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
   }
 
   action(dwt_writeDMADataFromTBE, "dwt", desc="DMA Write data to memory from TBE") {
-    directory[address].DataBlk.copyPartial(TBEs[address].DataBlk, TBEs[address].Offset, TBEs[address].Len);
+    directory[address].DataBlk.copyPartial(TBEs[address].DataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len);
   }
 
   action(v_allocateTBE, "v", desc="Allocate TBE") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
       TBEs.allocate(address);
       TBEs[address].DataBlk := in_msg.DataBlk;
-      TBEs[address].Offset := in_msg.Offset;
+      TBEs[address].PhysicalAddress := in_msg.PhysicalAddress;
       TBEs[address].Len := in_msg.Len;
     }
   }
@@ -389,7 +391,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, latency="TO_MEM_CTRL_LATENCY") {
+      enqueue(memQueue_out, MemoryMsg, latency="1") {
         out_msg.Address := address;
         out_msg.Type := MemoryRequestType:MEMORY_READ;
         out_msg.Sender := machineID;
@@ -403,7 +405,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, latency="TO_MEM_CTRL_LATENCY") {
+      enqueue(memQueue_out, MemoryMsg, latency="1") {
         out_msg.Address := address;
         out_msg.Type := MemoryRequestType:MEMORY_READ;
         out_msg.Sender := machineID;
@@ -416,7 +418,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
   }
 //  action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") {
 //     peek(dmaRequestQueue_in, DMARequestMsg) {
-//      enqueue(memQueue_out, MemoryMsg, latency="TO_MEM_CTRL_LATENCY") {
+//      enqueue(memQueue_out, MemoryMsg, latency="1") {
 //        out_msg.Address := address;
 //        out_msg.Type := MemoryRequestType:MEMORY_WB;
 //        out_msg.OriginalRequestorMachId := machineID;
@@ -431,12 +433,12 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") {
      peek(dmaRequestQueue_in, DMARequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, latency="TO_MEM_CTRL_LATENCY") {
+      enqueue(memQueue_out, MemoryMsg, latency="1") {
         out_msg.Address := address;
         out_msg.Type := MemoryRequestType:MEMORY_WB;
         //out_msg.OriginalRequestorMachId := machineID;
         //out_msg.DataBlk := in_msg.DataBlk;
-        out_msg.DataBlk.copyPartial(in_msg.DataBlk, in_msg.Offset, in_msg.Len);
+        out_msg.DataBlk.copyPartial(in_msg.DataBlk, addressOffset(in_msg.PhysicalAddress), in_msg.Len);
         out_msg.MessageSize := in_msg.MessageSize;
         //out_msg.Prefetch := in_msg.Prefetch;
 
@@ -447,12 +449,12 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(qw_queueMemoryWBRequest_partialTBE, "qwt", desc="Queue off-chip writeback request") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, latency="TO_MEM_CTRL_LATENCY") {
+      enqueue(memQueue_out, MemoryMsg, latency="1") {
         out_msg.Address := address;
         out_msg.Type := MemoryRequestType:MEMORY_WB;
         out_msg.OriginalRequestorMachId := in_msg.Requestor;
         //out_msg.DataBlk := in_msg.DataBlk;
-        out_msg.DataBlk.copyPartial(TBEs[address].DataBlk, TBEs[address].Offset, TBEs[address].Len);
+        out_msg.DataBlk.copyPartial(TBEs[address].DataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len);
         out_msg.MessageSize := in_msg.MessageSize;
         //out_msg.Prefetch := in_msg.Prefetch;
 
@@ -465,7 +467,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
 
   action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, latency="TO_MEM_CTRL_LATENCY") {
+      enqueue(memQueue_out, MemoryMsg, latency="1") {
         out_msg.Address := address;
         out_msg.Type := MemoryRequestType:MEMORY_WB;
         out_msg.OriginalRequestorMachId := in_msg.Requestor;
index d5de185520a2e3d6626160afd24a7a2fde6d9365..e883288df9ede5370228041b3d40631c77c3a48b 100644 (file)
@@ -1,5 +1,7 @@
 
-machine(DMA, "DMA Controller") {
+machine(DMA, "DMA Controller") 
+: int request_latency
+{
 
   MessageBuffer responseFromDir, network="From", virtual_network="4", ordered="true", no_vector="true";
   MessageBuffer reqToDirectory, network="To", virtual_network="5", ordered="false", no_vector="true";
@@ -35,12 +37,12 @@ machine(DMA, "DMA Controller") {
 
   out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="...");
 
-  in_port(dmaRequestQueue_in, DMARequestMsg, mandatoryQueue, desc="...") {
+  in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") {
     if (dmaRequestQueue_in.isReady()) {
-      peek(dmaRequestQueue_in, DMARequestMsg) {
-        if (in_msg.Type == DMARequestType:READ ) {
+      peek(dmaRequestQueue_in, SequencerMsg) {
+        if (in_msg.Type == SequencerRequestType:LD ) {
           trigger(Event:ReadRequest, in_msg.LineAddress);
-        } else if (in_msg.Type == DMARequestType:WRITE) {
+        } else if (in_msg.Type == SequencerRequestType:ST) {
           trigger(Event:WriteRequest, in_msg.LineAddress);
         } else {
           error("Invalid request type");
@@ -64,9 +66,9 @@ machine(DMA, "DMA Controller") {
   }
 
   action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") {
-    peek(dmaRequestQueue_in, DMARequestMsg) {
-      enqueue(reqToDirectory_out, DMARequestMsg) {
-        out_msg.PhysicalAddress := address;
+    peek(dmaRequestQueue_in, SequencerMsg) {
+      enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) {
+        out_msg.PhysicalAddress := in_msg.PhysicalAddress;
         out_msg.LineAddress := in_msg.LineAddress; 
         out_msg.Type := DMARequestType:READ;
         out_msg.DataBlk := in_msg.DataBlk;
@@ -78,9 +80,9 @@ machine(DMA, "DMA Controller") {
   }
 
   action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") {
-    peek(dmaRequestQueue_in, DMARequestMsg) {
-        enqueue(reqToDirectory_out, DMARequestMsg) {
-          out_msg.PhysicalAddress := address;
+    peek(dmaRequestQueue_in, SequencerMsg) {
+      enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) {
+          out_msg.PhysicalAddress := in_msg.PhysicalAddress;
           out_msg.LineAddress := in_msg.LineAddress; 
           out_msg.Type := DMARequestType:WRITE;
           out_msg.DataBlk := in_msg.DataBlk;
index 8c0afed2ead55c6fad0acd973101f99a999b42a4..d4d5572003fb2d8f54565159e10f7493833f9352 100644 (file)
@@ -107,7 +107,6 @@ structure(DMARequestMsg, desc="...", interface="NetworkMessage") {
   Address LineAddress,       desc="Line address for this request";
   NetDest Destination,       desc="Destination";
   DataBlock DataBlk,         desc="DataBlk attached to this request";
-  int Offset,                desc="The offset into the datablock";
   int Len,                   desc="The length of the request";
   MessageSizeType MessageSize, desc="size category of the message";
 }
index a65ade10f22fc4f370389abb9b2ff086db240295..8fe0d3baf094d3463eb42c2aa75cbceaa48f7b2f 100644 (file)
  *
  */
 
-machine(L1Cache, "Directory protocol") {
+machine(L1Cache, "Directory protocol") 
+ : int request_latency, 
+   int l2_select_low_bit, 
+   int l2_select_high_bit
+{
 
   // NODE L1 CACHE
   // From this node's L1 cache TO the network
@@ -125,7 +129,7 @@ machine(L1Cache, "Directory protocol") {
   external_type(CacheMemory) {
     bool cacheAvail(Address);
     Address cacheProbe(Address);
-    void allocate(Address);
+    void allocate(Address, Entry);
     void deallocate(Address);
     Entry lookup(Address);
     void changePermission(Address, AccessPermission);
@@ -141,11 +145,11 @@ machine(L1Cache, "Directory protocol") {
 
 
   MessageBuffer mandatoryQueue, ordered="false", abstract_chip_ptr="true";
-  Sequencer sequencer, abstract_chip_ptr="true", constructor_hack="i";
+  Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])';
 
   TBETable TBEs, template_hack="<L1Cache_TBE>";
-  CacheMemory L1IcacheMemory, template_hack="<L1Cache_Entry>", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,MachineType_L1Cache,int_to_string(i)+"_L1I"', abstract_chip_ptr="true";
-  CacheMemory L1DcacheMemory, template_hack="<L1Cache_Entry>", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,MachineType_L1Cache,int_to_string(i)+"_L1D"', abstract_chip_ptr="true";
+  CacheMemory L1IcacheMemory, factory='RubySystem::getCache(m_cfg["icache"])';
+  CacheMemory L1DcacheMemory, factory='RubySystem::getCache(m_cfg["dcache"])';
   TimerTable useTimerTable;
 
   Entry getCacheEntry(Address addr), return_by_ref="yes" {
@@ -305,7 +309,7 @@ machine(L1Cache, "Directory protocol") {
         assert(in_msg.Destination.isElement(machineID));
         DEBUG_EXPR("MRM_DEBUG: L1 received");
         DEBUG_EXPR(in_msg.Type);
-        if (in_msg.Type == CoherenceRequestType:GETX) {
+if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestType:DMA_READ || in_msg.Type == CoherenceRequestType:DMA_WRITE) {
           if (in_msg.Requestor == machineID && in_msg.RequestorMachine == MachineType:L1Cache) {
             trigger(Event:Own_GETX, in_msg.Address);
           } else {
@@ -357,40 +361,40 @@ machine(L1Cache, "Directory protocol") {
           // ** INSTRUCTION ACCESS ***
 
           // Check to see if it is in the OTHER L1
-          if (L1DcacheMemory.isTagPresent(in_msg.Address)) {
+          if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) {
             // The block is in the wrong L1, put the request on the queue to the shared L2
-            trigger(Event:L1_Replacement, in_msg.Address);
+            trigger(Event:L1_Replacement, in_msg.LineAddress);
           }
-          if (L1IcacheMemory.isTagPresent(in_msg.Address)) {
+          if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) {
             // The tag matches for the L1, so the L1 asks the L2 for it.
-            trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address);
+            trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
           } else {
-            if (L1IcacheMemory.cacheAvail(in_msg.Address)) {
+            if (L1IcacheMemory.cacheAvail(in_msg.LineAddress)) {
               // L1 does't have the line, but we have space for it in the L1 so let's see if the L2 has it
-              trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address);
+              trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
             } else {
               // No room in the L1, so we need to make room in the L1
-              trigger(Event:L1_Replacement, L1IcacheMemory.cacheProbe(in_msg.Address));
+              trigger(Event:L1_Replacement, L1IcacheMemory.cacheProbe(in_msg.LineAddress));
             }
           }
         } else {
           // *** DATA ACCESS ***
 
           // Check to see if it is in the OTHER L1
-          if (L1IcacheMemory.isTagPresent(in_msg.Address)) {
+          if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) {
             // The block is in the wrong L1, put the request on the queue to the shared L2
-            trigger(Event:L1_Replacement, in_msg.Address);
+            trigger(Event:L1_Replacement, in_msg.LineAddress);
           }
-          if (L1DcacheMemory.isTagPresent(in_msg.Address)) {
+          if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) {
             // The tag matches for the L1, so the L1 ask the L2 for it
-            trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address);
+            trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
           } else {
-            if (L1DcacheMemory.cacheAvail(in_msg.Address)) {
+            if (L1DcacheMemory.cacheAvail(in_msg.LineAddress)) {
               // L1 does't have the line, but we have space for it in the L1 let's see if the L2 has it
-              trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address);
+              trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
             } else {
               // No room in the L1, so we need to make room in the L1
-              trigger(Event:L1_Replacement, L1DcacheMemory.cacheProbe(in_msg.Address));
+              trigger(Event:L1_Replacement, L1DcacheMemory.cacheProbe(in_msg.LineAddress));
             }
           }
         }
@@ -403,11 +407,12 @@ machine(L1Cache, "Directory protocol") {
 
   action(a_issueGETS, "a", desc="Issue GETS") {
     peek(mandatoryQueue_in, CacheMsg) {
-      enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
+      enqueue(requestNetwork_out, RequestMsg, latency= request_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceRequestType:GETS;
         out_msg.Requestor := machineID;
-        out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address, machineID));
+        out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                                 l2_select_low_bit, l2_select_high_bit));
         out_msg.MessageSize := MessageSizeType:Request_Control;
         out_msg.AccessMode := in_msg.AccessMode;
         out_msg.Prefetch := in_msg.Prefetch;
@@ -417,11 +422,12 @@ machine(L1Cache, "Directory protocol") {
 
   action(b_issueGETX, "b", desc="Issue GETX") {
     peek(mandatoryQueue_in, CacheMsg) {
-      enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
+      enqueue(requestNetwork_out, RequestMsg, latency=request_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceRequestType:GETX;
         out_msg.Requestor := machineID;
-        out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address, machineID));
+        out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                                 l2_select_low_bit, l2_select_high_bit));
         out_msg.MessageSize := MessageSizeType:Request_Control;
         out_msg.AccessMode := in_msg.AccessMode;
         out_msg.Prefetch := in_msg.Prefetch;
@@ -430,34 +436,37 @@ machine(L1Cache, "Directory protocol") {
   }
 
   action(d_issuePUTX, "d", desc="Issue PUTX") {
-    // enqueue(writebackNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
-    enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
+    // enqueue(writebackNetwork_out, RequestMsg, latency=request_latency) {
+    enqueue(requestNetwork_out, RequestMsg, latency=request_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceRequestType:PUTX;
       out_msg.Requestor := machineID;
-      out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address, machineID));
+      out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                               l2_select_low_bit, l2_select_high_bit));
       out_msg.MessageSize := MessageSizeType:Writeback_Control;
     }
   }
 
   action(dd_issuePUTO, "\d", desc="Issue PUTO") {
-    // enqueue(writebackNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
-    enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
+    // enqueue(writebackNetwork_out, RequestMsg, latency=request_latency) {
+    enqueue(requestNetwork_out, RequestMsg, latency=request_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceRequestType:PUTO;
       out_msg.Requestor := machineID;
-      out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address, machineID));
+      out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                               l2_select_low_bit, l2_select_high_bit));
       out_msg.MessageSize := MessageSizeType:Writeback_Control;
     }
   }
 
   action(dd_issuePUTS, "\ds", desc="Issue PUTS") {
-    // enqueue(writebackNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
-    enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
+    // enqueue(writebackNetwork_out, RequestMsg, latency=request_latency) {
+    enqueue(requestNetwork_out, RequestMsg, latency=request_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceRequestType:PUTS;
       out_msg.Requestor := machineID;
-      out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address, machineID));
+      out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                               l2_select_low_bit, l2_select_high_bit));
       out_msg.MessageSize := MessageSizeType:Writeback_Control;
     }
   }
@@ -465,11 +474,12 @@ machine(L1Cache, "Directory protocol") {
   action(e_sendData, "e", desc="Send data from cache to requestor") {
     peek(requestNetwork_in, RequestMsg) {
       if (in_msg.RequestorMachine == MachineType:L2Cache) {
-        enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+        enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
           out_msg.Address := address;
           out_msg.Type := CoherenceResponseType:DATA;
           out_msg.Sender := machineID;
-          out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(in_msg.Address, machineID));
+          out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                                   l2_select_low_bit, l2_select_high_bit));
           out_msg.DataBlk := getCacheEntry(address).DataBlk;
           // out_msg.Dirty := getCacheEntry(address).Dirty;
           out_msg.Dirty := false;
@@ -480,7 +490,7 @@ machine(L1Cache, "Directory protocol") {
         DEBUG_EXPR(in_msg.Address);
       }
       else {
-        enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+        enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
           out_msg.Address := address;
           out_msg.Type := CoherenceResponseType:DATA;
           out_msg.Sender := machineID;
@@ -497,11 +507,12 @@ machine(L1Cache, "Directory protocol") {
   }
 
   action(e_sendDataToL2, "ee", desc="Send data from cache to requestor") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:DATA;
       out_msg.Sender := machineID;
-      out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address, machineID));
+      out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                               l2_select_low_bit, l2_select_high_bit));
       out_msg.DataBlk := getCacheEntry(address).DataBlk;
       out_msg.Dirty := getCacheEntry(address).Dirty;
       out_msg.Acks := 0; // irrelevant
@@ -513,12 +524,13 @@ machine(L1Cache, "Directory protocol") {
   action(ee_sendDataExclusive, "\e", desc="Send data from cache to requestor, don't keep a shared copy") {
     peek(requestNetwork_in, RequestMsg) {
       if (in_msg.RequestorMachine == MachineType:L2Cache) {
-        enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+        enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
           out_msg.Address := address;
           out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
           out_msg.Sender := machineID;
           out_msg.SenderMachine := MachineType:L1Cache;
-          out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(in_msg.Address, machineID));
+          out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                                   l2_select_low_bit, l2_select_high_bit));
           out_msg.DataBlk := getCacheEntry(address).DataBlk;
           out_msg.Dirty := getCacheEntry(address).Dirty;
           out_msg.Acks := in_msg.Acks;
@@ -527,7 +539,7 @@ machine(L1Cache, "Directory protocol") {
         DEBUG_EXPR("Sending exclusive data to L2");
       }
       else {
-        enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+        enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
           out_msg.Address := address;
           out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
           out_msg.Sender := machineID;
@@ -546,7 +558,7 @@ machine(L1Cache, "Directory protocol") {
   action(f_sendAck, "f", desc="Send ack from cache to requestor") {
     peek(requestNetwork_in, RequestMsg) {
       if (in_msg.RequestorMachine == MachineType:L1Cache) {
-        enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+        enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
           out_msg.Address := address;
           out_msg.Type := CoherenceResponseType:ACK;
           out_msg.Sender := machineID;
@@ -557,12 +569,13 @@ machine(L1Cache, "Directory protocol") {
         }
       }
       else {
-        enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+        enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
           out_msg.Address := address;
           out_msg.Type := CoherenceResponseType:ACK;
           out_msg.Sender := machineID;
           out_msg.SenderMachine := MachineType:L1Cache;
-          out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(in_msg.Address, machineID));
+          out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                                   l2_select_low_bit, l2_select_high_bit));
           out_msg.Acks := 0 - 1; // -1
           out_msg.MessageSize := MessageSizeType:Response_Control;
         }
@@ -571,21 +584,23 @@ machine(L1Cache, "Directory protocol") {
   }
 
   action(g_sendUnblock, "g", desc="Send unblock to memory") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:UNBLOCK;
       out_msg.Sender := machineID;
-      out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address, machineID));
+      out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                               l2_select_low_bit, l2_select_high_bit));
       out_msg.MessageSize := MessageSizeType:Unblock_Control;
     }
   }
 
   action(gg_sendUnblockExclusive, "\g", desc="Send unblock exclusive to memory") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE;
       out_msg.Sender := machineID;
-      out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address, machineID));
+      out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                               l2_select_low_bit, l2_select_high_bit));
       out_msg.MessageSize := MessageSizeType:Unblock_Control;
     }
   }
@@ -627,7 +642,6 @@ machine(L1Cache, "Directory protocol") {
   action(m_decrementNumberOfMessages, "m", desc="Decrement the number of messages for which we're waiting") {
     peek(responseToL1Cache_in, ResponseMsg) {
       DEBUG_EXPR("MRM_DEBUG: L1 decrementNumberOfMessages");
-      DEBUG_EXPR(id);
       DEBUG_EXPR(in_msg.Acks);
       TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - in_msg.Acks;
     }
@@ -660,7 +674,7 @@ machine(L1Cache, "Directory protocol") {
   action(q_sendDataFromTBEToCache, "q", desc="Send data from TBE to cache") {
     peek(requestNetwork_in, RequestMsg) {
       if (in_msg.RequestorMachine == MachineType:L1Cache) {
-        enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+        enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
           out_msg.Address := address;
           out_msg.Type := CoherenceResponseType:DATA;
           out_msg.Sender := machineID;
@@ -673,11 +687,12 @@ machine(L1Cache, "Directory protocol") {
         }
       }
       else {
-        enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+        enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
           out_msg.Address := address;
           out_msg.Type := CoherenceResponseType:DATA;
           out_msg.Sender := machineID;
-          out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID));
+          out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                                   l2_select_low_bit, l2_select_high_bit));
           out_msg.DataBlk := TBEs[address].DataBlk;
           // out_msg.Dirty := TBEs[address].Dirty;
           out_msg.Dirty := false;
@@ -691,7 +706,7 @@ machine(L1Cache, "Directory protocol") {
   action(q_sendExclusiveDataFromTBEToCache, "qq", desc="Send data from TBE to cache") {
     peek(requestNetwork_in, RequestMsg) {
       if (in_msg.RequestorMachine == MachineType:L1Cache) {
-        enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+        enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
           out_msg.Address := address;
           out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
           out_msg.Sender := machineID;
@@ -703,11 +718,12 @@ machine(L1Cache, "Directory protocol") {
         }
       }
       else {
-        enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+        enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
           out_msg.Address := address;
           out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
           out_msg.Sender := machineID;
-          out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID));
+          out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                                   l2_select_low_bit, l2_select_high_bit));
           out_msg.DataBlk := TBEs[address].DataBlk;
           out_msg.Dirty := TBEs[address].Dirty;
           out_msg.Acks := in_msg.Acks;
@@ -720,11 +736,12 @@ machine(L1Cache, "Directory protocol") {
 
   // L2 will usually request data for a writeback
   action(qq_sendWBDataFromTBEToL2, "\q", desc="Send data from TBE to L2") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L1_REQUEST_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
       out_msg.Address := address;
       out_msg.Sender := machineID;
       out_msg.SenderMachine := MachineType:L1Cache;
-      out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address, machineID));
+      out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, 
+                                               l2_select_low_bit, l2_select_high_bit));
       out_msg.Dirty := TBEs[address].Dirty;
       if (TBEs[address].Dirty) {
         out_msg.Type := CoherenceResponseType:WRITEBACK_DIRTY_DATA;
@@ -770,13 +787,13 @@ machine(L1Cache, "Directory protocol") {
 
   action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") {
     if (L1DcacheMemory.isTagPresent(address) == false) {
-      L1DcacheMemory.allocate(address);
+      L1DcacheMemory.allocate(address, new Entry);
     }
   }
 
   action(jj_allocateL1ICacheBlock, "\j", desc="Set L1 I-cache tag equal to tag of block B.") {
     if (L1IcacheMemory.isTagPresent(address) == false) {
-      L1IcacheMemory.allocate(address);
+      L1IcacheMemory.allocate(address, new Entry);
     }
   }
 
@@ -784,7 +801,7 @@ machine(L1Cache, "Directory protocol") {
 
   action(uu_profileMiss, "\u", desc="Profile the demand miss") {
     peek(mandatoryQueue_in, CacheMsg) {
-      profile_miss(in_msg, id);
+      //      profile_miss(in_msg);
     }
   }
 
index fa01f925ca2c62dcf1ce1c7949c75c012c3b41d9..68d3a2cd39aa7503e95d88c4d00e0e94fed6db19 100644 (file)
  *
  */
 
-machine(L2Cache, "Token protocol") {
+machine(L2Cache, "Token protocol") 
+: int response_latency, 
+  int request_latency
+{
 
   // L2 BANK QUEUES
   // From local bank of L2 cache TO the network
@@ -208,7 +211,7 @@ machine(L2Cache, "Token protocol") {
   external_type(CacheMemory) {
     bool cacheAvail(Address);
     Address cacheProbe(Address);
-    void allocate(Address);
+    void allocate(Address, Entry);
     void deallocate(Address);
     Entry lookup(Address);
     void changePermission(Address, AccessPermission);
@@ -225,13 +228,15 @@ machine(L2Cache, "Token protocol") {
 
 
   TBETable L2_TBEs, template_hack="<L2Cache_TBE>";
-  CacheMemory L2cacheMemory, template_hack="<L2Cache_Entry>", constructor_hack='L2_CACHE_NUM_SETS_BITS,L2_CACHE_ASSOC,MachineType_L2Cache,int_to_string(i)+"_L2"';
+  CacheMemory L2cacheMemory, factory='RubySystem::getCache(m_cfg["cache"])';
   PerfectCacheMemory localDirectory, template_hack="<L2Cache_DirEntry>";
 
 
   Entry getL2CacheEntry(Address addr), return_by_ref="yes" {
     if (L2cacheMemory.isTagPresent(addr)) {
       return L2cacheMemory[addr];
+    } else {
+      return L2cacheMemory[addr];
     }
   }
 
@@ -579,7 +584,7 @@ machine(L2Cache, "Token protocol") {
   in_port(requestNetwork_in, RequestMsg, GlobalRequestToL2Cache) {
     if (requestNetwork_in.isReady()) {
       peek(requestNetwork_in, RequestMsg) {
-        if (in_msg.Type == CoherenceRequestType:GETX) {
+        if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestType:DMA_READ || in_msg.Type == CoherenceRequestType:DMA_WRITE) {
           if (in_msg.Requestor == machineID) {
             trigger(Event:Own_GETX, in_msg.Address);
           } else {
@@ -675,7 +680,7 @@ machine(L2Cache, "Token protocol") {
 
   action(a_issueGETS, "a", desc="issue local request globally") {
     peek(L1requestNetwork_in, RequestMsg) {
-      enqueue(globalRequestNetwork_out, RequestMsg, latency="L2_REQUEST_LATENCY") {
+      enqueue(globalRequestNetwork_out, RequestMsg, latency=request_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceRequestType:GETS;
         out_msg.RequestorMachine := MachineType:L2Cache;
@@ -688,7 +693,7 @@ machine(L2Cache, "Token protocol") {
 
   action(a_issueGETX, "\a", desc="issue local request globally") {
     peek(L1requestNetwork_in, RequestMsg) {
-      enqueue(globalRequestNetwork_out, RequestMsg, latency="L2_REQUEST_LATENCY") {
+      enqueue(globalRequestNetwork_out, RequestMsg, latency=request_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceRequestType:GETX;
         out_msg.RequestorMachine := MachineType:L2Cache;
@@ -700,7 +705,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(b_issuePUTX, "b", desc="Issue PUTX") {
-    enqueue(globalRequestNetwork_out, RequestMsg, latency="L2_REQUEST_LATENCY") {
+    enqueue(globalRequestNetwork_out, RequestMsg, latency=request_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceRequestType:PUTX;
       out_msg.RequestorMachine := MachineType:L2Cache;
@@ -711,7 +716,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(b_issuePUTO, "\b", desc="Issue PUTO") {
-    enqueue(globalRequestNetwork_out, RequestMsg, latency="L2_REQUEST_LATENCY") {
+    enqueue(globalRequestNetwork_out, RequestMsg, latency=request_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceRequestType:PUTO;
       out_msg.Requestor := machineID;
@@ -723,7 +728,7 @@ machine(L2Cache, "Token protocol") {
 
   /* PUTO, but local sharers exist */
   action(b_issuePUTO_ls, "\bb", desc="Issue PUTO") {
-    enqueue(globalRequestNetwork_out, RequestMsg, latency="L2_REQUEST_LATENCY") {
+    enqueue(globalRequestNetwork_out, RequestMsg, latency=request_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceRequestType:PUTO_SHARERS;
       out_msg.Requestor := machineID;
@@ -734,7 +739,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(c_sendDataFromTBEToL1GETS, "c", desc="Send data from TBE to L1 requestors in TBE") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:DATA;
       out_msg.Sender := machineID;
@@ -750,7 +755,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(c_sendDataFromTBEToL1GETX, "\c", desc="Send data from TBE to L1 requestors in TBE") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
       out_msg.Sender := machineID;
@@ -766,7 +771,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(c_sendExclusiveDataFromTBEToL1GETS, "\cc", desc="Send data from TBE to L1 requestors in TBE") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
       out_msg.Sender := machineID;
@@ -779,7 +784,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(c_sendDataFromTBEToFwdGETX, "cc", desc="Send data from TBE to external GETX") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
       out_msg.Sender := machineID;
@@ -793,7 +798,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(c_sendDataFromTBEToFwdGETS, "ccc", desc="Send data from TBE to external GETX") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:DATA;
       out_msg.Sender := machineID;
@@ -810,7 +815,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(c_sendExclusiveDataFromTBEToFwdGETS, "\ccc", desc="Send data from TBE to external GETX") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
       out_msg.Sender := machineID;
@@ -827,7 +832,7 @@ machine(L2Cache, "Token protocol") {
 
   action(d_sendDataToL1GETS, "d", desc="Send data directly to L1 requestor") {
     peek(L1requestNetwork_in, RequestMsg) {
-      enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+      enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceResponseType:DATA;
         out_msg.Sender := machineID;
@@ -845,7 +850,7 @@ machine(L2Cache, "Token protocol") {
 
   action(d_sendDataToL1GETX, "\d", desc="Send data and a token from TBE to L1 requestor") {
     peek(L1requestNetwork_in, RequestMsg) {
-      enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+      enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
         out_msg.Sender := machineID;
@@ -863,7 +868,7 @@ machine(L2Cache, "Token protocol") {
 
   action(dd_sendDataToFwdGETX, "dd", desc="send data") {
     peek(requestNetwork_in, RequestMsg) {
-      enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+      enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
         out_msg.Sender := machineID;
@@ -882,7 +887,7 @@ machine(L2Cache, "Token protocol") {
 
   action(dd_sendDataToFwdGETS, "\dd", desc="send data") {
     peek(requestNetwork_in, RequestMsg) {
-      enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+      enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceResponseType:DATA;
         out_msg.Sender := machineID;
@@ -900,7 +905,7 @@ machine(L2Cache, "Token protocol") {
 
   action(dd_sendExclusiveDataToFwdGETS, "\d\d", desc="send data") {
     peek(requestNetwork_in, RequestMsg) {
-      enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+      enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
         out_msg.Sender := machineID;
@@ -913,7 +918,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(e_sendAck, "e", desc="Send ack with the tokens we've collected thus far.") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:ACK;
       out_msg.Sender := machineID;
@@ -927,7 +932,7 @@ machine(L2Cache, "Token protocol") {
 
   action(e_sendAckToL1Requestor, "\e", desc="Send ack with the tokens we've collected thus far.") {
     peek(L1requestNetwork_in, RequestMsg) {
-      enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+      enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceResponseType:ACK;
         out_msg.Sender := machineID;
@@ -940,7 +945,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(e_sendAckToL1RequestorFromTBE, "eee", desc="Send ack with the tokens we've collected thus far.") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:ACK;
       out_msg.Sender := machineID;
@@ -955,14 +960,13 @@ machine(L2Cache, "Token protocol") {
     L2_TBEs[address].NumIntPendingAcks := countLocalSharers(address);
     DEBUG_EXPR(address);
     DEBUG_EXPR(getLocalSharers(address));
-    DEBUG_EXPR(id);
     DEBUG_EXPR(L2_TBEs[address].NumIntPendingAcks);
     if (isLocalOwnerValid(address)) {
       L2_TBEs[address].NumIntPendingAcks := L2_TBEs[address].NumIntPendingAcks + 1;
       DEBUG_EXPR(getLocalOwner(address));
     }
 
-    enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+    enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
       out_msg.Address := address;
       out_msg.Type := CoherenceRequestType:INV;
       out_msg.Requestor := machineID;
@@ -982,7 +986,7 @@ machine(L2Cache, "Token protocol") {
     L2_TBEs[address].NumIntPendingAcks := countLocalSharers(address);
 
     if (countLocalSharers(address) > 0) {
-      enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+      enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
         out_msg.Address := address;
         out_msg.Type := CoherenceRequestType:INV;
         out_msg.Requestor := machineID;
@@ -1013,7 +1017,7 @@ machine(L2Cache, "Token protocol") {
             L2_TBEs[address].NumIntPendingAcks := countLocalSharers(address);
           }
 
-          enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+          enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
             out_msg.Address := address;
             out_msg.Type := CoherenceRequestType:INV;
             out_msg.Requestor := in_msg.Requestor;
@@ -1038,7 +1042,7 @@ machine(L2Cache, "Token protocol") {
         L2_TBEs[address].NumIntPendingAcks := countLocalSharers(address);
       }
     }
-    enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+    enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
         out_msg.Address := address;
         out_msg.Type := CoherenceRequestType:INV;
         out_msg.Requestor := L2_TBEs[address].L1_GetX_ID;
@@ -1051,7 +1055,7 @@ machine(L2Cache, "Token protocol") {
 
 
   action(f_sendUnblock, "f", desc="Send unblock to global directory") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:UNBLOCK;
       out_msg.Destination.add(map_Address_to_Directory(address));
@@ -1063,7 +1067,7 @@ machine(L2Cache, "Token protocol") {
 
 
   action(f_sendExclusiveUnblock, "\f", desc="Send unblock to global directory") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
       out_msg.Address := address;
       out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE;
       out_msg.Destination.add(map_Address_to_Directory(address));
@@ -1140,7 +1144,7 @@ machine(L2Cache, "Token protocol") {
 
   action(j_forwardGlobalRequestToLocalOwner, "j", desc="Forward external request to local owner") {
     peek(requestNetwork_in, RequestMsg) {
-      enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+      enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
         out_msg.Address := in_msg.Address;
         out_msg.Type := in_msg.Type;
         out_msg.Requestor := machineID;
@@ -1156,7 +1160,7 @@ machine(L2Cache, "Token protocol") {
 
   action(k_forwardLocalGETSToLocalSharer, "k", desc="Forward local request to local sharer/owner") {
     peek(L1requestNetwork_in, RequestMsg) {
-      enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+      enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
         out_msg.Address := in_msg.Address;
         out_msg.Type := CoherenceRequestType:GETS;
         out_msg.Requestor := in_msg.Requestor;
@@ -1169,7 +1173,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(k_forwardLocalGETXToLocalOwner, "\k", desc="Forward local request to local owner") {
-    enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+    enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
       out_msg.Address := address;
       out_msg.Type := CoherenceRequestType:GETX;
       out_msg.Requestor := L2_TBEs[address].L1_GetX_ID;
@@ -1183,7 +1187,7 @@ machine(L2Cache, "Token protocol") {
   // same as previous except that it assumes to TBE is present to get number of acks
   action(kk_forwardLocalGETXToLocalExclusive, "kk", desc="Forward local request to local owner") {
     peek(L1requestNetwork_in, RequestMsg) {
-      enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+      enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
         out_msg.Address := in_msg.Address;
         out_msg.Type := CoherenceRequestType:GETX;
         out_msg.Requestor := in_msg.Requestor;
@@ -1197,7 +1201,7 @@ machine(L2Cache, "Token protocol") {
 
   action(kk_forwardLocalGETSToLocalOwner, "\kk", desc="Forward local request to local owner") {
     peek(L1requestNetwork_in, RequestMsg) {
-      enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+      enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
         out_msg.Address := in_msg.Address;
         out_msg.Type := CoherenceRequestType:GETS;
         out_msg.Requestor := in_msg.Requestor;
@@ -1211,7 +1215,7 @@ machine(L2Cache, "Token protocol") {
 
   action(l_writebackAckNeedData, "l", desc="Send writeback ack to L1 requesting data") {
     peek(L1requestNetwork_in, RequestMsg) {
-      enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+      enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
         out_msg.Address := in_msg.Address;
         // out_msg.Type := CoherenceResponseType:WRITEBACK_SEND_DATA;
         out_msg.Type := CoherenceRequestType:WB_ACK_DATA;
@@ -1225,7 +1229,7 @@ machine(L2Cache, "Token protocol") {
 
   action(l_writebackAckDropData, "\l", desc="Send writeback ack to L1 indicating to drop data") {
     peek(L1requestNetwork_in, RequestMsg) {
-      enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+      enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
         out_msg.Address := in_msg.Address;
         // out_msg.Type := CoherenceResponseType:WRITEBACK_ACK;
         out_msg.Type := CoherenceRequestType:WB_ACK;
@@ -1239,7 +1243,7 @@ machine(L2Cache, "Token protocol") {
 
   action(ll_writebackNack, "\ll", desc="Send writeback nack to L1") {
     peek(L1requestNetwork_in, RequestMsg) {
-      enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+      enqueue( localRequestNetwork_out, RequestMsg, latency=response_latency ) {
         out_msg.Address := in_msg.Address;
         out_msg.Type := CoherenceRequestType:WB_NACK;
         out_msg.Requestor := machineID;
@@ -1305,7 +1309,7 @@ machine(L2Cache, "Token protocol") {
 
 
   action( qq_sendDataFromTBEToMemory, "qq", desc="Send data from TBE to directory") {
-    enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+    enqueue(responseNetwork_out, ResponseMsg, latency=response_latency) {
       out_msg.Address := address;
       out_msg.Sender := machineID;
       out_msg.SenderMachine := MachineType:L2Cache;
@@ -1372,7 +1376,7 @@ machine(L2Cache, "Token protocol") {
   }
 
   action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") {
-    L2cacheMemory.allocate(address);
+    L2cacheMemory.allocate(address, new Entry);
   }
 
   action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block.  Sets the cache to not present, allowing a replacement in parallel with a fetch.") {
@@ -1389,7 +1393,7 @@ machine(L2Cache, "Token protocol") {
   action(uu_profileMiss, "\u", desc="Profile the demand miss") {
     peek(L1requestNetwork_in, RequestMsg) {
       // AccessModeType not implemented
-      profile_L2Cache_miss(convertToGenericType(in_msg.Type), in_msg.AccessMode, MessageSizeTypeToInt(in_msg.MessageSize),  in_msg.Prefetch, machineIDToNodeID(in_msg.Requestor));
+      //      profile_L2Cache_miss(convertToGenericType(in_msg.Type), in_msg.AccessMode, MessageSizeTypeToInt(in_msg.MessageSize),  in_msg.Prefetch, machineIDToNodeID(in_msg.Requestor));
     }
   }
 
index a016836c2d2aadf5c387c3147692cabc9ef08280..edd67707e14fb5158c92132b6f921808e15be049 100644 (file)
  * $Id$
  */
 
-machine(Directory, "Directory protocol") {
+machine(Directory, "Directory protocol") 
+: int directory_latency 
+{
 
   // ** IN QUEUES **
   MessageBuffer foo1, network="From", virtual_network="0", ordered="false";  // a mod-L2 bank -> this Dir
   MessageBuffer requestToDir, network="From", virtual_network="1", ordered="false";  // a mod-L2 bank -> this Dir
   MessageBuffer responseToDir, network="From", virtual_network="2", ordered="false";  // a mod-L2 bank -> this Dir
-
+  
   MessageBuffer goo1, network="To", virtual_network="0", ordered="false";
   MessageBuffer forwardFromDir, network="To", virtual_network="1", ordered="false";
   MessageBuffer responseFromDir, network="To", virtual_network="2", ordered="false";  // Dir -> mod-L2 bank
@@ -56,11 +58,16 @@ machine(Directory, "Directory protocol") {
     OO, desc="Blocked, was in owned";
     MO, desc="Blocked, going to owner or maybe modified";
     MM, desc="Blocked, going to modified";
+    MM_DMA, desc="Blocked, going to I";
 
     MI, desc="Blocked on a writeback";
     MIS, desc="Blocked on a writeback, but don't remove from sharers when received";
     OS, desc="Blocked on a writeback";
     OSS, desc="Blocked on a writeback, but don't remove from sharers when received";
+
+    XI_M, desc="In a stable state, going to I, waiting for the memory controller";
+    XI_U, desc="In a stable state, going to I, waiting for an unblock";
+    OI_D, desc="In O, going to I, waiting for data";
   }
 
   // Events
@@ -75,6 +82,11 @@ machine(Directory, "Directory protocol") {
     Exclusive_Unblock, desc="The processor become the exclusive owner (E or M) of the line";
     Clean_Writeback, desc="The final message as part of a PutX/PutS, no data";
     Dirty_Writeback, desc="The final message as part of a PutX/PutS, contains data";
+    Memory_Data,   desc="Fetched data from memory arrives";
+    Memory_Ack,    desc="Writeback Ack from memory arrives";
+    DMA_READ,      desc="DMA Read";
+    DMA_WRITE,     desc="DMA Write";
+    Data,          desc="Data to directory";
   }
 
   // TYPES
@@ -88,15 +100,36 @@ machine(Directory, "Directory protocol") {
     int WaitingUnblocks,           desc="Number of acks we're waiting for";
   }
 
+  structure(TBE, desc="...") {
+    Address address,   desc="Address for this entry";
+    int Len,           desc="Length of request";
+    DataBlock DataBlk, desc="DataBlk";
+    MachineID Requestor, desc="original requestor";
+  }
+
   external_type(DirectoryMemory) {
     Entry lookup(Address);
     bool isPresent(Address);
   }
 
+  external_type(TBETable) {
+    TBE lookup(Address);
+    void allocate(Address);
+    void deallocate(Address);
+    bool isPresent(Address);
+  }
+
+  // to simulate detailed DRAM
+  external_type(MemoryControl, inport="yes", outport="yes") {
+
+  }
+
 
   // ** OBJECTS **
 
-  DirectoryMemory directory, constructor_hack="i";
+  DirectoryMemory directory, factory='RubySystem::getDirectory(m_cfg["directory_name"])';
+  MemoryControl memBuffer, factory='RubySystem::getMemoryControl(m_cfg["memory_controller_name"])';
+  TBETable TBEs, template_hack="<Directory_TBE>";
 
   State getState(Address addr) {
     return directory[addr].DirectoryState;
@@ -164,6 +197,7 @@ machine(Directory, "Directory protocol") {
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
 //  out_port(requestQueue_out, ResponseMsg, requestFromDir); // For recycling requests
   out_port(goo1_out, ResponseMsg, goo1);
+  out_port(memQueue_out, MemoryMsg, memBuffer);
 
   // ** IN_PORTS **
 
@@ -188,6 +222,8 @@ machine(Directory, "Directory protocol") {
           trigger(Event:Dirty_Writeback, in_msg.Address);
         } else if (in_msg.Type == CoherenceResponseType:WRITEBACK_CLEAN_ACK) {
           trigger(Event:Clean_Writeback, in_msg.Address);
+        } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) {
+          trigger(Event:Data, in_msg.Address);        
         } else {
           error("Invalid message");
         }
@@ -208,7 +244,27 @@ machine(Directory, "Directory protocol") {
           trigger(Event:PUTO, in_msg.Address);
         } else if (in_msg.Type == CoherenceRequestType:PUTO_SHARERS) {
           trigger(Event:PUTO_SHARERS, in_msg.Address);
+        } else if (in_msg.Type == CoherenceRequestType:DMA_READ) {
+          trigger(Event:DMA_READ, in_msg.Address);
+        } else if (in_msg.Type == CoherenceRequestType:DMA_WRITE) {
+          trigger(Event:DMA_WRITE, in_msg.Address);
+        } else {
+          error("Invalid message");
+        }
+      }
+    }
+  }
+
+  // off-chip memory request/response is done
+  in_port(memQueue_in, MemoryMsg, memBuffer) {
+    if (memQueue_in.isReady()) {
+      peek(memQueue_in, MemoryMsg) {
+        if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
+          trigger(Event:Memory_Data, in_msg.Address);
+        } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) {
+          trigger(Event:Memory_Ack, in_msg.Address);
         } else {
+          DEBUG_EXPR(in_msg.Type);
           error("Invalid message");
         }
       }
@@ -219,7 +275,7 @@ machine(Directory, "Directory protocol") {
 
   action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
+      enqueue(forwardNetwork_out, RequestMsg, latency=directory_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceRequestType:WB_ACK;
         out_msg.Requestor := in_msg.Requestor;
@@ -231,7 +287,7 @@ machine(Directory, "Directory protocol") {
 
   action(b_sendWriteBackNack, "b", desc="Send writeback nack to requestor") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
+      enqueue(forwardNetwork_out, RequestMsg, latency=directory_latency) {
         out_msg.Address := address;
         out_msg.Type := CoherenceRequestType:WB_NACK;
         out_msg.Requestor := in_msg.Requestor;
@@ -254,26 +310,21 @@ machine(Directory, "Directory protocol") {
     directory[address].Sharers.clear();
   }
 
-  action(d_sendData, "d", desc="Send data to requestor") {
-    peek(requestQueue_in, RequestMsg) {
-      enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") {
-      // enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+  action(d_sendDataMsg, "d", desc="Send data to requestor") {
+    peek(memQueue_in, MemoryMsg) {
+      enqueue(responseNetwork_out, ResponseMsg, latency="1") {
         out_msg.Address := address;
-
-        if (in_msg.Type == CoherenceRequestType:GETS && directory[address].Sharers.count() == 0) {
-          out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
-        } else {
-          out_msg.Type := CoherenceResponseType:DATA;
-        }
-
         out_msg.Sender := machineID;
         out_msg.SenderMachine := MachineType:Directory;
-        out_msg.Destination.add(in_msg.Requestor);
-        out_msg.DataBlk := directory[in_msg.Address].DataBlk;
+        out_msg.Destination.add(in_msg.OriginalRequestorMachId);
+        //out_msg.DataBlk := directory[in_msg.Address].DataBlk;
+        out_msg.DataBlk := in_msg.DataBlk;
         out_msg.Dirty := false; // By definition, the block is now clean
-        out_msg.Acks := directory[address].Sharers.count();
-        if (directory[address].Sharers.isElement(in_msg.Requestor)) {
-          out_msg.Acks := out_msg.Acks - 1;
+        out_msg.Acks := in_msg.Acks;
+        if (in_msg.ReadX) {
+          out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
+        } else {
+          out_msg.Type := CoherenceResponseType:DATA;
         }
         out_msg.MessageSize := MessageSizeType:Response_Data;
       }
@@ -289,7 +340,7 @@ machine(Directory, "Directory protocol") {
 
   action(f_forwardRequest, "f", desc="Forward request to owner") {
     peek(requestQueue_in, RequestMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
+      enqueue(forwardNetwork_out, RequestMsg, latency=directory_latency) {
         out_msg.Address := address;
         out_msg.Type := in_msg.Type;
         out_msg.Requestor := in_msg.Requestor;
@@ -303,11 +354,27 @@ machine(Directory, "Directory protocol") {
     }
   }
 
+  action(f_forwardRequestDirIsRequestor, "\f", desc="Forward request to owner") {
+    peek(requestQueue_in, RequestMsg) {
+      enqueue(forwardNetwork_out, RequestMsg, latency=directory_latency) {
+        out_msg.Address := address;
+        out_msg.Type := in_msg.Type;
+        out_msg.Requestor := machineID;
+        out_msg.Destination.addNetDest(directory[in_msg.Address].Owner);
+        out_msg.Acks := directory[address].Sharers.count();
+        if (directory[address].Sharers.isElement(in_msg.Requestor)) {
+          out_msg.Acks := out_msg.Acks - 1;
+        }
+        out_msg.MessageSize := MessageSizeType:Forwarded_Control;
+      }
+    }
+  }
+
   action(g_sendInvalidations, "g", desc="Send invalidations to sharers, not including the requester") {
     peek(requestQueue_in, RequestMsg) {
       if ((directory[in_msg.Address].Sharers.count() > 1) ||
           ((directory[in_msg.Address].Sharers.count() > 0) && (directory[in_msg.Address].Sharers.isElement(in_msg.Requestor) == false))) {
-        enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
+        enqueue(forwardNetwork_out, RequestMsg, latency=directory_latency) {
           out_msg.Address := address;
           out_msg.Type := CoherenceRequestType:INV;
           out_msg.Requestor := in_msg.Requestor;
@@ -338,7 +405,7 @@ machine(Directory, "Directory protocol") {
     }
   }
 
-  action(ll_checkDataInMemory, "\l", desc="Check PUTX/PUTO data is same as in the memory") {
+  action(ll_checkDataInMemory, "\ld", desc="Check PUTX/PUTO data is same as in the memory") {
     peek(unblockNetwork_in, ResponseMsg) {
       assert(in_msg.Dirty == false);
       assert(in_msg.MessageSize == MessageSizeType:Writeback_Control);
@@ -366,6 +433,70 @@ machine(Directory, "Directory protocol") {
     assert(directory[address].WaitingUnblocks >= 0);
   }
 
+  action(q_popMemQueue, "q", desc="Pop off-chip request queue") {
+    memQueue_in.dequeue();
+  }
+
+  action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
+    peek(requestQueue_in, RequestMsg) {
+      enqueue(memQueue_out, MemoryMsg, latency="1") {
+        out_msg.Address := address;
+        out_msg.Type := MemoryRequestType:MEMORY_READ;
+        out_msg.Sender := machineID;
+        out_msg.OriginalRequestorMachId := in_msg.Requestor;
+        out_msg.DataBlk := directory[in_msg.Address].DataBlk;
+        out_msg.MessageSize := in_msg.MessageSize;
+        //out_msg.Prefetch := false;
+        // These are not used by memory but are passed back here with the read data:
+        out_msg.ReadX := (in_msg.Type == CoherenceRequestType:GETS && directory[address].Sharers.count() == 0);
+        out_msg.Acks := directory[address].Sharers.count();
+        if (directory[address].Sharers.isElement(in_msg.Requestor)) {
+          out_msg.Acks := out_msg.Acks - 1;
+        }
+        DEBUG_EXPR(out_msg);
+      }
+    }
+  }
+
+  action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") {
+    peek(unblockNetwork_in, ResponseMsg) {
+      enqueue(memQueue_out, MemoryMsg, latency="1") {
+        out_msg.Address := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := machineID;
+       if (TBEs.isPresent(address)) {
+          out_msg.OriginalRequestorMachId := TBEs[address].Requestor;
+       }
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.MessageSize := in_msg.MessageSize;
+        //out_msg.Prefetch := false;
+        // Not used:
+        out_msg.ReadX := false;
+        out_msg.Acks := directory[address].Sharers.count();  // for dma requests
+        DEBUG_EXPR(out_msg);
+      }
+    }
+  }
+
+  action(qw_queueMemoryWBRequest2, "/qw", desc="Queue off-chip writeback request") {
+    peek(requestQueue_in, RequestMsg) {
+      enqueue(memQueue_out, MemoryMsg, latency="1") {
+        out_msg.Address := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := machineID;
+        out_msg.OriginalRequestorMachId := in_msg.Requestor;
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.MessageSize := in_msg.MessageSize;
+        //out_msg.Prefetch := false;
+        // Not used:
+        out_msg.ReadX := false;
+        out_msg.Acks := directory[address].Sharers.count();  // for dma requests
+        DEBUG_EXPR(out_msg);
+      }
+    }
+  }
+
+
   //  action(z_stall, "z", desc="Cannot be handled right now.") {
     // Special name recognized as do nothing case
   //  }
@@ -374,26 +505,106 @@ machine(Directory, "Directory protocol") {
     requestQueue_in.recycle();
   }
 
+  action(a_sendDMAAck, "\a", desc="Send DMA Ack that write completed, along with Inv Ack count") {
+    peek(memQueue_in, MemoryMsg) {
+      enqueue(responseNetwork_out, ResponseMsg, latency="1") {
+      out_msg.Address := address;
+      out_msg.Sender := machineID;
+      out_msg.SenderMachine := MachineType:Directory;
+        out_msg.Destination.add(in_msg.OriginalRequestorMachId);
+      out_msg.DataBlk := in_msg.DataBlk;
+      out_msg.Acks := in_msg.Acks;
+      out_msg.Type := CoherenceResponseType:DMA_ACK;
+      out_msg.MessageSize := MessageSizeType:Writeback_Control;
+      }
+    }
+  }
+
+  action(l_writeDMADataToMemory, "\l", desc="Write data from a DMA_WRITE to memory") {
+    peek(requestQueue_in, RequestMsg) {
+      directory[address].DataBlk.copyPartial(in_msg.DataBlk, addressOffset(in_msg.Address), in_msg.Len);
+    }
+  }
+
+  action(l_writeDMADataToMemoryFromTBE, "\ll", desc="Write data from a DMA_WRITE to memory") {
+    directory[address].DataBlk.copyPartial(TBEs[address].DataBlk, addressOffset(address), TBEs[address].Len);
+  }
+
+  action(v_allocateTBE, "v", desc="Allocate TBE entry") {
+    peek (requestQueue_in, RequestMsg) {
+      TBEs.allocate(address);
+      TBEs[address].Len := in_msg.Len;
+      TBEs[address].DataBlk := in_msg.DataBlk;
+      TBEs[address].Requestor := in_msg.Requestor;
+    }
+  }
+
+  action(w_deallocateTBE, "w", desc="Deallocate TBE entry") {
+    TBEs.deallocate(address);
+  }
+
+
+
   // TRANSITIONS
 
   transition(I, GETX, MM) {
-    d_sendData;
+    qf_queueMemoryFetchRequest;
+    i_popIncomingRequestQueue;
+  }
+
+  transition(I, DMA_READ, XI_M) {
+    qf_queueMemoryFetchRequest;
     i_popIncomingRequestQueue;
   }
 
+  transition(I, DMA_WRITE, XI_M) {
+    qw_queueMemoryWBRequest2;
+    l_writeDMADataToMemory;
+    i_popIncomingRequestQueue;
+  }
+
+  transition(XI_M, Memory_Data, XI_U) {
+    d_sendDataMsg;  // ack count may be zero
+    q_popMemQueue;
+  }
+
+  transition(XI_M, Memory_Ack, XI_U) {
+    a_sendDMAAck;  // ack count may be zero
+    q_popMemQueue;
+  }
+
+  transition(XI_U, Exclusive_Unblock, I) {
+    cc_clearSharers;
+    c_clearOwner;
+    j_popIncomingUnblockQueue;
+  }
+
   transition(S, GETX, MM) {
-    d_sendData;
+    qf_queueMemoryFetchRequest;
     g_sendInvalidations;
     i_popIncomingRequestQueue;
   }
 
+  transition(S, DMA_READ, XI_M) {
+    qf_queueMemoryFetchRequest;
+    g_sendInvalidations;  // the DMA will collect the invalidations then send an Unblock Exclusive
+    i_popIncomingRequestQueue;
+  }
+
+  transition(S, DMA_WRITE, XI_M) {
+    qw_queueMemoryWBRequest2;
+    l_writeDMADataToMemory;
+    g_sendInvalidations;  // the DMA will collect invalidations
+    i_popIncomingRequestQueue;
+  }
+
   transition(I, GETS, IS) {
-    d_sendData;
+    qf_queueMemoryFetchRequest;
     i_popIncomingRequestQueue;
   }
 
   transition({S, SS}, GETS, SS) {
-    d_sendData;
+    qf_queueMemoryFetchRequest;
     n_incrementOutstanding;
     i_popIncomingRequestQueue;
   }
@@ -414,6 +625,27 @@ machine(Directory, "Directory protocol") {
     i_popIncomingRequestQueue;
   }
 
+  transition(O, DMA_READ, XI_U) {
+    f_forwardRequest;     // this will cause the data to go to DMA directly
+    g_sendInvalidations;  // this will cause acks to be sent to the DMA
+    i_popIncomingRequestQueue;
+  }
+
+  transition({O,M}, DMA_WRITE, OI_D) {
+    f_forwardRequestDirIsRequestor;    // need the modified data before we can proceed
+    g_sendInvalidations;               // these go to the DMA Controller
+    v_allocateTBE;
+    i_popIncomingRequestQueue;
+  }
+
+  transition(OI_D, Data, XI_M) {
+    qw_queueMemoryWBRequest;
+    l_writeDataToMemory;
+    l_writeDMADataToMemoryFromTBE;
+    w_deallocateTBE;
+    j_popIncomingUnblockQueue;
+  }
+
   transition({O, OO}, GETS, OO) {
     f_forwardRequest;
     n_incrementOutstanding;
@@ -425,6 +657,12 @@ machine(Directory, "Directory protocol") {
     i_popIncomingRequestQueue;
   }
 
+  // no exclusive unblock will show up to the directory
+  transition(M, DMA_READ, XI_U) {
+    f_forwardRequest;     // this will cause the data to go to DMA directly
+    i_popIncomingRequestQueue;
+  }
+
   transition(M, GETS, MO) {
     f_forwardRequest;
     i_popIncomingRequestQueue;
@@ -457,7 +695,7 @@ machine(Directory, "Directory protocol") {
   }
 
 
-  transition({MM, MO, MI, MIS, OS, OSS}, {GETS, GETX, PUTO, PUTO_SHARERS, PUTX}) {
+  transition({MM, MO, MI, MIS, OS, OSS}, {GETS, GETX, PUTO, PUTO_SHARERS, PUTX, DMA_READ}) {
     zz_recycleRequest;
   }
 
@@ -472,7 +710,7 @@ machine(Directory, "Directory protocol") {
     j_popIncomingUnblockQueue;
   }
 
-  transition({IS, SS, OO}, {GETX, PUTO, PUTO_SHARERS, PUTX}) {
+  transition({IS, SS, OO}, {GETX, PUTO, PUTO_SHARERS, PUTX, DMA_READ}) {
     zz_recycleRequest;
   }
 
@@ -519,12 +757,14 @@ machine(Directory, "Directory protocol") {
     c_clearOwner;
     cc_clearSharers;
     l_writeDataToMemory;
+    qw_queueMemoryWBRequest;
     j_popIncomingUnblockQueue;
   }
 
   transition(MIS, Dirty_Writeback, S) {
     c_moveOwnerToSharer;
     l_writeDataToMemory;
+    qw_queueMemoryWBRequest;
     j_popIncomingUnblockQueue;
   }
 
@@ -536,12 +776,14 @@ machine(Directory, "Directory protocol") {
   transition(OS, Dirty_Writeback, S) {
     c_clearOwner;
     l_writeDataToMemory;
+    qw_queueMemoryWBRequest;
     j_popIncomingUnblockQueue;
   }
 
   transition(OSS, Dirty_Writeback, S) {
     c_moveOwnerToSharer;
     l_writeDataToMemory;
+    qw_queueMemoryWBRequest;
     j_popIncomingUnblockQueue;
   }
 
@@ -570,4 +812,15 @@ machine(Directory, "Directory protocol") {
   transition({OS, OSS}, Unblock, O) {
     j_popIncomingUnblockQueue;
   }
+
+  transition({I, S, O, M, IS, SS, OO, MO, MM, MI, MIS, OS, OSS}, Memory_Data) {
+    d_sendDataMsg;
+    q_popMemQueue;
+  }
+
+  transition({I, S, O, M, IS, SS, OO, MO, MM, MI, MIS, OS, OSS}, Memory_Ack) {
+    //a_sendAck;
+    q_popMemQueue;
+  }
+
 }
diff --git a/src/mem/protocol/MOESI_CMP_directory-dma.sm b/src/mem/protocol/MOESI_CMP_directory-dma.sm
new file mode 100644 (file)
index 0000000..74246c7
--- /dev/null
@@ -0,0 +1,267 @@
+
+machine(DMA, "DMA Controller") 
+: int request_latency,
+  int response_latency
+{
+  
+  MessageBuffer goo1, network="From", virtual_network="0", ordered="false";
+  MessageBuffer goo2, network="From", virtual_network="1", ordered="false";
+  MessageBuffer responseFromDir, network="From", virtual_network="2", ordered="false";
+
+  MessageBuffer foo1, network="To", virtual_network="0", ordered="false";
+  MessageBuffer reqToDir, network="To", virtual_network="1", ordered="false";
+  MessageBuffer respToDir, network="To", virtual_network="2", ordered="false";
+  
+  enumeration(State, desc="DMA states", default="DMA_State_READY") {
+    READY, desc="Ready to accept a new request";
+    BUSY_RD,  desc="Busy: currently processing a request";
+    BUSY_WR,  desc="Busy: currently processing a request";
+  }
+  
+  enumeration(Event, desc="DMA events") {
+    ReadRequest,  desc="A new read request";
+    WriteRequest, desc="A new write request";
+    Data,         desc="Data from a DMA memory read";
+    DMA_Ack,      desc="DMA write to memory completed";
+    Inv_Ack,      desc="Invalidation Ack from a sharer";
+    All_Acks,     desc="All acks received";
+  }
+
+  structure(TBE, desc="...") {
+    Address address, desc="Physical address";
+    int NumAcks, default="0", desc="Number of Acks pending";
+    DataBlock DataBlk, desc="Data";
+  }
+
+  external_type(DMASequencer) {
+    void ackCallback();
+    void dataCallback(DataBlock);
+  }
+
+  external_type(TBETable) {
+    TBE lookup(Address);
+    void allocate(Address);
+    void deallocate(Address);
+    bool isPresent(Address);
+  }
+
+  MessageBuffer mandatoryQueue, ordered="false";
+  MessageBuffer triggerQueue, ordered="true";
+  DMASequencer dma_sequencer, factory='RubySystem::getDMASequencer(m_cfg["dma_sequencer"])';
+  TBETable TBEs, template_hack="<DMA_TBE>";
+  State cur_state;
+
+  State getState(Address addr) {
+    return cur_state;
+  }
+  void setState(Address addr, State state) {
+  cur_state := state;
+  }
+
+  out_port(reqToDirectory_out, RequestMsg, reqToDir, desc="...");
+  out_port(respToDirectory_out, ResponseMsg, respToDir, desc="...");
+  out_port(foo1_out, ResponseMsg, foo1, desc="...");
+  out_port(triggerQueue_out, TriggerMsg, triggerQueue, desc="...");
+
+  in_port(goo1_in, RequestMsg, goo1) {
+    if (goo1_in.isReady()) {
+      peek(goo1_in, RequestMsg) {
+        assert(false);
+      }
+    }
+  }
+  
+  in_port(goo2_in, RequestMsg, goo2) {
+    if (goo2_in.isReady()) {
+      peek(goo2_in, RequestMsg) {
+        assert(false);
+      }
+    }
+  }
+
+  in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") {
+    if (dmaRequestQueue_in.isReady()) {
+      peek(dmaRequestQueue_in, SequencerMsg) {
+        if (in_msg.Type == SequencerRequestType:LD ) {
+          trigger(Event:ReadRequest, in_msg.PhysicalAddress);
+        } else if (in_msg.Type == SequencerRequestType:ST) {
+          trigger(Event:WriteRequest, in_msg.PhysicalAddress);
+        } else {
+          error("Invalid request type");
+        }
+      }
+    }
+  }
+
+  in_port(dmaResponseQueue_in, ResponseMsg, responseFromDir, desc="...") {
+    if (dmaResponseQueue_in.isReady()) {
+      peek( dmaResponseQueue_in, ResponseMsg) {
+        if (in_msg.Type == CoherenceResponseType:DMA_ACK) {
+          trigger(Event:DMA_Ack, in_msg.Address);
+        } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) {
+          trigger(Event:Data, in_msg.Address);
+        } else if (in_msg.Type == CoherenceResponseType:ACK) {
+          trigger(Event:Inv_Ack, in_msg.Address);
+        } else {
+          error("Invalid response type");
+        }
+      }
+    }
+  }
+
+  // Trigger Queue
+  in_port(triggerQueue_in, TriggerMsg, triggerQueue) {
+    if (triggerQueue_in.isReady()) {
+      peek(triggerQueue_in, TriggerMsg) {
+        if (in_msg.Type == TriggerType:ALL_ACKS) {
+          trigger(Event:All_Acks, in_msg.Address);
+        } else {
+          error("Unexpected message");
+        }
+      }
+    }
+  }
+
+  action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") {
+    peek(dmaRequestQueue_in, SequencerMsg) {
+      enqueue(reqToDirectory_out, RequestMsg, latency=request_latency) {
+        out_msg.Address := address;
+        out_msg.Type := CoherenceRequestType:DMA_READ;
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.Len := in_msg.Len;
+        out_msg.Destination.add(map_Address_to_Directory(address));
+        out_msg.Requestor := machineID;
+        out_msg.MessageSize := MessageSizeType:Writeback_Control;
+      }
+    }
+  }
+
+  action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") {
+    peek(dmaRequestQueue_in, SequencerMsg) {
+      enqueue(reqToDirectory_out, RequestMsg, latency=request_latency) {
+          out_msg.Address := address;
+          out_msg.Type := CoherenceRequestType:DMA_WRITE;
+          out_msg.DataBlk := in_msg.DataBlk;
+          out_msg.Len := in_msg.Len;
+          out_msg.Destination.add(map_Address_to_Directory(address));
+          out_msg.Requestor := machineID;
+          out_msg.MessageSize := MessageSizeType:Writeback_Control;
+        }
+      }
+  }
+
+  action(a_ackCallback, "a", desc="Notify dma controller that write request completed") {
+      dma_sequencer.ackCallback();
+  }
+
+  action(o_checkForCompletion, "o", desc="Check if we have received all the messages required for completion") {
+    if (TBEs[address].NumAcks == 0) {
+      enqueue(triggerQueue_out, TriggerMsg) {
+        out_msg.Address := address;
+        out_msg.Type := TriggerType:ALL_ACKS;
+      }
+    }
+  }
+
+  action(u_updateAckCount, "u", desc="Update ack count") {
+    peek(dmaResponseQueue_in, ResponseMsg) {
+      TBEs[address].NumAcks := TBEs[address].NumAcks - in_msg.Acks;
+    }
+  }
+
+  action( u_sendExclusiveUnblockToDir, "\u", desc="send exclusive unblock to directory") {
+    enqueue(respToDirectory_out, ResponseMsg, latency=response_latency) {
+      out_msg.Address := address;
+      out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE;
+      out_msg.Destination.add(map_Address_to_Directory(address));
+      out_msg.MessageSize := MessageSizeType:Writeback_Control;
+    }
+  }
+
+  action(p_popRequestQueue, "p", desc="Pop request queue") {
+    dmaRequestQueue_in.dequeue();
+  }
+
+  action(p_popResponseQueue, "\p", desc="Pop request queue") {
+    dmaResponseQueue_in.dequeue();
+  }
+
+  action(p_popTriggerQueue, "pp", desc="Pop trigger queue") {
+    triggerQueue_in.dequeue();
+  }
+
+  action(t_updateTBEData, "t", desc="Update TBE Data") {
+    peek(dmaResponseQueue_in, ResponseMsg) {
+      TBEs[address].DataBlk := in_msg.DataBlk;
+    }
+  }
+
+  action(d_dataCallbackFromTBE, "/d", desc="data callback with data from TBE") {
+    dma_sequencer.dataCallback(TBEs[address].DataBlk);
+  }
+
+  action(v_allocateTBE, "v", desc="Allocate TBE entry") {
+    TBEs.allocate(address);
+  }
+
+  action(w_deallocateTBE, "w", desc="Deallocate TBE entry") {
+    TBEs.deallocate(address);
+  }
+
+  action(z_stall, "z", desc="dma is busy..stall") {
+    // do nothing
+  }
+
+
+
+  transition(READY, ReadRequest, BUSY_RD) {
+    s_sendReadRequest;
+    v_allocateTBE;
+    p_popRequestQueue;
+  }
+
+  transition(BUSY_RD, Inv_Ack) {
+    u_updateAckCount;
+    o_checkForCompletion;
+    p_popResponseQueue;
+  }
+
+  transition(BUSY_RD, Data) {
+    t_updateTBEData;
+    u_updateAckCount;
+    o_checkForCompletion;
+    p_popResponseQueue;
+  }
+
+  transition(BUSY_RD, All_Acks, READY) {
+    d_dataCallbackFromTBE;
+    u_sendExclusiveUnblockToDir;
+    w_deallocateTBE;
+    p_popTriggerQueue;
+  }
+
+  transition(READY, WriteRequest, BUSY_WR) {
+    s_sendWriteRequest;
+    v_allocateTBE;
+    p_popRequestQueue;
+  }
+
+  transition(BUSY_WR, Inv_Ack) {
+    u_updateAckCount;
+    o_checkForCompletion;
+    p_popResponseQueue;
+  }
+
+  transition(BUSY_WR, DMA_Ack) {
+    u_updateAckCount; // actually increases
+    o_checkForCompletion;
+    p_popResponseQueue;
+  }
+
+  transition(BUSY_WR, All_Acks, READY) {
+    a_ackCallback; 
+    u_sendExclusiveUnblockToDir;
+    w_deallocateTBE;
+    p_popTriggerQueue;
+  }
+}
index 08b4abec3caa77edb989f118c468c97d473eb104..edbff0c966882291119609fec61450cd622d593b 100644 (file)
@@ -44,6 +44,9 @@ enumeration(CoherenceRequestType, desc="...") {
   WB_ACK_DATA,    desc="Writeback ack";
   WB_NACK,   desc="Writeback neg. ack";
   INV,       desc="Invalidation";
+  
+  DMA_READ,  desc="DMA Read";
+  DMA_WRITE, desc="DMA Write";
 }
 
 // CoherenceResponseType
@@ -56,6 +59,8 @@ enumeration(CoherenceResponseType, desc="...") {
   WRITEBACK_CLEAN_DATA,   desc="Clean writeback (contains data)";
   WRITEBACK_CLEAN_ACK,   desc="Clean writeback (contains no data)";
   WRITEBACK_DIRTY_DATA,   desc="Dirty writeback (contains data)";
+
+  DMA_ACK,           desc="Ack that a DMA write completed";
 }
 
 // TriggerType
@@ -72,10 +77,12 @@ structure(TriggerMsg, desc="...", interface="Message") {
 // RequestMsg (and also forwarded requests)
 structure(RequestMsg, desc="...", interface="NetworkMessage") {
   Address Address,             desc="Physical address for this request";
+  int Len,                     desc="Length of Request";
   CoherenceRequestType Type,   desc="Type of request (GetS, GetX, PutX, etc)";
   MachineID Requestor,            desc="Node who initiated the request";
   MachineType RequestorMachine,   desc="type of component";
   NetDest Destination,             desc="Multicast destination mask";
+  DataBlock DataBlk,           desc="data for the cache line (DMA WRITE request)";
   int Acks,                    desc="How many acks to expect";
   MessageSizeType MessageSize, desc="size category of the message";
   AccessModeType AccessMode,    desc="user/supervisor access type";
@@ -95,32 +102,4 @@ structure(ResponseMsg, desc="...", interface="NetworkMessage") {
   MessageSizeType MessageSize, desc="size category of the message";
 }
 
-GenericRequestType convertToGenericType(CoherenceRequestType type) {
-  if(type == CoherenceRequestType:PUTX) {
-    return GenericRequestType:PUTX;
-  } else if(type == CoherenceRequestType:GETS) {
-    return GenericRequestType:GETS;
-  } else if(type == CoherenceRequestType:GETX) {
-    return GenericRequestType:GETX;
-  } else if(type == CoherenceRequestType:PUTS) {
-    return GenericRequestType:PUTS;
-  } else if(type == CoherenceRequestType:PUTX) {
-    return GenericRequestType:PUTS;
-  } else if(type == CoherenceRequestType:PUTO) {
-    return GenericRequestType:PUTO;
-  } else if(type == CoherenceRequestType:PUTO_SHARERS) {
-    return GenericRequestType:PUTO;
-  } else if(type == CoherenceRequestType:INV) {
-    return GenericRequestType:INV;
-  } else if(type == CoherenceRequestType:WB_ACK) {
-    return GenericRequestType:WB_ACK;
-  } else if(type == CoherenceRequestType:WB_ACK_DATA) {
-    return GenericRequestType:WB_ACK;
-  } else if(type == CoherenceRequestType:WB_NACK) {
-    return GenericRequestType:NACK;
-  } else {
-    DEBUG_EXPR(type);
-    error("invalid CoherenceRequestType");
-  }
-}
 
index c552d7157542c8337606489115ae8ed1d62fa857..f288aa4b0539707b3b81de7a41b74a763242ccba 100644 (file)
@@ -1,5 +1,6 @@
 MOESI_CMP_directory-msg.sm
 MOESI_CMP_directory-L2cache.sm
 MOESI_CMP_directory-L1cache.sm
+MOESI_CMP_directory-dma.sm
 MOESI_CMP_directory-dir.sm
 standard_CMP-protocol.sm
diff --git a/src/mem/protocol/MOESI_CMP_directory_m-dir.sm b/src/mem/protocol/MOESI_CMP_directory_m-dir.sm
deleted file mode 100644 (file)
index 3a4d875..0000000
+++ /dev/null
@@ -1,652 +0,0 @@
-
-/*
- * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- */
-
-machine(Directory, "Directory protocol") {
-
-  // ** IN QUEUES **
-  MessageBuffer foo1, network="From", virtual_network="0", ordered="false";  // a mod-L2 bank -> this Dir
-  MessageBuffer requestToDir, network="From", virtual_network="1", ordered="false";  // a mod-L2 bank -> this Dir
-  MessageBuffer responseToDir, network="From", virtual_network="2", ordered="false";  // a mod-L2 bank -> this Dir
-
-  MessageBuffer goo1, network="To", virtual_network="0", ordered="false";
-  MessageBuffer forwardFromDir, network="To", virtual_network="1", ordered="false";
-  MessageBuffer responseFromDir, network="To", virtual_network="2", ordered="false";  // Dir -> mod-L2 bank
-
-
-  // STATES
-  enumeration(State, desc="Directory states", default="Directory_State_I") {
-    // Base states
-    I, desc="Invalid";
-    S, desc="Shared";
-    O, desc="Owner";
-    M, desc="Modified";
-
-    IS, desc="Blocked, was in idle";
-    SS, desc="Blocked, was in shared";
-    OO, desc="Blocked, was in owned";
-    MO, desc="Blocked, going to owner or maybe modified";
-    MM, desc="Blocked, going to modified";
-
-    MI, desc="Blocked on a writeback";
-    MIS, desc="Blocked on a writeback, but don't remove from sharers when received";
-    OS, desc="Blocked on a writeback";
-    OSS, desc="Blocked on a writeback, but don't remove from sharers when received";
-  }
-
-  // Events
-  enumeration(Event, desc="Directory events") {
-    GETX, desc="A GETX arrives";
-    GETS, desc="A GETS arrives";
-    PUTX, desc="A PUTX arrives";
-    PUTO, desc="A PUTO arrives";
-    PUTO_SHARERS, desc="A PUTO arrives, but don't remove from sharers list";
-    Unblock, desc="An unblock message arrives";
-    Last_Unblock, desc="An unblock message arrives, we're not waiting for any additional unblocks";
-    Exclusive_Unblock, desc="The processor become the exclusive owner (E or M) of the line";
-    Clean_Writeback, desc="The final message as part of a PutX/PutS, no data";
-    Dirty_Writeback, desc="The final message as part of a PutX/PutS, contains data";
-    Memory_Data,   desc="Fetched data from memory arrives";
-    Memory_Ack,    desc="Writeback Ack from memory arrives";
-  }
-
-  // TYPES
-
-  // DirectoryEntry
-  structure(Entry, desc="...") {
-    State DirectoryState,          desc="Directory state";
-    DataBlock DataBlk,             desc="data for the block";
-    NetDest Sharers,                   desc="Sharers for this block";
-    NetDest Owner,                     desc="Owner of this block";
-    int WaitingUnblocks,           desc="Number of acks we're waiting for";
-  }
-
-  external_type(DirectoryMemory) {
-    Entry lookup(Address);
-    bool isPresent(Address);
-  }
-
-  // to simulate detailed DRAM
-  external_type(MemoryControl, inport="yes", outport="yes") {
-
-  }
-
-
-  // ** OBJECTS **
-
-  DirectoryMemory directory, constructor_hack="i";
-  MemoryControl memBuffer, constructor_hack="i";
-
-  State getState(Address addr) {
-    return directory[addr].DirectoryState;
-  }
-
-  void setState(Address addr, State state) {
-    if (directory.isPresent(addr)) {
-
-      if (state == State:I) {
-        assert(directory[addr].Owner.count() == 0);
-        assert(directory[addr].Sharers.count() == 0);
-      }
-
-      if (state == State:S) {
-        assert(directory[addr].Owner.count() == 0);
-      }
-
-      if (state == State:O) {
-        assert(directory[addr].Owner.count() == 1);
-        assert(directory[addr].Sharers.isSuperset(directory[addr].Owner) == false);
-      }
-
-      if (state == State:M) {
-        assert(directory[addr].Owner.count() == 1);
-        assert(directory[addr].Sharers.count() == 0);
-      }
-
-      if ((state != State:SS) && (state != State:OO)) {
-        assert(directory[addr].WaitingUnblocks == 0);
-      }
-
-      if ( (directory[addr].DirectoryState != State:I) && (state == State:I) ) {
-        directory[addr].DirectoryState := state;
-         // disable coherence checker
-        // sequencer.checkCoherence(addr);
-      }
-      else {
-        directory[addr].DirectoryState := state;
-      }
-    }
-  }
-
-  // if no sharers, then directory can be considered both a sharer and exclusive w.r.t. coherence checking
-  bool isBlockShared(Address addr) {
-    if (directory.isPresent(addr)) {
-      if (directory[addr].DirectoryState == State:I) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  bool isBlockExclusive(Address addr) {
-    if (directory.isPresent(addr)) {
-      if (directory[addr].DirectoryState == State:I) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-
-  // ** OUT_PORTS **
-  out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
-  out_port(responseNetwork_out, ResponseMsg, responseFromDir);
-//  out_port(requestQueue_out, ResponseMsg, requestFromDir); // For recycling requests
-  out_port(goo1_out, ResponseMsg, goo1);
-  out_port(memQueue_out, MemoryMsg, memBuffer);
-
-  // ** IN_PORTS **
-
-  in_port(foo1_in, ResponseMsg, foo1) {
-
-  }
-
-  // in_port(unblockNetwork_in, ResponseMsg, unblockToDir) {
-  //  if (unblockNetwork_in.isReady()) {
-  in_port(unblockNetwork_in, ResponseMsg, responseToDir) {
-    if (unblockNetwork_in.isReady()) {
-      peek(unblockNetwork_in, ResponseMsg) {
-        if (in_msg.Type == CoherenceResponseType:UNBLOCK) {
-          if (directory[in_msg.Address].WaitingUnblocks == 1) {
-            trigger(Event:Last_Unblock, in_msg.Address);
-          } else {
-            trigger(Event:Unblock, in_msg.Address);
-          }
-        } else if (in_msg.Type == CoherenceResponseType:UNBLOCK_EXCLUSIVE) {
-          trigger(Event:Exclusive_Unblock, in_msg.Address);
-        } else if (in_msg.Type == CoherenceResponseType:WRITEBACK_DIRTY_DATA) {
-          trigger(Event:Dirty_Writeback, in_msg.Address);
-        } else if (in_msg.Type == CoherenceResponseType:WRITEBACK_CLEAN_ACK) {
-          trigger(Event:Clean_Writeback, in_msg.Address);
-        } else {
-          error("Invalid message");
-        }
-      }
-    }
-  }
-
-  in_port(requestQueue_in, RequestMsg, requestToDir) {
-    if (requestQueue_in.isReady()) {
-      peek(requestQueue_in, RequestMsg) {
-        if (in_msg.Type == CoherenceRequestType:GETS) {
-          trigger(Event:GETS, in_msg.Address);
-        } else if (in_msg.Type == CoherenceRequestType:GETX) {
-          trigger(Event:GETX, in_msg.Address);
-        } else if (in_msg.Type == CoherenceRequestType:PUTX) {
-          trigger(Event:PUTX, in_msg.Address);
-        } else if (in_msg.Type == CoherenceRequestType:PUTO) {
-          trigger(Event:PUTO, in_msg.Address);
-        } else if (in_msg.Type == CoherenceRequestType:PUTO_SHARERS) {
-          trigger(Event:PUTO_SHARERS, in_msg.Address);
-        } else {
-          error("Invalid message");
-        }
-      }
-    }
-  }
-
-  // off-chip memory request/response is done
-  in_port(memQueue_in, MemoryMsg, memBuffer) {
-    if (memQueue_in.isReady()) {
-      peek(memQueue_in, MemoryMsg) {
-        if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
-          trigger(Event:Memory_Data, in_msg.Address);
-        } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) {
-          trigger(Event:Memory_Ack, in_msg.Address);
-        } else {
-          DEBUG_EXPR(in_msg.Type);
-          error("Invalid message");
-        }
-      }
-    }
-  }
-
-  // Actions
-
-  action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") {
-    peek(requestQueue_in, RequestMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
-        out_msg.Address := address;
-        out_msg.Type := CoherenceRequestType:WB_ACK;
-        out_msg.Requestor := in_msg.Requestor;
-        out_msg.Destination.add(in_msg.Requestor);
-        out_msg.MessageSize := MessageSizeType:Writeback_Control;
-      }
-    }
-  }
-
-  action(b_sendWriteBackNack, "b", desc="Send writeback nack to requestor") {
-    peek(requestQueue_in, RequestMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
-        out_msg.Address := address;
-        out_msg.Type := CoherenceRequestType:WB_NACK;
-        out_msg.Requestor := in_msg.Requestor;
-        out_msg.Destination.add(in_msg.Requestor);
-        out_msg.MessageSize := MessageSizeType:Writeback_Control;
-      }
-    }
-  }
-
-  action(c_clearOwner, "c", desc="Clear the owner field") {
-    directory[address].Owner.clear();
-  }
-
-  action(c_moveOwnerToSharer, "cc", desc="Move owner to sharers") {
-    directory[address].Sharers.addNetDest(directory[address].Owner);
-    directory[address].Owner.clear();
-  }
-
-  action(cc_clearSharers, "\c", desc="Clear the sharers field") {
-    directory[address].Sharers.clear();
-  }
-
-  action(d_sendDataMsg, "d", desc="Send data to requestor") {
-    peek(memQueue_in, MemoryMsg) {
-      enqueue(responseNetwork_out, ResponseMsg, latency="1") {
-        out_msg.Address := address;
-        out_msg.Sender := machineID;
-        out_msg.SenderMachine := MachineType:Directory;
-        out_msg.Destination.add(in_msg.OriginalRequestorMachId);
-        //out_msg.DataBlk := directory[in_msg.Address].DataBlk;
-        out_msg.DataBlk := in_msg.DataBlk;
-        out_msg.Dirty := false; // By definition, the block is now clean
-        out_msg.Acks := in_msg.Acks;
-        if (in_msg.ReadX) {
-          out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
-        } else {
-          out_msg.Type := CoherenceResponseType:DATA;
-        }
-        out_msg.MessageSize := MessageSizeType:Response_Data;
-      }
-    }
-  }
-
-  action(e_ownerIsUnblocker, "e", desc="The owner is now the unblocker") {
-    peek(unblockNetwork_in, ResponseMsg) {
-      directory[address].Owner.clear();
-      directory[address].Owner.add(in_msg.Sender);
-    }
-  }
-
-  action(f_forwardRequest, "f", desc="Forward request to owner") {
-    peek(requestQueue_in, RequestMsg) {
-      enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
-        out_msg.Address := address;
-        out_msg.Type := in_msg.Type;
-        out_msg.Requestor := in_msg.Requestor;
-        out_msg.Destination.addNetDest(directory[in_msg.Address].Owner);
-        out_msg.Acks := directory[address].Sharers.count();
-        if (directory[address].Sharers.isElement(in_msg.Requestor)) {
-          out_msg.Acks := out_msg.Acks - 1;
-        }
-        out_msg.MessageSize := MessageSizeType:Forwarded_Control;
-      }
-    }
-  }
-
-  action(g_sendInvalidations, "g", desc="Send invalidations to sharers, not including the requester") {
-    peek(requestQueue_in, RequestMsg) {
-      if ((directory[in_msg.Address].Sharers.count() > 1) ||
-          ((directory[in_msg.Address].Sharers.count() > 0) && (directory[in_msg.Address].Sharers.isElement(in_msg.Requestor) == false))) {
-        enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") {
-          out_msg.Address := address;
-          out_msg.Type := CoherenceRequestType:INV;
-          out_msg.Requestor := in_msg.Requestor;
-          // out_msg.Destination := directory[in_msg.Address].Sharers;
-          out_msg.Destination.addNetDest(directory[in_msg.Address].Sharers);
-          out_msg.Destination.remove(in_msg.Requestor);
-          out_msg.MessageSize := MessageSizeType:Invalidate_Control;
-        }
-      }
-    }
-  }
-
-  action(i_popIncomingRequestQueue, "i", desc="Pop incoming request queue") {
-    requestQueue_in.dequeue();
-  }
-
-  action(j_popIncomingUnblockQueue, "j", desc="Pop incoming unblock queue") {
-    unblockNetwork_in.dequeue();
-  }
-
-  action(l_writeDataToMemory, "l", desc="Write PUTX/PUTO data to memory") {
-    peek(unblockNetwork_in, ResponseMsg) {
-      assert(in_msg.Dirty);
-      assert(in_msg.MessageSize == MessageSizeType:Writeback_Data);
-      directory[in_msg.Address].DataBlk := in_msg.DataBlk;
-      DEBUG_EXPR(in_msg.Address);
-      DEBUG_EXPR(in_msg.DataBlk);
-    }
-  }
-
-  action(ll_checkDataInMemory, "\l", desc="Check PUTX/PUTO data is same as in the memory") {
-    peek(unblockNetwork_in, ResponseMsg) {
-      assert(in_msg.Dirty == false);
-      assert(in_msg.MessageSize == MessageSizeType:Writeback_Control);
-
-      // NOTE: The following check would not be valid in a real
-      // implementation.  We include the data in the "dataless"
-      // message so we can assert the clean data matches the datablock
-      // in memory
-      assert(directory[in_msg.Address].DataBlk == in_msg.DataBlk);
-    }
-  }
-
-  action(m_addUnlockerToSharers, "m", desc="Add the unlocker to the sharer list") {
-    peek(unblockNetwork_in, ResponseMsg) {
-      directory[address].Sharers.add(in_msg.Sender);
-    }
-  }
-
-  action(n_incrementOutstanding, "n", desc="Increment outstanding requests") {
-    directory[address].WaitingUnblocks := directory[address].WaitingUnblocks + 1;
-  }
-
-  action(o_decrementOutstanding, "o", desc="Decrement outstanding requests") {
-    directory[address].WaitingUnblocks := directory[address].WaitingUnblocks - 1;
-    assert(directory[address].WaitingUnblocks >= 0);
-  }
-
-  action(q_popMemQueue, "q", desc="Pop off-chip request queue") {
-    memQueue_in.dequeue();
-  }
-
-  action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
-    peek(requestQueue_in, RequestMsg) {
-      enqueue(memQueue_out, MemoryMsg, latency="1") {
-        out_msg.Address := address;
-        out_msg.Type := MemoryRequestType:MEMORY_READ;
-        out_msg.Sender := machineID;
-        out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.DataBlk := directory[in_msg.Address].DataBlk;
-        out_msg.MessageSize := in_msg.MessageSize;
-        //out_msg.Prefetch := false;
-        // These are not used by memory but are passed back here with the read data:
-        out_msg.ReadX := (in_msg.Type == CoherenceRequestType:GETS && directory[address].Sharers.count() == 0);
-        out_msg.Acks := directory[address].Sharers.count();
-        if (directory[address].Sharers.isElement(in_msg.Requestor)) {
-          out_msg.Acks := out_msg.Acks - 1;
-        }
-        DEBUG_EXPR(out_msg);
-      }
-    }
-  }
-
-  action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") {
-    peek(unblockNetwork_in, ResponseMsg) {
-      enqueue(memQueue_out, MemoryMsg, latency="1") {
-        out_msg.Address := address;
-        out_msg.Type := MemoryRequestType:MEMORY_WB;
-        out_msg.Sender := machineID;
-        //out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.DataBlk := in_msg.DataBlk;
-        out_msg.MessageSize := in_msg.MessageSize;
-        //out_msg.Prefetch := false;
-        // Not used:
-        out_msg.ReadX := false;
-        out_msg.Acks := 0;
-        DEBUG_EXPR(out_msg);
-      }
-    }
-  }
-
-
-  //  action(z_stall, "z", desc="Cannot be handled right now.") {
-    // Special name recognized as do nothing case
-  //  }
-
-  action(zz_recycleRequest, "\z", desc="Recycle the request queue") {
-    requestQueue_in.recycle();
-  }
-
-  // TRANSITIONS
-
-  transition(I, GETX, MM) {
-    qf_queueMemoryFetchRequest;
-    i_popIncomingRequestQueue;
-  }
-
-  transition(S, GETX, MM) {
-    qf_queueMemoryFetchRequest;
-    g_sendInvalidations;
-    i_popIncomingRequestQueue;
-  }
-
-  transition(I, GETS, IS) {
-    qf_queueMemoryFetchRequest;
-    i_popIncomingRequestQueue;
-  }
-
-  transition({S, SS}, GETS, SS) {
-    qf_queueMemoryFetchRequest;
-    n_incrementOutstanding;
-    i_popIncomingRequestQueue;
-  }
-
-  transition({I, S}, PUTO) {
-    b_sendWriteBackNack;
-    i_popIncomingRequestQueue;
-  }
-
-  transition({I, S, O}, PUTX) {
-    b_sendWriteBackNack;
-    i_popIncomingRequestQueue;
-  }
-
-  transition(O, GETX, MM) {
-    f_forwardRequest;
-    g_sendInvalidations;
-    i_popIncomingRequestQueue;
-  }
-
-  transition({O, OO}, GETS, OO) {
-    f_forwardRequest;
-    n_incrementOutstanding;
-    i_popIncomingRequestQueue;
-  }
-
-  transition(M, GETX, MM) {
-    f_forwardRequest;
-    i_popIncomingRequestQueue;
-  }
-
-  transition(M, GETS, MO) {
-    f_forwardRequest;
-    i_popIncomingRequestQueue;
-  }
-
-  transition(M, PUTX, MI) {
-    a_sendWriteBackAck;
-    i_popIncomingRequestQueue;
-  }
-
-  // happens if M->O transition happens on-chip
-  transition(M, PUTO, MI) {
-    a_sendWriteBackAck;
-    i_popIncomingRequestQueue;
-  }
-
-  transition(M, PUTO_SHARERS, MIS) {
-    a_sendWriteBackAck;
-    i_popIncomingRequestQueue;
-  }
-
-  transition(O, PUTO, OS) {
-    a_sendWriteBackAck;
-    i_popIncomingRequestQueue;
-  }
-
-  transition(O, PUTO_SHARERS, OSS) {
-    a_sendWriteBackAck;
-    i_popIncomingRequestQueue;
-  }
-
-
-  transition({MM, MO, MI, MIS, OS, OSS}, {GETS, GETX, PUTO, PUTO_SHARERS, PUTX}) {
-    zz_recycleRequest;
-  }
-
-  transition({MM, MO}, Exclusive_Unblock, M) {
-    cc_clearSharers;
-    e_ownerIsUnblocker;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(MO, Unblock, O) {
-    m_addUnlockerToSharers;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition({IS, SS, OO}, {GETX, PUTO, PUTO_SHARERS, PUTX}) {
-    zz_recycleRequest;
-  }
-
-  transition(IS, GETS) {
-    zz_recycleRequest;
-  }
-
-  transition(IS, Unblock, S) {
-    m_addUnlockerToSharers;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(IS, Exclusive_Unblock, M) {
-    cc_clearSharers;
-    e_ownerIsUnblocker;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(SS, Unblock) {
-    m_addUnlockerToSharers;
-    o_decrementOutstanding;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(SS, Last_Unblock, S) {
-    m_addUnlockerToSharers;
-    o_decrementOutstanding;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(OO, Unblock) {
-    m_addUnlockerToSharers;
-    o_decrementOutstanding;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(OO, Last_Unblock, O) {
-    m_addUnlockerToSharers;
-    o_decrementOutstanding;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(MI, Dirty_Writeback, I) {
-    c_clearOwner;
-    cc_clearSharers;
-    l_writeDataToMemory;
-    qw_queueMemoryWBRequest;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(MIS, Dirty_Writeback, S) {
-    c_moveOwnerToSharer;
-    l_writeDataToMemory;
-    qw_queueMemoryWBRequest;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(MIS, Clean_Writeback, S) {
-    c_moveOwnerToSharer;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(OS, Dirty_Writeback, S) {
-    c_clearOwner;
-    l_writeDataToMemory;
-    qw_queueMemoryWBRequest;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(OSS, Dirty_Writeback, S) {
-    c_moveOwnerToSharer;
-    l_writeDataToMemory;
-    qw_queueMemoryWBRequest;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(OSS, Clean_Writeback, S) {
-    c_moveOwnerToSharer;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(MI, Clean_Writeback, I) {
-    c_clearOwner;
-    cc_clearSharers;
-    ll_checkDataInMemory;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition(OS, Clean_Writeback, S) {
-    c_clearOwner;
-    ll_checkDataInMemory;
-    j_popIncomingUnblockQueue;
-  }
-
-  transition({MI, MIS}, Unblock, M) {
-    j_popIncomingUnblockQueue;
-  }
-
-  transition({OS, OSS}, Unblock, O) {
-    j_popIncomingUnblockQueue;
-  }
-
-  transition({I, S, O, M, IS, SS, OO, MO, MM, MI, MIS, OS, OSS}, Memory_Data) {
-    d_sendDataMsg;
-    q_popMemQueue;
-  }
-
-  transition({I, S, O, M, IS, SS, OO, MO, MM, MI, MIS, OS, OSS}, Memory_Ack) {
-    //a_sendAck;
-    q_popMemQueue;
-  }
-
-}
diff --git a/src/mem/protocol/MOESI_CMP_directory_m.slicc b/src/mem/protocol/MOESI_CMP_directory_m.slicc
deleted file mode 100644 (file)
index 3abe860..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-MOESI_CMP_directory-msg.sm
-MOESI_CMP_directory-L2cache.sm
-MOESI_CMP_directory-L1cache.sm
-MOESI_CMP_directory_m-dir.sm
-standard_CMP-protocol.sm
index 022bb6862c99fa3fa738b853c132d603965260cd..559e54a8c876fcf71bf12bf07d027dbb6d7d980a 100644 (file)
 // Mapping functions
 
 // NodeID map_address_to_node(Address addr);
+MachineID mapAddressToRange(Address addr, MachineType type, int low, int high);
 MachineID map_Address_to_DMA(Address addr);
 MachineID map_Address_to_Directory(Address addr);
 NodeID map_Address_to_DirectoryNode(Address addr);
-MachineID map_Address_to_CentralArbiterNode(Address addr);
-NodeID oldmap_L1RubyNode_to_L2Cache(Address addr, NodeID L1RubyNode);
-MachineID map_L1CacheMachId_to_L2Cache(Address addr, MachineID L1CacheMachId);
-MachineID map_L2ChipId_to_L2Cache(Address addr, NodeID L2ChipId);
-// MachineID map_L1RubyNode_to_Arb(NodeID L1RubyNode);
+
 
 MachineID getL1MachineID(NodeID L1RubyNode);
 NodeID getChipID(MachineID L2machID);
index a8b58b96cce9452417505aaff694c2178efc6cb4..412fd0de0700e892906bc5b33e16208eeaca9682 100644 (file)
@@ -39,7 +39,10 @@ external_type(string, primitive="yes");
 external_type(uint64, primitive="yes");
 external_type(Time, primitive="yes", default="0");
 external_type(Address);
-
+external_type(DataBlock, desc="..."){
+  void clear();
+  void copyPartial(DataBlock, int, int);
+}
 
 // Declarations of external types that are common to all protocols
 
@@ -131,12 +134,12 @@ enumeration(CacheRequestType, desc="...", default="CacheRequestType_NULL") {
   IO,          desc="I/O";
   REPLACEMENT, desc="Replacement";
   COMMIT,      desc="Commit version";
-  LD_XACT,     desc="Transactional Load";
-  LDX_XACT,    desc="Transactional Load-Intend-To-Modify";
-  ST_XACT,     desc="Transactional Store";
-  BEGIN_XACT,  desc="Begin Transaction";
-  COMMIT_XACT, desc="Commit Transaction";
-  ABORT_XACT,  desc="Abort Transaction";
+  NULL,        desc="Invalid request type";
+}
+
+enumeration(SequencerRequestType, desc="...", default="SequencerRequestType_NULL") {
+  LD,          desc="Load";
+  ST,          desc="Store";
   NULL,        desc="Invalid request type";
 }
 
@@ -167,7 +170,9 @@ enumeration(GenericRequestType, desc="...", default="GenericRequestType_NULL") {
   ST_XACT,     desc="Transactional Store";
   BEGIN_XACT,  desc="Begin Transaction";
   COMMIT_XACT, desc="Commit Transaction";
-  ABORT_XACT,  desc="Abort Transaction";
+  ABORT_XACT,  desc="Abort Transaction";       
+  DMA_READ,    desc="DMA READ";
+  DMA_WRITE,   desc="DMA WRITE";
   NULL,        desc="null request type";
 }
 
@@ -232,6 +237,18 @@ structure(CacheMsg, desc="...", interface="Message") {
   PrefetchBit Prefetch,      desc="Is this a prefetch request";
 }
 
+// CacheMsg
+structure(SequencerMsg, desc="...", interface="Message") {
+  Address LineAddress,       desc="Line address for this request";
+  Address PhysicalAddress,   desc="Physical address for this request";
+  SequencerRequestType Type,     desc="Type of request (LD, ST, etc)";
+  Address ProgramCounter,    desc="Program counter of the instruction that caused the miss";
+  AccessModeType AccessMode, desc="user/supervisor access type";
+  DataBlock DataBlk,         desc="Data";
+  int Len,                   desc="size in bytes of access";
+  PrefetchBit Prefetch,      desc="Is this a prefetch request";
+}
+
 // MaskPredictorType
 enumeration(MaskPredictorType, "MaskPredictorType_Undefined", desc="...") {
   Undefined, desc="Undefined";
index 7a7fbdae1579e5350d174412bf3a37f28a5a5ce6..d360af160378e682049cd9760783d3854215a69d 100644 (file)
@@ -34,7 +34,7 @@ void profileCacheCLBsize(int size, int numStaleI);
 void profileMemoryCLBsize(int size, int numStaleI);
 
 // used by 2level exclusive cache protocols
-void profile_miss(CacheMsg msg, NodeID id);
+void profile_miss(CacheMsg msg);
 
 // used by non-fast path protocols
 void profile_L1Cache_miss(CacheMsg msg, NodeID l1cacheID);
index aa5648a9e600fabd55191529dbb57988441269f6..9679b7b6f3ecf6160a5569f8ebeb1d3b36f4226c 100644 (file)
 
 // External Types
 
-external_type(DataBlock, desc="..."){
-  void clear();
-  void copyPartial(DataBlock, int, int);
-}
-
 external_type(MessageBuffer, buffer="yes", inport="yes", outport="yes");
 
 external_type(OutPort, primitive="yes");
index 7f7ebf5edf35c9dc90002c076ce27a243bb82f1d..b37725402228501987307d72e68182b08795ca67 100644 (file)
@@ -57,5 +57,5 @@ int N_tokens();
 bool distributedPersistentEnabled();
 Address setOffset(Address addr, int offset);
 Address makeLineAddress(Address addr);
-
+int addressOffset(Address addr);
 
index d43e384e5ad39eaf9dc3c0cb265a59fe694dc548..451281f20e3dbae64c961e6f40838e67e09acd68 100644 (file)
@@ -17,11 +17,16 @@ L1_CACHE_LATENCY = 1
 num_memories = 2
 memory_size_mb = 1024
 NUM_DMA = 1
+protocol = "MI_example"
 
 # check for overrides
 
+
 for i in 0..$*.size-1 do
-  if $*[i] == "-p"
+  if $*[i] == "-c"
+    protocol = $*[i+1]
+    i = i+1
+  elsif $*[i] == "-p"
     num_cores = $*[i+1].to_i
     i = i+1
   elsif $*[i] == "-m"
@@ -36,13 +41,17 @@ end
 net_ports = Array.new
 iface_ports = Array.new
 
+assert(protocol == "MI_example", __FILE__ + " cannot be used with protocol " + protocol)
+
+require protocol+".rb"
+
 num_cores.times { |n|
   cache = SetAssociativeCache.new("l1u_"+n.to_s, L1_CACHE_SIZE_KB, L1_CACHE_LATENCY, L1_CACHE_ASSOC, "PSEUDO_LRU")
   sequencer = Sequencer.new("Sequencer_"+n.to_s, cache, cache)
   iface_ports << sequencer
   net_ports << MI_example_CacheController.new("L1CacheController_"+n.to_s,
                                    "L1Cache",
-                                   [cache],
+                                   cache,
                                    sequencer)
 }
 num_memories.times { |n|
@@ -55,7 +64,7 @@ num_memories.times { |n|
 NUM_DMA.times { |n|
   dma_sequencer = DMASequencer.new("DMASequencer_"+n.to_s)
   iface_ports << dma_sequencer
-  net_ports << DMAController.new("DMAController_"+n.to_s, "DMA", dma_sequencer)
+  net_ports << MI_example_DMAController.new("DMAController_"+n.to_s, "DMA", dma_sequencer)
 }
 
 topology = CrossbarTopology.new("theTopology", net_ports)
diff --git a/src/mem/ruby/config/MI_example.rb b/src/mem/ruby/config/MI_example.rb
new file mode 100644 (file)
index 0000000..3196bb6
--- /dev/null
@@ -0,0 +1,35 @@
+
+class MI_example_CacheController < L1CacheController
+  attr :cache
+  def initialize(obj_name, mach_type, cache, sequencer)
+    super(obj_name, mach_type, [cache], sequencer)
+    @cache = cache
+  end
+  def argv()
+    vec = super()
+    vec += " cache " + @cache.obj_name
+    vec += " issue_latency "+issue_latency.to_s
+    vec += " cache_response_latency "+cache_response_latency.to_s
+  end
+
+end
+
+class MI_example_DirectoryController < DirectoryController
+  def initialize(obj_name, mach_type, directory, memory_control)
+    super(obj_name, mach_type, directory, memory_control)
+  end
+  def argv()
+    vec = super()
+    vec += " directory_latency "+directory_latency.to_s
+  end
+end
+
+class MI_example_DMAController < DMAController
+  def initialize(obj_name, mach_type, dma_sequencer)
+    super(obj_name, mach_type, dma_sequencer)
+  end
+  def argv()
+    vec = super
+    vec += " request_latency "+request_latency.to_s
+  end
+end
diff --git a/src/mem/ruby/config/MOESI_CMP_directory.rb b/src/mem/ruby/config/MOESI_CMP_directory.rb
new file mode 100644 (file)
index 0000000..936eb8e
--- /dev/null
@@ -0,0 +1,79 @@
+
+require "cfg.rb"
+
+def log_int(n)
+  assert(n.is_a?(Fixnum), "log_int takes a number for an argument")
+  counter = 0
+  while n >= 2 do
+    counter += 1
+    n = n >> 1
+  end
+  return counter
+end
+
+
+class MOESI_CMP_directory_L1CacheController < L1CacheController
+  attr :icache, :dcache
+  attr :num_l2_controllers
+  def initialize(obj_name, mach_type, icache, dcache, sequencer, num_l2_controllers)
+    super(obj_name, mach_type, [icache, dcache], sequencer)
+    @icache = icache
+    @dcache = dcache
+    @num_l2_controllers = num_l2_controllers
+  end
+  def argv()
+    num_select_bits = log_int(num_l2_controllers)
+    num_block_bits = log_int(RubySystem.block_size_bytes)
+
+    l2_select_low_bit = num_block_bits
+    l2_select_high_bit = num_block_bits + num_select_bits - 1
+
+    vec = super()
+    vec += " icache " + @icache.obj_name
+    vec += " dcache " + @dcache.obj_name
+    vec += " request_latency "+request_latency().to_s
+    vec += " l2_select_low_bit " + l2_select_low_bit.to_s
+    vec += " l2_select_high_bit " + l2_select_high_bit.to_s
+    return vec
+  end
+end
+
+class MOESI_CMP_directory_L2CacheController < CacheController
+  attr :cache
+  def initialize(obj_name, mach_type, cache)
+    super(obj_name, mach_type, [cache])
+    @cache = cache
+  end
+  def argv()
+    vec = super()
+    vec += " cache " + @cache.obj_name
+    vec += " request_latency "+request_latency().to_s
+    vec += " response_latency "+response_latency().to_s
+    return vec
+  end
+end
+
+
+class MOESI_CMP_directory_DirectoryController < DirectoryController
+  def initialize(obj_name, mach_type, directory, memory_control)
+    super(obj_name, mach_type, directory, memory_control)
+  end
+  def argv()
+    vec = super()
+    vec += " directory_latency "+directory_latency.to_s
+    return vec
+  end
+
+end
+
+class MOESI_CMP_directory_DMAController < DMAController
+  def initialize(obj_name, mach_type, dma_sequencer)
+    super(obj_name, mach_type, dma_sequencer)
+  end
+  def argv()
+    vec = super
+    vec += " request_latency "+request_latency.to_s
+    vec += " response_latency "+response_latency.to_s
+    return vec
+  end
+end
diff --git a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb
new file mode 100644 (file)
index 0000000..11cb7fb
--- /dev/null
@@ -0,0 +1,98 @@
+#!/usr/bin/ruby
+#
+#  Creates a homogeneous CMP system with a single unified cache per
+#  core and a crossbar network.  Uses the default parameters listed
+#  below, which can be overridden using command line args.
+#
+
+require "cfg.rb"
+
+# default values
+
+num_cores = 2
+L1_ICACHE_SIZE_KB = 32
+L1_ICACHE_ASSOC = 8
+L1_ICACHE_LATENCY = 1
+L1_DCACHE_SIZE_KB = 32
+L1_DCACHE_ASSOC = 8
+L1_DCACHE_LATENCY = 1
+L2_CACHE_SIZE_KB = 2048 # total size (sum of all banks)
+L2_CACHE_ASSOC = 16
+L2_CACHE_LATENCY = 12
+num_l2_banks = num_cores
+num_memories = 1
+memory_size_mb = 1024
+NUM_DMA = 1
+
+protocol = "MOESI_CMP_directory"
+
+# check for overrides
+
+for i in 0..$*.size-1 do
+  if $*[i] == "-c" or $*[i] == "--protocol"
+    i += 1
+    protocol = $*[i]
+  elsif $*[i] == "-m"
+    num_memories = $*[i+1].to_i
+    i = i+1
+  elsif $*[i] == "-p"
+    num_cores = $*[i+1].to_i
+    i = i+1
+  elsif $*[i] == "-s"
+    memory_size_mb = $*[i+1].to_i
+    i = i + 1
+  end
+end
+
+net_ports = Array.new
+iface_ports = Array.new
+
+assert(protocol == "MOESI_CMP_directory", __FILE__+" cannot be used with protocol "+protocol);
+
+require protocol+".rb"
+
+num_cores.times { |n|
+  icache = SetAssociativeCache.new("l1i_"+n.to_s, L1_ICACHE_SIZE_KB, L1_ICACHE_LATENCY, L1_ICACHE_ASSOC, "PSEUDO_LRU")
+  dcache = SetAssociativeCache.new("l1d_"+n.to_s, L1_DCACHE_SIZE_KB, L1_DCACHE_LATENCY, L1_DCACHE_ASSOC, "PSEUDO_LRU")
+  sequencer = Sequencer.new("Sequencer_"+n.to_s, icache, dcache)
+  iface_ports << sequencer
+  if protocol == "MOESI_CMP_directory"
+    net_ports << MOESI_CMP_directory_L1CacheController.new("L1CacheController_"+n.to_s,
+                                                           "L1Cache",
+                                                           icache, dcache,
+                                                           sequencer,
+                                                           num_l2_banks)
+  end
+}
+num_l2_banks.times { |n|
+  cache = SetAssociativeCache.new("l2u_"+n.to_s, L2_CACHE_SIZE_KB/num_l2_banks, L2_CACHE_LATENCY, L2_CACHE_ASSOC, "PSEUDO_LRU")
+  if protocol == "MOESI_CMP_directory"
+    net_ports << MOESI_CMP_directory_L2CacheController.new("L2CacheController_"+n.to_s,
+                                                           "L2Cache",
+                                                           cache)
+  end
+}
+num_memories.times { |n|
+  directory = DirectoryMemory.new("DirectoryMemory_"+n.to_s, memory_size_mb/num_memories)
+  memory_control = MemoryControl.new("MemoryControl_"+n.to_s)
+  if protocol == "MOESI_CMP_directory"
+    net_ports << MOESI_CMP_directory_DirectoryController.new("DirectoryController_"+n.to_s,
+                                                             "Directory",
+                                                             directory, 
+                                                             memory_control)
+  end
+}
+NUM_DMA.times { |n|
+  dma_sequencer = DMASequencer.new("DMASequencer_"+n.to_s)
+  iface_ports << dma_sequencer
+  if protocol == "MOESI_CMP_directory"
+    net_ports << MOESI_CMP_directory_DMAController.new("DMAController_"+n.to_s,
+                                                       "DMA",
+                                                       dma_sequencer)
+  end
+}
+
+topology = CrossbarTopology.new("theTopology", net_ports)
+on_chip_net = Network.new("theNetwork", topology)
+
+RubySystem.init(iface_ports, on_chip_net)
index a43b5e125783f3638080e2aa5246d8bf79202a2b..82fbb64a55453937828624db0a53ffe8a9d38d9d 100644 (file)
@@ -233,6 +233,7 @@ class RubySystem
       end
     }
     str += LibRubyObject.printConstructors
+    #puts str.gsub('%',' ').gsub('#','\n')
     return str
   end
 
@@ -287,35 +288,33 @@ end
 
 
 class CacheController < NetPort
-  @@total_cache_controllers = 0
-  attr :caches
-  attr :sequencer
-  def initialize(obj_name, mach_type, caches, sequencer)
+  @@total_cache_controllers = Hash.new
+
+  def initialize(obj_name, mach_type, caches)
     super(obj_name, mach_type)
-    @caches = caches
-    @caches.each { |cache|
+    caches.each { |cache|
       cache.controller = self
     }
 
-    @sequencer = sequencer
-    @sequencer.controller = self
-
-    @version = @@total_cache_controllers
-    @@total_cache_controllers += 1
-    @sequencer.version = @version
-    buffer_size()
+    if !@@total_cache_controllers.has_key?(mach_type)
+      @@total_cache_controllers[mach_type] = 0
+    end
+    @version = @@total_cache_controllers[mach_type]
+    @@total_cache_controllers[mach_type] += 1
+    
+    # call inhereted parameters
+    transitions_per_cycle
+    buffer_size
+    number_of_TBEs
+    recycle_latency
   end
 
   def argv()
     vec = "version "+@version.to_s
-    @caches.each { |cache|
-      vec += " cache " + cache.obj_name
-    }
-    vec += " sequencer "+@sequencer.obj_name
     vec += " transitions_per_cycle "+@params[:transitions_per_cycle].to_s
     vec += " buffer_size "+@params[:buffer_size].to_s
     vec += " number_of_TBEs "+@params[:number_of_TBEs].to_s
-
+    vec += " recycle_latency "+@params[:recycle_latency].to_s
   end
 
   def cppClassName()
@@ -323,6 +322,23 @@ class CacheController < NetPort
   end
 end
 
+class L1CacheController < CacheController
+  attr :sequencer
+
+  def initialize(obj_name, mach_type, caches, sequencer)
+    super(obj_name, mach_type, caches)
+
+    @sequencer = sequencer
+    @sequencer.controller = self
+    @sequencer.version = @version
+  end
+
+  def argv()
+    vec = super()
+    vec += " sequencer "+@sequencer.obj_name
+  end
+end
+
 class DirectoryController < NetPort
   @@total_directory_controllers = 0
   attr :directory
@@ -364,7 +380,7 @@ class DMAController < NetPort
   end
 
   def argv()
-    "version "+@version.to_s+" dma_sequencer "+@dma_sequencer.obj_name+" transitions_per_cycle "+@params[:transitions_per_cycle].to_s + " buffer_size "+@params[:buffer_size].to_s + " number_of_TBEs "+@params[:number_of_TBEs].to_s
+    "version "+@version.to_s+" dma_sequencer "+@dma_sequencer.obj_name+" transitions_per_cycle "+@params[:transitions_per_cycle].to_s + " buffer_size "+@params[:buffer_size].to_s + " number_of_TBEs "+@params[:number_of_TBEs].to_s +  " recycle_latency "+@params[:recycle_latency].to_s
   end
 
   def cppClassName()
@@ -606,7 +622,7 @@ class Network < LibRubyObject
   end
 
   def printTopology()
-    topology.printFile
+    topology().printFile
   end
   def cppClassName()
     "SimpleNetwork"
@@ -686,31 +702,6 @@ class Profiler < LibRubyObject
 
 end
 
-class MI_example_CacheController < CacheController
-  def initialize(obj_name, mach_type, caches, sequencer)
-    super(obj_name, mach_type, caches, sequencer)
-  end
-  def argv()
-    vec = super()
-    vec += " issue_latency "+issue_latency.to_s
-    vec += " cache_response_latency "+cache_response_latency.to_s
-  end
-
-end
-
-class MI_example_DirectoryController < DirectoryController
-  def initialize(obj_name, mach_type, directory, memory_control)
-    super(obj_name, mach_type, directory, memory_control)
-  end
-  def argv()
-    vec = super()
-    vec += " to_mem_ctrl_latency "+to_mem_ctrl_latency.to_s
-    vec += " directory_latency "+directory_latency.to_s
-    vec += " memory_latency "+memory_latency.to_s
-  end
-
-end
-
 #added by SS
 class GarnetNetwork < Network
   def initialize(name, topo)
index e54b148e08da43346bbe8b889f6a217edfa3c989..4723df5059d74c52c15f363bac7869eec67eaea7 100644 (file)
@@ -105,19 +105,6 @@ class Profiler < LibRubyObject
   default_param :all_instructions, Boolean, false
 end
 
-#added by SS
-class MI_example_CacheController < CacheController
-  default_param :issue_latency, Integer, 2
-  default_param :cache_response_latency, Integer, 12
-end
-
-class MI_example_DirectoryController < DirectoryController
-  default_param :to_mem_ctrl_latency, Integer, 1
-  default_param :directory_latency, Integer, 6
-  default_param :memory_latency, Integer, 158
-end
-
-
 #added by SS
 class MemoryControl < LibRubyObject
 
@@ -141,6 +128,43 @@ class MemoryControl < LibRubyObject
 
 end
 
+###### Protocols #######
+
+## MI_example protocol
+
+class MI_example_CacheController < L1CacheController
+  default_param :issue_latency, Integer, 2
+  default_param :cache_response_latency, Integer, 12
+end
+
+class MI_example_DirectoryController < DirectoryController
+  default_param :directory_latency, Integer, 6
+end
+
+class MI_example_DMAController < DMAController
+  default_param :request_latency, Integer, 6
+end
+
+## MOESI_CMP_directory protocol
+
+class MOESI_CMP_directory_L1CacheController < L1CacheController
+  default_param :request_latency, Integer, 2
+end
+
+class MOESI_CMP_directory_L2CacheController < CacheController
+  default_param :request_latency, Integer, 2
+  default_param :response_latency, Integer, 2
+end
+
+class MOESI_CMP_directory_DirectoryController < DirectoryController
+  default_param :directory_latency, Integer, 6
+end
+
+class MOESI_CMP_directory_DMAController < DMAController
+  default_param :request_latency, Integer, 6
+  default_param :response_latency, Integer, 6
+end
+
 class RubySystem
 
   # Random seed used by the simulation. If set to "rand", the seed
index cd3cdbe489f9327772f35753d85e37dfda4748b8..a6d99ada9ab35a8c69fa8e4aa30b978eca2ce49a 100644 (file)
@@ -85,6 +85,14 @@ MachineID map_Address_to_DMA(const Address & addr)
   return dma;
 }
 
+inline
+MachineID mapAddressToRange(const Address & addr, MachineType type, int low_bit, int high_bit)
+{
+  MachineID mach = {type, 0};
+  mach.num = addr.bitSelect(low_bit, high_bit);
+  return mach;
+}
+
 extern inline NodeID machineIDToNodeID(MachineID machID)
 {
   return machID.num;
index e4e20c99aeb4f919380b7ec37c3ad2b1152b26b8..0ea5df08bf0c5c7ba2e44256821d9869e465bbbc 100644 (file)
@@ -173,4 +173,9 @@ extern inline Address makeLineAddress(Address addr)
   return result;
 }
 
+extern inline int addressOffset(Address addr)
+{
+  return addr.getOffset();
+}
+
 #endif //SLICC_UTIL_H
index d29dba6021a3db0b1b7912dfc2e22a6b6fdb0626..8af8920071f4ba6cc10ff5e604fdc95611ba86db 100644 (file)
@@ -4,9 +4,8 @@
 #include "mem/ruby/slicc_interface/AbstractController.hh"
 
 /* SLICC generated types */
-#include "mem/protocol/DMARequestMsg.hh"
-#include "mem/protocol/DMARequestType.hh"
-#include "mem/protocol/DMAResponseMsg.hh"
+#include "mem/protocol/SequencerMsg.hh"
+#include "mem/protocol/SequencerRequestType.hh"
 #include "mem/ruby/system/System.hh"
 
 DMASequencer::DMASequencer(const string & name)
@@ -66,20 +65,16 @@ int64_t DMASequencer::makeRequest(const RubyRequest & request)
   active_request.bytes_issued = 0;
   active_request.id = makeUniqueRequestID();
 
-  DMARequestMsg msg;
+  SequencerMsg msg;
   msg.getPhysicalAddress() = Address(paddr);
   msg.getLineAddress() = line_address(msg.getPhysicalAddress());
-  msg.getType() = write ? DMARequestType_WRITE : DMARequestType_READ;
-  msg.getOffset() = paddr & m_data_block_mask;
-  msg.getLen() = (msg.getOffset() + len) <= RubySystem::getBlockSizeBytes() ?
+  msg.getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD;
+  int offset = paddr & m_data_block_mask;
+  msg.getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ?
     len : 
-    RubySystem::getBlockSizeBytes() - msg.getOffset();
-  if (write) {
-    msg.getType() = DMARequestType_WRITE;
-    msg.getDataBlk().setData(data, msg.getOffset(), msg.getLen());
-  } else {
-    msg.getType() = DMARequestType_READ;
-  }
+    RubySystem::getBlockSizeBytes() - offset;
+  if (write)
+    msg.getDataBlk().setData(data, offset, msg.getLen());
   m_mandatory_q_ptr->enqueue(msg);
   active_request.bytes_issued += msg.getLen();
 
@@ -96,14 +91,13 @@ void DMASequencer::issueNext()
     return;
   }
 
-  DMARequestMsg msg;
+  SequencerMsg msg;
   msg.getPhysicalAddress() = Address(active_request.start_paddr + 
                                     active_request.bytes_completed);
   assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0);
   msg.getLineAddress() = line_address(msg.getPhysicalAddress());
-  msg.getOffset() = 0;
-  msg.getType() = (active_request.write ? DMARequestType_WRITE : 
-                  DMARequestType_READ);
+  msg.getType() = (active_request.write ? SequencerRequestType_ST : 
+                  SequencerRequestType_LD);
   msg.getLen() = (active_request.len - 
                  active_request.bytes_completed < RubySystem::getBlockSizeBytes() ?
                  active_request.len - active_request.bytes_completed :
@@ -111,9 +105,9 @@ void DMASequencer::issueNext()
   if (active_request.write) {
     msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed], 
                             0, msg.getLen());
-    msg.getType() = DMARequestType_WRITE;
+    msg.getType() = SequencerRequestType_ST;
   } else {
-    msg.getType() = DMARequestType_READ;
+    msg.getType() = SequencerRequestType_LD;
   }
   m_mandatory_q_ptr->enqueue(msg);
   active_request.bytes_issued += msg.getLen();
index b279d21af9cbb60e56fb9b82793285c0e3be6471..c87be94a230de6f56086ebc7eb69b8f8d53163f6 100644 (file)
@@ -58,12 +58,14 @@ void DirectoryMemory::init(const vector<string> & argv)
     if ( (*it) == "version" )
       m_version = atoi( (*(++it)).c_str() );
     else if ( (*it) == "size_mb" ) {
-      m_size_bytes = atoi((*(++it)).c_str()) * (1<<20);
+      m_size_bytes = atoi((*(++it)).c_str()) * static_cast<uint64>(1<<20);
       m_size_bits = log_int(m_size_bytes);
     } else if ( (*it) == "controller" ) {
       m_controller = RubySystem::getController((*(++it)));
-    } else
+    } else {
+      cerr << "DirectoryMemory: Unkown config parameter: " << (*it) << endl;
       assert(0);
+    }
   }
   assert(m_controller != NULL);
 
index 6445ecc62888369e759bf495187ac9935375dda9..39de679ed854ee590081d5e83f14aabb845f1d04 100644 (file)
@@ -59,7 +59,7 @@ public:
   int mapAddressToLocalIdx(PhysAddress address);
   static int mapAddressToDirectoryVersion(PhysAddress address);
 
-  int getSize() { return m_size_bytes; }
+  uint64 getSize() { return m_size_bytes; }
 
   // Public Methods
   void printConfig(ostream& out) const;
@@ -84,8 +84,8 @@ private:
   // Data Members (m_ prefix)
   Directory_Entry **m_entries;
   //  int m_size;  // # of memory module blocks this directory is responsible for
-  uint32 m_size_bytes;
-  uint32 m_size_bits;
+  uint64 m_size_bytes;
+  uint64 m_size_bits;
   int m_num_entries;
   int m_version;
 
index 90c9273e517a66742c123a609e9be3d091eaf284..6561d028b4805938af4cc725bb563ea7a6171905 100644 (file)
@@ -43,7 +43,6 @@
 #include "mem/gems_common/Map.hh"
 #include "mem/protocol/AccessPermission.hh"
 #include "mem/ruby/common/Address.hh"
-#include "mem/ruby/slicc_interface/AbstractChip.hh"
 
 template<class ENTRY>
 class PerfectCacheLineState {
@@ -53,12 +52,19 @@ public:
   ENTRY m_entry;
 };
 
+template<class ENTRY>
+extern inline
+ostream& operator<<(ostream& out, const PerfectCacheLineState<ENTRY>& obj)
+{
+  return out;
+}
+
 template<class ENTRY>
 class PerfectCacheMemory {
 public:
 
   // Constructors
-  PerfectCacheMemory(AbstractChip* chip_ptr);
+  PerfectCacheMemory();
 
   // Destructor
   //~PerfectCacheMemory();
@@ -106,7 +112,6 @@ private:
 
   // Data Members (m_prefix)
   Map<Address, PerfectCacheLineState<ENTRY> > m_map;
-  AbstractChip* m_chip_ptr;
 };
 
 // Output operator declaration
@@ -129,9 +134,8 @@ ostream& operator<<(ostream& out, const PerfectCacheMemory<ENTRY>& obj)
 
 template<class ENTRY>
 extern inline
-PerfectCacheMemory<ENTRY>::PerfectCacheMemory(AbstractChip* chip_ptr)
+PerfectCacheMemory<ENTRY>::PerfectCacheMemory()
 {
-  m_chip_ptr = chip_ptr;
 }
 
 // STATIC METHODS
index dbf4dbc78608351099f6dbd6e3333d91aa4ab6db..38ef091775de46ca191acf0b3c95501a4803c146 100644 (file)
@@ -104,6 +104,9 @@ public:
   static RubyPort* getPortOnly(const string & name) {
     assert(m_ports.count(name) == 1); return m_ports[name]; }
   static RubyPort* getPort(const string & name, void (*hit_callback)(int64_t)) {
+    if (m_ports.count(name) != 1){
+      cerr << "Port " << name << " has " << m_ports.count(name) << " instances" << endl;
+    }
     assert(m_ports.count(name) == 1); m_ports[name]->registerHitCallback(hit_callback); return m_ports[name]; }
   static Network* getNetwork() { assert(m_network_ptr != NULL); return m_network_ptr; }
   static Topology* getTopology(const string & name) { assert(m_topologies.count(name) == 1); return m_topologies[name]; }
index edc2de23032d1d470064eec60ce458110761e5c6..5d496da045d751ac94dd25cfe90cd5211e540257 100644 (file)
 #include "mem/ruby/system/TimerTable.hh"
 #include "mem/ruby/eventqueue/RubyEventQueue.hh"
 
-TimerTable::TimerTable(Chip* chip_ptr)
+TimerTable::TimerTable()
 {
-  assert(chip_ptr != NULL);
   m_consumer_ptr  = NULL;
-  m_chip_ptr = chip_ptr;
   m_next_valid = false;
   m_next_address = Address(0);
   m_next_time = 0;
index 9912036f3c44b81d77f518d39deb53952926389a..eda84069d33bb754c3f4143d77fa44a32b81f578 100644 (file)
 #include "mem/gems_common/Map.hh"
 #include "mem/ruby/common/Address.hh"
 class Consumer;
-class Chip;
 
 class TimerTable {
 public:
 
   // Constructors
-  TimerTable(Chip* chip_ptr);
+  TimerTable();
 
   // Destructor
   //~TimerTable();
@@ -77,7 +76,6 @@ private:
 
   // Data Members (m_prefix)
   Map<Address, Time> m_map;
-  Chip* m_chip_ptr;
   mutable bool m_next_valid;
   mutable Time m_next_time; // Only valid if m_next_valid is true
   mutable Address m_next_address;  // Only valid if m_next_valid is true
index 53f9a6c334a6ba59a9dc92615b17b53bb6d1fd6d..33c9b84ed31a55ff7810756c31711bf81f38f5cb 100644 (file)
@@ -50,28 +50,28 @@ public:
   // Constructors
   AST(Map<string, string> pairs) { m_pairs = pairs; };
   AST() {};
-
+  
   // Destructor
   virtual ~AST() {};
-
+  
   // Public Methods
   virtual void print(ostream& out) const = 0;
   void error(string err_msg) const { m_location.error(err_msg); };
   string embedError(string err_msg) const { return m_location.embedError(err_msg); };
   void warning(string err_msg) const { m_location.warning(err_msg); };
-
+  
   const Location& getLocation() const { return m_location; };
-
+  
   const Map<string, string>& getPairs() const { return m_pairs; };
   Map<string, string>& getPairs() { return m_pairs; };
-
+  
 private:
   // Private Methods
-
+  
   // Private copy constructor and assignment operator
   //  AST(const AST& obj);
   //  AST& operator=(const AST& obj);
-
+  
   // Data Members (m_ prefix)
   Location m_location;
   Map<string, string> m_pairs;
index 2734722d1bcea074ce5ab747582768c2276110b7..e46412ff7d2f3b585a3d12c813e6604eebf0e7a6 100644 (file)
  *
  */
 
+
 #include "mem/slicc/ast/ActionDeclAST.hh"
 #include "mem/slicc/symbols/Action.hh"
+#include "mem/slicc/ast/StatementListAST.hh"
 
 ActionDeclAST::ActionDeclAST(string* ident_ptr,
                              PairListAST* pairs_ptr,
index 53d938ca868c6780fc24e605e936a6dcba5b2a88..4970ee254ad225a576a856eeaad665b6fd1db636 100644 (file)
@@ -41,7 +41,8 @@
 
 #include "mem/slicc/slicc_global.hh"
 #include "mem/slicc/ast/DeclAST.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
+
+class StatementListAST;
 
 class ActionDeclAST : public DeclAST {
 public:
index 8be0378c9cd5891c6ff1c6239cfa0d90dddeb3cb..a422d8a2808782ce877ad39337a42a2e1e997d13 100644 (file)
@@ -77,7 +77,14 @@ void EnqueueStatementAST::generate(string& code, Type* return_type_ptr) const
   code += ".enqueue(out_msg";
 
   if (getPairs().exist("latency")) {
-    code += ", m_LATENCY_" + getPairs().lookup("latency");
+    bool is_number = true;
+    string val = getPairs().lookup("latency");
+    for (int i=0; i<val.size(); i++)
+      if (!isdigit(val[i])) is_number = false;
+    if (is_number)
+      code += ", " + getPairs().lookup("latency");
+    else
+      code += ", m_" + getPairs().lookup("latency");
   }
 
   code += ");\n";
index 4ca2c897818b0cb5dc1cbfa11c755b3d69ad0e66..529811f25902db4a54c1b90ca1d6d6e24ec496a2 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "mem/slicc/ast/FormalParamAST.hh"
 #include "mem/slicc/ast/StatementAST.hh"
+#include "mem/slicc/ast/TypeAST.hh"
 #include "mem/slicc/symbols/SymbolTable.hh"
 
 FormalParamAST::~FormalParamAST()
@@ -46,6 +47,16 @@ FormalParamAST::~FormalParamAST()
   delete m_type_ast_ptr;
 }
 
+string FormalParamAST::getTypeName() const 
+{ 
+  return m_type_ast_ptr->toString(); 
+}
+
+Type* FormalParamAST::getType() const
+{
+  return m_type_ast_ptr->lookupType();
+}
+
 Type* FormalParamAST::generate(string& code) const
 {
   string param = "param_" + *m_ident_ptr;
index 63d66cc03e9fe7da136286e40476faab35face99..ca27948b7a4c6095dfb9ecd30d3b8ac1cbaa420b 100644 (file)
@@ -40,7 +40,9 @@
 #define FORMALPARAMAST_H
 
 #include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/TypeAST.hh"
+#include "mem/slicc/ast/AST.hh"
+
+class TypeAST;
 
 
 class FormalParamAST : public AST {
@@ -55,6 +57,8 @@ public:
   Type* generate(string& code) const;
   void print(ostream& out) const { out << "[FormalParamAST: " << *m_ident_ptr << "]"; }
   string getName() const { return *m_ident_ptr; }
+  string getTypeName() const;
+  Type* getType() const;
 private:
   // Private Methods
 
index 7fb0e6346d77f05e2a9ca126230b860e0da2796a..2a0905f06ddd295e0df846900615f137fc5f6132 100644 (file)
@@ -37,6 +37,7 @@
  */
 
 #include "mem/slicc/ast/FuncDeclAST.hh"
+#include "mem/slicc/ast/FormalParamAST.hh"
 #include "mem/slicc/symbols/SymbolTable.hh"
 #include "mem/slicc/main.hh"
 
index d6069430359f527e0ac92b6110a13c804bb35032..205e71a85d0037588b4f84690731e0add2846111 100644 (file)
@@ -43,7 +43,8 @@
 #include "mem/slicc/ast/DeclAST.hh"
 #include "mem/slicc/ast/TypeFieldAST.hh"
 #include "mem/slicc/ast/TypeAST.hh"
-#include "mem/slicc/ast/FormalParamAST.hh"
+
+class FormalParamsAST;
 
 class FuncDeclAST : public DeclAST {
 public:
index 2096db5916aa18ad9348a048aa43ba98422fd3da..ae80264584e93c5216856e1151d39fdd0f72d89b 100644 (file)
  */
 
 #include "mem/slicc/ast/MachineAST.hh"
+#include "mem/slicc/ast/FormalParamAST.hh"
 #include "mem/slicc/symbols/SymbolTable.hh"
 
 MachineAST::MachineAST(string* ident_ptr,
                        PairListAST* pairs_ptr,
-                       Vector<TypeFieldAST*>* config_params_ptr,
-                       std::vector<std::string*>* latency_vector,
+                       Vector<FormalParamAST*>* config_parameters,
                        DeclListAST* decl_list_ptr)
 
   : DeclAST(pairs_ptr)
 {
   m_ident_ptr = ident_ptr;
   m_pairs_ptr = pairs_ptr;
-  m_config_params_ptr = config_params_ptr;
+  m_config_parameters = config_parameters;
   m_decl_list_ptr = decl_list_ptr;
-  m_latency_vector = latency_vector;
 }
 
 MachineAST::~MachineAST()
@@ -69,7 +68,7 @@ void MachineAST::generate()
   g_sym_table.pushFrame();
 
   // Create a new machine
-  machine_ptr = new StateMachine(*m_ident_ptr, getLocation(), getPairs(), m_latency_vector);
+  machine_ptr = new StateMachine(*m_ident_ptr, getLocation(), getPairs(), m_config_parameters);
   g_sym_table.newCurrentMachine(machine_ptr);
 
   // Generate code for all the internal decls
index 8f83e4cfea86f0c201353e57a30e120d2b8adf12..5d1bc2a1cda2db2e53d0e892b0196802c911dc68 100644 (file)
 #include "mem/slicc/ast/TypeFieldAST.hh"
 #include "mem/slicc/symbols/StateMachine.hh"
 
+class FormalParamAST;
+
 class MachineAST : public DeclAST {
 public:
   // Constructors
   MachineAST(string* ident_ptr,
              PairListAST* pairs_ptr,
-             Vector<TypeFieldAST*>* config_params_ptr,
-             std::vector<std::string*>* latency_vector,
+             Vector<FormalParamAST*>* config_parameters,
              DeclListAST* decl_list_ptr);
 
   // Destructor
@@ -69,10 +70,9 @@ private:
   MachineAST& operator=(const MachineAST& obj);
 
   // Data Members (m_ prefix)
-  std::vector<std::string*>* m_latency_vector;
+  Vector<FormalParamAST*>* m_config_parameters;
   string* m_ident_ptr;
   DeclListAST* m_decl_list_ptr;
-  Vector<TypeFieldAST*>* m_config_params_ptr;
   PairListAST* m_pairs_ptr;
 };
 
index 1c7d582ecc6c4534d0b33c191b46dddf7cbd82a7..95e8d25e513b229e452a81e54eac3449ea8c9e62 100644 (file)
@@ -76,7 +76,7 @@ tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE',
            'NOT', 'AND', 'OR',
            'PLUS', 'DASH', 'STAR', 'SLASH',
            'DOUBLE_COLON', 'SEMICOLON',
-           'ASSIGN', 'DOT', 'LATENCY',
+           'ASSIGN', 'DOT',
            'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ]
 tokens += reserved.values()
 
@@ -190,19 +190,8 @@ def p_decl(p):
             | d_func_def"""
     p[0] = p[1]
 
-def p_latency(p):
-    """latency : LATENCY"""
-    pass
-
-def p_latencies(p):
-    """latencies : latency latencies
-                 | empty"""
-    return []
-
 def p_d_machine(p):
-    """d_machine : MACHINE '(' ident pair_l ')' '{' decl_l '}'
-           | MACHINE '(' ident pair_l ')' ':' type_members '{' decl_l '}'
-           | MACHINE '(' ident pair_l ')' ':' latencies '{' decl_l '}'"""
+    """d_machine : MACHINE '(' ident pair_l ')' ':' param_l '{' decl_l '}'"""
 
     if len(p) == 9:
         decl_l = p[7]
@@ -542,10 +531,19 @@ def scan(filenames):
     for filename in filenames:
         lex.lexer.lineno = 1
         try:
+            print "parsing ",filename
             results = yacc.parse(file(filename, 'r').read())
-        except (TokenError, ParseError), e:
-            raise type(e), tuple([filename] + [ i for i in e ])
+        except (ParseError,TokenError), e:
+            print "File ",filename," ",e
+            raise e
+        #except ParseError, e:
+        #    print "File ",filename," "e
+        #    raise e, tuple([filename] + [ i for i in e ])
+
+        #except ParseError, e:
+        #    print e
 
+            
         for result in results:
             result.add(hh, cc)
 
index fa5a3b355319438462c3b001b7f4a681dcbee53b..c8cef3b210766bf3967ad229200b9514e4ed748c 100644 (file)
@@ -111,8 +111,6 @@ extern "C" int yylex();
 %type <expr_ptr> expr literal enumeration
 %type <expr_vector_ptr> expr_list
 
-%type <stdstring_vector_ptr> myrule
-
 %type <pair_ptr> pair
 %type <pair_list_ptr> pair_list pairs
 
@@ -148,9 +146,7 @@ decls: decl decls { $2->insertAtTop($1); $$ = $2; }
      | { $$ = new Vector<DeclAST*>; }
      ;
 
-decl:  MACHINE_DECL     '(' ident pair_list ')' ':' myrule '{' decl_list '}' { $$ = new MachineAST($3, $4, NULL, $7, $9); }
-//    |  MACHINE_DECL     '(' ident pair_list ')' ':' type_members '{' decl_list '}' { $$ = new MachineAST($3, $4, $7, string_vector, $9); }
-    |  MACHINE_DECL     '(' ident pair_list ')' '{' decl_list '}' { $$ = new MachineAST($3, $4, NULL, new vector<string*>(), $7); }
+decl:  MACHINE_DECL     '(' ident pair_list ')' ':' formal_param_list '{' decl_list '}' { $$ = new MachineAST($3, $4, $7, $9); }
     |  ACTION_DECL      '(' ident pair_list ')' statement_list { $$ = new ActionDeclAST($3, $4, $6); }
     |  IN_PORT_DECL     '(' ident ',' type ',' var pair_list ')' statement_list { $$ = new InPortDeclAST($3, $5, $7, $8, $10); }
     |  OUT_PORT_DECL    '(' ident ',' type ',' var pair_list ')' SEMICOLON { $$ = new OutPortDeclAST($3, $5, $7, $8); }
@@ -336,10 +332,6 @@ var: ident { $$ = new VarExprAST($1); }
 field: ident { $$ = $1; }
      ;
 
-myrule: myrule IDENT { $1->push_back($2); }
-      | IDENT { $$ = new vector<string*>(1, $1); }
-      ;
-
 %%
 
 extern FILE *yyin;
index 4a9ee37144be4ff4f8c1b9c65af868d55967ec9c..7bc84ffe0e44e32104da0358758983fe49037819 100644 (file)
 #include "mem/slicc/symbols/SymbolTable.hh"
 #include "mem/gems_common/util.hh"
 #include "mem/gems_common/Vector.hh"
+#include "mem/slicc/ast/FormalParamAST.hh"
 
 #include <set>
 
-StateMachine::StateMachine(string ident, const Location& location, const Map<string, string>& pairs,  std::vector<std::string*>* latency_vector)
+StateMachine::StateMachine(string ident, const Location& location, const Map<string, string>& pairs,  Vector<FormalParamAST*>* config_parameters)
   : Symbol(ident, location, pairs)
 {
   m_table_built = false;
-  m_latency_vector = *latency_vector;
+  m_config_parameters = config_parameters;
+  
+  for (int i=0; i< m_config_parameters->size(); i++) {
+    Var* var = new Var(m_config_parameters->ref(i)->getName(), 
+                      location, 
+                      m_config_parameters->ref(i)->getType(), 
+                      "m_"+m_config_parameters->ref(i)->getName(),
+                      Map<string, string>(),
+                      this);
+    g_sym_table.registerSym(m_config_parameters->ref(i)->getName(), var);
+  }
 }
 
 StateMachine::~StateMachine()
@@ -284,9 +295,8 @@ void StateMachine::printControllerH(ostream& out, string component)
   out << "private:" << endl;
 //added by SS
 //  found_to_mem = 0;
-  std::vector<std::string*>::const_iterator it;
-  for(it=m_latency_vector.begin();it!=m_latency_vector.end();it++){
-        out << "  int m_" << (*it)->c_str() << ";" << endl;
+  for(int i=0;i<m_config_parameters->size();i++){
+    out << "  int m_" << m_config_parameters->ref(i)->getName() << ";" << endl;
   }
   if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
     out << "  bool servicing_atomic;" << endl;
@@ -429,41 +439,22 @@ void StateMachine::printControllerC(ostream& out, string component)
   out << "    else if (argv[i] == \"number_of_TBEs\") " << endl;
   out << "      m_number_of_TBEs = atoi(argv[i+1].c_str());" << endl;
 
-  if (m_latency_vector.size()) {
-  out << "    else { " << endl;
-    std::vector<std::string*>::const_iterator it;
-    for(it=m_latency_vector.begin();it!=m_latency_vector.end();it++) {
-      string str = (*it)->c_str();
-      str.erase(0,8);
-//convert to lowercase
-      size_t i;
-      char* strc = (char*) malloc (str.length()+1);
-      strc[str.length()]=0;
-      for(i=0; i < str.length(); i++) {
-        strc[i] = str.at(i);
-        strc[i] = tolower(strc[i]);
-      }
-      str = strc;
-      delete strc;
-      out << "      if (argv[i] == \"" << str << "\"){" << endl;
-      if (str == "to_mem_ctrl_latency")
-        out << "        m_" << (*it)->c_str() << "=" << "atoi(argv[i+1].c_str())+(random() % 5);" << endl;
+  if (m_config_parameters->size()) {
+    for(int i= 0 ; i < m_config_parameters->size(); i++) {
+      out << "    else if (argv[i] == \"" << m_config_parameters->ref(i)->getName() << "\")" << endl;
+      if (m_config_parameters->ref(i)->getTypeName() == "int")
+       out << "      m_" << m_config_parameters->ref(i)->getName() << "=" << "atoi(argv[i+1].c_str());" << endl;      
       else
-        out << "        m_" << (*it)->c_str() << "=" << "atoi(argv[i+1].c_str());" << endl;
-//      out << "        printf (\"SET m_" << it->c_str() << "= %i \\n \", m_" << it->c_str() << ");" << endl;
-      out << "      }" << endl;
+       assert(0); // only int parameters are supported right now
+      //      if (str == "to_mem_ctrl_latency")
+      //        out << "        m_" << (*it)->c_str() << "=" << "atoi(argv[i+1].c_str())+(random() % 5);" << endl;
     }
-  out << "    }" << endl;
   }
   out << "  }" << endl;
-
   out << "  m_net_ptr = net_ptr;" << endl;
   out << "  m_machineID.type = MachineType_" << component << ";" << endl;
   out << "  m_machineID.num = m_version;" << endl;
 
-//  out << "  printf (\"I set m_LATENCY_ISSUE_LATENCY to %i \\n \", m_LATENCY_ISSUE_LATENCY);" << endl;
-//  out << "  printf (\"I set m_LATENCY_CACHE_RESPONSE_LATENCY to %i \\n \", m_LATENCY_CACHE_RESPONSE_LATENCY);" << endl;
-
   // make configuration array
   out << "  for (size_t i=0; i < argv.size(); i+=2) {" << endl;
   out << "    if (argv[i] != \"version\") " << endl;
@@ -724,25 +715,7 @@ void StateMachine::printControllerC(ostream& out, string component)
 
 
       string c_code_string = action.lookupPair("c_code");
-/*
-      size_t found = c_code_string.find("RubyConfig::get");
-
-      if (found!=string::npos){ //found --> replace it with local access
-        //if it is related to latency --> replace it
-        std::vector<std::string*>::const_iterator it;
-        for(it=m_latency_vector.begin();it!=m_latency_vector.end();it++){
-          string str = (*it)->c_str();
-          str.erase(0,8);
-          size_t fd = c_code_string.find(str, found);
-          if (fd!=string::npos && (fd == found+15)){
-            string rstr = "m_";
-            rstr += (*it)->c_str();
-            c_code_string.replace(found,15+str.size()+2,rstr);
-            break;
-          }
-        }
-      }
-*/
+
       // add here:
       if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
         if (c_code_string.find("writeCallback") != string::npos) {
index 101e38547060990849c5610e4c220406a2f2eee7..f5f3ab073b60b49375f4457c649e1c04daf6138c 100644 (file)
@@ -49,11 +49,12 @@ class State;
 class Action;
 class Var;
 class Func;
+class FormalParamAST;
 
 class StateMachine : public Symbol {
 public:
   // Constructors
-  StateMachine(string ident, const Location& location, const Map<string, string>& pairs,  std::vector<std::string*>* latency_vector);
+  StateMachine(string ident, const Location& location, const Map<string, string>& pairs,  Vector<FormalParamAST*>* config_parameters);
 
   // Destructor
   ~StateMachine();
@@ -94,7 +95,7 @@ public:
   void print(ostream& out) const { out << "[StateMachine: " << toString() << "]" << endl; }
 private:
 
-  std::vector<std::string*> m_latency_vector;
+  Vector<FormalParamAST*>* m_config_parameters;
 
   // Private Methods
   void checkForDuplicate(const Symbol& sym) const;