FPGA|CPLD|ASIC论坛
直播中

h1654155275.5916

7年用户 992经验值
私信 关注
[经验]

FPGA中for循环的理解与运用

For循环是任何HDL语言中最让人容易误解的代码之一。For循环可以以可综合与不可综合两种版本实现。不过C语言中的For循环与HDL众的For循环不太一样,要想熟练运用的话就得先理解它。


将软件编程风格的For循环代码改成HDL代码


For循环是新手硬件开发人员常常困扰的领域。您可能已经在C里运行了无数次,因此您认为它们在Verilog和VHDL中是相同的。此处要明确指明:For循环在硬件语言与软件语言中是不同的。


在可综合代码中For循环可以用来拓展复制逻辑。在你完全理解复制逻辑是如何运作之前,千万不要轻易使用for循环。以下是软件语言对HDL语言的转换。
  1. // 软件语言例程:
  2. For (int i=0; i<10; i++)
  3.    data[i] = data[i] + 1;
VHDL的等效代码
  1. P_INCREMENT : process (clock)
  2. begin
  3.   if rising_edge(clock) then
  4.     if index < 10 then
  5.       data(index) <= data(index) + 1;
  6.       index       <= index + 1;
  7.     end if;
  8.   end if;
  9. end process P_INCREMENT;
还有Verilog的版本
  1. always @(posedge clock)
  2.   begin
  3.     if (index < 10)
  4.       begin
  5.         data[index] <= data[index] + 1;
  6.         index       <= index + 1;
  7.       end
  8.   end

在可综合代码中使用For循环

For循环可以用于综合。For循环在可综合语句中的用途主要是扩展复制逻辑。以下是两个语言的代码与仿真

VHDL
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;

  4. entity Example_For_Loop is
  5.   port (
  6.     i_Clock : std_logic
  7.     );
  8. end Example_For_Loop;

  9. architecture behave of Example_For_Loop is

  10.   signal r_Shift_With_For : std_logic_vector(3 downto 0) := X"1";
  11.   signal r_Shift_Regular  : std_logic_vector(3 downto 0) := X"1";
  12.    
  13. begin

  14.   p_Shift_With_For : process (i_Clock)
  15.   begin
  16.     if rising_edge(i_Clock) then
  17.       for ii in 0 to 2 loop
  18.         r_Shift_With_For(ii+1) <= r_Shift_With_For(ii);
  19.       end loop;  -- ii
  20.     end if;
  21.   end process;

  22.   p_Shift_Without_For : process (i_Clock)
  23.   begin
  24.     if rising_edge(i_Clock) then
  25.       r_Shift_Regular(1) <= r_Shift_Regular(0);
  26.       r_Shift_Regular(2) <= r_Shift_Regular(1);
  27.       r_Shift_Regular(3) <= r_Shift_Regular(2);
  28.     end if;
  29.   end process;
  30.    
  31.    
  32. end behave;
Verilog
  1. module for_loop_synthesis (i_Clock);     
  2.   input i_Clock;
  3.   integer ii=0;
  4.   reg [3:0] r_Shift_With_For = 4'h1;
  5.   reg [3:0] r_Shift_Regular  = 4'h1;

  6.   always @(posedge i_Clock)
  7.     begin
  8.       for(ii=0; ii<3; ii=ii+1)
  9.         r_Shift_With_For[ii+1] <= r_Shift_With_For[ii];
  10.     end

  11.   always @(posedge i_Clock)
  12.     begin
  13.       r_Shift_Regular[1] <= r_Shift_Regular[0];
  14.       r_Shift_Regular[2] <= r_Shift_Regular[1];
  15.       r_Shift_Regular[3] <= r_Shift_Regular[2];
  16.     end   
  17. endmodule   


  18. module for_loop_synthesis_tb ();    // Testbench
  19.   reg r_Clock = 1'b0;
  20.   for_loop_synthesis UUT (.i_Clock(r_Clock));
  21.   always
  22.     #10 r_Clock = !r_Clock;
  23. endmodule
仿真结果
1.png

回帖(1)

徐思龙

2019-8-7 08:14:56
不错,很好的经验分享,辛苦麻烦了,欠缺这方面的资料,非常感谢
举报

更多回帖

发帖
×
20
完善资料,
赚取积分