• 有限状态机FSM(自动售报机Verilog实现)


    有限状态机FSM(自动售报机Verilog实现)

    FSM

    • 状态机就是一种能够描述具有逻辑顺序和时序顺序事件的方法。

    状态机有两大类:Mealy型和Moore型。
    Moore型状态机的输出只与当前状态有关,而Mealy型状态机的输出不仅取决于当前状态,还受到输入的直接控制,并且可能与状态无关。

    当使用Verilog来描述一个简单状态机的设计时,应将状态寄存器的控制器的控制和状态机状态里的组合逻辑分开。

    • 分离功能使得在逻辑部分的代码中可以使用阻塞赋值语句

    状态更新逻辑包含状态寄存器,不能被外设读取。组合逻辑使用输入和当前状态值来对输出赋值,并改变状态机的下一状态。


    同步时序电路的设计方法

    • 逻辑抽象,得出电路的状态转换图或者状态转换表
    • 状态化简
    • 状态分配(状态编码:Binary,Gray,One-Hot)
    • Verilog根据最简状态转换图编程,检查设计的电路能否自启动

    四个要素

    • 当前输入
    • 当前状态
    • 下一状态
    • 当前输出值

    代码风格

    一段式

    当前状态、下一状态、当前输出值都写在一个always块中

    二段式

    当前状态、下一状态、当前输出值写在两个always块中

    • 注意:这样三种组合方式,及有三种方式写这两个always块。

    三段式

    当前状态、下一状态、当前输出值分别写在各自的always块中,这样需要3个always块。


    自动售报机Verilog实现


    设计说明

    设计一个简单的数字电路用于电子的报纸售卖机的投币器。

    • 假设报纸的价格为15分。
    • 投币器只能接受5分和1角的硬币。
    • 必须提供适当的数目的零钱,投币器不找零。
    • 合法的硬币组合包括1个5分的硬币和1个一角的硬币,3个5分的硬币,1个1角的硬币和1个5分的硬币。2个1角的硬币是合法的,但是投币器不找零。

    电路说明

    • 当投入硬币时,一个两位的信号coin[1:0]被传送到数字电路。该信号在全局clock信号的下一个下降沿取值,并且准确地保持一个始终周期。
    • 数字电路的输出是一位的。每次当投入硬币总数为15分或者超过15分时,输出信号newspaper变为高电平,并且保持一个时钟周期。售卖机的门也被打开。
    • 可以用一个reset信号复位有限状态机。假设为同步复位。

    有限状态机FSM

    可以用有限状态机表示该数字电路的功能。

    • 输入:2位,coin[1:0]。没有硬币时,x0 = 2'b00;有一个5分的硬币时,x5 = 2'b01;有一个1角的硬币时,x10 = 2'b10。
    • 输出:1位,newspaper。当newspaper = 1'b1时,打开门。
    • 状态:4个状态。s0 = 0分,s5 = 5分,s10 = 10分,s15 = 15分。

    状态机转换图

    状态 钱数 输入 硬币[1:0]
    s0 0分 x0 2'b00
    s5 5分 x5 2'b01
    s10 10分 x10 2'b10
    s15 15分 - 无关


    verilog描述


    design code

    module vend(
                input    [1:0]   coin,
                input            clock,
                input            reset,
                output           newspaper
                );
    
    //声明有限状态机的内部状态
    wire    [1:0]   NEXT_STATE;
    reg     [1:0]   PRES_STATE;
    
    //状态编码
    parameter     s0  = 2'b00;
    parameter     s5  = 2'b01;
    parameter     s10 = 2'b10;
    parameter     s15 = 2'b11;
    
    //用同步复位、时钟正跳变沿触发的状态触发器
    always@(posedge clock)
    begin
        if(reset == 1'b1)
            PRES_STATE <= s0;
        else
            PRES_STATE <= NEXT_STATE;
    end
    
    //组合逻辑
    function [2:0] fsm;  //状态变化及输出组合逻辑
        input  [1:0]  fsm_coin;
        input  [1:0]  fsm_PRES_STATE;
    
        reg           fsm_newspaper;
        reg    [1:0]  fsm_NEXT_STATE;
    
        begin
            case(fsm_PRES_STATE)
                s0:     //状态为s0
                   begin
                       if(fsm_coin == 2'b10)
                       begin
                           fsm_newspaper   = 1'b0;
                           fsm_NEXT_STATE  = s10;
                       end
                       else if(fsm_coin == 2'b01)
                       begin
                           fsm_newspaper   = 1'b0;
                           fsm_NEXT_STATE  = s5;
                       end
                       else
                       begin
                           fsm_newspaper   = 1'b0;
                           fsm_NEXT_STATE  = s0;
                       end
                   end
                s5:     //状态为s5
                   begin
                       if(fsm_coin == 2'b10)
                       begin
                           fsm_newspaper   = 1'b0;
                           fsm_NEXT_STATE  = s15;
                       end
                       else if(fsm_coin == 2'b01)
                       begin
                           fsm_newspaper   = 1'b0;
                           fsm_NEXT_STATE  = s10;
                       end
                       else
                       begin
                           fsm_newspaper   = 1'b0;
                           fsm_NEXT_STATE  = s5;
                       end
                   end
                s10:     //状态为s10
                   begin
                       if(fsm_coin == 2'b10)
                       begin
                           fsm_newspaper   = 1'b0;
                           fsm_NEXT_STATE  = s15;
                       end
                       else if(fsm_coin == 2'b01)
                       begin
                           fsm_newspaper   = 1'b0;
                           fsm_NEXT_STATE  = s15;
                       end
                       else
                       begin
                           fsm_newspaper   = 1'b0;
                           fsm_NEXT_STATE  = s10;
                       end
                   end
                s15:     //状态为s15
                   begin
                       fsm_newspaper   = 1'b1;
                       fsm_NEXT_STATE  = s0;
                   end
               endcase
    
               fsm = {fsm_newspaper,fsm_NEXT_STATE};
        end
    endfunction
    
    //每当硬币放入或当前状态改变时,组合逻辑动作
    assign  {newspaper,NEXT_STATE} = fsm(coin,PRES_STATE);
    
    endmodule
    

    testbench

    module vend_tb;
    
    reg           clock;
    reg           reset;
    reg   [1:0]   coin;
    wire          newspaper;
    
    always #20 clock = ~clock;
    
    initial
    begin
        clock = 0;
        reset = 1;
        #100;
        reset = 0;
    
        @(posedge clock) coin[1:0] = 2'b00;
        @(posedge clock);
        @(posedge clock) coin[1:0] = 2'b01;
        @(posedge clock);
        @(posedge clock) coin[1:0] = 2'b10;
        @(posedge clock);
    
        @(posedge clock) coin[1:0] = 2'b10;
        @(posedge clock);
        @(posedge clock) coin[1:0] = 2'b10;
        @(posedge clock);
        
        @(posedge clock) coin[1:0] = 2'b00;
        @(posedge clock);
        @(posedge clock) coin[1:0] = 2'b01;
        @(posedge clock);
        @(posedge clock) coin[1:0] = 2'b01;
        @(posedge clock);
        @(posedge clock) coin[1:0] = 2'b01;
    
        #200 $finish;
    end
    
    initial begin
      $fsdbDumpfile("test.fsdb");
      $fsdbDumpvars();
    end
    
    vend u_vend( 
                .coin(coin),
                .clock(clock),
                .reset(reset),
                .newspaper(newspaper)
                 );
    
    endmodule
    

    仿真结果



    参考资料

    [1]. Verilog HDL数字设计与综合(第二版) [美]Simir Palnitkar 著 夏宇闻 等译
    [2]. Verilog 数字VLSI设计教程 [美] John Willianms 著 李林 等译
    [3]. 有限状态机 FSM 设计
    [4]. 有限狀態機FSM coding style整理 (SOC) (Verilog)

  • 相关阅读:
    C++使用GDI+实现图片格式转换
    易语言调用C++写的DLL
    【PE】手动给PE文件添加一段代码MessageBoxA
    SHGetSpecialFolderLocation获取开始文件夹
    MySQL导入导出数据
    MySQL5.7修改密码
    Elasticsearch 基于external的乐观锁的版本控制
    Elasticsearch修改字段类型 (_reindex)
    es 迁移数据, 重建索引
    SHELL
  • 原文地址:https://www.cnblogs.com/OneFri/p/6189422.html
Copyright © 2020-2023  润新知