#include <sstream>
#include <stdarg.h>
-#include <assert.h>
+#include <math.h>
+
+YOSYS_NAMESPACE_BEGIN
using namespace AST;
using namespace AST_INTERNAL;
X(AST_ARGUMENT)
X(AST_RANGE)
X(AST_CONSTANT)
+ X(AST_REALVALUE)
X(AST_CELLTYPE)
X(AST_IDENTIFIER)
X(AST_PREFIX)
X(AST_ASSIGN)
X(AST_CELL)
X(AST_PRIMITIVE)
+ X(AST_CELLARRAY)
X(AST_ALWAYS)
X(AST_INITIAL)
X(AST_BLOCK)
X(AST_DEFAULT)
X(AST_FOR)
X(AST_WHILE)
+ X(AST_REPEAT)
X(AST_GENVAR)
X(AST_GENFOR)
X(AST_GENIF)
is_signed = false;
is_string = false;
range_valid = false;
+ range_swapped = false;
port_id = 0;
range_left = -1;
range_right = 0;
integer = 0;
+ realvalue = 0;
id2ast = NULL;
basic_prep = false;
std::string type_name = type2str(type);
fprintf(f, "%s%s <%s:%d>", indent.c_str(), type_name.c_str(), filename.c_str(), linenum);
+
+ if (id2ast)
+ fprintf(f, " [%p -> %p]", this, id2ast);
+ else
+ fprintf(f, " [%p]", this);
+
if (!str.empty())
fprintf(f, " str='%s'", str.c_str());
if (!bits.empty()) {
if (port_id > 0)
fprintf(f, " port=%d", port_id);
if (range_valid || range_left != -1 || range_right != 0)
- fprintf(f, " range=[%d:%d]%s", range_left, range_right, range_valid ? "" : "!");
+ fprintf(f, " %srange=[%d:%d]%s", range_swapped ? "swapped_" : "", range_left, range_right, range_valid ? "" : "!");
if (integer != 0)
fprintf(f, " int=%u", (int)integer);
+ if (realvalue != 0)
+ fprintf(f, " real=%e", realvalue);
fprintf(f, "\n");
for (auto &it : attributes) {
fprintf(f, "%zd'b %s", bits.size(), RTLIL::Const(bits).as_string().c_str());
break;
+ case AST_REALVALUE:
+ fprintf(f, "%e", realvalue);
+ break;
+
case AST_BLOCK:
if (children.size() == 1) {
children[0]->dumpVlog(f, indent);
return false;
if (range_valid != other.range_valid)
return false;
+ if (range_swapped != other.range_swapped)
+ return false;
if (port_id != other.port_id)
return false;
if (range_left != other.range_left)
return false;
}
+int AstNode::isConst()
+{
+ if (type == AST_CONSTANT)
+ return 1;
+ if (type == AST_REALVALUE)
+ return 2;
+ return 0;
+}
+
+double AstNode::asReal(bool is_signed)
+{
+ if (type == AST_CONSTANT) {
+ RTLIL::Const val(bits);
+
+ bool is_negative = is_signed && val.bits.back() == RTLIL::State::S1;
+ if (is_negative)
+ val = const_neg(val, val, false, false, val.bits.size());
+
+ double v = 0;
+ for (size_t i = 0; i < val.bits.size(); i++)
+ // IEEE Std 1800-2012 Par 6.12.2: Individual bits that are x or z in
+ // the net or the variable shall be treated as zero upon conversion.
+ if (val.bits.at(i) == RTLIL::State::S1)
+ v += exp2(i);
+ if (is_negative)
+ v *= -1;
+
+ return v;
+ }
+
+ if (type == AST_REALVALUE)
+ return realvalue;
+
+ log_abort();
+}
+
+RTLIL::Const AstNode::realAsConst(int width)
+{
+ double v = round(realvalue);
+ RTLIL::Const result;
+ if (!std::isfinite(v)) {
+ result.bits = std::vector<RTLIL::State>(width, RTLIL::State::Sx);
+ } else {
+ bool is_negative = v < 0;
+ if (is_negative)
+ v *= -1;
+ for (int i = 0; i < width; i++, v /= 2)
+ result.bits.push_back((fmod(floor(v), 2) != 0) ? RTLIL::State::S1 : RTLIL::State::S0);
+ if (is_negative)
+ result = const_neg(result, result, false, false, result.bits.size());
+ }
+ return result;
+}
+
// create a new AstModule from an AST_MODULE AST node
static AstModule* process_module(AstNode *ast, bool defer)
{
- assert(ast->type == AST_MODULE);
+ log_assert(ast->type == AST_MODULE);
if (defer)
log("Storing AST representation for module `%s'.\n", ast->str.c_str());
flag_icells = icells;
flag_autowire = autowire;
- assert(current_ast->type == AST_DESIGN);
+ log_assert(current_ast->type == AST_DESIGN);
for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) {
if (flag_icells && (*it)->str.substr(0, 2) == "\\$")
(*it)->str = (*it)->str.substr(1);
if (defer)
(*it)->str = "$abstract" + (*it)->str;
- if (design->modules.count((*it)->str)) {
+ if (design->has((*it)->str)) {
if (!ignore_redef)
log_error("Re-definition of module `%s' at %s:%d!\n",
(*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
(*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
continue;
}
- design->modules[(*it)->str] = process_module(*it, defer);
+ design->add(process_module(*it, defer));
}
}
modname = "$paramod" + stripped_name + para_info;
}
- if (design->modules.count(modname) == 0) {
+ if (!design->has(modname)) {
new_ast->str = modname;
- design->modules[modname] = process_module(new_ast, false);
- design->modules[modname]->check();
+ design->add(process_module(new_ast, false));
+ design->module(modname)->check();
} else {
log("Found cached RTLIL representation for module `%s'.\n", modname.c_str());
}
RTLIL::Module *AstModule::clone() const
{
AstModule *new_mod = new AstModule;
+ new_mod->name = name;
cloneInto(new_mod);
new_mod->ast = ast->clone();
get_line_num = &internal_get_line_num;
}
+YOSYS_NAMESPACE_END
+