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 & amp; & amp; money == 2'b10) || (state == TWO & amp; & amp; 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 & amp; & amp; 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); //Reset on the falling edge of sys_clk sys_rst_n <= 1'b0; #(CYCLE * 5); #(10); //Align clock sys_rst_n <= 1'b1; #(CYCLE * 30); pi_money_half <= 1'b1; #(CYCLE * 3); // 0.5 yuan deposited three times 1.5 pi_money_half <= 1'b0; pi_money_one <= 1'b1; #(CYCLE) ; // 1 yuan is deposited once, 2.5 yuan is issued, and the amount is cleared to zero pi_money_one <= 1'b0; #(CYCLE * 10) ; pi_money_half <= 1'b1; #(CYCLE * 2); // 0.5 yuan, deposit twice, 1 yuan pi_money_half <= 1'b0; pi_money_one <= 1'b1; #(CYCLE); // 1 yuan deposited once 2 yuan pi_money_one <= 1'b0; pi_money_half <= 1'b1; #(CYCLE); // 0.5 Yuan deposit once 2.5 Coke is issued and the amount is reset to zero 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 yuan deposited three times, 3 yuan issued Coke, the amount is reset to zero pi_money_one <= 1'b0; #(CYCLE * 10) ; $stop ; end always #( CYCLE / 2 ) sys_clk = ~sys_clk; endmodule