Skip to content

Commit d18dd28

Browse files
committed
Constrained random: emit rand constraint right away
This change gets rid of most of the shared pointers and useless memory allocations. Signed-off-by: Arkadiusz Kozdra <akozdra@antmicro.com>
1 parent f623db7 commit d18dd28

File tree

2 files changed

+16
-51
lines changed

2 files changed

+16
-51
lines changed

include/verilated_random.cpp

+14-24
Original file line numberDiff line numberDiff line change
@@ -254,17 +254,6 @@ static Process& getSolver() {
254254
// VlRandomizer:: Methods
255255

256256
void VlRandomVar::emit(std::ostream& s) const { s << m_name; }
257-
void VlRandomConst::emit(std::ostream& s) const {
258-
s << "#b";
259-
for (int i = 0; i < m_width; i++) s << (VL_BITISSET_Q(m_val, m_width - i - 1) ? '1' : '0');
260-
}
261-
void VlRandomBinOp::emit(std::ostream& s) const {
262-
s << '(' << m_op << ' ';
263-
m_lhs->emit(s);
264-
s << ' ';
265-
m_rhs->emit(s);
266-
s << ')';
267-
}
268257
void VlRandomExtract::emit(std::ostream& s) const {
269258
s << "((_ extract " << m_idx << ' ' << m_idx << ") ";
270259
m_expr->emit(s);
@@ -307,27 +296,28 @@ bool VlRandomVar::set(std::string&& val) const {
307296
return true;
308297
}
309298

310-
std::shared_ptr<const VlRandomExpr> VlRandomizer::randomConstraint(VlRNG& rngr, int bits) {
311-
unsigned long long hash = VL_RANDOM_RNG_I(rngr) & ((1 << bits) - 1);
312-
std::shared_ptr<const VlRandomExpr> concat = nullptr;
313-
std::vector<std::shared_ptr<const VlRandomExpr>> varbits;
299+
void VlRandomizer::randomConstraint(std::ostream& os, VlRNG& rngr, int bits) {
300+
IData hash = VL_RANDOM_RNG_I(rngr) & ((1 << bits) - 1);
301+
std::vector<std::unique_ptr<const VlRandomExpr>> varbits;
314302
for (const auto& var : m_vars) {
315303
for (int i = 0; i < var.second->width(); i++)
316-
varbits.emplace_back(std::make_shared<const VlRandomExtract>(var.second, i));
304+
varbits.emplace_back(std::make_unique<const VlRandomExtract>(var.second, i));
317305
}
306+
os << "(= #b";
307+
for (int i = bits - 1; i >= 0; i--) os << (VL_BITISSET_I(hash, i) ? '1' : '0');
308+
if (bits > 1) os << " (concat";
318309
for (int i = 0; i < bits; i++) {
319-
std::shared_ptr<const VlRandomExpr> bit = nullptr;
310+
os << " (bvxor";
320311
for (unsigned j = 0; j * 2 < varbits.size(); j++) {
321312
unsigned idx = j + VL_RANDOM_RNG_I(rngr) % (varbits.size() - j);
322-
auto sel = varbits[idx];
323313
std::swap(varbits[idx], varbits[j]);
324-
bit = bit == nullptr ? sel : std::make_shared<const VlRandomBinOp>("bvxor", bit, sel);
314+
os << ' ';
315+
varbits[j]->emit(os);
325316
}
326-
concat = concat == nullptr ? bit
327-
: std::make_shared<const VlRandomBinOp>("concat", concat, bit);
317+
os << ')';
328318
}
329-
return std::make_shared<const VlRandomBinOp>(
330-
"=", concat, std::make_shared<const VlRandomConst>(hash, bits));
319+
if (bits > 1) os << ')';
320+
os << ')';
331321
}
332322

333323
bool VlRandomizer::next(VlRNG& rngr) {
@@ -356,7 +346,7 @@ bool VlRandomizer::next(VlRNG& rngr) {
356346

357347
for (int i = 0; i < _VL_SOLVER_HASH_LEN_TOTAL && sat; i++) {
358348
f << "(assert ";
359-
randomConstraint(rngr, _VL_SOLVER_HASH_LEN)->emit(f);
349+
randomConstraint(f, rngr, _VL_SOLVER_HASH_LEN);
360350
f << ")\n";
361351
f << "\n(check-sat)\n";
362352
sat = parseSolution(f);

include/verilated_random.h

+2-27
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
class VlRandomExpr VL_NOT_FINAL {
3434
public:
3535
virtual void emit(std::ostream& s) const = 0;
36+
virtual ~VlRandomExpr() = default;
3637
};
3738
class VlRandomVar final : public VlRandomExpr {
3839
const char* const m_name; // Variable name
@@ -55,19 +56,6 @@ class VlRandomVar final : public VlRandomExpr {
5556
void emit(std::ostream& s) const override;
5657
};
5758

58-
class VlRandomConst final : public VlRandomExpr {
59-
const QData m_val; // Constant value
60-
const int m_width; // Constant width in bits
61-
62-
public:
63-
VlRandomConst(QData val, int width)
64-
: m_val{val}
65-
, m_width{width} {
66-
assert(width <= sizeof(m_val) * 8);
67-
}
68-
void emit(std::ostream& s) const override;
69-
};
70-
7159
class VlRandomExtract final : public VlRandomExpr {
7260
const std::shared_ptr<const VlRandomExpr> m_expr; // Sub-expression
7361
const unsigned m_idx; // Extracted index
@@ -79,19 +67,6 @@ class VlRandomExtract final : public VlRandomExpr {
7967
void emit(std::ostream& s) const override;
8068
};
8169

82-
class VlRandomBinOp final : public VlRandomExpr {
83-
const char* const m_op; // Binary operation identifier
84-
const std::shared_ptr<const VlRandomExpr> m_lhs, m_rhs; // Sub-expressions
85-
86-
public:
87-
VlRandomBinOp(const char* op, std::shared_ptr<const VlRandomExpr> lhs,
88-
std::shared_ptr<const VlRandomExpr> rhs)
89-
: m_op{op}
90-
, m_lhs{lhs}
91-
, m_rhs{rhs} {}
92-
void emit(std::ostream& s) const override;
93-
};
94-
9570
//=============================================================================
9671
// VlRandomizer is the object holding constraints and variable references.
9772

@@ -103,7 +78,7 @@ class VlRandomizer final {
10378
const VlQueue<CData>* m_randmode; // rand_mode state;
10479

10580
// PRIVATE METHODS
106-
std::shared_ptr<const VlRandomExpr> randomConstraint(VlRNG& rngr, int bits);
81+
void randomConstraint(std::ostream& os, VlRNG& rngr, int bits);
10782
bool parseSolution(std::iostream& file);
10883

10984
public:

0 commit comments

Comments
 (0)