模拟期间不会初始化信号值

时间:2017-02-25 01:01:01

标签: vhdl simulation

我们有一个大学项目,我们必须模拟DSP的MAC单元。 对于模拟,我正在通过EDA游乐场使用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;

我一直在这里和谷歌搜索其他有相同问题的人,但是给出的解决方案没有帮助。

我尝试过使用testbench中的重置变量,但没有。它就像它根本不会被初始化,而其他一切都正常工作。

1 个答案:

答案 0 :(得分:0)

问题是在将add_res加载到寄存器时必须知道add_res和mul_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;

这就是:

mac_testbench_fixed.png

您可以注意到没有必要尝试折叠A和add_res。出于模拟目的,由在0模拟时间过去后生效的信号分配引起的增量循环不需要模拟时间。

计划信号更新和增量周期用于模拟按顺序固有分配的信号的并发性。 (在修改的体系结构中,是的,对A的赋值将比add_res晚一个增量循环)。

(是的,我在测试平台的过程刺激中在刺激的尾端放置了一个StopClock事务。)