Forum: FPGA, VHDL & Co. Hardware mit VHDL "richtig" beschreiben.


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von Dimi (Gast)


Lesenswert?

Guten Tag an alle!!!

Ich brauche paar tipps zum Thema VHDL.
Mein Design funktioniert zwar, aber ich hatte viele Timing-Probleme (die 
ich
bereits schot gelöst habe).
Trotzdem mache ich mir immer noch gedanken um "richtigkeit" meines 
VHDL-Codes.
So sieht's bei mir aus...
1
PORT_CS <= '1' when cpu_IORQ = '0' and cpu_WR = '0' and cpu_A(15 downto 8) = "01110011" else '0';
2
3
process (clk25,reset)
4
begin
5
   if reset = '0' then
6
      RAM_Page <= "00";
7
      ROM_Page <= '0';
8
   elsif rising_edge(clk25) then
9
      if P7ORT_CS = '1' then
10
         RAM_Page <= cpu_DO(1 downto 0);
11
         ROM_Page <= cpu_DO(3);
12
      end if;
13
   end if;
14
end process;


Jetzt weiss ich nicht ob es besser wäre die Bedingug direkt im "IF" zu 
schreiben:

1
process (clk25,reset)
2
begin
3
   if reset = '0' then
4
      RAM_Page <= "00";
5
      ROM_Page <= '0';
6
   elsif rising_edge(clk25) then
7
      if cpu_IORQ = '0' and cpu_WR = '0' and cpu_A(15 downto 8) = "01110011" then
8
         RAM_Page <= cpu_DO(1 downto 0);
9
         ROM_Page <= cpu_DO(3);
10
      end if;
11
   end if;
12
end process;


Macht es überhaupt underschiede? Wenn ja, welche???

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>Macht es überhaupt underschiede?
Nein, schau dir einfach mal die RTL-Schematics an.
Die 2. Lösung ist einfach schöner lesbar, weil kompakter...



Ein Tipp:
Nimm den Reset mit in den synchronen Teil des Prozesses, auch wenn die 
allgegenwärtigen Code-Beispiele anders aussehen.
1
process (clk25)
2
begin
3
   if rising_edge(clk25) then
4
      if reset = '0' then
5
         RAM_Page <= "00";
6
         ROM_Page <= '0';
7
      elsif cpu_IORQ = '0' and cpu_WR = '0' and cpu_A(15 downto 8) = "01110011" then
8
         RAM_Page <= cpu_DO(1 downto 0);
9
         ROM_Page <= cpu_DO(3);
10
      end if;
11
   end if;
12
end process;
1. Grund: Was würde in deinem Design passieren, wenn der Reset super 
knapp vor der steigenden Flanke des Taktes inaktiv würde? Bekommen das 
alle FFs gleich- und rechtzeitig mit? Läuft dann dein ganzes FPGA 
zuverlässig an?
Nein: der Reset ist ein asynchrones Signal (das asynchrone Signal 
schlechthin), der muss auch auf deinen Takt einsynchronisiert werden 
(wie jedes andere asynchrone Signal). Und wenn der Reset dann schon 
synchron ist, gehört er auch in den getakteten Teil.

2. Grund: Der ganze Rest des Designs ist synchron, nur für den 
asynchronen Reset zwingst du das Synthesetool, asynchrone FFs zu 
verwenden. Der Synthesizer verwendet dann sozusagen die "falschen" FFs. 
Und mit diesen FFs kann der synchrone Teil der Schaltung (und das ist 
der, der die Arbeit tut) nicht so schön optimiert werden.

3. Grund: wozu brauchst du einen Reset? Für den allgegenwärtigen 
Reset-Taster? Ist der es Wert, wertvolle Resourcen zu vergeuden?

Dazu auch:
http://www.xilinx.com/support/documentation/white_papers/wp272.pdf

Meine Aussagen gelten für Xilinx, inwiefern das für andere Architekturen 
passt: bitte selber überprüfen.

von Dimi (Gast)


Lesenswert?

Vielen dank für die Info!!!!

Alles super erklärt!

Zu Punkt 3.
Ein Reset brauche ich schon, kann aber 90% davon wegschmeissen.
Ich werde heute noch alles ändern. :)
Es ist mir einfach SEHR interessant, wie sich die
Laufzeiten ändern!

p.S. ich dachte immer das "reset" eines FlipFlops keine
zusätzliche Resourcen verwendet, da die FlipFlops
SET- und RESET- eingänge haben und diese werden dafür verwendet.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Dimi wrote:
> p.S. ich dachte immer das "reset" eines FlipFlops keine
> zusätzliche Resourcen verwendet
Richtig: es werden für den Reset keine zusätzlichen Ressourcen 
verschwendet, die sind alle schon da.
Nur werden für den asynchronen Reset dann auch asynchrone FFs 
eingesetzt. Und so ein FF kann nur entweder asynchron (FDCP, mit preset 
und clear) oder synchron (FDRS, mit set und reset) konfiguriert werden. 
Und bei einem synchronen Design kann der Synthesizer mit einem 
synchronen FF wesentlich mehr anfangen.

> da die FlipFlops SET- und RESET- eingänge haben
Ja, es gibt wie gesagt grundlegend 2 verschiedene Möglichkeiten, die FFs 
zu konfigurieren (mal von den DDR-FFs abgesehen).

Ein kleines Beispiel:
Asynchroner Reset
1
architecture Behavioral of Reset_1 is -- AsyncSync
2
signal do : std_logic;
3
begin
4
   process (clk)
5
   begin
6
      if (reset='1') then            -- async. Reset
7
         do <= '0';
8
      elsif rising_edge(clk) then
9
         if    (set='1') then        -- sync. Set
10
            do <= '1';
11
         elsif (load='1') then       -- laden
12
            do <= din;
13
         else
14
            do <= do;                -- speichern
15
         end if;
16
      end if;
17
   end process;
18
   dout <= do;
19
end Behavioral;

Und im Anhang die RTL-Schematic.
Schön aufwendig, nicht wahr?
:
:
:

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

:
:
Und dann:
Synchroner Reset
1
architecture Behavioral of Reset_1 is -- Synchron
2
signal do : std_logic;
3
begin
4
   process (clk)
5
   begin
6
      if rising_edge(clk) then
7
         if   (reset='1') then       -- sync. Reset
8
            do <= '0';
9
         elsif (set='1')  then       -- sync. Set
10
            do <= '1';
11
         elsif (load='1') then       -- laden
12
            do <= din;
13
         else
14
            do <= do;                -- speichern
15
         end if;
16
      end if;
17
   end process;
18
   dout <= do;
19
end Behavioral;

Schön einfach, nicht wahr?
Welche der beiden Lösungen dürfte schneller sein?
Spätestens jetzt sollte der Groschen fallen... ;-)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Meine Lieblingsschreibweise wäre dann so:
1
architecture Behavioral of Reset_1 is -- Synchron
2
signal do : std_logic;
3
begin
4
   process begin
5
      wait until rising_edge(clk);
6
      if    (reset='1') then   do <= '0';  -- sync. Reset
7
      elsif (set='1')   then   do <= '1';  -- sync. Set
8
      elsif (load='1')  then   do <= din;  -- laden
9
--    else                     do <= do;   -- speichern: implizit
10
      end if;
11
   end process;
12
   dout <= do;
13
end Behavioral;

Schöner gehts nimmer...   ;-)

von Dimi (Gast)


Lesenswert?

VIELEN VIELEN DANK!!!

Die Ergebnisse kommen noch :)

von Matthias F. (flint)


Lesenswert?

@lkmiller: Könntest du, nachdem du das ganze schon parat hast, das ganze 
noch umdrehen, also im Reset '1' zuweisen und im synchronen Set '0'.

Dann müsste sich das Ganze, wenigstens bei Xilinx, wieder ziemlich 
ändern, weil das Reset an sich eine höhere Priorität hat als das Set und 
das Synthesetool das wieder so hinbauen muss.

Würde mich interessieren, ob ich mit dieser Vermutung recht habe.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

>Würde mich interessieren, ob ich mit dieser Vermutung recht habe.
Hier geht die Geschichte unentschieden aus:
beide Lösungen brauchen gleich viel zusätzliche Logik.

Ansatz:
(Beispiel: synchron)
1
         wait until rising_edge(clk);
2
         if   (reset='1') then       -- sync. Reset 
3
            do <= '1';               --    auf '1'
4
         elsif (set='1')  then       -- sync. Set
5
            do <= '0';               --    auf '0'
6
         elsif (load='1') then       -- laden
7
            do <= din;
8
         else
9
            do <= do;                -- speichern
10
         end if;

Im Bild:
oben asynchrones FF
unten synchrones FF


Fazit:
man muss dem FPGA schon ein wenig "nach dem Maul" programmieren ;-)

von Matthias F. (flint)


Lesenswert?

Danke für die Mühe.

Theoretisch könnte man ja auch die Daten an Eingang und Ausgang 
invertieren, dann könnte man auch das Set/Reset Assignment umdrehen und 
das Synthesetool könnte wieder die Priorisierung der verschiedenen 
Eingänge ausnutzen.

Wobei das wohl auch Hirnw*chserei ist, nachdem man für eine Invertierung 
ja erst wieder über eine LUT gehen muss. Aber spannend ist das Thema 
jedenfalls :) .

Lesetipp dazu ist übrigens das Xilinx WP275 "Get your priorities right".

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>nachdem man für eine Invertierung ja erst wieder über eine LUT gehen muss
Nein, das ist nicht nur theoretische Kunst. Natürlich wirst du nicht 
jeden Pfad optimal hinbekommen. Aber wenn du den kritischen Logikpfad 
u.U. durch das Herausnehmen einer Logikebene und Einfügen derselben in 
den Set/Reset-Pfad schneller bekommst, dann hat das was.

