FPGA DDR2读写控制器时序代码

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。


以下是我写的一个单个数据写DDR的例子,用状态机来实现,已经通过验证. 大家可以参考!

/*****************************************************************************/
//把Ram寄存器的16bytes数据写入ddr中
always @(posedge c3_clk0)
begin
if(c3_rst0 || !c3_calib_done)
begin
c3_p0_wr_en<=1'b0;
c3_p0_wr_mask<=16'd0;
c3_p0_wr_data<=128'd0;
ddr_write_busy <=1'b0;
c3_p0_cmd_en_w<=1'b0;
c3_p0_cmd_instr_w<=3'd0;
c3_p0_cmd_bl_w<=6'd0;
c3_p0_cmd_byte_addr_w<=30'd0;
ddr_write_state<=write_idle;
end
else
begin
case(ddr_write_state)
write_idle:
begin
c3_p0_wr_en<=1'b0;
c3_p0_wr_mask<=16'd0;
if(ddr_wr_req) //如果写DDR请求
begin
ddr_write_busy<=1'b1; //ddr写数据忙标志
ddr_write_state<=write_fifo;
c3_p0_wr_data<=ddr_wdata_reg; //准备写入DDR的数据
end
end

write_fifo:
begin
if(!c3_p0_wr_full) //如p0写fifo数据不满
begin
c3_p0_wr_en<=1'b1;
ddr_write_state<=write_data_done;
end
end

write_data_done:
begin
c3_p0_wr_en<=1'b0;
ddr_write_state<=write_cmd_start;
end

write_cmd_start:
begin
c3_p0_cmd_en_w<=1'b0;
c3_p0_cmd_instr_w<=3'b010; //010为写命令
c3_p0_cmd_bl_w<=6'd0; //burst length为1个128bit数据
c3_p0_cmd_byte_addr_w<=c3_p0_cmd_byte_addr_w+16; //地址加16
ddr_write_state<=write_cmd;
end

write_cmd:
begin
if (!c3_p0_cmd_full) //如果命令FIFO不满
begin
c3_p0_cmd_en_w<=1'b1; //写命令使能
ddr_write_state<=write_done;
end
end

write_done:
begin
c3_p0_cmd_en_w<=1'b0;
ddr_write_state<=write_idle;
ddr_write_busy<=1'b0;
end

default:
begin
c3_p0_wr_en<=1'b0;
c3_p0_cmd_en_w<=1'b0;
c3_p0_cmd_instr_w<=3'd0;
c3_p0_cmd_bl_w<=6'd0;
ddr_write_state<=write_idle;
end

endcase;
end
end










sigadsp 发表于 2013-4-23 20:26:25 | 只看该作者




下面是读单个DDR的数据的例子,已经通过验证.
/*****************************************************************************/
//DDR数据读处理程序
always @(posedge c3_clk0)
begin
if(c3_rst0 || !c3_calib_done)
begin
c3_p0_rd_en<=1'b0;
ddr_rd_busy <=1'b0;
c3_p0_cmd_en_r<=1'b0;
c3_p0_cmd_instr_r<=3'd0;
c3_p0_cmd_bl_r<=6'd0;
c3_p0_cmd_byte_addr_r<=30'd16;
ddr_read_state<=read_idle;
ddr_data<=128'd0;
end
else
begin
if(ddr_addr_set)
c3_p0_cmd_byte_addr_r<=30'd16; //ddr的地址置位
else if(pic_store_done)
begin
case(ddr_read_state)
read_idle:
begin
if(ddr_rden_req) //如果有ddr读请求
begin
ddr_read_state<=read_cmd_start;
ddr_rd_busy <=1'b1;
end
end

read_cmd_start:
begin
c3_p0_cmd_en_r<=1'b0;
c3_p0_cmd_instr_r<=3'b001; //命令字为读
c3_p0_cmd_bl_r<=6'd0; //single read
ddr_read_state<=read_cmd;
end

read_cmd:
begin
c3_p0_cmd_en_r<=1'b1; //ddr读命令使能
ddr_read_state<=read_wait;
end

read_wait:
begin
c3_p0_cmd_en_r<=1'b0;
if(!c3_p0_rd_empty) //如果read fifo不空
ddr_read_state<=read_data;
end

read_data:
begin
c3_p0_rd_en<=1'b1; //读数据使能
ddr_read_state<=read_done;
ddr_data<=c3_p0_rd_data;
end

read_done:
begin
c3_p0_rd_en<=1'b0;
ddr_rd_busy <=1'b0;
c3_p0_cmd_byte_addr_r<=c3_p0_cmd_byte_addr_r+16; //ddr的地址加16
ddr_read_state<=read_idle;
end

default:
begin
c3_p0_rd_en<=1'b0;
c3_p0_cmd_en_r<=1'b0;
ddr_read_state<=read_idle;
end
endcase;
end

end
end


相关文档
最新文档