FPGA project : complex_fsm

module complex_fsm (
    input           wire        sys_clk         ,
    input           wire        sys_rst_n       ,
    input           wire        pi_money_one    ,
    input           wire        pi_money_half   ,

    output          reg         po_cola         ,
    output          reg         po_money
);
    // define signal
    wire    [01:00]     money   ;
    reg     [04:00]     state   ;

    // define parameter 
    parameter           IDLE     = 5'b00001 ,
                        HALF     = 5'b00010 ,
                        ONE      = 5'b00100 ,
                        ONE_HALF = 5'b01000 ,
                        TWO      = 5'b10000 ;

    // money
    assign money = ( pi_money_half ) ? 2'b01 : ( pi_money_one ) ? 2'b10 : 2'b00 ;

    // state 
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            state <= IDLE ;
        end else begin
            case ( state )
                IDLE     : begin
                            if( money == 2'b01 ) begin
                                state <= HALF ;
                            end else begin
                                if( money == 2'b10 ) begin
                                    state <= ONE ;
                                end else begin
                                    state <= IDLE ;
                                end
                            end
                        end
                HALF     : begin
                            if( money == 2'b01 ) begin
                                state <= ONE ;
                            end else begin
                                if( money == 2'b10 ) begin
                                    state <= ONE_HALF ;
                                end else begin
                                    state <= HALF ;
                                end
                            end
                        end
                ONE      : begin
                            if( money == 2'b01 ) begin
                                state <= ONE_HALF ;
                            end else begin
                                if( money == 2'b10 ) begin
                                    state <= TWO ;
                                end else begin
                                    state <= ONE ;
                                end
                            end
                        end
                ONE_HALF : begin
                            if( money == 2'b01 ) begin
                                state <= TWO ;
                            end else begin
                                if( money == 2'b10 ) begin
                                    state <= IDLE ;
                                end else begin
                                    state <= ONE_HALF ;
                                end
                            end
                        end
                TWO      : begin
                            if( money == 2'b01  || money == 2'b10 ) begin
                                state <= IDLE ;
                            end else begin
                                state <= TWO ;
                            end
                        end
                default  : state <= IDLE ;
            endcase 
        end
    end

    // po_cola 
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            po_cola <= 0 ;
        end else begin
            if( (state == ONE_HALF && money == 2'b10) || (state == TWO && money != 2'b00) ) begin
                po_cola <= 1'b1 ;
            end else begin
                po_cola <= 0 ;
            end
        end
    end
    // po_money
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            po_money <= 0 ;
        end else begin 
            if(state == TWO && money == 2'b10) begin
                po_money <= 1 ;
            end else begin
                po_money <= 0 ;
            end
        end
    end
endmodule
`timescale 1ns/1ns
module test();
    reg                         sys_clk         ;
    reg                         sys_rst_n       ;
    reg                         pi_money_one    ;
    reg                         pi_money_half   ;

    wire                        po_cola         ;
    wire                        po_money        ;
// Instantiation
complex_fsm complex_fsm_insert (
    .sys_clk                    ( sys_clk       ) ,
    .sys_rst_n                  ( sys_rst_n     ) ,
    .pi_money_one               ( pi_money_one  ) ,
    .pi_money_half              ( pi_money_half ) ,

    .po_cola                    ( po_cola       ) ,
    .po_money                   ( po_money      )
);
    parameter CYCLE = 20 ;

    initial begin
        sys_clk    = 1'b1 ;
        sys_rst_n <= 1'b1 ;
        pi_money_half  <= 1'b0 ;
        pi_money_one   <= 1'b0 ;
        #( 30 )           ; // 在sys_clk 下降沿复位
        sys_rst_n <= 1'b0 ;
        #( CYCLE * 5 )    ;
        #( 10 )           ; // 对齐时钟
        sys_rst_n <= 1'b1 ;

        #(CYCLE * 30 )    ;
        pi_money_half  <= 1'b1 ;
        #(CYCLE * 3)           ; // 0.5 元 存入三次 1.5
        pi_money_half  <= 1'b0 ;
        pi_money_one   <= 1'b1 ; 
        #(CYCLE)               ; // 1 元 存入一次 2.5元 出可乐 金额清零
        pi_money_one   <= 1'b0 ;
        #(CYCLE * 10)          ;

        pi_money_half  <= 1'b1 ;
        #(CYCLE * 2)           ; // 0.5 元 存两次 1元
        pi_money_half  <= 1'b0 ;
        pi_money_one   <= 1'b1 ; 
        #(CYCLE)               ; // 1 元 存入一次 2元
        pi_money_one   <= 1'b0 ;
        pi_money_half  <= 1'b1 ;
        #(CYCLE )              ; // 0.5 元 存入一次 2.5 出可乐 金额清零
        pi_money_half  <= 1'b0 ;
        #(CYCLE * 10)          ;

        pi_money_one   <= 1'b1 ; 
        #(CYCLE )              ;
        pi_money_one   <= 1'b0 ;
        #(CYCLE )              ;
        pi_money_one   <= 1'b1 ;
        #(CYCLE )              ;
        pi_money_one   <= 1'b0 ;
        #(CYCLE )              ;
        pi_money_one   <= 1'b1 ; 
        #(CYCLE )              ; // 1 元 存入三次 3元 出可乐 金额清零
        pi_money_one   <= 1'b0 ;
        #(CYCLE * 10)          ;

        $stop             ;
    end


    always #( CYCLE / 2 ) sys_clk = ~sys_clk ;

endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值