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