/*
 * Copyright (c) 2011-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:TCP, "GPU TCP (L1 Data Cache)")
 : VIPERCoalescer* coalescer;
   Sequencer* sequencer;
   bool use_seq_not_coal;
   CacheMemory * L1cache;
   bool WB; /*is this cache Writeback?*/
   bool disableL1; /* bypass L1 cache? */
   int TCC_select_num_bits;
   Cycles issue_latency := 40;  // time to send data down to TCC
   Cycles l2_hit_latency := 18;

  MessageBuffer * requestFromTCP, network="To", virtual_network="1", vnet_type="request";
  MessageBuffer * responseFromTCP, network="To", virtual_network="3", vnet_type="response";
  MessageBuffer * unblockFromCore, network="To", virtual_network="5", vnet_type="unblock";

  MessageBuffer * probeToTCP, network="From", virtual_network="1", vnet_type="request";
  MessageBuffer * responseToTCP, network="From", virtual_network="3", vnet_type="response";
  MessageBuffer * mandatoryQueue;

{
  state_declaration(State, desc="TCP Cache States", default="TCP_State_I") {
    I, AccessPermission:Invalid, desc="Invalid";
    V, AccessPermission:Read_Only, desc="Valid";
    A, AccessPermission:Invalid, desc="Waiting on Atomic";
  }

  enumeration(Event, desc="TCP Events") {
    // Core initiated
    Load,           desc="Load";
    Store,          desc="Store to L1 (L1 is dirty)";
    StoreThrough,   desc="Store directly to L2(L1 is clean)";
    Atomic,         desc="Atomic";
    Flush,          desc="Flush if dirty(wbL1 for Store Release)";
    Evict,          desc="Evict if clean(invL1 for Load Acquire)";
    // Mem sys initiated
    Repl,           desc="Replacing block from cache";

    // TCC initiated
    TCC_Ack,        desc="TCC Ack to Core Request";
    TCC_AckWB,      desc="TCC Ack for WB";
    // Disable L1 cache
    Bypass,         desc="Bypass the entire L1 cache";
 }

  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";
    TagArrayFlash,    desc="Flash clear the data array";
  }


  structure(Entry, desc="...", interface="AbstractCacheEntry") {
    State CacheState,           desc="cache state";
    bool Dirty,                 desc="Is the data dirty (diff than memory)?";
    DataBlock DataBlk,          desc="data for the block";
    bool FromL2, default="false", desc="block just moved from L2";
    WriteMask writeMask, desc="written bytes masks";
  }

  structure(TBE, desc="...") {
    State TBEState,    desc="Transient state";
    DataBlock DataBlk, desc="data for the block, required for concurrent writebacks";
    bool Dirty,        desc="Is the data dirty (different than memory)?";
    int NumPendingMsgs,desc="Number of acks/data messages that this processor is waiting for";
    bool Shared,       desc="Victim hit by shared probe";
   }

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

  TBETable TBEs, template="<TCP_TBE>", constructor="m_number_of_TBEs";
  int TCC_select_low_bit, default="RubySystem::getBlockSizeBits()";
  int WTcnt, default="0";
  int Fcnt, default="0";
  bool inFlush, default="false";

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

  // Internal functions
  Tick clockEdge();
  Tick cyclesToTicks(Cycles c);
  Entry getCacheEntry(Addr address), return_by_pointer="yes" {
    Entry cache_entry := static_cast(Entry, "pointer", L1cache.lookup(address));
    return cache_entry;
  }

  DataBlock getDataBlock(Addr addr), return_by_ref="yes" {
    TBE tbe := TBEs.lookup(addr);
    if(is_valid(tbe)) {
      return tbe.DataBlk;
    } else {
      return getCacheEntry(addr).DataBlk;
    }
  }

  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 TCP_State_to_permission(tbe.TBEState);
    }

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

    return AccessPermission:NotPresent;
  }

  bool isValid(Addr addr) {
      AccessPermission perm := getAccessPermission(addr);
      if (perm == AccessPermission:NotPresent ||
          perm == AccessPermission:Invalid ||
          perm == AccessPermission:Busy) {
          return false;
      } else {
          return true;
      }
  }

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

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

  bool checkResourceAvailable(RequestType request_type, Addr addr) {
    if (request_type == RequestType:DataArrayRead) {
      return L1cache.checkResourceAvailable(CacheResourceType:DataArray, addr);
    } else if (request_type == RequestType:DataArrayWrite) {
      return L1cache.checkResourceAvailable(CacheResourceType:DataArray, addr);
    } else if (request_type == RequestType:TagArrayRead) {
      return L1cache.checkResourceAvailable(CacheResourceType:TagArray, addr);
    } else if (request_type == RequestType:TagArrayWrite) {
      return L1cache.checkResourceAvailable(CacheResourceType:TagArray, addr);
    } else if (request_type == RequestType:TagArrayFlash) {
      // FIXME should check once per cache, rather than once per cacheline
      return L1cache.checkResourceAvailable(CacheResourceType:TagArray, addr);
    } else {
      error("Invalid RequestType type in checkResourceAvailable");
      return true;
    }
  }

  // Out Ports

  out_port(requestNetwork_out, CPURequestMsg, requestFromTCP);

  // In Ports

  in_port(responseToTCP_in, ResponseMsg, responseToTCP) {
    if (responseToTCP_in.isReady(clockEdge())) {
      peek(responseToTCP_in, ResponseMsg, block_on="addr") {
        Entry cache_entry := getCacheEntry(in_msg.addr);
        TBE tbe := TBEs.lookup(in_msg.addr);
        if (in_msg.Type == CoherenceResponseType:TDSysResp) {
          // disable L1 cache
          if (disableL1) {
	          trigger(Event:Bypass, in_msg.addr, cache_entry, tbe);
          } else {
            if (is_valid(cache_entry) || L1cache.cacheAvail(in_msg.addr)) {
              trigger(Event:TCC_Ack, in_msg.addr, cache_entry, tbe);
            } else {
              Addr victim := L1cache.cacheProbe(in_msg.addr);
              trigger(Event:Repl, victim, getCacheEntry(victim), TBEs.lookup(victim));
            }
          }
        } else if (in_msg.Type == CoherenceResponseType:TDSysWBAck ||
                     in_msg.Type == CoherenceResponseType:NBSysWBAck) {
            trigger(Event:TCC_AckWB, in_msg.addr, cache_entry, tbe);
          } else {
            error("Unexpected Response Message to Core");
          }
      }
    }
  }

  in_port(mandatoryQueue_in, RubyRequest, mandatoryQueue, desc="...") {
    if (mandatoryQueue_in.isReady(clockEdge())) {
      peek(mandatoryQueue_in, RubyRequest, block_on="LineAddress") {
        Entry cache_entry := getCacheEntry(in_msg.LineAddress);
        TBE tbe := TBEs.lookup(in_msg.LineAddress);
        DPRINTF(RubySlicc, "%s\n", in_msg);
        if (in_msg.Type == RubyRequestType:LD) {
          trigger(Event:Load, in_msg.LineAddress, cache_entry, tbe);
        } else if (in_msg.Type == RubyRequestType:ATOMIC ||
                   in_msg.Type == RubyRequestType:ATOMIC_RETURN ||
                   in_msg.Type == RubyRequestType:ATOMIC_NO_RETURN) {
          trigger(Event:Atomic, in_msg.LineAddress, cache_entry, tbe);
        } else if (in_msg.Type == RubyRequestType:ST) {
          if(disableL1) {
            trigger(Event:StoreThrough, in_msg.LineAddress, cache_entry, tbe);
          } else {
            if (is_valid(cache_entry) || L1cache.cacheAvail(in_msg.LineAddress)) {
              trigger(Event:StoreThrough, in_msg.LineAddress, cache_entry, tbe);
            } else {
              Addr victim := L1cache.cacheProbe(in_msg.LineAddress);
              trigger(Event:Repl, victim, getCacheEntry(victim), TBEs.lookup(victim));
            }
          } // end if (disableL1)
        } else if (in_msg.Type == RubyRequestType:FLUSH) {
            trigger(Event:Flush, in_msg.LineAddress, cache_entry, tbe);
        } else if (in_msg.Type == RubyRequestType:REPLACEMENT){
            trigger(Event:Evict, in_msg.LineAddress, cache_entry, tbe);
        } else {
          error("Unexpected Request Message from VIC");
        }
      }
    }
  }

  // Actions

  action(ic_invCache, "ic", desc="invalidate cache") {
    if(is_valid(cache_entry)) {
      cache_entry.writeMask.clear();
      L1cache.deallocate(address);
    }
    unset_cache_entry();
  }

  action(n_issueRdBlk, "n", desc="Issue RdBlk") {
    enqueue(requestNetwork_out, CPURequestMsg, issue_latency) {
      out_msg.addr := address;
      out_msg.Type := CoherenceRequestType:RdBlk;
      out_msg.Requestor := machineID;
      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCC,
                              TCC_select_low_bit, TCC_select_num_bits));
      out_msg.MessageSize := MessageSizeType:Request_Control;
      out_msg.InitialRequestTime := curCycle();
    }
  }

  action(rb_bypassDone, "rb", desc="bypass L1 of read access") {
    peek(responseToTCP_in, ResponseMsg) {
      DataBlock tmp:= in_msg.DataBlk;
      if (use_seq_not_coal) {
        sequencer.readCallback(address, tmp, false, MachineType:L1Cache);
      } else {
        coalescer.readCallback(address, MachineType:L1Cache, tmp);
      }
      if(is_valid(cache_entry)) {
        unset_cache_entry();
      }
    }
  }

  action(wab_bypassDone, "wab", desc="bypass L1 of write access") {
    peek(responseToTCP_in, ResponseMsg) {
      DataBlock tmp := in_msg.DataBlk;
      if (use_seq_not_coal) {
        sequencer.writeCallback(address, tmp, false, MachineType:L1Cache);
      } else {
        coalescer.writeCallback(address, MachineType:L1Cache, tmp);
      }
    }
  }

  action(norl_issueRdBlkOrloadDone, "norl", desc="local load done") {
    peek(mandatoryQueue_in, RubyRequest){
      if (cache_entry.writeMask.containsMask(in_msg.writeMask)) {
          if (use_seq_not_coal) {
            sequencer.readCallback(address, cache_entry.DataBlk, false, MachineType:L1Cache);
          } else {
            coalescer.readCallback(address, MachineType:L1Cache, cache_entry.DataBlk);
          }
      } else {
        enqueue(requestNetwork_out, CPURequestMsg, issue_latency) {
          out_msg.addr := address;
          out_msg.Type := CoherenceRequestType:RdBlk;
          out_msg.Requestor := machineID;
          out_msg.Destination.add(mapAddressToRange(address,MachineType:TCC,
                              TCC_select_low_bit, TCC_select_num_bits));
          out_msg.MessageSize := MessageSizeType:Request_Control;
          out_msg.InitialRequestTime := curCycle();
        }
      }
    }
  }

  action(wt_writeThrough, "wt", desc="Flush dirty data") {
    WTcnt := WTcnt + 1;
    APPEND_TRANSITION_COMMENT("write++ = ");
    APPEND_TRANSITION_COMMENT(WTcnt);
    enqueue(requestNetwork_out, CPURequestMsg, issue_latency) {
      out_msg.addr := address;
      out_msg.Requestor := machineID;
      assert(is_valid(cache_entry));
      out_msg.DataBlk := cache_entry.DataBlk;
      out_msg.writeMask.clear();
      out_msg.writeMask.orMask(cache_entry.writeMask);
      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCC,
                              TCC_select_low_bit, TCC_select_num_bits));
      out_msg.MessageSize := MessageSizeType:Data;
      out_msg.Type := CoherenceRequestType:WriteThrough;
      out_msg.InitialRequestTime := curCycle();
      out_msg.Shared := false;

      // forward inst sequence number to lower TCC
      peek(mandatoryQueue_in, RubyRequest) {
        out_msg.instSeqNum := in_msg.instSeqNum;
      }
    }
  }

  action(at_atomicThrough, "at", desc="send Atomic") {
    peek(mandatoryQueue_in, RubyRequest) {
      enqueue(requestNetwork_out, CPURequestMsg, issue_latency) {
        out_msg.addr := address;
        out_msg.Requestor := machineID;
        out_msg.writeMask.clear();
        out_msg.writeMask.orMask(in_msg.writeMask);
        out_msg.Destination.add(mapAddressToRange(address,MachineType:TCC,
                                TCC_select_low_bit, TCC_select_num_bits));
        out_msg.MessageSize := MessageSizeType:Data;
        out_msg.Type := CoherenceRequestType:Atomic;
        out_msg.InitialRequestTime := curCycle();
        out_msg.Shared := false;
      }
    }
  }

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

  action(t_allocateTBE, "t", desc="allocate TBE Entry") {
    check_allocate(TBEs);
    TBEs.allocate(address);
    set_tbe(TBEs.lookup(address));
  }

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

  action(sf_setFlush, "sf", desc="set flush") {
    inFlush := true;
    APPEND_TRANSITION_COMMENT(" inFlush is true");
  }

  action(p_popMandatoryQueue, "pm", desc="Pop Mandatory Queue") {
    mandatoryQueue_in.dequeue(clockEdge());
  }

  action(pr_popResponseQueue, "pr", desc="Pop Response Queue") {
    responseToTCP_in.dequeue(clockEdge());
  }

  action(l_loadDone, "l", desc="local load done") {
    assert(is_valid(cache_entry));
    if (use_seq_not_coal) {
      sequencer.readCallback(address, cache_entry.DataBlk, false, MachineType:L1Cache);
    } else {
      coalescer.readCallback(address, MachineType:L1Cache, cache_entry.DataBlk);
    }
  }

  action(ad_atomicDone, "ad", desc="atomic done") {
    assert(is_valid(cache_entry));
    coalescer.atomicCallback(address, MachineType:L1Cache, cache_entry.DataBlk);
  }

  action(s_storeDone, "s", desc="local store done") {
    assert(is_valid(cache_entry));

    if (use_seq_not_coal) {
      sequencer.writeCallback(address, cache_entry.DataBlk, false, MachineType:L1Cache);
    } else {
      coalescer.writeCallback(address, MachineType:L1Cache, cache_entry.DataBlk);
    }
    cache_entry.Dirty := true;
  }

  action(inv_invDone, "inv", desc="local inv done") {
    if (use_seq_not_coal) {
        DPRINTF(RubySlicc, "Sequencer does not define invCallback!\n");
        assert(false);
    } else {
      coalescer.invTCPCallback(address);
    }
  }

  action(wd_wtDone, "wd", desc="writethrough done") {
    if (use_seq_not_coal) {
      DPRINTF(RubySlicc, "Sequencer does not define writeCompleteCallback!\n");
      assert(false);
    } else {
      peek(responseToTCP_in, ResponseMsg) {
        coalescer.writeCompleteCallback(address, in_msg.instSeqNum);
      }
    }
  }

  action(dw_dirtyWrite, "dw", desc="update write mask"){
    peek(mandatoryQueue_in, RubyRequest) {
      cache_entry.DataBlk.copyPartial(in_msg.WTData,in_msg.writeMask);
      cache_entry.writeMask.orMask(in_msg.writeMask);
    }
  }
  action(w_writeCache, "w", desc="write data to cache") {
    peek(responseToTCP_in, ResponseMsg) {
      assert(is_valid(cache_entry));
      DataBlock tmp := in_msg.DataBlk;
      tmp.copyPartial(cache_entry.DataBlk,cache_entry.writeMask);
      cache_entry.DataBlk := tmp;
    }
  }

  action(mru_updateMRU, "mru", desc="Touch block for replacement policy") {
    L1cache.setMRU(address);
  }

//  action(zz_recycleMandatoryQueue, "\z", desc="recycle mandatory queue") {
//    mandatoryQueue_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
//  }

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

  // added for profiling
  action(uu_profileDataMiss, "\udm", desc="Profile the demand miss"){
    L1cache.profileDemandMiss();
  }

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


  // Transitions
  // ArrayRead/Write assumptions:
  // All requests read Tag Array
  // TBE allocation write the TagArray to I
  // TBE only checked on misses
  // Stores will also write dirty bits in the tag
  // WriteThroughs still need to use cache entry as staging buffer for wavefront

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

  transition({A}, {Load, Atomic, StoreThrough}) { //TagArrayRead} {
      z_stall;
  }

  transition(I, Load) {TagArrayRead} {
    n_issueRdBlk;
    uu_profileDataMiss;
    p_popMandatoryQueue;
  }

  transition(V, Load) {TagArrayRead, DataArrayRead} {
    l_loadDone;
    mru_updateMRU;
    uu_profileDataHit;
    p_popMandatoryQueue;
  }

  transition({V, I}, Atomic, A) {TagArrayRead, TagArrayWrite} {
    t_allocateTBE;
    mru_updateMRU;
    at_atomicThrough;
    p_popMandatoryQueue;
  }

  transition(I, StoreThrough) {TagArrayRead, TagArrayWrite, DataArrayWrite} {
    a_allocate;
    dw_dirtyWrite;
    s_storeDone;
    uu_profileDataMiss;
    wt_writeThrough;
    ic_invCache;
    p_popMandatoryQueue;
  }

  transition(V, StoreThrough, I) {TagArrayRead, TagArrayWrite, DataArrayWrite} {
    dw_dirtyWrite;
    s_storeDone;
    uu_profileDataHit;
    wt_writeThrough;
    ic_invCache;
    p_popMandatoryQueue;
  }

  transition(I, TCC_Ack, V) {TagArrayRead, TagArrayWrite, DataArrayRead, DataArrayWrite} {
    a_allocate;
    w_writeCache;
    l_loadDone;
    pr_popResponseQueue;
  }

  transition(I, Bypass, I) {
    rb_bypassDone;
    pr_popResponseQueue;
  }

  transition(A, Bypass, I){
    d_deallocateTBE;
    wab_bypassDone;
    pr_popResponseQueue;
  }

  transition(A, TCC_Ack, I) {TagArrayRead, DataArrayRead, DataArrayWrite} {
    d_deallocateTBE;
    a_allocate;
    w_writeCache;
    ad_atomicDone;
    pr_popResponseQueue;
    ic_invCache;
  }

  transition(V, TCC_Ack, V) {TagArrayRead, DataArrayRead, DataArrayWrite} {
    w_writeCache;
    l_loadDone;
    pr_popResponseQueue;
  }

  transition({I, V}, Repl, I) {TagArrayRead, TagArrayWrite} {
    ic_invCache;
  }

  transition({A}, Repl) {TagArrayRead, TagArrayWrite} {
    ic_invCache;
  }

  transition({V, I, A},Flush) {TagArrayFlash} {
    sf_setFlush;
    p_popMandatoryQueue;
  }

  transition({I, V}, Evict, I) {TagArrayFlash} {
    inv_invDone;
    p_popMandatoryQueue;
    ic_invCache;
  }

  transition(A, Evict) {TagArrayFlash} {
    inv_invDone;
    p_popMandatoryQueue;
  }

  // TCC_AckWB only snoops TBE
  transition({V, I, A}, TCC_AckWB) {
    wd_wtDone;
    pr_popResponseQueue;
  }
}
