define, parameter, localparam, specparam, defpara用法简析

article/2025/9/22 2:23:16

1.概述

在Verilog中,parameter既不属于变量范畴也不属于线网范畴,经常用来定义一个标志符代表一个常量,当一个模块被另一个模块引用例化时,高层模块可以对低层模块的参数值进行改写。这样就允许在编译时将不同的参数传递给多个相同名字的模块,而不用单独为只有参数不同的多个模块再新建文件。通过使用参数,可以提高程序的可读性、可复用性和可维护性。

目前常用的参数主要分为两大类:module参数(parameter和localparam)和specify参数(specparam)

`define:        作用 -> 常用于定义常量可以跨模块、跨文件;范围 -> 整个工程;parameter:       作用 -> 常用于模块间参数传递;范围 -> 本module内有效的定义;localparam        作用 -> 常用于状态机的参数定义;范围 -> 本module内有效的定义,不可用于参数传递;specparam         作用->关键字 specparam 在 specify 块中定义延迟数值常量,然后赋值给路径延迟范围->specparam 定义的常量只能在 specify 块内部使用其中: Verilog specify 块语句:https://www.runoob.com/w3cnote/verilog2-specify.html

宏定义 'define

若直接在module中通过localparam或者parameter进行参数定义的话,会带来两个问题:

  • 代码长度增加,不够美观;

  • 不利于参数和代码修改;

用一个指定的标识符(即名字)来代表一个字符串,它的一般形式为:`define 标识符(宏名) 字符串(宏内容)    如:`define signal string

它的作用是指定用标识符signal来代替string这个字符串,在编译预处理时,把程序中在该命令以后所有的signal都替换成string。这种方法使用户能以一个简单的名字代替一个长的字符串,也可以用一个有含义的名字来代替没有含义的数字和符号,因此把这个标识符(名字)称为“宏名”,在编译预处理时将宏名替换成字符串的过程称为“宏展开”。

verilog中define八点说明:原文链接

  • 宏名建议使用大写字母,以与变量名相区别

  • 'define命令可以出现在模块定义里面,也可以出现在模块定义外面。宏名的有效范围为定义命令之后到原文件结束。通常,`define命令写在模块定义的外面,作为程序的一部分,在此程序内有效

  • 在引用已定义的宏名时,必须在宏名的前面加上符号“`”,表示该名字是一个经过宏定义的名字

  • 宏定义是用宏名代替一个字符串,也就是作简单的置换,不作语法检查

  • 宏定义不是Verilog HDL语句,不必在行末加分号

  • 在进行宏定义时,可以引用已定义的宏名,可以层层置换

  • 宏名和宏内容必须在同一行中进行声明。如果在宏内容中包含有注释行,注释行不会作为被置换的内容

parameter

parameter是Verilog数据类型中的一种,不过与常规的reg或wire不同,parameter不是变量,而是常量。
parameter因其常量特性,无法在仿真的过程中进行修改,不过在编译的时候,我们可以使用defparam对其进行修改。

  • parameter可以被声明为integer,real,realtime,time四种类型
  • 也可以在parameter后加上signed使其变为有符号数
  • 可以声明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]

parameter定义常量,可以定义在模块内部或外部

parameter在模块内部定义常量:

 
module param_idef(input clk,input [2:0]din,output reg [3:0]sum);parameter ADD = 2'd1;
always@(posedge clk)
beginsum <= din+ADD;
end
endmodule

parameter在模块内部定义常量:

 
module param_odef
#(parameter ADD2 = 2'd1)
(input clk,input [2:0]din,output reg [3:0]sum);always@(posedge clk)
beginsum <= din+ADD2;
end
endmodule

localparam

  • localparam指定的参数不能通过defparam进行修改

  • localparam指定的参数不能通过模块例化进行修改;

  • localparam指定的参数可通过parameter赋值进行间接的修改,此时可利用parameter的修改方式实现localparam的修改;

  • 在这里插入图片描述

上述代码中MSB和LSB均可以通过defparam和模块例化的方式进行修改,但是FIFO_MSB和FIFO_LSB仅能通过MSB、LSB、SIZE进行修改或者直接赋值为常量。也就是说,如果要对localparam进行重新修改,那么只能通过parameter间接的进行修改,其参数化是通过parameter体现的

specparam

路径延迟用关键字 specify 和 endspecify 描述,关键字之间组成 specify 块语句。specify 是模块中独立的一部分,不能出现在其他语句块(initial, always 等)中。specify 块语句主要有以下功能:

  • 指定所有路径中引脚到引脚的延迟;

  • 定义 specparam 常量;

  • 在电路中设置时序检查。

实例:

   specifyspecparam ab_2_out = 2.5 ;specparam cd_2_out = 3.5 ;//每条路径都有一个源引脚和目的引脚,将这些路径的延迟依次用 specify 语句描述出来,称为并行连接。(a => out) = ab_2_out ;(b => out) = ab_2_out ;(c => out) = cd_2_out ;(d => out) = cd_2_out ;endspecify

parameter,localparameter,specparam参数的异同点

在这里插入图片描述

Verilog 带参数例化

链接:参数覆盖有两种方式:1)使用关键字 defparam,2)带参数值模块例化

原文链接:
https://developer.aliyun.com/article/12283

https://blog.csdn.net/Times_poem/article/details/51371940
https://www.cnblogs.com/xgcl-wei/p/9090918.html
https://www.runoob.com/w3cnote/verilog-defparam.html
https://blog.csdn.net/weixin_43698385/article/details/124745762?spm=1001.2101.3001.6650.17&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-17-124745762-blog-108027613.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-17-124745762-blog-108027613.pc_relevant_default&utm_relevant_index=19


http://chatgpt.dhexx.cn/article/LLKQr87l.shtml

相关文章

【原创】parameter、localparam和specparam

在Verilog中&#xff0c;parameter既不属于变量范畴也不属于线网范畴&#xff0c;经常用来定义一个标志符代表一个常量&#xff0c;所以参数的值在仿真运行的过程中不能进行修改。但是通过使用参数&#xff0c;可以提高程序的可读性、可复用性和可维护性。目前常用的参数主要分…

model.parameters()的理解与使用

model.parameters()保存的是Weights和Bais参数的值。 首先定义一个模型 #design Model class NeuralNetwork(nn.Module):def __init__(self):super(NeuralNetwork,self).__init__()self.flatten nn.Flatten()self.linear_relu_stack nn.Sequential(nn.Linear(2*2, 5),nn.ReL…

@param详解注解

param注解的四种使用场景 第一种&#xff1a;方法有多个参数&#xff0c;需要 Param 注解 Mapper public interface UserMapper {Integer insert(Param("username") String username, Param("address") String address); }对应的 XML 文件如下&#xff1…

ios touchesBegan不触发

ios touchesBegan不触发 今天简单写了一个touchesBegan&#xff0c;发现无法触发&#xff0c;点击无效&#xff0c;网上找了半天没有效果。 最终发现问题是uiimageview需要开启交互&#xff1a;

UITableView是不会响应touchesBegan:方法的

2019独角兽企业重金招聘Python工程师标准>>> UITableView是不会响应touchesBegan:withEvent:之类的UIResponder的方法的。因此&#xff0c;加在其上的所有视图的响应者链就断了。如果在UITableView其上加任何的自身不具备类似UIButton一样有目标动作机制的UIView及其…

ios-tableView的touchesBegan事件和didSelectRowAtIndexPath方法

今天做了个测试&#xff0c;看看tableView如果实现了touchesBegan方法和实现了didSelectRowAtIndexPath点击的时候会去实现哪一个&#xff1f; 答案是touchesBegan。 先附上测试的函数 -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {N…

iOS事件机制,以及不同手势使用touchesBegan等表现形式

事件处理方法 UIResponder中定义了一系列对事件的处理方法&#xff0c;他们分别是&#xff1a; –(void)touchesBegan:(NSSet )touches withEvent:(UIEvent )event–(void)touchesMoved:(NSSet )touches withEvent:(UIEvent )event–(void)touchesEnded:(NSSet )touches withEv…

touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event使用

iOSProgramming – 触摸事件处理&#xff08;2&#xff09; 在上一篇《iOS Programming – 触摸事件处理&#xff08;1&#xff09;》中了解触摸、事件和响应者之后&#xff0c;接下去学习如何处理用户的触摸事件。首先触摸的对象是视图&#xff0c;而视图的类UIView继承了UIRe…

iOS事件机制,以及不同手势使用touchesBegan等表现

2019独角兽企业重金招聘Python工程师标准>>> //事件处理方法 UIResponder中定义了一系列对事件的处理方法&#xff0c;他们分别是&#xff1a; –(void)touchesBegan:(NSSet )touches withEvent:(UIEvent )event –(void)touchesMoved:(NSSet )touches withEvent:(U…

ios事件-触摸事件3(UIButton 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()的关系)

ios事件-触摸事件3(UIButton 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()、touchesCancelled()的关系) 先看效果图 本文中&#xff0c;凡是看到xxx(),即表示xxx是一个函数或者方法&#xff01;&#xff01;&#xff01;事件分为事件传递和事…

【application Extension 之TodayExtension】扩展与宿主App之间共享数据有两种方式

文章目录 前言I 、点击跳转到APPII、扩展与宿主App之间共享数据有两种方式:2.1.通过NSUserDefaults2.2. 通过一个扩展与App都可以访问的共享容器,来存放文件,数据(Core Data, Sqlite等都可以存放在这个共享的容器中)III、扩展Widget高度前言

PHP-递归算法

在PHP开发过程中&#xff0c;递归算法通常用于无限极分类。那么所谓递归就是一种函数调用自身的机制。简单来说就是在函数体内直接或间接自己调用自己&#xff0c;但需要设置自调用的条件&#xff0c;若满足条件&#xff0c;则调用函数本身&#xff0c;若不满足则终止本函数的自…

php 递归 递归方式与算法

先设置数据在本地数据库&#xff0c;设置前要先了解pid字段的关系。如果做成菜单还需添加一个路由字段&#xff0c;自行定义。 第一种方式 先将数据提取出转换成数组。重点是Yarray方法里的递归方式。 接下来进行解析方式。 重点&#xff1a;一定要在进行递归之前声明一个静态…

关于递归函数

递归函数概念 递归就是一个函数在它的函数体内调用它自身。执行递归函数将反复调用其自身&#xff0c;每调用一次就进入新的一层。递归函数必须有结束条件。 当函数在一直递推&#xff0c;直到遇到墙后返回&#xff0c;这个墙就是结束条件。 所以递归要有两个要素&#xff0c;…

php递归函数详解

很多同学在学习递归函数的时候会感到头晕&#xff0c;无法搞清楚递归函数的原理和运行机制&#xff0c;本文将给大家详细讲解递归函数的运行机制和运用。 那什么是递归函数呢&#xff1f; 递归函数即为自调用函数&#xff0c;在函数体内直接或间接自己调用自己&#xff0c;但需…

递归函数

一、基本的递归函数 首先先来了解下C程序在内存中的组织方式&#xff0c;基本上来说一个可执行的程序在内存中有4个区域组成&#xff1a;代码段、静态数据区、堆与栈。代码段包含程序运行时所执行的机器指令&#xff1b;静态数据区是包含在程序的生命周期内的一直持续的数据&a…

PHP 递归函数的理解

很多同学在学习递归函数的时候会感到头晕&#xff0c;无法搞清楚递归函数的原理和运行机制&#xff0c;本文将给大家详细讲解递归函数的运行机制和运用。那什么是递归函数呢&#xff1f;递归函数即为自调用函数&#xff0c;在函数体内直接或间接自己调用自己&#xff0c;但需要…

PHP中使用递归函数

下面是使用递归函数的一个小例子。 目的是根据parent_id和task_id对task进行分类。 具体实现&#xff1a; <?php //连接数据库&#xff0c;使用前几天创建的数据库连接文件进行连接&#xff0c;如果没有这个文件可以去我的博客里找一下 require_once(./db.php); $conn…

PHP递归详解

递归 递归是一种函数调用自身的机制递归必须要有边界条件&#xff0c;也就是递归出口&#xff08;退出递归&#xff09;递归前进段和递归返回段&#xff0c;也就是最后得到的值当边界条件不满足时&#xff0c;递归前进&#xff1b;当边界条件&#xff08;递归出口&#xff09;…

PHP 递归函数

递归函数即自调用函数&#xff0c;在函数体内部直接或间接的自己调用自己&#xff0c;即函数的嵌套调用就是函数本身。通常 在此类型的函数体中会附加一个条件判断&#xff0c;以判断是否需要执行递归调用&#xff0c;并且在特定的条件下终止函数的递归 调用动作&#xff0c;…