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

Ких фильтр на Verilog

Доброго времени суток!
Только начинаю разбираться в данной теме, поэтому прошу не кидаться тапками

Следую инструкции указанной https://marsohod.org/11-blog/327-fir-verilog.
Однако, при запуске GtkWave диапазон времени всегда разный. Также в cmd всегда показывается разное значение endtime скрины прилагаю. Как это можно исправить? Просто у автора endtime=4ms и работа фильтра хорошо прослеживается. У меня же максимум endtime=400us
 
 

1.jpg

2.jpg

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


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

Вот код модуля 

module fir ( clk, coefs, in, out );

parameter IWIDTH = 16;    //input data (signal) width
parameter CWIDTH = 16;    //tap coef data width (should be less then 32 bit)
parameter TAPS   = 2;    //number of filter taps
localparam MWIDTH = (IWIDTH+CWIDTH); //multiplied width
localparam RWIDTH = (MWIDTH+TAPS-1); //filter result width

input  wire clk;
input  wire [IWIDTH-1:0]in;
input  wire [TAPS*32-1:0]coefs; //all input coefficient concatineted
output wire [RWIDTH-1:0]out; //output takes only top bits part of result

genvar i;
generate
    for( i=0; i<TAPS; i=i+1 )
    begin:tap
        //make tap register chain
        reg [IWIDTH-1:0]r=0;
        if(i==0)
        begin
            //1st tap takes signal from input
            always @(posedge clk)
                r <= in;
        end
        else
        begin
            //tap reg takes signal from prev tap reg
            always @(posedge clk)
                tap.r <= tap[i-1].r;
        end

        //get tap multiplication constant coef
        wire [CWIDTH-1:0]c;
        assign c = coefs[((TAPS-1-i)*32+CWIDTH-1):(TAPS-1-i)*32];

        //calculate multiplication and fix result in register
        reg [MWIDTH-1:0]m;
        always @(posedge clk)
            m <= $signed(r) * $signed( c );
            
        //make combinatorial adders
        reg [MWIDTH-1+i:0]a;
        if(i==0)
        begin
            always @*
                tap.a = $signed(tap.m);
        end
        else
        begin
            always @*
                tap.a = $signed(tap.m)+$signed(tap[i-1].a);
        end
    end
endgenerate

//fix calculated taps summa in register
reg [RWIDTH-1:0]result;
always @(posedge clk)
    result <= tap[TAPS-1].a;

//deliver output
assign out = result;

endmodule

 

Вот код тестбенча

 

`timescale 1ns / 1ns

module testbench();

reg tb_clk;
initial tb_clk=0;
always
    #25 tb_clk = ~tb_clk;

real PI=3.14159265358979323846;
real last_time=0; //Sec
real current_time=0; //Sec
real angle=0;    //Rad
real frequency=100; //Hz
integer freq_x100kHz=0; //*100kHz
reg signed [15:0]sin16;

//function which calculates Sinus(x)
function real sin;
input x;
real x;
real x1,y,y2,y3,y5,y7,sum,sign;
 begin
  sign = 1.0;
  x1 = x;
  if (x1<0)
  begin
   x1 = -x1;
   sign = -1.0;
  end
  while (x1 > PI/2.0)
  begin
   x1 = x1 - PI;
   sign = -1.0*sign;
  end  
  y = x1*2/PI;
  y2 = y*y;
  y3 = y*y2;
  y5 = y3*y2;
  y7 = y5*y2;
  sum = 1.570794*y - 0.645962*y3 +
      0.079692*y5 - 0.004681712*y7;
  sin = sign*sum;
 end
endfunction

task set_freq;
input f;
real f;
begin
    frequency = f;
    freq_x100kHz = f/100000.0;
end
endtask

always @(posedge tb_clk)
begin
    current_time = $realtime;
    angle = angle+(current_time-last_time)*2*PI*frequency/1000000000.0;
    //$display("%f %f",current_time,angle);
    while ( angle > PI*2.0 )
    begin
        angle = angle-PI*2.0;
    end 
    sin16 = 32000*sin(angle);
    last_time = current_time;
end

//low-pass filter
wire [57:0]out_lowpass;
fir #( .TAPS(27) ) fir_lp_inst(
    .clk(tb_clk),
    .coefs( { 
        -32'd510,
        -32'd520,
        -32'd625,
        -32'd575,
        -32'd287,
         32'd306,
         32'd1232,
         32'd2467,
         32'd3927,
         32'd5477,
         32'd6948,
         32'd8162,
         32'd8962,
         32'd9241,
         32'd8962,
         32'd8162,
         32'd6948,
         32'd5477,
         32'd3927,
         32'd2467,
         32'd1232,
         32'd306,
        -32'd287,
        -32'd575,
        -32'd625,
        -32'd520,
        -32'd510
        } ),
    .in(sin16),
    .out(out_lowpass)
    );

//band-pass
wire [55:0]out_bandpass;
fir #( .TAPS(25) ) fir_bp_inst(
    .clk(tb_clk),
    .coefs( { 
        -32'd801,
        -32'd1026,
        -32'd210,
         32'd1914,
         32'd4029,
         32'd3905,
         32'd330,
        -32'd5174,
        -32'd8760,
        -32'd7040,
        -32'd152,
         32'd7700,
         32'd11130,
         32'd7700,
        -32'd152,
        -32'd7040,
        -32'd8760,
        -32'd5174,
         32'd330,
         32'd3905,
         32'd4029,
         32'd1914,
        -32'd210,
        -32'd1026,
        -32'd801
        } ),
    .in(sin16),
    .out(out_bandpass)
    );

integer i;
real f;

initial
begin
    $dumpfile("out.vcd");
    $dumpvars(0,testbench);
    f=100000;
    for(i=0; i<4000; i=i+1)
    begin
        set_freq(f);
        #1000;
        f=f+1000;
    end
    $finish;
end

endmodule 

 

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


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

On 5/24/2021 at 5:37 PM, mr.nelipenko said:
Однако, при запуске GtkWave диапазон времени всегда разный. Также в cmd всегда показывается разное значение endtime скрины прилагаю. Как это можно исправить? Просто у автора endtime=4ms и работа фильтра хорошо прослеживается. У меня же максимум endtime=400us

Хотел бы уточнить, является ли это какой то проблемой, что-то работает не так или результат фильтрации не отвечает ожиданиям? В плане, ну время не такое, а остальное то работает нормально? Цифры на выходе совпадают? Может там в тесте рандом какой то от системного времени берется.

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


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

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

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

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

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

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

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

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

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

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