Andy Tomlin Posted September 30, 2022 Report Posted September 30, 2022 I could use some directional advice. My original plan was to use sc_fifo for most of the interconnects in our design. However I wanted to integrate our logging infrastructure. The quick and dirty method would be to have a macro for read which after performing the port read would perform the logging, but this seems a bit crude. The next thought would be to extend/wrap the sc_fifo. template <class T> class rdyVldSrc : public sc_port<sc_fifo_blocking_out_if< T > > { private: logBlock log_; public: rdyVldSrc(const char * module, std::string block ) : sc_port<sc_fifo_blocking_out_if< T > >(module), log_(std::string(module), block) {} }; template <class T> class rdyVldDst : public sc_port<sc_fifo_blocking_in_if< T > > { private: logBlock log_; public: rdyVldDst(const char * module, std::string block ) : sc_port<sc_fifo_blocking_in_if< T > >(module), log_(std::string(module), block) {} void readWithLog(T & readData) { //call base class read log_.logPrint(readData.prt(), LOG_NORMAL); } }; However I cannot figure out how to call the base class read. this->read(readData); does not work because the compiler cannot resolve. From other posts it looks like this is not a viable path.... This would be my preferred path if someone can suggest. Next I tried taking the sc_fifo implementation, and trimming it down but the sc_fifo.h implementation uses sc_event::kernel_event which is private and sc_fifo has access as it is a friend. the alternative is the macro.. #define READ(port, var) port->read(var); log_.logPrint(var.prt()); Quote
David Black Posted October 1, 2022 Report Posted October 1, 2022 The definition of a channel in systemc is a class that implements one or more interfaces and a base class. In the case of sc_fifo, the base class is sc_prim_channel, and there are two interfaces, which you appear to have discovered. However, you are trying to derive from the interfaces, which will not work. Interfaces are merely the API and should/do not contain implementation. You should derive from the sc_fifo<T> class directly to override the read method. Then you could call sc_fifo<T>::read(). This is all basic C++ stuff once you see the architecture. // The following is for conceptualization and does not represent the full details of sc_fifo, // which can be found in the IEEE-1666-2011 standard document. The depth might be an int. template<typename T> struct sc_fifo_in_if : virtual sc_interface { virtual T read() = 0; }; template<typename T> struct sc_fifo_out_if : virtual sc_interface { virtual void write(const T&) = 0; }; template<typename T> struct sc_fifo : sc_prim_channel, sc_fifo_in_if<T>, sc_fifo_out_if<T> { sc_fifo(char* nm, size_t depth = 16) : sc_prim_channel{ nm }, m_depth{ depth } { sc_assert( depth > 0 ); ... } T read() override { ... } void write(const T& data) override { ... } // other methods... }; // Outline of what you do template<typename T> struct my_fifo<T> : sc_fifo<T> { // IMPORTANT: You must pass an instance name and depth back to the base class static constexpr const size_t default = 0; // or whatever value you want my_fifo(char* nm, size_t depth = default) : sc_fifo<T>{ nm, depth } { sc_assert( depth > 0 )... } T read() override { auto data = sc_fifo<T>::read(); // log data from here return data; } }; Andy Tomlin 1 Quote
Andy Tomlin Posted October 1, 2022 Author Report Posted October 1, 2022 @David Black Thanks for the help. Its completely obvious now you point it out. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.