Hallo, anbei stelle ich mal den fertigen VHDL Code für einen XC9572 zur Kontrolle. Es ist mein Erstlingswerk in Sachen CPLD & VHDL. Der Code stellt eine 1:1 Hardwarenachbildung eines Bildwiederholspeichers dar und funktioniert auch in der realen Schaltung, aber ich möchte 1. wissen, wo die Profis etwas anders/besser machen würden... und 2. hab ich beim Testen einige Erfahrungen gemacht die mir unerklärlich sind und die ich gern mal am realen Code erläutert haben möchte. Die konkreten Fragen formuliere ich in einem weiteren Beitrag. Danke Euch allen die mal drüber schauen :-)
Ich würde versuchen: 1. weniger Takte zu nehmen (ok ist ein CPLD, da muß man u.U. etwas tricksen) 2. daraus folgen auch weniger Prozesse (damit gewinnt die Übersichtlichkeit) 3. bessere Bezeichner (weißt Du in zwei Wochen noch, was QD43_44_20 macht?) 4. ieee.numeric_std.all statt dem Synopsis-Quatsch und last but not last 5. ein Testbench zum Simulieren dazuzupacken. Duke
> 1. weniger Takte zu nehmen (ok ist ein CPLD, da muß man u.U. etwas > tricksen) Wie soll ich das tun ??? die Takte sind doch nötig um das Bild zu zeichnen. > 2. daraus folgen auch weniger Prozesse (damit gewinnt die > Übersichtlichkeit) Nun ich hab das schön extra immer gemacht und finde es so ansich schön übersichtlich, denn jeder Prozess stellt eine eigene Baugruppe dar. > 3. bessere Bezeichner (weißt Du in zwei Wochen noch, was QD43_44_20 > macht?) Ja ich weiß das später noch ganz genau, weil ich ja reale Hardware nachgebildet habe und eben genau die IC Bezeichnungen verwendet habe ! > 4. ieee.numeric_std.all statt dem Synopsis-Quatsch und last but not last Hm.. was soll das ändern ? bzw. verbessern ? > 5. ein Testbench zum Simulieren dazuzupacken. Ok hier ist sie... Gruß Ralph
Ralph H. schrieb: >> 4. ieee.numeric_std.all statt dem Synopsis-Quatsch und last but not last > Hm.. was soll das ändern ? bzw. verbessern ? Das wird definiert
1 | use IEEE.STD_LOGIC_unsigned.ALL; --nötig für die Zähler ! |
Wehe, da kopiert mal einer (und sei es du selber) einen Codeabschnitt aus deiner Datei und kopiert die irgendwohin, wo oben steht:
1 | use IEEE.STD_LOGIC_signed.ALL; --nötig für die Zähler ! |
Wie werden dann Vergleiche interpretiert? Sowas kann dir mit der numeric_std nicht passieren, denn da haben die Signale definierte Typen signed oder unsigned >> 5. ein Testbench zum Simulieren dazuzupacken. > Ok hier ist sie... :-)
> Sowas kann dir mit der numeric_std nicht passieren, denn da haben die > Signale definierte Typen signed oder unsigned OK aber dann funktionieren die Zähler nicht mehr so schön einfach. :-(
Ralph H. schrieb: > OK aber dann funktionieren die Zähler nicht mehr so schön einfach. :-( Doch:
1 | signal QD43_44_20 : UNSIGNED (8 downto 0) := (others => '0'); -- Ausgang D43,D44,D20 Zähler |
2 | :
|
3 | if rising_edge(TaktD43) then QD43_44_20 <= QD43_44_20 + 1 ; end if ; --zählen.. |
4 | if QD43_44_20 = 320 then QD43_44_20 <= "000000000" ; end if ; --max. bis 320 |
Nur das ändert sich: STD_LOGIC_VECTOR --> UNSIGNED Und da im Beitrag "Re: 32Bit Zähler zählt nur bis 255." ist auch noch ein Tipp..
OK Danke Lothar, aber wenn ich dann den Wert QD43_44_20 ausgeben will z.B. durch Ausgang <= QD43_44_20 ; dann hab ich doch versch. Datentypen oder ? Ausgang wäre ja STD_LOGIC_VECTOR ..
Da hilft ein Cast weiter: std_vektor <= std_logic_vector(QD43_44_20); Die Übergänge von integer via signed/unsigned nach std_logic habe ich mir da mal aufgemalt: http://www.lothar-miller.de/s9y/archives/14-Numeric_Std.html Das ist letzlich wesentlich durchschaubarer als die Synopsys-Libs mit ihren conv_... Funktionen.
Ralph H. schrieb: > OK Danke Lothar, aber wenn ich dann den Wert QD43_44_20 ausgeben will > z.B. durch Ausgang <= QD43_44_20 ; dann hab ich doch versch. Datentypen > oder ? > Ausgang wäre ja STD_LOGIC_VECTOR .. Richtig. Dort darfst Du casten
1 | Ausgang <= std_logic_vector(QD43_44_20); |
Würde ich aber nur machen, wenn aus dem Chip rausgeht. Sonst den Typ beibehalten, das schafft gleich Klarheit im übergeordneten Modul... Duke
OK das werd ich dann heute abend mal ausprobieren. Aber nochmal für mein Verständnis... diese Änderung es ist nur nötig, damit ich mich später mal nicht wundere, wenn ich Codeschnipsel hiervon verwende, weil die falsche Biliothek (..unsiged) benutzt wurde.
Ralph H. schrieb: > diese Änderung es ist nur nötig, damit ich mich später > mal nicht wundere, wenn ich Codeschnipsel hiervon verwende, weil die > falsche Biliothek (..unsiged) benutzt wurde. Ja. Und um die genormte numeric_std verwenden zu können... ;-)
@Lothar und Duke... Ich hab das nun geändert und mir gemerkt in Zukunft so zu verwenden. Gibt es noch Verbesserungen ? Wenn nein dann mal meine 1.Frage.. Beim Betrachten des Zählerstandes von QD19 in der Testbench ist mir aufgefallen, das der Zählerstand 6 für eine halbe Taktperiode eingenommen wird, obwohl es 0 sein müsste. Dafür ist der Zählerstand 0 auch nur ne halbe Taktperiode lang. Ich hab mir da mal nur den Zähler QD19 in einer extra Architecture mit Testbench unter die Lupe genommen. Dort ist das Verhalten nicht zu sehen. Habt ihr ne Erklärung dafür ?
1 | D19: |
2 | process(VDCLK) -- Basis ist VDCLK Takt der durch 6 geteilt wird |
3 | begin
|
4 | if rising_edge(VDCLK) then QD19 <= QD19 + 1 ; end if ;--zählen.. |
5 | if QD19 = 6 then QD19 <= "000" ; end if ;--max. bis 6 |
6 | end process D19; |
Wird da die erste if-Schleife nicht einfach zu früh beendet, so dass das Rücksetzen letztendlich asynchron verläuft? In der Simulation wird QD19 auch nicht von der Sensitivitätsliste erfasst und zudem erst, nachdem der Zähler den Wert 6 angenommen hat, zurücgesetzt?
Eigentlich sollte da am Ende kein ? sondern ein ! stehen :) Durch das process(VDCLK) wird der process auch bei der fallenden Flanke aktiviert, wodurch er genau eine halbe Taktperiode noch bei 6 steht.
Annexe schrieb: > if-Schleife Siehe http://www.if-schleife.de Annexe schrieb: > Durch das process(VDCLK) wird der process auch bei der fallenden Flanke > aktiviert, wodurch er genau eine halbe Taktperiode noch bei 6 steht. Allerdings nur in der Simulation. In der Hardware wird das tatsächlich (wie vermutet) als asynchroner kombinatorischer Reset ausgeführt werden...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.