etherlink.cc revision 1954
12689Sktlim@umich.edu/* 22689Sktlim@umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 32689Sktlim@umich.edu * All rights reserved. 42689Sktlim@umich.edu * 52689Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without 62689Sktlim@umich.edu * modification, are permitted provided that the following conditions are 72689Sktlim@umich.edu * met: redistributions of source code must retain the above copyright 82689Sktlim@umich.edu * notice, this list of conditions and the following disclaimer; 92689Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright 102689Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the 112689Sktlim@umich.edu * documentation and/or other materials provided with the distribution; 122689Sktlim@umich.edu * neither the name of the copyright holders nor the names of its 132689Sktlim@umich.edu * contributors may be used to endorse or promote products derived from 142689Sktlim@umich.edu * this software without specific prior written permission. 152689Sktlim@umich.edu * 162689Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172689Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182689Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192689Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202689Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212689Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222689Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232689Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242689Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252689Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262689Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272689Sktlim@umich.edu */ 282689Sktlim@umich.edu 292689Sktlim@umich.edu/* @file 302689Sktlim@umich.edu * Device module for modelling a fixed bandwidth full duplex ethernet link 312689Sktlim@umich.edu */ 322689Sktlim@umich.edu 332689Sktlim@umich.edu#include <cmath> 342521SN/A#include <deque> 353960Sgblack@eecs.umich.edu#include <string> 364194Ssaidi@eecs.umich.edu#include <vector> 371070SN/A 381070SN/A#include "base/random.hh" 392521SN/A#include "base/trace.hh" 402680Sktlim@umich.edu#include "dev/etherdump.hh" 412521SN/A#include "dev/etherint.hh" 422522SN/A#include "dev/etherlink.hh" 432037SN/A#include "dev/etherpkt.hh" 4456SN/A#include "sim/builder.hh" 452378SN/A#include "sim/serialize.hh" 462521SN/A#include "sim/system.hh" 472378SN/A#include "sim/root.hh" 484762Snate@binkert.org 494762Snate@binkert.orgusing namespace std; 502378SN/A 512SN/AEtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1, 522SN/A double rate, Tick delay, Tick delayVar, EtherDump *dump) 532107SN/A : SimObject(name) 542SN/A{ 552SN/A link[0] = new Link(name + ".link0", this, 0, rate, delay, delayVar, dump); 562SN/A link[1] = new Link(name + ".link1", this, 1, rate, delay, delayVar, dump); 572SN/A 582SN/A interface[0] = new Interface(name + ".int0", link[0], link[1]); 591070SN/A interface[1] = new Interface(name + ".int1", link[1], link[0]); 602378SN/A 612378SN/A interface[0]->setPeer(peer0); 622521SN/A peer0->setPeer(interface[0]); 632640Sstever@eecs.umich.edu interface[1]->setPeer(peer1); 642640Sstever@eecs.umich.edu peer1->setPeer(interface[1]); 652378SN/A} 662378SN/A 672378SN/AEtherLink::~EtherLink() 682902Ssaidi@eecs.umich.edu{ 692SN/A delete link[0]; 701070SN/A delete link[1]; 711070SN/A 721070SN/A delete interface[0]; 732378SN/A delete interface[1]; 741070SN/A} 754838Ssaidi@eecs.umich.edu 764838Ssaidi@eecs.umich.eduEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) 771070SN/A : EtherInt(name), txlink(tx) 782520SN/A{ 792520SN/A tx->setTxInt(this); 802520SN/A rx->setRxInt(this); 812520SN/A} 822520SN/A 832520SN/AEtherLink::Link::Link(const string &name, EtherLink *p, int num, 842520SN/A double rate, Tick delay, Tick delay_var, EtherDump *d) 852520SN/A : objName(name), parent(p), number(num), txint(NULL), rxint(NULL), 862520SN/A ticksPerByte(rate), linkDelay(delay), delayVar(delay_var), dump(d), 872521SN/A doneEvent(this) 882521SN/A{ } 892521SN/A 902521SN/Avoid 912520SN/AEtherLink::serialize(ostream &os) 921070SN/A{ 932158SN/A link[0]->serialize("link0", os); 941070SN/A link[1]->serialize("link1", os); 954762Snate@binkert.org} 963812Ssaidi@eecs.umich.edu 973812Ssaidi@eecs.umich.eduvoid 983812Ssaidi@eecs.umich.eduEtherLink::unserialize(Checkpoint *cp, const string §ion) 993812Ssaidi@eecs.umich.edu{ 1004762Snate@binkert.org link[0]->unserialize("link0", cp, section); 1013812Ssaidi@eecs.umich.edu link[1]->unserialize("link1", cp, section); 1024762Snate@binkert.org} 1031070SN/A 1043812Ssaidi@eecs.umich.eduvoid 1053812Ssaidi@eecs.umich.eduEtherLink::Link::txComplete(PacketPtr packet) 1061070SN/A{ 1073812Ssaidi@eecs.umich.edu DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); 1083812Ssaidi@eecs.umich.edu DDUMP(EthernetData, packet->data, packet->length); 1093812Ssaidi@eecs.umich.edu rxint->sendPacket(packet); 1103812Ssaidi@eecs.umich.edu} 1111070SN/A 1123812Ssaidi@eecs.umich.educlass LinkDelayEvent : public Event 1133812Ssaidi@eecs.umich.edu{ 1143812Ssaidi@eecs.umich.edu protected: 1151070SN/A EtherLink::Link *link; 1163812Ssaidi@eecs.umich.edu PacketPtr packet; 1173812Ssaidi@eecs.umich.edu 1181070SN/A public: 1193812Ssaidi@eecs.umich.edu // non-scheduling version for createForUnserialize() 1203812Ssaidi@eecs.umich.edu LinkDelayEvent(); 1211074SN/A LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when); 1223812Ssaidi@eecs.umich.edu 1233812Ssaidi@eecs.umich.edu void process(); 1241074SN/A 1253812Ssaidi@eecs.umich.edu virtual void serialize(ostream &os); 1263812Ssaidi@eecs.umich.edu virtual void unserialize(Checkpoint *cp, const string §ion); 1273812Ssaidi@eecs.umich.edu static Serializable *createForUnserialize(Checkpoint *cp, 1283812Ssaidi@eecs.umich.edu const string §ion); 1293812Ssaidi@eecs.umich.edu}; 1302378SN/A 1312378SN/Avoid 1321070SN/AEtherLink::Link::txDone() 133878SN/A{ 1342SN/A if (dump) 1352SN/A dump->dump(packet); 1362SN/A 1372SN/A if (linkDelay > 0) { 1382378SN/A DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay); 1391070SN/A new LinkDelayEvent(this, packet, curTick + linkDelay); 1401070SN/A } else { 1412378SN/A txComplete(packet); 1422378SN/A } 1432378SN/A 1442378SN/A packet = 0; 1452SN/A assert(!busy()); 1462SN/A 1471808SN/A txint->sendDone(); 1484095Sbinkertn@umich.edu} 1491808SN/A 1502901Ssaidi@eecs.umich.edubool 1514762Snate@binkert.orgEtherLink::Link::transmit(PacketPtr pkt) 1522901Ssaidi@eecs.umich.edu{ 1532901Ssaidi@eecs.umich.edu if (busy()) { 1542901Ssaidi@eecs.umich.edu DPRINTF(Ethernet, "packet not sent, link busy\n"); 1552901Ssaidi@eecs.umich.edu return false; 1562901Ssaidi@eecs.umich.edu } 1573960Sgblack@eecs.umich.edu 1583960Sgblack@eecs.umich.edu DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length); 1594095Sbinkertn@umich.edu DDUMP(EthernetData, pkt->data, pkt->length); 1604095Sbinkertn@umich.edu 1614095Sbinkertn@umich.edu packet = pkt; 1623960Sgblack@eecs.umich.edu Random<Tick> var; 1633960Sgblack@eecs.umich.edu Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0 + 164180SN/A var.uniform(delayVar)); 1652680Sktlim@umich.edu DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", 1662SN/A delay, ticksPerByte); 1671806SN/A doneEvent.schedule(curTick + delay); 1682680Sktlim@umich.edu 1692680Sktlim@umich.edu return true; 1701806SN/A} 1711806SN/A 1721806SN/Avoid 1731806SN/AEtherLink::Link::serialize(const string &base, ostream &os) 1742680Sktlim@umich.edu{ 1752680Sktlim@umich.edu bool packet_exists = packet; 1761806SN/A paramOut(os, base + ".packet_exists", packet_exists); 1772680Sktlim@umich.edu if (packet_exists) 1781806SN/A packet->serialize(base + ".packet", os); 1791806SN/A 1802680Sktlim@umich.edu bool event_scheduled = doneEvent.scheduled(); 1811806SN/A paramOut(os, base + ".event_scheduled", event_scheduled); 1821070SN/A if (event_scheduled) { 1834095Sbinkertn@umich.edu Tick event_time = doneEvent.when(); 1844095Sbinkertn@umich.edu paramOut(os, base + ".event_time", event_time); 1854095Sbinkertn@umich.edu } 1864095Sbinkertn@umich.edu 1874095Sbinkertn@umich.edu} 1884095Sbinkertn@umich.edu 1894095Sbinkertn@umich.eduvoid 1904095Sbinkertn@umich.eduEtherLink::Link::unserialize(const string &base, Checkpoint *cp, 1914095Sbinkertn@umich.edu const string §ion) 1924095Sbinkertn@umich.edu{ 1931070SN/A bool packet_exists; 1944095Sbinkertn@umich.edu paramIn(cp, section, base + ".packet_exists", packet_exists); 1954095Sbinkertn@umich.edu if (packet_exists) { 1964095Sbinkertn@umich.edu packet = new PacketData(16384); 1974095Sbinkertn@umich.edu packet->unserialize(base + ".packet", cp, section); 1984095Sbinkertn@umich.edu } 1991070SN/A 2001070SN/A bool event_scheduled; 2011806SN/A paramIn(cp, section, base + ".event_scheduled", event_scheduled); 202180SN/A if (event_scheduled) { 20375SN/A Tick event_time; 204180SN/A paramIn(cp, section, base + ".event_time", event_time); 2051129SN/A doneEvent.schedule(event_time); 2061129SN/A } 2072114SN/A} 2082680Sktlim@umich.edu 2094194Ssaidi@eecs.umich.eduLinkDelayEvent::LinkDelayEvent() 2101129SN/A : Event(&mainEventQueue), link(NULL) 2111129SN/A{ 2121129SN/A setFlags(AutoSerialize); 2132680Sktlim@umich.edu setFlags(AutoDelete); 214180SN/A} 2152680Sktlim@umich.edu 2162680Sktlim@umich.eduLinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr p, Tick when) 2172680Sktlim@umich.edu : Event(&mainEventQueue), link(l), packet(p) 218180SN/A{ 219180SN/A setFlags(AutoSerialize); 2202680Sktlim@umich.edu setFlags(AutoDelete); 2214095Sbinkertn@umich.edu schedule(when); 2224095Sbinkertn@umich.edu} 2232SN/A 2242SN/Avoid 2252378SN/ALinkDelayEvent::process() 2262378SN/A{ 2272378SN/A link->txComplete(packet); 2282378SN/A} 2292378SN/A 2302378SN/Avoid 2313162Ssaidi@eecs.umich.eduLinkDelayEvent::serialize(ostream &os) 2323162Ssaidi@eecs.umich.edu{ 2332378SN/A paramOut(os, "type", string("LinkDelayEvent")); 2342378SN/A Event::serialize(os); 2352378SN/A 2362378SN/A EtherLink *parent = link->parent; 2371070SN/A bool number = link->number; 2381070SN/A SERIALIZE_OBJPTR(parent); 2391070SN/A SERIALIZE_SCALAR(number); 2402378SN/A 2411984SN/A packet->serialize("packet", os); 2422378SN/A} 2431070SN/A 2441070SN/A 2451070SN/Avoid 2461070SN/ALinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) 2471070SN/A{ 2481070SN/A Event::unserialize(cp, section); 2492378SN/A 2501984SN/A EtherLink *parent; 2512378SN/A bool number; 2521070SN/A UNSERIALIZE_OBJPTR(parent); 2532SN/A UNSERIALIZE_SCALAR(number); 2542SN/A 2552SN/A link = parent->link[number]; 2562SN/A 2572SN/A packet = new PacketData(16384); 2582SN/A packet->unserialize("packet", cp, section); 2592SN/A} 2602SN/A 2612SN/A 2622SN/ASerializable * 2632SN/ALinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion) 2642SN/A{ 2652SN/A return new LinkDelayEvent(); 2662SN/A} 2672SN/A 2682SN/AREGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent) 2692SN/A 2702SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 2712902Ssaidi@eecs.umich.edu 2722902Ssaidi@eecs.umich.edu SimObjectParam<EtherInt *> int1; 2732902Ssaidi@eecs.umich.edu SimObjectParam<EtherInt *> int2; 2744762Snate@binkert.org Param<double> speed; 2752424SN/A Param<Tick> delay; 2764762Snate@binkert.org Param<Tick> delay_var; 2774762Snate@binkert.org SimObjectParam<EtherDump *> dump; 2782424SN/A 2792424SN/AEND_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 2804762Snate@binkert.org 2812424SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) 2822902Ssaidi@eecs.umich.edu 2832424SN/A INIT_PARAM(int1, "interface 1"), 2842424SN/A INIT_PARAM(int2, "interface 2"), 2852424SN/A INIT_PARAM(speed, "link speed in bits per second"), 2862424SN/A INIT_PARAM(delay, "transmit delay of packets in us"), 287 INIT_PARAM(delay_var, "Difference in amount of time to traverse wire"), 288 INIT_PARAM(dump, "object to dump network packets to") 289 290END_INIT_SIM_OBJECT_PARAMS(EtherLink) 291 292CREATE_SIM_OBJECT(EtherLink) 293{ 294 return new EtherLink(getInstanceName(), int1, int2, speed, delay, delay_var, 295 dump); 296} 297 298REGISTER_SIM_OBJECT("EtherLink", EtherLink) 299