具有多个延迟的 VHDL 状态机 - 最佳方法? [英] VHDL state machine with several delays - best approach?

查看:22
本文介绍了具有多个延迟的 VHDL 状态机 - 最佳方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个困扰我的通用问题,因为我能够理解有限状态机的基础知识.假设我有四个状态 s0 - s3,其中通电后,FSM 将自动从s0"开始.在某个定义的延迟之后,FSM 将进入s1"——其他状态也是如此.不同状态之间的延迟是不一样的.

This is a generic question that has bugged me since I was able to understand the Basics of a finite state machine. Suppose I have four states s0 - s3, where the FSM will automatically start at 's0' after power is applied. After some defined delay, the FSM shall enter 's1' - the same goes for the other states. The delay between the different states is not the same.

例如:

加电 -> 's0' -> 100 ms -> 's1' -> 50 us -> 's2' -> 360 us -> 's3' -> 's3'

Power up -> 's0' -> 100 ms -> 's1' -> 50 us -> 's2' -> 360 us -> 's3' -> 's3'

在像 C 这样的过程语言中,我只需调用一个延迟例程,其中一个参数是所需的延迟并完成它.

In a procedural language as C, I'd just call a delay routine with one parameter being the required delay and be done with it.

如何优雅地实现这种 FSM?

How do I implement this sort of FSM elegantly ?

最好,克里斯

推荐答案

我的模式:一个延迟计数器,每个状态转换都可以在需要时进行编程,即在每个新延迟开始时.

My pattern : a delay counter which each state transition can program as and when required, i.e. at the start of each new delay.

这一切都是可综合的,尽管某些工具(尤其是 Synplicity)在精确时间计算方面存在问题,除非您的时钟周期是整数纳秒.有关此错误的更多信息,请参阅此问答.如果遇到这种情况,幻数(32000 而不是 Synplicity 在该问题中计算的 32258)可能是最简单的解决方法.

It's all synthesisable, though some tools (notably Synplicity) have trouble with accurate Time calculations unless your clock period is an integer number of nanoseconds. For more information on this bug, see this Q&A. If you run into this situation, magic numbers (32000 instead of Synplicity's calculated 32258 in that question) may be the simplest workaround.

将其包装在实体/架构中作为(简单的)练习.

Wrapping it in an entity/architecture left as an (easy) exercise.

-- first, some declarations for readability instead of magic numbers
constant clock_period : time := 10 ns; 
--WARNING : Synplicity has a bug : by default it rounds to nanoseconds!
constant longest_delay : time := 100 ms;
subtype delay_type is natural range 0 to longest_delay / clock_period;

constant reset_delay : delay_type := 100 ms / clock_period - 1;
constant s1_delay  : delay_type := 50 us / clock_period - 1;
constant s2_delay  : delay_type := 360 us / clock_period - 1;
-- NB take care to avoid off-by-1 error!

type state_type is (s0, s1, s2, s3);

-- now the state machine declarations:

signal state : state_type;
signal delay : delay_type;

-- now the state machine itself:

process(clock, reset) is

begin
   if reset = '1' then
      state <= s0;
      delay <= reset_delay;
   elsif rising_edge(clock) then
      -- default actions such as default outputs first
      -- operate the delay counter
      if delay > 0 then 
         delay <= delay - 1;
      end if;
      -- state machine proper
      case state is
      when s0 =>
         -- do nothing while delay counts down
         if delay = 0 then
            --start 50us delay when entering S1
            delay <= s1_delay;
            state <= s1;
         end if;
      when s1 =>
         if delay = 0 then
            delay <= s2_delay;
            state <= s2;
         end if;
      when s2 =>
         if delay = 0 then
            state <= s3;
         end if;
      when others =>
         null;
      end case;       
   end if;
end process;

这篇关于具有多个延迟的 VHDL 状态机 - 最佳方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