通過狀態機來對axi_lite總線進行操作


通過狀態機來對axi_lite總線進行操作

狀態跳轉:

1.初始狀態

axi_lite讀寫兩個信道分開進行控制,在初始狀態,就根據讀,寫信號來判斷應該跳轉到那一個狀態。

2.寫狀態

在寫狀態中不需要跳轉條件,即寫狀態只需要消耗一個時鍾周期,然后自動跳轉到下一個狀態。

3.寫有效狀態

當接收到slave端的awready wready 即地址寫准備和數據寫准備信號后,跳轉到write_ready狀態。

4.write_ready狀態

write_ready狀態中,等到slavebvalid信號的到來,然后跳轉到write_bready狀態。

5.write_bready狀態

WRITE_BREADY 狀態不需要狀態跳轉條件,只需要消耗一個時鍾周期,同時在這個狀態中,也沒有相關信號需要輸出。

6.write_end狀態

write_end狀態也不需要狀態跳轉條件,寫完數據之后,直接回到初始狀態。

7.read_start狀態

類比write_start狀態

8.read_valid狀態

類比write_valid信號,只是讀數據的過程中不需要接收數據准備信號,在read_valid狀態中,當接收到slave端的讀地址准備信號后,跳轉到read_ready狀態。

9.read_ready

slave端傳回來讀數據有效信號后,狀態機跳轉進read_finish狀態。

10.read_finish狀態

類比write_finish狀態

11.read_end狀態

類比write_end狀態

總結axi_lite讀寫時序:

寫:首先准備好訪問地址,和需要寫入的數據同時給出地址有效,數據有效,bready信號,

當接收到slave端的地址ready和數據ready信號后,表示可以進行下一寫操作了,同時,還需要等待slave端的bvalid信號到來,表示一次寫完成了,即slave端的一個寫反饋過程

讀:首先准備好訪問地址,和地址有效信號先拉高,當接收到slave端的地址ready信號后,表示可以進行下一次讀操作了,同時,當slave端傳過來valid信號的同時,才可以接受axi_lite上讀取的數據。

狀態機輸出控制:

1.在完成一次完整的狀態后,必須對相關信號進行清除

 2.初始狀態不需要數據信號,write_start信號輸出結果如下:

3.write_valid狀態輸出結果:

4.write_ready狀態輸出結果:

5.write_bready狀態無需輸出信號,write_end狀態數據結果:

6.read_start狀態輸出結果:

7.read_valid狀態輸出結果:

8.read_ready狀態中不需要輸出,read_finish輸出結果:

9.read_end狀態中輸出結果:

axi_lite總線時序波形圖具體分析(仿真版)

寫:

觀察awvalid,wvalid,bready是怎么左對齊的,awready,wready是怎么對齊的,還有awready,wready,awvalid,wvalid是怎么右對齊的,breadybvalid是怎么右對齊的,反正你需要知道這些信號之間的關系與實際的波形圖。

這次加上了地址與數據。

讀:

