Altera_Forum
Honored Contributor
10 years agogetting crazy with FSM in VHDL. The FSM runs weird and misbehavior
background:
To Let FPGA (cyclone 3) communication with a DSP board. i am trying to send three datas from DSP board to the FPGA board. code:library ieee;use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dsp_com is port
(
clock : in std_logic;
FPGA_CLK : out std_logic;
led1: out std_logic_vector(3 downto 0) := (others => '1');
Reset: in std_logic :='Z';
dsp_db : inout std_logic_vector(12 downto 0) := (others =>'Z');
dsp_db_output : out std_logic_vector(12 downto 0);
dsp_db_input : in std_logic_vector(12 downto 0);
wr_en : out std_logic:='0'; -- initial state is input
FPGA_ACK : out std_logic := '0'; --default state is 0
DSP_ACK : in std_logic := 'Z'
);
end dsp_com;
architecture FSM_Moore of dsp_com is
TYPE State_type IS (S0, S1, S8, S9, S10, S11); -- 12 States
signal PresentState: State_type;
signal s_DSP_ACK : std_logic ;
signal s_Reset : std_logic;
signal s_dsp_db_input : std_logic_vector(12 downto 0);
signal Adc_address : std_logic_vector(3 downto 0);
signal Adc_buffer : std_logic_vector(12 downto 0);
signal data_from_dsp1 : std_logic_vector(3 downto 0);
signal data_from_dsp2 : std_logic_vector(3 downto 0);
signal data_from_dsp3 : std_logic_vector(3 downto 0);
begin
--5k Hz signal work as FPGA_CLK
clkdsp : process(clock)
variable count : integer range 0 to 2000 :=0;
variable n :std_logic := '0';
begin
if rising_edge(clock) then
count := count + 1;
if(count >= 2000) then
n := not n;
FPGA_CLK <= n ;
count := 0;
end if;
end if;
end process clkdsp;
synchronous : process(clock)
begin
if rising_edge(clock)then
s_DSP_ACK <= DSP_ACK;
s_Reset <= Reset;
s_dsp_db_input <= dsp_db_input;
else
null;
end if;
end process synchronous;
--read the address and get the data
--first: process(clock,s_Reset)
-- begin
-- if (s_Reset = '0') then
-- PresentState <= S0;
-- elsif rising_edge(clock) then
-- PresentState <= PresentState;
-- end if;
-- end process;
first : process(s_Reset, clock)
begin
if (s_Reset = '0') then
PresentState <= S0;
elsif(rising_edge(clock)) then
case PresentState is
when S0 => if s_DSP_ACK = '1' then PresentState <= S1;
else PresentState <= S0; end if;
-- wr_en <= '0'; -- input
-------------------------------single read ADC------------------------------------
when S1 =>
if ((s_DSP_ACK = '0') and (s_dsp_db_input(3 downto 0) = "0100")) then PresentState <= S8;
else PresentState <= S1;end if;
-- wr_en <= '0'; -- input
--------------------------receive 3 datas in sequence ------------------------------------
when S8 => if s_DSP_ACK = '1' then PresentState <= S9;
else PresentState <= S8 ; end if;
-- wr_en <= '0'; -- input
when S9 => if s_DSP_ACK = '0' then PresentState <= S10;
else PresentState <= S9 ; end if;
-- wr_en <= '0'; -- input
when S10 => if s_DSP_ACK = '1' then PresentState <= S11;
else PresentState <= S10; end if;
-- wr_en <= '0'; -- input
when S11 => if s_DSP_ACK = '0' then PresentState <= S0;
else PresentState <= S11; end if;
-- wr_en <= '0';
end case;
end if;
end process;
-- Output depends solely on the current state
second : process(PresentState, data_from_dsp1, data_from_dsp2, data_from_dsp3, s_dsp_db_input(3 downto 0))
--variable DATA : std_logic_vector(12 downto 0);
begin
case PresentState is
when S0 =>
FPGA_ACK <= '0';
led1 <= "0000";
wr_en <= '0'; -- input
-----------------get the adc-buffer--------------
when S1 =>
adc_address <= s_dsp_db_input(3 downto 0); -- get the address
FPGA_ACK <= '1';
led1 <= "0001";
wr_en <= '0'; -- input
----------------------------------------------
------------------------------------------------
when S8 =>
FPGA_ACK <= '0';
led1 <= "1000";
wr_en <= '0'; -- input
when S9 =>
FPGA_ACK <= '1';
data_from_dsp1(3 downto 0) <= s_dsp_db_input(3 downto 0);
if(data_from_dsp1 = "0101")then
led1 <= "1001";
else
led1 <= "0000";
end if;
wr_en <= '0'; -- input
when S10 =>
FPGA_ACK <= '0';
data_from_dsp2(3 downto 0) <= s_dsp_db_input(3 downto 0);
if(data_from_dsp2 ="0111")then
led1 <= "1010";
else
led1 <= "0000";
end if;
wr_en <= '0'; -- input
when S11 =>
FPGA_ACK <= '1';
data_from_dsp3(3 downto 0) <= s_dsp_db_input(3 downto 0);
if(data_from_dsp3 ="1000")then
led1 <= "1011";
else
led1 <= "0000";
end if;
wr_en <= '0'; -- input
end case;
end process;
end FSM_Moore ;
i have already synchronize the input signals e.g. dsp_ack, and db_input to the FSM. this is the most frequency problem that cause FSM runs misbehavior Issue: issues:
when i debug the c program in DSP board and FPGA, every thing is ok ! FSM can switch to the next state according to the DSP_ACK. but if i let the program run. i saw the state is alway stuck at S0 in FPGA, but for the DSP side, the code are still running. anyone has any ideas to this problem? appreciate for you guys' reply ! regard, napon