Compare commits

...

68 Commits

Author SHA1 Message Date
Ryszard Rozak d0d240f8bd
Merge b3aaedf7d6 into 98b8d43a4a 2025-07-21 15:40:20 +02:00
Igor Zaworski 98b8d43a4a
Fix parameter-dependent type linking (#6170) 2025-07-21 07:30:10 -04:00
Bartłomiej Chmiel d419c49921
Internals: Fix unused variable, no functional change (#6204)
Signed-off-by: Bartłomiej Chmiel <bchmiel@antmicro.com>
2025-07-21 07:28:01 -04:00
Max Wipfli a50ea2a1a6
Optimize 2 ** X to 1 << X if base is signed (#6203) 2025-07-20 09:56:34 -04:00
Wilson Snyder 078bb21a89 Add wire data type checking per IEEE. 2025-07-20 07:21:30 -04:00
Wilson Snyder b8b9478938 Improve enum base type checking error message. 2025-07-19 22:37:07 -04:00
Wilson Snyder f535a73ea7 Commentary: Changes update 2025-07-19 21:12:23 -04:00
Wilson Snyder 641e0e5672 Internals: Fix assertion if bad display 2025-07-19 21:12:10 -04:00
Ibrahim Burak Yorulmaz 9d146eae16
Fix VPI signal range order (#6189) (#6200) 2025-07-19 20:22:02 -04:00
Wilson Snyder 7d43a935bd Add SPECIFYIGN warning for specify constructs that were previously silently ignored. 2025-07-18 19:32:34 -04:00
Yilou Wang 9b99d9697f
Fix virtual interface member propagation (#6175) (#6184) 2025-07-18 09:07:31 -04:00
Ryszard Rozak a21ecb2ab9
Add support for randomize..with on objects of aliased types (#6195) 2025-07-18 13:04:47 +02:00
Ryszard Rozak 28808f38bb
Dump function to which AstAddrOfCFunc points (#6188) 2025-07-18 08:37:00 +02:00
Wilson Snyder 7a6775ca84 Internals: Rename memPeakUsageBytes 2025-07-17 22:16:59 -04:00
Wilson Snyder e527ff49a3 Report `--stats` final results after build phase 2025-07-17 20:41:46 -04:00
Wilson Snyder c1506deef9 Add enum base type checking per IEEE. 2025-07-17 20:20:43 -04:00
Wilson Snyder 87050670b4 Fix structure select causing 'Wide Op' error (#6191). 2025-07-17 18:17:49 -04:00
Wilson Snyder fb1373b854 Tests: Reformat. Ignore whitespace if comparing. No test functional change. 2025-07-16 21:31:40 -04:00
Wilson Snyder 7f1011e5f7 Make some CVTREAL fatal where IEEE requires it. 2025-07-16 18:07:07 -04:00
Wilson Snyder 7a32771c7e Commentary: Changes update 2025-07-16 17:26:01 -04:00
Wilson Snyder 94b043d6c9 Internals: Print versions with `make format` 2025-07-16 17:25:22 -04:00
Igor Zaworski 8c5ba3a0d7
Fix conflicting function/class name linking error (#6182) 2025-07-16 17:25:01 -04:00
Igor Zaworski 826e5b0826
Fix `--coverage-expr` null pointer dereference (#6181) 2025-07-16 12:07:34 -04:00
Artur Bieniek abd509ce53
Support delays in emitted Verilog (#6177) 2025-07-16 11:52:56 -04:00
Ryszard Rozak 1bf24c7eb4
Add support for disabling begin just under fork from outside that begin (#5432 partial) (#6183) 2025-07-16 16:04:17 +02:00
Wilson Snyder 1f0357ba93 Add NOEFFECT warning, replacing previous `foreach` error. 2025-07-16 08:18:57 -04:00
Wilson Snyder db6b17fdb4 Fix error message 2025-07-15 17:41:08 -04:00
Artur Bieniek f3e109d8c5
Support covergroup extends, etc. (#6160) 2025-07-15 09:31:08 -04:00
Wilson Snyder 371ac07c6f Fix CVTREAL not being able to be disabled in e.g. primitive terminals. 2025-07-14 20:08:44 -04:00
Wilson Snyder caf3522364 Support implicit enum declarations with packed dimensions 2025-07-14 19:50:02 -04:00
Geza Lore 03e0d49d99
Optimize DFG partial assignments (#6176)
This is mostly a refactoring, but also enables handling some more
UNOPTFLAT, when the variable is only partially assigned in the cycle.

Previously the way partial assignments to variables were handled were
through the DfgVerexVar types themselves, which kept track of all
drivers. This has been replaced by DfgVertexSplice (which always drives
a DfgVeretexVar), and all DfgVertexVar now only have a single source,
either a DfgVertexSplice, if partially assigned, or an arbitrary
DfgVertex when updated as a whole.
2025-07-14 17:09:34 -04:00
Ryszard Rozak b3aaedf7d6 Other suggestions
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-26 08:48:49 +02:00
github action 8fd865129e Apply 'make format' 2025-06-26 06:40:06 +00:00
Ryszard Rozak f1bfa8bdda
Apply suggestions from code review
Co-authored-by: Wilson Snyder <wsnyder@wsnyder.org>
2025-06-26 08:38:54 +02:00
Ryszard Rozak 13309fd88c Dump range
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:12 +02:00
Ryszard Rozak 0ef968188f Update tests
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:12 +02:00
Ryszard Rozak 86109cfe04 Fix ascending ranges
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:12 +02:00
Ryszard Rozak e764037841 Fix emitting indices
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:12 +02:00
Ryszard Rozak 8997006d3e WIP: Emit it with loop
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:12 +02:00
Ryszard Rozak 6b719d975a Use __vlCoverToggleInsert
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:12 +02:00
Ryszard Rozak 84ea40d3f3 Fix typo
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:12 +02:00
Ryszard Rozak b7f5e6749e Store ranges instead of dtypep
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:12 +02:00
Ryszard Rozak 190ac9ae65 Swap indices in test
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:12 +02:00
Ryszard Rozak 0ea5d557b3 Fix checking if var is ranged
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:12 +02:00
Ryszard Rozak e851c211c4 Split AstCOverDecl class, use dtypep instead of begin and end
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:12 +02:00
Ryszard Rozak b3df96915a Apply other suggestions
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 755803ee64 Apply suggestions from code review
Co-authored-by: Wilson Snyder <wsnyder@wsnyder.org>
2025-06-25 15:17:11 +02:00
Ryszard Rozak ff4bf5bab1 Update output
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 1a566504d9 Fix indices not starting from 0
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak b65ef0065d Change index in test
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 2d935fc551 Add {}
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak ddbf75dc59 Add test with [0:0]
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 7244dd530f Add test
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 4518a23075 Change unsigned int to uint32_t
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 0d66bc3d0d FIx multithread case
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 3223043c17 Skip WData element if xor is 0
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 276e37f039 Replace i++ with ++i
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 5436bedc52 Update expected numbers of optimizations
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak c48ef3bdab Add _W implementation
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak c0ff829952 Add _I and _Q implementations
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 1e4f678836 Pass pointer to first element instead of index
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 9ccd566ccb WIP: Emit separate vlCoverInsert per element
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak e134f8b9aa Emit call to VL_COV_TOGGLE_CHG_
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak e183a10836 Add size field to AstCoverDecl
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 7e2b5ba0c9 Pass togcov expression, add comments
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak 78bf946230 Pass expr from AstCoverToggle to AstCOverInc
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak babcf59462 Throw assert if type is non-opaque
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
Ryszard Rozak fa9bd6470b Create 1 AstCoverToggle for AstBasicDType
Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
2025-06-25 15:17:11 +02:00
157 changed files with 4730 additions and 2684 deletions

14
Changes
View File

@ -14,19 +14,29 @@ Verilator 5.039 devel
**Other:**
* Add ENUMITEMWIDTH error, and apply to X-extended and ranged values.
* Add NOEFFECT warning, replacing previous `foreach` error.
* Add SPECIFYIGN warning for specify constructs that were previously silently ignored.
* Add enum base data type, and wire data type checking per IEEE.
* Support member-level triggers for virtual interfaces (#5166) (#6148). [Yilou Wang]
* Support disabling a fork in additional contexts (#5432 partial) (#6174) (#6183). [Ryszard Rozak, Antmicro Ltd.]
* Support disable dotted references (#6154). [Ryszard Rozak, Antmicro Ltd.]
* Support randomize() on class member selects (#6161). [Igor Zaworski, Antmicro Ltd.]
* Support randomize() on class member selects (#6161) (#6195). [Igor Zaworski, Ryszard Rozak, Antmicro Ltd.]
* Support multiple variables on RHS of a `force` assignment (#6163). [Artur Bieniek, Antmicro Ltd.]]
* Support covergroup extends, etc., as unsupported (#6160). [Artur Bieniek, Antmicro Ltd.]
* Change control file `public_flat_*` and other signal attributes to support __ in names (#6140).
* Fix constructor parameters in inheritance hierarchies (#6036) (#6070). [Petr Nohavica]
* Fix cmake `-Wno` compiler flag testing (#6145). [Martin Stadler]
* Fix class extends dotted error (#6162). [Igor Zaworski, Antmicro Ltd.]
* Fix genvar error with `-O0` (#6165). [Max Wipfli]
* Fix uninitialized thread PGO counters (#6167). [Bartłomiej Chmiel, Antmicro Ltd.]
* Fix additional UNOPTFLAT combinational cycles automatically in DFG (#6168) (#6173). [Geza Lore]
* Fix additional UNOPTFLAT combinational cycles automatically in DFG (#6168) (#6173) (#6176). [Geza Lore]
* Fix omitting error when assigning to an input (#6169). [Artur Bieniek, Antmicro Ltd.]]
* Fix param-dependent class typedef linking (#6171). [Igor Zaworski, Antmicro Ltd.]
* Fix virtual interface member propagation (#6175) (#6184). [Yilou Wang]
* Fix `--coverage-expr` null pointer dereference (#6181). [Igor Zaworski, Antmicro Ltd.]
* Fix conflicting function/class name linking error (#6182). [Igor Zaworski, Antmicro Ltd.]
* Fix VPI signal range order (#6189) (#6200). [Ibrahim Burak Yorulmaz]
* Fix structure select causing 'Wide Op' error (#6191). [Danny Oler]
Verilator 5.038 2025-07-08

View File

@ -470,6 +470,7 @@ CLANGFORMAT_FLAGS = -i
CLANGFORMAT_FILES = $(CHECK_CPP) $(CHECK_H) $(CHECK_YL) test_regress/t/*.c* test_regress/t/*.h
format-c clang-format:
$(CLANGFORMAT) --version
@$(CLANGFORMAT) --version | egrep 14.0 > /dev/null \
|| echo "*** You are not using clang-format-14, indents may differ from master's ***"
$(CLANGFORMAT) $(CLANGFORMAT_FLAGS) $(CLANGFORMAT_FILES)
@ -538,6 +539,7 @@ YAPF = yapf3
YAPF_FLAGS = -i --parallel
format-py yapf:
$(YAPF) --version
$(YAPF) $(YAPF_FLAGS) $(PY_FILES)
GERSEMI = gersemi

View File

@ -84,6 +84,7 @@ Huang Rui
Huanghuang Zhou
HungMingWu
HyungKi Jeong
Ibrahim Burak Yorulmaz
Igor Zaworski
Ilya Barkov
Iru Cai
@ -157,6 +158,7 @@ Martin Schmidt
Martin Stadler
Mateusz Gancarz
Matthew Ballance
Max Wipfli
Michael Bikovitsky
Michael Killough
Michal Czyz

View File

@ -68,11 +68,16 @@ pdf:
######################################################################
html latex linkcheck spelling::
html latex linkcheck::
$(MAKE) vl-extract
$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)
$(PYTHON3) bin/vl_sphinx_fix _build
spelling::
$(MAKE) vl-extract
$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)
sort -o guide/spelling.txt guide/spelling.txt
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)

View File

@ -3,6 +3,6 @@
:linenos:
:emphasize-lines: 3
int array[5];
bit [1:0] rd_addr;
wire int rd_value = array[rd_addr]; //<--- Warning
logic [31:0] array[5];
bit [1:0] rd_addr;
wire [31:0] rd_value = array[rd_addr]; //<--- Warning

View File

@ -2,4 +2,4 @@
.. code-block:: sv
:emphasize-lines: 1
wire int rd_value = array[{1'b0, rd_addr}]; //<--- Fixed
wire [31:0] rd_value = array[{1'b0, rd_addr}]; //<--- Fixed

View File

@ -1,4 +1,4 @@
.. comment: generated by t_lint_widthexpand_docs_bad
.. code-block::
%Warning-WIDTHEXPAND: example.v:3:29 Bit extraction of array[4:0] requires 3 bit index, not 2 bits.
%Warning-WIDTHEXPAND: example.v:3:31 Bit extraction of array[4:0] requires 3 bit index, not 2 bits.

View File

@ -458,7 +458,7 @@ List Of Warnings
Warns that Verilator does not support certain forms of
:code:`constraint`, :code:`constraint_mode`, or :code:`rand_mode`, and
the construct was are ignored.
the construct was ignored.
Ignoring this warning may make Verilator randomize() simulations differ
from other simulators.
@ -486,7 +486,7 @@ List Of Warnings
Warns that Verilator does not support certain forms of
:code:`covergroup`, :code:`coverpoint`, and coverage options, and the
construct was are ignored.
construct was ignored.
Disabling the :option:`UNSUPPORTED` error also disables this warning.
@ -1308,6 +1308,21 @@ List Of Warnings
simulate correctly.
.. option:: NOEFFECT
Warns that the statement will have no effect and is roughly equivalent
to not being present. This is only issued when it is "non-obvious",
e.g. a :code:`if (0)` will not result in this warning.
Faulty example:
.. code-block:: sv
foreach (array[]) begin ... end //<--- Warning
For a fix, remove the statement.
.. option:: NOLATCH
.. TODO better example
@ -1764,6 +1779,18 @@ List Of Warnings
simulators.
.. option:: SPECIFYIGN
Warns that Verilator does not support certain constructs in
:code:`specify` blocks, nor :code:`$sdf_annotate`, and the construct was
ignored.
Disabling the :option:`UNSUPPORTED` error also disables this warning.
Ignoring this warning may make Verilator ignore lint checking on the
construct, and get different results from other simulators.
.. option:: SPLITVAR
Warns that a variable with a :option:`/*verilator&32;split_var*/`

View File

@ -314,6 +314,7 @@ Noack
Nodine
Ober
Oleg
Oler
Olof
Olofsson
Oron
@ -601,6 +602,7 @@ coroutines
countbits
countones
cout
covergroup
cpp
cppstyle
cpu

View File

@ -3061,7 +3061,7 @@ void VerilatedContext::statsPrintSummary() VL_MT_UNSAFE {
= vl_timescaled_double((cputime != 0.0) ? (simtimeInUnits / cputime) : 0, "%0.3f %s");
VL_PRINTF("- Verilator: %s at %s; walltime %0.3f s; speed %s/s\n", endwhy.c_str(),
simtime.c_str(), walltime, simtimePerf.c_str());
const double modelMB = VlOs::memUsageBytes() / 1024.0 / 1024.0;
const double modelMB = VlOs::memPeakUsageBytes() / 1024.0 / 1024.0;
VL_PRINTF("- Verilator: cpu %0.3f s on %u threads; alloced %0.0f MB\n", cputime,
threadsInModels(), modelMB);
}

View File

@ -75,6 +75,58 @@ class VerilatedCovImp;
ccontextp->_insertp("hier", name, __VA_ARGS__); \
} while (false)
static inline void VL_COV_TOGGLE_CHG_ST_I(const int width, uint32_t* covp, const IData newData,
const IData oldData) {
for (int i = 0; i < width; ++i) *(covp + i) += ((newData ^ oldData) >> i) & 1;
}
static inline void VL_COV_TOGGLE_CHG_ST_Q(const int width, uint32_t* covp, const IData newData,
const IData oldData) {
for (int i = 0; i < width; ++i) *(covp + i) += ((newData ^ oldData) >> i) & 1;
}
static inline void VL_COV_TOGGLE_CHG_ST_W(const int width, uint32_t* covp, WDataInP newData,
WDataInP oldData) {
for (int i = 0; i < VL_WORDS_I(width); ++i) {
const EData changed = newData[i] ^ oldData[i];
if (changed) {
for (int j = 0; j < width - i * 32; ++j) *(covp + i * 32 + j) += (changed >> j) & 1;
}
}
}
static inline void VL_COV_TOGGLE_CHG_MT_I(const int width, std::atomic<uint32_t>* covp,
const IData newData, const IData oldData) VL_MT_SAFE {
for (int i = 0; i < width; ++i) {
if (VL_BITISSET_I((newData ^ oldData), i)) {
(covp + i)->fetch_add(1, std::memory_order_relaxed);
}
}
}
static inline void VL_COV_TOGGLE_CHG_MT_Q(const int width, std::atomic<uint32_t>* covp,
const IData newData, const IData oldData) VL_MT_SAFE {
for (int i = 0; i < width; ++i) {
if (VL_BITISSET_Q((newData ^ oldData), i)) {
(covp + i)->fetch_add(1, std::memory_order_relaxed);
}
}
}
static inline void VL_COV_TOGGLE_CHG_MT_W(const int width, std::atomic<uint32_t>* covp,
WDataInP newData, WDataInP oldData) VL_MT_SAFE {
for (int i = 0; i < VL_WORDS_I(width); ++i) {
const EData changed = newData[i] ^ oldData[i];
if (changed) {
for (int j = 0; j < width - i * 32; ++j) {
if (VL_BITISSET_E(changed, j)) {
(covp + i * 32 + j)->fetch_add(1, std::memory_order_relaxed);
}
}
}
}
}
//=============================================================================
// VerilatedCov
/// Per-VerilatedContext coverage data class.

View File

@ -637,7 +637,7 @@ extern std::string getenvStr(const std::string& envvar,
extern uint16_t getcpu() VL_MT_SAFE;
/// Return memory usage in bytes, or 0 if unknown
extern uint64_t memUsageBytes() VL_MT_SAFE;
extern uint64_t memPeakUsageBytes() VL_MT_SAFE;
// Internal: Record CPU time, starting point on construction, and current delta from that
class DeltaCpuTime final {

View File

@ -102,9 +102,9 @@ uint16_t getcpu() VL_MT_SAFE {
}
//=========================================================================
// VlOs::memUsageBytes implementation
// VlOs::memPeakUsageBytes implementation
uint64_t memUsageBytes() VL_MT_SAFE {
uint64_t memPeakUsageBytes() VL_MT_SAFE {
#if defined(_WIN32) || defined(__MINGW32__)
const HANDLE process = GetCurrentProcess();
PROCESS_MEMORY_COUNTERS pmc;
@ -124,6 +124,7 @@ uint64_t memUsageBytes() VL_MT_SAFE {
&size, &resident, &share, &text, &lib, &data, &dt);
fclose(fp);
if (VL_UNCOVERABLE(7 != items)) return 0;
// Return the vm size, not the current active set size (/proc/self/status VmRSS + VmSwap)
return (text + data) * getpagesize();
#endif
}

View File

@ -561,6 +561,7 @@ public:
public:
ASTGEN_MEMBERS_AstAddrOfCFunc;
void dump(std::ostream& str) const override;
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return true; }

View File

@ -399,6 +399,52 @@ public:
ASTGEN_MEMBERS_AstNodeCase;
int instrCount() const override { return INSTR_COUNT_BRANCH; }
};
class AstNodeCoverDecl VL_NOT_FINAL : public AstNodeStmt {
// Coverage analysis point declaration
//
// [After V3CoverageJoin] Duplicate declaration to get data from instead
// @astgen ptr := m_dataDeclp : Optional[AstNodeCoverDecl]
string m_page; // Coverage point's page tag
string m_text; // Coverage point's text
string m_hier; // Coverage point's hierarchy
int m_binNum = 0; // Set by V3EmitCSyms to tell final V3Emit what to increment
public:
AstNodeCoverDecl(VNType t, FileLine* fl, const string& page, const string& comment)
: AstNodeStmt(t, fl)
, m_page{page}
, m_text{comment} {}
ASTGEN_MEMBERS_AstNodeCoverDecl;
const char* broken() const override {
if (m_dataDeclp
&& (m_dataDeclp == this || m_dataDeclp->m_dataDeclp)) { // Avoid O(n^2) accessing
v3fatalSrc("dataDeclp should point to real data, not be a list: " << cvtToHex(this));
}
return nullptr;
}
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
int instrCount() const override { return 1 + 2 * INSTR_COUNT_LD; }
bool maybePointedTo() const override VL_MT_SAFE { return true; }
int binNum() const { return m_binNum; }
void binNum(int flag) { m_binNum = flag; }
virtual int size() const = 0;
const string& comment() const { return m_text; } // text to insert in code
const string& page() const { return m_page; }
const string& hier() const { return m_hier; }
void hier(const string& flag) { m_hier = flag; }
void comment(const string& flag) { m_text = flag; }
bool sameNode(const AstNode* samep) const override {
const AstNodeCoverDecl* const asamep = VN_DBG_AS(samep, NodeCoverDecl);
return (fileline() == asamep->fileline() && hier() == asamep->hier()
&& comment() == asamep->comment() && page() == asamep->page());
}
bool isPredictOptimizable() const override { return false; }
void dataDeclp(AstNodeCoverDecl* nodep) { m_dataDeclp = nodep; }
// dataDecl nullptr means "use this one", but often you want "this" to
// indicate to get data from here
AstNodeCoverDecl* dataDeclNullp() const { return m_dataDeclp; }
AstNodeCoverDecl* dataDeclThisp() { return dataDeclNullp() ? dataDeclNullp() : this; }
};
class AstNodeCoverOrAssert VL_NOT_FINAL : public AstNodeStmt {
// Cover or Assert
// Parents: {statement list}
@ -2978,64 +3024,15 @@ public:
return true; // SPECIAL: We don't process code after breaks
}
};
class AstCoverDecl final : public AstNodeStmt {
// Coverage analysis point declaration
//
// [After V3CoverageJoin] Duplicate declaration to get data from instead
// @astgen ptr := m_dataDeclp : Optional[AstCoverDecl]
string m_page;
string m_text;
string m_hier;
string m_linescov;
int m_offset; // Offset column numbers to uniq-ify IFs
int m_binNum = 0; // Set by V3EmitCSyms to tell final V3Emit what to increment
public:
AstCoverDecl(FileLine* fl, const string& page, const string& comment, const string& linescov,
int offset)
: ASTGEN_SUPER_CoverDecl(fl)
, m_page{page}
, m_text{comment}
, m_linescov{linescov}
, m_offset{offset} {}
ASTGEN_MEMBERS_AstCoverDecl;
const char* broken() const override {
if (m_dataDeclp
&& (m_dataDeclp == this || m_dataDeclp->m_dataDeclp)) { // Avoid O(n^2) accessing
v3fatalSrc("dataDeclp should point to real data, not be a list: " << cvtToHex(this));
}
return nullptr;
}
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
int instrCount() const override { return 1 + 2 * INSTR_COUNT_LD; }
bool maybePointedTo() const override VL_MT_SAFE { return true; }
int binNum() const { return m_binNum; }
void binNum(int flag) { m_binNum = flag; }
int offset() const { return m_offset; }
const string& comment() const { return m_text; } // text to insert in code
const string& linescov() const { return m_linescov; }
const string& page() const { return m_page; }
const string& hier() const { return m_hier; }
void hier(const string& flag) { m_hier = flag; }
void comment(const string& flag) { m_text = flag; }
bool sameNode(const AstNode* samep) const override {
const AstCoverDecl* const asamep = VN_DBG_AS(samep, CoverDecl);
return (fileline() == asamep->fileline() && linescov() == asamep->linescov()
&& hier() == asamep->hier() && comment() == asamep->comment());
}
bool isPredictOptimizable() const override { return false; }
void dataDeclp(AstCoverDecl* nodep) { m_dataDeclp = nodep; }
// dataDecl nullptr means "use this one", but often you want "this" to
// indicate to get data from here
AstCoverDecl* dataDeclNullp() const { return m_dataDeclp; }
AstCoverDecl* dataDeclThisp() { return dataDeclNullp() ? dataDeclNullp() : this; }
};
class AstCoverInc final : public AstNodeStmt {
// Coverage analysis point; increment coverage count
// @astgen op1 := toggleExprp : Optional[AstNodeExpr] // [After V3Clock]
// @astgen op2 := toggleCovExprp : Optional[AstNodeExpr] // [After V3Clock]
// These are expressions to which the node corresponds. Used only in toggle coverage
//
// @astgen ptr := m_declp : AstCoverDecl // [After V3CoverageJoin] Declaration
// @astgen ptr := m_declp : AstNodeCoverDecl // [After V3CoverageJoin] Declaration
public:
AstCoverInc(FileLine* fl, AstCoverDecl* declp)
AstCoverInc(FileLine* fl, AstNodeCoverDecl* declp)
: ASTGEN_SUPER_CoverInc(fl)
, m_declp{declp} {}
ASTGEN_MEMBERS_AstCoverInc;
@ -3049,7 +3046,7 @@ public:
bool isPredictOptimizable() const override { return false; }
bool isOutputter() override { return true; }
bool isPure() override { return false; }
AstCoverDecl* declp() const { return m_declp; } // Where defined
AstNodeCoverDecl* declp() const { return m_declp; } // Where defined
};
class AstCoverToggle final : public AstNodeStmt {
// Toggle analysis of given signal
@ -3912,6 +3909,47 @@ public:
: ASTGEN_SUPER_GenCase(fl, exprp, itemsp) {}
ASTGEN_MEMBERS_AstGenCase;
};
class AstCoverOtherDecl final : public AstNodeCoverDecl {
// Coverage analysis point declaration
// Used for other than toggle types of coverage
string m_linescov;
int m_offset; // Offset column numbers to uniq-ify IFs
public:
AstCoverOtherDecl(FileLine* fl, const string& page, const string& comment,
const string& linescov, int offset)
: ASTGEN_SUPER_CoverOtherDecl(fl, page, comment)
, m_linescov{linescov}
, m_offset{offset} {}
ASTGEN_MEMBERS_AstCoverOtherDecl;
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
int offset() const { return m_offset; }
int size() const override { return 1; }
const string& linescov() const { return m_linescov; }
bool sameNode(const AstNode* samep) const override {
const AstCoverOtherDecl* const asamep = VN_DBG_AS(samep, CoverOtherDecl);
return AstNodeCoverDecl::sameNode(samep) && linescov() == asamep->linescov();
}
};
class AstCoverToggleDecl final : public AstNodeCoverDecl {
// Coverage analysis point declaration
// Used for toggle coverage
const VNumRange m_range; // Packed array range covering each toggle bit
public:
AstCoverToggleDecl(FileLine* fl, const string& page, const string& comment,
const VNumRange& range)
: ASTGEN_SUPER_CoverToggleDecl(fl, page, comment)
, m_range{range} {}
ASTGEN_MEMBERS_AstCoverToggleDecl;
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
int size() const override { return m_range.elements(); }
const VNumRange& range() const { return m_range; }
bool sameNode(const AstNode* samep) const override {
const AstCoverToggleDecl* const asamep = VN_DBG_AS(samep, CoverToggleDecl);
return AstNodeCoverDecl::sameNode(samep) && range() == asamep->range();
}
};
// === AstNodeCoverOrAssert ===
class AstAssert final : public AstNodeCoverOrAssert {

View File

@ -189,6 +189,12 @@ void AstNodeCond::numberOperate(V3Number& out, const V3Number& lhs, const V3Numb
}
}
void AstAddrOfCFunc::dump(std::ostream& str) const {
this->AstNodeExpr::dump(str);
str << " -> ";
funcp()->dump(str);
}
void AstBasicDType::init(VBasicDTypeKwd kwd, VSigning numer, int wantwidth, int wantwidthmin,
AstRange* rangep) {
// wantwidth=0 means figure it out, but if a widthmin is >=0
@ -1110,6 +1116,9 @@ AstNode* AstArraySel::baseFromp(AstNode* nodep, bool overMembers) {
} else if (overMembers && VN_IS(nodep, MemberSel)) {
nodep = VN_AS(nodep, MemberSel)->fromp();
continue;
} else if (overMembers && VN_IS(nodep, StructSel)) {
nodep = VN_AS(nodep, StructSel)->fromp();
continue;
}
// AstNodePreSel stashes the associated variable under an ATTROF
// of VAttrType::VAR_BASE so it isn't constified
@ -2861,10 +2870,9 @@ void AstBegin::dumpJson(std::ostream& str) const {
dumpJsonBoolFunc(str, needProcess);
dumpJsonGen(str);
}
void AstCoverDecl::dump(std::ostream& str) const {
void AstNodeCoverDecl::dump(std::ostream& str) const {
this->AstNodeStmt::dump(str);
if (!page().empty()) str << " page=" << page();
if (!linescov().empty()) str << " lc=" << linescov();
if (this->dataDeclNullp()) {
static bool s_recursing = false;
str << " -> ";
@ -2879,12 +2887,30 @@ void AstCoverDecl::dump(std::ostream& str) const {
if (binNum()) str << " bin" << std::dec << binNum();
}
}
void AstCoverDecl::dumpJson(std::ostream& str) const {
void AstNodeCoverDecl::dumpJson(std::ostream& str) const {
dumpJsonStrFunc(str, page);
dumpJsonStrFunc(str, linescov);
dumpJsonNumFunc(str, binNum);
dumpJsonGen(str);
}
void AstCoverOtherDecl::dump(std::ostream& str) const {
this->AstNodeCoverDecl::dump(str);
if (!linescov().empty()) str << " lc=" << linescov();
}
void AstCoverOtherDecl::dumpJson(std::ostream& str) const {
this->AstNodeCoverDecl::dumpJson(str);
dumpJsonStrFunc(str, linescov);
}
void AstCoverToggleDecl::dump(std::ostream& str) const {
this->AstNodeCoverDecl::dump(str);
if (range().ranged()) str << " range=[" << range().left() << ":" << range().right() << "]";
}
void AstCoverToggleDecl::dumpJson(std::ostream& str) const {
this->AstNodeCoverDecl::dumpJson(str);
if (range().ranged()) {
dumpJsonStr(str, "range",
std::to_string(range().left()) + ":" + std::to_string(range().right()));
}
}
void AstCoverInc::dump(std::ostream& str) const {
this->AstNodeStmt::dump(str);
str << " -> ";

View File

@ -289,7 +289,7 @@ class BeginVisitor final : public VNVisitor {
}
iterateChildren(nodep);
}
void visit(AstCoverDecl* nodep) override {
void visit(AstNodeCoverDecl* nodep) override {
// Don't need to fix path in coverage statements, they're not under
// any BEGINs, but V3Coverage adds them all under the module itself.
iterateChildren(nodep);
@ -530,7 +530,11 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) {
}
// The parser validates we don't have "foreach (array[,,,])"
AstNode* const bodyp = nodep->stmtsp();
UASSERT_OBJ(newp, nodep, "foreach has no non-empty loop variable");
if (!newp) {
nodep->v3warn(NOEFFECT, "foreach with no loop variable has no effect");
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return nullptr;
}
if (bodyp) {
bodyPointp->replaceWith(bodyp->unlinkFrBackWithNext());
} else {

View File

@ -161,10 +161,10 @@ class CCtorsVisitor final : public VNVisitor {
if (v3Global.opt.coverage()) {
V3CCtorsBuilder configure_coverage{nodep, "_configure_coverage", VCtorType::COVERAGE};
for (AstNode* np = nodep->stmtsp(); np; np = np->nextp()) {
if (AstCoverDecl* const coverp = VN_CAST(np, CoverDecl)) {
if (AstNodeCoverDecl* const coverp = VN_CAST(np, NodeCoverDecl)) {
// ... else we don't have a static VlSym to be able to coverage insert
UASSERT_OBJ(!VN_IS(nodep, Class), coverp,
"CoverDecl should be in class's package, not class itself");
"NodeCoverDecl should be in class's package, not class itself");
np = coverp->backp();
configure_coverage.add(coverp->unlinkFrBack());
}

View File

@ -175,7 +175,7 @@ class ClassVisitor final : public VNVisitor {
// m_toScopeMoves.emplace_back(nodep, m_classScopep);
//}
}
void visit(AstCoverDecl* nodep) override {
void visit(AstNodeCoverDecl* nodep) override {
// Need to declare coverage in package, where we have access to symbol table
iterateChildren(nodep);
if (m_classPackagep) m_classPackagep->addStmtsp(nodep->unlinkFrBack());

View File

@ -100,18 +100,20 @@ class ClockVisitor final : public VNVisitor {
// if (debug()) nodep->dumpTree("- ct: ");
// COVERTOGGLE(INC, ORIG, CHANGE) ->
// IF(ORIG ^ CHANGE) { INC; CHANGE = ORIG; }
AstNode* const incp = nodep->incp()->unlinkFrBack();
AstCoverInc* const incp = nodep->incp()->unlinkFrBack();
AstNodeExpr* const origp = nodep->origp()->unlinkFrBack();
AstNodeExpr* const changeWrp = nodep->changep()->unlinkFrBack();
AstNodeExpr* const changeRdp = ConvertWriteRefsToRead::main(changeWrp->cloneTree(false));
AstNodeExpr* comparedp = nullptr;
incp->toggleExprp(origp->cloneTree(false));
incp->toggleCovExprp(changeRdp->cloneTree(false));
// Xor will optimize better than Eq, when CoverToggle has bit selects,
// but can only use Xor with non-opaque types
if (const AstBasicDType* const bdtypep
= VN_CAST(origp->dtypep()->skipRefp(), BasicDType)) {
if (!bdtypep->isOpaque()) comparedp = new AstXor{nodep->fileline(), origp, changeRdp};
}
if (!comparedp) comparedp = AstEq::newTyped(nodep->fileline(), origp, changeRdp);
UASSERT_OBJ(comparedp, nodep, "Toggle coverage of non-opaque type variable");
AstIf* const newp = new AstIf{nodep->fileline(), comparedp, incp};
// We could add another IF to detect posedges, and only increment if so.
// It's another whole branch though versus a potential memory miss.

View File

@ -1267,8 +1267,12 @@ class ConstVisitor final : public VNVisitor {
&& nodep->lhsp()->isPure());
}
bool operandIsTwo(const AstNode* nodep) {
return (VN_IS(nodep, Const) && !VN_AS(nodep, Const)->num().isFourState()
&& nodep->width() <= VL_QUADSIZE && VN_AS(nodep, Const)->toUQuad() == 2);
const AstConst* const constp = VN_CAST(nodep, Const);
if (!constp) return false; // not constant
if (constp->num().isFourState()) return false; // four-state
if (nodep->width() > VL_QUADSIZE) return false; // too wide
if (nodep->isSigned() && constp->num().isNegative()) return false; // signed and negative
return constp->toUQuad() == 2;
}
bool operandIsTwostate(const AstNode* nodep) {
return (VN_IS(nodep, Const) && !VN_AS(nodep, Const)->num().isFourState());
@ -3550,6 +3554,7 @@ class ConstVisitor final : public VNVisitor {
TREEOP ("AstDiv {$lhsp, operandIsPowTwo($rhsp)}", "replaceDivShift(nodep)"); // a/2^n -> a>>n
TREEOP ("AstModDiv{$lhsp, operandIsPowTwo($rhsp)}", "replaceModAnd(nodep)"); // a % 2^n -> a&(2^n-1)
TREEOP ("AstPow {operandIsTwo($lhsp), !$rhsp.isZero}", "replacePowShift(nodep)"); // 2**a == 1<<a
TREEOP ("AstPowSU {operandIsTwo($lhsp), !$rhsp.isZero}", "replacePowShift(nodep)"); // 2**a == 1<<a
TREEOP ("AstSub {$lhsp.castAdd, operandSubAdd(nodep)}", "AstAdd{AstSub{$lhsp->castAdd()->lhsp(),$rhsp}, $lhsp->castAdd()->rhsp()}"); // ((a+x)-y) -> (a+(x-y))
TREEOPC("AstAnd {$lhsp.isOne, matchRedundantClean(nodep)}", "DONE") // 1 & (a == b) -> (IData)(a == b)
// Trinary ops

View File

@ -39,17 +39,28 @@ class ExprCoverageEligibleVisitor final : public VNVisitor {
// STATE
bool m_eligible = true;
static bool elemDTypeEligible(const AstNodeDType* dtypep) {
dtypep = dtypep->skipRefp();
if (AstNodeDType* const dtp = dtypep->virtRefDTypep()) {
if (!elemDTypeEligible(dtp)) return false;
}
if (AstNodeDType* const dtp = dtypep->virtRefDType2p()) {
if (!elemDTypeEligible(dtp)) return false;
}
return !VN_IS(dtypep, ClassRefDType);
}
void visit(AstNodeVarRef* nodep) override {
AstNodeDType* dtypep = nodep->varp()->dtypep();
// Class objecs and references not supported for expression coverage
// Class objects and references not supported for expression coverage
// because the object may not persist until the point at which
// coverage data is gathered
// This could be resolved in the future by protecting against dereferrencing
// null pointers when cloning the expression for expression coverage
if (VN_CAST(dtypep, ClassRefDType)) {
m_eligible = false;
} else {
if (dtypep && elemDTypeEligible(dtypep)) {
iterateChildren(nodep);
} else {
m_eligible = false;
}
}
@ -169,22 +180,8 @@ class CoverageVisitor final : public VNVisitor {
return nullptr;
}
AstCoverInc* newCoverInc(FileLine* fl, const string& hier, const string& page_prefix,
const string& comment, const string& linescov, int offset,
AstCoverInc* newCoverInc(FileLine* fl, AstNodeCoverDecl* const declp,
const string& trace_var_name) {
// We could use the basename of the filename to the page, but seems
// better for code from an include file to be listed under the
// module using it rather than the include file.
// Note the module name could have parameters appended, we'll consider this
// a feature as it allows for each parameterized block to be counted separately.
// Someday the user might be allowed to specify a different page suffix
const string page = page_prefix + "/" + m_modp->prettyName();
AstCoverDecl* const declp = new AstCoverDecl{fl, page, comment, linescov, offset};
declp->hier(hier);
m_modp->addStmtsp(declp);
UINFO(9, "new " << declp);
AstCoverInc* const incp = new AstCoverInc{fl, declp};
if (!trace_var_name.empty()
&& v3Global.opt.traceCoverage()
@ -306,9 +303,12 @@ class CoverageVisitor final : public VNVisitor {
iterateAndNextNull(nodep->stmtsp());
if (m_state.lineCoverageOn(nodep)) {
lineTrack(nodep);
AstCoverOtherDecl* const declp
= new AstCoverOtherDecl{nodep->fileline(), "v_line/" + m_modp->prettyName(),
"block", linesCov(m_state, nodep), 0};
m_modp->addStmtsp(declp);
AstNode* const newp
= newCoverInc(nodep->fileline(), "", "v_line", "block", linesCov(m_state, nodep),
0, traceNameForLine(nodep, "block"));
= newCoverInc(nodep->fileline(), declp, traceNameForLine(nodep, "block"));
insertProcStatement(nodep, newp);
}
}
@ -344,9 +344,12 @@ class CoverageVisitor final : public VNVisitor {
iterateChildren(nodep);
if (m_state.lineCoverageOn(nodep)) {
lineTrack(nodep);
AstCoverOtherDecl* const declp
= new AstCoverOtherDecl{nodep->fileline(), "v_line/" + m_modp->prettyName(),
"block", linesCov(m_state, nodep), 0};
m_modp->addStmtsp(declp);
AstNode* const newp
= newCoverInc(nodep->fileline(), "", "v_line", "block", linesCov(m_state, nodep),
0, traceNameForLine(nodep, "block"));
= newCoverInc(nodep->fileline(), declp, traceNameForLine(nodep, "block"));
insertProcStatement(nodep, newp);
}
}
@ -392,35 +395,23 @@ class CoverageVisitor final : public VNVisitor {
}
}
void toggleVarBottom(const ToggleEnt& above, const AstVar* varp) {
void toggleVarBottom(const ToggleEnt& above, const AstVar* varp, const VNumRange& range) {
const std::string hierPrefix
= (m_beginHier != "") ? AstNode::prettyName(m_beginHier) + "." : "";
AstCoverToggleDecl* const declp
= new AstCoverToggleDecl{varp->fileline(), "v_toggle/" + m_modp->prettyName(),
hierPrefix + varp->name() + above.m_comment, range};
m_modp->addStmtsp(declp);
AstCoverToggle* const newp = new AstCoverToggle{
varp->fileline(),
newCoverInc(varp->fileline(), "", "v_toggle",
hierPrefix + varp->name() + above.m_comment, "", 0, ""),
varp->fileline(), newCoverInc(varp->fileline(), declp, ""),
above.m_varRefp->cloneTree(false), above.m_chgRefp->cloneTree(false)};
m_modp->addStmtsp(newp);
}
void toggleVarRecurse(const AstNodeDType* const dtypep, const int depth, // per-iteration
const ToggleEnt& above, const AstVar* const varp) { // Constant
if (const AstBasicDType* const bdtypep = VN_CAST(dtypep, BasicDType)) {
if (bdtypep->isRanged()) {
for (int index_docs = bdtypep->lo(); index_docs < bdtypep->hi() + 1;
++index_docs) {
const int index_code = index_docs - bdtypep->lo();
ToggleEnt newent{above.m_comment + "["s + cvtToStr(index_docs) + "]",
new AstSel{varp->fileline(),
above.m_varRefp->cloneTree(false), index_code, 1},
new AstSel{varp->fileline(),
above.m_chgRefp->cloneTree(false), index_code, 1}};
toggleVarBottom(newent, varp);
newent.cleanup();
}
} else {
toggleVarBottom(above, varp);
}
if (const AstBasicDType* const basicp = VN_CAST(dtypep, BasicDType)) {
toggleVarBottom(above, varp, basicp->nrange());
} else if (const AstUnpackArrayDType* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) {
const int index_code = index_docs - adtypep->lo();
@ -533,20 +524,26 @@ class CoverageVisitor final : public VNVisitor {
iterate(nodep->thenp());
lineTrack(nodep);
AstNodeExpr* const thenp = nodep->thenp()->unlinkFrBack();
nodep->thenp(new AstExprStmt{thenp->fileline(),
newCoverInc(nodep->fileline(), "", "v_branch",
"cond_then", linesCov(m_state, nodep), 0,
traceNameForLine(nodep, "cond_then")),
thenp});
AstCoverOtherDecl* const thenDeclp
= new AstCoverOtherDecl{thenp->fileline(), "v_branch/" + m_modp->prettyName(),
"cond_then", linesCov(m_state, nodep), 0};
m_modp->addStmtsp(thenDeclp);
nodep->thenp(new AstExprStmt{
thenp->fileline(),
newCoverInc(nodep->fileline(), thenDeclp, traceNameForLine(nodep, "cond_then")),
thenp});
m_state = lastState;
createHandle(nodep);
iterate(nodep->elsep());
AstNodeExpr* const elsep = nodep->elsep()->unlinkFrBack();
nodep->elsep(new AstExprStmt{elsep->fileline(),
newCoverInc(nodep->fileline(), "", "v_branch",
"cond_else", linesCov(m_state, nodep), 1,
traceNameForLine(nodep, "cond_else")),
elsep});
AstCoverOtherDecl* const elseDeclp
= new AstCoverOtherDecl{thenp->fileline(), "v_branch/" + m_modp->prettyName(),
"cond_else", linesCov(m_state, nodep), 1};
m_modp->addStmtsp(elseDeclp);
nodep->elsep(new AstExprStmt{
elsep->fileline(),
newCoverInc(nodep->fileline(), elseDeclp, traceNameForLine(nodep, "cond_else")),
elsep});
m_state = lastState;
} else {
@ -603,22 +600,32 @@ class CoverageVisitor final : public VNVisitor {
// Normal if. Linecov shows what's inside the if (not condition that is
// always executed)
UINFO(4, " COVER-branch: " << nodep);
nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_branch", "if",
linesCov(ifState, nodep), 0,
traceNameForLine(nodep, "if")));
AstCoverOtherDecl* const ifDeclp
= new AstCoverOtherDecl{nodep->fileline(), "v_branch/" + m_modp->prettyName(),
"if", linesCov(ifState, nodep), 0};
m_modp->addStmtsp(ifDeclp);
nodep->addThensp(
newCoverInc(nodep->fileline(), ifDeclp, traceNameForLine(nodep, "if")));
// The else has a column offset of 1 to uniquify it relative to the if
// As "if" and "else" are more than one character wide, this won't overlap
// another token
nodep->addElsesp(newCoverInc(nodep->fileline(), "", "v_branch", "else",
linesCov(elseState, nodep), 1,
traceNameForLine(nodep, "else")));
AstCoverOtherDecl* const elseDeclp
= new AstCoverOtherDecl{nodep->fileline(), "v_branch/" + m_modp->prettyName(),
"else", linesCov(elseState, nodep), 1};
m_modp->addStmtsp(elseDeclp);
nodep->addElsesp(
newCoverInc(nodep->fileline(), elseDeclp, traceNameForLine(nodep, "else")));
}
// If/else attributes to each block as non-branch coverage
else if (first_elsif || cont_elsif) {
UINFO(4, " COVER-elsif: " << nodep);
if (ifState.lineCoverageOn(nodep)) {
nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_line", "elsif",
linesCov(ifState, nodep), 0,
AstCoverOtherDecl* const elsifDeclp = new AstCoverOtherDecl{
nodep->fileline(), "v_line/" + m_modp->prettyName(), "elsif",
linesCov(ifState, nodep), 0};
m_modp->addStmtsp(elsifDeclp);
nodep->addThensp(newCoverInc(nodep->fileline(), elsifDeclp,
traceNameForLine(nodep, "elsif")));
}
// and we don't insert the else as the child if-else will do so
@ -626,14 +633,21 @@ class CoverageVisitor final : public VNVisitor {
// Cover as separate blocks (not a branch as is not two-legged)
if (ifState.lineCoverageOn(nodep)) {
UINFO(4, " COVER-half-if: " << nodep);
nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_line", "if",
linesCov(ifState, nodep), 0,
traceNameForLine(nodep, "if")));
AstCoverOtherDecl* const ifDeclp = new AstCoverOtherDecl{
nodep->fileline(), "v_line/" + m_modp->prettyName(), "if",
linesCov(ifState, nodep), 0};
m_modp->addStmtsp(ifDeclp);
nodep->addThensp(
newCoverInc(nodep->fileline(), ifDeclp, traceNameForLine(nodep, "if")));
}
if (elseState.lineCoverageOn(nodep)) {
UINFO(4, " COVER-half-el: " << nodep);
nodep->addElsesp(newCoverInc(nodep->fileline(), "", "v_line", "else",
linesCov(elseState, nodep), 1,
AstCoverOtherDecl* const elseDeclp = new AstCoverOtherDecl{
nodep->fileline(), "v_line/" + m_modp->prettyName(), "else",
linesCov(elseState, nodep), 1};
m_modp->addStmtsp(elseDeclp);
nodep->addElsesp(newCoverInc(nodep->fileline(), elseDeclp,
traceNameForLine(nodep, "else")));
}
}
@ -655,9 +669,12 @@ class CoverageVisitor final : public VNVisitor {
if (m_state.lineCoverageOn(nodep)) { // if the case body didn't disable it
lineTrack(nodep);
UINFO(4, " COVER: " << nodep);
nodep->addStmtsp(newCoverInc(nodep->fileline(), "", "v_line", "case",
linesCov(m_state, nodep), 0,
traceNameForLine(nodep, "case")));
AstCoverOtherDecl* const declp
= new AstCoverOtherDecl{nodep->fileline(), "v_line/" + m_modp->prettyName(),
"case", linesCov(m_state, nodep), 0};
m_modp->addStmtsp(declp);
nodep->addStmtsp(
newCoverInc(nodep->fileline(), declp, traceNameForLine(nodep, "case")));
}
}
}
@ -670,9 +687,13 @@ class CoverageVisitor final : public VNVisitor {
if (!nodep->coverincsp() && v3Global.opt.coverageUser()) {
// Note the name may be overridden by V3Assert processing
lineTrack(nodep);
nodep->addCoverincsp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover",
linesCov(m_state, nodep), 0,
m_beginHier + "_vlCoverageUserTrace"));
AstCoverOtherDecl* const declp
= new AstCoverOtherDecl{nodep->fileline(), "v_user/" + m_modp->prettyName(),
"cover", linesCov(m_state, nodep), 0};
declp->hier(m_beginHier);
m_modp->addStmtsp(declp);
nodep->addCoverincsp(
newCoverInc(nodep->fileline(), declp, m_beginHier + "_vlCoverageUserTrace"));
}
}
void visit(AstStop* nodep) override {
@ -744,8 +765,10 @@ class CoverageVisitor final : public VNVisitor {
}
comment += ") => ";
comment += (m_objective ? '1' : '0');
AstNode* const newp
= newCoverInc(fl, "", "v_expr", comment, "", 0, traceNameForLine(nodep, name));
AstCoverOtherDecl* const declp = new AstCoverOtherDecl{
nodep->fileline(), "v_expr/" + m_modp->prettyName(), comment, "", 0};
m_modp->addStmtsp(declp);
AstNode* const newp = newCoverInc(fl, declp, traceNameForLine(nodep, name));
UASSERT_OBJ(condp, nodep, "No terms in expression coverage branch");
AstIf* const ifp = new AstIf{fl, condp, newp, nullptr};
ifp->user2(true);
@ -858,7 +881,6 @@ class CoverageVisitor final : public VNVisitor {
!= strs[!term.m_objective].end())
impossible = true;
}
if (!redundant) expr.push_back(term);
}
if (!impossible) m_exprs.push_back(std::move(expr));

View File

@ -75,7 +75,7 @@ class CoverageJoinVisitor final : public VNVisitor {
// The CoverDecl the duplicate pointed to now needs to point to the
// original's data. I.e. the duplicate will get the coverage number
// from the non-duplicate
AstCoverDecl* const datadeclp = nodep->incp()->declp()->dataDeclThisp();
AstNodeCoverDecl* const datadeclp = nodep->incp()->declp()->dataDeclThisp();
removep->incp()->declp()->dataDeclp(datadeclp);
UINFO(8, " new " << removep->incp()->declp());
// Mark the found node as a duplicate of the first node

View File

@ -97,6 +97,16 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
vtxp2clonep.emplace(&vtx, cp);
break;
}
case VDfgType::atSpliceArray: {
DfgSpliceArray* const cp = new DfgSpliceArray{*clonep, vtx.fileline(), vtx.dtypep()};
vtxp2clonep.emplace(&vtx, cp);
break;
}
case VDfgType::atSplicePacked: {
DfgSplicePacked* const cp = new DfgSplicePacked{*clonep, vtx.fileline(), vtx.dtypep()};
vtxp2clonep.emplace(&vtx, cp);
break;
}
default: {
vtx.v3fatalSrc("Unhandled operation vertex type: " + vtx.typeName());
VL_UNREACHABLE;
@ -109,49 +119,55 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
// Constants have no inputs
// Hook up inputs of cloned variables
for (const DfgVertexVar& vtx : m_varVertices) {
switch (vtx.type()) {
case VDfgType::atVarArray: {
const DfgVarArray* const vp = vtx.as<DfgVarArray>();
DfgVarArray* const cp = vtxp2clonep.at(vp)->as<DfgVarArray>();
vp->forEachSourceEdge([&](const DfgEdge& edge, size_t i) {
if (DfgVertex* const srcp = edge.sourcep()) {
cp->addDriver(vp->driverFileLine(i), //
vp->driverIndex(i), //
vtxp2clonep.at(srcp));
}
});
break;
}
case VDfgType::atVarPacked: {
const DfgVarPacked* const vp = vtx.as<DfgVarPacked>();
DfgVarPacked* const cp = vtxp2clonep.at(vp)->as<DfgVarPacked>();
vp->forEachSourceEdge([&](const DfgEdge& edge, size_t i) {
if (DfgVertex* const srcp = edge.sourcep()) {
cp->addDriver(vp->driverFileLine(i), //
vp->driverLsb(i), //
vtxp2clonep.at(srcp));
}
});
break;
}
default: {
vtx.v3fatalSrc("Unhandled variable vertex type: " + vtx.typeName());
VL_UNREACHABLE;
break;
}
// All variable vertices are unary
if (DfgVertex* const srcp = vtx.srcp()) {
vtxp2clonep.at(&vtx)->as<DfgVertexVar>()->srcp(vtxp2clonep.at(srcp));
}
}
// Hook up inputs of cloned operation vertices
for (const DfgVertex& vtx : m_opVertices) {
DfgVertex* const cp = vtxp2clonep.at(&vtx);
// The code below doesn't work for DfgVertexVariadic, but none of the opVertices are such.
UASSERT_OBJ(!vtx.is<DfgVertexVariadic>(), &vtx, "DfgVertexVariadic not handled");
const auto oSourceEdges = vtx.sourceEdges();
auto cSourceEdges = cp->sourceEdges();
UASSERT_OBJ(oSourceEdges.second == cSourceEdges.second, &vtx, "Mismatched source count");
for (size_t i = 0; i < oSourceEdges.second; ++i) {
if (DfgVertex* const srcp = oSourceEdges.first[i].sourcep()) {
cSourceEdges.first[i].relinkSource(vtxp2clonep.at(srcp));
if (vtx.is<DfgVertexVariadic>()) {
switch (vtx.type()) {
case VDfgType::atSpliceArray: {
const DfgSpliceArray* const vp = vtx.as<DfgSpliceArray>();
DfgSpliceArray* const cp = vtxp2clonep.at(vp)->as<DfgSpliceArray>();
vp->forEachSourceEdge([&](const DfgEdge& edge, size_t i) {
if (DfgVertex* const srcp = edge.sourcep()) {
cp->addDriver(vp->driverFileLine(i), //
vp->driverIndex(i), //
vtxp2clonep.at(srcp));
}
});
break;
}
case VDfgType::atSplicePacked: {
const DfgSplicePacked* const vp = vtx.as<DfgSplicePacked>();
DfgSplicePacked* const cp = vtxp2clonep.at(vp)->as<DfgSplicePacked>();
vp->forEachSourceEdge([&](const DfgEdge& edge, size_t i) {
if (DfgVertex* const srcp = edge.sourcep()) {
cp->addDriver(vp->driverFileLine(i), //
vp->driverLsb(i), //
vtxp2clonep.at(srcp));
}
});
break;
}
default: {
vtx.v3fatalSrc("Unhandled DfgVertexVariadic sub type: " + vtx.typeName());
VL_UNREACHABLE;
break;
}
}
} else {
DfgVertex* const cp = vtxp2clonep.at(&vtx);
const auto oSourceEdges = vtx.sourceEdges();
auto cSourceEdges = cp->sourceEdges();
UASSERT_OBJ(oSourceEdges.second == cSourceEdges.second, &vtx,
"Mismatched source count");
for (size_t i = 0; i < oSourceEdges.second; ++i) {
if (DfgVertex* const srcp = oSourceEdges.first[i].sourcep()) {
cSourceEdges.first[i].relinkSource(vtxp2clonep.at(srcp));
}
}
}
}
@ -313,6 +329,25 @@ static void dumpDotVertex(std::ostream& os, const DfgVertex& vtx) {
return;
}
if (vtx.is<DfgVertexSplice>()) {
os << toDotId(vtx);
os << " [label=\"" << vtx.typeName() << "\n";
if (const DfgSpliceArray* const sp = vtx.cast<DfgSpliceArray>()) {
const int elements = VN_AS(sp->dtypep(), UnpackArrayDType)->elementsConst();
os << "_[" << elements << "]";
} else {
os << "W" << vtx.width();
}
os << " / F" << vtx.fanout() << '"';
if (vtx.hasMultipleSinks()) {
os << ", shape=doubleoctagon";
} else {
os << ", shape=octagon";
}
os << "]\n";
return;
}
os << toDotId(vtx);
os << " [label=\"" << vtx.typeName() << "\nW" << vtx.width() << " / F" << vtx.fanout() << '"';
if (vtx.hasMultipleSinks()) {
@ -336,7 +371,7 @@ static void dumpDotVertexAndSourceEdges(std::ostream& os, const DfgVertex& vtx)
vtx.forEachSourceEdge([&](const DfgEdge& edge, size_t idx) { //
if (edge.sourcep()) {
string headLabel;
if (vtx.arity() > 1 || vtx.is<DfgVertexVar>()) headLabel = vtx.srcName(idx);
if (vtx.arity() > 1 || vtx.is<DfgVertexSplice>()) headLabel = vtx.srcName(idx);
dumpDotEdge(os, edge, headLabel);
}
});
@ -521,24 +556,34 @@ bool DfgVertex::selfEquals(const DfgVertex& that) const { return true; }
V3Hash DfgVertex::selfHash() const { return V3Hash{}; }
bool DfgVertex::equals(const DfgVertex& that, EqualsCache& cache) const {
// If same vertex, then equal
if (this == &that) return true;
// If different type, then not equal
if (this->type() != that.type()) return false;
// If different data type, then not equal
if (this->dtypep() != that.dtypep()) return false;
// If different number of inputs, then not equal
auto thisPair = this->sourceEdges();
const DfgEdge* const thisSrcEdgesp = thisPair.first;
const size_t thisArity = thisPair.second;
auto thatPair = that.sourceEdges();
const DfgEdge* const thatSrcEdgesp = thatPair.first;
const size_t thatArity = thatPair.second;
if (thisArity != thatArity) return false;
// Check vertex specifics
if (!this->selfEquals(that)) return false;
// Check sources
const auto key = (this < &that) ? EqualsCache::key_type{this, &that} //
: EqualsCache::key_type{&that, this};
// Note: the recursive invocation can cause a re-hash but that will not invalidate references
uint8_t& result = cache[key];
if (!result) {
result = 2; // Assume equals
auto thisPair = this->sourceEdges();
const DfgEdge* const thisSrcEdgesp = thisPair.first;
const size_t thisArity = thisPair.second;
auto thatPair = that.sourceEdges();
const DfgEdge* const thatSrcEdgesp = thatPair.first;
const size_t thatArity = thatPair.second;
UASSERT_OBJ(thisArity == thatArity, this, "Same type vertices must have same arity!");
for (size_t i = 0; i < thisArity; ++i) {
const DfgVertex* const thisSrcVtxp = thisSrcEdgesp[i].m_sourcep;
const DfgVertex* const thatSrcVtxp = thatSrcEdgesp[i].m_sourcep;
@ -561,7 +606,12 @@ V3Hash DfgVertex::hash() {
// variables, which we rely on.
if (!is<DfgVertexVar>()) {
hash += m_type;
hash += width(); // Currently all non-variable vertices are packed, so this is safe
if (AstUnpackArrayDType* const adtypep = VN_CAST(dtypep(), UnpackArrayDType)) {
hash += adtypep->elementsConst();
// TODO: maybe include sub-dtype, but not hugely important at the moment
} else {
hash += width();
}
const auto pair = sourceEdges();
const DfgEdge* const edgesp = pair.first;
const size_t arity = pair.second;
@ -579,19 +629,16 @@ uint32_t DfgVertex::fanout() const {
return result;
}
DfgVarPacked* DfgVertex::getResultVar() {
UASSERT_OBJ(!this->is<DfgVarArray>(), this, "Arrays are not supported by " << __FUNCTION__);
DfgVertexVar* DfgVertex::getResultVar() {
// It's easy if the vertex is already a variable ...
if (DfgVarPacked* const varp = this->cast<DfgVarPacked>()) return varp;
if (DfgVertexVar* const varp = this->cast<DfgVertexVar>()) return varp;
// Inspect existing variables fully written by this vertex, and choose one
DfgVarPacked* resp = nullptr;
// Inspect existing variables written by this vertex, and choose one
DfgVertexVar* resp = nullptr;
// cppcheck-has-bug-suppress constParameter
this->forEachSink([&resp](DfgVertex& sink) {
DfgVarPacked* const varp = sink.cast<DfgVarPacked>();
DfgVertexVar* const varp = sink.cast<DfgVertexVar>();
if (!varp) return;
if (!varp->isDrivenFullyByDfg()) return;
// Ignore SystemC variables, they cannot participate in expressions or
// be assigned rvalue expressions.
if (varp->varp()->isSc()) return;
@ -694,6 +741,42 @@ bool DfgSel::selfEquals(const DfgVertex& that) const { return lsb() == that.as<D
V3Hash DfgSel::selfHash() const { return V3Hash{lsb()}; }
// DfgSpliceArray ----------
bool DfgSpliceArray::selfEquals(const DfgVertex& that) const {
const DfgSpliceArray* const thatp = that.as<DfgSpliceArray>();
const size_t arity = this->arity();
for (size_t i = 0; i < arity; ++i) {
if (driverIndex(i) != thatp->driverIndex(i)) return false;
}
return true;
}
V3Hash DfgSpliceArray::selfHash() const {
V3Hash hash;
const size_t arity = this->arity();
for (size_t i = 0; i < arity; ++i) hash += driverIndex(i);
return hash;
}
// DfgSplicePacked ----------
bool DfgSplicePacked::selfEquals(const DfgVertex& that) const {
const DfgSplicePacked* const thatp = that.as<DfgSplicePacked>();
const size_t arity = this->arity();
for (size_t i = 0; i < arity; ++i) {
if (driverLsb(i) != thatp->driverLsb(i)) return false;
}
return true;
}
V3Hash DfgSplicePacked::selfHash() const {
V3Hash hash;
const size_t arity = this->arity();
for (size_t i = 0; i < arity; ++i) hash += driverLsb(i);
return hash;
}
// DfgVertexVar ----------
bool DfgVertexVar::selfEquals(const DfgVertex& that) const {

View File

@ -238,8 +238,7 @@ public:
// Width of result
uint32_t width() const {
// This is a hot enough function that this is an expensive check, so in debug build only.
UDEBUGONLY(UASSERT_OBJ(VN_IS(dtypep(), BasicDType), this, "non-packed has no 'width()'"););
UASSERT_OBJ(VN_IS(dtypep(), BasicDType), this, "non-packed has no 'width()'");
return dtypep()->width();
}
@ -283,7 +282,7 @@ public:
// Return a canonical variable vertex that holds the value of this vertex,
// or nullptr if no such variable exists in the graph. This is O(fanout).
DfgVarPacked* getResultVar() VL_MT_DISABLED;
DfgVertexVar* getResultVar() VL_MT_DISABLED;
// Cache type for 'scopep' below
using ScopeCache = std::unordered_map<const DfgVertex*, AstScope*>;
@ -572,7 +571,7 @@ class DfgVertexVariadic VL_NOT_FINAL : public DfgVertex {
protected:
DfgVertexVariadic(DfgGraph& dfg, VDfgType type, FileLine* flp, AstNodeDType* dtypep,
uint32_t initialCapacity = 1)
uint32_t initialCapacity)
: DfgVertex{dfg, type, flp, dtypep}
, m_srcsp{allocSources(initialCapacity)}
, m_srcCap{initialCapacity} {}
@ -914,15 +913,14 @@ bool DfgVertex::isOnes() const {
// Inline method definitions - for DfgVertexVar
//------------------------------------------------------------------------------
DfgVertexVar::DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVar* varp, uint32_t initialCapacity)
: DfgVertexVariadic{dfg, type, varp->fileline(), dtypeFor(varp), initialCapacity}
DfgVertexVar::DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVar* varp)
: DfgVertexUnary{dfg, type, varp->fileline(), dtypeFor(varp)}
, m_varp{varp}
, m_varScopep{nullptr} {
UASSERT_OBJ(dfg.modulep(), varp, "Un-scoped DfgVertexVar created in scoped DfgGraph");
}
DfgVertexVar::DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVarScope* vscp,
uint32_t initialCapacity)
: DfgVertexVariadic{dfg, type, vscp->fileline(), dtypeFor(vscp), initialCapacity}
DfgVertexVar::DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVarScope* vscp)
: DfgVertexUnary{dfg, type, vscp->fileline(), dtypeFor(vscp)}
, m_varp{vscp->varp()}
, m_varScopep{vscp} {
UASSERT_OBJ(!dfg.modulep(), vscp, "Scoped DfgVertexVar created in un-scoped DfgGraph");

View File

@ -183,49 +183,37 @@ class AstToDfgVisitor final : public VNVisitor {
return m_foundUnhandled;
}
// Build DfgEdge representing the LValue assignment. Returns false if unsuccessful.
bool convertAssignment(FileLine* flp, AstNode* nodep, DfgVertex* vtxp) {
DfgVertexSplice* convertLValue(AstNode* nodep) {
FileLine* const flp = nodep->fileline();
if (AstVarRef* const vrefp = VN_CAST(nodep, VarRef)) {
m_foundUnhandled = false;
visit(vrefp);
// cppcheck-has-bug-suppress knownConditionTrueFalse
if (m_foundUnhandled) return false;
getVertex(vrefp)->template as<DfgVarPacked>()->addDriver(flp, 0, vtxp);
return true;
}
if (AstSel* const selp = VN_CAST(nodep, Sel)) {
AstVarRef* const vrefp = VN_CAST(selp->fromp(), VarRef);
const AstConst* const lsbp = VN_CAST(selp->lsbp(), Const);
if (!vrefp || !lsbp) {
++m_ctx.m_nonRepLhs;
return false;
if (m_foundUnhandled) return nullptr;
DfgVertexVar* const vtxp = getVertex(vrefp)->template as<DfgVertexVar>();
// Ensure driving splice vertex exists
if (!vtxp->srcp()) {
if (VN_IS(vtxp->dtypep(), UnpackArrayDType)) {
vtxp->srcp(new DfgSpliceArray{*m_dfgp, flp, vtxp->dtypep()});
} else {
vtxp->srcp(new DfgSplicePacked{*m_dfgp, flp, vtxp->dtypep()});
}
}
m_foundUnhandled = false;
visit(vrefp);
// cppcheck-has-bug-suppress knownConditionTrueFalse
if (m_foundUnhandled) return false;
getVertex(vrefp)->template as<DfgVarPacked>()->addDriver(flp, lsbp->toUInt(), vtxp);
return true;
}
if (AstArraySel* const selp = VN_CAST(nodep, ArraySel)) {
AstVarRef* const vrefp = VN_CAST(selp->fromp(), VarRef);
const AstConst* const idxp = VN_CAST(selp->bitp(), Const);
if (!vrefp || !idxp) {
++m_ctx.m_nonRepLhs;
return false;
}
m_foundUnhandled = false;
visit(vrefp);
// cppcheck-has-bug-suppress knownConditionTrueFalse
if (m_foundUnhandled) return false;
getVertex(vrefp)->template as<DfgVarArray>()->addDriver(flp, idxp->toUInt(), vtxp);
return true;
return vtxp->srcp()->as<DfgVertexSplice>();
}
++m_ctx.m_nonRepLhs;
return nullptr;
}
// Build DfgEdge representing the LValue assignment. Returns false if unsuccessful.
bool convertAssignment(FileLine* flp, AstNode* nodep, DfgVertex* vtxp) {
// Concatenation on the LHS. Select parts of the driving 'vtxp' then convert each part
if (AstConcat* const concatp = VN_CAST(nodep, Concat)) {
AstNode* const lhsp = concatp->lhsp();
AstNode* const rhsp = concatp->rhsp();
{
{ // Convet LHS of concat
FileLine* const lFlp = lhsp->fileline();
DfgSel* const lVtxp = new DfgSel{*m_dfgp, lFlp, DfgVertex::dtypeFor(lhsp)};
lVtxp->fromp(vtxp);
@ -233,7 +221,7 @@ class AstToDfgVisitor final : public VNVisitor {
if (!convertAssignment(flp, lhsp, lVtxp)) return false;
}
{
{ // Convert RHS of concat
FileLine* const rFlp = rhsp->fileline();
DfgSel* const rVtxp = new DfgSel{*m_dfgp, rFlp, DfgVertex::dtypeFor(rhsp)};
rVtxp->fromp(vtxp);
@ -241,7 +229,37 @@ class AstToDfgVisitor final : public VNVisitor {
return convertAssignment(flp, rhsp, rVtxp);
}
}
++m_ctx.m_nonRepLhs;
if (AstSel* const selp = VN_CAST(nodep, Sel)) {
AstVarRef* const vrefp = VN_CAST(selp->fromp(), VarRef);
const AstConst* const lsbp = VN_CAST(selp->lsbp(), Const);
if (!vrefp || !lsbp) {
++m_ctx.m_nonRepLhs;
return false;
}
if (DfgVertexSplice* const splicep = convertLValue(vrefp)) {
splicep->template as<DfgSplicePacked>()->addDriver(flp, lsbp->toUInt(), vtxp);
return true;
}
} else if (AstArraySel* const selp = VN_CAST(nodep, ArraySel)) {
AstVarRef* const vrefp = VN_CAST(selp->fromp(), VarRef);
const AstConst* const idxp = VN_CAST(selp->bitp(), Const);
if (!vrefp || !idxp) {
++m_ctx.m_nonRepLhs;
return false;
}
if (DfgVertexSplice* const splicep = convertLValue(vrefp)) {
splicep->template as<DfgSpliceArray>()->addDriver(flp, idxp->toUInt(), vtxp);
return true;
}
} else if (VN_IS(nodep, VarRef)) {
if (DfgVertexSplice* const splicep = convertLValue(nodep)) {
splicep->template as<DfgSplicePacked>()->addDriver(flp, 0, vtxp);
return true;
}
} else {
++m_ctx.m_nonRepLhs;
}
return false;
}
@ -315,18 +333,23 @@ class AstToDfgVisitor final : public VNVisitor {
for (DfgVarPacked* const varp : m_varPackedps) {
// Delete variables with no sinks nor sources (this can happen due to reverting
// uncommitted vertices, which does not remove variables)
if (!varp->hasSinks() && varp->arity() == 0) {
if (!varp->hasSinks() && !varp->srcp()) {
VL_DO_DANGLING(varp->unlinkDelete(*m_dfgp), varp);
continue;
}
// Nothing to do for un-driven (input) variables
if (!varp->srcp()) continue;
DfgSplicePacked* const splicep = varp->srcp()->as<DfgSplicePacked>();
// Gather (and unlink) all drivers
std::vector<Driver> drivers;
drivers.reserve(varp->arity());
varp->forEachSourceEdge([this, varp, &drivers](DfgEdge& edge, size_t idx) {
drivers.reserve(splicep->arity());
splicep->forEachSourceEdge([this, splicep, &drivers](DfgEdge& edge, size_t idx) {
DfgVertex* const driverp = edge.sourcep();
UASSERT(driverp, "Should not have created undriven sources");
addDriver(varp->driverFileLine(idx), varp->driverLsb(idx), driverp, drivers);
addDriver(splicep->driverFileLine(idx), splicep->driverLsb(idx), driverp, drivers);
edge.unlinkSource();
});
@ -424,10 +447,10 @@ class AstToDfgVisitor final : public VNVisitor {
}
// Reinsert drivers in order
varp->resetSources();
splicep->resetSources();
for (const Driver& driver : drivers) {
if (!driver.m_vtxp) break; // Stop at end of compacted list
varp->addDriver(driver.m_fileline, driver.m_lsb, driver.m_vtxp);
splicep->addDriver(driver.m_fileline, driver.m_lsb, driver.m_vtxp);
}
// Prune vertices potentially unused due to resolving multiple drivers.
@ -442,6 +465,15 @@ class AstToDfgVisitor final : public VNVisitor {
vtxp->forEachSource([&](DfgVertex& src) { prune.emplace(&src); });
vtxp->unlinkDelete(*m_dfgp);
}
// If the whole variable is driven, remove the splice node
if (splicep->arity() == 1 //
&& splicep->driverLsb(0) == 0 //
&& splicep->source(0)->width() == varp->width()) {
varp->srcp(splicep->source(0));
varp->driverFileLine(splicep->driverFileLine(0));
splicep->unlinkDelete(*m_dfgp);
}
}
}
@ -450,7 +482,7 @@ class AstToDfgVisitor final : public VNVisitor {
for (DfgVarArray* const varp : m_varArrayps) {
// Delete variables with no sinks nor sources (this can happen due to reverting
// uncommitted vertices, which does not remove variables)
if (!varp->hasSinks() && varp->arity() == 0) {
if (!varp->hasSinks() && !varp->srcp()) {
VL_DO_DANGLING(varp->unlinkDelete(*m_dfgp), varp);
}
}

View File

@ -363,7 +363,7 @@ class TraceDriver final : public DfgVisitor {
UINFO(9, "TraceDriver - Unhandled vertex type: " << vtxp->typeName());
}
void visit(DfgVarPacked* vtxp) override {
void visit(DfgSplicePacked* vtxp) override {
// Proceed with the driver that wholly covers the searched bits
const auto pair = vtxp->sourceEdges();
for (size_t i = 0; i < pair.second; ++i) {
@ -378,6 +378,13 @@ class TraceDriver final : public DfgVisitor {
}
}
void visit(DfgVarPacked* vtxp) override {
if (DfgVertex* const srcp = vtxp->srcp()) {
SET_RESULT(trace(srcp, m_msb, m_lsb));
return;
}
}
void visit(DfgConcat* vtxp) override {
DfgVertex* const rhsp = vtxp->rhsp();
DfgVertex* const lhsp = vtxp->lhsp();
@ -607,10 +614,7 @@ class IndependentBits final : public DfgVisitor {
mask(vtxp).setAllBits1(); // intentionally not using MASK here
}
void visit(DfgVarPacked* vtxp) override {
// The mask of the traced variable is known to be all ones
if (vtxp == m_varp) return;
void visit(DfgSplicePacked* vtxp) override {
// Combine the masks of all drivers
V3Number& m = MASK(vtxp);
vtxp->forEachSourceEdge([&](DfgEdge& edge, size_t i) {
@ -619,6 +623,14 @@ class IndependentBits final : public DfgVisitor {
});
}
void visit(DfgVarPacked* vtxp) override {
// The mask of the traced variable is known to be all ones
if (vtxp == m_varp) return;
// Combine the masks of all drivers
if (DfgVertex* const srcp = vtxp->srcp()) MASK(vtxp) = MASK(srcp);
}
void visit(DfgConcat* vtxp) override {
const DfgVertex* const rhsp = vtxp->rhsp();
const DfgVertex* const lhsp = vtxp->lhsp();
@ -732,6 +744,13 @@ class IndependentBits final : public DfgVisitor {
DfgVertex* const currp = m_workList.front();
m_workList.pop_front();
if (VN_IS(currp->dtypep(), UnpackArrayDType)) {
// For an unpacked array vertex, just enque it's sinks.
// (There can be no loops through arrays directly)
currp->forEachSink([&](DfgVertex& vtx) { m_workList.emplace_back(&vtx); });
continue;
}
// Grab current mask of item
const V3Number& maskCurr = mask(currp);
// Remember current mask
@ -764,16 +783,11 @@ public:
// so bits reported dependent might not actually be, but all bits reported
// independent are known to be so.
static V3Number apply(DfgVarPacked* varp) {
UASSERT_OBJ(varp->srcp(), varp, "Don't call on undriven variable");
IndependentBits independentBits{varp};
// Combine the masks of all drivers of the variable
// The mask represents the dependent bits, so invert it
V3Number result{varp->fileline(), static_cast<int>(varp->width()), 0};
varp->forEachSourceEdge([&](DfgEdge& edge, size_t i) {
const DfgVertex* const srcp = edge.sourcep();
// The mask represents the dependent bits, so invert it
V3Number inverseMask{srcp->fileline(), static_cast<int>(srcp->width()), 0};
inverseMask.opNot(independentBits.mask(srcp));
result.opSelInto(inverseMask, varp->driverLsb(i), srcp->width());
});
result.opNot(independentBits.mask(varp->srcp()));
return result;
}
};

View File

@ -341,32 +341,20 @@ class ExtractCyclicComponents final {
return *clonep;
}
// Fix up non-variable sources of a DfgVertexVar that are in a different component,
// using the provided 'relink' callback
template <typename T_Vertex>
void fixSources(T_Vertex& vtx, std::function<void(T_Vertex&, DfgVertex&, size_t)> relink) {
static_assert(std::is_base_of<DfgVertexVar, T_Vertex>::value,
"'Vertex' must be a 'DfgVertexVar'");
// Fix edges that cross components
void fixEdges(DfgVertexVar& vtx) {
const size_t component = state(vtx).component;
vtx.forEachSourceEdge([&](DfgEdge& edge, size_t idx) {
DfgVertex& source = *edge.sourcep();
// DfgVertexVar sources are fixed up by `fixSinks` on those sources
if (source.is<DfgVertexVar>()) return;
const size_t sourceComponent = state(source).component;
// Same component is OK
if (sourceComponent == component) return;
// Unlink the source edge (source is reconnected by 'relink'
edge.unlinkSource();
// Apply the fixup
// cppcheck-has-bug-suppress constVariable
DfgVertexVar& clone = getClone(vtx, sourceComponent);
relink(*(clone.as<T_Vertex>()), source, idx);
});
}
// Fix up sinks of given variable vertex that are in a different component
void fixSinks(DfgVertexVar& vtx) {
const size_t component = state(vtx).component;
// All variable vertices have at most a single source, and only variable
// vertices can have multiple sinks, therefore the source must be either:
// - in the same component as the variable vertex
// - be a variable vertex itself, which might be in a different component
// The later case will be fixed up when handling the source variable
DfgVertex* const srcp = vtx.srcp();
UASSERT_OBJ(!srcp || srcp->is<DfgVertexVar>() || state(*srcp).component == component, &vtx,
"Driver of DfgVertexVar must be in the same component");
// Fix up sinks in a differetn component
vtx.forEachSinkEdge([&](DfgEdge& edge) {
const size_t sinkComponent = state(*edge.sinkp()).component;
// Same component is OK
@ -376,49 +364,6 @@ class ExtractCyclicComponents final {
});
}
// Fix edges that cross components
void fixEdges(DfgVertexVar& vtx) {
if (DfgVarPacked* const vvtxp = vtx.cast<DfgVarPacked>()) {
fixSources<DfgVarPacked>(
*vvtxp, [&](DfgVarPacked& clone, DfgVertex& driver, size_t driverIdx) {
clone.addDriver(vvtxp->driverFileLine(driverIdx), //
vvtxp->driverLsb(driverIdx), &driver);
});
fixSinks(*vvtxp);
return;
}
if (DfgVarArray* const vvtxp = vtx.cast<DfgVarArray>()) {
fixSources<DfgVarArray>( //
*vvtxp, [&](DfgVarArray& clone, DfgVertex& driver, size_t driverIdx) {
clone.addDriver(vvtxp->driverFileLine(driverIdx), //
vvtxp->driverIndex(driverIdx), &driver);
});
fixSinks(*vvtxp);
return;
}
}
static void packSources(DfgGraph& dfg) {
// Remove undriven variable sources
for (DfgVertexVar* const vtxp : dfg.varVertices().unlinkable()) {
if (DfgVarPacked* const varp = vtxp->cast<DfgVarPacked>()) {
varp->packSources();
if (!varp->hasSinks() && varp->arity() == 0) {
VL_DO_DANGLING(varp->unlinkDelete(dfg), varp);
}
continue;
}
if (DfgVarArray* const varp = vtxp->cast<DfgVarArray>()) {
varp->packSources();
if (!varp->hasSinks() && varp->arity() == 0) {
VL_DO_DANGLING(varp->unlinkDelete(dfg), varp);
}
continue;
}
}
}
template <typename Vertex>
void moveVertices(DfgVertex::List<Vertex>& list) {
for (DfgVertex* const vtxp : list.unlinkable()) {
@ -446,11 +391,6 @@ class ExtractCyclicComponents final {
UASSERT_OBJ(component == state(snk).component, &vtx,
"Edge crossing components without variable involvement");
});
if (const DfgVertexVar* const vtxp = vtx.cast<DfgVertexVar>()) {
vtxp->forEachSourceEdge([](const DfgEdge& edge, size_t) {
UASSERT_OBJ(edge.sourcep(), edge.sinkp(), "Missing source on variable vertex");
});
}
});
}
@ -489,11 +429,6 @@ class ExtractCyclicComponents final {
if (&vtx == lastp) break;
}
// Pack sources of variables to remove the now undriven inputs
// (cloning might have unlinked some of the inputs),
packSources(m_dfg);
for (const auto& dfgp : m_components) packSources(*dfgp);
// Check results for consistency
if (VL_UNLIKELY(m_doExpensiveChecks)) {
checkEdges(m_dfg);

View File

@ -201,45 +201,52 @@ class DfgToAstVisitor final : DfgVisitor {
++m_ctx.m_resultEquations;
}
void convertVarDriver(const DfgVarPacked* dfgVarp) {
if (dfgVarp->isDrivenFullyByDfg()) {
// Whole variable is driven. Render driver and assign directly to whole variable.
FileLine* const flp = dfgVarp->driverFileLine(0);
AstVarRef* const lhsp = new AstVarRef{flp, getNode(dfgVarp), VAccess::WRITE};
AstNodeExpr* const rhsp = convertDfgVertexToAstNodeExpr(dfgVarp->source(0));
addResultEquation(dfgVarp, flp, lhsp, rhsp);
} else {
void convertPackedDriver(const DfgVarPacked* dfgVarp) {
if (DfgSplicePacked* const splicep = dfgVarp->srcp()->cast<DfgSplicePacked>()) {
// Variable is driven partially. Render each driver as a separate assignment.
dfgVarp->forEachSourceEdge([&](const DfgEdge& edge, size_t idx) {
splicep->forEachSourceEdge([&](const DfgEdge& edge, size_t idx) {
UASSERT_OBJ(edge.sourcep(), dfgVarp, "Should have removed undriven sources");
// Render the rhs expression
AstNodeExpr* const rhsp = convertDfgVertexToAstNodeExpr(edge.sourcep());
// Create select LValue
FileLine* const flp = dfgVarp->driverFileLine(idx);
FileLine* const flp = splicep->driverFileLine(idx);
AstVarRef* const refp = new AstVarRef{flp, getNode(dfgVarp), VAccess::WRITE};
AstConst* const lsbp = new AstConst{flp, dfgVarp->driverLsb(idx)};
AstConst* const lsbp = new AstConst{flp, splicep->driverLsb(idx)};
const int width = static_cast<int>(edge.sourcep()->width());
AstSel* const lhsp = new AstSel{flp, refp, lsbp, width};
// Add assignment of the value to the selected bits
addResultEquation(dfgVarp, flp, lhsp, rhsp);
});
return;
}
// Whole variable is driven. Render driver and assign directly to whole variable.
FileLine* const flp
= dfgVarp->driverFileLine() ? dfgVarp->driverFileLine() : dfgVarp->fileline();
AstVarRef* const lhsp = new AstVarRef{flp, getNode(dfgVarp), VAccess::WRITE};
AstNodeExpr* const rhsp = convertDfgVertexToAstNodeExpr(dfgVarp->srcp());
addResultEquation(dfgVarp, flp, lhsp, rhsp);
}
void convertArrayDiver(const DfgVarArray* dfgVarp) {
// Variable is driven partially. Assign from parts of the canonical var.
dfgVarp->forEachSourceEdge([&](const DfgEdge& edge, size_t idx) {
UASSERT_OBJ(edge.sourcep(), dfgVarp, "Should have removed undriven sources");
// Render the rhs expression
AstNodeExpr* const rhsp = convertDfgVertexToAstNodeExpr(edge.sourcep());
// Create select LValue
FileLine* const flp = dfgVarp->driverFileLine(idx);
AstVarRef* const refp = new AstVarRef{flp, getNode(dfgVarp), VAccess::WRITE};
AstConst* const idxp = new AstConst{flp, dfgVarp->driverIndex(idx)};
AstArraySel* const lhsp = new AstArraySel{flp, refp, idxp};
// Add assignment of the value to the selected bits
addResultEquation(dfgVarp, flp, lhsp, rhsp);
});
if (DfgSpliceArray* const splicep = dfgVarp->srcp()->cast<DfgSpliceArray>()) {
// Variable is driven partially. Assign from parts of the canonical var.
splicep->forEachSourceEdge([&](const DfgEdge& edge, size_t idx) {
UASSERT_OBJ(edge.sourcep(), dfgVarp, "Should have removed undriven sources");
// Render the rhs expression
AstNodeExpr* const rhsp = convertDfgVertexToAstNodeExpr(edge.sourcep());
// Create select LValue
FileLine* const flp = splicep->driverFileLine(idx);
AstVarRef* const refp = new AstVarRef{flp, getNode(dfgVarp), VAccess::WRITE};
AstConst* const idxp = new AstConst{flp, splicep->driverIndex(idx)};
AstArraySel* const lhsp = new AstArraySel{flp, refp, idxp};
// Add assignment of the value to the selected bits
addResultEquation(dfgVarp, flp, lhsp, rhsp);
});
return;
}
UASSERT_OBJ(false, dfgVarp, "Should not have wholly driven arrays in Dfg");
}
// VISITORS
@ -285,11 +292,11 @@ class DfgToAstVisitor final : DfgVisitor {
// The graph must have been regularized, so we only need to render assignments
for (DfgVertexVar& vtx : dfg.varVertices()) {
// If there is no driver (this vertex is an input to the graph), then nothing to do.
if (!vtx.isDrivenByDfg()) continue;
if (!vtx.srcp()) continue;
// Render packed variable assignments
if (const DfgVarPacked* const dfgVarp = vtx.cast<DfgVarPacked>()) {
convertVarDriver(dfgVarp);
convertPackedDriver(dfgVarp);
continue;
}

View File

@ -172,7 +172,7 @@ void V3DfgPasses::inlineVars(DfgGraph& dfg) {
// Don't inline SystemC variables, as SystemC types are not interchangeable with
// internal types, and hence the variables are not interchangeable either.
if (varp->hasSinks() && varp->isDrivenFullyByDfg() && !varp->varp()->isSc()) {
DfgVertex* const driverp = varp->source(0);
DfgVertex* const driverp = varp->srcp();
// We must keep the original driver in certain cases, when swapping them would
// not be functionally or technically (implementation reasons) equivalent:
@ -381,12 +381,14 @@ void V3DfgPasses::binToOneHot(DfgGraph& dfg, V3DfgBinToOneHotContext& ctx) {
// The index variable
DfgVarPacked* const idxVtxp = [&]() {
// If there is an existing result variable, use that, otherwise create a new variable
DfgVarPacked* varp = srcp->getResultVar();
if (!varp) {
DfgVarPacked* varp = nullptr;
if (DfgVertexVar* const vp = srcp->getResultVar()) {
varp = vp->as<DfgVarPacked>();
} else {
const std::string name = dfg.makeUniqueName("BinToOneHot_Idx", nTables);
varp = dfg.makeNewVar(flp, name, idxDTypep, nullptr)->as<DfgVarPacked>();
varp->varp()->isInternal(true);
varp->addDriver(flp, 0, srcp);
varp->srcp(srcp);
}
varp->setHasModRefs();
return varp;
@ -554,9 +556,9 @@ void V3DfgPasses::eliminateVars(DfgGraph& dfg, V3DfgEliminateVarsContext& ctx) {
if (!varp->hasModRefs()) {
// If it is only referenced in this DFG, it can be removed
++ctx.m_varsRemoved;
varp->replaceWith(varp->source(0));
varp->replaceWith(varp->srcp());
varp->nodep()->unlinkFrBack()->deleteTree();
} else if (DfgVarPacked* const driverp = varp->source(0)->cast<DfgVarPacked>()) {
} else if (DfgVarPacked* const driverp = varp->srcp()->cast<DfgVarPacked>()) {
// If it's driven from another variable, it can be replaced by that. However, we do not
// want to propagate SystemC variables into the design.
if (driverp->varp()->isSc()) continue;

View File

@ -1202,11 +1202,15 @@ class V3DfgPeephole final : public DfgVisitor {
void visit(DfgArraySel* vtxp) override {
if (DfgConst* const idxp = vtxp->bitp()->cast<DfgConst>()) {
if (DfgVarArray* const varp = vtxp->fromp()->cast<DfgVarArray>()) {
const size_t idx = idxp->toSizeT();
if (DfgVertex* const driverp = varp->driverAt(idx)) {
APPLYING(INLINE_ARRAYSEL) {
replace(vtxp, driverp);
return;
if (varp->srcp()) {
if (DfgSpliceArray* const splicep = varp->srcp()->cast<DfgSpliceArray>()) {
const size_t idx = idxp->toSizeT();
if (DfgVertex* const driverp = splicep->driverAt(idx)) {
APPLYING(INLINE_ARRAYSEL) {
replace(vtxp, driverp);
return;
}
}
}
}
}

View File

@ -45,12 +45,23 @@ class DfgRegularize final {
// Ensure intermediate values used multiple times are written to variables
for (DfgVertex& vtx : m_dfg.opVertices()) {
const bool needsIntermediateVariable = [&]() {
// Splice vertices represent partial assignments, so they need a variable
// iff and only if they have a non-variable sink.
if (vtx.is<DfgVertexSplice>()) {
const bool hasNonVarSink
= vtx.findSink<DfgVertex>([](const DfgVertex& snk) { //
return !snk.is<DfgVertexVar>();
});
return hasNonVarSink;
}
// Anything that drives an SC variable needs an intermediate,
// as we can only assign simple variables to SC variables at runtime.
const bool hasScSink = vtx.findSink<DfgVertexVar>([](const DfgVertexVar& var) { //
return var.varp()->isSc();
});
if (hasScSink) return true;
// // Splice vertices always need a variable as they represent partial updates
// if (vtx.is<DfgVertexSplice>()) return true;
// Operations without multiple sinks need no variables
if (!vtx.hasMultipleSinks()) return false;
// Array selects need no variables, they are just memory references
@ -63,26 +74,21 @@ class DfgRegularize final {
// This is an op that requires a result variable. Ensure it is
// assigned to one, and redirect other sinks read that variable.
if (DfgVarPacked* const varp = vtx.getResultVar()) {
// A variable already exists
UASSERT_OBJ(varp->arity() == 1, varp, "Result variable with multiple drivers");
FileLine* const flp = varp->driverFileLine(0);
varp->sourceEdge(0)->unlinkSource();
varp->resetSources();
if (DfgVertexVar* const varp = vtx.getResultVar()) {
varp->sourceEdge<0>()->unlinkSource();
vtx.replaceWith(varp);
varp->addDriver(flp, 0, &vtx);
varp->srcp(&vtx);
} else {
// Need to create an intermediate variable
const std::string name = m_dfg.makeUniqueName("Regularize", m_nTmps);
FileLine* const flp = vtx.fileline();
AstScope* const scopep = scoped ? vtx.scopep(scopeCache) : nullptr;
DfgVarPacked* const newp
= m_dfg.makeNewVar(flp, name, vtx.dtypep(), scopep)->as<DfgVarPacked>();
DfgVertexVar* const newp = m_dfg.makeNewVar(flp, name, vtx.dtypep(), scopep);
++m_nTmps;
++m_ctx.m_temporariesIntroduced;
// Replace vertex with the variable and add back driver
vtx.replaceWith(newp);
newp->addDriver(vtx.fileline(), 0, &vtx);
newp->srcp(&vtx);
}
}
}

View File

@ -38,22 +38,24 @@
// === Abstract base node types (DfgVertex*) ===================================
class DfgVertexVar VL_NOT_FINAL : public DfgVertexVariadic {
class DfgVertexVar VL_NOT_FINAL : public DfgVertexUnary {
AstVar* const m_varp; // The AstVar associated with this vertex (not owned by this vertex)
AstVarScope* const m_varScopep; // The AstVarScope associated with this vertex (not owned)
bool m_hasDfgRefs = false; // This AstVar is referenced in a different DFG of the module
bool m_hasModRefs = false; // This AstVar is referenced outside the DFG, but in the module
bool m_hasExtRefs = false; // This AstVar is referenced from outside the module
// Location of driver of this variable. Only used for converting back to Ast. Might be nullptr.
FileLine* m_driverFileLine = nullptr;
bool selfEquals(const DfgVertex& that) const final VL_MT_DISABLED;
V3Hash selfHash() const final VL_MT_DISABLED;
public:
inline DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVar* varp, uint32_t initialCapacity);
inline DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVarScope* vscp, uint32_t initialCapacity);
inline DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVar* varp);
inline DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVarScope* vscp);
ASTGEN_MEMBERS_DfgVertexVar;
bool isDrivenByDfg() const { return arity() > 0; }
const std::string srcName(size_t) const override { return ""; }
AstVar* varp() const { return m_varp; }
AstVarScope* varScopep() const { return m_varScopep; }
@ -68,6 +70,13 @@ public:
void setHasExtRefs() { m_hasExtRefs = true; }
bool hasNonLocalRefs() const { return hasDfgRefs() || hasModRefs() || hasExtRefs(); }
FileLine* driverFileLine() const { return m_driverFileLine; }
void driverFileLine(FileLine* flp) { m_driverFileLine = flp; }
bool isDrivenFullyByDfg() const {
return srcp() && !srcp()->is<DfgVertexSplice>() && !varp()->isForced();
}
// Variable cannot be removed, even if redundant in the DfgGraph (might be used externally)
bool keep() const {
// Keep if referenced outside this module
@ -82,6 +91,12 @@ public:
return false;
}
};
class DfgVertexSplice VL_NOT_FINAL : public DfgVertexVariadic {
public:
DfgVertexSplice(DfgGraph& dfg, VDfgType type, FileLine* flp, AstNodeDType* dtypep)
: DfgVertexVariadic{dfg, type, flp, dtypep, 1u} {}
ASTGEN_MEMBERS_DfgVertexSplice;
};
// === Concrete node types =====================================================
@ -184,14 +199,49 @@ class DfgVarArray final : public DfgVertexVar {
public:
DfgVarArray(DfgGraph& dfg, AstVar* varp)
: DfgVertexVar{dfg, dfgType(), varp, 4u} {
: DfgVertexVar{dfg, dfgType(), varp} {
UASSERT_OBJ(VN_IS(dtypep(), UnpackArrayDType), varp, "Non array DfgVarArray");
}
DfgVarArray(DfgGraph& dfg, AstVarScope* vscp)
: DfgVertexVar{dfg, dfgType(), vscp, 4u} {
: DfgVertexVar{dfg, dfgType(), vscp} {
UASSERT_OBJ(VN_IS(dtypep(), UnpackArrayDType), vscp, "Non array DfgVarArray");
}
ASTGEN_MEMBERS_DfgVarArray;
};
class DfgVarPacked final : public DfgVertexVar {
friend class DfgVertex;
friend class DfgVisitor;
public:
DfgVarPacked(DfgGraph& dfg, AstVar* varp)
: DfgVertexVar{dfg, dfgType(), varp} {
UASSERT_OBJ(!VN_IS(dtypep(), UnpackArrayDType), varp, "Array DfgVarPacked");
}
DfgVarPacked(DfgGraph& dfg, AstVarScope* vscp)
: DfgVertexVar{dfg, dfgType(), vscp} {
UASSERT_OBJ(!VN_IS(dtypep(), UnpackArrayDType), vscp, "Array DfgVarPacked");
}
ASTGEN_MEMBERS_DfgVarPacked;
};
// === DfgVertexSplice ===
class DfgSpliceArray final : public DfgVertexSplice {
friend class DfgVertex;
friend class DfgVisitor;
using DriverData = std::pair<FileLine*, uint32_t>;
std::vector<DriverData> m_driverData; // Additional data associated with each driver
bool selfEquals(const DfgVertex& that) const override VL_MT_DISABLED;
V3Hash selfHash() const override VL_MT_DISABLED;
public:
DfgSpliceArray(DfgGraph& dfg, FileLine* flp, AstNodeDType* dtypep)
: DfgVertexSplice{dfg, dfgType(), flp, dtypep} {
UASSERT_OBJ(VN_IS(dtypep, UnpackArrayDType), flp, "Non array DfgSpliceArray");
}
ASTGEN_MEMBERS_DfgSpliceArray;
void addDriver(FileLine* flp, uint32_t index, DfgVertex* vtxp) {
m_driverData.emplace_back(flp, index);
@ -203,27 +253,6 @@ public:
DfgVertexVariadic::resetSources();
}
// Remove undriven sources
void packSources() {
// Grab and reset the driver data
std::vector<DriverData> driverData;
driverData.swap(m_driverData);
// Grab and unlink the sources
std::vector<DfgVertex*> sources{arity()};
forEachSourceEdge([&](DfgEdge& edge, size_t idx) {
sources[idx] = edge.sourcep();
edge.unlinkSource();
});
DfgVertexVariadic::resetSources();
// Add back the driven sources
for (size_t i = 0; i < sources.size(); ++i) {
if (!sources[i]) continue;
addDriver(driverData[i].first, driverData[i].second, sources[i]);
}
}
FileLine* driverFileLine(size_t idx) const { return m_driverData[idx].first; }
uint32_t driverIndex(size_t idx) const { return m_driverData[idx].second; }
@ -234,26 +263,27 @@ public:
return edgep ? edgep->sourcep() : nullptr;
}
const string srcName(size_t idx) const override { return cvtToStr(driverIndex(idx)); }
const std::string srcName(size_t idx) const override {
return std::to_string(driverIndex(idx));
}
};
class DfgVarPacked final : public DfgVertexVar {
class DfgSplicePacked final : public DfgVertexSplice {
friend class DfgVertex;
friend class DfgVisitor;
using DriverData = std::pair<FileLine*, uint32_t>;
std::vector<DriverData> m_driverData; // Additional data associate with each driver
std::vector<DriverData> m_driverData; // Additional data associated with each driver
bool selfEquals(const DfgVertex& that) const override VL_MT_DISABLED;
V3Hash selfHash() const override VL_MT_DISABLED;
public:
DfgVarPacked(DfgGraph& dfg, AstVar* varp)
: DfgVertexVar{dfg, dfgType(), varp, 1u} {}
DfgVarPacked(DfgGraph& dfg, AstVarScope* vscp)
: DfgVertexVar{dfg, dfgType(), vscp, 1u} {}
ASTGEN_MEMBERS_DfgVarPacked;
bool isDrivenFullyByDfg() const {
return arity() == 1 && source(0)->dtypep() == dtypep() && !varp()->isForced();
DfgSplicePacked(DfgGraph& dfg, FileLine* flp, AstNodeDType* dtypep)
: DfgVertexSplice{dfg, dfgType(), flp, dtypep} {
UASSERT_OBJ(!VN_IS(dtypep, UnpackArrayDType), flp, "Array DfgSplicePacked");
}
ASTGEN_MEMBERS_DfgSplicePacked;
void addDriver(FileLine* flp, uint32_t lsb, DfgVertex* vtxp) {
m_driverData.emplace_back(flp, lsb);
@ -265,33 +295,10 @@ public:
DfgVertexVariadic::resetSources();
}
// Remove undriven sources
void packSources() {
// Grab and reset the driver data
std::vector<DriverData> driverData;
driverData.swap(m_driverData);
// Grab and unlink the sources
std::vector<DfgVertex*> sources{arity()};
forEachSourceEdge([&](DfgEdge& edge, size_t idx) {
sources[idx] = edge.sourcep();
edge.unlinkSource();
});
DfgVertexVariadic::resetSources();
// Add back the driven sources
for (size_t i = 0; i < sources.size(); ++i) {
if (!sources[i]) continue;
addDriver(driverData[i].first, driverData[i].second, sources[i]);
}
}
FileLine* driverFileLine(size_t idx) const { return m_driverData[idx].first; }
uint32_t driverLsb(size_t idx) const { return m_driverData[idx].second; }
const string srcName(size_t idx) const override {
return isDrivenFullyByDfg() ? "" : cvtToStr(driverLsb(idx));
}
const std::string srcName(size_t idx) const override { return std::to_string(driverLsb(idx)); }
};
#endif

View File

@ -247,14 +247,14 @@ void EmitCFunc::displayArg(AstNode* dispp, AstNode** elistp, bool isScan, const
AstNode* argp = nullptr;
if (!ignore) {
argp = *elistp;
// Prep for next parameter
*elistp = (*elistp)->nextp();
if (VL_UNCOVERABLE(!argp)) {
// expectDisplay() checks this first, so internal error if found here
dispp->v3error(
"Internal: Missing arguments for $display-like format"); // LCOV_EXCL_LINE
return; // LCOV_EXCL_LINE
}
// Prep for next parameter
*elistp = (*elistp)->nextp();
if (argp->widthMin() > VL_VALUE_STRING_MAX_WIDTH) {
dispp->v3warn(E_UNSUPPORTED, "Unsupported: Exceeded limit of "
+ cvtToStr(VL_VALUE_STRING_MAX_WIDTH)

View File

@ -661,7 +661,7 @@ public:
}
iterateChildrenConst(nodep);
}
void visit(AstCoverDecl* nodep) override {
void visit(AstCoverOtherDecl* nodep) override {
putns(nodep, "vlSelf->__vlCoverInsert("); // As Declared in emitCoverageDecl
puts("&(vlSymsp->__Vcoverage[");
puts(cvtToStr(nodep->dataDeclThisp()->binNum()));
@ -689,15 +689,67 @@ public:
putsQuoted(nodep->linescov());
puts(");\n");
}
void visit(AstCoverToggleDecl* nodep) override {
putns(nodep, "vlSelf->__vlCoverToggleInsert("); // As Declared in emitCoverageDecl
puts(cvtToStr(nodep->range().right()));
puts(", ");
puts(cvtToStr(nodep->range().left()));
puts(", ");
puts(cvtToStr(nodep->range().ranged()));
puts(", ");
puts("&(vlSymsp->__Vcoverage[");
puts(cvtToStr(nodep->dataDeclThisp()->binNum()));
puts("])");
// If this isn't the first instantiation of this module under this
// design, don't really count the bucket, and rely on verilator_cov to
// aggregate counts. This is because Verilator combines all
// hierarchies itself, and if verilator_cov also did it, you'd end up
// with (number-of-instant) times too many counts in this bin.
puts(", first"); // Enable, passed from __Vconfigure parameter
puts(", ");
putsQuoted(protect(nodep->fileline()->filename()));
puts(", ");
puts(cvtToStr(nodep->fileline()->lineno()));
puts(", ");
puts(cvtToStr(nodep->fileline()->firstColumn()));
puts(", ");
putsQuoted((!nodep->hier().empty() ? "." : "")
+ protectWordsIf(nodep->hier(), nodep->protect()));
puts(", ");
putsQuoted(protectWordsIf(nodep->page(), nodep->protect()));
puts(", ");
putsQuoted(protectWordsIf(nodep->comment(), nodep->protect()));
puts(");\n");
}
void visit(AstCoverInc* nodep) override {
if (v3Global.opt.threads() > 1) {
putns(nodep, "vlSymsp->__Vcoverage[");
puts(cvtToStr(nodep->declp()->dataDeclThisp()->binNum()));
puts("].fetch_add(1, std::memory_order_relaxed);\n");
if (nodep->declp()->size() == 1) {
if (v3Global.opt.threads() > 1) {
putns(nodep, "vlSymsp->__Vcoverage[");
puts(cvtToStr(nodep->declp()->dataDeclThisp()->binNum()));
puts("].fetch_add(1, std::memory_order_relaxed);\n");
} else {
putns(nodep, "++(vlSymsp->__Vcoverage[");
puts(cvtToStr(nodep->declp()->dataDeclThisp()->binNum()));
puts("]);\n");
}
} else {
putns(nodep, "++(vlSymsp->__Vcoverage[");
puts("VL_COV_TOGGLE_CHG_");
if (v3Global.opt.threads() > 1) {
puts("MT_");
} else {
puts("ST_");
}
emitIQW(nodep->toggleExprp());
puts("(");
puts(cvtToStr(nodep->declp()->size()));
puts(", ");
puts("vlSymsp->__Vcoverage + ");
puts(cvtToStr(nodep->declp()->dataDeclThisp()->binNum()));
puts("]);\n");
puts(", ");
iterateConst(nodep->toggleExprp());
puts(", ");
iterateConst(nodep->toggleCovExprp());
puts(");\n");
}
}
void visit(AstDisableFork* nodep) override { putns(nodep, "vlProcess->disableFork();\n"); }

View File

@ -181,6 +181,14 @@ class EmitCHeader final : public EmitCConstInit {
"linescovp);\n");
}
if (v3Global.opt.coverageToggle() && !VN_IS(modp, Class)) {
decorateFirst(first, section);
puts("void __vlCoverToggleInsert(int begin, int end, bool ranged, ");
puts(v3Global.opt.threads() > 1 ? "std::atomic<uint32_t>" : "uint32_t");
puts("* countp, bool enable, const char* filenamep, int lineno, int column,\n");
puts("const char* hierp, const char* pagep, const char* commentp);\n");
}
if (v3Global.opt.savable()) {
decorateFirst(first, section);
puts("void " + protect("__Vserialize") + "(VerilatedSerialize& os);\n");

View File

@ -103,7 +103,7 @@ class EmitCGatherDependencies final : VNVisitorConst {
addSelfDependency(nodep->selfPointer(), nodep->varp());
iterateChildrenConst(nodep);
}
void visit(AstCoverDecl* nodep) override {
void visit(AstNodeCoverDecl* nodep) override {
addSymsDependency();
iterateChildrenConst(nodep);
}
@ -307,17 +307,16 @@ class EmitCImp final : EmitCFunc {
splitSizeInc(10);
}
void emitCoverageImp() {
// Rather than putting out VL_COVER_INSERT calls directly, we do it via this
// function. This gets around gcc slowness constructing all of the template
// arguments.
if (v3Global.opt.coverage()) {
puts("\n// Coverage\n");
// Rather than putting out VL_COVER_INSERT calls directly, we do it via this
// function. This gets around gcc slowness constructing all of the template
// arguments.
puts("void " + prefixNameProtect(m_modp) + "::__vlCoverInsert(");
puts(v3Global.opt.threads() > 1 ? "std::atomic<uint32_t>" : "uint32_t");
puts("* countp, bool enable, const char* filenamep, int lineno, int column,\n");
puts("const char* hierp, const char* pagep, const char* commentp, const char* "
"linescovp) "
"{\n");
"linescovp) {\n");
if (v3Global.opt.threads() > 1) {
puts("assert(sizeof(uint32_t) == sizeof(std::atomic<uint32_t>));\n");
puts("uint32_t* count32p = reinterpret_cast<uint32_t*>(countp);\n");
@ -343,6 +342,48 @@ class EmitCImp final : EmitCFunc {
puts("}\n");
splitSizeInc(10);
}
if (v3Global.opt.coverageToggle()) {
puts("\n// Toggle Coverage\n");
puts("void " + prefixNameProtect(m_modp) + "::__vlCoverToggleInsert(");
puts("int begin, int end, bool ranged, ");
puts(v3Global.opt.threads() > 1 ? "std::atomic<uint32_t>" : "uint32_t");
puts("* countp, bool enable, const char* filenamep, int lineno, int column,\n");
puts("const char* hierp, const char* pagep, const char* commentp) {\n");
if (v3Global.opt.threads() > 1) {
puts("assert(sizeof(uint32_t) == sizeof(std::atomic<uint32_t>));\n");
}
puts("int step = (end >= begin) ? 1 : -1;\n");
// range is inclusive
puts("for (int i = begin; i != end + step; i += step) {\n");
if (v3Global.opt.threads() > 1) {
puts("uint32_t* count32p = reinterpret_cast<uint32_t*>(countp);\n");
} else {
puts("uint32_t* count32p = countp;\n");
}
// static doesn't need save-restore as is constant
puts("static uint32_t fake_zero_count = 0;\n");
puts("std::string fullhier = std::string{VerilatedModule::name()} + hierp;\n");
puts("if (!fullhier.empty() && fullhier[0] == '.') fullhier = fullhier.substr(1);\n");
puts("std::string commentWithIndex = commentp;\n");
puts("if (ranged) commentWithIndex += '[' + std::to_string(i) + ']';\n");
// Used for second++ instantiation of identical bin
puts("if (!enable) count32p = &fake_zero_count;\n");
puts("*count32p = 0;\n");
puts("VL_COVER_INSERT(vlSymsp->_vm_contextp__->coveragep(), VerilatedModule::name(), "
"count32p,");
puts(" \"filename\",filenamep,");
puts(" \"lineno\",lineno,");
puts(" \"column\",column,\n");
puts("\"hier\",fullhier,");
puts(" \"page\",pagep,");
puts(" \"comment\",commentWithIndex.c_str(),");
puts(" \"\", \"\");\n"); // linescov argument, but in toggle coverage it is always
// empty
puts("++countp;\n");
puts("}\n");
puts("}\n");
splitSizeInc(10);
}
}
void emitDestructorImp(const AstNodeModule* modp) {
puts("\n");

View File

@ -376,10 +376,11 @@ class EmitCSyms final : EmitCBaseVisitorConst {
iterateChildrenConst(nodep);
m_statVarScopeBytes += nodep->varp()->dtypep()->widthTotalBytes();
}
void visit(AstCoverDecl* nodep) override {
void visit(AstNodeCoverDecl* nodep) override {
// Assign numbers to all bins, so we know how big of an array to use
if (!nodep->dataDeclNullp()) { // else duplicate we don't need code for
nodep->binNum(m_coverBins++);
nodep->binNum(m_coverBins);
m_coverBins += nodep->size();
}
}
void visit(AstCFunc* nodep) override {
@ -964,9 +965,9 @@ void EmitCSyms::emitSymImp() {
} else {
if (basicp->isRanged()) {
bounds += " ,";
bounds += cvtToStr(basicp->hi());
bounds += cvtToStr(basicp->left());
bounds += ",";
bounds += cvtToStr(basicp->lo());
bounds += cvtToStr(basicp->right());
pdim++;
}
break; // AstBasicDType - nothing below, 1

View File

@ -231,7 +231,7 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
putbs("continue");
if (!m_suppressSemi) puts(";\n");
}
void visit(AstCoverDecl*) override {} // N/A
void visit(AstNodeCoverDecl*) override {} // N/A
void visit(AstCoverInc*) override {} // N/A
void visit(AstCoverToggle*) override {} // N/A
@ -922,6 +922,20 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
m_sensesp = nodep->sensesp();
iterateAndNextConstNull(nodep->stmtsp());
}
void visit(AstDelay* nodep) override {
puts(""); // this is for proper alignment
puts("#");
iterateConst(nodep->lhsp());
puts(";\n");
iterateAndNextConstNull(nodep->stmtsp());
}
void visit(AstCAwait* nodep) override {
AstCMethodHard* methodp = VN_CAST(nodep->exprp(), CMethodHard);
UASSERT_OBJ(methodp, nodep, "AstCAwait expression must be an AstCMethodHard");
puts(""); // this is for proper alignment
puts("#");
iterateConst(methodp->pinsp());
}
void visit(AstParseRef* nodep) override { puts(nodep->prettyName()); }
void visit(AstNodeText*) override {}
void visit(AstVarScope*) override {}

View File

@ -125,6 +125,7 @@ public:
MULTIDRIVEN, // Driven from multiple blocks
MULTITOP, // Multiple top level modules
NEWERSTD, // Newer language standard required
NOEFFECT, // Statement has no effect
NOLATCH, // No latch detected in always_latch block
NONSTD, // Non-standard feature present in other sims
NULLPORT, // Null port detected in module definition
@ -145,6 +146,7 @@ public:
SELRANGE, // Selection index out of range
SHORTREAL, // Shortreal not supported
SIDEEFFECT, // Sideeffect ignored
SPECIFYIGN, // Specify construct ignored
SPLITVAR, // Cannot split the variable
STATICVAR, // Static variable declared in a loop with a declaration assignment
STMTDLY, // Delayed statement
@ -190,41 +192,33 @@ public:
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
constexpr operator en() const VL_MT_SAFE { return m_e; }
const char* ascii() const VL_MT_SAFE {
// clang-format off
static const char* const names[] = {
// Leading spaces indicate it can't be disabled.
" MIN", " INFO", " FATAL", " FATALMANY", " FATALSRC", " ERROR", " FIRST_NAMED",
// Boolean
" I_CELLDEFINE", " I_COVERAGE", " I_DEF_NETTYPE_WIRE", " I_LINT", " I_TIMING", " I_TRACING", " I_UNUSED",
" I_CELLDEFINE", " I_COVERAGE", " I_DEF_NETTYPE_WIRE", " I_LINT", " I_TIMING",
" I_TRACING", " I_UNUSED",
// Errors
"LIFETIME", "NEEDTIMINGOPT", "NOTIMING", "PORTSHORT", "TASKNSVAR", "UNSUPPORTED",
// Warnings
" EC_FIRST_WARN",
"ALWCOMBORDER", "ASCRANGE", "ASSIGNDLY", "ASSIGNIN", "BADSTDPRAGMA", "BADVLTPRAGMA",
"BLKANDNBLK", "BLKLOOPINIT", "BLKSEQ", "BSSPACE",
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CASTCONST", "CDCRSTLOGIC", "CLKDATA",
"CMPCONST", "COLONPLUS", "COMBDLY", "CONSTRAINTIGN", "CONTASSREG", "COVERIGN",
"DECLFILENAME", "DEFOVERRIDE", "DEFPARAM", "DEPRECATED",
"ENCAPSULATED", "ENDLABEL", "ENUMITEMWIDTH", "ENUMVALUE", "EOFNEWLINE",
"GENCLK", "GENUNNAMED", "HIERBLOCK",
"IFDEPTH", "IGNOREDRETURN",
"IMPERFECTSCH", "IMPLICIT", "IMPLICITSTATIC", "IMPORTSTAR", "IMPURE",
"INCABSPATH", "INFINITELOOP", "INITIALDLY", "INSECURE",
"LATCH", "LITENDIAN", "MINTYPMAXDLY", "MISINDENT", "MODDUP", "MODMISSING",
"MULTIDRIVEN", "MULTITOP", "NEWERSTD", "NOLATCH", "NONSTD", "NULLPORT", "PINCONNECTEMPTY",
"PINMISSING", "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PREPROCZERO", "PROCASSINIT", "PROCASSWIRE",
"PROFOUTOFDATE", "PROTECTED", "RANDC", "REALCVT", "REDEFMACRO", "RISEFALLDLY",
"SELRANGE", "SHORTREAL", "SIDEEFFECT", "SPLITVAR",
"STATICVAR", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET",
"TICKCOUNT", "TIMESCALEMOD",
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS",
"UNPACKED", "UNSIGNED", "UNUSEDGENVAR", "UNUSEDLOOP" ,"UNUSEDPARAM", "UNUSEDSIGNAL",
"USERERROR", "USERFATAL", "USERINFO", "USERWARN",
"VARHIDDEN", "WAITCONST", "WIDTH", "WIDTHCONCAT", "WIDTHEXPAND", "WIDTHTRUNC", "WIDTHXZEXPAND",
"ZERODLY", "ZEROREPL",
" MAX"
};
// clang-format on
" EC_FIRST_WARN", "ALWCOMBORDER", "ASCRANGE", "ASSIGNDLY", "ASSIGNIN", "BADSTDPRAGMA",
"BADVLTPRAGMA", "BLKANDNBLK", "BLKLOOPINIT", "BLKSEQ", "BSSPACE", "CASEINCOMPLETE",
"CASEOVERLAP", "CASEWITHX", "CASEX", "CASTCONST", "CDCRSTLOGIC", "CLKDATA", "CMPCONST",
"COLONPLUS", "COMBDLY", "CONSTRAINTIGN", "CONTASSREG", "COVERIGN", "DECLFILENAME",
"DEFOVERRIDE", "DEFPARAM", "DEPRECATED", "ENCAPSULATED", "ENDLABEL", "ENUMITEMWIDTH",
"ENUMVALUE", "EOFNEWLINE", "GENCLK", "GENUNNAMED", "HIERBLOCK", "IFDEPTH",
"IGNOREDRETURN", "IMPERFECTSCH", "IMPLICIT", "IMPLICITSTATIC", "IMPORTSTAR", "IMPURE",
"INCABSPATH", "INFINITELOOP", "INITIALDLY", "INSECURE", "LATCH", "LITENDIAN",
"MINTYPMAXDLY", "MISINDENT", "MODDUP", "MODMISSING", "MULTIDRIVEN", "MULTITOP",
"NEWERSTD", "NOEFFECT", "NOLATCH", "NONSTD", "NULLPORT", "PINCONNECTEMPTY",
"PINMISSING", "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PREPROCZERO", "PROCASSINIT",
"PROCASSWIRE", "PROFOUTOFDATE", "PROTECTED", "RANDC", "REALCVT", "REDEFMACRO",
"RISEFALLDLY", "SELRANGE", "SHORTREAL", "SIDEEFFECT", "SPECIFYIGN", "SPLITVAR",
"STATICVAR", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET", "TICKCOUNT", "TIMESCALEMOD",
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS", "UNPACKED", "UNSIGNED",
"UNUSEDGENVAR", "UNUSEDLOOP", "UNUSEDPARAM", "UNUSEDSIGNAL", "USERERROR", "USERFATAL",
"USERINFO", "USERWARN", "VARHIDDEN", "WAITCONST", "WIDTH", "WIDTHCONCAT",
"WIDTHEXPAND", "WIDTHTRUNC", "WIDTHXZEXPAND", "ZERODLY", "ZEROREPL", " MAX"};
return names[m_e];
}
// Warnings that default to off

View File

@ -459,7 +459,7 @@ class InlineRelinkVisitor final : public VNVisitor {
if (afterp) nodep->addScopeEntrp(afterp);
iterateChildren(nodep);
}
void visit(AstCoverDecl* nodep) override {
void visit(AstNodeCoverDecl* nodep) override {
// Fix path in coverage statements
nodep->hier(VString::dot(m_cellp->prettyName(), ".", nodep->hier()));
iterateChildren(nodep);

View File

@ -779,14 +779,51 @@ public:
if (!foundp) baddot = dotname;
return foundp;
}
static bool checkIfClassOrPackage(const VSymEnt* const symp) {
if (VN_IS(symp->nodep(), Class) || VN_IS(symp->nodep(), Package)) return true;
const AstRefDType* refDTypep = nullptr;
if (const AstTypedef* const typedefp = VN_CAST(symp->nodep(), Typedef)) {
if (VN_IS(typedefp->childDTypep(), ClassRefDType)) return true;
if (const AstRefDType* const refp = VN_CAST(typedefp->childDTypep(), RefDType)) {
refDTypep = refp;
}
} else if (const AstParamTypeDType* const paramTypep
= VN_CAST(symp->nodep(), ParamTypeDType)) {
if (const AstRequireDType* const requireDTypep
= VN_CAST(paramTypep->childDTypep(), RequireDType)) {
if (const AstRefDType* const refp = VN_CAST(requireDTypep->lhsp(), RefDType)) {
refDTypep = refp;
} else if (VN_IS(requireDTypep->lhsp(), VoidDType)
|| VN_IS(requireDTypep->lhsp(), BasicDType)
|| VN_IS(requireDTypep->lhsp(), ClassRefDType)) {
return true;
}
}
}
// TODO: this should be handled properly - case when it is known what type is
// referenced by AstRefDType (refDTypep->typeofp() is null or
// refDTypep->classOrPackageOpp() is null)
if (refDTypep && !refDTypep->typeofp() && !refDTypep->classOrPackageOpp()) {
// When still unknown - return because it may be a class, classes may not be
// linked at this point. Return in case it gets resolved to a class in the future
return true;
}
return false;
}
VSymEnt* resolveClassOrPackage(VSymEnt* lookSymp, AstClassOrPackageRef* nodep, bool fallback,
bool classOnly, const string& forWhat) {
if (nodep->classOrPackageSkipp()) return getNodeSym(nodep->classOrPackageSkipp());
VSymEnt* foundp;
if (fallback) {
foundp = lookSymp->findIdFallback(nodep->name());
VSymEnt* currentLookSymp = lookSymp;
do {
foundp = currentLookSymp->findIdFlat(nodep->name());
if (foundp && !checkIfClassOrPackage(foundp)) foundp = nullptr;
if (!foundp) currentLookSymp = currentLookSymp->fallbackp();
} while (!foundp && currentLookSymp);
} else {
foundp = lookSymp->findIdFlat(nodep->name());
if (foundp && !checkIfClassOrPackage(foundp)) foundp = nullptr;
}
if (!foundp && v3Global.rootp()->stdPackagep()) { // Look under implied std::
foundp = getNodeSym(v3Global.rootp()->stdPackagep())->findIdFlat(nodep->name());
@ -3552,9 +3589,6 @@ class LinkDotResolveVisitor final : public VNVisitor {
UINFO(9, indent() << m_ds.ascii());
VL_RESTORER(m_usedPins);
m_usedPins.clear();
UASSERT_OBJ(m_statep->forPrimary() || VN_IS(nodep->classOrPackageNodep(), ParamTypeDType)
|| nodep->classOrPackageSkipp(),
nodep, "ClassRef has unlinked class");
UASSERT_OBJ(m_statep->forPrimary() || !nodep->paramsp(), nodep,
"class reference parameter not removed by V3Param");
{
@ -3565,6 +3599,10 @@ class LinkDotResolveVisitor final : public VNVisitor {
m_statep->resolveClassOrPackage(m_ds.m_dotSymp, nodep, m_ds.m_dotPos != DP_PACKAGE,
false, ":: reference");
}
UASSERT_OBJ(m_statep->forPrimary()
|| VN_IS(nodep->classOrPackageNodep(), ParamTypeDType)
|| nodep->classOrPackageSkipp(),
nodep, "ClassRef has unlinked class");
// ClassRef's have pins, so track
if (nodep->classOrPackageSkipp()) {

View File

@ -185,6 +185,56 @@ class LinkJumpVisitor final : public VNVisitor {
return new AstStmtExpr{
fl, new AstMethodCall{fl, queueRefp, "push_back", new AstArg{fl, "", processSelfp}}};
}
void handleDisableOnFork(AstDisable* const nodep, const std::vector<AstBegin*>& forks) {
// The support is limited only to disabling a fork from outside that fork.
// It utilizes the process::kill()` method. For each `disable` a queue of processes is
// declared. At the beginning of each fork that can be disabled, its process handle is
// pushed to the queue. `disable` statement is replaced with calling `kill()` method on
// each element of the queue.
FileLine* const fl = nodep->fileline();
const std::string targetName = nodep->targetp()->name();
if (existsBlockAbove(targetName)) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: disabling fork from within same fork");
}
if (m_ftaskp) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: disabling fork from task / function");
}
AstPackage* const topPkgp = v3Global.rootp()->dollarUnitPkgAddp();
AstClass* const processClassp
= VN_AS(getMemberp(v3Global.rootp()->stdPackagep(), "process"), Class);
// Declare queue of processes (as a global variable for simplicity)
AstVar* const processQueuep = new AstVar{
fl, VVarType::VAR, m_queueNames.get(targetName), VFlagChildDType{},
new AstQueueDType{fl, VFlagChildDType{},
new AstClassRefDType{fl, processClassp, nullptr}, nullptr}};
processQueuep->lifetime(VLifetime::STATIC);
topPkgp->addStmtsp(processQueuep);
AstVarRef* const queueWriteRefp
= new AstVarRef{fl, topPkgp, processQueuep, VAccess::WRITE};
AstStmtExpr* pushCurrentProcessp = getQueuePushProcessSelfp(queueWriteRefp);
for (AstBegin* const beginp : forks) {
if (pushCurrentProcessp->backp()) {
pushCurrentProcessp = pushCurrentProcessp->cloneTree(false);
}
if (beginp->stmtsp()) {
// There is no need to add it to empty block
beginp->stmtsp()->addHereThisAsNext(pushCurrentProcessp);
}
}
AstVarRef* const queueRefp = new AstVarRef{fl, topPkgp, processQueuep, VAccess::READWRITE};
AstTaskRef* const killQueueCall
= new AstTaskRef{fl, VN_AS(getMemberp(processClassp, "killQueue"), Task),
new AstArg{fl, "", queueRefp}};
killQueueCall->classOrPackagep(processClassp);
nodep->addNextHere(new AstStmtExpr{fl, killQueueCall});
}
static bool directlyUnderFork(const AstNode* const nodep) {
if (nodep->backp()->nextp() == nodep) return directlyUnderFork(nodep->backp());
if (VN_IS(nodep->backp(), Fork)) return true;
return false;
}
// VISITORS
void visit(AstNodeModule* nodep) override {
@ -369,35 +419,9 @@ class LinkJumpVisitor final : public VNVisitor {
if (VN_IS(targetp, Task)) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: disabling task by name");
} else if (AstFork* const forkp = VN_CAST(targetp, Fork)) {
// The support is limited only to disabling a fork from outside that fork.
// It utilizes the process::kill()` method. For each `disable` a queue of processes is
// declared. At the beginning of each fork that can be disabled, its process handle is
// pushed to the queue. `disable` statement is replaced with calling `kill()` method on
// each element of the queue.
if (existsBlockAbove(forkp->name())) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: disabling fork from within same fork");
}
if (m_ftaskp) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: disabling fork from task / function");
}
AstPackage* const topPkgp = v3Global.rootp()->dollarUnitPkgAddp();
AstClass* const processClassp
= VN_AS(getMemberp(v3Global.rootp()->stdPackagep(), "process"), Class);
// Declare queue of processes (as a global variable for simplicity)
AstVar* const processQueuep = new AstVar{
fl, VVarType::VAR, m_queueNames.get(forkp->name()), VFlagChildDType{},
new AstQueueDType{fl, VFlagChildDType{},
new AstClassRefDType{fl, processClassp, nullptr}, nullptr}};
processQueuep->lifetime(VLifetime::STATIC);
topPkgp->addStmtsp(processQueuep);
AstVarRef* const queueWriteRefp
= new AstVarRef{fl, topPkgp, processQueuep, VAccess::WRITE};
AstStmtExpr* const pushCurrentProcessp = getQueuePushProcessSelfp(queueWriteRefp);
std::vector<AstBegin*> forks;
for (AstNode* forkItemp = forkp->stmtsp(); forkItemp; forkItemp = forkItemp->nextp()) {
// Add push_back statement at the beginning of each fork.
// Wrap into begin block if needed
// Further handling of disable stmt requires all forks to be begin blocks
AstBegin* beginp = VN_CAST(forkItemp, Begin);
if (!beginp) {
beginp = new AstBegin{fl, "", nullptr};
@ -406,34 +430,28 @@ class LinkJumpVisitor final : public VNVisitor {
// In order to continue the iteration
forkItemp = beginp;
}
if (pushCurrentProcessp->backp()) {
beginp->stmtsp()->addHereThisAsNext(pushCurrentProcessp->cloneTree(false));
} else {
beginp->stmtsp()->addHereThisAsNext(pushCurrentProcessp);
}
forks.push_back(beginp);
}
AstVarRef* const queueRefp
= new AstVarRef{fl, topPkgp, processQueuep, VAccess::READWRITE};
AstTaskRef* const killQueueCall
= new AstTaskRef{fl, VN_AS(getMemberp(processClassp, "killQueue"), Task),
new AstArg{fl, "", queueRefp}};
killQueueCall->classOrPackagep(processClassp);
nodep->addNextHere(new AstStmtExpr{fl, killQueueCall});
handleDisableOnFork(nodep, forks);
} else if (AstBegin* const beginp = VN_CAST(targetp, Begin)) {
const std::string targetName = beginp->name();
if (existsBlockAbove(targetName)) {
if (beginp->user3()) {
nodep->v3warn(E_UNSUPPORTED,
"Unsupported: disabling block that contains a fork");
} else {
// Jump to the end of the named block
AstJumpLabel* const labelp = findAddLabel(beginp, false);
nodep->addNextHere(new AstJumpGo{nodep->fileline(), labelp});
}
if (directlyUnderFork(beginp)) {
std::vector<AstBegin*> forks{beginp};
handleDisableOnFork(nodep, forks);
} else {
nodep->v3warn(E_UNSUPPORTED, "disable isn't underneath a begin with name: '"
<< targetName << "'");
const std::string targetName = beginp->name();
if (existsBlockAbove(targetName)) {
if (beginp->user3()) {
nodep->v3warn(E_UNSUPPORTED,
"Unsupported: disabling block that contains a fork");
} else {
// Jump to the end of the named block
AstJumpLabel* const labelp = findAddLabel(beginp, false);
nodep->addNextHere(new AstJumpGo{nodep->fileline(), labelp});
}
} else {
nodep->v3warn(E_UNSUPPORTED, "disable isn't underneath a begin with name: '"
<< targetName << "'");
}
}
} else {
nodep->v3fatalSrc("Disable linked with node of unhandled type "

View File

@ -578,7 +578,7 @@ class LinkParseVisitor final : public VNVisitor {
} else if (VN_IS(bracketp, SelLoopVars)) {
// Ok
} else {
nodep->v3error("Syntax error; foreach missing bracketed loop variable"
nodep->v3error("Foreach missing bracketed loop variable is no-operation"
" (IEEE 1800-2023 12.7.3)");
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return;

View File

@ -1803,8 +1803,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
DECL_OPTION("-Wwarn-UNSUPPORTED", CbCall, []() {
FileLine::globalWarnOff(V3ErrorCode::E_UNSUPPORTED, false);
FileLine::globalWarnOff(V3ErrorCode::COVERIGN, false);
FileLine::globalWarnOff(V3ErrorCode::SPECIFYIGN, false);
V3Error::pretendError(V3ErrorCode::E_UNSUPPORTED, false);
V3Error::pretendError(V3ErrorCode::COVERIGN, false);
V3Error::pretendError(V3ErrorCode::SPECIFYIGN, false);
});
DECL_OPTION("-Wwarn-WIDTH", CbCall, []() {
FileLine::globalWarnOff(V3ErrorCode::WIDTH, false);

View File

@ -1116,7 +1116,7 @@ class ParamVisitor final : public VNVisitor {
} else {
cellp->v3fatalSrc("Expected module parameterization");
}
UASSERT_OBJ(srcModp, cellp, "Unlinked class ref");
if (!srcModp) continue;
// Update path
string someInstanceName = modp->someInstanceName();

View File

@ -2198,14 +2198,14 @@ class RandomizeVisitor final : public VNVisitor {
AstClass* classp = nullptr;
if (AstMethodCall* const callp = VN_CAST(nodep, MethodCall)) {
UASSERT_OBJ(callp->fromp()->dtypep(), callp->fromp(), "Object dtype is not linked");
AstClassRefDType* const classrefdtypep
= VN_CAST(callp->fromp()->dtypep(), ClassRefDType);
if (!classrefdtypep) {
nodep->v3warn(E_UNSUPPORTED,
"Inline constraints are not supported for this node type");
return;
}
const AstNodeDType* const fromDTypep = callp->fromp()->dtypep();
UASSERT_OBJ(fromDTypep, callp->fromp(), "Object dtype is not linked");
const AstClassRefDType* const classrefdtypep
= VN_CAST(fromDTypep->skipRefp(), ClassRefDType);
UASSERT_OBJ(classrefdtypep, callp->fromp(),
"Randomize called on expression of non-class type "
<< fromDTypep->skipRefp()->prettyDTypeNameQ()
<< " (it should be detected earlier)");
classp = classrefdtypep->classp();
UASSERT_OBJ(classp, classrefdtypep, "Class type is unlinked to its ref type");
} else {

View File

@ -104,6 +104,17 @@ void invertAndMergeSenTreeMap(
for (const auto& pair : senTreeMap) result.emplace(pair.second, pair.first);
}
AstSenTree* findTriggeredIface(const AstVarScope* vscp,
const VirtIfaceTriggers::IfaceSensMap& vifTrigged,
const VirtIfaceTriggers::IfaceMemberSensMap& vifMemberTriggered) {
const auto ifaceIt = vifTrigged.find(vscp->varp()->sensIfacep());
if (ifaceIt != vifTrigged.end()) return ifaceIt->second;
for (const auto& memberIt : vifMemberTriggered) {
if (memberIt.first.m_ifacep == vscp->varp()->sensIfacep()) { return memberIt.second; }
}
return nullptr;
}
//============================================================================
// Code generation utility functions
@ -955,8 +966,10 @@ AstNode* createInputCombLoop(AstNetlist* netlistp, AstCFunc* const initFuncp,
AstSenTree* const dpiExportTriggered
= dpiExportTriggerVscp ? createTriggerSenTree(netlistp, trig.m_vscp, dpiExportTriggerIndex)
: nullptr;
const auto& vifTriggered
const auto& vifTriggeredIco
= virtIfaceTriggers.makeIfaceToSensMap(netlistp, firstVifTriggerIndex, trig.m_vscp);
const auto& vifMemberTriggeredIco
= virtIfaceTriggers.makeMemberToSensMap(netlistp, firstVifTriggerIndex, trig.m_vscp);
// Create and Order the body function
AstCFunc* const icoFuncp
@ -968,8 +981,9 @@ AstNode* createInputCombLoop(AstNetlist* netlistp, AstCFunc* const initFuncp,
}
if (varp->isWrittenByDpi()) out.push_back(dpiExportTriggered);
if (vscp->varp()->sensIfacep()) {
const auto it = vifTriggered.find(vscp->varp()->sensIfacep());
if (it != vifTriggered.end()) out.push_back(it->second);
AstSenTree* ifaceTriggered = findTriggeredIface(
vscp, vifTriggeredIco, vifMemberTriggeredIco);
out.push_back(ifaceTriggered);
}
});
splitCheck(icoFuncp);
@ -1371,6 +1385,8 @@ void schedule(AstNetlist* netlistp) {
const auto& vifTriggeredAct
= virtIfaceTriggers.makeIfaceToSensMap(netlistp, firstVifTriggerIndex, actTrig.m_vscp);
const auto& vifMemberTriggeredAct
= virtIfaceTriggers.makeMemberToSensMap(netlistp, firstVifTriggerIndex, actTrig.m_vscp);
AstCFunc* const actFuncp = V3Order::order(
netlistp, {&logicRegions.m_pre, &logicRegions.m_act, &logicReplicas.m_act}, trigToSenAct,
@ -1379,8 +1395,9 @@ void schedule(AstNetlist* netlistp) {
if (it != actTimingDomains.end()) out = it->second;
if (vscp->varp()->isWrittenByDpi()) out.push_back(dpiExportTriggeredAct);
if (vscp->varp()->sensIfacep()) {
const auto sit = vifTriggeredAct.find(vscp->varp()->sensIfacep());
if (sit != vifTriggeredAct.end()) out.push_back(sit->second);
AstSenTree* ifaceTriggered
= findTriggeredIface(vscp, vifTriggeredAct, vifMemberTriggeredAct);
out.push_back(ifaceTriggered);
}
});
splitCheck(actFuncp);
@ -1408,6 +1425,8 @@ void schedule(AstNetlist* netlistp) {
: nullptr;
const auto& vifTriggered
= virtIfaceTriggers.makeIfaceToSensMap(netlistp, firstVifTriggerIndex, trigVscp);
const auto& vifMemberTriggered
= virtIfaceTriggers.makeMemberToSensMap(netlistp, firstVifTriggerIndex, trigVscp);
const auto& timingDomains = timingKit.remapDomains(trigMap);
AstCFunc* const funcp = V3Order::order(
@ -1417,8 +1436,9 @@ void schedule(AstNetlist* netlistp) {
if (it != timingDomains.end()) out = it->second;
if (vscp->varp()->isWrittenByDpi()) out.push_back(dpiExportTriggered);
if (vscp->varp()->sensIfacep()) {
const auto sit = vifTriggered.find(vscp->varp()->sensIfacep());
if (sit != vifTriggered.end()) out.push_back(sit->second);
AstSenTree* ifaceTriggered
= findTriggeredIface(vscp, vifTriggered, vifMemberTriggered);
out.push_back(ifaceTriggered);
}
});

View File

@ -168,6 +168,7 @@ class VirtIfaceTriggers final {
}
};
public:
using IfaceMemberTrigger = std::pair<IfaceMember, AstVarScope*>;
using IfaceMemberTriggerVec = std::vector<IfaceMemberTrigger>;
using IfaceMemberSensMap = std::map<IfaceMember, AstSenTree*>;
@ -179,7 +180,6 @@ class VirtIfaceTriggers final {
IfaceMemberTriggerVec m_memberTriggers;
IfaceTriggerVec m_ifaceTriggers;
public:
void addMemberTrigger(const AstIface* ifacep, const AstVar* memberVarp,
AstVarScope* triggerVscp) {
m_memberTriggers.emplace_back(IfaceMember(ifacep, memberVarp), triggerVscp);

View File

@ -215,7 +215,7 @@ void V3Stats::statsStage(const string& name) {
V3Stats::addStatPerf("Stage, Elapsed time (sec), " + digitName, wallTimeDelta);
V3Stats::addStatPerf("Stage, Elapsed time (sec), TOTAL", wallTimeDelta);
const double memory = VlOs::memUsageBytes() / 1024.0 / 1024.0;
const double memory = VlOs::memPeakUsageBytes() / 1024.0 / 1024.0;
V3Stats::addStatPerf("Stage, Memory (MB), " + digitName, memory);
}
@ -266,7 +266,7 @@ void V3Stats::summaryReport() {
<< ", cvt=" << walltimeCvt << ", bld=" << walltimeBuild << "); cpu " << cputime
<< " s on " << std::max(v3Global.opt.verilateJobs(), v3Global.opt.buildJobs())
<< " threads";
const double memory = VlOs::memUsageBytes() / 1024.0 / 1024.0;
const double memory = VlOs::memPeakUsageBytes() / 1024.0 / 1024.0;
if (VL_UNCOVERABLE(memory != 0.0)) std::cout << "; alloced " << memory << " MB";
std::cout << "\n";
}

View File

@ -545,7 +545,7 @@ class UndrivenVisitor final : public VNVisitorConst {
void visit(AstPrimitive*) override {}
// Coverage artifacts etc shouldn't count as a sink
void visit(AstCoverDecl*) override {}
void visit(AstNodeCoverDecl*) override {}
void visit(AstCoverInc*) override {}
void visit(AstCoverToggle*) override {}
void visit(AstTraceDecl*) override {}

View File

@ -629,8 +629,8 @@ class WidthVisitor final : public VNVisitor {
iterateCheckString(nodep, "RHS", nodep->rhsp(), BOTH);
nodep->dtypeSetString();
} else {
iterateCheckSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH);
iterateCheckSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
iterateCheckIntegralSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH);
iterateCheckIntegralSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
if (m_streamConcat) {
packIfUnpacked(nodep->lhsp());
@ -837,7 +837,7 @@ class WidthVisitor final : public VNVisitor {
if (vdtypep && vdtypep->isString()) {
iterateCheckString(nodep, "LHS", nodep->srcp(), BOTH);
} else {
iterateCheckSelf(nodep, "LHS", nodep->srcp(), SELF, BOTH);
iterateCheckIntegralSelf(nodep, "LHS", nodep->srcp(), SELF, BOTH);
}
if ((vdtypep && vdtypep->isString()) || nodep->srcp()->isString()) {
@ -971,7 +971,7 @@ class WidthVisitor final : public VNVisitor {
if (debug() >= 9) nodep->dumpTree("- selWidth: ");
userIterateAndNext(nodep->fromp(), WidthVP{CONTEXT_DET, PRELIM}.p());
userIterateAndNext(nodep->lsbp(), WidthVP{SELF, PRELIM}.p());
checkCvtUS(nodep->fromp());
checkCvtUS(nodep->fromp(), false);
iterateCheckSizedSelf(nodep, "Select LHS", nodep->fromp(), SELF, BOTH);
int width = nodep->widthConst();
if (width <= 0) {
@ -1510,7 +1510,7 @@ class WidthVisitor final : public VNVisitor {
return;
}
checkCvtUS(nodep->lhsp());
checkCvtUS(nodep->lhsp(), false);
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
nodep->dtypeFrom(nodep->lhsp());
}
@ -2422,6 +2422,18 @@ class WidthVisitor final : public VNVisitor {
nodep->dtypeSetLogicSized(1, bdtypep->numeric());
VL_DANGLING(bdtypep);
}
if (nodep->isNet()) {
AstNodeDType* const badDtp = dtypeNot4StateIntegralRecurse(nodep->dtypep());
if (badDtp)
nodep->v3error(
"Net " << nodep->prettyNameQ()
<< " data type must be 4-state integral or array/union/struct of such"
<< " (IEEE 1800-2023 6.7.1)\n"
<< nodep->warnContextPrimary() << '\n'
<< badDtp->warnOther() << "... Location of failing data type "
<< badDtp->prettyDTypeNameQ() << '\n'
<< badDtp->warnContextSecondary());
}
if (nodep->valuep() && !didchk) {
// if (debug()) nodep->dumpTree("- final: ");
// AstPattern requires assignments to pass datatype on PRELIM
@ -2483,10 +2495,15 @@ class WidthVisitor final : public VNVisitor {
UINFO(5, " ENUMDTYPE " << nodep);
nodep->refDTypep(iterateEditMoveDTypep(nodep, nodep->subDTypep()));
nodep->dtypep(nodep);
AstBasicDType* basicp = nodep->dtypep()->skipRefp()->basicp();
if (!basicp || !basicp->keyword().isIntNumeric()) {
AstNodeDType* basicp = nodep->dtypep()->skipRefp()->basicp();
AstNodeDType* const badDtp = dtypeNotIntAtomOrVecRecurse(nodep->subDTypep());
if (badDtp) {
nodep->v3error(
"Enum type must be an integer atom or vector type (IEEE 1800-2023 6.19)");
"Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19)\n"
<< nodep->warnContextPrimary() << '\n'
<< badDtp->warnOther() << "... Location of failing data type "
<< badDtp->prettyDTypeNameQ() << '\n'
<< badDtp->warnContextSecondary());
basicp = nodep->findSigned32DType()->basicp();
nodep->refDTypep(basicp);
}
@ -6826,7 +6843,7 @@ class WidthVisitor final : public VNVisitor {
UASSERT_OBJ(!nodep->op2p(), nodep, "For unary ops only!");
if (m_vup->prelim()) {
userIterateAndNext(nodep->lhsp(), WidthVP{CONTEXT_DET, PRELIM}.p());
if (!real_ok) checkCvtUS(nodep->lhsp());
if (!real_ok) checkCvtUS(nodep->lhsp(), false);
}
if (real_ok && nodep->lhsp()->isDouble()) {
spliceCvtD(nodep->lhsp());
@ -6867,7 +6884,7 @@ class WidthVisitor final : public VNVisitor {
UASSERT_OBJ(!nodep->op2p(), nodep, "For unary ops only!");
if (m_vup->prelim()) {
userIterateAndNext(nodep->lhsp(), WidthVP{SELF, PRELIM}.p());
checkCvtUS(nodep->lhsp());
checkCvtUS(nodep->lhsp(), true);
const int width = nodep->lhsp()->width();
AstNodeDType* const expDTypep = nodep->findLogicDType(width, width, rs_out);
nodep->dtypep(expDTypep);
@ -6895,7 +6912,7 @@ class WidthVisitor final : public VNVisitor {
// RHS is self-determined. RHS is always treated as unsigned, has no effect on result.
if (m_vup->prelim()) {
userIterateAndNext(nodep->lhsp(), WidthVP{SELF, PRELIM}.p());
checkCvtUS(nodep->lhsp());
checkCvtUS(nodep->lhsp(), false);
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
nodep->dtypeFrom(nodep->lhsp());
}
@ -6955,8 +6972,8 @@ class WidthVisitor final : public VNVisitor {
// Determine expression widths only relying on what's in the subops
userIterateAndNext(nodep->lhsp(), WidthVP{CONTEXT_DET, PRELIM}.p());
userIterateAndNext(nodep->rhsp(), WidthVP{CONTEXT_DET, PRELIM}.p());
checkCvtUS(nodep->lhsp());
checkCvtUS(nodep->rhsp());
checkCvtUS(nodep->lhsp(), false);
checkCvtUS(nodep->rhsp(), false);
const int width = std::max(nodep->lhsp()->width(), nodep->rhsp()->width());
const int mwidth = std::max(nodep->lhsp()->widthMin(), nodep->rhsp()->widthMin());
const bool expSigned = (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned());
@ -6990,8 +7007,8 @@ class WidthVisitor final : public VNVisitor {
userIterateAndNext(nodep->lhsp(), WidthVP{CONTEXT_DET, PRELIM}.p());
userIterateAndNext(nodep->rhsp(), WidthVP{CONTEXT_DET, PRELIM}.p());
if (!real_ok) {
checkCvtUS(nodep->lhsp());
checkCvtUS(nodep->rhsp());
checkCvtUS(nodep->lhsp(), false);
checkCvtUS(nodep->rhsp(), false);
}
if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) {
spliceCvtD(nodep->lhsp());
@ -7330,8 +7347,12 @@ class WidthVisitor final : public VNVisitor {
}
(void)underp; // cppcheck
}
void iterateCheckIntegralSelf(AstNode* nodep, const char* side, AstNode* underp, Determ determ,
Stage stage) {
iterateCheckSelf(nodep, side, underp, determ, stage, true);
}
void iterateCheckSelf(AstNode* nodep, const char* side, AstNode* underp, Determ determ,
Stage stage) {
Stage stage, bool integralOnly = false) {
// Coerce child to any data type; child is self-determined
// i.e. isolated from expected type.
// e.g. nodep=CONCAT, underp=lhs in CONCAT(lhs,rhs)
@ -7341,7 +7362,8 @@ class WidthVisitor final : public VNVisitor {
if (stage & PRELIM) {
underp = userIterateSubtreeReturnEdits(underp, WidthVP{SELF, PRELIM}.p());
}
underp = VN_IS(underp, NodeExpr) ? checkCvtUS(VN_AS(underp, NodeExpr)) : underp;
underp
= VN_IS(underp, NodeExpr) ? checkCvtUS(VN_AS(underp, NodeExpr), integralOnly) : underp;
AstNodeDType* const expDTypep = underp->dtypep();
underp = iterateCheck(nodep, side, underp, SELF, FINAL, expDTypep, EXTEND_EXP);
(void)underp; // cppcheck
@ -7357,7 +7379,7 @@ class WidthVisitor final : public VNVisitor {
if (stage & PRELIM) {
underp = userIterateSubtreeReturnEdits(underp, WidthVP{SELF, PRELIM}.p());
}
underp = VN_IS(underp, NodeExpr) ? checkCvtUS(VN_AS(underp, NodeExpr)) : underp;
underp = VN_IS(underp, NodeExpr) ? checkCvtUS(VN_AS(underp, NodeExpr), false) : underp;
AstNodeDType* const expDTypep = underp->dtypep();
underp = iterateCheck(nodep, side, underp, SELF, FINAL, expDTypep, EXTEND_EXP);
AstNodeDType* const checkDtp = expDTypep->skipRefToEnump();
@ -7674,12 +7696,16 @@ class WidthVisitor final : public VNVisitor {
//----------------------------------------------------------------------
// SIGNED/DOUBLE METHODS
AstNodeExpr* checkCvtUS(AstNodeExpr* nodep) {
if (nodep && nodep->isDouble()) {
nodep->v3error("Expected integral (non-" << nodep->dtypep()->prettyDTypeNameQ()
<< ") input to "
<< nodep->backp()->prettyTypeName());
nodep = spliceCvtS(nodep, true, 32);
AstNodeExpr* checkCvtUS(AstNodeExpr* nodep, bool fatal) {
if (nodep && nodep->dtypep()->skipRefp()->isDouble()) {
if (fatal) {
nodep->v3error("Expected integral input to " << nodep->backp()->prettyTypeName());
} else {
nodep->v3warn(REALCVT,
"Implicit conversion of real to integer; expected integral input to "
<< nodep->backp()->prettyTypeName());
}
nodep = spliceCvtS(nodep, false, 32);
}
return nodep;
}
@ -8300,6 +8326,39 @@ class WidthVisitor final : public VNVisitor {
if (nodep->subDTypep()) return hasOpenArrayIterateDType(nodep->subDTypep()->skipRefp());
return false;
}
AstNodeDType* dtypeNotIntAtomOrVecRecurse(AstNodeDType* nodep, bool ranged = false) {
// If node is _not_ integer or atomic, return node that makes it fail
nodep = nodep->skipRefToEnump();
if (AstBasicDType* const dtp = VN_CAST(nodep, BasicDType)) {
if (ranged && (!dtp->isBitLogic() || dtp->isRanged()))
return dtp; // Packed when already packed
if (dtp->keyword().isIntNumeric()) return nullptr;
return dtp;
} else if (AstPackArrayDType* const dtp = VN_CAST(nodep, PackArrayDType)) {
if (ranged) return dtp; // Packed when already packed
return dtypeNotIntAtomOrVecRecurse(nodep->subDTypep(), true);
}
return nodep;
}
AstNodeDType* dtypeNot4StateIntegralRecurse(AstNodeDType* nodep) {
// If node is _not_ inet valid data type, 4-state integral packed or union, return node
// that makes it fail
nodep = nodep->skipRefp();
if (AstBasicDType* const dtp = VN_CAST(nodep, BasicDType)) {
if (!dtp->keyword().isFourstate()) return dtp;
return nullptr;
} else if (AstNodeArrayDType* const dtp = VN_CAST(nodep, NodeArrayDType)) {
return dtypeNot4StateIntegralRecurse(dtp->subDTypep());
} else if (AstNodeUOrStructDType* const dtp = VN_CAST(nodep, NodeUOrStructDType)) {
for (AstMemberDType* itemp = dtp->membersp(); itemp;
itemp = VN_AS(itemp->nextp(), MemberDType)) {
AstNodeDType* const badDtp = dtypeNot4StateIntegralRecurse(itemp->dtypep());
if (badDtp) return badDtp;
}
return nullptr;
}
return nodep;
}
//----------------------------------------------------------------------
// METHODS - special type detection

View File

@ -649,7 +649,6 @@ static void process() {
// Final statistics
if (v3Global.opt.stats()) V3Stats::statsStage("emit");
reportStatsIfEnabled();
}
static void verilate(const string& argString) {
@ -769,6 +768,7 @@ static void verilate(const string& argString) {
V3Os::filesystemFlushBuildDir(v3Global.opt.makeDir());
if (v3Global.opt.hierTop()) V3Os::filesystemFlushBuildDir(v3Global.opt.hierTopDataDir());
if (v3Global.opt.stats()) V3Stats::statsStage("wrote");
// Final writing shouldn't throw warnings, but...
V3Error::abortIfWarnings();
@ -867,6 +867,7 @@ int main(int argc, char** argv) {
execBuildJob();
}
reportStatsIfEnabled();
V3DiagSarif::output(true);
// Explicitly release resources

View File

@ -270,6 +270,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$rewind" { FL; return yD_REWIND; }
"$rtoi" { FL; return yD_RTOI; }
"$sampled" { FL; return yD_SAMPLED; }
"$sdf_annotate" { FL; return yD_SDF_ANNOTATE; }
"$setup" { FL; return yaTIMINGSPEC; }
"$setuphold" { FL; return yD_SETUPHOLD; }
"$sformat" { FL; return yD_SFORMAT; }

View File

@ -98,6 +98,7 @@ public:
bool m_tracingParse = true; // Tracing disable for parser
bool m_inImplements = false; // Is inside class implements list
bool m_insideProperty = false; // Is inside property declaration
bool m_specifyignWarned = false; // Issued a SPECIFYIGN warning
bool m_typedPropertyPort = false; // Typed property port occurred on port lists
bool m_modportImpExpActive
= false; // Standalone ID is a tf_identifier instead of port_identifier
@ -926,6 +927,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
%token<fl> yD_ROSE_GCLK "$rose_gclk"
%token<fl> yD_RTOI "$rtoi"
%token<fl> yD_SAMPLED "$sampled"
%token<fl> yD_SDF_ANNOTATE "$sdf_annotate"
%token<fl> yD_SETUPHOLD "$setuphold"
%token<fl> yD_SFORMAT "$sformat"
%token<fl> yD_SFORMATF "$sformatf"
@ -2226,10 +2228,11 @@ data_typeNoRef<nodeDTypep>: // ==IEEE: data_type, excluding class_ty
new AstDefImplicitDType{$1->fileline(),
"__typeimpsu" + cvtToStr(GRAMMARP->s_typeImpNum++),
VFlagChildDType{}, $1}, $2, true); }
| enumDecl
{ $$ = new AstDefImplicitDType{$1->fileline(),
"__typeimpenum" + cvtToStr(GRAMMARP->s_typeImpNum++),
VFlagChildDType{}, $1}; }
| enumDecl packed_dimensionListE
{ $$ = GRAMMARP->createArray(
new AstDefImplicitDType{$1->fileline(),
"__typeimpenum" + cvtToStr(GRAMMARP->s_typeImpNum++),
VFlagChildDType{}, $1}, $2, true); }
| ySTRING
{ $$ = new AstBasicDType{$1, VBasicDTypeKwd::STRING}; }
| yCHANDLE
@ -4180,6 +4183,7 @@ loop_variables<nodep>: // IEEE: loop_variables
parseRefBase { $$ = $1; }
| loop_variables ',' parseRefBase { $$ = $1->addNext($3); }
| ',' parseRefBase { $$ = new AstEmpty{$1}; $$->addNext($2); }
| ',' { $$ = new AstEmpty{$1}; }
;
//************************************************
@ -4282,6 +4286,7 @@ system_t_call<nodeStmtp>: // IEEE: system_tf_call (as task)
| yD_DUMPON '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::ON}; DEL($3); }
//
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? nullptr : new AstUCStmt{$1, $3}); }
| yD_SDF_ANNOTATE '(' exprEListE ')' { $$ = nullptr; $1->v3warn(SPECIFYIGN, "Ignoring unsupported: $sdf_annotate"); }
| yD_STACKTRACE parenE { $$ = new AstStackTraceT{$1}; }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemT{$1, $3}; }
//
@ -5351,6 +5356,11 @@ exprList<nodeExprp>:
| exprList ',' expr { $$ = $1->addNext($3); }
;
exprEListE<nodep>: // expression list with empty commas allowed
exprE { $$ = $1; }
| exprEListE ',' exprE { $$ = addNextNull($1, $3); }
;
exprDispList<nodeExprp>: // exprList for within $display
expr { $$ = $1; }
| exprDispList ',' expr { $$ = $1->addNext($3); }
@ -5823,8 +5833,12 @@ tablelVal<udpTableLineValp>:
// Specify
specify_block<nodep>: // ==IEEE: specify_block
ySPECIFY specify_itemList yENDSPECIFY { $$ = $2; }
| ySPECIFY yENDSPECIFY { $$ = nullptr; }
specifyFront specify_itemList yENDSPECIFY { $$ = $2; }
| specifyFront yENDSPECIFY { $$ = nullptr; }
;
specifyFront: // IEEE: specify_block front
ySPECIFY { GRAMMARP->m_specifyignWarned = false; }
;
specify_itemList<nodep>: // IEEE: { specify_item }
@ -5835,7 +5849,13 @@ specify_itemList<nodep>: // IEEE: { specify_item }
specify_item<nodep>: // ==IEEE: specify_item
specparam_declaration { $$ = $1; }
| system_timing_check { $$ = $1; }
| junkToSemiList ';' { $$ = nullptr; }
| junkToSemiList ';'
{ $$ = nullptr;
if (!GRAMMARP->m_specifyignWarned) {
GRAMMARP->m_specifyignWarned = true;
$1->v3warn(SPECIFYIGN, "Ignoring unsupported: specify block construct");
}
}
;
specparam_declaration<nodep>: // ==IEEE: specparam_declaration
@ -5924,9 +5944,9 @@ idAnyE<strp>:
| idAny { $$ = $1; }
;
junkToSemiList:
junkToSemi { } /* ignored */
| junkToSemiList junkToSemi { } /* ignored */
junkToSemiList<fl>:
junkToSemi { $$ = CRELINE(); }
| junkToSemiList junkToSemi { $$ = CRELINE(); }
;
junkToSemi:
@ -6118,6 +6138,8 @@ idArrayedForeach<nodeExprp>: // IEEE: id + select (under foreach expression)
| idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus{$2, $1, $3, $5}; }
// // IEEE: loop_variables (under foreach expression)
// // To avoid conflicts we allow expr as first element, must post-check
| idArrayed '[' ']'
{ $$ = new AstSelLoopVars{$2, $1, new AstEmpty{$3}}; }
| idArrayed '[' expr ',' loop_variables ']'
{ $$ = new AstSelLoopVars{$2, $1, addNextNull(static_cast<AstNode*>($3), $5)}; }
| idArrayed '[' ',' loop_variables ']'
@ -6821,21 +6843,38 @@ covergroup_declaration<nodep>: // ==IEEE: covergroup_declaration
| covergroup_declarationFront '(' tf_port_listE ')'
/*cont*/ coverage_eventE ';' coverage_spec_or_optionListE
/*cont*/ yENDGROUP endLabelE
{ $$ = $1;
{ AstFunc* const newp = new AstFunc{$<fl>1, "new", nullptr, nullptr};
newp->classMethod(true);
newp->isConstructor(true);
newp->dtypep($1->dtypep());
newp->addStmtsp($3);
$1->addMembersp(newp);
$$ = $1;
GRAMMARP->endLabel($<fl>9, $1, $9); }
// // IEEE 1800-2023 added:
| covergroup_declarationFront yEXTENDS idAny/*covergroup_identifier*/
/*cont*/ ';' coverage_spec_or_optionListE
/*cont*/ yENDGROUP endLabelE
{ $$ = $1;
GRAMMARP->endLabel($<fl>7, $1, $7); }
;
covergroup_extendsE<fl>: // IEEE: Part of covergroup_declaration
/* empty */ { $$ = nullptr; }
| yEXTENDS { $$ = $1; }
;
covergroup_declarationFront<classp>: // IEEE: part of covergroup_declaration
yCOVERGROUP idAny
{ $$ = new AstClass{$<fl>2, *$2, PARSEP->libname()};
yCOVERGROUP covergroup_extendsE idAny
{
$$ = new AstClass{$<fl>3, *$3, PARSEP->libname()};
AstFunc* const sample = new AstFunc{$<fl>1, "sample", nullptr, nullptr};
sample->classMethod(true);
sample->dtypep(sample->findVoidDType());
$$->addMembersp(sample);
AstFunc* const getCoverage = new AstFunc{$<fl>1, "get_coverage", nullptr, nullptr};
getCoverage->classMethod(true);
getCoverage->dtypep(getCoverage->findVoidDType());
$$->addMembersp(getCoverage);
BBCOVERIGN($<fl>1, "Ignoring unsupported: covergroup"); }
;
;
cgexpr<nodeExprp>: // IEEE-2012: covergroup_expression, before that just expression
expr { $$ = $1; }
@ -7005,7 +7044,7 @@ cross_itemList<nodep>: // IEEE: part of list_of_cross_items
;
cross_item<nodep>: // ==IEEE: cross_item
idAny/*cover_point_identifier or variable_identifier*/ { $$ = nullptr; /*UNSUP*/ }
idDotted/*cover_point_identifier or variable_identifier*/ { $1->deleteTree(); $$ = nullptr; /*UNSUP*/ }
;
cross_body<nodep>: // ==IEEE: cross_body
@ -7551,7 +7590,12 @@ class_item<nodep>: // ==IEEE: class_item
| class_declaration { $$ = $1; }
| timeunits_declaration { $$ = $1; }
| covergroup_declaration
{ $$ = nullptr; BBCOVERIGN($1, "Ignoring unsupported: covergroup within class"); }
{
const string cgName = $1->name();
$1->name("__vlAnonCG_" + cgName);
AstVar* const newp = new AstVar{$<fl>1, VVarType::VAR, cgName, VFlagChildDType{}, new AstRefDType($<fl>1, $1->name())};
$$ = addNextNull($1, newp);
}
// // local_parameter_declaration under parameter_declaration
| parameter_declaration ';' { $$ = $1; }
| ';' { $$ = nullptr; }

View File

@ -5,290 +5,284 @@
// SPDX-License-Identifier: CC0-1.0
module t_case_huge_sub (/*AUTOARG*/
// Outputs
outa, outb, outc,
// Inputs
index
);
// Outputs
outa, outb, outc,
// Inputs
index
);
input [7:0] index;
output [9:0] outa;
output [1:0] outb;
output outc;
input [7:0] index;
output logic [9:0] outa;
output logic [1:0] outb;
output logic outc;
// =============================
/*AUTOREG*/
// Beginning of automatic regs (for this module's undeclared outputs)
reg [9:0] outa;
reg [1:0] outb;
reg outc;
// End of automatics
// =============================
// Created from Python3:
// for i in range(1024):
// print(" 10'h%03x: begin outa = 10'h%03x; outb = 2'b%d%d; outc = 1'b%d; end"
// % (i, random.randint(0,1024), random.randint(0,1),
// random.randint(0,1), random.randint(0,1)))
// =============================
// Created from Python3:
// for i in range(1024):
// print(" 10'h%03x: begin outa = 10'h%03x; outb = 2'b%d%d; outc = 1'b%d; end"
// % (i, random.randint(0,1024), random.randint(0,1),
// random.randint(0,1), random.randint(0,1)))
always @(/*AS*/index) begin
case (index)
8'h00: begin outa = 10'h152; outb = 2'b00; outc = 1'b1; end
8'h01: begin outa = 10'h318; outb = 2'b11; outc = 1'b1; end
8'h02: begin outa = 10'h29f; outb = 2'b11; outc = 1'b0; end
8'h03: begin outa = 10'h392; outb = 2'b01; outc = 1'b1; end
8'h04: begin outa = 10'h1ef; outb = 2'b00; outc = 1'b0; end
8'h05: begin outa = 10'h06c; outb = 2'b10; outc = 1'b1; end
8'h06: begin outa = 10'h29f; outb = 2'b11; outc = 1'b0; end
8'h07: begin outa = 10'h29a; outb = 2'b10; outc = 1'b0; end
8'h08: begin outa = 10'h3ce; outb = 2'b01; outc = 1'b0; end
8'h09: begin outa = 10'h37c; outb = 2'b01; outc = 1'b0; end
8'h0a: begin outa = 10'h058; outb = 2'b10; outc = 1'b0; end
8'h0b: begin outa = 10'h3b2; outb = 2'b01; outc = 1'b1; end
8'h0c: begin outa = 10'h36f; outb = 2'b11; outc = 1'b0; end
8'h0d: begin outa = 10'h2c5; outb = 2'b11; outc = 1'b0; end
8'h0e: begin outa = 10'h23a; outb = 2'b00; outc = 1'b0; end
8'h0f: begin outa = 10'h222; outb = 2'b01; outc = 1'b1; end
8'h10: begin outa = 10'h328; outb = 2'b00; outc = 1'b1; end
8'h11: begin outa = 10'h3c3; outb = 2'b00; outc = 1'b1; end
8'h12: begin outa = 10'h12c; outb = 2'b01; outc = 1'b0; end
8'h13: begin outa = 10'h1d0; outb = 2'b00; outc = 1'b1; end
8'h14: begin outa = 10'h3ff; outb = 2'b01; outc = 1'b1; end
8'h15: begin outa = 10'h115; outb = 2'b11; outc = 1'b1; end
8'h16: begin outa = 10'h3ba; outb = 2'b10; outc = 1'b0; end
8'h17: begin outa = 10'h3ba; outb = 2'b00; outc = 1'b0; end
8'h18: begin outa = 10'h10d; outb = 2'b00; outc = 1'b1; end
8'h19: begin outa = 10'h13b; outb = 2'b01; outc = 1'b1; end
8'h1a: begin outa = 10'h0a0; outb = 2'b10; outc = 1'b1; end
8'h1b: begin outa = 10'h264; outb = 2'b11; outc = 1'b0; end
8'h1c: begin outa = 10'h3a2; outb = 2'b10; outc = 1'b0; end
8'h1d: begin outa = 10'h07c; outb = 2'b00; outc = 1'b1; end
8'h1e: begin outa = 10'h291; outb = 2'b00; outc = 1'b0; end
8'h1f: begin outa = 10'h1d1; outb = 2'b10; outc = 1'b0; end
8'h20: begin outa = 10'h354; outb = 2'b11; outc = 1'b1; end
8'h21: begin outa = 10'h0c0; outb = 2'b00; outc = 1'b1; end
8'h22: begin outa = 10'h191; outb = 2'b00; outc = 1'b0; end
8'h23: begin outa = 10'h379; outb = 2'b01; outc = 1'b0; end
8'h24: begin outa = 10'h073; outb = 2'b00; outc = 1'b0; end
8'h25: begin outa = 10'h2fd; outb = 2'b11; outc = 1'b1; end
8'h26: begin outa = 10'h2e0; outb = 2'b11; outc = 1'b1; end
8'h27: begin outa = 10'h337; outb = 2'b01; outc = 1'b1; end
8'h28: begin outa = 10'h2c7; outb = 2'b11; outc = 1'b1; end
8'h29: begin outa = 10'h19e; outb = 2'b11; outc = 1'b0; end
8'h2a: begin outa = 10'h107; outb = 2'b10; outc = 1'b0; end
8'h2b: begin outa = 10'h06a; outb = 2'b01; outc = 1'b1; end
8'h2c: begin outa = 10'h1c7; outb = 2'b01; outc = 1'b1; end
8'h2d: begin outa = 10'h107; outb = 2'b10; outc = 1'b0; end
8'h2e: begin outa = 10'h0cf; outb = 2'b01; outc = 1'b1; end
8'h2f: begin outa = 10'h009; outb = 2'b11; outc = 1'b1; end
8'h30: begin outa = 10'h09d; outb = 2'b00; outc = 1'b1; end
8'h31: begin outa = 10'h28e; outb = 2'b00; outc = 1'b0; end
8'h32: begin outa = 10'h010; outb = 2'b01; outc = 1'b0; end
8'h33: begin outa = 10'h1e0; outb = 2'b10; outc = 1'b0; end
8'h34: begin outa = 10'h079; outb = 2'b01; outc = 1'b1; end
8'h35: begin outa = 10'h13e; outb = 2'b10; outc = 1'b1; end
8'h36: begin outa = 10'h282; outb = 2'b11; outc = 1'b0; end
8'h37: begin outa = 10'h21c; outb = 2'b11; outc = 1'b1; end
8'h38: begin outa = 10'h148; outb = 2'b00; outc = 1'b1; end
8'h39: begin outa = 10'h3c0; outb = 2'b10; outc = 1'b0; end
8'h3a: begin outa = 10'h176; outb = 2'b01; outc = 1'b1; end
8'h3b: begin outa = 10'h3fc; outb = 2'b10; outc = 1'b1; end
8'h3c: begin outa = 10'h295; outb = 2'b11; outc = 1'b1; end
8'h3d: begin outa = 10'h113; outb = 2'b10; outc = 1'b1; end
8'h3e: begin outa = 10'h354; outb = 2'b01; outc = 1'b1; end
8'h3f: begin outa = 10'h0db; outb = 2'b11; outc = 1'b0; end
8'h40: begin outa = 10'h238; outb = 2'b01; outc = 1'b0; end
8'h41: begin outa = 10'h12b; outb = 2'b01; outc = 1'b1; end
8'h42: begin outa = 10'h1dc; outb = 2'b10; outc = 1'b0; end
8'h43: begin outa = 10'h137; outb = 2'b01; outc = 1'b1; end
8'h44: begin outa = 10'h1e2; outb = 2'b01; outc = 1'b1; end
8'h45: begin outa = 10'h3d5; outb = 2'b11; outc = 1'b1; end
8'h46: begin outa = 10'h30c; outb = 2'b11; outc = 1'b0; end
8'h47: begin outa = 10'h298; outb = 2'b11; outc = 1'b0; end
8'h48: begin outa = 10'h080; outb = 2'b00; outc = 1'b1; end
8'h49: begin outa = 10'h35a; outb = 2'b11; outc = 1'b1; end
8'h4a: begin outa = 10'h01b; outb = 2'b00; outc = 1'b0; end
8'h4b: begin outa = 10'h0a3; outb = 2'b11; outc = 1'b0; end
8'h4c: begin outa = 10'h0b3; outb = 2'b11; outc = 1'b1; end
8'h4d: begin outa = 10'h17a; outb = 2'b00; outc = 1'b0; end
8'h4e: begin outa = 10'h3ae; outb = 2'b11; outc = 1'b0; end
8'h4f: begin outa = 10'h078; outb = 2'b11; outc = 1'b0; end
8'h50: begin outa = 10'h322; outb = 2'b00; outc = 1'b1; end
8'h51: begin outa = 10'h213; outb = 2'b11; outc = 1'b0; end
8'h52: begin outa = 10'h11a; outb = 2'b11; outc = 1'b0; end
8'h53: begin outa = 10'h1a7; outb = 2'b00; outc = 1'b0; end
8'h54: begin outa = 10'h35a; outb = 2'b00; outc = 1'b1; end
8'h55: begin outa = 10'h233; outb = 2'b00; outc = 1'b0; end
8'h56: begin outa = 10'h01d; outb = 2'b01; outc = 1'b1; end
8'h57: begin outa = 10'h2d5; outb = 2'b00; outc = 1'b0; end
8'h58: begin outa = 10'h1a0; outb = 2'b00; outc = 1'b1; end
8'h59: begin outa = 10'h3d0; outb = 2'b00; outc = 1'b1; end
8'h5a: begin outa = 10'h181; outb = 2'b01; outc = 1'b1; end
8'h5b: begin outa = 10'h219; outb = 2'b01; outc = 1'b1; end
8'h5c: begin outa = 10'h26a; outb = 2'b01; outc = 1'b1; end
8'h5d: begin outa = 10'h050; outb = 2'b10; outc = 1'b0; end
8'h5e: begin outa = 10'h189; outb = 2'b10; outc = 1'b0; end
8'h5f: begin outa = 10'h1eb; outb = 2'b01; outc = 1'b1; end
8'h60: begin outa = 10'h224; outb = 2'b00; outc = 1'b1; end
8'h61: begin outa = 10'h2fe; outb = 2'b00; outc = 1'b0; end
8'h62: begin outa = 10'h0ae; outb = 2'b00; outc = 1'b1; end
8'h63: begin outa = 10'h1cd; outb = 2'b00; outc = 1'b0; end
8'h64: begin outa = 10'h273; outb = 2'b10; outc = 1'b1; end
8'h65: begin outa = 10'h268; outb = 2'b10; outc = 1'b0; end
8'h66: begin outa = 10'h111; outb = 2'b01; outc = 1'b0; end
8'h67: begin outa = 10'h1f9; outb = 2'b00; outc = 1'b0; end
8'h68: begin outa = 10'h232; outb = 2'b00; outc = 1'b1; end
8'h69: begin outa = 10'h255; outb = 2'b11; outc = 1'b0; end
8'h6a: begin outa = 10'h34c; outb = 2'b01; outc = 1'b1; end
8'h6b: begin outa = 10'h049; outb = 2'b01; outc = 1'b1; end
8'h6c: begin outa = 10'h197; outb = 2'b11; outc = 1'b0; end
8'h6d: begin outa = 10'h0fe; outb = 2'b11; outc = 1'b0; end
8'h6e: begin outa = 10'h253; outb = 2'b01; outc = 1'b1; end
8'h6f: begin outa = 10'h2de; outb = 2'b11; outc = 1'b0; end
8'h70: begin outa = 10'h13b; outb = 2'b10; outc = 1'b1; end
8'h71: begin outa = 10'h040; outb = 2'b10; outc = 1'b0; end
8'h72: begin outa = 10'h0b4; outb = 2'b00; outc = 1'b1; end
8'h73: begin outa = 10'h233; outb = 2'b11; outc = 1'b1; end
8'h74: begin outa = 10'h198; outb = 2'b00; outc = 1'b1; end
8'h75: begin outa = 10'h018; outb = 2'b00; outc = 1'b1; end
8'h76: begin outa = 10'h2f7; outb = 2'b00; outc = 1'b1; end
8'h77: begin outa = 10'h134; outb = 2'b11; outc = 1'b0; end
8'h78: begin outa = 10'h1ca; outb = 2'b10; outc = 1'b0; end
8'h79: begin outa = 10'h286; outb = 2'b10; outc = 1'b1; end
8'h7a: begin outa = 10'h0e6; outb = 2'b11; outc = 1'b1; end
8'h7b: begin outa = 10'h064; outb = 2'b10; outc = 1'b1; end
8'h7c: begin outa = 10'h257; outb = 2'b00; outc = 1'b1; end
8'h7d: begin outa = 10'h31a; outb = 2'b10; outc = 1'b1; end
8'h7e: begin outa = 10'h247; outb = 2'b01; outc = 1'b0; end
8'h7f: begin outa = 10'h299; outb = 2'b00; outc = 1'b0; end
8'h80: begin outa = 10'h02c; outb = 2'b00; outc = 1'b0; end
8'h81: begin outa = 10'h2bb; outb = 2'b11; outc = 1'b0; end
8'h82: begin outa = 10'h180; outb = 2'b10; outc = 1'b0; end
8'h83: begin outa = 10'h245; outb = 2'b01; outc = 1'b1; end
8'h84: begin outa = 10'h0da; outb = 2'b10; outc = 1'b0; end
8'h85: begin outa = 10'h367; outb = 2'b10; outc = 1'b0; end
8'h86: begin outa = 10'h304; outb = 2'b01; outc = 1'b0; end
8'h87: begin outa = 10'h38b; outb = 2'b11; outc = 1'b0; end
8'h88: begin outa = 10'h09f; outb = 2'b01; outc = 1'b0; end
8'h89: begin outa = 10'h1f0; outb = 2'b10; outc = 1'b1; end
8'h8a: begin outa = 10'h281; outb = 2'b10; outc = 1'b1; end
8'h8b: begin outa = 10'h019; outb = 2'b00; outc = 1'b0; end
8'h8c: begin outa = 10'h1f2; outb = 2'b10; outc = 1'b0; end
8'h8d: begin outa = 10'h0b1; outb = 2'b01; outc = 1'b1; end
8'h8e: begin outa = 10'h058; outb = 2'b01; outc = 1'b1; end
8'h8f: begin outa = 10'h39b; outb = 2'b00; outc = 1'b1; end
8'h90: begin outa = 10'h2ec; outb = 2'b10; outc = 1'b1; end
8'h91: begin outa = 10'h250; outb = 2'b00; outc = 1'b1; end
8'h92: begin outa = 10'h3f4; outb = 2'b10; outc = 1'b1; end
8'h93: begin outa = 10'h057; outb = 2'b10; outc = 1'b1; end
8'h94: begin outa = 10'h18f; outb = 2'b01; outc = 1'b1; end
8'h95: begin outa = 10'h105; outb = 2'b01; outc = 1'b1; end
8'h96: begin outa = 10'h1ae; outb = 2'b00; outc = 1'b1; end
8'h97: begin outa = 10'h04e; outb = 2'b10; outc = 1'b0; end
8'h98: begin outa = 10'h240; outb = 2'b11; outc = 1'b0; end
8'h99: begin outa = 10'h3e4; outb = 2'b01; outc = 1'b0; end
8'h9a: begin outa = 10'h3c6; outb = 2'b01; outc = 1'b0; end
8'h9b: begin outa = 10'h109; outb = 2'b00; outc = 1'b1; end
8'h9c: begin outa = 10'h073; outb = 2'b10; outc = 1'b1; end
8'h9d: begin outa = 10'h19f; outb = 2'b01; outc = 1'b0; end
8'h9e: begin outa = 10'h3b8; outb = 2'b01; outc = 1'b0; end
8'h9f: begin outa = 10'h00e; outb = 2'b00; outc = 1'b1; end
8'ha0: begin outa = 10'h1b3; outb = 2'b11; outc = 1'b1; end
8'ha1: begin outa = 10'h2bd; outb = 2'b11; outc = 1'b0; end
8'ha2: begin outa = 10'h324; outb = 2'b00; outc = 1'b1; end
8'ha3: begin outa = 10'h343; outb = 2'b10; outc = 1'b0; end
8'ha4: begin outa = 10'h1c9; outb = 2'b01; outc = 1'b0; end
8'ha5: begin outa = 10'h185; outb = 2'b00; outc = 1'b1; end
8'ha6: begin outa = 10'h37a; outb = 2'b00; outc = 1'b1; end
8'ha7: begin outa = 10'h0e0; outb = 2'b01; outc = 1'b1; end
8'ha8: begin outa = 10'h0a3; outb = 2'b10; outc = 1'b0; end
8'ha9: begin outa = 10'h019; outb = 2'b11; outc = 1'b0; end
8'haa: begin outa = 10'h099; outb = 2'b00; outc = 1'b1; end
8'hab: begin outa = 10'h376; outb = 2'b01; outc = 1'b1; end
8'hac: begin outa = 10'h077; outb = 2'b00; outc = 1'b1; end
8'had: begin outa = 10'h2b1; outb = 2'b11; outc = 1'b1; end
8'hae: begin outa = 10'h27f; outb = 2'b00; outc = 1'b0; end
8'haf: begin outa = 10'h265; outb = 2'b11; outc = 1'b0; end
8'hb0: begin outa = 10'h156; outb = 2'b10; outc = 1'b1; end
8'hb1: begin outa = 10'h1ce; outb = 2'b00; outc = 1'b0; end
8'hb2: begin outa = 10'h008; outb = 2'b01; outc = 1'b0; end
8'hb3: begin outa = 10'h12e; outb = 2'b11; outc = 1'b1; end
8'hb4: begin outa = 10'h199; outb = 2'b11; outc = 1'b0; end
8'hb5: begin outa = 10'h330; outb = 2'b10; outc = 1'b0; end
8'hb6: begin outa = 10'h1ab; outb = 2'b01; outc = 1'b1; end
8'hb7: begin outa = 10'h3bd; outb = 2'b00; outc = 1'b0; end
8'hb8: begin outa = 10'h0ca; outb = 2'b10; outc = 1'b0; end
8'hb9: begin outa = 10'h367; outb = 2'b00; outc = 1'b0; end
8'hba: begin outa = 10'h334; outb = 2'b00; outc = 1'b0; end
8'hbb: begin outa = 10'h040; outb = 2'b00; outc = 1'b1; end
8'hbc: begin outa = 10'h1a7; outb = 2'b10; outc = 1'b1; end
8'hbd: begin outa = 10'h036; outb = 2'b11; outc = 1'b1; end
8'hbe: begin outa = 10'h223; outb = 2'b11; outc = 1'b1; end
8'hbf: begin outa = 10'h075; outb = 2'b01; outc = 1'b0; end
8'hc0: begin outa = 10'h3c4; outb = 2'b00; outc = 1'b1; end
8'hc1: begin outa = 10'h2cc; outb = 2'b01; outc = 1'b0; end
8'hc2: begin outa = 10'h123; outb = 2'b01; outc = 1'b0; end
8'hc3: begin outa = 10'h3fd; outb = 2'b01; outc = 1'b1; end
8'hc4: begin outa = 10'h11e; outb = 2'b00; outc = 1'b0; end
8'hc5: begin outa = 10'h27c; outb = 2'b11; outc = 1'b1; end
8'hc6: begin outa = 10'h1e2; outb = 2'b11; outc = 1'b0; end
8'hc7: begin outa = 10'h377; outb = 2'b11; outc = 1'b0; end
8'hc8: begin outa = 10'h33a; outb = 2'b11; outc = 1'b0; end
8'hc9: begin outa = 10'h32d; outb = 2'b11; outc = 1'b1; end
8'hca: begin outa = 10'h014; outb = 2'b11; outc = 1'b0; end
8'hcb: begin outa = 10'h332; outb = 2'b10; outc = 1'b0; end
8'hcc: begin outa = 10'h359; outb = 2'b00; outc = 1'b0; end
8'hcd: begin outa = 10'h0a4; outb = 2'b10; outc = 1'b1; end
8'hce: begin outa = 10'h348; outb = 2'b00; outc = 1'b1; end
8'hcf: begin outa = 10'h04b; outb = 2'b11; outc = 1'b1; end
8'hd0: begin outa = 10'h147; outb = 2'b10; outc = 1'b1; end
8'hd1: begin outa = 10'h026; outb = 2'b00; outc = 1'b1; end
8'hd2: begin outa = 10'h103; outb = 2'b00; outc = 1'b0; end
8'hd3: begin outa = 10'h106; outb = 2'b00; outc = 1'b1; end
8'hd4: begin outa = 10'h35a; outb = 2'b00; outc = 1'b0; end
8'hd5: begin outa = 10'h254; outb = 2'b01; outc = 1'b0; end
8'hd6: begin outa = 10'h0cd; outb = 2'b01; outc = 1'b0; end
8'hd7: begin outa = 10'h17c; outb = 2'b11; outc = 1'b1; end
8'hd8: begin outa = 10'h37e; outb = 2'b10; outc = 1'b1; end
8'hd9: begin outa = 10'h0a9; outb = 2'b11; outc = 1'b1; end
8'hda: begin outa = 10'h0fe; outb = 2'b01; outc = 1'b0; end
8'hdb: begin outa = 10'h3c0; outb = 2'b11; outc = 1'b1; end
8'hdc: begin outa = 10'h1d9; outb = 2'b10; outc = 1'b1; end
8'hdd: begin outa = 10'h10e; outb = 2'b00; outc = 1'b1; end
8'hde: begin outa = 10'h394; outb = 2'b01; outc = 1'b0; end
8'hdf: begin outa = 10'h316; outb = 2'b01; outc = 1'b0; end
8'he0: begin outa = 10'h05b; outb = 2'b11; outc = 1'b0; end
8'he1: begin outa = 10'h126; outb = 2'b01; outc = 1'b1; end
8'he2: begin outa = 10'h369; outb = 2'b11; outc = 1'b0; end
8'he3: begin outa = 10'h291; outb = 2'b10; outc = 1'b1; end
8'he4: begin outa = 10'h2ca; outb = 2'b00; outc = 1'b1; end
8'he5: begin outa = 10'h25b; outb = 2'b01; outc = 1'b1; end
8'he6: begin outa = 10'h106; outb = 2'b00; outc = 1'b0; end
8'he7: begin outa = 10'h172; outb = 2'b11; outc = 1'b1; end
8'he8: begin outa = 10'h2f7; outb = 2'b00; outc = 1'b1; end
8'he9: begin outa = 10'h2d3; outb = 2'b11; outc = 1'b1; end
8'hea: begin outa = 10'h182; outb = 2'b00; outc = 1'b0; end
8'heb: begin outa = 10'h327; outb = 2'b00; outc = 1'b1; end
8'hec: begin outa = 10'h1d0; outb = 2'b10; outc = 1'b0; end
8'hed: begin outa = 10'h204; outb = 2'b00; outc = 1'b1; end
8'hee: begin outa = 10'h11f; outb = 2'b00; outc = 1'b1; end
8'hef: begin outa = 10'h365; outb = 2'b11; outc = 1'b1; end
8'hf0: begin outa = 10'h2c2; outb = 2'b01; outc = 1'b1; end
8'hf1: begin outa = 10'h2b5; outb = 2'b10; outc = 1'b0; end
8'hf2: begin outa = 10'h1f8; outb = 2'b10; outc = 1'b1; end
8'hf3: begin outa = 10'h2a7; outb = 2'b01; outc = 1'b1; end
8'hf4: begin outa = 10'h1be; outb = 2'b10; outc = 1'b1; end
8'hf5: begin outa = 10'h25e; outb = 2'b10; outc = 1'b1; end
8'hf6: begin outa = 10'h032; outb = 2'b10; outc = 1'b0; end
8'hf7: begin outa = 10'h2ef; outb = 2'b00; outc = 1'b0; end
8'hf8: begin outa = 10'h02f; outb = 2'b00; outc = 1'b1; end
8'hf9: begin outa = 10'h201; outb = 2'b10; outc = 1'b0; end
8'hfa: begin outa = 10'h054; outb = 2'b01; outc = 1'b1; end
8'hfb: begin outa = 10'h013; outb = 2'b10; outc = 1'b0; end
8'hfc: begin outa = 10'h249; outb = 2'b01; outc = 1'b0; end
8'hfd: begin outa = 10'h09a; outb = 2'b10; outc = 1'b0; end
8'hfe: begin outa = 10'h012; outb = 2'b00; outc = 1'b0; end
8'hff: begin outa = 10'h114; outb = 2'b10; outc = 1'b1; end
endcase
end
always @* begin
// verilog_format: off
case (index)
8'h00: begin outa = 10'h152; outb = 2'b00; outc = 1'b1; end
8'h01: begin outa = 10'h318; outb = 2'b11; outc = 1'b1; end
8'h02: begin outa = 10'h29f; outb = 2'b11; outc = 1'b0; end
8'h03: begin outa = 10'h392; outb = 2'b01; outc = 1'b1; end
8'h04: begin outa = 10'h1ef; outb = 2'b00; outc = 1'b0; end
8'h05: begin outa = 10'h06c; outb = 2'b10; outc = 1'b1; end
8'h06: begin outa = 10'h29f; outb = 2'b11; outc = 1'b0; end
8'h07: begin outa = 10'h29a; outb = 2'b10; outc = 1'b0; end
8'h08: begin outa = 10'h3ce; outb = 2'b01; outc = 1'b0; end
8'h09: begin outa = 10'h37c; outb = 2'b01; outc = 1'b0; end
8'h0a: begin outa = 10'h058; outb = 2'b10; outc = 1'b0; end
8'h0b: begin outa = 10'h3b2; outb = 2'b01; outc = 1'b1; end
8'h0c: begin outa = 10'h36f; outb = 2'b11; outc = 1'b0; end
8'h0d: begin outa = 10'h2c5; outb = 2'b11; outc = 1'b0; end
8'h0e: begin outa = 10'h23a; outb = 2'b00; outc = 1'b0; end
8'h0f: begin outa = 10'h222; outb = 2'b01; outc = 1'b1; end
8'h10: begin outa = 10'h328; outb = 2'b00; outc = 1'b1; end
8'h11: begin outa = 10'h3c3; outb = 2'b00; outc = 1'b1; end
8'h12: begin outa = 10'h12c; outb = 2'b01; outc = 1'b0; end
8'h13: begin outa = 10'h1d0; outb = 2'b00; outc = 1'b1; end
8'h14: begin outa = 10'h3ff; outb = 2'b01; outc = 1'b1; end
8'h15: begin outa = 10'h115; outb = 2'b11; outc = 1'b1; end
8'h16: begin outa = 10'h3ba; outb = 2'b10; outc = 1'b0; end
8'h17: begin outa = 10'h3ba; outb = 2'b00; outc = 1'b0; end
8'h18: begin outa = 10'h10d; outb = 2'b00; outc = 1'b1; end
8'h19: begin outa = 10'h13b; outb = 2'b01; outc = 1'b1; end
8'h1a: begin outa = 10'h0a0; outb = 2'b10; outc = 1'b1; end
8'h1b: begin outa = 10'h264; outb = 2'b11; outc = 1'b0; end
8'h1c: begin outa = 10'h3a2; outb = 2'b10; outc = 1'b0; end
8'h1d: begin outa = 10'h07c; outb = 2'b00; outc = 1'b1; end
8'h1e: begin outa = 10'h291; outb = 2'b00; outc = 1'b0; end
8'h1f: begin outa = 10'h1d1; outb = 2'b10; outc = 1'b0; end
8'h20: begin outa = 10'h354; outb = 2'b11; outc = 1'b1; end
8'h21: begin outa = 10'h0c0; outb = 2'b00; outc = 1'b1; end
8'h22: begin outa = 10'h191; outb = 2'b00; outc = 1'b0; end
8'h23: begin outa = 10'h379; outb = 2'b01; outc = 1'b0; end
8'h24: begin outa = 10'h073; outb = 2'b00; outc = 1'b0; end
8'h25: begin outa = 10'h2fd; outb = 2'b11; outc = 1'b1; end
8'h26: begin outa = 10'h2e0; outb = 2'b11; outc = 1'b1; end
8'h27: begin outa = 10'h337; outb = 2'b01; outc = 1'b1; end
8'h28: begin outa = 10'h2c7; outb = 2'b11; outc = 1'b1; end
8'h29: begin outa = 10'h19e; outb = 2'b11; outc = 1'b0; end
8'h2a: begin outa = 10'h107; outb = 2'b10; outc = 1'b0; end
8'h2b: begin outa = 10'h06a; outb = 2'b01; outc = 1'b1; end
8'h2c: begin outa = 10'h1c7; outb = 2'b01; outc = 1'b1; end
8'h2d: begin outa = 10'h107; outb = 2'b10; outc = 1'b0; end
8'h2e: begin outa = 10'h0cf; outb = 2'b01; outc = 1'b1; end
8'h2f: begin outa = 10'h009; outb = 2'b11; outc = 1'b1; end
8'h30: begin outa = 10'h09d; outb = 2'b00; outc = 1'b1; end
8'h31: begin outa = 10'h28e; outb = 2'b00; outc = 1'b0; end
8'h32: begin outa = 10'h010; outb = 2'b01; outc = 1'b0; end
8'h33: begin outa = 10'h1e0; outb = 2'b10; outc = 1'b0; end
8'h34: begin outa = 10'h079; outb = 2'b01; outc = 1'b1; end
8'h35: begin outa = 10'h13e; outb = 2'b10; outc = 1'b1; end
8'h36: begin outa = 10'h282; outb = 2'b11; outc = 1'b0; end
8'h37: begin outa = 10'h21c; outb = 2'b11; outc = 1'b1; end
8'h38: begin outa = 10'h148; outb = 2'b00; outc = 1'b1; end
8'h39: begin outa = 10'h3c0; outb = 2'b10; outc = 1'b0; end
8'h3a: begin outa = 10'h176; outb = 2'b01; outc = 1'b1; end
8'h3b: begin outa = 10'h3fc; outb = 2'b10; outc = 1'b1; end
8'h3c: begin outa = 10'h295; outb = 2'b11; outc = 1'b1; end
8'h3d: begin outa = 10'h113; outb = 2'b10; outc = 1'b1; end
8'h3e: begin outa = 10'h354; outb = 2'b01; outc = 1'b1; end
8'h3f: begin outa = 10'h0db; outb = 2'b11; outc = 1'b0; end
8'h40: begin outa = 10'h238; outb = 2'b01; outc = 1'b0; end
8'h41: begin outa = 10'h12b; outb = 2'b01; outc = 1'b1; end
8'h42: begin outa = 10'h1dc; outb = 2'b10; outc = 1'b0; end
8'h43: begin outa = 10'h137; outb = 2'b01; outc = 1'b1; end
8'h44: begin outa = 10'h1e2; outb = 2'b01; outc = 1'b1; end
8'h45: begin outa = 10'h3d5; outb = 2'b11; outc = 1'b1; end
8'h46: begin outa = 10'h30c; outb = 2'b11; outc = 1'b0; end
8'h47: begin outa = 10'h298; outb = 2'b11; outc = 1'b0; end
8'h48: begin outa = 10'h080; outb = 2'b00; outc = 1'b1; end
8'h49: begin outa = 10'h35a; outb = 2'b11; outc = 1'b1; end
8'h4a: begin outa = 10'h01b; outb = 2'b00; outc = 1'b0; end
8'h4b: begin outa = 10'h0a3; outb = 2'b11; outc = 1'b0; end
8'h4c: begin outa = 10'h0b3; outb = 2'b11; outc = 1'b1; end
8'h4d: begin outa = 10'h17a; outb = 2'b00; outc = 1'b0; end
8'h4e: begin outa = 10'h3ae; outb = 2'b11; outc = 1'b0; end
8'h4f: begin outa = 10'h078; outb = 2'b11; outc = 1'b0; end
8'h50: begin outa = 10'h322; outb = 2'b00; outc = 1'b1; end
8'h51: begin outa = 10'h213; outb = 2'b11; outc = 1'b0; end
8'h52: begin outa = 10'h11a; outb = 2'b11; outc = 1'b0; end
8'h53: begin outa = 10'h1a7; outb = 2'b00; outc = 1'b0; end
8'h54: begin outa = 10'h35a; outb = 2'b00; outc = 1'b1; end
8'h55: begin outa = 10'h233; outb = 2'b00; outc = 1'b0; end
8'h56: begin outa = 10'h01d; outb = 2'b01; outc = 1'b1; end
8'h57: begin outa = 10'h2d5; outb = 2'b00; outc = 1'b0; end
8'h58: begin outa = 10'h1a0; outb = 2'b00; outc = 1'b1; end
8'h59: begin outa = 10'h3d0; outb = 2'b00; outc = 1'b1; end
8'h5a: begin outa = 10'h181; outb = 2'b01; outc = 1'b1; end
8'h5b: begin outa = 10'h219; outb = 2'b01; outc = 1'b1; end
8'h5c: begin outa = 10'h26a; outb = 2'b01; outc = 1'b1; end
8'h5d: begin outa = 10'h050; outb = 2'b10; outc = 1'b0; end
8'h5e: begin outa = 10'h189; outb = 2'b10; outc = 1'b0; end
8'h5f: begin outa = 10'h1eb; outb = 2'b01; outc = 1'b1; end
8'h60: begin outa = 10'h224; outb = 2'b00; outc = 1'b1; end
8'h61: begin outa = 10'h2fe; outb = 2'b00; outc = 1'b0; end
8'h62: begin outa = 10'h0ae; outb = 2'b00; outc = 1'b1; end
8'h63: begin outa = 10'h1cd; outb = 2'b00; outc = 1'b0; end
8'h64: begin outa = 10'h273; outb = 2'b10; outc = 1'b1; end
8'h65: begin outa = 10'h268; outb = 2'b10; outc = 1'b0; end
8'h66: begin outa = 10'h111; outb = 2'b01; outc = 1'b0; end
8'h67: begin outa = 10'h1f9; outb = 2'b00; outc = 1'b0; end
8'h68: begin outa = 10'h232; outb = 2'b00; outc = 1'b1; end
8'h69: begin outa = 10'h255; outb = 2'b11; outc = 1'b0; end
8'h6a: begin outa = 10'h34c; outb = 2'b01; outc = 1'b1; end
8'h6b: begin outa = 10'h049; outb = 2'b01; outc = 1'b1; end
8'h6c: begin outa = 10'h197; outb = 2'b11; outc = 1'b0; end
8'h6d: begin outa = 10'h0fe; outb = 2'b11; outc = 1'b0; end
8'h6e: begin outa = 10'h253; outb = 2'b01; outc = 1'b1; end
8'h6f: begin outa = 10'h2de; outb = 2'b11; outc = 1'b0; end
8'h70: begin outa = 10'h13b; outb = 2'b10; outc = 1'b1; end
8'h71: begin outa = 10'h040; outb = 2'b10; outc = 1'b0; end
8'h72: begin outa = 10'h0b4; outb = 2'b00; outc = 1'b1; end
8'h73: begin outa = 10'h233; outb = 2'b11; outc = 1'b1; end
8'h74: begin outa = 10'h198; outb = 2'b00; outc = 1'b1; end
8'h75: begin outa = 10'h018; outb = 2'b00; outc = 1'b1; end
8'h76: begin outa = 10'h2f7; outb = 2'b00; outc = 1'b1; end
8'h77: begin outa = 10'h134; outb = 2'b11; outc = 1'b0; end
8'h78: begin outa = 10'h1ca; outb = 2'b10; outc = 1'b0; end
8'h79: begin outa = 10'h286; outb = 2'b10; outc = 1'b1; end
8'h7a: begin outa = 10'h0e6; outb = 2'b11; outc = 1'b1; end
8'h7b: begin outa = 10'h064; outb = 2'b10; outc = 1'b1; end
8'h7c: begin outa = 10'h257; outb = 2'b00; outc = 1'b1; end
8'h7d: begin outa = 10'h31a; outb = 2'b10; outc = 1'b1; end
8'h7e: begin outa = 10'h247; outb = 2'b01; outc = 1'b0; end
8'h7f: begin outa = 10'h299; outb = 2'b00; outc = 1'b0; end
8'h80: begin outa = 10'h02c; outb = 2'b00; outc = 1'b0; end
8'h81: begin outa = 10'h2bb; outb = 2'b11; outc = 1'b0; end
8'h82: begin outa = 10'h180; outb = 2'b10; outc = 1'b0; end
8'h83: begin outa = 10'h245; outb = 2'b01; outc = 1'b1; end
8'h84: begin outa = 10'h0da; outb = 2'b10; outc = 1'b0; end
8'h85: begin outa = 10'h367; outb = 2'b10; outc = 1'b0; end
8'h86: begin outa = 10'h304; outb = 2'b01; outc = 1'b0; end
8'h87: begin outa = 10'h38b; outb = 2'b11; outc = 1'b0; end
8'h88: begin outa = 10'h09f; outb = 2'b01; outc = 1'b0; end
8'h89: begin outa = 10'h1f0; outb = 2'b10; outc = 1'b1; end
8'h8a: begin outa = 10'h281; outb = 2'b10; outc = 1'b1; end
8'h8b: begin outa = 10'h019; outb = 2'b00; outc = 1'b0; end
8'h8c: begin outa = 10'h1f2; outb = 2'b10; outc = 1'b0; end
8'h8d: begin outa = 10'h0b1; outb = 2'b01; outc = 1'b1; end
8'h8e: begin outa = 10'h058; outb = 2'b01; outc = 1'b1; end
8'h8f: begin outa = 10'h39b; outb = 2'b00; outc = 1'b1; end
8'h90: begin outa = 10'h2ec; outb = 2'b10; outc = 1'b1; end
8'h91: begin outa = 10'h250; outb = 2'b00; outc = 1'b1; end
8'h92: begin outa = 10'h3f4; outb = 2'b10; outc = 1'b1; end
8'h93: begin outa = 10'h057; outb = 2'b10; outc = 1'b1; end
8'h94: begin outa = 10'h18f; outb = 2'b01; outc = 1'b1; end
8'h95: begin outa = 10'h105; outb = 2'b01; outc = 1'b1; end
8'h96: begin outa = 10'h1ae; outb = 2'b00; outc = 1'b1; end
8'h97: begin outa = 10'h04e; outb = 2'b10; outc = 1'b0; end
8'h98: begin outa = 10'h240; outb = 2'b11; outc = 1'b0; end
8'h99: begin outa = 10'h3e4; outb = 2'b01; outc = 1'b0; end
8'h9a: begin outa = 10'h3c6; outb = 2'b01; outc = 1'b0; end
8'h9b: begin outa = 10'h109; outb = 2'b00; outc = 1'b1; end
8'h9c: begin outa = 10'h073; outb = 2'b10; outc = 1'b1; end
8'h9d: begin outa = 10'h19f; outb = 2'b01; outc = 1'b0; end
8'h9e: begin outa = 10'h3b8; outb = 2'b01; outc = 1'b0; end
8'h9f: begin outa = 10'h00e; outb = 2'b00; outc = 1'b1; end
8'ha0: begin outa = 10'h1b3; outb = 2'b11; outc = 1'b1; end
8'ha1: begin outa = 10'h2bd; outb = 2'b11; outc = 1'b0; end
8'ha2: begin outa = 10'h324; outb = 2'b00; outc = 1'b1; end
8'ha3: begin outa = 10'h343; outb = 2'b10; outc = 1'b0; end
8'ha4: begin outa = 10'h1c9; outb = 2'b01; outc = 1'b0; end
8'ha5: begin outa = 10'h185; outb = 2'b00; outc = 1'b1; end
8'ha6: begin outa = 10'h37a; outb = 2'b00; outc = 1'b1; end
8'ha7: begin outa = 10'h0e0; outb = 2'b01; outc = 1'b1; end
8'ha8: begin outa = 10'h0a3; outb = 2'b10; outc = 1'b0; end
8'ha9: begin outa = 10'h019; outb = 2'b11; outc = 1'b0; end
8'haa: begin outa = 10'h099; outb = 2'b00; outc = 1'b1; end
8'hab: begin outa = 10'h376; outb = 2'b01; outc = 1'b1; end
8'hac: begin outa = 10'h077; outb = 2'b00; outc = 1'b1; end
8'had: begin outa = 10'h2b1; outb = 2'b11; outc = 1'b1; end
8'hae: begin outa = 10'h27f; outb = 2'b00; outc = 1'b0; end
8'haf: begin outa = 10'h265; outb = 2'b11; outc = 1'b0; end
8'hb0: begin outa = 10'h156; outb = 2'b10; outc = 1'b1; end
8'hb1: begin outa = 10'h1ce; outb = 2'b00; outc = 1'b0; end
8'hb2: begin outa = 10'h008; outb = 2'b01; outc = 1'b0; end
8'hb3: begin outa = 10'h12e; outb = 2'b11; outc = 1'b1; end
8'hb4: begin outa = 10'h199; outb = 2'b11; outc = 1'b0; end
8'hb5: begin outa = 10'h330; outb = 2'b10; outc = 1'b0; end
8'hb6: begin outa = 10'h1ab; outb = 2'b01; outc = 1'b1; end
8'hb7: begin outa = 10'h3bd; outb = 2'b00; outc = 1'b0; end
8'hb8: begin outa = 10'h0ca; outb = 2'b10; outc = 1'b0; end
8'hb9: begin outa = 10'h367; outb = 2'b00; outc = 1'b0; end
8'hba: begin outa = 10'h334; outb = 2'b00; outc = 1'b0; end
8'hbb: begin outa = 10'h040; outb = 2'b00; outc = 1'b1; end
8'hbc: begin outa = 10'h1a7; outb = 2'b10; outc = 1'b1; end
8'hbd: begin outa = 10'h036; outb = 2'b11; outc = 1'b1; end
8'hbe: begin outa = 10'h223; outb = 2'b11; outc = 1'b1; end
8'hbf: begin outa = 10'h075; outb = 2'b01; outc = 1'b0; end
8'hc0: begin outa = 10'h3c4; outb = 2'b00; outc = 1'b1; end
8'hc1: begin outa = 10'h2cc; outb = 2'b01; outc = 1'b0; end
8'hc2: begin outa = 10'h123; outb = 2'b01; outc = 1'b0; end
8'hc3: begin outa = 10'h3fd; outb = 2'b01; outc = 1'b1; end
8'hc4: begin outa = 10'h11e; outb = 2'b00; outc = 1'b0; end
8'hc5: begin outa = 10'h27c; outb = 2'b11; outc = 1'b1; end
8'hc6: begin outa = 10'h1e2; outb = 2'b11; outc = 1'b0; end
8'hc7: begin outa = 10'h377; outb = 2'b11; outc = 1'b0; end
8'hc8: begin outa = 10'h33a; outb = 2'b11; outc = 1'b0; end
8'hc9: begin outa = 10'h32d; outb = 2'b11; outc = 1'b1; end
8'hca: begin outa = 10'h014; outb = 2'b11; outc = 1'b0; end
8'hcb: begin outa = 10'h332; outb = 2'b10; outc = 1'b0; end
8'hcc: begin outa = 10'h359; outb = 2'b00; outc = 1'b0; end
8'hcd: begin outa = 10'h0a4; outb = 2'b10; outc = 1'b1; end
8'hce: begin outa = 10'h348; outb = 2'b00; outc = 1'b1; end
8'hcf: begin outa = 10'h04b; outb = 2'b11; outc = 1'b1; end
8'hd0: begin outa = 10'h147; outb = 2'b10; outc = 1'b1; end
8'hd1: begin outa = 10'h026; outb = 2'b00; outc = 1'b1; end
8'hd2: begin outa = 10'h103; outb = 2'b00; outc = 1'b0; end
8'hd3: begin outa = 10'h106; outb = 2'b00; outc = 1'b1; end
8'hd4: begin outa = 10'h35a; outb = 2'b00; outc = 1'b0; end
8'hd5: begin outa = 10'h254; outb = 2'b01; outc = 1'b0; end
8'hd6: begin outa = 10'h0cd; outb = 2'b01; outc = 1'b0; end
8'hd7: begin outa = 10'h17c; outb = 2'b11; outc = 1'b1; end
8'hd8: begin outa = 10'h37e; outb = 2'b10; outc = 1'b1; end
8'hd9: begin outa = 10'h0a9; outb = 2'b11; outc = 1'b1; end
8'hda: begin outa = 10'h0fe; outb = 2'b01; outc = 1'b0; end
8'hdb: begin outa = 10'h3c0; outb = 2'b11; outc = 1'b1; end
8'hdc: begin outa = 10'h1d9; outb = 2'b10; outc = 1'b1; end
8'hdd: begin outa = 10'h10e; outb = 2'b00; outc = 1'b1; end
8'hde: begin outa = 10'h394; outb = 2'b01; outc = 1'b0; end
8'hdf: begin outa = 10'h316; outb = 2'b01; outc = 1'b0; end
8'he0: begin outa = 10'h05b; outb = 2'b11; outc = 1'b0; end
8'he1: begin outa = 10'h126; outb = 2'b01; outc = 1'b1; end
8'he2: begin outa = 10'h369; outb = 2'b11; outc = 1'b0; end
8'he3: begin outa = 10'h291; outb = 2'b10; outc = 1'b1; end
8'he4: begin outa = 10'h2ca; outb = 2'b00; outc = 1'b1; end
8'he5: begin outa = 10'h25b; outb = 2'b01; outc = 1'b1; end
8'he6: begin outa = 10'h106; outb = 2'b00; outc = 1'b0; end
8'he7: begin outa = 10'h172; outb = 2'b11; outc = 1'b1; end
8'he8: begin outa = 10'h2f7; outb = 2'b00; outc = 1'b1; end
8'he9: begin outa = 10'h2d3; outb = 2'b11; outc = 1'b1; end
8'hea: begin outa = 10'h182; outb = 2'b00; outc = 1'b0; end
8'heb: begin outa = 10'h327; outb = 2'b00; outc = 1'b1; end
8'hec: begin outa = 10'h1d0; outb = 2'b10; outc = 1'b0; end
8'hed: begin outa = 10'h204; outb = 2'b00; outc = 1'b1; end
8'hee: begin outa = 10'h11f; outb = 2'b00; outc = 1'b1; end
8'hef: begin outa = 10'h365; outb = 2'b11; outc = 1'b1; end
8'hf0: begin outa = 10'h2c2; outb = 2'b01; outc = 1'b1; end
8'hf1: begin outa = 10'h2b5; outb = 2'b10; outc = 1'b0; end
8'hf2: begin outa = 10'h1f8; outb = 2'b10; outc = 1'b1; end
8'hf3: begin outa = 10'h2a7; outb = 2'b01; outc = 1'b1; end
8'hf4: begin outa = 10'h1be; outb = 2'b10; outc = 1'b1; end
8'hf5: begin outa = 10'h25e; outb = 2'b10; outc = 1'b1; end
8'hf6: begin outa = 10'h032; outb = 2'b10; outc = 1'b0; end
8'hf7: begin outa = 10'h2ef; outb = 2'b00; outc = 1'b0; end
8'hf8: begin outa = 10'h02f; outb = 2'b00; outc = 1'b1; end
8'hf9: begin outa = 10'h201; outb = 2'b10; outc = 1'b0; end
8'hfa: begin outa = 10'h054; outb = 2'b01; outc = 1'b1; end
8'hfb: begin outa = 10'h013; outb = 2'b10; outc = 1'b0; end
8'hfc: begin outa = 10'h249; outb = 2'b01; outc = 1'b0; end
8'hfd: begin outa = 10'h09a; outb = 2'b10; outc = 1'b0; end
8'hfe: begin outa = 10'h012; outb = 2'b00; outc = 1'b0; end
8'hff: begin outa = 10'h114; outb = 2'b10; outc = 1'b1; end
endcase
// verilog_format: on
end
endmodule

View File

@ -5,290 +5,286 @@
// SPDX-License-Identifier: CC0-1.0
module t_case_huge_sub2 (/*AUTOARG*/
// Outputs
outa,
// Inputs
index
);
// Outputs
outa,
// Inputs
index
);
input [9:0] index;
output [9:0] outa;
input [9:0] index;
output logic [9:0] outa;
// =============================
/*AUTOREG*/
// Beginning of automatic regs (for this module's undeclared outputs)
reg [9:0] outa;
// End of automatics
// =============================
// Created from Python3:
// for i in range(1024):
// print(" 10'h%03x: begin outa = 10'h%03x; outb = 2'b%d%d; outc = 1'b%d; end"
// % (i, random.randint(0,1024), random.randint(0,1),
// random.randint(0,1), random.randint(0,1)))
// =============================
// Created from Python3:
// for i in range(1024):
// print(" 10'h%03x: begin outa = 10'h%03x; outb = 2'b%d%d; outc = 1'b%d; end"
// % (i, random.randint(0,1024), random.randint(0,1),
// random.randint(0,1), random.randint(0,1)))
always @(/*AS*/index) begin
case (index[7:0])
`ifdef VERILATOR // Harder test
8'h00: begin outa = $c("0"); end // Makes whole table non-optimizable
always @(/*AS*/index) begin
case (index[7:0])
`ifdef VERILATOR // Harder test
8'h00: begin
outa = $c("0");
end // Makes whole table non-optimizable
`else
8'h00: begin outa = 10'h0; end
8'h00: outa = 10'h0;
`endif
8'h01: begin outa = 10'h318; end
8'h02: begin outa = 10'h29f; end
8'h03: begin outa = 10'h392; end
8'h04: begin outa = 10'h1ef; end
8'h05: begin outa = 10'h06c; end
8'h06: begin outa = 10'h29f; end
8'h07: begin outa = 10'h29a; end
8'h08: begin outa = 10'h3ce; end
8'h09: begin outa = 10'h37c; end
8'h0a: begin outa = 10'h058; end
8'h0b: begin outa = 10'h3b2; end
8'h0c: begin outa = 10'h36f; end
8'h0d: begin outa = 10'h2c5; end
8'h0e: begin outa = 10'h23a; end
8'h0f: begin outa = 10'h222; end
8'h10: begin outa = 10'h328; end
8'h11: begin outa = 10'h3c3; end
8'h12: begin outa = 10'h12c; end
8'h13: begin outa = 10'h1d0; end
8'h14: begin outa = 10'h3ff; end
8'h15: begin outa = 10'h115; end
8'h16: begin outa = 10'h3ba; end
8'h17: begin outa = 10'h3ba; end
8'h18: begin outa = 10'h10d; end
8'h19: begin outa = 10'h13b; end
8'h1a: begin outa = 10'h0a0; end
8'h1b: begin outa = 10'h264; end
8'h1c: begin outa = 10'h3a2; end
8'h1d: begin outa = 10'h07c; end
8'h1e: begin outa = 10'h291; end
8'h1f: begin outa = 10'h1d1; end
8'h20: begin outa = 10'h354; end
8'h21: begin outa = 10'h0c0; end
8'h22: begin outa = 10'h191; end
8'h23: begin outa = 10'h379; end
8'h24: begin outa = 10'h073; end
8'h25: begin outa = 10'h2fd; end
8'h26: begin outa = 10'h2e0; end
8'h27: begin outa = 10'h337; end
8'h28: begin outa = 10'h2c7; end
8'h29: begin outa = 10'h19e; end
8'h2a: begin outa = 10'h107; end
8'h2b: begin outa = 10'h06a; end
8'h2c: begin outa = 10'h1c7; end
8'h2d: begin outa = 10'h107; end
8'h2e: begin outa = 10'h0cf; end
8'h2f: begin outa = 10'h009; end
8'h30: begin outa = 10'h09d; end
8'h31: begin outa = 10'h28e; end
8'h32: begin outa = 10'h010; end
8'h33: begin outa = 10'h1e0; end
8'h34: begin outa = 10'h079; end
8'h35: begin outa = 10'h13e; end
8'h36: begin outa = 10'h282; end
8'h37: begin outa = 10'h21c; end
8'h38: begin outa = 10'h148; end
8'h39: begin outa = 10'h3c0; end
8'h3a: begin outa = 10'h176; end
8'h3b: begin outa = 10'h3fc; end
8'h3c: begin outa = 10'h295; end
8'h3d: begin outa = 10'h113; end
8'h3e: begin outa = 10'h354; end
8'h3f: begin outa = 10'h0db; end
8'h40: begin outa = 10'h238; end
8'h41: begin outa = 10'h12b; end
8'h42: begin outa = 10'h1dc; end
8'h43: begin outa = 10'h137; end
8'h44: begin outa = 10'h1e2; end
8'h45: begin outa = 10'h3d5; end
8'h46: begin outa = 10'h30c; end
8'h47: begin outa = 10'h298; end
8'h48: begin outa = 10'h080; end
8'h49: begin outa = 10'h35a; end
8'h4a: begin outa = 10'h01b; end
8'h4b: begin outa = 10'h0a3; end
8'h4c: begin outa = 10'h0b3; end
8'h4d: begin outa = 10'h17a; end
8'h4e: begin outa = 10'h3ae; end
8'h4f: begin outa = 10'h078; end
8'h50: begin outa = 10'h322; end
8'h51: begin outa = 10'h213; end
8'h52: begin outa = 10'h11a; end
8'h53: begin outa = 10'h1a7; end
8'h54: begin outa = 10'h35a; end
8'h55: begin outa = 10'h233; end
8'h56: begin outa = 10'h01d; end
8'h57: begin outa = 10'h2d5; end
8'h58: begin outa = 10'h1a0; end
8'h59: begin outa = 10'h3d0; end
8'h5a: begin outa = 10'h181; end
8'h5b: begin outa = 10'h219; end
8'h5c: begin outa = 10'h26a; end
8'h5d: begin outa = 10'h050; end
8'h5e: begin outa = 10'h189; end
8'h5f: begin outa = 10'h1eb; end
8'h60: begin outa = 10'h224; end
8'h61: begin outa = 10'h2fe; end
8'h62: begin outa = 10'h0ae; end
8'h63: begin outa = 10'h1cd; end
8'h64: begin outa = 10'h273; end
8'h65: begin outa = 10'h268; end
8'h66: begin outa = 10'h111; end
8'h67: begin outa = 10'h1f9; end
8'h68: begin outa = 10'h232; end
8'h69: begin outa = 10'h255; end
8'h6a: begin outa = 10'h34c; end
8'h6b: begin outa = 10'h049; end
8'h6c: begin outa = 10'h197; end
8'h6d: begin outa = 10'h0fe; end
8'h6e: begin outa = 10'h253; end
8'h6f: begin outa = 10'h2de; end
8'h70: begin outa = 10'h13b; end
8'h71: begin outa = 10'h040; end
8'h72: begin outa = 10'h0b4; end
8'h73: begin outa = 10'h233; end
8'h74: begin outa = 10'h198; end
8'h75: begin outa = 10'h018; end
8'h76: begin outa = 10'h2f7; end
8'h77: begin outa = 10'h134; end
8'h78: begin outa = 10'h1ca; end
8'h79: begin outa = 10'h286; end
8'h7a: begin outa = 10'h0e6; end
8'h7b: begin outa = 10'h064; end
8'h7c: begin outa = 10'h257; end
8'h7d: begin outa = 10'h31a; end
8'h7e: begin outa = 10'h247; end
8'h7f: begin outa = 10'h299; end
8'h80: begin outa = 10'h02c; end
8'h81: begin outa = 10'h2bb; end
8'h82: begin outa = 10'h180; end
8'h83: begin outa = 10'h245; end
8'h84: begin outa = 10'h0da; end
8'h85: begin outa = 10'h367; end
8'h86: begin outa = 10'h304; end
8'h87: begin outa = 10'h38b; end
8'h88: begin outa = 10'h09f; end
8'h89: begin outa = 10'h1f0; end
8'h8a: begin outa = 10'h281; end
8'h8b: begin outa = 10'h019; end
8'h8c: begin outa = 10'h1f2; end
8'h8d: begin outa = 10'h0b1; end
8'h8e: begin outa = 10'h058; end
8'h8f: begin outa = 10'h39b; end
8'h90: begin outa = 10'h2ec; end
8'h91: begin outa = 10'h250; end
8'h92: begin outa = 10'h3f4; end
8'h93: begin outa = 10'h057; end
8'h94: begin outa = 10'h18f; end
8'h95: begin outa = 10'h105; end
8'h96: begin outa = 10'h1ae; end
8'h97: begin outa = 10'h04e; end
8'h98: begin outa = 10'h240; end
8'h99: begin outa = 10'h3e4; end
8'h9a: begin outa = 10'h3c6; end
8'h9b: begin outa = 10'h109; end
8'h9c: begin outa = 10'h073; end
8'h9d: begin outa = 10'h19f; end
8'h9e: begin outa = 10'h3b8; end
8'h9f: begin outa = 10'h00e; end
8'ha0: begin outa = 10'h1b3; end
8'ha1: begin outa = 10'h2bd; end
8'ha2: begin outa = 10'h324; end
8'ha3: begin outa = 10'h343; end
8'ha4: begin outa = 10'h1c9; end
8'ha5: begin outa = 10'h185; end
8'ha6: begin outa = 10'h37a; end
8'ha7: begin outa = 10'h0e0; end
8'ha8: begin outa = 10'h0a3; end
8'ha9: begin outa = 10'h019; end
8'haa: begin outa = 10'h099; end
8'hab: begin outa = 10'h376; end
8'hac: begin outa = 10'h077; end
8'had: begin outa = 10'h2b1; end
8'hae: begin outa = 10'h27f; end
8'haf: begin outa = 10'h265; end
8'hb0: begin outa = 10'h156; end
8'hb1: begin outa = 10'h1ce; end
8'hb2: begin outa = 10'h008; end
8'hb3: begin outa = 10'h12e; end
8'hb4: begin outa = 10'h199; end
8'hb5: begin outa = 10'h330; end
8'hb6: begin outa = 10'h1ab; end
8'hb7: begin outa = 10'h3bd; end
8'hb8: begin outa = 10'h0ca; end
8'hb9: begin outa = 10'h367; end
8'hba: begin outa = 10'h334; end
8'hbb: begin outa = 10'h040; end
8'hbc: begin outa = 10'h1a7; end
8'hbd: begin outa = 10'h036; end
8'hbe: begin outa = 10'h223; end
8'hbf: begin outa = 10'h075; end
8'hc0: begin outa = 10'h3c4; end
8'hc1: begin outa = 10'h2cc; end
8'hc2: begin outa = 10'h123; end
8'hc3: begin outa = 10'h3fd; end
8'hc4: begin outa = 10'h11e; end
8'hc5: begin outa = 10'h27c; end
8'hc6: begin outa = 10'h1e2; end
8'hc7: begin outa = 10'h377; end
8'hc8: begin outa = 10'h33a; end
8'hc9: begin outa = 10'h32d; end
8'hca: begin outa = 10'h014; end
8'hcb: begin outa = 10'h332; end
8'hcc: begin outa = 10'h359; end
8'hcd: begin outa = 10'h0a4; end
8'hce: begin outa = 10'h348; end
8'hcf: begin outa = 10'h04b; end
8'hd0: begin outa = 10'h147; end
8'hd1: begin outa = 10'h026; end
8'hd2: begin outa = 10'h103; end
8'hd3: begin outa = 10'h106; end
8'hd4: begin outa = 10'h35a; end
8'hd5: begin outa = 10'h254; end
8'hd6: begin outa = 10'h0cd; end
8'hd7: begin outa = 10'h17c; end
8'hd8: begin outa = 10'h37e; end
8'hd9: begin outa = 10'h0a9; end
8'hda: begin outa = 10'h0fe; end
8'hdb: begin outa = 10'h3c0; end
8'hdc: begin outa = 10'h1d9; end
8'hdd: begin outa = 10'h10e; end
8'hde: begin outa = 10'h394; end
8'hdf: begin outa = 10'h316; end
8'he0: begin outa = 10'h05b; end
8'he1: begin outa = 10'h126; end
8'he2: begin outa = 10'h369; end
8'he3: begin outa = 10'h291; end
8'he4: begin outa = 10'h2ca; end
8'he5: begin outa = 10'h25b; end
8'he6: begin outa = 10'h106; end
8'he7: begin outa = 10'h172; end
8'he8: begin outa = 10'h2f7; end
8'he9: begin outa = 10'h2d3; end
8'hea: begin outa = 10'h182; end
8'heb: begin outa = 10'h327; end
8'hec: begin outa = 10'h1d0; end
8'hed: begin outa = 10'h204; end
8'hee: begin outa = 10'h11f; end
8'hef: begin outa = 10'h365; end
8'hf0: begin outa = 10'h2c2; end
8'hf1: begin outa = 10'h2b5; end
8'hf2: begin outa = 10'h1f8; end
8'hf3: begin outa = 10'h2a7; end
8'hf4: begin outa = 10'h1be; end
8'hf5: begin outa = 10'h25e; end
8'hf6: begin outa = 10'h032; end
8'hf7: begin outa = 10'h2ef; end
8'hf8: begin outa = 10'h02f; end
8'hf9: begin outa = 10'h201; end
8'hfa: begin outa = 10'h054; end
8'hfb: begin outa = 10'h013; end
8'hfc: begin outa = 10'h249; end
8'hfd: begin outa = 10'h09a; end
8'hfe: begin outa = 10'h012; end
8'hff: begin outa = 10'h114; end
endcase
end
8'h01: outa = 10'h318;
8'h02: outa = 10'h29f;
8'h03: outa = 10'h392;
8'h04: outa = 10'h1ef;
8'h05: outa = 10'h06c;
8'h06: outa = 10'h29f;
8'h07: outa = 10'h29a;
8'h08: outa = 10'h3ce;
8'h09: outa = 10'h37c;
8'h0a: outa = 10'h058;
8'h0b: outa = 10'h3b2;
8'h0c: outa = 10'h36f;
8'h0d: outa = 10'h2c5;
8'h0e: outa = 10'h23a;
8'h0f: outa = 10'h222;
8'h10: outa = 10'h328;
8'h11: outa = 10'h3c3;
8'h12: outa = 10'h12c;
8'h13: outa = 10'h1d0;
8'h14: outa = 10'h3ff;
8'h15: outa = 10'h115;
8'h16: outa = 10'h3ba;
8'h17: outa = 10'h3ba;
8'h18: outa = 10'h10d;
8'h19: outa = 10'h13b;
8'h1a: outa = 10'h0a0;
8'h1b: outa = 10'h264;
8'h1c: outa = 10'h3a2;
8'h1d: outa = 10'h07c;
8'h1e: outa = 10'h291;
8'h1f: outa = 10'h1d1;
8'h20: outa = 10'h354;
8'h21: outa = 10'h0c0;
8'h22: outa = 10'h191;
8'h23: outa = 10'h379;
8'h24: outa = 10'h073;
8'h25: outa = 10'h2fd;
8'h26: outa = 10'h2e0;
8'h27: outa = 10'h337;
8'h28: outa = 10'h2c7;
8'h29: outa = 10'h19e;
8'h2a: outa = 10'h107;
8'h2b: outa = 10'h06a;
8'h2c: outa = 10'h1c7;
8'h2d: outa = 10'h107;
8'h2e: outa = 10'h0cf;
8'h2f: outa = 10'h009;
8'h30: outa = 10'h09d;
8'h31: outa = 10'h28e;
8'h32: outa = 10'h010;
8'h33: outa = 10'h1e0;
8'h34: outa = 10'h079;
8'h35: outa = 10'h13e;
8'h36: outa = 10'h282;
8'h37: outa = 10'h21c;
8'h38: outa = 10'h148;
8'h39: outa = 10'h3c0;
8'h3a: outa = 10'h176;
8'h3b: outa = 10'h3fc;
8'h3c: outa = 10'h295;
8'h3d: outa = 10'h113;
8'h3e: outa = 10'h354;
8'h3f: outa = 10'h0db;
8'h40: outa = 10'h238;
8'h41: outa = 10'h12b;
8'h42: outa = 10'h1dc;
8'h43: outa = 10'h137;
8'h44: outa = 10'h1e2;
8'h45: outa = 10'h3d5;
8'h46: outa = 10'h30c;
8'h47: outa = 10'h298;
8'h48: outa = 10'h080;
8'h49: outa = 10'h35a;
8'h4a: outa = 10'h01b;
8'h4b: outa = 10'h0a3;
8'h4c: outa = 10'h0b3;
8'h4d: outa = 10'h17a;
8'h4e: outa = 10'h3ae;
8'h4f: outa = 10'h078;
8'h50: outa = 10'h322;
8'h51: outa = 10'h213;
8'h52: outa = 10'h11a;
8'h53: outa = 10'h1a7;
8'h54: outa = 10'h35a;
8'h55: outa = 10'h233;
8'h56: outa = 10'h01d;
8'h57: outa = 10'h2d5;
8'h58: outa = 10'h1a0;
8'h59: outa = 10'h3d0;
8'h5a: outa = 10'h181;
8'h5b: outa = 10'h219;
8'h5c: outa = 10'h26a;
8'h5d: outa = 10'h050;
8'h5e: outa = 10'h189;
8'h5f: outa = 10'h1eb;
8'h60: outa = 10'h224;
8'h61: outa = 10'h2fe;
8'h62: outa = 10'h0ae;
8'h63: outa = 10'h1cd;
8'h64: outa = 10'h273;
8'h65: outa = 10'h268;
8'h66: outa = 10'h111;
8'h67: outa = 10'h1f9;
8'h68: outa = 10'h232;
8'h69: outa = 10'h255;
8'h6a: outa = 10'h34c;
8'h6b: outa = 10'h049;
8'h6c: outa = 10'h197;
8'h6d: outa = 10'h0fe;
8'h6e: outa = 10'h253;
8'h6f: outa = 10'h2de;
8'h70: outa = 10'h13b;
8'h71: outa = 10'h040;
8'h72: outa = 10'h0b4;
8'h73: outa = 10'h233;
8'h74: outa = 10'h198;
8'h75: outa = 10'h018;
8'h76: outa = 10'h2f7;
8'h77: outa = 10'h134;
8'h78: outa = 10'h1ca;
8'h79: outa = 10'h286;
8'h7a: outa = 10'h0e6;
8'h7b: outa = 10'h064;
8'h7c: outa = 10'h257;
8'h7d: outa = 10'h31a;
8'h7e: outa = 10'h247;
8'h7f: outa = 10'h299;
8'h80: outa = 10'h02c;
8'h81: outa = 10'h2bb;
8'h82: outa = 10'h180;
8'h83: outa = 10'h245;
8'h84: outa = 10'h0da;
8'h85: outa = 10'h367;
8'h86: outa = 10'h304;
8'h87: outa = 10'h38b;
8'h88: outa = 10'h09f;
8'h89: outa = 10'h1f0;
8'h8a: outa = 10'h281;
8'h8b: outa = 10'h019;
8'h8c: outa = 10'h1f2;
8'h8d: outa = 10'h0b1;
8'h8e: outa = 10'h058;
8'h8f: outa = 10'h39b;
8'h90: outa = 10'h2ec;
8'h91: outa = 10'h250;
8'h92: outa = 10'h3f4;
8'h93: outa = 10'h057;
8'h94: outa = 10'h18f;
8'h95: outa = 10'h105;
8'h96: outa = 10'h1ae;
8'h97: outa = 10'h04e;
8'h98: outa = 10'h240;
8'h99: outa = 10'h3e4;
8'h9a: outa = 10'h3c6;
8'h9b: outa = 10'h109;
8'h9c: outa = 10'h073;
8'h9d: outa = 10'h19f;
8'h9e: outa = 10'h3b8;
8'h9f: outa = 10'h00e;
8'ha0: outa = 10'h1b3;
8'ha1: outa = 10'h2bd;
8'ha2: outa = 10'h324;
8'ha3: outa = 10'h343;
8'ha4: outa = 10'h1c9;
8'ha5: outa = 10'h185;
8'ha6: outa = 10'h37a;
8'ha7: outa = 10'h0e0;
8'ha8: outa = 10'h0a3;
8'ha9: outa = 10'h019;
8'haa: outa = 10'h099;
8'hab: outa = 10'h376;
8'hac: outa = 10'h077;
8'had: outa = 10'h2b1;
8'hae: outa = 10'h27f;
8'haf: outa = 10'h265;
8'hb0: outa = 10'h156;
8'hb1: outa = 10'h1ce;
8'hb2: outa = 10'h008;
8'hb3: outa = 10'h12e;
8'hb4: outa = 10'h199;
8'hb5: outa = 10'h330;
8'hb6: outa = 10'h1ab;
8'hb7: outa = 10'h3bd;
8'hb8: outa = 10'h0ca;
8'hb9: outa = 10'h367;
8'hba: outa = 10'h334;
8'hbb: outa = 10'h040;
8'hbc: outa = 10'h1a7;
8'hbd: outa = 10'h036;
8'hbe: outa = 10'h223;
8'hbf: outa = 10'h075;
8'hc0: outa = 10'h3c4;
8'hc1: outa = 10'h2cc;
8'hc2: outa = 10'h123;
8'hc3: outa = 10'h3fd;
8'hc4: outa = 10'h11e;
8'hc5: outa = 10'h27c;
8'hc6: outa = 10'h1e2;
8'hc7: outa = 10'h377;
8'hc8: outa = 10'h33a;
8'hc9: outa = 10'h32d;
8'hca: outa = 10'h014;
8'hcb: outa = 10'h332;
8'hcc: outa = 10'h359;
8'hcd: outa = 10'h0a4;
8'hce: outa = 10'h348;
8'hcf: outa = 10'h04b;
8'hd0: outa = 10'h147;
8'hd1: outa = 10'h026;
8'hd2: outa = 10'h103;
8'hd3: outa = 10'h106;
8'hd4: outa = 10'h35a;
8'hd5: outa = 10'h254;
8'hd6: outa = 10'h0cd;
8'hd7: outa = 10'h17c;
8'hd8: outa = 10'h37e;
8'hd9: outa = 10'h0a9;
8'hda: outa = 10'h0fe;
8'hdb: outa = 10'h3c0;
8'hdc: outa = 10'h1d9;
8'hdd: outa = 10'h10e;
8'hde: outa = 10'h394;
8'hdf: outa = 10'h316;
8'he0: outa = 10'h05b;
8'he1: outa = 10'h126;
8'he2: outa = 10'h369;
8'he3: outa = 10'h291;
8'he4: outa = 10'h2ca;
8'he5: outa = 10'h25b;
8'he6: outa = 10'h106;
8'he7: outa = 10'h172;
8'he8: outa = 10'h2f7;
8'he9: outa = 10'h2d3;
8'hea: outa = 10'h182;
8'heb: outa = 10'h327;
8'hec: outa = 10'h1d0;
8'hed: outa = 10'h204;
8'hee: outa = 10'h11f;
8'hef: outa = 10'h365;
8'hf0: outa = 10'h2c2;
8'hf1: outa = 10'h2b5;
8'hf2: outa = 10'h1f8;
8'hf3: outa = 10'h2a7;
8'hf4: outa = 10'h1be;
8'hf5: outa = 10'h25e;
8'hf6: outa = 10'h032;
8'hf7: outa = 10'h2ef;
8'hf8: outa = 10'h02f;
8'hf9: outa = 10'h201;
8'hfa: outa = 10'h054;
8'hfb: outa = 10'h013;
8'hfc: outa = 10'h249;
8'hfd: outa = 10'h09a;
8'hfe: outa = 10'h012;
8'hff: outa = 10'h114;
endcase
end
endmodule

View File

@ -5,289 +5,285 @@
// SPDX-License-Identifier: CC0-1.0
module t_case_huge_sub3 (/*AUTOARG*/
// Outputs
outr,
// Inputs
clk, index
);
// Outputs
outr,
// Inputs
clk, index
);
input clk;
input [9:0] index;
output [3:0] outr;
input clk;
input [9:0] index;
output logic [3:0] outr;
// =============================
/*AUTOREG*/
// Beginning of automatic regs (for this module's undeclared outputs)
reg [3:0] outr;
// End of automatics
// =============================
// Created from Pthon3:
// for i in range(256):
// print(" 8'h%02x: begin outr <= outr^index[8:5]^4'h%01x; end"
// % (i, random.randint(0,15)))
// =============================
// Created from Pthon3:
// for i in range(256):
// print(" 8'h%02x: begin outr <= outr^index[8:5]^4'h%01x; end"
// % (i, random.randint(0,15)))
// Reset cheating
initial outr = 4'b0;
// Reset cheating
initial outr = 4'b0;
always @(posedge clk) begin
case (index[7:0])
8'h00: begin outr <= 4'h0; end
8'h01: begin /*No Change*/ end
8'h02: begin outr <= outr^index[8:5]^4'ha; end
8'h03: begin outr <= outr^index[8:5]^4'h4; end
8'h04: begin outr <= outr^index[8:5]^4'hd; end
8'h05: begin outr <= outr^index[8:5]^4'h1; end
8'h06: begin outr <= outr^index[8:5]^4'hf; end
8'h07: begin outr <= outr^index[8:5]^4'he; end
8'h08: begin outr <= outr^index[8:5]^4'h0; end
8'h09: begin outr <= outr^index[8:5]^4'h4; end
8'h0a: begin outr <= outr^index[8:5]^4'h5; end
8'h0b: begin outr <= outr^index[8:5]^4'ha; end
8'h0c: begin outr <= outr^index[8:5]^4'h2; end
8'h0d: begin outr <= outr^index[8:5]^4'hf; end
8'h0e: begin outr <= outr^index[8:5]^4'h5; end
8'h0f: begin outr <= outr^index[8:5]^4'h0; end
8'h10: begin outr <= outr^index[8:5]^4'h3; end
8'h11: begin outr <= outr^index[8:5]^4'hb; end
8'h12: begin outr <= outr^index[8:5]^4'h0; end
8'h13: begin outr <= outr^index[8:5]^4'hf; end
8'h14: begin outr <= outr^index[8:5]^4'h3; end
8'h15: begin outr <= outr^index[8:5]^4'h5; end
8'h16: begin outr <= outr^index[8:5]^4'h7; end
8'h17: begin outr <= outr^index[8:5]^4'h2; end
8'h18: begin outr <= outr^index[8:5]^4'h3; end
8'h19: begin outr <= outr^index[8:5]^4'hb; end
8'h1a: begin outr <= outr^index[8:5]^4'h5; end
8'h1b: begin outr <= outr^index[8:5]^4'h4; end
8'h1c: begin outr <= outr^index[8:5]^4'h2; end
8'h1d: begin outr <= outr^index[8:5]^4'hf; end
8'h1e: begin outr <= outr^index[8:5]^4'h0; end
8'h1f: begin outr <= outr^index[8:5]^4'h4; end
8'h20: begin outr <= outr^index[8:5]^4'h6; end
8'h21: begin outr <= outr^index[8:5]^4'ha; end
8'h22: begin outr <= outr^index[8:5]^4'h6; end
8'h23: begin outr <= outr^index[8:5]^4'hb; end
8'h24: begin outr <= outr^index[8:5]^4'ha; end
8'h25: begin outr <= outr^index[8:5]^4'he; end
8'h26: begin outr <= outr^index[8:5]^4'h7; end
8'h27: begin outr <= outr^index[8:5]^4'ha; end
8'h28: begin outr <= outr^index[8:5]^4'h3; end
8'h29: begin outr <= outr^index[8:5]^4'h8; end
8'h2a: begin outr <= outr^index[8:5]^4'h1; end
8'h2b: begin outr <= outr^index[8:5]^4'h8; end
8'h2c: begin outr <= outr^index[8:5]^4'h4; end
8'h2d: begin outr <= outr^index[8:5]^4'h4; end
8'h2e: begin outr <= outr^index[8:5]^4'he; end
8'h2f: begin outr <= outr^index[8:5]^4'h8; end
8'h30: begin outr <= outr^index[8:5]^4'ha; end
8'h31: begin outr <= outr^index[8:5]^4'h7; end
8'h32: begin outr <= outr^index[8:5]^4'h0; end
8'h33: begin outr <= outr^index[8:5]^4'h3; end
8'h34: begin outr <= outr^index[8:5]^4'h1; end
8'h35: begin outr <= outr^index[8:5]^4'h3; end
8'h36: begin outr <= outr^index[8:5]^4'h4; end
8'h37: begin outr <= outr^index[8:5]^4'h6; end
8'h38: begin outr <= outr^index[8:5]^4'h4; end
8'h39: begin outr <= outr^index[8:5]^4'hb; end
8'h3a: begin outr <= outr^index[8:5]^4'h7; end
8'h3b: begin outr <= outr^index[8:5]^4'h1; end
8'h3c: begin outr <= outr^index[8:5]^4'h2; end
8'h3d: begin outr <= outr^index[8:5]^4'h0; end
8'h3e: begin outr <= outr^index[8:5]^4'h2; end
8'h3f: begin outr <= outr^index[8:5]^4'ha; end
8'h40: begin outr <= outr^index[8:5]^4'h7; end
8'h41: begin outr <= outr^index[8:5]^4'h5; end
8'h42: begin outr <= outr^index[8:5]^4'h5; end
8'h43: begin outr <= outr^index[8:5]^4'h4; end
8'h44: begin outr <= outr^index[8:5]^4'h8; end
8'h45: begin outr <= outr^index[8:5]^4'h5; end
8'h46: begin outr <= outr^index[8:5]^4'hf; end
8'h47: begin outr <= outr^index[8:5]^4'h6; end
8'h48: begin outr <= outr^index[8:5]^4'h7; end
8'h49: begin outr <= outr^index[8:5]^4'h4; end
8'h4a: begin outr <= outr^index[8:5]^4'ha; end
8'h4b: begin outr <= outr^index[8:5]^4'hd; end
8'h4c: begin outr <= outr^index[8:5]^4'hb; end
8'h4d: begin outr <= outr^index[8:5]^4'hf; end
8'h4e: begin outr <= outr^index[8:5]^4'hd; end
8'h4f: begin outr <= outr^index[8:5]^4'h7; end
8'h50: begin outr <= outr^index[8:5]^4'h9; end
8'h51: begin outr <= outr^index[8:5]^4'ha; end
8'h52: begin outr <= outr^index[8:5]^4'hf; end
8'h53: begin outr <= outr^index[8:5]^4'h3; end
8'h54: begin outr <= outr^index[8:5]^4'h1; end
8'h55: begin outr <= outr^index[8:5]^4'h0; end
8'h56: begin outr <= outr^index[8:5]^4'h2; end
8'h57: begin outr <= outr^index[8:5]^4'h9; end
8'h58: begin outr <= outr^index[8:5]^4'h2; end
8'h59: begin outr <= outr^index[8:5]^4'h4; end
8'h5a: begin outr <= outr^index[8:5]^4'hc; end
8'h5b: begin outr <= outr^index[8:5]^4'hd; end
8'h5c: begin outr <= outr^index[8:5]^4'h3; end
8'h5d: begin outr <= outr^index[8:5]^4'hb; end
8'h5e: begin outr <= outr^index[8:5]^4'hd; end
8'h5f: begin outr <= outr^index[8:5]^4'h7; end
8'h60: begin outr <= outr^index[8:5]^4'h7; end
8'h61: begin outr <= outr^index[8:5]^4'h3; end
8'h62: begin outr <= outr^index[8:5]^4'h3; end
8'h63: begin outr <= outr^index[8:5]^4'hb; end
8'h64: begin outr <= outr^index[8:5]^4'h9; end
8'h65: begin outr <= outr^index[8:5]^4'h4; end
8'h66: begin outr <= outr^index[8:5]^4'h3; end
8'h67: begin outr <= outr^index[8:5]^4'h6; end
8'h68: begin outr <= outr^index[8:5]^4'h7; end
8'h69: begin outr <= outr^index[8:5]^4'h7; end
8'h6a: begin outr <= outr^index[8:5]^4'hf; end
8'h6b: begin outr <= outr^index[8:5]^4'h6; end
8'h6c: begin outr <= outr^index[8:5]^4'h8; end
8'h6d: begin outr <= outr^index[8:5]^4'he; end
8'h6e: begin outr <= outr^index[8:5]^4'h4; end
8'h6f: begin outr <= outr^index[8:5]^4'h6; end
8'h70: begin outr <= outr^index[8:5]^4'hc; end
8'h71: begin outr <= outr^index[8:5]^4'h9; end
8'h72: begin outr <= outr^index[8:5]^4'h5; end
8'h73: begin outr <= outr^index[8:5]^4'ha; end
8'h74: begin outr <= outr^index[8:5]^4'h7; end
8'h75: begin outr <= outr^index[8:5]^4'h0; end
8'h76: begin outr <= outr^index[8:5]^4'h1; end
8'h77: begin outr <= outr^index[8:5]^4'he; end
8'h78: begin outr <= outr^index[8:5]^4'ha; end
8'h79: begin outr <= outr^index[8:5]^4'h7; end
8'h7a: begin outr <= outr^index[8:5]^4'hf; end
8'h7b: begin outr <= outr^index[8:5]^4'he; end
8'h7c: begin outr <= outr^index[8:5]^4'h6; end
8'h7d: begin outr <= outr^index[8:5]^4'hc; end
8'h7e: begin outr <= outr^index[8:5]^4'hc; end
8'h7f: begin outr <= outr^index[8:5]^4'h0; end
8'h80: begin outr <= outr^index[8:5]^4'h0; end
8'h81: begin outr <= outr^index[8:5]^4'hd; end
8'h82: begin outr <= outr^index[8:5]^4'hb; end
8'h83: begin outr <= outr^index[8:5]^4'hc; end
8'h84: begin outr <= outr^index[8:5]^4'h2; end
8'h85: begin outr <= outr^index[8:5]^4'h8; end
8'h86: begin outr <= outr^index[8:5]^4'h3; end
8'h87: begin outr <= outr^index[8:5]^4'ha; end
8'h88: begin outr <= outr^index[8:5]^4'he; end
8'h89: begin outr <= outr^index[8:5]^4'h9; end
8'h8a: begin outr <= outr^index[8:5]^4'h1; end
8'h8b: begin outr <= outr^index[8:5]^4'h1; end
8'h8c: begin outr <= outr^index[8:5]^4'hc; end
8'h8d: begin outr <= outr^index[8:5]^4'h2; end
8'h8e: begin outr <= outr^index[8:5]^4'h2; end
8'h8f: begin outr <= outr^index[8:5]^4'hd; end
8'h90: begin outr <= outr^index[8:5]^4'h0; end
8'h91: begin outr <= outr^index[8:5]^4'h6; end
8'h92: begin outr <= outr^index[8:5]^4'h7; end
8'h93: begin outr <= outr^index[8:5]^4'hc; end
8'h94: begin outr <= outr^index[8:5]^4'hb; end
8'h95: begin outr <= outr^index[8:5]^4'h3; end
8'h96: begin outr <= outr^index[8:5]^4'h0; end
8'h97: begin outr <= outr^index[8:5]^4'hc; end
8'h98: begin outr <= outr^index[8:5]^4'hc; end
8'h99: begin outr <= outr^index[8:5]^4'hb; end
8'h9a: begin outr <= outr^index[8:5]^4'h6; end
8'h9b: begin outr <= outr^index[8:5]^4'h5; end
8'h9c: begin outr <= outr^index[8:5]^4'h5; end
8'h9d: begin outr <= outr^index[8:5]^4'h4; end
8'h9e: begin outr <= outr^index[8:5]^4'h7; end
8'h9f: begin outr <= outr^index[8:5]^4'he; end
8'ha0: begin outr <= outr^index[8:5]^4'hc; end
8'ha1: begin outr <= outr^index[8:5]^4'hc; end
8'ha2: begin outr <= outr^index[8:5]^4'h0; end
8'ha3: begin outr <= outr^index[8:5]^4'h1; end
8'ha4: begin outr <= outr^index[8:5]^4'hd; end
8'ha5: begin outr <= outr^index[8:5]^4'h3; end
8'ha6: begin outr <= outr^index[8:5]^4'hc; end
8'ha7: begin outr <= outr^index[8:5]^4'h2; end
8'ha8: begin outr <= outr^index[8:5]^4'h3; end
8'ha9: begin outr <= outr^index[8:5]^4'hd; end
8'haa: begin outr <= outr^index[8:5]^4'h5; end
8'hab: begin outr <= outr^index[8:5]^4'hb; end
8'hac: begin outr <= outr^index[8:5]^4'he; end
8'had: begin outr <= outr^index[8:5]^4'h0; end
8'hae: begin outr <= outr^index[8:5]^4'hf; end
8'haf: begin outr <= outr^index[8:5]^4'h9; end
8'hb0: begin outr <= outr^index[8:5]^4'hf; end
8'hb1: begin outr <= outr^index[8:5]^4'h7; end
8'hb2: begin outr <= outr^index[8:5]^4'h9; end
8'hb3: begin outr <= outr^index[8:5]^4'hf; end
8'hb4: begin outr <= outr^index[8:5]^4'he; end
8'hb5: begin outr <= outr^index[8:5]^4'h3; end
8'hb6: begin outr <= outr^index[8:5]^4'he; end
8'hb7: begin outr <= outr^index[8:5]^4'h8; end
8'hb8: begin outr <= outr^index[8:5]^4'hf; end
8'hb9: begin outr <= outr^index[8:5]^4'hd; end
8'hba: begin outr <= outr^index[8:5]^4'h3; end
8'hbb: begin outr <= outr^index[8:5]^4'h5; end
8'hbc: begin outr <= outr^index[8:5]^4'hd; end
8'hbd: begin outr <= outr^index[8:5]^4'ha; end
8'hbe: begin outr <= outr^index[8:5]^4'h7; end
8'hbf: begin outr <= outr^index[8:5]^4'he; end
8'hc0: begin outr <= outr^index[8:5]^4'h2; end
8'hc1: begin outr <= outr^index[8:5]^4'he; end
8'hc2: begin outr <= outr^index[8:5]^4'h9; end
8'hc3: begin outr <= outr^index[8:5]^4'hb; end
8'hc4: begin outr <= outr^index[8:5]^4'h0; end
8'hc5: begin outr <= outr^index[8:5]^4'h5; end
8'hc6: begin outr <= outr^index[8:5]^4'h9; end
8'hc7: begin outr <= outr^index[8:5]^4'h6; end
8'hc8: begin outr <= outr^index[8:5]^4'ha; end
8'hc9: begin outr <= outr^index[8:5]^4'hf; end
8'hca: begin outr <= outr^index[8:5]^4'h3; end
8'hcb: begin outr <= outr^index[8:5]^4'hb; end
8'hcc: begin outr <= outr^index[8:5]^4'he; end
8'hcd: begin outr <= outr^index[8:5]^4'h2; end
8'hce: begin outr <= outr^index[8:5]^4'h5; end
8'hcf: begin outr <= outr^index[8:5]^4'hf; end
8'hd0: begin outr <= outr^index[8:5]^4'h2; end
8'hd1: begin outr <= outr^index[8:5]^4'h9; end
8'hd2: begin outr <= outr^index[8:5]^4'hb; end
8'hd3: begin outr <= outr^index[8:5]^4'h8; end
8'hd4: begin outr <= outr^index[8:5]^4'h0; end
8'hd5: begin outr <= outr^index[8:5]^4'h2; end
8'hd6: begin outr <= outr^index[8:5]^4'hb; end
8'hd7: begin outr <= outr^index[8:5]^4'h2; end
8'hd8: begin outr <= outr^index[8:5]^4'ha; end
8'hd9: begin outr <= outr^index[8:5]^4'hf; end
8'hda: begin outr <= outr^index[8:5]^4'h8; end
8'hdb: begin outr <= outr^index[8:5]^4'h4; end
8'hdc: begin outr <= outr^index[8:5]^4'he; end
8'hdd: begin outr <= outr^index[8:5]^4'h6; end
8'hde: begin outr <= outr^index[8:5]^4'h9; end
8'hdf: begin outr <= outr^index[8:5]^4'h9; end
8'he0: begin outr <= outr^index[8:5]^4'h7; end
8'he1: begin outr <= outr^index[8:5]^4'h0; end
8'he2: begin outr <= outr^index[8:5]^4'h9; end
8'he3: begin outr <= outr^index[8:5]^4'h3; end
8'he4: begin outr <= outr^index[8:5]^4'h2; end
8'he5: begin outr <= outr^index[8:5]^4'h4; end
8'he6: begin outr <= outr^index[8:5]^4'h5; end
8'he7: begin outr <= outr^index[8:5]^4'h5; end
8'he8: begin outr <= outr^index[8:5]^4'hf; end
8'he9: begin outr <= outr^index[8:5]^4'ha; end
8'hea: begin outr <= outr^index[8:5]^4'hc; end
8'heb: begin outr <= outr^index[8:5]^4'hd; end
8'hec: begin outr <= outr^index[8:5]^4'h1; end
8'hed: begin outr <= outr^index[8:5]^4'h5; end
8'hee: begin outr <= outr^index[8:5]^4'h9; end
8'hef: begin outr <= outr^index[8:5]^4'h0; end
8'hf0: begin outr <= outr^index[8:5]^4'hd; end
8'hf1: begin outr <= outr^index[8:5]^4'hf; end
8'hf2: begin outr <= outr^index[8:5]^4'h4; end
8'hf3: begin outr <= outr^index[8:5]^4'ha; end
8'hf4: begin outr <= outr^index[8:5]^4'h8; end
8'hf5: begin outr <= outr^index[8:5]^4'he; end
8'hf6: begin outr <= outr^index[8:5]^4'he; end
8'hf7: begin outr <= outr^index[8:5]^4'h1; end
8'hf8: begin outr <= outr^index[8:5]^4'h6; end
8'hf9: begin outr <= outr^index[8:5]^4'h0; end
8'hfa: begin outr <= outr^index[8:5]^4'h5; end
8'hfb: begin outr <= outr^index[8:5]^4'h1; end
8'hfc: begin outr <= outr^index[8:5]^4'h8; end
8'hfd: begin outr <= outr^index[8:5]^4'h6; end
8'hfe: begin outr <= outr^index[8:5]^4'h1; end
default: begin outr <= outr^index[8:5]^4'h6; end
endcase
end
always @(posedge clk) begin
// verilog_format: off
case (index[7:0])
8'h00: begin outr <= 4'h0; end
8'h01: begin /*No Change*/ end
8'h02: begin outr <= outr^index[8:5]^4'ha; end
8'h03: begin outr <= outr^index[8:5]^4'h4; end
8'h04: begin outr <= outr^index[8:5]^4'hd; end
8'h05: begin outr <= outr^index[8:5]^4'h1; end
8'h06: begin outr <= outr^index[8:5]^4'hf; end
8'h07: begin outr <= outr^index[8:5]^4'he; end
8'h08: begin outr <= outr^index[8:5]^4'h0; end
8'h09: begin outr <= outr^index[8:5]^4'h4; end
8'h0a: begin outr <= outr^index[8:5]^4'h5; end
8'h0b: begin outr <= outr^index[8:5]^4'ha; end
8'h0c: begin outr <= outr^index[8:5]^4'h2; end
8'h0d: begin outr <= outr^index[8:5]^4'hf; end
8'h0e: begin outr <= outr^index[8:5]^4'h5; end
8'h0f: begin outr <= outr^index[8:5]^4'h0; end
8'h10: begin outr <= outr^index[8:5]^4'h3; end
8'h11: begin outr <= outr^index[8:5]^4'hb; end
8'h12: begin outr <= outr^index[8:5]^4'h0; end
8'h13: begin outr <= outr^index[8:5]^4'hf; end
8'h14: begin outr <= outr^index[8:5]^4'h3; end
8'h15: begin outr <= outr^index[8:5]^4'h5; end
8'h16: begin outr <= outr^index[8:5]^4'h7; end
8'h17: begin outr <= outr^index[8:5]^4'h2; end
8'h18: begin outr <= outr^index[8:5]^4'h3; end
8'h19: begin outr <= outr^index[8:5]^4'hb; end
8'h1a: begin outr <= outr^index[8:5]^4'h5; end
8'h1b: begin outr <= outr^index[8:5]^4'h4; end
8'h1c: begin outr <= outr^index[8:5]^4'h2; end
8'h1d: begin outr <= outr^index[8:5]^4'hf; end
8'h1e: begin outr <= outr^index[8:5]^4'h0; end
8'h1f: begin outr <= outr^index[8:5]^4'h4; end
8'h20: begin outr <= outr^index[8:5]^4'h6; end
8'h21: begin outr <= outr^index[8:5]^4'ha; end
8'h22: begin outr <= outr^index[8:5]^4'h6; end
8'h23: begin outr <= outr^index[8:5]^4'hb; end
8'h24: begin outr <= outr^index[8:5]^4'ha; end
8'h25: begin outr <= outr^index[8:5]^4'he; end
8'h26: begin outr <= outr^index[8:5]^4'h7; end
8'h27: begin outr <= outr^index[8:5]^4'ha; end
8'h28: begin outr <= outr^index[8:5]^4'h3; end
8'h29: begin outr <= outr^index[8:5]^4'h8; end
8'h2a: begin outr <= outr^index[8:5]^4'h1; end
8'h2b: begin outr <= outr^index[8:5]^4'h8; end
8'h2c: begin outr <= outr^index[8:5]^4'h4; end
8'h2d: begin outr <= outr^index[8:5]^4'h4; end
8'h2e: begin outr <= outr^index[8:5]^4'he; end
8'h2f: begin outr <= outr^index[8:5]^4'h8; end
8'h30: begin outr <= outr^index[8:5]^4'ha; end
8'h31: begin outr <= outr^index[8:5]^4'h7; end
8'h32: begin outr <= outr^index[8:5]^4'h0; end
8'h33: begin outr <= outr^index[8:5]^4'h3; end
8'h34: begin outr <= outr^index[8:5]^4'h1; end
8'h35: begin outr <= outr^index[8:5]^4'h3; end
8'h36: begin outr <= outr^index[8:5]^4'h4; end
8'h37: begin outr <= outr^index[8:5]^4'h6; end
8'h38: begin outr <= outr^index[8:5]^4'h4; end
8'h39: begin outr <= outr^index[8:5]^4'hb; end
8'h3a: begin outr <= outr^index[8:5]^4'h7; end
8'h3b: begin outr <= outr^index[8:5]^4'h1; end
8'h3c: begin outr <= outr^index[8:5]^4'h2; end
8'h3d: begin outr <= outr^index[8:5]^4'h0; end
8'h3e: begin outr <= outr^index[8:5]^4'h2; end
8'h3f: begin outr <= outr^index[8:5]^4'ha; end
8'h40: begin outr <= outr^index[8:5]^4'h7; end
8'h41: begin outr <= outr^index[8:5]^4'h5; end
8'h42: begin outr <= outr^index[8:5]^4'h5; end
8'h43: begin outr <= outr^index[8:5]^4'h4; end
8'h44: begin outr <= outr^index[8:5]^4'h8; end
8'h45: begin outr <= outr^index[8:5]^4'h5; end
8'h46: begin outr <= outr^index[8:5]^4'hf; end
8'h47: begin outr <= outr^index[8:5]^4'h6; end
8'h48: begin outr <= outr^index[8:5]^4'h7; end
8'h49: begin outr <= outr^index[8:5]^4'h4; end
8'h4a: begin outr <= outr^index[8:5]^4'ha; end
8'h4b: begin outr <= outr^index[8:5]^4'hd; end
8'h4c: begin outr <= outr^index[8:5]^4'hb; end
8'h4d: begin outr <= outr^index[8:5]^4'hf; end
8'h4e: begin outr <= outr^index[8:5]^4'hd; end
8'h4f: begin outr <= outr^index[8:5]^4'h7; end
8'h50: begin outr <= outr^index[8:5]^4'h9; end
8'h51: begin outr <= outr^index[8:5]^4'ha; end
8'h52: begin outr <= outr^index[8:5]^4'hf; end
8'h53: begin outr <= outr^index[8:5]^4'h3; end
8'h54: begin outr <= outr^index[8:5]^4'h1; end
8'h55: begin outr <= outr^index[8:5]^4'h0; end
8'h56: begin outr <= outr^index[8:5]^4'h2; end
8'h57: begin outr <= outr^index[8:5]^4'h9; end
8'h58: begin outr <= outr^index[8:5]^4'h2; end
8'h59: begin outr <= outr^index[8:5]^4'h4; end
8'h5a: begin outr <= outr^index[8:5]^4'hc; end
8'h5b: begin outr <= outr^index[8:5]^4'hd; end
8'h5c: begin outr <= outr^index[8:5]^4'h3; end
8'h5d: begin outr <= outr^index[8:5]^4'hb; end
8'h5e: begin outr <= outr^index[8:5]^4'hd; end
8'h5f: begin outr <= outr^index[8:5]^4'h7; end
8'h60: begin outr <= outr^index[8:5]^4'h7; end
8'h61: begin outr <= outr^index[8:5]^4'h3; end
8'h62: begin outr <= outr^index[8:5]^4'h3; end
8'h63: begin outr <= outr^index[8:5]^4'hb; end
8'h64: begin outr <= outr^index[8:5]^4'h9; end
8'h65: begin outr <= outr^index[8:5]^4'h4; end
8'h66: begin outr <= outr^index[8:5]^4'h3; end
8'h67: begin outr <= outr^index[8:5]^4'h6; end
8'h68: begin outr <= outr^index[8:5]^4'h7; end
8'h69: begin outr <= outr^index[8:5]^4'h7; end
8'h6a: begin outr <= outr^index[8:5]^4'hf; end
8'h6b: begin outr <= outr^index[8:5]^4'h6; end
8'h6c: begin outr <= outr^index[8:5]^4'h8; end
8'h6d: begin outr <= outr^index[8:5]^4'he; end
8'h6e: begin outr <= outr^index[8:5]^4'h4; end
8'h6f: begin outr <= outr^index[8:5]^4'h6; end
8'h70: begin outr <= outr^index[8:5]^4'hc; end
8'h71: begin outr <= outr^index[8:5]^4'h9; end
8'h72: begin outr <= outr^index[8:5]^4'h5; end
8'h73: begin outr <= outr^index[8:5]^4'ha; end
8'h74: begin outr <= outr^index[8:5]^4'h7; end
8'h75: begin outr <= outr^index[8:5]^4'h0; end
8'h76: begin outr <= outr^index[8:5]^4'h1; end
8'h77: begin outr <= outr^index[8:5]^4'he; end
8'h78: begin outr <= outr^index[8:5]^4'ha; end
8'h79: begin outr <= outr^index[8:5]^4'h7; end
8'h7a: begin outr <= outr^index[8:5]^4'hf; end
8'h7b: begin outr <= outr^index[8:5]^4'he; end
8'h7c: begin outr <= outr^index[8:5]^4'h6; end
8'h7d: begin outr <= outr^index[8:5]^4'hc; end
8'h7e: begin outr <= outr^index[8:5]^4'hc; end
8'h7f: begin outr <= outr^index[8:5]^4'h0; end
8'h80: begin outr <= outr^index[8:5]^4'h0; end
8'h81: begin outr <= outr^index[8:5]^4'hd; end
8'h82: begin outr <= outr^index[8:5]^4'hb; end
8'h83: begin outr <= outr^index[8:5]^4'hc; end
8'h84: begin outr <= outr^index[8:5]^4'h2; end
8'h85: begin outr <= outr^index[8:5]^4'h8; end
8'h86: begin outr <= outr^index[8:5]^4'h3; end
8'h87: begin outr <= outr^index[8:5]^4'ha; end
8'h88: begin outr <= outr^index[8:5]^4'he; end
8'h89: begin outr <= outr^index[8:5]^4'h9; end
8'h8a: begin outr <= outr^index[8:5]^4'h1; end
8'h8b: begin outr <= outr^index[8:5]^4'h1; end
8'h8c: begin outr <= outr^index[8:5]^4'hc; end
8'h8d: begin outr <= outr^index[8:5]^4'h2; end
8'h8e: begin outr <= outr^index[8:5]^4'h2; end
8'h8f: begin outr <= outr^index[8:5]^4'hd; end
8'h90: begin outr <= outr^index[8:5]^4'h0; end
8'h91: begin outr <= outr^index[8:5]^4'h6; end
8'h92: begin outr <= outr^index[8:5]^4'h7; end
8'h93: begin outr <= outr^index[8:5]^4'hc; end
8'h94: begin outr <= outr^index[8:5]^4'hb; end
8'h95: begin outr <= outr^index[8:5]^4'h3; end
8'h96: begin outr <= outr^index[8:5]^4'h0; end
8'h97: begin outr <= outr^index[8:5]^4'hc; end
8'h98: begin outr <= outr^index[8:5]^4'hc; end
8'h99: begin outr <= outr^index[8:5]^4'hb; end
8'h9a: begin outr <= outr^index[8:5]^4'h6; end
8'h9b: begin outr <= outr^index[8:5]^4'h5; end
8'h9c: begin outr <= outr^index[8:5]^4'h5; end
8'h9d: begin outr <= outr^index[8:5]^4'h4; end
8'h9e: begin outr <= outr^index[8:5]^4'h7; end
8'h9f: begin outr <= outr^index[8:5]^4'he; end
8'ha0: begin outr <= outr^index[8:5]^4'hc; end
8'ha1: begin outr <= outr^index[8:5]^4'hc; end
8'ha2: begin outr <= outr^index[8:5]^4'h0; end
8'ha3: begin outr <= outr^index[8:5]^4'h1; end
8'ha4: begin outr <= outr^index[8:5]^4'hd; end
8'ha5: begin outr <= outr^index[8:5]^4'h3; end
8'ha6: begin outr <= outr^index[8:5]^4'hc; end
8'ha7: begin outr <= outr^index[8:5]^4'h2; end
8'ha8: begin outr <= outr^index[8:5]^4'h3; end
8'ha9: begin outr <= outr^index[8:5]^4'hd; end
8'haa: begin outr <= outr^index[8:5]^4'h5; end
8'hab: begin outr <= outr^index[8:5]^4'hb; end
8'hac: begin outr <= outr^index[8:5]^4'he; end
8'had: begin outr <= outr^index[8:5]^4'h0; end
8'hae: begin outr <= outr^index[8:5]^4'hf; end
8'haf: begin outr <= outr^index[8:5]^4'h9; end
8'hb0: begin outr <= outr^index[8:5]^4'hf; end
8'hb1: begin outr <= outr^index[8:5]^4'h7; end
8'hb2: begin outr <= outr^index[8:5]^4'h9; end
8'hb3: begin outr <= outr^index[8:5]^4'hf; end
8'hb4: begin outr <= outr^index[8:5]^4'he; end
8'hb5: begin outr <= outr^index[8:5]^4'h3; end
8'hb6: begin outr <= outr^index[8:5]^4'he; end
8'hb7: begin outr <= outr^index[8:5]^4'h8; end
8'hb8: begin outr <= outr^index[8:5]^4'hf; end
8'hb9: begin outr <= outr^index[8:5]^4'hd; end
8'hba: begin outr <= outr^index[8:5]^4'h3; end
8'hbb: begin outr <= outr^index[8:5]^4'h5; end
8'hbc: begin outr <= outr^index[8:5]^4'hd; end
8'hbd: begin outr <= outr^index[8:5]^4'ha; end
8'hbe: begin outr <= outr^index[8:5]^4'h7; end
8'hbf: begin outr <= outr^index[8:5]^4'he; end
8'hc0: begin outr <= outr^index[8:5]^4'h2; end
8'hc1: begin outr <= outr^index[8:5]^4'he; end
8'hc2: begin outr <= outr^index[8:5]^4'h9; end
8'hc3: begin outr <= outr^index[8:5]^4'hb; end
8'hc4: begin outr <= outr^index[8:5]^4'h0; end
8'hc5: begin outr <= outr^index[8:5]^4'h5; end
8'hc6: begin outr <= outr^index[8:5]^4'h9; end
8'hc7: begin outr <= outr^index[8:5]^4'h6; end
8'hc8: begin outr <= outr^index[8:5]^4'ha; end
8'hc9: begin outr <= outr^index[8:5]^4'hf; end
8'hca: begin outr <= outr^index[8:5]^4'h3; end
8'hcb: begin outr <= outr^index[8:5]^4'hb; end
8'hcc: begin outr <= outr^index[8:5]^4'he; end
8'hcd: begin outr <= outr^index[8:5]^4'h2; end
8'hce: begin outr <= outr^index[8:5]^4'h5; end
8'hcf: begin outr <= outr^index[8:5]^4'hf; end
8'hd0: begin outr <= outr^index[8:5]^4'h2; end
8'hd1: begin outr <= outr^index[8:5]^4'h9; end
8'hd2: begin outr <= outr^index[8:5]^4'hb; end
8'hd3: begin outr <= outr^index[8:5]^4'h8; end
8'hd4: begin outr <= outr^index[8:5]^4'h0; end
8'hd5: begin outr <= outr^index[8:5]^4'h2; end
8'hd6: begin outr <= outr^index[8:5]^4'hb; end
8'hd7: begin outr <= outr^index[8:5]^4'h2; end
8'hd8: begin outr <= outr^index[8:5]^4'ha; end
8'hd9: begin outr <= outr^index[8:5]^4'hf; end
8'hda: begin outr <= outr^index[8:5]^4'h8; end
8'hdb: begin outr <= outr^index[8:5]^4'h4; end
8'hdc: begin outr <= outr^index[8:5]^4'he; end
8'hdd: begin outr <= outr^index[8:5]^4'h6; end
8'hde: begin outr <= outr^index[8:5]^4'h9; end
8'hdf: begin outr <= outr^index[8:5]^4'h9; end
8'he0: begin outr <= outr^index[8:5]^4'h7; end
8'he1: begin outr <= outr^index[8:5]^4'h0; end
8'he2: begin outr <= outr^index[8:5]^4'h9; end
8'he3: begin outr <= outr^index[8:5]^4'h3; end
8'he4: begin outr <= outr^index[8:5]^4'h2; end
8'he5: begin outr <= outr^index[8:5]^4'h4; end
8'he6: begin outr <= outr^index[8:5]^4'h5; end
8'he7: begin outr <= outr^index[8:5]^4'h5; end
8'he8: begin outr <= outr^index[8:5]^4'hf; end
8'he9: begin outr <= outr^index[8:5]^4'ha; end
8'hea: begin outr <= outr^index[8:5]^4'hc; end
8'heb: begin outr <= outr^index[8:5]^4'hd; end
8'hec: begin outr <= outr^index[8:5]^4'h1; end
8'hed: begin outr <= outr^index[8:5]^4'h5; end
8'hee: begin outr <= outr^index[8:5]^4'h9; end
8'hef: begin outr <= outr^index[8:5]^4'h0; end
8'hf0: begin outr <= outr^index[8:5]^4'hd; end
8'hf1: begin outr <= outr^index[8:5]^4'hf; end
8'hf2: begin outr <= outr^index[8:5]^4'h4; end
8'hf3: begin outr <= outr^index[8:5]^4'ha; end
8'hf4: begin outr <= outr^index[8:5]^4'h8; end
8'hf5: begin outr <= outr^index[8:5]^4'he; end
8'hf6: begin outr <= outr^index[8:5]^4'he; end
8'hf7: begin outr <= outr^index[8:5]^4'h1; end
8'hf8: begin outr <= outr^index[8:5]^4'h6; end
8'hf9: begin outr <= outr^index[8:5]^4'h0; end
8'hfa: begin outr <= outr^index[8:5]^4'h5; end
8'hfb: begin outr <= outr^index[8:5]^4'h1; end
8'hfc: begin outr <= outr^index[8:5]^4'h8; end
8'hfd: begin outr <= outr^index[8:5]^4'h6; end
8'hfe: begin outr <= outr^index[8:5]^4'h1; end
default: begin outr <= outr^index[8:5]^4'h6; end
endcase
// verilog_format: on
end
endmodule

View File

@ -7,59 +7,56 @@
// verilator lint_off LATCH
module t_case_huge_sub4 (/*AUTOARG*/
// Outputs
outq,
// Inputs
index
);
// Outputs
outq,
// Inputs
index
);
input [7:0] index;
output [9:0] outq;
input [7:0] index;
output logic [9:0] outq;
// =============================
/*AUTOREG*/
// Beginning of automatic regs (for this module's undeclared outputs)
reg [9:0] outq;
// End of automatics
// =============================
// =============================
always @(/*AS*/index) begin
case (index)
// default below: no change
8'h00: begin outq = 10'h001; end
8'he0: begin outq = 10'h05b; end
8'he1: begin outq = 10'h126; end
8'he2: begin outq = 10'h369; end
8'he3: begin outq = 10'h291; end
8'he4: begin outq = 10'h2ca; end
8'he5: begin outq = 10'h25b; end
8'he6: begin outq = 10'h106; end
8'he7: begin outq = 10'h172; end
8'he8: begin outq = 10'h2f7; end
8'he9: begin outq = 10'h2d3; end
8'hea: begin outq = 10'h182; end
8'heb: begin outq = 10'h327; end
8'hec: begin outq = 10'h1d0; end
8'hed: begin outq = 10'h204; end
8'hee: begin outq = 10'h11f; end
8'hef: begin outq = 10'h365; end
8'hf0: begin outq = 10'h2c2; end
8'hf1: begin outq = 10'h2b5; end
8'hf2: begin outq = 10'h1f8; end
8'hf3: begin outq = 10'h2a7; end
8'hf4: begin outq = 10'h1be; end
8'hf5: begin outq = 10'h25e; end
8'hf6: begin outq = 10'h032; end
8'hf7: begin outq = 10'h2ef; end
8'hf8: begin outq = 10'h02f; end
8'hf9: begin outq = 10'h201; end
8'hfa: begin outq = 10'h054; end
8'hfb: begin outq = 10'h013; end
8'hfc: begin outq = 10'h249; end
8'hfd: begin outq = 10'h09a; end
8'hfe: begin outq = 10'h012; end
8'hff: begin outq = 10'h114; end
default: ; // No change
endcase
end
always @* begin
// verilog_format: off
case (index)
// default below: no change
8'h00: begin outq = 10'h001; end
8'he0: begin outq = 10'h05b; end
8'he1: begin outq = 10'h126; end
8'he2: begin outq = 10'h369; end
8'he3: begin outq = 10'h291; end
8'he4: begin outq = 10'h2ca; end
8'he5: begin outq = 10'h25b; end
8'he6: begin outq = 10'h106; end
8'he7: begin outq = 10'h172; end
8'he8: begin outq = 10'h2f7; end
8'he9: begin outq = 10'h2d3; end
8'hea: begin outq = 10'h182; end
8'heb: begin outq = 10'h327; end
8'hec: begin outq = 10'h1d0; end
8'hed: begin outq = 10'h204; end
8'hee: begin outq = 10'h11f; end
8'hef: begin outq = 10'h365; end
8'hf0: begin outq = 10'h2c2; end
8'hf1: begin outq = 10'h2b5; end
8'hf2: begin outq = 10'h1f8; end
8'hf3: begin outq = 10'h2a7; end
8'hf4: begin outq = 10'h1be; end
8'hf5: begin outq = 10'h25e; end
8'hf6: begin outq = 10'h032; end
8'hf7: begin outq = 10'h2ef; end
8'hf8: begin outq = 10'h02f; end
8'hf9: begin outq = 10'h201; end
8'hfa: begin outq = 10'h054; end
8'hfb: begin outq = 10'h013; end
8'hfc: begin outq = 10'h249; end
8'hfd: begin outq = 10'h09a; end
8'hfe: begin outq = 10'h012; end
8'hff: begin outq = 10'h114; end
default: ; // No change
endcase
// verilog_format: on
end
endmodule

View File

@ -4,326 +4,326 @@
// any use, without warranty, 2024 by Varun Koyyalagunta, Tenstorrent.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/);
module t;
localparam W = 23;
localparam W = 23;
localparam [W-1:0] R0 = W'('h200000 + 0);
localparam [W-1:0] R1 = W'('h200000 + 1);
localparam [W-1:0] R2 = W'('h200000 + 2);
localparam [W-1:0] R3 = W'('h200000 + 3);
localparam [W-1:0] R4 = W'('h200000 + 4);
localparam [W-1:0] R5 = W'('h200000 + 5);
localparam [W-1:0] R6 = W'('h200000 + 6);
localparam [W-1:0] R7 = W'('h200000 + 7);
localparam [W-1:0] R8 = W'('h200000 + 8);
localparam [W-1:0] R9 = W'('h200000 + 9);
localparam [W-1:0] R10 = W'('h200000 + 10);
localparam [W-1:0] R11 = W'('h200000 + 11);
localparam [W-1:0] R12 = W'('h200000 + 12);
localparam [W-1:0] R13 = W'('h200000 + 13);
localparam [W-1:0] R14 = W'('h200000 + 14);
localparam [W-1:0] R15 = W'('h200000 + 15);
localparam [W-1:0] R16 = W'('h200000 + 16);
localparam [W-1:0] R17 = W'('h200000 + 17);
localparam [W-1:0] R18 = W'('h200000 + 18);
localparam [W-1:0] R19 = W'('h200000 + 19);
localparam [W-1:0] R20 = W'('h200000 + 20);
localparam [W-1:0] R21 = W'('h200000 + 21);
localparam [W-1:0] R22 = W'('h200000 + 22);
localparam [W-1:0] R23 = W'('h200000 + 23);
localparam [W-1:0] R24 = W'('h200000 + 24);
localparam [W-1:0] R25 = W'('h200000 + 25);
localparam [W-1:0] R26 = W'('h200000 + 26);
localparam [W-1:0] R27 = W'('h200000 + 27);
localparam [W-1:0] R28 = W'('h200000 + 28);
localparam [W-1:0] R29 = W'('h200000 + 29);
localparam [W-1:0] R30 = W'('h200000 + 30);
localparam [W-1:0] R31 = W'('h200000 + 31);
localparam [W-1:0] R32 = W'('h200000 + 32);
localparam [W-1:0] R33 = W'('h200000 + 33);
localparam [W-1:0] R34 = W'('h200000 + 34);
localparam [W-1:0] R35 = W'('h200000 + 35);
localparam [W-1:0] R36 = W'('h200000 + 36);
localparam [W-1:0] R37 = W'('h200000 + 37);
localparam [W-1:0] R38 = W'('h200000 + 38);
localparam [W-1:0] R39 = W'('h200000 + 39);
localparam [W-1:0] R40 = W'('h200000 + 40);
localparam [W-1:0] R41 = W'('h200000 + 41);
localparam [W-1:0] R42 = W'('h200000 + 42);
localparam [W-1:0] R43 = W'('h200000 + 43);
localparam [W-1:0] R44 = W'('h200000 + 44);
localparam [W-1:0] R45 = W'('h200000 + 45);
localparam [W-1:0] R46 = W'('h200000 + 46);
localparam [W-1:0] R47 = W'('h200000 + 47);
localparam [W-1:0] R48 = W'('h200000 + 48);
localparam [W-1:0] R49 = W'('h200000 + 49);
localparam [W-1:0] R50 = W'('h200000 + 50);
localparam [W-1:0] R51 = W'('h200000 + 51);
localparam [W-1:0] R52 = W'('h200000 + 52);
localparam [W-1:0] R53 = W'('h200000 + 53);
localparam [W-1:0] R54 = W'('h200000 + 54);
localparam [W-1:0] R55 = W'('h200000 + 55);
localparam [W-1:0] R56 = W'('h200000 + 56);
localparam [W-1:0] R57 = W'('h200000 + 57);
localparam [W-1:0] R58 = W'('h200000 + 58);
localparam [W-1:0] R59 = W'('h200000 + 59);
localparam [W-1:0] R60 = W'('h200000 + 60);
localparam [W-1:0] R61 = W'('h200000 + 61);
localparam [W-1:0] R62 = W'('h200000 + 62);
localparam [W-1:0] R63 = W'('h200000 + 63);
localparam [W-1:0] R64 = W'('h200000 + 64);
localparam [W-1:0] R65 = W'('h200000 + 65);
localparam [W-1:0] R66 = W'('h200000 + 66);
localparam [W-1:0] R67 = W'('h200000 + 67);
localparam [W-1:0] R68 = W'('h200000 + 68);
localparam [W-1:0] R69 = W'('h200000 + 69);
localparam [W-1:0] R70 = W'('h200000 + 70);
localparam [W-1:0] R71 = W'('h200000 + 71);
localparam [W-1:0] R72 = W'('h200000 + 72);
localparam [W-1:0] R73 = W'('h200000 + 73);
localparam [W-1:0] R74 = W'('h200000 + 74);
localparam [W-1:0] R75 = W'('h200000 + 75);
localparam [W-1:0] R76 = W'('h200000 + 76);
localparam [W-1:0] R77 = W'('h200000 + 77);
localparam [W-1:0] R78 = W'('h200000 + 78);
localparam [W-1:0] R79 = W'('h200000 + 79);
localparam [W-1:0] R80 = W'('h200000 + 80);
localparam [W-1:0] R81 = W'('h200000 + 81);
localparam [W-1:0] R82 = W'('h200000 + 82);
localparam [W-1:0] R83 = W'('h200000 + 83);
localparam [W-1:0] R84 = W'('h200000 + 84);
localparam [W-1:0] R85 = W'('h200000 + 85);
localparam [W-1:0] R86 = W'('h200000 + 86);
localparam [W-1:0] R87 = W'('h200000 + 87);
localparam [W-1:0] R88 = W'('h200000 + 88);
localparam [W-1:0] R89 = W'('h200000 + 89);
localparam [W-1:0] R90 = W'('h200000 + 90);
localparam [W-1:0] R91 = W'('h200000 + 91);
localparam [W-1:0] R92 = W'('h200000 + 92);
localparam [W-1:0] R93 = W'('h200000 + 93);
localparam [W-1:0] R94 = W'('h200000 + 94);
localparam [W-1:0] R95 = W'('h200000 + 95);
localparam [W-1:0] R96 = W'('h200000 + 96);
localparam [W-1:0] R97 = W'('h200000 + 97);
localparam [W-1:0] R98 = W'('h200000 + 98);
localparam [W-1:0] R99 = W'('h200000 + 99);
typedef struct packed {
logic r0;
logic r1;
logic r2;
logic r3;
logic r4;
logic r5;
logic r6;
logic r7;
logic r8;
logic r9;
logic r10;
logic r11;
logic r12;
logic r13;
logic r14;
logic r15;
logic r16;
logic r17;
logic r18;
logic r19;
logic r20;
logic r21;
logic r22;
logic r23;
logic r24;
logic r25;
logic r26;
logic r27;
logic r28;
logic r29;
logic r30;
logic r31;
logic r32;
logic r33;
logic r34;
logic r35;
logic r36;
logic r37;
logic r38;
logic r39;
logic r40;
logic r41;
logic r42;
logic r43;
logic r44;
logic r45;
logic r46;
logic r47;
logic r48;
logic r49;
logic r50;
logic r51;
logic r52;
logic r53;
logic r54;
logic r55;
logic r56;
logic r57;
logic r58;
logic r59;
logic r60;
logic r61;
logic r62;
logic r63;
logic r64;
logic r65;
logic r66;
logic r67;
logic r68;
logic r69;
logic r70;
logic r71;
logic r72;
logic r73;
logic r74;
logic r75;
logic r76;
logic r77;
logic r78;
logic r79;
logic r80;
logic r81;
logic r82;
logic r83;
logic r84;
logic r85;
logic r86;
logic r87;
logic r88;
logic r89;
logic r90;
logic r91;
logic r92;
logic r93;
logic r94;
logic r95;
logic r96;
logic r97;
logic r98;
logic r99;
} hit_t;
function automatic hit_t get_hit(input logic [22:0] a);
hit_t hit = '0;
unique case (a)
R0 : begin hit.r0 = 1'b1; end
R1 : begin hit.r1 = 1'b1; end
R2 : begin hit.r2 = 1'b1; end
R3 : begin hit.r3 = 1'b1; end
R4 : begin hit.r4 = 1'b1; end
R5 : begin hit.r5 = 1'b1; end
R6 : begin hit.r6 = 1'b1; end
R7 : begin hit.r7 = 1'b1; end
R8 : begin hit.r8 = 1'b1; end
R9 : begin hit.r9 = 1'b1; end
R10 : begin hit.r10 = 1'b1; end
R11 : begin hit.r11 = 1'b1; end
R12 : begin hit.r12 = 1'b1; end
R13 : begin hit.r13 = 1'b1; end
R14 : begin hit.r14 = 1'b1; end
R15 : begin hit.r15 = 1'b1; end
R16 : begin hit.r16 = 1'b1; end
R17 : begin hit.r17 = 1'b1; end
R18 : begin hit.r18 = 1'b1; end
R19 : begin hit.r19 = 1'b1; end
R20 : begin hit.r20 = 1'b1; end
R21 : begin hit.r21 = 1'b1; end
R22 : begin hit.r22 = 1'b1; end
R23 : begin hit.r23 = 1'b1; end
R24 : begin hit.r24 = 1'b1; end
R25 : begin hit.r25 = 1'b1; end
R26 : begin hit.r26 = 1'b1; end
R27 : begin hit.r27 = 1'b1; end
R28 : begin hit.r28 = 1'b1; end
R29 : begin hit.r29 = 1'b1; end
R30 : begin hit.r30 = 1'b1; end
R31 : begin hit.r31 = 1'b1; end
R32 : begin hit.r32 = 1'b1; end
R33 : begin hit.r33 = 1'b1; end
R34 : begin hit.r34 = 1'b1; end
R35 : begin hit.r35 = 1'b1; end
R36 : begin hit.r36 = 1'b1; end
R37 : begin hit.r37 = 1'b1; end
R38 : begin hit.r38 = 1'b1; end
R39 : begin hit.r39 = 1'b1; end
R40 : begin hit.r40 = 1'b1; end
R41 : begin hit.r41 = 1'b1; end
R42 : begin hit.r42 = 1'b1; end
R43 : begin hit.r43 = 1'b1; end
R44 : begin hit.r44 = 1'b1; end
R45 : begin hit.r45 = 1'b1; end
R46 : begin hit.r46 = 1'b1; end
R47 : begin hit.r47 = 1'b1; end
R48 : begin hit.r48 = 1'b1; end
R49 : begin hit.r49 = 1'b1; end
R50 : begin hit.r50 = 1'b1; end
R51 : begin hit.r51 = 1'b1; end
R52 : begin hit.r52 = 1'b1; end
R53 : begin hit.r53 = 1'b1; end
R54 : begin hit.r54 = 1'b1; end
R55 : begin hit.r55 = 1'b1; end
R56 : begin hit.r56 = 1'b1; end
R57 : begin hit.r57 = 1'b1; end
R58 : begin hit.r58 = 1'b1; end
R59 : begin hit.r59 = 1'b1; end
R60 : begin hit.r60 = 1'b1; end
R61 : begin hit.r61 = 1'b1; end
R62 : begin hit.r62 = 1'b1; end
R63 : begin hit.r63 = 1'b1; end
R64 : begin hit.r64 = 1'b1; end
R65 : begin hit.r65 = 1'b1; end
R66 : begin hit.r66 = 1'b1; end
R67 : begin hit.r67 = 1'b1; end
R68 : begin hit.r68 = 1'b1; end
R69 : begin hit.r69 = 1'b1; end
R70 : begin hit.r70 = 1'b1; end
R71 : begin hit.r71 = 1'b1; end
R72 : begin hit.r72 = 1'b1; end
R73 : begin hit.r73 = 1'b1; end
R74 : begin hit.r74 = 1'b1; end
R75 : begin hit.r75 = 1'b1; end
R76 : begin hit.r76 = 1'b1; end
R77 : begin hit.r77 = 1'b1; end
R78 : begin hit.r78 = 1'b1; end
R79 : begin hit.r79 = 1'b1; end
R80 : begin hit.r80 = 1'b1; end
R81 : begin hit.r81 = 1'b1; end
R82 : begin hit.r82 = 1'b1; end
R83 : begin hit.r83 = 1'b1; end
R84 : begin hit.r84 = 1'b1; end
R85 : begin hit.r85 = 1'b1; end
R86 : begin hit.r86 = 1'b1; end
R87 : begin hit.r87 = 1'b1; end
R88 : begin hit.r88 = 1'b1; end
R89 : begin hit.r89 = 1'b1; end
R90 : begin hit.r90 = 1'b1; end
R91 : begin hit.r91 = 1'b1; end
R92 : begin hit.r92 = 1'b1; end
R93 : begin hit.r93 = 1'b1; end
R94 : begin hit.r94 = 1'b1; end
R95 : begin hit.r95 = 1'b1; end
R96 : begin hit.r96 = 1'b1; end
R97 : begin hit.r97 = 1'b1; end
R98 : begin hit.r98 = 1'b1; end
R99 : begin hit.r99 = 1'b1; end
default: begin hit = '0; end
endcase
return hit;
endfunction
localparam [W-1:0] R0 = W'('h200000 + 0);
localparam [W-1:0] R1 = W'('h200000 + 1);
localparam [W-1:0] R2 = W'('h200000 + 2);
localparam [W-1:0] R3 = W'('h200000 + 3);
localparam [W-1:0] R4 = W'('h200000 + 4);
localparam [W-1:0] R5 = W'('h200000 + 5);
localparam [W-1:0] R6 = W'('h200000 + 6);
localparam [W-1:0] R7 = W'('h200000 + 7);
localparam [W-1:0] R8 = W'('h200000 + 8);
localparam [W-1:0] R9 = W'('h200000 + 9);
localparam [W-1:0] R10 = W'('h200000 + 10);
localparam [W-1:0] R11 = W'('h200000 + 11);
localparam [W-1:0] R12 = W'('h200000 + 12);
localparam [W-1:0] R13 = W'('h200000 + 13);
localparam [W-1:0] R14 = W'('h200000 + 14);
localparam [W-1:0] R15 = W'('h200000 + 15);
localparam [W-1:0] R16 = W'('h200000 + 16);
localparam [W-1:0] R17 = W'('h200000 + 17);
localparam [W-1:0] R18 = W'('h200000 + 18);
localparam [W-1:0] R19 = W'('h200000 + 19);
localparam [W-1:0] R20 = W'('h200000 + 20);
localparam [W-1:0] R21 = W'('h200000 + 21);
localparam [W-1:0] R22 = W'('h200000 + 22);
localparam [W-1:0] R23 = W'('h200000 + 23);
localparam [W-1:0] R24 = W'('h200000 + 24);
localparam [W-1:0] R25 = W'('h200000 + 25);
localparam [W-1:0] R26 = W'('h200000 + 26);
localparam [W-1:0] R27 = W'('h200000 + 27);
localparam [W-1:0] R28 = W'('h200000 + 28);
localparam [W-1:0] R29 = W'('h200000 + 29);
localparam [W-1:0] R30 = W'('h200000 + 30);
localparam [W-1:0] R31 = W'('h200000 + 31);
localparam [W-1:0] R32 = W'('h200000 + 32);
localparam [W-1:0] R33 = W'('h200000 + 33);
localparam [W-1:0] R34 = W'('h200000 + 34);
localparam [W-1:0] R35 = W'('h200000 + 35);
localparam [W-1:0] R36 = W'('h200000 + 36);
localparam [W-1:0] R37 = W'('h200000 + 37);
localparam [W-1:0] R38 = W'('h200000 + 38);
localparam [W-1:0] R39 = W'('h200000 + 39);
localparam [W-1:0] R40 = W'('h200000 + 40);
localparam [W-1:0] R41 = W'('h200000 + 41);
localparam [W-1:0] R42 = W'('h200000 + 42);
localparam [W-1:0] R43 = W'('h200000 + 43);
localparam [W-1:0] R44 = W'('h200000 + 44);
localparam [W-1:0] R45 = W'('h200000 + 45);
localparam [W-1:0] R46 = W'('h200000 + 46);
localparam [W-1:0] R47 = W'('h200000 + 47);
localparam [W-1:0] R48 = W'('h200000 + 48);
localparam [W-1:0] R49 = W'('h200000 + 49);
localparam [W-1:0] R50 = W'('h200000 + 50);
localparam [W-1:0] R51 = W'('h200000 + 51);
localparam [W-1:0] R52 = W'('h200000 + 52);
localparam [W-1:0] R53 = W'('h200000 + 53);
localparam [W-1:0] R54 = W'('h200000 + 54);
localparam [W-1:0] R55 = W'('h200000 + 55);
localparam [W-1:0] R56 = W'('h200000 + 56);
localparam [W-1:0] R57 = W'('h200000 + 57);
localparam [W-1:0] R58 = W'('h200000 + 58);
localparam [W-1:0] R59 = W'('h200000 + 59);
localparam [W-1:0] R60 = W'('h200000 + 60);
localparam [W-1:0] R61 = W'('h200000 + 61);
localparam [W-1:0] R62 = W'('h200000 + 62);
localparam [W-1:0] R63 = W'('h200000 + 63);
localparam [W-1:0] R64 = W'('h200000 + 64);
localparam [W-1:0] R65 = W'('h200000 + 65);
localparam [W-1:0] R66 = W'('h200000 + 66);
localparam [W-1:0] R67 = W'('h200000 + 67);
localparam [W-1:0] R68 = W'('h200000 + 68);
localparam [W-1:0] R69 = W'('h200000 + 69);
localparam [W-1:0] R70 = W'('h200000 + 70);
localparam [W-1:0] R71 = W'('h200000 + 71);
localparam [W-1:0] R72 = W'('h200000 + 72);
localparam [W-1:0] R73 = W'('h200000 + 73);
localparam [W-1:0] R74 = W'('h200000 + 74);
localparam [W-1:0] R75 = W'('h200000 + 75);
localparam [W-1:0] R76 = W'('h200000 + 76);
localparam [W-1:0] R77 = W'('h200000 + 77);
localparam [W-1:0] R78 = W'('h200000 + 78);
localparam [W-1:0] R79 = W'('h200000 + 79);
localparam [W-1:0] R80 = W'('h200000 + 80);
localparam [W-1:0] R81 = W'('h200000 + 81);
localparam [W-1:0] R82 = W'('h200000 + 82);
localparam [W-1:0] R83 = W'('h200000 + 83);
localparam [W-1:0] R84 = W'('h200000 + 84);
localparam [W-1:0] R85 = W'('h200000 + 85);
localparam [W-1:0] R86 = W'('h200000 + 86);
localparam [W-1:0] R87 = W'('h200000 + 87);
localparam [W-1:0] R88 = W'('h200000 + 88);
localparam [W-1:0] R89 = W'('h200000 + 89);
localparam [W-1:0] R90 = W'('h200000 + 90);
localparam [W-1:0] R91 = W'('h200000 + 91);
localparam [W-1:0] R92 = W'('h200000 + 92);
localparam [W-1:0] R93 = W'('h200000 + 93);
localparam [W-1:0] R94 = W'('h200000 + 94);
localparam [W-1:0] R95 = W'('h200000 + 95);
localparam [W-1:0] R96 = W'('h200000 + 96);
localparam [W-1:0] R97 = W'('h200000 + 97);
localparam [W-1:0] R98 = W'('h200000 + 98);
localparam [W-1:0] R99 = W'('h200000 + 99);
typedef struct packed {
logic r0;
logic r1;
logic r2;
logic r3;
logic r4;
logic r5;
logic r6;
logic r7;
logic r8;
logic r9;
logic r10;
logic r11;
logic r12;
logic r13;
logic r14;
logic r15;
logic r16;
logic r17;
logic r18;
logic r19;
logic r20;
logic r21;
logic r22;
logic r23;
logic r24;
logic r25;
logic r26;
logic r27;
logic r28;
logic r29;
logic r30;
logic r31;
logic r32;
logic r33;
logic r34;
logic r35;
logic r36;
logic r37;
logic r38;
logic r39;
logic r40;
logic r41;
logic r42;
logic r43;
logic r44;
logic r45;
logic r46;
logic r47;
logic r48;
logic r49;
logic r50;
logic r51;
logic r52;
logic r53;
logic r54;
logic r55;
logic r56;
logic r57;
logic r58;
logic r59;
logic r60;
logic r61;
logic r62;
logic r63;
logic r64;
logic r65;
logic r66;
logic r67;
logic r68;
logic r69;
logic r70;
logic r71;
logic r72;
logic r73;
logic r74;
logic r75;
logic r76;
logic r77;
logic r78;
logic r79;
logic r80;
logic r81;
logic r82;
logic r83;
logic r84;
logic r85;
logic r86;
logic r87;
logic r88;
logic r89;
logic r90;
logic r91;
logic r92;
logic r93;
logic r94;
logic r95;
logic r96;
logic r97;
logic r98;
logic r99;
} hit_t;
function automatic hit_t get_hit(input logic [22:0] a);
hit_t hit = '0;
unique case (a)
R0: hit.r0 = 1'b1;
R1: hit.r1 = 1'b1;
R2: hit.r2 = 1'b1;
R3: hit.r3 = 1'b1;
R4: hit.r4 = 1'b1;
R5: hit.r5 = 1'b1;
R6: hit.r6 = 1'b1;
R7: hit.r7 = 1'b1;
R8: hit.r8 = 1'b1;
R9: hit.r9 = 1'b1;
R10: hit.r10 = 1'b1;
R11: hit.r11 = 1'b1;
R12: hit.r12 = 1'b1;
R13: hit.r13 = 1'b1;
R14: hit.r14 = 1'b1;
R15: hit.r15 = 1'b1;
R16: hit.r16 = 1'b1;
R17: hit.r17 = 1'b1;
R18: hit.r18 = 1'b1;
R19: hit.r19 = 1'b1;
R20: hit.r20 = 1'b1;
R21: hit.r21 = 1'b1;
R22: hit.r22 = 1'b1;
R23: hit.r23 = 1'b1;
R24: hit.r24 = 1'b1;
R25: hit.r25 = 1'b1;
R26: hit.r26 = 1'b1;
R27: hit.r27 = 1'b1;
R28: hit.r28 = 1'b1;
R29: hit.r29 = 1'b1;
R30: hit.r30 = 1'b1;
R31: hit.r31 = 1'b1;
R32: hit.r32 = 1'b1;
R33: hit.r33 = 1'b1;
R34: hit.r34 = 1'b1;
R35: hit.r35 = 1'b1;
R36: hit.r36 = 1'b1;
R37: hit.r37 = 1'b1;
R38: hit.r38 = 1'b1;
R39: hit.r39 = 1'b1;
R40: hit.r40 = 1'b1;
R41: hit.r41 = 1'b1;
R42: hit.r42 = 1'b1;
R43: hit.r43 = 1'b1;
R44: hit.r44 = 1'b1;
R45: hit.r45 = 1'b1;
R46: hit.r46 = 1'b1;
R47: hit.r47 = 1'b1;
R48: hit.r48 = 1'b1;
R49: hit.r49 = 1'b1;
R50: hit.r50 = 1'b1;
R51: hit.r51 = 1'b1;
R52: hit.r52 = 1'b1;
R53: hit.r53 = 1'b1;
R54: hit.r54 = 1'b1;
R55: hit.r55 = 1'b1;
R56: hit.r56 = 1'b1;
R57: hit.r57 = 1'b1;
R58: hit.r58 = 1'b1;
R59: hit.r59 = 1'b1;
R60: hit.r60 = 1'b1;
R61: hit.r61 = 1'b1;
R62: hit.r62 = 1'b1;
R63: hit.r63 = 1'b1;
R64: hit.r64 = 1'b1;
R65: hit.r65 = 1'b1;
R66: hit.r66 = 1'b1;
R67: hit.r67 = 1'b1;
R68: hit.r68 = 1'b1;
R69: hit.r69 = 1'b1;
R70: hit.r70 = 1'b1;
R71: hit.r71 = 1'b1;
R72: hit.r72 = 1'b1;
R73: hit.r73 = 1'b1;
R74: hit.r74 = 1'b1;
R75: hit.r75 = 1'b1;
R76: hit.r76 = 1'b1;
R77: hit.r77 = 1'b1;
R78: hit.r78 = 1'b1;
R79: hit.r79 = 1'b1;
R80: hit.r80 = 1'b1;
R81: hit.r81 = 1'b1;
R82: hit.r82 = 1'b1;
R83: hit.r83 = 1'b1;
R84: hit.r84 = 1'b1;
R85: hit.r85 = 1'b1;
R86: hit.r86 = 1'b1;
R87: hit.r87 = 1'b1;
R88: hit.r88 = 1'b1;
R89: hit.r89 = 1'b1;
R90: hit.r90 = 1'b1;
R91: hit.r91 = 1'b1;
R92: hit.r92 = 1'b1;
R93: hit.r93 = 1'b1;
R94: hit.r94 = 1'b1;
R95: hit.r95 = 1'b1;
R96: hit.r96 = 1'b1;
R97: hit.r97 = 1'b1;
R98: hit.r98 = 1'b1;
R99: hit.r99 = 1'b1;
default: hit = '0;
endcase
return hit;
endfunction
initial begin
if (get_hit(R30) !== hit_t'{r30: 1'b1, default: '0}) $stop;
if (get_hit('1) !== '0) $stop;
if (get_hit('0) !== '0) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
initial begin
if (get_hit(R30) !== hit_t'{r30: 1'b1, default: '0}) $stop;
if (get_hit('1) !== '0) $stop;
if (get_hit('0) !== '0) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile()
test.execute()
test.passes()

View File

@ -0,0 +1,26 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
class Class1 #(type T);
static function int get();
return T::Helper::getter();
endfunction
endclass
class Class2;
typedef Class2 Helper;
static function int getter();
return 13;
endfunction
endclass
module t;
initial begin
if (Class1#(Class2)::get() != 13) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile()
test.passes()

View File

@ -0,0 +1,17 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
class setup_coefficients;
static function int create();
return 1;
endfunction
endclass
class biquad_vseq;
int c_setup = setup_coefficients::create();
function void setup_coefficients();
endfunction
endclass: biquad_vseq

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile(verilator_flags2=['--coverage-expr'])
test.execute()
test.passes()

View File

@ -0,0 +1,26 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
class Class1;
int value0 = 7;
endclass
module t;
initial begin
int i = 0;
Class1 q[15];
for (int j = 0; j < 15; j = j + 1) begin
Class1 x = new;
q[j] = x;
end
while (i < 15) begin
if ((q[i].value0 > 8) || (q[i].value0 < 5)) $stop;
i += 1;
end
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile(verilator_flags2=['--coverage-expr'])
test.execute()
test.passes()

View File

@ -0,0 +1,26 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
class Class1;
int value0 = 7;
endclass
module t;
initial begin
int i = 0;
Class1 q[int] = '{};
for (int j = 0; j < 15; j = j + 1) begin
Class1 x = new;
q[j] = x;
end
while (i < 15) begin
if ((q[i].value0 > 8) || (q[i].value0 < 5)) $stop;
i += 1;
end
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile(verilator_flags2=['--coverage-expr'])
test.execute()
test.passes()

View File

@ -0,0 +1,26 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
class Class1;
int value0 = 7;
endclass
module t;
initial begin
int i = 0;
Class1 q[] = new [15];
for (int j = 0; j < 15; j = j + 1) begin
Class1 x = new;
q[j] = x;
end
while (i < 15) begin
if ((q[i].value0 > 8) || (q[i].value0 < 5)) $stop;
i += 1;
end
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile(verilator_flags2=['--coverage-expr'])
test.execute()
test.passes()

View File

@ -0,0 +1,26 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
class Class1;
int value0 = 7;
endclass
module t;
initial begin
int i = 0;
Class1 q[$];
repeat(15) begin
Class1 x = new;
q = { q, x };
end
while (i < q.size()) begin
if ((q[i].value0 > 8) || (q[i].value0 < 5)) $stop;
i += 1;
end
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -45,6 +45,15 @@
} str_queue_t;
str_queue_t str_queue;
typedef struct packed {
// verilator lint_off ASCRANGE
bit [3:5] x;
// verilator lint_on ASCRANGE
bit [0:0] y;
} str_bit_t;
%000002 str_bit_t str_bit;
%000002 str_bit_t [5:2] str_bit_arr;
alpha a1 (/*AUTOINST*/
// Outputs
.toggle_up (toggle_up),
@ -97,10 +106,16 @@
if (cyc == 3) begin
str_queue.q.push_back(1);
toggle <= '1;
str_bit.x <= '1;
str_bit.y <= '1;
str_bit_arr[4].x <= '1;
end
if (cyc == 4) begin
if (str_queue.q.size() != 1) $stop;
toggle <= '0;
str_bit.x[3] <= 0;
str_bit.y[0] <= 0;
str_bit_arr[4].x[3] <= 0;
end
else if (cyc == 10) begin
$write("*-* All Finished *-*\n");

View File

@ -21,7 +21,7 @@ test.inline_checks()
test.file_grep_not(test.obj_dir + "/coverage.dat", "largeish")
if test.vlt_all:
test.file_grep(test.stats, r'Coverage, Toggle points joined\s+(\d+)', 27)
test.file_grep(test.stats, r'Coverage, Toggle points joined\s+(\d+)', 13)
test.run(cmd=[
os.environ["VERILATOR_ROOT"] + "/bin/verilator_coverage",

View File

@ -44,6 +44,15 @@ module t (/*AUTOARG*/
} str_queue_t;
str_queue_t str_queue;
typedef struct packed {
// verilator lint_off ASCRANGE
bit [3:5] x;
// verilator lint_on ASCRANGE
bit [0:0] y;
} str_bit_t;
str_bit_t str_bit;
str_bit_t [5:2] str_bit_arr;
alpha a1 (/*AUTOINST*/
// Outputs
.toggle_up (toggle_up),
@ -96,10 +105,16 @@ module t (/*AUTOARG*/
if (cyc == 3) begin
str_queue.q.push_back(1);
toggle <= '1;
str_bit.x <= '1;
str_bit.y <= '1;
str_bit_arr[4].x <= '1;
end
if (cyc == 4) begin
if (str_queue.q.size() != 1) $stop;
toggle <= '0;
str_bit.x[3] <= 0;
str_bit.y[0] <= 0;
str_bit_arr[4].x[3] <= 0;
end
else if (cyc == 10) begin
$write("*-* All Finished *-*\n");

View File

@ -62,6 +62,35 @@
} str_queue_t;
str_queue_t str_queue;
typedef struct packed {
// verilator lint_off ASCRANGE
bit [3:5] x;
// verilator lint_on ASCRANGE
bit [0:0] y;
} str_bit_t;
%000002 str_bit_t str_bit;
-000002 point: comment=str_bit.x[3] hier=top.t
-000001 point: comment=str_bit.x[4] hier=top.t
-000001 point: comment=str_bit.x[5] hier=top.t
-000002 point: comment=str_bit.y[0] hier=top.t
%000002 str_bit_t [5:2] str_bit_arr;
-000000 point: comment=str_bit_arr[2].x[3] hier=top.t
-000000 point: comment=str_bit_arr[2].x[4] hier=top.t
-000000 point: comment=str_bit_arr[2].x[5] hier=top.t
-000000 point: comment=str_bit_arr[2].y[0] hier=top.t
-000000 point: comment=str_bit_arr[3].x[3] hier=top.t
-000000 point: comment=str_bit_arr[3].x[4] hier=top.t
-000000 point: comment=str_bit_arr[3].x[5] hier=top.t
-000000 point: comment=str_bit_arr[3].y[0] hier=top.t
-000002 point: comment=str_bit_arr[4].x[3] hier=top.t
-000001 point: comment=str_bit_arr[4].x[4] hier=top.t
-000001 point: comment=str_bit_arr[4].x[5] hier=top.t
-000000 point: comment=str_bit_arr[4].y[0] hier=top.t
-000000 point: comment=str_bit_arr[5].x[3] hier=top.t
-000000 point: comment=str_bit_arr[5].x[4] hier=top.t
-000000 point: comment=str_bit_arr[5].x[5] hier=top.t
-000000 point: comment=str_bit_arr[5].y[0] hier=top.t
alpha a1 (/*AUTOINST*/
// Outputs
.toggle_up (toggle_up),
@ -138,10 +167,16 @@
if (cyc == 3) begin
str_queue.q.push_back(1);
toggle <= '1;
str_bit.x <= '1;
str_bit.y <= '1;
str_bit_arr[4].x <= '1;
end
if (cyc == 4) begin
if (str_queue.q.size() != 1) $stop;
toggle <= '0;
str_bit.x[3] <= 0;
str_bit.y[0] <= 0;
str_bit_arr[4].x[3] <= 0;
end
else if (cyc == 10) begin
$write("*-* All Finished *-*\n");

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile()
test.passes()

View File

@ -0,0 +1,19 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
/* verilator lint_off COVERIGN */
module t;
covergroup cgArgs(int var1, int var2=42);
endgroup
cgArgs cov1 = new(69, 77);
cgArgs cov2 = new(69);
function x();
cov1.sample();
cov2.get_coverage();
endfunction;
endmodule

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile()
test.passes()

View File

@ -0,0 +1,39 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
/* verilator lint_off COVERIGN */
module t;
class base;
enum {red, green, blue} color;
covergroup g1 (bit [3:0] a) with function sample(bit b);
option.weight = 10;
option.per_instance = 1;
coverpoint a;
coverpoint b;
c: coverpoint color;
endgroup
function new();
g1 = new(0);
endfunction
endclass
class derived extends base;
bit d;
covergroup extends g1;
option.weight = 1; // overrides the weight from base g1
// uses per_instance = 1 from base g1
c: coverpoint color // overrides the c coverpoint in base g1
{
ignore_bins ignore = {blue};
}
coverpoint d; // adds new coverpoint
cross a, d; // crosses new coverpoint with inherited one
endgroup :g1
function new();
super.new();
endfunction
endclass
endmodule

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile()
test.passes()

View File

@ -0,0 +1,39 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
/* verilator lint_off COVERIGN */
module t;
class base;
function new();
g1 = new(0);
endfunction
enum {red, green, blue} color;
covergroup g1 (bit [3:0] a) with function sample(bit b);
option.weight = 10;
option.per_instance = 1;
coverpoint a;
coverpoint b;
c: coverpoint color;
endgroup
endclass
class derived extends base;
bit d;
function new();
super.new();
endfunction
covergroup extends g1;
option.weight = 1; // overrides the weight from base g1
// uses per_instance = 1 from base g1
c: coverpoint color // overrides the c coverpoint in base g1
{
ignore_bins ignore = {blue};
}
coverpoint d; // adds new coverpoint
cross a, d; // crosses new coverpoint with inherited one
endgroup :g1
endclass
endmodule

View File

@ -0,0 +1,5 @@
%Error: t/t_covergroup_func_override_bad.v:10:5: syntax error, unexpected function
10 | function sample();
| ^~~~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
if test.vlt_all:
test.lint(fails=True, expect_filename=test.golden_filename)
else:
test.compile(nc_flags2=["-coverage", "functional"])
test.execute()
test.passes()

View File

@ -0,0 +1,17 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
/* verilator lint_off COVERIGN */
module t();
covergroup cg;
function sample();
endfunction
function get_coverage();
endfunction
endgroup
endmodule

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile()
test.passes()

View File

@ -0,0 +1,18 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
/* verilator lint_off COVERIGN */
class myClass;
covergroup embeddedCg;
endgroup
function new();
embeddedCg = new();
embeddedCg.sample();
embeddedCg.get_coverage();
endfunction
endclass

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile()
test.passes()

View File

@ -0,0 +1,30 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
/* verilator lint_off COVERIGN */
class myClass;
covergroup embeddedCg;
endgroup
function new();
embeddedCg = new();
embeddedCg.sample();
embeddedCg.get_coverage();
endfunction
endclass
class secondClass;
covergroup embeddedCg;
endgroup
function new();
embeddedCg = new();
embeddedCg.sample();
embeddedCg.get_coverage();
endfunction
endclass

View File

@ -0,0 +1,8 @@
%Error: t/t_covergroup_in_class_duplicate_bad.v:13:16: Duplicate declaration of CLASS '__vlAnonCG_embeddedCg': '__vlAnonCG_embeddedCg'
13 | covergroup embeddedCg;
| ^~~~~~~~~~
t/t_covergroup_in_class_duplicate_bad.v:9:16: ... Location of original declaration
9 | covergroup embeddedCg;
| ^~~~~~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile(fails=True, expect_filename=test.golden_filename)
test.passes()

View File

@ -0,0 +1,16 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
/* verilator lint_off COVERIGN */
class myClass;
covergroup embeddedCg;
endgroup
covergroup embeddedCg;
endgroup
endclass

View File

@ -0,0 +1,5 @@
%Error: t/t_covergroup_new_override_bad.v:10:5: syntax error, unexpected function
10 | function new();
| ^~~~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
if test.vlt_all:
test.lint(fails=True, expect_filename=test.golden_filename)
else:
test.compile(nc_flags2=["-coverage", "functional"])
test.execute()
test.passes()

View File

@ -0,0 +1,14 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
/* verilator lint_off COVERIGN */
module t();
covergroup cg;
function new();
endfunction
endgroup
endmodule

View File

@ -385,28 +385,21 @@
136 | cross a, b {
| ^~~~~
%Warning-COVERIGN: t/t_covergroup_unsup.v:154:4: Ignoring unsupported: covergroup
154 | covergroup cg_more extends cg_empty;
154 | covergroup cgArgs(int cg_lim);
| ^~~~~~~~~~
%Warning-COVERIGN: t/t_covergroup_unsup.v:157:4: Ignoring unsupported: covergroup
157 | covergroup cg_args(int cg_lim);
| ^~~~~~~~~~
%Warning-COVERIGN: t/t_covergroup_unsup.v:164:7: Ignoring unsupported: covergroup
164 | covergroup cov1 @m_z;
%Warning-COVERIGN: t/t_covergroup_unsup.v:161:7: Ignoring unsupported: covergroup
161 | covergroup cov1 @m_z;
| ^~~~~~~~~~
%Warning-COVERIGN: t/t_covergroup_unsup.v:164:23: Ignoring unsupported: coverage clocking event
164 | covergroup cov1 @m_z;
%Warning-COVERIGN: t/t_covergroup_unsup.v:161:23: Ignoring unsupported: coverage clocking event
161 | covergroup cov1 @m_z;
| ^
%Warning-COVERIGN: t/t_covergroup_unsup.v:165:10: Ignoring unsupported: coverpoint
165 | coverpoint m_x;
%Warning-COVERIGN: t/t_covergroup_unsup.v:162:10: Ignoring unsupported: coverpoint
162 | coverpoint m_x;
| ^~~~~~~~~~
%Warning-COVERIGN: t/t_covergroup_unsup.v:166:10: Ignoring unsupported: coverpoint
166 | coverpoint m_y;
%Warning-COVERIGN: t/t_covergroup_unsup.v:163:10: Ignoring unsupported: coverpoint
163 | coverpoint m_y;
| ^~~~~~~~~~
%Warning-COVERIGN: t/t_covergroup_unsup.v:164:18: Ignoring unsupported: covergroup within class
164 | covergroup cov1 @m_z;
| ^~~~
%Error: t/t_covergroup_unsup.v:169:23: Can't find definition of variable: 'cov1'
169 | function new(); cov1 = new; endfunction
| ^~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Warning-COVERIGN: t/t_covergroup_unsup.v:171:7: Ignoring unsupported: covergroup
171 | covergroup extends cg_empty;
| ^~~~~~~~~~
%Error: Exiting due to

View File

@ -151,10 +151,7 @@ module t (/*AUTOARG*/
}
endgroup
covergroup cg_more extends cg_empty;
endgroup
covergroup cg_args(int cg_lim);
covergroup cgArgs(int cg_lim);
endgroup
class CgCls;
@ -170,10 +167,15 @@ module t (/*AUTOARG*/
`endif
endclass
class CgEmb;
covergroup extends cg_empty;
endgroup
endclass
always @(posedge clk) begin
cg_more cov1 = new;
cg_empty cov1 = new;
`ifndef T_COVERGROUP_UNSUP_IGN
cg_args cov2 = new(2);
cgArgs cov2 = new(2);
`endif
if (cyc == 10) begin
$write("*-* All Finished *-*\n");

View File

@ -74,6 +74,8 @@ module Vt_debug_emitv_t;
if (the_ifaces[2].ifsig) begin
$write("");
end
#64'h1;
$write("After #1 delay");
end
end
bit [6:5] [4:3] [2:1] arraymanyd[10:11][12:13][14:15];

View File

@ -14,7 +14,7 @@ test.scenarios("vlt")
test.lint(
# We also have dump-tree turned on, so hit a lot of AstNode*::dump() functions
# Likewise XML
v_flags=["--lint-only --dumpi-tree 9 --dumpi-V3EmitV 9 --debug-emitv"])
v_flags=["--lint-only --dumpi-tree 9 --dumpi-V3EmitV 9 --debug-emitv --timing"])
output_vs = test.glob_some(test.obj_dir + "/" + test.vm_prefix + "_*_width.tree.v")

View File

@ -86,6 +86,7 @@ module t (/*AUTOARG*/
if (|downto_32[55+:3]) $write("");
if (|downto_32[60-:7]) $write("");
if (the_ifaces[2].ifsig) $write("");
#1 $write("After #1 delay");
end
bit [6:5][4:3][2:1] arraymanyd[10:11][12:13][14:15];

Some files were not shown because too many files have changed in this diff Show More