tag 标签: cpld/fpga

相关博文
  • 热度 18
    2015-3-24 13:54
    1195 次阅读|
    0 个评论
       引言: 数字滤波器是语音与图像处理、模式识别、雷达信号处理、频谱分析等应用中的一种基本的处理部件,它能满足波器对幅度和相位特性的严格要求,避免模拟滤波器所无法克服的电压漂移、温度漂移和噪声等问题。有限冲激响应(FIR)滤波器能在设计任意幅频特性的同时保证严格的线性相位特性。   一、FIR数字滤波器   FIR滤波器用当前和过去输入样值的加权和来形成它的输出,如下所示的前馈差分方程所描述的。   FIR滤波器又称为移动均值滤波器,因为任何时间点的输出均依赖于包含有最新的M个输入样值的一个窗。由于它的响应只依赖于有限个输入,FIR滤波器对一个离散事件冲激有一个有限长非零响应,即一个M阶FIR滤波器对一个冲激的响应在M个时钟周期之后为零。   FIR滤波器可用图1所示的z域块图来描述。   其中每个标有z-1的方框都代表了有一个时钟周期延时的寄存器单元。这个图中标出了数据通道和必须由滤波器完成的操作。滤波器的每一级都保存了一个已延时的输入样值,各级的输入连接和输出连接被称为抽头,并且系数集合{hk}称为滤波器的抽头系数。一个M阶的滤波器有M+1个抽头。通过移位寄存器 用每个时钟边沿n(时间下标)处的数据流采样值乘以抽头,并且求和得到输出yFIR 。滤波器的加法和乘法必须足够快,在下一个时钟来到之前形成y 。并且在每一级中都必须测量它们的大小以适应他们数据通道的宽度。在要求精度的实际应用中,Lattice结构可以减少有限字长的影响,但增加了计算成本。一般的目标是尽可能快地滤波,以达到高采样率。通过组合逻辑的最长信号通路包括M级加法和一级乘法运算。FIR结构指定机器的每一个算术单元有限字长,并且管理运算过程中数据流。   二、FIR数字滤波器设计的实现   目前FIR滤波器的实现方法有三种:利用单片通用数字滤波器集成电路、DSP器件和可编程逻辑器件实现。单片通用数字滤波器使用方便,但由于字长和阶数的规格较少,不能完全满足实际需要。使用DSP器件实现虽然简单,但由于程序顺序执行,执行速度必然不快。FPGA/CPLD有着规整的内部逻辑阵列和丰富的连线资源,特别适合于数字信号处理任务,相对于串行运算为主导的通用DSP芯片来说,其并行性和可扩展性更好。但长期以来,FPGA/CPLD一直被用于系统逻辑或时序控制上,很少有信号处理方面的应用,其原因主要是因为在FPGA/CPLD中缺乏实现乘法运算的有效结构。   现在的FPGA产品已经能够完全胜任这种任务了。其中Altera公司的Stratix系列产品采用1.5V内核,0.13um全铜工艺制造,它除了具有以前Altera FPGA芯片的所有特性外,还有如下特点:芯片内有三种RAM块,即512bit容量的小RAM(M512)、4KB容量的标准RAM(M4K) 、512KB的大容量RAM(MegaRAM)。内嵌硬件乘法器和乘加结构的DSP块,适于实现高速信号处理;采用全新的布线结构,分为三种长度的行列布线,在保证延时可预测的同时增加布线的灵活性;增加片内终端匹配电阻,提高信号完整性,简化PCB布线;同时具有时钟管理和锁相环能力。   FIR滤波器的Verilog HDL设计实例   1、设计意图   本例主要是在Stratix器件内实现基本有限脉冲响应滤波器。   FIR的基本结构包括一系列的乘法和加法。FIR的运算可用式(1)的方程描述,现重写如下:   一个L=8的FIR设计如图2,利用了输入的8个样本。因此称之为8抽头滤波器。该结构是有一个移位寄存器,乘法器和加法器组成的,可实现L=8阶的FIR。其数据通道必须足够宽,以适应乘法器和加法器的输出。这些采样值被编码为有限字长的形式,然后通过M个寄存器并行移动。可见用一个MAC级连链就可以构成这种机器。每个寄存器提供一个单位样本内延迟。这些延迟输入与各自的系数相乘,然后叠加得到输出。图2所示为基于MAC的8阶FIR数字滤波器结构   在该设计中有八个抽头,各抽头有18位输入和滤波器系数。由于一个DSP块可以支持4个18位输入的分支,所以设计需要2个DSP块。输入数据串行加载到DSP块中,DSP内部的移入/移出寄存器链用于产生延迟。滤波器系数从TriMatrix™ 的ROM存储器中加载。   2、Verilog HDL代码编写风格   HDL代码编写应该具有很好的易读性和可重用性,而自顶向下的分割方法可以帮助我们达到最佳的结果。HDL代码在达到功能的情况下要尽可能的简洁,尽量避免使用带有特殊库单元的实例,因为这样会使得整个进程变得不可靠。   在本设计中,我们将设计划分成一个顶级文件和三个次级文件,并且调用了QuartusII中的MegaFunction功能辅助完成整个设计。   图3显示FIR滤波器的顶级方块图   表1:FIR滤波器的设计范例的端口列表       3、验证仿真   完全可综合设计的一个优点就是同样的HDL代码能够用于验证和综合。在使用HDL代码之前必须要验证设计的功能,最好且最简单的方法就是利用验证工具,其次是利用仿真工具作有目的的仿真。   QuartusII内部带有仿真器,只要通过建立正确的Vector Waveform File(向量波形文件)就可以开始仿真了。图4所示为QuartusII内部仿真器得到的8阶FIR的脉冲响应波形。   五、结论   利用Verilog HDL设计数字滤波 器的最大优点就是可使设计更加灵活。比较硬件电路图设计,Verilog HDL语言设计的参数可以很容易在Verilog程序中更改,通过综合工具的简化和综合即可以得到电路图,其效率要高出利用卡诺图进行人工设计许多。而且编译过程也非常简单高效。优秀编码风格能够在综合过程中节省芯片使用的单元,从而降低设计成本。   参考文献:    . 夏宇闻。VerilogHDL数字系统设计教程,北京航空航天大学出版社,北京. 2003.    . Altera Corporation. Introduction to QuartusII. 2003    . Michael D. Ciletti. Advanced Digital Design with Verilog HDL. Prentice Hall, NJ.2005.    .彭保等.基于VerilogHDL的FPGA设计. 微计算机信息, 2004年第20卷第10期
  • 热度 29
    2014-8-10 10:44
    2215 次阅读|
    5 个评论
            一直很想学FPGA,去年11月份买了一套FPGA的开发板,玩了没两天,换了新的工作,那套开发板也束之高阁了。最近公司做了一个《时间管理》的培训,发现自己这一年总是在浪费时间没有什么进步,很后悔。然后决定好好学习一下特权同学的《深入浅出玩转FPGA》那套视频,因为还有些基础在,就直接跳到lesson12—乘法器设计实验。   看特权同学的视频,一直没有弄明白最关键的乘法操作的两句话(红色字体)。 else if (i 5'd0 i 5'd16) begin if(areg )   yout_r = {1'b0,yout_r +breg,yout_r }; else               yout_r = yout_r 1; end else if (i == 5'd16 areg )  yout_r = yout_r + breg; 然后自己在在草稿纸上慢慢演算,弄明白了二进制乘法是怎么相乘的。 我们以四位数乘以四位数举例:用4位二进制乘数的最高位乘以被乘数时,得出的结果最高只可能出现在第7位上(从广义上说就是结果的次高位上),所以第八位(广义上说就是最高位)只是用来准备存放进位的。 1010(被乘数) X1011(乘数) --------------------------- 乘数的最低位为1      得到0101 0000(右移累加) 乘数的次低位为1      得到0111 1000(右移累加) 乘数的第三位为0      得到0011 1100(右移) 乘数的最高位为1      得到0110 1110(右移累加) 我总结的规律就是乘数位上为1,结果先右移一位,次高位开始累加乘数。                                乘数位上为0,结果就只右移一位。 我感觉我总结的规律与特权同学的不一样,我先验证我所得到规律是否正确。 我写的乘法器的源码: module ex(               clk,rst_n,               ain,bin,start,yout,done               ); input clk,rst_n,start; input ain; input bin; output done; output yout; reg areg; reg breg; reg yout_r; reg done_r; reg i; always @(posedge clk or negedge rst_n)       if(!rst_n) i = 5'd0;            else if(start == 1 i=5'd16) i = i + 1'b1;            else if(!start) i = 5'd0;            always @(posedge clk or negedge rst_n)      if(!rst_n) done_r = 1'b0;            else if(i == 5'd16) done_r = 1'b1;            else if(i == 5'd17) done_r = 1'b0;   assign done = done_r;       always @(posedge clk or negedge rst_n) begin          if(!rst_n) begin                             areg = 16'h0000;                             breg = 16'h0000;                             yout_r = 32'h00000000;                    end          else if(start) begin                                        if(i == 5'd0) begin                                                    areg = ain;                                                breg = bin;                                      end                             else if(i 5'd0 i 5'd17) begin                                                if(areg ) yout_r = {1'b0,yout +breg,yout_r };                                                  else yout_r = yout_r1;                                             end                    end end assign yout = yout_r; endmodule   testbench: module ex_tb; reg clk; reg rst_n;         reg start; reg ain; reg bin;   wire yout; wire done;   ex i_ex (        .clk       (clk),        .rst_n     (rst_n),       .ain       (ain),       .bin       (bin),       .start      (start),       .yout      (yout),       .done      (done) );   initial begin          clk = 0;          forever          #10 clk = ~clk;  end   initial begin          rst_n = 1'b0;          start = 1'b0;          ain = 16'd0;          bin = 16'd0;          #1000;          rst_n = 1'b1;                      #1000;          ain = 16'd65535;          bin = 16'd32768;          #100;          start = 1'b1;          #4500;          start = 1'b0;          #1000_000;          $stop; end endmodule modelsim跑出来的结果: 计算器所得的结果 说明我的代码应该完全正确。 特权同学代码仿真出来的结果: 发现是错误的。 特权同学的代码错在哪儿?以下是网友的分析: 细心的读者估计已经发现{1'b0,yout +breg,yout_r }这条语句中位数怎么算都是31位啊,明明应该是32位的嘛(视频里也说是32位的啊)为什么会出现这个bug呢? 这里,有些网友是这样解释的yout +breg这两个16位数相加如果足够大,肯定是会产生进位的,所以就成了17位。呵呵,现在刚好17+14+1=32位了吧。 但是这个解释有一个很明显的bug:那要是没有进位呢?不还是16位的吗? 笔者认真考虑了一个晚上想了很多解释最终觉得以下两个解释,虽然自己也不是很有信心,但勉强可以支撑一下这个算法: 1,对于verilog语言“+”会产生一个一个加法器,而加法器都是会带进位位的,所以yout +breg会自动产生一个进位位,变成17位。 2,即使上面一个说法不成立,那么当{...}中不足32位时应该会在最高位自动补0或者X吧,这样最终依然是32位。并且不影响后面的计算结果。 对于这样两种猜想,由于本人能力有限,且刚刚接触FPGA所以不敢保证不是谬论,还希望高手们要多多指教。 上面啰嗦了这么多,其实只是对特权大哥代码的一个解读,真正有问题的是下一句: 根据上面总结出的那个规律,最高位只是用来进位用的那么这句代码: yout_r =yout_r +breg; 就明显有问题了,如果两个加数相加产生进位该怎么办呢?     暂时就写这么多,有什么不对的地方欢迎大家批评指正!!!
  • 热度 17
    2012-5-11 20:02
    2846 次阅读|
    2 个评论
           Error: Peak virtual memory: 171 megabytes  Error: Processing ended: Fri May 11 10:36:21 2012 相信有很多和我一样同学遇到过很多这样的问题,开始遇到这个问题的时候我也感觉很麻烦,在网上搜索资料,刚才在网上搜到的解决办法是“Assignments--Settings-- EDA Tool Settings   -- Design Entry Synthesis--Tool name   下设置正确的综合工具。按照LMF文件设置对应的工具名称。”我也试过好多次,编译的时候还是一样出现上面的Error,最后我把那个Message窗口滚动了一下,看到了上面有两个Error,我把上面的两个Error改正了之后,然后编译没有报错。希望大家有问题共同讨论,有好的问题解决办法上传,大家一起进步。   小哲同学。 希望大家有问题共同讨论,有好的问题解决办法上传,大家一起进步。 小哲同学。