In a SystemVerilog UVM testbench, we're randomizing transaction objects, and for some specific tests, we create additional constraints. However those testcase constraints are only used by the randomization engine if you call the testcase randomize() method and not obj.randomize(). This is quite confusing.
I wonder why all constraints on the object are not used regardless of which randomize is called? Why do constraints have a scope?
For example:
class trans;
rand int addr;
constraint addr_c; // Method 1: constraint prototype
function void post_randomize();
$display("addr %d",addr);
endfunction
endclass
//////////////////// Test case code /////////////////
// Method 1: extend constraint prototype addr_c external to test class.
// constraint trans::addr_c { addr > 0 && addr < 10; }
// works but requires prototype, careful if trans is in another package
class my_test;
trans trans1;
// Method 2: Add constraint to the test
constraint test_constraint_c { trans1.addr > 11 && trans1.addr < 20; }
function new();
trans1 = new;
repeat (20) begin
// This doesn't use test_constraint_c (why??)
assert(trans1.randomize()) else $display("TEST", "Randomization Failed");
// This uses test_constraint_c
assert(randomize(trans1)) else $display("TEST", "Randomization Failed");
end
endfunction
endclass
module tb;
my_test test1;
initial test1 = new;
endmodule
You have 2 classes which are unrelated to each other: trans and my_test.
The trans class does not know about the test_constraint_c constraint because the constraint is only part of the my_test class. Thus, when you call the randomize function on the object (trans1.randomize()), it has no constraints to apply.
In the test, when you call the randomize method on the trans1 variable, it will apply any active constraints in the my_test class, namely test_constraint_c.
An alternate approach is to extend the trans class with a new constraint block.
Related
Let's say there is one rand 10-bit variable named data. I want to make sure there won't be 7 consecutive 0s or 1s. Can someone suggest to me how can I constraint in such a way?
constraint c_data
{
foreach(data[i])
{
(data[i] && data[i+7]) == 0;
}
}
But then array will be out of bound when i is greater than 3.
You can add an implication to keep the indexes bounded
parameter width = 7;
constraint c_data
{
foreach(data[i])
{
(i < data.size() - width) -> !(data[i+:width] inside {'0,'1});
}
}
Here is one way to avoid values like 10'b0000000111 or 10'b1111111000:
class foo;
rand bit [9:0] data;
constraint c_data {
!(data[9:3] inside {'0, '1});
!(data[8:2] inside {'0, '1});
!(data[7:1] inside {'0, '1});
!(data[6:0] inside {'0, '1});
}
endclass
module tb;
foo foo;
initial begin
foo = new();
repeat (10_000) begin
if (!foo.randomize()) $error;
$displayb(foo.data);
end
end
endmodule
How can I state (in Dafny) an "ensures" guarantee that the object returned by a method will be "new", i.e., will not be the same as an object used anywhere else (yet)?
The following code shows a minimal example:
method newArray(a:array<int>) returns (b:array<int>)
requires a != null
ensures b != null
ensures a != b
ensures b.Length == a.Length+1
{
b := new int[a.Length+1];
}
class Testing {
var test : array<int>;
method doesnotwork()
requires this.test!=null
requires this.test.Length > 10;
modifies this
{
this.test := newArray(this.test); //change array a with b
this.test[3] := 9; //error modifies clause
}
method doeswork()
requires this.test!=null
requires this.test.Length > 10;
modifies this
{
this.test := new int[this.test.Length+1];
this.test[3] := 9;
}
}
The "doeswork" function compiles (and verifies) correctly, but the other one does not, as the Dafny compiler cannot know that the object returned by the "newArray" function is new, i.e., is not required to be listed as modifiable in the "require" statement of the "doesnotwork" function in order for that function to fulfill the requirement that it only modifies "this". In the "doeswork" function, I simply inserted the definition of the "newArray" function, and then it works.
You can find the example above under https://rise4fun.com/Dafny/hHWwr, where it can also be ran online.
Thanks!
You can say ensures fresh(b) on newArray.
fresh means exactly what you described: the object is not the same as any object that was allocated before the call to newArray.
I've stucked with problems of using reflect library. I descided to use it because of many recomendations, but i'm just learning go and some parts are not really easy..
I've got this part of code :
func countDataByName(sourceName string, statData interface{}, filters Filter, chartName string) []ChartElement {
...
//step 1 - filter
filteredData := reflect.ValueOf(statData).MethodByName("FilterData").Call([]reflect.Value{})
//step 2 - cluster
// clusterData := reflect.ValueOf(filteredData).MethodByName("clusterData").Call([]reflect.Value{})
//step 3 - count
// countedData := reflect.ValueOf(clusterData).MethodByName(chartName).Call([]reflect.Value{})
fmt.Println("Never prints to anywhere", filteredData)
...
return filterData
}
If I execute the method like this, I get error : reflect: Call with too few input arguments. But if I change reflect.ValueOf(statData) on reflect.ValueOf(&statData) than error is reflect: call of reflect.Value.Call on zero Value
statData comes with one of 2 types, and fore this types I have structs and methods, like this :
type NoaggModel struct {
Date string
Hour int
Id_user int
Id_line int
Id_region int
Id_tree_devision int
N_inb int
N_inb_d int
T_ring int
T_inb int
T_inb_d int
T_hold int
T_acw int
T_acw_d int
T_wait int
}
func (ng *NoaggModel) FilterData( data NoaggModel) {
fmt.Println("FilterData")
fmt.Println("data : ", data)
}
this Println also not works. Code panics above , and method was not triggered. Where is my mistake here?
Upd 1:
Found that if I remove param data in functioin that I want to call, than it calls nicely. But!
I have statData as 1 row, of structs, so type is NoaggModel. And in the method FilterData I get this 1 row as ng. But I need to change it to the []NoaggModel. How to call reflect in this case and how to pass parameter to the filter function ?
Upd 2:
I modified few parts :
func (ng *NoaggModel) FilterData(filter interface{}, data NoaggModel) {
fmt.Println("data : ",ng)
}
In here, how to pass correct type to filter, if it is set up in revel controller, and method is in model. Or should I set the type in each model and call it in controller?
And in controller I wrote :
//step 1 - filter
in := make([]reflect.Value, 2)
in[0] = reflect.ValueOf(filters)
in[1] = reflect.ValueOf(statData)
filteredData := reflect.ValueOf(statData).MethodByName("FilterData").Call(in)
StatData is a row of type NoaggModel, but I get the error :
reflect: Call using *models.NoaggModel as type models.NoaggModel
The type was set also by reflect in code above, like this :
...
var sourceTypes = map[string]reflect.Type{
"noagg": reflect.TypeOf(models.NoaggModel{}),
"oracle": reflect.TypeOf(models.OracleModel{}),
}
deserializedData = reflect.New(sourceTypes[sourceName]).Interface()
...
// deserialised becomes statData
Reflection is not easy. And should be avoided if possible.
I admit that I did recommend using reflect to dynamically create instances of types based on a map, which is really useful when you don't know which types you might have to handle. But in your case you should consider using interfaces.
While I don't really know what you want to achieve, I would suggest starting by creating an interface that all your Models need to implement (modify it to fit your needs):
type Model interface {
FilterData(interface{})
}
NoaggModel and OracleModel would then implement the above interface by defining similar methods like this:
func (ng *NoaggModel) FilterData(filter interface{}) {
fmt.Printf("data: %#v, filter: %#v\n", ng, filter)
}
Then, change deserializedData (and statData) to be of the interface type Model instead of interface{}. And since you only have two types, you can avoid using reflect by having a switch instead:
...
var deserializedData Model
switch sourceName {
case "noagg":
deserializedData = new(models.NoaggModel)
case "oracle":
deserializedData = new(models.OracleModel)
}
...
// Marshal the values into deserializedData which now holds an instance of the desired type
...
deserializedData.FilterData("Replace this string with your filter")
And it is done without having to import reflect!
I want to write a generic-width swap, but I'm not sure what the syntax should be.
My first guess:
task automatic swap #( int W=1 ) ( ref logic [W-1:0] a, ref logic [W-1:0] b );
begin
automatic logic[W-1:0] temp=a; a=b; b=temp;
end endtask
But I get the following error (from Cadence irun):
ncvlog: *E,SVNOCS: Class specialization syntax not allowed in method name for out-of-block method declaration.
Also, what is the syntax to invoke such a task?
Tasks and functions cannot have their own parameters. You can achieve the same effect by declaring a static method in a parameterized class. The methods can be made more generic by making the parameter a data type instead of a bit width. Example:
class generic #(type T=logic);
// Note: you may want to replace 'ref' with 'inout'
static function void swap( ref T a, b );
{b,a} = {a,b};
endfunction
endclass
Then somewhere in your code, you can do this like:
generic#(logic[4:0])::swap( my_a, my_b);
generic#(int)::swap( my_int_a, my_int_b);
generic#(my_struct_st)::swap( my_struct_a, my_struct_b);
generic#(my_class)::swap( my_class_a, my_class_b);
generic#(virtural my_interface)::swap( my_if_a, my_if_b);
Both of the reflect.Type interface and reflect.Value type implement the same Kind() method signature, suppose that we have some value object v := reflect.ValueOf(x)
Is v.Kind() just call v.Type().Kind() ?
They contain the same value, but do not seem to refer to the same thing:
type.go source
value.go source
A Type is usually implemented by unexported struct rtype (via TypeOf), while the Value contains a *rtype and extends flag, which is itself a reduced form of the Kind:
// flag holds metadata about the value.
// The lowest bits are flag bits:
// - flagRO: obtained via unexported field, so read-only
// - flagIndir: val holds a pointer to the data
// - flagAddr: v.CanAddr is true (implies flagIndir)
// - flagMethod: v is a method value.
// The next five bits give the Kind of the value.
// This repeats typ.Kind() except for method values.
// The remaining 23+ bits give a method number for method values.
// If flag.kind() != Func, code can assume that flagMethod is unset.
// If typ.size > ptrSize, code can assume that flagIndir is set.
When getting the ValueOf something:
// ValueOf returns a new Value initialized to the concrete value
// stored in the interface i. ValueOf(nil) returns the zero Value.
func ValueOf(i interface{}) Value {
[...]
// For an interface value with the noAddr bit set,
// the representation is identical to an empty interface.
eface := *(*emptyInterface)(unsafe.Pointer(&i))
typ := eface.typ
/** Flag is built from the type, then kept separate (my comment) */
fl := flag(typ.Kind()) << flagKindShift
if typ.size > ptrSize {
fl |= flagIndir
}
return Value{typ, unsafe.Pointer(eface.word), fl}
}
And so when you get the kind of a Value (remember it extends its flag):
func (v Value) Kind() Kind {
return v.kind()
}
func (f flag) kind() Kind {
return Kind((f >> flagKindShift) & flagKindMask)
}
While getting the kind of a type: (Type is an interface, usually implemented by *rtype)
func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
So although they seem to be equal in most of the cases, v.Kind() is not v.Type().Kind()
The file reflect/value.go states that the relevant field in the implementation of reflect.Value "repeats typ.Kind() except for method values". So, unless the value is a method, value.Kind() and value.Type().Kind() return the same number.