| /* | |
| * Copyright (c) 2009 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: 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. | |
| * | |
| * | |
| * Authors: Brad Beckmann | |
| * Tushar Krishna | |
| */ | |
| machine(MachineType:Directory, "Garnet_standalone Directory") | |
| : MessageBuffer * requestToDir, network="From", virtual_network="0", | |
| vnet_type = "request"; | |
| MessageBuffer * forwardToDir, network="From", virtual_network="1", | |
| vnet_type = "forward"; | |
| MessageBuffer * responseToDir, network="From", virtual_network="2", | |
| vnet_type = "response"; | |
| { | |
| // STATES | |
| state_declaration(State, desc="Directory states", default="Directory_State_I") { | |
| // Base states | |
| I, AccessPermission:Invalid, desc="Invalid"; | |
| } | |
| // Events | |
| enumeration(Event, desc="Directory events") { | |
| // processor requests | |
| Receive_Request, desc="Receive Message"; | |
| Receive_Forward, desc="Receive Message"; | |
| Receive_Response, desc="Receive Message"; | |
| } | |
| // TYPES | |
| // DirectoryEntry | |
| structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") { | |
| State DirectoryState, desc="Directory state"; | |
| DataBlock DataBlk, desc="data for the block"; | |
| } | |
| // ** FUNCTIONS ** | |
| Tick clockEdge(); | |
| State getState(Addr addr) { | |
| return State:I; | |
| } | |
| void setState(Addr addr, State state) { | |
| } | |
| AccessPermission getAccessPermission(Addr addr) { | |
| return AccessPermission:NotPresent; | |
| } | |
| void setAccessPermission(Addr addr, State state) { | |
| } | |
| void functionalRead(Addr addr, Packet *pkt) { | |
| error("Garnet_standalone does not support functional read."); | |
| } | |
| int functionalWrite(Addr addr, Packet *pkt) { | |
| error("Garnet_standalone does not support functional write."); | |
| } | |
| // ** IN_PORTS ** | |
| in_port(requestQueue_in, RequestMsg, requestToDir) { | |
| if (requestQueue_in.isReady(clockEdge())) { | |
| peek(requestQueue_in, RequestMsg) { | |
| if (in_msg.Type == CoherenceRequestType:MSG) { | |
| trigger(Event:Receive_Request, in_msg.addr); | |
| } else { | |
| error("Invalid message"); | |
| } | |
| } | |
| } | |
| } | |
| in_port(forwardQueue_in, RequestMsg, forwardToDir) { | |
| if (forwardQueue_in.isReady(clockEdge())) { | |
| peek(forwardQueue_in, RequestMsg) { | |
| if (in_msg.Type == CoherenceRequestType:MSG) { | |
| trigger(Event:Receive_Forward, in_msg.addr); | |
| } else { | |
| error("Invalid message"); | |
| } | |
| } | |
| } | |
| } | |
| in_port(responseQueue_in, RequestMsg, responseToDir) { | |
| if (responseQueue_in.isReady(clockEdge())) { | |
| peek(responseQueue_in, RequestMsg) { | |
| if (in_msg.Type == CoherenceRequestType:MSG) { | |
| trigger(Event:Receive_Response, in_msg.addr); | |
| } else { | |
| error("Invalid message"); | |
| } | |
| } | |
| } | |
| } | |
| // Actions | |
| action(i_popIncomingRequestQueue, "i", desc="Pop incoming request queue") { | |
| requestQueue_in.dequeue(clockEdge()); | |
| } | |
| action(f_popIncomingForwardQueue, "f", desc="Pop incoming forward queue") { | |
| forwardQueue_in.dequeue(clockEdge()); | |
| } | |
| action(r_popIncomingResponseQueue, "r", desc="Pop incoming response queue") { | |
| responseQueue_in.dequeue(clockEdge()); | |
| } | |
| // TRANSITIONS | |
| // The directory simply drops the received packets. | |
| // The goal of Garnet_standalone is only to track network stats. | |
| transition(I, Receive_Request) { | |
| i_popIncomingRequestQueue; | |
| } | |
| transition(I, Receive_Forward) { | |
| f_popIncomingForwardQueue; | |
| } | |
| transition(I, Receive_Response) { | |
| r_popIncomingResponseQueue; | |
| } | |
| } |