tipos srr sll shift_left rol right left example datos vhdl

vhdl - srr - Desplace un std_logic_vector de n bit a derecha o izquierda



vhdl rol example (6)

Esto normalmente se hace manualmente eligiendo los bits apropiados del vector y luego agregando 0s.

Por ejemplo, para desplazar un vector de 8 bits.

variable tmp : std_logic_vector(15 downto 0) ... tmp := x"00" & tmp(15 downto 8);

Esperemos que esta simple respuesta sea útil para alguien.

Tengo una signal tmp : std_logic_vector(15 downto 0) vectorial signal tmp : std_logic_vector(15 downto 0)

Tengo que cambiarlo a izquierda o derecha de n bit. ¿Cómo puedo realizar esta operación? Pensé en la operación de concatenación pero no sabía cómo usarla.


Hay dos maneras en que puede lograr esto. Concatenación, y funciones de cambio / rotación.

  • La concatenación es la forma "manual" de hacer las cosas. Usted especifica qué parte de la señal original desea "mantener" y luego concatenar datos en uno u otro extremo. Por ejemplo: tmp <= tmp (14 downto 0) & ''0'';

  • Funciones de cambio (lógicas, aritméticas): son funciones genéricas que le permiten cambiar o rotar un vector de muchas maneras. Las funciones son: sll (shift left logic), srl (shift right logic). Un cambio lógico inserta ceros. Los cambios aritméticos (sra / sla) insertan el bit más a la izquierda o más a la derecha, pero funcionan de la misma manera que el cambio lógico. Tenga en cuenta que para todas estas operaciones, especifique qué desea cambiar (tmp) y cuántas veces desea realizar el cambio ( n bits)

  • Funciones de rotación: rol (girar a la izquierda), ror (girar a la derecha). La rotación hace precisamente eso, el MSB termina en el LSB y todo se desplaza a la izquierda (rol) o al revés para ror.

Aquí hay una referencia útil que encontré (vea la primera página).


No sugeriría usar sll o srl con std_logic_vector.

Durante la simulación, sll me dio un valor de ''U'' para esos bits, donde esperaba 0.

Usa las shift_left() , shift_right() .

Por ejemplo:

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))));


Personalmente, creo que la concatenación es la mejor solución. La implementación genérica sería

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;

Ambos se implementarán como registros de desplazamiento. Si necesita más registros de turnos de los que está dispuesto a gastar recursos (por ejemplo, dividir 1000 números por 4), podría considerar usar un BRAM para almacenar los valores y un solo registro de turnos para contener "índices" que resulten en el Cambio correcto de todos los números.


Use la biblioteca ieee.numeric_std y el tipo de vector apropiado para los números en los que está trabajando ( unsigned o con signed ).

Luego, los operadores son sla / sra para los cambios aritméticos (es decir, rellenar con el bit de signo en los desplazamientos a la derecha y lsb en los desplazamientos a la izquierda) y sll / srl para los cambios lógicos (es decir, rellenar con ''0'').

Pasa un parámetro al operador para definir el número de bits a desplazar:

A <= B srl 2; -- logical shift right 2 bits

Actualizar:

No tengo idea de lo que estaba escribiendo arriba (¡gracias a Val por señalarlo!)

Por supuesto, la forma correcta de cambiar los tipos con unsigned y unsigned es con las funciones shift_left y shift_right definidas en ieee.numeric_std .

Los operadores shift y sll , ror , etc. son para vectores de boolean , bit o std_ulogic , y pueden tener un comportamiento interesante inesperado en el sentido de que los cambios aritméticos duplican el bit final incluso cuando se desplaza a la izquierda.

Y mucha más historia se puede encontrar aquí:

http://jdebp.eu./FGA/bit-shifts-in-vhdl.html

Sin embargo, la respuesta a la pregunta original es todavía

sig <= tmp sll number_of_bits;


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

Primero, necesita convertir el std_logic_vector con la función to_bitvector() porque la sentencia sll funciona con la lógica 1 y 0 bits.