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

📄 tg68_fast.vhd

📁 Mc68000 rtl code Simulation and Synthesis
💻 VHD
📖 第 1 页 / 共 5 页
字号:
			set_store_in_tmp <='0';
			exec_DIRECT <= '0';
			exec_write_back <= '0';
			direct_data <= '0';
			use_direct_data <= '0';
			Z_error <= '0';
	  	ELSIF rising_edge(clk) THEN
			IF clkena='1' THEN
				direct_data <= '0';
				IF endOPC='1' THEN
					set_store_in_tmp <='0';
					exec_DIRECT <= '0';
					exec_write_back <= '0';
					use_direct_data <= '0';
					Z_error <= '0';
				ELSE
					IF set_Z_error='1'  THEN
						Z_error <= '1';
					END IF;	
					exec_DIRECT <= set_exec_MOVE;
					IF setstate_mux="10" AND write_back='1' THEN
						exec_write_back <= '1';
					END IF;	
				END IF;
				IF set_direct_data='1' THEN
					direct_data <= '1';
					use_direct_data <= '1';
				END IF;	
				IF set_exec_MOVE='1' AND state="11" THEN
					use_direct_data <= '1';
				END IF;

				IF (exec_DIRECT='1' AND state="00" AND getbrief='0' AND endOPC='0') OR state="10" THEN
					set_store_in_tmp <= '1'; 
					ea_data <= data_read;
				END IF;	
				
				IF writePC_add='1' THEN
					data_write_tmp <= TG68_PC_add;
				ELSIF writePC='1' OR fetchOPC='1' OR interrupt='1' OR (trap_trap='1' AND decodeOPC='1') THEN		--fetchOPC f黵 Trap
					data_write_tmp <= TG68_PC;
				ELSIF execOPC='1' OR (get_ea_now='1' AND ea_only='1') THEN		--get_ea_now='1' AND ea_only='1' ist f黵 pea
					data_write_tmp <= registerin(31 downto 8)&(registerin(7)OR exec_tas)&registerin(6 downto 0);
				ELSIF (exec_DIRECT='1' AND state="10") OR direct_data='1' THEN
					data_write_tmp <= data_read;
				ELSIF movem_busy='1' AND datatype="10" AND movem_presub='1' THEN
					data_write_tmp <= OP2out(15 downto 0)&OP2out(31 downto 16);
				ELSIF (NOT trap AND decodeOPC)='1' OR movem_busy='1'THEN
					data_write_tmp <= OP2out;
				ELSIF writeSR='1'THEN
					data_write_tmp(15 downto 0) <= trap_SR(15 downto 8)& Flags(7 downto 0);
				END IF;
			END IF;	
		END IF;	
	END PROCESS;
	
-----------------------------------------------------------------------------
-- set dest regaddr
-----------------------------------------------------------------------------
PROCESS (opcode, rf_dest_addr_tmp, to_USP, Flags, trap, movem_addr, movem_presub, movem_regaddr, setbriefext, brief, setstackaddr, dest_hbits, dest_areg, data_is_source)
	BEGIN
		rf_dest_addr <= rf_dest_addr_tmp;
		IF rf_dest_addr_tmp(3 downto 0)="1111" AND to_USP='0' THEN
			rf_dest_addr(4) <= Flags(13) OR trap; 
		END IF;
		IF movem_addr='1' THEN
			IF movem_presub='1' THEN
				rf_dest_addr_tmp <= "000"&(movem_regaddr XOR "1111");
			ELSE
				rf_dest_addr_tmp <= "000"&movem_regaddr;
			END IF; 
		ELSIF setbriefext='1' THEN
			rf_dest_addr_tmp <= ("000"&brief(15 downto 12));
		ELSIF setstackaddr='1' THEN	
			rf_dest_addr_tmp <= "0001111";
		ELSIF dest_hbits='1' THEN	
			rf_dest_addr_tmp <= "000"&dest_areg&opcode(11 downto 9);
		ELSE
			IF opcode(5 downto 3)="000" OR data_is_source='1' THEN 			
				rf_dest_addr_tmp <= "000"&dest_areg&opcode(2 downto 0);
			ELSE
				rf_dest_addr_tmp <= "0001"&opcode(2 downto 0);
			END IF;
		END IF;	
	END PROCESS;
	
-----------------------------------------------------------------------------
-- set OP1
-----------------------------------------------------------------------------
PROCESS (reg_QA, OP1out_zero, from_SR, Flags, ea_data_OP1, set_store_in_tmp, ea_data)
	BEGIN
		OP1out <= reg_QA;
		IF OP1out_zero='1' THEN
			OP1out <= (OTHERS => '0');	
		ELSIF from_SR='1' THEN
			OP1out(15 downto 0) <= Flags;
		ELSIF ea_data_OP1='1' AND set_store_in_tmp='1' THEN
			OP1out <= ea_data;
		END IF;
	END PROCESS;
	
