AXXI4总线协议 ------ AXI_FULL协议

https://download.csdn.net/download/mvpkuku/90855619

 一、AXI_FULL协议的前提知识

1. 各端口的功能

2. 4K边界问题 

3. outstanding 

4.时序仿真体验 

可通过VIVADO自带ADMA工程观察仿真波形图

二、FPGA实现 (主要用于读写DDR)

1.功能模块及框架

将用户端的写/读相关信号转换为AXI4_MASTER接口信号。因此顶层设计主要分为用户端接口以及AXI4协议主机接口

1、换存数据量较小的时候,FIFO建议采用DRAM
DRAM是由逻辑资源搭建而成的,消耗的是LUT的资源
缓存命令、地址、帧长度等等。

2、缓存数据量比较大的时候,采用BRAM,
BRAM是一种资源。

18k = 18 * 1024bit = 36bit(最大宽度) * 512(深度)= 18bit * 1024 = 9bit * 2048
36k = 2 * 18k = 72bit(最大宽度) * 512(深度)= 36bit * 1024 = 18bit * 2048
37bit = 36bit + 36bit

FIFO使用了一个18k的bram,即使FIFo的深度和宽度开的很小,很多空间没有使用,
这个FIFO的消耗的BRAM,不能被其他的模块(FIFO)使用
FIFO采用BRAM的时候,消耗最少相同的BARM数量,建议把FIFO的深度和宽度开到最大

AXI_DATA_WIDTH == 64
64bit + 1bit = 65bit = 36bit + 36bit  至少2个18k bram

2.写通道实现 

2.1 wr_ctrl模块 

写入用户端信号(写使能,写数据,写地址)

1.对复位信号以及ddr初始化完成信号进行同步,进而对用户端信号进行有效寄存

2.对用户端写数据进行计数(位宽转换,突发写字节数)

3.生成数据及数据有效,写数据最后一位,写突发长度

4.生成写请求和写地址

ps:3、4输出信号均给wr_buffer模块进行跨时钟与缓存

下一个模块的cmd_wren在wr_req_en为1时拉高,并且此模块在此时更新地址

wr_req_en作为wr_buffer状态机启动信号

2.2 wr_buffer模块

1.复位信号进行跨时钟域同步(用户时钟/AXI4时钟)

2.将地址和length写入CMD fifo (clk),cmd_wren在wr_req_en为1时拉高,并且此时更新地址

3..将数据和last 写入data fifo

写数据随着上层数据有效写入data_fifo

4.状态机设计(输出传给axi4_master模块)

axi_aw_req_en和axi_aw_ready)握手机制控制是否开始写状态

//表示AXI4写请求  本模块时序控制,状态机一个状态产生请求信号,握手成功之后拉低
//axi_aw_req_en 和axi_aw_ready同时为高,开启一次AXI4写传输

并在该信号跳转开始写数据状态的同时,拉高cmd_rden,读出数据突发长度以及写地址

5.输出信号的时序

突发长度和地址cmd_dout分配

其次是是数据有效同上,已进入写数据状态就拉高

数据和last由当data_en为高时由data_dout分配

三个信号同步

2.3 axi_master模块

1.对除了与下游从机交互的握手信号以及写地址,写突发长度的信号进行固定赋值;

2. axi_aw_req_en启动状态机

3.组合逻辑输出作为丛机给wr_buffer的握手准备信号,一个由状态机产生,一个由下游从机输入

4.对和下游从机交互的握手信号以及写地址,写突发长度以及数据,数据最后一位的信号 时序控制

2.4 实现顶层代码 

