2011-05-11 57 views
3

編碼狀態機我在找到創造VHDL一個系統,它接收通過一個FTDI USB到串行設備後濾波的圖像。作爲其中的一部分,我相信我已經確定了我的CPLD應該處於的狀態,但是我從來沒有用VHDL創建複雜的狀態機,所以我在質疑我的方法是否正確。目前,我的狀態機的基本輪廓是這樣的:在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; 

我的問題在這裏,每一個狀態機教程中,我已經能夠找到在每個上升沿改變狀態(或相似,但每一次時鐘)並且這個設備應該處於IDLE狀態,並且只有在USB_RXFN變低時才轉換到NEGOTIATING狀態,停留在RECEIVING狀態直到整個映像已經被轉移等等。

有沒有什麼根本上有缺陷的我的方法? CPLD不適合這個目的嗎?或者是否有可能保持一個以上的時鐘狀態,並且爲簡單起見,教程只是以這種方式編寫的?

回答

3

簡而言之,您閱讀過的教程只是爲了簡化而編寫的。

這是完全可以移動到另一個之前等待某些事件的狀態。這可以在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; 
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; 
+1

看來我不能「接受」兩個答案,所以我選擇了第一個發佈的簡單優點的另一個答案,但是我要感謝您的貢獻。 – medivh 2011-05-11 18:08:46

+0

@medivh - 沒問題:) – 2011-05-12 11:48:05