模拟期间不会初始化信号值
Signal value won't be initialized during simulation
我们有一个大学项目,我们必须为 DSP 模拟一个 MAC 单元。
对于模拟,我通过 EDA playground 使用 Aldec Riviera Pro 2014.06。
问题是,即使我初始化了一个名为 add_res 的 32 位有符号信号,在模拟中它的值将一直显示为 XXXX_XXXX。
Here's the simulation's result.
这是 design.vhd
的代码
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
-----------------------------
ENTITY mac IS
PORT (B, C : IN SIGNED (15 DOWNTO 0);
clk : IN STD_LOGIC;
A : OUT SIGNED (31 DOWNTO 0));
END mac;
-----------------------------
ARCHITECTURE mac_rtl OF mac IS
SIGNAL mul_res: SIGNED (31 DOWNTO 0);
SIGNAL add_res: SIGNED (31 DOWNTO 0) := (others => '0');
BEGIN
mul_res <= B * C;
PROCESS (clk)
BEGIN
A <= mul_res + add_res;
add_res <= A;
END PROCESS;
END mac_rtl;
这是 testbench.vhd
的代码
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity testbench is
end entity testbench;
architecture BENCH of testbench is
component mac is
port (B, C : in SIGNED (15 DOWNTO 0);
clk : in STD_LOGIC;
A : out SIGNED (31 DOWNTO 0));
end component;
signal StopClock : BOOLEAN;
signal clk : STD_LOGIC;
signal B, C : SIGNED (15 DOWNTO 0);
signal A : SIGNED (31 DOWNTO 0);
begin
ClockGenerator: process
begin
clk <= '0';
wait for 2 ns;
while not StopClock loop
clk <= '0';
wait for 1 ns;
clk <= '1';
wait for 1 ns;
end loop;
wait;
end process ClockGenerator;
Stimulus: process
begin
B <= "0000000000000010";
C <= "0000000000001000";
wait;
end process Stimulus;
DUT : entity work.mac
port map (B, C, clk, A);
end architecture BENCH;
我在这里和 Google 中大体上搜索了其他有同样问题的人,但给出的解决方案没有帮助。
我已经尝试使用来自测试平台的 Reset 变量,但没有任何效果。好像根本不会初始化,其他一切正常。
问题是 add_res 和 mul_res 的值必须在 add_res 加载到寄存器时已知。
请注意,该过程对 clk 敏感,但不使用边缘,也不使用 clk 值进行限定。
我修改了您的体系结构以符合 add_res 更新到 clk 上升沿的条件。有一个内置的假设,你当时在 mult_res 上有非元值。这可以通过定义默认初始值来部分解决。
此外,A 的新值在信号更新之前不可用,这不会发生在当前模拟周期中有任何待恢复的进程时。这意味着您需要分配给 add_res (无论如何都保存累加值)并分配给进程外的 A:
ARCHITECTURE mac_rtl OF mac IS
SIGNAL mul_res: SIGNED (31 DOWNTO 0) := (others => '0'); -- added init val
SIGNAL add_res: SIGNED (31 DOWNTO 0) := (others => '0');
BEGIN
mul_res <= B * C;
PROCESS (clk)
BEGIN
if rising_edge(clk) then -- ADDED
-- A <= mul_res + add_res; CHANGED
add_res <= mul_res + add_res;
-- add_res <= A; CHANGED
end if; -- ADDED
END PROCESS;
A <= add_res;
END mac_rtl;
这给出了:
您可能注意到没有必要尝试折叠 A 和 add_res。出于仿真目的,在经过 0 个仿真时间后生效的信号分配引起的增量循环不占用仿真时间。
计划的信号更新和增量周期用于模拟固有顺序分配的信号中的并发性。 (是的,在修改后的架构中,对 A 的分配将比 add_res 晚一个增量周期)。
(是的,我在测试台中的过程刺激中的刺激的尾端放置了一个 StopClock 事务)。
我们有一个大学项目,我们必须为 DSP 模拟一个 MAC 单元。 对于模拟,我通过 EDA playground 使用 Aldec Riviera Pro 2014.06。 问题是,即使我初始化了一个名为 add_res 的 32 位有符号信号,在模拟中它的值将一直显示为 XXXX_XXXX。
Here's the simulation's result.
这是 design.vhd
的代码LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
-----------------------------
ENTITY mac IS
PORT (B, C : IN SIGNED (15 DOWNTO 0);
clk : IN STD_LOGIC;
A : OUT SIGNED (31 DOWNTO 0));
END mac;
-----------------------------
ARCHITECTURE mac_rtl OF mac IS
SIGNAL mul_res: SIGNED (31 DOWNTO 0);
SIGNAL add_res: SIGNED (31 DOWNTO 0) := (others => '0');
BEGIN
mul_res <= B * C;
PROCESS (clk)
BEGIN
A <= mul_res + add_res;
add_res <= A;
END PROCESS;
END mac_rtl;
这是 testbench.vhd
的代码library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity testbench is
end entity testbench;
architecture BENCH of testbench is
component mac is
port (B, C : in SIGNED (15 DOWNTO 0);
clk : in STD_LOGIC;
A : out SIGNED (31 DOWNTO 0));
end component;
signal StopClock : BOOLEAN;
signal clk : STD_LOGIC;
signal B, C : SIGNED (15 DOWNTO 0);
signal A : SIGNED (31 DOWNTO 0);
begin
ClockGenerator: process
begin
clk <= '0';
wait for 2 ns;
while not StopClock loop
clk <= '0';
wait for 1 ns;
clk <= '1';
wait for 1 ns;
end loop;
wait;
end process ClockGenerator;
Stimulus: process
begin
B <= "0000000000000010";
C <= "0000000000001000";
wait;
end process Stimulus;
DUT : entity work.mac
port map (B, C, clk, A);
end architecture BENCH;
我在这里和 Google 中大体上搜索了其他有同样问题的人,但给出的解决方案没有帮助。
我已经尝试使用来自测试平台的 Reset 变量,但没有任何效果。好像根本不会初始化,其他一切正常。
问题是 add_res 和 mul_res 的值必须在 add_res 加载到寄存器时已知。
请注意,该过程对 clk 敏感,但不使用边缘,也不使用 clk 值进行限定。
我修改了您的体系结构以符合 add_res 更新到 clk 上升沿的条件。有一个内置的假设,你当时在 mult_res 上有非元值。这可以通过定义默认初始值来部分解决。
此外,A 的新值在信号更新之前不可用,这不会发生在当前模拟周期中有任何待恢复的进程时。这意味着您需要分配给 add_res (无论如何都保存累加值)并分配给进程外的 A:
ARCHITECTURE mac_rtl OF mac IS
SIGNAL mul_res: SIGNED (31 DOWNTO 0) := (others => '0'); -- added init val
SIGNAL add_res: SIGNED (31 DOWNTO 0) := (others => '0');
BEGIN
mul_res <= B * C;
PROCESS (clk)
BEGIN
if rising_edge(clk) then -- ADDED
-- A <= mul_res + add_res; CHANGED
add_res <= mul_res + add_res;
-- add_res <= A; CHANGED
end if; -- ADDED
END PROCESS;
A <= add_res;
END mac_rtl;
这给出了:
您可能注意到没有必要尝试折叠 A 和 add_res。出于仿真目的,在经过 0 个仿真时间后生效的信号分配引起的增量循环不占用仿真时间。
计划的信号更新和增量周期用于模拟固有顺序分配的信号中的并发性。 (是的,在修改后的架构中,对 A 的分配将比 add_res 晚一个增量周期)。
(是的,我在测试台中的过程刺激中的刺激的尾端放置了一个 StopClock 事务)。