mirror of https://github.com/YosysHQ/yosys.git
Ensure signed constants are correctly parsed, represented, and exported in RTLIL. Add a test to check parsing and exporting
This commit is contained in:
parent
4cddc19994
commit
91e3773b51
|
@ -51,6 +51,9 @@ void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f << stringf("%d'", width);
|
f << stringf("%d'", width);
|
||||||
|
if (data.flags & RTLIL::CONST_FLAG_SIGNED) {
|
||||||
|
f << stringf("s");
|
||||||
|
}
|
||||||
if (data.is_fully_undef_x_only()) {
|
if (data.is_fully_undef_x_only()) {
|
||||||
f << "x";
|
f << "x";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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; }
|
||||||
"$"[^ \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]+ {
|
-?[0-9]+ {
|
||||||
char *end = nullptr;
|
char *end = nullptr;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
|
@ -412,8 +412,16 @@ constant:
|
||||||
TOK_VALUE {
|
TOK_VALUE {
|
||||||
char *ep;
|
char *ep;
|
||||||
int width = strtol($1, &ep, 10);
|
int width = strtol($1, &ep, 10);
|
||||||
|
bool is_signed = false;
|
||||||
|
if (*ep == '\'') {
|
||||||
|
ep++;
|
||||||
|
}
|
||||||
|
if (*ep == 's') {
|
||||||
|
is_signed = true;
|
||||||
|
ep++;
|
||||||
|
}
|
||||||
std::list<RTLIL::State> bits;
|
std::list<RTLIL::State> bits;
|
||||||
while (*(++ep) != 0) {
|
while (*ep != 0) {
|
||||||
RTLIL::State bit = RTLIL::Sx;
|
RTLIL::State bit = RTLIL::Sx;
|
||||||
switch (*ep) {
|
switch (*ep) {
|
||||||
case '0': bit = RTLIL::S0; break;
|
case '0': bit = RTLIL::S0; break;
|
||||||
|
@ -424,7 +432,9 @@ constant:
|
||||||
case 'm': bit = RTLIL::Sm; break;
|
case 'm': bit = RTLIL::Sm; break;
|
||||||
}
|
}
|
||||||
bits.push_front(bit);
|
bits.push_front(bit);
|
||||||
|
ep++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bits.size() == 0)
|
if (bits.size() == 0)
|
||||||
bits.push_back(RTLIL::Sx);
|
bits.push_back(RTLIL::Sx);
|
||||||
while ((int)bits.size() < width) {
|
while ((int)bits.size() < width) {
|
||||||
|
@ -438,6 +448,10 @@ constant:
|
||||||
$$ = new RTLIL::Const;
|
$$ = new RTLIL::Const;
|
||||||
for (auto it = bits.begin(); it != bits.end(); it++)
|
for (auto it = bits.begin(); it != bits.end(); it++)
|
||||||
$$->bits.push_back(*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);
|
free($1);
|
||||||
} |
|
} |
|
||||||
TOK_INT {
|
TOK_INT {
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
! mkdir -p temp
|
||||||
|
read_rtlil <<EOT
|
||||||
|
module \test
|
||||||
|
attribute \bottom_bound 3's101
|
||||||
|
wire width 3 output 1 \a
|
||||||
|
connect \a 3'001
|
||||||
|
end
|
||||||
|
EOT
|
||||||
|
write_rtlil temp/rtlil_signed_attribute.il
|
||||||
|
! grep -F -q "attribute \bottom_bound 3's101" temp/rtlil_signed_attribute.il
|
Loading…
Reference in New Issue