Verilog模块之间的传递参数

问题描述 投票:0回答:2

我对Verilog相当陌生,正在学习绳索。我有一些代码生成一个8位向上计数器(模块counter.v),然后由顶级模块(top_module.v)调用。有一个模拟测试装置(test_fixture.v),它调用顶层模块进行测试。

我正在尝试使用参数(parameter COUNTER_WIDTH)定义计数器的宽度,但很难这样做。一位同事为我修复了代码,现在确实可以使用,但是我想了解一些内容,以便可以了解实际发生的情况。

这里是计数器模块的代码:

module counter
#(parameter COUNTER_WIDTH = 8)
(
    input wire CLK,
    input wire RST,
    input wire CE,
    output reg[COUNTER_WIDTH-1:0] out = {COUNTER_WIDTH{1'b0}}
    );


   always @(posedge CLK) begin
      if (RST == 1) begin
         out <= {COUNTER_WIDTH{1'b0}};
      end else begin
      if (CE == 1) begin
         out <= out + 1'b1;
      end
    end
  end
endmodule

顶部模块:

module top_module
#(parameter COUNTER_WIDTH = 8)
(
    input wire CLK,
    input wire CE,
    input wire RST,
    output wire[COUNTER_WIDTH-1:0] out
    );

counter #(
    .COUNTER_WIDTH(COUNTER_WIDTH)
    )
counter_inst(
    .CLK(CLK),
    .RST(RST),
    .CE(CE),
    .out(out)
);

endmodule

和测试装置:

module test_fixture();

parameter COUNTER_WIDTH = 8;

// inputs
reg CLK = 0;
reg RST = 0;
reg CE = 0;

// outputs
wire [COUNTER_WIDTH-1:0] Q;

// instance of top module to be tested
top_module #(
    .COUNTER_WIDTH(COUNTER_WIDTH)
) 

test_inst(
    .CLK(CLK),
    .RST(RST),
    .CE(CE),
    .out(Q)
);
endmodule

我认为我对计数器模块没问题,但是对顶部模块/测试治具中发生的事情有疑问:

  • 似乎在每个模块中声明了参数COUNTER_WIDTH(#(参数COUNTER_WIDTH = 8)),然后在另一个模块中将参数声明“连接到”(如果是正确的表达式)(例如#(。COUNTER_WIDTH (COUNTER_WIDTH))
  • 这种理解正确吗?如果是这样,为什么我们必须在模块中声明参数and将其连接到另一个模块中的参数?

感谢您的帮助!

parameter-passing verilog vivado
2个回答
0
投票

将参数视为一种特殊的常量输入,其值在编译时是固定的。给参数指定不同的名称是否有助于您的理解?

module counter
#(parameter COUNTER_WIDTH = 8)
(
    input wire CLK,
    input wire RST,
    input wire CE,
    output reg[COUNTER_WIDTH-1:0] out = {COUNTER_WIDTH{1'b0}}
    );


   always @(posedge CLK) begin
      if (RST == 1) begin
         out <= {COUNTER_WIDTH{1'b0}};
      end else begin
      if (CE == 1) begin
         out <= out + 1'b1;
      end
    end
  end
endmodule

然后,在顶部模块中,为参数指定一个不同的名称:

module top_module
#(parameter COUNTER_NUM_BITS = 8)
(
    input wire CLK,
    input wire CE,
    input wire RST,
    output wire[COUNTER_NUM_BITS-1:0] out
    );

counter #(
    .COUNTER_WIDTH(COUNTER_NUM_BITS)
    )
counter_inst(
    .CLK(CLK),
    .RST(RST),
    .CE(CE),
    .out(out)
);

endmodule

再次在测试装置中:

module test_fixture();

localparam COUNTER_SIZE = 8;   // This is not overridden from outside, so using
                               // a localparam would be better here.
                               // (A localparam being a kind of parameter that
                               //  cannot be overridden from outside. Normal 
                               //  languages would call it a constant.)    
// inputs
reg CLK = 0;
reg RST = 0;
reg CE = 0;

// outputs
wire [COUNTER_SIZE-1:0] Q;

// instance of top module to be tested
top_module #(
    .COUNTER_NUM_BITS(COUNTER_SIZE)
) 

test_inst(
    .CLK(CLK),
    .RST(RST),
    .CE(CE),
    .out(Q)
);
endmodule

0
投票

为什么我们必须在一个模块内声明参数并将其连接到另一个模块内的参数?

因为,当您实例化模块时,不必为参数赋值。在这种情况下,工具需要至少具有some值才能使用。

所以您在哪里做:

counter #(
    .COUNTER_WIDTH(COUNTER_WIDTH)
    )
counter_inst(
    .CLK(CLK),
    .RST(RST),
    .CE(CE),
    .out(out)
);

您也可以使用:

counter
counter_inst(
    .CLK(CLK),
    .RST(RST),
    .CE(CE),
    .out(out)
);

在这种情况下,使用默认值。

© www.soinside.com 2019 - 2024. All rights reserved.