Halfback 0 11 ноября, 2021 Опубликовано 11 ноября, 2021 (изменено) · Жалоба Всем доброго времени суток! Реализовал полифазный децимирующий фильтр на 70 точек (на выходе каждая 10-я точка относительно входа), в моделсиме показывает всё как надо, в железе на столе тоже работает, но квартус валит слэки по Setup (Slow 1200mV 0C и +85С, по Fast - слэков нет). Причем в sdc когда ставлю 80МГц - слэков нет, на 100МГц еже есть. Буду очень признателен если поможете найти плохое место в коде. Может есть возможность что-то поправить/улучшить? Скрытый текст module PoliPhaseFilter_70 ( input clk, input signed [15:0] datain, input nreset, output signed [15:0] dataout, output clkDec // выходной клок синхр. данных ); localparam BANK_NUM = 10; localparam VALUE_NUM = 7; //регистры с входными данные reg signed [15:0] BANK_D0[BANK_NUM-1:0]; reg signed [15:0] BANK_D1[BANK_NUM-1:0]; reg signed [15:0] BANK_D2[BANK_NUM-1:0]; reg signed [15:0] BANK_D3[BANK_NUM-1:0]; reg signed [15:0] BANK_D4[BANK_NUM-1:0]; reg signed [15:0] BANK_D5[BANK_NUM-1:0]; reg signed [15:0] BANK_D6[BANK_NUM-1:0]; reg signed [15:0] BANK_C [BANK_NUM-1:0][VALUE_NUM-1:0]; //коэффициенты полифазного фильтра reg signed [31+3+4:0] RESSUMM = 0; // промежуточная сумма reg signed [31+3+4:0] RESSUMM_out = 0; // итоговая сумма -> на выход фильтра reg rclkDec = 0; integer i; reg [3:0] step=0; // 10 шагов //результаты перемножений значений данных на коэфф фильтра wire signed [15:0] mult0_1, mult0_2, mult1_1, mult1_2, mult2_1, mult2_2, mult3_1, mult3_2, mult4_1,mult4_2,mult5_1,mult5_2,mult6_1,mult6_2; //сумма результатов перемножений wire signed [31+3:0] resmult1; assign resmult1 = mult0_1*mult0_2 + mult1_1*mult1_2 + mult2_1*mult2_2 + mult3_1*mult3_2 + mult4_1*mult4_2 + mult5_1*mult5_2 + mult6_1*mult6_2; initial begin //обнуление всех регистров, формирование коэффициентов for(i = 0; i < BANK_NUM; i=i+1) begin BANK_D0[i]<=0; BANK_D1[i]<=0; BANK_D2[i]<=0; BANK_D3[i]<=0; BANK_D4[i]<=0; BANK_D5[i]<=0; BANK_D6[i]<=0; end RESSUMM <= 0; RESSUMM_out <= 0; BANK_C[0][0]= -16'd293; BANK_C[0][1]= -16'd1513;BANK_C[0][2] = 16'd3442; BANK_C[0][3] = 16'd16735;BANK_C[0][4] = 16'd15664;BANK_C[0][5] = 16'd2358; BANK_C[0][6] = -16'd1445; BANK_C[1][0]= -16'd278; BANK_C[1][1]= -16'd1518;BANK_C[1][2] = 16'd4646; BANK_C[1][3] = 16'd17631;BANK_C[1][4] = 16'd14446;BANK_C[1][5] = 16'd1407; BANK_C[1][6] = -16'd1331; BANK_C[2][0]= -16'd396; BANK_C[2][1]= -16'd1446;BANK_C[2][2] = 16'd5952; BANK_C[2][3] = 16'd18326;BANK_C[2][4] = 16'd13114;BANK_C[2][5] = 16'd596; BANK_C[2][6] = -16'd1185; BANK_C[3][0]= -16'd534; BANK_C[3][1]= -16'd1279;BANK_C[3][2] = 16'd7340; BANK_C[3][3] = 16'd18800;BANK_C[3][4] = 16'd11702;BANK_C[3][5] = -16'd74; BANK_C[3][6] = -16'd1022; BANK_C[4][0]= -16'd688; BANK_C[4][1]= -16'd1003;BANK_C[4][2] = 16'd8781; BANK_C[4][3] = 16'd19041;BANK_C[4][4] = 16'd10247;BANK_C[4][5] = -16'd604; BANK_C[4][6] = -16'd854; BANK_C[5][0]= -16'd854; BANK_C[5][1]= -16'd604; BANK_C[5][2] = 16'd10247;BANK_C[5][3] = 16'd19041;BANK_C[5][4] = 16'd8781; BANK_C[5][5] = -16'd1003;BANK_C[5][6] = -16'd688; BANK_C[6][0]= -16'd1022;BANK_C[6][1]= -16'd74; BANK_C[6][2] = 16'd11702;BANK_C[6][3] = 16'd18800;BANK_C[6][4] = 16'd7340; BANK_C[6][5] = -16'd1279;BANK_C[6][6] = -16'd534; BANK_C[7][0]= -16'd1185;BANK_C[7][1]= 16'd596; BANK_C[7][2] = 16'd13114;BANK_C[7][3] = 16'd18326;BANK_C[7][4] = 16'd5952; BANK_C[7][5] = -16'd1446;BANK_C[7][6] = -16'd396; BANK_C[8][0]= -16'd1331;BANK_C[8][1]= 16'd1407; BANK_C[8][2] = 16'd14446;BANK_C[8][3] = 16'd17631;BANK_C[8][4] = 16'd4646; BANK_C[8][5] = -16'd1518;BANK_C[8][6] = -16'd278; BANK_C[9][0]= -16'd1445;BANK_C[9][1]= 16'd2358; BANK_C[9][2] = 16'd15664;BANK_C[9][3] = 16'd16735;BANK_C[9][4] = 16'd3442; BANK_C[9][5] = -16'd1513;BANK_C[9][6] = -16'd293; end //initial always @ (posedge clk) begin if(nreset==1'b0) begin RESSUMM <= 0; RESSUMM_out <= 0; step <= 0; for(i = 0; i < BANK_NUM; i=i+1) begin BANK_D0[i]<=0; BANK_D1[i]<=0; BANK_D2[i]<=0; BANK_D3[i]<=0; BANK_D4[i]<=0; BANK_D5[i]<=0; BANK_D6[i]<=0; end end else begin //формирование строба для чтения выходного регистра if(step==0) rclkDec <= 1; if(step==5) rclkDec <= 0; BANK_D0[step] <= datain; // // сдвигаем данные BANK_D6[step]<=BANK_D5[step];BANK_D5[step]<=BANK_D4[step];BANK_D4[step]<=BANK_D3[step]; BANK_D3[step]<=BANK_D2[step];BANK_D2[step]<=BANK_D1[step];BANK_D1[step]<=BANK_D0[step]; case (step) 0,1,2,3,4,5,6,7,8: begin step <= step + 4'd1; RESSUMM <= RESSUMM + resmult1; end 9: begin step <= 4'd0; RESSUMM_out <= RESSUMM + resmult1;// формируем выход RESSUMM <= 0; end endcase end //else if end //always assign clkDec = rclkDec; assign mult0_1 = BANK_D0[step]; assign mult0_2 = BANK_C[step][6]; assign mult1_1 = BANK_D1[step]; assign mult1_2 = BANK_C[step][5]; assign mult2_1 = BANK_D2[step]; assign mult2_2 = BANK_C[step][4]; assign mult3_1 = BANK_D3[step]; assign mult3_2 = BANK_C[step][3]; assign mult4_1 = BANK_D4[step]; assign mult4_2 = BANK_C[step][2]; assign mult5_1 = BANK_D5[step]; assign mult5_2 = BANK_C[step][1]; assign mult6_1 = BANK_D6[step]; assign mult6_2 = BANK_C[step][0]; assign dataout = RESSUMM_out[33:18]; // обрезаем выходной регистр сверху и снизу для получения нужных 16 бит endmodule Изменено 11 ноября, 2021 пользователем Halfback Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 11 ноября, 2021 Опубликовано 11 ноября, 2021 · Жалоба assign resmult1 = mult0_1*mult0_2 + mult1_1*mult1_2 + mult2_1*mult2_2 + mult3_1*mult3_2 + mult4_1*mult4_2 + mult5_1*mult5_2 + mult6_1*mult6_2; assign mult0_1 = BANK_D0[step] как минимум после этого, удивительно что это еще на 80МГц работает ЗЫ. Скачайте учебник по ЦОС от альтеры, там в разделе фильтров много крайне полезной информации 43 minutes ago, Halfback said: Может есть возможность что-то поправить/улучшить? что-то мне подсказывает что BANK_D у вас будет реализован на регистрах, если с памятью проблем нет, то я бы переделал все на блочную память) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 11 ноября, 2021 Опубликовано 11 ноября, 2021 · Жалоба в дополнение к des00 обратите внимание еще на Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Halfback 0 12 ноября, 2021 Опубликовано 12 ноября, 2021 (изменено) · Жалоба 11.11.2021 в 09:55, des00 сказал: ЗЫ. Скачайте учебник по ЦОС от альтеры, там в разделе фильтров много крайне полезной информации Не поделитесь ссылкой или как в гугле поискать? Пока в поисковике вижу только Altera DSP Builder, но как я понимаю это не то что мне нужно... 10 часов назад, Maverick_ сказал: обратите внимание еще на обратил. У меня для Cyclone III (Quartus 13.0.1) нет такого примера, но есть вот такой темплейт для DSP Features/Sum of Four Multipliers (Stratix V, Arria-V, Cyclone-V and later device families) Мне не совсем понятно чем эта реализация отличается от моей. Если разница есть то ткните пожалуйста. Скрытый текст // Quartus II Verilog Template // Sum of four multipliers // For use with the Stratix V, Arria-V, Cyclone-V and later device families module sum_of_4(a1, b1, a2, b2, a3, b3, a4, b4, p); //This template is applicable to sum-of-4 18x18 mode on Stratix-V parameter a_width = 18; parameter b_width = 18; input [a_width-1:0] a1; input [b_width-1:0] b1; input [a_width-1:0] a2; input [b_width-1:0] b2; input [a_width-1:0] a3; input [b_width-1:0] b3; input [a_width-1:0] a4; input [b_width-1:0] b4; output [a_width+b_width+1:0] p; wire signed [a_width-1:0] a1; wire signed [b_width-1:0] b1; wire signed [a_width-1:0] a2; wire signed [b_width-1:0] b2; wire signed [a_width-1:0] a3; wire signed [b_width-1:0] b3; wire signed [a_width-1:0] a4; wire signed [b_width-1:0] b4; wire signed [a_width+b_width+1:0] p; //Static add/sub is supported assign p = a1 * b1 + a2 * b2 - a3 * b3 + a4 * b4; endmodule есть еще вот такой темплейт Sums of Multipliers (я так понял для плис помедленнее). Я таким образом тоже реализовывал - умножение с суммированием в виде отдельного модуля, где то-же самое делалось по клоку. Но ситуация со слеками никак не изменилась. Еще непонятно - целенаправлено ли скобки т.о. расставлены или нет. Скрытый текст // Quartus II Verilog Template // Sum of four multipliers module sum_of_four_multipliers #(parameter WIDTH=18) ( input clk, ena, input [WIDTH-1:0] dataa, datab, datac, datad, input [WIDTH-1:0] datae, dataf, datag, datah, output reg [2*WIDTH+1:0] dataout ); always @ (posedge clk) begin if (ena == 1) begin dataout <= (dataa * datab + datac * datad) + (datae * dataf + datag * datah); end end endmodule Изменено 12 ноября, 2021 пользователем Halfback Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 11 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба 25 minutes ago, Halfback said: Не поделитесь ссылкой или как в гугле поискать? Adder Trees, page 17: Advanced Synthesis Cookbook Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба 1 hour ago, Halfback said: Не поделитесь ссылкой или как в гугле поискать? Пока в поисковике вижу только Altera DSP Builder, но как я понимаю это не то что мне нужно... https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/manual/stx_cookbook.pdf 1 hour ago, Halfback said: обратил. У меня для Cyclone III (Quartus 13.0.1) нет такого примера, но есть вот такой темплейт для DSP Features/Sum of Four Multipliers (Stratix V, Arria-V, Cyclone-V and later device families) Мне не совсем понятно чем эта реализация отличается от моей. Если разница есть то ткните пожалуйста. количеством регистров и латентностью вычислений. Вот из каких кубиков вы будете собирать свой фильтр. Можно косвенно оценить задержки вашей схемы, для вычислений за 1 такт. 57 minutes ago, blackfin said: Adder Trees, page 17: Advanced Synthesis Cookbook это как раз сорцы к доке) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться