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