威三电子  

               威三电子

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

2026-08-26 09:22:01

浏览:

一、      概述在之前我们把dds产生的两个sin波形存储到了ddr4中,接下来需要使用ddr4的读指令将两种波形读取出来。之前写ddr4的功能由0通道和1


一、      概述

在之前我们把dds产生的两个sin波形存储到了ddr4中,接下来需要使用ddr4的读指令将两种波形读取出来。之前写ddr4的功能由0通道和1通道来完成。这次使用通道2和通道3来完成ddr4的读功能。

二、      读取波形数据

1、通道2功能描述

使用通道2和通道3ddr4中读取波形数据,由interconnect来分配通道的使用权。其中需要考虑的是何时产生读开始,合理分配读地址。因为之前只写入了5120个数据,本次也读取共5120个数据。不需要考虑读突发长度,每次突发长度都为256

         通道2接口列表:

信号名称

输入输出

位宽

备注

chnl_clk_2

input

1

时钟

chnl_rst_2

input

1

复位

wr_sin_end

input

1

拉高表示sin波形已经存到ddr4

rd_start_2

output

1

读开始,表示开始从ddr4中读数据

araddr_in_2

output

32

读地址,读开始后,***个数据在ddr4中存储的地址,读指令的初始地址

arlen_in_2

output

8

读长度,***多支持256突发,值为255

rd_data_2

input

512

ddr4中读取的数据

rd_en_2

input

1

读取数据有效标志

araddr_cnt_2

input

32

读地址计数,表示当前读取的数据在ddr4中存储的地址

rd_end_2

input

1

读突发结束

rd_busy_2

input

1

读忙碌信号

araddr_cnt_3

input

32

可以根据通道3的地址计数,来决定下一次读开始时的读地址,这样两个通道的读地址不会冲突,并可以使地址连续

rd_busy_3

input

1

通道3的读忙碌标志,为了能在两个读通道都结束后再发起读开始

 

产生读开始信号:

         先定义读开始信号,在读ddr4之前,我们计算出目前ddr4中存储的数据数量为5120个,(每个通道共10次写突发,每次突发256个数据)。***次的读开始由wr_sin_end产生,后面的度开始需要等待通道2和通道3全部空闲后再发起。共发起10次读突发。

         always @(posedge chnl_clk_2) begin

              if (chnl_rst_2) begin

                            rd_start_2_cnt <= 0;

              end

              else if (rd_start_2) begin

                            rd_start_2_cnt <= rd_start_2_cnt + 1;

              end

end

 

always @(posedge chnl_clk_2) begin

              rd_busy_2_r <= rd_busy_2;

end

 

always @(posedge chnl_clk_2) begin

              if (chnl_rst_2) begin

                            rd_idle_flag_2 <= 0;

              end

              else if (rd_idle_flag_2 == 1 && rd_busy_3 == 0) begin

                            rd_idle_flag_2 <= 0;

              end

              else if (rd_busy_2 == 0 && rd_busy_2_r == 1) begin

                            rd_idle_flag_2 <= 1;

              end

end

