2014-10-26 66 views
0

我有一個任務寫VHDL狀態機來控制一個小型的內置MC(由4個觸發器,2 MUX4to1,MUX1to4,ROM,ALU,Inport組成)。State_Machine VHDL代碼,請你檢查它爲什麼不起作用!它合成好

我寫了不同的代碼,並嘗試了幾種方法,但模擬它顯示沒有結果,我得到'U'的結果。

下面的代碼,請檢查我可能錯過的明顯錯誤。 我認爲問題在於stjatemachine不會通過狀態進行轉換,也不會在每個狀態中執行代碼。

---------------------------------------------------------------------------------- 
-- Company: 
-- Engineer: 
-- 
-- Create Date: 07:48:47 10/26/2014 
-- Design Name: 
-- Module Name: STATE_MACHINE - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
-- 
-- Dependencies: 
-- 
-- Revision: 
-- Revision 0.01 - File Created 
-- Additional Comments: 
-- 
---------------------------------------------------------------------------------- 
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL;-- Uncomment the following library declaration if using 
-- arithmetic functions with Signed or Unsigned values 
--use IEEE.NUMERIC_STD.ALL; 

-- Uncomment the following library declaration if instantiating 
-- any Xilinx primitives in this code. 
--library UNISIM; 
--use UNISIM.VComponents.all; 

entity STATE_MACHINE is 
port (

     --General Ports 
     CLK : in STD_LOGIC; 
     Re_Run_Programme : in STD_LOGIC; 

     --Process A parts 
     Programme_Start : in STD_LOGIC; 
     Data_From_ROM : in STD_LOGIC_VECTOR(7 downto 0); 
     ADDR_To_ROM : out STD_LOGIC_VECTOR (5 downto 0); 
     Programme_Status: out STD_LOGIC; 
     EN_OUT : out STD_LOGIC; 

     --Process B Part 


     --Process C Parts 

     MUX_FF_Select : out STD_LOGIC_VECTOR (1 downto 0); 

     MUX1_Select : out STD_LOGIC_VECTOR(1 downto 0); 
     MUX2_Select : out STD_LOGIC_VECTOR(1 downto 0); 
     ALU_Select : out STD_LOGIC_VECTOR(1 downto 0); 

     EN_A_Ports : out STD_LOGIC; 
     EN_B_Ports : out STD_LOGIC; 

     BUS_Select : out STD_LOGIC_VECTOR (1 downto 0); 
     Reset  : out STD_LOGIC 



    ); 
end STATE_MACHINE; 

architecture Behavioral of STATE_MACHINE is 

type State_Type is (State_A,State_B,State_C,State_D); 
signal State,Next_State : State_Type; 

signal Counter : STD_LOGIC_VECTOR(5 downto 0); 

--signal MO_A : STD_LOGIC; 
--signal MO_B : STD_LOGIC; 
--signal MO_C : STD_LOGIC; 
--signal MO_D : STD_LOGIC; 

signal FF_Instruction : STD_LOGIC_VECTOR (7 downto 0);   -- 00 
signal MUX_ALU_Instruction : STD_LOGIC_VECTOR (7 downto 0);   -- 01 
signal BUS_A_B_Ports_Instruction : STD_LOGIC_VECTOR (7 downto 0); -- 10 
signal Reset_Instruction : STD_LOGIC_VECTOR (7 downto 0); 

signal FF_Path : STD_LOGIC; 
signal MUX_ALU_Path : STD_LOGIC; 
signal BUS_A_B_Ports_Path : STD_LOGIC; 
signal Reset_Path : STD_LOGIC; 

signal EN_OUT_reg : STD_LOGIC; 

--signal Next_Call : STD_LOGIC_VECTOR (7 downto 0); 
signal Instruction_Finder : STD_LOGIC_VECTOR (7 downto 0); 
signal Instruction_Identifier : STD_LOGIC_VECTOR(7 downto 0); 
signal Instruction : STD_LOGIC_VECTOR(7 downto 0); 
signal Call_Next_Instruction : STD_LOGIC_VECTOR(5 downto 0); 


begin 



FF_Instruction  <= "00000000"; 
MUX_ALU_Instruction  <= "01000000"; 
BUS_A_B_Ports_Instruction <= "10000000"; 
Reset_Instruction   <= "11000000"; 

Instruction_Finder <= "11000000"; 

Counter <= "000000"; 
Call_Next_Instruction <= "000000"; 


