接上一篇,介绍mem_burst程序。【图片来源于黑金】
通过vivado自带的IP core可生成一个MIG IP控制器.我们的任务就是
设计程序控制与DDR相连的MIG 以及用户的逻辑程序,如下图需要设计mem_burst和mem_tset
封装程序【mem_burst的设计思路】
内存读取
读取内存需要以上粉色框标记的部分输入输出。大致思路是:
状态机:IDLE——MEM_READ——MEM_READ_WAIT——READ_END
①用户传来rd_burst_req【请求读】以及 rd_burst_len【要读的lenth】和d_burst_addr【首地址】将命令有效位【add_en==1】
②当mem_burst检测到请求读时会进入mem_read的状态,当app_rdy是高电平时【ddr空闲状态】,mem_burst取出 首地址后面的读取地址输出给ddr_ip,把rd_burst_len个地址全部传给ddr_ip后 add_en==0并且进入mem_read_wait状态
③只有当ddr_ip的app_rd_data_valid是高电平【ddr传来的数据是有效的】数据计数器才会计数否则会处在mem_read_wait状态直到有效数据获取完毕【数据计数器记满rd_burst_len】
④当数据全部传完时进入read_end状态,面向外部用户的输出rd_burst_finish拉高
注:
mem_burst用一个assign语句一直将外部要求的 读取地址rd_burst_addr~rd_burst_addr+rd_burst_len直接传给输出app_addr;
mem_burst用两个assign语句一直将来自ddr_ip的app_rd_data以及app_rd_data_valid直接传给输出 rd_burst_data以及rd_burst_data_valid;
mem_burst用一个assign语句一直将state=read_end传给rd_burst_finish;
在状态mem_read和状态mem_read_wait中我们都要判断数据是否有效【app_rd_data_valid?=1】并将数据传给外部用户。原因是接收地址和传数据本身并不冲突可以在接收下一次传输地址时进行上一次的数据传输。
时序变换分析
写入内存
读取内存需要以上绿色框标记的部分输入输出。大致思路是:
状态机:IDLE——MEM_WRITE——MEM_WRITE_WAIT——WRITE_END
①用户传来wr_burst_req【请求写】以及wr_burst_len【写入数据lenth】wr_burst_addr【写入的首地址】后 将写地址命令有效【app_en拉高】 且将app_wdf_end拉高
②当检测到请求写命令后进入mem_write状态,在这个状态会执行两个部分:
第一部分:app_rdy==1时地址计数器计数【跟读内存一样会有assign语句不断将外部输入的地址输出给ddr_ip】,传输完所有地址时app_en【写命令】拉低且app_wdf_end拉低。
第二部分:wr_burst_data_req==1【表示请求用户发送准备写给ddr的数据】时数据计数器计数,这里的数据不是直接写入ddr_ip中而是写入到ddr_ip的FIFO中
③当用户的数据全部写入ddr_ip的FIFO中后进入mem_write_wait状态,在这个状态中当ddr空闲时【app_rdy拉高】还要将外部发送的地址传给ddr_ip,这一步骤和mem_write时一模一样但他的作用并不是编辑地址寄存器,而是判断写入地址寄存器这一操作是否完成,当地址发完(也就是编辑完地址寄存器)且ddr写入数据位有效【app_wdf_rdy拉高】或者 写地址命令无效【app_en拉低】且ddr写入数据位有效【app_wdf_rdy拉高】进入wreite_end状态
④wreite_end状态时将wr_burst_finish拉高发给用户端
注:
①与都内存一样,只有当ddr空闲时【app_rdy拉高】时才可以把地址传给ddr;
②在状态mem_write下当wr_burst_data_req==1时数据计数器才计数,而定义:assign wr_burst_data_req=(state==mem_write)&&app_wdf_rdy【app_wdf_rdy是ddr发给burst的,告知外部可以写入数据】
app_wdf_wren是由burst程序发给ddr的,我们定义
assign app_wdf_wren=app_wdf_rdy&&wr_burst_data_req;
通过对这两个输出端口定义分析可知:当ddr写入数据位有效【app_wdf_rdy拉高】以及请求用户准备写入位数据【wr_burst_data_req拉高】时,表示被写入的数据有效【app_wdf_wren被拉高】
③用户接口发送写命令(地址)与把数据写到ddr中是完全独立的,用户发送的数据是要先放到ddr_ip的FIFO中的,只要写入数据位有效【app_wdf_rdy拉高】就可以把数据写入到ddr_ip中
时序分析
以上就是封装程序