sc_lv_base.cc revision 13322
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#include "systemc/ext/utils/messages.hh"
55
56namespace sc_dt
57{
58
59// explicit template instantiations
60template class sc_proxy<sc_lv_base>;
61template class sc_proxy<sc_bv_base>;
62
63void
64sc_proxy_out_of_bounds(const char *msg, int64 val)
65{
66    std::stringstream ss;
67    if (msg != NULL)
68        ss << msg;
69    if (val != 0)
70        ss << val;
71    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, ss.str().c_str());
72}
73
74// ----------------------------------------------------------------------------
75//  CLASS : sc_lv_base
76//
77//  Arbitrary size logic vector base class.
78// ----------------------------------------------------------------------------
79
80static const sc_digit data_array[] = {
81    SC_DIGIT_ZERO, ~SC_DIGIT_ZERO, SC_DIGIT_ZERO, ~SC_DIGIT_ZERO
82};
83
84static const sc_digit ctrl_array[] = {
85    SC_DIGIT_ZERO, SC_DIGIT_ZERO, ~SC_DIGIT_ZERO, ~SC_DIGIT_ZERO
86};
87
88void
89sc_lv_base::init(int length_, const sc_logic& init_value)
90{
91    // check the length
92    if (length_ <= 0) {
93        SC_REPORT_ERROR("zero length", 0);
94        sc_core::sc_abort(); // can't recover from here
95    }
96    // allocate memory for the data and control words
97    m_len = length_;
98    m_size = (m_len - 1) / SC_DIGIT_SIZE + 1;
99    m_data = new sc_digit[m_size * 2];
100    m_ctrl = m_data + m_size;
101    // initialize the bits to 'init_value'
102    sc_digit dw = data_array[init_value.value()];
103    sc_digit cw = ctrl_array[init_value.value()];
104    int sz = m_size;
105    for (int i = 0; i < sz; ++i) {
106        m_data[i] = dw;
107        m_ctrl[i] = cw;
108    }
109    clean_tail();
110}
111
112void
113sc_lv_base::assign_from_string(const std::string &s)
114{
115    // s must have been converted to bin
116    int len = m_len;
117    int s_len = s.length() - 1;
118    int min_len = sc_min(len, s_len);
119    int i = 0;
120    for (; i < min_len; ++i) {
121        char c = s[s_len - i - 1];
122        set_bit(i, sc_logic::char_to_logic[(int)c]);
123    }
124    // if formatted, fill the rest with sign(s), otherwise fill with zeros
125    sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t(s[0] - '0')
126                                             : sc_logic_value_t(0));
127    for (; i < len; ++i) {
128        set_bit(i, fill);
129    }
130}
131
132// constructors
133sc_lv_base::sc_lv_base(const char *a) :
134    m_len(0), m_size(0), m_data(0), m_ctrl(0)
135{
136    std::string s = convert_to_bin(a);
137    init(s.length() - 1);
138    assign_from_string(s);
139}
140
141sc_lv_base::sc_lv_base(const char *a, int length_) :
142    m_len(0), m_size(0), m_data(0), m_ctrl(0)
143{
144    init(length_);
145    assign_from_string(convert_to_bin(a));
146}
147
148sc_lv_base::sc_lv_base(const sc_lv_base &a) :
149    sc_proxy<sc_lv_base>(), m_len(a.m_len), m_size(a.m_size),
150      m_data(new sc_digit[m_size * 2]), m_ctrl(m_data + m_size)
151{
152    // copy the bits
153    int sz = m_size;
154    for (int i = 0; i < sz; ++i) {
155        m_data[i] = a.m_data[i];
156        m_ctrl[i] = a.m_ctrl[i];
157    }
158}
159
160// assignment operators
161sc_lv_base &
162sc_lv_base::operator = (const char *a)
163{
164    assign_from_string(convert_to_bin(a));
165    return *this;
166}
167
168// returns true if logic vector contains only 0's and 1's
169bool
170sc_lv_base::is_01() const
171{
172    int sz = m_size;
173    for (int i = 0; i < sz; ++i) {
174        if (m_ctrl[i] != 0) {
175            return false;
176        }
177    }
178    return true;
179}
180
181} // namespace sc_dt
182