📄 tg68_fast.vhd
字号:
memaddr, memaddr_a, set_mem_addsub, movem_presub, movem_busy, state, PCmarker, execOPC, datatype, setdisp, setdispbrief, briefext, setdispbyte, brief,
trap_vector, interrupt, set_mem_rega, reg_QA, setaddrlong, data_read, decodeOPC, TG68_PC, data_in, long_done, last_data_read, mem_byte,
data_write_tmp, addsub_q, set_vectoraddr)
BEGIN
clkena <= clkena_in AND NOT longread AND NOT get_extendedOPC;
-- IF rising_edge(clk) THEN
-- IF clkena='1' THEN
-- trap_vector <= "000000000000000000000000011"&rIPL_nr&"00";
trap_vector <= (others => '0');
-- IF trap_addr_fault='1' THEN
-- trap_vector(7 downto 0) <= X"08";
-- END IF;
-- IF trap_addr_error='1' THEN
-- trap_vector(7 downto 0) <= X"0C";
-- END IF;
IF trap_illegal='1' THEN
trap_vector(7 downto 0) <= X"10";
-- END IF;
ELSIF z_error='1' THEN
trap_vector(7 downto 0) <= X"14";
-- END IF;
-- IF trap_chk='1' THEN
-- trap_vector(7 downto 0) <= X"18";
-- END IF;
ELSIF trap_trapv='1' THEN
trap_vector(7 downto 0) <= X"1C";
-- END IF;
ELSIF trap_priv='1' THEN
trap_vector(7 downto 0) <= X"20";
-- END IF;
-- IF trap_trace='1' THEN
-- trap_vector(7 downto 0) <= X"24";
-- END IF;
ELSIF trap_1010='1' THEN
trap_vector(7 downto 0) <= X"28";
-- END IF;
ELSIF trap_1111='1' THEN
trap_vector(7 downto 0) <= X"2C";
-- END IF;
ELSIF trap_trap='1' THEN
trap_vector(7 downto 2) <= "10"&opcode(3 downto 0);
-- ELSIF trap_interrupt='1' THEN
ELSE
trap_vector(7 downto 2) <= "011"&rIPL_nr;
-- END IF;
-- END IF;
END IF;
memaddr_a(3 downto 0) <= "0000";
memaddr_a(7 downto 4) <= (OTHERS=>memaddr_a(3));
memaddr_a(15 downto 8) <= (OTHERS=>memaddr_a(7));
memaddr_a(31 downto 16) <= (OTHERS=>memaddr_a(15));
IF movem_presub='1' THEN
IF movem_busy='1' OR longread='1' THEN
memaddr_a(3 downto 0) <= "1110";
END IF;
ELSIF state(1)='1' OR (get_extendedOPC='1' AND PCmarker='1') THEN
memaddr_a(1) <= '1';
ELSIF execOPC='1' THEN
IF datatype="10" THEN
memaddr_a(3 downto 0) <= "1100";
ELSE
memaddr_a(3 downto 0) <= "1110";
END IF;
ELSIF setdisp='1' THEN
IF setdispbrief='1' THEN
memaddr_a <= briefext;
ELSIF setdispbyte='1' THEN
memaddr_a(7 downto 0) <= brief(7 downto 0);
ELSE
memaddr_a(15 downto 0) <= brief;
END IF;
END IF;
memaddr_in <= memaddr+memaddr_a;
IF longread='0' THEN
IF set_mem_addsub='1' THEN
memaddr_in <= addsub_q;
ELSIF set_vectoraddr='1' THEN
memaddr_in <= trap_vector;
ELSIF interrupt='1' THEN
memaddr_in <= "1111111111111111111111111111"&rIPL_nr&'0';
ELSIF set_mem_rega='1' THEN
memaddr_in <= reg_QA;
ELSIF setaddrlong='1' AND longread='0' THEN
memaddr_in <= data_read;
ELSIF decodeOPC='1' THEN
memaddr_in <= TG68_PC;
END IF;
END IF;
data_read(15 downto 0) <= data_in;
data_read(31 downto 16) <= (OTHERS=>data_in(15));
IF long_done='1' THEN
data_read(31 downto 16) <= last_data_read;
END IF;
IF mem_byte='1' AND memaddr(0)='0' THEN
data_read(7 downto 0) <= data_in(15 downto 8);
END IF;
IF longread='1' THEN
data_write <= data_write_tmp(31 downto 16);
ELSE
data_write(7 downto 0) <= data_write_tmp(7 downto 0);
IF mem_byte='1' THEN
data_write(15 downto 8) <= data_write_tmp(7 downto 0);
ELSE
data_write(15 downto 8) <= data_write_tmp(15 downto 8);
IF datatype="00" THEN
data_write(7 downto 0) <= data_write_tmp(15 downto 8);
END IF;
END IF;
END IF;
IF reset='0' THEN
longread <= '0';
long_done <= '0';
ELSIF rising_edge(clk) THEN
IF clkena_in='1' THEN
last_data_read <= data_in;
long_done <= longread;
IF get_extendedOPC='0' OR (get_extendedOPC='1' AND PCmarker='1') THEN
memaddr <= memaddr_in;
END IF;
IF get_extendedOPC='0' THEN
IF ((setstate_mux(1)='1' AND datatype="10") OR longreaddirect='1') AND longread='0' AND interrupt='0' THEN
longread <= '1';
ELSE
longread <= '0';
END IF;
END IF;
END IF;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- brief
-----------------------------------------------------------------------------
process (clk, brief, OP1out)
begin
IF brief(11)='1' THEN
OP1outbrief <= OP1out(31 downto 16);
ELSE
OP1outbrief <= (OTHERS=>OP1out(15));
END IF;
IF rising_edge(clk) THEN
IF clkena='1' THEN
-- briefext <= OP1outbrief&OP1out(15 downto 0);
CASE brief(10 downto 9) IS
WHEN "00" => briefext <= OP1outbrief&OP1out(15 downto 0);
WHEN "01" => briefext <= OP1outbrief(14 downto 0)&OP1out(15 downto 0)&'0';
WHEN "10" => briefext <= OP1outbrief(13 downto 0)&OP1out(15 downto 0)&"00";
WHEN "11" => briefext <= OP1outbrief(12 downto 0)&OP1out(15 downto 0)&"000";
END CASE;
end if;
end if;
end process;
-----------------------------------------------------------------------------
-- PC Calc + fetch opcode
-----------------------------------------------------------------------------
process (clk, reset, opcode, TG68_PC, TG68_PC_dec, TG68_PC_br8, TG68_PC_brw, PC_dataa, PC_datab, execOPC, last_data_read, get_extendedOPC,
setstate_delay, setstate)
begin
PC_dataa <= TG68_PC;
PC_datab(2 downto 0) <= "010";
PC_datab(7 downto 3) <= (others => PC_datab(2));
PC_datab(15 downto 8) <= (others => PC_datab(7));
PC_datab(31 downto 16) <= (others => PC_datab(15));
IF execOPC='0' THEN
IF TG68_PC_br8='1' THEN
PC_datab(7 downto 0) <= opcode(7 downto 0);
END IF;
IF TG68_PC_dec(1)='1' THEN
PC_datab(2) <= '1';
END IF;
IF TG68_PC_brw = '1' THEN
PC_datab(15 downto 0) <= last_data_read(15 downto 0);
END IF;
END IF;
TG68_PC_add <= PC_dataa+PC_datab;
IF get_extendedOPC='1' THEN
setstate_mux <= setstate_delay;
ELSE
setstate_mux <= setstate;
END IF;
IF reset = '0' THEN
opcode(15 downto 12) <= X"7"; --moveq
opcode(8 downto 6) <= "010"; --long
TG68_PC <= (others =>'0');
state <= "01";
decodeOPC <= '0';
fetchOPC <= '0';
endOPC <= '0';
interrupt <= '0';
trap_interrupt <= '1';
execOPC <= '0';
getbrief <= '0';
TG68_PC_dec <= "00";
directPC <= '0';
directSR <= '0';
stop <= '0';
exec_ADD <= '0';
exec_OR <= '0';
exec_AND <= '0';
exec_EOR <= '0';
exec_MOVE <= '0';
exec_MOVEQ <= '0';
exec_MOVESR <= '0';
exec_ADDQ <= '0';
exec_CMP <= '0';
exec_ROT <= '0';
exec_EXT <= '0';
exec_ABCD <= '0';
exec_SBCD <= '0';
exec_MULU <= '0';
exec_DIVU <= '0';
exec_Scc <= '0';
exec_CPMAW <= '0';
mem_byte <= '0';
rot_cnt <="000001";
get_extendedOPC <= '0';
get_bitnumber <= '0';
get_movem_mask <= '0';
test_delay <= "000";
PCmarker <= '0';
ELSIF rising_edge(clk) THEN
IF clkena_in='1' THEN
get_extendedOPC <= set_get_extendedOPC;
get_bitnumber <= set_get_bitnumber;
get_movem_mask <= set_get_movem_mask;
setstate_delay <= setstate;
TG68_PC_dec <= TG68_PC_dec(0)&set_TG68_PC_dec;
IF directPC='1' AND clkena='1' THEN
TG68_PC <= data_read;
ELSIF ea_to_pc='1' AND longread='0' THEN
TG68_PC <= memaddr_in;
ELSIF (state ="00" AND TG68_PC_nop='0') OR TG68_PC_br8='1' OR TG68_PC_brw='1' OR TG68_PC_dec(1)='1' THEN
TG68_PC <= TG68_PC_add;
END IF;
IF get_bitnumber='1' THEN
bit_number_reg <= data_read(4 downto 0);
END IF;
IF clkena='1' OR get_extendedOPC='1' THEN
IF set_get_extendedOPC='1' THEN
state <= "00";
ELSIF get_extendedOPC='1' THEN
state <= setstate_mux;
ELSIF fetchOPC='1' OR (state="10" AND write_back='1' AND setstate/="10") OR set_rot_cnt/="000001" OR stop='1' THEN
state <= "01"; --decode cycle, execute cycle
ELSE
state <= setstate_mux;
END IF;
IF setstate_mux(1)='1' AND datatype="00" AND set_get_extendedOPC='0' THEN
mem_byte <= '1';
ELSE
mem_byte <= '0';
END IF;
END IF;
END IF;
IF clkena='1' THEN
exec_ADD <= '0';
exec_OR <= '0';
exec_AND <= '0';
exec_EOR <= '0';
exec_MOVE <= '0';
exec_MOVEQ <= '0';
exec_MOVESR <= '0';
exec_ADDQ <= '0';
exec_CMP <= '0';
exec_ROT <= '0';
exec_ABCD <= '0';
exec_SBCD <= '0';
fetchOPC <= '0';
exec_CPMAW <= '0';
endOPC <= '0';
interrupt <= '0';
execOPC <= '0';
exec_EXT <= '0';
exec_Scc <= '0';
decodeOPC <= fetchOPC;
directPC <= set_directPC;
directSR <= set_directSR;
exec_MULU <= set_exec_MULU;
exec_DIVU <= set_exec_DIVU;
stop <= set_stop OR (stop AND NOT interrupt);
IF set_PCmarker='1' THEN
PCmarker <= '1';
ELSIF (state="10" AND longread='0') OR (ea_only='1' AND get_ea_now='1') THEN
PCmarker <= '0';
END IF;
IF (decodeOPC OR execOPC)='1' THEN
rot_cnt <= set_rot_cnt;
END IF;
IF microstep='0' AND setstate_mux="00" AND (setnextpass='0' OR ea_only='1') AND endOPC='0' AND movem_busy='0' AND set_movem_busy='0' AND set_get_bitnumber='0' THEN
nextpass <= '0';
-- IF stop='0' THEN
IF (exec_write_back='0' OR state="11") AND set_rot_cnt="000001" THEN
endOPC <= '1';
IF Flags(10 downto 8)<IPL_nr OR IPL_nr="111" THEN
interrupt <= '1';
trap_interrupt <= '1';
rIPL_nr <= IPL_nr;
ELSE
IF stop='0' THEN
fetchOPC <= '1';
END IF;
END IF;
END IF;
IF exec_write_back='0' OR state/="11" THEN
IF stop='0' THEN
execOPC <= '1';
END IF;
exec_ADD <= set_exec_ADD;
exec_OR <= set_exec_OR;
exec_AND <= set_exec_AND;
exec_EOR <= set_exec_EOR;
exec_MOVE <= set_exec_MOVE;
exec_MOVEQ <= set_exec_MOVEQ;
exec_MOVESR <= set_exec_MOVESR;
exec_ADDQ <= set_exec_ADDQ;
exec_CMP <= set_exec_CMP;
exec_ROT <= set_exec_ROT;
exec_tas <= set_exec_tas;
exec_EXT <= set_exec_EXT;
exec_ABCD <= set_exec_ABCD;
exec_SBCD <= set_exec_SBCD;
exec_Scc <= set_exec_Scc;
exec_CPMAW <= set_exec_CPMAW;
END IF;
-- END IF;
ELSE
IF endOPC='0' AND (setnextpass='1' OR (regdirectsource='1' AND decodeOPC='1')) THEN
nextpass <= '1';
END IF;
END IF;
IF interrupt='1' THEN
opcode(15 downto 12) <= X"7"; --moveq
opcode(8 downto 6) <= "010"; --long
-- trap_PC <= TG68_PC;
END IF;
IF fetchOPC='1' THEN
trap_interrupt <= '0';
IF (test_IPL='1' AND (Flags(10 downto 8)<IPL_nr OR IPL_nr="111")) OR to_SR='1' THEN
-- IF (test_IPL='1' AND (Flags(10 downto 8)<IPL_nr OR IPL_nr="111")) OR to_SR='1' OR opcode(15 downto 6)="0100111011" THEN --nur f黵 Validator
opcode <= X"60FE";
IF to_SR='0' THEN
test_delay <= "001";
END IF;
ELSE
opcode <= data_read(15 downto 0);
END IF;
getbrief <= '0';
-- trap_PC <= TG68_PC;
ELSE
test_delay <= test_delay(1 downto 0)&'0';
getbrief <= setgetbrief;
END IF;
IF decodeOPC='1' OR interrupt='1' THEN
trap_SR <= Flags;
END IF;
IF getbrief='1' THEN
brief <= data_read(15 downto 0);
END IF;
end if;
end if;
end process;
-----------------------------------------------------------------------------
-- handle EA_data, data_write_tmp
-----------------------------------------------------------------------------
PROCESS (clk, reset, opcode)
BEGIN
IF reset = '0' THEN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -