簡體   English   中英

在VHDL ALU中進行借/借

[英]Carry/Borrow in VHDL ALU

我正在VHDL中制作通用的N位ALU。 我在分配加法或減法借用進位值時遇到麻煩。 我嘗試了以下方法:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL; 

entity alu is
    generic(n: integer :=1); --Default to 1
    port (
        a : in std_logic_vector(n-1 downto 0);
        b : in std_logic_vector(n-1 downto 0);
        op : in std_logic_vector(1 downto 0);
        output : out std_logic_vector(n-1 downto 0);
        carryborrow: out std_logic 
    );
end alu;

architecture Behavioral of alu is
    signal result: std_logic_vector(n downto 0); 
begin
process( a, b, op )
begin
    case op is
    when "00" => 
        result(n) <= '0'; 
        result(n-1 downto 0) <= a and b; --and gate 
        output <= result(n-1 downto 0); 
        carryborrow <= '0'; 
    when "01" => 
        result(n) <= '0'; 
        result(n-1 downto 0) <= a or b; --or gate 
        output <= result(n-1 downto 0); 
        carryborrow <= '0'; 
    when "10" => 
        result(n) <= '0'; 
        result(n-1 downto 0) <= std_logic_vector(signed(a) + signed(b)); --addition
        output <= result(n-1 downto 0); 
        carryborrow <= result(n); 
    when "11" => 
        result(n) <= '0';
        result(n-1 downto 0) <= std_logic_vector(signed(a) - signed(b)); --subtraction
        output <= result(n-1 downto 0); 
        carryborrow <= result(n); 
    when others => 
        NULL; 
    end case; 

end process;

end Behavioral;

這似乎將carryborrowcarryborrow位設置為始終為0。如何將其分配給應該沒有類型錯誤的內容?

您的代碼中有錯誤:

i)您沒有考慮到信號不會立即更新的事實。 因此,以下幾行將不符合您的預期:

    result(n) <= '0'; 
    result(n-1 downto 0) <= a and b; --and gate 
    output <= result(n-1 downto 0); 

取而代之的是,您需要將驅動outputcarryborrow借位的線放在組合過程之外,如下所示。 ii)假設您希望此代碼是可綜合的,只需將NULL放入always分支中將導致推斷出鎖存器。 您還需要在other分支中驅動result

因此,假設您的進位輸出如何與andor運算相符,這就是我編寫代碼的方式:

architecture Behavioral of alu is
    signal result: std_logic_vector(n downto 0); 
begin
process( a, b, op )
begin
    case op is
    when "00" => 
        result <= '0' & (a and b); --and gate 
    when "01" => 
        result <= '0' & (a or b); --or gate 
    when "10" => 
        result <= std_logic_vector(resize(signed(a), n+1) + resize(signed(b), n+1)); --addition
    when "11" => 
        result <= std_logic_vector(resize(signed(a), n+1) - resize(signed(b), n+1)); --subtraction
    when others => 
        result <= (others => 'X');
    end case; 
  end process;

  output <= result(n-1 downto 0); 
  carryborrow <= result(n); 

end Behavioral;

我通常這樣做:

result <= std_logic_vector(signed(a(n-1) & a) + signed(b(n-1) & b));
result <= std_logic_vector(signed(a(n-1) & a) - signed(b(n-1) & b));

當結果加長一位時,請擴展符號,然后進行操作以防止溢出。

嗯,在4位環境中考慮這個問題,例如a="0101"b="1001" 添加它們應得到output="1110" ,不帶進位。

但是,以resize(signed(a), n+1)resize(signed(b), n+1)擴展的resize(signed(a), n+1)將設置a="00101"b="11001" ,從而設置result="11110"和進位carryborrow='1' ,這是錯誤的!

通過符號擴展向量ab ,數字范圍已增加到5位,因此result必須是6位才能保持進位,然后回到平方。 向量ab只能進行零擴展,即在將它們添加到result之前為'0' & a'0' & b ,然后carryborrowcarryborrow位作為result MSB(最高有效位)將獲得正確的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM