//状态编码,采用独热码
parameter start_fl00k = 6'b000001, //状态A
fl00k_cnt = 6'b000010, //状态B
start_fl0k = 6'b000100, //状态C
fl0k_cn = 6'b001000, //状态D
start_flk = 6'b010000, //状态E
flk_cnt = 6'b100000; //状态F
always @(posedge clk or posedge clear) begin
if(clear)
present<=start_fl0k; //异步复位至start_fl0k状态
else
present<=next; //状态转换
end
always @(present or cntover or cntlow) begin //状态转换的触发信号列表
case(present) //用case语句描述状态转换
start_fl00k: //100k量程状态
next<=fl00k_cnt;
fl00k_cnt: begin //100k量程控制状态
if(cntlow) //欠量程
next<=start_fl0k; //进入10k量程状态
else
next<=fl00k_cnt; //保持100k量程控制状态
end
start_fl0k: //10k量程状态
next<=fl0k_cnt;
fl0k_cnt: begin //10k量程控制状态
if(cntlow) //欠量程
next<=start_flk; //进入1k量程状态
else if(cntover) //过量程
next<=start_fl00k; //进入100k量程状态
else
next<=fl0k_cnt; //保持1k量程控制状态
end
start_flk: //1k量程状态
next<=flk_cnt;
flk_cnt: begin //1k量程控制状态
if(cntover) //过量程
next<=start_fl0k; //进入10k量程状态
else
next<=flk_cnt; //保持1k量程控制状态
end
default:
next<=start_fl0k; //缺省状态为10k量程状态
endcase
end
//各状态的输出控制模块
always @(present) begin
case(present)
start_fl00k: begin //100k量程状态输出控制
reset=1;
std_f_sel=2'b00;
end
fl00k_cnt: begin //100k量程控制状态输出控制
reset=0;
std_f_sel=2'b00;
end
start_fl0k: begin //10k量程状态输出控制
reset=1;
std_f_sel=2'b01;
end
fl0k_cnt: begin //10k量程控制状态输出控制
reset=0;
std_f_sel=2'b01;
end
start_flk: begin //1k量程状态输出控制
reset=1;
std_f_sel=2'b11;
end
flk_cnt: begin //1k量程控制状态输出控制
reset=0;
std_f_sel=2'b11;
end
default: begin //默认(10k量程)状态输出控制
reset=1;
std_f_sel=2'b01;
end
endcase
end
endmodule
在状态机设计中,常常将状态转换和状态输出控制分为两个部分进行设计,方便语言的编写修改和读写规则。在下面的源代码中读者应该注意这个设计的特点。