微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 求教一下状态机的状态跳转问题

求教一下状态机的状态跳转问题

时间:10-02 整理:3721RD 点击:
先说明一下常见的状态机写法:
  2段式:一个时序逻辑,一个组合逻辑(状态跳转和决定输出)。
  3段式:2个时序逻辑,一个组合逻辑控制状态跳转。
最近在看到他人的代码的时候,对有些状态机的写法还不是很明了,上来求教一下大家.
always @(posedge clk or negedge rst_n)
begin : TX_STAT_UPDATE
    if (~rst_n) begin
        rStatTxCur      <= TX_IDLE;
        rPlsStatChanged <= 1'b0;
    end
    else begin
        rStatTxCur      <= rStatTxNext;                         //  更新当前发送器的状态机状态
        rPlsStatChanged <= (rStatTxCur != rStatTxNext);
    end
end
/*********************************************************************************************************
** 根据多个信号和当前状态机的状态, 判断发送器状态机的下一个状态
**
** [特别注意]:
** 状态值使用OneHot编码, 而这种编码一般会优为移位寄存器, 为了防止状态出现00000的情况(如时钟质量差),
** 在综合器中要设置'safe stat mechine = on'(安全状态机)
********************************************************************************************************/
always @(
    rPlsBaudTick or
    wFlgTxStart or
    rStatTxCur or
    rTxClkCnt or
    rTxBitCnt or
    wDatWid or
    wFlgParEn or
    wFlgParMod or
    clk_en or
    wStopBits or
    enable
    )
begin : TX_NEXT_STAT_JUDGE
    case (rStatTxCur)                                           //  根据当前状态机的状态, 判断输入信号, 得
                                                                //  到发送器状态机的下一个状态
    TX_IDLE: begin                                             
        if (wFlgTxStart && enable)                              //  当模块端口的发送数据标志有效, 则启动发送事件
            rStatTxNext <= TX_READY;
        else
            rStatTxNext <= TX_IDLE;
    end
   
    TX_READY: begin
        if (clk_en) begin                                       //  同步UART时钟
            rStatTxNext <= TX_START;                            //  进入发送器状态机的发送起始位状态
        end
        else begin
            rStatTxNext <= TX_READY;
        end
    end
    TX_START: begin
        if (rPlsBaudTick)                                       //  持续一个波特位, 进入帧的数据位状态
            rStatTxNext <= TX_DATA;
        else
            rStatTxNext <= TX_START;
    end
   
    TX_DATA:
    begin
        if ( (rTxBitCnt == wDatWid) && (rPlsBaudTick) ) begin   //  当逐位发送完帧格式设置的位数后, 进入下一状态
            if (wFlgParEn)
                rStatTxNext <= TX_PARITY;                       //  如果使能校验位, 则进入校验状态
            else
                rStatTxNext <= TX_STOP1;                        //  否则进入停止位状态
        end
        else begin
            rStatTxNext <= TX_DATA;
        end
    end
    TX_PARITY: begin
        if (rPlsBaudTick)
            rStatTxNext <= TX_STOP1;                            //  持续一个波特位后, 进入停止位状态
        else
            rStatTxNext <= TX_PARITY;
    end
    TX_STOP1: begin
        if (rPlsBaudTick) begin
            if (wStopBits)                                      //  如果设置了2个停止位, 则再进入停止位
                rStatTxNext <= TX_STOP2;
            else
                rStatTxNext <= TX_DONE;
        end
        else begin
            rStatTxNext <= TX_STOP1;
        end
    end
    TX_STOP2: begin
        if (rPlsBaudTick)
            rStatTxNext <= TX_DONE;
        else
            rStatTxNext <= TX_STOP2;
    end
    TX_DONE: begin
        rStatTxNext <= TX_IDLE;                                 //  再次进入空闲状态
    end
   
    default: begin
        rStatTxNext <= TX_IDLE;
    end
    endcase
end
还有一个always块代码没列出,这个是时序逻辑,问题就出在上面的第二个always模块,它里面用的是非阻塞赋值方式来进行状态的跳转以及判断的,有哪个大虾给解释一下这样做有什么优缺点么?虽然自己也这样写过,但对这个用法还是很迷糊。希望能得到大家的指点。

我看你第二个always是阻塞方式描述的呀?难道<=是非阻塞?

我觉得 这段always语句用 阻塞 和非阻塞的效果应该差不多...
  阻塞我感觉类似于顺序执行,而非阻塞则类似于并行,现在整个always语句中间下面的if语句只有一个短句
所以阻塞和非阻塞时一个效果....

第二段always用阻塞和非阻塞是一样的,不过一般编码风格是推荐用非阻塞赋值的



    现在是一个语句这样赋值,效果是一样的,但如果有多个语句的话,那<=和=的赋值效果还一样么?求教了。



    现在是一个语句这样赋值,效果是一样的。但如果有多个语句这样赋值的话,那<=和=的赋值效果还一样么?求教了。

状态机无所谓怎么写,只要判断转移条件合理就行了,=和=〉在verilog中的用法和状态机没什么关系,关键是你可能还没仔细看过verilog方面的教程之类的书,你只要搞清楚组合逻辑和时序逻辑怎样书写就不会有这样的疑问了



    恩,是这么说的,这一次我想把这个问题搞懂,以免在以后的过程中又出现问题,
   阻塞、非阻塞赋值是没错,但如果理解错了,就真的错了,这个影响到对结果的引用。希望你能多指点些。非常感谢!

看看啥!

建议将每一个verilog的写法都能对应到具体的物理电路上。
如果实现的是一个组合逻辑,用什么能表示呢?

路过  围观!

理论上应该是有区别的,至于在仿真的时候会不会出现问题就不知道了,
我的理解是应该会出现差异



   恩,我觉得也是,应该是有差异的。这个是描述语言而不是设计语言。
不同的赋值,对结果的引用也是不一样的。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top