2012-04-13 03:08:20 +02:00
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
2006-08-26 13:35:28 +02:00
|
|
|
//*************************************************************************
|
|
|
|
|
// DESCRIPTION: Verilator: Error handling
|
|
|
|
|
//
|
2019-11-08 04:33:59 +01:00
|
|
|
// Code available from: https://verilator.org
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
//
|
2022-01-01 14:26:40 +01:00
|
|
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
2020-03-21 16:24:24 +01:00
|
|
|
// can redistribute it and/or modify it under the terms of either the GNU
|
2009-05-04 23:07:57 +02:00
|
|
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
|
|
|
|
// Version 2.0.
|
2020-03-21 16:24:24 +01:00
|
|
|
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
2019-10-05 02:17:11 +02:00
|
|
|
|
2021-03-04 03:57:07 +01:00
|
|
|
#ifndef VERILATOR_V3ERROR_H_
|
|
|
|
|
#define VERILATOR_V3ERROR_H_
|
2018-10-14 19:43:24 +02:00
|
|
|
|
2006-12-18 20:20:45 +01:00
|
|
|
#include "config_build.h"
|
|
|
|
|
#include "verilatedos.h"
|
2018-10-14 19:43:24 +02:00
|
|
|
|
2019-10-03 03:38:06 +02:00
|
|
|
// Limited V3 headers here - this is a base class for Vlc etc
|
|
|
|
|
#include "V3String.h"
|
|
|
|
|
|
2020-11-16 13:31:12 +01:00
|
|
|
#include <array>
|
2006-08-26 13:35:28 +02:00
|
|
|
#include <bitset>
|
2018-10-14 19:43:24 +02:00
|
|
|
#include <cassert>
|
2022-09-18 21:53:42 +02:00
|
|
|
#include <cctype>
|
2018-10-14 19:43:24 +02:00
|
|
|
#include <deque>
|
2011-10-11 13:07:24 +02:00
|
|
|
#include <map>
|
2012-05-22 03:31:52 +02:00
|
|
|
#include <set>
|
2018-10-14 19:43:24 +02:00
|
|
|
#include <sstream>
|
2006-08-26 13:35:28 +02:00
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class V3ErrorCode final {
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
// clang-format off
|
2020-08-16 18:05:35 +02:00
|
|
|
enum en: uint8_t {
|
2019-05-19 22:13:13 +02:00
|
|
|
EC_MIN=0, // Keep first
|
|
|
|
|
//
|
|
|
|
|
EC_INFO, // General information out
|
|
|
|
|
EC_FATAL, // Kill the program
|
2020-03-15 13:09:51 +01:00
|
|
|
EC_FATALEXIT, // Kill the program, suppress with --quiet-exit
|
2019-05-19 22:13:13 +02:00
|
|
|
EC_FATALSRC, // Kill the program, for internal source errors
|
|
|
|
|
EC_ERROR, // General error out, can't suppress
|
2021-04-18 16:16:18 +02:00
|
|
|
EC_FIRST_NAMED, // Just a code so the program knows where to start info/errors
|
2019-05-19 22:13:13 +02:00
|
|
|
// Boolean information we track per-line, but aren't errors
|
2020-06-07 17:58:53 +02:00
|
|
|
I_CELLDEFINE, // Inside cell define from `celldefine/`endcelldefine
|
2019-05-19 22:13:13 +02:00
|
|
|
I_COVERAGE, // Coverage is on/off from /*verilator coverage_on/off*/
|
|
|
|
|
I_TRACING, // Tracing is on/off from /*verilator tracing_on/off*/
|
|
|
|
|
I_LINT, // All lint messages
|
|
|
|
|
I_DEF_NETTYPE_WIRE, // `default_nettype is WIRE (false=NONE)
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
I_TIMING, // Enable timing from /*verilator timing_on/off*/
|
2019-05-19 22:13:13 +02:00
|
|
|
// Error codes:
|
|
|
|
|
E_DETECTARRAY, // Error: Unsupported: Can't detect changes on arrayed variable
|
2020-11-25 13:03:01 +01:00
|
|
|
E_ENCAPSULATED, // Error: local/protected violation
|
2019-02-28 03:06:07 +01:00
|
|
|
E_PORTSHORT, // Error: Output port is connected to a constant, electrical short
|
2020-06-10 01:20:16 +02:00
|
|
|
E_UNSUPPORTED, // Error: Unsupported (generally)
|
2019-02-28 03:06:07 +01:00
|
|
|
E_TASKNSVAR, // Error: Task I/O not simple
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
E_NEEDTIMINGOPT, // Error: --timing/--no-timing option not specified
|
|
|
|
|
E_NOTIMING, // Timing control encountered with --no-timing
|
2019-05-19 22:13:13 +02:00
|
|
|
//
|
|
|
|
|
// Warning codes:
|
|
|
|
|
EC_FIRST_WARN, // Just a code so the program knows where to start warnings
|
|
|
|
|
//
|
|
|
|
|
ALWCOMBORDER, // Always_comb with unordered statements
|
|
|
|
|
ASSIGNDLY, // Assignment delays
|
|
|
|
|
ASSIGNIN, // Assigning to input
|
2021-04-27 00:16:24 +02:00
|
|
|
BADSTDPRAGMA, // Any error related to pragmas
|
2019-05-19 22:13:13 +02:00
|
|
|
BLKANDNBLK, // Blocked and non-blocking assignments to same variable
|
|
|
|
|
BLKLOOPINIT, // Delayed assignment to array inside for loops
|
|
|
|
|
BLKSEQ, // Blocking assignments in sequential block
|
|
|
|
|
BSSPACE, // Backslash space
|
|
|
|
|
CASEINCOMPLETE, // Case statement has missing values
|
|
|
|
|
CASEOVERLAP, // Case statements overlap
|
|
|
|
|
CASEWITHX, // Case with X values
|
|
|
|
|
CASEX, // Casex
|
2020-12-06 04:58:36 +01:00
|
|
|
CASTCONST, // Cast is constant
|
2019-05-19 22:13:13 +02:00
|
|
|
CDCRSTLOGIC, // Logic in async reset path
|
2022-05-15 17:03:32 +02:00
|
|
|
CLKDATA, // Clock used as data. Historical, never issued.
|
2019-05-19 22:13:13 +02:00
|
|
|
CMPCONST, // Comparison is constant due to limited range
|
|
|
|
|
COLONPLUS, // :+ instead of +:
|
2018-11-26 23:58:18 +01:00
|
|
|
COMBDLY, // Combinatorial delayed assignment
|
2018-12-01 16:12:10 +01:00
|
|
|
CONTASSREG, // Continuous assignment on reg
|
2018-11-26 23:58:18 +01:00
|
|
|
DEFPARAM, // Style: Defparam
|
|
|
|
|
DECLFILENAME, // Declaration doesn't match filename
|
2020-01-03 17:27:51 +01:00
|
|
|
DEPRECATED, // Feature will be deprecated
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
RISEFALLDLY, // Unsupported: rise/fall/turn-off delays
|
|
|
|
|
MINTYPMAXDLY, // Unsupported: min/typ/max delay expressions
|
2019-05-19 22:13:13 +02:00
|
|
|
ENDLABEL, // End lable name mismatch
|
2021-03-15 02:23:48 +01:00
|
|
|
EOFNEWLINE, // End-of-file missing newline
|
2022-05-15 17:03:32 +02:00
|
|
|
GENCLK, // Generated Clock. Historical, never issued.
|
2020-08-15 15:43:53 +02:00
|
|
|
HIERBLOCK, // Ignored hierarchical block setting
|
2019-05-19 22:13:13 +02:00
|
|
|
IFDEPTH, // If statements too deep
|
2019-09-09 13:50:21 +02:00
|
|
|
IGNOREDRETURN, // Ignoring return value (function as task)
|
2022-05-15 17:03:32 +02:00
|
|
|
IMPERFECTSCH, // Imperfect schedule (disabled by default). Historical, never issued.
|
2018-11-29 00:25:34 +01:00
|
|
|
IMPLICIT, // Implicit wire
|
|
|
|
|
IMPORTSTAR, // Import::* in $unit
|
|
|
|
|
IMPURE, // Impure function not being inlined
|
2019-05-19 22:13:13 +02:00
|
|
|
INCABSPATH, // Include has absolute path
|
2017-12-27 03:35:08 +01:00
|
|
|
INFINITELOOP, // Infinite loop
|
2019-05-19 22:13:13 +02:00
|
|
|
INITIALDLY, // Initial delayed statement
|
2019-10-06 19:24:21 +02:00
|
|
|
INSECURE, // Insecure options
|
2021-01-05 20:26:01 +01:00
|
|
|
LATCH, // Latch detected outside of always_latch block
|
2019-05-19 22:13:13 +02:00
|
|
|
LITENDIAN, // Little bit endian vector
|
|
|
|
|
MODDUP, // Duplicate module
|
|
|
|
|
MULTIDRIVEN, // Driven from multiple blocks
|
2019-06-30 22:46:48 +02:00
|
|
|
MULTITOP, // Multiple top level modules
|
2021-01-05 20:26:01 +01:00
|
|
|
NOLATCH, // No latch detected in always_latch block
|
2021-04-09 16:39:46 +02:00
|
|
|
NULLPORT, // Null port detected in module definition
|
2021-04-02 00:17:42 +02:00
|
|
|
PINCONNECTEMPTY,// Cell pin connected by name with empty reference
|
2019-05-19 22:13:13 +02:00
|
|
|
PINMISSING, // Cell pin not specified
|
|
|
|
|
PINNOCONNECT, // Cell pin not connected
|
2021-04-02 00:17:42 +02:00
|
|
|
PINNOTFOUND, // instance port name not found in it's module
|
2020-08-23 01:42:21 +02:00
|
|
|
PKGNODECL, // Error: Package/class needs to be predeclared
|
2018-11-26 23:58:18 +01:00
|
|
|
PROCASSWIRE, // Procedural assignment on wire
|
2021-09-27 04:51:11 +02:00
|
|
|
PROFOUTOFDATE, // Profile data out of date
|
2021-04-27 00:16:24 +02:00
|
|
|
PROTECTED, // detected `pragma protected
|
2020-12-10 01:17:30 +01:00
|
|
|
RANDC, // Unsupported: 'randc' converted to 'rand'
|
2018-11-26 23:58:18 +01:00
|
|
|
REALCVT, // Real conversion
|
2019-05-19 22:13:13 +02:00
|
|
|
REDEFMACRO, // Redefining existing define macro
|
|
|
|
|
SELRANGE, // Selection index out of range
|
2019-11-23 14:34:40 +01:00
|
|
|
SHORTREAL, // Shortreal not supported
|
2020-02-29 01:15:08 +01:00
|
|
|
SPLITVAR, // Cannot split the variable
|
2019-05-19 22:13:13 +02:00
|
|
|
STMTDLY, // Delayed statement
|
|
|
|
|
SYMRSVDWORD, // Symbol is Reserved Word
|
|
|
|
|
SYNCASYNCNET, // Mixed sync + async reset
|
2018-09-23 21:09:47 +02:00
|
|
|
TICKCOUNT, // Too large tick count
|
2020-04-16 01:39:03 +02:00
|
|
|
TIMESCALEMOD, // Need timescale for module
|
2019-05-19 22:13:13 +02:00
|
|
|
UNDRIVEN, // No drivers
|
2022-05-15 17:03:32 +02:00
|
|
|
UNOPT, // Unoptimizable block. Historical, never issued.
|
2019-05-19 22:13:13 +02:00
|
|
|
UNOPTFLAT, // Unoptimizable block after flattening
|
2018-07-22 18:09:27 +02:00
|
|
|
UNOPTTHREADS, // Thread partitioner unable to fill all requested threads
|
2019-05-19 22:13:13 +02:00
|
|
|
UNPACKED, // Unsupported unpacked
|
|
|
|
|
UNSIGNED, // Comparison is constant due to unsigned arithmetic
|
|
|
|
|
UNUSED, // No receivers
|
|
|
|
|
USERERROR, // Elaboration time $error
|
|
|
|
|
USERFATAL, // Elaboration time $fatal
|
|
|
|
|
USERINFO, // Elaboration time $info
|
|
|
|
|
USERWARN, // Elaboration time $warning
|
|
|
|
|
VARHIDDEN, // Hiding variable
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
WAITCONST, // Wait condition is constant
|
2019-05-19 22:13:13 +02:00
|
|
|
WIDTH, // Width mismatch
|
|
|
|
|
WIDTHCONCAT, // Unsized numbers/parameters in concatenations
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
ZERODLY, // #0 delay
|
2019-05-19 22:13:13 +02:00
|
|
|
_ENUM_MAX
|
|
|
|
|
// ***Add new elements below also***
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-04-15 13:58:34 +02:00
|
|
|
// clang-format on
|
2006-08-26 13:35:28 +02:00
|
|
|
enum en m_e;
|
2022-09-16 14:17:38 +02:00
|
|
|
V3ErrorCode()
|
2020-08-16 17:40:42 +02:00
|
|
|
: m_e{EC_MIN} {}
|
2015-10-04 04:33:06 +02:00
|
|
|
// cppcheck-suppress noExplicitConstructor
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr V3ErrorCode(en _e)
|
2020-08-16 17:40:42 +02:00
|
|
|
: m_e{_e} {}
|
2018-08-25 15:52:45 +02:00
|
|
|
explicit V3ErrorCode(const char* msgp); // Matching code or ERROR
|
2022-09-16 14:17:38 +02:00
|
|
|
explicit V3ErrorCode(int _e)
|
2020-08-18 14:10:44 +02:00
|
|
|
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr operator en() const { return m_e; }
|
2006-08-26 13:35:28 +02:00
|
|
|
const char* ascii() const {
|
2020-04-15 13:58:34 +02:00
|
|
|
// clang-format off
|
2020-05-29 03:04:36 +02:00
|
|
|
static const char* const names[] = {
|
2019-05-19 22:13:13 +02:00
|
|
|
// Leading spaces indicate it can't be disabled.
|
2021-04-18 16:16:18 +02:00
|
|
|
" MIN", " INFO", " FATAL", " FATALEXIT", " FATALSRC", " ERROR", " FIRST_NAMED",
|
2019-05-19 22:13:13 +02:00
|
|
|
// Boolean
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
" I_CELLDEFINE", " I_COVERAGE", " I_TRACING", " I_LINT", " I_DEF_NETTYPE_WIRE", " I_TIMING",
|
2019-02-28 03:06:07 +01:00
|
|
|
// Errors
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
"DETECTARRAY", "ENCAPSULATED", "PORTSHORT", "UNSUPPORTED", "TASKNSVAR", "NEEDTIMINGOPT", "NOTIMING",
|
2019-02-28 03:06:07 +01:00
|
|
|
// Warnings
|
2019-05-19 22:13:13 +02:00
|
|
|
" EC_FIRST_WARN",
|
2021-04-27 00:16:24 +02:00
|
|
|
"ALWCOMBORDER", "ASSIGNDLY", "ASSIGNIN", "BADSTDPRAGMA",
|
2019-05-19 22:13:13 +02:00
|
|
|
"BLKANDNBLK", "BLKLOOPINIT", "BLKSEQ", "BSSPACE",
|
2020-12-06 04:58:36 +01:00
|
|
|
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CASTCONST", "CDCRSTLOGIC", "CLKDATA",
|
2018-12-01 16:12:10 +01:00
|
|
|
"CMPCONST", "COLONPLUS", "COMBDLY", "CONTASSREG",
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
"DEFPARAM", "DECLFILENAME", "DEPRECATED", "RISEFALLDLY", "MINTYPMAXDLY",
|
2021-03-15 02:23:48 +01:00
|
|
|
"ENDLABEL", "EOFNEWLINE", "GENCLK", "HIERBLOCK",
|
2019-03-10 19:57:01 +01:00
|
|
|
"IFDEPTH", "IGNOREDRETURN",
|
|
|
|
|
"IMPERFECTSCH", "IMPLICIT", "IMPORTSTAR", "IMPURE",
|
2019-10-06 19:24:21 +02:00
|
|
|
"INCABSPATH", "INFINITELOOP", "INITIALDLY", "INSECURE",
|
2021-01-05 20:26:01 +01:00
|
|
|
"LATCH", "LITENDIAN", "MODDUP",
|
2021-04-09 16:39:46 +02:00
|
|
|
"MULTIDRIVEN", "MULTITOP","NOLATCH", "NULLPORT", "PINCONNECTEMPTY",
|
2021-04-02 00:17:42 +02:00
|
|
|
"PINMISSING", "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PROCASSWIRE",
|
2021-09-27 04:51:11 +02:00
|
|
|
"PROFOUTOFDATE", "PROTECTED", "RANDC", "REALCVT", "REDEFMACRO",
|
2020-02-29 01:15:08 +01:00
|
|
|
"SELRANGE", "SHORTREAL", "SPLITVAR", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET",
|
2020-04-16 01:39:03 +02:00
|
|
|
"TICKCOUNT", "TIMESCALEMOD",
|
2019-12-15 03:39:47 +01:00
|
|
|
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS",
|
2018-07-22 18:09:27 +02:00
|
|
|
"UNPACKED", "UNSIGNED", "UNUSED",
|
2019-05-19 22:13:13 +02:00
|
|
|
"USERERROR", "USERFATAL", "USERINFO", "USERWARN",
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
"VARHIDDEN", "WAITCONST", "WIDTH", "WIDTHCONCAT", "ZERODLY",
|
2019-05-19 22:13:13 +02:00
|
|
|
" MAX"
|
|
|
|
|
};
|
2020-04-15 13:58:34 +02:00
|
|
|
// clang-format on
|
2019-05-19 22:13:13 +02:00
|
|
|
return names[m_e];
|
2009-07-22 20:38:20 +02:00
|
|
|
}
|
2008-08-05 19:41:53 +02:00
|
|
|
// Warnings that default to off
|
2020-06-07 17:58:53 +02:00
|
|
|
bool defaultsOff() const {
|
|
|
|
|
return (m_e == IMPERFECTSCH || m_e == I_CELLDEFINE || styleError());
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
// Warnings that warn about nasty side effects
|
2020-04-15 13:58:34 +02:00
|
|
|
bool dangerous() const { return (m_e == COMBDLY); }
|
2006-10-11 17:41:42 +02:00
|
|
|
// Warnings we'll present to the user as errors
|
|
|
|
|
// Later -Werror- options may make more of these.
|
2020-04-15 13:58:34 +02:00
|
|
|
bool pretendError() const {
|
2021-04-27 00:16:24 +02:00
|
|
|
return (m_e == ASSIGNIN || m_e == BADSTDPRAGMA || m_e == BLKANDNBLK || m_e == BLKLOOPINIT
|
|
|
|
|
|| m_e == CONTASSREG || m_e == IMPURE || m_e == PINNOTFOUND || m_e == PKGNODECL
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
|| m_e == PROCASSWIRE // Says IEEE
|
|
|
|
|
|| m_e == ZERODLY);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2009-07-22 20:38:20 +02:00
|
|
|
// Warnings to mention manual
|
2020-04-15 13:58:34 +02:00
|
|
|
bool mentionManual() const {
|
|
|
|
|
return (m_e == EC_FATALSRC || m_e == SYMRSVDWORD || pretendError());
|
|
|
|
|
}
|
2007-10-31 22:17:23 +01:00
|
|
|
// Warnings that are lint only
|
2020-04-15 13:58:34 +02:00
|
|
|
bool lintError() const {
|
|
|
|
|
return (m_e == ALWCOMBORDER || m_e == BSSPACE || m_e == CASEINCOMPLETE
|
2020-12-06 04:58:36 +01:00
|
|
|
|| m_e == CASEOVERLAP || m_e == CASEWITHX || m_e == CASEX || m_e == CASTCONST
|
|
|
|
|
|| m_e == CMPCONST || m_e == COLONPLUS || m_e == ENDLABEL || m_e == IMPLICIT
|
2021-01-05 20:26:01 +01:00
|
|
|
|| m_e == LATCH || m_e == LITENDIAN || m_e == PINMISSING || m_e == REALCVT
|
|
|
|
|
|| m_e == UNSIGNED || m_e == WIDTH);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2010-12-25 21:13:56 +01:00
|
|
|
// Warnings that are style only
|
2020-04-15 13:58:34 +02:00
|
|
|
bool styleError() const {
|
|
|
|
|
return (m_e == ASSIGNDLY // More than style, but for backward compatibility
|
2021-03-15 02:23:48 +01:00
|
|
|
|| m_e == BLKSEQ || m_e == DEFPARAM || m_e == DECLFILENAME || m_e == EOFNEWLINE
|
|
|
|
|
|| m_e == IMPORTSTAR || m_e == INCABSPATH || m_e == PINCONNECTEMPTY
|
|
|
|
|
|| m_e == PINNOCONNECT || m_e == SYNCASYNCNET || m_e == UNDRIVEN || m_e == UNUSED
|
|
|
|
|
|| m_e == VARHIDDEN);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-02-02 16:34:29 +01:00
|
|
|
};
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr bool operator==(const V3ErrorCode& lhs, const V3ErrorCode& rhs) {
|
2020-02-02 16:34:29 +01:00
|
|
|
return lhs.m_e == rhs.m_e;
|
|
|
|
|
}
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr bool operator==(const V3ErrorCode& lhs, V3ErrorCode::en rhs) { return lhs.m_e == rhs; }
|
|
|
|
|
constexpr bool operator==(V3ErrorCode::en lhs, const V3ErrorCode& rhs) { return lhs == rhs.m_e; }
|
2020-02-02 16:34:29 +01:00
|
|
|
inline std::ostream& operator<<(std::ostream& os, const V3ErrorCode& rhs) {
|
|
|
|
|
return os << rhs.ascii();
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2022-09-23 11:57:01 +02:00
|
|
|
// ######################################################################
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class V3Error final {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Base class for any object that wants debugging and error reporting
|
2012-05-22 03:31:52 +02:00
|
|
|
|
2021-03-13 00:10:45 +01:00
|
|
|
using MessagesSet = std::set<std::string>;
|
|
|
|
|
using ErrorExitCb = void (*)(void);
|
2012-05-22 03:31:52 +02:00
|
|
|
|
2020-04-15 13:58:34 +02:00
|
|
|
private:
|
|
|
|
|
static bool s_describedWarnings; // Told user how to disable warns
|
2021-04-18 16:16:18 +02:00
|
|
|
static bool s_describedWeb; // Told user to see web
|
2020-11-15 22:21:26 +01:00
|
|
|
static std::array<bool, V3ErrorCode::_ENUM_MAX>
|
|
|
|
|
s_describedEachWarn; // Told user specifics about this warning
|
|
|
|
|
static std::array<bool, V3ErrorCode::_ENUM_MAX>
|
|
|
|
|
s_pretendError; // Pretend this warning is an error
|
2020-04-15 13:58:34 +02:00
|
|
|
static int s_debugDefault; // Option: --debugi Default debugging level
|
|
|
|
|
static int s_errorLimit; // Option: --error-limit Number of errors before exit
|
|
|
|
|
static bool s_warnFatal; // Option: --warnFatal Warnings are fatal
|
|
|
|
|
static int s_errCount; // Error count
|
|
|
|
|
static int s_warnCount; // Warning count
|
|
|
|
|
static int s_tellManual; // Tell user to see manual, 0=not yet, 1=doit, 2=disable
|
|
|
|
|
static std::ostringstream s_errorStr; // Error string being formed
|
|
|
|
|
static V3ErrorCode s_errorCode; // Error string being formed will abort
|
|
|
|
|
static bool s_errorContexted; // Error being formed got context
|
|
|
|
|
static bool s_errorSuppressed; // Error being formed should be suppressed
|
|
|
|
|
static MessagesSet s_messages; // What errors we've outputted
|
|
|
|
|
static ErrorExitCb s_errorExitCb; // Callback when error occurs for dumping
|
2013-05-25 18:15:38 +02:00
|
|
|
|
2020-08-16 20:19:12 +02:00
|
|
|
static constexpr unsigned MAX_ERRORS = 50; // Fatal after this may errors
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2020-04-15 13:58:34 +02:00
|
|
|
V3Error() {
|
|
|
|
|
std::cerr << ("Static class");
|
2020-06-05 14:00:22 +02:00
|
|
|
V3Error::vlAbort();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2020-04-15 13:58:34 +02:00
|
|
|
public:
|
2017-11-01 23:51:41 +01:00
|
|
|
// CONSTRUCTORS
|
2006-08-26 13:35:28 +02:00
|
|
|
// ACCESSORS
|
2019-05-19 22:13:13 +02:00
|
|
|
static void debugDefault(int level) { s_debugDefault = level; }
|
|
|
|
|
static int debugDefault() { return s_debugDefault; }
|
|
|
|
|
static void errorLimit(int level) { s_errorLimit = level; }
|
|
|
|
|
static int errorLimit() { return s_errorLimit; }
|
|
|
|
|
static void warnFatal(bool flag) { s_warnFatal = flag; }
|
|
|
|
|
static bool warnFatal() { return s_warnFatal; }
|
|
|
|
|
static string msgPrefix(); // returns %Error/%Warn
|
|
|
|
|
static int errorCount() { return s_errCount; }
|
|
|
|
|
static int warnCount() { return s_warnCount; }
|
2019-06-22 23:01:39 +02:00
|
|
|
static bool errorContexted() { return s_errorContexted; }
|
|
|
|
|
static void errorContexted(bool flag) { s_errorContexted = flag; }
|
2006-08-26 13:35:28 +02:00
|
|
|
// METHODS
|
2019-05-19 22:13:13 +02:00
|
|
|
static void incErrors();
|
|
|
|
|
static void incWarnings() { s_warnCount++; }
|
|
|
|
|
static void init();
|
2020-04-15 13:58:34 +02:00
|
|
|
static void abortIfErrors() {
|
|
|
|
|
if (errorCount()) abortIfWarnings();
|
|
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
static void abortIfWarnings();
|
|
|
|
|
static void suppressThisWarning(); // Suppress next %Warn if user has it off
|
|
|
|
|
static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code] = flag; }
|
|
|
|
|
static bool isError(V3ErrorCode code, bool supp);
|
2018-08-25 15:52:45 +02:00
|
|
|
static string lineStr(const char* filename, int lineno);
|
|
|
|
|
static V3ErrorCode errorCode() { return s_errorCode; }
|
2019-06-22 23:01:39 +02:00
|
|
|
static void errorExitCb(ErrorExitCb cb) { s_errorExitCb = cb; }
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2012-05-22 03:24:17 +02:00
|
|
|
// When printing an error/warning, print prefix for multiline message
|
|
|
|
|
static string warnMore();
|
2019-07-14 21:06:49 +02:00
|
|
|
/// When building an error, don't show context info
|
2020-04-15 13:58:34 +02:00
|
|
|
static string warnContextNone() {
|
|
|
|
|
V3Error::errorContexted(true);
|
|
|
|
|
return "";
|
|
|
|
|
}
|
2012-05-22 03:24:17 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
// Internals for v3error()/v3fatal() macros only
|
|
|
|
|
// Error end takes the string stream to output, be careful to seek() as needed
|
2012-05-22 03:24:17 +02:00
|
|
|
static void v3errorPrep(V3ErrorCode code) {
|
2020-04-15 13:58:34 +02:00
|
|
|
s_errorStr.str("");
|
|
|
|
|
s_errorCode = code;
|
|
|
|
|
s_errorContexted = false;
|
|
|
|
|
s_errorSuppressed = false;
|
|
|
|
|
}
|
2018-02-02 03:24:41 +01:00
|
|
|
static std::ostringstream& v3errorStr() { return s_errorStr; }
|
2020-06-05 14:00:22 +02:00
|
|
|
static void vlAbortOrExit();
|
2019-05-19 22:13:13 +02:00
|
|
|
static void vlAbort();
|
2020-04-15 13:58:34 +02:00
|
|
|
// static, but often overridden in classes.
|
2022-04-22 23:39:45 +02:00
|
|
|
static void v3errorEnd(std::ostringstream& sstr, const string& extra = "");
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Global versions, so that if the class doesn't define a operator, we get the functions anyways.
|
2018-02-02 03:24:41 +01:00
|
|
|
inline void v3errorEnd(std::ostringstream& sstr) { V3Error::v3errorEnd(sstr); }
|
2019-05-19 22:13:13 +02:00
|
|
|
inline void v3errorEndFatal(std::ostringstream& sstr) {
|
2020-04-15 13:58:34 +02:00
|
|
|
V3Error::v3errorEnd(sstr);
|
2020-05-16 13:53:27 +02:00
|
|
|
assert(0); // LCOV_EXCL_LINE
|
2022-10-02 22:35:45 +02:00
|
|
|
VL_UNREACHABLE;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2014-11-22 17:48:39 +01:00
|
|
|
// Theses allow errors using << operators: v3error("foo"<<"bar");
|
2006-08-26 13:35:28 +02:00
|
|
|
// Careful, you can't put () around msg, as you would in most macro definitions
|
2020-01-25 02:10:44 +01:00
|
|
|
// Note the commas are the comma operator, not separating arguments. These are needed to ensure
|
|
|
|
|
// evaluation order as otherwise we couldn't ensure v3errorPrep is called first.
|
2020-04-15 13:58:34 +02:00
|
|
|
#define v3warnCode(code, msg) \
|
2020-05-30 19:46:12 +02:00
|
|
|
v3errorEnd((V3Error::v3errorPrep(code), (V3Error::v3errorStr() << msg), V3Error::v3errorStr()))
|
2020-04-15 13:58:34 +02:00
|
|
|
#define v3warnCodeFatal(code, msg) \
|
|
|
|
|
v3errorEndFatal( \
|
2020-05-30 19:46:12 +02:00
|
|
|
(V3Error::v3errorPrep(code), (V3Error::v3errorStr() << msg), V3Error::v3errorStr()))
|
2020-04-15 13:58:34 +02:00
|
|
|
#define v3warn(code, msg) v3warnCode(V3ErrorCode::code, msg)
|
|
|
|
|
#define v3info(msg) v3warnCode(V3ErrorCode::EC_INFO, msg)
|
2017-07-07 02:25:59 +02:00
|
|
|
#define v3error(msg) v3warnCode(V3ErrorCode::EC_ERROR, msg)
|
|
|
|
|
#define v3fatal(msg) v3warnCodeFatal(V3ErrorCode::EC_FATAL, msg)
|
2020-03-15 13:09:51 +01:00
|
|
|
// Use this instead of fatal() if message gets suppressed with --quiet-exit
|
|
|
|
|
#define v3fatalExit(msg) v3warnCodeFatal(V3ErrorCode::EC_FATALEXIT, msg)
|
2006-08-26 13:35:28 +02:00
|
|
|
// Use this instead of fatal() to mention the source code line.
|
2020-04-15 13:58:34 +02:00
|
|
|
#define v3fatalSrc(msg) \
|
|
|
|
|
v3warnCodeFatal(V3ErrorCode::EC_FATALSRC, \
|
|
|
|
|
__FILE__ << ":" << std::dec << __LINE__ << ": " << msg)
|
2018-07-15 02:44:43 +02:00
|
|
|
// Use this when normal v3fatal is called in static method that overrides fileline.
|
|
|
|
|
#define v3fatalStatic(msg) \
|
2020-05-30 19:46:12 +02:00
|
|
|
(::v3errorEndFatal((V3Error::v3errorPrep(V3ErrorCode::EC_FATAL), \
|
|
|
|
|
(V3Error::v3errorStr() << msg), V3Error::v3errorStr())))
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2019-11-10 02:35:12 +01:00
|
|
|
#define UINFO(level, stmsg) \
|
2020-05-30 19:46:12 +02:00
|
|
|
do { \
|
2020-04-15 13:58:34 +02:00
|
|
|
if (VL_UNCOVERABLE(debug() >= (level))) { \
|
|
|
|
|
cout << "- " << V3Error::lineStr(__FILE__, __LINE__) << stmsg; \
|
|
|
|
|
} \
|
2020-05-30 19:46:12 +02:00
|
|
|
} while (false)
|
2019-11-10 02:35:12 +01:00
|
|
|
#define UINFONL(level, stmsg) \
|
2020-05-30 19:46:12 +02:00
|
|
|
do { \
|
2020-04-15 13:58:34 +02:00
|
|
|
if (VL_UNCOVERABLE(debug() >= (level))) { cout << stmsg; } \
|
2020-05-30 19:46:12 +02:00
|
|
|
} while (false)
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2017-03-31 23:46:15 +02:00
|
|
|
#ifdef VL_DEBUG
|
2020-04-15 13:58:34 +02:00
|
|
|
#define UDEBUGONLY(stmts) \
|
2020-05-30 19:46:12 +02:00
|
|
|
do { stmts } while (false)
|
2017-03-31 23:46:15 +02:00
|
|
|
#else
|
2020-04-15 13:58:34 +02:00
|
|
|
#define UDEBUGONLY(stmts) \
|
2020-05-30 19:46:12 +02:00
|
|
|
do { \
|
2020-04-15 13:58:34 +02:00
|
|
|
if (false) { stmts } \
|
2020-05-30 19:46:12 +02:00
|
|
|
} while (false)
|
2017-03-31 23:46:15 +02:00
|
|
|
#endif
|
|
|
|
|
|
2019-07-06 18:57:50 +02:00
|
|
|
// Assertion without object, generally UOBJASSERT preferred
|
2020-04-15 13:58:34 +02:00
|
|
|
#define UASSERT(condition, stmsg) \
|
|
|
|
|
do { \
|
2021-02-22 03:25:21 +01:00
|
|
|
if (VL_UNCOVERABLE(!(condition))) v3fatalSrc(stmsg); \
|
2020-04-15 13:58:34 +02:00
|
|
|
} while (false)
|
2019-07-06 18:57:50 +02:00
|
|
|
// Assertion with object
|
2020-04-15 13:58:34 +02:00
|
|
|
#define UASSERT_OBJ(condition, obj, stmsg) \
|
|
|
|
|
do { \
|
2021-02-22 03:25:21 +01:00
|
|
|
if (VL_UNCOVERABLE(!(condition))) (obj)->v3fatalSrc(stmsg); \
|
2020-04-15 13:58:34 +02:00
|
|
|
} while (false)
|
2006-08-26 13:35:28 +02:00
|
|
|
// For use in V3Ast static functions only
|
2020-04-15 13:58:34 +02:00
|
|
|
#define UASSERT_STATIC(condition, stmsg) \
|
|
|
|
|
do { \
|
|
|
|
|
if (VL_UNCOVERABLE(!(condition))) { \
|
|
|
|
|
std::cerr << "Internal Error: " << __FILE__ << ":" << std::dec << __LINE__ << ":" \
|
|
|
|
|
<< (stmsg) << std::endl; \
|
2020-06-05 14:00:22 +02:00
|
|
|
V3Error::vlAbort(); \
|
2020-04-15 13:58:34 +02:00
|
|
|
} \
|
|
|
|
|
} while (false)
|
2018-07-14 23:44:39 +02:00
|
|
|
// Check self test values for expected value. Safe from side-effects.
|
|
|
|
|
// Type argument can be removed when go to C++11 (use auto).
|
2020-04-15 13:58:34 +02:00
|
|
|
#define UASSERT_SELFTEST(Type, got, exp) \
|
|
|
|
|
do { \
|
|
|
|
|
Type g = (got); \
|
|
|
|
|
Type e = (exp); \
|
|
|
|
|
UASSERT(g == e, "Self-test failed '" #got "==" #exp "'" \
|
|
|
|
|
" got=" \
|
|
|
|
|
<< g << " expected=" << e); \
|
|
|
|
|
} while (false)
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2019-07-06 18:57:50 +02:00
|
|
|
#define V3ERROR_NA \
|
2020-04-04 04:31:54 +02:00
|
|
|
do { \
|
|
|
|
|
v3error("Internal: Unexpected Call"); \
|
|
|
|
|
v3fatalSrc("Unexpected Call"); \
|
|
|
|
|
} while (false)
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2020-04-05 16:26:53 +02:00
|
|
|
/// Throw fatal and return a value. The return value will never really be
|
|
|
|
|
/// needed, but required to avoid compiler error.
|
|
|
|
|
#define V3ERROR_NA_RETURN(value) \
|
|
|
|
|
V3ERROR_NA; \
|
|
|
|
|
return value
|
|
|
|
|
|
2022-09-18 21:53:42 +02:00
|
|
|
// Helper macros for VL_DEFINE_DEBUG_FUNCTIONS
|
|
|
|
|
#define VL_DEFINE_DEBUG(name) \
|
|
|
|
|
VL_ATTR_UNUSED static int debug##name() { \
|
2018-05-14 12:50:47 +02:00
|
|
|
static int level = -1; \
|
2021-07-10 13:03:51 +02:00
|
|
|
if (VL_UNLIKELY(level < 0)) { \
|
2022-09-18 21:53:42 +02:00
|
|
|
std::string tag{VL_STRINGIFY(name)}; \
|
|
|
|
|
tag[0] = std::tolower(tag[0]); \
|
|
|
|
|
const unsigned debugTag = v3Global.opt.debugLevel(tag); \
|
|
|
|
|
const unsigned debugSrc = v3Global.opt.debugSrcLevel(__FILE__); \
|
|
|
|
|
const unsigned debugLevel = debugTag >= debugSrc ? debugTag : debugSrc; \
|
|
|
|
|
if (!v3Global.opt.available()) return static_cast<int>(debugLevel); \
|
|
|
|
|
level = static_cast<int>(debugLevel); \
|
2021-07-10 13:03:51 +02:00
|
|
|
} \
|
2018-05-14 12:50:47 +02:00
|
|
|
return level; \
|
2022-09-18 21:53:42 +02:00
|
|
|
} \
|
|
|
|
|
static_assert(true, "")
|
|
|
|
|
|
|
|
|
|
#define VL_DEFINE_DUMP(name) \
|
|
|
|
|
VL_ATTR_UNUSED static int dump##name() { \
|
|
|
|
|
static int level = -1; \
|
|
|
|
|
if (VL_UNLIKELY(level < 0)) { \
|
|
|
|
|
std::string tag{VL_STRINGIFY(name)}; \
|
|
|
|
|
tag[0] = std::tolower(tag[0]); \
|
|
|
|
|
const unsigned dumpTag = v3Global.opt.dumpLevel(tag); \
|
|
|
|
|
const unsigned dumpSrc = v3Global.opt.dumpSrcLevel(__FILE__); \
|
|
|
|
|
const unsigned dumpLevel = dumpTag >= dumpSrc ? dumpTag : dumpSrc; \
|
|
|
|
|
if (!v3Global.opt.available()) return static_cast<int>(dumpLevel); \
|
|
|
|
|
level = static_cast<int>(dumpLevel); \
|
|
|
|
|
} \
|
|
|
|
|
return level; \
|
|
|
|
|
} \
|
|
|
|
|
static_assert(true, "")
|
|
|
|
|
|
|
|
|
|
// Define debug*() and dump*() routines. This needs to be added to every compilation unit so that
|
|
|
|
|
// --debugi-<tag/srcfile> and --dumpi-<tag/srcfile> can be used to control debug prints and dumping
|
|
|
|
|
#define VL_DEFINE_DEBUG_FUNCTIONS \
|
|
|
|
|
VL_DEFINE_DEBUG(); /* Define 'int debug()' */ \
|
|
|
|
|
VL_DEFINE_DUMP(); /* Define 'int dump()' */ \
|
Introduce DFG based combinational logic optimizer (#3527)
Added a new data-flow graph (DFG) based combinational logic optimizer.
The capabilities of this covers a combination of V3Const and V3Gate, but
is also more capable of transforming combinational logic into simplified
forms and more.
This entail adding a new internal representation, `DfgGraph`, and
appropriate `astToDfg` and `dfgToAst` conversion functions. The graph
represents some of the combinational equations (~continuous assignments)
in a module, and for the duration of the DFG passes, it takes over the
role of AstModule. A bulk of the Dfg vertices represent expressions.
These vertex classes, and the corresponding conversions to/from AST are
mostly auto-generated by astgen, together with a DfgVVisitor that can be
used for dynamic dispatch based on vertex (operation) types.
The resulting combinational logic graph (a `DfgGraph`) is then optimized
in various ways. Currently we perform common sub-expression elimination,
variable inlining, and some specific peephole optimizations, but there
is scope for more optimizations in the future using the same
representation. The optimizer is run directly before and after inlining.
The pre inline pass can operate on smaller graphs and hence converges
faster, but still has a chance of substantially reducing the size of the
logic on some designs, making inlining both faster and less memory
intensive. The post inline pass can then optimize across the inlined
module boundaries. No optimization is performed across a module
boundary.
For debugging purposes, each peephole optimization can be disabled
individually via the -fno-dfg-peepnole-<OPT> option, where <OPT> is one
of the optimizations listed in V3DfgPeephole.h, for example
-fno-dfg-peephole-remove-not-not.
The peephole patterns currently implemented were mostly picked based on
the design that inspired this work, and on that design the optimizations
yields ~30% single threaded speedup, and ~50% speedup on 4 threads. As
you can imagine not having to haul around redundant combinational
networks in the rest of the compilation pipeline also helps with memory
consumption, and up to 30% peak memory usage of Verilator was observed
on the same design.
Gains on other arbitrary designs are smaller (and can be improved by
analyzing those designs). For example OpenTitan gains between 1-15%
speedup depending on build type.
2022-09-23 17:46:22 +02:00
|
|
|
VL_DEFINE_DUMP(Dfg); /* Define 'int dumpDfg()' */ \
|
2022-09-18 21:53:42 +02:00
|
|
|
VL_DEFINE_DUMP(Graph); /* Define 'int dumpGraph()' */ \
|
|
|
|
|
VL_DEFINE_DUMP(Tree); /* Define 'int dumpTree()' */ \
|
|
|
|
|
static_assert(true, "")
|
2018-05-14 12:50:47 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
2019-05-19 22:13:13 +02:00
|
|
|
#endif // Guard
|