-----------------------------------------------------------------------------
-- set source regaddr
-----------------------------------------------------------------------------
PROCESS (opcode, Flags, movem_addr, movem_presub, movem_regaddr, source_lowbits, source_areg, from_USP, rf_source_addr_tmp)
	BEGIN
		rf_source_addr <= rf_source_addr_tmp;
		IF rf_source_addr_tmp(3 downto 0)="1111" AND from_USP='0' THEN
			rf_source_addr(4) <= Flags(13); 
		END IF;
		IF movem_addr='1' THEN
			IF movem_presub='1' THEN
				rf_source_addr_tmp <= "000"&(movem_regaddr XOR "1111");
			ELSE
				rf_source_addr_tmp <= "000"&movem_regaddr;
			END IF; 
		ELSIF from_USP='1' THEN	
			rf_source_addr_tmp <= "0001111";
		ELSIF source_lowbits='1' THEN
			rf_source_addr_tmp <= "000"&source_areg&opcode(2 downto 0);
		ELSE
			rf_source_addr_tmp <= "000"&source_areg&opcode(11 downto 9);
		END IF;	
	END PROCESS;
	
-----------------------------------------------------------------------------
-- set OP2
-----------------------------------------------------------------------------
PROCESS (OP2out, reg_QB, opcode, datatype, OP2out_one, exec_EXT, exec_MOVEQ, EXEC_ADDQ, use_direct_data, data_write_tmp, ea_data_OP1, set_store_in_tmp, ea_data)
	BEGIN
		OP2out(15 downto 0) <= reg_QB(15 downto 0);
		OP2out(31 downto 16) <= (OTHERS => OP2out(15));
		IF OP2out_one='1' THEN
			OP2out(15 downto 0) <= "1111111111111111";
		ELSIF exec_EXT='1' THEN
			IF opcode(6)='0' THEN	--ext.w
				OP2out(15 downto 8) <= (OTHERS => OP2out(7));		
			END IF;	
		ELSIF use_direct_data='1' THEN	
			OP2out <= data_write_tmp;	
		ELSIF ea_data_OP1='0' AND set_store_in_tmp='1' THEN
			OP2out <= ea_data;	
		ELSIF exec_MOVEQ='1' THEN
			OP2out(7 downto 0) <= opcode(7 downto 0);
			OP2out(15 downto 8) <= (OTHERS => opcode(7));
		ELSIF exec_ADDQ='1' THEN
			OP2out(2 downto 0) <= opcode(11 downto 9);
			IF opcode(11 downto 9)="000" THEN
				OP2out(3) <='1';
			ELSE
				OP2out(3) <='0';
			END IF;
			OP2out(15 downto 4) <= (OTHERS => '0');
		ELSIF datatype="10" THEN
			OP2out(31 downto 16) <= reg_QB(31 downto 16);
		END IF;
	END PROCESS;
	
-----------------------------------------------------------------------------
-- addsub
-----------------------------------------------------------------------------
PROCESS (OP1out, OP2out, presub, postadd, execOPC, OP2out_one, datatype, use_SP, use_XZFlag, use_XFlag, Flags, setaddsub)
	BEGIN
		addsub_a <= OP1out;
		addsub_b <= OP2out;
		addsub <= NOT presub;
		c_in(0) <='0';
		IF execOPC='0' AND OP2out_one='0' THEN
			IF datatype="00" AND use_SP='0' THEN
				addsub_b <= "00000000000000000000000000000001";
			ELSIF datatype="10" AND (presub OR postadd)='1' THEN
				addsub_b <= "00000000000000000000000000000100";
			ELSE 
				addsub_b <= "00000000000000000000000000000010";
			END IF;
		ELSE	
			IF (use_XZFlag='1' OR use_XFlag='1') AND Flags(4)='1' THEN
				c_in(0) <= '1';
			END IF;
			addsub <= setaddsub;
		END IF;
    END PROCESS;

-----------------------------------------------------------------------------
-- Write Reg
-----------------------------------------------------------------------------
PROCESS (clkena, OP1in, datatype, presub, postadd, endOPC, regwrena, state, execOPC, last_data_read, movem_addr, rf_dest_addr, reg_QA)
	BEGIN
		Lwrena <= '0';
		Hwrena <= '0';
		registerin <= OP1in;
		
		IF (presub='1' OR postadd='1') AND endOPC='0' THEN		-- -(An)+
			Hwrena <= '1';
			Lwrena <= '1';
		ELSIF Regwrena='1' THEN		--read (mem)
			Lwrena <= '1';
			CASE datatype IS
				WHEN "00" =>		--BYTE
					registerin(15 downto 8) <= reg_QA(15 downto 8);
				WHEN "01" =>		--WORD
					IF rf_dest_addr(3)='1' OR movem_addr='1' THEN
						Hwrena <='1';
					END IF;
				WHEN OTHERS =>		--LONG
					Hwrena <= '1';
			END CASE;
		END IF;	
	END PROCESS;
	
