Verilog # parameter参数传入generate参数重定义举例说明

1.parameter
在例化多个相同模块但每个模块需要不同参数时常常会使用。

// para 模块
module para(
   input                clk,
   input                rst,
   input       [WA-1:0] a,
   input       [WB-1:0] b,
   output reg  [WS-1:0] sum
   );
parameter WA = 1;
parameter WB = 1;
parameter WS = 2;

always @(posedge clk)
begin
   if(rst)
      sum <= 0;
   else
      sum <= a + b;
end
endmodule

模块para中使用parameter定义了三个常量 WA=1、 W=1、 WS=2 来指出 a、b 和sum 的位宽。

// 顶层例化调用
module top(
   input          clk,
   input          rst,
   input    [4:0] m,
   input    [5:0] n,
   output   [6:0] res
);
   reg      [5:0] a;
   reg      [6:0] b;
   wire     [6:0] sum;

always @(posedge clk)
begin
   if(rst)
      a <= 6'd0;
   else
      a <= n - m;
end

always @(posedge clk)
begin
   if(rst)
      b <= 7'd0;
   else
      b <= m + n;
end

para #(
   .WA(6),	//重新定义常量 WA 的值为 6
   .WB(7),
   .WS(7)
   )para1(
   .clk(clk),
   .rst(rst),
   .a(a),
   .b(b),
   .sum(res)
);

endmodule

para 模块在例化时通过 # 对模块中的常量进行了重新定义。

// 仿真验证
`timescale 1ns / 1ps

module para_tb(
);

reg         clk;
reg         rst;
reg   [4:0] m;
reg   [5:0] n;
wire  [6:0] res;

initial begin
   m <= 5'b10001;
   n <= 6'b100101;
end

top top_tb(
   .clk(clk),
   .rst(rst),
   .m(m),
   .n(n),
   .res(res)
);

parameter CLK_PERIOD = 10;
initial begin
   clk = 1;
   forever begin
      #(CLK_PERIOD/2)
      clk = ~clk;
   end
end
initial begin
   rst = 0;
   #CLK_PERIOD
   rst = 1;
   #CLK_PERIOD
   rst = 0;
end

endmodule

仿真结果:
在这里插入图片描述
可以看出a、 b、 sum 的位宽 WA WB WS 由原来模块中的 1、1、2 重新定义成了 6、7、7。

2.generate

geberate for、generate if、generate case示例:

module top 
#(parameter integer flag = 0)
(
input                clk_sys,
input          [7:0] a,
input          [7:0] b,
output         [7:0] c,
output   reg   [7:0] ab_xor,
output   reg   [8:0] ab_ad
);

genvar i;
generate for(i=0;i<8;i=i+1) begin: ab_xor_gen
   always @(posedge clk_sys)
      ab_xor[i] <= a[i] + b[i];
end
endgenerate

generate if(flag==0) begin:add
   always @(posedge clk_sys)
      ab_ad <= a + b;
end else begin:subsrtact
   always @(posedge clk_sys)
      ab_ad <= a - b;
end
endgenerate

generate 
   case(flag)
      0:
         assign c = a;
      1:
         assign c = a + 1'b1;
      default:
         assign c = b;
   endcase
endgenerate

endmodule

仿真

`timescale 1ns / 1ps
module tb_temp();

reg                  clk_sys;
reg            [7:0] a;
reg            [7:0] b;
wire           [7:0] c;
wire           [7:0] ab_xor;
wire           [8:0] ab_ad;

initial  begin
   clk_sys = 1'b1;
   forever begin
      #5;
      clk_sys = 1'b0;
      #5;
      clk_sys = 1'b1;
   end
end

initial  begin
   a = 8'b10010011;
   b = 8'b00110011;
end

top #( 
.flag                (1) 
)
top_inst(
.clk_sys             (clk_sys),
.a                   (a),
.b                   (b),
.c                   (c),
.ab_xor              (ab_xor),
.ab_ad               (ab_ad)
);

endmodule

仿真结果:
在这里插入图片描述

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Verilog参数化是指在RTL(Register Transfer Level)设计中使用参数来灵活地定义和定制模块的行为和特性。参数可以在实例化模块时通过参数赋值来调整模块的功能。 在Verilog中,通过parameter关键字来声明参数,并在模块定义中使用这些参数定义模块的行为。通过参数化,可以在设计阶段根据实际需求,动态地改变模块的功能,而不需要修改模块的源代码。 参数化可以实现设计的复用。通过改变参数的赋值,可以实例化出不同的模块,满足不同的需求。这样可以提高设计的灵活性和可维护性。 参数可以是基本数据类型,如整数或布尔类型,也可以是自定义的数据类型,如结构体。当参数是整数类型时,可以根据具体的值来控制模块的行为。当参数是布尔类型时,可以通过不同的赋值来打开或关闭特定的功能。 参数还可以用于控制模块实例中的信号位宽。通过将输入和输出端口的位宽定义参数,可以灵活地调整模块的位宽,以适应不同的数据尺寸。 需要注意的是,参数是在编译时静态确定的,即模块实例化时参数的赋值是固定的。如果需要在运行时动态改变模块的行为,需要使用传参的方式来实现。 总之,参数化是Verilog中一种要的技术,可以根据实际需求灵活地定义和定制模块的行为和特性。通过适当使用参数化,可以提高设计的效率和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值