www.mikrocontroller.net

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


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Unnormaley (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_misc.all;
use IEEE.std_logic_signed.all;
use IEEE.numeric_std.all;

entity shifter is
  port (
    s : in std_logic_vector (4 downto 0);
    d : in std_logic_vector (31 downto 0);
    q : out std_logic_vector (31 downto 0)
  );
end shifter;

architecture behavior of shifter
begin
  process(s, d)
    variable const : Integer;
    variable temp : std_logic_vector(31 downto 0);
  begin
    const := conv_integer(s);
    temp := d;

    if const >= 1 and const <= 32 then
      for i in 1 to const loop
        temp := temp(30 downto 0) & '0'
      end loop;
    end if;

    q <= temp;
  end process;
end behavior;

Bitte um Tipps! :)

Autor: Sigi (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Such mal nach BarrelShifter.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite Flattr this
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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... ;-)

Autor: Tim T. (tim_taylor)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Nachfolgender Code ist zwar für einen 16-Bit Barrelshifter, aber das 
Prinzip sollte klar sein:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity BS_LSL is
  port (
    a   : in  STD_LOGIC_VECTOR (15 downto 0);
    pos : in  STD_LOGIC_VECTOR (3 downto 0);
    y   : out STD_LOGIC_VECTOR (15 downto 0)
  );
end BS_LSL;

architecture Behavioral of BS_LSL is

  signal STAGE1 : STD_LOGIC_VECTOR (15 downto 0);
  signal STAGE2 : STD_LOGIC_VECTOR (15 downto 0);
  signal STAGE3 : STD_LOGIC_VECTOR (15 downto 0);

begin

  STAGE1 <= A(14 downto 0) & "0" when pos(0) = '1' else A;
  STAGE2 <= STAGE1(13 downto 0) & "00" when pos(1) = '1' else STAGE1;
  STAGE3 <= STAGE2(11 downto 0) & "0000" when pos(2) = '1' else STAGE2;
  Y <= STAGE3(7 downto 0) & "00000000" when pos(3) = '1' else STAGE3;

end Behavioral;

Autor: Tim T. (tim_taylor)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Nochwas zur Größe und Geschwindigkeit:

Die Kompakteste Variante (aus dem von LM ausgegrabenen Thread):
  process (a, pos) 
    variable m : integer;
    begin
      case pos is
        when "0000" => m := 1;
        when "0001" => m := 2;
        when "0010" => m := 4;
        when "0011" => m := 8;
        when "0100" => m := 16;
        when "0101" => m := 32;
        when "0110" => m := 64;
        when "0111" => m := 128;
        when "1000" => m := 256;
        when "1001" => m := 512;
        when "1010" => m := 1024;
        when "1011" => m := 2048;
        when "1100" => m := 4096;
        when "1101" => m := 8192;
        when "1110" => m := 16384;
        when others => m := 32768;
      end case;  
      y <= std_logic_vector(unsigned(a) * m);
    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:
   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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net