AXI_LITE源码学习笔记

1. axi_awready信号的产生

准备接收写地址信号

// Implement axi_awready generation
// axi_awready is asserted for one S_AXI_ACLK clock cycle when both
// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
// de-asserted when reset is low. always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 'b0 )
begin
axi_awready <= 'b0;
aw_en <= 'b1;
end
else
begin
if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)
//当满足输入信号 S_AXI_AWVALID写地址有效,S_AXI_WVALID 写数据有效 都为‘1’时,axi_awready被置‘1’ ~axi_awready作为触发条件,互锁的设计
begin
// slave is ready to accept write address when
// there is a valid write address and write data
// on the write address and data bus. This design
// expects no outstanding transactions.
axi_awready <= 'b1;
aw_en <= 'b0;
end
else if (S_AXI_BREADY && axi_bvalid)
//aw_en 写地址使能置‘1’的条件:
// S_AXI_BREADY 输入信号为‘1’,即主机准备接收写响应信号,说明上一个写操作已经完成了
// axi_bvalid 表示写操作有效信号
begin
aw_en <= 'b1;
axi_awready <= 'b0;
end
else
begin
axi_awready <= 'b0;
end
end
end

2.axi_awaddr信号的锁存

    // Implement axi_awaddr latching
// This process is used to latch the address when both
// S_AXI_AWVALID and S_AXI_WVALID are valid. always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 'b0 )
begin
axi_awaddr <= ;
end
else
begin
if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)
//锁存awaddr的条件为:
//axi_awready 写地址ready为0,表示正在接收写地址信号,
//S_AXI_AWVALID S_AXI_WVALID 为1 表示 写地址信号和写数据信号均有效
begin
// Write Address latching
axi_awaddr <= S_AXI_AWADDR; //锁存awaddr 写地址信号
end
end
end

3.axi_wready信号的产生,准备接收写数据信号

// Implement axi_wready generation
// axi_wready is asserted for one S_AXI_ACLK clock cycle when both
// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is
// de-asserted when reset is low. always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 'b0 )
begin
axi_wready <= 'b0;
end
else
begin
if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID && aw_en )
// axi_wready信号产生的条件为:
// S_AXI_WVALID S_AXI_AWVALID 为‘1’ 表示写数据有效,写地址有效
begin
// slave is ready to accept write data when
// there is a valid write address and write data
// on the write address and data bus. This design
// expects no outstanding transactions.
axi_wready <= 'b1; //产生 write data ready 信号
end
else
begin
axi_wready <= 'b0;
end
end
end

4. S_AXI_WDATA信号的锁存

// Implement memory mapped register select and write logic generation
// The write data is accepted and written to memory mapped registers when
// axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
// select byte enables of slave registers while writing.
// These registers are cleared when reset (active low) is applied.
// Slave register write enable is asserted when valid address and data are available
// and the slave is ready to accept the write address and write data.
assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;
 //锁存S_AXI_WDATA信号的条件为:
