Gitter-FPGA-Probleme mit eingebautem DELAY-Modul

Ich versuche, Eingangsdaten, die von der ADC-Komponente in DDR kommen, zu meinem FPGA zu verzögern und sie anschließend in der steigenden Taktflanke auszugeben. Der ADC, den ich verwende: ADS5463:Geben Sie hier die Bildbeschreibung ein

Ich verwende Lattice ECP3 FPGA, basierend auf dem FPGA-Datenblatt hat dieses FPGA ein eingebautes Verzögerungsmodul namens DELAYB:

Geben Sie hier die Bildbeschreibung ein

Der Grund, warum ich versuche, die Eingänge zu verzögern, besteht darin, die Setup-Zeit und die Haltezeit zu maximieren, wie es der ADS5463 empfiehlt.

Mein Code für den Versuch, dieses Verzögerungsmodul zu verwenden und die verzögerten Daten im steigenden Flankentakt auszugeben:

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   

Wenn ich versuche, diesen Code zu synthetisieren, erhalte ich diese Fehlermeldung von Diamond Lattice:

FEHLER – Die dynamische Verzögerungszelle „genblk1[0].delay“ kann die Komponente „negedge_data[0]“ nicht ansteuern.

FEHLER – Die dynamische Verzögerungszelle „genblk1[11].delay“ kann die Komponente „negedge_data[11]“ nicht ansteuern.

FEHLER – Die dynamische Verzögerungszelle „genblk1[10].delay“ kann die Komponente „negedge_data[10]“ nicht ansteuern.

FEHLER – Die dynamische Verzögerungszelle „genblk1[9].delay“ kann die Komponente „negedge_data[9]“ nicht ansteuern.

FEHLER – Die dynamische Verzögerungszelle „genblk1[8].delay“ kann die Komponente „negedge_data[8]“ nicht ansteuern.

FEHLER – Die dynamische Verzögerungszelle „genblk1[7].delay“ kann die Komponente „negedge_data[7]“ nicht ansteuern.

FEHLER – Die dynamische Verzögerungszelle „genblk1[6].delay“ kann die Komponente „negedge_data[6]“ nicht ansteuern.

FEHLER – Die dynamische Verzögerungszelle „genblk1[5].delay“ kann die Komponente „negedge_data[5]“ nicht ansteuern.

FEHLER – Die dynamische Verzögerungszelle „genblk1[4].delay“ kann die Komponente „negedge_data[4]“ nicht ansteuern.

FEHLER – Die dynamische Verzögerungszelle „genblk1[3].delay“ kann die Komponente „negedge_data[3]“ nicht ansteuern.

FEHLER – Die dynamische Verzögerungszelle „genblk1 2 .delay“ kann die Komponente „negedge_data 2 “ nicht ansteuern.

FEHLER – Die dynamische Verzögerungszelle „genblk1 1 .delay“ kann die Komponente „negedge_data 1 “ nicht ansteuern.

INFO - Fehler im Design des Benutzers gefunden. Ausgabedateien nicht geschrieben. Überprüfen Sie den Kartenbericht für weitere Details.

Kann mir bitte jemand helfen, zu sehen, was passiert? Ich habe Ref-Design, das diese Komponenten verwendet und dort funktioniert es gut, was ist falsch?

Nach dem Rakend-Kommentar bearbeiten:

OK, nachdem IFS1P3IX-Instanzen zu den Ausgangsregistern des DELAYB-Moduls hinzugefügt wurden, wie in der Referenz empfohlen. Es hat die oben genannten Fehler behoben, aber jetzt ist mein Design, das die data_inputs in den High-Z-Modus versetzt, es funktioniert immer noch nicht, das Design besteht die Synthesen, gibt mir aber diese Warnung, wodurch das Design jetzt funktioniert.

der neue Code:

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   

die kritische Warnung Diamond Drop auf mich:

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.

Irgendeine Idee, warum es passiert?

