sc_lv_base.cc revision 12854:c95c35407325
1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_lv_base.cpp -- Arbitrary size logic vector class.
23
24  Original Author: Gene Bushuyev, Synopsys, Inc.
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date:
34  Description of Modification:
35
36 *****************************************************************************/
37
38
39// $Log: sc_lv_base.cpp,v $
40// Revision 1.2  2011/08/24 22:05:40  acg
41//  Torsten Maehne: initialization changes to remove warnings.
42//
43// Revision 1.1.1.1  2006/12/15 20:20:04  acg
44// SystemC 2.3
45//
46// Revision 1.3  2006/01/13 18:53:53  acg
47// Andy Goodrich: added $Log command so that CVS comments are reproduced in
48// the source.
49//
50
51#include <sstream>
52
53#include "systemc/ext/dt/bit/sc_lv_base.hh"
54
55namespace sc_dt
56{
57
58// explicit template instantiations
59template class sc_proxy<sc_lv_base>;
60template class sc_proxy<sc_bv_base>;
61
62void
63sc_proxy_out_of_bounds(const char *msg, int64 val)
64{
65    std::stringstream ss;
66    if (msg != NULL)
67        ss << msg;
68    if (val != 0)
69        ss << val;
70    SC_REPORT_ERROR("out of bounds", ss.str().c_str());
71}
72
73// ----------------------------------------------------------------------------
74//  CLASS : sc_lv_base
75//
76//  Arbitrary size logic vector base class.
77// ----------------------------------------------------------------------------
78
79static const sc_digit data_array[] = {
80    SC_DIGIT_ZERO, ~SC_DIGIT_ZERO, SC_DIGIT_ZERO, ~SC_DIGIT_ZERO
81};
82
83static const sc_digit ctrl_array[] = {
84    SC_DIGIT_ZERO, SC_DIGIT_ZERO, ~SC_DIGIT_ZERO, ~SC_DIGIT_ZERO
85};
86
87void
88sc_lv_base::init(int length_, const sc_logic& init_value)
89{
90    // check the length
91    if (length_ <= 0) {
92        SC_REPORT_ERROR("zero length", 0);
93        sc_core::sc_abort(); // can't recover from here
94    }
95    // allocate memory for the data and control words
96    m_len = length_;
97    m_size = (m_len - 1) / SC_DIGIT_SIZE + 1;
98    m_data = new sc_digit[m_size * 2];
99    m_ctrl = m_data + m_size;
100    // initialize the bits to 'init_value'
101    sc_digit dw = data_array[init_value.value()];
102    sc_digit cw = ctrl_array[init_value.value()];
103    int sz = m_size;
104    for (int i = 0; i < sz; ++i) {
105        m_data[i] = dw;
106        m_ctrl[i] = cw;
107    }
108    clean_tail();
109}
110
111void
112sc_lv_base::assign_from_string(const std::string &s)
113{
114    // s must have been converted to bin
115    int len = m_len;
116    int s_len = s.length() - 1;
117    int min_len = sc_min(len, s_len);
118    int i = 0;
119    for (; i < min_len; ++i) {
120        char c = s[s_len - i - 1];
121        set_bit(i, sc_logic::char_to_logic[(int)c]);
122    }
123    // if formatted, fill the rest with sign(s), otherwise fill with zeros
124    sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t(s[0] - '0')
125                                             : sc_logic_value_t(0));
126    for (; i < len; ++i) {
127        set_bit(i, fill);
128    }
129}
130
131// constructors
132sc_lv_base::sc_lv_base(const char *a) :
133    m_len(0), m_size(0), m_data(0), m_ctrl(0)
134{
135    std::string s = convert_to_bin(a);
136    init(s.length() - 1);
137    assign_from_string(s);
138}
139
140sc_lv_base::sc_lv_base(const char *a, int length_) :
141    m_len(0), m_size(0), m_data(0), m_ctrl(0)
142{
143    init(length_);
144    assign_from_string(convert_to_bin(a));
145}
146
147sc_lv_base::sc_lv_base(const sc_lv_base &a) :
148    sc_proxy<sc_lv_base>(), m_len(a.m_len), m_size(a.m_size),
149      m_data(new sc_digit[m_size * 2]), m_ctrl(m_data + m_size)
150{
151    // copy the bits
152    int sz = m_size;
153    for (int i = 0; i < sz; ++i) {
154        m_data[i] = a.m_data[i];
155        m_ctrl[i] = a.m_ctrl[i];
156    }
157}
158
159// assignment operators
160sc_lv_base &
161sc_lv_base::operator = (const char *a)
162{
163    assign_from_string(convert_to_bin(a));
164    return *this;
165}
166
167// returns true if logic vector contains only 0's and 1's
168bool
169sc_lv_base::is_01() const
170{
171    int sz = m_size;
172    for (int i = 0; i < sz; ++i) {
173        if (m_ctrl[i] != 0) {
174            return false;
175        }
176    }
177    return true;
178}
179
180} // namespace sc_dt
181