系统概述
系统时钟为24MHz,使用高云GW2A FPGA从AD9280读取数据后经过一个FIFO作为缓冲,经FIR滤波器处理之后使用AD9708输出。AD9280与AD9708都使用八位并口传输数据。FIFO与FIR滤波器使用高云IP核。FIR滤波器系数使用Matlab的FDATOOL生成。
滤波器系数生成
到处时选择导出为C头文件,这样系数是有符号十进制数。将这些系数复制到一个文本文件中,一行一个系数,不要有其他符号。
IP核生成
选择’Advanced FIR Filter’IP核。
我在上一个步骤中生成的FIR系数是偶对称、偶整数,具有50个抽头系数,为14位量化。因此’FIR Type’选择’fir symmetry’以节省硬件资源。下方的’Coefficient File’选择上一步骤中的文本文件。
FIFO我选择了异步FIFO,为以后的拓展留下空间。
代码
module top (
input clk,
input rst_n,
output da_clk,
output reg [7:0] da_data,
output ad_clk,
input [7:0] ad_data
);
assign ad_clk = clk24m;
assign da_clk = clk24m;
wire fir_valid_out;
wire fir_sync_out;
wire [20:0] fir_data_out;
wire signed [7:0] signed_fifo_dout;
assign signed_fifo_dout = fifo_dout - 8'd128;
Advanced_FIR_Filter_Top u_fir(
.clk(clk24m), //input clk
.rstn(rst_n), //input rstn
.fir_rfi_o(), //output fir_rfi_o
.fir_valid_i(fifo_rden), //input fir_valid_i
.fir_sync_i(1'b1), //input fir_sync_i
.fir_data_i(signed_fifo_dout), //input [7:0] fir_data_i,使用转换后的有符号数据
.fir_valid_o(fir_valid_out), //output fir_valid_o
.fir_sync_o(fir_sync_out), //output fir_sync_o
.fir_data_o(fir_data_out) //output [18:0] fir_data_o
);
always @(posedge clk24m or negedge rst_n) begin
if (!rst_n) begin
da_data <= 8'h80; // 初始化为128
end else if (fir_valid_out) begin
da_data <= fir_data_out[14:7]+ 8'd128;
end
end
wire fifo_full;
wire fifo_empty;
wire fifo_wren;
wire fifo_rden;
assign fifo_wren = rst_n & !fifo_full;
assign fifo_rden = rst_n & !fifo_empty;
wire [7:0] fifo_dout;
fifo_top u_fifo(
.Data(ad_data), //input [7:0] Data
.WrClk(clk24m), //input WrClk
.RdClk(clk24m), //input RdClk
.WrEn(fifo_wren), //input WrEn
.RdEn(fifo_rden), //input RdEn
.Almost_Empty(fifo_empty), //output Almost_Empty
.Q(fifo_dout), //output [7:0] Q
.Empty(), //output Empty
.Full(fifo_full) //output Full
);
wire clk24m;
Gowin_rPLL u_rpll(
.clkout(clk24m), //output clkout
.clkin(clk) //input clkin
);
endmodule
注意事项
- FIR滤波器的设计方法选择等纹波。如果选择窗函数,会导致输出有明显的阶梯状。(至少在49阶低通滤波器下是这样的)
- 输入FIR滤波器之前要把直流量减去。
- 从滤波器的输出中选择哪8位非常重要