{"id":461,"date":"2025-07-19T17:47:57","date_gmt":"2025-07-19T09:47:57","guid":{"rendered":"https:\/\/blog.keruone.cn\/?p=461"},"modified":"2025-07-21T14:05:18","modified_gmt":"2025-07-21T06:05:18","slug":"pll_in_fpga","status":"publish","type":"post","link":"https:\/\/blog.keruone.cn\/index.php\/2025\/07\/19\/pll_in_fpga\/","title":{"rendered":"\u57fa\u4e8e FPGA \u7684 PLL \u8c03\u8bd5\u8bb0\u5f55"},"content":{"rendered":"<h1>\u57fa\u4e8e FPGA \u7684 PLL \u8c03\u8bd5\u8bb0\u5f55<\/h1>\n<p>\u5f00\u59cb\u65f6\u95f4\uff1a2025.7.17<br \/>\n\u7ed3\u675f\u65f6\u95f4\uff1a2025.7.19<br \/>\n\u64b0\u5199\u8005: Keruone<br \/>\n\u4ee3\u7801\u4e3b\u8981\u7f16\u5199\u8005\uff1aKeruone\u3001Friday<\/p>\n<p>\u7279\u522b\u9e23\u8c22: \u5f90\u6d69\u4fca\u3001\u65b9\u777f\u3001\u91d1\u5784\u665f<\/p>\n<p><strong>\u6458\u8981<\/strong>\uff1a\u672c\u535a\u5ba2\u8bb0\u5f55\u4e86\u57fa\u4e8e FPGA \u7684\u9501\u76f8\u73af\uff08PLL\uff09\u8c03\u8bd5\u8fc7\u7a0b\uff0c\u5305\u62ec\u9501\u76f8\u73af\u7684\u57fa\u672c\u539f\u7406\u3001\u6a21\u5757\u8bbe\u8ba1\u4e0e\u5b9e\u73b0\u3001\u4ee3\u7801\u5b9e\u73b0\u4ee5\u53ca\u8c03\u8bd5\u7ecf\u9a8c\u3002\u535a\u5ba2\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u9501\u76f8\u73af\u7684\u6838\u5fc3\u6a21\u5757\uff0c\u5982\u9274\u76f8\u5668\uff08PD\uff09\u3001\u6570\u5b57\u632f\u8361\u5668\uff08NCO\uff09\u548c FIR \u4f4e\u901a\u6ee4\u6ce2\u5668\uff0c\u5e76\u63d0\u4f9b\u4e86 Verilog \u4ee3\u7801\u5b9e\u73b0\u3002\u901a\u8fc7 FPGA \u5f00\u53d1\u677f\uff08Altera Cyclone IV\uff09\u5b9e\u73b0\u4e86\u5b8c\u6574\u7684\u9501\u76f8\u73af\u7cfb\u7edf\uff0c\u652f\u6301\u56fa\u5b9a\u9891\u7387\u548c\u52a8\u6001\u8c03\u6574\u7684\u9501\u76f8\u529f\u80fd\u3002<\/p>\n<p><strong>\u5173\u952e\u8bcd<\/strong>\uff1aFPGA\u3001\u9501\u76f8\u73af\uff08PLL\uff09\u3001\u9274\u76f8\u5668\uff08PD\uff09\u3001\u6570\u5b57\u632f\u8361\u5668\uff08NCO\uff09\u3001DDS\u3001FIR \u4f4e\u901a\u6ee4\u6ce2\u5668\u3001Verilog\u3001Quartus Prime\u3001\u9891\u7387\u63a7\u5236\u5b57\u3001\u76f8\u4f4d\u63a7\u5236\u5b57\u3001\u8c03\u8bd5\u8bb0\u5f55<\/p>\n<p><strong>\u76ee\u5f55<\/strong>\uff1a<br \/>\n<\/p>\n<hr \/>\n<h2>1. \u9501\u76f8\u73af\u539f\u7406\u6982\u8ff0<\/h2>\n<p>\u9501\u76f8\u73af\u7684\u539f\u7406\u5176\u5b9e\u7f51\u4e0a\u6709\u5f88\u591a\u8d44\u6599\uff0c\u8fd9\u91cc\u91cd\u590d\u7684\u5c31\u4e0d\u591a\u8d58\u8ff0\u4e86\uff0c\u5728\u8fd9\u91cc\u6211\u53ef\u80fd\u63d0\u53ca\u66f4\u591a\u7684\u662f\u81ea\u5df1\u7684\u7406\u89e3\u3002<\/p>\n<p>\u9996\u5148\uff0c\u6211\u4eec\u5148\u7b80\u5355\u4ecb\u7ecd\u4e00\u4e0b\u9501\u76f8\u73af\uff0c\u5b83\u7684\u6700\u76f4\u63a5\u7684\u7528\u9014\uff0c\u5c31\u662f\u8ba9\u8f93\u51fa\u4fe1\u53f7\u201c\u7d27\u7d27\u8ddf\u968f\u201d\u8f93\u5165\u4fe1\u53f7\u3002<\/p>\n<blockquote>\n<ul>\n<li>\uff08\u4f60\u5e94\u8be5\u77e5\u9053\uff0c\u4e0d\u540c\u7684\u8bbe\u5907\u5373\u4f7f\u8f93\u51fa\u540c\u6837\u7684\u9891\u7387\uff0c\u90a3\u4e5f\u4ecd\u7136\u4f1a\u6709\u51e0hz\u7684\u9891\u7387\u504f\u5dee\u3002\u53cd\u6620\u5728\u793a\u6ce2\u5668\u4e0a\uff0c\u5c31\u662f\u540c\u65f6\u663e\u793a\u8f93\u5165\u4fe1\u53f7\u548c\u8f93\u51fa\u4fe1\u53f7\u65f6\uff0c\u4f1a\u53d1\u73b0\u4e24\u4e2a\u4fe1\u53f7\u95f4\u4f1a\u5fae\u5fae\u79fb\u52a8\uff09<\/li>\n<\/ul>\n<\/blockquote>\n<ul>\n<li><strong><em>\u6ce8\u610f<\/em><\/strong>\uff1a\u4f60\u5e94\u8be5\u6ce8\u610f\u5230\uff0c\u6211\u8fd9\u91cc\u6240\u63d0\u53ca\u7684\u9501\u76f8\u73af\uff0c\u5b83\u7684\u8f93\u5165\u8f93\u51fa\u9891\u7387\u90fd\u662f\u975e\u5e38\u63a5\u8fd1\u7684\u3002\u90a3\u4f60\u5e94\u8be5\u6ce8\u610f\u5230\uff0c\u672c\u6587\u6240\u63d0\u53ca\u53ca\u8ba8\u8bba\u7684\u9501\u76f8\u73af\uff0c\u4e5f\u662f\u9891\u7387\u975e\u5e38\u63a5\u8fd1\u7684\u3002<br \/>\n> \u4e3a\u6b64\uff0c\u5982\u679c\u4f60\u60f3\u8981\u5b9e\u73b0\u9891\u7387\u53ef\u4ee5\u5927\u8303\u56f4\u53d8\u5316\u7684\u9501\u76f8\u73af\uff0c\u90a3\u4f60\u5e94\u8be5\u4f7f\u7528\u4e32\u53e3(\u5982SPI\u3001UART)\u6765\u901a\u4fe1\uff0c\u544a\u8bc9 fpga \u9891\u7387\u63a7\u5236\u5b57\u5927\u81f4\u8981\u4e3a\u591a\u5c11\uff0c\u518d\u8fdb\u884c\u5fae\u8c03\uff1b\u6216\u8005 FFT \u6765\u68c0\u6d4b\u51fa\u8f93\u5165\u9891\u7387\uff0c\u518d\u8c03\u6574 fpga \u9891\u7387\u63a7\u5236\u5b57\u3002\u6700\u540e\u518d\u8fdb\u884c\u9501\u76f8\u3002<br \/>\n> \u6216\u8005\u4f60\u53ef\u4ee5\u7f51\u4e0a\u518d\u641c\u5bfb\u641c\u5bfb\u770b\u770b\uff0c\u6709\u6ca1\u6709\u4ec0\u4e48\u66f4\u597d\u7684\u6cd5\u5b50\u3002<\/li>\n<\/ul>\n<p>\u90a3\u6211\u4eec\u8be5\u5982\u4f55\u5b9e\u73b0\u9501\u76f8\u5462\uff1f<br \/>\n\u5728\u56de\u7b54\u8fd9\u4e2a\u95ee\u9898\u4e4b\u524d\uff0c\u6211\u4eec\u5148\u60f3\u60f3\uff0c\u4e3a\u4ec0\u4e48\u53eb\u505a\u201c\u9501\u76f8\u73af\u201d\u800c\u4e0d\u662f\u201c\u9501\u9891\u73af\u201d\u3002<br \/>\n\u9501\u76f8\u9501\u76f8\uff0c\u987e\u540d\u601d\u4e49\uff0c\u5b83\u9501\u5b9a\u7684\u662f\u76f8\u4f4d\uff0c\u5c06\u8f93\u51fa\u548c\u8f93\u5165\u7684\u4fe1\u53f7\u7684<strong>\u76f8\u4f4d<\/strong>\u9501\u5728\u4e00\u8d77\uff0c\u800c\u9891\u7387\u53ea\u662f\u201c\u987a\u5e26\u201d\u7684\u3002\u901a\u8fc7\u7535\u8def\u7684\u53cd\u9988\uff0c\u63a7\u5236\u76f8\u4f4d\u8ddf\u968f\u3002<\/p>\n<h3>1.1 \u9274\u76f8\uff08PD\uff09<\/h3>\n<p>\u6839\u636e\u4e0a\u9762\u7684\u63cf\u8ff0\uff0c\u6211\u4eec\u53ef\u4ee5\u201c\u8fd1\u4f3c\u201d\u5047\u8bbe\uff0c\u5728\u6dfb\u52a0\u53cd\u9988\u56de\u8def\u524d\uff0c\u8f93\u5165\u548c\u8f93\u51fa\u7684\u4fe1\u53f7\u53ea\u6709\u76f8\u4f4d\u5dee\uff0c\u6ca1\u6709\u9891\u7387\u5dee\uff0c\u5373<br \/>\n<span class=\"katex math multi-line\">\\begin{aligned}<br \/>\ns_{in} &amp;= \\sin(\\omega_0 t + \\theta_{in}) &#92;<br \/>\ns_{out} &amp;= \\sin(\\omega_0 t + \\theta_{out})<br \/>\n\\end{aligned}<\/span><br \/>\n\u90a3\u4e48\uff0c\u6211\u4eec\u8be5\u5982\u4f55\u63d0\u53d6\u5176\u4e2d\u7684\u76f8\u4f4d\u4fe1\u53f7\u5462\uff1f\u8fd9\u4e2a\u65f6\u5019\uff0c\u6700\u76f4\u63a5\u7684\u529e\u6cd5\u5c31\u662f<strong>\u76f8\u79ef\u5316\u548c\u5dee<\/strong>+<strong>\u4f4e\u901a\u6ee4\u6ce2\u5668<\/strong>\u3002<br \/>\n<span class=\"katex math multi-line\">s_{in} \\cdot s_{out} = \\frac{1}{2} \\left[ \\cos\\left( \\theta_{in} &#8211; \\theta_{out} \\right) &#8211; \\cos\\left( 2\\omega_0 t + \\theta_{in} + \\theta_{out} \\right) \\right]<\/span><\/p>\n<blockquote><p>\n  \u5982\u679c\u5fd8\u8bb0\u4e86\u4ec0\u4e48\u662f\u79ef\u5316\u548c\u5dee\uff0c\u53ef\u4ee5\u53c2\u8003<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/baike.baidu.com\/item\/%E7%A7%AF%E5%8C%96%E5%92%8C%E5%B7%AE\/6973123\">\u767e\u5ea6\u767e\u79d1<\/a><\/p>\n<p>  \u6211\u4eec\u6765\u89c2\u5bdf\u4e00\u4e0b\uff0c\u53ef\u4ee5\u53d1\u73b0\uff0c\u8fd9\u91cc\u6709\u4e24\u4e2a\u5206\u91cf\uff1a<br \/>\n  &#8211; 1. \u4e0e\u76f8\u4f4d\u76f8\u5173\u7684\u76f4\u6d41\u5206\u91cf<br \/>\n  &#8211; 2. \u9ad8\u9891\u5206\u91cf\u3002\n<\/p><\/blockquote>\n<p>\u90a3\u8fd9\u4e2a\u65f6\u5019\u7406\u8bba\u4e0a\u5c06\u8f93\u51fa\u7684\u6ce2\u5f62<strong>\u76f8\u4e58<\/strong>\uff0c\u518d\u901a\u8fc7<strong>\u4f4e\u901a\u6ee4\u6ce2\u5668<\/strong>\uff0c\u6211\u4eec\u5c31\u5f97\u5230\u4e86\u4e0e\u76f8\u4f4d\u5dee\u76f8\u5173\u7684\u7535\u538b\u4fe1\u53f7<span class=\"katex math inline\">\\frac{1}{2}\\cos\\left( \\theta_{in} &#8211; \\theta_{out} \\right)<\/span>\u3002<br \/>\n\u8fd9\u4e2a\u4fe1\u53f7\u5f88\u5173\u952e\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u8fd9\u4e2a\u4fe1\u53f7\u6765\u5b9e\u73b0<strong>\u53cd\u9988<\/strong>\uff0c\u4ece\u800c\u5b9e\u73b0<strong>\u9501\u76f8<\/strong>\u3002<\/p>\n<p>\u7efc\u4e0a\uff0c\u672c\u6587 PD \u90e8\u5206\u5728 fpga \u4e2d\u5c06\u4f1a\u7528\u5230\u4e24\u4e2a\u6a21\u5757\uff1a<br \/>\n&#8211; 1. \u4e58\u6cd5\u5668<br \/>\n&#8211; 2. FIR II<\/p>\n<blockquote><p>\n  \u4e0a\u8ff0\u5185\u5bb9\u8be6\u89c1\u4ee3\u7801\u90e8\u5206<\/p>\n<p>  \u9644\uff0c\u4e3a\u4ec0\u4e48\u4f7f\u7528sin\u800c\u4e0d\u4f7f\u7528cos\uff1f\u6709\u4eba\u4f1a\u95ee\uff0c\u8fd9\u4e24\u4e2a\u4fe1\u53f7\u76f8\u4e58\u7684\u7ed3\u679c\u4e0d\u662f\u4e0d\u4e00\u6837\u5417\uff1f<br \/>\n  \u6211\u7684\u56de\u7b54\u662f\uff1a<\/p>\n<blockquote><p>\n    \u7406\u8bba\u4e0a\u8ba1\u7b97\u7684\u8868\u8c61\u662f\u4f1a\u4e0d\u4e00\u6837\uff0c\u4f46\u662f\u4f60\u9700\u8981\u6ce8\u610f\u5230\uff0c\u4e24\u4e2a\u4fe1\u53f7\u7684<strong>\u76f8\u4f4d\u5dee<\/strong>\u662f<strong>\u4e0d\u786e\u5b9a<\/strong>\u7684\uff0c\u4f60\u6bcf\u6b21\u4f7f\u7528\u8fd9\u4e2a\u9501\u76f8\u73af\u65f6\uff0c\u968f\u7740\u4f60\u7684\u53c2\u8003\u70b9\u4e0d\u540c\u3001\u4f7f\u7528\u7684\u65f6\u95f4\u4e0d\u540c\u3001\u5f00\u542f\u7684\u65f6\u95f4\u4e0d\u540c\uff0c\u76f8\u4f4d\u90fd\u662f\u4e0d\u540c\u7684\u3002<br \/>\n    \u90a3sin\u548ccos\u6709\u4ec0\u4e48\u533a\u522b\uff1f\u4e0d\u5c31\u4e00\u4e2a90\u5ea6\u76f8\u4f4d\u5dee\u5457\u3002\u8fd9\u653e\u5728\u4e0d\u786e\u5b9a\u7684\u521d\u59cb\u76f8\u4f4d\u4e2d\uff0c\u4e0d\u5c31\u52a0\u51cf90\u7684\u5173\u7cfb\uff0c\u5176\u5b9e\u662f\u6ca1\u6709\u4efb\u4f55\u5f71\u54cd\u7684\u3002<br \/>\n    \u6240\u4ee5\uff0c\u4e0d\u8981\u7ea0\u7ed3\u4e58sin\u8fd8\u662fcos\uff0c<strong>\u7b49\u4ef7<\/strong>\u7684\u3002\n  <\/p><\/blockquote>\n<\/blockquote>\n<h3>1.2 \u6570\u5b57\u632f\u8361\u5668(NCO)<\/h3>\n<p>\u524d\u6587\u4e00\u76f4\u5728\u63d0\u53ca\u8f93\u51fa\u4fe1\u53f7\uff0c\u4f46\u662f\u8f93\u51fa\u4fe1\u53f7\u662f\u54ea\u91cc\u6765\u7684\uff1f\u7b54\uff0c\u6765\u81ea\u6570\u5b57\u632f\u8361\u5668\u3002<br \/>\n\u6570\u5b57\u632f\u8361\u5668(NCO)\u8fd9\u4e2a\u8bcd\u53ef\u80fd\u6709\u70b9\u964c\u751f\uff0c\u4f46\u4e5f\u6ca1\u5173\u7cfb\u3002\u5728\u8fd9\u7bc7\u535a\u5ba2\u91cc\uff0c\u6211\u4eec\u5b9e\u73b0\u7684\u65b9\u5f0f\u5176\u5b9e\u5c31\u662f\u4e00\u4e2a\u6709<strong>\u9891\u7387\u63a7\u5236\u5b57<\/strong>\u548c<strong>\u76f8\u4f4d\u63a7\u5236\u5b57<\/strong>\u7684 <strong>DDS<\/strong> \u7f62\u4e86\u3002<\/p>\n<blockquote><p>\n  \u5982\u679c\u4f60\u4e0d\u77e5\u9053\u4ec0\u4e48\u662f DDS \uff0c\u90a3\u6211\u53ea\u80fd\u5efa\u8bae\u4f60\u7f51\u4e0a\u67e5\u4e00\u67e5\u4e86\uff0c\u6bd4\u5982<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/blog.csdn.net\/woshiyuzhoushizhe\/article\/details\/101159860\">\u8fd9\u91cc<\/a>\uff0c\n<\/p><\/blockquote>\n<p>\u90a3\u8fd9\u91cc\uff0c\u6211\u4eec\u53ef\u4ee5\u5f88\u660e\u663e\u7684\u89c2\u5bdf\u5230\u4e24\u4e2a\u53ef\u4ee5\u7528\u6765\u53cd\u9988\u7684\u53c2\u6570\uff1a<br \/>\n&#8211; 1. \u9891\u7387\u63a7\u5236\u5b57<br \/>\n&#8211; 2. \u76f8\u4f4d\u63a7\u5236\u5b57<\/p>\n<p>\u9996\u5148\u5148\u8bf4\u7ed3\u8bba\uff0c\u6211\u4eec\u901a\u8fc7\u8c03\u6574\u76f8\u4f4d\u63a7\u5236\u5b57\u5b9e\u73b0\u9501\u76f8\u3002<br \/>\n\u4e3a\u4ec0\u4e48\uff1f\u9996\u5148\uff0c\u6211\u4eec\u5148\u5047\u8bbe\u5c06\u4eceDDS\u8f93\u51fa\u5230\u4e58\u6cd5\u5668\u7684\u4fe1\u53f7\u5b58\u50a8\u5728\u4e00\u5f20\u67091024\u4e2a\u4e0d\u540c\u6570\u636e\u7684rom\u8868\u4e2d\u3002\u63a5\u7740\u8ba9\u6211\u4eec\u6765\u7b80\u5355\u56de\u987e\u4e00\u4e0b\u8fd9\u4e24\u7684\u533a\u522b\uff1a<br \/>\n&#8211; 1. \u9891\u7387\u63a7\u5236\u5b57\uff1a\u6700\u901a\u4fd7\u7684\u7406\u89e3\uff0c\u5373\u5728rom\u8868\u4e2d\uff0c\u6bcf\u4e2aclk\u8fdb\u6765\u65f6\uff0crom\u8868\u4e2d\u6307\u5411\u8f93\u51fa\u7684\u6307\u9488\u79fb\u52a8\u591a\u5c11\u4e2a\u7d22\u5f15\uff0cDDS\u8f93\u51fa\u8be5\u7d22\u5f15\u7684\u6570\u503c<br \/>\n&#8211; 2. \u76f8\u4f4d\u63a7\u5236\u5b57\uff1a\u76f4\u63a5\u5728\u7d22\u5f15\u4e0a\u52a0\u52a0\u51cf\u51cf<\/p>\n<p>\u90a3\u8fd9\u4e2a\u65f6\u5019\u80af\u5b9a\u4f1a\u6709\u4eba\u95ee\uff0c\u8fd9\u4e0d\u90fd\u662f\u4fee\u6539\u5730\u5740(\u7d22\u5f15)\u5417\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u80fd\u4f7f\u7528\u9891\u7387\u63a7\u5236\u5b57\u53cd\u9988\u5462\uff1f<br \/>\n\u6211\u4eec\u518d\u6765\u56de\u987e\u4e00\u4e0b\uff0c\u8fd9\u662f&#8221;<strong>\u9501\u76f8\u73af<\/strong>&#8220;\uff0c\u4e0d\u662f&#8221;<strong>\u9501\u9891\u73af<\/strong>&#8220;\u3002\u6240\u4ee5\u5bf9\u6b64\uff0c\u9891\u7387\u63a7\u5236\u5b57\u662f<strong>\u95f4\u63a5\uff08\u79ef\u5206\uff09<\/strong> \u63a7\u5236\u76f8\u4f4d\uff0c\u800c\u76f8\u4f4d\u63a7\u5236\u5b57\u662f<strong>\u76f4\u63a5<\/strong>\u63a7\u5236\u76f8\u4f4d\u3002\u81ea\u7136\u800c\u7136\uff0c\u76f8\u4f4d\u63a7\u5236\u5b57\u7684\u53cd\u9988\u4f1a\u8fc5\u901f\u5f88\u591a\u3002<\/p>\n<blockquote><p>\n  \u53e6\u4e00\u79cd\u89e3\u91ca\u662f\uff1a\u4f5c\u7528\u4e8e\u9891\u7387\u63a7\u5236\u5b57\u4e0a\u7684\u53d8\u5316\uff0c\u5728\u4fee\u6539\u4e4b\u540e\u7684\u6bcf\u4e00\u4e2a\u65f6\u949f\u5468\u671f\uff0c\u8fd9\u4e2a \u0394\u03c9 \u90fd\u4f1a\u6301\u7eed\u4ea7\u751f\u4f5c\u7528\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5b83\u4f1a\u901a\u8fc7\u65f6\u95f4\u79ef\u5206 \u6700\u7ec8\u5f62\u6210\u76f8\u4f4d\u7684\u53d8\u5316\u3002\n<\/p><\/blockquote>\n<p><span class=\"katex math multi-line\">\\theta(t) = \\int \\omega(t) \\, dt<\/span><\/p>\n<blockquote><p>\n  <em>\u4e0d\u8fc7\u8bf4\u53cd\u9988\u9891\u7387\u80fd\u4e0d\u80fd\u53cd\u9988\u5427\uff0c\u5176\u5b9e\u4e5f\u662f\u80fd\u53cd\u9988\u7684\uff0c\u53ea\u4e0d\u8fc7\u6548\u679c\u4e0d\u592a\u884c\uff0c\u4f1a\u5de6\u53f3\u6643\u8361\u3002<\/em>\n<\/p><\/blockquote>\n<h3>1.3 \u6846\u56fe<\/h3>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/\u539f\u7406\u6846\u56fe.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/\u539f\u7406\u6846\u56fe.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\u539f\u7406\u6846\u56fe\" \/><\/div><\/p>\n<h3>1.4 \u8865\u5145\u4e0e\u500d\u9891<\/h3>\n<p>*\u5bf9\u4e8e\u7c7b\u4f3c\u65f6\u949f\u4fe1\u53f7\u7684\u4e0a\u4e0b\u4e0a\u4e0b\u7684\u65b9\u6ce2\u8109\u51b2\uff0c\u53ef\u4ee5\u53c2\u8003\u8fd9\u7bc7<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/blog.csdn.net\/DBLLLLLLLL\/article\/details\/84395583\">\u535a\u5ba2<\/a><\/p>\n<blockquote><p>\n  \u5bf9\u6b64\u5982\u679c\u4f60\u6709\u500d\u9891\u7684\u9700\u6c42\uff0c\u5176\u5b9e\u53ea\u8981\u5728\u53cd\u9988\u8f93\u51fa\u4fe1\u53f7\u7684\u56de\u8def\u4e0a\u6dfb\u52a0\u4e00\u4e2a\u5206\u9891\u5668\u5c31\u884c\u4e86\uff08\u8fd9\u4e5f\u662f\u50cf\u5355\u7247\u673a\u8fd9\u4e9b\u8bbe\u5907\u5982\u4f55\u83b7\u5f97\u9ad8\u9891\u7684\u7531\u6765\uff09\n<\/p><\/blockquote>\n<p>\u5bf9\u6b64\uff0c\u6846\u56fe\u53ef\u4ee5\u53c2\u8003\u8fd9\u91cc\uff1a<br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pica.zhimg.com\/v2-72fb6311c2831c86f14aff2ac1d80536_r.jpg?source=1def8aca'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pica.zhimg.com\/v2-72fb6311c2831c86f14aff2ac1d80536_r.jpg?source=1def8aca\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\u500d\u9891\u53c2\u8003\" \/><\/div><br \/>\n**\u4e0a\u56fe\u6765\u81ea\u8fd9\u7bc7<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/www.zhihu.com\/question\/23107343\">\u535a\u5ba2<\/a>*<\/p>\n<h3>1.5 \u7528\u9014<\/h3>\n<ol>\n<li>\u666e\u901a\u7684\u9501\u9891\uff1a<br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/\u9501\u9891100kHz.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/\u9501\u9891100kHz.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\u9501\u9891100kHz\" \/><\/div><\/li>\n<li>\u9501\u5b9a\u5fae\u5c0f\u4fe1\u53f7\uff1a<br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/\u9501\u98913.2kHz31\u6b21\u8c10\u6ce2\u5206\u91cf.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/\u9501\u98913.2kHz31\u6b21\u8c10\u6ce2\u5206\u91cf.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\u9501\u5b9a\u5fae\u7b11\u4fe1\u53f7\" \/><\/div><\/li>\n<li>\u500d\u9891<\/li>\n<li>\u8c03\u5236\u89e3\u8c03<\/li>\n<\/ol>\n<hr \/>\n<h2>2. \u4ee3\u7801\u5b9e\u73b0<\/h2>\n<blockquote><p>\n  <em>\u6ce8\u610f\uff0c\u6211\u672c\u8eab\u5e76\u4e0d\u662f\u4e13\u95e8\u5199 verilog \u7684\uff0c\u6240\u4ee5\u4ee3\u7801\u53ef\u80fd\u6709\u4e9b\u4e0d\u89c4\u8303\uff0c\u8bf7\u539f\u8c05\u3002<\/em>\n<\/p><\/blockquote>\n<h3>2.1 \u8bbe\u5907\u53c2\u6570\u4ecb\u7ecd<\/h3>\n<p>\u672c\u9879\u76ee\u57fa\u4e8e\u4ee5\u4e0b\u786c\u4ef6\u548c\u5f00\u53d1\u73af\u5883\u5b9e\u73b0\uff1a<\/p>\n<table>\n<thead>\n<tr>\n<th>\u53c2\u6570\u7c7b\u522b<\/th>\n<th>\u5177\u4f53\u4fe1\u606f<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u5f00\u53d1\u8f6f\u4ef6<\/td>\n<td>Quartus Prime 18.0<\/td>\n<\/tr>\n<tr>\n<td>\u82af\u7247\u578b\u53f7<\/td>\n<td>Altera Cyclone IV EP4CE10E22C8N<\/td>\n<\/tr>\n<tr>\n<td>\u5f00\u53d1\u677f\u578b\u53f7<\/td>\n<td>EP4CE10V1<\/td>\n<\/tr>\n<tr>\n<td>\u5b9e\u9645\u9009\u7528\u5668\u4ef6<\/td>\n<td>EP4CE10E22C8\uff08\u5728 Quartus \u4e2d\u9009\u62e9\uff09<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>*\u6ce8\u610f\uff0c\u6211\u4eec\u793e\u56e2\u6709\u4e24\u5757\u677f\u5b50\uff0c\u4e00\u5757\u662f\u9ed1\u7684\uff0c\u4e00\u5757\u84dd\u7684\uff0c\u5206\u522b\u662fCyclone IV\u548cII\u7684\uff0c\u4e0d\u8981\u62ff\u9519\u4e86\u3002<\/p>\n<h3>2.2 \u9274\u76f8\u5668<\/h3>\n<p>\u6839\u636e\u524d\u6587\u7684\u4ecb\u7ecd\uff0c\u9274\u76f8\u5668\u7531\u4e24\u90e8\u5206\u7ec4\u6210\uff1a\u4e58\u6cd5\u5668 \u548c FIR II\u6570\u5b57\u4f4e\u901a\u6ee4\u6ce2\u5668\u3002<\/p>\n<h4>2.2.1 \u4e58\u6cd5\u5668<\/h4>\n<p>\u8fd9\u4e2a\u5c31\u4e0d\u591a\u4ecb\u7ecd\u4e86\uff0c\u8003\u8651\u5230\u6211\u4eec\u7684\u677f\u5b50 adc \u91c7\u96c6\u548c dac \u8f93\u51fa\u90fd\u662f 10bit \u7684\u4fe1\u53f7\uff0c\u6240\u4ee5\u7528IP\u6838\u914d\u7f6e\u4e58\u6cd5\u5668\u65f6\uff0c\u53ea\u9700\u8981\u914d\u7f6e\u8f93\u5165\u4e24\u4e2a\u901a\u9053\u5206\u522b10bit\uff0c\u8f93\u51fa20bit\u5373\u53ef\u3002<\/p>\n<h4>2.2.2 FIR II \u6570\u5b57\u4f4e\u901a\u6ee4\u6ce2\u5668<\/h4>\n<p>\u6ee4\u6ce2\u5668\u5177\u4f53\u7684\u53c2\u6570\u914d\u7f6e\u65b9\u6cd5\u53ef\u4ee5\u53c2\u8003<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/blog.csdn.net\/bleauchat\/article\/details\/85136485\">\u8fd9\u91cc<\/a>\u548c<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/www.cnblogs.com\/cofin\/p\/10220648.html\">\u8fd9\u91cc<\/a><\/p>\n<p>\u5728\u6b64\uff0c\u6211\u4eec\u8bbe\u7f6eclk\u9891\u7387\u4e3a50MHz\uff0c\u91c7\u6837\u7387\u4e3a500kHz\uff0c\u901a\u5e26\u9891\u7387\u7ea6\u4e3a5kHz\uff0c\u622a\u6b62\u9891\u7387\u4e3a15kHz\uff0c\u4f7f\u7528matlab\u6765\u8bbe\u8ba1\u53c2\u6570\uff0c\u518d\u5bfc\u5165\u5230quartus\u4e2d\u3002<br \/>\n\u6211\u4eec\u7684\u677f\u5b50clk\u9891\u7387\u4e3a50MHz\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740\u6211\u4eec\u91c7\u6837\u9891\u7387\u5c31\u662f50MHz\u3002\u5982\u679c\u53ea\u662fadc\u91c7\u96c6\u4fe1\u53f7\u76f4\u63a5\u8f93\u51fa\u5230dac\u7684\u8bdd\uff0c\u90a3\u786e\u5b9e\u53ef\u4ee550MHz\uff0c\u4f46\u662fFIR\u8bbe\u8ba1\u5b8c\u6bd5\u540e\uff0c\u9636\u6570\u4f1a\u8fbe\u5230\u60ca\u4eba\u768414000+\uff0c\u8fd9\u663e\u7136\u4e0d\u73b0\u5b9e\uff0c\u6240\u4ee5\u91c7\u6837\u9891\u7387\u80af\u5b9a\u5f97\u964d\u4f4e\u3002<\/p>\n<p>\u5728IP\u6838\u4e2d\uff0c\u8fd8\u6709\u8fd9\u51e0\u4e2a\u53c2\u6570\u9700\u8981\u5173\u6ce8\u4e00\u4e0b\uff1a<br \/>\n1. <strong>\u53c2\u6570\u4f4d\u5bbd<\/strong>\u3002\u4e5f\u5c31\u5f71\u54cd\u5f71\u54cd\u7cbe\u5ea6\uff0c\u4f60\u5728Cofficient\u6807\u7b7e\u680f\u4e2d\u662f\u53ef\u4ee5\u76f4\u89c2\u7684\u770b\u5230\u4e0d\u540c\u4f4d\u5bbd\u5bf9\u6ee4\u6ce2\u5668\u7684\u5f71\u54cd\u3002\u8fd9\u91cc\u9009\u62e9\u4e8612bit\u3002<br \/>\n2. \u8f93\u51fa\u7684<strong>MSB\u622a\u65ad<\/strong>\uff08\u9ad8\u4f4d\u5f00\u59cb\u591a\u5c11\u4f4d\u4e0d\u8981\uff09\u548c<strong>LSB\u622a\u65ad<\/strong>\uff08\u4f4e\u4f4d\u5f00\u59cb\u591a\u5c11\u4f4d\u4e0d\u8981\uff09\u3002\u56e0\u4e3a\u901a\u8fc7FIR\u540e\u7684\u4fe1\u53f7\u4f1a\u6839\u636e\u8f93\u5165\u4f4d\u6570\u548c\u53c2\u6570\u5bbd\u5ea6\u5f71\u54cd\u8f93\u51fa\u7684\u5b9e\u9645\u5bbd\u5ea6\u3002\u50cf\u6211\u8fd9\u5b9e\u9645\u8f93\u51fa\u662f31bit\uff0c\u56e0\u4e3a\u5982\u679c\u76f4\u63a5\u4ece\u9ad8\u4f4d\u622a10bit\u4f5c\u4e3a\u6700\u7ec8\u8f93\u51fa\u7684\u8bdd\u4fe1\u53f7\u4f1a\u5f88\u5c0f\uff0c\u4e0d\u5229\u4e8e\u53cd\u9988\u3002\u6240\u4ee5\u6211\u5728MSB\u622a\u65ad\u4e865bit\uff0cLSB\u622a\u65ad\u4e8616\u4f4d\u3002\u8fd9\u6837\u76f8\u8f83\u4e8e\u76f4\u63a5\u4ece\u9ad8\u4f4d\u622a10bit\uff0c\u6570\u503c\u662f\u653e\u5927\u4e86\u7684\uff0cFIR\u7684\u8f93\u51fa\u53d8\u5316\u4f1a\u66f4\u52a0\u660e\u663e\u3002\uff08\u8fd9\u91cc\u53c2\u6570\u5982\u679c\u81ea\u5df1\u8bbe\u8ba1FIR\u7684\u8bdd\u5c31\u81ea\u5df1\u5b9e\u9a8c\u4e2d\u770b\u770b\u7ed3\u679c\u518d\u6765\u8c03\u6574\u5427\uff09<\/p>\n<p>\u5176\u4f59\u7684IP\u6838\u53c2\u6570\u5c31\u653e\u5f20\u622a\u56fe\u5427\uff1a<br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/FIR_II_figure1.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/FIR_II_figure1.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"figure1\" \/><\/div><br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/FIR_II_figure2.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/FIR_II_figure2.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"figure2\" \/><\/div><br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/FIR_II_figure3.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/FIR_II_figure3.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"figure3\" \/><\/div><br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/FIR_II_figure4.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/FIR_II_figure4.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"figure4\" \/><\/div><br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/FIR_II_figure5.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/blog.keruone.cn\/wp-content\/uploads\/2025\/07\/FIR_II_figure5.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"figure5\" \/><\/div><\/p>\n<p>\u8c03\u7528\u8fd9IP\u6838\u7684\u4ee3\u7801\u5982\u4e0b\u6240\u793a<\/p>\n<details>\n<summary>\u70b9\u51fb\u5c55\u5f00\uff1aFIR\u6ee4\u6ce2\u5668\u6a21\u5757\u4ee3\u7801\uff08FIR_II_FILTER\uff09<\/summary>\n<pre><code class=\"language-verilog line-numbers\">\/\/==============================================================================\n\/\/ Company: Ningbo University\n\/\/ Engineer: Keruone\n\/\/ Create Date: 2025\/07\/19\n\/\/ Module Name: FIR_II_FILTER\n\/\/ Description: FIR Filter with 500kHz sampling rate and signed data processing\n\/\/==============================================================================\n\nmodule FIR_II_FILTER (\n  \/\/ Clock Interface\n  input clk,                                      \/\/ 50MHz \u7cfb\u7edf\u65f6\u949f\n\n  \/\/ Data Interface\n  input signed [9:0] fir_signed_input,            \/\/ ADC \u8f93\u5165\u6570\u636e (\u6709\u7b26\u53f7)\n  output reg signed [9:0] fir_signed_output,      \/\/ DAC \u8f93\u51fa\u6570\u636e (\u6709\u7b26\u53f7)\n\n  \/\/ Clock Output Interface\n  output clk_adc,                                 \/\/ ADC \u65f6\u949f\u8f93\u51fa (500kHz)\n  output clk_dac                                  \/\/ DAC \u65f6\u949f\u8f93\u51fa (500kHz)\n);\n\n\/\/==============================================================================\n\/\/ Parameter Definitions\n\/\/==============================================================================\n\n  \/\/ Clock Divider Parameters\n  parameter CLK_DIV_COUNT = 49;                   \/\/ \u5206\u9891\u8ba1\u6570\u503c (50MHz\/500kHz\/2 - 1)\n  parameter RESET_CYCLES  = 15;                   \/\/ \u590d\u4f4d\u5468\u671f\u6570\n\n\/\/==============================================================================\n\/\/ Internal Signal Declarations\n\/\/==============================================================================\n\n  \/\/ Reset Generation\n  reg [3:0]  reset_counter;                       \/\/ \u590d\u4f4d\u8ba1\u6570\u5668\n  reg        reset_n;                             \/\/ \u5185\u90e8\u590d\u4f4d\u4fe1\u53f7\n\n  \/\/ Clock Generation\n  reg [6:0]  clk_div_counter;                     \/\/ \u5206\u9891\u8ba1\u6570\u5668 (0-49)\n  reg        clk_500k;                            \/\/ 500kHz \u65f6\u949f\n  reg        clk_500k_prev;                       \/\/ 500kHz \u65f6\u949f\u7684\u524d\u4e00\u72b6\u6001\n  wire       clk_500k_posedge;                    \/\/ 500kHz \u65f6\u949f\u4e0a\u5347\u6cbf\u68c0\u6d4b\n\n  \/\/ Data Processing\n  reg signed [9:0] adc_data_reg;                  \/\/ ADC \u6570\u636e\u5bc4\u5b58\u5668 (\u6709\u7b26\u53f7)\n  reg        adc_valid;                           \/\/ ADC \u6570\u636e\u6709\u6548\u4fe1\u53f7\n\n  \/\/ FIR Filter Interface\n  wire signed [9:0] fir_output;                   \/\/ FIR \u6709\u7b26\u53f7\u8f93\u51fa\n  wire       fir_output_valid;                    \/\/ FIR \u8f93\u51fa\u6709\u6548\u4fe1\u53f7\n\n\/\/==============================================================================\n\/\/ Reset Generation Circuit\n\/\/==============================================================================\n\n  \/\/ \u590d\u4f4d\u8ba1\u6570\u5668\u521d\u59cb\u5316\n  initial begin\n      reset_counter = 4'd0;\n  end\n\n  \/\/ \u5185\u90e8\u590d\u4f4d\u4fe1\u53f7\u751f\u6210\u5668\n  always @(posedge clk) begin\n      if (reset_counter &lt; RESET_CYCLES) begin\n          reset_counter &lt;= reset_counter + 1'b1;\n          reset_n       &lt;= 1'b0;\n      end else begin\n          reset_n &lt;= 1'b1;\n      end\n  end\n\n\/\/==============================================================================\n\/\/ Clock Divider (50MHz -&gt; 500kHz)\n\/\/==============================================================================\n\n  \/\/ 50MHz -&gt; 500kHz \u5206\u9891\u5668\n  always @(posedge clk or negedge reset_n) begin\n      if (!reset_n) begin\n          clk_div_counter &lt;= 7'd0;\n          clk_500k        &lt;= 1'b0;\n      end else begin\n          if (clk_div_counter &gt;= CLK_DIV_COUNT) begin\n              clk_div_counter &lt;= 7'd0;\n              clk_500k        &lt;= ~clk_500k;       \/\/ \u7ffb\u8f6c\u751f\u6210500kHz\n          end else begin\n              clk_div_counter &lt;= clk_div_counter + 1'b1;\n          end\n      end\n  end\n\n\/\/==============================================================================\n\/\/ Edge Detection for 500kHz Clock\n\/\/==============================================================================\n\n  \/\/ 500kHz \u65f6\u949f\u4e0a\u5347\u6cbf\u68c0\u6d4b\n  always @(posedge clk or negedge reset_n) begin\n      if (!reset_n) begin\n          clk_500k_prev &lt;= 1'b0;\n      end else begin\n          clk_500k_prev &lt;= clk_500k;\n      end\n  end\n\n  assign clk_500k_posedge = clk_500k &amp; ~clk_500k_prev;\n\n\/\/==============================================================================\n\/\/ ADC Data Sampling\n\/\/==============================================================================\n\n  \/\/ ADC \u6570\u636e\u91c7\u6837 (\u76f4\u63a5\u4f7f\u7528\u6709\u7b26\u53f7\u6570\u636e)\n  always @(posedge clk or negedge reset_n) begin\n      if (!reset_n) begin\n          adc_data_reg &lt;= 10'sd0;                 \/\/ \u6709\u7b26\u53f7\u96f6\u503c\n          adc_valid    &lt;= 1'b0;\n      end else begin\n          if (clk_500k_posedge) begin\n              adc_data_reg &lt;= fir_signed_input;   \/\/ \u91c7\u6837\u6709\u7b26\u53f7ADC\u6570\u636e\n              adc_valid    &lt;= 1'b1;               \/\/ \u6570\u636e\u6709\u6548\n          end else begin\n              adc_valid &lt;= 1'b0;                  \/\/ \u5176\u4ed6\u65f6\u5019\u6570\u636e\u65e0\u6548\n          end\n      end\n  end\n\n\/\/==============================================================================\n\/\/ FIR Filter Instantiation\n\/\/==============================================================================\n\n  \/\/ \u5b9e\u4f8b\u5316 FIR \u6ee4\u6ce2\u5668 (\u76f4\u63a5\u4f7f\u7528\u6709\u7b26\u53f7\u6570\u636e)\n  FIR_FILTER fir_filter_inst (\n      .clk                (clk),                  \/\/ 50MHz \u65f6\u949f\n      .reset_n            (reset_n),              \/\/ \u590d\u4f4d\u4fe1\u53f7\n      .ast_sink_data      (adc_data_reg),         \/\/ \u6709\u7b26\u53f7\u8f93\u5165\u6570\u636e\n      .ast_sink_valid     (adc_valid),            \/\/ \u6570\u636e\u6709\u6548\u4fe1\u53f7\n      .ast_sink_error     (2'b00),                \/\/ \u65e0\u9519\u8bef\n      .ast_source_data    (fir_output),           \/\/ \u6709\u7b26\u53f7\u8f93\u51fa\u6570\u636e\n      .ast_source_valid   (fir_output_valid),     \/\/ \u8f93\u51fa\u6709\u6548\u4fe1\u53f7\n      .ast_source_error   ()                      \/\/ \u9519\u8bef\u4fe1\u53f7\uff08\u672a\u4f7f\u7528\uff09\n  );\n\n\/\/==============================================================================\n\/\/ DAC Output Data Processing\n\/\/==============================================================================\n\n  \/\/ DAC \u8f93\u51fa\u6570\u636e\u9501\u5b58 (\u76f4\u63a5\u4f7f\u7528\u6709\u7b26\u53f7\u6570\u636e)\n  always @(posedge clk or negedge reset_n) begin\n      if (!reset_n) begin\n          fir_signed_output &lt;= 10'sd0;            \/\/ \u590d\u4f4d\u65f6\u8f93\u51fa\u6709\u7b26\u53f7\u96f6\u503c\n      end else begin\n          if (fir_output_valid) begin\n              fir_signed_output &lt;= fir_output;     \/\/ \u66f4\u65b0DAC\u8f93\u51fa\n          end\n      end\n  end\n\n\/\/==============================================================================\n\/\/ Output Clock Assignment\n\/\/==============================================================================\n\n  \/\/ \u8f93\u51fa\u65f6\u949f\u5206\u914d\n  assign clk_adc = clk_500k;                      \/\/ ADC \u65f6\u949f 500kHz\n  assign clk_dac = clk_500k;                      \/\/ DAC \u65f6\u949f 500kHz\n\nendmodule\n<\/code><\/pre>\n<\/details>\n<ul>\n<li><strong>\u529f\u80fd<\/strong>\uff1a\u5b9e\u73b0\u4e86\u4e00\u4e2a<strong>\u57fa\u4e8e500kHz\u91c7\u6837\u7387\u7684FIR\u6ee4\u6ce2\u5668\u6a21\u5757<\/strong>\uff0c\u7528\u4e8e\u5bf9ADC\u8f93\u5165\u7684\u6709\u7b26\u53f710\u4f4d\u6570\u636e\u8fdb\u884c\u6ee4\u6ce2\u5904\u7406\uff0c\u5e76\u5c06\u7ed3\u679c\u8f93\u51fa\u7ed9DAC\u3002<\/li>\n<li><strong>\u6838\u5fc3\u529f\u80fd\u70b9<\/strong>\uff1a\n<ul>\n<li>\u4ece50MHz\u7cfb\u7edf\u65f6\u949f\u5206\u9891\u51fa500kHz\u7684ADC\/DAC\u65f6\u949f\uff1b<\/li>\n<li>\u5bf9ADC\u8f93\u5165\u6570\u636e\u8fdb\u884c\u91c7\u6837\u5e76\u9001\u5165FIR\u6ee4\u6ce2\u5668\uff1b<\/li>\n<li>\u6ee4\u6ce2\u7ed3\u679c\u8f93\u51fa\u81f3DAC\uff1b<\/li>\n<li>\u652f\u6301\u6709\u7b26\u53f7\u6570\u636e\u5904\u7406\uff08signed [9:0]\uff09\uff1b<\/li>\n<\/ul>\n<\/li>\n<li><strong>\u4f7f\u7528\u65b9\u5f0f<\/strong>\uff1a\n<ol>\n<li>\u5728\u9876\u5c42\u6a21\u5757\u4e2d\u5b9e\u4f8b\u5316\u8be5\u6a21\u5757\uff1b<\/li>\n<li>\u5c06\u9700\u8981\u6ee4\u6ce2\u7684\u4fe1\u53f7\u8f93\u5165\u8fde\u63a5\u5230 <code>fir_signed_input<\/code>\uff1b<\/li>\n<li>\u5c06\u8fd0\u6ee4\u6ce2\u540e\u7684\u4fe1\u53f7\u8f93\u51fa\u8fde\u63a5\u5230 <code>fir_signed_output<\/code>\uff1b<\/li>\n<li>\u4f7f\u7528 <code>clk_adc<\/code> \u548c <code>clk_dac<\/code> \u9a71\u52a8\u5916\u90e8ADC\/DAC\u82af\u7247\uff0c\u4e0d\u8fc7\u8fd9\u91cc\u662f500kHz\u7684\u4fe1\u53f7\uff0c\u5982\u679c\u4e0d\u60f3\u8981\u4ee5\u8fd9\u4e2a\u9891\u7387\u9a71\u52a8\u7684\uff0c\u8bf7\u4e0d\u8981\u8fde\u63a5\uff1b<\/li>\n<li>\u5185\u90e8\u8c03\u7528\u7684 <code>FIR_FILTER<\/code> \u6a21\u5757\u9700\u63d0\u524d\u751f\u6210\uff08\u5982\u4f7f\u7528Quartus\u7684IP\u6838\u5de5\u5177\uff09\uff1b<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<h3>2.3 \u6570\u5b57\u632f\u8361\u5668<\/h3>\n<p>\u672c\u8bbe\u8ba1\u4e2d\u4f7f\u7528\u7684\u6570\u5b57\u632f\u8361\u5668\uff08NCO\uff09\u662f\u901a\u8fc7\u81ea\u5df1\u7f16\u5199\u7684\u6a21\u5757\u5b9e\u73b0\u7684\uff0c\u800c\u4e0d\u662f\u4f7f\u7528 Quartus \u63d0\u4f9b\u7684 IP \u6838\u3002<\/p>\n<p>\u4e3a\u4ec0\u4e48\u4e0d\u7528 IP \u6838\uff1f\u4e2a\u4eba\u89c2\u70b9\u5982\u4e0b\uff1a<br \/>\n&#8211; IP \u6838\u652f\u6301\u7684\u9891\u7387\u63a7\u5236\u5b57\u6700\u591a\u53ea\u6709 24 \u4f4d\uff08\u591a\u4e86\u6211\u7f16\u8bd1\u5c31\u5931\u8d25\u4e86\uff09\uff1b<br \/>\n&#8211; \u4f7f\u7528 IP \u6838\u8d44\u6e90\u5360\u7528\u5927\u3001\u7075\u6d3b\u6027\u5dee\uff1b<br \/>\n&#8211; \u4fee\u6539\u6ce2\u5f62\u6570\u636e\u4e0d\u591f\u65b9\u4fbf\uff0c\u8c03\u8bd5\u8d77\u6765\u4e5f\u4e0d\u76f4\u89c2\uff1b<br \/>\n&#8211; \u81ea\u5df1\u5199\u7684\u8bdd\uff0c\u9891\u7387\u63a7\u5236\u5b57\u53ef\u4ee5\u505a\u5230 32 \u4f4d\uff0c\u7cbe\u5ea6\u66f4\u9ad8\uff1b<br \/>\n&#8211; \u8fd8\u80fd\u65b9\u4fbf\u5730\u6dfb\u52a0\u591a\u8def\u8f93\u51fa\u3001\u4efb\u610f\u6ce2\u5f62\u3001\u76f8\u4f4d\u63a7\u5236\u7b49\u529f\u80fd\u3002<\/p>\n<p>\u6a21\u5757\u529f\u80fd\u7b80\u4ecb<\/p>\n<ul>\n<li>\u4f7f\u7528 32 \u4f4d\u76f8\u4f4d\u7d2f\u52a0\u5668\uff0c\u5b9e\u73b0\u9ad8\u7cbe\u5ea6\u9891\u7387\u63a7\u5236\uff1b<\/li>\n<li>\u901a\u8fc7\u67e5\u627e ROM \u8868\u8f93\u51fa\u6b63\u5f26\u6ce2\u5f62\uff1b<\/li>\n<li>\u652f\u6301\u53cc\u8def\u8f93\u51fa\uff1a\n<ul>\n<li>\u7b2c\u4e00\u8def\u7528\u4e8e\u53cd\u9988\u63a7\u5236\uff1b<\/li>\n<li>\u7b2c\u4e8c\u8def\u53ef\u4ee5\u8bbe\u7f6e\u4efb\u610f\u76f8\u4f4d\u5dee\uff08\u5982 90\u00b0\u3001180\u00b0\uff09\uff1b<\/li>\n<\/ul>\n<\/li>\n<li>\u4f7f\u7528 MIF \u6587\u4ef6\u52a0\u8f7d ROM \u6570\u636e\uff0c\u65b9\u4fbf\u4fee\u6539\u6ce2\u5f62\uff1b<\/li>\n<li>\u8f93\u51fa\u4f7f\u7528\u6d41\u6c34\u7ebf\u5bc4\u5b58\u5668\uff0c\u63d0\u9ad8\u65f6\u5e8f\u6027\u80fd\uff1b<\/li>\n<li>\u65f6\u949f\u9891\u7387\u4e3a 50MHz\uff0c\u652f\u6301\u9ad8\u901f\u8f93\u51fa\u3002<\/li>\n<\/ul>\n<p>\u5173\u952e\u516c\u5f0f\u8bf4\u660e<\/p>\n<ol>\n<li>\u9891\u7387\u63a7\u5236\u5b57\u8ba1\u7b97\uff1a<\/li>\n<\/ol>\n<p><span class=\"katex math multi-line\">Fword = \\frac{F_{out} \\times 2^{32}}{F_{clk}}<\/span><\/p>\n<blockquote><p>\n  \u4f8b\u5982\uff1a\u8981\u5728 50MHz \u7cfb\u7edf\u65f6\u949f\u4e0b\u8f93\u51fa 1kHz \u4fe1\u53f7\uff1a<br \/>\n  <span class=\"katex math multi-line\">Fword = \\frac{1000 \\times 2^{32}}{50 \\times 10^6} \\approx 85899<\/span>\n<\/p><\/blockquote>\n<ol start=\"2\">\n<li>\u76f8\u4f4d\u5dee\u4e0e phase_diff \u7684\u5173\u7cfb\uff1a<\/li>\n<\/ol>\n<p><span class=\"katex math multi-line\">phase&#95;diff = \\frac{\u671f\u671b\u76f8\u4f4d\u5dee}{360^\\circ} \\times 1024<\/span><\/p>\n<blockquote><p>\n  \u4f8b\u5982\uff1a\u8bbe\u7f6e 90\u00b0 \u76f8\u4f4d\u5dee\uff1a<br \/>\n  <span class=\"katex math multi-line\">phase&#95;diff = \\frac{90}{360} \\times 1024 = 256<\/span>\n<\/p><\/blockquote>\n<p>\u5e38\u7528\u914d\u7f6e\u793a\u4f8b<\/p>\n<table>\n<thead>\n<tr>\n<th>\u529f\u80fd\u9700\u6c42<\/th>\n<th>phase_diff<\/th>\n<th>\u8bf4\u660e<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u540c\u76f8\u8f93\u51fa<\/td>\n<td>0<\/td>\n<td>\u4e24\u8def\u4fe1\u53f7\u5b8c\u5168\u4e00\u81f4<\/td>\n<\/tr>\n<tr>\n<td>\u6b63\u4ea4\u8f93\u51fa<\/td>\n<td>256<\/td>\n<td>I\/Q \u8c03\u5236\uff0c\u7b2c\u4e8c\u8def\u8d85\u524d 90\u00b0<\/td>\n<\/tr>\n<tr>\n<td>\u53cd\u76f8\u8f93\u51fa<\/td>\n<td>512<\/td>\n<td>\u8f93\u51fa\u53cd\u76f8\u4fe1\u53f7<\/td>\n<\/tr>\n<tr>\n<td>\u4e09\u76f8\u7cfb\u7edf<\/td>\n<td>0, 341, 683<\/td>\n<td>\u4e09\u76f8\u76f8\u5dee 120\u00b0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>*\u6ce8\uff0c\u5176\u5b9e\u8fd9\u91cc\u8bbe\u8ba1\u7684\u521d\u8877\u662f\u8003\u8651\u5230\u968f\u7740\u9891\u7387\u7684\u4e0d\u540c\uff0c\u9501\u5b9a\u540e\u7684\u76f8\u4f4d\u5dee\u4e5f\u4f1a\u4e0d\u540c\uff0c\u5b9e\u9645\u8f93\u51fa\u7684\u6ce2\u5f62\u9700\u8981\u8c03\u6574<\/p>\n<details>\n<summary>\u70b9\u51fb\u5c55\u5f00\uff1aDDS \u6a21\u5757\u4ee3\u7801\uff08DDS\uff09<\/summary>\n<pre><code class=\"language-verilog line-numbers\">\/\/==============================================================================\n\/\/ Company:     Ningbo University\n\/\/ Engineer:    Friday\n\/\/ Create Date: 2025\/07\/03\n\/\/ Modified:    2025\/07\/19 - Added dual output with configurable phase difference\n\/\/ \n\/\/ Module Name: DDS (Direct Digital Synthesis)\n\/\/ Description: \u53cc\u8def\u8f93\u51faDDS\u6a21\u5757\uff0c\u652f\u6301\u72ec\u7acb\u76f8\u4f4d\u63a7\u5236\n\/\/              \u7b2c\u4e00\u8def\u7528\u4e8e\u53cd\u9988\u63a7\u5236\uff0c\u7b2c\u4e8c\u8def\u53ef\u8bbe\u7f6e\u76f8\u4f4d\u5dee\n\/\/==============================================================================\n\nmodule DDS (\n  \/\/ ========== \u65f6\u949f\u548c\u590d\u4f4d\u4fe1\u53f7 ==========\n  input  wire        clk,         \/\/ \u7cfb\u7edf\u65f6\u949f (50MHz)\n  input  wire        reset_n,     \/\/ \u5f02\u6b65\u590d\u4f4d\uff0c\u4f4e\u7535\u5e73\u6709\u6548\n\n  \/\/ ========== \u8f93\u51fa\u4fe1\u53f7 ==========\n  output wire        dac_clk,     \/\/ DAC\u65f6\u949f\u8f93\u51fa (\u4e0e\u7cfb\u7edf\u65f6\u949f\u540c\u9891)\n  output wire [9:0]  sin_out,     \/\/ \u7b2c\u4e00\u8def\u6b63\u5f26\u6ce2\u8f93\u51fa (\u53cd\u9988\u4fe1\u53f7)\n  output wire [9:0]  sin_out2,    \/\/ \u7b2c\u4e8c\u8def\u6b63\u5f26\u6ce2\u8f93\u51fa (\u53ef\u8bbe\u76f8\u4f4d\u5dee)\n\n  \/\/ ========== \u63a7\u5236\u53c2\u6570 ==========\n  input  wire [31:0] Fword,       \/\/ \u9891\u7387\u63a7\u5236\u5b57\n  input  wire [9:0]  Pword,       \/\/ \u7b2c\u4e00\u8def\u76f8\u4f4d\u63a7\u5236\u5b57\n  input  wire [9:0]  phase_diff   \/\/ \u7b2c\u4e8c\u8def\u76f8\u4f4d\u5dee\u63a7\u5236\u5b57\n);\n\n  \/\/==========================================================================\n  \/\/ \u5185\u90e8\u4fe1\u53f7\u5b9a\u4e49\n  \/\/==========================================================================\n\n  \/\/ \u76f8\u4f4d\u7d2f\u52a0\u5668\n  reg  [31:0] phase_accumulator;   \/\/ 32\u4f4d\u76f8\u4f4d\u7d2f\u52a0\u5668\n\n  \/\/ ROM\u63a5\u53e3\u4fe1\u53f7\n  wire [9:0]  rom_addr1;           \/\/ \u7b2c\u4e00\u8defROM\u5730\u5740\n  wire [9:0]  rom_addr2;           \/\/ \u7b2c\u4e8c\u8defROM\u5730\u5740\n  wire [9:0]  wave_data1;          \/\/ \u7b2c\u4e00\u8defROM\u8f93\u51fa\u6570\u636e\n  wire [9:0]  wave_data2;          \/\/ \u7b2c\u4e8c\u8defROM\u8f93\u51fa\u6570\u636e\n\n  \/\/ \u8f93\u51fa\u5bc4\u5b58\u5668\n  reg  [9:0]  sin_out_reg1;        \/\/ \u7b2c\u4e00\u8def\u8f93\u51fa\u5bc4\u5b58\u5668\n  reg  [9:0]  sin_out_reg2;        \/\/ \u7b2c\u4e8c\u8def\u8f93\u51fa\u5bc4\u5b58\u5668\n\n  \/\/==========================================================================\n  \/\/ \u8f93\u51fa\u4fe1\u53f7\u8fde\u63a5\n  \/\/==========================================================================\n\n  assign dac_clk  = clk;           \/\/ DAC\u65f6\u949f\u76f4\u63a5\u8fde\u63a5\u7cfb\u7edf\u65f6\u949f\n  assign sin_out  = sin_out_reg1;  \/\/ \u7b2c\u4e00\u8def\u8f93\u51fa\n  assign sin_out2 = sin_out_reg2;  \/\/ \u7b2c\u4e8c\u8def\u8f93\u51fa\n\n  \/\/==========================================================================\n  \/\/ \u76f8\u4f4d\u7d2f\u52a0\u5668 - \u5b9e\u73b0\u9891\u7387\u63a7\u5236\n  \/\/==========================================================================\n\n  always @(posedge clk or negedge reset_n) begin\n      if (!reset_n) begin\n          phase_accumulator &lt;= 32'h0000_0000;\n      end\n      else begin\n          phase_accumulator &lt;= phase_accumulator + Fword;\n      end\n  end\n\n  \/\/==========================================================================\n  \/\/ ROM\u5730\u5740\u751f\u6210 - \u5b9e\u73b0\u76f8\u4f4d\u63a7\u5236\n  \/\/==========================================================================\n\n  \/\/ \u7b2c\u4e00\u8def\uff1a\u57fa\u51c6\u76f8\u4f4d = \u7d2f\u52a0\u5668\u9ad810\u4f4d + \u76f8\u4f4d\u504f\u79fb\n  assign rom_addr1 = phase_accumulator[31:22] + Pword;\n\n  \/\/ \u7b2c\u4e8c\u8def\uff1a\u5728\u7b2c\u4e00\u8def\u57fa\u7840\u4e0a\u589e\u52a0\u76f8\u4f4d\u5dee\n  assign rom_addr2 = phase_accumulator[31:22] + Pword + phase_diff;\n\n  \/\/==========================================================================\n  \/\/ \u6b63\u5f26\u6ce2ROM\u5b9e\u4f8b\u5316\n  \/\/==========================================================================\n\n  \/\/ \u7b2c\u4e00\u8def\u6b63\u5f26\u6ce2\u67e5\u627e\u8868\n  rom u_sin_rom1 (\n      .address ( rom_addr1  ),\n      .clock   ( dac_clk    ),\n      .q       ( wave_data1 )\n  );\n\n  \/\/ \u7b2c\u4e8c\u8def\u6b63\u5f26\u6ce2\u67e5\u627e\u8868\n  rom u_sin_rom2 (\n      .address ( rom_addr2  ),\n      .clock   ( dac_clk    ),\n      .q       ( wave_data2 )\n  );\n\n  \/\/==========================================================================\n  \/\/ \u8f93\u51fa\u5bc4\u5b58\u5668 - \u65f6\u5e8f\u5bf9\u9f50\u548c\u6d41\u6c34\u7ebf\n  \/\/==========================================================================\n\n  always @(posedge dac_clk) begin\n      sin_out_reg1 &lt;= wave_data1;  \/\/ \u7b2c\u4e00\u8def\u8f93\u51fa\u5bc4\u5b58\n      sin_out_reg2 &lt;= wave_data2;  \/\/ \u7b2c\u4e8c\u8def\u8f93\u51fa\u5bc4\u5b58\n  end\n\nendmodule\n<\/code><\/pre>\n<\/details>\n<h3>2.4 \u9876\u5c42PLL\u5c01\u88c5<\/h3>\n<p>\u6839\u636e\u524d\u6587\u4ecb\u7ecd\u7684\u5404\u4e2a\u6a21\u5757\uff0c\u6211\u4eec\u9700\u8981\u5c06\u9274\u76f8\u5668\u3001\u6570\u5b57\u632f\u8361\u5668\u3001PID\u63a7\u5236\u5668\u7b49\u7ec4\u4ef6\u6574\u5408\u6210\u4e00\u4e2a\u5b8c\u6574\u7684\u9501\u76f8\u73af\u7cfb\u7edf\u3002<\/p>\n<h4>2.4.1 PLL_MODULE\u6838\u5fc3\u6a21\u5757\u8bbe\u8ba1<\/h4>\n<p>PLL_MODULE \u662f\u9501\u76f8\u73af\u7684\u6838\u5fc3\u5b9e\u73b0\u6a21\u5757\uff0c\u5305\u542b\u4e86\u5b8c\u6574\u7684\u4fe1\u53f7\u5904\u7406\u94fe\u8def\u548c\u63a7\u5236\u903b\u8f91\u3002<\/p>\n<p><strong>\u4e3b\u8981\u529f\u80fd\u7279\u70b9\uff1a<\/strong><\/p>\n<ol>\n<li><strong>\u53cc\u8defDDS\u8f93\u51fa<\/strong>\uff1a\n<ul>\n<li>\u7b2c\u4e00\u8def\u7528\u4e8e\u53cd\u9988\u63a7\u5236\uff08<code>nco_sin1<\/code>\uff09<\/li>\n<li>\u7b2c\u4e8c\u8def\u4f5c\u4e3a\u5b9e\u9645\u8f93\u51fa\uff08<code>nco_sin2<\/code>\uff09\uff0c\u53ef\u8bbe\u7f6e\u76f8\u4f4d\u5dee<\/li>\n<\/ul>\n<\/li>\n<li><strong>PID\u63a7\u5236\u5668<\/strong>\uff1a\n<ul>\n<li>\u91c7\u7528\u5b9a\u70b9\u6570\u8fd0\u7b97\uff08Q16.16\u683c\u5f0f\uff09<\/li>\n<li>\u652f\u6301\u6bd4\u4f8b\uff08P\uff09\u3001\u79ef\u5206\uff08I\uff09\u3001\u5fae\u5206\uff08D\uff09\u4e09\u9879\u63a7\u5236<\/li>\n<li>\u5728250kHz\u9891\u7387\u4e0b\u66f4\u65b0\u63a7\u5236\u53c2\u6570<\/li>\n<\/ul>\n<\/li>\n<li><strong>\u4fe1\u53f7\u5904\u7406\u94fe<\/strong>\uff1a\n<pre><code class=\"line-numbers\">ADC\u8f93\u5165 \u2192 \u7b26\u53f7\u8f6c\u6362 \u2192 \u4e58\u6cd5\u5668 \u2192 FIR\u6ee4\u6ce2 \u2192 PID\u63a7\u5236 \u2192 \u76f8\u4f4d\u8c03\u6574 \u2192 DDS\u8f93\u51fa\n<\/code><\/pre>\n<\/li>\n<\/ol>\n<p><strong>\u5173\u952e\u53c2\u6570\u8bf4\u660e\uff1a<\/strong><\/p>\n<table>\n<thead>\n<tr>\n<th>\u53c2\u6570\u7c7b\u522b<\/th>\n<th>\u53c2\u6570\u540d\u79f0<\/th>\n<th>\u6570\u503c<\/th>\n<th>\u8bf4\u660e<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u65f6\u949f\u5206\u9891<\/td>\n<td>DIVIDER_COUNT<\/td>\n<td>99<\/td>\n<td>50MHz\u2192250kHz\u5206\u9891\u6bd4<\/td>\n<\/tr>\n<tr>\n<td>PID\u589e\u76ca<\/td>\n<td>KP<\/td>\n<td>16384<\/td>\n<td>\u6bd4\u4f8b\u589e\u76ca\uff08Q16.16\u683c\u5f0f\u4e0b\u76840.25\uff09<\/td>\n<\/tr>\n<tr>\n<td>PID\u589e\u76ca<\/td>\n<td>KI<\/td>\n<td>0<\/td>\n<td>\u79ef\u5206\u589e\u76ca\uff08\u4e00\u9636\u7cfb\u7edf\u7f6e\u96f6\uff09<\/td>\n<\/tr>\n<tr>\n<td>PID\u589e\u76ca<\/td>\n<td>KD<\/td>\n<td>0<\/td>\n<td>\u5fae\u5206\u589e\u76ca\uff08\u4e00\u9636\u7cfb\u7edf\u7f6e\u96f6\uff09<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<blockquote><p>\n  <strong>\u6ce8\u610f<\/strong>\uff1a\u5bf9\u4e8e\u4e00\u9636\u9501\u76f8\u73af\u6765\u8bf4\uff0c\u8c03\u6574 KP \u5c31\u591f\u4e86\uff0cKI \u548c KD \u5168\u90e8\u7f6e\u96f6\u5373\u53ef\u3002\u8fd9\u6837\u53ef\u4ee5\u907f\u514d\u7cfb\u7edf\u9707\u8361\uff0c\u63d0\u9ad8\u7a33\u5b9a\u6027\u3002\n<\/p><\/blockquote>\n<p><strong>\u4fe1\u53f7\u8f6c\u6362\u5904\u7406\uff1a<\/strong><\/p>\n<pre><code class=\"language-verilog line-numbers\">\/\/ ADC\u8f93\u5165\uff1a\u65e0\u7b26\u53f7 \u2192 \u6709\u7b26\u53f7\nassign signed_adc = adc - 10'sd512;\n\n\/\/ DAC\u8f93\u51fa\uff1a\u6709\u7b26\u53f7 \u2192 \u65e0\u7b26\u53f7  \nassign dac_output = signed_dac + 10'sd512;\n\n\/\/ DDS\u53cd\u9988\uff1a\u65e0\u7b26\u53f7 \u2192 \u6709\u7b26\u53f7\nassign dds_feedback = nco_sin1 - 10'd512;\n<\/code><\/pre>\n<blockquote><p>\n  \u4e3a\u4ec0\u4e48\u8981\u505a\u8fd9\u4e9b\u8f6c\u6362\uff1f<br \/>\n  &#8211; ADC\u548cDAC\u82af\u7247\u901a\u5e38\u4f7f\u7528\u65e0\u7b26\u53f7\u6570\u636e\u683c\u5f0f\uff080-1023\uff09<br \/>\n  &#8211; \u5185\u90e8\u4fe1\u53f7\u5904\u7406\u9700\u8981\u6709\u7b26\u53f7\u8fd0\u7b97\uff08-512\u5230+511\uff09<br \/>\n  &#8211; \u901a\u8fc7\u52a0\u51cf512\u5b9e\u73b0\u4e24\u79cd\u683c\u5f0f\u7684\u8f6c\u6362\n<\/p><\/blockquote>\n<p><strong>PID\u63a7\u5236\u5668\u5b9e\u73b0\u7ec6\u8282\uff1a<\/strong><\/p>\n<p>\u63a7\u5236\u5668\u91c7\u7528250kHz\u66f4\u65b0\u9891\u7387\uff0c\u907f\u514d\u8fc7\u5feb\u54cd\u5e94\u5bfc\u81f4\u7cfb\u7edf\u4e0d\u7a33\u5b9a\uff1a<\/p>\n<pre><code class=\"language-verilog line-numbers\">\/\/ \u4ec5\u5728250kHz\u4e0a\u5347\u6cbf\u66f4\u65b0PID\u53c2\u6570\nif (clk_250khz_posedge) begin\n    \/\/ P\u9879\uff1akp * error\n    p_term &lt;= (KP * signed_firout_32) &gt;&gt;&gt; 16;\n\n    \/\/ \u66f4\u65b0\u76f8\u4f4d\u63a7\u5236\u5b57\n    phaseCtlWord &lt;= phaseCtlWord + p_term[31:0];\nend\n<\/code><\/pre>\n<p><strong>\u9891\u7387\u63a7\u5236\u5b57\u8ba1\u7b97\uff1a<\/strong><\/p>\n<p>\u5bf9\u4e8e10kHz\u8f93\u51fa\u9891\u7387\u572850MHz\u7cfb\u7edf\u65f6\u949f\u4e0b\uff1a<\/p>\n<p><span class=\"katex math multi-line\">Fword = \\frac{F_{out} \\times 2^{32}}{F_{clk}} = \\frac{10000 \\times 2^{32}}{50 \\times 10^6} = 8589933<\/span><\/p>\n<h4>2.4.2 \u6a21\u5757\u8c03\u7528\u793a\u4f8b<\/h4>\n<p>\u4e3a\u4e86\u65b9\u4fbf\u4f7f\u7528\uff0c\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u4e2a\u7b80\u5316\u7684\u9876\u5c42\u5c01\u88c5\u793a\u4f8b\u3002\u8fd9\u4e2a\u5c01\u88c5\u9690\u85cf\u4e86\u5185\u90e8\u590d\u6742\u7684\u53c2\u6570\u914d\u7f6e\uff0c\u8ba9\u7528\u6237\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528\uff1a<\/p>\n<p><strong>\u8bbe\u8ba1\u601d\u8def\uff1a<\/strong><\/p>\n<ol>\n<li><strong>\u63a5\u53e3\u7b80\u5316<\/strong>\uff1a\u5916\u90e8\u8c03\u7528\u65f6\u4e0d\u9700\u8981\u5173\u5fc3\u9891\u7387\u63a7\u5236\u5b57\u3001\u76f8\u4f4d\u5dee\u7b49\u5185\u90e8\u53c2\u6570<\/li>\n<li><strong>\u53c2\u6570\u56fa\u5316<\/strong>\uff1a\u5c06\u5e38\u7528\u7684\u914d\u7f6e\u53c2\u6570\u5b9a\u4e49\u4e3a\u5e38\u91cf\uff0c\u51cf\u5c11\u51fa\u9519\u6982\u7387<\/li>\n<li><strong>\u517c\u5bb9\u6027<\/strong>\uff1a\u4fdd\u6301\u7b80\u6d01\u7684\u5916\u90e8\u63a5\u53e3<\/li>\n<\/ol>\n<p><strong>\u5e38\u91cf\u53c2\u6570\u914d\u7f6e\uff1a<\/strong><\/p>\n<pre><code class=\"language-verilog line-numbers\">\/\/ \u9891\u7387\u63a7\u5236\u5b57\u5e38\u91cf\uff0810kHz@50MHz\uff09\nlocalparam [31:0] FREQ_CTRL_WORD_CONST = 32'd8589933;\n\n\/\/ \u76f8\u4f4d\u5dee\u63a7\u5236\u5e38\u91cf\uff08\u7ea6-18\u5ea6\u76f8\u4f4d\u5dee\uff09\nlocalparam signed [9:0] PHASE_DIFF_CONST = -10'sd50;\n<\/code><\/pre>\n<p><strong>\u4f7f\u7528\u65b9\u5f0f\uff1a<\/strong><\/p>\n<ol>\n<li><strong>\u76f4\u63a5\u8c03\u7528PLL_MODULE<\/strong>\uff1a\u5982\u679c\u9700\u8981\u52a8\u6001\u8c03\u6574\u9891\u7387\u548c\u76f8\u4f4d\u5dee\n<pre><code class=\"language-verilog line-numbers\">PLL_MODULE u_pll (\n   .FREQ_CTRL_WORD(your_freq_word),\n   .PHASE_DIFF(your_phase_diff),\n   \/\/ ... \u5176\u4ed6\u4fe1\u53f7\n);\n<\/code><\/pre>\n<\/li>\n<li><strong>\u4f7f\u7528\u5c01\u88c5\u7684PLL\u6a21\u5757<\/strong>\uff1a\u5982\u679c\u4f7f\u7528\u56fa\u5b9a\u53c2\u6570\n<pre><code class=\"language-verilog line-numbers\">PLL u_pll_simple (\n   .clk(clk),\n   .rst_n(rst_n),\n   .adc(adc_data),\n   .dac_output(dac_out),\n   \/\/ ... \u5176\u4ed6\u4fe1\u53f7\n);\n<\/code><\/pre>\n<\/li>\n<\/ol>\n<blockquote><p>\n  <strong>\u5efa\u8bae<\/strong>\uff1a\u521d\u5b66\u8005\u5efa\u8bae\u4f7f\u7528\u5c01\u88c5\u540e\u7684PLL\u6a21\u5757\uff0c\u53c2\u6570\u5df2\u7ecf\u8c03\u8bd5\u597d\u4e86\u3002\u5982\u679c\u9700\u8981\u4e0d\u540c\u9891\u7387\u7684\u9501\u76f8\u73af\uff0c\u53ef\u4ee5\u4fee\u6539\u5c01\u88c5\u6a21\u5757\u4e2d\u7684\u5e38\u91cf\u53c2\u6570\u3002\n<\/p><\/blockquote>\n<p><strong>\u8c03\u8bd5\u63a5\u53e3\u8bf4\u660e\uff1a<\/strong><\/p>\n<ul>\n<li><code>key2<\/code>\uff1a\u63a7\u5236DAC1\u8f93\u51fa\u9009\u62e9\n<ul>\n<li><code>key2=0<\/code>\uff1a\u8f93\u51fa\u4e58\u6cd5\u5668\u7ed3\u679c\uff08\u8c03\u8bd5\u7528\uff09<\/li>\n<li><code>key2=1<\/code>\uff1a\u8f93\u51faDDS\u4fe1\u53f7\uff08\u6b63\u5e38\u5de5\u4f5c\u6a21\u5f0f\uff09<\/li>\n<\/ul>\n<\/li>\n<li><code>dac2_output<\/code>\uff1a\u59cb\u7ec8\u8f93\u51faFIR\u6ee4\u6ce2\u5668\u7ed3\u679c\uff0c\u7528\u4e8e\u89c2\u5bdf\u8bef\u5dee\u4fe1\u53f7<\/li>\n<\/ul>\n<h4>2.4.3 \u53c2\u8003\u4ee3\u7801<\/h4>\n<details>\n<summary>\u70b9\u51fb\u5c55\u5f00\uff1aPLL\u6a21\u5757\u5c01\u88c5 <\/summary>\n<pre><code class=\"language-verilog line-numbers\">\/\/==============================================================================\n\/\/ Company: Ningbo University\n\/\/ Engineer: Keruone\u3001Friday\n\/\/ Create Date: 2025\/07\/19\n\/\/ Module Name: PLL_MODULE\n\/\/ Description: Phase-Locked Loop with dual DDS output and PID control\n\/\/==============================================================================\n\nmodule PLL_MODULE(\n  \/\/ Clock and Reset\n  input  logic        clk,\n  input  logic        rst_n,\n\n  \/\/ ADC Interface\n  input  logic [9:0]  adc,\n  output logic        clk_adc,\n\n  \/\/ DAC Interface - Channel 1\n  output logic [9:0]  dac_output,\n  output logic        clk_dac,\n\n  \/\/ DAC Interface - Channel 2  \n  output logic [9:0]  dac2_output,\n  output logic        clk_dac2,\n\n  \/\/ DDS Output Phase Diff\n  input logic   [31:0]  FREQ_CTRL_WORD,\n  input logic   signed [9:0] PHASE_DIFF,\n\n  \/\/ Control Interface\n  input  logic        key2\n\n);\n\n\/\/==============================================================================\n\/\/ Parameter Definitions\n\/\/==============================================================================\n\n  \/\/ Clock Divider Parameters\n  localparam int DIVIDER_COUNT = 99;              \/\/ 50MHz\/250kHz = 200\u5206\u9891\n\n  \/\/ PID Controller Parameters (Q16.16 format)\n  \/\/ \u5bf9\u4e8e\u4e00\u9636\u9501\u76f8\u73af\u6765\u8bf4\u8c03\u6574 kp \u5c31\u591f\u4e86\uff0c ki \u548c kd \u5168\u90e8\u7f6e\u96f6\u5373\u53ef\n  localparam signed [31:0] KP = 32'sd16384;       \/\/ \u6bd4\u4f8b\u589e\u76ca (0.25 in Q16.16)\n  localparam signed [31:0] KI = 32'sd0;           \/\/ \u79ef\u5206\u589e\u76ca (0.05 in Q16.16)  \n  localparam signed [31:0] KD = 32'sd0;           \/\/ \u5fae\u5206\u589e\u76ca (0.025 in Q16.16)\n\n  \/\/ DDS Parameters\n\/\/  localparam [31:0]           FREQ_CTRL_WORD = 32'd8589933;   \/\/ \u56fa\u5b9a\u9891\u7387\u63a7\u5236\u5b57\uff08\u4f8b\u5982\uff1a10kHz@50MHz\uff09\n\/\/  localparam signed[9:0]      PHASE_DIFF      = -10'd50;          \/\/ \u4e24\u8defDDS\u8f93\u51fa\u76f8\u4f4d\u5dee\n\n\/\/==============================================================================\n\/\/ Internal Signal Declarations\n\/\/==============================================================================\n\n  \/\/ DDS Signals\n  logic [9:0]  nco_sin1;                          \/\/ DDS\u7b2c\u4e00\u8def\u8f93\u51fa\uff08\u7528\u4e8e\u53cd\u9988\uff09\n  logic [9:0]  nco_sin2;                          \/\/ DDS\u7b2c\u4e8c\u8def\u8f93\u51fa\uff08\u5b9e\u9645\u8f93\u51fa\uff09\n  logic [9:0]  dds_sin_out;                       \/\/ \u5904\u7406\u540e\u7684DDS\u8f93\u51fa\u4fe1\u53f7\n  logic [9:0]  dds_feedback;                      \/\/ \u7528\u4e8e\u53cd\u9988\u7684DDS\u4fe1\u53f7\n\n  \/\/ Signal Processing\n  logic signed [9:0]  signed_adc;                 \/\/ \u6709\u7b26\u53f7ADC\u8f93\u5165\n  logic signed [9:0]  signed_dac;                 \/\/ \u6709\u7b26\u53f7DAC\u8f93\u51fa\n  logic [19:0] mult_result1;                      \/\/ \u4e58\u6cd5\u5668\u7ed3\u679c\n  logic signed [9:0]  mult_signed1;               \/\/ \u622a\u53d6\u540e\u7684\u4e58\u6cd5\u5668\u8f93\u51fa\n  logic signed [9:0]  signed_firout;              \/\/ FIR\u6ee4\u6ce2\u5668\u8f93\u51fa\n\n  \/\/ Control Signals\n  logic [31:0] freqCtlWord;                       \/\/ 32\u4f4d\u9891\u7387\u63a7\u5236\u5b57\uff08\u56fa\u5b9a\u503c\uff09\n  logic signed [31:0] phaseCtlWord;               \/\/ 32\u4f4d\u6709\u7b26\u53f7\u76f8\u4f4d\u63a7\u5236\u5b57\n  logic [9:0]  phaseCtlWord_10;                   \/\/ 10\u4f4d\u76f8\u4f4d\u63a7\u5236\u5b57\u7ed9DDS\n\n  \/\/ PID Controller Variables\n  logic signed [31:0] error_previous;             \/\/ \u524d\u4e00\u6b21\u8bef\u5dee\n  logic signed [63:0] integral_sum;               \/\/ \u79ef\u5206\u7d2f\u52a0\uff08\u6269\u5c55\u4f4d\u5bbd\u9632\u6b62\u6ea2\u51fa\uff09\n  logic signed [63:0] p_term;                     \/\/ P\u9879\u8ba1\u7b97\u7ed3\u679c\n  logic signed [63:0] i_term;                     \/\/ I\u9879\u8ba1\u7b97\u7ed3\u679c  \n  logic signed [63:0] d_term;                     \/\/ D\u9879\u8ba1\u7b97\u7ed3\u679c\n  logic signed [31:0] error_diff;                 \/\/ \u8bef\u5dee\u5dee\u503c\n  logic signed [31:0] signed_firout_32;           \/\/ \u6269\u5c55\u7684\u8bef\u5dee\u4fe1\u53f7\n\n  \/\/ Clock Generation\n  logic [7:0]  clk_divider_cnt;                   \/\/ \u65f6\u949f\u5206\u9891\u8ba1\u6570\u5668\n  logic        clk_250khz;                        \/\/ 250kHz\u65f6\u949f\n  logic        clk_250khz_posedge;                \/\/ 250kHz\u65f6\u949f\u4e0a\u5347\u6cbf\n  logic        clk_250khz_prev;                   \/\/ 250kHz\u65f6\u949f\u524d\u4e00\u72b6\u6001\n\n\/\/==============================================================================\n\/\/ Clock Divider (250kHz Generation)\n\/\/==============================================================================\n\n  \/\/ 250kHz\u65f6\u949f\u5206\u9891\u5668\n  always_ff @(posedge clk or negedge rst_n) begin\n      if (!rst_n) begin\n          clk_divider_cnt &lt;= 8'd0;\n          clk_250khz      &lt;= 1'b0;\n      end else begin\n          if (clk_divider_cnt &gt;= DIVIDER_COUNT) begin\n              clk_divider_cnt &lt;= 8'd0;\n              clk_250khz      &lt;= ~clk_250khz;\n          end else begin\n              clk_divider_cnt &lt;= clk_divider_cnt + 1'b1;\n          end\n      end\n  end\n\n  \/\/ 250kHz\u65f6\u949f\u4e0a\u5347\u6cbf\u68c0\u6d4b\n  always_ff @(posedge clk or negedge rst_n) begin\n      if (!rst_n) begin\n          clk_250khz_prev &lt;= 1'b0;\n      end else begin\n          clk_250khz_prev &lt;= clk_250khz;\n      end\n  end\n\n  assign clk_250khz_posedge = clk_250khz &amp; ~clk_250khz_prev;\n\n\/\/==============================================================================\n\/\/ Control Word Generation\n\/\/==============================================================================\n\n  \/\/ \u56fa\u5b9a\u9891\u7387\u63a7\u5236\u5b57\n  assign freqCtlWord = FREQ_CTRL_WORD;\n\n  \/\/ \u53d6\u76f8\u4f4d\u63a7\u5236\u5b57\u7684\u9ad810\u4f4d\u7ed9DDS\uff08\u9650\u5236\u57280-1023\u8303\u56f4\u5185\uff09\n  assign phaseCtlWord_10 = phaseCtlWord[19:10];\n\n  \/\/ \u5c0610\u4f4d\u8bef\u5dee\u4fe1\u53f7\u6269\u5c55\u523032\u4f4d\u8fdb\u884c\u8ba1\u7b97\n  assign signed_firout_32 = {{22{signed_firout[9]}}, signed_firout};\n  assign error_diff       = signed_firout_32 - error_previous;\n\n\/\/==============================================================================\n\/\/ PID Controller (250kHz Update Rate)\n\/\/==============================================================================\n\n  always_ff @(posedge clk or negedge rst_n) begin\n      if (!rst_n) begin\n          phaseCtlWord   &lt;= 32'sd0;               \/\/ \u521d\u59cb\u76f8\u4f4d\u63a7\u5236\u5b57\u4e3a0\n          error_previous &lt;= 32'sd0;\n          integral_sum   &lt;= 64'sd0;\n      end else if (clk_250khz_posedge) begin      \/\/ \u4ec5\u5728250kHz\u4e0a\u5347\u6cbf\u66f4\u65b0\n          \/\/ \u5b9a\u70b9\u6570PID\u8ba1\u7b97 (Q16.16\u683c\u5f0f)\n\n          \/\/ P\u9879\uff1akp * error\n          p_term &lt;= (KP * signed_firout_32) &gt;&gt;&gt; 16;\n\n          \/\/ I\u9879\uff1a\u7d2f\u52a0\u8bef\u5dee\u5e76\u4e58\u4ee5ki\n          integral_sum &lt;= integral_sum + signed_firout_32;\n          i_term       &lt;= (KI * integral_sum[31:0]) &gt;&gt;&gt; 16;  \/\/ \u53d6\u79ef\u5206\u548c\u7684\u4f4e32\u4f4d\n\n          \/\/ D\u9879\uff1akd * (error - error_previous)\n          d_term &lt;= (KD * error_diff) &gt;&gt;&gt; 16;\n\n          \/\/ \u66f4\u65b0\u76f8\u4f4d\u63a7\u5236\u5b57\n          phaseCtlWord &lt;= phaseCtlWord + p_term[31:0] + i_term[31:0] + d_term[31:0];\n\n          \/\/ \u4fdd\u5b58\u5f53\u524d\u8bef\u5dee\u7528\u4e8e\u4e0b\u6b21D\u9879\u8ba1\u7b97\n          error_previous &lt;= signed_firout_32;\n      end\n  end\n\n\/\/==============================================================================\n\/\/ Signal Processing Chain\n\/\/==============================================================================\n\n  \/\/ \u4e58\u6cd5\u5668\u5b9e\u4f8b\u5316\n  mult mult1 (\n      .clock  (clk),\n      .dataa  (signed_adc),\n      .datab  (dds_feedback),\n      .result (mult_result1)\n  );\n\n  \/\/ FIR\u6ee4\u6ce2\u5668\u5b9e\u4f8b\u5316\n  FIR_II_FILTER fir_inst1 (\n      .clk               (clk),\n      .fir_signed_input  (mult_signed1),\n      .clk_adc           (clk_adc),\n      .fir_signed_output (signed_firout),\n      .clk_dac           ()                       \/\/ \u672a\u4f7f\u7528\uff0c\u907f\u514d\u9636\u8dc3\u53d8\u5316\n  );\n  \/*  Do not use `clk_dac`. \n      If this CLK is used to drive the dac, \n      the output signal will exhibit a significant step-like variation. \n      Unless you are using it for debugging the FIR effect.\n  *\/\n\n  \/\/ DDS\u6a21\u5757\u5b9e\u4f8b\u5316\n  DDS u2 (\n      .clk        (clk),\n      .reset_n    (rst_n),\n      .dac_clk    (clk_dac),                      \/\/ \u9a71\u52a8DAC\u5b9e\u9645\u4f7f\u7528\u8fd9\u91cc\u8f93\u51fa\u7684DAC\u65f6\u949f\n      .sin_out    (nco_sin1),                     \/\/ \u7528\u4e8e\u53cd\u9988\u7684\u4fe1\u53f7\n      .sin_out2   (nco_sin2),                     \/\/ \u5b9e\u9645\u8f93\u51fa\u4fe1\u53f7\n      .Fword      (freqCtlWord),                  \/\/ \u56fa\u5b9a\u9891\u7387\u63a7\u5236\u5b57\n      .Pword      (phaseCtlWord_10),              \/\/ \u76f8\u4f4d\u63a7\u5236\u5b57\uff0810\u4f4d\uff09\n      .phase_diff (PHASE_DIFF)                    \/\/ \u4e24\u8def\u8f93\u51fa\u76f8\u4f4d\u5dee\n  );\n\n\/\/==============================================================================\n\/\/ Output Signal Processing\n\/\/==============================================================================\n\n  \/\/ ADC\u8f93\u5165\u4fe1\u53f7\u5904\u7406\uff1a\u65e0\u7b26\u53f7\u8f6c\u6709\u7b26\u53f7\n  assign signed_adc = adc - 10'sd512;            \/\/ \u8f93\u5165\u65e0\u7b26\u53f7\u8f6c\u6709\u7b26\u53f7 (Necessary)\n\n  \/\/ DAC\u65f6\u949f\u5206\u914d\n  assign clk_dac2 = clk_dac;                     \/\/ \u4f7f\u7528DDS\u8f93\u51fa\u7684DAC\u65f6\u949f\u6765\u9a71\u52a8 (Necessary)\n\n  \/\/ DAC1\u8f93\u51fa\u4fe1\u53f7\u9009\u62e9\n  assign signed_dac  = key2 ? dds_sin_out : mult_signed1;\n  assign dac_output  = signed_dac + 10'sd512;    \/\/ \u6709\u7b26\u53f7\u8f6c\u65e0\u7b26\u53f7\u8f93\u51fa (Optional)\n\n  \/\/ DAC2\u8f93\u51fa\u4fe1\u53f7\n  assign dac2_output = signed_firout + 10'sd512; \/\/ \u76f4\u63a5\u8f93\u51fa\u6ee4\u6ce2\u5668\u8f93\u51fa (Optional)\n\n  \/\/ \u4e58\u6cd5\u5668\u8f93\u51fa\u622a\u53d6\n  assign mult_signed1 = mult_result1[19:10];     \/\/ \u7528\u4e8eFIR\u6ee4\u6ce2 (Necessary)\n\n  \/\/ DDS\u8f93\u51fa\u4fe1\u53f7\u5904\u7406\n  assign dds_feedback = nco_sin1 - 10'd512;      \/\/ \u7528\u4e8e\u4e58\u6cd5\u5668\u53cd\u9988 (Necessary)\n  assign dds_sin_out  = nco_sin2 - 10'd512;      \/\/ \u5b9e\u9645\u8f93\u51fa\u4fe1\u53f7\n\nendmodule\n\n\/\/==============================================================================\n\/\/ End of Module\n\/\/==============================================================================\n<\/code><\/pre>\n<\/details>\n<details>\n<summary>\u70b9\u51fb\u5c55\u5f00\uff1a\u8c03\u7528\u793a\u4f8b <\/summary>\n<pre><code class=\"language-verilog line-numbers\">\/\/==============================================================================\n\/\/ Company: Ningbo University  \n\/\/ Engineer: Keurone\u3001Friday\n\/\/ Create Date: 2025\/07\/19\n\/\/ Module Name: PLL (Top Level Wrapper)\n\/\/ Description: Top-level wrapper for PLL_MODULE to maintain pin compatibility\n\/\/\n\/\/ \u7279\u522b\u9e23\u8c22\uff1a\u5f90\u6d69\u4fca\u3001\u91d1\u5784\u665f\n\/\/==============================================================================\n\nmodule PLL (\n  \/\/ ========== \u539f\u59cb\u63a5\u53e3\u4fdd\u6301\u4e0d\u53d8 ==========\n  \/\/ \u65f6\u949f\u548c\u590d\u4f4d\n  input  wire        clk,\n  input  wire        rst_n,\n\n  \/\/ ADC\u63a5\u53e3\n  input  wire [9:0]  adc,\n  output wire        clk_adc,\n\n  \/\/ DAC\u63a5\u53e3 - \u901a\u90531\n  output wire [9:0]  dac_output,\n  output wire        clk_dac,\n\n  \/\/ DAC\u63a5\u53e3 - \u901a\u90532\n  output wire [9:0]  dac2_output,\n  output wire        clk_dac2,\n\n  \/\/ \u63a7\u5236\u63a5\u53e3\n  input  wire        key2\n);\n\n  \/\/==========================================================================\n  \/\/ DDS\u63a7\u5236\u5e38\u91cf\u5b9a\u4e49\n  \/\/==========================================================================\n\n  \/\/ \u9891\u7387\u63a7\u5236\u5b57\u5e38\u91cf\uff0810kHz@50MHz\uff09\n  localparam [31:0] FREQ_CTRL_WORD_CONST = 32'd8589933;\n\n  \/\/ \u76f8\u4f4d\u5dee\u63a7\u5236\u5e38\u91cf\n  localparam signed [9:0] PHASE_DIFF_CONST = -10'sd50;\n\n  \/\/==========================================================================\n  \/\/ PLL\u6838\u5fc3\u6a21\u5757\u5b9e\u4f8b\u5316\n  \/\/==========================================================================\n\n  PLL_MODULE u_pll_core (\n      \/\/ \u65f6\u949f\u548c\u590d\u4f4d\n      .clk            ( clk                    ),\n      .rst_n          ( rst_n                  ),\n\n      \/\/ ADC\u63a5\u53e3\n      .adc            ( adc                    ),\n      .clk_adc        ( clk_adc                ),\n\n      \/\/ DAC\u63a5\u53e3 - \u901a\u90531\n      .dac_output     ( dac_output             ),\n      .clk_dac        ( clk_dac                ),\n\n      \/\/ DAC\u63a5\u53e3 - \u901a\u90532\n      .dac2_output    ( dac2_output            ),\n      .clk_dac2       ( clk_dac2               ),\n\n      \/\/ DDS\u63a7\u5236\u63a5\u53e3\uff08\u4f7f\u7528\u5e38\u91cf\uff09\n      .PHASE_DIFF     ( PHASE_DIFF_CONST       ),\n      .FREQ_CTRL_WORD ( FREQ_CTRL_WORD_CONST   ),\n\n      \/\/ \u63a7\u5236\u63a5\u53e3\n      .key2           ( key2                   )\n  );\n\nendmodule\n<\/code><\/pre>\n<\/details>\n<hr \/>\n<h2>3. \u5b8c\u6574 quartus \u5de5\u7a0b\u5206\u4eab<\/h2>\n<p>\u901a\u8fc7\u7f51\u76d8\u5206\u4eab\u7684\u6587\u4ef6\uff1a2025PLL_In_FPGA.zip<br \/>\n\u94fe\u63a5: https:\/\/pan.baidu.com\/s\/1VqRUN3udlJt8LI9_PqVSvg?pwd=snkr \u63d0\u53d6\u7801: snkr<\/p>\n<hr \/>\n<h2>4. \u53c2\u8003<\/h2>\n<ol>\n<li>\n<p>\u539f\u7406\u53c2\u8003\uff1a<br \/>\nhttps:\/\/blog.csdn.net\/DBLLLLLLLL\/article\/details\/84395583<br \/>\nhttps:\/\/blog.csdn.net\/weixin_43824941\/article\/details\/118739186<\/p>\n<\/li>\n<li>\n<p>FIR\u53c2\u8003\uff1a<br \/>\nhttps:\/\/blog.csdn.net\/qq_42839007\/article\/details\/104354810<\/p>\n<\/li>\n<li>\n<p>Matlab FIR\u8bbe\u8ba1\uff1a<br \/>\nhttps:\/\/blog.csdn.net\/bleauchat\/article\/details\/85136485<br \/>\nhttps:\/\/www.cnblogs.com\/cofin\/p\/10220648.html<\/p>\n<\/li>\n<li>\n<p>\u4e66\u7c4d\u53c2\u8003\uff1a<br \/>\n\u300a\u9501\u76f8\u73af\u6280\u672f\u539f\u7406\u53caFPGA\u5b9e\u73b0\u300b \u675c\u52c7<br \/>\n\u300a\u6570\u5b57\u6ee4\u6ce2\u5668\u7684MATLAB\u4e0eFPGA\u5b9e\u73b0-Altera\/Verilog\u7248(\u7b2c\u4e8c\u7248)\u300b \u675c\u52c7<\/p>\n<\/li>\n<li>\n<p>\u793e\u56e2\u8d44\u6599\uff1a<br \/>\n\u65b0\u7248 FPGA \u5f00\u53d1\u677f\u4f7f\u7528\u8bf4\u660e\u4e66<\/p>\n<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>\u57fa\u4e8e FPGA \u7684 PLL \u8c03\u8bd5\u8bb0\u5f55 \u5f00\u59cb\u65f6\u95f4\uff1a2025.7.17 \u7ed3\u675f\u65f6\u95f4\uff1a2025.7.19 \u64b0\u5199\u8005: K [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[13],"tags":[],"class_list":["post-461","post","type-post","status-publish","format-standard","hentry","category-iea_nbu"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/posts\/461","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/comments?post=461"}],"version-history":[{"count":6,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/posts\/461\/revisions"}],"predecessor-version":[{"id":476,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/posts\/461\/revisions\/476"}],"wp:attachment":[{"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/media?parent=461"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/categories?post=461"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.keruone.cn\/index.php\/wp-json\/wp\/v2\/tags?post=461"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}