`timescale 1ns / 1ps
//
// Description: 写通道
//
module axi_wr_channel#(parameter		USER_WR_DATA_WIDTH = 16  ,parameter       AXI_DATA_WIDTH     = 128 ,parameter       AXI_ADDR_WIDTH     = 32  
)(input                              user_wr_clk       , //用户端写时钟input                              axi_clk           , // AXI4端时钟input                              reset             ,input                              ddr_init_done     ,/*-------------用户写端口信号------------------------*/input                              user_wr_en        ,input   [USER_WR_DATA_WIDTH-1:0]   user_wr_data      ,input   [AXI_ADDR_WIDTH-1:0]       user_wr_base_addr , //一定要被4096整除input   [AXI_ADDR_WIDTH-1:0]       user_wr_end_addr  , //一定要被4096整除	/*-------------AXI写通道端口信号---------------------*/output                             m_axi_awvalid     ,input                              m_axi_awready     ,output  [AXI_ADDR_WIDTH-1:0]       m_axi_awaddr      ,output  [3:0]                      m_axi_awid        ,output  [7:0]                      m_axi_awlen       ,output  [1:0]                      m_axi_awburst     ,output  [2:0]                      m_axi_awsize      ,output  [2:0]                      m_axi_awport      ,output  [3:0]                      m_axi_awqos       ,output                             m_axi_awlock      ,output  [3:0]                      m_axi_awcache     ,output                             m_axi_wvalid      ,input                              m_axi_wready      ,output  [AXI_DATA_WIDTH-1:0]       m_axi_wdata       ,output  [AXI_DATA_WIDTH/8-1:0]     m_axi_wstrb       ,   	output                             m_axi_wlast  	 ,input      [3:0]                   m_axi_bid         ,input      [1:0]                   m_axi_bresp       ,input                              m_axi_bvalid      ,output                             m_axi_bready      
);wire                          wr_req_en;wire [7:0]                    wr_burst_length;wire [AXI_ADDR_WIDTH-1:0]     wr_data_addr;wire                          wr_data_valid;wire [AXI_DATA_WIDTH-1:0]     wr_data_out;wire                          wr_data_last;wire                          axi_aw_req_en;wire                      	  axi_aw_ready;wire [7:0] 	  				  axi_aw_burst_len;wire [AXI_ADDR_WIDTH-1:0] 	  axi_aw_addr;wire                      	  axi_w_valid;wire                      	  axi_w_ready;wire [AXI_DATA_WIDTH-1:0] 	  axi_w_data;wire                      	  axi_w_last;wr_ctrl #(.USER_WR_DATA_WIDTH(USER_WR_DATA_WIDTH),.AXI_DATA_WIDTH(AXI_DATA_WIDTH),.AXI_ADDR_WIDTH(AXI_ADDR_WIDTH),.WR_BURST_LENGTH(1024)) wr_ctrl (.clk               (user_wr_clk),.reset             (reset),.ddr_init_done     (ddr_init_done),.user_wr_en        (user_wr_en),.user_wr_data      (user_wr_data),.user_wr_base_addr (user_wr_base_addr),.user_wr_end_addr  (user_wr_end_addr),.wr_req_en         (wr_req_en),.wr_burst_length   (wr_burst_length),.wr_data_addr      (wr_data_addr),.wr_data_valid     (wr_data_valid),.wr_data_out       (wr_data_out),.wr_data_last      (wr_data_last));wr_buffer #(.AXI_DATA_WIDTH(AXI_DATA_WIDTH),.AXI_ADDR_WIDTH(AXI_ADDR_WIDTH)) wr_buffer (.clk              (user_wr_clk),.axi_clk          (axi_clk),.reset            (reset),.wr_req_en        (wr_req_en),.wr_burst_length  (wr_burst_length),.wr_data_addr     (wr_data_addr),.wr_data_valid    (wr_data_valid),.wr_data_in       (wr_data_out),.wr_data_last     (wr_data_last),.axi_aw_req_en    (axi_aw_req_en),.axi_aw_ready     (axi_aw_ready),.axi_aw_burst_len (axi_aw_burst_len),.axi_aw_addr      (axi_aw_addr),			.axi_w_valid      (axi_w_valid),.axi_w_ready      (axi_w_ready),.axi_w_data       (axi_w_data),.axi_w_last       (axi_w_last));axi_wr_master #(.AXI_DATA_WIDTH(AXI_DATA_WIDTH),.AXI_ADDR_WIDTH(AXI_ADDR_WIDTH)) axi_wr_master (.axi_clk          (axi_clk),.reset            (reset),.axi_aw_req_en    (axi_aw_req_en),.axi_aw_ready     (axi_aw_ready),.axi_aw_burst_len (axi_aw_burst_len),.axi_aw_addr      (axi_aw_addr),.axi_w_valid      (axi_w_valid),.axi_w_ready      (axi_w_ready),.axi_w_data       (axi_w_data),.axi_w_last       (axi_w_last),.m_axi_awvalid    (m_axi_awvalid),.m_axi_awready    (m_axi_awready),.m_axi_awaddr     (m_axi_awaddr),.m_axi_awid       (m_axi_awid),.m_axi_awlen      (m_axi_awlen),.m_axi_awburst    (m_axi_awburst),.m_axi_awsize     (m_axi_awsize),.m_axi_awport     (m_axi_awport),.m_axi_awqos      (m_axi_awqos),.m_axi_awlock     (m_axi_awlock),.m_axi_awcache    (m_axi_awcache),.m_axi_wvalid     (m_axi_wvalid),.m_axi_wready     (m_axi_wready),.m_axi_wdata      (m_axi_wdata),.m_axi_wstrb      (m_axi_wstrb),.m_axi_wlast      (m_axi_wlast),.m_axi_bid        (m_axi_bid),.m_axi_bresp      (m_axi_bresp),.m_axi_bvalid     (m_axi_bvalid),.m_axi_bready     (m_axi_bready));endmodule

2.5 部分仿真时序图 

3.读通道实现 

3.1 rd_ctrl模块

基本上与wr_ctrl模块类似,主要注意几个区别:

1.状态机由读请求的上升沿在ddr初始化完成之后启动;

2.给用户端读忙的信号,只要不处于初始态  user_rd_req_busy

3.wr-buffer输入fifo是否写满的信号 rd_req_ready

3.2 rd_buffer模块 

同理:仍然与wr_buffer对比

1. rd_cmd_fifo 

通过 cmd_wrcount 给出 fifo是否写满的信号 rd_req_ready,在这个前提下cmd开始写入fifo

cmd_rden由下游axi_master的握手信号控制

2. rd_data_fifo

        由下游axi_master 数据写入 (axi_clk)data_wren/data_din;

        data_rden 需要data_fifo非空,并且不在data_fifo非读,一周期拉低

        rd_data_fifo_out :在data_rden一次性读取位宽128的数据,然后在rd_data_flag进行数据的移位

        rd_data_fifo_last:通过data_dout[64]判断是否为1,持续最后一个128位宽数据时间

3. 状态机起始跳转需要cmd非空而且data_fifo没写满;

结束跳转的条件

4.最后将rd_data_fifo_out截取16位给到用户端口,同步数据有效,rd_data_fifo_last计数最后一个移位数据给到用户端口

 3.3 axi_rd_master模块

 m_axi控制拉低,axi_控制拉高

`timescale 1ns / 1ps
//
// Description:读通道
/
module axi_rd_channel#(parameter	AXI_DATA_WIDTH      = 128,parameter   AXI_ADDR_WIDTH      = 32 ,parameter   USER_RD_DATA_WIDTH	= 16)(input                              user_rd_clk       , //用户端读时钟input                              axi_clk           , //axi的时钟input                              reset             ,input                              ddr_init_done     ,/*--------------用户端读请求信号----------------------*/input                              user_rd_req        , //上升沿触发用户读请求input    [AXI_ADDR_WIDTH-1:0]      user_rd_base_addr  , //一定要被4096整除input    [AXI_ADDR_WIDTH-1:0]      user_rd_end_addr   , //一定要被4096整除output                             user_rd_req_busy   , //用户读请求忙标志	output  						   user_rd_valid      ,output                             user_rd_last       ,output   [USER_RD_DATA_WIDTH-1:0]  user_rd_data       ,/*-------------AXI读通道端口信号---------------------*/output                             m_axi_arvalid     ,input                              m_axi_arready     ,output   [AXI_ADDR_WIDTH-1:0]      m_axi_araddr      ,output   [3:0]                     m_axi_arid        ,output   [7:0]                     m_axi_arlen       ,output   [1:0]                     m_axi_arburst     ,output   [2:0]                     m_axi_arsize      ,output   [2:0]                     m_axi_arport      ,output   [3:0]                     m_axi_arqos       ,output                             m_axi_arlock      ,output   [3:0]                     m_axi_arcache     ,input    [3:0]                     m_axi_rid         ,input                              m_axi_rvalid      ,output                             m_axi_rready      ,input    [AXI_DATA_WIDTH-1:0]      m_axi_rdata       ,input                              m_axi_rlast       ,input    [1:0]                     m_axi_rresp     );wire                          rd_req_en       ;wire                [7:0]     rd_burst_length ;wire [AXI_ADDR_WIDTH-1:0]     rd_data_addr    ;wire                          rd_req_ready    ;wire                          axi_ar_req_en   ;wire                          axi_ar_ready    ;wire [7:0]                    axi_ar_burst_len;wire [AXI_ADDR_WIDTH-1:0]     axi_ar_addr     ;wire                          axi_r_valid     ;wire [AXI_DATA_WIDTH-1:0]     axi_r_data      ;wire                          axi_r_last      ;rd_ctrl #(.AXI_DATA_WIDTH(AXI_DATA_WIDTH),.AXI_ADDR_WIDTH(AXI_ADDR_WIDTH),.RD_BURST_LENGTH(1024)) rd_ctrl (.clk               (user_rd_clk),.reset             (reset),.ddr_init_done     (ddr_init_done),.user_rd_req       (user_rd_req),.user_rd_base_addr (user_rd_base_addr),.user_rd_end_addr  (user_rd_end_addr),.user_rd_req_busy  (user_rd_req_busy),.rd_req_en         (rd_req_en),.rd_burst_length   (rd_burst_length),.rd_data_addr      (rd_data_addr),.rd_req_ready      (rd_req_ready));rd_buffer #(.AXI_DATA_WIDTH(AXI_DATA_WIDTH),.AXI_ADDR_WIDTH(AXI_ADDR_WIDTH),.USER_RD_DATA_WIDTH(USER_RD_DATA_WIDTH)) rd_buffer (.clk              (user_rd_clk),.axi_clk          (axi_clk),.reset            (reset),.rd_req_en        (rd_req_en),.rd_burst_length  (rd_burst_length),.rd_data_addr     (rd_data_addr),.rd_req_ready     (rd_req_ready),.axi_ar_req_en    (axi_ar_req_en),.axi_ar_ready     (axi_ar_ready),.axi_ar_burst_len (axi_ar_burst_len),.axi_ar_addr      (axi_ar_addr),.axi_r_valid      (axi_r_valid),.axi_r_data       (axi_r_data),.axi_r_last       (axi_r_last),.user_rd_valid    (user_rd_valid),.user_rd_last     (user_rd_last),.user_rd_data     (user_rd_data));axi_rd_master #(.AXI_DATA_WIDTH(AXI_DATA_WIDTH),.AXI_ADDR_WIDTH(AXI_ADDR_WIDTH)) axi_rd_master (.axi_clk          (axi_clk),.reset            (reset),.axi_ar_req_en    (axi_ar_req_en),.axi_ar_ready     (axi_ar_ready),.axi_ar_burst_len (axi_ar_burst_len),.axi_ar_addr      (axi_ar_addr),.axi_r_valid      (axi_r_valid),.axi_r_data       (axi_r_data),.axi_r_last       (axi_r_last),.m_axi_arvalid    (m_axi_arvalid),.m_axi_arready    (m_axi_arready),.m_axi_araddr     (m_axi_araddr),.m_axi_arid       (m_axi_arid),.m_axi_arlen      (m_axi_arlen),.m_axi_arburst    (m_axi_arburst),.m_axi_arsize     (m_axi_arsize),.m_axi_arport     (m_axi_arport),.m_axi_arqos      (m_axi_arqos),.m_axi_arlock     (m_axi_arlock),.m_axi_arcache    (m_axi_arcache),.m_axi_rid        (m_axi_rid),.m_axi_rvalid     (m_axi_rvalid),.m_axi_rready     (m_axi_rready),.m_axi_rdata      (m_axi_rdata),.m_axi_rlast      (m_axi_rlast),.m_axi_rresp      (m_axi_rresp));endmodule

