/**
* @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-2022 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::event::Bag &bag) override
{
assert(bag.size() == 1);
if (bag.at(0).on_port(IN_P) and state() == G) {
state(GR);
}
}
common::event::Bag
lambda(typename common::DoubleTime::type /* t */) const override
{
common::event::Bag msgs;
switch (state()) {
case I0:
msgs.push_back(
artis::common::event::ExternalEvent(OUT_W, 0));
break;
case I1:
msgs.push_back(
artis::common::event::ExternalEvent(OUT_G, 1));
break;
case G:break;
case GR:
msgs.push_back(
artis::common::event::ExternalEvent(OUT_G, 0));
break;
case WW:
msgs.push_back(
artis::common::event::ExternalEvent(OUT_W, 1));
break;
case W:
msgs.push_back(
artis::common::event::ExternalEvent(OUT_W, 0));
break;
case DW:
msgs.push_back(
artis::common::event::ExternalEvent(OUT_G, 1));
break;
}
return msgs;
}
bool rho(typename common::DoubleTime::type /* time */,
const common::event::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::event::Bag &bag) override
{
std::for_each(bag.begin(), bag.end(),
[this](const artis::common::event::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::event::Bag
lambda(typename common::DoubleTime::type /* t */) const override
{
common::event::Bag msgs;
return msgs;
}
bool rho(typename common::DoubleTime::type /* time */,
const common::event::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::event::Bag
lambda(typename common::DoubleTime::type /* t */) const override
{
common::event::Bag msgs;
switch (state()) {
case INIT:
msgs.push_back(
artis::common::event::ExternalEvent(OUT_P, 1));
break;
case SEND:break;
}
return msgs;
}
bool rho(typename common::DoubleTime::type /* time */,
const common::event::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