56#include "debug/Ethernet.hh"
57#include "debug/EthernetData.hh"
61#include "params/EtherLink.hh"
73 p.delay,
p.delay_var,
p.dump);
75 p.delay,
p.delay_var,
p.dump);
94 if (if_name ==
"int0")
96 else if (if_name ==
"int1")
111 : objName(
name), parent(
p), number(num), txint(NULL), rxint(NULL),
112 ticksPerByte(rate), linkDelay(delay), delayVar(delay_var),
dump(
d),
114 txQueueEvent([
this]{ processTxQueue(); },
name)
134 DPRINTF(Ethernet,
"packet received: len=%d\n", packet->length);
135 DDUMP(EthernetData, packet->data, packet->length);
136 rxint->sendPacket(packet);
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);
151 assert(txQueue.empty());
164 auto cur(txQueue.front());
168 if (!txQueue.empty()) {
169 auto next(txQueue.front());
170 assert(next.first >
curTick());
171 parent->schedule(txQueueEvent, next.first);
174 assert(cur.first ==
curTick());
175 txComplete(cur.second);
182 DPRINTF(Ethernet,
"packet not sent, link busy\n");
186 DPRINTF(Ethernet,
"packet sent: len=%d\n", pkt->length);
187 DDUMP(EthernetData, pkt->data, pkt->length);
190 Tick delay = (
Tick)ceil(((
double)pkt->simLength * ticksPerByte) + 1.0);
194 DPRINTF(Ethernet,
"scheduling packet: delay=%d, (rate=%f)\n",
195 delay, ticksPerByte);
196 parent->schedule(doneEvent,
curTick() + delay);
204 bool packet_exists = packet !=
nullptr;
207 packet->serialize(
base +
".packet", cp);
209 bool event_scheduled = doneEvent.scheduled();
210 paramOut(cp,
base +
".event_scheduled", event_scheduled);
211 if (event_scheduled) {
212 Tick event_time = doneEvent.when();
216 const size_t tx_queue_size(txQueue.size());
219 for (
const auto &
pe : txQueue) {
221 pe.second->serialize(
csprintf(
"%s.txQueue[%i].packet",
base, idx), cp);
231 paramIn(cp,
base +
".packet_exists", packet_exists);
233 packet = std::make_shared<EthPacketData>();
234 packet->unserialize(
base +
".packet", cp);
237 bool event_scheduled;
238 paramIn(cp,
base +
".event_scheduled", event_scheduled);
239 if (event_scheduled) {
242 parent->schedule(doneEvent, event_time);
245 size_t tx_queue_size = 0;
247 for (
size_t idx = 0; idx < tx_queue_size; ++idx) {
249 EthPacketPtr delayed_packet = std::make_shared<EthPacketData>();
252 delayed_packet->unserialize(
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));
260 if (!txQueue.empty())
261 parent->schedule(txQueueEvent, txQueue.front().first);
266 warn(
"Old-style EtherLink serialization format detected, "
267 "in-flight packets may have been dropped.\n");
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Interface(const std::string &name, Link *txlink, Link *rxlink)
void unserialize(const std::string &base, CheckpointIn &cp)
void serialize(const std::string &base, CheckpointOut &cp) const
Link(const std::string &name, EtherLink *p, int num, double rate, Tick delay, Tick delay_var, EtherDump *dump)
bool transmit(EthPacketPtr packet)
void setRxInt(Interface *i)
void setTxInt(Interface *i)
void txComplete(EthPacketPtr packet)
EtherLink(const Params &p)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void serialize(CheckpointOut &cp) const override
Serialize an object.
virtual std::string name() const
Ports are used to interface objects to each other.
Abstract superclass for simulation objects.
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...
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
bool optParamIn(CheckpointIn &cp, const std::string &name, T ¶m, bool do_warn=true)
This function is used for restoring optional parameters from the checkpoint.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
void dump()
Dump all statistics data to the registered outputs.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
std::ostream CheckpointOut
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
uint64_t Tick
Tick count type.
std::string csprintf(const char *format, const Args &...args)
std::shared_ptr< EthPacketData > EthPacketPtr
const std::string & name()