How can I use Verilog defines in an if-else statements - if-statement

I have a Verilog define like this:
`define NUM_BANKS 4
and if want to use it in the following code:
if (`NUM_BANKS > 1)
do something ..
else
do something else ..
Lint tool is complaining that this expression is going to always be evaluated to true.

After the `define is applied, the if will always evaulate 4 > 1. The compiler is giving an error, since the if will always be irrelevant.
I'd recommend either replacing your `define with a parameter (if you're looking to have it be changed by a higher-level module or instantiation), or use the compiler directives (http://www.csee.umbc.edu/portal/help/VHDL/verilog/compiler.html for example)
`define HASBANKS
`ifdef (HASBANKS)
...
`else
...
`endif

Lint is correct, since in your expression, 4 > 1 is always true. So if this is what you want, there is no problem.
Neo

Related

Why is this allowed in If statements in various languages?

In various programming and scripting languages like C and PHP, if statements use the following convention:
if ( variable == 1 ) { do something }
As far as I know, every language that follows this convention also allows:
if ( variable = 1 ) { do something }
This is a not too uncommon mistake even a seasoned programmer can make. Rather than a comparison, it is an assignment, which will (almost) always be successful and return 1, which is a non-zero number, meaning true. The only time I think this would fail is if the variable isnt in scope or possibly a type mismatch. Yes, all its looking for 1 or 0, true of false and the comparison itself is irrelevant. However, I assume a compariison makes up 99.9999% of these if statements. Is there a reason a comparison isnt required? Why is this allowed? Am I missing something obvious?

If... else condition in LUA language

I'm new to coding and I recently started to take my baby steps in LUA. I have a small problem so it would be very helpful if you can help me. In my code, I need to code that
If x ~= 1 and x~=2 and x~=3 and x~=4 then (do something) end
is there a faster way not to hardcode that part, not to type the whole thing from x~=1 to x~=4?
Thank you!
If you need something like if x ~= 1 and x~=2 and x~=3 and x~=4 then (do something) end x is usually an integer.
Then
if x < 1 or x > 4 then
-- do your stuff here
end
Is what you are looking for. If you want to explicitly check wether x is unquald 1,2,3,4 you can simply do something like Egor suggested.
But as you see unless you can describe your conditions in a shorter mathematical way you still have separate unique conditions and you won't come around writing them down.
If you have to check those conditions repeatedly you can use a truth table like in Egor's example or you write a function that returns if that condition is met for its argument.

How do I return the value after checking for a condition?

The following code has to check for an 'e' value such that the gcd(h,e)=1. Where 1
module great(p,q,e,d);
input p,q;
output e,d;
reg e,d;
h=((p-1)*(q-1));
always
begin
for(e=2;e<h;e=e+1)
begin
g1=gcd(h,e);
if(g1==1)
return e;
If, by "return a value", you mean spit out a value you can use in another module, you would use the output of this module as your "return" value. But even ignoring the return e, I don't think your code will work if you tried to run it, because it is too much like a programming language. There's several major things wrong:
You already declared output e,d so you can't declare two reg with the same name. You probably want output reg e,d instead.
You didn't declare a type for h or g1.
You have a for loop for e but e can never be anything other than 0 or 1 because you didn't set a size for it, so by default it is only 1-bit long. Even if it was big enough that you could increment it past 1, it's a wire type by default, and you can't make those kind of increments to a wire directly.
I assume gcd is some module you made somewhere else, but this isn't how you interconnect modules together. You can't call it like it's a function. You have to use wire and reg to connect the inputs and outputs of two modules together, almost like you're plugging components in.
Those are what stick out the most to me, anyway. I think you are coding your Verilog as if it were Python and that's what's causing these misunderstandings. Verilog is very, very different.

Read and write variable in an IF statement

I'm hoping to perform the following steps in a single IF statement to save on code writing:
If ret is TRUE, set ret to the result of function lookup(). If ret is now FALSE, print error message.
The code I've written to do this is as follows:
BOOLEAN ret = TRUE;
// ... functions assigning to `ret`
if ( ret && !(ret = lookup()) )
{
fprintf(stderr, "Error in lookup()\n");
}
I've got a feeling that this isn't as simple as it looks. Reading from, assigning to and reading again from the same variable in an IF statement. As far as I'm aware, the compiler will always split statements like this up into their constituent operations according to precedence and evaluates conjuncts one at a time, failing immediately when evaluating an operand to false rather than evaluating them all. If so, then I expect the code to follow the steps I wrote above.
I've used assignments in IF statements a lot and I know they work, but not with another read beforehand.
Is there any reason why this isn't good code? Personally, I think it's easy to read and the meaning is clear, I'm just concerned about the compiler maybe not producing the equivalent logic for whatever reason. Perhaps compiler vendor disparities, optimisations or platform dependencies could be an issue, though I doubt this.
...to save on code writing This is almost never a valid argument. Don't do this. Particularly, don't obfuscate your code into a buggy, unreadable mess to "save typing". That is very bad programming.
I've got a feeling that this isn't as simple as it looks. Reading from, assigning to and reading again from the same variable in an IF statement.
Correct. It has little to do with the if statement in itself though, and everything to do with the operators involved.
As far as I'm aware, the compiler will always split statements like this up into their constituent operations according to precedence and evaluates conjuncts one at a time
Well, yes... but there is operator precedence and there is order of evaluation of subexpressions, they are different things. To make things even more complicated, there are sequence points.
If you don't know the difference between operator precedence and order of evaluation, or if you don't know what sequence points are, you need to instantly stop stuffing as many operators as you can into a single line, because in that case, you are going to write horrible bugs all over the place.
In your specific case, you get away with the bad programming just because as a special case, there happens to be a sequence point between the left and right evaluation of the && operator. Had you written some similar mess with a different operator, for example ret + !(ret = lookup(), your code would have undefined behavior. A bug which will take hours, days or weeks to find. Well, at least you saved 10 seconds of typing!
Also, in both C and C++ use the standard bool type and not some home-brewed version.
You need to correct your code into something more readable and safe:
bool ret = true;
if(ret)
{
ret = lookup();
}
if(!ret)
{
fprintf(stderr, "Error in lookup()\n");
}
Is there any reason why this isn't good code?
Yes, there are a lot issues whith such dirty code fragments!
1)
Nobody can read it and it is not maintainable. A lot of coding guidlines contain a rule which tells you: "One statement per line".
2) If you combine multiple expressions in one if statement, only the first statements will be executed until the expression is defined! This means: if you have multiple expressions which combined with AND the first expression which generates false will be the last one which will be executed. Same with OR combinations: The first one which evaluates to true is the last one which is executed.You already wrote this and you! know this, but this is a bit of tricky programming. If all your colleges write code that way, it is maybe ok, but as I know, my colleagues will not understand what you are doing in the first step!
3) You should never compare and assign in one statement. It is simply ugly!
4) if YOU! already think about " I'm just concerned about the compiler maybe not producing the equivalent logic" you should think again why you are not sure what you are doing! I believe that everybody who must work with such a dirty code will think again on such combinations.
Hint: Don't do that! Never!

