Unidad 7 · PLL · el oscilador como integrador de fase, el acumulador módulo 2π, el DDS y su tabla
El receptor genera su propia sinusoide con un oscilador cuya frecuencia se maneja con una señal de control. El control no fija la fase: fija a qué ritmo crece. Por eso, mirado desde la fase, el oscilador es un integrador, en el VCO analógico y un acumulador en el NCO digital. De ahí sale todo: que un control constante sea otra frecuencia, que un registro de bits que desborda sea un oscilador entero, y que el lazo tenga un integrador más del que pone el filtro.
En la filmina el VCO recibe la señal de control , una tensión, y entrega
Con constante la salida sólo depende de , la frecuencia natural del VCO: la que da sin control. Lo que el control mueve es , y lo mueve a través de la frecuencia. La frecuencia instantánea de la salida es la derivada de todo el argumento del coseno:
y el VCO se diseña para que el apartamiento de la frecuencia natural sea proporcional al control:
dice cuántos hertz agrega cada volt, y es lo mismo en rad/s por volt, que es como aparece en el diagrama del lazo. La filmina escribe primero , con la ganancia metida adentro del control, y después la hace explícita: son la misma ecuación con otra unidad para .
Al lazo no le importa la sinusoide: le importa su fase. Lo que hay que obtener es la transferencia de a .
Paso 1: el control fija la derivada. La ecuación de diseño, , no habla de la fase sino de su pendiente. Es un acelerador, no un volante: el pie fija la velocidad, y la posición es lo que se va juntando.
Paso 2: integrar para despejar la fase. Con el lazo arrancando en y , por el teorema fundamental del cálculo:
Paso 3: pasar a Laplace. La derivada se transforma como , y la condición inicial es cero. La ecuación de diseño queda , y despejando:
Un polo en : el VCO, visto desde la fase, es un integrador con ganancia . Ese bloque está en todo PLL, tenga el filtro de lazo los integradores que tenga. Cómo se cierra el lazo alrededor de él está en la nota del PLL.
Paso 4: lo que el integrador recuerda. Para correr la fase y dejarla ahí, el control tiene que dar un pulso de área y volver a cero. Cuando vuelve, la fase no vuelve: se queda donde la dejó el pulso. En el script de la clase, un pulso de control de cuatro muestras de alto 1 deja la fase del NCO en 4 para siempre (bloque 1 del análisis en MATLAB, más abajo).
Con constante, la integral es una recta:
Es la frase de la filmina: la salida tiene una frecuencia constante , o, dicho desde la fase, una rampa de fase. Las dos lecturas son la misma cosa: una fase que crece en línea recta respecto de un oscilador a es una sinusoide de otra frecuencia.
Esto da vuelta lo que el lazo tiene que hacer. Si la entrada llega a , su fase relativa es , y el VCO sólo la sigue si su control se queda para siempre en . Enganchado, en la filmina, es con constante: las frecuencias coinciden y la diferencia de fase no crece. Algo tiene que sostener ese control constante con el error de fase en cero, y eso es lo que pide el integrador del filtro de lazo (sección 08).
En un receptor digital no hay tensión de control: hay un número por muestra. El oscilador controlado numéricamente, el NCO, es el VCO discretizado, y se obtiene igual que el VCO, pero integrando de a una muestra.
Paso 1: cortar la integral en pedazos de ancho . La fase en es la de una muestra antes más lo que se integró en el último intervalo:
El pedazo se aproxima por un rectángulo de alto , el valor en el borde derecho.
Paso 2: normalizar. En el script de la clase, phase_system.m, la ganancia vale 1 —junto con la del detector, por muestra, quedó absorbida en Kp y Ki—, así que el control se mide directamente en radianes por muestra:
Es un acumulador: un registro que guarda la fase y le suma el control en cada muestra.
Paso 3: pasar a . Atrasar una muestra es multiplicar por . La recursión queda ; se pasa el primer término a la izquierda y se saca factor común:
Es la línea NCO = z/(z-1) del script. El polo quedó en , que es la imagen de por : el acumulador es el integrador del mundo discreto, y con un control constante la fase sale : la rampa de la sección anterior, en muestras. Un control de rad por muestra corre la frecuencia hertz.
El otro borde del rectángulo. Si en el paso 1 se toma el valor del borde izquierdo, , sale , que es el modelo del libro de Rice: la fase de hoy es la suma de los controles hasta ayer. Es el mismo acumulador con una muestra de retardo, o sea el NCO del script con Lat = 1. Con las constantes de la clase esa muestra mueve el sobrepico del escalón de 39,72 % a 40,14 %. Qué más hace la latencia está en el PLL en tiempo discreto.
El modelo de fase alcanza para analizar el lazo, pero el receptor necesita la sinusoide. El oscilador completo, al que Rice llama sintetizador digital directo (DDS), son dos piezas: el acumulador de fase y una tabla que convierte fase en coseno.
La fase que guarda el registro es la fase instantánea entera, , y es el odómetro de la sinusoide: cuánto giró desde que arrancó. La frecuencia instantánea es cuánto avanza por muestra. es la frecuencia natural, el avance que tiene sin control, y es el control, el del script. En el modelo de fase del lazo no aparece porque es una rampa conocida que se resta de entrada; en el oscilador sí, porque es la que hace girar.
Como lo que se guarda es la fase y no la frecuencia, cambiar el control no hace saltar la salida: la fase sigue desde donde estaba y sólo cambia su pendiente. La frecuencia puede ser discontinua; la fase, no.
El coseno no se calcula: se lee. La tabla (LUT, look-up table) guarda en la dirección , y el acumulador le da la dirección. Con dos tablas, o una sola leída un cuarto de vuelta corrida, salen el coseno y el seno juntos: la exponencial compleja que el receptor usa para rotar.
En hardware la fase es un entero. Un acumulador de bits guarda entre y , y ese entero representa una fracción de vuelta. En cada muestra le suma la palabra de control , también entera:
Paso 1: la frecuencia que sale. La fase avanza de vuelta por muestra, y con muestras por segundo eso es
Paso 2: la resolución. Como es entero, las frecuencias posibles son los múltiplos de la que da :
Es la sinusoide más lenta: el registro tarda muestras en dar una vuelta. Cada bit más parte la grilla a la mitad. A los GHz del script de la clase:
| N | resolución fs/2N |
|---|---|
| 8 | 62,5 MHz |
| 16 | 244 141 Hz |
| 24 | 953,674 Hz |
| 32 | 3,72529 Hz |
Paso 3: pedir una frecuencia. Para una frecuencia pedida la palabra es , y la que sale difiere de la pedida en media resolución como mucho. Medido con un NCO de 24 bits armado a mano: pedidos 1 000 001 234 Hz, la palabra es y salen 1 000 000 953,6743 Hz: 280,33 Hz de error, debajo de los 476,84 que es media resolución. La frecuencia se midió sobre la salida, ajustando una recta a la fase desenrollada de la exponencial que entrega la tabla, y da la misma cifra a cuatro decimales que la fórmula del paso 1. Son dos caminos distintos —uno cuenta enteros, el otro pasa por la tabla y por angle— y coinciden.
Ese error de cuantización no se queda quieto: una diferencia de frecuencia es una fase que crece. Los 280 Hz son una rampa de fase de rad/s respecto de la portadora pedida, una vuelta entera cada 3,6 ms. Si el NCO está dentro de un PLL no importa, porque el lazo la ve como cualquier otro corrimiento y la corrige; si el oscilador está suelto, se acumula.
Con cuatro bits, pedir no mueve nada: la palabra redondea a 0, porque media resolución es 0,03125, y el registro se queda quieto mientras el coseno pedido da casi dos vueltas en 64 muestras. Pasando 0,03125 la palabra salta a 1 y el NCO gira, pero a 0,0625, el doble de lo pedido. Lo que sale está siempre sobre la grilla de , y la diferencia con lo pedido se ve abajo como una recta: el error de frecuencia es una rampa de fase. Con la deriva tras 64 muestras es −1,6 ciclos con , 0,4 con 6, −0,1 con 8 y 0,025 con 10: cada dos bits, cuatro veces menos, y el signo depende de para qué lado redondeó la palabra.
La fase acumulada crece sin parar y el registro tiene bits. Cuando una suma no entra, el acarreo que sale del bit más alto se pierde. Ese acarreo pesa , y unidades del registro son exactamente una vuelta, . Como , tirar una vuelta no cambia la salida: el sumador hace la reducción módulo sin un solo bloque extra. Es el diente de sierra del panel de arriba.
Leído en complemento a dos, el mismo registro va de a , la fase cae en y la suma sigue siendo la misma, porque el entero con signo y el sin signo difieren justo en . Una palabra de control negativa es una frecuencia negativa: la exponencial gira para el otro lado, y eso es lo que el lazo usa cuando la portadora llega por debajo de la natural.
Y los desbordes cuentan ciclos. En el NCO de 24 bits de la sección anterior hubo 4095 desbordes en 65 535 sumas, y : cada desborde es una vuelta completa de la sinusoide.
Una tabla direccionada con los 32 bits del acumulador tendría entradas. Lo que se hace es truncar: sólo los bits de arriba van a la tabla y los de abajo se tiran. El corte está afuera del lazo del acumulador, que sigue sumando con sus bits, así que la frecuencia media no cambia. Lo que cambia es la fase que ve la tabla en cada muestra:
Con palabra constante ese error no es ruido: es un diente de sierra periódico. Multiplicado por la portadora, cada armónico suyo pone un par de líneas a los costados del tono, las espurias, y la mayor mide respecto del tono: dB, seis decibeles por bit, como en un conversor. Medido con el ejemplo de Rice —acumulador de 28 bits, , FFT de 1500 puntos para que el tono caiga justo en un bin, tabla sin redondear los valores—:
| W | espuria mayor | −6,02W | dónde, en f/fs |
|---|---|---|---|
| 6 | −35,99 dB | −36,12 dB | −0,386 |
| 8 | −48,13 dB | −48,16 dB | 0,390 |
| 10 | −60,20 dB | −60,21 dB | 0,494 |
| 12 | −72,25 dB | −72,25 dB | −0,090 |
| 14 | −84,29 dB | −84,29 dB | −0,426 |
La fila de 8 bits es la figura del libro: −48 dB en 0,39 ciclos por muestra. La regla sale de tratar el error de fase como un ángulo chico; con 6 bits la medida queda 0,13 dB arriba de ella, y desde 10 bits coinciden a la centésima.
Lo que el truncamiento no toca es la frecuencia. La pendiente de la fase de la salida truncada difiere de en 3,5·10⁻⁸ ciclos por muestra o menos en las cinco filas. Si la frecuencia hubiera caído a la grilla de una tabla de 8 bits, el error sería el de pasar de 0,022 a 6/256: 1,4·10⁻³, cuarenta mil veces más. Truncar dentro del lazo del acumulador, sumando con bits, sí daría ese error, y para siempre.
En el script de clase la ganancia de lazo abierto es el filtro por el NCO:
Dos polos en , uno de cada bloque: MATLAB devuelve 1 1. Un lazo con dos integradores es de tipo 2, y eso es lo que le permite seguir una rampa de fase —un corrimiento de frecuencia— con error de fase cero. El primer integrador lo pone el oscilador sin que nadie lo pida; el filtro pone el segundo. Sin el del NCO, el PI solo daría un lazo de tipo 1.
Medido con las constantes de la clase (, ) y una rampa de 10⁻³ rad por muestra, al cabo de 20 000 muestras: con el PI el error de fase es 8,0·10⁻¹² rad; con sólo la rama proporcional, el lazo tiene un integrador nada más —el del NCO— y se queda en 0,2000 rad, que es exactamente . Ese error es el que hace falta para que la rama proporcional sostenga el control constante que pide la sección 03. Por qué la tabla de filtros de la filmina sale así, y qué hacen y , está en el filtro de lazo.
Un NCO armado a mano contra la frecuencia ideal, el desborde, el truncamiento y el NCO dentro del lazo del script phase_system.m. Lo que figura como comentario es la salida real de correrlo en R2026a.
%% 1. El NCO del script de clase: un acumulador fs = 16e9; Ts = 1/fs; z = tf('z', Ts); NCO = z/(z-1); disp(pole(NCO).') % 1 c = [0 0 1 1 1 1 0 0 0 0]; % un pulso de control de 4 muestras fase = lsim(NCO, c, (0:9)*Ts).'; disp(fase) % 0 0 1 2 3 4 4 4 4 4 %% 2. Un control constante es una rampa de fase fase = lsim(NCO, 0.01*ones(1, 6), (0:5)*Ts).'; disp(fase) % 0.0100 0.0200 0.0300 0.0400 0.0500 0.0600 %% 3. La resolución del acumulador de N bits: fs/2^N for N = [8 16 24 32] fprintf('N = %2d: resolución %.6g Hz\n', N, fs/2^N) end % N = 8: resolución 6.25e+07 Hz % N = 16: resolución 244141 Hz % N = 24: resolución 953.674 Hz % N = 32: resolución 3.72529 Hz %% 4. Un NCO de 24 bits, a mano N = 24; f_pedida = 1e9 + 1234; % Hz u = round(f_pedida*2^N/fs); % la palabra de control f_obtenida = u*fs/2^N; K = 2^16; r = zeros(1, K); for n = 2:K r(n) = mod(r(n-1) + u, 2^N); % sumar y tirar el acarreo end y = exp(1j*2*pi*r/2^N); % la tabla, sin truncar p = polyfit(0:K-1, unwrap(angle(y)), 1); f_medida = p(1)/(2*pi)*fs; fprintf('u = %d\n', u) fprintf('pedida %.4f Hz, obtenida %.4f Hz, error %.4f Hz\n', f_pedida, f_obtenida, f_pedida - f_obtenida) fprintf('medida desde la salida: %.4f Hz\n', f_medida) fprintf('desbordes en %d sumas: %d (u*(K-1)/2^N = %.3f)\n', K-1, sum(diff(r) < 0), u*(K-1)/2^N) % u = 1048577 % pedida 1000001234.0000 Hz, obtenida 1000000953.6743 Hz, error 280.3257 Hz % medida desde la salida: 1000000953.6743 Hz % desbordes en 65535 sumas: 4095 (u*(K-1)/2^N = 4095.941) %% 5. Los enteros de MATLAB no desbordan: saturan disp(int8(127) + int8(1)) % 127 disp(mod(127 + 1 + 128, 256) - 128) % lo que hace un sumador de 8 bits % -128 %% 6. Truncar la fase antes de la tabla: espurias N = 28; K = 1500; f0 = 11/500; % el ejemplo de Rice u = round(f0*2^N); r = mod((0:K-1)*u, 2^N); for W = 6:2:14 tabla = exp(1j*2*pi*(0:2^W-1)/2^W); y = tabla(floor(r/2^(N-W)) + 1); % los N-W bits de abajo se tiran Y = abs(fft(y)); [tono, k0] = max(Y); Y(k0) = 0; [espuria, ke] = max(Y); fe = (ke-1)/K; if fe >= 0.5, fe = fe - 1; end p = polyfit(0:K-1, unwrap(angle(y)), 1); fprintf('W = %2d: espuria %7.2f dB (-6,02W = %7.2f) en %+.4f; error de frecuencia %.1e\n', ... W, 20*log10(espuria/tono), -6.0206*W, fe, p(1)/(2*pi) - u/2^N) end % W = 6: espuria -35.99 dB (-6,02W = -36.12) en -0.3860; error de frecuencia -3.5e-08 % W = 8: espuria -48.13 dB (-6,02W = -48.16) en +0.3900; error de frecuencia -1.0e-08 % W = 10: espuria -60.20 dB (-6,02W = -60.21) en +0.4940; error de frecuencia -4.1e-09 % W = 12: espuria -72.25 dB (-6,02W = -72.25) en -0.0900; error de frecuencia -2.1e-09 % W = 14: espuria -84.29 dB (-6,02W = -84.29) en -0.4260; error de frecuencia 1.1e-10 %% 7. En el lazo: el NCO es el segundo integrador Kp = 0.005; Ki = Kp/100; G = (Kp + Ki*z/(z-1))*NCO; disp(pole(minreal(G)).') % 1 1 n = 0:19999; th = 1e-3*n; % rampa de fase: 1e-3 rad/muestra fi = lsim(feedback(G, 1), th, n*Ts); fprintf('PI + NCO: error final %.1e rad\n', th(end) - fi(end)) fi = lsim(feedback(Kp*NCO, 1), th, n*Ts); fprintf('P + NCO: error final %.4f rad\n', th(end) - fi(end)) for Lat = [0 1] s = stepinfo(feedback(G, z^-Lat)); fprintf('Lat = %d: sobrepico %.2f %%\n', Lat, s.Overshoot) end % PI + NCO: error final 8.0e-12 rad % P + NCO: error final 0.2000 rad % Lat = 0: sobrepico 39.72 % % Lat = 1: sobrepico 40.14 %
Cuatro detalles que muerden si no se los conoce:
int8(127) + int8(1) da 127, no -128: MATLAB no reproduce el desborde de un sumador. El módulo hay que escribirlo, con mod sobre enteros guardados en double —exactos hasta 2⁵³, sobra para 32 bits— o con fi y 'OverflowAction','Wrap' si está el toolbox de punto fijo.NCO del script no tiene retardo. z/(z-1) suma el control de la muestra actual: el pulso del bloque 1 se ve en la fase en la misma muestra en que entra. El DDS de Rice tiene un más, que es Lat = 1.unwrap necesita que la fase avance menos de π por muestra. Para medir la frecuencia de un NCO que pasa de el ajuste da la frecuencia reflejada, que es lo que el muestreo deja ver.NCO = z/(z-1) en el script; el de Rice tiene un más.