/*
 * Copyright (c) 2021-2022 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.
 *
 * 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:MiscNode, "CHI Misc Node for handling and distrbuting DVM operations") :

  // Additional pipeline latency modeling for the different request types
  // When defined, these are applied after the initial tag array read and
  // sending necessary snoops.
  Cycles snp_latency := 0; // Applied before handling any snoop
  Cycles snp_inv_latency := 0; // Additional latency for invalidating snoops

  // Request TBE allocation latency
  Cycles allocation_latency := 0;

  // Enqueue latencies for outgoing messages
  // NOTE: should remove this and only use parameters above?
  Cycles request_latency := 1;
  Cycles response_latency := 1;
  Cycles sched_response_latency := 1;
  Cycles snoop_latency := 1;
  Cycles data_latency := 1;

  // Recycle latency on resource stalls
  Cycles stall_recycle_lat := 1;

  // Number of entries in the TBE tables
  int number_of_DVM_TBEs;
  int number_of_non_sync_TBEs;

  // wait for the final tag update to complete before deallocating TBE and
  // going to final stable state
  bool dealloc_wait_for_tag := "False";

  // Width of the data channel. Data transfer are split in multiple messages
  // at the protocol level when this is less than the cache line size.
  int data_channel_size;

  // Combine Comp+DBIDResp responses for DvmOp(Non-sync)
  // CHI-D and later only!
  bool early_nonsync_comp;

  // additional latency for the WU Comp response
  Cycles comp_wu_latency := 0;

  // Additional latency for sending RetryAck
  Cycles retry_ack_latency := 0;

  // Additional latency for sending PCrdGrant
  Cycles crd_grant_latency := 0;

  // Additional latency for retrying a request
  Cycles retry_req_latency := 0;

  // stall new requests to destinations with a pending retry
  bool throttle_req_on_retry := "True";

  // Message Queues

  // Interface to the network
  // Note vnet_type is used by Garnet only. "response" type is assumed to
  // have data, so use it for data channels and "none" for the rest.
  // network="To" for outbound queue; network="From" for inbound
  // virtual networks: 0=request, 1=snoop, 2=response, 3=data

  MessageBuffer * reqOut,   network="To", virtual_network="0", vnet_type="none";
  MessageBuffer * snpOut,   network="To", virtual_network="1", vnet_type="none";
  MessageBuffer * rspOut,   network="To", virtual_network="2", vnet_type="none";
  MessageBuffer * datOut,   network="To", virtual_network="3", vnet_type="response";

  MessageBuffer * reqIn,   network="From", virtual_network="0", vnet_type="none";
  MessageBuffer * snpIn,   network="From", virtual_network="1", vnet_type="none";
  MessageBuffer * rspIn,   network="From", virtual_network="2", vnet_type="none";
  MessageBuffer * datIn,   network="From", virtual_network="3", vnet_type="response";

  // Mandatory queue for receiving requests from the sequencer
  MessageBuffer * mandatoryQueue;

  // Internal queue for trigger events
  MessageBuffer * triggerQueue;

  // Internal queue for retry trigger events
  MessageBuffer * retryTriggerQueue;

  // Internal queue for scheduled response messages
  MessageBuffer * schedRspTriggerQueue;

  // Internal queue for accepted requests
  MessageBuffer * reqRdy;

  // Internal queue for accepted snoops
  MessageBuffer * snpRdy;

{

  ////////////////////////////////////////////////////////////////////////////
  // States
  ////////////////////////////////////////////////////////////////////////////

  // Should only involve states relevant to TLBI or Sync operations
  state_declaration(State, default="MiscNode_State_null") {
    Unallocated, AccessPermission:Invalid, desc="TBE is not associated with a DVM op";

    DvmSync_Partial, AccessPermission:Invalid, desc="DvmSync which is waiting for extra data";
    DvmSync_ReadyToDist, AccessPermission:Invalid, desc="DvmSync which has all data, ready to distribute to other cores";
    DvmSync_Distributing, AccessPermission:Invalid, desc="DvmSync which is distributing snoops to the rest of the cores";
    DvmSync_Waiting, AccessPermission:Invalid, desc="DvmSync which is waiting for snoop responses to come back";

    DvmNonSync_Partial, AccessPermission:Invalid, desc="DVM non-sync waiting for extra data from initiator";
    DvmNonSync_ReadyToDist, AccessPermission:Invalid, desc="DVM non-sync with all data, ready to distribute to other cores";
    DvmNonSync_Distributing, AccessPermission:Invalid, desc="DVM non-sync distributing snoops to the rest of the cores";
    DvmNonSync_Waiting, AccessPermission:Invalid, desc="DVM non-sync waiting for snoop responses to come back";

    DvmOp_Complete, AccessPermission:Invalid, desc="A completed DVM op";

    // Null state for debugging
    null, AccessPermission:Invalid, desc="Null state";
  }


  ////////////////////////////////////////////////////////////////////////////
  // Events
  ////////////////////////////////////////////////////////////////////////////

  enumeration(Event) {
    // Events triggered by incoming requests. Allocate TBE and move
    // request or snoop to the ready queue
    AllocRequest,           desc="Allocates a TBE for a request. Triggers a retry if table is full";
    AllocRequestWithCredit, desc="Allocates a TBE for a request. Always succeeds. Used when a client is retrying after being denied.";

    SnpResp_I,      desc="";
    NCBWrData,      desc="";

    // Retry handling
    SendRetryAck,   desc="Send RetryAck";
    SendPCrdGrant,  desc="Send PCrdGrant";
    DoRetry,        desc="Resend the current pending request";

    DvmTlbi_Initiate, desc="Initiate a DVM TLBI on the provided TBE";
    DvmSync_Initiate, desc="Initiate a DVM Sync on the provided TBE";
    DvmSendNextMessage_P1, desc="Trigger a SnpDvmOp_P1 message based on the TBE type";
    DvmSendNextMessage_P2, desc="Trigger a SnpDvmOp_P2 message based on the TBE type";
    DvmFinishDistributing, desc="Move the TBE out of the Distributing state into Waiting";
    DvmFinishWaiting, desc="Move the TBE out of the Waiting state and complete it";
    DvmUpdatePendingOps, desc="Update which operation is currently distributing";

    // This is triggered once a transaction doesn't have
    // any queued action and is not expecting responses/data. The transaction
    // is finalized and the next stable state is stored in the cache/directory
    // See the processNextState and makeFinalState functions
    Final,          desc="";

    null,           desc="";
  }

  ////////////////////////////////////////////////////////////////////////////
  // Data structures
  ////////////////////////////////////////////////////////////////////////////

  // Cache block size
  int blockSize, default="RubySystem::getBlockSizeBytes()";

  // Helper class for tracking expected response and data messages
  structure(ExpectedMap, external ="yes") {
    void clear(int dataChunks);
    void addExpectedRespType(CHIResponseType);
    void addExpectedDataType(CHIDataType);
    void setExpectedCount(int val);
    void addExpectedCount(int val);
    bool hasExpected();
    bool hasReceivedResp();
    bool hasReceivedData();
    int expected();
    int received();
    bool receiveResp(CHIResponseType);
    bool receiveData(CHIDataType);
    bool receivedDataType(CHIDataType);
    bool receivedRespType(CHIResponseType);
  }

  // Tracks a pending retry
  structure(RetryQueueEntry) {
    Addr txnId,           desc="Transaction ID";
    MachineID retryDest, desc="Retry destination";
    bool isNonSync, desc="Is a NonSync operation";
  }

  // Queue for event triggers. Used to specify a list of actions that need
  // to be performed across multiple transitions.
  // This class is also used to track pending retries
  structure(TriggerQueue, external ="yes") {
    Event front();
    Event back();
    bool frontNB();
    bool backNB();
    bool empty();
    void push(Event);
    void pushNB(Event);
    void pushFront(Event);
    void pushFrontNB(Event);
    void pop();
  }

  // TBE fields
  structure(TBE, desc="Transaction buffer entry definition") {
    Tick timestamp, desc="Time this entry was allocated. Affects order of trigger events";

    int storSlot, desc="Slot in the storage tracker occupied by this entry";

    // Transaction info mostly extracted from the request message
    Addr txnId, desc="Unique Transaction ID";
    CHIRequestType reqType, desc="Request type that initiated this transaction";
    bool isNonSync, desc="Is a non-sync DVM operation";
    MachineID requestor,    desc="Requestor ID";

    // Transaction state information
    State state,    desc="SLICC line state";

    NetDest notSentTargets, desc="Set of MachineIDs we haven't snooped yet";
    NetDest pendingTargets, desc="Set of MachineIDs that were snooped, but haven't responded";
    NetDest receivedTargets, desc="Set of MachineIDs that have responded to snoops";

    // Helper structures to track expected events and additional transient
    // state info

    // List of actions to be performed while on a transient state
    // See the processNextState function for details
    TriggerQueue actions, template="<MiscNode_Event>", desc="List of actions";
    Event pendAction,         desc="Current pending action";
    Tick delayNextAction,     desc="Delay next action until given tick";
    State finalState,         desc="Final state; set when pendAction==Final";

    // List of expected responses and data. Checks the type of data against the
    // expected ones for debugging purposes
    // See the processNextState function for details
    ExpectedMap expected_req_resp, template="<CHIResponseType,CHIDataType>";
    ExpectedMap expected_snp_resp, template="<CHIResponseType,CHIDataType>";
    bool waiting_on_other_txns, desc="Is waiting for other transactions to update before finishing.";
    CHIResponseType slicchack1; // fix compiler not including headers
    CHIDataType slicchack2; // fix compiler not including headers

    // Tracks pending scheduled responses
    int sched_responses;
    bool block_on_sched_responses;

    // This TBE stalled a message and thus we need to call wakeUpBuffers
    // at some point
    bool wakeup_pending_req;
    bool wakeup_pending_snp;
    bool wakeup_pending_tgr;
  }

  // TBE table definition
  structure(MN_TBETable, external ="yes") {
    TBE lookup(Addr);
    void allocate(Addr);
    void deallocate(Addr);
    bool isPresent(Addr);

    TBE chooseNewDistributor();
  }

  structure(TBEStorage, external ="yes") {
    int size();
    int capacity();
    int reserved();
    int slotsAvailable();
    bool areNSlotsAvailable(int n);
    void incrementReserved();
    void decrementReserved();
    int addEntryToNewSlot();
    void removeEntryFromSlot(int slot);
  }

  structure(MN_TBEStorage, external ="yes") {
    int size();
    int capacity();
    int reserved();
    int slotsAvailable(int partition);
    bool areNSlotsAvailable(int n, int partition);
    void incrementReserved(int partition);
    void decrementReserved(int partition);
    int addEntryToNewSlot(int partition);
    void removeEntryFromSlot(int slot, int partition);

    // Which operation to retry depends on the current available storage.
    // If there's a NonSync op waiting for PCrdGrant and the Nonsync reserved space is free,
    // the NonSync takes priority.
    // => Make the MN_TBEStorage responsible for calculating this.
    void emplaceRetryEntry(RetryQueueEntry ret);
    bool hasPossibleRetry();
    RetryQueueEntry popNextRetryEntry();
  }

  // Definitions of the TBE tables

  // TBE table for DVM requests
  MN_TBETable dvmTBEs, constructor="m_number_of_DVM_TBEs";
  TBEStorage nonSyncTBEs, constructor="this, m_number_of_non_sync_TBEs";
  TBEStorage genericTBEs, constructor="this, (m_number_of_DVM_TBEs - m_number_of_non_sync_TBEs)";
  MN_TBEStorage storDvmTBEs, template="<MiscNode_RetryQueueEntry>", constructor="this, {m_genericTBEs_ptr, m_nonSyncTBEs_ptr}";

  // txnId of the current TBE which is distributing snoops
  // NOTE - this is a safety measure for making sure we don't
  // tell the same person to start snooping twice.
  // Don't rely on it, if someone stops distributing and no-one starts
  // this variable will not be updated.
  Addr currentDistributor, default="0";
  bool hasCurrentDistributor, default="false";
  bool needsToCheckPendingOps, default="false";

  // Pending RetryAck/PCrdGrant
  structure(RetryTriggerMsg, interface="Message") {
    Addr txnId;
    Event event;
    MachineID retryDest;

    bool functionalRead(Packet *pkt) { return false; }
    bool functionalRead(Packet *pkt, WriteMask &mask) { return false; }
    bool functionalWrite(Packet *pkt) { return false; }
  }

  // Pending transaction actions (generated by TBE:actions)
  structure(TriggerMsg, interface="Message") {
    Addr txnId;
    bool from_hazard; // this actions was generate during a snoop hazard
    bool functionalRead(Packet *pkt) { return false; }
    bool functionalRead(Packet *pkt, WriteMask &mask) { return false; }
    bool functionalWrite(Packet *pkt) { return false; }
  }


  ////////////////////////////////////////////////////////////////////////////
  // Input/output port definitions
  ////////////////////////////////////////////////////////////////////////////

  include "CHI-dvm-misc-node-ports.sm";
  // CHI-dvm-misc-node-ports.sm also includes CHI-dvm-misc-node-funcs.sm

  ////////////////////////////////////////////////////////////////////////////
  // Actions and transitions
  ////////////////////////////////////////////////////////////////////////////

  include "CHI-dvm-misc-node-actions.sm";
  include "CHI-dvm-misc-node-transitions.sm";
}
