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