diff options
Diffstat (limited to 'src/mem/protocol/MESI_CMP_directory-mem.sm')
-rw-r--r-- | src/mem/protocol/MESI_CMP_directory-mem.sm | 242 |
1 files changed, 226 insertions, 16 deletions
diff --git a/src/mem/protocol/MESI_CMP_directory-mem.sm b/src/mem/protocol/MESI_CMP_directory-mem.sm index 1fcd234fe..84768c333 100644 --- a/src/mem/protocol/MESI_CMP_directory-mem.sm +++ b/src/mem/protocol/MESI_CMP_directory-mem.sm @@ -31,23 +31,39 @@ * $Id: MOESI_CMP_token-dir.sm 1.6 05/01/19 15:48:35-06:00 mikem@royal16.cs.wisc.edu $ */ +// This file is copied from Yasuko Watanabe's prefetch / memory protocol +// Copied here by aep 12/14/07 -machine(Directory, "Token protocol") { + +machine(Directory, "MESI_CMP_filter_directory protocol") : LATENCY_MEMORY_LATENCY LATENCY_TO_MEM_CTRL_LATENCY { MessageBuffer requestToDir, network="From", virtual_network="2", ordered="false"; MessageBuffer responseToDir, network="From", virtual_network="3", ordered="false"; MessageBuffer responseFromDir, network="To", virtual_network="3", ordered="false"; + MessageBuffer dmaRequestFromDir, network="To", virtual_network="4", ordered="true", no_vector="true"; + MessageBuffer dmaRequestToDir, network="From", virtual_network="5", ordered="true", no_vector="true"; + + // STATES enumeration(State, desc="Directory states", default="Directory_State_I") { // Base states I, desc="Owner"; + ID, desc="Intermediate state for DMA_READ when in I"; + ID_W, desc="Intermediate state for DMA_WRITE when in I"; } // Events enumeration(Event, desc="Directory events") { - Fetch, desc="A GETX arrives"; - Data, desc="A GETS arrives"; + Fetch, desc="A memory fetch arrives"; + Data, desc="writeback data arrives"; + Memory_Data, desc="Fetched data from memory arrives"; + Memory_Ack, desc="Writeback Ack from memory arrives"; +//added by SS for dma + DMA_READ, desc="A DMA Read memory request"; + DMA_WRITE, desc="A DMA Write memory request"; + + } // TYPES @@ -62,10 +78,21 @@ machine(Directory, "Token protocol") { bool isPresent(Address); } + // to simulate detailed DRAM + external_type(MemoryControl, inport="yes", outport="yes") { + + } + // ** OBJECTS ** - DirectoryMemory directory, constructor_hack="i"; +// DirectoryMemory directory, constructor_hack="i"; +// MemoryControl memBuffer, constructor_hack="i"; + + DirectoryMemory directory, factory='RubySystem::getDirectory(m_cfg["directory_name"])'; + + MemoryControl memBuffer, factory='RubySystem::getMemoryControl(m_cfg["memory_controller_name"])'; + State getState(Address addr) { return State:I; @@ -74,20 +101,44 @@ machine(Directory, "Token protocol") { void setState(Address addr, State state) { } + bool isGETRequest(CoherenceRequestType type) { + return (type == CoherenceRequestType:GETS) || + (type == CoherenceRequestType:GET_INSTR) || + (type == CoherenceRequestType:GETX); + } + + // ** OUT_PORTS ** out_port(responseNetwork_out, ResponseMsg, responseFromDir); + out_port(memQueue_out, MemoryMsg, memBuffer); + out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaRequestFromDir); // ** IN_PORTS ** +//added by SS for dma + in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) { + if (dmaRequestQueue_in.isReady()) { + peek(dmaRequestQueue_in, DMARequestMsg) { + if (in_msg.Type == DMARequestType:READ) { + trigger(Event:DMA_READ, in_msg.PhysicalAddress); + } else if (in_msg.Type == DMARequestType:WRITE) { + trigger(Event:DMA_WRITE, in_msg.PhysicalAddress); + } else { + error("Invalid message"); + } + } + } + } + + in_port(requestNetwork_in, RequestMsg, requestToDir) { if (requestNetwork_in.isReady()) { peek(requestNetwork_in, RequestMsg) { assert(in_msg.Destination.isElement(machineID)); - if (in_msg.Type == CoherenceRequestType:GETS) { - trigger(Event:Fetch, in_msg.Address); - } else if (in_msg.Type == CoherenceRequestType:GETX) { + if (isGETRequest(in_msg.Type)) { trigger(Event:Fetch, in_msg.Address); } else { + DEBUG_EXPR(in_msg); error("Invalid message"); } } @@ -108,27 +159,45 @@ machine(Directory, "Token protocol") { } } + // off-chip memory request/response is done + in_port(memQueue_in, MemoryMsg, memBuffer) { + if (memQueue_in.isReady()) { + peek(memQueue_in, MemoryMsg) { + if (in_msg.Type == MemoryRequestType:MEMORY_READ) { + trigger(Event:Memory_Data, in_msg.Address); + } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) { + trigger(Event:Memory_Ack, in_msg.Address); + } else { + DEBUG_EXPR(in_msg.Type); + error("Invalid message"); + } + } + } + } + + + // Actions action(a_sendAck, "a", desc="Send ack to L2") { - peek(responseNetwork_in, ResponseMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") { + peek(memQueue_in, MemoryMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="TO_MEM_CTRL_LATENCY") { out_msg.Address := address; out_msg.Type := CoherenceResponseType:MEMORY_ACK; out_msg.Sender := machineID; - out_msg.Destination.add(in_msg.Sender); + out_msg.Destination.add(in_msg.OriginalRequestorMachId); out_msg.MessageSize := MessageSizeType:Response_Control; } } } action(d_sendData, "d", desc="Send data to requestor") { - peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") { + peek(memQueue_in, MemoryMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="TO_MEM_CTRL_LATENCY") { out_msg.Address := address; out_msg.Type := CoherenceResponseType:MEMORY_DATA; out_msg.Sender := machineID; - out_msg.Destination.add(in_msg.Requestor); - out_msg.DataBlk := directory[in_msg.Address].DataBlk; + out_msg.Destination.add(in_msg.OriginalRequestorMachId); + out_msg.DataBlk := in_msg.DataBlk; out_msg.Dirty := false; out_msg.MessageSize := MessageSizeType:Response_Data; } @@ -143,6 +212,42 @@ machine(Directory, "Token protocol") { responseNetwork_in.dequeue(); } + action(l_popMemQueue, "q", desc="Pop off-chip request queue") { + memQueue_in.dequeue(); + } + + action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { + peek(requestNetwork_in, RequestMsg) { + enqueue(memQueue_out, MemoryMsg, latency="TO_MEM_CTRL_LATENCY") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.OriginalRequestorMachId := in_msg.Requestor; + out_msg.MessageSize := in_msg.MessageSize; + out_msg.Prefetch := in_msg.Prefetch; + out_msg.DataBlk := directory[in_msg.Address].DataBlk; + + DEBUG_EXPR(out_msg); + } + } + } + + action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") { + peek(responseNetwork_in, ResponseMsg) { + enqueue(memQueue_out, MemoryMsg, latency="TO_MEM_CTRL_LATENCY") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.Sender := machineID; + out_msg.OriginalRequestorMachId := in_msg.Sender; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.MessageSize := in_msg.MessageSize; + //out_msg.Prefetch := in_msg.Prefetch; + + DEBUG_EXPR(out_msg); + } + } + } + action(m_writeDataToMemory, "m", desc="Write dirty writeback to memory") { peek(responseNetwork_in, ResponseMsg) { directory[in_msg.Address].DataBlk := in_msg.DataBlk; @@ -150,17 +255,122 @@ machine(Directory, "Token protocol") { DEBUG_EXPR(in_msg.DataBlk); } } +//added by SS for dma + action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(memQueue_out, MemoryMsg, latency="TO_MEM_CTRL_LATENCY") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.OriginalRequestorMachId := machineID; + out_msg.MessageSize := in_msg.MessageSize; + out_msg.DataBlk := directory[address].DataBlk; + DEBUG_EXPR(out_msg); + } + } + } + + action(p_popIncomingDMARequestQueue, "p", desc="Pop incoming DMA queue") { + dmaRequestQueue_in.dequeue(); + } + + action(dr_sendDMAData, "dr", desc="Send Data to DMA controller from directory") { + peek(memQueue_in, MemoryMsg) { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="MEMORY_LATENCY") { + out_msg.PhysicalAddress := address; + out_msg.Type := DMAResponseType:DATA; + out_msg.DataBlk := in_msg.DataBlk; // we send the entire data block and rely on the dma controller to split it up if need be + out_msg.Destination.add(map_Address_to_DMA(address)); + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(dw_writeDMAData, "dw", desc="DMA Write data to memory") { + peek(dmaRequestQueue_in, DMARequestMsg) { + directory[in_msg.PhysicalAddress].DataBlk.copyPartial(in_msg.DataBlk, in_msg.Offset, in_msg.Len); + } + } + + action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(memQueue_out, MemoryMsg, latency="TO_MEM_CTRL_LATENCY") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.OriginalRequestorMachId := machineID; + //out_msg.DataBlk := in_msg.DataBlk; + out_msg.DataBlk.copyPartial(in_msg.DataBlk, in_msg.Offset, in_msg.Len); + out_msg.MessageSize := in_msg.MessageSize; + //out_msg.Prefetch := in_msg.Prefetch; + + DEBUG_EXPR(out_msg); + } + } + } + + action(da_sendDMAAck, "da", desc="Send Ack to DMA controller") { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="MEMORY_LATENCY") { + out_msg.PhysicalAddress := address; + out_msg.Type := DMAResponseType:ACK; + out_msg.Destination.add(map_Address_to_DMA(address)); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + + action(z_recycleRequestQueue, "z", desc="recycle request queue") { + requestNetwork_in.dequeue(); + } // TRANSITIONS transition(I, Fetch) { - d_sendData; + //d_sendData; + qf_queueMemoryFetchRequest; j_popIncomingRequestQueue; } transition(I, Data) { m_writeDataToMemory; - a_sendAck; + //a_sendAck; + qw_queueMemoryWBRequest; k_popIncomingResponseQueue; } + + transition(I, Memory_Data) { + d_sendData; + l_popMemQueue; + } + + transition(I, Memory_Ack) { + a_sendAck; + l_popMemQueue; + } + +//added by SS for dma support + transition(I, DMA_READ, ID) { + qf_queueMemoryFetchRequestDMA; + p_popIncomingDMARequestQueue; + } + + transition(ID, Memory_Data, I) { + dr_sendDMAData; + l_popMemQueue; + } + + transition(I, DMA_WRITE, ID_W) { + dw_writeDMAData; + qw_queueMemoryWBRequest_partial; + p_popIncomingDMARequestQueue; + } + + transition(ID_W, Memory_Ack, I) { + da_sendDMAAck; + l_popMemQueue; + } + + transition({ID, ID_W}, {Fetch, Data} ) { + z_recycleRequestQueue; + } + + } |