- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I made a FSM in verilog that is working in simulation.
I found a strange behaviour however, when I synthesize it in Quartus 2. The state WRITE should immediately go to WRITE_DONE, which it does. But when in state WRITE_DONE, it should wait for the trigger of "ye" going low before moving on to the next state. But when I synthesize and put this on FPGA, the WRITE_DONE is immediately passing to YE_PROG2 state on the next clock cycle, without waiting for the 'if condition'. Does anyone have any suggestion why this might be happening? is there an error in my code I'm missing that's causing the synthesis to not do what I want? The code seems straightforward to me. I did pull out the 'ye' signal in SignalTap to make sure it's high. always@(posedge clk or negedge resetn)
begin
if (!resetn)
begin
state <= IDLE;
end
else
begin
state <= next_state;
end
end
always@(*)
begin
//next_state = IDLE;
case(state)
IDLE: begin
if (read_start | read_next)//(xe & se & ye & yadr_change)) //(xe & ye & se)
next_state = XYS;
else if (xe & prog & !se)
next_state = XPS;
else
next_state = IDLE;
end
// READ
XYS: begin
if ((xe & ye & se) == 0)
next_state = IDLE;
else if (xys_count >= 2)//(xys_count == 2)
next_state = READ;
end
READ: next_state = READ_READY;
READ_READY: begin
if (hreadyout_rise)
next_state = READ2;
end
READ2: next_state = READ_READY2;
READ_READY2: begin
if (hreadyout_rise)
next_state = IDLE;
end
// WRITE
XPS: begin
if ((xe & prog & !se) == 0)
next_state = IDLE;
else if (ye_rise)
next_state = YE_PROG;
end
YE_PROG: begin
if ((xe & prog & !se) == 0)
next_state = IDLE;
else if (prog_count == 5'd31)//(prog_count > 30)
next_state = WRITE;
end
WRITE: next_state = WRITE_DONE;
WRITE_DONE: begin
if (!ye)
next_state = YE_PROG2;
end
YE_PROG2: begin
if ((xe & prog & !se) == 0)
next_state = IDLE;
else if (prog_count == 5'd31)
next_state = WRITE2;
end
WRITE2: next_state = WRITE_DONE2;
WRITE_DONE2: begin
if ((xe & prog & !se) == 0)
next_state = IDLE;
else if (ye_fall)//(hreadyout_rise)
next_state = IDLE;
end
default: next_state = IDLE;
endcase // case (state)
end // always@ (*)
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
where do all the control signals come from? are they synchronised to the clock?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the control signals are inputs to the module. They are direct outputs from a mux, but the source is coming from another block which has the same clock, so they are synchronized to the clock.
As part of my debugging, I tried replacing 'ye' if the if statement of that state to ye_reg (a registered version of the input directly in this module), but it still didn't work. Also, when I look at the control inputs to the module in SignalTap, they are static during the time the state changes (ye_reg included). As a test, I also tried to remove the if statement and make WRITE_DONE stay in that state if it reaches it. This did happen. I also replaced the 'ye' condition in WRITE_DONE with a small counter, so that it should wait to reach a count value before moving to next state - it didn't do that and just went right to YE_PROG2. So somehow, when I get to this state, it seems to be ignoring the 'if' statement (whatever the condition) and just passing on to the next YE_PROG2 state. I don't have any other idea how I can debug this.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Couple of things to check
1. Make sure your signaltap clock is the same as your state machine clock 2. Take a look at Synthesis report -> State Machines section. Check if all your states are synthesized correctly and nothing got optimized.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3. Add SDC constraints to ensure that SignalTap and design doesn't have timing problems
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I believe I found the problem in my code. I think a latch was being inferred during synthesis.
I added 'next_state = state' before the case statement (where the next_state = IDLE is commented out) and it works now. I thought the default state would prevent this, but I guess not. Thanks everyone.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page