⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem_phy_calib.v

📁 xilinx公司的DDR实现源码
💻 V
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////// Copyright (c) 2005 Xilinx, Inc.// All Rights Reserved/////////////////////////////////////////////////////////////////////////////////   ____  ____//  /   /\/   /// /___/  \  /    Vendor: Xilinx// \   \   \/     Version: 1.0//  \   \         Filename: addr_gen.v//  /   /         Timestamp: 12 Dec 2005// /___/   /\     // \   \  /  \//  \___\/\___\//////Device: Virtex-5///////////////////////////////////////////////////////////////////////////////// This module does the claibration after initialization. module mem_phy_calib (		  input clk90,                  input reset90,		  input clk0,		  input reset0,		  input ctrl_rden,		  input idelay_ctrl_rdy,		  input [(`data_width*2)-1:0] capture_data,		  input          phy_init_rden,		  input          phy_init_initialization_done,		  input          phy_init_st1_read,		  input          phy_init_st2_read,                  output [43:0] test_bus,		  output reg [`data_strobe_width-1:0] phy_calib_rden,		  output reg first_calib_done,		  output reg second_calib_done,		  output reg [`data_width-1:0]    phy_calib_dq_dlyinc,		  output reg [`data_width-1:0]    phy_calib_dq_dlyce,		  		  output reg [`data_width-1:0]    phy_calib_dq_dlyrst,		  output reg [`data_strobe_width-1:0]    phy_calib_dqs_dlyinc,		  output reg [`data_strobe_width-1:0]    phy_calib_dqs_dlyce,		  		  output reg [`data_strobe_width-1:0]    phy_calib_dqs_dlyrst);   reg [3:0] 		 state_r;   reg [3:0]                 state_r_test;   reg [(`data_width*2)-1:0] capture_data_r2_test;   reg [`data_strobe_width-1:0] dqs_count_r1_test;   reg                   data_detect_r;   reg [5:0] 		 inc_count_r;   reg [4:0] 		 tap_count_r;   reg [5:0] 		 dec_count_r;   reg [5:0] 		 rise_count_r;   reg                   rise_done_r;   reg [5:0] 		 start_window_r;   reg                   add_dq_delay_r;      reg                   phy_init_rden_270_r;   reg                   ctrl_rden_270_r;   reg                   first_calib_done_90_r;   reg                   second_calib_done_90_r;               reg                   stg2_read_r1;   reg                   stg2_read_r2;   reg                   stg2_read_r3;   reg                   stg1_read_r1;   reg                   stg1_read_r2;      reg [4:0]             read_en_r;   reg [(`data_strobe_width*2)-1 :0] read_en_stg_r;   reg [`data_strobe_width-1:0] 		 dqs_count_r, dqs_count_r1;   reg [`data_strobe_width-1:0] 		 rden_count_r;   reg [(`data_width*2)-1:0] capture_data_r;   reg [(`data_width*2)-1:0] capture_data_r1;	reg [(`data_width*2)-1:0] capture_data_r2;   reg 			     dq_calib_done_r;   reg 			     dq_calib_begin_r;   reg [3:0] 		 dq_state_r;   reg [1:0] 		 dq_inc_count_r;   reg [1:0] 		 dq_dec_count_r;   reg [2:0] 		 dq_count_r;   reg                  data_match;   reg                  data_check_r;   reg                  data_xor_r;   reg                  data_xor_r1;            wire                  read_en_r1_edge;   wire                  read_en_r2_edge;   wire                  read_en_r3_edge;   wire                  read_en_r4_edge;   reg [7:0] 		 rd_en_stages_r;   wire [14:0] load_mode_reg;wire [14:0] ext_mode_reg;assign    REGISTERED_VALUE = `registered; assign    CAS_LATENCY_VALUE = load_mode_reg[6:4];assign    ADDITIVE_LATENCY_VALUE = ext_mode_reg[5:3];assign    ECC_VALUE=    `ecc_enable;         localparam 		  IDLE     = 4'h0;   localparam             CHECK = 4'h1;   localparam             INC      = 4'h2;   localparam             WAIT0    = 4'h3;   localparam             WAIT1    = 4'h4;   localparam             WAIT2    = 4'h5;   localparam             DEC      = 4'h6;   localparam             SELECT   = 4'h7;   localparam             DQS_DQ_INC      =  4'h8;   localparam             FINAL_INC = 4'h9;   localparam             FINAL_CHECK    = 4'hA;   localparam             DEC_WAIT = 4'hB;   localparam             DQ_CALIB = 4'hC;   localparam             INC_WAIT0 = 4'hD;   localparam             INC_WAIT1 = 4'hE;   localparam             INC_WAIT2   = 4'hF;         localparam             DQ_IDLE = 4'h0;   localparam             DQ_DQ_CHECK = 4'h1;   localparam             DQ_DQ_DEC = 4'h2;   localparam             DQ_DQ_INC = 4'h3;   localparam             DQ_DQ_WAIT0 = 4'h4;   localparam             DQ_DQ_WAIT1 = 4'h5;   localparam             DQ_DQ_WAIT2 = 4'h6;   localparam             DQ_DQ_SELECT = 4'h7;   localparam             DQ_DQ_CALIB_DONE0 = 4'h8;   localparam             DQ_DQ_CALIB_DONE1 = 4'h9;         assign    load_mode_reg         = `load_mode_register;assign    ext_mode_reg         = `ext_load_mode_register;assign    REGISTERED_VALUE = `registered; assign    CAS_LATENCY_VALUE = load_mode_reg[6:4];assign    ADDITIVE_LATENCY_VALUE = ext_mode_reg[5:3];    assign test_bus = {capture_data_r2_test[31:0], dqs_count_r1_test, state_r_test[3:0]};  //12'd0,dqs_count_r1,rise_done_r,rise_count_r,inc_count_r[4:0],   // SM for the first stage of calibration. In the first stage of calibration the taps for DQS are incremented until   // there is valid data. Once there is a data match the sm will increase the taps to find out the window for valid data.   // This will be done with respect to clock0 first and then with clock180. The clock that takes the lowest number of taps   // will be chosen. During the calibration the SM will look at bit 0 of the DQS byte. Once the calibration is done for the   // DQS, then the DQ calibration will be done by the next state machine.    always@(posedge clk90) begin      if(reset90 || ~idelay_ctrl_rdy)begin 	state_r <= IDLE;	 data_detect_r <= 1'd0; // will go high when there is a data match. 	 phy_calib_dqs_dlyinc <= `data_strobe_width'd0;	 phy_calib_dqs_dlyce <= `data_strobe_width'd0;	 phy_calib_dqs_dlyrst <= `data_strobe_width'hff;	 inc_count_r <= 6'd0;	 tap_count_r <= 5'd0;	 dec_count_r <= 6'd0;	          first_calib_done_90_r <= 1'd0; // flag to indicate the first stage of calibration is done. 	 rise_count_r <= 6'd0; // counter to count the taps during clock0 calibration. 	 rise_done_r <= 1'd0; // flag for clock0 calibration          dqs_count_r <= `data_strobe_width'd0; // count for dqs	 dqs_count_r1 <= `data_strobe_width'd0; // count for dqs	 capture_data_r <= `data_width*2'd0;	 capture_data_r1 <= `data_width*2'd0;	 capture_data_r2 <= `data_width*2'd0;	 start_window_r <= 6'd0; // register to keep track of the start of the window. 	 dq_calib_begin_r <= 1'd0; // flag to the dq calib state machine.	 add_dq_delay_r <= 1'd0;	 data_check_r <= 1'd0;	 	 	       end  else begin // if (reset90 || ~idelay_ctrl_rdy)	 capture_data_r <= capture_data;	 capture_data_r1 <= capture_data_r;	 capture_data_r2 <= capture_data_r1;	 dqs_count_r1 <= dqs_count_r;	 data_check_r <= ((capture_data_r1[dqs_count_r*8] == capture_data_r1[(dqs_count_r*8) + `data_width] ) && ((capture_data_r1[dqs_count_r*8] ^ capture_data_r[dqs_count_r*8]) && (capture_data_r1[(dqs_count_r*8) + `data_width] ^ capture_data_r[(dqs_count_r*8) + `data_width]))); 	         case(state_r)	  IDLE: if(stg1_read_r2) state_r <= CHECK;	  CHECK: begin // The condition checks for data match. Also checks for rise and fall counter not going over 64.	               // once the window is 16, we stop incrementing (inc_counter <= 4'd15)	     if(data_check_r && (~(&rise_count_r))) begin		data_detect_r <= 1'd1;		state_r <= INC;		inc_count_r <= inc_count_r + 1'd1;	     end	     else begin // if data_detect went high or rise,fall count has reached 64 without match		if((data_detect_r) || (&rise_count_r))begin            		      state_r <= DEC;		      tap_count_r <= 5'd4;		end else		  state_r <= INC;	     end // else: !if((capture_data_r[dqs_count_r*8] == capture_data_r[(dqs_count_r*8) + `data_width] )...	  end // case: CHECK	  INC: begin	     phy_calib_dqs_dlyce[dqs_count_r] <= 1'd1;	     phy_calib_dqs_dlyinc[dqs_count_r] <= 1'd1;	     state_r <= WAIT0;	     rise_count_r <= rise_count_r + 1'd1;	  end 	       	  WAIT0: begin                    state_r <= WAIT1;	            add_dq_delay_r <= 1'd0;	     	    phy_calib_dqs_dlyce[dqs_count_r] <= 1'd0;	            phy_calib_dqs_dlyinc[dqs_count_r] <= 1'd0;	            phy_calib_dqs_dlyrst[dqs_count_r] <= 1'd0;	  end	  WAIT1: state_r <= WAIT2;	                      WAIT2: begin	              if(rise_done_r ) // IF both clock0 and clock180 windows are found.                           state_r <= FINAL_INC;	              else                          state_r <= CHECK;	  end	  	  DEC: begin	           tap_count_r <= tap_count_r -1;	           phy_calib_dqs_dlyrst[dqs_count_r] <= 1'd1; // reset90 all the taps to 0	           data_detect_r <= 1'd0;	           start_window_r <= rise_count_r - inc_count_r;                   if(inc_count_r < 6'd14)	             begin			add_dq_delay_r <= 1'd1;			if(tap_count_r > 5'd0) begin			   state_r <= DEC;			   			end else begin			   state_r <= WAIT0;			   inc_count_r <= 6'd0;			   rise_count_r <= 6'd0;			end // else: !if(tap_count_r == 5'd1)		     end else		       begin	                                 rise_done_r <= 1'd1;       		          state_r <= DEC_WAIT;		      end // else: !if(inc_count_r < 5'd8)	     	  end // case: DEC	  DEC_WAIT: begin                       state_r <= SELECT; // wait state for dqs_rst	               phy_calib_dqs_dlyrst[dqs_count_r] <= 1'd0;	            end 	  	  SELECT: begin // state to select either clock0 or clock180	        state_r <= DQS_DQ_INC;                if(inc_count_r > 6'd15)		  rise_count_r <= inc_count_r/2;	        else		  rise_count_r <= inc_count_r -8;                  //rise_count_r <= ((inc_count_r -8));// loading the counter with the tap value that needs to incremented from the start of the window.	  end // case: SELECT	  DQS_DQ_INC: begin	     	           if(start_window_r > 6'd0)begin // increment until the start of window. 		      phy_calib_dqs_dlyce[dqs_count_r] <= 1'd1;		      phy_calib_dqs_dlyinc[dqs_count_r] <= 1'd1;		      start_window_r <= start_window_r - 1'b1;		      state_r <= INC_WAIT0;		   end else begin // once incremented do the individual dq calibration in the SM below.                       if(dq_calib_done_r)		        state_r <= FINAL_INC;		      else			dq_calib_begin_r <= 1'd1;		      		   end // else: !if(start_window_r > 6'd0)	     	  end // case: INC	  	  INC_WAIT0: begin                         state_r <= INC_WAIT1;	     	        phy_calib_dqs_dlyce[dqs_count_r] <= 1'd0;	                phy_calib_dqs_dlyinc[dqs_count_r] <= 1'd0;	             end    	  INC_WAIT1: state_r <= INC_WAIT2;          INC_WAIT2: state_r <= DQS_DQ_INC;	      	FINAL_INC:begin	   dq_calib_begin_r <= 1'd0;	   	          if(rise_count_r > 6'd0) // increment until the middle of the window. 		    begin		       phy_calib_dqs_dlyce[dqs_count_r] <= 1'd1;		       phy_calib_dqs_dlyinc[dqs_count_r] <= 1'd1;		       rise_count_r <= rise_count_r - 1'd1;		       state_r <= WAIT0;		    end else begin		       state_r <= FINAL_CHECK;		       dqs_count_r <= dqs_count_r + 1'b1; // increment the dqs counter                    end	end // case: FINAL_INC	  	  FINAL_CHECK: begin	           if(dqs_count_r >= (`data_strobe_width)) begin // if all the dqs has been calibrated then end the first calibration. 		      first_calib_done_90_r <= 1'd1; 		     // state_r <= IDLE;		   end	           else begin // reset90 all the counters and start on the next dqs. 		      	 inc_count_r <= 4'd0;		      	 dec_count_r <= 6'd0;	 	                 rise_count_r <= 6'd0;	                 rise_done_r <= 1'd0;		        // phy_calib_dqs_dlyrst[dqs_count_r] <= 1'd1;		         state_r <= WAIT0;		   end // else: !if(dqs_count_r >= `data_strobe_width)	  end // case: FINAL_CHECK	     	endcase // case(state_r)            end // else: !if(reset90 || ~idelay_ctrl_rdy)         end // always@ (posedge clk90)      // This state machine does the DQ calibration. After the DQS calibration is done, the dq calibration   // will be done.  The DQ bits start with a tap setting of 5. The taps will be incremented or decremented   // to fine tune the individual DQ window.   always@(posedge clk90) begin      if(reset90 || ~idelay_ctrl_rdy)begin	 dq_state_r <= DQ_IDLE;	 dq_calib_done_r <= 1'd0;	 dq_inc_count_r <= 2'd0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -