value of rD (Modelica) [duplicate] - modelica

This question already has answers here:
Modelica evaluation of an expression
(2 answers)
Closed 4 days ago.
I'm new to modelica.
What is the evaluated value of rD in the following modelica Code ?
model A
Real rA = 1 + rB;
Real rB = 4;
model B
Real rB = 10;
Real rC = rA;
end B;
B myB;
Real rD = myB.rC;
// What is the result of the evaluation of rD ?
// Case A : Evaluation of rD = 1 + 4 = 5
// Case B : Evaluation of rD = 1 + 10 = 11
end A;

You can use inner/outer references to propagate the value of rA from top-level model A to component model B.
Based on this, for case A the code looks like:
model A
inner Real rA=1 + rB;
Real rB=4;
model B
outer Real rA;
Real rB=10;
Real rC=rA;
end B;
B myB;
Real rD=myB.rC;
// What is the result of the evaluation of rD ?
// Case A : Evaluation of rD = 1 + 4 = 5
// Case B : Evaluation of rD = 1 + 10 = 11
end A;
For case B:
model A
inner Real rA = 1 + rB;
Real rB = myB.rB;
model B
outer Real rA;
Real rB = 10;
Real rC = rA;
end B;
B myB;
Real rD = myB.rC;
// What is the result of the evaluation of rD ?
// Case A : Evaluation of rD = 1 + 4 = 5
// Case B : Evaluation of rD = 1 + 10 = 11
end A;
Hope this works!

Related

Modelica evaluation of an expression

I'm new to Modelica, and I'm wondering, what would be the evaluation of rA within model B.
Is the value 5 or 11 ?
model A
Real rA = 1 + rB;
Real rB = 4;
model B
Real rB = 10;
// Case A : Evaluation of rA = 1 + 4 = 5
// Case B : Evaluation of rA = 1 + 10 = 11
end B;
end A;
Edit : what would be the evaluation of rD in model A using the code below ?
Is the value 5 or 11 ?
model A
Real rA = 1 + rB;
Real rB = 4;
model B
Real rB = 10;
Real rC = rA;
end B;
B myB;
Real rD = myB.rC;
// What is the result of the evaluation of rD ?
// Case A : Evaluation of rD = 1 + 4 = 5
// Case B : Evaluation of rD = 1 + 10 = 11
end A;
The rD = 1 + 4. The rB in model B is not involved in the calculation of rC (or rA). The expression is not like a C macro that is evaluated in that context again.
If you want to have the behavior that myB.rB influences the calculation of myB.rC then you need to change your code.
model A
Real rA = 1 + rB;
Real rB = 4;
model B
Real rB = 10;
Real rC = 1 + rB;
end B;
B myB;
Real rD = myB.rC;
// What is the result of the evaluation of rD?
// Case B : Evaluation of rD = 1 + 10 = 11
end A;
or make a function if that expression is complicated:
model A
function f
input Real x;
output Real y;
algorithm
y := 1 + x;
end f;
Real rA = f(rB);
Real rB = 4;
model B
Real rB = 10;
Real rC = f(rB);
end B;
B myB;
Real rD = myB.rC;
// What is the result of the evaluation of rD?
// Case B : Evaluation of rD = 1 + 10 = 11
end A;
Model B is not instantiated so B.rB=10 is not "known" by model A. Thus, rA = 5
If you want the result to be 11 then the code should be something like:
model A
B b;
Real rA = 1 + rB;
Real rB = b.rB;
model B
Real rB = 10;
// Case A : Evaluation of rA = 1 + 4 = 5
// Case B : Evaluation of rA = 1 + 10 = 11
end B;
end A;

Returning an object of the same class from an overloaded method operation "plus" rather than struct?

