Skip to content

Commit eff70d9

Browse files
committed
add a proxy function for sign and width detection
1 parent 6950d8f commit eff70d9

File tree

1 file changed

+36
-27
lines changed

1 file changed

+36
-27
lines changed

systemverilog-plugin/third_party/yosys/simplify.cc

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ namespace systemverilog_plugin
5151
using namespace ::Yosys;
5252
using namespace ::Yosys::AST_INTERNAL;
5353

54+
55+
void detect_sign_width_proxy(Yosys::AST::AstNode * node, int& width, bool& sign, bool *found_real = NULL) {
56+
if (node->type == Yosys::AST::AST_IDENTIFIER && node->id2ast && node->id2ast->type == Yosys::AST::AST_TYPEDEF) {
57+
node->id2ast->dumpAst(nullptr, "---------");
58+
node->id2ast = node->id2ast->children[0];
59+
}
60+
node->detectSignWidth(width, sign, found_real);
61+
}
62+
5463
void annotateTypedEnums(Yosys::AST::AstNode *ast_node, Yosys::AST::AstNode *template_node)
5564
{
5665
//check if enum
@@ -1036,8 +1045,8 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
10361045
did_something = true;
10371046
while (!ast_node->children[1]->basic_prep && simplify(ast_node->children[1], false, false, false, stage, -1, false, in_param) == true)
10381047
did_something = true;
1039-
ast_node->children[0]->detectSignWidth(backup_width_hint, backup_sign_hint);
1040-
ast_node->children[1]->detectSignWidth(width_hint, sign_hint);
1048+
detect_sign_width_proxy(ast_node->children[0], backup_width_hint, backup_sign_hint);
1049+
detect_sign_width_proxy(ast_node->children[1], width_hint, sign_hint);
10411050
width_hint = max(width_hint, backup_width_hint);
10421051
child_0_is_self_determined = true;
10431052
// test only once, before optimizations and memory mappings but after assignment LHS was mapped to an identifier
@@ -1117,7 +1126,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
11171126
}
11181127
while (!ast_node->children[0]->basic_prep && simplify(ast_node->children[0], false, false, false, stage, -1, false, true) == true)
11191128
did_something = true;
1120-
ast_node->children[0]->detectSignWidth(width_hint, sign_hint);
1129+
detect_sign_width_proxy(ast_node->children[0], width_hint, sign_hint);
11211130
if (ast_node->children.size() > 1 && ast_node->children[1]->type == Yosys::AST::AST_RANGE) {
11221131
while (!ast_node->children[1]->basic_prep && simplify(ast_node->children[1], false, false, false, stage, -1, false, true) == true)
11231132
did_something = true;
@@ -1129,7 +1138,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
11291138
case Yosys::AST::AST_ENUM_ITEM:
11301139
while (!ast_node->children[0]->basic_prep && simplify(ast_node->children[0], false, false, false, stage, -1, false, in_param))
11311140
did_something = true;
1132-
ast_node->children[0]->detectSignWidth(width_hint, sign_hint);
1141+
detect_sign_width_proxy(ast_node->children[0], width_hint, sign_hint);
11331142
if (ast_node->children.size() > 1 && ast_node->children[1]->type == Yosys::AST::AST_RANGE) {
11341143
while (!ast_node->children[1]->basic_prep && simplify(ast_node->children[1], false, false, false, stage, -1, false, in_param))
11351144
did_something = true;
@@ -1230,11 +1239,11 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
12301239
for (auto child : ast_node->children)
12311240
while (!child->basic_prep && simplify(child, false, false, in_lvalue, stage, -1, false, in_param) == true)
12321241
did_something = true;
1233-
ast_node->detectSignWidth(width_hint, sign_hint);
1242+
detect_sign_width_proxy(ast_node, width_hint, sign_hint);
12341243
}
12351244

12361245
if (ast_node->type == Yosys::AST::AST_FCALL && ast_node->str == "\\$past")
1237-
ast_node->detectSignWidth(width_hint, sign_hint);
1246+
detect_sign_width_proxy(ast_node, width_hint, sign_hint);
12381247

12391248
if (ast_node->type == Yosys::AST::AST_TERNARY) {
12401249
if (width_hint < 0) {
@@ -1253,13 +1262,13 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
12531262
did_something = true;
12541263

12551264
unevaluated_tern_branch = backup_unevaluated_tern_branch;
1256-
ast_node->detectSignWidth(width_hint, sign_hint);
1265+
detect_sign_width_proxy(ast_node, width_hint, sign_hint);
12571266
}
12581267
int width_hint_left, width_hint_right;
12591268
bool sign_hint_left, sign_hint_right;
12601269
bool found_real_left, found_real_right;
1261-
ast_node->children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left);
1262-
ast_node->children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right);
1270+
detect_sign_width_proxy(ast_node->children[1], width_hint_left, sign_hint_left, &found_real_left);
1271+
detect_sign_width_proxy(ast_node->children[2], width_hint_right, sign_hint_right, &found_real_right);
12631272
if (found_real_left || found_real_right) {
12641273
child_1_is_self_determined = true;
12651274
child_2_is_self_determined = true;
@@ -1280,7 +1289,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
12801289

12811290
if (const_fold && ast_node->type == Yosys::AST::AST_CASE)
12821291
{
1283-
ast_node->detectSignWidth(width_hint, sign_hint);
1292+
detect_sign_width_proxy(ast_node, width_hint, sign_hint);
12841293
while (simplify(ast_node->children[0], const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
12851294
if (ast_node->children[0]->type == Yosys::AST::AST_CONSTANT && ast_node->children[0]->bits_only_01()) {
12861295
ast_node->children[0]->is_signed = sign_hint;
@@ -1415,7 +1424,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
14151424
width_hint = backup_width_hint;
14161425
sign_hint = backup_sign_hint;
14171426
if (width_hint < 0)
1418-
ast_node->detectSignWidth(width_hint, sign_hint);
1427+
detect_sign_width_proxy(ast_node, width_hint, sign_hint);
14191428
}
14201429

14211430
current_block = backup_current_block;
@@ -1994,7 +2003,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
19942003
{
19952004
int expr_width_hint = -1;
19962005
bool expr_sign_hint = true;
1997-
varbuf->detectSignWidth(expr_width_hint, expr_sign_hint);
2006+
detect_sign_width_proxy(varbuf, expr_width_hint, expr_sign_hint);
19982007
while (simplify(varbuf, true, false, false, stage, 32, true, false)) { }
19992008
}
20002009

@@ -2035,7 +2044,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
20352044
{
20362045
int expr_width_hint = -1;
20372046
bool expr_sign_hint = true;
2038-
buf->detectSignWidth(expr_width_hint, expr_sign_hint);
2047+
detect_sign_width_proxy(buf, expr_width_hint, expr_sign_hint);
20392048
while (simplify(buf, true, false, false, stage, expr_width_hint, expr_sign_hint, false)) { }
20402049
}
20412050

@@ -2086,7 +2095,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
20862095
{
20872096
int expr_width_hint = -1;
20882097
bool expr_sign_hint = true;
2089-
buf->detectSignWidth(expr_width_hint, expr_sign_hint);
2098+
detect_sign_width_proxy(buf, expr_width_hint, expr_sign_hint);
20902099
while (simplify(buf, true, false, false, stage, expr_width_hint, expr_sign_hint, true)) { }
20912100
}
20922101

@@ -2500,7 +2509,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
25002509

25012510
int shamt_width_hint = -1;
25022511
bool shamt_sign_hint = true;
2503-
shift_expr->detectSignWidth(shamt_width_hint, shamt_sign_hint);
2512+
detect_sign_width_proxy(shift_expr, shamt_width_hint, shamt_sign_hint);
25042513

25052514
Yosys::AST::AstNode *wire_sel = new Yosys::AST::AstNode(Yosys::AST::AST_WIRE, new Yosys::AST::AstNode(Yosys::AST::AST_RANGE, ast_node->mkconst_int(shamt_width_hint-1, true), ast_node->mkconst_int(0, true)));
25062515
wire_sel->str = stringf("$bitselwrite$sel$%s:%d$%d", encode_filename(ast_node->filename).c_str(), ast_node->location.first_line, autoidx++);
@@ -2709,7 +2718,7 @@ skip_dynamic_range_lvalue_expansion:;
27092718
{
27102719
int child_width_hint = -1;
27112720
bool child_sign_hint = true;
2712-
child->detectSignWidth(child_width_hint, child_sign_hint);
2721+
detect_sign_width_proxy(child, child_width_hint, child_sign_hint);
27132722

27142723
Yosys::AST::AstNode *rhs = wire_tmp_id->clone();
27152724
rhs->children.push_back(new Yosys::AST::AstNode(Yosys::AST::AST_RANGE, ast_node->mkconst_int(cursor+child_width_hint-1, true), ast_node->mkconst_int(cursor, true)));
@@ -3128,12 +3137,12 @@ skip_dynamic_range_lvalue_expansion:;
31283137
// Is this needed?
31293138
//while (simplify(buf, true, false, false, stage, width_hint, sign_hint, false)) { }
31303139

3131-
if (buf->type == Yosys::AST::AST_IDENTIFIER && buf->id2ast && buf->id2ast->type == Yosys::AST::AST_TYPEDEF) {
3132-
// If the identifier points to a typedef, use the type that is stored inside the typedef (children[0]).
3133-
log_assert(buf->id2ast->children.size());
3134-
buf->id2ast = buf->id2ast->children[0];
3135-
}
3136-
buf->detectSignWidth(width_hint, sign_hint);
3140+
//if (buf->type == Yosys::AST::AST_IDENTIFIER && buf->id2ast && buf->id2ast->type == Yosys::AST::AST_TYPEDEF) {
3141+
// // If the identifier points to a typedef, use the type that is stored inside the typedef (children[0]).
3142+
// log_assert(buf->id2ast->children.size());
3143+
// buf->id2ast = buf->id2ast->children[0];
3144+
//}
3145+
detect_sign_width_proxy(buf, width_hint, sign_hint);
31373146

31383147
if (buf->type == Yosys::AST::AST_IDENTIFIER) {
31393148
id_ast = buf->id2ast;
@@ -3285,7 +3294,7 @@ skip_dynamic_range_lvalue_expansion:;
32853294
RTLIL::unescape_id(ast_node->str).c_str());
32863295
int child_width_hint = width_hint;
32873296
bool child_sign_hint = sign_hint;
3288-
ast_node->children[0]->detectSignWidth(child_width_hint, child_sign_hint);
3297+
detect_sign_width_proxy(ast_node->children[0], child_width_hint, child_sign_hint);
32893298
x = ast_node->children[0]->asReal(child_sign_hint);
32903299
}
32913300

@@ -3296,7 +3305,7 @@ skip_dynamic_range_lvalue_expansion:;
32963305
RTLIL::unescape_id(ast_node->str).c_str());
32973306
int child_width_hint = width_hint;
32983307
bool child_sign_hint = sign_hint;
3299-
ast_node->children[1]->detectSignWidth(child_width_hint, child_sign_hint);
3308+
detect_sign_width_proxy(ast_node->children[1], child_width_hint, child_sign_hint);
33003309
y = ast_node->children[1]->asReal(child_sign_hint);
33013310
}
33023311

@@ -3364,7 +3373,7 @@ skip_dynamic_range_lvalue_expansion:;
33643373
int exp_width = -1;
33653374
bool exp_sign = false;
33663375
Yosys::AST::AstNode *exp = ast_node->children[0];
3367-
exp->detectSignWidth(exp_width, exp_sign, NULL);
3376+
detect_sign_width_proxy(exp, exp_width, exp_sign, NULL);
33683377

33693378
newNode = ast_node->mkconst_int(0, false);
33703379

@@ -3997,10 +4006,10 @@ replace_fcall_later:;
39974006
if (choice->type == Yosys::AST::AST_CONSTANT) {
39984007
int other_width_hint = width_hint;
39994008
bool other_sign_hint = sign_hint, other_real = false;
4000-
not_choice->detectSignWidth(other_width_hint, other_sign_hint, &other_real);
4009+
detect_sign_width_proxy(not_choice, other_width_hint, other_sign_hint, &other_real);
40014010
if (other_real) {
40024011
newNode = new Yosys::AST::AstNode(Yosys::AST::AST_REALVALUE);
4003-
choice->detectSignWidth(width_hint, sign_hint);
4012+
detect_sign_width_proxy(choice, width_hint, sign_hint);
40044013
newNode->realvalue = choice->asReal(sign_hint);
40054014
} else {
40064015
RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint);

0 commit comments

Comments
 (0)