Universalschiebung Arithmetik rechts in VHDL
Frage
Ich bin der Gestaltung Universalschalt Rechenzeichen. Gibt es einen besseren Weg, es neben der Verwendung des 32-Bit-Multiplexer (Decoder) in einer Weise präsentiert unten zu erreichen?
ENTITY isra IS
PORT (
clk: in std_logic;
rst: in std_logic;
di: in std_logic_vector (31 downto 0);
sel: in std_logic_vector (31 downto 0);
res: out std_logic_vector (31 downto 0) := (others => '0')
);
END isra;
PROCESS
BEGIN
WAIT UNTIL clk'EVENT AND clk = '1';
IF rst = '1' THEN
res <= (others => '0');
ELSE
CASE sel IS
when X"00000001" => res <= to_stdlogicvector(to_bitvector(a) sra 1);
when X"00000002" => res <= to_stdlogicvector(to_bitvector(a) sra 2);
...
when X"0000001F" => res <= to_stdlogicvector(to_bitvector(a) sra 31);
when others => res <= (others => '0');
END CASE;
END IF;
END PROCESS;
Lösung
Verwenden Sie die Indizierung?
PROCESS
VARIABLE shift_count : INTEGER RANGE 0 TO 31;
BEGIN
IF rst = '1' THEN
res <= (others => '0');
ELSIF RISING_EDGE(clk) THEN
shift_count := to_integer(sel);
FOR I IN 0 TO 31 LOOP
IF I + shift_count < 32 THEN
res(I) <= din(I + shift_count);
ELSE
res(I) <= din(31); -- for logical shift right, use '0' instead
END IF;
END LOOP;
END IF;
END PROCESS;
Diese Version ist viel einfacher zu parametrieren in ein generisches.
Beachten Sie, dass VHDL eine Verhaltensbeschreibung ist, ist es kein Mux nicht angibt. Der Compiler kann verschiedene Designs erzeugen je nachdem, ob Sie bei der Optimierung für Größe, Geschwindigkeit, Pipelining ermöglichen, etc.
Beachten Sie, dass 5 2: 1-Mux: 1 Multiplexern dies in einem viel kleineren Bereich als eine einzelne 32 implementieren kann. Ist dies nicht der Block ist, dass Ihre Taktrate begrenzt, das auch sein mag vorzuziehen.
Beachten Sie auch, dass Ihr sel
Eingang viel zu breit ist, es braucht nur 5 Bits.
Andere Tipps
Sie können die SRA-Funktion nutzen, ohne Schleifen oder case-Anweisungen:
res <= to_stdlogicvector(to_bitvector(di) sra to_integer(sel));
Beachten Sie, dass Sie benötigen, um sel ein unsigned, kein std_logic_vector zu machen:
sel: in unsigned (31 downto 0);
Falls Sie das nicht möchten, können Sie immer noch sel in einen unsigned gegossen. Sie könnten auch zu uns brauchen numeric_bit:
use ieee.numeric_bit.all;
Well von einer Hardware-Sicht verschieben rechts in einem einzigen Takt, eine variable Anzahl von Positionen wird jedes Bit ein einzelner Flip-Flop mit einem von 32 möglichen Werten auf einer Auswahl basierten. Also von diesem Standpunkt aus betrachtet, das ist, wie Sie es tun.
Ich würde sel machen == 0 ein Fall und machen es zu einem Pass-Through, though. Logisch, dass mehr Sinn als alle Null Einstellung macht.