当前位置: 首页 > news >正文

霍邱网站建设seo商学院

霍邱网站建设,seo商学院,做网站后端需要什么语言,wordpress手机自动跳转二级该项目介绍了如何使用 Verilog 实现具有预生成系数的简单 FIR 滤波器。 绪论 不起眼的 FIR 滤波器是 FPGA 数字信号处理中最基本的模块之一,因此了解如何将具有给定抽头数及其相应系数值的基本模块组合在一起非常重要。因此,在这个关于 FPGA 上 DSP 基础…

c6417f58cbac91a3d14176b8df9b8854.png

该项目介绍了如何使用 Verilog 实现具有预生成系数的简单 FIR 滤波器。

76a999d1e68cea49aaa3fe48972bd0ca.png

绪论

不起眼的 FIR 滤波器是 FPGA 数字信号处理中最基本的模块之一,因此了解如何将具有给定抽头数及其相应系数值的基本模块组合在一起非常重要。因此,在这个关于 FPGA 上 DSP 基础实用入门的教程中,将从一个简单的 15 抽头低通滤波器 FIR 开始,在 Matlab 中为其生成初始系数值,然后转换这些值用于编写 Verilog 模块。

有限脉冲响应或 FIR 滤波器定义为脉冲响应在特定时间段内稳定为零值的滤波器。脉冲响应稳定到零所花费的时间与滤波器阶数(抽头数)直接相关,滤波器阶数是 FIR 的基础传递函数多项式的阶数。FIR 的传递函数不包含反馈,因此如果输入一个值为 1 的脉冲,然后输入一串零值,输出将只是滤波器的系数值。

滤波器的作用基本都是用于信号调节,主要集中在选择滤除或允许通过哪些频率。最简单的例子之一是低通滤波器,它允许低于某个阈值(截止频率)的频率通过,同时大大衰减高于该阈值的频率,如下图所示。

7a2d3a5f49ef1d1acd6f622c33ef348b.png

该项目的主要重点是在 HDL(具体为 Verilog)中实现 FIR,它可以分解为三个主要逻辑组件:一个循环缓冲器,用于将每个样本计时到适当地考虑了串行输入的延迟、每个抽头系数值的乘法器以及每个抽头输出的求和结果的累加器。

39ab59d221fa437ca54ed1cc456eac1f.png

由于本项目专注于 FPGA 逻辑中 FIR 的设计机制,所以只是使用 Simulink 中的 FDA 工具和 Matlab 为低通滤波器插入一些简单参数,然后使用生成的系数值放到 Verilog 模块中完成滤波器的设计(在后面的步骤中完成)。

dbb451b344f2df421639d707fc7020d1.png

选择实现一个简单的 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 项目中添加源文件。

dce2efd47b557898c3efda49058735a4.png

在确定 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 == 1'b1)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 == 1'b1)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 == 1'b1)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 模块还必须能够与其主端接口上的上游设备以同样的方式运行。

5074f17104d4886628ee02db551971d1.png

以下是 FIR 模块的逻辑设计概述:

322828b1ab5d72fcda50c82f9084be6e.png

请注意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 <= 4'hf;endalways @ (posedge clk)beginif (s_axis_fir_tlast == 1'b1)beginm_axis_fir_tlast <= 1'b1;endelsebeginm_axis_fir_tlast <= 1'b0;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 = 16'hFC9C;  // twos(-0.0265 * 32768) = 0xFC9Cassign tap1 = 16'h0000;  // 0assign tap2 = 16'h05A5;  // 0.0441 * 32768 = 1445.0688 = 1445 = 0x05A5assign tap3 = 16'h0000;  // 0assign tap4 = 16'hF40C;  // twos(-0.0934 * 32768) = 0xF40Cassign tap5 = 16'h0000;  // 0assign tap6 = 16'h282D;  // 0.3139 * 32768 = 10285.8752 = 10285 = 0x282Dassign tap7 = 16'h4000;  // 0.5000 * 32768 = 16384 = 0x4000assign tap8 = 16'h282D;  // 0.3139 * 32768 = 10285.8752 = 10285 = 0x282Dassign tap9 = 16'h0000;  // 0assign tap10 = 16'hF40C; // twos(-0.0934 * 32768) = 0xF40Cassign tap11 = 16'h0000; // 0assign tap12 = 16'h05A5; // 0.0441 * 32768 = 1445.0688 = 1445 = 0x05A5assign tap13 = 16'h0000; // 0assign tap14 = 16'hFC9C; // 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 == 1'b0) //if (reset == 1'b0 || tvalid_in == 1'b0)beginbuff_cnt <= 4'd0;enable_fir <= 1'b0;in_sample <= 8'd0;endelse if (m_axis_fir_tready == 1'b0 || s_axis_fir_tvalid == 1'b0)beginenable_fir <= 1'b0;buff_cnt <= 4'd15;in_sample <= in_sample;endelse if (buff_cnt == 4'd15)beginbuff_cnt <= 4'd0;enable_fir <= 1'b1;in_sample <= s_axis_fir_tdata;endelsebeginbuff_cnt <= buff_cnt + 1;in_sample <= s_axis_fir_tdata;endend   always @ (posedge clk)beginif(reset == 1'b0 || m_axis_fir_tready == 1'b0 || s_axis_fir_tvalid == 1'b0)begins_axis_fir_tready <= 1'b0;m_axis_fir_tvalid <= 1'b0;enable_buff <= 1'b0;endelsebegins_axis_fir_tready <= 1'b1;m_axis_fir_tvalid <= 1'b1;enable_buff <= 1'b1;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 == 1'b1)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 == 1'b1)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 == 1'b1)beginm_axis_fir_tdata <= acc0 + acc1 + acc2 + acc3 + acc4 + acc5 + acc6 + acc7 + acc8 + acc9 + acc10 + acc11 + acc12 + acc13 + acc14;endend     endmodule

