【 FPGA 】常数( localparam )和参数( parameter )
在Verilog HDL中,使用localparam(局部参数)声明常量,可以使代码清晰并有助于以后的维护,例如声明数据总线的位宽和范围:
localparam DATA_WIDTH = 8;
DATA_RANGE = 2**DATA_WIDTH;
或定义符号端口名称:
UART_PORT = 4'b0001;
LCD_PORT = 4'b0010;
MOUSE_PORT = 4'b0100;
习惯用大写字母表示常数。
一个带进位的固定位宽加法器的例子:
未使用常数的情况:
-
module adder_carry(
-
input [3:0] a,
-
input [3:0] b,
-
output [3:0] sum,
-
output cout
-
);
-
wire [4:0] sum_ext;
-
assign sum_ext = {1'b0,a} + {1'b0,b};
-
assign sum = sum_ext[3:0];
-
assign cout = sum_ext[4];
-
endmodule
如果改成8位加法器,这些位宽都要一个一个的手动更改,遇到大一点的项目,这将变得尤为困难。
我们对上述代码改进一下,使用局部常数:
-
module adder_carry
-
(
-
-
input [3:0] a,
-
input [3:0] b,
-
output [3:0] sum,
-
input cout
-
);
-
localparam N = 4;
-
localparam N1 = N-1;
-
wire [N:0] sum_ext;
-
assign sum_ext = {1'b0,a} + {1'b0,b};
-
assign sum = sum_ext[N1:0];
-
assign cout = sum_ext[N];
-
endmodule
上述代码使用了局部变量,这还不够优化,下面介绍参数的使用方法。
Verilog模块可以实例化为组件并成为更大设计模块的一部分。Verilog提供一种结构成为parameter,向模块传递信息,这种机制使得模块多功能化并能重复使用。参数在模块内不能改变,因此功能和常数类似。
在Verilog HDL 2001中,参数声明部分可以在模块的开头,即端口声明之前。如下:
module 模块名
#(parameter 参数名1 = 默认值1,
parameter 参数名2 = 默认值2)
(
...
);
......
endmodule
为了增强可读性以及可维护性,可以采用符号常数N来表示加法器的位数。
-
module adder_carry
-
#(parameter N = 4)
-
(
-
-
input [N-1:0] a,
-
input [N-1:0] b,
-
output [N-1:0] sum,
-
input cout
-
);
-
localparam N1 = N-1;
-
wire [N:0] sum_ext;
-
assign sum_ext = {1'b0,a} + {1'b0,b};
-
assign sum = sum_ext[N1:0];
-
assign cout = sum_ext[N];
-
endmodule
如果之后,加法器在其他代码中作为组件使用,那么就可以在组件实例化中给参数指定所需的值并将原来的默认值覆盖。
如果省略参数赋值,则采用默认参数,如下:
-
module adder_instant(
-
input [3:0] a4,
-
input [3:0] b4,
-
output [3:0] sum4,
-
output cout4,
-
input [7:0] a8,
-
input [7:0] b8,
-
output [7:0] sum8,
-
output cout8
-
);
-
//实例化8位加法器
-
adder_carry #(.N(8)) uu1(.a(a8),.b(b8),.sum(sum8),.cout(cout8));
-
-
//实例化4位加法器
-
adder_carry uu2(.a(a4),.b(b4),.sum(sum4),.cout(cout4));
-
endmodule
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/85637429
- 点赞
- 收藏
- 关注作者
评论(0)