2 * Copyright (c) 2020 Advanced Micro Devices, Inc.
3 * Copyright (c) 2019 ARM Limited
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
15 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
16 * All rights reserved.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 #include "mem/ruby/network/simple/SimpleNetwork.hh"
47 #include "base/cast.hh"
48 #include "mem/ruby/common/NetDest.hh"
49 #include "mem/ruby/network/MessageBuffer.hh"
50 #include "mem/ruby/network/simple/SimpleLink.hh"
51 #include "mem/ruby/network/simple/Switch.hh"
52 #include "mem/ruby/network/simple/Throttle.hh"
53 #include "mem/ruby/profiler/Profiler.hh"
57 SimpleNetwork::SimpleNetwork(const Params
*p
)
58 : Network(p
), m_buffer_size(p
->buffer_size
),
59 m_endpoint_bandwidth(p
->endpoint_bandwidth
),
60 m_adaptive_routing(p
->adaptive_routing
)
63 for (vector
<BasicRouter
*>::const_iterator i
= p
->routers
.begin();
64 i
!= p
->routers
.end(); ++i
) {
65 Switch
* s
= safe_cast
<Switch
*>(*i
);
66 m_switches
.push_back(s
);
67 s
->init_net_ptr(this);
70 m_int_link_buffers
= p
->int_link_buffers
;
71 m_num_connected_buffers
= 0;
79 // The topology pointer should have already been initialized in
80 // the parent class network constructor.
81 assert(m_topology_ptr
!= NULL
);
82 m_topology_ptr
->createLinks(this);
85 // From a switch to an endpoint node
87 SimpleNetwork::makeExtOutLink(SwitchID src
, NodeID global_dest
,
89 std::vector
<NetDest
>& routing_table_entry
)
91 NodeID local_dest
= getLocalNodeID(global_dest
);
92 assert(local_dest
< m_nodes
);
93 assert(src
< m_switches
.size());
94 assert(m_switches
[src
] != NULL
);
96 SimpleExtLink
*simple_link
= safe_cast
<SimpleExtLink
*>(link
);
98 m_switches
[src
]->addOutPort(m_fromNetQueues
[local_dest
],
99 routing_table_entry
[0], simple_link
->m_latency
,
100 simple_link
->m_bw_multiplier
);
103 // From an endpoint node to a switch
105 SimpleNetwork::makeExtInLink(NodeID global_src
, SwitchID dest
, BasicLink
* link
,
106 std::vector
<NetDest
>& routing_table_entry
)
108 NodeID local_src
= getLocalNodeID(global_src
);
109 assert(local_src
< m_nodes
);
110 m_switches
[dest
]->addInPort(m_toNetQueues
[local_src
]);
113 // From a switch to a switch
115 SimpleNetwork::makeInternalLink(SwitchID src
, SwitchID dest
, BasicLink
* link
,
116 std::vector
<NetDest
>& routing_table_entry
,
117 PortDirection src_outport
,
118 PortDirection dst_inport
)
120 // Create a set of new MessageBuffers
121 std::vector
<MessageBuffer
*> queues(m_virtual_networks
);
123 for (int i
= 0; i
< m_virtual_networks
; i
++) {
125 assert(m_num_connected_buffers
< m_int_link_buffers
.size());
126 MessageBuffer
* buffer_ptr
= m_int_link_buffers
[m_num_connected_buffers
];
127 m_num_connected_buffers
++;
128 queues
[i
] = buffer_ptr
;
131 // Connect it to the two switches
132 SimpleIntLink
*simple_link
= safe_cast
<SimpleIntLink
*>(link
);
134 m_switches
[dest
]->addInPort(queues
);
135 m_switches
[src
]->addOutPort(queues
, routing_table_entry
[0],
136 simple_link
->m_latency
,
137 simple_link
->m_bw_multiplier
);
141 SimpleNetwork::regStats()
145 for (MessageSizeType type
= MessageSizeType_FIRST
;
146 type
< MessageSizeType_NUM
; ++type
) {
147 m_msg_counts
[(unsigned int) type
]
148 .name(name() + ".msg_count." + MessageSizeType_to_string(type
))
149 .flags(Stats::nozero
)
151 m_msg_bytes
[(unsigned int) type
]
152 .name(name() + ".msg_byte." + MessageSizeType_to_string(type
))
153 .flags(Stats::nozero
)
156 // Now state what the formula is.
157 for (int i
= 0; i
< m_switches
.size(); i
++) {
158 m_msg_counts
[(unsigned int) type
] +=
159 sum(m_switches
[i
]->getMsgCount(type
));
162 m_msg_bytes
[(unsigned int) type
] =
163 m_msg_counts
[(unsigned int) type
] * Stats::constant(
164 Network::MessageSizeType_to_int(type
));
169 SimpleNetwork::collateStats()
171 for (int i
= 0; i
< m_switches
.size(); i
++) {
172 m_switches
[i
]->collateStats();
177 SimpleNetwork::print(ostream
& out
) const
179 out
<< "[SimpleNetwork]";
183 SimpleNetworkParams::create()
185 return new SimpleNetwork(this);
189 * The simple network has an array of switches. These switches have buffers
190 * that need to be accessed for functional reads and writes. Also the links
191 * between different switches have buffers that need to be accessed.
194 SimpleNetwork::functionalRead(Packet
*pkt
)
196 for (unsigned int i
= 0; i
< m_switches
.size(); i
++) {
197 if (m_switches
[i
]->functionalRead(pkt
))
200 for (unsigned int i
= 0; i
< m_int_link_buffers
.size(); ++i
) {
201 if (m_int_link_buffers
[i
]->functionalRead(pkt
))
209 SimpleNetwork::functionalWrite(Packet
*pkt
)
211 uint32_t num_functional_writes
= 0;
213 for (unsigned int i
= 0; i
< m_switches
.size(); i
++) {
214 num_functional_writes
+= m_switches
[i
]->functionalWrite(pkt
);
217 for (unsigned int i
= 0; i
< m_int_link_buffers
.size(); ++i
) {
218 num_functional_writes
+= m_int_link_buffers
[i
]->functionalWrite(pkt
);
220 return num_functional_writes
;