- 一段式状态机
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
- 两段式状态机:
用两个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 描述状态输出。(可用组合电路输出,也可用时序电路输出)。