4.仿真实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/81625.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React系列——nvm、node、npm、yarn(MAC)

nvm,node,npm之间的区别 1、nvm:nodejs版本管理工具。nvm 可以管理很多 node 版本和 npm 版本。 2、nodejs:在项目开发时的所需要的代码库 3、npm:nodejs包管理工具。nvm、nodejs、npm的关系 nvm 管理 nodejs 和 npm…

2025年AI与网络安全的终极博弈:冲击、重构与生存法则

引言 2025年,生成式AI的推理速度突破每秒千万次,网络安全行业正经历前所未有的范式革命。攻击者用AI批量生成恶意代码,防御者用AI构建智能护盾,这场技术军备竞赛正重塑行业规则——60%的传统安全岗位面临转型,70%的防…

【Android】Android 实现一个依赖注入的注解

Android 实现一个依赖注入的注解 🎯 目标功能 自定义注解 Inject创建一个 Injector 类,用来扫描并注入对象支持 Activity 或其他类中的字段注入 🧩 步骤一:定义注解 import java.lang.annotation.ElementType; import java.lan…

Spring Boot与Kafka集成实践:从入门到实战

Spring Boot与Kafka集成实践 引言 在现代分布式系统中,消息队列是不可或缺的组件之一。Apache Kafka作为一种高吞吐量的分布式消息系统,广泛应用于日志收集、流处理、事件驱动架构等场景。Spring Boot作为Java生态中最流行的微服务框架,提供…

