-- -- 8051 compatible microcontroller core -- -- Version : 0300 -- -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -- (c) 2004-2005 Andreas Voggeneder (andreas.voggeneder@fh-hagenberg.at) -- -- All rights reserved -- -- Redistribution and use in source and synthezised forms, with or without -- modification, are permitted provided that the following conditions are met: -- -- Redistributions of source code must retain the above copyright notice, -- this list of conditions and the following disclaimer. -- -- Redistributions in synthesized form must reproduce the above copyright -- notice, this list of conditions and the following disclaimer in the -- documentation and/or other materials provided with the distribution. -- -- Neither the name of the author nor the names of other contributors may -- be used to endorse or promote products derived from this software without -- specific prior written permission. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. -- -- Please report bugs to the author, but before you do so, please -- make sure that this is not a derivative work and that -- you have the latest version of this file. -- -- The latest version of this file can be found at: -- http://www.opencores.org/cvsweb.shtml/t51/ -- -- Limitations : -- -- File history : -- -- 16-Dec-05 : Bugfix for JBC instruction -- 21-Jan-06 : Bugfix for INC DPTR instruction for special cases -- 19-Feb-06 : Bugfix for Interrupts at stalled instructions library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use work.T51_Pack.all; entity T51 is generic( DualBus : integer := 1; -- FALSE: single bus movx RAMAddressWidth : integer := 8; SecondDPTR : integer := 0; t8032 : integer := 0; -- 0== advanced movx timing, not compatible to T8032 tristate : integer := 1; simenv : integer := 0 ); port( Clk : in std_logic; Rst_n : in std_logic; Ready : in std_logic; ROM_Addr : out std_logic_vector(15 downto 0); ROM_Data : in std_logic_vector(7 downto 0); RAM_Addr : out std_logic_vector(15 downto 0); RAM_RData : in std_logic_vector(7 downto 0); RAM_WData : out std_logic_vector(7 downto 0); RAM_Cycle : out std_logic; RAM_Rd : out std_logic; RAM_Wr : out std_logic; Int_Trig : in std_logic_vector(6 downto 0); Int_Acc : out std_logic_vector(6 downto 0); SFR_Rd_RMW : out std_logic; SFR_Wr : out std_logic; SFR_Addr : out std_logic_vector(6 downto 0); SFR_WData : out std_logic_vector(7 downto 0); SFR_RData_in : in std_logic_vector(7 downto 0); IRAM_Wr : out std_logic; IRAM_Addr : out std_logic_vector(7 downto 0); IRAM_WData : out std_logic_vector(7 downto 0) ); end T51; architecture rtl of T51 is constant Altera_IRAM_c : boolean :=false; -- speeds up instructions "mov @Ri,direct" and "mov Ri,direct" by one cycle -- but not fully testet. So use it with care constant fast_cpu_c : integer := 0; -- Registers signal ACC : std_logic_vector(7 downto 0); signal B : std_logic_vector(7 downto 0); signal PSW : std_logic_vector(7 downto 1); -- Bit 0 is parity signal PSW0 : std_logic; signal IP : std_logic_vector(7 downto 0); signal SP : unsigned(7 downto 0); signal DPL0 : std_logic_vector(7 downto 0); -- DPTR 0 signal DPH0 : std_logic_vector(7 downto 0); -- DPTR 0 signal DPL1 : std_logic_vector(7 downto 0); -- DPTR 1 signal DPH1 : std_logic_vector(7 downto 0); -- DPTR 1 signal DPL : std_logic_vector(7 downto 0); -- current DPTR signal DPH : std_logic_vector(7 downto 0); -- current DPTR signal DPS,next_DPS : std_logic; signal dptr_inc : std_logic_vector(15 downto 0); signal DPS_r : std_logic; signal PC : unsigned(15 downto 0); signal P2R : std_logic_vector(7 downto 0); signal PCC : std_logic_vector(15 downto 0); signal NPC : unsigned(15 downto 0); signal OPC : unsigned(15 downto 0); -- ALU signals signal Op_A : std_logic_vector(7 downto 0); signal Op_B : std_logic_vector(7 downto 0); signal Mem_A : std_logic_vector(7 downto 0); signal Mem_B : std_logic_vector(7 downto 0); signal Old_Mem_B : std_logic_vector(7 downto 0); signal ACC_Q : std_logic_vector(7 downto 0); signal B_Q : std_logic_vector(7 downto 0); signal Res_Bus : std_logic_vector(7 downto 0); signal Status_D : std_logic_vector(7 downto 5); signal Status_Wr : std_logic_vector(7 downto 5); -- Misc signals signal Int_AddrA : std_logic_vector(7 downto 0); signal Int_AddrA_r : std_logic_vector(7 downto 0); signal Int_AddrB : std_logic_vector(7 downto 0); signal MCode : std_logic_vector(3 downto 0); signal FCycle : std_logic_vector(1 downto 0); signal RET_r : std_logic; signal RET : std_logic; signal Stall_pipe : std_logic; signal Ri_Stall : std_logic; signal PSW_Stall : std_logic; signal ACC_Stall : std_logic; signal SP_Stall : std_logic; signal movx_Stall : std_logic; signal iReady : std_logic; signal Next_PSW7 : std_logic; signal Next_ACC_Z : std_logic; signal ACC_Wr : std_logic; signal B_Wr : std_logic; signal SFR_RData_r : std_logic_vector(7 downto 0); signal SFR_RData : std_logic_vector(7 downto 0); signal Mem_Din : std_logic_vector(7 downto 0); signal Bit_Pattern : std_logic_vector(7 downto 0); -- Registered instruction words. signal Inst : std_logic_vector(7 downto 0); signal Inst1 : std_logic_vector(7 downto 0); signal Inst2 : std_logic_vector(7 downto 0); -- Control signals signal Rst_r_n : std_logic; signal Last : std_logic; signal SFR_Wr_i : std_logic; signal Mem_Wr : std_logic; signal J_Skip : std_logic; signal IPending : std_logic; signal Int_Trig_r : std_logic_vector(6 downto 0); signal IStart : std_logic; signal ICall : std_logic; signal HPInt : std_logic; signal LPInt : std_logic; signal PCPaused : std_logic_vector(3 downto 0); signal PCPause : std_logic; signal Inst_Skip : std_logic; signal Div_Rdy : std_logic; signal RAM_Rd_i : std_logic; signal RAM_Wr_i : std_logic; signal INC_DPTR : std_logic; signal CJNE : std_logic; signal DJNZ : std_logic; -- Mux control signal AMux_SFR : std_logic; signal BMux_Inst2 : std_logic; signal RMux_PCL : std_logic; signal RMux_PCH : std_logic; signal next_Mem_Wr : std_logic; signal rd_flag,xxx_flag : std_logic; signal rd_flag_r : std_ulogic; signal rd_sfr_flag : std_logic; signal Do_ACC_Wr : std_logic; signal ramc,ramc_r,ramrw_r : std_logic; begin iReady <= Ready and not xxx_flag; ram_cycle <= ramc; Last <= '1' when ICall = '1' and FCycle = "11" else '0' when ICall = '1' else '1' when MCode(1 downto 0) = FCycle and iReady = '1' else '0'; -- (ROM_Data, ICall, Inst, Inst1, Inst2, Last, FCycle, PSW, Mem_B, SP, Old_Mem_B, Ready, Int_AddrA_r) process (FCycle, ICall, Inst, Inst1, Inst2, Int_AddrA_r, Last, Mem_B, Old_Mem_B, PSW, ROM_Data, Ready, SP, SFR_Wr_i, Res_Bus) begin Int_AddrA <= "--------"; -- Int_AddrB <= "--------"; Int_AddrB <= "000" & PSW(4 downto 3) & "00" & Inst(0); rd_flag <= '0'; rd_sfr_flag <= '0'; if Inst(3 downto 0) = "0000" or Inst(3 downto 0) = "0010" then if Inst(3 downto 0) = "0000" or (Inst(3 downto 0) = "0010" and (Inst(7) = '1' or Inst(6 downto 4) = "111")) then if Inst1(7) = '0' then Int_AddrA <= "0010" & Inst1(6 downto 3); else Int_AddrA <= "1" & Inst1(6 downto 3) & "000"; end if; else Int_AddrA <= Inst1; end if; if Inst = "00010010" or ICall = '1' then -- LCALL if FCycle = "01" then Int_AddrA <= std_logic_vector(SP + 1); else Int_AddrA <= std_logic_vector(SP + 2); end if; end if; if Inst = "11000000" then -- 11000000 2 PUSH data addr INC SP: MOV "@SP", if FCycle = "10" then Int_AddrA <= std_logic_vector(SP); else Int_AddrA <= Inst1; end if; end if; if Inst = "11010000" then -- 11010000 2 POP data addr MOV ,"@SP": DEC SP if FCycle = "10" then Int_AddrA <= Inst1; else Int_AddrA <= std_logic_vector(SP); end if; end if; if Inst(7 downto 5) = "001" and Inst(3 downto 0) = "0010" then -- RET, RETI Int_AddrA <= std_logic_vector(SP); Int_AddrB <= std_logic_vector(SP - 1); end if; elsif Inst(4 downto 0) = "10001" then -- ACALL if FCycle = "01" then Int_AddrA <= std_logic_vector(SP + 1); else Int_AddrA <= std_logic_vector(SP + 2); end if; elsif Inst(3 downto 0) = "0011" then Int_AddrA <= inst1; elsif Inst(3 downto 0) = "0100" then elsif Inst(3 downto 0) = "0101" then if Inst(7 downto 4) = "1000" and FCycle = "11" then Int_AddrA <= Inst2; else Int_AddrA <= Inst1; end if; elsif Inst(3 downto 1) = "011" then -- @Ri Adressing mode if FCycle(1 downto 0) = "01" then Int_AddrA <= Mem_B; else Int_AddrA <= Old_Mem_B; end if; if Inst(7 downto 4) = "1000" and FCycle = "10" then Int_AddrA <= Inst1; -- mov direct,@Ri end if; if Inst(7 downto 4) = "1010" and FCycle = "01" then Int_AddrA <= ROM_Data; -- mov @Ri,direct rd_flag <= '1'; end if; elsif Inst(3) = '1' then Int_AddrA <= "000" & PSW(4 downto 3) & Inst(2 downto 0); if Inst(7 downto 4) = "1000" and FCycle = "10" then Int_AddrA <= Inst1; end if; if Inst(7 downto 4) = "1010" and FCycle = "01" then Int_AddrA <= ROM_Data; -- mov Ri,data rd_flag <= '1'; end if; end if; -- if Last = '1' then -- Modified by AVG if (Inst(7 downto 5) /= "001" or Inst(3 downto 0) /= "0010") and -- not a RET, RETI (ROM_Data(3 downto 1) = "011" or -- Next or current Instruction has @Ri Addressing Mode Inst(3 downto 1) = "011" or ROM_Data(7 downto 1)="1110001" or ROM_Data(7 downto 1)="1111001") then -- MOVX @Ri,A ; MOVX A,@Ri if Last = '1' then Int_AddrB <= "000" & PSW(4 downto 3) & "00" & ROM_Data(0); -- write to psw is in progress => forward argument -- decreases timing !!! if fast_cpu_c/=0 and SFR_Wr_i = '1' and Int_AddrA_r = "11010000" then Int_AddrB <= "000" & Res_Bus(4 downto 3) & "00" & ROM_Data(0); end if; end if; rd_sfr_flag <= '1'; end if; -- end if; -- if Inst(7 downto 1) = "1011011" then -- cjne @ri,#im -- Int_AddrB <= "000" & PSW(4 downto 3) & "00" & Inst(0); -- end if; if Ready = '0' then Int_AddrA <= Int_AddrA_r; end if; end process; Op_A <= SFR_RData_r when AMux_SFR = '1' else Mem_A; Op_B <= Inst2 when BMux_Inst2 = '1' else Inst1; -- Store return Address to mem (Stack) when a call (or interrupt) occured Mem_Din <= PCC(7 downto 0) when RMux_PCL = '1' else PCC(15 downto 8) when RMux_PCH = '1' else Res_Bus; process (Clk) begin if Clk'event and Clk = '1' then AMux_SFR <= '0'; BMux_Inst2 <= '0'; RMux_PCL <= '0'; RMux_PCH <= '0'; if Int_AddrA(7) = '1' then AMux_SFR <= '1'; end if; if Inst(3 downto 1) = "011" then -- relative addressing mode -- not "mov @ri,direct" if not (Inst(7 downto 4) = "1010") then -- and FCycle = "10") then -- Indirect addressing AMux_SFR <= '0'; end if; end if; if Inst = "11010000" then -- 11010000 2 POP data addr MOV ,"@SP": DEC SP -- if FCycle = "10" then AMux_SFR <= '0'; -- end if; end if; if Inst(3 downto 0) = "0011" or Inst(3 downto 0) = "0101" then BMux_Inst2 <= '1'; end if; -- LCALL, ACALL, Int if (Inst = "00010010" or Inst(4 downto 0) = "10001" or ICall = '1') then if FCycle = "01" then RMux_PCL <= '1'; elsif FCycle = "10" then RMux_PCH <= '1'; end if; end if; end if; end process; SFR_Wr <= SFR_Wr_i; SFR_Addr <= Int_AddrA(6 downto 0); SFR_WData <= Res_Bus; SFR_Rd_RMW <= '1' when Last = '1' and MCode(3) = '1' and Int_AddrA(7) = '1' and (Inst(7 downto 4) = "1000" or Inst(3 downto 1) /= "011") and Inst /= "11000000" else -- no push '0'; next_Mem_Wr <= '1' when Last = '1' and MCode(3) = '1' and (Int_AddrA(7) = '0' or -- Instruction is no MOV and indirect addressing mode (Inst(7 downto 4) /= "1000" and Inst(3 downto 1) = "011") or Inst = "11000000" ) else -- PUSH Instruction '0'; process (Clk) begin if Clk'event and Clk = '1' then SFR_Wr_i <= '0'; Mem_Wr <= '0'; if Last = '1' and MCode(3) = '1' then -- MOV or no indirect addressing if Int_AddrA(7) = '1' and (Inst(7 downto 4) = "1000" or Inst(3 downto 1) /= "011") and Inst /= "11000000" then -- Direct addressing if(Inst = "00010000") then -- JBC, write result only back if jump is taken SFR_Wr_i <= J_Skip; else -- Direct addressing SFR_Wr_i <= '1'; end if; else Mem_Wr <= '1'; end if; end if; -- LCALL, ACALL, Int if iReady = '1' and (Inst = "00010010" or Inst(4 downto 0) = "10001" or ICall = '1') then if FCycle /= "11" then -- LCALL Mem_Wr <= '1'; end if; end if; end if; end process; -- Instruction register Inst_Skip <= RET_r or J_Skip; -- '1' when (RET_r = '1' and unsigned(Mem_B) /= PC(15 downto 8)) else J_Skip; ???????????? -- Ri_Stall <= '1' when Inst /= "00000000" and -- Int_AddrA = "000" & PSW(4 downto 3) & Inst(2 downto 0) and --Write to Ri in Progress -- ROM_Data(3 downto 1) = "011" and --@Ri at next opcode -- Last = '1' and MCode(3) = '1' else '0'; -- WHEN MCODE(3)==1 => Write to Memory or FSR is in Progress -- Modified by AVG Ri_Stall <= '1' when Inst /= "00000000" and next_Mem_Wr ='1' and (Int_AddrA = "000" & PSW(4 downto 3) & "00"&ROM_Data(0) and (ROM_Data(3 downto 1) = "011" or -- @Ri at next opcode ROM_Data(7 downto 1)="1110001" or -- movx a,@ri at next opcode ROM_Data(7 downto 1)="1111001")) -- movx @ri,a at next opcod else '0'; -- WHEN MCODE(3)==1 => Write to Memory or FSR is in Progress -- Modified by AVG PSW_Stall <= '1' when Int_AddrA = "11010000" and next_Mem_Wr='0' and -- PSW Adressed and no memory write (ROM_Data(3 downto 1) = "011" or -- @Ri at next opcode ROM_Data(3) = '1') and -- Rx at next opcode Last = '1' and MCode(3) = '1' else '0'; -- WHEN MCODE(2)==1 => Write to ACC in Progress -- Stall Pipe when Write to ACC is in Progress and next Instruction is JMP @A+DPTR -- Modified by AVG ACC_Stall <= '1' when ROM_Data = "01110011" and Last = '1' and MCode(2) = '1' else '0'; -- when a write to SP is in progress -- and next opcode is a call or interrupt -- -> stall pipe (nop insertion) -- Modified by AVG SP_Stall <= '1' when Last = '1' and MCode(3) = '1' and Int_AddrA = "10000001" and (Inst(7 downto 4) = "1000" or -- mov opcode Inst(3 downto 1) /= "011") and -- and no indirect addressing Inst /= "11000000" and -- and not PUSH (ROM_Data = "00010010" or ROM_Data(4 downto 0) = "10001" or IStart = '1') else -- LCALL, ACALL, Int '0'; -- to subsequent movx instructions movx_Stall <= '1' when Last = '1' and -- movx opcode at current instruction Inst(7 downto 5) = "111" and Inst(3 downto 2) = "00" and Inst(1 downto 0) /= "01" and -- movx opcode at next instruction ROM_Data(7 downto 5) = "111" and ROM_Data(3 downto 2) = "00" and ROM_Data(1 downto 0) /= "01" else '0'; Stall_pipe <= (Ri_Stall or PSW_Stall or ACC_Stall or SP_Stall or movx_Stall) and not IStart; process (Rst_n, Clk) variable bitnr_v : natural range 0 to 7; begin if Rst_n = '0' then Rst_r_n <= '0'; Inst <= (others => '0'); -- Force NOP at reset. Inst1 <= (others => '0'); Inst2 <= (others => '0'); Bit_Pattern <= "00000000"; elsif Clk'event and Clk = '1' then Rst_r_n <= '1'; if iReady = '0' then elsif Rst_r_n = '0' or Inst_Skip = '1' or IStart = '1' or Stall_pipe = '1' then -- Ri_Stall = '1' or PSW_Stall = '1' or ACC_Stall = '1' then -- Skip/Stall/Flush: NOP insertion Inst <= (others => '0'); elsif Inst = "10000100" and PCPause = '1' then -- DIV else if Last = '1' then Inst <= ROM_Data; end if; if FCycle = "01" then Inst1 <= ROM_Data; end if; if FCycle = "10" then Inst2 <= ROM_Data; end if; end if; if FCycle = "01" then Bit_Pattern <= "00000000"; bitnr_v := to_integer(unsigned(ROM_Data(2 downto 0))); Bit_Pattern(bitnr_v) <= '1'; -- case ROM_Data(2 downto 0) is -- when "000" => -- Bit_Pattern <= "00000001"; -- when "001" => -- Bit_Pattern <= "00000010"; -- when "010" => -- Bit_Pattern <= "00000100"; -- when "011" => -- Bit_Pattern <= "00001000"; -- when "100" => -- Bit_Pattern <= "00010000"; -- when "101" => -- Bit_Pattern <= "00100000"; -- when "110" => -- Bit_Pattern <= "01000000"; -- when others => -- Bit_Pattern <= "10000000"; -- end case; end if; end if; end process; -- Accumulator, B and status register tristate_mux: if tristate/=0 generate SFR_RData <= PSW & PSW0 when Int_AddrA = "11010000" else "ZZZZZZZZ"; SFR_RData <= ACC when Int_AddrA = "11100000" else "ZZZZZZZZ"; SFR_RData <= B when Int_AddrA = "11110000" else "ZZZZZZZZ"; -- Stack pointer SFR_RData <= std_logic_vector(SP) when Int_AddrA = "10000001" else "ZZZZZZZZ"; SFR_RData <= dptr_inc(7 downto 0) when (SecondDPTR/=0 and (INC_DPTR and next_DPS) = '1' and Int_AddrA = "10000100") or ((INC_DPTR and not next_DPS) = '1' and Int_AddrA = "10000010") else "ZZZZZZZZ"; SFR_RData <= dptr_inc(15 downto 8) when (SecondDPTR/=0 and (INC_DPTR and next_DPS) = '1' and Int_AddrA = "10000101") or ((INC_DPTR and not next_DPS) = '1' and Int_AddrA = "10000011") else "ZZZZZZZZ"; SFR_RData <= DPL1 when SecondDPTR/=0 and INC_DPTR='0' and Int_AddrA = "10000100" else "ZZZZZZZZ"; SFR_RData <= DPH1 when SecondDPTR/=0 and INC_DPTR='0' and Int_AddrA = "10000101" else "ZZZZZZZZ"; SFR_RData <= "0000000"&DPS when SecondDPTR/=0 and Int_AddrA = "10000110" else "ZZZZZZZZ"; SFR_RData <= DPL0 when INC_DPTR='0' and Int_AddrA = "10000010" else "ZZZZZZZZ"; SFR_RData <= DPH0 when INC_DPTR='0' and Int_AddrA = "10000011" else "ZZZZZZZZ"; SFR_RData <= IP when Int_AddrA = "10111000" else "ZZZZZZZZ"; SFR_RData <= SFR_RData_in; end generate; std_mux: if tristate=0 generate SFR_RData <= PSW & PSW0 when Int_AddrA = "11010000" else ACC when Int_AddrA = "11100000" else B when Int_AddrA = "11110000" else std_logic_vector(SP) when Int_AddrA = "10000001" else dptr_inc(7 downto 0) when (SecondDPTR/=0 and (INC_DPTR and next_DPS) = '1' and Int_AddrA = "10000100") or ((INC_DPTR and not next_DPS) = '1' and Int_AddrA = "10000010") else dptr_inc(15 downto 8) when (SecondDPTR/=0 and (INC_DPTR and next_DPS) = '1' and Int_AddrA = "10000101") or ((INC_DPTR and not next_DPS) = '1' and Int_AddrA = "10000011") else DPL1 when SecondDPTR/=0 and INC_DPTR='0' and Int_AddrA = "10000100" else DPH1 when SecondDPTR/=0 and INC_DPTR='0' and Int_AddrA = "10000101" else "0000000"&DPS when SecondDPTR/=0 and Int_AddrA = "10000110" else DPL0 when INC_DPTR='0' and Int_AddrA = "10000010" else DPH0 when INC_DPTR='0' and Int_AddrA = "10000011" else IP when Int_AddrA = "10111000" else SFR_RData_in; -- -- is it an internal or external read -- Int_Read <= '1' when Int_AddrA = "11010000" or -- Int_AddrA = "11100000" or -- Int_AddrA = "11110000" or -- Int_AddrA = "10000001" or -- -- (SecondDPTR and Int_AddrA = "10000100") or -- (SecondDPTR and Int_AddrA = "10000101") or -- (SecondDPTR and Int_AddrA = "10000110") or -- -- Int_AddrA = "10000010" or -- Int_AddrA = "10000011" or -- Int_AddrA = "10111000" else -- '0'; end generate; PSW0 <= ACC(7) xor ACC(6) xor ACC(5) xor ACC(4) xor ACC(3) xor ACC(2) xor ACC(1) xor ACC(0); Next_PSW7 <= Res_Bus(7) when SFR_Wr_i = '1' and Int_AddrA_r = "11010000" else Status_D(7) when Status_Wr(7) = '1' else PSW(7); Next_ACC_Z <= '1' when ACC_Q = "00000000" and ACC_Wr = '1' else '1' when ACC = "00000000" else '0'; process (Rst_n, Clk) -- variable B_Wr : std_logic; begin if Rst_n = '0' then PSW <= "0000000"; ACC <= "00000000"; B <= "00000000"; ACC_Wr <= '0'; B_Wr <= '0'; elsif Clk'event and Clk = '1' then if ACC_Wr = '1' then ACC <= ACC_Q; end if; if B_Wr = '1' then B <= B_Q; end if; if (MCode(2) and Last) = '1' or (Inst = "10000100" and PCPause = '0') then ACC_Wr <= '1'; else ACC_Wr <= '0'; end if; if ((Inst = "10000100" and PCPause = '0') or Inst = "10100100") and Last = '1' then -- DIV, MUL B_Wr <= '1'; else B_Wr <= '0'; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "11100000" then ACC <= Res_Bus; end if; if RAM_Rd_i = '1' then ACC <= RAM_RData; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "11110000" then B <= Res_Bus; end if; if Inst(7 downto 5) = "100" and Inst(3 downto 0) = "0011" then -- MOVC if FCycle = "11" then ACC <= ROM_Data; end if; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "11010000" then PSW <= Res_Bus(7 downto 1); end if; -- CY if Status_Wr(7) = '1' then PSW(7) <= Status_D(7); end if; -- AC if Status_Wr(6) = '1' then PSW(6) <= Status_D(6); end if; -- OV if Status_Wr(5) = '1' then PSW(2) <= Status_D(5); end if; end if; end process; process (Rst_n, Clk) begin if Rst_n = '0' then SP <= "00000111"; elsif Clk'event and Clk = '1' then if SFR_Wr_i = '1' and Int_AddrA_r = "10000001" then SP <= unsigned(Res_Bus); end if; if iReady = '1' then if Inst(7 downto 5) = "001" and Inst(3 downto 0) = "0010" then SP <= SP - 2; end if; if (Inst = "00010010" or Inst(4 downto 0) = "10001" or ICall = '1') and Last = '1' then -- LCALL, ACALL, ICall SP <= SP + 2; end if; if Inst = "11000000" and PCPaused(0) = '1' then -- 11000000 2 PUSH data addr INC SP: MOV "@SP", SP <= SP + 1; end if; if Inst = "11010000" and Last = '1' then -- 11010000 2 POP data addr MOV ,"@SP": DEC SP SP <= SP - 1; end if; end if; end if; end process; twoDPTR: if SecondDPTR/=0 generate next_DPS <= Res_Bus(0) when SFR_Wr_i = '1' and Int_AddrA_r = "10000110" else DPS; DPL <= DPL0 when next_DPS='0' else DPL1; DPH <= DPH0 when next_DPS='0' else DPH1; -- SFR_RData <= DPL1 when Int_AddrA = "10000100" else "ZZZZZZZZ"; -- SFR_RData <= DPH1 when Int_AddrA = "10000101" else "ZZZZZZZZ"; -- SFR_RData <= "0000000"&DPS when Int_AddrA = "10000110" else "ZZZZZZZZ"; end generate; oneDPTR: if SecondDPTR=0 generate DPL <= DPL0; DPH <= DPH0; next_DPS <= '0'; end generate; -- DPTR/RAM_Addr RAM_WData <= ACC; --(Inst, P2R, DPH, DPL, Int_AddrA_r, SFR_Wr_i, Res_Bus, INC_DPTR, Mem_B) process (DPH, DPL, INC_DPTR, dptr_inc, Inst, Int_AddrA_r, Mem_B, P2R, Res_Bus, SFR_Wr_i, DPS) begin RAM_Addr <= DPH & DPL; if Inst(1) = '0' then if (SFR_Wr_i = '1' and Int_AddrA_r = "10000010" and DPS = '0') or (SecondDPTR/=0 and SFR_Wr_i = '1' and Int_AddrA_r = "10000100" and DPS = '1') then RAM_Addr(7 downto 0) <= Res_Bus; end if; if (SFR_Wr_i = '1' and Int_AddrA_r = "10000011" and DPS = '0') or (SecondDPTR/=0 and SFR_Wr_i = '1' and Int_AddrA_r = "10000101" and DPS = '1') then RAM_Addr(15 downto 8) <= Res_Bus; end if; -- 10100011 1 INC DPTR if INC_DPTR = '1' then -- RAM_Addr <= std_logic_vector(unsigned(DPH) & unsigned(DPL) + 1); RAM_Addr <= dptr_inc; end if; else -- movx a,@ri or movx @ri,a RAM_Addr <= P2R & Mem_B; if SFR_Wr_i = '1' and Int_AddrA_r = "10100000" then RAM_Addr(15 downto 8) <= Res_Bus; end if; end if; end process; --if Inst(7 downto 2) = "111000" and Inst(1 downto 0) /= "01" then -- MOVX Instruction ramc <= '1' when Inst(7 downto 5) = "111" and Inst(3 downto 2) = "00" and Inst(1 downto 0) /= "01" and PCPaused(0) = '0' else '0'; -- RAM_Rd <= RAM_Rd_i and ramc and not ramrw_r when DualBus=0 else -- RAM_Rd_i and ramc; RAM_Rd <= RAM_Rd_i and ramc when t8032=0 else RAM_Rd_i; RAM_Wr <= RAM_Wr_i; Do_ACC_Wr <= '1' when (ACC_Wr or RAM_Rd_i)='1' or (SFR_Wr_i = '1' and Int_AddrA_r = "11100000") else '0'; -- Gefählich sind: -- mov @Ri,direct -- mov Ri,data -- da diese Befehle die Quelldaten einen Takt früher lesen als alle anderen Befehle -- xxx_flag <= '1' when ((SFR_Wr_i and rd_flag)= '1' and Int_AddrA_r=Int_AddrA) or -- ((Do_ACC_Wr and rd_flag)='1' and Int_AddrA = "11010000") or -- (Status_Wr/="000" and rd_flag='1' and Int_AddrA="11010000") or -- (fast_cpu_c=0 and (rd_sfr_flag and SFR_Wr_i) = '1' and Int_AddrA_r = "11010000") else -- '0'; fast: if fast_cpu_c/=0 generate xxx_flag <= '1' when ((SFR_Wr_i and rd_flag)= '1' and Int_AddrA_r=Int_AddrA) or ((Do_ACC_Wr and rd_flag)='1' and Int_AddrA = "11010000") or -- WR to ACC in Progress and read from PSW ((B_Wr and rd_flag)= '1' and Int_AddrA = "11110000") or (Status_Wr/="000" and rd_flag='1' and Int_AddrA="11010000") or -- (ramc='1' and ramc_r='0') (t8032=0 and Inst(7 downto 2) = "111000" and Inst(1 downto 0) /= "01" and ramc_r='0') --MOVX A,?? -- (((RAM_Rd_i and ramc)='1' or RAM_Wr_i='1') and ramrw_r='0' and DualBus=0) else '0'; end generate; slow: if fast_cpu_c=0 generate -- Inserts an Waitstate on every mov @Ri,direct or mov Ri,data Instruction xxx_flag <= '1' when (rd_flag and not rd_flag_r) = '1' or -- mov @ri,direct or mov ri,direct ((rd_sfr_flag and SFR_Wr_i) = '1' and Int_AddrA_r = "11010000") or -- Wr to PSW and @Ri Adressing at next instruction -- (ramc='1' and ramc_r='0') (t8032=0 and Inst(7 downto 2) = "111000" and Inst(1 downto 0) /= "01" and ramc_r='0') or --MOVX A,?? -- (((RAM_Rd_i and ramc)='1' or RAM_Wr_i='1') and ramrw_r='0' and DualBus=0) (t8032=0 and (RAM_Wr_i='1') and ramrw_r='0' and DualBus=0) else '0'; process(Rst_n, Clk) begin if Rst_n = '0' then rd_flag_r <= '0'; elsif Clk'event and Clk = '1' then rd_flag_r <= rd_flag; end if; end process; end generate; process (Rst_n, Clk) variable tmp : unsigned(15 downto 0); begin if Rst_n = '0' then P2R <= "11111111"; DPL0 <= "00000000"; DPH0 <= "00000000"; INC_DPTR <= '0'; RAM_Rd_i <= '0'; RAM_Wr_i <= '0'; if SecondDPTR/=0 then DPL1 <= "00000000"; DPH1 <= "00000000"; DPS_r <= '0'; end if; ramc_r <= '0'; ramrw_r <= '0'; elsif Clk'event and Clk = '1' then if Ready='1' then ramc_r <= ramc; ramrw_r <= (RAM_Rd_i and ramc) or RAM_Wr_i; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "10100000" then P2R <= Res_Bus; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "10000010" then DPL0 <= Res_Bus; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "10000011" then DPH0 <= Res_Bus; end if; if SecondDPTR/=0 then if SFR_Wr_i = '1' and Int_AddrA_r = "10000100" then DPL1 <= Res_Bus; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "10000101" then DPH1 <= Res_Bus; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "10000110" then DPS_r <= Res_Bus(0); end if; end if; if iReady = '1' then if SecondDPTR=0 or (SecondDPTR/=0 and DPS='0') then -- 10010000 3 MOV DPTR,#data if Inst = "10010000" and FCycle = "10" then DPH0 <= Inst1; end if; if Inst = "10010000" and FCycle = "11" then DPL0 <= Inst2; end if; -- 10100011 1 INC DPTR if INC_DPTR = '1' then -- tmp := unsigned(DPH) & unsigned(DPL) + 1; -- DPH0 <= std_logic_vector(tmp(15 downto 8)); -- DPL0 <= std_logic_vector(tmp(7 downto 0)); DPH0 <= dptr_inc(15 downto 8); DPL0 <= dptr_inc(7 downto 0); end if; elsif SecondDPTR/=0 and DPS='1' then -- 10010000 3 MOV DPTR,#data if Inst = "10010000" and FCycle = "10" then DPH1 <= Inst1; end if; if Inst = "10010000" and FCycle = "11" then DPL1 <= Inst2; end if; -- 10100011 1 INC DPTR if INC_DPTR = '1' then -- tmp := unsigned(DPH) & unsigned(DPL) + 1; -- DPH1 <= std_logic_vector(tmp(15 downto 8)); -- DPL1 <= std_logic_vector(tmp(7 downto 0)); DPH1 <= dptr_inc(15 downto 8); DPL1 <= dptr_inc(7 downto 0); end if; end if; INC_DPTR <= '0'; if Inst = "10100011" then INC_DPTR <= '1'; end if; end if; if Ready='1' or t8032/=0 then RAM_Wr_i <= '0'; -- movx instruction if t8032=0 then if (Inst(7 downto 2) = "111100" and Inst(1 downto 0) /= "01") then RAM_Wr_i <= '1'; end if; elsif (Inst(7 downto 2) = "111100" and Inst(1 downto 0) /= "01" and DualBus/=0) or (Inst(7 downto 2) = "111100" and Inst(1 downto 0) /= "01" and iReady = '0' and DualBus=0) then RAM_Wr_i <= '1'; end if; RAM_Rd_i <= '0'; -- if Inst(7 downto 2) = "111000" and Inst(1 downto 0) /= "01" and iReady = '1' then if Inst(7 downto 2) = "111000" and Inst(1 downto 0) /= "01" then RAM_Rd_i <= '1'; end if; end if; end if; end process; dptr_inc <= std_logic_vector(unsigned(DPH) & unsigned(DPL) + 1); process(DPS_r) begin if SecondDPTR/=0 then DPS <= DPS_r; else DPS <= '0'; end if; end process; -- Interrupts IStart <= Last and IPending and not Inst_Skip; process (Rst_n, Clk) begin if Rst_n = '0' then LPInt <= '0'; HPInt <= '0'; Int_Acc <= (others => '0'); Int_Trig_r <= (others => '0'); IPending <= '0'; IP <= "00000000"; ICall <= '0'; elsif Clk'event and Clk = '1' then if SFR_Wr_i = '1' and Int_AddrA_r = "10111000" then IP <= Res_Bus; end if; if iReady = '1' then if (Int_Trig and IP(6 downto 0)) /= "0000000" and HPInt = '0' and IPending = '0' and ICall = '0' then Int_Trig_r <= Int_Trig and IP(6 downto 0); IPending <= '1'; HPInt <= '1'; elsif Int_Trig /= "0000000" and LPInt = '0' and HPInt = '0' and IPending = '0' and ICall = '0' then IPending <= '1'; Int_Trig_r <= Int_Trig; LPInt <= '1'; end if; if ICall = '1' then IPending <= '0'; end if; if IStart = '1' and SP_Stall='0' then ICall <= '1'; end if; if ICall = '1' and Last = '1' then ICall <= '0'; Int_Trig_r <= (others => '0'); end if; Int_Acc <= (others => '0'); if IPending = '1' and ICall = '1' then if Int_Trig_r(0) = '1' then Int_Acc(0) <= '1'; elsif Int_Trig_r(1) = '1' then Int_Acc(1) <= '1'; elsif Int_Trig_r(2) = '1' then Int_Acc(2) <= '1'; elsif Int_Trig_r(3) = '1' then Int_Acc(3) <= '1'; elsif Int_Trig_r(4) = '1' then Int_Acc(4) <= '1'; elsif Int_Trig_r(5) = '1' then Int_Acc(5) <= '1'; elsif Int_Trig_r(6) = '1' then Int_Acc(6) <= '1'; end if; end if; if Inst = "00110010" then -- reti if HPInt = '0' then LPInt <= '0'; else HPInt <= '0'; end if; end if; end if; end if; end process; -- Program counter ROM_Addr <= std_logic_vector(NPC); process (Rst_n, Clk) begin if Rst_n = '0' then PC <= (others => '0'); OPC <= (others => '0'); FCycle <= "01"; RET_r <= '0'; PCPaused <= (others => '0'); elsif Clk'event and Clk = '1' then if iReady = '1' then PC <= NPC; RET_r <= RET; if PCPause = '1' then PCPaused <= std_logic_vector(unsigned(PCPaused) + 1); else PCPaused <= (others => '0'); end if; if PCPause = '0' then FCycle <= std_logic_vector(unsigned(FCycle) + 1); if Last = '1' then FCycle <= "01"; end if; end if; if Inst(7 downto 5) = "100" and Inst(3 downto 0) = "0011" then -- MOVC if FCycle = "01" then OPC <= PC; end if; end if; end if; end if; end process; -- (FCycle, Inst, Inst2, CJNE, DJNZ, PC, OPC, Inst1, ROM_Data, -- Next_PSW7, Next_ACC_Z, DPL, DPH, ACC, PCPaused, Op_A, Mem_A, Mem_B, -- Bit_Pattern, Ri_Stall, PSW_Stall, ACC_Stall, RET_r, Div_Rdy, ICall, -- Int_Trig_r, Ready, Rst_r_n) process (ACC, Bit_Pattern, CJNE, DJNZ, DPH, DPL, Div_Rdy, FCycle, ICall, Inst, Inst1, Inst2, Int_Trig_r, Mem_A, Mem_B, Next_ACC_Z, Next_PSW7, OPC, Op_A, PC, PCPaused, RET_r, ROM_Data, iReady, Rst_r_n, Stall_pipe,RAM_Rd_i,RAM_Wr_i,ramc) begin NPC <= PC; J_Skip <= '0'; RET <= '0'; PCPause <= '0'; -- push,pop if (Inst(7 downto 5) = "110" and Inst(3 downto 0) = "0000" and FCycle = "01" and PCPaused(0) = '0') or -- PUSH, POP (t8032=0 and Inst(7 downto 2) = "111000" and Inst(1 downto 0) /= "01" and DualBus=0 and PCPaused(0) = '0') or (t8032/=0 and Inst(7 downto 5) = "111" and Inst(3 downto 2) = "00" and Inst(1 downto 0) /= "01" and DualBus=0 and PCPaused(0) = '0') or -- Single bus MOVX (Inst = "10000100" and (PCPaused(3 downto 1) = "000" or Div_Rdy = '0')) then -- DIV PCPause <= '1'; else -- if Ri_Stall = '0' and PSW_Stall = '0' and ACC_Stall='0' then if Stall_pipe = '0' then NPC <= PC + 1; end if; end if; -- Single bus MOVX if (t8032=0 and Inst(7 downto 2) = "111000" and Inst(1 downto 0) /= "01" and DualBus=0) or (t8032/=0 and Inst(7 downto 5) = "111" and Inst(3 downto 2) = "00" and Inst(1 downto 0) /= "01" and DualBus=0) then J_Skip <= '1'; end if; -- Return if Inst(7 downto 5) = "001" and Inst(3 downto 0) = "0010" then -- RET, RETI RET <= '1'; J_Skip <= '1'; end if; -- MOVC if Inst(7 downto 5) = "100" and Inst(3 downto 0) = "0011" and FCycle = "11" then NPC <= OPC; J_Skip <= '1'; end if; -- 2 byte 8 bit relative jump if FCycle = "10" then if (Inst = "01000000" and Next_PSW7 = '1') or -- JC (Inst = "01010000" and Next_PSW7 = '0') or -- JNC (Inst = "01100000" and Next_ACC_Z = '1') or -- JZ (Inst = "01110000" and Next_ACC_Z = '0') or -- JNZ (Inst(7 downto 3) = "11011" and DJNZ = '1') or -- DJNZ Inst = "10000000" then -- SJMP NPC <= PC + unsigned(resize(signed(Inst1),16)); J_Skip <= '1'; end if; end if; -- 3 byte 8 bit relative jump if FCycle = "11" then if (Inst = "00100000" or Inst = "00010000") and (Bit_Pattern and Op_A) /= "00000000" then -- JB, JBC NPC <= PC + unsigned(resize(signed(Inst2),16)); J_Skip <= '1'; end if; if Inst = "00110000" and (Bit_Pattern and Op_A) = "00000000" then -- JNB NPC <= PC + unsigned(resize(signed(Inst2),16)); J_Skip <= '1'; end if; if Inst(7 downto 4) = "1011" and Inst(3 downto 2) /= "00" and CJNE = '1' then -- CJNE NPC <= PC + unsigned(resize(signed(Inst2),16)); J_Skip <= '1'; end if; if Inst = "11010101" and DJNZ = '1' then -- DJNZ NPC <= PC + unsigned(resize(signed(Inst2),16)); J_Skip <= '1'; end if; end if; -- 11 bit absolute if FCycle = "10" then if Inst(4 downto 0) = "00001" or Inst(4 downto 0) = "10001" then -- AJMP, ACALL NPC(15 downto 11) <= PC(15 downto 11); NPC(10 downto 8) <= unsigned(Inst(7 downto 5)); NPC(7 downto 0) <= unsigned(Inst1); J_Skip <= '1'; end if; end if; -- 16 bit absolute if FCycle = "10" then if Inst = "00000010" or Inst = "00010010" then -- LJMP, LCALL NPC(15 downto 8) <= unsigned(Inst1); NPC(7 downto 0) <= unsigned(ROM_Data); end if; if ICall = '1' then NPC <= (1 => '1', 0 => '1', others => '0'); if Int_Trig_r(1) = '1' then NPC(5 downto 3) <= "001"; elsif Int_Trig_r(2) = '1' then NPC(5 downto 3) <= "010"; elsif Int_Trig_r(3) = '1' then NPC(5 downto 3) <= "011"; elsif Int_Trig_r(4) = '1' then NPC(5 downto 3) <= "100"; elsif Int_Trig_r(5) = '1' then NPC(5 downto 3) <= "101"; elsif Int_Trig_r(6) = '1' then NPC(5 downto 3) <= "110"; end if; end if; end if; -- A+DPTR Absolute if Inst = "01110011" then -- JMP @A+DPTR NPC <= (unsigned(DPH) & unsigned(DPL)) + unsigned(resize(signed(ACC),16)); J_Skip <= '1'; end if; if Inst(7 downto 5) = "100" and Inst(3 downto 0) = "0011" then -- MOVC if FCycle = "10" then if Inst(4) = '0' then NPC <= unsigned(ACC) + OPC; else NPC <= unsigned(ACC) + (unsigned(DPH) & unsigned(DPL)); end if; end if; end if; if RET_r = '1' then -- and unsigned(Mem_A) /= PC(15 downto 8) then ??????????????????????????? NPC <= unsigned(Mem_A) & unsigned(Mem_B); end if; if iReady = '0' then NPC <= PC; end if; if Rst_r_n = '0' then NPC <= (others => '0'); end if; end process; -- ALU alu : T51_ALU generic map( tristate => tristate ) port map( Clk => Clk, Last => Last, OpCode => Inst, ACC => ACC, B => B, IA => Op_A, IB => Op_B, Bit_Pattern => Bit_Pattern, CY_In => PSW(7), AC_In => PSW(6), ACC_Q => ACC_Q, B_Q => B_Q, IDCPBL_Q => Res_Bus, Div_Rdy => Div_Rdy, CJNE => CJNE, DJNZ => DJNZ, CY_Out => Status_D(7), AC_Out => Status_D(6), OV_Out => Status_D(5), CY_Wr => Status_Wr(7), AC_Wr => Status_Wr(6), OV_Wr => Status_Wr(5)); process (Clk) begin if Clk'event and Clk = '1' then Old_Mem_B <= Mem_B; if FCycle = "01" then if Inst(1) = '1' then PCC <= std_logic_vector(PC + 2); else PCC <= std_logic_vector(PC + 1); end if; if ICall = '1' then PCC <= std_logic_vector(PC - 1); end if; end if; SFR_RData_r <= SFR_RData; end if; end process; Generic_MODEL: if not Altera_IRAM_c generate ram : T51_RAM generic map( RAMAddressWidth => RAMAddressWidth) port map( Clk => Clk, Rst_n => Rst_n, ARE => Ready, Wr => Mem_Wr, DIn => Mem_Din, Int_AddrA => Int_AddrA, Int_AddrA_r => Int_AddrA_r, Int_AddrB => Int_AddrB, Mem_A => Mem_A, Mem_B => Mem_B); end generate; Altera_MODEL: if Altera_IRAM_c generate ram : T51_RAM_Altera generic map( RAMAddressWidth => RAMAddressWidth) port map( Clk => Clk, Rst_n => Rst_n, ARE => Ready, Wr => Mem_Wr, DIn => Mem_Din, Int_AddrA => Int_AddrA, Int_AddrA_r => Int_AddrA_r, Int_AddrB => Int_AddrB, Mem_A => Mem_A, Mem_B => Mem_B); end generate; IRAM_Wr <= Mem_Wr; IRAM_Addr <= Int_AddrA_r; IRAM_WData <= Mem_Din; process (Inst) begin case Inst is -- 1 downto 0 instruction length -- 2 write ACC -- 3 write register file when "00000000" => MCode <= "0001"; -- 00000000 1 NOP when "00000001" => MCode <= "0010"; -- aaa00001 2 AJMP code addr when "00000010" => MCode <= "0011"; -- 00000010 3 LJMP code addr when "00000011" => MCode <= "0101"; -- 00000011 1 RR A when "00000100" => MCode <= "0101"; -- 00000100 1 INC A when "00000101" => MCode <= "1010"; -- 00000101 2 INC data addr when "00000110" => MCode <= "1001"; -- 0000011i 1 INC @Ri when "00000111" => MCode <= "1001"; -- 0000011i 1 INC @Ri when "00001000" => MCode <= "1001"; -- 00001rrr 1 INC Rn when "00001001" => MCode <= "1001"; -- 00001rrr 1 INC Rn when "00001010" => MCode <= "1001"; -- 00001rrr 1 INC Rn when "00001011" => MCode <= "1001"; -- 00001rrr 1 INC Rn when "00001100" => MCode <= "1001"; -- 00001rrr 1 INC Rn when "00001101" => MCode <= "1001"; -- 00001rrr 1 INC Rn when "00001110" => MCode <= "1001"; -- 00001rrr 1 INC Rn when "00001111" => MCode <= "1001"; -- 00001rrr 1 INC Rn when "00010000" => MCode <= "1011"; -- 00010000 3 JBC bit addr, code addr when "00010001" => MCode <= "0010"; -- aaa10001 2 ACALL code addr when "00010010" => MCode <= "0011"; -- 00010010 3 LCALL code addr when "00010011" => MCode <= "0101"; -- 00010011 1 RRC A when "00010100" => MCode <= "0101"; -- 00010100 1 DEC A when "00010101" => MCode <= "1010"; -- 00010101 2 DEC data addr when "00010110" => MCode <= "1001"; -- 0001011i 1 DEC @Ri when "00010111" => MCode <= "1001"; -- 0001011i 1 DEC @Ri when "00011000" => MCode <= "1001"; -- 00011rrr 1 DEC Rn when "00011001" => MCode <= "1001"; -- 00011rrr 1 DEC Rn when "00011010" => MCode <= "1001"; -- 00011rrr 1 DEC Rn when "00011011" => MCode <= "1001"; -- 00011rrr 1 DEC Rn when "00011100" => MCode <= "1001"; -- 00011rrr 1 DEC Rn when "00011101" => MCode <= "1001"; -- 00011rrr 1 DEC Rn when "00011110" => MCode <= "1001"; -- 00011rrr 1 DEC Rn when "00011111" => MCode <= "1001"; -- 00011rrr 1 DEC Rn when "00100000" => MCode <= "0011"; -- 00100000 3 JB bit addr, code addr when "00100001" => MCode <= "0010"; -- aaa00001 2 AJMP code addr when "00100010" => MCode <= "0001"; -- 00100010 1 RET when "00100011" => MCode <= "0101"; -- 00100011 1 RL A when "00100100" => MCode <= "0110"; -- 00100100 2 ADD A,#data when "00100101" => MCode <= "0110"; -- 00100101 2 ADD A,data addr when "00100110" => MCode <= "0101"; -- 0010011i 1 ADD A,@Ri when "00100111" => MCode <= "0101"; -- 0010011i 1 ADD A,@Ri when "00101000" => MCode <= "0101"; -- 00101rrr 1 ADD A,Rn when "00101001" => MCode <= "0101"; -- 00101rrr 1 ADD A,Rn when "00101010" => MCode <= "0101"; -- 00101rrr 1 ADD A,Rn when "00101011" => MCode <= "0101"; -- 00101rrr 1 ADD A,Rn when "00101100" => MCode <= "0101"; -- 00101rrr 1 ADD A,Rn when "00101101" => MCode <= "0101"; -- 00101rrr 1 ADD A,Rn when "00101110" => MCode <= "0101"; -- 00101rrr 1 ADD A,Rn when "00101111" => MCode <= "0101"; -- 00101rrr 1 ADD A,Rn when "00110000" => MCode <= "0011"; -- 00110000 3 JNB bit addr, code addr when "00110001" => MCode <= "0010"; -- aaa10001 2 ACALL code addr when "00110010" => MCode <= "0001"; -- 00110010 1 RETI when "00110011" => MCode <= "0101"; -- 00110011 1 RLC A when "00110100" => MCode <= "0110"; -- 00110100 2 ADDC A,#data when "00110101" => MCode <= "0110"; -- 00110101 2 ADDC A,data addr when "00110110" => MCode <= "0101"; -- 0011011i 1 ADDC A,@Ri when "00110111" => MCode <= "0101"; -- 0011011i 1 ADDC A,@Ri when "00111000" => MCode <= "0101"; -- 00111rrr 1 ADDC A,Rn when "00111001" => MCode <= "0101"; -- 00111rrr 1 ADDC A,Rn when "00111010" => MCode <= "0101"; -- 00111rrr 1 ADDC A,Rn when "00111011" => MCode <= "0101"; -- 00111rrr 1 ADDC A,Rn when "00111100" => MCode <= "0101"; -- 00111rrr 1 ADDC A,Rn when "00111101" => MCode <= "0101"; -- 00111rrr 1 ADDC A,Rn when "00111110" => MCode <= "0101"; -- 00111rrr 1 ADDC A,Rn when "00111111" => MCode <= "0101"; -- 00111rrr 1 ADDC A,Rn when "01000000" => MCode <= "0010"; -- 01000000 2 JC code addr when "01000001" => MCode <= "0010"; -- aaa00001 2 AJMP code addr when "01000010" => MCode <= "1010"; -- 01000010 2 ORL data addr,A when "01000011" => MCode <= "1011"; -- 01000011 3 ORL data addr,#data when "01000100" => MCode <= "0110"; -- 01000100 2 ORL A,#data when "01000101" => MCode <= "0110"; -- 01000101 2 ORL A,data addr when "01000110" => MCode <= "0101"; -- 0100011i 1 ORL A,@Ri when "01000111" => MCode <= "0101"; -- 0100011i 1 ORL A,@Ri when "01001000" => MCode <= "0101"; -- 01001rrr 1 ORL A,Rn when "01001001" => MCode <= "0101"; -- 01001rrr 1 ORL A,Rn when "01001010" => MCode <= "0101"; -- 01001rrr 1 ORL A,Rn when "01001011" => MCode <= "0101"; -- 01001rrr 1 ORL A,Rn when "01001100" => MCode <= "0101"; -- 01001rrr 1 ORL A,Rn when "01001101" => MCode <= "0101"; -- 01001rrr 1 ORL A,Rn when "01001110" => MCode <= "0101"; -- 01001rrr 1 ORL A,Rn when "01001111" => MCode <= "0101"; -- 01001rrr 1 ORL A,Rn when "01010000" => MCode <= "0010"; -- 01010000 2 JNC code addr when "01010001" => MCode <= "0010"; -- aaa10001 2 ACALL code addr when "01010010" => MCode <= "1010"; -- 01010010 2 ANL data addr,A when "01010011" => MCode <= "1011"; -- 01010011 3 ANL data addr,#data when "01010100" => MCode <= "0110"; -- 01010100 2 ANL A,#data when "01010101" => MCode <= "0110"; -- 01010101 2 ANL A,data addr when "01010110" => MCode <= "0101"; -- 0101011i 1 ANL A,@Ri when "01010111" => MCode <= "0101"; -- 0101011i 1 ANL A,@Ri when "01011000" => MCode <= "0101"; -- 01011rrr 1 ANL A,Rn when "01011001" => MCode <= "0101"; -- 01011rrr 1 ANL A,Rn when "01011010" => MCode <= "0101"; -- 01011rrr 1 ANL A,Rn when "01011011" => MCode <= "0101"; -- 01011rrr 1 ANL A,Rn when "01011100" => MCode <= "0101"; -- 01011rrr 1 ANL A,Rn when "01011101" => MCode <= "0101"; -- 01011rrr 1 ANL A,Rn when "01011110" => MCode <= "0101"; -- 01011rrr 1 ANL A,Rn when "01011111" => MCode <= "0101"; -- 01011rrr 1 ANL A,Rn when "01100000" => MCode <= "0010"; -- 01100000 2 JZ code addr when "01100001" => MCode <= "0010"; -- aaa00001 2 AJMP code addr when "01100010" => MCode <= "1010"; -- 01100010 2 XRL data addr,A when "01100011" => MCode <= "1011"; -- 01100011 3 XRL data addr,#data when "01100100" => MCode <= "0110"; -- 01100100 2 XRL A,#data when "01100101" => MCode <= "0110"; -- 01100101 2 XRL A,data addr when "01100110" => MCode <= "0101"; -- 0110011i 1 XRL A,@Ri when "01100111" => MCode <= "0101"; -- 0110011i 1 XRL A,@Ri when "01101000" => MCode <= "0101"; -- 01101rrr 1 XRL A,Rn when "01101001" => MCode <= "0101"; -- 01101rrr 1 XRL A,Rn when "01101010" => MCode <= "0101"; -- 01101rrr 1 XRL A,Rn when "01101011" => MCode <= "0101"; -- 01101rrr 1 XRL A,Rn when "01101100" => MCode <= "0101"; -- 01101rrr 1 XRL A,Rn when "01101101" => MCode <= "0101"; -- 01101rrr 1 XRL A,Rn when "01101110" => MCode <= "0101"; -- 01101rrr 1 XRL A,Rn when "01101111" => MCode <= "0101"; -- 01101rrr 1 XRL A,Rn when "01110000" => MCode <= "0010"; -- 01110000 2 JNZ code addr when "01110001" => MCode <= "0010"; -- aaa10001 2 ACALL code addr when "01110010" => MCode <= "0010"; -- 01110010 2 ORL C, bit addr when "01110011" => MCode <= "0001"; -- 01110011 1 JMP @A+DPTR when "01110100" => MCode <= "0110"; -- 01110100 2 MOV A,#data when "01110101" => MCode <= "1011"; -- 01110101 3 MOV data addr,#data when "01110110" => MCode <= "1010"; -- 0111011i 2 MOV @Ri,#data when "01110111" => MCode <= "1010"; -- 0111011i 2 MOV @Ri,#data when "01111000" => MCode <= "1010"; -- 01111rrr 2 MOV Rn,#data when "01111001" => MCode <= "1010"; -- 01111rrr 2 MOV Rn,#data when "01111010" => MCode <= "1010"; -- 01111rrr 2 MOV Rn,#data when "01111011" => MCode <= "1010"; -- 01111rrr 2 MOV Rn,#data when "01111100" => MCode <= "1010"; -- 01111rrr 2 MOV Rn,#data when "01111101" => MCode <= "1010"; -- 01111rrr 2 MOV Rn,#data when "01111110" => MCode <= "1010"; -- 01111rrr 2 MOV Rn,#data when "01111111" => MCode <= "1010"; -- 01111rrr 2 MOV Rn,#data when "10000000" => MCode <= "0010"; -- 10000000 2 SJMP code addr when "10000001" => MCode <= "0010"; -- aaa00001 2 AJMP code addr when "10000010" => MCode <= "0010"; -- 10000010 2 ANL C,bit addr when "10000011" => MCode <= "0011"; -- 10000011 1 MOVC A,@A+PC when "10000100" => MCode <= "0001"; -- 10000100 1 DIV AB when "10000101" => MCode <= "1011"; -- 10000101 3 MOV data addr,data addr when "10000110" => MCode <= "1010"; -- 1000011i 2 MOV data addr,@Ri when "10000111" => MCode <= "1010"; -- 1000011i 2 MOV data addr,@Ri when "10001000" => MCode <= "1010"; -- 10001rrr 2 MOV data addr,Rn when "10001001" => MCode <= "1010"; -- 10001rrr 2 MOV data addr,Rn when "10001010" => MCode <= "1010"; -- 10001rrr 2 MOV data addr,Rn when "10001011" => MCode <= "1010"; -- 10001rrr 2 MOV data addr,Rn when "10001100" => MCode <= "1010"; -- 10001rrr 2 MOV data addr,Rn when "10001101" => MCode <= "1010"; -- 10001rrr 2 MOV data addr,Rn when "10001110" => MCode <= "1010"; -- 10001rrr 2 MOV data addr,Rn when "10001111" => MCode <= "1010"; -- 10001rrr 2 MOV data addr,Rn when "10010000" => MCode <= "0011"; -- 10010000 3 MOV DPTR,#data when "10010001" => MCode <= "0010"; -- aaa10001 2 ACALL code addr when "10010010" => MCode <= "1010"; -- 10010010 2 MOV bit addr,C when "10010011" => MCode <= "0011"; -- 10010011 1 MOVC A,@A+DPTR when "10010100" => MCode <= "0110"; -- 10010100 2 SUBB A,#data when "10010101" => MCode <= "0110"; -- 10010101 2 SUBB A,data addr when "10010110" => MCode <= "0101"; -- 1001011i 1 SUBB A,@Ri when "10010111" => MCode <= "0101"; -- 1001011i 1 SUBB A,@Ri when "10011000" => MCode <= "0101"; -- 10011rrr 1 SUBB A,Rn when "10011001" => MCode <= "0101"; -- 10011rrr 1 SUBB A,Rn when "10011010" => MCode <= "0101"; -- 10011rrr 1 SUBB A,Rn when "10011011" => MCode <= "0101"; -- 10011rrr 1 SUBB A,Rn when "10011100" => MCode <= "0101"; -- 10011rrr 1 SUBB A,Rn when "10011101" => MCode <= "0101"; -- 10011rrr 1 SUBB A,Rn when "10011110" => MCode <= "0101"; -- 10011rrr 1 SUBB A,Rn when "10011111" => MCode <= "0101"; -- 10011rrr 1 SUBB A,Rn when "10100000" => MCode <= "0010"; -- 10100000 2 ORL C,/bit addr when "10100001" => MCode <= "0010"; -- aaa00001 2 AJMP code addr when "10100010" => MCode <= "0010"; -- 10100010 2 MOV C,bit addr when "10100011" => MCode <= "0001"; -- 10100011 1 INC DPTR when "10100100" => MCode <= "0101"; -- 10100100 1 MUL AB when "10100101" => MCode <= "0001"; -- 10100101 reserved when "10100110" => MCode <= "1010"; -- 1010011i 2 MOV @Ri,data addr when "10100111" => MCode <= "1010"; -- 1010011i 2 MOV @Ri,data addr when "10101000" => MCode <= "1010"; -- 10101rrr 2 MOV Rn,data addr when "10101001" => MCode <= "1010"; -- 10101rrr 2 MOV Rn,data addr when "10101010" => MCode <= "1010"; -- 10101rrr 2 MOV Rn,data addr when "10101011" => MCode <= "1010"; -- 10101rrr 2 MOV Rn,data addr when "10101100" => MCode <= "1010"; -- 10101rrr 2 MOV Rn,data addr when "10101101" => MCode <= "1010"; -- 10101rrr 2 MOV Rn,data addr when "10101110" => MCode <= "1010"; -- 10101rrr 2 MOV Rn,data addr when "10101111" => MCode <= "1010"; -- 10101rrr 2 MOV Rn,data addr when "10110000" => MCode <= "0010"; -- 10110000 2 ANL C,/bit addr when "10110001" => MCode <= "0010"; -- aaa10001 2 ACALL code addr when "10110010" => MCode <= "1010"; -- 10110010 2 CPL bit addr when "10110011" => MCode <= "0001"; -- 10110011 1 CPL C when "10110100" => MCode <= "0011"; -- 10110100 3 CJNE A,#data,code addr when "10110101" => MCode <= "0011"; -- 10110101 3 CJNE A,data addr,code addr when "10110110" => MCode <= "0011"; -- 1011011i 3 CJNE @Ri,#data,code addr when "10110111" => MCode <= "0011"; -- 1011011i 3 CJNE @Ri,#data,code addr when "10111000" => MCode <= "0011"; -- 10111rrr 3 CJNE Rn,#data,code addr when "10111001" => MCode <= "0011"; -- 10111rrr 3 CJNE Rn,#data,code addr when "10111010" => MCode <= "0011"; -- 10111rrr 3 CJNE Rn,#data,code addr when "10111011" => MCode <= "0011"; -- 10111rrr 3 CJNE Rn,#data,code addr when "10111100" => MCode <= "0011"; -- 10111rrr 3 CJNE Rn,#data,code addr when "10111101" => MCode <= "0011"; -- 10111rrr 3 CJNE Rn,#data,code addr when "10111110" => MCode <= "0011"; -- 10111rrr 3 CJNE Rn,#data,code addr when "10111111" => MCode <= "0011"; -- 10111rrr 3 CJNE Rn,#data,code addr when "11000000" => MCode <= "1010"; -- 11000000 2 PUSH data addr when "11000001" => MCode <= "0010"; -- aaa00001 2 AJMP code addr when "11000010" => MCode <= "1010"; -- 11000010 2 CLR bit addr when "11000011" => MCode <= "0001"; -- 11000011 1 CLR C when "11000100" => MCode <= "0101"; -- 11000100 1 SWAP A when "11000101" => MCode <= "1110"; -- 11000101 2 XCH A,data addr when "11000110" => MCode <= "1101"; -- 1100011i 1 XCH A,@Ri when "11000111" => MCode <= "1101"; -- 1100011i 1 XCH A,@Ri when "11001000" => MCode <= "1101"; -- 11001rrr 1 XCH A,Rn when "11001001" => MCode <= "1101"; -- 11001rrr 1 XCH A,Rn when "11001010" => MCode <= "1101"; -- 11001rrr 1 XCH A,Rn when "11001011" => MCode <= "1101"; -- 11001rrr 1 XCH A,Rn when "11001100" => MCode <= "1101"; -- 11001rrr 1 XCH A,Rn when "11001101" => MCode <= "1101"; -- 11001rrr 1 XCH A,Rn when "11001110" => MCode <= "1101"; -- 11001rrr 1 XCH A,Rn when "11001111" => MCode <= "1101"; -- 11001rrr 1 XCH A,Rn when "11010000" => MCode <= "1010"; -- 11010000 2 POP data addr when "11010001" => MCode <= "0010"; -- aaa10001 2 ACALL code addr when "11010010" => MCode <= "1010"; -- 11010010 2 SETB bit addr when "11010011" => MCode <= "0001"; -- 11010011 1 SETB C when "11010100" => MCode <= "0101"; -- 11010100 1 DA A when "11010101" => MCode <= "1011"; -- 11010101 3 DJNZ data addr, code addr when "11010110" => MCode <= "1101"; -- 1101011i 1 XCHD A,@Ri when "11010111" => MCode <= "1101"; -- 1101011i 1 XCHD A,@Ri when "11011000" => MCode <= "1010"; -- 11011rrr 2 DJNZ Rn,code addr when "11011001" => MCode <= "1010"; -- 11011rrr 2 DJNZ Rn,code addr when "11011010" => MCode <= "1010"; -- 11011rrr 2 DJNZ Rn,code addr when "11011011" => MCode <= "1010"; -- 11011rrr 2 DJNZ Rn,code addr when "11011100" => MCode <= "1010"; -- 11011rrr 2 DJNZ Rn,code addr when "11011101" => MCode <= "1010"; -- 11011rrr 2 DJNZ Rn,code addr when "11011110" => MCode <= "1010"; -- 11011rrr 2 DJNZ Rn,code addr when "11011111" => MCode <= "1010"; -- 11011rrr 2 DJNZ Rn,code addr when "11100000" => MCode <= "0101"; -- 11100000 1 MOVX A,@DPTR when "11100001" => MCode <= "0010"; -- aaa00001 2 AJMP code addr when "11100010" => MCode <= "0101"; -- 1110001i 1 MOVX A,@Ri when "11100011" => MCode <= "0101"; -- 1110001i 1 MOVX A,@Ri when "11100100" => MCode <= "0101"; -- 11100100 1 CLR A when "11100101" => MCode <= "0110"; -- 11100101 2 MOV A,data addr when "11100110" => MCode <= "0101"; -- 1110011i 1 MOV A,@Ri when "11100111" => MCode <= "0101"; -- 1110011i 1 MOV A,@Ri when "11101000" => MCode <= "0101"; -- 11101rrr 1 MOV A,Rn when "11101001" => MCode <= "0101"; -- 11101rrr 1 MOV A,Rn when "11101010" => MCode <= "0101"; -- 11101rrr 1 MOV A,Rn when "11101011" => MCode <= "0101"; -- 11101rrr 1 MOV A,Rn when "11101100" => MCode <= "0101"; -- 11101rrr 1 MOV A,Rn when "11101101" => MCode <= "0101"; -- 11101rrr 1 MOV A,Rn when "11101110" => MCode <= "0101"; -- 11101rrr 1 MOV A,Rn when "11101111" => MCode <= "0101"; -- 11101rrr 1 MOV A,Rn when "11110000" => MCode <= "0001"; -- 11110000 1 MOVX @DPTR,A when "11110001" => MCode <= "0010"; -- aaa10001 2 ACALL code addr when "11110010" => MCode <= "0001"; -- 1111001i 1 MOVX @Ri,A when "11110011" => MCode <= "0001"; -- 1111001i 1 MOVX @Ri,A when "11110100" => MCode <= "0101"; -- 11110100 1 CPL A when "11110101" => MCode <= "1010"; -- 11110101 2 MOV data addr,A when "11110110" => MCode <= "1001"; -- 1111011i 1 MOV @Ri,A when "11110111" => MCode <= "1001"; -- 1111011i 1 MOV @Ri,A when "11111000" => MCode <= "1001"; -- 11111rrr 1 MOV Rn,A when "11111001" => MCode <= "1001"; -- 11111rrr 1 MOV Rn,A when "11111010" => MCode <= "1001"; -- 11111rrr 1 MOV Rn,A when "11111011" => MCode <= "1001"; -- 11111rrr 1 MOV Rn,A when "11111100" => MCode <= "1001"; -- 11111rrr 1 MOV Rn,A when "11111101" => MCode <= "1001"; -- 11111rrr 1 MOV Rn,A when "11111110" => MCode <= "1001"; -- 11111rrr 1 MOV Rn,A when "11111111" => MCode <= "1001"; -- 11111rrr 1 MOV Rn,A when others => MCode <= "----"; end case; end process; end;