在 VHDL 中序列化代码
Serializing code in VHDL
我正在尝试使用 VHDL 在 Spartan-6 FPGA 上创建一个(非常基本的)GPU。
我遇到的最大问题是我对 HDL 的理解非常有限 - 我一直在使用嵌套 for
循环来编写代码 tracing/scanline 光栅化算法,而没有考虑这些当循环在合成中解开时,巨大的循环会消耗 >100% 的 DSP 切片。
我的问题是,如果我有一个时钟触发的计数器来代替 for
循环(使用计数器作为索引并将它的最大值重置为 0),这是否意味着所有逻辑只生成一次?我可以看到,在 600x800 屏幕上进行光线追踪,例如时钟频率为 200 MHz,整个屏幕的整体刷新率将降至 625 Hz,但理论上应该仍然足够快..?
非常感谢!
如果你实现了一个for循环,那么for循环中的功能会同时对for循环所经过的所有值执行。为实现这一点,综合工具必须为 for 循环中的每个值实现一次功能,因此您仍将拥有大量的硬件实现。
例如,此代码将展开到并行硬件以实现功能,在这种情况下是和门,但由于 for 循环而不会在硬件中产生任何开销:
process (clk_i) is
begin
if rising_edge(clk_i) then
for idx_par in z_par_o'range loop
z_par_o(idx_par) <= a_i(idx_par) and b_i(idx_par); -- Functionality
end loop;
end if;
end process;
不同数据值的交错处理必须通过 VHDL 中的显式处理来实现,因此具有带有该值的信号,并且每次功能计算给定值的结果时对该值进行递增和换行.
此代码将为该功能制作串行硬件,但由于循环会产生硬件开销:
process (clk_i) is
begin
if rising_edge(clk_i) then
if rst_i = '1' then -- Reset
idx_ser <= 0;
else -- Operation
z_par_o(idx_ser) <= a_i(idx_ser) and b_i(idx_ser); -- Functionality
if idx_ser /= LEN - 1 then -- Not at end of range
idx_ser <= idx_ser + 1; -- Increment
else -- At end of range
idx_ser <= 0; -- Wrap
end if;
end if;
end if;
end process;
普通的 VHDL 综合工具无法展开 for 循环以随时间执行。
我正在尝试使用 VHDL 在 Spartan-6 FPGA 上创建一个(非常基本的)GPU。
我遇到的最大问题是我对 HDL 的理解非常有限 - 我一直在使用嵌套 for
循环来编写代码 tracing/scanline 光栅化算法,而没有考虑这些当循环在合成中解开时,巨大的循环会消耗 >100% 的 DSP 切片。
我的问题是,如果我有一个时钟触发的计数器来代替 for
循环(使用计数器作为索引并将它的最大值重置为 0),这是否意味着所有逻辑只生成一次?我可以看到,在 600x800 屏幕上进行光线追踪,例如时钟频率为 200 MHz,整个屏幕的整体刷新率将降至 625 Hz,但理论上应该仍然足够快..?
非常感谢!
如果你实现了一个for循环,那么for循环中的功能会同时对for循环所经过的所有值执行。为实现这一点,综合工具必须为 for 循环中的每个值实现一次功能,因此您仍将拥有大量的硬件实现。
例如,此代码将展开到并行硬件以实现功能,在这种情况下是和门,但由于 for 循环而不会在硬件中产生任何开销:
process (clk_i) is
begin
if rising_edge(clk_i) then
for idx_par in z_par_o'range loop
z_par_o(idx_par) <= a_i(idx_par) and b_i(idx_par); -- Functionality
end loop;
end if;
end process;
不同数据值的交错处理必须通过 VHDL 中的显式处理来实现,因此具有带有该值的信号,并且每次功能计算给定值的结果时对该值进行递增和换行.
此代码将为该功能制作串行硬件,但由于循环会产生硬件开销:
process (clk_i) is
begin
if rising_edge(clk_i) then
if rst_i = '1' then -- Reset
idx_ser <= 0;
else -- Operation
z_par_o(idx_ser) <= a_i(idx_ser) and b_i(idx_ser); -- Functionality
if idx_ser /= LEN - 1 then -- Not at end of range
idx_ser <= idx_ser + 1; -- Increment
else -- At end of range
idx_ser <= 0; -- Wrap
end if;
end if;
end if;
end process;
普通的 VHDL 综合工具无法展开 for 循环以随时间执行。