ubuntu的虚拟机上的网络图标没有了

非正常的关机导致虚拟机连接xshell连接不上,ping也ping不通。网络的图标也没有了。 记录一下解决步骤 1、重启服务 sudo systemctl restart NetworkManager 2、图标显示 sudo nmcli network off sudo nmcli network on 3、sudo dhclient ens33 //(网卡) …

生产者 - 消费者模式实现方法整理

一、Channels &#xff08;一&#xff09;使用场景 适用于高并发、大数据量传输&#xff0c;且需要异步操作的场景&#xff0c;如实时数据处理系统。 &#xff08;二&#xff09;使用方法 创建 Channel<T>&#xff08;无界&#xff09;或 BoundedChannel<T>&…

OpenCV光流估计:原理、实现与应用

一、什么是光流&#xff1f; 光流(Optical Flow)是计算机视觉中描述图像序列中像素运动模式的重要概念。它表示图像中物体在连续帧之间的表观运动&#xff0c;是由物体或相机的运动引起的。 光流的基本假设 亮度恒常性&#xff1a;同一物体点在连续帧中的亮度保持不变时间持…

Java实现MinIO上传PDF文件并配置浏览器在线打开及vue2上传页面

win下载启动minio结合vue2实现文件上传浏览 一.下载启动minio 1. 下载minio 2.在D盘创建文件夹 1.首先创建minio文件夹再minio中依次创建bin/data/logs,如下图 2.把下载的minio.exe放到minio->bin文件中 3.在bin文件夹中输入cmd打开命令框输入命令minio.exe server D:…

