déplacement d'un vecteur logique std De N bit vers la droite ou la gauche
j'ai un vecteur signal tmp : std_logic_vector(15 downto 0)
j'ai pour le déplacer à gauche ou à droite de n bits. comment puis-je réaliser cette opération. Je pensais à une opération de concaténation mais je ne savais pas comment l'utiliser.
6 réponses
ieee.numeric_std
bibliothèque, et le type de vecteur pour les numéros que vous travaillez (unsigned
ou signed
).
Alors les opérateurs sont sla
/sra
pour les postes arithmétiques (c'est-à-dire remplir avec le signe bit sur les postes de droite et lsb sur les postes de gauche) et sll
/srl
pour les déplacements logiques (c'est-à-dire remplir avec '0').
vous passez un paramètre à l'opérateur pour définir le nombre de bits à maj:
A <= B srl 2; -- logical shift right 2 bits
mise à Jour:
Je n'ai aucune idée de ce que j'écrivais ci-dessus (Merci à Val de le souligner!)
bien sûr, la façon correcte de maj signed
et unsigned
types shift_left
et shift_right
fonctions définies dans ieee.numeric_std
.
décalage et de rotation des opérateurs sll
,ror
etc sont pour les vecteurs de boolean
,bit
ou std_ulogic
, et peut avoir il est intéressant de noter comportement inattendu en ce que les déplacements arithmétiques dupliquent le bit de fin même lors du déplacement à gauche.
Et bien plus encore, l'histoire peut être trouvé ici:
http://jdebp.eu./FGA/bit-shifts-in-vhdl.html
cependant, la réponse à la question initiale est toujours
sig <= tmp sll number_of_bits;
il y a deux façons d'y arriver. Fonctions de concaténation et de changement/rotation.
la concaténation est la façon "manuelle" de faire les choses. Vous spécifiez quelle partie du signal original vous voulez "conserver" et ensuite concaténer sur les données à une extrémité ou l'autre. Par exemple: tmp <= tmp (14 downto 0) & '0';
fonctions de décalage (logique, arithmétique): ce sont des fonctions génériques qui vous permettent de changer ou de tourner un vecteur dans de nombreuses façons. Les fonctions sont: sll (maj gauche de la logique), srl (décalage à droite logique). Un changement logique insère des zéros. Déplacements arithmétiques (sra/sla) insérez le plus à gauche ou le plus à droite, mais travaillez de la même façon que le déplacement logique. notez que pour toutes ces opérations vous spécifiez ce que vous voulez déplacer (tmp), et combien de fois vous voulez effectuer le déplacement ( n bits)
fonctions de rotation: rol (tourner à gauche), ror (tourner droit.) La rotation fait justement cela, le MSB se retrouve dans la LSB et tout se déplace à gauche (rol) ou l'inverse pour ror.
Voici un pratique de référence j'ai trouvé (voir la première page).
Personnellement, je pense que la concaténation est la meilleure solution. La mise en œuvre Générique serait
entity shifter is
generic (
REGSIZE : integer := 8);
port(
clk : in str_logic;
Data_in : in std_logic;
Data_out : out std_logic(REGSIZE-1 downto 0);
end shifter ;
architecture bhv of shifter is
signal shift_reg : std_logic_vector(REGSIZE-1 downto 0) := (others<='0');
begin
process (clk) begin
if rising_edge(clk) then
shift_reg <= shift_reg(REGSIZE-2 downto 0) & Data_in;
end if;
end process;
end bhv;
Data_out <= shift_reg;
Les deux seront implémentés comme des registres de changement. Si vous avez besoin de plus de registres de travail posté que vous n'êtes prêt à dépenser des ressources (par exemple en divisant 1000 nombres par 4), vous pourriez envisager d'utiliser une BRAM pour stocker les valeurs et un seul registre de travail posté pour contenir des "indices" qui donnent le déplacement correct de tous les nombres.
je suggèrent d'utiliser sll
ou srl
avec std_logic_vector.
pendant la simulation sll
m'a donné la valeur ' U ' pour ces bits, où je m'attendais à 0.
Utiliser shift_left()
,shift_right()
fonctions.
Par exemple:
OP1 : in std_logic_vector(7 downto 0);
signal accum: std_logic_vector(7 downto 0);
accum <= std_logic_vector(shift_left(unsigned(accum), to_integer(unsigned(OP1))));
accum <= std_logic_vector(shift_right(unsigned(accum), to_integer(unsigned(OP1))));
ceci est typiquement fait manuellement en choisissant les bits appropriés du vecteur et en ajoutant des 0s.
par exemple, pour déplacer un vecteur 8 bits
variable tmp : std_logic_vector(15 downto 0)
...
tmp := x"00" & tmp(15 downto 8);
espérons que cette réponse simple est utile à quelqu'un
add_Pbl <= to_stdlogicvector(to_bitvector(dato_cu(25 downto 2)) sll 1);
add_Pbl is a std_logic_vector of 24 bit
dato_cu is a std_logic_vector of 32 bit
tout d'abord, vous devez convertir le std_logic_vector
to_bitvector()
fonction
parce que la déclaration sll fonctionne avec la logique 1 et 0 bits.