FPGA——关于状态机
2018-01-19 16:34
120 查看
状态机,是我大二在实验室学习时,学长给我们安排的任务之一。那个时候,我还没有学过《数电》,一直搞不明白状态机的意思,做了一周,都没有结果。
任务是检测序列,检测到1011时输出一个高电平。
我们都知道verilog语言依靠不同的always语句块实现了硬件电路的并行执行,但是在工程中,我们不仅要处理并行执行电路,偶尔也会遇到需要串行执行的电路要求。刚开始学习FPGA的话,可能会想到我们可以利用很多很多的使能信号实现,但是这样维护的成本大大增加。状态机就可以完美的实现这一功能。先简单介绍一下状态机的基本概念。
状态机的基本要素是输入、输出和状态。输入是引起状态变化的条件,输出是状态变化引起的变化。状态就是字面理解的意思了,状态机,通俗的说就是因为输入导致状态在不断的变化的硬件电路。
Moore型状态机的输出仅与状态有关,与输入无关。
Mealy型状态机的输入不仅与状态有关,还与输入条件有关。
一段式写法,输入、输出和状态在一个always语句块中,后期不容易维护。
module pro( input clk, input rst_n, input data, output cntout ); parameter INITIALSTATE = 5'b00_001, STATE_0 = 5'b00_010, STATE_1 = 5'b00_100, STATE_2 = 5'b01_000, STATE_3 = 5'b10_000; //———————————————————————————————————————————— //一段式写法, 既把输入、输出和状态写在一个always语句块 reg[4:0] state_ce; //状态寄存器 reg cnt; always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin cnt <= 1'b0; state_ce <= INITIALSTATE; end else case(state_ce) INITIALSTATE: begin cnt <= 1'b0; if(data == 1'b1) state_ce <= STATE_0; else state_ce <= INITIALSTATE; end STATE_0: if(data == 1'b0) state_ce <= STATE_1; else state_ce <= STATE_0; STATE_1: if(data == 1'b1) state_ce <= STATE_2; else state_ce <= INITIALSTATE; STATE_2: if(data == 1'b1) state_ce <= STATE_3; else state_ce <= STATE_1; STATE_3: begin state_ce <= INITIALSTATE; cnt <= 1'b1; end endcase end assign cntout = cnt; endmodule
二段式写法,分成了组合逻辑和时序逻辑。时序逻辑里作状态的转移,组合逻辑里作输入条件判断和输出。但是组合逻辑输出容易出现毛刺问题。
module pro( input clk, input rst_n, input data, output cntout ); parameter INITIALSTATE = 5'b00_001, STATE_0 = 5'b00_010, STATE_1 = 5'b00_100, STATE_2 = 5'b01_000, STATE_3 = 5'b10_000; reg[4:0] state_ce; reg[4:0] state_nt; reg cnt; always @ (posedge clk or negedge rst_n) begin if(!rst_n) state_ce <= INITIALSTATE; else state_ce <= state_nt; end always @ (state_ce or data) begin case(state_ce) INITIALSTATE: begin cnt = 1'b0; if(data == 1'b1) state_nt = STATE_0; else state_nt = INITIALSTATE; end STATE_0: begin cnt = 1'b0; if(data == 1'b0) state_nt = STATE_1; else state_nt = STATE_0; end STATE_1: begin cnt = 1'b0; if(data == 1'b1) state_nt = STATE_2; else state_nt = INITIALSTATE; end STATE_2: begin if(data == 1'b1) state_nt= STATE_3; else state_nt =STATE_1; end STATE_3: begin cnt = 1'b1; state_nt = INITIALSTATE; end endcase end assign cntout = cnt; endmodule
三段式写法,又将输出写作时序逻辑输出,解决了二段式中毛刺的问题。
module pro( input clk, input rst_n, input data, output cntout ); parameter INITIALSTATE = 5'b00_001, STATE_0 = 5'b00_010, STATE_1 = 5'b00_100, STATE_2 = 5'b01_000, STATE_3 = 5'b10_000; reg[4:0] state_ce; reg[4:0] state_nt; reg cnt; always @ (posedge clk or negedge rst_n) begin if(!rst_n) state_ce <= INITIALSTATE; else state_ce <= state_nt; end always @ (state_ce or data) begin case(state_ce) INITIALSTATE: if(data == 1'b1) state_nt = STATE_0; else state_nt = INITIALSTATE; STATE_0: if(data == 1'b0) state_nt = STATE_1; else state_nt = STATE_0; STATE_1: if(data == 1'b1) state_nt = STATE_2; else state_nt = INITIALSTATE; STATE_2: if(data == 1'b1) state_nt = STATE_3; else state_nt = STATE_2; STATE_3: state_nt = INITIALSTATE; endcase end always @ (posedge clk or negedge rst_n) begin if(!rst_n) cnt <= 'd0; else if(state_nt == STATE_3) cnt <= 1'b1; else cnt <= 1'b0; end assign cntout = cnt; endmodule
相关文章推荐
- 关于 FPGA 和 外部芯片接口时序设计
- FPGA状态机跑飞原因分析
- 关于FPGA逻辑设计的21个小贴士
- WF - 关于状态机工作流
- 关于FPGA的保持时间不满足
- 关于FPGA学习的几个问题
- 关于在FPGA上实现AES算法的笔记
- 【转】关于FPGA中建立时间和保持时间的探讨
- FPGA/CPLD状态机稳定性研究
- 对于FPGA状态机的设计心得
- 关于状态机的思想问题
- 关于FPGA逻辑设计的21个小贴士
- fpga状态机详解
- 状态机--状态机4,关于战斗中负责兵种状态切换的状态机
- FPGA三段式状态机的思维陷阱
- 关于状态机 finite-state machine
- 关于FPGA学习的几个问题
- 关于FPGA软核的一些总结(microblaze && NIOS II)
- 关于FPGA中的块RAM和分布式RAM
- 关于 状态机中的组合逻辑