【问题标题】:Compilation of verilog code in quartus prime takes much longer after adding block添加块后,在 quartus prime 中编译 verilog 代码需要更长的时间
【发布时间】:2022-01-16 14:28:43
【问题描述】:

我正在尝试使用我的 DEE-10 Lite 在 verilog 中制作蛇游戏,并使用 Quartus Prime(Lite Edition 版本 20.1.1)进行编译。

添加以下 for 循环后,分析和综合时间几乎增加了 10 倍:

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

reg [5:0] 大小 = 6'd0; 注册 [5:0] 一个 [0:64];

我确定问题出在我的行为上而不是数据路径/寄存器上。我希望有一个解决方案。我也包含了其余的代码。我也在使用 vga 来显示板子。我确定编译问题是由于 for 语句造成的,因为我尝试过编译时包含和不包含它。

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

【问题讨论】:

  • 你为什么用 VHDL 标签来标记你的 Verilog 问题?
  • VHDL 标签应该被移除,这不是 VHDL 问题

标签: verilog fpga quartus intel-fpga


【解决方案1】:

合成需要时间,因为 for 循环展开取决于变量“大小”而不是常数。我可以建议您使用固定值 SIZE_MAX 进行最大 for 循环迭代。根据“大小”可以达到的最大值确定 SIZE_MAX。 我还看到'size' 和'i' init 是这样的,你将有a[0]&lt;=a[-1] 类型的分配。

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 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多