3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-23 09:05:32 +00:00

Merge branch 'YosysHQ:master' into master

This commit is contained in:
hakan-demirli 2024-01-31 01:03:59 +03:00 committed by GitHub
commit 8c731658c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
40 changed files with 868 additions and 559 deletions

View file

@ -110,9 +110,9 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) {
} else if (fmt[i] == 'c') {
part.type = FmtPart::CHARACTER;
} else if (fmt[i] == 't') {
part.type = FmtPart::TIME;
part.type = FmtPart::VLOG_TIME;
} else if (fmt[i] == 'r') {
part.type = FmtPart::TIME;
part.type = FmtPart::VLOG_TIME;
part.realtime = true;
} else {
log_assert(false && "Unexpected character in format substitution");
@ -172,7 +172,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const {
}
break;
case FmtPart::TIME:
case FmtPart::VLOG_TIME:
log_assert(part.sig.size() == 0);
YS_FALLTHROUGH
case FmtPart::CHARACTER:
@ -205,7 +205,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const {
fmt += part.signed_ ? 's' : 'u';
} else if (part.type == FmtPart::CHARACTER) {
fmt += 'c';
} else if (part.type == FmtPart::TIME) {
} else if (part.type == FmtPart::VLOG_TIME) {
if (part.realtime)
fmt += 'r';
else
@ -328,7 +328,7 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
case VerilogFmtArg::TIME: {
FmtPart part = {};
part.type = FmtPart::TIME;
part.type = FmtPart::VLOG_TIME;
part.realtime = arg->realtime;
part.padding = ' ';
part.width = 20;
@ -419,7 +419,7 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
part.padding = ' ';
} else if (fmt[i] == 't' || fmt[i] == 'T') {
if (arg->type == VerilogFmtArg::TIME) {
part.type = FmtPart::TIME;
part.type = FmtPart::VLOG_TIME;
part.realtime = arg->realtime;
if (!has_width && !has_leading_zero)
part.width = 20;
@ -541,7 +541,7 @@ std::vector<VerilogFmtArg> Fmt::emit_verilog() const
break;
}
case FmtPart::TIME: {
case FmtPart::VLOG_TIME: {
VerilogFmtArg arg;
arg.type = VerilogFmtArg::TIME;
if (part.realtime)
@ -569,82 +569,60 @@ std::vector<VerilogFmtArg> Fmt::emit_verilog() const
return args;
}
void Fmt::emit_cxxrtl(std::ostream &f, std::function<void(const RTLIL::SigSpec &)> emit_sig) const
std::string escape_cxx_string(const std::string &input)
{
for (auto &part : parts) {
switch (part.type) {
case FmtPart::STRING:
f << " << \"";
for (char c : part.str) {
switch (c) {
case '\\':
YS_FALLTHROUGH
case '"':
f << '\\' << c;
break;
case '\a':
f << "\\a";
break;
case '\b':
f << "\\b";
break;
case '\f':
f << "\\f";
break;
case '\n':
f << "\\n";
break;
case '\r':
f << "\\r";
break;
case '\t':
f << "\\t";
break;
case '\v':
f << "\\v";
break;
default:
f << c;
break;
}
}
f << '"';
break;
case FmtPart::INTEGER:
case FmtPart::CHARACTER: {
f << " << value_formatted<" << part.sig.size() << ">(";
emit_sig(part.sig);
f << ", " << (part.type == FmtPart::CHARACTER);
f << ", " << (part.justify == FmtPart::LEFT);
f << ", (char)" << (int)part.padding;
f << ", " << part.width;
f << ", " << part.base;
f << ", " << part.signed_;
f << ", " << part.plus;
f << ')';
break;
}
case FmtPart::TIME: {
// CXXRTL only records steps taken, so there's no difference between
// the values taken by $time and $realtime.
f << " << value_formatted<64>(";
f << "value<64>{steps}";
f << ", " << (part.type == FmtPart::CHARACTER);
f << ", " << (part.justify == FmtPart::LEFT);
f << ", (char)" << (int)part.padding;
f << ", " << part.width;
f << ", " << part.base;
f << ", " << part.signed_;
f << ", " << part.plus;
f << ')';
break;
}
default: log_abort();
std::string output = "\"";
for (auto c : input) {
if (::isprint(c)) {
if (c == '\\')
output.push_back('\\');
output.push_back(c);
} else {
char l = c & 0xf, h = (c >> 4) & 0xf;
output.append("\\x");
output.push_back((h < 10 ? '0' + h : 'a' + h - 10));
output.push_back((l < 10 ? '0' + l : 'a' + l - 10));
}
}
output.push_back('"');
if (output.find('\0') != std::string::npos) {
output.insert(0, "std::string {");
output.append(stringf(", %zu}", input.size()));
}
return output;
}
void Fmt::emit_cxxrtl(std::ostream &os, std::string indent, std::function<void(const RTLIL::SigSpec &)> emit_sig, const std::string &context) const
{
os << indent << "std::string buf;\n";
for (auto &part : parts) {
os << indent << "buf += fmt_part { ";
os << "fmt_part::";
switch (part.type) {
case FmtPart::STRING: os << "STRING"; break;
case FmtPart::INTEGER: os << "INTEGER"; break;
case FmtPart::CHARACTER: os << "CHARACTER"; break;
case FmtPart::VLOG_TIME: os << "VLOG_TIME"; break;
}
os << ", ";
os << escape_cxx_string(part.str) << ", ";
os << "fmt_part::";
switch (part.justify) {
case FmtPart::LEFT: os << "LEFT"; break;
case FmtPart::RIGHT: os << "RIGHT"; break;
}
os << ", ";
os << "(char)" << (int)part.padding << ", ";
os << part.width << ", ";
os << part.base << ", ";
os << part.signed_ << ", ";
os << part.plus << ", ";
os << part.realtime;
os << " }.render(";
emit_sig(part.sig);
os << ", " << context << ");\n";
}
os << indent << "return buf;\n";
}
std::string Fmt::render() const
@ -658,8 +636,8 @@ std::string Fmt::render() const
break;
case FmtPart::INTEGER:
case FmtPart::TIME:
case FmtPart::CHARACTER: {
case FmtPart::CHARACTER:
case FmtPart::VLOG_TIME: {
std::string buf;
if (part.type == FmtPart::INTEGER) {
RTLIL::Const value = part.sig.as_const();
@ -742,7 +720,7 @@ std::string Fmt::render() const
} else log_abort();
} else if (part.type == FmtPart::CHARACTER) {
buf = part.sig.as_const().decode_string();
} else if (part.type == FmtPart::TIME) {
} else if (part.type == FmtPart::VLOG_TIME) {
// We only render() during initial, so time is always zero.
buf = "0";
}

View file

@ -50,12 +50,13 @@ struct VerilogFmtArg {
// RTLIL format part, such as the substitutions in:
// "foo {4:> 4du} bar {2:<01hs}"
// Must be kept in sync with `struct fmt_part` in backends/cxxrtl/runtime/cxxrtl/cxxrtl.h!
struct FmtPart {
enum {
STRING = 0,
INTEGER = 1,
CHARACTER = 2,
TIME = 3,
VLOG_TIME = 3,
} type;
// STRING type
@ -64,20 +65,20 @@ struct FmtPart {
// INTEGER/CHARACTER types
RTLIL::SigSpec sig;
// INTEGER/CHARACTER/TIME types
// INTEGER/CHARACTER/VLOG_TIME types
enum {
RIGHT = 0,
LEFT = 1,
} justify = RIGHT;
char padding = '\0';
size_t width = 0;
// INTEGER type
unsigned base = 10;
bool signed_ = false;
bool plus = false;
// TIME type
// VLOG_TIME type
bool realtime = false;
};
@ -93,7 +94,7 @@ public:
void parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_like, int default_base, RTLIL::IdString task_name, RTLIL::IdString module_name);
std::vector<VerilogFmtArg> emit_verilog() const;
void emit_cxxrtl(std::ostream &f, std::function<void(const RTLIL::SigSpec &)> emit_sig) const;
void emit_cxxrtl(std::ostream &os, std::string indent, std::function<void(const RTLIL::SigSpec &)> emit_sig, const std::string &context) const;
std::string render() const;

View file

@ -2157,17 +2157,10 @@ void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
}
void operator()(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) {
log_assert(GetSize(lhs) == GetSize(rhs));
lhs.unpack();
rhs.unpack();
for (int i = 0; i < GetSize(lhs); i++) {
RTLIL::SigBit &lhs_bit = lhs.bits_[i];
RTLIL::SigBit &rhs_bit = rhs.bits_[i];
if ((lhs_bit.wire != nullptr && wires_p->count(lhs_bit.wire)) || (rhs_bit.wire != nullptr && wires_p->count(rhs_bit.wire))) {
lhs_bit = State::Sx;
rhs_bit = State::Sx;
}
}
// If a deleted wire occurs on the lhs or rhs we just remove that part
// of the assignment
lhs.remove2(*wires_p, &rhs);
rhs.remove2(*wires_p, &lhs);
}
};
@ -3693,6 +3686,9 @@ RTLIL::SigChunk::SigChunk(const RTLIL::SigBit &bit)
RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
{
log_assert(offset >= 0);
log_assert(length >= 0);
log_assert(offset + length <= width);
RTLIL::SigChunk ret;
if (wire) {
ret.wire = wire;
@ -4238,6 +4234,34 @@ void RTLIL::SigSpec::remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigS
check();
}
void RTLIL::SigSpec::remove2(const pool<RTLIL::Wire*> &pattern, RTLIL::SigSpec *other)
{
if (other)
cover("kernel.rtlil.sigspec.remove_other");
else
cover("kernel.rtlil.sigspec.remove");
unpack();
if (other != NULL) {
log_assert(width_ == other->width_);
other->unpack();
}
for (int i = GetSize(bits_) - 1; i >= 0; i--) {
if (bits_[i].wire != NULL && pattern.count(bits_[i].wire)) {
bits_.erase(bits_.begin() + i);
width_--;
if (other != NULL) {
other->bits_.erase(other->bits_.begin() + i);
other->width_--;
}
}
}
check();
}
RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const
{
if (other)
@ -4377,6 +4401,9 @@ void RTLIL::SigSpec::remove(int offset, int length)
RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
{
log_assert(offset >= 0);
log_assert(length >= 0);
log_assert(offset + length <= width_);
unpack();
cover("kernel.rtlil.sigspec.extract_pos");
return std::vector<RTLIL::SigBit>(bits_.begin() + offset, bits_.begin() + offset + length);

View file

@ -924,6 +924,7 @@ public:
void remove(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const;
void remove2(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other);
void remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other);
void remove2(const pool<RTLIL::Wire*> &pattern, RTLIL::SigSpec *other);
void remove(int offset, int length = 1);
void remove_const();