注意arvalid,rready信號的左邊是怎么對齊的,右邊的rready要多一個時鍾周期。

 

  1 `timescale 1ns / 1ps
  2 //////////////////////////////////////////////////////////////////////////////////
  3 // Company: 
  4 // Engineer: chensimin
  5 // 
  6 // Create Date: 2018/02/07 09:54:03
  7 // Design Name: 
  8 // Module Name: ipc_axi_spi
  9 // Project Name: 
 10 // Target Devices: 
 11 // Tool Versions: 
 12 // Description: 
 13 // 
 14 // Dependencies: 
 15 // 
 16 // Revision:
 17 // Revision 0.01 - File Created
 18 // Additional Comments:
 19 // 
 20 //////////////////////////////////////////////////////////////////////////////////
 21 
 22 
 23 module axi_spi(
 24     
 25         input   clk_100M,
 26         inout   [3:0]spi_dq,
 27         inout   spi_ss,
 28 //-----------------------ipc_interface---------------------------
 29         input   wire   [11:0]    ipc_addr,
 30         input   wire   [31:0]    ipc_wdata,
 31         output  wire   [31:0]    ipc_rdata,    
 32         input   wire             ipc_rd,
 33         input   wire             ipc_wr,
 34         output  wire             ipc_ack
 35 
 36     );
 37 
 38 
 39 //--------------------------------------------------------------
 40 
 41     ila_0 your_instance_name (
 42         .clk(clk_100M), // input wire clk
 43         .probe0(ipc_wr_rise), // input wire [0:0]  probe0  
 44         .probe1(ipc_rd_rise), // input wire [0:0]  probe1 
 45         .probe2(m_axi_awvalid), // input wire [0:0]  probe2 
 46         .probe3(m_axi_wvalid), // input wire [0:0]  probe3 
 47         .probe4(m_axi_arvalid), // input wire [0:0]  probe4 
 48         .probe5(m_axi_rready), // input wire [0:0]  probe5 
 49         .probe6(m_axi_bready), // input wire [0:0]  probe6 
 50         .probe7(s_axi_awready), // input wire [0:0]  probe7 
 51         .probe8(s_axi_arready), // input wire [0:0]  probe8 
 52         .probe9(s_axi_wready), // input wire [0:0]  probe9 
 53         .probe10(s_axi_rvalid), // input wire [0:0]  probe10 
 54         .probe11(s_axi_bvalid), // input wire [0:0]  probe11 
 55         .probe12(io0_i), // input wire [0:0]  probe12 
 56         .probe13(io0_o), // input wire [0:0]  probe13 
 57         .probe14(io0_t), // input wire [0:0]  probe14 
 58         .probe15(io1_i), // input wire [0:0]  probe15 
 59         .probe16(io1_o), // input wire [0:0]  probe16 
 60         .probe17(io1_t), // input wire [0:0]  probe17 
 61         .probe18(io2_i), // input wire [0:0]  probe18 
 62         .probe19(io2_o), // input wire [0:0]  probe19 
 63         .probe20(io2_t), // input wire [0:0]  probe20 
 64         .probe21(io3_i), // input wire [0:0]  probe21 
 65         .probe22(io3_o), // input wire [0:0]  probe22 
 66         .probe23(io3_t), // input wire [0:0]  probe23 
 67         .probe24(ss_i), // input wire [0:0]  probe24 
 68         .probe25(ss_o), // input wire [0:0]  probe25 
 69         .probe26(ss_t), // input wire [0:0]  probe26
 70         .probe27(m_axi_awaddr), // input wire [6:0]  probe27 
 71         .probe28(m_axi_araddr), // input wire [6:0]  probe28 
 72         .probe29(current_state), // input wire [6:0]  probe29 
 73         .probe30(next_state), // input wire [6:0]  probe30 
 74         .probe31(m_axi_wdata), // input wire [31:0]  probe31 
 75         .probe32(m_axi_rdata), // input wire [31:0]  probe32 
 76         .probe33(s_axi_rdata), // input wire [31:0]  probe33
 77         .probe34(ipc_addr), // input wire [11:0]  probe34 
 78         .probe35(ipc_wdata), // input wire [31:0]  probe35 
 79         .probe36(ipc_rdata), // input wire [31:0]  probe36 
 80         .probe37(ipc_rd), // input wire [0:0]  probe37 
 81         .probe38(ipc_wr), // input wire [0:0]  probe38 
 82         .probe39(ipc_ack) // input wire [0:0]  probe39
 83     );
 84 
 85 
 86 
 87 
 88 
 89 
 90 
 91 
 92 
 93 //--------------------------------------------------------------
 94 
 95     reg ipc_rd_delay_1;
 96     reg ipc_wr_delay_1;
 97     reg ipc_rd_delay_2;
 98     reg ipc_wr_delay_2;
 99     wire ipc_rd_rise;
100     wire ipc_wr_rise;
101     always @(posedge clk_100M or posedge rst)
102     begin
103         if(rst)
104         begin
105             ipc_rd_delay_1 <= 1'b0;
106             ipc_wr_delay_1 <= 1'b0;
107             ipc_rd_delay_2 <= 1'b0;
108             ipc_wr_delay_2 <= 1'b0;
109         end
110         else 
111         begin
112             ipc_rd_delay_1 <= ipc_rd;
113             ipc_wr_delay_1 <= ipc_wr;
114             ipc_rd_delay_2 <= ipc_rd_delay_1;
115             ipc_wr_delay_2 <= ipc_wr_delay_1;
116         end
117     end
118 
119     assign ipc_rd_rise = !ipc_rd_delay_2 && ipc_rd_delay_1;
120     assign ipc_wr_rise = !ipc_wr_delay_2 && ipc_wr_delay_1;
121 
122 //--------------------------------------------------------------
123     reg [6:0]current_state;
124     reg [6:0]next_state;
125     always @ (posedge clk_100M or posedge rst)
126     begin
127         if(rst)
128             current_state <= IDLE;
129         else
130             current_state <= next_state;
131     end
132 
133 //--------------------------------------------------------------
134     parameter   [4:0]   IDLE            =   5'd0    ,
135                         WRITE_START     =   5'd1    ,
136                         WRITE_VALID     =   5'd2    ,
137                         WRITE_READY     =   5'd3    ,
138                         WRITE_BREADY    =   5'd4    ,
139                         WRITE_END       =   5'd5    ,
140                         READ_START      =   5'd11   ,
141                         READ_VALID      =   5'd12   ,
142                         READ_READY      =   5'd13   ,
143                         READ_FINISH     =   5'd14   ,
144                         READ_END        =   5'd15   ;
145 
146     always @ (*)
147     begin
148         next_state = IDLE;
149         case(current_state)
150         IDLE:
151         begin
152             if(ipc_wr_rise)
153                 next_state = WRITE_START;
154             else if(ipc_rd_rise)
155                 next_state = READ_START;
156             else
157                 next_state = IDLE;
158         end
159 
160         WRITE_START:
161         begin
162             next_state = WRITE_VALID;
163         end
164 
165         WRITE_VALID:
166         begin
167             if(s_axi_awready && s_axi_wready)
168                 next_state = WRITE_READY;
169             else
170                 next_state = WRITE_VALID;
171         end
172 
173         WRITE_READY:
174         begin
175             if(s_axi_bvalid)
176                 next_state = WRITE_BREADY;
177             else
178                 next_state = WRITE_READY;
179         end
180 
181         WRITE_BREADY:
182         begin
183             next_state = WRITE_END;
184         end
185 
186         WRITE_END:
187         begin
188             next_state = IDLE;
189         end
190 
191         READ_START:
192         begin
193             next_state = READ_VALID;
194         end
195 
196         READ_VALID:
197         begin
198             if(s_axi_arready)
199                 next_state = READ_READY;
200             else 
201                 next_state = READ_VALID;
202         end
203 
204         READ_READY:
205         begin
206             if(s_axi_rvalid)
207                 next_state = READ_FINISH;
208             else
209                 next_state = READ_READY;
210         end
211 
212         READ_FINISH:
213         begin
214             next_state = READ_END;
215         end
216 
217         READ_END:
218         begin
219             next_state = IDLE;
220         end
221 
222         endcase
223     end
224 
225 //-------------------------------------------------------------
226     reg m_axi_awvalid;
227     reg m_axi_wvalid;
228     reg m_axi_arvalid;
229 
230     reg m_axi_rready;
231     reg m_axi_bready;
232     
233     reg [6:0]m_axi_awaddr; 
234     reg [6:0]m_axi_araddr;
235 
236     reg [31:0]m_axi_wdata;
237     reg [31:0]m_axi_rdata;
238 
239     reg ipc_ack_r;
240 
241 
242     always @(posedge clk_100M or posedge rst) 
243     begin
244         if (rst) 
245         begin
246             m_axi_awvalid <= 1'b0;
247             m_axi_wvalid <= 1'b0;
248             m_axi_arvalid <= 1'b0;
249             m_axi_rready <= 1'b0;
250             m_axi_bready <= 1'b0;
251             m_axi_awaddr <= 0; 
252             m_axi_araddr <= 0;
253             m_axi_wdata <= 0;
254             m_axi_rdata <= 0;
255             ipc_ack_r <= 1'b0;
256         end
257         else 
258         begin
259 
260             m_axi_awvalid <= 1'b0;
261             m_axi_wvalid <= 1'b0;
262             m_axi_arvalid <= 1'b0;
263             m_axi_rready <= 1'b0;
264             m_axi_bready <= 1'b0;
265             ipc_ack_r <= 1'b0;
266 
267             case(next_state)
268             //IDLE:
269 
270             WRITE_START:
271             begin
272                 m_axi_awaddr <= ipc_addr[6:0];
273                 m_axi_wdata <= ipc_wdata;
274                 m_axi_awvalid <= 1'b1;
275                 m_axi_wvalid <= 1'b1;
276                 m_axi_bready <= 1'b1;
277             end
278 
279             WRITE_VALID:
280             begin
281                 m_axi_awvalid <= 1'b1;
282                 m_axi_wvalid <= 1'b1;    
283                 m_axi_bready <= 1'b1;
284             end
285 
286             WRITE_READY:
287             begin
288                 m_axi_bready <= 1'b1;
289             end
290 
291             //WRITE_BREADY:
292             WRITE_END:
293             begin
294                 ipc_ack_r <= 1'b1;
295             end
296 
297             READ_START:
298             begin
299                 m_axi_araddr <= ipc_addr[6:0];
300                 m_axi_arvalid <= 1'b1;
301             end
302 
303             READ_VALID:
304             begin
305                 m_axi_arvalid <= 1'b1;
306             end
307 
308             //READ_READY:
309 
310             READ_FINISH:
311             begin
312                 m_axi_rdata <= s_axi_rdata;
313                 m_axi_rready <= 1'b1;
314             end
315 
316             READ_END:
317             begin
318                 ipc_ack_r <= 1'b1;
319             end
320 
321             default:
322             begin
323                 m_axi_awvalid <= 1'b0;
324                 m_axi_wvalid <= 1'b0;
325                 m_axi_arvalid <= 1'b0;
326                 m_axi_rready <= 1'b0;
327                 m_axi_bready <= 1'b0;
328                 ipc_ack_r <= 1'b0;
329             end
330 
331             endcase
332 
333         end
334     end
335 
336     assign ipc_rdata = m_axi_rdata;
337     assign ipc_ack = ipc_ack_r;
338 
339 //-------------------------------------------------------------
340     wire s_axi_awready;
341     wire s_axi_arready;
342     wire s_axi_wready;
343     wire s_axi_rvalid;
344     wire s_axi_bvalid;
345     wire [31:0]s_axi_rdata;
346 
347     wire io0_i;
348     wire io0_o;
349     wire io0_t;
350     wire io1_i;
351     wire io1_o;
352     wire io1_t;
353     wire io2_i;
354     wire io2_o;
355     wire io2_t;
356     wire io3_i;
357     wire io3_o;
358     wire io3_t;
359     wire ss_i;
360     wire ss_o;
361     wire ss_t;
362     
363     axi_quad_spi_0 U1 (
364       .ext_spi_clk(clk_100M),      // input wire ext_spi_clk
365       .s_axi_aclk(clk_100M),        // input wire s_axi_aclk
366       .s_axi_aresetn(~rst),  // input wire s_axi_aresetn
367       .s_axi_awaddr(m_axi_awaddr),    // input wire [6 : 0] s_axi_awaddr
368       .s_axi_awvalid(m_axi_awvalid),  // input wire s_axi_awvalid
369       .s_axi_awready(s_axi_awready),  // output wire s_axi_awready
370       .s_axi_wdata(m_axi_wdata),      // input wire [31 : 0] s_axi_wdata
371       .s_axi_wstrb(4'b1111),      // input wire [3 : 0] s_axi_wstrb
372       .s_axi_wvalid(m_axi_wvalid),    // input wire s_axi_wvalid
373       .s_axi_wready(s_axi_wready),    // output wire s_axi_wready
374       .s_axi_bresp(),      // output wire [1 : 0] s_axi_bresp
375       .s_axi_bvalid(s_axi_bvalid),    // output wire s_axi_bvalid
376       .s_axi_bready(m_axi_bready),    // input wire s_axi_bready
377       .s_axi_araddr(m_axi_araddr),    // input wire [6 : 0] s_axi_araddr
378       .s_axi_arvalid(m_axi_arvalid),  // input wire s_axi_arvalid
379       .s_axi_arready(s_axi_arready),  // output wire s_axi_arready
380       .s_axi_rdata(s_axi_rdata),      // output wire [31 : 0] s_axi_rdata
381       .s_axi_rresp(),      // output wire [1 : 0] s_axi_rresp
382       .s_axi_rvalid(s_axi_rvalid),    // output wire s_axi_rvalid
383       .s_axi_rready(m_axi_rready),    // input wire s_axi_rready
384       .io0_i(io0_i),                  // input wire io0_i
385       .io0_o(io0_o),                  // output wire io0_o
386       .io0_t(io0_t),                  // output wire io0_t
387       .io1_i(io1_i),                  // input wire io1_i
388       .io1_o(io1_o),                  // output wire io1_o
389       .io1_t(io1_t),                  // output wire io1_t
390       .io2_i(io2_i),                  // input wire io2_i
391       .io2_o(io2_o),                  // output wire io2_o
392       .io2_t(io2_t),                  // output wire io2_t
393       .io3_i(io3_i),                  // input wire io3_i
394       .io3_o(io3_o),                  // output wire io3_o
395       .io3_t(io3_t),                  // output wire io3_t
396       .ss_i(ss_i),                    // input wire [0 : 0] ss_i
397       .ss_o(ss_o),                    // output wire [0 : 0] ss_o
398       .ss_t(ss_t),                    // output wire ss_t
399       .cfgclk(cfgclk),                // output wire cfgclk
400       .cfgmclk(cfgmclk),              // output wire cfgmclk
401       .eos(eos),                      // output wire eos
402       .preq(preq),                    // output wire preq
403       .ip2intc_irpt(ip2intc_irpt)    // output wire ip2intc_irpt
404     );
405 
406     IOBUF   dq0(
407         .IO (spi_dq[0]),
408         .O  (io0_i),
409         .I  (io0_o),
410         .T  (io0_t)
411     );
412 
413     IOBUF   dq1(
414         .IO (spi_dq[1]),
415         .O  (io1_i),
416         .I  (io1_o),
417         .T  (io1_t)
418     );
419 
420     IOBUF   dq2(
421         .IO (spi_dq[2]),
422         .O  (io2_i),
423         .I  (io2_o),
424         .T  (io2_t)
425     );
426 
427     IOBUF   dq3(
428         .IO (spi_dq[3]),
429         .O  (io3_i),
430         .I  (io3_o),
431         .T  (io3_t)
432     );
433 
434     IOBUF   spiss(
435         .IO (spi_ss),
436         .O  (ss_i),
437         .I  (ss_o),
438         .T  (ss_t)
439     );
440 
441 endmodule

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM