ruby: cleaning up RubyQueue and RubyNetwork dprintfs
[gem5.git] / src / mem / protocol / MI_example-dma.sm
1
2 machine(DMA, "DMA Controller")
3 : DMASequencer * dma_sequencer,
4 int request_latency = 6
5 {
6
7 MessageBuffer responseFromDir, network="From", virtual_network="1", ordered="true", no_vector="true";
8 MessageBuffer reqToDirectory, network="To", virtual_network="0", ordered="false", no_vector="true";
9
10 enumeration(State, desc="DMA states", default="DMA_State_READY") {
11 READY, desc="Ready to accept a new request";
12 BUSY_RD, desc="Busy: currently processing a request";
13 BUSY_WR, desc="Busy: currently processing a request";
14 }
15
16 enumeration(Event, desc="DMA events") {
17 ReadRequest, desc="A new read request";
18 WriteRequest, desc="A new write request";
19 Data, desc="Data from a DMA memory read";
20 Ack, desc="DMA write to memory completed";
21 }
22
23 MessageBuffer mandatoryQueue, ordered="false", no_vector="true";
24 State cur_state, no_vector="true";
25
26 State getState(Address addr) {
27 return cur_state;
28 }
29 void setState(Address addr, State state) {
30 cur_state := state;
31 }
32
33 out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="...");
34
35 in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") {
36 if (dmaRequestQueue_in.isReady()) {
37 peek(dmaRequestQueue_in, SequencerMsg) {
38 if (in_msg.Type == SequencerRequestType:LD ) {
39 trigger(Event:ReadRequest, in_msg.LineAddress);
40 } else if (in_msg.Type == SequencerRequestType:ST) {
41 trigger(Event:WriteRequest, in_msg.LineAddress);
42 } else {
43 error("Invalid request type");
44 }
45 }
46 }
47 }
48
49 in_port(dmaResponseQueue_in, DMAResponseMsg, responseFromDir, desc="...") {
50 if (dmaResponseQueue_in.isReady()) {
51 peek( dmaResponseQueue_in, DMAResponseMsg) {
52 if (in_msg.Type == DMAResponseType:ACK) {
53 trigger(Event:Ack, in_msg.LineAddress);
54 } else if (in_msg.Type == DMAResponseType:DATA) {
55 trigger(Event:Data, in_msg.LineAddress);
56 } else {
57 error("Invalid response type");
58 }
59 }
60 }
61 }
62
63 action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") {
64 peek(dmaRequestQueue_in, SequencerMsg) {
65 enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) {
66 out_msg.PhysicalAddress := in_msg.PhysicalAddress;
67 out_msg.LineAddress := in_msg.LineAddress;
68 out_msg.Type := DMARequestType:READ;
69 out_msg.Requestor := machineID;
70 out_msg.DataBlk := in_msg.DataBlk;
71 out_msg.Len := in_msg.Len;
72 out_msg.Destination.add(map_Address_to_Directory(address));
73 out_msg.MessageSize := MessageSizeType:Writeback_Control;
74 }
75 }
76 }
77
78 action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") {
79 peek(dmaRequestQueue_in, SequencerMsg) {
80 enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) {
81 out_msg.PhysicalAddress := in_msg.PhysicalAddress;
82 out_msg.LineAddress := in_msg.LineAddress;
83 out_msg.Type := DMARequestType:WRITE;
84 out_msg.Requestor := machineID;
85 out_msg.DataBlk := in_msg.DataBlk;
86 out_msg.Len := in_msg.Len;
87 out_msg.Destination.add(map_Address_to_Directory(address));
88 out_msg.MessageSize := MessageSizeType:Writeback_Control;
89 }
90 }
91 }
92
93 action(a_ackCallback, "a", desc="Notify dma controller that write request completed") {
94 peek (dmaResponseQueue_in, DMAResponseMsg) {
95 dma_sequencer.ackCallback();
96 }
97 }
98
99 action(d_dataCallback, "d", desc="Write data to dma sequencer") {
100 peek (dmaResponseQueue_in, DMAResponseMsg) {
101 dma_sequencer.dataCallback(in_msg.DataBlk);
102 }
103 }
104
105 action(p_popRequestQueue, "p", desc="Pop request queue") {
106 dmaRequestQueue_in.dequeue();
107 }
108
109 action(p_popResponseQueue, "\p", desc="Pop request queue") {
110 dmaResponseQueue_in.dequeue();
111 }
112
113 transition(READY, ReadRequest, BUSY_RD) {
114 s_sendReadRequest;
115 p_popRequestQueue;
116 }
117
118 transition(READY, WriteRequest, BUSY_WR) {
119 s_sendWriteRequest;
120 p_popRequestQueue;
121 }
122
123 transition(BUSY_RD, Data, READY) {
124 d_dataCallback;
125 p_popResponseQueue;
126 }
127
128 transition(BUSY_WR, Ack, READY) {
129 a_ackCallback;
130 p_popResponseQueue;
131 }
132 }