Menu
In the interview he asked one question “What is difference between Test Case and Test Scenarios” then that guy was confused on the answering the question and unable to answer question properly. So I thought to shed some light on basic software testing terminologies.
UVM TESTBENCH
Uvm components, uvm env and uvm test are the three main building blocks of a testbench in uvm based verification.
Uvm_env
uvm_env is extended from uvm_component and does not contain any extra functionality. uvm_env is used to create and connect the uvm_components like driver, monitors , sequeners etc. A environment class can also be used as sub-environment in another environment. As there is no difference between uvm_env and uvm_component , we will discuss about uvm_component, in the next section.
Verification Components
uvm verification component classes are derived from uvm_component class which provides features like hierarchy searching, phasing, configuration , reporting , factory and transaction recording.
Following are some of the uvm component classes
uvm_agent
uvm_monitor
uvm_scoreboard
uvm_driver
uvm_sequencer
NOTE: uvm_env and uvm_test are also extended from uvm_component.
A typical uvm verification environment:
An agent typically contains three subcomponents: a driver, sequencer, and monitor. If the agent is active, subtypes should contain all three subcomponents. If the agent is passive, subtypes should contain only the monitor.
About Uvm_component Class:
uvm_compoenent class is inherited from uvm_report_object which is inherited from uvm_object.
As I mentioned previously, uvm_component class provides features like hierarchy searching, phasing, configuration , reporting , factory and transaction recording.
We will discuss about phasing concept in this section and rest of the features will be discussed as separate topics.
(S)UVM phases
UVM Components execute their behavior in strictly ordered, pre-defined phases. Each phase is defined by its own virtual method, which derived components can override to incorporate component-specific behavior. By default , these methods do nothing.
-->virtualfunctionvoid build()
This phase is used to construct various child components/ports/exports and configures them.
-->virtualfunctionvoid connect()
This phase is used for connecting the ports/exports of the components.
-->virtualfunctionvoid end_of_elaboration()
This phase is used for configuring the components if required.
-->virtualfunctionvoid start_of_simulation()
This phase is used to print the banners and topology.
-->virtualtask run()
In this phase , Main body of the test is executed where all threads are forked off.
-->virtualfunctionvoid extract()
In this phase, all the required information is gathered.
-->virtualfunctionvoid check()
In this phase, check the results of the extracted information such as un responded requests in scoreboard, read statistics registers etc.
-->virtualfunctionvoid report()
This phase is used for reporting the pass/fail status.
Only build() method is executed in top down manner. i.e after executing parent build() method, child objects build() methods are executed. All other methods are executed in bottom-up manner. The run() method is the only method which is time consuming. The run() method is forked, so the order in which all components run() method are executed is undefined.
Uvm_test
uvm_test is derived from uvm_component class and there is no extra functionality is added. The advantage of used uvm_test for defining the user defined test is that the test case selection can be done from command line option +UVM_TESTNAME=<testcase_string> . User can also select the testcase by passing the testcase name as string to uvm_root::run_test(<testcase_string>) method.
In the above <testcase_string> is the object type of the testcase class.
Lets implement environment for the following topology. I will describe the implementation of environment , testcase and top module. Agent, monitor and driver are implemented similar to environment.
1)Extend uvm_env class and define user environment.
class env extends uvm_env;
2)Declare the utility macro. This utility macro provides the implementation of create() and get_type_name() methods and all the requirements needed for factory.
`uvm_component_utils(env)
3)Declare the objects for agents.
agent ag1;
agent ag2;
4)Define the constructor. In the constructor, call the super methods and pass the parent object. Parent is the object in which environment is instantiated.
functionnew(stringname, uvm_component parent =null);
super.new(name, parent);
endfunction:new
5)Define build method. In the build method, construct the agents.
To construct agents, use create() method. The advantage of create() over new() is that when create() method is called, it will check if there is a factory override and constructs the object of override type.
functionvoid build();
super.build();
uvm_report_info(get_full_name(),'Build',UVM_LOW);
ag1 = agent::type_id::create('ag1',this);
ag2 = agent::type_id::create('ag2',this);
endfunction
6)Define connect(),end_of_elaboration(),start_of_simulation(),run(),extract(),check(),report() methods.
Just print a message from these methods, as we dont have any logic in this example to define.
functionvoid connect();
uvm_report_info(get_full_name(),'Connect',UVM_LOW);
endfunction
(S)Complete code of environment class:
class env extends uvm_env;
`uvm_component_utils(env)
agent ag1;
agent ag2;
functionnew(stringname, uvm_component parent);
super.new(name, parent);
endfunction
functionvoid build();
uvm_report_info(get_full_name(),'Build',UVM_LOW);
ag1 = agent::type_id::create('ag1',this);
ag2 = agent::type_id::create('ag2',this);
endfunction
functionvoid connect();
uvm_report_info(get_full_name(),'Connect',UVM_LOW);
endfunction
functionvoid end_of_elaboration();
uvm_report_info(get_full_name(),'End_of_elaboration',UVM_LOW);
endfunction
functionvoid start_of_simulation();
uvm_report_info(get_full_name(),'Start_of_simulation',UVM_LOW);
endfunction
task run();
uvm_report_info(get_full_name(),'Run',UVM_LOW);
endtask
functionvoid extract();
uvm_report_info(get_full_name(),'Extract',UVM_LOW);
endfunction
functionvoid check();
uvm_report_info(get_full_name(),'Check',UVM_LOW);
endfunction
functionvoid report();
uvm_report_info(get_full_name(),'Report',UVM_LOW);
endfunction
endclass
Now we will implement the testcase.
1)Extend uvm_test and define the test case
class test1 extends uvm_test;
2)Declare component ustilits using utility macro.
`uvm_component_utils(test1)
2)Declare environment class handle.
env t_env;
3)Define constructor method. In the constructor, call the super method and construct the environment object.
functionnew(stringname='test1', uvm_component parent=null);
super.new(name, parent);
t_env =new('t_env',this);
endfunction:new
4)Define the end_of_elaboration method. In this method, call the print() method. This print() method will print the topology of the test.
functionvoid end_of_elaboration();
uvm_report_info(get_full_name(),'End_of_elaboration',UVM_LOW);
print();
endfunction
4)Define the run method and call the global_stop_request() method.
task run ();
#1000;
global_stop_request();
endtask: run
(S)Testcase source code:
class test1 extends uvm_test;
`uvm_component_utils(test1)
env t_env;
functionnew(stringname='test1', uvm_component parent=null);
super.new(name, parent);
t_env =new('t_env',this);
endfunction:new
functionvoid end_of_elaboration();
uvm_report_info(get_full_name(),'End_of_elaboration',UVM_LOW);
print();
endfunction
task run ();
#1000;
global_stop_request();
endtask: run
endclass
Top Module:
To start the testbench, run_test() method must be called from initial block.
Run_test() mthod Phases all components through all registered phases.
module top;
initial
run_test();
endmodule
(S)Download the source code
uvm_phases.tar
Browse the code in uvm_phases.tar
(S)Command to run the simulation
VCS Users : make vcs
Questa Users: make questa
(S)Log file:
[RNTST] Running test test1...
uvm_test_top.t_env [uvm_test_top.t_env] Build
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Build
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Build
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Build
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Build
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Build
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Build
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Connect
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Connect
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Connect
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Connect
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Connect
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Connect
uvm_test_top.t_env [uvm_test_top.t_env] Connect
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] End_of_elaboration
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] End_of_elaboration
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] End_of_elaboration
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] End_of_elaboration
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] End_of_elaboration
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] End_of_elaboration
uvm_test_top.t_env [uvm_test_top.t_env] End_of_elaboration
uvm_test_top [uvm_test_top] End_of_elaboration
----------------------------------------------------------------------
Name Type Size Value
----------------------------------------------------------------------
uvm_test_top test1 - uvm_test_top@2
t_env env - t_env@4
ag1 agent - ag1@6
drv driver - drv@12
rsp_port uvm_analysis_port - rsp_port@16
sqr_pull_port uvm_seq_item_pull_+ - sqr_pull_port@14
mon monitor - mon@10
ag2 agent - ag2@8
drv driver - drv@20
rsp_port uvm_analysis_port - rsp_port@24
sqr_pull_port uvm_seq_item_pull_+ - sqr_pull_port@22
mon monitor - mon@18
uvm_test_top.t_env.ag1.drv[uvm_test_top.t_env.ag1.drv]Start_of_simulation
uvm_test_top.t_env.ag1.mon[uvm_test_top.t_env.ag1.mon]Start_of_simulation
uvm_test_top.t_env.ag1[uvm_test_top.t_env.ag1]Start_of_simulation
uvm_test_top.t_env.ag2.drv[uvm_test_top.t_env.ag2.drv]Start_of_simulation
uvm_test_top.t_env.ag2.mon[uvm_test_top.t_env.ag2.mon]Start_of_simulatio
..
..
..
..
Observe the above log report:
1)Build method was called in top-down fashion. Look at the following part of message.
uvm_test_top.t_env [uvm_test_top.t_env] Build
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Build
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Build
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Build
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Build
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Build
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Build
2)Connect method was called in bottopm up fashion. Look at the below part of log file,
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Connect
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Connect
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Connect
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Connect
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Connect
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Connect
uvm_test_top.t_env [uvm_test_top.t_env] Connect
3)Following part of log file shows the testcase topology.
Uvm components, uvm env and uvm test are the three main building blocks of a testbench in uvm based verification.
Uvm_env
uvm_env is extended from uvm_component and does not contain any extra functionality. uvm_env is used to create and connect the uvm_components like driver, monitors , sequeners etc. A environment class can also be used as sub-environment in another environment. As there is no difference between uvm_env and uvm_component , we will discuss about uvm_component, in the next section.
Verification Components
uvm verification component classes are derived from uvm_component class which provides features like hierarchy searching, phasing, configuration , reporting , factory and transaction recording.
Following are some of the uvm component classes
uvm_agent
uvm_monitor
uvm_scoreboard
uvm_driver
uvm_sequencer
NOTE: uvm_env and uvm_test are also extended from uvm_component.
A typical uvm verification environment:
An agent typically contains three subcomponents: a driver, sequencer, and monitor. If the agent is active, subtypes should contain all three subcomponents. If the agent is passive, subtypes should contain only the monitor.
About Uvm_component Class:
uvm_compoenent class is inherited from uvm_report_object which is inherited from uvm_object.
As I mentioned previously, uvm_component class provides features like hierarchy searching, phasing, configuration , reporting , factory and transaction recording.
We will discuss about phasing concept in this section and rest of the features will be discussed as separate topics.
(S)UVM phases
UVM Components execute their behavior in strictly ordered, pre-defined phases. Each phase is defined by its own virtual method, which derived components can override to incorporate component-specific behavior. By default , these methods do nothing.
-->virtualfunctionvoid build()
This phase is used to construct various child components/ports/exports and configures them.
-->virtualfunctionvoid connect()
This phase is used for connecting the ports/exports of the components.
-->virtualfunctionvoid end_of_elaboration()
This phase is used for configuring the components if required.
-->virtualfunctionvoid start_of_simulation()
This phase is used to print the banners and topology.
-->virtualtask run()
In this phase , Main body of the test is executed where all threads are forked off.
-->virtualfunctionvoid extract()
In this phase, all the required information is gathered.
-->virtualfunctionvoid check()
In this phase, check the results of the extracted information such as un responded requests in scoreboard, read statistics registers etc.
-->virtualfunctionvoid report()
This phase is used for reporting the pass/fail status.
Only build() method is executed in top down manner. i.e after executing parent build() method, child objects build() methods are executed. All other methods are executed in bottom-up manner. The run() method is the only method which is time consuming. The run() method is forked, so the order in which all components run() method are executed is undefined.
Uvm_test
uvm_test is derived from uvm_component class and there is no extra functionality is added. The advantage of used uvm_test for defining the user defined test is that the test case selection can be done from command line option +UVM_TESTNAME=<testcase_string> . User can also select the testcase by passing the testcase name as string to uvm_root::run_test(<testcase_string>) method.
In the above <testcase_string> is the object type of the testcase class.
Lets implement environment for the following topology. I will describe the implementation of environment , testcase and top module. Agent, monitor and driver are implemented similar to environment.
1)Extend uvm_env class and define user environment.
class env extends uvm_env;
2)Declare the utility macro. This utility macro provides the implementation of create() and get_type_name() methods and all the requirements needed for factory.
`uvm_component_utils(env)
3)Declare the objects for agents.
agent ag1;
agent ag2;
4)Define the constructor. In the constructor, call the super methods and pass the parent object. Parent is the object in which environment is instantiated.
functionnew(stringname, uvm_component parent =null);
super.new(name, parent);
endfunction:new
5)Define build method. In the build method, construct the agents.
To construct agents, use create() method. The advantage of create() over new() is that when create() method is called, it will check if there is a factory override and constructs the object of override type.
functionvoid build();
super.build();
uvm_report_info(get_full_name(),'Build',UVM_LOW);
ag1 = agent::type_id::create('ag1',this);
ag2 = agent::type_id::create('ag2',this);
endfunction
6)Define connect(),end_of_elaboration(),start_of_simulation(),run(),extract(),check(),report() methods.
Just print a message from these methods, as we dont have any logic in this example to define.
functionvoid connect();
uvm_report_info(get_full_name(),'Connect',UVM_LOW);
endfunction
(S)Complete code of environment class:
class env extends uvm_env;
`uvm_component_utils(env)
agent ag1;
agent ag2;
functionnew(stringname, uvm_component parent);
super.new(name, parent);
endfunction
functionvoid build();
uvm_report_info(get_full_name(),'Build',UVM_LOW);
ag1 = agent::type_id::create('ag1',this);
ag2 = agent::type_id::create('ag2',this);
endfunction
functionvoid connect();
uvm_report_info(get_full_name(),'Connect',UVM_LOW);
endfunction
functionvoid end_of_elaboration();
uvm_report_info(get_full_name(),'End_of_elaboration',UVM_LOW);
endfunction
functionvoid start_of_simulation();
uvm_report_info(get_full_name(),'Start_of_simulation',UVM_LOW);
endfunction
task run();
uvm_report_info(get_full_name(),'Run',UVM_LOW);
endtask
functionvoid extract();
uvm_report_info(get_full_name(),'Extract',UVM_LOW);
endfunction
functionvoid check();
uvm_report_info(get_full_name(),'Check',UVM_LOW);
endfunction
functionvoid report();
uvm_report_info(get_full_name(),'Report',UVM_LOW);
endfunction
endclass
Now we will implement the testcase.
1)Extend uvm_test and define the test case
class test1 extends uvm_test;
2)Declare component ustilits using utility macro.
`uvm_component_utils(test1)
2)Declare environment class handle.
env t_env;
3)Define constructor method. In the constructor, call the super method and construct the environment object.
functionnew(stringname='test1', uvm_component parent=null);
super.new(name, parent);
t_env =new('t_env',this);
endfunction:new
4)Define the end_of_elaboration method. In this method, call the print() method. This print() method will print the topology of the test.
functionvoid end_of_elaboration();
uvm_report_info(get_full_name(),'End_of_elaboration',UVM_LOW);
print();
endfunction
4)Define the run method and call the global_stop_request() method.
task run ();
#1000;
global_stop_request();
endtask: run
(S)Testcase source code:
class test1 extends uvm_test;
`uvm_component_utils(test1)
env t_env;
functionnew(stringname='test1', uvm_component parent=null);
super.new(name, parent);
t_env =new('t_env',this);
endfunction:new
functionvoid end_of_elaboration();
uvm_report_info(get_full_name(),'End_of_elaboration',UVM_LOW);
print();
endfunction
task run ();
#1000;
global_stop_request();
endtask: run
endclass
Top Module:
To start the testbench, run_test() method must be called from initial block.
Run_test() mthod Phases all components through all registered phases.
module top;
initial
run_test();
endmodule
(S)Download the source code
uvm_phases.tar
Browse the code in uvm_phases.tar
(S)Command to run the simulation
VCS Users : make vcs
Questa Users: make questa
(S)Log file:
[RNTST] Running test test1...
uvm_test_top.t_env [uvm_test_top.t_env] Build
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Build
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Build
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Build
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Build
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Build
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Build
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Connect
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Connect
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Connect
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Connect
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Connect
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Connect
uvm_test_top.t_env [uvm_test_top.t_env] Connect
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] End_of_elaboration
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] End_of_elaboration
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] End_of_elaboration
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] End_of_elaboration
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] End_of_elaboration
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] End_of_elaboration
uvm_test_top.t_env [uvm_test_top.t_env] End_of_elaboration
uvm_test_top [uvm_test_top] End_of_elaboration
----------------------------------------------------------------------
Name Type Size Value
----------------------------------------------------------------------
uvm_test_top test1 - uvm_test_top@2
t_env env - t_env@4
ag1 agent - ag1@6
drv driver - drv@12
rsp_port uvm_analysis_port - rsp_port@16
sqr_pull_port uvm_seq_item_pull_+ - sqr_pull_port@14
mon monitor - mon@10
ag2 agent - ag2@8
drv driver - drv@20
rsp_port uvm_analysis_port - rsp_port@24
sqr_pull_port uvm_seq_item_pull_+ - sqr_pull_port@22
mon monitor - mon@18
uvm_test_top.t_env.ag1.drv[uvm_test_top.t_env.ag1.drv]Start_of_simulation
uvm_test_top.t_env.ag1.mon[uvm_test_top.t_env.ag1.mon]Start_of_simulation
uvm_test_top.t_env.ag1[uvm_test_top.t_env.ag1]Start_of_simulation
uvm_test_top.t_env.ag2.drv[uvm_test_top.t_env.ag2.drv]Start_of_simulation
uvm_test_top.t_env.ag2.mon[uvm_test_top.t_env.ag2.mon]Start_of_simulatio
..
..
..
..
Observe the above log report:
1)Build method was called in top-down fashion. Look at the following part of message.
uvm_test_top.t_env [uvm_test_top.t_env] Build
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Build
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Build
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Build
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Build
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Build
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Build
2)Connect method was called in bottopm up fashion. Look at the below part of log file,
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Connect
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Connect
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Connect
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Connect
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Connect
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Connect
uvm_test_top.t_env [uvm_test_top.t_env] Connect
3)Following part of log file shows the testcase topology.
When adding a new file to a VB.Net project in Visual Studio, I'm given the option of both a 'Class' and a 'Module'. A class is described as
While a module is described as
This seems to imply that a module is less useful that a class, since a class can store groups of functions and more.
Is it the case that a module is simply a group of functions, or is there more to the module than the visual studio documentation suggests?
StephenStephen12622 gold badges44 silver badges1010 bronze badges
5 Answers
A class is a type. You can use this type like any other type (
String
, Integer
, Date
, FileInfo
...) to declare variables, parameters, properties and function return types.Let's make a little example:
Now you can declare variables of type
Person
Whereas modules are static. I.e. Data stored in a module exists exactly once. On the other hand, you don't have to instantiate a module with
New
, therefore they are often used to store global data and for methods that are available globally. For instance you could store the persons list in a module.But there is much more you can do with classes. You can derive a class from a base class. This new class inherits everything from the base class and can add more stuff to it. For instance you could derive an
Employee
class from Person
The
Overridable
keyword in Person.Print
allows deriving classes to re-define (to override) the Print
method. (Functions and Subs in classes are called methods.)Employees are assignment compatible to Persons. You could add an employee to the
persons
list. This does not require any change in the For Each loop, i.e., the call of person.Print()
automatically calls the right Print
method (the first one for 'normal' persons and the second one for employees).There is much more to say about classes. I hope that you got a certain idea of what you can do with classes.
Olivier Jacot-DescombesOlivier Jacot-Descombes72k1010 gold badges9696 silver badges145145 bronze badges
A class is more of a unit, and a module is essentially a loose collection of stuff like functions, variables, or even classes.
In a public module, classes in the project have access to the functions and variables of the module. You don't have to specify the module name to address one. You can also have classes in a module.
The variables and functions of a class are under tighter 'ownership' by the class. Public variables and functions (methods) used by other classes are used with the classname:
classname.method
, unlike those in modules.There is only one instance of a module, but a one or more instances of a class can be used at once.
xpdaxpda13.2k88 gold badges4444 silver badges7373 bronze badges
A module is nothing more than another name for a static class.
That's all there is to it.
If you don't believe it, compile a module with VB.NET and decompile with ILSpy using C-Sharp.
That's all there is to it.
If you don't believe it, compile a module with VB.NET and decompile with ILSpy using C-Sharp.
And yes, that means you're correct, in terms of functionality, a module is a SUBset of a class.
It follows, that in terms of functionality, a class is a SUPERset of a module, because it can contain static as well as non-static methods & variables, as well as the virtual and protected access modifiers.
Stefan SteigerStefan SteigerIt follows, that in terms of functionality, a class is a SUPERset of a module, because it can contain static as well as non-static methods & variables, as well as the virtual and protected access modifiers.
47.3k5757 gold badges277277 silver badges366366 bronze badges
The main difference between classes and modules is that classes can be instantiated as objects while standard modules cannot. Because there is only one copy of a standard module's data, when one part of your program changes a public variable in a standard module, any other part of the program gets the same value if it then reads that variable. In contrast, object data exists separately for each instantiated object. Another difference is that unlike standard modules, classes can implement interfaces.
Source: http://msdn.microsoft.com/en-us/library/7825002w(en-US,VS.80).aspx
Sven KannenbergSven Kannenberg40111 gold badge77 silver badges1919 bronze badges
Actually, you use classes to create objects. For example in the following .NET console application
Bugsr
is a Rectangle
object:4,17099 gold badges2727 silver badges3737 bronze badges
Mahdi JaziniMahdi Jazini