ZYNQ_project:key_led

条件里是十进制可以不加进制说明,编译器默认是10进制,其他进制要说明。

实验目标:

ZYNQ_project:key_led_第1张图片

 模块框图:

ZYNQ_project:key_led_第2张图片

时序图:

ZYNQ_project:key_led_第3张图片

代码:

`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

仿真:

你可能感兴趣的:(fpga开发)