我正在实施一个简单的加法器。但是,我需要一点点独特的转折。
我正在实现的是代码段(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;
但我无法弄清楚如何检测借款。有干净的方法吗?
更新
我的新代码是:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.tinycpu.all;
entity carryover is
port(
EnableCarry: in std_logic; --When disabled, SegmentIn goes to SegmentOut
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)
-- Debug: out std_logic_vector(8 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
process(DataIn, SegmentIn,Addend, EnableCarry)
begin
temp <= std_logic_vector(signed('0' & DataIn) + signed(Addend(7) & Addend));
if (EnableCarry and ((not Addend(7)) and (DataIn(7)) and temp(8)))='1' then
SegmentOut <= std_logic_vector(unsigned(SegmentIn)+1);
elsif (EnableCarry and (Addend(7) and (not DataIn(7)) and temp(8)))='1' then
SegmentOut <= std_logic_vector(unsigned(SegmentIn)-1);
else
SegmentOut <= SegmentIn;
end if;
end process;
--Debug <= Temp;
DataOut <= temp(7 downto 0);
end Behavioral;
添加已签名的数字按计划工作,Temp现在始终是正确的结果,但SegmentOut始终等于SegmentIn。我不明白为什么因为SegmentIn + 1
,我实际上手工计算了Addend = 0x04,DataIn = 0xFE,SegmentIn = 0x00和CarryEnable = 1的输入,if语句等于(1 and ((not 0) and 1 and 1))='1'
然而,SegmentOut永远不会改变。有没有人看到这是如何实现的问题?
答案 0 :(得分:0)
当求和符号位相等但不等于求和位时发生溢出:
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
始终为正,溢出只能在进位时发生(对于两个正数)。所以你应该把你的陈述改为(并且可能以某种方式将这两个联合起来):
SegmentOut <= unsigned(SegmentIn) + 1 when (not Addend(7) and temp(7));
SegmentOut <= unsigned(SegmentIn) - 1 when (Addend(7) and temp(7));
这是一个真相表:
Addend(7) DataIn(7) temp(7)| Carry Borrow
0 0 0 | 0 0
0 0 1 | 1 0
1 0 0 | 0 0
1 0 1 | 0 1
编辑:正如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);