------------------------------------------------------------------------------
--ALU
------------------------------------------------------------------------------		
PROCESS (opcode, OP1in, OP1out, OP2out, datatype, c_out, exec_ABCD, exec_SBCD, exec_CPMAW, exec_MOVESR, bits_out, Flags, flag_z, use_XZFlag, addsub_ofl, 
	dummy_s, dummy_a, niba_hc, niba_h, niba_l, niba_lc, nibs_hc, nibs_h, nibs_l, nibs_lc, addsub_q, movem_addr, data_read, exec_MULU, exec_DIVU, exec_OR,
	exec_AND, exec_Scc, exec_EOR, exec_MOVE, exec_exg, exec_ROT, execOPC, exec_swap, exec_Bits, rot_out, dummy_mulu, dummy_div, save_memaddr, memaddr,
	memaddr_in, ea_only, get_ea_now)
	BEGIN
	
--BCD_ARITH-------------------------------------------------------------------
		--ADC
			dummy_a <= niba_hc&(niba_h(4 downto 1)+('0',niba_hc,niba_hc,'0'))&(niba_l(4 downto 1)+('0',niba_lc,niba_lc,'0'));
			niba_l <= ('0'&OP1out(3 downto 0)&'1') + ('0'&OP2out(3 downto 0)&Flags(4));
			niba_lc <= niba_l(5) OR (niba_l(4) AND niba_l(3)) OR (niba_l(4) AND niba_l(2));

			niba_h <= ('0'&OP1out(7 downto 4)&'1') + ('0'&OP2out(7 downto 4)&niba_lc);
			niba_hc <= niba_h(5) OR (niba_h(4) AND niba_h(3)) OR (niba_h(4) AND niba_h(2));
		--SBC			
			dummy_s <= nibs_hc&(nibs_h(4 downto 1)-('0',nibs_hc,nibs_hc,'0'))&(nibs_l(4 downto 1)-('0',nibs_lc,nibs_lc,'0'));
			nibs_l <= ('0'&OP1out(3 downto 0)&'0') - ('0'&OP2out(3 downto 0)&Flags(4));
			nibs_lc <= nibs_l(5);

			nibs_h <= ('0'&OP1out(7 downto 4)&'0') - ('0'&OP2out(7 downto 4)&nibs_lc);
			nibs_hc <= nibs_h(5);
------------------------------------------------------------------------------		
					
			flag_z <= "000";

			OP1in <= addsub_q;
			IF movem_addr='1' THEN
				OP1in <= data_read;
			ELSIF exec_ABCD='1' THEN	
				OP1in(7 downto 0) <= dummy_a(7 downto 0);
			ELSIF exec_SBCD='1' THEN	
				OP1in(7 downto 0) <= dummy_s(7 downto 0);
			ELSIF exec_MULU='1' THEN
				OP1in <= dummy_mulu;	
			ELSIF exec_DIVU='1' AND execOPC='1' THEN
				OP1in <= dummy_div;	
			ELSIF exec_OR='1' THEN
				OP1in <= OP2out OR OP1out;
			ELSIF exec_AND='1' OR exec_Scc='1' THEN
				OP1in <= OP2out AND OP1out;
			ELSIF exec_EOR='1' THEN
				OP1in <= OP2out XOR OP1out;
			ELSIF exec_MOVE='1' OR exec_exg='1' THEN
				OP1in <= OP2out;
			ELSIF exec_ROT='1' THEN
				OP1in <= rot_out;
			ELSIF save_memaddr='1' THEN
				OP1in <= memaddr;	
			ELSIF get_ea_now='1' AND ea_only='1' THEN
				OP1in <= memaddr_in;	
			ELSIF exec_swap='1' THEN	
				OP1in <= OP1out(15 downto 0)& OP1out(31 downto 16);
			ELSIF exec_bits='1' THEN
				OP1in <= bits_out;	
			ELSIF exec_MOVESR='1' THEN
				OP1in(15 downto 0) <= Flags;
			END IF;
			
			IF use_XZFlag='1' AND flags(2)='0' THEN
				flag_z <= "000";
			ELSIF OP1in(7 downto 0)="00000000" THEN
				flag_z(0) <= '1';
				IF OP1in(15 downto 8)="00000000" THEN
					flag_z(1) <= '1';
					IF OP1in(31 downto 16)="0000000000000000" THEN
						flag_z(2) <= '1';	
					END IF;
				END IF;
			END IF;
			
