/*****************************************************************************

  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
  more contributor license agreements.  See the NOTICE file distributed
  with this work for additional information regarding copyright ownership.
  Accellera licenses this file to you under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with the
  License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  implied.  See the License for the specific language governing
  permissions and limitations under the License.

 *****************************************************************************/

/*****************************************************************************

  sc_lv_base.cpp -- Arbitrary size logic vector class.

  Original Author: Gene Bushuyev, Synopsys, Inc.

 *****************************************************************************/

/*****************************************************************************

  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
  changes you are making here.

      Name, Affiliation, Date:
  Description of Modification:

 *****************************************************************************/


// $Log: sc_lv_base.cpp,v $
// Revision 1.2  2011/08/24 22:05:40  acg
//  Torsten Maehne: initialization changes to remove warnings.
//
// Revision 1.1.1.1  2006/12/15 20:20:04  acg
// SystemC 2.3
//
// Revision 1.3  2006/01/13 18:53:53  acg
// Andy Goodrich: added $Log command so that CVS comments are reproduced in
// the source.
//

#include <sstream>

#include "systemc/ext/dt/bit/sc_lv_base.hh"

namespace sc_dt
{

// explicit template instantiations
template class sc_proxy<sc_lv_base>;
template class sc_proxy<sc_bv_base>;

void
sc_proxy_out_of_bounds(const char *msg, int64 val)
{
    std::stringstream ss;
    if (msg != NULL)
        ss << msg;
    if (val != 0)
        ss << val;
    SC_REPORT_ERROR("(E5) out of bounds", ss.str().c_str());
}

// ----------------------------------------------------------------------------
//  CLASS : sc_lv_base
//
//  Arbitrary size logic vector base class.
// ----------------------------------------------------------------------------

static const sc_digit data_array[] = {
    SC_DIGIT_ZERO, ~SC_DIGIT_ZERO, SC_DIGIT_ZERO, ~SC_DIGIT_ZERO
};

static const sc_digit ctrl_array[] = {
    SC_DIGIT_ZERO, SC_DIGIT_ZERO, ~SC_DIGIT_ZERO, ~SC_DIGIT_ZERO
};

void
sc_lv_base::init(int length_, const sc_logic& init_value)
{
    // check the length
    if (length_ <= 0) {
        SC_REPORT_ERROR("zero length", 0);
        sc_core::sc_abort(); // can't recover from here
    }
    // allocate memory for the data and control words
    m_len = length_;
    m_size = (m_len - 1) / SC_DIGIT_SIZE + 1;
    m_data = new sc_digit[m_size * 2];
    m_ctrl = m_data + m_size;
    // initialize the bits to 'init_value'
    sc_digit dw = data_array[init_value.value()];
    sc_digit cw = ctrl_array[init_value.value()];
    int sz = m_size;
    for (int i = 0; i < sz; ++i) {
        m_data[i] = dw;
        m_ctrl[i] = cw;
    }
    clean_tail();
}

void
sc_lv_base::assign_from_string(const std::string &s)
{
    // s must have been converted to bin
    int len = m_len;
    int s_len = s.length() - 1;
    int min_len = sc_min(len, s_len);
    int i = 0;
    for (; i < min_len; ++i) {
        char c = s[s_len - i - 1];
        set_bit(i, sc_logic::char_to_logic[(int)c]);
    }
    // if formatted, fill the rest with sign(s), otherwise fill with zeros
    sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t(s[0] - '0')
                                             : sc_logic_value_t(0));
    for (; i < len; ++i) {
        set_bit(i, fill);
    }
}

// constructors
sc_lv_base::sc_lv_base(const char *a) :
    m_len(0), m_size(0), m_data(0), m_ctrl(0)
{
    std::string s = convert_to_bin(a);
    init(s.length() - 1);
    assign_from_string(s);
}

sc_lv_base::sc_lv_base(const char *a, int length_) :
    m_len(0), m_size(0), m_data(0), m_ctrl(0)
{
    init(length_);
    assign_from_string(convert_to_bin(a));
}

sc_lv_base::sc_lv_base(const sc_lv_base &a) :
    sc_proxy<sc_lv_base>(), m_len(a.m_len), m_size(a.m_size),
      m_data(new sc_digit[m_size * 2]), m_ctrl(m_data + m_size)
{
    // copy the bits
    int sz = m_size;
    for (int i = 0; i < sz; ++i) {
        m_data[i] = a.m_data[i];
        m_ctrl[i] = a.m_ctrl[i];
    }
}

// assignment operators
sc_lv_base &
sc_lv_base::operator = (const char *a)
{
    assign_from_string(convert_to_bin(a));
    return *this;
}

// returns true if logic vector contains only 0's and 1's
bool
sc_lv_base::is_01() const
{
    int sz = m_size;
    for (int i = 0; i < sz; ++i) {
        if (m_ctrl[i] != 0) {
            return false;
        }
    }
    return true;
}

} // namespace sc_dt