Wichtig ist hier zuerst das Wissen oder wenigstens eine Ahnung, _was 
überhaupt_ aus der Beschreibung gemacht werden wird. Wenn man nicht 
alles falsch macht, hat man schon Vieles richtig gemacht.

von Matthias F. (flint)


Lesenswert?

Es kann jedenfalls nicht schaden, zu verstehen, wie die HW die man da 
bearbeitet, funktioniert. In diesem speziellen Fall braucht man aber 
auch für den ungünstigen Fall nur eine Logikebene (wenn ich es richtig 
sehe), wenn man Daten davor und danach invertieren will aber zwei. Darum 
hab ich das doppelte Invertieren mal nur in die Ecke Spielerei 
geschoben.

Und wenn man gerade so an der Grenze ist mit dem Timing würden viele 
wohl einfach einen schnelleren Speedgrade nehmen, ist vermutlich auch 
wirtschaftlich die vernünftigere Entscheidung.

Aber ein wenig Spielerei muss ja auch sein :) .

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> In diesem speziellen Fall...
Richtig, hier wird sowieso nur 1 LUT nötig sein. Aber sobald in die Set- 
und Reset-Abfragen etwas mehr reinkommt (Adressdecoder, States) könnten 
unnötigerweise 2 Logikebenen synthetisiert werden. Und auf einmal ("Ich 
habe doch fast nichts geändert") ist es zu langsam oder zu groß.

> verstehen, wie die HW die man da bearbeitet, funktioniert...
Das ist wie mit dem Wissen, wie die rote Ampel funktioniert:
Die Strasse darunter ist an sich immer gleich gut befahrbar. Aber mit 
dem Wissen, dass die Ampel zur Strasse gehört, wirds dann auch 
ungefährlich. Sonst geht das Überqueren mal gut und und mal nicht... ;-)

von Rick Dangerus (Gast)


Lesenswert?

@Lothar Miller:
Jetzt musst Du nur noch die C-like Klammern in den if-Abfragen 
einsparen. Da wäre es perfekt :-)

Rick

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Danke für die Blumen,
aber wenn ich tippe geht nach if( automatisch die Klammer auf.
Egal ob C oder VHDL, ich kann da gar nicht anders... ;-)

von FPGA-Designer (Gast)


Lesenswert?

Die Klammern machen schon Sinn, wenn man zwsichen C<->VHDL wechselt.

"Die 2. Lösung ist einfach schöner lesbar, weil kompakter..."

Ich nicht! Ich finde die erste mit dem explizieten chip select die 
bessere.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>Ich finde die erste mit dem explizieten chip select die bessere.
Wenn ich aus einem ganzen Adressraum mehrere Adressbereiche selektieren 
will, dann erzeuge ich mir auch einzelne Chip-Selects für jeden Bereich. 
Nur bestehen die dann nicht wie hier
1
PORT_CS <= '1' when cpu_IORQ = '0' and cpu_WR = '0' and cpu_A(15 downto 8) = "01110011" else '0';
aus einer ganzen Latte Kombinatorik, sondern eben nur aus den 
Adressleitungen. So etwa:
1
PORT_CS <= '1' when (cpu_A(15 downto 8) = "01110011") else '0';
2
:
3
:
4
    elsif (cpu_IORQ='0' and cpu_WR='0' and PORT_CS) then
5
:
Und am eigentlichen Verwendungsort werden dann RD bzw WR dazu 
kombiniert.

von Hagen R. (hagen)


Lesenswert?

und wo ist da der Unterschied ? Der Synthese juckt das nicht.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ich sehe gerade, dass ich auf eine alte Frage noch eine Antwort schuldig 
bin...  :-/

Hagen Re schrieb:
> und wo ist da der Unterschied ?
Der Unterschied ist, dass ein CS wörtlich ausgesprochen "Chip-Select" 
heißt. Und in der ersten Variante beinhaltet dieser Chip-Select viel 
mehr als sein Name vermuten lassen würde. Ich finde sowas sehr 
irreführend...

von Philip K. (philip_k)


Lesenswert?

Lothar Miller schrieb:
> Ich sehe gerade, dass ich auf eine alte Frage noch eine Antwort schuldig
> bin...  :-/
>
> Hagen Re schrieb:
>> und wo ist da der Unterschied ?
> Der Unterschied ist, dass ein CS wörtlich ausgesprochen "Chip-Select"
> heißt. Und in der ersten Variante beinhaltet dieser Chip-Select viel
> mehr als sein Name vermuten lassen würde. Ich finde sowas sehr
> irreführend...

Das ist dann aber doch eher ein Problem der Namensgebung. Ich finde es 
auch übersichtlicher, wenn umfangreichere Kombinatorik separat steht.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Philip K. schrieb:
> Das ist dann aber doch eher ein Problem der Namensgebung.
Ja, klar.
Nur darum ging dieser Teil der Diskussion, wie
FPGA-Designer schrieb im Beitrag #966748:
> "Die 2. Lösung ist einfach schöner lesbar...

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
Noch kein Account? Hier anmelden.