MOESI_CMP_directory-dir.sm revision 14184
114184Sgabeblack@google.com/*
214184Sgabeblack@google.com * Copyright (c) 2019 ARM Limited
314184Sgabeblack@google.com * All rights reserved
414184Sgabeblack@google.com *
514184Sgabeblack@google.com * The license below extends only to copyright in the software and shall
614184Sgabeblack@google.com * not be construed as granting a license to any other intellectual
714184Sgabeblack@google.com * property including but not limited to intellectual property relating
814184Sgabeblack@google.com * to a hardware implementation of the functionality of the software
914184Sgabeblack@google.com * licensed hereunder.  You may use the software subject to the license
1014184Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated
1114184Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software,
1214184Sgabeblack@google.com * modified or unmodified, in source code or in binary form.
1314184Sgabeblack@google.com *
1414184Sgabeblack@google.com * Copyright (c) 1999-2013 Mark D. Hill and David A. Wood
1514184Sgabeblack@google.com * All rights reserved.
1614184Sgabeblack@google.com *
1714184Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
1814184Sgabeblack@google.com * modification, are permitted provided that the following conditions are
1914184Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
2014184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
2114184Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
2214184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
2314184Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
2414184Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
2514184Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
2614184Sgabeblack@google.com * this software without specific prior written permission.
2714184Sgabeblack@google.com *
2814184Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2914184Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3014184Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3114184Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3214184Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3314184Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3414184Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3514184Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3614184Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3714184Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3814184Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3914184Sgabeblack@google.com */
4014184Sgabeblack@google.com
4114184Sgabeblack@google.commachine(MachineType:Directory, "Directory protocol")
4214184Sgabeblack@google.com:  DirectoryMemory * directory;
4314184Sgabeblack@google.com   Cycles directory_latency := 6;
4414184Sgabeblack@google.com   Cycles to_memory_controller_latency := 1;
4514184Sgabeblack@google.com
4614184Sgabeblack@google.com   // Message Queues
4714184Sgabeblack@google.com   MessageBuffer * requestToDir, network="From", virtual_network="1",
4814184Sgabeblack@google.com        vnet_type="request";  // a mod-L2 bank -> this Dir
4914184Sgabeblack@google.com   MessageBuffer * responseToDir, network="From", virtual_network="2",
5014184Sgabeblack@google.com        vnet_type="response";  // a mod-L2 bank -> this Dir
5114184Sgabeblack@google.com
5214184Sgabeblack@google.com   MessageBuffer * forwardFromDir, network="To", virtual_network="1",
5314184Sgabeblack@google.com        vnet_type="forward";
5414184Sgabeblack@google.com   MessageBuffer * responseFromDir, network="To", virtual_network="2",
5514184Sgabeblack@google.com        vnet_type="response";  // Dir -> mod-L2 bank
5614184Sgabeblack@google.com
5714184Sgabeblack@google.com   MessageBuffer * responseFromMemory;
5814184Sgabeblack@google.com{
5914184Sgabeblack@google.com  // STATES
6014184Sgabeblack@google.com  state_declaration(State, desc="Directory states", default="Directory_State_I") {
6114184Sgabeblack@google.com    // Base states
6214184Sgabeblack@google.com    I, AccessPermission:Read_Write, desc="Invalid";
6314184Sgabeblack@google.com    S, AccessPermission:Read_Only, desc="Shared";
6414184Sgabeblack@google.com    O, AccessPermission:Maybe_Stale, desc="Owner";
6514184Sgabeblack@google.com    M, AccessPermission:Maybe_Stale, desc="Modified";
6614184Sgabeblack@google.com
6714184Sgabeblack@google.com    IS, AccessPermission:Busy, desc="Blocked, was in idle";
6814184Sgabeblack@google.com    SS, AccessPermission:Read_Only, desc="Blocked, was in shared";
6914184Sgabeblack@google.com    OO, AccessPermission:Busy, desc="Blocked, was in owned";
7014184Sgabeblack@google.com    MO, AccessPermission:Busy, desc="Blocked, going to owner or maybe modified";
7114184Sgabeblack@google.com    MM, AccessPermission:Busy, desc="Blocked, going to modified";
7214184Sgabeblack@google.com
7314184Sgabeblack@google.com    MI, AccessPermission:Busy, desc="Blocked on a writeback";
7414184Sgabeblack@google.com    MIS, AccessPermission:Busy, desc="Blocked on a writeback, but don't remove from sharers when received";
7514184Sgabeblack@google.com    OS, AccessPermission:Busy, desc="Blocked on a writeback";
7614184Sgabeblack@google.com    OSS, AccessPermission:Busy, desc="Blocked on a writeback, but don't remove from sharers when received";
7714184Sgabeblack@google.com
7814184Sgabeblack@google.com    XI_M, AccessPermission:Busy, desc="In a stable state, going to I, waiting for the memory controller";
7914184Sgabeblack@google.com    XI_U, AccessPermission:Busy, desc="In a stable state, going to I, waiting for an unblock";
8014184Sgabeblack@google.com    OI_D, AccessPermission:Busy, desc="In O, going to I, waiting for data";
8114184Sgabeblack@google.com
8214184Sgabeblack@google.com    OD, AccessPermission:Busy, desc="In O, waiting for dma ack from L2";
8314184Sgabeblack@google.com    MD, AccessPermission:Busy, desc="In M, waiting for dma ack from L2";
8414184Sgabeblack@google.com  }
8514184Sgabeblack@google.com
8614184Sgabeblack@google.com  // Events
8714184Sgabeblack@google.com  enumeration(Event, desc="Directory events") {
8814184Sgabeblack@google.com    GETX, desc="A GETX arrives";
8914184Sgabeblack@google.com    GETS, desc="A GETS arrives";
9014184Sgabeblack@google.com    PUTX, desc="A PUTX arrives";
9114184Sgabeblack@google.com    PUTO, desc="A PUTO arrives";
9214184Sgabeblack@google.com    PUTO_SHARERS, desc="A PUTO arrives, but don't remove from sharers list";
9314184Sgabeblack@google.com    Unblock, desc="An unblock message arrives";
9414184Sgabeblack@google.com    Last_Unblock, desc="An unblock message arrives, we're not waiting for any additional unblocks";
9514184Sgabeblack@google.com    Exclusive_Unblock, desc="The processor become the exclusive owner (E or M) of the line";
9614184Sgabeblack@google.com    Clean_Writeback, desc="The final message as part of a PutX/PutS, no data";
9714184Sgabeblack@google.com    Dirty_Writeback, desc="The final message as part of a PutX/PutS, contains data";
9814184Sgabeblack@google.com    Memory_Data,   desc="Fetched data from memory arrives";
9914184Sgabeblack@google.com    Memory_Ack,    desc="Writeback Ack from memory arrives";
10014184Sgabeblack@google.com    DMA_READ,      desc="DMA Read";
10114184Sgabeblack@google.com    DMA_WRITE,     desc="DMA Write";
10214184Sgabeblack@google.com    DMA_ACK,       desc="DMA Ack";
10314184Sgabeblack@google.com    Data,          desc="Data to directory";
10414184Sgabeblack@google.com  }
10514184Sgabeblack@google.com
10614184Sgabeblack@google.com  // TYPES
10714184Sgabeblack@google.com
10814184Sgabeblack@google.com  // DirectoryEntry
10914184Sgabeblack@google.com  structure(Entry, desc="...", interface='AbstractEntry') {
11014184Sgabeblack@google.com    State DirectoryState,          desc="Directory state";
11114184Sgabeblack@google.com    NetDest Sharers,                   desc="Sharers for this block";
11214184Sgabeblack@google.com    NetDest Owner,                     desc="Owner of this block";
11314184Sgabeblack@google.com    int WaitingUnblocks,           desc="Number of acks we're waiting for";
11414184Sgabeblack@google.com  }
11514184Sgabeblack@google.com
11614184Sgabeblack@google.com  structure(TBE, desc="...") {
11714184Sgabeblack@google.com    Addr PhysicalAddress,   desc="Physical address for this entry";
11814184Sgabeblack@google.com    int Len,           desc="Length of request";
11914184Sgabeblack@google.com    DataBlock DataBlk, desc="DataBlk";
12014184Sgabeblack@google.com    MachineID Requestor, desc="original requestor";
12114184Sgabeblack@google.com  }
12214184Sgabeblack@google.com
12314184Sgabeblack@google.com  structure(TBETable, external = "yes") {
12414184Sgabeblack@google.com    TBE lookup(Addr);
12514184Sgabeblack@google.com    void allocate(Addr);
12614184Sgabeblack@google.com    void deallocate(Addr);
12714184Sgabeblack@google.com    bool isPresent(Addr);
12814184Sgabeblack@google.com  }
12914184Sgabeblack@google.com
13014184Sgabeblack@google.com  // ** OBJECTS **
13114184Sgabeblack@google.com  TBETable TBEs, template="<Directory_TBE>", constructor="m_number_of_TBEs";
13214184Sgabeblack@google.com
13314184Sgabeblack@google.com  Tick clockEdge();
13414184Sgabeblack@google.com  Tick cyclesToTicks(Cycles c);
13514184Sgabeblack@google.com  void set_tbe(TBE b);
13614184Sgabeblack@google.com  void unset_tbe();
13714184Sgabeblack@google.com
13814184Sgabeblack@google.com  Entry getDirectoryEntry(Addr addr), return_by_pointer="yes" {
13914184Sgabeblack@google.com    Entry dir_entry := static_cast(Entry, "pointer", directory[addr]);
14014184Sgabeblack@google.com
14114184Sgabeblack@google.com    if (is_valid(dir_entry)) {
14214184Sgabeblack@google.com      return dir_entry;
14314184Sgabeblack@google.com    }
14414184Sgabeblack@google.com
14514184Sgabeblack@google.com    dir_entry :=  static_cast(Entry, "pointer",
14614184Sgabeblack@google.com                              directory.allocate(addr, new Entry));
14714184Sgabeblack@google.com    return dir_entry;
14814184Sgabeblack@google.com  }
14914184Sgabeblack@google.com
15014184Sgabeblack@google.com  State getState(TBE tbe, Addr addr) {
15114184Sgabeblack@google.com    return getDirectoryEntry(addr).DirectoryState;
15214184Sgabeblack@google.com  }
15314184Sgabeblack@google.com
15414184Sgabeblack@google.com  void setState(TBE tbe, Addr addr, State state) {
15514184Sgabeblack@google.com    if (directory.isPresent(addr)) {
15614184Sgabeblack@google.com
15714184Sgabeblack@google.com      if (state == State:I) {
15814184Sgabeblack@google.com        assert(getDirectoryEntry(addr).Owner.count() == 0);
15914184Sgabeblack@google.com        assert(getDirectoryEntry(addr).Sharers.count() == 0);
16014184Sgabeblack@google.com      }
16114184Sgabeblack@google.com
16214184Sgabeblack@google.com      if (state == State:S) {
16314184Sgabeblack@google.com        assert(getDirectoryEntry(addr).Owner.count() == 0);
16414184Sgabeblack@google.com      }
16514184Sgabeblack@google.com
16614184Sgabeblack@google.com      if (state == State:O) {
16714184Sgabeblack@google.com        assert(getDirectoryEntry(addr).Owner.count() == 1);
16814184Sgabeblack@google.com        assert(getDirectoryEntry(addr).Sharers.isSuperset(getDirectoryEntry(addr).Owner) == false);
16914184Sgabeblack@google.com      }
17014184Sgabeblack@google.com
17114184Sgabeblack@google.com      if (state == State:M) {
17214184Sgabeblack@google.com        assert(getDirectoryEntry(addr).Owner.count() == 1);
17314184Sgabeblack@google.com        assert(getDirectoryEntry(addr).Sharers.count() == 0);
17414184Sgabeblack@google.com      }
17514184Sgabeblack@google.com
17614184Sgabeblack@google.com      if ((state != State:SS) && (state != State:OO)) {
17714184Sgabeblack@google.com        assert(getDirectoryEntry(addr).WaitingUnblocks == 0);
17814184Sgabeblack@google.com      }
17914184Sgabeblack@google.com
18014184Sgabeblack@google.com      if ( (getDirectoryEntry(addr).DirectoryState != State:I) && (state == State:I) ) {
18114184Sgabeblack@google.com        getDirectoryEntry(addr).DirectoryState := state;
18214184Sgabeblack@google.com         // disable coherence checker
18314184Sgabeblack@google.com        // sequencer.checkCoherence(addr);
18414184Sgabeblack@google.com      }
18514184Sgabeblack@google.com      else {
18614184Sgabeblack@google.com        getDirectoryEntry(addr).DirectoryState := state;
18714184Sgabeblack@google.com      }
18814184Sgabeblack@google.com    }
18914184Sgabeblack@google.com  }
19014184Sgabeblack@google.com
19114184Sgabeblack@google.com  AccessPermission getAccessPermission(Addr addr) {
19214184Sgabeblack@google.com    if (directory.isPresent(addr)) {
19314184Sgabeblack@google.com      DPRINTF(RubySlicc, "%s\n", Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState));
19414184Sgabeblack@google.com      return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
19514184Sgabeblack@google.com    }
19614184Sgabeblack@google.com
19714184Sgabeblack@google.com    DPRINTF(RubySlicc, "AccessPermission_NotPresent\n");
19814184Sgabeblack@google.com    return AccessPermission:NotPresent;
19914184Sgabeblack@google.com  }
20014184Sgabeblack@google.com
20114184Sgabeblack@google.com  void setAccessPermission(Addr addr, State state) {
20214184Sgabeblack@google.com    if (directory.isPresent(addr)) {
20314184Sgabeblack@google.com      getDirectoryEntry(addr).changePermission(Directory_State_to_permission(state));
20414184Sgabeblack@google.com    }
20514184Sgabeblack@google.com  }
20614184Sgabeblack@google.com
20714184Sgabeblack@google.com  void functionalRead(Addr addr, Packet *pkt) {
20814184Sgabeblack@google.com    functionalMemoryRead(pkt);
20914184Sgabeblack@google.com  }
21014184Sgabeblack@google.com
21114184Sgabeblack@google.com  int functionalWrite(Addr addr, Packet *pkt) {
21214184Sgabeblack@google.com    int num_functional_writes := 0;
21314184Sgabeblack@google.com    num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt);
21414184Sgabeblack@google.com    return num_functional_writes;
21514184Sgabeblack@google.com  }
21614184Sgabeblack@google.com
21714184Sgabeblack@google.com  // if no sharers, then directory can be considered
21814184Sgabeblack@google.com  // both a sharer and exclusive w.r.t. coherence checking
21914184Sgabeblack@google.com  bool isBlockShared(Addr addr) {
22014184Sgabeblack@google.com    if (directory.isPresent(addr)) {
22114184Sgabeblack@google.com      if (getDirectoryEntry(addr).DirectoryState == State:I) {
22214184Sgabeblack@google.com        return true;
22314184Sgabeblack@google.com      }
22414184Sgabeblack@google.com    }
22514184Sgabeblack@google.com    return false;
22614184Sgabeblack@google.com  }
22714184Sgabeblack@google.com
22814184Sgabeblack@google.com  bool isBlockExclusive(Addr addr) {
22914184Sgabeblack@google.com    if (directory.isPresent(addr)) {
23014184Sgabeblack@google.com      if (getDirectoryEntry(addr).DirectoryState == State:I) {
23114184Sgabeblack@google.com        return true;
23214184Sgabeblack@google.com      }
23314184Sgabeblack@google.com    }
23414184Sgabeblack@google.com    return false;
23514184Sgabeblack@google.com  }
23614184Sgabeblack@google.com
23714184Sgabeblack@google.com  // ** OUT_PORTS **
23814184Sgabeblack@google.com  out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
23914184Sgabeblack@google.com  out_port(responseNetwork_out, ResponseMsg, responseFromDir);
24014184Sgabeblack@google.com
24114184Sgabeblack@google.com  // ** IN_PORTS **
24214184Sgabeblack@google.com
24314184Sgabeblack@google.com  in_port(unblockNetwork_in, ResponseMsg, responseToDir, rank=2) {
24414184Sgabeblack@google.com    if (unblockNetwork_in.isReady(clockEdge())) {
24514184Sgabeblack@google.com      peek(unblockNetwork_in, ResponseMsg) {
24614184Sgabeblack@google.com        if (in_msg.Type == CoherenceResponseType:UNBLOCK) {
24714184Sgabeblack@google.com          if (getDirectoryEntry(in_msg.addr).WaitingUnblocks == 1) {
24814184Sgabeblack@google.com            trigger(Event:Last_Unblock, in_msg.addr,
24914184Sgabeblack@google.com                    TBEs[in_msg.addr]);
25014184Sgabeblack@google.com          } else {
25114184Sgabeblack@google.com            trigger(Event:Unblock, in_msg.addr,
25214184Sgabeblack@google.com                    TBEs[in_msg.addr]);
25314184Sgabeblack@google.com          }
25414184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceResponseType:UNBLOCK_EXCLUSIVE) {
25514184Sgabeblack@google.com          trigger(Event:Exclusive_Unblock, in_msg.addr,
25614184Sgabeblack@google.com                  TBEs[in_msg.addr]);
25714184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) {
25814184Sgabeblack@google.com          trigger(Event:Data, in_msg.addr,
25914184Sgabeblack@google.com                  TBEs[in_msg.addr]);
26014184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceResponseType:DMA_ACK) {
26114184Sgabeblack@google.com          trigger(Event:DMA_ACK, in_msg.addr,
26214184Sgabeblack@google.com                  TBEs[in_msg.addr]);
26314184Sgabeblack@google.com        } else {
26414184Sgabeblack@google.com          error("Invalid message");
26514184Sgabeblack@google.com        }
26614184Sgabeblack@google.com      }
26714184Sgabeblack@google.com    }
26814184Sgabeblack@google.com  }
26914184Sgabeblack@google.com
27014184Sgabeblack@google.com  in_port(requestQueue_in, RequestMsg, requestToDir, rank=1) {
27114184Sgabeblack@google.com    if (requestQueue_in.isReady(clockEdge())) {
27214184Sgabeblack@google.com      peek(requestQueue_in, RequestMsg) {
27314184Sgabeblack@google.com        if (in_msg.Type == CoherenceRequestType:GETS) {
27414184Sgabeblack@google.com          trigger(Event:GETS, in_msg.addr, TBEs[in_msg.addr]);
27514184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:GETX) {
27614184Sgabeblack@google.com          trigger(Event:GETX, in_msg.addr, TBEs[in_msg.addr]);
27714184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:PUTX) {
27814184Sgabeblack@google.com          trigger(Event:PUTX, in_msg.addr, TBEs[in_msg.addr]);
27914184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:PUTO) {
28014184Sgabeblack@google.com          trigger(Event:PUTO, in_msg.addr, TBEs[in_msg.addr]);
28114184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:PUTO_SHARERS) {
28214184Sgabeblack@google.com          trigger(Event:PUTO_SHARERS, in_msg.addr, TBEs[in_msg.addr]);
28314184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:WRITEBACK_DIRTY_DATA) {
28414184Sgabeblack@google.com          trigger(Event:Dirty_Writeback, in_msg.addr,
28514184Sgabeblack@google.com                  TBEs[in_msg.addr]);
28614184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:WRITEBACK_CLEAN_ACK) {
28714184Sgabeblack@google.com          trigger(Event:Clean_Writeback, in_msg.addr,
28814184Sgabeblack@google.com                  TBEs[in_msg.addr]);
28914184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:DMA_READ) {
29014184Sgabeblack@google.com          trigger(Event:DMA_READ, makeLineAddress(in_msg.addr),
29114184Sgabeblack@google.com                  TBEs[makeLineAddress(in_msg.addr)]);
29214184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:DMA_WRITE) {
29314184Sgabeblack@google.com          trigger(Event:DMA_WRITE, makeLineAddress(in_msg.addr),
29414184Sgabeblack@google.com                  TBEs[makeLineAddress(in_msg.addr)]);
29514184Sgabeblack@google.com        } else {
29614184Sgabeblack@google.com          error("Invalid message");
29714184Sgabeblack@google.com        }
29814184Sgabeblack@google.com      }
29914184Sgabeblack@google.com    }
30014184Sgabeblack@google.com  }
30114184Sgabeblack@google.com
30214184Sgabeblack@google.com  // off-chip memory request/response is done
30314184Sgabeblack@google.com  in_port(memQueue_in, MemoryMsg, responseFromMemory, rank=0) {
30414184Sgabeblack@google.com    if (memQueue_in.isReady(clockEdge())) {
30514184Sgabeblack@google.com      peek(memQueue_in, MemoryMsg) {
30614184Sgabeblack@google.com        if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
30714184Sgabeblack@google.com          trigger(Event:Memory_Data, in_msg.addr, TBEs[in_msg.addr]);
30814184Sgabeblack@google.com        } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) {
30914184Sgabeblack@google.com          trigger(Event:Memory_Ack, in_msg.addr, TBEs[in_msg.addr]);
31014184Sgabeblack@google.com        } else {
31114184Sgabeblack@google.com          DPRINTF(RubySlicc, "%s\n", in_msg.Type);
31214184Sgabeblack@google.com          error("Invalid message");
31314184Sgabeblack@google.com        }
31414184Sgabeblack@google.com      }
31514184Sgabeblack@google.com    }
31614184Sgabeblack@google.com  }
31714184Sgabeblack@google.com
31814184Sgabeblack@google.com  // Actions
31914184Sgabeblack@google.com
32014184Sgabeblack@google.com  action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") {
32114184Sgabeblack@google.com    peek(requestQueue_in, RequestMsg) {
32214184Sgabeblack@google.com      enqueue(responseNetwork_out, ResponseMsg, directory_latency) {
32314184Sgabeblack@google.com        out_msg.addr := address;
32414184Sgabeblack@google.com        out_msg.Type := CoherenceResponseType:WB_ACK;
32514184Sgabeblack@google.com        out_msg.Sender := in_msg.Requestor;
32614184Sgabeblack@google.com        out_msg.SenderMachine := MachineType:Directory;
32714184Sgabeblack@google.com        out_msg.Destination.add(in_msg.Requestor);
32814184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Writeback_Control;
32914184Sgabeblack@google.com      }
33014184Sgabeblack@google.com    }
33114184Sgabeblack@google.com  }
33214184Sgabeblack@google.com
33314184Sgabeblack@google.com  action(b_sendWriteBackNack, "b", desc="Send writeback nack to requestor") {
33414184Sgabeblack@google.com    peek(requestQueue_in, RequestMsg) {
33514184Sgabeblack@google.com      enqueue(responseNetwork_out, ResponseMsg, directory_latency) {
33614184Sgabeblack@google.com        out_msg.addr := address;
33714184Sgabeblack@google.com        out_msg.Type := CoherenceResponseType:WB_NACK;
33814184Sgabeblack@google.com        out_msg.Sender := in_msg.Requestor;
33914184Sgabeblack@google.com        out_msg.SenderMachine := MachineType:Directory;
34014184Sgabeblack@google.com        out_msg.Destination.add(in_msg.Requestor);
34114184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Writeback_Control;
34214184Sgabeblack@google.com      }
34314184Sgabeblack@google.com    }
34414184Sgabeblack@google.com  }
34514184Sgabeblack@google.com
34614184Sgabeblack@google.com  action(c_clearOwner, "c", desc="Clear the owner field") {
34714184Sgabeblack@google.com    getDirectoryEntry(address).Owner.clear();
34814184Sgabeblack@google.com  }
34914184Sgabeblack@google.com
35014184Sgabeblack@google.com  action(c_moveOwnerToSharer, "cc", desc="Move owner to sharers") {
35114184Sgabeblack@google.com    getDirectoryEntry(address).Sharers.addNetDest(getDirectoryEntry(address).Owner);
35214184Sgabeblack@google.com    getDirectoryEntry(address).Owner.clear();
35314184Sgabeblack@google.com  }
35414184Sgabeblack@google.com
35514184Sgabeblack@google.com  action(cc_clearSharers, "\c", desc="Clear the sharers field") {
35614184Sgabeblack@google.com    getDirectoryEntry(address).Sharers.clear();
35714184Sgabeblack@google.com  }
35814184Sgabeblack@google.com
35914184Sgabeblack@google.com  action(d_sendDataMsg, "d", desc="Send data to requestor") {
36014184Sgabeblack@google.com    peek(memQueue_in, MemoryMsg) {
36114184Sgabeblack@google.com      enqueue(responseNetwork_out, ResponseMsg, 1) {
36214184Sgabeblack@google.com        out_msg.addr := address;
36314184Sgabeblack@google.com        out_msg.Sender := machineID;
36414184Sgabeblack@google.com        out_msg.SenderMachine := MachineType:Directory;
36514184Sgabeblack@google.com        out_msg.Destination.add(in_msg.OriginalRequestorMachId);
36614184Sgabeblack@google.com        out_msg.DataBlk := in_msg.DataBlk;
36714184Sgabeblack@google.com        out_msg.Dirty := false; // By definition, the block is now clean
36814184Sgabeblack@google.com        out_msg.Acks := in_msg.Acks;
36914184Sgabeblack@google.com        if (in_msg.ReadX) {
37014184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
37114184Sgabeblack@google.com        } else {
37214184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:DATA;
37314184Sgabeblack@google.com        }
37414184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Response_Data;
37514184Sgabeblack@google.com      }
37614184Sgabeblack@google.com    }
37714184Sgabeblack@google.com  }
37814184Sgabeblack@google.com
37914184Sgabeblack@google.com  action(p_fwdDataToDMA, "\d", desc="Send data to requestor") {
38014184Sgabeblack@google.com    peek(requestQueue_in, RequestMsg) {
38114184Sgabeblack@google.com      enqueue(responseNetwork_out, ResponseMsg, 1) {
38214184Sgabeblack@google.com        out_msg.addr := address;
38314184Sgabeblack@google.com        out_msg.Sender := machineID;
38414184Sgabeblack@google.com        out_msg.SenderMachine := MachineType:Directory;
38514184Sgabeblack@google.com        out_msg.Destination.add(in_msg.Requestor);
38614184Sgabeblack@google.com        out_msg.Dirty := false; // By definition, the block is now clean
38714184Sgabeblack@google.com        out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
38814184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Response_Data;
38914184Sgabeblack@google.com      }
39014184Sgabeblack@google.com    }
39114184Sgabeblack@google.com  }
39214184Sgabeblack@google.com
39314184Sgabeblack@google.com  action(e_ownerIsUnblocker, "e", desc="The owner is now the unblocker") {
39414184Sgabeblack@google.com    peek(unblockNetwork_in, ResponseMsg) {
39514184Sgabeblack@google.com      getDirectoryEntry(address).Owner.clear();
39614184Sgabeblack@google.com      getDirectoryEntry(address).Owner.add(in_msg.Sender);
39714184Sgabeblack@google.com    }
39814184Sgabeblack@google.com  }
39914184Sgabeblack@google.com
40014184Sgabeblack@google.com  action(f_forwardRequest, "f", desc="Forward request to owner") {
40114184Sgabeblack@google.com    peek(requestQueue_in, RequestMsg) {
40214184Sgabeblack@google.com      enqueue(forwardNetwork_out, RequestMsg, directory_latency) {
40314184Sgabeblack@google.com        out_msg.addr := address;
40414184Sgabeblack@google.com        out_msg.Type := in_msg.Type;
40514184Sgabeblack@google.com        out_msg.Requestor := in_msg.Requestor;
40614184Sgabeblack@google.com        out_msg.RequestorMachine := machineIDToMachineType(in_msg.Requestor);
40714184Sgabeblack@google.com        out_msg.Destination.addNetDest(getDirectoryEntry(in_msg.addr).Owner);
40814184Sgabeblack@google.com        out_msg.Acks := getDirectoryEntry(address).Sharers.count();
40914184Sgabeblack@google.com        if (getDirectoryEntry(address).Sharers.isElement(in_msg.Requestor)) {
41014184Sgabeblack@google.com          out_msg.Acks := out_msg.Acks - 1;
41114184Sgabeblack@google.com        }
41214184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Forwarded_Control;
41314184Sgabeblack@google.com      }
41414184Sgabeblack@google.com    }
41514184Sgabeblack@google.com  }
41614184Sgabeblack@google.com
41714184Sgabeblack@google.com  action(f_forwardRequestDirIsRequestor, "\f", desc="Forward request to owner") {
41814184Sgabeblack@google.com    peek(requestQueue_in, RequestMsg) {
41914184Sgabeblack@google.com      enqueue(forwardNetwork_out, RequestMsg, directory_latency) {
42014184Sgabeblack@google.com        out_msg.addr := address;
42114184Sgabeblack@google.com        out_msg.Type := in_msg.Type;
42214184Sgabeblack@google.com        out_msg.Requestor := machineID;
42314184Sgabeblack@google.com        out_msg.RequestorMachine := machineIDToMachineType(in_msg.Requestor);
42414184Sgabeblack@google.com        out_msg.Destination.addNetDest(getDirectoryEntry(in_msg.addr).Owner);
42514184Sgabeblack@google.com        out_msg.Acks := getDirectoryEntry(address).Sharers.count();
42614184Sgabeblack@google.com        if (getDirectoryEntry(address).Sharers.isElement(in_msg.Requestor)) {
42714184Sgabeblack@google.com          out_msg.Acks := out_msg.Acks - 1;
42814184Sgabeblack@google.com        }
42914184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Forwarded_Control;
43014184Sgabeblack@google.com      }
43114184Sgabeblack@google.com    }
43214184Sgabeblack@google.com  }
43314184Sgabeblack@google.com
43414184Sgabeblack@google.com  action(g_sendInvalidations, "g", desc="Send invalidations to sharers, not including the requester") {
43514184Sgabeblack@google.com    peek(requestQueue_in, RequestMsg) {
43614184Sgabeblack@google.com      if ((getDirectoryEntry(in_msg.addr).Sharers.count() > 1) ||
43714184Sgabeblack@google.com          ((getDirectoryEntry(in_msg.addr).Sharers.count() > 0) &&
43814184Sgabeblack@google.com           (getDirectoryEntry(in_msg.addr).Sharers.isElement(in_msg.Requestor) == false))) {
43914184Sgabeblack@google.com        enqueue(forwardNetwork_out, RequestMsg, directory_latency) {
44014184Sgabeblack@google.com          out_msg.addr := address;
44114184Sgabeblack@google.com          out_msg.Type := CoherenceRequestType:INV;
44214184Sgabeblack@google.com          out_msg.Requestor := in_msg.Requestor;
44314184Sgabeblack@google.com          out_msg.RequestorMachine := machineIDToMachineType(in_msg.Requestor);
44414184Sgabeblack@google.com          // out_msg.Destination := getDirectoryEntry(in_msg.addr).Sharers;
44514184Sgabeblack@google.com          out_msg.Destination.addNetDest(getDirectoryEntry(in_msg.addr).Sharers);
44614184Sgabeblack@google.com          out_msg.Destination.remove(in_msg.Requestor);
44714184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:Invalidate_Control;
44814184Sgabeblack@google.com        }
44914184Sgabeblack@google.com      }
45014184Sgabeblack@google.com    }
45114184Sgabeblack@google.com  }
45214184Sgabeblack@google.com
45314184Sgabeblack@google.com  action(i_popIncomingRequestQueue, "i", desc="Pop incoming request queue") {
45414184Sgabeblack@google.com    requestQueue_in.dequeue(clockEdge());
45514184Sgabeblack@google.com  }
45614184Sgabeblack@google.com
45714184Sgabeblack@google.com  action(j_popIncomingUnblockQueue, "j", desc="Pop incoming unblock queue") {
45814184Sgabeblack@google.com    unblockNetwork_in.dequeue(clockEdge());
45914184Sgabeblack@google.com  }
46014184Sgabeblack@google.com
46114184Sgabeblack@google.com  action(m_addUnlockerToSharers, "m", desc="Add the unlocker to the sharer list") {
46214184Sgabeblack@google.com    peek(unblockNetwork_in, ResponseMsg) {
46314184Sgabeblack@google.com      getDirectoryEntry(address).Sharers.add(in_msg.Sender);
46414184Sgabeblack@google.com    }
46514184Sgabeblack@google.com  }
46614184Sgabeblack@google.com
46714184Sgabeblack@google.com  action(n_incrementOutstanding, "n", desc="Increment outstanding requests") {
46814184Sgabeblack@google.com    getDirectoryEntry(address).WaitingUnblocks := getDirectoryEntry(address).WaitingUnblocks + 1;
46914184Sgabeblack@google.com  }
47014184Sgabeblack@google.com
47114184Sgabeblack@google.com  action(o_decrementOutstanding, "o", desc="Decrement outstanding requests") {
47214184Sgabeblack@google.com    getDirectoryEntry(address).WaitingUnblocks := getDirectoryEntry(address).WaitingUnblocks - 1;
47314184Sgabeblack@google.com    assert(getDirectoryEntry(address).WaitingUnblocks >= 0);
47414184Sgabeblack@google.com  }
47514184Sgabeblack@google.com
47614184Sgabeblack@google.com  action(q_popMemQueue, "q", desc="Pop off-chip request queue") {
47714184Sgabeblack@google.com    memQueue_in.dequeue(clockEdge());
47814184Sgabeblack@google.com  }
47914184Sgabeblack@google.com
48014184Sgabeblack@google.com  action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
48114184Sgabeblack@google.com    peek(requestQueue_in, RequestMsg) {
48214184Sgabeblack@google.com      queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
48314184Sgabeblack@google.com    }
48414184Sgabeblack@google.com  }
48514184Sgabeblack@google.com
48614184Sgabeblack@google.com  action(qw_queueMemoryWBFromCacheRequest, "qw", desc="Queue off-chip writeback request") {
48714184Sgabeblack@google.com    peek(requestQueue_in, RequestMsg) {
48814184Sgabeblack@google.com      if (is_valid(tbe)) {
48914184Sgabeblack@google.com        queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
49014184Sgabeblack@google.com                         in_msg.DataBlk);
49114184Sgabeblack@google.com      } else {
49214184Sgabeblack@google.com        queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
49314184Sgabeblack@google.com                         in_msg.DataBlk);
49414184Sgabeblack@google.com      }
49514184Sgabeblack@google.com    }
49614184Sgabeblack@google.com  }
49714184Sgabeblack@google.com
49814184Sgabeblack@google.com  action(qw_queueMemoryWBRequestFromMessageAndTBE, "qwmt",
49914184Sgabeblack@google.com    desc="Queue off-chip writeback request") {
50014184Sgabeblack@google.com    peek(unblockNetwork_in, ResponseMsg) {
50114184Sgabeblack@google.com      DataBlock DataBlk := in_msg.DataBlk;
50214184Sgabeblack@google.com      DataBlk.copyPartial(tbe.DataBlk, getOffset(tbe.PhysicalAddress),
50314184Sgabeblack@google.com                          tbe.Len);
50414184Sgabeblack@google.com      queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
50514184Sgabeblack@google.com                       DataBlk);
50614184Sgabeblack@google.com    }
50714184Sgabeblack@google.com  }
50814184Sgabeblack@google.com
50914184Sgabeblack@google.com  action(qw_queueMemoryWBFromDMARequest, "/qw", desc="Queue off-chip writeback request") {
51014184Sgabeblack@google.com    peek(requestQueue_in, RequestMsg) {
51114184Sgabeblack@google.com      queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
51214184Sgabeblack@google.com                       in_msg.DataBlk);
51314184Sgabeblack@google.com    }
51414184Sgabeblack@google.com  }
51514184Sgabeblack@google.com
51614184Sgabeblack@google.com  action(zz_recycleRequest, "\z", desc="Recycle the request queue") {
51714184Sgabeblack@google.com    requestQueue_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
51814184Sgabeblack@google.com  }
51914184Sgabeblack@google.com
52014184Sgabeblack@google.com  action(a_sendDMAAck, "\a", desc="Send DMA Ack that write completed, along with Inv Ack count") {
52114184Sgabeblack@google.com    peek(requestQueue_in, RequestMsg) {
52214184Sgabeblack@google.com      enqueue(responseNetwork_out, ResponseMsg, 1) {
52314184Sgabeblack@google.com      out_msg.addr := address;
52414184Sgabeblack@google.com      out_msg.Sender := machineID;
52514184Sgabeblack@google.com      out_msg.SenderMachine := MachineType:Directory;
52614184Sgabeblack@google.com      out_msg.Destination.add(in_msg.Requestor);
52714184Sgabeblack@google.com      out_msg.DataBlk := in_msg.DataBlk;
52814184Sgabeblack@google.com      out_msg.Acks := getDirectoryEntry(address).Sharers.count();  // for dma requests
52914184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:DMA_ACK;
53014184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Writeback_Control;
53114184Sgabeblack@google.com      }
53214184Sgabeblack@google.com    }
53314184Sgabeblack@google.com  }
53414184Sgabeblack@google.com
53514184Sgabeblack@google.com  action(a_sendDMAAck2, "\aa", desc="Send DMA Ack that write completed, along with Inv Ack count") {
53614184Sgabeblack@google.com    peek(unblockNetwork_in, ResponseMsg) {
53714184Sgabeblack@google.com      enqueue(responseNetwork_out, ResponseMsg, 1) {
53814184Sgabeblack@google.com      out_msg.addr := address;
53914184Sgabeblack@google.com      out_msg.Sender := machineID;
54014184Sgabeblack@google.com      out_msg.SenderMachine := MachineType:Directory;
54114184Sgabeblack@google.com      if (is_valid(tbe)) {
54214184Sgabeblack@google.com        out_msg.Destination.add(tbe.Requestor);
54314184Sgabeblack@google.com      }
54414184Sgabeblack@google.com      out_msg.DataBlk := in_msg.DataBlk;
54514184Sgabeblack@google.com      out_msg.Acks := getDirectoryEntry(address).Sharers.count();  // for dma requests
54614184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:DMA_ACK;
54714184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Writeback_Control;
54814184Sgabeblack@google.com      }
54914184Sgabeblack@google.com    }
55014184Sgabeblack@google.com  }
55114184Sgabeblack@google.com
55214184Sgabeblack@google.com  action(v_allocateTBE, "v", desc="Allocate TBE entry") {
55314184Sgabeblack@google.com    peek (requestQueue_in, RequestMsg) {
55414184Sgabeblack@google.com      TBEs.allocate(address);
55514184Sgabeblack@google.com      set_tbe(TBEs[address]);
55614184Sgabeblack@google.com      tbe.PhysicalAddress := in_msg.addr;
55714184Sgabeblack@google.com      tbe.Len := in_msg.Len;
55814184Sgabeblack@google.com      tbe.DataBlk := in_msg.DataBlk;
55914184Sgabeblack@google.com      tbe.Requestor := in_msg.Requestor;
56014184Sgabeblack@google.com    }
56114184Sgabeblack@google.com  }
56214184Sgabeblack@google.com
56314184Sgabeblack@google.com  action(w_deallocateTBE, "w", desc="Deallocate TBE entry") {
56414184Sgabeblack@google.com    TBEs.deallocate(address);
56514184Sgabeblack@google.com    unset_tbe();
56614184Sgabeblack@google.com  }
56714184Sgabeblack@google.com
56814184Sgabeblack@google.com
56914184Sgabeblack@google.com  // TRANSITIONS
57014184Sgabeblack@google.com  transition(I, GETX, MM) {
57114184Sgabeblack@google.com    qf_queueMemoryFetchRequest;
57214184Sgabeblack@google.com    i_popIncomingRequestQueue;
57314184Sgabeblack@google.com  }
57414184Sgabeblack@google.com
57514184Sgabeblack@google.com  transition(I, DMA_READ, XI_M) {
57614184Sgabeblack@google.com    qf_queueMemoryFetchRequest;
57714184Sgabeblack@google.com    i_popIncomingRequestQueue;
57814184Sgabeblack@google.com  }
57914184Sgabeblack@google.com
58014184Sgabeblack@google.com  transition(I, DMA_WRITE, XI_U) {
58114184Sgabeblack@google.com    qw_queueMemoryWBFromDMARequest;
58214184Sgabeblack@google.com    a_sendDMAAck;  // ack count may be zero
58314184Sgabeblack@google.com    i_popIncomingRequestQueue;
58414184Sgabeblack@google.com  }
58514184Sgabeblack@google.com
58614184Sgabeblack@google.com  transition(XI_M, Memory_Data, I) {
58714184Sgabeblack@google.com    d_sendDataMsg;  // ack count may be zero
58814184Sgabeblack@google.com    q_popMemQueue;
58914184Sgabeblack@google.com  }
59014184Sgabeblack@google.com
59114184Sgabeblack@google.com  transition(XI_U, Exclusive_Unblock, I) {
59214184Sgabeblack@google.com    cc_clearSharers;
59314184Sgabeblack@google.com    c_clearOwner;
59414184Sgabeblack@google.com    j_popIncomingUnblockQueue;
59514184Sgabeblack@google.com  }
59614184Sgabeblack@google.com
59714184Sgabeblack@google.com  transition(S, GETX, MM) {
59814184Sgabeblack@google.com    qf_queueMemoryFetchRequest;
59914184Sgabeblack@google.com    g_sendInvalidations;
60014184Sgabeblack@google.com    i_popIncomingRequestQueue;
60114184Sgabeblack@google.com  }
60214184Sgabeblack@google.com
60314184Sgabeblack@google.com  transition(S, DMA_READ) {
60414184Sgabeblack@google.com    //qf_queueMemoryFetchRequest;
60514184Sgabeblack@google.com    p_fwdDataToDMA;
60614184Sgabeblack@google.com    //g_sendInvalidations;  // the DMA will collect the invalidations then send an Unblock Exclusive
60714184Sgabeblack@google.com    i_popIncomingRequestQueue;
60814184Sgabeblack@google.com  }
60914184Sgabeblack@google.com
61014184Sgabeblack@google.com  transition(S, DMA_WRITE, XI_U) {
61114184Sgabeblack@google.com    qw_queueMemoryWBFromDMARequest;
61214184Sgabeblack@google.com    a_sendDMAAck;  // ack count may be zero
61314184Sgabeblack@google.com    g_sendInvalidations;  // the DMA will collect invalidations
61414184Sgabeblack@google.com    i_popIncomingRequestQueue;
61514184Sgabeblack@google.com  }
61614184Sgabeblack@google.com
61714184Sgabeblack@google.com  transition(I, GETS, IS) {
61814184Sgabeblack@google.com    qf_queueMemoryFetchRequest;
61914184Sgabeblack@google.com    i_popIncomingRequestQueue;
62014184Sgabeblack@google.com  }
62114184Sgabeblack@google.com
62214184Sgabeblack@google.com  transition({S, SS}, GETS, SS) {
62314184Sgabeblack@google.com    qf_queueMemoryFetchRequest;
62414184Sgabeblack@google.com    n_incrementOutstanding;
62514184Sgabeblack@google.com    i_popIncomingRequestQueue;
62614184Sgabeblack@google.com  }
62714184Sgabeblack@google.com
62814184Sgabeblack@google.com  transition({I, S}, PUTO) {
62914184Sgabeblack@google.com    b_sendWriteBackNack;
63014184Sgabeblack@google.com    i_popIncomingRequestQueue;
63114184Sgabeblack@google.com  }
63214184Sgabeblack@google.com
63314184Sgabeblack@google.com  transition({I, S, O}, PUTX) {
63414184Sgabeblack@google.com    b_sendWriteBackNack;
63514184Sgabeblack@google.com    i_popIncomingRequestQueue;
63614184Sgabeblack@google.com  }
63714184Sgabeblack@google.com
63814184Sgabeblack@google.com  transition(O, GETX, MM) {
63914184Sgabeblack@google.com    f_forwardRequest;
64014184Sgabeblack@google.com    g_sendInvalidations;
64114184Sgabeblack@google.com    i_popIncomingRequestQueue;
64214184Sgabeblack@google.com  }
64314184Sgabeblack@google.com
64414184Sgabeblack@google.com  transition(O, DMA_READ, OD) {
64514184Sgabeblack@google.com    f_forwardRequest;     // this will cause the data to go to DMA directly
64614184Sgabeblack@google.com    //g_sendInvalidations;  // this will cause acks to be sent to the DMA
64714184Sgabeblack@google.com    i_popIncomingRequestQueue;
64814184Sgabeblack@google.com  }
64914184Sgabeblack@google.com
65014184Sgabeblack@google.com  transition(OD, DMA_ACK, O) {
65114184Sgabeblack@google.com    j_popIncomingUnblockQueue;
65214184Sgabeblack@google.com  }
65314184Sgabeblack@google.com
65414184Sgabeblack@google.com  transition({O,M}, DMA_WRITE, OI_D) {
65514184Sgabeblack@google.com    f_forwardRequestDirIsRequestor;    // need the modified data before we can proceed
65614184Sgabeblack@google.com    g_sendInvalidations;               // these go to the DMA Controller
65714184Sgabeblack@google.com    v_allocateTBE;
65814184Sgabeblack@google.com    i_popIncomingRequestQueue;
65914184Sgabeblack@google.com  }
66014184Sgabeblack@google.com
66114184Sgabeblack@google.com  transition(OI_D, Data, XI_U) {
66214184Sgabeblack@google.com    qw_queueMemoryWBRequestFromMessageAndTBE;
66314184Sgabeblack@google.com    a_sendDMAAck2;  // ack count may be zero
66414184Sgabeblack@google.com    w_deallocateTBE;
66514184Sgabeblack@google.com    j_popIncomingUnblockQueue;
66614184Sgabeblack@google.com  }
66714184Sgabeblack@google.com
66814184Sgabeblack@google.com  transition({O, OO}, GETS, OO) {
66914184Sgabeblack@google.com    f_forwardRequest;
67014184Sgabeblack@google.com    n_incrementOutstanding;
67114184Sgabeblack@google.com    i_popIncomingRequestQueue;
67214184Sgabeblack@google.com  }
67314184Sgabeblack@google.com
67414184Sgabeblack@google.com  transition(M, GETX, MM) {
67514184Sgabeblack@google.com    f_forwardRequest;
67614184Sgabeblack@google.com    i_popIncomingRequestQueue;
67714184Sgabeblack@google.com  }
67814184Sgabeblack@google.com
67914184Sgabeblack@google.com  // no exclusive unblock will show up to the directory
68014184Sgabeblack@google.com  transition(M, DMA_READ, MD) {
68114184Sgabeblack@google.com    f_forwardRequest;     // this will cause the data to go to DMA directly
68214184Sgabeblack@google.com    i_popIncomingRequestQueue;
68314184Sgabeblack@google.com  }
68414184Sgabeblack@google.com
68514184Sgabeblack@google.com  transition(MD, DMA_ACK, M) {
68614184Sgabeblack@google.com    j_popIncomingUnblockQueue;
68714184Sgabeblack@google.com  }
68814184Sgabeblack@google.com
68914184Sgabeblack@google.com  transition(M, GETS, MO) {
69014184Sgabeblack@google.com    f_forwardRequest;
69114184Sgabeblack@google.com    i_popIncomingRequestQueue;
69214184Sgabeblack@google.com  }
69314184Sgabeblack@google.com
69414184Sgabeblack@google.com  transition(M, PUTX, MI) {
69514184Sgabeblack@google.com    a_sendWriteBackAck;
69614184Sgabeblack@google.com    i_popIncomingRequestQueue;
69714184Sgabeblack@google.com  }
69814184Sgabeblack@google.com
69914184Sgabeblack@google.com  // happens if M->O transition happens on-chip
70014184Sgabeblack@google.com  transition(M, PUTO, MI) {
70114184Sgabeblack@google.com    a_sendWriteBackAck;
70214184Sgabeblack@google.com    i_popIncomingRequestQueue;
70314184Sgabeblack@google.com  }
70414184Sgabeblack@google.com
70514184Sgabeblack@google.com  transition(M, PUTO_SHARERS, MIS) {
70614184Sgabeblack@google.com    a_sendWriteBackAck;
70714184Sgabeblack@google.com    i_popIncomingRequestQueue;
70814184Sgabeblack@google.com  }
70914184Sgabeblack@google.com
71014184Sgabeblack@google.com  transition(O, PUTO, OS) {
71114184Sgabeblack@google.com    a_sendWriteBackAck;
71214184Sgabeblack@google.com    i_popIncomingRequestQueue;
71314184Sgabeblack@google.com  }
71414184Sgabeblack@google.com
71514184Sgabeblack@google.com  transition(O, PUTO_SHARERS, OSS) {
71614184Sgabeblack@google.com    a_sendWriteBackAck;
71714184Sgabeblack@google.com    i_popIncomingRequestQueue;
71814184Sgabeblack@google.com  }
71914184Sgabeblack@google.com
72014184Sgabeblack@google.com
72114184Sgabeblack@google.com  transition({MM, MO, MI, MIS, OS, OSS, XI_M, XI_U, OI_D, OD, MD}, {GETS, GETX, PUTO, PUTO_SHARERS, PUTX, DMA_READ, DMA_WRITE}) {
72214184Sgabeblack@google.com    zz_recycleRequest;
72314184Sgabeblack@google.com  }
72414184Sgabeblack@google.com
72514184Sgabeblack@google.com  transition({MM, MO}, Exclusive_Unblock, M) {
72614184Sgabeblack@google.com    cc_clearSharers;
72714184Sgabeblack@google.com    e_ownerIsUnblocker;
72814184Sgabeblack@google.com    j_popIncomingUnblockQueue;
72914184Sgabeblack@google.com  }
73014184Sgabeblack@google.com
73114184Sgabeblack@google.com  transition(MO, Unblock, O) {
73214184Sgabeblack@google.com    m_addUnlockerToSharers;
73314184Sgabeblack@google.com    j_popIncomingUnblockQueue;
73414184Sgabeblack@google.com  }
73514184Sgabeblack@google.com
73614184Sgabeblack@google.com  transition({IS, SS, OO}, {GETX, PUTO, PUTO_SHARERS, PUTX, DMA_READ, DMA_WRITE}) {
73714184Sgabeblack@google.com    zz_recycleRequest;
73814184Sgabeblack@google.com  }
73914184Sgabeblack@google.com
74014184Sgabeblack@google.com  transition(IS, GETS) {
74114184Sgabeblack@google.com    zz_recycleRequest;
74214184Sgabeblack@google.com  }
74314184Sgabeblack@google.com
74414184Sgabeblack@google.com  transition(IS, Unblock, S) {
74514184Sgabeblack@google.com    m_addUnlockerToSharers;
74614184Sgabeblack@google.com    j_popIncomingUnblockQueue;
74714184Sgabeblack@google.com  }
74814184Sgabeblack@google.com
74914184Sgabeblack@google.com  transition(IS, Exclusive_Unblock, M) {
75014184Sgabeblack@google.com    cc_clearSharers;
75114184Sgabeblack@google.com    e_ownerIsUnblocker;
75214184Sgabeblack@google.com    j_popIncomingUnblockQueue;
75314184Sgabeblack@google.com  }
75414184Sgabeblack@google.com
75514184Sgabeblack@google.com  transition(SS, Unblock) {
75614184Sgabeblack@google.com    m_addUnlockerToSharers;
75714184Sgabeblack@google.com    o_decrementOutstanding;
75814184Sgabeblack@google.com    j_popIncomingUnblockQueue;
75914184Sgabeblack@google.com  }
76014184Sgabeblack@google.com
76114184Sgabeblack@google.com  transition(SS, Last_Unblock, S) {
76214184Sgabeblack@google.com    m_addUnlockerToSharers;
76314184Sgabeblack@google.com    o_decrementOutstanding;
76414184Sgabeblack@google.com    j_popIncomingUnblockQueue;
76514184Sgabeblack@google.com  }
76614184Sgabeblack@google.com
76714184Sgabeblack@google.com  transition(OO, Unblock) {
76814184Sgabeblack@google.com    m_addUnlockerToSharers;
76914184Sgabeblack@google.com    o_decrementOutstanding;
77014184Sgabeblack@google.com    j_popIncomingUnblockQueue;
77114184Sgabeblack@google.com  }
77214184Sgabeblack@google.com
77314184Sgabeblack@google.com  transition(OO, Last_Unblock, O) {
77414184Sgabeblack@google.com    m_addUnlockerToSharers;
77514184Sgabeblack@google.com    o_decrementOutstanding;
77614184Sgabeblack@google.com    j_popIncomingUnblockQueue;
77714184Sgabeblack@google.com  }
77814184Sgabeblack@google.com
77914184Sgabeblack@google.com  transition(MI, Dirty_Writeback, I) {
78014184Sgabeblack@google.com    c_clearOwner;
78114184Sgabeblack@google.com    cc_clearSharers;
78214184Sgabeblack@google.com    qw_queueMemoryWBFromCacheRequest;
78314184Sgabeblack@google.com    i_popIncomingRequestQueue;
78414184Sgabeblack@google.com  }
78514184Sgabeblack@google.com
78614184Sgabeblack@google.com  transition(MIS, Dirty_Writeback, S) {
78714184Sgabeblack@google.com    c_moveOwnerToSharer;
78814184Sgabeblack@google.com    qw_queueMemoryWBFromCacheRequest;
78914184Sgabeblack@google.com    i_popIncomingRequestQueue;
79014184Sgabeblack@google.com  }
79114184Sgabeblack@google.com
79214184Sgabeblack@google.com  transition(MIS, Clean_Writeback, S) {
79314184Sgabeblack@google.com    c_moveOwnerToSharer;
79414184Sgabeblack@google.com    i_popIncomingRequestQueue;
79514184Sgabeblack@google.com  }
79614184Sgabeblack@google.com
79714184Sgabeblack@google.com  transition(OS, Dirty_Writeback, S) {
79814184Sgabeblack@google.com    c_clearOwner;
79914184Sgabeblack@google.com    qw_queueMemoryWBFromCacheRequest;
80014184Sgabeblack@google.com    i_popIncomingRequestQueue;
80114184Sgabeblack@google.com  }
80214184Sgabeblack@google.com
80314184Sgabeblack@google.com  transition(OSS, Dirty_Writeback, S) {
80414184Sgabeblack@google.com    c_moveOwnerToSharer;
80514184Sgabeblack@google.com    qw_queueMemoryWBFromCacheRequest;
80614184Sgabeblack@google.com    i_popIncomingRequestQueue;
80714184Sgabeblack@google.com  }
80814184Sgabeblack@google.com
80914184Sgabeblack@google.com  transition(OSS, Clean_Writeback, S) {
81014184Sgabeblack@google.com    c_moveOwnerToSharer;
81114184Sgabeblack@google.com    i_popIncomingRequestQueue;
81214184Sgabeblack@google.com  }
81314184Sgabeblack@google.com
81414184Sgabeblack@google.com  transition(MI, Clean_Writeback, I) {
81514184Sgabeblack@google.com    c_clearOwner;
81614184Sgabeblack@google.com    cc_clearSharers;
81714184Sgabeblack@google.com    i_popIncomingRequestQueue;
81814184Sgabeblack@google.com  }
81914184Sgabeblack@google.com
82014184Sgabeblack@google.com  transition(OS, Clean_Writeback, S) {
82114184Sgabeblack@google.com    c_clearOwner;
82214184Sgabeblack@google.com    i_popIncomingRequestQueue;
82314184Sgabeblack@google.com  }
82414184Sgabeblack@google.com
82514184Sgabeblack@google.com  transition({MI, MIS}, Unblock, M) {
82614184Sgabeblack@google.com    j_popIncomingUnblockQueue;
82714184Sgabeblack@google.com  }
82814184Sgabeblack@google.com
82914184Sgabeblack@google.com  transition({OS, OSS}, Unblock, O) {
83014184Sgabeblack@google.com    j_popIncomingUnblockQueue;
83114184Sgabeblack@google.com  }
83214184Sgabeblack@google.com
83314184Sgabeblack@google.com  transition({I, S, O, M, IS, SS, OO, MO, MM, MI, MIS, OS, OSS}, Memory_Data) {
83414184Sgabeblack@google.com    d_sendDataMsg;
83514184Sgabeblack@google.com    q_popMemQueue;
83614184Sgabeblack@google.com  }
83714184Sgabeblack@google.com
83814184Sgabeblack@google.com  transition({I, S, O, M, IS, SS, OO, MO, MM, MI, MIS, OS, OSS, XI_U, XI_M}, Memory_Ack) {
83914184Sgabeblack@google.com    //a_sendAck;
84014184Sgabeblack@google.com    q_popMemQueue;
84114184Sgabeblack@google.com  }
84214184Sgabeblack@google.com
84314184Sgabeblack@google.com}
844