mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-21 21:33:40 +00:00
ast, read_verilog: ownership in AST, use C++ styles for parser and lexer
This commit is contained in:
parent
cd71f190cd
commit
8a9f491ffc
19 changed files with 3295 additions and 3312 deletions
|
@ -85,7 +85,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
|
|||
set_src_attr(wire, that);
|
||||
wire->is_signed = that->is_signed;
|
||||
|
||||
if (that != NULL)
|
||||
if (that != nullptr)
|
||||
for (auto &attr : that->attributes) {
|
||||
if (attr.second->type != AST_CONSTANT)
|
||||
that->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||
|
@ -195,22 +195,22 @@ struct AST_INTERNAL::LookaheadRewriter
|
|||
if (node->lookahead) {
|
||||
log_assert(node->type == AST_IDENTIFIER);
|
||||
if (!lookaheadids.count(node->str)) {
|
||||
AstNode *wire = new AstNode(AST_WIRE);
|
||||
for (auto c : node->id2ast->children)
|
||||
auto wire = std::make_unique<AstNode>(AST_WIRE);
|
||||
for (auto& c : node->id2ast->children)
|
||||
wire->children.push_back(c->clone());
|
||||
wire->fixup_hierarchy_flags();
|
||||
wire->str = stringf("$lookahead%s$%d", node->str.c_str(), autoidx++);
|
||||
wire->set_attribute(ID::nosync, AstNode::mkconst_int(1, false));
|
||||
wire->is_logic = true;
|
||||
while (wire->simplify(true, 1, -1, false)) { }
|
||||
current_ast_mod->children.push_back(wire);
|
||||
lookaheadids[node->str] = make_pair(node->id2ast, wire);
|
||||
lookaheadids[node->str] = make_pair(node->id2ast, wire.get());
|
||||
wire->genRTLIL();
|
||||
current_ast_mod->children.push_back(std::move(wire));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto child : node->children)
|
||||
collect_lookaheadids(child);
|
||||
for (auto& child : node->children)
|
||||
collect_lookaheadids(child.get());
|
||||
}
|
||||
|
||||
bool has_lookaheadids(AstNode *node)
|
||||
|
@ -218,8 +218,8 @@ struct AST_INTERNAL::LookaheadRewriter
|
|||
if (node->type == AST_IDENTIFIER && lookaheadids.count(node->str) != 0)
|
||||
return true;
|
||||
|
||||
for (auto child : node->children)
|
||||
if (has_lookaheadids(child))
|
||||
for (auto& child : node->children)
|
||||
if (has_lookaheadids(child.get()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -230,8 +230,8 @@ struct AST_INTERNAL::LookaheadRewriter
|
|||
if (node->type == AST_IDENTIFIER && lookaheadids.count(node->str) == 0)
|
||||
return true;
|
||||
|
||||
for (auto child : node->children)
|
||||
if (has_nonlookaheadids(child))
|
||||
for (auto& child : node->children)
|
||||
if (has_nonlookaheadids(child.get()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -241,16 +241,16 @@ struct AST_INTERNAL::LookaheadRewriter
|
|||
{
|
||||
if (node->type == AST_ASSIGN_LE)
|
||||
{
|
||||
if (has_lookaheadids(node->children[0]))
|
||||
if (has_lookaheadids(node->children[0].get()))
|
||||
{
|
||||
if (has_nonlookaheadids(node->children[0]))
|
||||
if (has_nonlookaheadids(node->children[0].get()))
|
||||
log_error("incompatible mix of lookahead and non-lookahead IDs in LHS expression.\n");
|
||||
|
||||
rewrite_lookaheadids(node->children[0], true);
|
||||
rewrite_lookaheadids(node->children[0].get(), true);
|
||||
node->type = AST_ASSIGN_EQ;
|
||||
}
|
||||
|
||||
rewrite_lookaheadids(node->children[1], lhs);
|
||||
rewrite_lookaheadids(node->children[1].get(), lhs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -261,21 +261,21 @@ struct AST_INTERNAL::LookaheadRewriter
|
|||
lhs = false;
|
||||
}
|
||||
|
||||
for (auto child : node->children)
|
||||
rewrite_lookaheadids(child, lhs);
|
||||
for (auto& child : node->children)
|
||||
rewrite_lookaheadids(child.get(), lhs);
|
||||
}
|
||||
|
||||
LookaheadRewriter(AstNode *top)
|
||||
{
|
||||
// top->dumpAst(NULL, "REWRITE-BEFORE> ");
|
||||
// top->dumpVlog(NULL, "REWRITE-BEFORE> ");
|
||||
// top->dumpAst(nullptr, "REWRITE-BEFORE> ");
|
||||
// top->dumpVlog(nullptr, "REWRITE-BEFORE> ");
|
||||
|
||||
AstNode *block = nullptr;
|
||||
|
||||
for (auto c : top->children)
|
||||
for (auto& c : top->children)
|
||||
if (c->type == AST_BLOCK) {
|
||||
log_assert(block == nullptr);
|
||||
block = c;
|
||||
block = c.get();
|
||||
}
|
||||
log_assert(block != nullptr);
|
||||
|
||||
|
@ -284,25 +284,25 @@ struct AST_INTERNAL::LookaheadRewriter
|
|||
|
||||
for (auto it : lookaheadids)
|
||||
{
|
||||
AstNode *ref_orig = new AstNode(AST_IDENTIFIER);
|
||||
auto ref_orig = std::make_unique<AstNode>(AST_IDENTIFIER);
|
||||
ref_orig->str = it.second.first->str;
|
||||
ref_orig->id2ast = it.second.first;
|
||||
ref_orig->was_checked = true;
|
||||
|
||||
AstNode *ref_temp = new AstNode(AST_IDENTIFIER);
|
||||
auto ref_temp = std::make_unique<AstNode>(AST_IDENTIFIER);
|
||||
ref_temp->str = it.second.second->str;
|
||||
ref_temp->id2ast = it.second.second;
|
||||
ref_temp->was_checked = true;
|
||||
|
||||
AstNode *init_assign = new AstNode(AST_ASSIGN_EQ, ref_temp->clone(), ref_orig->clone());
|
||||
AstNode *final_assign = new AstNode(AST_ASSIGN_LE, ref_orig, ref_temp);
|
||||
auto init_assign = std::make_unique<AstNode>(AST_ASSIGN_EQ, ref_temp->clone(), ref_orig->clone());
|
||||
auto final_assign = std::make_unique<AstNode>(AST_ASSIGN_LE, std::move(ref_orig), std::move(ref_temp));
|
||||
|
||||
block->children.insert(block->children.begin(), init_assign);
|
||||
block->children.push_back(final_assign);
|
||||
block->children.insert(block->children.begin(), std::move(init_assign));
|
||||
block->children.push_back(std::move(final_assign));
|
||||
}
|
||||
|
||||
// top->dumpAst(NULL, "REWRITE-AFTER> ");
|
||||
// top->dumpVlog(NULL, "REWRITE-AFTER> ");
|
||||
// top->dumpAst(nullptr, "REWRITE-AFTER> ");
|
||||
// top->dumpVlog(nullptr, "REWRITE-AFTER> ");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -310,7 +310,7 @@ struct AST_INTERNAL::LookaheadRewriter
|
|||
struct AST_INTERNAL::ProcessGenerator
|
||||
{
|
||||
// input and output structures
|
||||
AstNode *always;
|
||||
std::unique_ptr<AstNode> always;
|
||||
RTLIL::SigSpec initSyncSignals;
|
||||
RTLIL::Process *proc;
|
||||
RTLIL::SigSpec outputSignals;
|
||||
|
@ -341,14 +341,14 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
// The most recently assigned $print or $check cell \PRIORITY.
|
||||
int last_effect_priority;
|
||||
|
||||
ProcessGenerator(AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg), last_effect_priority(0)
|
||||
ProcessGenerator(std::unique_ptr<AstNode> a, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(std::move(a)), initSyncSignals(initSyncSignalsArg), last_effect_priority(0)
|
||||
{
|
||||
// rewrite lookahead references
|
||||
LookaheadRewriter la_rewriter(always);
|
||||
LookaheadRewriter la_rewriter(always.get());
|
||||
|
||||
// generate process and simple root case
|
||||
proc = current_module->addProcess(stringf("$proc$%s:%d$%d", RTLIL::encode_filename(always->filename).c_str(), always->location.first_line, autoidx++));
|
||||
set_src_attr(proc, always);
|
||||
set_src_attr(proc, always.get());
|
||||
for (auto &attr : always->attributes) {
|
||||
if (attr.second->type != AST_CONSTANT)
|
||||
always->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||
|
@ -358,13 +358,13 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
|
||||
// create initial temporary signal for all output registers
|
||||
RTLIL::SigSpec subst_lvalue_from, subst_lvalue_to;
|
||||
collect_lvalues(subst_lvalue_from, always, true, true);
|
||||
collect_lvalues(subst_lvalue_from, always.get(), true, true);
|
||||
subst_lvalue_to = new_temp_signal(subst_lvalue_from);
|
||||
subst_lvalue_map = subst_lvalue_from.to_sigbit_map(subst_lvalue_to);
|
||||
|
||||
bool found_global_syncs = false;
|
||||
bool found_anyedge_syncs = false;
|
||||
for (auto child : always->children)
|
||||
for (auto& child : always->children)
|
||||
{
|
||||
if ((child->type == AST_POSEDGE || child->type == AST_NEGEDGE) && GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER &&
|
||||
child->children.at(0)->id2ast && child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute(ID::gclk)) {
|
||||
|
@ -388,7 +388,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
|
||||
// create syncs for the process
|
||||
bool found_clocked_sync = false;
|
||||
for (auto child : always->children)
|
||||
for (auto& child : always->children)
|
||||
if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE) {
|
||||
if (GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER && child->children.at(0)->id2ast &&
|
||||
child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute(ID::gclk))
|
||||
|
@ -420,9 +420,9 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
}
|
||||
|
||||
// process the AST
|
||||
for (auto child : always->children)
|
||||
for (auto& child : always->children)
|
||||
if (child->type == AST_BLOCK)
|
||||
processAst(child);
|
||||
processAst(child.get());
|
||||
|
||||
for (auto sync: proc->syncs)
|
||||
processMemWrites(sync);
|
||||
|
@ -472,7 +472,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
for (int i = 0; i < GetSize(chunks); i++)
|
||||
{
|
||||
RTLIL::SigChunk &chunk = chunks[i];
|
||||
if (chunk.wire == NULL)
|
||||
if (chunk.wire == nullptr)
|
||||
continue;
|
||||
|
||||
std::string wire_name;
|
||||
|
@ -484,7 +484,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
} while (current_module->wires_.count(wire_name) > 0);
|
||||
|
||||
RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width);
|
||||
set_src_attr(wire, always);
|
||||
set_src_attr(wire, always.get());
|
||||
|
||||
chunk.wire = wire;
|
||||
chunk.offset = 0;
|
||||
|
@ -499,10 +499,10 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
switch (ast->type)
|
||||
{
|
||||
case AST_CASE:
|
||||
for (auto child : ast->children)
|
||||
for (auto& child : ast->children)
|
||||
if (child != ast->children[0]) {
|
||||
log_assert(child->type == AST_COND || child->type == AST_CONDX || child->type == AST_CONDZ);
|
||||
collect_lvalues(reg, child, type_eq, type_le, false);
|
||||
collect_lvalues(reg, child.get(), type_eq, type_le, false);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -511,19 +511,19 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
case AST_CONDZ:
|
||||
case AST_ALWAYS:
|
||||
case AST_INITIAL:
|
||||
for (auto child : ast->children)
|
||||
for (auto& child : ast->children)
|
||||
if (child->type == AST_BLOCK)
|
||||
collect_lvalues(reg, child, type_eq, type_le, false);
|
||||
collect_lvalues(reg, child.get(), type_eq, type_le, false);
|
||||
break;
|
||||
|
||||
case AST_BLOCK:
|
||||
for (auto child : ast->children) {
|
||||
for (auto& child : ast->children) {
|
||||
if (child->type == AST_ASSIGN_EQ && type_eq)
|
||||
reg.append(child->children[0]->genRTLIL());
|
||||
if (child->type == AST_ASSIGN_LE && type_le)
|
||||
reg.append(child->children[0]->genRTLIL());
|
||||
if (child->type == AST_CASE || child->type == AST_BLOCK)
|
||||
collect_lvalues(reg, child, type_eq, type_le, false);
|
||||
collect_lvalues(reg, child.get(), type_eq, type_le, false);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -583,8 +583,8 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
switch (ast->type)
|
||||
{
|
||||
case AST_BLOCK:
|
||||
for (auto child : ast->children)
|
||||
processAst(child);
|
||||
for (auto& child : ast->children)
|
||||
processAst(child.get());
|
||||
break;
|
||||
|
||||
case AST_ASSIGN_EQ:
|
||||
|
@ -641,9 +641,9 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
RTLIL::SigSpec this_case_eq_rvalue = this_case_eq_lvalue;
|
||||
this_case_eq_rvalue.replace(subst_rvalue_map.stdmap());
|
||||
|
||||
RTLIL::CaseRule *default_case = NULL;
|
||||
RTLIL::CaseRule *last_generated_case = NULL;
|
||||
for (auto child : ast->children)
|
||||
RTLIL::CaseRule *default_case = nullptr;
|
||||
RTLIL::CaseRule *last_generated_case = nullptr;
|
||||
for (auto& child : ast->children)
|
||||
{
|
||||
if (child == ast->children[0])
|
||||
continue;
|
||||
|
@ -657,14 +657,14 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
|
||||
RTLIL::CaseRule *backup_case = current_case;
|
||||
current_case = new RTLIL::CaseRule;
|
||||
set_src_attr(current_case, child);
|
||||
set_src_attr(current_case, child.get());
|
||||
last_generated_case = current_case;
|
||||
addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue);
|
||||
for (auto node : child->children) {
|
||||
for (auto& node : child->children) {
|
||||
if (node->type == AST_DEFAULT)
|
||||
default_case = current_case;
|
||||
else if (node->type == AST_BLOCK)
|
||||
processAst(node);
|
||||
processAst(node.get());
|
||||
else
|
||||
current_case->compare.push_back(node->genWidthRTLIL(width_hint, sign_hint, &subst_rvalue_map.stdmap()));
|
||||
}
|
||||
|
@ -678,7 +678,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
subst_rvalue_map.restore();
|
||||
}
|
||||
|
||||
if (last_generated_case != NULL && ast->get_bool_attribute(ID::full_case) && default_case == NULL) {
|
||||
if (last_generated_case != nullptr && ast->get_bool_attribute(ID::full_case) && default_case == nullptr) {
|
||||
#if 0
|
||||
// this is a valid transformation, but as optimization it is premature.
|
||||
// better: add a default case that assigns 'x' to everything, and let later
|
||||
|
@ -690,7 +690,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
sw->cases.push_back(default_case);
|
||||
#endif
|
||||
} else {
|
||||
if (default_case == NULL) {
|
||||
if (default_case == nullptr) {
|
||||
default_case = new RTLIL::CaseRule;
|
||||
addChunkActions(default_case->actions, this_case_eq_ltemp, this_case_eq_rvalue);
|
||||
}
|
||||
|
@ -760,7 +760,7 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
default_base = 16;
|
||||
|
||||
std::vector<VerilogFmtArg> args;
|
||||
for (auto node : ast->children) {
|
||||
for (auto& node : ast->children) {
|
||||
int width;
|
||||
bool is_signed;
|
||||
node->detectSignWidth(width, is_signed, nullptr);
|
||||
|
@ -866,8 +866,8 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
break;
|
||||
|
||||
default:
|
||||
// ast->dumpAst(NULL, "ast> ");
|
||||
// current_ast_mod->dumpAst(NULL, "mod> ");
|
||||
// ast->dumpAst(nullptr, "ast> ");
|
||||
// current_ast_mod->dumpAst(nullptr, "mod> ");
|
||||
log_abort();
|
||||
}
|
||||
}
|
||||
|
@ -876,14 +876,14 @@ struct AST_INTERNAL::ProcessGenerator
|
|||
{
|
||||
// Maps per-memid AST_MEMWR IDs to indices in the mem_write_actions array.
|
||||
dict<std::pair<std::string, int>, int> port_map;
|
||||
for (auto child : always->children)
|
||||
for (auto& child : always->children)
|
||||
if (child->type == AST_MEMWR)
|
||||
{
|
||||
std::string memid = child->str;
|
||||
int portid = child->children[3]->asInt(false);
|
||||
int cur_idx = GetSize(sync->mem_write_actions);
|
||||
RTLIL::MemWriteAction action;
|
||||
set_src_attr(&action, child);
|
||||
set_src_attr(&action, child.get());
|
||||
action.memid = memid;
|
||||
action.address = child->children[0]->genWidthRTLIL(-1, true, &subst_rvalue_map.stdmap());
|
||||
action.data = child->children[1]->genWidthRTLIL(current_module->memories[memid]->width, true, &subst_rvalue_map.stdmap());
|
||||
|
@ -971,11 +971,11 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
bool sub_sign_hint = true;
|
||||
int sub_width_hint = -1;
|
||||
int this_width = 0;
|
||||
AstNode *range = NULL;
|
||||
AstNode *id_ast = NULL;
|
||||
AstNode *range = nullptr;
|
||||
AstNode *id_ast = nullptr;
|
||||
|
||||
bool local_found_real = false;
|
||||
if (found_real == NULL)
|
||||
if (found_real == nullptr)
|
||||
found_real = &local_found_real;
|
||||
|
||||
switch (type)
|
||||
|
@ -1019,22 +1019,22 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
input_error("Failed to detect width for parameter %s!\n", str.c_str());
|
||||
}
|
||||
if (children.size() != 0)
|
||||
range = children[0];
|
||||
range = children[0].get();
|
||||
} else if (id_ast->type == AST_WIRE || id_ast->type == AST_AUTOWIRE) {
|
||||
if (!id_ast->range_valid) {
|
||||
if (id_ast->type == AST_AUTOWIRE)
|
||||
this_width = 1;
|
||||
else {
|
||||
// current_ast_mod->dumpAst(NULL, "mod> ");
|
||||
// current_ast_mod->dumpAst(nullptr, "mod> ");
|
||||
// log("---\n");
|
||||
// id_ast->dumpAst(NULL, "decl> ");
|
||||
// dumpAst(NULL, "ref> ");
|
||||
// id_ast->dumpAst(nullptr, "decl> ");
|
||||
// dumpAst(nullptr, "ref> ");
|
||||
input_error("Failed to detect width of signal access `%s'!\n", str.c_str());
|
||||
}
|
||||
} else {
|
||||
this_width = id_ast->range_left - id_ast->range_right + 1;
|
||||
if (children.size() != 0)
|
||||
range = children[0];
|
||||
range = children[0].get();
|
||||
}
|
||||
} else if (id_ast->type == AST_GENVAR) {
|
||||
this_width = 32;
|
||||
|
@ -1043,26 +1043,23 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
input_error("Failed to detect width of memory access `%s'!\n", str.c_str());
|
||||
this_width = id_ast->children[0]->range_left - id_ast->children[0]->range_right + 1;
|
||||
if (children.size() > 1)
|
||||
range = children[1];
|
||||
range = children[1].get();
|
||||
} else if (id_ast->type == AST_STRUCT_ITEM || id_ast->type == AST_STRUCT || id_ast->type == AST_UNION) {
|
||||
AstNode *tmp_range = make_index_range(id_ast);
|
||||
auto tmp_range = make_index_range(id_ast);
|
||||
this_width = tmp_range->range_left - tmp_range->range_right + 1;
|
||||
delete tmp_range;
|
||||
} else
|
||||
input_error("Failed to detect width for identifier %s!\n", str.c_str());
|
||||
if (range) {
|
||||
if (range->children.size() == 1)
|
||||
this_width = 1;
|
||||
else if (!range->range_valid) {
|
||||
AstNode *left_at_zero_ast = children[0]->children[0]->clone_at_zero();
|
||||
AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone_at_zero() : left_at_zero_ast->clone();
|
||||
auto left_at_zero_ast = children[0]->children[0]->clone_at_zero();
|
||||
auto right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone_at_zero() : left_at_zero_ast->clone();
|
||||
while (left_at_zero_ast->simplify(true, 1, -1, false)) { }
|
||||
while (right_at_zero_ast->simplify(true, 1, -1, false)) { }
|
||||
if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
|
||||
input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
|
||||
this_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;
|
||||
delete left_at_zero_ast;
|
||||
delete right_at_zero_ast;
|
||||
} else
|
||||
this_width = range->range_left - range->range_right + 1;
|
||||
sign_hint = false;
|
||||
|
@ -1106,7 +1103,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
break;
|
||||
|
||||
case AST_CONCAT:
|
||||
for (auto child : children) {
|
||||
for (auto& child : children) {
|
||||
sub_width_hint = 0;
|
||||
sub_sign_hint = true;
|
||||
child->detectSignWidthWorker(sub_width_hint, sub_sign_hint);
|
||||
|
@ -1135,7 +1132,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
case AST_BIT_OR:
|
||||
case AST_BIT_XOR:
|
||||
case AST_BIT_XNOR:
|
||||
for (auto child : children)
|
||||
for (auto& child : children)
|
||||
child->detectSignWidthWorker(width_hint, sign_hint, found_real);
|
||||
break;
|
||||
|
||||
|
@ -1175,7 +1172,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
case AST_MUL:
|
||||
case AST_DIV:
|
||||
case AST_MOD:
|
||||
for (auto child : children)
|
||||
for (auto& child : children)
|
||||
child->detectSignWidthWorker(width_hint, sign_hint, found_real);
|
||||
break;
|
||||
|
||||
|
@ -1216,12 +1213,13 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
width_hint = max(width_hint, sub_width_hint);
|
||||
sign_hint &= sub_sign_hint;
|
||||
};
|
||||
visit_case_expr(children[0]);
|
||||
visit_case_expr(children[0].get());
|
||||
for (size_t i = 1; i < children.size(); i++) {
|
||||
AstNode *child = children[i];
|
||||
for (AstNode *v : child->children)
|
||||
AstNode *child = children[i].get();
|
||||
for (auto& v : child->children) {
|
||||
if (v->type != AST_DEFAULT && v->type != AST_BLOCK)
|
||||
visit_case_expr(v);
|
||||
visit_case_expr(v.get());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1269,9 +1267,9 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
if (func->type != AST_FUNCTION)
|
||||
input_error("Function call to %s resolved to something that isn't a function!\n", RTLIL::unescape_id(str).c_str());
|
||||
const AstNode *wire = nullptr;
|
||||
for (const AstNode *child : func->children)
|
||||
for (const auto& child : func->children)
|
||||
if (child->str == func->str) {
|
||||
wire = child;
|
||||
wire = child.get();
|
||||
break;
|
||||
}
|
||||
log_assert(wire && wire->type == AST_WIRE);
|
||||
|
@ -1280,10 +1278,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
if (!wire->children.empty())
|
||||
{
|
||||
log_assert(wire->children.size() == 1);
|
||||
const AstNode *range = wire->children.at(0);
|
||||
const AstNode *range = wire->children.at(0).get();
|
||||
log_assert(range->type == AST_RANGE && range->children.size() == 2);
|
||||
AstNode *left = range->children.at(0)->clone();
|
||||
AstNode *right = range->children.at(1)->clone();
|
||||
auto left = range->children.at(0)->clone();
|
||||
auto right = range->children.at(1)->clone();
|
||||
left->set_in_param_flag(true);
|
||||
right->set_in_param_flag(true);
|
||||
while (left->simplify(true, 1, -1, false)) { }
|
||||
|
@ -1292,8 +1290,6 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
input_error("Function %s has non-constant width!",
|
||||
RTLIL::unescape_id(str).c_str());
|
||||
result_width = abs(int(left->asInt(true) - right->asInt(true)));
|
||||
delete left;
|
||||
delete right;
|
||||
}
|
||||
width_hint = max(width_hint, result_width);
|
||||
break;
|
||||
|
@ -1306,6 +1302,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
for (auto f : log_files)
|
||||
current_scope_ast->dumpAst(f, "verilog-ast> ");
|
||||
input_error("Don't know how to detect sign and width for %s node!\n", type2str(type).c_str());
|
||||
|
||||
}
|
||||
|
||||
if (*found_real)
|
||||
|
@ -1517,11 +1514,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
// shifter cell is created and the output signal of this cell is returned
|
||||
case AST_IDENTIFIER:
|
||||
{
|
||||
RTLIL::Wire *wire = NULL;
|
||||
RTLIL::Wire *wire = nullptr;
|
||||
RTLIL::SigChunk chunk;
|
||||
bool is_interface = false;
|
||||
|
||||
AST::AstNode *member_node = NULL;
|
||||
AST::AstNode *member_node = nullptr;
|
||||
int add_undef_bits_msb = 0;
|
||||
int add_undef_bits_lsb = 0;
|
||||
|
||||
|
@ -1608,14 +1605,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
}
|
||||
|
||||
if (!children[0]->range_valid) {
|
||||
AstNode *left_at_zero_ast = children[0]->children[0]->clone_at_zero();
|
||||
AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone_at_zero() : left_at_zero_ast->clone();
|
||||
auto left_at_zero_ast = children[0]->children[0]->clone_at_zero();
|
||||
auto right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone_at_zero() : left_at_zero_ast->clone();
|
||||
while (left_at_zero_ast->simplify(true, 1, -1, false)) { }
|
||||
while (right_at_zero_ast->simplify(true, 1, -1, false)) { }
|
||||
if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
|
||||
input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
|
||||
int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;
|
||||
AstNode *fake_ast = new AstNode(AST_NONE, clone(), children[0]->children.size() >= 2 ?
|
||||
auto 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();
|
||||
if (member_node)
|
||||
|
@ -1637,9 +1634,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
if (GetSize(shift_val) >= 32)
|
||||
fake_ast->children[1]->is_signed = true;
|
||||
RTLIL::SigSpec sig = binop2rtlil(fake_ast, ID($shiftx), width, fake_ast->children[0]->genRTLIL(), shift_val);
|
||||
delete left_at_zero_ast;
|
||||
delete right_at_zero_ast;
|
||||
delete fake_ast;
|
||||
return sig;
|
||||
} else {
|
||||
chunk.width = children[0]->range_left - children[0]->range_right + 1;
|
||||
|
@ -2092,7 +2086,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
cell->set_bool_attribute(ID::module_not_derived);
|
||||
|
||||
for (auto it = children.begin(); it != children.end(); it++) {
|
||||
AstNode *child = *it;
|
||||
AstNode *child = it->get();
|
||||
if (child->type == AST_CELLTYPE) {
|
||||
cell->type = child->str;
|
||||
if (flag_icells && cell->type.begins_with("\\$"))
|
||||
|
@ -2101,7 +2095,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
}
|
||||
if (child->type == AST_PARASET) {
|
||||
IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str;
|
||||
const AstNode *value = child->children[0];
|
||||
const AstNode *value = child->children[0].get();
|
||||
if (value->type == AST_REALVALUE)
|
||||
log_file_warning(filename, location.first_line, "Replacing floating point parameter %s.%s = %f with string.\n",
|
||||
log_id(cell), log_id(paraname), value->realvalue);
|
||||
|
@ -2114,7 +2108,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
if (child->type == AST_ARGUMENT) {
|
||||
RTLIL::SigSpec sig;
|
||||
if (child->children.size() > 0) {
|
||||
AstNode *arg = child->children[0];
|
||||
AstNode *arg = child->children[0].get();
|
||||
int local_width_hint = -1;
|
||||
bool local_sign_hint = false;
|
||||
// don't inadvertently attempt to detect the width of interfaces
|
||||
|
@ -2186,16 +2180,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
|
||||
// use ProcessGenerator for always blocks
|
||||
case AST_ALWAYS: {
|
||||
AstNode *always = this->clone();
|
||||
ProcessGenerator generator(always);
|
||||
auto always = this->clone();
|
||||
ProcessGenerator generator(std::move(always));
|
||||
ignoreThisSignalsInInitial.append(generator.outputSignals);
|
||||
delete always;
|
||||
} break;
|
||||
|
||||
case AST_INITIAL: {
|
||||
AstNode *always = this->clone();
|
||||
ProcessGenerator generator(always, ignoreThisSignalsInInitial);
|
||||
delete always;
|
||||
auto always = this->clone();
|
||||
ProcessGenerator generator(std::move(always), ignoreThisSignalsInInitial);
|
||||
} break;
|
||||
|
||||
case AST_TECALL: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue