2013-07-09 51 views
1

自上週以來,我一直在這個問題上停滯不前,並試圖從不同的方式接收正確的答案,但不幸的是,現在它沒有工作。 我有一臺狀態機,它接收三種模式併爲它們中的每一個製作一個矩陣,然後將它們彙總在一起併發送到輸出。但狀態機發送第一個模式的矩陣輸出。 我認爲問題在於加法器應該使用時鐘(狀態1),並且狀態機進入具有每個時鐘的事件邊沿的下一個狀態,因此它不能與加法器同步。但我不知道如何解決這個問題。我會善意地提供任何幫助。狀態機執行一個模式

P.S該包必須包含在代碼中。

---------------------------------------------------------------------------------- 
-- Company: 
-- Engineer: 
-- 
-- Create Date: 14:11:16 0NUMBITS-1/11/2012 
-- 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_ARITH.ALL; 
use IEEE.STD_LOGIC_SIGNED.ALL; 
use work.my_data_types.all; 

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

entity state_machine2 is 
port(
     pattern  : in std_logic_vector(0 to NUMBITS-1);     --The incorrect pattern 
     clk   : in std_logic; 
     result  : out matrix2D(0 to NUMBITS-1, 0 to NUMBITS-1) 
    );  
end state_machine2; 

architecture Behavioral of state_machine2 is 

    type state is (zero , one, two); 
    signal pr_state, nx_state : state ; 
    signal s_out_matrix  : matrix2D(0 to NUMBITS-1, 0 to NUMBITS-1); 
    signal s_flipflop_adder : matrix2D(0 to NUMBITS-1, 0 to NUMBITS-1):= (others => (others => (others => '0'))); 
    signal q    : integer; 

