📄 tg68_fast.vhd
字号:
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)®isterin(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 + -