Skip to content
10 changes: 10 additions & 0 deletions examples/sy/signal_abstraction/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "top.hpp"

int sc_main(int argc, char **argv)
{
top top1("top1");

sc_start();

return 0;
}
47 changes: 47 additions & 0 deletions examples/sy/signal_abstraction/top.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <forsyde.hpp>

using namespace sc_core;
using namespace ForSyDe;


void report_func(abst_ext<float> inp1)
{
if (inp1.is_present())
std::cout << "Input value: " << inp1.unsafe_from_abst_ext() << std::endl;
else
std::cout << "Input value: absent" << std::endl;
}

void signalabst_func(abst_ext<float>& out, const unsigned long& take, const std::vector<abst_ext<float>>& inp)
{


float sum = 0;
for (unsigned long i = 0; i < inp.size(); i++)
{
sum += unsafe_from_abst_ext(inp[i]);
}
out.set_val(sum/take);
}

SC_MODULE(top)

{
SY::signal <float> out_source;
SY::signal <float> out_signalabst;

std::vector<abst_ext<float>> s1 = {36.7, 36.8, 36.7, 36.8, 36.9, 36.9, 37.0, 37.0, 37.1, 37.2, 37.3, 37.2, 37.3, 37.3, 37.4, 37.5, 37.6, 36.6};
std::vector<abst_ext<float>> s2 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};


SC_CTOR(top)
{
std::cout<<s2<<std::endl;
SY::make_vsource ("source", s2, out_source) ;
auto abstsig = new SY::signalabst <float,float> ("signalabst", 4, signalabst_func);
abstsig-> iport1 (out_source);
abstsig-> oport1(out_signalabst);
SY::make_sink("report1", report_func, out_signalabst);
}
};

71 changes: 71 additions & 0 deletions examples/ut/two_scenario/controller.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef CONTROLLER_HPP
#define CONTROLLER_HPP

#include <forsyde.hpp>

typedef std::function <std::vector<int>(const std::vector<int>&)> scenrio_func;

///!< gamma function for the zipU process of the top module
size_t gamma_func_zipa (const size_t &ca)
{
return ca;
}

size_t gamma_func_zipb (const size_t &ca)
{
return 1;
}

///<! Mealy Detector process
void gamma_detector_func(unsigned int& tokens, const int& state)
{
tokens = 1;
}


void next_state_detector_func(int& next_state, const int& cur_state, const std::vector<int>& inp)
{

if (cur_state == 0)
next_state = 1;
else
next_state = 0;

}

void output_decode_detector_func(
std::vector<
std::tuple<
size_t, size_t, scenrio_func
>
>& out, const int& cur_state, const std::vector<int>& inp
)
{
out.resize(1);
if (cur_state == 0)
{
out[0] = std::make_tuple(3, 1, [=] (const std::vector<int>& inp){
std::vector<int> out(1);
out[0] =inp[0] + inp[1] + inp[2];
return out;
});
}
else
{
out[0] = std::make_tuple(2, 1, [=] (const std::vector<int>& inp){
std::vector<int> out(1);
out[0] =inp[1]-inp[0];
return out;
});
}

}

///<! Kernels Function
void kernel_func(std::vector<int>& out, const std::vector<std::tuple<std::vector<int>,std::vector<std::tuple<size_t, size_t, scenrio_func>>>>& inp)
{
out = std::get<2>(std::get<1>(inp[0])[0])(std::get<0>(inp[0]));
}


#endif
12 changes: 12 additions & 0 deletions examples/ut/two_scenario/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "top.hpp"

int sc_main(int argc, char **argv)
{
top top1("top1");

sc_start();

return 0;
}


14 changes: 14 additions & 0 deletions examples/ut/two_scenario/ramp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

#ifndef RAMP_HPP
#define RAMP_HPP

#include <forsyde.hpp>

using namespace ForSyDe;

void ramp_func(int& out1, const int& inp1)
{
out1 = inp1 + 1;
}

#endif
14 changes: 14 additions & 0 deletions examples/ut/two_scenario/report.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef REPORT_HPP
#define REPORT_HPP

#include <forsyde.hpp>
#include <iostream>

using namespace ForSyDe;

void report_func(const int& inp1)
{
std::cout << "output value: " << inp1 << std::endl;
}

#endif
62 changes: 62 additions & 0 deletions examples/ut/two_scenario/top.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include <forsyde.hpp>
#include "report.hpp"
#include "ramp.hpp"
#include "controller.hpp"

using namespace sc_core;
using namespace ForSyDe;