--					--Flags NZVC
			IF datatype="00" THEN 						--Byte
				set_flags <= OP1IN(7)&flag_z(0)&addsub_ofl(0)&c_out(0);
				IF exec_ABCD='1' THEN	
					set_flags(0) <= dummy_a(8);
				ELSIF exec_SBCD='1' THEN	
					set_flags(0) <= dummy_s(8);
				END IF;
			ELSIF datatype="10" OR exec_CPMAW='1' THEN 						--Long
				set_flags <= OP1IN(31)&flag_z(2)&addsub_ofl(2)&c_out(2);
			ELSE 						--Word
				set_flags <= OP1IN(15)&flag_z(1)&addsub_ofl(1)&c_out(1);
			END IF;
	END PROCESS;
			
------------------------------------------------------------------------------
--Flags
------------------------------------------------------------------------------		
PROCESS (clk, reset, opcode)
	BEGIN
		IF reset='0' THEN
			Flags(13) <= '1';
			SVmode <= '1';
			Flags(10 downto 8) <= "111";
		ELSIF rising_edge(clk) THEN		
		
	        IF clkena = '1' THEN
				IF directSR='1' THEN
					Flags <= data_read(15 downto 0);
				END IF;	
				IF interrupt='1' THEN
					Flags(10 downto 8) <=rIPL_nr;
					SVmode <= '1';
				END IF;	
				IF writeSR='1' OR interrupt='1' THEN
					Flags(13) <='1';
				END IF;	
				IF endOPC='1' AND to_SR='0' THEN
					SVmode <= Flags(13);
				END IF;
				IF execOPC='1' AND to_SR='1' THEN
					Flags(7 downto 0) <= OP1in(7 downto 0);			--CCR
					IF datatype="01" AND (opcode(14)='0' OR opcode(9)='1') THEN		--move to CCR wird als word gespeichert
						Flags(15 downto 8) <= OP1in(15 downto 8);	--SR
						SVmode <= OP1in(13);
					END IF;	
				ELSIF Z_error='1' THEN
					IF opcode(8)='0' THEN
						Flags(3 downto 0) <= "1000";
					ELSE
						Flags(3 downto 0) <= "0100";
					END IF;		
				ELSIF no_Flags='0' AND trap='0' THEN
					IF exec_ADD='1' THEN
						Flags(4) <= set_flags(0);
					ELSIF exec_ROT='1' AND rot_bits/="11" AND rot_nop='0' THEN
						Flags(4) <= rot_XC; 	
					END IF;
					
					IF (exec_ADD OR exec_CMP)='1' THEN
						Flags(3 downto 0) <= set_flags;
					ELSIF decodeOPC='1' and set_exec_ROT='1' THEN
						Flags(1) <= '0';
					ELSIF exec_DIVU='1' THEN
						IF set_V_Flag='1' THEN	
							Flags(3 downto 0) <= "1010";
						ELSE
							Flags(3 downto 0) <= OP1IN(15)&flag_z(1)&"00";
						END IF;
					ELSIF exec_OR='1' OR exec_AND='1' OR exec_EOR='1' OR exec_MOVE='1' OR exec_swap='1' OR exec_MULU='1' THEN
						Flags(3 downto 0) <= set_flags(3 downto 2)&"00";
					ELSIF exec_ROT='1' THEN
						Flags(3 downto 2) <= set_flags(3 downto 2);
						Flags(0) <= rot_XC;
						IF rot_bits="00" THEN		--ASL/ASR
							Flags(1) <= ((set_flags(3) XOR rot_rot) OR Flags(1));	
						END IF;	
					ELSIF exec_bits='1' THEN
						Flags(2) <= NOT one_bit_in;				 	
					END IF;
				END IF;	
			END IF;	
		END IF;	
	END PROCESS;
	
-----------------------------------------------------------------------------
-- execute opcode
-----------------------------------------------------------------------------
PROCESS (clk, reset, OP2out, opcode, fetchOPC, decodeOPC, execOPC, endOPC, prefix, nextpass, condition, set_V_flag, trap, trapd, interrupt, trap_interrupt,
	     Z_error, microaddr, c_in, rot_cnt, one_bit_in, bit_number_reg, bit_number, ea_only, get_ea_now, ea_build, datatype, exec_write_back, get_extendedOPC,
	     Flags, SVmode, movem_addr, movem_busy, getbrief, set_exec_AND, set_exec_OR, set_exec_EOR, TG68_PC_dec)
	BEGIN
		TG68_PC_br8 <= '0';	
		TG68_PC_brw <= '0';	
		TG68_PC_nop <= '0';	
		setstate <= "00";
		Regwrena <= '0';
		microstep <= '0';
		microset <= '0';
		postadd <= '0';
		presub <= '0';
		movem_presub <= '0';
		setaddsub <= '1';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -