2013-11-21 70 views
0

這是一個長分區二進制分頻器的模擬。該程序按預期執行,除了不會從寄存器的5個MSB中減去除數,無論我如何編寫它。爲什麼我的VHDL狀態機不會執行減法?

以下是代碼:

  library ieee; 
      use ieee.std_logic_1164.all; 
      use ieee.std_logic_unsigned.all; 
      use ieee.std_logic_arith.all; 

      ENTITY divider IS 

       PORT(
          Clock    :IN STD_LOGIC; 
          Dividend   :IN STD_LOGIC_VECTOR(7 DOWNTO 0); 
          Divisor   :IN STD_LOGIC_VECTOR(4 DOWNTO 0); 
          Reset    :IN STD_LOGIC; 
          St     :IN STD_LOGIC; 

          outDRegister   :OUT STD_LOGIC_VECTOR(8 DOWNTO 0):="000000000"; 
          outCurrentState   :OUT STD_LOGIC_VECTOR(2 DOWNTO 0):="000"; 
          Quotient   :OUT STD_LOGIC_VECTOR(3 DOWNTO 0); 
          Remainder  :OUT STD_LOGIC_VECTOR(4 DOWNTO 0)); 
      END divider; 

      ARCHITECTURE Behavior of divider IS 

      SIGNAL DRegister      :STD_LOGIC_VECTOR(8 DOWNTO 0); 
      SIGNAL SubOut       :STD_LOGIC_VECTOR(4 DOWNTO 0); 
      Signal C,ShiftIn, ShiftRes   :STD_LOGIC; 
      Signal ShiftEnable     :STD_LOGIC; 
      Signal tempSt       :STD_LOGIC:='1'; 
      TYPE State_type IS (S0, S1, S2, S3, S4, S5); 
      SIGNAL y:State_type:=S0; 

      BEGIN 
      PROCESS(Dividend,Divisor,y, st, reset, clock) IS 
      BEGIN 
      If (Reset='0') THEN 
      Y<=S0; 
      ELSIF (Clock'EVENT and CLOCK = '1') THEN 

       CASE y IS 
        WHEN S0=> 
         IF(st='0' AND tempSt='1' AND reset = '1') THEN 
          DRegister <= '0'&Dividend; 
          y<=S1; 
         ELSIF(st='1' AND reset = '1') THEN 
          Quotient <= DRegister(3 DOWNTO 0); 
          Remainder <= DRegister(8 DOWNTO 4); 
          y<=S0; 
         END IF; 
         outDRegister<=DRegister; 
         outCurrentState<="000"; 
         tempSt<=st; 

        WHEN S1=> 
         IF(DRegister(8 DOWNTO 4)>=Divisor) THEN 
          y<=S0; 
         ELSE 
          DRegister <= (DRegister(7 DOWNTO 0) & '0'); 
          y<=S2; 
         END IF; 
         outDRegister<=DRegister; 
         outCurrentState<="001"; 
        WHEN S2=> 
         IF(DRegister(8 DOWNTO 4)>=Divisor) THEN 
          DRegister(8 DOWNTO 4)<=(DRegister(8 DOWNTO 4) - Divisor);--Does not work!! Does nothing. 
          DRegister <= DRegister(7 DOWNTO 0) & '1'; 
         ELSE 
          DRegister <= DRegister(7 DOWNTO 0) & '0'; 
         END IF; 
         outDRegister<=DRegister; 
         outCurrentState<="010";  
         y<=S3; 

        WHEN S3=> 
         IF(DRegister(8 DOWNTO 4)>=Divisor) THEN 
          DRegister(8 DOWNTO 4)<=(DRegister(8 DOWNTO 4) - Divisor);--Does not work!! Does nothing. 
          DRegister <= DRegister(7 DOWNTO 0) & '1'; 
         ELSE 
          DRegister <= DRegister(7 DOWNTO 0) & '0'; 

         END IF; 
         outDRegister<=DRegister; 
         outCurrentState<="011"; 
         y<=S4; 

        WHEN S4=> 
         IF(DRegister(8 DOWNTO 4)>=Divisor) THEN 
          DRegister(8 DOWNTO 4)<=(DRegister(8 DOWNTO 4) - Divisor);--Does not work!! Does nothing. 
          DRegister <= DRegister(7 DOWNTO 0) & '1'; 
         ELSE 
          DRegister <= DRegister(7 DOWNTO 0) & '0'; 
         END IF; 
         outDRegister<=DRegister; 
         outCurrentState<="100"; 
         y<=S5; 

        WHEN S5=> 
         IF(DRegister(8 DOWNTO 4)>=Divisor) THEN 
          DRegister(8 DOWNTO 4)<=(DRegister(8 DOWNTO 4) - Divisor);--Does not work!! Does nothing. 
         END IF; 
         outDRegister<=DRegister; 
         outCurrentState<="101"; 

         y<=S0; 

       END CASE; 

      END IF; 




      END PROCESS; 


      END Behavior; 

回答

0

第一步是在VHDL變量和信號分配之間的差閱讀起來。你的問題在於此。一種解決方案涉及問題狀態的中間變量;另一個涉及重寫信號分配。

我通常的解釋是here,頁面底部有一個鏈接「VHDL's Crown Jewel」,這也非常值得一讀。

還要注意:

  • 有算術更好的庫:ieee.numeric_std而非std_logic_unsigned或std_logic_arith或(最糟糕的)混合兩種。
  • 對於算術,有比std_logic_vector更好的數據類型:ieee.numeric_std.unsigned(或signed),或者甚至是integernatural的子類型;
  • 當你正在寫一個乾淨的單進程狀態機,它的靈敏度名單隻需要clock, reset
  • 你可以失去的括號條件表達式,If Reset='0' Then是罰款(這不是你父親的C編譯器)
  • rising_edge(Clock)優先於Clock'EVENT and CLOCK = '1'
    但這些都是主要問題的外圍。
0

有問題的代碼部分,因爲你也標記爲:

... 
DRegister(8 downto 4) <= (DRegister(8 downto 4) - Divisor); --Does not work!! Does nothing. 
DRegister    <= DRegister(7 downto 0) & '1'; 
... 

在VHDL中,沒有更新的信號的值,直到當前 模擬週期的結束,所以值DRegister用於第二次分配至 DRegister以上不會被第一次分配至DRegister

所以,所述第一分配的到DRegister(8 downto 4)效果通過 重寫所述第二分配到所有的位中DRegister,由此 Divisor的減法不產生任何影響。

糾正代碼的一種方法,以便只對所有DRegister位進行單一賦值。

你可能想看看David Koontz的答案,在 https://stackoverflow.com/a/20104800/2352082因爲這涵蓋了類似的問題。