Specman e subtyping: How to refer to FALSE value of conditional field in when/extend subtyping? - specman

I have a unit my_unit with a boolean field my_bool. I need to add a specific logic to my_unit when my_bool == FALSE. Is it possible?
unit my_unit {
my_bool : bool;
when my_bool {
// Works fine, I can add logic to my_unit
};
when not my_bool {
// This causes compilation error!!!
// Here I need to add another logic
};
};
Is there a way to do it? Thank you for your help

The compiler seems to be treating when my_bool as when TRUE'my_bool. If you want to write code for the when the variable is FALSE, you can write:
unit my_unit {
// ...
when FALSE'my_bool {
// ...
};
};

Related

How to accept both ref and non ref values as a function argument

I want to take any kind of values inside a function (r/lvalue) and I also want to ensure that the value will not be mutated in the scope of the function, even if the value itself is not a const.
struct Tree(T) {
T item;
Tree!T* parent, left, right;
this(T item) {
this.item = item;
}
Tree!T* searchTree(const ref T item) {
if (&this is null)
return null;
if (this.item == item)
return &this;
return (this.item < item) ? this.right.searchTree(item) : this.right.searchTree(item);
}
}
unittest {
auto text1 = "Hello", text2 = "World";
auto tree2 = Tree!string(text1);
assert(tree2.searchTree(text2) is null);
assert(tree2.searchTree(text1) !is null);
}
This works with ref parameters however if I give int literals to the function, it fails:
auto tree1 = Tree!int(4);
assert(tree1.searchTree(5) is null);
assert(tree1.searchTree(4) !is null);
Templates to the rescue! D has a feature called auto ref that automatically generates the overloads for ref and non-ref parameters. The only requirement is that the function must be a template.
For your searchTree function, that means it needs to have this signature:
Tree!T* searchTree()(const auto ref T item)
With that simple change, your code should compile and do The Right Thing™.
there is currently an experimental compiler switch for DMD that allows this.
try adding "-preview=rvaluerefparam" to your compiler switches.

Specman macros: How to use optional tags?

I have a macro for defining ports:
-- Create simple port
define <p_def'struct_member> "p_def <name'name> <type'type>" as {
<name'name> : inout simple_port of <type'type> is instance;
keep bind(<name'name>,empty);
};
I would like to extend the macro to support a list of ports. I would like to use for it an optional tag [<len'name>] that defines the list size, something like this:
-- Create simple port OR list of simple ports
define <p_def'struct_member> "p_def <name'name> [\[<len'name>\] ] <type'type>" as {
if len does not exist { // How to implement it?
<name'name> : inout simple_port of <type'type> is instance;
keep bind(<name'name>,empty);
} else { // len exists
<name'name>[<len'name>] : list of inout simple_port of <type'type> is instance;
keep for each in <name'name> {
bind(it,empty);
};
};
};
** For example, defining a list of ports of size 10 will look this way:
p_def my_list_of_ports[10] bit;
I cannot find in Specman e Language Reference how can I know if the optional tag ([<len'name>]) is defined or not.. Do you know how to implement the "if len does not exist" statement in macro?
Thank you for your help
In case someone is interested what is the answer:
define <p_def'struct_member> "p_def <name'name>[\[<len'name>\]] <type'type>" as computed {
if <len'name> == NULL {
result = appendf("%s : inout simple_port of %s is instance; \n keep bind(%s,empty);", <name'name>, <type'type>, <name'name>);
} else { // list
result = appendf("%s[%s] : list of inout simple_port of %s is instance; keep for each in %s { bind(it,empty); };", <name'name>, <len'name>, <type'type>, <name'name>);
};
};

Idiomatic way to check for parameter initialization

I have a variable param which has to be initialized at runtime.
Then, I have a part of the code which implements the following:
if (param has been initialized)
...do something...
else
print error and exit
What is the most idiomatic way to do this in Scala?
So far I have used Option[X] in this way:
var param : Option[TheType] = None
...
val param_value : TheType = x getOrElse {println("Error"); null}
But, since I have to return null it seems dirty.
How should I do it?
Simply map or foreach over it:
param.foreach { param_value =>
// Do everything you need to do with `param_value` here
} getOrElse sys.exit(3) # Param was empty, kill the program
You can also use the for comprehension style:
for {
param_value <- param
} yield yourOperation(param_value)
The upside of this is that if your calling code is expecting to do something with param_value as a return value from yourMethod you will encode the possibility of param_value not existing in your return type (it will be an Option[TheType] rather than a potentially null TheType.)
I might me wrong but it seems to me that the use of Future would fit with your problem: Instead of explicitly checking whether your required param_value has been initialized and finish the program if not, you could make your resource dependent code to execute when the resource has been rightly initialized:
val param: Future[TheType] = future {
INITIALIZATION CODE HERE
}
param onFailure {
case e => println("Error!");
}
param onSuccess {
case param_value: TheType => {
YOUR BUSINESS CODE HERE
}
}

how to setup a for loop inside if statement with correct syntax Play framework Scala Template

I am trying to setup a variable in the scala template. Loop through the roles that user have , if found out the user is customer , then do something with the input. If not then do something else.
But scala isnt that simple , it won't compile on following code.
#var = #{ if(user != null){
#for(role <- user.roles.filter(_.getName()=="customer")) {
var=#customer(input)
}
}
}
#if( var == null){
var=#others(input)
}
It gives me two errors
t.scala.html:275:: identifier expected but 'for' found.
[error] #for(role <- user.roles.filter(_.getName()=="customer"))
t.scala.html:278: expected start of definition
Also , is there a better way to do this in scala ? Thanks
My reference : Scala template set variable
Update:
My goal was trying to do something like below , but in scala template:
result=null
for role in User.roles:
if(role == "customer"):
result=customer(xyz)
break
if(result==null):
result = others(xyz)
To set up a for loop inside of an if statement in a Scala template, you don't need to assign a variable. You can simply use an if block in the template where you want to display stuff. For example
#if(user != null) {
#for(role <- user.roles.filter(_.getName()=="customer")) {
#customer(input)
#* Do other stuff related to 'role' and 'input' here *#
}
} else {
#* Do something else *#
}
For further reference I encourage you to look at the documentation for Play templates. If you really want to define a variable you could do it using the defining helper:
#defining(user.getFirstName() + " " + user.getLastName()) { fullName =>
<div>Hello #fullName</div>
}
Instead of defining a variable you could also define a resusable block, which might be useful in your case. For example,
#customer_loop(input: String) = {
#if(user != null) {
#for(role <- user.roles.filter(_.getName()=="customer")) {
#customer(input)
#* Do other stuff related to 'role' and 'input' here *#
}
} else {
#* Do something else *#
}
}
To declare a variable do
#import scala.Any; var result:Any=null //where Any is the datatype accoding to your requirement
To reassign its value do
#{result = "somevalue"}
So the solution accoding to the pseudo you provided
#import java.lang.String; var result:String=null
#import scala.util.control._;val loop = new Breaks;
#loop.breakable {
#for(role <- roleList) {
#if(role.equals("customer")) {
#{
result = "somevalue"
}
#{loop.break};
}
}
}
#if(result==null){
#{result="notfound"}
}
Also check Similar1,Similar2

