基于FPGA的俄罗斯方块


vh文件

definitions.vh

// The width of the screen in pixels
`define PIXEL_WIDTH 640
// The height of the screen in pixels
`define PIXEL_HEIGHT 480

// Used for VGA horizontal and vertical sync
`define HSYNC_FRONT_PORCH 16
`define HSYNC_PULSE_WIDTH 96
`define HSYNC_BACK_PORCH 48
`define VSYNC_FRONT_PORCH 10
`define VSYNC_PULSE_WIDTH 2
`define VSYNC_BACK_PORCH 33

// How many pixels wide/high each block is
`define BLOCK_SIZE 20

// How many blocks wide the game board is
`define BLOCKS_WIDE 10

// How many blocks high the game board is
`define BLOCKS_HIGH 22

// Width of the game board in pixels
`define BOARD_WIDTH (`BLOCKS_WIDE * `BLOCK_SIZE)
// Starting x pixel for the game board
`define BOARD_X (((`PIXEL_WIDTH - `BOARD_WIDTH) / 2) - 1)

// Height of the game board in pixels
`define BOARD_HEIGHT (`BLOCKS_HIGH * `BLOCK_SIZE)
// Starting y pixel for the game board
`define BOARD_Y (((`PIXEL_HEIGHT - `BOARD_HEIGHT) / 2) - 1)

// The number of bits used to store a block position
`define BITS_BLK_POS 8
// The number of bits used to store an X position
`define BITS_X_POS 4
// The number of bits used to store a Y position
`define BITS_Y_POS 5
// The number of bits used to store a rotation
`define BITS_ROT 2
// The number of bits used to store how wide / long a block is (max of decimal 4)
`define BITS_BLK_SIZE 3
// The number of bits for the score. The score goes up to 10000
`define BITS_SCORE 14
// The number of bits used to store each block
`define BITS_PER_BLOCK 3

// The type of each block
`define EMPTY_BLOCK 3'b000
`define I_BLOCK 3'b001
`define O_BLOCK 3'b010
`define T_BLOCK 3'b011
`define S_BLOCK 3'b100
`define Z_BLOCK 3'b101
`define J_BLOCK 3'b110
`define L_BLOCK 3'b111

// Color mapping
`define WHITE 8'b11111111
`define BLACK 8'b00000000
`define GRAY 8'b10100100
`define CYAN 8'b11110000
`define YELLOW 8'b00111111
`define PURPLE 8'b11000111
`define GREEN 8'b00111000
`define RED 8'b00000111
`define BLUE 8'b11000000
`define ORANGE 8'b00011111

// Error value
`define ERR_BLK_POS 8'b11111111

// Modes
`define MODE_BITS 3
`define MODE_PLAY 0
`define MODE_DROP 1
`define MODE_PAUSE 2
`define MODE_IDLE 3
`define MODE_SHIFT 4

// The maximum value of the drop timer
`define DROP_TIMER_MAX 10000

calc_cur_blk.v

