Datum:
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! :)
Datum:
Such mal nach BarrelShifter.
Datum:
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... ;-)
Datum:
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; |
Datum:
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
