Add AST_SELFSZ and improve handling of bit slices
authorClaire Wolf <claire@symbioticeda.com>
Wed, 29 Apr 2020 12:28:04 +0000 (14:28 +0200)
committerClaire Wolf <claire@symbioticeda.com>
Sat, 2 May 2020 09:21:01 +0000 (11:21 +0200)
Signed-off-by: Claire Wolf <claire@symbioticeda.com>
frontends/ast/ast.cc
frontends/ast/ast.h
frontends/ast/genrtlil.cc
frontends/ast/simplify.cc
frontends/verilog/verilog_parser.y

index 8daae7dcbac04cf3f5d51d94d9da3db233a388df..689fa9fb4d936d637aa562f7924d6212101fbae0 100644 (file)
@@ -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, ")");
index 0baea7b63d4abdd1022b6da8f3343227d48a7860..8932108e3790dd2fbc4b2ffb734a060e1e517d03 100644 (file)
@@ -75,6 +75,7 @@ namespace AST
                AST_TO_BITS,
                AST_TO_SIGNED,
                AST_TO_UNSIGNED,
+               AST_SELFSZ,
                AST_CONCAT,
                AST_REPLICATE,
                AST_BIT_NOT,
index 6a39bbc049df405623d429310d050c882643516b..37cbb8a838283f48182517b875d16fa821229723 100644 (file)
@@ -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);
index af347b8f1fb7b34031cfd94832834128a014f45a..af5e142175c50546e5b667444b0dd7a29cc00bcc 100644 (file)
@@ -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:
index 4a5aba79e509d7ab078c16351c49e962fc0bd5a7..903c8e77fee08645cad0721190f7b41d55b4b6a8 100644 (file)
@@ -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));
        } |