sc_clock.cc revision 13379:c4765c7fa0df
12381SN/A/* 210694SMarco.Balboni@ARM.com * Copyright 2018 Google, Inc. 38949Sandreas.hansson@arm.com * 48949Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 58949Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 68949Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 78949Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 88949Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 98949Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 108949Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 118949Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 128949Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 138949Sandreas.hansson@arm.com * this software without specific prior written permission. 142592SN/A * 157636Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262381SN/A * 272381SN/A * Authors: Gabe Black 282381SN/A */ 292381SN/A 302381SN/A#include "base/logging.hh" 312381SN/A#include "base/types.hh" 322381SN/A#include "sim/core.hh" 332381SN/A#include "sim/eventq.hh" 342381SN/A#include "systemc/core/kernel.hh" 352381SN/A#include "systemc/core/process_types.hh" 362381SN/A#include "systemc/core/sched_event.hh" 372381SN/A#include "systemc/core/scheduler.hh" 382381SN/A#include "systemc/ext/channel/messages.hh" 392381SN/A#include "systemc/ext/channel/sc_clock.hh" 402665Ssaidi@eecs.umich.edu#include "systemc/ext/core/sc_main.hh" 412665Ssaidi@eecs.umich.edu#include "systemc/ext/core/sc_module.hh" // for sc_gen_unique_name 422665Ssaidi@eecs.umich.edu#include "systemc/ext/utils/sc_report_handler.hh" 432665Ssaidi@eecs.umich.edu 449031Sandreas.hansson@arm.comnamespace sc_gem5 452381SN/A{ 462381SN/A 472381SN/Aclass ClockTick : public ScEvent 482381SN/A{ 492662Sstever@eecs.umich.edu private: 502381SN/A ::sc_core::sc_time _period; 512381SN/A std::string name; 522381SN/A Process *p; 532381SN/A ProcessMemberFuncWrapper<::sc_core::sc_clock> funcWrapper; 542381SN/A 558229Snate@binkert.org public: 563348Sbinkertn@umich.edu ClockTick(::sc_core::sc_clock *clock, bool to, 573348Sbinkertn@umich.edu ::sc_core::sc_time _period) : 583348Sbinkertn@umich.edu ScEvent([this]() { tick(); }), 595735Snate@binkert.org _period(_period), name(clock->basename()), p(nullptr), 604024Sbinkertn@umich.edu funcWrapper(clock, to ? &::sc_core::sc_clock::tickUp : 615735Snate@binkert.org &::sc_core::sc_clock::tickDown) 623940Ssaidi@eecs.umich.edu { 635314Sstever@gmail.com name += std::string(to ? "_posedge_action" : "_negedge_action"); 646216Snate@binkert.org name = ::sc_core::sc_gen_unique_name(name.c_str()); 652392SN/A } 664167Sbinkertn@umich.edu 672394SN/A void 688737Skoansin.tan@gmail.com createProcess() 693349Sbinkertn@umich.edu { 702394SN/A p = new Method(name.c_str(), &funcWrapper, true); 712812Srdreslin@umich.edu p->dontInitialize(true); 722812Srdreslin@umich.edu scheduler.reg(p); 734022Sstever@eecs.umich.edu } 744022Sstever@eecs.umich.edu 755735Snate@binkert.org ~ClockTick() 765735Snate@binkert.org { 774022Sstever@eecs.umich.edu if (scheduled()) 785735Snate@binkert.org scheduler.deschedule(this); 795735Snate@binkert.org if (p) 805735Snate@binkert.org p->popListNode(); 814022Sstever@eecs.umich.edu } 824022Sstever@eecs.umich.edu 834022Sstever@eecs.umich.edu void 844022Sstever@eecs.umich.edu tick() 854473Sstever@eecs.umich.edu { 865319Sstever@gmail.com scheduler.schedule(this, _period); 874022Sstever@eecs.umich.edu p->ready(); 884022Sstever@eecs.umich.edu } 894022Sstever@eecs.umich.edu}; 9010883Sali.jafri@arm.com 914022Sstever@eecs.umich.edu}; 924022Sstever@eecs.umich.edu 934022Sstever@eecs.umich.edunamespace sc_core 944022Sstever@eecs.umich.edu{ 9510886Sandreas.hansson@arm.com 964022Sstever@eecs.umich.edusc_clock::sc_clock() : 977465Ssteve.reinhardt@amd.com sc_clock(sc_gen_unique_name("clock"), sc_time(1.0, SC_NS), 984628Sstever@eecs.umich.edu 0.5, SC_ZERO_TIME, true) 997465Ssteve.reinhardt@amd.com{} 1007465Ssteve.reinhardt@amd.com 1014022Sstever@eecs.umich.edusc_clock::sc_clock(const char *name) : 1024022Sstever@eecs.umich.edu sc_clock(name, sc_time(1.0, SC_NS), 0.5, SC_ZERO_TIME, true) 10310885Sandreas.hansson@arm.com{} 10410885Sandreas.hansson@arm.com 1054626Sstever@eecs.umich.edusc_clock::sc_clock(const char *name, const sc_time &period, 1064626Sstever@eecs.umich.edu double duty_cycle, const sc_time &start_time, 1077669Ssteve.reinhardt@amd.com bool posedge_first) : 1084626Sstever@eecs.umich.edu sc_interface(), sc_signal<bool>(name, posedge_first ? false : true), 1094040Ssaidi@eecs.umich.edu _period(period), _dutyCycle(duty_cycle), _startTime(start_time), 1104040Ssaidi@eecs.umich.edu _posedgeFirst(posedge_first) 1115650Sgblack@eecs.umich.edu{ 1125650Sgblack@eecs.umich.edu if (period == SC_ZERO_TIME) { 1134870Sstever@eecs.umich.edu std::string msg = 1144870Sstever@eecs.umich.edu "increase the period: clock '" + 1154870Sstever@eecs.umich.edu std::string(name) + "'"; 1164870Sstever@eecs.umich.edu SC_REPORT_ERROR(SC_ID_CLOCK_PERIOD_ZERO_, msg.c_str()); 1174870Sstever@eecs.umich.edu } 1184870Sstever@eecs.umich.edu 1198436SBrad.Beckmann@amd.com if (duty_cycle * period == SC_ZERO_TIME) { 1208436SBrad.Beckmann@amd.com std::string msg = 1215314Sstever@gmail.com "increase the period or increase the duty cycle: clock '" + 1225314Sstever@gmail.com std::string(name) + "'"; 1238184Ssomayeh@cs.wisc.edu SC_REPORT_ERROR(SC_ID_CLOCK_HIGH_TIME_ZERO_, msg.c_str()); 12410886Sandreas.hansson@arm.com } 12510886Sandreas.hansson@arm.com 1264022Sstever@eecs.umich.edu if (duty_cycle * period == period) { 1274022Sstever@eecs.umich.edu std::string msg = 1284022Sstever@eecs.umich.edu "increase the period or decrease the duty cycle: clock '" + 1294022Sstever@eecs.umich.edu std::string(name) + "'"; 1305735Snate@binkert.org SC_REPORT_ERROR(SC_ID_CLOCK_LOW_TIME_ZERO_, msg.c_str()); 1315735Snate@binkert.org } 1325735Snate@binkert.org 1334022Sstever@eecs.umich.edu _gem5UpEdge = new ::sc_gem5::ClockTick(this, true, period); 1344022Sstever@eecs.umich.edu _gem5DownEdge = new ::sc_gem5::ClockTick(this, false, period); 1354626Sstever@eecs.umich.edu} 1364626Sstever@eecs.umich.edu 1377465Ssteve.reinhardt@amd.comsc_clock::sc_clock(const char *name, double period_v, sc_time_unit period_tu, 1384022Sstever@eecs.umich.edu double duty_cycle) : 1394626Sstever@eecs.umich.edu sc_clock(name, sc_time(period_v, period_tu), duty_cycle, SC_ZERO_TIME, 1404626Sstever@eecs.umich.edu true) 1414626Sstever@eecs.umich.edu{} 1424626Sstever@eecs.umich.edu 1434022Sstever@eecs.umich.edusc_clock::sc_clock(const char *name, double period_v, sc_time_unit period_tu, 1444022Sstever@eecs.umich.edu double duty_cycle, double start_time_v, 1456076Sgblack@eecs.umich.edu sc_time_unit start_time_tu, bool posedge_first) : 1464626Sstever@eecs.umich.edu sc_clock(name, sc_time(period_v, period_tu), duty_cycle, 1474870Sstever@eecs.umich.edu sc_time(start_time_v, start_time_tu), posedge_first) 1485314Sstever@gmail.com{} 1498184Ssomayeh@cs.wisc.edu 1504022Sstever@eecs.umich.edusc_clock::sc_clock(const char *name, double period, double duty_cycle, 1514022Sstever@eecs.umich.edu double start_time, bool posedge_first) : 1524022Sstever@eecs.umich.edu sc_clock(name, sc_time(period, true), duty_cycle, 1535735Snate@binkert.org sc_time(start_time, true), posedge_first) 1545735Snate@binkert.org{} 1555735Snate@binkert.org 1565735Snate@binkert.orgsc_clock::~sc_clock() 1575735Snate@binkert.org{ 1585735Snate@binkert.org if (_gem5UpEdge->scheduled()) 1595735Snate@binkert.org ::sc_gem5::scheduler.deschedule(_gem5UpEdge); 1604022Sstever@eecs.umich.edu if (_gem5DownEdge->scheduled()) 1615735Snate@binkert.org ::sc_gem5::scheduler.deschedule(_gem5DownEdge); 1625735Snate@binkert.org delete _gem5UpEdge; 1634022Sstever@eecs.umich.edu delete _gem5DownEdge; 1645735Snate@binkert.org} 1654022Sstever@eecs.umich.edu 1664022Sstever@eecs.umich.eduvoid 1674022Sstever@eecs.umich.edusc_clock::write(const bool &) 1685735Snate@binkert.org{ 1694022Sstever@eecs.umich.edu panic("write() called on sc_clock."); 1704022Sstever@eecs.umich.edu} 1714022Sstever@eecs.umich.edu 1724022Sstever@eecs.umich.educonst sc_time &sc_clock::period() const { return _period; } 1734022Sstever@eecs.umich.edudouble sc_clock::duty_cycle() const { return _dutyCycle; } 1744022Sstever@eecs.umich.educonst sc_time &sc_clock::start_time() const { return _startTime; } 1755735Snate@binkert.orgbool sc_clock::posedge_first() const { return _posedgeFirst; } 1765735Snate@binkert.org 1775735Snate@binkert.orgconst sc_time & 1784022Sstever@eecs.umich.edusc_clock::time_stamp() 1794022Sstever@eecs.umich.edu{ 1804022Sstever@eecs.umich.edu return sc_time_stamp(); 1814022Sstever@eecs.umich.edu} 1824022Sstever@eecs.umich.edu 18310583SCurtis.Dunham@arm.comvoid 18410583SCurtis.Dunham@arm.comsc_clock::before_end_of_elaboration() 18510583SCurtis.Dunham@arm.com{ 18610583SCurtis.Dunham@arm.com _gem5UpEdge->createProcess(); 18710583SCurtis.Dunham@arm.com _gem5DownEdge->createProcess(); 18810583SCurtis.Dunham@arm.com if (_posedgeFirst) { 18910583SCurtis.Dunham@arm.com ::sc_gem5::scheduler.schedule(_gem5UpEdge, _startTime); 19010583SCurtis.Dunham@arm.com ::sc_gem5::scheduler.schedule(_gem5DownEdge, 19110570Sandreas.hansson@arm.com _startTime + _period * _dutyCycle); 19210570Sandreas.hansson@arm.com } else { 19310570Sandreas.hansson@arm.com ::sc_gem5::scheduler.schedule(_gem5DownEdge, _startTime); 19410570Sandreas.hansson@arm.com ::sc_gem5::scheduler.schedule(_gem5UpEdge, 19510570Sandreas.hansson@arm.com _startTime + _period * (1.0 - _dutyCycle)); 19610570Sandreas.hansson@arm.com } 1974022Sstever@eecs.umich.edu} 1986102Sgblack@eecs.umich.edu 19910343SCurtis.Dunham@arm.com} // namespace sc_core 20010343SCurtis.Dunham@arm.com