Add functional coverage to signal with condition - functional-programming

I'm new to functional coverage in system-verilog. I want to write a covergroup when two signal are not equal.
For example, I have two separate coverages for each signal.
covergroup group1 #(posedge `TB_TOP.clk);
cpb_1 : coverpoint `TB_TOP.sig1 {
bins r_zero = {0};
bins r_one = {1};
endgroup
covergroup group2 #(posedge `TB_TOP.clk);
cpb_2 : coverpoint `TB_TOP.sig2 {
bins r_zero = {0};
bins r_one = {1};
endgroup
Now I want to add another when sig1 not equal to sig2 at posedge of clock.
Thanks

You mean something like this?
covergroup group3 #(posedge `TB_TOP.clk);
// coverpoint can take an expression, so provide sig1!=sig2
cpb_3: coverpoint (`TB_TOP.sig1 != `TB_TOP.sig2) {
// Since we only want to cover this case, sample a true value (1) only
bins covered = {1};
}
endgroup

Related

Arduino Loop not recognizing break condition?

I currently have a nested for loop system that is writing commands to a motor and reading from the attached encoder. For some reason, the program will not break out of the loop using the conditional. I have used some print statements to debug a little and it clearly recognizes that PWMcount is greater than 76 as it prints as far as I will let it count. Any advice is much appreciated, Thank You!
for(int PWMcount = 58;PWMcount < 76;) { //10-20 RAMP
for (int counter = 1; counter < 4;) {
if (counter != 3) {
finalTime = millis();
float newPos;
newPos = encoder.read();
if (newPos != oldPos) {
deltaTime = (finalTime - initialTime);
deltaPos = (newPos-oldPos);
oldPos = newPos;
initialTime = finalTime;
//Serial.println(deltaPos/deltaTime);
}
counter = counter+1;
delay(100);
// Serial.println(PWMcount);
}
else {
finalTime = millis(); //catches time for beginning of each loop iteration
float newPos;
newPos = encoder.read();
if (newPos != oldPos) { //Checks for encoder movement
deltaTime = (finalTime - initialTime); //calculates deltaT in milliseconds
deltaPos = (newPos-oldPos); //sets change in position from one iteration to the next
oldPos = newPos; //Sets old to new to fail if statement unless movement is detected.
initialTime = finalTime; //sets time at beginning of loop to time of ending last loop in order to correctly calculate deltaT in the next iteration
//Serial.println(deltaPos/deltaTime); //Prints rate of the encoder disk in deg/ms (Confirmed by manually taking data and seeing that 1 Rotation outputs values from 0-360
}
counter = 1;
PWMcount=PWMcount+1;
analogWrite(RPWM_Output, PWMcount); // Increases Motor PWM in accordance to loop
}
Serial.println(PWMcount); // UNCOMMENT TO TROUBLESHOOT PWM
delay(100);
}
}
This for loop never completes:
for (int counter = 1; counter < 4;)
The body of the loop is a single if statement. On the last iteration of the loop, the else branch is taken, and that branch sets the loop variable counter back to 1, so the expression counter < 4 is always true, and so that loop never exits.
Since it never exits, the code never gets to a point where the outer loop conditional is tested, nor where the outer loop would ever branch back to the beginning at all.
One possible way to fix the situation would be to combine the two loop conditions, making it a single loop:
for(int PWMcount = 58, counter = 1; PWMcount < 76;) { //10-20 RAMP
if (counter != 3) {
finalTime = millis();
float newPos;
newPos = encoder.read();
if (newPos != oldPos) {
deltaTime = (finalTime - initialTime);
deltaPos = (newPos-oldPos);
oldPos = newPos;
initialTime = finalTime;
//Serial.println(deltaPos/deltaTime);
}
counter = counter+1;
delay(100);
// Serial.println(PWMcount);
}
else {
finalTime = millis(); //catches time for beginning of each loop iteration
float newPos;
newPos = encoder.read();
if (newPos != oldPos) { //Checks for encoder movement
deltaTime = (finalTime - initialTime); //calculates deltaT in milliseconds
deltaPos = (newPos-oldPos); //sets change in position from one iteration to the next
oldPos = newPos; //Sets old to new to fail if statement unless movement is detected.
initialTime = finalTime; //sets time at beginning of loop to time of ending last loop in order to correctly calculate deltaT in the next iteration
//Serial.println(deltaPos/deltaTime); //Prints rate of the encoder disk in deg/ms (Confirmed by manually taking data and seeing that 1 Rotation outputs values from 0-360
}
counter = 1;
PWMcount=PWMcount+1;
analogWrite(RPWM_Output, PWMcount); // Increases Motor PWM in accordance to loop
Serial.println(PWMcount); // UNCOMMENT TO TROUBLESHOOT PWM
delay(100);
}
}
A couple of notes:
The loop condition does not bother to check the counter value, because the loop body obviates the comparison. The counter variable is always less than 4.
I moved the last two lines of the outer loop into the else branch of the if statement. They never executed in your original code, so maybe you just want to remove them altogether. But if the intent was to execute those two lines each line the inner loop reached its end (i.e. counter is 3), then this change matches that intent.

