Vivado FIR compiler 7.2 滤波器 仿真中遇到的问题及解决

一、Matlab FIR 滤波器定点系数导出及 Vivado FIR 滤波器 IP核 生成

  • 参见基于vivado的fir ip核的重采样设计与实现[1],这里不再赘述。
  • 本文默认读者对Vivado按钮分布比较了解,不再讲解按钮位置。

二、部分问题及解决方法(本文例程是对数据上采样滤波)

1、文件准备
  • IP核生成【位于:Sources->Hierarchy->Design Sources
  • 设计文件【在:Add Sources->Add or create design sources
    (1)【接口添加参考:Sources->IP Sources->IP->fir_compiler_0->Change Log->fir_compiler_0_stub(fir_compiler_0为IP 核名字)】。
    (2)【例化文件参考:Sources->IP Sources->IP->fir_compiler_0->Instantiation Template->fir_compiler_0.veo】。
  • 仿真文件【在:Add Sources->Add or create simulation sources
    (1)接口即例化文件同上,仿真是设置该文件为顶层文件(选择该文件右键->set as top)。
2、IP核(官方文件PG149)
  • Filter Options:滤波器参数(Filter Options -> Filter Coefficients -> Select Source)可以由coe文件导入,也可以直接输入矩阵,每个系数之间用英文逗号分隔。
    (1) coe文件创建参考引用[1],测试时该文件内系数以十六进制存储,生成的滤波器由于系数都是按照整数对待,最终滤波器预览的通带幅度增益较大,但是对功能没有影响,可以自己推算定点位置,对输出的数据进行处理;
    (2) Vector输入,可以使用matlab将上述系数除以 2n【n为推算值,注意Fir 滤波器系数绝对值小于1】;或者生成浮点系数转化为定点数使用,【参考 Matlab FIR 滤波器生成(使用APP),将导出的系数使用round(Index*2n)/2n定点,n根据定点位数同时考虑系数最大值得出】。
    (3) Filter Specification可以选择插值、抽取以及不处理等选项,其中插值倍数为2及以上整数倍,使用的插值数据为0.
  • Channel Specification:设置(Hardware Oversampling Specification)输入数据采样速率,时钟速率,例如:数据10M,四倍上采样,则可以设置时钟速率为40M及以上。
  • Implementation:设置输入数据输出数据滤波器系数因子的格式(有无符号、数据总位宽及小数位宽、输出数据非全位宽时选择截取策略)
    (1) Coefficient Options -> Coefficient Structure : 选择滤波器实现策略(详细内容参考PG149第23页),其中Symmetric 输出会先输出几个0(具体个数参看Implementation Details -> Information -> Coefficient front padding ),后面对应长度数据被截断而无法输出,但是滤波器资源消耗较少;Non Symmetric 无 多余0输出,但是消耗较多资源。
3、TestBench
  • 这里使用例程说明
//设计文件,按照上文介绍的方法生成
`timescale 1ns / 1ps
module fir(aclk, s_axis_data_tvalid, s_axis_data_tready, 
  s_axis_data_tdata, m_axis_data_tvalid, m_axis_data_tdata)
/* synthesis syn_black_box black_box_pad_pin="aclk,s_axis_data_tvalid,s_axis_data_tready,s_axis_data_tdata[15:0],m_axis_data_tvalid,m_axis_data_tdata[15:0]" */;
  input aclk;
  input s_axis_data_tvalid;
  output s_axis_data_tready;
  input [15:0]s_axis_data_tdata;
  output m_axis_data_tvalid;
  output [31:0]m_axis_data_tdata;

  fir_compiler_0 your_instance_name (
  .aclk(aclk),                              // input wire aclk
  .s_axis_data_tvalid(s_axis_data_tvalid),  // input wire s_axis_data_tvalid
  .s_axis_data_tready(s_axis_data_tready),  // output wire s_axis_data_tready
  .s_axis_data_tdata(s_axis_data_tdata),    // input wire [15 : 0] s_axis_data_tdata
  .m_axis_data_tvalid(m_axis_data_tvalid),  // output wire m_axis_data_tvalid
  .m_axis_data_tdata(m_axis_data_tdata)    // output wire [31 : 0] m_axis_data_tdata
);
endmodule
//tb文件
`timescale 1ns / 1ps
module fir_tb();
reg s_axis_data_tvalid;  
reg aclk;  
reg[9:0] s_axis_data_tdata;  
reg[9:0] Mem[33:0];             //读入数据存储寄存器

