VHDL ALU中的进位/借位

VHDL ALU中的进位/借位,vhdl,add,alu,Vhdl,Add,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 :

我正在用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;
IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.NUMERIC_STD.ALL;
实体alu是
泛型(n:整数:=1)--默认为1
港口(
a:在标准逻辑向量中(n-1向下至0);
b:标准逻辑向量(n-1到0);
op:标准逻辑向量(1到0);
输出:输出标准逻辑向量(n-1向下至0);
carryborrow:out std_逻辑
);
末端alu;
alu的体系结构是
信号结果:标准逻辑向量(n到0);
开始
流程(a、b、op)
开始
案例op是
当“00”=>
结果(n)I通常这样做:

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));
result我通常会这样做:

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));

result您的代码中有错误:

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;
i) 您没有考虑到信号不会立即更新这一事实。因此,以下几行不会如我所想的那样:

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

您的代码中存在错误:

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;
i) 您没有考虑到信号不会立即更新这一事实。因此,以下几行不会如我所想的那样:

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

HMM,在4位环境中考虑这一点,例如“代码> A=“0101”<代码>和<代码> B=“1001”< /代码>。添加它们将得到无进位的

输出=“1110”

但是,使用
resize(带符号的(a),n+1)
resize(带符号的(b),n+1)
扩展符号将设置
a=“00101”
b=“11001”
,从而设置
result=“11110”
carryborrow=“1”
,这是错误的

通过符号扩展向量
a
b
,数字范围增加到了5位,因此
结果
需要6位才能保持进位,我们回到了平方一。
向量<代码> a <代码> >代码> b <代码>应仅为零扩展,即<代码> >代码>和<代码> '0'和b<代码>,然后将它们添加到<代码>结果< /代码>,然后<代码> CuyRoo< <代码>,作为<代码>结果> <代码>的MSB(最高有效位),将得到正确的值。

< P> HMM,在4位环境中考虑这一点,例如“代码> A=“0101”
b=“1001”
。添加它们将给出
输出=“1110”
,不带进位

但是,使用
resize(带符号的(a),n+1)
resize(带符号的(b),n+1)
扩展符号将设置
a=“00101”
b=“11001”
,从而设置
result=“11110”
carryborrow=“1”
,这是错误的

通过符号扩展向量
a
b
,数字范围增加到了5位,因此
结果
需要6位才能保持进位,我们回到了平方一。
向量
a
b
只能进行零扩展,即
'0'&a
'0'&b
在添加到
结果之前,然后
carryborrow
,因为
结果的MSB(最高有效位)
将获得正确的值。

考虑从头到尾读取二进制有符号的数字(2'sC)易受溢出的符号位的影响。你的意思是做无符号运算吗?@ USER 1155120,那么我不应该把我的向量转换成<代码>签名< /代码>,对吗?我错过了你的测试台。测试你的代码通常是走的路:它告诉你出了什么问题。考虑一遍遍历。二进制符号num。贝尔斯(2'sC)很容易因携带符号位而溢出。你的意思是做无符号算术吗?@user1155120所以我不应该将向量转换为有符号的,对吗?我缺少你的测试平台。测试你的代码通常是一种方法:它会告诉你出了什么问题。这会导致一个错误:
错误,在ex中键入error按
@saratibetts或您可以使用
numeric_std
中的
resize
功能,该功能对
有符号的
类型执行相同的操作,但也可以正确扩展
无符号的
类型。即
结果这会导致错误:
错误,表达式中的类型错误
@saratibetts或您可以使用
numeric_std
中的de>resize
函数,它对
有符号的
类型执行相同的操作,但也正确地扩展了
无符号的
类型。ie
结果你好,RackHam,欢迎使用SO。我无法真正验证您的答案,但我可以请您尝试整理一下。它将从一些格式设置中受益,使其更简单r阅读!你好,RackHam,欢迎来到SO。我不能真正验证你的答案,但我可以请你尝试整理一下。这将得益于一些格式设置,使其更易于阅读!