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

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.

Related

Effective creation of Subclasses which have four (2 x 2) options

I am very new to OOP in Matlab. Let's say I have a super class with one property, X. Next I want to define subclasses that has properties V, A, and B, where V is some manipulation of X, with four options:
V = A1*X - B1;
V = A1*X - B2;
V = A2*X - B1;
V = A2*X - B2;
In the actual code the options are something completely different, and it takes quite some time to calculate V, so once it is calculated I definitely want to store it. (In fact my options for A and B are actually discrete choices, so there are really just four possible combinations).
So what I did is: I created a subclass, VClass, with properties A, B, V (and X).
The SuperClass has methods:
function obj = SuperClass(X)
obj.XX = XX;
end
function add_V(obj,A,B)
if A == A1 && B == B1;
obj.A1B1 = VClass();
obj.A1B1.init_V(X,A,B);
elseif A == A2 && B == B1;
obj.A2B1 = VClass();
obj.A2B1.init_V(X,A,B);
et cetera...
end
The VClass has method:
function init_V(obj,X,A,B)
obj.V = A*X - B;
obj.A = A;
obj.B = B;
obj.X = X;
end
The thing that I don't like is that I created subclasses with names A1B1, A1B2, A2B1, and A2B2, so in every method I repeat a lot of code. I suppose I could use 'eval' with creation of a name for the subclass:
if A == A1 && B == B1;
name = 'A1B1';
.....
and in combination with:
eval(['obj.',name,' = VClass();']);
eval(['obj.',name,'.init_V(X,A,B);']);
But I am not too happy about that either, since it makes the code difficult to read.
Does anybody have another suggestion? (and any other comments of course also very welcome, since I just started with OOP)

nargin, vargin, exist, what is the best way to implement optional arguments matlab

I have a function in matlab:
function output = myfunc(a,b,c,d,e)
%a and b are mandetory
%c d and e are optional
end
How would I handle inputs if a user gave an optional arg for e but not for c and d?
nargin just gives the number of arguments. would exist be the best way?
Just use nargin. It will tell you how many arguments are present. Use varargin only when you have a variable number of arguments, that is you have no limit in number of arguments, or you want to access the arguments in an indexing fashion. I assume this is not the case for you, so one solution might look like this.
function output = myfunc(a,b,c,d,e)
%a and b are mandetory
%c d and e are optional
if nargin < 3 || isempty(c)
c = <default value for c>
end
if nargin < 4 || isempty(d)
d = <default value for d>
end
if nargin < 5 || isempty(e)
e = <default value for e>
end
<now do dome calculation using a to e>
<If a or b is accessed here, but not provded by the caller an error is generated by MATLAB>
If the user does not want to provide a value for c or d but provides e, he has to pass [], e.g. func(a,b,c,[],e), to omit d.
Alternatively you could use
if nargin == 5
<use a b c d and e>
elseif nargin == 2
<use a and b>
else
error('two or five arguments required');
end
to check if all a arguments e are present. But this requires exactly 2 or 5 arguments.
You can to define c, d and e as optional and then assign values based on position. This requires empty inputs if they want e but not c. For example:
function output = myfunc( a, b, varargin )
optionals = {0,0,0}; % placeholder for c d e with default values
numInputs = nargin - 2; % a and b are required
inputVar = 1;
while numInputs > 0
if ~isempty(varargin{inputVar})
optionals{inputVar} = varargin{inputVar};
end
inputVar = inputVar + 1;
numInputs = numInputs - 1;
end
c = optionals{1};
d = optionals{2};
e = optionals{3};
output = a + b + c + d + e;
This will just add everything together. There is alot of error checking that needs to happen with this. A better approach might be inputParser. This does paired inputs and checking. See Input Parser help

MATLAB boxplot of high dimensional vectors with different lengths

