背景: 3 つの行列を乗算するための動作ファイルを作成しようとしています。最初に入力行列を読み取ってから中間行列を出力できるかどうかを確認して、デバッグしようとしています。
動作ファイル:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
entity DCT_beh is
port (
Clk : in std_logic;
Start : in std_logic;
Din : in INTEGER;
Done : out std_logic;
Dout : out INTEGER
);
end DCT_beh;
architecture behavioral of DCT_beh is
begin
process
type RF is array ( 0 to 7, 0 to 7 ) of INTEGER;
variable i, j, k : INTEGER;
variable InBlock : RF;
variable COSBlock : RF;
variable TempBlock : RF;
variable OutBlock : RF;
variable A, B, P, Sum : INTEGER;
begin
COSBlock := (
( 125, 122, 115, 103, 88, 69, 47, 24 ),
( 125, 103, 47, -24, -88, -122, -115, -69 ),
( 125, 69, -47, -122, -88, 24, 115, 103 ),
( 125, 24, -115, -69, 88, 103, -47, -122 ),
( 125, -24, -115, 69, 88, -103, -47, 122 ),
( 125, -69, -47, 122, -88, -24, 115, -103 ),
( 125, -103, 47, 24, -88, 122, -115, 69 ),
( 125, -122, 115, -103, 88, -69, 47, -24 )
);
--Starting
wait until Start = '1';
Done <= '0';
--Read Input Data
for i in 0 to 7 loop
for j in 0 to 7 loop
wait until Clk = '1' and clk'event;
InBlock(i,j) := Din;
end loop;
end loop;
--TempBlock = COSBLOCK * InBlock
for i in 0 to 7 loop
for j in 0 to 7 loop
Sum := 0;
for k in 0 to 7 loop
A := COSBlock( i, k );
B := InBlock( k, j );
P := A * B;
Sum := Sum + P;
if( k = 7 ) then
TempBlock( i, j ) := Sum;
end if;
end loop;
end loop;
end loop;
--Finishing
wait until Clk = '1' and Clk'event;
Done <= '1';
--Output Data
for i in 0 to 7 loop
for j in 0 to 7 loop
wait until Clk = '1' and Clk'event;
Done <= '0';
Dout <= tempblock(i,j);
end loop;
end loop;
end process;
end behavioral;
テストベンチ ファイル:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY lab4b_tb IS
END lab4b_tb;
ARCHITECTURE behavior OF lab4b_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT DCT_beh
PORT(
Clk : IN std_logic;
Start : IN std_logic;
Din : IN INTEGER;
Done : OUT std_logic;
Dout : OUT INTEGER
);
END COMPONENT;
--Inputs
signal Clk : std_logic := '0';
signal Start : std_logic := '0';
signal Din : INTEGER;
--Outputs
signal Done : std_logic;
signal Dout : INTEGER;
-- Clock period definitions
constant Clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: DCT_beh PORT MAP (
Clk => Clk,
Start => Start,
Din => Din,
Done => Done,
Dout => Dout
);
-- Clock process definitions
Clk_process :process
begin
Clk <= '0';
wait for Clk_period/2;
Clk <= '1';
wait for Clk_period/2;
end process;
-- Stimulus process
stim_proc: process
variable i, j : INTEGER;
variable cnt : INTEGER;
begin
-- hold reset state for 100 ns.
wait for 100 ns;
start <= '1';
wait for clk_period;
start <= '0';
for cnt in 0 to 63 loop
wait until clk = '1' and clk'event;
din <= cnt;
end loop;
--wait for 100 ns;
--start <= '1';
--wait for clk_period;
--start <= '0';
--for i in 0 to 63 loop
-- wait for clk_period;
--if (i < 24) then
--din <= 255;
--elsif (i > 40) then
--din <= 255;
--else
--din <= 0;
--end if;
--end loop;
wait;
end process;
END;
start = 1 のときに私がしていることから、行列は入力ブロックに読み込まれます。この場合、マトリックスは 0 から 63 までの一意のインクリメンタル値で埋められます。次に、done = 1 の場合、アウトブロックを出力します。これは乗算されたアウト マトリックスです。問題は、私のシミュレーションで、最終的な行列にあるはずの値が正しい順序になっていないことです。たとえば、次の行には、乗算された行列 tempblock の最初の行が含まれています。
14464.000 15157.000 15850.000 16543.000 17236.000 17929.000 18622.000 19315.000
私のシミュレーションの写真でわかるように、これらの値のいくつかを取得しますが、信号は奇妙な大きな値になります。
din(0), din(1), din(2)...din(n) が inputblock(0,0), inputblock(0,1), inputblock(0, 2) など。しかし、動作ファイルを徹底的に調べたところ、問題は見られませんでした。テストベンチの設計方法に何か問題がありますか?
編集:これを出力するのに助けが必要です
din<=0;
for i in 0 to 63 loop
wait until clk = '1' and clk'event;
if i = 0 then
Start <= '1','0' after clk_period;
end if;
if (i < 24) then
din <= 255;
elsif (i > 40) then
din <= 255;
else
din <= 0;
end if;
end loop;
回答のコードに似ていると思いましたが、まったく同じ問題に遭遇しました。これはどのように修正されますか?これが現在出力されているものの写真です。正しい値はありますが、1 クロック周期だけシフトされています。
最終編集:自分で解決しました。問題はループ境界にありました。