57 #include "debug/Ethernet.hh"
58 #include "debug/EthernetData.hh"
62 #include "params/EtherLink.hh"
73 p->delay, p->delay_var, p->dump);
75 p->delay, p->delay_var, p->dump);
95 if (if_name ==
"int0")
97 else if (if_name ==
"int1")
102 panic(
"interface already connected to\n");
117 : objName(name), parent(p), number(num), txint(NULL), rxint(NULL),
118 ticksPerByte(rate), linkDelay(delay), delayVar(delay_var),
dump(d),
119 doneEvent(this), txQueueEvent(this)
139 DPRINTF(Ethernet,
"packet received: len=%d\n", packet->length);
140 DDUMP(EthernetData, packet->data, packet->length);
141 rxint->sendPacket(packet);
151 DPRINTF(Ethernet,
"packet delayed: delay=%d\n", linkDelay);
152 txQueue.emplace_back(std::make_pair(
curTick() + linkDelay, packet));
153 if (!txQueueEvent.scheduled())
154 parent->schedule(txQueueEvent, txQueue.front().first);
156 assert(txQueue.empty());
169 auto cur(txQueue.front());
173 if (!txQueue.empty()) {
174 auto next(txQueue.front());
175 assert(next.first >
curTick());
176 parent->schedule(txQueueEvent, next.first);
179 assert(cur.first ==
curTick());
180 txComplete(cur.second);
187 DPRINTF(Ethernet,
"packet not sent, link busy\n");
191 DPRINTF(Ethernet,
"packet sent: len=%d\n", pkt->length);
192 DDUMP(EthernetData, pkt->data, pkt->length);
195 Tick delay = (
Tick)ceil(((
double)pkt->simLength * ticksPerByte) + 1.0);
199 DPRINTF(Ethernet,
"scheduling packet: delay=%d, (rate=%f)\n",
200 delay, ticksPerByte);
201 parent->schedule(doneEvent,
curTick() + delay);
209 bool packet_exists = packet !=
nullptr;
210 paramOut(cp, base +
".packet_exists", packet_exists);
212 packet->serialize(base +
".packet", cp);
214 bool event_scheduled = doneEvent.scheduled();
215 paramOut(cp, base +
".event_scheduled", event_scheduled);
216 if (event_scheduled) {
217 Tick event_time = doneEvent.when();
218 paramOut(cp, base +
".event_time", event_time);
221 const size_t tx_queue_size(txQueue.size());
222 paramOut(cp, base +
".tx_queue_size", tx_queue_size);
224 for (
const auto &
pe : txQueue) {
226 pe.second->serialize(
csprintf(
"%s.txQueue[%i].packet", base, idx), cp);
236 paramIn(cp, base +
".packet_exists", packet_exists);
238 packet = make_shared<EthPacketData>();
239 packet->unserialize(base +
".packet", cp);
242 bool event_scheduled;
243 paramIn(cp, base +
".event_scheduled", event_scheduled);
244 if (event_scheduled) {
246 paramIn(cp, base +
".event_time", event_time);
247 parent->schedule(doneEvent, event_time);
250 size_t tx_queue_size;
251 if (
optParamIn(cp, base +
".tx_queue_size", tx_queue_size)) {
252 for (
size_t idx = 0; idx < tx_queue_size; ++idx) {
254 EthPacketPtr delayed_packet = make_shared<EthPacketData>();
257 delayed_packet->unserialize(
258 csprintf(
"%s.txQueue[%i].packet", base, idx), cp);
260 fatal_if(!txQueue.empty() && txQueue.back().first > tick,
261 "Invalid txQueue packet order in EtherLink!\n");
262 txQueue.emplace_back(std::make_pair(tick, delayed_packet));
265 if (!txQueue.empty())
266 parent->schedule(txQueueEvent, txQueue.front().first);
271 warn(
"Old-style EtherLink serialization format detected, "
272 "in-flight packets may have been dropped.\n");
277 EtherLinkParams::create()
void txComplete(EthPacketPtr packet)
Interface(const std::string &name, Link *txlink, Link *rxlink)
void unserialize(const std::string &base, CheckpointIn &cp)
const std::string & name()
bool optParamIn(CheckpointIn &cp, const string &name, T ¶m, bool warn)
#define DDUMP(x, data, count)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Link(const std::string &name, EtherLink *p, int num, double rate, Tick delay, Tick delay_var, EtherDump *dump)
std::enable_if< std::is_integral< T >::value, T >::type random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Tick curTick()
The current simulated tick.
std::string csprintf(const char *format, const Args &...args)
void serialize(const std::string &base, CheckpointOut &cp) const
uint64_t Tick
Tick count type.
EtherLink(const Params *p)
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
std::shared_ptr< EthPacketData > EthPacketPtr
void serialize(CheckpointOut &cp) const override
Serialize an object.
The base EtherObject class, allows for an accesor function to a simobj that returns the Port...
virtual const std::string name() const
EtherInt * getEthPort(const std::string &if_name, int idx) override
Additional function to return the Port of a memory object.
std::ostream CheckpointOut
void setRxInt(Interface *i)
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
bool transmit(EthPacketPtr packet)
void setTxInt(Interface *i)
void dump()
Dump all statistics data to the registered outputs.
fatal_if(p->js_features.size() > 16,"Too many job slot feature registers specified (%i)\n", p->js_features.size())