Estoy implementando un filtro FIR en Verilog, usando la placa DE2. Por alguna razón, la salida de los parlantes está llena de estática, aunque parece filtrar algunas frecuencias. Aquí está el código para el FIR:
// Local wires.
wire read_ready, write_ready, read, write;
wire [23:0] readdata_left, readdata_right;
wire [23:0] writedata_left, writedata_right;
assign writedata_left = output_sample;
assign writedata_right = output_sample;
assign read = 1;
assign write = 1;
wire [23:0] input_sample = readdata_left;
reg [23:0] output_sample;
La muestra de entrada se pasa a través del FIR y la muestra de salida se pasa a los altavoces izquierdo y derecho para simplificar.
//The FIR filter
parameter N = 40;
reg signed[23:0] coeffs[39:0];
reg [23:0] holderBefore[39:0];
wire [23:0] toAdd[39:0];
// -- 1000-1100
always @(*)
begin
coeffs[0]=24'b100000000110101001111110; // -- 1
coeffs[1]=24'b100000000110100011011011; // -- 2
coeffs[2]=24'b100000000111000100001100; // -- 3
coeffs[3]=24'b100000000111111000101000;// -- 4
coeffs[4]=24'b100000001000011111111100;// -- 5
coeffs[5]=24'b100000001000011001011001;// -- 6
coeffs[6]=24'b100000000111010001010011;// -- 7
coeffs[7]=24'b100000000100100110111010;// -- 8
coeffs[8]=24'b100000000000011010001101;// -- 9
coeffs[9]=24'b000000000101101111000000;// -- 10
coeffs[10]=24'b000000001101100001000100;// -- 11
coeffs[11]=24'b000000010110111100000000;// -- 12
coeffs[12]=24'b000000100001011111000001;// -- 13
coeffs[13]=24'b000000101100101001010111;// -- 14
coeffs[14]=24'b000000111000000000110100;// -- 15
coeffs[15]=24'b000001000010101010011001;// -- 16
coeffs[16]=24'b000001001100001011111000;// -- 17
coeffs[17]=24'b000001010011111101111100;// -- 18
coeffs[18]=24'b000001011001011001010010;// -- 19
coeffs[19]=24'b000001011100010000110010;// -- 20
coeffs[20]=24'b000001011100010000110010;// -- 20
coeffs[21]=24'b000001011001011001010010;// -- 19
coeffs[22]=24'b000001001100001011111000;// -- 18
coeffs[23]=24'b000001001100001011111000;// -- 17
coeffs[24]=24'b000001000010101010011001;// -- 16
coeffs[25]=24'b000000111000000000110100;// -- 15
coeffs[26]=24'b000000101100101001010111;// -- 14
coeffs[27]=24'b000000100001011111000001;// -- 13
coeffs[28]=24'b000000010110111100000000;// -- 12
coeffs[29]=24'b000000001101100001000100;// -- 11
coeffs[30]=24'b000000000101101111000000;// -- 10
coeffs[31]=24'b100000000000011010001101;// -- 9
coeffs[32]=24'b100000000100100110111010;// -- 8
coeffs[33]=24'b100000000111010001010011;// -- 7
coeffs[34]=24'b100000001000011001011001;// -- 6
coeffs[35]=24'b100000001000011111111100;// -- 5
coeffs[36]=24'b100000000111111000101000;// -- 4
coeffs[37]=24'b100000000111000100001100;// -- 3
coeffs[38]=24'b100000000110100011011011;// -- 2
coeffs[39]=24'b100000000110101001111110;// -- 1
end
genvar i;
generate
for (i=0; i<N; i=i+1)
begin: mult
multiplier mult1(
.dataa(coeffs[i]),
.datab(holderBefore[i]),
.out(toAdd[i]));
end
endgenerate
always @(posedge CLOCK_50 or posedge reset)
begin
if(reset)
begin
holderBefore[39] <= 0;
holderBefore[38] <= 0;
holderBefore[37] <= 0;
holderBefore[36] <= 0;
holderBefore[35] <= 0;
holderBefore[34] <= 0;
holderBefore[33] <= 0;
holderBefore[32] <= 0;
holderBefore[31] <= 0;
holderBefore[30] <= 0;
holderBefore[29] <= 0;
holderBefore[28] <= 0;
holderBefore[27] <= 0;
holderBefore[26] <= 0;
holderBefore[25] <= 0;
holderBefore[24] <= 0;
holderBefore[23] <= 0;
holderBefore[22] <= 0;
holderBefore[21] <= 0;
holderBefore[20] <= 0;
holderBefore[19] <= 0;
holderBefore[18] <= 0;
holderBefore[17] <= 0;
holderBefore[16] <= 0;
holderBefore[15] <= 0;
holderBefore[14] <= 0;
holderBefore[13] <= 0;
holderBefore[12] <= 0;
holderBefore[11] <= 0;
holderBefore[10] <= 0;
holderBefore[9] <= 0;
holderBefore[8] <= 0;
holderBefore[7] <= 0;
holderBefore[6] <= 0;
holderBefore[5] <= 0;
holderBefore[4] <= 0;
holderBefore[3] <= 0;
holderBefore[2] <= 0;
holderBefore[1] <= 0;
holderBefore[0] <= 0;
output_sample <= 0;
end
else
begin
holderBefore[39] <= holderBefore[38];
holderBefore[38] <= holderBefore[37];
holderBefore[37] <= holderBefore[36];
holderBefore[36] <= holderBefore[35];
holderBefore[35] <= holderBefore[34];
holderBefore[34] <= holderBefore[33];
holderBefore[33] <= holderBefore[32];
holderBefore[32] <= holderBefore[31];
holderBefore[31] <= holderBefore[30];
holderBefore[30] <= holderBefore[29];
holderBefore[29] <= holderBefore[28];
holderBefore[28] <= holderBefore[27];
holderBefore[27] <= holderBefore[26];
holderBefore[26] <= holderBefore[25];
holderBefore[25] <= holderBefore[24];
holderBefore[24] <= holderBefore[23];
holderBefore[23] <= holderBefore[22];
holderBefore[22] <= holderBefore[21];
holderBefore[21] <= holderBefore[20];
holderBefore[20] <= holderBefore[19];
holderBefore[19] <= holderBefore[18];
holderBefore[18] <= holderBefore[17];
holderBefore[17] <= holderBefore[16];
holderBefore[16] <= holderBefore[15];
holderBefore[15] <= holderBefore[14];
holderBefore[14] <= holderBefore[13];
holderBefore[13] <= holderBefore[12];
holderBefore[12] <= holderBefore[11];
holderBefore[11] <= holderBefore[10];
holderBefore[10] <= holderBefore[9];
holderBefore[9] <= holderBefore[8];
holderBefore[8] <= holderBefore[7];
holderBefore[7] <= holderBefore[6];
holderBefore[6] <= holderBefore[5];
holderBefore[5] <= holderBefore[4];
holderBefore[4] <= holderBefore[3];
holderBefore[3] <= holderBefore[2];
holderBefore[2] <= holderBefore[1];
holderBefore[1] <= holderBefore[0];
holderBefore[0] <= input_sample;
output_sample <= (input_sample + toAdd[0] + toAdd[1] +
toAdd[2] + toAdd[3] + toAdd[4] + toAdd[5] +
toAdd[6] + toAdd[7] + toAdd[8] + toAdd[9] +
toAdd[10] + toAdd[11] + toAdd[12]+ toAdd[13] + toAdd[14] +
toAdd[15] + toAdd[16] + toAdd[17] + toAdd[18] +
toAdd[19] + toAdd[20] + toAdd[21] + toAdd[22] +
toAdd[23] + toAdd[24] + toAdd[25] +toAdd[26] + toAdd[27] + toAdd[28] + toAdd[29] +
toAdd[19] + toAdd[20] + toAdd[21] + toAdd[22] +
toAdd[30] + toAdd[31] + toAdd[32]+ toAdd[33] + toAdd[34] + toAdd[35] + toAdd[36] +
toAdd[37] + toAdd[38] + toAdd[39]);
end
end
//The multiplier
module multiplier (dataa,datab,out);
input [23:0]dataa;
input [23:0]datab;
reg [47:0]result;
output[23:0]out;
always@(*)begin
result = dataa*datab;
end
assign out = result[46:24];
endmodule
Dado que los coeficientes son correctos, ¿hay algún problema con el código? Supongo que hay un problema con la representación de los coeficientes en binario, o el multiplicador está mal, pero no puedo resolverlo.
Su código será un poco más fácil de leer con un solo toque como módulo como (pseudocódigo verilog, ignorando, por ejemplo, cambios de bit después de mul, etc.)
module tap(reset, clk, samplein, sampleout, coef, sumin, sumout)
always@(posedge clk) begin
if(reset) begin
sumout <= 0;
sampleout <= 0;
end else begin
sampleout <= samplein;
sumout <= sumin + coef * samplein;
end
endmodule
úsalo como:
tap tap0(reset, clk, input, buf[0], coef[0], 0, sum[0]);
tap tap1(reset, clk, buf[0], buf[1], coef[0], 0, sum[1]);
...
tap tap39(reset, clk, buf[38], buf[39], coef[39], 0, output);
Creo que esto es mucho más fácil de usar en un banco de pruebas
Lo ideal sería hacer una grabación de los datos de entrada con SignalTap o similar para ver cómo llegan los datos dentro de la FPGA, o en su defecto generar algunos datos de prueba en el formato esperado usando un micrófono y matlab. Luego puede escribir Verilog para leer sus muestras y depurar el diseño usando un simulador y una herramienta de visor de forma de onda. Icarus Verilog y GTKWave son lo suficientemente buenos para hacer este trabajo sin costo alguno.
Altera tiene un núcleo FIR que tal vez quieras probar.
david tweed
AlgoBaller
gestión
roland mieslinger
roland mieslinger
roland mieslinger