Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Logic VHDL-从电平采样到边缘触发的转换-直观的解释?_Logic_Vhdl_Simulation_Waveform_Synthesis - Fatal编程技术网

Logic VHDL-从电平采样到边缘触发的转换-直观的解释?

Logic VHDL-从电平采样到边缘触发的转换-直观的解释?,logic,vhdl,simulation,waveform,synthesis,Logic,Vhdl,Simulation,Waveform,Synthesis,我有以下代码(一个基本的“RS-232信号”发送器) 在这里,我希望更改逻辑以测试send上的上升沿,而baud_clk上没有上升沿 我知道这不是解决问题的有效方法(当然合成器会发出呻吟声),但我希望有人能简单地解释为什么不能这样做。如果可以在一个过程中使用两个边缘检测器,会发生什么情况?这里有一个我无法理解的概念,我似乎总是以同样的方式编写代码并产生这个问题。我正在努力与多年来根深蒂固的软件编程习惯作斗争,这对我没有多大帮助 听起来好像send与baud\u clk是异步的。因此,您需要执行某

我有以下代码(一个基本的“RS-232信号”发送器)

在这里,我希望更改逻辑以测试
send
上的上升沿,而
baud_clk
上没有上升沿


我知道这不是解决问题的有效方法(当然合成器会发出呻吟声),但我希望有人能简单地解释为什么不能这样做。如果可以在一个过程中使用两个边缘检测器,会发生什么情况?这里有一个我无法理解的概念,我似乎总是以同样的方式编写代码并产生这个问题。我正在努力与多年来根深蒂固的软件编程习惯作斗争,这对我没有多大帮助

听起来好像
send
baud\u clk
是异步的。因此,您需要执行某种形式的时钟域交叉(CDC)以正确实现您的设计,否则您的设计将无法通过计时,并且可能无法正常工作。CDC是一个标准术语,您应该能够在其他问题和其他地方找到更多相关信息

正如您所发现的,如果一个设计对两个不同信号的边缘敏感,那么它就不可能在真正的硬件中实现。没有一种“正确”的方法来做你想做的事情,但这里有一个例子,它使用了一个简单的“切换”CDC。这非常简单,但请注意,如果一个
send
请求在传输前一个字节之前到达,则设计可能会错过发送一个字节。在断言
send
信号和传输启动之间也会引入一些延迟。不清楚这些问题在您的系统中是否重要

创建另一个对
发送敏感的进程

-- The initial state doesn't matter, but we want the design to work in simulation
signal send_toggle : std_logic := '0';  

process(send)
begin
  if (rising_edge(send)) then
    send_toggle <= not send_toggle;
  end if;
end process;
以上是一个非常标准的电路块,可以在许多单位CDC场景中使用

然后,您的传输过程可以注册
send\u toggle\u r2
信号,以查找转换,从而确定是否应该开始发送。此信号位于正确的时钟域中:

signal send_toggle_r1 : std_logic;
signal send_toggle_r2 : std_logic;

process(baud_clk)
begin
  if (rising_edge(baud_clk)) then
    send_toggle_r1 <= send_toggle;
    send_toggle_r2 <= send_toggle_r1;
  end if;
end process;
signal send_toggle_r3 : std_logic;

process(baud_clk) is
begin
    if rising_edge(baud_clk) then
        send_toggle_r3 <= send_toggle_r2;
        if ((send_toggle_r3 /= send_toggle_r2) and (shifter = IDLE_BITS)) then
            shifter <= "11" & data & '0';
        elsif (shifter /= IDLE_BITS) then
            shifter <= '0' & shifter(10 downto 1); -- shifter >>= 1;
        end if;
    end if;
end process;
信号发送切换3:标准逻辑;
进程(波特率时钟)为
开始
如果上升沿(波特时钟),则

baud\u clk
驱动发送开关\u r3边缘检测器链。位定时不是绝对完美的,但这对于标准的“UART”场景来说并不重要。

