Forum: FPGA, VHDL & Co. Addition mit Carry


von Duke Scarring (Gast)


Lesenswert?

Hallo Forum!

Gesucht wird eine schnelle Addition, die einen eventuellen Überlauf 
gleich mit addiert.
Hintergrund ist die Berechung von UDP-Checksummen.
Bisher verwende ich zwei Additionen:
1
function udp_checksum( valuea : unsigned( 15 downto 0); 
2
                       valueb : unsigned( 15 downto 0)) return unsigned is
3
    variable addcarry: unsigned( 16 downto 0);
4
    variable result:   unsigned( 15 downto 0);
5
begin
6
    addcarry := resize( valuea, addcarry'length) + valueb;
7
    result   := addcarry( 16 downto 16)          + addcarry( 15 downto 0);
8
    return result;
9
end function udp_checksum;
Geht das auch eleganter, sprich ohne zwei Additionen hintereinander?
Wie wurde das z.B. beim Z80 gelöst? Da gibt es auch einen ADC (add with 
carry) Befehl?

Duke

von Klaus F. (kfalser)


Lesenswert?

Bei einer Addition mit Carry wird das Carry-Bit aus der vorhergehenden 
Addition übernommen und ergibt wieder ein neues Carry-Bit für die 
nächste Addition, oder?

Das macht jedenfalls ein MC, wie der Z80.

von Duke Scarring (Gast)


Lesenswert?

Stimmt, da habe ich was durcheinander gebracht.
Dann wird es wahrscheinlich nichts mit der Optimierung.

Duke

von Sigi (Gast)


Lesenswert?

CarryIn und CarryOut für A+B:

Sei A,B : std_logic_vector(n-1 downto 0)

Damit:
A2 <= '0' & A & CarryIn
B2 <= '0' & B & '0'
C2 <= A2 + B2

CarryOut <= C2(n+1)     (oder n?)

(kostet kaum mehr Zeit als eine "normale" Addition)

von Stefan Weide (Gast)


Lesenswert?

Für diese Art der Prüfsummenbildung würde ich einen Carry-Select-Adder 
empfehlen.

Das würde dann in etwa so aussehen:
1
function udp_checksum( valuea : unsigned( 15 downto 0); 
2
                       valueb : unsigned( 15 downto 0)) return unsigned is
3
    variable addAB: unsigned( 16 downto 0);
4
    variable addAB1: unsigned( 15 downto 0);
5
    variable result:   unsigned( 15 downto 0);
6
begin
7
    addAB := resize( valuea, addAB'length) + valueb;
8
    addAB1 := valuea + valueb + 1;
9
    if addAB(addAB'left)='0' then
10
      result   := addAB( 15 downto 0);
11
    else
12
      result   := addAB1( 15 downto 0);
13
    end if;
14
    return result;
15
end function udp_checksum;

Damit werden die Additionen nicht mehr Kaskadiert und du solltest die 
maximal mögliche Frequenz erzielen.

von Josef G. (bome) Benutzerseite


Lesenswert?

Sigi schrieb:
> A2 <= '0' & A & CarryIn
> B2 <= '0' & B & '0'

Muss heissen:
  A2 <= '0' & A & CarryIn
  B2 <= '0' & B & '1'

von berndl (Gast)


Lesenswert?

Duke Scarring schrieb:
> Dann wird es wahrscheinlich nichts mit der Optimierung.

Evtl. eine Mischung aus "carry lookahead" und "ripple carry"?

Also z.B. jeweils 4 Bit als schnellen "carry lookahead" bauen und dann 
das ganze mit "ripple carry" Addierern zusammenbauen. Kostet halt mehr 
HW...

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.