Есть ли лучший способ использовать для цикла? - PullRequest
0 голосов
/ 21 апреля 2019

Я пишу код для (128 бит) степени (4 бита) и делителя, чтобы найти остаток (128 бит) мощности (4 бита) и переменную (4 бита).Я использовал повторяющееся сложение, чтобы найти первую операцию, и повторяющееся вычитание, чтобы найти остаток.Я использовал для цикла, чтобы сделать то же самое.верхняя граница цикла for действительно высока для (128 бит) мощности (4 бита), и симуляция выдает ошибку.Симуляция внезапно останавливается, сообщая, что процесс завершенИ в силе модуля обнаружена фатальная ошибка (Xilinx 12.1 на windows xp).Эта ошибка появляется в xilinx 14.7 в Windows 10:

ОШИБКА: Переносимость: 3 - Это приложение Xilinx исчерпало память или обнаружило конфликт памяти.Текущее использование памяти - 3085052 кб.Вы можете попробовать увеличить физическую или виртуальную память вашей системы.Если вы используете систему Win32, вы можете увеличить объем памяти вашего приложения с 2 ГБ до 3 ГБ, используя ключ / 3G в файле 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;

Чтобы найти напоминание, верхняя граница для цикла действительно высокая.Есть ли эффективный способ решить эту проблему?Пожалуйста помоги.

1 Ответ

0 голосов
/ 29 апреля 2019

Лучший способ в вашем контексте - не использовать циклы.

Как правило, для достижения наилучшей производительности и приемлемого размера области реализации вы должны использовать реализацию состояния (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

Извините за мой английский.

...