fastmodel: create base class for EVS CPU
authorEarl Ou <shunhsingou@google.com>
Mon, 1 Feb 2021 01:41:33 +0000 (09:41 +0800)
committerEarl Ou <shunhsingou@google.com>
Tue, 2 Feb 2021 01:07:19 +0000 (01:07 +0000)
Previously we use attribute and event for communication between gem5
SimObject to systemC fastmodel sc_module. Creating a base class allows us
to perform casting once and get all the interface required. Also,
instead of warning on attribute not found, we should make simulator
panic if the sc_module does not provide the interface we need.

Change-Id: I91e1036cb792d556dfc4010e7a0f138b1519b079
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40277
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/fastmodel/CortexA76/cortex_a76.cc
src/arch/arm/fastmodel/CortexA76/evs.cc
src/arch/arm/fastmodel/CortexA76/evs.hh
src/arch/arm/fastmodel/CortexR52/cortex_r52.cc
src/arch/arm/fastmodel/CortexR52/evs.cc
src/arch/arm/fastmodel/CortexR52/evs.hh
src/arch/arm/fastmodel/iris/cpu.cc
src/arch/arm/fastmodel/iris/cpu.hh

index d2b96764e2f0135e6c8c74ddda00be1234ee4906..1decdf97ca57fee74ea1bf503578d4757722f3f8 100644 (file)
@@ -104,16 +104,9 @@ CortexA76Cluster::CortexA76Cluster(const Params &p) :
     for (int i = 0; i < p.cores.size(); i++)
         p.cores[i]->setCluster(this, i);
 
-    sc_core::sc_attr_base *base;
-
-    base = evs->get_attribute(Iris::Gem5CpuClusterAttributeName);
-    auto *gem5_cluster_attr =
-        dynamic_cast<sc_core::sc_attribute<CortexA76Cluster *> *>(base);
-    panic_if(base && !gem5_cluster_attr,
-             "The EVS gem5 CPU cluster attribute was not of type "
-             "sc_attribute<FastModel::CortexA76Cluster *>.");
-    if (gem5_cluster_attr)
-        gem5_cluster_attr->value = this;
+    Iris::BaseCpuEvs *e = dynamic_cast<Iris::BaseCpuEvs *>(evs);
+    panic_if(!e, "EVS should be of type Iris::BaseCpuEvs");
+    e->setCluster(this);
 
     set_evs_param("core.BROADCASTATOMIC", p.BROADCASTATOMIC);
     set_evs_param("core.BROADCASTCACHEMAINT", p.BROADCASTCACHEMAINT);
index 360a5dd494d3969661dd3f3bb75d101c4dcf8766..29d8877f6757f60743571aae6008b415d873b04a 100644 (file)
@@ -39,19 +39,23 @@ namespace FastModel
 
 template <class Types>
 void
-ScxEvsCortexA76<Types>::clockChangeHandler()
+ScxEvsCortexA76<Types>::setClkPeriod(Tick clk_period)
 {
-    clockRateControl->set_mul_div(SimClock::Int::s, clockPeriod.value);
+    clockRateControl->set_mul_div(SimClock::Int::s, clk_period);
+}
+
+template <class Types>
+void
+ScxEvsCortexA76<Types>::setCluster(SimObject *cluster)
+{
+    gem5CpuCluster = dynamic_cast<CortexA76Cluster *>(cluster);
+    panic_if(!gem5CpuCluster, "Cluster should be of type CortexA76Cluster");
 }
 
 template <class Types>
 ScxEvsCortexA76<Types>::ScxEvsCortexA76(
         const sc_core::sc_module_name &mod_name, const Params &p) :
     Base(mod_name), amba(Base::amba, p.name + ".amba", -1),
