0

次のような複数の定義を持つパッケージを作成しています

    -- Control Register Address Type Declaration
    SUBTYPE ctrl_reg_addr_type IS std_logic_vector( ADDR_BITS-1 DOWNTO 0 );
    -- Control Register Data Type Declaration
    SUBTYPE ctrl_reg_data_type IS std_logic_vector( DATA_BITS-1 DOWNTO 0 );
    -- Control Register Type Declaration
    SUBTYPE ctrl_reg_word_type IS std_logic_vector( CTRL_BITS-1 DOWNTO 0 );

    -- Left/Right Line-In Control Type Declarations
    CONSTANT LINE_IN_VOL_BITS : integer := 5;

    SUBTYPE line_in_volume_type IS natural
    RANGE 0 TO ( 2**LINE_IN_VOL_BITS )-1;

    TYPE line_in_ctrl_type IS RECORD

        -- Left/Right Channel Line Input Volume (4:0)
        -- Registers: LINVOL/RINVOL
        -- 0x1F = +12.0dB
        -- ...  =   1.5dB steps
        -- 0x00 = -34.5dB
        -- 0x17 - 0dB (Default)
        volume : std_logic_vector( LINE_IN_VOL_BITS-1 DOWNTO 0 );
        -- Left/Right Channel Line Input Mute to ADC (7)
        -- Registers: LINMUTE/RINMUTE
        -- 0x1 = Enable Mute
        -- 0x0 = Disable Mute
        mute   : std_logic;
        -- Left/Right Channel Line Input Volume and Mute Load (8)
        -- Registers: LRINBOTH/RLINBOTH
        -- 0x1 = Enable Simultaneous Load of LINVOL/LINMUTE <-> RINVOL/RINMUTE
        -- 0x0 = Disable Simultaneous Load
        both   : std_logic;

    END RECORD line_in_ctrl_type;

次のような関数を使用して、レコード タイプ内のフィールドを変更したいと考えています。

    -- Left/Right Line-In Increase Volume Function Body
    FUNCTION increase_volume( ctrl : line_in_ctrl_type )
    RETURN line_in_ctrl_type IS

        VARIABLE volume : line_in_volume_type := 0;
        VARIABLE tmp    : line_in_ctrl_type;

    BEGIN

        tmp    := ctrl;
        volume := natural( to_integer( unsigned( ctrl.volume ) ) );

        IF ( volume < line_in_volume_type'HIGH ) THEN

            volume     := volume + 1;

            tmp.volume := std_logic_vector(
                              to_unsigned( volume, LINE_IN_VOL_BITS ) );

        END IF;

        RETURN ( tmp );

    END FUNCTION increase_volume;

    -- Left/Right Line-In Increase Volume Function Body
    FUNCTION increase_volume( ctrl : line_in_ctrl_type;
                              step : natural )
    RETURN line_in_ctrl_type IS

        VARIABLE volume : line_in_volume_type := 0;
        VARIABLE tmp    : line_in_ctrl_type;

    BEGIN

        tmp    := ctrl;
        volume := natural( to_integer( unsigned( ctrl.volume ) ) );

        IF ( volume < ( line_in_volume_type'HIGH - step ) ) THEN

            volume     := volume + step;

            tmp.volume := std_logic_vector(
                              to_unsigned( volume, LINE_IN_VOL_BITS ) );

        ELSE

            tmp := increase_volume( tmp );

        END IF;

        RETURN ( tmp );

    END FUNCTION increase_volume;

私の質問は、示されている例と同様の関数を使用して、レコード値を明示的に変更するよりも多くの LE を使用するかどうかです。

4

2 に答える 2

1

このような関数を使用すると、ロジックの負荷が便利な形式にまとめられます。

すべてをコピーして貼り付ける場合と比較して、ロジックの使用方法が大幅に異なる場合は、合成ベンダーにバグを報告してください。

于 2012-05-14T14:31:30.567 に答える
1

VHDL での関数の使用は非常に抽象的です (VHDL のように)。RTL から可能な限り遠く離れている可能性があります。これは、LE で何が干渉されるかを判断するのが非常に難しいことを意味します。それは主に合成ツールと、それらが論理構造をどのように選択するかに依存します。

関数はマクロのように合成されます。呼び出すたびに、同じ論理ブロックの別のインスタンスをインスタンス化することになる場合があります。どのくらいの頻度で電話していますか?

LE を効率的に使用するには、機能ブロックを再利用するコードを記述する必要があります。たとえば、一般的な構造の読み取り/書き込みエンジンを作成し、それを一度使用しますが、入力と出力をさまざまな場所との間でルーティングします。

LE の使用が心配で、それでも関数を使用したい場合は、十分な大きさの FPGA があるかどうかを検討することをお勧めします。

于 2012-05-12T22:36:16.720 に答える