Skip to content

Commit 53509a9

Browse files
authored
Merge pull request #5692 from YosysHQ/emil/modtools-fix-db-port-deletion
modtools: fix database sanity
2 parents 679156d + abc7563 commit 53509a9

2 files changed

Lines changed: 77 additions & 5 deletions

File tree

kernel/modtools.h

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ YOSYS_NAMESPACE_BEGIN
2828

2929
struct ModIndex : public RTLIL::Monitor
3030
{
31+
struct PointerOrderedSigBit : public RTLIL::SigBit {
32+
PointerOrderedSigBit(SigBit s) {
33+
wire = s.wire;
34+
if (wire)
35+
offset = s.offset;
36+
else
37+
data = s.data;
38+
}
39+
inline bool operator<(const RTLIL::SigBit &other) const {
40+
if (wire == other.wire)
41+
return wire ? (offset < other.offset) : (data < other.data);
42+
if (wire != nullptr && other.wire != nullptr)
43+
return wire < other.wire; // look here
44+
return (wire != nullptr) < (other.wire != nullptr);
45+
}
46+
};
3147
struct PortInfo {
3248
RTLIL::Cell* cell;
3349
RTLIL::IdString port;
@@ -77,7 +93,7 @@ struct ModIndex : public RTLIL::Monitor
7793

7894
SigMap sigmap;
7995
RTLIL::Module *module;
80-
std::map<RTLIL::SigBit, SigBitInfo> database;
96+
std::map<PointerOrderedSigBit, SigBitInfo> database;
8197
int auto_reload_counter;
8298
bool auto_reload_module;
8399

@@ -94,8 +110,11 @@ struct ModIndex : public RTLIL::Monitor
94110
{
95111
for (int i = 0; i < GetSize(sig); i++) {
96112
RTLIL::SigBit bit = sigmap(sig[i]);
97-
if (bit.wire)
113+
if (bit.wire) {
98114
database[bit].ports.erase(PortInfo(cell, port, i));
115+
if (!database[bit].is_input && !database[bit].is_output && database[bit].ports.empty())
116+
database.erase(bit);
117+
}
99118
}
100119
}
101120

@@ -132,11 +151,11 @@ struct ModIndex : public RTLIL::Monitor
132151
}
133152
}
134153

135-
void check()
154+
bool ok()
136155
{
137156
#ifndef NDEBUG
138157
if (auto_reload_module)
139-
return;
158+
return true;
140159

141160
for (auto it : database)
142161
log_assert(it.first == sigmap(it.first));
@@ -156,11 +175,17 @@ struct ModIndex : public RTLIL::Monitor
156175
else if (!(it.second == database_bak.at(it.first)))
157176
log("ModuleIndex::check(): Different content for database[%s].\n", log_signal(it.first));
158177

159-
log_assert(database == database_bak);
178+
return false;
160179
}
180+
return true;
161181
#endif
162182
}
163183

184+
void check()
185+
{
186+
log_assert(ok());
187+
}
188+
164189
void notify_connect(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) override
165190
{
166191
log_assert(module == cell->module);

tests/unit/kernel/modindexTest.cc

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <gtest/gtest.h>
2+
3+
#include "kernel/modtools.h"
4+
#include "kernel/rtlil.h"
5+
6+
YOSYS_NAMESPACE_BEGIN
7+
8+
TEST(ModIndexSwapTest, has)
9+
{
10+
Design* d = new Design;
11+
Module* m = d->addModule("$m");
12+
Wire* o = m->addWire("$o", 2);
13+
o->port_input = true;
14+
Wire* i = m->addWire("$i", 2);
15+
i->port_input = true;
16+
m->fixup_ports();
17+
m->addNot("$not", i, o);
18+
auto mi = ModIndex(m);
19+
mi.reload_module();
20+
for (auto [sb, info] : mi.database) {
21+
EXPECT_TRUE(mi.database.find(sb) != mi.database.end());
22+
}
23+
m->swap_names(i, o);
24+
for (auto [sb, info] : mi.database) {
25+
EXPECT_TRUE(mi.database.find(sb) != mi.database.end());
26+
}
27+
}
28+
29+
TEST(ModIndexDeleteTest, has)
30+
{
31+
if (log_files.empty()) log_files.emplace_back(stdout);
32+
Design* d = new Design;
33+
Module* m = d->addModule("$m");
34+
Wire* w = m->addWire("$w");
35+
Wire* o = m->addWire("$o");
36+
o->port_output = true;
37+
m->fixup_ports();
38+
Cell* not_ = m->addNotGate("$not", w, o);
39+
auto mi = ModIndex(m);
40+
mi.reload_module();
41+
mi.dump_db();
42+
Wire* a = m->addWire("\\a");
43+
not_->setPort(ID::A, a);
44+
EXPECT_TRUE(mi.ok());
45+
}
46+
47+
YOSYS_NAMESPACE_END

0 commit comments

Comments
 (0)