9

I am relatively new to FPGAs, and I am looking for some guidance for modern best practice regarding the declaration of modules in Verilog.

I have seen two ways of declaring a module in verilog. The first reminds me of Traditional C, such as the examples on wikipedia:

module toplevel(clock,reset);
    input clock;
    input reset;

    /* snip */
endmodule

Whereas the alternative syntax has the input/output specifier as part of the argument list, not too dissimilar to VHDL, as in this example:

module fadder(
    input a,         //data in a
    input b,         //data in b
    input cin,       //carry in
    output sum_out,  //sum output
    output c_out     //carry output
);

/* snip */
endmodule

For newly written verilog code, which syntax is preferred? "Preferred", in this instance, means something written in a standard or related material (either explicitly written, or implicitly by examples given in the standard), or written in a well-regarded style guide. The question isn't asking for a personal preference!

Damien
  • 785
  • 3
  • 8
  • 18

3 Answers3

10

The second syntax form was indented to replace the first syntax form. If you look at the 1364-2001 Verlog LRM, as well as the current 1800-2012 SystemVerilog LRM, you will notice that all examples of module declarations use the second form. The first form is only there for legacy, but unfortunately, it has taken longer than expected for textbooks and course material to switch over.

The key benefit of this newer (or ANSI-style) syntax is that you only have to declare your port name in one place. With the older syntax, you had to declare a port name up to three times; once for the positional ordering, another time for the port direction, and if the port needed to be something other than a wire, a third time to declare its data type.

dave_59
  • 39,096
  • 3
  • 24
  • 63
9

The second is preferred. This was introduced in Verilog 2001. This is often called "ANSI-style".

When I teach Verilog I teach both, but recommend ANSI-style for all new code. (And mention that I am only teaching the first style so that the students can understand legacy code.)

If you get on to System-Verilog, you will find that some things only work with ANSI-style anyway.

Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44
  • SystemVerilog does support Non-ANSI; refer to [IEEE Std 1800-2012](http://standards.ieee.org/getieee/1800/download/1800-2012.pdf) § 23.2.2.1. ANSI is the preferred style – Greg Aug 24 '16 at 17:21
  • 2
    @Greg, What Matthew is conveying is that there are certain new SystemVerilog features that only work with ANSI-style ports. For example, you cannot define a generic `interface` port using non-ANSI style ports - because the LRM only created synthax for that feature using ANSI-style ports. – dave_59 Aug 24 '16 at 19:38
  • @dave_59, I think I miss read the last line when I first read it. I also missed the detail that non-ANSI doesn't support some features like generic `interface`. – Greg Aug 24 '16 at 20:49
  • (and @dave_59) - a bit pedantic, I know, but the phrase 'ANSI-style' is incorrect, and doesn't appear in the 2005 LRM in this context. It seems to have been made up by someone else (and "ANSI C" refers only to the temporary C89 anyway). New-style port lists are not C-style, because they allow comma-separated lists, and C doesn't. – EML May 13 '19 at 16:37
  • @EML, IEEE 1800-2017 in section 23.2.1 Module header definition says *There are two styles of module header definitions, the non-ANSI header and the ANSI header.* The word *style* is not a formal definition anyway- it means "in the spirit of" – dave_59 May 13 '19 at 17:44
  • Hi @dave_59 - yup, have't read 1800; Not Verilog, IMHO :) Whoever originally (pre-SV) coined the "ANSI" phrase is clearly someone who believes that Verilog "is just like C". Anyway, it's clearly ludicrous to invoke an American Standards Institute to (incorrectly) describe your language's style of port definitions, with no context. ANSI have done a vast number of things, with only a very brief involvement with C, 30 years ago. It's particularly ludicrous given that Verilog's heritage is Hilo, Pascal, and VHDL, and absolutely *not* C. – EML May 14 '19 at 07:52
4

The second mode is preferred but there is a case where you might want to use the first one. This is if you have lots of complex calculations to be done on parameters to get to the right port widths. Below is just a small artificial example. Yes, you can replace the localparam with their expressions but that may make your code unreadable.
I think it is one of the omission of (system) Verilog that you can't use local_param after a #(parameter.. definition.

module example 
#(parameter       
   L2DEPTH   =  8,
   OFFSET    =  2
)
(siga,sigb,sigc,sig_out);
localparam DEPTH = 1<<L2DEPTH;
localparan TOP   = DEPTH+OFFSET;
localparam BOT   = DEPTH-OFFSET;
localparam DBLDEPTH   = 2<<L2DEPTH;;
input  [  L2DEPT-1:0] siga;
input  [     TOP-1:0] sigb;
input  [     BOT-1:0] sigc;
output [DBLDEPTH-1:0] sig_out;
Oldfart
  • 6,104
  • 2
  • 13
  • 15
  • 1
    Not correct. You certainly can a `localparam` declaration in the *parameter_port_list*. – dave_59 May 06 '20 at 00:57
  • @dave_59 To offer another perspective, when one has more complex stuff derived from the params that really should be in a `define, it's not always possible to put this in the parameter lists. E.g., suppose the output of a module is of type packed struct with field widths that are dependent on the input parameters. This can't be in a package, since packages can't be parameterized. Therefore, the type definition needs to go in between the input parameter declaration and output signal declaration. – Dragonsheep Apr 28 '21 at 07:54
  • Agreed there might be a rare case where it's more difficult to use the ANSI-style ports, but not the case you just mentioned. `module DUT #(int P=1, Q= 3, type T = struct packed {bit [P:Q] d;})(input T fff);` – dave_59 Apr 28 '21 at 15:24