vhdl如何在进程中使用实体

时间:2014-02-07 10:40:05

标签: entity vhdl

我很难理解如何在另一个过程中使用顺序逻辑实体。该过程是状态机,其在每个时钟信号上从输入读取值或执行计算。这些计算需要多次迭代才能完成。但是,每次迭代都应该使用一个子实体,该子实体使用与上述相同的原理(双状态状态机,基于时钟的迭代)来定义,以获得在同一次迭代中所需的一些结果。

在我看来,我有两个选择:

  1. 在主实体内的单独进程中实现子实体,并找到一种方法来暂停主进程并将其与子实体执行同步 - 这将意味着使用主实体的时钟信号
  2. 在主要实体的过程中实现子实体(基本上类似于函数调用)并找到一种方法来停止主要过程,直到子实体执行完成 - 这在我看来几乎不可能使用主时钟信号
  3. 它们中没有一个看起来非常吸引人且相当复杂,所以我要求一些经验丰富的见解和澄清。我真的希望有一种我更缺失的传统方式。

1 个答案:

答案 0 :(得分:2)

“实体”在这里是一个不幸的选择,因为它表明VHDL Entity可能是你想要的也可能不是。

你正在考虑大致正确的行,但是有点不清楚你的意思是“吸引人”;所以你的目标不明确,这使得很难提供帮助。

分别采取两种方法:

(1)单独的过程是划分任务的有效方法。它们自然会并行运行。在同步设计中(最佳实践,最安全和最简单 - 不是通用的,但你需要引人注目的理由做其他事情),它们通常都由相同的系统时钟计时。

当您需要同步它们时,您可以使用额外的“握手”信号。通常,您的主SM将启动子系统,等待子系统确认,再次等待子系统完成,然后使用结果。

main_sm : process(clk)
begin
   if rising_edge(clk) then
      case state is
      ...
      when start_op =>
         subsystem_start <= '1';
         if subsystem_busy = '1' then
            state <= wait_subsystem;
         end if;

      when wait_subsystem <= 
         subsystem_start <= '0';
         if subsystem_busy = '0' then
            state <= use_result;
         end if;

      when use_result => -- carry on processing
      ...
      end case;
   end if;  
end process main_sm;

应该清楚如何编写子系统来匹配......

这在子系统处理需要大量,可变或未知时间完成时最有用 - 可能是将字符发送到UART或串行分频器。小心,它还可以允许几个顶级进程访问子系统以节省硬件(显然,子系统握手逻辑一次只响应一个进程!)

(2)如果要在过程中实施子实体,则应将其写为子程序,即在推测时,程序或函数。如果它被声明为进程的本地,则它可以访问该进程的环境;否则你可以传递它参数。当子程序可以在当前时钟周期内完成时,这是最简单的;通常你可以构造代码,以便它可以。

在综合工具中尝试以下操作:

main_sm : process(clk)

   procedure wait_here (level : std_logic; nextstate : state_type) is
   begin
      subsystem_start <= level;
      if subsystem_busy = level then
         state <= nextstate;
      end if;
   end wait_here;

begin
   ...
      when start_op =>
         wait_here('1', wait_subsystem);
      when wait_subsystem <= 
         wait_here('0', use_result);

上面的握手重写应该有效,并且在一些合成工具中,但其他人可能无法为子程序提供良好的综合支持。

您可以在模拟过程中使用跨越多个时钟周期的子程序;诀窍是消除敏感性列表并使用

wait until rising_edge(clk);

代替。这也是潜在可合成的,并且可以用于例如在程序的循环中。然而,一些综合工具拒绝了它,而Xilinx XST实际上正在变得更糟,而不是更好地支持它。