
module scan_clk ( clkout ,clk ,rst );
input rst ;
input clk ;
wire clk ;
output clkout ;
reg clkout_r ;
parameter period= 200000;
reg [31:0] cnt;
always @( posedge clk or negedge rst) //分频50Hz
begin
if ( !rst )
begin
cnt <= {31{1'b0}} ;
clkout_r <= 0 ;
end
else begin
cnt<= cnt+1;
if (cnt== (period >> 1) - 1) //设定周期时间的一半
clkout_r <= #1 1'b1;
else if (cnt == period - 1)//设定的周期时间
begin
clkout_r <= #1 1'b0;
cnt <= #1 'b0;
end
end
end
assign clkout = clkout_r ;
endmodule
module key_scan ( clk ,keydrv ,rst );
input clk ;
input rst ;
wire clk ;
output [3:0] keydrv ;
wire [3:0] keydrv ;
parameter s1 = 4'b1110;
parameter s2 = 4'b1101;
parameter s3 = 4'b1011;
parameter s4 = 4'b0111;
reg [3:0]current_state;
reg [3:0]next_state;
always @ ( posedge clk or negedge rst )
begin
if ( !rst )
current_state <= s1;
elsecurrent_state <= next_state ;
end
always @ ( current_state )
begin
case ( current_state )
s1: next_state <=s2;
s2: next_state <=s3;
s3: next_state <=s4;
s4: next_state <=s1;
default: next_state <=s1;
endcase
end
assignkeydrv = current_state ;
endmodule
`timescale 1 ms / 1 ns
module mms (enter,clk, KEYO ,KEYI ,rst,DIG,Y,right,wrong,change,led_c,clr,led_clr);
input enter;
output right;
reg right;
output wrong;
reg wrong;
input change;
output led_c;
reg led_c;
input clr;
output led_clr;
reg led_clr;
input[3:0]KEYO ; //与原理图一致,是键盘输出端口给FPGA
inputclk ;
inputrst ;
output[3:0]KEYI ;//与原理图一致,是FPGA输出给 键盘
wirescanclk;
wire[3:0]keydrv ;
reg[3:0]keyvalue;
reg [7:0] temp_r;
reg[3:0]scankey_o;
reg[3:0]scankey_i;
wiredis;
output [7:0] Y;
reg [7:0] Y_r;
assign Y=~Y_r;
output [3:0] DIG;
reg [3:0] DIG;
assign dis = &KEYO ;
reg dis_pre;
assign KEYI = keydrv;
scan_clk key_clk(
.clk ( clk),
.clkout ( scanclk) ,
.rst ( rst )
);
key_scan key_scan(
.clk ( scanclk ) ,
.keydrv (keydrv) ,
.rst ( rst )
);
always @ ( posedge clk or negedge rst ) begin
if ( rst==1'b0 ) begin
scankey_o <= 4'b0 ;
scankey_i <= 4'b0 ;
dis_pre <= dis;
end else if ( clk ==1'b1 ) begin
dis_pre <= dis;
if ( (dis == 1'b0)&&(dis_pre==1'b1) ) begin
scankey_o <= keydrv;
scankey_i <= KEYO ;
temp_r<={scankey_o,scankey_i};
end
end
end
reg clkk;
always @( temp_r or rst ) begin
if ( rst==1'b0 ) begin//译码输出
keyvalue =4'b1111;
clkk<=1'b0;
end
else
begin
case ( temp_r)
8'b1110_1110 : begin
keyvalue <= 4'h7;clkk<=1'b1;
end
8'b1110_1101 : begin
keyvalue <= 4'h8;clkk<=1'b1;
end
8'b1110_1011 : begin
keyvalue <= 4'h9;clkk<=1'b1;
end
8'b1101_1110 : begin
keyvalue <= 4'h4;clkk<=1'b1;
end
8'b1101_1101 : begin
keyvalue <= 4'h5;clkk<=1'b1;
end
8'b1101_1011 : begin
keyvalue <= 4'h6;clkk<=1'b1;
end
8'b1011_1110 : begin
keyvalue <= 4'h1;clkk<=1'b1;
end
8'b1011_1101 : begin
keyvalue <= 4'h2;clkk<=1'b1;
end
8'b1011_1011 : begin
keyvalue <= 4'h3;clkk<=1'b1;
end
8'b0111_1101 : begin
keyvalue <= 4'h0;clkk<=1'b1;
end
default : begin
keyvalue<=4'b1111;clkk<=1'b0;
end
endcase
end
end
reg [2:0] cnt;
always @(negedge rst or posedge clkk)
begin if(!rst)begin cnt<=0;RG<=0;end
else
begin cnt<=cnt+1;RG<={keyvalue,RG[15:4]};end
end
//output [15:0] RG;
reg [15:0] RG;
/*
always @(cnt)
if(!rst) RG<=0;
else begin
case (cnt)
3'b001:begin RG[3:0]<=keyvalue;end
3'b010:begin RG[7:4]<=keyvalue;end
3'b011:begin RG[11:8]<=keyvalue;end
3'b100:begin RG[15:12]<=keyvalue;end
default : RG<=RG;
endcase
end
*/
reg[1:0] js;
always @(posedge scanclk)
begin
if(!rst)js<=0;
else
js<=js+1;
end
always @(js)
begin
if(!rst) DIG<=0;
else
begin
case(js)
2'b00:begin DIG<=4'b0111; A<=RG[3:0];end
2'b01:begin DIG<=4'b1011; A<=RG[7:4];end
2'b10:begin DIG<=4'b1101; A<=RG[11:8];end
2'b11:begin DIG<=4'b1110; A<=RG[15:12];end
endcase
end
end
reg [3:0] A;
always @(A or rst )
begin
if ( rst==1'b0 ) //译码输出
Y_r <= 8'b0000_0000;
else begin
Y_r =8'b0000_0000;
case (A )
//5'hh: Y-r = 8'b0000_0000;// wu xian shi
4'h0: Y_r = 8'b0011_1111; // 0
4'h1: Y_r = 8'b0000_0110; // 1
4'h2: Y_r = 8'b0101_1011; // 2
4'h3: Y_r = 8'b0100_1111; // 3
4'h4: Y_r = 8'b0110_0110; // 4
4'h5: Y_r = 8'b0110_1101; // 5
4'h6: Y_r = 8'b0111_1101; // 6
4'h7: Y_r = 8'b0000_0111; // 7
4'h8: Y_r = 8'b0111_1111; // 8
4'h9: Y_r = 8'b0110_1111; // 9
//4'b0001: Y_r = 8'b1000_0000; //.
default: Y_r = 8'b0100_1001;
endcase
end
end
reg [15:0] MM;
always @(enter)
begin
if(!enter) begin right<=1'b0;wrong<=1'b0;
//MM<=16'b0001_0010_0011_0100;
end
else
begin if(enter==1'ba1)
begin if(RG==MM) begin right<=1'b1;wrong<=1'b0;end
else begin right<=1'b0; wrong<=1'b1;end
end
end
end
always @(change or clr)
if(!clr)
begin led_clr<=1'b0;
begin
if(!change) led_c<=1'b0;
else
begin
if(change)
begin led_c<=1'b1;
MM<=RG;
end
end
end
end
else begin if(clr) begin led_clr<=1'b1;MM<=0;end
end
endmodule
