Delay and rise/fall times in assign statements for real variables in SystemVerilog - system-verilog

I need to write a uni directional analog switch in Systemverilog with some delay and rise and fall times.
input real in;
output real out;
assign #<delay> out = (enable === 1'b1)?in:0.0;
With above, I do not see any delay and output is exactly same as input with enable = 1. Is there a way I can add delays and rise/fall times to the above?

rise/fall delays are not defined for anything other than integral values.

Related

MATLAB how to write a for loop with 2 conditions, one is "==", the other is "~="?

I am trying to write an S-Function in Simulink, with the inputs "t" for time, and "LIBs" for the amount of material entering the system. There are 2 outputs. The idea is like this in Simulink.
Simulink model concept
What I want to do is that, at a certain time iteration, the input "LIBs" goes to a different output. But during the iteration, there are some special points at which I don't want the input to go to any output.
The code is like this:
MATLAB
function [Batts_Spent, Batts_N_Spent] = BattsL6Y(t, LIBs)
for t = 2011:6:2035
if t ~= 2005:10:2035
Batts_Spent = LIBs;
end
end
for t = 2015:10:2035
if t ~= 2005:6:2035
Batts_N_Spent = LIBs;
end
end
for t = 2011:6:2035
if t == 2015:10:2035
Batts_Spent = LIBs;
end
end
end
I am sure that this code is not correct, but I don't know how to write it correctly.
And also, even if I have several input and output ports, the S-Function block in the Simulink project still remains only one input and output port. Should I change it to a MATLAB Function block?
In your case t is an input parameter, which makes it look like the function is called for each value of t. Then you have a loop iterating over all values of t. Considering your image, you don't need a loop at all. You can use if in combination with mod. For example:
function [Batts_Spent, Batts_N_Spent] = BattsL6Y(t, LIBs)
if mod(t-2005,6)==0 && t>=2005
Batts_Spent = LIBs;
end
end
This is only "Every 6th time the value of LIBs will be assigned to the first output". This isn't a finished solution but should be sufficient to get you started. You need a second if like this for the other output.

Modelica Simulation breaks when if condition changes

I try a simple code on modelica using if:
model thermostat1
parameter Real T0=10;
Real T(start=T0);
equation
if T<73 then
der(T)=-T+80;
else
der(T)=-T+50;
end if;
end thermostat1;
the simulation stops at the moment T reaches 73.
Why can't the simulation continue with the new equation ( der(T)=-T+50 )?
And how can i fix it?
Thank you.
What happens in your model is called chattering. This means, that there are very frequent events happening.
In you case specifically this is caused by the condition T<73 combined with the definitions of the derivatives. Let me try to explain what happens with the model you have provided:
The temperature rises until it reaches 73
Then the temperature starts to fall because the condition in the if-statement turns fall
This causes the if-statement to immediately change to true again, making the temperature rise
This causes the if-statement to change to false again, making the temperature fall
goto 3.
This causes the condition T<73 to change at a very high frequency, in turn creating many events, which have to be handled by the solver. This makes the progress in time very little (what you refer to as "the simulation stops").
There are multiple ways to solve this problem. One is to add a hysteresis to the model. I did that in code below. To describe the hysteresis part I used the code from Modelica.Blocks.Logical.Hysteresis. This will make the boolean variable upperLimit (which replaces your T<73) change only if temperature gets higher than T_highand lower than T_low. I chose this solution as it seems reasonable for a thermostat.
model thermostat1
parameter Real T0=10;
parameter Real T_High=74;
parameter Real T_Low=72;
Boolean upperLimit "Output of hysteresis block";
Real T(start=T0);
equation
upperLimit =not pre(upperLimit) and T > T_High or pre(upperLimit) and T >= T_Low;
if upperLimit then
der(T)=-T+50;
else
der(T)=-T+80;
end if;
end thermostat1;
The result of the simulation then looks like:
More general information can be found e.g. at http://book.xogeny.com/behavior/discrete/decay/

Simulink with if/else and different signal dimension

