Para el diseño HDL que estoy desarrollando actualmente para un SoC zynq, necesito invertir una señal de reloj debido a un par diferencial intercambiado a nivel de placa.
El uso de "NOT" para invertir agrega una LUT en la ruta y, como tal, introduce un sesgo de al menos 500ps entre el invertido y el original (que también se coloca en otra salida diferencial. Y esto es demasiado en nuestro caso).
¿Hay alguna manera de invertir una señal de reloj para que el sesgo entre el original y la copia invertida sea mínimo?
Encontré una posible solución utilizando la primitiva ODDR, pero esto parece más una solución temporal que una solución.
Gracias de antemano.
Con los dispositivos Xilinx, usar un ODDR es en realidad la forma recomendada de generar una señal de reloj en un pin, especialmente si tiene restricciones de tiempo estrictas. Haga esto para ambos clk
y clk180
, y ambos tendrán el mismo tiempo repetible. No es una solución en absoluto.
Vea el comentario en el foro de Xilinx aquí por un ingeniero de Xilinx:
ODDR mantiene el ciclo de trabajo y proporciona la mejor ruta posible. Sin enrutamiento de reloj en ninguna interconexión, el reloj permanece en los recursos de reloj global a los que pertenecen.
También se menciona en la guía del usuario de Xilinx 7-Series Select IO , página 128, sección "Recursos OLÓGICOS" > "Reenvío de reloj":
Salida DDR puede reenviar una copia del reloj a la salida. Esto es útil para propagar un reloj y datos DDR con retrasos idénticos y para la generación de múltiples relojes.
Puede jugar con el equilibrio de los retrasos de LUT con otros LUT, ODELAY y restricciones, pero esto no se acercará a la simplicidad o la previsibilidad de tiempo del método ODDR.
Podría intentar agregar el mismo retraso a ambas salidas. El truco es introducir una lógica que no se pueda optimizar pero que agregue un retraso de LUT.
Probablemente esté familiarizado con el uso de puertas EXOR para invertir condicionalmente una señal.
Agregaría una función EXOR a ambos puertos de salida. La señal de "control" de un EXOR es alta y la otra no. La señal de control en cada puerta EXOR debe ser tal que pueda cambiar. por ejemplo, un registro en el que puede escribir un uno o un cero. Nunca harás eso, pero las herramientas de síntesis no lo saben, por lo que debe mantener la puerta EXOR. No puede optimizarlo.
Ayer traté de evitar que la lógica se optimizara utilizando varias restricciones de Xilinx, pero fallé. Al final, utilicé el método de trabajo seguro que describí anteriormente, pero usé un pin de entrada para hacer que la LUT no inversora no esté optimizada:
//
// Same delay path for o1 and o2
// where o2 = ~o1
//
module keep (
input clk,
input reset_n,
input never_changes, // Always low
output o1,o2
);
reg [1:0] count;
// Some (arbitrary) test registers
always @(posedge clk or negedge reset_n)
begin
if (!reset_n)
count <= 2'b0;
else
count <= count + 2'b01;
end
/*
This did not work:
XOR2 X1(.I0(count[1]),.I1(1'b0),.O(o1));
// synthesis attribute optimize of X1 is off
XOR2 X2(.I0(count[1]),.I1(1'b1),.O(o2));
// synthesis attribute optimize of X2 is off
*/
// This can't fail: Note that never_changes should be low
assign o1 = never_changes ^ count[1];
assign o2 = ~count[1];
endmodule
Este es el resultado de las salidas después de lugar y ruta:
keep
, not optimize
.
DonFusili
Spehro Pefhany
Tomás
Tomás
DonFusili
cal-linux