I have noticed that there is a precedence of assignment while using if-else conditionals in Verilog. For example as in the code below:
if(counter < 6)
z <= 1;
else if(counter < 12)
z <= 2;
else
z <= 3;
I noticed that until the counter is less than 6, the value of z is assigned the value of 1 (z <= 1) and as soon as the value of the counter exceeds 6 and is less than 12, z is assigned the value 2 (z <= 2).
What if there are different variables used inside the conditionals as in the code below?
if(wire1_is_enabled)
z <= 1;
else if(wire2_is_enabled)
z <= 0;
What happens when both conditions are true? What is the behaviour of the assignment operator here?
I believe this is poor programming habit.
Yes, nested if-else branching statements naturally assume a priority in the order of execution. Think about using a case statement instead of deeply nesting if statements which are much more readable.
There is nothing wrong with this coding style unless you have code like:
if(counter < 6)
z <= 1;
else if(counter < 2)
z <= 2; // unreachable
else
z <= 3;
Then the statement z <= 2; becomes unreachable because when the first condition is false, the second condition can never be true. Fortunately there are a number of tools that can flag this problem for you.
Both if and case statements assume priority logic. However, you have an option to explicitly add a priority or unique keyword before the if or case keywords to declare and check your intent. See sections 12.4 and 12.5 in the IEEE 1800-2017 SystemVerilog LRM.
The 2 if/else statements behave the same way; the first condition to be true has the highest priority. Once a condition evaluates to true, all the following else clauses are ignored. Therefore, z <= 1 if both wire1_is_enabled and wire2_is_enabled are true. This is easy to prove to yourself with a simple simulation.
This is not a poor coding habit. This situation is common in Verilog. When you say programming, perhaps you are thinking of software languages. Keep in mind that these are hardware signals instead of software variables.
Related
I want to write something utterly ridiculous that calls for a great depth of conditional nesting. The least disorienting way to write this is to forgo brackets entirely, but I have not been able to find any info on if nesting single-statement if-else guards is legal; the non-nested version causes people enough problems it seems.
Is it valid to write the following? (In both C and C++, please let me know if they differ on this.)
float x = max(abs(min), abs(max));
uint32 count = 0u;
// divides and conquers but, tries to shortcut toward more common values
if (x < 100'000.f)
if (x < 10.f)
count = 1u;
else
if(x < 1'000.f)
if (x < 100.f)
count = 2u;
else
count = 3u;
else
if (x < 10'000.f)
count = 4u;
else
count = 5u;
else
... // covers the IEEE-754 float32 range to ~1.0e+37 (maybe 37 end branches)
--skippable lore--
The underlying puzzle (this is for fun) is that I want to figure out the number of glyphs necessary to display a float's internal representation without rounding/truncation, in constant time. Counting the fractional part's glyph count in constant time was much neater/faster, but unfortunately I wasn't able to figure out any bit-twiddling tricks for the integer part, so I've decided to just brute-force it. Never use math when you can use your fists.
From cppreference.com:
in nested if-statements, the else is associated with the closest if that doesn't have an else
So as long as every if has an else, nesting without brackets works fine. The problem occurs when an else should not be associated with the closest if. For example:
if ( condition1 ) {
if ( condition2 )
DoSomething();
} // <-- This is needed so the else goes with the intended if.
else
DoOtherThing();
A quick scan of your code looks like it's fine.
int max_range = 100;
// I do not want to add more else if.. Actually max range is still 100 with more else ifs.
// Range can take values from 0 to 100
if (range <= 10){
a[0]= value;
}
else if (range > 10 && range <= 20){
a[1]= value;
}
else if (range> 20 && range <= 30){
a[2]= value;
}
else if (range > 30 && range <= 40){
a[3]= value;
}
else if (range> 40 && <= max_range){
a[4]= value;
}
It is simple code. I would like it to remove the nested else if's and use a for loop.
How can I convert this into a for loop?
You don't need a loop, you are doing one action.
a[std::max(0, std::min(4, (range - 1) / 10))] = value;
My other answer is very particular to the boundaries being multiples of 10. A runtime modifiable version would be something like
std::set<int> boundaries = { 10, 20, 30, 40, max_range };
// ... potentially modify `a` and `boundaries`, keeping the number of elements equal
a[std::distance(boundaries.begin(), boundaries.lower_bound(range))] = value
I would like it to remove the nested else if's and use a for loop Probably incorrect expression: There's no nested if-else in your example.
Loops, if-else and switch work differently however they all handle conditions:
Loops do iteration; Checking for some condition n times whereas if, switch they check once. So you cannot convert a if-else into a loop.
It's really a good programming trying to make the code effective and as smaller as possible but it is not always the case. If so why such experts build a huge programs with maybe millions of code lines.
Your code works fine.
1.Imagine condition if (obj.is_x() || obj.is_y() || obj.is_z())
Will obj.is_y() and obj.is_z() be called and evaluated if obj.is_x() returned true ?
2.Is this a bad idea(in general)? Does this code look bad ?
bool isbn13_prefix_valid (const string& prefix)
{
unsigned num = stoi(prefix);
if (num == 978 || num == 979) return 1; //super common ones
else if ( num >= 0 && num <= 5 || num == 7 || num >= 600 && num <= 649
|| num >= 80 && num <= 94 || num >= 950 && num <= 989
|| num >= 9900 && num <= 9989 || num >= 99900 && num <= 99999)
return 1;
return 0;
}
No, it will not, due to short-circuiting.
Yes, that code looks bad. Not because it's incorrect, but because you're stuffing an extremely long conditional into a single if statement. Try refactoring your code to make it cleaner.
Your code is absolutely fine. I'd like to see a comment where these strange numbers come from, that's all.
Turning it into a dozen trivial functions as has been suggested is in no way helpful. It actually makes it a lot harder to read the code, because it gets spread out over many many lines of code. Yes, it is complex. But that's due to the problem being complex, and trying to spread the complexity out doesn't help one bit.
Your actual question: In a || b, a is evaluated first. If it is true, then b is not evaluated and the result is true. If a is false, then b is also evaluated and the result is true or false, depending on the result of b.
An optimising compiler may start evaluating b before it has finished evaluating a, if it can prove that the evaluation of b has no side effects, and if it believes that (mostly due to parallelism in the hardware) it is on average faster to evaluate as much in parallel as possible, even if some things are evaluated when it wasn't necessary. But this is not noticable in the results of your code, and will only make the code faster.
I have the following piece of simple code that is potentially going to be executed many hundreds of millions of times;
for (int i = 0; i < 8; i++)
if (((p[i].X >= x) && (p[i].X <= x + d))
&&((p[i].Y >= y) && (p[i].Y <= y + d))
&&((p[i].Z >= z) && (p[i].Z <= z + d)))
return 1;
Will the optimizer in the Visual C++ 2010 compiler unroll this loop for me, or am I better off to do it manually? I've looked at other similar questions but don't see any specific results. I
The real question is, what do you gain from unrolling ?
Unrolling shaves off one branch (if i >= 8 stop) for every "unroll".
Your loop body contains 6 branches already (if * 1, || * 2, && * 3); so is there much to gain in unrolling it ?
It might be interesting to see how the code is optimized; but I am quite unsure whether unrolling should be your primary focus, I'd be more worried about how the complex condition is handled!
if(y-- > 0 && matriz[x][y--]!=9 && matriz[x][y--]!=0)
When i'm doing this, my variable y is not decremented, right? And i can do this comparison y-- > 0?
Imagine that i have y=0, i want to compare if -1 > 0.
Thanks
Assuming all tests pass, your code is effectively equivalent to this:
if (y > 0)
{
y--; // post-decrement
if (matriz[x][y] != 9)
{
y--; // post-decrement
if (matriz[x][y] != 0)
{
y--; // post-decrement
// all true
}
}
}
If any fail, you still decrement (equivalence would be in an else-clause), but I'm omitting that for brevity.
Hopefully this is enough to clarify. I find it quite unwieldy, and if y < 2 at the start you'll end up with a negative index, which is probably a bad thing.
If y=0, your final two conditions will not be evaluated, since the first condition will fail.
If you want your first comparison to be -1>0, you need a prefix decrement: --y > 0
Yes you can do the comparison. Why are you writing such code? Please Please write could that is readable and that is understandable.