Verilog: Path

Gast #2776896
Lesenswert?

Hallo,
folgendes Problem: ich habe ein Verilog Model eines DFF mit clear.

`timescale 1ns/1ps
`celldefine
`suppress_faults
`enable_portfaults
module DFFCLR (Q, QN, CK, D, RN);
output Q, QN;
input  D, CK, RN;
reg NOTIFIER;
supply1 xSN;

  buf     XX0 (xRN, RN);
  buf     IC (clk, CK);
  udp_dff I0 (n0, D, clk, xRN, xSN, NOTIFIER);
  and     I4 (flag, xRN, xSN);
  buf     I1 (Q, n0);
  not     I2 (QN, n0);

  specify
    specparam
    tplh$RN$Q  = 1.0,
    tphl$RN$Q  = 1.0,
    tplh$RN$QN  = 1.0,
    tphl$RN$QN  = 1.0,
    tplh$CK$Q  = 1.0,
    tphl$CK$Q  = 1.0,
    tplh$CK$QN  = 1.0,
    tphl$CK$QN  = 1.0,
    tsetup$D$CK  = 1.0,
    thold$D$CK  = 0.5,
    trec$RN    = 1.0,
    trem$RN    = 0.5,
    tminpwl$RN     = 1.0,
    tminpwl$CK    = 1.0,
    tminpwh$CK    = 1.0;


    if (flag)
      (posedge CK *> (Q    +: D)) = (tplh$CK$Q,    tphl$CK$Q);
    if (flag)
      (posedge CK *> (QN   -: D)) = (tplh$CK$QN,   tphl$CK$QN);
    $setuphold(posedge CK &&& (flag == 1), posedge D, tsetup$D$CK, 
thold$D$CK, NOTIFIER);
    $setuphold(posedge CK &&& (flag == 1), negedge D, tsetup$D$CK, 
thold$D$CK, NOTIFIER);
      (negedge RN *>  (Q    +: 1'b0)) = (tphl$RN$Q);
      (negedge RN *>  (QN -: 1'b0)) = (tplh$RN$QN);
    $setuphold(posedge CK, posedge RN, trec$RN, trem$RN, NOTIFIER);
    $width(negedge RN, tminpwl$RN, 0, NOTIFIER);
    $width(negedge CK &&& (flag == 1), tminpwl$CK, 0, NOTIFIER);
    $width(posedge CK &&& (flag == 1), tminpwh$CK, 0, NOTIFIER);

   endspecify
endmodule //

Ich simuliere derzeit in Cadence Verilog-XL und möchte da die Option 
Path Delay simulieren.
Allerdings bekomme ich folgenden Fehler:

Error!    Multiple path delays defined to node
          Q ; Path delay
          outputs must have only one driver within the
          module


Sobald ich allerdings alles zwischen specify und endspecify lösche, sind 
die Fehler weg.. allerdings auch das timing futsch.

Da ich kein Verilog-Schreiber, sondern lediglich ein Nutzer von 
Standardzellen bin - hat irgendjemand was komisches in der Zelle 
gesehen?

Danke, Grüße,
Thomas
Gast #2777151
Lesenswert?

Tom,

nun ich würde mich auch nicht unbedingt als verilog Guru bezeichnen, 
aber ich vermute es liegt an den Zeilen:

    if (flag)
      (posedge CK *> (Q    +: D)) = (tplh$CK$Q,    tphl$CK$Q);

sowie
      (negedge RN *>  (Q    +: 1'b0)) = (tphl$RN$Q);

und die entsprechende Zeilen für QN natürlich.

flag wird wie folgt definiert
  and     I4 (flag, xRN, xSN);

und heisst wohl wenn xRN und xSN beide HI sind, dann wird der Clock 
berücksichtigt. Die (negedge... Zeile oben scheint immer zu greifen. Als 
erstes würde ich versuchen den (negedge... in einem else Teil zum 'if 
(flag)' zu verschieben.

Dieses else Teil ist somit immer aktiv wenn entweder xRN oder xSN Low 
sind. Ich gehe davon aus, dass diese die asynchrone Setz/Rücksetz 
Eingänge and aktiv LOW sind.
Gast #2777379
Lesenswert?

Hallo Tom,

geht folgendes nicht? Wie gesagt ich bin hier leider kein Guru?

    if (flag)
      (posedge CK *> (Q    +: D)) = (tplh$CK$Q,    tphl$CK$Q);
    else
      (negedge RN *>  (Q    +: 1'b0)) = (tphl$RN$Q);

    if (flag)
      (posedge CK *> (QN   -: D)) = (tplh$CK$QN,   tphl$CK$QN);
    else
      negedge RN *>  (QN -: 1'b0)) = (tplh$RN$QN);

    $setuphold(posedge CK &&& (flag == 1), posedge D, tsetup$D$CK,
thold$D$CK, NOTIFIER);
    $setuphold(posedge CK &&& (flag == 1), negedge D, tsetup$D$CK,
thold$D$CK, NOTIFIER);
    $setuphold(posedge CK, posedge RN, trec$RN, trem$RN, NOTIFIER);
    $width(negedge RN, tminpwl$RN, 0, NOTIFIER);
    $width(negedge CK &&& (flag == 1), tminpwl$CK, 0, NOTIFIER);
    $width(posedge CK &&& (flag == 1), tminpwh$CK, 0, NOTIFIER);

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren