【问题标题】:shift a std_logic_vector of n bit to right or left将 n 位的 std_logic_vector 向右或向左移动
【发布时间】:2012-02-19 13:04:12
【问题描述】:

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

我必须将它移到 n 位的左侧或右侧。我怎样才能实现这个操作。想串联操作,不知道怎么用。

【问题讨论】:

    标签: vhdl


    【解决方案1】:

    建议将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))));
    

    【讨论】:

      【解决方案2】:

      使用ieee.numeric_std 库和适合您正在处理的数字的向量类型(unsignedsigned)。

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

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

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

      更新:

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

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

      移位和循环运算符sllrorare for vectors of boolean, bit or std_ulogicinterestingly unexpected behaviour 是因为即使向左移位,算术移位也会复制结​​束位。

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

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

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

      sig <= tmp sll number_of_bits;
      

      【讨论】:

      • 我在 ieee.std_logic_arith 库中找到了函数 shr 和 shl 来进行移位操作
      • @Mazzy 不要使用那个库。它实际上不是标准的 IEEE 并且已被弃用。
      • 我有一些工具不允许这些函数用于大于 32 位的向量,并且必须进行手动移位和连接(在其他答案中有介绍)。
      • 这仅适用于 VHDL2008。你能为 VHDL 推荐一些东西吗?
      • @marpangal:对我来说,VHDL VHDL 2008,并且已经有近十年的历史了。如果您被旧工具卡住了,我深表歉意,但我对如何处理它们非常“过时”。
      【解决方案3】:

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

      例如,将向量移动 8 位

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

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

      【讨论】:

        【解决方案4】:
        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 位。

        【讨论】:

          【解决方案5】:

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

          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 来存储值并使用单个移位寄存器来包含“索引”,从而导致所有数字的正确移位。

          【讨论】:

          • 我很好奇...为什么你说连接比使用标准定义的函数更好?
          • 这可能是我太天真了,但是当我以前用 VHDL 编程时,我在使用那些特定的内置函数时遇到了很多麻烦。在错误类型上使用内置插件可能会造成混淆(尽管我现在无法对此进行测试以验证)。我的猜测是这些内置函数在标准逻辑向量上效果不佳。
          【解决方案6】:

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

          • 串联是“手动”的做事方式。您指定要“保留”原始信号的哪一部分,然后将数据连接到一端或另一端。例如:tmp

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

          • 旋转函数:rol(向左旋转)、ror(向右旋转)。旋转就是这样做的,MSB 最终在 LSB 中,一切都向左移动 (rol) 或相反的 ror。

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

          【讨论】:

          • 我尝试使用移位功能,但收到错误:Overloaded Operator srl 与其参数配置文件不匹配
          • 我正在使用 ieee.numeric_std,ieee.numberic_bit,ieee.std_logic_unsigned
          • 我尝试使用 ieee.numeric_std,ieee.numeric_bit,ieee.std_logic_unsigned 和 ieee.std_logic_signed 但在我的体系结构中我实现了求和运算并且收到错误无法解决重载,因为它是歧义
          • 编辑您的问题并在无效的代码 sn-p 中发布。
          猜你喜欢
          • 1970-01-01
          • 2013-02-14
          • 2012-11-26
          • 1970-01-01
          • 2019-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-13
          相关资源
          最近更新 更多