平臺(tái):Vivado2021.1
芯片:xcku115-flva1517-2-i (active)
語(yǔ)言:VerilogHDL
參考文件:pg149.下載地址
FIR Compiler LogiCORE IP Product Guide ? FIR Compiler (PG149) ? 閱讀器 ? AMD 自適應(yīng)計(jì)算文檔門(mén)戶(hù) (xilinx.com)
FIR濾波器
最近準(zhǔn)備研究以下濾波器。還是從xilinx的官方IP出發(fā),來(lái)學(xué)習(xí)以下這部分。
使用matlab直觀的感受以下。輸入信號(hào)為5khz,和10mhz正弦波疊加。
設(shè)置FIR濾波器參數(shù)。采樣率為50mhz,通帶起始頻率為100KHz,阻帶起始頻率為1MHz。
使用matlab打開(kāi)濾波器設(shè)計(jì)小工具。產(chǎn)生COE文件。
直接輸入filterDesigner。
打開(kāi)后的界面如下圖所示。
我們按照設(shè)計(jì)參數(shù)對(duì)濾波器進(jìn)行設(shè)置。
選擇響應(yīng)類(lèi)型為低通。選擇為FIR濾波器。采樣率為50mhz,通帶起始頻率為100KHz,阻帶起始頻率為1MHz。設(shè)置好后選擇設(shè)置量化參數(shù)。
濾波器算法選擇定點(diǎn)。分子字長(zhǎng)選擇16位。設(shè)置完成后點(diǎn)擊應(yīng)用。
選擇目標(biāo)。Xilinx系數(shù)(.coe)文件。保存在你選定的文件夾中。
這樣就生成了需要的FIR濾波器參數(shù)。可以在IP設(shè)計(jì)階段直接導(dǎo)入到xilinx的IP中。
同時(shí)還需要將生成的波形數(shù)據(jù)進(jìn)行歸一化處理。在量化到2^16次方上去。
所以需要使用matlab產(chǎn)生用于IP核仿真的數(shù)據(jù)。
%對(duì)數(shù)據(jù)進(jìn)行歸一化
max_abs_value = max(abs(x)); % 獲取數(shù)據(jù)的最大絕對(duì)值
normalized_data = x / max_abs_value; % 歸一化數(shù)據(jù)
% 量化為16位數(shù)據(jù)
simdata = normalized_data;
quantized_data = round(simdata * (2^15 - 1));
% 轉(zhuǎn)換為十六進(jìn)制數(shù)據(jù)
hex_data = dec2hex(quantized_data, 4);
%保存數(shù)據(jù)文件
fileID = fopen('E:\simdata.txt','w');%將數(shù)據(jù)寫(xiě)入txt。
% fprintf(fileID,'%d\n',quantized_data );%保存為十進(jìn)制數(shù)據(jù)
for i = 1:length(hex_data)
fprintf(fileID, '%s\n', hex_data(i, :)); % 將每行的十六進(jìn)制數(shù)據(jù)寫(xiě)入文件
end
fclose(fileID);
這里對(duì)產(chǎn)生的波形數(shù)據(jù)進(jìn)行過(guò)歸一化后。轉(zhuǎn)換為16進(jìn)制數(shù)據(jù)寫(xiě)入到文件simdata.txt中。
下面是整體的matlab代碼。
fs = 50000000; % 采樣率為50MHz
t = 0:1/fs:0.01; % 時(shí)間向量,采樣時(shí)間為0.01秒
f1 = 5000; % 5kHz正弦波頻率
f2 = 10000000; % 10mHz正弦波頻率
x = sin(2*pi*f1*t) + sin(2*pi*f2*t) ; % 輸入信號(hào),多個(gè)正弦波疊加
%對(duì)數(shù)據(jù)進(jìn)行歸一化
max_abs_value = max(abs(x)); % 獲取數(shù)據(jù)的最大絕對(duì)值
normalized_data = x / max_abs_value; % 歸一化數(shù)據(jù)
% 量化為16位數(shù)據(jù)
simdata = normalized_data;
quantized_data = round(simdata * (2^15 - 1));
% 轉(zhuǎn)換為十六進(jìn)制數(shù)據(jù)
hex_data = dec2hex(quantized_data, 4);
%保存數(shù)據(jù)文件
fileID = fopen('E:\CODE\Vivado\KU_TEST\ku_test_sim\flash_test\coe\simdata.txt','w');%將數(shù)據(jù)寫(xiě)入txt。
% fprintf(fileID,'%d\n',quantized_data );%保存為十進(jìn)制數(shù)據(jù)
for i = 1:length(hex_data)
fprintf(fileID, '%s\n', hex_data(i, :)); % 將每行的十六進(jìn)制數(shù)據(jù)寫(xiě)入文件
end
fclose(fileID);
order = 10; % FIR濾波器階數(shù)
cutoff = [100000]; % 截止頻率
b = fir1(order, cutoff/(fs/2)); % 設(shè)計(jì)FIR低通濾波器系數(shù)
y = filter(b, 1, x); % 應(yīng)用FIR濾波器
% 時(shí)域波形繪制
subplot(2, 2, 1);
plot(t, x);
title('濾波前的時(shí)域波形');
xlabel('時(shí)間');
ylabel('幅值');
subplot(2, 2, 3);
plot(t, y);
title('濾波后的時(shí)域波形');
xlabel('時(shí)間');
ylabel('幅值');
% 頻域波形繪制
X = fft(x);
Y = fft(y);
f = linspace(0, fs, length(t));
subplot(2, 2, 2);
plot(f, abs(X));
title('濾波前的頻域波形');
xlabel('頻率');
ylabel('幅值');
subplot(2, 2, 4);
plot(f, abs(Y));
title('濾波后的頻域波形');
xlabel('頻率');
ylabel('幅值');
使用matlab產(chǎn)生兩個(gè)波形疊加。通過(guò)FIR濾波器后,畫(huà)出了濾波前后的時(shí)域頻域波形。
下面是FPGA部分。
IP核的資料是PG149,里面詳細(xì)的介紹了這個(gè)IP資源。這里我們從應(yīng)用的角度出發(fā)來(lái)使用這個(gè)IP。
接口方面。還是使用了熟悉的AXI接口。
接口非常的簡(jiǎn)單。只需要輸入valid核數(shù)據(jù)即可。輸出端有valid和數(shù)據(jù)有效。
此IP核的主界面。
在左側(cè)部分分別是,IP核的接口。頻率響應(yīng)曲線(xiàn)。以及詳細(xì)信息。和系數(shù)重載功能。
選擇系數(shù)源,分別為coefile(COE文件)和Vector(系數(shù)矢量)。
這里我們選擇coe文件,我們直接從matlab中生成的coe文件。直接選定到文件夾。
Number of Coefficient Sets多個(gè)系數(shù)集,對(duì)于多系數(shù)過(guò)濾器,單個(gè).coe文件用于指定系數(shù)集。 每個(gè)系數(shù)集應(yīng)附加到前一組系數(shù)。我們這里沒(méi)有使用。
Number of Coefficients (per set)系數(shù)數(shù)量(每組):每個(gè)濾波器組的濾波器系數(shù)數(shù)量。自動(dòng)計(jì)算。
Use Reloadable Coefficients使用可重新加載的系數(shù):當(dāng)選擇重新加載選項(xiàng)時(shí),在核心上提供一個(gè)系數(shù)重新加載接口。這里我們不使用。
Filter Type濾波器類(lèi)型:支持五種濾波器類(lèi)型:?jiǎn)嗡俾蔉IR(有限脈沖響應(yīng)濾波器)、插值FIR、抽取FIR、Hilbert變換和插值FIR。
我們選擇為單速率。
下面的速率變化類(lèi)型和插值速率抽值速率。分別對(duì)應(yīng)于不同類(lèi)型的濾波器設(shè)置。
下面是通道規(guī)范頁(yè)。
Channel Sequence支持基本的和高級(jí)的。我們選擇基本的即可。
Number of Channels通道數(shù)我們選擇一通道。
下面的Select Sequence和Sequence ID List在高級(jí)模式中使用。
Select format選擇格式。
Sample Period采樣周期。
Input Sampling Frequency采樣頻率。跟你設(shè)置的采樣頻率一致。
Clock Frequency時(shí)鐘頻率。
Coefficient Type系數(shù)數(shù)據(jù)可以指定為有符號(hào)或無(wú)符號(hào)。
Quantization量化方式指定為整數(shù)。
Coefficient Width系數(shù)位寬,這里選擇為16位模式。選擇后在matlab中生成coe文件時(shí)選擇一致。
Coefficient Structure系數(shù)結(jié)構(gòu):支持五種系數(shù)結(jié)構(gòu):非對(duì)稱(chēng)、對(duì)稱(chēng)、負(fù)對(duì)稱(chēng)、半帶和希爾伯特。
數(shù)據(jù)路徑選擇。
同樣的,選擇輸入數(shù)類(lèi)型,數(shù)據(jù)位寬。這里選擇后需要在模擬產(chǎn)生輸入數(shù)據(jù)時(shí),產(chǎn)生一致。
Output Rounding Mode輸出數(shù)據(jù)的精度。默認(rèn)為全精度。后面的選擇可以選擇輸出數(shù)據(jù)位寬。
詳細(xì)頁(yè)
Goal優(yōu)化選項(xiàng)。使用最下面積最快速度和custom定制。
Select Optimization和List選擇分別定制優(yōu)化。
下面的Memory Options就是選擇緩存的類(lèi)型。這里可以根據(jù)你的需求自己選擇或者自動(dòng)。
DSP Slice Column Options:DSP選擇。
Multi-column Support可以選擇為自動(dòng)和定制。
Interface Tab接口頁(yè)。
Data Channel Options選擇AXI接口相關(guān)的參數(shù)。
TLAST指示AXI需要支持TLAST位不。以及是否使用tuser,tready等。
Configuration Channel Options
CONFIG通道用于選擇活動(dòng)的濾波器系數(shù)集。該通道還用于應(yīng)用重新加載的濾波器系數(shù)。
Reload Channel Options和重加載相關(guān)。
Control Signals控制信號(hào)。選擇復(fù)位時(shí)鐘等等。
總結(jié)界面。
我們?cè)陧攲永揑P核。
下面我們對(duì)該IP核進(jìn)行仿真。
下面分別是例化代碼和仿真tb。
// *********************************************************************************/
// Project Name :
// Author : i_huyi
// Email : i_huyi@qq.com
// Creat Time : 2023/10/20 16:46:10
// File Name : .v
// Module Name :
// Called By :
// Abstract :
//
// CopyRight(c) 2020, xxx xxx xxx Co., Ltd..
// All Rights Reserved
//
// *********************************************************************************/
// Modification History:
// 1. initial
// *********************************************************************************/
// *************************
// MODULE DEFINITION
// *************************
`timescale 1 ns / 1 ps
module fir#(
parameter U_DLY = 1
)
(
//
input wire[15:0] fir_data_in ,
input wire fir_data_inen ,
output wire[39:0] fir_data_out ,
output wire fir_data_outvalid ,
//
input wire clk ,
input wire rst_n
);
//--------------------------------------
// localparam
//--------------------------------------
//--------------------------------------
// register
//--------------------------------------
//--------------------------------------
// wire
//--------------------------------------
wire s_axis_data_tvalid ;
wire[15:0] s_axis_data_tdata ;
wire s_axis_data_tready ;
wire m_axis_data_tvalid ;
wire[39:0] m_axis_data_tdata ;
//--------------------------------------
// assign
//--------------------------------------
assign s_axis_data_tvalid = fir_data_inen;
assign s_axis_data_tdata = fir_data_in;
assign fir_data_out = m_axis_data_tdata;
assign fir_data_outvalid = m_axis_data_tvalid;
//------------------------------------------------------------
//------------------------------------------------------------
fir_compiler_0 u_fir_compiler_0 (
.aresetn (rst_n ),// input wire aresetn
.aclk (clk ),// 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 [39 : 0] m_axis_data_tdata
);
//------------------------------------------------------------
//------------------------------------------------------------
//------------------------------------------------------------
//------------------------------------------------------------
endmodule
仿真tb
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/10/23 09:33:40
// Design Name:
// Module Name: fir_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module fir_tb;
//input
reg [15:0] fir_data_in;
reg fir_data_inen;
reg clk;
reg rst_n;
reg [15:0] simdata [0:32767];
reg [15:0] read_data;
//output
wire[39:0] fir_data_out;
wire fir_data_outvalid;
fir u_fir(
.fir_data_in (fir_data_in ),
.fir_data_inen (fir_data_inen ),
.fir_data_out (fir_data_out ),
.fir_data_outvalid (fir_data_outvalid ),
//
.clk (clk ),
.rst_n (rst_n )
);
//------------------------------------------------------
//復(fù)位參數(shù)
//------------------------------------------------------
integer i;
//設(shè)置復(fù)位參數(shù)
initial
begin
$display("[%t] : reset begin...", $realtime);
rst_n = 0;
for( i=0 ; i<100 ; i=i+1)
begin
@(posedge clk );
end
$display("[%t] : reset stop...", $realtime);
rst_n = 1;
end
initial
begin
clk = 0;
read_data = 0;
fir_data_in = 0;
fir_data_inen = 0;
wait(rst_n == 1);
fir_data_inen = 1;
$display("[%t] : read data begin...", $realtime);
repeat(32767)
begin
@(posedge clk);
read_data = read_data + 16'd1;
fir_data_in = simdata[read_data];
end
repeat(100)@(posedge clk);
$display("[%t] : read data stop...", $realtime);
$finish(0);
end
initial
begin
$readmemh("E:/CODE/Vivado/KU_TEST/ku_test_sim/flash_test/coe/simdata.txt",simdata);
end
always #2 clk = ~clk;
endmodule
在經(jīng)過(guò)一段時(shí)間的仿真后,我們看到通過(guò)模擬產(chǎn)生的正弦波數(shù)據(jù)的高頻分量在FIR濾波器的作用下只保留了低頻部分。
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-811225.html
今天的FIR濾波器就學(xué)習(xí)到這里。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-811225.html
到了這里,關(guān)于Xilinx的FIR濾波器IP的設(shè)計(jì)與仿真的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!