mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-07 01:54:10 +00:00
fmt,cxxrtl: support {,PLUS_,SPACE_}MINUS
integer formats.
The first two were already supported with the `plus` boolean flag. The third one is a new specifier, which is allocated the ` ` character. In addition, `MINUS` is now allocated the `-` character, but old format where there is no `+`, `-`, or `-` in the respective position is also accepted for compatibility.
This commit is contained in:
parent
8388846e3a
commit
6d6b138607
|
@ -1033,7 +1033,11 @@ struct fmt_part {
|
||||||
// INTEGER type
|
// INTEGER type
|
||||||
unsigned base; // = 10;
|
unsigned base; // = 10;
|
||||||
bool signed_; // = false;
|
bool signed_; // = false;
|
||||||
bool plus; // = false;
|
enum {
|
||||||
|
MINUS = 0,
|
||||||
|
PLUS_MINUS = 1,
|
||||||
|
SPACE_MINUS = 2,
|
||||||
|
} sign; // = MINUS;
|
||||||
bool hex_upper; // = false;
|
bool hex_upper; // = false;
|
||||||
|
|
||||||
// VLOG_TIME type
|
// VLOG_TIME type
|
||||||
|
@ -1105,8 +1109,11 @@ struct fmt_part {
|
||||||
buf += '0' + remainder.template trunc<4>().template get<uint8_t>();
|
buf += '0' + remainder.template trunc<4>().template get<uint8_t>();
|
||||||
xval = quotient;
|
xval = quotient;
|
||||||
}
|
}
|
||||||
if (negative || plus)
|
switch (sign) {
|
||||||
buf += negative ? '-' : '+';
|
case MINUS: buf += negative ? "-" : ""; break;
|
||||||
|
case PLUS_MINUS: buf += negative ? "-" : "+"; break;
|
||||||
|
case SPACE_MINUS: buf += negative ? "-" : " "; break;
|
||||||
|
}
|
||||||
std::reverse(buf.begin(), buf.end());
|
std::reverse(buf.begin(), buf.end());
|
||||||
} else assert(false && "Unsupported base for fmt_part");
|
} else assert(false && "Unsupported base for fmt_part");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -128,10 +128,20 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) {
|
||||||
log_assert(false && "Unexpected end in format substitution");
|
log_assert(false && "Unexpected end in format substitution");
|
||||||
|
|
||||||
if (part.type == FmtPart::INTEGER) {
|
if (part.type == FmtPart::INTEGER) {
|
||||||
if (fmt[i] == '+') {
|
if (fmt[i] == '-') {
|
||||||
part.plus = true;
|
part.sign = FmtPart::MINUS;
|
||||||
if (++i == fmt.size())
|
if (++i == fmt.size())
|
||||||
log_assert(false && "Unexpected end in format substitution");
|
log_assert(false && "Unexpected end in format substitution");
|
||||||
|
} else if (fmt[i] == '+') {
|
||||||
|
part.sign = FmtPart::PLUS_MINUS;
|
||||||
|
if (++i == fmt.size())
|
||||||
|
log_assert(false && "Unexpected end in format substitution");
|
||||||
|
} else if (fmt[i] == ' ') {
|
||||||
|
part.sign = FmtPart::SPACE_MINUS;
|
||||||
|
if (++i == fmt.size())
|
||||||
|
log_assert(false && "Unexpected end in format substitution");
|
||||||
|
} else {
|
||||||
|
// also accept no sign character and treat like MINUS for compatibility
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fmt[i] == 'u')
|
if (fmt[i] == 'u')
|
||||||
|
@ -204,8 +214,11 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const {
|
||||||
case 16: fmt += part.hex_upper ? 'H' : 'h'; break;
|
case 16: fmt += part.hex_upper ? 'H' : 'h'; break;
|
||||||
default: log_abort();
|
default: log_abort();
|
||||||
}
|
}
|
||||||
if (part.plus)
|
switch (part.sign) {
|
||||||
fmt += '+';
|
case FmtPart::MINUS: fmt += '-'; break;
|
||||||
|
case FmtPart::PLUS_MINUS: fmt += '+'; break;
|
||||||
|
case FmtPart::SPACE_MINUS: fmt += ' '; break;
|
||||||
|
}
|
||||||
fmt += part.signed_ ? 's' : 'u';
|
fmt += part.signed_ ? 's' : 'u';
|
||||||
} else if (part.type == FmtPart::STRING) {
|
} else if (part.type == FmtPart::STRING) {
|
||||||
fmt += 'c';
|
fmt += 'c';
|
||||||
|
@ -379,7 +392,7 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
|
||||||
part.justify = FmtPart::LEFT;
|
part.justify = FmtPart::LEFT;
|
||||||
} else if (fmt[i] == '+') {
|
} else if (fmt[i] == '+') {
|
||||||
// always show sign; not in IEEE 1800-2017 or verilator but iverilog has it
|
// always show sign; not in IEEE 1800-2017 or verilator but iverilog has it
|
||||||
part.plus = true;
|
part.sign = FmtPart::PLUS_MINUS;
|
||||||
} else break;
|
} else break;
|
||||||
}
|
}
|
||||||
if (i == fmt.size()) {
|
if (i == fmt.size()) {
|
||||||
|
@ -442,7 +455,7 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
|
||||||
if (part.padding == '\0')
|
if (part.padding == '\0')
|
||||||
part.padding = (has_leading_zero && part.justify == FmtPart::RIGHT) ? '0' : ' ';
|
part.padding = (has_leading_zero && part.justify == FmtPart::RIGHT) ? '0' : ' ';
|
||||||
|
|
||||||
if (part.type == FmtPart::INTEGER && part.base != 10 && part.plus)
|
if (part.type == FmtPart::INTEGER && part.base != 10 && part.sign != FmtPart::MINUS)
|
||||||
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1);
|
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1);
|
||||||
|
|
||||||
if (part.type == FmtPart::INTEGER && !has_leading_zero)
|
if (part.type == FmtPart::INTEGER && !has_leading_zero)
|
||||||
|
@ -495,8 +508,8 @@ std::vector<VerilogFmtArg> Fmt::emit_verilog() const
|
||||||
args.push_back(arg);
|
args.push_back(arg);
|
||||||
|
|
||||||
fmt.str += '%';
|
fmt.str += '%';
|
||||||
if (part.plus)
|
if (part.sign == FmtPart::PLUS_MINUS || part.sign == FmtPart::SPACE_MINUS)
|
||||||
fmt.str += '+';
|
fmt.str += '+'; // treat space/minus as plus/minus
|
||||||
if (part.justify == FmtPart::LEFT)
|
if (part.justify == FmtPart::LEFT)
|
||||||
fmt.str += '-';
|
fmt.str += '-';
|
||||||
if (part.width == 0) {
|
if (part.width == 0) {
|
||||||
|
@ -553,7 +566,8 @@ std::vector<VerilogFmtArg> Fmt::emit_verilog() const
|
||||||
args.push_back(arg);
|
args.push_back(arg);
|
||||||
|
|
||||||
fmt.str += '%';
|
fmt.str += '%';
|
||||||
if (part.plus)
|
log_assert(part.sign == FmtPart::MINUS || part.sign == FmtPart::PLUS_MINUS);
|
||||||
|
if (part.sign == FmtPart::PLUS_MINUS)
|
||||||
fmt.str += '+';
|
fmt.str += '+';
|
||||||
if (part.justify == FmtPart::LEFT)
|
if (part.justify == FmtPart::LEFT)
|
||||||
fmt.str += '-';
|
fmt.str += '-';
|
||||||
|
@ -620,7 +634,13 @@ void Fmt::emit_cxxrtl(std::ostream &os, std::string indent, std::function<void(c
|
||||||
os << part.width << ", ";
|
os << part.width << ", ";
|
||||||
os << part.base << ", ";
|
os << part.base << ", ";
|
||||||
os << part.signed_ << ", ";
|
os << part.signed_ << ", ";
|
||||||
os << part.plus << ", ";
|
os << "fmt_part::";
|
||||||
|
switch (part.sign) {
|
||||||
|
case FmtPart::MINUS: os << "MINUS"; break;
|
||||||
|
case FmtPart::PLUS_MINUS: os << "PLUS_MINUS"; break;
|
||||||
|
case FmtPart::SPACE_MINUS: os << "SPACE_MINUS"; break;
|
||||||
|
}
|
||||||
|
os << ", ";
|
||||||
os << part.hex_upper << ", ";
|
os << part.hex_upper << ", ";
|
||||||
os << part.realtime;
|
os << part.realtime;
|
||||||
os << " }.render(";
|
os << " }.render(";
|
||||||
|
@ -718,8 +738,11 @@ std::string Fmt::render() const
|
||||||
buf += '0' + RTLIL::const_mod(absvalue, 10, false, false, 4).as_int();
|
buf += '0' + RTLIL::const_mod(absvalue, 10, false, false, 4).as_int();
|
||||||
absvalue = RTLIL::const_div(absvalue, 10, false, false, absvalue.size());
|
absvalue = RTLIL::const_div(absvalue, 10, false, false, absvalue.size());
|
||||||
}
|
}
|
||||||
if (negative || part.plus)
|
switch (part.sign) {
|
||||||
buf += negative ? '-' : '+';
|
case FmtPart::MINUS: buf += negative ? "-" : ""; break;
|
||||||
|
case FmtPart::PLUS_MINUS: buf += negative ? "-" : "+"; break;
|
||||||
|
case FmtPart::SPACE_MINUS: buf += negative ? "-" : " "; break;
|
||||||
|
}
|
||||||
std::reverse(buf.begin(), buf.end());
|
std::reverse(buf.begin(), buf.end());
|
||||||
}
|
}
|
||||||
} else log_abort();
|
} else log_abort();
|
||||||
|
|
|
@ -76,7 +76,11 @@ struct FmtPart {
|
||||||
// INTEGER type
|
// INTEGER type
|
||||||
unsigned base = 10;
|
unsigned base = 10;
|
||||||
bool signed_ = false;
|
bool signed_ = false;
|
||||||
bool plus = false;
|
enum {
|
||||||
|
MINUS = 0,
|
||||||
|
PLUS_MINUS = 1,
|
||||||
|
SPACE_MINUS = 2,
|
||||||
|
} sign = MINUS;
|
||||||
bool hex_upper = false;
|
bool hex_upper = false;
|
||||||
|
|
||||||
// VLOG_TIME type
|
// VLOG_TIME type
|
||||||
|
|
Loading…
Reference in a new issue