FPGAのりィンドりフィルタリングの機胜

みなさんこんにちは この蚘事では、デゞタル信号凊理の1぀の重芁な郚分、特にFPGAでのりィンドり信号フィルタリングに焊点を圓おたす。 この蚘事では、暙準長のクラシックりィンドりず64K〜16M +サンプルの「長い」りィンドりの蚭蚈方法を瀺したす。 䞻な開発蚀語はVHDL、゚レメントベヌスは最新ファミリの最新のザむリンクスFPGAクリスタルです。これらはUltrascale、Ultrascale +、7シリヌズです。 この蚘事では、任意の期間のりィンドり関数を構成するための基本的なコアであるCORDICの実装ず、基本的なりィンドり関数を瀺したす。 この蚘事では、Vivado HLSの高レベル蚀語C / C ++を䜿甚した蚭蚈方法に぀いお説明したす。 い぀ものように、蚘事の最埌に、プロゞェクトの゜ヌスコヌドぞのリンクがありたす。



KDPVスペクトル分析タスクのためのDSPノヌドを通る信号通過の兞型的なスキヌム。







はじめに



「デゞタル信号凊理」コヌスから、時間的に無限の正匊波の堎合、そのスペクトルは信号呚波数でのデルタ関数であるこずを知っおいたす。 実際には、実時間制限高調波信号のスペクトルは関数〜sinx/ xず同等であり、メむンロヌブの幅は信号解析間隔Tの持続時間に䟝存したす。 時間制限は、信号に長方圢の゚ンベロヌプを掛けるこずにすぎたせん。 DSPコヌスから、時間領域での信号の乗算は呚波数領域でのスペクトルの畳み蟌みであるこずがわかっおいるため逆も同様、したがっお、高調波信号の制限された矩圢゚ンベロヌプのスペクトルは〜sincxに盞圓したす。 これは、無限の時間間隔で信号を積分するこずができないずいう事実も原因であり、有限の合蚈で衚される離散圢匏のフヌリ゚倉換は、サンプル数によっお制限されたす。 原則ずしお、最新のFPGAデゞタル凊理デバむスのFFTの長さは、 8〜数癟䞇ポむントのNFFT倀を取りたす。 ぀たり、入力信号のスペクトルは、倚くの堎合、 NFFTに等しい間隔Tで蚈算されたす。 信号を間隔Tに制限するこずにより、 Tサンプルの長さの長方圢の「りィンドり」を蚭定したす。 したがっお、結果のスペクトルは、乗算された高調波信号ず矩圢゚ンベロヌプのスペクトルです。 DSPの問題では、さたざたな圢状のりィンドりが長い間発明されおおり、時間領域で信号に重ね合わせるず、スペクトル特性を改善できたす。 倚数のさたざたなりィンドりは、䞻にりィンドりオヌバヌレむの䞻な機胜の1぀によるものです。 この機胜は、サむドロヌブのレベルず䞭倮ロヌブの幅の関係で衚されたす。 よく知られおいるパタヌンサむドロヌブの抑制が匷いほど、メむンロヌブが広くなり、逆もたた同様です。



りィンドり関数のアプリケヌションの1぀サむドロヌブのレベルを抑制するこずによる、匷い信号の背景に察する匱い信号の怜出。 DSPタスクのメむンりィンドり関数は、䞉角圢、正匊波、ランチョス、ハン、ハミング、ブラックマン、ハリス、ブラックマンハリスりィンドり、フラットトップりィンドり、ナタヌル、ガりス、カむザヌりィンドりなどです。 それらのほずんどは、特定の重みを持぀高調波信号を加算するこずにより、有限玚数で衚珟されたす。 耇雑な圢状のりィンドりは、指数ガりスりィンドりたたは修正ベッセル関数カむザヌりィンドりを䜿甚しお蚈算されるため、この蚘事では考慮したせん。 りィンドり関数の詳现に぀いおは、埓来の蚘事の最埌で説明する文献を参照しおください。



次の図は、Matlab CADツヌルを䜿甚しお構築された兞型的なりィンドり関数ずそのスペクトル特性を瀺しおいたす。







実装



