copy an object to a handle in systemverilog - system-verilog

i have one module, mod1, which includes one class, my_test. Inside mod1 there is an instance of another module mod2 and mod2 includes a class, my_config. the "my_test" class also includes the my_config class.
I want to copy the object of my_config class to another handle of this class which is instantiated inside mod2 module. Below are the code snippets, you can follow. my_test, my_config, mod1, mod2 are in different files.
class my_test;
my_config cfg_2; // instance of my_config class
// here the object is created
// here i have assigned some values to the properties of my_config class
...
endclass : my_test
module mod2;
my_config cfg_1; // instance of my_config class
// mod2 file includes my_config class
...
endmodule : mod2
`include "my_test.sv" // included inside the file "mod1"
module mod1;
mod2 m2(..); // module instance of module mod2
// mod1 file includes my_test class
m2.cfg_1 = cfg_2; // cfg_1 is instance of my_config, inside mod2
// In the above line i am trying to copy the object cfg_2 to the handle cfg_1
// I AM GETTING ERROR IN THE ABOVE LINE.
...
endmodule : mod1
Can anyone please help me out. Thanks

You don't show the instance of my_test here, but assuming you create it under the name my_test_inst, then do the following:
module mod1();
//...
// you can only add procedural code in initial blocks
initial
m2.cfg_1 = my_test_inst.cfg_2
endmodule

Related

Can I use in Google Apps Scripts a defined Class in a library with ES6 (V8)?

I'm trying to use a class defined in a library but I only receive an error as a result.
[LibraryProject]/library/model/Update.gs
class Update {
constructor(obj = {}) {
if(typeof obj == "string"){
options = JSON.parse(obj);
}
Object.assign(this, obj);
}
text(){
return (this.message && this.message.text)?this.message.text:''
}
}
TASKS
✅ Create a new version of the project. (File > Manage versions...)
✅ Load this library in another project [Alias: CustomService] (Resources > Libraries...)
✅ Use functions of CustomService
❌ Use class of CustomService
If I try to use a Class
[NormalProject]/index.gs
function test (){
Logger.log(CustomService.libraryFunction())
var update = new CustomService.Update("");
Logger.log(update)
}
TypeError: CustomService.Update is not a constructor (línea 3, archivo "Code")
How can I instantiate an Object of this Class?
If I run...
Logger
As written in the official documentation,
Only the following properties in the script are available to library users:
enumerable global properties
function declarations,
variables created outside a function with var, and
properties explicitly set on the global object.
This would mean every property in the global this object are available to library users.
Before ES6, All declarations outside a function (and function declaration themselves) were properties of this global object. After ES6, There are two kinds of global records:
Object record- Same as ES5.
Function declarations
Function generators
Variable assignments
Declarative record - New
Everything else - let, const, class
Those in the declarative record are not accessible from the global "object", though they are globals themselves. Thus, the class declaration in the library is not accessible to library users. You could simply add a variable assignment to the class to add a property to the global object(outside any function):
var Update = class Update{/*your code here*/}
References:
Library official documentation
Global environment records
Related Answers:
ES6- What about introspection
Do let statements create properties on the global object
Based on your tests, it appears that you cannot directly import a class from a GAS library. I'd recommend creating a factory method to instantiate the class instead.
Something along these lines:
// Library GAS project
/**
* Foo class
*/
class Foo {
constructor(params) {...}
bar() {...}
}
/* globally accessible factory method */
function createFoo(fooParams) {
return new Foo(fooParams);
}
// Client GAS project
function test() {
var foo = FooService.createFoo(fooParams);
Logger.log(foo.bar());
}

Variable YYY originally saved as a XXX cannot be instantiated as an object and will be read in as a uint32

I've made a mistake and recorded a bunch of important data using a class definition that I can't find anymore. The methods are not important, I just want the data; a struct conversion would be fine.
Is there any way I can recover this?
Googling it did not help.
The solution is to create a new class that overloads the loadobj method. See here for more information regarding the load process for classes.
I replicated your problem by creating a class:
classdef myclass
properties
Prop1
Prop2
Prop3
end
methods
function obj = myclass(a,b,c)
obj.Prop1 = a;
obj.Prop2 = b;
obj.Prop3 = c;
end
end
end
Then I created an object of this class and saving it to a file "x.mat":
x = myclass('a',56,[1,2,3]);
save x
Next, I deleted the myclass file and did clear classes. This put me in your situation.
I then created a new myclass class that overloads the loadobj method:
classdef myclass
properties
data
end
methods (Static)
function obj = loadobj(s)
obj = myclass;
obj.data = s;
end
end
end
Note how it doesn't know any of the original properties. This does not matter. If any of the original properties is missing when loading an object from a MAT-file, loadobj will be called with s being a struct containing all the properties of the original object.
With this new class definition, load x created an object x of class myclass, where x.data was a struct containing the properties of the object saved in "x.mat".

How to pass parameterized class to a module instance?

include "cls.sv"
module top();
int x;
spl_cls #(10) o_spl_cls;
/*Code Continues, here o_spl_cls object has been created using
new();*/
dummy i_dummy(o_spl_cls); //I instantiated another module and passed
//object
endmodule
//This is my dummy module
module dummy(spl_cls i_spl_cls);
....
endmodule
//my spl_cls is
class spl_cls#(int data=0);
//...rest code
endclass
I am getting Error.
How to pass parameterized object to another module instance or class?
You will need to parameterize all references to spl_cls that you want to make assigments to.
module dummy(spl_cls#(10) i_spl_cls);
....
endmodule
A better solution would be to use a typedef
module top();
typedef spl_cls #(10) spl_cls_10;
int x;
spl_cls_10 o_spl_cls;
/*Code Continues, here o_spl_cls object has been created using
new();*/
dummy #(spl_cls_10) i_dummy(o_spl_cls); //I instantiated another module and passed
//object
endmodule
//This is my dummy module
module dummy #(type C)(C i_spl_cls);
....
endmodule

Using a file name string as a SystemVerilog interface parameter?

Is it possible to use a string as a SystemVerilog interface paramter. I have 4 instances of the same interface, and I was wondering if I can `include different assertion files for each instance.
My interface looks like this:
interface dai_if #(P_WD_DATA = 24,
string P_FILE_NAME = "assertion_file_name")();
//Internal Signal Defined Here
`include "assertion_file_name"
endinterface : dai_if
In the top level, where I instantiate the four instances I have the following code:
module tb_top;
parameter P_WD_DATA = 24;
parameter string DAI_SER_IN_FILE = "dai_ser_in_checkers.v";
parameter string DAI_SER_OUT_FILE = "dai_ser_out_checkers.v";
parameter string DAI_PAR_IN_FILE = "dai_par_in_checkers.v";
parameter string DAI_PAR_OUT_FILE = "dai_par_out_checkers.v";
Then I instanced each of the interfaces like this:
dai_if #(.P_WD_DATA(P_WD_DATA),
.P_FILE_NAME(DAI_SER_IN_FILE))
dai_ser_ivif();
Is this the correct method, or am I missing something?
Thanks
You cannot use parameters to define include files as the `include macro is performed long before the parameters are evaluated (note that marcos such as `include and `define are run as part of preprocessing while parameters are defined and used during elaboration; a stage of compilation).
However, there are ways to get the desired behavior. Instead of using the parameter string to directly include a file, you can use it to conditionally instantiate the code from an include file like so:
module top;
...
myInterface #(.assertType("TYPE1")) myInstance();
...
interface myInterface #(parameter assertType = "TYPE0") ();
...
// NOTE: This is NOT inside any process block (like always, initial, etc)
case (assertType)
"TYPE0": begin
`include "assert_type0.sv"
end
"TYPE1": begin
`include "assert_type1.sv"
end
"TYPE2": begin
`include "assert_type2.sv"
end
endcase
...
endinterface
In the above, during compilation, all the assertion code from all the files will be included, but the only ones to take affect will be those included in the file from branch of the case specified by the parameter, and the others will be left uninstantiated.

Does UVM support nested/inner classes?

The code guideline for our verification environment is one class per file.
Sometimes a uvm_object is only needed by 1 other uvm_component, so, following object-oriented theory, we should use nested/inner classes.
Nested classes are fully supported by SystemVerilog. However, are they supported by UVM?
Is it possible to compile something like the following:
class inception_level_1 extends uvm_test;
`uvm_component_utils(inception_level_1)
function new(string name = "inception_level_1", uvm_component parent = null);
super.new(name, parent);
endfunction
class inception_level_2 extends uvm_object;
int a;
`uvm_object_utils_begin(inception_level_2)
`uvm_field_int(a, UVM_DEFAULT)
`uvm_object_utils_end
function new(string name = "inception_level_2");
super.new(name);
endfunction
endclass
endclass
Currently the above code gives a compile error:
** Error: testbench.sv(20): (vlog-2889) Illegal to access non-static method 'uvm_report_warning' outside its class scope.
Full code example here: http://www.edaplayground.com/x/3r8
SystemVerilog has packages, which is the preferred mechanism to "hide" class declarations from other packages.
You will have problems using the field macros, or anything else that tries to reference identifiers from inside the inner class that are defined with the same name in both the global uvm_pkg and the outer class. All the uvm_report_... methods are defined in both because uvm_component is extended from uvm_report_object, and uvm_report_... is in the global uvm_pkg.
You will also have problems using the factory with nested classes. Only the outer class will be able to provide overrides by type, but string based overrides by name are global. So even if you nested the inner class, scopes other than the outer class will be able to provide it as an override by string name.
I changed the code to remove the field macros and this runs. So it seems like this is supported if you can give up the field automation macros: http://www.edaplayground.com/x/i5
class inception_level_1 extends uvm_test;
`uvm_component_utils(inception_level_1)
function new(string name = "inception_level_1", uvm_component parent = null);
super.new(name, parent);
endfunction
class inception_level_2 extends uvm_object;
int a;
`uvm_object_utils(inception_level_2)
function new(string name = "inception_level_2");
super.new(name);
endfunction
endclass
endclass
in general it does work. however there are situations where UVM uses shortcuts which conflict with the class-in-class scenario. examples are
string based factory (inception_level_2 can only be registered once despite that foo:inception_level_2 and bla::inception_level_2 would be different classes)
name lookup collision (here for uvm_report_warning which should goto uvm_pkg::uvm_report_warning and not to the enclosing class uvm_component::uvm_report_warning)
... etc