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

📄 cal_ctl.v

📁 XILINX memory interface generator. XILINX的外部存储器接口。
💻 V
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
 * Implements the calibration technique. performs the following functions:
 * 1. control circuit that determines each tap value
 * 2. hold the total delay value of different taps.
 * 3. determine the tap to use for a given frequency -> select the appropriate tap
 * 
 ***************************************************************************/
`define idleSetup 4'b0000
`define idleD0 4'b0001
`define idleD1 4'b0010
`define idleD2 4'b0011
`define idleD3 4'b0100
`define idleD4 4'b0101
`define idleD5 4'b0110

`define waitSetup 4'b0111
`define waitDcmD0 4'b1000
`define waitDcmD1 4'b1001
`define waitDcmD2 4'b1010
`define waitDcmD3 4'b1011
`define waitDcmD4 4'b1100
`define waitDcmD5 4'b1101

`define idleDone 4'b1110

`define idleReset 1'b1
`define waitReset 1'b0
 `define lBound 8'b0011_0010 // 1000ps, = 1000ps/20 taps.
 `define uBound 8'b0101_0000 // 1600ps, = 1600ps/20 taps.
// `define lBound 8'b0001_0100 // for sims
// `define uBound 8'b0010_0000 // for sims
`define slipCnt 4'b1100

`define tap1 5'b00000
`define tap2 5'b10000
`define tap3 5'b11000
`define tap4 5'b11100
`define tap5 5'b11110
`define tap6 5'b11111
`define defaultTap `tap3

`timescale 1ns/100ps

