Verilog RTL 基础
Verilog 中信号类型、组合与时序过程、赋值语义和模块接口的基本约束。
- 问题
- Verilog 中信号类型、组合与时序过程、赋值语义和模块接口的基本约束。
- 环境
- Verilog · FPGA · RTL
- 状态
- 待发布
- 首次发布
- 2026年4月7日
- 最后更新
- 2026年8月10日
- 预计阅读
- 2 分钟
说明:语言边界 本文说明传统 Verilog RTL 的基础语义。新项目如采用 SystemVerilog,应同时遵循团队的
logic、always_comb、always_ff、断言和 lint 规范,不能只套用这里的简化写法。
四值逻辑与驱动
Verilog 信号除 0 和 1 外还有 x(未知)与 z(高阻)。仿真里的 x 往往表示未初始化、冲突驱动或无法确定的逻辑;不应把它当作可以忽略的“默认值”。z 常见于三态或未被驱动的网络,片内逻辑的三态通常会被综合为多路选择结构。
传统 Verilog 中,wire 表示由连续赋值或模块输出驱动的网络,reg 表示可在过程块中赋值的变量;reg 这个词不自动意味着综合出物理寄存器,是否产生寄存器取决于过程和赋值是否覆盖所有路径。
组合逻辑和时序逻辑
组合逻辑应覆盖所有输入路径,避免无意推断锁存器:
always @(*) begin next_state = state; // 默认赋值 case (state) IDLE: if (start) next_state = RUN; RUN: if (done) next_state = IDLE; default: next_state = IDLE; endcaseend时序逻辑由时钟沿触发,并通常使用非阻塞赋值 <=:
always @(posedge clk or negedge rst_n) begin if (!rst_n) state <= IDLE; else state <= next_state;end组合过程通常使用阻塞赋值 =,时序过程通常使用非阻塞赋值 <=。不要在同一个寄存器的多个过程块中赋值,也不要在同一过程内随意混用两种语义。
模块接口与可综合性
模块边界要写清时钟、复位、方向、位宽和有效/就绪握手。命名端口连接比位置连接更抗接口变更:
counter u_counter ( .clk (clk), .rst_n (rst_n), .enable(enable), .count (count));initial、延时控制、fork/join 和部分系统任务在仿真中有用,但其综合含义依赖目标工具与器件。把 testbench 与可综合 RTL 分开维护,并用 lint、仿真和时序检查共同验证。
FIFO 与跨时钟域的具体约束见 FPGA FIFO 与时钟域交叉。