2012-10-26 151 views
0

我正在嘗試爲VHDL寫一個ADC的逐次逼近寄存器。我正在把它變成一個狀態機。我只是有點不確定我的代碼在最後的狀態塊(current_state = S_LSB)。這段代碼是否有效?在返回狀態之前有沒有更好的方法來重置DigitalOutTemp和OutTemp?狀態機的VHDL代碼

備註比較器的值取決於DigitalOutTemp輸出經過數模轉換器後的值。

LIBRARY ieee; 
USE  ieee.std_logic_1164.all; 

ENTITY SARegister IS 
PORT (
    Comparator, Clock      : IN std_logic; 
    DigitalOutFinal, DigitalOutTemp : OUT std_logic_vector (13 downto 0) 
); 
END; 

ARCHITECTURE Behavioural OF SARegister IS 

CONSTANT S_MSB  : STD_LOGIC_VECTOR(3 downto 0) := "0000"; 
CONSTANT S_TWELVE : STD_LOGIC_VECTOR(3 downto 0) := "0001"; 
CONSTANT S_ELEVEN : STD_LOGIC_VECTOR(3 downto 0) := "0010"; 
CONSTANT S_TEN  : STD_LOGIC_VECTOR(3 downto 0) := "0011"; 
CONSTANT S_NINE  : STD_LOGIC_VECTOR(3 downto 0) := "0100"; 
CONSTANT S_EIGHT : STD_LOGIC_VECTOR(3 downto 0) := "0101"; 
CONSTANT S_SEVEN : STD_LOGIC_VECTOR(3 downto 0) := "0110"; 
CONSTANT S_SIX  : STD_LOGIC_VECTOR(3 downto 0) := "0111"; 
CONSTANT S_FIVE  : STD_LOGIC_VECTOR(3 downto 0) := "1000"; 
CONSTANT S_FOUR  : STD_LOGIC_VECTOR(3 downto 0) := "1001"; 
CONSTANT S_THREE : STD_LOGIC_VECTOR(3 downto 0) := "1010"; 
CONSTANT S_TWO  : STD_LOGIC_VECTOR(3 downto 0) := "1011"; 
CONSTANT S_ONE  : STD_LOGIC_VECTOR(3 downto 0) := "1100"; 
CONSTANT S_LSB  : STD_LOGIC_VECTOR(3 downto 0) := "1101"; 

SIGNAL Next_state  : STD_LOGIC_VECTOR(3 DOWNTO 0); 
SIGNAL Current_state : STD_LOGIC_VECTOR(3 DOWNTO 0); 
SIGNAL OutTemp   : STD_LOGIC_VECTOR(13 DOWNTO 0);  

BEGIN 

PROCESS (Clock) 
BEGIN 

    IF (rising_edge (Clock)) THEN  
     Current_state <= Next_state; 
    END IF; 

END PROCESS; 

