1

自上周以来,我一直坚持这个问题,并试图从不同的方式获得正确的答案,但不幸的是,现在它没有奏效。我有一个状态机,它接收三个模式并为每个模式创建一个矩阵,然后将所有这些模式相加并将其发送到输出。但是状态机将第一个模式的矩阵发送到输出。我认为问题在于加法器应该与时钟(状态一)一起工作,并且状态机随着每个时钟的事件边缘进入下一个状态,因此它不能与加法器同步。但我不知道如何解决这个问题。我会很乐意提供任何帮助。

PS 包必须包含在代码中。

----------------------------------------------------------------------------------
-- 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;
4

1 回答 1

0

有几件事很突出...

首先,无论何时创建状态机,都需要有一种方法来重置它,理想情况下是一个输入信号,它可以强制顺序元素进入已知状态。在您的情况下,无法重置pr_state,因此无法从代码中知道起始状态应该是什么。此外,通过为 分配默认值来避免“重置”顺序元素s_flipflop_adder,因为这可能会导致模拟和实际实现之间的不匹配。

其次,不要在同一进程内生成顺序和组合信号。对于每个信号,确定它是顺序的(即触发器,在时钟沿更新)还是组合的(即几乎立即从其他信号的值更新,仅因逻辑元件中的传播延迟而减慢)。对于顺序信号,创建一个顺序过程,其中所有内容都在if rising_edge(clk)orif clk'event and clk = '1'语句中(在大多数情况下等效),并且灵敏度列表中只有时钟(可能还有您的复位信号,如果它是异步的)。对于组合信号,把它们放在一个组合过程中,这是一个没有时钟和完整灵敏度列表的过程。

在您的设计中,第一个过程是适当的顺序过程。然而,第二个过程以组合过程开始(具有不完整的敏感性列表),但随后s_flipflop_adder在 case 语句的分支中嵌套了一个顺序赋值。该信号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;

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

于 2014-12-29T19:46:37.697 回答