自上周以来,我一直在处理这个问题,并试图从不同的方式得到正确的答案,但不幸的是,从现在起,它就没有起作用。我有一个状态机,它接收三个模式,并为每个模式制作一个矩阵,然后将所有模式相加并发送到输出。但是状态机发送第一个模式的矩阵来输出。我认为问题是加法器应该与时钟(状态一)一起工作,状态机会随着每个时钟的事件边缘进入下一个状态,因此它无法与加法器同步。但我不知道该怎么解决这个问题。如果有任何帮助,我都会很乐意的。
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;
有几件事很突出。。。
首先,无论何时创建状态机,都需要有一种方法来重置它,理想情况下是一个输入信号,它会迫使顺序元素进入已知状态。在您的情况下,无法重置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;
谢谢你发布这个问题,因为这些都是非常常见的错误。