module cal_ctl(
	       clk,
	       okToSelTap,
	       psDone,
	       reset,
	       hxSamp1,
	       phSamp1,
	       locReset,
	       selTap,
	       psEn,
	       psInc,
	       dcmlocked,
	       tapForDqs
	       );
   
   input         clk;
   input 	 dcmlocked;
   input 	 psDone;
   input 	 reset;
   input 	 hxSamp1;
   input 	 phSamp1;
   
   input 	 okToSelTap;
      
   output 	 locReset;
   output 	 psEn;
   output 	 psInc;
   output [4:0]  selTap;    /*  synthesis syn_keep = 1 */
   output [4:0]  tapForDqs; /*  synthesis syn_keep = 1 */
   
   reg 		 psEn;
   reg 		 psInc;
   reg [4:0] 	 selTap;
   reg [3:0] 	 state;
   reg [7:0] 	 posPhShft;
   reg [7:0] 	 negPhShft;
   reg 		 prevSamp;

   reg [7:0] 	 d0Shft;
   reg [7:0] 	 d1Shft;
   reg [7:0] 	 d2Shft;
   reg [7:0] 	 d3Shft;
   reg [7:0] 	 d4Shft;
   reg [7:0] 	 d5Shft;
   reg [7:0] 	 suShft;
   
   reg [4:0]	 tapForDqs;

   reg 		 waitOneCycle;
   reg 		 waitTwoCycle;
   reg 		 wait3Cycle;
   reg 		 wait4Cycle;
   reg 		 psDoneReg;
   reg 		 wait5Cycle;
   reg [7:0] 	 decPosSh;
   reg [7:0] 	 decNegSh;
   reg 		 rstate;
   reg 		 resetDcm;
   reg [4:0] 	 inTapForDqs;
   reg [3:0] 	 selCnt;
   reg [4:0] 	 newTap;
   reg 		 okSelCnt;
   reg [3:0] 	 midPt;
   reg [2:0] 	 uPtr;
   reg [2:0] 	 lPtr;
   
   reg [7:0] 	 ozShft;
   reg [7:0] 	 zoShft;

   wire      	 locReset;
    
  
   assign locReset = (~reset && dcmlocked) ? 1'b0 : 1'b1;


   always @(posedge clk) begin
      if (reset) begin 
	 ozShft[7:0] <= 8'h00;
	 zoShft[7:0] <= 8'h00;
      end else begin
	 zoShft[7:0] <= suShft[7:0] - posPhShft[7:0];
	 ozShft[7:0] <= negPhShft[7:0]+ suShft[7:0];
      end
   end
   
   // 1. divide clock by 2 since there is no way to get from clock net to D input.
   // this is done outside in module cal_div2
   
   // 2. register normal clock with phClkDiv2 twice to prvent metastability.
   // done outside this block now.
   
   // 3. at offset of 0 between clkDiv2 and phSamp1, set up time may not be met.
   // increase the offset using phase shift to meet the set up time. the number of
   // phase shifts required to meet set up is determined.
   always @(posedge clk) begin
      if (reset) begin
	 psEn     <= 1'b0;
	 psInc    <= 1'b0;
	 state    <= `idleSetup;
	 prevSamp <= 1'b0;
	 
	 posPhShft[7:0] <= 8'h00;
	 negPhShft[7:0] <= 8'h00;

	 d0Shft[7:0] <= 8'h00;
	 d1Shft[7:0] <= 8'h00;
	 d2Shft[7:0] <= 8'h00;
	 d3Shft[7:0] <= 8'h00;
	 d4Shft[7:0] <= 8'h00;
	 d5Shft[7:0] <= 8'h00;
	 suShft[7:0] <= 8'h00;
	 
	 selTap[4:0] <= `tap1;
	 waitOneCycle <= 1'b1;
	 waitTwoCycle <= 1'b0;
	 wait3Cycle <= 1'b0;
	 wait4Cycle <= 1'b0;
	 wait5Cycle <= 1'b0;
	 psDoneReg <= 1'b0;
	 decPosSh[7:0] <= 8'h00;
	 decNegSh[7:0] <= 8'h00;
	 resetDcm <= 1'b0;
	 rstate <= `idleReset;
      end else begin // if (!reset)
	 psDoneReg <= psDone;
	 if (dcmlocked) begin
	    if (resetDcm) begin
	       if (rstate == `idleReset) begin
		  if (posPhShft[7:0] != decPosSh[7:0]) begin
		     psEn          <= 1'b1;
		     psInc         <= 1'b0;
		     decPosSh[7:0] <= decPosSh[7:0] + 1'b1;
		     rstate        <= `waitReset;
		  end else if (negPhShft[7:0] != decNegSh[7:0]) begin
		     psEn          <= 1'b1;
		     psInc         <= 1'b1;
		     decNegSh[7:0] <= decNegSh[7:0] + 1'b1;
		     rstate        <= `waitReset;
		  end else begin
		     resetDcm       <= 1'b0;
		     posPhShft[7:0] <= 8'h00;
		     negPhShft[7:0] <= 8'h00;
		     decNegSh[7:0]  <= 8'h00;
		     decPosSh[7:0]  <= 8'h00;
		  end 
	       end else if (rstate == `waitReset) begin
		  psEn <= 1'b0;
		  if (psDoneReg) rstate <= `idleReset;
		  else rstate           <= `waitReset;
	       end
	    
	    end else begin // if (resetDcm)
	       	       
	       if (waitOneCycle) begin
		  waitOneCycle <= 1'b0;
		  waitTwoCycle <= 1'b1;
	       end else if (waitTwoCycle) begin
		  waitTwoCycle <= 1'b0;
		  wait3Cycle <= 1'b1;
	       end else if (wait3Cycle) begin
		  wait3Cycle <= 1'b0;
		  wait4Cycle <= 1'b1;
	       end else if (wait4Cycle) begin
	          wait4Cycle <= 1'b0;
		  wait5Cycle <= 1'b1;
	       end else if (wait5Cycle) begin
		  wait5Cycle <= 1'b0;
		  if (state == `idleSetup) prevSamp <= phSamp1;
		  else prevSamp <= hxSamp1;
	       end else begin
		  if (state == `idleSetup) begin
		     if ((phSamp1 == 1'b1) && (prevSamp == 1'b0))begin // 0 to 1 transition
			suShft[7:0] <= posPhShft[7:0];
			state        <= `idleD0;
			rstate       <= `idleReset;
			resetDcm     <= 1'b1;
			waitOneCycle <= 1'b1;
		     end else if ((phSamp1 == 1'b0) && (prevSamp == 1'b1)) begin // shd never happen
			suShft[7:0] <= negPhShft[7:0];
			state        <= `idleD0;
			rstate       <= `idleReset;
			resetDcm     <= 1'b1;
			waitOneCycle <= 1'b1;
		     end else if ((phSamp1 == 1'b0) && (prevSamp == 1'b0))begin
			//increment shift
			psEn     <= 1'b1;
			psInc    <= 1'b1;
			state    <= `waitSetup;
			prevSamp <= 1'b0;
		     end else if ((phSamp1 == 1'b1) && (prevSamp == 1'b1))begin
			psEn     <= 1'b1;
			psInc    <= 1'b0;
			prevSamp <= 1'b1;
			state    <= `waitSetup;
		     end
		  end else if (state == `waitSetup)begin // if (state == `idleSetup)
		     psEn <= 1'b0;
		     if (psDoneReg)  state <= `idleSetup;
		  end else if (state == `idleD0) begin
		     if ((hxSamp1 == 1'b1) && (prevSamp == 1'b0)) begin
			d0Shft[7:0]  <= zoShft;
			selTap[4:0]  <= `tap2;
			waitOneCycle <= 1'b1;
			state        <= `idleD1;
			rstate       <= `idleReset;
			resetDcm     <= 1'b1;
		     end else if ((hxSamp1 == 1'b0) && (prevSamp == 1'b1) ) begin
			d0Shft[7:0]  <= ozShft;
			selTap[4:0]  <= `tap2;
			waitOneCycle <= 1'b1;
			state        <= `idleD1;
			rstate       <= `idleReset;
			resetDcm     <= 1'b1;
		     end else if ((hxSamp1 == 1'b0) && (prevSamp == 1'b0)) begin
			// increment phase shift delay
			psEn     <= 1'b1;
			psInc    <= 1'b1;
			state    <= `waitDcmD0;

⌨️ 快捷键说明

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