1) Die Verzögerungsmodule werden normalerweise nicht von Hand instanziiert, sondern sind Teil des automatischen DDR-Instanziierungsprozesses über IPExpress. 2) Im Laufe Ihrer Fragen habe ich das Gefühl, dass Sie versuchen, eine DDR-Schnittstelle "per Hand" zu implementieren. Der beabsichtigte Weg ist hier beschrieben: latticesemi.com/~/media/LatticeSemi/Documents/ApplicationNotes/… - suchen Sie nach ddr generisch.
@ChristianB. danke für den Kommentar. Ich kenne dieses PDF, ich habe versucht, Generic DDR mit LVDS-Eingängen zu erstellen, und als es erstellt wurde, wurde es zu meinem Top-Modul des Projekts, ohne Erfolg, eine andere Datei als Top-Modul zuzuweisen. Soll ich es als Top-Modul behalten und die FPGA-Pins den Signalen zuweisen, die diese IP erzeugt? Ich habe erstellt: "GDDRX1_RX.SCLK.Aligned"
Ich habe versucht, die Verzögerungsinstanzen auch für eine Verzögerungsleitung (ab)zuverwenden, aber es stellt sich heraus, dass Lattice Diamond/Technology Lib ziemlich starr ist, wenn es um Einschränkungen geht. Haben Sie es also geschafft, die von IPExpress generierte DDR inzwischen zu verwenden? Manchmal muss man das Hauptmodul manuell über die Projekteinstellungen ändern.
@ChristianB. Danke für die Mühe und die Sorge Mann. Ich habe auch verstanden, dass die manuelle Verwendung dieser Gittermodule nur große Kopfschmerzen bereitet. Ich hatte Erfolg mit dem IPexpress, ich habe die Datei für diese Schnittstelle generiert und sie ein wenig geändert und in ein anderes Projekt kopiert und auf diese Weise das Problem gelöst, dass sie zum Top-Modul wurde. Morgen will ich es nochmal versuchen und ohne Tricks ein neues Projekt mit dem IPexpress öffnen. Ich denke, das Problem liegt vielleicht daran, dass ich LVDS-Eingänge für die Schnittstelle wähle, also muss es ein Top-Modul sein? was Sie denken?
Trotzdem werde ich es morgen versuchen und eine neue Frage öffnen, wenn ich ein anderes Problem hatte.
Das Problem ist, dass der Gitterdiamant "annimmt", dass ein Modul, das nicht instanziiert ist, wahrscheinlich ein Top-Modul ist. Dies ist bei allen gerade erstellten Modulen der Fall. Man kann das oberste Modul manuell ändern: Wählen Sie in der Baumansicht auf der linken Seite die Registerkarte "Dateiliste". Die aktive Implementierung sollte hervorgehoben werden. Klicken Sie mit der rechten Maustaste darauf und wählen Sie "Einheit der obersten Ebene festlegen".
@ChristianB. ok danke.. Ich habe dieses Problem bereits überwunden. Ich habe eine andere Frage gestellt, ich freue mich, wenn Sie einen Blick darauf werfen: electronic.stackexchange.com/questions/483503/…

Antworten (1)

Aufgrund des Fehlers und der Beschreibung „Data goes to DDR registers“ können die DELAYB-Module nur vor dem PIO-Register verwendet werden. Dies ist möglicherweise nicht in der Lage, die anderen Register anzusteuern.

Dieses Beispiel zeigt auch, dass das DELAYB-Treiber-IO-Register.

Bearbeitet:

Eine weitere Überprüfung im FPGA-Referenzleitfaden zeigt:

Der DELAYB-Block kann auch verwendet werden, um Nicht-DDR-Eingänge zu verzögern, die das Eingangs-PIO-Register verwenden.

Dies bedeutet, dass der DELAYB-Block für DDR- (wahrscheinlich die IDDR- und ODDR-Komponenten) und PIO-Register verwendet werden kann.

Jeder PIO enthält einen SysIO-Puffer und E/A-Logik (IOLOGIC). Die E/A-Logik umfasst Eingangs-, Ausgangs- und Tri-State-Register, die sowohl Anwendungen mit einfacher Datenrate (SDR) als auch Anwendungen mit doppelter Datenrate (DDR) zusammen mit der erforderlichen Takt- und Datenauswahllogik implementieren.

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

@Rakned Danke! Es hat bei den Fehlern geholfen, aber jetzt stehe ich vor einer neuen Warnung, die dazu führt, dass das Design nicht funktioniert. Können Sie sich den bearbeiteten Beitrag ansehen?
@MichaelAstahov Möglicherweise stimmt etwas mit den Verbindungen nicht oder das Zurücksetzen hat dazu geführt, dass das Tool die Signale optimiert hat. Aber ich glaube, es ist besser, es als eine andere Frage zu stellen, da es möglicherweise nicht am DELAYB-Modul liegt und einige andere Personen helfen können. Und was ist mit den ADC-Codes passiert? Ich hoffe, es ist kein xy-Problem
ok, ich nehme deinen Rat an und öffne eine andere Frage. Ich habe vorerst den ADC-Code kommentiert (der 3-alwyas-Block, der steigende/fallende verzögerte Daten in das Ausgangsregister einfügt), da ich vorerst nur sehen möchte, dass das DELAY-Modul funktioniert und die Daten in das 'data_input_delay'-Register überträgt.
@MichaelAstahov, warum versuchen Sie nicht, IDDR zum Zwischenspeichern von ADC-Daten zu verwenden, anstatt normale Flip-Flops zu verwenden? Das machen wir normalerweise.
ok danke, ich hatte Probleme damit, aber ich überwinde sie jetzt im zweiten Versuch, wenn ich das generische DDR-Gitter in IPexpress verwende. Ich habe also einige gültige Daten, mit denen ich jetzt arbeiten kann. Trotzdem ist es immer noch interessant, warum es nicht manuell funktioniert :(