In a SystemVerilog design many basic types and sizes are shared. Passing them down as Verilog-style module parameters through endless levels of instantiation hierarchy isn’t the best way to keep SystemVerilog module definitions generic.
SystemVerilog added two lexical scoping mechanisms beyond module definitions for this purpose, the compilation-unit scope (
$unit) and packages. I recommend packages.
An old objection that is no longer accurate was that types and sizes from packages could not be used in the declarations of module ports without either fully qualified package references (such as
type_package::T) or wildcard imports into
$unit. But that was fixed in IEEE Std 1800-2009 by allowing package imports directly after the module name in a definition.
A new objection is that package imports after the module name clutter up the code, because if they are sharing global types and values they are needed in almost every module and interface definition. But here I show an easy way to get rid of the clutter with an unobtrusive macro.
`define _ import global_parameters::*, type_package::*;
module test `_
( input var T in[N]
, output var T out[N]
always_comb out = in;
As I wrote here,
Unlike class specializations, interface specializations cannot be used in a module port declaration. For example, the following is disallowed
module m #(parameter N) (IFC#(N) ifc, ...);
Steven Sharp followed up here that perhaps it was an oversight instead of a decision. Either way, it is still disallowed. He discusses some of the problems this causes for separate compilation. Happily, it is possible to get the effect of at least type checking SystemVerilog interfaces by combining class specializations (8.25) and interface-based typedefs (6.18) using a couple macros.
`define SIGNATURE_DEFINE(Params) \
typedef SIGNATURE Params \%SIGNATURE ;
`define SIGNATURE_CHECK(Params, Port) \
if (1) begin \
typedef SIGNATURE Params Expected; \
typedef Port.\%SIGNATURE Actual; \
if (type(Expected) != type(Actual)) begin \
Here’s a simple example
virtual class SIGNATURE#(int N, type T);
interface IFC#(int N, type T);
T a[N], z[N];
modport mp (input a, output z);
module test#(int N, type T)(IFC.mp ifc_mp);
Copyright © 2016 Brad Pierce
According to Chris Edwards in “Expanding role of UVM takes center stage at DVCon Europe”
[DVCon Europe general chair Martin] Barnasconi says UVM provides a useful framework that can be extended beyond its home of SystemVerilog-based IP verification […]
“We need to think beyond SystemVerilog,” says Barnasconi. “That’s where the challenge is if you ask me. System-level people might use SystemC, C++ or Matlab Simulink. The methodology concept behind UVM is something we should build upon to make it more applicable to other disciplines.
“In the conference there is a tutorial on UVM in SystemC. Teams are trying to bring the methodology to different languages. It underlines the ‘U’ in universal in my view. We also have the trend towards software-driven verification. We need to enable this software layer can be used within sequences defined in UVM.”
According to Dave Rich in “A Decade of SystemVerilog: Unifying Design and Verification?”
Most design engineers still debug their simulations the same way they debug in the lab: they look at waveforms. During simulation, they rarely look at the design source code, and certainly never look at the testbench code (unless it’s just basic pin wiggling like a waveform). Verification engineers are not much different. They rely on waveform debugging because that is what they were brought up on, and many do not even realize source-level debugging is available to them.
I recommend requiring the following macro instead of direct uses of
`define CASE(EXPR) \
unique case (EXPR) inside
except when there’s a strong justification for the more expensive alternative
`define PRIORITY_CASE(EXPR) \
priority case (EXPR) inside
If, as usual, the expectation is that every value should find a match, or if there is a
default branch, then close with
`define ENDCASE \
But if the intent really is for some values not to match any case items, and there is no
default branch, then close with
`define ENDCASE_NOT_FULL \