1

最近VHDLを学び始めました。VHDL コードを記述して、算術演算を決定します。

ステートメントですが、機能しません。実際にシミュレートすると、出力はそうではありません

変化し、0.0のままです。私のミスがどこにあるのかわからない。を使用する必要がありますか

外部クロック? やっても変わらない(-_-;)

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

package mypack is
    type real_vector is array (integer range <>) of real;
end mypack;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.mypack.all;

entity convolution is port (
    x:in real_vector(0 to 3);
    y:in real_vector(0 to 1);

    f:out real_vector (0 to 4)
);
end convolution;

architecture Behavioral of convolution is
    --signal temp : real_vector (0 to 4):= (others => 0.0);
    --signal enable : std_logic :='0';
begin
    process (x,y)
        variable sum :real;
    begin

        for n in f'range loop
            enable <= '0';
            for k in y'range loop
                sum:=sum + x(k)*y(n-k);
            end loop;
            -- temp(n) <= sum;
            f(n) <= sum ;
            sum:=0.0;
        end loop;

        enable <= '1';

        --if (enable'event and enable='1') then
        --    f <= temp;
        --end if;

    end process;
end Behavioral;
4

2 に答える 2

0

VHDL はプログラミング言語ではなく、ハードウェア記述言語です。

このため、信頼性の高い結果を得て、最終設計を可能な限り最適化するために、ハードウェアにネイティブな std_logic_vectors、unsigneds、およびその他のプリミティブを使用することが重要です。

for ループ全体がプロセスの 1 回の反復で完全に実行されるため、出力の変化は見られません。最終結果は for ループの最後の状態、この場合は になりsum:=0.0;ます。これを修正するには、デザインで外部クロックを使用することを強くお勧めします。そのクロックは、プロセスのセンシティビティ リストの一部です。これにより、プロセスを本質的に for ループとして使用できるようになり、明示的な for ループが完全に不要になります。

これとよく似た質問が EE スタック交換サイトで数日前に出てきました。この方法でプロセスを for ループとして使用する方法を説明する非常に包括的な回答を書きました。

これは、他の質問に対する私の回答へのリンクです。 リンキー

私はあなたのコードを調べて、少し修正しました (そして時計を追加しました!)。私はそれをシミュレートしていないので、100% のタイミングで実行されない可能性がありますが、プロセスを for ループとして使用し、適切な軌道に乗せるという点で私が何を意味するかを確認する例です。

どうぞ。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

-- unsigned types are part of the numeric_std package. They are like std_logic types, but have native support for +,-,*, etc.
package mypack is
    type x_vector is array(0 to 3) of unsigned(0 to 31);
    type y_vector is array(0 to 1) of unsigned(0 to 31);
    type f_vector is array(0 to 4) of unsigned(0 to 31);
end mypack;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

use work.mypack.all;

entity convolution is 
port (
    clk : in std_logic;
    rst : in std_logic;
    x:in x_vector;
    y:in y_vector;
    f:out f_vector
);
end convolution;

architecture Behavioral of convolution is
    signal enable : std_logic;

    -- These are your for-loop count variables
    signal n_count : unsigned(0 to 4);
    signal k_count : unsigned(0 to 1);

    -- sum variable (you might want to look into making this 64 bits long, so the answer doesn't overflow)
    signal sum : unsigned (0 to 31);
begin

    -- process only executes when clock or reset changes
    convolve : process (clk,rst)
    begin
        if (rst = '1') then

            -- this is where you set your variables to 0;
            n_count <= (others => '0');
            k_count <= (others => '0');
            sum <= (others => '0');
            enable <= '0';

            -- nice way of setting all values in f array to zero (nest "others =>" for as many dimensions as you need)
            f <= (others => (others => '0'));

        elsif (rising_edge(clk)) then
            -- if your n counter hits its max value ('high), reset the counter
            if (n_count = n_count'high) then
                n_count <= (others => '0');
                -- Add whatever you want to do when n hits it's max here...

            -- This is what is executed while n is counting up.
            else 

                -- if your k counter hits its max value ('high), reset the counter
                if (k_count = k_count'high) then
                    k_count <= (others => '0');
                    -- Add whatever you want it to do when k hits it's max here...

                -- This is what is executed while k is counting up (with n)
                else
                    -- This is where the actual convolution takes place.
                    -- The counters are converted to integers in order to be used as array references
                    sum <= sum + sum + (x(to_integer(k_count))*y(to_integer(n_count-k_count)));
                    -- Increment k!
                    k_count <= k_count + "1";
                end if;
                -- Increment n!
                n_count <= n_count + "1";

                -- I'm not hugely sure what you want to do with the enable, but this is where 
                -- it was in the other code.  
                enable <= '0';
                -- drive F with sum value
                f(to_integer(n_count)) <= sum;
                -- clear sum for next round.
                sum <= (others => '0');
            end if;
            -- enable again.
            enable <= '1';
        end if;
    end process;
end Behavioral;
于 2013-02-18T03:06:40.250 に答える
0

コードサンプルで確認できることがいくつかあります。

  1. 実数型を使用します。通常は合成可能ではなく、シミュレーションでのみ機能するため、それらを避ける必要があります。代わりに、固定小数点演算を使用することもできます。
  2. 変数を使用します。変数は通常のシグナルとは異なる動作をするため、実際に何をしているのかわからない限り、変数の使用を避けるようにしてください。シグナル値はプロセスの最後に割り当てられますが、変数にはすぐに値が割り当てられます。したがって、変数は、より複雑なステートメント (#defineたとえば C のステートメントなど) を単純化するためだけに使用されることがよくあります。
  3. デザインを同期/クロック化し、レジスタを使用する必要があります。クロック サイクルごとに 1 つの特定の操作を行います。

メインループの最後のステートメントsum:=0.0は、割り当ての sum の値を上書きすると思いますf(n) <= sum

于 2013-02-16T11:05:37.483 に答える