112027Sjungma@eit.uni-kl.de/***************************************************************************** 212027Sjungma@eit.uni-kl.de 312027Sjungma@eit.uni-kl.de Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 412027Sjungma@eit.uni-kl.de more contributor license agreements. See the NOTICE file distributed 512027Sjungma@eit.uni-kl.de with this work for additional information regarding copyright ownership. 612027Sjungma@eit.uni-kl.de Accellera licenses this file to you under the Apache License, Version 2.0 712027Sjungma@eit.uni-kl.de (the "License"); you may not use this file except in compliance with the 812027Sjungma@eit.uni-kl.de License. You may obtain a copy of the License at 912027Sjungma@eit.uni-kl.de 1012027Sjungma@eit.uni-kl.de http://www.apache.org/licenses/LICENSE-2.0 1112027Sjungma@eit.uni-kl.de 1212027Sjungma@eit.uni-kl.de Unless required by applicable law or agreed to in writing, software 1312027Sjungma@eit.uni-kl.de distributed under the License is distributed on an "AS IS" BASIS, 1412027Sjungma@eit.uni-kl.de WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1512027Sjungma@eit.uni-kl.de implied. See the License for the specific language governing 1612027Sjungma@eit.uni-kl.de permissions and limitations under the License. 1712027Sjungma@eit.uni-kl.de 1812027Sjungma@eit.uni-kl.de *****************************************************************************/ 1912027Sjungma@eit.uni-kl.de 2012027Sjungma@eit.uni-kl.de#ifndef __TLM_FIFO_H__ 2112027Sjungma@eit.uni-kl.de#define __TLM_FIFO_H__ 2212027Sjungma@eit.uni-kl.de 2312027Sjungma@eit.uni-kl.de// 2412027Sjungma@eit.uni-kl.de// This implements put, get and peek 2512027Sjungma@eit.uni-kl.de// 2612027Sjungma@eit.uni-kl.de// It also implements 0 and infinite size fifos - but the size 2712027Sjungma@eit.uni-kl.de// zero fifos aren't rendezvous like zero length fifos, they simply are both 2812027Sjungma@eit.uni-kl.de// full and empty at the same time. 2912027Sjungma@eit.uni-kl.de// 3012027Sjungma@eit.uni-kl.de// The size can be dynamically changed using the resize interface 3112027Sjungma@eit.uni-kl.de// 3212027Sjungma@eit.uni-kl.de// To get an infinite fifo use a -ve size in the constructor. 3312027Sjungma@eit.uni-kl.de// The absolute value of the size is taken as the starting size of the 3412027Sjungma@eit.uni-kl.de// actual physical buffer. 3512027Sjungma@eit.uni-kl.de// 3612027Sjungma@eit.uni-kl.de 3712027Sjungma@eit.uni-kl.de//#include <systemc> 3812027Sjungma@eit.uni-kl.de 3912027Sjungma@eit.uni-kl.de#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h" 4012027Sjungma@eit.uni-kl.de#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h" 4112027Sjungma@eit.uni-kl.de 4212027Sjungma@eit.uni-kl.denamespace tlm { 4312027Sjungma@eit.uni-kl.de 4412027Sjungma@eit.uni-kl.detemplate <typename T> 4512027Sjungma@eit.uni-kl.declass tlm_fifo : 4612027Sjungma@eit.uni-kl.de public virtual tlm_fifo_get_if<T>, 4712027Sjungma@eit.uni-kl.de public virtual tlm_fifo_put_if<T>, 4812027Sjungma@eit.uni-kl.de public sc_core::sc_prim_channel 4912027Sjungma@eit.uni-kl.de{ 5012027Sjungma@eit.uni-kl.depublic: 5112027Sjungma@eit.uni-kl.de 5212027Sjungma@eit.uni-kl.de // constructors 5312027Sjungma@eit.uni-kl.de 5412027Sjungma@eit.uni-kl.de explicit tlm_fifo( int size_ = 1 ) 5512027Sjungma@eit.uni-kl.de : sc_core::sc_prim_channel( sc_core::sc_gen_unique_name( "fifo" ) ) { 5612027Sjungma@eit.uni-kl.de 5712027Sjungma@eit.uni-kl.de init( size_ ); 5812027Sjungma@eit.uni-kl.de 5912027Sjungma@eit.uni-kl.de } 6012027Sjungma@eit.uni-kl.de 6112027Sjungma@eit.uni-kl.de explicit tlm_fifo( const char* name_, int size_ = 1 ) 6212027Sjungma@eit.uni-kl.de : sc_core::sc_prim_channel( name_ ) { 6312027Sjungma@eit.uni-kl.de 6412027Sjungma@eit.uni-kl.de init( size_ ); 6512027Sjungma@eit.uni-kl.de 6612027Sjungma@eit.uni-kl.de } 6712027Sjungma@eit.uni-kl.de 6812027Sjungma@eit.uni-kl.de // destructor 6912027Sjungma@eit.uni-kl.de 7012027Sjungma@eit.uni-kl.de virtual ~tlm_fifo() {} 7112027Sjungma@eit.uni-kl.de 7212027Sjungma@eit.uni-kl.de // tlm get interface 7312027Sjungma@eit.uni-kl.de 7412027Sjungma@eit.uni-kl.de T get( tlm_tag<T> * = 0 ); 7512027Sjungma@eit.uni-kl.de 7612027Sjungma@eit.uni-kl.de bool nb_get( T& ); 7712027Sjungma@eit.uni-kl.de bool nb_can_get( tlm_tag<T> * = 0 ) const; 7812027Sjungma@eit.uni-kl.de const sc_core::sc_event &ok_to_get( tlm_tag<T> * = 0 ) const { 7912027Sjungma@eit.uni-kl.de return m_data_written_event; 8012027Sjungma@eit.uni-kl.de } 8112027Sjungma@eit.uni-kl.de 8212027Sjungma@eit.uni-kl.de // tlm peek interface 8312027Sjungma@eit.uni-kl.de 8412027Sjungma@eit.uni-kl.de T peek( tlm_tag<T> * = 0 ) const; 8512027Sjungma@eit.uni-kl.de 8612027Sjungma@eit.uni-kl.de bool nb_peek( T& ) const; 8712027Sjungma@eit.uni-kl.de bool nb_can_peek( tlm_tag<T> * = 0 ) const; 8812027Sjungma@eit.uni-kl.de const sc_core::sc_event &ok_to_peek( tlm_tag<T> * = 0 ) const { 8912027Sjungma@eit.uni-kl.de return m_data_written_event; 9012027Sjungma@eit.uni-kl.de } 9112027Sjungma@eit.uni-kl.de 9212027Sjungma@eit.uni-kl.de // tlm put interface 9312027Sjungma@eit.uni-kl.de 9412027Sjungma@eit.uni-kl.de void put( const T& ); 9512027Sjungma@eit.uni-kl.de 9612027Sjungma@eit.uni-kl.de bool nb_put( const T& ); 9712027Sjungma@eit.uni-kl.de bool nb_can_put( tlm_tag<T> * = 0 ) const; 9812027Sjungma@eit.uni-kl.de 9912027Sjungma@eit.uni-kl.de const sc_core::sc_event& ok_to_put( tlm_tag<T> * = 0 ) const { 10012027Sjungma@eit.uni-kl.de return m_data_read_event; 10112027Sjungma@eit.uni-kl.de } 10212027Sjungma@eit.uni-kl.de 10312027Sjungma@eit.uni-kl.de // resize if 10412027Sjungma@eit.uni-kl.de 10512027Sjungma@eit.uni-kl.de void nb_expand( unsigned int n = 1 ); 10612027Sjungma@eit.uni-kl.de void nb_unbound( unsigned int n = 16 ); 10712027Sjungma@eit.uni-kl.de 10812027Sjungma@eit.uni-kl.de bool nb_reduce( unsigned int n = 1 ); 10912027Sjungma@eit.uni-kl.de bool nb_bound( unsigned int n ); 11012027Sjungma@eit.uni-kl.de 11112027Sjungma@eit.uni-kl.de // debug interface 11212027Sjungma@eit.uni-kl.de 11312027Sjungma@eit.uni-kl.de bool nb_peek( T & , int n ) const; 11412027Sjungma@eit.uni-kl.de bool nb_poke( const T & , int n = 0 ); 11512027Sjungma@eit.uni-kl.de 11612027Sjungma@eit.uni-kl.de int used() const { 11712027Sjungma@eit.uni-kl.de return m_num_readable - m_num_read; 11812027Sjungma@eit.uni-kl.de } 11912027Sjungma@eit.uni-kl.de 12012027Sjungma@eit.uni-kl.de int size() const { 12112027Sjungma@eit.uni-kl.de return m_size; 12212027Sjungma@eit.uni-kl.de } 12312027Sjungma@eit.uni-kl.de 12412027Sjungma@eit.uni-kl.de void debug() const { 12512027Sjungma@eit.uni-kl.de 12612027Sjungma@eit.uni-kl.de if( is_empty() ) std::cout << "empty" << std::endl; 12712027Sjungma@eit.uni-kl.de if( is_full() ) std::cout << "full" << std::endl; 12812027Sjungma@eit.uni-kl.de 12912027Sjungma@eit.uni-kl.de std::cout << "size " << size() << " - " << used() << " used " 13012027Sjungma@eit.uni-kl.de << std::endl; 13112027Sjungma@eit.uni-kl.de std::cout << "readable " << m_num_readable 13212027Sjungma@eit.uni-kl.de << std::endl; 13312027Sjungma@eit.uni-kl.de std::cout << "written/read " << m_num_written << "/" << m_num_read 13412027Sjungma@eit.uni-kl.de << std::endl; 13512027Sjungma@eit.uni-kl.de 13612027Sjungma@eit.uni-kl.de } 13712027Sjungma@eit.uni-kl.de 13812027Sjungma@eit.uni-kl.de // support functions 13912027Sjungma@eit.uni-kl.de 14012027Sjungma@eit.uni-kl.de static const char* const kind_string; 14112027Sjungma@eit.uni-kl.de 14212027Sjungma@eit.uni-kl.de const char* kind() const 14312027Sjungma@eit.uni-kl.de { return kind_string; } 14412027Sjungma@eit.uni-kl.de 14512027Sjungma@eit.uni-kl.de 14612027Sjungma@eit.uni-kl.deprotected: 14712027Sjungma@eit.uni-kl.de sc_core::sc_event &read_event( tlm_tag<T> * = 0 ) { 14812027Sjungma@eit.uni-kl.de return m_data_read_event; 14912027Sjungma@eit.uni-kl.de } 15012027Sjungma@eit.uni-kl.de 15112027Sjungma@eit.uni-kl.deprotected: 15212027Sjungma@eit.uni-kl.de 15312027Sjungma@eit.uni-kl.de void update(); 15412027Sjungma@eit.uni-kl.de 15512027Sjungma@eit.uni-kl.de // support methods 15612027Sjungma@eit.uni-kl.de 15712027Sjungma@eit.uni-kl.de void init( int ); 15812027Sjungma@eit.uni-kl.de 15912027Sjungma@eit.uni-kl.deprotected: 16012027Sjungma@eit.uni-kl.de 16112027Sjungma@eit.uni-kl.de circular_buffer<T> buffer; 16212027Sjungma@eit.uni-kl.de 16312027Sjungma@eit.uni-kl.de int m_size; // logical size of fifo 16412027Sjungma@eit.uni-kl.de 16512027Sjungma@eit.uni-kl.de int m_num_readable; // #samples readable 16612027Sjungma@eit.uni-kl.de int m_num_read; // #samples read during this delta cycle 16712027Sjungma@eit.uni-kl.de int m_num_written; // #samples written during this delta cycle 16812027Sjungma@eit.uni-kl.de bool m_expand; // has an expand occurred during this delta cycle ? 16912027Sjungma@eit.uni-kl.de int m_num_read_no_notify; // #samples read without notify during this delta cycle 17012027Sjungma@eit.uni-kl.de 17112027Sjungma@eit.uni-kl.de sc_core::sc_event m_data_read_event; 17212027Sjungma@eit.uni-kl.de sc_core::sc_event m_data_written_event; 17312027Sjungma@eit.uni-kl.de 17412027Sjungma@eit.uni-kl.deprivate: 17512027Sjungma@eit.uni-kl.de 17612027Sjungma@eit.uni-kl.de // disabled 17712027Sjungma@eit.uni-kl.de tlm_fifo( const tlm_fifo<T>& ); 17812027Sjungma@eit.uni-kl.de tlm_fifo& operator = ( const tlm_fifo<T>& ); 17912027Sjungma@eit.uni-kl.de 18012027Sjungma@eit.uni-kl.de // 18112027Sjungma@eit.uni-kl.de // use nb_can_get() and nb_can_put() rather than the following two 18212027Sjungma@eit.uni-kl.de // private functions 18312027Sjungma@eit.uni-kl.de // 18412027Sjungma@eit.uni-kl.de 18512027Sjungma@eit.uni-kl.de bool is_empty() const { 18612027Sjungma@eit.uni-kl.de return used() == 0; 18712027Sjungma@eit.uni-kl.de } 18812027Sjungma@eit.uni-kl.de 18912027Sjungma@eit.uni-kl.de bool is_full() const { 19012027Sjungma@eit.uni-kl.de //return size() == m_num_readable + m_num_written; // Old buggy code 19112027Sjungma@eit.uni-kl.de if( size() < 0 ) 19212027Sjungma@eit.uni-kl.de return false; 19312027Sjungma@eit.uni-kl.de else 19412027Sjungma@eit.uni-kl.de return size() <= m_num_readable + m_num_written; 19512027Sjungma@eit.uni-kl.de } 19612027Sjungma@eit.uni-kl.de 19712027Sjungma@eit.uni-kl.de}; 19812027Sjungma@eit.uni-kl.de 19912027Sjungma@eit.uni-kl.detemplate <typename T> 20012027Sjungma@eit.uni-kl.deconst char* const tlm_fifo<T>::kind_string = "tlm_fifo"; 20112027Sjungma@eit.uni-kl.de 20212027Sjungma@eit.uni-kl.de 20312027Sjungma@eit.uni-kl.de/****************************************************************** 20412027Sjungma@eit.uni-kl.de// 20512027Sjungma@eit.uni-kl.de// init and update 20612027Sjungma@eit.uni-kl.de// 20712027Sjungma@eit.uni-kl.de******************************************************************/ 20812027Sjungma@eit.uni-kl.de 20912027Sjungma@eit.uni-kl.detemplate< typename T > 21012027Sjungma@eit.uni-kl.deinline 21112027Sjungma@eit.uni-kl.devoid 21212027Sjungma@eit.uni-kl.detlm_fifo<T>::init( int size_ ) { 21312027Sjungma@eit.uni-kl.de 21412027Sjungma@eit.uni-kl.de if( size_ > 0 ) { 21512027Sjungma@eit.uni-kl.de buffer.resize( size_ ); 21612027Sjungma@eit.uni-kl.de } 21712027Sjungma@eit.uni-kl.de 21812027Sjungma@eit.uni-kl.de else if( size_ < 0 ) { 21912027Sjungma@eit.uni-kl.de buffer.resize( -size_ ); 22012027Sjungma@eit.uni-kl.de } 22112027Sjungma@eit.uni-kl.de 22212027Sjungma@eit.uni-kl.de else { 22312027Sjungma@eit.uni-kl.de buffer.resize( 16 ); 22412027Sjungma@eit.uni-kl.de } 22512027Sjungma@eit.uni-kl.de 22612027Sjungma@eit.uni-kl.de m_size = size_; 22712027Sjungma@eit.uni-kl.de m_num_readable = 0; 22812027Sjungma@eit.uni-kl.de m_num_read = 0; 22912027Sjungma@eit.uni-kl.de m_num_written = 0; 23012027Sjungma@eit.uni-kl.de m_expand = false; 23112027Sjungma@eit.uni-kl.de m_num_read_no_notify = false; 23212027Sjungma@eit.uni-kl.de 23312027Sjungma@eit.uni-kl.de} 23412027Sjungma@eit.uni-kl.de 23512027Sjungma@eit.uni-kl.detemplate < typename T> 23612027Sjungma@eit.uni-kl.deinline 23712027Sjungma@eit.uni-kl.devoid 23812027Sjungma@eit.uni-kl.detlm_fifo<T>::update() 23912027Sjungma@eit.uni-kl.de{ 24012027Sjungma@eit.uni-kl.de if( m_num_read > m_num_read_no_notify || m_expand ) { 24112027Sjungma@eit.uni-kl.de m_data_read_event.notify( sc_core::SC_ZERO_TIME ); 24212027Sjungma@eit.uni-kl.de } 24312027Sjungma@eit.uni-kl.de 24412027Sjungma@eit.uni-kl.de if( m_num_written > 0 ) { 24512027Sjungma@eit.uni-kl.de m_data_written_event.notify( sc_core::SC_ZERO_TIME ); 24612027Sjungma@eit.uni-kl.de } 24712027Sjungma@eit.uni-kl.de 24812027Sjungma@eit.uni-kl.de m_expand = false; 24912027Sjungma@eit.uni-kl.de m_num_read = 0; 25012027Sjungma@eit.uni-kl.de m_num_written = 0; 25112027Sjungma@eit.uni-kl.de m_num_readable = buffer.used(); 25212027Sjungma@eit.uni-kl.de m_num_read_no_notify = 0; 25312027Sjungma@eit.uni-kl.de 25412027Sjungma@eit.uni-kl.de} 25512027Sjungma@eit.uni-kl.de 25612027Sjungma@eit.uni-kl.de} // namespace tlm 25712027Sjungma@eit.uni-kl.de 25812027Sjungma@eit.uni-kl.de#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h" 25912027Sjungma@eit.uni-kl.de#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h" 26012027Sjungma@eit.uni-kl.de#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h" 26112027Sjungma@eit.uni-kl.de 26212027Sjungma@eit.uni-kl.de#endif 26312027Sjungma@eit.uni-kl.de 264