有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 sky 于 2021-3-16 22:33 编辑
状态机是fpga设计中极其重要的一种技巧,掌握状态机的写法可以使fpga的开发事半功倍。
下面记录一下状态机的基本知识理论。.
实例:
三种状态机实现代码:
- // 一段式状态机
-
- module style1_fsm(i_clk, rst_n, i1, i2, o1, o2, err);
-
- input i_clk, rst_n, i1, i2;
- output o1, o2, err;
-
- parameter [3:0] IDLE = 4'b0001,
- S1 = 4'b0010,
- S2 = 4'b0100,
- ERROR= 4'b1000;
-
- reg o1, o2, err;
- reg [3:0] state;
-
- always @(posedge i_clk or negedge rst_n)
- begin
- if(!rst_n) begin
- state <= IDLE;
- {o1, o2, err} <= 3'b000;
- end
- else
- case(state)
- IDLE: begin
- if(!i1) begin
- {o1, o2, err} <= 3'b000;
- state <= IDLE;
- end
- if(i1 & i2) begin
- {o1, o2, err} <= 3'b100;
- state <= S1;
- end
- if(i1 & !i2) begin
- {o1, o2, err} <= 3'b111;
- state <= ERROR;
- end
- end
- S1: begin
- if(!i2) begin
- {o1, o2, err} <= 3'b100;
- state <= S1;
- end
- if(i1 & i2) begin
- {o1, o2, err} <= 3'b010;
- state <= S2;
- end
- if(!i1 & i2) begin
- {o1, o2, err} <= 3'b111;
- state <= ERROR;
- end
- end
- S2: begin
- if(i2) begin
- {o1, o2, err} <= 3'b010;
- state <= S2;
- end
- if(i1 & !i2) begin
- {o1, o2, err} <= 3'b000;
- state <= IDLE;
- end
- if(!i1 & !i2) begin
- {o1, o2, err} <= 3'b111;
- state <= ERROR;
- end
- end
- ERROR: begin
- if(i1) begin
- {o1, o2, err} <= 3'b111;
- state <= ERROR;
- end
- if(!i1) begin
- {o1, o2, err} <= 3'b000;
- state <= IDLE;
- end
- end
- default:begin
- {o1, o2, err} <= 3'b000;
- state <= IDLE;
- end
- endcase
-
- end
-
-
- endmodule
复制代码- // 两段式状态机
-
- module style2_fsm(i_clk, rst_n, i1, i2, o1, o2, err);
-
- input i_clk, rst_n, i1, i2;
- output o1, o2, err;
-
- parameter [3:0] IDLE = 4'b0001,
- S1 = 4'b0010,
- S2 = 4'b0100,
- ERROR= 4'b1000;
-
- reg o1, o2, err;
- reg [3:0] curr_state, next_state;
-
- always @(posedge i_clk or negedge rst_n) begin
- if(!rst_n)
- curr_state <= IDLE;
- else
- curr_state <= next_state;
- end
-
- always @(curr_state or i1 or i2) begin
- case(curr_state)
- IDLE: begin
- if(!i1) begin
- IDLE_OUT;
- next_state = IDLE;
- end
- if(i1 & i2) begin
- S1_OUT;
- next_state = S1;
- end
- if(i1 & !i2) begin
- ERROR_OUT;
- next_state = ERROR;
- end
- end
- S1: begin
- if(!i2) begin
- S1_OUT;
- next_state = S1;
- end
- if(!i1 & i2) begin
- ERROR_OUT;
- next_state = ERROR;
- end
- if(i1 & i2) begin
- S2_OUT;
- next_state = S2;
- end
- end
- S2: begin
- if(i2) begin
- S2_OUT;
- next_state = S2;
- end
- if(i1 & !i2) begin
- IDLE_OUT;
- next_state = IDLE;
- end
- if(!i1 & !i2) begin
- ERROR_OUT;
- next_state = ERROR;
- end
- end
- ERROR: begin
- if(i1) begin
- ERROR_OUT;
- next_state = ERROR;
- end
- if(!i1) begin
- IDLE_OUT;
- next_state = IDLE;
- end
- end
- default:begin
- IDLE_OUT;
- next_state <= IDLE;
- end
- endcase
- end
-
- task IDLE_OUT;
- {o1, o2, err} = 3'b000;
- endtask
-
- task S1_OUT;
- {o1, o2, err} = 3'b100;
- endtask
-
- task S2_OUT;
- {o1, o2, err} = 3'b010;
- endtask
-
- task ERROR_OUT;
- {o1, o2, err} = 3'b111;
- endtask
-
- endmodule
复制代码- // 三段式状态机
-
- module style3_fsm(i_clk, rst_n, i1, i2, o1, o2, err);
-
- input i_clk, rst_n, i1, i2;
- output o1, o2, err;
-
- parameter [3:0] IDLE = 4'b0001,
- S1 = 4'b0010,
- S2 = 4'b0100,
- ERROR= 4'b1000;
-
- reg o1, o2, err;
- reg [3:0] curr_state, next_state;
-
- always @(posedge i_clk or negedge rst_n)
- begin
- if(!rst_n)
- curr_state <= IDLE;
- else
- curr_state <= next_state;
- end
-
- always @(curr_state or i1 or i2)
- begin
- case(curr_state)
- IDLE: begin
- if(!i1) next_state = IDLE;
- if(i1 & i2) next_state = S1;
- if(i1 & !i2) next_state = ERROR;
- end
- S1: begin
- if(!i2) next_state = S1;
- if(i1 & i2) next_state = S2;
- if(!i1 & i2) next_state = ERROR;
- end
- S2: begin
- if(i2) next_state = S2;
- if(i1 & !i2) next_state = IDLE;
- if(!i1 & !i2) next_state = ERROR;
- end
- ERROR: begin
- if(i1) next_state = ERROR;
- if(!i1) next_state = IDLE;
- end
- default:begin
- next_state = IDLE; // 不加这个default项 输出会一直是000!!!
- end
- endcase
- end
-
- always @(posedge i_clk or negedge rst_n)
- begin
- if(!rst_n)
- {o1, o2, err} <= 3'b000;
- else begin
- case(next_state)
- IDLE: {o1, o2, err} <= 3'b000;
- S1: {o1, o2, err} <= 3'b100;
- S2: {o1, o2, err} <= 3'b010;
- ERROR: {o1, o2, err} <= 3'b111;
- default:{o1, o2, err} <= 3'b000;//不加这个default 复位前信号都为不定值X
- endcase
- end
- end
-
-
-
- endmodule
复制代码
完
|