|
Как ускорить компиляцию проекта на квартусе, при этом не уронив fmax |
|
|
|
Mar 18 2011, 20:47
|
вопрошающий
    
Группа: Свой
Сообщений: 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МГц не дотягивает! Спасибо И
|
|
|
|
|
 |
Ответов
|
Mar 20 2011, 14:57
|
вопрошающий
    
Группа: Свой
Сообщений: 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
|
|
|
|
Сообщений в этой теме
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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|