【问题标题】:VHDL: for...loop instead of for...generateVHDL:for ...循环而不是for ...生成
【发布时间】:2020-10-24 15:44:32
【问题描述】:

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

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,g,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;

测试台:

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,b,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;

【问题讨论】:

  • 它不起作用,因为该进程没有敏感度列表。我很惊讶它甚至可以运行,因为没有敏感度列表的进程应该等待,否则它会在零时间内永远循环。我想这不是整个代码?请发帖MCVE
  • @Tricky 两个进程最后都有一个“等待”,这还不够吗?我已经在主帖中添加了整个项目
  • 您的第二个代码块只是部分代码。它有一个没有等待或敏感列表的进程。您是否尝试过追溯未初始化信号的来源?
  • 您是否检查过您已将所有代码添加到项目中,并且没有关于丢失代码或黑框的警告?
  • 等等,我不明白!我的项目包含 3 个代码块(第 1 部分 + 第 2 部分 + 测试台(这是最后一个代码块))。前两个代码块是第 1 部分的两个版本(一个带有 for...generate,另一个带有 for...loop)。在这两个过程中都有一个“等待”;在“结束循环;”之后,我是否必须在其他地方再等待?

标签: loops vhdl generate


【解决方案1】:

由于无条件等待语句,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 标准 1076-2008
11.3 流程说明

如果在保留字process之后出现进程敏感度列表,则假定进程语句包含隐式等待语句作为进程语句部分的最后一条语句;这个隐式等待语句的形式是

等待 开启sensitivity_list ;

敏感度列表的构建规则见 10.2 等待语句。

14.7.5 模型执行
14.7.5.1 概述

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

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

14.7.5.2 初始化

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

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

.. f) 对于模型中的每个非延迟过程 P,以下动作按指示的顺序发生:

  1. 进程一直执行,直到挂起。
    ...

进程在等待语句中暂停和恢复。具有敏感性列表的进程将隐式等待语句作为最后一条语句。

10.2 等待语句

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

现有的等待语句没有超时子句,并且会导致进程在初始化后的第一个进程执行后停止执行。用于为信号输出提供更新波形的输入值在那个时候都是'U'。

14.7.5.3 模拟循环

一个模拟循环由以下步骤组成:

...
f) 以下动作按指定顺序发生:

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

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

【讨论】:

  • 非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-10
  • 1970-01-01
  • 2012-01-27
  • 2011-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多