MOESI_CMP_directory-dma.sm revision 14184
114184Sgabeblack@google.com/* 214184Sgabeblack@google.com * Copyright (c) 2019 ARM Limited 314184Sgabeblack@google.com * All rights reserved 414184Sgabeblack@google.com * 514184Sgabeblack@google.com * The license below extends only to copyright in the software and shall 614184Sgabeblack@google.com * not be construed as granting a license to any other intellectual 714184Sgabeblack@google.com * property including but not limited to intellectual property relating 814184Sgabeblack@google.com * to a hardware implementation of the functionality of the software 914184Sgabeblack@google.com * licensed hereunder. You may use the software subject to the license 1014184Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated 1114184Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software, 1214184Sgabeblack@google.com * modified or unmodified, in source code or in binary form. 1314184Sgabeblack@google.com * 1414184Sgabeblack@google.com * Copyright (c) 2009-2013 Mark D. Hill and David A. Wood 1514184Sgabeblack@google.com * Copyright (c) 2010-2011 Advanced Micro Devices, Inc. 1614184Sgabeblack@google.com * All rights reserved. 1714184Sgabeblack@google.com * 1814184Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 1914184Sgabeblack@google.com * modification, are permitted provided that the following conditions are 2014184Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 2114184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 2214184Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 2314184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 2414184Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 2514184Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 2614184Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 2714184Sgabeblack@google.com * this software without specific prior written permission. 2814184Sgabeblack@google.com * 2914184Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3014184Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3114184Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3214184Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3314184Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3414184Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3514184Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3614184Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3714184Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3814184Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3914184Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4014184Sgabeblack@google.com */ 4114184Sgabeblack@google.com 4214184Sgabeblack@google.commachine(MachineType:DMA, "DMA Controller") 4314184Sgabeblack@google.com : DMASequencer * dma_sequencer; 4414184Sgabeblack@google.com Cycles request_latency := 14; 4514184Sgabeblack@google.com Cycles response_latency := 14; 4614184Sgabeblack@google.com 4714184Sgabeblack@google.com MessageBuffer * responseFromDir, network="From", virtual_network="2", 4814184Sgabeblack@google.com vnet_type="response"; 4914184Sgabeblack@google.com 5014184Sgabeblack@google.com MessageBuffer * reqToDir, network="To", virtual_network="1", 5114184Sgabeblack@google.com vnet_type="request"; 5214184Sgabeblack@google.com MessageBuffer * respToDir, network="To", virtual_network="2", 5314184Sgabeblack@google.com vnet_type="dmaresponse"; 5414184Sgabeblack@google.com 5514184Sgabeblack@google.com MessageBuffer * mandatoryQueue; 5614184Sgabeblack@google.com MessageBuffer * triggerQueue; 5714184Sgabeblack@google.com{ 5814184Sgabeblack@google.com state_declaration(State, desc="DMA states", default="DMA_State_READY") { 5914184Sgabeblack@google.com READY, AccessPermission:Invalid, desc="Ready to accept a new request"; 6014184Sgabeblack@google.com BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request"; 6114184Sgabeblack@google.com BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request"; 6214184Sgabeblack@google.com } 6314184Sgabeblack@google.com 6414184Sgabeblack@google.com enumeration(Event, desc="DMA events") { 6514184Sgabeblack@google.com ReadRequest, desc="A new read request"; 6614184Sgabeblack@google.com WriteRequest, desc="A new write request"; 6714184Sgabeblack@google.com Data, desc="Data from a DMA memory read"; 6814184Sgabeblack@google.com DMA_Ack, desc="DMA write to memory completed"; 6914184Sgabeblack@google.com Inv_Ack, desc="Invalidation Ack from a sharer"; 7014184Sgabeblack@google.com All_Acks, desc="All acks received"; 7114184Sgabeblack@google.com } 7214184Sgabeblack@google.com 7314184Sgabeblack@google.com structure(TBE, desc="...") { 7414184Sgabeblack@google.com Addr address, desc="Physical address"; 7514184Sgabeblack@google.com int NumAcks, default="0", desc="Number of Acks pending"; 7614184Sgabeblack@google.com DataBlock DataBlk, desc="Data"; 7714184Sgabeblack@google.com } 7814184Sgabeblack@google.com 7914184Sgabeblack@google.com structure(TBETable, external = "yes") { 8014184Sgabeblack@google.com TBE lookup(Addr); 8114184Sgabeblack@google.com void allocate(Addr); 8214184Sgabeblack@google.com void deallocate(Addr); 8314184Sgabeblack@google.com bool isPresent(Addr); 8414184Sgabeblack@google.com } 8514184Sgabeblack@google.com 8614184Sgabeblack@google.com TBETable TBEs, template="<DMA_TBE>", constructor="m_number_of_TBEs"; 8714184Sgabeblack@google.com State cur_state; 8814184Sgabeblack@google.com 8914184Sgabeblack@google.com Tick clockEdge(); 9014184Sgabeblack@google.com void set_tbe(TBE b); 9114184Sgabeblack@google.com void unset_tbe(); 9214184Sgabeblack@google.com void wakeUpAllBuffers(); 9314184Sgabeblack@google.com MachineID mapAddressToMachine(Addr addr, MachineType mtype); 9414184Sgabeblack@google.com 9514184Sgabeblack@google.com State getState(TBE tbe, Addr addr) { 9614184Sgabeblack@google.com return cur_state; 9714184Sgabeblack@google.com } 9814184Sgabeblack@google.com void setState(TBE tbe, Addr addr, State state) { 9914184Sgabeblack@google.com cur_state := state; 10014184Sgabeblack@google.com } 10114184Sgabeblack@google.com 10214184Sgabeblack@google.com AccessPermission getAccessPermission(Addr addr) { 10314184Sgabeblack@google.com return AccessPermission:NotPresent; 10414184Sgabeblack@google.com } 10514184Sgabeblack@google.com 10614184Sgabeblack@google.com void setAccessPermission(Addr addr, State state) { 10714184Sgabeblack@google.com } 10814184Sgabeblack@google.com 10914184Sgabeblack@google.com void functionalRead(Addr addr, Packet *pkt) { 11014184Sgabeblack@google.com error("DMA does not support functional read."); 11114184Sgabeblack@google.com } 11214184Sgabeblack@google.com 11314184Sgabeblack@google.com int functionalWrite(Addr addr, Packet *pkt) { 11414184Sgabeblack@google.com error("DMA does not support functional write."); 11514184Sgabeblack@google.com } 11614184Sgabeblack@google.com 11714184Sgabeblack@google.com out_port(reqToDirectory_out, RequestMsg, reqToDir, desc="..."); 11814184Sgabeblack@google.com out_port(respToDirectory_out, ResponseMsg, respToDir, desc="..."); 11914184Sgabeblack@google.com out_port(triggerQueue_out, TriggerMsg, triggerQueue, desc="..."); 12014184Sgabeblack@google.com 12114184Sgabeblack@google.com in_port(dmaResponseQueue_in, ResponseMsg, responseFromDir, rank=2) { 12214184Sgabeblack@google.com if (dmaResponseQueue_in.isReady(clockEdge())) { 12314184Sgabeblack@google.com peek( dmaResponseQueue_in, ResponseMsg) { 12414184Sgabeblack@google.com if (in_msg.Type == CoherenceResponseType:DMA_ACK) { 12514184Sgabeblack@google.com trigger(Event:DMA_Ack, makeLineAddress(in_msg.addr), 12614184Sgabeblack@google.com TBEs[makeLineAddress(in_msg.addr)]); 12714184Sgabeblack@google.com } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE || 12814184Sgabeblack@google.com in_msg.Type == CoherenceResponseType:DATA) { 12914184Sgabeblack@google.com trigger(Event:Data, makeLineAddress(in_msg.addr), 13014184Sgabeblack@google.com TBEs[makeLineAddress(in_msg.addr)]); 13114184Sgabeblack@google.com } else if (in_msg.Type == CoherenceResponseType:ACK) { 13214184Sgabeblack@google.com trigger(Event:Inv_Ack, makeLineAddress(in_msg.addr), 13314184Sgabeblack@google.com TBEs[makeLineAddress(in_msg.addr)]); 13414184Sgabeblack@google.com } else { 13514184Sgabeblack@google.com error("Invalid response type"); 13614184Sgabeblack@google.com } 13714184Sgabeblack@google.com } 13814184Sgabeblack@google.com } 13914184Sgabeblack@google.com } 14014184Sgabeblack@google.com 14114184Sgabeblack@google.com // Trigger Queue 14214184Sgabeblack@google.com in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=1) { 14314184Sgabeblack@google.com if (triggerQueue_in.isReady(clockEdge())) { 14414184Sgabeblack@google.com peek(triggerQueue_in, TriggerMsg) { 14514184Sgabeblack@google.com if (in_msg.Type == TriggerType:ALL_ACKS) { 14614184Sgabeblack@google.com trigger(Event:All_Acks, in_msg.addr, TBEs[in_msg.addr]); 14714184Sgabeblack@google.com } else { 14814184Sgabeblack@google.com error("Unexpected message"); 14914184Sgabeblack@google.com } 15014184Sgabeblack@google.com } 15114184Sgabeblack@google.com } 15214184Sgabeblack@google.com } 15314184Sgabeblack@google.com 15414184Sgabeblack@google.com in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, rank=0) { 15514184Sgabeblack@google.com if (dmaRequestQueue_in.isReady(clockEdge())) { 15614184Sgabeblack@google.com peek(dmaRequestQueue_in, SequencerMsg) { 15714184Sgabeblack@google.com if (in_msg.Type == SequencerRequestType:LD ) { 15814184Sgabeblack@google.com trigger(Event:ReadRequest, in_msg.LineAddress, 15914184Sgabeblack@google.com TBEs[in_msg.LineAddress]); 16014184Sgabeblack@google.com } else if (in_msg.Type == SequencerRequestType:ST) { 16114184Sgabeblack@google.com trigger(Event:WriteRequest, in_msg.LineAddress, 16214184Sgabeblack@google.com TBEs[in_msg.LineAddress]); 16314184Sgabeblack@google.com } else { 16414184Sgabeblack@google.com error("Invalid request type"); 16514184Sgabeblack@google.com } 16614184Sgabeblack@google.com } 16714184Sgabeblack@google.com } 16814184Sgabeblack@google.com } 16914184Sgabeblack@google.com 17014184Sgabeblack@google.com action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") { 17114184Sgabeblack@google.com peek(dmaRequestQueue_in, SequencerMsg) { 17214184Sgabeblack@google.com enqueue(reqToDirectory_out, RequestMsg, request_latency) { 17314184Sgabeblack@google.com out_msg.addr := in_msg.PhysicalAddress; 17414184Sgabeblack@google.com out_msg.Type := CoherenceRequestType:DMA_READ; 17514184Sgabeblack@google.com out_msg.DataBlk := in_msg.DataBlk; 17614184Sgabeblack@google.com out_msg.Len := in_msg.Len; 17714184Sgabeblack@google.com out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 17814184Sgabeblack@google.com out_msg.Requestor := machineID; 17914184Sgabeblack@google.com out_msg.RequestorMachine := MachineType:DMA; 18014184Sgabeblack@google.com out_msg.MessageSize := MessageSizeType:Writeback_Control; 18114184Sgabeblack@google.com } 18214184Sgabeblack@google.com } 18314184Sgabeblack@google.com } 18414184Sgabeblack@google.com 18514184Sgabeblack@google.com action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") { 18614184Sgabeblack@google.com peek(dmaRequestQueue_in, SequencerMsg) { 18714184Sgabeblack@google.com enqueue(reqToDirectory_out, RequestMsg, request_latency) { 18814184Sgabeblack@google.com out_msg.addr := in_msg.PhysicalAddress; 18914184Sgabeblack@google.com out_msg.Type := CoherenceRequestType:DMA_WRITE; 19014184Sgabeblack@google.com out_msg.DataBlk := in_msg.DataBlk; 19114184Sgabeblack@google.com out_msg.Len := in_msg.Len; 19214184Sgabeblack@google.com out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 19314184Sgabeblack@google.com out_msg.Requestor := machineID; 19414184Sgabeblack@google.com out_msg.RequestorMachine := MachineType:DMA; 19514184Sgabeblack@google.com out_msg.MessageSize := MessageSizeType:Writeback_Control; 19614184Sgabeblack@google.com } 19714184Sgabeblack@google.com } 19814184Sgabeblack@google.com } 19914184Sgabeblack@google.com 20014184Sgabeblack@google.com action(a_ackCallback, "a", desc="Notify dma controller that write request completed") { 20114184Sgabeblack@google.com dma_sequencer.ackCallback(address); 20214184Sgabeblack@google.com } 20314184Sgabeblack@google.com 20414184Sgabeblack@google.com action(o_checkForCompletion, "o", desc="Check if we have received all the messages required for completion") { 20514184Sgabeblack@google.com assert(is_valid(tbe)); 20614184Sgabeblack@google.com if (tbe.NumAcks == 0) { 20714184Sgabeblack@google.com enqueue(triggerQueue_out, TriggerMsg) { 20814184Sgabeblack@google.com out_msg.addr := address; 20914184Sgabeblack@google.com out_msg.Type := TriggerType:ALL_ACKS; 21014184Sgabeblack@google.com } 21114184Sgabeblack@google.com } 21214184Sgabeblack@google.com } 21314184Sgabeblack@google.com 21414184Sgabeblack@google.com action(u_updateAckCount, "u", desc="Update ack count") { 21514184Sgabeblack@google.com peek(dmaResponseQueue_in, ResponseMsg) { 21614184Sgabeblack@google.com assert(is_valid(tbe)); 21714184Sgabeblack@google.com tbe.NumAcks := tbe.NumAcks - in_msg.Acks; 21814184Sgabeblack@google.com } 21914184Sgabeblack@google.com } 22014184Sgabeblack@google.com 22114184Sgabeblack@google.com action( u_sendExclusiveUnblockToDir, "\u", desc="send exclusive unblock to directory") { 22214184Sgabeblack@google.com enqueue(respToDirectory_out, ResponseMsg, response_latency) { 22314184Sgabeblack@google.com out_msg.addr := address; 22414184Sgabeblack@google.com out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE; 22514184Sgabeblack@google.com out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 22614184Sgabeblack@google.com out_msg.Sender := machineID; 22714184Sgabeblack@google.com out_msg.SenderMachine := MachineType:DMA; 22814184Sgabeblack@google.com out_msg.MessageSize := MessageSizeType:Writeback_Control; 22914184Sgabeblack@google.com } 23014184Sgabeblack@google.com } 23114184Sgabeblack@google.com 23214184Sgabeblack@google.com action(p_popRequestQueue, "p", desc="Pop request queue") { 23314184Sgabeblack@google.com dmaRequestQueue_in.dequeue(clockEdge()); 23414184Sgabeblack@google.com } 23514184Sgabeblack@google.com 23614184Sgabeblack@google.com action(p_popResponseQueue, "\p", desc="Pop request queue") { 23714184Sgabeblack@google.com dmaResponseQueue_in.dequeue(clockEdge()); 23814184Sgabeblack@google.com } 23914184Sgabeblack@google.com 24014184Sgabeblack@google.com action(p_popTriggerQueue, "pp", desc="Pop trigger queue") { 24114184Sgabeblack@google.com triggerQueue_in.dequeue(clockEdge()); 24214184Sgabeblack@google.com } 24314184Sgabeblack@google.com 24414184Sgabeblack@google.com action(t_updateTBEData, "t", desc="Update TBE Data") { 24514184Sgabeblack@google.com peek(dmaResponseQueue_in, ResponseMsg) { 24614184Sgabeblack@google.com assert(is_valid(tbe)); 24714184Sgabeblack@google.com tbe.DataBlk := in_msg.DataBlk; 24814184Sgabeblack@google.com } 24914184Sgabeblack@google.com } 25014184Sgabeblack@google.com 25114184Sgabeblack@google.com action(d_dataCallbackFromTBE, "/d", desc="data callback with data from TBE") { 25214184Sgabeblack@google.com assert(is_valid(tbe)); 25314184Sgabeblack@google.com dma_sequencer.dataCallback(tbe.DataBlk, address); 25414184Sgabeblack@google.com } 25514184Sgabeblack@google.com 25614184Sgabeblack@google.com action(v_allocateTBE, "v", desc="Allocate TBE entry") { 25714184Sgabeblack@google.com TBEs.allocate(address); 25814184Sgabeblack@google.com set_tbe(TBEs[address]); 25914184Sgabeblack@google.com } 26014184Sgabeblack@google.com 26114184Sgabeblack@google.com action(w_deallocateTBE, "w", desc="Deallocate TBE entry") { 26214184Sgabeblack@google.com TBEs.deallocate(address); 26314184Sgabeblack@google.com unset_tbe(); 26414184Sgabeblack@google.com } 26514184Sgabeblack@google.com 26614184Sgabeblack@google.com action(zz_stallAndWaitRequestQueue, "zz", desc="...") { 26714184Sgabeblack@google.com stall_and_wait(dmaRequestQueue_in, address); 26814184Sgabeblack@google.com } 26914184Sgabeblack@google.com 27014184Sgabeblack@google.com action(wkad_wakeUpAllDependents, "wkad", desc="wake-up all dependents") { 27114184Sgabeblack@google.com wakeUpAllBuffers(); 27214184Sgabeblack@google.com } 27314184Sgabeblack@google.com 27414184Sgabeblack@google.com transition(READY, ReadRequest, BUSY_RD) { 27514184Sgabeblack@google.com s_sendReadRequest; 27614184Sgabeblack@google.com v_allocateTBE; 27714184Sgabeblack@google.com p_popRequestQueue; 27814184Sgabeblack@google.com } 27914184Sgabeblack@google.com 28014184Sgabeblack@google.com transition(BUSY_RD, Inv_Ack) { 28114184Sgabeblack@google.com u_updateAckCount; 28214184Sgabeblack@google.com o_checkForCompletion; 28314184Sgabeblack@google.com p_popResponseQueue; 28414184Sgabeblack@google.com } 28514184Sgabeblack@google.com 28614184Sgabeblack@google.com transition(BUSY_RD, Data, READY) { 28714184Sgabeblack@google.com t_updateTBEData; 28814184Sgabeblack@google.com d_dataCallbackFromTBE; 28914184Sgabeblack@google.com w_deallocateTBE; 29014184Sgabeblack@google.com //u_updateAckCount; 29114184Sgabeblack@google.com //o_checkForCompletion; 29214184Sgabeblack@google.com p_popResponseQueue; 29314184Sgabeblack@google.com wkad_wakeUpAllDependents; 29414184Sgabeblack@google.com } 29514184Sgabeblack@google.com 29614184Sgabeblack@google.com transition(BUSY_RD, All_Acks, READY) { 29714184Sgabeblack@google.com d_dataCallbackFromTBE; 29814184Sgabeblack@google.com //u_sendExclusiveUnblockToDir; 29914184Sgabeblack@google.com w_deallocateTBE; 30014184Sgabeblack@google.com p_popTriggerQueue; 30114184Sgabeblack@google.com wkad_wakeUpAllDependents; 30214184Sgabeblack@google.com } 30314184Sgabeblack@google.com 30414184Sgabeblack@google.com transition(READY, WriteRequest, BUSY_WR) { 30514184Sgabeblack@google.com s_sendWriteRequest; 30614184Sgabeblack@google.com v_allocateTBE; 30714184Sgabeblack@google.com p_popRequestQueue; 30814184Sgabeblack@google.com } 30914184Sgabeblack@google.com 31014184Sgabeblack@google.com transition(BUSY_WR, Inv_Ack) { 31114184Sgabeblack@google.com u_updateAckCount; 31214184Sgabeblack@google.com o_checkForCompletion; 31314184Sgabeblack@google.com p_popResponseQueue; 31414184Sgabeblack@google.com } 31514184Sgabeblack@google.com 31614184Sgabeblack@google.com transition(BUSY_WR, DMA_Ack) { 31714184Sgabeblack@google.com u_updateAckCount; // actually increases 31814184Sgabeblack@google.com o_checkForCompletion; 31914184Sgabeblack@google.com p_popResponseQueue; 32014184Sgabeblack@google.com } 32114184Sgabeblack@google.com 32214184Sgabeblack@google.com transition(BUSY_WR, All_Acks, READY) { 32314184Sgabeblack@google.com a_ackCallback; 32414184Sgabeblack@google.com u_sendExclusiveUnblockToDir; 32514184Sgabeblack@google.com w_deallocateTBE; 32614184Sgabeblack@google.com p_popTriggerQueue; 32714184Sgabeblack@google.com wkad_wakeUpAllDependents; 32814184Sgabeblack@google.com } 32914184Sgabeblack@google.com 33014184Sgabeblack@google.com transition({BUSY_RD,BUSY_WR}, {ReadRequest,WriteRequest}) { 33114184Sgabeblack@google.com zz_stallAndWaitRequestQueue; 33214184Sgabeblack@google.com } 33314184Sgabeblack@google.com} 334