如何使用右移位器实现左移位器?

时间:2014-11-03 11:41:54

标签: vhdl bit-shift logical-operators bluespec

我使用5级多路复用器(Shift1 / 2/4/8/16)实现了右移位器(32位)。我的问题是如何扩展我的实现以使用最少的额外硬件实现Left Shifter?

2 个答案:

答案 0 :(得分:0)

左移可以使用右移通过反转参数向量,右移,然后反转结果,因此:

shift_left(arg, n) = reverse(shift_right(reverse(arg), n))

可以在reverse_any_vector中找到std_logic_vector的反转功能。

答案 1 :(得分:0)

为了避免这个不是编程的想法,也不清楚这个问题是不是一个示范。为了与标签保持一致,VHDL是一种用于模拟和合成硬件的硬件建模语言。该问题中提到的五个多路复用器对于本领域技术人员来说足以用VHDL实现。

这主要表明的是,有人应该非常小心你使用哪个标签,非VHDL熟悉的程序员比熟悉VHDL的人更多。在这个答案中,有两个非常接近的投票,一个是关于主题(不是关于编程),另一个是关于不清楚的问题。

示例(以VHDL格式):

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;   -- for stimulus, 2's complement

entity barrel_shft is
end entity;

architecture foo of barrel_shft is
    signal inp_val:        std_logic_vector (31 downto 0) := X"feedface";
    signal shift:          std_logic_vector (4 downto 0)  := (others => '0');
    signal M1,M2,M3,M4:    std_logic_vector (31 downto 0);
    signal shft:           std_logic_vector (4 downto 0);
    signal reverse:        std_logic := '0';
    signal result:         std_logic_vector (31 downto 0);

begin

    shft <=   shift when reverse = '0' else
              std_logic_vector ( unsigned (not shift) + 1); -- 2's Complement
BS1:
    M1  <=    inp_val(0)  & inp_val (31 downto 1)  when shft(0) = '1' else
              inp_val;
BS2:    
    M2 <=     M1 (1 downto 0)  & M1 (31 downto 2)  when shft(1) = '1' else
              M1;
BS4:
    M3 <=     M2 (3 downto 0)  & M2 (31 downto 4)  when shft(2) = '1' else
              M2;
BS8:
    M4 <=     M3 (7 downto 0)  & M3 (31 downto 8)  when shft(3) = '1' else
              M3;
BS16:
    result <= M4 (15 downto 0) & M4 (31 downto 16) when shft(4) = '1' else
              M4;

STIMULUS:
    process
    begin
        for i in 0 to 63 loop
            if i = 32 then
                reverse <= '1';
            end if;
            wait for 10 ns;
            shift <= std_logic_vector(unsigned(shift) + 1);
        end loop;
        wait for 10 ns;
        wait;
    end process;
end architecture;

32位桶形移位器可由5个2:1多路复用器组成。您可以为每个多路复用器阶段编写3:1多路复用器表达式,尽管重新设计移位索引可能会节省硬件。双补码包括反转输入和加1,增量是一个下放的加法,其中大部分B输入为零。合成软件现在倾向于为您提供最小化的实现。

此示例使用信号reverse表示应执行左移,其中移位距离被转换为它的二进制补码值。在任何一种情况下,移位距离都通过shft传送到五个多路复用器,其中每个多路复用器使用基于shft的适当位的2移位距离的功率。

下面的波形捕获以从右移到左移的过渡为中心,由reverse表示转到'1'。显示此转换是因为波形被放大并且前一个右移镜像,而完整的缩放不会显示结果的值。

左移一个相当于右移31.(32位桶形移位器的移位范围为0到31十进制)。

barrel_shft transistion reverse = '1'

可以点击波形图像打开

对于任何其他32位模式,可以更改示例实现输入值inp_val

实施由读者自行决定。为了避免混淆,VHDL代表VHSIC硬件描述语言, Verilog与标签相关联,有时也称为HDL或Verilog HDL。你是一个名副其实的迷宫式标签,不太相似。

我认为这种方法(使用左移的移位值的两个补码)应该小一些,以反转五个多路复用堆栈的两端(32位输入,32位输出)在莫滕的回答中推断出来。反向本身就是导线,反向选择涉及两个32位2:1多路复用器,在右移和左移之间进行选择时。这两个补充所需的资源少于此。

以下显示了两个补码实现的门级表示。请注意,它将适合4个LUT(最大的6个输入)。

-- shft <=   shift when reverse = '0' else
--           std_logic_vector ( unsigned (not shift) + 1); -- 2's Compliment

shft(0) <= shift(0);
shft(1) <= not shift(1) xor  not shift(0) when reverse = '1' else 
           shift(1);
shft(2) <= not shift(2) xor (not shift(0) and not shift(1)) when reverse = '1' else
           shift(2);
shft(3) <= not shift(3) xor (not shift(0) and not shift(1) and not shift(2)) when reverse = '1' else 
           shift(3);
shft(4) <= not shift(4) xor (not shift(0) and not shift(1) and not shift(2) and not shift(3)) when reverse = '1' else
           shift(4);

(这是通过知道增量看起来是手工编码的。)