Verilog HDL实现状态机(二)

      上一章中,可乐的定价为3元,且只能投一元的硬币,不可以找零,实现了简单版本的状态机,本章,将可乐定价为2.5元,可以投1元,0.5元的硬币,可以找零;

     绘制模块框图如下:

 pi_money_half :投币0.5元;

 pi_money_one:投币1元;

 po_cola:出可乐;

 po_money:找零;

输入:0.5、1;

输出:不出可乐/不找零(编码:00)、出可乐/不找零(编码:10)、出可乐/找零(编码:11);

状态:0(编码:00)、0.5(编码:01)、1(编码:10)、1.5、2、2.5、3;

状态转移图如下:

可乐状态机的波形图如下图所示:

对照波形图编写Verilog HDL文件如下:

`timescale  1ns/1ns

module  complex_fsm
(
    input   wire        sys_clk         ,
    input   wire        sys_rst_n       ,
    input   wire        pi_money_half   ,
    input   wire        pi_money_one    ,
    
    output  reg         po_cola         ,
    output  reg         po_money
);

parameter   IDLE    =   5'b00001,
            HALF    =   5'b00010,
            ONE     =   5'b00100,
            ONE_HALF=   5'b01000,
            TWO     =   5'b10000;

wire    [1:0]   pi_money    ;
reg     [4:0]   state   ;

assign  pi_money = {pi_money_one,pi_money_half};

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        state   <=  IDLE;
    else    case(state)
        IDLE    :   if(pi_money ==2'b01)
                        state   <=  HALF;
                        else    if(pi_money ==2'b10)
                            state   <=  ONE;
                        else
                            state   <=  IDLE;
        HALF    :   if(pi_money ==2'b01)
                        state   <=  ONE;
                        else    if(pi_money ==2'b10)
                            state   <=  ONE_HALF;
                        else
                            state   <=  HALF;
        ONE     :   if(pi_money == 2'b01)
                              state <= ONE_HALF;
                          else    if(pi_money == 2'b10)
                              state <= TWO;
                          else
                              state <= ONE;
        ONE_HALF:   if(pi_money == 2'b01)
                              state <= TWO;
                          else    if(pi_money == 2'b10)
                              state <= IDLE;
                          else
                              state <= ONE_HALF;
        TWO     :   if((pi_money == 2'b01) || (pi_money == 2'b10))
                              state <= IDLE;
                          else
                              state <= TWO;
        default :       state <= IDLE;
    endcase
    
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        po_cola <= 1'b0;
    else    if((state == ONE_HALF && pi_money == 2'b10) 
                || (state == TWO && pi_money == 2'b01)
                || (state == TWO && pi_money == 2'b10))
        po_cola <=  1'b1;
    else
        po_cola <= 1'b0;
        
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        po_money    <= 1'b0;
    else    if(state == TWO && pi_money == 2'b10)
        po_money    <=  1'b1;
    else
        po_money    <=  1'b0;
        
endmodule

使用程序编译后得到状态转移图如下:

仿真文件的代码如下:

`timescale  1ns/1ns

module tb_complex_fsm();

reg sys_clk ;
reg sys_rst_n;
reg pi_money_half;
reg pi_money_one;
reg random_data;

wire    po_cola ;
wire    po_money;

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

always #10 sys_clk = ~sys_clk;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_clk == 1'b0)
        random_data <=  1'b0;
    else
        random_data <=  {$random} % 2;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_clk == 1'b0)
        pi_money_half  <=  1'b0;
    else
        pi_money_half  <=  random_data;
        
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_clk == 1'b0)
        pi_money_one  <=  1'b0;
    else
        pi_money_one  <=  ~random_data;

wire    [1:0]  pi_money = complex_fsm_inst.pi_money;
wire    [4:0]  state = complex_fsm_inst.state;

initial
    begin
        $timeformat(-9, 0, "ns", 6);
        $monitor("@time %t: pi_money_one=%b pi_money_half=%b pi_money=%b state=%b po_cola=%b po_money=%b", $time, pi_money_one, pi_money_half, pi_money, state, po_cola, po_money);
    end
complex_fsm complex_fsm_inst(
    .sys_clk        (sys_clk        ),
    .sys_rst_n      (sys_rst_n      ),
    .pi_money_one   (pi_money_one   ),
    .pi_money_half  (pi_money_half  ),
                    
    .po_cola        (po_cola        ),
    .po_money       (po_money       ) 
);

endmodule

通过仿真,得到仿真波形图如下:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NUAA舜哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值