Verilog HDL : How to write if statements
I was in the middle of an FPGA clock building exercise.
I was writing counters for seconds, minutes and hours using Intel® Quartus® Prime development software.
I was able to write a one-digit second counter (0 to 9) by using a clock enable signal to count up the seconds, but I could not write a two-digit second counter (09 to 10). Here is my design at that time.
I could not confirm that the second digit was counting up even after the first second digit passed 9 at the rising edge of the clock.
Therefore, I created a circuit in which the second digit counts up after the first digit reaches 9, ignoring the clock enable signal, and checked it on the actual device, and found that the second digit counted up to 1 when the first digit was 8.
The simulation image is shown here.
So, why don't the second digits count up when the first digit counts up to 10? I rewrote the circuit with a crazy idea, and was able to confirm that the digits were displayed on the actual device without any problems.
However, I could not get the second digit to count up to the minute digit, so I asked my senior to look at the design and he said, "You don't understand the if statement at all.
Quartus® II development software did not show any errors, so I wondered what was wrong...
According to my senior, if statements check the truth of conditional statements from the top to the bottom.
I'll explain the design I just described based on that.
I don't know what I am writing and what I want it to do.
The last two lines are unnecessary.
It took me a long time to get the Quartus® II development software confused, too. Sorry Quartus® II.
If you look at the second else if statement, you will see that it says that qa takes data at the "rising edge of clk" in 4'b1001 (9) and sets qa to zero. The clock is set to 1MHz High.
The value was 9 only at the moment the 1MHz clock went High, but it is not something that the human eye can recognize, is it?
The above description shows that the conditional branch was going back and forth.
The conditional signal other than clk and clr_n was clk_en. clk_en is a 1s period signal generated based on a 1MHz clock.
I wanted to trigger clk_en of 1s to count up. The only thing I wanted to do was to trigger clk_en at 1s to count up. I can't describe it unless the priority of the conditional expression is clear.
Here is the improved counter description.
always@(posedge clk)
begin
if (clr_n == 1'b0)
qa <= 4'b0000;//d'0
else if (clk_en == 1'b1)
if(qa == 4'b1001)//d'9
qa <= 4'b0000;
else
qa <= qa + 4' b0001;
else
qa <= qa;
end
When using if statements, it was necessary to prioritize each signal and keep in mind to write conditional statements starting with the one with the highest priority.
We found that too much nesting (nesting) can increase the complexity of the condition and create redundant logic that the designer did not intend, consuming a significant amount of FPGA logic elements (LEs).
As an example, a clock design created with the previous over-nested and incorrect counter consumed approximately 700 LEs.
By rewriting it, it consumed only about 40 LE.
It seems that a concise and optimized description is necessary to make good use of FPGAs.
The tool also performs optimization, but there are limits.
We recognized the importance of the design description to make the most effective use of the tool's functionality.
Recommended articles/documents are here
- Altera FPGA Development Flow / FPGA Top Page
- Verilog HDL
- Verilog HDL : Difference between Blocking and Non-blocking Logic Synthesis
- Difference between Verilog HDL and VHDL - Struggles in Conversion
- Difference between VHDL and Verilog HDL ~ signals with different bit widths
New Engineer's Blush Blog Articles