zoukankan      html  css  js  c++  java
  • Verilog笔记.三段式状态机

    之前都是用的一段式状态机,逻辑与输出混在一起,复杂点的就比较吃力了。

    所以就开始着手三段式状态机。

    组合逻辑与时序逻辑分开,这样就能简单许多了。

    但是两者在思考方式上也有着很大的区别。

    三段式,分作:状态寄存器,次态组合逻辑,输出逻辑。

    以下今天写完的程序。

     1 //state register  
     2 always@(posedge clk)
     3 begin
     4     if(!rst)begin
     5         current <= IDLE;
     6     end    
     7     else begin
     8         current <= next;
     9     end
    10 end
    11 //next state logic
    12 always@(S_AXIS_tready or run or current)
    13 begin
    14     case(current)
    15     IDLE:if(S_AXIS_tready)begin
    16              if(run) next = WRIT;
    17              else    next = IDLE;
    18          end
    19          else begin
    20              next = IDLE;
    21          end 
    22     WRIT:if(S_AXIS_tready)begin
    23              if(run) next = WRIT;
    24              else      next = IDLE;
    25          end
    26          else begin
    27              if(run) next = WAIT;
    28              else      next = IDLE;
    29          end
    30      WAIT:if(S_AXIS_tready)begin
    31               if(run) next = WRIT;
    32               else      next = IDLE;
    33           end
    34           else begin
    35               if(run) next = WAIT;
    36               else      next = IDLE;
    37           end 
    38     default:next = IDLE;
    39     endcase
    40 end
    41 //output logic
    42 always@(posedge clk)
    43 begin
    44     if(!rst)begin
    45         S_AXIS_tvalid <= 1'b0;
    46         S_AXIS_tlast <= 1'b0;
    47         S_AXIS_tdata <= 32'h00000000;
    48         Gdata <= 32'h00000000;
    49     end
    50     else begin
    51         case(next)
    52         IDLE:begin
    53             S_AXIS_tlast <= 1'b0;
    54             S_AXIS_tvalid <= 1'b0;
    55             S_AXIS_tdata <= 32'h00000000;
    56             Gdata <= 32'h00000000;
    57         end
    58         WRIT:begin
    59             S_AXIS_tvalid <= 1'b1;
    60             if(S_AXIS_tdata <= 32'h3ff)begin
    61                 Gdata <=  Gdata + 1'b1;
    62                 S_AXIS_tdata <=  Gdata;             
    63             end
    64             else begin
    65                 S_AXIS_tdata <= S_AXIS_tdata;//32'h00000000;
    66                 S_AXIS_tlast <= 1'b1;
    67             end
    68         end   
    69         WAIT:begin
    70             S_AXIS_tlast <= 1'b0;
    71             S_AXIS_tvalid <= 1'b0;
    72             S_AXIS_tdata <= S_AXIS_tdata;
    73         end
    74         default:begin
    75             S_AXIS_tvalid <= 1'bx;
    76             S_AXIS_tlast <= 1'bx;
    77             S_AXIS_tdata <= 32'hx;
    78         end        
    79         endcase
    80     end
    81 end

    下面是改成三段式前的代码

     1 always@(posedge clk) begin
     2   if(!rst) begin 
     3     S_AXIS_tvalid <= 1'b0;
     4     S_AXIS_tlast <= 1'b0;
     5     S_AXIS_tdata <= 32'd0;
     6     state <= IDLE;
     7   end
     8   else begin
     9     case(state) //状态机
    10     IDLE: begin // idle
    11       if(start_posedge && S_AXIS_tready) begin //启动信号到来且FIFO可写
    12         S_AXIS_tvalid <= 1'b1;       //设置写FIFO有效
    13         state <= WRIT;
    14       end
    15       else begin
    16         S_AXIS_tvalid <= 1'b0;
    17         Gdata <= 32'h0;
    18         state <= IDLE;
    19       end
    20     end
    21     WRIT:begin
    22       if(S_AXIS_tready) begin //FIFO可写
    23         Gdata <= Gdata + 1'b1;
    24 //        S_AXIS_tdata <= Gdata;
    25         S_AXIS_tdata <= S_AXIS_tdata;
    26         if(S_AXIS_tdata == 32'hfff) begin //判断是否结束
    27           S_AXIS_tlast <= 1'b1;//发送最后一个数据
    28           state <= WAIT;
    29         end
    30         else begin//等待数据发完
    31           S_AXIS_tlast <= 1'b0;
    32           state <= WRIT;
    33         end
    34       end
    35       else begin//等待FIFO可写
    36         S_AXIS_tdata <= S_AXIS_tdata;
    37         state <= WRIT;
    38       end
    39     end
    40     WAIT:begin
    41       if(!S_AXIS_tready) begin //FIFO满则等待
    42         S_AXIS_tvalid <= 1'b1;
    43         S_AXIS_tlast <= 1'b1;
    44         S_AXIS_tdata <= S_AXIS_tdata;
    45         state <= WAIT;
    46       end
    47       else begin //写入结束
    48         S_AXIS_tvalid <= 1'b0;
    49         S_AXIS_tlast <= 1'b0;
    50         S_AXIS_tdata <= 16'd0;
    51         state <= IDLE;
    52       end
    53     end
    54     default: state <= IDLE;
    55     endcase
    56   end
    57 end

    参考

    https://www.cnblogs.com/lifan3a/articles/4583577.html

    https://blog.csdn.net/jason_child/article/details/60466050

  • 相关阅读:
    linux 常用函数
    现在什么都不是浮云
    laosao
    2012年
    工作任务
    代码整理
    如何做一个男人
    很重要的2点
    录像预录的设计及实现
    弄了一个小网站
  • 原文地址:https://www.cnblogs.com/protogenoi/p/9723779.html
Copyright © 2011-2022 走看看