如何根据触发信号生成两个时钟脉冲。我在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个时钟脉冲的标志。
答案 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;