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