关键字:FPGA 滤波器 Xilinx
利用FPGA进行数字信号处理时,信号中的直流分量通常需要去除,而直流分量在AD前段就存在,如果采用模拟电路去除直流分量比较复杂,因此通常在AD后端数字域去除直流分量。在FPGA中,常规去直流的方法是先对信号进行累加,然后对累加值进行移位即可得到直流分量,如累加8192个数据,则直流分量可由累加值右移13位得到。
本文介绍一种根据Xilinx FPGA中DSP48E1资源设计的去直流模块,其基本原理采用一阶滤波器,如图1所示,通过一个一阶RC电路,在V0端可等效一个低通滤波器,得到直流分量。
![](http://image.ednchina.com/2013/11/EDNCOL_2013NOV19_PMA_POWER_AN_01.JPG)
由上式可推导出,
![](http://data:image/jpeg;base64,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)
定义系数,![](http://data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAcFBQYFBAcGBQYIBwcIChELCgkJChUPEAwRGBUaGRgVGBcbHichGx0lHRcYIi4iJSgpKywrGiAvMy8qMicqKyr/2wBDAQcICAoJChQLCxQqHBgcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKir/wAARCAA6AEsDASIAAhEBAxEB/8QAGgABAAMBAQEAAAAAAAAAAAAAAAQFBgIDCP/EAC8QAAEDAwMDAQcFAQEAAAAAAAECAwQABREGEiETMUEiFBYyUVaU0QdCYYGRFYL/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A+kaUpQKUpQKVy4VhtRbSFLAO1KjgE+AT4rFQNYanuFhN4GnbPHhp6u9ci+LRsDalJUSfZ8AZSTnPag29KxzWrr/JtFtktaZYZfkwjNmImz1sNQUHlCVOFk5WRu3JwNu057gnvTeq7/eZcFNw0y3BizI6ny8iatxTIHwhSVMoGSfAUT5xig11KUoPN99uNGcfeJDbSCtZCSSABk8Dk/1XlbrhFu1tYn254PxZKA404AQFJPY881U64uj1o0bPfidb2t1AjRugMuBxwhCVJHkp3bsDwk1Ufp4J79nhS13NtuCtklm0JjISqMjOEpUr4twxg/zQbalYS+a2mW29yYbVzsbSGl4CJDUguJ4HcpGP8rS2W7OT9Mt3J5bMtZQtRMFC9q9qiMISv1Z4xz5oLasHPsk17VsmxIbxY7qtE+V3IIRw82eMYcPRSUHgoLh4q398x9Oag+wP5p75j6c1B9gfzQR/1Fu7UDTnsCy6F3RYjEojrcSGiR1iopSdo6e4A98qGPmNRFQ03EZQwCGkoSEZz8IHHes/75j6c1B9gfzT3zH05qD7A/mg0tKqbTfxdpK2RarpC2I3b5kbppPIGAc9+atqCPJgxpjsZ2SylxcR3rME/sXtUjcP/K1D+68LfY7ba5cuTAiIZemOl19YyStROSee3POBxUTSrst60PLnznprqZ0poOOobSQlt5baRhCUjsgE8dyfGALqgUpSgzV+vd7jajhWqwxbfIL7C3n1SnloLCU9lEJSfSTwD8wam2jUUefpyNdZhTDS8vpEOK9IX1C3wfkVDj+CKws63q1ncr5cREu8aXCKBb0SY8qIl1pHxoVgJDiVq3EJyTyM47VtzJ/6WjkOW+yLWJLAbRbpzXs4QFekpcQoelKR3ABOBwFcAhaqmR0TW4inkCQ4hTiGs+pSUkAnHyGR/tUC79d7lJkI01bY70eK6ppyTMf2JdUk4UlASCcg+SAD86absc3T89xmQRcESGUE3EqIcQUAJ6SgpROzuUYJ7q3ZVla66wXN7TFhi6dftNyk3KKjpI6EJxUd45O1Qf29NKTn9xBHkA8UF3pO+TNRWhyfNtiraDIcbZaW4FrKEHaVKxwDuChj5AHzV3XDJdLDZkJQl0pG9KFFSQrHIBIGRnzgV3QRYEBq2x1R4ylhgKy00SNrKcD0I44SDkgHOM4GEgASqUoFKUoFKUoFKUoFKUoP/9k=)
由此可得到下式:![](http://image.ednchina.com/2013/11/xEDNCOL_2013NOV19_PMA_POWER_AN_04.JPG.pagespeed.ic.IvxpJ4uWpO.jpg)
由上式可得到如图2所示结构
![](http://image.ednchina.com/2013/11/EDNCOL_2013NOV19_PMA_POWER_AN_05.JPG)
仔细观察发现图2中结构与Xilinx FPGA的DSP48E1结构十分相似,如图3所示,两个结构做了类比,其中Vi - Vo的减法可由DSP48E1中的Pre-Adder实现,k*(vi - vo)的乘法可由DSP48E1中的Multipler实现,而Vo + k*(vi - vo)加法可由DSP48E1中的Accumulator实现。因此实现这个去直流模块只需1个DSP48E1资源,并且在Xilinx 7系列FPGA中,DSP48E1最大支持25-bit的Pre-adder、25*18-bit的Multipler和48-bit的Accumulator,基本可满足常规处理。
![](http://image.ednchina.com/2013/11/EDNCOL_2013NOV19_PMA_POWER_AN_06.JPG)
具体实现:
在ISE的HDL language template中可以找到DSP48的宏定义,这边需要用到ADDMACC_MACRO,只需要将这个宏模板拷贝到程序中直接例化即可调用DSP48,去直流模块的DSP48E1实现代码如下所示:
module DCOff_DSP(
input clk,
input rst,
input [15:0] din,
output [15:0] dc
);
wire signed [31:0] PRODUCT;
wire signed [15:0] K;
wire signed [31:0] ACOUT;
assign K=16'h0085;
ADDMACC_MACRO #(
.DEVICE("7SERIES"), // Target Device: "VIRTEX6", "SPARTAN6", "7SERIES"
.LATENCY(4), // Desired clock cycle latency, 0-4
.WIDTH_PREADD(16), // Pre-adder input width, 1-25
.WIDTH_MULTIPLIER(16), // Multiplier input width, 1-18
.WIDTH_PRODUCT(32) // MACC output width, 1-48
) ADDMACC_MACRO_inst (
.PRODUCT(PRODUCT), // MACC result output, width defined by WIDTH_PRODUCT parameter
.CARRYIN(1'b0), // 1-bit carry-in input
.CLK(clk), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.LOAD(1'b1), // 1-bit accumulator load input
.LOAD_DATA(PRODUCT), // Accumulator load data input, width defined by WIDTH_PRODUCT parameter
.MULTIPLIER(K), // Multiplier data input, width defined by WIDTH_MULTIPLIER parameter
.PREADD2(-PRODUCT[31:16]), // Preadder data input, width defined by WIDTH_PREADD parameter
.PREADD1(din), // Preadder data input, width defined by WIDTH_PREADD parameter
.RST(rst) // 1-bit active high synchronous reset
);
assign dc=PRODUCT[31:16];
endmodule
|