Problemas de FPGA de celosía con el módulo DELAY incorporado

Estoy tratando de retrasar los datos de entrada provenientes del componente ADC en DDR a mi FPGA, luego enviarlos en el borde ascendente del reloj. El ADC estoy usando: ADS5463:ingrese la descripción de la imagen aquí

Estoy usando Lattice ECP3 FPGA, basado en la hoja de datos de fpga, este fpga tiene un módulo de retardo integrado llamado DELAYB:

ingrese la descripción de la imagen aquí

La razón por la que estoy tratando de retrasar las entradas es para maximizar el tiempo de configuración y el tiempo de espera como recomienda el ADS5463.

Mi código para tratar de usar este módulo de retraso y generar los datos retrasados ​​en el reloj de flanco ascendente:

module top(
    input rstn,
    input dry,               //DRY=fs/2 -> fs=300Mhz -> DRY=150MHz               
    input [11:0] data_input, 
    output clk2,
    output [11:0] data_output
    );

    wire clk2;
    wire rst;
    wire [11:0] data_input_delay;
    reg [11:0] posedge_data;
    reg [11:0] negedge_data;
    reg [23:0] data_output;


    assign rst = ~rstn;

    //divide clk. clk2=dry_i/2=75MHz.
    CLKDIVB div2 (
        .CLKI   (dry),
        .RST    (rst),
        .RELEASE(1'b1),
        .CDIV1  (),
        .CDIV2  (clk2),
        .CDIV4  (),
        .CDIV8  ()
        ); 

    //delay data => 35ps steps. 
    genvar i;
    generate 
        for (i = 0; i < 12; i = i + 1) begin
            DELAYB delay (
                .A(data_input[i]),
                .DEL0(1'b1),
                .DEL1(1'b1),
                .DEL2(1'b0),
                .DEL3(1'b0),
                .Z(data_input_delay[i])
                ); 
        end
    endgenerate


    always @(posedge dry, posedge rst)
    begin
        if (rst) begin
            posedge_data   <= 12'b100000000000;
        end else begin
            posedge_data   <= data_input_delay;
        end
    end

    always @(negedge dry, posedge rst)
    begin
        if (rst) begin
            negedge_data   <= 12'b100000000000;
        end else begin
            negedge_data   <= data_input_delay;
        end
    end 

    always @(posedge clk2, posedge rst)
    begin
        if (rst) begin
            data_output   <= 24'b100000000000100000000000;
        end else begin
            data_output  <= {posedge_data, negedge_data};
        end
    end 

endmodule   

Cuando intento sintetizar este código, recibo este mensaje de error de Diamond Lattice:

ERROR: la celda de retraso dinámico 'genblk1[0].delay' no puede controlar el componente 'negedge_data[0]'.

ERROR: la celda de retraso dinámico 'genblk1[11].delay' no puede controlar el componente 'negedge_data[11]'.

ERROR: la celda de retraso dinámico 'genblk1[10].delay' no puede controlar el componente 'negedge_data[10]'.

ERROR: la celda de retraso dinámico 'genblk1[9].delay' no puede controlar el componente 'negedge_data[9]'.

ERROR: la celda de retraso dinámico 'genblk1[8].delay' no puede controlar el componente 'negedge_data[8]'.

ERROR: la celda de retraso dinámico 'genblk1[7].delay' no puede controlar el componente 'negedge_data[7]'.

ERROR: la celda de retraso dinámico 'genblk1[6].delay' no puede controlar el componente 'negedge_data[6]'.

ERROR: la celda de retraso dinámico 'genblk1[5].delay' no puede controlar el componente 'negedge_data[5]'.

ERROR: la celda de retraso dinámico 'genblk1[4].delay' no puede controlar el componente 'negedge_data[4]'.

ERROR: la celda de retraso dinámico 'genblk1[3].delay' no puede controlar el componente 'negedge_data[3]'.

ERROR: la celda de retraso dinámico 'genblk1 2 .delay' no puede controlar el componente 'negedge_data 2 '.

ERROR: la celda de retraso dinámico 'genblk1 1 .delay' no puede controlar el componente 'negedge_data 1 '.

INFO - Errores encontrados en el diseño del usuario. Archivos de salida no escritos. Consulte el informe del mapa para obtener más detalles.

Alguien por favor me puede ayudar a ver mi eso que está sucediendo? Tengo un diseño de referencia que usa estos componentes y funciona bien, ¿qué pasa?

Editar después del comentario de Rakend:

bien después de agregar instancias IFS1P3IX a los registros de salida del módulo DELAYB como se recomienda en la referencia. Reparó los errores mencionados anteriormente, pero ahora mi diseño coloca las entradas de datos en modo High-Z, todavía no funciona, el diseño pasa las síntesis pero me da esta advertencia que hace que el diseño ahora funcione.

el nuevo código:

module top (rstn,dry,data_input,clk2,led_clk,led_rst,data_output);

    input rstn;
    input dry;               //DRY=fs/2 -> fs=300Mhz -> DRY=150MHz               
    input [11:0] data_input; 
    output wire clk2;
    output  led_clk;
    output reg  led_rst;
    output reg [23:0] data_output;

    wire rst;
    wire [11:0] data_input_temp;
    wire [11:0] data_input_delay;
    reg [25:0] adc_clk_count = 26'b0;


    assign rst = ~rstn;

    //divide clk. clk2=dry_i/2=75MHz.
    CLKDIVB div2 (
        .CLKI   (dry),
        .RST    (rst),
        .RELEASE(1'b1),
        .CDIV1  (),
        .CDIV2  (clk2),
        .CDIV4  (),
        .CDIV8  ()
        ); 

    genvar i;
    generate 
        for (i = 0; i < 12; i = i + 1) begin
            DELAYB delay (
                .A(data_input[i]),
                .DEL0(1'b1),
                .DEL1(1'b1),
                .DEL2(1'b0),
                .DEL3(1'b0),
                .Z(data_input_temp[i])
                ); 
        end
    endgenerate

    genvar j;
    generate 
        for (j = 0; j < 12; j = j + 1) begin
            IFS1P3IX data_reg (
                .Q(data_input_delay[j]),
                .SP(1'b1),
                .CD(rst),
                .SCLK(dry),
                .D(data_input_temp[j])
            ); 
        end
    endgenerate

endmodule   

la advertencia crítica Diamond drop on me:

2019991 WARNING - CL168 :"C:\----\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[11].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[10].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[9].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\----------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[8].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[7].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[6].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[5].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[4].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[3].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[2].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\---------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[1].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\---------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[0].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\-------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[11].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[10].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\----------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[9].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[8].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\---------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[7].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[6].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\---------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[5].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\---------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[4].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\----------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[3].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[2].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\----------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[1].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\-----------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[0].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.

2019993 WARNING - MT420 |Found inferred clock top|dry with period 5.00ns. Please declare a user-defined clock on port dry.
1166052 WARNING - logical net 'CDIV1' has no load.
1166052 WARNING - logical net 'CDIV4' has no load.
1166052 WARNING - logical net 'CDIV8' has no load.
1166052 WARNING - logical net 'data_input_c[0]' has no load.
1166052 WARNING - logical net 'data_input_c[1]' has no load.
1166052 WARNING - logical net 'data_input_c[2]' has no load.
1166052 WARNING - logical net 'data_input_c[3]' has no load.
1166052 WARNING - logical net 'data_input_c[4]' has no load.
1166052 WARNING - logical net 'data_input_c[5]' has no load.
1166052 WARNING - logical net 'data_input_c[6]' has no load.
1166052 WARNING - logical net 'data_input_c[7]' has no load.
1166052 WARNING - logical net 'data_input_c[8]' has no load.
1166052 WARNING - logical net 'data_input_c[9]' has no load.
1166052 WARNING - logical net 'data_input_c[10]' has no load.
1166052 WARNING - logical net 'data_input_c[11]' has no load.
1163101 WARNING - DRC complete with 15 warnings.
1100523 WARNING - C:/--------/ADC_Interface
51001030    WARNING - Using local reset signal 'rstn_c' to infer global GSR net.

¿Alguna idea de por qué sucede?

1) los módulos de retardo normalmente no se instancian a mano pero son parte del proceso automático de instanciación de DDR a través de IPExpress. 2) en el transcurso de sus preguntas, tengo la sensación de que intenta implementar una interfaz DDR "a mano". La forma prevista se describe aquí: latticesemi.com/~/media/LatticeSemi/Documents/ApplicationNotes/… - busque ddr genérico.
@ChristianB. gracias por el comentario. Estoy familiarizado con este PDF, traté de crear Generic DDR con entradas LVDS y cuando se creó se convirtió en mi módulo principal del proyecto sin ningún éxito para asignar ningún otro archivo como módulo principal. ¿Debo mantenerlo como módulo superior y asignar los pines FPGA a las señales que creó esta IP? Creé: "GDDRX1_RX.SCLK.Aligned"
Intenté (ab)utilizar las instancias de retardo también para una línea de retardo, pero resulta que la biblioteca de tecnología/diamante de celosía es bastante rígida cuando se trata de restricciones. Entonces, ¿lograste usar el DDR generado por IPExpress ahora? A veces, uno tiene que cambiar manualmente el módulo principal a través de la configuración del proyecto.
@ChristianB. Gracias por el esfuerzo y la preocupación hombre. También entendí que usar estos módulos de celosía manualmente es solo un gran dolor de cabeza. Tuve éxito usando IPexpress, generé el archivo para esta interfaz y lo cambié un poco y lo copié a otro proyecto y de esta manera superé el problema de que se convirtió en el módulo superior. Mañana quiero volver a intentarlo y abrir un nuevo proyecto usando IPexpress sin ningún truco. Creo que el problema puede deberse a que estoy eligiendo entradas LVDS para la interfaz, ¿así que tiene que ser el módulo superior? ¿qué piensas?
de todos modos, lo intentaré mañana y abriré una nueva pregunta si tuve otro problema.
El problema es que el diamante de celosía "asume" que un módulo que no está instanciado es probablemente un módulo superior. Este es el caso de cualquier módulo recién creado. Uno puede cambiar manualmente el módulo superior: en la vista de árbol a la izquierda, seleccione la pestaña "Lista de archivos". La implementación activa debe ser destacada. Haga clic derecho sobre él y seleccione "Establecer unidad de nivel superior".
@ChristianB. ok gracias.. ya supere este problema. Hice otra pregunta. Estaré encantado si echas un vistazo: electronics.stackexchange.com/questions/483503/…

Respuestas (1)

Según el error y la descripción "Datos que van a registros DDR", los módulos DELAYB solo se pueden usar antes del registro PIO. Es posible que esto no pueda controlar los otros registros.

Este ejemplo también muestra que el registro de E/S de conducción DELAYB.

Editado:

Verificación adicional en la guía de referencia FPGA muestra:

El bloque DELAYB también se puede usar para retrasar entradas que no sean DDR que usen el registro PIO de entrada.

Esto significa que el bloque DELAYB puede usarse para registros DDR (probablemente los componentes IDDR y ODDR) y PIO.

Cada PIO incluye un búfer sysIO y una lógica de E/S (IOLOGIC). La lógica de E/S incluye registros de entrada, salida y de tres estados que implementan aplicaciones de velocidad de datos única (SDR) y velocidad de datos doble (DDR) junto con la lógica de selección de datos y reloj necesaria.

Consulte http://www.latticesemi.com/en/Support/AnswerDatabase/1/9/4/1946

@Rakned ¡Gracias! me ayudó con los errores, pero ahora estoy enfrentando una nueva advertencia que hace que el diseño no funcione, ¿puedes mirar la publicación editada?
@MichaelAstahov Puede haber algún problema con las conexiones o el reinicio hizo que la herramienta optimizara las señales. Pero creo que es mejor plantearlo como una pregunta diferente, ya que puede que no se deba al módulo DELAYB y otras personas pueden ayudar. Además, ¿qué pasó con los códigos adc? espero que no sea un problema xy
Ok, tomaré tu consejo y abriré otra pregunta. Comenté por ahora el código ADC (el bloque de 3 alwyas que pone datos retrasados ​​ascendentes/descendentes en el registro de salida) porque por ahora todo lo que quiero ver es que el módulo DELAY funcione y transfiera los datos al registro 'data_input_delay'.
@MichaelAstahov, ¿por qué no intenta usar IDDR para bloquear los datos de ADC en lugar de usar chanclas normales? Esto es lo que solemos hacer.
ok, gracias, tuve problemas con eso, pero los superé ahora en el segundo intento cuando uso la red DDR genérica proporcionada en IPexpress. Así que tengo algunos datos válidos para trabajar ahora. De todos modos, sigue siendo interesante por qué no funciona manualmente :(