sc_proxy.hh revision 13325
12SN/A/***************************************************************************** 21762SN/A 32SN/A Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 42SN/A more contributor license agreements. See the NOTICE file distributed 52SN/A with this work for additional information regarding copyright ownership. 62SN/A Accellera licenses this file to you under the Apache License, Version 2.0 72SN/A (the "License"); you may not use this file except in compliance with the 82SN/A License. You may obtain a copy of the License at 92SN/A 102SN/A http://www.apache.org/licenses/LICENSE-2.0 112SN/A 122SN/A Unless required by applicable law or agreed to in writing, software 132SN/A distributed under the License is distributed on an "AS IS" BASIS, 142SN/A WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 152SN/A implied. See the License for the specific language governing 162SN/A permissions and limitations under the License. 172SN/A 182SN/A *****************************************************************************/ 192SN/A 202SN/A/***************************************************************************** 212SN/A 222SN/A sc_proxy.h -- Proxy base class for vector data types. 232SN/A 242SN/A This class is created for several purposes: 252SN/A 1) hiding operators from the global namespace that would be 262SN/A otherwise found by Koenig lookup 272665Ssaidi@eecs.umich.edu 2) avoiding repeating the same operations in every class 282665Ssaidi@eecs.umich.edu including proxies that could also be achieved by common 292665Ssaidi@eecs.umich.edu base class, but this method allows 302665Ssaidi@eecs.umich.edu 3) improve performance by using non-virtual functions 312665Ssaidi@eecs.umich.edu 322SN/A Original Author: Gene Bushuyev, Synopsys, Inc. 332SN/A 342SN/A *****************************************************************************/ 352SN/A 363506Ssaidi@eecs.umich.edu/***************************************************************************** 373506Ssaidi@eecs.umich.edu 382SN/A MODIFICATION LOG - modifiers, enter your name, affiliation, date and 392973Sgblack@eecs.umich.edu changes you are making here. 403584Ssaidi@eecs.umich.edu 4156SN/A Name, Affiliation, Date: 423614Sgblack@eecs.umich.edu Description of Modification: 431717SN/A 442518SN/A *****************************************************************************/ 4556SN/A 462518SN/A// $Log: sc_proxy.h,v $ 472518SN/A// Revision 1.3 2010/12/07 20:09:07 acg 482SN/A// Andy Goodrich: Fix for returning enough data 493614Sgblack@eecs.umich.edu// 503614Sgblack@eecs.umich.edu// Revision 1.2 2009/02/28 00:26:14 acg 513614Sgblack@eecs.umich.edu// Andy Goodrich: bug fixes. 523614Sgblack@eecs.umich.edu// 533065Sgblack@eecs.umich.edu// Revision 1.1.1.1 2006/12/15 20:31:36 acg 543065Sgblack@eecs.umich.edu// SystemC 2.2 553506Ssaidi@eecs.umich.edu// 563065Sgblack@eecs.umich.edu// Revision 1.3 2006/01/13 18:53:53 acg 572SN/A// Andy Goodrich: added $Log command so that CVS comments are reproduced in 582973Sgblack@eecs.umich.edu// the source. 592SN/A// 603840Shsul@eecs.umich.edu 613825Ssaidi@eecs.umich.edu#ifndef __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__ 623903Ssaidi@eecs.umich.edu#define __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__ 633840Shsul@eecs.umich.edu 643825Ssaidi@eecs.umich.edu#include <iostream> 653506Ssaidi@eecs.umich.edu 663506Ssaidi@eecs.umich.edu#include "../../utils/functions.hh" 674054Sbinkertn@umich.edu#include "../int/sc_int_base.hh" 684054Sbinkertn@umich.edu#include "../int/sc_signed.hh" 694054Sbinkertn@umich.edu#include "../int/sc_uint_base.hh" 704054Sbinkertn@umich.edu#include "../int/sc_unsigned.hh" 714054Sbinkertn@umich.edu#include "messages.hh" 724054Sbinkertn@umich.edu#include "sc_bit.hh" 734054Sbinkertn@umich.edu#include "sc_logic.hh" 744054Sbinkertn@umich.edu 754054Sbinkertn@umich.edunamespace sc_dt 764054Sbinkertn@umich.edu{ 774054Sbinkertn@umich.edu 784054Sbinkertn@umich.edu// classes defined in this module 794054Sbinkertn@umich.edutemplate <class X> 804054Sbinkertn@umich.educlass sc_proxy; 814054Sbinkertn@umich.edu 824054Sbinkertn@umich.edu// forward class declarations 834054Sbinkertn@umich.educlass sc_bv_base; 844054Sbinkertn@umich.educlass sc_lv_base; 854054Sbinkertn@umich.edutemplate <class X> 864054Sbinkertn@umich.educlass sc_bitref_r; 874054Sbinkertn@umich.edutemplate <class X> 883506Ssaidi@eecs.umich.educlass sc_bitref; 893506Ssaidi@eecs.umich.edutemplate <class X> 902SN/Aclass sc_subref_r; 912SN/Atemplate <class X> 922SN/Aclass sc_subref; 932SN/Atemplate <class X, class Y> 942SN/Aclass sc_concref_r; 953748Sgblack@eecs.umich.edutemplate <class X, class Y> 963748Sgblack@eecs.umich.educlass sc_concref; 973748Sgblack@eecs.umich.edu 983748Sgblack@eecs.umich.educonst int SC_DIGIT_SIZE = BITS_PER_BYTE * sizeof(sc_digit); 993748Sgblack@eecs.umich.edu 1003748Sgblack@eecs.umich.educonst sc_digit SC_DIGIT_ZERO = (sc_digit)0; 1013748Sgblack@eecs.umich.educonst sc_digit SC_DIGIT_ONE = (sc_digit)1; 1023748Sgblack@eecs.umich.educonst sc_digit SC_DIGIT_TWO = (sc_digit)2; 1033748Sgblack@eecs.umich.edu 1043748Sgblack@eecs.umich.eduvoid sc_proxy_out_of_bounds(const char *msg=NULL, int64 val=0); 1053748Sgblack@eecs.umich.edu 1063748Sgblack@eecs.umich.edu// assignment functions; forward declarations 1073748Sgblack@eecs.umich.edu 1083748Sgblack@eecs.umich.edutemplate <class X, class Y> 1093748Sgblack@eecs.umich.eduinline void assign_p_(sc_proxy<X> &px, const sc_proxy<Y> &py); 1103748Sgblack@eecs.umich.edu 1113748Sgblack@eecs.umich.edu// Vector types that are not derived from sc_proxy must have a length() 1123748Sgblack@eecs.umich.edu// function and an operator []. 1133748Sgblack@eecs.umich.edu 1143748Sgblack@eecs.umich.edutemplate <class X, class T> 1153748Sgblack@eecs.umich.eduinline void assign_v_(sc_proxy<X> &px, const T &a); 1163748Sgblack@eecs.umich.edu 1173748Sgblack@eecs.umich.edu// other functions; forward declarations 1183748Sgblack@eecs.umich.educonst std::string convert_to_bin(const char *s); 1193748Sgblack@eecs.umich.educonst std::string convert_to_fmt(const std::string &s, sc_numrep numrep, bool); 1203748Sgblack@eecs.umich.edu 1213748Sgblack@eecs.umich.edu// ---------------------------------------------------------------------------- 1223748Sgblack@eecs.umich.edu// CLASS TEMPLATE : sc_proxy_traits 1233748Sgblack@eecs.umich.edu// 1243748Sgblack@eecs.umich.edu// Template traits helper to select the correct bit/value/vector_types for 1253748Sgblack@eecs.umich.edu// sc_proxy-based vector classes. 1263748Sgblack@eecs.umich.edu// 1273748Sgblack@eecs.umich.edu// All types derived from/based on a bit-vector contain typedef to a plain 1283748Sgblack@eecs.umich.edu// bool, all others point to the sc_logic_value_t/sc_logic/sc_lv_base types. 1293748Sgblack@eecs.umich.edu// ---------------------------------------------------------------------------- 1303748Sgblack@eecs.umich.edu 1313748Sgblack@eecs.umich.edutemplate <typename X> 1323748Sgblack@eecs.umich.edustruct sc_proxy_traits; 1333748Sgblack@eecs.umich.edu 1343748Sgblack@eecs.umich.edutemplate <> 1353748Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_bv_base> 1363748Sgblack@eecs.umich.edu{ 1373748Sgblack@eecs.umich.edu typedef sc_proxy_traits<sc_bv_base> traits_type; 1383748Sgblack@eecs.umich.edu typedef bool value_type; 1393748Sgblack@eecs.umich.edu typedef sc_logic bit_type; // sc_logic needed for mixed expressions 1403748Sgblack@eecs.umich.edu typedef sc_bv_base vector_type; 1413748Sgblack@eecs.umich.edu}; 1423748Sgblack@eecs.umich.edu 1433748Sgblack@eecs.umich.edutemplate <> 1443748Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_lv_base> 1452SN/A{ 1462SN/A typedef sc_proxy_traits<sc_lv_base> traits_type; 1474046Sbinkertn@umich.edu typedef sc_logic_value_t value_type; 1482SN/A typedef sc_logic bit_type; 1494046Sbinkertn@umich.edu typedef sc_lv_base vector_type; 1504046Sbinkertn@umich.edu}; 1513903Ssaidi@eecs.umich.edu 1524054Sbinkertn@umich.edutemplate <typename X> 1532973Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_bitref_r<X> > : sc_proxy_traits<X> {}; 1543065Sgblack@eecs.umich.edu 1553380Sgblack@eecs.umich.edutemplate <typename X> 1563380Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_bitref<X> > : sc_proxy_traits<X> {}; 1573380Sgblack@eecs.umich.edu 1583380Sgblack@eecs.umich.edutemplate <typename X> 1593380Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_subref_r<X> > : sc_proxy_traits<X> {}; 1603380Sgblack@eecs.umich.edu 1613380Sgblack@eecs.umich.edutemplate <typename X> 1623380Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_subref<X> > : sc_proxy_traits<X> {}; 1633380Sgblack@eecs.umich.edu 1643380Sgblack@eecs.umich.edutemplate <typename X> 1653380Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_proxy<X> > : sc_proxy_traits<X> {}; 1663380Sgblack@eecs.umich.edu 1673380Sgblack@eecs.umich.edu 1683380Sgblack@eecs.umich.edutemplate <typename X, typename Y> 1693065Sgblack@eecs.umich.edustruct sc_mixed_proxy_traits_helper : sc_proxy_traits<sc_lv_base> 1703588Sgblack@eecs.umich.edu{}; // logic vector by default 1713588Sgblack@eecs.umich.edu 1723588Sgblack@eecs.umich.edutemplate <typename X> 1733790Sgblack@eecs.umich.edustruct sc_mixed_proxy_traits_helper<X, X> : X {}; 1743790Sgblack@eecs.umich.edu 1753380Sgblack@eecs.umich.edutemplate <typename X, typename Y> 1763059Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_concref_r<X, Y> > : 1773588Sgblack@eecs.umich.edu sc_mixed_proxy_traits_helper< 1783380Sgblack@eecs.umich.edu typename X::traits_type, typename Y::traits_type> 1793380Sgblack@eecs.umich.edu{}; 1803790Sgblack@eecs.umich.edu 1813790Sgblack@eecs.umich.edutemplate <typename X, typename Y> 1823380Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_concref<X, Y> > : 1833380Sgblack@eecs.umich.edu sc_mixed_proxy_traits_helper< 1843588Sgblack@eecs.umich.edu typename X::traits_type, typename Y::traits_type> 1853380Sgblack@eecs.umich.edu{}; 1863380Sgblack@eecs.umich.edu 1873380Sgblack@eecs.umich.edu 1883380Sgblack@eecs.umich.edu// ---------------------------------------------------------------------------- 1893380Sgblack@eecs.umich.edu// CLASS TEMPLATE : sc_proxy 1903059Sgblack@eecs.umich.edu// 1913380Sgblack@eecs.umich.edu// Base class template for bit/logic vector classes. 1923380Sgblack@eecs.umich.edu// (Barton/Nackmann implementation) 1933380Sgblack@eecs.umich.edu// ---------------------------------------------------------------------------- 1943380Sgblack@eecs.umich.edu 1953588Sgblack@eecs.umich.edutemplate <class X> 1963380Sgblack@eecs.umich.educlass sc_proxy // #### : public sc_value_base 1973380Sgblack@eecs.umich.edu{ 1983059Sgblack@eecs.umich.edu public: 1993059Sgblack@eecs.umich.edu typedef typename sc_proxy_traits<X>::traits_type traits_type; 2003380Sgblack@eecs.umich.edu typedef typename traits_type::bit_type bit_type; 2013380Sgblack@eecs.umich.edu typedef typename traits_type::value_type value_type; 2023380Sgblack@eecs.umich.edu 2033380Sgblack@eecs.umich.edu // virtual destructor 2043380Sgblack@eecs.umich.edu virtual ~sc_proxy() {} 2053588Sgblack@eecs.umich.edu 2063380Sgblack@eecs.umich.edu // casts 2073380Sgblack@eecs.umich.edu X &back_cast() { return static_cast<X &>(*this); } 2083380Sgblack@eecs.umich.edu 2093588Sgblack@eecs.umich.edu const X &back_cast() const { return static_cast<const X &>(*this); } 2103059Sgblack@eecs.umich.edu 2113065Sgblack@eecs.umich.edu // assignment operators 2122973Sgblack@eecs.umich.edu template <class Y> 2134054Sbinkertn@umich.edu X & 2144054Sbinkertn@umich.edu assign_(const sc_proxy<Y> &a) 2154054Sbinkertn@umich.edu { 2164054Sbinkertn@umich.edu assign_p_(*this, a); 2174054Sbinkertn@umich.edu return back_cast(); 2184054Sbinkertn@umich.edu } 2194054Sbinkertn@umich.edu 2201904SN/A X &assign_(const char *a); 2214054Sbinkertn@umich.edu X &assign_(const bool *a); 2221904SN/A X &assign_(const sc_logic *a); 2234054Sbinkertn@umich.edu 2244046Sbinkertn@umich.edu X & 225452SN/A assign_(const sc_unsigned &a) 2263064Sgblack@eecs.umich.edu { 2272SN/A assign_v_(*this, a); 2284054Sbinkertn@umich.edu return back_cast(); 2291904SN/A } 2302SN/A 2314054Sbinkertn@umich.edu X & 2323064Sgblack@eecs.umich.edu assign_(const sc_signed &a) 2332SN/A { 2342SN/A assign_v_(*this, a); 2351904SN/A return back_cast(); 2361904SN/A } 2371904SN/A 2382299SN/A X &assign_(const sc_uint_base &a) { return assign_((uint64)a); } 2394054Sbinkertn@umich.edu X &assign_(const sc_int_base &a) { return assign_((int64)a); } 2401904SN/A X &assign_(unsigned int a); 2411904SN/A X &assign_(int a); 2421904SN/A X &assign_(unsigned long a); 2431904SN/A X &assign_(long a); 2441904SN/A X &assign_(uint64 a); 2451904SN/A X &assign_(int64 a); 2461904SN/A 247452SN/A // bitwise operators and functions 2481904SN/A 2491904SN/A // bitwise complement 2501904SN/A X &b_not(); 2512SN/A 2522SN/A const sc_lv_base operator ~ () const; 2531904SN/A 2541904SN/A // bitwise and 2551904SN/A X &operator &= (const char *b); 2561904SN/A X &operator &= (const bool *b); 2571904SN/A X &operator &= (const sc_logic *b); 2581904SN/A X &operator &= (const sc_unsigned &b); 2592SN/A X &operator &= (const sc_signed &b); 2601904SN/A X &operator &= (const sc_uint_base &b) { return operator &= ((uint64)b); } 2612SN/A X &operator &= (const sc_int_base &b) { return operator &= ((int64)b); } 2622SN/A X &operator &= (unsigned long b); 2631904SN/A X &operator &= (long b); 2642SN/A X &operator &= (unsigned int b) { return operator &= ((unsigned long)b); } 2654054Sbinkertn@umich.edu X &operator &= (int b) { return operator &= ((long)b); } 2661904SN/A X &operator &= (uint64 b); 2671904SN/A X &operator &= (int64 b); 2681904SN/A 2694054Sbinkertn@umich.edu const sc_lv_base operator & (const char *b) const; 2701904SN/A const sc_lv_base operator & (const bool *b) const; 2711904SN/A const sc_lv_base operator & (const sc_logic *b) const; 2721904SN/A const sc_lv_base operator & (const sc_unsigned &b) const; 2731904SN/A const sc_lv_base operator & (const sc_signed &b) const; 2741904SN/A const sc_lv_base operator & (const sc_uint_base &b) const; 2751904SN/A const sc_lv_base operator & (const sc_int_base &b) const; 2761904SN/A const sc_lv_base operator & (unsigned long b) const; 2771904SN/A const sc_lv_base operator & (long b) const; 2781904SN/A const sc_lv_base operator & (unsigned int b) const; 2791904SN/A const sc_lv_base operator & (int b) const; 2801904SN/A const sc_lv_base operator & (uint64 b) const; 2814054Sbinkertn@umich.edu const sc_lv_base operator & (int64 b) const; 2821904SN/A 2831904SN/A // bitwise or 2844054Sbinkertn@umich.edu X &operator |= (const char *b); 2852525SN/A X &operator |= (const bool *b); 2861904SN/A X &operator |= (const sc_logic *b); 2872525SN/A X &operator |= (const sc_unsigned &b); 2882525SN/A X &operator |= (const sc_signed &b); 2892525SN/A X &operator |= (const sc_uint_base &b) { return operator |= ((uint64)b); } 2901904SN/A X &operator |= (const sc_int_base &b) { return operator |= ((int64)b); } 2911904SN/A X &operator |= (unsigned long b); 2921904SN/A X &operator |= (long b); 2934054Sbinkertn@umich.edu X &operator |= (unsigned int b) { return operator |= ((unsigned long)b); } 2941904SN/A X &operator |= (int b) { return operator |= ((long)b); } 2951904SN/A X &operator |= (uint64 b); 2964054Sbinkertn@umich.edu X &operator |= (int64 b); 2971904SN/A 2981967SN/A const sc_lv_base operator | (const char *b) const; 2991967SN/A const sc_lv_base operator | (const bool *b) const; 3001967SN/A const sc_lv_base operator | (const sc_logic *b) const; 3011967SN/A const sc_lv_base operator | (const sc_unsigned &b) const; 3021967SN/A const sc_lv_base operator | (const sc_signed &b) const; 3032SN/A const sc_lv_base operator | (const sc_uint_base &b) const; 3043817Ssaidi@eecs.umich.edu const sc_lv_base operator | (const sc_int_base &b) const; 3053506Ssaidi@eecs.umich.edu const sc_lv_base operator | (unsigned long b) const; 3064054Sbinkertn@umich.edu const sc_lv_base operator | (long b) const; 3073506Ssaidi@eecs.umich.edu const sc_lv_base operator | (unsigned int b) const; 3083506Ssaidi@eecs.umich.edu const sc_lv_base operator | (int b) const; 3093506Ssaidi@eecs.umich.edu const sc_lv_base operator | (uint64 b) const; 3103814Ssaidi@eecs.umich.edu const sc_lv_base operator | (int64 b) const; 3113506Ssaidi@eecs.umich.edu 3123931Ssaidi@eecs.umich.edu // bitwise xor 3133931Ssaidi@eecs.umich.edu X &operator ^= (const char *b); 3143748Sgblack@eecs.umich.edu X &operator ^= (const bool *b); 3153748Sgblack@eecs.umich.edu X &operator ^= (const sc_logic *b); 3163748Sgblack@eecs.umich.edu X &operator ^= (const sc_unsigned &b); 3173748Sgblack@eecs.umich.edu X &operator ^= (const sc_signed &b); 3183748Sgblack@eecs.umich.edu X &operator ^= (const sc_uint_base &b) { return operator ^= ((uint64)b); } 3193748Sgblack@eecs.umich.edu X &operator ^= (const sc_int_base &b) { return operator ^= ((int64)b); } 3203748Sgblack@eecs.umich.edu X &operator ^= (unsigned long b); 3213748Sgblack@eecs.umich.edu X &operator ^= (long b); 3223748Sgblack@eecs.umich.edu X &operator ^= (unsigned int b) { return operator ^= ((unsigned long)b); } 3233748Sgblack@eecs.umich.edu X &operator ^= (int b) { return operator ^= ((long)b); } 3244001Ssaidi@eecs.umich.edu X &operator ^= (uint64 b); 3253748Sgblack@eecs.umich.edu X &operator ^= (int64 b); 3263748Sgblack@eecs.umich.edu 3273748Sgblack@eecs.umich.edu const sc_lv_base operator ^ (const char *b) const; 3283748Sgblack@eecs.umich.edu const sc_lv_base operator ^ (const bool *b) const; 3293748Sgblack@eecs.umich.edu const sc_lv_base operator ^ (const sc_logic *b) const; 3303748Sgblack@eecs.umich.edu const sc_lv_base operator ^ (const sc_unsigned &b) const; 3313748Sgblack@eecs.umich.edu const sc_lv_base operator ^ (const sc_signed &b) const; 3323748Sgblack@eecs.umich.edu const sc_lv_base operator ^ (const sc_uint_base &b) const; 3333748Sgblack@eecs.umich.edu const sc_lv_base operator ^ (const sc_int_base &b) const; 3343748Sgblack@eecs.umich.edu const sc_lv_base operator ^ (unsigned long b) const; 3353880Ssaidi@eecs.umich.edu const sc_lv_base operator ^ (long b) const; 3363603Ssaidi@eecs.umich.edu const sc_lv_base operator ^ (unsigned int b) const; 3373603Ssaidi@eecs.umich.edu const sc_lv_base operator ^ (int b) const; 3384054Sbinkertn@umich.edu const sc_lv_base operator ^ (uint64 b) const; 3394054Sbinkertn@umich.edu const sc_lv_base operator ^ (int64 b) const; 3404054Sbinkertn@umich.edu 3413903Ssaidi@eecs.umich.edu // bitwise left shift 3423903Ssaidi@eecs.umich.edu X &operator <<= (int n); 3433903Ssaidi@eecs.umich.edu const sc_lv_base operator << (int n) const; 3444046Sbinkertn@umich.edu 3453903Ssaidi@eecs.umich.edu // bitwise right shift 3463903Ssaidi@eecs.umich.edu X &operator >>= (int n); 3473903Ssaidi@eecs.umich.edu const sc_lv_base operator >> (int n) const; 3483903Ssaidi@eecs.umich.edu 3493903Ssaidi@eecs.umich.edu // bitwise left rotate 3503903Ssaidi@eecs.umich.edu X &lrotate(int n); 3513903Ssaidi@eecs.umich.edu 3523903Ssaidi@eecs.umich.edu // bitwise right rotate 3533903Ssaidi@eecs.umich.edu X &rrotate(int n); 3543903Ssaidi@eecs.umich.edu 3553903Ssaidi@eecs.umich.edu // bitwise reverse 3563903Ssaidi@eecs.umich.edu X &reverse(); 3573903Ssaidi@eecs.umich.edu 3583903Ssaidi@eecs.umich.edu // bit selection 3593506Ssaidi@eecs.umich.edu sc_bitref<X> operator [] (int i) { return sc_bitref<X>(back_cast(), i); } 3603584Ssaidi@eecs.umich.edu sc_bitref_r<X> 3613584Ssaidi@eecs.umich.edu operator [] (int i) const 3623584Ssaidi@eecs.umich.edu { 3633748Sgblack@eecs.umich.edu return sc_bitref_r<X>(back_cast(), i); 3643928Ssaidi@eecs.umich.edu } 3653928Ssaidi@eecs.umich.edu sc_bitref<X> bit(int i) { return sc_bitref<X>(back_cast(), i); } 3663928Ssaidi@eecs.umich.edu sc_bitref_r<X> bit(int i) const { return sc_bitref_r<X>(back_cast(), i); } 3673748Sgblack@eecs.umich.edu 3683603Ssaidi@eecs.umich.edu // part selection 3693584Ssaidi@eecs.umich.edu sc_subref<X> 3703814Ssaidi@eecs.umich.edu operator () (int hi, int lo) 3713814Ssaidi@eecs.umich.edu { 3723814Ssaidi@eecs.umich.edu return sc_subref<X>(back_cast(), hi, lo); 3733814Ssaidi@eecs.umich.edu } 3743814Ssaidi@eecs.umich.edu sc_subref_r<X> 3753743Sgblack@eecs.umich.edu operator () (int hi, int lo) const 3763743Sgblack@eecs.umich.edu { 3773584Ssaidi@eecs.umich.edu return sc_subref_r<X>(back_cast(), hi, lo); 3783743Sgblack@eecs.umich.edu } 3793989Ssaidi@eecs.umich.edu sc_subref<X> 3803989Ssaidi@eecs.umich.edu range(int hi, int lo) 3813603Ssaidi@eecs.umich.edu { 3823931Ssaidi@eecs.umich.edu return sc_subref<X>(back_cast(), hi, lo); 3833603Ssaidi@eecs.umich.edu } 3843584Ssaidi@eecs.umich.edu sc_subref_r<X> 3853931Ssaidi@eecs.umich.edu range(int hi, int lo) const 3863945Ssaidi@eecs.umich.edu { 3873931Ssaidi@eecs.umich.edu return sc_subref_r<X>(back_cast(), hi, lo); 3883931Ssaidi@eecs.umich.edu } 3893931Ssaidi@eecs.umich.edu 3903931Ssaidi@eecs.umich.edu // reduce functions 3913748Sgblack@eecs.umich.edu value_type and_reduce() const; 3923748Sgblack@eecs.umich.edu value_type 3933748Sgblack@eecs.umich.edu nand_reduce() const 3943748Sgblack@eecs.umich.edu { 3953748Sgblack@eecs.umich.edu return sc_logic::not_table[and_reduce()]; 3963815Ssaidi@eecs.umich.edu } 3973748Sgblack@eecs.umich.edu value_type or_reduce() const; 3983748Sgblack@eecs.umich.edu value_type nor_reduce() const { return sc_logic::not_table[or_reduce()]; } 3993815Ssaidi@eecs.umich.edu value_type xor_reduce() const; 4003748Sgblack@eecs.umich.edu value_type 4013748Sgblack@eecs.umich.edu xnor_reduce() const 4023815Ssaidi@eecs.umich.edu { 4033748Sgblack@eecs.umich.edu return sc_logic::not_table[xor_reduce()]; 4043748Sgblack@eecs.umich.edu } 4053815Ssaidi@eecs.umich.edu 4063748Sgblack@eecs.umich.edu // relational operators 4073748Sgblack@eecs.umich.edu bool operator == (const char *b) const; 4083815Ssaidi@eecs.umich.edu bool operator == (const bool *b) const; 4093748Sgblack@eecs.umich.edu bool operator == (const sc_logic *b) const; 4103748Sgblack@eecs.umich.edu bool operator == (const sc_unsigned &b) const; 4113748Sgblack@eecs.umich.edu bool operator == (const sc_signed &b) const; 4123584Ssaidi@eecs.umich.edu bool operator == (const sc_uint_base &b) const; 4133748Sgblack@eecs.umich.edu bool operator == (const sc_int_base &b) const; 4143748Sgblack@eecs.umich.edu bool operator == (unsigned long b) const; 4153748Sgblack@eecs.umich.edu bool operator == (long b) const; 4163748Sgblack@eecs.umich.edu bool operator == (unsigned int b) const; 4173748Sgblack@eecs.umich.edu bool operator == (int b) const; 4183748Sgblack@eecs.umich.edu bool operator == (uint64 b) const; 4193748Sgblack@eecs.umich.edu bool operator == (int64 b) const; 4203748Sgblack@eecs.umich.edu 4213748Sgblack@eecs.umich.edu // explicit conversions to character string 4223748Sgblack@eecs.umich.edu const std::string to_string() const; 4233748Sgblack@eecs.umich.edu const std::string to_string(sc_numrep) const; 4243748Sgblack@eecs.umich.edu const std::string to_string(sc_numrep, bool) const; 4253748Sgblack@eecs.umich.edu 4263748Sgblack@eecs.umich.edu // explicit conversions 4273790Sgblack@eecs.umich.edu inline int64 to_int64() const { return to_anything_signed(); } 4283790Sgblack@eecs.umich.edu inline uint64 to_uint64() const; 4293790Sgblack@eecs.umich.edu int to_int() const { return (int)to_anything_signed(); } 4303748Sgblack@eecs.umich.edu 4314011Ssaidi@eecs.umich.edu unsigned int 4324001Ssaidi@eecs.umich.edu to_uint() const 4334011Ssaidi@eecs.umich.edu { 4344011Ssaidi@eecs.umich.edu return (unsigned int)to_anything_unsigned(); 4354011Ssaidi@eecs.umich.edu } 4364011Ssaidi@eecs.umich.edu 4374011Ssaidi@eecs.umich.edu long to_long() const { return (long)to_anything_signed(); } 4384011Ssaidi@eecs.umich.edu 4393790Sgblack@eecs.umich.edu unsigned long 4403790Sgblack@eecs.umich.edu to_ulong() const 4413790Sgblack@eecs.umich.edu { 4423748Sgblack@eecs.umich.edu return (unsigned long)to_anything_unsigned(); 4433748Sgblack@eecs.umich.edu } 4443748Sgblack@eecs.umich.edu 4453748Sgblack@eecs.umich.edu // other methods 4463748Sgblack@eecs.umich.edu void 4473748Sgblack@eecs.umich.edu print(::std::ostream &os=::std::cout) const 4483748Sgblack@eecs.umich.edu { 4493748Sgblack@eecs.umich.edu // The test below will force printing in binary if decimal is 4503748Sgblack@eecs.umich.edu // specified. 4513790Sgblack@eecs.umich.edu if (sc_io_base(os, SC_DEC) == SC_DEC) 4523790Sgblack@eecs.umich.edu os << to_string(); 4533790Sgblack@eecs.umich.edu else 4543748Sgblack@eecs.umich.edu os << to_string(sc_io_base(os, SC_BIN), sc_io_show_base(os)); 4553790Sgblack@eecs.umich.edu } 4563790Sgblack@eecs.umich.edu 4573748Sgblack@eecs.umich.edu void scan(::std::istream &is=::std::cin); 4583989Ssaidi@eecs.umich.edu 4593748Sgblack@eecs.umich.edu protected: 4603790Sgblack@eecs.umich.edu void check_bounds(int n) const; // check if bit n accessible 4613790Sgblack@eecs.umich.edu void check_wbounds(int n) const; // check if word n accessible 4623989Ssaidi@eecs.umich.edu 4633748Sgblack@eecs.umich.edu sc_digit to_anything_unsigned() const; 4643790Sgblack@eecs.umich.edu int64 to_anything_signed() const; 4653790Sgblack@eecs.umich.edu}; 4663989Ssaidi@eecs.umich.edu 4673748Sgblack@eecs.umich.edu 4683748Sgblack@eecs.umich.edu// ---------------------------------------------------------------------------- 4693880Ssaidi@eecs.umich.edu 4703880Ssaidi@eecs.umich.edu// bitwise operators and functions 4713880Ssaidi@eecs.umich.edu 4723880Ssaidi@eecs.umich.edu// bitwise and 4733880Ssaidi@eecs.umich.edu 4743880Ssaidi@eecs.umich.edutemplate <class X, class Y> 4753880Ssaidi@eecs.umich.eduinline X &operator &= (sc_proxy<X> &px, const sc_proxy<Y> &py); 4764008Ssaidi@eecs.umich.edu 4773931Ssaidi@eecs.umich.edu 4783931Ssaidi@eecs.umich.edutemplate <class X, class Y> 4794001Ssaidi@eecs.umich.eduinline const sc_lv_base operator & ( 4804001Ssaidi@eecs.umich.edu const sc_proxy<X> &px, const sc_proxy<Y> &py); 4813931Ssaidi@eecs.umich.edu 4824008Ssaidi@eecs.umich.edu 4833863Ssaidi@eecs.umich.edu#define DECL_BITWISE_AND_OP_T(tp) \ 4843584Ssaidi@eecs.umich.edutemplate <class X> \ 4853584Ssaidi@eecs.umich.eduinline const sc_lv_base operator & (tp b, const sc_proxy<X> &px); 4863584Ssaidi@eecs.umich.edu 4873814Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const char *) 4883814Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const bool *) 4893584Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const sc_logic *) 4903584Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const sc_unsigned &) 4913931Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const sc_signed &) 4923584Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const sc_uint_base &) 4933931Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const sc_int_base &) 4943931Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(unsigned long) 4953748Sgblack@eecs.umich.eduDECL_BITWISE_AND_OP_T(long) 4963748Sgblack@eecs.umich.eduDECL_BITWISE_AND_OP_T(unsigned int) 4973748Sgblack@eecs.umich.eduDECL_BITWISE_AND_OP_T(int) 4983748Sgblack@eecs.umich.eduDECL_BITWISE_AND_OP_T(uint64) 4993748Sgblack@eecs.umich.eduDECL_BITWISE_AND_OP_T(int64) 5003748Sgblack@eecs.umich.edu 5013748Sgblack@eecs.umich.edu#undef DECL_BITWISE_AND_OP_T 5023748Sgblack@eecs.umich.edu 5033748Sgblack@eecs.umich.edu// bitwise or 5043748Sgblack@eecs.umich.edutemplate <class X, class Y> 5053748Sgblack@eecs.umich.eduinline X &operator |= (sc_proxy<X> &px, const sc_proxy<Y> &py); 5063748Sgblack@eecs.umich.edu 5073748Sgblack@eecs.umich.edutemplate <class X, class Y> 5083748Sgblack@eecs.umich.eduinline const sc_lv_base operator | ( 5093748Sgblack@eecs.umich.edu const sc_proxy<X> &px, const sc_proxy<Y> &py); 5103748Sgblack@eecs.umich.edu 5113748Sgblack@eecs.umich.edu 5123748Sgblack@eecs.umich.edu#define DECL_BITWISE_OR_OP_T(tp) \ 5134001Ssaidi@eecs.umich.edutemplate <class X> \ 5144001Ssaidi@eecs.umich.eduinline const sc_lv_base operator | (tp a, const sc_proxy<X> &px); 5153748Sgblack@eecs.umich.edu 5163748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const char *) 5173748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const bool *) 5183748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const sc_logic *) 5193748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const sc_unsigned &) 5203748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const sc_signed &) 5213748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const sc_uint_base &) 5223748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const sc_int_base &) 5233748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(unsigned long) 5243748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(long) 5253748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(unsigned int) 5263748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(int) 5273748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(uint64) 5283748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(int64) 5293748Sgblack@eecs.umich.edu 5303748Sgblack@eecs.umich.edu#undef DECL_BITWISE_OR_OP_T 5313748Sgblack@eecs.umich.edu 5323748Sgblack@eecs.umich.edu// bitwise xor 5333748Sgblack@eecs.umich.edutemplate <class X, class Y> 5343748Sgblack@eecs.umich.eduinline X &operator ^= (sc_proxy<X> &px, const sc_proxy<Y> &py); 5353880Ssaidi@eecs.umich.edu 5363880Ssaidi@eecs.umich.edutemplate <class X, class Y> 5373603Ssaidi@eecs.umich.eduinline const sc_lv_base operator ^ ( 5383584Ssaidi@eecs.umich.edu const sc_proxy<X> &px, const sc_proxy<Y> &py); 5393603Ssaidi@eecs.umich.edu 5403584Ssaidi@eecs.umich.edu#define DECL_BITWISE_XOR_OP_T(tp) \ 5413603Ssaidi@eecs.umich.edutemplate <class X> \ 5423584Ssaidi@eecs.umich.eduinline const sc_lv_base operator ^ (tp a, const sc_proxy<X> &px); 5433584Ssaidi@eecs.umich.edu 5443603Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const char *) 5453584Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const bool *) 5463814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const sc_logic *) 5473814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const sc_unsigned &) 5483814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const sc_signed &) 5493814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const sc_uint_base &) 5503814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const sc_int_base &) 5513814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(unsigned long) 5523814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(long) 5533584Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(unsigned int) 5543584Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(int) 5553584Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(uint64) 5563603Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(int64) 5573584Ssaidi@eecs.umich.edu 5583584Ssaidi@eecs.umich.edu#undef DECL_BITWISE_XOR_OP_T 5593748Sgblack@eecs.umich.edu 5603748Sgblack@eecs.umich.edu// relational operators 5613748Sgblack@eecs.umich.edutemplate <class X, class Y> 5623584Ssaidi@eecs.umich.eduinline bool operator == (const sc_proxy<X> &px, const sc_proxy<Y> &py); 5633584Ssaidi@eecs.umich.edu 5643584Ssaidi@eecs.umich.edutemplate <class X, class Y> 5653584Ssaidi@eecs.umich.eduinline bool operator != (const sc_proxy<X> &px, const sc_proxy<Y> &py); 5663603Ssaidi@eecs.umich.edu 5673748Sgblack@eecs.umich.edu#define DECL_REL_OP_T(tp) \ 5683584Ssaidi@eecs.umich.edutemplate <class X> \ 5693748Sgblack@eecs.umich.eduinline bool operator == (tp b, const sc_proxy<X> &px); \ 5703748Sgblack@eecs.umich.edu \ 5713748Sgblack@eecs.umich.edutemplate <class X> \ 5723748Sgblack@eecs.umich.eduinline bool operator != (const sc_proxy<X> &px, tp b); \ 5733748Sgblack@eecs.umich.edu \ 5743748Sgblack@eecs.umich.edutemplate <class X> \ 5753748Sgblack@eecs.umich.eduinline bool operator != (tp b, const sc_proxy<X> &px); 5763748Sgblack@eecs.umich.edu 5773748Sgblack@eecs.umich.eduDECL_REL_OP_T(const char *) 5783748Sgblack@eecs.umich.eduDECL_REL_OP_T(const bool *) 5793748Sgblack@eecs.umich.eduDECL_REL_OP_T(const sc_logic *) 5803748Sgblack@eecs.umich.eduDECL_REL_OP_T(const sc_unsigned &) 5813790Sgblack@eecs.umich.eduDECL_REL_OP_T(const sc_signed &) 5823989Ssaidi@eecs.umich.eduDECL_REL_OP_T(const sc_uint_base &) 5833748Sgblack@eecs.umich.eduDECL_REL_OP_T(const sc_int_base &) 5844001Ssaidi@eecs.umich.eduDECL_REL_OP_T(unsigned long) 5854001Ssaidi@eecs.umich.eduDECL_REL_OP_T(long) 5864001Ssaidi@eecs.umich.eduDECL_REL_OP_T(unsigned int) 5873748Sgblack@eecs.umich.eduDECL_REL_OP_T(int) 5883790Sgblack@eecs.umich.eduDECL_REL_OP_T(uint64) 5893989Ssaidi@eecs.umich.eduDECL_REL_OP_T(int64) 5903748Sgblack@eecs.umich.edu 5913748Sgblack@eecs.umich.edu#undef DECL_REL_OP_T 5923748Sgblack@eecs.umich.edu 5933748Sgblack@eecs.umich.edu// l-value concatenation 5943748Sgblack@eecs.umich.edu 5953748Sgblack@eecs.umich.edu// Due to the fact that temporary objects cannot be passed to non-const 5963748Sgblack@eecs.umich.edu// references, we have to enumerate, use call by value, and use dynamic 5973748Sgblack@eecs.umich.edu// memory allocation (and deallocation). 5983748Sgblack@eecs.umich.edu 5993748Sgblack@eecs.umich.edu 6003748Sgblack@eecs.umich.edu// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 6013748Sgblack@eecs.umich.edu 6023748Sgblack@eecs.umich.edutemplate <class X> 6033748Sgblack@eecs.umich.eduinline void 6043748Sgblack@eecs.umich.eduget_words_(const X &x, int wi, sc_digit &x_dw, sc_digit &x_cw) 6053748Sgblack@eecs.umich.edu{ 6063748Sgblack@eecs.umich.edu x_dw = x.get_word(wi); 6073790Sgblack@eecs.umich.edu x_cw = x.get_cword(wi); 6083790Sgblack@eecs.umich.edu} 6093748Sgblack@eecs.umich.edu 6103748Sgblack@eecs.umich.edutemplate <class X> 6113790Sgblack@eecs.umich.eduinline void 6123790Sgblack@eecs.umich.eduset_words_(X &x, int wi, sc_digit x_dw, sc_digit x_cw) 6133748Sgblack@eecs.umich.edu{ 6143748Sgblack@eecs.umich.edu x.set_word(wi, x_dw); 6153790Sgblack@eecs.umich.edu x.set_cword(wi, x_cw); 6163989Ssaidi@eecs.umich.edu} 6173748Sgblack@eecs.umich.edu 6183748Sgblack@eecs.umich.edutemplate <class X> 6193790Sgblack@eecs.umich.eduinline void 6203989Ssaidi@eecs.umich.eduextend_sign_w_(X &x, int wi, bool sign) 6213748Sgblack@eecs.umich.edu{ 6223748Sgblack@eecs.umich.edu int sz = x.size(); 6233748Sgblack@eecs.umich.edu unsigned int sgn = (sign ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO); 6243748Sgblack@eecs.umich.edu for (int i = wi; i < sz; ++i) { 6253748Sgblack@eecs.umich.edu set_words_(x, i, sgn, SC_DIGIT_ZERO); 6263748Sgblack@eecs.umich.edu } 6273748Sgblack@eecs.umich.edu} 6283748Sgblack@eecs.umich.edu 6293815Ssaidi@eecs.umich.edu// assignment functions 6303748Sgblack@eecs.umich.edutemplate <class X, class Y> 6313748Sgblack@eecs.umich.eduinline void 6323815Ssaidi@eecs.umich.eduassign_p_(sc_proxy<X> &px, const sc_proxy<Y> &py) 6333748Sgblack@eecs.umich.edu{ 6343748Sgblack@eecs.umich.edu if ((void *)&px != (void *)&py) { 6353815Ssaidi@eecs.umich.edu X &x = px.back_cast(); 6363748Sgblack@eecs.umich.edu const Y &y = py.back_cast(); 6373748Sgblack@eecs.umich.edu int sz = x.size(); 6383815Ssaidi@eecs.umich.edu int min_sz = sc_min(sz, y.size()); 6393748Sgblack@eecs.umich.edu int i = 0; 6403748Sgblack@eecs.umich.edu for (; i < min_sz; ++i) { 6413815Ssaidi@eecs.umich.edu set_words_(x, i, y.get_word(i), y.get_cword(i)); 6423748Sgblack@eecs.umich.edu } 6433748Sgblack@eecs.umich.edu // extend with zeros 6443584Ssaidi@eecs.umich.edu extend_sign_w_(x, i, false); 6453584Ssaidi@eecs.umich.edu x.clean_tail(); 6463748Sgblack@eecs.umich.edu } 6473584Ssaidi@eecs.umich.edu} 6483931Ssaidi@eecs.umich.edu 6493931Ssaidi@eecs.umich.edu// Vector types that are not derived from sc_proxy, sc_int_base, 6503748Sgblack@eecs.umich.edu// sc_uint_base, sc_signed, or sc_unsigned, must have a length() 6513748Sgblack@eecs.umich.edu// function and an operator []. The vector argument type must support 6523748Sgblack@eecs.umich.edu// accessing bits that are beyond the msb. The vector argument type 6533748Sgblack@eecs.umich.edu// decides what to do there (e.g. sign extension or zero padding). 6543748Sgblack@eecs.umich.edu 6553931Ssaidi@eecs.umich.edutemplate <class X, class T> 6563931Ssaidi@eecs.umich.eduinline void 6573931Ssaidi@eecs.umich.eduassign_v_(sc_proxy<X> &px, const T &a) 6583931Ssaidi@eecs.umich.edu{ 6593931Ssaidi@eecs.umich.edu X &x = px.back_cast(); 6603931Ssaidi@eecs.umich.edu int i; 6613931Ssaidi@eecs.umich.edu int len_x = x.length(); 6624008Ssaidi@eecs.umich.edu int len_a = a.length(); 6633931Ssaidi@eecs.umich.edu if (len_a > len_x) 6643584Ssaidi@eecs.umich.edu len_a = len_x; 6653584Ssaidi@eecs.umich.edu for (i = 0; i < len_a; ++i) { 6663903Ssaidi@eecs.umich.edu x.set_bit(i, sc_logic_value_t((bool)a[i])); 6673903Ssaidi@eecs.umich.edu } 6683903Ssaidi@eecs.umich.edu for (; i < len_x; ++i) { 6693903Ssaidi@eecs.umich.edu x.set_bit(i, sc_logic_value_t(false)); 6703903Ssaidi@eecs.umich.edu } 6713903Ssaidi@eecs.umich.edu} 6723903Ssaidi@eecs.umich.edu 6733903Ssaidi@eecs.umich.edutemplate <class X> 6743903Ssaidi@eecs.umich.eduinline void 6753903Ssaidi@eecs.umich.eduassign_v_(sc_proxy<X> &px, const sc_int_base &a) 6763880Ssaidi@eecs.umich.edu{ 6773903Ssaidi@eecs.umich.edu X &x = px.back_cast(); 6783903Ssaidi@eecs.umich.edu int i; 6793903Ssaidi@eecs.umich.edu bool sign = a < 0; 6803903Ssaidi@eecs.umich.edu int len_x = x.length(); 6813903Ssaidi@eecs.umich.edu int len_a = a.length(); 6823903Ssaidi@eecs.umich.edu if ( len_a > len_x ) len_a = len_x; 6833903Ssaidi@eecs.umich.edu for (i = 0; i < len_a; ++i) { 6843903Ssaidi@eecs.umich.edu x.set_bit(i, sc_logic_value_t((bool)a[i])); 6853903Ssaidi@eecs.umich.edu } 6863903Ssaidi@eecs.umich.edu for (; i < len_x; ++i) { 6873880Ssaidi@eecs.umich.edu x.set_bit(i, sc_logic_value_t(sign)); 6883826Ssaidi@eecs.umich.edu } 6893825Ssaidi@eecs.umich.edu} 6904011Ssaidi@eecs.umich.edu 6913825Ssaidi@eecs.umich.edutemplate <class X> 6923892Ssaidi@eecs.umich.eduinline void 6933892Ssaidi@eecs.umich.eduassign_v_(sc_proxy<X> &px, const sc_signed &a) 6943584Ssaidi@eecs.umich.edu{ 6953584Ssaidi@eecs.umich.edu X &x = px.back_cast(); 6963584Ssaidi@eecs.umich.edu int i; 6973506Ssaidi@eecs.umich.edu bool sign = a < 0; 6983584Ssaidi@eecs.umich.edu int len_x = x.length(); 6993584Ssaidi@eecs.umich.edu int len_a = a.length(); 7003506Ssaidi@eecs.umich.edu if (len_a > len_x) 7013584Ssaidi@eecs.umich.edu len_a = len_x; 7022SN/A for (i = 0; i < len_a; ++i) { 7032SN/A x.set_bit(i, sc_logic_value_t((bool)a[i])); 7044054Sbinkertn@umich.edu } 705 for (; i < len_x; ++i) { 706 x.set_bit(i, sc_logic_value_t(sign)); 707 } 708} 709 710template <class X> 711inline void 712assign_v_(sc_proxy<X> &px, const sc_uint_base &a) 713{ 714 X &x = px.back_cast(); 715 int i; 716 int len_x = x.length(); 717 int len_a = a.length(); 718 if (len_a > len_x) 719 len_a = len_x; 720 for (i = 0; i < len_a; ++i) { 721 x.set_bit(i, sc_logic_value_t((bool)a[i])); 722 } 723 for (; i < len_x; ++i) { 724 x.set_bit(i, sc_logic_value_t(false)); 725 } 726} 727 728template <class X> 729inline void 730assign_v_(sc_proxy<X> &px, const sc_unsigned &a) 731{ 732 X &x = px.back_cast(); 733 int i; 734 int len_x = x.length(); 735 int len_a = a.length(); 736 if (len_a > len_x) 737 len_a = len_x; 738 for (i = 0; i < len_a; ++i) { 739 x.set_bit(i, sc_logic_value_t((bool)a[i])); 740 } 741 for (; i < len_x; ++i) { 742 x.set_bit(i, sc_logic_value_t(false)); 743 } 744} 745 746// assignment operators 747template <class X> 748inline X & 749sc_proxy<X>::assign_(const char *a) 750{ 751 X &x = back_cast(); 752 std::string s = convert_to_bin(a); 753 int len = x.length(); 754 int s_len = s.length() - 1; 755 int min_len = sc_min(len, s_len); 756 int i = 0; 757 for (; i < min_len; ++i) { 758 char c = s[s_len - i - 1]; 759 x.set_bit(i, sc_logic::char_to_logic[(int)c]); 760 } 761 // if formatted, fill the rest with sign(s), otherwise fill with zeros 762 sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t(s[0] - '0') 763 : sc_logic_value_t(0)); 764 for (; i < len; ++i) { 765 x.set_bit(i, fill); 766 } 767 return x; 768} 769 770template <class X> 771inline X & 772sc_proxy<X>::assign_(const bool *a) 773{ 774 // the length of 'a' must be larger than or equal to the length of 'this' 775 X &x = back_cast(); 776 int len = x.length(); 777 for (int i = 0; i < len; ++i) { 778 x.set_bit(i, sc_logic_value_t(a[i])); 779 } 780 return x; 781} 782 783template <class X> 784inline X & 785sc_proxy<X>::assign_(const sc_logic *a) 786{ 787 // the length of 'a' must be larger than or equal to the length of 'this' 788 X &x = back_cast(); 789 int len = x.length(); 790 for (int i = 0; i < len; ++i) { 791 x.set_bit(i, a[i].value()); 792 } 793 return x; 794} 795 796template <class X> 797inline X & 798sc_proxy<X>::assign_(unsigned int a) 799{ 800 X &x = back_cast(); 801 set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO); 802 // extend with zeros 803 extend_sign_w_(x, 1, false); 804 x.clean_tail(); 805 return x; 806} 807 808template <class X> 809inline X & 810sc_proxy<X>::assign_(int a) 811{ 812 X &x = back_cast(); 813 set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO); 814 // extend with sign(a) 815 extend_sign_w_(x, 1, (a < 0)); 816 x.clean_tail(); 817 return x; 818} 819 820#if SC_LONG_64 821template <class X> 822inline X & 823sc_proxy<X>::assign_(unsigned long a) 824{ 825 X &x = back_cast(); 826 set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO); 827 if (x.size() > 1) { 828 set_words_(x, 1, ((sc_digit)(a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), 829 SC_DIGIT_ZERO); 830 // extend with zeros 831 extend_sign_w_(x, 2, false); 832 } 833 x.clean_tail(); 834 return x; 835} 836 837template <class X> 838inline X & 839sc_proxy<X>::assign_(long a) 840{ 841 X &x = back_cast(); 842 set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO); 843 if (x.size() > 1) { 844 set_words_(x, 1, 845 ((sc_digit)((uint64)a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), 846 SC_DIGIT_ZERO); 847 // extend with sign(a) 848 extend_sign_w_(x, 2, (a < 0)); 849 } 850 x.clean_tail(); 851 return x; 852} 853 854#else 855 856template <class X> 857inline X & 858sc_proxy<X>::assign_(unsigned long a) 859{ 860 X &x = back_cast(); 861 set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO); 862 // extend with zeros 863 extend_sign_w_(x, 1, false); 864 x.clean_tail(); 865 return x; 866} 867 868template <class X> 869inline X & 870sc_proxy<X>::assign_(long a) 871{ 872 X &x = back_cast(); 873 set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO); 874 // extend with sign(a) 875 extend_sign_w_(x, 1, (a < 0)); 876 x.clean_tail(); 877 return x; 878} 879 880#endif 881 882template <class X> 883inline X & 884sc_proxy<X>::assign_(uint64 a) 885{ 886 X &x = back_cast(); 887 set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO); 888 if (x.size() > 1) { 889 set_words_(x, 1, ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), 890 SC_DIGIT_ZERO ); 891 // extend with zeros 892 extend_sign_w_(x, 2, false); 893 } 894 x.clean_tail(); 895 return x; 896} 897 898template <class X> 899inline X & 900sc_proxy<X>::assign_(int64 a) 901{ 902 X &x = back_cast(); 903 set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO); 904 if (x.size() > 1) { 905 set_words_(x, 1, 906 ((sc_digit)((uint64)a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), 907 SC_DIGIT_ZERO ); 908 // extend with sign(a) 909 extend_sign_w_(x, 2, (a < 0)); 910 } 911 x.clean_tail(); 912 return x; 913} 914 915// bitwise operators and functions 916 917// bitwise complement 918template <class X> 919inline X & 920sc_proxy<X>::b_not() 921{ 922 X &x = back_cast(); 923 int sz = x.size(); 924 for (int i = 0; i < sz; ++i) { 925 sc_digit x_dw, x_cw; 926 get_words_(x, i, x_dw, x_cw); 927 x.set_word(i, x_cw | ~x_dw); 928 } 929 x.clean_tail(); 930 return x; 931} 932 933// bitwise and 934template <class X, class Y> 935inline X & 936b_and_assign_(sc_proxy<X> &px, const sc_proxy<Y> &py) 937{ 938 X &x = px.back_cast(); 939 const Y &y = py.back_cast(); 940 sc_assert(x.length() == y.length()); 941 int sz = x.size(); 942 for (int i = 0; i < sz; ++i) { 943 sc_digit x_dw, x_cw, y_dw, y_cw; 944 get_words_(x, i, x_dw, x_cw); 945 get_words_(y, i, y_dw, y_cw); 946 sc_digit cw = (x_dw & y_cw) | (x_cw & y_dw) | (x_cw & y_cw); 947 sc_digit dw = cw | (x_dw & y_dw); 948 set_words_(x, i, dw, cw); 949 } 950 // tail cleaning not needed 951 return x; 952} 953 954// bitwise or 955template <class X, class Y> 956inline X & 957b_or_assign_(sc_proxy<X> &px, const sc_proxy<Y> &py) 958{ 959 X &x = px.back_cast(); 960 const Y &y = py.back_cast(); 961 sc_assert(x.length() == y.length()); 962 int sz = x.size(); 963 for (int i = 0; i < sz; ++i) { 964 sc_digit x_dw, x_cw, y_dw, y_cw; 965 get_words_(x, i, x_dw, x_cw); 966 get_words_(y, i, y_dw, y_cw); 967 sc_digit cw = (x_cw & y_cw) | (x_cw & ~y_dw) | (~x_dw & y_cw); 968 sc_digit dw = cw | x_dw | y_dw; 969 set_words_(x, i, dw, cw); 970 } 971 // tail cleaning not needed 972 return x; 973} 974 975// bitwise xor 976template <class X, class Y> 977inline X & 978b_xor_assign_(sc_proxy<X> &a, const sc_proxy<Y> &b) 979{ 980 X &x = a.back_cast(); 981 const Y &y = b.back_cast(); 982 sc_assert(x.length() == y.length()); 983 int sz = x.size(); 984 for (int i = 0; i < sz; ++i) { 985 sc_digit x_dw, x_cw, y_dw, y_cw; 986 get_words_(x, i, x_dw, x_cw); 987 get_words_(y, i, y_dw, y_cw); 988 sc_digit cw = x_cw | y_cw; 989 sc_digit dw = cw | (x_dw ^ y_dw); 990 set_words_( x, i, dw, cw ); 991 } 992 // tail cleaning not needed 993 return x; 994} 995 996// bitwise left shift 997template <class X> 998inline X & 999sc_proxy<X>::operator <<= (int n) 1000{ 1001 X &x = back_cast(); 1002 if (n < 0) { 1003 sc_proxy_out_of_bounds("left shift operation is only allowed with " 1004 "positive shift values, shift value = ", n); 1005 return x; 1006 } 1007 if (n >= x.length()) { 1008 extend_sign_w_(x, 0, false); 1009 // no tail cleaning needed 1010 return x; 1011 } 1012 int sz = x.size(); 1013 int wn = n / SC_DIGIT_SIZE; 1014 int bn = n % SC_DIGIT_SIZE; 1015 if (wn != 0) { 1016 // shift words 1017 int i = sz - 1; 1018 for (; i >= wn; --i) { 1019 set_words_(x, i, x.get_word(i - wn), x.get_cword(i - wn)); 1020 } 1021 for (; i >= 0; --i) { 1022 set_words_(x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO); 1023 } 1024 } 1025 if (bn != 0) { 1026 // shift bits 1027 for (int i = sz - 1; i >= 1; --i) { 1028 sc_digit x_dw, x_cw; 1029 get_words_(x, i, x_dw, x_cw); 1030 x_dw <<= bn; 1031 x_dw |= x.get_word(i - 1) >> (SC_DIGIT_SIZE - bn); 1032 x_cw <<= bn; 1033 x_cw |= x.get_cword(i - 1) >> (SC_DIGIT_SIZE - bn); 1034 set_words_(x, i, x_dw, x_cw); 1035 } 1036 sc_digit x_dw, x_cw; 1037 get_words_(x, 0, x_dw, x_cw); 1038 x_dw <<= bn; 1039 x_cw <<= bn; 1040 set_words_(x, 0, x_dw, x_cw); 1041 } 1042 x.clean_tail(); 1043 return x; 1044} 1045 1046// bitwise right shift 1047template <class X> 1048inline X & 1049sc_proxy<X>::operator >>= (int n) 1050{ 1051 X &x = back_cast(); 1052 if (n < 0) { 1053 sc_proxy_out_of_bounds("right shift operation is only allowed with " 1054 "positive shift values, shift value = ", n); 1055 return x; 1056 } 1057 if (n >= x.length()) { 1058 extend_sign_w_(x, 0, false); 1059 // no tail cleaning needed 1060 return x; 1061 } 1062 int sz = x.size(); 1063 int wn = n / SC_DIGIT_SIZE; 1064 int bn = n % SC_DIGIT_SIZE; 1065 if (wn != 0) { 1066 // shift words 1067 int i = 0; 1068 for (; i < (sz - wn); ++i) { 1069 set_words_(x, i, x.get_word(i + wn), x.get_cword(i + wn)); 1070 } 1071 for (; i < sz; ++i) { 1072 set_words_(x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO); 1073 } 1074 } 1075 if (bn != 0) { 1076 // shift bits 1077 for (int i = 0; i < (sz - 1); ++i) { 1078 sc_digit x_dw, x_cw; 1079 get_words_(x, i, x_dw, x_cw); 1080 x_dw >>= bn; 1081 x_dw |= x.get_word(i + 1) << (SC_DIGIT_SIZE - bn); 1082 x_cw >>= bn; 1083 x_cw |= x.get_cword(i + 1) << (SC_DIGIT_SIZE - bn); 1084 set_words_(x, i, x_dw, x_cw); 1085 } 1086 sc_digit x_dw, x_cw; 1087 get_words_(x, sz - 1, x_dw, x_cw); 1088 x_dw >>= bn; 1089 x_cw >>= bn; 1090 set_words_(x, sz - 1, x_dw, x_cw); 1091 } 1092 x.clean_tail(); 1093 return x; 1094} 1095 1096// bitwise left rotate 1097template <class X> 1098inline const sc_lv_base lrotate(const sc_proxy<X> &x, int n); 1099 1100// bitwise right rotate 1101template <class X> 1102inline const sc_lv_base rrotate(const sc_proxy<X>& x, int n); 1103 1104// bitwise reverse 1105template <class X> 1106inline X & 1107sc_proxy<X>::reverse() 1108{ 1109 X &x = back_cast(); 1110 int len = x.length(); 1111 int half_len = len / 2; 1112 for (int i = 0, j = len - 1; i < half_len; ++ i, --j) { 1113 value_type t = x.get_bit(i); 1114 x.set_bit(i, x.get_bit(j)); 1115 x.set_bit(j, t); 1116 } 1117 return x; 1118} 1119 1120template <class X> 1121inline const sc_lv_base reverse(const sc_proxy<X> &a); 1122 1123// reduce functions 1124template <class X> 1125inline typename sc_proxy<X>::value_type 1126sc_proxy<X>::and_reduce() const 1127{ 1128 const X &x = back_cast(); 1129 value_type result = value_type(1); 1130 int len = x.length(); 1131 for (int i = 0; i < len; ++i) { 1132 result = sc_logic::and_table[result][x.get_bit(i)]; 1133 } 1134 return result; 1135} 1136 1137template <class X> 1138inline typename sc_proxy<X>::value_type 1139sc_proxy<X>::or_reduce() const 1140{ 1141 const X &x = back_cast(); 1142 value_type result = value_type(0); 1143 int len = x.length(); 1144 for (int i = 0; i < len; ++i) { 1145 result = sc_logic::or_table[result][x.get_bit(i)]; 1146 } 1147 return result; 1148} 1149 1150template <class X> 1151inline typename sc_proxy<X>::value_type 1152sc_proxy<X>::xor_reduce() const 1153{ 1154 const X &x = back_cast(); 1155 value_type result = value_type(0); 1156 int len = x.length(); 1157 for (int i = 0; i < len; ++i) { 1158 result = sc_logic::xor_table[result][x.get_bit(i)]; 1159 } 1160 return result; 1161} 1162 1163// relational operators 1164template <class X, class Y> 1165inline bool 1166operator != (const sc_proxy<X> &px, const sc_proxy<Y> &py) 1167{ 1168 return !(px == py); 1169} 1170 1171 1172#define DEFN_REL_OP_T(tp) \ 1173template <class X> \ 1174inline bool operator == (tp b, const sc_proxy<X> &px) { return (px == b); } \ 1175 \ 1176template <class X> \ 1177inline bool operator != (const sc_proxy<X> &px, tp b) { return !(px == b); } \ 1178 \ 1179template <class X> \ 1180inline bool operator != (tp b, const sc_proxy<X> &px) { return !(px == b); } 1181 1182DEFN_REL_OP_T(const char *) 1183DEFN_REL_OP_T(const bool *) 1184DEFN_REL_OP_T(const sc_logic *) 1185DEFN_REL_OP_T(const sc_unsigned &) 1186DEFN_REL_OP_T(const sc_signed &) 1187DEFN_REL_OP_T(const sc_uint_base &) 1188DEFN_REL_OP_T(const sc_int_base &) 1189DEFN_REL_OP_T(unsigned long) 1190DEFN_REL_OP_T(long) 1191DEFN_REL_OP_T(unsigned int) 1192DEFN_REL_OP_T(int) 1193DEFN_REL_OP_T(uint64) 1194DEFN_REL_OP_T(int64) 1195 1196#undef DEFN_REL_OP_T 1197 1198// explicit conversions to character string 1199template <class X> 1200inline const std::string 1201sc_proxy<X>::to_string() const 1202{ 1203 const X &x = back_cast(); 1204 int len = x.length(); 1205 std::string s; // (len + 1); 1206 for (int i = 0; i < len; ++i) { 1207 s += sc_logic::logic_to_char[x.get_bit(len - i - 1)]; 1208 } 1209 return s; 1210} 1211 1212template <class X> 1213inline const std::string 1214sc_proxy<X>::to_string(sc_numrep numrep) const 1215{ 1216 return convert_to_fmt(to_string(), numrep, true); 1217} 1218 1219template <class X> 1220inline const std::string 1221sc_proxy<X>::to_string(sc_numrep numrep, bool w_prefix) const 1222{ 1223 return convert_to_fmt(to_string(), numrep, w_prefix); 1224} 1225 1226// other methods 1227template <class X> 1228inline void 1229sc_proxy<X>::scan(::std::istream &is) 1230{ 1231 std::string s; 1232 is >> s; 1233 back_cast() = s.c_str(); 1234} 1235 1236template <class X> 1237inline void 1238sc_proxy<X>::check_bounds(int n) const // check if bit n accessible 1239{ 1240 if (n < 0 || n >= back_cast().length()) { 1241 sc_proxy_out_of_bounds(NULL, n); 1242 sc_core::sc_abort(); // can't recover from here 1243 } 1244} 1245 1246template <class X> 1247inline void 1248sc_proxy<X>::check_wbounds(int n) const // check if word n accessible 1249{ 1250 if (n < 0 || n >= back_cast().size()) { 1251 sc_proxy_out_of_bounds(NULL, n); 1252 sc_core::sc_abort(); // can't recover from here 1253 } 1254} 1255 1256template <class X> 1257inline sc_digit 1258sc_proxy<X>::to_anything_unsigned() const 1259{ 1260 // only 0 word is returned 1261 // can't convert logic values other than 0 and 1 1262 const X &x = back_cast(); 1263 int len = x.length(); 1264 if (x.get_cword(0) != SC_DIGIT_ZERO) { 1265 SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0); 1266 } 1267 sc_digit w = x.get_word(0); 1268 if (len >= SC_DIGIT_SIZE) { 1269 return w; 1270 } 1271 return (w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len))); 1272} 1273 1274template <class X> 1275inline uint64 1276sc_proxy<X>::to_uint64() const 1277{ 1278 // words 1 and 0 returned. 1279 // can't convert logic values other than 0 and 1 1280 const X &x = back_cast(); 1281 int len = x.length(); 1282 if (x.get_cword(0) != SC_DIGIT_ZERO) { 1283 SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0); 1284 } 1285 uint64 w = x.get_word(0); 1286 if (len > SC_DIGIT_SIZE) { 1287 if (x.get_cword(1) != SC_DIGIT_ZERO) { 1288 SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0); 1289 } 1290 uint64 w1 = x.get_word(1); 1291 w = w | (w1 << SC_DIGIT_SIZE); 1292 return w; 1293 } else if (len == SC_DIGIT_SIZE) { 1294 return w; 1295 } else { 1296 return (w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len))); 1297 } 1298} 1299 1300template <class X> 1301inline int64 1302sc_proxy<X>::to_anything_signed() const 1303{ 1304 const X &x = back_cast(); 1305 int len = x.length(); 1306 int64 w = 0; 1307 1308 if (len > SC_DIGIT_SIZE) { 1309 if (x.get_cword(1) != SC_DIGIT_ZERO) 1310 SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0); 1311 w = x.get_word(1); 1312 } 1313 if (x.get_cword(0) != SC_DIGIT_ZERO) 1314 SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0); 1315 w = (w << SC_DIGIT_SIZE) | x.get_word(0); 1316 if (len >= 64) { 1317 return w; 1318 } 1319 1320 uint64 zero = 0; 1321 value_type sgn = x.get_bit(len - 1); 1322 if (sgn == 0) { 1323 return (int64)(w & (~zero >> (64 - len))); 1324 } else { 1325 return (int64)(w | (~zero << len)); 1326 } 1327} 1328 1329 1330// ---------------------------------------------------------------------------- 1331 1332// functional notation for the reduce methods 1333template <class X> 1334inline typename sc_proxy<X>::value_type 1335and_reduce(const sc_proxy<X> &a) 1336{ 1337 return a.and_reduce(); 1338} 1339 1340template <class X> 1341inline typename sc_proxy<X>::value_type 1342nand_reduce(const sc_proxy<X> &a) 1343{ 1344 return a.nand_reduce(); 1345} 1346 1347template <class X> 1348inline typename sc_proxy<X>::value_type 1349or_reduce(const sc_proxy<X> &a) 1350{ 1351 return a.or_reduce(); 1352} 1353 1354template <class X> 1355inline typename sc_proxy<X>::value_type 1356nor_reduce(const sc_proxy<X> &a) 1357{ 1358 return a.nor_reduce(); 1359} 1360 1361template <class X> 1362inline typename sc_proxy<X>::value_type 1363xor_reduce(const sc_proxy<X> &a) 1364{ 1365 return a.xor_reduce(); 1366} 1367 1368template <class X> 1369inline typename sc_proxy<X>::value_type 1370xnor_reduce(const sc_proxy<X> &a) 1371{ 1372 return a.xnor_reduce(); 1373} 1374 1375// ---------------------------------------------------------------------------- 1376 1377template <class X> 1378inline ::std::ostream & 1379operator << (::std::ostream &os, const sc_proxy<X> &a) 1380{ 1381 a.print(os); 1382 return os; 1383} 1384 1385template <class X> 1386inline ::std::istream & 1387operator >> (::std::istream &is, sc_proxy<X> &a) 1388{ 1389 a.scan(is); 1390 return is; 1391} 1392 1393} // namespace sc_dt 1394 1395#endif // __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__ 1396