SV lrm interpretation for v2k libraries - system-verilog

this is a question for lrm experts. I am trying to find an lrm saying about parsing of v2k lib contents and finding some bits and pieces which contradicts each other. So, here is a schematic example:
library lib1 pkg1.sv, top1.sv, mod1.sv;
library lib2 pkg2.sv, top2.sv, mod2.sv;
pkg1.sv and pkg2.sv
package pkg;
...
endpackage
top1.sv and top2.sv:
module top()
import pkg::*;
mod mod(...);
...
endmodule
mod1.sv and mod2.sv
module mod(...);
...
endmodule
sometop.sv
module sometop();
mod mod1(...);
mod mod2(...);
...
endmodule
config v1;
...
mod1 use lib1.mod;
mod2 use lib2.mod;
endconfig
In the example above same module names and same package names are in multiple libraries. It has been proven that vcs parses the all packages and hierarchies from lib1 for mod1 and from lib2 if for mod2. This is an expected behavior from the consumer point of view.
However,
33.4 A configuration may change the binding of a module, primitive, interface, or program instance, but shall not change the binding of a package.
33.2.1 A library is a named collection of cells. A cell is a design element (see 3.2), such as a module, primitive,interface, program, package, or configuration.
The standards talks a lot of binding cells to the libraries, but I could not find any clause that would dictate that the compiler has to chose hierarchies or packages from the same library.
Can someone explain this behavior from LRM point of view?

There is no contradiction here. Packages must be compiled before they can be imported and they are bound at that time (IEEE 1800-2017 26.3). When you compile lib1 you are binding lib1.pkg with lib2.mod and lib2.pkg with lib1.mod.
The config clause is changing the binding of sometop with lib1.mod or lib2.mod. The packages that these modules were bound to remain unchanged.

Related

Why does Erlang offer both `import` for modules and `include` for headers?