听起来
send
baud\u clk
是异步的。因此,您需要执行某种形式的时钟域交叉(CDC)以正确实现您的设计,否则您的设计将无法通过计时,并且可能无法正常工作。CDC是一个标准术语,您应该能够在其他问题和其他地方找到更多相关信息

正如您所发现的,如果一个设计对两个不同信号的边缘敏感,那么它就不可能在真正的硬件中实现。没有一种“正确”的方法来做你想做的事情,但这里有一个例子,它使用了一个简单的“切换”CDC。这非常简单,但请注意,如果一个
send
请求在传输前一个字节之前到达,则设计可能会错过发送一个字节。在断言
send
信号和传输启动之间也会引入一些延迟。不清楚这些问题在您的系统中是否重要

创建另一个对
发送敏感的进程

-- The initial state doesn't matter, but we want the design to work in simulation
signal send_toggle : std_logic := '0';  

process(send)
begin
  if (rising_edge(send)) then
    send_toggle <= not send_toggle;
  end if;
end process;
以上是一个非常标准的电路块,可以在许多单位CDC场景中使用

然后,您的传输过程可以注册
send\u toggle\u r2
信号,以查找转换,从而确定是否应该开始发送。此信号位于正确的时钟域中:

signal send_toggle_r1 : std_logic;
signal send_toggle_r2 : std_logic;

process(baud_clk)
begin
  if (rising_edge(baud_clk)) then
    send_toggle_r1 <= send_toggle;
    send_toggle_r2 <= send_toggle_r1;
  end if;
end process;
signal send_toggle_r3 : std_logic;

process(baud_clk) is
begin
    if rising_edge(baud_clk) then
        send_toggle_r3 <= send_toggle_r2;
        if ((send_toggle_r3 /= send_toggle_r2) and (shifter = IDLE_BITS)) then
            shifter <= "11" & data & '0';
        elsif (shifter /= IDLE_BITS) then
            shifter <= '0' & shifter(10 downto 1); -- shifter >>= 1;
        end if;
    end if;
end process;
信号发送切换3:标准逻辑;
进程(波特率时钟)为
开始
如果上升沿(波特时钟),则

baud\u clk
驱动发送开关\u r3边缘检测器链。位定时可能不是绝对完美的,但对于标准的“UART”场景来说,这并不重要。

CDC和亚稳态对我来说确实是新术语,感谢您指出这些。我将阅读这些内容,并查看其他一些关于SO的VHDL主题(这看起来是一个非常有价值的关于这个让人心烦意乱的主题的知识来源)。希望我最终能在家里正确设置我的工具链,并在周末尝试模拟/运行您建议的代码更改,然后报告。@Wossname您在原始问题中的评论中询问,我扩展了演示scarry_jeff的答案,并展示了一种提供异步忙的方法。@Thrarry_jeff,信号发送切换r2的原因是什么?如果我删除它并允许send_toggle_r1传播到send_toggle_r3,则系统似乎仍在模拟中工作。@Wossname您需要两个紧密耦合的寄存器才能形成标准的单位CDC元素
send\u toggle\u r3
是进一步利用此CDC元素输出的逻辑。行为模拟不会突出显示CDC问题(在本例中可能是设置/保持冲突),除非您在代码中专门对此类行为建模,并且不建议这样做。CDC问题没有出现在行为模拟中这一事实是它们很难找到和解决的一个重要原因。对于我来说,CDC和亚稳态确实是一个新名词,感谢你指出这些。我将阅读这些内容,并查看其他一些关于SO的VHDL主题(这看起来是一个非常有价值的关于这个让人心烦意乱的主题的知识来源)。希望我最终能在家里正确设置我的工具链,并在周末尝试模拟/运行您建议的代码更改,然后报告。@Wossname您在原始问题的评论中问到,我扩展了演示scarry_jeff的