From 91e3773b51b905a00876b66e965fcd36a8cad79e Mon Sep 17 00:00:00 2001 From: Roland Coeurjoly Date: Mon, 19 Aug 2024 16:56:08 +0200 Subject: [PATCH] Ensure signed constants are correctly parsed, represented, and exported in RTLIL. Add a test to check parsing and exporting --- backends/rtlil/rtlil_backend.cc | 3 +++ frontends/rtlil/rtlil_lexer.l | 2 +- frontends/rtlil/rtlil_parser.y | 16 +++++++++++++++- tests/various/rtlil_signed_attribute.ys | 10 ++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 tests/various/rtlil_signed_attribute.ys diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index 574eb3aaa..032954d8c 100644 --- a/backends/rtlil/rtlil_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -51,6 +51,9 @@ void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi } } f << stringf("%d'", width); + if (data.flags & RTLIL::CONST_FLAG_SIGNED) { + f << stringf("s"); + } if (data.is_fully_undef_x_only()) { f << "x"; } else { diff --git a/frontends/rtlil/rtlil_lexer.l b/frontends/rtlil/rtlil_lexer.l index e16413216..c374dd395 100644 --- a/frontends/rtlil/rtlil_lexer.l +++ b/frontends/rtlil/rtlil_lexer.l @@ -88,7 +88,7 @@ USING_YOSYS_NAMESPACE "\\"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; } "$"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; } -[0-9]+'[01xzm-]* { rtlil_frontend_yylval.string = strdup(yytext); return TOK_VALUE; } +[0-9]+'s?[01xzm-]* { rtlil_frontend_yylval.string = strdup(yytext); return TOK_VALUE; } -?[0-9]+ { char *end = nullptr; errno = 0; diff --git a/frontends/rtlil/rtlil_parser.y b/frontends/rtlil/rtlil_parser.y index 7d99b2c42..874e6fdd0 100644 --- a/frontends/rtlil/rtlil_parser.y +++ b/frontends/rtlil/rtlil_parser.y @@ -412,8 +412,16 @@ constant: TOK_VALUE { char *ep; int width = strtol($1, &ep, 10); + bool is_signed = false; + if (*ep == '\'') { + ep++; + } + if (*ep == 's') { + is_signed = true; + ep++; + } std::list bits; - while (*(++ep) != 0) { + while (*ep != 0) { RTLIL::State bit = RTLIL::Sx; switch (*ep) { case '0': bit = RTLIL::S0; break; @@ -424,7 +432,9 @@ constant: case 'm': bit = RTLIL::Sm; break; } bits.push_front(bit); + ep++; } + if (bits.size() == 0) bits.push_back(RTLIL::Sx); while ((int)bits.size() < width) { @@ -438,6 +448,10 @@ constant: $$ = new RTLIL::Const; for (auto it = bits.begin(); it != bits.end(); it++) $$->bits.push_back(*it); + if (is_signed) { + $$->flags |= RTLIL::CONST_FLAG_SIGNED; + log("Setting SIGNED flag for constant with width %d\n", width); + } free($1); } | TOK_INT { diff --git a/tests/various/rtlil_signed_attribute.ys b/tests/various/rtlil_signed_attribute.ys new file mode 100644 index 000000000..900fe589f --- /dev/null +++ b/tests/various/rtlil_signed_attribute.ys @@ -0,0 +1,10 @@ +! mkdir -p temp +read_rtlil <