I have a MATLAB class that has a simple overloaded plus function, and I can't get it to return an object. I want the function to add each field value together and output an object of the same class, with the field values being sums of the two inputs. When I add the two objects together, I get a struct, not an object. I am new to classes and am likely doing this wrong; any help would be great.
The code is as follows:
classdef Molar
properties
A = 0;
B = 0;
C = 0;
end
methods
function M = Molar(val)
M.A = val;
M.B = val+1;
M.C = val+2;
end
function M = plus(M1,M2)
M.A = M1.A + M2.A;
M.B = M1.B + M2.B;
M.C = M1.C + M2.C;
end
end
end
When it runs and I do:
>> x = Molar(2)
x =
Molar with properties:
A: 2
B: 3
C: 4
>> y = Molar(3)
y =
Molar with properties:
A: 3
B: 4
C: 5
Then I get a struct when I do the + operation. How can I get this to return another Molar object?
>> x+y
ans =
struct with fields:
A: 5
B: 7
C: 9
I wonder if it has to do with needing to use the constructor method differently?
Any help in this regard would be appreciated.
The first parameter should be the returned value:
function M = plus(M,M2)
M.A = M.A + M2.A;
M.B = M.B + M2.B;
M.C = M.C + M2.C;
end

Error in system verilog 2012 Reference guide regarding non-blocking in always_comb ? and delayed assertion property marker?

2 questions
in the system verilog 2012 reference guide there is a reference to coding a sequential logic in an always_comb, is this possible since there is no clocking reference for an always_comb block - as seen here -> [sequential logic in always_comb]
while using system verilog assertion in Synopsys Verdi, is it possible that the green arrow(indicating the asserted property is satisfied) to be fired half or once clock cycle later, after the property being satisfied
Thanks :D
Regarding question 1. non-blocking assignments don't necessarily imply sequential behavior. Blocking/non-blocking assignments are a simulation construct. Let's look at a small example to understand it better:
module some_gate(
input logic a,
input logic b,
output logic c,
output logic d
);
// c is 'a or b'
// d is 'a and c'
endmodule
We have two input signals and two output signals. We want to model a composite gate.
In classical Verilog style, we would write the following:
always #(a or b) begin
c = a || b;
d = a && c;
end
This means, whenever a or b changes, compute the values of c and of d. Because we used a blocking assignment for c, the value we computed here gets "propagated" to the computation of d. This essentially means that we've chained the logic described by d to come after the logic for c.
We can test this using a little testbench:
module test;
logic a, b, c, d;
some_gate dut(.*);
always #(a or b or c or d)
$display("[%0d] a = %b, b = %b, c = %b, d = %b", $time(), a, b, c, d);
initial begin
#1 a = 1;
#1 b = 1;
#1 a = 0;
#1 $finish();
end
endmodule
If we simulate this, we'll get:
[1] a = 1, b = x, c = x, d = x
[1] a = 1, b = x, c = 1, d = 1
[2] a = 1, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 0
This is because the display process triggers once for each change of the variables. a gets changed from x to 1, but c haven't been updated yet. Then c and d get updated in the same time step. Later on, we change b, but this doesn't trigger any changes on c or d. Then, we change a again and later in the same time slice, d gets updated.
It's a bit redundant to have to specify the sensitivity list, since if we know that we want combinatorial logic, we should re-trigger the process whenever something on the right hand side of an assignment changes. This is what always_comb is for.
We can re-write our code using always_comb, by just getting rid of the sensitivity list:
always_comb begin
c = a || b;
d = a && c;
end
Running this code will lead to the same prints:
[1] a = 1, b = x, c = x, d = x
[1] a = 1, b = x, c = 1, d = 1
[2] a = 1, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 0
Now comes the interesting part. We can model the exact same circuit using always_comb and non-blocking assignments:
always_comb begin
c <= a || b;
d <= a && c;
end
Running this code, though, will produce slightly different prints:
[1] a = 1, b = x, c = x, d = x
[1] a = 1, b = x, c = 1, d = x
[1] a = 1, b = x, c = 1, d = 1
[2] a = 1, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 0
Notice that in the first time step we have 3 prints, instead of one. Let's look closer at what happens here. First, we change a, but c and d haven't been updated yet. Second, c gets updated, but d stays the same. This is because of the non-blocking assignment on c, leading to d "seeing" the "old" value of c. Third, after c was officially updated, the tool schedules an update on d and we see the last print for the first time step. The rest is the same as in the previous cases.
Remember from a previous paragraph that always_comb re-triggers whenever something on the right hand side of an assignment changes. The trick here is that this always_comb actually behaves like:
always #(a or b or c) begin
c <= a || b;
d <= a && c;
end
This is non-standard Verilog, but would still model the same logic. Notice that c has been explicitly added to the sensitivity list. If we omit this, then we'd be describing a latch. This style is discouraged, because it's easy to get wrong (i.e. forget to add intermediate logic nodes to the sensitivity list).
The key takeaway point here is that blocking or non-blocking assignments don't either describe sequential or combinatorial logic. It's the entire context (i.e. the sensitivity lists that determine when they get executed) that controls what logic circuit gets inferred from the code.
The full code example is available on EDAPlayground.
Regarding question 2. this is tool specific and this isn't the forum for this. You should ask this on the vendor's website.