PROCESS (Current_state, Comparator) 
BEGIN 
    Next_state <= Current_state; 
    DigitalOutTemp <= "10000000000000"; 
    OutTemp <= "10000000000000"; 
    DigitalOutFinal <= "00000000000000"; 

    IF (Current_state = S_MSB) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(13) <= '0'; 
      OutTemp(13) <= '0'; 
     END IF; 
     DigitalOutTemp(12) <='1'; 
     OutTemp(12) <= '1'; 
     Next_state <= S_TWELVE; 

    ELSIF (Current_state = S_TWELVE) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(12) <= '0'; 
      OutTemp(12) <= '0'; 
     END IF; 
     DigitalOutTemp(11) <='1'; 
     OutTemp(11) <= '1'; 
     Next_state <= S_ELEVEN; 

    ELSIF (Current_state = S_ELEVEN) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(11) <= '0'; 
      OutTemp(11) <= '0'; 
     END IF; 
     DigitalOutTemp(10) <='1'; 
     OutTemp(10) <= '1';   
     Next_state <= S_TEN; 

    ELSIF (Current_state = S_TEN) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(10) <= '0'; 
      OutTemp(10) <= '0'; 
     END IF; 
     DigitalOutTemp(9) <='1'; 
     OutTemp(9) <= '1';   
     Next_state <= S_NINE; 

    ELSIF (Current_state = S_NINE) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(9) <= '0'; 
      OutTemp(9) <= '0'; 
     END IF; 
     DigitalOutTemp(8) <='1'; 
     OutTemp(8) <= '1';   
     Next_state <= S_EIGHT; 

    ELSIF (Current_state = S_EIGHT) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(8) <= '0'; 
      OutTemp(8) <= '0'; 
     END IF; 
     DigitalOutTemp(7) <='1'; 
     OutTemp(7) <= '1';   
     Next_state <= S_SEVEN; 

    ELSIF (Current_state = S_SEVEN) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(7) <= '0'; 
      OutTemp(7) <= '0'; 
     END IF; 
     DigitalOutTemp(6) <='1'; 
     OutTemp(6) <= '1';   
     Next_state <= S_SIX; 

    ELSIF (Current_state = S_SIX) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(6) <= '0'; 
      OutTemp(6) <= '0'; 
     END IF; 
     DigitalOutTemp(5) <='1'; 
     OutTemp(5) <= '1';   
     Next_state <= S_FIVE; 

    ELSIF (Current_state = S_FIVE) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(5) <= '0'; 
      OutTemp(5) <= '0'; 
     END IF; 
     DigitalOutTemp(4) <='1'; 
     OutTemp(4) <= '1';   
     Next_state <= S_FOUR; 

    ELSIF (Current_state = S_FOUR) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(4) <= '0'; 
      OutTemp(4) <= '0'; 
     END IF; 
     DigitalOutTemp(3) <='1'; 
     OutTemp(3) <= '1';   
     Next_state <= S_THREE; 

    ELSIF (Current_state = S_THREE) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(3) <= '0'; 
      OutTemp(3) <= '0'; 
     END IF; 
     DigitalOutTemp(2) <='1'; 
     OutTemp(2) <= '1';   
     Next_state <= S_TWO; 

    ELSIF (Current_state = S_TWO) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(2) <= '0'; 
      OutTemp(2) <= '0'; 
     END IF; 
     DigitalOutTemp(1) <='1';  
     OutTemp(1) <= '1';  
     Next_state <= S_ONE; 

    ELSIF (Current_state = S_ONE) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(1) <= '0'; 
      OutTemp(1) <= '0'; 
     END IF; 
     DigitalOutTemp(0) <='1'; 
     OutTemp(0) <= '1';   
     Next_state <= S_LSB; 

    ELSIF (Current_state = S_LSB) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(0) <= '0'; 
      OutTemp(0) <= '0'; 
     END IF; 

     DigitalOutFinal <= OutTemp; 

     DigitalOutTemp <= "10000000000000"; 
     OutTemp <= "10000000000000"; 

     Next_state <= S_MSB; 

    END IF; 
END PROCESS; 
END; 

回答

0

它很難告訴你的代碼試圖完成,所以我想我會做一些一般性意見,可以幫助你一起。

代碼中存在大量不必要的重複,您可以使用計數器來索引您的位而不是每個狀態中的硬編碼索引,例如使用從您的MSB到LSB的計數器idx可以這樣做:

... 

elsif (current_state = COMPARE) then 

    OutTemp(idx)  <= comparator; 

    if idx > 0 then 
    OutTemp(idx-1) <= '1'; 
    idx   <= idx - 1; 
    next_state  <= current_state; 
    else 
    idx   <= MSB; 
    next_state  <= idle; 
    end if; 
end if; 

這是假設你要設置OutTemp(idx-1)在以前的狀態,這令我有點毫無意義的,但也許它通過外接硬件需要...

你也複製你OutTemp通過分配信號和端口,我會刪除所有任務的端口DigitalOutTemp,而是下面的添加到您的超頻過程:

process (clock) 
begin 

    if rising_edge(clock) then  
    Current_state <= Next_state; 
    DigitalOutTemp <= OutTemp; 
    end if; 
end process; 

這將設置DigitalOutTemp同步,如果你不希望這樣,您可以設置它的時鐘程序,而不是外面,但我會建議你可以同步設置它來避免毛刺。

要回答你的問題,最終狀態:

ELSIF (Current_state = S_LSB) THEN 
     IF (Comparator = '0') THEN 
      DigitalOutTemp(0) <= '0'; 
      OutTemp(0) <= '0'; 
     END IF; 

     DigitalOutFinal <= OutTemp; 

     DigitalOutTemp <= "10000000000000"; 
     OutTemp <= "10000000000000"; 

     Next_state <= S_MSB; 

    END IF; 

..將只設置DigitalOutTemp爲「10000000000000"DigitalOutFinal到什麼是在以前的狀態OutTemp看來,你期望OutTemp一直。更新爲OutTemp(0),但這不會是這種情況,對OutTemp(0)的分配是預定的用於該過程的結束;它不是立即可見的

在IF語句中OutTemp(0)DigitalOutTemp(0)的分配將不會執行任何操作,因爲他們的計劃寫入被您的分配進一步取消。

所以要回答你的問題,它看起來像有效的代碼,它可能會編譯和綜合,但它不會展現你期望的行爲。

希望這會有所幫助。