From 4c48fc283bc6483302b9d90efed665d485a4698f Mon Sep 17 00:00:00 2001 From: YoYo Date: Sun, 26 May 2024 16:19:17 +0800 Subject: [PATCH] fix(#4402):missing sign while for loop iteration variable is signed --- backends/verilog/verilog_backend.cc | 7 +++++-- frontends/ast/genrtlil.cc | 2 +- frontends/ast/simplify.cc | 5 ++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 31bbc996f..048d488c1 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -414,12 +414,15 @@ void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire) #else // do not use Verilog-2k "output reg" syntax in Verilog export std::string range = ""; + std::string sign = ""; if (wire->width != 1) { if (wire->upto) range = stringf(" [%d:%d]", wire->start_offset, wire->width - 1 + wire->start_offset); else range = stringf(" [%d:%d]", wire->width - 1 + wire->start_offset, wire->start_offset); } + if (wire->is_signed) + sign = " signed "; if (wire->port_input && !wire->port_output) f << stringf("%s" "input%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); if (!wire->port_input && wire->port_output) @@ -427,14 +430,14 @@ void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire) if (wire->port_input && wire->port_output) f << stringf("%s" "inout%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); if (reg_wires.count(wire->name)) { - f << stringf("%s" "reg%s %s", indent.c_str(), range.c_str(), id(wire->name).c_str()); + f << stringf("%s" "reg%s%s %s", indent.c_str(), sign.c_str(), range.c_str(), id(wire->name).c_str()); if (wire->attributes.count(ID::init)) { f << stringf(" = "); dump_const(f, wire->attributes.at(ID::init)); } f << stringf(";\n"); } else - f << stringf("%s" "wire%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); + f << stringf("%s" "wire%s%s %s;\n", indent.c_str(), sign.c_str(), range.c_str(), id(wire->name).c_str()); #endif } diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3d47bd3c0..d3a0a27aa 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1840,8 +1840,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int width = max(width_hint, 1); width_hint = -1, sign_hint = true; children[0]->detectSignWidthWorker(width_hint, sign_hint); - children[1]->detectSignWidthWorker(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); + children[1]->detectSignWidthWorker(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec sig = binop2rtlil(this, type_name, width, left, right); return sig; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 3d8478ef1..4af575ad3 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2380,7 +2380,10 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (varbuf->type != AST_CONSTANT) input_error("Right hand side of 1st expression of %s for-loop is not constant!\n", loop_type_str); - + if (init_ast->children[0]->id2ast) + varbuf->is_signed = init_ast->children[0]->id2ast->is_signed; + else + varbuf->is_signed = init_ast->children[0]->is_signed; auto resolved = current_scope.at(init_ast->children[0]->str); if (resolved->range_valid) { int const_size = varbuf->range_left - varbuf->range_right;