Forum: FPGA, VHDL & Co. Instruktion SLLI (Shift logical left i times)


von Unnormaley (Gast)


Lesenswert?

Hallo,


ich bin gerade dabei eine CPU für mein FPGA board zu synthetisieren. Nun 
bin ich auf die Idee gekommen, dass es doch sinnvoll sein kann eine 
Instruktion "SLLI" zu implementieren. Diese shiftet ein 32-Bit Register 
logisch i-Mal nach links. Nun wollte ich mal wissen, wie man sowas in 
VHDL implementieren kann?

Ich habe hier mal meinen Code, jedoch will Xilinx das nicht 
synthetisieren. Der Fehler ist in der for-Schleife, hier müssen die 
Grenzen Konstant sein und nicht von Variablen abhängen (hier const). 
Irgendwelche Tipps, was ich tun kann? Ich dachte villeiecht könnte 
Xilinx eine 32-Bit Shifter synthetisieren, mit einem Eingang zum 
Angeben, um wie viel geshiftet werden soll...

Hier mein aktueller Code:
1
library IEEE;
2
use IEEE.std_logic_1164.all;
3
use IEEE.std_logic_misc.all;
4
use IEEE.std_logic_signed.all;
5
use IEEE.numeric_std.all;
6
7
entity shifter is
8
  port (
9
    s : in std_logic_vector (4 downto 0);
10
    d : in std_logic_vector (31 downto 0);
11
    q : out std_logic_vector (31 downto 0)
12
  );
13
end shifter;
14
15
architecture behavior of shifter
16
begin
17
  process(s, d)
18
    variable const : Integer;
19
    variable temp : std_logic_vector(31 downto 0);
20
  begin
21
    const := conv_integer(s);
22
    temp := d;
23
24
    if const >= 1 and const <= 32 then
25
      for i in 1 to const loop
26
        temp := temp(30 downto 0) & '0'
27
      end loop;
28
    end if;
29
30
    q <= temp;
31
  end process;
32
end behavior;

Bitte um Tipps! :)

von Sigi (Gast)


Lesenswert?

Such mal nach BarrelShifter.

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


Lesenswert?

Unnormaley schrieb:
> use IEEE.std_logic_1164.all;
> use IEEE.std_logic_misc.all;
> use IEEE.std_logic_signed.all;
> use IEEE.numeric_std.all;
Viel hilft viel...
Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"

Sigi schrieb:
> Such mal nach BarrelShifter.
Und du findest (wenn du hier im Forum suchst) den 
Beitrag "Re: Vektorinhalt variabel zuweisen"
(auch wenn der Thread zum Schluss hin ein wenig ausfranst... ;-)

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Nachfolgender Code ist zwar für einen 16-Bit Barrelshifter, aber das 
Prinzip sollte klar sein:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity BS_LSL is
5
  port (
6
    a   : in  STD_LOGIC_VECTOR (15 downto 0);
7
    pos : in  STD_LOGIC_VECTOR (3 downto 0);
8
    y   : out STD_LOGIC_VECTOR (15 downto 0)
9
  );
10
end BS_LSL;
11
12
architecture Behavioral of BS_LSL is
13
14
  signal STAGE1 : STD_LOGIC_VECTOR (15 downto 0);
15
  signal STAGE2 : STD_LOGIC_VECTOR (15 downto 0);
16
  signal STAGE3 : STD_LOGIC_VECTOR (15 downto 0);
17
18
begin
19
20
  STAGE1 <= A(14 downto 0) & "0" when pos(0) = '1' else A;
21
  STAGE2 <= STAGE1(13 downto 0) & "00" when pos(1) = '1' else STAGE1;
22
  STAGE3 <= STAGE2(11 downto 0) & "0000" when pos(2) = '1' else STAGE2;
23
  Y <= STAGE3(7 downto 0) & "00000000" when pos(3) = '1' else STAGE3;
24
25
end Behavioral;

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Nochwas zur Größe und Geschwindigkeit:

Die Kompakteste Variante (aus dem von LM ausgegrabenen Thread):
1
  process (a, pos) 
2
    variable m : integer;
3
    begin
4
      case pos is
5
        when "0000" => m := 1;
6
        when "0001" => m := 2;
7
        when "0010" => m := 4;
8
        when "0011" => m := 8;
9
        when "0100" => m := 16;
10
        when "0101" => m := 32;
11
        when "0110" => m := 64;
12
        when "0111" => m := 128;
13
        when "1000" => m := 256;
14
        when "1001" => m := 512;
15
        when "1010" => m := 1024;
16
        when "1011" => m := 2048;
17
        when "1100" => m := 4096;
18
        when "1101" => m := 8192;
19
        when "1110" => m := 16384;
20
        when others => m := 32768;
21
      end case;  
22
      y <= std_logic_vector(unsigned(a) * m);
23
    end process;
Number of Slices 9
Number of 4 input LUTs 16
Number of MULT18X18SIOs 1
S3A 12.868ns


Die vermeintlich schnellste aus dem vorgenannten Thread:
1
   Y <= std_logic_vector( shift_left(unsigned(A), to_integer(unsigned(pos))) );
Number of Slices 31
Number of 4 input LUTs 56
S3A 11.647ns


Das oben von mir gepostete Beispiel:
Number of Slices 32
Number of 4 input LUTs 58
S3A 11.475ns

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.