This example was taken from a uvm_users_guide_1.1, page 27:
`timescale 1ns/1ps
package a_pkg;
class a;
function void f(inout time t);
t += 10ns;
endfunction
endclass
endpackage
program p;
import a_pkg::*;
...
endprogram
Is the :: the same as . ? And what does the * stand for?
Refer to IEEE Std 1800-2017, section 26.3 Referencing data in packages. The ::* syntax is a wildcard import, defined as:
A wildcard import allows all identifiers declared within a package to
be imported provided the identifier is not otherwise defined in the
importing scope
:: is the package scope resolution operator. * allows all identifiers to be imported, as opposed to explicitly name identifiers to be imported.
In your example, it allows access to the a class inside the p program.
Related
In Modelica models, we often use outer components, such as system settings and other common variables, but if I am reading a new model, is there any easy way to allow me to find which component is using outer components?
As an example, the following screenshot is Modelica.Fluid.Examples.HeatingSystem, how could I know which component is using the "system" as an outer component?
I could read the code line by line, but is there an easier way to do this?
Dymola does not provide such a feature in the gui. But with the ModelManagement library its possible to obtain such information. The library is available with the standard Dymola license and pre-installed.
Below you find the function SO.printComponents() which uses the ModelManagement library to obtain all components in a class which match the given criterias.
For your model the printed output is:
Components in Modelica.Fluid.Examples.HeatingSystem using Modelica.Fluid.System as outer:
tank<Modelica.Fluid.Vessels.BaseClasses.PartialLumpedVessel>.heatTransfer<Modelica.Fluid.Interfaces.PartialHeatTransfer>.system
tank<Modelica.Fluid.Interfaces.PartialLumpedVolume>.system
pump<Modelica.Fluid.Machines.BaseClasses.PartialPump>.heatTransfer<Modelica.Fluid.Interfaces.PartialHeatTransfer>.system
...
valve<Modelica.Fluid.Interfaces.PartialTwoPort>.system
...
You see all components in Modelica.Fluid.Examples.HeatingSystem which contain an instance of Modelica.Fluid.System with the prefix outer.
If a component inherited the system instance from a base class via extends, the base class is given between angle brackets in the form <base-class>.
The first component in the output for example means, that the tank component is extending the PartialLumpedVessel class, which contains a component heatTransfer which extends the PartialHeatTransfer which contains the system instance we are looking for.
Note that for multilevel inheritance only the final base class is given, not the full path to it. This is e.g. relevant for the valve, which inherits the system instance from PartialTwoPort via PartialValve and PartialTwoPortTransport.
Background information
The ModelManagement library features some interesting functions in the package ModelManagement.Structure which allow to obtain information about Modelica classes.
The functions are divided into two different types:
ModelManagement.Structure.AST: For these functions, only Modelica code of the selected class is considered. Everything that is inherited is not considered.
ModelManagement.Structure.Instantiated: All functions in this package operate on the translated model
At the first glance ModelManagement.Structure.Instantiated.UsedModels seems a good starting point. But its documentation says:
Optionally disabled components, base-classes, and called functions are not included.
As the Fluid package makes heavy use of inheritance, we would easily miss a component when inheritance is not considered.
Fortunately the Testing library contains a function, which returns all inherited base classes Testing.Utilities.Class.getExtendedClasses. In addition ModelManagement.Structure.AST.ComponentsInClassAttributes allows us to retrieve all components of a given class (but not the inherited ones).
With those two functions, we can build a new function that:
Retrieves all components of a class, including the ones inherited from base classes
Checks if a component matches our search criteria (in your case it should be an outer instance of Modelica.Fluid.System)
Recursively check sub-components of all components, as the usage of system could happen further down in the hierarchy
Here is the code. Additionally a small print function is included, which prints the found components nicely to the terminal.
package SO
function getComponentsUsingClass "Get all components in class c1 which use class c2 as local component"
import ModelManagement.Structure.AST;
import Testing.Utilities.Class.getExtendedClasses;
import Testing.Utilities.Vectors.catStrings;
input String c1 "Full path of class of which components are retrieved";
input String c2 "Full path of class which must be used in the components";
input Boolean isOuter=false "Return only components where c2 is used as an outer instance";
output String cmp[:] "All components in c1 using c2";
protected
String sub[:] "Sub-components";
Boolean baseClass "True if current class is a baseClass of c1 (c1 extends it)";
String prefix "Used to give base classe";
algorithm
cmp :=fill("", 0);
// loop over class c1 and all its base classes
for c in cat(1,{c1}, getExtendedClasses(c1)) loop
baseClass :=c <> c1;
prefix :=if baseClass then "<" + c + ">." else ".";
// loop over all components in the current class
for cmpa in AST.ComponentsInClassAttributes(c) loop
if cmpa.fullTypeName==c2 and cmpa.isOuter==isOuter then
cmp :=cat(1, cmp, {prefix+cmpa.name});
end if;
// if the current component is a Modelica class, obtain all sub-components using c2
// (Mon-Modelica classes would e.g. be the attributes min, max, stateSelect etc. of built in classes)
if cmpa.fullTypeName<>"" then
sub := getComponentsUsingClass(cmpa.fullTypeName, c2, isOuter);
sub :=catStrings(fill(prefix+cmpa.name, size(sub, 1)), sub);
cmp :=cat(1, cmp, sub);
end if;
end for;
end for;
end getComponentsUsingClass;
function printComponents
import Modelica.Utilities.Streams.print;
import DymolaModels.Utilities.Strings.stripLeft;
input String c1="Modelica.Fluid.Examples.HeatingSystem" "Full path of class of which components are retrieved";
input String c2="Modelica.Fluid.System" "Full path of class which must be used in the components";
input Boolean isOuter=true "Return only components where c2 is used as an outer instance";
algorithm
print("Components in " + c1 + " using " + c2 + (if isOuter then " as outer" else "") + ":");
for c in getComponentsUsingClass(c1, c2,isOuter) loop
print(" " + stripLeft(c, "."));
end for;
end printComponents;
annotation (uses(
Modelica(version="4.0.0"),
Testing(version="1.3.1"),
ModelManagement(version="1.2.0"),
DymolaModels(version="1.2")));
end SO;
In a system verilog design, I have a top-module, sub-module and a sub-sub module. sub-sub module instantiated in sub-module instantiated in top module.Top module also has an instance of sub-sub module.The hierarchy tree is shown below
The sub-sub module definition has some code written in a 'ifndef block like this
module sub_sub()
{
...........
`ifndef OFF
<code to avoid>
`endif
...........
}
How can I disable the code to avoid only in sub-sub module instance1 during compilation?
I used `define OFF in sub-module instance but it disables code to avoid from all instances.
The cleaner solution is to pass a parameter and use a generate-if/case statement. Example:
module sub_sub #(parameter OFF=0) ( ... );
generate
if (OFF) begin
<code to avoid>
end
endgenerate
endmodule
module sub ( ... );
...
sub_sub #( .OFF(1'b1) ) inst ( ... );
endmodule
module top ( ... );
...
sub inst0 ( ... );
sub_sub #( .OFF(1'b0) ) inst1 ( ... );
endmodule
Technically the the if (OFF) does not need to be in an explicit generate-endgenerate; it is inferred otherwise. It is recommended for human readability.
For full detail on generate blocks, refer to IEEE Std 1800-2012 § 27. Generate constructs
The scope of `define macros, and most other compiler directives is a compilation unit. A compilation unit is a stream of source text that a compiler parses. A macro gets defined at the point it appears in the compilation unit and is visible from that point onward.
The scopes defined by modules and other namespaces are irrelevant because macros are pre-processed before any Verilog or SystemVerilog syntax gets recognized. This means you can never have instance specific control over macro definitions.
If you want instance specific control over your code, you need to define parameters with instance specific overrides. Then you can use generate-if/case constructs to control the code you want to execute. If the generate construct is too restrictive for you, you can use procedural-if/case statements and optimization will remove branches not taken as a result of constant parameters.
The best way is to modify your sub_sub module using parameter as suggested in other answers.
However, this may not be practical if you can't edit/modify the sub_sub module, for example, it may be an encrypted IP.
In this case, one solution is to create wrapper nested module for each sub_sub module. You can do as follows:
// Wrapper for sub_sub with OFF defined
module sub_sub_wrapper1;
`define OFF
`include "sub_sub.v"
`undef OFF
endmodule
// Wrapper for sub_sub without OFF defined
module sub_sub_wrapper2;
`include "sub_sub.v"
endmodule
////////////////
module sub;
sub_sub_wrapper1 subsub1();
endmodule
module top;
sub sub1();
sub_sub_wrapper2 subsub2();
endmodule
Quick sample
In this case of course I am assuming you are able to edit your top and sub module. And just note that nested module is only supported in system-verilog.
I need to use the part of the standard library called Coq.Arith.PeanoNat (https://coq.inria.fr/library/Coq.Arith.PeanoNat.html).
I've tried either importing the entire Arith library or just this module, but I can't use it either way.
Every other library I've tried works just fine. When I do Require Import Bool. I compile and I can use it correctly. Upon Print Bool. I can take a look at all the functions inside in the next format:
Module
Bool
:= Struct
Definition...
.
.
.
End
When I do either Require Import Arith.PeanoNat. or Require Import Arith. I get this as immediate output:
[Loading ML file z_syntax_plugin.cmxs ... done]
[Loading ML file quote_plugin.cmxs ... done]
[Loading ML file newring_plugin.cmxs ... done]
<W> Grammar extension: in [tactic:simple_tactic], some rule has been masked
<W> Grammar extension: in [tactic:simple_tactic], some rule has been masked
<W> Grammar extension: in [tactic:simple_tactic], some rule has been masked
<W> Grammar extension: in [tactic:simple_tactic], some rule has been masked
<W> Grammar extension: in [tactic:simple_tactic], some rule has been masked
When I ask Coq Print Arith.PeanoNat it outputs: Module Arith := Struct End, it seems to be empty. When I try to use anything from the library, for example le_le under boolean comparisons, I get the standard Error: leb_le not a defined object. I have updated Coq and the libraries, and I have no idea of what might be going on here. I'd appreciate your input in fixing this library problem.
If I am not mistaken, Require is the keyword to load a file. Import has to do with managing name spaces. Often they are used together, as in Require Import PeanoNat., but they are really doing two different things.
When coq files (DirName/FileName.vo) are loaded with Require, it is as if the contents of FileName.vo is wrapped in Module DirName.FileName ... End. Everyting defined in the file is then accessed with DirName.FileName.Name.
The file can itself have modules M inside of it, and to get to M's contents, one has to type DirName.FileName.ModuleName.Name1 etc.
Import is used to get all the definitions up to the top level. By doing Import DirName.FileName.ModuleName the module Name1 is now imported to the top level, and can be referenced without the long path.
In your example above, the file Arith/PeanoNat.vo defines the module Nat. Actually, that is all it defines. So if you do Require Import Arith.PeanoNat you get PeanoNat.Nat at the top level. And then Import PeanoNat.Nat will bring Nat to the top level. Note that you can't do Require Import PeanoNat.Nat because it is no .vo file.
Coq can sometimes find a .vo file without you having to specify the whole path, so you can also do Require Import PeanoNat. and coq will find the file. If you wonder where it found it, do Locate PeanoNat.
Coq < Require Import PeanoNat.
Coq < Locate PeanoNat.
Module Coq.Arith.PeanoNat
Another Nat is also available from another place than PeanoNat.
Coq < Require Import Nat.
Warning: Notation _ + _ was already used in scope nat_scope
Warning: Notation _ * _ was already used in scope nat_scope
Warning: Notation _ - _ was already used in scope nat_scope
Coq < Locate Nat.
Module Coq.Init.Nat
So, you don't Import a library, you Require it. You use Import to not have to use the full path name. I hope this helps you debug what is happening.
When I try Print Arith.PeanoNat, the output is slightly different: I get Module PeanoNat := Struct Module Nat End and then even though leb_le is not in scope, Nat.leb_le is.
(I run 8.5beta2 in case that's relevant).
I've a simple assertion:
Lets say
assert #(posedge clk) (a |=> b);
I generally connect it with design signals using separate binding module
module bind_module;
bind dut assertion a1 (.*);
endmodule
I've a situation: dut has a bus of 45bits, each bit is generated / driven individually but all of them follow same assertion.
Can I use bind statement inside generate block? (for a range of 0 to 44) and then instead of .* use .a (in_bus[i]), .b (out_bus[i])
Assuming you intend the following:
genvar i;
generate
for(i=0; i<45; i=i+1) begin : gen_asrt
bind dut assertion a1( .a(in_bus[i]), .b(out_bus[i]), .* );
end
This will not work for 2 reasons:
The instance name a1 is being clobbered on each loop. Each instance name within a module needs to be unique. Quoting from IEEE std 1800-2012 § 23.11 'Binding auxiliary code to scopes or instances':
It is legal for more than one bind statement to bind a bind_instantiation into the same target scope. However, it shall be an error for a bind_instantiation to introduce an instance name that clashes with another name in the module name space of the target scope (see 3.13). This applies to both preexisting names as well as instance names introduced by other bind statements. The latter situation will occur if the design contains more than one instance of a module containing a bind statement.
i in the bind statement is referring to an i variable name within the scope of dut, not the genvar i. Again, quoting from IEEE std 1800-2012 § 23.11 'Binding auxiliary code to scopes or instances':
When an instance is bound into a target scope, the effect will be as if the instance was present at the very end of the target scope. In other words, all declarations present in the target scope or imported into the target scope are visible to the bound instance. Wildcard import candidates that have been imported into the scope are visible, but a bind statement cannot cause the import of a wildcard candidate. Declarations present or imported into $unit are not visible in the bind statement.
How to bind this kind of checker:
You could create one module that handles the generate statements, then instantiate that module with a bind statement. Example:
module bind_assertions #(parameter SIZE=1) ( input clock, input [SIZE-1:0] a,b );
genvar i;
generate
for(i=0; i<SIZE; i=i+1) begin : gen_asrt
assertion a1_even( .a(a[i]), .b(b[i]), .* );
end
endgenerate
endmodule
bind dut bind_assertions#(45) a1( .a(in_bus), .b(out_bus), .* );
Technically, you could bind an array of instances. It is legal syntax according to § 23.11's Syntax 23-9 plus Appendix A.4.1.1 'Module instantiation'. However it this seems to fail on all the simulators I currently have access to. Example (if it works on your simulator):
bind dut assertion a1[44:0]( .a(in_bus[44:0]), .b(out_bus[44:0]), .* );
Can bind exist within a generate block?
IEEE std 1800-2012 § 27.3 'Generate construct syntax' does mention bind_directive within the syntax for generate constructs is given in Syntax 27-1. Like binding an array of instances, not all simulators support this feature yet. IEEE std 1800-2009 § 27.3 also mentions bind_directive but IEEE std 1800-2005 (first IEEE version of SystemVerilog) does not. Example (if it works on your simulator):
parameter DO_BIND=1;
generate
if(DO_BIND==1) begin
bind dut bind_assertions#(45) a1( .a(in_bus), .b(out_bus), .* );
end
endgenerate
In a Fortran 2003 module I'm defining a type called t_savepoint and, later, I want to define an interface for a subroutine called fs_initializesavepoint, which takes an object of type t_savepoint as only argument.
Here is the code for the whole module:
module m_serialization
implicit none
type :: t_savepoint
integer :: savepoint_index
real :: savepoint_value
end type t_savepoint
interface
subroutine fs_initializesavepoint(savepoint)
type(t_savepoint) :: savepoint
end subroutine fs_initializesavepoint
end interface
end module m_serialization
The reason why I want such an interface is that later on I will make this fortran module interoperate with C.
If I try to compile it (gfortran-4.7.0), I get the following error message:
type(t_savepoint) :: savepoint
1
Error: The type of 'savepoint' at (1) has not been declared within the interface
The error disappears if I move the definition of the type inside the subroutine; but if then I want to use the same type within many subroutines, should I repeat the definition in all of them?
Thank you in advance.
EDIT: a solution would be to move the definition of the type onto another module and then to use it in every subroutine. However I don't like this solution too much, because the type t_savepoint and the subroutines are part of the same conceptual topic.
Rightly or wrongly in an interface block you don't have access to the environment by host association. To fix this you need to import the datatype exlicitly:
[luser#cromer stackoverflow]$ cat type.f90
module m_serialization
implicit none
type :: t_savepoint
integer :: savepoint_index
real :: savepoint_value
end type t_savepoint
interface
subroutine fs_initializesavepoint(savepoint)
Import :: t_savepoint
type(t_savepoint) :: savepoint
end subroutine fs_initializesavepoint
end interface
end module m_serialization
[luser#cromer stackoverflow]$ gfortran -c type.f90
This is f2003.
However I suspect the way you have put this suggests you are not going about coding this up the best way. Better is simply to put the routine itself in the module. Then you don't need bother with the interface at all:
module m_serialization
implicit none
type :: t_savepoint
integer :: savepoint_index
real :: savepoint_value
end type t_savepoint
Contains
Subroutine fs_initializesavepoint(savepoint)
type(t_savepoint) :: savepoint
Write( *, * ) savepoint%savepoint_index, savepoint%savepoint_value
End Subroutine fs_initializesavepoint
end module m_serialization
[luser#cromer stackoverflow]$ gfortran -c type.f90
Given that modules are really designed to deal with connected entities this is really the way to do it in Fortran. It also has the advantage of only requiring a f95 compiler, so is universally available (though admittedly import is commonly implemented)