aboutsummaryrefslogtreecommitdiffstats
path: root/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'frontends')
-rw-r--r--frontends/ast/ast.cc6
-rw-r--r--frontends/ast/ast.h3
-rw-r--r--frontends/ast/genrtlil.cc32
-rw-r--r--frontends/ast/simplify.cc92
-rw-r--r--frontends/ilang/ilang_parser.y6
-rw-r--r--frontends/verilog/verilog_frontend.cc2
-rw-r--r--frontends/verilog/verilog_frontend.h2
-rw-r--r--frontends/verilog/verilog_parser.y79
8 files changed, 150 insertions, 72 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 6a9af3f57..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 = "=="; }
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 5894c7b3c..d4e9baa5f 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -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);
@@ -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 cdb7e91e0..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;
@@ -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/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..db9a130cf 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));
} |
@@ -885,6 +885,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 +974,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 +1101,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 +1110,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 +1122,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 +1390,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 +1749,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 +2345,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 +2537,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();
} |