VHDL 时钟或触发升频器延迟
VHDL Clock or Trigger Upscaler Delay
我正在 FPGA 上开发控制算法,但我不能声称对 VHDL 有经验。我需要的一个功能是一种 'Trigger Upscaler',所以我想增加触发频率而不是降低它。
这里有一个解释:
我得到一个 50 MHz 的系统时钟,并得到一个 1 个时钟周期的触发脉冲,频率为 1 kHz,因此每毫秒一个。这个触发器是某些微积分的开始,它必须 运行 比那更快。所以我想知道我是否可以生成一个 10 kHz 的新触发器。这是我到目前为止的基本代码:
calc_prescaler: process
begin
wait until rising_edge(clk);
-- When a new trig appears, send 1 tick and reset counters
if trig_in = '1' then
cnt_clk <= (others => '0');
cnt_active <= '1';
trig_out <= '1';
trig_count <= (others => '0');
else
trig_out <= '0';
-- Safety feature: Do not send more ticks than estimated
-- Useful in case trig_in freezes
if trig_count > par_max - 1 then
cnt_active <= '0';
trig_count <= (others => '0');
end if;
if cnt_active = '1' then
cnt_clk <= cnt_clk + 1;
end if;
-- If Counter reaches desired values, send 1 tick and increase tick counter
if cnt_clk = par_fac - 1 then
trig_count <= trig_count + 1;
trig_out <= '1';
cnt_clk <= (others => '0');
end if;
end if;
-- Reset
if res_n = '0' then
trig_out <= '0';
cnt_clk <= (others => '0');
trig_count <= (others => '0');
cnt_active <= '0';
end if;
有两个变量,par_fac 是所需(更高)触发频率与系统时钟之间的比率,par_max 是 trig_out 上的刻度数,如果没有新 trig_in。
到目前为止对我有用,但问题是两个触发器不同步,有 1 个时钟周期的延迟。
您对如何修改我的方法有什么建议吗?欢迎任何实施方式,我唯一的要求是:
- trig_in 和 trig_out 之间没有延迟
- 如果 trig_in ticks 停止
,则没有 trig_out ticks
在任何时序逻辑中,输出总是相对于输入延迟一个时钟周期。这意味着您无法为进程内的每个触发器输入生成第一个报价单。
if trig_in = '1' then
cnt_clk <= (others => '0');
cnt_active <= '1';
--trig_out <= '1'; don't do this
trig_count <= (others => '0');
对于剩余的滴答,只需使用较低的计数器值提前一个时钟周期生成它们:
if cnt_clk = par_fac - 1 then
trig_count <= trig_count + 1;
--trig_out <= '1'; don't do this
cnt_clk <= (others => '0');
end if;
-- instead:
if cnt_clk = par_fac - 2 then
trig_out <= '1';
end if;
然后,在流程之外,您以前使用 trig_out
的任何地方现在都使用 trig_in or trig_out
。
我正在 FPGA 上开发控制算法,但我不能声称对 VHDL 有经验。我需要的一个功能是一种 'Trigger Upscaler',所以我想增加触发频率而不是降低它。
这里有一个解释:
calc_prescaler: process
begin
wait until rising_edge(clk);
-- When a new trig appears, send 1 tick and reset counters
if trig_in = '1' then
cnt_clk <= (others => '0');
cnt_active <= '1';
trig_out <= '1';
trig_count <= (others => '0');
else
trig_out <= '0';
-- Safety feature: Do not send more ticks than estimated
-- Useful in case trig_in freezes
if trig_count > par_max - 1 then
cnt_active <= '0';
trig_count <= (others => '0');
end if;
if cnt_active = '1' then
cnt_clk <= cnt_clk + 1;
end if;
-- If Counter reaches desired values, send 1 tick and increase tick counter
if cnt_clk = par_fac - 1 then
trig_count <= trig_count + 1;
trig_out <= '1';
cnt_clk <= (others => '0');
end if;
end if;
-- Reset
if res_n = '0' then
trig_out <= '0';
cnt_clk <= (others => '0');
trig_count <= (others => '0');
cnt_active <= '0';
end if;
有两个变量,par_fac 是所需(更高)触发频率与系统时钟之间的比率,par_max 是 trig_out 上的刻度数,如果没有新 trig_in。
到目前为止对我有用,但问题是两个触发器不同步,有 1 个时钟周期的延迟。
您对如何修改我的方法有什么建议吗?欢迎任何实施方式,我唯一的要求是: - trig_in 和 trig_out 之间没有延迟 - 如果 trig_in ticks 停止
,则没有 trig_out ticks在任何时序逻辑中,输出总是相对于输入延迟一个时钟周期。这意味着您无法为进程内的每个触发器输入生成第一个报价单。
if trig_in = '1' then
cnt_clk <= (others => '0');
cnt_active <= '1';
--trig_out <= '1'; don't do this
trig_count <= (others => '0');
对于剩余的滴答,只需使用较低的计数器值提前一个时钟周期生成它们:
if cnt_clk = par_fac - 1 then
trig_count <= trig_count + 1;
--trig_out <= '1'; don't do this
cnt_clk <= (others => '0');
end if;
-- instead:
if cnt_clk = par_fac - 2 then
trig_out <= '1';
end if;
然后,在流程之外,您以前使用 trig_out
的任何地方现在都使用 trig_in or trig_out
。