-    clockChanged(Iris::ClockEventName.c_str()),
-    clockPeriod(Iris::PeriodAttributeName.c_str()),
-    gem5CpuCluster(Iris::Gem5CpuClusterAttributeName.c_str()),
-    sendFunctional(Iris::SendFunctionalAttributeName.c_str()),
     params(p)
 {
     for (int i = 0; i < CoreCount; i++) {
@@ -82,15 +86,6 @@ ScxEvsCortexA76<Types>::ScxEvsCortexA76(
     }
 
     clockRateControl.bind(this->clock_rate_s);
-
-    this->add_attribute(gem5CpuCluster);
-    this->add_attribute(clockPeriod);
-    SC_METHOD(clockChangeHandler);
-    this->dont_initialize();
-    this->sensitive << clockChanged;
-
-    sendFunctional.value = [this](PacketPtr pkt) { sendFunc(pkt); };
-    this->add_attribute(sendFunctional);
 }
 
 template <class Types>
@@ -109,12 +104,10 @@ ScxEvsCortexA76<Types>::before_end_of_elaboration()
 {
     Base::before_end_of_elaboration();
 
-    auto *cluster = gem5CpuCluster.value;
-
-    auto set_on_change = [cluster](
+    auto set_on_change = [this](
             SignalReceiver &recv, ArmInterruptPinGen *gen, int num)
     {
-        auto *pin = gen->get(cluster->getCore(num)->getContext(0));
+        auto *pin = gen->get(gem5CpuCluster->getCore(num)->getContext(0));
         auto handler = [pin](bool status)
         {
             status ? pin->raise() : pin->clear();
@@ -123,15 +116,15 @@ ScxEvsCortexA76<Types>::before_end_of_elaboration()
     };
 
     for (int i = 0; i < CoreCount; i++) {
-        set_on_change(*cnthpirq[i], cluster->params().cnthpirq, i);
-        set_on_change(*cnthvirq[i], cluster->params().cnthvirq, i);
-        set_on_change(*cntpsirq[i], cluster->params().cntpsirq, i);
-        set_on_change(*cntvirq[i], cluster->params().cntvirq, i);
-        set_on_change(*commirq[i], cluster->params().commirq, i);
-        set_on_change(*ctidbgirq[i], cluster->params().ctidbgirq, i);
-        set_on_change(*pmuirq[i], cluster->params().pmuirq, i);
-        set_on_change(*vcpumntirq[i], cluster->params().vcpumntirq, i);
-        set_on_change(*cntpnsirq[i], cluster->params().cntpnsirq, i);
+        set_on_change(*cnthpirq[i], gem5CpuCluster->params().cnthpirq, i);
+        set_on_change(*cnthvirq[i], gem5CpuCluster->params().cnthvirq, i);
+        set_on_change(*cntpsirq[i], gem5CpuCluster->params().cntpsirq, i);
+        set_on_change(*cntvirq[i], gem5CpuCluster->params().cntvirq, i);
+        set_on_change(*commirq[i], gem5CpuCluster->params().commirq, i);
+        set_on_change(*ctidbgirq[i], gem5CpuCluster->params().ctidbgirq, i);
+        set_on_change(*pmuirq[i], gem5CpuCluster->params().pmuirq, i);
+        set_on_change(*vcpumntirq[i], gem5CpuCluster->params().vcpumntirq, i);
+        set_on_change(*cntpnsirq[i], gem5CpuCluster->params().cntpnsirq, i);
     }
 }
 
index e57bdd76395d8863d0bd2be2861db6c48ce6bca4..fa12ff82175d6a2906b50f441793a213e98cccd1 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "arch/arm/fastmodel/amba_ports.hh"
 #include "arch/arm/fastmodel/common/signal_receiver.hh"
+#include "arch/arm/fastmodel/iris/cpu.hh"
 #include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh"
 #include "mem/port_proxy.hh"
 #include "params/FastModelScxEvsCortexA76x1.hh"
@@ -52,7 +53,7 @@ namespace FastModel
 class CortexA76Cluster;
 
 template <class Types>
-class ScxEvsCortexA76 : public Types::Base
+class ScxEvsCortexA76 : public Types::Base, public Iris::BaseCpuEvs
 {
   private:
     static const int CoreCount = Types::CoreCount;
@@ -81,14 +82,7 @@ class ScxEvsCortexA76 : public Types::Base
     std::vector<std::unique_ptr<SignalReceiver>> vcpumntirq;
     std::vector<std::unique_ptr<SignalReceiver>> cntpnsirq;
 
-    sc_core::sc_event clockChanged;
-    sc_core::sc_attribute<Tick> clockPeriod;
-    sc_core::sc_attribute<CortexA76Cluster *> gem5CpuCluster;
-    sc_core::sc_attribute<PortProxy::SendFunctionalFunc> sendFunctional;
-
-    void sendFunc(PacketPtr pkt);
-
-    void clockChangeHandler();
+    CortexA76Cluster *gem5CpuCluster;
 
     const Params &params;
 
@@ -106,6 +100,12 @@ class ScxEvsCortexA76 : public Types::Base
         Base::start_of_simulation();
     }
     void start_of_simulation() override {}
+
+    void sendFunc(PacketPtr pkt) override;
+
+    void setClkPeriod(Tick clk_period) override;
+
+    void setCluster(SimObject *cluster) override;
 };
 
 struct ScxEvsCortexA76x1Types
index 18bb33d487de12e5e48ad6aa7aed8fc983a9d7b7..3a8ac3dc1d2d68b883f49af50479677ea7a153d2 100644 (file)
@@ -99,16 +99,9 @@ CortexR52Cluster::CortexR52Cluster(const Params &p) :
     for (int i = 0; i < p.cores.size(); i++)
         p.cores[i]->setCluster(this, i);
 
-    sc_core::sc_attr_base *base;
-
-    base = evs->get_attribute(Iris::Gem5CpuClusterAttributeName);
-    auto *gem5_cluster_attr =
-        dynamic_cast<sc_core::sc_attribute<CortexR52Cluster *> *>(base);
-    panic_if(base && !gem5_cluster_attr,
-             "The EVS gem5 CPU cluster attribute was not of type "
-             "sc_attribute<FastModel::CortexR52Cluster *>.");
-    if (gem5_cluster_attr)
-        gem5_cluster_attr->value = this;
+    Iris::BaseCpuEvs *e = dynamic_cast<Iris::BaseCpuEvs *>(evs);
+    panic_if(!e, "EVS should be of type Iris::BaseCpuEvs");
+    e->setCluster(this);
 
     set_evs_param("core.CLUSTER_ID", params().CLUSTER_ID);
     set_evs_param("core.DBGROMADDR", params().DBGROMADDR);
index 50ac670f6fa0c33b539ca81110c8ef993ce8df24..cd84aa62e796ec3df435e487e5d2576d93f93a7f 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "arch/arm/fastmodel/CortexR52/evs.hh"
 
+#include "arch/arm/fastmodel/CortexR52/cortex_r52.hh"
 #include "arch/arm/fastmodel/iris/cpu.hh"
 #include "base/logging.hh"
 #include "sim/core.hh"
@@ -37,9 +38,17 @@ namespace FastModel
 
 template <class Types>
 void
-ScxEvsCortexR52<Types>::clockChangeHandler()
+ScxEvsCortexR52<Types>::setClkPeriod(Tick clk_period)
 {
-    clockRateControl->set_mul_div(SimClock::Int::s, clockPeriod.value);
+    clockRateControl->set_mul_div(SimClock::Int::s, clk_period);
+}
+
+template <class Types>
+void
+ScxEvsCortexR52<Types>::setCluster(SimObject *cluster)
+{
+    gem5CpuCluster = dynamic_cast<CortexR52Cluster *>(cluster);
+    panic_if(!gem5CpuCluster, "Cluster should be of type CortexR52Cluster");
 }
 
 template <class Types>
@@ -61,10 +70,6 @@ template <class Types>
 ScxEvsCortexR52<Types>::ScxEvsCortexR52(
         const sc_core::sc_module_name &mod_name, const Params &p) :
     Base(mod_name),
-    clockChanged(Iris::ClockEventName.c_str()),
-    clockPeriod(Iris::PeriodAttributeName.c_str()),
-    gem5CpuCluster(Iris::Gem5CpuClusterAttributeName.c_str()),
-    sendFunctional(Iris::SendFunctionalAttributeName.c_str()),
     params(p)
 {
     for (int i = 0; i < CoreCount; i++)
@@ -77,15 +82,6 @@ ScxEvsCortexR52<Types>::ScxEvsCortexR52(
 
     clockRateControl.bind(this->clock_rate_s);
     signalInterrupt.bind(this->signal_interrupt);
-
-    this->add_attribute(gem5CpuCluster);
-    this->add_attribute(clockPeriod);
-    SC_METHOD(clockChangeHandler);
-    this->dont_initialize();
-    this->sensitive << clockChanged;
-
-    sendFunctional.value = [this](PacketPtr pkt) { sendFunc(pkt); };
-    this->add_attribute(sendFunctional);
 }
 
 template <class Types>
index 3f663020abd7aa7c7d9c239f3d2d8ed7c2afa6b9..e03a32200be14523afb48800218609251177a867 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "arch/arm/fastmodel/amba_ports.hh"
 #include "arch/arm/fastmodel/common/signal_receiver.hh"
+#include "arch/arm/fastmodel/iris/cpu.hh"
 #include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh"
 #include "arch/arm/fastmodel/protocol/signal_interrupt.hh"
 #include "dev/intpin.hh"
@@ -54,7 +55,7 @@ namespace FastModel
 class CortexR52Cluster;
 
 template <class Types>
-class ScxEvsCortexR52 : public Types::Base
+class ScxEvsCortexR52 : public Types::Base, public Iris::BaseCpuEvs
 {
   private:
     static const int CoreCount = Types::CoreCount;
@@ -105,14 +106,7 @@ class ScxEvsCortexR52 : public Types::Base
 
     std::vector<std::unique_ptr<ClstrInt>> spis;
 
-    sc_core::sc_event clockChanged;
-    sc_core::sc_attribute<Tick> clockPeriod;
-    sc_core::sc_attribute<CortexR52Cluster *> gem5CpuCluster;
-    sc_core::sc_attribute<PortProxy::SendFunctionalFunc> sendFunctional;
-
-    void sendFunc(PacketPtr pkt);
-
-    void clockChangeHandler();
+    CortexR52Cluster *gem5CpuCluster;
 
     const Params &params;
 
@@ -141,6 +135,12 @@ class ScxEvsCortexR52 : public Types::Base
         Base::start_of_simulation();
     }
     void start_of_simulation() override {}
+
+    void sendFunc(PacketPtr pkt) override;
+
+    void setClkPeriod(Tick clk_period) override;
+
+    void setCluster(SimObject *cluster) override;
 };
 
 struct ScxEvsCortexR52x1Types
index cf93c8cd5d7f9b9e796a25ae433daef9e93f083b..a155deaf4ce7299a3828ffb724570dce10878493 100644 (file)
@@ -36,30 +36,9 @@ namespace Iris
 
 BaseCPU::BaseCPU(const BaseCPUParams &params, sc_core::sc_module *_evs) :
     ::BaseCPU::BaseCPU(params), evs(_evs),
-    clockEvent(nullptr), periodAttribute(nullptr)
+    evs_base_cpu(dynamic_cast<Iris::BaseCpuEvs *>(_evs))
 {
-    sc_core::sc_attr_base *base;
-
-    const auto &event_vec = evs->get_child_events();
-    auto event_it = std::find_if(event_vec.begin(), event_vec.end(),
-            [](const sc_core::sc_event *e) -> bool {
-                return e->basename() == ClockEventName; });
-    if (event_it != event_vec.end())
-        clockEvent = *event_it;
-
-    base = evs->get_attribute(PeriodAttributeName);
-    periodAttribute = dynamic_cast<sc_core::sc_attribute<Tick> *>(base);
-    panic_if(base && !periodAttribute,
-            "The EVS clock period attribute is not of type "
-            "sc_attribute<Tick>.");
-
-    base = evs->get_attribute(SendFunctionalAttributeName);
-    sendFunctional =
-        dynamic_cast<sc_core::sc_attribute<PortProxy::SendFunctionalFunc> *>(
-                base);
-    panic_if(base && !sendFunctional,
-            "The EVS send functional attribute is not of type "
-            "sc_attribute<PortProxy::SendFunctionalFunc>.");
+    panic_if(!evs_base_cpu, "EVS should be of type BaseCpuEvs");
 
     // Make sure fast model knows we're using debugging mechanisms to control
     // the simulation, and it shouldn't shut down if simulation time stops
index 277258a2f703a22eb99dc21dedcf2849ede9068b..c5dd19f24312a8ea2ebcc49c764cc7590e325ffd 100644 (file)
 namespace Iris
 {
 
-// The name of the event that should be notified when the CPU subsystem needs
-// to adjust it's clock.
-static const std::string ClockEventName = "gem5_clock_period_event";
-// The name of the attribute the subsystem should create which can be set to
-// the desired clock period, in gem5's Ticks.
-static const std::string PeriodAttributeName = "gem5_clock_period_attribute";
-// The name of the attribute the subsystem should create which will be set to
-// a pointer to its corresponding gem5 CPU.
-static const std::string Gem5CpuClusterAttributeName = "gem5_cpu_cluster";
-// The name of the attribute the subsystem should create to hold the
-// sendFunctional delegate for port proxies.
-static const std::string SendFunctionalAttributeName = "gem5_send_functional";
+// The base interface of the EVS used by gem5 BaseCPU below.
+class BaseCpuEvs
+{
+  public:
+    virtual void sendFunc(PacketPtr pkt) = 0;
+    virtual void setClkPeriod(Tick clk_period) = 0;
+    virtual void setCluster(SimObject *cluster) = 0;
+};
 
 // This CPU class adds some mechanisms which help attach the gem5 and fast
 // model CPUs to each other. It acts as a base class for the gem5 CPU, and
@@ -87,32 +83,19 @@ class BaseCPU : public ::BaseCPU
     PortProxy::SendFunctionalFunc
     getSendFunctional() override
     {
-        if (sendFunctional)
-            return sendFunctional->value;
-        return ::BaseCPU::getSendFunctional();
+        return [this] (PacketPtr pkt) { evs_base_cpu->sendFunc(pkt); };
     }
 
   protected:
     sc_core::sc_module *evs;
-
-  private:
-    sc_core::sc_event *clockEvent;
-    sc_core::sc_attribute<Tick> *periodAttribute;
-    sc_core::sc_attribute<PortProxy::SendFunctionalFunc> *sendFunctional;
+    // Hold casted pointer to *evs.
+    Iris::BaseCpuEvs *evs_base_cpu;
 
   protected:
     void
     clockPeriodUpdated() override
     {
-        if (!clockEvent || !periodAttribute) {
-            warn("Unable to notify EVS of clock change, missing:");
-            warn_if(!clockEvent, "  Clock change event");
-            warn_if(!periodAttribute, "  Clock period attribute");
-            return;
-        }
-
-        periodAttribute->value = clockPeriod();
-        clockEvent->notify();
+        evs_base_cpu->setClkPeriod(clockPeriod());
     }
 
     void init() override;