FPGA 貪吃蛇設計
作成日: 2024年12月24日
作成日: 2024年12月24日
FPGA
EP3C10E144C8
幫我用quartus2設計貪吃蛇遊戲,得分用7段顯示器表示用com控制讓兩個7段顯示器都會亮(0是亮1是暗),8x8led面板為地圖(0是亮1是暗),不用註解
verilog// Top Module module snake_game( input CLOCK_50, output [6:0] HEX0, output [6:0] HEX1, output [7:0] LED_ROW, output [7:0] LED_COL, output [1:0] COM ); wire clk; wire [13:0] div_clk; wire [6:0] seg0, seg1; wire [7:0] row, col; wire [1:0] com_sel; wire reset; assign reset = 1'b0; clk_divider cd(CLOCK_50, clk); display_driver dd(clk, seg0, seg1, HEX0, HEX1, com_sel, COM); led_matrix lm(clk, row, col, LED_ROW, LED_COL); game_logic gl(clk, reset, seg0, seg1, row, col); endmodule // Clock Divider module clk_divider( input clk_in, output reg clk_out ); reg [24:0] counter; always @(posedge clk_in) begin counter <= counter + 1; if(counter == 25000000) begin counter <= 0; clk_out <= ~clk_out; end end endmodule // 7-Segment Display Driver module display_driver( input clk, input [6:0] seg0, input [6:0] seg1, output reg [6:0] HEX0, output reg [6:0] HEX1, output reg [1:0] com, output [1:0] COM ); always @(posedge clk) begin case(com) 2'b00: begin HEX0 <= seg0; HEX1 <= 7'b1111111; end 2'b01: begin HEX0 <= 7'b1111111; HEX1 <= seg1; end default: begin HEX0 <= 7'b1111111; HEX1 <= 7'b1111111; end endcase com <= com + 1; end assign COM = ~com; endmodule // LED Matrix Driver module led_matrix( input clk, input [7:0] row_data, input [7:0] col_data, output reg [7:0] LED_ROW, output reg [7:0] LED_COL ); reg [2:0] current_row; always @(posedge clk) begin current_row <= current_row + 1; LED_ROW <= ~(1 << current_row); LED_COL <= ~(col_data); end endmodule // Game Logic module game_logic( input clk, input reset, output reg [6:0] seg0, output reg [6:0] seg1, output reg [7:0] row, output reg [7:0] col ); reg [3:0] score; always @(posedge clk or posedge reset) begin if(reset) begin score <= 0; row <= 8'b11111111; col <= 8'b11111111; end else begin // Simple score increment score <= score + 1; // Simple pattern for LED row <= ~(8'b00011000); col <= ~(8'b00100100); end end always @(*) begin case(score[3:0]) 4'd0: seg0 = 7'b1000000; 4'd1: seg0 = 7'b1111001; 4'd2: seg0 = 7'b0100100; 4'd3: seg0 = 7'b0110000; 4'd4: seg0 = 7'b0011001; 4'd5: seg0 = 7'b0010010; 4'd6: seg0 = 7'b0000010; 4'd7: seg0 = 7'b1111000; 4'd8: seg0 = 7'b0000000; 4'd9: seg0 = 7'b0010000; default: seg0 = 7'b1111111; endcase case(score[7:4]) 4'd0: seg1 = 7'b1000000; 4'd1: seg1 = 7'b1111001; 4'd2: seg1 = 7'b0100100; 4'd3: seg1 = 7'b0110000; 4'd4: seg1 = 7'b0011001; 4'd5: seg1 = 7'b0010010; 4'd6: seg1 = 7'b0000010; 4'd7: seg1 = 7'b1111000; 4'd8: seg1 = 7'b0000000; 4'd9: seg1 = 7'b0010000; default: seg1 = 7'b1111111; endcase end endmodule
top module名子是snakeGameV3
verilogmodule snakeGameV3( input CLOCK_50, output [6:0] HEX0, output [6:0] HEX1, output [7:0] LED_ROW, output [7:0] LED_COL, output [1:0] COM ); wire clk; wire [6:0] seg0, seg1; wire [7:0] row, col; wire [1:0] com_sel; wire reset; assign reset = 1'b0; clk_divider cd(CLOCK_50, clk); display_driver dd(clk, seg0, seg1, HEX0, HEX1, com_sel, COM); led_matrix lm(clk, row, col, LED_ROW, LED_COL); game_logic gl(clk, reset, seg0, seg1, row, col); endmodule module clk_divider( input clk_in, output reg clk_out ); reg [24:0] counter; always @(posedge clk_in) begin counter <= counter + 1; if(counter == 25000000) begin counter <= 0; clk_out <= ~clk_out; end end endmodule module display_driver( input clk, input [6:0] seg0, input [6:0] seg1, output reg [6:0] HEX0, output reg [6:0] HEX1, output reg [1:0] com, output [1:0] COM ); always @(posedge clk) begin case(com) 2'b00: begin HEX0 <= seg0; HEX1 <= 7'b1111111; end 2'b01: begin HEX0 <= 7'b1111111; HEX1 <= seg1; end default: begin HEX0 <= 7'b1111111; HEX1 <= 7'b1111111; end endcase com <= com + 1; end assign COM = ~com; endmodule module led_matrix( input clk, input [7:0] row_data, input [7:0] col_data, output reg [7:0] LED_ROW, output reg [7:0] LED_COL ); reg [2:0] current_row; always @(posedge clk) begin current_row <= current_row + 1; LED_ROW <= ~(1 << current_row); LED_COL <= ~(col_data); end endmodule module game_logic( input clk, input reset, output reg [6:0] seg0, output reg [6:0] seg1, output reg [7:0] row, output reg [7:0] col ); reg [3:0] score; always @(posedge clk or posedge reset) begin if(reset) begin score <= 0; row <= 8'b11111111; col <= 8'b11111111; end else begin score <= score + 1; row <= ~(8'b00011000); col <= ~(8'b00100100); end end always @(*) begin case(score[3:0]) 4'd0: seg0 = 7'b1000000; 4'd1: seg0 = 7'b1111001; 4'd2: seg0 = 7'b0100100; 4'd3: seg0 = 7'b0110000; 4'd4: seg0 = 7'b0011001; 4'd5: seg0 = 7'b0010010; 4'd6: seg0 = 7'b0000010; 4'd7: seg0 = 7'b1111000; 4'd8: seg0 = 7'b0000000; 4'd9: seg0 = 7'b0010000; default: seg0 = 7'b1111111; endcase case(score[7:4]) 4'd0: seg1 = 7'b1000000; 4'd1: seg1 = 7'b1111001; 4'd2: seg1 = 7'b0100100; 4'd3: seg1 = 7'b0110000; 4'd4: seg1 = 7'b0011001; 4'd5: seg1 = 7'b0010010; 4'd6: seg1 = 7'b0000010; 4'd7: seg1 = 7'b1111000; 4'd8: seg1 = 7'b0000000; 4'd9: seg1 = 7'b0010000; default: seg1 = 7'b1111111; endcase end endmodule
Error (10232): Verilog HDL error at snakeGameV3.v(113): index 7 cannot fall outside the declared range [3:0] for vector "score"
Error (10232): Verilog HDL error at snakeGameV3.v(113): index 4 cannot fall outside the declared range [3:0] for vector "score"
Error (12152): Can't elaborate user hierarchy "game_logic:gl"
Info (144001): Generated suppressed messages file C:/LogicDesign/snakeGameV3/output_files/snakeGameV3.map.smsg
Error: Quartus II 64-Bit Analysis & Synthesis was unsuccessful. 3 errors, 6 warnings
Error: Peak virtual memory: 4604 megabytes
Error: Processing ended: Tue Dec 24 16:32:21 2024
Error: Elapsed time: 00:00:01
Error: Total CPU time (on all processors): 00:00:00
Error (293001): Quartus II Full Compilation was unsuccessful. 5 errors, 6 warnings
下面的程式將 score
宣告成 8 bit,這樣就可以順利使用 score[3:0]
與 score[7:4]
來分別對應到個位數與十位數。請直接使用此程式碼 (無註解),即可解決先前的 index-out-of-range 錯誤。
verilogmodule snakeGameV3( input CLOCK_50, output [6:0] HEX0, output [6:0] HEX1, output [7:0] LED_ROW, output [7:0] LED_COL, output [1:0] COM ); wire clk; wire [6:0] seg0, seg1; wire [7:0] row, col; wire [1:0] com_sel; wire reset; assign reset = 1'b0; clk_divider cd(CLOCK_50, clk); display_driver dd(clk, seg0, seg1, HEX0, HEX1, com_sel, COM); led_matrix lm(clk, row, col, LED_ROW, LED_COL); game_logic gl(clk, reset, seg0, seg1, row, col); endmodule module clk_divider( input clk_in, output reg clk_out ); reg [24:0] counter; always @(posedge clk_in) begin counter <= counter + 1; if(counter == 25000000) begin counter <= 0; clk_out <= ~clk_out; end end endmodule module display_driver( input clk, input [6:0] seg0, input [6:0] seg1, output reg [6:0] HEX0, output reg [6:0] HEX1, output reg [1:0] com, output [1:0] COM ); always @(posedge clk) begin case(com) 2'b00: begin HEX0 <= seg0; HEX1 <= 7'b1111111; end 2'b01: begin HEX0 <= 7'b1111111; HEX1 <= seg1; end default: begin HEX0 <= 7'b1111111; HEX1 <= 7'b1111111; end endcase com <= com + 1; end assign COM = ~com; endmodule module led_matrix( input clk, input [7:0] row_data, input [7:0] col_data, output reg [7:0] LED_ROW, output reg [7:0] LED_COL ); reg [2:0] current_row; always @(posedge clk) begin current_row <= current_row + 1; LED_ROW <= ~(1 << current_row); LED_COL <= ~(col_data); end endmodule module game_logic( input clk, input reset, output reg [6:0] seg0, output reg [6:0] seg1, output reg [7:0] row, output reg [7:0] col ); reg [7:0] score; always @(posedge clk or posedge reset) begin if(reset) begin score <= 8'd0; row <= 8'b11111111; col <= 8'b11111111; end else begin score <= score + 1; row <= ~(8'b00011000); col <= ~(8'b00100100); end end always @(*) begin case(score[3:0]) 4'd0: seg0 = 7'b1000000; 4'd1: seg0 = 7'b1111001; 4'd2: seg0 = 7'b0100100; 4'd3: seg0 = 7'b0110000; 4'd4: seg0 = 7'b0011001; 4'd5: seg0 = 7'b0010010; 4'd6: seg0 = 7'b0000010; 4'd7: seg0 = 7'b1111000; 4'd8: seg0 = 7'b0000000; 4'd9: seg0 = 7'b0010000; default: seg0 = 7'b1111111; endcase case(score[7:4]) 4'd0: seg1 = 7'b1000000; 4'd1: seg1 = 7'b1111001; 4'd2: seg1 = 7'b0100100; 4'd3: seg1 = 7'b0110000; 4'd4: seg1 = 7'b0011001; 4'd5: seg1 = 7'b0010010; 4'd6: seg1 = 7'b0000010; 4'd7: seg1 = 7'b1111000; 4'd8: seg1 = 7'b0000000; 4'd9: seg1 = 7'b0010000; default: seg1 = 7'b1111111; endcase end endmodule
只要把原本的 score
從 4 bit 改成 8 bit(如上所示 reg [7:0] score;
),並且依照 score[3:0]
對應個位數、score[7:4]
對應十位數即可解決問題。