How to count peaks multiple times?

I am opening a valve to let fluid flow. The pressure being measured here is with how much pressure the fluid is being pulled into a system. I am trying to measure the average value of only first 10 Pdiff (PMax-PMin). once the average value is calculated, the valve is closed.
And based on this average value, the valve will again open and close for 1 peak, and then for 2 peaks, and for 3 peaks and so on. I am storing the pressure value in an array and comparing the value with its before and after value, I get max and min values.
You increment your peakcounter using ++peakcounter but then immediately set peakcounter=0 in the if block of if(peakcounter==0)
Since you reset your peakcounter, you never get to peakcounter == 2
if ( valstate == false && Pdelta >= average)
{
{
++peakcounter; // keeps the count of how many times the value has gone
above average
}
// Checks for the number of times and then performs action
if (peakcounter == 1) {
digitalWrite(4, HIGH);
startTime = millis();
valstate = true;
peakcounter = 0; //the offending line
}
What you need to do the following (Note: code is not optimized. I don't fully understand what you need, but this should fix the issue you wrote about)
int currentMax = 0;
// your code here....
if ( valstate == false && Pdelta >= average){
++peakcounter;
if(peakcounter > currentMax){
// Checks for the number of times and then performs action
if (peakcounter == 1) {
digitalWrite(4, HIGH);
startTime = millis();
valstate = true;
peakcounter = 0;
currentMax++;
}
//the rest of your peakcount checking code here
}

Converting area of intersection to generate a coordinate

I was working on a project where I get analog values from a resistive touchscreen and turn them into intersection points.
Here is an example:
Here is my code for the data collection using an Arduino Uno and construction of the points using tool called processing.
#define side1 2
#define side2 3
#define side3 4
#define side4 5
#define contact A0
void setup() {
pinMode(contact, INPUT);
pinMode(side1, OUTPUT);
pinMode(side2, OUTPUT);
pinMode(side3, OUTPUT);
pinMode(side4, OUTPUT);
Serial.begin(9600);
}
void loop() {
int sensorValue1;
int sensorValue2;
int sensorValue3;
int sensorValue4;
// SENSOR VALUE 1:
digitalWrite(side1, LOW);
digitalWrite(side2, HIGH);
digitalWrite(side3, HIGH);
digitalWrite(side4, HIGH);
delay(5);
for (int i = 0; i < 10; i++){
sensorValue1 = analogRead(contact);
}
// SENSOR VALUE 2:
digitalWrite(side2, LOW);
digitalWrite(side3, HIGH);
digitalWrite(side4, HIGH);
digitalWrite(side1, HIGH);
delay(5);
for (int i = 0; i < 10; i++){
sensorValue2 = analogRead(contact);
}
// SENSOR VALUE 3:
digitalWrite(side3, LOW);
digitalWrite(side2, HIGH);
digitalWrite(side4, HIGH);
digitalWrite(side1, HIGH);
delay(5);
for (int i = 0; i < 10; i++){
sensorValue3 = analogRead(contact);
}
// SENSOR VALUE 2:
digitalWrite(side4, LOW);
digitalWrite(side3, HIGH);
digitalWrite(side2, HIGH);
digitalWrite(side1, HIGH);
delay(5);
for (int i = 0; i < 10; i++){
sensorValue4 = analogRead(contact);
}
Serial.print(sensorValue1);
Serial.print(",");
Serial.print(sensorValue2);
Serial.print(",");
Serial.print(sensorValue3);
Serial.print(",");
Serial.print(sensorValue4);
Serial.println();
}
This is the Processing code for the construction of the graph.
import processing.serial.*;
Serial myPort; // The serial port
int maxNumberOfSensors = 4;
float[] sensorValues = new float[maxNumberOfSensors];
float sensorValueX;
float sensorValueX1;
float sensorValueY;
float sensorValueY1;
int scaleValue = 2;
void setup () {
size(600, 600); // set up the window to whatever size you want
//println(Serial.list()); // List all the available serial ports
String portName = "COM5";
myPort = new Serial(this, portName, 9600);
myPort.clear();
myPort.bufferUntil('\n'); // don't generate a serialEvent() until you get a newline (\n) byte
background(255); // set inital background
smooth(); // turn on antialiasing
}
void draw () {
//background(255);
//noFill();
fill(100,100,100,100);
ellipse(height,0, scaleValue*sensorValues[0], scaleValue*sensorValues[0]);
ellipse(0,width, scaleValue*sensorValues[1], scaleValue*sensorValues[1]);
ellipse(height,width, scaleValue*sensorValues[2], scaleValue*sensorValues[2]);
ellipse(0,0, scaleValue*sensorValues[3], scaleValue*sensorValues[3]);
//ellipse(sensorValueY, sensorValueX, 10,10);
//println(sensorValueY,sensorValueX);
sensorValueX = ((sensorValues[3]*sensorValues[3])-(sensorValues[2]*sensorValues[2])+600*600)/2000;
sensorValueX1 = ((sensorValues[0]*sensorValues[0])-(sensorValues[1]*sensorValues[1])+600*600)/2000;
sensorValueY = ((sensorValues[3]*sensorValues[3])-(sensorValues[2]*sensorValues[2])+(600*600))/2000;
sensorValueY1 = ((sensorValues[1]*sensorValues[1])-(sensorValues[0]*sensorValues[0])+(600*600))/2000;
line(0, scaleValue*sensorValueX, height,scaleValue* sensorValueX);
line(scaleValue*sensorValueY, 0, scaleValue*sensorValueY, width);
ellipse(scaleValue*sensorValueY, scaleValue*sensorValueX, 20,20);
line(0, scaleValue*sensorValueX1, height,scaleValue* sensorValueX1);
line(scaleValue*sensorValueY1, 0, scaleValue*sensorValueY1, width);
ellipse(scaleValue*sensorValueY1, scaleValue*sensorValueX1, 20,20);
println(scaleValue*sensorValueX,scaleValue*sensorValueY);
}
void serialEvent (Serial myPort) {
String inString = myPort.readStringUntil('\n'); // get the ASCII string
if (inString != null) { // if it's not empty
inString = trim(inString); // trim off any whitespace
int incomingValues[] = int(split(inString, ",")); // convert to an array of ints
if (incomingValues.length <= maxNumberOfSensors && incomingValues.length > 0) {
for (int i = 0; i < incomingValues.length; i++) {
// map the incoming values (0 to 1023) to an appropriate gray-scale range (0-255):
sensorValues[i] = map(incomingValues[i], 0, 1023, 0, width);
//println(incomingValues[i]+ " " + sensorValues[i]);
}
}
}
}
I was wondering how I could convert the intersection of those points to a coordinate? Example: in the image, I showed you, I set the parameters for the dimensions to be (600,600). Is it possible to change that intersection are to a coordinate value? Currently, my code is printing out coordinates however they are diagonals such at the x and y values are equal. I want the coordinates of x and y to have different quantities so that I can get coordinates for different sides in the square. Can somebody help?
By reading your code I'm assuming that you know the position of all n sensors and the distance from each n sensor to a target. So what you're essentially trying to do is trilateration (as mentioned by Nico Schertler). In other words determining a relative position based on the distance between n points.
Just a quick definition note in case of confusion:
Triangulation = Working with angles
Trilateration = Working with distances
Trilateration requires at least 3 points and distances.
1 sensor gives you the distance the target is away from the sensor
2 sensors gives you 2 possible locations the target can be
3 sensors tells you which of the 2 locations the target is at
The first solution that probably comes to mind is calculating the intersections
between 3 sensors treating them as circles. Given that there might be some error in the distances this means that the circles might not always intersect. Which rules out this solution.
The following code has all been done in Processing.
I took the liberty of making a class Sensor.
class Sensor {
public PVector p; // position
public float d; // distance from sensor to target (radius of the circle)
public Sensor(float x, float y) {
this.p = new PVector(x, y);
this.d = 0;
}
}
Now to calculate and approximate the intersection point between the sensors/circles, do the following:
PVector trilateration(Sensor s1, Sensor s2, Sensor s3) {
PVector s = PVector.sub(s2.p, s1.p).div(PVector.sub(s2.p, s1.p).mag());
float a = s.dot(PVector.sub(s3.p, s1.p));
PVector t = PVector.sub(s3.p, s1.p).sub(PVector.mult(s, a)).div(PVector.sub(s3.p, s1.p).sub(PVector.mult(s, a)).mag());
float b = t.dot(PVector.sub(s3.p, s1.p));
float c = PVector.sub(s2.p, s1.p).mag();
float x = (sq(s1.d) - sq(s2.d) + sq(c)) / (c * 2);
float y = ((sq(s1.d) - sq(s3.d) + sq(a) + sq(b)) / (b * 2)) - ((a / b) * x);
s.mult(x);
t.mult(y);
return PVector.add(s1.p, s).add(t);
}
Where s1, s2, s3 is any of your 3 sensors, do the following to calculate the the intersection point between the given sensors:
PVector target = trilateration(s1, s2, s3);
While it is possible to calculate the intersection between any amount of sensors. It becomes more and more complex the more sensors you want to include. Especially since you're doing it yourself. If you're able to use external Java libraries, then it would be a lot easier.
If you're able to use external Java libraries, then I highly recommend using com.lemmingapex.trilateration. Then you'd be able to calculate the intersection point between 4 sensors by doing:
Considering s1, s2, s3, s4 as instances of the previously mentioned class Sensor.
double[][] positions = new double[][] { { s1.x, s1.y }, { s2.x, s2.y }, { s3.x, s3.y }, { s4.x, s4.y } };
double[] distances = new double[] { s1.d, s2.d, s3.d, s4.d };
NonLinearLeastSquaresSolver solver = new NonLinearLeastSquaresSolver(
new TrilaterationFunction(positions, distances),
new LevenbergMarquardtOptimizer());
Optimum optimum = solver.solve();
double[] target = optimum.getPoint().toArray();
double x = target[0];
double y = target[1];
The following examples, are examples of the trilateration() method I wrote and not an example of the library above.
Example 1 - No Sensor Error
The 3 big circles being any 3 sensors and the single red circle being the approximated point.
Example 2 - With Sensor Error
The 3 big circles being any 3 sensors and the single red circle being the approximated point.
What you need to compute is the point that it nearest to the a set of circles,
let denote their centers by (x1,y1), (x2,y2), (x3,y3), (x4,y4) and their radii by r1,r2,r3,r4.
You want to find (x,y) that minimizes
F(x,y) = Sum_i [ square( d2( (x,y), (xi,yi)) - ri) ]
This can be achieved by using Newton's algorithm. Newton's algorithm works from an "initial guess" (let's say at the center of the screen), improved iteratively by solving a series of linear systems (in this case, with 2 variables, easy to solve).
M P = -G
where M is the (2x2) matrix of the second order derivatives of F with respect to x and y (called the Hessian), and G the vector of the first order derivatives of F with
respect to x and y (the gradient). This gives the "update" vector P, that tells how to move the coordinates:
Then (x,y) is updated by x = x + Px, y = y + Py, and so on and so forth (recompute M and G, solve for P, update x and y, recompute M and G, solve for P, update x and y). In your case it will probably converge in a handful of iterations.
Since you got two variables only, the 2x2 linear solve is trivial, and the expression of F and its derivatives is simple, thus you can implement it without needing an external library.
Note1: the Levenberg-Marquardt algorithm mentioned in the other answer is a variant of Newton's algorithm (specialized for sum of squares, like here, and that neglects some terms, and that regularizes the matrix M by adding small numbers to its diagonal coefficients). More on this here.
Note2: a simple gradient descent will also probably work (a bit simpler to implement, since it only uses first order derivatives), but given that you only got two variables to implement, the 2x2 linear solve is trivial, so Newton is probably worth it (requires a much much smaller number of iterations for convergence, may be critial if your system is interactive).

Having incrementing problems in Arduino code

Basically I am reading raw values from an accelerometer (i.e these values change in response to gravity and acceleration).
I have set a range of values for the raw values(i.e from -100 to 100 instead):
x = map(ax, -2048, 2048, -100, 100 );
now im trying to increment "count" x greater than 50:
if (x>50) {
count++;
}
main example code here:
void loop(){
x = map(ax, -2048, 2048, -100, 100 );
if (x>50) {
count++;
}
}
but when I compile the code, x becomes greater than 50 and the count just keeps incrementing and what I want it to do is count 'one by one' only when the value becomes greater than 50 seen as the values change as accelerometer moves?
I think you want to count how many times you measure a value over 50. If you check the condition in every loop() iteration, then you will get how many time (measured in loops) the value is over 50.
You need something like this
boolean checked = false;
void loop(){
x = map(ax, -2048, 2048, -100, 100 );
if (x > 50 && !checked) {
count++;
checked = true;
}
if (x < 50 && checked) {
checked = false;
}
}

why fundamental Frequency and magnitude are not null when microphone is off?

I would like to make real time audio processing with Qt and display the spectrum using FFTW3.
What I've done in steps:
I capture any sound from computer device and fill it into the buffer.
I assign sound samples to double array
I compute the fundamental frequency.
when I'm display the fundamental frequency and Magnetitude when the microphone is on but no signal(silence) , the fundamental frequency is not what I expected , the code don't always return zero , sometimes the code returns 1500Hz,2000hz as frequency
and when the microphone is off (mute) the code don't return zero as fundamamental frequency but returns a number between 0 and 9000Hz. Any help woulbd be appreciated
here is my code
QByteArray *buffer;
QAudioInput *audioInput;
audioInput = new QAudioInput(format, this);
//Check the number of samples in input buffer
qint64 len = audioInput->bytesReady();
//Limit sample size
if(len > 4096)
len = 4096;
//Read sound samples from input device to buffer
qint64 l = input->read(buffer.data(), len);
int input_size= BufferSize;
int output_size = input_size; //input_size/2+1;
fftw_plan p3;
double in[output_size];
fftw_complex out[output_size];
short *outdata = (short*)m_buffer.data();// assign sample into short array
int data_size = size_t(outdata);
int data_size1 = sizeof(outdata);
int count = 0;
double w = 0;
for(int i(chanelNumber); i < output_size/2; i= i + 2) //fill array in
{
w= 0.5 * (1 - cos(2*M_PI*i/output_size)); // Hann Windows
double x = 0;
if(i < data_size){
x = outdata[i];
}
if(count < output_size){
in[count] = x;// fill Array In with sample from buffer
count++;
}
}
for(int i=count; i<output_size; i++){
in[i] = 0;
}
p3 = fftw_plan_dft_r2c_1d(output_size, in, out, FFTW_ESTIMATE);// create Plan
fftw_execute(p3);// FFT
for (int i = 0; i < (output_size/2); i++) {
long peak=0;
double Amplitudemax=0;
double r1 = out[i][0] * out[i][0];
double im1 = out[i][3] * out[i][4];
double t1 = r1 + im1;
//double t = 20*log(sqrt(t1));
double t = sqrt(t1)/(double)(output_size/2);
double f = (double)i*8000 / ((double)output_size/2);
if(Magnitude > AmplitudeMax)
{
AmplitudeMax = Magnitude;
Peak =2* i;
}
}
fftw_destroy_plan(p3);
return Peak*(static_cast<double>(8000)/output_Size);
What you think is silence might contain some small amount of noise. The FFT of random noise will also appear random, and thus have a random magnitude peak. But it is possible that noise might come from equipment or electronics in the environment (fans, flyback transformers, etc.), or the power supply to your ADC or mic, thus showing some frequency biases.
If the noise level is low enough, normally one checks the level of the magnitude peak, compares it against a threshold, and cuts off frequency estimation reporting below this threshold.

Resources