1. 概述算法
在Verilog中咱们经常会遇到要将一个常量(算法中的某个参数)赋给不少个变量的状况,如:spa
x = 10;
y = 10;
z = 10;
若是此时10要改成9,就须要在代码中修改3个地方,很是的不方便,而且这个10是没有任何意义的,咱们不知道它表明什么,因此为了代码的易重用、易读性,咱们应使常量参数化,如:.net
parameter MAX = 10;
x = MAX;
y = MAX;
z = MAX;blog
这样就只须要修改MAX就能够了,而且MAX是有意义的,增长代码的易读性。ip
parameter是常量,不是变量,因此不容许在运行时修改它的值,即不能在组合逻辑或者时序逻辑中对其进行赋值。内存
有两种类型的parameters:
1)module parameters
2)specify parameters,只能提供定时和延时的值,不可综合。
2. module parametersci
module parameters有parameter和localparam两种,它们所表明的值均可在编译时进行修改(参数传递),parameter可直接修改,localparam只能间接修改。it
2.1 parameterio
parameter在模块中声明后,后续编译时还能够被从新声明的值所覆盖。编译
parameter msb = 7; // defines msb as a constant value 7
parameter e = 25, f = 9; // defines two constant numbers
parameter r = 5.7; // declares r as a real parameter
parameter byte_size = 8,
byte_mask = byte_size - 1;
parameter average_delay = (r + f) / 2;
parameter signed [3:0] mux_selector = 0;
parameter real r1 = 3.5e17;
parameter p1 = 13'h7e;
parameter [31:0] dec_const = 1'b1; // value converted to 32 bits
parameter newconst = 3'h4; // implied range of [2:0]
parameter newconst = 4; // implied range of at least [31:0]
注:
1)若是参数在声明时没有指定type和range,则默认为最后赋值给参数的type和range;
2)若是参数有指定range,但没有type,则它的符号默认为unsigned,而且range和符号都不会被后面的声明所覆盖;
3)若是参数有指定range,而且指定为有符号type,则它的range和符号都不会被后面的声明所覆盖;
2.2 localparam
localparam除了不能直接对其进行修改外,其余属性与parameter同样。可经过在声明时将parameter赋给localparam进行间接修改。状态机通常都使用localparam。
parameter X = 3;
localparam Y = X*2;
这样修改X就间接修改了localparam Y的值。
2.3 编译时parameter的参数传递
对parameter的修改有两种方式:
1)defparam声明
2)模块实例声明
注:若是defparam声明和模块实例声明冲突了,则使用defparam声明的值。
2.3.1 defparam声明
defparam使用层次化名称对模块中的参数从新赋值,以下面的代码所示,mod_a是一个实例化的模块,para_a和para_b是mod_a中的参数。
defparam mod_a.para_a = 2;
defparam mod_a.para_b = 3;
mod_mod mod_a();
注:若是有多个defparam声明一个parameter,则该parameter取文本(代码)中最后一个defparam声明的值。
2.3.2 模块实例声明
模块实例声明有两种实现方式:
1)有序列表
列表的顺序必须严格按照模块中参数声明的顺序,且不可跳过任何一个参数。以下面代码,mod_mod中有三个参数,a = 4,b = 5,c = 6.
mod_mod #(1, 2, 3) mod_a(); //三个参数都修改
mod_mod #(4, 2, 3) mod_a(); //只修改b和c,可是也要将a的值声明
mod_mod #(1, 5, 3) mod_a(); //只修改a和c,可是也要将b的值声明
2)参数名
声明时的参数名称须要和模块实例中的参数名称一致,不须要从新声明的参数能够缺省。
mod_mod #(.a(2), .b(3)) mod_a(); //两个参数都从新声明
mod_mod #(.b(3)) mod_b(); //只声明参数b
注:针对一个实例的参数声明只能经过一种方式,不可混合,不一样实例能够混合。如
// 不合法
mod_mod #(3, .b(4)) mod_a(); //同时使用两种方式,不合法
// 合法
mod_mod #(3, 4) mod_a(); //只使用有序列表的方式
mod_mod #(.a(3), .b(4)) mod_b(); //只使用参数名方式
3. `define与parameter的区别
`define做用于整个工程,而parameter只做用于本模块,一旦`define指令被编译,则在整个编译过程当中都有效,因此仿真时使用`define相对于parameter重声明占用更少的内存。
参考资料:
1) IEEE Std 1364TM-2005: IEEE Standard for Verilog Hardware Description Language.
2) Verilog Coding Styles for Improved Simulation Efficiency.
3) https://blog.csdn.net/Times_poem/article/details/51371940
---------------------
做者:qq_16923717
来源:CSDN
原文:https://blog.csdn.net/qq_16923717/article/details/81067096