我很难理解如何在另一个过程中使用顺序逻辑实体。该过程是状态机,其在每个时钟信号上从输入读取值或执行计算。这些计算需要多次迭代才能完成。但是,每次迭代都应该使用一个子实体,该子实体使用与上述相同的原理(双状态状态机,基于时钟的迭代)来定义,以获得在同一次迭代中所需的一些结果。
在我看来,我有两个选择:
它们中没有一个看起来非常吸引人且相当复杂,所以我要求一些经验丰富的见解和澄清。我真的希望有一种我更缺失的传统方式。
答案 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实际上正在变得更糟,而不是更好地支持它。