Difference between "||" and "or" in system verilog [duplicate] - system-verilog

This question already has answers here:
Verilog - what is the difference in use between vertical bar (|) and "or"
(2 answers)
Closed 6 months ago.
I am trying to wait for a change in 2 signals in following 2 ways.
Option 1: #(a or b)
Option 2: #(a || b)
If any change observed for any signal then I am trying to display the value as shown below.
module wait_test;
int a, b;
initial
begin
#10 a += 10;
#10 b += 10;
#10 a += 10;
#10 b += 10;
end
initial
forever
begin
#(a or b)
$display($time,"\ta = %0d,b = %0d", a, b);
end
endmodule
Result:
10 a = 10,b = 0
20 a = 10,b = 10
30 a = 20,b = 10
40 a = 20,b = 20
When I replace #(a or b) with #(a || b), I only observe 1st display with no errors. Please help me with the reason.
Result:
10 a = 10,b = 0

The or operator in this context is described in IEEE Std 1800-2017, section 9.4.2.1 Event OR operator. Whenever there is a change in either a or b, the $display statement will be executed, as you have seen.
The || operator is a simple logical OR. It will first evaluate the expression (a || b), then the event control # syntax will wait for a change in the expression, not the individual signals. At time 0, both signals are 0, which means the expression is 0. At time 10, a changes to 10, which means the expression changes to 1. Although the signals continue to change every 10 time units, the expression remains 1, so there are no further changes in the expression.
#(a || b) is not a typical construct. #(a or b) is a typical construct.
Also, your initial forever block is much more commonly coded as:
always #* begin
$display($time,"\ta = %0d,b = %0d", a, b);
end

Related

variable delay in assertions in System Verilog

I am a newbie learning System Verilog assertions and found a code online from verificationguide.com for variable delays in assertions. But I am unable to understand a few things.
Can someone elaborate on these following given descriptions?
// Copy variable value to the local variable.
(1,delay=v_delay)
How does this data gets copied?
// Decrements the value of the local variable and checks for the value of ‘delay’ equals ‘0’.
(1,delay=delay-1) [*0:$] ##0 delay <= 0
What does *0 mean? I know $ is for infinite checking till the end of the simulation. And why is ##0 needed as it just means 0 delay, if I am not wrong?
// waits for value of ‘delay’ equals to ‘0’
first_match((1,delay=delay-1) [*0:$] ##0 delay <=0)
How does the first_match function works and whats the syntax of it?
Please find the code below:
//-------------------------------------------------------------------------
// www.verificationguide.com
//-------------------------------------------------------------------------
module asertion_variable_delay;
bit clk,a,b;
int cfg_delay;
always #5 clk = ~clk; //clock generation
//generating 'a'
initial begin
cfg_delay = 4;
a=1; b = 0;
#15 a=0; b = 1;
#10 a=1;
#10 a=0; b = 1;
#10 a=1; b = 0;
#10;
$finish;
end
//delay sequence
sequence delay_seq(v_delay);
int delay;
(1,delay=v_delay) ##0 first_match((1,delay=delay-1) [*0:$] ##0 delay <=0);
endsequence
//calling assert property
a_1: assert property(#(posedge clk) a |-> delay_seq(cfg_delay) |-> b);
//wave dump
//initial begin
// $dumpfile("dump.vcd"); $dumpvars;
//end
endmodule
1) The sequence delay_seq has a variable cfg_delay which is passed from the property. That is actually assigned to v_delay, which is in turn assigned to the local variable delay.
2) *0 is called an empty match. For example a[*0:$] |-> b means
a [*0] or a [*1] or a [*2] .. a [$]
3) For example ($rose(b) ## [3:4] b) has two possible matches and ($rose(b) ## [3:$] b) can have infinite number of matches. To avoid unexpected behaviors because of multiple matches or cause an assertion to never succeed because all threads of antecedent must be tested for property to succeed. The first_match operator matches only the first of possibly multiple matches for an evaluation attempt and causes all the subsequent matches to be discarded.

Finding occurences of a digit in a number by recursion in Matlab

This recursive function takes two input arguments, The first (A) is a number and the second (n) is a digit, checks the occurrence of n in A. (A is updated by removing its last digit in each recursion). it seems like the recursion is infinite and the base case (A == 0) is not valid but why.
function counts = countn(A,n)
if (A == 0)
counts= 0;
end
if (n == mod(A,10))
disp(A);
disp(floor(A/10));
disp(mod(A,10));
B = floor(A/10);
counts = countn(B,n) + 1;
else
B = floor(A/10);
countn(B,n);
end
end
It does not stop because it first evaluates the first if statement if( A == 0) and afterward the if (n == mod(A,10)) where it jumps in the else branch and recursively calls the function again. So it does not stop in the first if statement as you likely expected it to do.
something like this should work:
function counts = countn(A,n)
if (A == 0)
counts = 0;
elseif (n == mod(A,10))
disp(A);
disp(floor(A/10));
disp(mod(A,10));
B = floor(A/10);
counts = countn(B,n) + 1;
else
B = floor(A/10);
counts = countn(B,n);
end
end
You also have to update count counts variable in the else branch to avoid the uninitialized use of variables.
Have a look at how to use a debugger manual. Simply click on the line number inside your function and run your code. Use the F10 and F11 keys to evaluate your code line by line. This helps you understand what your program does.

One-liner for if then [duplicate]

This question already has answers here:
ternary operator in matlab
(12 answers)
Closed 8 years ago.
Is there a one-liner in MATLAB for this?
if a > b
foo = 'r';
else
foo = 'g';
end
There is no syntactic sugar for one-line if-statements in MatLab, but if your statement is really simple you could write it in one line.
I used to have one-line if-statements like that in my old project:
if (k < 1); k = 1; end;
In your case it'll look something like:
if a > b; foo = 'r'; else; foo = 'g'; end;
or, if you don't like semicolons
if a > b, foo = 'r'; else, foo = 'g'; end
Not as pretty as you may have expected, though.
Not as elegant as a C style ternary operator but you can take advantage of the fact that matlab will automatically cast logicals into doubles in this situation. So you can just multiply your desired result for true (r in this case) by your condition (a > b), and add that to the product of your desired result for false (i.e. g) with the not of your condition:
foo = (a > b)*c + (~(a > b))*d
so if we let c = 'r' and d = 'g' then all we need to do is cast foo back to a char at the end:
char(foo)
or
char((a > b)*'r' + ~(a > b)*'g')
Note that this will only work if c and d have the same dimensions (because of the +)...
Try to avoid using if statements in matlab, and just convert your logic to (vector) math:
foo = 1 + (a <= b)
Edit:
For the more general case, of assigning 'r' or 'g', you can use:
col = {'r', 'g'};
foo = col(1 + (a > b));
So for example with an isGreen boolean you could do:
foo = col(1 + isGreen);
This could also be a boolean returning function
foo = col(1 + isGreen(a))

What are # and : used for in Qbasic?

I have a legacy code doing math calculations. It is reportedly written in QBasic, and runs under VB6 successfully. I plan to write the code into a newer language/platform. For which I must first work backwards and come up with a detailed algorithm from existing code.
The problem is I can't understand syntax of few lines:
Dim a(1 to 200) as Double
Dim b as Double
Dim f(1 to 200) as Double
Dim g(1 to 200) as Double
For i = 1 to N
a(i) = b: a(i+N) = c
f(i) = 1#: g(i) = 0#
f(i+N) = 0#: g(i+N) = 1#
Next i
Based on my work with VB5 like 9 years ago, I am guessing that a, f and g are Double arrays indexed from 1 to 200. However, I am completely lost about this use of # and : together inside the body of the for-loop.
: is the line continuation character, it allows you to chain multiple statements on the same line. a(i) = b: a(i+N) = c is equivalent to:
a(i)=b
a(i+N)=c
# is a type specifier. It specifies that the number it follows should be treated as a double.
I haven't programmed in QBasic for a while but I did extensively in highschool. The # symbol indicates a particular data type. It is to designate the RHS value as a floating point number with double precision (similar to saying 1.0f in C to make 1.0 a single-precision float). The colon symbol is similar to the semicolon in C, as well, where it delimits different commands. For instance:
a(i) = b: a(i+N) = c
is, in C:
a[i] = b; a[i+N] = c;

MATLAB: If Statement inside loop is not executing, nor printing to the screen

So, we are trying to execute the following code. The two if statements are executing, however, the inside if statements are failing to execute (we verified this by not suppressing the output). Is there a reason why? Or are we just not able to reach this state?
Specifications
The input is as follows: v is a vector of int values and c is a integer. c must be less than or equal to one of the values within v
The problem that we are trying to solve with this algorithm is as follows:
Given a cash register, how does one make change such that the fewest coins
possible are returned to the customer?
Ex: Input: v = [1, 10, 25, 50], c = 40. Output O = [5, 1, 1, 0]
We are just looking for not a better solution but more of a reason why that portion of the code is not executing.
function O = changeGreedy(v,c)
O = zeros(size(v,1), size(v,2));
for v_item = 1:size(v,2)
%locate largest term
l_v_item = 1
for temp = 2:size(v,2)
if v(l_v_item) < v(temp)
l_v_item = temp
end
end
%"Items inside if statement are not executing"
if (c > v(l_v_item))
v(l_v_item) = -1 %"Not executing"
else
O(l_v_item) = idivide(c, v(l_v_item)) %"Not executing"
c = mod(c, v(l_v_item)) %"Not executing"
end
end
If c or v are not integers, i.e. class(c) evaluates to double, then I get the following error message
??? Error using ==> idivide>idivide_check at 66
At least one argument must belong to an integer class.
Error in ==> idivide at 42
idivide_check(a,b);
and the program stops executing. Thus, the inside of the second statement never executes. In contrast, if, say, c is an integer, for example of class uint8, everything executes just fine.
Also: what are you actually trying to achieve with this code?
Try to do this operation on your input data:
v = int32([1, 10, 25, 50]), c = int32(40)
and run again, at least some portions of your code will execute. There is an error raised by idivide, which apparently you missed:
??? Error using ==> idivide>idivide_check at 67
At least one argument must belong to an integer class.
Error in ==> idivide at 42
idivide_check(a,b);
Indeed, idivide seems to require that you have actual integer input data (that is, class(c) and class(v) both evaluate to an integer type, such as int32).