Verilog初级教程(19)Verilog中的参数

文章目录

    • 前言
    • 正文
      • 模块参数
      • 覆盖参数
      • 例子说明
        • 递增计数器
        • 递减计数器
      • Specify参数
      • 模块参数与Specify参数的区别
    • 往期回顾
    • 参考资料及推荐关注

前言

Verilog中的参数是使得设计更具有通用性、易读性的手段之一,使用十分频繁。

正文

参数是Verilog结构,它允许一个模块以不同的规格重复使用。例如,一个4位加法器可以被参数化为接受一个位数的值,并且可以在模块实例化期间传递新的参数值。所以,一个N位加法器可以变成4位、8位或16位加法器。它们就像函数的参数一样,在函数调用过程中被传递进来。

parameter MSB = 7;                  // MSB is a parameter with a constant value 7
parameter REAL = 4.5;               // REAL holds a real number

parameter FIFO_DEPTH = 256,
          MAX_WIDTH = 32;           // Declares two parameters

parameter [7:0] f_const = 2'b3;     // 2 bit value is converted to 8 bits; 8'b3

参数基本上是常量,因此在运行时修改它们的值是非法的。重新声明一个已经被net、变量或其他参数使用的名称是非法的。(即不能使用已经被使用过的名称)

参数主要有两种,module parameterspecify parameter,都可以接受范围规格。但是,一般情况下,只要要存储的值符合要求的宽就可以,因此不需要范围规格。

模块参数

模块参数可以用来覆盖模块内的参数定义,这使得模块在编译时有一组不同的参数。参数可以用defparam语句或在模块实例语句中修改。通常的做法是在参数的名称中使用大写字母,使其一目了然。

下图所示的模块使用参数来指定设计内的总线宽度、数据宽度和FIFO的深度,在模块实例化时可以用新的值覆盖,也可以使用defparam语句。

// Verilog 1995 style port declaration
module design_ip  ( addr,
                    wdata,
                    write,
                    sel,
                    rdata);

     parameter  BUS_WIDTH    = 32,
                DATA_WIDTH   = 64,
                FIFO_DEPTH   = 512;

     input addr;
     input wdata;
     input write;
     input sel;
     output rdata;

     wire [BUS_WIDTH-1:0] addr;
     wire [DATA_WIDTH-1:0] wdata;
     reg  [DATA_WIDTH-1:0] rdata;

     reg [7:0] fifo [FIFO_DEPTH];

     // Design code goes here ...
endmodule

在新的 ANSI 风格的 Verilog port 声明中,您可以声明如下所示的参数。

module design_ip
	#(parameter BUS_WIDTH=32,
		parameter DATA_WIDTH=64) (

		input [BUS_WIDTH-1:0] addr,
   	// Other port declarations
   );

覆盖参数

在模块实例化的过程中,可以用新的值来覆盖参数。第一部分实例化名为design_ip的模块,名称为d0,其中新的参数是在#( )内传递进来的。第二部分使用名为defparam的Verilog构造来设置新的参数值。

  • 第一种方法是RTL设计中最常用的传递新参数的方法。
  • 第二种方法常用于测试台仿真中,以快速更新设计参数,而无需对模块进行重新设置。
module tb;

	  // Module instantiation override
		design_ip  #(BUS_WIDTH = 64, DATA_WIDTH = 128) d0 ( [port list]);

		// Use of defparam to override
		defparam d0.FIFO_DEPTH = 128;

endmodule

例子说明

模块计数器有两个参数N和DOWN,声明其默认值分别为2和0。N控制输出的位数,有效控制计数器的宽度。默认情况下,它是一个2位的计数器。参数DOWN控制计数器是递增还是递减。默认情况下,计数器将递减,因为该参数被设置为0。

递增计数器

module counter
  #( 	parameter N = 2,
   		parameter DOWN = 0)

  ( input 							clk,
    input 							rstn,
    input 							en,
   	output 	reg [N-1:0] out);

  always @ (posedge clk) begin
    if (!rstn) begin
      out <= 0;
    end 
    else begin
      if (en)
        if (DOWN)
          out <= out - 1;
        else
          	out <= out + 1;
      else
         out <= out;
    end
  end
endmodule

模块计数器被实例化时,N为2,尽管它不是必需的,因为默认值是2。在模块实例化过程中,DOWN没有被传递进来,因此默认值为0,使其成为一个向上的计数器。

module design_top (    input clk,
                input rstn,
                input en,
                output [1:0] out);

    counter #(.N(2)) u0 (	.clk(clk),
                          .rstn(rstn),
                          .en(en));
endmodule

请看,默认参数是用来实现计数器的,其中N等于2使其成为2位计数器,DOWN等于0使其成为递增计数器。计数器的输出在顶层不连接。

Verilog初级教程(19)Verilog中的参数_第1张图片
展开计数器:
Verilog初级教程(19)Verilog中的参数_第2张图片

递减计数器

上述计数器参数传递修改下就可以实现递减计数器,如下:

module design_top (    input clk,
                input rstn,
                input en,
                output [3:0] out);

    counter #(.N(4), .DOWN(1))
    		u1 (	.clk(clk),
              .rstn(rstn),
              .en(en));
endmodule

Verilog初级教程(19)Verilog中的参数_第3张图片

Specify参数

这些主要用于提供定时和延迟值,使用specparam关键字来声明。它既可以在specify块内使用,也可以在主模块体中使用。

// Use of specify block
specify
	specparam  t_rise = 200, t_fall = 150;
	specparam  clk_to_q = 70, d_to_q = 100;
endspecify

// Within main module
module  my_block ( ... );
 	specparam  dhold = 2.0;
 	specparam  ddly  = 1.5;

 	parameter  WIDTH = 32;
endmodule

模块参数与Specify参数的区别

Specify参数 模块参数
由关键词specparam声明 通过parameter声明
可以在specify块内或者主模块内部声明 仅仅可以在主模块内部声明
SDF可用于覆盖值 实例声明参数值或defparam可用于覆盖

往期回顾

Verilog初级教程(18)Verilog中的函数与任务

Verilog初级教程(17)Verilog中的case语句

Verilog初级教程(16)Verilog中的控制块

Verilog初级教程(15)Verilog中的阻塞与非阻塞语句

Verilog初级教程(14)Verilog中的赋值语句

Verilog初级教程(13)Verilog中的块语句

Verilog初级教程(12)Verilog中的generate块

Verilog初级教程(11)Verilog中的initial块

Verilog初级教程(10)Verilog的always块

Verilog初级教程(9)Verilog的运算符

Verilog初级教程(8)Verilog中的assign语句

Verilog初级教程(7)Verilog模块例化以及悬空端口的处理

Verilog初级教程(6)Verilog模块与端口

Verilog初级教程(5)Verilog中的多维数组和存储器

Verilog初级教程(4)Verilog中的标量与向量

Verilog初级教程(3)Verilog 数据类型

Verilog初级教程(2)Verilog HDL的初级语法

Verilog初级教程(1)认识 Verilog HDL

芯片设计抽象层及其设计风格

Verilog以及VHDL所倡导的的代码准则

FPGA/ASIC初学者应该学习Verilog还是VHDL?

参考资料及推荐关注

Verilog Parameters

个人微信公众号: FPGA LAB

交个朋友

你可能感兴趣的:(#,数字设计基础教程)