VHDL中如何实现输入到输出无Delta Delay的端口赋值?
解决时钟端口无Delta延迟别名化的问题
刚好之前处理过完全一样的场景——仿真里的Delta延迟导致时钟跨域误报,综合却完全正常。核心需求就是让输出端口成为输入端口的完全别名,共享同一个信号存储单元,彻底消除仿真延迟。
下面分两种主流HDL给出精准解决方案,综合和仿真都能满足要求:
Verilog / SystemVerilog 实现
如果你的环境支持SystemVerilog,直接用alias语句是最优雅的方式,它会让两个端口完全绑定,没有任何仿真延迟:
module clock_alias( input wire clk_in, output wire clk_out ); // 直接将clk_out设为clk_in的别名,无Delta延迟 alias clk_out = clk_in; endmodule
如果只能用纯Verilog,用buf原语(零延迟缓冲)也能达到同样效果:
module clock_alias( input wire clk_in, output wire clk_out ); // 零延迟原语连接,仿真无Delta延迟,综合直接连线 buf(clk_out, clk_in); endmodule
这两种方式在综合时都会被优化成直接导线,和普通assign的综合结果完全一致,不会引入任何额外逻辑。
VHDL 实现
VHDL里要实现零延迟别名,有两种可靠方式:
- 使用0ns传输延迟:通过
transport关键字强制仿真器立即更新信号,消除Delta延迟:
entity clock_alias is port( clk_in : in std_logic; clk_out : out std_logic ); end entity clock_alias; architecture rtl of clock_alias is begin -- transport 0ns 强制当前Delta周期内更新,无延迟 clk_out <= transport clk_in after 0 ns; end architecture rtl;
- VHDL-2008别名方案:如果你的工具支持VHDL-2008,可以直接给输入信号创建别名,再绑定到输出:
entity clock_alias is port( clk_in : in std_logic; clk_out : out std_logic ); end entity clock_alias; architecture rtl of clock_alias is -- 创建clk_in的别名 alias clk_in_alias : std_logic is clk_in; begin -- 直接绑定别名到输出,无Delta延迟 clk_out <= clk_in_alias; end architecture rtl;
这两种方式综合后都会被优化为直接连线,同时仿真时完全消除Delta延迟,让clk_out的行为和clk_in完全一致。
关键说明
普通赋值(Verilog的assign、VHDL的普通信号赋值)之所以会产生Delta延迟,是因为仿真器会在当前Delta周期的所有事件处理完后才更新目标信号;而别名/零延迟原语/0ns传输延迟,都是让目标信号直接引用源信号的存储单元,或者强制立即更新,从根源上避免了延迟。
内容的提问来源于stack exchange,提问作者Michael Grover
相关产品推荐
相关产品推荐

