Verilog is a hardware description language (HDL) used for designing digital circuits and systems. Writing Verilog code with a consistent and organized style is important to make the code maintainable, readable, and error-free.

Verilog coding style can have a significant impact on the synthesis process, where your high-level Verilog code is converted into a gate-level netlist that can be implemented on an FPGA or ASIC. A well-structured and organized Verilog codebase can lead to more efficient synthesis with less hardware, and save area and power.

Consider the following three implementations of a Mod-3 counter that results in hardware circuits with different logic elements. An adder to increment and flops to store the counter value are the two must-have elements to implement a counter.

The difference lies in how the synthesis tool uses the hardware description to implement the reset logic. Its worthwhile to remember that there are trade-offs for each approach like area over power and reusability.

Example #1


module cntr_mod3 (input clk, rstn, output reg [1:0] out);
  always @(posedge clk) begin
    if (!rstn | out[1] & out[0])
      out <= 0;
    else
      out <= out + 1;
  end 
endmodule

Note that the synthesis tool implemented the hardware logic exactly as described using an AND and OR gate.

Example #2


module cntr_mod3 (input clk, rstn, output reg [1:0] out);
  always @(posedge clk) begin
    if (!rstn)
      out <= 0;
    else
      if (out == 3) 
        out <= 0;
      else  
        out <= out + 1;
  end 
endmodule

Note that synthesis resulted in two multiplexer circuit which has a lot more gates than the previous result, and thereby have higher area and power.

Example #3


module cntr_mod3 (input clk, rstn, output reg [1:0] out);
  always @(posedge clk) begin
    if (!rstn)
      out <= 0;
    else 
      if (&out)
        out <= 0;
      else
      	out <= out + 1;
  end 
endmodule

Note that synthesis resulted in a single MUX and a reduction AND element as described by the Verilog RTL code.