/*
 * Copyright (c) 2010-2015 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder 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 HOLDER 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.
 *
 * Author: Blake Hechtman
 */

machine(MachineType:TCC, "TCC Cache")
 : CacheMemory * L2cache;
   bool WB; /*is this cache Writeback?*/
   Cycles l2_request_latency := 50;
   Cycles l2_response_latency := 20;

  // From the TCPs or SQCs
  MessageBuffer * requestFromTCP, network="From", virtual_network="1", vnet_type="request";
  // To the Cores. TCC deals only with TCPs/SQCs.
  MessageBuffer * responseToCore, network="To", virtual_network="3", vnet_type="response";
  // From the NB
  MessageBuffer * probeFromNB, network="From", virtual_network="0", vnet_type="request";
  MessageBuffer * responseFromNB, network="From", virtual_network="2", vnet_type="response";
  // To the NB
  MessageBuffer * requestToNB, network="To", virtual_network="0", vnet_type="request";
  MessageBuffer * responseToNB, network="To", virtual_network="2", vnet_type="response";
  MessageBuffer * unblockToNB, network="To", virtual_network="4", vnet_type="unblock";

  MessageBuffer * triggerQueue;

{
  // EVENTS
  enumeration(Event, desc="TCC Events") {
    // Requests coming from the Cores
    RdBlk,                  desc="RdBlk event";
    WrVicBlk,               desc="L1 Write Through";
    WrVicBlkBack,           desc="L1 Write Through(dirty cache)";
    Atomic,                 desc="Atomic Op";
    AtomicDone,             desc="AtomicOps Complete";
    AtomicNotDone,          desc="AtomicOps not Complete";
    Data,                   desc="data messgae";
    // Coming from this TCC
    L2_Repl,                desc="L2 Replacement";
    // Probes
    PrbInv,                 desc="Invalidating probe";
    // Coming from Memory Controller
    WBAck,                  desc="writethrough ack from memory";
  }

  // STATES
  state_declaration(State, desc="TCC State", default="TCC_State_I") {
    M, AccessPermission:Read_Write, desc="Modified(dirty cache only)";
    W, AccessPermission:Read_Write, desc="Written(dirty cache only)";
    V, AccessPermission:Read_Only,  desc="Valid";
    I, AccessPermission:Invalid,    desc="Invalid";
    IV, AccessPermission:Busy,      desc="Waiting for Data";
    WI, AccessPermission:Busy,      desc="Waiting on Writethrough Ack";
    A, AccessPermission:Busy,       desc="Invalid waiting on atomici Data";
  }

  enumeration(RequestType, desc="To communicate stats from transitions to recordStats") {
    DataArrayRead,    desc="Read the data array";
    DataArrayWrite,   desc="Write the data array";
    TagArrayRead,     desc="Read the data array";
    TagArrayWrite,    desc="Write the data array";
  }


  // STRUCTURES

  structure(Entry, desc="...", interface="AbstractCacheEntry") {
    State CacheState,           desc="cache state";
    bool Dirty,                 desc="Is the data dirty (diff from memory?)";
    DataBlock DataBlk,          desc="Data for the block";
    WriteMask writeMask,        desc="Dirty byte mask";
  }

  structure(TBE, desc="...") {
    State TBEState,     desc="Transient state";
    DataBlock DataBlk,  desc="data for the block";
    bool Dirty,         desc="Is the data dirty?";
    bool Shared,        desc="Victim hit by shared probe";
    MachineID From,     desc="Waiting for writeback from...";
    NetDest Destination, desc="Data destination";
    int numAtomics,     desc="number remaining atomics";
    int atomicDoneCnt,  desc="number AtomicDones triggered";
  }

  structure(TBETable, external="yes") {
    TBE lookup(Addr);
    void allocate(Addr);
    void deallocate(Addr);
    bool isPresent(Addr);
  }

  TBETable TBEs, template="<TCC_TBE>", constructor="m_number_of_TBEs";

  void set_cache_entry(AbstractCacheEntry b);
  void unset_cache_entry();
  void set_tbe(TBE b);
  void unset_tbe();
  void wakeUpAllBuffers();
  void wakeUpBuffers(Addr a);
  void wakeUpAllBuffers(Addr a);

  MachineID mapAddressToMachine(Addr addr, MachineType mtype);

  // FUNCTION DEFINITIONS
  Tick clockEdge();

  Entry getCacheEntry(Addr addr), return_by_pointer="yes" {
    return static_cast(Entry, "pointer", L2cache.lookup(addr));
  }

  DataBlock getDataBlock(Addr addr), return_by_ref="yes" {
    return getCacheEntry(addr).DataBlk;
  }

  bool presentOrAvail(Addr addr) {
    return L2cache.isTagPresent(addr) || L2cache.cacheAvail(addr);
  }

  State getState(TBE tbe, Entry cache_entry, Addr addr) {
    if (is_valid(tbe)) {
      return tbe.TBEState;
    } else if (is_valid(cache_entry)) {
      return cache_entry.CacheState;
    }
    return State:I;
  }

  void setState(TBE tbe, Entry cache_entry, Addr addr, State state) {
    if (is_valid(tbe)) {
        tbe.TBEState := state;
    }

    if (is_valid(cache_entry)) {
        cache_entry.CacheState := state;
    }
  }

  void functionalRead(Addr addr, Packet *pkt) {
    TBE tbe := TBEs.lookup(addr);
    if(is_valid(tbe)) {
      testAndRead(addr, tbe.DataBlk, pkt);
    } else {
      functionalMemoryRead(pkt);
    }
  }

  int functionalWrite(Addr addr, Packet *pkt) {
    int num_functional_writes := 0;

    TBE tbe := TBEs.lookup(addr);
    if(is_valid(tbe)) {
      num_functional_writes := num_functional_writes +
            testAndWrite(addr, tbe.DataBlk, pkt);
    }

    num_functional_writes := num_functional_writes +
        functionalMemoryWrite(pkt);
    return num_functional_writes;
  }

  AccessPermission getAccessPermission(Addr addr) {
    TBE tbe := TBEs.lookup(addr);
    if(is_valid(tbe)) {
      return TCC_State_to_permission(tbe.TBEState);
    }

    Entry cache_entry := getCacheEntry(addr);
    if(is_valid(cache_entry)) {
      return TCC_State_to_permission(cache_entry.CacheState);
    }

    return AccessPermission:NotPresent;
  }

  void setAccessPermission(Entry cache_entry, Addr addr, State state) {
    if (is_valid(cache_entry)) {
      cache_entry.changePermission(TCC_State_to_permission(state));
    }
  }

  void recordRequestType(RequestType request_type, Addr addr) {
    if (request_type == RequestType:DataArrayRead) {
        L2cache.recordRequestType(CacheRequestType:DataArrayRead, addr);
    } else if (request_type == RequestType:DataArrayWrite) {
        L2cache.recordRequestType(CacheRequestType:DataArrayWrite, addr);
    } else if (request_type == RequestType:TagArrayRead) {
        L2cache.recordRequestType(CacheRequestType:TagArrayRead, addr);
    } else if (request_type == RequestType:TagArrayWrite) {
        L2cache.recordRequestType(CacheRequestType:TagArrayWrite, addr);
    }
  }

  bool checkResourceAvailable(RequestType request_type, Addr addr) {
    if (request_type == RequestType:DataArrayRead) {
      return L2cache.checkResourceAvailable(CacheResourceType:DataArray, addr);
    } else if (request_type == RequestType:DataArrayWrite) {
      return L2cache.checkResourceAvailable(CacheResourceType:DataArray, addr);
    } else if (request_type == RequestType:TagArrayRead) {
      return L2cache.checkResourceAvailable(CacheResourceType:TagArray, addr);
    } else if (request_type == RequestType:TagArrayWrite) {
      return L2cache.checkResourceAvailable(CacheResourceType:TagArray, addr);
    } else {
      error("Invalid RequestType type in checkResourceAvailable");
      return true;
    }
  }


  // ** OUT_PORTS **

  // Three classes of ports
  // Class 1: downward facing network links to NB
  out_port(requestToNB_out, CPURequestMsg, requestToNB);
  out_port(responseToNB_out, ResponseMsg, responseToNB);
  out_port(unblockToNB_out, UnblockMsg, unblockToNB);

  // Class 2: upward facing ports to GPU cores
  out_port(responseToCore_out, ResponseMsg, responseToCore);

  out_port(triggerQueue_out, TriggerMsg, triggerQueue);
  //
  // request queue going to NB
  //


// ** IN_PORTS **
  in_port(triggerQueue_in, TriggerMsg, triggerQueue) {
    if (triggerQueue_in.isReady(clockEdge())) {
      peek(triggerQueue_in, TriggerMsg) {
        TBE tbe := TBEs.lookup(in_msg.addr);
        Entry cache_entry := getCacheEntry(in_msg.addr);

        // There is a possible race where multiple AtomicDone triggers can be
        // sent if another Atomic to the same address is issued after the
        // AtomicDone is triggered but before the message arrives here. For
        // that case we count the number of AtomicDones in flight for this
        // address and only call AtomicDone to deallocate the TBE when it is
        // the last in flight message.
        if (tbe.numAtomics == 0 && tbe.atomicDoneCnt == 1) {
            trigger(Event:AtomicDone, in_msg.addr, cache_entry, tbe);
        } else {
            trigger(Event:AtomicNotDone, in_msg.addr, cache_entry, tbe);
        }
      }
    }
  }



  in_port(responseFromNB_in, ResponseMsg, responseFromNB) {
    if (responseFromNB_in.isReady(clockEdge())) {
      peek(responseFromNB_in, ResponseMsg, block_on="addr") {
        TBE tbe := TBEs.lookup(in_msg.addr);
        Entry cache_entry := getCacheEntry(in_msg.addr);
        if (in_msg.Type == CoherenceResponseType:NBSysResp) {
          if(presentOrAvail(in_msg.addr)) {
            trigger(Event:Data, in_msg.addr, cache_entry, tbe);
          } else {
            Addr victim :=  L2cache.cacheProbe(in_msg.addr);
            trigger(Event:L2_Repl, victim, getCacheEntry(victim), TBEs.lookup(victim));
          }
        } else if (in_msg.Type == CoherenceResponseType:NBSysWBAck) {
          trigger(Event:WBAck, in_msg.addr, cache_entry, tbe);
        } else {
          error("Unexpected Response Message to Core");
        }
      }
    }
  }

  // Finally handling incoming requests (from TCP) and probes (from NB).
  in_port(probeNetwork_in, NBProbeRequestMsg, probeFromNB) {
    if (probeNetwork_in.isReady(clockEdge())) {
      peek(probeNetwork_in, NBProbeRequestMsg) {
        DPRINTF(RubySlicc, "%s\n", in_msg);
        Entry cache_entry := getCacheEntry(in_msg.addr);
        TBE tbe := TBEs.lookup(in_msg.addr);
        trigger(Event:PrbInv, in_msg.addr, cache_entry, tbe);
      }
    }
  }

  in_port(coreRequestNetwork_in, CPURequestMsg, requestFromTCP, rank=0) {
    if (coreRequestNetwork_in.isReady(clockEdge())) {
      peek(coreRequestNetwork_in, CPURequestMsg) {
        TBE tbe := TBEs.lookup(in_msg.addr);
        Entry cache_entry := getCacheEntry(in_msg.addr);
        if (in_msg.Type == CoherenceRequestType:WriteThrough) {
            if(WB) {
                if(presentOrAvail(in_msg.addr)) {
                    trigger(Event:WrVicBlkBack, in_msg.addr, cache_entry, tbe);
                } else {
                    Addr victim :=  L2cache.cacheProbe(in_msg.addr);
                    trigger(Event:L2_Repl, victim, getCacheEntry(victim), TBEs.lookup(victim));
                }
            } else {
                trigger(Event:WrVicBlk, in_msg.addr, cache_entry, tbe);
            }
        } else if (in_msg.Type == CoherenceRequestType:Atomic) {
          trigger(Event:Atomic, in_msg.addr, cache_entry, tbe);
        } else if (in_msg.Type == CoherenceRequestType:RdBlk) {
          trigger(Event:RdBlk, in_msg.addr, cache_entry, tbe);
        } else {
          DPRINTF(RubySlicc, "%s\n", in_msg);
          error("Unexpected Response Message to Core");
        }
      }
    }
  }
  // BEGIN ACTIONS

  action(i_invL2, "i", desc="invalidate TCC cache block") {
    if (is_valid(cache_entry)) {
        L2cache.deallocate(address);
    }
    unset_cache_entry();
  }

  action(sd_sendData, "sd", desc="send Shared response") {
    peek(coreRequestNetwork_in, CPURequestMsg) {
      enqueue(responseToCore_out, ResponseMsg, l2_response_latency) {
        out_msg.addr := address;
        out_msg.Type := CoherenceResponseType:TDSysResp;
        out_msg.Sender := machineID;
        out_msg.Destination.add(in_msg.Requestor);
        out_msg.DataBlk := cache_entry.DataBlk;
        out_msg.MessageSize := MessageSizeType:Response_Data;
        out_msg.Dirty := false;
        out_msg.State := CoherenceState:Shared;
        DPRINTF(RubySlicc, "%s\n", out_msg);
      }
    }
  }


  action(sdr_sendDataResponse, "sdr", desc="send Shared response") {
    enqueue(responseToCore_out, ResponseMsg, l2_response_latency) {
      out_msg.addr := address;
      out_msg.Type := CoherenceResponseType:TDSysResp;
      out_msg.Sender := machineID;
      out_msg.Destination := tbe.Destination;
      out_msg.DataBlk := cache_entry.DataBlk;
      out_msg.MessageSize := MessageSizeType:Response_Data;
      out_msg.Dirty := false;
      out_msg.State := CoherenceState:Shared;
      DPRINTF(RubySlicc, "%s\n", out_msg);
    }
    enqueue(unblockToNB_out, UnblockMsg, 1) {
      out_msg.addr := address;
      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
      out_msg.MessageSize := MessageSizeType:Unblock_Control;
      DPRINTF(RubySlicc, "%s\n", out_msg);
    }
  }


  action(rd_requestData, "r", desc="Miss in L2, pass on") {
    if(tbe.Destination.count()==1){
      peek(coreRequestNetwork_in, CPURequestMsg) {
        enqueue(requestToNB_out, CPURequestMsg, l2_request_latency) {
          out_msg.addr := address;
          out_msg.Type := in_msg.Type;
          out_msg.Requestor := machineID;
          out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
          out_msg.Shared := false; // unneeded for this request
          out_msg.MessageSize := in_msg.MessageSize;
          DPRINTF(RubySlicc, "%s\n", out_msg);
        }
      }
    }
  }

  action(w_sendResponseWBAck, "w", desc="send WB Ack") {
    peek(responseFromNB_in, ResponseMsg) {
      enqueue(responseToCore_out, ResponseMsg, l2_response_latency) {
        out_msg.addr := address;
        out_msg.Type := CoherenceResponseType:TDSysWBAck;
        out_msg.Destination.clear();
        out_msg.Destination.add(in_msg.WTRequestor);
        out_msg.Sender := machineID;
        out_msg.MessageSize := MessageSizeType:Writeback_Control;
        out_msg.instSeqNum := in_msg.instSeqNum;
      }
    }
  }

  action(swb_sendWBAck, "swb", desc="send WB Ack") {
    peek(coreRequestNetwork_in, CPURequestMsg) {
      enqueue(responseToCore_out, ResponseMsg, l2_response_latency) {
        out_msg.addr := address;
        out_msg.Type := CoherenceResponseType:TDSysWBAck;
        out_msg.Destination.clear();
        out_msg.Destination.add(in_msg.Requestor);
        out_msg.Sender := machineID;
        out_msg.MessageSize := MessageSizeType:Writeback_Control;
        out_msg.instSeqNum := in_msg.instSeqNum;
      }
    }
  }

  action(ar_sendAtomicResponse, "ar", desc="send Atomic Ack") {
    peek(responseFromNB_in, ResponseMsg) {
        enqueue(responseToCore_out, ResponseMsg, l2_response_latency) {
          out_msg.addr := address;
          out_msg.Type := CoherenceResponseType:TDSysResp;
          out_msg.Destination.add(in_msg.WTRequestor);
          out_msg.Sender := machineID;
          out_msg.MessageSize := in_msg.MessageSize;
          out_msg.DataBlk := in_msg.DataBlk;
        }
    }
  }

  action(a_allocateBlock, "a", desc="allocate TCC block") {
    if (is_invalid(cache_entry)) {
      set_cache_entry(L2cache.allocate(address, new Entry));
      cache_entry.writeMask.clear();
    }
  }

  action(p_profileMiss, "pm", desc="Profile cache miss") {
      L2cache.profileDemandMiss();
  }

  action(p_profileHit, "ph", desc="Profile cache hit") {
      L2cache.profileDemandHit();
  }

  action(t_allocateTBE, "t", desc="allocate TBE Entry") {
    if (is_invalid(tbe)) {
      check_allocate(TBEs);
      TBEs.allocate(address);
      set_tbe(TBEs.lookup(address));
      tbe.Destination.clear();
      tbe.numAtomics := 0;
      tbe.atomicDoneCnt := 0;
    }
    if (coreRequestNetwork_in.isReady(clockEdge())) {
      peek(coreRequestNetwork_in, CPURequestMsg) {
        if(in_msg.Type == CoherenceRequestType:RdBlk || in_msg.Type == CoherenceRequestType:Atomic){
          tbe.Destination.add(in_msg.Requestor);
        }
      }
    }
  }

  action(dt_deallocateTBE, "dt", desc="Deallocate TBE entry") {
    tbe.Destination.clear();
    TBEs.deallocate(address);
    unset_tbe();
  }

  action(wcb_writeCacheBlock, "wcb", desc="write data to TCC") {
    peek(responseFromNB_in, ResponseMsg) {
      cache_entry.DataBlk := in_msg.DataBlk;
      DPRINTF(RubySlicc, "Writing to TCC: %s\n", in_msg);
    }
  }

  action(wdb_writeDirtyBytes, "wdb", desc="write data to TCC") {
    peek(coreRequestNetwork_in, CPURequestMsg) {
      cache_entry.DataBlk.copyPartial(in_msg.DataBlk,in_msg.writeMask);
      cache_entry.writeMask.orMask(in_msg.writeMask);
      DPRINTF(RubySlicc, "Writing to TCC: %s\n", in_msg);
    }
  }

  action(wt_writeThrough, "wt", desc="write back data") {
    peek(coreRequestNetwork_in, CPURequestMsg) {
      enqueue(requestToNB_out, CPURequestMsg, l2_request_latency) {
        out_msg.addr := address;
        out_msg.Requestor := machineID;
        out_msg.WTRequestor := in_msg.Requestor;
        out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
        out_msg.MessageSize := MessageSizeType:Data;
        out_msg.Type := CoherenceRequestType:WriteThrough;
        out_msg.Dirty := true;
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.writeMask.orMask(in_msg.writeMask);
        out_msg.instSeqNum := in_msg.instSeqNum;
      }
    }
  }

  action(wb_writeBack, "wb", desc="write back data") {
    enqueue(requestToNB_out, CPURequestMsg, l2_request_latency) {
      out_msg.addr := address;
      out_msg.Requestor := machineID;
      out_msg.WTRequestor := machineID;
      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
      out_msg.MessageSize := MessageSizeType:Data;
      out_msg.Type := CoherenceRequestType:WriteThrough;
      out_msg.Dirty := true;
      out_msg.DataBlk := cache_entry.DataBlk;
      out_msg.writeMask.orMask(cache_entry.writeMask);
    }
  }

  action(at_atomicThrough, "at", desc="write back data") {
    peek(coreRequestNetwork_in, CPURequestMsg) {
      enqueue(requestToNB_out, CPURequestMsg, l2_request_latency) {
        out_msg.addr := address;
        out_msg.Requestor := machineID;
        out_msg.WTRequestor := in_msg.Requestor;
        out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
        out_msg.MessageSize := MessageSizeType:Data;
        out_msg.Type := CoherenceRequestType:Atomic;
        out_msg.Dirty := true;
        out_msg.writeMask.orMask(in_msg.writeMask);
      }
    }
  }

  action(pi_sendProbeResponseInv, "pi", desc="send probe ack inv, no data") {
    enqueue(responseToNB_out, ResponseMsg, 1) {
      out_msg.addr := address;
      out_msg.Type := CoherenceResponseType:CPUPrbResp;  // TCC, L3  respond in same way to probes
      out_msg.Sender := machineID;
      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
      out_msg.Dirty := false;
      out_msg.Hit := false;
      out_msg.Ntsl := true;
      out_msg.State := CoherenceState:NA;
      out_msg.MessageSize := MessageSizeType:Response_Control;
    }
  }
  action(ut_updateTag, "ut", desc="update Tag (i.e. set MRU)") {
    L2cache.setMRU(address);
  }

  action(p_popRequestQueue, "p", desc="pop request queue") {
    coreRequestNetwork_in.dequeue(clockEdge());
  }

  action(pr_popResponseQueue, "pr", desc="pop response queue") {
    responseFromNB_in.dequeue(clockEdge());
  }

  action(pp_popProbeQueue, "pp", desc="pop probe queue") {
    probeNetwork_in.dequeue(clockEdge());
  }

  action(st_stallAndWaitRequest, "st", desc="Stall and wait on the address") {
    stall_and_wait(coreRequestNetwork_in, address);
  }

  action(wada_wakeUpAllDependentsAddr, "wada", desc="Wake up any requests waiting for this address") {
    wakeUpAllBuffers(address);
  }

  action(z_stall, "z", desc="stall") {
      // built-in
  }


  action(ina_incrementNumAtomics, "ina", desc="inc num atomics") {
    tbe.numAtomics := tbe.numAtomics + 1;
  }


  action(dna_decrementNumAtomics, "dna", desc="inc num atomics") {
    tbe.numAtomics := tbe.numAtomics - 1;
    if (tbe.numAtomics==0) {
      enqueue(triggerQueue_out, TriggerMsg, 1) {
        tbe.atomicDoneCnt := tbe.atomicDoneCnt + 1;
        out_msg.addr := address;
        out_msg.Type := TriggerType:AtomicDone;
      }
    }
  }

  action(dadc_decrementAtomicDoneCnt, "dadc", desc="decrement atomics done cnt flag") {
    tbe.atomicDoneCnt := tbe.atomicDoneCnt - 1;
  }

  action(ptr_popTriggerQueue, "ptr", desc="pop Trigger") {
    triggerQueue_in.dequeue(clockEdge());
  }

  // END ACTIONS

  // BEGIN TRANSITIONS
  // transitions from base
  // Assumptions for ArrayRead/Write
  // TBE checked before tags
  // Data Read/Write requires Tag Read

  // Stalling transitions do NOT check the tag array...and if they do,
  // they can cause a resource stall deadlock!

  transition(WI, {RdBlk, WrVicBlk, Atomic, WrVicBlkBack}) { //TagArrayRead} {
      // by putting the stalled requests in a buffer, we reduce resource contention
      // since they won't try again every cycle and will instead only try again once
      // woken up
      st_stallAndWaitRequest;
  }
  transition(A, {RdBlk, WrVicBlk, WrVicBlkBack}) { //TagArrayRead} {
      // by putting the stalled requests in a buffer, we reduce resource contention
      // since they won't try again every cycle and will instead only try again once
      // woken up
      st_stallAndWaitRequest;
  }
  transition(IV, {WrVicBlk, Atomic, WrVicBlkBack}) { //TagArrayRead} {
      // by putting the stalled requests in a buffer, we reduce resource contention
      // since they won't try again every cycle and will instead only try again once
      // woken up
      st_stallAndWaitRequest;
  }
  transition({M, V}, RdBlk) {TagArrayRead, DataArrayRead} {
    p_profileHit;
    sd_sendData;
    ut_updateTag;
    p_popRequestQueue;
  }
  transition(W, RdBlk, WI) {TagArrayRead, DataArrayRead} {
    p_profileHit;
    t_allocateTBE;
    wb_writeBack;
  }

  transition(I, RdBlk, IV) {TagArrayRead} {
    p_profileMiss;
    t_allocateTBE;
    rd_requestData;
    p_popRequestQueue;
  }

  transition(IV, RdBlk) {
    p_profileMiss;
    t_allocateTBE;
    rd_requestData;
    p_popRequestQueue;
  }

  transition(V, Atomic, A) {TagArrayRead} {
    p_profileHit;
    i_invL2;
    t_allocateTBE;
    at_atomicThrough;
    ina_incrementNumAtomics;
    p_popRequestQueue;
  }

transition(I, Atomic, A) {TagArrayRead} {
    p_profileMiss;
    i_invL2;
    t_allocateTBE;
    at_atomicThrough;
    ina_incrementNumAtomics;
    p_popRequestQueue;
  }

  transition(A, Atomic) {
    p_profileMiss;
    // by putting the stalled requests in a buffer, we reduce resource contention
    // since they won't try again every cycle and will instead only try again once
    // woken up
    st_stallAndWaitRequest;
  }

  transition({M, W}, Atomic, WI) {TagArrayRead} {
    p_profileHit;
    t_allocateTBE;
    wb_writeBack;
  }

  transition(I, WrVicBlk) {TagArrayRead} {
    p_profileMiss;
    wt_writeThrough;
    p_popRequestQueue;
  }

  transition(V, WrVicBlk) {TagArrayRead, DataArrayWrite} {
    p_profileHit;
    ut_updateTag;
    wdb_writeDirtyBytes;
    wt_writeThrough;
    p_popRequestQueue;
  }

  transition({V, M}, WrVicBlkBack, M) {TagArrayRead, TagArrayWrite, DataArrayWrite} {
    p_profileHit;
    ut_updateTag;
    swb_sendWBAck;
    wdb_writeDirtyBytes;
    p_popRequestQueue;
  }

  transition(W, WrVicBlkBack) {TagArrayRead, TagArrayWrite, DataArrayWrite} {
    p_profileHit;
    ut_updateTag;
    swb_sendWBAck;
    wdb_writeDirtyBytes;
    p_popRequestQueue;
  }

  transition(I, WrVicBlkBack, W) {TagArrayRead, TagArrayWrite, DataArrayWrite} {
    p_profileMiss;
    a_allocateBlock;
    ut_updateTag;
    swb_sendWBAck;
    wdb_writeDirtyBytes;
    p_popRequestQueue;
  }

  transition({W, M}, L2_Repl, WI) {TagArrayRead, DataArrayRead} {
    t_allocateTBE;
    wb_writeBack;
    i_invL2;
  }

  transition({I, V}, L2_Repl, I) {TagArrayRead, TagArrayWrite} {
    i_invL2;
  }

  transition({A, IV, WI}, L2_Repl) {
    i_invL2;
  }

  transition({I, V}, PrbInv, I) {TagArrayRead, TagArrayWrite} {
    pi_sendProbeResponseInv;
    pp_popProbeQueue;
  }

  transition(M, PrbInv, W) {TagArrayRead, TagArrayWrite} {
    pi_sendProbeResponseInv;
    pp_popProbeQueue;
  }

  transition(W, PrbInv) {TagArrayRead} {
    pi_sendProbeResponseInv;
    pp_popProbeQueue;
  }

  transition({A, IV, WI}, PrbInv) {
    pi_sendProbeResponseInv;
    pp_popProbeQueue;
  }

  transition(IV, Data, V) {TagArrayRead, TagArrayWrite, DataArrayWrite} {
    a_allocateBlock;
    ut_updateTag;
    wcb_writeCacheBlock;
    sdr_sendDataResponse;
    pr_popResponseQueue;
    wada_wakeUpAllDependentsAddr;
    dt_deallocateTBE;
  }

  transition(A, Data) {TagArrayRead, TagArrayWrite, DataArrayWrite} {
    a_allocateBlock;
    ar_sendAtomicResponse;
    dna_decrementNumAtomics;
    pr_popResponseQueue;
  }

  transition(A, AtomicDone, I) {TagArrayRead, TagArrayWrite} {
    dt_deallocateTBE;
    wada_wakeUpAllDependentsAddr;
    ptr_popTriggerQueue;
  }

  transition(A, AtomicNotDone) {TagArrayRead} {
    dadc_decrementAtomicDoneCnt;
    ptr_popTriggerQueue;
  }

  //M,W should not see WBAck as the cache is in WB mode
  //WBAcks do not need to check tags
  transition({I, V, IV, A}, WBAck) {
    w_sendResponseWBAck;
    pr_popResponseQueue;
  }

  transition(WI, WBAck,I) {
    dt_deallocateTBE;
    pr_popResponseQueue;
  }
}
