11060SN/A/* 21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 31060SN/A * All rights reserved. 41060SN/A * 51060SN/A * Redistribution and use in source and binary forms, with or without 61060SN/A * modification, are permitted provided that the following conditions are 71060SN/A * met: redistributions of source code must retain the above copyright 81060SN/A * notice, this list of conditions and the following disclaimer; 91060SN/A * redistributions in binary form must reproduce the above copyright 101060SN/A * notice, this list of conditions and the following disclaimer in the 111060SN/A * documentation and/or other materials provided with the distribution; 121060SN/A * neither the name of the copyright holders nor the names of its 131060SN/A * contributors may be used to endorse or promote products derived from 141060SN/A * this software without specific prior written permission. 151060SN/A * 161060SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171060SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181060SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191060SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201060SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211060SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221060SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231060SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A * 282760SN/A * Authors: Nathan Binkert 292760SN/A * Kevin Lim 301060SN/A */ 311060SN/A 321060SN/A#ifndef __BASE_TIMEBUF_HH__ 331060SN/A#define __BASE_TIMEBUF_HH__ 341060SN/A 352989SN/A#include <cassert> 363918SN/A#include <cstring> 371060SN/A#include <vector> 381060SN/A 391060SN/Atemplate <class T> 401060SN/Aclass TimeBuffer 411060SN/A{ 421060SN/A protected: 431060SN/A int past; 441060SN/A int future; 456227SN/A unsigned size; 465984SN/A int _id; 471060SN/A 481060SN/A char *data; 492291SN/A std::vector<char *> index; 506227SN/A unsigned base; 511060SN/A 5210200SAndrew.Bardsley@arm.com void valid(int idx) const 531060SN/A { 541060SN/A assert (idx >= -past && idx <= future); 551060SN/A } 561060SN/A 571060SN/A public: 581060SN/A friend class wire; 591060SN/A class wire 601060SN/A { 611060SN/A friend class TimeBuffer; 621060SN/A protected: 631060SN/A TimeBuffer<T> *buffer; 641060SN/A int index; 651060SN/A 661060SN/A void set(int idx) 671060SN/A { 681060SN/A buffer->valid(idx); 691060SN/A index = idx; 701060SN/A } 711060SN/A 721060SN/A wire(TimeBuffer<T> *buf, int i) 731060SN/A : buffer(buf), index(i) 741060SN/A { } 751060SN/A 761060SN/A public: 771060SN/A wire() 781060SN/A { } 791060SN/A 801060SN/A wire(const wire &i) 811060SN/A : buffer(i.buffer), index(i.index) 821060SN/A { } 831060SN/A 841060SN/A const wire &operator=(const wire &i) 851060SN/A { 861060SN/A buffer = i.buffer; 871060SN/A set(i.index); 881060SN/A return *this; 891060SN/A } 901060SN/A 911060SN/A const wire &operator=(int idx) 921060SN/A { 931060SN/A set(idx); 941060SN/A return *this; 951060SN/A } 961060SN/A 971060SN/A const wire &operator+=(int offset) 981060SN/A { 991060SN/A set(index + offset); 1001060SN/A return *this; 1011060SN/A } 1021060SN/A 1031060SN/A const wire &operator-=(int offset) 1041060SN/A { 1051060SN/A set(index - offset); 1061060SN/A return *this; 1071060SN/A } 1081060SN/A 1091060SN/A wire &operator++() 1101060SN/A { 1111060SN/A set(index + 1); 1121060SN/A return *this; 1131060SN/A } 1141060SN/A 1151060SN/A wire &operator++(int) 1161060SN/A { 1171060SN/A int i = index; 1181060SN/A set(index + 1); 1191060SN/A return wire(this, i); 1201060SN/A } 1211060SN/A 1221060SN/A wire &operator--() 1231060SN/A { 1241060SN/A set(index - 1); 1251060SN/A return *this; 1261060SN/A } 1271060SN/A 1281060SN/A wire &operator--(int) 1291060SN/A { 1301060SN/A int i = index; 1311060SN/A set(index - 1); 1321060SN/A return wire(this, i); 1331060SN/A } 1341060SN/A T &operator*() const { return *buffer->access(index); } 1351060SN/A T *operator->() const { return buffer->access(index); } 1361060SN/A }; 1371060SN/A 1381060SN/A 1391060SN/A public: 1401060SN/A TimeBuffer(int p, int f) 14111320Ssteve.reinhardt@amd.com : past(p), future(f), size(past + future + 1), 1421060SN/A data(new char[size * sizeof(T)]), index(size), base(0) 1431060SN/A { 1441060SN/A assert(past >= 0 && future >= 0); 1451060SN/A char *ptr = data; 1466227SN/A for (unsigned i = 0; i < size; i++) { 1471060SN/A index[i] = ptr; 1483918SN/A std::memset(ptr, 0, sizeof(T)); 1491060SN/A new (ptr) T; 1501060SN/A ptr += sizeof(T); 1511060SN/A } 1525984SN/A 1535984SN/A _id = -1; 1541060SN/A } 1551060SN/A 1561060SN/A TimeBuffer() 1571060SN/A : data(NULL) 1581060SN/A { 1591060SN/A } 1601060SN/A 1611060SN/A ~TimeBuffer() 1621060SN/A { 1636227SN/A for (unsigned i = 0; i < size; ++i) 1641060SN/A (reinterpret_cast<T *>(index[i]))->~T(); 1651060SN/A delete [] data; 1661060SN/A } 1671060SN/A 1685984SN/A void id(int id) 1695984SN/A { 1705984SN/A _id = id; 1715984SN/A } 1725984SN/A 1735984SN/A int id() 1745984SN/A { 1755984SN/A return _id; 1765984SN/A } 1775984SN/A 1781060SN/A void 1791060SN/A advance() 1801060SN/A { 1811060SN/A if (++base >= size) 1821060SN/A base = 0; 1831060SN/A 1841060SN/A int ptr = base + future; 1856227SN/A if (ptr >= (int)size) 1861060SN/A ptr -= size; 1871060SN/A (reinterpret_cast<T *>(index[ptr]))->~T(); 1883918SN/A std::memset(index[ptr], 0, sizeof(T)); 1891060SN/A new (index[ptr]) T; 1901060SN/A } 1911060SN/A 19210200SAndrew.Bardsley@arm.com protected: 19310200SAndrew.Bardsley@arm.com //Calculate the index into this->index for element at position idx 19410200SAndrew.Bardsley@arm.com //relative to now 19510200SAndrew.Bardsley@arm.com inline int calculateVectorIndex(int idx) const 1961060SN/A { 1971060SN/A //Need more complex math here to calculate index. 1981060SN/A valid(idx); 1991060SN/A 2001060SN/A int vector_index = idx + base; 2016227SN/A if (vector_index >= (int)size) { 2021060SN/A vector_index -= size; 2031060SN/A } else if (vector_index < 0) { 2041060SN/A vector_index += size; 2051060SN/A } 2061060SN/A 20710200SAndrew.Bardsley@arm.com return vector_index; 20810200SAndrew.Bardsley@arm.com } 20910200SAndrew.Bardsley@arm.com 21010200SAndrew.Bardsley@arm.com public: 21110200SAndrew.Bardsley@arm.com T *access(int idx) 21210200SAndrew.Bardsley@arm.com { 21310200SAndrew.Bardsley@arm.com int vector_index = calculateVectorIndex(idx); 21410200SAndrew.Bardsley@arm.com 2151060SN/A return reinterpret_cast<T *>(index[vector_index]); 2161060SN/A } 2171060SN/A 2181060SN/A T &operator[](int idx) 2191060SN/A { 22010200SAndrew.Bardsley@arm.com int vector_index = calculateVectorIndex(idx); 2211060SN/A 2221060SN/A return reinterpret_cast<T &>(*index[vector_index]); 2231060SN/A } 2241060SN/A 22510200SAndrew.Bardsley@arm.com const T &operator[] (int idx) const 22610200SAndrew.Bardsley@arm.com { 22710200SAndrew.Bardsley@arm.com int vector_index = calculateVectorIndex(idx); 22810200SAndrew.Bardsley@arm.com 22910200SAndrew.Bardsley@arm.com return reinterpret_cast<const T &>(*index[vector_index]); 23010200SAndrew.Bardsley@arm.com } 23110200SAndrew.Bardsley@arm.com 2321060SN/A wire getWire(int idx) 2331060SN/A { 2341060SN/A valid(idx); 2351060SN/A 2361060SN/A return wire(this, idx); 2371060SN/A } 2381060SN/A 2391060SN/A wire zero() 2401060SN/A { 2411060SN/A return wire(this, 0); 2421060SN/A } 2432873SN/A 2446227SN/A unsigned getSize() 2452873SN/A { 2462873SN/A return size; 2472873SN/A } 2481060SN/A}; 2491060SN/A 2501060SN/A#endif // __BASE_TIMEBUF_HH__ 2511060SN/A 252