Zynq实现分布式Fir滤波器

摘要

通过ZYBOZ7开发板实现了分布式结构的FIR滤波器,实现了AD输入两路信号,通过开关输入可以分别单路输出、相加、相乘、相加后滤波、相乘后滤波的功能。

一、设计目标

设计基于FPGA的分布式结构的FIR滤波器,实现对输入信号的采集、滤波和输出。

二、 设计方案

1.硬件

材料型号规格
ZyboZ7开发板zynq-7000xc7z020clg400
DAPmodDA316位串行/类SPI接口
AD拓展接口--

实物图:
在这里插入图片描述

2.系统流程图

信号发生器1
信号发生器2
AD
FIR核
DA
示波器

三、具体实现步骤

1.XADC的使用

在这里插入图片描述
XADC包括一个双12位、1兆每秒采样(MSPS) ADC和片上ADC传感器。上图显示了XADC的框图。双重adc支持多种操作模式,例如,外部触发和同步。支持单极和差分输入。adc最多可以访问17个外部模拟输入通道。
由数据手册可知,ADC由两种操作模式:事件触发和连续转换模式。连续转换模式会在上次转换完成后继续下一次转换,默认一次转换需要26个ADCCLK;事件触发模式使用外部信号上升沿触发,启动一次转换。因为需按照固定采样率采样,故选择事件触发模式,使用100K信号触发,故采样率为100k。同时配置XDAC的时钟分频系数为4,clk为100MHz,所以ADCCLK实际大约为25MHz。
ADC的通道采样模式有四种:双ADC、独立ADC、单通道、多通道序列采样。因为本文须同时对两路信号信号进行采样,所以选择双ADC的模式,此模式下,在被外界信号触发后,两路ADC同时开始转换,并将结果保存的寄存器中。
在这里插入图片描述
ADC的接口可以配置为DRP(Dynamic Reconfiguration Port)和AXI,因为本文没有使用到PS部分,所以使用DRP接口。DRP接口读写时序如上图所示。
在这里插入图片描述
ADC的通道选择AD7和AD15,XADC引出如下引脚。查询时序图每次转换完成时会有eoc信号上升沿,channel会在转换完成时输出通道地址(AD7地址为7’h17,AD15地址为7’h1f),因为采用双ADC模式,所以channel只会输出AD7的地址。为了在每次转换完成时读取两通道AD的值,故编写XADC_wrapper.v封装了一层。编写如下状态机实现一次eoc信号触发两通道采样结果的读取:

Eoc转换完成信号
ToReadAD7
WaitAD7
ToReadAD15
WaitAD15

仿真结果如下:
在这里插入图片描述
代码整理好后会上传到Github。

2.PmodDA3的调试

在这里插入图片描述

Pmod DA3是一个基于Analog Devices AD5541A的16位数字模拟转换器,参考电压为2.5V,其单端SMA输出口能够将从类SPI接口所获得的信息转换成一个清晰、有保障的单调模拟输出。
为了控制PmodDA3,需要编写一个并转串行的模块,此模块的外部接口如下图所示:输入16为数据,在DA_drdy信号上升沿时将数据读入并转化为串行后通过Pmod接口发送给DA模块。
在这里插入图片描述
参考AD5541A用户手册的时序图编写并转串模块,SCK为发送数据的时钟,其由clk分频得到,本文配置其为25Mhz;_CS为片选信号,_CS信号拉低时,DA会在下个SCLK的上升沿读取DIN信号作为信号最高位(DB15),每个SCLK读取一个二进制位,16个上升沿读取完成,_CS信号置高。_LDAC信号为装载信号,在数据传输完成后拉低,触发DA模块内部数据装载到DAC单元实现模拟信号输出。
在这里插入图片描述
编写状态机实现上述时序:

DA_drdy信号触发
Start
Idle
SendData
LoadData

仿真结果:
在这里插入图片描述
编写个小程序:定义 reg[15:0] counter=0,每来一个clk ,counter+100,到65535溢出。如此就可以实现控制DA生成锯齿波,嘿嘿!
在这里插入图片描述

3.Fir滤波器

- 系统自带的IP核

- Matlab生成DA滤波器

4.开关控制

开关控制较为简单,顶层模块定义[3:0] sw输入信号,对其分配管脚,通过case(sw)语句块实现更改开关状态切换功能。

按键状态功能
0001AD7单路输出
0010AD15单路输出
0011两路相乘
1011两路相加
0111两路相乘滤波
1111两路相加滤波

实现代码如下:

