2
\$\begingroup\$

This is an extension of the following post: Queue values are not being accessed

As per the recommendation of the posts and using loops, I then tried to implement my problem using a Finite State Machine. But, when I tried to simulate my program using University Program Waveform of Altera Quartus, the following error pops up in the simulation window even though the synthesis had no error.

Error: Iteration limit reached within 195 ns

I am attaching the FSM part of the code:

parameter IDLE=4'b 0000;
parameter ROW_COL_SELEC=4'b 0001;
parameter LEFT_CHECKER=4'b 0010;
parameter UP_CHECKER=4'b 0011;
parameter DOWN_CHECKER=4'b 0100;
parameter RIGHT_CHECKER=4'b 0101;
parameter ENQUEU_VALID=4'b 0110;
parameter DEQUEUE_FIRST=4'b 0111;
parameter FINAL_RESULT=4'b 1000;
//signal declaration for the queue element entry.
always @(posedge clk)begin
  if(rst)begin
      current_state<=IDLE;
       end
  else begin
      current_state<=next_state;
       end
       end
always @(*)begin
case(current_state)
IDLE:begin
   i<=0;
    costp<=0;
    j<=0;
    queue[0]<={source_r,source_c,costp};
    for(ii=1; ii<20; ii++)queue[ii]<=10'b 0000000000;
    for(ij=0;ij<5;ij++)begin
       for(ik=0; ik<4;ik++)begin
            visited[ij][ik]<=0;
             end
        end
    next_state<=ROW_COL_SELEC;
    end
ROW_COL_SELEC:begin
     temp<=queue[0];
       row<=queue[0][9:7];
       col<=queue[0][6:5];
       costp<=queue[0][4:0];
       if((row==dest_r) && col==dest_c)next_state<=FINAL_RESULT;
       else next_state<=LEFT_CHECKER;
       end
LEFT_CHECKER:begin
     if(((grid[row+x[0]][col+y[0]]==1)||(visited[row+x[0]][col+y[0]]==0))&&((row+x[0]>=0 && row+x[0]<=4)&&(col+y[0]>=0&&col+y[0]<=3)))begin // checks the validity of the left posistions
                         k<=1;           
                         end
       else k<=0;
       next_state<=UP_CHECKER;
       end
UP_CHECKER:begin
     if(((grid[row+x[1]][col+y[1]]==1)||(visited[row+x[1]][col+y[1]]==0))&&((row+x[1]>=0 && row+x[1]<=4)&&(col+y[1]>=0&&col+y[1]<=3)))begin // checks the validity of the up posistions
                     l<=1;
                     end
      else l<=0;
       next_state<=DOWN_CHECKER;
       end
DOWN_CHECKER:begin
     if(((grid[row+x[2]][col+y[2]]==1)||(visited[row+x[2]][col+y[2]]==0))&&((row+x[2]>=0 && row+x[2]<=4)&&(col+y[2]>=0&&col+y[2]<=3)))begin // checks the validity of the right posistions
                     m<=1;
                        end    
       else m<=0;
       next_state<=RIGHT_CHECKER;
       end
RIGHT_CHECKER:begin
     if(((grid[row+x[3]][col+y[3]]==1)||(visited[row+x[3]][col+y[3]]==0))&&((row+x[3]>=0 && row+x[3]<=4)&&(col+y[3]>=0&&col+y[3]<=3)))begin // checks the validity of the down posistions
                      n<=1;
                      end
       else n<=0;
       next_state<=ENQUEU_VALID;
       end 
