etherlink.cc revision 2665
12SN/A/* 21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 292665Ssaidi@eecs.umich.edu * Ron Dreslinski 302665Ssaidi@eecs.umich.edu */ 312665Ssaidi@eecs.umich.edu 322SN/A/* @file 332SN/A * Device module for modelling a fixed bandwidth full duplex ethernet link 342SN/A */ 352SN/A 367349SAli.Saidi@ARM.com#include <cmath> 377680Sgblack@eecs.umich.edu#include <deque> 3856SN/A#include <string> 398229Snate@binkert.org#include <vector> 401717SN/A 412518SN/A#include "base/random.hh" 4256SN/A#include "base/trace.hh" 434776Sgblack@eecs.umich.edu#include "dev/etherdump.hh" 448232Snate@binkert.org#include "dev/etherint.hh" 454762Snate@binkert.org#include "dev/etherlink.hh" 463065Sgblack@eecs.umich.edu#include "dev/etherpkt.hh" 472SN/A#include "sim/builder.hh" 482973Sgblack@eecs.umich.edu#include "sim/serialize.hh" 492SN/A#include "sim/system.hh" 503506Ssaidi@eecs.umich.edu#include "sim/root.hh" 514054Sbinkertn@umich.edu 524054Sbinkertn@umich.eduusing namespace std; 535866Sksewell@umich.edu 545866Sksewell@umich.eduEtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1, 555866Sksewell@umich.edu double rate, Tick delay, Tick delayVar, EtherDump *dump) 565866Sksewell@umich.edu : SimObject(name) 575866Sksewell@umich.edu{ 585866Sksewell@umich.edu link[0] = new Link(name + ".link0", this, 0, rate, delay, delayVar, dump); 595784Sgblack@eecs.umich.edu link[1] = new Link(name + ".link1", this, 1, rate, delay, delayVar, dump); 604054Sbinkertn@umich.edu 614776Sgblack@eecs.umich.edu interface[0] = new Interface(name + ".int0", link[0], link[1]); 624054Sbinkertn@umich.edu interface[1] = new Interface(name + ".int1", link[1], link[0]); 638300Schander.sudanthi@arm.com 648300Schander.sudanthi@arm.com interface[0]->setPeer(peer0); 658300Schander.sudanthi@arm.com peer0->setPeer(interface[0]); 668300Schander.sudanthi@arm.com interface[1]->setPeer(peer1); 678300Schander.sudanthi@arm.com peer1->setPeer(interface[1]); 688300Schander.sudanthi@arm.com} 698232Snate@binkert.org 705866Sksewell@umich.eduEtherLink::~EtherLink() 714054Sbinkertn@umich.edu{ 724776Sgblack@eecs.umich.edu delete link[0]; 734054Sbinkertn@umich.edu delete link[1]; 748232Snate@binkert.org 754776Sgblack@eecs.umich.edu delete interface[0]; 764054Sbinkertn@umich.edu delete interface[1]; 778300Schander.sudanthi@arm.com} 788300Schander.sudanthi@arm.com 798300Schander.sudanthi@arm.comEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) 808232Snate@binkert.org : EtherInt(name), txlink(tx) 815715Shsul@eecs.umich.edu{ 824776Sgblack@eecs.umich.edu tx->setTxInt(this); 834776Sgblack@eecs.umich.edu rx->setRxInt(this); 844776Sgblack@eecs.umich.edu} 857720Sgblack@eecs.umich.edu 869809Sumesh.b2006@gmail.comEtherLink::Link::Link(const string &name, EtherLink *p, int num, 879809Sumesh.b2006@gmail.com double rate, Tick delay, Tick delay_var, EtherDump *d) 889809Sumesh.b2006@gmail.com : objName(name), parent(p), number(num), txint(NULL), rxint(NULL), 897349SAli.Saidi@ARM.com ticksPerByte(rate), linkDelay(delay), delayVar(delay_var), dump(d), 907349SAli.Saidi@ARM.com doneEvent(this) 915784Sgblack@eecs.umich.edu{ } 927720Sgblack@eecs.umich.edu 937349SAli.Saidi@ARM.comvoid 944776Sgblack@eecs.umich.eduEtherLink::serialize(ostream &os) 954776Sgblack@eecs.umich.edu{ 965784Sgblack@eecs.umich.edu link[0]->serialize("link0", os); 977720Sgblack@eecs.umich.edu link[1]->serialize("link1", os); 985784Sgblack@eecs.umich.edu} 995784Sgblack@eecs.umich.edu 1005784Sgblack@eecs.umich.eduvoid 1015784Sgblack@eecs.umich.eduEtherLink::unserialize(Checkpoint *cp, const string §ion) 1025784Sgblack@eecs.umich.edu{ 1035784Sgblack@eecs.umich.edu link[0]->unserialize("link0", cp, section); 1044776Sgblack@eecs.umich.edu link[1]->unserialize("link1", cp, section); 1054776Sgblack@eecs.umich.edu} 1064776Sgblack@eecs.umich.edu 1074776Sgblack@eecs.umich.eduvoid 1084776Sgblack@eecs.umich.eduEtherLink::Link::txComplete(EthPacketPtr packet) 1097349SAli.Saidi@ARM.com{ 1104776Sgblack@eecs.umich.edu DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); 1115784Sgblack@eecs.umich.edu DDUMP(EthernetData, packet->data, packet->length); 1125784Sgblack@eecs.umich.edu rxint->sendPacket(packet); 1135784Sgblack@eecs.umich.edu} 1148232Snate@binkert.org 1155784Sgblack@eecs.umich.educlass LinkDelayEvent : public Event 1165784Sgblack@eecs.umich.edu{ 1175784Sgblack@eecs.umich.edu protected: 11810231Ssteve.reinhardt@amd.com EtherLink::Link *link; 1197600Sminkyu.jeong@arm.com EthPacketPtr packet; 1207600Sminkyu.jeong@arm.com 1217600Sminkyu.jeong@arm.com public: 1228232Snate@binkert.org // non-scheduling version for createForUnserialize() 1235784Sgblack@eecs.umich.edu LinkDelayEvent(); 1245784Sgblack@eecs.umich.edu LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt, Tick when); 1255784Sgblack@eecs.umich.edu 1268232Snate@binkert.org void process(); 1275784Sgblack@eecs.umich.edu 1285784Sgblack@eecs.umich.edu virtual void serialize(ostream &os); 1298232Snate@binkert.org virtual void unserialize(Checkpoint *cp, const string §ion); 1305784Sgblack@eecs.umich.edu static Serializable *createForUnserialize(Checkpoint *cp, 1315784Sgblack@eecs.umich.edu const string §ion); 1328232Snate@binkert.org}; 1335784Sgblack@eecs.umich.edu 1344776Sgblack@eecs.umich.eduvoid 1354776Sgblack@eecs.umich.eduEtherLink::Link::txDone() 1364776Sgblack@eecs.umich.edu{ 1374776Sgblack@eecs.umich.edu if (dump) 1384776Sgblack@eecs.umich.edu dump->dump(packet); 1394776Sgblack@eecs.umich.edu 1403506Ssaidi@eecs.umich.edu if (linkDelay > 0) { 1413506Ssaidi@eecs.umich.edu DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay); 1425784Sgblack@eecs.umich.edu new LinkDelayEvent(this, packet, curTick + linkDelay); 1435784Sgblack@eecs.umich.edu } else { 1445784Sgblack@eecs.umich.edu txComplete(packet); 1455784Sgblack@eecs.umich.edu } 1465784Sgblack@eecs.umich.edu 1475784Sgblack@eecs.umich.edu packet = 0; 1485784Sgblack@eecs.umich.edu assert(!busy()); 1495784Sgblack@eecs.umich.edu 1505784Sgblack@eecs.umich.edu txint->sendDone(); 1515784Sgblack@eecs.umich.edu} 1525784Sgblack@eecs.umich.edu 1538232Snate@binkert.orgbool 1548232Snate@binkert.orgEtherLink::Link::transmit(EthPacketPtr pkt) 1558232Snate@binkert.org{ 1568232Snate@binkert.org if (busy()) { 1575791Srstrong@cs.ucsd.edu DPRINTF(Ethernet, "packet not sent, link busy\n"); 1585784Sgblack@eecs.umich.edu return false; 1595784Sgblack@eecs.umich.edu } 1608232Snate@binkert.org 1615784Sgblack@eecs.umich.edu DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length); 1625784Sgblack@eecs.umich.edu DDUMP(EthernetData, pkt->data, pkt->length); 1635784Sgblack@eecs.umich.edu 1645784Sgblack@eecs.umich.edu packet = pkt; 1657811Ssteve.reinhardt@amd.com Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); 1664776Sgblack@eecs.umich.edu if (delayVar != 0) { 1672SN/A Random<Tick> var; 1682SN/A delay += var.uniform(0, delayVar); 1694776Sgblack@eecs.umich.edu } 1702SN/A DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", 1714776Sgblack@eecs.umich.edu delay, ticksPerByte); 1724776Sgblack@eecs.umich.edu doneEvent.schedule(curTick + delay); 1733748Sgblack@eecs.umich.edu 1745034Smilesck@eecs.umich.edu return true; 1758902Sandreas.hansson@arm.com} 176 177void 178EtherLink::Link::serialize(const string &base, ostream &os) 179{ 180 bool packet_exists = packet; 181 paramOut(os, base + ".packet_exists", packet_exists); 182 if (packet_exists) 183 packet->serialize(base + ".packet", os); 184 185 bool event_scheduled = doneEvent.scheduled(); 186 paramOut(os, base + ".event_scheduled", event_scheduled); 187 if (event_scheduled) { 188 Tick event_time = doneEvent.when(); 189 paramOut(os, base + ".event_time", event_time); 190 } 191 192} 193 194void 195EtherLink::Link::unserialize(const string &base, Checkpoint *cp, 196 const string §ion) 197{ 198 bool packet_exists; 199 paramIn(cp, section, base + ".packet_exists", packet_exists); 200 if (packet_exists) { 201 packet = new EthPacketData(16384); 202 packet->unserialize(base + ".packet", cp, section); 203 } 204 205 bool event_scheduled; 206 paramIn(cp, section, base + ".event_scheduled", event_scheduled); 207 if (event_scheduled) { 208 Tick event_time; 209 paramIn(cp, section, base + ".event_time", event_time); 210 doneEvent.schedule(event_time); 211 } 212} 213 214LinkDelayEvent::LinkDelayEvent() 215 : Event(&mainEventQueue), link(NULL) 216{ 217 setFlags(AutoSerialize); 218 setFlags(AutoDelete); 219} 220 221LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p, Tick when) 222 : Event(&mainEventQueue), link(l), packet(p) 223{ 224 setFlags(AutoSerialize); 225 setFlags(AutoDelete); 226 schedule(when); 227} 228 229void 230LinkDelayEvent::process() 231{ 232 link->txComplete(packet); 233} 234 235void 236LinkDelayEvent::serialize(ostream &os) 237{ 238 paramOut(os, "type", string("LinkDelayEvent")); 239 Event::serialize(os); 240 241 EtherLink *parent = link->parent; 242 bool number = link->number; 243 SERIALIZE_OBJPTR(parent); 244 SERIALIZE_SCALAR(number); 245 246 packet->serialize("packet", os); 247} 248 249 250void 251LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) 252{ 253 Event::unserialize(cp, section); 254 255 EtherLink *parent; 256 bool number; 257 UNSERIALIZE_OBJPTR(parent); 258 UNSERIALIZE_SCALAR(number); 259 260 link = parent->link[number]; 261 262 packet = new EthPacketData(16384); 263 packet->unserialize("packet", cp, section); 264} 265 266 267Serializable * 268LinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion) 269{ 270 return new LinkDelayEvent(); 271} 272 273REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent) 274 275BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 276 277 SimObjectParam<EtherInt *> int1; 278 SimObjectParam<EtherInt *> int2; 279 Param<double> speed; 280 Param<Tick> delay; 281 Param<Tick> delay_var; 282 SimObjectParam<EtherDump *> dump; 283 284END_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 285 286BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) 287 288 INIT_PARAM(int1, "interface 1"), 289 INIT_PARAM(int2, "interface 2"), 290 INIT_PARAM(speed, "link speed in bits per second"), 291 INIT_PARAM(delay, "transmit delay of packets in us"), 292 INIT_PARAM(delay_var, "Difference in amount of time to traverse wire"), 293 INIT_PARAM(dump, "object to dump network packets to") 294 295END_INIT_SIM_OBJECT_PARAMS(EtherLink) 296 297CREATE_SIM_OBJECT(EtherLink) 298{ 299 return new EtherLink(getInstanceName(), int1, int2, speed, delay, delay_var, 300 dump); 301} 302 303REGISTER_SIM_OBJECT("EtherLink", EtherLink) 304