微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > xilinx MIG读取DDR2出现的问题

xilinx MIG读取DDR2出现的问题

时间:10-02 整理:3721RD 点击:
*****************************************************************************/
//把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
/*****-----------------------------------------------------------------------------------*/
/*****************************************************************************/
//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
/***----------------------------------------------------------------------------------------*/
代码如上,就是单个读写。现在的问题是,我单个单个的连续写不同的地址(地址间隔16),写入的数据,通过读出验证是完全正确的!但验证方式是只读一个地址,分几次更换地址重新烧录来验证。如果我一次单个单个的读几个地址来验证的话,就出现,后面读取的地址数据一直是就开始读取的那个地址的数据。比如:我首先向地址0,16,32,48写如1,2,3,4;如过我只读一个地址(0 or 16 or 32 or 48),读出的数据和我写入的一致,但如果我单个单个连续读0,16,32,48,则读出的数据则是1,1,1,1,假如我单个单个连续读32,16,48,则读出的数据则是3,3,3。这个问题是什么问题?希望大家指点!

自己UP

感谢分享

代码有点长,不看了,你这样dbg不是办法,最好弄个ddr仿真模型,仿真去找出你哪里错了,你这个问题。或者用逻辑分析仪

如果是ip得话,那你只能仔细去看看ip得使用文档了。或者别的用过这ip得来回答你,他们应该清楚,没用过这个没法给别的意见

    Great work done.



   谢谢你的答复,仿真模型怎么高,逻辑分析仪,我一直没搞通,老是编译有错误!

仿真模型就是模拟DDR芯片行为的模型。你不仿真的吗?不仿真你就得对自己的代码非常清楚,但是项目大了难免会有BUG。如果搞不到DDR的仿真模型,要么自己根据DDR芯片文档写个(这个比较难,要写完善的更难)。用逻辑分析仪还是很麻烦的,追问题还是得结合代码



   用IP自己生成的仿真是可以仿真通过的,但是仿真自己的工程,好像都没不能仿真的。我引进到FIFO的时钟和我操作的时钟是一样的。 现在我怀疑是我读写FIFO的是工作时钟与我的操作时钟似乎不匹配?!?!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top