将n位的std_logic_vector向右或向左移动

时间:2012-01-26 12:27:59

标签: vhdl

我有一个向量signal tmp : std_logic_vector(15 downto 0)

我必须将它移到n位左侧或右侧。我怎么才能实现这个操作。我想连接操作,但我不知道如何使用它。

6 个答案:

答案 0 :(得分:24)

使用ieee.numeric_std库以及您正在处理的数字(unsignedsigned)的相应矢量类型。

然后运算符为sla / sra用于算术移位(即在右移位上填充符号位,在左移位上填充lsb)和sll / srl用于逻辑移位(即填写'0'。

将参数传递给运算符以定义要移位的位数:

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

更新

我不知道我上面写的是什么(感谢Val指出这一点!)

当然,转换signedunsigned类型的正确方法是使用shift_left中定义的shift_rightieee.numeric_std函数。

移位和旋转运算符sllrorare for vectors of boolean, bit or std_ulogic,并且可以interestingly unexpected behaviour,因为即使向左移位,算术移位也会复制结​​束位。 / p>

此处可以找到更多历史记录:

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

然而,原始问题的答案仍然是

sig <= tmp sll number_of_bits;

答案 1 :(得分:16)

有两种方法可以实现这一目标。连接和移位/旋转功能。

  • 连接是&#34;手册&#34;做事的方式。你可以指定你想要的原始信号的哪个部分&#34;保持&#34;然后将数据连接到一端或另一端。例如: tmp&lt; = tmp(14 downto 0)&amp; &#39; 0&#39 ;;

  • 移位函数(逻辑,算术):这些是通用函数,允许您以多种方式移动或旋转向量。函数是:sll(向左移位逻辑),srl(向右移位逻辑)。逻辑移位插入零。算术位移(sra / sla)插入最左边或最右边的位,但工作方式与逻辑移位相同。 请注意,对于所有这些操作,您可以指定要移位的内容(tmp),以及要执行移位的次数( n 位)

  • 旋转功能:rol(向左旋转),ror(向右旋转)。旋转就是这样,MSB最终进入LSB,一切都向左移动(rol)或反过来为ror。

这是我找到的handy reference(见第一页)。

答案 2 :(得分:6)

就个人而言,我认为连接是更好的解决方案。通用实现将是

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;

两者都将实现为移位寄存器。如果您发现自己需要更多的移位寄存器而不是您愿意花费资源(EG将1000个数字除以4),您可以考虑使用BRAM来存储值,并使用单个移位寄存器来包含导致所有数字的正确移位。

答案 3 :(得分:4)

建议将sllsrl与std_logic_vector一起使用。

在模拟期间sll给了我&#39; U&#39;这些位的值,我预期的0。

使用shift_left()shift_right()个功能。

例如:

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

答案 4 :(得分:2)

这通常通过从向量中选择适当的位然后追加0来手动完成。

例如,将矢量移位8位

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

希望这个简单的答案对某人有用

答案 5 :(得分:0)

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

首先,您需要使用std_logic_vector函数转换to_bitvector() 因为sll语句使用逻辑1和0位。