diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 47c7bbd13..9ac2a3801 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include 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 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(); // Claim on first use + if (!nodep->user4p()) nodep->user4p(reinterpret_cast(++m_nextId)); + return reinterpret_cast(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 m_bitPolarities; // Polarity of bits found during iterate() std::vector> 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 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 m_containsMemberAccess; // Caches results of matchBiopToBitwise + // Caches results of matchBiopToBitwise, keyed on node id + std::unordered_map 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 m_recursingEnumItems; std::unordered_set 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 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) { diff --git a/test_regress/t/t_class_short_circuit.v b/test_regress/t/t_class_short_circuit.v index bfbb199e9..9a4a5fa63 100644 --- a/test_regress/t/t_class_short_circuit.v +++ b/test_regress/t/t_class_short_circuit.v @@ -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 diff --git a/test_regress/t/t_opt_const_big_logor_tree.py b/test_regress/t/t_opt_const_big_logor_tree.py new file mode 100755 index 000000000..ced1c5704 --- /dev/null +++ b/test_regress/t/t_opt_const_big_logor_tree.py @@ -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() diff --git a/test_regress/t/t_opt_const_big_logor_tree.v b/test_regress/t/t_opt_const_big_logor_tree.v new file mode 100644 index 000000000..35826a5c4 --- /dev/null +++ b/test_regress/t/t_opt_const_big_logor_tree.v @@ -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