VR 互动实训与展示,借科技开启沉浸式体验新篇​

对于企业而言&#xff0c;产品设计与展示是极为关键的环节&#xff0c;这直接关系到能否成功吸引客户&#xff0c;以及精准获取市场反馈。在当下科技飞速发展的时代&#xff0c;VR 互动实训为这一至关重要的环节注入了全新活力&#xff0c;带来了前所未有的体验。以某智能家居企…

进阶-数据结构部分:1、数据结构入门

飞书文档https://x509p6c8to.feishu.cn/wiki/HRLkwznHiiOgZqkqhLrcZNqVnLd 一、存储结构 顺序存储 链式存储 二、常用数据结构 2.1、栈 先进后出 场景&#xff1a; 后退/前进功能&#xff1a;网页浏览器中的后退和前进按钮可以使用栈来实现。在浏览网页时&#xff0c;每次…

HarmonyOS Navigation组件深度解析与应用实践

HarmonyOS Navigation组件深度解析与应用实践 一、组件架构与核心能力 HarmonyOS Navigation组件作为路由导航的根视图容器&#xff0c;采用三层架构设计&#xff1a; 标题层&#xff1a;支持主副标题配置&#xff0c;提供Mini/Free/Full三种显示模式内容层&#xff1a;默认…

基于AI的Web数据管道,使用n8n、Scrapeless和Claude

