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//
2112027Sjungma@eit.uni-kl.de// To the LRM writer : this class is purely an artifact of the implementation.
2212027Sjungma@eit.uni-kl.de//
2312027Sjungma@eit.uni-kl.de
2412027Sjungma@eit.uni-kl.de#ifndef __CIRCULAR_BUFFER_H__
2512027Sjungma@eit.uni-kl.de#define __CIRCULAR_BUFFER_H__
2612027Sjungma@eit.uni-kl.de
2712027Sjungma@eit.uni-kl.de#include <iostream>
2812027Sjungma@eit.uni-kl.de
2912027Sjungma@eit.uni-kl.denamespace tlm {
3012027Sjungma@eit.uni-kl.de
3112027Sjungma@eit.uni-kl.detemplate < typename T >
3212027Sjungma@eit.uni-kl.declass circular_buffer
3312027Sjungma@eit.uni-kl.de{
3412027Sjungma@eit.uni-kl.depublic:
3512027Sjungma@eit.uni-kl.de
3612027Sjungma@eit.uni-kl.de  explicit
3712027Sjungma@eit.uni-kl.de  circular_buffer( int size = 0 );
3812027Sjungma@eit.uni-kl.de  ~circular_buffer();
3912027Sjungma@eit.uni-kl.de
4012027Sjungma@eit.uni-kl.de  void resize( int size );
4112027Sjungma@eit.uni-kl.de  void clear();
4212027Sjungma@eit.uni-kl.de
4312027Sjungma@eit.uni-kl.de  T read();
4412027Sjungma@eit.uni-kl.de  void write( const T & );
4512027Sjungma@eit.uni-kl.de
4612027Sjungma@eit.uni-kl.de  bool is_empty() const { return used() == 0; }
4712027Sjungma@eit.uni-kl.de  bool is_full() const { return free() == 0; }
4812027Sjungma@eit.uni-kl.de
4912027Sjungma@eit.uni-kl.de  int size() const { return m_size; }
5012027Sjungma@eit.uni-kl.de  int used() const { return m_used; }
5112027Sjungma@eit.uni-kl.de  int free() const { return m_free; }
5212027Sjungma@eit.uni-kl.de
5312027Sjungma@eit.uni-kl.de  const T& read_data() const
5412027Sjungma@eit.uni-kl.de    { return buf_read( m_buf, m_ri ); }
5512027Sjungma@eit.uni-kl.de
5612027Sjungma@eit.uni-kl.de  const T& peek_data( int i ) const
5712027Sjungma@eit.uni-kl.de    { return buf_read( m_buf, (m_ri + i) % size() ); }
5812027Sjungma@eit.uni-kl.de
5912027Sjungma@eit.uni-kl.de  T & poke_data( int i )
6012027Sjungma@eit.uni-kl.de    { return buf_read( m_buf , (m_wi + i) % size() ); }
6112027Sjungma@eit.uni-kl.de
6212027Sjungma@eit.uni-kl.de  void debug() const;
6312027Sjungma@eit.uni-kl.de
6412027Sjungma@eit.uni-kl.deprivate:
6512027Sjungma@eit.uni-kl.de  void increment_write_pos( int i = 1 );
6612027Sjungma@eit.uni-kl.de  void increment_read_pos( int i = 1 );
6712027Sjungma@eit.uni-kl.de
6812027Sjungma@eit.uni-kl.de  void init();
6912027Sjungma@eit.uni-kl.de
7012027Sjungma@eit.uni-kl.de  circular_buffer( const circular_buffer<T> &b );              // disabled
7112027Sjungma@eit.uni-kl.de  circular_buffer<T> &operator=( const circular_buffer<T> & ); // disabled
7212027Sjungma@eit.uni-kl.de
7312027Sjungma@eit.uni-kl.de  void* buf_alloc( int size );
7412027Sjungma@eit.uni-kl.de  void  buf_free( void*& buf );
7512027Sjungma@eit.uni-kl.de  void  buf_write( void* buf, int n, const T & t );
7612027Sjungma@eit.uni-kl.de  T&    buf_read( void* buf, int n ) const;
7712027Sjungma@eit.uni-kl.de  void  buf_clear( void* buf, int n );
7812027Sjungma@eit.uni-kl.de
7912027Sjungma@eit.uni-kl.deprivate:
8012027Sjungma@eit.uni-kl.de  int    m_size;                   // size of the buffer
8112027Sjungma@eit.uni-kl.de  void*  m_buf;                    // the buffer
8212027Sjungma@eit.uni-kl.de  int    m_free;                   // number of free spaces
8312027Sjungma@eit.uni-kl.de  int    m_used;                   // number of used spaces
8412027Sjungma@eit.uni-kl.de  int    m_ri;                     // index of next read
8512027Sjungma@eit.uni-kl.de  int    m_wi;                     // index of next write
8612027Sjungma@eit.uni-kl.de
8712027Sjungma@eit.uni-kl.de};
8812027Sjungma@eit.uni-kl.de
8912027Sjungma@eit.uni-kl.detemplate< typename T >
9012027Sjungma@eit.uni-kl.devoid
9112027Sjungma@eit.uni-kl.decircular_buffer<T>::debug() const
9212027Sjungma@eit.uni-kl.de{
9312027Sjungma@eit.uni-kl.de
9412027Sjungma@eit.uni-kl.de  std::cout << "Buffer debug" << std::endl;
9512027Sjungma@eit.uni-kl.de  std::cout << "Size : " << size() << std::endl;
9612027Sjungma@eit.uni-kl.de  std::cout << "Free/Used " << free() << "/" << used() << std::endl;
9712027Sjungma@eit.uni-kl.de  std::cout << "Indices : r/w = " << m_ri << "/" << m_wi << std::endl;
9812027Sjungma@eit.uni-kl.de
9912027Sjungma@eit.uni-kl.de  if( is_empty() ) {
10012027Sjungma@eit.uni-kl.de
10112027Sjungma@eit.uni-kl.de    std::cout << "empty" << std::endl;
10212027Sjungma@eit.uni-kl.de
10312027Sjungma@eit.uni-kl.de  }
10412027Sjungma@eit.uni-kl.de
10512027Sjungma@eit.uni-kl.de  if( is_full() ) {
10612027Sjungma@eit.uni-kl.de
10712027Sjungma@eit.uni-kl.de    std::cout << "full" << std::endl;
10812027Sjungma@eit.uni-kl.de
10912027Sjungma@eit.uni-kl.de  }
11012027Sjungma@eit.uni-kl.de
11112027Sjungma@eit.uni-kl.de  std::cout << "Data : " << std::endl;
11212027Sjungma@eit.uni-kl.de  for( int i = 0; i < used(); i++ ) {
11312027Sjungma@eit.uni-kl.de
11412027Sjungma@eit.uni-kl.de    std::cout << peek_data( i ) << std::endl;
11512027Sjungma@eit.uni-kl.de
11612027Sjungma@eit.uni-kl.de  }
11712027Sjungma@eit.uni-kl.de
11812027Sjungma@eit.uni-kl.de
11912027Sjungma@eit.uni-kl.de}
12012027Sjungma@eit.uni-kl.de
12112027Sjungma@eit.uni-kl.detemplate < typename T >
12212027Sjungma@eit.uni-kl.decircular_buffer<T>::circular_buffer( int size )
12312027Sjungma@eit.uni-kl.de  : m_size(size)
12412027Sjungma@eit.uni-kl.de  , m_buf(0)
12512027Sjungma@eit.uni-kl.de{
12612027Sjungma@eit.uni-kl.de  init();
12712027Sjungma@eit.uni-kl.de
12812027Sjungma@eit.uni-kl.de}
12912027Sjungma@eit.uni-kl.de
13012027Sjungma@eit.uni-kl.detemplate < typename T >
13112027Sjungma@eit.uni-kl.devoid
13212027Sjungma@eit.uni-kl.decircular_buffer<T>::clear()
13312027Sjungma@eit.uni-kl.de{
13412027Sjungma@eit.uni-kl.de  for( int i=0; i < used(); i++ ) {
13512027Sjungma@eit.uni-kl.de    buf_clear( m_buf, i );
13612027Sjungma@eit.uni-kl.de  }
13712027Sjungma@eit.uni-kl.de  m_free = m_size;
13812027Sjungma@eit.uni-kl.de  m_used = m_ri = m_wi = 0;
13912027Sjungma@eit.uni-kl.de}
14012027Sjungma@eit.uni-kl.de
14112027Sjungma@eit.uni-kl.detemplate < typename T >
14212027Sjungma@eit.uni-kl.decircular_buffer<T>::~circular_buffer()
14312027Sjungma@eit.uni-kl.de{
14412027Sjungma@eit.uni-kl.de  clear();
14512027Sjungma@eit.uni-kl.de  buf_free( m_buf );
14612027Sjungma@eit.uni-kl.de}
14712027Sjungma@eit.uni-kl.de
14812027Sjungma@eit.uni-kl.detemplate < typename T >
14912027Sjungma@eit.uni-kl.devoid
15012027Sjungma@eit.uni-kl.decircular_buffer<T>::resize( int size )
15112027Sjungma@eit.uni-kl.de{
15212027Sjungma@eit.uni-kl.de
15312027Sjungma@eit.uni-kl.de  int i;
15412027Sjungma@eit.uni-kl.de  void * new_buf = buf_alloc(size);
15512027Sjungma@eit.uni-kl.de
15612027Sjungma@eit.uni-kl.de  for( i = 0; i < size && i < used(); i++ ) {
15712027Sjungma@eit.uni-kl.de
15812027Sjungma@eit.uni-kl.de    buf_write( new_buf, i, peek_data( i ) );
15912027Sjungma@eit.uni-kl.de    buf_clear( m_buf, (m_ri + i) % m_size );
16012027Sjungma@eit.uni-kl.de
16112027Sjungma@eit.uni-kl.de  }
16212027Sjungma@eit.uni-kl.de
16312027Sjungma@eit.uni-kl.de  buf_free( m_buf );
16412027Sjungma@eit.uni-kl.de
16512027Sjungma@eit.uni-kl.de  m_size = size;
16612027Sjungma@eit.uni-kl.de  m_ri   = 0;
16712027Sjungma@eit.uni-kl.de  m_wi   = i % m_size;
16812027Sjungma@eit.uni-kl.de  m_used = i;
16912027Sjungma@eit.uni-kl.de  m_free = m_size - m_used;
17012027Sjungma@eit.uni-kl.de
17112027Sjungma@eit.uni-kl.de  m_buf  = new_buf;
17212027Sjungma@eit.uni-kl.de}
17312027Sjungma@eit.uni-kl.de
17412027Sjungma@eit.uni-kl.de
17512027Sjungma@eit.uni-kl.detemplate < typename T >
17612027Sjungma@eit.uni-kl.devoid
17712027Sjungma@eit.uni-kl.decircular_buffer<T>::init() {
17812027Sjungma@eit.uni-kl.de
17912027Sjungma@eit.uni-kl.de  if( m_size > 0 ) {
18012027Sjungma@eit.uni-kl.de    m_buf = buf_alloc( m_size );
18112027Sjungma@eit.uni-kl.de  }
18212027Sjungma@eit.uni-kl.de
18312027Sjungma@eit.uni-kl.de  m_free = m_size;
18412027Sjungma@eit.uni-kl.de  m_used = 0;
18512027Sjungma@eit.uni-kl.de  m_ri = 0;
18612027Sjungma@eit.uni-kl.de  m_wi = 0;
18712027Sjungma@eit.uni-kl.de
18812027Sjungma@eit.uni-kl.de}
18912027Sjungma@eit.uni-kl.de
19012027Sjungma@eit.uni-kl.detemplate < typename T >
19112027Sjungma@eit.uni-kl.deT
19212027Sjungma@eit.uni-kl.decircular_buffer<T>::read()
19312027Sjungma@eit.uni-kl.de{
19412027Sjungma@eit.uni-kl.de  T t = read_data();
19512027Sjungma@eit.uni-kl.de
19612027Sjungma@eit.uni-kl.de  buf_clear( m_buf, m_ri );
19712027Sjungma@eit.uni-kl.de  increment_read_pos();
19812027Sjungma@eit.uni-kl.de
19912027Sjungma@eit.uni-kl.de  return t;
20012027Sjungma@eit.uni-kl.de}
20112027Sjungma@eit.uni-kl.de
20212027Sjungma@eit.uni-kl.detemplate < typename T >
20312027Sjungma@eit.uni-kl.devoid
20412027Sjungma@eit.uni-kl.decircular_buffer<T>::write( const T &t )
20512027Sjungma@eit.uni-kl.de{
20612027Sjungma@eit.uni-kl.de  buf_write( m_buf, m_wi, t );
20712027Sjungma@eit.uni-kl.de  increment_write_pos();
20812027Sjungma@eit.uni-kl.de}
20912027Sjungma@eit.uni-kl.de
21012027Sjungma@eit.uni-kl.de
21112027Sjungma@eit.uni-kl.detemplate < typename T >
21212027Sjungma@eit.uni-kl.devoid
21312027Sjungma@eit.uni-kl.decircular_buffer<T>::increment_write_pos( int i ) {
21412027Sjungma@eit.uni-kl.de
21512027Sjungma@eit.uni-kl.de  m_wi = ( m_wi + i ) % m_size;
21612027Sjungma@eit.uni-kl.de  m_used += i;
21712027Sjungma@eit.uni-kl.de  m_free -= i;
21812027Sjungma@eit.uni-kl.de
21912027Sjungma@eit.uni-kl.de}
22012027Sjungma@eit.uni-kl.de
22112027Sjungma@eit.uni-kl.detemplate < typename T >
22212027Sjungma@eit.uni-kl.devoid
22312027Sjungma@eit.uni-kl.decircular_buffer<T>::increment_read_pos( int i ) {
22412027Sjungma@eit.uni-kl.de
22512027Sjungma@eit.uni-kl.de  m_ri = ( m_ri + i ) % m_size;
22612027Sjungma@eit.uni-kl.de  m_used -= i;
22712027Sjungma@eit.uni-kl.de  m_free += i;
22812027Sjungma@eit.uni-kl.de
22912027Sjungma@eit.uni-kl.de}
23012027Sjungma@eit.uni-kl.de
23112027Sjungma@eit.uni-kl.detemplate < typename T >
23212027Sjungma@eit.uni-kl.deinline void*
23312027Sjungma@eit.uni-kl.decircular_buffer<T>::buf_alloc( int size )
23412027Sjungma@eit.uni-kl.de    { return new unsigned char[ size * sizeof(T) ]; }
23512027Sjungma@eit.uni-kl.de
23612027Sjungma@eit.uni-kl.detemplate < typename T >
23712027Sjungma@eit.uni-kl.deinline void
23812027Sjungma@eit.uni-kl.decircular_buffer<T>::buf_free( void* & buf )
23912027Sjungma@eit.uni-kl.de    { delete [] static_cast<unsigned char*>(buf); buf = 0; }
24012027Sjungma@eit.uni-kl.de
24112027Sjungma@eit.uni-kl.detemplate < typename T >
24212027Sjungma@eit.uni-kl.deinline void
24312027Sjungma@eit.uni-kl.decircular_buffer<T>::buf_write( void* buf, int n, const T & t )
24412027Sjungma@eit.uni-kl.de{
24512027Sjungma@eit.uni-kl.de  T* p = static_cast<T*>(buf) + n;
24612027Sjungma@eit.uni-kl.de  new (p) T(t);
24712027Sjungma@eit.uni-kl.de}
24812027Sjungma@eit.uni-kl.de
24912027Sjungma@eit.uni-kl.detemplate < typename T >
25012027Sjungma@eit.uni-kl.deinline T&
25112027Sjungma@eit.uni-kl.decircular_buffer<T>::buf_read( void* buf, int n ) const
25212027Sjungma@eit.uni-kl.de{
25312027Sjungma@eit.uni-kl.de  T* p = static_cast<T*>(buf) + n;
25412027Sjungma@eit.uni-kl.de  return *p;
25512027Sjungma@eit.uni-kl.de}
25612027Sjungma@eit.uni-kl.de
25712027Sjungma@eit.uni-kl.detemplate < typename T >
25812027Sjungma@eit.uni-kl.deinline void
25912027Sjungma@eit.uni-kl.decircular_buffer<T>::buf_clear( void* buf, int n )
26012027Sjungma@eit.uni-kl.de{
26112027Sjungma@eit.uni-kl.de  T* p = static_cast<T*>(buf) + n;
26212027Sjungma@eit.uni-kl.de  p->~T();
26312027Sjungma@eit.uni-kl.de}
26412027Sjungma@eit.uni-kl.de
26512027Sjungma@eit.uni-kl.de} // namespace tlm
26612027Sjungma@eit.uni-kl.de
26712027Sjungma@eit.uni-kl.de#endif
26812027Sjungma@eit.uni-kl.de
269