• FPGA,verilog程序技巧之状态机与稳定性,高速


                 关于FPGA的verilog语言的书,已经有很多很多了,甚至程序的写作标准也很完善了。本人FPGA入行两年,对很多的小问题,还有百度上很容易能想到,能看到的,我就不在描述,必定意义不大。对刚入门的FPGA的朋友,你们暂时还涉及不到稳定性问题。关于小白们,我能给你们的意见是,多百度,上面可以帮你解决,前2年遇到的所有问题。

               状态机的重要性,写过一两年程序的人都知道,不用多说了吧。直接上重点。

               第一个:输出信号填写问题,下面是我转载的一些能百度的到的东西。好像都比较正常。这里我还要强调的是,每个状态机的输出信号都需要全面。

    举例:

    always @ (posedge clk or negedge rst_n)              这里的状态机简单的描述,其实还有很多状态。

    ...//初始化                                              out3在s1  s2输出都是一样的,在状态跳转从s1跳到s2的

     case(next_state)                                                    时候out3会在s1处所存,所以就算在s2的地方不写一次out3 <= 1'b0 ;情况S1:                                                                         也是是输出0.对状态机要求高的话,需要这么写。

      out1 <= 1'b1;  

     out2 <= 1'b0;  

    out3 <= 1'b0;       //看这里    

    S2:

      out2 <= 1'b0;

     out2 <= 1'b1;

    out3 <= 1'b0 ;            //看这里    

    default:...    

    endcase

    end

                         第二个:程序输出结构。看程序应该能懂,不需要太多解释吧。

    举例:

    always @ (posedge clk or negedge rst_n)        

    case (next_state)                                                                                           

    S1:                                                                                                                      

    out1 <= 1'b1;                 //看这里                                          所有的不受if控制的输出都要写到if的外面。

     out2 <= 1'b0;                  

    if (x)                  

       out3 <= 1'b0;

    else

       out3 <=1'b1;

    S2:

      out2 <= 1'b0;       //看这里   

     out2 <= 1'b1;

    if (y)

       out3 <= 1'b0;

    else

       out3 <=1'b1;

    default:...    

    endcase

    end

                                        第三个。三段式(多段式)。简单描述就是将第三段的输出,在分为多段。

    举例:(我不知道我这么写例子是否恰当,只能表达一个意思吧)

    always @ (posedge clk or negedge rst_n)        

    case (next_state)                                                                                           

    S1:                                                                                                                      

    out1 <= 1'b1;            

     out2 <= 1'b0;                  

    S2:

      out2 <= 1'b0;      

     out2 <= 1'b1; 

    default:...    

    endcase

    end

    -------------------------------------------------------------------

    always @ (posedge clk or negedge rst_n)        

    case (next_state)                                                                                           

    S1:                                                                                                                                     

    if (x)                  

       out3 <= 1'b0;

    else

       out3 <=1'b1;

    S2:

    if (y)

       out3 <= 1'b0;

    else

       out3 <=1'b1;

    default:...    

    endcase

    end

                                             第四个。状态机的拆分,讲连续变化的状态机,从大的状态机里面拿出来。我只能这么说,没办法举例子了。这里涉及的编程思想也比较多了,没法描述但是要有这个思想。

                                              第五个。独热码好像有时候也不够稳定。你可以使用fifo来做状态缓存。当然这里只是理论概念,因为我还没写过,三段式,独热码,程序拆分后,还是不稳定的程序。但是如果以上内容你都做了,速度和稳定性还不够,你可以考虑的。主要的想法是这样的,fifo在多时钟域都可以良好的切换,就说明它的亚稳态现象很低,为什么状态机不稳定,就是对状态采样的时候,出现的问题。所以,它应该能做到更好的效果。

    微笑本人能力有限,但努力奉献我的知识,希望各位朋友可以快速成长。

    -----------------------------------百度上截取--------------------------------------------------------------

    Verilog有限状态机三段式描述方法

    PART1

    1、好的状态机标准

    好的状态机的标准很多,最重要的几个方面如下:

    第一,状态机要安全,是指FSM不会进入死循环,特别是不会进入非预知的状态,而且由于某些扰动进入非设计状态,也能很快的恢复到正常的状态循环中来。这里面有两层含义:其一要求该FSM的综合实现结果无毛刺等异常扰动;其二要求FSM要完备,即使受到异常扰动进入非设计状态,也能很快恢复到正常状态。

    第二,状态机的设计要满足设计的面积和速度的要求。

    第三,状态机的设计要清晰易懂、易维护。


    2、状态机描述方法

    状态机描述时关键是要描述清楚几个状态机的要素,即如何进行状态转移每个状态的输出是什么状态转移的条件等。具体描述时方法各种各样,最常见的有三种描述方式:

    (1)一段式:整个状态机写到一个always模块里面,在该模块中既描述状态转移,又描述状态的输入和输出;

    (2)二段式:用两个always模块来描述状态机,其中一个always模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件描述状态转移规律以及输出

    (3)三段式:在两个always模块描述方法基础上,使用三个always模块,一个always模块采用同步时序描述状态转移,一个always采用组合逻辑判断状态转移条件,描述状态转移规律,另一个always模块描述状态输出(可以用组合电路输出,也可以时序电路输出)


    一般而言,推荐的FSM  描述方法是后两种。这是因为:FSM和其他设计一样,最好使用同步时序方式设计,以提高设计的稳定性,消除毛刺。状态机实现后,一般来说,状态转移部分同步时序电路状态的转移条件的判断组合逻辑


    第二种描述方法同第一种描述方法相比,将同步时序和组合逻辑分别放到不同的always模块中实现,这样做的好处不仅仅是便于阅读、理解、维护,更重要的是利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。

    在第二种方式的描述中,描述当前状态的输出用组合逻辑实现,组合逻辑很容易产生毛刺,而且不利于约束,不利于综合器和布局布线器实现高性能的设计。

    第三种描述方式与第二种相比,关键在于根据状态转移规律,在上一状态根据输入条件判断出当前状态的输出,从而在不插入额外时钟节拍的前提下,实现了寄存器输出。


    PART2

    时序电路的状态是一个状态变量集合,这些状态变量在任意时刻的值都包含了为确定电路的未来行为而必需考虑的所有历史信息。

    状态机采用VerilogHDL语言编码,建议分为三个always段完成。


    三段式建模描述FSM的状态机输出时,只需指定case敏感表为次态寄存器,然后直接在每个次态的case分支中描述该状态的输出即可,不用考虑状态转移条件。

    三段式描述方法虽然代码结构复杂了一些,但是换来的优势是:使FSM做到了同步寄存器输出,消除了组合逻辑输出的不稳定与毛刺的隐患,而且更利于时序路径分组,一般来说在FPGA/CPLD等可编程逻辑器件上的综合与布局布线效果更佳。

    示列如下:

     

    //第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器

    always @ (posedge clk or negedge rst_n)   //异步复位

     if(!rst_n)

      current_state <= IDLE;

     else

      current_state <= next_state;  //注意,使用的是非阻塞赋值

     

    //第二个进程,组合逻辑always模块,描述状态转移条件判断

    always @ (current_state)       //电平触发

     begin

       next_state = x; //要初始化,使得系统复位后能进入正确的状态

       case(current_state)

       S1: if(...)

          next_state = S2;          //阻塞赋值

       ...

       endcase

    end

     

    //第三个进程,同步时序always模块,格式化描述次态寄存器输出

    always @ (posedge clk or negedge rst_n)

    ...//初始化

     case(next_state)

    S1:

      out1 <= 1'b1;               //注意是非阻塞逻辑

    S2:

      out2 <= 1'b1;

    default:...     //default的作用是免除综合工具综合出锁存器

    endcase

    end

     

     

    两段式有限状态机与三段式有限状态机的区别

    FSM将时序部分(状态转移部分)和组合部分(判断状态转移条件和产生输出)分开,写为两个always语句,即为两段式有限状态机。
    将组合部分中的判断状态转移条件和产生输入再分开写,则为三段式有限状态机。
    区别:
    二段式在组合逻辑特别复杂时适用,但要注意需在后面加一个触发器以消除组合逻辑对输出产生的毛刺。三段式没有这个问题,由于第三个always会生成触发器。
    设计时注意方面:
    1.编码原则

    binarygray-code适用于触发器资源较少,组合电路资源丰富的情况CPLD),对于FPGA,适用one-hot code。这样不但充分利用FPGA丰富的触发器资源,还因为只需比较一个bit,速度快,组合电路简单。

    2.FSM初始化问题:
    GSR(Gobal Set/Reset)只是在加电时清零所有的reg和片内ram,并不保证FSM能进入初始化状态,要利用GSR,方案是适用one-hot code with zero idle,即初始状态编码为全零。已可以适用异步复位rst
    3.FSM输出可以适用task
    4FSM中的case最好加上default,默认态可以设为初始态
    5.尤其注意
    第二段的always(组合部分,赋值用=)里面判断条件一定要包含所有情况!可以用else保证包含完全。
    6第二段always,组合逻辑电平要维持超过一个clock,仿真时注意。

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------

  • 相关阅读:
    项目经理成长之路-初入职场(二)
    项目经理成长之路-我的大学(一)
    别了郑州,2020再出发
    RPC协议实践入门
    Spark学习进度11-Spark Streaming&Structured Streaming
    使用Python自动填写问卷星(pyppeteer反爬虫版)
    All mirror URLs are not using ftp, http[s] or file.
    2018蓝桥杯A组省赛A,B,C,D
    Spark学习进度10-DS&DF基础操作
    SparkSQL学习进度9-SQL实战案例
  • 原文地址:https://www.cnblogs.com/maohuawang/p/3807225.html
Copyright © 2020-2023  润新知