What's the point of issuing a compiler warning for "while(true)" and not issuing one for "for(;;)"?

When I compile C++ code with Visual C++ 9 with "warning level 4" the following:
while( true ) {
//loop body with break on certain condition
}
and the following:
for( ; true; ) {
//same loop body
}
both trigger C4127: conditional expression is constant warning but the following:
for( ; ; ) {
//same loop body
}
compiles without warning.
Why this difference, especially between the second and the third variant?
The reason for warning the user of constant conditional expressions is to help avoid bugs where the expression ends up being constant (for example, due to a typo). In the last case, there is no expression, so there is no risk of it accidentally being constant.
The reason is simple, though stupid.
It is important to diagnose infinite loop, but such might not be evident:
while(i >= 0) { --i; } // infinite if i unsigned
while(SOME_MACRO(i)) // err, depends on the expansion of macros
It is a great feature of a compiler to produce a warning for a tautological test, that is a test that turns out to be either always true or always false, because it's not obvious when it comes from a macro expansion or within a dependent context.
It just seems that VC++ pushed a bit too far here, and instead of considering tautological conditions warns for all true or false conditions it can find, even when they are already clearly stated in the code.
The for ( ;; ) construct is the canonical way to intentionally code an "endless" loop. I could imagine the compiler designers didn't want to generate a warning for that.
No point. After all, the langauge specification says ($6.5.3/2),
Either or both of the condition and
the expression can be omitted. A
missing condition makes the implied
while clause equivalent to
while(true).
So for ( ; ; ) is equivalent to while(true) even according to the Standard. Therefore, I don't see any reason why the compiler should give warning in one case but not in the other!
--
If the compiler decides to give warning, then in my opinion, the compiler should give warning when the condition is missing as opposed to when it's present, so that the warning would be interpreted as hint for programmer to mention his intention clearly and explicitly.
I mean, for ( ;; ) is more likely to be a typo than the explicit mention of condition in for ( ;true; ). The latter tells programmer's clear and explicit intent. As Steve says in comment:
For an int value y, char x = y is
equivalent to char x = (char)y, but
you might want a warning for an
implicit narrowing conversion on the
first but not the second.
So explicit intention should not receive warning, while implicit intention should receive!
Compiler warning are here to help catch potential bugs. Using an always true condition in a while loop is probably an error. For exemple, in the following code, this is probably a bug, and I'd like the compiler to warn me about it:
unsigned int x;
// ...
while (x >= 0) {
// ...
}
In such a situation, in optimized build the compiler will probably deduce that the condition is always true (since an unsigned integer cannot be smaller than 0). So there is a need for detection of an always true condition in while loop. I think that whoever wrote the detection of such an error didn't special case the while (true) case, as there is a simple way to do a infinite loop with for (;;).
You can read here, how the decision to add a warning or not in Visual Studio, is taken (the exemple are about C# but I suppose that the team has the same rule of thumb for warning in C++).