Why does combining these if statements result in higher logic element utilization? - verilog

I have a project in verilog where I'm keeping track of the date. I have the following code to handle the different length of months, unless I am mistaken I can combine these all by oring each condition and just having one if statement. This however will result in using 1 more LE. Why?
if( ( months == 4 || months == 6 || months == 9 || months == 11 ) && days == 31 && set_state == 0 ) begin
months = months + 1;
days = 1;
end
else if( months == 2 && years[1:0] == 0 && days == 30 && set_state == 0 ) begin
months = months + 1;
days = 1;
end
else if( months == 2 && years[1:0] != 0 && days == 29 && set_state == 0 ) begin
months = months + 1;
days = 1;
end
else if( days == 32 ) begin
months = months + 1;
days = 1;
end
EDIT: This is what uses the additional LE
if( ( ( months == 4 || months == 6 || months == 9 || months == 11 ) && days == 31 && set_state == 0 ) ||
( months == 2 && years[1:0] == 0 && days == 30 && set_state == 0 ) ||
( months == 2 && years[1:0] != 0 && days == 29 && set_state == 0 ) ||
( days == 32 ) ) begin
months = months + 1;
days = 1;
end

The two statements are logically equivalent using the following Boolean law:
A | (~A & B) = A | B
I think it has to do with the synthesis tool logic minimization algorithm that does not synthesize exactly the same circuits, although they are logically equivalent.

Related

cs50 Credit issue with identifying card company

I'm completely new to programming and have been working through pset1 this week but credit is proving to be a bit tough. I've managed to get the checksum working but I'm having real trouble identifying which company the card belongs to, the last part of the code seems to introduce more errors every time I try to fix it. I would really appreciate it if anybody could point me in the right direction.
#include <cs50.h>
#include <stdio.h>
int main (void)
{
long long ccnumber;
do
{
ccnumber = get_long_long("Credit card number: ");
}
while (ccnumber < 0);
long long cc = ccnumber;
int s1;
while (cc > 0)
{
int l1 = cc % 10;
s1 = s1 + l1;
cc = cc / 100;
}
cc = ccnumber / 10;
int s2;
while (cc > 0)
{
int l1 = cc % 10;
l1 = l1 * 2;
if (l1 > 9) l1 = l1 % 10 + l1 / 10;
s2 = s2 + l1;
cc = cc / 100;
}
int s3 = s1 + s2;
if (s3 % 10 == 0)
s3 = true;
long long n = ccnumber;
int count = 0;
while (n != 0)
{
n /= 10;
++count;
}
int twonumbers = ccnumber;
while(twonumbers >= 100)
{
twonumbers = twonumbers / 10;
}
int firstnumber = ccnumber;
while(firstnumber >= 10)
{
firstnumber = firstnumber / 10;
}
if (twonumbers == 34 || 37 && (count == 15 ))
printf("AMERICAN EXPRESS\n");
else if (twonumbers == 51 || 52 || 53 || 54 | 55 && (count == 16 ))
printf("MASTER CARD\n");
else if (firstnumber == 4 && (count == 13 || 16 ))
printf("VISA\n");
else
printf("INVALID\n");
}
Your ending if statements are not correct:
if (twonumbers == 34 || 37 && (count == 15 ))
...
should be
if ((twonumbers == 34 || twonumbers == 37) && (count == 15 ))
And the same for each if statement - you have to repeat what is being compared for every or statement or the compiler will assume "true" as in this case, 37 is no equal to 0.
Not, you can also compare ranges as well:
else if (twonumbers >= 51 && twonumbers <= 55 && count == 16)
Note I also correct a binary or there on the last compare (you had only 1 | and not 2 ||)
The last is
else if (firstnumber == 4 && (count == 13 || count == 16 ))
I also question what:
int s3 = s1 + s2;
if (s3 % 10 == 0)
s3 = true;
is doing as this will actually always be "true" in a C sense, but in reality, you don't actually use s3 anywhere so I am confused.
Lastly, turn on all compiler warning. It would have told you about a lot of the things I mention here.
Now, I am not saying that this is the only thing wrong here, but it was the most obvious.

Convert SystemVerilog assertion with delay to invarspec

