在VHDL中设计组合移位运算符

时间:2012-10-16 00:23:13

标签: vhdl bit-shift

这是我的问题:我需要从头开始使用组合逻辑设计一个16位左/右逻辑/算术移位组件(除了使用std_logic_vector和std_logic)。

这就是我所拥有的:

library ieee;
use ieee.std_logic_1164.all;

entity Shift16 is
    port
    (
        -- Input ports
        I       : in std_logic_vector(15 downto 0);
        Shift   : in std_logic_vector(3 downto 0);

        -- Sel(1) == 0 -> Logical ; Sel(0) == Left
        Sel : in std_logic_vector(1 downto 0);

        -- Output ports
        O       : out std_logic_vector(15 downto 0)
    );
end Shift16;

architecture Struct of Shift16 is
component Mux16to1 is
    port (I :   in std_logic_vector(15 downto 0);
            S   :   in std_logic_vector(3 downto 0);
            O   :   out std_logic);
end component;

component Mux2to1_16 is
    port
    ( A, B : in  std_logic_vector(15 downto 0); S : in  std_logic;
      Q : out std_logic_vector(15 downto 0) );
end component;

signal OLeft, ORight : std_logic_vector(15 downto 0);

signal PadVal   : std_logic;

type gen_signal is array (15 downto 0) of std_logic_vector(15 downto 0);

signal leftPad, rightPad : gen_signal;

begin

    process (I, Sel)
    begin
        if (Sel(0) = '0') then -- logical
            PadVal <= '0';
        else 
            PadVal <= I(15); -- aritmetic
        end if;

        for j in 15 downto 0 loop
            for k in j downto 0 loop
                leftPad(j, k) <= I(15-j);
                rightPad(j, k) <= PadVal;
            end loop;

            for k in 15 downto j+1 loop 
                leftPad(j, k) <= PadVal;
                rightPad(j, k) <= I(15-j);
            end loop;
        end loop;
    end process;



    muxarr_left_shift: for index in 15 downto 0 generate
    begin  
        mux: Mux16to1 port map (leftPad(index), Shift, OLeft(index));
    end generate;

    muxarr_right_shift: for index in 15 downto 0 generate
    begin
        mux: Mux16to1 port map (rightPad(index), Shift, ORight(index));
    end generate;   

    OutputMux: Mux2to1_16 port map (ORight, OLeft, Sel(1), O);

end Struct;

Mux组件正是它们的样子,只是我的自定义版本。

我最初的想法是使用16个16对1多路复用器并将它们连接起来,因此移位量是每个的选择。这将非常快,但由于某种原因,代码无法编译。

我想我也过于复杂,我不知道我能做些什么来做得更好......

编译错误是:Error (10382): VHDL error at Shl16.vhd(52): index of object of array type gen_signal must have 1 dimensions

2 个答案:

答案 0 :(得分:1)

我认为你应该改变:

    for j in 15 downto 0 loop
        for k in j downto 0 loop
            leftPad(j, k) <= I(15-j);
            rightPad(j, k) <= PadVal;
        end loop;

        for k in 15 downto j+1 loop 
            leftPad(j, k) <= PadVal;
            rightPad(j, k) <= I(15-j);
        end loop;
    end loop;

    for j in 15 downto 0 loop
        for k in j downto 0 loop
            leftPad(j)(k) <= I(15-j);
            rightPad(j)(k) <= PadVal;
        end loop;

        for k in 15 downto j+1 loop
            leftPad(j)(k) <= PadVal;
            rightPad(j)(k) <= I(15-j);
        end loop;
    end loop;

因为你的类型声明。

type gen_signal is array (15 downto 0) of std_logic_vector(15 downto 0);

P / s:如果您想保持循环,请将类型更改为:

type gen_signal is array (15 downto 0, 15 downto 0) of std_logic;

但我认为它不适合您的portmap。所以,你应该使用上面的方法。我用Questasim 10.0b检查了第一个方法。

P / S(再次):我仔细阅读了您的代码并找到了:

process (I, Sel)

敏感列表可能不适合循环,除非您想要latch。我认为你应该分成两个过程。

答案 1 :(得分:0)

如下:

process (all) is
    variable shift_bits : integer;
begin
    shift_bits := to_integer(unsigned(shift));
    O <= (others => '0');            -- fill with padding first - stop latch
    if sel(0) = '1' then                 -- left shift
        O(O'high downto - O'high-shift_bits) <=
            I(shift_bits-1 downto 0);
    else                                 -- right shift
        if sel(1) = '1' then             -- if arithmetic
            O <= (others => I(I'high));  -- pad with sign bit
        end if;
        O(shift_bits-1 downto 0) <=
            I(I'high downto i'high-shift_bits);
    end if;
end process;

合成67 LUT6s


另一条评论 - 为什么没有明确定义控制位,所以你不必用评论来描述发生了什么:

entity Shift16 is
    port
    (
        I             : in std_logic_vector(15 downto 0);
        Shift_count   : in unsigned(3 downto 0);
        shift_logical : in std_logic;
        shift_right  : in std_logic;

        O       : out std_logic_vector(15 downto 0)
    );
end Shift16;