--Re Run the programme 
Process(CLK) 
begin 
    if rising_edge(CLK) then 
     if (Re_Run_Programme = '1') then 
      State <= State_A; 
--   MO_A <= '0'; 
      else 
      State <= Next_State; 
     end if; 
    end if; 
end Process; 

--next state 
Process(CLK,State) 
begin 

Next_State <= State; 

case State is 


--#### STATE A ##### 
    when State_A => 

    --if falling_edge(CLK) then 

      ADDR_To_ROM <= Call_Next_Instruction; 
      --EN_OUT <= '1'; 
      --if falling_edge (CLK) then 
       --Instruction <= DATA_From_ROM; 
      --end if; 
    Next_State <= State_B; 

    --end if; 


--#### STATE B ##### 
    when State_B => 
    EN_OUT <= '1'; 
       Instruction <= DATA_From_ROM; 

     Instruction_Identifier <= (Instruction and Instruction_Finder); 
     case (Instruction_Identifier) is 
      when "00000000" => FF_Path <= '1'; 
      when "01000000" => MUX_ALU_Path <= '1'; 
      when "10000000" => BUS_A_B_Ports_Path <= '1'; 
      when "11000000" => Reset_Path <= '1'; 
      when others => null; 
     end case; 
     Next_State <= State_C after 40ns; 

--#### STATE C##### 

    when State_C => 

     --######## 
     if ((FF_Path = '1') and (Counter = 2)) then 
      MUX_FF_Select <= "00"; 
     end if; 
     if ((FF_Path = '1') and (Counter = 4)) then 
      MUX_FF_Select <= "00" after 20ns; 
     end if; 

     --######## 

     if (falling_edge(CLK) and (MUX_ALU_Path = '1')) then 
      MUX1_Select <= "00"; 
      MUX2_Select <= "00"; 
     end if; 

     --######## 

     if (rising_edge(CLK) and BUS_A_B_Ports_Path = '1') then 
      if Counter = 1 then 
       BUS_Select <= "01"; 
      end if; 
      if Counter = 3 then 
       BUS_Select <= "10"; 
      end if; 
      EN_A_Ports <= '1'; 
      EN_B_Ports <= '1'; 
     end if; 

     --######## 

     if (rising_edge(CLK) and Reset_Path = '1') then 
     Reset <= '1'; 
     end if; 

     Next_State <= State_D after 60ns; 

--#### STATE D ##### 

    when State_D => 


     EN_OUT <= '0'; 
     Counter <= Counter + 1; 

     if Counter > 5 then  
      Next_State <= State_D; 
     end if; 

     Call_Next_Instruction <= Counter; 

     Next_State <= State_A; 


    end case; 
end process; 


end Behavioral; 

GitHub的鏈接代碼:https://github.com/quasarMind/StateMachine.git

+0

這將永遠不會合成:60ns後的'Next_State <= State_D;'你也在使用時鐘的'falling_edge'和'rising_edge',這很難合成。 – 2014-10-26 19:19:40

+0

以正確的同步形式重寫第二個進程,就像第一個進程一樣。更好的是,將它們都轉換爲一個進程狀態機。 – 2014-10-26 19:28:35

+0

@BillLynch看來,使用上升沿和下降沿都不是一個好習慣,我是VHDL的新手,但是你能否介紹一下這個問題,因爲我需要輸出沒有打開的命令相同的時鐘事件,所以如何能夠在下一個時鐘上依次執行另一個時鐘,謝謝! – Sam 2014-10-26 20:07:04

回答

0

除了由比爾·林奇和布賴恩·德拉蒙德意見處理合成的資格有原因的模型得到所有「U的似乎周圍多個驅動器旋轉的 Instruction_FinderCounterCall_Next_Instruction 。一個司機是初始化的另一個提供所有的'U's,這兩個解決所有的'U's。

爲了模擬,看看你的狀態機實際上不會(和迴避合成的問題)的目的,在其聲明中這三個信號設置的默認值,並註釋掉額外的並行信號賦值語句,如:

signal Counter : STD_LOGIC_VECTOR(5 downto 0) := (others => '0'); 

signal Instruction_Finder : STD_LOGIC_VECTOR (7 downto 0) := "11000000"; 

signal Call_Next_Instruction : STD_LOGIC_VECTOR(5 downto 0) := (others => '0'); 


-- Instruction_Finder <= "11000000"; 
-- Counter <= "000000"; 
-- Call_Next_Instruction <= "000000"; 

大多數綜合供應商會遵守FPGA目標信號的默認值,否則您可以添加重置。

相關問題