通过状态机来对axi_lite总线进行操作
通过状态机来对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总线进行操作的更多相关文章
- 【转】AXI_Lite 总线详解
目录: · 1.前言 · 2.AXI总线与ZYNQ的关系 · 3 AXI 总线和 AXI 接口以及 AXI 协议 · 3.1 AXI 总线概述 · 3.2 AXI 接口介绍 ·3.3 AXI 协议概述 ...
- S02_CH12_ AXI_Lite 总线详解
S02_CH12_ AXI_Lite 总线详解 12.1前言 ZYNQ拥有ARM+FPGA这个神奇的架构,那么ARM和FPGA究竟是如何进行通信的呢?本章通过剖析AXI总线源码,来一探其中的秘密. 1 ...
- Keil C51总线外设操作问题的深入分析
阅读了<单片机与嵌入式系统应用>2005年第10期杂志<经验交流>栏目的一篇文章<Keil C51对同一端口的连续读取方法>(原文)后,笔者认为该文并未就此问题进行 ...
- STM32F4XX中断方式通过IO模拟I2C总线Master模式
STM32的I2C硬核为了规避NXP的知识产权,使得I2C用起来经常出问题,因此ST公司推出了CPAL库,CPAL库在中断方式工作下仅支持无子地址 的器件,无法做到中断方式完成读写大部分I2C器件.同 ...
- phxpaxos实现状态机CAS操作
看过了phxpaxos的实现,发现选主逻辑中非主也能够调用Propose.因此即使开启了选主功能,也可能会出现两个人同时Propose的场景.而Propose时,InstanceID只是作为输出而非输 ...
- Zynq-PL中创建AXI Master接口IP及AXI4-Lite总线主从读写时序测试(转)
转载:原文 http://www.eefocus.com/antaur/blog/17-08/423751_6cc0d.html 0. 引言 通过之前的学习,可以在PL端创建从机模式的AXI接口IP ...
- 总线读写---verilog代码
总线读写---verilog代码 `timescale 1ns / 1ps ////////////////////////////////////////////////////////////// ...
- 一种基于uCos-II操作系统和lwIP协议栈的IEEE-1588主站以及基于该主站的报文处理方法
主站以及应用于电力系统的支持IEEE‐1588协议的主时钟(IEEE‐1588主站)的实现方法.该方法是在一个低成本的硬件平台上,借助uCos‐II操作系统和TCP/IP的协议栈,对以太网数据进行了分 ...
- [WCF编程]10.操作:单向操作
一.单向操作概述 WCF提供了单向操作,一旦客户端调用,WCF会生成一个请求,但没有相关的应答信息返回给客户端.所以,单向操作是不能有返回值,服务抛出的任何异常都不会传递给客户端. 理想情况下,一旦客 ...
随机推荐
- 大数据-02-Scala入门
Scala 简介 它是一门基于JVM的面向函数和面向对象的编程语言, 它包含了求值表达式,闭包,切片操作,模式匹配,隐式转换等特性. 可变量/不可变量 可变集合/不可变集合.集合操作 函数 值函数 求 ...
- Python网络爬虫之requests模块(2)
session处理cookie proxies参数设置请求代理ip 基于线程池的数据爬取 xpath的解析流程 bs4的解析流程 常用xpath表达式 常用bs4解析方法 引入 有些时候,我们在使用爬 ...
- numpy unable to find vcvarsall.bat
出现这种情况,是需要引用vc的编译器,可以安装vs来解决,并且安装numpy前, 设置如下宏 SET VS100COMNTOOLS=%VS110COMNTOOLS% SET VS90COMNTOOLS ...
- arcgis server备份还原过程
一.备份过程 1.找到已经安装的arcgis server安装目录,并找到备份工具: 2.快捷键win + R启动cmd,将备份工具文件拖入cmd窗口,enter 3. 通过backup.py脚本进行 ...
- vertical起作用的条件
只有当display为行内块元素时(inline-block),vertical-align:middle:才生效,或者将display设置为table-cell,需要多行文字居中时才需要,单行文字, ...
- xdoj-1279(有趣的线段树--吉司机?!)
题目链接 一 核心: f(x)=91 (x<=100) f(x)=x-10 (x>100) 那么同一区间就可能不同的操作,那么该怎么解决呢? 我门直到同一区间的数据属于同一类别的时候再进行 ...
- lesson4Embedding-fastai
dense layer:mnist识别中,需要十组dense权重矩阵来计算这十个输出内容,conv矩阵每一个元素乘以另一个矩阵的元素并相加,得到一个值,最后加上sigmoid(softmax在二元情况 ...
- Atcode ABC105-C:Base -2 Number
C - Base -2 Number Time Limit: 2 sec / Memory Limit: 1024 MB Score : 300300 points Problem Statement ...
- testMk
test test test test test test xinz 个人编程,写一个命令行程序 Red Green 功能设计,并提交文档到github 功利主义是一种在西方影响巨大的伦理学说,其原则 ...
- strchr与sscanf
strchr(s,',')返回字符串s中从左往右第一个字符's'的指针: sscanf(输入的字符或字符串,“%格式符”,存储值):