さまざまなバリエーションで実際に使用している有用な例を共有したいと思います。 VHDLでデジタルデバイスを設計する場合、入力ベクトルのサイズを変更するだけでなく、モジュール設計をより柔軟にする必要がありました。
問題
たとえば、設計されたデジタルフィルターがあり、その係数は浮動小数点数で表されます 。 しかし、解決する問題の枠組みの中で、 固定小数点数で動作するシステムを構築する必要があります ;また、係数を再計算する必要なく容量を変更できるようにしたいと思います。
問題をさらに深く掘り下げるために、次のパラメーターを持つモジュールがある状況を想像してください。
コンポーネント FIRCustomizeDesign はパラメーターP0(0-n)は、入力データのビット深度の変化に伴って変化する可能性のあるあらゆる種類の値を送信し、それらを正しく再カウントする必要があります。 この場合、 整数型(その次元が十分な場合)で操作すると便利です。モジュールアーキテクチャでは、簡単にsigned / unsignedに変換されます
ジェネリック (
SizeD : 整数 := 16 ; -入力ベクトルの次元。
-数値形式は、整数部ごとに1ビット、小数部にはSizeD-1を想定しています。 間隔[-1; 1]。
-わかりやすくするために、パラメーターの数を減らしました。
P01 : 整数 := - 32768 ; -=(-0.5)* 2 ^ SizeD-(ビットサイズSizeDに依存)
-フィルター係数をIntegerに渡します。
-さらに、型変換を実行します。 より便利です
-モジュールを接続するために、追加のライブラリを追加する必要はありません。
P02 : 整数 := 22016 ; -=(43/64)* 2 ^ SizeD
P03 : 整数 := - 4352 ; -= -0.0664
-などなど...
) ;
ポート (
rst、sclk : std_logic内 ;
data_ready : std_logic ; -入力準備
-0番目のビットを最下位とみなします。
i_data : in std_logic_vector ( SizeD- 1 downto 0 ) ;
Pipeline_ready : out std_logic ;
準備完了: std_logic ; -出力準備
o_data : out std_logic_vector ( SizeD- 1 downto 0 ) ;
) ;
VAL <= to_signed ( P0、SizeD ) + to_signed ( P1、SizeD ) ; -正しい計算を検証するためしたがって、ビット深度を試して、 SizeD数を変更する場合 、すべてのフィルター係数を再計算する必要があります。 同意します、多くの場合、これはあまり便利ではありません。 もちろん、外部ジェネレーターを作成することは可能ですが、ソリューションは軽量ではなく、毎回追加の移動が必要になります。
-選択したビット深度で、
outdata <= std_logic_vector ( VAL ) ; -透明性のある結論。
私の目標は、標準VHDLライブラリを使用して、 SizeDを変更するとすべてのP0(1-n)が自動的に再計算されるようにパラメーターを記述することです。
解決策
つまずきのブロックは、一般的な場合、初期係数が浮動小数点数の形式であるということです。幸いなことに、これらの目的のために、 VHDL-93のみをサポートする刺激装置およびシンセサイザー用のライブラリfloatfixlibがVHDL 200xに既に含まれています 。
以下はテストに接続する例です。トップモジュールでの使用と基本的な違いはありません。
ライブラリー ieee
ieeeを 使用し ます 。 std_logic_1164 すべて ;
ieeeを 使用し ます 。 numeric_std すべて ;
ieee .std_logic_textioを使用します 。 すべて ;
ieee .math_realを使用します 。 すべて ;
ライブラリfloatfixlib ;
floatfixlib.fixed_pkgを使用します。 すべて ;
LIBRARY std ;
std.textioを使用します。 すべて ;
エンティティ FIRCustomizeDesign_tb は
-空
FIRCustomizeDesign_tbを終了します。
FIRCustomizeDesign_tbのアーキテクチャ DUT は
-Intergerで固定型(符号付き固定小数点)を変換するための関数
関数 sFix2Int ( r : UNRESOLVED_sfixed )
戻り 整数 は
始める
-値の一意性のためにタイプUNRESOLVED_sfixedを選択して固定を変換します。
-次に、それをstd_logic_vectorに変換し、SIGNEDで署名されていることを示し、
-目的の値はすでに受信されていますが、整数にキャストする必要があります。
return ( to_integer ( SIGNED ( to_Std_Logic_Vector ( r ) ) ) )) ;
終了 関数 sFix2Int ;
定数 SizeD : 整数 := 16 ;
定数 clk_period : time := 100 ns ;
-フィルター係数を定義します。
-数値を分割するには、明示的に実数として定義する必要があります。
-これがVHDL構文の管理方法です。
定数 P01 : 実数 := - 実数 ( 17 ) / 実数 ( 128 ) ;
定数 P02 : 実数 := sqrt ( 実数 ( 0.675 ) ) ; -私たちは
-高精度の数学演算。
定数 P03 : 実数 := 実数 ( 0 ) ; -すべてが厳密に入力されます。
-など
-固定小数点付きの符号付き数字
定数 Decimal_Length : integer := 1 ; -整数部の長さ。
-例として、フォーマットは固定されています:
定数 Fractional_Length : 整数 := SizeD-Decimal_Length ;
-数値の境界を、to_sfixed関数が理解できる形式にします。
定数 fx_left : integer := Decimal_Length- 1 ;
定数 fx_right : 整数 := - (小数部の長さ) ;
-よりエレガントな録音のサブタイプを定義します。
サブタイプ qfixed は固定されています( fx_left downto fx_right ) ;
-すべてがターゲット形式に縮小されました。
定数 fP01 : qfixed := to_sfixed ( aP21、fx_left、fx_right ) ;
定数 fP02 : qfixed := to_sfixed ( aP22、fx_left、fx_right ) ;
定数 fP03 : qfixed := to_sfixed ( aP23、fx_left、fx_right ) ;
始める
FIRDUT : FIRCustomizeDesign ジェネリック マップ (
SizeD => SizeD、
P01 => sFix2Int ( fP01 ) 、 -固定された整数に変換します
P02 => sFix2Int ( fP02 ) 、
P03 => sFix2Int ( fP03 )
)
ポート マップ (
rst => rst、clk => clk、data_ready => data_ready、
i_data => i_data、ready => ready、pipeline_ready => pipeline_ready、
o_data0 => o_data0
) ;
-その後、すべてが標準です。
test_reactor :
プロセス ...
DUTを終了します。
利点:
- ここで、ソースデータのビット深度を変更し、モジュールの動作を分析するには、 SizeD定数を変更するだけで十分です。
- 数学的計算は、ターゲット数値形式に変換される前に高精度で実行できます。
短所:
- 型変換の構造はかなり扱いにくいように見えますが、これはハードタイプで表現されるVHDLの機能でもあります。
- 中間型整数を使用すると追加の制限が課せられますが、私のタスクの一部として、すべてで十分でした。
ジェネリックパラメーターの可能性のかなり狭い例が示されていますが、その中でさえ普遍的なソリューションを作成するための十分に大きな可能性があります。
ご清聴ありがとうございました。