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