zoukankan      html  css  js  c++  java
  • 【转载】Verilog中的parameter

    1. 概述

    在Verilog中我们常常会遇到要将一个常量(算法中的某个参数)赋给很多个变量的情况,如:

    x = 10;
    y = 10;
    z = 10;
    如果此时10要改为9,就需要在代码中修改3个地方,非常的不方便,并且这个10是没有任何意义的,我们不知道它代表什么,所以为了代码的易重用、易读性,我们应使常量参数化,如:

    parameter MAX = 10;
    x = MAX;
    y = MAX;
    z = MAX;

    这样就只需要修改MAX就可以了,并且MAX是有意义的,增加代码的易读性。

    parameter是常量,不是变量,所以不允许在运行时修改它的值,即不能在组合逻辑或者时序逻辑中对其进行赋值。

    有两种类型的parameters:
    1)module parameters
    2)specify parameters,只能提供定时和延时的值,不可综合。
    2. module parameters

    module parameters有parameter和localparam两种,它们所代表的值都可在编译时进行修改(参数传递),parameter可直接修改,localparam只能间接修改。

    2.1 parameter

    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
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    SpringBoot 应用程序启动过程探秘
    git创建分支并推送远程
    idea中@Autowired注解下变量报红
    java.lang.IllegalStateException: Either 'name' or 'value' must be provided in @FeignClient的解决方案
    项目启动中报错Address already in use: bind的解决方案
    Maven配置阿里云镜像和配置jdk1.8编译项目
    MySQL优化之Explain
    英文字母和中文汉字在不同字符集编码下的字节数
    Netty中两种Keepalive的区别
    @ConfigurationProperties和@Value的区别
  • 原文地址:https://www.cnblogs.com/moluoqishi/p/10714990.html
Copyright © 2011-2022 走看看