FPGA基础 -- Verilog表达式之操作数:常数
🧠 一、Verilog 常数操作数的本质是什么?
在 Verilog 中,**常数操作数(Constant Operand)**是指那些不依赖于仿真时动态赋值的固定值,它们常用于表达式中参与计算、比较或位操作。
举个通俗的例子:
小学生做加法题:
5 + 3
里5
和3
就是常数操作数。
在 Verilog 中类似写作:
assign sum = 5 + 3;
🛠️ 二、Verilog 常数的书写格式总览
Verilog 的常数有三种主要形式,建议记住下面这个口诀:
位宽在前,进制紧跟,数值在后,撇号分明。
🌟 格式:
[位宽]'[进制][数值]
🚦支持的进制:
进制缩写 | 意义 |
---|---|
b | 二进制 |
o | 八进制 |
d | 十进制(default) |
h | 十六进制 |
🧪 举例说明:
表达式 | 含义 |
---|---|
8'b10101010 | 8位二进制数 10101010 |
4'd9 | 4位十进制常数,值为9 |
12'hABC | 12位十六进制数,等于 2748 |
'b1 | 无位宽限制的 1 |
5'b0 | 5位全为0 |
⚠️ 注意:
- 必须有撇号
'
。例如8d255
是非法的,正确写法是8'd255
。 - 如果不指定位宽,则默认是 32位有符号整型(取决于上下文)。
- 大写小写
B
、H
、D
都合法,但建议统一风格使用小写。
🧭 三、常数在表达式中的实际作用
✅ 1. 赋值初始化
reg [7:0] counter = 8'd0;
初始化一个 8 位寄存器为 0,常数的使用让含义一目了然。
✅ 2. 条件判断(比较)
if (state == 3'd4)next_state = 3'd0;
清晰明了地表达状态转换条件,常数语义明确,避免魔法数字。
✅ 3. 位运算
assign mask = 8'b00001111;
assign result = data & mask;
通过常数参与位掩码操作,是硬件逻辑中最常见的应用方式。
✅ 4. 左移、右移中的位移量
assign shifted = value << 4;
这里的
4
也是常数,在硬件中表现为硬连线逻辑。
🧠 四、常见进阶技巧
🔁 技巧1:用 localparam
命名常数,避免魔法数
localparam IDLE = 2'd0, RUN = 2'd1, DONE = 2'd2;
✅ 好处:
- 增强代码可读性
- 更容易修改维护
- 避免混淆位宽
🎭 技巧2:用全 1
或全 0
值快速赋值
assign data = {8{1'b1}}; // 等价于 8'b11111111
或:
assign data = ~8'd0; // 结果是 8'b11111111
🧯 技巧3:防止位宽不匹配导致的截断/扩展
错误示例:
assign result = 4'd3 + 8'd5; // 跨位宽操作,可能截断
建议使用统一位宽:
assign result = 8'd3 + 8'd5;
🚫 五、易错点警示 ⚠️
❶ 忘记写撇号 '
assign a = 8d255; // ❌ 错误,应该是 8'd255
❷ 位宽不匹配引发误判
if (signal == 1) // signal 是 2 位宽
应写为:
if (signal == 2'd1)
❸ 多位二进制书写易错
assign mask = 8'b1111; // 实际是 00001111,不是 11111111