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

个人网站可以做百度推广么网络安全工程师年薪

个人网站可以做百度推广么,网络安全工程师年薪,做公众号好还是网站好,西安互联网网站搭建公司排名该项目介绍了如何使用 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.yayakq.cn/news/580321/

相关文章:

  • 网站制作与网页设计课程设计wordpress免费资源模板
  • php 企业网站源码西城区好的网站建设多少钱
  • 电脑游戏网站建设wap网
  • 做内衣模特接广告网站wordpress4.9.8漏洞
  • 新乡手机网站建设官网wordpress login to view all
  • 佛山公司网站建设四川网站营销seo费用
  • 网站 昆明wordpress本地很慢
  • 上海专业做网站电话定制网站平台的安全设计
  • 镇平做网站苏州信息造价网
  • 专做网站的公司wordpress安装插件
  • 建设网站服务请示seo网站排名的软件
  • 北京建站模板企业软件系统开发在哪儿
  • 找个免费的网站网站建设 电话咨询
  • c 网站开发 书网页与网站的关系
  • 广州培训+网站开发容桂做网站
  • 网站开发绑定微信qq注册wordpress 展示模板下载
  • 网站建设图片如何加载藁城 网站
  • 湖南手机版建站系统哪家好东莞销售网站设计
  • 手风琴网站模板深圳燃气公司电话95511
  • 做直播网站有市场吗网站备案查询站长工具
  • 影视自助建站官网素材网哪个好
  • 网站制作与网页设计课程设计商店建筑设计
  • 网站承建商有哪些网站建设 军报
  • 福永专业外贸网站建设公司律师用的网站模板
  • 做低价的跨境电商网站郑州seo技术培训班
  • 网站页脚怎么做能好看点怎样建设一个网站教学
  • 网站建设方案书doc模板中企动力邮箱登陆首页
  • 襄阳住房城乡建设厅官方网站南昌企业建站模板
  • 深圳建设厅官方网站西安哪家公司做网站
  • 综合网站系统中国基建人才库证书查询