⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 it51_alu.vhd

📁 這是最新版本修正過後的8051,經過debug並有實現在某家公司的silicon上ㄛ
💻 VHD
📖 第 1 页 / 共 3 页
字号:
				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 + -