手把手教你学veriolg(十八)--Verilog 带参数例化

目录

Verilog 带参数例化

1. 参数化模块定义

示例:定义一个参数化的模块

2. 例化带参数的模块

示例:例化带参数的模块

3. 使用本地参数

示例:使用本地参数

4. 使用参数化宏定义

示例:使用参数化宏定义

5. 使用参数化实例化在生成语句中

示例:使用参数化实例化在生成语句中

总结


 

Verilog 带参数例化

在 Verilog 中,带参数的模块例化允许你在实例化一个模块时传递参数给该模块。这些参数可以是模块中的常量、端口宽度或其他任何需要在实例化时确定的值。使用带参数的模块可以增强代码的灵活性和重用性,因为同一个模块可以用于多种不同的应用场景,只需要在实例化时指定不同的参数即可。

1. 参数化模块定义

首先,我们需要定义一个带有参数的模块。参数通常用于定义模块内部的一些常量或端口的宽度。

示例:定义一个参数化的模块

 

verilog

深色版本

module parametric_module #(
    parameter WIDTH = 8,
    parameter DEPTH = 16
)(
    input wire clk,
    input wire reset,
    input wire [WIDTH-1:0] data_in,
    output reg [WIDTH-1:0] data_out
);

    // 模块内部逻辑
    always @(posedge clk or posedge reset) begin
        if (reset) begin
            data_out <= {DEPTH{1'b0}};
        end else begin
            data_out <= data_in;
        end
    end

endmodule

在这个例子中,parametric_module 拥有两个参数 WIDTHDEPTH,分别用于定义输入数据的宽度和输出数据的初始值。

2. 例化带参数的模块

接下来,我们需要在顶层模块或其他模块中实例化这个参数化的模块,并为其传递参数。

示例:例化带参数的模块

 

verilog

深色版本

module top_module;
    wire clk, reset;
    wire [7:0] data_in;
    wire [7:0] data_out;

    // 使用默认参数值例化模块
    parametric_module #() uut_default (
        .clk(clk),
        .reset(reset),
        .data_in(data_in),
        .data_out(data_out)
    );

    // 使用自定义参数值例化模块
    parametric_module #(16, 32) uut_custom (
        .clk(clk),
        .reset(reset),
        .data_in(data_in),
        .data_out(data_out)
    );

endmodule

在这个例子中,我们使用默认参数值来例化 uut_default 模块,此时 WIDTHDEPTH 都取默认值 8 和 16。对于 uut_custom 模块,则显式指定了 WIDTH 为 16,DEPTH 为 32。

3. 使用本地参数

在模块定义中,也可以使用本地参数(localparam),它们是只在当前模块作用域内有效的参数。

示例:使用本地参数

 

verilog

深色版本

module parametric_module #(
    parameter LOCALPARAM_WIDTH = 8
)(
    input wire clk,
    input wire reset,
    input wire [LOCALPARAM_WIDTH-1:0] data_in,
    output reg [LOCALPARAM_WIDTH-1:0] data_out
);

    localparam LOCALPARAM_DEPTH = LOCALPARAM_WIDTH * 2;

    // 模块内部逻辑
    always @(posedge clk or posedge reset) begin
        if (reset) begin
            data_out <= {LOCALPARAM_DEPTH{1'b0}};
        end else begin
            data_out <= data_in;
        end
    end

endmodule

在这个例子中,LOCALPARAM_WIDTH 作为模块参数传递,而 LOCALPARAM_DEPTH 则是一个本地参数,它的值依赖于 LOCALPARAM_WIDTH 的值。

4. 使用参数化宏定义

在某些情况下,你可能希望定义一些宏来简化参数的定义和使用。

示例:使用参数化宏定义

 

verilog

深色版本

`define PARAM_WIDTH 8
`define PARAM_DEPTH 16

module parametric_module #(
    parameter WIDTH = `PARAM_WIDTH,
    parameter DEPTH = `PARAM_DEPTH
)(
    input wire clk,
    input wire reset,
    input wire [WIDTH-1:0] data_in,
    output reg [WIDTH-1:0] data_out
);

    // 模块内部逻辑
    always @(posedge clk or posedge reset) begin
        if (reset) begin
            data_out <= {DEPTH{1'b0}};
        end else begin
            data_out <= data_in;
        end
    end

endmodule

在这个例子中,我们使用宏定义 PARAM_WIDTHPARAM_DEPTH 来简化参数的定义。

5. 使用参数化实例化在生成语句中

在使用生成语句(generate)时,也可以传递参数给生成的模块实例。

示例:使用参数化实例化在生成语句中

 

verilog

深色版本

module top_module;
    wire clk, reset;
    wire [7:0] data_in;
    wire [7:0] data_out;

    generate
        for (genvar i = 0; i < 4; i = i + 1) begin : gen_inst
            parametric_module #(i*2, i*4) uut (
                .clk(clk),
                .reset(reset),
                .data_in(data_in),
                .data_out(data_out)
            );
        end
    endgenerate
endmodule

在这个例子中,使用生成语句生成了四个 parametric_module 实例,并分别为其传递不同的参数值。

总结

带参数的模块例化是 Verilog 中一个非常有用的特性,它允许你在实例化模块时传递参数,从而增强代码的灵活性和重用性。通过定义和传递参数,可以轻松地适应不同的应用场景,而不必修改模块本身的代码。希望本节的内容能够帮助你更好地理解和使用 Verilog 的带参数例化,并在实际的设计中发挥重要作用。继续深入学习 Verilog 的其他特性和高级功能,将有助于你更好地掌握这门语言,并应用于实际的硬件设计中。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值