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. 指定某个div随着指定大div滚动,而不是随着整个窗口固定不动

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  2. JAVA的设计模式之观察者模式----结合ActiveMQ消息队列说明

    1----------------------观察者模式------------------------------ 观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的 ...

  3. [转]linux C/C++服务器后台开发面试题总结

    linux C/C++服务器后台开发面试题总结  https://www.cnblogs.com/nancymake/p/6516933.html 一.编程语言 1.根据熟悉的语言,谈谈两种语言的区别 ...

  4. 操作cookie篇

    1.设置cookie setcookie(key,value); 2.设置cookie有效期(默认值0,浏览器关闭失效,PHP_INT_MAX最大值,永久不失效,time()-1,删除cookie) ...

  5. Groovy实现代码热载的机制和原理

    前言: 真的很久没在博客园上更新博客了, 现在趁这段空闲的时间, 对之前接触的一些工程知识做下总结. 先来讲下借用Groovy如何来实现代码的热载, 以及其中涉及到的原理和需要注意的点. 总的来说, ...

  6. Java中的容器 I————浅谈List

    一.List接口的继承关系 List接口是Collection接口的子接口,而ArrayList和LinkedList以及Vector是其实现类. List的特点是可以将元素维护在特定的序列中,可以再 ...

  7. [Data Structure] An Algorithm for Matching Delimiters

    An important task when processing arithmetic expressions is to mach delimiters. We can use Stack to ...

  8. DES算法,JAVA,遇到的问题

    (1)使用Based64编码时出现的问题. java.lang.IllegalArgumentException 这中情况出现在解密时,主要原因是based64加密时用了sun的内部包sun.misc ...

  9. 变量与算术表达式 - C程序设计语言

    #include <stdio.h> int main() { float fahr,celsius; float lower,upper,step; lower = 0; upper = ...

  10. 算法训练 K好数 解析

    算法训练 K好数 时间限制:1.0s 内存限制:256.0MB 提交此题 锦囊1 锦囊2 问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K ...