Fix folding of short circuiting operators guarding member access (#8238)

V3Const eagerly deletes nodes (we want that in V3Const instead of using
pushDeletep, as otherwise the transient peak memory use during
verilation can be very high)

The std::map used to cache the predicate checking if a subtree contains
a member access then stale if a new node is allocated in the same address.

Fix by using unique node IDs stored in user4 as cache keys.

This is the bug uncovered by #8147

Related to #6963
This commit is contained in:
Geza Lore
2026-08-28 20:16:03 +02:00
committed by GitHub
parent 6a05cc680b
commit 297713df8b
4 changed files with 311 additions and 45 deletions
+68 -45
View File
@@ -38,6 +38,7 @@
#include <algorithm>
#include <memory>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
VL_DEFINE_DEBUG_FUNCTIONS;
@@ -78,15 +79,29 @@ static int countTrailingZeroes(uint64_t val) {
#endif
}
// Allocates a unique id for each AstNode it is applied to, held in user4.
class VNIdAllocator final {
// NODE STATE
// AstNode::user4p -> size_t. Unique id of the node (0/nullptr if not allocated yet)
// MEMBERS
// Claimed lazily on first use TODO: fix conflict with V3Param user4 slot
std::unique_ptr<VNUser4InUse> m_inuser4p;
size_t m_nextId = 0; // Id allocated most recently
public:
// Return the unique id of the given node, allocating a new one if it has none yet
size_t operator()(AstNode* nodep) {
if (!m_inuser4p) m_inuser4p = std::make_unique<VNUser4InUse>(); // Claim on first use
if (!nodep->user4p()) nodep->user4p(reinterpret_cast<void*>(++m_nextId));
return reinterpret_cast<size_t>(nodep->user4p());
}
};
// This visitor can be used in the post-expanded Ast from V3Expand, where the Ast satisfies:
// - Constants are 64 bit at most (because words are accessed via AstWordSel)
// - Variables are scoped.
class ConstBitOpTreeVisitor final : public VNVisitorConst {
// NODE STATE
// AstVarRef::user4u -> Base index of m_varInfos that points VarInfo
// AstVarScope::user4u -> Same as AstVarRef::user4
const VNUser4InUse m_inuser4;
// TYPES
// Holds a node to be added as a term in the reduction tree, it's equivalent op count, and a
@@ -382,6 +397,10 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst {
m_frozenNodes; // Nodes that cannot be optimized
std::vector<BitPolarityEntry> m_bitPolarities; // Polarity of bits found during iterate()
std::vector<std::unique_ptr<VarInfo>> m_varInfos; // VarInfo for each variable, [0] is nullptr
VNIdAllocator& m_ids; // Node id allocator, owned by ConstVisitor
// Base index of m_varInfos that points VarInfo, keyed by AstVarScope/AstVarRef id,
// zero means not set yet.
std::unordered_map<size_t, int> m_baseIdxs;
// METHODS
@@ -411,15 +430,14 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst {
UASSERT_OBJ(ref.refp(), m_rootp, "null varref in And/Or/Xor optimization");
AstNode* nodep = ref.refp()->varScopep();
if (!nodep) nodep = ref.refp()->varp(); // Not scoped
int baseIdx = nodep->user4();
if (baseIdx == 0) { // Not set yet
baseIdx = m_varInfos.size();
int& baseIdxr = m_baseIdxs[m_ids(nodep)];
if (baseIdxr == 0) { // Not set yet
baseIdxr = m_varInfos.size();
const int numWords
= ref.refp()->dtypep()->isWide() ? ref.refp()->dtypep()->widthWords() : 1;
m_varInfos.resize(m_varInfos.size() + numWords);
nodep->user4(baseIdx);
}
const size_t idx = baseIdx + std::max(0, ref.wordIdx());
const size_t idx = baseIdxr + std::max(0, ref.wordIdx());
VarInfo* varInfop = m_varInfos[idx].get();
if (!varInfop) {
varInfop = new VarInfo{this, ref.refp(), ref.varWidth()};
@@ -671,10 +689,11 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst {
}
// CONSTRUCTORS
ConstBitOpTreeVisitor(AstNodeExpr* nodep, unsigned externalOps)
ConstBitOpTreeVisitor(AstNodeExpr* nodep, unsigned externalOps, VNIdAllocator& ids)
: m_ops{externalOps}
, m_rootp{nodep} {
// Fill nullptr at [0] because AstVarScope::user4 is 0 by default
, m_rootp{nodep}
, m_ids{ids} {
// Fill nullptr at [0] because a base index of 0 means not set yet
m_varInfos.push_back(nullptr);
CONST_BITOP_RETURN_IF(!isAndTree() && !isOrTree() && !isXorTree(), nodep);
if (AstNodeBiop* const biopp = VN_CAST(nodep, NodeBiop)) {
@@ -703,11 +722,11 @@ public:
// Reduction ops are transformed in the same way.
// &{v[0], v[1]} => 2'b11 == (2'b11 & v)
static AstNodeExpr* simplify(AstNodeExpr* nodep, int resultWidth, unsigned externalOps,
VDouble0& reduction) {
VDouble0& reduction, VNIdAllocator& ids) {
UASSERT_OBJ(1 <= resultWidth && resultWidth <= 64, nodep, "resultWidth out of range");
// Walk tree, gathering all terms referenced in expression
const ConstBitOpTreeVisitor visitor{nodep, externalOps};
const ConstBitOpTreeVisitor visitor{nodep, externalOps, ids};
// If failed on root node is not optimizable, or there are no variable terms, then done
if (visitor.m_failed || visitor.m_varInfos.size() == 1) return nullptr;
@@ -913,12 +932,11 @@ class ConstVisitor final : public VNVisitor {
static constexpr unsigned CONCAT_MERGABLE_MAX_DEPTH = 10; // Limit alg recursion
// NODE STATE
// ** only when m_warn/m_doExpensive is set. If state is needed other times,
// ** must track down everywhere V3Const is called and make sure no overlaps.
// AstVar::user4p -> Used by variable marking/finding
// AstEnum::user4 -> bool. Recursing.
// See VNIdAllocator. All per node state below is held in side tables keyed on the
// node ids it hands out, as node pointers are not stable keys within V3Const.
// STATE
VNIdAllocator m_ids; // Node id allocator
bool m_params = false; // If true, propagate parameterized and true numbers only
bool m_required = false; // If true, must become a constant
bool m_wremove = true; // Inside scope, no assignw removal
@@ -940,10 +958,19 @@ class ConstVisitor final : public VNVisitor {
VDouble0 m_statConcatMerge; // Concat merges
VDouble0 m_statCondExprRedundant; // Conditional repeated expressions
VDouble0 m_statIfCondExprRedundant; // Conditional repeated expressions
VDouble0 m_statMemberAccessVisits; // Nodes visited by containsMemberAccessRecurse
const bool m_globalPass; // ConstVisitor invoked as a global pass
static uint32_t s_globalPassNum; // Counts number of times ConstVisitor invoked as global pass
V3UniqueNames m_concswapNames; // For generating unique temporary variable names
std::map<const AstNode*, bool> m_containsMemberAccess; // Caches results of matchBiopToBitwise
// Caches results of matchBiopToBitwise, keyed on node id
std::unordered_map<size_t, bool> m_containsMemberAccess;
// Items of enum currently being recursed into. Cannot use VNIdAllocator, as this runs in
// every mode, including those invoked under a pass holding user4 (V3Param). Node pointers
// are safe as keys here, unlike elsewhere in V3Const: folding the item value below does
// free nodes whose addresses are then reused, but AstEnumItem is only ever constructed
// while parsing (verilog.y and V3LinkParse), so a reused address can never become one,
// and every key looked up is an AstEnumItem.
std::unordered_set<const AstEnumItem*> m_recursingEnumItems;
std::unordered_set<AstJumpBlock*> m_usedJumpBlocks; // JumpBlocks used by some JumpGo
// METHODS
@@ -1485,8 +1512,8 @@ class ConstVisitor final : public VNVisitor {
nodep->dumpTree(debugPrefix + "INPUT: ");
} // LCOV_EXCL_STOP
AstNodeExpr* const newp
= ConstBitOpTreeVisitor::simplify(rootp, width, externalOps, m_statBitOpReduction);
AstNodeExpr* const newp = ConstBitOpTreeVisitor::simplify(rootp, width, externalOps,
m_statBitOpReduction, m_ids);
if (newp) {
nodep->replaceWithKeepDType(newp);
@@ -2442,17 +2469,15 @@ class ConstVisitor final : public VNVisitor {
const bool need_temp_pure = !nodep->rhsp()->isPure();
if (m_warn && !VN_IS(nodep, AssignDly)
&& !need_temp_pure) { // Is same var on LHS and RHS?
// Note only do this (need user4) when m_warn, which is
// done as unique visitor
// If the rhs is not pure, we need a temporary variable anyway
const VNUser4InUse m_inuser4;
nodep->lhsp()->foreach([](const AstVarRef* nodep) {
UASSERT_OBJ(nodep->varp(), nodep, "Unlinked VarRef");
nodep->varp()->user4(1);
std::unordered_set<size_t> lhsVarIds;
nodep->lhsp()->foreach([&](const AstVarRef* refp) {
UASSERT_OBJ(refp->varp(), refp, "Unlinked VarRef");
lhsVarIds.emplace(m_ids(refp->varp()));
});
nodep->rhsp()->foreach([&need_temp](const AstVarRef* nodep) {
UASSERT_OBJ(nodep->varp(), nodep, "Unlinked VarRef");
if (nodep->varp()->user4()) need_temp = true;
nodep->rhsp()->foreach([&](const AstVarRef* refp) {
UASSERT_OBJ(refp->varp(), refp, "Unlinked VarRef");
if (lhsVarIds.count(m_ids(refp->varp()))) need_temp = true;
});
}
if (need_temp_pure) {
@@ -2932,10 +2957,12 @@ class ConstVisitor final : public VNVisitor {
iterate(nodep); // Again?
}
bool containsMemberAccessRecurse(const AstNode* const nodep) {
bool containsMemberAccessRecurse(AstNode* const nodep) {
if (!nodep) return false;
const auto it = m_containsMemberAccess.lower_bound(nodep);
if (it != m_containsMemberAccess.end() && it->first == nodep) return it->second;
const size_t id = m_ids(nodep);
const auto it = m_containsMemberAccess.find(id);
if (it != m_containsMemberAccess.end()) return it->second;
++m_statMemberAccessVisits;
bool result = false;
if (VN_IS(nodep, MemberSel) || VN_IS(nodep, MethodCall) || VN_IS(nodep, CMethodCall)) {
result = true;
@@ -2960,7 +2987,7 @@ class ConstVisitor final : public VNVisitor {
&& containsMemberAccessRecurse(nodep->nextp())) {
result = true;
}
m_containsMemberAccess.insert(it, std::make_pair(nodep, result));
m_containsMemberAccess.emplace(id, result);
return result;
}
@@ -3428,12 +3455,13 @@ class ConstVisitor final : public VNVisitor {
bool did = false;
if (nodep->itemp()->valuep()) {
// UINFOTREE(1, nodep->itemp()->valuep(), "", "visitvaref");
if (nodep->itemp()->user4()) {
const AstEnumItem* const itemp = nodep->itemp();
if (m_recursingEnumItems.count(itemp)) {
nodep->v3error("Recursive enum value: " << nodep->itemp()->prettyNameQ());
} else {
nodep->itemp()->user4(true);
m_recursingEnumItems.emplace(itemp);
iterateAndNextNull(nodep->itemp()->valuep());
nodep->itemp()->user4(false);
m_recursingEnumItems.erase(itemp);
}
if (AstConst* const valuep = VN_CAST(nodep->itemp()->valuep(), Const)) {
const V3Number& num = valuep->num();
@@ -3582,13 +3610,6 @@ class ConstVisitor final : public VNVisitor {
// SENGATE(SENITEM(x)) -> SENITEM(x), then let it collapse with the
// other SENITEM(x).
// Mark x in SENITEM(x)
for (AstSenItem* senp = nodep->sensesp(); senp; senp = VN_AS(senp->nextp(), SenItem)) {
if (senp->varrefp() && senp->varrefp()->varScopep()) {
senp->varrefp()->varScopep()->user4(1);
}
}
// Pass 1: Sort the sensitivity items so "posedge a or b" and "posedge b or a" and
// similar, optimizable expressions end up next to each other.
for (AstSenItem *nextp, *senp = nodep->sensesp(); senp; senp = nextp) {
@@ -4671,6 +4692,8 @@ public:
V3Stats::addStatSum("Optimizations, If cond redundant expressions",
m_statIfCondExprRedundant);
V3Stats::addStatSum("Optimizations, Concat merges", m_statConcatMerge);
V3Stats::addStatSum("Optimizations, Member access predicate node visits",
m_statMemberAccessVisits);
}
AstNode* mainAcceptEdit(AstNode* nodep) {
+11
View File
@@ -6,6 +6,7 @@
class Cls;
int x;
bit b;
function new;
x = 10;
endfunction
@@ -19,14 +20,24 @@ class Cls;
endclass
module t;
bit dbg = 0;
initial begin
Cls cls;
Cls nullc;
if (cls != null && cls.x == 10) $stop;
if (cls != null && cls.get_x() == 10) $stop;
cls = new;
if (!cls.set_x(1) || cls.x != 1) $stop;
if (!cls.set_x(2) || cls.get_x() != 2) $stop;
// Both '||' guard a member access of a null handle, so both must short circuit.
// The shared '(nullc == null)' operand and the 32-bit 'nullc.b == 0' compare used
// to leave a stale entry in V3Const's member-access cache, converting the second
// '||' to a bitwise Or and dereferencing 'nullc.b' unconditionally.
dbg = (nullc == null || dbg) && (nullc == null || nullc.b == 0);
if (dbg !== 1'b1) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of either the GNU Lesser General Public License Version 3
# or the Perl Artistic License Version 2.0.
# SPDX-FileCopyrightText: 2026 Wilson Snyder
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
if test.have_dev_gcov:
test.skip("Too slow with code coverage")
test.timeout(10 if not test.have_dev_asan else 30)
test.compile(verilator_make_gmake=False, verilator_flags2=["--stats"])
visits = int(
test.file_grep(test.stats, r'Optimizations, Member access predicate node visits\s+(\d+)')[0])
if visits > 12000:
test.error("Member access predicate went quadratic: {} node visits".format(visits))
test.passes()
+206
View File
@@ -0,0 +1,206 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
module t (input x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13,
x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28,
x29, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43,
x44, x45, x46, x47, x48, x49, x50, x51, x52, x53, x54, x55, x56, x57, x58,
x59, x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x70, x71, x72, x73,
x74, x75, x76, x77, x78, x79, x80, x81, x82, x83, x84, x85, x86, x87, x88,
x89, x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x100, x101, x102,
x103, x104, x105, x106, x107, x108, x109, x110, x111, x112, x113, x114,
x115, x116, x117, x118, x119, x120, x121, x122, x123, x124, x125, x126,
x127, x128, x129, x130, x131, x132, x133, x134, x135, x136, x137, x138,
x139, x140, x141, x142, x143, x144, x145, x146, x147, x148, x149, x150,
x151, x152, x153, x154, x155, x156, x157, x158, x159, x160, x161, x162,
x163, x164, x165, x166, x167, x168, x169, x170, x171, x172, x173, x174,
x175, x176, x177, x178, x179, x180, x181, x182, x183, x184, x185, x186,
x187, x188, x189, x190, x191, x192, x193, x194, x195, x196, x197, x198,
x199, x200, x201, x202, x203, x204, x205, x206, x207, x208, x209, x210,
x211, x212, x213, x214, x215, x216, x217, x218, x219, x220, x221, x222,
x223, x224, x225, x226, x227, x228, x229, x230, x231, x232, x233, x234,
x235, x236, x237, x238, x239, x240, x241, x242, x243, x244, x245, x246,
x247, x248, x249, x250, x251, x252, x253, x254, x255, x256, x257, x258,
x259, x260, x261, x262, x263, x264, x265, x266, x267, x268, x269, x270,
x271, x272, x273, x274, x275, x276, x277, x278, x279, x280, x281, x282,
x283, x284, x285, x286, x287, x288, x289, x290, x291, x292, x293, x294,
x295, x296, x297, x298, x299, x300, x301, x302, x303, x304, x305, x306,
x307, x308, x309, x310, x311, x312, x313, x314, x315, x316, x317, x318,
x319, x320, x321, x322, x323, x324, x325, x326, x327, x328, x329, x330,
x331, x332, x333, x334, x335, x336, x337, x338, x339, x340, x341, x342,
x343, x344, x345, x346, x347, x348, x349, x350, x351, x352, x353, x354,
x355, x356, x357, x358, x359, x360, x361, x362, x363, x364, x365, x366,
x367, x368, x369, x370, x371, x372, x373, x374, x375, x376, x377, x378,
x379, x380, x381, x382, x383, x384, x385, x386, x387, x388, x389, x390,
x391, x392, x393, x394, x395, x396, x397, x398, x399, x400, x401, x402,
x403, x404, x405, x406, x407, x408, x409, x410, x411, x412, x413, x414,
x415, x416, x417, x418, x419, x420, x421, x422, x423, x424, x425, x426,
x427, x428, x429, x430, x431, x432, x433, x434, x435, x436, x437, x438,
x439, x440, x441, x442, x443, x444, x445, x446, x447, x448, x449, x450,
x451, x452, x453, x454, x455, x456, x457, x458, x459, x460, x461, x462,
x463, x464, x465, x466, x467, x468, x469, x470, x471, x472, x473, x474,
x475, x476, x477, x478, x479, x480, x481, x482, x483, x484, x485, x486,
x487, x488, x489, x490, x491, x492, x493, x494, x495, x496, x497, x498,
x499, x500, x501, x502, x503, x504, x505, x506, x507, x508, x509, x510,
x511, x512, x513, x514, x515, x516, x517, x518, x519, x520, x521, x522,
x523, x524, x525, x526, x527, x528, x529, x530, x531, x532, x533, x534,
x535, x536, x537, x538, x539, x540, x541, x542, x543, x544, x545, x546,
x547, x548, x549, x550, x551, x552, x553, x554, x555, x556, x557, x558,
x559, x560, x561, x562, x563, x564, x565, x566, x567, x568, x569, x570,
x571, x572, x573, x574, x575, x576, x577, x578, x579, x580, x581, x582,
x583, x584, x585, x586, x587, x588, x589, x590, x591, x592, x593, x594,
x595, x596, x597, x598, x599, x600, x601, x602, x603, x604, x605, x606,
x607, x608, x609, x610, x611, x612, x613, x614, x615, x616, x617, x618,
x619, x620, x621, x622, x623, x624, x625, x626, x627, x628, x629, x630,
x631, x632, x633, x634, x635, x636, x637, x638, x639, x640, x641, x642,
x643, x644, x645, x646, x647, x648, x649, x650, x651, x652, x653, x654,
x655, x656, x657, x658, x659, x660, x661, x662, x663, x664, x665, x666,
x667, x668, x669, x670, x671, x672, x673, x674, x675, x676, x677, x678,
x679, x680, x681, x682, x683, x684, x685, x686, x687, x688, x689, x690,
x691, x692, x693, x694, x695, x696, x697, x698, x699, x700, x701, x702,
x703, x704, x705, x706, x707, x708, x709, x710, x711, x712, x713, x714,
x715, x716, x717, x718, x719, x720, x721, x722, x723, x724, x725, x726,
x727, x728, x729, x730, x731, x732, x733, x734, x735, x736, x737, x738,
x739, x740, x741, x742, x743, x744, x745, x746, x747, x748, x749, x750,
x751, x752, x753, x754, x755, x756, x757, x758, x759, x760, x761, x762,
x763, x764, x765, x766, x767, x768, x769, x770, x771, x772, x773, x774,
x775, x776, x777, x778, x779, x780, x781, x782, x783, x784, x785, x786,
x787, x788, x789, x790, x791, x792, x793, x794, x795, x796, x797, x798,
x799, x800, x801, x802, x803, x804, x805, x806, x807, x808, x809, x810,
x811, x812, x813, x814, x815, x816, x817, x818, x819, x820, x821, x822,
x823, x824, x825, x826, x827, x828, x829, x830, x831, x832, x833, x834,
x835, x836, x837, x838, x839, x840, x841, x842, x843, x844, x845, x846,
x847, x848, x849, x850, x851, x852, x853, x854, x855, x856, x857, x858,
x859, x860, x861, x862, x863, x864, x865, x866, x867, x868, x869, x870,
x871, x872, x873, x874, x875, x876, x877, x878, x879, x880, x881, x882,
x883, x884, x885, x886, x887, x888, x889, x890, x891, x892, x893, x894,
x895, x896, x897, x898, x899, x900, x901, x902, x903, x904, x905, x906,
x907, x908, x909, x910, x911, x912, x913, x914, x915, x916, x917, x918,
x919, x920, x921, x922, x923, x924, x925, x926, x927, x928, x929, x930,
x931, x932, x933, x934, x935, x936, x937, x938, x939, x940, x941, x942,
x943, x944, x945, x946, x947, x948, x949, x950, x951, x952, x953, x954,
x955, x956, x957, x958, x959, x960, x961, x962, x963, x964, x965, x966,
x967, x968, x969, x970, x971, x972, x973, x974, x975, x976, x977, x978,
x979, x980, x981, x982, x983, x984, x985, x986, x987, x988, x989, x990,
x991, x992, x993, x994, x995, x996, x997, x998, x999,
output [1:0] out
);
assign out = {(x0 || x1 || x2 || x3 || x4 || x5 || x6 || x7 || x8 || x9
|| x10 || x11 || x12 || x13 || x14 || x15 || x16 || x17 || x18 || x19 || x20
|| x21 || x22 || x23 || x24 || x25 || x26 || x27 || x28 || x29 || x30 || x31
|| x32 || x33 || x34 || x35 || x36 || x37 || x38 || x39 || x40 || x41 || x42
|| x43 || x44 || x45 || x46 || x47 || x48 || x49 || x50 || x51 || x52 || x53
|| x54 || x55 || x56 || x57 || x58 || x59 || x60 || x61 || x62 || x63 || x64
|| x65 || x66 || x67 || x68 || x69 || x70 || x71 || x72 || x73 || x74 || x75
|| x76 || x77 || x78 || x79 || x80 || x81 || x82 || x83 || x84 || x85 || x86
|| x87 || x88 || x89 || x90 || x91 || x92 || x93 || x94 || x95 || x96 || x97
|| x98 || x99 || x100 || x101 || x102 || x103 || x104 || x105 || x106 || x107
|| x108 || x109 || x110 || x111 || x112 || x113 || x114 || x115 || x116
|| x117 || x118 || x119 || x120 || x121 || x122 || x123 || x124 || x125
|| x126 || x127 || x128 || x129 || x130 || x131 || x132 || x133 || x134
|| x135 || x136 || x137 || x138 || x139 || x140 || x141 || x142 || x143
|| x144 || x145 || x146 || x147 || x148 || x149 || x150 || x151 || x152
|| x153 || x154 || x155 || x156 || x157 || x158 || x159 || x160 || x161
|| x162 || x163 || x164 || x165 || x166 || x167 || x168 || x169 || x170
|| x171 || x172 || x173 || x174 || x175 || x176 || x177 || x178 || x179
|| x180 || x181 || x182 || x183 || x184 || x185 || x186 || x187 || x188
|| x189 || x190 || x191 || x192 || x193 || x194 || x195 || x196 || x197
|| x198 || x199 || x200 || x201 || x202 || x203 || x204 || x205 || x206
|| x207 || x208 || x209 || x210 || x211 || x212 || x213 || x214 || x215
|| x216 || x217 || x218 || x219 || x220 || x221 || x222 || x223 || x224
|| x225 || x226 || x227 || x228 || x229 || x230 || x231 || x232 || x233
|| x234 || x235 || x236 || x237 || x238 || x239 || x240 || x241 || x242
|| x243 || x244 || x245 || x246 || x247 || x248 || x249 || x250 || x251
|| x252 || x253 || x254 || x255 || x256 || x257 || x258 || x259 || x260
|| x261 || x262 || x263 || x264 || x265 || x266 || x267 || x268 || x269
|| x270 || x271 || x272 || x273 || x274 || x275 || x276 || x277 || x278
|| x279 || x280 || x281 || x282 || x283 || x284 || x285 || x286 || x287
|| x288 || x289 || x290 || x291 || x292 || x293 || x294 || x295 || x296
|| x297 || x298 || x299 || x300 || x301 || x302 || x303 || x304 || x305
|| x306 || x307 || x308 || x309 || x310 || x311 || x312 || x313 || x314
|| x315 || x316 || x317 || x318 || x319 || x320 || x321 || x322 || x323
|| x324 || x325 || x326 || x327 || x328 || x329 || x330 || x331 || x332
|| x333 || x334 || x335 || x336 || x337 || x338 || x339 || x340 || x341
|| x342 || x343 || x344 || x345 || x346 || x347 || x348 || x349 || x350
|| x351 || x352 || x353 || x354 || x355 || x356 || x357 || x358 || x359
|| x360 || x361 || x362 || x363 || x364 || x365 || x366 || x367 || x368
|| x369 || x370 || x371 || x372 || x373 || x374 || x375 || x376 || x377
|| x378 || x379 || x380 || x381 || x382 || x383 || x384 || x385 || x386
|| x387 || x388 || x389 || x390 || x391 || x392 || x393 || x394 || x395
|| x396 || x397 || x398 || x399 || x400 || x401 || x402 || x403 || x404
|| x405 || x406 || x407 || x408 || x409 || x410 || x411 || x412 || x413
|| x414 || x415 || x416 || x417 || x418 || x419 || x420 || x421 || x422
|| x423 || x424 || x425 || x426 || x427 || x428 || x429 || x430 || x431
|| x432 || x433 || x434 || x435 || x436 || x437 || x438 || x439 || x440
|| x441 || x442 || x443 || x444 || x445 || x446 || x447 || x448 || x449
|| x450 || x451 || x452 || x453 || x454 || x455 || x456 || x457 || x458
|| x459 || x460 || x461 || x462 || x463 || x464 || x465 || x466 || x467
|| x468 || x469 || x470 || x471 || x472 || x473 || x474 || x475 || x476
|| x477 || x478 || x479 || x480 || x481 || x482 || x483 || x484 || x485
|| x486 || x487 || x488 || x489 || x490 || x491 || x492 || x493 || x494
|| x495 || x496 || x497 || x498 || x499 || x500 || x501 || x502 || x503
|| x504 || x505 || x506 || x507 || x508 || x509 || x510 || x511 || x512
|| x513 || x514 || x515 || x516 || x517 || x518 || x519 || x520 || x521
|| x522 || x523 || x524 || x525 || x526 || x527 || x528 || x529 || x530
|| x531 || x532 || x533 || x534 || x535 || x536 || x537 || x538 || x539
|| x540 || x541 || x542 || x543 || x544 || x545 || x546 || x547 || x548
|| x549 || x550 || x551 || x552 || x553 || x554 || x555 || x556 || x557
|| x558 || x559 || x560 || x561 || x562 || x563 || x564 || x565 || x566
|| x567 || x568 || x569 || x570 || x571 || x572 || x573 || x574 || x575
|| x576 || x577 || x578 || x579 || x580 || x581 || x582 || x583 || x584
|| x585 || x586 || x587 || x588 || x589 || x590 || x591 || x592 || x593
|| x594 || x595 || x596 || x597 || x598 || x599 || x600 || x601 || x602
|| x603 || x604 || x605 || x606 || x607 || x608 || x609 || x610 || x611
|| x612 || x613 || x614 || x615 || x616 || x617 || x618 || x619 || x620
|| x621 || x622 || x623 || x624 || x625 || x626 || x627 || x628 || x629
|| x630 || x631 || x632 || x633 || x634 || x635 || x636 || x637 || x638
|| x639 || x640 || x641 || x642 || x643 || x644 || x645 || x646 || x647
|| x648 || x649 || x650 || x651 || x652 || x653 || x654 || x655 || x656
|| x657 || x658 || x659 || x660 || x661 || x662 || x663 || x664 || x665
|| x666 || x667 || x668 || x669 || x670 || x671 || x672 || x673 || x674
|| x675 || x676 || x677 || x678 || x679 || x680 || x681 || x682 || x683
|| x684 || x685 || x686 || x687 || x688 || x689 || x690 || x691 || x692
|| x693 || x694 || x695 || x696 || x697 || x698 || x699 || x700 || x701
|| x702 || x703 || x704 || x705 || x706 || x707 || x708 || x709 || x710
|| x711 || x712 || x713 || x714 || x715 || x716 || x717 || x718 || x719
|| x720 || x721 || x722 || x723 || x724 || x725 || x726 || x727 || x728
|| x729 || x730 || x731 || x732 || x733 || x734 || x735 || x736 || x737
|| x738 || x739 || x740 || x741 || x742 || x743 || x744 || x745 || x746
|| x747 || x748 || x749 || x750 || x751 || x752 || x753 || x754 || x755
|| x756 || x757 || x758 || x759 || x760 || x761 || x762 || x763 || x764
|| x765 || x766 || x767 || x768 || x769 || x770 || x771 || x772 || x773
|| x774 || x775 || x776 || x777 || x778 || x779 || x780 || x781 || x782
|| x783 || x784 || x785 || x786 || x787 || x788 || x789 || x790 || x791
|| x792 || x793 || x794 || x795 || x796 || x797 || x798 || x799 || x800
|| x801 || x802 || x803 || x804 || x805 || x806 || x807 || x808 || x809
|| x810 || x811 || x812 || x813 || x814 || x815 || x816 || x817 || x818
|| x819 || x820 || x821 || x822 || x823 || x824 || x825 || x826 || x827
|| x828 || x829 || x830 || x831 || x832 || x833 || x834 || x835 || x836
|| x837 || x838 || x839 || x840 || x841 || x842 || x843 || x844 || x845
|| x846 || x847 || x848 || x849 || x850 || x851 || x852 || x853 || x854
|| x855 || x856 || x857 || x858 || x859 || x860 || x861 || x862 || x863
|| x864 || x865 || x866 || x867 || x868 || x869 || x870 || x871 || x872
|| x873 || x874 || x875 || x876 || x877 || x878 || x879 || x880 || x881
|| x882 || x883 || x884 || x885 || x886 || x887 || x888 || x889 || x890
|| x891 || x892 || x893 || x894 || x895 || x896 || x897 || x898 || x899
|| x900 || x901 || x902 || x903 || x904 || x905 || x906 || x907 || x908
|| x909 || x910 || x911 || x912 || x913 || x914 || x915 || x916 || x917
|| x918 || x919 || x920 || x921 || x922 || x923 || x924 || x925 || x926
|| x927 || x928 || x929 || x930 || x931 || x932 || x933 || x934 || x935
|| x936 || x937 || x938 || x939 || x940 || x941 || x942 || x943 || x944
|| x945 || x946 || x947 || x948 || x949 || x950 || x951 || x952 || x953
|| x954 || x955 || x956 || x957 || x958 || x959 || x960 || x961 || x962
|| x963 || x964 || x965 || x966 || x967 || x968 || x969 || x970 || x971
|| x972 || x973 || x974 || x975 || x976 || x977 || x978 || x979 || x980
|| x981 || x982 || x983 || x984 || x985 || x986 || x987 || x988 || x989
|| x990 || x991 || x992 || x993 || x994 || x995 || x996 || x997 || x998
|| x999), 1'b0};
// verilog_format: on
endmodule