gpt4 book ai didi

vhdl - 我如何解决这个增量周期时钟延迟问题

转载 作者:行者123 更新时间:2023-12-01 15:14:54 27 4
gpt4 key购买 nike

我有以下代码的简化示例,其中 DeltasTest可以模拟实体以显示问题。实际设计中的时钟是否基于泛型反转或不反转,并在此之下提供其他几个实体。

问题是简单的边缘检测器在行为模拟中不起作用(data_out 只是一个小故障),这是由于反转阶段在时钟上引入了增量周期延迟。有没有标准或其他优雅的方法来解决这个问题?

到目前为止,我最好的解决方案是分配 data_in信号到另一个信号,使其具有与 clk 相同的增量周期延迟.我想过根据需要使用函数来反转时钟,基于泛型作为函数的第二个参数,但是时钟被用在很多地方,这看起来不是很优雅,我注意到它甚至可以解决问题。我迫不及待地想把时钟倒置分配给 transport分配,但是,正如预期的那样,这没有任何区别。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Deltas is
Generic (
CLK_INVERT : boolean := false
);
Port (
clk : in std_logic;
data_in : in std_logic
);
end Deltas;

architecture Behavioral of Deltas is

-- Signals
signal data_reg : std_logic := '0';
signal clk_inverted : std_logic := '0';
signal data_out : std_logic := '0';

begin

ClkInvert : if (CLK_INVERT) generate
clk_inverted <= not clk;
else generate
clk_inverted <= clk;
end generate;

process (clk_inverted)
begin
if (rising_edge(clk_inverted)) then
data_reg <= data_in;
end if;
end process;

process (data_reg, data_in)
begin
if (data_reg /= data_in) then
data_out <= '1';
else
data_out <= '0';
end if;
end process;

-- Other entities use `clk_inverted`. Commented out so that this example compiles
--LowerEntity : entity work.Counter
--port map (
-- clk => clk_inverted
--);

end Behavioral;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity DeltasTest is
end DeltasTest;

architecture Behavioral of DeltasTest is

signal clk : std_logic := '0';
signal data_in : std_logic := '0';

begin

clk <= not clk after 10 ns;

process (clk)
variable count : integer := 0;
begin
if (rising_edge(clk)) then
count := count + 1;
if (count = 4) then
count := 0;
data_in <= not data_in;
end if;
end if;
end process;

uut : entity work.Deltas
Port map (
clk => clk,
data_in => data_in
);

end Behavioral;

最佳答案

我认为您对 data_in 上的额外增量周期的“解决方案”可能是最干净的简单解决方案。

在语义上,分配给 clk_inverted可以转化为硬件作为时钟信号中的反相器,因此模拟中的增量周期延迟代表了真实硬件中引入的(可能是(*)真实的)竞争条件。

因此,模拟行为不仅是一种烦恼,而且是一种有用的特性,警告您必须注意与良好同步设计实践的潜在偏差。

(*) 仅“可能真实”,因为根据技术,综合可能会通过检测相反的边缘将反转“推”到下游 FF - 根据 Morten 的评论自动转换您的设计。

当额外的 delta 周期被埋在其他人的 IP 中时,问题就变得更大了,可能是外部组件的模型,例如内存。然后 IP 不再受您的控制,板级仿真可能会在错误的时钟周期中读取或写入数据。

在这里,我的答案是添加近似的 I/O 延迟,或者作为 FPGA 的 I/O 分配中的惯性延迟(来自 FPGA 数据表或综合报告),或者作为 PCB 上的传输延迟。这确保了我的模拟近似于电路板的行为 - 不是完美的,但足够接近让我能够按照正常的同步实践来设计内部逻辑。

更简洁的解决方案是基于通用生成两个不同的时钟进程。这完全消除了讨厌的增量循环。

最后!使用 SM 的 2 进程形式,其中保持时钟进程尽可能简单有好处......

没那么快...

您要重构的行为是时钟边缘检测,它已经从过时的复杂(级别和事件)表达式重构为一个简单的函数。

为什么不进一步重构时钟边沿检测,例如......

function clock_edge(signal clk : in std_logic) return boolean is
begin
if CLK_INVERT then
return falling_edge(clk);
else
return rising_edge(clk);
end if;
end clock_edge;
...

process (my_clock) is
begin
if clock_edge(my_clk) then ...

我尚未对此进行测试,以查看综合工具是否可以根据需要实现这一点。有些可能会,有些可能不会(如果他们只是对系统提供的功能进行特殊处理而不是正确地完成工作)

在分层设计中,此功能将位于一个包中,供任何需要它的实体使用。这带来了泛型的可见性问题:一个建议是在包中使用常量,另一个建议是将泛型作为第二个参数传递给函数。正确的方法可能取决于综合工具施加的限制。

关于vhdl - 我如何解决这个增量周期时钟延迟问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36153003/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com