乡镇网站建设自查报告,陇城科技网站建设,淘宝自动推广软件,做网站用windows和 linux该项目介绍了如何使用 Verilog 实现具有预生成系数的简单 FIR 滤波器。 绪论 不起眼的 FIR 滤波器是 FPGA 数字信号处理中最基本的模块之一#xff0c;因此了解如何将具有给定抽头数及其相应系数值的基本模块组合在一起非常重要。因此#xff0c;在这个关于 FPGA 上 DSP 基础… 该项目介绍了如何使用 Verilog 实现具有预生成系数的简单 FIR 滤波器。 绪论 不起眼的 FIR 滤波器是 FPGA 数字信号处理中最基本的模块之一因此了解如何将具有给定抽头数及其相应系数值的基本模块组合在一起非常重要。因此在这个关于 FPGA 上 DSP 基础实用入门的教程中将从一个简单的 15 抽头低通滤波器 FIR 开始在 Matlab 中为其生成初始系数值然后转换这些值用于编写 Verilog 模块。 有限脉冲响应或 FIR 滤波器定义为脉冲响应在特定时间段内稳定为零值的滤波器。脉冲响应稳定到零所花费的时间与滤波器阶数抽头数直接相关滤波器阶数是 FIR 的基础传递函数多项式的阶数。FIR 的传递函数不包含反馈因此如果输入一个值为 1 的脉冲然后输入一串零值输出将只是滤波器的系数值。 滤波器的作用基本都是用于信号调节主要集中在选择滤除或允许通过哪些频率。最简单的例子之一是低通滤波器它允许低于某个阈值截止频率的频率通过同时大大衰减高于该阈值的频率如下图所示。 该项目的主要重点是在 HDL具体为 Verilog中实现 FIR它可以分解为三个主要逻辑组件一个循环缓冲器用于将每个样本计时到适当地考虑了串行输入的延迟、每个抽头系数值的乘法器以及每个抽头输出的求和结果的累加器。 由于本项目专注于 FPGA 逻辑中 FIR 的设计机制所以只是使用 Simulink 中的 FDA 工具和 Matlab 为低通滤波器插入一些简单参数然后使用生成的系数值放到 Verilog 模块中完成滤波器的设计在后面的步骤中完成。 选择实现一个简单的 15 抽头低通滤波器 FIR采样率为 1Ms/s通带频率为 200kHz阻带频率为 355kHz得到以下系数 -0.0265
0
0.0441
0
-0.0934
0
0.3139
0.5000
0.3139
0
-0.0934
0
0.0441
0
-0.0265 为 FIR 模块创建设计文件 在 Vivado 项目中添加源文件。 在确定 FIR 的顺序抽头数并获得系数值后接下来需要定义的下一组参数就是输入样本、输出样本和系数本身的位宽。 对于这个 FIR选择将输入样本和系数寄存器设置为 16 位宽并将输出样本寄存器设置为 32 位因为两个 16 位值的乘积是一个 32 位值两个值的宽度相乘得到乘积的宽度所以如果选择了 8 位抽头的 16 位输入样本那么输出样本将为 24 位宽。 这些值也都是带符号的因此 MSB 用作符号位在选择输入样本寄存器的初始宽度时一定要记住这一点。要在 Verilog 中将这些值设置为有符号数据类型使用关键字signed reg signed [15:0] register_name; 接下来要解决的是如何在 Verilog 中处理系数值小数点值需要转换为定点值。由于所有系数值都小于 1因此寄存器的所有 15 位总共 16 位MSB 是有符号位都可以用于小数位。通常必须决定要将寄存器中的多少位用于数字的整数部分与数字的小数部分。因此转换分数值抽头的数学是(fractional coefficient value)*(2^(15))该乘积的小数值被四舍五入并且如果系数为负则计算该值的二进制补码 tap0 twos(-0.0265 * 32768) 0xFC9C
tap1 0
tap2 0.0441 * 32768 1445.0688 1445 0x05A5
tap3 0
tap4 twos(-0.0934 * 32768) 0xF40C
tap5 0
tap6 0.3139 * 32768 10285.8752 10285 0x282D
tap7 0.5000 * 32768 16384 0x4000
tap8 0.3139 * 32768 10285.8752 10285 0x282D
tap9 0
tap10 twos(-0.0934 * 32768) 0xF40C
tap11 0
tap12 0.0441 * 32768 1445.0688 1445 0x05A5
tap13 0
tap14 twos(-0.0265 * 32768) 0xFC9C 现在我们终于准备好关注 FIR 模块的逻辑第一个是循环缓冲区它引入串行输入样本流并为滤波器的 15 个抽头创建一个包含 15 个输入样本的数组。 always (posedge clk)beginif(enable_buff 1b1)beginbuff0 in_sample;buff1 buff0; buff2 buff1; buff3 buff2; buff4 buff3; buff5 buff4; buff6 buff5; buff7 buff6; buff8 buff7; buff9 buff8; buff10 buff9; buff11 buff10; buff12 buff11; buff13 buff12; buff14 buff13; endend 接下来乘法阶段将每个样本乘以每个系数值 /* Multiply stage of FIR */always (posedge clk)beginif (enable_fir 1b1)beginacc0 tap0 * buff0;acc1 tap1 * buff1;acc2 tap2 * buff2;acc3 tap3 * buff3;acc4 tap4 * buff4;acc5 tap5 * buff5;acc6 tap6 * buff6;acc7 tap7 * buff7;acc8 tap8 * buff8;acc9 tap9 * buff9;acc10 tap10 * buff10;acc11 tap11 * buff11;acc12 tap12 * buff12;acc13 tap13 * buff13;acc14 tap14 * buff14;endend 乘法阶段的结果值通过加法累加到寄存器中最终成为滤波器的输出数据流。 /* Accumulate stage of FIR */ always (posedge clk) beginif (enable_fir 1b1)beginm_axis_fir_tdata acc0 acc1 acc2 acc3 acc4 acc5 acc6 acc7 acc8 acc9 acc10 acc11 acc12 acc13 acc14;endend 最后逻辑的最后一部分是将数据流进和流出 FIR 模块的接口。AXI Stream 接口是最常见的接口之一。关键方面是允许控制上游和下游设备之间的数据流的tready和tvalid信号。这意味着 FIR 模块需要向其下游设备提供tvalid信号以指示其输出是有效数据并且如果下游设备解除其tready信号则能够暂停但仍保留其输出。FIR 模块还必须能够与其主端接口上的上游设备以同样的方式运行。 以下是 FIR 模块的逻辑设计概述 请注意tready和tvalid信号如何设置输入循环缓冲器的使能值和 FIR 的乘法级以及数据或系数通过的每个寄存器都被声明为有符号的。 FIR模块Verilog代码 timescale 1ns / 1psmodule FIR(input clk,input reset,input signed [15:0] s_axis_fir_tdata, input [3:0] s_axis_fir_tkeep,input s_axis_fir_tlast,input s_axis_fir_tvalid,input m_axis_fir_tready,output reg m_axis_fir_tvalid,output reg s_axis_fir_tready,output reg m_axis_fir_tlast,output reg [3:0] m_axis_fir_tkeep,output reg signed [31:0] m_axis_fir_tdata);always (posedge clk)beginm_axis_fir_tkeep 4hf;endalways (posedge clk)beginif (s_axis_fir_tlast 1b1)beginm_axis_fir_tlast 1b1;endelsebeginm_axis_fir_tlast 1b0;endend// 15-tap FIR reg enable_fir, enable_buff;reg [3:0] buff_cnt;reg signed [15:0] in_sample; reg signed [15:0] buff0, buff1, buff2, buff3, buff4, buff5, buff6, buff7, buff8, buff9, buff10, buff11, buff12, buff13, buff14; wire signed [15:0] tap0, tap1, tap2, tap3, tap4, tap5, tap6, tap7, tap8, tap9, tap10, tap11, tap12, tap13, tap14; reg signed [31:0] acc0, acc1, acc2, acc3, acc4, acc5, acc6, acc7, acc8, acc9, acc10, acc11, acc12, acc13, acc14; /* Taps for LPF running 1MSps with a cutoff freq of 400kHz*/assign tap0 16hFC9C; // twos(-0.0265 * 32768) 0xFC9Cassign tap1 16h0000; // 0assign tap2 16h05A5; // 0.0441 * 32768 1445.0688 1445 0x05A5assign tap3 16h0000; // 0assign tap4 16hF40C; // twos(-0.0934 * 32768) 0xF40Cassign tap5 16h0000; // 0assign tap6 16h282D; // 0.3139 * 32768 10285.8752 10285 0x282Dassign tap7 16h4000; // 0.5000 * 32768 16384 0x4000assign tap8 16h282D; // 0.3139 * 32768 10285.8752 10285 0x282Dassign tap9 16h0000; // 0assign tap10 16hF40C; // twos(-0.0934 * 32768) 0xF40Cassign tap11 16h0000; // 0assign tap12 16h05A5; // 0.0441 * 32768 1445.0688 1445 0x05A5assign tap13 16h0000; // 0assign tap14 16hFC9C; // twos(-0.0265 * 32768) 0xFC9C/* This loop sets the tvalid flag on the output of the FIR high once * the circular buffer has been filled with input samples for the * first time after a reset condition. */always (posedge clk or negedge reset)beginif (reset 1b0) //if (reset 1b0 || tvalid_in 1b0)beginbuff_cnt 4d0;enable_fir 1b0;in_sample 8d0;endelse if (m_axis_fir_tready 1b0 || s_axis_fir_tvalid 1b0)beginenable_fir 1b0;buff_cnt 4d15;in_sample in_sample;endelse if (buff_cnt 4d15)beginbuff_cnt 4d0;enable_fir 1b1;in_sample s_axis_fir_tdata;endelsebeginbuff_cnt buff_cnt 1;in_sample s_axis_fir_tdata;endend always (posedge clk)beginif(reset 1b0 || m_axis_fir_tready 1b0 || s_axis_fir_tvalid 1b0)begins_axis_fir_tready 1b0;m_axis_fir_tvalid 1b0;enable_buff 1b0;endelsebegins_axis_fir_tready 1b1;m_axis_fir_tvalid 1b1;enable_buff 1b1;endend/* Circular buffer bring in a serial input sample stream that * creates an array of 15 input samples for the 15 taps of the filter. */always (posedge clk)beginif(enable_buff 1b1)beginbuff0 in_sample;buff1 buff0; buff2 buff1; buff3 buff2; buff4 buff3; buff5 buff4; buff6 buff5; buff7 buff6; buff8 buff7; buff9 buff8; buff10 buff9; buff11 buff10; buff12 buff11; buff13 buff12; buff14 buff13; endelsebeginbuff0 buff0;buff1 buff1; buff2 buff2; buff3 buff3; buff4 buff4; buff5 buff5; buff6 buff6; buff7 buff7; buff8 buff8; buff9 buff9; buff10 buff10; buff11 buff11; buff12 buff12; buff13 buff13; buff14 buff14;endend/* Multiply stage of FIR */always (posedge clk)beginif (enable_fir 1b1)beginacc0 tap0 * buff0;acc1 tap1 * buff1;acc2 tap2 * buff2;acc3 tap3 * buff3;acc4 tap4 * buff4;acc5 tap5 * buff5;acc6 tap6 * buff6;acc7 tap7 * buff7;acc8 tap8 * buff8;acc9 tap9 * buff9;acc10 tap10 * buff10;acc11 tap11 * buff11;acc12 tap12 * buff12;acc13 tap13 * buff13;acc14 tap14 * buff14;endend /* Accumulate stage of FIR */ always (posedge clk) beginif (enable_fir 1b1)beginm_axis_fir_tdata acc0 acc1 acc2 acc3 acc4 acc5 acc6 acc7 acc8 acc9 acc10 acc11 acc12 acc13 acc14;endend endmodule 创建仿真文件 要测试 FIR 模块需要创建一个测试平台作为其仿真源 在 FIR 模块中有两个主要的东西需要测试滤波器算法和 AXI 流接口。为实现这一点测试台中创建了一个状态机它生成一个简单的 200kHz 正弦波并切换从属端的有效信号和 FIR 接口主控端的tready信号。 FIR 模块的测试平台 timescale 1ns / 1psmodule tb_FIR;reg clk, reset, s_axis_fir_tvalid, m_axis_fir_tready;reg signed [15:0] s_axis_fir_tdata;wire m_axis_fir_tvalid;wire [3:0] m_axis_fir_tkeep;wire [31:0] m_axis_fir_tdata;/** 100Mhz (10ns) clock */always beginclk 1; #5;clk 0; #5;endalways beginreset 1; #20;reset 0; #50;reset 1; #1000000;endalways begins_axis_fir_tvalid 0; #100;s_axis_fir_tvalid 1; #1000;s_axis_fir_tvalid 0; #50;s_axis_fir_tvalid 1; #998920;endalways beginm_axis_fir_tready 1; #1500;m_axis_fir_tready 0; #100;m_axis_fir_tready 1; #998400;end/* Instantiate FIR module to test. */FIR FIR_i(.clk(clk),.reset(reset),.s_axis_fir_tdata(s_axis_fir_tdata), .s_axis_fir_tkeep(s_axis_fir_tkeep), .s_axis_fir_tlast(s_axis_fir_tlast), .s_axis_fir_tvalid(s_axis_fir_tvalid), .m_axis_fir_tready(m_axis_fir_tready),.m_axis_fir_tvalid(m_axis_fir_tvalid), .s_axis_fir_tready(s_axis_fir_tready), .m_axis_fir_tlast(m_axis_fir_tlast), .m_axis_fir_tkeep(m_axis_fir_tkeep), .m_axis_fir_tdata(m_axis_fir_tdata)); reg [4:0] state_reg;reg [3:0] cntr;parameter wvfm_period 4d4;parameter init 5d0;parameter sendSample0 5d1;parameter sendSample1 5d2;parameter sendSample2 5d3;parameter sendSample3 5d4;parameter sendSample4 5d5;parameter sendSample5 5d6;parameter sendSample6 5d7;parameter sendSample7 5d8;/* This state machine generates a 200kHz sinusoid. */always (posedge clk or posedge reset)beginif (reset 1b0)begincntr 4d0;s_axis_fir_tdata 16d0;state_reg init;endelsebegincase (state_reg)init : //0begincntr 4d0;s_axis_fir_tdata 16h0000;state_reg sendSample0;endsendSample0 : //1begins_axis_fir_tdata 16h0000;if (cntr wvfm_period)begincntr 4d0;state_reg sendSample1;endelsebegin cntr cntr 1;state_reg sendSample0;endend sendSample1 : //2begins_axis_fir_tdata 16h5A7E; if (cntr wvfm_period)begincntr 4d0;state_reg sendSample2;endelsebegin cntr cntr 1;state_reg sendSample1;endend sendSample2 : //3begins_axis_fir_tdata 16h7FFF;if (cntr wvfm_period)begincntr 4d0;state_reg sendSample3;endelsebegin cntr cntr 1;state_reg sendSample2;endend sendSample3 : //4begins_axis_fir_tdata 16h5A7E;if (cntr wvfm_period)begincntr 4d0;state_reg sendSample4;endelsebegin cntr cntr 1;state_reg sendSample3;endend sendSample4 : //5begins_axis_fir_tdata 16h0000;if (cntr wvfm_period)begincntr 4d0;state_reg sendSample5;endelsebegin cntr cntr 1;state_reg sendSample4;endend sendSample5 : //6begins_axis_fir_tdata 16hA582; if (cntr wvfm_period)begincntr 4d0;state_reg sendSample6;endelsebegin cntr cntr 1;state_reg sendSample5;endend sendSample6 : //6begins_axis_fir_tdata 16h8000; if (cntr wvfm_period)begincntr 4d0;state_reg sendSample7;endelsebegin cntr cntr 1;state_reg sendSample6;endend sendSample7 : //6begins_axis_fir_tdata 16hA582; if (cntr wvfm_period)begincntr 4d0;state_reg sendSample0;endelsebegin cntr cntr 1;state_reg sendSample7;endend endcaseendendendmodule 运行行为仿真 FIR 模块及其测试平台文件就位后从 Flow Navigator 窗口启动 Vivado 中的仿真器选择 Run Behavioral Simulation 选项。 如行为仿真所示FIR 正确过滤信号并正确响应 AXI 流信号。 总结 代码都在上面大家有兴趣可以自行运行但是大家可能会注意到这个 FIR 模块在设计上运行综合和实现时时序应该是不能通过的。我们将在下一篇文章中详细介绍如何在无法满足时序要求时重新设计你的设计~
文章转载自: http://www.morning.zlnmm.cn.gov.cn.zlnmm.cn http://www.morning.gyqnc.cn.gov.cn.gyqnc.cn http://www.morning.ghssm.cn.gov.cn.ghssm.cn http://www.morning.blqmn.cn.gov.cn.blqmn.cn http://www.morning.wdlyt.cn.gov.cn.wdlyt.cn http://www.morning.kszkm.cn.gov.cn.kszkm.cn http://www.morning.mehrim.com.gov.cn.mehrim.com http://www.morning.rbjth.cn.gov.cn.rbjth.cn http://www.morning.qnqt.cn.gov.cn.qnqt.cn http://www.morning.zhiheliuxue.com.gov.cn.zhiheliuxue.com http://www.morning.tsgxz.cn.gov.cn.tsgxz.cn http://www.morning.fksxs.cn.gov.cn.fksxs.cn http://www.morning.xgbq.cn.gov.cn.xgbq.cn http://www.morning.hcsqznn.cn.gov.cn.hcsqznn.cn http://www.morning.lmpfk.cn.gov.cn.lmpfk.cn http://www.morning.jqtb.cn.gov.cn.jqtb.cn http://www.morning.qfwzm.cn.gov.cn.qfwzm.cn http://www.morning.pqnkg.cn.gov.cn.pqnkg.cn http://www.morning.lwwnq.cn.gov.cn.lwwnq.cn http://www.morning.qrwdg.cn.gov.cn.qrwdg.cn http://www.morning.tmsxn.cn.gov.cn.tmsxn.cn http://www.morning.bhrkx.cn.gov.cn.bhrkx.cn http://www.morning.pkpqh.cn.gov.cn.pkpqh.cn http://www.morning.ghfmd.cn.gov.cn.ghfmd.cn http://www.morning.qnpyz.cn.gov.cn.qnpyz.cn http://www.morning.xcdph.cn.gov.cn.xcdph.cn http://www.morning.nckzt.cn.gov.cn.nckzt.cn http://www.morning.wrbx.cn.gov.cn.wrbx.cn http://www.morning.wkkqw.cn.gov.cn.wkkqw.cn http://www.morning.glpxx.cn.gov.cn.glpxx.cn http://www.morning.zkrzb.cn.gov.cn.zkrzb.cn http://www.morning.wfkbk.cn.gov.cn.wfkbk.cn http://www.morning.bfybb.cn.gov.cn.bfybb.cn http://www.morning.xdhcr.cn.gov.cn.xdhcr.cn http://www.morning.gediba.com.gov.cn.gediba.com http://www.morning.yhyqg.cn.gov.cn.yhyqg.cn http://www.morning.rwmqp.cn.gov.cn.rwmqp.cn http://www.morning.gryzk.cn.gov.cn.gryzk.cn http://www.morning.kchwr.cn.gov.cn.kchwr.cn http://www.morning.qtqk.cn.gov.cn.qtqk.cn http://www.morning.qxwrd.cn.gov.cn.qxwrd.cn http://www.morning.bnmrp.cn.gov.cn.bnmrp.cn http://www.morning.kyfnh.cn.gov.cn.kyfnh.cn http://www.morning.qmmfr.cn.gov.cn.qmmfr.cn http://www.morning.rrqbm.cn.gov.cn.rrqbm.cn http://www.morning.kstgt.cn.gov.cn.kstgt.cn http://www.morning.mxnrl.cn.gov.cn.mxnrl.cn http://www.morning.jfymz.cn.gov.cn.jfymz.cn http://www.morning.pjtnk.cn.gov.cn.pjtnk.cn http://www.morning.qkwxp.cn.gov.cn.qkwxp.cn http://www.morning.jthjr.cn.gov.cn.jthjr.cn http://www.morning.krbjb.cn.gov.cn.krbjb.cn http://www.morning.bygyd.cn.gov.cn.bygyd.cn http://www.morning.jwbfj.cn.gov.cn.jwbfj.cn http://www.morning.jkftn.cn.gov.cn.jkftn.cn http://www.morning.ygwbg.cn.gov.cn.ygwbg.cn http://www.morning.dbddm.cn.gov.cn.dbddm.cn http://www.morning.qggm.cn.gov.cn.qggm.cn http://www.morning.tlzbt.cn.gov.cn.tlzbt.cn http://www.morning.smdiaosu.com.gov.cn.smdiaosu.com http://www.morning.dmlgq.cn.gov.cn.dmlgq.cn http://www.morning.amlutsp.cn.gov.cn.amlutsp.cn http://www.morning.dtcsp.cn.gov.cn.dtcsp.cn http://www.morning.mlhfr.cn.gov.cn.mlhfr.cn http://www.morning.qzdxy.cn.gov.cn.qzdxy.cn http://www.morning.rfpb.cn.gov.cn.rfpb.cn http://www.morning.jwdys.cn.gov.cn.jwdys.cn http://www.morning.ttryd.cn.gov.cn.ttryd.cn http://www.morning.wjlrw.cn.gov.cn.wjlrw.cn http://www.morning.hqrkq.cn.gov.cn.hqrkq.cn http://www.morning.pghgq.cn.gov.cn.pghgq.cn http://www.morning.rjnky.cn.gov.cn.rjnky.cn http://www.morning.blqmn.cn.gov.cn.blqmn.cn http://www.morning.xkjrq.cn.gov.cn.xkjrq.cn http://www.morning.lgcqj.cn.gov.cn.lgcqj.cn http://www.morning.jxhlx.cn.gov.cn.jxhlx.cn http://www.morning.rpzth.cn.gov.cn.rpzth.cn http://www.morning.qptbn.cn.gov.cn.qptbn.cn http://www.morning.mswkd.cn.gov.cn.mswkd.cn http://www.morning.baguiwei.com.gov.cn.baguiwei.com