用 VHDL 编码状态机

发布于 2024-11-06 13:24:59 字数 728 浏览 0 评论 0原文

我正在考虑在 VHDL 中创建一个系统,该系统在通过 FTDI USB 转串口设备接收到图像后对其进行过滤。作为其中的一部分,我相信我已经确定了我的 CPLD 应该处于的状态,但我以前从未在 VHDL 中创建过复杂的状态机,所以我怀疑我的方法是否合理。目前,我的状态机的基本轮廓是这样的:

begin
    process(clk, reset, USB_RXFN, USB_TXEN)
    begin
        case state is
            when IDLE =>
            when NEGOTIATING =>
            when RECEIVING =>
            when FILTERING =>
            when TRANSMITTING =>
            when OTHERS  => -- this should never happen but go to IDLE
    end process;

我的问题是,我能够找到的每个状态机教程都会在每个上升沿(或类似的,但每个时钟一次)更改状态,并且该设备应该处于空闲状态很多,并且只有在 USB_RXFN 变低时才转换为“协商”,保持在“协商”状态直到完成,保持在“接收”状态直到整个图像已传输等等...

我的方法是否存在根本缺陷? CPLD 是否根本不适合此用途?或者是否有可能保持一种状态超过一个时钟,并且为了简单起见,教程只是这样编写的?

I'm looking into creating a system in VHDL that filters an image after receiving it through an FTDI usb-to-serial device. As part of this, I believe I've identified the states that my CPLD should be in, but I have never created a complex state machine in VHDL before, so I'm questioning whether my methods are sound. Currently, the basic outline for my state machine is thus:

begin
    process(clk, reset, USB_RXFN, USB_TXEN)
    begin
        case state is
            when IDLE =>
            when NEGOTIATING =>
            when RECEIVING =>
            when FILTERING =>
            when TRANSMITTING =>
            when OTHERS  => -- this should never happen but go to IDLE
    end process;

My problem here is that every state machine tutorial I've been able to find changes state on every rising edge (or similar, but once per clock) and this device should sit in IDLE a lot and only transition to NEGOTIATING when USB_RXFN goes low, stay in NEGOTIATING until that's done, stay in RECEIVING until the entire image has been transferred etc...

Is there something fundamentally flawed in my approach? Are CPLD's simply unsuited for this purpose? Or is it possible to stay in a state for more than a single clock and the tutorials are just written that way for simplicity?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

想念有你 2024-11-13 13:24:59

简而言之,您阅读的教程只是为了简单起见而这样编写的。

在一个状态中等待某个事件然后再转移到另一个状态是完全可以的。这可以在 VHDL 中以多种方式表达,一种常见的方式是同时具有 StateNextState 信号,例如:

architecture foo of bar is
    type StateType is (IDLE, NEGOTIATING, RECEIVING, FILTERING, TRANSMITTING);
    signal State : StateType;
    signal NextState : StateType;
begin
    FSM: process(clk, reset)
    begin
        if reset='1' then
            State <= IDLE;
        elsif clk'event and clk='1' then
            State <= NextState;
        end if;
    end process FSM;

    STATES: process(State, USB_RXFN, USB_TXEN) -- ...
    begin
        NextState <= State; -- by default, stay in the same state (avoid a latch while you're at it)
        case State is
            when IDLE =>
                if USB_RXFN='0' then
                    NextState <= NEGOTIATING;
                end if;
            -- etc
        end case;
    end process STATES;
end foo;

In brief, the tutorials you've read have just been written that way for simplicity.

It's perfectly ok to wait for some event in a state before moving to another. This can be expressed in many ways in VHDL, one common way is to have both State and NextState signals, something like:

architecture foo of bar is
    type StateType is (IDLE, NEGOTIATING, RECEIVING, FILTERING, TRANSMITTING);
    signal State : StateType;
    signal NextState : StateType;
begin
    FSM: process(clk, reset)
    begin
        if reset='1' then
            State <= IDLE;
        elsif clk'event and clk='1' then
            State <= NextState;
        end if;
    end process FSM;

    STATES: process(State, USB_RXFN, USB_TXEN) -- ...
    begin
        NextState <= State; -- by default, stay in the same state (avoid a latch while you're at it)
        case State is
            when IDLE =>
                if USB_RXFN='0' then
                    NextState <= NEGOTIATING;
                end if;
            -- etc
        end case;
    end process STATES;
end foo;
南街九尾狐 2024-11-13 13:24:59

是的,您可以等待任意时间和/或输入您喜欢的组合,然后再转移到另一个状态。这是一个单一进程的示例。我更喜欢单个进程(TomiJ 展示了一个经典的 2 进程状态机,我重用了其中的一些 - 感谢 TomiJ),因为它有点短,并且可以避免在错过敏感列表之外的信号时无意中推断出锁存器。 “非时钟”进程。

architecture foo of bar is
begin
    FSM: process(clk, reset)
        type StateType is (IDLE, NEGOTIATING, RECEIVING, FILTERING, TRANSMITTING);
        variable state, next_state : StateType;
    begin
        if reset='1' then
            state := IDLE;
            next_state := IDLE;
        elsif rising_edge(clk) then
            case state is
                when IDLE =>
                    if USB_RXFN='0' then
                        next_state := NEGOTIATING;
                    end if;
                -- etc
            end case;
            -- Perform other logic based on state or next_state here

            -- finally update state for next time
            state := next_state;
        end if;
    end process FSM;
end foo;

Yes, you can wait for any amount of time and/or input combinations that you like before moving to another state. Here's a single process example. I prefer a single process (TomiJ has shown a classic 2-process state-machine, I've reused some of it - thanks TomiJ) as it's a bit shorter and avoids inadvertently inferring latches if you miss a signal out of the sensitivity list of the "non-clocked" process.

architecture foo of bar is
begin
    FSM: process(clk, reset)
        type StateType is (IDLE, NEGOTIATING, RECEIVING, FILTERING, TRANSMITTING);
        variable state, next_state : StateType;
    begin
        if reset='1' then
            state := IDLE;
            next_state := IDLE;
        elsif rising_edge(clk) then
            case state is
                when IDLE =>
                    if USB_RXFN='0' then
                        next_state := NEGOTIATING;
                    end if;
                -- etc
            end case;
            -- Perform other logic based on state or next_state here

            -- finally update state for next time
            state := next_state;
        end if;
    end process FSM;
end foo;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文