首页 > 解决方案 > 有没有更好的使用for循环的方法?

问题描述

我正在编写(128 位)(4 位)幂的代码和一个除法器,以找到(128 位)(4 位)幂的余数和(4 位)的变量。我使用重复加法来找到第一个操作,并使用重复减法来找到余数。我用for循环来做同样的事情。对于(4 位)的(128 位)幂,for 循环的上限非常高,并且模拟给出了错误。模拟突然停止,说进程已终止。并且在模块电源中发现了一个致命错误(Windows xp 上的 Xilinx 12.1)。此错误在 windows 10 上的 xilinx 14.7 上弹出:

ERROR:Portability:3 - 此 Xilinx 应用程序内存不足或遇到内存冲突。当前内存使用量为 3085052 kb。您可以尝试增加系统的物理或虚拟内存。如果您使用的是 Win32 系统,则可以使用 boot.ini 文件中的 /3G 开关将应用程序内存从 2GB 增加到 3GB。有关这方面的更多信息,请参阅 Xilinx 答复记录 #14932。有关此问题的技术支持,请访问http://www.xilinx.com/support

模拟器以意外方式终止。有关详细信息,请查看 ISim 日志 (isim.log)。有没有什么有效的方法可以避免这个问题?请帮忙。寻找力量:

entity power is
    Port ( mes : in  STD_LOGIC_VECTOR (207 downto 0);
           d : in  STD_LOGIC_VECTOR (11 downto 0);
           outt : out  STD_LOGIC_VECTOR (2007 downto 0);
           clk : in  STD_LOGIC);
end power;

architecture Behavioral of power is
signal mes1:unsigned (207 downto 0);
signal d1:unsigned (11 downto 0);
signal mes3:unsigned (2007 downto 0);
begin
process(clk)
begin
if(clk'event and clk='1') then
mes1<=unsigned(mes);
d1<=unsigned(d);
end if;
end process;

process(clk,mes1)
variable varr:unsigned (2007 downto 0);
variable cnt,cnt1: unsigned (207 downto 0);
variable mes2: unsigned (2007 downto 0);
begin

cnt:=x"0000000000000000000000000000000000000000000000000001";
mes2:=x"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
mes2(207 downto 0):=mes1;
if(clk'event and clk='1') then
for i in 0 to 90 loop
     if(cnt<d1) then
      varr:=x"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
      cnt1:=x"0000000000000000000000000000000000000000000000000001";
           for j in 0 to 150000 loop
               if (cnt1<=mes1) then
                    varr:=varr+mes2;
                      cnt1:=cnt1+1;
                end if;
            end loop;
              mes2:=varr;
              cnt:=cnt+1;
      end if;
end loop;
mes3<=mes2;
end if;
end process;


process(clk)
begin
if(clk'event and clk='1') then
outt<=std_logic_vector(mes3);
end if;
end process;


end Behavioral;

要找到余数:

entity div22 is
    Port ( a : in  STD_LOGIC_VECTOR (2007 downto 0);
           b : in  STD_LOGIC_VECTOR (7 downto 0);
           remi : out  STD_LOGIC_VECTOR (2007 downto 0);
           clk : in  STD_LOGIC);
end div22;

architecture Behavioral of div22 is

signal q:unsigned (11 downto 0);
signal a1,r:unsigned (2007 downto 0);
signal b1:unsigned (7 downto 0);
--signal i:STD_LOGIC_VECTOR (3 downto 0);
begin

process(clk)
begin
if(clk'event and clk='1') then
a1<=unsigned(a);
b1<=unsigned(b);
end if;
end process;

process(clk,a1,b1)
variable remo1,remo2: unsigned(2007 downto 0);
begin
remo1:=a1;
if RISING_EDGE(clk) then
for i in 0 to 150000 loop
      remo2:=remo1;

     if(remo2>=b1) then
      remo1:=remo2-b1; 

      end if;
end loop;
r<=remo1;
end if;
end process;
process(clk,r)
begin
if RISING_EDGE(clk) then
remi<= std_logic_vector(r);
end if;
end process;

end Behavioral;

要找到提醒,for 循环的上限非常高。有没有什么有效的方法来解决这个问题?请帮忙。

标签: vhdlfpga

解决方案


在您的上下文中,最好的方法是不使用循环。

通常,为了获得最佳性能和可接受的实现区域大小,您应该使用状态实现 (fsm)。您应该在频率(关键路径)和完成工作所需的周期数之间取得平衡。这是我的硕士论文中“总除法的其余部分 - 余数”操作的基本实现(在 Verilog 中)。就我而言,问题是加法器太大了。所以在我的最终版本中,添加实现是并行的——我使用了一些较小的加法器来获得更好的频率。此代码是我的硕士论文的 RSA 实现的一部分。

module div(a,n,clk,reset,R, ready); // a,b,n mniejszy rozmiar
// a mod n = R
parameter size=1024; // data length

parameter
  A0 = 2'b00, // Reset.
  A1 = 2'b01, // Find  _n > _R.  
  A2 = 2'b10, // Calc.
  A3 = 2'b11; // Ready - calc done.

input [size-1:0] a,n;

input clk,reset;
output ready;
output [size-1:0] R;

reg signed [size:0] _R;
reg [size:0] _n;
reg [size-1:0] tmp_r;
reg ready; // operation is done.
reg [11:0]i;

(*safe_implementation = "yes"*)// directive for XST
(* signal_encoding = "user" *) // directive for XST

(* fsm_encoding = "user" *)    // directive for XST
reg [1:0] cs;

initial
  begin
     _R = 0;
     _n = 0;
     i = 0;
     ready = 0;
      tmp_r = 0;
      cs = A0;
  end



always @(posedge clk)
  begin
    if (reset)
       begin
          _R = a;
          _n = n;
          i = 0;
          tmp_r= a;
          ready = 0;
          cs = A0;
        end
     else
    begin
       case(cs)
          A0:
            begin
               cs = A1; 
             end
          A1:
            begin
            _n = _n << 1;
               i = i + 1;
               if ( _n > _R )
                 begin
                    _n = _n >> 1;
                _R = _R - _n;                 
                    cs = A2;
                  end
               else
                 begin
                    cs = A1;
                  end
             end
          A2:
            begin
               if (i==0)
                  begin
                    cs = A3;
                  end
                else
                  begin
                    _n = _n >> 1;
                  if (_R[size]==1'b0)
                    begin
                       tmp_r = _R;  // Save last positiv number. 
                        _R = _R - _n;
                     end
                  else
                    begin
                       _R = _R + _n;
                     end
                  i = i -1;
                  cs = A2;
               end    
             end
          A3:
            begin
               ready = 1'b1;
               cs = A3;
             end
          default:;  
        endcase
    end
  end

assign R=tmp_r;  
endmodule

div fsm

您可以在我的硕士论文中找到更多技巧来获得适用于您的上下文的更好性能和区域优化(问题是它是波兰语): https ://www.researchgate.net/publication/332752272_Realizacja_wybranych_algorytmow_kryptograficznych_w_strukturach_FPGA_Smolinski_Lukasz

对不起我的英语不好。


推荐阅读