im Anhang habe ich euch das Projekt angehängt um das es geht. ich bin
dabei eine Steuerung für mein bitseriellen Cordic zu implementieren
allerdings bekomme ich eine Warnung die ich einfach nicht beheben kann.
Zudem bin ich mir nicht wirklich sicher ob die Art und Weise wie ich
meine FSM beschreibe überhaupt in ordnung ist.
Mein Design orientiert sich an der traditionellen architektur mit 3
shiftregistern, einem rom und 3 1 bit Subb/Add rechenwerken.
der Ablauf wird mittels einer FSM geregelt die unter anderem auch das
Argument mit Y vergleicht und die SubADDSel leitung der addierer steuert
um zu entscheiden ob addiert oder subtrahiert werden soll.
Diesen Vergleich findet ihr ab Zeile 161 in der ich Die differenz
berechne und das erste bit als Sign bit verwendet und an die addierer
schicken.
genau an dieser Stelle kommt aber auch die folgende Warnung:
WARNING:HDLCompiler:871 -
"C:\Users\D3XT3ER-Eee\Desktop\srcV1.2_Final\seriaAdder\SerialAdder.vhd"
Line 66: Using initial value "0000000000000000" for serial_addersignal_z
since it is never assigned
WARNING:Xst:737 - Found 1-bit latch for signal <Cin>. Latches may be
generated from incomplete case or if statements. We do not recommend the
use of latches in FPGA/CPLD designs, as they may lead to timing
problems.
WARNING:Xst:3002 - This design contains one or more registers/latches
that are directly
incompatible with the Spartan6 architecture. The two primary causes
of this is
either a register or latch described with both an asynchronous set
and
asynchronous reset, or a register or latch described with an
asynchronous
set or reset which however has an initialization value of the
opposite
polarity (i.e. asynchronous reset with an initialization value of 1).
wenn ich jetzt allerdings Zeile 162, 163 oder 164 ausklammere, dann
verschwindet diese Warnung.
Weiss jemand Rat?
sergej schrieb:> Zeile 162, 163 oder 164
Welche sind das? Muss ich jetzt nachzählen?
> dann verschwindet diese Warnung.
Welche der drei angezeigten Warnungen ist "diese"?
Noch ein Wort zum Sonntag (und evtl. zum angemeckerten Cin-Latch):
1
Cin<='0'whenSubAddSell='0'else
2
'1'whenSubAddSell='1';
Dir ist klar, das std_logic eine NEUNwertige Logik ist? Du verwendest
zwei davon. Was passiert bei den anderen 7 Zuständen?
Und warum schreibst du nicht einfach sowas:
1
Cin<=SubAddSell;
BTW: diese Zuweisung ist hier sinnlos:
AngleOutput<= "ZZZZZZZZZZZZZZZZ";
Denn das Fehlen jeglicher Steuersignale legt nahe, dass da offenbar kein
Tristate-Bus nach aussen hin tätig ist...
Lothar Miller schrieb:> sergej schrieb:>> Zeile 162, 163 oder 164> Welche sind das? Muss ich jetzt nachzählen?
Hallo Lothar, entschuldige, ich habe damit gerechnet, dass du den Code
im Editor aufmachst um ihn dir anzusehen und könntest dann die
Zeilennummern sehen. es geht um die Anweisungen
>> dann verschwindet diese Warnung.> Welche der drei angezeigten Warnungen ist "diese"?>> Noch ein Wort zum Sonntag (und evtl. zum angemeckerten Cin-Latch):Cin> <= '0' when SubAddSell = '0' else> '1' when SubAddSell = '1';> Dir ist klar, das std_logic eine NEUNwertige Logik ist? Du verwendest> zwei davon. Was passiert bei den anderen 7 Zuständen?> Und warum schreibst du nicht einfach sowas:Cin <= SubAddSell;
Das ist mir im nachhinein auch aufgefallen, ich habe es geändert und nun
scheinen auch die warnungen:
WARNING:Xst:737 - Found 1-bit latch for signal <Cin>. Latches may be
generated from incomplete case or if statements. We do not recommend the
use of latches in FPGA/CPLD designs, as they may lead to timing
problems.
WARNING:Xst:3002 - This design contains one or more registers/latches
that are directly
incompatible with the Spartan6 architecture. The two primary causes
of this is
either a register or latch described with both an asynchronous set
and
asynchronous reset, or a register or latch described with an
asynchronous
set or reset which however has an initialization value of the
opposite
polarity (i.e. asynchronous reset with an initialization value of 1).
verschwunden zu sein.
Ich habe allerdings nun ein anderes Problem.
ich benötige bei jeder neuen Iteration den inhalt des RegistersY um ihn
mit dem übergebenen Argument zu vergleichen.
Den Inhalt hole ich mir im Moment so:
TempOutputY <= signed(OutputSignalY) when CurrentSTATE = NEWITERATION
and AddCounter = 0 else TempOutputY
das soll bedeuten, wenn der Addcounter = 0 ist soll er den Wert
übernehmen ansonsten seinen Wert beibehalten. JEtzt ist mir natürlich
klar, dass ich damit ein LAtch verursache aber anders bekomme ich es
einfach nicht gelöst. mit einem Process bekomme ich einen unnötigen
taktdelay.
Meine Konkrete frage ist jetzt, wie schaffe ich es einen Wert bei
Addcounter= 0 zu übernehmen und ihn ansonsten unverändert zu lassen?
sergej schrieb:> mit einem Process bekomme ich einen unnötigen taktdelay.
Deine Denkweise ist falsch. Es ist nicht der Prozess, der einen Takt
Latency bringt, es ist der Takt an sich, der die Latency bringt. Du
bekommst diese Latency auch dann, wenn du es so schreibst:
TempOutputY <= signed(OutputSignalY) when rising_edge(Serial_Adder_CLK)
and CurrentSTATE = NEWITERATION and AddCounter = 0;
> aber anders bekomme ich es einfach nicht gelöst.
Dein Problem ist, dass du das Schieberegister (das an sich ja schon
speichert) so tief in einer Komponente vergraben hast, dass du diese
Speicherfunktion nicht mehr nutzen kannst. Am einfachsten wäre es
nämlich, nur dann zu Schieben, wenn alle Bedingungen erfüllt sind.
Eine andere Möglichkeit ist, mit einem Flag nur die Gültigkeit des
Wertes zu signalisieren, und das Speichern (wenn nötig) einer
übergeordnetetn Instanz zu überlassen. Dann ist die nämlich dafür
verantwortlich, wenn Latency auftritt.
sergej schrieb:> Meine Konkrete frage ist jetzt, wie schaffe ich es einen Wert bei> Addcounter= 0 zu übernehmen und ihn ansonsten unverändert zu lassen?
Was heißt für dich "bei Addcounter= 0 zu übernehmen"?
Sobald ein Flipflop beteiligt ist, gibt es einen Eingang und einen Takt.
Und der FF Ausgang übernimmt den Pegel vom Eingang mit einer Flanke am
Takt. Du musst also an der Stelle, wo die Daten für den "nächsten Takt"
berechnet werden, diese Daten in das "Ausgabgeregister" übernehmen. Das
bedeutet eigentlich einfach, dass du "einen Takt vorausdenken" musst.
Lothar Miller schrieb:> Dein Problem ist, dass du das Schieberegister (das an sich ja schon> speichert) so tief in einer Komponente vergraben hast, dass du diese> Speicherfunktion nicht mehr nutzen kannst. Am einfachsten wäre es> nämlich, nur dann zu Schieben, wenn alle Bedingungen erfüllt sind.
Ja ich würde es auch nicht noch einmal machen wenn ich wüsste dass es
solche probleme gibt.
> Was heißt für dich "bei Addcounter= 0 zu übernehmen"?> Sobald ein Flipflop beteiligt ist, gibt es einen Eingang und einen Takt.> Und der FF Ausgang übernimmt den Pegel vom Eingang mit einer Flanke am> Takt. Du musst also an der Stelle, wo die Daten für den "nächsten Takt"> berechnet werden, diese Daten in das "Ausgabgeregister" übernehmen. Das> bedeutet eigentlich einfach, dass du "einen Takt vorausdenken" musst.
mit übernehmen meine ich, dass mein Signal TempOutputY den
Registerinhalt bei Addcounter = 0 zugewiesen bekommt. ich habe ja eine
Addition von 16 bit und dafür brauche ich ja auch 16 Takte. wenn ich
jetzt aber ein Takt Delay zulasse, dann komme ich auf 17 und das möchte
ich verhindern.
So wie es aussieht komme ich nicht daran vorbei das Schieberegister
entsprechend zu modifizieren.
erst schieben wenn alle bedingungen erfüllt sind, ergibt ja das selbe
problem wie mit dem Taktdelay. meine berechnung dauert dann länger als
nötig.
sergej schrieb:> erst schieben wenn alle bedingungen erfüllt sind, ergibt ja das selbe> problem wie mit dem Taktdelay. meine berechnung dauert dann länger als> nötig.
Nein. Das Signal zum Schieben kommt ja nicht überraschend irgendwann von
aussen. Du selber weißt ja schon, was als Nächstes kommt, denn du
selber löst den Vorgang ja aus. Und wenn du weißt, dass demnächst
geschoben werden wird, kannst du die Signale entsprechend vorbereiten.
Garantiert! Das Schieben an sich geht nur mit dem Takt und bringt
natürlich einen Takt "Verzögerung"...
> ich habe ja eine Addition von 16 bit und dafür brauche ich ja auch 16> Takte. wenn ich jetzt aber ein Takt Delay zulasse, dann komme ich auf 17> und das möchte ich verhindern.
Du klemmst dich hier selber ein: du musst nicht immer erst den einen
Zyklus fertig machen und erst dann den Nächsten anfangen. Du kannst mit
dem letzten Takt schon die Daten für den nächsten Zyklus an das
Schieberegister anlegen. Dann hast du, auch wenn du die Daten wie in
meinem Codeschnipsel einfach synchron übernimmst, bestenfalls im ersten
Durchlauf das Ergebnis einen Takt Latency. Aber ab dann bekommst du
jeden 16. Takt ein neues Ergebnis...
Lothar Miller schrieb:> Du klemmst dich hier selber ein: du musst nicht immer erst den einen> Zyklus fertig machen und erst dann den Nächsten anfangen. Du kannst mit> dem letzten Takt schon die Daten für den nächsten Zyklus an das> Schieberegister anlegen. Dann hast du, auch wenn du die Daten wie in> meinem Codeschnipsel einfach synchron übernimmst, bestenfalls im ersten> Durchlauf das Ergebnis einen Takt Latency. Aber ab dann bekommst du> jeden 16. Takt ein neues Ergebnis...
Ich verstehe glaube ich was du meinst aber wie ich das umsetzen muss
weiß ich nicht.
Ich weiß, dass mein Zyklus nach addcounter=15 zuende ist und ich beim
nächsten Takt das angelgte Signal benötigen werde. Aber wie beschreibe
ich es dass er Mir beim nächsten Takt das Signal anlegen soll?