VHDL:for ...循环而不是for ...生成

问题描述

你好,我在使用for ... loop而不是for ... generate时遇到问题。我想用于...循环,因为我们的教授只教过我们。

library ieee;
use ieee.std_logic_1164.all;

entity supersomm_4bit is
  port (
    c_in: in std_logic;
    a,b: in std_logic_vector(3 downto 0);
    s: out std_logic_vector(3 downto 0);
    sP,sG: out std_logic
  );
end supersomm_4bit;

architecture arch of supersomm_4bit is
  signal p,g,c: std_logic_vector(3 downto 0);

  begin
    g1: for i in 0 to 3 generate
      g(i) <= a(i) and b(i);
      p(i) <= a(i) or b(i);
    end generate;

    c(0) <= c_in;
    c(1) <= g(0) or (p(0) and c(0));
    c(2) <= g(1) or (p(1) and g(0)) or (p(1) and p(0) and c(0));
    c(3) <= g(2) or (p(2) and g(1)) or (p(2) and p(1) and g(0))
            or (p(2) and p(1) and p(0) and c(0));

    g2: for i in 0 to 3 generate
      s(i) <= a(i) xor b(i) xor c(i);
    end generate;

    sP <= p(0) and p(1) and p(2) and p(3);
    sG <= g(3) or (p(3) and g(2)) or (p(3) and p(2) and g(1))
          or (p(3) and p(2) and p(1) and g(0));
end arch;

我试图做这样的事情

architecture for_loop of supersomm_4bit is
  signal p,c: std_logic_vector(3 downto 0);
  begin
    process begin
        for i in 0 to 3 loop
        g(i) <= a(i) and b(i);
        p(i) <= a(i) or b(i);
        end loop;
        wait;
    end process;

    c(0) <= c_in;
    c(1) <= g(0) or (p(0) and c(0));
    c(2) <= g(1) or (p(1) and g(0)) or (p(1) and p(0) and c(0));
    c(3) <= g(2) or (p(2) and g(1)) or (p(2) and p(1) and g(0))
            or (p(2) and p(1) and p(0) and c(0));
        
    process begin
        for i in 0 to 3 loop
        s(i) <= a(i) xor b(i) xor c(i);
        end loop;
        wait;
    end process;

    sP <= p(0) and p(1) and p(2) and p(3);
    sG <= g(3) or (p(3) and g(2)) or (p(3) and p(2) and g(1))
            or (p(3) and p(2) and p(1) and g(0));
end architecture for_loop;

,但不起作用(s和sP / sG未初始化)。我也尝试过将所有代码放在一个过程中,但仍然无法正常工作。 我是在做错什么,还是应该简单地避免使用for ... loop? 谢谢!

编辑(添加整个项目):

library ieee;
use ieee.std_logic_1164.all;

entity unita_cla is
  port (
    a,b: in std_logic_vector(15 downto 0);
    c_in: in std_logic;
    S: out std_logic_vector(15 downto 0);
    C_OUT: out std_logic
  );
end unita_cla;

architecture arch of unita_cla is
  signal C: std_logic_vector(4 downto 1);
  signal P,G: std_logic_vector(3 downto 0);

  component supersomm_4bit
    port (
      c_in: in std_logic;
      a,b: in std_logic_vector(3 downto 0);
      s: out std_logic_vector(3 downto 0);
      sP,sG: out std_logic
    );
  end component;

  begin
    C(1) <= G(0) or (P(0) and c_in);
    C(2) <= G(1) or (P(1) and G(0)) or (P(1) and P(0) and c_in);
    C(3) <= G(2) or (P(2) and G(1)) or (P(2) and P(1) and G(0))
            or (P(2) and P(1) and P(0) and c_in);
    C(4) <= G(3) or (P(3) and G(2)) or (P(3) and P(2) and G(1))
            or (P(3) and P(2) and P(1) and G(0))
            or (P(3) and P(2) and P(1) and P(0) and c_in);

    bit0_3: supersomm_4bit port map (c_in,a(3 downto 0),b(3 downto 0),S(3 downto 0),P(0),G(0));
    bit4_7: supersomm_4bit port map (C(1),a(7 downto 4),b(7 downto 4),S(7 downto 4),P(1),G(1));
    bit8_11: supersomm_4bit port map (C(2),a(11 downto 8),b(11 downto 8),S(11 downto 8),P(2),G(2));
    bit12_15: supersomm_4bit port map (C(3),a(15 downto 12),b(15 downto 12),S(15 downto 12),P(3),G(3));

    C_OUT <= C(4);
end arch;

TESTBENCH:

library ieee;
use ieee.std_logic_1164.all;

