📄 it51_alu.vhd
字号:
OpCode = "11110101" or OpCode(7 downto 1) = "1111011" or OpCode(7 downto 3) = "11111" or (OpCode(7 downto 5) = "110" and OpCode(3 downto 0) = "0000") then -- 01110101 3 MOV data addr,#data -- 0111011i 2 MOV @Ri,#data -- 01111rrr 2 MOV Rn,#data -- 1000011i 2 MOV data addr,@Ri -- 10001rrr 2 MOV data addr,Rn -- 10010000 3 MOV DPTR,#data -- Not handled here -- 1010011i 2 MOV @Ri,data addr -- 10101rrr 2 MOV Rn,data addr -- 11110000 1 MOVX @DPTR,A -- 1111001i 1 MOVX @Ri,A -- 11110101 2 MOV data addr,A -- 1111011i 1 MOV @Ri,A -- 11111rrr 1 MOV Rn,A -- 11000000 2 PUSH data addr INC SP: MOV "@SP",<src> -- 11010000 2 POP data addr MOV <dest>,"@SP": DEC SP Do_I_MOV <= '1'; end if; if OpCode = "10000101" then -- 10000101 3 MOV data addr,data addr Do_I_MOVD <= '1'; end if;-- 030714 >>> if OpCode(7 downto 3) = "10111" then -- 10111rrr 3 CJNE Rn,#data,code addr Do_I_CJNE <= '1'; end if; if OpCode(7 downto 1) = "1011011" and not PCPause then -- 1011011i 3 CJNE @Ri,#data,code addr Do_I_CJNE <= '1'; end if;-- <<< -- Bit Operations Do_B_Inv <= '0'; Do_B_C_BA <= '0'; Do_B_C_Dir <= '0'; Do_B_BA_Dir <= '0'; Do_B_MOV <= '0'; Do_B_JBC <= '0'; Do_B_Op <= OpCode(5 downto 4); if OpCode(1 downto 0) = "00" then Do_B_Inv <= '1'; end if; if OpCode = "01110010" or OpCode = "10000010" or OpCode = "10100000" or OpCode = "10100010" or OpCode = "10110000" then -- 01110010 2 ORL C, bit addr -- 10000010 2 ANL C,bit addr -- 10100000 2 ORL C,/bit addr -- 10100010 2 MOV C,bit addr -- 10110000 2 ANL C,/bit addr Do_B_C_BA <= '1'; end if; if OpCode = "10110011" or OpCode = "11000011" or OpCode = "11010011" then -- 10110011 1 CPL C -- 11000011 1 CLR C -- 11010011 1 SETB C Do_B_C_Dir <= '1'; end if; if OpCode = "10110010" or OpCode = "11000010" or OpCode = "11010010" then -- 10110010 2 CPL bit addr -- 11000010 2 CLR bit addr -- 11010010 2 SETB bit addr Do_B_BA_Dir <= '1'; end if; if OpCode = "10010010" then -- 10010010 2 MOV bit addr,C Do_B_MOV <= '1'; end if; if OpCode = "00010000" then -- 00010000 3 JBC bit addr, code addr Do_B_JBC <= '1'; end if; Last_r <= Last; end if; end process;-- YFC >>>-- BUG op_d4 DA : process (ACC, CY_In, AC_In) variable accu : unsigned(8 downto 0); variable lc : std_logic; begin accu := unsigned("0" & ACC); if AC_In = '1' or accu(3 downto 0) > 9 then accu := accu + 6; end if; lc := accu(8);-- if CY_In = '1' or accu(7 downto 4) > 9 then if CY_In = '1' or accu(8 downto 4) > 9 then accu := accu + 96; end if; accu(8) := accu(8) or lc or CY_In; ADA <= std_logic_vector(accu); end process;-- <<< MOV : process (MOV_Op, IB, ACC, IA_d) begin case MOV_Op is when "0111" => -- 01110101 3 MOV data addr,#data -- 0111011i 2 MOV @Ri,#data -- 01111rrr 2 MOV Rn,#data MOV_Q <= IB; when "1000" => -- 10000101 3 MOV data addr,data addr -- 1000011i 2 MOV data addr,@Ri -- 10001rrr 2 MOV data addr,Rn MOV_Q <= IA_d; when "1010" => -- 1010011i 2 MOV @Ri,data addr -- 10101rrr 2 MOV Rn,data addr MOV_Q <= IA_d; when "1111" => -- 11110000 1 MOVX @DPTR,A -- 1111001i 1 MOVX @Ri,A -- 11110101 2 MOV data addr,A -- 1111011i 1 MOV @Ri,A -- 11111rrr 1 MOV Rn,A MOV_Q <= ACC; when "1100"|"1101"=> -- 11000000 2 PUSH data addr INC SP: MOV "@SP",<src> -- 11010000 2 POP data addr MOV <dest>,"@SP": DEC SP MOV_Q <= IA_d; when others => MOV_Q <= "--------"; end case; end process; AddSub(ACC(3 downto 0), AOP2(3 downto 0), Do_A_SUBB, Do_A_SUBB xor (Do_A_Carry and CY_In), AS_Q(3 downto 0), AS_AC); AddSub(ACC(6 downto 4), AOP2(6 downto 4), Do_A_SUBB, AS_AC, AS_Q(6 downto 4), AS_Carry7); AddSub(ACC(7 downto 7), AOP2(7 downto 7), Do_A_SUBB, AS_Carry7, AS_Q(7 downto 7), AS_CY); AddSub(IA, IB, '1', '1', CJNE_Q, CJNE_CY_n); -- Accumulator ALU AOP2 <= IB when Do_A_Imm = '1' else IA; ACC_Q <= ACC_Q_0 and ACC_Q_1 and ACC_Q_2 and ACC_Q_3 and ACC_Q_3 and ACC_Q_4 and ACC_Q_5 and ACC_Q_6 and ACC_Q_7 and ACC_Q_8 and ACC_Q_9 and ACC_Q_10 and ACC_Q_11 and ACC_Q_12 and ACC_Q_13 and ACC_Q_14 and ACC_Q_15 and ACC_Q_16 and ACC_Q_17 and ACC_Q_18 and ACC_Q_19 ; ACC_Q_0 <= "00000000" when Do_A_CLR ='1' else (others =>'1'); -- No flags ACC_Q_1 <= ACC(0) & ACC(7 downto 1) when Do_A_RR ='1' else (others =>'1'); -- No flags ACC_Q_2 <= CY_In & ACC(7 downto 1) when Do_A_RRC ='1' else (others =>'1'); -- Sets CY ACC_Q_3 <= ACC(6 downto 0) & ACC(7) when Do_A_RL ='1' else (others =>'1'); -- No flags ACC_Q_4 <= ACC(6 downto 0) & CY_In when Do_A_RLC ='1' else (others =>'1'); -- Sets CY ACC_Q_5 <= (ACC + 1) when Do_A_INC ='1' else (others =>'1'); -- No flags ACC_Q_6 <= (ACC - 1) when Do_A_DEC ='1' else (others =>'1'); -- No flags ACC_Q_7 <= not ACC when Do_A_CPL ='1' else (others =>'1'); -- No flags ACC_Q_8 <= ACC or AOP2 when Do_A_ORL ='1' else (others =>'1'); -- No flags ACC_Q_9 <= ACC and AOP2 when Do_A_ANL ='1' else (others =>'1'); -- No flags ACC_Q_10 <= ACC xor AOP2 when Do_A_XRL ='1' else (others =>'1'); -- No flags ACC_Q_11 <= ACC(3 downto 0) & ACC(7 downto 4) when Do_A_SWAP='1' else (others =>'1'); -- No flags ACC_Q_12 <= IA when Do_A_XCH ='1' else (others =>'1'); -- No flags ACC_Q_13 <= ACC(7 downto 4) & IA(3 downto 0) when Do_A_XCHD='1' else (others =>'1'); -- No flags ACC_Q_14 <= AOP2 when Do_A_MOV ='1' else (others =>'1'); -- No flags ACC_Q_15 <= ADA(7 downto 0) when Do_A_DA ='1' else (others =>'1'); -- Sets CY ACC_Q_16 <= AS_Q when Do_A_ADD ='1' else (others =>'1'); -- Sets CY, (AC, OV) ACC_Q_17 <= AS_Q when Do_A_SUBB='1' else (others =>'1'); -- Sets CY, (AC, OV) ACC_Q_18 <= Mul_Q(7 downto 0) when Do_A_MUL ='1' else (others =>'1'); -- Sets OV ACC_Q_19 <= Div_Q(7 downto 0) when Do_A_DIV ='1' else (others =>'1'); -- Sets OV-- ACC_Q_20 <= "--------"; CY_Out <= ACC(0) when Do_A_RRC ='1' else ACC(7) when Do_A_RLC ='1' else ADA(8) when Do_A_DA ='1' else AS_CY xor Do_A_SUBB when Do_A_ADD ='1' or Do_A_SUBB = '1' else not CJNE_CY_n when Do_I_CJNE ='1' else not CY_In when Do_B_C_Dir='1' and Do_B_Op = "11" else '0' when Do_B_C_Dir='1' and Do_B_Op = "00" else '1' when Do_B_C_Dir='1' and Do_B_Op = "01" else CY_In or Bit_IsOne when Do_B_C_BA ='1' and Do_B_Op = "11" and Do_B_Inv = '0' else CY_In and Bit_IsOne when Do_B_C_BA ='1' and Do_B_Op = "00" and Do_B_Inv = '0' else CY_In or Bit_IsOne when Do_B_C_BA ='1' and Do_B_Op = "10" and Do_B_Inv = '1' else Bit_IsOne when Do_B_C_BA ='1' and Do_B_Op = "10" and Do_B_Inv = '0' else CY_In and Bit_IsOne when Do_B_C_BA ='1' and Do_B_Op = "11" and Do_B_Inv = '1' else '0' when Do_A_DIV ='1' or Do_A_MUL = '1' else '-'; OV_Out <= AS_CY xor AS_Carry7 when Do_A_ADD = '1' or Do_A_SUBB = '1' else Mul_OV when Do_A_MUL = '1' else Div_OV when Do_A_DIV = '1' else '-'; AC_Out <= AS_AC xor Do_A_SUBB when Do_A_ADD = '1' or Do_A_SUBB = '1' else 'Z'; -- Auxiliary ALU IOP <= IB when Do_I_Imm = '1' else ACC;-- IDCPBL_Q <= (IA + 1) when Do_I_INC = '1' else -- No flags-- (IA - 1) when Do_I_DEC = '1' else -- No flags-- IOP or IA when Do_I_ORL = '1' else -- No flags-- IOP and IA when Do_I_ANL = '1' else -- No flags-- IOP xor IA when Do_I_XRL = '1' else -- No flags-- ACC when Do_A_XCH = '1' else -- No flags-- IA(7 downto 4) & ACC(3 downto 0) when Do_A_XCHD = '1' else -- No flags-- MOV_Q when Do_I_MOV = '1' else -- No flags-- IA_d when Do_I_MOVD = '1' else -- No flags-- Bit_Result when Do_B_JBC = '1' or-- Do_B_BA_Dir = '1' or-- Do_B_MOV = '1' else-- "--------"; IDCPBL: process (Do_B_JBC, Do_B_BA_Dir, Do_B_MOV, Bit_Result, Do_I_MOV, Do_I_MOVD, MOV_Q, IA_d, Do_A_XCH, Do_A_XCHD, ACC, IA, Do_I_INC, Do_I_DEC, Do_I_ORL, Do_I_ANL, Do_I_XRL, IOP) variable X1 : std_logic_vector(1 downto 0); variable X2 : std_logic_vector(1 downto 0); variable X3 : std_logic_vector(4 downto 0); begin X1 := Do_I_MOV & Do_I_MOVD; X2 := Do_A_XCH & Do_A_XCHD; X3 := Do_I_INC & Do_I_DEC & Do_I_ORL & Do_I_ANL & Do_I_XRL; IDCPBL_Q <= "--------"; if Do_B_JBC = '1' or Do_B_BA_Dir = '1' or Do_B_MOV = '1' then IDCPBL_Q <= Bit_Result; end if; case (X1) is when "10" => IDCPBL_Q <= MOV_Q; when "01" => IDCPBL_Q <= IA_d; when others => null; end case; case (X2) is when "10" => IDCPBL_Q <= ACC; when "01" => IDCPBL_Q <= IA(7 downto 4) & ACC(3 downto 0); when others => null; end case; case (X3) is when "10000" => IDCPBL_Q <= (IA + 1); when "01000" => IDCPBL_Q <= (IA - 1); when "00100" => IDCPBL_Q <= IOP or IA; when "00010" => IDCPBL_Q <= IOP and IA; when "00001" => IDCPBL_Q <= IOP xor IA; when others => null; end case; end process; DJNZ <= '1' when (IA - 1) /= "00000000" else '0'; CJNE <= '1' when Do_I_CJNE = '1' and CJNE_Q /= "00000000" else '0' when Do_I_CJNE = '1' else '1' when AS_Q /= "00000000" else '0'; -- Sets CY -- Bit operations Bit_Op1 <= IA and not Bit_Pattern; Bit_Op2 <= Bit_Pattern and not IA when Do_B_Inv = '1' else Bit_Pattern and IA; Bit_IsOne <= '0' when Bit_Op2 = "00000000" else '1'; Bit_Result <= IA xor Bit_Pattern when Do_B_BA_Dir = '1' and Do_B_Op = "11" else Bit_Op1 when (Do_B_BA_Dir = '1' and Do_B_Op = "00") or Do_B_JBC = '1' else IA or Bit_Pattern when Do_B_BA_Dir = '1' and Do_B_Op = "01" else Bit_Op1 or (Bit_Pattern and CY_In & CY_In & CY_In & CY_In & CY_In & CY_In & CY_In & CY_In) when Do_B_MOV = '1' else "--------"; -- Mul / Div md : IT51_MD port map(Clk, Rst_n, ACC, B, Mul_Q, Mul_OV, Div_Q, Div_OV, Div_Rdy); B_Q <= Mul_Q(15 downto 8) when Do_A_MUL = '1' else -- Sets OV Div_Q(15 downto 8) when Do_A_DIV = '1' else "--------"; -- Sets OV -- Flags AC_Wr <= Last_r when (Do_A_ADD = '1' or Do_A_SUBB = '1') and Do_A_CJNE = '0' else '0'; OV_Wr <= Last_r when ((Do_A_ADD = '1' or Do_A_SUBB = '1') and Do_A_CJNE = '0') or Do_A_DIV = '1' or Do_A_MUL = '1' else '0'; CY_Wr <= Last_r when Do_A_ADD = '1' or Do_A_SUBB = '1' or Do_A_RRC = '1' or Do_A_RLC = '1' or Do_I_CJNE = '1' or Do_A_DA = '1' or Do_B_C_BA = '1' or Do_B_C_Dir = '1' or Do_A_DIV = '1' or Do_A_MUL = '1' else '0';end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -