23,verilog之参数parameter介绍

发布时间:2024年01月20日

注:扫码关注小青菜哥哥的weixin公众号,免费获得更多优质的核探测器与电子学内容~

https://img-blog.csdnimg.cn/2ee3fd694ac942f0b1aa035ff308dc03.jpeg

参数parameter的作用大体与宏定义类似,用来改变一个模块的局部参数,如信号宽度等。

参数parameter的声明有两种格式:一种是verilog-1995,在模块内部声明;另一种是verilog-2001新增的,在模块名字后面声明,这种方式更加友好。

使用参数时,这两者格式既可以任选其一,亦可以两种都用,但是推荐使用verilog-2001新增的格式。因此以后我们只说parameter的verilog-2001用法,1995的语法不再介绍。

parameter可以有一个类型(type: signed or unsigned)说明和一个位宽范围(range)说明,其标准格式为:

parameter [ type] [ range ] list_of_param_assignments

先举几个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]

结合上述例子,我们总结一下parameter的类型(type: signed or unsigned)和范围(range)应符合以下规则:

1,参数被赋值后,没有类型或范围定义的参数声明应默认为分配给该参数的值的类型和范围。

2,具有范围定义但没有类型定义的参数应为参数声明的范围且应为无符号。符号和范围不应受参数值覆盖的影响。

3,具有类型定义但没有范围定义的参数应属于声明指定的类型。在被赋值后,带符号的参数应默认为分配给该参数的值的范围。

4,具有类型定义和范围定义的参数声明的符号和范围都是确定好的,参数的符号和范围不受赋值的符号和范围影响。

5,没有范围定义的参数,无论是有符号类型定义还是没有类型定义,都应该有一个隐含的范围,其中 lsb 等于 0,msb 等于分配给参数的值的范围减1。

6,一个没有范围定义的参数,有符号类型说明或没有类型说明,并且分配给它的值的范围是不确定的,那么就应该有一个隐含的范围,lsb 等于 0,msb为 31。

下面举例子说明参数使用的方法,我们以后按照这个格式使用parameter即可:

parameter使用的例子1:

module AAAA#(parameter MSB=3, LSB=0, DEPTH=4) // These parameters can be overridden
(
    input [MSB:LSB] in,

    input clk,

    output [MSB:LSB] out,

    output full, empty
);

……

endmodule

parameter使用的例子2:

module BBBB #(

??? parameter? A = 8'h11,

?????? parameter? B = 8'h08,?????????????

??? parameter? C = 8'h00

)(

input?? axi_tclk ,

output? Fifo_full,

output? Fifo_empty,

output? fifo_cmd_empty

);

……

endmodule

模块调用parameter的例子1:

AAAA #(

??? .MSB(MSB3),

????.LSB(LSB2),

????.DEPTH(DEPTH5)
)AAAA_inst(

??? .in(in),

??? .clk(clk),

??? .out(out),

??? .full(full),

??? .empty(empty)
? );

模块调用parameter的例子2:

BBBB #(

??? .A (AAA),

????.B (BBB),

????.C (CCC)

) BBBB_inst (

??? .axi_tclk?????? (axi_tclk),

??? .Fifo_full????? (Fifo_full),

??? .Fifo_empty???? (Fifo_empty),

??? .fifo_cmd_empty (fifo_cmd_empty)
? );

在模块实例化时,参数传递同样需要遵循以下规则:

  1. 对于没有范围和类型的参数,默认使用模块实例时传进来数值的范围和类型
  2. 对于有范围但没类型定义的参数,就认为参数类型时无符号。模块实例传进来数值的范围和类型要转换成参数的范围和类型。
  3. 对于没有范围但有类型的参数,就使用参数的类型。模块实例传进来数值的类型要转换成参数的类型。对于符号数,默认使用模块实例传进来数值的范围。
  4. 对于有范围和类型的参数,模块实例传进来数值的类型和范围要转换成参数的范围和类型。

另外,参数传递还有一个关键字defparam,本来用它十分的简单明了和使用方便,但这个关键字如今被滥用了,所以基本上大家都不使用defparam做参数传递,如今该关键字已经过时,应该抛弃掉,以后就不要用了,相关的用法博主也就不介绍了。

今天的博文就到这里了,有问题请在小青菜哥哥的公众号留言,谢谢!

文章来源:https://blog.csdn.net/Logical_Killer/article/details/135705354
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。