数字IC-1.9 吃透通信协议中状态机的代码编写套路

打印 上一主题 下一主题

主题 509|帖子 509|积分 1527

目录


一、前言

本文针对verilog HDL语言编写不同通信协议时,需要对不同命令状态机进行代码实现的方法进行了浅薄的探讨。作者水平有限,还请大家指正。
文中利用SPI协议对flash发送全擦除指令为例子,分别探讨以下两种不同编写方法的优劣及具体实现方式:1、利用always语句块方法得到状态跳变条件或时间等待标志进行协议端口输出的写法(下文称 “逻辑法”);2、使用cnt计数器,在驱动时钟频率至少是spi_clk时钟频率两倍以上的前提下,对时序的不同时刻行为进行具体相应描述的编写方法(下文称 “时序法”)。

两者比较的结论
逻辑法:优点-后续工程中定制化修改更加方便,协议通信描述逻辑更加清晰具体,更能够抽象化规律化描述协议通信时的行为。缺点-编写不同协议行为之间的跳变限制逻辑设计较为复杂,代码仿真调节次数较多,需要反复考虑不同寄存器之间的延迟问题以提前空出延时余量,满足时序高效紧凑需求。(特点:小块时序逻辑更多,布线更简单,面积更小,速度稍慢)
时序法:优点-编写新思路简单清晰,开发速度快,可以简单有效地定位到bug存在位置,代码执行效率高。缺点-后期定制化其他功能修改的地方多,不容易看懂时序之间跳变的规律,不能够很客观的描述协议行为序列变化之间的关系。(特点:程序块较少,但一个case里计数器递进判断条件较多,布线由于比较集中,因此比较复杂,面积较大,速度更快)
使用建议:逻辑法更适用于已知固定长度,固定格式,一小段命令一小段命令发送命令或者接收状态的协议。对于非定常连续触发的协议或者一条命令内通信线时序变化非常复杂的协议,则推荐使用时序法来进行编写。 但是在实际工程运用中,其实它们并没有很明确的分界线,一般都是配合使用,博主的菜鸡经验是,连续信号耦合强且该信号持续期间有状态跳变的用逻辑法,连续信号只存在一个状态内且多线信号变化较为复杂的用时序法。

二、例子预备知识

        本文利用spi协议与flash芯片进行通信,向它发送全部扇区擦除指令。该指令由两个部分组成,一个是写使能部分WE,一个是全擦除命令BE部分。时序图如下。

 本文将使用硬件表述语言,分别使用两种方法来描述上述时序。其中WE写使能(8'h06)是用时序法实现的,BE全擦除(8'hc7)是用逻辑法实现的。

三、时序法WE命令代码举例

时序

         由上图可以看到,当spi_clk为上升沿时从机就会通过mosi对数据进行采样,因此要在上升沿之间的低电平时期就要把需要发出的命令数据放在mosi线上了(这是由于组合逻辑的非阻塞赋值延时一个时钟周期决定的)。
        注意: 此时spi_cmd_reg的命令8'n06是不变的,这是由于下面代码中命令直接寻址发送的编写方法决定的。

源码
        时序法通过case语句在每个时刻对spi协议的各个数据线行为跳变进行直接操控,使得这种方法编写起来简单有效。代码执行效率高,不需要在不同数据线之间设计相互承接的变化触发条件。但是这个方法对于人的阅读来说不够客观。
[code]w_en_100ns : begin                    case(cnt_son_stage)                        7'd0 : begin                             spi_cs
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宝塔山

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表