реклама на сайте
подробности

 
 
> Как ускорить компиляцию проекта на квартусе, при этом не уронив fmax
iiv
сообщение Mar 18 2011, 20:47
Сообщение #1


вопрошающий
*****

Группа: Свой
Сообщений: 1 726
Регистрация: 24-01-11
Пользователь №: 62 436



Всем привет,

есть незадачка - мой системверилог проект очень долго компилится (2-5 часов) и не всегда его fmax бывает приемлим.

Сам проект - всего-то около 600 строк без ниоса и наворотов, используется только мегафункции памяти (M9K, M144), altpll и altmult_add.

В самом проекте есть два параметра, назову из K и M, где K - это объем кольцевого буффера памяти, M - число использующихся умножителей.

Если K примерно 70% от всей доступной памяти, M - 10% от всех доступных умножителей, fmax на основной клок получается хороший (490МГц). Компилится все около часу на хорошем i5.

Если
1) K примерно 10-20% от всей доступной памяти, M - любое, или
2) K и M примерно по 30%,
fmax получается еще приемлимый, окло 400МГц (мне не меньше надо) но компилится уже около 2-5 часов.

Если я пытаюсь задействовать почти все умножители и хотя бы 70% памяти, то обычно квартус через 1-2 часа падает со своей какой-то внутренней ошибкой или через 5-7 часов все-таки заканчивает работу, но fmax получается очень маленьким - около 300МГц.

Алгоритмически все упирается в одну простую конструкцию:
Код
...
parameter   N=42;
input                   Clk;
input       [13:0]      In[0:2];
...

reg  signed [13:0]      D[0:2][0:1];
reg  signed [13:0]      Data[0:2][0:N];
wire signed [31:0]      ScalY[0:8][0:N-1];

...

// Generating modules

generate
genvar i, j, k;
for(i=0; i<N; i+=2) begin : aaa
   for(j=0; j<3; j++) begin : bbb
     for(k=0; k<3; k++) begin : ccc
       MultOne MultOne_Module(Clk, D[j][0], D[j][1], Data[k][i], Data[k][i+1], Clk2, ScalY[j+3*k][i], ScalY[j+3*k][i+1]);
end end end
endgenerate

...


module MultOne(Clk, A1, A2, B1, B2, Clk2, Res1, Res2);
parameter SHR=18;
input Clk, Clk2;
input signed [13:0] A1, A2, B1, B2;
output reg signed [31:0] Res1, Res2;

reg signed [13:0] P1, P2, Q1, Q2;
reg signed [28:0] Sum;
reg signed [28:0] SumR0, SumR1, SumR2, SumDM0, SumDM1;
reg signed [28+SHR:0] ScalX1, ScalX2;
reg signed [31:0] Z_Res1, Z_Res2;

//   Sum<=P1*Q1+P2*Q2;
my_madd my_madd_module(Clk, P1, Q1, P2, Q2, Sum);

always @(posedge Clk)
begin
   P1<=A1;
   P2<=A2;
   Q1<=B1;
   Q2<=B2;
   SumR0<=Sum;
   SumR1<=SumR0;
   SumR2<=SumR1;
end

always @(posedge Clk2) // этот клок в два раза медленнее Clk
begin
   SumDM0<=SumR1;
   SumDM1<=SumR2;
   ScalX1<=ScalX1+SumDM0-(ScalX1>>>SHR);
   ScalX2<=ScalX2+SumDM1-(ScalX2>>>SHR);
   Z_Res1<=ScalX1[28+SHR:SHR-3];
   Z_Res2<=ScalX2[28+SHR:SHR-3];
   Res1<=Z_Res1;
   Res2<=Z_Res2;
end
endmodule


Как я понимаю, основная загвоздка у Квартуса возникает тогда, когда я пытаюсь поместить сотни дублей моего MultOne модуля (в мой кристал влазит 384) мне очень хочется вычислять при N=42, то есть когда задействовано 378 умножителей.

Теперь мой вопрос... Могу ли я как-то помочь квартусу, чтобы он стал быстрее компилировать, например, можно ли скомпилить сколько-то этих модулей и физически куда-то в кристалле разместить? Шаманил вокруг LogicLock Regions and Design Partitions Window, но, кажется так запутался, что ничего не могу поделать сам, поэтому прошу помощи у Вас!

Пожалуйста, посоветуйте, что мне сделать, чтобы увеличить fmax и не ждать по 5 часов на компиляцию этих нескольких строк кода!

ЗЫ: при компиляции в квартусе стоят все опции, которые ускоряют fmaxна основе адвизора! Если их отключать, компиляция конечно за пол часа заканчивается но и fmax даже до 200МГц не дотягивает!

Спасибо

И
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
jojo
сообщение Mar 19 2011, 21:17
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 574
Регистрация: 9-10-04
Из: FPGA-city
Пользователь №: 827



Возможно, из-за дрожания тактового сигнала данные сбиваются.

Я сейчас больше с Xilinx работаю. По памяти, вроде надо в Timequest провести анализ путей на Fmax, потом построить список путей в отчёте, потом нажать на сбойный путь и сделать Locate in Chip Planner. Там подсветятся ресурсы сбойного пути. Наверное, можно прямее сделать это же.

В том же отчёте TimeQuest можно увидеть, из чего складывается задержка. Нажмите на сбойный путь и Locate in Technology Map Viewer.

Что-то в документации должно быть на эту тему.

Надо либо законстрейнить положение, либо добавить регистры, либо перестроить сбойный путь.
Go to the top of the page
 
+Quote Post
iiv
сообщение Mar 20 2011, 14:57
Сообщение #3


вопрошающий
*****

Группа: Свой
Сообщений: 1 726
Регистрация: 24-01-11
Пользователь №: 62 436



Уважаемые друзья, Jojo, Slawikg, Bogaev_Roman и все, кто помогает мне советами!

Огромное вам за советы человеческое СПАСИБО!

С Логиклоком я сейчас разбираюсь, и начал на мелкой кошке тренироваться.

По последним Вашим замечаниям мне показалось, что я могу что-то еще не учесть.

Вдруг вас не затруднит, пробегитесь, пожалуйста по тексту моего проекта, вдруг Вы сразу заметите что-то, что я делаю криво. Буду Вам очень-очень благодарен!

Урезал проект до минимума, оставив только самый сложный кусок, который и тормозит ужастно и должен на большой частоте работать.

Код
module ...

wire [13:0]  MidData[0:2]; // приходят из еще одного модуля (выход от ФИФО на МЛАБах) и синхронизованы с Clk
wire [31:0]  CommonTimers[0:54]; // приходят из еще одного модуля (каунтеры 55 ножек), тоже синхронизованы с Clk
wire         Clk;

...

DATA_Aq DATA_Aq_module(Clk, MidData, GPIO1_D[25], GPIO1_D[24], GPIO1_D[23], GPIO1_D[29], GPIO1_D[28],
CommonTimers);

my_pll my_pll_module1(OSC1_50, Clk); // 8-ми кратный умножитель частоты, на выходе должно быть 400МГц
endmodule


module DATA_Aq(Clk, In, ClkOut, OutOn, Out, SP1, SP2, InputCounters);
parameter   N=42;
parameter   M=100;
parameter   LSSH=3;
parameter   MAXLOCBUF=(56>N*9+5)?56:N*9+5;
parameter   IMPULSEBITS=14;
parameter   IMPULSELEN=16*1024;
input                   Clk, ClkOut, OutOn, SP1, SP2;
input       [13:0]      In[0:2];
input       [31:0]      InputCounters[0:54];
output reg              Out;

// Memory ////////////////////////////

reg  signed [13:0]      D[0:2][0:1];
reg  signed [13:0]      Data[0:2][0:M-1];
wire signed [31:0]      ScalY[0:8][0:N-1];
reg  signed [31:0]      MiddleSum[0:2];
reg         [31:0]      LocBuf[0:MAXLOCBUF];
wire signed [31:0]      ShortSumY[0:8][0:N-1];

reg  signed [31+LSSH:0] LevelSumY[0:5];
reg  signed [31:0]      LevelSum[0:5], ShortSum[0:5];
reg         [5:0]       cmpres;
reg         [2:0]       cmpton;
reg                     cmpon;
reg                     InDataSW;
reg         [255:0]     OutData;
reg         [7:0]       OutDataLen;
reg [IMPULSEBITS-1:0]   PosIn, PosOut;
reg         [31:0]      OutCounter;
reg         [63:0]      CurTimer, ImpulseTime, ReadImpulseTime;
reg         [17:0]      NewStatus;
reg         [7:0]       BlockLen;
reg         [31:0]      Counters[0:54];
reg         [2:0]       MemCounter;
reg                     MemClk;

wire        [251:0]     OutDataMem;
wire        [251:0]     InDataMem;

assign InDataMem[251:238]=Data[0][M-1];
assign InDataMem[237:224]=Data[1][M-1];
assign InDataMem[223:210]=Data[2][M-1];

