条件里是十进制可以不加进制说明,编译器默认是10进制,其他进制要说明。
实验目标:
模块框图:
时序图:
代码:
`include "para.v"
module key_filter (
input wire sys_clk ,
input wire sys_rst_n ,
input wire [`key_length -1 :0] key_in ,
output reg [`key_length -1:0] key_flag
);
reg [`key_length -1 :0] key_in_r1 ;
reg [`key_length -1 :0] key_in_r2 ;
reg [3:0] state_c ;
reg [3:0] state_n ;
reg [19:0] cnt_core ;
wire nege ;
wire pose ;
wire cnt_done_filter ;
wire IDLEtoFILTER_UP ;
wire FILTER_UPtoSAMPLING ;
wire FILTER_UPtoIDLE ;
wire SAMPLINGtoFILTER_BACK ;
wire FILTER_BACKtoIDLE ;
localparam IDLE = 4'b0001 ,
FILTER_UP = 4'b0010 ,
SAMPLING = 4'b0100 ,
FILTER_BACK = 4'b1000 ;
/*********************************************************************/
// reg [`key_length -1 :0] key_in_r1 ;
// reg [`key_length -1 :0] key_in_r2 ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
key_in_r1 <= 2'b11 ;
key_in_r2 <= 2'b11 ;
end
else begin
key_in_r1 <= key_in ;
key_in_r2 <= key_in_r1 ;
end
end
// wire nege ;
assign nege = |(~key_in_r1 & key_in_r2) ;
// wire pose ;
assign pose = |( key_in_r1 & ~key_in_r2 );
// reg [3:0] state_c ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
state_c <= IDLE ;
else
state_c <= state_n ;
end
// reg [3:0] state_n ;
always @(*) begin
case(state_c)
IDLE : if(IDLEtoFILTER_UP)
state_n = FILTER_UP ;
else
state_n = IDLE ;
FILTER_UP : if(FILTER_UPtoSAMPLING)
state_n = SAMPLING ;
else if(FILTER_UPtoIDLE)
state_n = IDLE ;
else
state_n = FILTER_UP ;
SAMPLING : if(SAMPLINGtoFILTER_BACK)
state_n = FILTER_BACK ;
else
state_n = SAMPLING ;
FILTER_BACK : if(FILTER_BACKtoIDLE)
state_n = IDLE ;
else
state_n = FILTER_BACK ;
default : state_n = IDLE ;
endcase
end
assign IDLEtoFILTER_UP = state_c == ( IDLE ) && ( nege ) ;
assign FILTER_UPtoSAMPLING = state_c == ( FILTER_UP ) && ( cnt_done_filter ) ;
assign FILTER_UPtoIDLE = state_c == ( FILTER_UP ) && ( pose ) ;
assign SAMPLINGtoFILTER_BACK = state_c == ( SAMPLING ) && ( pose ) ;
assign FILTER_BACKtoIDLE = state_c == ( FILTER_BACK ) && ( cnt_done_filter ) ;
// reg [19:0] cnt_core ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
cnt_core <= 20'd0 ;
else
case (state_c)
IDLE : cnt_core <= 20'd0 ;
FILTER_UP : if( cnt_core == `MAX_CNT_10MS - 1 )
cnt_core <= 20'd0 ;
else
cnt_core <= cnt_core + 1'b1 ;
SAMPLING : cnt_core <= 20'd0 ;
FILTER_BACK : if( cnt_core == `MAX_CNT_10MS - 1 )
cnt_core <= 20'd0 ;
else
cnt_core <= cnt_core + 1'b1 ;
default : cnt_core <= 20'd0 ;
endcase
end
// cnt_done_filter
assign cnt_done_filter = ( cnt_core == `MAX_CNT_10MS - 1 ) ;
// reg [`key_length -1:0] key_flag
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
key_flag <= 0 ;
else if(FILTER_UPtoSAMPLING)
key_flag <= ~key_in_r2 ;
else
key_flag <= 0 ;
end
endmodule
// led闪烁实验,间隔0.25s
`include "para.v"
module led(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [1:0] key_in ,
output reg [1:0] led_out
);
reg [1:0] led_mod ;
reg [23:0] cnt_25ms ;
wire cnt_25ms_flag ;
// led_mod
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
led_mod <= 2'b00 ;
else if((led_mod == 2'b01 && key_in == 2'b01) || (led_mod == 2'b10 && key_in == 2'b10))
led_mod <= 2'b00 ;
else if(key_in == 2'b01)
led_mod <= 2'b01 ;
else if(key_in == 2'b10)
led_mod <= 2'b10 ;
else
led_mod <= led_mod ;
end
// cnt_25ms
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
cnt_25ms <= 24'd0 ;
else if(led_mod == 2'b01 || led_mod == 2'b10) begin
if(cnt_25ms == `MAX_CNT_250MS - 1)
cnt_25ms <= 24'd0 ;
else
cnt_25ms <= cnt_25ms + 1'b1 ;
end
else
cnt_25ms <= 24'd0 ;
end
assign cnt_25ms_flag = (cnt_25ms == `MAX_CNT_250MS - 1) ;
// led_out
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n)
led_out <= 2'b11 ;
else
case (led_mod)
2'b00: led_out <= 2'b11 ;
2'b01: if(led_out[1] == led_out[0])
led_out <= 2'b10 ;
else if(cnt_25ms_flag)
led_out <= ~led_out ;
else
led_out <= led_out ;
2'b10: if(led_out[1] != led_out[0])
led_out <= 2'b11 ;
else if(cnt_25ms_flag)
led_out <= ~led_out ;
else
led_out <= led_out ;
default: led_out <= led_out ;
endcase
end
endmodule
`define key_length 2
`define MAX_CNT_10MS 500_000
`define MAX_CNT_500MS 25_000_000
`define MAX_CNT_250MS 12_500_000
`include "para.v"
module top(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [1:0] key_in ,
output wire [1:0] led_out
);
// 例化间连�?
wire [`key_length -1:0] key_flag ;
key_filter key_filter_inst(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_in ( key_in ) ,
.key_flag ( key_flag )
);
led led_inst(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_in ( key_flag ) ,
.led_out ( led_out )
);
endmodule