MIG读取DDR2出现的问题

2020-02-23 10:41发布

*****************************************************************************/
//把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。这个问题是什么问题?希望大家指点!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。