/** * @file tests/fddevs/models.hpp * @author The ARTIS Development Team * See the AUTHORS or Authors.txt file */ /* * ARTIS - the multimodeling and simulation environment * This file is a part of the ARTIS environment * * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef TESTS_FDDEVS_MODELS_HPP #define TESTS_FDDEVS_MODELS_HPP #include #include #include namespace artis { namespace tests { namespace fddevs { enum CRC_state_values { I0 = 0, I1, G, GR, WW, W, DW }; class CRC : public artis::fddevs::Dynamics { public: enum inputs { IN_P }; enum outputs { OUT_G, OUT_W }; CRC(const std::string &name, const artis::fddevs::Context &context) : artis::fddevs::Dynamics(name, context) { input_ports({{IN_P, "p"}}); output_ports({{OUT_G, "g"}, {OUT_W, "w"}}); initial_state(I0); } ~CRC() override = default; void delta_tau(typename common::DoubleTime::type /* t */) override { switch (state()) { case I0: { state(I1); break; } case I1: { state(G); break; } case G: { state(G); break; } case GR: { state(WW); break; } case WW: { state(W); break; } case W: { state(DW); break; } case DW: { state(G); break; } } } void delta_x(typename common::DoubleTime::type /* t */, typename common::DoubleTime::type /* e */, const common::Bag &bag) override { assert(bag.size() == 1); if (bag.at(0).on_port(IN_P) and state() == G) { state(GR); } } common::Bag lambda(typename common::DoubleTime::type /* t */) const override { common::Bag msgs; switch (state()) { case I0: msgs.push_back( artis::common::ExternalEvent(OUT_W, 0)); break; case I1: msgs.push_back( artis::common::ExternalEvent(OUT_G, 1)); break; case G:break; case GR: msgs.push_back( artis::common::ExternalEvent(OUT_G, 0)); break; case WW: msgs.push_back( artis::common::ExternalEvent(OUT_W, 1)); break; case W: msgs.push_back( artis::common::ExternalEvent(OUT_W, 0)); break; case DW: msgs.push_back( artis::common::ExternalEvent(OUT_G, 1)); break; } return msgs; } bool rho(typename common::DoubleTime::type /* time */, const common::Bag &bag) const override { return state() == G and bag.at(0).on_port(IN_P); } typename common::DoubleTime::type tau(typename common::DoubleTime::type /* t */) const override { switch (state()) { case I0:return 0; case I1:return 0; case G:return 10; case GR:return 5; case WW:return 2; case W:return 26; case DW:return 2; } return common::DoubleTime::infinity; } }; enum MXR_state_values { A00 = 0, A01, A10, A11, R11 }; class MXR : public artis::fddevs::Dynamics { public: enum inputs { IN_A, IN_B }; MXR(const std::string &name, const artis::fddevs::Context &context) : artis::fddevs::Dynamics(name, context) { input_ports({{IN_A, "a"}, {IN_B, "b"}}); initial_state(A00); } ~MXR() override = default; void delta_tau(typename common::DoubleTime::type /* t */) override { if (state() == A11) { state(R11); } } void delta_x(typename common::DoubleTime::type /* t */, typename common::DoubleTime::type /* e */, const common::Bag &bag) override { std::for_each(bag.begin(), bag.end(), [this](const artis::common::ExternalEvent &e) { int data; e.data()(data); if (e.on_port(IN_A)) { switch (state()) { case A00: { if (data == 1) { state(A01); } break; } case A01: { if (data == 0) { state(A00); } break; } case A10: { if (data == 1) { state(A11); } break; } case A11: { if (data == 0) { state(A10); } break; } case R11:break; } } else if (e.on_port(IN_B)) { switch (state()) { case A00: { if (data == 1) { state(A10); } break; } case A01: { if (data == 1) { state(A11); } break; } case A10: { if (data == 0) { state(A00); } break; } case A11: { if (data == 0) { state(A01); } break; } case R11:break; } } }); } common::Bag lambda(typename common::DoubleTime::type /* t */) const override { common::Bag msgs; return msgs; } bool rho(typename common::DoubleTime::type /* time */, const common::Bag & /* bag */) const override { return false; } typename common::DoubleTime::type tau(typename common::DoubleTime::type /* t */) const override { if (state() == A11) { return 0.01; } else { return common::DoubleTime::infinity; } } }; enum Beep_state_values { INIT = 0, SEND }; class Beep : public artis::fddevs::Dynamics { public: enum outputs { OUT_P }; Beep(const std::string &name, const artis::fddevs::Context &context) : artis::fddevs::Dynamics(name, context) { output_ports({{OUT_P, "p"}}); initial_state(INIT); } ~Beep() override = default; void delta_tau(typename common::DoubleTime::type /* t */) override { if (state() == INIT) { state(SEND); } } common::Bag lambda(typename common::DoubleTime::type /* t */) const override { common::Bag msgs; switch (state()) { case INIT: msgs.push_back( artis::common::ExternalEvent(OUT_P, 1)); break; case SEND:break; } return msgs; } bool rho(typename common::DoubleTime::type /* time */, const common::Bag & /* bag */) const override { return false; } typename common::DoubleTime::type tau(typename common::DoubleTime::type /* t */) const override { switch (state()) { case INIT:return 27; case SEND:return common::DoubleTime::infinity; } return common::DoubleTime::infinity; } }; } } } // namespace artis tests fddevs #endif