entity unita_cla_tb is
end unita_cla_tb;

architecture testbench of unita_cla_tb is
  signal a,b,S: std_logic_vector(15 downto 0);
  signal c_in,C_OUT: std_logic;

  component unita_cla
    port (
      a,b: in std_logic_vector(15 downto 0);
      c_in: in std_logic;
      S: out std_logic_vector(15 downto 0);
      C_OUT: out std_logic
    );
  end component;

  begin
    u1: unita_cla port map (a,c_in,S,C_OUT);
    tb: process
    begin
      a <= "0000000000000000";
      b <= "0000000000000000";
      c_in <= '1';
      wait for 10 ns;
      a <= "1111111111111111";
      b <= "0000000000000000";
      c_in <= '0';
      wait for 10 ns;
      a <= "1010101010101010";
      b <= "0101010101010101";
      c_in <= '1';
      wait for 10 ns;
      a <= "1111111111111111";
      b <= "1111111111111111";
      c_in <= '0';
      wait for 10 ns;
      a <= "1010101010101010";
      b <= "1010101010101010";
      c_in <= '1';
      wait for 10 ns;
      wait;
    end process;
  end testbench;

解决方法

由于无条件的等待语句,supersomm_4bit体系结构的for循环版本中的两个进程仅执行一次。添加敏感度列表并删除等待语句:

architecture for_loop of supersomm_4bit is
    signal p,g,c: std_logic_vector(3 downto 0);
begin
    process (a,b)  -- ADDED sensitiity list
    begin
        for i in 0 to 3 loop
            g(i) <= a(i) and b(i);
            p(i) <= a(i) or b(i);
        end loop;
        -- wait;  -- resumes for every change in a or b
    end process;

    c(0) <= c_in;
    c(1) <= g(0) or (p(0) and c(0));
    c(2) <= g(1) or (p(1) and g(0)) or (p(1) and p(0) and c(0));
    c(3) <= g(2) or (p(2) and g(1)) or (p(2) and p(1) and g(0))
            or (p(2) and p(1) and p(0) and c(0));

    process  (a,b,c)  -- ADDED sensitivity list
    begin
        for i in 0 to 3 loop
        s(i) <= a(i) xor b(i) xor c(i);
        end loop;
        -- wait;   -- resumes for every change in a,b or c
    end process;

    sP <= p(0) and p(1) and p(2) and p(3);
    sG <= g(3) or (p(3) and g(2)) or (p(3) and p(2) and g(1))
            or (p(3) and p(2) and p(1) and g(0));
end architecture for_loop;

允许模拟匹配建筑拱门的模拟。对于灵敏度列表中具有事件(新值)的任何信号,每个过程都会恢复。

IEEE Std 1076-2008
11.3流程声明

如果过程敏感性列表出现在保留字 process 之后,则假定process语句包含一个隐式的wait语句,作为process语句部分的最后一条语句;该隐式的wait语句的格式为

等待 敏感度列表上;

有关敏感性列表的构建规则,请参见10.2 Wait语句。

14.7.5模型执行
14.7.5.1常规

模型的执行包括初始化阶段,然后在该模型的描述中重复执行流程语句。每次这样的重复被称为一个模拟周期。在每个循环中,将计算描述中所有信号的值。如果由于计算而在给定信号上发生事件,则对该信号敏感的过程语句将恢复并在仿真周期中执行。

在初始化阶段和每个模拟周期的某些阶段,计算当前时间Tc和下一个模拟周期的时间Tn。 Tn是通过将其设置为最早的...来计算的。

14.7.5.2初始化

在初始化开始时,当前时间Tc假定为0 ns。

初始化阶段包括以下步骤:

.. f)对于模型中每个未推迟的流程P,将按照指示的顺序执行以下操作:

  1. 该过程一直执行到暂停为止。
    ...

进程在等待语句中挂起并恢复。带有敏感度列表的进程将隐式的wait语句作为最后一个语句。

10.2等待声明

timeout子句指定该进程在此wait语句处保持挂起的最长时间。如果没有出现超时子句,则假定(STD.STANDARD.TIME'HIGH – STD.STANDARD.NOW)的超时子句。如果timeout子句中的时间表达式评估为负值,则会出现错误。

现有的wait语句没有timeout子句,并且会导致该进程在初始化之后的第一次进程执行之后停止执行。当时用于提供信号输出更新波形的输入值将全部为“ U”。

14.7.5.3仿真周期

模拟周期包括以下步骤:

...
f)按照指定的顺序执行以下操作:

...
2)对于每个进程P,如果P当前对信号S敏感,并且在此模拟周期中S上发生了事件,则P恢复。

在当前模拟时间安排和更新。