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

Maz*_*zzy 19 vhdl

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

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

Mar*_*son 25

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

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

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

A <= B srl 2; -- logical shift right 2 bits
Run Code Online (Sandbox Code Playgroud)

更新:

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

当然,移位signedunsigned类型的正确方法是使用shift_left和中shift_right定义的函数ieee.numeric_std.

的移位和循环运算符sll,ror是用于向量boolean,bitstd_ulogic,并且可以具有有趣的是意外的行为,所述算术移位即使复制结束位左移时.

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

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

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

sig <= tmp sll number_of_bits;
Run Code Online (Sandbox Code Playgroud)

  • @Mazzy不要使用该库.它实际上不是标准IEEE并且已被弃用. (4认同)
  • @marpangal:对我来说,VHDL*是*VHDL 2008,已经有近十年了.如果你遇到旧工具,我会道歉,但我对它们的处理方式非常"过时". (2认同)

Jos*_*osh 16

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

  • 连接是"手动"的做事方式.您可以指定要"保留"原始信号的哪一部分,然后将数据连接到一端或另一端.例如:tmp <= tmp(14 downto 0)&'0';

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

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

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


Pau*_*eeb 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;
Run Code Online (Sandbox Code Playgroud)

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

  • 我很好奇...为什么你说concatentation比使用标准定义的函数更好? (3认同)

Ram*_*ich 6

建议使用sllsrl与 std_logic_vector一起使用。

在模拟过程中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))));
Run Code Online (Sandbox Code Playgroud)


iyo*_*p45 6

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

例如,将向量移位 8 位

variable tmp : std_logic_vector(15 downto 0)
...
tmp := x"00" & tmp(15 downto 8);
Run Code Online (Sandbox Code Playgroud)

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