一个基于触发信号的时钟周期脉冲

Dav*_*ter 0 triggers clock vhdl pulse

我正在做一个MIDI接口。UART工作正常,它将8位消息以及标志发送到控制单元。当标志变高时,单元会将消息存储在寄存器中,并将clr_flag变高,以便再次将UART的标志设置为低。问题是我不能将此clr_flag设置为一个周期长。我需要将其设置为一个周期长,因为该信号还控制一个状态机,该状态机指示正在存储的消息类型(例如,note_on-> key_note->力度)。

我的问题是,信号(在这种情况下为标志)如何仅在一个clk周期内触发脉冲?我现在在一个时钟周期内几乎发出了一个脉冲,但是我做了两次,因为该标志尚未变为0。香港专业教育学院尝试了很多方法,现在我有这个:

get_data:process(clk, flag)
  begin
  if reset = '1' then
    midi <= (others => '0');
    clr_flag <= '0';
    control_flag <= '0';

  elsif ((clk'event and clk='1') and flag = '1') then
      midi <= data_in;
      clr_flag <= '1'; 
      control_flag <= '1';     
  elsif((clk'event and clk='0') and control_flag = '1') then
    control_flag <= '0';
  elsif((clk'event and clk='1') and control_flag = '0') then
    clr_flag <= '0';
  end if;
end process;
Run Code Online (Sandbox Code Playgroud)

这个双脉冲或长于一个周期脉冲的问题(在此之前,我使clr_flag成为两个周期的clk脉冲)是系统将经过两个状态而不是每个标志一个。

简而言之:当一个信号变高时(与何时变低无关),应在一个时钟周期内产生一个脉冲。

谢谢你的帮助。

Bri*_*ond 5

制作一个单周期脉冲的技巧是意识到已经制作了脉冲,只要触发输入为高电平就必须等待,然后才能重新启动。本质上,您正在构建一个非常简单的状态机,但是只有两个状态时,您可以使用一个简单的布尔值来区分它们。

Morten对时钟过程采用一种标准模式的需求是正确的。我选择了另一种同样有效的方法。

get_data:process(clk, reset)
   variable idle : boolean;
begin
   if reset = '1' then
      idle := true;
   elsif rising_edge(clk) then
      clr_flag <= '0';     -- default action
      if idle then
         if flag = '1' then
            clr_flag <= '1';  -- overrides default FOR THIS CYCLE ONLY
            idle <= false;
         end if;
      else
         if flag = '0' then
            idle := true;
         end if;
      end if;
  end if;
end process;
Run Code Online (Sandbox Code Playgroud)