SC_MODULE(top)
{
UT::signal<int> from_source, from_constant, from_kernels;
UT::signal<size_t> zip_control;
UT::signal<std::tuple<std::vector<int>,std::vector<std::tuple<size_t, size_t, scenrio_func>>>> from_zip;
UT::signal<std::tuple<size_t, size_t, scenrio_func>> from_detector, from_detector2;

SC_CTOR(top)
{

UT::make_source("ramp1", ramp_func, 1, 20, from_source);

UT::make_constant("constant1", 1, 0, from_constant);
auto detector = UT::make_mealy("detector",
gamma_detector_func,
next_state_detector_func,
output_decode_detector_func,
0,
from_detector,
from_constant
);

detector->oport1(from_detector2);

UT::make_comb("cextract",[](std::vector<size_t>& out,const std::vector<std::tuple<size_t, size_t, scenrio_func>>& inp){
out.resize(1);
out[0] = std::get<0>(inp[0]);
}, 1, zip_control, from_detector2);

/// -> Without using helper

// auto zipU1 = new UT::zipU <int, std::tuple<size_t, size_t, scenrio_func>, size_t>("zipU1", gamma_func_zipa, gamma_func_zipb);
// zipU1->iport1 (from_source);
// zipU1->iport2 (from_detector);
// zipU1->controlport (zip_control);
// zipU1->oport1 (from_zip);


// -> using helper

UT::make_zipU("zipU1", gamma_func_zipa, gamma_func_zipb, from_zip, from_source, from_detector, zip_control);
UT::make_comb ("kernels",
kernel_func,
1,
from_kernels,
from_zip
);

UT::make_sink("sink", report_func, from_kernels);
}

};

90 changes: 90 additions & 0 deletions src/forsyde/sy_process_constructors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2112,6 +2112,96 @@ class fanout : public sy_process
#endif
};

template <class T0, class T1>
class signalabst : public sy_process
{
public:
typedef std::function<void(abst_ext<T1>&, const unsigned long&, const std::vector<abst_ext<T0>>&)> functype;

SY_in <T0> iport1; ///< port for the input channel
SY_out <T1> oport1; ///< port for the output channel

signalabst(const sc_module_name& _name,
const unsigned long& take_samples, functype _func
) : sy_process(_name), take_samples(take_samples), _func(_func)
{
#ifdef FORSYDE_INTROSPECTION


#endif
}

//! Specifying from which process constructor is the module built
std::string forsyde_kind() const {return "SY::signalabst";}

private:

abst_ext<T0>* ival1;
abst_ext<T1>* oval1;
std::vector<abst_ext<T0>>* ivals;
unsigned long take_samples;
functype _func;
int tok_cnt;


//Implementing the abstract semantics
void init()
{
ival1 = new abst_ext<T0>;
oval1 = new abst_ext<T1>;
ivals = new std::vector<abst_ext<T0>>;
tok_cnt = 0;


}

void prep()
{

*ival1 = iport1.read();
ivals->push_back(*ival1);
tok_cnt ++;
}

void exec()
{
if (tok_cnt == take_samples)
{
_func(*oval1, take_samples, *ivals);
tok_cnt = 0;
ivals->clear();
}

else
{
oval1->set_abst();
}

}

void prod()
{
WRITE_MULTIPORT(oport1, abst_ext<T1>(*oval1))
}

void clean()
{
delete oval1;
delete ival1;
delete ivals;
}

#ifdef FORSYDE_INTROSPECTION
void bindInfo()
{
boundInChans.resize(1); // only one input port
boundInChans[0].port = &iport1;
boundOutChans.resize(1); // only one output port
boundOutChans[0].port = &oport1;
}
#endif
};

}
}

Expand Down
30 changes: 30 additions & 0 deletions src/forsyde/ut_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,36 @@ inline fanout<T>* make_fanout(const std::string& pName,
return p;
}

//! Helper function to construct a zipU process
/*! This function is used to construct a zipU process (SystemC module) and
* connect its output and output signals.
* It provides a more functional style definition of a ForSyDe process.
* It also removes bilerplate code by using type-inference feature of
* C++ and automatic binding to the input FIFOs.
*/

template <class T1, template <class> class I1If,
Comment thread
mohammadvazirpanah marked this conversation as resolved.
class T2, template <class> class I2If,
class TCS, template <class> class I3If,
template <class> class OIf>
inline zipU<T1,T2,TCS>* make_zipU(const std::string& pName,
const typename zipU<T1,T2,TCS>::gamma_functype& _gamma_func_a,
const typename zipU<T1,T2,TCS>::gamma_functype& _gamma_func_b,
OIf<std::tuple<std::vector<T1>,std::vector<T2>>>& outS,
I1If<T1>& inp1S,
I2If<T2>& inp2S,
I3If<TCS>& inp3S
)
{
auto p = new zipU<T1,T2,TCS>(pName.c_str(), _gamma_func_a, _gamma_func_b);

(*p).iport1(inp1S);
(*p).iport2(inp2S);
(*p).controlport(inp3S);
(*p).oport1(outS);

return p;
}

}
}
Expand Down
Loading