Vhdl 如何设计带有单独进位和借位标志的简单加法器?

Vhdl 如何设计带有单独进位和借位标志的简单加法器?,vhdl,alu,Vhdl,Alu,我正在实现一个简单的加法器。然而,我有一个独特的扭转位的需要 我要实现的是跨代码段(CS)寄存器和指令指针(IP)寄存器的“滚动”功能。所以,当你做一个+20的相对跳跃时,IP是254,IP将滚动到18,CS将增加1 这部分容易,难的部分则相反。当检测到一个借位时,比如跳转为-20,IP为0,它需要将CS减少1,使IP滚动到236 到目前为止,我的代码是 entity carryover is port( DataIn: in std_logic_vector(7 downto 0

我正在实现一个简单的加法器。然而,我有一个独特的扭转位的需要

我要实现的是跨代码段(CS)寄存器和指令指针(IP)寄存器的“滚动”功能。所以,当你做一个+20的相对跳跃时,IP是254,IP将滚动到18,CS将增加1

这部分容易,难的部分则相反。当检测到一个借位时,比如跳转为-20,IP为0,它需要将CS减少1,使IP滚动到236

到目前为止,我的代码是

entity carryover is 
  port(
    DataIn: in std_logic_vector(7 downto 0);
    SegmentIn: in std_logic_vector(7 downto 0);
    Addend: in std_logic_vector(7 downto 0); --How much to increase DataIn by (as a signed number). Believe it or not, that's the actual word for what we need.
    DataOut: out std_logic_vector(7 downto 0);
    SegmentOut: out std_logic_vector(7 downto 0);
   );
end carryover;

architecture Behavioral of carryover is
  signal temp: std_logic_vector(8 downto 0);
begin
  --treat as unsigned because it doesn't actually matter for addition and just make carry and borrow correct
  temp <= std_logic_vector(unsigned("0" & DataIn) + (unsigned)Addend);
  DataOut <= temp(7 downto 0);
  SegmentOut <= unsigned(SegmentIn) + 1 when (not temp(8)) and (not Addend(7) 

end Behavioral;
实体结转为
港口(
数据输入:标准逻辑向量(7到0);
SegmentIn:标准逻辑向量(7到0);
加数:在std_logic_vector(7到0);--增加多少数据(作为一个有符号的数字)。信不信由你,这就是我们需要的实际单词。
数据输出:输出标准逻辑向量(7到0);
分段输出:输出标准逻辑向量(7到0);
);
端部结转;
结转的结构是
信号温度:标准逻辑向量(8到0);
开始
--将其视为未签名,因为它实际上与加法无关,只需使进位和借位正确即可

当总和符号位等于但不等于总和符号位时,会发生temp溢出:

A = + 12, B = + 4.            A = + 4, B = – 12
А = 0.1100                    A = 0.0100
В = 0.0100                    B = 1.0100
    ------                        ------   
C   1.0000                    C   1.1000
As = Bs, Cs = 1 – overflow    As != Bs - not overflow.
由于
DateIn
始终为正数,因此只能使用进位(对于两个正数)发生溢出。因此,您应该将您的声明更改为(并可能以某种方式将这两者结合起来):

编辑:正如Paul Seeb所说:

SegmentOut <= unsigned(signed(SegmentIn) + signed(Addend(7) & Addend(7) & Addend(7) & Addend(7) & Addend(7) & Addend(7) & Addend(7) & "1")) when (temp(7) and CarryFlag); 

SegmentOut当总和符号位等于但不等于总和符号位时发生溢出:

A = + 12, B = + 4.            A = + 4, B = – 12
А = 0.1100                    A = 0.0100
В = 0.0100                    B = 1.0100
    ------                        ------   
C   1.0000                    C   1.1000
As = Bs, Cs = 1 – overflow    As != Bs - not overflow.
由于
DateIn
始终为正数,因此只能使用进位(对于两个正数)发生溢出。因此,您应该将您的声明更改为(并可能以某种方式将这两者结合起来):

编辑:正如Paul Seeb所说:

SegmentOut <= unsigned(signed(SegmentIn) + signed(Addend(7) & Addend(7) & Addend(7) & Addend(7) & Addend(7) & Addend(7) & Addend(7) & "1")) when (temp(7) and CarryFlag); 

SegmentOut当你说“clean”时,你是指按位检查吗?此外,如果您计划进行负跳跃,您可能需要切换到有符号算术,以确保解释器理解可能发生的加法和减法。我相信这对于if语句来说是非常简单的,但我不认为这是您正在寻找的“干净”解决方案。当您说“干净”时,您是指按位检查吗?此外,如果您计划进行负跳跃,您可能需要切换到有符号算术,以确保解释器理解可能发生的加法和减法。我相信这对于if语句来说是非常简单的,但我不认为这是您正在寻找的“干净”解决方案。您可以通过使用有符号算术和更改是加1还是负1,并将答案转换为无符号值,将这两个语句“合并”为一个加法器/减法器。@PaulSeeb谢谢。编辑了我的答案。但我们为什么要使用符号算术呢?我不明白。我使用了稍微修改过的代码版本(难道你不应该使用temp(8)而不是temp(7)?),但是SegmentOut仍然没有改变。请看更新我的问题,不管我最终发现我的测试代码是错误的0x10+(-12)而不是0x10+(-0x12):)唯一比愚蠢的错误更糟糕的是,我在我的测试中多次这样做career@Earlz您应该分析和符号,但不能从符号位进位<代码>温度(8)
-是进位,
温度(7)
是符号。您的代码之所以有效,是因为您测试了0x10和-0x12,但如果您尝试了0x7F和0x7F,则无法工作。您可以使用有符号算术,通过更改是加1还是负1,并将答案转换为无符号值,将这两条语句“合并”为一个加法器/减法器。@PaulSeeb谢谢。编辑了我的答案。但我们为什么要使用符号算术呢?我不明白。我使用了稍微修改过的代码版本(难道你不应该使用temp(8)而不是temp(7)?),但是SegmentOut仍然没有改变。请看更新我的问题,不管我最终发现我的测试代码是错误的0x10+(-12)而不是0x10+(-0x12):)唯一比愚蠢的错误更糟糕的是,我在我的测试中多次这样做career@Earlz您应该分析和符号,但不能从符号位进位<代码>温度(8)
-是进位,
温度(7)
是符号。您的代码之所以能够工作,是因为您测试了0x10和-0x12,但如果您尝试了0x7F和0x7F,则不会工作。
SegmentOut <= unsigned(signed(SegmentIn) + signed(Addend(7) & Addend(7) & Addend(7) & Addend(7) & Addend(7) & Addend(7) & Addend(7) & "1")) when (temp(7) and CarryFlag);