//两个ready 两个valid
//axi_wready , 输出信号, 从设备可以接受写数据
//S_AXI_WVALID, 输入信号,主设备写数据有效
//axi_awready, 输出信号,表示从设备可以接受写地址信号
//S_AXI_AWVALID, 输入信号,表示主设备写地址有效
//input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR, always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 'b0 )
begin
slv_reg0 <= ;
slv_reg1 <= ;
slv_reg2 <= ;
slv_reg3 <= ;
end
else begin
if (slv_reg_wren) //接受写地址和写数据使能
begin
case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
//数据存储在哪一个寄存器中取决于axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]中的两位,即这两位中存储的是控制信号
'h0:
for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
if ( S_AXI_WSTRB[byte_index] == ) begin //写选通信号
// Respective byte enables are asserted as per write strobes
// Slave register 0
slv_reg0[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
end
'h1:
for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
if ( S_AXI_WSTRB[byte_index] == ) begin
// Respective byte enables are asserted as per write strobes
// Slave register 1
slv_reg1[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
end
'h2:
for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
if ( S_AXI_WSTRB[byte_index] == ) begin
// Respective byte enables are asserted as per write strobes
// Slave register 2
slv_reg2[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
end
'h3:
for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
if ( S_AXI_WSTRB[byte_index] == ) begin
// Respective byte enables are asserted as per write strobes
// Slave register 3
slv_reg3[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
end
default : begin
slv_reg0 <= slv_reg0;
slv_reg1 <= slv_reg1;
slv_reg2 <= slv_reg2;
slv_reg3 <= slv_reg3;
end
endcase
end
end
end

5.写响应信号的产生bvalid, 表示本次写操作有效(1个时钟脉冲)

// Implement write response logic generation
// The write response and response valid signals are asserted by the slave
// when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.
// This marks the acceptance of address and indicates the status of
// write transaction. always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 'b0 )
begin
axi_bvalid <= ;
axi_bresp <= 'b0;
end
else
begin
if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID)
//产生条件:
//两个valid,两个ready, 互锁设计 ~bvalid
begin
// indicates a valid write response is available
axi_bvalid <= 'b1;
axi_bresp <= 'b0; // 'OKAY' response
end // work error responses in future
else
begin
if (S_AXI_BREADY && axi_bvalid)
//条件:
// S_AXI_BREADY 主机准备接收写响应信号
// axi_bvalid 信号为‘1’
//check if bready is asserted while bvalid is high)
//(there is a possibility that bready is always asserted high)
begin
axi_bvalid <= 'b0;
end
end
end
end

6.axi_arready (准备接收读地址信号)信号的产生与S_AXI_ARADDR信号的锁存

// Implement axi_arready generation
// axi_arready is asserted for one S_AXI_ACLK clock cycle when
// S_AXI_ARVALID is asserted. axi_awready is
// de-asserted when reset (active low) is asserted.
// The read address is also latched when S_AXI_ARVALID is
// asserted. axi_araddr is reset to zero on reset assertion. always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 'b0 )
begin
axi_arready <= 'b0;
axi_araddr <= 'b0;
end
else
begin
if (~axi_arready && S_AXI_ARVALID)
//S_AXI_ARVALID 主机给定读地址有效信号
//~axi_arready 为互锁设计
begin
// indicates that the slave has acceped the valid read address
axi_arready <= 'b1; //读地址操作
// Read address latching
axi_araddr <= S_AXI_ARADDR; // ready 信号置位的同时,锁存读地址信号
end
else
begin
axi_arready <= 'b0;
end
end
end

7. axi_rvalid(读数据有效)信号的产生(为1个脉冲信号)

// Implement axi_arvalid generation
// axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both
// S_AXI_ARVALID and axi_arready are asserted. The slave registers
// data are available on the axi_rdata bus at this instance. The
// assertion of axi_rvalid marks the validity of read data on the
// bus and axi_rresp indicates the status of read transaction.axi_rvalid
// is deasserted on reset (active low). axi_rresp and axi_rdata are
// cleared to zero on reset (active low).
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 'b0 )
begin
axi_rvalid <= ;
axi_rresp <= ;
end
else
begin
if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)
//置位的条件为:
// 读地址ready信号置‘1’
// 读地址有效
// ~axi_rvalid 为互锁设计
begin
// Valid read data is available at the read data bus
axi_rvalid <= 'b1;
axi_rresp <= 'b0; // 'OKAY' response
end
else if (axi_rvalid && S_AXI_RREADY)
// S_AXI_RREADY 表示主机准备接收读取出来的数据
begin
// Read data is accepted by the master
axi_rvalid <= 'b0;
end
end
end

8.axi_rdata读出数据的驱动

// Implement memory mapped register select and read logic generation
// Slave register read enable is asserted when valid address is available
// and the slave is ready to accept the read address.
assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid; // axi_arready, 输出信号, 表示从设备可以接受读地址信号
// S_AXI_ARVALID 输入信号,表示读地址信号有效
// axi_rvalid 输出信号, 表示读取的数据有效 // read always @(*)
begin
// Address decoding for reading registers
case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
//由给定的axi_araddr信号中的[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]中的两位来决定哪一个寄存器中的值来驱动reg_data_out
'h0 : reg_data_out <= slv_reg0;
'h1 : reg_data_out <= slv_reg1;
'h2 : reg_data_out <= slv_reg2;
'h3 : reg_data_out <= slv_reg3;
default : reg_data_out <= ;
endcase
end // Output register or memory read data
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 'b0 )
begin
axi_rdata <= ;
end
else
begin
// When there is a valid read address (S_AXI_ARVALID) with
// acceptance of read address by the slave (axi_arready),
// output the read dada
if (slv_reg_rden)
begin
axi_rdata <= reg_data_out; // register read data
end
end
end

AXI_LITE源码学习笔记的更多相关文章

  1. Underscore.js 源码学习笔记(下)

    上接 Underscore.js 源码学习笔记(上) === 756 行开始 函数部分. var executeBound = function(sourceFunc, boundFunc, cont ...

  2. Underscore.js 源码学习笔记(上)

    版本 Underscore.js 1.9.1 一共 1693 行.注释我就删了,太长了… 整体是一个 (function() {...}());  这样的东西,我们应该知道这是一个 IIFE(立即执行 ...

  3. Hadoop源码学习笔记(6)——从ls命令一路解剖

    Hadoop源码学习笔记(6) ——从ls命令一路解剖 Hadoop几个模块的程序我们大致有了点了解,现在我们得细看一下这个程序是如何处理命令的. 我们就从原头开始,然后一步步追查. 我们先选中ls命 ...

  4. Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构

    Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构 之前我们简要的看过了DataNode的main函数以及整个类的大至,现在结合前面我们研究的线程和RPC,则可以进一步 ...

  5. Hadoop源码学习笔记(4) ——Socket到RPC调用

    Hadoop源码学习笔记(4) ——Socket到RPC调用 Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程.那这里如何让网络编程变得简单.透明的呢? 网络编程中,首先我们要 ...

  6. Hadoop源码学习笔记(3) ——初览DataNode及学习线程

    Hadoop源码学习笔记(3) ——初览DataNode及学习线程 进入了main函数,我们走出了第一步,接下来看看再怎么走: public class DataNode extends Config ...

  7. Hadoop源码学习笔记(2) ——进入main函数打印包信息

    Hadoop源码学习笔记(2) ——进入main函数打印包信息 找到了main函数,也建立了快速启动的方法,然后我们就进去看一看. 进入NameNode和DataNode的主函数后,发现形式差不多: ...

  8. Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类

    Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何 ...

  9. JDK源码学习笔记——LinkedHashMap

    HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序. LinkedHashMap保证了元素迭代的顺序.该迭代顺序可以是插入顺序或者是访问顺序.通过维护一个 ...

随机推荐

  1. Kesci: Keras 实现 LSTM——时间序列预测

    博主之前参与的一个科研项目是用 LSTM 结合 Attention 机制依据作物生长期内气象环境因素预测作物产量.本篇博客将介绍如何用 keras 深度学习的框架搭建 LSTM 模型对时间序列做预测. ...

  2. PTA——类型转换

    PTA习题 7-6 厘米换算英尺英寸 (15 分) #include<stdio.h> int main(){ int a; int b,c; scanf("%d",& ...

  3. UE4 C++ Tips

    篇写的是关于UE4的C++方面的小技巧: 1.在构造函数里 //构建组件 RootComponent = CreateDefaultSubobject<USceneComponent>(T ...

  4. RESTful规范(二)

    七 解析器 解析器的作用: -用来解析前台传过来的数据编码方式 urlencoded:form表单:name=lqz&age= formdata :上传文件:--dadfgdgag-- jso ...

  5. MySQL数据库-外键链表之一对多,多对多

    外键链表之一对多 外键链表:就是a表通过外键连接b表的主键,建立链表关系,需要注意的是a表外键字段类型,必须与要关联的b表的主键字段类型一致,否则无法创建索引 一对多:就是b表的某一个字段值对应a表外 ...

  6. Java中的Graphics2D类基本使用教程

    Java语言在Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供.坐标转换.颜色管理以及文字布局等更精确的 ...

  7. MySQL数据库的学习

    ------------------------------------- 管理数据库PS: Mysql的管理 主要是包括 用户的管理. show........各种的信息   SHOW COLUMN ...

  8. Go语言实战 (William,Kennedy 等著)

    第1章 关于Go语言的介绍 (已看) 1.1 用Go解决现代编程难题 1.1.1 开发速度 1.1.2 并发 1. goroutine 2. 通道 1.1.3 Go语言的类型系统 1. 类型简单 2. ...

  9. Unity 原厂免费资源学习

     

  10. 让Windows XP的键盘“说话”,全语音键盘

    长期面对无声的电脑,我们难免疲倦.如果正在输入的内容被系统一字(字母)不差地念出来,你还能在无声的疲倦中输入错误的内容吗?本文以Windows 2000/XP中一个鲜为人知的“讲述人”为例,来教你DI ...