Electronic – How to define a module with a modified parameter in Verilog


I want to define an add module which has a modified parameter in my declaration of the new instance but it doesn't go well.

It is in Verilog. I want to define an instance of this module:

module add #(parameter wd=1) (input wire [wd-1:0] a,b, output wire [wd-1:0] o);
   assign o = a + b;

I tried this line but I get an error:

 add len_plus_1 #(8)(.a(len),.b(8'h1),.o(lenPlus1));

Best Answer

You've got the order wrong. When using module-instance parameter value assignment (the rather wordy terminology for this method), the syntax is:

module-name #(parameter-assignment) instance-name (module-terminal-list) ;

where the parameter assignment can be by name or by the order of the values. You're already familiar with the module terminal list, so I'll just give the parameter BNF:

parameter-assignment ::= (values-by-name / values-by-order) 
values-by-name ::= .parameter-name(parameter-value)*[, parameter-name(parameter-value)]
values-by-order ::= parameter-value*[, parameter-value]

So your example should be one of the following:

add #(.wd(8)) len_plus_1(.a(len),.b(8'h1),.o(lenPlus1));
add #(8) len_plus_1(.a(len),.b(8'h1),.o(lenPlus1));

The former (named) version is preferred, because it maintains its behavior if you add another parameter.

The following example gives additional options (this is adapted from Figure 9-4 in Verilog HDL: A Guide to Digital Design and Synthesis by Palnitkar)

module bus_master;
  // Note: These could also be ANSI C-style parameter declarations with 
  // module bus_master (#parameter delay1 = 2, delay2 = 3, delay3 = 7);
  parameter delay1 = 2;
  parameter delay2 = 3;
  parameter delay3 = 7;
  <module internals>

module top;
  // Assignment by name:
  bus_master #(.delay2(4), delay3(8)) b1();
     //delay1 = 2 (default), delay2 = 4, delay3 = 8
  bus_master #(.delay1(1), delay3(6)) b2();
     //delay1 = 1, delay2 = 3 (default), delay3 = 6

  // Assignment by order:
  bus_master #(7, 8, 9) b3();
     //delay1 = 7, delay2 = 8, delay3 = 9
  bus_master #(1, 3, 5) b4();
     //delay1 = 1, delay2 = 3 (default, but by assignment), delay3 = 5
  bus_master #(1, 5) b5();
     //delay1 = 1, delay2 = 5, delay3 = 7 (default)

There is also another method which uses the defparam keyword to define the values before instantiation like this:

module top; 
  defparam b6.delay1 = 1;
  bus_master b6();
     //delay1 = 1, delay2 = 3 (default), delay3 = 7 (default)

but that's considered poor style (though personally, I'd prefer it to the values-by-order syntax).