Parameterized Modules (SystemVerilog) - boolean

I have read the book "Digital Design and Computers Architecture" by David Harris and I have a question about SystemVerilog examples in this book. After the introduction in the "parameterized construction", which is # (parameter ...), this operator is used almost in every example.
For example, the "subtractor" module from this book:
module subtractor #(parameter N = 8)
(input logic [N - 1:0] a,b,
output logic [N - 1:0] y);
assign y = a - b;
endmodule
What's the reason of using N in this code?
Can't we just write the following?:
input logic [7:0] a,b,
output logic [7:0] y);
Moreover, such parameters are used in almost every example further in the book but, as for me, there is no reason for using it. We can set the number of bits directly in square brackets without using additional "parameters".
So, what is the reason of such form of coding above?

The use of parameters serves a number of purposes.
It is always a better programming practice to use a symbolic name associated with a value than using a literal value directly. DATA_WIDTH instead of N would have been a more appropriate example. This documents the meaning of the value.
When a change to that value is needed, you have a single place to make that change, and less chance that you'll miss a change, or change an unintended value.
The use of parameters allows you to re-use the same code in many different places by creating a template and then overriding the parameter values as needed.

Related

Does MATLAB have any set-like datatype?

I am looking for a way to compare finite sequential data with non-deterministic ordering in MATLAB. Basically, what I want is an array, but without imposing an order on the contained elements. If I have the objects
a = [x y z];
and
b = [x z y];
I'd want isequal(a, b) to return true. With arrays, this is not the case. The easy fix would be to sort the entries before comparing them. Unfortunately, in my case the elements are complex objects which cannot easily be mapped to have an unambigious numerical relationship to each other. Another approach would be not to use isequal, but rather a custom comparison function which asserts matching lengths and then simply checks if each element from the first array is contained in the second one. However, in my case the arrays are non-trivially nested inside the structs I am trying to compare via isequal, and it would be quite complicated to write a custom comparison function for the encapsulating structs. Other than this ordering problem, the inbuilt isequal function covers all of my needs, as it correctly handles arbitrarily nested structs with arbitrary fields, so I would really like to avoid writing a complicated custom function for that.
Is there any datatype in MATLAB which allows for the described behavior? Or is there a way to easily build such a custom type? In Java, I could simply write a wrapper class with a custom implementation for the equals method, but there seems to be no such mechanism in MATLAB?
I've found a way to solve my problem elegantly. Contrary to my previously stated belief, MATLAB actually does allow for class-specific overriding of isequal.
classdef CustomType
properties
value
end
methods
function self = CustomType(value)
self.value = value;
end
function equal = isequal(self, other)
if not(isa(other, 'CustomType'))
equal = false;
return;
end
% implement custom comparison rules here
end
end
end
So, I can simply assign the fields in question like this and don't have to change anything else in my code:
a = Set([x y z]); % custom type
...
b = Set([x z y]);
...
isequal(a, b); % true
In my use case, I don't even need the uniqueness property of sets. So I only have to perform order-independent comparison and don't need to waste performance on ensuring unrequired properties. Furthermore, by using a dedicated type, I can differentiate explicitly between fields which have order (i.e. regular arrays) and those which don't, at the moment of assignment.
Another solution might be to overwrite the inbuilt isequal and make it apply custom comparison rules when its arguments are of specific type. However, this would slow down all comparisons in the whole program and make for bad encapsulation. I feel like using a custom type with an overriden isequal is the way to solve this kind of problem. But I still think that sets (and other types of commonly used containers) should be included in the basic repertoire of MATLAB.

Division by zero depending on parameter

I am using the FixedRotation component and get a division by zero error. This happens in a translated expression of the form
var = nominator/fixedRotation.R_rel_inv.T[1,3]
because T[1,3] is 0 for the chosen parameters:
n={0,1,0}
angle=180 deg.
It seems that Openmodelica keeps the symbolic variable and tries to be generic but in this case this leads to division by zero because it chooses to put T[1,3] in the denominator.
What are the modifications in order to tell the compiler that the evaluated values T[1,3] for the compilation shall be considered as if the values were hard coded? R_rel is internally in fixedRotation not defined with Evaluate=true...
Should I use custom version of this block? (when I copy paste the source code to a new model and set the parameters R_rel and R_rel_inv to Evalute=true then the simulation works without division by zero)...
BUT is there a modifier to tell from outside that a parameter shall be Evaluate=true without the need to make a new model?
Any other way to prevent division by zero?
Try propagating the parameter at a higher level and setting annotation(Evaluate=true) on this.
For example:
model A
parameter Real a=1;
end A;
model B
parameter Real aPropagated = 2 annotation(Evaluate=true);
A Ainstance(a=aPropagated);
end B;
I don't understand how the Evaluate annotation should help here. The denominator is obviously zero and this is what shall be in fact treated.
To solve division by zero, there are various possibilities (e.g. to set a particular value for that case or to define a small offset to denominator, you can find examples in the Modelica Standard Library). You can also consider the physical meaning of the equation and handle this accordingly.
Since the denominator depends on a parameter, you can also set an assert() to warn the user there is wrong parameter value.
Btw. R_rel_inv is protected and shall, thus, not be used. Use R_rel instead. Also, to deal with rotation matrices, usage of functions from Modelica.Mechanics.MultiBody.Frames is a preferrable way.
And: to use custom version or own implementation depends on your preferences. Custom version is maintained by the comunity, own version is in your hands.

