使用DDR4控制器实现多通道数据读写(十三)

一、概述

在上一章节中使用仿真简单验证了interconnect的功能,使用四个axi4的主端口同时发起读写命令,经过interconnect后,将这些读写指令依次发给ddr4控制器。Ddr4控制器响应后再依次将响应发送到各个通道。从而实现多通道读写ddr4控制器的功能。

本章节继上一章节来概述实现的具体过程。

测试功能模块框图:

二、测试模块说明

通道0测试模块接口列表:

三、测试模块代码

module chnl_test_0(

input wire chnl_clk_0,

input wire chnl_rst_0,

//wr

output reg wr_start_0,

output reg 31:0 awaddr_in_0,

output reg 7:0 awlen_in_0,

output reg 511:0 wdata_in_0,

input wire wvalid_0,

input wire wready_0,

input wire 31:0 awaddr_cnt_0,

input wire wr_busy_0,

//rd

output reg rd_start_0,

output reg 31:0 araddr_in_0,

output reg 7:0 arlen_in_0,

input wire 511:0 rd_data_0,

input wire rd_en_0,

input wire 31:0 araddr_cnt_0,

input wire rd_end_0,

input wire rd_busy_0

);

reg 31:0 clk_cnt;

always @(posedge chnl_clk_0) begin

if (chnl_rst_0) begin

clk_cnt <= 0;

end

else if (clk_cnt <= 'd999) begin

clk_cnt <= clk_cnt + 1;

end

end

always @(posedge chnl_clk_0) begin

if (chnl_rst_0) begin

wr_start_0 <= 0;

end

else if (clk_cnt == 'd990) begin

wr_start_0 <= 1;

end

else begin

wr_start_0 <= 0;

end

end

always @(posedge chnl_clk_0) begin

if (chnl_rst_0) begin

awaddr_in_0 <= 0;

end

else if (clk_cnt == 'd990) begin

awaddr_in_0 <= 0;

end

else begin

awaddr_in_0 <= 0;

end

end

always @(posedge chnl_clk_0) begin

if (chnl_rst_0) begin

awlen_in_0 <= 0;

end

else if (clk_cnt == 'd990) begin

awlen_in_0 <= 'd127;

end

else begin

awlen_in_0 <= 0;

end

end

always @(posedge chnl_clk_0) begin

if (chnl_rst_0) begin

wdata_in_0 <= 0;

end

else if (wr_busy_0 == 0) begin

wdata_in_0 <= 0;

end

else if (wvalid_0 && wready_0) begin

wdata_in_0 <= wdata_in_0 + 1;

end

end

always @(posedge chnl_clk_0) begin

if (chnl_rst_0) begin

rd_start_0 <= 0;

end

else if (clk_cnt == 'd999) begin

rd_start_0 <= 1;

end

else begin

rd_start_0 <= 0;

end

end

always @(posedge chnl_clk_0) begin

if (chnl_rst_0) begin

araddr_in_0 <= 0;

end

else if (clk_cnt == 'd999) begin

araddr_in_0 <= 0;

end

else begin

araddr_in_0 <= 0;

end

end

always @(posedge chnl_clk_0) begin

if (chnl_rst_0) begin

arlen_in_0 <= 0;

end

else if (clk_cnt == 'd999) begin

arlen_in_0 <= 'd127;

end

else begin

arlen_in_0 <= 0;

end

end

endmodule

测试模块说明:

1、产生写开始标志:

使用计数器来触发读写开始标志,计数器计数到'd1000时停止计数。当计数器计数到'd990时产生写开始标志。

2、产生写起始地址:

与写开始标志同时产生。写地址可以为0,或者为64的整数倍,因为每个数据都需要64个地址来存储,ddr4的地址空间为4GB,使用64的整数倍作为起始地址,这样当写到ddr4的最后一个地址空间时,可以将完整的512位数据存储进去。如果将随意的地址作为写起始地址,当写到ddr4的最后一个地址空间时,不足以将完整的512位数据放进去。最后一个512位数据的地址空间不足64位,还需要使用掩码来将数据分开,而被掩掉的数据还需要写进ddr4的低位空闲地址中。这样不仅写入数据难度增加,后期读取数据的时候也不方便。所以使用64的整数倍作为起始地址,这样当ddr4写到最后的地址空间时,512位的数据也正好可以存储进去。

3、产生写长度:

与写开始标志同时产生。ddr4支持最高256突发长度.输入的写长度值最高为255。在测试代码中给的是127,写入128个数据。

4、产生读开始标志:

为了可以读出写入的数据,所以产生读开始标志时刻相比写开始标志晚几个时钟周期,当计数器计数到'd999时产生读开始标志。

5、产生读起始地址:

与读开始标志同时产生。我们的目的时将写入的数据读出来,所以读起始地址与写起始地址相同。

6、产生读长度:

与写开始标志同时产生。读长度与写长度相同。

复制代码
以上为通道0的测试代码,与另外三个通道的测试代码大同小异,需要注意的是起始地址不要与其他通道冲突,不然在同一地址下,后写入的数据会将先写入的数据覆盖,导致读出该地址的数据为后写入的数据。例如通道0从地址0开始写入128个数据,那么本次写突发后,地址增加到64*128=8192,那么其他通道的读写地址应该避免在0-8192区间。

三、章节总结

本章节概述了测试模块的代码说明,详细讲解了如何产生读写信号,和突发地址和突发长度的注意事项。下一章节再继续讲述与interconnect交互的axi读写模块。

本文章由威三学社出品

对课程感兴趣可以私信联系

相关推荐
仲南音15 小时前
Xilinx FPGA——时钟IP核MMCM、PLL
fpga开发
I'm a winner1 天前
基于Xilinx FPGA的LVDS高速串行通信系统(三)--数据训练及握手机制【文末源码】
fpga开发
upper20201 天前
coremark移植坑之-nostartfiles -nostdlib参数
学习·fpga开发·coremark移植·riscv设计
Eloudy2 天前
Vivado 纯命令行构建 FPGA 项目教程
fpga开发
Rambo.xia2 天前
AXI跨时钟域与数据一致性——CDC FIFO深度不够、写后读冒险、多Master仲裁、乱序返回,出了Bug根本查不出来
fpga开发·bug
upper20202 天前
FPGA部署卷积神经网络识别MINST图片
fpga开发·卷积神经网络·minst·minst识别·部署神经网络·神经网络识别图片
你是我的解忧王子2 天前
嵌入式 ADC采样 原始数据分析上层(平均值 波动率 正态分布 线性补偿 系统误差)
fpga开发·数据挖掘·数据分析
9527华安3 天前
FPGA纯verilog代码ISP图像处理培训教程,基于IMX214,提供工程源码+视频教程+FPGA开发板
图像处理·fpga开发·isp·imx214·mipi
千寻xun3 天前
二、实战篇-NVME SSD控制之ZYNQ实现(六)-读写NVME SSD硬盘数据
fpga开发·nvme·nvme ssd
千寻xun3 天前
二、实战篇-NVME SSD控制之ZYNQ实现(三)
fpga开发·nvme ssd·nvme协议