【问题标题】:VHDL No Delta Delay Input to Output AssignmentVHDL 无增量延迟输入到输出分配
【发布时间】:2018-02-08 21:02:43
【问题描述】:

我遇到了如下情况:

library ieee;
use ieee.std_logic_1164;

entity clkin_to_clkout is
port (
  clk_in : in std_logic;
  clk_out : out std_logic);
end entity clkin_to_clkout;

architecture arch of clkin_to_clkout is
begin

    clk_out <= clk_in;

end architecture arch;

clk_in 到 clk_out 的分配对综合来说不是问题,但在模拟器中,它会导致从 clk_in 到 clk_out 的增量延迟,从而创建时钟跨越边界。有没有办法在不引入增量延迟的情况下将实体输出分配给实体输入?谢谢。

编辑:对一些 cmets 的回应。首先,我想回答这个确切的问题。为了澄清起见,我希望输出端口的行为与输入端口的别名完全相同。如果答案是“在 VHDL 中,不可能使输出端口与输入端口的行为完全匹配”,那么这是正确的答案,我会接受它作为语言的限制。其次,如果看不出问题出在哪里,请在下面的testbench中实例化clkin_to_clkout实体,模拟几个clk1周期后观察mr_sig_del_dly和mr_sig_clk_dly的区别:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity delta_delay is
end entity delta_delay;

architecture arch of delta_delay is

  signal clk1: std_logic := '0';
  signal clk2 : std_logic;
  signal mr_sig : unsigned(7 downto 0) := (others => '0');
  signal mr_sig_del_dly : unsigned(7 downto 0);
  signal mr_sig_clk_dly : unsigned(7 downto 0);

  component clkin_to_clkout is
  port (
    clk_in : in std_logic;
    clk_out : out std_logic);
  end component clkin_to_clkout;

begin

  clk1 <= not clk1 after 10 ns;

  clk_inst : clkin_to_clkout
  port map (
    clk_in  => clk1,
    clk_out => clk2);

  mr_sig <= mr_sig + 1 when rising_edge(clk1);
  mr_sig_del_dly <= mr_sig when rising_edge(clk2);
  mr_sig_clk_dly <= mr_sig when rising_edge(clk1);

end architecture arch;

当您进行仿真时,您会观察到 mr_sig_clk_dly 按预期延迟了 1 个时钟周期,因为它被分配在与 mr_sig 相同的时钟 (clk1) 上。 mr_sig_del_dly 不会延迟 1 个 clk1 周期,即使 clk2 只是 clkin_to_clkout 模块中的 clk1 的直通。这是因为 clk2 是 clk1 的增量延迟版本,因为我使用了信号分配。 再次感谢您的所有回复。

【问题讨论】:

  • 为什么增量延迟是个问题?时钟跨越边界与增量延迟无关。
  • 请看我对你的回答的评论。
  • 我做到了。无论如何,这个组件有什么用?您似乎要求我们解决您认为可以解决您最初问题的问题。又名XY-problem。请告诉我们您最初遇到的问题。
  • 这与我在这里问的问题几乎相同stackoverflow.com/questions/36153003/…
  • Delta 延迟不会引入时钟边界跨越问题。但是他们很可能暴露这样的问题。

标签: vhdl


【解决方案1】:

在 VHDL-2008 或之前的版本中,无法使输出端口与输入端口的行为完全匹配。 参考 Jim Lewis 对原始问题的评论。 谢谢,吉姆和所有发表意见的人。

【讨论】:

    【解决方案2】:

    您似乎不知道什么是增量延迟。 增量延迟是无限小的延迟。每个分配(至少)在模拟中都有一个增量延迟。这就是 VHDL 的工作原理。

    编辑:

    在你的 cmets 之后,我知道你来自哪里。您遇到的问题可能只是模拟,因为综合会简化它。但是,有一个电子等效物,即多相时钟。考虑您想要一个两相时钟,即差分信号,其中第二个信号是第一个信号的倒数。如果您仅通过使用一个反相器来实现这些时钟,则第二个信号将具有相位偏移。这是由于逆变器组件的延迟。因此,在时钟生成逻辑(如 PLL 和 DCM)中,非反相信号也被延迟(使用可变延迟缓冲器)。 IE。 所有时钟信号都需要处理,为它们提供相同的(增量)延迟。

    同样的解决方案可以应用在 VHDL 中。示例:

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity clk_buffers is
        port(
            clk : in std_logic;
            clk1 : out std_logic;
            clk2_n : out std_logic
            );
    end entity;
    
    architecture rtl of clk_buffers is begin
        clk1 <= clk;
        clk2_n <= not clk;
    end architecture;
    
    library ieee;
    
    entity test_bench is end entity;
    architecture behavioural of test_bench is
        use ieee.std_logic_1164.all;
        signal clk, clk1, clk2_n : std_logic := '1';
        signal base, child1, child2 : integer := 0;
    begin
        clk <= not clk after 1 ns;
    
        clk_buffers_inst : entity work.clk_buffers
            port map(clk => clk, clk1 => clk1, clk2_n => clk2_n);
            
        base <= base+1 when rising_edge(clk1);
        child1 <= base when rising_edge(clk1);
        child2 <= base when falling_edge(clk2_n);
    end architecture;
    

    【讨论】:

    • 我知道什么是 delta 延迟,这确实会在仿真中产生时钟交叉问题,因为一旦在 clk_out 上引入了 delta 延迟,clk_in 和 clk_out 就不再是同一个时钟了。考虑我是否有一个使用该实体的更高实体并在该更高实体的 clk_in 时钟上计时一些信号。如果我想在 clk_out 上为这些相同的信号提供时钟,我必须实例化一个时钟交叉机制(FIFO,额外的触发器)来跨越从 clk_in 到 clk_out 的边界。
    • 您是否真的尝试过创造您所描述的条件?您是否看到您对时钟域的感知变化会导致行为发生实际变化?
    • @DLnd 不,我没有。但我不是有问题的人。也许您应该评论原始问题;)
    • @michaelgrover 恐怕那是因为你在其他地方做错了什么。您显示的代码完全正常,不会引起任何问题。
    • @JHBonarius 抱歉,这是对 OP 评论的回复,而不是您的回答。
    猜你喜欢
    • 2020-05-03
    • 2022-12-06
    • 1970-01-01
    • 2021-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多