Forum: FPGA, VHDL & Co. Shift von Pipeline Elementen


von Patrick B. (p51d)


Lesenswert?

Hallo

Ich möchte eine einfache Division erreichen. Sprich am Shift-Eingang 
leigt 2 an, dann sollen die Daten um 2 Bits nach rechst verschoben 
ausgegeben werden.
Ich dachte mir, dass man das über eine For-Schleife lösen könnte:
1
type pipeline_array is array(0 to MAX_SHIFTS-1) of std_logic_vector(DATA_WIDTH-1 downto 0);
2
signal pipeline : pipeline_array;
3
4
divide : process(clk)
5
begin
6
  if rising_edge(clk) then
7
    if reset = '1' then
8
      for i in 0 to (MAX_SHIFTS-1) loop
9
        pipeline(i) <= (others => '0');
10
      end loop;
11
    else
12
      for i in 0 to (MAX_SHIFTS-1) loop
13
        if ce = '1' then
14
          if std_logic_vector(to_unsigned(i, SHIFT_WIDTH)) < i_shifts then
15
            pipeline(i+1) <= '0' & pipeline(i)(DATA_WIDTH-1 downto 1);
16
          else
17
            pipeline(i+1) <= pipeline(i);
18
          end if;
19
        end if;        
20
      end loop;
21
    end if;
22
  end if;
23
end process;

Das Modul hätte eine konstate Verzögerung. Für jedes Element soll anhand 
des i_shift Eingangs entschieden werden, ob nochmals geschoben werden 
soll, oder ob die nächste Stufe das Ergebnis direkt übernehmen soll.

Fehlermeldungen bekomme ich keine, aber leider stoppt der Simulator beim 
ersten "gültigen" Takt. Sieht jemand den Fehler? Oder gibts eine 
einfachere Lösung für die Division als Schiebeoperation, die vom Eingang 
abhängig ist?

Die IP Cores für Radix-2 sind für mich viel zu umfangreich (da ich nur 
eine 2^n Division brauche).

Besten Dank,
Gruss
Patrick

EDIT:
Hab den Fehler für das Stoppen des Simulators gefunden. Die For-Schleife 
darf natürlich nur bis (MAX_SHIFTS-2) gehen, ansonsten gibts einen 
fehlerhaften Zugriff.

: Bearbeitet durch User
von Markus F. (Gast)


Lesenswert?

Das kann man so nur lösen, wenn man alle erdenklichen Versionen der 
Shift-Operation ausformuliert und dann die richtige real selektiert. Es 
muss ja real alles möglich sein, was vorkommen kann. So macht man sowas 
aber nicht.

von Duke Scarring (Gast)


Lesenswert?

Markus F. schrieb:
> Das kann man so nur lösen, wenn man alle erdenklichen Versionen der
> Shift-Operation ausformuliert und dann die richtige real selektiert. Es
> muss ja real alles möglich sein, was vorkommen kann. So macht man sowas
> aber nicht.
Doch. Mir ist das unter dem Namen Barrel-Shifter bekannt.

Duke

von Thomas R. (Firma: abaxor engineering) (abaxor)


Lesenswert?

Duke Scarring schrieb:
> Markus F. schrieb:
>> Das kann man so nur lösen, wenn man alle erdenklichen Versionen der
>> Shift-Operation ausformuliert und dann die richtige real selektiert. Es
>> muss ja real alles möglich sein, was vorkommen kann. So macht man sowas
>> aber nicht.
> Doch. Mir ist das unter dem Namen Barrel-Shifter bekannt.

Nur gibt es die nicht in FPGAs, sie heißen jetzt DSP-Slices :-).

Mit einem 18x18 Multiplizierer kann man problemlos 0..18 Bit nach rechts 
schieben und das mit konstanter Latenz

Tom

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

> Mit einem 18x18 Multiplizierer kann man problemlos 0..18 Bit nach rechts
> schieben und das mit konstanter Latenz
>
> Tom

Wieviele Takte braucht der Multiplizierer dafür?

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


Lesenswert?

René D. schrieb:
> Wieviele Takte braucht der Multiplizierer dafür?
Einen.
Oder andersrum: der Multiplizierer an sich braucht gar keinen. Aber er 
hat Register hinter sich...

