3

FTDIUSB-シリアルデバイスを介して画像を受信した後に画像をフィルタリングするシステムをVHDLで作成することを検討しています。その一環として、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;

ここでの私の問題は、すべてのステートマシンのチュートリアルで、すべての立ち上がりエッジ(または同様の、ただしクロックごとに1回)で状態の変化を見つけることができ、このデバイスはIDLEに多く存在し、USB_RXFNがローになったときにのみNEGOTIATINGに移行する必要があることです。それが完了するまで交渉を続け、画像全体が転送されるまで受信を続けます。

私のアプローチに根本的な欠陥はありますか?CPLDは単にこの目的には適していませんか?または、複数のクロックの間状態を維持することは可能であり、チュートリアルは単純化のためにそのように書かれていますか?

4

2 に答える 2

3

簡単に言うと、これまで読んだチュートリアルは、簡単にするためにそのように記述されています。

別の状態に移動する前に、ある状態で何らかのイベントを待つことはまったく問題ありません。これは、VHDL ではさまざまな方法で表現できます。一般的な方法の 1 つは、 と の両方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;
于 2011-05-11T10:36:50.283 に答える
3

はい、別の状態に移動する前に、任意の時間および/または入力の組み合わせを待つことができます。単一のプロセスの例を次に示します。私は単一のプロセスを好みます (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;
于 2011-05-11T14:50:53.207 に答える