之前都是用的一段式狀態機,邏輯與輸出混在一起,復雜點的就比較吃力了。
所以就開始着手三段式狀態機。
組合邏輯與時序邏輯分開,這樣就能簡單許多了。
但是兩者在思考方式上也有着很大的區別。
三段式,分作:狀態寄存器,次態組合邏輯,輸出邏輯。
以下今天寫完的程序。
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