113521Sgabeblack@google.com/***************************************************************************** 213521Sgabeblack@google.com 313521Sgabeblack@google.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 413521Sgabeblack@google.com more contributor license agreements. See the NOTICE file distributed 513521Sgabeblack@google.com with this work for additional information regarding copyright ownership. 613521Sgabeblack@google.com Accellera licenses this file to you under the Apache License, Version 2.0 713521Sgabeblack@google.com (the "License"); you may not use this file except in compliance with the 813521Sgabeblack@google.com License. You may obtain a copy of the License at 913521Sgabeblack@google.com 1013521Sgabeblack@google.com http://www.apache.org/licenses/LICENSE-2.0 1113521Sgabeblack@google.com 1213521Sgabeblack@google.com Unless required by applicable law or agreed to in writing, software 1313521Sgabeblack@google.com distributed under the License is distributed on an "AS IS" BASIS, 1413521Sgabeblack@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1513521Sgabeblack@google.com implied. See the License for the specific language governing 1613521Sgabeblack@google.com permissions and limitations under the License. 1713521Sgabeblack@google.com 1813521Sgabeblack@google.com *****************************************************************************/ 1913521Sgabeblack@google.com 2013521Sgabeblack@google.com#ifndef __TLM_CORE_1_REQ_RSP_CHANNELS_FIFO_CIRCULAR_BUFFER_HH__ 2113521Sgabeblack@google.com#define __TLM_CORE_1_REQ_RSP_CHANNELS_FIFO_CIRCULAR_BUFFER_HH__ 2213521Sgabeblack@google.com 2313521Sgabeblack@google.com#include <iostream> 2413521Sgabeblack@google.com 2513521Sgabeblack@google.comnamespace tlm 2613521Sgabeblack@google.com{ 2713521Sgabeblack@google.com 2813521Sgabeblack@google.comtemplate <typename T> 2913521Sgabeblack@google.comclass circular_buffer 3013521Sgabeblack@google.com{ 3113521Sgabeblack@google.com public: 3213521Sgabeblack@google.com explicit circular_buffer(int size=0); 3313521Sgabeblack@google.com ~circular_buffer(); 3413521Sgabeblack@google.com 3513521Sgabeblack@google.com void resize(int size); 3613521Sgabeblack@google.com void clear(); 3713521Sgabeblack@google.com 3813521Sgabeblack@google.com T read(); 3913521Sgabeblack@google.com void write(const T &); 4013521Sgabeblack@google.com 4113521Sgabeblack@google.com bool is_empty() const { return used() == 0; } 4213521Sgabeblack@google.com bool is_full() const { return free() == 0; } 4313521Sgabeblack@google.com 4413521Sgabeblack@google.com int size() const { return m_size; } 4513521Sgabeblack@google.com int used() const { return m_used; } 4613521Sgabeblack@google.com int free() const { return m_free; } 4713521Sgabeblack@google.com 4813521Sgabeblack@google.com const T &read_data() const { return buf_read(m_buf, m_ri); } 4913521Sgabeblack@google.com const T & 5013521Sgabeblack@google.com peek_data(int i) const 5113521Sgabeblack@google.com { 5213521Sgabeblack@google.com return buf_read(m_buf, (m_ri + i) % size()); 5313521Sgabeblack@google.com } 5413521Sgabeblack@google.com 5513521Sgabeblack@google.com T & 5613521Sgabeblack@google.com poke_data(int i) 5713521Sgabeblack@google.com { 5813521Sgabeblack@google.com return buf_read(m_buf, (m_wi + i) % size()); 5913521Sgabeblack@google.com } 6013521Sgabeblack@google.com 6113521Sgabeblack@google.com void debug() const; 6213521Sgabeblack@google.com 6313521Sgabeblack@google.com private: 6413521Sgabeblack@google.com void increment_write_pos(int i=1); 6513521Sgabeblack@google.com void increment_read_pos(int i=1); 6613521Sgabeblack@google.com 6713521Sgabeblack@google.com void init(); 6813521Sgabeblack@google.com 6913521Sgabeblack@google.com // Disabled. 7013521Sgabeblack@google.com circular_buffer(const circular_buffer<T> &b); 7113521Sgabeblack@google.com circular_buffer<T> &operator = (const circular_buffer<T> &); 7213521Sgabeblack@google.com 7313521Sgabeblack@google.com void *buf_alloc(int size); 7413521Sgabeblack@google.com void buf_free(void *&buf); 7513521Sgabeblack@google.com void buf_write(void *buf, int n, const T &t); 7613521Sgabeblack@google.com T &buf_read(void *buf, int n) const; 7713521Sgabeblack@google.com void buf_clear(void *buf, int n); 7813521Sgabeblack@google.com 7913521Sgabeblack@google.com private: 8013521Sgabeblack@google.com int m_size; // size of the buffer 8113521Sgabeblack@google.com void *m_buf; // the buffer 8213521Sgabeblack@google.com int m_free; // number of free spaces 8313521Sgabeblack@google.com int m_used; // number of used spaces 8413521Sgabeblack@google.com int m_ri; // index of next read 8513521Sgabeblack@google.com int m_wi; // index of next write 8613521Sgabeblack@google.com}; 8713521Sgabeblack@google.com 8813521Sgabeblack@google.comtemplate <typename T> 8913521Sgabeblack@google.comvoid 9013521Sgabeblack@google.comcircular_buffer<T>::debug() const 9113521Sgabeblack@google.com{ 9213521Sgabeblack@google.com std::cout << "Buffer debug" << std::endl; 9313521Sgabeblack@google.com std::cout << "Size : " << size() << std::endl; 9413521Sgabeblack@google.com std::cout << "Free/Used " << free() << "/" << used() << std::endl; 9513521Sgabeblack@google.com std::cout << "Indices : r/w = " << m_ri << "/" << m_wi << std::endl; 9613521Sgabeblack@google.com 9713521Sgabeblack@google.com if (is_empty()) { 9813521Sgabeblack@google.com std::cout << "empty" << std::endl; 9913521Sgabeblack@google.com } 10013521Sgabeblack@google.com 10113521Sgabeblack@google.com if (is_full()) { 10213521Sgabeblack@google.com std::cout << "full" << std::endl; 10313521Sgabeblack@google.com } 10413521Sgabeblack@google.com 10513521Sgabeblack@google.com std::cout << "Data : " << std::endl; 10613521Sgabeblack@google.com for (int i = 0; i < used(); i++) { 10713521Sgabeblack@google.com std::cout << peek_data( i ) << std::endl; 10813521Sgabeblack@google.com } 10913521Sgabeblack@google.com} 11013521Sgabeblack@google.com 11113521Sgabeblack@google.comtemplate <typename T> 11213521Sgabeblack@google.comcircular_buffer<T>::circular_buffer(int size) : m_size(size), m_buf(0) 11313521Sgabeblack@google.com{ 11413521Sgabeblack@google.com init(); 11513521Sgabeblack@google.com} 11613521Sgabeblack@google.com 11713521Sgabeblack@google.comtemplate <typename T> 11813521Sgabeblack@google.comvoid 11913521Sgabeblack@google.comcircular_buffer<T>::clear() 12013521Sgabeblack@google.com{ 12113521Sgabeblack@google.com for (int i = 0; i < used(); i++) { 12213521Sgabeblack@google.com buf_clear(m_buf, (m_ri + i) % m_size); 12313521Sgabeblack@google.com } 12413521Sgabeblack@google.com m_free = m_size; 12513521Sgabeblack@google.com m_used = m_ri = m_wi = 0; 12613521Sgabeblack@google.com} 12713521Sgabeblack@google.com 12813521Sgabeblack@google.comtemplate <typename T> 12913521Sgabeblack@google.comcircular_buffer<T>::~circular_buffer() 13013521Sgabeblack@google.com{ 13113521Sgabeblack@google.com clear(); 13213521Sgabeblack@google.com buf_free(m_buf); 13313521Sgabeblack@google.com} 13413521Sgabeblack@google.com 13513521Sgabeblack@google.comtemplate <typename T> 13613521Sgabeblack@google.comvoid 13713521Sgabeblack@google.comcircular_buffer<T>::resize(int size) 13813521Sgabeblack@google.com{ 13913521Sgabeblack@google.com int i; 14013521Sgabeblack@google.com void *new_buf = buf_alloc(size); 14113521Sgabeblack@google.com 14213521Sgabeblack@google.com for (i = 0; i < size && i < used(); i++) { 14313521Sgabeblack@google.com buf_write(new_buf, i, peek_data(i)); 14413521Sgabeblack@google.com buf_clear(m_buf, (m_ri + i) % m_size); 14513521Sgabeblack@google.com } 14613521Sgabeblack@google.com 14713521Sgabeblack@google.com buf_free(m_buf); 14813521Sgabeblack@google.com 14913521Sgabeblack@google.com m_size = size; 15013521Sgabeblack@google.com m_ri = 0; 15113521Sgabeblack@google.com m_wi = i % m_size; 15213521Sgabeblack@google.com m_used = i; 15313521Sgabeblack@google.com m_free = m_size - m_used; 15413521Sgabeblack@google.com 15513521Sgabeblack@google.com m_buf = new_buf; 15613521Sgabeblack@google.com} 15713521Sgabeblack@google.com 15813521Sgabeblack@google.com 15913521Sgabeblack@google.comtemplate <typename T> 16013521Sgabeblack@google.comvoid 16113521Sgabeblack@google.comcircular_buffer<T>::init() 16213521Sgabeblack@google.com{ 16313521Sgabeblack@google.com if (m_size > 0) { 16413521Sgabeblack@google.com m_buf = buf_alloc(m_size); 16513521Sgabeblack@google.com } 16613521Sgabeblack@google.com 16713521Sgabeblack@google.com m_free = m_size; 16813521Sgabeblack@google.com m_used = 0; 16913521Sgabeblack@google.com m_ri = 0; 17013521Sgabeblack@google.com m_wi = 0; 17113521Sgabeblack@google.com} 17213521Sgabeblack@google.com 17313521Sgabeblack@google.comtemplate <typename T> 17413521Sgabeblack@google.comT 17513521Sgabeblack@google.comcircular_buffer<T>::read() 17613521Sgabeblack@google.com{ 17713521Sgabeblack@google.com T t = read_data(); 17813521Sgabeblack@google.com 17913521Sgabeblack@google.com buf_clear(m_buf, m_ri); 18013521Sgabeblack@google.com increment_read_pos(); 18113521Sgabeblack@google.com 18213521Sgabeblack@google.com return t; 18313521Sgabeblack@google.com} 18413521Sgabeblack@google.com 18513521Sgabeblack@google.comtemplate <typename T> 18613521Sgabeblack@google.comvoid 18713521Sgabeblack@google.comcircular_buffer<T>::write(const T &t) 18813521Sgabeblack@google.com{ 18913521Sgabeblack@google.com buf_write(m_buf, m_wi, t); 19013521Sgabeblack@google.com increment_write_pos(); 19113521Sgabeblack@google.com} 19213521Sgabeblack@google.com 19313521Sgabeblack@google.comtemplate <typename T> 19413521Sgabeblack@google.comvoid 19513521Sgabeblack@google.comcircular_buffer<T>::increment_write_pos(int i) 19613521Sgabeblack@google.com{ 19713521Sgabeblack@google.com m_wi = (m_wi + i) % m_size; 19813521Sgabeblack@google.com m_used += i; 19913521Sgabeblack@google.com m_free -= i; 20013521Sgabeblack@google.com} 20113521Sgabeblack@google.com 20213521Sgabeblack@google.comtemplate <typename T> 20313521Sgabeblack@google.comvoid 20413521Sgabeblack@google.comcircular_buffer<T>::increment_read_pos(int i) 20513521Sgabeblack@google.com{ 20613521Sgabeblack@google.com m_ri = (m_ri + i) % m_size; 20713521Sgabeblack@google.com m_used -= i; 20813521Sgabeblack@google.com m_free += i; 20913521Sgabeblack@google.com} 21013521Sgabeblack@google.com 21113521Sgabeblack@google.comtemplate <typename T> 21213521Sgabeblack@google.cominline void * 21313521Sgabeblack@google.comcircular_buffer<T>::buf_alloc(int size) 21413521Sgabeblack@google.com{ 21513521Sgabeblack@google.com return new unsigned char [size * sizeof(T)]; 21613521Sgabeblack@google.com} 21713521Sgabeblack@google.com 21813521Sgabeblack@google.comtemplate <typename T> 21913521Sgabeblack@google.cominline void 22013521Sgabeblack@google.comcircular_buffer<T>::buf_free(void *&buf) 22113521Sgabeblack@google.com{ 22213521Sgabeblack@google.com delete [] static_cast<unsigned char *>(buf); 22313521Sgabeblack@google.com buf = nullptr; 22413521Sgabeblack@google.com} 22513521Sgabeblack@google.com 22613521Sgabeblack@google.comtemplate <typename T> 22713521Sgabeblack@google.cominline void 22813521Sgabeblack@google.comcircular_buffer<T>::buf_write(void *buf, int n, const T &t) 22913521Sgabeblack@google.com{ 23013521Sgabeblack@google.com T *p = static_cast<T *>(buf) + n; 23113521Sgabeblack@google.com new (p)T(t); 23213521Sgabeblack@google.com} 23313521Sgabeblack@google.com 23413521Sgabeblack@google.comtemplate <typename T> 23513521Sgabeblack@google.cominline T & 23613521Sgabeblack@google.comcircular_buffer<T>::buf_read(void *buf, int n) const 23713521Sgabeblack@google.com{ 23813521Sgabeblack@google.com T *p = static_cast<T *>(buf) + n; 23913521Sgabeblack@google.com return *p; 24013521Sgabeblack@google.com} 24113521Sgabeblack@google.com 24213521Sgabeblack@google.comtemplate <typename T> 24313521Sgabeblack@google.cominline void 24413521Sgabeblack@google.comcircular_buffer<T>::buf_clear(void *buf, int n) 24513521Sgabeblack@google.com{ 24613521Sgabeblack@google.com T *p = static_cast<T *>(buf) + n; 24713521Sgabeblack@google.com p->~T(); 24813521Sgabeblack@google.com} 24913521Sgabeblack@google.com 25013521Sgabeblack@google.com} // namespace tlm 25113521Sgabeblack@google.com 25213521Sgabeblack@google.com#endif /* __TLM_CORE_1_REQ_RSP_CHANNELS_FIFO_CIRCULAR_BUFFER_HH__ */ 253