将n位的std_logicvector向右或向左移位



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

我必须把它移到n位的左边或右边。我怎样才能实现这个操作。我想过串联操作,但我不知道如何使用它。

使用ieee.numeric_std库,并为正在处理的数字使用适当的矢量类型(unsignedsigned)。

然后运算符是算术移位的"sla"/"sra"(即右移时用符号位填充,左移时用lsb填充)和逻辑移位的"sll"/"srl"(即用"0"填充)。

您将一个参数传递给操作员,以定义要移位的位数:

A <= B srl 2; -- logical shift right 2 bits
---更新:---我不知道我在上面写什么(感谢瓦尔指出这一点!)

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

移位和旋转运算符sllror等用于booleanbitstd_ulogic的向量,并且可能具有有趣的意外行为,因为即使在向左移位时,算术移位也会复制结束位。

更多的历史可以在这里找到:

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

然而,最初问题的答案仍然是

sig <= tmp sll number_of_bits;

有两种方法可以实现这一点。连接和移位/旋转函数。

  • 串联是一种"手动"的做事方式。指定要"保留"原始信号的哪一部分,然后将数据连接到一端或另一端。例如:tmp<=tmp(14下降到0)&'0'

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

  • 旋转功能:rol(向左旋转),ror(向右旋转)。旋转正是这样做的,MSB最终在LSB中,所有东西都向左移动(rol)或以其他方式移动ror。

这是我找到的一个方便的参考资料(见第一页)。

我不建议将sllsrl与std_logic_vvector一起使用。

在模拟过程中,sll给了我这些比特的"U"值,我预期为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))));

就我个人而言,我认为串联是更好的解决方案。一般实施方式为

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;

两者都将作为移位寄存器实现。如果你发现自己需要比你愿意花费资源更多的移位寄存器(例如,将1000个数字除以4),你可以考虑使用BRAM来存储值,使用单个移位寄存器来包含"索引",从而使所有数字正确移位。

这通常是手动完成的,方法是从矢量中选择适当的位,然后追加0。

例如,要将矢量移位8位

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

希望这个简单的答案对

有用
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

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

最新更新