Matlab recursion

Need a little help understanding what is happening in this function particularly line 7 [Fnm1,Fnm2] = fibrecurmemo(N-1); I don't understand how a new variable can be declared here with in the array. an example of what is happening would be appreciated.
function [Fn,Fnm1] = fibrecurmemo(N)
% Computes the Fibonacci number, F(N), using a memoized recursion
if N <= 2
Fn = 1;
Fnm1 = 1;
else
[Fnm1,Fnm2] = fibrecurmemo(N-1);
Fn = Fnm1 + Fnm2;
end
end
Say we start with:
fibrecurmemo(3) %// N is 3
The else statements run (since N > 2):
[Fnm1,Fnm2] = fibrecurmemo(2); %//statement 1
Fn = Fnm1 + Fnm2; %//statement 2
Before statement 2 can run, fibrecurmemo(2) must first run.
The if statements in fibrecurmemo(2) run (since N <= 2):
Fn = 1;
Fnm1 = 1;
As a result, fibrecurmemo(2) returns 1, 1.
Contininuing from statement 1 above,
[1,1] = fibrecurmemo(2); %//statement 1
Fn = 1 + 1; %//statement 2
Finally,
[2, 1] = fibrecurmemo(3);
The function returns two values.
function [xFive,yFive] = addFive(x,y)
xFive = x + 5;
yFive = y + 5;
end
xx = (addFive(3,4))
xx will be equal to 8 in this example
the syntax for assignment for multiple return values is
[a,b,c,...] = someFunc();
where someFunc() has output of [a,b,c,...]
[aa,bb] = addFive(3,4);
cc = addFive(3,4);
if you do it this way you would get
aa == 8
bb == 9
cc == 8
in the case of cc instead of [aa,bb] Then you will just get the first return value.
i.e. you could do
x = fibrecurmemo(5)
[y,z] = fibrecurmemo(5)
in this case x == y

coding for repetitive increase

In the following code, I want a and b to increase by 1 each time the calculations are done. Can someone please have a look:
for t = 1:20
a = 2;
b = 2;
r = a + b;
if r<5
display('reaching target')
elseif r>5
disp('job done')
end
a = a+1;
b = b+1;
end
If I run this, it'll show me reaching target 20 times on screen, meaning for t = 1, a = 2, b = 2, and r = 4 which is less than 5 so displaying reaching target is true. Next step, t = 2, I want a to increase to 3 from 2 and b = 3 as well (increment by 1), and then r = 6 which is greater than 5 so it should display 'job done', but it's not doing that. What is wrong?
You are reassigning the value 2 to both a and b at every start of the loop, r is always going to be equal to 4. Take the initialization of a and b out of the loop.
a = 2;
b = 2;
for t = 1:20
r = a + b;
if r<5
display('reaching target')
elseif r>5
disp('job done')
end
a = a+1;
b = b+1;
end