always @(posedge chnl_clk_2) begin

              if (chnl_rst_2) begin

                            rd_start_2 <= 0;

              end

              else if (rd_idle_flag_2 == 1 && rd_busy_3 == 0 && rd_start_2_cnt <= 'd9) begin

                            rd_start_2 <= 1;

              end

              else if (wr_sin_end) begin

                            rd_start_2 <= 1;

              end

              else begin

                            rd_start_2 <= 0;

              end

end

 

         在产生读开始信号的同时,产生读地址和读突发长度,对于读突发长度,固定为255。对于读地址,因为本次的读开始为通道2和通道3全部突发结束后再产生的读开始信号,在两通道同时产生读开始时,验证过interconnect会先读通道2,再读通道3。所以在这里使用通道3的地址计数作为读地址。这样就可以连续将DDR4的地址中的数据读出。

 

always @(posedge chnl_clk_2) begin

              if (chnl_rst_2) begin

                            araddr_in_2 <= 0;

              end

              else if (rd_idle_flag_2 == 1 && rd_busy_3 == 0 && rd_start_2_cnt <= 'd9) begin

                            araddr_in_2 <= araddr_cnt_3;

              end

              else if (wr_sin_end) begin

                            araddr_in_2 <= 0;

              end

end

 

 

always @(posedge chnl_clk_2) begin

              if (chnl_rst_2) begin

                            arlen_in_2 <= 0;

              end

              else if (rd_idle_flag_2 == 1 && rd_busy_3 == 0 && rd_start_2_cnt <= 'd9) begin

                            arlen_in_2 <= 'd255;

              end

              else if (wr_sin_end) begin

                            arlen_in_2 <= 'd255;

              end

end

         读取的数据位宽为512位,我们存储的波形数据位宽为8位。

wire [7:0]       rd_chnl_2_sin;

assign rd_chnl_2_sin = rd_data_2[7:0];

 

2、通道3功能描述

通道3接口列表:

信号名称

输入输出

位宽

备注

chnl_clk_3

input

1

时钟

chnl_rst_3

input

1

复位

rd_start_3

output

1

读开始,表示开始从ddr4中读数据

araddr_in_3

output

32

读地址,读开始后,***个数据在ddr4中存储的地址,读指令的初始地址

arlen_in_3

output

8

读长度,***多支持256突发,值为255

rd_data_3

input

512

ddr4中读取的数据

rd_en_3

input

1

读取数据有效标志

araddr_cnt_3

input

32

读地址计数,表示当前读取的数据在ddr4中存储的地址

rd_end_3

input

1

读突发结束

rd_busy_3

input

1

读忙碌信号

wr_sin_end

input

1

拉高表示sin波形已经存到ddr4

rd_busy_2

input

1

通道2的读忙碌标志,为了能在两个读通道都结束后再发起读开始





 

通道3中,对于读开始信号的产生,与通道2相同,不同点在于读地址。

因为interconnect会先读通道2请求的地址,并且长度固定位256,那么通道3的***次读地址就为’h4000,后面每次发起读请求,读地址都为当前写地址计数+’h4000

 

always @(posedge chnl_clk_3) begin

              if (chnl_rst_3) begin

                            rd_start_3_cnt <= 0;

              end

              else if (rd_start_3) begin

                            rd_start_3_cnt <= rd_start_3_cnt + 1;

              end

end

 

always @(posedge chnl_clk_3) begin

              rd_busy_3_r <= rd_busy_3;

end

 

always @(posedge chnl_clk_3) begin

              if (chnl_rst_3) begin

                            rd_idle_flag_3 <= 0;

              end

              else if (rd_idle_flag_3 == 1 && rd_busy_2 == 0) begin

                            rd_idle_flag_3 <= 0;

              end

              else if (rd_busy_3 == 0 && rd_busy_3_r == 1) begin

                            rd_idle_flag_3 <= 1;

              end

end

 

always @(posedge chnl_clk_3) begin

              if (chnl_rst_3) begin

                            rd_start_3 <= 0;

              end

              else if (rd_idle_flag_3 == 1 && rd_busy_2 == 0 && rd_start_3_cnt <= 'd9) begin

                            rd_start_3 <= 1;

              end

              else if (wr_sin_end) begin

                            rd_start_3 <= 1;

              end

              else begin

                            rd_start_3 <= 0;

              end

end

 

always @(posedge chnl_clk_3) begin

              if (chnl_rst_3) begin

                            araddr_in_3 <= 0;

              end

              else if (rd_idle_flag_3 == 1 && rd_busy_2 == 0 && rd_start_3_cnt <= 'd9) begin

                            araddr_in_3 <= araddr_cnt_3 + 'h4000;

              end

              else if (wr_sin_end) begin

                            araddr_in_3 <= 'h4000;

              end

end

 

always @(posedge chnl_clk_3) begin

              if (chnl_rst_3) begin

                            arlen_in_3 <= 0;

              end

              else if (rd_idle_flag_3 == 1 && rd_busy_2 == 0 && rd_start_3_cnt <= 'd9) begin

                            arlen_in_3 <= 'd255;

              end

              else if (wr_sin_end) begin

                            arlen_in_3 <= 'd255;

              end

end

读取的数据位宽为512位,我们存储的波形数据位宽为8位。

wire [7:0]       rd_chnl_3_sin;

assign rd_chnl_3_sin = rd_data_3[7:0];

 

三、      总结

本章节使用通道2和通道3将之前储存在ddr4中的波形数据读出,可以看出读通道与写通道的过程相同,通道2读取通道0写入的数据,通道3读取通道1写入的数据。下一接通过仿真来观察各个通道的数据传递情况,验证多通道的读写功能。

本文章由威三学院出品

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

0
使用DDR4控制器实现多通道数据读写(二十二)
一、      概述在之前我们把dds产生的两个sin波形存储到了ddr4中,接下来需要使用ddr4的读指令将两种波形读取出来。之前写ddr4的功能由0通道和1
长按图片保存/分享

北京威三电子科技有限公司

突破技术壁垒,芯创智联领航未来

 


北京威三电子科技有限公司 版权所有
京ICP备2026012969号
 

热线:

159-2199-9232

 

图片展示

淘宝店铺:

威三科教

地址:

北京市延庆区辰龙国际6号楼406室

微信公众号:

北京威三电子科技有限公司 

热线:159-2199-9232

淘宝店铺:威三科教

地址:北京市延庆区辰龙国际6号楼406


微信公众号

图片展示
北京威三电子科技有限公司 版权所有| 京ICP备2026012969号
微信公众号
客服中心
热线电话
15921999232
上班时间
周一到周五
二维码
扫码关注
客服中心
热线电话
15921999232
上班时间
周一到周五
二维码
扫码关注
添加微信好友,详细了解产品
使用企业微信
“扫一扫”加入群聊
复制成功!
添加微信好友,详细了解产品
我知道了