以VHDL格式生成2个时钟脉冲

时间:2015-10-08 23:18:07

标签: vhdl

如何根据触发信号生成两个时钟脉冲。我在stackoverflow中找到了这个代码(效果很好):

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;

我想知道是否有人可以帮助我生成一个持续2个时钟脉冲而不是1个时钟脉冲的标志。

3 个答案:

答案 0 :(得分:0)

输入信号:reset有效低电平和trigger。输出信号:clk

如果您需要生成两个时钟脉冲并且您知道半个周期,则可以使用以下命令生成它:

process(reset, trigger)
begin

    if (reset = '0') then
        clk <= '0';
    elsif (trigger = '1') then
        clk <= '1';
        wait for half_period;
        clk <= '0';
        wait for half_period;
        clk <= '1';
        wait for half_period;
        clk <= '0';
        wait for half_period;
    else
        clk <= '0';
    end if;
end process;

复位为低电平且产生两个时钟脉冲,直到触发为1(因此,如果触发没有下降,则继续产生时钟)。

否则,如果你有一个主时钟(mclk),你可以使用它来生成半频率的派生时钟:

signal id           : std_logic_vector(1 downto 0);
signal next_id      : std_logic_vector(1 downto 0);
signal edge_trigger : std_logic;
signal trigger_c    : std_logic;

process(id, edge_trigger)
begin
    if (id = "00") then
        if (edge_trigger = '1') then
            next_id <= "01";
        else
            next_id <= "00";
        end if;
    elsif (id = "01") then
        next_id <= "10";
    elsif (id = "10") then
        next_id <= "11";
    else
        next_id <= "00";
    end if;
end process;

process(reset, mclk)
begin
    if (reset = '0') then
        id        <= "00";
        trigger_c <= '0';
    elsif (mclk'event and (mclk = '1')) then
        id        <= next_id;
        trigger_c <= trigger;
    end if;
end if;

edge_trigger <= trigger and (not trigger_c);
clk <= '1' when ((id = "01") or (id = "11"))
           else
       '0';

在这种情况下,如果trigger没有下降,则只产生2个时钟脉冲。要生成其他两个时钟脉冲,trigger必须下降(至少mclk的时钟脉冲。)

也可以合成第二种解决方案。

答案 1 :(得分:0)

我会这样做:

signal s_flag, s_flag_1z : std_logic := '0';
begin
   get_data:process(clk, reset)
      variable idle : boolean;
   begin
      if reset = '1' then
         idle      := true;
         s_flag    <= '0';
         s_flag_1z <= '0';
      elsif rising_edge(clk) then
         s_flag    <= '0';     -- default action
         s_flag_1z <= s_flag;
         if idle then
            if flag = '1' then
               s_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;
cl_flag <= '1' when (s_flag & s_flag_1) /= "00" else '0';

现在该标志将是2个时钟周期的高电平,只需要少量添加。

/奔

答案 2 :(得分:0)

通过移位寄存器顶部的抽头,可变长度脉冲最干净,最简单

get_data:process(clk, reset) --make sure you really want asynchronous reset
  variable pulse_line : std_logic_vector(1 downto 0); --set the width to how many clocks you want the pulse
begin
  if reset = '1' then --again make sure you really want asynchronous reset
    pulse_line := (others => '1');
  elsif rising_edge(clk) then
    if flag = '1' then
      pulse_line := (others => '1'); --reset the shift register
    else
      pulse_line := pulse_line(pulse_line'high-1 downto 0) & '0'; --push a 0 onto bottom of the shift register
    end if;
    clr_flag <= pulse_line(pulse_line'high); --tap out the top of the shift register
  end if;
end process;