Verilog 脉冲按键输入电话号码模块

能准确地反映按键数字(按键S1-S8代表数字1-8)
显示器显示从低位向高位前移,逐位显示按键数字,最低位为当前输入位(最低为是数码管8)

引用chatGPT作答,以下是一个实现按键输入电话号码模块的 Verilog 代码示例:

module keypad_input(
    input clk,         // 时钟信号
    input rst_n,       // 复位信号(低电平有效)
    input [7:0] key,   // 按键信号,S1-S8 分别对应 key[0]-key[7]
    output reg [7:0] num_display  // 数码管显示信号,最低位为当前输入位(最低为是数码管8)
);

// 内部变量定义
reg [7:0] phone_num;    // 电话号码,从低位向高位存储
reg [2:0] digit_index;  // 当前输入的数字位

// 时钟边沿检测,更新数码管显示信号
always @(posedge clk) begin
    if (~rst_n) begin  // 复位信号生效
        phone_num <= 8'h00;
        digit_index <= 3'h0;
        num_display <= 8'h00;
    end else begin
        case (digit_index)
            3'h0: num_display <= {1'b0, key[0]};  // 显示最低位(数码管8)
            3'h1: num_display <= {1'b0, phone_num[0]};  // 显示第 2 位(数码管7)
            3'h2: num_display <= {1'b0, phone_num[1]};  // 显示第 3 位(数码管6)
            3'h3: num_display <= {1'b0, phone_num[2]};  // 显示第 4 位(数码管5)
        endcase
    end
end

// 按键输入检测,更新电话号码和数字位索引
always @(key) begin
    if (key[0]) begin  // 按键 S1 按下
        if (digit_index < 3'h3) begin
            phone_num[digit_index] <= 1'b1;
            digit_index <= digit_index + 1;
        end
    end else if (key[1]) begin  // 按键 S2 按下
        if (digit_index < 3'h3) begin
            phone_num[digit_index] <= 2'b01;
            digit_index <= digit_index + 1;
        end
    end else if (key[2]) begin  // 按键 S3 按下
        if (digit_index < 3'h3) begin
            phone_num[digit_index] <= 3'b011;
            digit_index <= digit_index + 1;
        end
    end else if (key[3]) begin  // 按键 S4 按下
        if (digit_index < 3'h3) begin
            phone_num[digit_index] <= 4'b0011;
            digit_index <= digit_index + 1;
        end
    end else if (key[4]) begin  // 按键 S5 按下
        if (digit_index < 3'h3) begin
            phone_num[digit_index] <= 5'b00011;
            digit_index <= digit_index + 1;
        end
    end else if (key[5]) begin  // 按键
if (digit_index < 3'h3) begin
        phone_num[digit_index] <= 6'b000011;
        digit_index <= digit_index + 1;
    end
end else if (key[6]) begin  // 按键 S7 按下
    if (digit_index < 3'h3) begin
        phone_num[digit_index] <= 7'b0000011;
        digit_index <= digit_index + 1;
    end
end else if (key[7]) begin  // 按键 S8 按下
    if (digit_index < 3'h3) begin
        phone_num[digit_index] <= 8'b00000011;
        digit_index <= digit_index + 1;
    end
end
end

endmodule

该模块包含一个时钟边沿检测的 always 块和一个按键输入检测的 always 块,分别用于更新数码管显示信号和电话号码。

时钟边沿检测的 always 块在每个时钟上升沿触发,根据数字位索引(digit_index)选择电话号码的相应位(phone_num),并将其传递给数码管显示信号(num_display)。特别地,在最低位(digit_index=0)时,直接将当前按键(key[0])传递给数码管显示信号的最低位(num_display[0])。

按键输入检测的 always 块在任何按键信号(key)发生变化时触发,根据按键的状态和数字位索引更新电话号码。如果按键 S1-S8 按下,则分别在电话号码的当前数字位(digit_index)写入相应的数字,并将数字位索引加 1。数字位索引的范围为 0 到 3,超过这个范围后将不再更新电话号码。