/** @page user-manual User Manual
@brief Instructions on how to use the slang tool as an end-user

@tableofcontents

@section quick-start Quick Start

The `slang` binary runs a full compilation of given SystemVerilog source files.
Eventually it will produce a full simulation binary as output, but for now it
serves as a checker of source code syntax, types, and various language rules.

Running it on one or more valid SystemVerilog files will note the top level modules
found, and will return zero:

@code{.sv}
// test1.sv
module m;
	struct { logic a; } s;
	int i = s.a + 1;
	initial $display("%d", i);
endmodule
@endcode

@code{.ansi}
> slang test1.sv
[93mTop level design units:
[0m    m

[1;32mBuild succeeded: [0m0 errors, 0 warnings

> echo $?
0
@endcode

Running it on a file with errors will produce nicely formatted diagnostic output:

@code{.sv}
// test2.sv
module m;
	struct { logic a; } s;
	int i = s + 1;
	initial $display("%d", i);
endmodule
@endcode

@code{.ansi}
[93mTop level design units:
[0m    m

[0;36m../test2.sv[0m:[1;36m4:12[0m: [1;31merror: [0m[1;37minvalid operands to binary expression ('<unnamed unpacked struct>' and 'int')[0m
        int i = s + 1;
[1;32m                ~ ^ ~[0m

[31mBuild failed: [0m1 error, 0 warnings
@endcode

@section compilation-units Compilation Units

By default `slang` treats all input files as separate SystemVerilog compilation units.
This is the preferred method both because it keeps the code logically separate (it doesn't
require a specific ordering of files on the command line in order to compile correctly) and
because internally the tool can parse files in parallel if it knows they don't have to be
parsed in a specific order.

If you have an older project where file ordering does matter, you can pass the `--single-unit`
option to have all input files treated as a single compilation unit.

@section built-in-macros Built-in Macros

There are a handful of slang-specific predefined macros that you can reference in your code:
Name | Value
---- | -----
\`__slang__ | 1
\`__slang_major__ | *slang major version number*
\`__slang_minor__ | *slang minor version number*

@section command-files Command Files

Command files allow specifying tool options in standalone composable files instead of needing
to pass all of them on the command line. One or more command files can be used by passing them
via the -F or -f command line flags -- both flags function identically except in the
treatment of file paths in the command file. -F files treat their paths as relative to the
command file itself, where as -f files treat paths as relative to the current working directory.

The format of a command file is straightforward; all text is treated as whitespace-delimited
arguments, similarly to how they might be passed on the command line. Newlines are treated
like any other form of whitespace. Some important features are as follows:

-  Command files can contain comments. '#' starts a line comment that continues to the end of
   the line, regardless of where the '#' occurs. '//' similarly starts a line comment, but only
   if preceeded by whitespace. '/&lowast;' and '&lowast;/' form a C-style multiline block comment.
-  Single quotes and double quotes group text in a similar fashion to how they work in Bash
   and other shells.
-  The backslash character can be used to escape special characters and treat them like normal text.
-  Environment variables in the command file are expanded. Variables can be specified in one of
   three styles: $VAR, \$\(VAR), and ${VAR}.
-  Command files can further include other command files by using -f or -F.
-  Arguments set in a command file are overridden by anything set on the command line if they would
   otherwise conflict.

@section system-funcs Nonstandard Built-in Functions

Besides the system tasks and functions specified in the SystemVerilog LRM, slang also provides
the following nonstandard built-in functions:

`$static_assert(condition[, message])`

Performs an elaboration-time check of the provided condition (which must be a constant expression)
and fails with an error if the condition is false. This works very similarly to the $error elaboration
system task, with the optional message being a string that accepts formatting specifiers in the same
style as the $sformatf function. If no message is provided it will print a default message about the failure.

$static_assert is usable in all contexts where $error is allowed, and additionally is supported in other
contexts such as packages. It can also be used in task, function, and other statement blocks.

If the assertion fails and the provided condition contains a comparison operator, slang will print
additional helpful information about both sides of the comparison to help diagnose the failure.

Example:

@code{.sv}
// test.sv
module m;
    localparam int foo = 12;
    struct packed { logic [4:1] a, b; } bar;
    $static_assert(foo < $bits(bar));
endmodule
@endcode

@code{.ansi}
test.sv:5:5: error: static assertion failed
    $static_assert(foo < $bits(bar));
    ^
test.sv:5:24: note: comparison reduces to (12 < 8)
    $static_assert(foo < $bits(bar));
                   ~~~~^~~~~~~~~~~~
@endcode

@section loop-unroll Driver loop unrolling

SystemVerilog specifies various rules about how nets and variables can be driven. These rules all operate on the
principal of "longest static prefixes" which are described in the LRM in section 11.5.3. Unintuitive behavior can
result when operating on nested subsets of arrays or structures due to these rules, for example:

@code{.sv}
module m;
    int foo[10];
    initial
        for (int i = 1; i < 10; i += 2) begin : baz
            foo[i] = 2;
        end

    for (genvar i = 0; i < 10; i += 2) begin
        always_comb foo[i] = 1;
    end
endmodule
@endcode

Under LRM rules, this results in a compilation error because inside a procedural block the for loop variable `i`
is not constant and therefore the longest static prefix of the assignment is just `foo`, and so all elements
are assumed assigned by the initial block. Most tools, slang included, implement an extension to attempt to
unroll all procedural for loops in order to extend the longest static prefix of assignments within those loops,
making the above example compile successfully. Such unrolling can be disabled with the `--strict-driver-checking`
command line flag.

The limitations of this feature are as follows:
- Only for loops are supported -- other kinds of loops are not.
- The for loop must declare its iteration variables and must provide stop and iteration expressions.
- The number of iterations of all for loops in a block must be less than the limit given by `--max-constexpr-steps`
- Only assignment statements are supported -- output args from subroutines are not taken into account.
- Conditional statements inside of for loops that depend on the iteration variable will work as expected.
- All other forms of flow control inside each for loop (including break / continue) are ignored.

*/