Coupled variables in hyperparameter optimization in MATLAB

I would like to find optimal hyperparamters for a specific function, I am using bayesopt routine in MATLAB.
I can set the variables to optimize like the following:
a = optimizableVariable('a',[0,1],'Type','integer');
But I have coupled variables, i.e, variables whose value depend on the existence of other variables, e.g., a={0,1}, b={0,1} iff a=1.
Meaning that b has an influence on the function if a==1.
I thought about creating a unique variables that encompasses all the possibilities, i.e., c=1 if a=0, c=2 if a=1,b=0, c=3 if a=1,b=0. The problem is that I am interested in optimizing continuous variables and the above approach does not hold anymore.
I tried something alone the line of
b = a * optimizableVariable('b',[0,1],'Type','integer');
But MATLAB threw an error.
Undefined operator '*' for input arguments of type 'optimizableVariable'.
After three months almost to the day, buried deep down in MATLAB documentation, the answer was to use constrained variables.
https://www.mathworks.com/help/stats/constraints-in-bayesian-optimization.html#bvaw2ar

string input to anonymous function in MATLAB

In matlab i know i can convert string into anonymous function with str2func.
For example;
s= '#(x) x.^2';
h= str2func(s);
h(2) would be 4
But what if i do not know the number of unknown? Let's say user of this program will enter lots of function to get a numerical solution of a system. When the user enters x^2, i should add #(x) to its beginning then convert it to a function. But in programming time i do not know how many function the user will enter with how many unknown. #(x) may should be #(x,y) as well as #(x,y,z). If the user enters the number of unknowns, how can i create and add the necessary prefix at runtime?
ps: number of unknown can be any integer number.
You need to know not only the quantity of variables but also their names and order. An expression may read x(c). Even if you know that the expression has two variables in it and are able to parse out x and c, you won't be able to tell if the user intended to define something like #(x, c) x(c), #(c, x) x(c) or even something like #(c, d) x(c) where x is actually a function.
Parsing the expressions just to get the names they use is something that you shouldn't have to do.
Restricting the variable names that are allowed can be messy. If the user is expecting MATLAB syntax and you are parsing as MATLAB, why make your life harder? Also, when you introduce a restriction like one-letter variable names only, you have to ask yourself if there will ever be a situation where you need more than 27 variables.
It would be much safer all around to have the user list the names of the variables they plan on using before the function, e.g. (x, y, pi) pi*(x^2 + y). Now all you have to do is prepend # and not worry about whether pi is a built-in or an argument. In my opinion the notation is quite clean.

Forcing a member of a struct

I am trying to force some internal nodes in my design. One thing I am trying to force is a member of a struct.
When I try to do this:
module struct_force;
struct {
logic a;
logic b;
logic c;} d;
initial begin
force d.a = 1;
$display(d);
end
endmodule
Incisive gives me an error:
Illegal use of a bit-select, part-select, member-select or mda element [9.3.1(IEEE)]
But VCS appears to be happy with it: See EDA playground example
From IEEE-1800 I see this related to force:
The left-hand side of the assignment can be a reference to a singular
variable, a net, a constant bit-select of a vector net, a constant
part-select of a vector net, or a concatenation of these.
I am having trouble parsing that sentence to figure out who is wrong: Is Incisive preventing me from doing something I should be able to do, or is VCS playing fast and loose with the spec?
If this is in fact illegal, what is work around to force just part of a struct?
The key term in the above sentence is singular variable. The variable you are trying to force is an unpacked struct, which is not a singular variable; it is an aggregate variable.
And if you turn it into a packed struct, you run into the sentence that follows the one you quoted: "It shall not be a bit-select or a part-select of a variable..."
Nets are effectively broken down into individual scalar bits whose value is a resolution function of the drivers of that net. A force becomes just another driver of that net.
It's not impossible to add this as an enhancement to the LRM, but a tool would have to break the variable up into individual bits - every regular assignment to that variable would have to be done bit-by bit to check if one of the bits was in a forced state.