6
\$\begingroup\$

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;
endmodule

I tried this line but I get an error:

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

1 Answer 1

7
\$\begingroup\$

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>
  ...
endmodule

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)
endmodule

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)
endmodule;

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

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.