在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 7426|回复: 12

[原创] 求教一下状态机的状态跳转问题

[复制链接]
发表于 2010-12-8 15:50:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
先说明一下常见的状态机写法:

  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模块,它里面用的是非阻塞赋值方式来进行状态的跳转以及判断的,有哪个大虾给解释一下这样做有什么优缺点么?虽然自己也这样写过,但对这个用法还是很迷糊。希望能得到大家的指点。
发表于 2010-12-8 23:23:24 | 显示全部楼层
我看你第二个always是阻塞方式描述的呀?难道<=是非阻塞?
发表于 2010-12-8 23:43:17 | 显示全部楼层
我觉得 这段always语句用 阻塞 和非阻塞的效果应该差不多...
  阻塞我感觉类似于顺序执行,而非阻塞则类似于并行,现在整个always语句中间下面的if语句只有一个短句
所以阻塞和非阻塞时一个效果....
发表于 2010-12-9 09:04:36 | 显示全部楼层
第二段always用阻塞和非阻塞是一样的,不过一般编码风格是推荐用非阻塞赋值的
 楼主| 发表于 2010-12-9 14:03:47 | 显示全部楼层
回复 4# AmoiBB


    现在是一个语句这样赋值,效果是一样的,但如果有多个语句的话,那<=和=的赋值效果还一样么?求教了。
 楼主| 发表于 2010-12-9 14:06:05 | 显示全部楼层
回复 3# csba5201989


    现在是一个语句这样赋值,效果是一样的。但如果有多个语句这样赋值的话,那<=和=的赋值效果还一样么?求教了。
发表于 2010-12-9 14:42:47 | 显示全部楼层
状态机无所谓怎么写,只要判断转移条件合理就行了,=和=〉在verilog中的用法和状态机没什么关系,关键是你可能还没仔细看过verilog方面的教程之类的书,你只要搞清楚组合逻辑和时序逻辑怎样书写就不会有这样的疑问了
 楼主| 发表于 2010-12-9 15:31:35 | 显示全部楼层
回复 7# goswami


    恩,是这么说的,这一次我想把这个问题搞懂,以免在以后的过程中又出现问题,
   阻塞、非阻塞赋值是没错,但如果理解错了,就真的错了,这个影响到对结果的引用。希望你能多指点些。非常感谢!
发表于 2010-12-12 11:07:49 | 显示全部楼层
看看啥!
发表于 2010-12-13 08:53:31 | 显示全部楼层
建议将每一个verilog的写法都能对应到具体的物理电路上。

如果实现的是一个组合逻辑,用什么能表示呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-15 04:32 , Processed in 0.024390 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表