Is it syntax correct with gate level Verilog file, where the the sub-modules are defined after the owning module or they should be defined before? Does it matter according to Verilog rules?
Regards,
This might be compiler dependent, but if you are using a tool that supports SystemVerilog (which most commercial tools do these days), it should be syntactically correct to define modules in any order, perhaps even in separate files.
See IEEE Std 1800-2012, Section 3.12 for more info.
Notice that after compilation, there is another step which is called elaboration. At that point all the module description should have been compiled correctly. From SystemVerilog LRM:
Compilation is the process of reading in SystemVerilog source code, decrypting encrypted code, and analyzing the source code for syntax
and semantic errors. Implementations may execute compilation in one or
more passes. Implementations may save compiled results in a
proprietary intermediate format, or may pass the compiled results
directly to an elaboration phase. Not all syntax and semantics can be
checked during the compilation process. Some checking can only be done
during or at the completion of elaboration.
SystemVerilog supports both single file and multiple file compilation
through the use of compilation units (see 3.12.1).
Elaboration is the
process of binding together the components that make up a design.
These components can include module instances, program instances,
interface instances, checker instances, primitive instances, and the
top level of the design hierarchy. Elaboration occurs after parsing
the source code and before simulation; and it involves expanding
instantiations, computing parameter values, resolving hierarchical
names, establishing net connectivity and in general preparing the
design for simulation.
The short answer is that you can forward-reference modules in Verilog; this has always been the case, and is not tool-dependent (in other words, you can do it in either order). There may be complications if you use libraries and configurations but, in general, you can assume that you can instantiate a module before it is defined.
In most of Verilog, you have to declare something before you reference it. There are some exceptions, including task and function calls, implicit wires, cross-module/hierarchical references, and module names. In these cases, the tool waits until elaboration to find the referenced object. There is no clear explanantion of much of this in the LRM, unfortunately. This is how Verilog-XL did it, and everyone else has done it ever since.
Note that this isn't related to 'gate-level' files.
According to the rules defined in the Verilog LRM, modules, functions and tasks are the only things that may be referenced before being declared. SystemVerilog adds interfaces and programs to that list. Verilog also has implicitly declared nets that makes it seem that you are referencing a net before it being declared, but I strongly suggest not using that feature by using the compile directive ``default_nettype none.
Related
Is a timescale or any other directive mandatory in Verilog (2001) or is its use a matter of convention or style? For example, I typically use default_nettype none to enforce explicit net declarations throughout my implementation. However, Verilog does not require me to do so.
When it comes to timescale, I obviously place it at the top of my HDL testbench. But why use it in every single module of an IP? In case of inconsistent definitions, could this lead to more problems rather than preventing them?
Generally speaking, Verilog compiler directives are not mandatory.
For timescale, refer to IEEE Std 1800-2017, section 22.7 `timescale:
If there is no timescale specified or it has been reset by a `resetall
directive, the default time unit and precision are tool-specific.
The directives are global in scope, which means that when the compiler encounters one, it remains in effect for all the following code which is compiled (until another is encountered). So, there is no need to add timescale directives to all your code.
However, in practice, I have seen compilers generate errors if the 1st module (or modules) compiled does not have a timescale directive but subsequent modules do. These simulators also offer a command-line option to set the default timescale to avoid this error.
Is it possible to make a fully compiled and standalone version of an RTL module, like a snapshot in Cadence terms, and then later instantiate this compiled module into a testbench?
Ultimately, running another compile step to create a final snapshot which contains the originally delivered snapshot but now instantiated in the testbench.
If so, are there any special considerations when compiling the original snapshot to enable this and how would you instantiate such a compiled object within a testbench?
Yes. But every simulation tool has slightly different approaches to the compilation flow. Most tools break this flow into a number steps: parsing, optimization, elaboration, and initialization (the snapshot you mention is the last step). Not all tools give you access to all the individual steps.
There are several ways to achieve what you ask for, but the choice really depends on why you want to do this, and what limitations you are willing to work with.
You can parse your module's source code into a library and then re-use that same library for compiling many different test benches. But usually the time consuming part is optimization.
Questa provides what you are looking for in what they call the Pre-compiled Design Unit (PDU) flow. You can optimize your RTL module and save it back into a library, and Questa simply choses the optimized module instead of the un-optimized module during elaboration. The special considerations are that you need to preserve any signals from optimization that might have hierarchical references from the testbench.
SystemVerilog introduced some very useful constructs to improve coding style. However, as one of my coworkers always says, "You are not writing software, you are describing hardware." With that in mind, what features of the language should be avoided when the end result needs to be synthesized? This paper shows what features are currently synthesizable by the Synopsys tools, but to be safe I think one should only use the features that are synthesizable by all of the major vendors. Also, what constructs will produce strange results in the netlist which will be difficult to follow in an ECO?
In summary: I like compact and easy to maintain code, but not if it causes issues in the back end. What should I avoid?
Edit: In response to the close vote I want to try to make this a bit more specific. This question was inspired by this answer. I am a big fan of using the 'sugar' as Dave calls it to reduce the code complexity, but not if some synthesis tools are going to mangle signal names and make the result difficult to deal with. I am looking for more examples like this.
Theoretically, if you can write software that is synthesized into machine code to run on a piece of hardware, that software can be synthesized into hardware. And conversely, there are hardware constructs in Verilog-1995 that are not considered synthesizable simply because none of the major vendors ever got around to supporting it (e.g. assign/deassign). We still have people using //synopsis translate on/off because it took so long for them to support `ifdef SYNOPSYS.
Most of what I consider to be safe for synthesis in SystemVerilog is what I call syntactic sugar for Verilog. This is just more convenient ways of writing the same Verilog code with a lot less typing. Examples would be:
data types: typedef, struct, enum, int, byte
use of those types as ports, arguments and function return values
assignment operators: ++ -- +=
type casting and bit-streaming
packages
interfaces
port connection shortcuts
defaults for function/tasks/macro arguments, and port connections
Most of the constructs that fall into this category are taken from C and don't really change how the code gets synthesized. It's just more convenient to define and reference signals.
The place it gets difficult to synthesize is where there is dynamically allocated storage. This would be class objects, queues, dynamic arrays, and strings. as well as dynamically created processes with fork/join.
I think some people have a misconception about SystemVerilog thinking it is only for Verification when in fact the first version of the standard was the synthesizable subset, and Intel was one of the first users of it as a language for Design.
SystemVerilog(SV) can be used both as a HDL (Hardware Description Language) and HVL (Hardware Verification Language) and that is why it is often termed an "HDVL".
There are several interesting design constructs in SV which are synthesizable and can be used instead instead of older Verilog constructs, which are helpful in optimizing code and achieving faster results.
enum of SV vs parameter of Verilog while modelling FSM.
Use of logic instead of reg and wire.
Use of always_ff, always_comb, always_latch in place of
single always blocks in Verilog.
Use of the unique and priority statements instead of Verilog's
full and parallel case statements.
Wide range of data types available in SV.
Now what I have discussed above are those constructs of SystemVerilog which are used in RTL design.
But, the constructs which are used in the Verification Environment are non-synthesizable. They are as follows:
Dynamic arrays and associative arrays.
Program Blocks and Clocking blocks.
Mailboxes
Semaphores
Classes and all their related features.
Tasks
Chandle data types.
Queues.
Constrained random features.
Delay, wait, and event control statements.
Haskell supports mutually recursive let-bindings, which is great. Haskell doesn't support mutually recursive modules, which is sometimes terrible. I know that GHC has its .hs-boot mechanism, but I think that's a bit of a hack.
As far as I know, transparent support for mutually recursive modules should be relatively "simple", and it can be done exactly like mutually recursive let-bindings: instead of taking each separate module as a compilation unit, I would take every strongly connected component of the module dependency graph as a compilation unit.
Am I missing something here? Is there any non-trivial reason why Haskell doesn't support mutually recursive modules in this way?
This 6-year-old feature request ticket contains a fair amount of discussion, which you may have already seen. The gist of it is that it's not entirely a simple change as far as GHC is concerned. A few specific issues raised:
GHC currently has a lot of baked-in assumptions about how modules are processed during compilation, and changing those assumptions significantly would vastly outweigh the benefits of transparent support for mutually recursive modules.
Lumping groups of modules together means they have to be compiled together, which means more recompilation and awkwardness with generating separate .hi and .o files.
Backward compatibility with existing builds that use hs-boot files.
You have the potential for mutually-recursive bindings that cross module boundaries in a mutually-recursive module group, which raises issues with anything that involves implicit, module-level scope (such as defaulting, and possibly type class instances).
And of course, the potential for unknown, unanticipated bugs, as with anything that alters long-standing assumptions in GHC. Even without massive changes to the compilation process, many things are currently assumed to be compiled on a per-module basis.
A lot of people would like to see this supported, but so far nobody has either produced a possible implementation or worked out a detailed, well-specified design that handles all the fiddly corner cases of the sort mentioned above.
I have some self-testing code for my SystemVerilog component and I want to ensure that my tests cover everything, especially the failure cases in my classes. All I need is line/branch coverage, just like what is normally used for other object oriented languages such as Java.
I tried using VCS (version 2012.06) coverage, and I found it only has a limited support for SystemVerilog, and does not support any coverage for SystemVerilog classes. Is there any simulator or tool that has this support?
The Certitude tool by SpringSoft (just purchased by Synopsys) is a tool which checks the effectiveness of your testbench. It essentially analyzes coverage of your testbench code and does a whole lot more.
http://www.springsoft.com/products/functional-qualification/certitude
2012/08/25
Until further notice, the answer is:
No, there is no tool/simulator that supports line coverage for SystemVerilog classes.
I'd have thought Modelsim's or Aldec's coverage would do what you need. To be honest, it looks like VCS does too, so maybe the other tools have the same flaws?
I have tried that new feature in Mentor Questasim simulator. They have implemented SV (systemverilog) class code coverage from Modelsim/Questa 10.2 on.
To activate that feature in a systemverilog file/class you need to:
Example :
vlog +cover my_design.sv
vsim –voptargs=+acc –coverage mydesign
vcover may take the following specifications .When no specification is mention , +vcover is equivalent with “+vcover=bcesft”.
b — Collect branch statistics.
c — Collect condition statistics. Collects only FEC statistics, unless -coverudp is specified.
e — Collect expression statistics, Collects only FEC statistics, unless -coverudp is specified.
s — Collect statement statistics.
t — Collect toggle statistics. Overridden if ‘x’ is specified elsewhere
x — Collect extended toggle statistics .This takes precedence, if ‘t’ is specified elsewhere.
f — Collect Finite State Machine statistics.
I've found covered, but didn't use it myself. It's open source, that's a plus, but seems not to be in development since 2010... :-/