rahdirs
Advanced Member level 1
- Joined
- May 22, 2013
- Messages
- 424
- Helped
- 93
- Reputation
- 192
- Reaction score
- 91
- Trophy points
- 1,308
- Location
- Mordor
- Activity points
- 4,492
NEXT_STATE_DECODE: process (state,clk,rst,init_calib_complete)
begin
--declare default state for next_state to avoid latches
next_state <= state; --default is to stay in current state
--insert statements to decode next_state
--below is a simple example
case (state) is
when st1_reset =>
if rst = '1' then
next_state <= st1_reset;
clr <= '1';
else
next_state <= st2_idle;
clr <= '1';
end if;
when st2_idle =>
if init_calib_complete = '1' then
next_state <= st3_write;
clr <= '1';
else
next_state <= st2_idle;
end if;
when st3_write =>
if(count = 1500) then
next_state <= st4_wait;
clr <= '1';
ui_c0_app_addr_i <= "111111111111111111111111111";
ui_c0_app_cmd_i <= "111";
ui_c0_app_en_i <= '0';
ui_c0_app_wdf_wren_i <= '0';
ui_c0_app_wdf_end_i <= '0';
wr_en_i <= '0';
rd_en_i <= '0';
else
next_state <= st3_write;
if(app_rdy_1 = '1') then
clr <= '0';
ui_c0_app_addr_i <= addr_count;
ui_c0_app_cmd_i <= "000";
ui_c0_app_en_i <= '1';
ui_c0_app_wdf_wren_i <= '1';
ui_c0_app_wdf_end_i <= '1';
wr_en_i <= '1';
rd_en_i <= '1';
else
clr <= '0';
ui_c0_app_addr_i <= addr_count;
ui_c0_app_cmd_i <= "000";
ui_c0_app_en_i <= '1';
ui_c0_app_wdf_wren_i <= '1';
ui_c0_app_wdf_end_i <= '1';
wr_en_i <= '1';
rd_en_i <= '0';
end if;
end if;
when st4_wait =>
if(count = 157) then
next_state <= st5_read;
clr <= '1';
else
clr <= '0';
next_state <= st4_wait;
end if;
when st5_read =>
if(count = 1500) then
next_state <= st1_reset;
clr <= '1';
ui_c0_app_en_i <= '0';
ui_c0_app_cmd_i <= "111";
else
next_state <= st5_read;
if(app_rdy_1 = '1') then
clr <= '0';
ui_c0_app_en_i <= '1';
ui_c0_app_cmd_i <= "001";
ui_c0_app_addr_i <= addr_count;
end if;
end if;
when others =>
next_state <= st1_reset;
end case;
end process;
end fsm_logic;
I don't see an attached waveform.
Your state machine coding style may be OK for a test bench, but it would not be good for FPGA synthesis,
Your state machine coding style may be OK for a test bench, but it would not be good for FPGA synthesis,
Your code will have the logic after the registers (for the output signals), which is not good for current FPGA's.
But what do you mean by "If you do the state machine in one clocked process, you will automatically get that right"?
Are you referring to my outputs which get updated one clock cycle later ?
Although you've solved your particular problem here, here are a couple of suggestions to help you avoid having to debug this same problem again in the future:This maybe because i'm driving clr signal at multiple places to different values.But my question is because it remains at only at one state at a time,shouldn't only one source be driving it ?
One issue I see with your process is the inclusion of signals in the sensitivity list that are not read in the process and missing ones which are read within the process.
NEXT_STATE_DECODE: process (state,clk,rst,init_calib_complete)
Your code will have the logic after the registers (for the output signals), which is not good for current FPGA's. The logic should be before the registers. If you do the state machine in one clocked process, you will automatically get that right.
case (state) is
when st3_write =>
if(count = 1500) then
clr <= '1';
ui_c0_app_addr_i <= (OTHERS => '1');
ui_c0_app_cmd_i <= "111";
ui_c0_app_en_i <= '0';
ui_c0_app_wdf_wren_i <= '0';
ui_c0_app_wdf_end_i <= '0';
wr_en_i <= '0';
rd_en_i <= '0';
next_state <= st4_wait;
That is what i was saying.When count & addr_count signals change,the entire process needs to execute again,but when do they change ? At every rising edge of clock.When signals in comb logic switch the entire process needs to be execute to determine if the input signal has changed any of the outputs. Therefore adding clk in lieu of the signals count and addr_count is just plain wrong.
You also don't seem to understand that if you have a registered signal (i.e. state) then using that signal in a combinatorial process will infer gates after the registers, so your outputs are all from combinational logic cones, not from the output of registers
exactly that, and those types of errors can be really difficult to find and usually end up as simulation synthesis mismatches. Not a good thing.So you are saying the delta time difference between count & addr_count changing with respect to clock & eventually the process getting rerun delta time earlier than supposed to may lead to errors ?
Yeah ditch the two process, use one process. You'll get a lot of agreement from a lot of the advanced forum members with the exception of a few individuals, who prefer the two process style.Oh so you were just saying about writing my fsm in single process & ditch my present two process fsm,on which there have been many threads as well on Xilinx forum,the advantages of one-process over two process like latches etc...
* driving different bits of a signal from different processes can work on some tools, and can fail on others.
As I mentioned earlier in the thread in #5, use std_ulogic rather than std_logic whenever possible and you can avoid ever having to debug this problem, you either will fail on the compile or at the start of the simulation and won't be able to run.In any case, you should only drive bits of a signals from one (and the same*) process. For sim, the resolution function will result in '0' or '1' if all drivers agree, so the signal will often toggle to 'X'.
Having a design error in your code does not mean the tool is not compliant to the LRM. You still should complain to the vendor about the behavior, but not because it does not conform to the LRM.If this is the case, you need to complain to the tool vendor, as its braking the lrm.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?