私は単純な加算器を実装しています。ただし、少しユニークなひねりが必要です。
私が実装しているのは、コード セグメント (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 が変化しないからです。これの実装方法に問題がある人はいますか?