MOESI_CMP_token-dma.sm revision 14184
114184Sgabeblack@google.com/* 214184Sgabeblack@google.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 314184Sgabeblack@google.com * All rights reserved. 414184Sgabeblack@google.com * 514184Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 614184Sgabeblack@google.com * modification, are permitted provided that the following conditions are 714184Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 814184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 914184Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1014184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1114184Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1214184Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1314184Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1414184Sgabeblack@google.com * this software without specific prior written permission. 1514184Sgabeblack@google.com * 1614184Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1714184Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1814184Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1914184Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2014184Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2114184Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2214184Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2314184Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2414184Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2514184Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2614184Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2714184Sgabeblack@google.com */ 2814184Sgabeblack@google.com 2914184Sgabeblack@google.com 3014184Sgabeblack@google.commachine(MachineType:DMA, "DMA Controller") 3114184Sgabeblack@google.com : DMASequencer * dma_sequencer; 3214184Sgabeblack@google.com Cycles request_latency := 6; 3314184Sgabeblack@google.com 3414184Sgabeblack@google.com // Messsage Queues 3514184Sgabeblack@google.com MessageBuffer * responseFromDir, network="From", virtual_network="5", 3614184Sgabeblack@google.com vnet_type="response"; 3714184Sgabeblack@google.com MessageBuffer * reqToDirectory, network="To", virtual_network="0", 3814184Sgabeblack@google.com vnet_type="request"; 3914184Sgabeblack@google.com 4014184Sgabeblack@google.com MessageBuffer * mandatoryQueue; 4114184Sgabeblack@google.com{ 4214184Sgabeblack@google.com state_declaration(State, desc="DMA states", default="DMA_State_READY") { 4314184Sgabeblack@google.com READY, AccessPermission:Invalid, desc="Ready to accept a new request"; 4414184Sgabeblack@google.com BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request"; 4514184Sgabeblack@google.com BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request"; 4614184Sgabeblack@google.com } 4714184Sgabeblack@google.com 4814184Sgabeblack@google.com enumeration(Event, desc="DMA events") { 4914184Sgabeblack@google.com ReadRequest, desc="A new read request"; 5014184Sgabeblack@google.com WriteRequest, desc="A new write request"; 5114184Sgabeblack@google.com Data, desc="Data from a DMA memory read"; 5214184Sgabeblack@google.com Ack, desc="DMA write to memory completed"; 5314184Sgabeblack@google.com } 5414184Sgabeblack@google.com 5514184Sgabeblack@google.com structure(TBE, desc="...") { 5614184Sgabeblack@google.com State TBEState, desc="Transient state"; 5714184Sgabeblack@google.com DataBlock DataBlk, desc="Data"; 5814184Sgabeblack@google.com } 5914184Sgabeblack@google.com 6014184Sgabeblack@google.com structure(TBETable, external = "yes") { 6114184Sgabeblack@google.com TBE lookup(Addr); 6214184Sgabeblack@google.com void allocate(Addr); 6314184Sgabeblack@google.com void deallocate(Addr); 6414184Sgabeblack@google.com bool isPresent(Addr); 6514184Sgabeblack@google.com } 6614184Sgabeblack@google.com 6714184Sgabeblack@google.com void set_tbe(TBE b); 6814184Sgabeblack@google.com void unset_tbe(); 6914184Sgabeblack@google.com void wakeUpAllBuffers(); 7014184Sgabeblack@google.com 7114184Sgabeblack@google.com TBETable TBEs, template="<DMA_TBE>", constructor="m_number_of_TBEs"; 7214184Sgabeblack@google.com 7314184Sgabeblack@google.com Tick clockEdge(); 7414184Sgabeblack@google.com MachineID mapAddressToMachine(Addr addr, MachineType mtype); 7514184Sgabeblack@google.com 7614184Sgabeblack@google.com State getState(TBE tbe, Addr addr) { 7714184Sgabeblack@google.com if (is_valid(tbe)) { 7814184Sgabeblack@google.com return tbe.TBEState; 7914184Sgabeblack@google.com } else { 8014184Sgabeblack@google.com return State:READY; 8114184Sgabeblack@google.com } 8214184Sgabeblack@google.com } 8314184Sgabeblack@google.com 8414184Sgabeblack@google.com void setState(TBE tbe, Addr addr, State state) { 8514184Sgabeblack@google.com if (is_valid(tbe)) { 8614184Sgabeblack@google.com tbe.TBEState := state; 8714184Sgabeblack@google.com } 8814184Sgabeblack@google.com } 8914184Sgabeblack@google.com 9014184Sgabeblack@google.com AccessPermission getAccessPermission(Addr addr) { 9114184Sgabeblack@google.com return AccessPermission:NotPresent; 9214184Sgabeblack@google.com } 9314184Sgabeblack@google.com 9414184Sgabeblack@google.com void setAccessPermission(Addr addr, State state) { 9514184Sgabeblack@google.com } 9614184Sgabeblack@google.com 9714184Sgabeblack@google.com void functionalRead(Addr addr, Packet *pkt) { 9814184Sgabeblack@google.com error("DMA does not support functional read."); 9914184Sgabeblack@google.com } 10014184Sgabeblack@google.com 10114184Sgabeblack@google.com int functionalWrite(Addr addr, Packet *pkt) { 10214184Sgabeblack@google.com error("DMA does not support functional write."); 10314184Sgabeblack@google.com } 10414184Sgabeblack@google.com 10514184Sgabeblack@google.com out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="..."); 10614184Sgabeblack@google.com 10714184Sgabeblack@google.com in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") { 10814184Sgabeblack@google.com if (dmaRequestQueue_in.isReady(clockEdge())) { 10914184Sgabeblack@google.com peek(dmaRequestQueue_in, SequencerMsg) { 11014184Sgabeblack@google.com if (in_msg.Type == SequencerRequestType:LD ) { 11114184Sgabeblack@google.com trigger(Event:ReadRequest, in_msg.LineAddress, TBEs[in_msg.LineAddress]); 11214184Sgabeblack@google.com } else if (in_msg.Type == SequencerRequestType:ST) { 11314184Sgabeblack@google.com trigger(Event:WriteRequest, in_msg.LineAddress, TBEs[in_msg.LineAddress]); 11414184Sgabeblack@google.com } else { 11514184Sgabeblack@google.com error("Invalid request type"); 11614184Sgabeblack@google.com } 11714184Sgabeblack@google.com } 11814184Sgabeblack@google.com } 11914184Sgabeblack@google.com } 12014184Sgabeblack@google.com 12114184Sgabeblack@google.com in_port(dmaResponseQueue_in, DMAResponseMsg, responseFromDir, desc="...") { 12214184Sgabeblack@google.com if (dmaResponseQueue_in.isReady(clockEdge())) { 12314184Sgabeblack@google.com peek( dmaResponseQueue_in, DMAResponseMsg) { 12414184Sgabeblack@google.com if (in_msg.Type == DMAResponseType:ACK) { 12514184Sgabeblack@google.com trigger(Event:Ack, in_msg.LineAddress, TBEs[in_msg.LineAddress]); 12614184Sgabeblack@google.com } else if (in_msg.Type == DMAResponseType:DATA) { 12714184Sgabeblack@google.com trigger(Event:Data, in_msg.LineAddress, TBEs[in_msg.LineAddress]); 12814184Sgabeblack@google.com } else { 12914184Sgabeblack@google.com error("Invalid response type"); 13014184Sgabeblack@google.com } 13114184Sgabeblack@google.com } 13214184Sgabeblack@google.com } 13314184Sgabeblack@google.com } 13414184Sgabeblack@google.com 13514184Sgabeblack@google.com action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") { 13614184Sgabeblack@google.com peek(dmaRequestQueue_in, SequencerMsg) { 13714184Sgabeblack@google.com enqueue(reqToDirectory_out, DMARequestMsg, request_latency) { 13814184Sgabeblack@google.com out_msg.PhysicalAddress := in_msg.PhysicalAddress; 13914184Sgabeblack@google.com out_msg.LineAddress := in_msg.LineAddress; 14014184Sgabeblack@google.com out_msg.Type := DMARequestType:READ; 14114184Sgabeblack@google.com out_msg.Requestor := machineID; 14214184Sgabeblack@google.com out_msg.DataBlk := in_msg.DataBlk; 14314184Sgabeblack@google.com out_msg.Len := in_msg.Len; 14414184Sgabeblack@google.com out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 14514184Sgabeblack@google.com out_msg.MessageSize := MessageSizeType:Writeback_Control; 14614184Sgabeblack@google.com } 14714184Sgabeblack@google.com } 14814184Sgabeblack@google.com } 14914184Sgabeblack@google.com 15014184Sgabeblack@google.com action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") { 15114184Sgabeblack@google.com peek(dmaRequestQueue_in, SequencerMsg) { 15214184Sgabeblack@google.com enqueue(reqToDirectory_out, DMARequestMsg, request_latency) { 15314184Sgabeblack@google.com out_msg.PhysicalAddress := in_msg.PhysicalAddress; 15414184Sgabeblack@google.com out_msg.LineAddress := in_msg.LineAddress; 15514184Sgabeblack@google.com out_msg.Type := DMARequestType:WRITE; 15614184Sgabeblack@google.com out_msg.Requestor := machineID; 15714184Sgabeblack@google.com out_msg.DataBlk := in_msg.DataBlk; 15814184Sgabeblack@google.com out_msg.Len := in_msg.Len; 15914184Sgabeblack@google.com out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 16014184Sgabeblack@google.com out_msg.MessageSize := MessageSizeType:Writeback_Control; 16114184Sgabeblack@google.com } 16214184Sgabeblack@google.com } 16314184Sgabeblack@google.com } 16414184Sgabeblack@google.com 16514184Sgabeblack@google.com action(a_ackCallback, "a", desc="Notify dma controller that write request completed") { 16614184Sgabeblack@google.com dma_sequencer.ackCallback(address); 16714184Sgabeblack@google.com } 16814184Sgabeblack@google.com 16914184Sgabeblack@google.com action(d_dataCallback, "d", desc="Write data to dma sequencer") { 17014184Sgabeblack@google.com dma_sequencer.dataCallback(tbe.DataBlk, address); 17114184Sgabeblack@google.com } 17214184Sgabeblack@google.com 17314184Sgabeblack@google.com action(t_updateTBEData, "t", desc="Update TBE Data") { 17414184Sgabeblack@google.com assert(is_valid(tbe)); 17514184Sgabeblack@google.com peek(dmaResponseQueue_in, DMAResponseMsg) { 17614184Sgabeblack@google.com tbe.DataBlk := in_msg.DataBlk; 17714184Sgabeblack@google.com } 17814184Sgabeblack@google.com } 17914184Sgabeblack@google.com 18014184Sgabeblack@google.com action(v_allocateTBE, "v", desc="Allocate TBE entry") { 18114184Sgabeblack@google.com TBEs.allocate(address); 18214184Sgabeblack@google.com set_tbe(TBEs[address]); 18314184Sgabeblack@google.com } 18414184Sgabeblack@google.com 18514184Sgabeblack@google.com action(w_deallocateTBE, "w", desc="Deallocate TBE entry") { 18614184Sgabeblack@google.com TBEs.deallocate(address); 18714184Sgabeblack@google.com unset_tbe(); 18814184Sgabeblack@google.com } 18914184Sgabeblack@google.com 19014184Sgabeblack@google.com action(p_popRequestQueue, "p", desc="Pop request queue") { 19114184Sgabeblack@google.com dmaRequestQueue_in.dequeue(clockEdge()); 19214184Sgabeblack@google.com } 19314184Sgabeblack@google.com 19414184Sgabeblack@google.com action(p_popResponseQueue, "\p", desc="Pop request queue") { 19514184Sgabeblack@google.com dmaResponseQueue_in.dequeue(clockEdge()); 19614184Sgabeblack@google.com } 19714184Sgabeblack@google.com 19814184Sgabeblack@google.com action(zz_stallAndWaitRequestQueue, "zz", desc="...") { 19914184Sgabeblack@google.com stall_and_wait(dmaRequestQueue_in, address); 20014184Sgabeblack@google.com } 20114184Sgabeblack@google.com 20214184Sgabeblack@google.com action(wkad_wakeUpAllDependents, "wkad", desc="wake-up all dependents") { 20314184Sgabeblack@google.com wakeUpAllBuffers(); 20414184Sgabeblack@google.com } 20514184Sgabeblack@google.com 20614184Sgabeblack@google.com transition(READY, ReadRequest, BUSY_RD) { 20714184Sgabeblack@google.com v_allocateTBE; 20814184Sgabeblack@google.com s_sendReadRequest; 20914184Sgabeblack@google.com p_popRequestQueue; 21014184Sgabeblack@google.com } 21114184Sgabeblack@google.com 21214184Sgabeblack@google.com transition(READY, WriteRequest, BUSY_WR) { 21314184Sgabeblack@google.com v_allocateTBE; 21414184Sgabeblack@google.com s_sendWriteRequest; 21514184Sgabeblack@google.com p_popRequestQueue; 21614184Sgabeblack@google.com } 21714184Sgabeblack@google.com 21814184Sgabeblack@google.com transition(BUSY_RD, Data, READY) { 21914184Sgabeblack@google.com t_updateTBEData; 22014184Sgabeblack@google.com d_dataCallback; 22114184Sgabeblack@google.com w_deallocateTBE; 22214184Sgabeblack@google.com p_popResponseQueue; 22314184Sgabeblack@google.com wkad_wakeUpAllDependents; 22414184Sgabeblack@google.com } 22514184Sgabeblack@google.com 22614184Sgabeblack@google.com transition(BUSY_WR, Ack, READY) { 22714184Sgabeblack@google.com a_ackCallback; 22814184Sgabeblack@google.com w_deallocateTBE; 22914184Sgabeblack@google.com p_popResponseQueue; 23014184Sgabeblack@google.com wkad_wakeUpAllDependents; 23114184Sgabeblack@google.com } 23214184Sgabeblack@google.com 23314184Sgabeblack@google.com transition({BUSY_RD,BUSY_WR}, {ReadRequest,WriteRequest}) { 23414184Sgabeblack@google.com zz_stallAndWaitRequestQueue; 23514184Sgabeblack@google.com } 23614184Sgabeblack@google.com} 237