一个关于状态机的问题
下面是状态机的一种写法:
这个状态机在满足 h_nx_state == S_H_SYNC 和h_pre_state == S_H_FRONT_PORCH 的状态下进行状态转换。
但是实际上实现出来的效果如下面的图一样,在复位过后,状态机所有的状态都可能同时为高,状态转换根本不正常。
always @( * ) begin if( h_nx_state == S_H_SYNC && h_pre_state == S_H_FRONT_PORCH ) begin case( v_pre_state ) S_V_SYNC : begin if( v_cnt == V_SYNC -1 ) v_nx_state <= S_V_BACK_PORCH; else v_nx_state <= S_V_SYNC; end S_V_BACK_PORCH : begin if( v_cnt == V_BACK_PORCH -1 ) v_nx_state <= S_V_ACTIVE; else v_nx_state <= S_V_BACK_PORCH; end S_V_ACTIVE : begin if( v_cnt == row -1 ) v_nx_state <= S_V_FRONT_PORCH; else v_nx_state <= S_V_ACTIVE; end S_V_FRONT_PORCH : begin if( v_cnt == V_FRONT_PORCH -1'b1 ) v_nx_state <= S_V_SYNC; else v_nx_state <= S_V_FRONT_PORCH; end default:; endcase end end
经过思考之后,笔者把程序修改成了下面这个样子。也就是状态机在任何时候都在判断状态,这样之后,状态就很确定。
always @( * ) begin case( v_pre_state ) S_V_SYNC : begin if( h_nx_state == S_H_SYNC && h_pre_state == S_H_FRONT_PORCH ) begin if( v_cnt == V_SYNC -1 ) v_nx_state = S_V_BACK_PORCH; else v_nx_state = S_V_SYNC; end else begin v_nx_state = S_V_SYNC; end end S_V_BACK_PORCH : begin if( h_nx_state == S_H_SYNC && h_pre_state == S_H_FRONT_PORCH ) begin if( v_cnt == V_BACK_PORCH -1 ) v_nx_state = S_V_ACTIVE; else v_nx_state = S_V_BACK_PORCH; end else begin v_nx_state = S_V_BACK_PORCH; end end S_V_ACTIVE : begin if( h_nx_state == S_H_SYNC && h_pre_state == S_H_FRONT_PORCH ) begin if( v_cnt == row -1 ) v_nx_state = S_V_FRONT_PORCH; else v_nx_state = S_V_ACTIVE; end else begin v_nx_state = S_V_ACTIVE; end end S_V_FRONT_PORCH : begin if( h_nx_state == S_H_SYNC && h_pre_state == S_H_FRONT_PORCH ) begin if( v_cnt == V_FRONT_PORCH -1'b1 ) v_nx_state = S_V_SYNC; else v_nx_state = S_V_FRONT_PORCH; end else begin v_nx_state = S_V_FRONT_PORCH; end end default:; endcase end