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

状态跳转:

1.初始状态

将axi_lite读写两个信道分开进行控制,在初始状态,就根据读,写信号来判断应该跳转到那一个状态。

2.写状态

在写状态中不需要跳转条件,即写状态只需要消耗一个时钟周期,然后自动跳转到下一个状态。

3.写有效状态

当接收到slave端的awready 和 wready 即地址写准备和数据写准备信号后,跳转到write_ready状态。

4.write_ready状态

在write_ready状态中,等到slave端bvalid信号的到来,然后跳转到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是怎么右对齐的,bready和bvalid是怎么右对齐的,反正你需要知道这些信号之间的关系与实际的波形图。

这次加上了地址与数据。

读:

注意arvalid,rready信号的左边是怎么对齐的,右边的rready要多一个时钟周期。

 `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: chensimin
//
// Create Date: 2018/02/07 09:54:03
// Design Name:
// Module Name: ipc_axi_spi
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////// module axi_spi( input clk_100M,
inout [:]spi_dq,
inout spi_ss,
//-----------------------ipc_interface---------------------------
input wire [:] ipc_addr,
input wire [:] ipc_wdata,
output wire [:] ipc_rdata,
input wire ipc_rd,
input wire ipc_wr,
output wire ipc_ack ); //-------------------------------------------------------------- ila_0 your_instance_name (
.clk(clk_100M), // input wire clk
.probe0(ipc_wr_rise), // input wire [0:0] probe0
.probe1(ipc_rd_rise), // input wire [0:0] probe1
.probe2(m_axi_awvalid), // input wire [0:0] probe2
.probe3(m_axi_wvalid), // input wire [0:0] probe3
.probe4(m_axi_arvalid), // input wire [0:0] probe4
.probe5(m_axi_rready), // input wire [0:0] probe5
.probe6(m_axi_bready), // input wire [0:0] probe6
.probe7(s_axi_awready), // input wire [0:0] probe7
.probe8(s_axi_arready), // input wire [0:0] probe8
.probe9(s_axi_wready), // input wire [0:0] probe9
.probe10(s_axi_rvalid), // input wire [0:0] probe10
.probe11(s_axi_bvalid), // input wire [0:0] probe11
.probe12(io0_i), // input wire [0:0] probe12
.probe13(io0_o), // input wire [0:0] probe13
.probe14(io0_t), // input wire [0:0] probe14
.probe15(io1_i), // input wire [0:0] probe15
.probe16(io1_o), // input wire [0:0] probe16
.probe17(io1_t), // input wire [0:0] probe17
.probe18(io2_i), // input wire [0:0] probe18
.probe19(io2_o), // input wire [0:0] probe19
.probe20(io2_t), // input wire [0:0] probe20
.probe21(io3_i), // input wire [0:0] probe21
.probe22(io3_o), // input wire [0:0] probe22
.probe23(io3_t), // input wire [0:0] probe23
.probe24(ss_i), // input wire [0:0] probe24
.probe25(ss_o), // input wire [0:0] probe25
.probe26(ss_t), // input wire [0:0] probe26
.probe27(m_axi_awaddr), // input wire [6:0] probe27
.probe28(m_axi_araddr), // input wire [6:0] probe28
.probe29(current_state), // input wire [6:0] probe29
.probe30(next_state), // input wire [6:0] probe30
.probe31(m_axi_wdata), // input wire [31:0] probe31
.probe32(m_axi_rdata), // input wire [31:0] probe32
.probe33(s_axi_rdata), // input wire [31:0] probe33
.probe34(ipc_addr), // input wire [11:0] probe34
.probe35(ipc_wdata), // input wire [31:0] probe35
.probe36(ipc_rdata), // input wire [31:0] probe36
.probe37(ipc_rd), // input wire [0:0] probe37
.probe38(ipc_wr), // input wire [0:0] probe38
.probe39(ipc_ack) // input wire [0:0] probe39
); //-------------------------------------------------------------- reg ipc_rd_delay_1;
reg ipc_wr_delay_1;
reg ipc_rd_delay_2;
reg ipc_wr_delay_2;
wire ipc_rd_rise;
wire ipc_wr_rise;
always @(posedge clk_100M or posedge rst)
begin
if(rst)
begin
ipc_rd_delay_1 <= 'b0;
ipc_wr_delay_1 <= 'b0;
ipc_rd_delay_2 <= 'b0;
ipc_wr_delay_2 <= 'b0;
end
else
begin
ipc_rd_delay_1 <= ipc_rd;
ipc_wr_delay_1 <= ipc_wr;
ipc_rd_delay_2 <= ipc_rd_delay_1;
ipc_wr_delay_2 <= ipc_wr_delay_1;
end
end assign ipc_rd_rise = !ipc_rd_delay_2 && ipc_rd_delay_1;
assign ipc_wr_rise = !ipc_wr_delay_2 && ipc_wr_delay_1; //--------------------------------------------------------------
reg [:]current_state;
reg [:]next_state;
always @ (posedge clk_100M or posedge rst)
begin
if(rst)
current_state <= IDLE;
else
current_state <= next_state;
end //--------------------------------------------------------------
parameter [:] IDLE = 'd0 ,
WRITE_START = 'd1 ,
WRITE_VALID = 'd2 ,
WRITE_READY = 'd3 ,
WRITE_BREADY = 'd4 ,
WRITE_END = 'd5 ,
READ_START = 'd11 ,
READ_VALID = 'd12 ,
READ_READY = 'd13 ,
READ_FINISH = 'd14 ,
READ_END = 'd15 ; always @ (*)
begin
next_state = IDLE;
case(current_state)
IDLE:
begin
if(ipc_wr_rise)
next_state = WRITE_START;
else if(ipc_rd_rise)
next_state = READ_START;
else
next_state = IDLE;
end WRITE_START:
begin
next_state = WRITE_VALID;
end WRITE_VALID:
begin
if(s_axi_awready && s_axi_wready)
next_state = WRITE_READY;
else
next_state = WRITE_VALID;
end WRITE_READY:
begin
if(s_axi_bvalid)
next_state = WRITE_BREADY;
else
next_state = WRITE_READY;
end WRITE_BREADY:
begin
next_state = WRITE_END;
end WRITE_END:
begin
next_state = IDLE;
end READ_START:
begin
next_state = READ_VALID;
end READ_VALID:
begin
if(s_axi_arready)
next_state = READ_READY;
else
next_state = READ_VALID;
end READ_READY:
begin
if(s_axi_rvalid)
next_state = READ_FINISH;
else
next_state = READ_READY;
end READ_FINISH:
begin
next_state = READ_END;
end READ_END:
begin
next_state = IDLE;
end endcase
end //-------------------------------------------------------------
reg m_axi_awvalid;
reg m_axi_wvalid;
reg m_axi_arvalid; reg m_axi_rready;
reg m_axi_bready; reg [:]m_axi_awaddr;
reg [:]m_axi_araddr; reg [:]m_axi_wdata;
reg [:]m_axi_rdata; reg ipc_ack_r; always @(posedge clk_100M or posedge rst)
begin
if (rst)
begin
m_axi_awvalid <= 'b0;
m_axi_wvalid <= 'b0;
m_axi_arvalid <= 'b0;
m_axi_rready <= 'b0;
m_axi_bready <= 'b0;
m_axi_awaddr <= ;
m_axi_araddr <= ;
m_axi_wdata <= ;
m_axi_rdata <= ;
ipc_ack_r <= 'b0;
end
else
begin m_axi_awvalid <= 'b0;
m_axi_wvalid <= 'b0;
m_axi_arvalid <= 'b0;
m_axi_rready <= 'b0;
m_axi_bready <= 'b0;
ipc_ack_r <= 'b0; case(next_state)
//IDLE: WRITE_START:
begin
m_axi_awaddr <= ipc_addr[:];
m_axi_wdata <= ipc_wdata;
m_axi_awvalid <= 'b1;
m_axi_wvalid <= 'b1;
m_axi_bready <= 'b1;
end WRITE_VALID:
begin
m_axi_awvalid <= 'b1;
m_axi_wvalid <= 'b1;
m_axi_bready <= 'b1;
end WRITE_READY:
begin
m_axi_bready <= 'b1;
end //WRITE_BREADY:
WRITE_END:
begin
ipc_ack_r <= 'b1;
end READ_START:
begin
m_axi_araddr <= ipc_addr[:];
m_axi_arvalid <= 'b1;
end READ_VALID:
begin
m_axi_arvalid <= 'b1;
end //READ_READY: READ_FINISH:
begin
m_axi_rdata <= s_axi_rdata;
m_axi_rready <= 'b1;
end READ_END:
begin
ipc_ack_r <= 'b1;
end default:
begin
m_axi_awvalid <= 'b0;
m_axi_wvalid <= 'b0;
m_axi_arvalid <= 'b0;
m_axi_rready <= 'b0;
m_axi_bready <= 'b0;
ipc_ack_r <= 'b0;
end endcase end
end assign ipc_rdata = m_axi_rdata;
assign ipc_ack = ipc_ack_r; //-------------------------------------------------------------
wire s_axi_awready;
wire s_axi_arready;
wire s_axi_wready;
wire s_axi_rvalid;
wire s_axi_bvalid;
wire [:]s_axi_rdata; wire io0_i;
wire io0_o;
wire io0_t;
wire io1_i;
wire io1_o;
wire io1_t;
wire io2_i;
wire io2_o;
wire io2_t;
wire io3_i;
wire io3_o;
wire io3_t;
wire ss_i;
wire ss_o;
wire ss_t; axi_quad_spi_0 U1 (
.ext_spi_clk(clk_100M), // input wire ext_spi_clk
.s_axi_aclk(clk_100M), // input wire s_axi_aclk
.s_axi_aresetn(~rst), // input wire s_axi_aresetn
.s_axi_awaddr(m_axi_awaddr), // input wire [6 : 0] s_axi_awaddr
.s_axi_awvalid(m_axi_awvalid), // input wire s_axi_awvalid
.s_axi_awready(s_axi_awready), // output wire s_axi_awready
.s_axi_wdata(m_axi_wdata), // input wire [31 : 0] s_axi_wdata
.s_axi_wstrb('b1111), // input wire [3 : 0] s_axi_wstrb
.s_axi_wvalid(m_axi_wvalid), // input wire s_axi_wvalid
.s_axi_wready(s_axi_wready), // output wire s_axi_wready
.s_axi_bresp(), // output wire [1 : 0] s_axi_bresp
.s_axi_bvalid(s_axi_bvalid), // output wire s_axi_bvalid
.s_axi_bready(m_axi_bready), // input wire s_axi_bready
.s_axi_araddr(m_axi_araddr), // input wire [6 : 0] s_axi_araddr
.s_axi_arvalid(m_axi_arvalid), // input wire s_axi_arvalid
.s_axi_arready(s_axi_arready), // output wire s_axi_arready
.s_axi_rdata(s_axi_rdata), // output wire [31 : 0] s_axi_rdata
.s_axi_rresp(), // output wire [1 : 0] s_axi_rresp
.s_axi_rvalid(s_axi_rvalid), // output wire s_axi_rvalid
.s_axi_rready(m_axi_rready), // input wire s_axi_rready
.io0_i(io0_i), // input wire io0_i
.io0_o(io0_o), // output wire io0_o
.io0_t(io0_t), // output wire io0_t
.io1_i(io1_i), // input wire io1_i
.io1_o(io1_o), // output wire io1_o
.io1_t(io1_t), // output wire io1_t
.io2_i(io2_i), // input wire io2_i
.io2_o(io2_o), // output wire io2_o
.io2_t(io2_t), // output wire io2_t
.io3_i(io3_i), // input wire io3_i
.io3_o(io3_o), // output wire io3_o
.io3_t(io3_t), // output wire io3_t
.ss_i(ss_i), // input wire [0 : 0] ss_i
.ss_o(ss_o), // output wire [0 : 0] ss_o
.ss_t(ss_t), // output wire ss_t
.cfgclk(cfgclk), // output wire cfgclk
.cfgmclk(cfgmclk), // output wire cfgmclk
.eos(eos), // output wire eos
.preq(preq), // output wire preq
.ip2intc_irpt(ip2intc_irpt) // output wire ip2intc_irpt
); IOBUF dq0(
.IO (spi_dq[]),
.O (io0_i),
.I (io0_o),
.T (io0_t)
); IOBUF dq1(
.IO (spi_dq[]),
.O (io1_i),
.I (io1_o),
.T (io1_t)
); IOBUF dq2(
.IO (spi_dq[]),
.O (io2_i),
.I (io2_o),
.T (io2_t)
); IOBUF dq3(
.IO (spi_dq[]),
.O (io3_i),
.I (io3_o),
.T (io3_t)
); IOBUF spiss(
.IO (spi_ss),
.O (ss_i),
.I (ss_o),
.T (ss_t)
); endmodule

通过状态机来对axi_lite总线进行操作的更多相关文章

  1. 【转】AXI_Lite 总线详解

    目录: · 1.前言 · 2.AXI总线与ZYNQ的关系 · 3 AXI 总线和 AXI 接口以及 AXI 协议 · 3.1 AXI 总线概述 · 3.2 AXI 接口介绍 ·3.3 AXI 协议概述 ...

  2. S02_CH12_ AXI_Lite 总线详解

    S02_CH12_ AXI_Lite 总线详解 12.1前言 ZYNQ拥有ARM+FPGA这个神奇的架构,那么ARM和FPGA究竟是如何进行通信的呢?本章通过剖析AXI总线源码,来一探其中的秘密. 1 ...

  3. Keil C51总线外设操作问题的深入分析

    阅读了<单片机与嵌入式系统应用>2005年第10期杂志<经验交流>栏目的一篇文章<Keil C51对同一端口的连续读取方法>(原文)后,笔者认为该文并未就此问题进行 ...

  4. STM32F4XX中断方式通过IO模拟I2C总线Master模式

    STM32的I2C硬核为了规避NXP的知识产权,使得I2C用起来经常出问题,因此ST公司推出了CPAL库,CPAL库在中断方式工作下仅支持无子地址 的器件,无法做到中断方式完成读写大部分I2C器件.同 ...

  5. phxpaxos实现状态机CAS操作

    看过了phxpaxos的实现,发现选主逻辑中非主也能够调用Propose.因此即使开启了选主功能,也可能会出现两个人同时Propose的场景.而Propose时,InstanceID只是作为输出而非输 ...

  6. Zynq-PL中创建AXI Master接口IP及AXI4-Lite总线主从读写时序测试(转)

    转载:原文  http://www.eefocus.com/antaur/blog/17-08/423751_6cc0d.html 0. 引言 通过之前的学习,可以在PL端创建从机模式的AXI接口IP ...

  7. 总线读写---verilog代码

    总线读写---verilog代码 `timescale 1ns / 1ps ////////////////////////////////////////////////////////////// ...

  8. 一种基于uCos-II操作系统和lwIP协议栈的IEEE-1588主站以及基于该主站的报文处理方法

    主站以及应用于电力系统的支持IEEE‐1588协议的主时钟(IEEE‐1588主站)的实现方法.该方法是在一个低成本的硬件平台上,借助uCos‐II操作系统和TCP/IP的协议栈,对以太网数据进行了分 ...

  9. [WCF编程]10.操作:单向操作

    一.单向操作概述 WCF提供了单向操作,一旦客户端调用,WCF会生成一个请求,但没有相关的应答信息返回给客户端.所以,单向操作是不能有返回值,服务抛出的任何异常都不会传递给客户端. 理想情况下,一旦客 ...

随机推荐

  1. L2-008. 最长对称子串

    L2-008. 最长对称子串 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 对给定的字符串,本题要求你输出最长对称子串的长度. ...

  2. SQL注入之Sqli-labs系列第十九关(基于头部的Referer POST报错注入)

    开始挑战第十八关(Header Injection- Referer- Error Based- string) 先来说下HTTP Referer: HTTP Referer是header的一部分,当 ...

  3. SpringMVC详细示例实战教程(较全开发教程)

    SpringMVC学习笔记---- 一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于Spring ...

  4. Python之路,第十八篇:Python入门与基础18

    python3  面向对象编程2 类方法: @classmethod 作用:1,类方法是只能访问类变量的方法: 2,类方法需要使用@classmethod 装饰器定义: 3,类方法的第一个参数是类的实 ...

  5. [LeetCode&Python] Problem 107. Binary Tree Level Order Traversal II

    Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left ...

  6. js学习:return arguments

    return函数 arguments

  7. 2017-2018-1 20155219《信息安全技术》实验二——Windows口令破解

    2017-2018-1 20155320<信息安全技术>实验二--Windows口令破解 实验目的 了解Windows口令破解原理 对信息安全有直观感性认识 能够运用工具实现口令破解 实验 ...

  8. kmp--看毛片算法

    string str; int next[N];// 核♥: next[k] 字符串前(k-1)个元素有next[k]个相等前后缀 // 初始化 next[0]=-1; next[1]=0; void ...

  9. mask-code-python

    tf.sqeeze: 给定张量输入,此操作返回相同类型的张量,并删除所有尺寸为1的尺寸. 如果不想删除所有尺寸1尺寸,可以通过指定squeeze_dims来删除特定尺寸1尺寸.如果不想删除所有大小是1 ...

  10. 四则运算V1.1

    作业:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/997 代码:https://coding.net/u/Dawnfox/p/f4 ...