• 通过状态机来对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
  • 相关阅读:
    c#基于业务对象的筛选
    SQLServer索引调优实践
    C#中抽象类和接口的区别
    c#基础(2) 理解委托和事件
    建议学习jQuery的步骤!
    SQL SERVER存储过程调用存储过程并接收输出参数或返回值的方法
    ASP.NET基于JQUERY的高性能的TreeView
    GetManifestResourceStream得到的Stream是null的解决
    Using GDI+ on Windows Mobile 初体验
    提供一个Windows mobile Native UI 程序,循序渐进开发,并附有代码!
  • 原文地址:https://www.cnblogs.com/chensimin1990/p/8526921.html
Copyright © 2020-2023  润新知