【Verilog基础】13.状态机

10010序列检测

对串行输入的数据流进行检测,只要发现 10010 码型会立即输出一个高位的电平
module seqdet( x, z, clk, rst);
    input x,clk, rst;
    output z;
    reg [2:0] state;//状态寄存器
    wire z;

    parameter IDLE = 3 'd0,
     A = 3 'd1, 
     B = 3 'd2,
     C = 3 'd3, 
     D = 3 'd4,
     E = 3 'd5, 
     F = 3 'd6,
     G = 3 'd7;
  assign z =(state==D && x==0) ? 1 :0;//状态为 D 时又收到了 0,表明 10010 收到应有输出 Z 为高
always @(posedge clk or negedge rst)
    if(!rst)
        begin
         state<=IDLE;
        end
    else
        casex( state)
            IDLE: if(x==1)
                    state<=A; //用状态变量记住高电平(x==1)来过
                 else state<= IDLE; //输入的是低电平,不符合要求,所以状态保留不变
            A: if (x==0)
                    state<=B; //用状态变量记住第二位正确低电平(x==0)来过
                else state<= A; //输入的是高电平,不符合要求,所以状态保留不变
            B: if (x==0)
                    state<=C; //用状态变量记住第三位正确低电平(x==0)来过
                else state<=F; //输入的是高电平,不符合要求,记住只有一位曾经对过
            C: if(x==1)
                     state<=D; //用状态变量记住第四位正确高电平(x==1)来过
                 else state<=G; //输入的是低电平,不符合要求,记住没有一位曾经对过
            D: if(x==0)
                      state<=E; //用状态变量记住第五位正确低电平(x==0)来过
                 else state<=A; //输入的是高电平,不符合要求,
            E: if(x==0)
                         state<=C; //用状态变量记住 1 0 0 曾经来过,此状态为 C
                 else state<=A; //输入的是高电平,只有 1 位正确,该状态是 A
            F: if(x==1)
                         state<=A; //输入的是高电平,只有 1 位正确,该状态是 A
                 else
                        state<=B; //输入的是低电平,已有 2 位正确,该状态是 B
            G: if(x==1)
                        state<=F; //输入的又是高电平,只有 1 位正确,记该状态 F
                 else state <=B; //输入的是低电平,已有 2 位正确,该状态是 B
            default: state<=IDLE;
          endcase
endmodule

 自动售卖机状态机

module drink_machine(
 //input
     clk,
     rst_n,
     nickel_in,//5 美分
     dime_in, //10 美分
     quarter_in,//25 美分
 //output
     collect, //投币者提货信号
     dispense, //同时机器发货信号
     nickel_out,//退回投币者 5 美分
     dime_out //退回投币者 10 美 分
 );
 
    input nickel_in,dime_in,quarter_in;
    input clk,rst_n;
    output collect,dispense;
    output nickel_out,dime_out;
    reg collect;
    reg dispense;
    reg nickel_out;
    reg dime_out;

    parameter IDLE =0;
    parameter FIVE =1;
    parameter TEN =2;
    parameter FIFTEEN =3;
    parameter TWENTY =4;
    parameter TWENTY_FIVE =5;
    parameter THIRTY =6;
    parameter ONE_DIME =7;
    reg [2:0] state;
always@(posedge clk or negedge rst_n)
    begin
        if(rst_n==1'b0)
         begin
             nickel_out <=0;
             dime_out <=0;
             dispense <=0;
             collect <=0;
             state <= IDLE;
         end
        else
         begin
             nickel_out <=0;
             dime_out <=0;
             dispense <=0;
             collect <=0;
        case(state)
         IDLE: begin 
             if(nickel_in)
                 state <= FIVE;
             else if(dime_in)
                 state <= TEN;
             else if(quarter_in)
                 state <= TWENTY_FIVE;
             end

         FIVE: begin
             if(nickel_in)
                 state <= TEN;
             else if(dime_in)
                 state <= FIFTEEN;

             else if(quarter_in)
                 state <= THIRTY;
             end

         TEN: begin
             if(nickel_in)
                 state <= FIFTEEN;
             else if(dime_in)
                 state <= TWENTY;
             else if(quarter_in)
             begin
                 state <= IDLE;
                 dispense<=1'b1;
                 collect <=1'b1;
             end
         end

         FIFTEEN:begin
             if(nickel_in)
                 state <= TWENTY;
             else if(dime_in)
                 state <= TWENTY_FIVE;
             else if(quarter_in)
             begin
                 state <= IDLE;
                 dispense<=1'b1;
                 collect <=1'b1;
                 nickel_out <=1'b1;
             end
          end

         TWENTY:begin
             if(nickel_in)
                 state <= TWENTY_FIVE;
             else if(dime_in)
                 state <= THIRTY;
             else if(quarter_in)
             begin
                 state <= IDLE;
                 dispense<=1'b1;
                 collect <=1'b1;
                 dime_out <=1'b1;
             end
         end 

         TWENTY_FIVE:begin
             if(nickel_in)
                 state <= THIRTY;

             else if(dime_in)
             begin
                 state <= IDLE;
                 dispense<=1'b1;
                 collect <=1'b1;
             end
             else if(quarter_in)
             begin
                 state <= IDLE;
                 dispense<=1'b1;
                 collect <=1'b1;
                 dime_out <=1'b1;
                 nickel_out <=1'b1;
             end
         end 

         THIRTY:begin
           if(nickel_in)
             begin
             state <= IDLE;
             dispense<=1'b1;
             collect <=1'b1;
             end
           else if(dime_in)
             begin
             state <= IDLE;
             dispense<=1'b1;
             collect <=1'b1;
             nickel_out <=1'b1;
             end
           else if(quarter_in)
             begin
             state <= ONE_DIME;
             dispense<=1'b1;
             collect <=1'b1;
             dime_out <=1'b1;
             end
         end 

     ONE_DIME:begin
         state <= IDLE;
         dime_out <=1'b1;
         end
     endcase 
    end
end

endmodule

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值