Перейти к содержанию
    

Реализация на Verilog полифазного фильтра, борьба со слэками

Всем доброго времени суток!

Реализовал полифазный децимирующий фильтр на 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

 

 

 

Изменено пользователем Halfback

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 у вас будет реализован на регистрах, если с памятью проблем нет, то я бы переделал все на блочную память)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

 

 

Изменено пользователем Halfback

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

25 minutes ago, Halfback said:

Не поделитесь ссылкой или как в гугле поискать?

Adder Trees, page 17: Advanced Synthesis Cookbook

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 такт.

cyclone3mult.png

57 minutes ago, blackfin said:

Adder Trees, page 17: Advanced Synthesis Cookbook

это как раз сорцы к доке)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...