I need to implement a if/else in simulink to find out if a input is a scalar value or a matrix. Please see, the diagram below :
Given:
Block(1) - is a input that can be a scalar "1" or a matrix "[[0 15];[5 10]]"
Block(2) - must return the signal dimension of the input. Ex: 1 for scalar and >1 for a matrix
The requirements are:
Everything must work interpreted or compiled (Simulink coder)
The final output of blocks (4) and (5) are scalars
I have average understanding of CMexSFunctions. So if I need to implement one to solve the problem it is ok
So far, I have had the following problems:
I don't at all if what I am planning to do is feasible
I don't know how to implement Block(2) to work on compiled mode
Even though there is a if/else, simulink performs a pre-check before running to verify if all signal dimensions are ok. During this check, it gives a error saying ex: that Block(5) has a input of matrix
Any Clues?
Block(2) is the easiest part which can be implemented using the "Probe" block in Simulink library. Your Input at port 1 must be variable sized signal since you are expecting a scalar or matrix.
I assume you are feeding Input(1) to blocks 4 and 5. At model compile time Simulink does not know which one of these blocks are going to run based on the input size. So Simulink needs to assume both blocks may get scalar or matrix. You need to make blocks 4 and 5 not throw error for both scalar and matrix even though they will be used only for one type at run-time.
If you are not able to do this, for the scalar case a simple work around is to place a Selector before block 5 that selects the first sample always. This will let Simulink know that the input to block 5 is always a scalar.

Is there a way to enforce the simulation step to be smaller than a compile-time constant in simulink?

Question
Is there a way to enforce the simulation step to be smaller than a compile-time constant in a simulink model?
Context
I'm trying to build a PWM block on simulink. As it is now, I have to make sure that the user chooses a step size responsibly (smaller than half the period chosen by him), otherwise the block behaves abnormally. The only way I came up was to stop the simulation if the step size is not small enough, but I find that very annoying (as a user). If possible, I'd like for the user to not worry about this at all.
Here's what I would do: add the following pseudo-code to the block callback StartFcn:
T_PWM = get_param(gcb,...); % get the block parameter (period) of the current PWM block (string)
T_PWM = str2double(T_PWM);
T_solver = get_param(bdroot,'FixedStep'); % get fixed used by the solver (string)
T_solver = str2double(T_solver); % convert from string to double
if T_solver > 0.5*T_PWM
error('Solver step size must be smaller than half the PWM period')
end

Implementation of custom counter logic in SIMULINK

I am trying to implement a counter logic in SIMULINK where
in1, in2 are inputs
out1 is the output
if in2 = 0, out1 = 0;
if in2 = 1, out1 = 1 after x high edges of in1
I have tried using "Detect Rise Positive" block but failed miserably because I don't have sufficient experience of implementing a timing diagram correctly in SIMULINK. Could anyone kindly point me to the right direction?
Update
An approach I have taken since I posted this question is the "Triggered and enabled subsystem". I am trying to set it up so that:
in2 becomes the enable signal
in1 becomes the trigger
in2 becomes the intput to the subsystem
Out1 becomes the output of the subsystem
But I think that the above was rubbish. Unfortunately it is not VHDL where I could have implemented it using 4-5 lines of description of the hardware logic.
Using a Triggered and Enabled subsystem is the right approach, but your inputs (and no doubt what's inside the subsystem) needs to be modified.
Don't have any input to the subsystem (other than the trigger and enable signals).
Inside the subsystem,
set the enable block property to reset the state when disabled.
set the outport property to reset when disabled and give the initial condition as 0.
create a counter out of a constant (value=1), a summation and a unit delay block.
feed the counter into a Compare to Constant block set to the 'x' value in your question.
feed that block to the outport.
When enabled, the counter should count the required number of steps (when triggered) before the output goes high.
A counter logic can be implemented very easily in simulink. Take a switch,give the control input as int1. If int1 is 1 ur output shuld be 0 else take another switch give its control input as int2. if int2 is 1 ur output shuld be 1+ previous value given in feedback funit delay block