我正在实现一个简单的加法器。但是,我需要一些独特的转折。
我正在实现的是跨代码段(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 语句等于 out (1 and ((not 0) and 1 and 1))='1'
,但是 SegmentOut 永远不会改变。有没有人看到这是如何实现的问题?