为什么数组更新会破坏元素值?
Why does an array update corrupt the element value?
以下独立的 VHDL 文件是从 CLaSH 的输出中简化而来的,这应该可以解释其有些奇怪的结构。
目的是在s.tup2_sel0
为"01"
的循环中递增s.tup2_sel1(0)
。但是,我在 VHDL 模拟器中看到的是 OUTPUT
(因此,s.tup2_sel1(0)
)在数组更新后变为 unknoqn(其值为 "XXXXXXXX"
)。为什么数组元素会损坏?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity CHIP8 is
port(-- clock
CLK : in std_logic;
-- asynchronous reset: active high
RESET : in std_logic;
OUTPUT : out unsigned(7 downto 0));
type array_of_unsigned_8 is array (integer range <>) of unsigned(7 downto 0);
type tup2 is record
tup2_sel0 : std_logic_vector(1 downto 0);
tup2_sel1 : array_of_unsigned_8(0 to 1);
end record;
end;
architecture structural of CHIP8 is
signal y1 : array_of_unsigned_8(0 to 1);
signal s : tup2;
signal s1 : tup2;
signal y : array_of_unsigned_8(0 to 1);
signal x : unsigned(7 downto 0);
begin
y <= s.tup2_sel1;
x <= y(0);
process(y)
variable ivec : array_of_unsigned_8(0 to 1);
begin
ivec := y;
ivec(0) := x + 1;
y1 <= ivec;
end process;
with s.tup2_sel0 select
s1 <= (tup2_sel0 => "01", tup2_sel1 => y) when "00",
(tup2_sel0 => "10", tup2_sel1 => y1) when "01",
(tup2_sel0 => "10", tup2_sel1 => y) when others;
process(CLK,RESET)
begin
if RESET = '1' then
s <= (tup2_sel0 => "00", tup2_sel1 => array_of_unsigned_8'(0 to 1 => to_unsigned(0,8)));
elsif rising_edge(CLK) then
s <= s1;
end if;
end process;
OUTPUT <= x;
end;
我的顶级测试台生成 RESET
信号:
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
ENTITY TB IS
END TB;
ARCHITECTURE behavior OF TB IS
signal CLK : std_logic := '0';
signal RESET : std_logic := '0';
signal OUTPUT : unsigned(7 downto 0);
constant CLK_period : time := 10 ns;
BEGIN
uut: entity work.CHIP8 PORT MAP (
CLK => CLK,
RESET => RESET,
OUTPUT => OUTPUT);
CLK_proc :process
begin
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end process;
RESET_proc: process
begin
RESET <= '1';
wait for CLK_period * 2;
RESET <= '0';
wait;
end process;
END;
process(y)
的敏感度列表中缺少信号 x
。这可能是有意为之,但 99% 都是错误。
因为它是生成的代码,所以我无法判断编写代码发射器的人是否像我一样聪明的 VHDL 程序员知道敏感度列表是一种语法糖,或者他们是否只是错过了向敏感度列表添加更多信号。 ..
如何翻译敏感度列表?
看这个例子:
process(y, x)
begin
-- some code
end process;
翻译成:
process
begin
-- some code
wait on y, x;
end process;
因此,如果他们聪明的话,他们可以推测仅在 y
事件上恢复进程,而不是在 'x' 事件上恢复进程。一些 VHDL 专家可能会使用它来优化进程唤醒,其他人会称之为棘手的代码行。
当信号包含 U
、-
、X
、W
等元值和 [=] 等算术时,可以生成 X
值使用 20=]。
除了重置条件外,我没有看到 tup2_sel1
的任何初始值。
那么,您在模拟中应用了 RESET 了吗?
以下独立的 VHDL 文件是从 CLaSH 的输出中简化而来的,这应该可以解释其有些奇怪的结构。
目的是在s.tup2_sel0
为"01"
的循环中递增s.tup2_sel1(0)
。但是,我在 VHDL 模拟器中看到的是 OUTPUT
(因此,s.tup2_sel1(0)
)在数组更新后变为 unknoqn(其值为 "XXXXXXXX"
)。为什么数组元素会损坏?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity CHIP8 is
port(-- clock
CLK : in std_logic;
-- asynchronous reset: active high
RESET : in std_logic;
OUTPUT : out unsigned(7 downto 0));
type array_of_unsigned_8 is array (integer range <>) of unsigned(7 downto 0);
type tup2 is record
tup2_sel0 : std_logic_vector(1 downto 0);
tup2_sel1 : array_of_unsigned_8(0 to 1);
end record;
end;
architecture structural of CHIP8 is
signal y1 : array_of_unsigned_8(0 to 1);
signal s : tup2;
signal s1 : tup2;
signal y : array_of_unsigned_8(0 to 1);
signal x : unsigned(7 downto 0);
begin
y <= s.tup2_sel1;
x <= y(0);
process(y)
variable ivec : array_of_unsigned_8(0 to 1);
begin
ivec := y;
ivec(0) := x + 1;
y1 <= ivec;
end process;
with s.tup2_sel0 select
s1 <= (tup2_sel0 => "01", tup2_sel1 => y) when "00",
(tup2_sel0 => "10", tup2_sel1 => y1) when "01",
(tup2_sel0 => "10", tup2_sel1 => y) when others;
process(CLK,RESET)
begin
if RESET = '1' then
s <= (tup2_sel0 => "00", tup2_sel1 => array_of_unsigned_8'(0 to 1 => to_unsigned(0,8)));
elsif rising_edge(CLK) then
s <= s1;
end if;
end process;
OUTPUT <= x;
end;
我的顶级测试台生成 RESET
信号:
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
ENTITY TB IS
END TB;
ARCHITECTURE behavior OF TB IS
signal CLK : std_logic := '0';
signal RESET : std_logic := '0';
signal OUTPUT : unsigned(7 downto 0);
constant CLK_period : time := 10 ns;
BEGIN
uut: entity work.CHIP8 PORT MAP (
CLK => CLK,
RESET => RESET,
OUTPUT => OUTPUT);
CLK_proc :process
begin
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end process;
RESET_proc: process
begin
RESET <= '1';
wait for CLK_period * 2;
RESET <= '0';
wait;
end process;
END;
process(y)
的敏感度列表中缺少信号 x
。这可能是有意为之,但 99% 都是错误。
因为它是生成的代码,所以我无法判断编写代码发射器的人是否像我一样聪明的 VHDL 程序员知道敏感度列表是一种语法糖,或者他们是否只是错过了向敏感度列表添加更多信号。 ..
如何翻译敏感度列表?
看这个例子:
process(y, x)
begin
-- some code
end process;
翻译成:
process
begin
-- some code
wait on y, x;
end process;
因此,如果他们聪明的话,他们可以推测仅在 y
事件上恢复进程,而不是在 'x' 事件上恢复进程。一些 VHDL 专家可能会使用它来优化进程唤醒,其他人会称之为棘手的代码行。
当信号包含
U
、-
、X
、W
等元值和 [=] 等算术时,可以生成 X
值使用 20=]。
除了重置条件外,我没有看到 tup2_sel1
的任何初始值。
那么,您在模拟中应用了 RESET 了吗?