Podrías intentar agregar el mismo retraso a ambas salidas. El truco es introducir una lógica que no pueda optimizarse, pero agrega un retraso de LUT.
Probablemente esté familiarizado con el uso de puertas EXOR para invertir condicionalmente una señal.
Yo 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. p.ej. un registro en el que puede escribir un uno o cero. Nunca harás eso, pero las herramientas de síntesis no lo saben, así que tiene que mantener la puerta EXOR. No puede optimizarlo.
Ayer traté de evitar que la lógica fuera optimizada usando varias restricciones de Xilinx pero falló. Al final, utilicé el método de trabajo seguro que describí anteriormente, pero utilicé un pin de entrada para hacer que la LUT no inversora no se optimice:
//
// 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 place & ruta: