/*
 * Copyright (c) 2020 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2013 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.
 */

machine(MachineType:L0Cache, "MESI Directory L0 Cache")
 : Sequencer * sequencer;
   CacheMemory * Icache;
   CacheMemory * Dcache;
   Cycles request_latency := 2;
   Cycles response_latency := 2;
   bool send_evictions;

   RubyPrefetcher * prefetcher;
   bool enable_prefetch := "False";

   // From this node's L0 cache to the network
   MessageBuffer * bufferToL1, network="To";

   // To this node's L0 cache FROM the network
   MessageBuffer * bufferFromL1, network="From";

   // Message queue between this controller and the processor
   MessageBuffer * mandatoryQueue;

   // Request Buffer for prefetches
   MessageBuffer * prefetchQueue;
{
  // STATES
  state_declaration(State, desc="Cache states", default="L0Cache_State_I") {
    // Base states

    // The cache entry has not been allocated.
    I, AccessPermission:Invalid, desc="Invalid";

    // The cache entry is in shared mode. The processor can read this entry
    // but it cannot write to it.
    S, AccessPermission:Read_Only, desc="Shared";

    // The cache entry is in exclusive mode. The processor can read this
    // entry. It can write to this entry without informing the directory.
    // On writing, the entry moves to M state.
    E, AccessPermission:Read_Only, desc="Exclusive";

    // The processor has read and write permissions on this entry.
    M, AccessPermission:Read_Write, desc="Modified";

    // Transient States

    // The cache controller has requested an instruction.  It will be stored
    // in the shared state so that the processor can read it.
    Inst_IS, AccessPermission:Busy, desc="Issued GETS, have not seen response yet";

    // The cache controller has requested that this entry be fetched in
    // shared state so that the processor can read it.
    IS, AccessPermission:Busy, desc="Issued GETS, have not seen response yet";

    // The cache controller has requested that this entry be fetched in
    // modify state so that the processor can read/write it.
    IM, AccessPermission:Busy, desc="Issued GETX, have not seen response yet";

    // The cache controller had read permission over the entry. But now the
    // processor needs to write to it. So, the controller has requested for
    // write permission.
    SM, AccessPermission:Read_Only, desc="Issued GETX, have not seen response yet";

    // Transient states in which block is being prefetched
    PF_Inst_IS, AccessPermission:Busy, desc="Issued GETS, have not seen response yet";
    PF_IS, AccessPermission:Busy, desc="Issued GETS, have not seen response yet";
    PF_IE, AccessPermission:Busy, desc="Issued GETX, have not seen response yet";
  }

  // EVENTS
  enumeration(Event, desc="Cache events") {
    // Events from core
    Load,            desc="Load request from the home processor";
    Ifetch,          desc="I-fetch request from the home processor";
    Store,           desc="Store request from the home processor";

    // invalidations from L1 (due to self or other core)
    InvOwn,          desc="Invalidate request from L1 (own)";
    InvElse,         desc="Invalidate request from L1 (else)";

    // internal generated request
    L0_Replacement,  desc="L0 Replacement", format="!r";

    // requests forwarded from other processors
    Fwd_GETX,   desc="GETX from other processor";
    Fwd_GETS,   desc="GETS from other processor";
    Fwd_GET_INSTR,   desc="GET_INSTR from other processor";

    // data arrives from L1 cache
    Data,               desc="Data for processor";
    Data_Exclusive,     desc="Data for processor";
    Data_Stale,         desc="Data for processor, but not for storage";

    Ack,        desc="Ack for processor";

    WB_Ack,        desc="Ack for replacement";

    Failed_SC,        desc="Store conditional request that will fail";

    // Prefetch events (generated by prefetcher)
    PF_L0_Replacement, desc="L0 Replacement caused by pretcher", format="!pr";
    PF_Load,         desc="Load request from prefetcher";
    PF_Ifetch,       desc="Instruction fetch request from prefetcher";
    PF_Store,        desc="Exclusive load request from prefetcher";
    PF_Bad_Addr,     desc="Throw away prefetch request due to bad address generation";
  }

  // TYPES

  // CacheEntry
  structure(Entry, desc="...", interface="AbstractCacheEntry" ) {
    State CacheState,        desc="cache state";
    DataBlock DataBlk,       desc="data for the block";
    bool Dirty, default="false",   desc="data is dirty";
    bool isPrefetched, default="false", desc="Set if this block was prefetched";
  }

  // TBE fields
  structure(TBE, desc="...") {
    Addr addr,              desc="Physical address for this TBE";
    State TBEState,        desc="Transient state";
    DataBlock DataBlk,                desc="Buffer for the data block";
    bool Dirty, default="false",   desc="data is dirty";
    int pendingAcks, default="0", desc="number of pending acks";
  }

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

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

  Tick clockEdge();
  Cycles ticksToCycles(Tick t);
  void set_cache_entry(AbstractCacheEntry a);
  void unset_cache_entry();
  void set_tbe(TBE a);
  void unset_tbe();
  void wakeUpBuffers(Addr a);
  void wakeUpAllBuffers(Addr a);
  void profileMsgDelay(int virtualNetworkType, Cycles c);
  MachineID mapAddressToMachine(Addr addr, MachineType mtype);

  // inclusive cache returns L0 entries only
  Entry getCacheEntry(Addr addr), return_by_pointer="yes" {
    Entry Dcache_entry := static_cast(Entry, "pointer", Dcache[addr]);
    if(is_valid(Dcache_entry)) {
      return Dcache_entry;
    }

    Entry Icache_entry := static_cast(Entry, "pointer", Icache[addr]);
    return Icache_entry;
  }

  Entry getDCacheEntry(Addr addr), return_by_pointer="yes" {
    Entry Dcache_entry := static_cast(Entry, "pointer", Dcache[addr]);
    return Dcache_entry;
  }

  Entry getICacheEntry(Addr addr), return_by_pointer="yes" {
    Entry Icache_entry := static_cast(Entry, "pointer", Icache[addr]);
    return Icache_entry;
  }

  State getState(TBE tbe, Entry cache_entry, Addr addr) {
    assert((Dcache.isTagPresent(addr) && Icache.isTagPresent(addr)) == false);

    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) {
    assert((Dcache.isTagPresent(addr) && Icache.isTagPresent(addr)) == false);

    // MUST CHANGE
    if(is_valid(tbe)) {
      tbe.TBEState := state;
    }

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

  AccessPermission getAccessPermission(Addr addr) {
    TBE tbe := TBEs[addr];
    if(is_valid(tbe)) {
      DPRINTF(RubySlicc, "%s\n", L0Cache_State_to_permission(tbe.TBEState));
      return L0Cache_State_to_permission(tbe.TBEState);
    }

    Entry cache_entry := getCacheEntry(addr);
    if(is_valid(cache_entry)) {
      DPRINTF(RubySlicc, "%s\n", L0Cache_State_to_permission(cache_entry.CacheState));
      return L0Cache_State_to_permission(cache_entry.CacheState);
    }

    DPRINTF(RubySlicc, "%s\n", AccessPermission:NotPresent);
    return AccessPermission:NotPresent;
  }

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

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

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

    num_functional_writes := num_functional_writes +
        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
    return num_functional_writes;
  }

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

  Event mandatory_request_type_to_event(RubyRequestType type) {
    if (type == RubyRequestType:LD) {
      return Event:Load;
    } else if (type == RubyRequestType:IFETCH) {
      return Event:Ifetch;
    } else if ((type == RubyRequestType:ST) || (type == RubyRequestType:ATOMIC)
               || (type == RubyRequestType:Store_Conditional)) {
      return Event:Store;
    } else {
      error("Invalid RubyRequestType");
    }
  }

  Event prefetch_request_type_to_event(RubyRequestType type) {
    if (type == RubyRequestType:LD) {
      return Event:PF_Load;
    } else if (type == RubyRequestType:IFETCH) {
      return Event:PF_Ifetch;
    } else if (type == RubyRequestType:ST) {
      return Event:PF_Store;
    } else {
      error("Invalid RubyRequestType");
    }
  }

  int getPendingAcks(TBE tbe) {
    return tbe.pendingAcks;
  }

  out_port(requestNetwork_out, CoherenceMsg, bufferToL1);
  out_port(optionalQueue_out, RubyRequest, prefetchQueue);

  void enqueuePrefetch(Addr address, RubyRequestType type) {
    enqueue(optionalQueue_out, RubyRequest, 1) {
      out_msg.LineAddress := address;
      out_msg.Type := type;
      out_msg.Prefetch := PrefetchBit:Yes;
      out_msg.AccessMode := RubyAccessMode:Supervisor;
    }
  }

  // Prefetch queue between the controller and the prefetcher
  // As per Spracklen et al. (HPCA 2005), the prefetch queue should be
  // implemented as a LIFO structure.  The structure would allow for fast
  // searches of all entries in the queue, not just the head msg. All
  // msgs in the structure can be invalidated if a demand miss matches.
  in_port(optionalQueue_in, RubyRequest, prefetchQueue, desc="...", rank = 2) {
    if (optionalQueue_in.isReady(clockEdge())) {
      peek(optionalQueue_in, RubyRequest) {
        // first check for valid address
        MachineID mid := mapAddressToMachine(in_msg.LineAddress, MachineType:Directory);
        NodeID nid := machineIDToNodeID(mid);
        int nidint := IDToInt(nid);
        int numDirs := machineCount(MachineType:Directory);
        if (nidint >= numDirs) {
          Entry cache_entry := static_cast(Entry, "pointer", Dcache.getNullEntry());
          TBE tbe := TBEs.getNullEntry();
          trigger(Event:PF_Bad_Addr, in_msg.LineAddress, cache_entry, tbe);
        } else if (in_msg.Type == RubyRequestType:IFETCH) {
          // Instruction Prefetch
          Entry icache_entry := getICacheEntry(in_msg.LineAddress);
          if (is_valid(icache_entry)) {
            // The block to be prefetched is already present in the
            // cache. This request will be made benign and cause the
            // prefetch queue to be popped.
            trigger(prefetch_request_type_to_event(in_msg.Type),
                    in_msg.LineAddress,
                    icache_entry, TBEs[in_msg.LineAddress]);
          }

          // Check to see if it is in the L0-D
          Entry cache_entry := getDCacheEntry(in_msg.LineAddress);
          if (is_valid(cache_entry)) {
            // The block is in the wrong L0 cache. We should drop
            // this request.
            trigger(prefetch_request_type_to_event(in_msg.Type),
                    in_msg.LineAddress,
                    cache_entry, TBEs[in_msg.LineAddress]);
          }

          if (Icache.cacheAvail(in_msg.LineAddress)) {
            // L0-I does't have the line, but we have space for it
            // in the L0-I so let's see if the L1 has it
            trigger(prefetch_request_type_to_event(in_msg.Type),
                    in_msg.LineAddress,
                    icache_entry, TBEs[in_msg.LineAddress]);
          } else {
            // No room in the L0-I, so we need to make room in the L0-I
            Addr addr := Icache.cacheProbe(in_msg.LineAddress);
            check_on_cache_probe(optionalQueue_in, addr);

            trigger(Event:PF_L0_Replacement, addr,
                    getICacheEntry(addr),
                    TBEs[addr]);
          }
        } else {
          // Data prefetch
          Entry cache_entry := getDCacheEntry(in_msg.LineAddress);
          if (is_valid(cache_entry)) {
            // The block to be prefetched is already present in the
            // cache. This request will be made benign and cause the
            // prefetch queue to be popped.
            trigger(prefetch_request_type_to_event(in_msg.Type),
                    in_msg.LineAddress,
                    cache_entry, TBEs[in_msg.LineAddress]);
          }

          // Check to see if it is in the L0-I
          Entry icache_entry := getICacheEntry(in_msg.LineAddress);
          if (is_valid(icache_entry)) {
            // The block is in the wrong L0. Just drop the prefetch
            // request.
            trigger(prefetch_request_type_to_event(in_msg.Type),
                    in_msg.LineAddress,
                    icache_entry, TBEs[in_msg.LineAddress]);
          }

          if (Dcache.cacheAvail(in_msg.LineAddress)) {
            // L0-D does't have the line, but we have space for it in
            // the L0-D let's see if the L1 has it
            trigger(prefetch_request_type_to_event(in_msg.Type),
                    in_msg.LineAddress,
                    cache_entry, TBEs[in_msg.LineAddress]);
          } else {
            // No room in the L0-D, so we need to make room in the L0-D
            Addr addr := Dcache.cacheProbe(in_msg.LineAddress);
            check_on_cache_probe(optionalQueue_in, addr);

            trigger(Event:PF_L0_Replacement, addr,
                    getDCacheEntry(addr),
                    TBEs[addr]);
          }
        }
      }
    }
  }

  // Messages for this L0 cache from the L1 cache
  in_port(messgeBuffer_in, CoherenceMsg, bufferFromL1, rank = 1) {
    if (messgeBuffer_in.isReady(clockEdge())) {
      peek(messgeBuffer_in, CoherenceMsg, block_on="addr") {
        assert(in_msg.Dest == machineID);

        Entry cache_entry := getCacheEntry(in_msg.addr);
        TBE tbe := TBEs[in_msg.addr];

        if(in_msg.Class == CoherenceClass:DATA_EXCLUSIVE) {
            trigger(Event:Data_Exclusive, in_msg.addr, cache_entry, tbe);
        } else if(in_msg.Class == CoherenceClass:DATA) {
            trigger(Event:Data, in_msg.addr, cache_entry, tbe);
        } else if(in_msg.Class == CoherenceClass:STALE_DATA) {
            trigger(Event:Data_Stale, in_msg.addr, cache_entry, tbe);
        } else if (in_msg.Class == CoherenceClass:ACK) {
            trigger(Event:Ack, in_msg.addr, cache_entry, tbe);
        } else if (in_msg.Class == CoherenceClass:WB_ACK) {
            trigger(Event:WB_Ack, in_msg.addr, cache_entry, tbe);
        } else if (in_msg.Class == CoherenceClass:INV_OWN) {
          trigger(Event:InvOwn, in_msg.addr, cache_entry, tbe);
        } else if (in_msg.Class == CoherenceClass:INV_ELSE) {
          trigger(Event:InvElse, in_msg.addr, cache_entry, tbe);
        } else if (in_msg.Class == CoherenceClass:GETX ||
                   in_msg.Class == CoherenceClass:UPGRADE) {
          // upgrade transforms to GETX due to race
          trigger(Event:Fwd_GETX, in_msg.addr, cache_entry, tbe);
        } else if (in_msg.Class == CoherenceClass:GETS) {
          trigger(Event:Fwd_GETS, in_msg.addr, cache_entry, tbe);
        } else if (in_msg.Class == CoherenceClass:GET_INSTR) {
          trigger(Event:Fwd_GET_INSTR, in_msg.addr, cache_entry, tbe);
        } else {
          error("Invalid forwarded request type");
        }
      }
    }
  }

  // Mandatory Queue betweens Node's CPU and it's L0 caches
  in_port(mandatoryQueue_in, RubyRequest, mandatoryQueue, desc="...", rank = 0) {
    if (mandatoryQueue_in.isReady(clockEdge())) {
      peek(mandatoryQueue_in, RubyRequest, block_on="LineAddress") {

        // Check for data access to blocks in I-cache and ifetchs to blocks in D-cache

        if (in_msg.Type == RubyRequestType:IFETCH) {
          // ** INSTRUCTION ACCESS ***

          Entry Icache_entry := getICacheEntry(in_msg.LineAddress);
          if (is_valid(Icache_entry)) {
            // The tag matches for the L0, so the L0 asks the L2 for it.
            trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress,
                    Icache_entry, TBEs[in_msg.LineAddress]);
          } else {

            // Check to see if it is in the OTHER L0
            Entry Dcache_entry := getDCacheEntry(in_msg.LineAddress);
            if (is_valid(Dcache_entry)) {
              // The block is in the wrong L0, put the request on the queue to the shared L2
              trigger(Event:L0_Replacement, in_msg.LineAddress,
                      Dcache_entry, TBEs[in_msg.LineAddress]);
            }

            if (Icache.cacheAvail(in_msg.LineAddress)) {
              // L0 does't have the line, but we have space for it
              // in the L0 so let's see if the L2 has it
              trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress,
                      Icache_entry, TBEs[in_msg.LineAddress]);
            } else {
              // No room in the L0, so we need to make room in the L0
              // Check if the line we want to evict is not locked
              Addr addr := Icache.cacheProbe(in_msg.LineAddress);
              check_on_cache_probe(mandatoryQueue_in, addr);
              trigger(Event:L0_Replacement, addr,
                      getICacheEntry(addr),
                      TBEs[addr]);
            }
          }
        } else {
          // *** DATA ACCESS ***
          Entry Dcache_entry := getDCacheEntry(in_msg.LineAddress);

          // early out for failed store conditionals

          if (in_msg.Type == RubyRequestType:Store_Conditional) {
              if (!sequencer.llscCheckMonitor(in_msg.LineAddress)) {
                trigger(Event:Failed_SC, in_msg.LineAddress,
                        Dcache_entry, TBEs[in_msg.LineAddress]);
            }
          }

          if (is_valid(Dcache_entry)) {
            // The tag matches for the L0, so the L0 ask the L1 for it
            trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress,
                    Dcache_entry, TBEs[in_msg.LineAddress]);
          } else {
            // if the request is not valid, the store conditional will fail
            if (in_msg.Type == RubyRequestType:Store_Conditional) {
                // if the line is not valid, it can't be locked
                trigger(Event:Failed_SC, in_msg.LineAddress,
                        Dcache_entry, TBEs[in_msg.LineAddress]);
            } else {
              // Check to see if it is in the OTHER L0
              Entry Icache_entry := getICacheEntry(in_msg.LineAddress);
              if (is_valid(Icache_entry)) {
                // The block is in the wrong L0, put the request on the queue to the private L1
                trigger(Event:L0_Replacement, in_msg.LineAddress,
                        Icache_entry, TBEs[in_msg.LineAddress]);
              }

              if (Dcache.cacheAvail(in_msg.LineAddress)) {
                // L1 does't have the line, but we have space for it
                // in the L0 let's see if the L1 has it
                trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress,
                        Dcache_entry, TBEs[in_msg.LineAddress]);
              } else {
                // No room in the L1, so we need to make room in the L0
                // Check if the line we want to evict is not locked
                Addr addr := Dcache.cacheProbe(in_msg.LineAddress);
                check_on_cache_probe(mandatoryQueue_in, addr);
                trigger(Event:L0_Replacement, addr,
                        getDCacheEntry(addr),
                        TBEs[addr]);
              }
            }
          }
        }
      }
    }
  }

  // ACTIONS
  action(a_issueGETS, "a", desc="Issue GETS") {
    peek(mandatoryQueue_in, RubyRequest) {
      enqueue(requestNetwork_out, CoherenceMsg, request_latency) {
        out_msg.addr := address;
        out_msg.Class := CoherenceClass:GETS;
        out_msg.Sender := machineID;
        out_msg.Dest := createMachineID(MachineType:L1Cache, version);
        DPRINTF(RubySlicc, "address: %#x, destination: %s\n",
                address, out_msg.Dest);
        out_msg.MessageSize := MessageSizeType:Control;
        out_msg.AccessMode := in_msg.AccessMode;
      }
    }
  }

  action(b_issueGETX, "b", desc="Issue GETX") {
    peek(mandatoryQueue_in, RubyRequest) {
      enqueue(requestNetwork_out, CoherenceMsg, request_latency) {
        out_msg.addr := address;
        out_msg.Class := CoherenceClass:GETX;
        out_msg.Sender := machineID;
        DPRINTF(RubySlicc, "%s\n", machineID);
        out_msg.Dest := createMachineID(MachineType:L1Cache, version);

        DPRINTF(RubySlicc, "address: %#x, destination: %s\n",
                address, out_msg.Dest);
        out_msg.MessageSize := MessageSizeType:Control;
        out_msg.AccessMode := in_msg.AccessMode;
      }
    }
  }

  action(c_issueUPGRADE, "c", desc="Issue GETX") {
    peek(mandatoryQueue_in, RubyRequest) {
      enqueue(requestNetwork_out, CoherenceMsg, request_latency) {
        out_msg.addr := address;
        out_msg.Class := CoherenceClass:UPGRADE;
        out_msg.Sender := machineID;
        out_msg.Dest := createMachineID(MachineType:L1Cache, version);

        DPRINTF(RubySlicc, "address: %#x, destination: %s\n",
                address, out_msg.Dest);
        out_msg.MessageSize := MessageSizeType:Control;
        out_msg.AccessMode := in_msg.AccessMode;
      }
    }
  }

  action(f_sendDataToL1, "f", desc="Send data to the L1 cache") {
    enqueue(requestNetwork_out, CoherenceMsg, response_latency) {
      assert(is_valid(cache_entry));
      out_msg.addr := address;
      out_msg.Class := CoherenceClass:INV_DATA;
      out_msg.DataBlk := cache_entry.DataBlk;
      out_msg.Dirty := cache_entry.Dirty;
      out_msg.Sender := machineID;
      out_msg.Dest := createMachineID(MachineType:L1Cache, version);
      out_msg.MessageSize := MessageSizeType:Writeback_Data;
    }
    cache_entry.Dirty := false;
  }

  action(fi_sendInvAck, "fi", desc="Send data to the L1 cache") {
    peek(messgeBuffer_in, CoherenceMsg) {
      enqueue(requestNetwork_out, CoherenceMsg, response_latency) {
        out_msg.addr := address;
        out_msg.Class := CoherenceClass:INV_ACK;
        out_msg.Sender := machineID;
        out_msg.Dest := createMachineID(MachineType:L1Cache, version);
        out_msg.MessageSize := MessageSizeType:Response_Control;
      }
    }
  }

  action(forward_eviction_to_cpu, "\cc", desc="Send eviction information to the processor") {
    if (send_evictions) {
      DPRINTF(RubySlicc, "Sending invalidation for %#x to the CPU\n", address);
      sequencer.evictionCallback(address);
    }
  }

  action(g_issuePUTX, "g", desc="Relinquish line to the L1 cache") {
    enqueue(requestNetwork_out, CoherenceMsg, response_latency) {
      assert(is_valid(cache_entry));
      out_msg.addr := address;
      out_msg.Class := CoherenceClass:PUTX;
      out_msg.Dirty := cache_entry.Dirty;
      out_msg.Sender:= machineID;
      out_msg.Dest := createMachineID(MachineType:L1Cache, version);

      if (cache_entry.Dirty) {
        out_msg.MessageSize := MessageSizeType:Writeback_Data;
        out_msg.DataBlk := cache_entry.DataBlk;
      } else {
        out_msg.MessageSize := MessageSizeType:Writeback_Control;
      }
    }
  }

  action(h_load_hit, "hd", desc="Notify sequencer the load completed (cache hit)") {
    assert(is_valid(cache_entry));
    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
    Dcache.setMRU(cache_entry);
    sequencer.readCallback(address, cache_entry.DataBlk);
  }

  action(h_ifetch_hit, "hi", desc="Notify sequencer the ifetch completed (cache hit)") {
    assert(is_valid(cache_entry));
    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
    Icache.setMRU(cache_entry);
    sequencer.readCallback(address, cache_entry.DataBlk);
  }

  // The action name uses a counterintuitive _hit prefix when it is only
  // called due to a cache miss. It is technically now a hit after having
  // serviced the miss.
  action(hx_load_hit, "hxd", desc="Notify sequencer the load completed (cache miss)") {
    assert(is_valid(cache_entry));
    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
    Dcache.setMRU(cache_entry);
    sequencer.readCallback(address, cache_entry.DataBlk, true);
  }

  // The action name uses a counterintuitive _hit prefix when it is only
  // called due to a cache miss. It is technically now a hit after having
  // serviced the miss.
  action(hx_ifetch_hit, "hxi", desc="Notify sequencer the ifetch completed (cache miss)") {
    assert(is_valid(cache_entry));
    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
    Icache.setMRU(cache_entry);
    sequencer.readCallback(address, cache_entry.DataBlk, true);
  }

  action(hh_store_hit, "\h", desc="Notify sequencer that store completed (cache hit)") {
    assert(is_valid(cache_entry));
    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
    Dcache.setMRU(cache_entry);
    sequencer.writeCallback(address, cache_entry.DataBlk);
    cache_entry.Dirty := true;
  }

  // The action name uses a counterintuitive _hit prefix when it is only
  // called due to a cache miss. It is technically now a hit after having
  // serviced the miss.
  action(hhx_store_hit, "\hx", desc="Notify sequencer that store completed (cache miss)") {
    assert(is_valid(cache_entry));
    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
    Dcache.setMRU(cache_entry);
    sequencer.writeCallback(address, cache_entry.DataBlk, true);
    cache_entry.Dirty := true;
  }

  action(i_allocateTBE, "i", desc="Allocate TBE (number of invalidates=0)") {
    check_allocate(TBEs);
    assert(is_valid(cache_entry));
    TBEs.allocate(address);
    set_tbe(TBEs[address]);
    tbe.Dirty := cache_entry.Dirty;
    tbe.DataBlk := cache_entry.DataBlk;
  }

  action(k_popMandatoryQueue, "k", desc="Pop mandatory queue") {
    mandatoryQueue_in.dequeue(clockEdge());
  }

  action(l_popRequestQueue, "l",
         desc="Pop incoming request queue and profile the delay within this virtual network") {
    Tick delay := messgeBuffer_in.dequeue(clockEdge());
    profileMsgDelay(2, ticksToCycles(delay));
  }

  action(o_popIncomingResponseQueue, "o",
         desc="Pop Incoming Response queue and profile the delay within this virtual network") {
    Tick delay := messgeBuffer_in.dequeue(clockEdge());
    profileMsgDelay(1, ticksToCycles(delay));
  }

  action(s_deallocateTBE, "s", desc="Deallocate TBE") {
    TBEs.deallocate(address);
    unset_tbe();
  }

  action(u_writeDataToCache, "u", desc="Write data to cache") {
    peek(messgeBuffer_in, CoherenceMsg) {
      assert(is_valid(cache_entry));
      cache_entry.DataBlk := in_msg.DataBlk;
    }
  }

  action(u_writeInstToCache, "ui", desc="Write data to cache") {
    peek(messgeBuffer_in, CoherenceMsg) {
      assert(is_valid(cache_entry));
      cache_entry.DataBlk := in_msg.DataBlk;
    }
  }

  action(ff_deallocateCacheBlock, "\f",
         desc="Deallocate L1 cache block.") {
    if (Dcache.isTagPresent(address)) {
      Dcache.deallocate(address);
    } else {
      Icache.deallocate(address);
    }
    unset_cache_entry();
  }

  action(oo_allocateDCacheBlock, "\o", desc="Set L1 D-cache tag equal to tag of block B") {
    if (is_invalid(cache_entry)) {
      set_cache_entry(Dcache.allocate(address, new Entry));
    }
  }

  action(pp_allocateICacheBlock, "\p", desc="Set L1 I-cache tag equal to tag of block B") {
    if (is_invalid(cache_entry)) {
      set_cache_entry(Icache.allocate(address, new Entry));
    }
  }

  action(z_stallAndWaitMandatoryQueue, "\z", desc="Stall cpu request queue") {
    stall_and_wait(mandatoryQueue_in, address);
  }

  action(kd_wakeUpDependents, "kd", desc="Wake-up dependents") {
    wakeUpAllBuffers(address);
  }

  action(uu_profileInstMiss, "\ui", desc="Profile the demand miss") {
    Icache.profileDemandMiss();
  }

  action(uu_profileInstHit, "\uih", desc="Profile the demand hit") {
    Icache.profileDemandHit();
  }

  action(uu_profileDataMiss, "\ud", desc="Profile the demand miss") {
    Dcache.profileDemandMiss();
  }

  action(uu_profileDataHit, "\udh", desc="Profile the demand hit") {
    Dcache.profileDemandHit();
  }

  // store conditionals

  action(hhc_storec_fail, "\hc",
         desc="Notify sequencer that store conditional failed") {
    sequencer.writeCallbackScFail(address, cache_entry.DataBlk);
  }

  // prefetching

  action(pa_issuePfGETS, "pa", desc="Issue prefetch GETS") {
    peek(optionalQueue_in, RubyRequest) {
      enqueue(requestNetwork_out, CoherenceMsg, request_latency) {
        out_msg.addr := address;
        out_msg.Class := CoherenceClass:GETS;
        out_msg.Sender := machineID;
        out_msg.Dest := createMachineID(MachineType:L1Cache, version);
        DPRINTF(RubySlicc, "address: %#x, destination: %s\n",
                address, out_msg.Dest);
        out_msg.MessageSize := MessageSizeType:Control;
        out_msg.Prefetch := in_msg.Prefetch;
        out_msg.AccessMode := in_msg.AccessMode;
      }
    }
  }

  action(pb_issuePfGETX, "pb", desc="Issue prefetch GETX") {
    peek(optionalQueue_in, RubyRequest) {
      enqueue(requestNetwork_out, CoherenceMsg, request_latency) {
        out_msg.addr := address;
        out_msg.Class := CoherenceClass:GETX;
        out_msg.Sender := machineID;
        DPRINTF(RubySlicc, "%s\n", machineID);
        out_msg.Dest := createMachineID(MachineType:L1Cache, version);

        DPRINTF(RubySlicc, "address: %#x, destination: %s\n",
                address, out_msg.Dest);
        out_msg.MessageSize := MessageSizeType:Control;
        out_msg.Prefetch := in_msg.Prefetch;
        out_msg.AccessMode := in_msg.AccessMode;
      }
    }
  }

  action(pq_popPrefetchQueue, "\pq", desc="Pop the prefetch request queue") {
    optionalQueue_in.dequeue(clockEdge());
  }

  action(mp_markPrefetched, "mp", desc="Write data from response queue to cache") {
      assert(is_valid(cache_entry));
      cache_entry.isPrefetched := true;
  }

  action(po_observeMiss, "\po", desc="Inform the prefetcher about a cache miss") {
    peek(mandatoryQueue_in, RubyRequest) {
      if (enable_prefetch) {
        prefetcher.observeMiss(in_msg.LineAddress, in_msg.Type);
      }
    }
  }

  action(ppm_observePfMiss, "\ppm",
         desc="Inform the prefetcher about a cache miss with in-flight prefetch") {
    peek(mandatoryQueue_in, RubyRequest) {
      prefetcher.observePfMiss(in_msg.LineAddress);
    }
  }

  action(pph_observePfHit, "\pph",
         desc="Inform the prefetcher if a cache hit was the result of a prefetch") {
    peek(mandatoryQueue_in, RubyRequest) {
      if (cache_entry.isPrefetched) {
        prefetcher.observePfHit(in_msg.LineAddress);
        cache_entry.isPrefetched := false;
      }
    }
  }

  action(z_stallAndWaitOptionalQueue, "\pz", desc="recycle prefetch request queue") {
    stall_and_wait(optionalQueue_in, address);
  }

  //*****************************************************
  // TRANSITIONS
  //*****************************************************

  // Transitions for Load/Store/Replacement/WriteBack from transient states
  transition({Inst_IS, IS, IM, SM}, {Load, Ifetch, Store, L0_Replacement}) {
    z_stallAndWaitMandatoryQueue;
  }

  // Transitions from Idle
  transition(I, Load, IS) {
    oo_allocateDCacheBlock;
    i_allocateTBE;
    a_issueGETS;
    uu_profileDataMiss;
    po_observeMiss;
    k_popMandatoryQueue;
  }

  transition(I, Ifetch, Inst_IS) {
    pp_allocateICacheBlock;
    i_allocateTBE;
    a_issueGETS;
    uu_profileInstMiss;
    po_observeMiss;
    k_popMandatoryQueue;
  }

  transition(I, Store, IM) {
    oo_allocateDCacheBlock;
    i_allocateTBE;
    b_issueGETX;
    uu_profileDataMiss;
    po_observeMiss;
    k_popMandatoryQueue;
  }

  transition({I, IS, IM, Inst_IS}, {InvOwn, InvElse}) {
    forward_eviction_to_cpu;
    fi_sendInvAck;
    l_popRequestQueue;
  }

  transition(SM, {InvOwn, InvElse}, IM) {
    forward_eviction_to_cpu;
    fi_sendInvAck;
    l_popRequestQueue;
  }

  // Transitions from Shared
  transition({S,E,M}, Load) {
    h_load_hit;
    uu_profileDataHit;
    pph_observePfHit;
    k_popMandatoryQueue;
  }

  transition({S,E,M}, Ifetch) {
    h_ifetch_hit;
    uu_profileInstHit;
    pph_observePfHit;
    k_popMandatoryQueue;
  }

  transition(S, Store, SM) {
    i_allocateTBE;
    c_issueUPGRADE;
    uu_profileDataMiss;
    k_popMandatoryQueue;
  }

  transition(S, {L0_Replacement,PF_L0_Replacement}, I) {
    forward_eviction_to_cpu;
    ff_deallocateCacheBlock;
  }

  transition(S, {InvOwn, InvElse}, I) {
    forward_eviction_to_cpu;
    fi_sendInvAck;
    ff_deallocateCacheBlock;
    l_popRequestQueue;
  }

  // Transitions from Exclusive
  transition({E,M}, Store, M) {
    hh_store_hit;
    uu_profileDataHit;
    pph_observePfHit;
    k_popMandatoryQueue;
  }

  transition(E, {L0_Replacement,PF_L0_Replacement}, I) {
    forward_eviction_to_cpu;
    g_issuePUTX;
    ff_deallocateCacheBlock;
  }

  transition(E, {InvOwn, InvElse, Fwd_GETX}, I) {
    // don't send data
    forward_eviction_to_cpu;
    fi_sendInvAck;
    ff_deallocateCacheBlock;
    l_popRequestQueue;
  }

  transition(E, {Fwd_GETS, Fwd_GET_INSTR}, S) {
    f_sendDataToL1;
    l_popRequestQueue;
  }

  // Transitions from Modified
  transition(M, {L0_Replacement,PF_L0_Replacement}, I) {
    forward_eviction_to_cpu;
    g_issuePUTX;
    ff_deallocateCacheBlock;
  }

  transition(M, {InvOwn, InvElse, Fwd_GETX}, I) {
    forward_eviction_to_cpu;
    f_sendDataToL1;
    ff_deallocateCacheBlock;
    l_popRequestQueue;
  }

  transition(M, {Fwd_GETS, Fwd_GET_INSTR}, S) {
    f_sendDataToL1;
    l_popRequestQueue;
  }

  transition(IS, Data, S) {
    u_writeDataToCache;
    hx_load_hit;
    s_deallocateTBE;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition(IS, Data_Exclusive, E) {
    u_writeDataToCache;
    hx_load_hit;
    s_deallocateTBE;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition(IS, Data_Stale, I) {
    u_writeDataToCache;
    forward_eviction_to_cpu;
    hx_load_hit;
    s_deallocateTBE;
    ff_deallocateCacheBlock;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition(Inst_IS, Data, S) {
    u_writeInstToCache;
    hx_ifetch_hit;
    s_deallocateTBE;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition(Inst_IS, Data_Exclusive, E) {
    u_writeInstToCache;
    hx_ifetch_hit;
    s_deallocateTBE;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition(Inst_IS, Data_Stale, I) {
    u_writeInstToCache;
    hx_ifetch_hit;
    s_deallocateTBE;
    ff_deallocateCacheBlock;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition({IM,SM}, Data_Exclusive, M) {
    u_writeDataToCache;
    hhx_store_hit;
    s_deallocateTBE;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  // store conditionals

  transition({I,S,E,M}, Failed_SC) {
    // IS,IM,SM don't handle store conditionals
    hhc_storec_fail;
    k_popMandatoryQueue;
  }

  // prefetcher

  transition({Inst_IS, IS, IM, SM, PF_Inst_IS, PF_IS, PF_IE}, PF_L0_Replacement) {
     z_stallAndWaitOptionalQueue;
  }

  transition({PF_Inst_IS, PF_IS}, {Store, L0_Replacement}) {
    z_stallAndWaitMandatoryQueue;
  }

  transition({PF_IE}, {Load, Ifetch, L0_Replacement}) {
    z_stallAndWaitMandatoryQueue;
  }

  transition({S,E,M,Inst_IS,IS,IM,SM,PF_Inst_IS,PF_IS,PF_IE},
             {PF_Load, PF_Store, PF_Ifetch}) {
      pq_popPrefetchQueue;
  }

  transition(I, PF_Load, PF_IS) {
    oo_allocateDCacheBlock;
    i_allocateTBE;
    pa_issuePfGETS;
    pq_popPrefetchQueue;
  }

  transition(PF_IS, Load, IS) {
    uu_profileDataMiss;
    ppm_observePfMiss;
    k_popMandatoryQueue;
  }

  transition(I, PF_Ifetch, PF_Inst_IS) {
    pp_allocateICacheBlock;
    i_allocateTBE;
    pa_issuePfGETS;
    pq_popPrefetchQueue;
  }

  transition(PF_Inst_IS, Ifetch, Inst_IS) {
    uu_profileInstMiss;
    ppm_observePfMiss;
    k_popMandatoryQueue;
  }

  transition(I, PF_Store, PF_IE) {
    oo_allocateDCacheBlock;
    i_allocateTBE;
    pb_issuePfGETX;
    pq_popPrefetchQueue;
  }

  transition(PF_IE, Store, IM) {
    uu_profileDataMiss;
    ppm_observePfMiss;
    k_popMandatoryQueue;
  }

  transition({PF_Inst_IS, PF_IS, PF_IE}, {InvOwn, InvElse}) {
    fi_sendInvAck;
    l_popRequestQueue;
  }

  transition(PF_IS, Data, S) {
    u_writeDataToCache;
    s_deallocateTBE;
    mp_markPrefetched;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition(PF_IS, Data_Exclusive, E) {
    u_writeDataToCache;
    s_deallocateTBE;
    mp_markPrefetched;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition(PF_IS, Data_Stale, I) {
    u_writeDataToCache;
    s_deallocateTBE;
    mp_markPrefetched;
    ff_deallocateCacheBlock;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition(PF_Inst_IS, Data, S) {
    u_writeInstToCache;
    s_deallocateTBE;
    mp_markPrefetched;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition(PF_Inst_IS, Data_Exclusive, E) {
    u_writeInstToCache;
    s_deallocateTBE;
    mp_markPrefetched;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition(PF_IE, Data_Exclusive, E) {
    u_writeDataToCache;
    s_deallocateTBE;
    mp_markPrefetched;
    o_popIncomingResponseQueue;
    kd_wakeUpDependents;
  }

  transition(I, PF_Bad_Addr) {
    pq_popPrefetchQueue;
  }
}
