Forum: FPGA, VHDL & Co. [VHDL] elegant gerade Parity generieren


von zachso (Gast)


Lesenswert?

Hallo!

ich gucke mir gerade den PCIlite-Core von opencores an, und dabei ist 
mir folgende codezeile aufgefallen:
1
pardat   <= d(0)  xor d(1)  xor d(2)  xor d(3)  xor d(4)  xor d(5)  xor d(6)  xor d(7)  xor d(8)  xor d(9)  xor d(10) xor d(11) xor 
2
d(12) xor d(13) xor d(14) xor d(15) xor d(16) xor d(17) xor d(18) xor d(19) xor d(20) xor d(21) xor d(22) xor d(23) xor d(24) xor 
3
d(25) xor d(26) xor d(27) xor d(28) xor d(29) xor d(30) xor d(31);
4
5
parcbe   <= cbe_i(0) xor cbe_i(1) xor cbe_i(2) xor cbe_i(3); 
6
7
par <= pardat xor parcbe;

hier wird eine gerade parity generiert aus dem vektor d(31 downto 0) und 
cbe(3 downto 0)

nun frage ich mich natuerlich ob das nicht um einiges eleganter geht 
irgendwie? das muss doch anders moeglich sein. leider faellt mir kein 
konstrukt ein was das bewerkstelligen koennte, kann mir vllt. einer von 
euch weiterhelfen?

danke
zachso

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


Lesenswert?

zachso schrieb:
> nun frage ich mich natuerlich ob das nicht um einiges eleganter geht
> irgendwie? das muss doch anders moeglich sein.
Sieh dir mal an, was der Synhtesizer draus macht. Ich würde sagen, dass 
da bei einer 4er LUT immer 4 Eingänge zsammengefasst werden, und dann 
immer 4 der Zwischenergebnisse wieder mit einer LUT. Schlussendlich 
bleiben also 3 ziemlich direkt verdrahtete Logikebenen.
Mit der 6er LUT vom Virtex6/Spartan6 sind es sogar nur 2 Logikebenen...

Das parcbe passt sogar in 1 4er-LUT und kann effizienter gar nicht 
dargestellt werden...

> par <= pardat xor parcbe;
Dafür wäre es allerdings u.U. besser, gleich alle beteiligten Signale in 
einem Term zu verknüpfen...
Also so:
1
par <=  d(0)  xor d(1)  xor d(2)  xor d(3)  xor d(4)  xor d(5)  xor d(6)  
2
        xor d(7)  xor d(8)  xor d(9)  xor d(10) xor d(11) xor d(12) xor d(13)
3
        xor d(14) xor d(15) xor d(16) xor d(17) xor d(18) xor d(19)
4
        xor d(20) xor d(21) xor d(22) xor d(23) xor d(24) xor d(25)
5
        xor d(26) xor d(27) xor d(28) xor d(29) xor d(30) xor d(31) 
6
        xor cbe_i(0) xor cbe_i(1) xor cbe_i(2) xor cbe_i(3);
Aber es kann auch gut sein, dass der Synthesizer das selber merkt und ie 
zusätzliche Logikebene rauslässt...

von Georg A. (Gast)


Lesenswert?

Ich habe auch mal so einen PCI-Core geschrieben und bin damals (~2005) 
drauf gestossen, dass die schnell geschriebene Lösung mit einer 
for-Schleife+Index bei xst langsamer war, als die von Hand in 
4er-Gruppen gegliederte Variante. Seitdem habe ich es nicht mehr 
untersucht, evtl. ist xst ja doch intelligenter geworden...

von user (Gast)


Lesenswert?

wie wäre es damit?

process(d)
  variable result : std_logic;
begin
  result := '0';
  for i in d'range loop
    result := result xor d(i);
  end for;
  par <= result;
end process;

von Hochpass (Gast)


Lesenswert?


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


Lesenswert?

Hochpass schrieb:
> http://www.xilinx.com/itp/xilinx4/data/docs/cgd/x4...
XOR_COLLAPSE
The default is YES.
--> XORs werden (schon seit der uralten Version 4) zusammengefasst.

Und siehe da: ein kleines Testprojekt aufgesetzt und ausprobiert...
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity XORing is
6
    Port ( d  : in  STD_LOGIC_VECTOR (31 downto 0);
7
           q0 : out  STD_LOGIC;
8
           q1 : out  STD_LOGIC;
9
           q2 : out  STD_LOGIC;
10
           q3 : out  STD_LOGIC);
11
end XORing;
12
13
architecture Behavioral of XORing is
14
15
function doXOR (din : std_logic_vector) return std_logic is
16
variable h : std_logic := '0';
17
begin
18
   h := '0';
19
   for i in din'range loop 
20
      h := h xor din(i);
21
   end loop;
22
   return h;
23
end doXOR;
24
25
begin
26
27
   q0 <= doXOR(d);
28
29
   q1 <=       d(0)  xor d(1)  xor d(2)  xor d(3)  xor d(4)  xor d(5)  xor d(6)  xor d(7)  
30
           xor d(8)  xor d(9)  xor d(10) xor d(11) xor d(12) xor d(13) xor d(14) xor d(15) 
31
           xor d(16) xor d(17) xor d(18) xor d(19) xor d(20) xor d(21) xor d(22) xor d(23)
32
           xor d(24) xor d(25) xor d(26) xor d(27) xor d(28) xor d(29) xor d(30) xor d(31); 
33
34
   process (d) 
35
   variable q : std_logic := '0';
36
   begin
37
      q := d(0);
38
      for i in 1 to 31 loop
39
         q := q xor d(i);
40
      end loop;
41
      q2 <= q;
42
   end process;
43
44
   process (d) 
45
   variable q : std_logic := '0';
46
   begin
47
      q := '0';
48
      for i in 0 to 31 loop
49
         q := q xor d(i);
50
      end loop;
51
      q3 <= q;
52
   end process;
53
54
end Behavioral;
Fazit: alle Ausgänge q0..3 bringen das selbe und werden einfach parallel 
geschaltet.

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


Angehängte Dateien:

Lesenswert?

Schlags kaputt, Anhang vergessen...
Hier die Technologie-Schematic, die die 3 Logikebenen zeigt, und ebenso, 
dass alle Ausgänge parallel hängen.

von Hochpass (Gast)


Lesenswert?

Jo so meinte ich das auch. Das macht das Tool selber. Bei der ISE weiß 
ich es, bei den anderen Tools gehe ich davon aus, dass es auch drin ist.

aber das xor_reduce hab ich auch schon mal benutzt:
http://www.vhdl.org/vhdlsynth/vhdl/reduce_pack.vhd

Es wird keinen Unterschied machen. Aber ich gebe zu dass ich es mir 
nicht bis aufs Gatter angeschaut habe, was die Tools draus machen.

von Georg A. (Gast)


Lesenswert?

Schön, ich frag mich nur, warum das damals anders war. Evtl. hat auch 
die Restschaltung noch einen Einfluss darauf.

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.