/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/compatibility.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"
#include "frontends/verilog/verilog_frontend.h"
#include "backends/ilang/ilang_backend.h"
#include <string.h>
#include <algorithm>
int RTLIL::autoidx = 1;
RTLIL::Const::Const()
{
flags = RTLIL::CONST_FLAG_NONE;
}
RTLIL::Const::Const(std::string str)
{
flags = RTLIL::CONST_FLAG_STRING;
for (int i = str.size()-1; i >= 0; i--) {
unsigned char ch = str[i];
for (int j = 0; j < 8; j++) {
bits.push_back((ch & 1) != 0 ? RTLIL::S1 : RTLIL::S0);
ch = ch >> 1;
}
}
}
RTLIL::Const::Const(int val, int width)
{
flags = RTLIL::CONST_FLAG_NONE;
for (int i = 0; i < width; i++) {
bits.push_back((val & 1) != 0 ? RTLIL::S1 : RTLIL::S0);
val = val >> 1;
}
}
RTLIL::Const::Const(RTLIL::State bit, int width)
{
flags = RTLIL::CONST_FLAG_NONE;
for (int i = 0; i < width; i++)
bits.push_back(bit);
}
bool RTLIL::Const::operator <(const RTLIL::Const &other) const
{
if (bits.size() != other.bits.size())
return bits.size() < other.bits.size();
for (size_t i = 0; i < bits.size(); i++)
if (bits[i] != other.bits[i])
return bits[i] < other.bits[i];
return false;
}
bool RTLIL::Const::operator ==(const RTLIL::Const &other) const
{
return bits == other.bits;
}
bool RTLIL::Const::operator !=(const RTLIL::Const &other) const
{
return bits != other.bits;
}
bool RTLIL::Const::as_bool() const
{
for (size_t i = 0; i < bits.size(); i++)
if (bits[i] == RTLIL::S1)
return true;
return false;
}
int RTLIL::Const::as_int() const
{
int ret = 0;
for (size_t i = 0; i < bits.size() && i < 32; i++)
if (bits[i] == RTLIL::S1)
ret |= 1 << i;
return ret;
}
std::string RTLIL::Const::as_string() const
{
std::string ret;
for (size_t i = bits.size(); i > 0; i--)
switch (bits[i-1]) {
case S0: ret += "0"; break;
case S1: ret += "1"; break;
case Sx: ret += "x"; break;
case Sz: ret += "z"; break;
case Sa: ret += "-"; break;
case Sm: ret += "m"; break;
}
return ret;
}
std::string RTLIL::Const::decode_string() const
{
std::string string;
std::vector <char> string_chars;
for (int i = 0; i < int (bits.size()); i += 8) {
char ch = 0;
for (int j = 0; j < 8 && i + j < int (bits.size()); j++)
if (bits[i + j] == RTLIL::State::S1)
ch |= 1 << j;
if (ch != 0)
string_chars.push_back(ch);
}
for (int i = int (string_chars.size()) - 1; i >= 0; i--)
string += string_chars[i];
return string;
}
bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const
{
if (full_selection)
return true;
if (selected_modules.count(mod_name) > 0)
return true;
if (selected_members.count(mod_name) > 0)
return true;
return false;
}
bool RTLIL::Selection::selected_whole_module(RTLIL::IdString mod_name) const
{
if (full_selection)
return true;
if (selected_modules.count(mod_name) > 0)
return true;
return false;
}
bool RTLIL::Selection::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const
{
if (full_selection)
return true;
if (selected_modules.count(mod_name) > 0)
return true;
if (selected_members.count(mod_name) > 0)
if (selected_members.at(mod_name).count(memb_name) > 0)
return true;
return false;
}
void RTLIL::Selection::optimize(RTLIL::Design *design)
{
if (full_selection) {
selected_modules.clear();
selected_members.clear();
return;
}
std::vector<RTLIL::IdString> del_list, add_list;
del_list.clear();
for (auto mod_name : selected_modules) {
if (design->modules_.count(mod_name) == 0)
del_list.push_back(mod_name);
selected_members.erase(mod_name);
}
for (auto mod_name : del_list)
selected_modules.erase(mod_name);
del_list.clear();
for (auto &it : selected_members)
if (design->modules_.count(it.first) == 0)