2012-10-16 59 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

更新代碼以刪除鎖存器並進行正確的邏輯轉換實際上是做了一些事情! –