1
\$\begingroup\$

I am planning to implement a maze routing program using Lee's algorithm. After searching some online resources, it seems that it requires a queue implementation for the BFS to work. After storing the queue values in the register:

   reg[9:0] queue[0:19];
   ...............
   temp<=queue[0];
   if(temp!= 0)begin
        j<=0;
         row<=temp[9:7];
         col<=temp[6:5];
         costp<=temp[4:0];

The control should go inside the if condition as the queue doesn't contain any zeros. But instead the control goes to the following prescript every time:

    else begin
      temp<= 10'b 1110011001;
      error<=1;
      end

Is it because my queue is not being processed correctly? For dequeuing the first queue input, I am using the following prescript:

            queue[0]<=queue[1];
            queue[1]<=queue[2]; 
             queue[2]<=queue[3];
             queue[3]<=queue[4];
             queue[4]<=queue[5];
             queue[5]<=queue[6];
             queue[6]<=queue[7];
             queue[7]<=queue[8];
             queue[8]<=queue[9];
             queue[9]<=queue[10];
             queue[10]<=queue[11];
             queue[11]<=queue[12];
             queue[12]<=queue[13];
             queue[13]<=queue[14];
             queue[14]<=queue[15];
             queue[15]<=queue[16];
             queue[16]<=queue[17];
             queue[17]<=queue[18];
             queue[18]<=queue[19];

I am also attaching the full Verilog code that I have written:

   

module maze_lee(cost,clk,rst,error,temp,i);
input rst,clk;
output wire [4:0]cost;
wire grid[0:4][0:3];// 5x4 grid initialization
//Source and destination declaration
reg [2:0]source_c=3'b 001;
reg [2:0]source_r=3'b 001;
reg [2:0]dest_r= 3'b 100;
reg [2:0]dest_c= 3'b 011;
//declaration ended
reg [2:0]row;
reg [1:0]col;
reg [9:0]queue[0:19];
reg [4:0]costp;
output reg  [8:0]i;
assign grid[0][0]=1;
assign grid[0][1]=0;
assign grid[0][2]=1;
assign grid[0][3]=1;
assign grid[1][0]=0;
assign grid[1][1]=1;
assign grid[1][2]=1;
assign grid[1][3]=0;
assign grid[2][0]=1;
assign grid[2][1]=1;
assign grid[2][2]=0;
assign grid[2][3]=1;
assign grid[3][0]=0;
assign grid[3][1]=1;
assign grid[3][2]=1;
assign grid[3][3]=1;
assign grid[4][0]=1;
assign grid[4][1]=0;
assign grid[4][2]=1;
assign grid[4][3]=1;
//maze declaration ended
//Visited 2D array to check whether the respective grid has been visited or not
reg visited[4:0][3:0];
//direction array defined
wire signed [2:0]x[0:3];
wire signed [2:0]y[0:3];//signed type has to be used as the arrays values can be negative;
//Direction definer
assign x[0]=0;
assign x[1]=-1;
assign x[2]=1;
assign x[3]=0;
assign y[0]=-1;
assign y[1]=0;
assign y[2]=0;
assign y[3]=1;
//declaration of direction definer changed
output reg [9:0]temp;
reg [8:0]j;// index counter of the direction definer array.
output reg error;
reg temp11,temp21,temp31,temp41;
reg temp12,temp22,temp32,temp42;
reg [5:0]costf;

