在 Verilog/SystemVerilog 中,`````是重音符号(backtick,反引号),用于编译器指令、系统任务和常量。
1. 编译器指令(Compiler Directives)
`define WIDTH 8 // 定义宏
`ifdef DEBUG // 条件编译
`include "debug.v"
`endif
`timescale 1ns/1ps // 时间单位和精度
2. 系统任务和函数(System Tasks/Functions)
`display("Hello"); // 显示信息
`finish; // 结束仿真
`time // 当前仿真时间
`random // 随机数
3. 特殊常量
// 最常见的使用:'0, '1, 'x, 'z
reg [7:0] data = '0; // 所有位设为 0
reg [7:0] all_ones = '1; // 所有位设为 1
reg [7:0] unknown = 'x; // 所有位设为 x(不定态)
reg [7:0] high_z = 'z; // 所有位设为 z(高阻态)
// 会自动根据信号宽度填充
reg [31:0] data32 = '1; // 32位全1
reg [15:0] data16 = '0; // 16位全0
具体用法示例:
示例1:全0初始化
// 传统写法
reg [31:0] data1 = 32'h0000_0000;
reg [15:0] data2 = 16'h0000;
reg [7:0] data3 = 8'h00;
// 使用 '0 的简洁写法
reg [31:0] data1 = '0; // 自动扩展为 32 位
reg [15:0] data2 = '0; // 自动扩展为 16 位
reg [7:0] data3 = '0; // 自动扩展为 8 位
示例2:参数化代码
module example #(
parameter WIDTH = 32
)(
input clk, rst,
output reg [WIDTH-1:0] data
);
// 使用 '0 可以自动适应参数
always @(posedge clk) begin
if (rst)
data <= '0; // 无论 WIDTH 是多少,都会正确清零
else
data <= data + 1;
end
endmodule
示例3:在赋值中使用
// 将总线全部设为高阻
wire [7:0] data_bus = 'z;
// 默认值
logic [3:0] state = 'x; // 初始为不定态
// 复位逻辑
always @(posedge clk) begin
if (reset) begin
counter <= '0; // 计数器清零
flags <= '0; // 标志位清零
buffer <= '0; // 缓冲区清零
end
end
与普通数字字面量的区别:
// 普通数字字面量
reg [7:0] a = 0; // 十进制0,实际是 8'b0000_0000
reg [7:0] b = 1; // 十进制1,实际是 8'b0000_0001
reg [7:0] c = 8'hFF; // 明确的 8 位全1
// 使用 ' 符号
reg [7:0] d = '0; // 自动填充为 8 位全0
reg [7:0] e = '1; // 自动填充为 8 位全1
reg [7:0] f = 'x; // 8 位全 x
reg [7:0] g = 'z; // 8 位全 z
特殊符号表:
| 符号 | 含义 | 示例 |
|---|---|---|
'0 |
全0 | reg [7:0] a = '0;→ 8'b0000_0000 |
'1 |
全1 | reg [7:0] a = '1;→ 8'b1111_1111 |
'x或 'X |
全不定态 | reg [7:0] a = 'x;→ 8'bxxxx_xxxx |
'z或 'Z |
全高阻态 | reg [7:0] a = 'z;→ 8'bzzzz_zzzz |
注意事项:
-
只能用于赋值,不能用于比较:
// 正确
reg [7:0] data = '0;// 错误
if (data == '0) begin // 不能这样比较 -
必须用单引号,不是双引号:
reg [7:0] a = '0; // 正确
reg [7:0] b = "0"; // 错误 -
在 case 语句中特殊用法:
case (data)
'0: display("All zeros"); // 匹配全0 '1: display("All ones"); // 匹配全1
'x: display("All unknown"); // 匹配全x default: display("Other");
endcase
总结:
符号的主要作用是:
1. **编译器指令** (`define,`ifdef 等)
2. **系统任务** (`display,`finish 等)
3. **特殊常量**(\`0, '1, 'x, 'z)用于自动位宽填充
在 RTL 代码中最常见的就是使用 `'0`来初始化或复位信号,这样代码更简洁且参数化友好。