/* * Copyright (c) 2010-2014 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "netenum.h" # include "compiler.h" # include using namespace std; netenum_t::netenum_t(ivl_variable_type_t btype, bool signed_flag, bool integer_flag, long msb, long lsb, size_t name_count, enum_type_t*enum_type) : base_type_(btype), enum_type_(enum_type), signed_flag_(signed_flag), integer_flag_(integer_flag), msb_(msb), lsb_(lsb), names_(name_count), bits_(name_count) { } netenum_t::~netenum_t() { } bool netenum_t::get_signed() const { return signed_flag_; } bool netenum_t::get_isint() const { return integer_flag_; } /* * Enumerations are by definition always packed. */ bool netenum_t::packed() const { return true; } long netenum_t::packed_width() const { if (msb_ >= lsb_) return msb_ - lsb_ + 1; else return lsb_ - msb_ + 1; } vector netenum_t::slice_dimensions() const { vector tmp (1); tmp[0] = netrange_t(msb_, lsb_); return tmp; } bool netenum_t::insert_name(size_t name_idx, perm_string name, const verinum&val) { std::pair::iterator, bool> res; assert((msb_-lsb_+1) > 0); assert(val.has_len() && val.len() == (unsigned)(msb_-lsb_+1)); // Insert a map of the name to the value. This also gets a // flag that returns true if the name is unique, or false // otherwise. res = names_map_.insert( make_pair(name,val) ); assert(name_idx < names_.size() && names_[name_idx] == 0); names_[name_idx] = name; return res.second; } void netenum_t::insert_name_close(void) { for (size_t idx = 0 ; idx < names_.size() ; idx += 1) { // If we failed to elaborate the name then skip this step. if (names_[idx].nil()) continue; netenum_t::iterator cur = names_map_.find(names_[idx]); vectorstr (cur->second.len() + 1); for (unsigned bit = 0 ; bit < cur->second.len() ; bit += 1) { switch (cur->second.get(bit)) { case verinum::V0: str[bit] = '0'; break; case verinum::V1: str[bit] = '1'; break; case verinum::Vx: str[bit] = 'x'; break; case verinum::Vz: str[bit] = 'z'; break; } } bits_[idx] = bits_strings.make(&str[0]); } } netenum_t::iterator netenum_t::find_name(perm_string name) const { return names_map_.find(name); } /* * Check to see if the given value is already in the enumeration mapping. */ perm_string netenum_t::find_value(const verinum&val) const { perm_string res; for(netenum_t::iterator cur = names_map_.begin(); cur != names_map_.end(); ++ cur) { if (cur->second == val) { res = cur->first; break; } } return res; } netenum_t::iterator netenum_t::end_name() const { return names_map_.end(); } netenum_t::iterator netenum_t::first_name() const { return names_map_.find(names_.front()); } netenum_t::iterator netenum_t::last_name() const { return names_map_.find(names_.back()); } perm_string netenum_t::name_at(size_t idx) const { assert(idx < names_.size()); return names_[idx]; } perm_string netenum_t::bits_at(size_t idx) const { return bits_[idx]; } bool netenum_t::matches(const netenum_t*other) const { return enum_type_ == other->enum_type_; }