assign InDataMem[209:196]=Data[0][M-2];
assign InDataMem[195:182]=Data[1][M-2];
assign InDataMem[181:168]=Data[2][M-2];

assign InDataMem[167:154]=Data[0][M-3];
assign InDataMem[153:140]=Data[1][M-3];
assign InDataMem[139:126]=Data[2][M-3];

assign InDataMem[125:112]=Data[0][M-4];
assign InDataMem[111: 98]=Data[1][M-4];
assign InDataMem[ 97: 84]=Data[2][M-4];

assign InDataMem[ 83: 70]=Data[0][M-5];
assign InDataMem[ 69: 56]=Data[1][M-5];
assign InDataMem[ 55: 42]=Data[2][M-5];

assign InDataMem[ 41: 28]=Data[0][M-6];
assign InDataMem[ 27: 14]=Data[1][M-6];
assign InDataMem[ 13:  0]=Data[2][M-6];

my_lmem  my_lmem_module1(InDataMem[143:  0], PosIn, InDataSW, PosOut, ClkOut, 1, OutDataMem[143:  0]); // 16*M144
my_lmem2 my_lmem_module2(InDataMem[251:144], PosIn, InDataSW, PosOut, ClkOut, 1, OutDataMem[251:144]); // 216*M9K

// Generating modules

generate
genvar i, j, k;
for(i=0; i<N; i+=2) begin : aaa
   for(j=0; j<3; j++) begin : bbb
     for(k=0; k<3; k++) begin : ccc
       MultOne MultOne_Module(Clk, D[j][0], D[j][1], Data[k][i], Data[k][i+1], InDataSW,
                              ScalY    [j+3*k][i], ScalY    [j+3*k][i+1],
                              ShortSumY[j+3*k][i], ShortSumY[j+3*k][i+1]);
end end end
endgenerate

// Initialization of variables

initial
begin
   MemCounter=0;
   MemClk=0;
   cmpres=0;
   InDataSW=0;
   ImpulseTime=0;
   ReadImpulseTime=0;
   OutData=0;
   OutDataLen=0;
   PosIn=0;
   PosOut=0;
   NewStatus=0;
   BlockLen=0;
   CurTimer=0;
   OutCounter=0;
end

// Reading Data from Channels ///////

always @(posedge Clk) // клок на 400МГц
begin
   for(int i=0; i<2; i++)
     for(int j=0; j<3; j++)
       D[j][i]<=Data[j][i+InDataSW];
   for(int j=0; j<3; j++)
     Data[j][0]<=In[j];
   for(int i=0; i<M-1; i++)
     for(int j=0; j<3; j++)
       Data[j][i+1]<=Data[j][i];
   InDataSW<=~InDataSW;
end


always @(posedge MemClk)  // программный делитель на 3 от клока на 200МГц, то есть 66.6666МГц
begin
   CurTimer<=CurTimer+1;
   if(PosIn)
     PosIn<=PosIn+1;
   else if(ReadImpulseTime==ImpulseTime && cmpon)
   begin
     ImpulseTime<=CurTimer;
     PosIn<=PosIn+1;
     for(int i=0; i<55; i++)
       Counters[i]<=InputCounters[i];
   end
end


always @(posedge InDataSW)  // программный делитель на 2 от клока на 400МГц, то есть 200МГц
begin
   for(int i=0; i<3; i++)
   begin
     ShortSum[i*2]<=ShortSumY[i][0];
     ShortSum[i*2+1]<=ShortSumY[i][0]-ShortSumY[i][1];
     MiddleSum[i]<=MiddleSum[i]+D[i][0]+D[i][1]-(MiddleSum[i]>>>17);
   end
//
   for(int i=0; i<6; i++)
     cmpres[i]<=((ShortSum[i]>=LevelSum[i])?1:0);
   cmpton<=(cmpres==6'h3f && BlockLen!=0)?{cmpton[1:0], 1'b1}:{cmpton[1:0], 1'b0};
//
   if(MemCounter==2)
   begin
     MemCounter<=0;
     MemClk<=1;
     cmpon<=(cmpton==7)?1:0;
   end
   else
   begin
     MemCounter<=MemCounter+1;
     MemClk<=0;
   end
//
   if(cmpres==6'h3f)
   begin
     for(int i=0; i<6; i++)
     begin
       LevelSumY[i]<=LevelSumY[i]-(LevelSumY[i]>>>LSSH)+ShortSum[i];
       LevelSum[i]<=LevelSumY[i]>>>LSSH;
     end
   end
end


always @(posedge SP1)
begin
   NewStatus<={NewStatus[16:0], SP2};
   if(NewStatus[17:13]==5'b01010 && NewStatus[4:0]==5'b01010)
     BlockLen<=NewStatus[12:5];
end


always @(posedge ClkOut) // медленный клок 15МГц для сбора данных с плиски, никак не синхронизован с теми клоками, которые выше, блок написан абы как, так как при этой скорости выжимать производительность не имеет смысла
begin
   if(OutOn==0)
   begin
     begin
       {OutData[254:0], Out}<=OutData;
       if(OutDataLen>0) OutDataLen<=OutDataLen-1;
       else
       begin
////////////////////////////////
         if(OutCounter==0)
         begin
           OutDataLen<=63;
           if(ImpulseTime>ReadImpulseTime)
           begin
             OutCounter<=64-57;
             OutData<={32'h0000ffff, 32'h0000ffff};
             LocBuf[0]<=ImpulseTime[63:32];
             LocBuf[1]<=ImpulseTime[31:0];
             for(int i=0; i<55; i++)
               LocBuf[i+2]<=Counters[i];
           end
           else
           begin
             OutCounter<=512-N*9-5;
             OutData<={32'h0000ffff, 32'h0000aaaa};
             LocBuf[0]<=CurTimer[63:32];
             LocBuf[1]<=CurTimer[31:0];
             for(int i=0; i<N*9; i++)
               LocBuf[i+2]<=ScalY[i%9][i/9];
             for(int i=0; i<3; i++)
               LocBuf[i+N*9+2]<=MiddleSum[i];
           end
         end
////////////////////////////////
         else if(OutCounter==63)
         begin
           OutCounter<=512;
           OutData<=LocBuf[0];
         end
////////////////////////////////
         else if(OutCounter==511)
         begin
           OutCounter<=0;
           OutData<=LocBuf[0];
         end
////////////////////////////////
         else if(OutCounter<511)
         begin
           OutDataLen<=31;
           OutCounter<=OutCounter+1;
           OutData<=LocBuf[0];
           for(int i=1; i<MAXLOCBUF; i++)
             LocBuf[i-1]<=LocBuf[i];
         end
////////////////////////////////
         else if(OutCounter<64*BlockLen+511)
         begin
           PosOut<=PosOut+1;
           OutCounter<=OutCounter+1;
           OutDataLen<=251;
           OutData<=OutDataMem;
         end
         else
////////////////////////////////
         begin
           PosOut<=0;
           OutCounter<=0;
           OutDataLen<=251;
           OutData<=OutDataMem;
           ReadImpulseTime=ImpulseTime;
         end
       end
     end
   end
end
endmodule


module MultOne(Clk, A1, A2, B1, B2, SW, Res1, Res2, PRes1, PRes2);
parameter SHR=18;
parameter RSH=5;
input Clk, SW;
input signed [13:0] A1, A2, B1, B2;
output reg signed [31:0] Res1, Res2;
output reg signed [31:0] PRes1, PRes2;

reg signed [13:0] P1, P2, Q1, Q2;
reg signed [28:0] Sum;
reg signed [28:0] SumR0, SumR1, SumR2, SumDM0, SumDM1;

// reg signed [31:0] Mul1, Mul2;
reg signed [28+SHR:0] ScalX1, ScalX2;
reg signed [28+RSH:0] ScalZ1, ScalZ2;

reg signed [31:0] Z_Res1, Z_Res2;
reg signed [31:0] Z_PRes1, Z_PRes2;

my_madd my_madd_module(Clk, P1, Q1, P2, Q2, Sum); // мегафункция altmult_add

always @(posedge Clk) // частота 400МГц
begin
   P1<=A1;
   P2<=A2;
   Q1<=B1;
   Q2<=B2;
//   Mul1<=P1*Q1; Mul2<=P2*Q2; Sum<=Mul1+Mul2;
   SumR0<=Sum;
   SumR1<=SumR0;
   SumR2<=SumR1;
end

always @(posedge SW) // половина частоты Clk
begin
   SumDM0<=SumR1;
   SumDM1<=SumR2;
//
   ScalX1<=ScalX1+SumDM0-(ScalX1>>>SHR);
   ScalX2<=ScalX2+SumDM1-(ScalX2>>>SHR);
   Z_Res1<=ScalX1[28+SHR:SHR-3];
   Z_Res2<=ScalX2[28+SHR:SHR-3];
   Res1<=Z_Res1;
   Res2<=Z_Res2;
//
   ScalZ1<=ScalZ1+SumDM0-(ScalZ1>>>RSH);
   ScalZ2<=ScalZ2+SumDM1-(ScalZ2>>>RSH);
   Z_PRes1<=ScalZ1[28+RSH:RSH-3];
   Z_PRes2<=ScalZ2[28+RSH:RSH-3];
   PRes1<=Z_PRes1;
   PRes2<=Z_PRes2;
end
endmodule


а констрейны написаны в файле так:

Код
set_time_format -unit ns -decimal_places 3

#**************************************************************
# Create Clock
#**************************************************************

derive_clocks -period "1.0"
create_clock -name {GPIO1_D[29]} -period 1000. -waveform {0.0 500.} [get_ports {GPIO1_D[29]}]
create_clock -name {GPIO1_D[25]} -period 60. -waveform {0.0 30.} [get_ports {GPIO1_D[25]}]

########################

create_clock "DATA_Aq:DATA_Aq_module|InDataSW" -name {DATA_Aq:DATA_Aq_module|InDataSW} -period 4.8 -waveform {0.0 2.4}
create_clock "DATA_Aq:DATA_Aq_module|MemClk" -name {DATA_Aq:DATA_Aq_module|MemClk} -period 28.8 -waveform {0.0 14.4}

########################

derive_pll_clocks

#**************************************************************
# Create Clock
#**************************************************************

create_clock "OSC2_50" -name "CLK" -period 20

#**************************************************************
# Create Generated Clock
#**************************************************************

create_generated_clock -master_clock 20. -source "OSC1_50" -name "CLK_OUT" -multiply_by 8 -divide_by 1
create_generated_clock -master_clock 20. -source "OSC1_50" -name "Clk" -multiply_by 8 -divide_by 1 [get_ports {my_pll_module1|altpll_component|auto_generated|pll1|clk[0]}]



Спасибо!

ЗЫ несколько редактирований этого сообщения были вызваны глюком при набивке сообщения и желанием откоментарить текст для удобства восприятия

Сообщение отредактировал iiv - Mar 20 2011, 15:26
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- iiv   Как ускорить компиляцию проекта на квартусе   Mar 18 2011, 20:47
- - Shtirlits   Ключевое слово верное - logic lock. С квартусом л...   Mar 18 2011, 21:26
- - des00   помочь можно только в том случае, если будет видно...   Mar 19 2011, 03:56
|- - iiv   Цитата(des00 @ Mar 19 2011, 07:56) помочь...   Mar 19 2011, 09:12
|- - jojo   Цитата(iiv @ Mar 19 2011, 12:12) Основная...   Mar 19 2011, 10:49
|- - iiv   Цитата(jojo @ Mar 19 2011, 14:49) Для пол...   Mar 19 2011, 11:11
- - Shtirlits   Logic lock не такой уж и сложный механизм! Поп...   Mar 19 2011, 11:20
- - jojo   Да, и частоту в констрейнах можно уменьшить, чтобы...   Mar 19 2011, 13:05
|- - iiv   Благодарю Вас за ответы и советы! Цитата(jojo...   Mar 19 2011, 14:21
|- - jojo   Цитата(iiv @ Mar 19 2011, 17:21) Будьте л...   Mar 19 2011, 15:33
|- - iiv   Уважаемый jojo, очень Вам благодарен за классные ...   Mar 19 2011, 19:47
|- - bogaev_roman   Цитата(iiv @ Mar 19 2011, 22:47) Если Fan...   Mar 20 2011, 10:50
|- - bogaev_roman   Цитата(iiv @ Mar 19 2011, 22:47) По спидг...   Mar 20 2011, 14:28
- - slawikg   ЦитатаПо спидгрейдам кристалла, умножители могут р...   Mar 20 2011, 14:17
- - bogaev_roman   Было бы гораздо удобней разбираться, если б Вы при...   Mar 20 2011, 15:48
|- - iiv   Уважаемый Роман, огромное спасибо Вам за советы и...   Mar 20 2011, 16:14
- - bogaev_roman   По поводу правильного использования timequest для ...   Mar 21 2011, 09:49
|- - iiv   Добрый день, Роман, огромное Вам спасибо за совет...   Apr 3 2011, 11:15
- - bogaev_roman   Цитататри клока генерятся одним ПЛЛ и имеют четко ...   Apr 4 2011, 14:59


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th July 2025 - 11:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.01456 секунд с 7
ELECTRONIX ©2004-2016