状态机嵌套的例子

该例是一个简化的EPROM的串行写入器。事实上,它是一个EPROM读写器设计中实现写功能的部分经删节得到的,去除了EPROM的启动、结束和EPROM控制字的写入等功能,只具备这样一个雏形。工作的步骤是:1.地址的串行写入;2.数据的串行写入;3.给信号源应答,信号源给出下一个操作对象;4.结束写操作。通过移位令并行数据得以一位一位输出。

模块源代码:

module writing(reset,clk,address,data,sda,ack);

  input reset,clk;

  input[7:0] data,address;

  output sda,ack; //sda负责串行数据输出;

           //ack是一个对象操作完毕后,模块给出的应答信号。

  reg link_write; //link_write 决定何时输出。

  reg[3:0] state; //主状态机的状态字。

  reg[4:0] sh8out_state; //从状态机的状态字。

  reg[7:0] sh8out_buf;    //输入数据缓冲。

  reg finish_F;           //用以判断是否处理完一个操作对象。

  reg ack;

  parameter

    idle=0,addr_write=1,data_write=2,stop_ack=3;

  parameter

    bit0=1,bit1=2,bit2=3,bit3=4,bit4=5,bit5=6,bit6=7,bit7=8;

  assign   sda = link_write? sh8out_buf[7] : 1'bz;

  always @(posedge clk)

    begin

        if(!reset)               //复位。

          begin

             link_write<= 0;

             state    <= idle;

             finish_F <= 0;

             sh8out_state<=idle;

                   ack<= 0;

             sh8out_buf<=0;

          end

        else

          case(state)

          idle:                     

            begin

                link_write  <= 0;

               state    <= idle;

               finish_F <= 0;

               sh8out_state<=idle;

                     ack<= 0;

               sh8out_buf<=address;

              state    <= addr_write;

            end

          addr_write:         //地址的输入。

            begin

                if(finish_F==0)

                  begin  shift8_out; end

                else

                  begin

                     sh8out_state <= idle;

                     sh8out_buf   <= data;

                            state <= data_write;

                         finish_F <= 0;

                  end

            end

          data_write:       //数据的写入。

            begin

                if(finish_F==0)

                  begin  shift8_out; end

                else

                  begin

                      link_write <= 0;

                           state <= stop_ack;

                        finish_F <= 0;

                             ack <= 1;

                  end

            end   

          stop_ack:             //完成应答。

            begin

                  ack <= 0;

              state <= idle;

            end

        

          endcase     

    end                         

task shift8_out;                //串行写入。

  begin

     case(sh8out_state)

     idle:

       begin

           link_write  <= 1;

          sh8out_state <= bit0;

        end

     bit0:

       begin

           link_write <= 1;

         sh8out_state <= bit1;                               

           sh8out_buf <= sh8out_buf<<1;

       end

     bit1:

       begin

         sh8out_state<=bit2;

         sh8out_buf<=sh8out_buf<<1;

       end

     bit2:

       begin

         sh8out_state<=bit3;

         sh8out_buf<=sh8out_buf<<1;

       end

     bit3:

       begin

         sh8out_state<=bit4;

         sh8out_buf<=sh8out_buf<<1;

       end

     bit4:

       begin

         sh8out_state<=bit5;

         sh8out_buf<=sh8out_buf<<1;

       end

   

     bit5:

       begin

         sh8out_state<=bit6;

         sh8out_buf<=sh8out_buf<<1;

       end

     bit6:

       begin

         sh8out_state<=bit7;

         sh8out_buf<=sh8out_buf<<1;

       end

     bit7:

       begin

         link_write<= 0;

         finish_F<=finish_F+1;                              

       end

     

     endcase

  end

endtask

endmodule        

测试模块源代码:

`timescale 1ns/100ps

`define clk_cycle 50

module writingTop;

  reg reset,clk;

  reg[7:0] data,address;

  wire ack,sda;

  always #`clk_cycle  clk = ~clk;

  initial

    begin

            clk=0;

            reset=1;

            data=0;

            address=0;

            #(2*`clk_cycle) reset=0;

            #(2*`clk_cycle) reset=1;

       #(100*`clk_cycle) $stop;

    end

  always @(posedge ack)      //接收到应答信号后,给出下一个处理对象。

    begin

            data=data+1;

            address=address+1;

    end       

  writing writing(.reset(reset),.clk(clk),.data(data),

                  .address(address),.ack(ack),.sda(sda));

endmodule

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值