Verilog编写锁存器应使用阻塞赋值还是非阻塞赋值?
Verilog锁存器的正确编码方式说明
你观察到两种赋值方式都能被Vivado综合为锁存器是符合预期的:综合工具的核心判断依据是你描述的逻辑是否符合锁存器的功能特性(电平有效时输出跟随输入变化,电平无效时输出保持),和你使用阻塞还是非阻塞赋值没有直接关系。
但从行业通用编码规范、仿真与综合结果一致性的角度来看,锁存器作为电平敏感逻辑,应当使用阻塞赋值,原因如下:
- 非阻塞赋值本身是为时钟沿触发的时序逻辑设计的语法,在电平敏感的
always块中使用时,会导致仿真调度时同时间步的读操作读到赋值前的旧值,和锁存器的真实硬件行为不符,极易出现前仿和后仿、仿真和实际电路行为不一致的问题。 - 阻塞赋值的行为完全匹配电平敏感逻辑的硬件特性:高电平有效期间,输入的变化会立刻传递到输出端,和真实锁存器的传输延迟表现完全一致,不会引入仿真层面的额外偏差。
你给出的示例代码存在语法问题:input是Verilog的保留关键字,不能作为信号名使用,标准的锁存器参考写法如下:
// 高电平有效锁存器标准写法 // 用@(*)自动推导敏感列表,避免手动写敏感列表遗漏信号 always @(*) begin if(enable) begin q = d; // d为锁存器输入信号,替代示例中的input关键字 end end
补充说明:非阻塞赋值仅推荐在时钟沿触发的时序逻辑(寄存器、触发器)描述中使用,这是Verilog编码的核心规范之一,严格遵循可以避免90%以上的仿真竞争冒险问题。
内容的提问来源于stack exchange,提问作者PARUL
相关产品推荐
相关产品推荐

