In a Verilog 2001 module, how can I define the width of a port at instantiation?
For example, a multiplier and the module that instantiates it might look like this:
module Multiplier #(parameter WIDTH = 8, parameter WIDTH1 = 8, WIDTH2 = 8) (
output [WIDTH-1:0] product,
input [WIDTH1-1:0] factor1,
input [WIDTH2-1:0] factor2
);
parameter WIDTHI = WIDTH1+WIDTH2;
wire [WIDTHI-1:0] intermediate_product;
assign intermediate_product = factor1 * factor2;
assign product = (intermediate_product >>> (WIDTHI-WIDTH));
endmodule
module User();
parameter WIDTH_OF_PRODUCT = 8;
parameter WIDTH_OF_FACTOR_1 = 8;
parameter WIDTH_OF_FACTOR_2 = 8;
wire [WIDTH_OF_PRODUCT] product;
reg [WIDTH_OF_FACTOR_1] factor1;
reg [WIDTH_OF_FACTOR_2] factor2;
Multiplier #(WIDTH_OF_PRODUCT,WIDTH_OF_FACTOR_1,WIDTH_OF_FACTOR_2)
m0(product, factor1, factor2);
endmodule
If the widths of the nets in User are defined at compile time, is there any way that the widths of the ports in the instantiation of Multiplier can be defined automatically?
I'd like an instantiation that looks like this:
Multiplier m0(product, factor1, factor2);
That would probably involve changing the definition of the Multiplier module.
Keep in mind that these are just examples. The point of my question regards how the two modules are defined with respect to their nets and ports.
Thanks in advance!
Update:
Here is a case that would not work with Multiplier defined as it is:
module Top();
parameter WIDE = 8;
parameter NARROW = 4;
wire [NARROW-1:0] narrow_product;
wire [WIDE-1:0] wide_product;
reg [NARROW-1:0] narrow_factor_1;
reg [WIDE-1:0] wide_factor_1;
reg [NARROW-1:0] narrow_factor_2;
reg [WIDE-1:0] wide_factor_1;
Multiplier mWide(wide_product, wide_factor_1, wide_factor_2);
Multiplier mNarrow(narrow_product, narrow_factor_1, narrow_factor_2); // PROBLEM
endmodule
My motivation for this is that the nets represent fixed point numbers, a representation of numbers with fractional parts. I will have to specify a precision for the fixed point numbers. While that could be a global constant, I may want to use different precisions. So, I will probably need parameters to specify the precisions of the ports in modules.
Update: Well, I can't do what I wanted to do. So here is what I have done, in case this helps anyone:
Since the widths of input and output are the same I defined them this way:
module Multiplier #(parameter WIDTH = 8,
parameter WIDTH1 = WIDTH,
parameter WIDTH2 = WIDTH1) (
output [WIDTH-1:0] product,
input [WIDTH1-1:0] factor1,
input [WIDTH2-1:0] factor2
);
...
endmodule
So then I can instantiate this way:
Multiplier #(16) m0(product, factor1, factor2);
if the product and the factors all have the same length. It's a little less verbose than specifying all of them, especially when I working with fixed point numbers where the instantiation would look like this:
Multiplier #(16,8) m0(product, factor1, factor2);
where the second number is a PRECISION parameter giving the width of the fractional part. (This would require an update to the Multiplier module definition to include PRECISION, PRECISION1, and PRECISION2 with definitions analogous to the WIDTH definitions.
product
,factor1
,factor2
have a width other than 8, they don't match the default port width ofMultiplier
anymore. The question is how the port widths can be derived from the widths of the connected signals. – mkrieger1