always@(posedge clk) begin
   if(rst)begin
     costp<=0;
     i<=0;
    queue[0]<={source_r,source_c,costp};
     queue[1]<=10'b 0000000000;
     queue[2]<=10'b 0000000000;
     queue[3]<=10'b 0000000000;
     queue[4]<=10'b 0000000000;
     queue[5]<=10'b 0000000000;
     queue[6]<=10'b 0000000000;
     queue[7]<=10'b 0000000000;
     queue[8]<=10'b 0000000000;
     queue[9]<=10'b 0000000000;
     queue[10]<=10'b 0000000000;
     queue[11]<=10'b 0000000000;
     queue[12]<=10'b 0000000000;
     queue[13]<=10'b 0000000000;
     queue[14]<=10'b 0000000000;
     queue[15]<=10'b 0000000000;
     queue[16]<=10'b 0000000000;
     queue[17]<=10'b 0000000000;
     queue[18]<=10'b 0000000000;
     queue[19]<=10'b 0000000000;
    visited[0][0]<=0;
     visited[0][1]<=0;
     visited[0][2]<=0;
     visited[0][3]<=0;
     visited[1][0]<=0;
     visited[1][1]<=0;
     visited[1][2]<=0;
     visited[1][3]<=0;
     visited[2][0]<=0;
     visited[2][1]<=0;
     visited[2][2]<=0;
     visited[2][3]<=0;
     visited[3][0]<=0;
     visited[3][1]<=0;
     visited[3][2]<=0;
     visited[3][3]<=0;
     visited[4][0]<=0;
     visited[4][1]<=0;
     visited[4][2]<=0;
     visited[4][3]<=0;       
     end
  else begin
    temp<=queue[0];
   if(temp!= 0)begin
        j<=0;
         row<=temp[9:7];
         col<=temp[6:5];
         costp<=temp[4:0];
         error<=0;
         if((row==dest_r)&&(col==dest_c))costf<=costp;
         else begin
            costf<=20;
            temp11<=grid[row+x[0]][col+y[0]];
             temp21<=grid[row+x[1]][col+y[1]];
             temp31<=grid[row+x[2]][col+y[2]];
             temp41<=grid[row+x[3]][col+y[3]];
            temp12<=visited[row+x[0]][col+y[0]];
             temp22<=visited[row+x[1]][col+y[1]];
             temp32<=visited[row+x[2]][col+y[2]];
             temp42<=visited[row+x[3]][col+y[3]];            
             if(((temp11==1)||(temp12==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
                 j<=j+1;
                  queue[i+j]<={(row+x[0]),(col+y[0]),costp+1};
                  visited[row+x[0]][col+y[0]]<=1;
                  end
             if(((temp21==1)||(temp22==0))&&((row+x[0]>=0 && row+x[0]<=4)&&(col+y[0]>=0&&col+y[0]<=3)))begin // checks the validity of the up posistions
                 j<=j+1;
                  queue[i+j]<={(row+x[1]),(col+y[1]),costp+1};
                  end
             if(((temp31==1)||(temp32==0))&&((row+x[0]>=0 && row+x[0]<=4)&&(col+y[0]>=0&&col+y[0]<=3)))begin // checks the validity of the right posistions
                 j<=j+1;
                  queue[i+j]<={(row+x[2]),(col+y[2]),costp+1};
                  end
             if(((temp41==1)||(temp42==0))&&((row+x[0]>=0 && row+x[0]<=4)&&(col+y[0]>=0&&col+y[0]<=3)))begin // checks the validity of the down posistions
                 j<=j+1;
                  queue[i+j]<={(row+x[3]),(col+y[3]),costp+1};
                  end
             i<=i+j;
            visited[row][col]<=1;
            // Time to dequeu the visited the grid.Confusion on whether to dequeue using Bruteforce method for now do it
            queue[0]<=queue[1];
            queue[1]<=queue[2]; 
             queue[2]<=queue[3];
             queue[3]<=queue[4];
             queue[4]<=queue[5];
             queue[5]<=queue[6];
             queue[6]<=queue[7];
             queue[7]<=queue[8];
             queue[8]<=queue[9];
             queue[9]<=queue[10];
             queue[10]<=queue[11];
             queue[11]<=queue[12];
             queue[12]<=queue[13];
             queue[13]<=queue[14];
             queue[14]<=queue[15];
             queue[15]<=queue[16];
             queue[16]<=queue[17];
             queue[17]<=queue[18];
             queue[18]<=queue[19];
             end
      end
      else begin
      temp<= 10'b 1110011001;
      error<=1;
      end
end
end
assign cost=costf;
endmodule

The main issues I am receiving is that the outputs are grounded completely. That can be seen from the following screenshot.

No output warnings

I ran simulation on Altera's University Waveform program, and yes, the output was always at constant zero. I expect cost to change because inside the if statement that I have stated at the start of the body, there is cost increase whenever clock pulse covers one time period. But instead, it is constant. The main output is cost because it will determine the shortest path in the desired algorithm.

Any help will be greatly appreciated.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ The question has been significantly improved and all previously requested information has been added into the question. Therefore it has been reopened and the obsolete comments removed. Of the 3 original votes to close, 2 were for "needs details" (details have now been added) and 1 vote was invalid (voted to move it to Meta). If someone still wants to VTC, please also add a comment clearly stating why, so that specific point can be addressed. Thanks. \$\endgroup\$
    – SamGibson
    Commented Jun 7, 2023 at 20:16

1 Answer 1

2
\$\begingroup\$

The warnings show that cost is a constant. This can be easily confirmed by running a Verilog simulation using a trivial testbench since you only have 2 inputs to your module:

module tb;
bit clk;
bit rst=1;

maze_lee dut (.clk(clk), .rst(rst));

always #5 clk++;

initial begin
    #33 rst=0;
    #500 $finish;
end
endmodule

The key is that you need to dump a waveform database that includes all signals inside your design module. When you look at waveforms, you can see why cost is constant.

waves

cost is driven by costf, which is assigned the constant 20 (shown as hex 14 in waves). costf never takes on another value because the following statement is never executed:

        if((row==dest_r)&&(col==dest_c))costf<=costp;

As you can see in waves, row does not equal dest_r.


If you find your code difficult to understand (as I do), there are some techniques you can use that may help.

There is a lot of code in one always block. It may be easier to understand the code better if you split it up into several always blocks. For example, you could move all assignments to queue into a separate always block.

When you see repeated code, like your assignments to queue, you could use a for loop. This replaces 19 lines of code with 1 line:

           for (int ii=0; ii<19; ii++) queue[ii] <= queue[ii+1];

for loops are not just for testbench code; they are synthesizable.

\$\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.