/*
 * 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;

   Prefetcher * 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.demand_misses;
  }

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

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

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

  // 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;
  }
}
