- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The verilog code below is a FSM I designed . I find this FSM can run correctly and jump between different states at first ,
but after running several seconds it will fall into a fixed state(state=0, state2=0 or state=7,state2=4) and never come out again. According to the logic , the FSM can step into state 0 only once after power on reset; moreover ,any time when falling into state 0,it should can come out and step into state 1. But the reality is that it never come out again. Is there any problem with this FSM code ? How to deal with this problem? Thanks! code: reg [2:0] state; reg [2:0] state2; reg [9:0] count; always @(posedge CLK) begin if(RESET)//power on reset begin state <= 0; state2 <= 0; count <= 0; end else begin case (state) 0: begin case (state2) 0: begin if (count == 0) begin //process count <= count + 1; end else if (count < 2) begin //process count <= count + 1; end else begin count <= 0; state2 <= 1; end [/INDENT]end 1: begin if (count == 0) begin //process count <= count + 1; end else if (count < 6) begin //process count <= count + 1; end else begin count <= 0; state2 <= 2; end [/INDENT]end 2: begin if (count == 0) begin //process count <= count + 1; end else if (count < 6) begin //process count <= count + 1; end else begin count <= 0; state2 <= 3; end [/INDENT]end 3: begin if (count == 0) begin //process count <= count + 1; end if (count == 1) begin //process count <= 0; state2 <= 0; state <= 1; end [/INDENT]end endcase [/INDENT][/INDENT]end 1: begin //process state <= 2; end 2: begin //process state <= 3; end 3: begin //process state <= 4; end 4: begin //process state <= 5; end 5: begin //process state <= 6; end 6: begin //process state <= 1; end default: begin state <= 1; end endcase [/INDENT]end [/INDENT]endLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
According to your code, there is no state 7. That would therefore be impossible. Also there is no state2 == 4. Also impossible. The only way this can be happening is if there is some input to the system not illustrated in the code that affects the state machine. That input may be an upset caused by the fact that you're not meeting timing. Are you meeting timing requirements?
Also, are you sure you are getting a clean reset? May I suggest the following:reg state;
reg state2;
reg count;
always @(posedge CLK or posedge RESET) begin
if(RESET) begin //power on reset
state <= 0;
state2 <= 0;
count <= 0;
end else begin
case (state)
0:
case (state2)
0: begin
count <= count + 1;
if(count == 2) begin
state2 <= 1;
count <= 0'
end
end
1: begin
count <= count + 1;
if(count == 6) begin
state2 <= 2;
count <= 0'
end
end
2: begin
count <= count + 1;
if(count == 6) begin
state2 <= 3;
count <= 0'
end
end
3: begin
count <= count + 1;
if(count) begin
state <= 1;
state2 <= 0;
count <= 0;
end
end
endcase
1: state <= 2;
2: state <= 3;
3: state <= 4;
4: state <= 5;
5: state <= 6;
6: state <= 1;
default: state <= 0;
endcase
end
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much for your suggestions!
Following facts may give you more information about this problem: 1.The compilation report shows the timing is meeted. 2.The "RESET" sigal is generated from following module: module SELF_RESET(// power on reset input CLK10, output reg SELF_RESET ); reg [3:0] count; always @(posedge CLK10) begin if(count != 10) begin count <= count + 1; SELF_RESET <= 1'b1; end else SELF_RESET <= 1'b0; [/INDENT]end [/INDENT] endmodule The CLK10 is 10MHz.The CLK in FSM is a 90MHz clock generated from a PLL in the FPGA with the input of 15MHz . Both the 10MHz and 15MHz are inputs of FPGA and these two clocks are in different clock domain. 3. Whatever signal cause the FSM jump into a state which is not exist or unwanted , the FSM should can jump out of this state according to the logic. For example, when the state is changed to 7, FSM should jump into the default state and then jump into state 1. When the state is changed to 0, it also can come out of state o and jump into state 1. But the fact is once the FSM fall into state 7 or state 0 after running correctly for several seconds, it will never come out again. Is my understanding about this FSM correct?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi tigre,
1) It is good design practice to always provide an external reset signal to your system. This is definitly required when you are targeting an ASIC design. 2) On an FPGA where the registers are initialized to a known state after configuration, you can of course provide a "Power Up" reset signal as you are doing. 3) Your design is working in two different clock domains, that are unrelated. You have one external clock of 10MHz and a second unrelated clock of 90MHz generated by a PLL from a separte 15MHz signal. When you are resting your circuit operating at 90MHz by a reset signal that is generated from an unrelated 10MHz clock, there is no direct correlation between the arrival of the RESET signal and the 90MHz CLK clock signal. This means that your RESET signal will be "racing" with the CLK signal to arrive first at the specific registers in your design. Depending on the specific wiring configuration obtained during the Fitting of your design, it can occur that some registers get reset and other do not. So the behavior that you describe is to be expected. Operating among clock domains is not trivial and you can always suffer from metastability. You can at least improve the behavior of your FSM by "synchronizing" your RESET signal via a number of registers in a chain. This could for example be done as follows for your design:reg RESET, RESET1;
wire RESET2;
always @(posedge CLK) begin
RESET = RESET1;
RESET1 = RESET2;
end
SELF_RESET u1 (clock, RESET2);
This adds two intermediate signals RESET1 and RESET2. In each flipflop the RESET signal will be "synchronized" better to the 90MHz CLK signal. The problems with metastability will be lower at least. Hope this helps...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't see a reason for the reported behaviour in the posted code. Because no asynchronous events are processed in the FSM (which is the most likely cause for FSM erratic behaviour), PLL loss of lock should be considered.
Although a reliable design operation can't be expected with an unstable clock, you can prevent FSM lockup in illegal states by specifying safe FSM in general synthesis options or synthesis attributes. To make safe FSM coding effective, both state machines should have default states. This is the respective Verilog syntax for specifying safe state machine synthesisreg state /* synthesis syn_encoding = "safe" */;
reg state2 /* synthesis syn_encoding = "safe" */;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@FvM
The code for the FSM (with the addition of the "default:" in all case statements) as suggested by jacobjones should work. Once started up the FSM from the "SELF_RESET" the FSM should operate without the problems mentioned by tigre. @tigre Is the behavior (after several seconds) that you describe occuring with the "SELF_RESET" that you posted before? 1) If YES. Why do you generated the "SELF_RESET" from a 10MHz clock unrelated to the 90MHz CLK? 2) If NO. I suppose that you are generating a RESET at several instances from an external signal in the 10MHz clock domain. If this is the case, your design can be influenced by races. (for a solution see my previous post).- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- The code for the FSM (with the addition of the "default:" in all case statements) as suggested by jacobjones should work. --- Quote End --- As far as I see, no default state is yet implemented for state2. Generally, without forcing safe state machine synthesis, you shouldn't make assumptions about behaviour in illegal states. Also, as long as you don't specify an explicite FSM processing, one state hot is the default coding style for any state machine recognized by the compiler. This implies additional possible illegal states outside the expected binary state variable number range. Safe state machine or explicite state encoding is the only way to avoid this issue. Furthermore, I realized that the FSM code in the original post isn't representing a full design, because it hasn't any output. Thus I wonder, if any details of the real design, omitted in the post, may cause the discussed problem. To be sure about, I would like to see a full design that still reproduces the issue. P.S.: Regarding the RESET discussion, I agree that driving the SELF_RESET logic from a different clock basically causes an asynchronous reset, that may cause a FSM to change to an illegal state at worst case. Thus the reset should be better synchronized to the FSM CLK by usual means. But this issue can't explain a FSM failure after correct initial startup.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@sanmao
1)There is only one SELF_RESET instance in my project. The 10MHz clock is the main clock in the project and the 90MHz clock is only used in one module. 2)I will rewrite the SELF_RESET code as you suggested. @FvM 1) I have check the pll "locked" signal after the FSM problem appears, it is in high level . So ,the 90MHz clock is stable. 2)/*synthesis syn_encoding = "safe"*/ added behind "state" definition can work in Quartus2? Does it have the same effect as "default" item in case statement?- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page