specman: Assign multiple struct member in one expression

Hy,
I expanding an existing specman test where some code like this appears:
struct dataset {
!register : int (bits:16);
... other members
}
...
data : list of dataset;
foo : dataset;
gen foo;
foo.register = 0xfe;
... assign other foo members ...
data.push(foo.copy());
is there a way to assign to the members of the struct in one line? like:
foo = { 0xff, ... };
I currently can't think of a direct way of setting all members as you want, but there is a way to initialize variables (I'm not sure if it works on struct members as well). Anyway something like the following may fit for you:
myfunc() is {
var foo : dataset = new dataset with {
.register = 0xff;
.bar = 0xfa;
}
data.push(foo.copy());
}
You can find more information about new with help new struct from the specman prompt.
Hope it helps!
the simple beuty of assigning fields by name is one language feature i've always found usefull , safe to code and readable.
this is how i'd go about it:
struct s {
a : int;
b : string;
c : bit;
};
extend sys {
ex() is {
var s := new s with {.a = 0x0; .b = "zero"; .c = 0;};
};
run() is also {
var s;
gen s keeping {.a == 0x0; .b == "zero"; .c == 0;};
};
};
i even do data.push(new dataset with {.reg = 0xff; bar = 0x0;}); but you may raise the readablity flag if you want.
warning: using unpack() is perfectly correct (see ross's answer), however error prone IMO. i recommend to verify (with code that actually runs) every place you opt to use unpack().
You can directly use the pack and unpack facility of Specman with "physical fields" ( those instance members prefixed with the modifier %).
Example:
define FLOODLES_WIDTH 47;
type floodles_t : uint(bits:FLOODLES_WIDTH);
define FLABNICKERS_WIDTH 28;
type flabnickers_t : uint(bits:FLABNICKERS_WIDTH);
struct foo_s {
%!floodle : floodles_t;
%!flabnicker : flabnickers_t;
};
extend sys {
run() is also {
var f : foo_s = new;
unpack(packing.low,64'hdeadbeefdeadbeef,f);
print f;
unpack(packing.low,64'hacedacedacedaced,f);
print f;
};
setup() is also {
set_config(print,radix,hex);
};
};
When this run, it prints:
Loading /nfs/pdx/home/rbroger1/tmp.e ...
read...parse...update...patch...h code...code...clean...
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
f = foo_s-#0: foo_s of unit: sys
---------------------------------------------- #tmp
0 !%floodle: 0x3eefdeadbeef
1 !%flabnicker: 0x001bd5b
f = foo_s-#0: foo_s of unit: sys
---------------------------------------------- #tmp
0 !%floodle: 0x2cedacedaced
1 !%flabnicker: 0x00159db
Look up packing, unpacking, physical fields, packing.low, packing.high in your Specman docs.
You can still use physical fields even if the struct doesn't map to the DUT. If your struct is already using physical fields for some other purpose then you'll need to pursue some sort of set* method for that struct.