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