aboutsummaryrefslogtreecommitdiffstats
path: root/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'frontends')
-rw-r--r--frontends/aiger/aigerparse.cc77
-rw-r--r--frontends/ast/ast.cc10
-rw-r--r--frontends/ast/ast.h3
-rw-r--r--frontends/ast/genrtlil.cc58
-rw-r--r--frontends/ast/simplify.cc94
-rw-r--r--frontends/ilang/ilang_parser.y6
-rw-r--r--frontends/rpc/Makefile.inc2
-rw-r--r--frontends/verific/verific.cc106
-rw-r--r--frontends/verific/verific.h2
-rw-r--r--frontends/verilog/verilog_frontend.cc2
-rw-r--r--frontends/verilog/verilog_frontend.h2
-rw-r--r--frontends/verilog/verilog_parser.y93
12 files changed, 309 insertions, 146 deletions
diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc
index 92cf92fa8..6fda92d73 100644
--- a/frontends/aiger/aigerparse.cc
+++ b/frontends/aiger/aigerparse.cc
@@ -784,7 +784,7 @@ void AigerReader::post_process()
ff->attributes[ID::abc9_mergeability] = mergeability[i];
}
- dict<RTLIL::IdString, int> wideports_cache;
+ dict<RTLIL::IdString, std::pair<int,int>> wideports_cache;
if (!map_filename.empty()) {
std::ifstream mf(map_filename);
@@ -799,11 +799,12 @@ void AigerReader::post_process()
log_assert(wire->port_input);
log_debug("Renaming input %s", log_id(wire));
+ RTLIL::Wire *existing = nullptr;
if (index == 0) {
// Cope with the fact that a CI might be identical
// to a PI (necessary due to ABC); in those cases
// simply connect the latter to the former
- RTLIL::Wire* existing = module->wire(escaped_s);
+ existing = module->wire(escaped_s);
if (!existing)
module->rename(wire, escaped_s);
else {
@@ -812,20 +813,29 @@ void AigerReader::post_process()
}
log_debug(" -> %s\n", log_id(escaped_s));
}
- else if (index > 0) {
- std::string indexed_name = stringf("%s[%d]", escaped_s.c_str(), index);
- RTLIL::Wire* existing = module->wire(indexed_name);
- if (!existing) {
+ else {
+ RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s.c_str(), index);
+ existing = module->wire(indexed_name);
+ if (!existing)
module->rename(wire, indexed_name);
- if (wideports)
- wideports_cache[escaped_s] = std::max(wideports_cache[escaped_s], index);
- }
else {
module->connect(wire, existing);
wire->port_input = false;
}
log_debug(" -> %s\n", log_id(indexed_name));
}
+
+ if (wideports && !existing) {
+ auto r = wideports_cache.insert(escaped_s);
+ if (r.second) {
+ r.first->second.first = index;
+ r.first->second.second = index;
+ }
+ else {
+ r.first->second.first = std::min(r.first->second.first, index);
+ r.first->second.second = std::max(r.first->second.second, index);
+ }
+ }
}
else if (type == "output") {
log_assert(static_cast<unsigned>(variable + co_count) < outputs.size());
@@ -834,14 +844,14 @@ void AigerReader::post_process()
log_assert(wire->port_output);
log_debug("Renaming output %s", log_id(wire));
+ RTLIL::Wire *existing;
if (index == 0) {
// Cope with the fact that a CO might be identical
// to a PO (necessary due to ABC); in those cases
// simply connect the latter to the former
- RTLIL::Wire* existing = module->wire(escaped_s);
- if (!existing) {
+ existing = module->wire(escaped_s);
+ if (!existing)
module->rename(wire, escaped_s);
- }
else {
wire->port_output = false;
existing->port_output = true;
@@ -850,14 +860,11 @@ void AigerReader::post_process()
}
log_debug(" -> %s\n", log_id(escaped_s));
}
- else if (index > 0) {
- std::string indexed_name = stringf("%s[%d]", escaped_s.c_str(), index);
- RTLIL::Wire* existing = module->wire(indexed_name);
- if (!existing) {
+ else {
+ RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s.c_str(), index);
+ existing = module->wire(indexed_name);
+ if (!existing)
module->rename(wire, indexed_name);
- if (wideports)
- wideports_cache[escaped_s] = std::max(wideports_cache[escaped_s], index);
- }
else {
wire->port_output = false;
existing->port_output = true;
@@ -865,10 +872,18 @@ void AigerReader::post_process()
}
log_debug(" -> %s\n", log_id(indexed_name));
}
- int init;
- mf >> init;
- if (init < 2)
- wire->attributes[ID::init] = init;
+
+ if (wideports && !existing) {
+ auto r = wideports_cache.insert(escaped_s);
+ if (r.second) {
+ r.first->second.first = index;
+ r.first->second.second = index;
+ }
+ else {
+ r.first->second.first = std::min(r.first->second.first, index);
+ r.first->second.second = std::max(r.first->second.second, index);
+ }
+ }
}
else if (type == "box") {
RTLIL::Cell* cell = module->cell(stringf("$box%d", variable));
@@ -882,7 +897,8 @@ void AigerReader::post_process()
for (auto &wp : wideports_cache) {
auto name = wp.first;
- int width = wp.second + 1;
+ int min = wp.second.first;
+ int max = wp.second.second;
RTLIL::Wire *wire = module->wire(name);
if (wire)
@@ -891,7 +907,7 @@ void AigerReader::post_process()
// Do not make ports with a mix of input/output into
// wide ports
bool port_input = false, port_output = false;
- for (int i = 0; i < width; i++) {
+ for (int i = min; i <= max; i++) {
RTLIL::IdString other_name = name.str() + stringf("[%d]", i);
RTLIL::Wire *other_wire = module->wire(other_name);
if (other_wire) {
@@ -900,20 +916,21 @@ void AigerReader::post_process()
}
}
- wire = module->addWire(name, width);
+ wire = module->addWire(name, max-min+1);
+ wire->start_offset = min;
wire->port_input = port_input;
wire->port_output = port_output;
- for (int i = 0; i < width; i++) {
- RTLIL::IdString other_name = name.str() + stringf("[%d]", i);
+ for (int i = min; i <= max; i++) {
+ RTLIL::IdString other_name = stringf("%s[%d]", name.c_str(), i);
RTLIL::Wire *other_wire = module->wire(other_name);
if (other_wire) {
other_wire->port_input = false;
other_wire->port_output = false;
if (wire->port_input)
- module->connect(other_wire, SigSpec(wire, i));
+ module->connect(other_wire, SigSpec(wire, i-min));
else
- module->connect(SigSpec(wire, i), other_wire);
+ module->connect(SigSpec(wire, i-min), other_wire);
}
}
}
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 733556621..689fa9fb4 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -94,6 +94,7 @@ std::string AST::type2str(AstNodeType type)
X(AST_TO_BITS)
X(AST_TO_SIGNED)
X(AST_TO_UNSIGNED)
+ X(AST_SELFSZ)
X(AST_CONCAT)
X(AST_REPLICATE)
X(AST_BIT_NOT)
@@ -110,6 +111,8 @@ std::string AST::type2str(AstNodeType type)
X(AST_SHIFT_RIGHT)
X(AST_SHIFT_SLEFT)
X(AST_SHIFT_SRIGHT)
+ X(AST_SHIFTX)
+ X(AST_SHIFT)
X(AST_LT)
X(AST_LE)
X(AST_EQ)
@@ -615,6 +618,7 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const
if (0) { case AST_POS: txt = "+"; }
if (0) { case AST_NEG: txt = "-"; }
if (0) { case AST_LOGIC_NOT: txt = "!"; }
+ if (0) { case AST_SELFSZ: txt = "@selfsz@"; }
fprintf(f, "%s(", txt.c_str());
children[0]->dumpVlog(f, "");
fprintf(f, ")");
@@ -628,6 +632,8 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const
if (0) { case AST_SHIFT_RIGHT: txt = ">>"; }
if (0) { case AST_SHIFT_SLEFT: txt = "<<<"; }
if (0) { case AST_SHIFT_SRIGHT: txt = ">>>"; }
+ if (0) { case AST_SHIFTX: txt = "@shiftx@"; }
+ if (0) { case AST_SHIFT: txt = "@shift@"; }
if (0) { case AST_LT: txt = "<"; }
if (0) { case AST_LE: txt = "<="; }
if (0) { case AST_EQ: txt = "=="; }
@@ -946,6 +952,7 @@ RTLIL::Const AstNode::realAsConst(int width)
// create a new AstModule from an AST_MODULE AST node
static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false)
{
+ log_assert(current_scope.empty());
log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE);
if (defer)
@@ -1117,6 +1124,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
}
ignoreThisSignalsInInitial = RTLIL::SigSpec();
+ current_scope.clear();
}
else {
for (auto &attr : ast->attributes) {
@@ -1229,11 +1237,13 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
// process enum/other declarations
(*it)->simplify(true, false, false, 1, -1, false, false);
design->verilog_packages.push_back((*it)->clone());
+ current_scope.clear();
}
else {
// must be global definition
(*it)->simplify(false, false, false, 1, -1, false, false); //process enum/other declarations
design->verilog_globals.push_back((*it)->clone());
+ current_scope.clear();
}
}
}
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 3f6329112..8932108e3 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -75,6 +75,7 @@ namespace AST
AST_TO_BITS,
AST_TO_SIGNED,
AST_TO_UNSIGNED,
+ AST_SELFSZ,
AST_CONCAT,
AST_REPLICATE,
AST_BIT_NOT,
@@ -91,6 +92,8 @@ namespace AST
AST_SHIFT_RIGHT,
AST_SHIFT_SLEFT,
AST_SHIFT_SRIGHT,
+ AST_SHIFTX,
+ AST_SHIFT,
AST_LT,
AST_LE,
AST_EQ,
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index d35335747..d4e9baa5f 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -43,12 +43,12 @@ using namespace AST_INTERNAL;
// helper function for creating RTLIL code for unary operations
static RTLIL::SigSpec uniop2rtlil(AstNode *that, IdString type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true)
{
- IdString name = stringf("%s$%s:%d$%d", type.c_str(), that->filename.c_str(), that->location.first_line, autoidx++);
+ IdString name = stringf("%s$%s:%d$%d", type.c_str(), that->filename.c_str(), that->location.first_line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(name, type);
- cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width);
- wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column);
if (gen_attributes)
for (auto &attr : that->attributes) {
@@ -74,12 +74,12 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
return;
}
- IdString name = stringf("$extend$%s:%d$%d", that->filename.c_str(), that->location.first_line, autoidx++);
+ IdString name = stringf("$extend$%s:%d$%d", that->filename.c_str(), that->location.first_line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(name, ID($pos));
- cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width);
- wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column);
if (that != NULL)
for (auto &attr : that->attributes) {
@@ -100,12 +100,12 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
// helper function for creating RTLIL code for binary operations
static RTLIL::SigSpec binop2rtlil(AstNode *that, IdString type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{
- IdString name = stringf("%s$%s:%d$%d", type.c_str(), that->filename.c_str(), that->location.first_line, autoidx++);
+ IdString name = stringf("%s$%s:%d$%d", type.c_str(), that->filename.c_str(), that->location.first_line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(name, type);
- cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width);
- wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column);
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
@@ -136,10 +136,10 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const
sstr << "$ternary$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($mux));
- cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", left.size());
- wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column);
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
@@ -171,7 +171,7 @@ struct AST_INTERNAL::LookaheadRewriter
for (auto c : node->id2ast->children)
wire->children.push_back(c->clone());
wire->str = stringf("$lookahead%s$%d", node->str.c_str(), autoidx++);
- wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
+ wire->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
wire->is_logic = true;
while (wire->simplify(true, false, false, 1, -1, false, false)) { }
current_ast_mod->children.push_back(wire);
@@ -809,6 +809,11 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
sign_hint = false;
break;
+ case AST_SELFSZ:
+ sub_width_hint = 0;
+ children.at(0)->detectSignWidthWorker(sub_width_hint, sign_hint);
+ break;
+
case AST_CONCAT:
for (auto child : children) {
sub_width_hint = 0;
@@ -856,6 +861,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
case AST_SHIFT_RIGHT:
case AST_SHIFT_SLEFT:
case AST_SHIFT_SRIGHT:
+ case AST_SHIFTX:
+ case AST_SHIFT:
case AST_POW:
children[0]->detectSignWidthWorker(width_hint, sign_hint, found_real);
break;
@@ -923,7 +930,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
}
break;
}
- /* fall through */
+ YS_FALLTHROUGH
// everything should have been handled above -> print error if not.
default:
@@ -1019,7 +1026,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (GetSize(children) >= 1 && children[0]->type == AST_CONSTANT) {
current_module->parameter_default_values[str] = children[0]->asParaConst();
}
- /* fall through */
+ YS_FALLTHROUGH
case AST_LOCALPARAM:
if (flag_pwires)
{
@@ -1205,13 +1212,18 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
AstNode *fake_ast = new AstNode(AST_NONE, clone(), children[0]->children.size() >= 2 ?
children[0]->children[1]->clone() : children[0]->children[0]->clone());
fake_ast->children[0]->delete_children();
- RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL();
+
+ int fake_ast_width = 0;
+ bool fake_ast_sign = true;
+ fake_ast->children[1]->detectSignWidth(fake_ast_width, fake_ast_sign);
+ RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL(fake_ast_width, fake_ast_sign);
+
if (id2ast->range_right != 0) {
- shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right, fake_ast->children[1]->is_signed);
+ shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right, fake_ast_sign);
fake_ast->children[1]->is_signed = true;
}
if (id2ast->range_swapped) {
- shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val, fake_ast->children[1]->is_signed);
+ shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val, fake_ast_sign);
fake_ast->children[1]->is_signed = true;
}
if (GetSize(shift_val) >= 32)
@@ -1265,7 +1277,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// just pass thru the signal. the parent will evaluate the is_signed property and interpret the SigSpec accordingly
case AST_TO_SIGNED:
- case AST_TO_UNSIGNED: {
+ case AST_TO_UNSIGNED:
+ case AST_SELFSZ: {
RTLIL::SigSpec sig = children[0]->genRTLIL();
if (sig.size() < width_hint)
sig.extend_u0(width_hint, sign_hint);
@@ -1356,6 +1369,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (0) { case AST_SHIFT_RIGHT: type_name = ID($shr); }
if (0) { case AST_SHIFT_SLEFT: type_name = ID($sshl); }
if (0) { case AST_SHIFT_SRIGHT: type_name = ID($sshr); }
+ if (0) { case AST_SHIFTX: type_name = ID($shiftx); }
+ if (0) { case AST_SHIFT: type_name = ID($shift); }
{
if (width_hint < 0)
detectSignWidth(width_hint, sign_hint);
@@ -1500,10 +1515,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
sstr << "$memrd$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($memrd));
- cell->attributes[ID::src] = stringf("%s:%d", filename.c_str(), location.first_line);
+ cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_DATA", current_module->memories[str]->width);
- wire->attributes[ID::src] = stringf("%s:%d", filename.c_str(), location.first_line);
+ wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
int mem_width, mem_size, addr_bits;
is_signed = id2ast->is_signed;
@@ -1807,7 +1822,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
is_signed = sign_hint;
return SigSpec(wire);
}
- } /* fall through */
+ }
+ YS_FALLTHROUGH
// everything should have been handled above -> print error if not.
default:
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 837c14ad7..f629df387 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -91,7 +91,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg
case 'D':
if (got_len)
goto unsupported_format;
- /* fall through */
+ YS_FALLTHROUGH
case 'x':
case 'X':
if (next_arg >= GetSize(children))
@@ -608,6 +608,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
case AST_TO_BITS:
case AST_TO_SIGNED:
case AST_TO_UNSIGNED:
+ case AST_SELFSZ:
case AST_CONCAT:
case AST_REPLICATE:
case AST_REDUCE_AND:
@@ -920,11 +921,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
range_swapped = templ->range_swapped;
range_left = templ->range_left;
range_right = templ->range_right;
- attributes["\\wiretype"] = mkconst_str(resolved_type->str);
+ attributes[ID::wiretype] = mkconst_str(resolved_type->str);
//check if enum
- if (templ->attributes.count("\\enum_type")){
+ if (templ->attributes.count(ID::enum_type)){
//get reference to enum node:
- std::string enum_type = templ->attributes["\\enum_type"]->str.c_str();
+ const std::string &enum_type = templ->attributes[ID::enum_type]->str;
// log("enum_type=%s (count=%lu)\n", enum_type.c_str(), current_scope.count(enum_type));
// log("current scope:\n");
// for (auto &it : current_scope)
@@ -972,7 +973,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
RTLIL::Const val = enum_item->children[0]->bitsAsConst(width, is_signed);
enum_item_str.append(val.as_string());
//set attribute for available val to enum item name mappings
- attributes[enum_item_str.c_str()] = mkconst_str(enum_item->str);
+ attributes[enum_item_str] = mkconst_str(enum_item->str);
}
}
@@ -1021,7 +1022,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
range_swapped = templ->range_swapped;
range_left = templ->range_left;
range_right = templ->range_right;
- attributes["\\wiretype"] = mkconst_str(resolved_type->str);
+ attributes[ID::wiretype] = mkconst_str(resolved_type->str);
for (auto template_child : templ->children)
children.push_back(template_child->clone());
did_something = true;
@@ -1079,7 +1080,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
if (old_range_valid != range_valid)
did_something = true;
- if (range_valid && range_left >= 0 && range_right > range_left) {
+ if (range_valid && range_right > range_left) {
int tmp = range_right;
range_right = range_left;
range_left = tmp;
@@ -1739,8 +1740,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
AstNode *node = children_list[1];
if (op_type != AST_POS)
- for (size_t i = 2; i < children_list.size(); i++)
+ for (size_t i = 2; i < children_list.size(); i++) {
node = new AstNode(op_type, node, children_list[i]);
+ node->location = location;
+ }
if (invert_results)
node = new AstNode(AST_BIT_NOT, node);
@@ -1786,7 +1789,18 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
result_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;
}
- if (0)
+ bool use_case_method = false;
+
+ if (children[0]->id2ast->attributes.count(ID::nowrshmsk)) {
+ AstNode *node = children[0]->id2ast->attributes.at(ID::nowrshmsk);
+ while (node->simplify(true, false, false, stage, -1, false, false)) { }
+ if (node->type != AST_CONSTANT)
+ log_file_error(filename, location.first_line, "Non-constant value for `nowrshmsk' attribute on `%s'!\n", children[0]->id2ast->str.c_str());
+ if (node->asAttrConst().as_bool())
+ use_case_method = true;
+ }
+
+ if (use_case_method)
{
// big case block
@@ -1794,10 +1808,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
newNode = new AstNode(AST_CASE, shift_expr);
for (int i = 0; i < source_width; i++) {
int start_bit = children[0]->id2ast->range_right + i;
+ int end_bit = std::min(start_bit+result_width,source_width) - 1;
AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true));
AstNode *lvalue = children[0]->clone();
lvalue->delete_children();
- int end_bit = std::min(start_bit+result_width,source_width) - 1;
lvalue->children.push_back(new AstNode(AST_RANGE,
mkconst_int(end_bit, true), mkconst_int(start_bit, true)));
cond->children.push_back(new AstNode(AST_BLOCK, new AstNode(type, lvalue, children[1]->clone())));
@@ -1810,14 +1824,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
AstNode *wire_mask = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(source_width-1, true), mkconst_int(0, true)));
wire_mask->str = stringf("$bitselwrite$mask$%s:%d$%d", filename.c_str(), location.first_line, autoidx++);
- wire_mask->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
+ wire_mask->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
wire_mask->is_logic = true;
while (wire_mask->simplify(true, false, false, 1, -1, false, false)) { }
current_ast_mod->children.push_back(wire_mask);
AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(source_width-1, true), mkconst_int(0, true)));
wire_data->str = stringf("$bitselwrite$data$%s:%d$%d", filename.c_str(), location.first_line, autoidx++);
- wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
+ wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
wire_data->is_logic = true;
while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
current_ast_mod->children.push_back(wire_data);
@@ -1844,11 +1858,40 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
AstNode *shamt = shift_expr;
- newNode->children.push_back(new AstNode(AST_ASSIGN_EQ, ref_mask->clone(),
- new AstNode(AST_SHIFT_LEFT, mkconst_bits(std::vector<RTLIL::State>(result_width, State::S1), false), shamt->clone())));
- newNode->children.push_back(new AstNode(AST_ASSIGN_EQ, ref_data->clone(),
- new AstNode(AST_SHIFT_LEFT, new AstNode(AST_BIT_AND, mkconst_bits(std::vector<RTLIL::State>(result_width, State::S1), false), children[1]->clone()), shamt)));
- newNode->children.push_back(new AstNode(type, lvalue, new AstNode(AST_BIT_OR, new AstNode(AST_BIT_AND, old_data, new AstNode(AST_BIT_NOT, ref_mask)), ref_data)));
+ int shamt_width_hint = 0;
+ bool shamt_sign_hint = true;
+ shamt->detectSignWidth(shamt_width_hint, shamt_sign_hint);
+
+ int start_bit = children[0]->id2ast->range_right;
+ bool use_shift = shamt_sign_hint;
+
+ if (start_bit != 0) {
+ shamt = new AstNode(AST_SUB, shamt, mkconst_int(start_bit, true));
+ use_shift = true;
+ }
+
+ AstNode *t;
+
+ t = mkconst_bits(std::vector<RTLIL::State>(result_width, State::S1), false);
+ if (use_shift)
+ t = new AstNode(AST_SHIFT, t, new AstNode(AST_NEG, shamt->clone()));
+ else
+ t = new AstNode(AST_SHIFT_LEFT, t, shamt->clone());
+ t = new AstNode(AST_ASSIGN_EQ, ref_mask->clone(), t);
+ newNode->children.push_back(t);
+
+ t = new AstNode(AST_BIT_AND, mkconst_bits(std::vector<RTLIL::State>(result_width, State::S1), false), children[1]->clone());
+ if (use_shift)
+ t = new AstNode(AST_SHIFT, t, new AstNode(AST_NEG, shamt));
+ else
+ t = new AstNode(AST_SHIFT_LEFT, t, shamt);
+ t = new AstNode(AST_ASSIGN_EQ, ref_data->clone(), t);
+ newNode->children.push_back(t);
+
+ t = new AstNode(AST_BIT_AND, old_data, new AstNode(AST_BIT_NOT, ref_mask));
+ t = new AstNode(AST_BIT_OR, t, ref_data);
+ t = new AstNode(type, lvalue, t);
+ newNode->children.push_back(t);
}
goto apply_newNode;
@@ -2637,7 +2680,7 @@ skip_dynamic_range_lvalue_expansion:;
bool recommend_const_eval = false;
bool require_const_eval = in_param ? false : has_const_only_constructs(recommend_const_eval);
- if ((in_param || recommend_const_eval || require_const_eval) && !decl->attributes.count("\\via_celltype"))
+ if ((in_param || recommend_const_eval || require_const_eval) && !decl->attributes.count(ID::via_celltype))
{
bool all_args_const = true;
for (auto child : children) {
@@ -2696,9 +2739,9 @@ skip_dynamic_range_lvalue_expansion:;
goto replace_fcall_with_id;
}
- if (decl->attributes.count("\\via_celltype"))
+ if (decl->attributes.count(ID::via_celltype))
{
- std::string celltype = decl->attributes.at("\\via_celltype")->asAttrConst().decode_string();
+ std::string celltype = decl->attributes.at(ID::via_celltype)->asAttrConst().decode_string();
std::string outport = str;
if (celltype.find(' ') != std::string::npos) {
@@ -2792,7 +2835,7 @@ skip_dynamic_range_lvalue_expansion:;
wire->is_reg = true;
wire->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
if (child->type == AST_ENUM_ITEM)
- wire->attributes["\\enum_base_type"] = child->attributes["\\enum_base_type"];
+ wire->attributes[ID::enum_base_type] = child->attributes[ID::enum_base_type];
wire_cache[child->str] = wire;
@@ -3024,6 +3067,7 @@ replace_fcall_later:;
}
}
break;
+ if (0) { case AST_SELFSZ: const_func = RTLIL::const_pos; }
if (0) { case AST_POS: const_func = RTLIL::const_pos; }
if (0) { case AST_NEG: const_func = RTLIL::const_neg; }
if (children[0]->type == AST_CONSTANT) {
@@ -3032,10 +3076,10 @@ replace_fcall_later:;
} else
if (children[0]->isConst()) {
newNode = new AstNode(AST_REALVALUE);
- if (type == AST_POS)
- newNode->realvalue = +children[0]->asReal(sign_hint);
- else
+ if (type == AST_NEG)
newNode->realvalue = -children[0]->asReal(sign_hint);
+ else
+ newNode->realvalue = +children[0]->asReal(sign_hint);
}
break;
case AST_TERNARY:
@@ -4092,7 +4136,7 @@ void AstNode::allocateDefaultEnumValues()
int last_enum_int = -1;
for (auto node : children) {
log_assert(node->type==AST_ENUM_ITEM);
- node->attributes["\\enum_base_type"] = mkconst_str(str);
+ node->attributes[ID::enum_base_type] = mkconst_str(str);
for (size_t i = 0; i < node->children.size(); i++) {
switch (node->children[i]->type) {
case AST_NONE:
diff --git a/frontends/ilang/ilang_parser.y b/frontends/ilang/ilang_parser.y
index 8e21fb176..118f13de9 100644
--- a/frontends/ilang/ilang_parser.y
+++ b/frontends/ilang/ilang_parser.y
@@ -107,16 +107,16 @@ module:
delete_current_module = false;
if (current_design->has($2)) {
RTLIL::Module *existing_mod = current_design->module($2);
- if (!flag_overwrite && (flag_lib || (attrbuf.count("\\blackbox") && attrbuf.at("\\blackbox").as_bool()))) {
+ if (!flag_overwrite && (flag_lib || (attrbuf.count(ID::blackbox) && attrbuf.at(ID::blackbox).as_bool()))) {
log("Ignoring blackbox re-definition of module %s.\n", $2);
delete_current_module = true;
- } else if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute("\\blackbox")) {
+ } else if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute(ID::blackbox)) {
rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str());
} else if (flag_nooverwrite) {
log("Ignoring re-definition of module %s.\n", $2);
delete_current_module = true;
} else {
- log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "", $2);
+ log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "", $2);
current_design->remove(existing_mod);
}
}
diff --git a/frontends/rpc/Makefile.inc b/frontends/rpc/Makefile.inc
index 7b270b6fe..fa1d068f9 100644
--- a/frontends/rpc/Makefile.inc
+++ b/frontends/rpc/Makefile.inc
@@ -1,3 +1,3 @@
-ifneq ($(CONFIG),emcc)
+ifeq ($(DISABLE_SPAWN),0)
OBJS += frontends/rpc/rpc_frontend.o
endif
diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc
index ae7fcefa7..5f8a78e48 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -149,7 +149,7 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj)
return s;
}
-void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj)
+void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj, Netlist *nl)
{
MapIter mi;
Att *attr;
@@ -163,6 +163,68 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att
continue;
attributes[RTLIL::escape_id(attr->Key())] = RTLIL::Const(std::string(attr->Value()));
}
+
+ if (nl) {
+ auto type_range = nl->GetTypeRange(obj->Name());
+ if (!type_range)
+ return;
+ if (!type_range->IsTypeEnum())
+ return;
+ if (nl->IsFromVhdl() && strcmp(type_range->GetTypeName(), "STD_LOGIC") == 0)
+ return;
+ auto type_name = type_range->GetTypeName();
+ if (!type_name)
+ return;
+ attributes.emplace(ID::wiretype, RTLIL::escape_id(type_name));
+
+ MapIter mi;
+ const char *k, *v;
+ FOREACH_MAP_ITEM(type_range->GetEnumIdMap(), mi, &k, &v) {
+ if (nl->IsFromVerilog()) {
+ // Expect <decimal>'b<binary>
+ auto p = strchr(v, '\'');
+ if (p) {
+ if (*(p+1) != 'b')
+ p = nullptr;
+ else
+ for (auto q = p+2; *q != '\0'; q++)
+ if (*q != '0' && *q != '1') {
+ p = nullptr;
+ break;
+ }
+ }
+ if (p == nullptr)
+ log_error("Expected TypeRange value '%s' to be of form <decimal>'b<binary>.\n", v);
+ attributes.emplace(stringf("\\enum_value_%s", p+2), RTLIL::escape_id(k));
+ }
+ else if (nl->IsFromVhdl()) {
+ // Expect "<binary>"
+ auto p = v;
+ if (p) {
+ if (*p != '"')
+ p = nullptr;
+ else {
+ auto *q = p+1;
+ for (; *q != '"'; q++)
+ if (*q != '0' && *q != '1') {
+ p = nullptr;
+ break;
+ }
+ if (p && *(q+1) != '\0')
+ p = nullptr;
+ }
+ }
+ if (p == nullptr)
+ log_error("Expected TypeRange value '%s' to be of form \"<binary>\".\n", v);
+ auto l = strlen(p);
+ auto q = (char*)malloc(l+1-2);
+ strncpy(q, p+1, l-2);
+ q[l-2] = '\0';
+ attributes.emplace(stringf("\\enum_value_%s", q), RTLIL::escape_id(k));
+ free(q);
+ }
+ }
+ }
}
RTLIL::SigSpec VerificImporter::operatorInput(Instance *inst)
@@ -845,7 +907,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
log(" importing port %s.\n", port->Name());
RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(port->Name()));
- import_attributes(wire->attributes, port);
+ import_attributes(wire->attributes, port, nl);
wire->port_id = nl->IndexOf(port) + 1;
@@ -872,7 +934,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(portbus->Name()), portbus->Size());
wire->start_offset = min(portbus->LeftIndex(), portbus->RightIndex());
- import_attributes(wire->attributes, portbus);
+ import_attributes(wire->attributes, portbus, nl);
if (portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_IN)
wire->port_input = true;
@@ -1021,7 +1083,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
log(" importing net %s as %s.\n", net->Name(), log_id(wire_name));
RTLIL::Wire *wire = module->addWire(wire_name);
- import_attributes(wire->attributes, net);
+ import_attributes(wire->attributes, net, nl);
net_map[net] = wire;
}
@@ -1046,7 +1108,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::Wire *wire = module->addWire(wire_name, netbus->Size());
wire->start_offset = min(netbus->LeftIndex(), netbus->RightIndex());
- import_attributes(wire->attributes, netbus);
+ import_attributes(wire->attributes, netbus, nl);
RTLIL::Const initval = Const(State::Sx, GetSize(wire));
bool initval_valid = false;
@@ -1153,26 +1215,6 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
for (auto net : anyseq_nets)
module->connect(net_map_at(net), module->Anyseq(new_verific_id(net)));
- char *id_name;
- TypeRange *type_range;
- FOREACH_MAP_ITEM(nl->GetTypeRangeTable(), mi, &id_name, &type_range)
- {
- if (!type_range)
- continue;
- if (!type_range->IsTypeEnum())
- continue;
- auto wire = module->wire(RTLIL::escape_id(id_name));
- log_assert(wire);
- wire->set_string_attribute(ID(wiretype), type_range->GetTypeName());
-
- MapIter mj;
- char *k, *v;
- FOREACH_MAP_ITEM(type_range->GetEnumIdMap(), mj, &k, &v) {
- IdString key = stringf("\\enum_value_%s", v);
- wire->set_string_attribute(key, k);
- }
- }
-
pool<Instance*, hash_ptr_ops> sva_asserts;
pool<Instance*, hash_ptr_ops> sva_assumes;
pool<Instance*, hash_ptr_ops> sva_covers;
@@ -1223,7 +1265,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
int numchunks = int(inst->OutputSize()) / memory->width;
int chunksbits = ceil_log2(numchunks);
- if ((numchunks * memory->width) != int(inst->OutputSize()) || (numchunks & (numchunks - 1)) != 0)
+ if ((numchunks * memory->width) != int(inst->OutputSize()))
log_error("Import of asymmetric memories of this type is not supported yet: %s %s\n", inst->Name(), inst->GetInput()->Name());
for (int i = 0; i < numchunks; i++)
@@ -1231,6 +1273,11 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::SigSpec addr = {operatorInput1(inst), RTLIL::Const(i, chunksbits)};
RTLIL::SigSpec data = operatorOutput(inst).extract(i * memory->width, memory->width);
+ if ((numchunks & (numchunks - 1)) != 0) {
+ addr = module->Mul(NEW_ID, operatorInput1(inst), RTLIL::Const(numchunks));
+ addr = module->Add(NEW_ID, addr, RTLIL::Const(i));
+ }
+
RTLIL::Cell *cell = module->addCell(numchunks == 1 ? inst_name :
RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), ID($memrd));
cell->parameters[ID::MEMID] = memory->name.str();
@@ -1253,7 +1300,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
int numchunks = int(inst->Input2Size()) / memory->width;
int chunksbits = ceil_log2(numchunks);
- if ((numchunks * memory->width) != int(inst->Input2Size()) || (numchunks & (numchunks - 1)) != 0)
+ if ((numchunks * memory->width) != int(inst->Input2Size()))
log_error("Import of asymmetric memories of this type is not supported yet: %s %s\n", inst->Name(), inst->GetOutput()->Name());
for (int i = 0; i < numchunks; i++)
@@ -1261,6 +1308,11 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::SigSpec addr = {operatorInput1(inst), RTLIL::Const(i, chunksbits)};
RTLIL::SigSpec data = operatorInput2(inst).extract(i * memory->width, memory->width);
+ if ((numchunks & (numchunks - 1)) != 0) {
+ addr = module->Mul(NEW_ID, operatorInput1(inst), RTLIL::Const(numchunks));
+ addr = module->Add(NEW_ID, addr, RTLIL::Const(i));
+ }
+
RTLIL::Cell *cell = module->addCell(numchunks == 1 ? inst_name :
RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), ID($memwr));
cell->parameters[ID::MEMID] = memory->name.str();
diff --git a/frontends/verific/verific.h b/frontends/verific/verific.h
index 2ccfcd42c..f168a2588 100644
--- a/frontends/verific/verific.h
+++ b/frontends/verific/verific.h
@@ -79,7 +79,7 @@ struct VerificImporter
RTLIL::SigBit net_map_at(Verific::Net *net);
RTLIL::IdString new_verific_id(Verific::DesignObj *obj);
- void import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, Verific::DesignObj *obj);
+ void import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, Verific::DesignObj *obj, Verific::Netlist *nl = nullptr);
RTLIL::SigSpec operatorInput(Verific::Instance *inst);
RTLIL::SigSpec operatorInput1(Verific::Instance *inst);
diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc
index 6879e0943..26abe49b5 100644
--- a/frontends/verilog/verilog_frontend.cc
+++ b/frontends/verilog/verilog_frontend.cc
@@ -48,7 +48,7 @@ static void error_on_dpi_function(AST::AstNode *node)
error_on_dpi_function(child);
}
-static void add_package_types(std::map<std::string, AST::AstNode *> &user_types, std::vector<AST::AstNode *> &package_list)
+static void add_package_types(dict<std::string, AST::AstNode *> &user_types, std::vector<AST::AstNode *> &package_list)
{
// prime the parser's user type lookup table with the package qualified names
// of typedefed names in the packages seen so far.
diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h
index 444cc7297..aa7881038 100644
--- a/frontends/verilog/verilog_frontend.h
+++ b/frontends/verilog/verilog_frontend.h
@@ -50,7 +50,7 @@ namespace VERILOG_FRONTEND
extern std::vector<UserTypeMap *> user_type_stack;
// names of package typedef'ed types
- extern std::map<std::string, AST::AstNode*> pkg_user_types;
+ extern dict<std::string, AST::AstNode*> pkg_user_types;
// state of `default_nettype
extern bool default_nettype_wire;
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 4a5aba79e..f250d7685 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -50,12 +50,12 @@ using namespace VERILOG_FRONTEND;
YOSYS_NAMESPACE_BEGIN
namespace VERILOG_FRONTEND {
int port_counter;
- std::map<std::string, int> port_stubs;
- std::map<std::string, AstNode*> *attr_list, default_attr_list;
- std::stack<std::map<std::string, AstNode*> *> attr_list_stack;
- std::map<std::string, AstNode*> *albuf;
+ dict<std::string, int> port_stubs;
+ dict<IdString, AstNode*> *attr_list, default_attr_list;
+ std::stack<dict<IdString, AstNode*> *> attr_list_stack;
+ dict<IdString, AstNode*> *albuf;
std::vector<UserTypeMap*> user_type_stack;
- std::map<std::string, AstNode*> pkg_user_types;
+ dict<std::string, AstNode*> pkg_user_types;
std::vector<AstNode*> ast_stack;
struct AstNode *astbuf1, *astbuf2, *astbuf3;
struct AstNode *current_function_or_task;
@@ -87,7 +87,7 @@ YOSYS_NAMESPACE_END
int frontend_verilog_yylex(YYSTYPE *yylval_param, YYLTYPE *yyloc_param);
-static void append_attr(AstNode *ast, std::map<std::string, AstNode*> *al)
+static void append_attr(AstNode *ast, dict<IdString, AstNode*> *al)
{
for (auto &it : *al) {
if (ast->attributes.count(it.first) > 0)
@@ -97,7 +97,7 @@ static void append_attr(AstNode *ast, std::map<std::string, AstNode*> *al)
delete al;
}
-static void append_attr_clone(AstNode *ast, std::map<std::string, AstNode*> *al)
+static void append_attr_clone(AstNode *ast, dict<IdString, AstNode*> *al)
{
for (auto &it : *al) {
if (ast->attributes.count(it.first) > 0)
@@ -106,7 +106,7 @@ static void append_attr_clone(AstNode *ast, std::map<std::string, AstNode*> *al)
}
}
-static void free_attr(std::map<std::string, AstNode*> *al)
+static void free_attr(dict<IdString, AstNode*> *al)
{
for (auto &it : *al)
delete it.second;
@@ -192,7 +192,7 @@ static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned =
%union {
std::string *string;
struct YOSYS_NAMESPACE_PREFIX AST::AstNode *ast;
- std::map<std::string, YOSYS_NAMESPACE_PREFIX AST::AstNode*> *al;
+ YOSYS_NAMESPACE_PREFIX dict<YOSYS_NAMESPACE_PREFIX RTLIL::IdString, YOSYS_NAMESPACE_PREFIX AST::AstNode*> *al;
struct specify_target *specify_target_ptr;
struct specify_triple *specify_triple_ptr;
struct specify_rise_fall *specify_rise_fall_ptr;
@@ -289,7 +289,7 @@ attr:
{
if (attr_list != nullptr)
attr_list_stack.push(attr_list);
- attr_list = new std::map<std::string, AstNode*>;
+ attr_list = new dict<IdString, AstNode*>;
for (auto &it : default_attr_list)
(*attr_list)[it.first] = it.second->clone();
} attr_opt {
@@ -311,7 +311,7 @@ defattr:
DEFATTR_BEGIN {
if (attr_list != nullptr)
attr_list_stack.push(attr_list);
- attr_list = new std::map<std::string, AstNode*>;
+ attr_list = new dict<IdString, AstNode*>;
for (auto &it : default_attr_list)
delete it.second;
default_attr_list.clear();
@@ -645,13 +645,13 @@ non_opt_range:
} |
'[' expr TOK_POS_INDEXED expr ']' {
$$ = new AstNode(AST_RANGE);
- AstNode *expr = new AstNode(AST_CONCAT, $2);
+ AstNode *expr = new AstNode(AST_SELFSZ, $2);
$$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), $4), AstNode::mkconst_int(1, true)));
$$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));
} |
'[' expr TOK_NEG_INDEXED expr ']' {
$$ = new AstNode(AST_RANGE);
- AstNode *expr = new AstNode(AST_CONCAT, $2);
+ AstNode *expr = new AstNode(AST_SELFSZ, $2);
$$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));
$$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), AstNode::mkconst_int(1, true)), $4));
} |
@@ -853,7 +853,19 @@ task_func_port:
}
if (astbuf2 && astbuf2->children.size() != 2)
frontend_verilog_yyerror("task/function argument range must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
- } wire_name | wire_name;
+ } wire_name |
+ {
+ if (!astbuf1) {
+ if (!sv_mode)
+ frontend_verilog_yyerror("task/function argument direction missing");
+ albuf = new dict<IdString, AstNode*>;
+ astbuf1 = new AstNode(AST_WIRE);
+ current_wire_rand = false;
+ current_wire_const = false;
+ astbuf1->is_input = true;
+ astbuf2 = NULL;
+ }
+ } wire_name;
task_func_body:
task_func_body behavioral_stmt |
@@ -885,6 +897,7 @@ specify_item:
cell->str = stringf("$specify$%d", autoidx++);
cell->children.push_back(new AstNode(AST_CELLTYPE));
cell->children.back()->str = target->dat ? "$specify3" : "$specify2";
+ SET_AST_NODE_LOC(cell, en_expr ? @1 : @2, @10);
char oper_polarity = 0;
char oper_type = oper->at(0);
@@ -973,6 +986,7 @@ specify_item:
cell->str = stringf("$specify$%d", autoidx++);
cell->children.push_back(new AstNode(AST_CELLTYPE));
cell->children.back()->str = "$specrule";
+ SET_AST_NODE_LOC(cell, @1, @14);
cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_str(*$1)));
cell->children.back()->str = "\\TYPE";
@@ -1099,8 +1113,8 @@ specify_rise_fall:
$$->fall = *$4;
delete $2;
delete $4;
- delete $6;
- log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
+ delete $6;
+ log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
} |
'(' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ')' {
$$ = new specify_rise_fall;
@@ -1108,11 +1122,11 @@ specify_rise_fall:
$$->fall = *$4;
delete $2;
delete $4;
- delete $6;
- delete $8;
- delete $10;
- delete $12;
- log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
+ delete $6;
+ delete $8;
+ delete $10;
+ delete $12;
+ log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
} |
'(' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ')' {
$$ = new specify_rise_fall;
@@ -1120,17 +1134,17 @@ specify_rise_fall:
$$->fall = *$4;
delete $2;
delete $4;
- delete $6;
- delete $8;
- delete $10;
- delete $12;
- delete $14;
- delete $16;
- delete $18;
- delete $20;
- delete $22;
- delete $24;
- log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
+ delete $6;
+ delete $8;
+ delete $10;
+ delete $12;
+ delete $14;
+ delete $16;
+ delete $18;
+ delete $20;
+ delete $22;
+ delete $24;
+ log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
}
specify_triple:
@@ -1388,7 +1402,7 @@ enum_type: TOK_ENUM {
delete astbuf1;
astbuf1 = tnode;
tnode->type = AST_WIRE;
- tnode->attributes["\\enum_type"] = AstNode::mkconst_str(astbuf2->str);
+ tnode->attributes[ID::enum_type] = AstNode::mkconst_str(astbuf2->str);
// drop constant but keep any range
delete tnode->children[0];
tnode->children.erase(tnode->children.begin()); }
@@ -1747,7 +1761,9 @@ single_prim:
/* no name */ {
astbuf2 = astbuf1->clone();
ast_stack.back()->children.push_back(astbuf2);
- } '(' cell_port_list ')';
+ } '(' cell_port_list ')' {
+ SET_AST_NODE_LOC(astbuf2, @1, @$);
+ }
cell_parameter_list_opt:
'#' '(' cell_parameter_list ')' | /* empty */;
@@ -2341,7 +2357,7 @@ unique_case_attr:
case_attr:
attr unique_case_attr {
- if ($2) (*$1)["\\parallel_case"] = AstNode::mkconst_int(1, false);
+ if ($2) (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false);
$$ = $1;
};
@@ -2533,7 +2549,12 @@ gen_stmt:
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
ast_stack.back()->children.push_back($3);
- } gen_stmt_block opt_gen_else {
+ AstNode *block = new AstNode(AST_GENBLOCK);
+ ast_stack.back()->children.push_back(block);
+ ast_stack.push_back(block);
+ } gen_stmt_or_null {
+ ast_stack.pop_back();
+ } opt_gen_else {
SET_AST_NODE_LOC(ast_stack.back(), @1, @7);
ast_stack.pop_back();
} |