Acquisition Behavior for a HDD Interpolative Timing Recovery System by Paul Carey Konigsberg Submitted to the Department of Electrical Engineering and Computer Science in Partial Fulfillment of the Requirements for the Degrees of Bachelor of Science in Electrical Science and Engineering and Master of Engineering in Electrical Engineering and Computer Science at the Massachusetts Institute of Technology January 28, 1999 Q Copyright 1998 Paul Carey Konigsberg.All rights reserved. The author hereby grants to M.I.T. permission to reproduce and distribute publicly paper and electronic copies of this thesis and to grant others the right to do so. Author Department of Electrical Engineering and Computer Science Jauary 2 8 ,, 9 9 9 Certified by Professor Jacob White Thesm upersor Accepted by Arthur C. Smith Chairman, Department Committee on Graduate Theses MASSACHUSETT INSTITUTE OF TECHNOLOGY ENGU 1 0U Acquisition Behavior for a HDD Interpolative Timing Recovery System by Paul C. Konigsberg Submitted to the Department of Electrical Engineering and Computer Science May 21, 1999 In Partial Fulfillment of the Requirements for the Degree of Bachelor of Science in Electrical and Engineering and Master of Engineering in Electrical Engineering and Computer Science ABSTRACT The acquisition behavior of an interpolating timing recovery system for a hard disk drive system was studied in Dallas, Texas at Texas Instruments Incorporated. Initially the interpolative timing recovery scheme was designed and tested in the MATLAB language. Upon satisfactory simulations in MATLAB, the design was reconstructed in a high level of the VHDL design language. Results pointed to some improvement in acquisition time in this digital timing recovery design over the analog design. Most valuable to practicing engineers is the tractability of a digital design which was shown to be quite viable. Thesis Supervisor: Jacob White Title: Professor, MIT Electrical Engineering & Computer Science MASSACHUSETTS INSTITUTE OF TECHNOLOGY JUL 1 5 1999 LIBRARIES Introduction This timing recovery system is one component of a read channel to a hard drive. Timing recovery is a relevant topic for the interpretation of information through any channel though, be it a CD-ROM or DVD drive, modem communication, or any other channel. Most common timing recovery systems are based on a feedback loop. On a hard disk drive, each sector has a known data sequence called a preamble. This preamble is used to adjust gain and timing of the read channel in order to properly read the data on the drive which follows the preamble. If the gain and timing recovery loops settle into their correct states quicker, then the preamble can be shorter and the drive could fit more data per sector. This thesis work used the "PR4" preamble which consist of a four bit pattern repeated many times. The four bit pattern is made of the four points along a sine wave at pi/4, 3pi/4, 5pi/4, and 7pi/4. This yields the four values: 0.7071, 0.7071, -0.7071, -0.7071 respectively. A new completely digital method of timing recovery for the hard disk drive read channel now exists which has many advantages over the older voltage controlled oscillator (VCO) synchronous sampling based methods. This newer method is called interpolative timing recovery (ITR) and is completely digital which translates into more robust performance under process variation. The VCO synchronous sampling based methods contain analog based circuitry. The ITR system is also a smaller feedback loop system which enables it to acquire lock, or correct timing, faster than the larger feedback loops of the older systems. (A smaller feedback loop is one with fewer time delays.) The most powerful aspect of the ITR system is its completely digital nature which allows system designers to easily "respin" it from one process to another. "Respinning" is the process of creating a new layout for a circuit because it is to be used in a new design or because a small 2 aspect of the components has changed. An example of this would be a change in transistor dimensions, which would call for much more redesigning, or "respinning", if the system were in an analog format. Before the signal originating from the hard disk drive media comes to the timing recovery loop it passes through a Pre-Amp chip which gives the signal its initial gain. Next comes the Automatic Gain Control (AGC) block which is another loop which fine tunes the proper gain level for the signal. Then the signal passes through an analog low pass filter which is show in the beginning of the timing recovery loop diagrams in figures 1 and 3. Low Pase ,,; Filter Target ADFRAnalysis To Viterbi Detector Loop Filter VCO Figure 1. Synchronous sampling timing recovery loop. An outline of the older synchronous sampling based system can be seen in figure one [1]. After reading an analog signal from the hard disk drive's inductive (or magneto-resistive) head, the signal passes through an analog low pass filter and then enters an analog to digital converter (A/D). This A/D samples the analog signal at a sampling rate approximately four times the flux change rate on the magnetic media. This shape is referred to as a dibit symbol. A dibit response is well approximated by a fourth order Lorenztian [3]. 3 Target Level Target Level Time Figure 2. Shows the two target levels on top of a sketched dibit response. As seen in figure 2 there are certain target levels which the A/D should be sampling to be considered sampling synchronously with the data rate. If the A/D is sampling the analog signal out of phase from these targets or at a rate other than four times the dibit rate the phase error detector will detect this and send a feedback signal to a voltage controlled oscillator (VCO) which controls the rate at which the A/D takes samples. This is the basic outline of a synchronous sampling based timing recovery loops since it adjust the sampling rate to be synchronous with the data in the signal. Low Pass Filter A/D FIR Interpolation Filter To Viterbi t fDetector VCO Loop Filter Target Analysis Figure 3. Block diagram of an ITR based timing recovery loop. A similar block diagram outlining an ITR based timing recovery system is shown in figure 3. Here there is no feedback to the A/D, so in order to ensure that it does not undersample the analog signal the VCO is set to an approximate oversampling rate. The oversampling rate is 5% over the 4 expected synchronous rate. This oversampling rate of 5% came from the bit error rate testing of different oversampling rates done in [1]. This is referred to as asynchronous sampling since it is in no way kept synchronous with the data encoded in the signal. After the A/D a phase error is calculated and sent to the ITR system which picks an appropriate 8-tap finite impulse response (FIR) filter to filter the A/D output. Again, 8-taps were chosen for the filters based on bit error rate testing done in [1] with various numbers of taps. A diminishing return was seen in adding more taps past eight, while the memory expense in Silicon becomes large in using more than eight taps. The feedback loop in the ITR system is within the components which calculate the phase error, select a filter, and filter the A/D output. This is a smaller loop than the VCO based systems feedback loop and therefore should acquire lock faster. Theoretical Background In this bandlimited signal case, as any introductory signal processing course shows, the ideal interpolation filter would be an infinite sinc pulse [4]. In order to create a finite length filter a minimum mean squared error technique was used. To make phase shifting interpolation filters, as are needed here, the infinite sinc pulse was shifted by the appropriate amount and the minimum mean squared error technique was used over and over again for 64 different filters for slightly different phase shifts. The derivation of this technique can be studied in [1]. The 64 evenly spaced phases corresponding to the 64 filters created a range in phase from -Tas/2 to Tas/2 where Tas is the period between asynchronously sampled data points. The ITR system can then choose any one of 64 filters to "fix" the asynchronously sampled data towards the correct phase. The correct phase is determined by matching the ITR's output to a known PR4 pre- 5 amble which is embedded in the asynchronously sampled data. By the time the system has processed the entire preamble the ITR system should be locked. In the locked state, the system should be switching through the set of filters at a constant rate determined by the rate of oversampling in the A/D block. In the locked state any initial phase error should be corrected and the frequency state variable should be settled to the correct value which corresponds to the exact oversampling rate. It should be noted that both in the locked state and while acquiring lock, the system will be effectively dropping an input roughly every 20 inputs since it is roughly set to oversample by 5%. This will happen when the system receives a request to correct a phase error greater than Tas/ 2 . After the input data point is dropped, the phase remainder is taken to select the next filter. This process is referred to as wrapping the phase. In order to check the stability of this system an approximate system function was derived and analyzed. The system was looked at from a phase standpoint and a system diagram can be seen in figure 4. The system in figure 4 was constructed from a phase delay analysis of the system presented in [1], as well as from a previous phase delay analysis of timing recovery loops, already done at Texas Instruments, by Steve Dondershine. 6 Phase Out Unit Delay 1 Figure 4. Approximate system for analyzing ITR system with respect to phase. The system in figure 4 has a tranfer function of 2 H(z) = 6 z_-2Z z 2-2z+ 4 5 1 2 + z + (cc+ p)z - cz The filter delays were increased to 4 and 5 in the event that the system needed further segmentation when it came to pipelining it into a physical device. Those system functions are H 4(z) and H5 (z) respectively. 7 2 H (Z) 4= H5(z) = z -2z+1 7 2 6 5 2 z - z +z +(x+p)z -cz 8_ 7 z 2z+1 z - 2z +z +(c+p)z -arCZ Here alpha and rho are the proportional and integral feedback parameters, respectively. With alpha set to 0.2 and rho at 0.0005, the poles and zeroes of these systems are plotted in figures 5 through 7. Although alpha and rho can be optimized for specific initial phase and frequency errors as well as a specific filter delay, they were left at these values for several reasons. For figures 5 through 7 the effect on system stability of adding delays to the system can be seen while no other aspect of the system is changed. Alpha and rho were not optimized for system simulations because the optimization process is time consuming, implementation specific, and does not fall within the specific goals of this master's thesis. 8 1 0.5 X X : 0) 0 - -. - . ...... . . .. E X X -0.5 -1 -1 -0.5 0 Real part 0.5 1 Figure 5. Pole-Zero plot of H(z) with no added delays. (An X marks a pole and an 0 marks a zero.) 9 1 .- x -. x 0.5- E -0.5- -- -1 -- -1 -0.5 0 Real part Figure 6. Pole-Zero plot of H4(z) (one added delay.) 10 0.5 1 .x 0.5 F x x.- CZ Cz .. . .. ..... . .. . . .. . .. E . . . .. . . . -x x -0.5 F -x -1 -1 -0.5 0 Real part 0.5 1 Figure 7. Pole-Zero plot of H5(z) (two added delays.) In the pole-zero plots of figures 5 through 7, all poles, which are marked by an X, are within the unit circle. There are two zeros at z=1 and a pole at z=0.9975. Since all the poles lie inside the unit circle, this implies stability since this would correspond to poles left of the jw axis in an splane plot after a transformation. Poles left of the jw axis in an s-plane pole zero plot correspond to decaying exponentials which are stable. More on the subject of stability can be found in [2] and [4]. It should be noted though that with poor choices for alpha and rho poles can move out- 11 side the unit circle and create unstable systems. The effect of adding delays in simulations did not noticeably increase the acquisition time although the added delays did produce some occasional small spikes in error. These spikes are believed to be the result of not optimizing the alpha and rho parameters to a new system with a different amount of delay. As a result, the frequency state variable has a large period oscillation until it settles. This causes the error spike with the large periodicity. This phase input/output system is only an approximation to the true ITR system though. The ITR filters have a measured delay through the loop of about 2.9814. The Mueller-Muller calculation was modeled as another delay. Lastly, the result of the process of switching ITR filters was modeled as a simple subtraction of phase from the input phase. This phase input/output system then, should drive its phase output to zero. Similarly the ITR system's output phase error should be driven to zero (with the frequency state variable settling to a final value as well.) Error in the real ITR system comes from several sources. From the filter derivations, error will come from the approximations made for infinity in the summations of convolutions and correlations. This affects both the accuracy of the phase each filter corrects and its unity magnitude gain over frequency. Figure 8 shows the magnitude and phase response of the 64 ITR FIR filters. Recall that the negative slope of the phase response is the group delay of the filter and that half of these filters have positive group delays while the other half have negative group delays covering minus half a symbol period to a positive half symbol period. Also, 5% oversampling corresponds to 0.475 on the frequency axes of the plots in figure 8. 12 Ca 0.1 C 0 C 0.2 201 0 0.1 0.2 0.3 0.6 0.5 0.4 Normalized frequency (Nyquist == 0.7 1) 0.8 0.9 1 0.7 0.8 0.9 1 200 CD) -0.. 2_00 - - -600 0 0.1 0.2 0.3 0.5 0.4 0.6 Normalized frequency (Nyquist ==1) Figure 8. Magnitude and phase response of the 64 ITR FIR filters. Another source of error comes from the quantization of phase into 64 bins. This is a source of pure quantization error. A phase bin is one symbol period divided by 64 would be Pi/2 divided by 64 which is 0.0245 radians. The error in lock varies somewhat between simulations as they may have slightly different oversampling rates in the A/D or different initial phase and frequency errors. This ultimately sets the system in a periodic cycle moving from one error level to the next and those error levels may lie anywhere within quantization limits. Another source of a separate quantization error comes from the quantization of output levels from the A/D. This effect can be 13 seen from the different amounts of error in simulations run with a sample and hold device in place of the A/D, versus a 64 output level quantized A/D. See appendix A for simulation graphs. The A/D quantized voltage signal values ranging from -1 to 1 into 64 levels, with each level being 0.0312 Volts apart. Often the magnitude of a given source of error had to measured empirically through simulation observation since converting Volts to radians on varying points along a sinusoid much less the true 4th order Lorenztian, was difficult. A key characteristic of this system is the propagation delay of information through the filters. A smaller delay through the filter corresponds to information passing through the filter faster and so the faster the system will lock. The filter's delay can be determined by measuring where the center of energy is in the filter. The center of energy of each filter was determined by squaring a filter's elements and multiplying those squares by their elemental index. The average of all these filter centers was 2.9814 as stated earlier. Figure 9 shows the center of energy for all 64 ITR FIR filters. 8 FilterCenter = X f[n]f[n]n n=1 14 3.4 3.3- 3.2- xxx x x x x x x x x x xx (3.1 - x - x x x %x x x xx 3-x x x x x Xx x x x x x x x x x xxxxxx x x 2.7 'III 0 10 20 40 30 Filter Number 50 60 70 Figure 9. Center of Energy for all 64 ITR FIR filters. The ITR system is a second order feedback control loop with parameters alpha, the proportional feedback of the ITR system, and rho, the integral feedback in the system. The dynamics of this loop can be studied in further detail in chapter two of Gardner's "Phaselock Techniques" [5]. The feedback is the measured phase error given by a stochastic gradient algorithm and the integral 15 of this measured phase error. A form of the stochastic gradient algorithm (derived in [3]) known as the Mueller-Muller equation for phase error is ek (k~tk)(tk)-1)(k-1- k-1)tk Here x is the actual output of the ITR system and t represents the target. This equation is a reasonable approximation for phase error. The stochastic gradient algorithm is the approximate solution to a minimum squared error technique used to find the phase error in a timing recovery system [3]. Results The ITR system settled to an error below the acceptable limit in 17 or fewer bits when tested within the ranges of -49% to 49% initial phase error and 4.8% to 5.2% oversampling rates. An acceptable limit for error was 0.062 radians. This comes from the sum of all the error in the system as discussed earlier. These results were obtained from the simulation written in matlab whose source code can be found in appendices B and C. Graphs showing the timing error converging to a settled state for the simulations can be found in appendix A. This system was designed to operate at a steady 5% oversampling rate. Therefore the frequency error state variable of the system is initially set to its final value in a 5 %oversampled system. In the other cases, like the 4.8% and 5.2% oversampled cases, the frequency error state variable takes some time to acquire its correct value. This was the best initial guess found so far for this system which is designed to operate at 5 % oversampling. Oversampling frequency error comes from variances in hard disk spindle speed, variances in the symbol write clock, as well as 16 other sources. Oversampling frequency should not be more than a few tenths of a percent off from the target 5 %. A future improvement in this system would be a better method for getting an initial guess at the frequency error. The initial phase error test at +/- 49 % of the symbol period represents nearly the worst possible initial phase error. A +/- 50 %phase error would be the worst possible error as the system would be quite confused as to what target it should be comparing the data against. (Though one target would be chosen as the system would not be halted over this dilemma.) This phase error was not tested because an initial phase error estimate which the system is given by another block would never be this poor. In this system, something very similar to a Mueller-Muller calculation was done to estimate the initial phase error. Again, in future designs this initial guess in phase error could be improved. Another future system improvement would be the optimization of the system parameters alpha and rho. Here alpha was 0.2 and rho was set at 0.0005 which were found by an unscientific trial and error process. Alpha and rho control how much the system's state variable move in response to new information from the feedback paths. If these parameters are set too low the system responds very slowly to feedback, and if they are set too high then the system bounces around too easily on noise in the feedback. The values used here were obtained from a combination of previous optimizations for alpha and rho which were based on the older synchronously sampling based timing recovery loops and some trial and error testing. Yet another improvement to this system would be a 7-bit A/D. An AID with higher than 7-bit quantization yields little more improvement in overall system error. The improvement in overall system error from the difference in quantization error from a 6-bit A/D to a 7-bit A/D is quite dra- 17 matic. Unfortunately, the Silicon area taken up by the A/D increases by a power of 2 with more accuracy bits. For even better system performance system delays should be minimized while a differential feedback path might be added. In hardware, experience has shown delays will increase acquisition time. Delays will also narrow the margins around the optimized alpha and rho for which the system performs best. Other work at Texas Instruments by Steve Dondershine has shown that a differential feedback path may help to increase these same margins around optimal alpha and rho. These increased margins would allow for a more robust system to have the optimal performance seen in simulations. In comparison to an older synchronously sampling based timing recovery systems already in use, this ITR system provides some improvement in performance and lots in its ease of manufacturing, durability, and especially design. As stated earlier, with all digital components manufacturing process variations are much smaller with the ITR based system which yield smaller product variations. All digital components are also more robust under thermal stress than their analog counterparts within the synchronously sampling based system. Digital circuitry is not as susceptible to error with drift in supply voltages or leaking capacitors as analog circuitry. [1] Synchronously sampling based timing recovery systems in use today which are digitally based, settle in roughly 70 - 100 bits, whereas analog synchronously sampling timing recovery loops settle in approximately 30 bits. An optimized ITR system can settle in a comparable if not shorter amount of time taken by synchronously sampling based systems in use today. In order to further test this ITR system's realizable benefit over conventional synchronously sampling based systems, the ITR system was translated from matlab into VHDL where simulations reported similar results. This code may be found in appendix D. VHDL is a circuit model- 18 ing language with several levels of abstraction. Initially the highest level of abstraction in VHDL was used. Still, at this level in VHDL system clock issues and block layout issues had to be considered. At a still lower level the true delays within the system would be better understood. That understanding would dictate how the calculation blocks might have to be pipelined in order to finish a block's calculation in the given clock period constraints. At this level, the VHDL model could be connected to another VHDL model of an A/D which has been constructed and tested with other real systems at Texas Instruments. At a still lower level, other applications could turn this simulation code into a gate layout design which could produce a physical device for testing. Conclusions A completely digital interpolative timing recovery loop with 5% oversampling which is asynchronous to the data can be simulated and presumably built successfully. With some performance benefit over synchronous sampling methods, the great advantage of an all digital design is the ease of taking it without redesigning it when the manufacturing process changes. Other advantages include larger margins of error in the manufacturing process and greater physical robustness to external factors such as heat, supply voltage drift, etc. Acknowledgments The author would like to thank Texas Instruments' Sami Kiriaki for the position at Texas Instruments as well as Steve Dondershine and Shawn Fahrenbruch for their guidance in modeling and background research. Lundy Taylor and Bogdan Staszewski were also very helpful with coding problems and understanding the timing recovery system. MIT Professor Jacob White is also appreciated for advising this thesis and making sure it conforms to MIT thesis requirements. 19 References [1] Mark Spurbeck and Richard T. Behrens Interpolated Timing Recovery for Hard Disk Drive Read Channels Cirrus Logic, Colorado. [2] Alan V. Oppenheim & Ronald W. Schafer, Discrete-Time Signal Processing, PrenticeHall 1989. [3] Edward A. Lee & David G. Messeschmitt, Digital Communication Second Edition, Kluwer Academic Publishers 1994. [4] William McC. Siebert, Circuits, Signals, and Systems,The MIT Press 1986. [5] Floyd M. Gardner, Phaselock Techniques Second Edition, Wiley & Sons, 1979. 20 Appendix A. Timing Error (in radians) of ITR system. Tdev in radians at 5%oversampling with 0%phase error. 0.8 0.6 'a)0.4 ... . . 0 Below 0.028558 after 500. 0.2 . Settled to 0.062 in9 bits. Alpha= 0.2 Rho= 0.0005 0 100 300 200 500 400 Bit Number 700 600 800 900 Tdev in radians at 5%oversampling with 0%phase error. 0.8 0.6 . . . . 0.4 Below 0.01475 after 500. 0.2 'C x x dM~ 0 Settled to 0.062 in 10 bits. Alpha = 0.2 Rho =0.0005 100 200 300 500 400 Bit Number With Sample & Hold instead of 6-bit quantizing A/D. 21 600 700 800 900 Tdev inradians at 5%oversampling with 25% phase error. 0.8 ...... .. . .. . .. . . . . . . . .. . 0.6S0.4 .......... .......... .......... .......... Below 0.023763' after 500. Settled to 0.062 in1bits. Alpha = 0.2 Rho: 0.0005 . : -NJ M NJ- %J 0 100 . %I 200 %J. -a %z 300 400 500 Bit Number 01 600 800 90( .... I 800 900 700 Tdev inradians at 5%oversampling with -25% phase error. ( 0.6 (I, C 0.4 0) V I- 0.2 ...... -........ . .... Below 0.030404 after 500. Alpha =0.2 Rho 0.0005 Settled to 0.062 in12 bits. x &.1&e g 0La 0 100 200 g, &g, " 300 W J . 400 500 Bit Number 22 600 700 Tdev inradians at 5%oversampling with 49% phase error. 0.8 0.61 0.4 - 0.2 x x xp~x ,xx X 0 0 0.051424 after 500. .Below Alpha =0.2 Rho =0.0005 Settled to 0.062 in10 bits. X X X X X X. X X X X X. X X X.x X X X X X X. X X X X XX X I 100 200 300 400 500 600 700 800 900 800 900 Bit Number Tdev inradians at 5%oversampling with -49% phase error. 0.8I I I I 0.6 F 0.4 Below 0.046118 after 500. 0.2 Settled to 0.062 in12 bits. Alpha 0.2Rho.= 0.0005 0Ir7M7 v."T 0 100 11111 1111! 200 300 400 500 Bit Number 23 600 700 Tdev inradians at 4.8% oversampling with 49% phase error. 0.8 ( 0.6 I c (U 0.4 F Below 0.052197 after 500. 0.2- K x x Settled to 0.062 in8bits. Alpha = 0.2 Rho 0.0005 .1. --IIx a' 0 100 200 300 400 500 Bit Number 600 700 800 90 800 900 Tdev inradians at 4.8% oversampling with -49% phase error. 0.8I 0.6 I c) 0.4 K Below 0.052197 after 500. 0.2 x x Alpha -0.2 Rho 0.0005 Settled to 0.062 in9bits. V" - 0 100 200 300 w. 400 500 Bit Number 24 600 700 Tdev inradians at 5.2% oversampling with 49% phase error. 0.8. I I I I I I 0.6 F Cl) C :5 0.4+ ( I- Below 0.048128 after 500. 0.2 - Settled to 0.062 in11 bits. Alpha= 0.2 Rho 0.0005 0 100 200 300 400 500 600 800 700 900 Bit Number Tdev inradians at 5.2% oversampling with -49% phase error. 0.8I 0.6 ( c5 0.4 4... 0.2X Below 0.048128 after 500. . Alpha = 0.2 Rho 0.0005 X 00 .............. .......... 100 200 300 Settled to 0.062 in 17 bits. 400 500 Bit Number 25 600 700 800 900 Appendix B. Matlab code which creates ITR filters. function [filters,phase-bins]=make filtershalfto-half(num-filters,maxphase) % function [filters,phasebins]=make-filtershalf tohalf(numfilters,maxphase) % 8-28-98 Paul Konigsberg % Texas Instruments % This function will make a matrix whose columns are % 8-tap FIR interpolation filters whose derivation % comes from the IEEE article, "Interpolated Timing Recovery % for Hard Disk Drive Read Channels" by Mark Spurbeck and %Richard T. Behrens (of Cirrus Logic). %numfilters is the number of filters you would like to %create. This variable will also decide how many phase bins % you will create. % max-phase is a fraction of PI that decides how far % the phase binning will go from 0. % The ideal data symbols used to create these filters % (g-k in the article) will be the PR4 preamble sine wave. PI = 3.141592654; T = PI/2; % Symbol period. %Ts = PI/2; % Period of ADC outputs at 5% oversampling should be PI/2.1 Ts = max_phase; infinity=4000; %Approximation to infinity. %numfilters=64; %Make the phase bins array with the center of the bin as the value. %tau=([ 1:numfilters]-0.5)/numfilters; %These next few lines squish all the bins together a little %so that there isn't a 0 filter (which would make 65 filters.) tau=[-round(num-filters/2):round(num-filters/2)]; tau=[tau(1:numfilters/2) tau(numfilters/2 + 2:numfilters+1)]; tau=abs(tau)-0.5; tau=[-tau(1:numfilters/2) tau(numfilters/2 + 1:num_filters)]/numfilters; phase bins=Ts*tau; % Get "dibit" input data which is perfect synchronous PR4 preamble. % See sine.m g=sine(0,infinity); % The symbol period here is T = PI/2 26 % Make the autocorrelation matric R. % R is the same to compute any filter. % Here's the first row of R. for i=1:length(g) % 8-tap filter. temp=O; % temp is a temporary variable. for k=1:length(g)-i+1 temp=temp+g(k)*g(k+i- 1); end R(1,i)=temp; end Rtemp=[R(1,1) R(1,2) R(1,3) R(1,4) R(1,5) R(1,6) R(1,7) R(1,8)]; Rtemp=toeplitz(Rtemp) %Here's the loop that makes all the filters. for index= :numfilters % Make h(i) the ideal filter. phase offset=tau(index); h=[-infinity:infinity]+phase-offset; h=sinc(h); % Make the p matrix for this filter. for n=1:8 % 8-taps in the filters. temp=O; for i=1:length(h) %Use absO since the autocorr. of x(i+1)=x(i-1). x=abs(n-1-(abs(i)-infinity+1)); if x>infinity- 1 x=infinity- 1; end temp=temp+h(i)*R(1 ,+x); end p(n, 1)=temp; end filters(:,index) = -1 *inv(Rtemp)*p; end % Get rid of phase=O center filter. % temp=filters(:,1:(length(tau)-1)/2); % filters=[temp filters(:,((length(tau)- 1)/2 + 2):length(tau))]; % temp=phase-bins(1:(length(tau)-1)/2); % phase bins=[temp phasebins(((length(tau)-1)/2 + 2):length(tau))]; the matlab code for creating the filters goes here. Matlab code needed by Matlab ITR simulation. (Creates A/D output.) function [asynchronous]=adc(data-length,percent,phase offset,print_it) 27 % function [output]=adc(data_length,percent,phaseoffsetprintjit) % 8-31-98 Paul Konigsberg % Texas Instruments %This function should output what the ADC should output, % an oversampled sine wave form, which contained %PR4 preamble data. The oversampling will be (percent) %or 5% by default. It can have an initial phase offset %which is given as a percentage of Ts the asynchronous sample period. PI = 3.14159; T = 4; % symbol period. W = 2*PI/T; %symbol frequency. P=30; N=100; T=4*N; k=(1:P*T); sinwave=sin(2*PI*k/T); if nargin<2 % Default 5% oversampling. percent = 5; end Ts=2*PI/((1 +percent/1 00)*T/N); % ade output period. phase-offset = PI/4-(Ts*phase offset/100); synchronous=sine(0,data-length); % synchronous sampling. t=N*(1:length(synchronous))-50; for i=1:datajlength tLprime(i)=i *(T/((1 +percent/1 00)*T/N)); end for i=1:datajlength % asynchronous sampling asynchronous(i)=sin(phase-offset+(i- 1)*Ts); end if print-it == 'no-print' else figure; subplot(2, 1,1); plot(k,sinwave,'r',t,synchronous,'bo'); ylabel('PR4 Preamble'); grid on; subplot(2,1,2); plot(k,sinwave,'r',t_prime-50,asynchronous,'bo'); grid on; ylabel(strcat('Oversampled PR4 at ',num2str(percent),'%')) 28 end Matlab code needed by Matlab ITR simulation. (Creates sine wave output.) function [output]=sine(phase,length) % function [output]=sine(phase,length) % 8-24-98 Paul Konigsberg Texas Instruments. % This function gives a length long PR4 preamble % based on a sine wave. % Phase should be a fraction of PI. PI=3.14159; for i=1:length output(i)=sin(PI*(i/2-1/4)+phase); end Matlab code needed by Matlab ITR simulation. (Initial phase error estimator.) function [initial-phase-guess,targets]=IPE2(data-in) % Paul Konigsberg 10-7-98 % Texas Instruments % function [initial-phaseguess,targets]=IPE2(datain) % This will make a rough guess on the initial phase % of the ADC samples in the presence of noise. PI=-3.14159; onetwoave=(data in(1)+data in(2))/2; threefourave=(data-in(3)+data-in(4))/2; onefourave=(data-in(1)+data-in(4))/2; twothreeave=(datain(2)+datajin(3))/2; if abs(onetwoave-threefourave) > abs(twothreeave-onefourave) if onetwoave > 0 initial-phase-guess=-.7071*( data-in(4)+0.7071 - ( datajin(3)+0.7071 )); targets=[1 1]; else initial-phase-guess=-.7071*( datajin(4)-0.7071 - (datain(3)-0.7071)); targets=[-1 -1]; 29 end else if twothreeave > 0 initial_phase-guess=.7071*( datajin(3)-0.7071 - ( datajin(2)-0.7071 )); targets=[-1 1]; else initial-phase-guess=-.7071*( datajin(3)+0.7071 - (datajin(2)+0.7071)); targets=[1 -1]; end end 30 Appendix C. Matlab which code runs ITR simulation. function [data out,Tdev,settle]=halfsys(filters,phases,initial-phase-error,print-it) % [dataoutTdev,settle] = halfsys(filters,phases,initial-phase error,print_it) % 9-3-98 Paul Konigsberg % Texas Instruments This should simulate the interpolative timing recovery system after the FIR which is demonstrated in "Interpolated Timing Recovery for Hard Disk Drive Read Channels" by Mark Spurbeck and Richard T. Behrens. % initial-phase-error: % represents how much of a A/D sampling period you % are ahead. %print-it will graph output data if set to 'y' otherwise no output will be graphed. % % Our input will be PR4 preamble for testing purposes. % This uses the total NO OP on dropped bits. But it does NOT GATE OUT % the dropped bit. alpha = 0.0315; rho = 0.00075; rho=0.0005; alpha = 0.2; % rho = 0.003; oversamplerate = 5.0; delay=0; noise = 0.0; PI = 3.14159; T = PI/2; % Synchronous sample period. % number of preamble cycles P = 60; % oversampling rate N = 100; % preamble period T = 4*N; errormargin = 0.062; %Error must be within this to be "settled". ADCbits = 6; %Number of bits on A/D. 6 bits = 64 levels of quant. target-high = sin(PI/4); target-low = -target-high; [valuenum_filters]=size(filters); dT(1)=0; 31 tau(1)=0; index old=0; stream-length = 1024; %Length of asynch data we will look at. tau=zeros(streamjlength, 1); dT=zeros(streamjlength, 1); Tdev=zeros(round(streamjlength-stream length/20),1); data-out=[]; voltage-error=zeros(1,streamlength); indeces=zeros(streamjlength, 1); % Quantize filters to 0.001 % filters=round(1000*filters)/1000; %create preamble for graphing purposes later. k = (1:P*T*4)'; % time index covers P preamble periods r = sin(2*PI*k/T); % sinusoidal preamble of period=T % gets oversampled and phase delayed PR4 ...preamble. asynch data=adc(streamjlength,oversample rate,initial-phase-error,'no_print'); % Quantize it to 64 levels between -1 and 1. quantlevels=(([1:(2AADC bits)]-1)/(2A(ADCbits-1)))- 1; for i=1:length(asynch-data) [value,place]=min(abs(quantjlevels-asynch-data(i))); asynchdata(i)=quant-levels(place); end % To add noise... asynch data=asynch data+noise*randn(size(asynch-data)); %Get initial phase estimation from IPEO with first 4 bits. [tg(1:5),targets]=IPE2(asynchdata(1:4)); oldtarget = targets(1); current-target = targets(2); dT(1:5)=0.0774; % Injected frequency error guess. tau(1:5)=alpha*tg(1)+15*dT(1) ; [value,index]=min(abs(phases-tau(1))); % index is the filter choice. index0=index; indexl=index; index2=index; index3=index; indeces=[]; pause on donothing=0; drops=zeros(stream length, 1); nopush=0; 32 for i=6:length(asynchdata)-8-round(length(asynch-data)/20) if donothing==1 % Drop this bit. else % use filter # index. ralph=[ralph index 1]; ralph2=[ralph2 index2]; ralph3=[ralph3 index3]; if no-push==O if delay==1 index=index2; index2=index3; elseif delay==2 index=index1; index1=index2; index2=index3; elseif delay==3 index=indexO; indexO=index1; index1=index2; index2=index3; else index=index3; end else nopush=O; end indeces=[indeces index]; %Just to see what filters were used. filtertaps=filters(:,index); data=filterjtaps(8)*asynch-data(i); data=data+filterjtaps(7)*asynchdata(i+1); data=data+filtertaps(6)*asynch-data(i+2); data=data+filterjtaps(5)*asynch-data(i+3); data=data+filterjtaps(4)*asynchdata(i+4); data=data+filterjtaps(3)*asynch-data(i+5); data=data+filterjtaps(2)*asynch-data(i+6); data=data+filtertaps(1)*asynch-data(i+7); dataout=[data-out data]; % dataout(i)=data; if data>O voltage-error(i)=data-target high; current-target = target-high; else voltage-error(i)=data-targetjlow; 33 currenttarget = targetlow; end tg(i)=voltage-error(i)*old-target - voltage..error(i- 1)*currenttarget; tau(i)=alpha*tg(i) + tau(i-1) + dT(i-1); dT(i)=rho*tg(i)+dT(i- 1); [value,index3]=min(abs(phases-tau(i))); %index is the filter choice. oldjtarget=current target; end if donothing==1 % "Dropped" this bit.... tau(i)=(tau(i- 1)-phases(num-filters)-O.O 123)+phases(1); [value,index3]=min(abs(phases-tau(i))); donothing=O; dT(i)=dT(i-1); drops(i)=1; if delay==1 index=index2; index2=index3; % nopush=1; elseif delay==2 index=index1; indexl=index2; index2=index3; % nopush=1; elseif delay==3 index=indexO; indexO=index1; index 1=index2; index2=index3; % nopush=1; else index=index3; end if delay>O dT(i)=rho*tg(i-1)+dT(i); tau(i)=alpha*tg(i- 1)+dT(i)+tau(i); [value,index3]=min(abs(phases-tau(i))); end; elseif tau(i)>(phases(num-filters)+0.0123) %Drop next bit if > max+halfbin. do-nothing=1; % 0.0123 is half a phase bin width for 64 phase bins. end end %for i=2:length(asynch-data) 34 % %%%POST PROCESSING. %%% % Calculate a Tdev. for i=1:length(data-out) if data out(i)>O & abs(data-out(i))<=1 % Tdev(i)=(mod(asin(data-out(i)),T)-asin(.707 1)); Tdev(i)=abs(asin(data-out(i))-asin(.707 1)); elseif abs(data-out(i))<=1 %Tdev(i)=(mod(-asin(data out(i)),T)-asin(.7071)); Tdev(i)=abs(-asin(dataout(i))-asin(.707 1)); end end %Figure out where it settled. settle= 1e9; for i=1:800 %length(Tdev) if abs(Tdev(i))>error-margin settle=i; end end % Figure out what the max Tdev was after long time... temp-data=Tdev(500:length(Tdev)); [maxTdev,value]=max(temp-data) % Calculate Muller Muller gain error. for i=2:length(data-out) if data-out(i-1)>0 error old=(data out(i- 1)-.707 1)*.707 1; else error old=(data out(i- 1)+.707 1)*-.707 1; end if data out(i)>0 error=(data-out(i)-.7071)*.7071; else error-(dataout(i)+.707 1)*-.707 1; end gain-error(i)=error+error_old; end parameter-text=['Alpha =' num2str(alpha)' Rho =' num2str(rho)]; settletext=['Settled to ' num2str(errormargin) ' in ' num2str(settle) 35 ' bits.']; if printit=='d' | printit=='a' %This would plot the asynchronous data input & synchronous data output. figure; subplot(2, 1,1) plot(asynch-data,'bd'); asynch-title=['Asynch Data at ' num2str(oversamplerate) '%']; asynch-title=[asynchtitle ' oversampleing with ']; asynchtitle=[asynchtitle num2str(initial-phase error) '%']; asynch title=[asynchtitle ' phase error.']; title(asynchjtitle); subplot(2,1,2); plot(data out,'bd'); title('Data Out after Filtering.'); text(1 25,0,settle text); text(500,0,parameter text); end if print-it=='t' I printit=='a' figure; plot(Tdev(1:910),'kx'); % axis([250 350 -.1 0.1]); grid on; Tdev-title=['Tdev in radians at ' num2str(oversamplejrate) '%']; Tdev-title=[Tdevtitle ' oversampling with ' num2str(initialphase-error) '%']; Tdevjtitle=[Tdevtitle ' phase error.']; title(Tdev title); MaxTdev_title=['Below ' num2str(maxTdev)' after 500.']; text(550,0.225,MaxTdev title); text(550,0. 1,settletext); text(150,0. 1,parameter text); xlabel('Bit Number'); ylabel('Tdev (radians)'); end if print_it=='f' | printjit==' a' % %%PLOTTING with a sine wave background.%%% t=[1:P]*T/4-T/8; figure; grid on; orient tall; %subplot(2,1,1); plot(k,r,'r' ,t,r(t),'bo'); grid on; % xlabel(['time, N=' num2str(N) ' samples per symbol bit']); % ylabel('preamble'); % axis([1 N*P -1 1]); subplot(2, 1,1); plot(Tdev,'mx'); 36 title(Tdevtitle); grid on; text( 150,-0.5,settle text); text( 150,0.5,parameter text); periods=O; j=1; p(1)=1; for i=2:length(data out) if mod(i+2,4)==O p(i)=200*(asin(data-out(i))/PI)+periods*400; elseif mod(i+1,4)==O p(i)=100-200*(asin(data-out(i))/PI)+100+periods*400; elseif mod(i,4)==O p(i)=300-200*(asin(data-out(i))/PI)+periods*400; else p(i)=200*(asin(data-out(i))/PI)+300+periods*400; end if j==4 periods=periods+1; j=O; end j=j+1; %pause(2) end p(2)=abs(p(2)); p=round(p); subplot(2,1,2); plot(k,r,'r',p,r(p),'bo'); axis([1 N*P*5 -1 1]); title(strcat(num2str(P),' Periods of Processed Data.')); end % if printit='f' OR 'a' fircoeffsfile=fopen('/users/pking/itr/mfiles/fircoeffs.doc','w'); for i=1:64 for j=1:8 fprintf(firicoeffsfile, '%fAn',filters(j,i)); end end fclose(fir_coeffs file); phases-file=fopen('/users/pking/itr/m-files/phases.doc','w'); for i=1:64 fprintf(phasesjfile,'%f',phases(i)); end fclose(phases-file); 37 for i=1:length(data out) real-diff(i)=abs(abs(data out(i))-0.707 1); end 38 Appendix D. VHDL code which runs top level (test bench) ITR simulation. -- Paul Konigsberg Top level for ITR system. -- Texas Instruments 10/30/98 - This is the top level test bench which tests ADC.vhd, READPHASES.vhd, -- READFIRS.vhd, and ITR_loop.vhd - ITRsystem datain -- I ADC -- - ------------------- >1 ITR-loop | dataout -------- > phases READPHASES---------->1 firs READFIRS------------ >1 Library IEEE; use IEEE.Stdlogic 1164.all; use work.all; use work.firtypes.all; use work.COMMON.all; entity ITR-system is -- port ( DATAOUT:out real -- Data output of the ITR system. end ITR-system; architecture instanceofITR-system of ITR-system is signal ENABLE:bit:='0'; signal FIRS:array-of firs; signal phases:phase-array; signal CLK:bit; signal DATAIN:real; signal DATAOUT:real:=0.0; 39 component READFIRS port ( FIRS:out array_of_firs; ENABLE:out bit end component; component READPHASES port ( phases:out phase-array end component; component ADC port ( ENABLE:in bit; DATAIN:out real end component; component ITR_loop port ( FIRS:in arrayofjfirs; ENABLE:in bit; CLK:in bit; DATAIN:in real; phases:in phase-array; DATAOUT:out real end component; component Tdevcalc port ( DATAOUT:in real end component; begin ADC1:ADC port map ( DATAIN => DATAIN, ENABLE => ENABLE READFIRS1:READFIRS 40 port map ( ENABLE => ENABLE, FIRS => FIRS READPHASES1:READPHASES port map ( phases => phases ITRjloop1:ITR-loop port map ( FIRS => FIRS, ENABLE => ENABLE, CLK => CLK, DATAIN => DATAIN, phases => phases, DATAOUT => DATAOUT Tdevcalc1:Tdevcalc port map ( DATAOUT => DATAOUT end instanceofITRsystem; VHDL code for ITRjloop.vhd. - Paul Konigsberg ITR loop: computing output, and control signals. - Texas Instruments 10/30/98 - library ieee; use ieee.stdlogic1 164.all; use work.all; use work.firtypes.all; use work.COMMON.all; use work.COMPONENTSCOMMON.all; entity ITRjloop is port ( FIRS: in array_of-firs; 41 ENABLE: in bit; CLK:in bit; DATAIN:in real; phases:in phase-array; DATAOUT:out real end entity ITRjoop; architecture instanceofITRloop of ITRjloop is signal target high:real:=0.7071; signal target_.low:real:=-O.7071; -- signals so we can watch their analog variation over time. signal tau-signal:real; signal dto-signal:real; signal filter-signal:integer; begin ITRlabel:process (DATAIN) is variable delay:integer:=0; variable filterholdi ,filter hold2,filterhold3:integer:= 15; variable variable variable variable variable variable variable variable variable variable variable variable variable variable i,filter:integer:= 15; alpha:real:=0.2; rho:real:=0.0005; tau:real:=O.O; integral-term:real:=0.08 137; data1,data2,data3,data4,data5,data6,data7,data8:real :=0.0; dto:real:=O.O; temp:phase-array; smallest:real:=0.0; timing-gradient:real:=0.0; currenttarget:real:=0.7071; oldjtarget:real:=0.7071; voltage-error:real:=0.0; oldvoltage-error:real:=0.0; begin if ENABLE='1' then data8:=data7; data7:=data6; data6:=data5; data5:=data4; data4:=data3; 42 data3:=data2; data2:=datal; datal:=DATAIN; if tau>phases(1) then tau:=tau-phases(1)+phases(64); else i:=filter; dto:=data8*FIRS(i, 1)+data7*FIRS(i,2)+data6*FIRS(i,3)+data5*FIRS(i,4)+data4*FIRS(i,5)+ data3*FIRS(i,6)+data2*FIRS(i,7)+data *FIRS(i,8); if dto > 0.0 then voltage-error:=dto-target-high; currenttarget:=target-high; else voltage-error:=dto-targetjlow; currenttarget:=targetjlow; end if; timing-gradient:=voltage-error*oldjtarget - oldvoltageerror*currentjtarget; tau:=alpha*timing-gradient+tau+integral_term; integral-term:=rho*timing-gradient+integral-term; oldjtarget:=current target; oldvoltage-error:=voltage-error; DATAOUT<=dto; dtosignal<=dto; end if; -- tau > max tau. --Search for best filter.... for i in 1 to 64 loop temp(i):=abs(phases(i)-tau); end loop; smallest:=temp(1); filterhold3:=1; for i in 2 to 64 loop if temp(i)<smallest then smallest:=temp(i); filterhold3:=i; end if; end loop; if delay=1 then filter:=filter-hold2; filterhold2:=filterhold3; end if; if delay=2 then filter:=filterhold1; filterhold 1:=filterhold2; filterhold2:=filterhold3; 43 end if; if delay=0 then filter:=filterhold3; end if; tausignal<=tau; filter-signal<=filter; end if; -- ENABLE='1' end process ITR_label; end architecture instanceofITRjloop; VHDL code for ADC.vhd. -- Paul Konigsberg -- ITR system block which creates A/D output for ITRjloop block. -- Texas Instruments 10/30/98 Now a true A/D. - library ieee; use ieee.stdjlogic1 164.all; use work.all; use work.COMMON.all; use work.COMPONENTSCOMMON.all; use work.all; use work.fir-types.all; entity ADC is port ( ENABLE:in bit; DATAIN:out real end entity ADC; architecture instanceofADC of ADC is signal CLK: stdlogic:='0'; signal ENA: stdlogic:='1'; signal DTO: real; begin 44 SO: entity work.IO_RSTREAM generic map ( FILENAME => "sinewave.doc", GAIN => 1.0 ) port map ( CLK => CLK, ENA => ENA, DTO => DTO CLOCKGEN: process is variable ADCbits: integer:=6; --Number of bits for AID. -- 6 bits = 64 levels of quant. variable current-phase:real:=0.0; variable phasediff:real:=0.0; variable OSR:real:=0.95; -- Over Sampling Ratio. variable variable variable variable variable variable variable variable variable variable sinewave:sine-wave_type; diffs:sinewavejtype; smallest:real; dtovar:real; -- To be assigned to DATAIN at the end. READ_SINE_WAVE:std_logic:='O'; temp:real; i,j,index:integer; realints:sine_wavejtype; quantlevelstemp-data:sine wavejtype; tempvar:real; begin --- This initial segment is run in the beginning and primarily loads the sine wave. if ENABLE='O' and READSINEWAVE='O' then for i in 1 to 1000 loop CLK <= not CLK; wait for 1 ns; CLK <= not CLK; wait for 1 ns; sinewave(i):=DTO; wait for 1 ns; end loop; READSINEWAVE:='1'; phasediff:=1.5708*OSR; temp:=1.0; for i in 1 to 1000 loop 45 realints(i):=temp; temp:=temp+1.0; end loop; for i in 1 to (2**ADCjbits) loop tempvar:=2.0**(-ADCbits+1); quant-levels(i):=((real-ints(i)-1.O)*temp_var)-1.0; end loop; end if; -------- This next segment runs later on and produces ADC output which can be phase delayed and variable freq. oversampled. It gets a bit complicated in the process of rounding the real variable temp to the integer index. if ENABLE='1' and READSINEWAVE='1' then currentphase:=current-phase+phase-diff; if current-phase>6.2832 then -- Wrapping around 2 pi. current_phase:=current_phase - 6.2832; end if; temp:=1000.0*(current-phase/6.2832); for i in I to 1000 loop diffs(i):=abs(real_ints(i)-temp); end loop; smallest:=diffs(1); for i in 2 to 1000 loop if diffs(i)<smallest then smallest:=diffs(i); index:=i; end if; end loop; --Found true sampled data point at sine wave(index). --Quantize the sine-wave(index) to one of -- 2**ADCbits levels. for i in 1 to 2**ADCbits loop temp-data(i):=abs(sinewave(index)-quantjlevels(i)); end loop; smallest:=tempdata(1); index:=1; for i in 2 to 2**ADCbits loop if temp-data(i)<smallest then smallest:=temp-data(i); index:=i; end if; 46 end loop; dto-var:=quant levels(index); DATAIN<=dtovar; end if; wait for 1 ns; end process; end architecture instanceofADC; VHDL code for READFIRS.vhd. - Paul Konigsberg - ITR system block which reads FIR filter coefficients from file. - Texas Instruments 10/30/98 library ieee; use ieee.stdlogic1 164.all; use work.all; use work.fir_types.all; use work.COMMON.all; use work.COMPONENTSCOMMON.all; entity READFIRS is port ( FIRS:out array-of firs:=(others=>(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0)); ENABLE:out bit end entity READFIRS; architecture reading_FIRS of READFIRS is signal TIME_STEP: time := 0.5 ns; signal CLK: stdlogic :='0'; signal DTO: real; signal DT1: real; signal last-dataread:real:=0.0; signal STOPREADING:bit:='O'; signal ENA:stdlogic:='1'; begin SO: entity work.IORSTREAM generic map ( FILENAME => "fircoeffs.doc", GAIN => 1.0 ) 47 port map ( CLK => CLK, ENA => ENA, DTO => DTO CLOCKGEN: process is variable i,j:integer:=1; begin if STOPREADING='0' then for i in 1 to 64 loop for j in I to 8 loop if lastdataread/=0.021929 then CLK <= not CLK; wait for 1 ns; CLK <= not CLK; wait for 1 ns; FIRS(i,j)<=DTO; lastdataread<=DTO; else STOPREADING<='1'; ENABLE<='1'; end if; end loop; end loop; end if; wait for 1 ns; end process CLOCKGEN; end architecture readingFIRS; VHDL code for READPHASES.vhd. --- Paul Konigsberg ITR system block which reads phase bins from file. -- Texas Instruments 11/10/98 library ieee; use ieee.stdlogic_ 164.all; use work.all; use work.firjtypes.all; use work.COMMON.all; use work.COMPONENTSCOMMON.all; 48 entity READPHASES is port ( phases:out phasearray:=(others=>0.O) end entity READPHASES; architecture reading-phases of READPHASES is signal TIME_STEP: time:= 0.5 ns; signal CLK: stdlogic :='0'; signal DTO: real; signal DT1: real; signal last-dataread:real:=0.0; signal ENA:stdlogic:='1'; begin SO: entity work.IORSTREAM generic map ( FILENAME => "phases.doc", GAIN => 1.0 ) port map ( CLK => CLK, ENA => ENA, DTO => DTO CLOCKGEN: process is variable i:integer:=1; begin for i in 1 to 64 loop if lastdataread<0.773126 then CLK <= not CLK; wait for 1 ns; CLK <= not CLK; wait for 1 ns; phases(i)<=-DTO; lastdataread<=DTO; end if; wait for 1 ns; end loop; end process CLOCKGEN; end architecture reading-phases; 49 VHDL code for fir-pkg.vhd. -- Paul Konigsberg -- 11/2/98 -- Texas Instruments - Package declarations for the ITR system. package fir-types is type array-of firs is array (1 to 64,1 to 8) of real; type phase-array is array (1 to 64) of real; type sine-wavejtype is array (1 to 1000) of real; end package firjtypes; VHDL code for iorstream.vhd (written by Bogdan Staszewski). $Header: /users/bogdan/V/common/RCS/iorstream.vhd,v 1.1 1998/02/12 00:03:04 a196312 Exp $ -- - Clocked Sample Stream Generator with Enable, iorstream.vhd -- (file text mode) - On every rising edge of the CLK clock, provided the ENA enable signal -is'',a real-type number will be read from file "FILENAME" and its - corresponding signal level will be output as DTO. - If the enable signal goes '0', the output will go to zero. If the data file gets exhausted the output will go to zero. -- (C) Bogdan Staszewski, Texas Instruments, Inc, 11/9/97 library ieee; use ieee.stdjlogic1 164.all; use std.textio.all; entity IORSTREAM is generic ( FILENAME: string := "data.rtx"; GAIN: real := 1.0 port ( ENA: in stdjlogic; CLK: in stdjogic; 50 DTO: out real:= 0.0 end entity IORSTREAM; --------------------------------------------------------architecture BINREAL of 10_RSTREAM is type FILEREALTYPE is file of real; file FILEREAL: FILEREALTYPE open readmode is FILENAME; begin process (CLK, ENA) is variable STATUSOK: boolean true; variable VAL: real; begin if (CLK'event and ENA='1' and CLK='1' and STATUSOK) then STATUSOK := not endfile (FILEREAL); if STATUSOK then read (FILEREAL, VAL); if (GAIN = 1.0) then DTO <= VAL; else DTO <= VAL * GAIN; end if; else DTO <= -100.0; -- report "10_RSTREAM: Read file exhausted"; end if; - reset elsif (ENA'event and ENA='0') then DTO <= 0.0; end if; end process; end architecture BINREAL; ------------------------------------------------------- the default architecture architecture TEXTREAL of 10_RSTREAM is FILENAME; is readmode open text file FILETEXT: begin process (CLK, ENA) is variable BUF: line; variable STATUSOK: boolean := true; variable VAL: real; begin if (CLK'event and ENA='1' and CLK='1' and STATUSOK) then STATUSOK := not endfile (FILETEXT); if STATUSOK then readline (FILE TEXT, BUF); read (BUF, VAL); 51 if (GAIN = 1.0) then DTO <= VAL; else DTO <= VAL * GAIN; end if; else DTO <= 0.0; report "IO_RSTREAM: Read file exhausted"; end if; elsif (ENA'event and ENA='0') then - DTO <= 0.0; end if; end process; end architecture TEXTREAL; ----------------------------------- end of io-rstream.vhd - 52 reset