MOESI_hammer-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 MessageBuffer * responseFromDir, network="From", virtual_network="1", 3514184Sgabeblack@google.com vnet_type="response"; 3614184Sgabeblack@google.com MessageBuffer * requestToDir, network="To", virtual_network="0", 3714184Sgabeblack@google.com vnet_type="request"; 3814184Sgabeblack@google.com MessageBuffer * mandatoryQueue; 3914184Sgabeblack@google.com{ 4014184Sgabeblack@google.com state_declaration(State, desc="DMA states", default="DMA_State_READY") { 4114184Sgabeblack@google.com READY, AccessPermission:Invalid, desc="Ready to accept a new request"; 4214184Sgabeblack@google.com BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request"; 4314184Sgabeblack@google.com BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request"; 4414184Sgabeblack@google.com } 4514184Sgabeblack@google.com 4614184Sgabeblack@google.com enumeration(Event, desc="DMA events") { 4714184Sgabeblack@google.com ReadRequest, desc="A new read request"; 4814184Sgabeblack@google.com WriteRequest, desc="A new write request"; 4914184Sgabeblack@google.com Data, desc="Data from a DMA memory read"; 5014184Sgabeblack@google.com Ack, desc="DMA write to memory completed"; 5114184Sgabeblack@google.com } 5214184Sgabeblack@google.com 5314184Sgabeblack@google.com structure(TBE, desc="...") { 5414184Sgabeblack@google.com State TBEState, desc="Transient state"; 5514184Sgabeblack@google.com DataBlock DataBlk, desc="Data"; 5614184Sgabeblack@google.com } 5714184Sgabeblack@google.com 5814184Sgabeblack@google.com structure(TBETable, external = "yes") { 5914184Sgabeblack@google.com TBE lookup(Addr); 6014184Sgabeblack@google.com void allocate(Addr); 6114184Sgabeblack@google.com void deallocate(Addr); 6214184Sgabeblack@google.com bool isPresent(Addr); 6314184Sgabeblack@google.com } 6414184Sgabeblack@google.com 6514184Sgabeblack@google.com void set_tbe(TBE b); 6614184Sgabeblack@google.com void unset_tbe(); 6714184Sgabeblack@google.com void wakeUpAllBuffers(); 6814184Sgabeblack@google.com 6914184Sgabeblack@google.com TBETable TBEs, template="<DMA_TBE>", constructor="m_number_of_TBEs"; 7014184Sgabeblack@google.com 7114184Sgabeblack@google.com Tick clockEdge(); 7214184Sgabeblack@google.com MachineID mapAddressToMachine(Addr addr, MachineType mtype); 7314184Sgabeblack@google.com 7414184Sgabeblack@google.com State getState(TBE tbe, Addr addr) { 7514184Sgabeblack@google.com if (is_valid(tbe)) { 7614184Sgabeblack@google.com return tbe.TBEState; 7714184Sgabeblack@google.com } else { 7814184Sgabeblack@google.com return State:READY; 7914184Sgabeblack@google.com } 8014184Sgabeblack@google.com } 8114184Sgabeblack@google.com 8214184Sgabeblack@google.com void setState(TBE tbe, Addr addr, State state) { 8314184Sgabeblack@google.com if (is_valid(tbe)) { 8414184Sgabeblack@google.com tbe.TBEState := state; 8514184Sgabeblack@google.com } 8614184Sgabeblack@google.com } 8714184Sgabeblack@google.com 8814184Sgabeblack@google.com AccessPermission getAccessPermission(Addr addr) { 8914184Sgabeblack@google.com return AccessPermission:NotPresent; 9014184Sgabeblack@google.com } 9114184Sgabeblack@google.com 9214184Sgabeblack@google.com void setAccessPermission(Addr addr, State state) { 9314184Sgabeblack@google.com } 9414184Sgabeblack@google.com 9514184Sgabeblack@google.com void functionalRead(Addr addr, Packet *pkt) { 9614184Sgabeblack@google.com error("DMA does not support functional read."); 9714184Sgabeblack@google.com } 9814184Sgabeblack@google.com 9914184Sgabeblack@google.com int functionalWrite(Addr addr, Packet *pkt) { 10014184Sgabeblack@google.com error("DMA does not support functional write."); 10114184Sgabeblack@google.com } 10214184Sgabeblack@google.com 10314184Sgabeblack@google.com out_port(requestToDir_out, DMARequestMsg, requestToDir, desc="..."); 10414184Sgabeblack@google.com 10514184Sgabeblack@google.com in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") { 10614184Sgabeblack@google.com if (dmaRequestQueue_in.isReady(clockEdge())) { 10714184Sgabeblack@google.com peek(dmaRequestQueue_in, SequencerMsg) { 10814184Sgabeblack@google.com if (in_msg.Type == SequencerRequestType:LD ) { 10914184Sgabeblack@google.com trigger(Event:ReadRequest, in_msg.LineAddress, TBEs[in_msg.LineAddress]); 11014184Sgabeblack@google.com } else if (in_msg.Type == SequencerRequestType:ST) { 11114184Sgabeblack@google.com trigger(Event:WriteRequest, in_msg.LineAddress, TBEs[in_msg.LineAddress]); 11214184Sgabeblack@google.com } else { 11314184Sgabeblack@google.com error("Invalid request type"); 11414184Sgabeblack@google.com } 11514184Sgabeblack@google.com } 11614184Sgabeblack@google.com } 11714184Sgabeblack@google.com } 11814184Sgabeblack@google.com 11914184Sgabeblack@google.com in_port(dmaResponseQueue_in, DMAResponseMsg, responseFromDir, desc="...") { 12014184Sgabeblack@google.com if (dmaResponseQueue_in.isReady(clockEdge())) { 12114184Sgabeblack@google.com peek( dmaResponseQueue_in, DMAResponseMsg) { 12214184Sgabeblack@google.com if (in_msg.Type == DMAResponseType:ACK) { 12314184Sgabeblack@google.com trigger(Event:Ack, in_msg.LineAddress, TBEs[in_msg.LineAddress]); 12414184Sgabeblack@google.com } else if (in_msg.Type == DMAResponseType:DATA) { 12514184Sgabeblack@google.com trigger(Event:Data, in_msg.LineAddress, TBEs[in_msg.LineAddress]); 12614184Sgabeblack@google.com } else { 12714184Sgabeblack@google.com error("Invalid response type"); 12814184Sgabeblack@google.com } 12914184Sgabeblack@google.com } 13014184Sgabeblack@google.com } 13114184Sgabeblack@google.com } 13214184Sgabeblack@google.com 13314184Sgabeblack@google.com action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") { 13414184Sgabeblack@google.com peek(dmaRequestQueue_in, SequencerMsg) { 13514184Sgabeblack@google.com enqueue(requestToDir_out, DMARequestMsg, request_latency) { 13614184Sgabeblack@google.com out_msg.PhysicalAddress := in_msg.PhysicalAddress; 13714184Sgabeblack@google.com out_msg.LineAddress := in_msg.LineAddress; 13814184Sgabeblack@google.com out_msg.Type := DMARequestType:READ; 13914184Sgabeblack@google.com out_msg.Requestor := machineID; 14014184Sgabeblack@google.com out_msg.DataBlk := in_msg.DataBlk; 14114184Sgabeblack@google.com out_msg.Len := in_msg.Len; 14214184Sgabeblack@google.com out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 14314184Sgabeblack@google.com out_msg.MessageSize := MessageSizeType:Writeback_Control; 14414184Sgabeblack@google.com } 14514184Sgabeblack@google.com } 14614184Sgabeblack@google.com } 14714184Sgabeblack@google.com 14814184Sgabeblack@google.com action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") { 14914184Sgabeblack@google.com peek(dmaRequestQueue_in, SequencerMsg) { 15014184Sgabeblack@google.com enqueue(requestToDir_out, DMARequestMsg, request_latency) { 15114184Sgabeblack@google.com out_msg.PhysicalAddress := in_msg.PhysicalAddress; 15214184Sgabeblack@google.com out_msg.LineAddress := in_msg.LineAddress; 15314184Sgabeblack@google.com out_msg.Type := DMARequestType:WRITE; 15414184Sgabeblack@google.com out_msg.Requestor := machineID; 15514184Sgabeblack@google.com out_msg.DataBlk := in_msg.DataBlk; 15614184Sgabeblack@google.com out_msg.Len := in_msg.Len; 15714184Sgabeblack@google.com out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 15814184Sgabeblack@google.com out_msg.MessageSize := MessageSizeType:Writeback_Control; 15914184Sgabeblack@google.com } 16014184Sgabeblack@google.com } 16114184Sgabeblack@google.com } 16214184Sgabeblack@google.com 16314184Sgabeblack@google.com action(a_ackCallback, "a", desc="Notify dma controller that write request completed") { 16414184Sgabeblack@google.com dma_sequencer.ackCallback(address); 16514184Sgabeblack@google.com } 16614184Sgabeblack@google.com 16714184Sgabeblack@google.com action(d_dataCallback, "d", desc="Write data to dma sequencer") { 16814184Sgabeblack@google.com dma_sequencer.dataCallback(tbe.DataBlk, address); 16914184Sgabeblack@google.com } 17014184Sgabeblack@google.com 17114184Sgabeblack@google.com action(t_updateTBEData, "t", desc="Update TBE Data") { 17214184Sgabeblack@google.com assert(is_valid(tbe)); 17314184Sgabeblack@google.com peek( dmaResponseQueue_in, DMAResponseMsg) { 17414184Sgabeblack@google.com tbe.DataBlk := in_msg.DataBlk; 17514184Sgabeblack@google.com } 17614184Sgabeblack@google.com } 17714184Sgabeblack@google.com 17814184Sgabeblack@google.com action(v_allocateTBE, "v", desc="Allocate TBE entry") { 17914184Sgabeblack@google.com TBEs.allocate(address); 18014184Sgabeblack@google.com set_tbe(TBEs[address]); 18114184Sgabeblack@google.com } 18214184Sgabeblack@google.com 18314184Sgabeblack@google.com action(w_deallocateTBE, "w", desc="Deallocate TBE entry") { 18414184Sgabeblack@google.com TBEs.deallocate(address); 18514184Sgabeblack@google.com unset_tbe(); 18614184Sgabeblack@google.com } 18714184Sgabeblack@google.com 18814184Sgabeblack@google.com action(p_popRequestQueue, "p", desc="Pop request queue") { 18914184Sgabeblack@google.com dmaRequestQueue_in.dequeue(clockEdge()); 19014184Sgabeblack@google.com } 19114184Sgabeblack@google.com 19214184Sgabeblack@google.com action(p_popResponseQueue, "\p", desc="Pop request queue") { 19314184Sgabeblack@google.com dmaResponseQueue_in.dequeue(clockEdge()); 19414184Sgabeblack@google.com } 19514184Sgabeblack@google.com 19614184Sgabeblack@google.com action(zz_stallAndWaitRequestQueue, "zz", desc="...") { 19714184Sgabeblack@google.com stall_and_wait(dmaRequestQueue_in, address); 19814184Sgabeblack@google.com } 19914184Sgabeblack@google.com 20014184Sgabeblack@google.com action(wkad_wakeUpAllDependents, "wkad", desc="wake-up all dependents") { 20114184Sgabeblack@google.com wakeUpAllBuffers(); 20214184Sgabeblack@google.com } 20314184Sgabeblack@google.com 20414184Sgabeblack@google.com transition(READY, ReadRequest, BUSY_RD) { 20514184Sgabeblack@google.com v_allocateTBE; 20614184Sgabeblack@google.com s_sendReadRequest; 20714184Sgabeblack@google.com p_popRequestQueue; 20814184Sgabeblack@google.com } 20914184Sgabeblack@google.com 21014184Sgabeblack@google.com transition(READY, WriteRequest, BUSY_WR) { 21114184Sgabeblack@google.com v_allocateTBE; 21214184Sgabeblack@google.com s_sendWriteRequest; 21314184Sgabeblack@google.com p_popRequestQueue; 21414184Sgabeblack@google.com } 21514184Sgabeblack@google.com 21614184Sgabeblack@google.com transition(BUSY_RD, Data, READY) { 21714184Sgabeblack@google.com t_updateTBEData; 21814184Sgabeblack@google.com d_dataCallback; 21914184Sgabeblack@google.com w_deallocateTBE; 22014184Sgabeblack@google.com p_popResponseQueue; 22114184Sgabeblack@google.com wkad_wakeUpAllDependents; 22214184Sgabeblack@google.com } 22314184Sgabeblack@google.com 22414184Sgabeblack@google.com transition(BUSY_WR, Ack, READY) { 22514184Sgabeblack@google.com a_ackCallback; 22614184Sgabeblack@google.com w_deallocateTBE; 22714184Sgabeblack@google.com p_popResponseQueue; 22814184Sgabeblack@google.com wkad_wakeUpAllDependents; 22914184Sgabeblack@google.com } 23014184Sgabeblack@google.com 23114184Sgabeblack@google.com transition({BUSY_RD,BUSY_WR}, {ReadRequest,WriteRequest}) { 23214184Sgabeblack@google.com zz_stallAndWaitRequestQueue; 23314184Sgabeblack@google.com } 23414184Sgabeblack@google.com 23514184Sgabeblack@google.com} 236