Systemverilog cross coverpoint syntax question - system-verilog

Hi I am new to stackoverflow and systemverilog/uvm. I am currently trying to get the a cross coverpoint to catch the condition that (a==b) && (c==d), regardless of what value they are. I have tried the following crosses and none of them seem to be working.
covergroup abcd_tracking with function sample (bit [7:0] a, bit [7:0] b, bit [7:0] c, bit [7:0] d);
coverpoint a {
bins a_bin[1] = {[0:$]};
}
coverpoint b {
bins b_bin[1] = {[0:$]};
}
coverpoint c {
bins c_bin[1] = {[0:$]};
}
coverpoint d {
bins d_bin[1] = {[0:$]};
abcd_cross : cross a,b,c,d
{
bins abcd_bin = abcd_cross with( (a==b) && (c==d) );
}
abcd_cross_2 : cross a,b,c,d
{
bins abcd_2_bin = ( binsof(a) intersect(b) && binsof(c) intersect(d) );
}
abcd_cross_3 : cross a,b,c,d
{
bins abcd_3_bin = ( binsof(a) intersect{[0:$]} with (a==b) && binsof(c) intersect{[0:$]} with (c==d) );
}
This should actually be an illegal condition that never gets hit, but the 3 cross coverpoints seem to be constantly getting hit even though checking with my log files, the sampled variables don't meet the condition I am trying to define in my cross coverpoint. What is the proper syntax for catching this particular condition: " (a==b) && (c==d) " ?

You have a number of syntax errors, but event beyond that, I think you have some misconceptions on how coverpoints and crosses work.
Your four coverpoints have only one bin for all possible values. That means each bin gets hit on the first sample with any value, which is 100% coverage for each of the four coverpoints on the first sample. And since a cross creates bins for all possible bin combinations, you only get one cross bin on the first sample. So each of the three crosses are covered on the first sample.
If you want a separate bin for each value of a coverpoint, you need to write
coverpoint a {
bins a_bin[256] = {[0:$]};
}
Now a simple cross of a,b,c,d would create 256*256*257*256 = 232 cross bins. Bins of a cross are automatically generated and you only specify bins if you want them merged or ignored. If are only interested in the cases where (a==b) && (c==d), you have ignore all the other bins with
abcd: cross a,b,c,d {
ignore_bins not_equal = abcd with( a!=b || c!=d);
}

Related

SystemVerilog covergroup include coverpoint based on parameter

I'm creating coverage for my design and I want to reuse a covergroup definition for multiple instances. The first instance should use all of the coverpoints as intended, but for the second instance, I want to exclude some of the coverpoints in the covergroup.
I was thinking I could use an input to the covergroup and iff () the unwanted coverpoints such that the first instance ties the input to 1 and the second instance ties the input to 0. However I think this will still show the coverpoints for the second instance as always not hit, and I want them to not be included at all.
covergroup cg_address(input bit enable) # (posedge clock);
address_check: coverpoint (address){
bins addr_0 = {5'd0};
bins addr_1 = {5'd1};
}
data_check: coverpoint (data) iff (enable){
bins data_0 = {10'd0};
bins data_1 = {10'd1};
}
endgroup : cg_address
cg_address cg_address_inst0 = new(1'b1);
cg_address cg_address_inst1 = new(1'b0); //want this one to exclude data_check coverpoint
I know the above code won't work because the second instance will still have the data_check coverpoint, it will just never hit either bin because the enable is tied to 0. Is there any other way I can try to exclude the data_check coverpoint for the second instance?
You need to do two things:
Set the weight of the coverpoint to 0.
Turn on option.per_instance = 1; for the covergroup.
For example:
covergroup cg_address(input bit enable) # (posedge clock);
option.per_instance = 1;
address_check: coverpoint (address){
bins addr_0 = {5'd0};
bins addr_1 = {5'd1};
}
data_check: coverpoint (data) {
option.weight = enable;
bins data_0 = {10'd0};
bins data_1 = {10'd1};
}
endgroup : cg_address
cg_address cg_address_inst0 = new(1);
cg_address cg_address_inst1 = new(0); //want this one to exclude data_check coverpoint

Find zero crossing of sampled function [duplicate]

I have written a function in MATLAB to count the number of zero crossings given a vector of signal data. If I find a zero crossing, I also check whether the absolute difference between the two vector indices involved is greater than a threshold value - this is to try to reduce the influence of signal noise.
zc = [];
thresh = 2;
for i = 1:length(v)-1
if ( (v(i)>0 && v(i+1)<0) || (v(i)<0 && v(i+1)>0) ) && abs(v(i)-v(i+1)) >= thresh
zc = [zc; i+1];
end
end
zcCount = length(zc);
I used the vector from the zero crossings function here to test it: http://hips.seas.harvard.edu/content/count-zero-crossings-matlab
A = [-0.49840598306643,
1.04975509964655,
-1.67055867973620,
-2.01437026154355,
0.98661592496732,
-0.06048256273708,
1.19294080740269,
2.68558025885591,
0.85373360483580,
1.00554850567375];
It seems to work fine but is there a more efficient way of achieving the same result? E.g. on the above webpage, they simply use the following line to calculate zero crossings:
z=find(diff(v>0)~=0)+1;
Is there a way to incorporate the threshold check into something similarly efficient?
How about
zeroCrossIndex=diff(v>0)~=0
threshholdIndex = diff(v) >= thresh;
zcCount = sum(zeroCrossIndex & threshholdIndex)

Combinational logic "IF" and "assign" statement in systemverilog

I found a very strange behaviour when design my ALU, hope someone can have a look it and tell me what is going on.
Here is the code
module adder (
output logic signed[31:0] y,
output logic Cout,
input logic signed[31:0] a, b,
input logic Cin, sub
);
logic [31:0] adder_b;
assign adder_b = b ^ {32{sub}};
assign {Cout, y} = {a[31],a} + {adder_b[31],adder_b} +Cin;
endmodule
////////////////////////////////////////////////////
////////////////////////////////////////////////////
////////////////////////////////////////////////////
module andlogic (
output logic [31:0] y,
input logic [31:0] a, b
);
assign y = a & b;
endmodule
////////////////////////////////////////////////////
////////////////////////////////////////////////////
////////////////////////////////////////////////////
module orlogic (
output logic [31:0] y,
input logic [31:0] a, b
);
assign y = a | b;
endmodule
////////////////////////////////////////////////////
////////////////////////////////////////////////////
////////////////////////////////////////////////////
module xorlogic (
output logic [31:0] y,
input logic [31:0] a, b
);
assign y = a ^ b;
endmodule
///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
module ALU(
output logic signed[31:0] Result,
output logic N,Z,C,V,
input logic signed[31:0] a, b,
input logic [2:0] ALU_control
);
wire [31:0] adder_rlt, and_rlt, or_rlt, xor_rlt;
logic Cin;
adder adder (
.y (adder_rlt),
.a (a),
.b (b),
.Cin (Cin),
.Cout (Cout),
.sub (sub)
);
andlogic andlogic (
.y (and_rlt),
.a (a),
.b (b)
);
orlogic orlogic (
.y (or_rlt),
.a (a),
.b (b)
);
xorlogic xorlogic (
.y (xor_rlt),
.a (a),
.b (b)
);
assign C = Cout;
assign sub = ALU_control[1];
assign Cin = ALU_control[1];
assign N = Result[31];
//assign Z = (Result ==0 )? 1:0;
assign V = {{~a[31]} & {~b[31]} & Result[31]}|{a[31] & b[31] & {~Result[31]}};
always_comb
begin
if (Result == 0) Z = 1;
else Z = 0;
case(ALU_control)
3'b001: Result = adder_rlt;
3'b010: Result = adder_rlt;
3'b011: Result = and_rlt;
3'b100: Result = or_rlt;
3'b101: Result = xor_rlt;
default: Result = 0;
endcase
end
endmodule
The first 4 modules are individual functions of my ALU, the adder contains both addition and subtraction. Then here is the odd thing:
My ALU has 4 flags, Z represent Zero, it sets when the value of output Result is 0. If I use these code to describe the behaviour of Z
always_comb
begin
if (Result == 0) Z = 1;
else Z = 0;
The simulation result is wrong, Z some time is 1, and some time is 0, and it looks like not depend on the value of Result at all.
What is more odd is the result of the synthesis result. Here the picture shows a part of my synplify synthesis result.
The gate level looks like correct, Z is a AND gate of all inverted Result signals, which when Result == 0, the output Z should be 1.
However, I spend all my afternoon yesterday try to figure out how to fix this bug, I fount that if I use assign statement instead of using if statement, then the simulation gives correct behaviour. assign Z = (Result ==0 )? 1:0;
I thought this two version of describing Z should be same! After I modified my code by using
assign Z = (Result ==0 )? 1:0;
The synthesis result still same as the picture I showed above...
Can someone tell me what is going on?
Thanks so much!!!
I believe the issue is with your order of operation. always_comb blocks execute procedurally, top to bottom. In simulation, Z is updated first with the existing value of Result (from the previous time the always block was executed). The Result is updated and Z is not re-evaluated. Result is not part of the sensitivity list because it is a left-hand value. Therefore, Z will not get updated until a signal that assigns Result changes.
Synthesis is different, it connects equivalent logic gates which may result in asynchronous feedback. Logical equivalent is not the same as functional equivalent. This is why synthesis is giving you what you logically intend and RTL simulation is giving what you functionally wrote. Explaining the reasons for the differences is outside the scope of this question.
When coding a RTL combinational block, just do a little self check and ask yourself:
Are the values at the end of a single pass of this always-block the intended final values? If no, rearrange your code.
Will any current values in this always-block be used assign any values in the next pass? If yes, rearrange your code or synchronize with a flip-flop.
In ALU case, tt is an easy fix. Change:
always_comb begin
if (Result==0) Z = 1; // <-- Z is evaluated using the previous value of Result
else Z = 0;
/*Logic to assign Result*/ // <-- change to Result does not re-trigger the always
end
To:
always_comb begin
/*Logic to assign Result*/ // <-- update Result first
if (Result==0) Z = 1; // <-- Z is evaluated using the final value of Result
else Z = 0;
end
An alternative solution (which I highly discourage) is to replace the always_comb with The IEEE1364-1995 style of combinational logic. Where the sensitivity list is manually defined. Here you can add Result to get the feed back update:
always #(ALU_control or adder_rlt or add_rlt or or_rtl or xor_rtl or Result)
I highly discourage because it easy to miss a necessary signal, unessary signals waste simulation time, creates a risk of zero time infinite loop, and you still don't get a guaranty functional equivalent between RTL and synthesis.

Matlab filter electical spikes in accelerometric data

I have a dataset of accelerometric data that is affected by electical spikes.
I'm looking for a good method to filter out or reduce these spikes as need to calculate on these data a rolling window of FFT and other statistical indicators such as kurtosis and skewness. I can't simply delete these outliers or replace them with NaN.
Sampling 2000[hz]
Until now I've tried on MATLAB 2012b:
Wavelet denoising (Haar wavelet)
Median Filter
Despike and iterpolate approach
Can you suggest a proper approach to deal with these data?
Download example dataset
I would suggest some local smoothing. By defining thresholds and averaging all values below and above.
Af = data.example1;
% Thresholds
Tl = -0.6;
To = 0.6;
peaks = find( Af < Tl | Af > To);
Af(peaks) = ( Af(peaks-1) + Af(peaks+1) ) / 2;
The problem with this approach is that your outliners sometimes consist of up to 6 samples.
So you need to smooth in multiple steps using a while loop:
Af = data.example1;
% Thresholds
Tl = -0.6;
To = 0.6;
% initialisation
peaks = find( Af < Tl | Af > To);
counter = 0;
while ~isempty(peaks)
peaks = find( Af < Tl | Af > To);
Af(peaks) = ( Af(peaks-1) + Af(peaks+1) ) / 2;
counter=counter+1;
end
after 6 iterations you get the following result:
I have used the file despiking from the matlab central file exchange with very good effect for similar problems, though I see you've tried that as well.
Another approach I've taken is to treat the spikes as statistical outliers and removed them using this function which uses Rosner's many outlier test. (NIST site is down for obvious reasons, so here is the Google cached version)
Edited to add: I was mistaken. My despiking algorithm did not come from the file exchange function I linked to above. It was actually pulled out of a journal article (the code is listed in the supplementary information to the paper, but they didn't publish the code to the file exchange). The paper was:
Practical Methods for Noise Removal: Applications to Spikes, Nonstationary Quasi-Periodic Noise, and Baseline Drift
Delphine Feuerstein , Kim H. Parker and Martyn G. Boutelle
Anal. Chem., 2009, 81 (12), pp 4987–4994
Since the copyright is held by the American Chemical Society and the authors, I can't copy the code here, but if you have access to a university library account, you can download a copy. If you don't, I left the link to the file exchange version, but I haven't used it so I can't vouch for its efficacy.
A moderator merged this question with this question - that's why it looks a little messy here. This answer considers additional issues in the second question!
The following is not an entirely clean solution, the code is adopted from my previous answer, but I added an exception for your case, so you don't need to delete values at the beginning and/or end of your data manually. It discards only these invalid values, that shouldn't cause problems.
Af = csvread(strcat('example_data_with_peak.txt'),5,0);
% Thresholds
Tl = -0.04;
To = 0.04;
% initialisation
peaks = find( Af < Tl | Af > To);
counter = 0;
while ~isempty(peaks)
peaks = find( Af < Tl | Af > To);
try
Af(peaks) = ( Af(peaks-1) + Af(peaks+1) ) / 2;
catch
if peaks(1) == 1
Af(1) = 0;
else
Af(end) = 0;
end
end
counter=counter+1;
end
figure(2);
plot(Af)
For determining the threshold you could use somethink like this, but it's also quite brute-force:
thresh = 15*mean(abs(findpeaks(Af)));
For others that may need this here's what I ended up using. Here's the data file data file link
Thanks goes to #thewaywewalk
Matlab filter electical spikes in accelerometric data
clear all, clc,clf,tic
aa=csvread(strcat('/tmp/example_data_with_peak.txt'),5,0); %will skip the first 5 rows that are text and zeros
figure(1);
plot(aa)
Af=aa;
% Thresholds
Tl = -mean(abs(aa))*10
To =mean(abs(aa))*10
% initialisation
[peaks_r,peaks_c] = find( Af < Tl | Af > To);
peaks = find( Af < Tl | Af > To);
counter = 0;
while ~isempty(peaks)
peaks = find( Af < Tl | Af > To);
try
Af(peaks) = ( Af(peaks-1) + Af(peaks+1) ) / 2;
catch
if peaks(1) == 1
Af(1) = 0;
else
Af(end) = 0;
end
end
counter=counter+1;
end
counter
figure(2);
plot(Af)
Here are the images of before and after.
I find that for the specific problem of one-point spikes (which arises in CCD detectors when a cosmic ray discharges a single CCD cell during the exposure) the following algorithm works very well:
N=length(y);
for i=[3:1:N-2]
# calculate the means of two nearest neighbours, and two next-nearest neighbours
y1=(y(i-1)+y(i+1))/2;
y2=(y(i-2)+y(i+2))/2;
# if those two means are close, but the current point is far off, it's a spike
if ( abs(y2-y(i)) > cutoff && abs(y1-y2) < cutoff)
z(i)=y2;
endif
endfor
Selecting the best strategy for a good cutoff selection is a separate issue; I tend to have it set to a fixed value based on the typical dark counts in the CCD. One can also use separate levels for what is "close" and what is "far off", like this:
if ( abs(y2-y(i)) > cutoff_far && abs(y1-y2) < cutoff_close )
One can also select a different criterion, like the difference between two means is X times smaller than the difference with the spike data:
if ( abs(y2-y(i)) > 10*abs(y1-y2) )
Peaks that are wider than a single-point spike survive this process unmolested.
An example of de-spiked Raman spectrum using a CCD detector

push relabel algorithm

I have done a MATLAB version of the push-relabel FIFO code (exactly like the one on wikipedia and tried it. The discharge function is exactly like wikipedia.
It works perfectly for small graphs (e.g. number of Nodes = 7). However, when I increase my graph size (i.e. number of nodes/vertices > 3500 or more) the "relabel" function runs very slowly, which is called in the "discharge" function. My graphs are huge (i.e. > 3000nodes) so I need to optimize my code.
I tried to optimize the code according to WIKIPEDIA suggestions for global relabeling/gap relabeling:
1) Make neighbour lists for each node, and let the index seen[u] be an iterator over this, instead of the range .
2) Use a gap heuristic.
I'm stuck at the first one , I don't understand what exactly I have to do since it seems there's details left out. (I made neighbor lists such that for vertex u, any connected nodes v(1..n) to u is in the neighbor list already, just not sure how to iterate with the seen[u] index).
[r,c] = find(C);
uc = unique(c);
s = struct;
for i=1:length(uc)
ind = find(c == uc(i));
s(uc(i)).n = [r(ind)];
end
AND the discharge function uses the 's' neighborhood struct list:
while (excess(u) > 0) %test if excess of current node is >0, if so...
if (seen(u) <= length(s(u).n)) %check next neighbor
v = s(u).n(seen(u));
resC = C(u,v) - F(u,v);
if ((resC > 0) && (height(u) == height(v) + 1)) %and if not all neighbours have been tried since last relabel
[C, F, excess] = push(C, F, excess, u, v); %push into untried neighbour
else
seen(u) = seen(u) + 1;
height = relabel(C, F, height, u, N);
end
else
height = relabel(C, F, height, u, N);
seen(u) = 1; %relabel start of queue
end
end
Can someone direct, show or help me please?