//Control Logic
parameter[3:0]   OnlyAd7=4'b0001; 
parameter[3:0]   OnlyAd15=4'b0010;
parameter[3:0]   Ad15_AD7_mlt=4'b0011; 
parameter[3:0]   Ad15_AD7_add=4'b1011; 
parameter[3:0]   Ad15_AD7_mlt_Fir=4'b0111;
parameter[3:0]   Ad15_AD7_add_Fir=4'b1111;
always@(posedge clk)
begin
       case(sw)
           OnlyAd7:
               begin
                  da_indata<=_DataAD7;
                  da_invalid<=Data_rdy;
               end
           OnlyAd15:
               begin
                  da_indata<=_DataAD15;
                  da_invalid<=Data_rdy;                
               end
           Ad15_AD7_mlt:
               begin
                   DataAD7=_DataAD7;
                   DataAD15=_DataAD15;
                   da_indata=DataAD15[15:8]*DataAD7[15:8]; 
                   da_invalid<=Data_rdy;                   
               end
           Ad15_AD7_add:
                   begin
                       DataAD7=_DataAD7;
                       DataAD15=_DataAD15;
                       da_indata=DataAD15[15:1]+DataAD7[15:1];
                       da_invalid<=Data_rdy;               
                   end
           Ad15_AD7_mlt_Fir:
               begin
                 DataAD7=_DataAD7;
                 DataAD15=_DataAD15;
                 fir_indata=DataAD15[15:8]*DataAD7[15:8]; 
                 fir_invalid<=Data_rdy;
                 da_indata<=(fir_outdata<<2);
                 da_invalid<=fir_outvalid; 
                 da_invalid<=Data_rdy;                 
               end
           Ad15_AD7_add_Fir:
               begin
                 DataAD7=_DataAD7;
                 DataAD15=_DataAD15;
                 fir_indata=DataAD15[15:1]+DataAD7[15:1];
                 fir_invalid<=Data_rdy;
                 da_indata<=(fir_outdata<<2);
                 da_invalid<=fir_outvalid; 
                 da_invalid<=Data_rdy;                   
               end
           default:
               begin
                 da_indata<=_DataAD7;
                 da_invalid<=Data_rdy;    
               end
       endcase    
end   

四、总结

总耗时3周,系统实现了AD输入两路信号,通过开关输入可以分别单路输出、相加、相乘、相加后滤波、相乘后滤波的功能。缺点是滤波器设计截至频率和实际测试截至频率不同,大约相差10倍,至今未找到原因在哪。
因为Fir核不是自己编写的,所以整体难度一般。主要是通过此项目对ZYNQ的FPGA部分进行入门学习,个人感觉开发过程中除了需要Verilog语言基础,仿真和Debug方法尤为重要。
欢迎和各位交流分享

分布式FIR滤波器代码的一部分 //----------------------- // module description //----------------------- module fir_da( //input din, clock, reset, // dout ); //----------------------- // port declaration //----------------------- input [7:0] din; input clock; input reset; output [7:0] dout; //----------------------------------------------------- // signal declaration //----------------------------------------------------- reg [7:0] din_reg_00_8b; //移位寄存器 reg [7:0] din_reg_01_8b; reg [7:0] din_reg_02_8b; reg [7:0] din_reg_03_8b; reg [7:0] din_reg_04_8b; reg [7:0] din_reg_05_8b; reg [7:0] din_reg_06_8b; function[7:0] lookup_0; input [3:0] din; begin case(din) 4'b0000: lookup_0=16'h0; 4'b0001: lookup_0=16'h0; 4'b0010: lookup_0=16'h1; 4'b0011: lookup_0=16'h1; 4'b0100: lookup_0=16'h3; 4'b0101: lookup_0=16'h3; 4'b0110: lookup_0=16'h4; 4'b0111: lookup_0=16'h4; 4'b1000: lookup_0=16'h4; 4'b1001: lookup_0=16'h4; 4'b1010: lookup_0=16'h5; 4'b1011: lookup_0=16'h5; 4'b1100: lookup_0=16'h7; 4'b1101: lookup_0=16'h7; 4'b1110: lookup_0=16'h8; 4'b1111: lookup_0=16'h8; endcase end endfunction function[7:0] lookup_1; input [3:0] din; begin case(din) 4'b0000: lookup_1=16'h0; 4'b0001: lookup_1=16'h0; 4'b0010: lookup_1=16'h1; 4'b0011: lookup_1=16'h1; 4'b0100: lookup_1=16'h3; 4'b0101: lookup_1=16'h3; 4'b0110: lookup_1=16'h4; 4'b0111: lookup_1=16'h4; 4'b1000: lookup_1=16'h4; 4'b1001: lookup_1=16'h4; 4'b1010: lookup_1=16'h5; 4'b1011: lookup_1=16'h5; 4'b1100: lookup_1=16'h7; 4'b1101: lookup_1=16'h7; 4'b1110: lookup_1=16'h8; 4'b1111: lookup_1=16'h8; endcase end endfunction
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值