: Bearbeitet durch Moderator
von Duke Scarring (Gast)


Lesenswert?

Lothar M. schrieb:
> Aber er
> hat Register hinter sich...
Die man durch Multiplexer umgehen kann.

Die Frage muss eher lauten: passt die Durchlaufzeit zur angepeilten 
Taktfrequenz.

Duke

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Duke Scarring schrieb:
> Markus F. schrieb:
>> Das kann man so nur lösen, wenn man alle erdenklichen Versionen der
>> Shift-Operation ausformuliert und dann die richtige real selektiert. Es
>> muss ja real alles möglich sein, was vorkommen kann. So macht man sowas
>> aber nicht.

Jetzt much ich dir auch mal wiedersprechen.

>  Mir ist das unter dem Namen Barrel-Shifter bekannt.
>
> Duke

Ich habe bei mir in der Mais-CPU eine Funktion, mit der in einem Takt 
geschiftet wird. Das habe ich vor langer Zeit geschrieben. Hatte auch 
lange gekonbelt.
1
  function shift_f
2
    (a          : in std_logic_vector(31 downto 0);
3
     b          : in std_logic_vector(31 downto 0);
4
     shift_func : in shift_function_type;
5
     rt_data    : in std_logic_vector(31 downto 0)) 
6
    return std_logic_vector
7
    
8
  is
9
10
    --barrel shifter unit
11
    variable shift1L, shift2L, shift4L, shift8L, shift16 :
12
      std_logic_vector(31 downto 0);
13
    variable shift1R, shift2R, shift4R, shift8R :
14
      std_logic_vector(31 downto 0);
15
    variable fills       : std_logic_vector(31 downto 16);
16
    variable shiftnumber : std_logic_vector(4 downto 0);
17
  begin
18
19
    if (shift_func(1) = '1' and rt_data(31) = '1') then
20
      fills := "1111111111111111";
21
    else
22
      fills := "0000000000000000";
23
    end if;
24
25
    if shift_func(2) = '0' then
26
      shiftnumber := b(10 downto 6);
27
    else
28
      shiftnumber := a(4 downto 0);
29
    end if;
30
    --SLL  rd<_rt << sa
31
    if shift_func (0) = '0' then        -- shift left
32
      if shiftnumber(0) = '1' then
33
        shift1L := rt_data(30 downto 0) & '0';
34
      else
35
        shift1L := rt_data;
36
      end if;
37
      if shiftnumber(1) = '1' then
38
        shift2L := shift1L(29 downto 0) & "00";
39
      else
40
        shift2L := shift1L;
41
      end if;
42
      if shiftnumber(2) = '1' then
43
        shift4L := shift2L(27 downto 0) & "0000";
44
      else
45
        shift4L := shift2L;
46
      end if;
47
      if shiftnumber(3) = '1' then
48
        shift8L := shift4L(23 downto 0) & "00000000";
49
      else
50
        shift8L := shift4L;
51
      end if;
52
      if shiftnumber(4) = '1' then
53
        shift16 := shift8L(15 downto 0) & X"0000";
54
      else
55
        shift16 := shift8L;
56
      end if;
57
      
58
    else                                --shift right
59
      if shiftnumber(0) = '1' then
60
        shift1R := fills(31) & rt_data(31 downto 1);
61
      else
62
        shift1R := rt_data;
63
      end if;
64
      if shiftnumber(1) = '1' then
65
        shift2R := fills(31 downto 30) & shift1R(31 downto 2);
66
      else
67
        shift2R := shift1R;
68
      end if;
69
      if shiftnumber(2) = '1' then
70
        shift4R := fills(31 downto 28) & shift2R(31 downto 4);
71
      else
72
        shift4R := shift2R;
73
      end if;
74
      if shiftnumber(3) = '1' then
75
        shift8R := fills(31 downto 24) & shift4R(31 downto 8);
76
      else
77
        shift8R := shift4R;
78
      end if;
79
      if shiftnumber(4) = '1' then
80
        shift16 := fills(31 downto 16) & shift8R(31 downto 16);
81
      else
82
        shift16 := shift8R;
83
      end if;
84
    end if;
85
    return(shift16);
86
    
87
  end shift_f;

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.