Gibt es eine optimiertere Art, einen Inkrementierer zu erstellen, als einen Volladdierer?

Ich entwerfe einen sehr einfachen Mikroprozessor als Projekt, um VHDL zu lernen. Ich brauche also etwas, um den 8-Bit-Programmzähler zu erhöhen. Ich muss es um zwei erhöhen. Gibt es ein besseres Design (entweder schneller oder weniger Logik für gleiche Geschwindigkeit erforderlich) als die Verwendung eines 8-Bit-Volladdierers? Das Gleiche interessiert mich auch, wenn Sie den PC nur um 1 erhöhen müssten.

Ich weiß fast nichts über VHDL und vielleicht halten Sie dies für selbstverständlich, wenn Sie von einem Volladdierer sprechen. Entschuldigen Sie, wenn dies der Fall ist, aber zur Verbesserung der Leistung haben Sie den "Carry Look-Ahead-Addierer".
Übrigens: Link für alle Fälle en.wikipedia.org/wiki/Carry_look-ahead_adder
@JaimePardos, alle ALUs verwenden dieses oder ein fortschrittlicheres Gerät, um die Geschwindigkeit zu erhöhen. Das Warten auf Verzögerungen von 32 Übertragsbits ist in einem modernen Prozessor nicht akzeptabel.

Antworten (5)

Hmmm, das hängt alles davon ab, was genau Sie lernen möchten. Ein Zähler oder Addierer in VHDL ist super einfach:

  signal count  :std_logic_vector (7 downto 0) := (others=>'0');
  . . .
  process (clk)
  begin
    if rising_edge(clk) then
      if count_enable='1' then
        count <= count + 1;  -- could be +2 also
      end if;
    end if;
  end process;

Und das ist es! Der VHDL-Compiler synthetisiert dafür normalerweise einen Volladdierer und optimiert alles heraus, was nicht benötigt wird – am Ende entsteht eine Art Halbaddierer. Das Schöne daran ist, dass Ihr Code lesbar und leicht verständlich ist und der Compiler sich darum kümmert, den besten Weg zu finden, ihn zu implementieren.

Nun, wenn Sie versuchen, etwas über Addierer und Zähler und dergleichen zu lernen, dann wird Ihnen mein kleiner Code-Schnipsel nicht viel helfen. In diesem Fall sollten Sie einen Halbaddierer manuell und auf die harte Tour implementieren.

Nachdem ich eine Weile darauf gestarrt und versucht hatte, einen effizienteren Weg zu finden, entschied ich mich dafür, nur den von VHDL bereitgestellten Volladdierer zu verwenden:S <= (I) + ("00000010");
Außerdem wählt ein gutes Synthesetool basierend auf Ihren Einschränkungen automatisch eine geeignete Implementierung aus, dh Welligkeit, wenn Geschwindigkeit nicht wichtig ist, und CLA oder eine andere optimierte Implementierung, wenn dies der Fall ist.

Sie brauchen eigentlich keinen Volladdierer zum Inkrementieren um 1; Die Verwendung von Halbaddierern, bei denen der erste Eingang auf 1 gesetzt ist und Übertragsbits mit dem nächsten Bit verkettet sind, würde ausreichen. Ich bin mir aber nicht sicher, ob es noch einen besseren Weg gibt.

Das Erhöhen um zwei könnte durch Ignorieren des ersten Bits einer Zahl und unter Verwendung der gleichen oben beschriebenen Methode erfolgen.

HINWEIS: kein VHDL-Experte, kann nicht sagen, ob dies tatsächlich schneller sein könnte, sollte aber weniger logisch sein.

Bearbeiten: Außerdem gibt es ein abgelaufenes Patent für einen einfachen binären Inkrementierer, der von Interesse sein könnte: http://www.freepatentsonline.com/3989940.pdf