`include "definitions.vh"

module calc_cur_blk(
    input wire [`BITS_PER_BLOCK-1:0] piece,
    input wire [3:0] pos_x,
    input wire [4:0] pos_y,
    input wire [1:0] rot,
    output reg [7:0] blk_1,
    output reg [7:0] blk_2,
    output reg [7:0] blk_3,
    output reg [7:0] blk_4,
    output reg [2:0] width,
    output reg [2:0] height
    );

    always @ (*) begin
        case (piece)
            `EMPTY_BLOCK: begin
                 blk_1 = `ERR_BLK_POS;
                 blk_2 = `ERR_BLK_POS;
                 blk_3 = `ERR_BLK_POS;
                 blk_4 = `ERR_BLK_POS;
                 width = 0;
                 height = 0;
            end
            `I_BLOCK: begin
                 if (rot == 0 || rot == 2) begin
                     blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x;
                     blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                     blk_3 = ((pos_y + 2) * `BLOCKS_WIDE) + pos_x;
                     blk_4 = ((pos_y + 3) * `BLOCKS_WIDE) + pos_x;
                     width = 1;
                     height = 4;
                 end else begin
                     blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x;
                     blk_2 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                     blk_3 = (pos_y * `BLOCKS_WIDE) + pos_x + 2;
                     blk_4 = (pos_y * `BLOCKS_WIDE) + pos_x + 3;
                     width = 4;
                     height = 1;
                 end
            end
            `O_BLOCK: begin
                blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x;
                blk_2 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                blk_3 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                blk_4 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                width = 2;
                height = 2;
            end
            `T_BLOCK: begin
                case (rot)
                    0: begin
                        blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                        blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                        blk_3 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                        blk_4 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 2;
                        width = 3;
                        height = 2;
                    end
                    1: begin
                        blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x;
                        blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                        blk_3 = ((pos_y + 2) * `BLOCKS_WIDE) + pos_x;
                        blk_4 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                        width = 2;
                        height = 3;
                    end
                    2: begin
                        blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x;
                        blk_2 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                        blk_3 = (pos_y * `BLOCKS_WIDE) + pos_x + 2;
                        blk_4 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                        width = 3;
                        height = 2;
                    end
                    3: begin
                        blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                        blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                        blk_3 = ((pos_y + 2) * `BLOCKS_WIDE) + pos_x + 1;
                        blk_4 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                        width = 2;
                        height = 3;
                    end
                endcase
            end
            `S_BLOCK: begin
                if (rot == 0 || rot == 2) begin
                    blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                    blk_2 = (pos_y * `BLOCKS_WIDE) + pos_x + 2;
                    blk_3 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                    blk_4 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                    width = 3;
                    height = 2;
                end else begin
                    blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x;
                    blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                    blk_3 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                    blk_4 = ((pos_y + 2) * `BLOCKS_WIDE) + pos_x + 1;
                    width = 2;
                    height = 3;
                end
            end
            `Z_BLOCK: begin
                if (rot == 0 || rot == 2) begin
                    blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x;
                    blk_2 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                    blk_3 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                    blk_4 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 2;
                    width = 3;
                    height = 2;
                end else begin
                    blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                    blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                    blk_3 = ((pos_y + 2) * `BLOCKS_WIDE) + pos_x;
                    blk_4 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                    width = 2;
                    height = 3;
                end
            end
            `J_BLOCK: begin
                case (rot)
                    0: begin
                        blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                        blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                        blk_3 = ((pos_y + 2) * `BLOCKS_WIDE) + pos_x + 1;
                        blk_4 = ((pos_y + 2) * `BLOCKS_WIDE) + pos_x;
                        width = 2;
                        height = 3;
                    end
                    1: begin
                        blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x;
                        blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                        blk_3 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                        blk_4 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 2;
                        width = 3;
                        height = 2;
                    end
                    2: begin
                        blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x;
                        blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                        blk_3 = ((pos_y + 2) * `BLOCKS_WIDE) + pos_x;
                        blk_4 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                        width = 2;
                        height = 3;
                    end
                    3: begin
                        blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x;
                        blk_2 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                        blk_3 = (pos_y * `BLOCKS_WIDE) + pos_x + 2;
                        blk_4 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 2;
                        width = 3;
                        height = 2;
                    end
                endcase
            end
            `L_BLOCK: begin
                case (rot)
                    0: begin
                        blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x;
                        blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                        blk_3 = ((pos_y + 2) * `BLOCKS_WIDE) + pos_x;
                        blk_4 = ((pos_y + 2) * `BLOCKS_WIDE) + pos_x + 1;
                        width = 2;
                        height = 3;
                    end
                    1: begin
                        blk_1 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                        blk_2 = (pos_y * `BLOCKS_WIDE) + pos_x;
                        blk_3 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                        blk_4 = (pos_y * `BLOCKS_WIDE) + pos_x + 2;
                        width = 3;
                        height = 2;
                    end
                    2: begin
                        blk_1 = (pos_y * `BLOCKS_WIDE) + pos_x + 1;
                        blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                        blk_3 = ((pos_y + 2) * `BLOCKS_WIDE) + pos_x + 1;
                        blk_4 = (pos_y * `BLOCKS_WIDE) + pos_x;
                        width = 2;
                        height = 3;
                    end
                    3: begin
                        blk_1 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x;
                        blk_2 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 1;
                        blk_3 = ((pos_y + 1) * `BLOCKS_WIDE) + pos_x + 2;
                        blk_4 = (pos_y * `BLOCKS_WIDE) + pos_x + 2;
                        width = 3;
                        height = 2;
                    end
                endcase
            end
        endcase
    end

endmodule

calc_test_pos_rot.v

`include "definitions.vh"

module calc_test_pos_rot(
    input wire [`MODE_BITS-1:0]  mode,
    input wire                   game_clk_rst,
    input wire                   game_clk,
    input wire                   btn_left_en,
    input wire                   btn_right_en,
    input wire                   btn_rotate_en,
    input wire                   btn_down_en,
    input wire                   btn_drop_en,
    input wire [`BITS_X_POS-1:0] cur_pos_x,
    input wire [`BITS_Y_POS-1:0] cur_pos_y,
    input wire [`BITS_ROT-1:0]   cur_rot,
    output reg [`BITS_X_POS-1:0] test_pos_x,
    output reg [`BITS_Y_POS-1:0] test_pos_y,
    output reg [`BITS_ROT-1:0]   test_rot
    );

    always @ (*) begin
        if (mode == `MODE_PLAY) begin
            if (game_clk) begin
                test_pos_x = cur_pos_x;
                test_pos_y = cur_pos_y + 1; // move down
                test_rot = cur_rot;
            end else if (btn_left_en) begin
                test_pos_x = cur_pos_x - 1; // move left
                test_pos_y = cur_pos_y;
                test_rot = cur_rot;
            end else if (btn_right_en) begin
                test_pos_x = cur_pos_x + 1; // move right
                test_pos_y = cur_pos_y;
                test_rot = cur_rot;
            end else if (btn_rotate_en) begin
                test_pos_x = cur_pos_x;
                test_pos_y = cur_pos_y;
                test_rot = cur_rot + 1; // rotate
            end else if (btn_down_en) begin
                test_pos_x = cur_pos_x;
                test_pos_y = cur_pos_y + 1; // move down
                test_rot = cur_rot;
            end else if (btn_drop_en) begin
                // do nothing, we set to drop mode
                test_pos_x = cur_pos_x;
                test_pos_y = cur_pos_y;
                test_rot = cur_rot;
            end else begin
                // do nothing, the block isn't moving this cycle
                test_pos_x = cur_pos_x;
                test_pos_y = cur_pos_y;
                test_rot = cur_rot;
            end
        end else if (mode == `MODE_DROP) begin
            if (game_clk_rst) begin
                // do nothing, we set to play mode
                test_pos_x = cur_pos_x;
                test_pos_y = cur_pos_y;
                test_rot = cur_rot;
            end else begin
                test_pos_x = cur_pos_x;
                test_pos_y = cur_pos_y + 1; // move down
                test_rot = cur_rot;
            end
        end else begin
            // Other mode, do nothing
            test_pos_x = cur_pos_x;
            test_pos_y = cur_pos_y;
            test_rot = cur_rot;
        end
    end

endmodule

complete_row.v

`include "definitions.vh"

module complete_row(
    input wire                                   clk,
    input wire                                   pause,
    input wire [(`BLOCKS_WIDE*`BLOCKS_HIGH)-1:0] fallen_pieces,
    output reg [`BITS_Y_POS-1:0]                 row,
    output wire                                  enabled
    );

    initial begin
        row = 0;
    end

     // Enabled is high when the current row is complete (all 1s)
     assign enabled = &fallen_pieces[row*`BLOCKS_WIDE +: `BLOCKS_WIDE];

     // Increment the row under test when the clock goes high
     always @ (posedge clk) begin
         if (!pause) begin
             if (row == `BLOCKS_HIGH - 1) begin
                 row <= 0;
             end else begin
                 row <= row + 1;
             end
         end
     end

endmodule

debouncer.v

module debouncer(
    input wire  raw,
    input wire  clk,
    output wire enabled,
    output wire disabled
    );

    reg debounced;
    reg debounced_prev;
    reg [15:0] counter;

    initial begin
        debounced = 0;
        debounced_prev = 0;
        counter = 0;
    end

    always @ (posedge clk) begin
        // 200 Hz
        if (counter == 12500) begin
            counter <= 0;
            debounced <= raw;
        end else begin
            counter <= counter + 1;
        end

        // Update previous
        debounced_prev <= debounced;
    end

    assign enabled = debounced && !debounced_prev;
    assign disabled = !debounced && debounced_prev;

endmodule

game_clock.v

module game_clock(
    input wire clk,
    input wire rst,
    input wire pause,
    output reg game_clk
    );

    reg [31:0] counter;
    always @ (posedge clk) begin
        if (!pause) begin
            if (rst) begin
                counter <= 0;
                game_clk <= 0;
            end else begin
                if (counter == 25000000) begin // 1 Hz
                    counter <= 0;
                    game_clk <= 1;
                end else begin
                    counter <= counter + 1;
                    game_clk <= 0;
                end
            end
        end
    end

endmodule

randomizer.v

module randomizer(
    input wire       clk,
    output reg [2:0] random
    );

    initial begin
        random = 1;
    end

    // Cycle through values at 100 MHz and select one
    // at user input, which is effectively random.
    always @ (posedge clk) begin
        if (random == 7) begin
            random <= 1;
        end else begin
            random <= random + 1;
        end
    end

endmodule

seg_display.v

`include "definitions.vh"

module seg_display(
    input wire       clk,
    input wire [3:0] score_1, // 1's place
    input wire [3:0] score_2, // 10's place
    input wire [3:0] score_3, // 100's place
    input wire [3:0] score_4, // 1000's place
    output reg [7:0] seg,
    output reg [3:0] an
    );

    // Divide the clock so we get a seg_clk that goes
    // at a couple hundred Hz for displaying the next digit
    reg [17:0] counter;
    reg seg_clk;
    always @ (posedge clk) begin
        if (counter == 50000) begin
            counter <= 0;
            seg_clk <= 1;
        end else begin
            counter <= counter + 1;
            seg_clk <= 0;
        end
    end

    // Which digit we are currently displaying
    reg [1:0] digit;

    initial begin
        digit = 0;
    end

    always @ (posedge seg_clk) begin
        digit <= digit + 1;
        if (digit == 0) begin
            an <= 4'b0111;
            display_digit(score_4);
        end else if (digit == 1) begin
            an <= 4'b1011;
            display_digit(score_3);
        end else if (digit == 2) begin
            an <= 4'b1101;
            display_digit(score_2);
        end else begin
            an <= 4'b1110;
            display_digit(score_1);
        end
    end

    task display_digit;
        input [3:0] d;
        begin
            case (d)
                0: seg <= 8'b11000000;
                1: seg <= 8'b11111001;
                2: seg <= 8'b10100100;
                3: seg <= 8'b10110000;
                4: seg <= 8'b10011001;
                5: seg <= 8'b10010010;
                6: seg <= 8'b10000010;
                7: seg <= 8'b11111000;
                8: seg <= 8'b10000000;
                default: seg <= 8'b10010000;
            endcase
        end
    endtask

endmodule // seg_display

tetris.v

`include "definitions.vh"

module tetris(
    input wire        clk_too_fast,
    input wire        btn_drop,
    input wire        btn_rotate,
    input wire        btn_left,
    input wire        btn_right,
    input wire        btn_down,
    input wire        sw_pause,
    input wire        sw_rst,
    output wire [7:0] rgb,
    /*
    //////////////////////
    input wire sw_red4,
    input wire sw_green4,
    input wire sw_blue3,
    input wire sw_blue4,
    //////////////////////
    output wire red4,
    output wire green4,
    output wire blue3,
    output wire blue4,
    */
    //////////////////////
    output wire       hsync,
    output wire       vsync,
    output wire [7:0] seg,
    output wire [3:0] an
    );
    //////////////////////
   /* assign red4=sw_red4;
    assign green4=sw_green4;
    assign blue3=sw_blue3;
    assign blue4=sw_blue4;*/
    /////////////////////
    // Divides the clock into 25 MHz
    reg clk_count;
    reg clk;
    initial begin
        clk_count = 0;
        clk = 0;
    end
    always @ (posedge clk_too_fast) begin
        clk_count <= ~clk_count;
        if (clk_count) begin
            clk <= ~clk;
        end
    end

    // Increments once per cycle to a maximum value. If this is
    // not yet at the maximum value, we cannot go into drop mode.
    reg [31:0] drop_timer;
    initial begin
        drop_timer = 0;
    end

    // This signal random_piece rotates between the types
    // of pieces at 100 MHz, and is selected based on user input,
    // making it effectively random.
    wire [`BITS_PER_BLOCK-1:0] random_piece;
    randomizer randomizer_ (
        .clk(clk),
        .random(random_piece)
    );

    // The enable signals for the five buttons, after
    // they have gone through the debouncer. Should only be high
    // for one cycle for each button press.
    wire btn_drop_en;
    wire btn_rotate_en;
    wire btn_left_en;
    wire btn_right_en;
    wire btn_down_en;
    // Debounce all of the input signals
    debouncer debouncer_btn_drop_ (
        .raw(btn_drop),
        .clk(clk),
        .enabled(btn_drop_en)
    );
    debouncer debouncer_btn_rotate_ (
        .raw(btn_rotate),
        .clk(clk),
        .enabled(btn_rotate_en)
    );
    debouncer debouncer_btn_left_ (
        .raw(btn_left),
        .clk(clk),
        .enabled(btn_left_en)
    );
    debouncer debouncer_btn_right_ (
        .raw(btn_right),
        .clk(clk),
        .enabled(btn_right_en)
    );
    debouncer debouncer_btn_down_ (
        .raw(btn_down),
        .clk(clk),
        .enabled(btn_down_en)
    );

    // Sets up wires for the pause and reset switch enable
    // and disable signals, and debounces the asynchronous input.
    wire sw_pause_en;
    wire sw_pause_dis;
    wire sw_rst_en;
    wire sw_rst_dis;
    debouncer debouncer_sw_pause_ (
        .raw(sw_pause),
        .clk(clk),
        .enabled(sw_pause_en),
        .disabled(sw_pause_dis)
    );
    debouncer debouncer_sw_rst_ (
        .raw(sw_rst),
        .clk(clk),
        .enabled(sw_rst_en),
        .disabled(sw_rst_dis)
    );

    // A memory bank for storing 1 bit for each board position.
    // If the fallen_pieces memory is 1, there is a block still that
    // has not been removed from play. This is used to draw the board
    // and to test for intersection with the falling piece.
    reg [(`BLOCKS_WIDE*`BLOCKS_HIGH)-1:0] fallen_pieces;

    // What type of piece the current falling tetromino is. The types
    // are defined in definitions.vh.
    reg [`BITS_PER_BLOCK-1:0] cur_piece;
    // The x position of the falling piece.
    reg [`BITS_X_POS-1:0] cur_pos_x;
    // The y position of the falling piece.
    reg [`BITS_Y_POS-1:0] cur_pos_y;
    // The current rotation of the falling piece (0 == 0 degrees, 1 == 90 degrees, etc)
    reg [`BITS_ROT-1:0] cur_rot;
    // The four flattened locations of the current falling tetromino. Used to
    // test for intersection, or add to fallen_pieces, etc.
    wire [`BITS_BLK_POS-1:0] cur_blk_1;
    wire [`BITS_BLK_POS-1:0] cur_blk_2;
    wire [`BITS_BLK_POS-1:0] cur_blk_3;
    wire [`BITS_BLK_POS-1:0] cur_blk_4;
    // The width and height of the current shape of the tetromino, based on its
    // type and rotation.
    wire [`BITS_BLK_SIZE-1:0] cur_width;
    wire [`BITS_BLK_SIZE-1:0] cur_height;
    // Use a calc_cur_blk module to get the values of the wires above from
    // the current position, type, and rotation of the falling tetromino.
    calc_cur_blk calc_cur_blk_ (
        .piece(cur_piece),
        .pos_x(cur_pos_x),
        .pos_y(cur_pos_y),
        .rot(cur_rot),
        .blk_1(cur_blk_1),
        .blk_2(cur_blk_2),
        .blk_3(cur_blk_3),
        .blk_4(cur_blk_4),
        .width(cur_width),
        .height(cur_height)
    );

    // The VGA controller. We give it the type of tetromino (cur_piece)
    // so that it knows the right color, and the four positions on the
    // board that it covers. We also pass in fallen_pieces so that it can
    // display the fallen tetromino squares in monochrome.
    vga_display display_ (
        .clk(clk),
        .cur_piece(cur_piece),
        .cur_blk_1(cur_blk_1),
        .cur_blk_2(cur_blk_2),
        .cur_blk_3(cur_blk_3),
        .cur_blk_4(cur_blk_4),
        .fallen_pieces(fallen_pieces),
        .rgb(rgb),
        .hsync(hsync),
        .vsync(vsync)
    );

    // The mode, used for finite state machine things. We also
    // need to store the old mode occasionally, like when we're paused.
    reg [`MODE_BITS-1:0] mode;
    reg [`MODE_BITS-1:0] old_mode;
    // The game clock
    wire game_clk;
    // The game clock reset
    reg game_clk_rst;

    // This module outputs the game clock, which is when the clock
    // that determines when the tetromino falls by itself.
    game_clock game_clock_ (
        .clk(clk),
        .rst(game_clk_rst),
        .pause(mode != `MODE_PLAY),
        .game_clk(game_clk)
    );

    // Set up some variables to test for intersection or off-screen-ness
    // of the current piece if the user's current action were to be
    // followed through. For example, if the user presses the left button,
    // we test where the current piece would be if it was moved one to the
    // left, i.e. x = x - 1.
    wire [`BITS_X_POS-1:0] test_pos_x;
    wire [`BITS_Y_POS-1:0] test_pos_y;
    wire [`BITS_ROT-1:0] test_rot;
    // Combinational logic to determine what position/rotation we are testing.
    // This has been hoisted out into a module so that the code is shorter.
    calc_test_pos_rot calc_test_pos_rot_ (
        .mode(mode),
        .game_clk_rst(game_clk_rst),
        .game_clk(game_clk),
        .btn_left_en(btn_left_en),
        .btn_right_en(btn_right_en),
        .btn_rotate_en(btn_rotate_en),
        .btn_down_en(btn_down_en),
        .btn_drop_en(btn_drop_en),
        .cur_pos_x(cur_pos_x),
        .cur_pos_y(cur_pos_y),
        .cur_rot(cur_rot),
        .test_pos_x(test_pos_x),
        .test_pos_y(test_pos_y),
        .test_rot(test_rot)
    );
    // Set up the outputs for the calc_test_blk module
    wire [`BITS_BLK_POS-1:0] test_blk_1;
    wire [`BITS_BLK_POS-1:0] test_blk_2;
    wire [`BITS_BLK_POS-1:0] test_blk_3;
    wire [`BITS_BLK_POS-1:0] test_blk_4;
    wire [`BITS_BLK_SIZE-1:0] test_width;
    wire [`BITS_BLK_SIZE-1:0] test_height;
    calc_cur_blk calc_test_block_ (
        .piece(cur_piece),
        .pos_x(test_pos_x),
        .pos_y(test_pos_y),
        .rot(test_rot),
        .blk_1(test_blk_1),
        .blk_2(test_blk_2),
        .blk_3(test_blk_3),
        .blk_4(test_blk_4),
        .width(test_width),
        .height(test_height)
    );

    // This function checks whether its input block positions intersect
    // with any fallen pieces.
    function intersects_fallen_pieces;
        input wire [7:0] blk1;
        input wire [7:0] blk2;
        input wire [7:0] blk3;
        input wire [7:0] blk4;
        begin
            intersects_fallen_pieces = fallen_pieces[blk1] ||
                                       fallen_pieces[blk2] ||
                                       fallen_pieces[blk3] ||
                                       fallen_pieces[blk4];
        end
    endfunction

    // This signal goes high when the test positions/rotations intersect with
    // fallen blocks.
    wire test_intersects = intersects_fallen_pieces(test_blk_1, test_blk_2, test_blk_3, test_blk_4);

    // If the falling piece can be moved left, moves it left
    task move_left;
        begin
            if (cur_pos_x > 0 && !test_intersects) begin
                cur_pos_x <= cur_pos_x - 1;
            end
        end
    endtask

    // If the falling piece can be moved right, moves it right
    task move_right;
        begin
            if (cur_pos_x + cur_width < `BLOCKS_WIDE && !test_intersects) begin
                cur_pos_x <= cur_pos_x + 1;
            end
        end
    endtask

    // Rotates the current block if it would not cause any part of the
    // block to go off screen and would not intersect with any fallen blocks.
    task rotate;
        begin
            if (cur_pos_x + test_width <= `BLOCKS_WIDE &&
                cur_pos_y + test_height <= `BLOCKS_HIGH &&
                !test_intersects) begin
                cur_rot <= cur_rot + 1;
            end
        end
    endtask

    // Adds the current block to fallen_pieces
    task add_to_fallen_pieces;
        begin
            fallen_pieces[cur_blk_1] <= 1;
            fallen_pieces[cur_blk_2] <= 1;
            fallen_pieces[cur_blk_3] <= 1;
            fallen_pieces[cur_blk_4] <= 1;
        end
    endtask

    // Adds the given blocks to fallen_pieces, and
    // chooses a new block for the user that appears
    // at the top of the screen.
    task get_new_block;
        begin
            // Reset the drop timer, can't drop until this is high enough
            drop_timer <= 0;
            // Choose a new block for the user
            cur_piece <= random_piece;
            cur_pos_x <= (`BLOCKS_WIDE / 2) - 1;
            cur_pos_y <= 0;
            cur_rot <= 0;
            // reset the game timer so the user has a full
            // cycle before the block falls
            game_clk_rst <= 1;
        end
    endtask

    // Moves the current piece down one, getting a new block if
    // the piece would go off the board or intersect with another block.
    task move_down;
        begin
            if (cur_pos_y + cur_height < `BLOCKS_HIGH && !test_intersects) begin
                cur_pos_y <= cur_pos_y + 1;
            end else begin
                add_to_fallen_pieces();
                get_new_block();
            end
        end
    endtask

    // Sets the mode to MODE_DROP, in which the current block will not respond
    // to user input and it will move down at one cycle per second until it hits
    // a block or the bottom of the board.
    task drop_to_bottom;
        begin
            mode <= `MODE_DROP;
        end
    endtask

    // The score register, increased by one when the user
    // completes a row.
    reg [3:0] score_1; // 1's place
    reg [3:0] score_2; // 10's place
    reg [3:0] score_3; // 100's place
    reg [3:0] score_4; // 1000's place
    // The 7-segment display module, which outputs the score
    seg_display score_display_ (
        .clk(clk),
        .score_1(score_1),
        .score_2(score_2),
        .score_3(score_3),
        .score_4(score_4),
        .an(an),
        .seg(seg)
    );
    // The module that determines which row, if any, is complete
    // and needs to be removed and the score incremented
    wire [`BITS_Y_POS-1:0] remove_row_y;
    wire remove_row_en;
    complete_row complete_row_ (
        .clk(clk),
        .pause(mode != `MODE_PLAY),
        .fallen_pieces(fallen_pieces),
        .row(remove_row_y),
        .enabled(remove_row_en)
    );

    // This task removes the completed row from fallen_pieces
    // and increments the score
    reg [`BITS_Y_POS-1:0] shifting_row;
    task remove_row;
        begin
            // Shift away remove_row_y
            mode <= `MODE_SHIFT;
            shifting_row <= remove_row_y;
            // Increment the score
            if (score_1 == 9) begin
                if (score_2 == 9) begin
                    if (score_3 == 9) begin
                        if (score_4 != 9) begin
                            score_4 <= score_4 + 1;
                            score_3 <= 0;
                            score_2 <= 0;
                            score_1 <= 0;
                        end
                    end else begin
                        score_3 <= score_3 + 1;
                        score_2 <= 0;
                        score_1 <= 0;
                    end
                end else begin
                    score_2 <= score_2 + 1;
                    score_1 <= 0;
                end
            end else begin
                score_1 <= score_1 + 1;
            end
        end
    endtask

    // Initialize any registers we need
    initial begin
        mode = `MODE_IDLE;
        fallen_pieces = 0;
        cur_piece = `EMPTY_BLOCK;
        cur_pos_x = 0;
        cur_pos_y = 0;
        cur_rot = 0;
        score_1 = 0;
        score_2 = 0;
        score_3 = 0;
        score_4 = 0;
    end

    // Starts a new game after a button is pressed in the MODE_IDLE state
    task start_game;
        begin
            mode <= `MODE_PLAY;
            fallen_pieces <= 0;
            score_1 <= 0;
            score_2 <= 0;
            score_3 <= 0;
            score_4 <= 0;
            get_new_block();
        end
    endtask

    // Determine if the game is over because the current position
    // intersects with a fallen block
    wire game_over = cur_pos_y == 0 && intersects_fallen_pieces(cur_blk_1, cur_blk_2, cur_blk_3, cur_blk_4);

    // Main game logic
    always @ (posedge clk) begin
        if (drop_timer < `DROP_TIMER_MAX) begin
            drop_timer <= drop_timer + 1;
        end
        game_clk_rst <= 0;
        if (mode == `MODE_IDLE && (sw_rst_en || sw_rst_dis)) begin
            // We are in idle mode and the user has requested to start the game
            start_game();
        end else if (sw_rst_en || sw_rst_dis || game_over) begin
            // We hit the reset switch or the game ended by itself,
            // go into idle mode where we wait for the user to press a button
            mode <= `MODE_IDLE;
            add_to_fallen_pieces();
            cur_piece <= `EMPTY_BLOCK;
        end else if ((sw_pause_en || sw_pause_dis) && mode == `MODE_PLAY) begin
            // If we switch on pause, save the old mode and enter
            // the pause mode.
            mode <= `MODE_PAUSE;
            old_mode <= mode;
        end else if ((sw_pause_en || sw_pause_dis) && mode == `MODE_PAUSE) begin
            // If we switch off pause, enter the old mode
            mode <= old_mode;
        end else if (mode == `MODE_PLAY) begin
            // Normal gameplay
            if (game_clk) begin
                move_down();
            end else if (btn_left_en) begin
                move_left();
            end else if (btn_right_en) begin
                move_right();
            end else if (btn_rotate_en) begin
                rotate();
            end else if (btn_down_en) begin
                move_down();
            end else if (btn_drop_en && drop_timer == `DROP_TIMER_MAX) begin
                drop_to_bottom();
            end else if (remove_row_en) begin
                remove_row();
            end
        end else if (mode == `MODE_DROP) begin
            // We are dropping the block until we hit respawn
            // at the top
            if (game_clk_rst && !sw_pause_en) begin
                mode <= `MODE_PLAY;
            end else begin
                move_down();
            end
        end else if (mode == `MODE_SHIFT) begin
            // We are shifting the row above shifting_row
            // into shifting_row's position
            if (shifting_row == 0) begin
                fallen_pieces[0 +: `BLOCKS_WIDE] <= 0;
                mode <= `MODE_PLAY;
            end else begin
                fallen_pieces[shifting_row*`BLOCKS_WIDE +: `BLOCKS_WIDE] <= fallen_pieces[(shifting_row - 1)*`BLOCKS_WIDE +: `BLOCKS_WIDE];
                shifting_row <= shifting_row - 1;
            end
        end
    end

endmodule

vga_display.v

`include "definitions.vh"

module vga_display(
    input wire                                   clk,
    input wire [`BITS_PER_BLOCK-1:0]             cur_piece,
    input wire [`BITS_BLK_POS-1:0]               cur_blk_1,
    input wire [`BITS_BLK_POS-1:0]               cur_blk_2,
    input wire [`BITS_BLK_POS-1:0]               cur_blk_3,
    input wire [`BITS_BLK_POS-1:0]               cur_blk_4,
    input wire [(`BLOCKS_WIDE*`BLOCKS_HIGH)-1:0] fallen_pieces,
    output reg [7:0]                             rgb,
    output wire                                  hsync,
    output wire                                  vsync
    );

    reg [9:0] counter_x = 0;
    reg [9:0] counter_y = 0;

    assign hsync = ~(counter_x >= (`PIXEL_WIDTH + `HSYNC_FRONT_PORCH) &&
                     counter_x < (`PIXEL_WIDTH + `HSYNC_FRONT_PORCH + `HSYNC_PULSE_WIDTH));
    assign vsync = ~(counter_y >= (`PIXEL_HEIGHT + `VSYNC_FRONT_PORCH) &&
                     counter_y < (`PIXEL_HEIGHT + `VSYNC_FRONT_PORCH + `VSYNC_PULSE_WIDTH));

    // Combinational logic to select the current pixel
    wire [9:0] cur_blk_index = ((counter_x-`BOARD_X)/`BLOCK_SIZE) + (((counter_y-`BOARD_Y)/`BLOCK_SIZE)*`BLOCKS_WIDE);
    reg [2:0] cur_vid_mem;
    always @ (*) begin
        // Check if we're within the drawing space
        if (counter_x >= `BOARD_X && counter_y >= `BOARD_Y &&
            counter_x <= `BOARD_X + `BOARD_WIDTH && counter_y <= `BOARD_Y + `BOARD_HEIGHT) begin
            if (counter_x == `BOARD_X || counter_x == `BOARD_X + `BOARD_WIDTH ||
                counter_y == `BOARD_Y || counter_y == `BOARD_Y + `BOARD_HEIGHT) begin
                // We're at the edge of the board, paint it white
                rgb = `WHITE;
            end else begin
                if (cur_blk_index == cur_blk_1 ||
                    cur_blk_index == cur_blk_2 ||
                    cur_blk_index == cur_blk_3 ||
                    cur_blk_index == cur_blk_4) begin
                    case (cur_piece)
                        `EMPTY_BLOCK: rgb = `GRAY;
                        `I_BLOCK: rgb = `CYAN;
                        `O_BLOCK: rgb = `YELLOW;
                        `T_BLOCK: rgb = `PURPLE;
                        `S_BLOCK: rgb = `GREEN;
                        `Z_BLOCK: rgb = `RED;
                        `J_BLOCK: rgb = `BLUE;
                        `L_BLOCK: rgb = `ORANGE;
                    endcase
                end else begin
                    rgb = fallen_pieces[cur_blk_index] ? `WHITE : `GRAY;
                end
            end
        end else begin
            // Outside the board
            rgb = `BLACK;
        end
    end

   always @ (posedge clk) begin
       if (counter_x >= `PIXEL_WIDTH + `HSYNC_FRONT_PORCH + `HSYNC_PULSE_WIDTH + `HSYNC_BACK_PORCH) begin
           counter_x <= 0;
           if (counter_y >= `PIXEL_HEIGHT + `VSYNC_FRONT_PORCH + `VSYNC_PULSE_WIDTH + `VSYNC_BACK_PORCH) begin
               counter_y <= 0;
           end else begin
               counter_y <= counter_y + 1;
           end
       end else begin
           counter_x <= counter_x + 1;
       end
   end

endmodule

为了能够用键盘进行游戏,需要编写按键的控制代码,这里为了简单,用了ps2键盘实现

ps2scan.v

`timescale 1ns / 1ps
module ps2scan (
    input wire clk, 
    input wire rst_n, 
    input wire ps2_sclk, 
    input wire ps2_sda, 
    output reg [7:0] out_data
    );  

    //端口信号:模块的输入输出接口
    //input clk;//系统时钟
    //input rst_n;//低电平复位
    //input    ps2_sclk;//ps2时钟信号(ps2设备自动产生,大约10KHz左右)
    //input ps2_sda;//ps2数据信号
    //output reg [7:0] out_data; //键值数据(采集ps2的一帧信号中间的8位有效位)

    //在发送时序中,数据在ps2_sclk的下降沿采集信号,以下为检测下降沿
    reg  in1,in2;    
    wire en;    

    always @ (posedge clk or negedge rst_n)
    begin
        if(!rst_n) 
            begin
                in1 <= 1'b0;
                in2 <= 1'b0;
            end
        else 
            begin                                
                in1 <= ps2_sclk;
                in2 <= in1;
            end
    end

    assign en = (~in1) & in2;    //当出现ps2_sclk下降沿后拉高一个时钟,以进行数据的采集


    //采集ps2的一帧信号中间的8位有效位:每检测一个下降沿算一位数据位,在中间8位采集有效数据
    reg[7:0] temp_data;            
    reg[3:0] num;    

    always @ (posedge clk or negedge rst_n)
    begin
        if(!rst_n) 
            begin
                num <= 4'd0;
                temp_data <= 8'd0;
            end
        else if(en) 
            case (num)
                4'd0:    num <= num+1'b1;    //开始位
                4'd1:    begin
                            num <= num+1'b1;
                            temp_data[0] <= ps2_sda;    //bit0
                        end
                4'd2:    begin
                            num <= num+1'b1;
                            temp_data[1] <= ps2_sda;    //bit1
                        end
                4'd3:    begin
                            num <= num+1'b1;
                            temp_data[2] <= ps2_sda;    //bit2
                        end
                4'd4:    begin
                            num <= num+1'b1;
                            temp_data[3] <= ps2_sda;    //bit3
                        end
                4'd5:    begin
                            num <= num+1'b1;
                            temp_data[4] <= ps2_sda;    //bit4
                        end
                4'd6:    begin
                            num <= num+1'b1;
                            temp_data[5] <= ps2_sda;    //bit5
                        end
                4'd7:    begin
                            num <= num+1'b1;
                            temp_data[6] <= ps2_sda;    //bit6
                        end
                4'd8:    begin
                            num <= num+1'b1;
                            temp_data[7] <= ps2_sda;    //bit7
                        end
                4'd9:    num <= num+1'b1;    //结束位
                4'd10:  num <= 4'd0;    
                default: num<=4'd0;
            endcase    
    end

    //判断是否有键按下:根据通码、断码的特性判断
    reg key;    

    always @ (posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            key <= 1'b0;
        else if(num==4'd10)
            begin    
                if(temp_data == 8'hf0) 
                        key <= 1'b1;
                else 
                    begin
                        if(!key) 
                            out_data <= temp_data;  
                        else 
                            key <= 1'b0;
                    end
            end
    end 

endmodule 

ps2_top.v

`timescale 1ns / 1ps
module ps2_top (
    input wire clk, 
    input wire rst_n, 
    input wire ps2_sclk, 
    input wire ps2_sda,
    output wire btn_drop,
    output wire btn_rotate,
    output wire btn_left,
    output wire btn_right,
    output wire btn_down
    );

    //外部接口
    //input clk;      //系统时钟50MHz
    //input rst_n;    //低电平复位
    //input ps2_sclk; //ps2时钟
    //input ps2_sda;  //ps2数据
    //output [2:0] sel;    //数码管位选
    //output [7:0] seg;     //数码管段选

    wire[7:0] out_data, tx_out;    

    /*****键盘扫描模块*****/
    ps2scan    ps2scan_inst(    
        .clk(clk),                 
        .rst_n(rst_n),                
        .ps2_sclk(ps2_sclk),
        .ps2_sda(ps2_sda),
        .out_data(out_data)
    );

    ASCII  ASCII_inst(       
        .out_data(out_data),
        .tx_out(tx_out),
        .btn_drop_wire(btn_drop),
        .btn_rotate_wire(btn_rotate),
        .btn_left_wire(btn_left),
        .btn_right_wire(btn_right),
        .btn_down_wire(btn_down)
        );
/*    
    seg_num  seg_num_inst( 
        .num(tx_out),
        .clk(clk),
        .rst_n(rst_n),
        .sel(sel),
        .seg(seg) 
    );    
*/    
endmodule 

ASCII.v

`timescale 1ns / 1ps
module ASCII( 
    input wire [7:0] out_data, 
    output reg [7:0] tx_out,
    output wire      btn_drop_wire,
    output wire      btn_rotate_wire,
    output wire      btn_left_wire,
    output wire      btn_right_wire,
    output wire      btn_down_wire
    );

    //?????????????é??????????????
    //input [7:0] out_data;   //?ü?????¨?è?ü??
    //output reg [7:0] tx_out;//?¨??ASCII??×??????ó????

    //?¨???é??±í??·?????????ASCII?????ü??×???????????????
    always@(*) 
        case (out_data)        
            8'h1c: tx_out <= 8'h41;    //A
            8'h32: tx_out <= 8'h42;    //B
            8'h21: tx_out <= 8'h43;    //C
            8'h23: tx_out <= 8'h44;    //D
            8'h24: tx_out <= 8'h45;    //E
            8'h2b: tx_out <= 8'h46;    //F
            8'h34: tx_out <= 8'h47;    //G
            8'h33: tx_out <= 8'h48;    //H
            8'h43: tx_out <= 8'h49;    //I
            8'h3b: tx_out <= 8'h4a;    //J
            8'h42: tx_out <= 8'h4b;    //K
            8'h4b: tx_out <= 8'h4c;    //L
            8'h3a: tx_out <= 8'h4d;    //M
            8'h31: tx_out <= 8'h4e;    //N    
            8'h44: tx_out <= 8'h4f;    //O
            8'h4d: tx_out <= 8'h50;    //P
            8'h15: tx_out <= 8'h51;    //Q
            8'h2d: tx_out <= 8'h52;    //R
            8'h1b: tx_out <= 8'h53;    //S
            8'h2c: tx_out <= 8'h54;    //T
            8'h3c: tx_out <= 8'h55;    //U
            8'h2a: tx_out <= 8'h56;    //V
            8'h1d: tx_out <= 8'h57;    //W
            8'h22: tx_out <= 8'h58;    //X
            8'h35: tx_out <= 8'h59;    //Y
            8'h1a: tx_out <= 8'h5a;    //Z
            default: tx_out <= 8'h00;
        endcase


    reg      btn_drop;
    reg      btn_rotate;
    reg      btn_left;
    reg      btn_right;
    reg      btn_down;
    assign btn_drop_wire = btn_drop;
    assign btn_rotate_wire =  btn_rotate;
    assign btn_left_wire =  btn_left;
    assign btn_right_wire =  btn_right;
    assign btn_down_wire =  btn_down;

    always @(*)
    begin
    if(out_data==8'h1d)     
    begin
    btn_drop = 1'b0;
    btn_rotate = 1'b1;
    btn_left = 1'b0;
    btn_right = 1'b0;
    btn_down = 1'b0;
    end
    else if(out_data==8'h1c) 
    begin
    btn_drop = 1'b0;
    btn_rotate = 1'b0;
    btn_left = 1'b1;
    btn_right = 1'b0;
    btn_down = 1'b0;
    end
    else if(out_data==8'h1b)
    begin
    btn_drop = 1'b0;
    btn_rotate = 1'b0;
    btn_left = 1'b0;
    btn_right = 1'b0;
    btn_down = 1'b1;
    end
    else if(out_data==8'h23)
    begin
    btn_drop = 1'b0;
    btn_rotate = 1'b0;
    btn_left = 1'b0;
    btn_right = 1'b1;
    btn_down = 1'b0;
    end
    else if(out_data==8'h2b)
    begin
    btn_drop = 1'b1;
    btn_rotate = 1'b0;
    btn_left = 1'b0;
    btn_right = 1'b0;
    btn_down = 1'b0;
    end
    end
endmodule 

seg_num.v

`timescale 1ns / 1ps
module seg_num (
    input wire clk, 
    input wire rst_n, 
    input wire [7:0] num, 
    output reg [3:0] sel, 
    output reg [7:0] seg
    );  

reg [16:0]number=17'd0;   
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
    number<=17'd0;
else
    begin
    if(number<40000)
    number<=number+1'b1;
    else 
    number<=0;
    end
end

always@(posedge clk)
begin
    if(number>20000)
    begin
    sel=4'b1101;
    case(num[7:4])
                4'd0:seg[7:0]<=8'b1100_0000;
                4'd1:seg[7:0]<=8'b1111_1001;
                4'd2:seg[7:0]<=8'b1010_0100;
                4'd3:seg[7:0]<=8'b1011_0000;
                4'd4:seg[7:0]<=8'b1001_1001;
                4'd5:seg[7:0]<=8'b1001_0010;
                4'd6:seg[7:0]<=8'b1000_0010;
                4'd7:seg[7:0]<=8'b1111_1000;
                4'd8:seg[7:0]<=8'b1000_0000;
                4'd9:seg[7:0]<=8'b1001_0000;
                4'd10:seg[7:0]<=8'b1000_1000;
                4'd11:seg[7:0]<=8'b1000_0011;
                4'd12:seg[7:0]<=8'b1010_0111;
                4'd13:seg[7:0]<=8'b1010_0001;
                4'd14:seg[7:0]<=8'b1000_0110;
                4'd15:seg[7:0]<=8'b1000_1110;
                default:seg[7:0]<=8'b1111_0111;
               endcase
            end

    else
    begin
    sel=4'b1110;
    case(num[3:0])
        4'd0:seg[7:0]<=8'b1100_0000;
        4'd1:seg[7:0]<=8'b1111_1001;
        4'd2:seg[7:0]<=8'b1010_0100;
        4'd3:seg[7:0]<=8'b1011_0000;
        4'd4:seg[7:0]<=8'b1001_1001;
        4'd5:seg[7:0]<=8'b1001_0010;
        4'd6:seg[7:0]<=8'b1000_0010;
        4'd7:seg[7:0]<=8'b1111_1000;
        4'd8:seg[7:0]<=8'b1000_0000;
        4'd9:seg[7:0]<=8'b1001_0000;
        4'd10:seg[7:0]<=8'b1000_1000;
        4'd11:seg[7:0]<=8'b1000_0011;
        4'd12:seg[7:0]<=8'b1010_0111;
        4'd13:seg[7:0]<=8'b1010_0001;
        4'd14:seg[7:0]<=8'b1000_0110;
        4'd15:seg[7:0]<=8'b1000_1110;
        default:seg[7:0]<=8'b1111_0111;
       endcase
       end
end
endmodule

文章作者: Roc-May
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Roc-May !
  目录