FPGA, VHDL & Co.
›
Thread
Verilog: Path
T
Tom
Gast
01.08.2012 08:47
#2776896
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
C
cfgardiner
Gast
01.08.2012 12:42
#2777151
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.
T
Tom
Gast
01.08.2012 14:11
#2777243
Hallo -
Danke für die Antwort.
Irgendwie scheint er an dieser Position kein else zu vertragen..
zumindest meckert der Compiler da..
C
cfgardiner
Gast
01.08.2012 15:51
#2777379
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.
Noch kein Account?
Die Registrierung ist kostenlos und dauert nur eine Minute.
Jetzt registrieren