SV常量变量
常量
全局
define
定义宏常量- 全局跨文件文本常量替换
模块级
parameter
定义可重写模块级常量- 编译时常量,实例化时可被覆盖
- 支持表达式计算
1 | module RAM #( |
localparam
定义不可重写模块级常量- 模块内部专用常量
- 不能被外部覆盖,常用于派生参数
1 | module ALU ( |
块、类级
const
定义运行时可初始化的常量- 可在类、函数、initial块中使用
- 需要显示初始化,初始化后不可变
1 | class Packet; |
枚举常量
typedef enum
定义枚举常量- 用于定义状态机、命令码等有限值集合
- 自动或手动赋值,提高代码可读性
1 | typedef enum logic [2:0] { // 显式指定底层类型 |
常量函数
- 用于复杂计算生成常量值
- 在编译时求值,只能包含常量表达式
1 | function automatic int clog2(input int n); |
静态变量
声明
- 隐式静态变量:
module
、program
中的function
和task
中声明的变量默认是静态的 - 显示静态变量:使用
static
关键词显式声明
特性
-
存储在全局数据区,固定内存位置
-
同一个模块多次实例化时共享静态变量
- 由于使用共享的静态存储区,这也可能导致不用线程之间窜用
-
适用场景
- 模块级配置参数
- 硬件寄存器建模
- 时序逻辑总是使用静态变量保持状态
- 如跨多个时钟周期保持值的计数器
- 跨时间控制语句的变量
生命周期
- 从仿真开始(时间0)持续到仿真结束
- 在多次触发的过程块中,只在仿真时间为0时进行一次初始化
1 | module |
自动变量
声明
- 隐式自动变量:
class
内部的fucntion
、task
中声明的变量默认是自动的,initial
和always
中声明的变量默认也是自动的 - 显示自动变量:使用
automatic
关键词显示声明- 建议在需要动态存储时,显式声明
automatic
,而非依赖隐式规则,避免混淆
- 建议在需要动态存储时,显式声明
1 | //program块中显示指定自动存储方式 |
特性
- 存储在栈帧中,动态分配内存
- 多实例独立,每次调用创建独立副本
- 适用场景
- 纯计算逻辑中使用自动变量
- 递归函数必须使用自动变量
- 不需要保持状态的中间变量
- 验证环境中的临时对象
生命周期
- 仅在作用域激活期间存在
- 每次进入作用域时重新初始化
- 作用域结束时销毁
initial
中的自动变量可能在进程挂起后被回收,根据仿真器调度选项而定
1 | always_ff @(posedge clk) begin |
时间值
单位与精度
- 一种方法是使用编译指示语句``timescale`。确保时延有适宜的量程和精度
- 当采用多种``timescale`时,可能会因编译次序导致问题
- 建议每个文件末尾都以``timescale`结束,将其恢复为公司规定的默认值
- 另一种方式是使用
timeunit
和timeprecision
声明语句为每个模块指明时间- 若使用上述语句替代``timescale`,要求把它们放入每个带时延的模块中
时间参数
- 控制时间显示格式:
$timeformat(四个参数)
,主要影响$display
、monitor
等任务中%t
格式符的输出- 第一个参数:时间单位指数(必填),如-9对应1ns、-12对应1ps
- 第二个参数:小数点后保留位数(默认0)
- 第三个参数:时间值后的后缀(默认空字符串)
- 第四个参数:时间字符串的最小宽度(默认20),自动左侧补空格
$time
的返回值是根据所在模块的时间精度要求进行舍入的整数,$realtime
的返回值则是带小数部分的完整实数- 在计算时延时也可以使用
time t
或realtime r
定义变量存储数据 - 如在``timescase 1ns/100ps
中,
time t = 800ps以1ns存储,
realtime r = 800ps`以0.8ns存储
- 在计算时延时也可以使用
1 | module timing; |