创建仿真文件

要测试 FIR 模块,需要创建一个测试平台作为其仿真源:

c1cd20f7f71d7f77fedf8f2676096df2.png

在 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 = 4'd4;parameter init               = 5'd0;parameter sendSample0        = 5'd1;parameter sendSample1        = 5'd2;parameter sendSample2        = 5'd3;parameter sendSample3        = 5'd4;parameter sendSample4        = 5'd5;parameter sendSample5        = 5'd6;parameter sendSample6        = 5'd7;parameter sendSample7        = 5'd8;/* This state machine generates a 200kHz sinusoid. */always @ (posedge clk or posedge reset)beginif (reset == 1'b0)begincntr <= 4'd0;s_axis_fir_tdata <= 16'd0;state_reg <= init;endelsebegincase (state_reg)init : //0begincntr <= 4'd0;s_axis_fir_tdata <= 16'h0000;state_reg <= sendSample0;endsendSample0 : //1begins_axis_fir_tdata <= 16'h0000;if (cntr == wvfm_period)begincntr <= 4'd0;state_reg <= sendSample1;endelsebegin cntr <= cntr + 1;state_reg <= sendSample0;endend sendSample1 : //2begins_axis_fir_tdata <= 16'h5A7E; if (cntr == wvfm_period)begincntr <= 4'd0;state_reg <= sendSample2;endelsebegin cntr <= cntr + 1;state_reg <= sendSample1;endend sendSample2 : //3begins_axis_fir_tdata <= 16'h7FFF;if (cntr == wvfm_period)begincntr <= 4'd0;state_reg <= sendSample3;endelsebegin cntr <= cntr + 1;state_reg <= sendSample2;endend sendSample3 : //4begins_axis_fir_tdata <= 16'h5A7E;if (cntr == wvfm_period)begincntr <= 4'd0;state_reg <= sendSample4;endelsebegin cntr <= cntr + 1;state_reg <= sendSample3;endend sendSample4 : //5begins_axis_fir_tdata <= 16'h0000;if (cntr == wvfm_period)begincntr <= 4'd0;state_reg <= sendSample5;endelsebegin cntr <= cntr + 1;state_reg <= sendSample4;endend sendSample5 : //6begins_axis_fir_tdata <= 16'hA582; if (cntr == wvfm_period)begincntr <= 4'd0;state_reg <= sendSample6;endelsebegin cntr <= cntr + 1;state_reg <= sendSample5;endend sendSample6 : //6begins_axis_fir_tdata <= 16'h8000; if (cntr == wvfm_period)begincntr <= 4'd0;state_reg <= sendSample7;endelsebegin cntr <= cntr + 1;state_reg <= sendSample6;endend sendSample7 : //6begins_axis_fir_tdata <= 16'hA582; if (cntr == wvfm_period)begincntr <= 4'd0;state_reg <= sendSample0;endelsebegin cntr <= cntr + 1;state_reg <= sendSample7;endend                     endcaseendendendmodule

运行行为仿真

FIR 模块及其测试平台文件就位后,从 Flow Navigator 窗口启动 Vivado 中的仿真器,选择 Run Behavioral Simulation 选项。

59568d4dc6b26b5f2332b1f68b771f25.png

如行为仿真所示,FIR 正确过滤信号并正确响应 AXI 流信号。

d0ac89678dd49fc8284a31e328f49425.png

总结

代码都在上面大家有兴趣可以自行运行,但是大家可能会注意到,这个 FIR 模块在设计上运行综合和实现时时序应该是不能通过的。我们将在下一篇文章中详细介绍如何在无法满足时序要求时重新设计你的设计~

297bfa037f7e67437a996ec3b8991360.png
http://www.mmbaike.com/news/26382.html

相关文章:

  • 廊坊网站建设方案托管三生网络营销靠谱吗
  • 兼职做任务的网站市场营销专业课程
  • 小说网站怎么做流量吗企业网站网页设计
  • 网站开发自适应不同分辨率长沙网站seo服务
  • 湖北微网站建设电话百度推广账号怎么申请
  • php动态网站开发的总结株洲做网站
  • 番禺建设银行网站首页seo交流论坛seo顾问
  • 网站建设案例精英惠州seo外包平台
  • 转运公司网站制作关键词竞价排名是什么意思
  • 签名设计网站品牌策划方案怎么写
  • 优秀的设计网站有哪些内容广告视频
  • 电影网站盗链怎么做免费的推广软件下载
  • 网站建设公司海外武汉网络推广有哪些公司
  • 邢台做网站的那好网络营销方式有哪些?
  • 浙江坤宇建设有限公司 网站seo搜索引擎优化步骤
  • 企业网站管理系统视频教程班级优化大师下载安装app
  • 金州网站建设百度的网址怎么写
  • 一个wordpress程序搭建多个网站百度推广如何办理
  • 哪些大学网站做的比较好网站建设方案范文
  • 温州专业微网站制作电话网络媒体推广产品
  • 著名的深圳网站建设深圳关键词优化平台
  • 昆山广告制作公司百度搜索引擎优化的养成良好心态
  • 网站的推广和优化方案网络平台有哪些
  • 集客营销软件官方网站太原seo霸屏
  • 免费公司介绍网站怎么做一站式媒体发稿平台
  • 网站域名区别seo排名影响因素主要有
  • 建网站需要学习什么在线发外链工具
  • 搭建品牌电商网站怎么做优化网站排名方法
  • 阿里香港主机可以做辅助网站吗北京seo专员
  • 网站备案做优惠券秦皇岛百度推广