wire s_axis_data_tready;  
wire m_axis_data_tvalid;  
wire[31:0] m_axis_data_tdata; 

integer k,i,file;              //声明计数变量

fir uut(  
   .aclk(aclk),  
   .s_axis_data_tready(s_axis_data_tready),  
   .s_axis_data_tvalid(s_axis_data_tvalid),  
   .m_axis_data_tvalid(m_axis_data_tvalid),  
   .s_axis_data_tdata(s_axis_data_tdata),  
   .m_axis_data_tdata(m_axis_data_tdata)  
    );

initial $readmemh("C:/Users/laptop/Desktop/Hardware/data_in.txt", Mem); //将文件以十六进制方式读入定义的寄存器Men.

initial begin
file = $fopen("C:/Users/laptop/Desktop/Hardware/data_out_10.txt","w");//以写方式打开文件
#5000 $fclose(file);//关闭文件
end

//产生输入有效信号,滤波器在上升沿读入
initial begin  
      s_axis_data_tvalid = 0;  
    for(i=0;i<=33;i=i+1)  
        begin  
        #75 s_axis_data_tvalid = 1;  
        #25 s_axis_data_tvalid = 0;  
        end  
    end 

//将输入数据以10M的速度输入
initial begin  
        s_axis_data_tdata = 0;  
            for(k=0;k<=33;k=k+1)  
            begin
            #50 s_axis_data_tdata = Mem[k];  
            #50;
            end
        end

//产生滤波器时钟(40M)
initial begin
        aclk <= 1'b0;
        end
always #12.5 aclk <= ~aclk;

//在输出使能有效时,将输出以有符号数十进制写入输出文件中,\n为换行符号。
always @(posedge aclk)
if (m_axis_data_tvalid) 
begin
	$fwrite(file,"%d\n",$signed(m_axis_data_tdata));   
end

endmodule
//输入输入data_in.txt
FFFF  
0004  
0001  
0008  
0001  
FFFF  
0000  
0008  
0001  
0001  
0002  
000c  
0001  
0002  
0001  
0000  
0015  
0002  
0004  
0008  
0000  
0001  
0020  
0001  
0008  
0001  
FFDD  
0002  
0001  
0041  
0002  
004B  
0000  
0001  
  • 仿真结果说明
    Vivado FIR compiler 7.2 滤波器 仿真中遇到的问题及解决_第1张图片
    (1) 第一行为输入有效信号s_axis_data_tvalid,第二行为时钟信号aclk,第三行为输入信号s_axis_data_tdata,第六行为输出有效信号m_axis_data_tvalid,第八行为输出信号m_axis_data_tdata,可以看到结果符合预期;输出信号为40M,跟随时钟1:1输出。
    (2) 输入有效信号一直置高位,输出有效信号将一直为0,且没有输出数据。
    (3) 仿真默认1000ns,继续仿真可以设置时间(位于当前窗口上方,本文设置为1us),点击设置时间左侧开始按钮,点击一次继续仿真设置时间的长度,点击RUN ALL 按钮,连续不断仿真,知道按下暂停按钮。
    (4) 右键仿真图左侧变量名称,选择Radix,可以设置数字显示格式,REAL可以定制详细格式。

微信公众号:通信随笔XIDIAN

在这里插入图片描述

你可能感兴趣的:(Vivado,verilog,verilog)