このホワイトペーパーでは、IPコアの使用方法について概説します。 Mokuクラウドコンパイルこれには、一般的な信号処理機能向けの8つのプリコンパイル済みIPコアと、カスタムAMD Vivado IPコアの統合が含まれています。各コアについては、使用例とMokuハードウェアを使用したテストセットアップとともに解説されています。また、カスタムIPのアップロード方法についても説明しています。
イントロダクション
Moku Cloud Compile は、Moku デバイスで利用できる強力なツールです。Moku FPGA ベースのテストおよび計測デバイスを使用すると、ユーザーはカスタム VHDL および Verilog コードをハードウェアに展開できます。Moku Cloud Compile を使用すると、独自の設計を既存の計測器と統合して、Moku 独自の Instrument-on-Chip アーキテクチャによって可能になる新しい機能を作成することで、計測器の機能を拡張およびカスタマイズできます。Moku Cloud Compile は、算術、フィルタリング、波形生成、および相関分析に最適化された 8 つのプリコンパイル済み IP コアを提供し、すべての Moku デバイスと互換性があります。これらのコアは、一般的なデジタル信号処理タスクをインスタンス化して簡素化する準備ができています。ユーザーは、AMD Vivado で作成した独自の IP コアをアップロードしてインポートすることもできます。 .xci ファイルを使用することで、カスタムハードウェアブロックを Moku Cloud Compile デザインにシームレスに統合できます。このドキュメントでは、各 IP コアの入出力ポート、機能、使用例の概要を説明し、カスタムデザインの構築とテストに関するガイダンスを提供します。 マルチインストゥルメントモードこれらの機能を組み合わせることで、Moku Cloud Compile は、ラピッドプロトタイピングと高度な信号処理アプリケーションの両方に対応する、より強力なプラットフォームになります。
8つのプリコンパイル済みIPコア
このセクションでは、表1に示すXNUMXつのプリコンパイル済みIPコアについて、入出力ポートの仕様と機能について詳しく説明します。各コアのユースケース例も示します。これらのIPコアはMoku Cloud Compileバックエンドにネイティブ統合されているため、ユーザー設計内で直接インスタンス化でき、開発プロセスを効率化し、実装オーバーヘッドを削減できます。
表 1: XNUMX つのプリコンパイル済み IP コアの名前と説明。
| いいえ。 | IPコア名 | 詳細説明 |
| 1 | 加算減算_16 | 動的に再構成可能な加算器/減算器モジュール。 |
| 2 | CIC_Dec_3Ordx8 | デシメーション係数が 8、フィルタ次数が 3 のカスケード インテグレータ コム (CIC) デシメータ。 |
| 3 | コーディック翻訳16 | 16 ビットの実数および虚数入力を振幅および位相出力に変換するコンバーター。 |
| 4 | カウンター_32 | 同期クリア機能を備えたアップ/ダウン カウントをサポートする 32 ビット カウンター。 |
| 5 | シネジェン_48 | 48 ビットの周波数ステップ分解能を備えた正弦波および余弦波波形ジェネレーター。 |
| 6 | FIR_フィルター_7係数 | 固定係数を持つフルレート FIR ローパス フィルター。 |
| 7 | FFT_1024 | 順方向または逆方向の変換を選択できる 1,024 ポイントの高速フーリエ変換 (FFT) ブロック。 |
| 8 | FFT_65536 | 選択可能な順方向または逆方向の変換と構成可能な出力スケーリングを備えた 65,536 ポイントの高速フーリエ変換 (FFT) ブロック。 |
1. 加算減算_16
AddSubtract_16モジュールは、16つの符号付きXNUMXビット入力に対して加算または減算を実行できる、動的に構成可能な演算ユニットを実装します。その動作は以下のロジックによって制御されます。
\(S =left{ begin{array}{rl} A + B text{(add: HIGH)} A – B text{(add: LOW)} end{array} right.\)AddSubtract_16 コアの入力ポートと出力ポートの詳細は表 2 に示されています。入力バス (A と B) と出力 (S) はどちらも符号付き 16 ビット整数 (int16) として扱われます。算術演算は add 信号によって制御され、ce (クロックイネーブル) 信号はモジュールのクロックを有効または無効にします。ce がハイに保持されている間、モジュールは継続的にアクティブになります。
表 2: AddSubtract_16 モジュールのポート定義、入力および出力信号インターフェイスの詳細。
| 名前 | リーダーシップ | 詳細説明 |
| A[15:0] | 入力 | 入力Aバス。 |
| B[15:0] | 入力 | 入力Bバス。 |
| clk | 入力 | クロック信号、立ち上がりエッジ。 |
| 加えます | 入力 | AddSubtract_16 によって実行される演算を制御します。(HIGH = 加算、LOW = 減算) |
| ce | 入力 | アクティブHIGHクロックイネーブル。常にHIGHに設定します。 |
| S[15:0] | 出力 | 出力バス。 |
コード1は、モジュールをインスタンス化し、Control0の0番目のビット(最下位ビット、LSB)を使用して制御する方法を示すVHDLの例です。マルチインストゥルメントモードの構成は図1に示されています。図2と図3に示すテスト結果は、Mokuハードウェアを使用して実行され、さまざまな信号条件下での減算と加算の動作が正しく行われていることを確認しています。
コード 1: VHDL の例は、AddSubtract_16 モジュールのインスタンス化を示しています。ここで、OutputA は、Control0 レジスタの LSB の状態に応じて、InputA + InputB または InputA – InputB のいずれかの結果を表します。
LIBRARY ieee;
ARCHITECTURE Behavioral OF CustomWrapper IS
SIGNAL s_temp : STD_LOGIC_VECTOR(15 DOWNTO 0);
BEGIN
AddSubtract : AddSubtract_16
PORT MAP(
A => STD_LOGIC_VECTOR(InputA),
B => STD_LOGIC_VECTOR(InputB),
clk => clk,
-- use Control0's 0th bit to control the operation
add => Control0(0),
-- constant high clock enable
ce => '1',
S => s_temp
);
OutputA <= signed(s_temp);
END ARCHITECTURE;

図 1: マルチインストゥルメント モードを使用した AddSubtract_16 のテスト構成。この構成では、Moku Cloud Compile の InputA と InputB は Moku オシロスコープの出力から内部的にルーティングされ、Moku Cloud Compile の処理済み出力はオシロスコープにフィードバックされます。図 2 に示すように、Moku オシロスコープの 2 チャンネル組み込み波形発生器は、5 kHz、500 mV の正弦波と、90% の対称性を持つ 100 Hz、5 Vpp のランプ信号を生成するように構成されています。Control0 の LSB を 0 に設定すると、Moku Cloud Compile は減算モードで動作します。観測された出力は、 もくオシロスコープ 減算器の動作が期待通りであることを確認します。続いて、図3では、Control0のLSBが1に設定され、Moku Cloud Compileが加算を実行するように設定されます。結果の出力は、期待通りの加算機能であることを確認します。

図2:Moku Cloud Compileは、500 mVpp、5 kHzの正弦波と5 Vpp、100 Hzのランプ波という0つの入力信号を用いて減算結果を出力します。Control0(0)をXNUMXに設定すると、システムは減算モードで動作するように設定されます。

図 3: 500 mVpp 5 kHz 正弦波と 5 Vpp、100 Hz ランプ波に対する Moku Cloud Compile の出力。Control0(0) を 1 に設定すると、システムは加算モードに構成されます。AddSubtract_16 モジュールにはキャリーアウト機構が含まれていないため、算術演算中にオーバーフローが発生する可能性があることに注意することが重要です。具体的には、入力 A + 入力 B の合計が符号付き 16 ビット範囲 \([-2^{15}, 2^{15}]\) を超えると、オーバーフローにより出力の符号が反転する可能性があります。潜在的なオーバーフローを検出する一般的な方法は、オペランドの最上位ビット (MSB) と結果を監視することです。入力の符号が反対の場合はオーバーフローは発生しません。ただし、両方の入力が同じ符号で出力の符号が異なる場合は、通常、オーバーフロー状態を示しています。この論文ではこの問題を認識していますが、オーバーフローの検出と軽減技術の詳細な議論は現在の範囲外です。入力ソースは、5 Vppの正弦波と5 VのDC信号として構成されています。理論的には、この組み合わせにより、出力波形は2.5 Vから7.5 Vの範囲になるはずです。しかし、Moku:Goのハードウェアは±5 Vの入出力範囲(10 Vpp)に制限されています。そのため、この範囲を超える出力の部分は、オーバーフローにより符号が反転します。この動作は図4に示されており、5 Vから7.5 Vの間にあるはずの波形の部分が、代わりに折り返されて-2.5 Vから-5 Vの間に現れています。

図4:5Vpp、1kHzの正弦波と5VのDCオフセットを加算すると、信号がMoku:Goデバイスの±5V入力範囲を超えるため、オーバーフローが発生します。Control0(0)を1に設定すると、システムは加算モードで動作し、出力の符号反転によってオーバーフローの発生が確認されます。
2. CIC_Dec_3Ordx8
CIC_Dec_3Ordx8 モジュールは、固定デシメーション レート 8 の 3 次カスケード積分器コム (CIC) デシメーション フィルタを実装しています。CIC フィルタは、高いサンプリング レートをダウンサンプリングする必要があるマルチ レート システムで広く使用されています。このアーキテクチャは、加算器、減算器、および遅延のみに依存しているため、デジタル レシーバやロック イン アンプなどのハードウェア効率の高いダウンサンプリング アプリケーションに最適です。モジュールの入出力ポートの概要は表 3 に示されており、レイテンシやフィルタ次数などの実装の詳細は表 4 に示されています。このモジュールは 16 ビット符号付き入力サンプルを受け入れ、25 ビット符号付き出力サンプルを生成します。入力インターフェイスは、入力チャネルと出力チャネルの両方に対してハンドシェイク信号 (tvalid、tready) を提供します。フィルタは、有効な入力が受信され、コアが準備完了の場合にのみ出力を更新します。
表 3: CIC_Dec_3Ordx8 IP コアのポートの説明。
| 名前 | リーダーシップ | 詳細説明 |
| アクルク | 入力 | クロック信号、立ち上がりエッジ。 |
| s_axis_data_tdata [15:0] | 入力 | データ入力チャネルのTDATA。未処理のサンプルデータを伝送します。 |
| s_axis_data_t有効 | 入力 | データ入力チャネルのTVALID。外部ブロックがデータを提供可能であることを通知するために使用されます。 |
| s_axis_data_tready | 出力 | データ入力チャネルのTREADY。CICデシメータがデータの受信準備が完了したことを示すために使用されます。 |
| m_axis_data_tdata [24:0] | 出力 | データ出力チャネルのTDATA。処理されたサンプルデータを伝送します。 |
| m_axis_data_t有効 | 出力 | データ出力チャネルのTVALID。CICデシメータによってアサートされ、サンプルデータを提供可能であることを通知します。 |
表 4: CIC_Dec_3Ordx8 IP コアの構成パラメータ。
| コンポーネント名 | CIC_Dec_3Ordx8 |
| フィルタの種類 | 間引き |
| ステージ数 | 3 |
| 差動遅延 | 1 |
| サポートされているレート | 8 |
| 入力サンプル周波数(MSa/s) | 31.25 |
| クロック周波数(MHz) | 31.25 |
| 入力データ幅 | 16 |
| 出力データ幅 | 25 |
| レイテンシ | 15 |
コード2に示すVHDLの例では、入力データはコアが準備完了状態(s_axis_data_treadyがハイ)のときのみ書き込まれ、出力は有効なデータが利用可能なとき(m_axis_data_tvalidがハイ)のみ取得されます。出力は、入力のダイナミックレンジとの整合性を保つため、最上位16ビットに切り捨ててスケーリングされます。重要なのは、valid信号はアサートする必要があり、この信号がハイのときのみ出力を更新する必要があるということです。そうしないと、出力は連続的なストリームではなく、パルス状または断続的な動作を示す可能性があります。これは、CIC_Dec_3Ordx8がデシメーション係数に従って、8クロックサイクルごとに1つの有効な出力サンプルを生成するためです。
コード2:8倍のデシメーション係数を持つCICデシメータのインスタンス化を示すVHDLサンプル。信号OutputAは、信号InputAのダウンサンプリングされたバージョンを表します。
LIBRARY ieee;
ARCHITECTURE Behavioral OF CustomWrapper IS
SIGNAL s_axis_data_tready : STD_LOGIC;
SIGNAL s_axis_data_tdata : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL m_axis_data_tvalid : STD_LOGIC;
SIGNAL m_axis_data_tdata : STD_LOGIC_VECTOR(31 DOWNTO 0);
BEGIN
Decimator : CIC_Dec_3Ordx8
PORT MAP(
aclk => clk,
s_axis_data_tdata => s_axis_data_tdata,
s_axis_data_tvalid => '1', -- always output
s_axis_data_tready => s_axis_data_tready,
m_axis_data_tdata => m_axis_data_tdata,
m_axis_data_tvalid => m_axis_data_tvalid
);
PROCESS (clk)
BEGIN
IF rising_edge(clk) THEN
-- update input data when CIC is ready
IF s_axis_data_tready THEN
s_axis_data_tdata <= STD_LOGIC_VECTOR(InputA);
ELSE
s_axis_data_tdata <= (OTHERS => '0');
END IF;
-- update Output only when data is valid
IF m_axis_data_tvalid THEN
-- Scale data correctly
OutputA <= signed(m_axis_data_tdata(24 DOWNTO 9));
END IF;
END IF;
END PROCESS;
END ARCHITECTURE;
マルチインストゥルメントモードのテストセットアップでは、 Moku 周波数応答アナライザー フィルタの周波数応答を評価するための図を図5に示します。CICフィルタの周波数応答は、帯域外信号の減衰特性を示し、デシメーション時のエイリアシングノイズ抑制効果を反映するため、特に重要です。図6と図7の測定結果は、デシメーションと補間アーティファクトによる予想される差異を考慮しつつ、理論的な期待値と良好な一致を示しています。

図 5: Moku Cloud Compile 出力を Moku 周波数応答アナライザーを使用して分析するマルチインストゥルメント モードのテスト構成。

図 6: Moku 周波数応答アナライザを使用して取得した CIC_Dec_3Ordx8 IP コアの周波数応答。

図 7: CIC_Dec_3Ordx8 のシミュレーション応答と実装応答の比較。
3. Cordic_Translate_16
CORDICコアは、三角関数の計算、そしてより一般的には双曲線関数と平方根演算を含む方程式の解法として用いられる反復法である座標回転デジタルコンピュータ(CORDIC)アルゴリズムを実装しています。入出力ポートの説明は表5に示されています。このCordic_Translate_16コアは、入力信号を直交座標(実数部と虚数部)から対応する極座標(振幅と位相)に変換します。モジュール全体の計算レイテンシは20クロックサイクルです。
表 5: Cordic_Translate_16 IP コアのポート定義。
| 名前 | リーダーシップ | 詳細説明 |
| アクルク | 入力 | クロック。アクティブな立ち上がりエッジ。 |
| s_axis_cartesian_t有効 | 入力 | チャネル S_AXIS_CARTESIAN のハンドシェイク信号。 |
| s_axis_cartesian_tdata [31:0] | 入力 | 機能構成に応じて、このポートには1つまたは2つのサブフィールドがあります。X_INとY_INで、X_INは[15:0]、Y_INは[31:16]です。これらは直交座標オペランドです。各サブフィールドは16ビット幅です。X_INとY_INはどちらも14ビットの小数部と2ビットの整数部を持ちます。 |
| m_axis_dout_t無効 | 出力 | 出力チャネルのハンドシェイク信号。 |
| m_axis_dout_tdata [31:0] | 出力 | 機能構成に応じて、このポートには次のサブフィールドが含まれます。AMPLITUDE_OUT、PHASE_OUT。AMPLITUDE_OUTは[15:0]、PHASE_OUTは[31:16]です。各サブフィールドは16ビット幅です。AMPLITUDE_OUTは14ビットの小数部と2ビットの整数部を持ちます。PHASE_OUTは13ビットの小数部と3ビットの整数部を持ち、単位はラジアンです。 |
Cordic_Translate_16 IP コアは、コードの虚数 (InputA) と実数 (InputB) の成分を対応する振幅 (OutputA) と位相角 (OutputB) に変換するコード 3 を使用してインスタンス化できます。
コード 3: Cordic_Translate_16 IP コアのインスタンス化を示す VHDL 実装例。
LIBRARY ieee;
ARCHITECTURE Behavioral OF CustomWrapper IS
SIGNAL m_axis_dout_tvalid : STD_LOGIC;
SIGNAL tdata_temp : signed(31 DOWNTO 0);
BEGIN
Cordic : Cordic_Translate_16
PORT MAP(
aclk => clk,
-- input is always valid
s_axis_cartesian_tvalid => '1',
-- InputA : imaginary part
-- InputB : real part
s_axis_cartesian_tdata => STD_LOGIC_VECTOR(InputA & InputB),
m_axis_dout_tvalid => m_axis_dout_tvalid,
m_axis_dout_tdata => tdata_temp
);
PROCESS (clk)
BEGIN
IF rising_edge(clk) THEN
IF m_axis_dout_tvalid THEN
OutputA <= signed(tdata_temp(15 DOWNTO 0));
OutputB <= signed(tdata_temp(31 DOWNTO 16));
END IF;
END IF;
END PROCESS;
END ARCHITECTURE;
インスタンス化された Cordic_Translate_16 は、図 8 に示すマルチインストゥルメント モード設定を使用してテストされます。Moku Cloud Compile の入力 A (虚数部) と入力 B (実数部) は、Moku オシロスコープの出力から Moku Cloud Compile に内部的にルーティングされ、対応する振幅と位相の出力が計算されます。これらの Moku Cloud Compile の出力は、視覚化と分析のためにオシロスコープにルーティングされます。結果を図 9 に示します。青色のトレースは、約 3.1415 ラジアンに相当する 3.9288 V のピーク値に達します。位相出力は 13 ビットの小数部で表されるため、分解能は 2^13 LSB/rad です。デジタル値を物理単位に変換するには、Moku Cloud Compile のデジタル分解能を決定する必要があります。 こちらMoku:Goのデジタル解像度が6550.4 LSB/Vの場合、ラジアン値は次のように計算されます。
\(frac{text{3.9288 V} times text{6550.4 LSBs/V}}{2^{13} text{LSBs/rad}}=text{3.1415 rad}\)さらに、Cordic_Translate_16 によって実行される 20 回の反復中に導入されるスケーリング効果の蓄積により、振幅出力の大きさは約 1.1644 倍に増加します。

図 8: Cordic_Translate_16 IP コアをテストするためのマルチインストゥルメント モードのテスト セットアップ。

図9:100つの出力チャンネルに、5Vppの90Hz正弦波を2°位相シフトさせて入力し、連続的に回転する複素ベクトルをエミュレートしています。InputA(赤線)は振幅、InputB(青線)は位相に対応しています。予想通り、振幅は一定ですが、位相は時間の経過とともに直線的に増加し、XNUMXπラジアンごとに折り返しています。
4. カウンター_32
Counter_32 IPコアは、ルックアップテーブル(LUT)と単一のDSPスライスを用いたカウンタ実装を提供します。入力ポートと出力ポートの機能は表6に示されています。32ビットの出力幅を持つアップ/ダウンカウントモードをサポートします。カウンタはクロックサイクルごとにXNUMXずつインクリメントし、SCLR信号をハイにすることで同期クリアできます。
表 6: Counter_32 のポート定義。
| 名前 | リーダーシップ | 詳細説明 |
| CLK | 入力 | 立ち上がりエッジ クロック信号。 |
| SCLR | 入力 | 同期クリア: ハイに駆動されると、出力を強制的にロー状態にします。 |
| UP | 入力 | アップダウンカウンタのカウント方向を制御します。値が高ければカウントアップし、低ければカウントダウンします。 |
| 質問 [31:0] | 出力 | カウンター出力。32 ビット幅。 |
コード4の例では、32つのCounter_16関数を実装しています。65,536つは双方向カウントで三角波を生成し、もうXNUMXつは単方向カウントでノコギリ波を生成します。設計はXNUMX未満の範囲で動作するため、カウンタの下位XNUMXビットのみが出力に接続されています。
コード 4: 三角波とノコギリ波用に 32 つの Counter_XNUMX をインスタンス化する VHDL の例。
LIBRARY ieee;
ARCHITECTURE Behavioural OF CustomWrapper IS
SIGNAL sclr_triangular : STD_LOGIC;
SIGNAL sclr_sawtooth : STD_LOGIC;
SIGNAL up_triangular : STD_LOGIC;
SIGNAL up_sawtooth : STD_LOGIC;
SIGNAL q_triangular : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL q_sawtooth : STD_LOGIC_VECTOR(31 DOWNTO 0);
BEGIN
-- Triangular wave
Triangular : Counter_32
PORT MAP(
clk => clk,
-- synchronous clear
sclr => sclr_triangular,
up => up_triangular,
q => q_triangular
);
OutputA <= signed(q_triangular(15 DOWNTO 0));
-- Triangular counter configuration
PROCESS (clk) IS
BEGIN
IF rising_edge(clk) THEN
-- reset
IF Control0(0) = '1' THEN
sclr_triangular <= '1';
up_triangular <= '1';
ELSE
-- don't clear
sclr_triangular <= '0';
-- Control1: counter limit
IF q_triangular = Control1 THEN
-- count down
up_triangular <= '0';
ELSIF q_triangular = x"00000000" THEN
-- count up
up_triangular <= '1';
ELSE
-- hold
up_triangular <= up_triangular; END IF; END IF; END IF; END PROCESS; Sawtooth : Counter_32 PORT MAP( clk => clk,
sclr => sclr_sawtooth, -- synchronous clear
up => up_sawtooth,
q => q_sawtooth
);
OutputB <= signed(q_sawtooth(15 DOWNTO 0));
-- Sawtooth counter configuration
PROCESS (clk) IS
BEGIN
IF rising_edge(clk) THEN
-- reset
IF Control0(0) = '1' THEN
sclr_sawtooth <= '1';
up_sawtooth <= '1';
ELSE
-- always count up
up_sawtooth <= '1';
-- Control2 : counter limit
IF q_sawtooth = Control2 THEN
-- clear
sclr_sawtooth <= '1';
ELSE
-- continue counting
sclr_sawtooth <= '0';
END IF;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE;
マルチインストゥルメントモード構成を図 10 に示します。Moku オシロスコープを使用して、2 つの Counter_32 モジュールによって生成された波形を可視化します。両方のカウンタは、Control1 と Control2 を介して制御値 6,550 に設定され、Moku:Go のデジタル分解能 6550.4 LSB/V に基づくと、ピーク出力は約 1 V になります。Control0 の LSB はリセット信号として機能し、動作前にハイに設定してからローに戻す必要があります。予想どおり、鋸歯状波形は上向きにのみカウントするため、三角波の 2 倍の周波数を持ちます。三角波は上向きと下向きのカウントサイクルを交互に繰り返します。テスト結果を図 11 に示します。赤いトレースは、交互に上向きと下向きのカウントによって生成された三角波を表します。青いトレースは鋸歯状波形に対応し、連続的に増加し、設定された制限値 6,550 に達するとリセットされます。

図 10: Counter_32 をテストするためのマルチインストゥルメント モード構成。

図 11: Moku Cloud Compile 制御レジスタの構成と 32 つの Counter_XNUMX モジュールの対応する出力。
5. シネジェン_48
SineGen_48 IP コアは、高解像度で歪みの少ない正弦波を生成します。その入力ポートと出力ポートの詳細は表 7 に示されています。48 ビットの周波数ステップ入力を受け取り、32 ビット出力ポートを介して 16 ビットの正弦波と余弦波の両方を出力します。このモジュールは、位相同期ループや同時振幅周波数変調 (AM および FM) など、さまざまな高度なアプリケーションに適した正弦波発生器サブブロックとして機能します。SineGen_48 IP コアは 48 ビットの周波数ステップ入力を必要とし、Moku Cloud Compile の制御レジスタは 32 ビットに制限されているため、完全な 48 ビット入力を形成するには 2 つのレジスタを組み合わせる必要があります。たとえば、コード 5 では、Control2 の最下位 16 ビットが Control1 の 32 ビットと連結されて、完全な周波数制御ワードが構築されます。生成された出力は、正弦波と余弦波に対応する2つの16ビット成分に分割され、それぞれ出力Aと出力Bに送られます。さらに、内部位相カウンタの最上位16ビットは出力Cに送られます。
コード 5: SineGen_48 の VHDL インスタンス化の例。
LIBRARY ieee;
ARCHITECTURE Behavioural OF CustomWrapper IS
SIGNAL m_axis_data_tvalid : STD_LOGIC;
SIGNAL m_axis_phase_tvalid : STD_LOGIC;
SIGNAL sine_temp : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL m_axis_phase_tdata : STD_LOGIC_VECTOR(47 DOWNTO 0);
BEGIN
SineCosineGen : SineGen_48
PORT MAP(
aclk => clk,
-- Use the 0th bit of Control0 to reset this module
aresetn => NOT Control0(0),
-- input signal is always available
s_axis_config_tvalid => '1',
-- 48-bit frequency step
s_axis_config_tdata => Control2(15 DOWNTO 0) & Control1,
m_axis_data_tvalid => m_axis_data_tvalid,
m_axis_data_tdata => sine_temp,
m_axis_phase_tvalid => m_axis_phase_tvalid,
m_axis_phase_tdata => m_axis_phase_tdata -- 48-bit phase counter output
);
-- only output data when data is valid
PROCESS (clk)
BEGIN
IF rising_edge(clk) THEN
IF m_axis_data_tvalid THEN
-- 32-bit, the most significant 16 bits are sine
-- and the least significant 16 bits are cosine
OutputA <= signed(sine_temp(15 DOWNTO 0));
OutputB <= signed(sine_temp(31 DOWNTO 16));
END IF;
IF m_axis_phase_tvalid THEN
OutputC <= signed(m_axis_phase_tdata(47 DOWNTO 32));
END IF;
END IF;
END PROCESS;
END ARCHITECTURE;
SineGen_48 IPコアをテストするためのマルチインストゥルメントモード構成を図12に示す。周波数ステップは、Control1を2,374,548,092、Control2を6に設定することで3.125kHzに設定される。48ビットの周波数制御ワード全体は次のように計算される。
\(text{周波数ステップ} = text{制御2} × 2^{32} + text{制御1} = 2,814,749,767\)そして、Hz単位の周波数は次のように計算できます。
\(text{周波数} = frac{text{クロックレート}}{2^{48}}times [text{コントロール 2} times 2^{32} + text{コントロール 1}]\)Moku:Go のクロックレートが 31.25 MHz であることを考慮すると、出力周波数は 3.125 kHz になります。

図 12: SineGen_48 IP コアをテストするためのマルチインストゥルメント モード構成。図 13 は SineGen_48 IP コアの出力を示しており、チャネル A (赤) はコサイン波形、チャネル B (青) はサイン波形を表しています。2 つの信号間の測定された位相差は、予想どおり 90° です。さらに、図 14 は、Moku Cloud Compile の出力 C にルーティングされた位相カウンタの動作を示しています。出力は連続的に増加するランプを示しており、位相信号が生成されたコサイン波形と同じ周波数で進んでいることが確認できます。

図13:Mokuオシロスコープを用いて可視化した正弦波と余弦波。チャンネルA(赤)は余弦波信号、チャンネルB(青)は正弦波信号を示しています。周波数ステップは、Control1を2,374,548,092、Control2を6に設定しています。

図14:Mokuオシロスコープの入力はMoku Cloud Compileの出力Aと出力Cに接続されています。青いトレースは位相カウンタ出力の上位16ビットを表しています。
6. FIR_Filter_7coef
FIR_Filter_7coef IPコアは、固定係数でフルクロックレートで動作し、マルチインストゥルメントモード設定で追加のインストゥルメントを必要とせずにローパスフィルタをMoku Cloud Compile設計に統合する必要があるユーザーに、リソース効率の良いソリューションを提供します。フィルタ係数は表8に、ポート定義は表9に記載されています。調整可能な係数を必要とするアプリケーションの場合、ユーザーは以下を使用できます。 Moku FIR フィルタービルダー または、カスタムFIRフィルタIPコアを再コンパイルするには、 カスタマイズされたIPコア この論文のセクション。
表 8: FIR_Filter_7coef で使用される係数。

表 9: FIR_Filter_7coef のポート定義。
| 名前 | リーダーシップ | 詳細説明 |
| アクルク | 入力 | 立ち上がりエッジクロック。 |
| s_axis_data_t有効 | 入力 | 入力データチャネルでは無効です。外部ブロックによってアサートされ、データが転送可能であることを示します。 |
| s_axis_data_tready | 出力 | 入力データチャネルの準備完了。コアがデータを受け入れる準備ができていることを示すためにコアによってアサートされます。 |
| s_axis_data_tdata [15:0] | 入力 | 入力データチャネルのtdata。フィルタリングするデータストリームを伝達します。内部構造についてはtdata構造体を参照してください。 |
| m_axis_data_t有効 | 出力 | 出力データチャネルのtvalid。コアによってアサートされ、データが転送可能であることを示します。 |
| m_axis_data_tdata [23:0] | 出力 | 出力データチャネルのtdata。これはフィルタリングされたデータストリームです。内部構造についてはtdata構造体を参照してください。 |
FIR_Filter_7coef IPコアのVHDLインスタンス化はコード6に示されています。この例では、フィルタは連続入力データを処理し、連続出力ストリームを生成するように設計されているため、ハンドシェイク信号は省略されています。適切な出力スケーリングを確保するため、フィルタ出力の最上位16ビットがOutputAにルーティングされます。このアプリケーションノートでは、デュアルボックスカーアベレージャの実装について検討し、4つのシングルボックスカーアベレージャグループで構成されるコア構造の概要を説明します。
コード 6: FIR_Filter_7coef IP コアをインスタンス化する VHDL の例。
LIBRARY ieee;
ARCHITECTURE Behavioural OF CustomWrapper IS
SIGNAL FIR_out_temp : STD_LOGIC_VECTOR(23 DOWNTO 0);
BEGIN
FIR_Filter : FIR_Filter_7coef
PORT MAP(
aclk => clk,
-- input data is always valid
s_axis_data_tvalid => '1',
-- FIR filter ready to accept data
s_axis_data_tready => OPEN,
s_axis_data_tdata => InputA,
-- FIR filtered data is available to be transferred
m_axis_data_tvalid => OPEN,
m_axis_data_tdata => FIR_out_temp
);
OutputA <= signed(FIR_out_temp(23 DOWNTO 8));
END ARCHITECTURE;
FIR_Filter_7coef マルチ計測器モードのテスト セットアップを図 15 に示します。Moku 周波数応答アナライザで測定したフィルタ応答を図 16 に示します。シミュレーション応答と測定応答の比較を図 17 に示します。

図 15: FIR_Filter_7coef IP コアのマルチインストゥルメント モード構成。

図 16: Moku 周波数応答アナライザーを使用して取得した周波数応答。

図 17: 指定された FIR 係数に基づくシミュレートされた応答と測定された周波数応答の比較。
7. FFT_1024
高速フーリエ変換(FFT)IPコアは、離散フーリエ変換(DFT)を効率的に計算する手法であるCooley-Tukeyアルゴリズムを実装しています。このアルゴリズムは、大規模フィルタリング、相互相関、粗い周波数解析などのアプリケーションに適しています。表10は、FFT_1024の入力と出力の定義を示しています。このセクションでは、FFTコアの実装例を示します。
表 10: FFT_1024 IP コアのポート定義。
| 名前 | リーダーシップ | 詳細説明 |
| アクルク | 入力 | 立ち上がりエッジクロック。 |
| リセット | 入力 | アクティブロー同期クリア(オプション、常にaclkenより優先されます)。aresetnアクティブパルスは最低2サイクル必要です。 |
| s_axis_config_tdata[7:0] | 入力 | 構成チャネル用のtdata。構成情報(CP_LEN、FWD/INV、NFFT、SCALE_SCH)を伝送します。FWD/INV(順方向または逆方向FFT)の制御には、最下位ビット(0ビット目)のみが使用されます。その他のビットは空です。 |
| s_axis_config_t有効 | 入力 | 構成チャネルでは無効です。外部ブロックによってアサートされ、データを提供可能であることを通知します。 |
| s_axis_config_tready | 出力 | 構成チャネルのtready。コアが構成データを受け入れる準備ができていることを示すためにアサートされます。 |
| s_axis_data_tdata[31:0] | 入力 | データ入力チャンネルのtdata。未処理のサンプルデータを保持します。実部は[15:0]、虚部は[31:16]です。 |
| s_axis_data_t有効 | 入力 | データ入力チャネルのtvalid。外部ブロックがデータを供給可能であることを示すために使用します。常にHighに設定することもできます。 |
| s_axis_data_tready | 出力 | データ入力チャネルのtready。コアがデータを受け入れる準備ができていることを示すために使用されます。 |
| s_axis_data_tlast | 入力 | データ入力チャネルのtlast。フレームの最後のサンプルで外部ブロックによってアサートされます。これは、event_tlast_unexpectedおよびevent_tlast_missingイベントを生成する場合を除いて、コアでは使用されません。 |
| m_axis_data_tdata[63:0] | 出力 | データ出力チャンネルのtdata。処理されたサンプルデータを伝送します。実部は[58:32]、虚部は[26:0]です。信号はいずれも27ビットの符号付きで、小数部は15ビットです。 |
| m_axis_data_tuser[15:0] | 出力 | データ出力チャンネルのtuser。サンプルごとの情報のインデックスを保持します。 |
| m_axis_data_t有効 | 出力 | データ出力チャネルのtvalid。コアによってアサートされ、サンプルデータを提供可能であることを通知します。 |
| m_axis_data_tready | 入力 | データ出力チャネルのtready。外部スレーブによってアサートされ、データの受信準備が完了したことを通知します。 |
| m_axis_data_tlast | 出力 | データ出力チャネルのtlast。フレームの最後のサンプルでコアによってアサートされます。 |
| イベントフレーム開始 | 出力 | コアが新しいフレームの処理を開始するときにアサートされます。 |
| イベント_tlast_予期しない | 出力 | コアがフレーム内の最後ではないデータ サンプルで s_axis_data_tlast High を検出するとアサートされます。 |
| イベント_tlast_missing | 出力 | フレームの最後のデータ サンプルで s_axis_data_tlast が Low のときにアサートされます。 |
| イベントステータスチャネル停止 | 出力 | コアがステータス チャネルにデータを書き込もうとしたが、書き込めなかったときにアサートされます。 |
| イベントデータインチャネル停止 | 出力 | コアがデータ入力チャネルからデータを要求したが、利用可能なデータがない場合にアサートされます。 |
| イベントデータ出力チャネル停止 | 出力 | コアがデータ出力チャネルにデータを書き込もうとしたが、書き込めなかったときにアサートされます。 |
FFT_1024 IPコアのVHDLインスタンス化はコード7に示されています。入力信号は純粋に実数であるため、s_axis_data_tdataの最下位16ビットのみがInputAに接続され、FFT出力の実数部と虚数部の最上位16ビットが、対応する振幅と位相を計算するCordic_Translate_16モジュールの入力に接続されます。この例では、s_axis_config_tdataの最下位ビットをハイに設定することで、FFTはハードコードされた設定により順方向フーリエ変換として構成されます。イベント信号は、この例では使用されないため、意図的に接続されていません。各FFTフレームの終了はm_axis_data_tlast信号で示され、この信号が出力されるとFFTコアがリセットされ、次の処理サイクルに備えます。Cordic_Translate_16の20サイクルの処理遅延を考慮するため、FFT出力インデックス(m_axis_data_tuser)はそれに応じて遅延されます。得られた振幅、位相、および周波数ビンインデックスは、それぞれ出力A、出力B、および出力Cに送られます。
コード 7: FFT 出力を対応する振幅と位相の値に変換するために使用される、FFT_1024 IP コアと Cordic_Translate_16 モジュールのインスタンス化を示す VHDL の例。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ARCHITECTURE Behavioural OF CustomWrapper IS
TYPE array_tuser IS ARRAY (0 TO 19) OF signed(15 DOWNTO 0);
SIGNAL aresetn, aresetn_dly : STD_LOGIC;
SIGNAL s_axis_data_tdata : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL s_axis_data_tready : STD_LOGIC;
SIGNAL m_axis_data_tlast : STD_LOGIC;
SIGNAL m_axis_data_tvalid, m_axis_data_tvalid_dly : STD_LOGIC;
SIGNAL m_axis_data_tuser : signed(15 DOWNTO 0);
SIGNAL m_axis_data_tuser_dly : array_tuser;
SIGNAL m_axis_dout_tvalid : STD_LOGIC;
SIGNAL tdata_temp : signed(31 DOWNTO 0);
SIGNAL im, real : STD_LOGIC_VECTOR(26 DOWNTO 0);
SIGNAL fftdata_temp : STD_LOGIC_VECTOR(63 DOWNTO 0);
BEGIN
FFT_DUT : FFT_1024
PORT MAP(
aclk => clk,
aresetn => (NOT reset) AND aresetn AND aresetn_dly,
-- Forward FFT with the LSB configured as 1
s_axis_config_tdata => x"01",
-- Config data is always valid
s_axis_config_tvalid => '1',
-- Leave config ready signal open
-- config data is constant
s_axis_config_tready => OPEN,
-- Input only has real values
s_axis_data_tdata => s_axis_data_tdata,
-- Input data is always valid
s_axis_data_tvalid => '1',
-- Data ready logic
s_axis_data_tready => s_axis_data_tready,
-- Continuous data stream
-- don't have last sample
s_axis_data_tlast => '0',
-- Transformed data
m_axis_data_tdata => fftdata_temp,
-- FFT frequency index
m_axis_data_tuser => m_axis_data_tuser,
-- output is valid
m_axis_data_tvalid => m_axis_data_tvalid,
-- Slave device is always ready to accept output
m_axis_data_tready => '1',
-- last sample of the frame
m_axis_data_tlast => m_axis_data_tlast,
-- don't care events
event_frame_started => OPEN,
event_tlast_unexpected => OPEN,
event_tlast_missing => OPEN,
event_status_channel_halt => OPEN,
event_data_in_channel_halt => OPEN,
event_data_out_channel_halt => OPEN
);
-- only output data when data is valid
PROCESS (clk)
BEGIN
IF rising_edge(clk) THEN
IF s_axis_data_tready THEN
s_axis_data_tdata <= x"0000" & STD_LOGIC_VECTOR(InputA);
END IF;
IF m_axis_data_tvalid THEN
im <= fftdata_temp(58 DOWNTO 32);
real <= fftdata_temp(26 DOWNTO 0);
END IF;
m_axis_data_tuser_dly <= m_axis_data_tuser & m_axis_data_tuser_dly(0 TO 18);
END IF;
END PROCESS;
-- reset process
-- reset fft when the tlast is high
PROCESS (clk)
BEGIN
IF rising_edge(Clk) THEN
aresetn_dly <= aresetn;
IF m_axis_data_tlast THEN
aresetn <= '0';
ELSE
aresetn <= '1'; END IF; END IF; END PROCESS; Cordic : Cordic_Translate_16 PORT MAP( aclk => clk,
s_axis_cartesian_tvalid => m_axis_data_tvalid,
s_axis_cartesian_tdata => STD_LOGIC_VECTOR(im(26 DOWNTO 11) & real(26 DOWNTO 11)),
m_axis_dout_tvalid => m_axis_dout_tvalid,
m_axis_dout_tdata => tdata_temp
);
PROCESS (clk)
BEGIN
IF rising_edge(clk) THEN
IF m_axis_dout_tvalid THEN
OutputA <= signed(tdata_temp(15 DOWNTO 0));
OutputB <= signed(tdata_temp(31 DOWNTO 16));
OutputC <= signed(m_axis_data_tuser_dly(19));
END IF;
END IF;
END PROCESS;
END ARCHITECTURE;
マルチインストゥルメントモードのテスト構成と対応する出力信号を図18と図19に示します。図18はFFT_1024およびCordic_Translate_16 IPコアからの振幅出力の測定セットアップを示し、図19は位相出力をキャプチャするための構成を示しています。図18では、振幅スペクトルに2つのピークが見られます。1つは正の周波数範囲にあり、もう1つは負の周波数範囲にあります。正の周波数ピークに関連付けられたインデックスは、インデックスランプの開始からのタイムスタンプに対応します。Moku:Goクロックが31.25MHzで動作し、インデックスランプの合計時間スパンが32.684マイクロ秒であることを考慮すると、推定周波数は次のように計算されます。

\(text{周波数} = frac{text{10.531 } mu text{s}}{text{32.684 } mu text{s}} × text{31.25 MHz} = text{10.0689 MHz}\)1024ポイントFFTでは、分解能帯域幅が約0.03 MHzになることに注意してください。したがって、この実装は粗い周波数推定にのみ適しています。より正確な分析には、次の方法を使用することをお勧めします。 Moku位相計図19は、位相出力を赤色で示しています。位相は、取得サイクル全体にわたるFFT解析ウィンドウの変動により不安定に見えます。この例は機能的なデモンストレーションとして機能しますが、ウィンドウ機能やスーパーヘテロダインブロックなどの必須コンポーネントが欠けているため、完全なスペクトルアナライザとは言えません。

図18:FFT_1024 IPコアのマルチインストゥルメントモードのテスト構成と振幅出力結果。10MHzの正弦波がMoku Cloud CompileのInputAに入力され、FFT_1024モジュールによって処理されます。結果として得られる振幅スペクトルはチャンネルA(赤)に表示され、入力信号の正と負の周波数成分に対応するXNUMXつのピークが見られます。

図19:FFT_1024 IPコアのマルチインストゥルメントモードのテスト構成と位相応答。観測された位相応答は、入力信号に対するFFT解析ウィンドウのランダムな時間オフセットにより不安定に見えます。
8. FFT_65536
FFT_65536はFFT_1024の派生版で、同じIPコアコンパイラを使用して生成されますが、FFTポイント数を増やした構成になっています。両コアは同じ基盤を共有していますが、FFT_65536はポイント数の増加に対応するため、構成パラメータと出力データ形式が異なります。詳細なポート仕様と更新された信号接続については表11に示されており、変更点は強調表示されています。ハードウェアリソースの制限により、FFT_65536 IPコアはMoku:GoまたはMoku:Labではサポートされておらず、Moku:Proにデプロイする必要があります。
表11: FFT_65536 IPコアのポート定義。FFT_1024と異なるパラメータは太字で示されています。
| 名前 | リーダーシップ | 詳細説明 |
| アクルク | 入力 | 立ち上がりエッジクロック。 |
| リセット | 入力 | アクティブロー同期クリア(オプション、常にaclkenより優先されます)。aresetnアクティブパルスは最低2サイクル必要です。 |
| s_axis_config_tdata[39:0] | 入力 | 設定チャネルのtdata。0ビット目は順方向または逆方向のFFTを制御します。[32:1]は出力のスケールです。その他のビットは空です。 |
| s_axis_config_t有効 | 入力 | 構成チャネルでは無効です。 |
| s_axis_config_tready | 出力 | 構成チャネルの準備が整いました。 |
| s_axis_data_tdata[31:0] | 入力 | データ入力チャンネルのtdata。未処理のサンプルデータ(実数[15:0]と虚数[31:16])を伝送します。 |
| s_axis_data_t有効 | 入力 | データ入力チャネルでは無効です。一定のハイに設定してください。 |
| s_axis_data_tready | 出力 | データ入力チャネルのtready。コアがデータを受け入れる準備ができていることを示すために使用されます。 |
| s_axis_data_tlast | 入力 | データ入力チャネルのtlast。フレームの最後のサンプルで外部マスターによってアサートされます。 |
| m_axis_data_tdata[31:0] | 出力 | データ出力チャンネルのtdata。処理されたサンプルデータの実数部[15:0]と虚数部[31:16]を出力します。信号形式は16ビット符号付きで、小数部は15ビットです。 |
| m_axis_data_tuser[15:0] | 出力 | データ出力チャンネルのtuser。サンプルごとの情報のインデックスを保持します。 |
| m_axis_data_t有効 | 出力 | データ出力チャネルのtvalid。コアによってアサートされ、サンプルデータを提供可能であることを通知します。 |
| m_axis_data_tready | 入力 | データ出力チャネルのtready。外部ブロックによってアサートされ、データの受信準備が完了したことを通知します。 |
| m_axis_data_tlast | 出力 | データ出力チャネルのtlast。フレームの最後のサンプルでコアによってアサートされます。 |
| イベントフレーム開始 | 出力 | コアが新しいフレームの処理を開始するときにアサートされます。 |
| イベント_tlast_予期しない | 出力 | コアがフレーム内の最後ではないデータ サンプルで s_axis_data_tlast High を検出するとアサートされます。 |
| イベント_tlast_missing | 出力 | フレームの最後のデータ サンプルで s_axis_data_tlast が Low のときにアサートされます。 |
| イベントステータスチャネル停止 | 出力 | コアがステータス チャネルにデータを書き込もうとしたが、書き込めなかったときにアサートされます。 |
| イベントデータインチャネル停止 | 出力 | コアがデータ入力チャネルからデータを要求したが、利用可能なデータがない場合にアサートされます。 |
| イベントデータ出力チャネル停止 | 出力 | コアがデータ出力チャネルにデータを書き込もうとしたが、書き込めなかったときにアサートされます。 |
FFT_65536とCordic_Translate_16をインスタンス化するVHDLの例をコード8に示します。Moku Cloud Compileの出力には、InputAの振幅と位相スペクトル、および周波数インデックスが含まれます。さらに、Control0はスケールパラメータの設定に使用され、Control1のLSBはFFTの方向を決定します。
コード 8: 65536 つの FFT_16 モジュールと XNUMX つの Cordic_Translate_XNUMX モジュールのインスタンス化を示す VHDL の例。
LIBRARY ieee;
ARCHITECTURE Behavioural OF CustomWrapper IS
TYPE array_tuser IS ARRAY (0 TO 19) OF signed(15 DOWNTO 0);
SIGNAL aresetn, aresetn_dly : STD_LOGIC;
SIGNAL s_axis_data_tdata : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL s_axis_data_tready : STD_LOGIC;
SIGNAL m_axis_data_tlast : STD_LOGIC;
SIGNAL m_axis_data_tvalid, m_axis_data_tvalid_dly : STD_LOGIC;
SIGNAL count_out, m_axis_data_tuser : signed(15 DOWNTO 0);
SIGNAL m_axis_data_tuser_dly : array_tuser;
SIGNAL fftdata_temp : signed(31 DOWNTO 0);
SIGNAL real, im : signed(15 DOWNTO 0);
SIGNAL m_axis_dout_tvalid : STD_LOGIC;
SIGNAL tdata_temp : signed(31 DOWNTO 0);
BEGIN
FFT_DUT : FFT_65536
PORT MAP(
aclk => clk,
-- aresetn => (not Reset) and FFT_reset and FFT_reset_dly,
aresetn => (NOT reset) AND aresetn AND aresetn_dly,
-- Control FFT direction with LSB of Control1
-- and scale of the FFT output with Control0
s_axis_config_tdata => "0000000" & Control0(31 DOWNTO 0) & Control1(0),
-- Config data is always valid
s_axis_config_tvalid => '1',
-- Leave config ready signal open
-- config data is constant
s_axis_config_tready => OPEN,
-- Input only has real values
s_axis_data_tdata => s_axis_data_tdata,
-- Input data is always valid
s_axis_data_tvalid => '1',
-- Data ready logic
s_axis_data_tready => s_axis_data_tready,
-- Continuous data stream
-- don't have last sample
s_axis_data_tlast => '0',
-- Transformed data
m_axis_data_tdata => fftdata_temp,
-- FFT frequency index
m_axis_data_tuser => m_axis_data_tuser,
-- output is valid
m_axis_data_tvalid => m_axis_data_tvalid,
-- Slave device is always ready to accept output
m_axis_data_tready => '1',
-- last sample of the frame
m_axis_data_tlast => m_axis_data_tlast,
-- don't care events
event_frame_started => OPEN,
event_tlast_unexpected => OPEN,
event_tlast_missing => OPEN,
event_status_channel_halt => OPEN,
event_data_in_channel_halt => OPEN,
event_data_out_channel_halt => OPEN
);
-- only output data when data is valid
PROCESS (clk)
BEGIN
IF rising_edge(clk) THEN
IF s_axis_data_tready THEN
s_axis_data_tdata <= x"0000" & STD_LOGIC_VECTOR(InputA);
END IF;
IF m_axis_data_tvalid THEN
-- real part
real <= fftdata_temp(15 DOWNTO 0);
-- imaginary part
im <= fftdata_temp(31 DOWNTO 16);
END IF;
-- delay 20 clk cycles
m_axis_data_tuser_dly <= m_axis_data_tuser & m_axis_data_tuser_dly(0 TO 18);
END IF;
END PROCESS;
-- reset process
-- reset fft when the tlast is high
PROCESS (clk)
BEGIN
IF rising_edge(Clk) THEN
aresetn_dly <= aresetn;
IF m_axis_data_tlast THEN
aresetn <= '0';
ELSE
aresetn <= '1'; END IF; END IF; END PROCESS; Cordic : Cordic_Translate_16 PORT MAP( aclk => clk,
s_axis_cartesian_tvalid => m_axis_data_tvalid,
s_axis_cartesian_tdata => STD_LOGIC_VECTOR(im & real),
m_axis_dout_tvalid => m_axis_dout_tvalid,
m_axis_dout_tdata => tdata_temp
);
PROCESS (clk)
BEGIN
IF rising_edge(clk) THEN
IF m_axis_dout_tvalid THEN
OutputA <= signed(tdata_temp(15 DOWNTO 0));
OutputB <= signed(tdata_temp(31 DOWNTO 16));
OutputC <= signed(m_axis_data_tuser_dly(19));
END IF;
END IF;
END PROCESS;
END ARCHITECTURE;
Moku:Pro マルチインストゥルメントモードのテスト構成を図20に示します。テスト対象信号はMokuオシロスコープの内蔵波形発生器によって生成され、内部デジタル信号バスを介してMokuクラウドコンパイルの入力にルーティングされます。MokuクラウドコンパイルはXNUMXつの出力を生成します。OutputAとOutputBは変換された振幅と位相を表し、OutputCは周波数インデックスに対応します。これらの出力はオシロスコープの入力に接続され、モニタリングされます。

図 20: Moku:Pro FFT_65536 のテストマルチインストゥルメント モード構成。FFT_65536 の出力振幅と周波数インデックスを図 21 に示します。Control0 は信号のオーバーフローを防ぐために微調整され、Control1 は順方向 FFT を実行するために 1 に設定されています。65,536 ポイント FFT に符号付き 16 ビット表現を使用しているためオーバーフローが発生し、周波数インデックスの符号が反転しているように見えることに注意が必要です。ただし、このオーバーフローは負の周波数と正の周波数を効果的に区別するため、無害です。振幅チャネルは、80 MHz 周波数インデックス付近にピークを示します。これは、Moku:Pro Moku Cloud Compile のクロック レートが 312.5 MHz であることを考慮すると、Moku Cloud Compile からの 80 MHz 入力信号に対応します。

\(text{周波数} = frac{53.86 mu text{s}}{104.95 mu text{s}} × frac{312.5 text{MHz}}{2} = 80.19 text{MHz}\)

図 21: インスタンス化された FFT_65536 のテスト結果と対応する振幅スペクトル出力。
カスタマイズされたIPコア
Moku Cloud Compileでは、Vivadoで生成されたIPコアの構成を定義するカスタム.xciファイルをアップロードすることもできます。Moku Cloud Compileはこれらの.xciファイルを解析し、対応するIPコアをバックエンドにロードして、ユーザーデザイン内でインスタンス化できるようにします。Moku Cloud Compileバックエンドとの互換性を確保するため、.xciファイルはVivadoバージョン2022.2を使用して生成する必要があることに注意してください。Vivado 2022.2でサポートされているすべてのIPコアは、Moku Cloud Compileでも同様にサポートされています。Vivado 2022.2は、以下のサイトからダウンロードできます。 AMDの公式ウェブサイト次のセクションでは、このプロセスを説明する例を示します。
1. Vivado プロジェクトを作成します。
プロジェクト作成プロセスでは、適切なハードウェアプラットフォームを選択することが重要です。ターゲットFPGAデバイスは、セットアッププロセスの一環として指定する必要があります。表12に、サポートされている22つのハードウェアプラットフォームのFPGAプラットフォームモデルを示します。また、図XNUMXに構成例を示します。
表 12: Moku プラットフォームの FPGA モデル番号。
| Platform | FPGAモデル |
| Moku:Go | xc7z020clg400-1 |
| Moku:Lab | xc7z020clg484-3 |
| Moku:Pro | xczu9egffvc900-2 |

図22:適切なFPGAプラットフォーム設定を使用して、Vivadoでプロジェクトを作成する必要があります。この例では、ターゲットデバイスとしてMoku:Goプラットフォームが選択されています。
2. IPコアを構築し、.xciファイルを見つける
カスタムIPコアは、図23に示す手順に従ってコンパイルできます。まず、 IPカタログ Project Manager 左側のパネル(ステップ1)で、必要なIPコアを選択します。次に、右側のパネルのリストから必要なIPコアを選択します(ステップ2)。設定中にクロック周波数が必要になる場合があります。プラットフォーム固有のクロックレートは表13に記載されています。IPコアの設定が完了すると、 ソース ウィンドウ(ステップ3)。生成された.xciファイルの場所は、 ソースファイルのプロパティ パネル(ステップ4)。
表 13: さまざまなハードウェア プラットフォームでの Moku Cloud Compile のクロック レート。
| Platform | Moku Cloud Compile のクロックレート (MHz) |
| Moku:Go | 31.25 |
| Moku:Lab | 125 |
| Moku:Pro | 312.5 |

図 23: IP コアを構成するプロセス。
3. .xciファイルをMoku Cloud Compileにアップロードし、OUTPUTDIRを変更する
IPコアがコンパイルされたら、.xciファイルをアップロードする必要があります。 Moku Cloud Compile ウェブインターフェースMoku Cloud Compileバックエンドでの再コンパイルを確実に成功させるには、 出力DIR パラメータは「../output」に設定する必要があります。この処理の例を図24に示します。

図24:.xciファイルをMoku Cloud Compileにアップロードし、OUTPUTDIRを「../output」に設定して、正しくコンパイルされるようにします。
4. Moku Cloud CompileでIPコアをインスタンス化し、デザインをビルドする
Moku Cloud Compile でカスタム IP コアをインスタンス化するには、ポート構成と信号接続を理解することが不可欠です。図 25 は、インスタンス化テンプレートを見つけるプロセスを示しています。まず「IP Sources」を選択し、インスタンス化のサンプルとなる .vho ファイルと .veo ファイルを見つけます。.vho ファイルは VHDL 用、.veo ファイルは Verilog 用です。

図25:IPコアインスタンス化テンプレートの場所。次に、テンプレートを使用してカスタムIPコアをインスタンス化するプロセスを図26に示します。これでセットアップは完了です。その後、Moku Cloud Compile内でカスタムIPコアをコンパイルしてビットストリームを生成できます。

図 26: Moku Cloud Compile 内で IP コアをインスタンス化し、その信号を CustomWrapper モジュールの対応するポートに接続します。
Verilogサポート
VerilogはVHDLと同様にハードウェア記述言語ですが、一般的にVHDLよりも簡潔で、ハードウェアモデリングと密接に関連しています。VHDLでは、通常、ユーザーはCustomWrapperエンティティの動作アーキテクチャのみを定義しますが、VerilogではCustomWrapperモジュール全体の宣言と構造定義の両方が必要です。これには、CustomWrapperポートと内部ロジックの明示的な指定が含まれます。このセクションでは、コード9に示すように、Verilogを使用してAddSubtract_16 IPコアをインスタンス化する例を示します。Verilogは、 大文字と小文字を区別したがって、合成エラーや動作エラーを回避するには、大文字と小文字を正しく使い、命名に一貫性を持たせることが不可欠です。
コード 9: AddSubtract_16 IP コアのサポートを示す Verilog 実装の例。
module CustomWrapper (
input wire Clk,
input wire Reset,
input wire [31:0] Sync,
// 4 input ports
input wire signed [15:0] InputA,
input wire signed [15:0] InputB,
input wire signed [15:0] InputC,
input wire signed [15:0] InputD,
// external trigger input port
input wire ExtTrig,
// 4 output ports
output wire signed [15:0] OutputA,
output wire signed [15:0] OutputB,
output wire signed [15:0] OutputC,
output wire signed [15:0] OutputD,
// enable/disable interpolation
output wire OutputInterpA,
output wire OutputInterpB,
output wire OutputInterpC,
output wire OutputInterpD,
// 16 control registers
input wire [31:0] Control0,
input wire [31:0] Control1,
input wire [31:0] Control2,
input wire [31:0] Control3,
input wire [31:0] Control4,
input wire [31:0] Control5,
input wire [31:0] Control6,
input wire [31:0] Control7,
input wire [31:0] Control8,
input wire [31:0] Control9,
input wire [31:0] Control10,
input wire [31:0] Control11,
input wire [31:0] Control12,
input wire [31:0] Control13,
input wire [31:0] Control14,
input wire [31:0] Control15
);
AddSubtract_16 AddSubtract_DUT (
.A(InputA), // input wire [15 : 0] A
.B(InputB), // input wire [15 : 0] B
.CLK(Clk), // input wire CLK
.ADD(Control0[0]), // input wire ADD
.CE(1'b1), // input wire CE
.S(OutputA) // output wire [15 : 0] S
);
endmodule
サンプル Verilog コードを Moku Cloud Compile にアップロードすると、AddSubtract_16 モジュールを正常にコンパイルでき、図 27 に示すように、対応するビットストリームが生成されます。

図 27: AddSubtract_16 モジュールをコンパイルし、Verilog コードからビットストリームを生成するための Moku Cloud Compile インターフェース。
製品概要
Moku Cloud Compileは、算術演算、フィルタリング、波形生成、スペクトル解析などの信号処理タスク向けに、8つのプリコンパイル済みIPコアを提供します。各コアについては、詳細なポート定義、VHDL実装例、Mokuハードウェアプラットフォーム上のマルチインストゥルメントモードを使用したテスト構成とともに、上記で説明しています。組み込みコアに加えて、Vivado 2022.2で生成された.xciファイルをインポートすることで、カスタムIPコアをアップロードすることもできます。Moku Cloud Compileは、VerilogとVHDLの両方をサポートしています。これらの機能により、Moku Cloud Compileの機能が強化され、FPGAベースのデジタル信号処理ソリューションを迅速に開発・展開するための強力かつ柔軟なプラットフォームとなっています。



