有限状态机简介 有限状态机(FSM)是许多数字系统中用来控制系统和数据流路径行为的时序电路。FSM的实例包括控制单元和时序。 本实验介绍了两种类型的FSM(Mealy和Moore)的概念,以及开发此类状态机的建模方式。 请参阅Vivado教程,了解如何使用Vivado工具创建项目和验证数字电路。 实验目标在本次实验中,你将会学到: 下面是奇偶校验校验机的状态图和相关模型: module mealy_2processes(input clk, input reset, input x, output reg parity); reg state, nextstate;parameter S0=0, S1=1;always @(posedge clk or posedge reset) // always block to update state if (reset)state <= S0;elsestate <= nextstate;always @(state or x) // always block to compute both output & nextstate beginparity = 1'b0; case(state)S0: if(x)beginparity = 1; nextstate = S1;end elsenextstate = S0;S1: if(x)nextstate = S0;else beginparity = 1; nextstate = S1;endend default:nextstate = S0; endcaseendmodule
三段式Mealy机器的图示及其建模如下: module mealy_3processes(input clk, input reset, input x, output reg parity); reg state, nextstate;parameter S0=0, S1=1;always @(posedge clk or posedge reset) // always block to update state if (reset)state <= S0;elsestate <= nextstate;always @(state or x) // always block to compute output beginparity = 1'b0; case(state)S0: if(x)parity = 1; S1: if(!x)parity = 1;endcase endalways @(state or x) // always block to compute nextstate beginnextstate = S0; case(state)S0: if(x)nextstate = S1; S1: if(!x)nextstate = S1; endcaseend endmodule
状态分配可以使用独热码(one – hot code),二进制编码,格雷码以及其他编码。通常,综合工具将确定状态分配的编码,但用户也可以通过更改综合属性来强制特定编码,如下所示。状态分配编码将对状态寄存器中使用的位数产生影响;独热编码使用最多的位数,但解码非常快,二进制编码使用最少的位数,但解码较长。 v 使用三段式Mealy状态机的实现一个序列检测器实验要求Mealy状态机有一个输入(ain)和一个输出(yout)。 当且仅当接收到的1的总数可被3整除时,输出为1(提示:0也算被3整除,但是,在复位周期中不把计数器归为0,复位信号过后把计数器归0——参考模拟波形时间= 200。设计一个testbench并通过behavioral simulation验证模型。 使用SW15作为时钟输入,SW0作为输入,BTNU按钮作为电路的复位输入,LED7:LED4上的1s计数和作为yout输出的LED0。 完成设计流程,生成比特流,并将其下载到Basys3或Nexys4 DDR板。验证功能。 实验步骤打开Vivado并创建一个空工程并命名为lab10_1。 创建并添加使用SW15作为时钟输入,SW0作为输入,BTNU按钮作为电路的复位输入,LED7:LED4上的1s计数和作为yout输出的LED0。 编写仿真文件来验证代码的正确 在工程中添加适当的管脚约束的XDC文件,并加入相关联的管脚,使用SW15作为时钟输入,SW0作为输入,BTNU按钮作为电路的复位输入,LED7:LED4上的1s计数和作为yout输出的LED0。 综合,实现设计。 生成比特流文件,下载到Nexys4开发板上,验证功能。 参考代码和分析module lab10_1( input clk, input rst, input ain, output reg [3:0]count, output reg yout );
parameter s0=0, s1=1,s2=2; reg [1:0]state,nextstate; always@(posedge clk or posedge rst) begin if(rst) begin state<=s0; count<=4’b0; end else begin state<=nextstate; if(ain) count<=count+1; end end always@(*) begin yout=0; case(state) s0:if(!ain) yout=1; s2:if(ain) yout=1; endcase end always@(*) begin case(state) s0:if(ain) nextstate=s1; else nextstate=s0; s1:if(ain) nextstate=s2; else nextstate=s1; s2:if(ain) nextstate=s0; else nextstate=s2; endcase end endmodule 米利型的输出是和当前状态以及输入都相关的,所以这里是这样的情况。但是如果是摩尔型的话输入只与当前状态相关,之后也会有介绍。 ## Moore FSM(摩尔型有限状态机) Moore型有限状态机的一般模型如下所示。 其输出由状态寄存器块生成。 使用当前输入和当前状态确定下一状态。 这里的状态寄存器也使用D触发器建模。 通常,Moore机器使用三个块来描述,其中一个块必须是顺序的,另外两个块可以使用always块或always和dataflow建模结构的组合来建模。
v 以下是使用Moore型有限状态机实现的奇偶校验器的状态图。与之关联模型如下所示。 v module moore_3processes(input clk, input reset, input x, output reg parity); reg state, nextstate;parameter S0=0, S1=1;always @(posedge clk or posedge reset) // always block to update state if (reset)state <= S0;elsestate <= nextstate;always @(state) // always block to compute output begincase(state)S0: parity = 0; S1: parity = 1;endcaseendalways @(state or x) // always block to compute nextstate beginnextstate = S0; case(state)S0: if(x)nextstate = S1; S1: if(!x)nextstate = S1;endcaseendendmodule
在本例中,输出块很简单,可以使用dataflow建模构造进行建模。 可以使用以下代码代替always块。 您还需要将输出类型从reg更改为wire。 assign parity = (state==S0) ? 1'b0: 1'b1; ## 使用三段式Moore状态机的实现一个序列检测器 ### 实验要求 Moore状态机有一个输入(ain)和一个输出(yout)。 当且仅当接收到的1的总数可被3整除时,输出为1(提示:0也算被3整除,但是,在复位周期中不把计数器归为0,复位信号过后把计数器归0——参考模拟波形时间= 200。设计一个testbench并通过behavioral simulation验证模型。 使用SW15作为时钟输入,SW0作为输入,BTNU按钮作为电路的复位输入,LED7:LED4上的1s计数和作为yout输出的LED0。 完成设计流程,生成比特流,并将其下载到Basys3或Nexys4 DDR板。验证功能。
实验步骤打开Vivado并创建一个空工程并命名为lab10_2。 创建并添加使用SW15作为时钟输入,SW0作为输入,BTNU按钮作为电路的复位输入,LED7:LED4上的1s计数和作为yout输出的LED0。 编写仿真文件来验证代码的正确 在工程中添加适当的管脚约束的XDC文件,并加入相关联的管脚,使用SW15作为时钟输入,SW0作为输入,BTNU按钮作为电路的复位输入,LED7:LED4上的1s计数和作为yout输出的LED0。 综合,实现设计。 生成比特流文件,下载到Nexys4开发板上,验证功能。 参考代码和分析module lab10_2( input clk, input rst, input ain, output reg [3:0]count, output reg yout );
parameter s0=0, s1=1,s2=2; reg [1:0]state,nextstate; always@(posedge clk or posedge rst) begin if(rst) begin state<=s0; count<=4’b0; end else begin state<=nextstate; if(ain) count<=count+1; end end always@() begin case(state) s0:yout=1; default:yout=0; endcase end always@() begin case(state) s0:if(ain) nextstate=s1; else nextstate=s0; s1:if(ain) nextstate=s2; else nextstate=s1; s2:if(ain) nextstate=s0; else nextstate=s2; endcase end endmodule
摩尔型相较米利型输出的状态只与输入相关 扩展实验内容扩展实验1使用三段式Moore状态机或者Mealy状态机实现一个序列检测器。
Moore状态机有两个输入(ain [1:0])和一个输出(yout)。 除非出现以下输入序列之一,否则输出将从0开始并保持为常量值: 扩展实验2使用ROM设计一个特定的计数计数器(下面列出的计数序列)来开发一个Mealy状态机。 实验要求打开Vivado并创建一个空工程并命名为lab10_kuozhan2。设计一个testbench并通过behavioral simulation验证模型。 使用SW15作为时钟输入,BTNU按钮作为电路的复位输入,LED2:LED0作为计数器的计数输出。 完成设计流程,生成比特流,并将其下载到Basys3或Nexys4 DDR板。 验证功能。
计数序列是: 000, 001, 011, 101, 111, 010 (repeat) 000, … 总结在这个实验中,您学习了Mealy和Moore状态机建模方法。还设计并实现了序列检测器、序列生成器和编码转换器,实践了两段和三段式的状态机。
|