merge
This commit is contained in:
commit
75c2baa81c
2 changed files with 214 additions and 0 deletions
139
src/mem/protocol/MESI_CMP_directory-dma.sm
Normal file
139
src/mem/protocol/MESI_CMP_directory-dma.sm
Normal file
|
@ -0,0 +1,139 @@
|
|||
|
||||
machine(DMA, "DMA Controller")
|
||||
: int request_latency
|
||||
{
|
||||
|
||||
MessageBuffer responseFromDir, network="From", virtual_network="6", ordered="true", no_vector="true";
|
||||
MessageBuffer reqToDirectory, network="To", virtual_network="7", ordered="false", no_vector="true";
|
||||
|
||||
enumeration(State, desc="DMA states", default="DMA_State_READY") {
|
||||
READY, desc="Ready to accept a new request";
|
||||
BUSY_RD, desc="Busy: currently processing a request";
|
||||
BUSY_WR, desc="Busy: currently processing a request";
|
||||
}
|
||||
|
||||
enumeration(Event, desc="DMA events") {
|
||||
ReadRequest, desc="A new read request";
|
||||
WriteRequest, desc="A new write request";
|
||||
Data, desc="Data from a DMA memory read";
|
||||
Ack, desc="DMA write to memory completed";
|
||||
}
|
||||
|
||||
external_type(DMASequencer) {
|
||||
void ackCallback();
|
||||
void dataCallback(DataBlock);
|
||||
}
|
||||
|
||||
MessageBuffer mandatoryQueue, ordered="false", no_vector="true";
|
||||
DMASequencer dma_sequencer, factory='RubySystem::getDMASequencer(m_cfg["dma_sequencer"])', no_vector="true";
|
||||
State cur_state, no_vector="true";
|
||||
|
||||
State getState(Address addr) {
|
||||
return cur_state;
|
||||
}
|
||||
void setState(Address addr, State state) {
|
||||
cur_state := state;
|
||||
}
|
||||
|
||||
out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="...");
|
||||
|
||||
in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") {
|
||||
if (dmaRequestQueue_in.isReady()) {
|
||||
peek(dmaRequestQueue_in, SequencerMsg) {
|
||||
if (in_msg.Type == SequencerRequestType:LD ) {
|
||||
trigger(Event:ReadRequest, in_msg.LineAddress);
|
||||
} else if (in_msg.Type == SequencerRequestType:ST) {
|
||||
trigger(Event:WriteRequest, in_msg.LineAddress);
|
||||
} else {
|
||||
error("Invalid request type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
in_port(dmaResponseQueue_in, DMAResponseMsg, responseFromDir, desc="...") {
|
||||
if (dmaResponseQueue_in.isReady()) {
|
||||
peek( dmaResponseQueue_in, DMAResponseMsg) {
|
||||
if (in_msg.Type == DMAResponseType:ACK) {
|
||||
trigger(Event:Ack, in_msg.LineAddress);
|
||||
} else if (in_msg.Type == DMAResponseType:DATA) {
|
||||
trigger(Event:Data, in_msg.LineAddress);
|
||||
} else {
|
||||
error("Invalid response type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") {
|
||||
peek(dmaRequestQueue_in, SequencerMsg) {
|
||||
enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) {
|
||||
out_msg.PhysicalAddress := in_msg.PhysicalAddress;
|
||||
out_msg.LineAddress := in_msg.LineAddress;
|
||||
out_msg.Type := DMARequestType:READ;
|
||||
out_msg.DataBlk := in_msg.DataBlk;
|
||||
out_msg.Len := in_msg.Len;
|
||||
out_msg.Destination.add(map_Address_to_Directory(address));
|
||||
out_msg.MessageSize := MessageSizeType:Writeback_Control;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") {
|
||||
peek(dmaRequestQueue_in, SequencerMsg) {
|
||||
enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) {
|
||||
out_msg.PhysicalAddress := in_msg.PhysicalAddress;
|
||||
out_msg.LineAddress := in_msg.LineAddress;
|
||||
out_msg.Type := DMARequestType:WRITE;
|
||||
out_msg.DataBlk := in_msg.DataBlk;
|
||||
out_msg.Len := in_msg.Len;
|
||||
out_msg.Destination.add(map_Address_to_Directory(address));
|
||||
out_msg.MessageSize := MessageSizeType:Writeback_Control;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
action(a_ackCallback, "a", desc="Notify dma controller that write request completed") {
|
||||
peek (dmaResponseQueue_in, DMAResponseMsg) {
|
||||
dma_sequencer.ackCallback();
|
||||
}
|
||||
}
|
||||
|
||||
action(d_dataCallback, "d", desc="Write data to dma sequencer") {
|
||||
peek (dmaResponseQueue_in, DMAResponseMsg) {
|
||||
dma_sequencer.dataCallback(in_msg.DataBlk);
|
||||
}
|
||||
}
|
||||
|
||||
action(p_popRequestQueue, "p", desc="Pop request queue") {
|
||||
dmaRequestQueue_in.dequeue();
|
||||
}
|
||||
|
||||
action(p_popResponseQueue, "\p", desc="Pop request queue") {
|
||||
dmaResponseQueue_in.dequeue();
|
||||
}
|
||||
|
||||
action(z_stall, "z", desc="dma is busy..stall") {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
transition(READY, ReadRequest, BUSY_RD) {
|
||||
s_sendReadRequest;
|
||||
p_popRequestQueue;
|
||||
}
|
||||
|
||||
transition(READY, WriteRequest, BUSY_WR) {
|
||||
s_sendWriteRequest;
|
||||
p_popRequestQueue;
|
||||
}
|
||||
|
||||
transition(BUSY_RD, Data, READY) {
|
||||
d_dataCallback;
|
||||
p_popResponseQueue;
|
||||
}
|
||||
|
||||
transition(BUSY_WR, Ack, READY) {
|
||||
a_ackCallback;
|
||||
p_popResponseQueue;
|
||||
}
|
||||
}
|
75
src/mem/ruby/config/MESI_CMP_directory.rb
Normal file
75
src/mem/ruby/config/MESI_CMP_directory.rb
Normal file
|
@ -0,0 +1,75 @@
|
|||
require "cfg.rb"
|
||||
require "util.rb"
|
||||
|
||||
|
||||
class MESI_CMP_directory_L2CacheController < CacheController
|
||||
attr :cache
|
||||
|
||||
def initialize(obj_name, mach_type, cache)
|
||||
super(obj_name, mach_type, [cache])
|
||||
@cache = cache
|
||||
end
|
||||
def argv()
|
||||
vec = super()
|
||||
vec += " cache " + cache.obj_name
|
||||
vec += " l2_request_latency "+l2_request_latency.to_s
|
||||
vec += " l2_response_latency "+l2_response_latency.to_s
|
||||
vec += " to_l1_latency "+to_L1_latency.to_s
|
||||
return vec
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class MESI_CMP_directory_L1CacheController < L1CacheController
|
||||
attr :icache, :dcache
|
||||
attr :num_l2_controllers
|
||||
|
||||
def initialize(obj_name, mach_type, icache, dcache, sequencer, num_l2_controllers)
|
||||
super(obj_name, mach_type, [icache, dcache], sequencer)
|
||||
@icache = icache
|
||||
@dcache = dcache
|
||||
@num_l2_controllers = num_l2_controllers
|
||||
end
|
||||
|
||||
def argv()
|
||||
num_select_bits = log_int(num_l2_controllers)
|
||||
num_block_bits = log_int(RubySystem.block_size_bytes)
|
||||
l2_select_low_bit = num_block_bits
|
||||
|
||||
vec = super()
|
||||
vec += " icache " + @icache.obj_name
|
||||
vec += " dcache " + @dcache.obj_name
|
||||
vec += " l1_request_latency "+l1_request_latency.to_s
|
||||
vec += " l1_response_latency "+l1_response_latency.to_s
|
||||
vec += " to_l2_latency "+to_L2_latency.to_s
|
||||
vec += " l2_select_low_bit " + l2_select_low_bit.to_s
|
||||
vec += " l2_select_num_bits " + num_select_bits.to_s
|
||||
return vec
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class MESI_CMP_directory_DMAController < DMAController
|
||||
def initialize(obj_name, mach_type, dma_sequencer)
|
||||
super(obj_name, mach_type, dma_sequencer)
|
||||
end
|
||||
def argv()
|
||||
vec = super
|
||||
vec += " request_latency "+request_latency.to_s
|
||||
return vec
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class MESI_CMP_directory_DirectoryController < DirectoryController
|
||||
def initialize(obj_name, mach_type, directory, memory_control)
|
||||
super(obj_name, mach_type, directory, memory_control)
|
||||
end
|
||||
def argv()
|
||||
vec = super()
|
||||
vec += " to_mem_ctrl_latency "+to_mem_ctrl_latency.to_s
|
||||
vec += " directory_latency "+directory_latency.to_s
|
||||
end
|
||||
|
||||
end
|
||||
require "defaults.rb"
|
Loading…
Reference in a new issue