gem5 v24.0.0.0
Loading...
Searching...
No Matches
etherlink.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41/* @file
42 * Device module for modelling a fixed bandwidth full duplex ethernet link
43 */
44
45#include "dev/net/etherlink.hh"
46
47#include <cassert>
48#include <cmath>
49#include <deque>
50#include <string>
51#include <vector>
52
53#include "base/logging.hh"
54#include "base/random.hh"
55#include "base/trace.hh"
56#include "debug/Ethernet.hh"
57#include "debug/EthernetData.hh"
58#include "dev/net/etherdump.hh"
59#include "dev/net/etherint.hh"
60#include "dev/net/etherpkt.hh"
61#include "params/EtherLink.hh"
62#include "sim/cur_tick.hh"
63#include "sim/serialize.hh"
64#include "sim/system.hh"
65
66namespace gem5
67{
68
70 : SimObject(p)
71{
72 link[0] = new Link(name() + ".link0", this, 0, p.speed,
73 p.delay, p.delay_var, p.dump);
74 link[1] = new Link(name() + ".link1", this, 1, p.speed,
75 p.delay, p.delay_var, p.dump);
76
77 interface[0] = new Interface(name() + ".int0", link[0], link[1]);
78 interface[1] = new Interface(name() + ".int1", link[1], link[0]);
79}
80
81
83{
84 delete link[0];
85 delete link[1];
86
87 delete interface[0];
88 delete interface[1];
89}
90
91Port &
92EtherLink::getPort(const std::string &if_name, PortID idx)
93{
94 if (if_name == "int0")
95 return *interface[0];
96 else if (if_name == "int1")
97 return *interface[1];
98 return SimObject::getPort(if_name, idx);
99}
100
101
102EtherLink::Interface::Interface(const std::string &name, Link *tx, Link *rx)
103 : EtherInt(name), txlink(tx)
104{
105 tx->setTxInt(this);
106 rx->setRxInt(this);
107}
108
109EtherLink::Link::Link(const std::string &name, EtherLink *p, int num,
110 double rate, Tick delay, Tick delay_var, EtherDump *d)
111 : objName(name), parent(p), number(num), txint(NULL), rxint(NULL),
112 ticksPerByte(rate), linkDelay(delay), delayVar(delay_var), dump(d),
113 doneEvent([this]{ txDone(); }, name),
114 txQueueEvent([this]{ processTxQueue(); }, name)
115{ }
116
117void
119{
120 link[0]->serialize("link0", cp);
121 link[1]->serialize("link1", cp);
122}
123
124void
126{
127 link[0]->unserialize("link0", cp);
128 link[1]->unserialize("link1", cp);
129}
130
131void
133{
134 DPRINTF(Ethernet, "packet received: len=%d\n", packet->length);
135 DDUMP(EthernetData, packet->data, packet->length);
136 rxint->sendPacket(packet);
137}
138
139void
141{
142 if (dump)
143 dump->dump(packet);
144
145 if (linkDelay > 0) {
146 DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay);
147 txQueue.emplace_back(std::make_pair(curTick() + linkDelay, packet));
148 if (!txQueueEvent.scheduled())
149 parent->schedule(txQueueEvent, txQueue.front().first);
150 } else {
151 assert(txQueue.empty());
152 txComplete(packet);
153 }
154
155 packet = 0;
156 assert(!busy());
157
158 txint->sendDone();
159}
160
161void
163{
164 auto cur(txQueue.front());
165 txQueue.pop_front();
166
167 // Schedule a new event to process the next packet in the queue.
168 if (!txQueue.empty()) {
169 auto next(txQueue.front());
170 assert(next.first > curTick());
171 parent->schedule(txQueueEvent, next.first);
172 }
173
174 assert(cur.first == curTick());
175 txComplete(cur.second);
176}
177
178bool
180{
181 if (busy()) {
182 DPRINTF(Ethernet, "packet not sent, link busy\n");
183 return false;
184 }
185
186 DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length);
187 DDUMP(EthernetData, pkt->data, pkt->length);
188
189 packet = pkt;
190 Tick delay = (Tick)ceil(((double)pkt->simLength * ticksPerByte) + 1.0);
191 if (delayVar != 0)
192 delay += random_mt.random<Tick>(0, delayVar);
193
194 DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
195 delay, ticksPerByte);
196 parent->schedule(doneEvent, curTick() + delay);
197
198 return true;
199}
200
201void
202EtherLink::Link::serialize(const std::string &base, CheckpointOut &cp) const
203{
204 bool packet_exists = packet != nullptr;
205 paramOut(cp, base + ".packet_exists", packet_exists);
206 if (packet_exists)
207 packet->serialize(base + ".packet", cp);
208
209 bool event_scheduled = doneEvent.scheduled();
210 paramOut(cp, base + ".event_scheduled", event_scheduled);
211 if (event_scheduled) {
212 Tick event_time = doneEvent.when();
213 paramOut(cp, base + ".event_time", event_time);
214 }
215
216 const size_t tx_queue_size(txQueue.size());
217 paramOut(cp, base + ".tx_queue_size", tx_queue_size);
218 unsigned idx(0);
219 for (const auto &pe : txQueue) {
220 paramOut(cp, csprintf("%s.txQueue[%i].tick", base, idx), pe.first);
221 pe.second->serialize(csprintf("%s.txQueue[%i].packet", base, idx), cp);
222
223 ++idx;
224 }
225}
226
227void
229{
230 bool packet_exists;
231 paramIn(cp, base + ".packet_exists", packet_exists);
232 if (packet_exists) {
233 packet = std::make_shared<EthPacketData>();
234 packet->unserialize(base + ".packet", cp);
235 }
236
237 bool event_scheduled;
238 paramIn(cp, base + ".event_scheduled", event_scheduled);
239 if (event_scheduled) {
240 Tick event_time;
241 paramIn(cp, base + ".event_time", event_time);
242 parent->schedule(doneEvent, event_time);
243 }
244
245 size_t tx_queue_size = 0;
246 if (optParamIn(cp, base + ".tx_queue_size", tx_queue_size)) {
247 for (size_t idx = 0; idx < tx_queue_size; ++idx) {
248 Tick tick;
249 EthPacketPtr delayed_packet = std::make_shared<EthPacketData>();
250
251 paramIn(cp, csprintf("%s.txQueue[%i].tick", base, idx), tick);
252 delayed_packet->unserialize(
253 csprintf("%s.txQueue[%i].packet", base, idx), cp);
254
255 fatal_if(!txQueue.empty() && txQueue.back().first > tick,
256 "Invalid txQueue packet order in EtherLink!\n");
257 txQueue.emplace_back(std::make_pair(tick, delayed_packet));
258 }
259
260 if (!txQueue.empty())
261 parent->schedule(txQueueEvent, txQueue.front().first);
262 } else {
263 // We can't reliably convert in-flight packets from old
264 // checkpoints. In fact, gem5 hasn't been able to load these
265 // packets for at least two years before the format change.
266 warn("Old-style EtherLink serialization format detected, "
267 "in-flight packets may have been dropped.\n");
268 }
269}
270
271} // namespace gem5
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition trace.hh:204
#define DPRINTF(x,...)
Definition trace.hh:210
virtual std::string name() const
Definition named.hh:47
Ports are used to interface objects to each other.
Definition port.hh:62
Abstract superclass for simulation objects.
Random random_mt
Definition random.cc:99
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition random.hh:90
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
bool optParamIn(CheckpointIn &cp, const std::string &name, T &param, bool do_warn=true)
This function is used for restoring optional parameters from the checkpoint.
Definition serialize.hh:357
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
#define warn(...)
Definition logging.hh:256
Bitfield< 9 > d
Definition misc_types.hh:64
Bitfield< 0 > p
Bitfield< 0 > pe
Definition misc.hh:619
Bitfield< 51, 12 > base
Definition pagetable.hh:141
void dump()
Dump all statistics data to the registered outputs.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
std::ostream CheckpointOut
Definition serialize.hh:66
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition types.cc:40
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition types.cc:72
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition types.hh:245
uint64_t Tick
Tick count type.
Definition types.hh:58
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
std::shared_ptr< EthPacketData > EthPacketPtr
Definition etherpkt.hh:90
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:03 for gem5 by doxygen 1.11.0