ENQUEU_VALID:begin
                if((n==1) && (m==1) && (l==1) && (k==1))begin
                         queue[j+1]<={(row+x[0]),(col+y[0]),costp+1};
                         queue[j+2]<={(row+x[1]),(col+y[1]),costp+1};
                         queue[j+3]<={(row+x[2]),(col+y[2]),costp+1};
                         queue[j+4]<={(row+x[3]),(col+y[3]),costp+1};
                     j<=j+4;                 
                         end
                       else if((n==1) && (m==1) && (l==1)&&(k==0))begin
                         queue[j+1]<={(row+x[1]),(col+y[1]),costp+1};
                         queue[j+2]<={(row+x[2]),(col+y[2]),costp+1};
                         queue[j+3]<={(row+x[3]),(col+y[3]),costp+1};
                         j<=j+3;
                         end
                       else if((n==1) && (m==1) && (l==0)&&(k==1))begin
                         queue[j+1]<={(row+x[0]),(col+y[0]),costp+1};
                         queue[j+2]<={(row+x[2]),(col+y[2]),costp+1};
                         queue[j+3]<={(row+x[3]),(col+y[3]),costp+1};
                         j<=j+3;
                         end
                       else if((n==1) && (m==0) && (l==1)&&(k==1))begin
                         queue[j+1]<={(row+x[0]),(col+y[0]),costp+1};
                         queue[j+2]<={(row+x[1]),(col+y[1]),costp+1};
                         queue[j+3]<={(row+x[3]),(col+y[3]),costp+1};
                         j<=j+3;
                         end
                       else if((n==0) && (m==1) && (l==1)&&(k==1))begin
                           queue[j+1]<={(row+x[0]),(col+y[0]),costp+1};
                           queue[j+2]<={(row+x[1]),(col+y[1]),costp+1};
                           queue[j+3]<={(row+x[2]),(col+y[2]),costp+1};
                           j<=j+3;
                           end
                       else if((n==1) && (m==1) && (l==0)&&(k==0))begin
                           queue[j+1]<={(row+x[2]),(col+y[2]),costp+1};
                           queue[j+2]<={(row+x[3]),(col+y[3]),costp+1};
                           j<=j+2;
                           end
                       else if((n==1) && (m==0) && (l==1)&&(k==0))begin
                           queue[j+1]<={(row+x[1]),(col+y[1]),costp+1};
                           queue[j+2]<={(row+x[3]),(col+y[3]),costp+1};
                           j<=j+2;
                           end
                       else if((n==0) && (m==1) && (l==1)&&(k==0))begin
                           queue[j+1]<={(row+x[1]),(col+y[1]),costp+1};
                           queue[j+2]<={(row+x[2]),(col+y[2]),costp+1};
                           j<=j+2;
                           end
                       else if((n==0) && (m==1) && (l==0)&&(k==1))begin
                           queue[j+1]<={(row+x[0]),(col+y[0]),costp+1};
                           queue[j+2]<={(row+x[2]),(col+y[2]),costp+1};
                           j<=j+2;
                           end             
                       else if((n==0) && (m==0) && (l==1)&&(k==1))begin 
                           queue[j+1]<={(row+x[0]),(col+y[0]),costp+1};
                          queue[j+2]<={(row+x[1]),(col+y[1]),costp+1};
                           j<=j+2;
                           end 
                       else if((n==1) && (m==0) && (l==0)&&(k==1))begin 
                          queue[j+1]<={(row+x[0]),(col+y[0]),costp+1};
                           queue[j+2]<={(row+x[3]),(col+y[3]),costp+1};
                           j<=j+2;
                           end
                       else if((n==1) && (m==0) && (l==0)&&(k==0))begin 
                        queue[j+1]<={(row+x[3]),(col+y[3]),costp+1};
                           j<=j+1;
                           end
                      else if((n==0) && (m==1) && (l==0)&&(k==0))begin
                        queue[j+1]<={(row+x[2]),(col+y[2]),costp+1};
                           j<=j+1;
                           end
                      else if((n==0) && (m==0) && (l==1)&&(k==0))begin
                          queue[j+1]<={(row+x[1]),(col+y[1]),costp+1};
                           j<=j+1;
                           end
                       else if((n==0) && (m==0) && (l==0)&&(k==1))begin
                           queue[j+1]<={(row+x[0]),(col+y[0]),costp+1};
                            j<=j+1;
                            end
                       else  begin
                          queue[j]<=queue[j];
                           j<=j+0;
                           end
                      next_state<=DEQUEUE_FIRST;
                           end
DEQUEUE_FIRST:begin
                    visited[row][col]<=1;
                        for(int kk=0;kk<19;kk++)begin
                         queue[kk]<=queue[kk+1];
                          end
                           next_state<=ROW_COL_SELEC;
                           end
FINAL_RESULT:begin
                  costp<=costp;
                        if(rst)next_state<=IDLE;
                        else next_state<=FINAL_RESULT;
                        end
endcase
end
endmodule
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

That error commonly occurs when you have a combinational loop in your code. For example, look at the costp signal in this code:

always @(*)begin
case(current_state)
IDLE:begin
   i<=0;
    costp<=0;
    j<=0;
    queue[0]<={source_r,source_c,costp};

always @* is used to infer combinational logic. You make an assignment to costp on the 5th line, then "read from" costp on the last line. This can cause the simulator to trigger the always block multiple times when costp changes.

You do the same thing with the queue signal.

You likely want to infer sequential logic for some of that, for example using:

always @(posedge clk) begin

Again, your code might be simpler if you split up that big always block into more blocks. For example, keep the logic that assigns to next_state, but consider making assignments to other signals in other blocks.

always @* begin
    case (current_state)
        IDLE            : next_state = ROW_COL_SELEC;
        ROW_COL_SELEC   : next_state = ((row==dest_r) && (col==dest_c)) ? FINAL_RESULT : LEFT_CHECKER;
        LEFT_CHECKER    : next_state = UP_CHECKER;
        UP_CHECKER      : next_state = DOWN_CHECKER;
        DOWN_CHECKER    : next_state = RIGHT_CHECKER;
        RIGHT_CHECKER   : next_state = ENQUEU_VALID;
        ENQUEU_VALID    : next_state = DEQUEUE_FIRST;
        DEQUEUE_FIRST   : next_state = ROW_COL_SELEC;
        FINAL_RESULT    : next_state = (rst) ? IDLE : FINAL_RESULT;
    endcase
end
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.