有没有更好的方法来使用for循环?

时间:2019-04-21 05:55:56

标签: vhdl fpga

我正在编写一个代码(128位)的幂(4位)和一个除法器,以查找(128位)次幂(4位)和变量(4位)的余数。我使用重复加法找到第一个运算,然后使用重复减法找到余数。我用循环来做同样的事情。对于(128位)的(4位)幂,for循环的上限确实很高,并且仿真给出了错误。仿真突然停止,说明该过程已终止。并且在模块电源(Windows XP上的Xilinx 12.1)中发现了致命错误。 在Windows 10的xilinx 14.7上弹出此错误:

  

错误:可移植性:3-此Xilinx应用程序的内存不足或   遇到内存冲突。当前的内存使用情况是3085052   kb。您可以尝试增加系统的物理或虚拟   记忆。如果您使用的是Win32系统,则可以增加   使用/ 3G开关将应用程序内存从2GB扩展到3GB   boot.ini文件。有关更多信息,请参考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循环的上限确实很高。有什么有效的方法可以解决这个问题?请帮忙。

1 个答案:

答案 0 :(得分:0)

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

通常,为了获得最佳性能和可接受的实现区域大小,应使用状态实现(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

对不起,我的英语。