一、 概述
在之前我们把dds产生的两个sin波形存储到了ddr4中,接下来需要使用ddr4的读指令将两种波形读取出来。之前写ddr4的功能由0通道和1通道来完成。这次使用通道2和通道3来完成ddr4的读功能。
二、 读取波形数据
1、通道2功能描述
使用通道2和通道3从ddr4中读取波形数据,由interconnect来分配通道的使用权。其中需要考虑的是何时产生读开始,合理分配读地址。因为之前只写入了5120个数据,本次也读取共5120个数据。不需要考虑读突发长度,每次突发长度都为256。
通道2接口列表:
产生读开始信号:
先定义读开始信号,在读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接口列表:
通道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写入的数据。下一接通过仿真来观察各个通道的数据传递情况,验证多通道的读写功能。
本文章由威三学社出品
对课程感兴趣可以私信联系