状态机仅针对一种模式执行

时间:2013-07-09 10:05:03

标签: vhdl

自上周以来我一直坚持这个问题,并尝试从不同的方式得到正确的答案但不幸的是,因为现在它没有奏效。 我有一个状态机,接收三个模式并为每个模式制作一个矩阵,然后将所有这些模式相加并将其发送到输出。但是状态机将第一个模式的矩阵发送到输出。 我认为问题是加法器应该与时钟(状态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;

1 个答案:

答案 0 :(得分:0)

有些事情脱颖而出......

首先,无论何时创建状态机,都需要有一种方法来重置它,理想情况下是一个强制顺序元素处于已知状态的输入信号。在您的情况下,无法重置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;

感谢您发布此问题,因为这些是非常常见的错误。