I have been looking for a way to use boxplot for different length vectors. thanx for stackoverflow helpers, they give this solution:
A = randn(10, 1); B = randn(12, 1); C = randn(4, 1);
g = [repmat(1, [10, 1]) ; repmat(2, [12, 1]); repmat(3, [4, 1])];
figure; boxplot([A; B; C], g);
unfortunately, my data contains over 100 vectors with different lengths, I wonder if it can be done without repeating the repmat for over 100 times.
As long as your vectors have different lengths, store it in a cell array.
There are plenty was of doing it, here are 3 examples
1) "Naive" for loop
g = [];
vars_cell = {A, B, C, ....};
for it = 1 : length(vars_cell)
g = [g; repmat(it,size(vars_cell{it}))];
end
This way of doing it works but is very slow with big quantites of vectors or big vectors! It comes from the fact that you are re-defining g at each iteration, changing its size each time.
2) Not-naive for loop
vars_cell = {A, B, C, ....};
%find the sum of the length of all the vectors
total_l = sum(cellfun(#(x) length(x),vars_cell));
g = zeros(total_l,1);
acc = 1;
for it = 1 : length(vars_cell)
l = size(vars_cell{it});
g(acc:acc+l-1) = repmat(it,l);
acc = acc+l;
end
This method will be much faster than the 1st one because it defines g only once
3) The "one-liner"
vars_cell = {A, B, C, ....};
g = cell2mat(arrayfun(#(it) repmat(it, size(vars_cell{it})),1:length(vars_cell),'UniformOutput',0)');
This is qute equivalent to the 2nd solution, but if you like one line answers this is what you are looking for!

Can I access a local variable of a function without outputting it?

I have a function in MATALB that looks like the following:
function [a, b] = SumIt(I1, I2)
a = sum(I1);
b = sum(I2);
c = sum(I1/I2);
end
In the command window, I run the function but I cannot access the c variable. I know that I can do something like this [a, b, c] = SumIt(I1, I2) and access c variable. Can I access the variable c without outputting it?
The issue is that I have many outputs that are useless but I need to access them. How can I do this?
I tried with global but I got the same error.
function [a, b] = SumIt(I1, I2)
global c;
a = sum(I1);
b = sum(I2);
c = sum(I1/I2);
end
>> [a, b] = SumIt([1 4 6], [1 2 3]);
>> c
Undefined function or variable 'c'.
The only way that this can be done is to have a function script that also declares SumIt as an additional function and also declaring c to be global outside of the scope of SumIt. Consider the following test function shown below:
function [] = test_func()
global c;
function [a, b] = SumIt(I1, I2)
a = sum(I1);
b = sum(I2);
c = sum(I1/I2);
end
[t1, t2] = SumIt(6, 3);
disp(['t1 = ' num2str(t1)]);
disp(['t2 = ' num2str(t2)]);
disp(['c = ' num2str(c)]);
end
I have created a test function called test_func where we declare c to be global, but it is outside of the scope of SumIt. After, I declare SumIt as a nested function, then try and call it with some example numbers. I then display the outputs of SumIt as well as c. Since I1 = 6, I2 = 3, we should get c = 2.
This is what I get when I run test_func:
>> test_func
t1 = 6
t2 = 3
c = 2
Minor note
It looks like I1 and I2 are vectors judging from the context of your use with sum. As such, you should probably consider using the element-by-element division operator ./ if what I am interpreting is correct. Are you trying to divide each element of I1 by I2 and then summing the result? If that's the case, you need to change your function such that it becomes:
function [a, b] = SumIt(I1, I2)
a = sum(I1);
b = sum(I2);
c = sum(I1./I2);
end

Counting Number of Specific Outputs of a Function

If I have a matrix and I want to apply a function to each row of the matrix. This function has three possible outputs, either x = 0, x = 1, or x > 0. There's a couple things I'm running into trouble with...
1) The cases that output x = 1 or x > 0 are different and I'm not sure how to differentiate between the two when writing my script.
2) My function isn't counting correctly? I think this might be a problem with how I have my loop set up?
This is what I've come up with. Logically, I feel like this should work (except for the hiccup w/ the first problem I've stated)
[m n] = size(matrix);
a = 0; b = 0; c = 0;
for i = 1 : m
x(i) = function(matrix(m,:));
if x > 0
a = a + 1;
end
if x == 0
b = b + 1;
end
if x == 1
c = c + 1;
end
end
First you probably have an error in line 4. It probably should be i instead of m.
x(i) = function(matrix(i,:));
You can calculate a, b and c out of the loop:
a = sum(x>0);
b = sum(x==0);
c = sum(x==1);
If you want to distinguish x==1 and x>0 then may be with sum(xor(x==1,x>0)).
Also you may have problem with precision error when comparing double values with 0 and 1.