0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于FPGA的状态机设计

CHANBAEK 来源:小小研究生 作者:xxyjs2020 2023-07-28 10:02 次阅读

数电基础

状态机的基础知识依然强烈推荐mooc上华科的数字电路与逻辑设计,yyds!但是数电基础一定要和实际应用结合起来,理论才能发挥真正的价值。我们知道FPGA是并行执行的,如果我们想要处理具有前后顺序的事件就需要引入状态机。

状态机有同步异步之分,同步是指状态机的状态跳转是在时钟的作用下进行的,异步是指状态跳转不是由统一的时钟控制。同步有限状态机分为Moore型Mealy型 ,Moore型的输出只与当前状态有关,而Mealy型的输出与当前状态和输入有关。

每一个状态都代表一个事件,从初始状态出发,不同的输入可能引发不同的下一个状态,并获得不同的输出(输出不是必须的,但一定有输入)。

设计规划

我们的目标是用状态机实现一个简单的可乐贩卖机系统。具体功能是:可乐机每次只能投入1枚1元硬币,且每瓶可乐卖3元钱,即投入3个硬币就可以让可乐机出可乐,如果投币不够3元想放弃投币需要按复位键,否则之前投入的钱不能退回。

Moore型用状态图来表示:

图片

初始状态是IDLE,如果输入0枚跳转到自身状态,输入1枚跳转到ONE状态,跳转到TWO状态也是同理,再输入0枚跳转到自身状态,输入1枚跳转到初始状态并输出1表示可乐售卖成功,其间任意状态复位有效都要回到初始状态并退钱。

Mealy型用状态图来表示:

图片

有四种状态,到TWO状态都与前面一致,TWO状态时投1枚跳转到THREE状态,THREE状态如果输入0枚就售出可乐且跳转到初始状态,输入1枚就售出可乐且跳转到ONE状态。

图片

编写代码

module simple_fsm
(
input wire sys_clk , 
input wire sys_rst_n , 
input wire pi_money , 
output reg po_cola 
);


 //parameter define
 parameter IDLE = 3'b001;
 parameter ONE = 3'b010;
 parameter TWO = 3'b100;


 //reg define
 reg [2:0] state ;


 //第一段状态机,描述当前状态state如何根据输入跳转到下一状态
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 state <= IDLE; //任何情况下只要按复位就回到初始状态
 else case(state)
 IDLE : if(pi_money == 1'b1) //判断输入情况
 state <= ONE;
 else
 state <= IDLE;


 ONE : if(pi_money == 1'b1)
 state <= TWO;
 else
 state <= ONE;


 TWO : if(pi_money == 1'b1)
 state <= IDLE;
 else
 state <= TWO;
 
 default: state <= IDLE;
 endcase


 //第二段状态机,描述当前状态state和输入pi_money如何影响po_cola输出
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 po_cola <= 1'b0;
 else if((state == TWO) && (pi_money == 1'b1))
 po_cola <= 1'b1;
 else
 po_cola <= 1'b0;


 endmodule

输入输出定义

参数定义:状态要用参数来表示,为了区分不同的状态,我们需要给 状态编码 ,这里使用了独热码,只有一位为1其余位为0。事实上这里使用二进制或格雷码也可以表示。二进制编码使用2位位宽就可以表示4种状态(有一种状态未使用)。使用独热码的原因是:独热码每个状态只有1bit是不同的,所以在执行(state == TWO)这条语句时,综合器会识别出这是一个比较器,而因为只有1比特为1,所以综合器会进行智能优化为(state[2] == 1’ b1),这就相当于把之前3比特的比较器变为了1比特的比较器,大大节省了组合逻辑资源。而我们FPGA中组合逻辑资源相对较少,而寄存器资源较多,所以牺牲寄存器资源来节省组合逻辑资源。状态很多时可以采用格雷码进行编码,位数少,且相邻状态转换时只有一位发生变化,相当于二进制和独热码的折衷处理。

采用新两段式,第一段用于定义状态跳转,第二段定义输出。这种新的写法现在在不同综合器中都可以被识别出来,既消除了组合逻辑可能产生的毛刺,又减小了代码量,仅仅根据状态转移图就能实现。如果有多个输出时第二段状态机就可以分为多个always块来表达,但理论上仍属于新二段状态机,所以几段式状态机并不是由always块的数量简单决定的)。

定义状态跳转 :状态变化的条件是时钟上升沿和复位。首先复位时,状态恢复到初始状态。没有复位时,需要定义每个状态的跳转。这里采用了case语句,复习一下:case语句检查表达式与列表中其他表达式是否匹配并对应分支。这里是检查state与IDLE,ONE,TWO匹配,当处于三种状态时,都有pi_money=0或1两种情况,按照之前讨论的跳转状态去设置。注意case语句如果不加default可能出现latch。

定义输出 :复位有效时,输出为0;只有一种情况输出为1,就是有足够买到可乐的钱时,也就是状态为TWO且投入1块钱;其他时候输出为0。

图片

图片

编写testbench

`timescale 1ns/1ns
module tb_simple_fsm();
//reg define
reg sys_clk ;
reg sys_rst_n ;
reg pi_money ;


//wire define
wire po_cola;


 initial begin
 sys_clk = 1'b1;
 sys_rst_n <= 1'b0;
 #20
 sys_rst_n <= 1'b1;
 end


 //sys_clk:模拟系统时钟,每10ns电平翻转一次,周期为20ns,频率为50MHz
 always #10 sys_clk = ~sys_clk;


 //pi_money:产生输入随机数,模拟投币1元的情况
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 pi_money <= 1'b0;
 else
 pi_money <= {$random} % 2; //取模求余数,产生非负随机数0、1


 //将RTL模块中的内部信号引入到Testbench模块中进行观察
 wire [2:0] state = simple_fsm_inst.state;


 initial begin
 $timeformat(-9, 0, "ns", 6);
 $monitor("@time %t: pi_money=%b state=%b po_cola=%b",
 $time, pi_money, state, po_cola);
 end


 //------------------------simple_fsm_inst------------------------
 simple_fsm simple_fsm_inst(
 .sys_clk (sys_clk ), 
 .sys_rst_n (sys_rst_n ), 
 .pi_money (pi_money ),
 .po_cola (po_cola ) 
 );


 endmodule

输入输出定义、初始化、时钟产生、随机数产生、打印结果、实例化都是我们非常熟悉的内容了。需要补充说明的是第29行,重新定义了一个state(名称尽量与rtl中一致),将实例化模块中的state与其等效,这样就可以在transcript中打印并观察到。因为transcript中观察到打印信息只能是RTL的端口信号,而state是内部信号(端口信号是输入输出时钟复位,中间信号是内部信号)。

对比波形

图片

图片

状态跳转与预期一致

应用拓展

前面的可乐贩卖机只能投1元的,我们来看看投0.5元的状态机:可乐定价为2.5元一瓶,可投入0.5元、1元硬币,投币不够2.5元需要按复位键退回钱款,投币超过2.5元需找零。

看似很复杂,实际只是变成两种输入,三种输出,五种状态。输入有0.5,1元;输出有不找零不出可乐,不找零出可乐,找零并出可乐;状态有0,0.5,1,1.5,2,到2块之后输入0.5就到0的状态并出可乐,输入1就到0的状态出可乐并找零。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1603

    文章

    21328

    浏览量

    593264
  • 状态机
    +关注

    关注

    2

    文章

    486

    浏览量

    27182
  • 状态图
    +关注

    关注

    0

    文章

    11

    浏览量

    7249
收藏 人收藏

    评论

    相关推荐

    FPGA工程师:如何在FPGA中实现状态机

    安全高效的状态机设计对于任何使用FPGA的工程师而言都是一项重要技能。选择Moore状态机、Mealy状态机还是混合机取决于整个系统的需求。无论选择哪种类型的
    发表于 03-29 15:02 1.2w次阅读
    <b class='flag-5'>FPGA</b>工程师:如何在<b class='flag-5'>FPGA</b>中实现<b class='flag-5'>状态机</b>?

    高效安全的状态机设

    本帖最后由 eehome 于 2013-1-5 09:56 编辑 高效安全的状态机设
    发表于 08-13 17:53

    状态机设计的例子

    本帖最后由 eehome 于 2013-1-5 09:56 编辑 状态机设计的例子
    发表于 08-19 23:01

    状态机设计指导

    状态机设计指导
    发表于 08-20 23:45

    状态机设计问题

    状态机设计中always @(*) beginnext = 2'bx;case (state)idle: next=s1;s1: next=s2;s2: next=idle;end以上代码先给
    发表于 10-06 18:49

    如何写好状态机

    如何写好状态机:状态机是逻辑设计的重要内容,状态机的设计水平直接反应工程师的逻辑功底,所以许多公司的硬件和逻辑工程师面试中,状态机设计几乎是必选题目。本章在引入
    发表于 06-14 19:24 96次下载

    状态机设

    状态机设计:8.1.1 数据类型定义语句TYPE语句的用法如下:TYPE 数据类型名IS 数据类型定义OF 基本数据类型;或TYPE 数据类型名IS 数据类型定义;TYPE st1 IS ARRAY ( 0 TO 15 ) OF STD_L
    发表于 08-09 23:07 36次下载

    高速环境下FPGA或CPLD中的状态机设

        本文给出了采用这些技术的高速环境状态机设计的规范及分析方法和优化方法,并给出了相应的示例。       为了使FPGA或CPLD中的状态机设
    发表于 04-15 11:27 609次阅读
    高速环境下<b class='flag-5'>FPGA</b>或CPLD中的<b class='flag-5'>状态机设</b>计

    VHDL有限状态机设计-ST

    EDA的有限状态机,广义而言是指只要涉及触发器的电路,无论电路大小都可以归结为状态机。有限状态机设计在学习EDA时是很重要的一章。
    发表于 06-08 16:46 3次下载

    华清远见FPGA代码-状态机

    FPGA学习资料教程——华清远见FPGA代码-状态机
    发表于 10-27 18:07 9次下载

    基于FPGA状态机设计实现EtherCAT从站基本通信链路并验证

    状态机,并通过解析各阶段数据状态变化,验证了各节点通信数据的正确性。实验结果表明,基于上述状态机FPGA实现EtherCAT从站基本通信链路是完全可行的。
    发表于 11-15 12:04 1.7w次阅读
    基于<b class='flag-5'>FPGA</b><b class='flag-5'>状态机设</b>计实现EtherCAT从站基本通信链路并验证

    FPGA状态机设计原则

    状态机状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。
    的头像 发表于 10-09 07:02 2175次阅读

    FPGA状态机简述

    FPGA设计中一种非常重要、非常根基的设计思想,堪称FPGA的灵魂,贯穿FPGA设计的始终。 02. 状态机简介 什么是状态机
    的头像 发表于 11-05 17:58 6236次阅读
    <b class='flag-5'>FPGA</b>:<b class='flag-5'>状态机</b>简述

    FPGA状态机设计思想

    硬件电路设计通常以并行方式实现,但是在实际工程中经常会存在系统按照顺序逻辑执行的需求。
    发表于 07-17 09:42 531次阅读
    <b class='flag-5'>FPGA</b><b class='flag-5'>状态机设</b>计思想

    如何在FPGA中实现状态机

    状态机往往是FPGA 开发的主力。选择合适的架构和实现方法将确保您获得一款最佳解决方案。 FPGA 常常用于执行基于序列和控制的行动, 比如实现一个简单的通信协议。对于设计人员来说,满足这些行动
    的头像 发表于 07-18 16:05 602次阅读
    如何在<b class='flag-5'>FPGA</b>中实现<b class='flag-5'>状态机</b>