Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
公告
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
17268 讨论

getting crazy with FSM in VHDL. The FSM runs weird and misbehavior

Altera_Forum
名誉分销商 II
1,631 次查看

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
0 项奖励
6 回复数
Altera_Forum
名誉分销商 II
703 次查看

Can you scope out the DSP_ACK signal. Does it ever go high when the DSP program is running?

0 项奖励
Altera_Forum
名誉分销商 II
703 次查看

Did you debug this in a testbench?  

Did you heed the synthesis warning about infered latches in your "second" process? you have signals here that are not set in all processes, which means latches will be infered (which are not a good idea). 

 

Other points of concern - why do you have an unused inout port? 

why do you have in ports that default to 'Z'? 

Why do you have a logic generated clock output?
0 项奖励
Altera_Forum
名誉分销商 II
703 次查看

thanks for your reply!  

yep, it goes high. sorry that i can not scope the dsp_ack signal because of short of osilliscope.
0 项奖励
Altera_Forum
名誉分销商 II
703 次查看

hallo tricky ! 

 

thanks for your reply! 

 

1.sorry that i did not meantioned it clearly, i debug the program in CCS , namly i debug the C code in DSP, for the fpga, i don't know how to debug it like C language. do you know it ? testbench ? 

 

2.yes, i get some infered latched in my process. okay, i will eliminate the latches by giving the signals a default values at the beginning of process. 

 

3.for the inout port, it's a mistake.. should be deleted. because in the top level of my VHDL , i need to use the bidirectional ports to transfer the data. so i divided the inout ports to three signals , input and output and wr_en to control the bidirectional ports. 

 

4. i thought that all the input signals should be assigned to the default state 'Z'.. am i made a mistake ?  

 

5. i need th logic generated clock output as an interrrupt signal for the DSP board.
0 项奖励
Altera_Forum
名誉分销商 II
703 次查看

Input ports in VHDL do not need to be defaulted to 'Z'. Only inout ports can use 'Z'. The default will be overridden if it's connected to an internal signal. And logic inside an FPGA can only be '1' or '0' so will get changed at synthesis time. 

 

I was worried about FPGA_CLK because you called it CLK and thought you might be using it as a clock elsewhere in the FPGA. this is bad practice. If it's going off as an interrupt only, then it should be ok (but its bad naming to call it _CLK, better called _IRQ) 

 

Testbenches are code you have written (usually in HDL) to test the functionality of your VHDL code. It is NOT synthesised, it is run through a simulator. You can then check all the outputs from your code to ensure they behave as you expect. There are plenty of tutorials around on the internet about how to write testbenches.
0 项奖励
Altera_Forum
名誉分销商 II
703 次查看

OK. IF you don't have a scope, please set up SignalTap in your FPGA design and monitor the DSP_ACK signal. You need to know whether that signal triggers high, because then you will know which part of your design to debug. Right now there is not enough information.

0 项奖励
回复