Often, I will build Modelica models with parameters that are dependent on other parameters:
model ParameterTest
parameter Real a = 5;
parameter Real b = a/2;
end ParameterTest;
Here, parameter b is no longer available to be parameterized in the compiled model and I've locked in the b=a/2 relationship.
Alternatively, I could have done the following:
model ParameterTest
parameter Real a = 5;
parameter Real b = 5/2;
end ParameterTest;
Here, I've lost some of the traceability and logic for my default value for parameter b and I need to manually maintain/update parameter b if I were to change parameter a in the future. This is a trivial example, but potentially in a more real-world example, the equation set and logic would be more sophisticated to determine parameter b.
While the above behaviors are perfectly logical and expected, what I would often prefer is a 3rd approach that gives me the best of both worlds: specify my default value for parameter b in terms of parameter a, but maintain the ability to change/parameterize b after compilation. Also, to give some motivation here: I would say that this situation/need arises when there isn't a strict relationship between the parameters (a and b in this case), but there is a convenient/typical default relationship.
For example, if an annotation like the following existed, it would be nice:
model ParameterTest
parameter Real a = 5;
parameter Real b = a/2 annotation(EvaluateExpression=true); // this would effectively replace "a/2" with "2.5" prior to compilation
end ParameterTest;
Is there any known way to achieve what I'm after? Or any other thoughts/suggestions?
I guess a model like the following would do what you want.
model ParameterTest
parameter Real a = 5;
parameter Real bVal = 0;
parameter Real b = if evaluateExpression then a/2 else bVal;
parameter Boolean evaluateExpression = true;
end ParameterTest;
I added a boolean parameter evaluateExpression that will influence if b get's computed or uses a parameter bVal.
In OpenModelica (OMEdit) you can change the value of b by changing evaluateExpression=false and bVal to some value at simulation time.
Related
I would like to test datasets with a variable number of values. Each value should be tested and I would like to have a standardized output that I can read in afterward again. My used framework is Matlab.
Example:
The use case would be a dataset which includes, e.g., 14 values that need to be testet. The comparison is already completely handled by my implementation. So I have 14 values, which I would like to compare against some tolerance or similar and get an output like
1..14
ok value1
ok value2
not ok value3
...
ok value14
Current solution:
I try to use the unit-testing framework and the according TAPPlugin that would produce exactly such an output (tap), one for every unit-test. My main problem is that the unit-testing framework does not take any input parameters. I already read about parametrization, but I do not know how this helps me. I could put the values as a list into the parameter, but how to I pass them there? Afaik the unit-test class does not allow additional parameters during initialization, so I cannot include this in the program the way I want.
I would like to avoid to need to format the TAP output on my own, because it is already there, but only for unit-test objects. Unfortunately, I cannot see how to implement this wisely.
How can I implement the output of a test anything protocol where I have a variable amount of comparisons (values) in Matlab?
If you are using class based unit tests you could access its properties from outside the test.
So let's say you have following unit test:
classdef MyTestCase < matlab.unittest.TestCase
properties
property1 = false;
end
methods(Test)
function test1(testCase)
verifyTrue(testCase,testCase.property1)
end
end
You could access and change properties from outside:
test=MyTestCase;
MyTestCase.property1 = true;
MyTestCase.run;
This should no succeed since you changed from false to true. If you want to have a more flexible way, you could have a list with the variables and a list with the requirements and then cycle through both in one of the test functions.
properties
variables = [];
requirements = [];
end
methods(Test)
function test1(testCase)
for i = 1:length(variables):
verifyEqual(testCase,testCase.variables[i],testCase.requirements [i])
end
end
end
Now you would set variables and requirements:
test=MyTestCase;
MyTestCase.variables = [1,2,3,4,5,6];
MyTestCase.requirements = [1,3,4,5,5,6];
MyTestCase.run;
Please note, that in theory you should not have multiple assert statements in one test.
Problem Description
I would like to use Non-SI-Units for time in economical modeling (e.g. System Dynamics). While of course I could go for seconds (s) and then use displayUnit there is to my knowledge no nice way to modify displayUnit for time in System Modeler, which I am mainly using.
So, writing a library I would like the user to make a choice of a global type called ModelTime which ideally would be declared as inner and replaceable at some top-level class. Then any component within a model could use the global type to consistently treat any time-related vars.
Minimal Example
The following example shows how I would like to implement this.
package Units declares two Non-SI Unit types( Time_year, Time_month)
package Interfaces contains a partial model class GenericSimulationModel which will be the top-level scope for any model written using the library. It is supposed to provide the type ModelTime as an inner and replaceable class
package Components defines a simple block class that uses ModelTime via an outer definition to define its output y that simple shows time in the globally chosen units of time
model Example ties all of this together to provide an example how any model using the library should work out
Here is the code:
model MinimalExample
package Units
type Time_year = Real(final quantity = "Time", final unit = "yr");
type Time_month = Real(final quantity = "Time", final unit = "mo");
end Units;
package Interfaces
partial model GenericSimulationModel "Top-level model scope providing global vars"
inner replaceable type ModelTime = Years "Set to : Months, Years";
protected
type Years = Units.Time_year;
type Months = Units.Time_month;
end GenericSimulationModel;
end Interfaces;
package Components
block ComponentUsingTime
outer type ModelTime = MinimalExample.Units.Time_year;
output ModelTime y;
equation
y = time;
end ComponentUsingTime;
end Components;
model Example
extends Interfaces.GenericSimulationModel(
redeclare replaceable type ModelTime = Months
);
Components.ComponentUsingTime c;
end Example;
equation
end MinimalExample;
While everything compiles without error in System Modeler and OpenModelica, it unfortunately does not work out: The redeclared type is not used within the component c in the Example model given above.
What can I do to achieve what I want to do?
I have received some feedback on Wolfram Community from someone at Wolfram MathCore (developers of the System Modeler):
The behavior you see for MinimalExample.example and MinimalLibrary.Example are bugs, and from what I can see they should work, I have forwarded them to a developer working on these things.
I have a parameter z for which I need the value to be 1, always.
model test
Real parameter z = 1;
end test;
When I drag and drop this model and double click on it, the parameters tab opens and I can change the value. How can i prevent that from happening?
Make the parameter final or protected. Final means you cannot modify it (and you can set the final modifier in a modification, like M m(final z=2) when instantiating a component). OpenModelica will also evaluate final parameters by default in order to produce a more efficient simulation (making them almost the same as constants).
Protected also means it cannot be modified (and in many tools will not be part of the result-file either).
There are different data types in SystemVerilog that can be used like the following:
reg [31:0] data;
logic [31:0] data;
bit [31:0] data;
How do the three of them differ?
reg and wire were the original types. Wires are constantly assigned and regs are evaluated at particular points, the advantage here is for the simulator to make optimisations.
wire w_data;
assign w_data = y;
// Same function as above using reg
reg r_data;
always #*
r_data = y ;
A common mistake when learning Verilog is to assume the a reg type implies a register in hardware. The earlier optimisation for the simulator can be done through the context of its usage.
This introduces logic which can be used in place of wire and reg.
logic w_data;
assign w_data = y;
// Same function as above using reg
logic r_data;
always #*
r_data = y ;
The type bit and byte have also been created that can only hold 2 states 0 or 1 no x or z. byte implies bit [7:0]. Using these types offers a small speed improvement but I would recommend not using them in RTL as your verification may miss uninitialized values or critical resets.
The usage of bit and byte would be more common in testbench components, but can lead to issues in case of having to drive x's to stimulate data corruption and recovery.
Update
At the time of writing I was under the impression that logic could not be used for tristate, I am unable to find the original paper that I based this on. Until further updates, comments or edits, I revoke my assertion that logic can not be used to create tri-state lines.
The tri type has been added, for explicitly defining a tri-state line. It is based on the properties of a wire, logic is based on the properties of a reg.
tri t_data;
assign t_data = (drive) ? y : 1'bz ;
If you no longer have to support backwards compatibility Verilog then I would recommend switching to using logic and tri. Using logic aids re-factoring and and tri reflects the design intent of a tristate line.
The choice of the name reg turned out to be a mistake, because the existence of registers is instead inferred based on how assignments are performed. Due to this, use of reg is essentially deprecated in favor of logic, which is actually the same type.
logic is a 1-bit, 4-state data type
bit is a 1-bit, 2-state data type which may simulate faster than logic
If a logic is also declared as a wire, it has the additional capability of supporting multiple drivers. Note that by default wire is equivalent to wire logic.
In general, the "nets" (such as wire and tri) are most suitable for designing communication buses.
Practically speaking, for RTL it usually doesn't matter whether you declare with reg, or logic, or wire. However, if you have to make an explicit declaration of a 4-state type (as opposed to when you don't), you should typically choose logic since that is what is intended by the language.
Related articles:
What’s the deal with those wire’s and reg’s in Verilog
An analysis of the "logic" data type by Cliff Cummings - 20021209
As I'm unable to add a comment I've to write what looks like a new answer but isn't. Sigh!
#e19293001, #Morgan, logic defines a 4-state variable unlike bit, and hence a logic variable can be used to store 1'bz so the following code is valid and compiles:
logic t_data;
assign t_data = (drive) ? y : 1'bz ;
But I agree that to reflect the design intent tri should be used instead of logic in these cases (although I must say I don't see people using tri instead of logic/wire too often).
reg and logic are exactly the same. These data types appear inside the always or initial blocks and store values i.e. always #(a) b <= a;, the reg b gets evaluated only when 'a' changes but otherwise it simply stores the value it has been assigned last.
wire are just simply connections and need to continuously driven. I agree that they can behave identical as #Morgan mentioned, but they can be imagined as a piece of hard wire, the value of which changes only the value at the other end or the source changes.
How do the three of them differ?
There is no difference between logic and reg.
The difference between bit and the other two is that bit is 2-state, whereas logic/reg are 4-state.
Refer to IEEE Std 1800-2017, section 6.11.2, 2-state (two-value) and 4-state (four-value) data types:
logic and reg denote the same type.
Also, section 6.3.1 Logic values:
The SystemVerilog value set consists of the following four basic values:
0 —represents a logic zero or a false condition
1 —represents a logic one or a true condition
x —represents an unknown logic value
z —represents a high-impedance state
Several SystemVerilog data types are 4-state types, which can store
all four logic values. All bits of 4-state vectors can be
independently set to one of the four basic values. Some SystemVerilog
data types are 2-state, and only store 0 or 1 values in each bit of a
vector.
Logic data type doesn't permit multiple driver. The last assignment wins in case of multiple assignment .Reg/Wire data type give X if multiple driver try to drive them with different value. Logic data type simply assign the last assignment value.
The "Reg" data type is used in procedural assignment, whereas the "Logic" data type can be used anywhere.
Consider the following F# code:
type ILinear =
interface
end
type IMetric =
interface
end
[<Measure>] type cm =
interface ILinear
interface IMetric
[<Measure>] type m =
interface ILinear
interface IMetric
[<Measure>] type time
I want to use these interfaces as a means of both grouping the types of the measures and as a way of allowing a level of genericness between "any measure" and "a specific measurement"--something akin to:
(* Yes, I know this syntax is probably incorrect *)
let rate (distance:float<'u:#ILinear,#IMetric>) (time:float<time>) =
distance/time
I realize this is probably pushing the limits of possibility but I'm just kind of curious if this is possible and if so, what the syntax would be. As I say, this is using interfaces as sort of a poor man's mixin.
I don't think this is possible, but I quite like the idea :-).
If it was possible, then the constraints would be probably written using the same syntax that you can use to write interface constraints for ordinary (non-measure) type parameters:
let rate<[<Measure>] 'u when 'u :> IMetric> (distance:float<'u>) (time:float<time>) =
distance/time
The error message clearly says that constraints can be only specified on ordinary type parameters (actually, I was even surprised that units of measure can implement interfaces - it doesn't look very useful as they are completely erased during the compilation):
error FS0703: Expected type parameter, not unit-of-measure parameter
The best workaround that I can think of is to write a simple wrapper that stores a value (with some unit) and additional (phantom) type that represents the constraints:
[<Struct>]
type FloatValue<[<Measure>] 'u, 'constr>(value:float<'u>) =
member x.Value = value
let cm f = FloatValue<_, IMetric>(f * 1.0<cm>)
The cm function takes a float and wraps it into a FloatValue. The second type argument is an ordinary type argument, so it can be provided with some type that implements interfaces (or with just a single interface). The rate function then looks like this:
let rate (distance:FloatValue<'u, #IMetric>) (time:float<time>) =
distance.Value / time
Since the constraints cannot be specified on a unit type, we have to specify them on the second type argument. You can then call the function using:
rate (cm 10.0) 5.0<time>