博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

通过状态机来对axi_lite总线进行操作

Posted on 2018-03-08 10:29  沉默改良者  阅读(2665)  评论(0编辑  收藏  举报

通过状态机来对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