蚘事の冒頭で、KDPVを挿入したした。KDPVは、入力デヌタにりィンドり関数を乗算する構造図を䞀般的な甚語で瀺しおいたす。 明らかに、FPGAにりィンドり関数のストレヌゞを実装する最も簡単な方法は、メモリに曞き蟌みブロックRAMBたたは分散分散 -それほど重芁ではありたせん、その埌、信号の入力サンプルが到着したずきにデヌタを呚期的に取埗するこずです。 原則ずしお、最新のFPGAでは、内郚メモリの量により、比范的小さなサむズのりィンドり関数を栌玍できたす。その埌、りィンドり関数に入力信号が乗算されたす。 小さいずは、64Kサンプルたでのりィンドり関数を意味したす。



しかし、りィンドり関数が長すぎる堎合はどうでしょうか たずえば、1Mの読み取り倀。 32ビットビットグリッドで衚瀺されるこのようなりィンドり関数には、RAMB36KタむプFPGAのザむリンクスクリスタルのNRAMB = 1024 * 1024 * 32/32768 = 1024ブロックメモリセルが必芁であるず簡単に蚈算できたす。 たた、16Mのサンプルの堎合は 16,000個のメモリセル 単䞀の最新FPGAにはそれほど倚くのメモリがありたせん。 倚くのFPGAでは、これは倚すぎたす。たた、FPGAリ゜ヌスそしおもちろん、顧客のお金を無駄に䜿甚しおいる堎合もありたす。



この点で、リモヌトデバむスからブロックメモリに係数を曞き蟌むこずなく、りィンドり関数サンプルをFPGAに盎接オンザフラむで生成する方法を考え出す必芁がありたす。 幞いなこずに、基本的なものは長い間発明されおきたした。 CORDIC  デゞタルデゞタル方匏などのアルゎリズムを䜿甚しお、匏が高調波信号ブラックマンハリス、ハン、ハミング、ナタヌルなどで衚される倚くのりィンドり関数を蚭蚈するこずができたす。



CORDIC



CORDICは、座暙系の回転を蚈算するための単玔で䟿利な反埩法です。これにより、プリミティブの加算およびシフト操䜜を実行しお耇雑な関数を蚈算できたす。 CORDICアルゎリズムを䜿甚しお、高調波信号sinx、cosxの倀を蚈算し、䜍盞-atanxおよびatan2x、y、双曲線䞉角関数を芋぀け、ベクトルを回転させ、数の根を抜出するなどができたす。



最初は、完成したCORDICカヌネルを䜿甚しお䜜業量を枛らしたかったのですが、ザむリンクスカヌネルには長い間嫌いがありたした。 githubのリポゞトリを調べた埌、私は提瀺されたすべおのカヌネルが倚くの理由に適しおいないこずに気付きたした䞍十分に文曞化されおいお読めず、普遍的ではなく、特定のタスクたたは芁玠ベヌスで䜜成され、verilogなどで曞かれおいたす。 それから、同志のlazifoにこの仕事をしおくれず頌みたした。 もちろん、CORDICの実装はDSPの分野で最も単玔なタスクの1぀であるため、圌はそれに察凊したした。 しかし、私は圌の仕事ず䞊行しおむラむラしおいるので、 自分のパラメヌタヌ化されたコアでバむクを曞きたした。 䞻な機胜は、 DATA_WIDTH出力信号の構成可胜なビット深床、 -1〜1の正芏化された入力フェヌズPHASE_WIDTH 、およびPRECISION蚈算の粟床です。 CORDICコアは、䞊列パむプラむンスキヌムに埓っお実行されたす。各クロックサむクルで、コアは蚈算を実行しお入力サンプルを受信する準備ができおいたす。 カヌネルは、出力サンプルの蚈算にNサむクルを費やしたす。その数は、出力サンプルの容量に䟝存したす容量が倧きいほど、出力倀を蚈算するための反埩が倚くなりたす。 すべおの蚈算は䞊行しお行われたす。 したがっお、CORDICはりィンドり関数を䜜成するための基本的なコアです。



りィンドり関数



この蚘事のフレヌムワヌクでは、高調波信号ハン、ハミング、さたざたな次数のブラックマン・ハリスなどで衚珟されるりィンドり関数のみを実珟したす。 これには䜕が必芁ですか 䞀般的に、りィンドりを構築するための匏は䞀連の有限長のように芋えたす。







係数a kの特定のセットず系列のメンバヌは、りィンドりの名前を決定したす。 最も人気があり、頻繁に䜿甚されるのは、異なる順序3〜11のBlackman-Harrisりィンドりです。 以䞋は、Blackman-Harrisりィンドりの係数の衚です。







原則ずしお、Blackman-Harrisりィンドりセットはスペクトル分析の倚くの問題に適甚可胜であり、GaussやKaiserなどの耇雑なりィンドりを䜿甚する必芁はありたせん。 Nattalたたはフラットトップりィンドりは、重量が異なるさたざたなりィンドりですが、Blackman-Harrisず同じ基本原理です。 シリヌズのメンバヌが倚いほど、サむドロヌブのレベルの抑制が匷くなるこずが知られおいたすりィンドり関数のビット深床の合理的な遞択に埓いたす。 タスクに基づいお、開発者は䜿甚するりィンドりの皮類を遞択するだけです。



FPGA実装-埓来のアプロヌチ



りィンドり関数のすべおのカヌネルは、FPGAでデゞタル回路を蚘述するための叀兞的なアプロヌチを䜿甚しお蚭蚈されおおり、VHDL蚀語で蚘述されおいたす。 以䞋は、䜜成されたコンポヌネントのリストです。





Blackman-Harrisりィンドりコンポヌネントの゜ヌスコヌドは3桁です。



entity bh_win_3term is generic ( TD : time:=0.5ns; --! Time delay PHI_WIDTH : integer:=10; --! Signal period = 2^PHI_WIDTH DAT_WIDTH : integer:=16; --! Output data width XSERIES : string:="ULTRA" --! for 6/7 series: "7SERIES"; for ULTRASCALE: "ULTRA"; ); port ( RESET : in std_logic; --! Global reset CLK : in std_logic; --! System clock AA0 : in std_logic_vector(DAT_WIDTH-1 downto 0); -- A0 AA1 : in std_logic_vector(DAT_WIDTH-1 downto 0); -- A1 AA2 : in std_logic_vector(DAT_WIDTH-1 downto 0); -- A2 ENABLE : in std_logic; --! Clock enable DT_WIN : out std_logic_vector(DAT_WIDTH-1 downto 0); --! Output DT_VLD : out std_logic --! Output data valid ); end bh_win_3term;
      
      





堎合によっおは、プロゞェクトにDSP48E1およびDSP48E2ノヌドを埋め蟌むためにUNISIMラむブラリを䜿甚したした。これにより、最終的にこれらのブロック内のパむプラむン凊理により蚈算速床を䞊げるこずができたすが、実際に瀺されおいるように、 P =のようなものをより速く簡単に曞くこずができたすA * B + Cおよびコヌドで次のディレクティブを指定したす。



 attribute USE_DSP of <signal_name>: signal is "YES";
      
      





これはうたく機胜し、シンセサむザヌに数孊関数が実装される芁玠のタむプを厳密に蚭定したす。



Vivado hls



さらに、 Vivado HLSツヌルを䜿甚しおすべおのコアを実装したした。 Vivado HLSの䞻な利点をリストしたす高レベル蚀語CたたはC ++での高速蚭蚈 Time-to-Market 、クロック呚波数の抂念の欠劂による開発ノヌドの迅速なモデリング、゜リュヌションの柔軟な構成リ゜ヌスずパフォヌマンスの芳点からプロゞェクト内のプラグマずディレクティブ、および高レベル蚀語の開発者向けの䜎゚ントリしきい倀。 䞻な欠点は、埓来のアプロヌチず比范した堎合のFPGAリ゜ヌスの最適でないコストです。 たた、埓来の叀いRTLメ゜ッドVHDL、Verilog、SVで提䟛される速床を達成するこずはできたせん。 さお、最倧の欠点はタンバリンず螊るこずですが、これはザむリンクスのすべおのCADの特城です。 泚Vivado HLSは、 任意粟床の利点を䜿甚しお曲がっお動䜜するため、Vivado HLSデバッガヌず実際のC ++モデルでは、しばしば異なる結果が埗られたした。



次の画像は、Vivado HLSで合成されたCORDICカヌネルのログを瀺しおいたす。 これは非垞に有益であり、䜿甚されるリ゜ヌスの量、カヌネルナヌザヌむンタヌフェむス、ルヌプずそのプロパティ、蚈算の遅延、出力倀の蚈算間隔シリアルおよびパラレル回路を蚭蚈する際に重芁の倚くの有甚な情報を衚瀺したす。







さたざたなコンポヌネント関数のデヌタを蚈算する方法も確認できたす。 フェヌズ0でフェヌズデヌタが読み取られ、ステヌゞ7および8でCORDICノヌドの結果が衚瀺されおいるこずがわかりたす。





Vivado HLSの結果Cコヌドから䜜成された合成RTLカヌネル。 ログは、時間分析で、カヌネルがすべおの制限を正垞に通過したこずを瀺しおいたす。







Vivado HLSのもう1぀の倧きな利点は、Cコヌドを怜蚌しお結果を怜蚌するために䜿甚されるモデルに基づいお、合成されたRTLコヌドをチェックするこずです。 これは原始的なテストかもしれたせんが、CずHDLのアルゎリズムの動䜜を比范するのに非垞にクヌルで䟿利だず思いたす。 以䞋は、Vivado HLSで取埗したりィンドり関数のカヌネル関数モデルのシミュレヌションを瀺すVivadoのスクリヌンショットです。







したがっお、すべおのりィンドり関数に぀いお、VHDLたたはC ++の蚭蚈方法に関係なく、同様の結果が埗られたした。 ただし、最初のケヌスでは、動䜜の頻床が高くなり、䜿甚されるリ゜ヌスの数が少なくなりたす。2番目のケヌスでは、最倧蚭蚈速床が達成されたす。 どちらのアプロヌチにも生呜に察する暩利がありたす。



具䜓的には、さたざたな方法を䜿甚しお開発に費やす時間を蚈算したした。 Vivado HLSでC ++プロゞェクトをVHDLよりも12倍高速に実装したした。



アプロヌチの比范



CORDICコアのHDLずC ++の゜ヌスコヌドを比范したす。 前述のように、アルゎリズムは加算、枛算、シフトの挔算に基づいおいたす。 VHDLでは、次のようになりたす3぀のデヌタベクトルがありたす-1぀は角床の回転を担圓し、他の2぀はXおよびY軞に沿ったベクトルの長さを決定したす。これはsinおよびcosず同等ですwikiの図を参照。







Z倀を繰り返し蚈算するこずにより、X倀ずY倀が䞊行しお蚈算されたすHDLで出力倀を巡回怜玢するプロセス



 constant ROM_LUT : rom_array := ( x"400000000000", x"25C80A3B3BE6", x"13F670B6BDC7", x"0A2223A83BBB", x"05161A861CB1", x"028BAFC2B209", x"0145EC3CB850", x"00A2F8AA23A9", x"00517CA68DA2", x"0028BE5D7661", x"00145F300123", x"000A2F982950", x"000517CC19C0", x"00028BE60D83", x"000145F306D6", x"0000A2F9836D", x"0000517CC1B7", x"000028BE60DC", x"0000145F306E", x"00000A2F9837", x"00000517CC1B", x"0000028BE60E", x"00000145F307", x"000000A2F983", x"000000517CC2", x"00000028BE61", x"000000145F30", x"0000000A2F98", x"0000000517CC", x"000000028BE6", x"0000000145F3", x"00000000A2FA", x"00000000517D", x"0000000028BE", x"00000000145F", x"000000000A30", x"000000000518", x"00000000028C", x"000000000146", x"0000000000A3", x"000000000051", x"000000000029", x"000000000014", x"00000000000A", x"000000000005", x"000000000003", x"000000000001", x"000000000000" ); pr_crd: process(clk, reset) begin if (reset = '1') then ---- Reset sine / cosine / angle vector ---- sigX <= (others => (others => '0')); sigY <= (others => (others => '0')); sigZ <= (others => (others => '0')); elsif rising_edge(clk) then sigX(0) <= init_x; sigY(0) <= init_y; sigZ(0) <= init_z; ---- calculate sine & cosine ---- lpXY: for ii in 0 to DATA_WIDTH-2 loop if (sigZ(ii)(sigZ(ii)'left) = '1') then sigX(ii+1) <= sigX(ii) + sigY(ii)(DATA_WIDTH+PRECISION-1 downto ii); sigY(ii+1) <= sigY(ii) - sigX(ii)(DATA_WIDTH+PRECISION-1 downto ii); else sigX(ii+1) <= sigX(ii) - sigY(ii)(DATA_WIDTH+PRECISION-1 downto ii); sigY(ii+1) <= sigY(ii) + sigX(ii)(DATA_WIDTH+PRECISION-1 downto ii); end if; end loop; ---- calculate phase ---- lpZ: for ii in 0 to DATA_WIDTH-2 loop if (sigZ(ii)(sigZ(ii)'left) = '1') then sigZ(ii+1) <= sigZ(ii) + ROM_TABLE(ii); else sigZ(ii+1) <= sigZ(ii) - ROM_TABLE(ii); end if; end loop; end if; end process;
      
      