I want to convert a SystemVerilog assertion with delay into an invarspec of a formal verifier. The synthesizer gives syntax error for ##1 in the code line below.
assert property ( ( req1 == 0 ) ##1( req1 == 1 ) ##1 !( req2 == 1 ) || ( gnt1 == 0 ) );
There are several properties that are to be verified and have delays. I am currently trying to convert them into formal (SMV) model specifications using a synthesizer which works fine for the properties not involving delays. Can I model delay for this formal verifier tool ? If so, how?
One approach is to explicitly model the delayed version of the signals in Verilog, and then you can use an assertion that has no time dependency.
For your example:
assert property ( ( req1 == 0 ) ##1( req1 == 1 ) ##1 !( req2 == 1 ) || ( gnt1 == 0 ) );
becomes:
reg req1_r,req1_rr;
always #(posedge clk) begin
req1_rr <= req1_r;
req1_r <= req1;
end
assert property ( !(( req1_rr == 0 ) && ( req1_r == 1 ))
|| !( req2 == 1 ) || ( gnt1 == 0 ) );

Apache Spark: Optimization Filter

So this is more of a design question.
Right now, I have a list of patient ids and I need to put them into one of 3 buckets.
The bucket they go into is completely based on the following RDDs
case class Diagnostic(patientID:String, date: Date, code: String)
case class LabResult(patientID: String, date: Date, testName: String, value: Double)
case class Medication(patientID: String, date: Date, medicine: String)
Right now I'm basically going to each RDD 3-4 times per patient_id per bucket to see if it goes into a bucket. This runs extremely slow, is there anything I can do to improve this?
Example is for bucket 1, I have to check if there a diagnostic, for patient_id 1 (even though there are multiple), has a code of 1 and that patient_id 1 has a medication where medicine is foo
Right now I'm doing this as two filters (one on each RDD)....
Ugly code example
if (labResult.filter({ lab =>
val testName = lab.testName
testName.contains("glucose")
}).count == 0) {
return false
} else if (labResult.filter({ lab =>
val testName = lab.testName
val testValue = lab.value
// all the built in rules
(testName == "hba1c" && testValue >= 6.0) ||
(testName == "hemoglobin a1c" && testValue >= 6.0) ||
(testName == "fasting glucose" && testValue >= 110) ||
(testName == "fasting blood glucose" && testValue >= 110) ||
(testName == "glucose" && testValue >= 110) ||
(testName == "glucose, serum" && testValue >= 110)
}).count > 0) {
return false
} else if (diagnostic.filter({ diagnosis =>
val code = diagnosis.code
(code == "790.21") ||
(code == "790.22") ||
(code == "790.2") ||
(code == "790.29") ||
(code == "648.81") ||
(code == "648.82") ||
(code == "648.83") ||
(code == "648.84") ||
(code == "648.0") ||
(code == "648.01") ||
(code == "648.02") ||
(code == "648.03") ||
(code == "648.04") ||
(code == "791.5") ||
(code == "277.7") ||
(code == "v77.1") ||
(code == "256.4") ||
(code == "250.*")
}).count > 0) {
return false
}
true

Trying to add a char to my if statement

This is Java/Groovy (we're learning syntax first). I've been stuck on it for 2 days.
This is my code:
char am = "a";
char pm = "p";
def to24hour(int hour) {
if (hour >= 1 && hour <= 12) {
int newHour = hour + 12;
return newHour;
} else if (hour >= 13 && hour <= 24) {
int newHour = hour
return newHour;
} else if (hour == 0){
int newHour = hour
return "invalid number used!";
} else {
return "invalid number used!";
}
}
to24hour(3);
This is the question:
Write a function called to24Hour that takes two parameters: an hour value and a letter that should be either A or P. The function converts a time specified as AM or PM to hours on the 24 hour clock. So, for example, calling the function with values 5 and P should return 17 whereas 5 and A should return 5. What are the possible problems with such a function (if invalid values are used)? How could you deal with these problems?
Try this:
char am = "a";
char pm = "p";
int to24hour(int hour, char clock) {
if (hour >= 1 && hour <= 11) {
if(clock == "p") return hour + 12
else return hour
} else if(hour == 12) {
if(clock == "p") hour
else return 0
} else {
throw Exception("invalid number used!")
}
}
[1..12, (1..11).toList() + [0]]
.transpose()
.each { assert to24hour(it[0], am) == it[1] }
[1..12, (13..23).toList() + [12]]
.transpose()
.each { assert to24hour(it[0], pm) == it[1] }

Finding the number of days in a month

I am making a program to display the no. of days in the month provided by user. I am making this program at Data Flow level. As I am new to verilog, I don't know if we can use if/else conditions or case statement in data flow level. because using if/else statement will make this program piece of cake. If not how can I implement the following idea in data flow level.
if(month==4 || month==6 || month==9|| month==11)
days=30;
else
if(month==2 && leapyear==1)
days=29;
Here is my verilog incomplete code:
module LeapYear(year,month,leapOrNot,Days);
input year,month;
output leapOrNot,Days;
//if (year % 400 == 0) || ( ( year % 100 != 0) && (year % 4 == 0 ))
leapOrNot=((year&400)===0) && ((year % 100)!==0 || (year & 4)===0);
Days=((month & 4)===4 ||(month & 6)===6 ||(month & 9)===9 ||(month & 11)===11 )
You cannot use if/else in a continuous assignment, but you can use the conditional operator, which is functionally equivalent.
Try this:
assign Days = (month == 4 || month == 6 || month == 9 || month == 11) ? 30 :
(month == 2 && leapyear == 1) ? 29;
That will produce what you put in your question. But's its not the correct answer as you are missing the conditions where Days is equal to 28 or 31.
EDIT:
Here's how to combine all the conditions into a single assign statement using the conditional operator.v
assign Days = (month == 4 || month == 6 || month == 9 || month == 11) ? 30 :
(month == 2 && leapyear == 1) ? 29 :
(month == 2 && leapyear == 0) ? 28 :
31;

Resources