hlt命令を廃止してjnc (jump if no carry)命令を追加する

テキストは加減算のキャリー、ボローを見ていないため少し不便である。そこで、hlt (停止)命令はよして代わりにjnc (jump if no carry)命令を追加する。要は、キャリービットを含む17ビットの信号REG_IN_TEMPを追加しただけである。hltの代用はjmp 自番地とする。
f:id:ti-nspire:20210206091111p:plain:w700

-- exec_jnc.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity exec_jnc is
    port(
        CLK_EX  : in std_logic;
        RESET_N : in std_logic;
        OP_CODE : in std_logic_vector(3 downto 0);
        REG_A   : in std_logic_vector(15 downto 0);
        REG_B   : in std_logic_vector(15 downto 0);
        OP_DATA : in std_logic_vector(7 downto 0);
        RAM_OUT : in std_logic_vector(15 downto 0);

        P_COUNT : out std_logic_vector(7 downto 0);
        REG_IN  : out std_logic_vector(15 downto 0);
        RAM_IN  : out std_logic_vector(15 downto 0);
        REG_WEN : out std_logic;
        RAM_WEN : out std_logic
    );
end exec_jnc;


architecture RTL of exec_jnc is

signal PC          : std_logic_vector(7 downto 0);
signal CMP_FLAG    : std_logic;
signal REG_IN_TEMP : std_logic_vector(16 downto 0);

begin
    process(CLK_EX)
    begin

        if(CLK_EX'event and CLK_EX = '1') then
            if(RESET_N = '0') then
                PC <= (others => '0');
                CMP_FLAG <= '0';
                REG_IN_TEMP <= (others => '0');
            else 
                case OP_CODE is
                    when "0000" =>   -- MOV  
                        REG_IN_TEMP <= '0' & REG_B;
                        REG_WEN <= '1';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "0001" => -- ADD
                        REG_IN_TEMP <= ('0' & REG_A) + ('0' & REG_B);
                        REG_WEN <= '1';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "0010" => -- SUB
                        REG_IN_TEMP <= ('0' & REG_A) - ('0' & REG_B);
                        REG_WEN <= '1';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "0011" => -- AND
                        REG_IN_TEMP <= '0' & (REG_A and REG_B);
                        REG_WEN <= '1';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "0100" => -- OR
                        REG_IN_TEMP <= '0' & (REG_A or REG_B);
                        REG_WEN <= '1';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "0101" => -- SL
                        REG_IN_TEMP <= '0' & REG_A(14 downto 0) & '0';
                        REG_WEN <= '1';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "0110" => -- SR
                        REG_IN_TEMP <= "00" & REG_A(15 downto 1);
                        REG_WEN <= '1';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "0111" => -- SRA
                        REG_IN_TEMP <= '0' & REG_A(15) & REG_A(15 downto 1);
                        REG_WEN <= '1';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "1000" => -- LDL
                        REG_IN_TEMP <= '0' & REG_A(15 downto 8) & OP_DATA;
                        REG_WEN <= '1';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "1001" => -- LDH
                        REG_IN_TEMP <= '0' & OP_DATA & REG_A(7 downto 0);
                        REG_WEN <= '1';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "1010" => -- CMP
                        if(REG_A = REG_B) then
                            CMP_FLAG <= '1';
                        else
                            CMP_FLAG <= '0';
                        end if; 
                        REG_WEN <= '0';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "1011" => -- JE
                        if(CMP_FLAG = '1') then
                            PC <= OP_DATA;
                        else
                            PC <= PC + 1;
                        end if;
                        REG_WEN <= '0';
                        RAM_WEN <= '0';
                    when "1100" => -- JMP
                        REG_WEN <= '0';
                        RAM_WEN <= '0';
                        PC <= OP_DATA;
                    when "1101" => -- LD
                        REG_IN_TEMP <= '0' & RAM_OUT;
                        REG_WEN <= '1';
                        RAM_WEN <= '0';
                        PC <= PC + 1;
                    when "1110" => -- ST
                        RAM_IN <= REG_A;
                        REG_WEN <= '0';
                        RAM_WEN <= '1';
                        PC <= PC + 1;
                    when "1111" => -- JNC
                        if(REG_IN_TEMP(16) = '0') then
                            PC <= OP_DATA;
                        else
                            PC <= PC + 1;
                        end if;
                        REG_WEN <= '0';
                        RAM_WEN <= '0';
                    when others =>
                        null;
                end case;
            end if;
        end if;
    end process;
    P_COUNT <= PC;
    REG_IN  <= REG_IN_TEMP(15 downto 0);
end RTL;