diff --git a/include/ac_channel.h b/include/ac_channel.h index 9cdf7c4..6309435 100644 --- a/include/ac_channel.h +++ b/include/ac_channel.h @@ -111,6 +111,7 @@ struct ac_channel_exception fifo_not_empty_when_reset, no_operator_sb_defined_for_channel_type, no_insert_defined_for_channel_type, + no_peek_defined_for_channel_type, no_size_in_connections, no_num_free_in_connections, no_output_empty_in_connections, @@ -122,6 +123,7 @@ struct ac_channel_exception "fifo not empty when reset", "No operator[] defined for channel type", "No insert defined for channel type", + "No peek defined for channel type", "Connections does not support size()", "Connections does not support num_free()", "Connections::Out does not support empty()", @@ -166,6 +168,19 @@ class ac_channel return chan.nb_read(t); } + __FORCE_INLINE T peek() + { + return chan.peek(); + } + __FORCE_INLINE void peek(T& t) + { + t = peek(); + } + __FORCE_INLINE bool nb_peek(T& t) + { + return chan.nb_peek(t); + } + __FORCE_INLINE void write(const T& t) { chan.write(t); @@ -315,6 +330,12 @@ class ac_channel template const T0 _read_bambu_internal(bool& res, bool& dummy); template + const T0 _peek_bambu_internal(void); + template + const T0 _peek_bambu_internal(bool& res); + template + const T0 _peek_bambu_internal(bool& res, bool& dummy); + template bool _write_bambu_internal(T0 t); #else struct fifo_abstract @@ -323,6 +344,8 @@ class ac_channel virtual fifo_type get_fifo_type() const = 0; virtual T read() = 0; virtual bool nb_read(T& t) = 0; + virtual T peek() = 0; + virtual bool nb_peek(T& t) = 0; virtual void write(const T& t) = 0; virtual bool nb_write(T& t) = 0; virtual bool empty() = 0; @@ -383,6 +406,15 @@ class ac_channel { return empty() ? false : (t = read(), true); } + T peek() + { + AC_CHANNEL_ASSERT(!empty(), ac_channel_exception::read_from_empty_channel); + return ch.front(); + } + bool nb_peek(T& t) + { + return empty() ? false : (t = peek(), true); + } void write(const T& t) { @@ -458,6 +490,16 @@ class ac_channel { return empty() ? false : (t = read(), true); } + T peek() + { + AC_CHANNEL_ASSERT(0, ac_channel_exception::no_peek_defined_for_channel_type); + return *static_cast(nullptr); + } + bool nb_peek(T&) + { + AC_CHANNEL_ASSERT(0, ac_channel_exception::no_peek_defined_for_channel_type); + return false; + } void write(const T& t) { @@ -536,6 +578,16 @@ class ac_channel { return fifo_in->PopNB(t); } + T peek() + { + AC_CHANNEL_ASSERT(0, ac_channel_exception::no_peek_defined_for_channel_type); + return *static_cast(nullptr); + } + bool nb_peek(T&) + { + AC_CHANNEL_ASSERT(0, ac_channel_exception::no_peek_defined_for_channel_type); + return false; + } void write(const T& t) { @@ -608,6 +660,16 @@ class ac_channel t = true; return (sync_in->nb_sync_in()); } + T peek() + { + AC_CHANNEL_ASSERT(0, ac_channel_exception::no_peek_defined_for_channel_type); + return *static_cast(nullptr); + } + bool nb_peek(T&) + { + AC_CHANNEL_ASSERT(0, ac_channel_exception::no_peek_defined_for_channel_type); + return false; + } void write(const T& t) { @@ -749,6 +811,49 @@ class ac_channel t = _read_bambu_internal(cond, dummy); } #endif +#if __clang_major__ >= 16 + template ::value, bool> = true> + __FORCE_INLINE void _peek0(T0& t) + { + enum + { + _BitWidth0 = 8 * sizeof(T0) + }; + bambu_bitcast_payload payload; + payload.bits = _peek_bambu_internal(); + t = payload.object; + } +#else + template ::value, bool> = true> + __FORCE_INLINE void _peek0(T0& t) + { + t = _peek_bambu_internal(); + } +#endif +#if __clang_major__ >= 16 + template ::value, bool> = true> + __FORCE_INLINE void _peek0(T0& t, bool& cond) + { + enum + { + _BitWidth0 = 8 * sizeof(T0) + }; + bool cond0; + unsigned _BitInt(_BitWidth0 + 1) res = _peek_bambu_internal(cond0); + unsigned char cond1 = (res >> ((unsigned _BitInt(_BitWidth0 + 1)) _BitWidth0)) & 1; + cond = cond1; + bambu_bitcast_payload payload; + payload.bits = res; + t = payload.object; + } +#else + template ::value, bool> = true> + __FORCE_INLINE void _peek0(T0& t, bool& cond) + { + bool dummy; + t = _peek_bambu_internal(cond, dummy); + } +#endif #if __clang_major__ >= 16 template >::value, bool> = true> __FORCE_INLINE void _read0(ac_int& t) @@ -782,6 +887,38 @@ class ac_channel unsigned _BitInt(W) val = res; t.from_BitInt(val); } + template >::value, bool> = true> + __FORCE_INLINE void _peek0(ac_int& t) + { + unsigned _BitInt(W) res = _peek_bambu_internal(); + t.from_BitInt(res); + } + template >::value, bool> = true> + __FORCE_INLINE void _peek0(ac_fixed& t) + { + unsigned _BitInt(W) res = _peek_bambu_internal(); + t.from_BitInt(res); + } + template >::value, bool> = true> + __FORCE_INLINE void _peek0(ac_int& t, bool& cond) + { + bool cond0; + unsigned _BitInt(W + 1) res = _peek_bambu_internal(cond0); + cond = (res >> ((unsigned _BitInt(W + 1)) W)) & 1; + unsigned _BitInt(W) val = res; + t.from_BitInt(val); + } + template >::value, bool> = true> + __FORCE_INLINE void _peek0(ac_fixed& t, bool& cond) + { + bool cond0; + unsigned _BitInt(W + 1) res = _peek_bambu_internal(cond0); + cond = (res >> ((unsigned _BitInt(W + 1)) W)) & 1; + unsigned _BitInt(W) val = res; + t.from_BitInt(val); + } #endif #endif @@ -806,6 +943,24 @@ class ac_channel return res; } + ///// peek + __FORCE_INLINE T peek() + { + T val; + _peek0(val); + return val; + } + + ///// nb_peek + __FORCE_INLINE bool nb_peek(T& t) + { + bool res; + T temp; + _peek0(temp, res); + t = res ? temp : t; + return res; + } + ///// write #if __clang_major__ >= 16 template ::value, bool> = true> @@ -910,6 +1065,14 @@ class ac_channel { return f->nb_read(t); } + inline T peek() + { + return f->peek(); + } + inline bool nb_peek(T& t) + { + return f->nb_peek(t); + } inline void write(const T& t) {