begin 

    process(clk) 
    begin 
     if(clk'event and clk = '1')then 
      pr_state <= nx_state; 
     end if; 
    end process; 

    process(pattern, pr_state) 

     variable cnt:  integer := -1;   
    begin 

    case pr_state is 
     when zero => 
      q <= 0;          -- state number 
      if(cnt < NUM_TRAIN_PATTERN)then 
       cnt := cnt + 1; 
       nx_state <= one; 
      else 
       nx_state <= two; 
      end if; 

     when one => 
      q <= 1; 
    For i in 0 to NUMBITS-1 loop         --The multiplication in the pattern 
     For j in 0 to NUMBITS-1 loop              
      if(i = j) then 
       s_out_matrix(i,j) <= (others => '0'); 
      elsif(pattern(i) = pattern(j)) then 
       s_out_matrix(i,j) <= (0 => '1', others => '0'); 
      else 
       s_out_matrix(i,j) <= (others => '1'); 
      end if; 
     end loop; 
    end loop; 

    if(clk'event and clk = '1')then      -- Sum of the matrixes 
     For i in 0 to NUMBITS-1 loop       
      For j in 0 to NUMBITS-1 loop   
       s_flipflop_adder(i,j) <= s_flipflop_adder(i,j) + s_out_matrix(i,j); 
      end loop; 
     end loop; 
    end if; 
      nx_state <= zero; 

     when two =>         
      q <= 2; 
      result <= s_flipflop_adder; 

      end case; 
      test_q <= q; 
     end process; 
end Behavioral; 

the package: 
---------------------------------------------------------------------------------- 
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_SIGNED.ALL; 
---- Uncomment the following library declaration if instantiating 
---- any Xilinx primitives in this code. 
--library UNISIM; 
--use UNISIM.VComponents.all; 

package my_data_types is 
    type matrix2D is array (integer range <> , integer range <>) of signed(2 downto 0); -- Matrix2D 
    constant NUMBITS : integer := 3; 
    constant NUM_TRAIN_PATTERN : natural := 3; 
end my_data_types; 
+2

嘗試將狀態機重寫爲適當的時鐘進程。 –

+5

第二個過程是可怕的。使用可變的異步狀態機與內嵌時鐘的東西混合使用。此外,過程敏感性列表甚至沒有clk信號,代碼也不會編譯。請在尋求幫助之前完善您的代碼。你的代碼有很多其他問題或糟糕的設計,但我認爲你明白了。 – Passepartout

回答

1

幾件事中脫穎而出......

首先,當你創建一個狀態機,需要有重置它迫使時序元件的方式,理想的輸入信號一個已知的狀態。在你的情況下,沒有辦法重置pr_state,因此無法從代碼中知道起始狀態應該是什麼。此外,通過像s_flipflop_adder那樣分配默認值來避免「重置」順序元素,因爲這可能會導致模擬與實際實施之間的不匹配。

其次,不要在同一個過程中產生順序和組合信號。對於每個信號,決定它是順序的(即觸發器,在時鐘沿更新)還是組合的(即從其他信號的值幾乎立即更新,僅由邏輯元件中的傳播延遲減慢)。對於順序信號,創建一個順序過程,其中所有內容都在if rising_edge(clk)if clk'event and clk = '1'語句(等同於大多數用途)內,並且在靈敏度列表中僅包含時鐘(如果是異步的話也可能是復位信號)。對於組合信號,將它們置於組合過程中,這是一個無時鐘和完整靈敏度列表的過程。

在您的設計中,第一個過程是一個正確的順序過程。然而,第二個過程從一個組合過程開始(具有不完整的靈敏度列表),但是隨後嵌套在case語句分支中的s_flipflop_adder被連續分配。信號s_flipflop_adder不太可能被分配,因爲clk不在靈敏度列表中,即使是這樣,合成工具也可能不會按照您的意圖解釋該混合。

最後,不要使用變量來保存狀態信息,就像您對cnt變量所做的一樣,並且確保僅在時鐘邊沿(即按順序)更新狀態。

考慮到這三點,狀態機將看起來更像這個(我內聯從my_data_types包的定義只是爲了使答案更易於閱讀):

library ieee; 
use ieee.std_logic_vector_1164.all; 
use ieee.std_logic_arith.all; 

entity state_machine2 is 
port(
    clk   : in std_logic; 
    rst   : in std_logic; 
    pattern  : in std_logic_vector(0 to NUMBITS-1); 
    result  : out matrix2D(0 to NUMBITS-1, 0 to NUMBITS-1)); 
end state_machine2; 

architecture Behavioral of state_machine2 istype state is (zero , one, two); 
    constant NUMBITS   : integer := 3; 
    constant NUM_TRAIN_PATTERN : natural := 3; 
    subtype signed3 is signed(NUMBITS-1 downto 0); 
    type matrix2D is array (integer range <> , integer range <>) of signed3; 

    signal pr_state   : state; 
    signal s_flipflop_adder : matrix2D(0 to NUMBITS-1, 0 to NUMBITS-1); 
    signal cnt    : integer; 
begin 
    process(clk) is 
     variable add_operand : signed3; 
    begin 
     if rising_edge(clk) then 
      if rst = '1' then 
       pr_state   <= zero; 
       cnt    <= -1; 
       s_flipflop_adder <= (others => (others => (others => '0'))); 
      else 
       case pr_state is 

       when zero => 
        cnt <= cnt + 1; 

        if cnt < NUM_TRAIN_PATTERN then 
         pr_state <= one; 
        else 
         pr_state <= two; 
        end if; 

       when one => 
        for i in 0 to NUMBITS-1 loop 
         for j in 0 to NUMBITS-1 loop 
          if i = j then 
           add_operand := (others => '0'); 
          elsif pattern(i) = pattern(j) then 
           add_operand := (0 => '1', others => '0'); 
          else 
           add_operand := (others => '1'); 
          end if; 

          s_flipflop_adder(i,j) <= s_flipflop_adder(i,j) 
                + add_operand; 
         end loop; 
        end loop; 

       when two => 
        result <= s_flipflop_adder; 
       end case; 
      end if; 
     end if; 
    end process; 
end Behavioral; 

謝謝你發佈這個問題,因爲這些都是很常見的錯誤。