#vhdl #fpga
#vhdl #fpga
Вопрос:
Я пишу код для (128 бит) степени (4 бита) и делителя, чтобы найти остаток (128 бит) степени (4 бита) и переменную (4 бита). Я использовал повторяющееся сложение, чтобы найти первую операцию, и повторяющееся вычитание, чтобы найти остаток. Я использовал цикл for для того же. верхняя граница цикла 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;
Чтобы найти напоминание, верхняя граница для цикла for действительно высока. Есть ли какой-либо эффективный способ решить эту проблему? Пожалуйста, помогите.
Комментарии:
1. Какую ошибку он выдает? Какую проблему вы пытаетесь решить? Вы обнаружите, что ваш вопрос закрыт, если вы не будете более конкретны.
2. @EML Ошибка не указана. Он просто говорит о какой-то фатальной ошибке при включении, когда я увеличиваю верхнюю границу цикла
3. Вероятно, вы используете массивные массивы. Вы пробовали использовать 64-битную систему с большим объемом оперативной памяти? Кроме того, этот код не будет синтезироваться. Ограничение цикла итерации для синтеза обычно равно 10000, и даже тогда использование ресурсов для этого кода, вероятно, будет больше, чем у любой fpga, плюс максимальная тактовая частота будет очень низкой. Я рекомендую спроектировать схему на бумаге перед написанием кода. Перевод c в vhdl для синтеза всегда будет давать плохие результаты.
4. Я думаю, что нам, опытным разработчикам HDL, интересно, что вы пытаетесь сделать. Почему вы используете HDL для написания кода, который никогда не поместится в FPGA или даже ASIC. Это заставляет меня думать, что у вас проблема с X-Y. Итак, в чем проблема / алгоритм, который вы пытаетесь решить. Потому что я подозреваю, что это не то решение, которое вы ищете.
5. Хорошо, теперь мы к чему-то пришли. Ваш вопрос относится к категории «Как мне реализовать X». К сожалению, в этом случае нет быстрого и простого ответа . По сути, вам нужно полностью переписать код, разделив его на этапы, которые решаются в последовательных циклах, балансируя параллельные и последовательные операции, которые оптимально используют доступную тактовую частоту. Потребовалось бы много месяцев обучения, чтобы научить вас писать эффективный HDL для этого. Я предлагаю начать просмотр кода HDL на www, который выполняет аналогичные алгоритмы.
Ответ №1:
Лучший способ в вашем контексте — не использовать циклы.
Как правило, для достижения наилучшей производительности и приемлемого размера области реализации вам следует использовать реализацию состояния (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
В моей магистерской диссертации вы можете найти больше приемов для повышения производительности и оптимизации области, применимых к вашему контексту (проблема в том, что он на польском языке):
https://www.researchgate.net/publication/332752272_Realizacja_wybranych_algorytmow_kryptograficznych_w_strukturach_FPGA_Smolinski_Lukasz
Извините за мой английский.