状态机-阶段1 练习4
注意:dout 在dout_vld有效时,其值有效,说明 dou_vld 和 dout 是在同一拍上
状态机:
产生输出:
代码:
1 module state_test( 2 clk, 3 rst_n, 4 din_vld, 5 din, 6 7 dout_vld, 8 dout 9 ); 10 11 parameter S0 = 0; 12 parameter S1 = 1; 13 parameter S2 = 2; 14 parameter S3 = 3; 15 parameter S4 = 4; 16 17 input clk; 18 input rst_n; 19 input din_vld; 20 input[2-1:0] din; 21 22 output dout_vld; 23 output[6-1:0] dout; 24 25 26 wire S02S1_start; 27 wire S02S2_start; 28 wire S12S2_start; 29 wire S12S3_start; 30 wire S12S0_start; 31 wire S22S3_start; 32 wire S22S4_start; 33 wire S22S0_start; 34 wire S32S4_start; 35 wire S32S0_start; 36 wire S42S0_start; 37 wire vld0; 38 wire vld1; 39 wire vld2; 40 wire vld3; 41 wire vld4; 42 43 44 reg dout_vld; 45 reg[6-1:0] dout; 46 47 reg[3-1:0] state_c; 48 reg[3-1:0] state_n; 49 50 //第一段,状态跳转 51 always @(posedge clk or negedge rst_n)begin 52 if(!rst_n)begin 53 state_c <= S0; 54 end 55 else begin 56 state_c <= state_n; 57 end 58 end 59 60 //第二段,组合逻辑,罗列出状态转移条件 61 always @(*)begin 62 case(state_c) 63 S0:begin 64 if(S02S1_start)begin 65 state_n = S1; 66 end 67 else if(S02S2_start)begin 68 state_n = S2; 69 end 70 else begin 71 state_n = state_c; 72 end 73 end 74 75 S1:begin 76 if(S12S2_start)begin 77 state_n = S2; 78 end 79 else if(S12S3_start)begin 80 state_n = S3; 81 end 82 else if(S12S0_start)begin 83 state_n = S0; 84 end 85 else begin 86 state_n = state_c; 87 end 88 end 89 90 S2:begin 91 if(S22S3_start)begin 92 state_n = S3; 93 end 94 else if(S22S4_start)begin 95 state_n = S4; 96 end 97 else if(S22S0_start)begin 98 state_n = S0; 99 end 100 else begin 101 state_n = state_c; 102 end 103 end 104 105 S3:begin 106 if(S32S4_start)begin 107 state_n = S4; 108 end 109 else if(S32S0_start)begin 110 state_n = S0; 111 end 112 else begin 113 state_n = state_c; 114 end 115 end 116 117 S4:begin 118 if(S42S0_start)begin 119 state_n = S0; 120 end 121 else begin 122 state_n = state_c; 123 end 124 end 125 126 default:begin 127 state_n = S0; 128 end 129 endcase 130 end 131 132 //第三段,设计条件 133 assign S02S1_start = state_c == S0 && din_vld && din == 0; 134 assign S02S2_start = state_c == S0 && din_vld && din == 1; 135 136 assign S12S2_start = state_c == S1 && din_vld && din == 0; 137 assign S12S3_start = state_c == S1 && din_vld && din == 1; 138 assign S12S0_start = state_c == S1 && din_vld && din == 2; 139 140 assign S22S3_start = state_c == S2 && din_vld && din == 0; 141 assign S22S4_start = state_c == S2 && din_vld && din == 1; 142 assign S22S0_start = state_c == S2 && din_vld && din == 2; 143 144 assign S32S4_start = state_c == S3 && din_vld && din == 0; 145 assign S32S0_start = state_c == S3 && din_vld && (din == 1 || din == 2); 146 147 assign S42S0_start = state_c == S4 && din_vld && (din == 0 || din == 1 || din == 2); 148 149 150 assign vld0 = state_c == S0 && din_vld && din == 2; 151 assign vld1 = state_c == S1 && din_vld && din == 2; 152 assign vld2 = state_c == S2 && din_vld && din == 2; 153 assign vld3 = state_c == S3 && din_vld && (din == 1 || din == 2); 154 assign vld4 = state_c == S4 && din_vld && (din == 0 || din == 1 || din == 2); 155 156 //第四段,设计输出 157 always @(posedge clk or negedge rst_n)begin 158 if(!rst_n)begin 159 dout_vld <= 0; 160 end 161 else if(vld0 || vld1 || vld2 || vld3 || vld4)begin 162 dout_vld <= 1; 163 end 164 else begin 165 dout_vld <= 0; 166 end 167 end 168 169 always @(posedge clk or negedge rst_n)begin 170 if(!rst_n)begin 171 dout <= 0; 172 end 173 else if(vld1 || (state_c == S4 && din_vld && din == 1))begin //这里所有判断跳进不能加上 && dout_vld ,dout 和 dout_vld 是在同一拍上有效 174 dout <= 5; 175 end 176 else if(vld2)begin 177 dout <= 10; 178 end 179 else if(state_c == S3 && din_vld && din == 2)begin 180 dout <= 15; 181 end 182 else if(state_c == S4 && din_vld && din == 2)begin 183 dout <= 20; 184 end 185 else begin 186 dout <= 0; 187 end 188 end 189 190 endmodule
测试代码:
1 module state_sim; 2 3 reg clk; 4 reg rst_n; 5 reg din_vld; 6 reg[2-1:0] din; 7 8 wire dout_vld; 9 wire[6-1:0] dout; 10 11 parameter CLK_CYCLE = 10; 12 13 initial begin 14 clk = 0; 15 forever begin 16 #(CLK_CYCLE/2); 17 clk = ~clk; 18 end 19 end 20 21 initial begin 22 rst_n = 0; 23 #1; 24 #(CLK_CYCLE*5); 25 rst_n = 1; 26 end 27 28 initial begin 29 #1; 30 din_vld = 0; 31 #(CLK_CYCLE*5); 32 repeat(100)begin 33 din_vld = 0; 34 #(CLK_CYCLE*3); 35 din_vld = 1; 36 #(CLK_CYCLE); 37 38 din_vld = 0; 39 #(CLK_CYCLE*3); 40 end 41 end 42 43 initial begin 44 #1; 45 din = 0; 46 #(CLK_CYCLE*5); 47 repeat(100)begin 48 #(CLK_CYCLE*3); 49 din = $urandom_range(0,2); 50 #(CLK_CYCLE); 51 52 din = 0; 53 #(CLK_CYCLE*3); 54 end 55 end 56 57 state_test u1_inist( 58 .clk(clk), 59 .rst_n(rst_n), 60 .din_vld(din_vld), 61 .din(din), 62 .dout_vld(dout_vld), 63 .dout(dout) 64 ); 65 66 endmodule
仿真波形:
quartus 状态图:
转移条件