Question

Je suis la conception opérateur arithmétique de décalage universel. Y at-il une meilleure façon d'y parvenir en plus d'utiliser le multiplexeur 32 bits (décodeur) d'une manière présentée ci-dessous?

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;
Était-ce utile?

La solution

Utilisez l'indexation?

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;

Cette version est beaucoup plus facile à paramétrer dans un générique.

Rappelez-vous que VHDL est une description du comportement, il ne précise pas MUX. Le compilateur peut générer des modèles différents selon que vous optimisez la taille, la vitesse, laissez pipelining, etc.

Notez que 5 2: 1 muxes peuvent mettre en œuvre ce dans une zone beaucoup plus petite qu'un seul 32: 1 MUX. Si ce n'est pas le bloc qui limite votre fréquence d'horloge, qui pourrait être préférable.

Notez également que votre entrée est sel beaucoup trop, il n'a besoin que d'être 5 bits.

Autres conseils

Vous pouvez utiliser la fonction sans boucles SRA ou déclarations de cas:

res <= to_stdlogicvector(to_bitvector(di) sra to_integer(sel));

Notez que vous devez faire un sel non signé, pas std_logic_vector:

sel: in unsigned (31  downto 0);

Si vous ne voulez pas, vous pouvez toujours jeter dans un sel non signé. Vous nous avez aussi besoin numeric_bit:

use ieee.numeric_bit.all;

Eh bien d'un point de vue matériel, de décalage vers la droite dans une seule horloge un nombre variable de positions, chaque bit est une bascule unique avec l'un des 32 valeurs possibles en fonction de la sélection. De ce point de vue, voici comment vous le faites.

Je ferais == 0 sel un cas et en faire un passthrough, cependant. Logiquement, cela a plus de sens que de mettre tout à zéro.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top