引言 在当今数据驱动的环境中&#xff0c;组织需要高效的方法来提取、处理和分析网络内容。传统的网络抓取面临着诸多挑战&#xff1a;反机器人保护、复杂的JavaScript渲染以及持续的维护需求。此外&#xff0c;理解非结构化的网络数据则需要复杂的处理能力。 本指南演示了如…

Cadence学习笔记之---PCB器件放置与布局

目录 01 | 引 言 02 | 环境描述 03 | 元件放置 04 | 布局相关操作 06 | 总 结 01 | 引 言 在上一篇文章中&#xff0c;介绍了如何设置PCB的电气规则约束&#xff0c;以及如何设置层叠&#xff0c;到此我们已经完成了使用Cadence设计PCB的前期准备工作&#xff1b; 在本篇…

力扣HOT100之二叉树:199. 二叉树的右视图

这道题没啥好说的&#xff0c;首先定义一个向量来保存每一层的最后一个元素&#xff0c;直接用层序遍历&#xff08;广度优先搜索&#xff09;遍历二叉树&#xff0c;然后将每一层的最后一个元素加入到这个向量中即可。属于是二叉树层序遍历的模板题。 /*** Definition for a …

CSS:三大特性

文章目录 一、层叠性二、继承性三、优先级 一、层叠性 二、继承性 可以在MDN网站上查看属性是否可以被继承 例如color 三、优先级

C++经典库介绍

在 C 开发的漫长历程中&#xff0c;涌现出了许多经典的库&#xff0c;它们在不同的领域发挥着重要作用&#xff0c;极大地提升了 C 开发的效率和质量。下面为你介绍一些 C 开发中的经典库。 标准模板库&#xff08;STL&#xff09; STL 堪称 C 编程领域的基石&#xff0c;是每…

Git本地使用小Tips

要将本地仓库 d:\test 的更新推送到另一个本地仓库 e:\test&#xff0c;可以使用 Git 的远程仓库功能。以下是具体步骤&#xff1a; ​​在 e:\test 中添加 d:\test 作为远程仓库​​ 在 e:\test 目录中打开 Git Bash 或命令行&#xff0c;执行以下命令&#xff1a; git remo…

AWS SageMaker vs Bedrock:该选哪个?

随着生成式 AI 的快速崛起&#xff0c;越来越多企业希望借助云上工具&#xff0c;加速 AI 应用的构建与落地。AWS 作为领先的云服务提供商&#xff0c;提供了两款核心 AI 服务&#xff1a;Amazon SageMaker 和 Amazon Bedrock。它们虽然同属 AWS AI 生态系统&#xff0c;但定位…

51单片机的lcd12864驱动程序

#include <reg51.h> #include <intrins.h>#define uchar

Git .gitattributes 文件用途详解

.gitattributes 是 Git 版本控制系统中的一个配置文件&#xff0c;用于定义特定文件或路径的属性&#xff0c;从而控制 Git 如何处理这些文件。它类似于 .gitignore&#xff0c;但功能更广泛&#xff0c;可以精细化管理文件在版本控制中的行为。 主要用途 以下是 .gitattribut…