2012-10-16 31 views
3

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

以下是我有:

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的Muxs并将它​​们连接起来,这样移位量就是每个Mone的选择。这会非常快,但由于某些原因代码不能编译。

我想我也过于复杂这一点,我不知道我能做些什么做的更好..

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

回答

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; 

但我不认为这是适合你的端口映射。所以,你应该使用上面的方法。我使用Questasim 10.0b检查了第一种方法。

P/S(再次):我仔细看了你的代码,发现:

process (I, Sel) 

敏感所列内容可能不适合循环,除非你想latch。我认为你应该分成2个进程。

+0

您的解决方案工作,但我怀疑这是一个优雅的。你的P.P.S.是什么意思?我现在正在学习VHDL。 – Nava2

+0

@ Nava2:我的意思是你应该关注过程的敏感列表(决定过程的种类)。在组合,触发器和锁存器之间存在很大的差异行为。我认为你想要一个组合过程就在这里(只是AND或NOT XOR等),那么你应该更新你的敏感列表,充满信号驱动正在进行。您错过了'PadVal',但是'PadVal'正在处理中。你应该分成2个进程:驱动'PadVal'并驱动'LeftVal'和'RightVal'。 – Khanh

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; 

Synthesises 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; 
+0

这样做的问题是移位是通过使用非常量值的数组操作完成的。它吐出来:'错误(10779):Shl16.vhd(36)处的VHDL错误:表达式不是常量'。 这是有道理的.. – Nava2

+0

啊 - 你想合成它...你可能需要一个更好的编译器来合成这段代码。没有任何内在的不可合成的东西。我刚刚在Synplify中尝试过它,它没问题(发现了一些功能错误的功能,因此更新了代码) –

+0

更新代码以删除锁存器并进行正确的逻辑转换实际上是做了一些事情! –