马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 南竹轩 于 2020-2-25 22:18 编辑
这里就没有形成文档,直接天马行空的敲一点关键内容吧。
一,参考文档
1.参考资料
XILINX_DDR3_IP核使用教程,一共仿真,综合,测试,应用,最终篇 5个,https://download.csdn.net/download/walkmen1990/10180050
2.官方文档
ug586_7Series_MIS
3. 黑金A7101 开发板 DDR3 例程
4.增加一点说明
ug586_7Series_MIS chapter 4
在chapter4 LPDDR2 SDRAM Memory Interface Solution里面有一句话
As shown in Figure 4-59, the maximum delay for a single write between the write data and
the associated write command is two clock cycles. When issuing back-to-back write
commands, there is no maximum delay between the write data and the associated
back-to-back write command, as shown in Figure 4-61.
也就是backtoback的数据(连续多个数据的写入)不必严格对齐,这句话在DDR3的描述里面没有出现,但是应该是一样的
二、代码解读
2.1 端口解读
2.1.1 test与burst文件交互接口
module mem_burst
#(
parameter MEM_DATA_BITS = 64,
parameter ADDR_BITS = 24
)
(
input test,
input rst, /*复位*/
input mem_clk, /*接口时钟*/
input rd_burst_req, /*读请求*/
input wr_burst_req, /*写请求*/
input[9:0] rd_burst_len, /*读数据长度*/
input[9:0] wr_burst_len, /*写数据长度*/
input[ADDR_BITS - 1:0] rd_burst_addr, /*读首地址*/
input[ADDR_BITS - 1:0] wr_burst_addr, /*写首地址*/
output rd_burst_data_valid, /*读出数据有效*/
output wr_burst_data_req, /*写数据信号*/
output[MEM_DATA_BITS - 1:0] rd_burst_data, /*读出的数据*/
input[MEM_DATA_BITS - 1:0] wr_burst_data, /*写入的数据*/
output rd_burst_finish, /*读完成*/
output wr_burst_finish, /*写完成*/
output burst_finish, /*读或写完成*/
......);
......................
2.1.2 app分类信号
这里将指令进行分类
【地址系统信号】
app_cmd
app_addr
app_cmd
app_rdy : 无论读数据还是写数据,发送地址的时候,原则上只需要判断这个信号的有效性;
app_en
【写数据系统信号】
app_wdf_rdy : 写数据的时候,原则上只需要判断这个信号的有效性;
app_wdf_wren
app_wdf_data
app_wdf_end
【读数据系统信号】
app_rd_data
app_rd_data_end
app_rd_data_valid
2.2 流程解读
(1)men_test 里面先拉高wr_burst_req信号 ,使进入MEM_WRITE状态机
else if(wr_burst_req)
begin
state <= MEM_WRITE;
(2)首先拉高app_en, 给地址,地址系统现行一步
// app_addr_r <= {wr_burst_addr,3'd0};
// app_en_r <= 1'b1; //命令有效
(3)地址系统和数据系统在MEM_WRITE状态机内分别累加
MEM_WRITE:
begin
//original
// if(app_rdy) //ddr用户接口空闲
// begin
// app_addr_r <= app_addr_r + 8; //app的数据宽度256,ddr的数据宽度是32位, 地址需要加8
// if(wr_addr_cnt == wr_burst_len - 1) //判断是否发送了wr_burst_len的地址的写命令
// begin
// //leoriginal 3
// app_wdf_end_r <= 1'b0;
// app_en_r <= 1'b0; //命令无效
// end
// else
// begin
// wr_addr_cnt <= wr_addr_cnt + 1;
// end
// end
// if(wr_burst_data_req) //写入ddr数据统计
// begin
// if(wr_data_cnt == wr_burst_len - 1) //等待buart长度的数据写入到DDR IP的FIFO里
// begin
// state <= MEM_WRITE_WAIT;
// end
// else
// begin
// wr_data_cnt <= wr_data_cnt + 1;
// end
// end
一般情况下,app_wdf_rdy拉低的频率和时间比app_rdy要少很多,所以数据系统先写完,进入MEM_WRITE_WAIT状态
(4)进入MEM_WRITE_WAIT状态,等待地址写完
(5)进入WRITE_END状态,写完状态,同时反馈wr_burst_finish ( = state == WRITE_END )信号
(6)进入IDLE 等待
(7)men_test模块接收wr_burst_finish后进入读取数据状态,开始读数据过程,读取过程和写类似
这里不赘述
2.3 关键信号解析
【wr_burst_req】 men_test产生写数据请求
【wr_burst_data_req】
信号定义://assign wr_burst_data_req = (state == MEM_WRITE ) & app_wdf_rdy ; // 写ddr数据请求信号 original
信号功能:men_burst.v产生,状态机MEN_WRITE期间拉高,反馈给men_test.v men_test检测这个信号为高就输出需要写入的数据;
这个信号可以作为fifo的读使能,数据比这个信号慢一拍输出
【app_wdf_wren_r】
信号定义:else if(app_wdf_rdy)
app_wdf_wren_r <= wr_burst_data_req; //写DDR数据准备好
信号功能:
功能1,将wr_burst_data_req延时一拍;
功能2,将wr_burst_data_req中间的由于app_wdf_rdy拉低的部分进行重新拉高;
【app_wdf_en】
信号定义:assign app_wdf_wren = app_wdf_wren_r & app_wdf_rdy;
信号功能:app_wdf_en指示数据有效信号
到这里基本清晰了。红色信号作为fifo读取或者外部数据发生的请求信号
根据红色信号【wr_burst_data_req】延一拍,平滑中间的0,再和 app_wdf_rdy与一遍,生成绿色的数据有效信号【app_wdf_wren】
数据比红色信号【wr_burst_data_req】慢一拍输出,也就产生了绿色的【app_wdf_data】信号
即数据【app_wdf_data】和信号有效信号【app_wdf_wren】已经完成对齐功能;
SRIO 中 iotx_tready 的用法可以参考这里!
另外,地址系统的信号 和红色信号一起拉高,也就是最开始的时候,地址信号比数据信号提前一个时钟给DDR控制器
else if(wr_burst_req)
begin
state <= MEM_WRITE;
app_cmd_r <= 3'b000; //写命令
app_addr_r <= {wr_burst_addr,3'd0};
app_en_r <= 1'b1; //命令有效
------------------------------------------------------分割线------------------------------------------------------
这里基本上主要模块分析完了
写地址命令和读地址命令并没有严格对齐,有点担心这里可能存在风险
可能存在的风险,下一章节进行分析
20200224
|