From 5eab6c4b414aef5801d825ab65c0e303a5bbe2e2 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 11 Apr 2005 15:32:06 -0400 Subject: [PATCH] Make the notion of a global event tick independent of the actual CPU cycle ticks. This allows the user to have CPUs of different frequencies, and also allows frequencies and latencies that are not evenly divisible by the CPU frequency. For now, the CPU frequency is still set to the global frequency, but soon, we'll hopefully make the global frequency fixed at something like 1THz and set all other frequencies independently. arch/alpha/ev5.cc: The cycles counter is based on the current cpu cycle. cpu/base_cpu.cc: frequency isn't the cpu parameter anymore, cycleTime is. cpu/base_cpu.hh: frequency isn't the cpu parameter anymore, cycleTime is. create several public functions for getting the cpu frequency and the numbers of ticks for a given number of cycles, etc. cpu/memtest/memtest.cc: cpu/simple_cpu/simple_cpu.cc: cpu/simple_cpu/simple_cpu.hh: cpu/trace/trace_cpu.cc: Now that ticks aren't cpu cycles, fixup code to advance by the proper number of ticks. cpu/memtest/memtest.hh: cpu/trace/trace_cpu.hh: Provide a function to get the number of ticks for a given number of cycles. dev/alpha_console.cc: Update for changes in the way that frequencies and latencies are accessed. Move some stuff to init() dev/alpha_console.hh: Need a pointer to the system and the cpu to get the frequency so we can pass the info to the console code. dev/etherbus.cc: dev/etherbus.hh: dev/etherlink.cc: dev/etherlink.hh: dev/ethertap.cc: dev/ide_disk.hh: dev/ns_gige.cc: dev/ns_gige.hh: update for changes in the way bandwidths are passed from python to C++ to accomidate the new way that ticks works. dev/ide_disk.cc: update for changes in the way bandwidths are passed from python to C++ to accomidate the new way that ticks works. Add some extra debugging printfs dev/platform.cc: dev/sinic.cc: dev/sinic.hh: outline the constructor and destructor dev/platform.hh: outline the constructor and destructor. don't keep track of the interrupt frequency. Only provide the accessor function. dev/tsunami.cc: dev/tsunami.hh: outline the constructor and destructor Don't set the interrupt frequency here. Get it from the actual device that does the interrupting. dev/tsunami_io.cc: dev/tsunami_io.hh: Make the interrupt interval a configuration parameter. (And convert the interval to the new latency/frequency stuff in the python) kern/linux/linux_system.cc: update for changes in the way bandwidths are passed from python to C++ to accomidate the new way that ticks works. For now, we must get the boot cpu's frequency as a parameter since allowing the system to have a pointer to the boot cpu would cause a cycle. kern/tru64/tru64_system.cc: For now, we must get the boot cpu's frequency as a parameter since allowing the system to have a pointer to the boot cpu would cause a cycle. python/m5/config.py: Fix support for cycle_time relative latencies and frequencies. Add support for getting a NetworkBandwidth or a MemoryBandwidth. python/m5/objects/BaseCPU.mpy: All CPUs now have a cycle_time. The default is the global frequency, but it is now possible to set the global frequency to some large value (like 1THz) and set each CPU frequency independently. python/m5/objects/BaseCache.mpy: python/m5/objects/Ide.mpy: Make this a Latency parameter python/m5/objects/BaseSystem.mpy: We need to pass the boot CPU's frequency to the system python/m5/objects/Ethernet.mpy: Update parameter types to use latency and bandwidth types python/m5/objects/Platform.mpy: this frequency isn't needed. We get it from the clock interrupt. python/m5/objects/Tsunami.mpy: The clock generator should hold the frequency sim/eventq.hh: Need to remove this assertion because the writeback event queue is different from the CPU's event queue which can cause this assertion to fail. sim/process.cc: Fix comment. sim/system.hh: Struct member to hold the boot CPU's frequency. sim/universe.cc: remove unneeded variable. --HG-- extra : convert_revision : 51efe4041095234bf458d9b3b0d417f4cae16fdc --- arch/alpha/ev5.cc | 2 +- cpu/base_cpu.cc | 5 +- cpu/base_cpu.hh | 14 +++-- cpu/memtest/memtest.cc | 2 +- cpu/memtest/memtest.hh | 3 + cpu/simple_cpu/simple_cpu.cc | 6 +- cpu/simple_cpu/simple_cpu.hh | 6 +- cpu/trace/trace_cpu.cc | 4 +- cpu/trace/trace_cpu.hh | 2 + dev/alpha_console.cc | 21 ++++--- dev/alpha_console.hh | 10 ++- dev/etherbus.cc | 27 ++++---- dev/etherbus.hh | 4 +- dev/etherlink.cc | 13 ++-- dev/etherlink.hh | 2 +- dev/ethertap.cc | 7 ++- dev/ide_disk.cc | 14 +++-- dev/ide_disk.hh | 2 +- dev/ns_gige.cc | 21 ++++--- dev/ns_gige.hh | 5 ++ dev/platform.cc | 9 +++ dev/platform.hh | 16 ++--- dev/sinic.cc | 16 ++--- dev/sinic.hh | 3 + dev/tsunami.cc | 13 ++-- dev/tsunami.hh | 2 +- dev/tsunami_io.cc | 31 ++++++---- dev/tsunami_io.hh | 19 +++--- kern/linux/linux_system.cc | 10 ++- kern/tru64/tru64_system.cc | 4 ++ python/m5/config.py | 102 ++++++++++++++++++++++++++----- python/m5/objects/BaseCPU.mpy | 2 + python/m5/objects/BaseCache.mpy | 2 +- python/m5/objects/BaseSystem.mpy | 2 + python/m5/objects/Ethernet.mpy | 39 ++++++------ python/m5/objects/Ide.mpy | 2 +- python/m5/objects/Platform.mpy | 1 - python/m5/objects/Tsunami.mpy | 2 +- sim/eventq.hh | 6 +- sim/process.cc | 4 +- sim/system.hh | 8 ++- sim/universe.cc | 2 - 42 files changed, 301 insertions(+), 164 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 2e32da531..d75f4a865 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -297,7 +297,7 @@ ExecContext::readIpr(int idx, Fault &fault) case AlphaISA::IPR_CC: retval |= ipr[idx] & ULL(0xffffffff00000000); - retval |= curTick & ULL(0x00000000ffffffff); + retval |= cpu->curCycle() & ULL(0x00000000ffffffff); break; case AlphaISA::IPR_VA: diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc index 74e57baa6..9d94c575c 100644 --- a/cpu/base_cpu.cc +++ b/cpu/base_cpu.cc @@ -51,11 +51,12 @@ int maxThreadsPerCPU = 1; #ifdef FULL_SYSTEM BaseCPU::BaseCPU(Params *p) - : SimObject(p->name), frequency(p->freq), checkInterrupts(true), + : SimObject(p->name), cycleTime(p->cycleTime), checkInterrupts(true), params(p), number_of_threads(p->numberOfThreads), system(p->system) #else BaseCPU::BaseCPU(Params *p) - : SimObject(p->name), params(p), number_of_threads(p->numberOfThreads) + : SimObject(p->name), cycleTime(p->cycleTime), params(p), + number_of_threads(p->numberOfThreads) #endif { // add self to global list of CPUs diff --git a/cpu/base_cpu.hh b/cpu/base_cpu.hh index f346f4ec5..ea12460db 100644 --- a/cpu/base_cpu.hh +++ b/cpu/base_cpu.hh @@ -46,9 +46,17 @@ class ExecContext; class BaseCPU : public SimObject { + protected: + // CPU's clock period in terms of the number of ticks of curTime. + Tick cycleTime; + + public: + inline Tick frequency() const { return Clock::Frequency / cycleTime; } + inline Tick cycles(int numCycles) const { return cycleTime * numCycles; } + inline Tick curCycle() const { return curTick / cycleTime; } + #ifdef FULL_SYSTEM protected: - Tick frequency; uint64_t interrupts[NumInterruptLevels]; uint64_t intstatus; @@ -67,8 +75,6 @@ class BaseCPU : public SimObject bool check_interrupts() const { return intstatus != 0; } uint64_t intr_status() const { return intstatus; } - - Tick getFreq() const { return frequency; } #endif protected: @@ -100,7 +106,7 @@ class BaseCPU : public SimObject Counter max_insts_all_threads; Counter max_loads_any_thread; Counter max_loads_all_threads; - Tick freq; + Tick cycleTime; bool functionTrace; Tick functionTraceStart; #ifdef FULL_SYSTEM diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc index 14b119880..86d03e162 100644 --- a/cpu/memtest/memtest.cc +++ b/cpu/memtest/memtest.cc @@ -225,7 +225,7 @@ void MemTest::tick() { if (!tickEvent.scheduled()) - tickEvent.schedule(curTick + 1); + tickEvent.schedule(curTick + cycles(1)); if (++noResponseCycles >= 500000) { cerr << name() << ": deadlocked at cycle " << curTick << endl; diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh index 45b2d24e8..ed25cf374 100644 --- a/cpu/memtest/memtest.hh +++ b/cpu/memtest/memtest.hh @@ -60,6 +60,9 @@ class MemTest : public SimObject // register statistics virtual void regStats(); + + inline Tick cycles(int numCycles) const { return numCycles; } + // main simulation loop (one cycle) void tick(); diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 6a95a52c2..719768bf1 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -809,7 +809,7 @@ SimpleCPU::tick() status() == DcacheMissStall); if (status() == Running && !tickEvent.scheduled()) - tickEvent.schedule(curTick + 1); + tickEvent.schedule(curTick + cycles(1)); } @@ -834,6 +834,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) SimObjectParam workload; #endif // FULL_SYSTEM + Param cycle_time; SimObjectParam icache; SimObjectParam dcache; @@ -865,6 +866,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU) INIT_PARAM(workload, "processes to run"), #endif // FULL_SYSTEM + INIT_PARAM(cycle_time, "cpu cycle time"), INIT_PARAM(icache, "L1 instruction cache object"), INIT_PARAM(dcache, "L1 data cache object"), INIT_PARAM(defer_registration, "defer system registration (for sampling)"), @@ -890,7 +892,7 @@ CREATE_SIM_OBJECT(SimpleCPU) params->max_loads_any_thread = max_loads_any_thread; params->max_loads_all_threads = max_loads_all_threads; params->deferRegistration = defer_registration; - params->freq = ticksPerSecond; + params->cycleTime = cycle_time; params->functionTrace = function_trace; params->functionTraceStart = function_trace_start; params->icache_interface = (icache) ? icache->getInterface() : NULL; diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index f245a7bba..2056ff707 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -80,12 +80,12 @@ class SimpleCPU : public BaseCPU TickEvent tickEvent; /// Schedule tick event, regardless of its current state. - void scheduleTickEvent(int delay) + void scheduleTickEvent(int numCycles) { if (tickEvent.squashed()) - tickEvent.reschedule(curTick + delay); + tickEvent.reschedule(curTick + cycles(numCycles)); else if (!tickEvent.scheduled()) - tickEvent.schedule(curTick + delay); + tickEvent.schedule(curTick + cycles(numCycles)); } /// Unschedule tick event, regardless of its current state. diff --git a/cpu/trace/trace_cpu.cc b/cpu/trace/trace_cpu.cc index 1902d0be4..a0e4ef24c 100644 --- a/cpu/trace/trace_cpu.cc +++ b/cpu/trace/trace_cpu.cc @@ -108,10 +108,10 @@ TraceCPU::tick() if (mainEventQueue.empty()) { new SimExitEvent("Finshed Memory Trace"); } else { - tickEvent.schedule(mainEventQueue.nextEventTime() + 1); + tickEvent.schedule(mainEventQueue.nextEventTime() + cycles(1)); } } else { - tickEvent.schedule(max(curTick + 1, nextCycle)); + tickEvent.schedule(max(curTick + cycles(1), nextCycle)); } } diff --git a/cpu/trace/trace_cpu.hh b/cpu/trace/trace_cpu.hh index cdac4bb4f..9b80e325d 100644 --- a/cpu/trace/trace_cpu.hh +++ b/cpu/trace/trace_cpu.hh @@ -105,6 +105,8 @@ class TraceCPU : public SimObject MemInterface *dcache_interface, MemTraceReader *data_trace); + inline Tick cycles(int numCycles) { return numCycles; } + /** * Perform all the accesses for one cycle. */ diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 8309ea16d..01ce17dd5 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -56,10 +56,10 @@ using namespace std; AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, - System *system, BaseCPU *cpu, Platform *p, + System *s, BaseCPU *c, Platform *p, int num_cpus, MemoryController *mmu, Addr a, HierParams *hier, Bus *bus) - : PioDevice(name, p), disk(d), console(cons), addr(a) + : PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), addr(a) { mmu->add_child(this, RangeSize(addr, size)); @@ -71,15 +71,9 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, alphaAccess = new AlphaAccess; alphaAccess->last_offset = size - 1; - alphaAccess->kernStart = system->getKernelStart(); - alphaAccess->kernEnd = system->getKernelEnd(); - alphaAccess->entryPoint = system->getKernelEntry(); alphaAccess->version = ALPHA_ACCESS_VERSION; alphaAccess->numCPUs = num_cpus; - alphaAccess->mem_size = system->physmem->size(); - alphaAccess->cpuClock = cpu->getFreq() / 1000000; - alphaAccess->intrClockFrequency = platform->intrFrequency(); alphaAccess->diskUnit = 1; alphaAccess->diskCount = 0; @@ -93,6 +87,17 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, alphaAccess->align2 = 0; } +void +AlphaConsole::init() +{ + alphaAccess->kernStart = system->getKernelStart(); + alphaAccess->kernEnd = system->getKernelEnd(); + alphaAccess->entryPoint = system->getKernelEntry(); + alphaAccess->mem_size = system->physmem->size(); + alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz + alphaAccess->intrClockFrequency = platform->intrFrequency(); +} + Fault AlphaConsole::read(MemReqPtr &req, uint8_t *data) { diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index 96b0a22c2..5685d7342 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -83,16 +83,24 @@ class AlphaConsole : public PioDevice /** the system console (the terminal) is accessable from the console */ SimConsole *console; + /** a pointer to the system we are running in */ + System *system; + + /** a pointer to the CPU boot cpu */ + BaseCPU *cpu; + Addr addr; static const Addr size = 0x80; // equal to sizeof(alpha_access); public: /** Standard Constructor */ AlphaConsole(const std::string &name, SimConsole *cons, SimpleDisk *d, - System *system, BaseCPU *cpu, Platform *platform, + System *s, BaseCPU *c, Platform *platform, int num_cpus, MemoryController *mmu, Addr addr, HierParams *hier, Bus *bus); + virtual void init(); + /** * memory mapped reads and writes */ diff --git a/dev/etherbus.cc b/dev/etherbus.cc index 82722383c..ab2314c02 100644 --- a/dev/etherbus.cc +++ b/dev/etherbus.cc @@ -45,12 +45,12 @@ using namespace std; -EtherBus::EtherBus(const string &name, double rate, bool loop, +EtherBus::EtherBus(const string &name, double speed, bool loop, EtherDump *packet_dump) - : SimObject(name), ticks_per_byte(rate), loopback(loop), - event(&mainEventQueue, this), - sender(0), dump(packet_dump) -{ } + : SimObject(name), ticksPerByte(speed), loopback(loop), + event(&mainEventQueue, this), sender(0), dump(packet_dump) +{ +} void EtherBus::txDone() @@ -93,9 +93,9 @@ EtherBus::send(EtherInt *sndr, PacketPtr &pkt) packet = pkt; sender = sndr; - int delay = (int)ceil(((double)pkt->length * ticks_per_byte) + 1.0); + int delay = (int)ceil(((double)pkt->length * ticksPerByte) + 1.0); DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", - delay, ticks_per_byte); + delay, ticksPerByte); event.schedule(curTick + delay); return true; @@ -104,25 +104,22 @@ EtherBus::send(EtherInt *sndr, PacketPtr &pkt) BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherBus) Param loopback; - Param speed; + Param speed; SimObjectParam packet_dump; END_DECLARE_SIM_OBJECT_PARAMS(EtherBus) BEGIN_INIT_SIM_OBJECT_PARAMS(EtherBus) - INIT_PARAM_DFLT(loopback, - "send the packet back to the interface from which it came", - true), - INIT_PARAM_DFLT(speed, "bus speed in bits per second", 100000000), - INIT_PARAM_DFLT(packet_dump, "object to dump network packets to", NULL) + INIT_PARAM(loopback, "send the packet back to the sending interface"), + INIT_PARAM(speed, "bus speed in ticks per byte"), + INIT_PARAM(packet_dump, "object to dump network packets to") END_INIT_SIM_OBJECT_PARAMS(EtherBus) CREATE_SIM_OBJECT(EtherBus) { - double rate = ((double)ticksPerSecond * 8.0) / (double)speed; - return new EtherBus(getInstanceName(), rate, loopback, packet_dump); + return new EtherBus(getInstanceName(), speed, loopback, packet_dump); } REGISTER_SIM_OBJECT("EtherBus", EtherBus) diff --git a/dev/etherbus.hh b/dev/etherbus.hh index 716636c79..2ce118b59 100644 --- a/dev/etherbus.hh +++ b/dev/etherbus.hh @@ -44,7 +44,7 @@ class EtherBus : public SimObject protected: typedef std::list devlist_t; devlist_t devlist; - double ticks_per_byte; + double ticksPerByte; bool loopback; protected: @@ -66,7 +66,7 @@ class EtherBus : public SimObject EtherDump *dump; public: - EtherBus(const std::string &name, double ticks_per_byte, bool loopback, + EtherBus(const std::string &name, double speed, bool loopback, EtherDump *dump); virtual ~EtherBus() {} diff --git a/dev/etherlink.cc b/dev/etherlink.cc index ba0fa705c..d63f4b3ad 100644 --- a/dev/etherlink.cc +++ b/dev/etherlink.cc @@ -48,12 +48,9 @@ using namespace std; EtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1, - Tick speed, Tick dly, EtherDump *dump) + double rate, Tick delay, EtherDump *dump) : SimObject(name) { - double rate = ((double)ticksPerSecond * 8.0) / (double)speed; - Tick delay = dly * Clock::Int::us; - link[0] = new Link(name + ".link0", this, 0, rate, delay, dump); link[1] = new Link(name + ".link1", this, 1, rate, delay, dump); @@ -271,7 +268,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) SimObjectParam int1; SimObjectParam int2; - Param speed; + Param speed; Param delay; SimObjectParam dump; @@ -281,9 +278,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) INIT_PARAM(int1, "interface 1"), INIT_PARAM(int2, "interface 2"), - INIT_PARAM_DFLT(speed, "link speed in bits per second", 100000000), - INIT_PARAM_DFLT(delay, "transmit delay of packets in us", 0), - INIT_PARAM_DFLT(dump, "object to dump network packets to", NULL) + INIT_PARAM(speed, "link speed in bits per second"), + INIT_PARAM(delay, "transmit delay of packets in us"), + INIT_PARAM(dump, "object to dump network packets to") END_INIT_SIM_OBJECT_PARAMS(EtherLink) diff --git a/dev/etherlink.hh b/dev/etherlink.hh index 28ab61301..e19471343 100644 --- a/dev/etherlink.hh +++ b/dev/etherlink.hh @@ -118,7 +118,7 @@ class EtherLink : public SimObject public: EtherLink(const std::string &name, EtherInt *peer0, EtherInt *peer1, - Tick speed, Tick delay, EtherDump *dump); + double rate, Tick delay, EtherDump *dump); virtual ~EtherLink(); virtual void serialize(std::ostream &os); diff --git a/dev/ethertap.cc b/dev/ethertap.cc index 807765d91..d0474b115 100644 --- a/dev/ethertap.cc +++ b/dev/ethertap.cc @@ -237,9 +237,10 @@ EtherTap::process(int revent) DPRINTF(Ethernet, "bus busy...buffer for retransmission\n"); packetBuffer.push(packet); if (!txEvent.scheduled()) - txEvent.schedule(curTick + 1000); - } else if (dump) + txEvent.schedule(curTick + retryTime); + } else if (dump) { dump->dump(packet); + } } } @@ -259,7 +260,7 @@ EtherTap::retransmit() } if (!packetBuffer.empty() && !txEvent.scheduled()) - txEvent.schedule(curTick + 1000); + txEvent.schedule(curTick + retryTime); } //===================================================================== diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index 213fc6a97..90a57bd2f 100644 --- a/dev/ide_disk.cc +++ b/dev/ide_disk.cc @@ -55,8 +55,8 @@ using namespace std; IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys, - int id, int delay) - : SimObject(name), ctrl(NULL), image(img), physmem(phys), + int id, Tick delay) + : SimObject(name), ctrl(NULL), image(img), physmem(phys), diskDelay(delay), dmaTransferEvent(this), dmaReadWaitEvent(this), dmaWriteWaitEvent(this), dmaPrdReadEvent(this), dmaReadEvent(this), dmaWriteEvent(this) @@ -64,9 +64,6 @@ IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys, // Reset the device state reset(id); - // calculate disk delay in microseconds - diskDelay = (delay * ticksPerSecond / 100000); - // fill out the drive ID structure memset(&driveID, 0, sizeof(struct hd_driveid)); @@ -354,8 +351,11 @@ IdeDisk::dmaPrdReadDone() void IdeDisk::doDmaRead() { + /** @TODO we need to figure out what the delay actually will be */ Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize); + DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n", + diskDelay, totalDiskDelay); if (dmaInterface) { if (dmaInterface->busy()) { // reschedule after waiting period @@ -455,8 +455,12 @@ IdeDisk::dmaReadDone() void IdeDisk::doDmaWrite() { + /** @TODO we need to figure out what the delay actually will be */ Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize); + DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n", + diskDelay, totalDiskDelay); + if (dmaInterface) { if (dmaInterface->busy()) { // reschedule after waiting period diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh index 9c6eea623..703625595 100644 --- a/dev/ide_disk.hh +++ b/dev/ide_disk.hh @@ -248,7 +248,7 @@ class IdeDisk : public SimObject * @param disk_delay The disk delay in milliseconds */ IdeDisk(const std::string &name, DiskImage *img, PhysicalMemory *phys, - int id, int disk_delay); + int id, Tick disk_delay); /** * Delete the data buffer. diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index bc3103540..47631642c 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -94,8 +94,8 @@ NSGigE::NSGigE(Params *p) : PciDev(p), ioEnable(false), txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size), txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL), - txXferLen(0), rxXferLen(0), txState(txIdle), txEnable(false), - CTDD(false), + txXferLen(0), rxXferLen(0), cycleTime(p->cycle_time), + txState(txIdle), txEnable(false), CTDD(false), txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle), rxEnable(false), CRDD(false), rxPktBytes(0), rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false), @@ -138,7 +138,7 @@ NSGigE::NSGigE(Params *p) } - intrDelay = p->intr_delay * Clock::Int::us; + intrDelay = p->intr_delay; dmaReadDelay = p->dma_read_delay; dmaWriteDelay = p->dma_write_delay; dmaReadFactor = p->dma_read_factor; @@ -1833,7 +1833,7 @@ NSGigE::transmit() if (!txFifo.empty() && !txEvent.scheduled()) { DPRINTF(Ethernet, "reschedule transmit\n"); - txEvent.schedule(curTick + 1000); + txEvent.schedule(curTick + retryTime); } } @@ -2231,9 +2231,9 @@ NSGigE::transferDone() DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n"); if (txEvent.scheduled()) - txEvent.reschedule(curTick + 1); + txEvent.reschedule(curTick + cycles(1)); else - txEvent.schedule(curTick + 1); + txEvent.schedule(curTick + cycles(1)); } bool @@ -2682,6 +2682,7 @@ REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt) BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) Param addr; + Param cycle_time; Param tx_delay; Param rx_delay; Param intr_delay; @@ -2713,9 +2714,10 @@ END_DECLARE_SIM_OBJECT_PARAMS(NSGigE) BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000), - INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000), - INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0), + INIT_PARAM(cycle_time, "State machine processor frequency"), + INIT_PARAM(tx_delay, "Transmit Delay"), + INIT_PARAM(rx_delay, "Receive Delay"), + INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"), INIT_PARAM(mmu, "Memory Controller"), INIT_PARAM(physmem, "Physical Memory"), INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true), @@ -2756,6 +2758,7 @@ CREATE_SIM_OBJECT(NSGigE) params->deviceNum = pci_dev; params->functionNum = pci_func; + params->cycle_time = cycle_time; params->intr_delay = intr_delay; params->pmem = physmem; params->tx_delay = tx_delay; diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index 58060edac..544a300c3 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -175,6 +175,10 @@ class NSGigE : public PciDev ns_desc txDescCache; ns_desc rxDescCache; + /* state machine cycle time */ + Tick cycleTime; + inline Tick cycles(int numCycles) const { return numCycles * cycleTime; } + /* tx State Machine */ TxState txState; bool txEnable; @@ -324,6 +328,7 @@ class NSGigE : public PciDev HierParams *hier; Bus *header_bus; Bus *payload_bus; + Tick cycle_time; Tick intr_delay; Tick tx_delay; Tick rx_delay; diff --git a/dev/platform.cc b/dev/platform.cc index cf012352b..adced0c5f 100644 --- a/dev/platform.cc +++ b/dev/platform.cc @@ -32,6 +32,15 @@ using namespace std; +Platform::Platform(const string &name, IntrControl *intctrl, PciConfigAll *pci) + : SimObject(name), intrctrl(intctrl), pciconfig(pci) +{ +} + +Platform::~Platform() +{ +} + void Platform::postPciInt(int line) { diff --git a/dev/platform.hh b/dev/platform.hh index 47ca6209f..eb56546be 100644 --- a/dev/platform.hh +++ b/dev/platform.hh @@ -31,8 +31,8 @@ * Generic interface for platforms */ -#ifndef __PLATFORM_HH_ -#define __PLATFORM_HH_ +#ifndef __DEV_PLATFORM_HH__ +#define __DEV_PLATFORM_HH__ #include "sim/sim_object.hh" #include "targetarch/isa_traits.hh" @@ -47,20 +47,16 @@ class Platform : public SimObject public: /** Pointer to the interrupt controller */ IntrControl *intrctrl; + /** Pointer to the PCI configuration space */ PciConfigAll *pciconfig; /** Pointer to the UART, set by the uart */ Uart *uart; - int interrupt_frequency; - public: - Platform(const std::string &name, IntrControl *intctrl, - PciConfigAll *pci, int intrFreq) - : SimObject(name), intrctrl(intctrl), pciconfig(pci), - interrupt_frequency(intrFreq) {} - virtual ~Platform() {} + Platform(const std::string &name, IntrControl *intctrl, PciConfigAll *pci); + virtual ~Platform(); virtual void postConsoleInt() = 0; virtual void clearConsoleInt() = 0; virtual Tick intrFrequency() = 0; @@ -69,4 +65,4 @@ class Platform : public SimObject virtual Addr pciToDma(Addr pciAddr) const; }; -#endif // __PLATFORM_HH_ +#endif // __DEV_PLATFORM_HH__ diff --git a/dev/sinic.cc b/dev/sinic.cc index 13e16afae..9535a58ca 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -78,10 +78,9 @@ const char *TxStateStrings[] = // Sinic PCI Device // Base::Base(Params *p) - : PciDev(p), rxEnable(false), txEnable(false), - intrDelay(p->intr_delay * Clock::Int::us), - intrTick(0), cpuIntrEnable(false), cpuPendingIntr(false), intrEvent(0), - interface(NULL) + : PciDev(p), rxEnable(false), txEnable(false), cycleTime(p->cycle_time), + intrDelay(p->intr_delay), intrTick(0), cpuIntrEnable(false), + cpuPendingIntr(false), intrEvent(0), interface(NULL) { } @@ -888,7 +887,7 @@ Device::transmit() reschedule: if (!txFifo.empty() && !txEvent.scheduled()) { DPRINTF(Ethernet, "reschedule transmit\n"); - txEvent.schedule(curTick + 1000); + txEvent.schedule(curTick + retryTime); } } @@ -1025,9 +1024,9 @@ Device::transferDone() DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n"); if (txEvent.scheduled()) - txEvent.reschedule(curTick + 1); + txEvent.reschedule(curTick + cycles(1)); else - txEvent.schedule(curTick + 1); + txEvent.schedule(curTick + cycles(1)); } bool @@ -1361,6 +1360,7 @@ REGISTER_SIM_OBJECT("SinicInt", Interface) BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device) + Param cycle_time; Param tx_delay; Param rx_delay; Param intr_delay; @@ -1393,6 +1393,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(Device) BEGIN_INIT_SIM_OBJECT_PARAMS(Device) + INIT_PARAM(cycle_time, "State machine cycle time"), INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000), INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000), INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0), @@ -1431,6 +1432,7 @@ CREATE_SIM_OBJECT(Device) params->name = getInstanceName(); params->intr_delay = intr_delay; params->physmem = physmem; + params->cycle_time = cycle_time; params->tx_delay = tx_delay; params->rx_delay = rx_delay; params->mmu = mmu; diff --git a/dev/sinic.hh b/dev/sinic.hh index 9b8920f3b..6597357a2 100644 --- a/dev/sinic.hh +++ b/dev/sinic.hh @@ -48,6 +48,8 @@ class Base : public PciDev protected: bool rxEnable; bool txEnable; + Tick cycleTime; + inline Tick cycles(int numCycles) const { return numCycles * cycleTime; } protected: Tick intrDelay; @@ -79,6 +81,7 @@ class Base : public PciDev public: struct Params : public PciDev::Params { + Tick cycle_time; Tick intr_delay; }; diff --git a/dev/tsunami.cc b/dev/tsunami.cc index c84dde9bc..55a2c5ea6 100644 --- a/dev/tsunami.cc +++ b/dev/tsunami.cc @@ -45,9 +45,9 @@ using namespace std; -Tsunami::Tsunami(const string &name, System *s, - IntrControl *ic, PciConfigAll *pci, int intr_freq) - : Platform(name, ic, pci, intr_freq), system(s) +Tsunami::Tsunami(const string &name, System *s, IntrControl *ic, + PciConfigAll *pci) + : Platform(name, ic, pci), system(s) { // set the back pointer from the system to myself system->platform = this; @@ -109,7 +109,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tsunami) SimObjectParam system; SimObjectParam intrctrl; SimObjectParam pciconfig; - Param interrupt_frequency; END_DECLARE_SIM_OBJECT_PARAMS(Tsunami) @@ -117,15 +116,13 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Tsunami) INIT_PARAM(system, "system"), INIT_PARAM(intrctrl, "interrupt controller"), - INIT_PARAM(pciconfig, "PCI configuration"), - INIT_PARAM_DFLT(interrupt_frequency, "frequency of interrupts", 1024) + INIT_PARAM(pciconfig, "PCI configuration") END_INIT_SIM_OBJECT_PARAMS(Tsunami) CREATE_SIM_OBJECT(Tsunami) { - return new Tsunami(getInstanceName(), system, intrctrl, pciconfig, - interrupt_frequency); + return new Tsunami(getInstanceName(), system, intrctrl, pciconfig); } REGISTER_SIM_OBJECT("Tsunami", Tsunami) diff --git a/dev/tsunami.hh b/dev/tsunami.hh index 7722c8417..70dc506fd 100644 --- a/dev/tsunami.hh +++ b/dev/tsunami.hh @@ -89,7 +89,7 @@ class Tsunami : public Platform * @param intrFreq frequency that interrupts happen */ Tsunami(const std::string &name, System *s, IntrControl *intctrl, - PciConfigAll *pci, int intrFreq); + PciConfigAll *pci); /** * Return the interrupting frequency to AlphaAccess diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index 1e4f44346..895888a09 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -53,18 +53,18 @@ using namespace std; #define UNIX_YEAR_OFFSET 52 // Timer Event for Periodic interrupt of RTC -TsunamiIO::RTCEvent::RTCEvent(Tsunami* t) - : Event(&mainEventQueue), tsunami(t) +TsunamiIO::RTCEvent::RTCEvent(Tsunami* t, Tick i) + : Event(&mainEventQueue), tsunami(t), interval(i) { DPRINTF(MC146818, "RTC Event Initilizing\n"); - schedule(curTick + ticksPerSecond/RTC_RATE); + schedule(curTick + interval); } void TsunamiIO::RTCEvent::process() { DPRINTF(MC146818, "RTC Timer Interrupt\n"); - schedule(curTick + ticksPerSecond/RTC_RATE); + schedule(curTick + interval); //Actually interrupt the processor here tsunami->cchip->postRTC(); } @@ -72,7 +72,7 @@ TsunamiIO::RTCEvent::process() const char * TsunamiIO::RTCEvent::description() { - return "tsunami RTC 1024Hz interrupt"; + return "tsunami RTC interrupt"; } void @@ -119,7 +119,7 @@ TsunamiIO::ClockEvent::process() void TsunamiIO::ClockEvent::Program(int count) { - DPRINTF(Tsunami, "Timer set to curTick + %d\n", count); + DPRINTF(Tsunami, "Timer set to curTick + %d\n", count * interval); schedule(curTick + count * interval); status = 0; } @@ -166,8 +166,8 @@ TsunamiIO::ClockEvent::unserialize(Checkpoint *cp, const std::string §ion) TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time, Addr a, MemoryController *mmu, HierParams *hier, Bus *bus, - Tick pio_latency) - : PioDevice(name, t), addr(a), tsunami(t), rtc(t) + Tick pio_latency, Tick ci) + : PioDevice(name, t), addr(a), clockInterval(ci), tsunami(t), rtc(t, ci) { mmu->add_child(this, RangeSize(addr, size)); @@ -188,6 +188,12 @@ TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time, picInterrupting = false; } +Tick +TsunamiIO::frequency() const +{ + return Clock::Frequency / clockInterval; +} + void TsunamiIO::set_time(time_t t) { @@ -485,26 +491,27 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) SimObjectParam io_bus; Param pio_latency; SimObjectParam hier; + Param frequency; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO) INIT_PARAM(tsunami, "Tsunami"), - INIT_PARAM_DFLT(time, "System time to use " - "(0 for actual time, default is 1/1/06", ULL(1136073600)), + INIT_PARAM(time, "System time to use (0 for actual time"), INIT_PARAM(mmu, "Memory Controller"), INIT_PARAM(addr, "Device Address"), INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), + INIT_PARAM(frequency, "clock interrupt frequency") END_INIT_SIM_OBJECT_PARAMS(TsunamiIO) CREATE_SIM_OBJECT(TsunamiIO) { return new TsunamiIO(getInstanceName(), tsunami, time, addr, mmu, hier, - io_bus, pio_latency); + io_bus, pio_latency, frequency); } REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO) diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh index a9f044ec9..9d74ccdef 100644 --- a/dev/tsunami_io.hh +++ b/dev/tsunami_io.hh @@ -38,9 +38,6 @@ #include "dev/tsunami.hh" #include "sim/eventq.hh" -/** How often the RTC interrupts */ -static const int RTC_RATE = 1024; - /* * Tsunami I/O device is a catch all for all the south bridge stuff we care * to implement. @@ -136,10 +133,14 @@ class TsunamiIO : public PioDevice protected: /** A pointer back to tsunami to create interrupt the processor. */ Tsunami* tsunami; + Tick interval; + public: - /** RTC Event initializes the RTC event by scheduling an event - * RTC_RATE times pre second. */ - RTCEvent(Tsunami* t); + /** + * RTC Event initializes the RTC event by scheduling an event + * RTC_RATE times pre second. + */ + RTCEvent(Tsunami* t, Tick i); /** * Interrupth the processor and reschedule the event. @@ -191,6 +192,8 @@ class TsunamiIO : public PioDevice /** Is the pic interrupting right now or not. */ bool picInterrupting; + Tick clockInterval; + /** A pointer to the Tsunami device which be belong to */ Tsunami *tsunami; @@ -225,7 +228,7 @@ class TsunamiIO : public PioDevice * Return the freqency of the RTC * @return interrupt rate of the RTC */ - Tick frequency() const { return RTC_RATE; } + Tick frequency() const; /** * Initialize all the data for devices supported by Tsunami I/O. @@ -237,7 +240,7 @@ class TsunamiIO : public PioDevice */ TsunamiIO(const std::string &name, Tsunami *t, time_t init_time, Addr a, MemoryController *mmu, HierParams *hier, Bus *bus, - Tick pio_latency); + Tick pio_latency, Tick ci); /** * Create the tm struct from seconds since 1970 diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index 4ac03143e..b6aa9c6f2 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -68,7 +68,8 @@ LinuxSystem::LinuxSystem(Params *p) physmem->dma_addr(paddr, sizeof(uint64_t)); if (est_cycle_frequency) - *(uint64_t *)est_cycle_frequency = htoa(ticksPerSecond); + *(uint64_t *)est_cycle_frequency = + Clock::Frequency / p->boot_cpu_frequency; } @@ -206,8 +207,8 @@ LinuxSystem::setDelayLoop(ExecContext *xc) uint8_t *loops_per_jiffy = physmem->dma_addr(paddr, sizeof(uint32_t)); - Tick cpuFreq = xc->cpu->getFreq(); - Tick intrFreq = platform->interrupt_frequency; + Tick cpuFreq = xc->cpu->frequency(); + Tick intrFreq = platform->intrFrequency(); *(uint32_t *)loops_per_jiffy = (uint32_t)((cpuFreq / intrFreq) * 0.9988); } @@ -215,6 +216,7 @@ LinuxSystem::setDelayLoop(ExecContext *xc) BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) + Param boot_cpu_frequency; SimObjectParam memctrl; SimObjectParam physmem; @@ -237,6 +239,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem) + INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), INIT_PARAM(memctrl, "memory controller"), INIT_PARAM(physmem, "phsyical memory"), INIT_PARAM(kernel, "file that contains the kernel code"), @@ -258,6 +261,7 @@ CREATE_SIM_OBJECT(LinuxSystem) { System::Params *p = new System::Params; p->name = getInstanceName(); + p->boot_cpu_frequency = boot_cpu_frequency; p->memctrl = memctrl; p->physmem = physmem; p->kernel_path = kernel; diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc index 7a2e033d8..e0ec31a43 100644 --- a/kern/tru64/tru64_system.cc +++ b/kern/tru64/tru64_system.cc @@ -28,6 +28,7 @@ #include "base/loader/symtab.hh" #include "base/trace.hh" +#include "cpu/base_cpu.hh" #include "cpu/exec_context.hh" #include "kern/tru64/tru64_events.hh" #include "kern/tru64/tru64_system.hh" @@ -116,6 +117,7 @@ Tru64System::~Tru64System() BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System) + Param boot_cpu_frequency; SimObjectParam memctrl; SimObjectParam physmem; @@ -137,6 +139,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(Tru64System) BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System) + INIT_PARAM(boot_cpu_frequency, "frequency of the boot cpu"), INIT_PARAM(memctrl, "memory controller"), INIT_PARAM(physmem, "phsyical memory"), INIT_PARAM(kernel, "file that contains the kernel code"), @@ -157,6 +160,7 @@ CREATE_SIM_OBJECT(Tru64System) { System::Params *p = new System::Params; p->name = getInstanceName(); + p->boot_cpu_frequency = boot_cpu_frequency; p->memctrl = memctrl; p->physmem = physmem; p->kernel_path = kernel; diff --git a/python/m5/config.py b/python/m5/config.py index e260c57a7..74988109b 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -265,7 +265,6 @@ def isParamContext(value): except: return False - class_decorator = 'M5M5_SIMOBJECT_' expr_decorator = 'M5M5_EXPRESSION_' dot_decorator = '_M5M5_DOT_' @@ -652,6 +651,14 @@ class Node(object): 'parent.any matched more than one: %s %s' % \ (obj.path, child.path) obj = child + for param in self.params: + if isConfigNode(param.ptype): + continue + if issubclass(param.ptype, realtype): + if obj is not None: + raise AttributeError, \ + 'parent.any matched more than one: %s' % obj.path + obj = param.value return obj, obj is not None try: @@ -672,7 +679,7 @@ class Node(object): return Proxy.getindex(value, index), True elif obj.param_names.has_key(last): value = obj.param_names[last] - realtype._convert(value.value) + #realtype._convert(value.value) return Proxy.getindex(value.value, index), True except KeyError: pass @@ -731,9 +738,18 @@ class Node(object): raise AttributeError, 'Parameter with no value' value = param.convert(param.value) + if hasattr(value, 'relative') and value.relative and value: + if param.name == 'cycle_time': + start = self.parent + else: + start = self + val = start.unproxy(parent.cycle_time, + (Frequency, Latency, ClockPeriod)) + value.clock = Frequency._convert(val) string = param.string(value) except Exception, e: - msg = 'exception in %s:%s\n%s' % (self.path, param.name, e) + msg = 'exception in %s:%s=%s\n%s' % (self.path, param.name, + value, e) e.args = (msg, ) raise @@ -765,6 +781,9 @@ class Node(object): raise AttributeError, 'Parameter with no value' value = param.convert(param.value) + if param.ptype in (Frequency, Latency, ClockPeriod): + val = self.parent.unproxy(parent.frequency, Frequency) + param.clock = Frequency._convert(val) string = param.string(value) except Exception, e: msg = 'exception in %s:%s\n%s' % (self.name, param.name, e) @@ -1382,27 +1401,33 @@ class RootFrequency(float,ParamType): _convert = classmethod(_convert) def _string(cls, value): - return '%d' % int(value) + return '%d' % int(round(value)) _string = classmethod(_string) class ClockPeriod(float,ParamType): _cpp_param_decl = 'Tick' def __new__(cls, value): + absolute = False relative = False try: val = toClockPeriod(value) except ValueError, e: - relative = True if value.endswith('f'): val = float(value[:-1]) if val: val = 1 / val + relative = True elif value.endswith('c'): val = float(value[:-1]) + relative = True + elif value.endswith('t'): + val = float(value[:-1]) + absolute = True else: raise e self = super(cls, ClockPeriod).__new__(cls, val) + self.absolute = absolute self.relative = relative return self @@ -1411,10 +1436,14 @@ class ClockPeriod(float,ParamType): _convert = classmethod(_convert) def _string(cls, value): - if not value.relative: - value *= root_frequency + if value and not value.absolute: + if value.relative: + base = root_frequency / value.clock + else: + base = root_frequency + value *= base - return '%d' % int(value) + return '%d' % int(round(value)) _string = classmethod(_string) class Frequency(float,ParamType): @@ -1439,15 +1468,21 @@ class Frequency(float,ParamType): _convert = classmethod(_convert) def _string(cls, value): - if not value.relative: - value = root_frequency / value + if value: + if value.relative: + base = root_frequency / value.clock + else: + base = root_frequency + + value = base / value - return '%d' % int(value) + return '%d' % int(round(value)) _string = classmethod(_string) class Latency(float,ParamType): _cpp_param_decl = 'Tick' def __new__(cls, value): + absolute = False relative = False try: val = toLatency(value) @@ -1455,9 +1490,13 @@ class Latency(float,ParamType): if value.endswith('c'): val = float(value[:-1]) relative = True + elif value.endswith('t'): + val = float(value[:-1]) + absolute = True else: raise e self = super(cls, Latency).__new__(cls, val) + self.absolute = absolute self.relative = relative return self @@ -1466,11 +1505,44 @@ class Latency(float,ParamType): _convert = classmethod(_convert) def _string(cls, value): - if not value.relative: - value *= root_frequency - return '%d' % value + if value and not value.absolute: + if value.relative: + base = root_frequency / value.clock + else: + base = root_frequency + value *= base + return '%d' % int(round(value)) _string = classmethod(_string) +class NetworkBandwidth(float,ParamType): + _cpp_param_decl = 'float' + def __new__(cls, value): + val = toNetworkBandwidth(value) / 8.0 + return super(cls, NetworkBandwidth).__new__(cls, val) + + def _convert(cls, value): + return cls(value) + _convert = classmethod(_convert) + + def _string(cls, value): + value = root_frequency / value + return '%f' % value + _string = classmethod(_string) + +class MemoryBandwidth(float,ParamType): + _cpp_param_decl = 'float' + def __new__(self, value): + val = toMemoryBandwidth(value) + return super(cls, MemoryBandwidth).__new__(cls, val) + + def _convert(cls, value): + return cls(value) + _convert = classmethod(_convert) + + def _string(cls, value): + value = root_frequency / value + return '%f' % value + _string = classmethod(_string) # Some memory range specifications use this as a default upper bound. MaxAddr = Addr.max @@ -1518,6 +1590,6 @@ __all__ = ['ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam', 'Int32', 'UInt32', 'Int64', 'UInt64', 'Counter', 'Addr', 'Tick', 'Percent', 'MemorySize', 'RootFrequency', 'Frequency', 'Latency', - 'ClockPeriod', + 'ClockPeriod', 'NetworkBandwidth', 'MemoryBandwidth', 'Range', 'AddrRange', 'MaxAddr', 'MaxTick', 'AllMemory', 'NULL', 'NextEthernetAddr', 'instantiate'] diff --git a/python/m5/objects/BaseCPU.mpy b/python/m5/objects/BaseCPU.mpy index d84e30e53..707d1b94f 100644 --- a/python/m5/objects/BaseCPU.mpy +++ b/python/m5/objects/BaseCPU.mpy @@ -23,3 +23,5 @@ simobj BaseCPU(SimObject): defer_registration = Param.Bool(False, "defer registration with system (for sampling)") + + cycle_time = Param.ClockPeriod(parent.frequency, "clock speed") diff --git a/python/m5/objects/BaseCache.mpy b/python/m5/objects/BaseCache.mpy index a9bda5c99..da0c7c50e 100644 --- a/python/m5/objects/BaseCache.mpy +++ b/python/m5/objects/BaseCache.mpy @@ -10,7 +10,7 @@ simobj BaseCache(BaseMem): block_size = Param.Int("block size in bytes") compressed_bus = Param.Bool(False, "This cache connects to a compressed memory") - compression_latency = Param.Int(0, + compression_latency = Param.Latency('0c', "Latency in cycles of compression algorithm") do_copy = Param.Bool(False, "perform fast copies in the cache") hash_delay = Param.Int(1, "time in cycles of hash access") diff --git a/python/m5/objects/BaseSystem.mpy b/python/m5/objects/BaseSystem.mpy index 450b6a58e..29fe3e1d9 100644 --- a/python/m5/objects/BaseSystem.mpy +++ b/python/m5/objects/BaseSystem.mpy @@ -1,6 +1,8 @@ simobj BaseSystem(SimObject): type = 'BaseSystem' abstract = True + boot_cpu_frequency = Param.ClockPeriod(parent.cpu[0].cycle_time, + "Boot Processor Frequency") memctrl = Param.MemoryController(parent.any, "memory controller") physmem = Param.PhysicalMemory(parent.any, "phsyical memory") kernel = Param.String("file that contains the kernel code") diff --git a/python/m5/objects/Ethernet.mpy b/python/m5/objects/Ethernet.mpy index 3acd8d04d..ed95ce233 100644 --- a/python/m5/objects/Ethernet.mpy +++ b/python/m5/objects/Ethernet.mpy @@ -10,16 +10,15 @@ simobj EtherLink(SimObject): type = 'EtherLink' int1 = Param.EtherInt("interface 1") int2 = Param.EtherInt("interface 2") - delay = Param.Tick(0, "transmit delay of packets in us") - speed = Param.Tick(100000000, "link speed in bits per second") + delay = Param.Latency('0us', "packet transmit delay") + speed = Param.NetworkBandwidth('100Mbps', "link speed") dump = Param.EtherDump(NULL, "dump object") simobj EtherBus(SimObject): type = 'EtherBus' - loopback = Param.Bool(True, - "send packet back to the interface from which it came") + loopback = Param.Bool(True, "send packet back to the sending interface") dump = Param.EtherDump(NULL, "dump object") - speed = Param.UInt64(100000000, "bus speed in bits per second") + speed = Param.NetworkBandwidth('100Mbps', "bus speed in bits per second") simobj EtherTap(EtherInt): type = 'EtherTap' @@ -38,16 +37,16 @@ simobj EtherDev(DmaDevice): dma_data_free = Param.Bool(False, "DMA of Data is free") dma_desc_free = Param.Bool(False, "DMA of Descriptors is free") - dma_read_delay = Param.Tick(0, "fixed delay for dma reads") - dma_read_factor = Param.Tick(0, "multiplier for dma reads") - dma_write_delay = Param.Tick(0, "fixed delay for dma writes") - dma_write_factor = Param.Tick(0, "multiplier for dma writes") + dma_read_delay = Param.Latency('0us', "fixed delay for dma reads") + dma_read_factor = Param.Latency('0us', "multiplier for dma reads") + dma_write_delay = Param.Latency('0us', "fixed delay for dma writes") + dma_write_factor = Param.Latency('0us', "multiplier for dma writes") rx_filter = Param.Bool(True, "Enable Receive Filter") - rx_delay = Param.Tick(1000, "Receive Delay") - tx_delay = Param.Tick(1000, "Transmit Delay") + rx_delay = Param.Latency('1us', "Receive Delay") + tx_delay = Param.Latency('1us', "Transmit Delay") - intr_delay = Param.Tick(0, "Interrupt Delay in microseconds") + intr_delay = Param.Latency('0us', "Interrupt Delay") payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload") physmem = Param.PhysicalMemory(parent.any, "Physical Memory") tlaser = Param.Turbolaser(parent.any, "Turbolaser") @@ -57,21 +56,23 @@ simobj NSGigE(PciDevice): hardware_address = Param.EthernetAddr(NextEthernetAddr, "Ethernet Hardware Address") + cycle_time = Param.Frequency('100MHz', "State machine processor frequency") + dma_data_free = Param.Bool(False, "DMA of Data is free") dma_desc_free = Param.Bool(False, "DMA of Descriptors is free") - dma_read_delay = Param.Tick(0, "fixed delay for dma reads") - dma_read_factor = Param.Tick(0, "multiplier for dma reads") - dma_write_delay = Param.Tick(0, "fixed delay for dma writes") - dma_write_factor = Param.Tick(0, "multiplier for dma writes") + dma_read_delay = Param.Latency('0us', "fixed delay for dma reads") + dma_read_factor = Param.Latency('0us', "multiplier for dma reads") + dma_write_delay = Param.Latency('0us', "fixed delay for dma writes") + dma_write_factor = Param.Latency('0us', "multiplier for dma writes") rx_filter = Param.Bool(True, "Enable Receive Filter") - rx_delay = Param.Tick(1000, "Receive Delay") - tx_delay = Param.Tick(1000, "Transmit Delay") + rx_delay = Param.Latency('1us', "Receive Delay") + tx_delay = Param.Latency('1us', "Transmit Delay") rx_fifo_size = Param.MemorySize('128kB', "max size in bytes of rxFifo") tx_fifo_size = Param.MemorySize('128kB', "max size in bytes of txFifo") - intr_delay = Param.Tick(0, "Interrupt Delay in microseconds") + intr_delay = Param.Latency('0us', "Interrupt Delay in microseconds") payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload") physmem = Param.PhysicalMemory(parent.any, "Physical Memory") diff --git a/python/m5/objects/Ide.mpy b/python/m5/objects/Ide.mpy index 786109efa..02b1d9567 100644 --- a/python/m5/objects/Ide.mpy +++ b/python/m5/objects/Ide.mpy @@ -4,7 +4,7 @@ class IdeID(Enum): vals = ['master', 'slave'] simobj IdeDisk(SimObject): type = 'IdeDisk' - delay = Param.Tick(1, "Fixed disk delay in microseconds") + delay = Param.Latency('1us', "Fixed disk delay in microseconds") driveID = Param.IdeID('master', "Drive ID") image = Param.DiskImage("Disk image") physmem = Param.PhysicalMemory(parent.any, "Physical memory") diff --git a/python/m5/objects/Platform.mpy b/python/m5/objects/Platform.mpy index a71ab3b77..166f3f4a1 100644 --- a/python/m5/objects/Platform.mpy +++ b/python/m5/objects/Platform.mpy @@ -1,5 +1,4 @@ simobj Platform(SimObject): type = 'Platform' abstract = True - interrupt_frequency = Param.Tick(1200, "frequency of interrupts") intrctrl = Param.IntrControl(parent.any, "interrupt controller") diff --git a/python/m5/objects/Tsunami.mpy b/python/m5/objects/Tsunami.mpy index a8471cee2..c17eae121 100644 --- a/python/m5/objects/Tsunami.mpy +++ b/python/m5/objects/Tsunami.mpy @@ -5,7 +5,6 @@ simobj Tsunami(Platform): type = 'Tsunami' pciconfig = Param.PciConfigAll("PCI configuration") system = Param.BaseSystem(parent.any, "system") - interrupt_frequency = Param.Int(1024, "frequency of interrupts") simobj TsunamiCChip(FooPioDevice): type = 'TsunamiCChip' @@ -19,6 +18,7 @@ simobj TsunamiIO(FooPioDevice): time = Param.UInt64(1136073600, "System time to use (0 for actual time, default is 1/1/06)") tsunami = Param.Tsunami(parent.any, "Tsunami") + frequency = Param.Frequency('1024Hz', "frequency of interrupts") simobj TsunamiPChip(FooPioDevice): type = 'TsunamiPChip' diff --git a/sim/eventq.hh b/sim/eventq.hh index d62e7df10..a0bb851c0 100644 --- a/sim/eventq.hh +++ b/sim/eventq.hh @@ -305,7 +305,11 @@ class EventQueue : public Serializable if (nextTick() > when) break; - assert(head->when() >= when && "event scheduled in the past"); + /** + * @todo this assert is a good bug catcher. I need to + * make it true again. + */ + //assert(head->when() >= when && "event scheduled in the past"); serviceOne(); } } diff --git a/sim/process.cc b/sim/process.cc index c18b31da7..3541fd040 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -162,9 +162,7 @@ Process::startup() // first exec context for this process... initialize & enable ExecContext *xc = execContexts[0]; - // mark this context as active. - // activate with zero delay so that we start ticking right - // away on cycle 0 + // mark this context as active so it will start ticking. xc->activate(0); } diff --git a/sim/system.hh b/sim/system.hh index 07881ff01..4f003f282 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -37,14 +37,15 @@ #include "kern/system_events.hh" #include "sim/sim_object.hh" +class BaseCPU; +class ExecContext; +class GDBListener; class MemoryController; +class ObjectFile; class PhysicalMemory; class Platform; class RemoteGDB; -class GDBListener; class SymbolTable; -class ObjectFile; -class ExecContext; namespace Kernel { class Binning; } class System : public SimObject @@ -101,6 +102,7 @@ class System : public SimObject struct Params { std::string name; + Tick boot_cpu_frequency; MemoryController *memctrl; PhysicalMemory *physmem; uint64_t init_param; diff --git a/sim/universe.cc b/sim/universe.cc index 5ae41eefd..ecf54c2e7 100644 --- a/sim/universe.cc +++ b/sim/universe.cc @@ -108,8 +108,6 @@ CREATE_SIM_OBJECT(Root) outputStream = simout.find(output_file); Root *root = new Root(getInstanceName()); - ticksPerSecond = frequency; - using namespace Clock; Frequency = frequency; Float::s = static_cast(Frequency); -- 2.30.2