how to use assertoff from test to disable assertion in side uvm object - system-verilog

I am looking for way to disable assert in side uvm component for certain test.
Below simple code represent my env, with comment for requirement.
I thought I can use $assertoff.
I can modify uvm component if required additional instrumentation to achieve this.
import uvm_pkg::*;
`include "uvm_macros.svh"
class tb_env extends uvm_component;
`uvm_component_utils(tb_env)
int exp_val = 0;
int act_val = 0;
function new(string name = "tb_env", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual task run_phase (uvm_phase phase);
super.run_phase(phase);
phase.raise_objection(this);
#10us;
ASRT: assert ( exp_val == act_val) else
`uvm_error(get_name(), "Error");
#10us;
`uvm_info(get_name(), "Done env", UVM_LOW);
phase.drop_objection(this);
endtask : run_phase
endclass
program tb_run;
initial
begin
tb_env env = new("env");
// Requirement: Disable assertion env.ASRT with system call $assertoff(...)
fork
run_test();
begin
#5us;
env.exp_val = 1;
end
join
end
endprogram

I would like to make things simple to understand. So, prefer to use some glue logic for suppressing the assertion.
For some simulators, $assertoff works only on modules and not on classes, you can use some guarding flag indicating the enable/disable of assertion. The assertion will be checked only when the flag is set. You can declare this flag anywhere in the base classes and use the same flag in enabling/disabling assertions from different extended classes.
One can also develop a generalized macro for this guarding flag. The following code disables the assertions by the use of a guard. If the guard is a static variable, then it can be accessed via scope resolution (::) also.
import uvm_pkg::*;
`include "uvm_macros.svh"
`define ASSERT(VAL,ERR) \
assert(!assert_guard || (VAL)) else begin // If assert_guard=0, then assertion passes without checking other condition \
`uvm_error(get_name(),ERR); \
end \
class tb_env extends uvm_component;
`uvm_component_utils(tb_env)
bit assert_guard;
int exp_val = 0;
int act_val = 0;
function new(string name = "tb_env", uvm_component parent = null);
super.new(name, parent);
assert_guard = 1; // by default assertions are on
endfunction
virtual task run_phase (uvm_phase phase);
super.run_phase(phase);
phase.raise_objection(this);
#10us;
ASRT: `ASSERT( exp_val == act_val, "Error");
#10us;
`uvm_info(get_name(), "Done env", UVM_LOW);
phase.drop_objection(this);
endtask : run_phase
endclass
module tb_run;
initial begin
tb_env env = new("env");
env.assert_guard = 0;
//tb_env::assert_guard = ; // If assert_guard was static
//$assertoff(0,env.run_phase.ASRT); // Works only for VCS
fork
run_test();
begin
#5us;
env.exp_val = 1;
end
join
end
endmodule
// Output:
UVM_INFO # 0: reporter [RNTST] Running test ...
UVM_INFO testbench.sv(31) # 20000: env [env] Done env
As an alternative approach, one can also make use of disable statement of disabling deffered assertion. But in this case, one needs to know exact time when the assertion is to be fired. Refer to IEEE 1800-2012 Section 16.4.4 for more information about this approach.

Yes you can use $assertoff for your purpose.
Here is your code without $assertoff.
class tb_env;
int exp_val = 0;
int act_val = 0;
virtual task run_phase ();
#10;
ASRT: assert ( exp_val == act_val) else
$error("Error");
endtask : run_phase
endclass
program tb_run;
tb_env env = new();
initial
begin
// $assertoff(0, env.run_phase.ASRT);
fork
env.run_phase();
begin
#5;
env.exp_val = 1;
$display("#%0t : exp_val - %0b, act_val - %0b", $time(), env.exp_val, env.act_val);
end
join
end
endprogram
// Output -
#5 : exp_val - 1, act_val - 0
"a.sv", 7: $unit::\tb_env::run_phase .ASRT: started at 10s failed at 10s
Offending '(this.exp_val == this.act_val)'
Error: "a.sv", 7: $unit.tb_env::run_phase.ASRT: at time 10
Error
$finish at simulation time 10
And here is your code with $assertoff.
class tb_env;
int exp_val = 0;
int act_val = 0;
virtual task run_phase ();
#10;
ASRT: assert ( exp_val == act_val) else
$error("Error");
endtask : run_phase
endclass
program tb_run;
tb_env env = new();
initial
begin
$assertoff(0, env.run_phase.ASRT);
fork
env.run_phase();
begin
#5;
env.exp_val = 1;
$display("#%0t : exp_val - %0b, act_val - %0b", $time(), env.exp_val, env.act_val);
end
join
end
endprogram
// Output -
Stopping new assertion attempts at time 0s: level = 0 arg = $unit::\tb_env::run_phase .ASRT (from inst tb_run (a.sv:17))
#5 : exp_val - 1, act_val - 0
$finish at simulation time 10

The $assertoff system task can turn assertions off in specific modules, but not specific classes or objects. So, you'll have to do it manually by modifying your tb_env class.

Related

Complex DataType in system verilog(hash of queues)

Suppose I declared a queue: axi4_req_txn_t wr_req_queue[$];
Now I want to have a hash of queue, key is the address and data is the pointer to the queue; Is it possible in systemverilog ?
when I write code like this: typedef wr_req_queue waw_hash[*]; the compiler reports that wr_req_queue is not a valid type.
A rule of thumb is to express any complicated struct as a typedef if you want to use in another typedef. So, here is a simple example of array of queues:
package pkg;
typedef int mytype_t; // whatever the type of queue elements
typedef mytype_t queue_type_t[$]; // queue of mytype_t
typedef queue_type_t array_type_t[int]; // associative array of queues
endpackage // pkg
// test the above
module tb;
import pkg::*;
array_type_t arr;
initial begin
arr[0] = {0};
arr[1] = {1};
arr[3] = {arr[0], arr[1]};
$display(arr);
end
endmodule // tb
Or vice versa, queue of arrays:
package pkg;
typedef int/*your type*/ mytype_t;
typedef mytype_t array_type_t[int];
typedef array_type_t queue_type_t[$];
endpackage // pkg
module tb;
import pkg::*;
array_type_t arr;
initial begin
array_type_t arr1, arr2;
queue_type_t que;
arr1[0] = 0;
arr2[0] = 1;
arr2[1] = 2;
que = {arr1};
que = {que,arr2};
$display(que);
end
endmodule // tb

Null Object Access error in system verilog

I am trying to perform binary tree insertion and in order traversal in System Verilog using OOPs concepts. I am getting error that the object is being used before creating it. Please take a look at the code and help me if someone find any mistakes
class node;
byte data;
node left;
node right;
function new();
this.data = data;
this.left = null;
this.right = null;
endfunction
endclass
class bin_search extends node;
node newNode;
node nd,root,current,parent;
byte in_data;
function new();
super.new();
this.in_data = in_data;
endfunction
function automatic insert(in_data);
newNode.data = nd.data;
if(root.data == null) begin
root = newNode;
return;
end
else begin
current = root;
parent = null;
end
forever begin
parent = current;
if(in_data < current.data) begin
current = current.left;
if(current.left == null) begin
parent.left = newNode;
return;
end
end
else begin
current = current.right;
if(current.right == null) begin
parent.right = newNode;
return;
end
end
end
endfunction
function automatic inorder_traverse(node node_tr);
//using nodes here
endfunction
endclass
module binary;
node NODE;
bin_search bs;
byte ins;
initial begin
NODE = new;
bs = new;
bs.insert(50);
$display("Binary search tree after insertion:");
bs.inorder_traverse(bs.root);
end
endmodule
Error message:
Error-[NOA] Null object access
binary.sv, 28
The object at dereference depth 1 is being used before it was
constructed/allocated.
Please make sure that the object is allocated before using it.
The null error is thrown from the following line.
newNode.data = nd.data;
I don't see neither newNode nor nd objects being constructed by calling new() either in constructor of bin_search class or in the insert() method itself.
You need to create objects of classes before accessing their members or methods.

Not getting decreasing gas in a C++ program

Ok, so I have this program that is suppose to simulate an "Uber" driver picking up and dropping off customers and informing him of how far he has driven and how much gas he should have felt. I basically have it all worked out but for the life of me I can't get the gas to go down it stays at a static number. I know it is probably something so simple its dumb but I can't see it.
in my FuelGauge.h
#ifndef FuelGauge_h
#define FuelGauge_h
#define MAXG 15
// Class FuelGauge definition
class FuelGauge
{
// Data member
static int gallons;
public:
// Overloading -- operator
void operator --()
{
--gallons;
}// End of function
// Function to return gallons
int getGallons()
{
return gallons;
}// End of function
};// End of class
// Initializes static data member
int FuelGauge::gallons = MAXG;
#endif /* FuelGauge_hpp */
in my Car.h
#ifndef Car_h
#define Car_h
#include "FuelGauge.h"
#include "Odometer.h"
// Class car definition
class Car
{
public:
// Declares object as data member using deligation
FuelGauge *fg;
Odometer *om;
// Overloads >> operator
friend std::istream & operator >>(std::istream &is, Car &c)
{
int no;
// Loops till valid mileage entered by the user
do
{
// Accepts mileage
std::cin>>no;
// Checks if the mileage is zero or negative show error message
if(no <= 0)
std::cout<<"\n Invalid response, mileage should be greater than 0. \n Please reenter data.";
// Otherwise come out of the loop
else
break;
}while(1);
// Loops till no
for(int x = 0; x < no; x++)
// Increase the mileage by one
++*c.om;
// Checks if the current mileage is greater than or equals to 24 and entered mileage is less than 24
if(c.om->getCurrentMileage() >= 24 && no < 24)
// Decrement by one
--*c.fg;
// Otherwise
else
{
// Calculate the remainder
int rem = (no / 24);
// Loops till remainder
for(int x = 0; x < rem; x++)
// Decrease by one
--*c.fg;
}// End of else
// return istream object
return is;
}// End of function
// Overload << operator
friend std::ostream & operator <<(std::ostream &os, Car &c)
{
// Checks if the current gallon is less than or equals to zero
if(c.fg->getGallons() <= 0)
{
// Display message and stop
std::cout<<"\n Drove "<<c.om->getCurrentMileage()<<" miles I'm out of gas.";
exit(0);
}// End of if condition
// Otherwise display total mileage traveled and fuel left
else
std::cout<<"\n Drove "<<c.om->getCurrentMileage()<<" miles now I have "<<c.fg->getGallons()<<" gallons left.";
return os;
}// End of function
};// End of class
#endif /* Car_hpp */
and lastly Main.cpp
#include<iostream>
#include<stdlib.h>
#include "FuelGauge.h"
#include "Odometer.h"
#include "Car.h"
using namespace std;
// main function definition
int main()
{
int customer = 1;
// Creates car object
Car cc;
// Loops till = 0 fuel available
do
{
// Accepts data and displays data using object
cout<<"\n How far away is customer #"<<customer<<"? ";
cin>>cc;
cout<<cc;
cout<<"\n How far does customer #"<<customer<<" need to go?";
cin>>cc;
cout<<cc;
}while(static_cast<void>(customer++),1);// End of do - while
}// End of main function
I believe that problem is in my FuelGauge.h but I'm not seeing it. If someone would be so kind to look it over and let me know if they see anything I would greatly appreciate it.

order of execution of forked processes

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/sem.h>
#include<sys/ipc.h>
int sem_id;
void update_file(int number)
{
struct sembuf sem_op;
FILE* file;
printf("Inside Update Process\n");
/* wait on the semaphore, unless it's value is non-negative. */
sem_op.sem_num = 0;
sem_op.sem_op = -1; /* <-- Amount by which the value of the semaphore is to be decreased */
sem_op.sem_flg = 0;
semop(sem_id, &sem_op, 1);
/* we "locked" the semaphore, and are assured exclusive access to file. */
/* manipulate the file in some way. for example, write a number into it. */
file = fopen("file.txt", "a+");
if (file) {
fprintf(file, " \n%d\n", number);
fclose(file);
}
/* finally, signal the semaphore - increase its value by one. */
sem_op.sem_num = 0;
sem_op.sem_op = 1;
sem_op.sem_flg = 0;
semop( sem_id, &sem_op, 1);
}
void write_file(char* contents)
{
printf("Inside Write Process\n");
struct sembuf sem_op;
sem_op.sem_num = 0;
sem_op.sem_op = -1;
sem_op.sem_flg = 0;
semop( sem_id, &sem_op, 1);
FILE *file = fopen("file.txt","w");
if(file)
{
fprintf(file,contents);
fclose(file);
}
sem_op.sem_num = 0;
sem_op.sem_op = 1;
sem_op.sem_flg = 0;
semop( sem_id, &sem_op, 1);
}
int main()
{
//key_t key = ftok("file.txt",'E');
sem_id = semget( IPC_PRIVATE, 1, 0600 | IPC_CREAT);
/*here 100 is any arbit number to be assigned as the key of the
semaphore,1 is the number of semaphores in the semaphore set, */
if(sem_id == -1)
{
perror("main : semget");
exit(1);
}
int rc = semctl( sem_id, 0, SETVAL, 1);
pid_t u = fork();
if(u == 0)
{
update_file(100);
exit(0);
}
else
{
wait();
}
pid_t w = fork();
if(w == 0)
{
write_file("Hello!!");
exit(0);
}
else
{
wait();
}
}
If I run the above code as a c code, the write_file() function is called after the update_file () function
Whereas if I run the same code as a c++ code, the order of execution is reverse... why is it so??
Just some suggestions, but it looks to me like it could be caused by a combination of things:
The wait() call is supposed to take a pointer argument (that can
be NULL). Compiler should have caught this, but you must be picking
up another definition somewhere that permits your syntax. You are
also missing an include for sys/wait.h. This might be why the
compiler isn't complaining as I'd expect it to.
Depending on your machine/OS configuration the fork'd process may
not get to run until after the parent yields. Assuming the "wait()"
you are calling isn't working the way we would be expecting, it is
possible for the parent to execute completely before the children
get to run.
Unfortunately, I wasn't able to duplicate the same temporal behavior. However, when I generated assembly files for each of the two cases (C & C++), I noticed that the C++ version is missing the "wait" system call, but the C version is as I would expect. To me, this suggests that somewhere in the C++ headers this special version without an argument is being #defined out of the code. This difference could be the reason behind the behavior you are seeing.
In a nutshell... add the #include, and change your wait calls to "wait(0)"

How to create a class, subclass and properties in Lua?

I'm having a hard time grokking classes in Lua. Fruitless googling led me to ideas about meta-tables, and implied that third-party libraries are necessary to simulate/write classes.
Here's a sample (just because I've noticed I get better answers when I provide sample code):
public class ElectronicDevice
{
protected bool _isOn;
public bool IsOn { get { return _isOn; } set { _isOn = value; } }
public void Reboot(){_isOn = false; ResetHardware();_isOn = true; }
}
public class Router : ElectronicDevice
{
}
public class Modem :ElectronicDevice
{
public void WarDialNeighborhood(string areaCode)
{
ElectronicDevice cisco = new Router();
cisco.Reboot();
Reboot();
if (_isOn)
StartDialing(areaCode);
}
}
Here is my first attempt to translate the above using the technique suggested by Javier.
I took the advice of RBerteig. However, invocations on derived classes still yield: "attempt to call method 'methodName' (a nil value)"
--Everything is a table
ElectronicDevice = {};
--Magic happens
mt = {__index=ElectronicDevice};
--This must be a constructor
function ElectronicDeviceFactory ()
-- Seems that the metatable holds the fields
return setmetatable ({isOn=true}, mt)
end
-- Simulate properties with get/set functions
function ElectronicDevice:getIsOn() return self.isOn end
function ElectronicDevice:setIsOn(value) self.isOn = value end
function ElectronicDevice:Reboot() self.isOn = false;
self:ResetHardware(); self.isOn = true; end
function ElectronicDevice:ResetHardware() print('resetting hardware...') end
Router = {};
mt_for_router = {__index=Router}
--Router inherits from ElectronicDevice
Router = setmetatable({},{__index=ElectronicDevice});
--Constructor for subclass, not sure if metatable is supposed to be different
function RouterFactory ()
return setmetatable ({},mt_for_router)
end
Modem ={};
mt_for_modem = {__index=Modem}
--Modem inherits from ElectronicDevice
Modem = setmetatable({},{__index=ElectronicDevice});
--Constructor for subclass, not sure if metatable is supposed to be different
function ModemFactory ()
return setmetatable ({},mt_for_modem)
end
function Modem:WarDialNeighborhood(areaCode)
cisco = RouterFactory();
--polymorphism
cisco.Reboot(); --Call reboot on a router
self.Reboot(); --Call reboot on a modem
if (self.isOn) then self:StartDialing(areaCode) end;
end
function Modem:StartDialing(areaCode)
print('now dialing all numbers in ' .. areaCode);
end
testDevice = ElectronicDeviceFactory();
print("The device is on? " .. (testDevice:getIsOn() and "yes" or "no") );
testDevice:Reboot(); --Ok
testRouter = RouterFactory();
testRouter:ResetHardware(); -- nil value
testModem = ModemFactory();
testModem:StartDialing('123'); -- nil value
Here's an example literal transcription of your code, with a helpful Class library that could be moved to another file.
This is by no means a canonical implementation of Class; feel free to define your object model however you like.
Class = {}
function Class:new(super)
local class, metatable, properties = {}, {}, {}
class.metatable = metatable
class.properties = properties
function metatable:__index(key)
local prop = properties[key]
if prop then
return prop.get(self)
elseif class[key] ~= nil then
return class[key]
elseif super then
return super.metatable.__index(self, key)
else
return nil
end
end
function metatable:__newindex(key, value)
local prop = properties[key]
if prop then
return prop.set(self, value)
elseif super then
return super.metatable.__newindex(self, key, value)
else
rawset(self, key, value)
end
end
function class:new(...)
local obj = setmetatable({}, self.metatable)
if obj.__new then
obj:__new(...)
end
return obj
end
return class
end
ElectronicDevice = Class:new()
function ElectronicDevice:__new()
self.isOn = false
end
ElectronicDevice.properties.isOn = {}
function ElectronicDevice.properties.isOn:get()
return self._isOn
end
function ElectronicDevice.properties.isOn:set(value)
self._isOn = value
end
function ElectronicDevice:Reboot()
self._isOn = false
self:ResetHardware()
self._isOn = true
end
Router = Class:new(ElectronicDevice)
Modem = Class:new(ElectronicDevice)
function Modem:WarDialNeighborhood(areaCode)
local cisco = Router:new()
cisco:Reboot()
self:Reboot()
if self._isOn then
self:StartDialing(areaCode)
end
end
If you were to stick to get/set methods for properties, you wouldn't need __index and __newindex functions, and could just have an __index table. In that case, the easiest way to simulate inheritance is something like this:
BaseClass = {}
BaseClass.index = {}
BaseClass.metatable = {__index = BaseClass.index}
DerivedClass = {}
DerivedClass.index = setmetatable({}, {__index = BaseClass.index})
DerivedClass.metatable = {__index = DerivedClass.index}
In other words, the derived class's __index table "inherits" the base class's __index table. This works because Lua, when delegating to an __index table, effectively repeats the lookup on it, so the __index table's metamethods are invoked.
Also, be wary about calling obj.Method(...) vs obj:Method(...). obj:Method(...) is syntactic sugar for obj.Method(obj, ...), and mixing up the two calls can produce unusual errors.
There are a number of ways you can do it but this is how I do (updated with a shot at inheritance):
function newRGB(r, g, b)
local rgb={
red = r;
green = g;
blue = b;
setRed = function(self, r)
self.red = r;
end;
setGreen = function(self, g)
self.green= g;
end;
setBlue = function(self, b)
self.blue= b;
end;
show = function(self)
print("red=",self.red," blue=",self.blue," green=",self.green);
end;
}
return rgb;
end
purple = newRGB(128, 0, 128);
purple:show();
purple:setRed(180);
purple:show();
---// Does this count as inheritance?
function newNamedRGB(name, r, g, b)
local nrgb = newRGB(r, g, b);
nrgb.__index = nrgb; ---// who is self?
nrgb.setName = function(self, n)
self.name = n;
end;
nrgb.show = function(self)
print(name,": red=",self.red," blue=",self.blue," green=",self.green);
end;
return nrgb;
end
orange = newNamedRGB("orange", 180, 180, 0);
orange:show();
orange:setGreen(128);
orange:show();
I don't implement private, protected, etc. although it is possible.
If you don't want to reinvent the wheel, there is a nice Lua library implementing several object models. It's called LOOP.
The way I liked to do it was by implementing a clone() function.
Note that this is for Lua 5.0. I think 5.1 has more built-in object oriented constructions.
clone = function(object, ...)
local ret = {}
-- clone base class
if type(object)=="table" then
for k,v in pairs(object) do
if type(v) == "table" then
v = clone(v)
end
-- don't clone functions, just inherit them
if type(v) ~= "function" then
-- mix in other objects.
ret[k] = v
end
end
end
-- set metatable to object
setmetatable(ret, { __index = object })
-- mix in tables
for _,class in ipairs(arg) do
for k,v in pairs(class) do
if type(v) == "table" then
v = clone(v)
end
-- mix in v.
ret[k] = v
end
end
return ret
end
You then define a class as a table:
Thing = {
a = 1,
b = 2,
foo = function(self, x)
print("total = ", self.a + self.b + x)
end
}
To instantiate it or to derive from it, you use clone() and you can override things by passing them in another table (or tables) as mix-ins
myThing = clone(Thing, { a = 5, b = 10 })
To call, you use the syntax :
myThing:foo(100);
That will print:
total = 115
To derive a sub-class, you basically define another prototype object:
BigThing = clone(Thing, {
-- and override stuff.
foo = function(self, x)
print("hello");
end
}
This method is REALLY simple, possibly too simple, but it worked well for my project.
It's really easy to do class-like OOP in Lua; just put all the 'methods' in the __index field of a metatable:
local myClassMethods = {}
local my_mt = {__index=myClassMethods}
function myClassMethods:func1 (x, y)
-- Do anything
self.x = x + y
self.y = y - x
end
............
function myClass ()
return setmetatable ({x=0,y=0}, my_mt)
Personally, I've never needed inheritance, so the above is enough for me. If it's not enough, you can set a metatable for the methods table:
local mySubClassMethods = setmetatable ({}, {__index=myClassMethods})
local my_mt = {__index=mySubClassMethods}
function mySubClassMethods:func2 (....)
-- Whatever
end
function mySubClass ()
return setmetatable ({....}, my_mt)
update:
There's an error in your updated code:
Router = {};
mt_for_router = {__index=Router}
--Router inherits from ElectronicDevice
Router = setmetatable({},{__index=ElectronicDevice});
Note that you initialize Router, and build mt_for_router from this; but then you reassign Router to a new table, while mt_for_router still points to the original Router.
Replace the Router={} with the Router = setmetatable({},{__index=ElectronicDevice}) (before the mt_for_router initialization).
Your updated code is wordy, but should work. Except, you have a typo that is breaking one of the metatables:
--Modem inherits from ElectronicDevice
Modem = setmetatable({},{__index,ElectronicDevice});
should read
--Modem inherits from ElectronicDevice
Modem = setmetatable({},{__index=ElectronicDevice});
The existing fragment made the Modem metatable be an array where the first element was almost certainly nil (the usual value of _G.__index unless you are using strict.lua or something similar) and the second element is ElectronicDevice.
The Lua Wiki description will make sense after you've grokked metatables a bit more. One thing that helps is to build a little infrastructure to make the usual patterns easier to get right.
I'd also recommend reading the chapter on OOP in PiL. You will want to re-read the chapters on tables and metatables too. Also, I've linked to the online copy of the 1st edition, but owning a copy of the 2nd is highly recommended. There is also a couple of articles in the Lua Gems book that relate. It, too, is recommended.
Another simple approach for subclass
local super = require("your base class")
local newclass = setmetatable( {}, {__index = super } )
local newclass_mt = { __index = newclass }
function newclass.new(...) -- constructor
local self = super.new(...)
return setmetatable( self, newclass_mt )
end
You still can use the functions from superclass even if overwritten
function newclass:dostuff(...)
super.dostuff(self,...)
-- more code here --
end
don't forget to use ONE dot when pass the self to the superclass function