Shift von Pipeline Elementen

#4605272
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.
Gast #4605450
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.
Gast #4606232
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
(Firma: abaxor engineering) #4606243
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
(Firma: www.dossmatik.de) #4606448
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;

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