このホワイトペーパーでは、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ビット入力に対して加算または減算を実行できる、動的に構成可能な演算ユニットを実装します。その動作は以下のロジックによって制御されます。
$latex S =left{begin{array}{rl}
A + B テキスト{(追加: HIGH)} \
A – B テキスト{(追加: LOW)}
配列の右を終了します。$
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オシロスコープの5チャンネル内蔵波形発生器は、500kHz、100mVの正弦波と、5%の対称性を持つ90Hz、0Vppのランプ波を生成するように設定されています。Control0のLSBをXNUMXに設定すると、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)と結果を監視することです。入力の符号が逆であればオーバーフローは発生しません。しかし、両方の入力の符号が同じで出力の符号が異なる場合は、通常、オーバーフロー状態を示します。本稿ではこの問題を認識していますが、オーバーフローの検出と軽減技術の詳細な議論は、現時点では本稿の範囲を超えています。
入力ソースは5Vppの正弦波と5VのDC信号に設定されています。理論的には、この組み合わせで2.5V~7.5Vの出力波形が生成されるはずです。しかし、Moku:Goハードウェアの入出力範囲は±5V(10Vpp)に制限されています。そのため、この範囲を超える出力部分では、オーバーフローにより符号反転が発生します。この動作は図4に示されており、本来5V~7.5Vの範囲にあるべき波形部分が折り返され、-2.5V~-5Vの範囲に現れています。
図4:5Vpp、1kHzの正弦波と5VのDCオフセットを加算すると、信号がMoku:Goデバイスの±5V入力範囲を超えるため、オーバーフローが発生します。Control0(0)を1に設定すると、システムは加算モードで動作し、出力の符号反転によってオーバーフローの発生が確認されます。
2. CIC_Dec_3Ordx8
CIC_Dec_3Ordx8モジュールは、固定デシメーションレート3の8次カスケード積分器櫛形(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がHigh)でのみ書き込まれ、出力は有効なデータが存在する状態(m_axis_data_tvalidがHigh)でのみキャプチャされます。出力は、入力ダイナミックレンジとの一貫性を保つために、上位16ビットに切り捨てられてスケーリングされます。valid信号はアサートされている必要があり、この信号がHighの場合にのみ出力を更新する必要があることに注意することが重要です。そうしないと、出力は連続的なストリームではなく、パルス状または断続的な動作を示す可能性があります。これは、CIC_Dec_3Ordx8がデシメーション係数に従って、XNUMXクロックサイクルごとにXNUMXつの有効な出力サンプルを生成するためです。
コード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のInputA(虚数)とInputB(実数)は、Mokuオシロスコープの出力からMoku Cloud Compileに内部的にルーティングされ、対応する振幅と位相の出力が計算されます。これらのMoku Cloud Compile出力は、可視化と解析のためにオシロスコープに再びルーティングされます。
結果は図9に示されています。青いトレースは3.9288Vのピーク値に達し、これは約3.1415ラジアンに相当します。位相出力は13小数ビットで表されるため、分解能は2^13LSB/radです。デジタル値を物理単位に変換するには、Moku Cloud Compileのデジタル分解能を決定する必要があり、その値は以下のとおりです。 こちらMoku:Goのデジタル解像度が6550.4 LSB/Vの場合、ラジアン値は次のように計算されます。
\(frac{text{3.9288 V} × text{6550.4 LSB/V}}{2^{13} text{LSB/rad}}=text{3.1415 rad}\)
さらに、Cordic_Translate_1.1644 によって実行された 20 回の反復中に導入されたスケーリング効果の蓄積により、振幅出力の大きさは約 16 倍に増加します。
図 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オシロスコープを使用して、32つのCounter_6,550モジュールによって生成された波形を視覚化しています。両方のカウンタは、Control1とControl2を介して制御値1に設定されており、Moku:Goのデジタル分解能6550.4 LSB/Vに基づいて、ピーク出力は約0Vになります。ControlXNUMXのLSBはリセット信号として機能し、動作前にハイに設定してからローに戻す必要があります。予想どおり、のこぎり波は三角波のXNUMX倍の周波数を持ちます。これは、三角波が上昇と下降のカウントサイクルを交互に繰り返すのに対し、のこぎり波は上昇のみをカウントするためです。
テスト結果は図11に示されています。赤いトレースは、カウントアップとカウントダウンを交互に繰り返すことで生成される三角波形を表しています。青いトレースは、連続的に増加し、設定された制限値6,550に達するとリセットされる鋸歯状波形に対応しています。
図 10: Counter_32 をテストするためのマルチインストゥルメント モード構成。
図 11: Moku Cloud Compile 制御レジスタの構成と 32 つの Counter_XNUMX モジュールの対応する出力。
5. シネジェン_48
SineGen_48 IPコアは、高解像度で低歪みの正弦波形を生成します。その入出力ポートの詳細は表7をご覧ください。48ビットの周波数ステップ入力を受け付け、16ビットの出力ポートから32ビットの正弦波と余弦波の両方を出力します。このモジュールは、位相同期回路(PLL)や振幅・周波数同時変調(AM/FM)など、幅広い高度なアプリケーションに適した正弦波形生成器サブブロックとして機能します。
SineGen_48 IPコアは48ビットの周波数ステップ入力を必要としますが、Moku Cloud Compileの制御レジスタは32ビットに制限されているため、48つのレジスタを組み合わせて完全な5ビット入力を形成する必要があります。例えば、コード16では、Control2の下位32ビットとControl1の16ビットを連結して、完全な周波数制御ワードを構築しています。生成された出力は、正弦波と余弦波に対応する16つのXNUMXビット成分に分割され、それぞれOutputAとOutputBに出力されます。さらに、内部位相カウンタの上位XNUMXビットはOutputCに出力されます。
コード 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 に示します。Control3.125 を 1 に、Control2,374,548,092 を 2 に設定することで、周波数ステップを 6 kHz に設定します。完全な 48 ビット周波数制御ワードは次のように計算されます。
\(text{周波数ステップ} = text{コントロール2} × 2^{32} + text{コントロール1} = 2,814,749,767\)
Hz 単位の周波数は次のように計算できます。
\(text{周波数} = frac{text{クロックレート}}{2^{48}}×[text{コントロール 2}×2^{32} + text{コントロール 1}]\)
Moku:Go のクロック レートが 31.25 MHz であるため、出力周波数は 3.125 kHz になります。
図 12: SineGen_48 IP コアをテストするためのマルチインストゥルメント モード構成。
図13はSineGen_48 IPコアの出力を示しており、チャンネルA(赤)はコサイン波形、チャンネルB(青)はサイン波形を表しています。90つの信号間の位相差は予想通り14°でした。また、図XNUMXはMoku Cloud CompileのOutputCに接続された位相カウンタの動作を示しています。出力は連続的に増加するランプを示しており、位相信号が生成されたコサイン波形と同じ周波数で進んでいることが確認できます。
図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または逆方向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のLSBをHighに設定することで、FFTを順方向フーリエ変換としてハードコード設定しています。イベント信号は、この例では使用しないため、意図的に未接続のままにしています。各FFTフレームの終了はm_axis_data_tlast信号によって示され、FFTコアは次の処理サイクルの準備のためにリセットされます。
Cordic_Translate_20の16サイクルの処理遅延を考慮すると、FFT出力インデックス(m_axis_data_tuser)はそれに応じて遅延されます。結果として得られる振幅、位相、周波数ビンのインデックスは、それぞれOutputA、OutputB、OutputCに出力されます。
コード 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では、振幅スペクトルに31.25つのピークが見られます。32.684つは正の周波数範囲に、もうXNUMXつは負の周波数範囲にあります。正の周波数ピークに関連付けられたインデックスは、インデックスランプの開始点を基準としたタイムスタンプに対応しています。Moku:GoクロックがXNUMXMHzで動作し、インデックスランプの全時間幅がXNUMXマイクロ秒であることを考えると、推定周波数は次のように計算されます。
![]()
\(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.03MHzとなることに注意が必要です。したがって、この実装は大まかな周波数推定にのみ適しています。より正確な解析を行うには、 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ポイント数の増加に対応するため、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は1に設定されて順方向FFTを実行します。16ポイントのFFTに符号付き65,536ビット表現を使用しているため、周波数インデックスの符号が反転しているように見え、オーバーフローが発生することに注意してください。ただし、このオーバーフローは負の周波数と正の周波数を効果的に区別するため、無害です。振幅チャンネルは80MHzの周波数インデックス付近でピークを示しています。これは、Moku:Pro Moku Cloud Compileのクロックレートが80MHzであることを考えると、Moku Cloud Compileからの312.5MHz入力信号に対応します。
![]()
\(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 に示します。これでセットアップが完了し、その後、カスタム IP コアを Moku Cloud Compile 内でコンパイルして、ビットストリームを生成できるようになります。

図 26: Moku Cloud Compile 内で IP コアをインスタンス化し、その信号を CustomWrapper モジュールの対応するポートに接続します。
Verilogサポート
VerilogはVHDLと同様にハードウェア記述言語ですが、一般的によりコンパクトで、ハードウェアモデリングと密接に連携しています。VHDLではCustomWrapperエンティティの動作アーキテクチャのみを定義するのが一般的ですが、VerilogではCustomWrapperモジュール全体の宣言と構造定義の両方が必要です。これには、CustomWrapperのポートと内部ロジックの明示的な指定も含まれます。
このセクションでは、コード16に示すように、Verilogを使用してAddSubtract_9 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ベースのデジタル信号処理ソリューションの迅速な開発と展開を可能にする強力で柔軟なプラットフォームとなります。