[VHDL] elegant gerade Parity generieren

Gast #2192505
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
Moderator (Firma: Titel) Persönliche Seite #2192617
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...
Gast #2192661
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...
Moderator (Firma: Titel) Persönliche Seite #2194846
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.
Gast #2195152
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren