-1

I am attempting to make the snake game in verilog using my DEE-10 Lite and compiling using Quartus Prime (Lite Edition Version 20.1.1).

The Analysis and Synthesis time takes almost 10 times longer after adding the following for loop:

for (i = 0); i < size; i = i + 1) begin
  a[size - i] <= a[size - i -1]
end 

reg [5:0] size = 6'd0; reg [5:0] a [0:64];

I'm sure the issue is with me thinking behaviourally instead of data paths/registers. I'm hoping there's a solution that. I've included the rest of the code as well. I'm also using vga to display the board. I'm certain the compilation issues are due to that for statement, as I've tried compilation with and without it included.

module SnakeGame(clk, reset_n, VGA_HS, VGA_VS, VGA_R, VGA_B, VGA_G, switch_one, switch_two, switch_three, ones, tens);

input clk;
input reset_n;
input switch_one, switch_two, switch_three;

output [3:0] VGA_R;
output [3:0] VGA_G;
output [3:0] VGA_B;
output VGA_HS;
output VGA_VS;
output [6: 0] ones, tens;

reg [3:0] red = 0, green = 0, blue = 0;

localparam NUM_COLS = 640;
localparam NUM_ROWS = 480;
localparam SIZE_OF_SQUARE = 60;

localparam COL_WIDTH = $clog2(NUM_COLS-1);
localparam ROW_WIDTH = $clog2(NUM_ROWS-1);

reg [31:0] randomizer = 32'd1;

wire disp_ena;
wire [COL_WIDTH-1:0] col;
wire [ROW_WIDTH-1:0] row;
wire clk25MHz;

reg[31:0] count     = 32'd0;
parameter D         = 25000000;  

 reg[2:0] direction = 0;

 reg [7:0] food = 8'd0;

 reg [5:0] a [0:64];
 
 reg [1:0] board [0:7][0:7];

 reg [0:7] x, y = 0;
 reg [1:0] spot;

reg [7:0] points = 8'd0;
wire[3:0] onesDigit;
wire[3:0] tensDigit;
 
 reg [5:0] size = 6'd0;
 reg state = 0; // 0 for regular state
// 1 for gameover

wire [7:0] random;

assign onesDigit = points % 10;
assign tensDigit = points / 10;

integer i, j, k;

ip ip1(
.areset(reset),
.inclk0(clk),
.c0(clk25MHz),
.locked()
);  

 vga_timer #(
            .COL_WIDTH(COL_WIDTH),
            .ROW_WIDTH(ROW_WIDTH)
        ) UUT (
            .clk     (clk25MHz),
            .reset_n    (reset_n),
            .h_sync     (VGA_HS),
            .v_sync     (VGA_VS),
            .disp_ena   (disp_ena),
            .col        (col),
            .row        (row)
        );
 
lfsr lfsr1(random, 0, clk, 0);

sevenSegmentDecoder onePlace(onesDigit, ones);
sevenSegmentDecoder tensPlace(tensDigit, tens);
 
initial begin
a[0] = 6'd41;
food <= 0; //TODO: change back to 64
end

always @(posedge clk) begin

if (count >= D-1) begin             //reset to 0 REACHED 1 SECOND
        count <= 32'd0;
 
 if (state == 1) begin
            state = 0;
            a[0] <= 6'd7;
        end
 
for (i = 0; i < size; i = i + 1) begin
a[size - i] <= a[size - i - 1];
end
 
if (switch_one) // up
a[0] <= a[0] - 6'd1;
else if (switch_two) // down
a[0] <= a[0] + 6'd8;
else if (switch_three) // right
a[0] <= a[0] + 6'd1;
else // left
a[0] <= a[0] - 6'd8;


        // GAME LOGIC
        // check if the snake ate itself
        if (state == 0) begin
            for (i = 0; i <= size; i = i + 1) begin
                // if the snakes head "eats" any part of the body gameover
                if (i != 0 && a[0] == a[i])
                    state = 1;
            end
        end

        // if the snakes "eats" the food increase size of snake and points, replace the food
        if (a[0] == food) begin : breakBlockFood
j = 0;
            points = points + 8'd1;
            size = size + 6'd1;
            if (size == 6'd63)
                state = 1;
            food <= random % 64;
        end

        //DRAW ALL COMPONENTS ON THE GAMEBOARD
        //redraw game board (All 0'S if in state 0 otherwise draw 3's)
        for (i = 0; i < 8; i = i + 1) begin : loop
            for (j = 0; j < 8; j = j + 1) begin : loop
                if (state == 0) begin
                    board[i][j] <= 2'd0;
                end else begin
                    board[i][j] <= 2'd3;
                end
            end
        end

        // draw the snake
        if (state == 0) begin
            for (i = 0; i <= size; i = i + 1) begin
                board[a[i] / 8][a[i] % 8] <= 1;
            end
        end

        // draw the food on the board
        if (state == 0)
            board[food / 8][food % 8] <= 2'd2;
 
    end else begin
        count <= count + 32'd1;
    end
//display all the items
if (disp_ena) begin
if (col < 480 && row < 480) begin
x <= col/60;
y <= row/60;
spot <= board[x][y];

if (spot == 2'd1) begin
red <= 4'h0;
blue <= 4'h0;
green <= 4'hf;
end else if (spot == 2'd2) begin
red <= 4'hf;
blue <= 4'h0;
green <= 4'h0;
end else begin
red <= 4'h0;
blue <= 4'h0;
green <= 4'h0;
end

end else begin
red <= 4'hF;
blue <= 4'hF;
green <= 4'hF;
end
   end
end

assign VGA_R = disp_ena ? red   : 4'b0000;
assign VGA_G = disp_ena ? green : 4'b0000;
assign VGA_B = disp_ena ? blue  : 4'b0000;

endmodule
user16145658
  • 695
  • 1
  • 5
  • 10

1 Answers1

-1

The synthesis is taking time because the for-loop unrolling is dependent upon a variable 'size' rather than a constant. I can suggest you use a fixed value SIZE_MAX for the maximum for-loop iteration. Determine SIZE_MAX based on the maximum value that 'size' can go upto. Also I see that the 'size' and 'i' init is such that you will have a[0]<=a[-1] kind of assignment.

parameter SIZE_MAX = 100; //Determine this based on your requirement

 a[0] <= size=='d0 ? 'd0 : a[size - 1];
for (i = 1; i < SIZE_MAX; i = i + 1) begin     
 a[i] <= a[i-1];
end 
Pradyuman Bissa
  • 171
  • 1
  • 9