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;