一段式状态机,两段式状态机实例

15 篇文章 2 订阅
14 篇文章 1 订阅
  1. 一段式状态机
parameter S0 =  3'd0; 
parameter S1 =  3'd1; 
parameter S2 =  3'd2; 
parameter S3 =  3'd3; 
parameter S4 =  3'd4; 
parameter S5 =  3'd5;


always @ (posedge  clk  ) begin 
		if (   rst  ) begin 
			<= 0;
			<= 0;
			<= 0;
		state <= S0;
		end 
		else begin 
		case (state)
				S0	:	begin 
							
							state <= S1;				
end 
				S1	:	begin 
							
;
							state <= S2;						
end 
				S2	:	begin 
							
							state <= S3;//12->8
						end 
				S3	:	begin 
							
							state <= S4;//8->4
						end 
				S4	:	begin 
							
							state <= S5;//4->0
						end 
				default :begin 
							
							state <= S0;
						end 
			endcase 
		end 
	end



  1. 两段式状态机:
    用两个always 模块来描述状态机 , 一个always 用组合逻辑判断状态转移条件 , 另一个用同步时序描述状态转移。
always@(*)begin
        S_n_state = S_c_state;
        case (S_c_state)
            IDLE: begin
                S_n_state = (I_init_calib_complete == 1'b1) ? WAIT_EN : IDLE;
            end
            WAIT_EN: begin
                S_n_state = (I_ddr_en == 1'd1) ? (I_rw_ctrl == 1'd1) ? READ_DATA: WRITE_DATA : WAIT_EN;
            end
            WRITE_DATA: begin
                case ({I_app_rdy,I_app_wdf_rdy})
                    2'b11: begin
                        S_n_state = WAIT_EN;
                    end 
                    2'b10: begin
                        S_n_state = WAIT_WDF_RYD;
                    end
                    2'b01: begin
                        S_n_state = WAIT_APP_RYD;
                    end
                    2'b00: begin
                        S_n_state = WRITE_DATA;
                    end
                    default: begin
                        S_n_state = WRITE_DATA;
                    end
                endcase
            end
            WAIT_WDF_RYD: begin
                S_n_state = (I_app_wdf_rdy == 1'd1) ? WAIT_EN : WAIT_WDF_RYD;
            end
            WAIT_APP_RYD: begin
                S_n_state = (I_app_rdy == 1'd1) ? WAIT_EN : WAIT_APP_RYD;
            end
            READ_DATA: begin
                S_n_state = (I_app_rdy == 1'd1) ? WAIT_EN : READ_DATA;
            End
//-------------------------------------
    //S_app_cmd
    always@(posedge I_sys_clk) begin
        if (I_sys_rst) begin
            S_app_cmd <= 3'd0;
        end else begin
            case (S_c_state)
                IDLE: begin
                    S_app_cmd <= 3'd0;
                end
                WAIT_EN: begin
                    S_app_cmd <= ((I_ddr_en == 1'd1) && (I_rw_ctrl == 1'd1)) ? 3'd1 : 3'd0;
                end
                default: begin
                    S_app_cmd <= S_app_cmd;
                end
            endcase
        end
    end
    //-------------------------------------
    //S_ddr_data
    always@(posedge I_sys_clk) begin
        if (I_sys_rst) begin
            S_ddr_dout <= 512'd0;
        end else begin
            case (S_c_state)
                IDLE: begin
                    S_ddr_dout <= 512'd0;
                end
                WAIT_EN: begin
                    S_ddr_dout <= ((I_ddr_en == 1'd1) && (I_rw_ctrl == 1'd0)) ? I_ddr_din : 512'd0;
                end
                default: begin
                    S_ddr_dout <= S_ddr_dout;
                end
            endcase
        end
    end
    //-------------------------------------
    //S_ddr_addr
    always@(posedge I_sys_clk) begin
        if (I_sys_rst) begin
            S_app_addr <= 28'd0;
        end else begin
            case (S_c_state)
                IDLE: begin
                    S_app_addr <= 28'd0;
                end
                WAIT_EN: begin
                    S_app_addr <= (I_ddr_en == 1'd1)? I_ddr_addr : 28'd0;
                end
                default: begin
                    S_app_addr <= S_app_addr;
                end
            endcase
        end
    end
    //-------------------------------------
    //S_app_en
    always@(posedge I_sys_clk) begin
        if (I_sys_rst) begin
            S_app_en <= 1'd0;
        end else begin
            case (S_c_state)
                IDLE: begin
                    S_app_en <= 1'd0;
                end
                WAIT_EN: begin
                    S_app_en <= (I_ddr_en == 1'd1) ? 1'd1 : 1'd0;
                end
                WRITE_DATA: begin
                    case ({I_app_rdy,I_app_wdf_rdy})
                        2'b11: begin
                            S_app_en <= 1'd0;
                        end 
                        2'b10: begin
                            S_app_en <= 1'd0;
                        end
                        2'b01: begin
                            S_app_en <= 1'd1;
                        end
                        2'b00: begin
                            S_app_en <= 1'd1;
                        end
                        default: begin
                            S_app_en <= 1'd0;
                        end
                    endcase
                end
                WAIT_WDF_RYD: begin
                    S_app_en <= 1'd0;
                end
                WAIT_APP_RYD: begin
                    S_app_en <= (I_app_rdy == 1'd1) ? 1'd0: 1'd1;
                end
                READ_DATA: begin
                    S_app_en <= (I_app_rdy == 1'd1) ? 1'd0: 1'd1;
                end
                default: begin
                    S_app_en <= 1'd0;
                end
            endcase
        end
    end

    //-------------------------------------
    //S_app_wdf_wren
    always@(posedge I_sys_clk) begin
        if (I_sys_rst) begin
            S_app_wdf_wren <= 1'd0;
        end else begin
            case (S_c_state)
                IDLE: begin
                    S_app_wdf_wren <= 1'd0;
                end
                WAIT_EN: begin
                    S_app_wdf_wren <= ((I_ddr_en == 1'd1) && (I_rw_ctrl == 1'd0)) ? 1'd1 : 1'd0;
                end
                WRITE_DATA: begin
                    case ({I_app_rdy,I_app_wdf_rdy})
                        2'b11: begin
                            S_app_wdf_wren <= 1'd0;
                        end 
                        2'b10: begin
                            S_app_wdf_wren <= 1'd1;
                        end
                        2'b01: begin
                            S_app_wdf_wren <= 1'd0;
                        end
                        2'b00: begin
                            S_app_wdf_wren <= 1'd1;
                        end
                        default: begin
                            S_app_wdf_wren <= 1'd0;
                        end
                    endcase
                end
                WAIT_APP_RYD: begin
                    S_app_wdf_wren <= 1'd0;
                end
                WAIT_WDF_RYD: begin
                    S_app_wdf_wren <= (I_app_wdf_rdy == 1'd1) ? 1'd0: 1'd1;
                end
                default: begin
                    S_app_wdf_wren <= 1'd0;
                end
            endcase
        end
    end
    //-------------------------------------
    //
    always@(posedge I_sys_clk) begin
        if (I_sys_rst) begin
            S_ddr_rdy <= 1'd0;
        end else begin
            case (S_n_state)
                WAIT_EN: begin
                    S_ddr_rdy <= 1'd1;
                end 
                default: begin
                    S_ddr_rdy <= 1'd0;
                end
            endcase
        end
    end
            default: begin
                S_n_state = IDLE;
            end 
        endcase
end

3.三段式状态机
用三个always 模块来描述状态机 , 一个always 用组合逻辑判断状态转移条件,描述状态转移规律, 另一个用同步时序描述状态转移, 最后在用一个always 描述状态输出。(可用组合电路输出,也可用时序电路输出)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值