Jump to content

    

iiv

Свой
  • Content Count

    2279
  • Joined

  • Last visited

Everything posted by iiv


  1. Вот представьте, что Вы хотите сказать то, о чем мы все подумали и у Вас получается или "типс" (то есть чаевые по-английски) или "тераипс" (при произношении "и" однозначно превратится в "е", а то и "ё"). Согласитесь, и то и другое очень не созвучно и на русском, и на английском языках. Так как в русском языке два корня в словах обычно объединяются гласной "о" из-за того, что эти корни оканчиваются на согласные, а, в нашем случае, имеет место полностью противоположная ситуация, вводим новое правило объединения корней русских заимствованных слов и используем красивую по звучанию буковку "м" получая терамипс! А Вам не наравится?
  2. Позвольте с Вами не согласиться, FPGA->x86_6->GPU Нормальный 5970 радеон за штуку бакс дает пиковых 1.1терафлопс на дабле, 600 терафлопс на дабле на тестовых и 400 на реальных получается. Итого 1 гигафлоп за бакс в пике и 0.4 гигафлопа за бакс в реале на дабле, причем это уже со стоимостью всего обвеса. Я конечно смог однажды на третьем стратиксе так отконвертить алгоритм, что его аналог на целочисленной арифметике функционировал с 900гфлопс эквивалентной производительности, но 150 стратикс все-таки не совсем дешев, итого те же 0.4гигафлопа за бакс, причем здесь только можно сказать об эквивалентных гигафлопах - в алгоритме умножение одно было отскалировано на сдвиг, все операции в целых числах, но именно этот алгоритм на ГПУ не через даблы был не реализуем. А если даблы на плиски честные делать, то, исходя из сегодняшних цен, если и 0.05гигафлопа за бакс получится, то сильно здорого. Если взять средний четырехядерный АМДшник, который стоит около 100 бакс, и на нем реально получить 20 гигафлопс на дабле ну совсем не напрягаясь (0.2гигафлопа на бакс), ИМХО, плискам пока только удел в интерфейсах, и энергоэкономных, переносимых, военных отраслях числа перемалывать. ЗЫ Что-то я задумался о своем, и не заметил, что топикстартер только о целочисленных операциях вопрошал. Почти все мною вышесказанное, переноситься из дабла и на целочисленные операции. На том же радеоне в целочисленной арифметике я терамипс на реальной задаче получал, а его пик, сложно подумать, 5.5терамипсов.
  3. Не, внутри плиски частоту тригером ронял, и вместо 8 бит по двум фронтам на 200МГц получал 32 бита по одному фронту на 100МГц. Дальше все уже было очень просто, правда у С25 циклона совсем впритык было умножителей, но, как-то удалось втиснуться.
  4. На очень схожей задаче - циклон3, 16бит 200МГц АЦП у меня все получалось только после деления частоты в два раза, через распараллеливание данных. Вход был по лвдсам и по обоим фронтам. На самой 200МГц частоте что-то разумное собрать не получилось, хотя тесты (какие-то простые арифметические операции) на 200МГц этот циклон тянул.
  5. Добрый день, Роман, огромное Вам спасибо за советы и ссылки про таймквест и логиклок - сильно помогло. Поставил все клоки через ПЛЛ, стало проще и нагляднее. Есть один момент, даже не знаю как правильно объяснить, помогите, пожалуйста, советом, как правильно. Основной клок у меня 400МГц, я его получаю из ПЛЛ на основе входной 50МГц частоты. Если у меня получаются фмакс(85С)=390-410, фмакс(0С)=400-420, то на практике имеются ошибки. Похоже где-то у меня не устойчиво частота получается. Я для этого хочу в ПЛЛ указать частоту 400МГц, а Квартус заставить компилиться на 420МГц. Этим вызвано то, что я указывал большие частоты в SDC файле. Скажите, пожалуйста, есть ли какой-то более правильный подход? И еще сразу вопрос... Читал про таймквест, но, до конца не понял, вдруг не сложно будет, посоветуйте, пожалуйста. Сейчас у меня есть 15 клоков. Все кроме 3-х из них - это асинхронные вводы-выводы, данные между которыми ходят через FIFO. Правильно ли я понимаю, что для всех этих клоков я должен написать в SDC такую инструкцию: set_clock_groups -exclusive -group {GPIO1_D[29]} А вот три клока генерятся одним ПЛЛ и имеют четко прописанные частоты 400МГц, 200МГц и 66.(6)МГц и данные между этими домейнами постоянно гуляют туда и обратно. Правильно ли я понимаю, что их как раз ни как не надо описывать? Спасибо И
  6. Уважаемый Роман, огромное спасибо Вам за советы и помощь! Косяк с MiddleSum - действительно мой косяк, правда который совсем, как оказалось, не влияет на получаемый результат, приходящий сигнал имеет постоянное значение, и это кривое усреднение не сказывается на получаемом результате. Уже придумал как переписать это все правильно и для работы с одним клоком. У меня к Вам два вопроса, я, к сожалению, не все до конца с понимаю с Квартусом и с терминологией, помогите, пожалуйста: Вот Timequest timing analyzer я в репорте имею, а вот где в нем можно найти этот report top failing paths, тыкните, пожалуйста, моим носом в точное место и простите великодушно за такой мой глупый вопрос! Правильно ли я понимаю, что если я буду использовать разрешающие сигналы на тригеррах, то этот кусок кода все еще должен констрейниться на высокой частоте. То есть если есть конструкция always @(posedge CLK) //здесь основная чатсота 400МГц if (InDataSW) //здесь разрешающий вход для триггеров begin .... // вот здесь могу ли я выполнять операции, которые длятся 5нс (200МГц) или все-таки только 2.5нс? end Если так, то мне подойдет решение только на ПЛЛ... Спасибо, и простите за глупые вопросы, я, пока еще только разбираюсь! Вот тут запутался в Вашем ответе, пожалуйста, помогите! Мне нужен один клок Clk для умножителей 400МГц и половинный клок InDataSW (200МГц) для сумм. Я не могу понять, что же я не правильно сделал: PS2/ Частота clk - 400МГц (период 2,5ns), по коду InDataSW получается в два раза меньше Цитата always @(posedge Clk) InDataSW<=~InDataSW, а в ограничениях Цитата InDataSW" -name {DATA_Aq:DATA_Aq_module|InDataSW} -period 4.8 -waveform {0.0 2.4} разве я не законстрейнил InDataSW на частоту 1000/4.8=208MHz? ЗЫ с одним вопросом про разрешающие сигналы - разобрался, поэтому поправил свой ответ
  7. Уважаемые друзья, 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]}] Спасибо! ЗЫ несколько редактирований этого сообщения были вызваны глюком при набивке сообщения и желанием откоментарить текст для удобства восприятия
  8. Уважаемый jojo, очень Вам благодарен за классные советы и разъяснения. Я, к сожалению, новичек в квартусе (только один год опыта) и, некоторые вещи пока еще не знаю. вот как это сделать, не понимаю. Допустим у меня есть собранный проект. ; Logic utilization ; 50 % ; ; Combinational ALUTs ; 23,937 / 113,600 ( 21 % ) ; ; Memory ALUTs ; 84 / 56,800 ( < 1 % ) ; ; Dedicated logic registers ; 60,800 / 113,600 ( 54 % ) ; ; Total registers ; 60800 ; ; Total block memory bits ; 4,131,624 / 5,630,976 ( 73 % ) ; ; DSP block 18-bit elements ; 210 / 384 ( 55 % ) ; Это последний из максимальных, который у меня собирается, но его fmax=398MHz (85С) и 420МГц (0С), то есть чуть-чуть меньше, чем надо. Я кстати заметил, что хоть кристалл и до 60С разогревается во время работы, но данные бывают битые, если fmax меньше 420МГц, хотя у меня клок системы через плл из плиски задается и составляет ровно 400МГц. Возможно где-то нестабильность имеется, ну да ладно, главное я знаю на какую частоту мне все затачивать. По спидгрейдам кристалла, умножители могут работать до 490МГц, все остальное - совсем простое - суммы примерно 40 битных чисел, работающие на полуклоке, то есть на 200МГц от основного клока. Вот получил я Technology Map Viewver на 615 страницах :) или Resource Property Editor с огромным числом информации, большая часть которой мне не понятна, или получил картинку от Chip Planner, красивая конечно, но что мне с ней делать, можно по разному ее покрасить, но путей там не видно... Если FanIn кнопку нажимаю, получается сначала какое-то мессиво, а потом квартус зависает с полной загрузкой компьютера. Это здесь именно я должен был увидеть картинку сбойных путей, подскажите, мне, если Вас не затруднит, пожалуйтса! ЗЫ: вроде и компьютер не совсем тормознутый, 2*2.2ГГц с 8 ГБ оперативки. Спасибо И
  9. Благодарю Вас за ответы и советы! и так по минимуму :) Будьте любезны, разъясните, пожалуйста, как это делается. Вот получил я, например, fmax=330MHz вместо ожидаемых 400МГц. И как я это исправлю, куда смотреть? Спасибо
  10. один в один как у меня было, пока я в проект памяти не напихал, а сейчас и это не помогает.
  11. С Вашим советом я полностью согласен, но, и модуль два умножения плюс сложение - это системная процедура altmult_add, и на входе по два регистра, и на выходе по два... Проверял - больше двух - уже не помогает. Это я уже прошел. Иначе 490МГц я бы не получал!!! И даже если у меня только умножительный модуль, но забитый под 70-80%, то я тоже получаю необходимые мне 400МГц, и ОТДЕЛЬНО, модуль с памятью, тоже нормально работает. Кстати, у меня память работает только на 1/6 от основного клока, то есть мне достаточно клока в 66МГц на запись, а на чтение и того меньше - всего-то 15МГц. Основная проблема возникает только при объединении двух модулей - такое чувство, что квартус не в сосотянии решить такую сложную задачу по размещению - фиттер висит по 5 часов а иногда падает с системной ошибкой. Как Вы думаете, на что еще кроме логик лок стоит обратить внимание (я уже начал разбираться с логик лок, но пока не помогает...) Спасибо И Спасибо Вам большое, разбираюсь в этом направлении, надеюсь поможет!
  12. Всем привет, есть незадачка - мой системверилог проект очень долго компилится (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МГц не дотягивает! Спасибо И
  13. Добрый день, Андрей! очень Вам благодарен за ответ! Мне этот путь как-то более понятен! Именно это у меня уже есть для 10МБитного интерфейса, и, тьфу-тьфу, функционирует! повидимому мне это и надо было справивать в первом моем топике! В доках про RGMII слова есть :) Я правильно понимаю, что вот например такой документ http://www.hp.com/rnd/pdfs/RGMIIv2_0_final_hp.pdf должен решить мою задачу? Спасибо!
  14. Добрый день, Вадим, благодарю Вас за ответ. Я сам бы очень не против влится в стройные ряды ниосопользователей, но, пока есть только негативный опыт, поэтому, пожалуйста, тыкните пальцем что я делал не так: 1. демо примеры Терасика на ниосе на схожей борде (работа с ДДР2 памятью) отожрали почти 50тыс лютов, что, как мне кажется, очень много, мне критично, чтобы весь интерфейс (ниос+етернет) не отожрал бы больше 5К лютов и не более 10 умножителей и не более 5-10 к9м блоков памяти. Если будет больше, то, скорей всего, у меня поплывут констрейны в самом проекте (он на 200 мгц клоке, поэтому маленькое его ухудшение приводит к падению допустимой частоты). 2. можно ли как-то организовать все так, что кроме стоимости борды я не заплачу ничего за ИП корки, то есть если такой ниос, который бы и бесплатный был бы, и 1ГБит етернет бы поддерживал, или это сказки? Если сказки, то сколько надо еще вбить в бюджет денег? 2. с чего начать... Есть ли, например, пример перекачивания небольших 1-10КБайт массивов на фиксированный мак номер из плиски через ниос через гигабитный етернет, а именно для этой борды? Если да, где это для начинающих можно было бы посмотреть. Пожалуйста, посоветуйте! Спасибо ИИВ
  15. Всем привет, Пожалуйста, посоветуйте, как мне правильнее подступиться к моей незадаче. Коротко о моей задаче: На плиске непрерывно получаются данные (около 50МБайт в секунду), которые я хочу посредством 1ГБитного етернета посылать на компьютер. На компьютере стоит линукс, команду tcpdump уже изучил. С самого компьютера мне надо изредка посылать на плиску некоторые управляющие команды (около 1000 раз в секунду по несколько байт). По задаче хватает жирной плиски типа 4-того циклона с 200 умножителями и более. Опыт программирования альтеровских плисок - имеется, но только на уровне чистого верилога и системверилога. Сам алгоритм для плиски уже есть, на схожей борде я его уже запускал, работает, проблема в выборе борды и программировании быстрого интерфейса с компьютером. Есть желание для этого проекта купить такую борду: http://www.terasic.com.tw/cgi-bin/page/arc...=139&No=502 так как и цена низкая, и в этот циклон все влезает, и два коннектора на гигабит имеются. Скачал я с терасика конфигурационные файлы для борды, засунул туда свой проект, все компилится, но не знаю как мне данные качать по этому гигабитному етернету. Во входе главного модуля етернет выглядит для меня так: //////////// Ethernet 0 ////////// output ENET0_GTX_CLK; input ENET0_INT_N; input ENET0_LINK100; output ENET0_MDC; inout ENET0_MDIO; output ENET0_RST_N; input ENET0_RX_CLK; input ENET0_RX_COL; input ENET0_RX_CRS; input [3:0] ENET0_RX_DATA; input ENET0_RX_DV; input ENET0_RX_ER; input ENET0_TX_CLK; output [3:0] ENET0_TX_DATA; output ENET0_TX_EN; output ENET0_TX_ER; input ENETCLK_25; и точно такое же на второй етернет коннектор. От того что я в мегавизарде сгенерил PHY и получил около сотни входов и выходов, как Вы догадываетесь, мне тоже легче не стало. У меня сейчас получается несколько альтернатив: 1) освоить ниос (ни разу не пользовал и так до сих пор не понимаю как оно функционгирует хотя и пытался как-то разобраться), прикрутить через него и авалон то, что мне надо, возможно потом платить за всякие мегакорки дополнительные деньги, 2) разобраться с тем, что есть, и заслать UDP пакет, его устройство я немного представляю, по крайней мере я повторял то, что описано в http://www.fpga4fun.com/10BASE-T0.html и на 10 мбит у меня все работало. Посоветуйте, пожалуйста, самый простой и короткий путь для освоения такого гигибитного етернета! ЗЫ: если я в чем-то глообально прокололся, тыкните носом, я еще эту борду не заказал, еще есть время переиграть! Спасибо ИИВ
  16. Уважаемы Метан, благодарю Вас за ту помощь, которую Вы оказываете мне для того, чтобы разобраться с моей задачей! ////////// USB ////////// output [17:1] OTG_A; output OTG_CS_n; inout [31:0] OTG_D; output OTG_DC_DACK; input OTG_DC_DREQ; input OTG_DC_IRQ; output OTG_HC_DACK; input OTG_HC_DREQ; input OTG_HC_IRQ; output OTG_OE_n; output OTG_V1ET_n; output OTG_WE_n; мне, к сожалению, эта информация ни о чем не говорит, и, очень надеюсь, что Вам она действительно поможет быстро объяснить мне что же делать. Читая мануалы к Квартусу и смотря примеры к борде, я нашел, что ниос как-то сам хорошо эти ноги использует, и, если ниосу залубенить на авалон что-то, и как-то правильно его об этом предупредить, то он пошлет эти данные в OTG, а тот, в сою очередь, по усб протоколу на линукс компьютер. Я, к сожалению, совсем пока не понимаю как это все происходит, поэтому очень интенсивно гуглю и читаю мануалы. Простите меня, я не понял что Вы сказали. Мои подключения, а, также, как я читать данные из /dev/ttyUSB0 буду, я уже описывал. очень надеюсь, что здесь я смог Вас правильно понять, подразумевая, что Вы меня спросили про скорость. Как я говорил, мне хотелось бы иметь скорость качания данных с плиски на линукс около 40МБайт в секунду. Используя СПИ я уже смог получить 1.2МБайт в секунду (это уже чистой скорости на моих даннных), но мне, к сожалению, не хватает. Наверное и 100МБайт в секунду - было бы хорошо, но я даже боюсь задумываться через какой интерфейс это вообще принципиально возможно. Спасибо
  17. Действительно, с терминами не дружу, я конечно имел ввиду хай спид :( Уважаемый Метан, благодарю Вас за отзыв. Действительно, я не совсем разбираюсь в терминах, поэтому наверное Вы меня не поняли. Задача у меня простая, я примерно описал: есть плиска - стратикс 3, несколько ног которых воткнуты в USB-OTG. Далее подключение USB воткнуто в линукс компьютер. Моя задача - качать большые массивы данных с плиски на компьютер с максимально большой скоростью, и получать от компьютера в плиску управляющую информацию, которой примерно на 5-6 порядков меньше. Вот думаю как это реализовать, в верилоге вроде чуток разбираюсь, особенно когда мне здесь советуют :)))) а вот про ниос только слышал и несколько примеров запустил, правда не совсем еще разобрался как эти примеры работают. Вот и думаю как мне решить поставленную задачу. За любой конструктивный совет, в том числе совет как мне правильно сформулировать вышеописанную задачу, буду примного благодарен. Спасибо Иван
  18. Доброй ночи, есть у меня USB-OTG фулл спид, который одим концом воткнут в плиску, а другим - в линукс компьютер. На последнем, я, повидимому его могу открыть чем-то типа open (из С) из соответствующего /dev/ttyUSB0. Хочу понять какой интерфейс мне надо реализовать на ниосе, чтобы я смог из авалоновской шины или локального фифо таскать по USB-OTG данные на мой линукс компьютер. Интересует максимально быстрый интерфейс. Реально ли при пике 480МБитс получить хотя бы 40МБайтс, скажите, пожалуйста! Спасибо Иван
  19. Уважаемый Роман, огромное Вам спасибо! Ваш ответ помог мне найти баг, я забыл написать derive pll clock, вернее до Вашего ответа не знал о ее существовании!!! Кстати, в топикстарте я кажется ошибся с количеством используемых PLL - действительно, на 200, 250, 300, 350МГц используется только 2 штуки, в то время как я пробовал и еще один дизайн с 250, 300, 350, 400МГц, где их уже было больше (не 4, а 3 получается). По поводу слаков - борюсь с этим другими методами, после переключения частоты я могу почти милисекунду нечего не делать, поэтому меня это не сильно тревожит. На более низких частотах у меня схема почти в 2 раза меньше энергии потребляет, поэтому мне это очень сподручно, но, бывает, что данных много и надо включить вентилятор и пустить максимальную частоту :) Кстати у меня слаки до 30 микросекунд доходят, так как сам модуль довольно заумный. Добрый день, Евгений, большое спасибо за идею! Она также разумна для моего другого проекта, но именно в этом проекте все у меня завязанно на то, что мне надо этот клок отдавать и внешнему потребителю, а потом синхронизоваться с его ответом, а внешний потребитель скорее всего будет глючить при пропусках. Кстати, возможно таким образом, если мне не будет хватать пллек, я, например, мог бы самопально реализовать делитель, то есть работать, например, на частотах 300, 200, 150, 120, 100 МГц, имея исходную в 600МГц.
  20. Добрый день, Роман, благодярю Вас за то, что разбираетесь с моей проблемой! SW у меня входная переменная, на входе то, что на включателях борды. Работает, проверял. а как мультиплексить частоты, или это принципиально невозможно? извиняюсь, что сразу не написал, в sdc есть констрейны на все клоки и на результат мультиплексирования, везде для всех клоков одна и та же строка: create_clock -name {Clk} -period 2.400 -waveform { 0.000 1.200 } [get_ports { Clk }] может быть как-то по-другому надо было писать? квартус ругается и не дает. Кристалл Стратикс 3, второй спидгрейд. не до конца понял, сейчас буду задавать уточняющие вопросы, вдруг сможете прояснить! Добрый день, tAmega, спасибо что откликнулись и помогаете разобраться с моей проблемой! правильно ли я понимаю, что Вы предлагаете менять частоту в самом ALTPLL? Если да, то, боюсь, что не получится, так как с 50МГц я не смог получить даже два клока, не говоря уж о всвех четырех. Если я Вас не правильно понял, пожалуйста, не обижайтесь на меня, и помогите, пожалуйста, мне Вас понять! Есть еще один маленький ньюанс, возможно он поможет как-то разобраться в причинах этой незадачки. Я потестироваться с одним pll, то есть с одной частотой. Там тоже есть проблема. Пусть я написал так: module test(OSC1_50, SW, InData, ClkOut, CLK_OUT) //... input OSC1_50; // входной клок 50МHz input [13:0] InData[0:3]; input ClkOut; output Res; output CLK_OUT; // сюда мне также надо выдать этот клок //... wire Clk; DATA_Aq DATA_Aq_module(Clk, InData, ClkOut, Res); my_pll4 my_pll_module4(OSC1_50, Clk300); // с помощью ALTPLL я здесь получаю необходимые клоки assign Clk=Clk300; assign CLK_OUT=Clk300; endmodule то на выходе с борды по осциллографу все в порядке, а вот на вход модуля DATA_Aq клок не передается. Если я соединяю проводком CLK_OUT и EXT_CLK и присваиваю assign Clk=EXT_CLK; то модуль начинает функционировать. Но если в выходе CLK_OUT поставить разветвитель и запитать клок внешней борды и EXT_CLK, то в EXT_CLK уже клока нет, типа борда все на себя тянет. Мне критично подать тот же клок, что и внутри плиски, на внешнюю борду, так как входные данные должны быть синхронизованы. Против этого я нашел кривое, но рабочее решение: module test(OSC1_50, SW, InData, ClkOut, CLK_OUT, EXT_CLK) //... input OSC1_50; // входной клок 50МHz input [1:0] SW; input [13:0] InData[0:3]; input ClkOut, EXT_CLK; output Res; output CLK_OUT; // сюда мне также надо выдать этот клок //... wire Clk300, Clk600; reg Counter300; DATA_Aq DATA_Aq_module(Counter300, InData, ClkOut, Res); my_pll4 my_pll_module4(OSC1_50, Clk300); // на выходе 300 МГц my_pll8 my_pll_module8(OSC1_50, Clk600); // на выходе 600 МГц always @(posedge Clk600) Counter300<=~Counter300; endmodule но что-то мне подсказывает, что это какое-то кривое решение. А надо мне именно 4 разных клока, то есть то, что у меня совсем не работает. Вдруг кто сможет мне посоветовать что же тут я делаю не правильного, и как правильно будет! Спасибо
  21. Добрый день, позвольте познакомиться с Вами, меня зовут Иван, я сейчас разбираюсь с Квартусом, что-то уже на СВерилоге научился, но далеко не все. Сейчас конкретно уперся в одну незадачку, которую не знаю как решить, помогите, пожалуйста, кто знает. Как мне кажется, должно быть все тривиально, но, я, кажется чего-то недогоняю. У меня есть самопально написанный простенький модуль на верилоге, с такими аргументами module DATA_Aq(Clk, In, ClkOut, Res); input Clk, ClkOut; input [13:0] In[0:3]; output reg Res; мне хочется гонять его на разных частотах входного клока (Clk), а именно 150,200,250,300МГц. На самой борде у меня есть клок в 50МГц, то есть с помощью 4 PLL (а может и 3-х, если 150 и 300 совместить) я могу получить на wire Clk150, Clk200, Clk250, Clk300; все мне необходимые клоки. Дальше я хотел с помошью входной переменной SW[1:0] принять решение какой клок мне нужен: module test(OSC1_50, SW, InData, ClkOut, CLK_OUT) //... input OSC1_50; // входной клок 50МHz input [1:0] SW; input [13:0] InData[0:3]; input ClkOut; output Res; output CLK_OUT; // сюда мне также надо выдать этот клок //... wire Clk150, Clk200, Clk250, Clk300; wire Clk; DATA_Aq DATA_Aq_module(Clk, InData, ClkOut, Res); my_pll1 my_pll_module1(OSC1_50, Clk150); // с помощью ALTPLL я здесь получаю необходимые клоки my_pll2 my_pll_module2(OSC1_50, Clk200); my_pll3 my_pll_module3(OSC1_50, Clk250); my_pll4 my_pll_module4(OSC1_50, Clk300); // вот тут я пытаюсь объединить клоки, но, кажется, чего-то не понимаю, и у меня ничего не работает, // помогите, пожалуйста, понять что я делаю не правильно! assign Clk=(SW[1])?((SW[0])?Clk300:Clk250):((SW[0])?Clk200:Clk150); assign CLK_OUT=(SW[1])?((SW[0])?Clk300:Clk250):((SW[0])?Clk200:Clk150); endmodule Что получается: в Clk приходит всегда один и тот же клок, точно его частоту я понять не смог, но она получается порядка 100МГц... Также Квартус не дает информации о максимально допустимом FMax для Clk, хотя есть компилить только модуль test, то Квартус показывает FMax(85C)=280MHz, FMax(0C)=310MHz. Подскажите, пожалуйста, что же я делаю не правильно? Спасибо Иван