精华内容
下载资源
问答
  • 2018-05-18 14:32:15

           FPGA工程师无时无刻不在接触状态机,那么状态机的编写到底用几段式呢,这个问题会一直困扰FPGA的初学者,而问题的答案似乎都很古老,传统的建议是用二段式或者三段式状态机。

           首先解释一下为什么传统建议使用二段式或者三段式状态机,因为以前的综合工具还不够强大,如果采用一段式编写状态机,组合电路和时序电路在一段代码块里,不利于电路的优化;而两段式、三段式状态机将组合电路、时序电路分开,便于电路的优化。

           当然,随着工具的进步,现在采用几段式编写状态机已经没有那么大的影响,反而一段式状态机能够有效避免毛刺和竞争的出现,更适合初学者或者调试初期使用。在编写两段式、三段式状态机的时候,应该注意毛刺和竞争的产生,在可能的情况下将输出寄存器化。

    更多相关内容
  • 状态机详解(一段式二段式、三段式)

    万次阅读 多人点赞 2018-12-26 17:13:34
    、有限状态机FSM(Finite State Machine) 组成元素: 输入、状态、状态转移条件、输出。 可以分为两类: Mealy状态机:时序逻辑的输出不仅取决于当前状态,还与输入有关; Moore状态机:时序逻辑的输出只...

    一、有限状态机FSM(Finite State Machine)

    • 组成元素

            输入、状态、状态转移条件、输出。

    • 可以分为两类

            Mealy状态机:时序逻辑的输出不仅取决于当前状态,还与输入有关;

            Moore状态机:时序逻辑的输出只与当前状态有关。

    • 描述方式

            ① 状态转移图:设计分析时使用,工具自动翻译的代码效率不高,适合规模小的设计;对于大规模设计,HDL更好;

            ② 状态转移表;

            ③ HDL描述。

    • 设计步骤

            ① 逻辑抽象,得到状态转移图:确定输入、输出、状态变量、画状态转移图;

            ② 状态简化,得到最简的状态转移图:合并等价状态;

            ③ 状态编码:binary、gray、one-hot编码方式;

            ④ 用HDL描述。

    二、Coding Style

    • 一段式

            只有一个always block,把所有的逻辑(输入、输出、状态)都在一个always block的时序逻辑中实现。这种写法看起来很简洁,但是不利于维护,如果状态复杂一些就很容易出错,不推荐这种方法

            在简单的状态机可以使用。

    • 二段式

            有两个always block,把时序逻辑和组合逻辑分隔开来。时序逻辑里进行当前状态和下一状态的切换,组合逻辑实现各个输入、输出以及状态判断。这种写法不仅便于阅读、理解、维护,而且利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。在两段式描述中,当前状态的输出用组合逻辑实现,可能存在竞争和冒险,产生毛刺

            要求对状态机的输出用寄存器打一拍,但很多情况不允许插入寄存器节拍,此时使用三段式描述。其优势在于能够根据状态转移规律,在上一状态根据输入条件判断出当前状态的输出,从而不需要额外插入时钟节拍。

    • 三段式

            有三个always block,一个时序逻辑采用同步时序的方式描述状态转移,一个采用组合逻辑的方式判断状态转移条件、描述状态转移规律,第三个模块使用同步时序的方式描述每个状态的输出。代码容易维护,时序逻辑的输出解决了两段式组合逻辑的毛刺问题,但是从资源消耗的角度上看,三段式的资源消耗多一些。

            模板如下:

    always @ ( posedge clk or negedge rst_n ) 
        begin  
            if ( !rst_n )  
                CS <= IDLE;  
            else  
                CS <= NS;  
        end  
      
    always @*  
        begin  
            NS = 'bx;                   //初始化寄存器,避免生成latch  
            case (CS)                   //注意为CS  
                IDLE: begin  
                      end;  
                S1: begin  
                    end;  
                default:  
                    NS = 'bx;           //与硬件电路一致  
            endcase  
        end  
      
    always @ (posedge clk or negedge rst_n) 
        begin  
            if ( !rst_n ) 
                begin  
                end  
            else 
                begin  
                    ...                 //初始化一组值,避免latch  
                    case (CS/NS)        //这里有2种写法,推荐NS写法(moore型写法) 
                        ...  
                        default: ;  
                    endcase  
                end  
        end  

    下面,举例说明:

            状态转换图如下所示:

    • 一段式:
        //时序逻辑电路
    	always @(posedge clk or negedge rst_n)
    		begin
    			if(!rst_n)
    				begin
    					cstate <= IDLE;
    					cmd <= 3'b000;
    				end
    			else
    				case(cstate)
    					IDLE:
    						if(wr_req)
    							begin
    								cstate <= WR_S1;
    								cmd <= 3'b001;
    							end
    						else if(rd_req)
    							begin
    								cstate <= RD_S1;
    								cmd <= 3'b011;
    							end
    						else
    							begin
    								cstate <= IDLE;
    								cmd <= 3'b000;
    							end
    					WR_S1:	begin
    								cstate <= WR_S2;
    								cmd <= 3'b010;
    							end
    					WR_S2:	begin
    								cstate <= IDLE;
    								cmd <= 3'b000;
    							end
    					RD_S1:
    						if(wr_req)
    							begin
    								cstate <= WR_S2;
    								cmd <= 3'b010;
    							end
    						else
    							begin
    								cstate <= RD_S2;
    								cmd <= 3'b100;
    							end
    					RD_S2:
    						if(wr_req)
    							begin
    								cstate <= WR_S1;
    								cmd <= 3'b001;
    							end
    						else
    							begin
    								cstate <= IDLE;
    								cmd <= 3'b000;
    							end
    					default:	cstate <= IDLE;
    				endcase
    		end

    testbench如下: 

    `timescale 1 ns/ 100 ps
    
    module fsm1_vlg_tst();
    
    	reg clk;
    	reg rd_req;
    	reg rst_n;
    	reg wr_req;                                             
    	wire [2:0]  cmd;
    	wire [2:0]  cstate;
                              
    	fsm1 i1 (   
    		.clk(clk),
    		.cmd(cmd),
    		.cstate(cstate),
    		.rd_req(rd_req),
    		.rst_n(rst_n),
    		.wr_req(wr_req)
    	);
    	always #10 clk = ~clk;
    	
    	initial                                                
    		begin
    			clk = 0;rst_n = 1;
    			wr_req = 0;rd_req = 0;
    			#2 rst_n = 0;
    			#10 rst_n = 1;
    			repeat(100)
    				begin
    					#20 wr_req = {$random}%2;
    						rd_req = {$random}%2;
    				end
    			#100 $stop;
    		end                                                    
                                                        
    endmodule

    功能仿真波形图:

     三段式:

    always block①:时序逻辑

    //1st always block, sequential logic, store current state
    always @(posedge clk or negedge rst_n)
    		if(!rst_n)
    			cstate <= IDLE;
    		else
    			cstate <= nstate;

    always block②:组合逻辑 

    //2nd always block, combinational logic, decide next state
    always @(cstate or wr_req or rd_req)
    		begin
                nstate = 3'bx;
    			case(cstate)
    				IDLE:	if(wr_req)
    							nstate = WR_S1;
    						else if(rd_req)
    							nstate = RD_S1;
    						else
    							nstate = IDLE;
    				WR_S1:		nstate = WR_S2;
    				WR_S2:		nstate = IDLE;
    				RD_S1:	if(wr_req)
    							nstate = WR_S2;
    						else
    							nstate = RD_S2;
    				RD_S2:	if(wr_req)
    							nstate = WR_S1;
    						else
    							nstate = IDLE;
    				default:	nstate = 3'bx;
    			endcase
    		end
    •  注意

            always @(敏感电平信号)需要列举完全,可以用“@*”或者“@(*)”代替;

            case(表达式)中的表达式为“cstate”,即现态

            阻塞赋值“=”;

            default项中“'bx”必须设置,与实际电路一致。

    always block③:时序逻辑 

    //3rd always block, FSM sequential output

    • Mealy型写法
    always @(posedge clk or negedge rst_n)
    		if(!rst_n)
    			cmd <= 3'b000;
    		else
    			case(cstate)
    				IDLE:	if(wr_req)
    							cmd <= 3'b001;
    						else if(rd_req)
    							cmd <= 3'b011;
    						else
    							cmd <= 3'b000;
    				WR_S1:		cmd <= 3'b010;
    				WR_S2:		cmd <= 3'b000;
    				RD_S1:	if(wr_req)
    							cmd <= 3'b010;
    						else
    							cmd <= 3'b100;
    				RD_S2:	if(wr_req)
    							cmd <= 3'b001;
    						else
    							cmd <= 3'b000;
    				default:;
    			endcase
    • 注意

            case(表达式)中的表达式为“cstate”,即现态

            非阻塞赋值“<=”; 

            default项必须设置。

    • Moore型写法
    always @(posedge clk or negedge rst_n)
    		if(!rst_n)
    			cmd <= 3'b000;
    		else
    			case(nstate)
    				IDLE:	cmd <= 3'b000;
    				WR_S1:	cmd <= 3'b001;
    				WR_S2:	cmd <= 3'b010;
    				RD_S1:	cmd <= 3'b011;
    				RD_S2:	cmd <= 3'b100;
    				default:;
    			endcase
    
    endmodule
    • 注意

            case(表达式)中的表达式为“nstate”,即次态,这里使用nextstate和state的区别在于,当状态跳转时,基于nextstate的输   出是立刻变化的,而基于state输出会延迟一个周期,其他情况都一样,应该根据自己的时序要求,选择用nextstate还是state。

            非阻塞赋值“<=”; 

            default项必须设置。

    参考状态机详解,以及三段式状态机的思维陷阱

    展开全文
  • 适合描述那些发生有先后顺序或者有逻辑规律的事情,状态机的本质就是对具有逻辑顺序或时序规律的事件进行描述的种方法,广泛用于多种场合。 因此,掌握有限状态机的Verilog描述方式至关重要;通过许多大神前辈的...

    有限状态机(FSM)的输出取决于过去状态以及当前输入,是时序逻辑电路。适合描述那些发生有先后顺序或者有逻辑规律的事情,状态机的本质就是对具有逻辑顺序或时序规律的事件进行描述的一种方法,广泛用于多种场合。

    因此,掌握有限状态机的Verilog描述方式至关重要;通过许多大神前辈的博客,我了解到状态机的描述具有三种方式,反思自己之前的描述深感逻辑混乱,毫无章法,因此重新对这方面进行学习与记录

    一、FSM的组成

    状态机:状态机描绘状态变迁的状态迁移图,体现了系统对外界事件的反应;
    状态机组成六要素:状态集合,初态,终态,输入符号集,输出符号集,状态转移函数;
    状态机工作四要素:现态 ,次态,输入,输出;

    状态机主要分为三部分:

    状态转移部分,描述状态机在时钟驱动下的状态转移这一过程(现态---次态);

    状态转移条件,之前我们已经知道状态机会不断进行状态转移,但是由当前状态转移为何种状态?也就是次态的取值是什么,这个工作是状态转移条件部分来描述执行;

    输出部分描述状态机的输出,即当前状态下的输出为什么;

    这三部分的描述可以放在Verilog描述过程的不同部分,即对应FSM的三种描述方式;

    二、FSM的三种描述方式

    一段式FSM描述:状态机写在1个always块,既描述状态转移,又描述状态的输入输出;(但是其各部分杂糅,在功能比较复杂的场合会比较混乱,不建议使用)
    二段式FSM描述:鉴于一段式描述的缺点,两段式描述使用2个always块,一个always块利用同步时序逻辑描述状态转移,一个always块利用组合逻辑描述状态转移条件以及输出;(但是输出一般使用组合逻辑描述,而组合逻辑易产生毛刺等不稳定因素,并影响系统执行速率)
    三段式FSM描述:三段式描述应运而生,通过使用3个always块,一个always块利用同步时序逻辑描述状态转移,一个always块利用组合逻辑描述状态转移条件,一个always块利用同步时序逻辑描述输出,避免了前两种描述方式的弊端;

    更详细的描述见下连接:

    基于Verilog HDL的有限状态机

    【 FPGA 】状态机,FPGA的灵魂

    三、仿真:

    按照不同描述方式实现1011序列产生,序列产生的内容详见Verilog实现序列产生器(状态转移形,移位形,计数形)

    而此处只关心状态机的描述方式:

    一段式描述:

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: guoliang CLL
    // 
    // Create Date: 2020/02/21 15:30:18
    // Design Name: 
    // Module Name: seq_gen_fsm1
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module seq_gen_fsm1(
        input clk,
        input rst_n,
        output reg seq
        );
     // state declaration
     parameter s0 = 2'b0,s1 = 2'b1,s2 = 2'b10,s3 = 2'b11;
     reg [1:0]state;
    // 状态转移+状态转移条件+输出
     always@(posedge clk or negedge rst_n)
     begin
        if(!rst_n)
            begin
                state <= s0;
                seq <= 1'b1;
            end
        else
            begin
                case(state)
                s0:begin
                state = s1;
                seq <= 1'b1;
                end
                s1:begin
                state = s2;
                seq <= 1'b0;
                end
                s2:begin
                state = s3;
                seq <= 1'b1;
                end
                s3:begin
                state = s0;
                seq <= 1'b1;
                end
                default:begin
                state = s0;
                seq <= 1'b1;
                end
                endcase
            end
     end
      
    endmodule
    

    二段式描述:

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: guoliang CLL
    // 
    // Create Date: 2020/02/21 15:30:49
    // Design Name: 
    // Module Name: seq_gen_fsm2
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module seq_gen_fsm2(
        input clk,
        input rst_n,
        output reg seq
        );
     // state declaration
     parameter s0 = 2'b0,s1 = 2'b1,s2 = 2'b10,s3 = 2'b11;
     reg [1:0]c_state,n_state;
     // 状态转移
     always@(posedge clk or negedge rst_n)
     begin
        if(!rst_n)
            begin
                c_state <= s0;
            end
        else
            begin
                c_state <= n_state;
            end
     end
    // 状态转移条件+输出
     always@(c_state or rst_n)
     begin
        if(!rst_n)
            begin
                n_state = s0;
            end
        else
            begin
                case(c_state)
                s0:begin
                n_state = s1;
                seq = 1'b1;
                end
                s1:begin
                n_state = s2;
                seq = 1'b0;
                end
                s2:begin
                n_state = s3;
                seq = 1'b1;
                end
                s3:begin
                n_state = s0;
                seq = 1'b1;
                end
                default:begin
                n_state = s0;
                seq = 1'b1;
                end
                endcase
            end
     end
     
    endmodule
    

    三段式描述:

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: guoliang CLL
    // 
    // Create Date: 2020/02/21 00:20:42
    // Design Name: 
    // Module Name: seq_gen_fsm
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module seq_gen_fsm(
        input clk,
        input rst_n,
        output reg seq
        );
     // state declaration
     parameter s0 = 2'b0,s1 = 2'b1,s2 = 2'b10,s3 = 2'b11;
     reg [1:0]c_state,n_state;
     // 状态转移
     always@(posedge clk or negedge rst_n)
     begin
        if(!rst_n)
            begin
                c_state <= s0;
            end
        else
            begin
                c_state <= n_state;
            end
     end
    // 状态转移条件
     always@(c_state or rst_n)
     begin
        if(!rst_n)
            begin
                n_state = s0;
            end
        else
            begin
                case(c_state)
                s0:n_state = s1;
                s1:n_state = s2;
                s2:n_state = s3;
                s3:n_state = s0;
                default:n_state = s0;
                endcase
            end
     end
     // 输出
     always@(posedge clk or negedge rst_n)
     begin
        if(!rst_n)
            begin
                seq <= 1'b0;
            end
        else
            begin
                case(n_state)
                s0:seq <= 1'b1;
                s1:seq <= 1'b0;
                s2:seq <= 1'b1;
                s3:seq <= 1'b1;
                default:seq <= 1'b0;
                endcase
            end
     end
     
    endmodule
    

    测试文件如下:

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: guoliang CLL
    // 
    // Create Date: 2020/02/21 00:35:17
    // Design Name: 
    // Module Name: seq_gen_tsb
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module seq_gen_tsb(
    
        );
    // port
    reg clk;
    reg rst_n;
    wire seq1,seq2,seq3;
    // clk
    initial
    begin
        clk = 1'b1;
        forever #10 clk = ~clk;
    end
    // 
    initial
    begin
        rst_n = 1'b1;
        #15 rst_n = 1'b0;
        #50 rst_n = 1'b1;
    end
    // instantation
    //seq_gen_shift inst(
    //seq_gen_count inst(
    seq_gen_fsm1 inst(
        .clk(clk),
        .rst_n(rst_n),
        .seq(seq1)
    );
    seq_gen_fsm2 inst2(
        .clk(clk),
        .rst_n(rst_n),
        .seq(seq2)
    );
    seq_gen_fsm inst3(
        .clk(clk),
        .rst_n(rst_n),
        .seq(seq3)
    );
    endmodule
    

     输出结果如下:

    可见,两段式与三段式描述输出一致,与理想波形一致;而一段式输出滞后一个时钟周期,原因在于一段式的描述特点,即根据当前状态进行输出的非阻塞赋值,因此输出必然滞后状态一个时钟周期;(二三段式描述为避免这一现象,按照次态选择输出,将非阻塞赋值的时间延迟通过这一方式补偿回来)

    四、参考文献:

    基于Verilog HDL的有限状态机

    【 FPGA 】状态机,FPGA的灵魂

    展开全文
  • 上篇博文讲了:FPGA中有限状态机的状态编码采用格雷码还是独热码? 那篇博文讲了状态机的状态...一段式的描述方法、二段式以及三段式,并比较三者之间的功能仿真情况,最后真心吐露这个案例的状态转移图的疑问?不...

    上篇博文讲了:FPGA中有限状态机的状态编码采用格雷码还是独热码?

    那篇博文讲了状态机的状态编码是用格雷码还是独热码的问题,以及两者之间的优劣。状态机的描述方式采用的是一段式描述方式,也就是将整个状态机全部写到一个always模块中去。

    这篇博文仍用上篇博文的案例,说说状态机的描述方法。一段式的描述方法、二段式以及三段式,并比较三者之间的功能仿真情况,最后真心吐露这个案例的状态转移图的疑问?不能把有问题的地方回避,我想我不要做这样的人。


    首先看看状态机的描述方法,和编码方式,这两段描述借鉴:基于Verilog HDL的有限状态机,人家说的不错,我也懒着码字了。

    状态机的描述方法

    状态机的描述方法多种多样,将整个状态机写到1个always 模块里,在该模块中既描述状态转移,又描述状态的输入和输出,这种写法一般被称为一段式FSM 描述方法;

    还有一种写法是使用两个always模块,其中一个always 模块采用同步时序的方式描述状态转移,而另一个模块采用组合逻辑的方式判断状态转移条件,描述状态转移规律,这种写法被称为两段式FSM 描述方法;

    还有一种写法是在两段式描述方法的基础上发展而来的,这种写法使用3 个always模块,一个always 模块采用同步时序的方式描述状态转移,一个采用组合逻辑的方式判断状态转移条件,描述状态转移规律,第三个always 模块使用同步时序电路描述每个状态的输出,这种写法称为三段式写法。

     

    状态机的状态编码

    二进制码(Binary)和格雷码(Gray)属于压缩状态编码,这种编码的优点是使用的状态向量最少,但是需要较多的逻辑资源用来状态译码。二进制码从一个状态转换到相邻状态时,可能有多个比特位发生变化,易产生中间状态转移问题,状态机的速度也要比采用其它编码方式慢。格雷码两个相邻的码值仅有一位就可区分,这将会减少电路中相邻物理信号线同时变化的情况,因而可以减少电路中的电噪声。Johnson码也有同样的特点,但是要用较多的位数。

    独热码(One-hot)指对任意给定的状态,状态寄存器中只有l位为1,其余位都为0。n状态的有限状态机需要n个触发器,但这种有限状态机只需对寄存器中的一位进行译码,简化了译码逻辑电路,额外触发器占用的面积可用译码电路省下来的面积抵消。当设计中加入更多的状态时,译码逻辑没有变得更加复杂,有限状态机的速度仅取决于到某特定状态的转移数量,而其它类型有限状态机在状态增加时速度会明显下降。独热码还具有设计简单、修改灵活、易于综合和调试等优点。独热码相对于二进制码,速度快但占用面积大。


    给出实际案例:

    下面是一个状态转移图,我们接下来就这个状态转移图来用不同的描述方式来描述。

    1)一段式描述方法:

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date:    21:27:04 09/02/2018 
    // Design Name: 
    // Module Name:    fsm 
    // Project Name: 
    // Target Devices: 
    // Tool versions: 
    // Description: 
    //
    // Dependencies: 
    //
    // Revision: 
    // Revision 0.01 - File Created
    // Additional Comments: 
    //
    //
    module fsm(
        input Clock,
        input rst_n,
        input A,
        output F,
        output G
        );
    reg F, G;
    reg [3:0] state;
    	
    parameter Idle = 4'b1000, Start = 4'b0100, Stop = 4'b0010, Clear = 4'b0001;
    	
    always @(posedge Clock) begin
     
    if(!rst_n) begin
    	state <= Idle;
        F <= 1'b0;
        G <= 1'b0;
    end
    else
    	case(state)
    	
    	Idle: begin
    	if(A) begin
    		state <= Start;
    		G <= 1'b0;
    	end
    	else
    		state <= Idle;
    	end
    	
    	Start: begin
    	if(!A)
    		state <= Stop;
    	else
    		state <= Start;
    		
    	end
    	
    	Stop: begin
    	if(A) begin
    		state <= Clear;
    		F <= 1'b1;
    	end
    	else
    		state <= Stop;
    	
    	end
    	
    	Clear: begin
    	if(!A)begin
    		state <= Idle;
    		F <= 1'b0;
    		G <= 1'b1;
    	end
    	else
    		state <= Clear;
    	
    	end
    	
    	default: state <= Idle;
    	
    	endcase 
    	
    end	
    	
     
    endmodule
    

    给出测试文件,测试文件在这个案例中通用:

    `timescale 1ns / 1ps
    
    
    // Company: 
    // Engineer:
    //
    // Create Date:   23:39:28 09/02/2018
    // Design Name:   fsm
    // Module Name:   G:/modelsim_file/fsm01/fsm_tb.v
    // Project Name:  fsm01
    // Target Device:  
    // Tool versions:  
    // Description: 
    //
    // Verilog Test Fixture created by ISE for module: fsm
    //
    // Dependencies:
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    
    
    module fsm_tb;
    
    	// Inputs
    	reg Clock;
    	reg rst_n;
    	reg A;
    
    	// Outputs
    	wire F;
    	wire G;
    
    	// Instantiate the Unit Under Test (UUT)
    	fsm uut (
    		.Clock(Clock), 
    		.rst_n(rst_n), 
    		.A(A), 
    		.F(F), 
    		.G(G)
    	);
    
    	initial begin
    		// Initialize Inputs	
    		rst_n = 0;
    		A = 0;
    		
    		#30 A = 1;
    		rst_n = 1;
    		#30 A = 0;
    		#20 A = 1;
    		#20 A = 0;
    		
    
    		// Wait 100 ns for global reset to finish
    		#100;
    	
    	end
    	initial begin
    		Clock = 0;		
    		forever #10 Clock = ~Clock;
    	end
          
    endmodule
    
    

    功能仿真:

    两段式描述方法:

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date:    21:27:04 09/02/2018 
    // Design Name: 
    // Module Name:    fsm 
    // Project Name: 
    // Target Devices: 
    // Tool versions: 
    // Description: 
    //
    // Dependencies: 
    //
    // Revision: 
    // Revision 0.01 - File Created
    // Additional Comments: 
    //
    //
    module fsm(
        input Clock,
        input rst_n,
        input A,
        output F,
        output G
        );
    reg F, G;
    reg [3:0] pre_state;
    reg [3:0] next_state;
    
    	
    parameter Idle = 4'b1000, Start = 4'b0100, Stop = 4'b0010, Clear = 4'b0001;
    
    //第一个过程,同步时序always块,描述状态转移方程	
    always @(posedge Clock) begin
    
    if(!rst_n)
    	pre_state <= Idle;
    else
    	pre_state  <= next_state;
    
    	
    end
    //第二个过程,组合逻辑always块,描述激励方程以及输出方程
    always @(pre_state or A or rst_n) begin
    
    case(pre_state)
    
    Idle:begin
    	if(!rst_n) begin
    		next_state = Idle;
    		F = 1'b0;
    		G = 1'b0;
    	end
    	else if(A) begin
    		next_state = Start;
    		G = 1'b0;
    	end
    	else begin
    		next_state = Idle;
    	end		
    end
    
    Start: begin
    	if(!rst_n) begin
    		next_state = Idle;
    		F = 1'b0;
    		G = 1'b0;
    	end
    	else if(!A) begin
    		next_state = Stop;
    	end
    	else begin
    		next_state = Start;
    	end
    end
    
    Stop: begin
    	if(!rst_n) begin
    		next_state = Idle;
    		F = 1'b0;
    		G = 1'b0;
    	end
    	else if(A) begin
    		next_state = Clear;
    		F = 1'b1;
    	end
    	else begin
    		next_state = Stop;
    	end
    end
    	
    Clear: begin
    	if(!rst_n) begin
    		next_state = Idle;
    		F = 1'b0;
    		G = 1'b0;
    	end
    	else if(!A) begin
    		next_state = Idle;
    		F = 0;
    		G = 1;
    	end
    	else begin
    		next_state = Clear;
    	end
    end
    
    default: begin
    	next_state = Idle;
    end
    
    endcase
    
    
    end
    
    
    endmodule
    

    三段式描述:

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date:    21:27:04 09/02/2018 
    // Design Name: 
    // Module Name:    fsm 
    // Project Name: 
    // Target Devices: 
    // Tool versions: 
    // Description: 
    //
    // Dependencies: 
    //
    // Revision: 
    // Revision 0.01 - File Created
    // Additional Comments: 
    //
    //
    module fsm(
        input Clock,
        input rst_n,
        input A,
        output F,
        output G
        );
    reg F, G;
    reg [3:0] pre_state;
    reg [3:0] next_state;
    
    	
    parameter Idle = 4'b1000, Start = 4'b0100, Stop = 4'b0010, Clear = 4'b0001;
    
    //第一个过程,同步时序always块,描述状态转移方程	
    always @(posedge Clock) begin
    
    if(!rst_n)
    	pre_state <= Idle;
    else
    	pre_state  <= next_state;
    
    	
    end
    //第二个过程,组合逻辑always块,描述激励方程
    always @(pre_state or A or rst_n) begin
    case(pre_state)
    
    Idle: begin
    	if(!rst_n) next_state = Idle;
    	else if(A) next_state = Start;
    	else next_state = Idle;
    end
    
    Start: begin
    	if(!rst_n) next_state = Idle;
    	else if(!A) next_state = Stop;
    	else next_state = Start;
    end
    
    Stop: begin
    	if(!rst_n) next_state = Idle;
    	else if(A) next_state = Clear;
    	else next_state = Stop;
    end
    
    Clear: begin
    	if(!rst_n) next_state = Idle;
    	else if(!A) next_state = Idle;
    	else next_state = Clear;
    end
    
    default: next_state = Idle;
    
    endcase
    
    end
    //第三个always块,描述输出方程
    always @(pre_state or A or rst_n) begin
    
    case(pre_state)
    
    Idle:begin
    	if(!rst_n) begin
    		F = 1'b0;
    		G = 1'b0;
    	end
    	else if(A) begin
    		G = 1'b0;
    	end
    	else begin
    	;
    	end		
    end
    
    Start: begin
    	if(!rst_n) begin
    		F = 1'b0;
    		G = 1'b0;
    	end
    	else if(!A) begin
    	;
    	end
    	else begin
    	;
    	end
    end
    
    Stop: begin
    	if(!rst_n) begin
    		F = 1'b0;
    		G = 1'b0;
    	end
    	else if(A) begin
    		F = 1'b1;
    	end
    	else begin
    	;
    
    	end
    end
    	
    Clear: begin
    	if(!rst_n) begin
    		F = 1'b0;
    		G = 1'b0;
    	end
    	else if(!A) begin
    		F = 0;
    		G = 1;
    	end
    	else begin
    	;
    	end
    end
    
    default: begin
    	;
    end
    
    endcase
    
    end
    
    endmodule
    

    功能仿真:


    可见,三种描述方式的仿真图都是一样的,说明了完成同样的功能。

    但是从代码的简洁度来看,就这个小状态转移图来说,无疑,一段式的描述方式是最为简单的。但是随着项目的复杂度增高,这种描述方式不便于维护和阅读。

    所以呢?要综合来看,不能说哪一种一定好,哪一种一定坏,要根据实际情况而定。

    最后我要提出的问题,就是Clear这个状态向Idle这个状态转移的条件:从状态图上看,注意图中的状态图的复位我用rst_n代替,这样更人性化!继续:从状态图上看,是!rst_n或!A有效时,向Idle状态转移,并且输出是F = 0 ,且 G =1;

    但是从原作者的一段式代码中,我们可以看出,复位信号rst_n的优先级别要高,如果复位了,那么状态肯定转向Idle,且此时,输出F=0且G=0.这明显和状态转移图中的意思不一样啊,我们推测状态转移图写法有误,所以这里我个人默认复位信号有限,其次是输入A和当前状态决定输出。也就是说,如果复位信号无效时,当前状态为Clear且 !A有效,那么输出就是F = 0 ,且 G =1,并且状态转向Idle.

     

    展开全文
  • (1)一段式:整个状态机写到一个always模块里面,在该模块中既描述状态转移,又描述状态的输入输出; (2)二段式:用两个always模块来描述状态机,其中一个always模块采用同步时序描述状态转移;另一个模块采...
  • 实例:FSM实现10010串的检测 ... 下状态S1,a = 1,z = 0.如果检测到0,跳转到S2。  下状态S2,a = 0,z = 0.如果检测到0,跳转到S3。  下状态S3,a = 0,z = 0.如果检测到1,跳转到S4。  ...
  • 万物基于状态机,这篇博客是博主根据自己的一些经验详细描述了一段式、两段式、三段式状态机,moore型状态机、mealy型状态机的异同点及优缺点,希望能大家一起努力,共同进步~
  • 1、状态机 1.1、理论 FPGA不同于CPU的一点特点就是CPU是顺序执行的,而FPGA是同步执行(并行)的。...状态机的每个状态代表个事件,从执行当前事件到执行另事件我们称之为状态 的跳转或状态的
  • 后来用VHDL, 看的一本E文的书上, 状态机的例子是典型的二段式(作者也没说明这是两段式),当时还觉得这种写法挺麻烦的,没有一段式的看起来舒服, 当时还没有切身的体会两种的区别以及一段式的劣处. 后来在一段式状态机...
  • 、分布式数据一致性 在分布式系统中,为了保证数据的高可用,通常会将数据保留多个副本(replica),这些副本会放置在不同的物理的机器上。 (1)什么是数据一致性 在数据有多份副本的情况下,如果网络、服务器...
  • 具体描述时方法各种各样,有的设计者习惯将整个状态机写到1 个always 模块里面,在该模块中即描述状态转移,又描述状态的输入输出,这种写法一般被称为一段式FSM 描述方法; 还有一种写法是用2 个always 模块,...
  • 设计题目:将下列状态图分别用一段式二段式、三段式状态机实现 如下图用verilog实现 1、一段状态机 一个模块既包含状态转移,又包含组合逻辑输入/输出。 `timescale 1ns / 1ps ///////////////////////////...
  • (1)一段式:整个状态机写到一个always模块里面,在该模块中既描述状态转移,又描述状态的输入输出; (2)二段式:用两个always模块来描述状态机,其中一个always模块采用同步时序描述状态转移;另...
  • 二段式FPGA的状态机

    千次阅读 2016-10-02 09:22:01
    数字系统有两大类有限状态机(Finite State Machine,FSM):Moore状态机Mealy状态机。 Moore状态机  其最大特点是输出只由当前状态确定,与输入无关。Moore状态机的状态图中的每个状态都包含个输出...
  • 分布式事务之——两段式、三段式

    千次阅读 2019-08-26 23:15:00
    、两段式 1、请求阶段(commit-request phase,或称表决阶段,voting phase) 事务询问。协调者向所有参与者发送事务内容,询问是否可以进行事务提交操作,然后就开始等待参与者的响应。 执行事务。各参与者...
  • 内存管理

    千次阅读 2019-03-18 20:23:54
    内存管理的概念   页存储管理能有效地提高内存利用率,而分段存储管理能反映程序的逻辑结构并有利于的共享。如果将这两种存储管理方法结合起来,就形成了存储管理方式。   管理就是将...
  • Windows内存管理方式主要分为:页式管理、段式管理段页式管理 首先看一下“基本的存储分配方式”种类:   1. 离散分配方式的出现  由于连续分配方式会形成许多内存碎片,虽可通过“紧凑”功能...
  • 1、段式和页式存储管理的地址结构很类似,但是它们有实质上的不同,以下错误的是(D)   A.页式的逻辑地址是连续的,段式的逻辑地址可以不连续   B.页式的地址是维的,段式的地址是维的   C.分页是...
  • 从页式管理开始,到之后的段式管理,都与之前的分区管理不同,最大的区别就在于个是分区管理是连续存储,这两种方式可以非连续。 实现原理 首先是必要概念: 物理块:将物理存储空间划分为大小相等的若干存储块...
  • 很长一段时间,我都搞不懂这三个地址到底是怎么回事,因为中间牵扯着地址转换,各种寄存器,各种描述符,描述表,每次看书看着看着就彻底晕菜了。 物理地址:最容易理解的,它就是实实在在物理内存上的地址,你PC...
  • VHDL三段式状态机

    千次阅读 2018-03-26 17:02:38
    ------------状态机第二段,各个状态之间的转移 begin case pr_state is  when integretion =>  if(ack1='1')then  nx_state; else nx_state; end if;  when read_line =>  if(dck='1')then nx_state; ...
  • 段式过流保护、差动保护

    千次阅读 2021-08-09 13:34:21
    1、基本原理 供电系统中的线路、设备等故障,会产生短路电流。短路电流比线路正常工作时大很多。通过电流互感器测量这个电流值...主保护:二段,不快也不慢。既能等待下级跳开,也能保护本级,并备用下级。 ...
  • 段式管理(segmentation),是指把个程序分成若干个段(segment)进行存储,每个段都是个逻辑实体(logical entity),程序员需要知道并使用它。它的产生是与程序的模块化直接有关的。段式管理是通过段表进行的...
  • 一段二段,三段电流保护

    千次阅读 2016-07-17 13:42:07
    电流二段:动作电流整定值较小,动作时间通常为0.5秒,又称“过流保护”,主要用于应对本条线路末端短路故障并作为下一段线路故障的后备保护。 电流三段:动作电流整定值最小(仅比额定电流大20%-50%),动作时间
  • 段式状态机的写法总结

    千次阅读 2017-10-19 23:23:46
    此前在写状态机时总是在构思好转移图后直接一气呵成,写成了if else ...三段式状态机顾名思义,分为三部分,阻塞赋值,非阻塞赋值 reg [ n-1:0]current_state;// n的值根据自己的需要确定 reg [ n-1:0]next_stat
  • 目录页式存储管理段式存储管理分页分段存储管理的主要区别段页式存储管理 页式存储管理 1. 基本原理 页式存储管理是把主存储器划分成大小相等的若干区域,每个区域称为块,并对它们加以顺序编号,如0#块、1#块...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 710,979
精华内容 284,391
关键字:

一段式和二段式