key_board

module    smg(
        clk,rst_n,col,row,smg1,smg2
);
input                        clk;
input                        rst_n;
input                [3:0]    row;
output        reg        [3:0]    col;
output        reg        [7:0]    smg1;
output        reg        [7:0]    smg2;

//div clk
reg                    clk_1k;
reg            [20:0]    cnt;

always @(posedge clk or negedge rst_n)
    if(!rst_n)begin
        clk_1k <= 1;
        cnt    <= 0;
    end
    else if(cnt < 24999)
        cnt <= cnt + 1'b1;
    else begin
        cnt <= 0;
        clk_1k <= ~clk_1k;
    end

    
//fsm
reg            [4:0]    cnt_time;
reg            [7:0]    row_col;
reg            [2:0]    state;
reg                    flag;//输出值有效标志
always @(posedge clk_1k or negedge rst_n)
    if(!rst_n)begin
        flag <= 0;
        state <= 0;
        cnt_time <= 0;
        row_col <= 0;
        col <= 0;
    end 
    else begin
        case(state)
        0 : begin
            if(row != 4'b1111)begin
                if(cnt_time < 19) //延时20ms
                    cnt_time <= cnt_time + 1;
                else begin
                    cnt_time <= 0;
                    state <= state + 1'b1;
                    col <= 4'b1110;   //扫描第一列
                end
            end
            else     cnt_time <= 0;
        end
        1 : begin
                if(row != 4'b1111)begin
                    row_col <= {row,col};//储存键值
                    flag <= 1;
                    state <= state + 1;
                    col <= 4'b0000;
                end
                else    col <= {col[2:0],col[3]};
        end
        2 : begin
                if(row == 4'b1111)begin
                    if(cnt_time < 19)begin
                        cnt_time <= cnt_time + 1;
                        flag <= 0;
                    end
                    else begin
                        cnt_time <= 0;
                        state <= 0;
                        col <= 4'b0000;
                    end
                end
                else begin
                    cnt_time <= 0;
                    flag <= 0;
                end
        end
        default : state <= 0;        
        endcase
    end
reg            [3:0]    key_value;
reg                    next_flag;
always @(posedge clk or negedge rst_n)
    if(!rst_n)
        next_flag <= 'd0;
    else 
        next_flag <= flag;
always @(posedge clk or negedge rst_n)
    if(!rst_n)
        key_value <= 0;
    else if(next_flag == 1 && flag == 0)begin
        case(row_col)
            8'b1110_1110 : key_value <= key_value + 1;
            8'b1110_1101 : key_value <= key_value + 1;
            8'b1110_1011 : key_value <= key_value + 1;
            8'b1110_0111 : key_value <= key_value + 1;
            8'b1101_1110 : key_value <= key_value + 1;
            8'b1101_1101 : key_value <= key_value + 1;
            8'b1101_1011 : key_value <= key_value + 1;
            8'b1101_0111 : key_value <= key_value + 1;
            8'b1011_1110 : key_value <= key_value + 1;
            8'b1011_1101 : key_value <= key_value + 1;
            8'b1011_1011 : key_value <= key_value + 1;
            8'b1011_0111 : key_value <= key_value + 1;
            8'b0111_1110 : key_value <= key_value + 1;
            8'b0111_1101 : key_value <= key_value + 1;
            8'b0111_1011 : key_value <= key_value + 1;
            8'b0111_0111 : key_value <= key_value + 1;        
            default         : key_value <= key_value + 0;
        endcase
    end
    
parameter _0=8'hc0,_1=8'hf9,_2=8'ha4,_3=8'hb0,_4=8'h99,
             _5=8'h92,_6=8'h82,_7=8'hf8,_8=8'h80,_9=8'h90;
always @(posedge clk or negedge rst_n)
    if(!rst_n)
        smg1 <= 0;
    else 
    case(key_value%10)
        4'd0:smg1<=_0;
        4'd1:smg1<=_1;
        4'd2:smg1<=_2;
        4'd3:smg1<=_3;
        4'd4:smg1<=_4;
        4'd5:smg1<=_5;    
        4'd6:smg1<=_6;
        4'd7:smg1<=_7;    
        4'd8:smg1<=_8;
        4'd9:smg1<=_9;
        default:smg1<=_0;
    endcase

always@(posedge clk or negedge rst_n)
if(!rst_n)
    smg2[7:0]<= 0;
else    
    case(key_value/10)
        4'd0:smg2<=_0;
        4'd1:smg2<=_1;
        4'd2:smg2<=_2;
        4'd3:smg2<=_3;
        4'd4:smg2<=_4;
        4'd5:smg2<=_5;    
        4'd6:smg2<=_6;
        4'd7:smg2<=_7;    
        4'd8:smg2<=_8;
        4'd9:smg2<=_9;
        default:smg2<=_0;
    endcase    
endmodule
原文地址:https://www.cnblogs.com/bixiaopengblog/p/6556212.html