Nun, ich bin auch kein Experte, aber ich würde annehmen, solange es keine "Schleifen" in der Hardware (dh seriell) gibt, sollte weniger Logik immer besser sein.
Für Ihre Bearbeitung. Wow, ich hatte vergessen, wie dicht Patent-PDFs sind.

Vielleicht können Sie einen Binärzähler verwenden , der aus JK-Flipflops besteht , bei dem Sie den Bitwert in jedes Flipflop laden und dann einfach die Uhr umschalten können. Das Zählen um 2 würde bedeuten, dass alles außer dem niederwertigsten Bit in den Zähler geladen wird, da sich dieses Bit nie ändert.

Dies wird wahrscheinlich nicht besser sein als eine Halbaddierer-Implementierung, aber vielleicht ist es einfacher zu verstehen :)

Was Sie speziell brauchen, ist eine Reihe von T-Triggern + eine Reihe von UND-Gattern. Sie sollten das 'Toggle'-Signal nur dann an Bit n übergeben, wenn alle vorherigen Bits 1 waren. Dies ist viel schneller als ein Volladdierer, erfordert kein Carry-Look-Ahead und verbraucht viel weniger Transistoren.

PS. Vor einiger Zeit habe ich mir genau die gleiche Frage gestellt ;-)

Was Sie beschreiben, ist in einem FPGA nicht schneller als die Verwendung eines normalen Voll- oder Halbaddierers und erfordert mehr Logikressourcen. Das ist zunächst nicht intuitiv, aber bleib hier bei mir. Wenn Sie die Logik aus rohen Gattern und Flip-Flops implementieren, haben Sie möglicherweise Recht. Aber FPGAs sind keine rohen Gates und Flip-Flops. FPGAs sind feste, aber halbprogrammierbare Logikstrukturen, und diese Strukturen umfassen dedizierte Carry-Ketten, die fest verdrahtet wurden, um superschnell zu sein. Viel schneller als die "normale Logik", und ihre Verwendung befreit die normale Logik für, nun ja, normale Logik.
Ich denke, Carry-Ketten werden im Allgemeinen besser für Anwendungen verwendet, die Volladdierer erfordern. Der entscheidende Punkt sollte jedoch darin bestehen, anzugeben, was die Hardware tun soll, und die FPGA-Software herausfinden zu lassen, wie dies angesichts der vorhandenen Chipressourcen am besten implementiert werden kann. Wenn es genügend andere mathematische Dinge gibt, um die vorhandenen dedizierten Carry-Ketten zu verbrauchen, kann ein Inkrementierer in gewöhnlicher Logik ziemlich gut ausgeführt werden. Wenn Carry-Chain-Ressourcen verfügbar sind, kann es sinnvoll sein, sie zu verwenden. Die FPGA-Software sollte in der Lage sein, es herauszufinden.
Ich sehe nicht, wo steht, dass es für ein FPGA ist. Ich stimme dir hier zu.

Es scheint auf jeden Fall eine Vereinfachung geben zu müssen – immerhin ist eine der Eingaben auf einen festen Wert begrenzt, der jedes Mal gleich ist!

Leider reicht das nur aus, um die Anzahl der Gates geringfügig zu reduzieren, aber nicht viel Zeit bis zur Fertigstellung. Das liegt daran, dass Sie einfachere Addierer erhalten - sie haben nur 1 Eingang plus Übertrag, sodass die Basisaddierer etwa 1/3 weniger Gatter haben. Aber die Verzögerung wird durch die Überträge bestimmt, die nicht reduziert werden, sie müssen immer noch die ganze Kette hochwellen. Sie erhalten also keine nennenswerte Beschleunigung. Und wenn es schnell gehen soll, müssen sich mindestens die Hälfte der Gates mit den Überträgen befassen, so dass sich 1/3 Gain insgesamt auf etwa 1/6 weniger Gates reduziert. Am Ende ungefähr die gleiche Geschwindigkeit und 85% der Größe eines Volladdierers.