Erlang's -import() directive lets you import code from other modules. Its include() directive lets you import code from headers. Why reasons are there to prefer either one over the other?
My hunch is that headers are good for short, easy-on-the-compiler kinds of code, such as record definitions, when you don't want to have to qualify the
Learn You Some Erlang states[1] that "Erlang header files are pretty similar to their C counter-part: they're nothing but a snippet of code that gets added to the module as if it were written there in the first place." Thus inclusion seems to cause the compiler to duplicate effort across different modules. And header files are what appear to be an optional complication on top of the mandatory module system. So why would I ever use a header file?
[1] https://learnyousomeerlang.com/a-short-visit-to-common-data-structures
Erlang's -import just allows you to call imported functions without the Module. It hurts legibility and should not be used: You need to check the import directive to know whether a function is local or external to the module.
With header files you get the same functionality as in C, you can use them to share -record definitions instead of having a dto-like module (1), you can use them to include -defines to use the same macros (2).
1:
-record(position, {x, y}).
Imagine that you have #position{} throughout the code, instead of defining the record everywhere and updating all of the copies when the record definition changes, you use a header (or a dto module with opaque types, but that's for another question).
And let's just hope that you remember to update all the copies, otherwise chaos ensues.
2:
-define(ENUM01, enum01).
-define(DEFAULT_TIMEOUT, 1000).
Instead of using enum01 and 1000 everywhere, which is error prone and requires multiple updates if you need to change them, you define them in a header and use them as ?ENUM01 and ?DEFAULT_TIMEOUT
Or you can be more thorough when testing:
-ifdef(TEST).
-define(assert(A), true = A).
-else
-define(assert(A), A).
-endif.
Or you can include some useful information:
-define(LOG(Level, X), logger:log(Level, X, #{line => ?LINE}).
The Erlang standard library uses header files to provide the ability to add metadata to your code.
For instance, EUnit functionality:
-include_lib("eunit/include/eunit.hrl").
import is helpful in building encapsulations, whereas include is kind of pre-processing(which means code will be part of the unit before it gets through the compiler).
An import ensues a dependency between two modules, which means a module A importing module B has B as dependency ... Whereas an include is extensional which means a module has included some code and that code is part of the module itself, and that is what header files do.
module(s) and header(s) are 2 semantically different things and serve different purposes. With modules, we can build abstractions by using the export(s), keep things confined by not exporting them, import from other modules(but they are not exported by default), re-export imported things etc etc. So when we import stuff, we can call upon functions from the other module, but only those which are exported in the other module. However that is not the case with header files. Everything inside a header file becomes part of the module which includes them. There is no sense of export/import inside header files. And header files are quite useful for writing and distributing definition(s) which otherwise could lead to redundancy in case of large programs.
So essentially they are 2 different things, so 2 different keywords available at our disposal. So don't prefer one over the other. Learn both of them as we need both of them.

How to print Package Variables

How to Print all package variables in Perl.
I have 2 packages in same script, I want to get all the variables used in packageA in packageB
What problem are you trying to solve?
But, there are so many other design issues here.
If there's some central source of truth for values in your program, that package can provide an interface to request a value. This is what I tend to do.
They are package variables, so package B can just use the variables from package A: $A::some_var.
package A could export all of its variables to any other package that wants to use them. Several Perl modules, such as Socket and Fcntl, do this.
If package B is really just a specialization of package A, inheritance might be the answer. You still need an interface though.

Does SystemVerilog support nested packages?

I have a tool that produces .sv RAL files for use in a UVM testbench. The problem is that this file creates the register block as a package. My issue is that for my testbench, I want to import multiple .sv RAL files (representing different reg blocks).
To do this, I want to create a single package all_my_regs_pkg.sv and `include the other packages into this package. I get a compilation error and looking into it, it looks like there isn't support for nested packages in SystemVerilog.
So do I need to manually import each of the reg block packages when I want to use them? I suppose I could create a file with the imports and just `include it, but is this the only way?
SystemVerilog does not allow nesting of package declarations. The best thing for you do do is to define a file that is a list of package import statements and have users `include that file where needed.
The is another SV feature that allows you to chain package imports, but you have to explicitly export a symbol that you import into a package to be imported by the next package. See Section 26.6 Exporting imported names from packages in the 1800-2012 LRM

Physical packages and package declaration in DROOLS

What is the use of physical packages and package declaration in Drools.
For eg,
I have a rule, Myrule.drl in the physical package com.mycompany
As I understand the package declaration in drools doesn't depend on the actual physical package the file lies in.
So I can give in Myrule.drl as
package com.sample;
rule "my rule"
when
then
end
Can somebody help me to understand what is the relation between the physical package/folder that the drl file lies and the package declaration in drl file?
Your understanding is correct. There is no relation between the package declaration in your DRL and the place where the DRL file is.
All the Java classes generated by either the RHS of the rules or the type declarations are going to be placed by Drools' Compiler in the package defined in the DRL file where they are. This allow you to have rules or declare types with same name but in different packages.
Hope it helps,
Why don't you just read the documentation, Drools "Expert" manual, Section 7.5?
A package is a collection of rules and other related constructs, such as imports and globals. The package members are typically related to each other - perhaps HR rules, for instance. A package represents a namespace, which ideally is kept unique for a given grouping of rules. The package name itself is the namespace, and is not related to files or folders in any way.
There's more...
Can somebody help me to understand what is the relation between the physical package/folder that the drl file lies and the package declaration in drl file?
There is no relationship (directly). You have to think in terms of what happens when you run the rules engine. When you run your application, these rules are turned into virtual objects placed in the declared namespace. So, for example:
DRL snippet
package com.mystuff
import java.util.logging.Logger;
import java.util.logging.Level;
rule "Hello World"
when
some condition...
then
Logger.log(Level.INFO, "Hello World");
end
When this rule is activated, given that you have logging turned on to the right levels, you will notice an entry similar to this one:
INFO com.mystuff.Rule_HelloWorld592399015 defaultConsequence Hello World
proving that the rule was turned into a virtual object (you won't find it as a .class file in your project) that it's located in the com.mystuff namespace as Estaban Aliverti mentioned on this post.
This is not that important if you are only operating with a single rule file. But, as you can imagine, if you have multiple files with similar rules, they will be resolved by the namespace included in the DRL file.

SystemVerilog: Using packages with classes and virtual interfaces

I'm a relative newbie to SystemVerilog.
I have a package with class A defined in it. This class uses a virtual interface, since
it's a driver (BFM) in a testbench. I'm using a package so I can use the same BFM in
other designs.
In my testbench, I import the A class and pass to it an instance of the virtual interface.
However, when a task in the class tries to assign a value to a signal in the interface, I'm getting a compilation error.
What am I doing wrong?
How can one package a BFM with a virtual interface?
Thanks,
Ran
SystemVerilog packages cannot include interfaces within the actual package. So your interface needs to be compiled along with you package source. The classes you define will reside in the package while the interface definition resides in the global scope where modules live.
Classes within packages can make references to virtual interfaces, but you need to make sure the interface is compiled and visible, apart from the package source.
Strictly according to the spec, I don't think this is possible since it adds an implicit external dependency:
Items within packages are generally type definitions, tasks, and
functions. Items within packages shall not have hierarchical
references to identifiers except those created within the package or
made visible by import of another package. A package shall not refer
to items defined in the compilation unit scope.
It doesn't say anything about the design element namespace, which is where interface declarations live, but accessing any member of an interface requires a hierarchical reference.
You should consider packages to be completely self-contained, other than pre-processor directives and import.
Generally the class declaration not present before its usage is resolved with the help of systemverilog typedef definition. For example "Class A uses Class B" and "Class B uses class A" then typedef is used to resolve the stalemate.
Now when you bring in the package with the above scenario then one needs to ensure both Class A and Class B have to be in same package. If they are not then the compile wont go through.
The reason being the SystemVerilog parser will need the definition of the classes indicated with the typedef at the end of the package parsing. This fails.
This issue needs to watched out that "typedef does not apply across package".