题目:
画出状态图:
dout 输出条件:
注意:在S3状态时,已收到了1.5元,所以不管后面收到1元还是0.5元都跳回S0,并找零钱(0元或0.5元),所以不需要在单独设立一个状态 S4(2元)。
代码:
1 //售货机 2 module state_test( 3 clk, 4 rst_n, 5 din_vld, 6 din, 7 dout 8 ); 9 10 parameter S0 = 0; 11 parameter S1 = 1; 12 parameter S2 = 2; 13 parameter S3 = 3; 14 15 input clk ; 16 input rst_n ; 17 input din_vld ; 18 input din ; 19 output dout ; 20 21 reg dout ; 22 reg [3-1:0] state_c ; 23 reg [3-1:0] state_n ; 24 25 wire S02S1_start; 26 wire S02S2_start; 27 wire S12S2_start; 28 wire S12S3_start; 29 wire S22S0_start; 30 wire S22S3_start; 31 wire S32S0_start; 32 33 34 //第一段,状态跳转 35 always @(posedge clk or negedge rst_n)begin 36 if(!rst_n)begin 37 state_c <= S0; 38 end 39 else begin 40 state_c <= state_n; 41 end 42 end 43 44 //第二段:组合逻辑always模块,描述状态转移条件判断 45 always @(*)begin 46 case(state_c) 47 S0:begin 48 if(S02S1_start)begin 49 state_n = S1; 50 end 51 else if(S02S2_start) begin 52 state_n = S2; 53 end 54 else begin 55 state_n = state_c; 56 end 57 end 58 59 S1:begin 60 if(S12S2_start)begin 61 state_n = S2; 62 end 63 else if(S12S3_start)begin 64 state_n = S3; 65 end 66 else begin 67 state_n = state_c; 68 end 69 end 70 71 S2:begin 72 if(S22S3_start)begin 73 state_n = S3; 74 end 75 else if(S22S0_start)begin 76 state_n = S0; 77 end 78 else begin 79 state_n = state_c; 80 end 81 end 82 83 S3:begin 84 if(S32S0_start)begin 85 state_n = S0; 86 end 87 else begin 88 state_n = state_c; 89 end 90 end 91 92 default:begin 93 state_n = S0; 94 end 95 endcase 96 end 97 98 //第三段:设计转移条件 99 assign S02S1_start = state_c == S0 && din_vld && din == 0; 100 assign S02S2_start = state_c == S0 && din_vld && din == 1; 101 102 assign S12S2_start = state_c == S1 && din_vld && din == 0; 103 assign S12S3_start = state_c == S1 && din_vld && din == 1; 104 105 assign S22S0_start = state_c == S2 && din_vld && din == 1; 106 assign S22S3_start = state_c == S2 && din_vld && din == 0; 107 108 assign S32S0_start = state_c == S3 && din_vld && (din == 0 || din == 1); 109 110 111 //第四段,设计输出 112 always @(posedge clk or negedge rst_n)begin 113 if(!rst_n)begin 114 dout <= 0; 115 end 116 else if(state_c == S3 && din_vld == 1 && din == 1)begin 117 dout <= 1; 118 end 119 else begin //if(din_vld == 1 && (state_c == S3 && din == 0) || (state_c == S2 && din == 1))begin 120 dout <= 0; 121 end 122 end 123 124 endmodule
测试代码:
1 module state_sim; 2 3 reg clk; 4 reg rst_n; 5 reg din_vld; 6 reg din; 7 8 wire dout; 9 10 parameter CLK_CYCLE = 10; 11 12 initial begin 13 clk = 0; 14 forever begin 15 #(CLK_CYCLE/2); 16 clk = ~clk; 17 end 18 end 19 20 initial begin 21 rst_n = 0; 22 #1; 23 #(CLK_CYCLE*5); 24 rst_n = 1; 25 end 26 27 initial begin 28 #1; 29 din_vld = 0; 30 repeat(100)begin 31 din_vld = 0; 32 #(CLK_CYCLE*10); 33 din_vld = 1; 34 #(CLK_CYCLE); 35 36 din_vld = 0; 37 #(CLK_CYCLE*5); 38 end 39 end 40 41 initial begin 42 #1; 43 din = 0; 44 repeat(100)begin 45 #(CLK_CYCLE*10); 46 din = $urandom_range(0,1); 47 #(CLK_CYCLE); 48 49 din = 0; 50 #(CLK_CYCLE*5); 51 end 52 end 53 54 state_test u1_inist( 55 .clk(clk), 56 .rst_n(rst_n), 57 .din_vld(din_vld), 58 .din(din), 59 .dout(dout) 60 ); 61 62 endmodule
仿真波形:
Quartus 综合出来的状态图:
转移条件: