From 589ed2d97032829568e73a5858772e39088aeeeb Mon Sep 17 00:00:00 2001 From: Claire Wolf Date: Wed, 29 Apr 2020 14:28:04 +0200 Subject: [PATCH] Add AST_SELFSZ and improve handling of bit slices Signed-off-by: Claire Wolf --- frontends/ast/ast.cc | 2 ++ frontends/ast/ast.h | 1 + frontends/ast/genrtlil.cc | 8 +++++++- frontends/ast/simplify.cc | 14 ++++++++++---- frontends/verilog/verilog_parser.y | 4 ++-- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 8daae7dcb..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) @@ -617,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, ")"); diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 0baea7b63..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, diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 6a39bbc04..37cbb8a83 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -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; @@ -1267,7 +1272,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); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index af347b8f1..af5e14217 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -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: @@ -1855,8 +1856,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, AstNode *shamt = shift_expr; + 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->is_signed; + bool use_shift = shamt_sign_hint; if (start_bit != 0) { shamt = new AstNode(AST_SUB, shamt, mkconst_int(start_bit, true)); @@ -3060,6 +3065,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) { @@ -3068,10 +3074,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: diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 4a5aba79e..903c8e77f 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -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)); } | -- 2.30.2