Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/forsyde.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@
// include the main SystemC library
#include <systemc>

// include type libraries
#include "forsyde/type_helpers.hpp"
#ifdef FORSYDE_INTROSPECTION
#include "forsyde/types.hpp"
#include "forsyde/type_introspect.hpp"
#endif

// include the abstract semantics
Expand Down
8 changes: 5 additions & 3 deletions src/forsyde/abssemantics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#ifndef ABSSEMANTICS_HPP
#define ABSSEMANTICS_HPP

#include "type_introspect.hpp"

/*! \file abssemantics.hpp
* \brief The common abstract semantics for all MoCs.
*
Expand Down Expand Up @@ -89,7 +91,7 @@ class signal: public sc_fifo<TokenType>
//! Returns the name of the token type
virtual const char* token_type() const
{
return get_type_name<T>();
return IntrospectiveType::traverse<T>();
}

virtual std::string moc() const = 0;
Expand Down Expand Up @@ -149,7 +151,7 @@ class in_port: public sc_fifo_in<TokenType>
//! Returns the plain name of the token type
virtual const char* token_type() const
{
return get_type_name<T>();
return IntrospectiveType::traverse<T>();
}
#endif
};
Expand Down Expand Up @@ -189,7 +191,7 @@ class out_port: public sc_fifo_out<TokenType>
//! Returns the name of the actual type (not abst_ext version)
virtual const char* token_type() const
{
return get_type_name<T>();
return IntrospectiveType::traverse<T>();
}
#endif
};
Expand Down
4 changes: 2 additions & 2 deletions src/forsyde/sdf_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ template <class T1, template <class> class I1If,
inline zip<T1,T2>* make_zip(std::string pName,
unsigned int i1toks,
unsigned int i2toks,
OIf<std::tuple<std::vector<T1>,std::vector<T2>>>& outS,
OIf<token_tuple<T1,T2>>& outS,
I1If<T1>& inp1S,
I2If<T2>& inp2S
)
Expand All @@ -370,7 +370,7 @@ template <template <class> class IIf,
class T1, template <class> class O1If,
class T2, template <class> class O2If>
inline unzip<T1,T2>* make_unzip(std::string pName,
IIf<std::tuple<std::vector<T1>,std::vector<T2>>>& inpS,
IIf<token_tuple<T1,T2>>& inpS,
unsigned int o1toks,
unsigned int o2toks,
O1If<T1>& out1S,
Expand Down
1 change: 1 addition & 0 deletions src/forsyde/sdf_moc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <functional>
#include <tuple>

#include "token.hpp"
#include "sdf_process.hpp"
#include "sdf_process_constructors.hpp"
#include "sdf_helpers.hpp"
Expand Down
42 changes: 21 additions & 21 deletions src/forsyde/sdf_process_constructors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <functional>
#include <tuple>
#include <vector>
#include <initializer_list>


#include "sdf_process.hpp"

Expand Down Expand Up @@ -1128,7 +1130,7 @@ class zip : public sdf_process
public:
SDF_in<T1> iport1; ///< port for the input channel 1
SDF_in<T2> iport2; ///< port for the input channel 2
SDF_out<std::tuple<std::vector<T1>,std::vector<T2>>> oport1;///< port for the output channel
SDF_out<token_tuple<T1,T2>> oport1;///< port for the output channel

//! The constructor requires the module name
/*! It creates an SC_THREAD which reads data from its input ports,
Expand All @@ -1153,29 +1155,27 @@ class zip : public sdf_process
unsigned i1toks;
unsigned i2toks;

// intermediate values
std::vector<T1> ival1;
std::vector<T2> ival2;
token_tuple<T1,T2> ival;


void init()
{
ival1.resize(i1toks);
ival2.resize(i2toks);
ival.resize({i1toks, i2toks});
}

void prep()
{
for (auto i=0; i<i1toks; i++)
ival1[i] = iport1.read();
ival.get<0>(i) = iport1.read();
for (auto i=0; i<i2toks; i++)
ival2[i] = iport2.read();
ival.get<1>(i) = iport2.read();
}

void exec() {}

void prod()
{
WRITE_MULTIPORT(oport1,std::make_tuple(ival1,ival2)) // write to the output
WRITE_MULTIPORT(oport1,ival) // write to the output
}

void clean() {}
Expand All @@ -1200,15 +1200,15 @@ class zipN : public sdf_process
{
public:
std::tuple <SDF_in<Ts>...> iport;///< tuple of ports for the input channels
SDF_out<std::tuple<std::vector<Ts>...> > oport1;///< port for the output channel
SDF_out<token_tuple<Ts...> > oport1;///< port for the output channel

//! The constructor requires the module name
/*! It creates an SC_THREAD which reads data from its input port,
* zips them together and writes the results using the output port
*/
zipN(sc_module_name _name,
std::vector<unsigned> in_toks)
:sdf_process(_name), oport1("oport1"), in_toks(in_toks)
std::initializer_list<unsigned> in_toks)
:sdf_process(_name), oport1("oport1"), in_toks(std::vector<unsigned>(in_toks))
{
if (in_toks.size()!=sizeof...(Ts))
SC_REPORT_ERROR(name(),"Wrong number of production rates provided");
Expand All @@ -1224,16 +1224,16 @@ class zipN : public sdf_process
private:
std::vector<unsigned> in_toks;
// intermediate values
std::tuple<std::vector<Ts>...>* in_val;
token_tuple<Ts...>* in_val;

void init()
{
in_val = new std::tuple<std::vector<Ts>...>;
in_val = new token_tuple<Ts...>;
}

void prep()
{
*in_val = sc_fifo_tuple_read<Ts...>(iport, in_toks);
in_val->t = sc_fifo_tuple_read<Ts...>(iport, in_toks);
}

void exec() {}
Expand Down Expand Up @@ -1326,7 +1326,7 @@ template <class T1, class T2>
class unzip : public sdf_process
{
public:
SDF_in<std::tuple<std::vector<T1>,std::vector<T2>>> iport1;///< port for the input channel
SDF_in<token_tuple<T1,T2>> iport1;///< port for the input channel
SDF_out<T1> oport1; ///< port for the output channel 1
SDF_out<T2> oport2; ///< port for the output channel 2

Expand Down Expand Up @@ -1363,7 +1363,7 @@ class unzip : public sdf_process

void prep()
{
*in_val = iport1.read();
*in_val = iport1.read().t;
}

void exec() {}
Expand Down Expand Up @@ -1399,16 +1399,16 @@ template <class... Ts>
class unzipN : public sdf_process
{
public:
SDF_in<std::tuple<std::vector<Ts>...>> iport1;///< port for the input channel
SDF_in<token_tuple<Ts...>> iport1;///< port for the input channel
std::tuple<SDF_out<Ts>...> oport;///< tuple of ports for the output channels

//! The constructor requires the module name
/*! It creates an SC_THREAD which reads data from its input port,
* unzips it and writes the results using the output ports
*/
unzipN(sc_module_name _name,
std::vector<unsigned> out_toks)
:sdf_process(_name), iport1("iport1"), out_toks(out_toks)
std::initializer_list<unsigned> out_toks)
:sdf_process(_name), iport1("iport1"), out_toks(std::vector<unsigned>(out_toks))
{
if (out_toks.size()!=sizeof...(Ts))
SC_REPORT_ERROR(name(),"Wrong number of production rates provided");
Expand All @@ -1433,7 +1433,7 @@ class unzipN : public sdf_process

void prep()
{
*in_val = iport1.read();
*in_val = iport1.read().t;
}

void exec() {}
Expand Down
86 changes: 86 additions & 0 deletions src/forsyde/token.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#ifndef TOKEN_TYPE_HPP
#define TOKEN_TYPE_HPP

/**********************************************************************
* token.hpp -- Containers for tokens in UT MoCs *
* *
* Author: George Ungureanu (ugeorge@kth.se) *
* *
* Purpose: Hides vector containers used for implementing multiple *
* produced/consumed tokens, used in some MoCs (e.g. SDF) *
* *
* Usage: This file is included automatically *
* *
* License: BSD3 *
*******************************************************************/


/*! \file token.hpp
* \brief Implements the token containers
*/

namespace ForSyDe
{

template<typename T>
using tokens = std::vector<T>;

template<typename... T>
struct token_tuple {
typedef std::tuple<tokens<T>...> type;
type t;

token_tuple() {}
token_tuple(std::initializer_list<size_t> list) { traverse_tuple<sizeof...(T), type>::resize(list.end(), t); }
explicit token_tuple(const std::tuple<tokens<T>...> t_) : t(t_) {};
token_tuple(const token_tuple<T...> & t_) : t(t_.t){}

void resize(std::initializer_list<size_t> list) { traverse_tuple<sizeof...(T), type>::resize(list.end(), t); }
token_tuple<T...>& operator=(const token_tuple<T...>& rhs) { t = rhs.t; return *this;}
token_tuple<T...>& operator=(const std::tuple<tokens<T>...>& rhs) { t = rhs; return *this;}

private:

// Default template for traversing a tuple
template <size_t N, typename Tup>
struct traverse_tuple {};

// Template specialization for traversing a tuple with multiple elements
template <size_t N, typename TT, typename... Tail>
struct traverse_tuple<N, std::tuple<tokens<TT>, Tail...>>{
static inline void resize(std::initializer_list<size_t>::iterator size, std::tuple<tokens<TT>, Tail...>& tv) {
--size;
std::get<N-1>(tv).resize(*size);
traverse_tuple<N-1, std::tuple<tokens<TT>, Tail...>>::resize(size, tv);
}
};

// Template specialization for traversing a tuple with one element
template <typename TT, typename... Tail>
struct traverse_tuple<1, std::tuple<tokens<TT>, Tail...>>{
static inline void resize(std::initializer_list<size_t>::iterator size, std::tuple<tokens<TT>, Tail...>& tv) {
std::get<0>(tv).resize(*size);
}
};
};

template<typename... T>
std::ostream& operator <<(std::ostream &os, const token_tuple<T...> &obj) {
return os;
}


// TODO: make an initializer traversal
template<typename T>
tokens<T> init(size_t n){
return tokens<T>(n);
}

template<typename... T>
tokens<token_tuple<T...>> init(size_t n, std::initializer_list<size_t> list){
return tokens<token_tuple<T...>>(n, token_tuple<T...>(list));
}

}

#endif
Loading