C ++、Vivado HLSでは、コヌドはほずんど同じように芋えたすが、レコヌドは䜕倍も短くなりたす。



 // Unrolled loop // int k; stg: for (k = 0; k < NWIDTH; k++) { #pragma HLS UNROLL if (z[k] < 0) { x[k+1] = x[k] + (y[k] >> k); y[k+1] = y[k] - (x[k] >> k); z[k+1] = z[k] + lut_angle[k]; } else { x[k+1] = x[k] - (y[k] >> k); y[k+1] = y[k] + (x[k] >> k); z[k+1] = z[k] - lut_angle[k]; } }
      
      







どうやら、シフトず远加の同じサむクルが䜿甚されたす。 ただし、デフォルトでは、C ++蚀語向けに、Vivado HLSのすべおのルヌプは「折りたたみ」され、順次実行されたす。 HLS UNROLLたたはHLS PIPELINEプラグマの導入により、シリアル蚈算がパラレル蚈算に倉換されたす。 これにより、FPGAリ゜ヌスが増加したすが、各クロックサむクルで新しい倀を蚈算しおコアに送信できたす。



VHDLおよびC ++でのプロゞェクトの合成結果を䞋図に瀺したす。 論理的に芋るず、違いは2倍であり、埓来のアプロヌチを支持しおいたす。 その他のFPGAリ゜ヌスの堎合、差異はわずかです。 C ++でのプロゞェクトの最適化には深く入りたせんでしたが、さたざたなディレクティブを蚭定したり、コヌドを郚分的に倉曎したりするこずで、䜿甚するリ゜ヌスの数を枛らすこずができたす。 どちらの堎合も、タむミングは〜350 MHzの特定のコア呚波数で収束したした。





実装機胜



蚈算は固定小数点圢匏で実行されるため、りィンドり関数にはFPGAでDSPシステムを蚭蚈する際に考慮しなければならない倚くの機胜がありたす。 たずえば、りィンドり関数デヌタのビット深床が倧きいほど、りィンドりオヌバヌレむの粟床が向䞊したす。 䞀方、りィンドり関数のビット深床が䞍十分な堎合、結果の波圢に歪みが生じ、スペクトル特性の品質に圱響したす。 たずえば、2 ^ 20 = 1Mサンプルの期間の信号を乗算する堎合、りィンドり関数には少なくずも20ビットが必芁です。



おわりに



この蚘事では、倖郚メモリたたはFPGAブロックメモリを䜿甚せずにりィンドり関数を蚭蚈する1぀の方法を瀺したす。 FPGAおよび堎合によっおはDSPブロックの論理リ゜ヌスのみを䜿甚する方法が瀺されおいたす。 CORDICアルゎリズムを䜿甚するず、任意のビット深床理由内、任意の長さ、次数のりィンドり関数を取埗できるため、りィンドりのほがすべおのスペクトル特性のセットを取埗できたす。



䜜品の1぀では、玄375 MHzの呚波数で1Mサンプルに察しお5桁ず7桁のブラックマン・ハリス窓関数の安定しお動䜜するカヌネルを取埗し、玄400 MHzの呚波数でCORDICに基づいおFFTの回転係数のゞェネレヌタヌを䜜成するこずができたした。 䜿甚枈みFPGAクリスタルKintex Ultrascale +xcku11p-ffva1156-2-e。



githubプロゞェクトぞのリンクはこちら 。 プロゞェクトには、Matlabの数孊モデル、VHDLのりィンドり関数ずCORDICの゜ヌスコヌド、Vivado HLSのC ++のリストされたりィンドり関数のモデルが含たれおいたす。



有甚な蚘事





DSPに関する非垞に人気のある本、 Ayficher E.、Jervis B.のデゞタル信号凊理もお勧めしたす。 実甚的なアプロヌチ



ご枅聎ありがずうございたした



All Articles