diff --git a/tests/tg68k/Makefile b/tests/tg68k/Makefile new file mode 100644 index 0000000..514efeb --- /dev/null +++ b/tests/tg68k/Makefile @@ -0,0 +1,55 @@ +CODE = testcode +SRCS = TG68K_ALU.vhd TG68K_Pack.vhd TG68KdotC_Kernel.vhd $(CODE)_defs_pack.vhd $(CODE)_pack.vhd tg68k_tb.vhd +OBJS = $(SRCS:.vhd=.o) +ROOT = tg68k_tb +VCD = $(ROOT).vcd +GHW = $(ROOT).ghw +TOOLS=../../../tools +PATCH = tg68k_pack_unpk.patch +ZIP = tg68k_pack_unpk.zip + +all: $(GHW) + +TG68KdotC_Kernel.o: TG68K_Pack.o +TG68K_ALU.o: TG68K_Pack.o +tg68k_tb.o: $(CODE)_pack.o +$(CODE)_pack.o: $(CODE)_defs_pack.o + +%.o: %.vhd # work-obj93.cf + ghdl -a $< + +work-obj93.cf: $(SRCS) + ghdl -i $(SRCS) + +$(ROOT): $(OBJS) + ghdl -e $@ + +clean:: + rm -f work-obj93.cf *.o $(CODE).bin $(CODE)_pack.vhd *~ *.lst *.ghw $(ROOT) + +$(VCD): $(ROOT) Makefile + ghdl -r $< --ieee-asserts=disable --stop-time=10000ns --vcd=$@ + +$(GHW): $(ROOT) Makefile + ghdl -r $< --ieee-asserts=disable --stop-time=10000ns --wave=$@ + +#view: $(VCD) +# gtkwave $< $(ROOT).sav + +view: $(GHW) + gtkwave $< $(ROOT).sav + +%.bin: %.s + $(TOOLS)/vasm/vasmm68k_mot -m68020 -Fbin -o $@ -L $(CODE).lst -nosym $< + hexdump -C $@ + +%_pack.vhd: %.bin + srec_cat $< -binary -o $@ --VHdl 2 testcode + +zip:: + make clean + make patch + zip -r $(ZIP) *.vhd $(CODE)* Makefile *.sav orig + +patch:: + for i in orig/*.vhd ; do diff -Nbaur $$i `basename $$i`; done >$(PATCH) | true diff --git a/tests/tg68k/TG68K_ALU.vhd b/tests/tg68k/TG68K_ALU.vhd new file mode 100644 index 0000000..0b6eebf --- /dev/null +++ b/tests/tg68k/TG68K_ALU.vhd @@ -0,0 +1,934 @@ +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2009-2011 Tobias Gubener -- +-- Subdesign fAMpIGA by TobiFlex -- +-- -- +-- This source file is free software: you can redistribute it and/or modify -- +-- it under the terms of the GNU General Public License as published -- +-- by the Free Software Foundation, either version 3 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- This source file is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU General Public License -- +-- along with this program. If not, see . -- +-- -- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +-- use ieee.std_logic_unsigned.all; +use IEEE.numeric_std.all; +use work.TG68K_Pack.all; + +entity TG68K_ALU is +generic( + MUL_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL, + DIV_Mode : integer := 0 --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV, + ); + port(clk : in std_logic; + Reset : in std_logic; + clkena_lw : in std_logic:='1'; + execOPC : in bit; + exe_condition : in std_logic; + exec_tas : in std_logic; + long_start : in bit; + movem_presub : in bit; + set_stop : in bit; + Z_error : in bit; + rot_bits : in std_logic_vector(1 downto 0); + exec : in bit_vector(lastOpcBit downto 0); + OP1out : in std_logic_vector(31 downto 0); + OP2out : in std_logic_vector(31 downto 0); + reg_QA : in std_logic_vector(31 downto 0); + reg_QB : in std_logic_vector(31 downto 0); + opcode : in std_logic_vector(15 downto 0); + datatype : in std_logic_vector(1 downto 0); + exe_opcode : in std_logic_vector(15 downto 0); + exe_datatype : in std_logic_vector(1 downto 0); + sndOPC : in std_logic_vector(15 downto 0); + last_data_read : in std_logic_vector(15 downto 0); + data_read : in std_logic_vector(15 downto 0); + FlagsSR : in std_logic_vector(7 downto 0); + micro_state : in micro_states; + bf_ext_in : in std_logic_vector(7 downto 0); + bf_ext_out : out std_logic_vector(7 downto 0); + bf_shift : in std_logic_vector(5 downto 0); + bf_width : in std_logic_vector(5 downto 0); + bf_loffset : in std_logic_vector(4 downto 0); + + set_V_Flag : buffer bit; + Flags : buffer std_logic_vector(7 downto 0); + c_out : buffer std_logic_vector(2 downto 0); + addsub_q : buffer std_logic_vector(31 downto 0); + ALUout : out std_logic_vector(31 downto 0) + ); +end TG68K_ALU; + +architecture logic of TG68K_ALU is +----------------------------------------------------------------------------- +----------------------------------------------------------------------------- +-- ALU and more +----------------------------------------------------------------------------- +----------------------------------------------------------------------------- + signal OP1in : std_logic_vector(31 downto 0); + signal addsub_a : std_logic_vector(31 downto 0); + signal addsub_b : std_logic_vector(31 downto 0); + signal notaddsub_b : std_logic_vector(33 downto 0); + signal add_result : std_logic_vector(33 downto 0); + signal addsub_ofl : std_logic_vector(2 downto 0); + signal opaddsub : bit; + signal c_in : std_logic_vector(3 downto 0); + signal flag_z : std_logic_vector(2 downto 0); + signal set_Flags : std_logic_vector(3 downto 0); --NZVC + signal CCRin : std_logic_vector(7 downto 0); + + signal niba_l : std_logic_vector(5 downto 0); + signal niba_h : std_logic_vector(5 downto 0); + signal niba_lc : std_logic; + signal niba_hc : std_logic; + signal bcda_lc : std_logic; + signal bcda_hc : std_logic; + signal nibs_l : std_logic_vector(5 downto 0); + signal nibs_h : std_logic_vector(5 downto 0); + signal nibs_lc : std_logic; + signal nibs_hc : std_logic; + + signal bcd_a : std_logic_vector(8 downto 0); + signal bcd_s : std_logic_vector(8 downto 0); + signal pack_out : std_logic_vector(15 downto 0); + signal pack_a : std_logic_vector(15 downto 0); + signal result_mulu : std_logic_vector(63 downto 0); + signal result_div : std_logic_vector(63 downto 0); + signal set_mV_Flag : std_logic; + signal V_Flag : bit; + + signal rot_rot : std_logic; + signal rot_lsb : std_logic; + signal rot_msb : std_logic; + signal rot_X : std_logic; + signal rot_C : std_logic; + signal rot_out : std_logic_vector(31 downto 0); + signal asl_VFlag : std_logic; + signal bit_bits : std_logic_vector(1 downto 0); + signal bit_number : std_logic_vector(4 downto 0); + signal bits_out : std_logic_vector(31 downto 0); + signal one_bit_in : std_logic; + signal bchg : std_logic; + signal bset : std_logic; + + signal mulu_sign : std_logic; + signal mulu_signext : std_logic_vector(16 downto 0); + signal muls_msb : std_logic; + signal mulu_reg : std_logic_vector(63 downto 0); + signal FAsign : std_logic; + signal faktorA : std_logic_vector(31 downto 0); + signal faktorB : std_logic_vector(31 downto 0); + + signal div_reg : std_logic_vector(63 downto 0); + signal div_quot : std_logic_vector(63 downto 0); + signal div_ovl : std_logic; + signal div_neg : std_logic; + signal div_bit : std_logic; + signal div_sub : std_logic_vector(32 downto 0); + signal div_over : std_logic_vector(32 downto 0); + signal nozero : std_logic; + signal div_qsign : std_logic; + signal divisor : std_logic_vector(63 downto 0); + signal divs : std_logic; + signal signedOP : std_logic; + signal OP1_sign : std_logic; + signal OP2_sign : std_logic; + signal OP2outext : std_logic_vector(15 downto 0); + + signal in_offset : std_logic_vector(5 downto 0); +-- signal in_width : std_logic_vector(5 downto 0); + signal datareg : std_logic_vector(31 downto 0); + signal insert : std_logic_vector(31 downto 0); +-- signal bf_result : std_logic_vector(31 downto 0); +-- signal bf_offset : std_logic_vector(5 downto 0); +-- signal bf_width : std_logic_vector(5 downto 0); +-- signal bf_firstbit : std_logic_vector(5 downto 0); + signal bf_datareg : std_logic_vector(31 downto 0); +-- signal bf_out : std_logic_vector(31 downto 0); + signal result : std_logic_vector(39 downto 0); + signal result_tmp : std_logic_vector(39 downto 0); + signal sign : std_logic_vector(31 downto 0); + signal bf_set1 : std_logic_vector(39 downto 0); + signal inmux0 : std_logic_vector(39 downto 0); + signal inmux1 : std_logic_vector(39 downto 0); + signal inmux2 : std_logic_vector(39 downto 0); + signal inmux3 : std_logic_vector(31 downto 0); + signal copymux0 : std_logic_vector(39 downto 0); + signal copymux1 : std_logic_vector(39 downto 0); + signal copymux2 : std_logic_vector(39 downto 0); + signal copymux3 : std_logic_vector(31 downto 0); + signal bf_set2 : std_logic_vector(31 downto 0); +-- signal bf_set3 : std_logic_vector(31 downto 0); + signal shift : std_logic_vector(39 downto 0); + signal copy : std_logic_vector(39 downto 0); +-- signal offset : std_logic_vector(5 downto 0); +-- signal width : std_logic_vector(5 downto 0); + signal bf_firstbit : std_logic_vector(5 downto 0); + signal mux : std_logic_vector(3 downto 0); + signal bitnr : std_logic_vector(4 downto 0); + signal mask : std_logic_vector(31 downto 0); + signal bf_bset : std_logic; + signal bf_NFlag : std_logic; + signal bf_bchg : std_logic; + signal bf_ins : std_logic; + signal bf_exts : std_logic; + signal bf_fffo : std_logic; + signal bf_d32 : std_logic; + signal bf_s32 : std_logic; + signal index : std_logic_vector(4 downto 0); +-- signal i : integer range 0 to 31; +-- signal i : integer range 0 to 31; +-- signal i : std_logic_vector(5 downto 0); +BEGIN +----------------------------------------------------------------------------- +-- set OP1in +----------------------------------------------------------------------------- +PROCESS (OP2out, reg_QB, opcode, OP1out, OP1in, exe_datatype, addsub_q, execOPC, exec, + pack_out, bcd_a, bcd_s, result_mulu, result_div, exe_condition, bf_shift, + Flags, FlagsSR, bits_out, exec_tas, rot_out, exe_opcode, result, bf_fffo, bf_firstbit, bf_datareg) + BEGIN + ALUout <= OP1in; + ALUout(7) <= OP1in(7) OR exec_tas; + IF exec(opcBFwb)='1' THEN + ALUout <= result(31 downto 0); + IF bf_fffo='1' THEN + ALUout <= (OTHERS =>'0'); + ALUout(5 downto 0) <= std_logic_vector(unsigned(bf_firstbit) + unsigned(bf_shift)); + END IF; + END IF; + + OP1in <= addsub_q; + IF exec(opcABCD)='1' THEN + OP1in(7 downto 0) <= bcd_a(7 downto 0); + ELSIF exec(opcSBCD)='1' THEN + OP1in(7 downto 0) <= bcd_s(7 downto 0); + ELSIF exec(opcMULU)='1' AND MUL_Mode/=3 THEN + IF exec(write_lowlong)='1' AND (MUL_Mode=1 OR MUL_Mode=2) THEN + OP1in <= result_mulu(31 downto 0); + ELSE + OP1in <= result_mulu(63 downto 32); + END IF; + ELSIF exec(opcDIVU)='1' AND DIV_Mode/=3 THEN + IF exe_opcode(15)='1' OR DIV_Mode=0 THEN +-- IF exe_opcode(15)='1' THEN + OP1in <= result_div(47 downto 32)&result_div(15 downto 0); + ELSE --64bit + IF exec(write_reminder)='1' THEN + OP1in <= result_div(63 downto 32); + ELSE + OP1in <= result_div(31 downto 0); + END IF; + END IF; + ELSIF exec(opcOR)='1' THEN + OP1in <= OP2out OR OP1out; + ELSIF exec(opcAND)='1' THEN + OP1in <= OP2out AND OP1out; + ELSIF exec(opcScc)='1' THEN + OP1in(7 downto 0) <= (others=>exe_condition); + ELSIF exec(opcEOR)='1' THEN + OP1in <= OP2out XOR OP1out; + ELSIF exec(opcMOVE)='1' OR exec(exg)='1' THEN +-- OP1in <= OP2out(31 downto 8)&(OP2out(7)OR exec_tas)&OP2out(6 downto 0); + OP1in <= OP2out; + ELSIF exec(opcROT)='1' THEN + OP1in <= rot_out; + ELSIF exec(opcSWAP)='1' THEN + OP1in <= OP1out(15 downto 0)& OP1out(31 downto 16); + ELSIF exec(opcBITS)='1' THEN + OP1in <= bits_out; + ELSIF exec(opcBF)='1' THEN + OP1in <= bf_datareg; + ELSIF exec(opcMOVESR)='1' THEN + OP1in(7 downto 0) <= Flags; + IF exe_datatype="00" THEN + OP1in(15 downto 8) <= "00000000"; + ELSE + OP1in(15 downto 8) <= FlagsSR; + END IF; + ELSIF exec(opcPACK)='1' THEN + OP1in(15 downto 0) <= pack_out; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- addsub +----------------------------------------------------------------------------- +PROCESS (OP1out, OP2out, execOPC, datatype, Flags, long_start, movem_presub, exe_datatype, exec, addsub_a, addsub_b, opaddsub, + notaddsub_b, add_result, c_in, sndOPC) + BEGIN + addsub_a <= OP1out; + IF exec(get_bfoffset)='1' THEN + IF sndOPC(11)='1' THEN + addsub_a <= OP1out(31)&OP1out(31)&OP1out(31)&OP1out(31 downto 3); + ELSE + addsub_a <= "000000000000000000000000000000"&sndOPC(10 downto 9); + END IF; + END IF; + + IF exec(subidx)='1' THEN + opaddsub <= '1'; + ELSE + opaddsub <= '0'; + END IF; + + c_in(0) <='0'; + addsub_b <= OP2out; + IF execOPC='0' AND exec(OP2out_one)='0' AND exec(get_bfoffset)='0'THEN + IF long_start='0' AND datatype="00" AND exec(use_SP)='0' THEN + addsub_b <= "00000000000000000000000000000001"; + ELSIF long_start='0' AND exe_datatype="10" AND (exec(presub) OR exec(postadd) OR movem_presub)='1' THEN + IF exec(movem_action)='1' THEN + addsub_b <= "00000000000000000000000000000110"; + ELSE + addsub_b <= "00000000000000000000000000000100"; + END IF; + ELSE + addsub_b <= "00000000000000000000000000000010"; + END IF; + ELSE + IF (exec(use_XZFlag)='1' AND Flags(4)='1') OR exec(opcCHK)='1' THEN + c_in(0) <= '1'; + END IF; + opaddsub <= exec(addsub); + END IF; + + IF opaddsub='0' OR long_start='1' THEN --ADD + notaddsub_b <= '0'&addsub_b&c_in(0); + ELSE --SUB + notaddsub_b <= NOT ('0'&addsub_b&c_in(0)); + END IF; + add_result <= std_logic_vector( unsigned('0'&addsub_a¬addsub_b(0)) + unsigned(notaddsub_b)); + c_in(1) <= add_result(9) XOR addsub_a(8) XOR addsub_b(8); + c_in(2) <= add_result(17) XOR addsub_a(16) XOR addsub_b(16); + c_in(3) <= add_result(33); + addsub_q <= add_result(32 downto 1); + addsub_ofl(0) <= (c_in(1) XOR add_result(8) XOR addsub_a(7) XOR addsub_b(7)); --V Byte + addsub_ofl(1) <= (c_in(2) XOR add_result(16) XOR addsub_a(15) XOR addsub_b(15)); --V Word + addsub_ofl(2) <= (c_in(3) XOR add_result(32) XOR addsub_a(31) XOR addsub_b(31)); --V Long + c_out <= c_in(3 downto 1); + END PROCESS; + +------------------------------------------------------------------------------ +--ALU +------------------------------------------------------------------------------ +PROCESS (OP1out, OP2out, pack_a, niba_hc, niba_h, niba_l, niba_lc, nibs_hc, nibs_h, nibs_l, nibs_lc, Flags) + BEGIN + IF exe_opcode(7 downto 6) = "01" THEN + -- PACK + pack_a <= std_logic_vector(unsigned(OP1out(15 downto 0))+unsigned(OP2out(15 downto 0))); + pack_out <= "00000000" & pack_a(11 downto 8) & pack_a(3 downto 0); + ELSE + -- UNPK + pack_a <= "0000" & OP2out(7 downto 4) & "0000" & OP2out(3 downto 0); + pack_out <= std_logic_vector(unsigned(OP1out(15 downto 0))+unsigned(pack_a)); + END IF; + +--BCD_ARITH------------------------------------------------------------------- + --ADC + bcd_a <= niba_hc & std_logic_vector(unsigned(niba_h(4 downto 1)) + ('0',niba_hc,niba_hc,'0')) & + std_logic_vector(unsigned(niba_l(4 downto 1)) + ('0',niba_lc,niba_lc,'0')); + niba_l <= std_logic_vector(unsigned('0'&OP1out(3 downto 0)&'1') + unsigned('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 <= std_logic_vector(unsigned('0'&OP1out(7 downto 4)&'1') + unsigned('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 + bcd_s <= nibs_hc & std_logic_vector(unsigned(nibs_h(4 downto 1)) - ('0',nibs_hc,nibs_hc,'0')) & + std_logic_vector(unsigned(nibs_l(4 downto 1)) - ('0',nibs_lc,nibs_lc,'0')); + nibs_l <= std_logic_vector(unsigned('0'&OP1out(3 downto 0)&'0') - unsigned('0'&OP2out(3 downto 0)&Flags(4))); + nibs_lc <= nibs_l(5); + + nibs_h <= std_logic_vector(unsigned('0'&OP1out(7 downto 4)&'0') - unsigned('0'&OP2out(7 downto 4)&nibs_lc)); + nibs_hc <= nibs_h(5); + END PROCESS; + +----------------------------------------------------------------------------- +-- Bits +----------------------------------------------------------------------------- +PROCESS (clk, exe_opcode, OP1out, OP2out, one_bit_in, bchg, bset, bit_Number, sndOPC) + BEGIN + IF rising_edge(clk) THEN + IF clkena_lw = '1' THEN + bchg <= '0'; + bset <= '0'; + CASE opcode(7 downto 6) IS + WHEN "01" => --bchg + bchg <= '1'; + WHEN "11" => --bset + bset <= '1'; + WHEN OTHERS => NULL; + END CASE; + END IF; + END IF; + + IF exe_opcode(8)='0' THEN + IF exe_opcode(5 downto 4)="00" THEN + bit_number <= sndOPC(4 downto 0); + ELSE + bit_number <= "00"&sndOPC(2 downto 0); + END IF; + ELSE + IF exe_opcode(5 downto 4)="00" THEN + bit_number <= reg_QB(4 downto 0); + ELSE + bit_number <= "00"®_QB(2 downto 0); + END IF; + END IF; + + one_bit_in <= OP1out(to_integer(unsigned(bit_Number))); + bits_out <= OP1out; + bits_out(to_integer(unsigned(bit_Number))) <= (bchg AND NOT one_bit_in) OR bset ; + END PROCESS; + +----------------------------------------------------------------------------- +-- Bit Field +----------------------------------------------------------------------------- +PROCESS (clk, mux, mask, bitnr, bf_ins, bf_bchg, bf_bset, bf_exts, bf_shift, inmux0, inmux1, inmux2, inmux3, bf_set2, OP1out, OP2out, result_tmp, bf_ext_in, + shift, datareg, bf_NFlag, result, reg_QB, sign, bf_d32, bf_s32, copy, bf_loffset, copymux0, copymux1, copymux2, copymux3, bf_width) + BEGIN + IF rising_edge(clk) THEN + IF clkena_lw = '1' THEN + bf_bset <= '0'; + bf_bchg <= '0'; + bf_ins <= '0'; + bf_exts <= '0'; + bf_fffo <= '0'; + bf_d32 <= '0'; + bf_s32 <= '0'; + CASE opcode(10 downto 8) IS + WHEN "010" => bf_bchg <= '1'; --BFCHG + WHEN "011" => bf_exts <= '1'; --BFEXTS +-- WHEN "100" => insert <= (OTHERS =>'0'); --BFCLR + WHEN "101" => bf_fffo <= '1'; --BFFFO + WHEN "110" => bf_bset <= '1'; --BFSET + WHEN "111" => bf_ins <= '1'; --BFINS + bf_s32 <= '1'; + WHEN OTHERS => NULL; + END CASE; + IF opcode(4 downto 3)="00" THEN + bf_d32 <= '1'; + END IF; + bf_ext_out <= result(39 downto 32); + END IF; + END IF; + shift <= bf_ext_in&OP2out; + IF bf_s32='1' THEN + shift(39 downto 32) <= OP2out(7 downto 0); + END IF; + + IF bf_shift(0)='1' THEN + inmux0 <= shift(0)&shift(39 downto 1); + ELSE + inmux0 <= shift; + END IF; + IF bf_shift(1)='1' THEN + inmux1 <= inmux0(1 downto 0)&inmux0(39 downto 2); + ELSE + inmux1 <= inmux0; + END IF; + IF bf_shift(2)='1' THEN + inmux2 <= inmux1(3 downto 0)&inmux1(39 downto 4); + ELSE + inmux2 <= inmux1; + END IF; + IF bf_shift(3)='1' THEN + inmux3 <= inmux2(7 downto 0)&inmux2(31 downto 8); + ELSE + inmux3 <= inmux2(31 downto 0); + END IF; + IF bf_shift(4)='1' THEN + bf_set2(31 downto 0) <= inmux3(15 downto 0)&inmux3(31 downto 16); + ELSE + bf_set2(31 downto 0) <= inmux3; + END IF; + + IF bf_loffset(4)='1' THEN + copymux3 <= sign(15 downto 0)&sign(31 downto 16); + ELSE + copymux3 <= sign; + END IF; + IF bf_loffset(3)='1' THEN + copymux2(31 downto 0) <= copymux3(23 downto 0)©mux3(31 downto 24); + ELSE + copymux2(31 downto 0) <= copymux3; + END IF; + IF bf_d32='1' THEN + copymux2(39 downto 32) <= copymux3(7 downto 0); + ELSE + copymux2(39 downto 32) <= "11111111"; + END IF; + IF bf_loffset(2)='1' THEN + copymux1 <= copymux2(35 downto 0)©mux2(39 downto 36); + ELSE + copymux1 <= copymux2; + END IF; + IF bf_loffset(1)='1' THEN + copymux0 <= copymux1(37 downto 0)©mux1(39 downto 38); + ELSE + copymux0 <= copymux1; + END IF; + IF bf_loffset(0)='1' THEN + copy <= copymux0(38 downto 0)©mux0(39); + ELSE + copy <= copymux0; + END IF; + + result_tmp <= bf_ext_in&OP1out; + IF bf_ins='1' THEN + datareg <= reg_QB; + ELSE + datareg <= bf_set2; + END IF; + IF bf_ins='1' THEN + result(31 downto 0) <= bf_set2; + result(39 downto 32) <= bf_set2(7 downto 0); + ELSIF bf_bchg='1' THEN + result(31 downto 0) <= NOT OP1out; + result(39 downto 32) <= NOT bf_ext_in; + ELSE + result <= (OTHERS => '0'); + END IF; + IF bf_bset='1' THEN + result <= (OTHERS => '1'); + END IF; + + sign <= (OTHERS => '0'); + bf_NFlag <= datareg(to_integer(unsigned(bf_width))); + FOR i in 0 to 31 LOOP + IF i > unsigned(bf_width(4 downto 0)) THEN + datareg(i) <= '0'; + sign(i) <= '1'; + END IF; + END LOOP; + + FOR i in 0 to 39 LOOP + IF copy(i)='1' THEN + result(i) <= result_tmp(i); + END IF; + END LOOP; + + IF bf_exts='1' AND bf_NFlag='1' THEN + bf_datareg <= datareg OR sign; + ELSE + bf_datareg <= datareg; + END IF; +-- bf_datareg <= copy(31 downto 0); +-- result(31 downto 0)<=datareg; +--BFFFO + mask <= datareg; + bf_firstbit <= '0'&bitnr; + bitnr <= "11111"; + IF mask(31 downto 28)="0000" THEN + IF mask(27 downto 24)="0000" THEN + IF mask(23 downto 20)="0000" THEN + IF mask(19 downto 16)="0000" THEN + bitnr(4) <= '0'; + IF mask(15 downto 12)="0000" THEN + IF mask(11 downto 8)="0000" THEN + bitnr(3) <= '0'; + IF mask(7 downto 4)="0000" THEN + bitnr(2) <= '0'; + mux <= mask(3 downto 0); + ELSE + mux <= mask(7 downto 4); + END IF; + ELSE + mux <= mask(11 downto 8); + bitnr(2) <= '0'; + END IF; + ELSE + mux <= mask(15 downto 12); + END IF; + ELSE + mux <= mask(19 downto 16); + bitnr(3) <= '0'; + bitnr(2) <= '0'; + END IF; + ELSE + mux <= mask(23 downto 20); + bitnr(3) <= '0'; + END IF; + ELSE + mux <= mask(27 downto 24); + bitnr(2) <= '0'; + END IF; + ELSE + mux <= mask(31 downto 28); + END IF; + + IF mux(3 downto 2)="00" THEN + bitnr(1) <= '0'; + IF mux(1)='0' THEN + bitnr(0) <= '0'; + END IF; + ELSE + IF mux(3)='0' THEN + bitnr(0) <= '0'; + END IF; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- Rotation +----------------------------------------------------------------------------- +PROCESS (exe_opcode, OP1out, Flags, rot_bits, rot_msb, rot_lsb, rot_rot, exec) + BEGIN + CASE exe_opcode(7 downto 6) IS + WHEN "00" => --Byte + rot_rot <= OP1out(7); + WHEN "01"|"11" => --Word + rot_rot <= OP1out(15); + WHEN "10" => --Long + rot_rot <= OP1out(31); + WHEN OTHERS => NULL; + END CASE; + + CASE rot_bits IS + WHEN "00" => --ASL, ASR + rot_lsb <= '0'; + rot_msb <= rot_rot; + WHEN "01" => --LSL, LSR + rot_lsb <= '0'; + rot_msb <= '0'; + WHEN "10" => --ROXL, ROXR + rot_lsb <= Flags(4); + rot_msb <= Flags(4); + WHEN "11" => --ROL, ROR + rot_lsb <= rot_rot; + rot_msb <= OP1out(0); + WHEN OTHERS => NULL; + END CASE; + + IF exec(rot_nop)='1' THEN + rot_out <= OP1out; + rot_X <= Flags(4); + IF rot_bits="10" THEN --ROXL, ROXR + rot_C <= Flags(4); + ELSE + rot_C <= '0'; + END IF; + ELSE + IF exe_opcode(8)='1' THEN --left + rot_out <= OP1out(30 downto 0)&rot_lsb; + rot_X <= rot_rot; + rot_C <= rot_rot; + ELSE --right + rot_X <= OP1out(0); + rot_C <= OP1out(0); + rot_out <= rot_msb&OP1out(31 downto 1); + CASE exe_opcode(7 downto 6) IS + WHEN "00" => --Byte + rot_out(7) <= rot_msb; + WHEN "01"|"11" => --Word + rot_out(15) <= rot_msb; + WHEN OTHERS => NULL; + END CASE; + END IF; + END IF; + END PROCESS; + +------------------------------------------------------------------------------ +--CCR op +------------------------------------------------------------------------------ +PROCESS (clk, Reset, exe_opcode, exe_datatype, Flags, last_data_read, OP2out, flag_z, OP1IN, c_out, addsub_ofl, + bcd_s, bcd_a, exec) + BEGIN + IF exec(andiSR)='1' THEN + CCRin <= Flags AND last_data_read(7 downto 0); + ELSIF exec(eoriSR)='1' THEN + CCRin <= Flags XOR last_data_read(7 downto 0); + ELSIF exec(oriSR)='1' THEN + CCRin <= Flags OR last_data_read(7 downto 0); + ELSE + CCRin <= OP2out(7 downto 0); + END IF; + +------------------------------------------------------------------------------ +--Flags +------------------------------------------------------------------------------ + flag_z <= "000"; + IF exec(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 exe_datatype="00" THEN --Byte + set_flags <= OP1IN(7)&flag_z(0)&addsub_ofl(0)&c_out(0); + IF exec(opcABCD)='1' THEN + set_flags(0) <= bcd_a(8); + ELSIF exec(opcSBCD)='1' THEN + set_flags(0) <= bcd_s(8); + END IF; + ELSIF exe_datatype="10" OR exec(opcCPMAW)='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; + + IF rising_edge(clk) THEN + IF clkena_lw = '1' THEN + IF exec(directSR)='1' OR set_stop='1' THEN + Flags(7 downto 0) <= data_read(7 downto 0); + END IF; + IF exec(directCCR)='1' THEN + Flags(7 downto 0) <= data_read(7 downto 0); + END IF; + + IF exec(opcROT)='1' THEN + asl_VFlag <= ((set_flags(3) XOR rot_rot) OR asl_VFlag); + ELSE + asl_VFlag <= '0'; + END IF; + IF exec(to_CCR)='1' THEN + Flags(7 downto 0) <= CCRin(7 downto 0); --CCR + ELSIF Z_error='1' THEN + IF exe_opcode(8)='0' THEN + Flags(3 downto 0) <= reg_QA(31)&"000"; + ELSE + Flags(3 downto 0) <= "0100"; + END IF; + ELSIF exec(no_Flags)='0' THEN + IF exec(opcADD)='1' THEN + Flags(4) <= set_flags(0); + ELSIF exec(opcROT)='1' AND rot_bits/="11" AND exec(rot_nop)='0' THEN + Flags(4) <= rot_X; + END IF; + + IF (exec(opcADD) OR exec(opcCMP))='1' THEN + Flags(3 downto 0) <= set_flags; + ELSIF exec(opcDIVU)='1' AND DIV_Mode/=3 THEN + IF V_Flag='1' THEN + Flags(3 downto 0) <= "1010"; + ELSE + Flags(3 downto 0) <= OP1IN(15)&flag_z(1)&"00"; + END IF; + ELSIF exec(write_reminder)='1' AND MUL_Mode/=3 THEN -- z-flag MULU.l + Flags(3) <= set_flags(3); + Flags(2) <= set_flags(2) AND Flags(2); + Flags(1) <= '0'; + Flags(0) <= '0'; + ELSIF exec(write_lowlong)='1' AND (MUL_Mode=1 OR MUL_Mode=2) THEN -- flag MULU.l + Flags(3) <= set_flags(3); + Flags(2) <= set_flags(2); + Flags(1) <= set_mV_Flag; --V + Flags(0) <= '0'; + ELSIF exec(opcOR)='1' OR exec(opcAND)='1' OR exec(opcEOR)='1' OR exec(opcMOVE)='1' OR exec(opcMOVEQ)='1' OR exec(opcSWAP)='1' OR exec(opcBF)='1' OR (exec(opcMULU)='1' AND MUL_Mode/=3) THEN + Flags(1 downto 0) <= "00"; + Flags(3 downto 2) <= set_flags(3 downto 2); + IF exec(opcBF)='1' THEN + Flags(3) <= bf_NFlag; + END IF; + ELSIF exec(opcROT)='1' THEN + Flags(3 downto 2) <= set_flags(3 downto 2); + Flags(0) <= rot_C; + IF rot_bits="00" AND ((set_flags(3) XOR rot_rot) OR asl_VFlag)='1' THEN --ASL/ASR + Flags(1) <= '1'; + ELSE + Flags(1) <= '0'; + END IF; + ELSIF exec(opcBITS)='1' THEN + Flags(2) <= NOT one_bit_in; + ELSIF exec(opcCHK)='1' THEN + IF exe_datatype="01" THEN --Word + Flags(3) <= OP1out(15); + ELSE + Flags(3) <= OP1out(31); + END IF; + IF OP1out(15 downto 0)=X"0000" AND (exe_datatype="01" OR OP1out(31 downto 16)=X"0000") THEN + Flags(2) <='1'; + ELSE + Flags(2) <='0'; + END IF; + Flags(1 downto 0) <= "00"; + END IF; + END IF; + END IF; + Flags(7 downto 5) <= "000"; + END IF; + END PROCESS; + +------------------------------------------------------------------------------- +---- MULU/MULS +------------------------------------------------------------------------------- +PROCESS (exe_opcode, OP2out, muls_msb, mulu_reg, FAsign, mulu_sign, reg_QA, faktorB, result_mulu, signedOP) + BEGIN + IF (signedOP='1' AND faktorB(31)='1') OR FAsign='1' THEN + muls_msb <= mulu_reg(63); + ELSE + muls_msb <= '0'; + END IF; + + IF signedOP='1' AND faktorB(31)='1' THEN + mulu_sign <= '1'; + ELSE + mulu_sign <= '0'; + END IF; + + IF MUL_Mode=0 THEN -- 16 Bit + result_mulu(63 downto 32) <= muls_msb&mulu_reg(63 downto 33); + result_mulu(15 downto 0) <= 'X'&mulu_reg(15 downto 1); + IF mulu_reg(0)='1' THEN + IF FAsign='1' THEN + result_mulu(63 downto 47) <= std_logic_vector(muls_msb & unsigned(mulu_reg(63 downto 48)) - unsigned(mulu_sign&faktorB(31 downto 16)) ); + ELSE + result_mulu(63 downto 47) <= std_logic_vector(muls_msb & unsigned(mulu_reg(63 downto 48)) + unsigned(mulu_sign&faktorB(31 downto 16)) ); + END IF; + END IF; + ELSE -- 32 Bit + result_mulu <= muls_msb&mulu_reg(63 downto 1); + IF mulu_reg(0)='1' THEN + IF FAsign='1' THEN + result_mulu(63 downto 31) <= std_logic_vector(muls_msb & unsigned(mulu_reg(63 downto 32))-unsigned(mulu_sign&faktorB)); + ELSE + result_mulu(63 downto 31) <= std_logic_vector(muls_msb & unsigned(mulu_reg(63 downto 32))+unsigned(mulu_sign&faktorB)); + END IF; + END IF; + END IF; + IF exe_opcode(15)='1' OR MUL_Mode=0 THEN + faktorB(31 downto 16) <= OP2out(15 downto 0); + faktorB(15 downto 0) <= (OTHERS=>'0'); + ELSE + faktorB <= OP2out; + END IF; + IF (result_mulu(63 downto 32)=X"00000000" AND (signedOP='0' OR result_mulu(31)='0')) OR + (result_mulu(63 downto 32)=X"FFFFFFFF" AND signedOP='1' AND result_mulu(31)='1') THEN + set_mV_Flag <= '0'; + ELSE + set_mV_Flag <= '1'; + END IF; + END PROCESS; + +PROCESS (clk) + BEGIN + IF rising_edge(clk) THEN + IF clkena_lw='1' THEN + IF micro_state=mul1 THEN + mulu_reg(63 downto 32) <= (OTHERS=>'0'); + IF divs='1' AND ((exe_opcode(15)='1' AND reg_QA(15)='1') OR (exe_opcode(15)='0' AND reg_QA(31)='1')) THEN --MULS Neg faktor + FAsign <= '1'; + mulu_reg(31 downto 0) <= std_logic_vector(0-unsigned(reg_QA)); + ELSE + FAsign <= '0'; + mulu_reg(31 downto 0) <= reg_QA; + END IF; + ELSIF exec(opcMULU)='0' THEN + mulu_reg <= result_mulu; + END IF; + END IF; + END IF; + END PROCESS; + +------------------------------------------------------------------------------- +---- DIVU/DIVS +------------------------------------------------------------------------------- + +PROCESS (execOPC, OP1out, OP2out, div_reg, div_neg, div_bit, div_sub, div_quot, OP1_sign, div_over, result_div, reg_QA, opcode, sndOPC, divs, exe_opcode, reg_QB, + signedOP, nozero, div_qsign, OP2outext) + BEGIN + divs <= (opcode(15) AND opcode(8)) OR (NOT opcode(15) AND sndOPC(11)); + divisor(15 downto 0) <= (OTHERS=> '0'); + divisor(63 downto 32) <= (OTHERS=> divs AND reg_QA(31)); + IF exe_opcode(15)='1' OR DIV_Mode=0 THEN + divisor(47 downto 16) <= reg_QA; + ELSE + divisor(31 downto 0) <= reg_QA; + IF exe_opcode(14)='1' AND sndOPC(10)='1' THEN + divisor(63 downto 32) <= reg_QB; + END IF; + END IF; + IF signedOP='1' OR opcode(15)='0' THEN + OP2outext <= OP2out(31 downto 16); + ELSE + OP2outext <= (OTHERS=> '0'); + END IF; + IF signedOP='1' AND OP2out(31) ='1' THEN + div_sub <= std_logic_vector(unsigned(div_reg(63 downto 31)) + unsigned('1'&OP2out(31 downto 0))); + ELSE + div_sub <= std_logic_vector(unsigned(div_reg(63 downto 31))-unsigned('0'&OP2outext(15 downto 0)&OP2out(15 downto 0))); + END IF; + IF DIV_Mode=0 THEN + div_bit <= div_sub(16); + ELSE + div_bit <= div_sub(32); + END IF; + IF div_bit='1' THEN + div_quot(63 downto 32) <= div_reg(62 downto 31); + ELSE + div_quot(63 downto 32) <= div_sub(31 downto 0); + END IF; + div_quot(31 downto 0) <= div_reg(30 downto 0)&NOT div_bit; + + + IF ((nozero='1' AND signedOP='1' AND (OP2out(31) XOR OP1_sign XOR div_neg XOR div_qsign)='1' ) --Overflow DIVS + OR (signedOP='0' AND div_over(32)='0')) AND DIV_Mode/=3 THEN --Overflow DIVU + set_V_Flag <= '1'; + ELSE + set_V_Flag <= '0'; + END IF; + END PROCESS; + +PROCESS (clk) + BEGIN + IF rising_edge(clk) THEN + IF clkena_lw='1' THEN + V_Flag <= set_V_Flag; + signedOP <= divs; + IF micro_state=div1 THEN + nozero <= '0'; + IF divs='1' AND divisor(63)='1' THEN -- Neg divisor + OP1_sign <= '1'; + div_reg <= std_logic_vector(0-unsigned(divisor)); + ELSE + OP1_sign <= '0'; + div_reg <= divisor; + END IF; + ELSE + div_reg <= div_quot; + nozero <= NOT div_bit OR nozero; + END IF; + IF micro_state=div2 THEN + div_qsign <= NOT div_bit; + div_neg <= signedOP AND (OP2out(31) XOR OP1_sign); + IF DIV_Mode=0 THEN + div_over(32 downto 16) <= std_logic_vector(unsigned('0'&div_reg(47 downto 32))-unsigned('0'&OP2out(15 downto 0))); + ELSE + div_over <= std_logic_vector(unsigned('0'&div_reg(63 downto 32))-unsigned('0'&OP2out)); + END IF; + END IF; + IF exec(write_reminder)='0' THEN +-- IF exec_DIVU='0' THEN + IF div_neg='1' THEN + result_div(31 downto 0) <= std_logic_vector(0-unsigned(div_quot(31 downto 0))); + ELSE + result_div(31 downto 0) <= div_quot(31 downto 0); + END IF; + + IF OP1_sign='1' THEN + result_div(63 downto 32) <= std_logic_vector(0-unsigned(div_quot(63 downto 32))); + ELSE + result_div(63 downto 32) <= div_quot(63 downto 32); + END IF; + END IF; + END IF; + END IF; + END PROCESS; +END; diff --git a/tests/tg68k/TG68K_Pack.vhd b/tests/tg68k/TG68K_Pack.vhd new file mode 100644 index 0000000..d18b48d --- /dev/null +++ b/tests/tg68k/TG68K_Pack.vhd @@ -0,0 +1,166 @@ +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2009-2013 Tobias Gubener -- +-- Subdesign fAMpIGA by TobiFlex -- +-- -- +-- This source file is free software: you can redistribute it and/or modify -- +-- it under the terms of the GNU General Public License as published -- +-- by the Free Software Foundation, either version 3 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- This source file is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU General Public License -- +-- along with this program. If not, see . -- +-- -- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +library IEEE; +use IEEE.std_logic_1164.all; + +package TG68K_Pack is + + type micro_states is (idle, nop, ld_nn, st_nn, ld_dAn1, ld_AnXn1, ld_AnXn2, st_dAn1, ld_AnXnbd1, ld_AnXnbd2, ld_AnXnbd3, + ld_229_1, ld_229_2, ld_229_3, ld_229_4, st_229_1, st_229_2, st_229_3, st_229_4, + st_AnXn1, st_AnXn2, bra1, bsr1, bsr2, nopnop, dbcc1, movem1, movem2, movem3, + andi, op_AxAy, cmpm, link1, link2, unlink1, unlink2, int1, int2, int3, int4, rte1, rte2, rte3, trap0, trap1, trap2, trap3, + trap4, trap5, trap6, movec1, movep1, movep2, movep3, movep4, movep5, rota1, bf1, + mul1, mul2, mul_end1, mul_end2, div1, div2, div3, div4, div_end1, div_end2, pack1, pack2, pack3); + + constant opcMOVE : integer := 0; -- + constant opcMOVEQ : integer := 1; -- + constant opcMOVESR : integer := 2; -- + constant opcADD : integer := 3; -- + constant opcADDQ : integer := 4; -- + constant opcOR : integer := 5; -- + constant opcAND : integer := 6; -- + constant opcEOR : integer := 7; -- + constant opcCMP : integer := 8; -- + constant opcROT : integer := 9; -- + constant opcCPMAW : integer := 10; + constant opcEXT : integer := 11; -- + constant opcABCD : integer := 12; -- + constant opcSBCD : integer := 13; -- + constant opcBITS : integer := 14; -- + constant opcSWAP : integer := 15; -- + constant opcScc : integer := 16; -- + constant andiSR : integer := 17; -- + constant eoriSR : integer := 18; -- + constant oriSR : integer := 19; -- + constant opcMULU : integer := 20; -- + constant opcDIVU : integer := 21; -- + constant dispouter : integer := 22; -- + constant rot_nop : integer := 23; -- + constant ld_rot_cnt : integer := 24; -- + constant writePC_add : integer := 25; -- + constant ea_data_OP1 : integer := 26; -- + constant ea_data_OP2 : integer := 27; -- + constant use_XZFlag : integer := 28; -- + constant get_bfoffset : integer := 29; -- + constant save_memaddr : integer := 30; -- + constant opcCHK : integer := 31; -- + constant movec_rd : integer := 32; -- + constant movec_wr : integer := 33; -- + constant Regwrena : integer := 34; -- + constant update_FC : integer := 35; -- + constant linksp : integer := 36; -- + constant movepl : integer := 37; -- + constant update_ld : integer := 38; -- + constant OP1addr : integer := 39; -- + constant write_reg : integer := 40; -- + constant changeMode : integer := 41; -- + constant ea_build : integer := 42; -- + constant trap_chk : integer := 43; -- + constant store_ea_data : integer := 44; -- + constant addrlong : integer := 45; -- + constant postadd : integer := 46; -- + constant presub : integer := 47; -- + constant subidx : integer := 48; -- + constant no_Flags : integer := 49; -- + constant use_SP : integer := 50; -- + constant to_CCR : integer := 51; -- + constant to_SR : integer := 52; -- + constant OP2out_one : integer := 53; -- + constant OP1out_zero : integer := 54; -- + constant mem_addsub : integer := 55; -- + constant addsub : integer := 56; -- + constant directPC : integer := 57; -- + constant direct_delta : integer := 58; -- + constant directSR : integer := 59; -- + constant directCCR : integer := 60; -- + constant exg : integer := 61; -- + constant get_ea_now : integer := 62; -- + constant ea_to_pc : integer := 63; -- + constant hold_dwr : integer := 64; -- + constant to_USP : integer := 65; -- + constant from_USP : integer := 66; -- + constant write_lowlong : integer := 67; -- + constant write_reminder : integer := 68; -- + constant movem_action : integer := 69; -- + constant briefext : integer := 70; -- + constant get_2ndOPC : integer := 71; -- + constant mem_byte : integer := 72; -- + constant longaktion : integer := 73; -- + constant opcRESET : integer := 74; -- + constant opcBF : integer := 75; -- + constant opcBFwb : integer := 76; -- + constant opcPACK : integer := 77; -- +-- constant s2nd_hbits : integer := 77; -- +-- constant : integer := 75; -- +-- constant : integer := 76; -- +-- constant : integer := 7; -- +-- constant : integer := 7; -- +-- constant : integer := 7; -- + + constant lastOpcBit : integer := 77; + + component TG68K_ALU + generic( + MUL_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL, + DIV_Mode : integer := 0 --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV, + ); + port( + clk : in std_logic; + Reset : in std_logic; + clkena_lw : in std_logic:='1'; + execOPC : in bit; + exe_condition : in std_logic; + exec_tas : in std_logic; + long_start : in bit; + movem_presub : in bit; + set_stop : in bit; + Z_error : in bit; + rot_bits : in std_logic_vector(1 downto 0); + exec : in bit_vector(lastOpcBit downto 0); + OP1out : in std_logic_vector(31 downto 0); + OP2out : in std_logic_vector(31 downto 0); + reg_QA : in std_logic_vector(31 downto 0); + reg_QB : in std_logic_vector(31 downto 0); + opcode : in std_logic_vector(15 downto 0); + datatype : in std_logic_vector(1 downto 0); + exe_opcode : in std_logic_vector(15 downto 0); + exe_datatype : in std_logic_vector(1 downto 0); + sndOPC : in std_logic_vector(15 downto 0); + last_data_read : in std_logic_vector(15 downto 0); + data_read : in std_logic_vector(15 downto 0); + FlagsSR : in std_logic_vector(7 downto 0); + micro_state : in micro_states; + bf_ext_in : in std_logic_vector(7 downto 0); + bf_ext_out : out std_logic_vector(7 downto 0); + bf_shift : in std_logic_vector(5 downto 0); + bf_width : in std_logic_vector(5 downto 0); + bf_loffset : in std_logic_vector(4 downto 0); + + set_V_Flag : buffer bit; + Flags : buffer std_logic_vector(7 downto 0); + c_out : buffer std_logic_vector(2 downto 0); + addsub_q : buffer std_logic_vector(31 downto 0); + ALUout : out std_logic_vector(31 downto 0) + ); + end component; + +end; diff --git a/tests/tg68k/TG68KdotC_Kernel.vhd b/tests/tg68k/TG68KdotC_Kernel.vhd new file mode 100644 index 0000000..499f796 --- /dev/null +++ b/tests/tg68k/TG68KdotC_Kernel.vhd @@ -0,0 +1,3312 @@ +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2009-2013 Tobias Gubener -- +-- Subdesign fAMpIGA by TobiFlex -- +-- -- +-- This source file is free software: you can redistribute it and/or modify -- +-- it under the terms of the GNU General Public License as published -- +-- by the Free Software Foundation, either version 3 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- This source file is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU General Public License -- +-- along with this program. If not, see . -- +-- -- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- add berr handling 10.03.2013 + +-- bugfix session 07/08.Feb.2013 +-- movem ,-(an) +-- movem (an)+, - thanks Gerhard Suttner +-- btst dn,#data - thanks Peter Graf +-- movep - thanks Till Harbaum +-- IPL vector - thanks Till Harbaum +-- + +-- optimize Register file + +-- to do 68010: +-- (MOVEC) +-- BKPT +-- RTD +-- MOVES +-- +-- to do 68020: +-- (CALLM) +-- (RETM) + +-- CAS, CAS2 +-- CHK2 +-- CMP2 +-- cpXXX Coprozessor stuff +-- PACK +-- TRAPcc +-- UNPK + +-- done 020: +-- Bitfields +-- address modes +-- long bra +-- DIVS.L, DIVU.L +-- LINK long +-- MULS.L, MULU.L +-- extb.l + +library ieee; +use ieee.std_logic_1164.all; +-- use ieee.std_logic_unsigned.all; +use work.TG68K_Pack.all; +use ieee.numeric_std.all; + +entity TG68KdotC_Kernel is + generic( + SR_Read : integer:= 0; --0=>user, 1=>privileged, 2=>switchable with CPU(0) + VBR_Stackframe : integer:= 0; --0=>no, 1=>yes/extended, 2=>switchable with CPU(0) + extAddr_Mode : integer:= 0; --0=>no, 1=>yes, 2=>switchable with CPU(1) + MUL_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL, + DIV_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV, + BitField : integer := 0 --0=>no, 1=>yes, 2=>switchable with CPU(1) + ); + port(clk : in std_logic; + nReset : in std_logic; --low active + clkena_in : in std_logic:='1'; + data_in : in std_logic_vector(15 downto 0); + IPL : in std_logic_vector(2 downto 0):="111"; + IPL_autovector : in std_logic:='0'; + berr : in std_logic:='0'; -- only 68000 Stackpointer dummy + CPU : in std_logic_vector(1 downto 0):="00"; -- 00->68000 01->68010 11->68020(only some parts - yet) + addr : buffer std_logic_vector(31 downto 0); + data_write : out std_logic_vector(15 downto 0); + nWr : out std_logic; + nUDS, nLDS : out std_logic; + busstate : out std_logic_vector(1 downto 0); -- 00-> fetch code 10->read data 11->write data 01->no memaccess + nResetOut : out std_logic; + FC : out std_logic_vector(2 downto 0); +-- + clr_berr : out std_logic; +-- for debug + db_OP1out : out std_logic_vector(31 downto 0); + db_OP2out : out std_logic_vector(31 downto 0); + skipFetch : out std_logic; + regin : buffer std_logic_vector(31 downto 0) + ); +end TG68KdotC_Kernel; + +architecture logic of TG68KdotC_Kernel is + + + signal syncReset : std_logic_vector(3 downto 0); + signal Reset : std_logic; + signal clkena_lw : std_logic; + signal TG68_PC : std_logic_vector(31 downto 0); + signal tmp_TG68_PC : std_logic_vector(31 downto 0); + signal TG68_PC_add : std_logic_vector(31 downto 0); + signal PC_dataa : std_logic_vector(31 downto 0); + signal PC_datab : std_logic_vector(31 downto 0); + signal memaddr : std_logic_vector(31 downto 0); + signal state : std_logic_vector(1 downto 0); + signal datatype : std_logic_vector(1 downto 0); + signal set_datatype : std_logic_vector(1 downto 0); + signal exe_datatype : std_logic_vector(1 downto 0); + signal setstate : std_logic_vector(1 downto 0); + + signal opcode : std_logic_vector(15 downto 0); + signal exe_opcode : std_logic_vector(15 downto 0); + signal sndOPC : std_logic_vector(15 downto 0); + + signal last_opc_read : std_logic_vector(15 downto 0); + signal registerin : std_logic_vector(31 downto 0); + signal reg_QA : std_logic_vector(31 downto 0); + signal reg_QB : std_logic_vector(31 downto 0); + signal Wwrena,Lwrena : bit; + signal Bwrena : bit; + signal Regwrena_now : bit; + signal rf_dest_addr : std_logic_vector(3 downto 0); + signal rf_source_addr : std_logic_vector(3 downto 0); + signal rf_source_addrd : std_logic_vector(3 downto 0); + + type regfile_t is array(0 to 15) of std_logic_vector(31 downto 0); + signal regfile : regfile_t; + signal RDindex_A : integer range 0 to 15; + signal RDindex_B : integer range 0 to 15; + signal WR_AReg : std_logic; + + + signal memaddr_reg : std_logic_vector(31 downto 0); + signal memaddr_delta : std_logic_vector(31 downto 0); + signal use_base : bit; + + signal ea_data : std_logic_vector(31 downto 0); + signal OP1out, OP2out : std_logic_vector(31 downto 0); + signal OP1outbrief : std_logic_vector(15 downto 0); + signal OP1in : std_logic_vector(31 downto 0); + signal ALUout : std_logic_vector(31 downto 0); + signal data_write_tmp : std_logic_vector(31 downto 0); + signal data_write_muxin : std_logic_vector(31 downto 0); + signal data_write_mux : std_logic_vector(47 downto 0); + signal nextpass : bit; + signal setnextpass : bit; + signal setdispbyte : bit; + signal setdisp : bit; + signal regdirectsource :bit; -- checken !!! + signal addsub_q : std_logic_vector(31 downto 0); + signal briefdata : std_logic_vector(31 downto 0); +-- signal c_in : std_logic_vector(3 downto 0); + signal c_out : std_logic_vector(2 downto 0); + + signal mem_address : std_logic_vector(31 downto 0); + signal memaddr_a : std_logic_vector(31 downto 0); + + signal TG68_PC_brw : bit; + signal TG68_PC_word : bit; + signal getbrief : bit; + signal brief : std_logic_vector(15 downto 0); + signal dest_areg : std_logic; + signal source_areg : std_logic; + signal data_is_source : bit; + signal store_in_tmp : bit; + signal write_back : bit; + signal exec_write_back: bit; + signal setstackaddr : bit; + signal writePC : bit; + signal writePCbig : bit; + signal set_writePCbig : bit; + signal setopcode : bit; + signal decodeOPC : bit; + signal execOPC : bit; + signal setexecOPC : bit; + signal endOPC : bit; + signal setendOPC : bit; + signal Flags : std_logic_vector(7 downto 0); -- ...XNZVC + signal FlagsSR : std_logic_vector(7 downto 0); -- T.S..III + signal SRin : std_logic_vector(7 downto 0); + signal exec_DIRECT : bit; + signal exec_tas : std_logic; + signal set_exec_tas : std_logic; + + signal exe_condition : std_logic; + signal ea_only : bit; + signal source_lowbits : bit; + signal source_2ndHbits : bit; + signal source_2ndLbits : bit; + signal dest_2ndHbits : bit; + signal dest_hbits : bit; + signal rot_bits : std_logic_vector(1 downto 0); + signal set_rot_bits : std_logic_vector(1 downto 0); + signal rot_cnt : std_logic_vector(5 downto 0); + signal set_rot_cnt : std_logic_vector(5 downto 0); + signal movem_actiond : bit; + signal movem_regaddr : std_logic_vector(3 downto 0); + signal movem_mux : std_logic_vector(3 downto 0); + signal movem_presub : bit; + signal movem_run : bit; + signal ea_calc_b : std_logic_vector(31 downto 0); + signal set_direct_data: bit; + signal use_direct_data: bit; + signal direct_data : bit; + + signal set_V_Flag : bit; + signal set_vectoraddr : bit; + signal writeSR : bit; + signal trap_berr : bit; + signal trap_illegal : bit; + signal trap_addr_error : bit; + signal trap_priv : bit; + signal trap_trace : bit; + signal trap_1010 : bit; + signal trap_1111 : bit; + signal trap_trap : bit; + signal trap_trapv : bit; + signal trap_interrupt : bit; + signal trapmake : bit; + signal trapd : bit; + signal trap_SR : std_logic_vector(7 downto 0); + signal make_trace : std_logic; + signal make_berr : std_logic; + + signal set_stop : bit; + signal stop : bit; + signal trap_vector : std_logic_vector(31 downto 0); + signal trap_vector_vbr : std_logic_vector(31 downto 0); + signal USP : std_logic_vector(31 downto 0); + signal illegal_write_mode : bit; + signal illegal_read_mode : bit; + signal illegal_byteaddr : bit; + + signal IPL_nr : std_logic_vector(2 downto 0); + signal rIPL_nr : std_logic_vector(2 downto 0); + signal IPL_vec : std_logic_vector(7 downto 0); + signal interrupt : bit; + signal setinterrupt : bit; + signal SVmode : std_logic; + signal preSVmode : std_logic; + signal Suppress_Base : bit; + signal set_Suppress_Base : bit; + signal set_Z_error : bit; + signal Z_error : bit; + signal ea_build_now : bit; + signal build_logical : bit; + signal build_bcd : bit; + + signal data_read : std_logic_vector(31 downto 0); + signal bf_ext_in : std_logic_vector(7 downto 0); + signal bf_ext_out : std_logic_vector(7 downto 0); + signal byte : bit; + signal long_start : bit; + signal long_start_alu : bit; + signal long_done : bit; + signal memmask : std_logic_vector(5 downto 0); + signal set_memmask : std_logic_vector(5 downto 0); + signal memread : std_logic_vector(3 downto 0); + signal wbmemmask : std_logic_vector(5 downto 0); + signal memmaskmux : std_logic_vector(5 downto 0); + signal oddout : std_logic; + signal set_oddout : std_logic; + signal PCbase : std_logic; + signal set_PCbase : std_logic; + + signal last_data_read : std_logic_vector(31 downto 0); + signal last_data_in : std_logic_vector(31 downto 0); + + signal bf_offset : std_logic_vector(5 downto 0); + signal bf_width : std_logic_vector(5 downto 0); + signal bf_bhits : std_logic_vector(5 downto 0); + signal bf_shift : std_logic_vector(5 downto 0); + signal alu_width : std_logic_vector(5 downto 0); + signal alu_bf_shift : std_logic_vector(5 downto 0); + signal bf_loffset : std_logic_vector(5 downto 0); + signal alu_bf_loffset : std_logic_vector(5 downto 0); + + signal movec_data : std_logic_vector(31 downto 0); + signal VBR : std_logic_vector(31 downto 0); + signal CACR : std_logic_vector(3 downto 0); + signal DFC : std_logic_vector(2 downto 0); + signal SFC : std_logic_vector(2 downto 0); + + + signal set : bit_vector(lastOpcBit downto 0); + signal set_exec : bit_vector(lastOpcBit downto 0); + signal exec : bit_vector(lastOpcBit downto 0); + + signal micro_state : micro_states; + signal next_micro_state : micro_states; + + + +BEGIN +db_OP1out <= OP1out; +db_OP2out <= OP2out; + +ALU: TG68K_ALU + generic map( + MUL_Mode => MUL_Mode, --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL, + DIV_Mode => DIV_Mode --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV, + ) + port map( + clk => clk, --: in std_logic; + Reset => Reset, --: in std_logic; + clkena_lw => clkena_lw, --: in std_logic:='1'; + execOPC => execOPC, --: in bit; + exe_condition => exe_condition, --: in std_logic; + exec_tas => exec_tas, --: in std_logic; + long_start => long_start_alu, --: in bit; + movem_presub => movem_presub, --: in bit; + set_stop => set_stop, --: in bit; + Z_error => Z_error, --: in bit; + + rot_bits => rot_bits, --: in std_logic_vector(1 downto 0); + exec => exec, --: in bit_vector(lastOpcBit downto 0); + OP1out => OP1out, --: in std_logic_vector(31 downto 0); + OP2out => OP2out, --: in std_logic_vector(31 downto 0); + reg_QA => reg_QA, --: in std_logic_vector(31 downto 0); + reg_QB => reg_QB, --: in std_logic_vector(31 downto 0); + opcode => opcode, --: in std_logic_vector(15 downto 0); + datatype => datatype, --: in std_logic_vector(1 downto 0); + exe_opcode => exe_opcode, --: in std_logic_vector(15 downto 0); + exe_datatype => exe_datatype, --: in std_logic_vector(1 downto 0); + sndOPC => sndOPC, --: in std_logic_vector(15 downto 0); + last_data_read => last_data_read(15 downto 0), --: in std_logic_vector(31 downto 0); + data_read => data_read(15 downto 0), --: in std_logic_vector(31 downto 0); + FlagsSR => FlagsSR, --: in std_logic_vector(7 downto 0); + micro_state => micro_state, --: in micro_states; + bf_ext_in => bf_ext_in, + bf_ext_out => bf_ext_out, + bf_shift => alu_bf_shift, + bf_width => alu_width, + bf_loffset => alu_bf_loffset(4 downto 0), + + set_V_Flag => set_V_Flag, --: buffer bit; + Flags => Flags, --: buffer std_logic_vector(8 downto 0); + c_out => c_out, --: buffer std_logic_vector(2 downto 0); + addsub_q => addsub_q, --: buffer std_logic_vector(31 downto 0); + ALUout => ALUout --: buffer std_logic_vector(31 downto 0) + ); + + long_start_alu <= to_bit(NOT memmaskmux(3)); +----------------------------------------------------------------------------- +-- Bus control +----------------------------------------------------------------------------- + nWr <= '0' WHEN state="11" ELSE '1'; + busstate <= state; + nResetOut <= '0' WHEN exec(opcRESET)='1' ELSE '1'; + memmaskmux <= memmask WHEN addr(0)='1' ELSE memmask(4 downto 0)&'1'; + nUDS <= memmaskmux(5); + nLDS <= memmaskmux(4); + clkena_lw <= '1' WHEN clkena_in='1' AND memmaskmux(3)='1' ELSE '0'; + clr_berr <= '1' WHEN setopcode='1' AND trap_berr='1' ELSE '0'; + + PROCESS (clk, nReset) + BEGIN + IF nReset='0' THEN + syncReset <= "0000"; + Reset <= '1'; + ELSIF rising_edge(clk) THEN + IF clkena_in='1' THEN + syncReset <= syncReset(2 downto 0)&'1'; + Reset <= NOT syncReset(3); + END IF; + END IF; + END PROCESS; + +PROCESS (clk, long_done, last_data_in, data_in, byte, addr, long_start, memmaskmux, memread, memmask, data_read) + BEGIN + IF memmaskmux(4)='0' THEN + data_read <= last_data_in(15 downto 0)&data_in; + ELSE + data_read <= last_data_in(23 downto 0)&data_in(15 downto 8); + END IF; + IF memread(0)='1' OR (memread(1 downto 0)="10" AND memmaskmux(4)='1')THEN + data_read(31 downto 16) <= (OTHERS=>data_read(15)); + END IF; + + IF rising_edge(clk) THEN + IF clkena_lw='1' AND state="10" THEN + IF memmaskmux(4)='0' THEN + bf_ext_in <= last_data_in(23 downto 16); + ELSE + bf_ext_in <= last_data_in(31 downto 24); + END IF; + END IF; + IF Reset='1' THEN + last_data_read <= (OTHERS => '0'); + ELSIF clkena_in='1' THEN + IF state="00" OR exec(update_ld)='1' THEN + last_data_read <= data_read; + IF state(1)='0' AND memmask(1)='0' THEN + last_data_read(31 downto 16) <= last_opc_read; + ELSIF state(1)='0' OR memread(1)='1' THEN + last_data_read(31 downto 16) <= (OTHERS=>data_in(15)); + END IF; + END IF; + last_data_in <= last_data_in(15 downto 0)&data_in(15 downto 0); + + END IF; + END IF; + long_start <= to_bit(NOT memmask(1)); + long_done <= to_bit(NOT memread(1)); + END PROCESS; + +PROCESS (byte, long_start, reg_QB, data_write_tmp, exec, data_read, data_write_mux, memmaskmux, bf_ext_out, + data_write_muxin, memmask, oddout, addr) + BEGIN + IF exec(write_reg)='1' THEN + data_write_muxin <= reg_QB; + ELSE + data_write_muxin <= data_write_tmp; + END IF; + + IF BitField=0 THEN + IF oddout=addr(0) THEN + data_write_mux <= "XXXXXXXX"&"XXXXXXXX"&data_write_muxin; + ELSE + data_write_mux <= "XXXXXXXX"&data_write_muxin&"XXXXXXXX"; + END IF; + ELSE + IF oddout=addr(0) THEN + data_write_mux <= "XXXXXXXX"&bf_ext_out&data_write_muxin; + ELSE + data_write_mux <= bf_ext_out&data_write_muxin&"XXXXXXXX"; + END IF; + END IF; + + IF memmaskmux(1)='0' THEN + data_write <= data_write_mux(47 downto 32); + ELSIF memmaskmux(3)='0' THEN + data_write <= data_write_mux(31 downto 16); + ELSE + data_write <= data_write_mux(15 downto 0); + END IF; + IF exec(mem_byte)='1' THEN --movep + data_write(7 downto 0) <= data_write_tmp(15 downto 8); + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- Registerfile +----------------------------------------------------------------------------- +PROCESS (clk, regfile, RDindex_A, RDindex_B, exec) + BEGIN + reg_QA <= regfile(RDindex_A); + reg_QB <= regfile(RDindex_B); + IF rising_edge(clk) THEN + IF clkena_lw='1' THEN + rf_source_addrd <= rf_source_addr; + WR_AReg <= rf_dest_addr(3); + RDindex_A <= to_integer(unsigned(rf_dest_addr(3 downto 0))); + RDindex_B <= to_integer(unsigned(rf_source_addr(3 downto 0))); + IF Wwrena='1' THEN + regfile(RDindex_A) <= regin; + END IF; + + IF exec(to_USP)='1' THEN + USP <= reg_QA; + END IF; + END IF; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- Write Reg +----------------------------------------------------------------------------- +PROCESS (OP1in, reg_QA, Regwrena_now, Bwrena, Lwrena, exe_datatype, WR_AReg, movem_actiond, exec, ALUout, memaddr, memaddr_a, ea_only, USP, movec_data) + BEGIN + regin <= ALUout; + IF exec(save_memaddr)='1' THEN + regin <= memaddr; + ELSIF exec(get_ea_now)='1' AND ea_only='1' THEN + regin <= memaddr_a; + ELSIF exec(from_USP)='1' THEN + regin <= USP; + ELSIF exec(movec_rd)='1' THEN + regin <= movec_data; + END IF; + + IF Bwrena='1' THEN + regin(15 downto 8) <= reg_QA(15 downto 8); + END IF; + IF Lwrena='0' THEN + regin(31 downto 16) <= reg_QA(31 downto 16); + END IF; + + Bwrena <= '0'; + Wwrena <= '0'; + Lwrena <= '0'; + IF exec(presub)='1' OR exec(postadd)='1' OR exec(changeMode)='1' THEN -- -(An)+ + Wwrena <= '1'; + Lwrena <= '1'; + ELSIF Regwrena_now='1' THEN --dbcc + Wwrena <= '1'; + ELSIF exec(Regwrena)='1' THEN --read (mem) + Wwrena <= '1'; + CASE exe_datatype IS + WHEN "00" => --BYTE + Bwrena <= '1'; + WHEN "01" => --WORD + IF WR_AReg='1' OR movem_actiond='1' THEN + Lwrena <='1'; + END IF; + WHEN OTHERS => --LONG + Lwrena <= '1'; + END CASE; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- set dest regaddr +----------------------------------------------------------------------------- +PROCESS (opcode, rf_source_addrd, brief, setstackaddr, dest_hbits, dest_areg, data_is_source, sndOPC, exec, set, dest_2ndHbits) + BEGIN + IF exec(movem_action) ='1' THEN + rf_dest_addr <= rf_source_addrd; + ELSIF set(briefext)='1' THEN + rf_dest_addr <= brief(15 downto 12); + ELSIF set(get_bfoffset)='1' THEN + rf_dest_addr <= sndOPC(9 downto 6); + ELSIF dest_2ndHbits='1' THEN + rf_dest_addr <= sndOPC(15 downto 12); + ELSIF set(write_reminder)='1' THEN + rf_dest_addr <= sndOPC(3 downto 0); + ELSIF setstackaddr='1' THEN + rf_dest_addr <= "1111"; + ELSIF dest_hbits='1' THEN + rf_dest_addr <= dest_areg&opcode(11 downto 9); + ELSE + IF opcode(5 downto 3)="000" OR data_is_source='1' THEN + rf_dest_addr <= dest_areg&opcode(2 downto 0); + ELSE + rf_dest_addr <= '1'&opcode(2 downto 0); + END IF; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- set source regaddr +----------------------------------------------------------------------------- +PROCESS (opcode, movem_presub, movem_regaddr, source_lowbits, source_areg, sndOPC, exec, set, source_2ndLbits, source_2ndHbits) + BEGIN + IF exec(movem_action)='1' OR set(movem_action) ='1' THEN + IF movem_presub='1' THEN + rf_source_addr <= movem_regaddr XOR "1111"; + ELSE + rf_source_addr <= movem_regaddr; + END IF; + ELSIF source_2ndLbits='1' THEN + rf_source_addr <= sndOPC(3 downto 0); + ELSIF source_2ndHbits='1' THEN + rf_source_addr <= sndOPC(15 downto 12); + ELSIF source_lowbits='1' THEN + rf_source_addr <= source_areg&opcode(2 downto 0); + ELSIF exec(linksp)='1' THEN + rf_source_addr <= "1111"; + ELSE + rf_source_addr <= source_areg&opcode(11 downto 9); + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- set OP1out +----------------------------------------------------------------------------- +PROCESS (reg_QA, store_in_tmp, ea_data, long_start, addr, exec, memmaskmux) + BEGIN + OP1out <= reg_QA; + IF exec(OP1out_zero)='1' THEN + OP1out <= (OTHERS => '0'); + ELSIF exec(ea_data_OP1)='1' AND store_in_tmp='1' THEN + OP1out <= ea_data; + ELSIF exec(opcPACK)='1' THEN + OP1out <= data_write_tmp; + ELSIF exec(movem_action)='1' OR memmaskmux(3)='0' OR exec(OP1addr)='1' THEN + OP1out <= addr; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- set OP2out +----------------------------------------------------------------------------- +PROCESS (OP2out, reg_QB, exe_opcode, exe_datatype, execOPC, exec, use_direct_data, + store_in_tmp, data_write_tmp, ea_data) + BEGIN + OP2out(15 downto 0) <= reg_QB(15 downto 0); + OP2out(31 downto 16) <= (OTHERS => OP2out(15)); + IF exec(OP2out_one)='1' THEN + OP2out(15 downto 0) <= "1111111111111111"; + ELSIF exec(opcEXT)='1' THEN + IF exe_opcode(6)='0' OR exe_opcode(8)='1' THEN --ext.w + OP2out(15 downto 8) <= (OTHERS => OP2out(7)); + END IF; + ELSIF use_direct_data='1' OR (exec(exg)='1' AND execOPC='1') OR exec(get_bfoffset)='1' THEN + OP2out <= data_write_tmp; + ELSIF (exec(ea_data_OP1)='0' AND store_in_tmp='1') OR exec(ea_data_OP2)='1' THEN + OP2out <= ea_data; + ELSIF exec(opcMOVEQ)='1' THEN + OP2out(7 downto 0) <= exe_opcode(7 downto 0); + OP2out(15 downto 8) <= (OTHERS => exe_opcode(7)); + ELSIF exec(opcADDQ)='1' THEN + OP2out(2 downto 0) <= exe_opcode(11 downto 9); + IF exe_opcode(11 downto 9)="000" THEN + OP2out(3) <='1'; + ELSE + OP2out(3) <='0'; + END IF; + OP2out(15 downto 4) <= (OTHERS => '0'); + ELSIF exe_datatype="10" THEN + OP2out(31 downto 16) <= reg_QB(31 downto 16); + END IF; + END PROCESS; + + +----------------------------------------------------------------------------- +-- handle EA_data, data_write +----------------------------------------------------------------------------- +PROCESS (clk) + BEGIN + IF rising_edge(clk) THEN + IF Reset = '1' THEN + store_in_tmp <='0'; + exec_write_back <= '0'; + direct_data <= '0'; + use_direct_data <= '0'; + Z_error <= '0'; + ELSIF clkena_lw='1' THEN + direct_data <= '0'; + IF state="11" THEN + exec_write_back <= '0'; + ELSIF setstate="10" AND write_back='1' THEN + exec_write_back <= '1'; + END IF; + + + IF set_direct_data='1' THEN + direct_data <= '1'; + IF set_exec(opcPACK)='1' THEN + use_direct_data <= '0'; + ELSE + use_direct_data <= '1'; + end IF; + ELSIF endOPC='1' THEN + use_direct_data <= '0'; + END IF; + exec_DIRECT <= set_exec(opcMOVE); + + IF endOPC='1' THEN + store_in_tmp <='0'; + Z_error <= '0'; + ELSE + IF set_Z_error='1' THEN + Z_error <= '1'; + END IF; + IF set_exec(opcMOVE)='1' AND state="11" THEN + use_direct_data <= '1'; + END IF; + + IF state="10" THEN + store_in_tmp <= '1'; + END IF; + IF direct_data='1' AND state="00" THEN + store_in_tmp <= '1'; + END IF; + END IF; + IF state="10" THEN + ea_data <= data_read; + ELSIF exec(get_2ndOPC)='1' THEN + ea_data <= addr; + ELSIF exec(store_ea_data)='1' OR (direct_data='1' AND state="00") THEN + ea_data <= last_data_read; + END IF; + + IF writePC='1' THEN + data_write_tmp <= TG68_PC; + ELSIF exec(writePC_add)='1' THEN + data_write_tmp <= TG68_PC_add; + ELSIF micro_state=trap0 THEN + data_write_tmp(15 downto 0) <= trap_vector(15 downto 0); + ELSIF exec(hold_dwr)='1' THEN + data_write_tmp <= data_write_tmp; + ELSIF exec(exg)='1' THEN + data_write_tmp <= OP1out; + ELSIF exec(get_ea_now)='1' AND ea_only='1' THEN -- ist for pea + data_write_tmp <= addr; + ELSIF execOPC='1' or micro_state=pack2 THEN + data_write_tmp <= ALUout; + ELSIF (exec_DIRECT='1' AND state="10") THEN + data_write_tmp <= data_read; + IF exec(movepl)='1' THEN + data_write_tmp(31 downto 8) <= data_write_tmp(23 downto 0); + END IF; + ELSIF exec(movepl)='1' THEN + data_write_tmp(15 downto 0) <= reg_QB(31 downto 16); + ELSIF direct_data='1' THEN + data_write_tmp <= last_data_read; + ELSIF writeSR='1'THEN + data_write_tmp(15 downto 0) <= trap_SR(7 downto 0)& Flags(7 downto 0); + ELSE + data_write_tmp <= OP2out; + END IF; + END IF; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- brief +----------------------------------------------------------------------------- +PROCESS (brief, OP1out, OP1outbrief, cpu) + BEGIN + IF brief(11)='1' THEN + OP1outbrief <= OP1out(31 downto 16); + ELSE + OP1outbrief <= (OTHERS=>OP1out(15)); + END IF; + briefdata <= OP1outbrief&OP1out(15 downto 0); + IF extAddr_Mode=1 OR (cpu(1)='1' AND extAddr_Mode=2) THEN + CASE brief(10 downto 9) IS + WHEN "00" => briefdata <= OP1outbrief&OP1out(15 downto 0); + WHEN "01" => briefdata <= OP1outbrief(14 downto 0)&OP1out(15 downto 0)&'0'; + WHEN "10" => briefdata <= OP1outbrief(13 downto 0)&OP1out(15 downto 0)&"00"; + WHEN "11" => briefdata <= OP1outbrief(12 downto 0)&OP1out(15 downto 0)&"000"; + WHEN OTHERS => NULL; + END CASE; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- MEM_IO +----------------------------------------------------------------------------- +PROCESS (clk, setdisp, memaddr_a, briefdata, memaddr_delta, setdispbyte, datatype, interrupt, rIPL_nr, IPL_vec, + memaddr_reg, reg_QA, use_base, VBR, last_data_read, trap_vector, exec, set, cpu) + BEGIN + + IF rising_edge(clk) THEN + IF clkena_lw='1' THEN +-- trap_vector(31 downto 8) <= (others => '0'); + trap_vector(31 downto 10) <= (others => '0'); +-- IF trap_addr_fault='1' THEN + IF trap_berr='1' THEN + trap_vector(9 downto 0) <= "00" & X"08"; + END IF; + IF trap_addr_error='1' THEN + trap_vector(9 downto 0) <= "00" & X"0C"; + END IF; + IF trap_illegal='1' THEN + trap_vector(9 downto 0) <= "00" & X"10"; + END IF; + IF z_error='1' THEN + trap_vector(9 downto 0) <= "00" & X"14"; + END IF; + IF exec(trap_chk)='1' THEN + trap_vector(9 downto 0) <= "00" & X"18"; + END IF; + IF trap_trapv='1' THEN + trap_vector(9 downto 0) <= "00" & X"1C"; + END IF; + IF trap_priv='1' THEN + trap_vector(9 downto 0) <= "00" & X"20"; + END IF; + IF trap_trace='1' THEN + trap_vector(9 downto 0) <= "00" & X"24"; + END IF; + IF trap_1010='1' THEN + trap_vector(9 downto 0) <= "00" & X"28"; + END IF; + IF trap_1111='1' THEN + trap_vector(9 downto 0) <= "00" & X"2C"; + END IF; + IF trap_trap='1' THEN + trap_vector(9 downto 0) <= "0010" & opcode(3 downto 0) & "00"; + END IF; + IF trap_interrupt='1' or set_vectoraddr = '1' THEN + trap_vector(9 downto 0) <= IPL_vec & "00"; --TH + END IF; + -- TH TODO: non-autovector IRQs + END IF; + END IF; + IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN + trap_vector_vbr <= trap_vector; + ELSE + trap_vector_vbr <= std_logic_vector(unsigned(trap_vector) + unsigned(VBR)); + END IF; + + memaddr_a(4 downto 0) <= "00000"; + memaddr_a(7 downto 5) <= (OTHERS=>memaddr_a(4)); + memaddr_a(15 downto 8) <= (OTHERS=>memaddr_a(7)); + memaddr_a(31 downto 16) <= (OTHERS=>memaddr_a(15)); + IF setdisp='1' THEN + IF exec(briefext)='1' THEN + memaddr_a <= std_logic_vector(unsigned(briefdata) + unsigned(memaddr_delta)); + ELSIF setdispbyte='1' THEN + memaddr_a(7 downto 0) <= last_data_read(7 downto 0); + ELSE + memaddr_a <= last_data_read; + END IF; + ELSIF set(presub)='1' THEN + IF set(longaktion)='1' THEN + memaddr_a(4 downto 0) <= "11100"; + ELSIF datatype="00" AND set(use_SP)='0' THEN + memaddr_a(4 downto 0) <= "11111"; + ELSE + memaddr_a(4 downto 0) <= "11110"; + END IF; + ELSIF interrupt='1' THEN + memaddr_a(4 downto 0) <= '1'&rIPL_nr&'0'; + END IF; + + IF rising_edge(clk) THEN + IF clkena_in='1' THEN + IF exec(get_2ndOPC)='1' OR (state="10" AND memread(0)='1') THEN + tmp_TG68_PC <= addr; + END IF; + use_base <= '0'; + IF memmaskmux(3)='0' OR exec(mem_addsub)='1' THEN + memaddr_delta <= addsub_q; + ELSIF state="01" AND exec_write_back='1' THEN + memaddr_delta <= tmp_TG68_PC; + ELSIF exec(direct_delta)='1' THEN + memaddr_delta <= data_read; + ELSIF exec(ea_to_pc)='1' AND setstate="00" THEN + memaddr_delta <= addr; + ELSIF set(addrlong)='1' THEN + memaddr_delta <= last_data_read; + ELSIF setstate="00" THEN + memaddr_delta <= TG68_PC_add; + ELSIF exec(dispouter)='1' THEN + memaddr_delta <= std_logic_vector(unsigned(ea_data)+unsigned(memaddr_a)); + ELSIF set_vectoraddr='1' THEN + memaddr_delta <= trap_vector_vbr; + ELSE + memaddr_delta <= memaddr_a; + IF interrupt='0' AND Suppress_Base='0' THEN +-- IF interrupt='0' AND Suppress_Base='0' AND setstate(1)='1' THEN + use_base <= '1'; + END IF; + END IF; + +-- IF clkena_in THEN + IF (long_done='0' AND state(1)='1') OR movem_presub='0' THEN + memaddr <= addr; + END IF; +-- END IF; + END IF; + END IF; + + addr <= std_logic_vector(unsigned(memaddr_reg)+unsigned(memaddr_delta)); + IF use_base='0' THEN + memaddr_reg <= (others=>'0'); + ELSE + memaddr_reg <= reg_QA; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- PC Calc + fetch opcode +----------------------------------------------------------------------------- +PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro_state, stop, make_trace, make_berr, IPL_nr, FlagsSR, set_rot_cnt, opcode, writePCbig, set_exec, exec, + PC_dataa, PC_datab, setnextpass, last_data_read, TG68_PC_brw, TG68_PC_word, Z_error, trap_trap, trap_trapv, interrupt, tmp_TG68_PC, TG68_PC) + BEGIN + + PC_dataa <= TG68_PC; + IF TG68_PC_brw = '1' THEN + PC_dataa <= tmp_TG68_PC; + END IF; + + PC_datab(2 downto 0) <= (others => '0'); + PC_datab(3) <= PC_datab(2); + PC_datab(7 downto 4) <= (others => PC_datab(3)); + PC_datab(15 downto 8) <= (others => PC_datab(7)); + PC_datab(31 downto 16) <= (others => PC_datab(15)); + IF interrupt='1' THEN + PC_datab(2 downto 1) <= "11"; + END IF; + IF exec(writePC_add) ='1' THEN + IF writePCbig='1' THEN + PC_datab(3) <= '1'; + PC_datab(1) <= '1'; + ELSE + PC_datab(2) <= '1'; + END IF; + IF trap_trap='1' OR trap_trapv='1' OR exec(trap_chk)='1' OR Z_error='1' THEN + PC_datab(1) <= '1'; + END IF; + ELSIF state="00" THEN + PC_datab(1) <= '1'; + END IF; + IF TG68_PC_brw = '1' THEN + IF TG68_PC_word='1' THEN + PC_datab <= last_data_read; + ELSE + PC_datab(7 downto 0) <= opcode(7 downto 0); + END IF; + END IF; + + TG68_PC_add <= std_logic_vector(unsigned(PC_dataa)+unsigned(PC_datab)); + + setopcode <= '0'; + setendOPC <= '0'; + setinterrupt <= '0'; + IF setstate="00" AND next_micro_state=idle AND setnextpass='0' AND (exec_write_back='0' OR state="11") AND set_rot_cnt="000001" AND set_exec(opcCHK)='0'THEN + setendOPC <= '1'; + IF FlagsSR(2 downto 0) + set_memmask <= "101111"; + WHEN "001" => + set_memmask <= "100111"; + WHEN "010" => + set_memmask <= "100011"; + WHEN "011" => + set_memmask <= "100001"; + WHEN OTHERS => + set_memmask <= "100000"; + END CASE; + IF setstate="00" THEN + set_memmask <= "100111"; + END IF; + END PROCESS; + +------------------------------------------------------------------------------ +--SR op +------------------------------------------------------------------------------ +PROCESS (clk, Reset, FlagsSR, last_data_read, OP2out, exec) + BEGIN + IF exec(andiSR)='1' THEN + SRin <= FlagsSR AND last_data_read(15 downto 8); + ELSIF exec(eoriSR)='1' THEN + SRin <= FlagsSR XOR last_data_read(15 downto 8); + ELSIF exec(oriSR)='1' THEN + SRin <= FlagsSR OR last_data_read(15 downto 8); + ELSE + SRin <= OP2out(15 downto 8); + END IF; + + IF rising_edge(clk) THEN + IF Reset='1' THEN + FlagsSR(7 downto 5) <= "001"; + FC(2) <= '1'; + SVmode <= '1'; + preSVmode <= '1'; + FlagsSR(2 downto 0) <= "111"; + make_trace <= '0'; + ELSIF clkena_lw = '1' THEN + IF setopcode='1' THEN + make_trace <= FlagsSR(7); + IF set(changeMode)='1' THEN + SVmode <= NOT SVmode; + ELSE + SVmode <= preSVmode; + END IF; + END IF; + IF set(changeMode)='1' THEN + preSVmode <= NOT preSVmode; + FlagsSR(5) <= NOT preSVmode; + FC(2) <= NOT preSVmode; + END IF; + IF micro_state=trap3 THEN + FlagsSR(7) <= '0'; + END IF; + IF trap_trace='1' AND state="10" THEN + make_trace <= '0'; + END IF; + IF exec(directSR)='1' OR set_stop='1' THEN + FlagsSR <= data_read(15 downto 8); + END IF; + IF interrupt='1' AND trap_interrupt='1' THEN + FlagsSR(2 downto 0) <=rIPL_nr; + END IF; +-- IF exec(to_CCR)='1' AND exec(to_SR)='1' THEN + IF exec(to_SR)='1' THEN + FlagsSR(7 downto 0) <= SRin; --SR + FC(2) <= SRin(5); +-- END IF; + ELSIF exec(update_FC)='1' THEN + FC(2) <= FlagsSR(5); + END IF; + IF interrupt='1' THEN + FC(2) <= '1'; + END IF; + END IF; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- decode opcode +----------------------------------------------------------------------------- +PROCESS (clk, cpu, OP1out, OP2out, opcode, exe_condition, nextpass, micro_state, decodeOPC, state, setexecOPC, Flags, FlagsSR, direct_data, build_logical, + build_bcd, set_Z_error, trapd, movem_run, last_data_read, set, set_V_Flag, z_error, trap_trace, trap_interrupt, + SVmode, preSVmode, stop, long_done, ea_only, setstate, execOPC, exec_write_back, exe_datatype, + datatype, interrupt, c_out, trapmake, rot_cnt, brief, addr, + long_start, set_datatype, sndOPC, set_exec, exec, ea_build_now, reg_QA, reg_QB, make_berr, trap_berr) + BEGIN + TG68_PC_brw <= '0'; + setstate <= "00"; + Regwrena_now <= '0'; + movem_presub <= '0'; + setnextpass <= '0'; + regdirectsource <= '0'; + setdisp <= '0'; + setdispbyte <= '0'; + getbrief <= '0'; + dest_areg <= '0'; + source_areg <= '0'; + data_is_source <= '0'; + write_back <= '0'; + setstackaddr <= '0'; + writePC <= '0'; + ea_build_now <= '0'; + set_rot_bits <= "XX"; + set_rot_cnt <= "000001"; + dest_hbits <= '0'; + source_lowbits <= '0'; + source_2ndHbits <= '0'; + source_2ndLbits <= '0'; + dest_2ndHbits <= '0'; + ea_only <= '0'; + set_direct_data <= '0'; + set_exec_tas <= '0'; + trap_illegal <='0'; + trap_addr_error <= '0'; + trap_priv <='0'; + trap_1010 <='0'; + trap_1111 <='0'; + trap_trap <='0'; + trap_trapv <= '0'; + trapmake <='0'; + set_vectoraddr <='0'; + writeSR <= '0'; + set_stop <= '0'; + illegal_write_mode <= '0'; + illegal_read_mode <= '0'; + illegal_byteaddr <= '0'; + set_Z_error <= '0'; + + next_micro_state <= idle; + build_logical <= '0'; + build_bcd <= '0'; + skipFetch <= make_berr; + set_writePCbig <= '0'; +-- set_recall_last <= '0'; + set_Suppress_Base <= '0'; + set_PCbase <= '0'; + + IF rot_cnt/="000001" THEN + set_rot_cnt <= std_logic_vector(unsigned(rot_cnt)-1); + END IF; + set_datatype <= datatype; + + set <= (OTHERS=>'0'); + set_exec <= (OTHERS=>'0'); + set(update_ld) <= '0'; +-- odd_start <= '0'; +------------------------------------------------------------------------------ +--Sourcepass +------------------------------------------------------------------------------ + CASE opcode(7 downto 6) IS + WHEN "00" => datatype <= "00"; --Byte + WHEN "01" => datatype <= "01"; --Word + WHEN OTHERS => datatype <= "10"; --Long + END CASE; + + IF trapmake='1' AND trapd='0' THEN + next_micro_state <= trap0; + IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN + set(writePC_add) <= '1'; +-- set_datatype <= "10"; + END IF; + IF preSVmode='0' THEN + set(changeMode) <= '1'; + END IF; + setstate <= "01"; + END IF; + IF interrupt='1' AND trap_berr='1' THEN + next_micro_state <= trap0; + IF preSVmode='0' THEN + set(changeMode) <= '1'; + END IF; + setstate <= "01"; + END IF; + IF micro_state=int1 OR (interrupt='1' AND trap_trace='1') THEN + next_micro_state <= trap0; +-- IF cpu(0)='0' THEN +-- set_datatype <= "10"; +-- END IF; + IF preSVmode='0' THEN + set(changeMode) <= '1'; + END IF; + setstate <= "01"; + END IF; + + IF setexecOPC='1' AND FlagsSR(5)/=preSVmode THEN + set(changeMode) <= '1'; +-- setstate <= "01"; +-- next_micro_state <= nop; + END IF; + + IF interrupt='1' AND trap_interrupt='1'THEN +-- skipFetch <= '1'; + next_micro_state <= int1; + set(update_ld) <= '1'; + setstate <= "10"; + END IF; + + IF set(changeMode)='1' THEN + set(to_USP) <= '1'; + set(from_USP) <= '1'; + setstackaddr <='1'; + END IF; + + IF ea_only='0' AND set(get_ea_now)='1' THEN + setstate <= "10"; +-- set_recall_last <= '1'; +-- set(update_ld) <= '0'; + END IF; + + IF setstate(1)='1' AND set_datatype(1)='1' THEN + set(longaktion) <= '1'; + END IF; + + IF (ea_build_now='1' AND decodeOPC='1') OR exec(ea_build)='1' THEN + CASE opcode(5 downto 3) IS --source + WHEN "010"|"011"|"100" => -- -(An)+ + set(get_ea_now) <='1'; + setnextpass <= '1'; + IF opcode(3)='1' THEN --(An)+ + set(postadd) <= '1'; + IF opcode(2 downto 0)="111" THEN + set(use_SP) <= '1'; + END IF; + END IF; + IF opcode(5)='1' THEN -- -(An) + set(presub) <= '1'; + IF opcode(2 downto 0)="111" THEN + set(use_SP) <= '1'; + END IF; + END IF; + WHEN "101" => --(d16,An) + next_micro_state <= ld_dAn1; + WHEN "110" => --(d8,An,Xn) + next_micro_state <= ld_AnXn1; + getbrief <='1'; + WHEN "111" => + CASE opcode(2 downto 0) IS + WHEN "000" => --(xxxx).w + next_micro_state <= ld_nn; + WHEN "001" => --(xxxx).l + set(longaktion) <= '1'; + next_micro_state <= ld_nn; + WHEN "010" => --(d16,PC) + next_micro_state <= ld_dAn1; + set(dispouter) <= '1'; + set_Suppress_Base <= '1'; + set_PCbase <= '1'; + WHEN "011" => --(d8,PC,Xn) + next_micro_state <= ld_AnXn1; + getbrief <= '1'; + set(dispouter) <= '1'; + set_Suppress_Base <= '1'; + set_PCbase <= '1'; + WHEN "100" => --#data + setnextpass <= '1'; + set_direct_data <= '1'; + IF datatype="10" THEN + set(longaktion) <= '1'; + END IF; + WHEN OTHERS => NULL; + END CASE; + WHEN OTHERS => NULL; + END CASE; + END IF; +------------------------------------------------------------------------------ +--prepere opcode +------------------------------------------------------------------------------ + CASE opcode(15 downto 12) IS +-- 0000 ---------------------------------------------------------------------------- + WHEN "0000" => + IF opcode(8)='1' AND opcode(5 downto 3)="001" THEN --movep + datatype <= "00"; --Byte + set(use_SP) <= '1'; --addr+2 + set(no_Flags) <='1'; + IF opcode(7)='0' THEN --to register + set_exec(Regwrena) <= '1'; + set_exec(opcMOVE) <= '1'; + set(movepl) <= '1'; + END IF; + IF decodeOPC='1' THEN + IF opcode(6)='1' THEN + set(movepl) <= '1'; + END IF; + IF opcode(7)='0' THEN + set_direct_data <= '1'; -- to register + END IF; + next_micro_state <= movep1; + END IF; + IF setexecOPC='1' THEN + dest_hbits <='1'; + END IF; + ELSE + IF opcode(8)='1' OR opcode(11 downto 9)="100" THEN --Bits + set_exec(opcBITS) <= '1'; + set_exec(ea_data_OP1) <= '1'; + IF opcode(7 downto 6)/="00" THEN + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + write_back <= '1'; + END IF; + IF opcode(5 downto 4)="00" THEN + datatype <= "10"; --Long + ELSE + datatype <= "00"; --Byte + END IF; + IF opcode(8)='0' THEN + IF decodeOPC='1' THEN + next_micro_state <= nop; + set(get_2ndOPC) <= '1'; + set(ea_build) <= '1'; + END IF; + ELSE + ea_build_now <= '1'; + END IF; + ELSIF opcode(11 downto 9)="111" THEN --MOVES not in 68000 + trap_illegal <= '1'; +-- trap_addr_error <= '1'; + trapmake <= '1'; + ELSE --andi, ...xxxi + IF opcode(11 downto 9)="000" THEN --ORI + set_exec(opcOR) <= '1'; + END IF; + IF opcode(11 downto 9)="001" THEN --ANDI + set_exec(opcAND) <= '1'; + END IF; + IF opcode(11 downto 9)="010" OR opcode(11 downto 9)="011" THEN --SUBI, ADDI + set_exec(opcADD) <= '1'; + END IF; + IF opcode(11 downto 9)="101" THEN --EORI + set_exec(opcEOR) <= '1'; + END IF; + IF opcode(11 downto 9)="110" THEN --CMPI + set_exec(opcCMP) <= '1'; + END IF; + IF opcode(7)='0' AND opcode(5 downto 0)="111100" AND (set_exec(opcAND) OR set_exec(opcOR) OR set_exec(opcEOR))='1' THEN --SR + IF decodeOPC='1' AND SVmode='0' AND opcode(6)='1' THEN --SR + trap_priv <= '1'; + trapmake <= '1'; + ELSE + set(no_Flags) <= '1'; + IF decodeOPC='1' THEN + IF opcode(6)='1' THEN + set(to_SR) <= '1'; + END IF; + set(to_CCR) <= '1'; + set(andiSR) <= set_exec(opcAND); + set(eoriSR) <= set_exec(opcEOR); + set(oriSR) <= set_exec(opcOR); + setstate <= "01"; + next_micro_state <= nopnop; + END IF; + END IF; + ELSE + IF decodeOPC='1' THEN + next_micro_state <= andi; + set(ea_build) <= '1'; + set_direct_data <= '1'; + IF datatype="10" THEN + set(longaktion) <= '1'; + END IF; + END IF; + IF opcode(5 downto 4)/="00" THEN + set_exec(ea_data_OP1) <= '1'; + END IF; + IF opcode(11 downto 9)/="110" THEN --CMPI + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + write_back <= '1'; + END IF; + IF opcode(10 downto 9)="10" THEN --CMPI, SUBI + set(addsub) <= '1'; + END IF; + END IF; + END IF; + END IF; + +-- 0001, 0010, 0011 ----------------------------------------------------------------- + WHEN "0001"|"0010"|"0011" => --move.b, move.l, move.w + set_exec(opcMOVE) <= '1'; + ea_build_now <= '1'; + IF opcode(8 downto 6)="001" THEN + set(no_Flags) <= '1'; + END IF; + IF opcode(5 downto 4)="00" THEN --Dn, An + IF opcode(8 downto 7)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + END IF; + CASE opcode(13 downto 12) IS + WHEN "01" => datatype <= "00"; --Byte + WHEN "10" => datatype <= "10"; --Long + WHEN OTHERS => datatype <= "01"; --Word + END CASE; + source_lowbits <= '1'; -- Dn=> An=> + IF opcode(3)='1' THEN + source_areg <= '1'; + END IF; + + IF nextpass='1' OR opcode(5 downto 4)="00" THEN + dest_hbits <= '1'; + IF opcode(8 downto 6)/="000" THEN + dest_areg <= '1'; + END IF; + END IF; +-- IF setstate="10" THEN +-- set(update_ld) <= '0'; +-- END IF; +-- + IF micro_state=idle AND (nextpass='1' OR (opcode(5 downto 4)="00" AND decodeOPC='1')) THEN + CASE opcode(8 downto 6) IS --destination + WHEN "000"|"001" => --Dn,An + set_exec(Regwrena) <= '1'; + WHEN "010"|"011"|"100" => --destination -(an)+ + IF opcode(6)='1' THEN --(An)+ + set(postadd) <= '1'; + IF opcode(11 downto 9)="111" THEN + set(use_SP) <= '1'; + END IF; + END IF; + IF opcode(8)='1' THEN -- -(An) + set(presub) <= '1'; + IF opcode(11 downto 9)="111" THEN + set(use_SP) <= '1'; + END IF; + END IF; + setstate <= "11"; + next_micro_state <= nop; + IF nextpass='0' THEN + set(write_reg) <= '1'; + END IF; + WHEN "101" => --(d16,An) + next_micro_state <= st_dAn1; +-- getbrief <= '1'; + WHEN "110" => --(d8,An,Xn) + next_micro_state <= st_AnXn1; + getbrief <= '1'; + WHEN "111" => + CASE opcode(11 downto 9) IS + WHEN "000" => --(xxxx).w + next_micro_state <= st_nn; + WHEN "001" => --(xxxx).l + set(longaktion) <= '1'; + next_micro_state <= st_nn; + WHEN OTHERS => NULL; + END CASE; + WHEN OTHERS => NULL; + END CASE; + END IF; +---- 0100 ---------------------------------------------------------------------------- + WHEN "0100" => --rts_group + IF opcode(8)='1' THEN --lea + IF opcode(6)='1' THEN --lea + IF opcode(7)='1' THEN + source_lowbits <= '1'; +-- IF opcode(5 downto 3)="000" AND opcode(10)='0' THEN --ext + IF opcode(5 downto 4)="00" THEN --extb.l + set_exec(opcEXT) <= '1'; + set_exec(opcMOVE) <= '1'; + set_exec(Regwrena) <= '1'; +-- IF opcode(6)='0' THEN +-- datatype <= "01"; --WORD +-- END IF; + ELSE + source_areg <= '1'; + ea_only <= '1'; + set_exec(Regwrena) <= '1'; + set_exec(opcMOVE) <='1'; + set(no_Flags) <='1'; + IF opcode(5 downto 3)="010" THEN --lea (Am),An + dest_areg <= '1'; + dest_hbits <= '1'; + ELSE + ea_build_now <= '1'; + END IF; + IF set(get_ea_now)='1' THEN + setstate <= "01"; + set_direct_data <= '1'; + END IF; + IF setexecOPC='1' THEN + dest_areg <= '1'; + dest_hbits <= '1'; + END IF; + END IF; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + ELSE --chk + IF opcode(7)='1' THEN + datatype <= "01"; --Word + set(trap_chk) <= '1'; + IF (c_out(1)='0' OR OP1out(15)='1' OR OP2out(15)='1') AND exec(opcCHK)='1' THEN + trapmake <= '1'; + END IF; + ELSIF cpu(1)='1' THEN --chk long for 68020 + datatype <= "10"; --Long + set(trap_chk) <= '1'; + IF (c_out(2)='1' OR OP1out(31)='1' OR OP2out(31)='1') AND exec(opcCHK)='1' THEN + trapmake <= '1'; + END IF; + ELSE + trap_illegal <= '1'; -- chk long for 68020 + trapmake <= '1'; + END IF; + IF opcode(7)='1' OR cpu(1)='1' THEN + IF (nextpass='1' OR opcode(5 downto 4)="00") AND exec(opcCHK)='0' AND micro_state=idle THEN + set_exec(opcCHK) <= '1'; + END IF; + ea_build_now <= '1'; + set(addsub) <= '1'; + IF setexecOPC='1' THEN + dest_hbits <= '1'; + source_lowbits <='1'; + END IF; + END IF; + END IF; + ELSE + CASE opcode(11 downto 9) IS + WHEN "000"=> + IF opcode(7 downto 6)="11" THEN --move from SR + IF SR_Read=0 OR (cpu(0)='0' AND SR_Read=2) OR SVmode='1' THEN +-- IF SVmode='1' THEN + ea_build_now <= '1'; + set_exec(opcMOVESR) <= '1'; + datatype <= "01"; + write_back <='1'; -- im 68000 wird auch erst gelesen + IF cpu(0)='1' AND state="10" THEN + skipFetch <= '1'; + END IF; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + ELSE + trap_priv <= '1'; + trapmake <= '1'; + END IF; + ELSE --negx + ea_build_now <= '1'; + set_exec(use_XZFlag) <= '1'; + write_back <='1'; + set_exec(opcADD) <= '1'; + set(addsub) <= '1'; + source_lowbits <= '1'; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + IF setexecOPC='1' THEN + set(OP1out_zero) <= '1'; + END IF; + END IF; + WHEN "001"=> + IF opcode(7 downto 6)="11" THEN --move from CCR 68010 + IF SR_Read=1 OR (cpu(0)='1' AND SR_Read=2) THEN + ea_build_now <= '1'; + set_exec(opcMOVESR) <= '1'; + datatype <= "00"; + write_back <='1'; -- im 68000 wird auch erst gelesen + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + ELSE --clr + ea_build_now <= '1'; + write_back <='1'; + set_exec(opcAND) <= '1'; + IF cpu(0)='1' AND state="10" THEN + skipFetch <= '1'; + END IF; + IF setexecOPC='1' THEN + set(OP1out_zero) <= '1'; + END IF; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + END IF; + WHEN "010"=> + ea_build_now <= '1'; + IF opcode(7 downto 6)="11" THEN --move to CCR + datatype <= "01"; + source_lowbits <= '1'; + IF (decodeOPC='1' AND opcode(5 downto 4)="00") OR state="10" OR direct_data='1' THEN + set(to_CCR) <= '1'; + END IF; + ELSE --neg + write_back <='1'; + set_exec(opcADD) <= '1'; + set(addsub) <= '1'; + source_lowbits <= '1'; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + IF setexecOPC='1' THEN + set(OP1out_zero) <= '1'; + END IF; + END IF; + WHEN "011"=> --not, move toSR + IF opcode(7 downto 6)="11" THEN --move to SR + IF SVmode='1' THEN + ea_build_now <= '1'; + datatype <= "01"; + source_lowbits <= '1'; + IF (decodeOPC='1' AND opcode(5 downto 4)="00") OR state="10" OR direct_data='1' THEN + set(to_SR) <= '1'; + set(to_CCR) <= '1'; + END IF; + IF exec(to_SR)='1' OR (decodeOPC='1' AND opcode(5 downto 4)="00") OR state="10" OR direct_data='1' THEN + setstate <="01"; + END IF; + ELSE + trap_priv <= '1'; + trapmake <= '1'; + END IF; + ELSE --not + ea_build_now <= '1'; + write_back <='1'; + set_exec(opcEOR) <= '1'; + set_exec(ea_data_OP1) <= '1'; + IF opcode(5 downto 3)="000" THEN + set_exec(Regwrena) <= '1'; + END IF; + IF setexecOPC='1' THEN + set(OP2out_one) <= '1'; + END IF; + END IF; + WHEN "100"|"110"=> + IF opcode(7)='1' THEN --movem, ext + IF opcode(5 downto 3)="000" AND opcode(10)='0' THEN --ext + source_lowbits <= '1'; + set_exec(opcEXT) <= '1'; + set_exec(opcMOVE) <= '1'; + set_exec(Regwrena) <= '1'; + IF opcode(6)='0' THEN + datatype <= "01"; --WORD + END IF; + ELSE --movem +-- IF opcode(11 downto 7)="10001" OR opcode(11 downto 7)="11001" THEN --MOVEM + ea_only <= '1'; + set(no_Flags) <= '1'; + IF opcode(6)='0' THEN + datatype <= "01"; --Word transfer + END IF; + IF (opcode(5 downto 3)="100" OR opcode(5 downto 3)="011") AND state="01" THEN -- -(An), (An)+ + set_exec(save_memaddr) <= '1'; + set_exec(Regwrena) <= '1'; + END IF; + IF opcode(5 downto 3)="100" THEN -- -(An) + movem_presub <= '1'; + set(subidx) <= '1'; + END IF; + IF state="10" THEN + set(Regwrena) <= '1'; + set(opcMOVE) <= '1'; + END IF; + IF decodeOPC='1' THEN + set(get_2ndOPC) <='1'; + IF opcode(5 downto 3)="010" OR opcode(5 downto 3)="011" OR opcode(5 downto 3)="100" THEN + next_micro_state <= movem1; + ELSE + next_micro_state <= nop; + set(ea_build) <= '1'; + END IF; + END IF; + IF set(get_ea_now)='1' THEN + IF movem_run='1' THEN + set(movem_action) <= '1'; + IF opcode(10)='0' THEN + setstate <="11"; + set(write_reg) <= '1'; + ELSE + setstate <="10"; + END IF; + next_micro_state <= movem2; + set(mem_addsub) <= '1'; + ELSE + setstate <="01"; + END IF; + END IF; + END IF; + ELSE + IF opcode(10)='1' THEN --MUL.L, DIV.L 68020 +-- IF cpu(1)='1' THEN + IF (opcode(6)='1' AND (DIV_Mode=1 OR (cpu(1)='1' AND DIV_Mode=2))) OR + (opcode(6)='0' AND (MUL_Mode=1 OR (cpu(1)='1' AND MUL_Mode=2))) THEN + IF decodeOPC='1' THEN + next_micro_state <= nop; + set(get_2ndOPC) <= '1'; + set(ea_build) <= '1'; + END IF; + IF (micro_state=idle AND nextpass='1') OR (opcode(5 downto 4)="00" AND exec(ea_build)='1')THEN + setstate <="01"; + dest_2ndHbits <= '1'; + source_2ndLbits <= '1'; + IF opcode(6)='1' THEN + next_micro_state <= div1; + ELSE + next_micro_state <= mul1; + set(ld_rot_cnt) <= '1'; + END IF; + END IF; + IF z_error='0' AND set_V_Flag='0' AND set(opcDIVU)='1' THEN + set(Regwrena) <= '1'; + END IF; + source_lowbits <='1'; + IF nextpass='1' OR (opcode(5 downto 4)="00" AND decodeOPC='1') THEN + dest_hbits <= '1'; + END IF; + datatype <= "10"; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + + ELSE --pea, swap + IF opcode(6)='1' THEN + datatype <= "10"; + IF opcode(5 downto 3)="000" THEN --swap + set_exec(opcSWAP) <= '1'; + set_exec(Regwrena) <= '1'; + ELSIF opcode(5 downto 3)="001" THEN --bkpt + + ELSE --pea + ea_only <= '1'; + ea_build_now <= '1'; + IF nextpass='1' AND micro_state=idle THEN + set(presub) <= '1'; + setstackaddr <='1'; + setstate <="11"; + next_micro_state <= nop; + END IF; + IF set(get_ea_now)='1' THEN + setstate <="01"; + END IF; + END IF; + ELSE + IF opcode(5 downto 3)="001" THEN --link.l + datatype <= "10"; + set_exec(opcADD) <= '1'; --for displacement + set_exec(Regwrena) <= '1'; + set(no_Flags) <= '1'; + IF decodeOPC='1' THEN + set(linksp) <= '1'; + set(longaktion) <= '1'; + next_micro_state <= link1; + set(presub) <= '1'; + setstackaddr <='1'; + set(mem_addsub) <= '1'; + source_lowbits <= '1'; + source_areg <= '1'; + set(store_ea_data) <= '1'; + END IF; + ELSE --nbcd + ea_build_now <= '1'; + set_exec(use_XZFlag) <= '1'; + write_back <='1'; + set_exec(opcADD) <= '1'; + set_exec(opcSBCD) <= '1'; + source_lowbits <= '1'; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + IF setexecOPC='1' THEN + set(OP1out_zero) <= '1'; + END IF; + END IF; + END IF; + END IF; + END IF; +-- + WHEN "101"=> --tst, tas 4aFC - illegal + IF opcode(7 downto 2)="111111" THEN --illegal + trap_illegal <= '1'; + trapmake <= '1'; + ELSE + ea_build_now <= '1'; + IF setexecOPC='1' THEN + source_lowbits <= '1'; + IF opcode(3)='1' THEN --MC68020... + source_areg <= '1'; + END IF; + END IF; + set_exec(opcMOVE) <= '1'; + IF opcode(7 downto 6)="11" THEN --tas + set_exec_tas <= '1'; + write_back <= '1'; + datatype <= "00"; --Byte + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + END IF; + END IF; +---- WHEN "110"=> + WHEN "111"=> --4EXX +-- +-- ea_only <= '1'; +-- ea_build_now <= '1'; +-- IF nextpass='1' AND micro_state=idle THEN +-- set(presub) <= '1'; +-- setstackaddr <='1'; +-- set(mem_addsub) <= '1'; +-- setstate <="11"; +-- next_micro_state <= nop; +-- END IF; +-- IF set(get_ea_now)='1' THEN +-- setstate <="01"; +-- END IF; +-- + + + + IF opcode(7)='1' THEN --jsr, jmp + datatype <= "10"; + ea_only <= '1'; + ea_build_now <= '1'; + IF exec(ea_to_pc)='1' THEN + next_micro_state <= nop; + END IF; + IF nextpass='1' AND micro_state=idle AND opcode(6)='0' THEN + set(presub) <= '1'; + setstackaddr <='1'; + setstate <="11"; + next_micro_state <= nopnop; + END IF; +-- achtung buggefahr + IF micro_state=ld_AnXn1 AND brief(8)='0'THEN --JMP/JSR n(Ax,Dn) + skipFetch <= '1'; + END IF; + IF state="00" THEN + writePC <= '1'; + END IF; + set(hold_dwr) <= '1'; + IF set(get_ea_now)='1' THEN --jsr + IF exec(longaktion)='0' OR long_done='1' THEN + skipFetch <= '1'; + END IF; + setstate <="01"; + set(ea_to_pc) <= '1'; + END IF; + ELSE -- + CASE opcode(6 downto 0) IS + WHEN "1000000"|"1000001"|"1000010"|"1000011"|"1000100"|"1000101"|"1000110"|"1000111"| --trap + "1001000"|"1001001"|"1001010"|"1001011"|"1001100"|"1001101"|"1001110"|"1001111" => --trap + trap_trap <='1'; + trapmake <= '1'; + WHEN "1010000"|"1010001"|"1010010"|"1010011"|"1010100"|"1010101"|"1010110"|"1010111"=> --link + datatype <= "10"; + set_exec(opcADD) <= '1'; --for displacement + set_exec(Regwrena) <= '1'; + set(no_Flags) <= '1'; + IF decodeOPC='1' THEN + next_micro_state <= link1; + set(presub) <= '1'; + setstackaddr <='1'; + set(mem_addsub) <= '1'; + source_lowbits <= '1'; + source_areg <= '1'; + set(store_ea_data) <= '1'; + END IF; + + WHEN "1011000"|"1011001"|"1011010"|"1011011"|"1011100"|"1011101"|"1011110"|"1011111" => --unlink + datatype <= "10"; + set_exec(Regwrena) <= '1'; + set_exec(opcMOVE) <= '1'; + set(no_Flags) <= '1'; + IF decodeOPC='1' THEN + setstate <= "01"; + next_micro_state <= unlink1; + set(opcMOVE) <= '1'; + set(Regwrena) <= '1'; + setstackaddr <='1'; + source_lowbits <= '1'; + source_areg <= '1'; + END IF; + + WHEN "1100000"|"1100001"|"1100010"|"1100011"|"1100100"|"1100101"|"1100110"|"1100111" => --move An,USP + IF SVmode='1' THEN +-- set(no_Flags) <= '1'; + set(to_USP) <= '1'; + source_lowbits <= '1'; + source_areg <= '1'; + datatype <= "10"; + ELSE + trap_priv <= '1'; + trapmake <= '1'; + END IF; + WHEN "1101000"|"1101001"|"1101010"|"1101011"|"1101100"|"1101101"|"1101110"|"1101111" => --move USP,An + IF SVmode='1' THEN +-- set(no_Flags) <= '1'; + set(from_USP) <= '1'; + datatype <= "10"; + set_exec(Regwrena) <= '1'; + ELSE + trap_priv <= '1'; + trapmake <= '1'; + END IF; + + WHEN "1110000" => --reset + IF SVmode='0' THEN + trap_priv <= '1'; + trapmake <= '1'; + ELSE + set(opcRESET) <= '1'; + IF decodeOPC='1' THEN + set(ld_rot_cnt) <= '1'; + set_rot_cnt <= "000000"; + END IF; + END IF; + + WHEN "1110001" => --nop + + WHEN "1110010" => --stop + IF SVmode='0' THEN + trap_priv <= '1'; + trapmake <= '1'; + ELSE + IF decodeOPC='1' THEN + setnextpass <= '1'; + set_stop <= '1'; + END IF; + IF stop='1' THEN + skipFetch <= '1'; + END IF; + + END IF; + + WHEN "1110011"|"1110111" => --rte/rtr + IF SVmode='1' OR opcode(2)='1' THEN + IF decodeOPC='1' THEN + setstate <= "10"; + set(postadd) <= '1'; + setstackaddr <= '1'; + IF opcode(2)='1' THEN + set(directCCR) <= '1'; + ELSE + set(directSR) <= '1'; + END IF; + next_micro_state <= rte1; + END IF; + ELSE + trap_priv <= '1'; + trapmake <= '1'; + END IF; + + WHEN "1110101" => --rts + datatype <= "10"; + IF decodeOPC='1' THEN + setstate <= "10"; + set(postadd) <= '1'; + setstackaddr <= '1'; + set(direct_delta) <= '1'; + set(directPC) <= '1'; + next_micro_state <= nopnop; + END IF; + + WHEN "1110110" => --trapv + IF decodeOPC='1' THEN + setstate <= "01"; + END IF; + IF Flags(1)='1' AND state="01" THEN + trap_trapv <= '1'; + trapmake <= '1'; + END IF; + + WHEN "1111010"|"1111011" => --movec + IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN + trap_illegal <= '1'; + trapmake <= '1'; + ELSIF SVmode='0' THEN + trap_priv <= '1'; + trapmake <= '1'; + ELSE + datatype <= "10"; --Long + IF last_data_read(11 downto 0)=X"800" THEN + set(from_USP) <= '1'; + IF opcode(0)='1' THEN + set(to_USP) <= '1'; + END IF; + END IF; + IF opcode(0)='0' THEN + set_exec(movec_rd) <= '1'; + ELSE + set_exec(movec_wr) <= '1'; + END IF; + IF decodeOPC='1' THEN + next_micro_state <= movec1; + getbrief <='1'; + END IF; + END IF; + + WHEN OTHERS => + trap_illegal <= '1'; + trapmake <= '1'; + END CASE; + END IF; + WHEN OTHERS => NULL; + END CASE; + END IF; +-- +---- 0101 ---------------------------------------------------------------------------- + WHEN "0101" => --subq, addq + + IF opcode(7 downto 6)="11" THEN --dbcc + IF opcode(5 downto 3)="001" THEN --dbcc + IF decodeOPC='1' THEN + next_micro_state <= dbcc1; + set(OP2out_one) <= '1'; + data_is_source <= '1'; + END IF; + ELSE --Scc + datatype <= "00"; --Byte + ea_build_now <= '1'; + write_back <= '1'; + set_exec(opcScc) <= '1'; + IF cpu(0)='1' AND state="10" THEN + skipFetch <= '1'; + END IF; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + END IF; + ELSE --addq, subq + ea_build_now <= '1'; + IF opcode(5 downto 3)="001" THEN + set(no_Flags) <= '1'; + END IF; + IF opcode(8)='1' THEN + set(addsub) <= '1'; + END IF; + write_back <= '1'; + set_exec(opcADDQ) <= '1'; + set_exec(opcADD) <= '1'; + set_exec(ea_data_OP1) <= '1'; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + END IF; +-- +---- 0110 ---------------------------------------------------------------------------- + WHEN "0110" => --bra,bsr,bcc + datatype <= "10"; + + IF micro_state=idle THEN + IF opcode(11 downto 8)="0001" THEN --bsr + set(presub) <= '1'; + setstackaddr <='1'; + IF opcode(7 downto 0)="11111111" THEN + next_micro_state <= bsr2; + set(longaktion) <= '1'; + ELSIF opcode(7 downto 0)="00000000" THEN + next_micro_state <= bsr2; + ELSE + next_micro_state <= bsr1; + setstate <= "11"; + writePC <= '1'; + END IF; + ELSE --bra + IF opcode(7 downto 0)="11111111" THEN + next_micro_state <= bra1; + set(longaktion) <= '1'; + ELSIF opcode(7 downto 0)="00000000" THEN + next_micro_state <= bra1; + ELSE + setstate <= "01"; + next_micro_state <= bra1; + END IF; + END IF; + END IF; + +-- 0111 ---------------------------------------------------------------------------- + WHEN "0111" => --moveq +-- IF opcode(8)='0' THEN -- Cloanto's Amiga Forver ROMs have mangled moveq instructions with a 1 here... + datatype <= "10"; --Long + set_exec(Regwrena) <= '1'; + set_exec(opcMOVEQ) <= '1'; + set_exec(opcMOVE) <= '1'; + dest_hbits <= '1'; +-- ELSE +-- trap_illegal <= '1'; +-- trapmake <= '1'; +-- END IF; + +---- 1000 ---------------------------------------------------------------------------- + WHEN "1000" => --or + IF opcode(7 downto 6)="11" THEN --divu, divs + IF DIV_Mode/=3 THEN + IF opcode(5 downto 4)="00" THEN --Dn, An + regdirectsource <= '1'; + END IF; + IF (micro_state=idle AND nextpass='1') OR (opcode(5 downto 4)="00" AND decodeOPC='1') THEN + setstate <="01"; + next_micro_state <= div1; + END IF; + ea_build_now <= '1'; + IF z_error='0' AND set_V_Flag='0' THEN + set_exec(Regwrena) <= '1'; + END IF; + source_lowbits <='1'; + IF nextpass='1' OR (opcode(5 downto 4)="00" AND decodeOPC='1') THEN + dest_hbits <= '1'; + END IF; + datatype <= "01"; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + + ELSIF opcode(8)='1' AND opcode(5 downto 4)="00" THEN --sbcd, pack , unpack + IF opcode(7 downto 6)="00" THEN --sbcd + build_bcd <= '1'; + set_exec(opcADD) <= '1'; + set_exec(opcSBCD) <= '1'; + ELSIF cpu(1)='1' AND (opcode(7 downto 6)="01" OR opcode(7 downto 6)="10") THEN --pack, unpack + datatype <= "01"; --Word + set_exec(opcPACK) <= '1'; + set(no_Flags) <= '1'; -- this command modifies no flags + + -- immediate value is kept in op1 + -- source value is in op2 + + -- xyz + if opcode(3)='0' then -- R/M bit = 0 -> Dy->Dy, 1 -(Ax),-(Ay) + dest_hbits <='1'; -- dest register is encoded in bits 9-11 + source_lowbits <= '1'; -- source register is encoded in bits 0-2 + + set_exec(Regwrena) <= '1'; -- write result into register + set_exec(ea_data_OP1) <= '1'; -- immediate value goes into op2 + set(hold_dwr) <= '1'; + + -- pack writes a byte only + IF opcode(7 downto 6) = "01" THEN + datatype <= "00"; --Byte + ELSE + datatype <= "01"; --Word + END IF; + + IF decodeOPC='1' THEN + next_micro_state <= nop; + set_direct_data <= '1'; + END IF; + else + set_exec(ea_data_OP1) <= '1'; + source_lowbits <= '1'; -- source register is encoded in bits 0-2 + + IF decodeOPC='1' THEN + -- first step: read source value + IF opcode(7 downto 6) = "10" THEN -- UNPK reads a byte + datatype <= "00"; -- Byte + END IF; + set_direct_data <= '1'; + setstate <= "10"; + set(update_ld) <= '1'; + set(presub) <= '1'; + next_micro_state <= pack1; + dest_areg <= '1'; --??? + end IF; + end IF; + + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + ELSE --or + set_exec(opcOR) <= '1'; + build_logical <= '1'; + END IF; + +---- 1001, 1101 ----------------------------------------------------------------------- + WHEN "1001"|"1101" => --sub, add + set_exec(opcADD) <= '1'; + ea_build_now <= '1'; + IF opcode(14)='0' THEN + set(addsub) <= '1'; + END IF; + IF opcode(7 downto 6)="11" THEN -- --adda, suba + IF opcode(8)='0' THEN --adda.w, suba.w + datatype <= "01"; --Word + END IF; + set_exec(Regwrena) <= '1'; + source_lowbits <='1'; + IF opcode(3)='1' THEN + source_areg <= '1'; + END IF; + set(no_Flags) <= '1'; + IF setexecOPC='1' THEN + dest_areg <='1'; + dest_hbits <= '1'; + END IF; + ELSE + IF opcode(8)='1' AND opcode(5 downto 4)="00" THEN --addx, subx + build_bcd <= '1'; + ELSE --sub, add + build_logical <= '1'; + END IF; + END IF; + +-- +---- 1010 ---------------------------------------------------------------------------- + WHEN "1010" => --Trap 1010 + trap_1010 <= '1'; + trapmake <= '1'; +---- 1011 ---------------------------------------------------------------------------- + WHEN "1011" => --eor, cmp + ea_build_now <= '1'; + IF opcode(7 downto 6)="11" THEN --CMPA + IF opcode(8)='0' THEN --cmpa.w + datatype <= "01"; --Word + set_exec(opcCPMAW) <= '1'; + END IF; + set_exec(opcCMP) <= '1'; + IF setexecOPC='1' THEN + source_lowbits <='1'; + IF opcode(3)='1' THEN + source_areg <= '1'; + END IF; + dest_areg <='1'; + dest_hbits <= '1'; + END IF; + set(addsub) <= '1'; + ELSE + IF opcode(8)='1' THEN + IF opcode(5 downto 3)="001" THEN --cmpm + set_exec(opcCMP) <= '1'; + IF decodeOPC='1' THEN + setstate <= "10"; + set(update_ld) <= '1'; + set(postadd) <= '1'; + next_micro_state <= cmpm; + END IF; + set_exec(ea_data_OP1) <= '1'; + set(addsub) <= '1'; + ELSE --EOR + build_logical <= '1'; + set_exec(opcEOR) <= '1'; + END IF; + ELSE --CMP + build_logical <= '1'; + set_exec(opcCMP) <= '1'; + set(addsub) <= '1'; + END IF; + END IF; +-- +---- 1100 ---------------------------------------------------------------------------- + WHEN "1100" => --and, exg + IF opcode(7 downto 6)="11" THEN --mulu, muls + IF MUL_Mode/=3 THEN + IF opcode(5 downto 4)="00" THEN --Dn, An + regdirectsource <= '1'; + END IF; + IF (micro_state=idle AND nextpass='1') OR (opcode(5 downto 4)="00" AND decodeOPC='1') THEN + setstate <="01"; + set(ld_rot_cnt) <= '1'; + next_micro_state <= mul1; + END IF; + ea_build_now <= '1'; + set_exec(Regwrena) <= '1'; + source_lowbits <='1'; + IF (nextpass='1') OR (opcode(5 downto 4)="00" AND decodeOPC='1') THEN + dest_hbits <= '1'; + END IF; + datatype <= "01"; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + + ELSIF opcode(8)='1' AND opcode(5 downto 4)="00" THEN --exg, abcd + IF opcode(7 downto 6)="00" THEN --abcd + build_bcd <= '1'; + set_exec(opcADD) <= '1'; + set_exec(opcABCD) <= '1'; + ELSE --exg + datatype <= "10"; + set(Regwrena) <= '1'; + set(exg) <= '1'; + IF opcode(6)='1' AND opcode(3)='1' THEN + dest_areg <= '1'; + source_areg <= '1'; + END IF; + IF decodeOPC='1' THEN + setstate <= "01"; + ELSE + dest_hbits <= '1'; + END IF; + END IF; + ELSE --and + set_exec(opcAND) <= '1'; + build_logical <= '1'; + END IF; +-- +---- 1110 ---------------------------------------------------------------------------- + WHEN "1110" => --rotation / bitfield + IF opcode(7 downto 6)="11" THEN + IF opcode(11)='0' THEN + set_exec(opcROT) <= '1'; + ea_build_now <= '1'; + datatype <= "01"; + set_rot_bits <= opcode(10 downto 9); + set_exec(ea_data_OP1) <= '1'; + write_back <= '1'; + ELSE --bitfield + IF BitField=0 OR (cpu(1)='0' AND BitField=2) THEN + trap_illegal <= '1'; + trapmake <= '1'; + ELSE + IF decodeOPC='1' THEN + next_micro_state <= nop; + set(get_2ndOPC) <= '1'; + set(ea_build) <= '1'; + END IF; + set_exec(opcBF) <= '1'; + IF opcode(10)='1' OR opcode(8)='0' THEN + set_exec(opcBFwb) <= '1'; +-- END IF; +-- IF opcode(10 downto 8)="111" THEN + set_exec(ea_data_OP1) <= '1'; + END IF; + IF opcode(10 downto 8)="010" OR opcode(10 downto 8)="100" OR opcode(10 downto 8)="110" OR opcode(10 downto 8)="111" THEN + write_back <= '1'; + END IF; + ea_only <= '1'; + IF opcode(10 downto 8)="001" OR opcode(10 downto 8)="011" OR opcode(10 downto 8)="101" THEN + set_exec(Regwrena) <= '1'; + END IF; + IF opcode(4 downto 3)="00" THEN + set_exec(Regwrena) <= '1'; + IF exec(ea_build)='1' THEN + dest_2ndHbits <= '1'; + source_2ndLbits <= '1'; + set(get_bfoffset) <='1'; + setstate <= "01"; + END IF; + END IF; + IF set(get_ea_now)='1' THEN + setstate <= "01"; + END IF; + IF exec(get_ea_now)='1' THEN + dest_2ndHbits <= '1'; + source_2ndLbits <= '1'; + set(get_bfoffset) <='1'; + setstate <= "01"; + set(mem_addsub) <='1'; + next_micro_state <= bf1; + END IF; + +-- BFINS D1,D0 s2ndHbits < D0 +-- BFEXT D0,D1 sLbits >>D0 -> D1 d2ndHbits +-- BFINS D1,(A0) s2ndHbits < (A0) +-- BFEXT (A0),D1 >>(A0) -> D1 d2ndHbits + IF setexecOPC='1' THEN + IF opcode(10 downto 8)="111" THEN --BFINS + source_2ndHbits <= '1'; + ELSE + source_lowbits <= '1'; + dest_2ndHbits <= '1'; + END IF; + END IF; + END IF; + END IF; + ELSE + set_exec(opcROT) <= '1'; + set_rot_bits <= opcode(4 downto 3); + data_is_source <= '1'; + set_exec(Regwrena) <= '1'; + IF decodeOPC='1' THEN + IF opcode(5)='1' THEN + next_micro_state <= rota1; + set(ld_rot_cnt) <= '1'; + setstate <= "01"; + ELSE + set_rot_cnt(2 downto 0) <= opcode(11 downto 9); + IF opcode(11 downto 9)="000" THEN + set_rot_cnt(3) <='1'; + ELSE + set_rot_cnt(3) <='0'; + END IF; + END IF; + END IF; + END IF; +-- +---- ---------------------------------------------------------------------------- + WHEN OTHERS => + trap_1111 <= '1'; + trapmake <= '1'; + + END CASE; + +-- use for AND, OR, EOR, CMP + IF build_logical='1' THEN + ea_build_now <= '1'; + IF set_exec(opcCMP)='0' AND (opcode(8)='0' OR opcode(5 downto 4)="00" ) THEN + set_exec(Regwrena) <= '1'; + END IF; + IF opcode(8)='1' THEN + write_back <= '1'; + set_exec(ea_data_OP1) <= '1'; + ELSE + source_lowbits <='1'; + IF opcode(3)='1' THEN --use for cmp + source_areg <= '1'; + END IF; + IF setexecOPC='1' THEN + dest_hbits <= '1'; + END IF; + END IF; + END IF; + +-- use for ABCD, SBCD + IF build_bcd='1' THEN + set_exec(use_XZFlag) <= '1'; + set_exec(ea_data_OP1) <= '1'; + write_back <= '1'; + source_lowbits <='1'; + IF opcode(3)='1' THEN + IF decodeOPC='1' THEN + setstate <= "10"; + set(update_ld) <= '1'; + set(presub) <= '1'; + next_micro_state <= op_AxAy; + dest_areg <= '1'; --??? + END IF; + ELSE + dest_hbits <= '1'; + set_exec(Regwrena) <= '1'; + END IF; + END IF; + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ + IF set_Z_error='1' THEN -- divu by zero + trapmake <= '1'; --wichtig for USP + IF trapd='0' THEN + writePC <= '1'; + END IF; + END IF; + +----------------------------------------------------------------------------- +-- execute microcode +----------------------------------------------------------------------------- + IF rising_edge(clk) THEN + IF Reset='1' THEN + micro_state <= ld_nn; + ELSIF clkena_lw='1' THEN + trapd <= trapmake; + micro_state <= next_micro_state; + END IF; + END IF; + + CASE micro_state IS + WHEN ld_nn => -- (nnnn).w/l=> + set(get_ea_now) <='1'; + setnextpass <= '1'; + set(addrlong) <= '1'; + + WHEN st_nn => -- =>(nnnn).w/l + setstate <= "11"; + set(addrlong) <= '1'; + next_micro_state <= nop; + + WHEN ld_dAn1 => -- d(An)=>, --d(PC)=> + set(get_ea_now) <='1'; + setdisp <= '1'; --word + setnextpass <= '1'; + + WHEN ld_AnXn1 => -- d(An,Xn)=>, --d(PC,Xn)=> + IF brief(8)='0' OR extAddr_Mode=0 OR (cpu(1)='0' AND extAddr_Mode=2) THEN + setdisp <= '1'; --byte + setdispbyte <= '1'; + setstate <= "01"; + set(briefext) <= '1'; + next_micro_state <= ld_AnXn2; + ELSE + IF brief(7)='1'THEN --suppress Base + set_suppress_base <= '1'; + ELSIF exec(dispouter)='1' THEN + set(dispouter) <= '1'; + END IF; + IF brief(5)='0' THEN --NULL Base Displacement + setstate <= "01"; + ELSE --WORD Base Displacement + IF brief(4)='1' THEN + set(longaktion) <= '1'; --LONG Base Displacement + END IF; + END IF; + next_micro_state <= ld_229_1; + END IF; + + WHEN ld_AnXn2 => + set(get_ea_now) <='1'; + setdisp <= '1'; --brief + setnextpass <= '1'; + +------------------------------------------------------------------------------------- + + WHEN ld_229_1 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + IF brief(5)='1' THEN --Base Displacement + setdisp <= '1'; --add last_data_read + END IF; + IF brief(6)='0' AND brief(2)='0' THEN --Preindex or Index + set(briefext) <= '1'; + setstate <= "01"; + IF brief(1 downto 0)="00" THEN + next_micro_state <= ld_AnXn2; + ELSE + next_micro_state <= ld_229_2; + END IF; + ELSE + IF brief(1 downto 0)="00" THEN + set(get_ea_now) <='1'; + setnextpass <= '1'; + ELSE + setstate <= "10"; + set(longaktion) <= '1'; + next_micro_state <= ld_229_3; + END IF; + END IF; + + WHEN ld_229_2 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + setdisp <= '1'; -- add Index + setstate <= "10"; + set(longaktion) <= '1'; + next_micro_state <= ld_229_3; + + WHEN ld_229_3 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + set_suppress_base <= '1'; + set(dispouter) <= '1'; + IF brief(1)='0' THEN --NULL Outer Displacement + setstate <= "01"; + ELSE --WORD Outer Displacement + IF brief(0)='1' THEN + set(longaktion) <= '1'; --LONG Outer Displacement + END IF; + END IF; + next_micro_state <= ld_229_4; + + WHEN ld_229_4 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + IF brief(1)='1' THEN -- Outer Displacement + setdisp <= '1'; --add last_data_read + END IF; + IF brief(6)='0' AND brief(2)='1' THEN --Postindex + set(briefext) <= '1'; + setstate <= "01"; + next_micro_state <= ld_AnXn2; + ELSE + set(get_ea_now) <='1'; + setnextpass <= '1'; + END IF; + +---------------------------------------------------------------------------------------- + WHEN st_dAn1 => -- =>d(An) + setstate <= "11"; + setdisp <= '1'; --word + next_micro_state <= nop; + + WHEN st_AnXn1 => -- =>d(An,Xn) + IF brief(8)='0' OR extAddr_Mode=0 OR (cpu(1)='0' AND extAddr_Mode=2) THEN + setdisp <= '1'; --byte + setdispbyte <= '1'; + setstate <= "01"; + set(briefext) <= '1'; + next_micro_state <= st_AnXn2; + ELSE + IF brief(7)='1'THEN --suppress Base + set_suppress_base <= '1'; +-- ELSIF exec(dispouter)='1' THEN +-- set(dispouter) <= '1'; + END IF; + IF brief(5)='0' THEN --NULL Base Displacement + setstate <= "01"; + ELSE --WORD Base Displacement + IF brief(4)='1' THEN + set(longaktion) <= '1'; --LONG Base Displacement + END IF; + END IF; + next_micro_state <= st_229_1; + END IF; + + WHEN st_AnXn2 => + setstate <= "11"; + setdisp <= '1'; --brief + next_micro_state <= nop; + +------------------------------------------------------------------------------------- + + WHEN st_229_1 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + IF brief(5)='1' THEN --Base Displacement + setdisp <= '1'; --add last_data_read + END IF; + IF brief(6)='0' AND brief(2)='0' THEN --Preindex or Index + set(briefext) <= '1'; + setstate <= "01"; + IF brief(1 downto 0)="00" THEN + next_micro_state <= st_AnXn2; + ELSE + next_micro_state <= st_229_2; + END IF; + ELSE + IF brief(1 downto 0)="00" THEN + setstate <= "11"; + next_micro_state <= nop; + ELSE + set(hold_dwr) <= '1'; + setstate <= "10"; + set(longaktion) <= '1'; + next_micro_state <= st_229_3; + END IF; + END IF; + + WHEN st_229_2 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + setdisp <= '1'; -- add Index + set(hold_dwr) <= '1'; + setstate <= "10"; + set(longaktion) <= '1'; + next_micro_state <= st_229_3; + + WHEN st_229_3 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + set(hold_dwr) <= '1'; + set_suppress_base <= '1'; + set(dispouter) <= '1'; + IF brief(1)='0' THEN --NULL Outer Displacement + setstate <= "01"; + ELSE --WORD Outer Displacement + IF brief(0)='1' THEN + set(longaktion) <= '1'; --LONG Outer Displacement + END IF; + END IF; + next_micro_state <= st_229_4; + + WHEN st_229_4 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + set(hold_dwr) <= '1'; + IF brief(1)='1' THEN -- Outer Displacement + setdisp <= '1'; --add last_data_read + END IF; + IF brief(6)='0' AND brief(2)='1' THEN --Postindex + set(briefext) <= '1'; + setstate <= "01"; + next_micro_state <= st_AnXn2; + ELSE + setstate <= "11"; + next_micro_state <= nop; + END IF; + +---------------------------------------------------------------------------------------- + WHEN bra1 => --bra + IF exe_condition='1' THEN + TG68_PC_brw <= '1'; --pc+0000 + next_micro_state <= nop; + skipFetch <= '1'; + END IF; + + WHEN bsr1 => --bsr short + TG68_PC_brw <= '1'; + next_micro_state <= nop; + + WHEN bsr2 => --bsr + IF long_start='0' THEN + TG68_PC_brw <= '1'; + END IF; + skipFetch <= '1'; + set(longaktion) <= '1'; + writePC <= '1'; + setstate <= "11"; + next_micro_state <= nopnop; + setstackaddr <='1'; + WHEN nopnop => --bsr + next_micro_state <= nop; + + WHEN dbcc1 => --dbcc + IF exe_condition='0' THEN + Regwrena_now <= '1'; + IF c_out(1)='1' THEN + skipFetch <= '1'; + next_micro_state <= nop; + TG68_PC_brw <= '1'; + END IF; + END IF; + + WHEN movem1 => --movem + IF last_data_read(15 downto 0)/=X"0000" THEN + setstate <="01"; + IF opcode(5 downto 3)="100" THEN + set(mem_addsub) <= '1'; + END IF; + next_micro_state <= movem2; + END IF; + WHEN movem2 => --movem + IF movem_run='0' THEN + setstate <="01"; + ELSE + set(movem_action) <= '1'; + set(mem_addsub) <= '1'; + next_micro_state <= movem2; + IF opcode(10)='0' THEN + setstate <="11"; + set(write_reg) <= '1'; + ELSE + setstate <="10"; + END IF; + END IF; + + WHEN andi => --andi + IF opcode(5 downto 4)/="00" THEN + setnextpass <= '1'; + END IF; + + WHEN op_AxAy => -- op -(Ax),-(Ay) + set_direct_data <= '1'; + set(presub) <= '1'; + dest_hbits <= '1'; + dest_areg <= '1'; + setstate <= "10"; + + WHEN cmpm => -- cmpm (Ay)+,(Ax)+ + set_direct_data <= '1'; + set(postadd) <= '1'; + dest_hbits <= '1'; + dest_areg <= '1'; + setstate <= "10"; + + WHEN link1 => -- link + setstate <="11"; + source_areg <= '1'; + set(opcMOVE) <= '1'; + set(Regwrena) <= '1'; + next_micro_state <= link2; + WHEN link2 => -- link + setstackaddr <='1'; + set(ea_data_OP2) <= '1'; + + WHEN unlink1 => -- unlink + setstate <="10"; + setstackaddr <='1'; + set(postadd) <= '1'; + next_micro_state <= unlink2; + WHEN unlink2 => -- unlink + set(ea_data_OP2) <= '1'; + + WHEN trap0 => -- TRAP + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + IF VBR_Stackframe=1 OR (cpu(0)='1' AND VBR_Stackframe=2) THEN --68010 + set(writePC_add) <= '1'; + datatype <= "01"; +-- set_datatype <= "10"; + next_micro_state <= trap1; + ELSE + IF trap_interrupt='1' OR trap_trace='1' OR trap_berr='1' THEN + writePC <= '1'; + END IF; + datatype <= "10"; + next_micro_state <= trap2; + END IF; + WHEN trap1 => -- TRAP + IF trap_interrupt='1' OR trap_trace='1' THEN + writePC <= '1'; + END IF; + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + datatype <= "10"; + next_micro_state <= trap2; + WHEN trap2 => -- TRAP + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + datatype <= "01"; + writeSR <= '1'; + IF trap_berr='1' THEN + next_micro_state <= trap4; + ELSE + next_micro_state <= trap3; + END IF; + WHEN trap3 => -- TRAP + set_vectoraddr <= '1'; + datatype <= "10"; + set(direct_delta) <= '1'; + set(directPC) <= '1'; + setstate <= "10"; + next_micro_state <= nopnop; + + WHEN trap4 => -- TRAP + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + datatype <= "01"; + writeSR <= '1'; + next_micro_state <= trap5; + WHEN trap5 => -- TRAP + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + datatype <= "10"; + writeSR <= '1'; + next_micro_state <= trap6; + WHEN trap6 => -- TRAP + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + datatype <= "01"; + writeSR <= '1'; + next_micro_state <= trap3; + + WHEN rte1 => -- RTE + datatype <= "10"; + setstate <= "10"; + set(postadd) <= '1'; + setstackaddr <= '1'; + IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN + set(direct_delta) <= '1'; + END IF; + set(directPC) <= '1'; + next_micro_state <= rte2; + WHEN rte2 => -- RTE + datatype <= "01"; + set(update_FC) <= '1'; + IF VBR_Stackframe=1 OR (cpu(0)='1' AND VBR_Stackframe=2) THEN + setstate <= "10"; + set(postadd) <= '1'; + setstackaddr <= '1'; + next_micro_state <= rte3; + ELSE + next_micro_state <= nop; + END IF; + WHEN rte3 => -- RTE + next_micro_state <= nop; +-- set(update_FC) <= '1'; + + WHEN movec1 => -- MOVEC + set(briefext) <= '1'; + set_writePCbig <='1'; + IF (brief(11 downto 0)=X"000" OR brief(11 downto 0)=X"001" OR brief(11 downto 0)=X"800" OR brief(11 downto 0)=X"801") OR + (cpu(1)='1' AND (brief(11 downto 0)=X"002" OR brief(11 downto 0)=X"802" OR brief(11 downto 0)=X"803" OR brief(11 downto 0)=X"804")) THEN + IF opcode(0)='0' THEN + set(Regwrena) <= '1'; + END IF; +-- ELSIF brief(11 downto 0)=X"800"OR brief(11 downto 0)=X"001" OR brief(11 downto 0)=X"000" THEN +-- trap_addr_error <= '1'; +-- trapmake <= '1'; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + + WHEN movep1 => -- MOVEP d(An) + setdisp <= '1'; + set(mem_addsub) <= '1'; + set(mem_byte) <= '1'; + set(OP1addr) <= '1'; + IF opcode(6)='1' THEN + set(movepl) <= '1'; + END IF; + IF opcode(7)='0' THEN + setstate <= "10"; + ELSE + setstate <= "11"; + END IF; + next_micro_state <= movep2; + WHEN movep2 => + IF opcode(6)='1' THEN + set(mem_addsub) <= '1'; + set(OP1addr) <= '1'; + END IF; + IF opcode(7)='0' THEN + setstate <= "10"; + ELSE + setstate <= "11"; + END IF; + next_micro_state <= movep3; + WHEN movep3 => + IF opcode(6)='1' THEN + set(mem_addsub) <= '1'; + set(OP1addr) <= '1'; + set(mem_byte) <= '1'; + IF opcode(7)='0' THEN + setstate <= "10"; + ELSE + setstate <= "11"; + END IF; + next_micro_state <= movep4; + ELSE + datatype <= "01"; --Word + END IF; + WHEN movep4 => + IF opcode(7)='0' THEN + setstate <= "10"; + ELSE + setstate <= "11"; + END IF; + next_micro_state <= movep5; + WHEN movep5 => + datatype <= "10"; --Long + + WHEN mul1 => -- mulu + IF opcode(15)='1' OR MUL_Mode=0 THEN + set_rot_cnt <= "001110"; + ELSE + set_rot_cnt <= "011110"; + END IF; + setstate <="01"; + next_micro_state <= mul2; + WHEN mul2 => -- mulu + setstate <="01"; + IF rot_cnt="00001" THEN + next_micro_state <= mul_end1; + ELSE + next_micro_state <= mul2; + END IF; + WHEN mul_end1 => -- mulu + datatype <= "10"; + set(opcMULU) <= '1'; + IF opcode(15)='0' AND (MUL_Mode=1 OR MUL_Mode=2) THEN + dest_2ndHbits <= '1'; + source_2ndLbits <= '1';--??? + set(write_lowlong) <= '1'; + IF sndOPC(10)='1' THEN + setstate <="01"; + next_micro_state <= mul_end2; + END IF; + set(Regwrena) <= '1'; + END IF; + datatype <= "10"; + WHEN mul_end2 => -- divu + set(write_reminder) <= '1'; + set(Regwrena) <= '1'; + set(opcMULU) <= '1'; + + WHEN div1 => -- divu + setstate <="01"; + next_micro_state <= div2; + WHEN div2 => -- divu + IF (OP2out(31 downto 16)=x"0000" OR opcode(15)='1' OR DIV_Mode=0) AND OP2out(15 downto 0)=x"0000" THEN --div zero + set_Z_error <= '1'; + ELSE + next_micro_state <= div3; + END IF; + set(ld_rot_cnt) <= '1'; + setstate <="01"; + WHEN div3 => -- divu + IF opcode(15)='1' OR DIV_Mode=0 THEN + set_rot_cnt <= "001101"; + ELSE + set_rot_cnt <= "011101"; + END IF; + setstate <="01"; + next_micro_state <= div4; + WHEN div4 => -- divu + setstate <="01"; + IF rot_cnt="00001" THEN + next_micro_state <= div_end1; + ELSE + next_micro_state <= div4; + END IF; + WHEN div_end1 => -- divu + IF opcode(15)='0' AND (DIV_Mode=1 OR DIV_Mode=2) THEN + set(write_reminder) <= '1'; + next_micro_state <= div_end2; + setstate <="01"; + END IF; + set(opcDIVU) <= '1'; + datatype <= "10"; + WHEN div_end2 => -- divu + dest_2ndHbits <= '1'; + source_2ndLbits <= '1';--??? + set(opcDIVU) <= '1'; + + WHEN rota1 => + IF OP2out(5 downto 0)/="000000" THEN + set_rot_cnt <= OP2out(5 downto 0); + ELSE + set_exec(rot_nop) <= '1'; + END IF; + + WHEN bf1 => + setstate <="10"; + + when pack1 => + -- result computation + IF opcode(7 downto 6) = "10" THEN -- UNPK reads a byte + datatype <= "00"; -- Byte + END IF; + set(ea_data_OP2) <= '1'; + set(opcPACK) <= '1'; + next_micro_state <= pack2; + + when pack2 => + -- write result + IF opcode(7 downto 6) = "01" THEN -- PACK writes a byte + datatype <= "00"; + END IF; + set(presub) <= '1'; + setstate <= "11"; + dest_hbits <= '1'; + dest_areg <= '1'; + next_micro_state <= pack3; + + when pack3 => + -- this is just to keep datatype == 00 + -- for byte writes + -- write result + IF opcode(7 downto 6) = "01" THEN -- PACK writes a byte + datatype <= "00"; + END IF; + + WHEN OTHERS => NULL; + END CASE; + END PROCESS; + +----------------------------------------------------------------------------- +-- MOVEC +----------------------------------------------------------------------------- +PROCESS (clk, VBR, CACR, brief) + BEGIN + IF rising_edge(clk) THEN + IF Reset = '1' THEN + VBR <= (OTHERS => '0'); + CACR <= (OTHERS => '0'); + ELSIF clkena_lw='1' AND exec(movec_wr)='1' THEN + CASE brief(11 downto 0) IS + WHEN X"002" => CACR <= reg_QA(3 downto 0); + WHEN X"801" => VBR <= reg_QA; + WHEN OTHERS => NULL; + END CASE; + END IF; + END IF; + movec_data <= (OTHERS=>'0'); + CASE brief(11 downto 0) IS + WHEN X"002" => movec_data(3 downto 0) <= CACR; + WHEN X"801" => --IF VBR_Stackframe=1 OR (cpu(0)='1' AND VBR_Stackframe=2) THEN + movec_data <= VBR; + --END IF; + WHEN OTHERS => NULL; + END CASE; + END PROCESS; + +----------------------------------------------------------------------------- +-- Conditions +----------------------------------------------------------------------------- +PROCESS (exe_opcode, Flags) + BEGIN + CASE exe_opcode(11 downto 8) IS + WHEN X"0" => exe_condition <= '1'; + WHEN X"1" => exe_condition <= '0'; + WHEN X"2" => exe_condition <= NOT Flags(0) AND NOT Flags(2); + WHEN X"3" => exe_condition <= Flags(0) OR Flags(2); + WHEN X"4" => exe_condition <= NOT Flags(0); + WHEN X"5" => exe_condition <= Flags(0); + WHEN X"6" => exe_condition <= NOT Flags(2); + WHEN X"7" => exe_condition <= Flags(2); + WHEN X"8" => exe_condition <= NOT Flags(1); + WHEN X"9" => exe_condition <= Flags(1); + WHEN X"a" => exe_condition <= NOT Flags(3); + WHEN X"b" => exe_condition <= Flags(3); + WHEN X"c" => exe_condition <= (Flags(3) AND Flags(1)) OR (NOT Flags(3) AND NOT Flags(1)); + WHEN X"d" => exe_condition <= (Flags(3) AND NOT Flags(1)) OR (NOT Flags(3) AND Flags(1)); + WHEN X"e" => exe_condition <= (Flags(3) AND Flags(1) AND NOT Flags(2)) OR (NOT Flags(3) AND NOT Flags(1) AND NOT Flags(2)); + WHEN X"f" => exe_condition <= (Flags(3) AND NOT Flags(1)) OR (NOT Flags(3) AND Flags(1)) OR Flags(2); + WHEN OTHERS => NULL; + END CASE; + END PROCESS; + +----------------------------------------------------------------------------- +-- Movem +----------------------------------------------------------------------------- +PROCESS (clk) + BEGIN + IF rising_edge(clk) THEN + IF clkena_lw='1' THEN + movem_actiond <= exec(movem_action); + IF decodeOPC='1' THEN + sndOPC <= data_read(15 downto 0); + ELSIF exec(movem_action)='1' OR set(movem_action) ='1' THEN + CASE movem_regaddr IS + WHEN "0000" => sndOPC(0) <= '0'; + WHEN "0001" => sndOPC(1) <= '0'; + WHEN "0010" => sndOPC(2) <= '0'; + WHEN "0011" => sndOPC(3) <= '0'; + WHEN "0100" => sndOPC(4) <= '0'; + WHEN "0101" => sndOPC(5) <= '0'; + WHEN "0110" => sndOPC(6) <= '0'; + WHEN "0111" => sndOPC(7) <= '0'; + WHEN "1000" => sndOPC(8) <= '0'; + WHEN "1001" => sndOPC(9) <= '0'; + WHEN "1010" => sndOPC(10) <= '0'; + WHEN "1011" => sndOPC(11) <= '0'; + WHEN "1100" => sndOPC(12) <= '0'; + WHEN "1101" => sndOPC(13) <= '0'; + WHEN "1110" => sndOPC(14) <= '0'; + WHEN "1111" => sndOPC(15) <= '0'; + WHEN OTHERS => NULL; + END CASE; + END IF; + END IF; + END IF; + END PROCESS; + +PROCESS (sndOPC, movem_mux) + BEGIN + movem_regaddr <="0000"; + movem_run <= '1'; + IF sndOPC(3 downto 0)="0000" THEN + IF sndOPC(7 downto 4)="0000" THEN + movem_regaddr(3) <= '1'; + IF sndOPC(11 downto 8)="0000" THEN + IF sndOPC(15 downto 12)="0000" THEN + movem_run <= '0'; + END IF; + movem_regaddr(2) <= '1'; + movem_mux <= sndOPC(15 downto 12); + ELSE + movem_mux <= sndOPC(11 downto 8); + END IF; + ELSE + movem_mux <= sndOPC(7 downto 4); + movem_regaddr(2) <= '1'; + END IF; + ELSE + movem_mux <= sndOPC(3 downto 0); + END IF; + IF movem_mux(1 downto 0)="00" THEN + movem_regaddr(1) <= '1'; + IF movem_mux(2)='0' THEN + movem_regaddr(0) <= '1'; + END IF; + ELSE + IF movem_mux(0)='0' THEN + movem_regaddr(0) <= '1'; + END IF; + END IF; + END PROCESS; +END; diff --git a/tests/tg68k/orig/TG68K_ALU.vhd b/tests/tg68k/orig/TG68K_ALU.vhd new file mode 100644 index 0000000..2f6cbdd --- /dev/null +++ b/tests/tg68k/orig/TG68K_ALU.vhd @@ -0,0 +1,920 @@ +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2009-2011 Tobias Gubener -- +-- Subdesign fAMpIGA by TobiFlex -- +-- -- +-- This source file is free software: you can redistribute it and/or modify -- +-- it under the terms of the GNU General Public License as published -- +-- by the Free Software Foundation, either version 3 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- This source file is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU General Public License -- +-- along with this program. If not, see . -- +-- -- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +-- use ieee.std_logic_unsigned.all; +use IEEE.numeric_std.all; +use work.TG68K_Pack.all; + +entity TG68K_ALU is +generic( + MUL_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL, + DIV_Mode : integer := 0 --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV, + ); + port(clk : in std_logic; + Reset : in std_logic; + clkena_lw : in std_logic:='1'; + execOPC : in bit; + exe_condition : in std_logic; + exec_tas : in std_logic; + long_start : in bit; + movem_presub : in bit; + set_stop : in bit; + Z_error : in bit; + rot_bits : in std_logic_vector(1 downto 0); + exec : in bit_vector(lastOpcBit downto 0); + OP1out : in std_logic_vector(31 downto 0); + OP2out : in std_logic_vector(31 downto 0); + reg_QA : in std_logic_vector(31 downto 0); + reg_QB : in std_logic_vector(31 downto 0); + opcode : in std_logic_vector(15 downto 0); + datatype : in std_logic_vector(1 downto 0); + exe_opcode : in std_logic_vector(15 downto 0); + exe_datatype : in std_logic_vector(1 downto 0); + sndOPC : in std_logic_vector(15 downto 0); + last_data_read : in std_logic_vector(15 downto 0); + data_read : in std_logic_vector(15 downto 0); + FlagsSR : in std_logic_vector(7 downto 0); + micro_state : in micro_states; + bf_ext_in : in std_logic_vector(7 downto 0); + bf_ext_out : out std_logic_vector(7 downto 0); + bf_shift : in std_logic_vector(5 downto 0); + bf_width : in std_logic_vector(5 downto 0); + bf_loffset : in std_logic_vector(4 downto 0); + + set_V_Flag : buffer bit; + Flags : buffer std_logic_vector(7 downto 0); + c_out : buffer std_logic_vector(2 downto 0); + addsub_q : buffer std_logic_vector(31 downto 0); + ALUout : out std_logic_vector(31 downto 0) + ); +end TG68K_ALU; + +architecture logic of TG68K_ALU is +----------------------------------------------------------------------------- +----------------------------------------------------------------------------- +-- ALU and more +----------------------------------------------------------------------------- +----------------------------------------------------------------------------- + signal OP1in : std_logic_vector(31 downto 0); + signal addsub_a : std_logic_vector(31 downto 0); + signal addsub_b : std_logic_vector(31 downto 0); + signal notaddsub_b : std_logic_vector(33 downto 0); + signal add_result : std_logic_vector(33 downto 0); + signal addsub_ofl : std_logic_vector(2 downto 0); + signal opaddsub : bit; + signal c_in : std_logic_vector(3 downto 0); + signal flag_z : std_logic_vector(2 downto 0); + signal set_Flags : std_logic_vector(3 downto 0); --NZVC + signal CCRin : std_logic_vector(7 downto 0); + + signal niba_l : std_logic_vector(5 downto 0); + signal niba_h : std_logic_vector(5 downto 0); + signal niba_lc : std_logic; + signal niba_hc : std_logic; + signal bcda_lc : std_logic; + signal bcda_hc : std_logic; + signal nibs_l : std_logic_vector(5 downto 0); + signal nibs_h : std_logic_vector(5 downto 0); + signal nibs_lc : std_logic; + signal nibs_hc : std_logic; + + signal bcd_a : std_logic_vector(8 downto 0); + signal bcd_s : std_logic_vector(8 downto 0); + signal result_mulu : std_logic_vector(63 downto 0); + signal result_div : std_logic_vector(63 downto 0); + signal set_mV_Flag : std_logic; + signal V_Flag : bit; + + signal rot_rot : std_logic; + signal rot_lsb : std_logic; + signal rot_msb : std_logic; + signal rot_X : std_logic; + signal rot_C : std_logic; + signal rot_out : std_logic_vector(31 downto 0); + signal asl_VFlag : std_logic; + signal bit_bits : std_logic_vector(1 downto 0); + signal bit_number : std_logic_vector(4 downto 0); + signal bits_out : std_logic_vector(31 downto 0); + signal one_bit_in : std_logic; + signal bchg : std_logic; + signal bset : std_logic; + + signal mulu_sign : std_logic; + signal mulu_signext : std_logic_vector(16 downto 0); + signal muls_msb : std_logic; + signal mulu_reg : std_logic_vector(63 downto 0); + signal FAsign : std_logic; + signal faktorA : std_logic_vector(31 downto 0); + signal faktorB : std_logic_vector(31 downto 0); + + signal div_reg : std_logic_vector(63 downto 0); + signal div_quot : std_logic_vector(63 downto 0); + signal div_ovl : std_logic; + signal div_neg : std_logic; + signal div_bit : std_logic; + signal div_sub : std_logic_vector(32 downto 0); + signal div_over : std_logic_vector(32 downto 0); + signal nozero : std_logic; + signal div_qsign : std_logic; + signal divisor : std_logic_vector(63 downto 0); + signal divs : std_logic; + signal signedOP : std_logic; + signal OP1_sign : std_logic; + signal OP2_sign : std_logic; + signal OP2outext : std_logic_vector(15 downto 0); + + signal in_offset : std_logic_vector(5 downto 0); +-- signal in_width : std_logic_vector(5 downto 0); + signal datareg : std_logic_vector(31 downto 0); + signal insert : std_logic_vector(31 downto 0); +-- signal bf_result : std_logic_vector(31 downto 0); +-- signal bf_offset : std_logic_vector(5 downto 0); +-- signal bf_width : std_logic_vector(5 downto 0); +-- signal bf_firstbit : std_logic_vector(5 downto 0); + signal bf_datareg : std_logic_vector(31 downto 0); +-- signal bf_out : std_logic_vector(31 downto 0); + signal result : std_logic_vector(39 downto 0); + signal result_tmp : std_logic_vector(39 downto 0); + signal sign : std_logic_vector(31 downto 0); + signal bf_set1 : std_logic_vector(39 downto 0); + signal inmux0 : std_logic_vector(39 downto 0); + signal inmux1 : std_logic_vector(39 downto 0); + signal inmux2 : std_logic_vector(39 downto 0); + signal inmux3 : std_logic_vector(31 downto 0); + signal copymux0 : std_logic_vector(39 downto 0); + signal copymux1 : std_logic_vector(39 downto 0); + signal copymux2 : std_logic_vector(39 downto 0); + signal copymux3 : std_logic_vector(31 downto 0); + signal bf_set2 : std_logic_vector(31 downto 0); +-- signal bf_set3 : std_logic_vector(31 downto 0); + signal shift : std_logic_vector(39 downto 0); + signal copy : std_logic_vector(39 downto 0); +-- signal offset : std_logic_vector(5 downto 0); +-- signal width : std_logic_vector(5 downto 0); + signal bf_firstbit : std_logic_vector(5 downto 0); + signal mux : std_logic_vector(3 downto 0); + signal bitnr : std_logic_vector(4 downto 0); + signal mask : std_logic_vector(31 downto 0); + signal bf_bset : std_logic; + signal bf_NFlag : std_logic; + signal bf_bchg : std_logic; + signal bf_ins : std_logic; + signal bf_exts : std_logic; + signal bf_fffo : std_logic; + signal bf_d32 : std_logic; + signal bf_s32 : std_logic; + signal index : std_logic_vector(4 downto 0); +-- signal i : integer range 0 to 31; +-- signal i : integer range 0 to 31; +-- signal i : std_logic_vector(5 downto 0); +BEGIN +----------------------------------------------------------------------------- +-- set OP1in +----------------------------------------------------------------------------- +PROCESS (OP2out, reg_QB, opcode, OP1out, OP1in, exe_datatype, addsub_q, execOPC, exec, + bcd_a, bcd_s, result_mulu, result_div, exe_condition, bf_shift, + Flags, FlagsSR, bits_out, exec_tas, rot_out, exe_opcode, result, bf_fffo, bf_firstbit, bf_datareg) + BEGIN + ALUout <= OP1in; + ALUout(7) <= OP1in(7) OR exec_tas; + IF exec(opcBFwb)='1' THEN + ALUout <= result(31 downto 0); + IF bf_fffo='1' THEN + ALUout <= (OTHERS =>'0'); + ALUout(5 downto 0) <= std_logic_vector(unsigned(bf_firstbit) + unsigned(bf_shift)); + END IF; + END IF; + + OP1in <= addsub_q; + IF exec(opcABCD)='1' THEN + OP1in(7 downto 0) <= bcd_a(7 downto 0); + ELSIF exec(opcSBCD)='1' THEN + OP1in(7 downto 0) <= bcd_s(7 downto 0); + ELSIF exec(opcMULU)='1' AND MUL_Mode/=3 THEN + IF exec(write_lowlong)='1' AND (MUL_Mode=1 OR MUL_Mode=2) THEN + OP1in <= result_mulu(31 downto 0); + ELSE + OP1in <= result_mulu(63 downto 32); + END IF; + ELSIF exec(opcDIVU)='1' AND DIV_Mode/=3 THEN + IF exe_opcode(15)='1' OR DIV_Mode=0 THEN +-- IF exe_opcode(15)='1' THEN + OP1in <= result_div(47 downto 32)&result_div(15 downto 0); + ELSE --64bit + IF exec(write_reminder)='1' THEN + OP1in <= result_div(63 downto 32); + ELSE + OP1in <= result_div(31 downto 0); + END IF; + END IF; + ELSIF exec(opcOR)='1' THEN + OP1in <= OP2out OR OP1out; + ELSIF exec(opcAND)='1' THEN + OP1in <= OP2out AND OP1out; + ELSIF exec(opcScc)='1' THEN + OP1in(7 downto 0) <= (others=>exe_condition); + ELSIF exec(opcEOR)='1' THEN + OP1in <= OP2out XOR OP1out; + ELSIF exec(opcMOVE)='1' OR exec(exg)='1' THEN +-- OP1in <= OP2out(31 downto 8)&(OP2out(7)OR exec_tas)&OP2out(6 downto 0); + OP1in <= OP2out; + ELSIF exec(opcROT)='1' THEN + OP1in <= rot_out; + ELSIF exec(opcSWAP)='1' THEN + OP1in <= OP1out(15 downto 0)& OP1out(31 downto 16); + ELSIF exec(opcBITS)='1' THEN + OP1in <= bits_out; + ELSIF exec(opcBF)='1' THEN + OP1in <= bf_datareg; + ELSIF exec(opcMOVESR)='1' THEN + OP1in(7 downto 0) <= Flags; + IF exe_datatype="00" THEN + OP1in(15 downto 8) <= "00000000"; + ELSE + OP1in(15 downto 8) <= FlagsSR; + END IF; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- addsub +----------------------------------------------------------------------------- +PROCESS (OP1out, OP2out, execOPC, datatype, Flags, long_start, movem_presub, exe_datatype, exec, addsub_a, addsub_b, opaddsub, + notaddsub_b, add_result, c_in, sndOPC) + BEGIN + addsub_a <= OP1out; + IF exec(get_bfoffset)='1' THEN + IF sndOPC(11)='1' THEN + addsub_a <= OP1out(31)&OP1out(31)&OP1out(31)&OP1out(31 downto 3); + ELSE + addsub_a <= "000000000000000000000000000000"&sndOPC(10 downto 9); + END IF; + END IF; + + IF exec(subidx)='1' THEN + opaddsub <= '1'; + ELSE + opaddsub <= '0'; + END IF; + + c_in(0) <='0'; + addsub_b <= OP2out; + IF execOPC='0' AND exec(OP2out_one)='0' AND exec(get_bfoffset)='0'THEN + IF long_start='0' AND datatype="00" AND exec(use_SP)='0' THEN + addsub_b <= "00000000000000000000000000000001"; + ELSIF long_start='0' AND exe_datatype="10" AND (exec(presub) OR exec(postadd) OR movem_presub)='1' THEN + IF exec(movem_action)='1' THEN + addsub_b <= "00000000000000000000000000000110"; + ELSE + addsub_b <= "00000000000000000000000000000100"; + END IF; + ELSE + addsub_b <= "00000000000000000000000000000010"; + END IF; + ELSE + IF (exec(use_XZFlag)='1' AND Flags(4)='1') OR exec(opcCHK)='1' THEN + c_in(0) <= '1'; + END IF; + opaddsub <= exec(addsub); + END IF; + + IF opaddsub='0' OR long_start='1' THEN --ADD + notaddsub_b <= '0'&addsub_b&c_in(0); + ELSE --SUB + notaddsub_b <= NOT ('0'&addsub_b&c_in(0)); + END IF; + add_result <= std_logic_vector( unsigned('0'&addsub_a¬addsub_b(0)) + unsigned(notaddsub_b)); + c_in(1) <= add_result(9) XOR addsub_a(8) XOR addsub_b(8); + c_in(2) <= add_result(17) XOR addsub_a(16) XOR addsub_b(16); + c_in(3) <= add_result(33); + addsub_q <= add_result(32 downto 1); + addsub_ofl(0) <= (c_in(1) XOR add_result(8) XOR addsub_a(7) XOR addsub_b(7)); --V Byte + addsub_ofl(1) <= (c_in(2) XOR add_result(16) XOR addsub_a(15) XOR addsub_b(15)); --V Word + addsub_ofl(2) <= (c_in(3) XOR add_result(32) XOR addsub_a(31) XOR addsub_b(31)); --V Long + c_out <= c_in(3 downto 1); + END PROCESS; + +------------------------------------------------------------------------------ +--ALU +------------------------------------------------------------------------------ +PROCESS (OP1out, OP2out, niba_hc, niba_h, niba_l, niba_lc, nibs_hc, nibs_h, nibs_l, nibs_lc, Flags) + BEGIN +--BCD_ARITH------------------------------------------------------------------- + --ADC + bcd_a <= niba_hc & std_logic_vector(unsigned(niba_h(4 downto 1)) + ('0',niba_hc,niba_hc,'0')) & + std_logic_vector(unsigned(niba_l(4 downto 1)) + ('0',niba_lc,niba_lc,'0')); + niba_l <= std_logic_vector(unsigned('0'&OP1out(3 downto 0)&'1') + unsigned('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 <= std_logic_vector(unsigned('0'&OP1out(7 downto 4)&'1') + unsigned('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 + bcd_s <= nibs_hc & std_logic_vector(unsigned(nibs_h(4 downto 1)) - ('0',nibs_hc,nibs_hc,'0')) & + std_logic_vector(unsigned(nibs_l(4 downto 1)) - ('0',nibs_lc,nibs_lc,'0')); + nibs_l <= std_logic_vector(unsigned('0'&OP1out(3 downto 0)&'0') - unsigned('0'&OP2out(3 downto 0)&Flags(4))); + nibs_lc <= nibs_l(5); + + nibs_h <= std_logic_vector(unsigned('0'&OP1out(7 downto 4)&'0') - unsigned('0'&OP2out(7 downto 4)&nibs_lc)); + nibs_hc <= nibs_h(5); + END PROCESS; + +----------------------------------------------------------------------------- +-- Bits +----------------------------------------------------------------------------- +PROCESS (clk, exe_opcode, OP1out, OP2out, one_bit_in, bchg, bset, bit_Number, sndOPC) + BEGIN + IF rising_edge(clk) THEN + IF clkena_lw = '1' THEN + bchg <= '0'; + bset <= '0'; + CASE opcode(7 downto 6) IS + WHEN "01" => --bchg + bchg <= '1'; + WHEN "11" => --bset + bset <= '1'; + WHEN OTHERS => NULL; + END CASE; + END IF; + END IF; + + IF exe_opcode(8)='0' THEN + IF exe_opcode(5 downto 4)="00" THEN + bit_number <= sndOPC(4 downto 0); + ELSE + bit_number <= "00"&sndOPC(2 downto 0); + END IF; + ELSE + IF exe_opcode(5 downto 4)="00" THEN + bit_number <= reg_QB(4 downto 0); + ELSE + bit_number <= "00"®_QB(2 downto 0); + END IF; + END IF; + + one_bit_in <= OP1out(to_integer(unsigned(bit_Number))); + bits_out <= OP1out; + bits_out(to_integer(unsigned(bit_Number))) <= (bchg AND NOT one_bit_in) OR bset ; + END PROCESS; + +----------------------------------------------------------------------------- +-- Bit Field +----------------------------------------------------------------------------- +PROCESS (clk, mux, mask, bitnr, bf_ins, bf_bchg, bf_bset, bf_exts, bf_shift, inmux0, inmux1, inmux2, inmux3, bf_set2, OP1out, OP2out, result_tmp, bf_ext_in, + shift, datareg, bf_NFlag, result, reg_QB, sign, bf_d32, bf_s32, copy, bf_loffset, copymux0, copymux1, copymux2, copymux3, bf_width) + BEGIN + IF rising_edge(clk) THEN + IF clkena_lw = '1' THEN + bf_bset <= '0'; + bf_bchg <= '0'; + bf_ins <= '0'; + bf_exts <= '0'; + bf_fffo <= '0'; + bf_d32 <= '0'; + bf_s32 <= '0'; + CASE opcode(10 downto 8) IS + WHEN "010" => bf_bchg <= '1'; --BFCHG + WHEN "011" => bf_exts <= '1'; --BFEXTS +-- WHEN "100" => insert <= (OTHERS =>'0'); --BFCLR + WHEN "101" => bf_fffo <= '1'; --BFFFO + WHEN "110" => bf_bset <= '1'; --BFSET + WHEN "111" => bf_ins <= '1'; --BFINS + bf_s32 <= '1'; + WHEN OTHERS => NULL; + END CASE; + IF opcode(4 downto 3)="00" THEN + bf_d32 <= '1'; + END IF; + bf_ext_out <= result(39 downto 32); + END IF; + END IF; + shift <= bf_ext_in&OP2out; + IF bf_s32='1' THEN + shift(39 downto 32) <= OP2out(7 downto 0); + END IF; + + IF bf_shift(0)='1' THEN + inmux0 <= shift(0)&shift(39 downto 1); + ELSE + inmux0 <= shift; + END IF; + IF bf_shift(1)='1' THEN + inmux1 <= inmux0(1 downto 0)&inmux0(39 downto 2); + ELSE + inmux1 <= inmux0; + END IF; + IF bf_shift(2)='1' THEN + inmux2 <= inmux1(3 downto 0)&inmux1(39 downto 4); + ELSE + inmux2 <= inmux1; + END IF; + IF bf_shift(3)='1' THEN + inmux3 <= inmux2(7 downto 0)&inmux2(31 downto 8); + ELSE + inmux3 <= inmux2(31 downto 0); + END IF; + IF bf_shift(4)='1' THEN + bf_set2(31 downto 0) <= inmux3(15 downto 0)&inmux3(31 downto 16); + ELSE + bf_set2(31 downto 0) <= inmux3; + END IF; + + IF bf_loffset(4)='1' THEN + copymux3 <= sign(15 downto 0)&sign(31 downto 16); + ELSE + copymux3 <= sign; + END IF; + IF bf_loffset(3)='1' THEN + copymux2(31 downto 0) <= copymux3(23 downto 0)©mux3(31 downto 24); + ELSE + copymux2(31 downto 0) <= copymux3; + END IF; + IF bf_d32='1' THEN + copymux2(39 downto 32) <= copymux3(7 downto 0); + ELSE + copymux2(39 downto 32) <= "11111111"; + END IF; + IF bf_loffset(2)='1' THEN + copymux1 <= copymux2(35 downto 0)©mux2(39 downto 36); + ELSE + copymux1 <= copymux2; + END IF; + IF bf_loffset(1)='1' THEN + copymux0 <= copymux1(37 downto 0)©mux1(39 downto 38); + ELSE + copymux0 <= copymux1; + END IF; + IF bf_loffset(0)='1' THEN + copy <= copymux0(38 downto 0)©mux0(39); + ELSE + copy <= copymux0; + END IF; + + result_tmp <= bf_ext_in&OP1out; + IF bf_ins='1' THEN + datareg <= reg_QB; + ELSE + datareg <= bf_set2; + END IF; + IF bf_ins='1' THEN + result(31 downto 0) <= bf_set2; + result(39 downto 32) <= bf_set2(7 downto 0); + ELSIF bf_bchg='1' THEN + result(31 downto 0) <= NOT OP1out; + result(39 downto 32) <= NOT bf_ext_in; + ELSE + result <= (OTHERS => '0'); + END IF; + IF bf_bset='1' THEN + result <= (OTHERS => '1'); + END IF; + + sign <= (OTHERS => '0'); + bf_NFlag <= datareg(to_integer(unsigned(bf_width))); + FOR i in 0 to 31 LOOP + IF i > unsigned(bf_width(4 downto 0)) THEN + datareg(i) <= '0'; + sign(i) <= '1'; + END IF; + END LOOP; + + FOR i in 0 to 39 LOOP + IF copy(i)='1' THEN + result(i) <= result_tmp(i); + END IF; + END LOOP; + + IF bf_exts='1' AND bf_NFlag='1' THEN + bf_datareg <= datareg OR sign; + ELSE + bf_datareg <= datareg; + END IF; +-- bf_datareg <= copy(31 downto 0); +-- result(31 downto 0)<=datareg; +--BFFFO + mask <= datareg; + bf_firstbit <= '0'&bitnr; + bitnr <= "11111"; + IF mask(31 downto 28)="0000" THEN + IF mask(27 downto 24)="0000" THEN + IF mask(23 downto 20)="0000" THEN + IF mask(19 downto 16)="0000" THEN + bitnr(4) <= '0'; + IF mask(15 downto 12)="0000" THEN + IF mask(11 downto 8)="0000" THEN + bitnr(3) <= '0'; + IF mask(7 downto 4)="0000" THEN + bitnr(2) <= '0'; + mux <= mask(3 downto 0); + ELSE + mux <= mask(7 downto 4); + END IF; + ELSE + mux <= mask(11 downto 8); + bitnr(2) <= '0'; + END IF; + ELSE + mux <= mask(15 downto 12); + END IF; + ELSE + mux <= mask(19 downto 16); + bitnr(3) <= '0'; + bitnr(2) <= '0'; + END IF; + ELSE + mux <= mask(23 downto 20); + bitnr(3) <= '0'; + END IF; + ELSE + mux <= mask(27 downto 24); + bitnr(2) <= '0'; + END IF; + ELSE + mux <= mask(31 downto 28); + END IF; + + IF mux(3 downto 2)="00" THEN + bitnr(1) <= '0'; + IF mux(1)='0' THEN + bitnr(0) <= '0'; + END IF; + ELSE + IF mux(3)='0' THEN + bitnr(0) <= '0'; + END IF; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- Rotation +----------------------------------------------------------------------------- +PROCESS (exe_opcode, OP1out, Flags, rot_bits, rot_msb, rot_lsb, rot_rot, exec) + BEGIN + CASE exe_opcode(7 downto 6) IS + WHEN "00" => --Byte + rot_rot <= OP1out(7); + WHEN "01"|"11" => --Word + rot_rot <= OP1out(15); + WHEN "10" => --Long + rot_rot <= OP1out(31); + WHEN OTHERS => NULL; + END CASE; + + CASE rot_bits IS + WHEN "00" => --ASL, ASR + rot_lsb <= '0'; + rot_msb <= rot_rot; + WHEN "01" => --LSL, LSR + rot_lsb <= '0'; + rot_msb <= '0'; + WHEN "10" => --ROXL, ROXR + rot_lsb <= Flags(4); + rot_msb <= Flags(4); + WHEN "11" => --ROL, ROR + rot_lsb <= rot_rot; + rot_msb <= OP1out(0); + WHEN OTHERS => NULL; + END CASE; + + IF exec(rot_nop)='1' THEN + rot_out <= OP1out; + rot_X <= Flags(4); + IF rot_bits="10" THEN --ROXL, ROXR + rot_C <= Flags(4); + ELSE + rot_C <= '0'; + END IF; + ELSE + IF exe_opcode(8)='1' THEN --left + rot_out <= OP1out(30 downto 0)&rot_lsb; + rot_X <= rot_rot; + rot_C <= rot_rot; + ELSE --right + rot_X <= OP1out(0); + rot_C <= OP1out(0); + rot_out <= rot_msb&OP1out(31 downto 1); + CASE exe_opcode(7 downto 6) IS + WHEN "00" => --Byte + rot_out(7) <= rot_msb; + WHEN "01"|"11" => --Word + rot_out(15) <= rot_msb; + WHEN OTHERS => NULL; + END CASE; + END IF; + END IF; + END PROCESS; + +------------------------------------------------------------------------------ +--CCR op +------------------------------------------------------------------------------ +PROCESS (clk, Reset, exe_opcode, exe_datatype, Flags, last_data_read, OP2out, flag_z, OP1IN, c_out, addsub_ofl, + bcd_s, bcd_a, exec) + BEGIN + IF exec(andiSR)='1' THEN + CCRin <= Flags AND last_data_read(7 downto 0); + ELSIF exec(eoriSR)='1' THEN + CCRin <= Flags XOR last_data_read(7 downto 0); + ELSIF exec(oriSR)='1' THEN + CCRin <= Flags OR last_data_read(7 downto 0); + ELSE + CCRin <= OP2out(7 downto 0); + END IF; + +------------------------------------------------------------------------------ +--Flags +------------------------------------------------------------------------------ + flag_z <= "000"; + IF exec(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 exe_datatype="00" THEN --Byte + set_flags <= OP1IN(7)&flag_z(0)&addsub_ofl(0)&c_out(0); + IF exec(opcABCD)='1' THEN + set_flags(0) <= bcd_a(8); + ELSIF exec(opcSBCD)='1' THEN + set_flags(0) <= bcd_s(8); + END IF; + ELSIF exe_datatype="10" OR exec(opcCPMAW)='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; + + IF rising_edge(clk) THEN + IF clkena_lw = '1' THEN + IF exec(directSR)='1' OR set_stop='1' THEN + Flags(7 downto 0) <= data_read(7 downto 0); + END IF; + IF exec(directCCR)='1' THEN + Flags(7 downto 0) <= data_read(7 downto 0); + END IF; + + IF exec(opcROT)='1' THEN + asl_VFlag <= ((set_flags(3) XOR rot_rot) OR asl_VFlag); + ELSE + asl_VFlag <= '0'; + END IF; + IF exec(to_CCR)='1' THEN + Flags(7 downto 0) <= CCRin(7 downto 0); --CCR + ELSIF Z_error='1' THEN + IF exe_opcode(8)='0' THEN + Flags(3 downto 0) <= reg_QA(31)&"000"; + ELSE + Flags(3 downto 0) <= "0100"; + END IF; + ELSIF exec(no_Flags)='0' THEN + IF exec(opcADD)='1' THEN + Flags(4) <= set_flags(0); + ELSIF exec(opcROT)='1' AND rot_bits/="11" AND exec(rot_nop)='0' THEN + Flags(4) <= rot_X; + END IF; + + IF (exec(opcADD) OR exec(opcCMP))='1' THEN + Flags(3 downto 0) <= set_flags; + ELSIF exec(opcDIVU)='1' AND DIV_Mode/=3 THEN + IF V_Flag='1' THEN + Flags(3 downto 0) <= "1010"; + ELSE + Flags(3 downto 0) <= OP1IN(15)&flag_z(1)&"00"; + END IF; + ELSIF exec(write_reminder)='1' AND MUL_Mode/=3 THEN -- z-flag MULU.l + Flags(3) <= set_flags(3); + Flags(2) <= set_flags(2) AND Flags(2); + Flags(1) <= '0'; + Flags(0) <= '0'; + ELSIF exec(write_lowlong)='1' AND (MUL_Mode=1 OR MUL_Mode=2) THEN -- flag MULU.l + Flags(3) <= set_flags(3); + Flags(2) <= set_flags(2); + Flags(1) <= set_mV_Flag; --V + Flags(0) <= '0'; + ELSIF exec(opcOR)='1' OR exec(opcAND)='1' OR exec(opcEOR)='1' OR exec(opcMOVE)='1' OR exec(opcMOVEQ)='1' OR exec(opcSWAP)='1' OR exec(opcBF)='1' OR (exec(opcMULU)='1' AND MUL_Mode/=3) THEN + Flags(1 downto 0) <= "00"; + Flags(3 downto 2) <= set_flags(3 downto 2); + IF exec(opcBF)='1' THEN + Flags(3) <= bf_NFlag; + END IF; + ELSIF exec(opcROT)='1' THEN + Flags(3 downto 2) <= set_flags(3 downto 2); + Flags(0) <= rot_C; + IF rot_bits="00" AND ((set_flags(3) XOR rot_rot) OR asl_VFlag)='1' THEN --ASL/ASR + Flags(1) <= '1'; + ELSE + Flags(1) <= '0'; + END IF; + ELSIF exec(opcBITS)='1' THEN + Flags(2) <= NOT one_bit_in; + ELSIF exec(opcCHK)='1' THEN + IF exe_datatype="01" THEN --Word + Flags(3) <= OP1out(15); + ELSE + Flags(3) <= OP1out(31); + END IF; + IF OP1out(15 downto 0)=X"0000" AND (exe_datatype="01" OR OP1out(31 downto 16)=X"0000") THEN + Flags(2) <='1'; + ELSE + Flags(2) <='0'; + END IF; + Flags(1 downto 0) <= "00"; + END IF; + END IF; + END IF; + Flags(7 downto 5) <= "000"; + END IF; + END PROCESS; + +------------------------------------------------------------------------------- +---- MULU/MULS +------------------------------------------------------------------------------- +PROCESS (exe_opcode, OP2out, muls_msb, mulu_reg, FAsign, mulu_sign, reg_QA, faktorB, result_mulu, signedOP) + BEGIN + IF (signedOP='1' AND faktorB(31)='1') OR FAsign='1' THEN + muls_msb <= mulu_reg(63); + ELSE + muls_msb <= '0'; + END IF; + + IF signedOP='1' AND faktorB(31)='1' THEN + mulu_sign <= '1'; + ELSE + mulu_sign <= '0'; + END IF; + + IF MUL_Mode=0 THEN -- 16 Bit + result_mulu(63 downto 32) <= muls_msb&mulu_reg(63 downto 33); + result_mulu(15 downto 0) <= 'X'&mulu_reg(15 downto 1); + IF mulu_reg(0)='1' THEN + IF FAsign='1' THEN + result_mulu(63 downto 47) <= std_logic_vector(muls_msb & unsigned(mulu_reg(63 downto 48)) - unsigned(mulu_sign&faktorB(31 downto 16)) ); + ELSE + result_mulu(63 downto 47) <= std_logic_vector(muls_msb & unsigned(mulu_reg(63 downto 48)) + unsigned(mulu_sign&faktorB(31 downto 16)) ); + END IF; + END IF; + ELSE -- 32 Bit + result_mulu <= muls_msb&mulu_reg(63 downto 1); + IF mulu_reg(0)='1' THEN + IF FAsign='1' THEN + result_mulu(63 downto 31) <= std_logic_vector(muls_msb & unsigned(mulu_reg(63 downto 32))-unsigned(mulu_sign&faktorB)); + ELSE + result_mulu(63 downto 31) <= std_logic_vector(muls_msb & unsigned(mulu_reg(63 downto 32))+unsigned(mulu_sign&faktorB)); + END IF; + END IF; + END IF; + IF exe_opcode(15)='1' OR MUL_Mode=0 THEN + faktorB(31 downto 16) <= OP2out(15 downto 0); + faktorB(15 downto 0) <= (OTHERS=>'0'); + ELSE + faktorB <= OP2out; + END IF; + IF (result_mulu(63 downto 32)=X"00000000" AND (signedOP='0' OR result_mulu(31)='0')) OR + (result_mulu(63 downto 32)=X"FFFFFFFF" AND signedOP='1' AND result_mulu(31)='1') THEN + set_mV_Flag <= '0'; + ELSE + set_mV_Flag <= '1'; + END IF; + END PROCESS; + +PROCESS (clk) + BEGIN + IF rising_edge(clk) THEN + IF clkena_lw='1' THEN + IF micro_state=mul1 THEN + mulu_reg(63 downto 32) <= (OTHERS=>'0'); + IF divs='1' AND ((exe_opcode(15)='1' AND reg_QA(15)='1') OR (exe_opcode(15)='0' AND reg_QA(31)='1')) THEN --MULS Neg faktor + FAsign <= '1'; + mulu_reg(31 downto 0) <= std_logic_vector(0-unsigned(reg_QA)); + ELSE + FAsign <= '0'; + mulu_reg(31 downto 0) <= reg_QA; + END IF; + ELSIF exec(opcMULU)='0' THEN + mulu_reg <= result_mulu; + END IF; + END IF; + END IF; + END PROCESS; + +------------------------------------------------------------------------------- +---- DIVU/DIVS +------------------------------------------------------------------------------- + +PROCESS (execOPC, OP1out, OP2out, div_reg, div_neg, div_bit, div_sub, div_quot, OP1_sign, div_over, result_div, reg_QA, opcode, sndOPC, divs, exe_opcode, reg_QB, + signedOP, nozero, div_qsign, OP2outext) + BEGIN + divs <= (opcode(15) AND opcode(8)) OR (NOT opcode(15) AND sndOPC(11)); + divisor(15 downto 0) <= (OTHERS=> '0'); + divisor(63 downto 32) <= (OTHERS=> divs AND reg_QA(31)); + IF exe_opcode(15)='1' OR DIV_Mode=0 THEN + divisor(47 downto 16) <= reg_QA; + ELSE + divisor(31 downto 0) <= reg_QA; + IF exe_opcode(14)='1' AND sndOPC(10)='1' THEN + divisor(63 downto 32) <= reg_QB; + END IF; + END IF; + IF signedOP='1' OR opcode(15)='0' THEN + OP2outext <= OP2out(31 downto 16); + ELSE + OP2outext <= (OTHERS=> '0'); + END IF; + IF signedOP='1' AND OP2out(31) ='1' THEN + div_sub <= std_logic_vector(unsigned(div_reg(63 downto 31)) + unsigned('1'&OP2out(31 downto 0))); + ELSE + div_sub <= std_logic_vector(unsigned(div_reg(63 downto 31))-unsigned('0'&OP2outext(15 downto 0)&OP2out(15 downto 0))); + END IF; + IF DIV_Mode=0 THEN + div_bit <= div_sub(16); + ELSE + div_bit <= div_sub(32); + END IF; + IF div_bit='1' THEN + div_quot(63 downto 32) <= div_reg(62 downto 31); + ELSE + div_quot(63 downto 32) <= div_sub(31 downto 0); + END IF; + div_quot(31 downto 0) <= div_reg(30 downto 0)&NOT div_bit; + + + IF ((nozero='1' AND signedOP='1' AND (OP2out(31) XOR OP1_sign XOR div_neg XOR div_qsign)='1' ) --Overflow DIVS + OR (signedOP='0' AND div_over(32)='0')) AND DIV_Mode/=3 THEN --Overflow DIVU + set_V_Flag <= '1'; + ELSE + set_V_Flag <= '0'; + END IF; + END PROCESS; + +PROCESS (clk) + BEGIN + IF rising_edge(clk) THEN + IF clkena_lw='1' THEN + V_Flag <= set_V_Flag; + signedOP <= divs; + IF micro_state=div1 THEN + nozero <= '0'; + IF divs='1' AND divisor(63)='1' THEN -- Neg divisor + OP1_sign <= '1'; + div_reg <= std_logic_vector(0-unsigned(divisor)); + ELSE + OP1_sign <= '0'; + div_reg <= divisor; + END IF; + ELSE + div_reg <= div_quot; + nozero <= NOT div_bit OR nozero; + END IF; + IF micro_state=div2 THEN + div_qsign <= NOT div_bit; + div_neg <= signedOP AND (OP2out(31) XOR OP1_sign); + IF DIV_Mode=0 THEN + div_over(32 downto 16) <= std_logic_vector(unsigned('0'&div_reg(47 downto 32))-unsigned('0'&OP2out(15 downto 0))); + ELSE + div_over <= std_logic_vector(unsigned('0'&div_reg(63 downto 32))-unsigned('0'&OP2out)); + END IF; + END IF; + IF exec(write_reminder)='0' THEN +-- IF exec_DIVU='0' THEN + IF div_neg='1' THEN + result_div(31 downto 0) <= std_logic_vector(0-unsigned(div_quot(31 downto 0))); + ELSE + result_div(31 downto 0) <= div_quot(31 downto 0); + END IF; + + IF OP1_sign='1' THEN + result_div(63 downto 32) <= std_logic_vector(0-unsigned(div_quot(63 downto 32))); + ELSE + result_div(63 downto 32) <= div_quot(63 downto 32); + END IF; + END IF; + END IF; + END IF; + END PROCESS; +END; diff --git a/tests/tg68k/orig/TG68K_Pack.vhd b/tests/tg68k/orig/TG68K_Pack.vhd new file mode 100644 index 0000000..e6011f1 --- /dev/null +++ b/tests/tg68k/orig/TG68K_Pack.vhd @@ -0,0 +1,165 @@ +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2009-2013 Tobias Gubener -- +-- Subdesign fAMpIGA by TobiFlex -- +-- -- +-- This source file is free software: you can redistribute it and/or modify -- +-- it under the terms of the GNU General Public License as published -- +-- by the Free Software Foundation, either version 3 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- This source file is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU General Public License -- +-- along with this program. If not, see . -- +-- -- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +library IEEE; +use IEEE.std_logic_1164.all; + +package TG68K_Pack is + + type micro_states is (idle, nop, ld_nn, st_nn, ld_dAn1, ld_AnXn1, ld_AnXn2, st_dAn1, ld_AnXnbd1, ld_AnXnbd2, ld_AnXnbd3, + ld_229_1, ld_229_2, ld_229_3, ld_229_4, st_229_1, st_229_2, st_229_3, st_229_4, + st_AnXn1, st_AnXn2, bra1, bsr1, bsr2, nopnop, dbcc1, movem1, movem2, movem3, + andi, op_AxAy, cmpm, link1, link2, unlink1, unlink2, int1, int2, int3, int4, rte1, rte2, rte3, trap0, trap1, trap2, trap3, + trap4, trap5, trap6, movec1, movep1, movep2, movep3, movep4, movep5, rota1, bf1, + mul1, mul2, mul_end1, mul_end2, div1, div2, div3, div4, div_end1, div_end2); + + constant opcMOVE : integer := 0; -- + constant opcMOVEQ : integer := 1; -- + constant opcMOVESR : integer := 2; -- + constant opcADD : integer := 3; -- + constant opcADDQ : integer := 4; -- + constant opcOR : integer := 5; -- + constant opcAND : integer := 6; -- + constant opcEOR : integer := 7; -- + constant opcCMP : integer := 8; -- + constant opcROT : integer := 9; -- + constant opcCPMAW : integer := 10; + constant opcEXT : integer := 11; -- + constant opcABCD : integer := 12; -- + constant opcSBCD : integer := 13; -- + constant opcBITS : integer := 14; -- + constant opcSWAP : integer := 15; -- + constant opcScc : integer := 16; -- + constant andiSR : integer := 17; -- + constant eoriSR : integer := 18; -- + constant oriSR : integer := 19; -- + constant opcMULU : integer := 20; -- + constant opcDIVU : integer := 21; -- + constant dispouter : integer := 22; -- + constant rot_nop : integer := 23; -- + constant ld_rot_cnt : integer := 24; -- + constant writePC_add : integer := 25; -- + constant ea_data_OP1 : integer := 26; -- + constant ea_data_OP2 : integer := 27; -- + constant use_XZFlag : integer := 28; -- + constant get_bfoffset : integer := 29; -- + constant save_memaddr : integer := 30; -- + constant opcCHK : integer := 31; -- + constant movec_rd : integer := 32; -- + constant movec_wr : integer := 33; -- + constant Regwrena : integer := 34; -- + constant update_FC : integer := 35; -- + constant linksp : integer := 36; -- + constant movepl : integer := 37; -- + constant update_ld : integer := 38; -- + constant OP1addr : integer := 39; -- + constant write_reg : integer := 40; -- + constant changeMode : integer := 41; -- + constant ea_build : integer := 42; -- + constant trap_chk : integer := 43; -- + constant store_ea_data : integer := 44; -- + constant addrlong : integer := 45; -- + constant postadd : integer := 46; -- + constant presub : integer := 47; -- + constant subidx : integer := 48; -- + constant no_Flags : integer := 49; -- + constant use_SP : integer := 50; -- + constant to_CCR : integer := 51; -- + constant to_SR : integer := 52; -- + constant OP2out_one : integer := 53; -- + constant OP1out_zero : integer := 54; -- + constant mem_addsub : integer := 55; -- + constant addsub : integer := 56; -- + constant directPC : integer := 57; -- + constant direct_delta : integer := 58; -- + constant directSR : integer := 59; -- + constant directCCR : integer := 60; -- + constant exg : integer := 61; -- + constant get_ea_now : integer := 62; -- + constant ea_to_pc : integer := 63; -- + constant hold_dwr : integer := 64; -- + constant to_USP : integer := 65; -- + constant from_USP : integer := 66; -- + constant write_lowlong : integer := 67; -- + constant write_reminder : integer := 68; -- + constant movem_action : integer := 69; -- + constant briefext : integer := 70; -- + constant get_2ndOPC : integer := 71; -- + constant mem_byte : integer := 72; -- + constant longaktion : integer := 73; -- + constant opcRESET : integer := 74; -- + constant opcBF : integer := 75; -- + constant opcBFwb : integer := 76; -- + constant s2nd_hbits : integer := 77; -- +-- constant : integer := 75; -- +-- constant : integer := 76; -- +-- constant : integer := 7; -- +-- constant : integer := 7; -- +-- constant : integer := 7; -- + + constant lastOpcBit : integer := 77; + + component TG68K_ALU + generic( + MUL_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL, + DIV_Mode : integer := 0 --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV, + ); + port( + clk : in std_logic; + Reset : in std_logic; + clkena_lw : in std_logic:='1'; + execOPC : in bit; + exe_condition : in std_logic; + exec_tas : in std_logic; + long_start : in bit; + movem_presub : in bit; + set_stop : in bit; + Z_error : in bit; + rot_bits : in std_logic_vector(1 downto 0); + exec : in bit_vector(lastOpcBit downto 0); + OP1out : in std_logic_vector(31 downto 0); + OP2out : in std_logic_vector(31 downto 0); + reg_QA : in std_logic_vector(31 downto 0); + reg_QB : in std_logic_vector(31 downto 0); + opcode : in std_logic_vector(15 downto 0); + datatype : in std_logic_vector(1 downto 0); + exe_opcode : in std_logic_vector(15 downto 0); + exe_datatype : in std_logic_vector(1 downto 0); + sndOPC : in std_logic_vector(15 downto 0); + last_data_read : in std_logic_vector(15 downto 0); + data_read : in std_logic_vector(15 downto 0); + FlagsSR : in std_logic_vector(7 downto 0); + micro_state : in micro_states; + bf_ext_in : in std_logic_vector(7 downto 0); + bf_ext_out : out std_logic_vector(7 downto 0); + bf_shift : in std_logic_vector(5 downto 0); + bf_width : in std_logic_vector(5 downto 0); + bf_loffset : in std_logic_vector(4 downto 0); + + set_V_Flag : buffer bit; + Flags : buffer std_logic_vector(7 downto 0); + c_out : buffer std_logic_vector(2 downto 0); + addsub_q : buffer std_logic_vector(31 downto 0); + ALUout : out std_logic_vector(31 downto 0) + ); + end component; + +end; \ No newline at end of file diff --git a/tests/tg68k/orig/TG68KdotC_Kernel.vhd b/tests/tg68k/orig/TG68KdotC_Kernel.vhd new file mode 100644 index 0000000..a64457f --- /dev/null +++ b/tests/tg68k/orig/TG68KdotC_Kernel.vhd @@ -0,0 +1,3232 @@ +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2009-2013 Tobias Gubener -- +-- Subdesign fAMpIGA by TobiFlex -- +-- -- +-- This source file is free software: you can redistribute it and/or modify -- +-- it under the terms of the GNU General Public License as published -- +-- by the Free Software Foundation, either version 3 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- This source file is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU General Public License -- +-- along with this program. If not, see . -- +-- -- +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- add berr handling 10.03.2013 + +-- bugfix session 07/08.Feb.2013 +-- movem ,-(an) +-- movem (an)+, - thanks Gerhard Suttner +-- btst dn,#data - thanks Peter Graf +-- movep - thanks Till Harbaum +-- IPL vector - thanks Till Harbaum +-- + +-- optimize Register file + +-- to do 68010: +-- (MOVEC) +-- BKPT +-- RTD +-- MOVES +-- +-- to do 68020: +-- (CALLM) +-- (RETM) + +-- CAS, CAS2 +-- CHK2 +-- CMP2 +-- cpXXX Coprozessor stuff +-- PACK +-- TRAPcc +-- UNPK + +-- done 020: +-- Bitfields +-- address modes +-- long bra +-- DIVS.L, DIVU.L +-- LINK long +-- MULS.L, MULU.L +-- extb.l + +library ieee; +use ieee.std_logic_1164.all; +-- use ieee.std_logic_unsigned.all; +use work.TG68K_Pack.all; +use ieee.numeric_std.all; + +entity TG68KdotC_Kernel is + generic( + SR_Read : integer:= 0; --0=>user, 1=>privileged, 2=>switchable with CPU(0) + VBR_Stackframe : integer:= 0; --0=>no, 1=>yes/extended, 2=>switchable with CPU(0) + extAddr_Mode : integer:= 0; --0=>no, 1=>yes, 2=>switchable with CPU(1) + MUL_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL, + DIV_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV, + BitField : integer := 0 --0=>no, 1=>yes, 2=>switchable with CPU(1) + ); + port(clk : in std_logic; + nReset : in std_logic; --low active + clkena_in : in std_logic:='1'; + data_in : in std_logic_vector(15 downto 0); + IPL : in std_logic_vector(2 downto 0):="111"; + IPL_autovector : in std_logic:='0'; + berr : in std_logic:='0'; -- only 68000 Stackpointer dummy + CPU : in std_logic_vector(1 downto 0):="00"; -- 00->68000 01->68010 11->68020(only some parts - yet) + addr : buffer std_logic_vector(31 downto 0); + data_write : out std_logic_vector(15 downto 0); + nWr : out std_logic; + nUDS, nLDS : out std_logic; + busstate : out std_logic_vector(1 downto 0); -- 00-> fetch code 10->read data 11->write data 01->no memaccess + nResetOut : out std_logic; + FC : out std_logic_vector(2 downto 0); +-- + clr_berr : out std_logic; +-- for debug + db_OP1out : out std_logic_vector(31 downto 0); + db_OP2out : out std_logic_vector(31 downto 0); + skipFetch : out std_logic; + regin : buffer std_logic_vector(31 downto 0) + ); +end TG68KdotC_Kernel; + +architecture logic of TG68KdotC_Kernel is + + + signal syncReset : std_logic_vector(3 downto 0); + signal Reset : std_logic; + signal clkena_lw : std_logic; + signal TG68_PC : std_logic_vector(31 downto 0); + signal tmp_TG68_PC : std_logic_vector(31 downto 0); + signal TG68_PC_add : std_logic_vector(31 downto 0); + signal PC_dataa : std_logic_vector(31 downto 0); + signal PC_datab : std_logic_vector(31 downto 0); + signal memaddr : std_logic_vector(31 downto 0); + signal state : std_logic_vector(1 downto 0); + signal datatype : std_logic_vector(1 downto 0); + signal set_datatype : std_logic_vector(1 downto 0); + signal exe_datatype : std_logic_vector(1 downto 0); + signal setstate : std_logic_vector(1 downto 0); + + signal opcode : std_logic_vector(15 downto 0); + signal exe_opcode : std_logic_vector(15 downto 0); + signal sndOPC : std_logic_vector(15 downto 0); + + signal last_opc_read : std_logic_vector(15 downto 0); + signal registerin : std_logic_vector(31 downto 0); + signal reg_QA : std_logic_vector(31 downto 0); + signal reg_QB : std_logic_vector(31 downto 0); + signal Wwrena,Lwrena : bit; + signal Bwrena : bit; + signal Regwrena_now : bit; + signal rf_dest_addr : std_logic_vector(3 downto 0); + signal rf_source_addr : std_logic_vector(3 downto 0); + signal rf_source_addrd : std_logic_vector(3 downto 0); + + type regfile_t is array(0 to 15) of std_logic_vector(31 downto 0); + signal regfile : regfile_t; + signal RDindex_A : integer range 0 to 15; + signal RDindex_B : integer range 0 to 15; + signal WR_AReg : std_logic; + + + signal memaddr_reg : std_logic_vector(31 downto 0); + signal memaddr_delta : std_logic_vector(31 downto 0); + signal use_base : bit; + + signal ea_data : std_logic_vector(31 downto 0); + signal OP1out, OP2out : std_logic_vector(31 downto 0); + signal OP1outbrief : std_logic_vector(15 downto 0); + signal OP1in : std_logic_vector(31 downto 0); + signal ALUout : std_logic_vector(31 downto 0); + signal data_write_tmp : std_logic_vector(31 downto 0); + signal data_write_muxin : std_logic_vector(31 downto 0); + signal data_write_mux : std_logic_vector(47 downto 0); + signal nextpass : bit; + signal setnextpass : bit; + signal setdispbyte : bit; + signal setdisp : bit; + signal regdirectsource :bit; -- checken !!! + signal addsub_q : std_logic_vector(31 downto 0); + signal briefdata : std_logic_vector(31 downto 0); +-- signal c_in : std_logic_vector(3 downto 0); + signal c_out : std_logic_vector(2 downto 0); + + signal mem_address : std_logic_vector(31 downto 0); + signal memaddr_a : std_logic_vector(31 downto 0); + + signal TG68_PC_brw : bit; + signal TG68_PC_word : bit; + signal getbrief : bit; + signal brief : std_logic_vector(15 downto 0); + signal dest_areg : std_logic; + signal source_areg : std_logic; + signal data_is_source : bit; + signal store_in_tmp : bit; + signal write_back : bit; + signal exec_write_back: bit; + signal setstackaddr : bit; + signal writePC : bit; + signal writePCbig : bit; + signal set_writePCbig : bit; + signal setopcode : bit; + signal decodeOPC : bit; + signal execOPC : bit; + signal setexecOPC : bit; + signal endOPC : bit; + signal setendOPC : bit; + signal Flags : std_logic_vector(7 downto 0); -- ...XNZVC + signal FlagsSR : std_logic_vector(7 downto 0); -- T.S..III + signal SRin : std_logic_vector(7 downto 0); + signal exec_DIRECT : bit; + signal exec_tas : std_logic; + signal set_exec_tas : std_logic; + + signal exe_condition : std_logic; + signal ea_only : bit; + signal source_lowbits : bit; + signal source_2ndHbits : bit; + signal source_2ndLbits : bit; + signal dest_2ndHbits : bit; + signal dest_hbits : bit; + signal rot_bits : std_logic_vector(1 downto 0); + signal set_rot_bits : std_logic_vector(1 downto 0); + signal rot_cnt : std_logic_vector(5 downto 0); + signal set_rot_cnt : std_logic_vector(5 downto 0); + signal movem_actiond : bit; + signal movem_regaddr : std_logic_vector(3 downto 0); + signal movem_mux : std_logic_vector(3 downto 0); + signal movem_presub : bit; + signal movem_run : bit; + signal ea_calc_b : std_logic_vector(31 downto 0); + signal set_direct_data: bit; + signal use_direct_data: bit; + signal direct_data : bit; + + signal set_V_Flag : bit; + signal set_vectoraddr : bit; + signal writeSR : bit; + signal trap_berr : bit; + signal trap_illegal : bit; + signal trap_addr_error : bit; + signal trap_priv : bit; + signal trap_trace : bit; + signal trap_1010 : bit; + signal trap_1111 : bit; + signal trap_trap : bit; + signal trap_trapv : bit; + signal trap_interrupt : bit; + signal trapmake : bit; + signal trapd : bit; + signal trap_SR : std_logic_vector(7 downto 0); + signal make_trace : std_logic; + signal make_berr : std_logic; + + signal set_stop : bit; + signal stop : bit; + signal trap_vector : std_logic_vector(31 downto 0); + signal trap_vector_vbr : std_logic_vector(31 downto 0); + signal USP : std_logic_vector(31 downto 0); + signal illegal_write_mode : bit; + signal illegal_read_mode : bit; + signal illegal_byteaddr : bit; + + signal IPL_nr : std_logic_vector(2 downto 0); + signal rIPL_nr : std_logic_vector(2 downto 0); + signal IPL_vec : std_logic_vector(7 downto 0); + signal interrupt : bit; + signal setinterrupt : bit; + signal SVmode : std_logic; + signal preSVmode : std_logic; + signal Suppress_Base : bit; + signal set_Suppress_Base : bit; + signal set_Z_error : bit; + signal Z_error : bit; + signal ea_build_now : bit; + signal build_logical : bit; + signal build_bcd : bit; + + signal data_read : std_logic_vector(31 downto 0); + signal bf_ext_in : std_logic_vector(7 downto 0); + signal bf_ext_out : std_logic_vector(7 downto 0); + signal byte : bit; + signal long_start : bit; + signal long_start_alu : bit; + signal long_done : bit; + signal memmask : std_logic_vector(5 downto 0); + signal set_memmask : std_logic_vector(5 downto 0); + signal memread : std_logic_vector(3 downto 0); + signal wbmemmask : std_logic_vector(5 downto 0); + signal memmaskmux : std_logic_vector(5 downto 0); + signal oddout : std_logic; + signal set_oddout : std_logic; + signal PCbase : std_logic; + signal set_PCbase : std_logic; + + signal last_data_read : std_logic_vector(31 downto 0); + signal last_data_in : std_logic_vector(31 downto 0); + + signal bf_offset : std_logic_vector(5 downto 0); + signal bf_width : std_logic_vector(5 downto 0); + signal bf_bhits : std_logic_vector(5 downto 0); + signal bf_shift : std_logic_vector(5 downto 0); + signal alu_width : std_logic_vector(5 downto 0); + signal alu_bf_shift : std_logic_vector(5 downto 0); + signal bf_loffset : std_logic_vector(5 downto 0); + signal alu_bf_loffset : std_logic_vector(5 downto 0); + + signal movec_data : std_logic_vector(31 downto 0); + signal VBR : std_logic_vector(31 downto 0); + signal CACR : std_logic_vector(3 downto 0); + signal DFC : std_logic_vector(2 downto 0); + signal SFC : std_logic_vector(2 downto 0); + + + signal set : bit_vector(lastOpcBit downto 0); + signal set_exec : bit_vector(lastOpcBit downto 0); + signal exec : bit_vector(lastOpcBit downto 0); + + signal micro_state : micro_states; + signal next_micro_state : micro_states; + + + +BEGIN +db_OP1out <= OP1out; +db_OP2out <= OP2out; + +ALU: TG68K_ALU + generic map( + MUL_Mode => MUL_Mode, --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL, + DIV_Mode => DIV_Mode --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV, + ) + port map( + clk => clk, --: in std_logic; + Reset => Reset, --: in std_logic; + clkena_lw => clkena_lw, --: in std_logic:='1'; + execOPC => execOPC, --: in bit; + exe_condition => exe_condition, --: in std_logic; + exec_tas => exec_tas, --: in std_logic; + long_start => long_start_alu, --: in bit; + movem_presub => movem_presub, --: in bit; + set_stop => set_stop, --: in bit; + Z_error => Z_error, --: in bit; + + rot_bits => rot_bits, --: in std_logic_vector(1 downto 0); + exec => exec, --: in bit_vector(lastOpcBit downto 0); + OP1out => OP1out, --: in std_logic_vector(31 downto 0); + OP2out => OP2out, --: in std_logic_vector(31 downto 0); + reg_QA => reg_QA, --: in std_logic_vector(31 downto 0); + reg_QB => reg_QB, --: in std_logic_vector(31 downto 0); + opcode => opcode, --: in std_logic_vector(15 downto 0); + datatype => datatype, --: in std_logic_vector(1 downto 0); + exe_opcode => exe_opcode, --: in std_logic_vector(15 downto 0); + exe_datatype => exe_datatype, --: in std_logic_vector(1 downto 0); + sndOPC => sndOPC, --: in std_logic_vector(15 downto 0); + last_data_read => last_data_read(15 downto 0), --: in std_logic_vector(31 downto 0); + data_read => data_read(15 downto 0), --: in std_logic_vector(31 downto 0); + FlagsSR => FlagsSR, --: in std_logic_vector(7 downto 0); + micro_state => micro_state, --: in micro_states; + bf_ext_in => bf_ext_in, + bf_ext_out => bf_ext_out, + bf_shift => alu_bf_shift, + bf_width => alu_width, + bf_loffset => alu_bf_loffset(4 downto 0), + + set_V_Flag => set_V_Flag, --: buffer bit; + Flags => Flags, --: buffer std_logic_vector(8 downto 0); + c_out => c_out, --: buffer std_logic_vector(2 downto 0); + addsub_q => addsub_q, --: buffer std_logic_vector(31 downto 0); + ALUout => ALUout --: buffer std_logic_vector(31 downto 0) + ); + + long_start_alu <= to_bit(NOT memmaskmux(3)); +----------------------------------------------------------------------------- +-- Bus control +----------------------------------------------------------------------------- + nWr <= '0' WHEN state="11" ELSE '1'; + busstate <= state; + nResetOut <= '0' WHEN exec(opcRESET)='1' ELSE '1'; + memmaskmux <= memmask WHEN addr(0)='1' ELSE memmask(4 downto 0)&'1'; + nUDS <= memmaskmux(5); + nLDS <= memmaskmux(4); + clkena_lw <= '1' WHEN clkena_in='1' AND memmaskmux(3)='1' ELSE '0'; + clr_berr <= '1' WHEN setopcode='1' AND trap_berr='1' ELSE '0'; + + PROCESS (clk, nReset) + BEGIN + IF nReset='0' THEN + syncReset <= "0000"; + Reset <= '1'; + ELSIF rising_edge(clk) THEN + IF clkena_in='1' THEN + syncReset <= syncReset(2 downto 0)&'1'; + Reset <= NOT syncReset(3); + END IF; + END IF; + END PROCESS; + +PROCESS (clk, long_done, last_data_in, data_in, byte, addr, long_start, memmaskmux, memread, memmask, data_read) + BEGIN + IF memmaskmux(4)='0' THEN + data_read <= last_data_in(15 downto 0)&data_in; + ELSE + data_read <= last_data_in(23 downto 0)&data_in(15 downto 8); + END IF; + IF memread(0)='1' OR (memread(1 downto 0)="10" AND memmaskmux(4)='1')THEN + data_read(31 downto 16) <= (OTHERS=>data_read(15)); + END IF; + + IF rising_edge(clk) THEN + IF clkena_lw='1' AND state="10" THEN + IF memmaskmux(4)='0' THEN + bf_ext_in <= last_data_in(23 downto 16); + ELSE + bf_ext_in <= last_data_in(31 downto 24); + END IF; + END IF; + IF Reset='1' THEN + last_data_read <= (OTHERS => '0'); + ELSIF clkena_in='1' THEN + IF state="00" OR exec(update_ld)='1' THEN + last_data_read <= data_read; + IF state(1)='0' AND memmask(1)='0' THEN + last_data_read(31 downto 16) <= last_opc_read; + ELSIF state(1)='0' OR memread(1)='1' THEN + last_data_read(31 downto 16) <= (OTHERS=>data_in(15)); + END IF; + END IF; + last_data_in <= last_data_in(15 downto 0)&data_in(15 downto 0); + + END IF; + END IF; + long_start <= to_bit(NOT memmask(1)); + long_done <= to_bit(NOT memread(1)); + END PROCESS; + +PROCESS (byte, long_start, reg_QB, data_write_tmp, exec, data_read, data_write_mux, memmaskmux, bf_ext_out, + data_write_muxin, memmask, oddout, addr) + BEGIN + IF exec(write_reg)='1' THEN + data_write_muxin <= reg_QB; + ELSE + data_write_muxin <= data_write_tmp; + END IF; + + IF BitField=0 THEN + IF oddout=addr(0) THEN + data_write_mux <= "XXXXXXXX"&"XXXXXXXX"&data_write_muxin; + ELSE + data_write_mux <= "XXXXXXXX"&data_write_muxin&"XXXXXXXX"; + END IF; + ELSE + IF oddout=addr(0) THEN + data_write_mux <= "XXXXXXXX"&bf_ext_out&data_write_muxin; + ELSE + data_write_mux <= bf_ext_out&data_write_muxin&"XXXXXXXX"; + END IF; + END IF; + + IF memmaskmux(1)='0' THEN + data_write <= data_write_mux(47 downto 32); + ELSIF memmaskmux(3)='0' THEN + data_write <= data_write_mux(31 downto 16); + ELSE + data_write <= data_write_mux(15 downto 0); + END IF; + IF exec(mem_byte)='1' THEN --movep + data_write(7 downto 0) <= data_write_tmp(15 downto 8); + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- Registerfile +----------------------------------------------------------------------------- +PROCESS (clk, regfile, RDindex_A, RDindex_B, exec) + BEGIN + reg_QA <= regfile(RDindex_A); + reg_QB <= regfile(RDindex_B); + IF rising_edge(clk) THEN + IF clkena_lw='1' THEN + rf_source_addrd <= rf_source_addr; + WR_AReg <= rf_dest_addr(3); + RDindex_A <= to_integer(unsigned(rf_dest_addr(3 downto 0))); + RDindex_B <= to_integer(unsigned(rf_source_addr(3 downto 0))); + IF Wwrena='1' THEN + regfile(RDindex_A) <= regin; + END IF; + + IF exec(to_USP)='1' THEN + USP <= reg_QA; + END IF; + END IF; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- Write Reg +----------------------------------------------------------------------------- +PROCESS (OP1in, reg_QA, Regwrena_now, Bwrena, Lwrena, exe_datatype, WR_AReg, movem_actiond, exec, ALUout, memaddr, memaddr_a, ea_only, USP, movec_data) + BEGIN + regin <= ALUout; + IF exec(save_memaddr)='1' THEN + regin <= memaddr; + ELSIF exec(get_ea_now)='1' AND ea_only='1' THEN + regin <= memaddr_a; + ELSIF exec(from_USP)='1' THEN + regin <= USP; + ELSIF exec(movec_rd)='1' THEN + regin <= movec_data; + END IF; + + IF Bwrena='1' THEN + regin(15 downto 8) <= reg_QA(15 downto 8); + END IF; + IF Lwrena='0' THEN + regin(31 downto 16) <= reg_QA(31 downto 16); + END IF; + + Bwrena <= '0'; + Wwrena <= '0'; + Lwrena <= '0'; + IF exec(presub)='1' OR exec(postadd)='1' OR exec(changeMode)='1' THEN -- -(An)+ + Wwrena <= '1'; + Lwrena <= '1'; + ELSIF Regwrena_now='1' THEN --dbcc + Wwrena <= '1'; + ELSIF exec(Regwrena)='1' THEN --read (mem) + Wwrena <= '1'; + CASE exe_datatype IS + WHEN "00" => --BYTE + Bwrena <= '1'; + WHEN "01" => --WORD + IF WR_AReg='1' OR movem_actiond='1' THEN + Lwrena <='1'; + END IF; + WHEN OTHERS => --LONG + Lwrena <= '1'; + END CASE; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- set dest regaddr +----------------------------------------------------------------------------- +PROCESS (opcode, rf_source_addrd, brief, setstackaddr, dest_hbits, dest_areg, data_is_source, sndOPC, exec, set, dest_2ndHbits) + BEGIN + IF exec(movem_action) ='1' THEN + rf_dest_addr <= rf_source_addrd; + ELSIF set(briefext)='1' THEN + rf_dest_addr <= brief(15 downto 12); + ELSIF set(get_bfoffset)='1' THEN + rf_dest_addr <= sndOPC(9 downto 6); + ELSIF dest_2ndHbits='1' THEN + rf_dest_addr <= sndOPC(15 downto 12); + ELSIF set(write_reminder)='1' THEN + rf_dest_addr <= sndOPC(3 downto 0); + ELSIF setstackaddr='1' THEN + rf_dest_addr <= "1111"; + ELSIF dest_hbits='1' THEN + rf_dest_addr <= dest_areg&opcode(11 downto 9); + ELSE + IF opcode(5 downto 3)="000" OR data_is_source='1' THEN + rf_dest_addr <= dest_areg&opcode(2 downto 0); + ELSE + rf_dest_addr <= '1'&opcode(2 downto 0); + END IF; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- set source regaddr +----------------------------------------------------------------------------- +PROCESS (opcode, movem_presub, movem_regaddr, source_lowbits, source_areg, sndOPC, exec, set, source_2ndLbits, source_2ndHbits) + BEGIN + IF exec(movem_action)='1' OR set(movem_action) ='1' THEN + IF movem_presub='1' THEN + rf_source_addr <= movem_regaddr XOR "1111"; + ELSE + rf_source_addr <= movem_regaddr; + END IF; + ELSIF source_2ndLbits='1' THEN + rf_source_addr <= sndOPC(3 downto 0); + ELSIF source_2ndHbits='1' THEN + rf_source_addr <= sndOPC(15 downto 12); + ELSIF source_lowbits='1' THEN + rf_source_addr <= source_areg&opcode(2 downto 0); + ELSIF exec(linksp)='1' THEN + rf_source_addr <= "1111"; + ELSE + rf_source_addr <= source_areg&opcode(11 downto 9); + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- set OP1out +----------------------------------------------------------------------------- +PROCESS (reg_QA, store_in_tmp, ea_data, long_start, addr, exec, memmaskmux) + BEGIN + OP1out <= reg_QA; + IF exec(OP1out_zero)='1' THEN + OP1out <= (OTHERS => '0'); + ELSIF exec(ea_data_OP1)='1' AND store_in_tmp='1' THEN + OP1out <= ea_data; + ELSIF exec(movem_action)='1' OR memmaskmux(3)='0' OR exec(OP1addr)='1' THEN + OP1out <= addr; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- set OP2out +----------------------------------------------------------------------------- +PROCESS (OP2out, reg_QB, exe_opcode, exe_datatype, execOPC, exec, use_direct_data, + store_in_tmp, data_write_tmp, ea_data) + BEGIN + OP2out(15 downto 0) <= reg_QB(15 downto 0); + OP2out(31 downto 16) <= (OTHERS => OP2out(15)); + IF exec(OP2out_one)='1' THEN + OP2out(15 downto 0) <= "1111111111111111"; + ELSIF exec(opcEXT)='1' THEN + IF exe_opcode(6)='0' OR exe_opcode(8)='1' THEN --ext.w + OP2out(15 downto 8) <= (OTHERS => OP2out(7)); + END IF; + ELSIF use_direct_data='1' OR (exec(exg)='1' AND execOPC='1') OR exec(get_bfoffset)='1' THEN + OP2out <= data_write_tmp; + ELSIF (exec(ea_data_OP1)='0' AND store_in_tmp='1') OR exec(ea_data_OP2)='1' THEN + OP2out <= ea_data; + ELSIF exec(opcMOVEQ)='1' THEN + OP2out(7 downto 0) <= exe_opcode(7 downto 0); + OP2out(15 downto 8) <= (OTHERS => exe_opcode(7)); + ELSIF exec(opcADDQ)='1' THEN + OP2out(2 downto 0) <= exe_opcode(11 downto 9); + IF exe_opcode(11 downto 9)="000" THEN + OP2out(3) <='1'; + ELSE + OP2out(3) <='0'; + END IF; + OP2out(15 downto 4) <= (OTHERS => '0'); + ELSIF exe_datatype="10" THEN + OP2out(31 downto 16) <= reg_QB(31 downto 16); + END IF; + END PROCESS; + + +----------------------------------------------------------------------------- +-- handle EA_data, data_write +----------------------------------------------------------------------------- +PROCESS (clk) + BEGIN + IF rising_edge(clk) THEN + IF Reset = '1' THEN + store_in_tmp <='0'; + exec_write_back <= '0'; + direct_data <= '0'; + use_direct_data <= '0'; + Z_error <= '0'; + ELSIF clkena_lw='1' THEN + direct_data <= '0'; + IF state="11" THEN + exec_write_back <= '0'; + ELSIF setstate="10" AND write_back='1' THEN + exec_write_back <= '1'; + END IF; + + + IF set_direct_data='1' THEN + direct_data <= '1'; + use_direct_data <= '1'; + ELSIF endOPC='1' THEN + use_direct_data <= '0'; + END IF; + exec_DIRECT <= set_exec(opcMOVE); + + IF endOPC='1' THEN + store_in_tmp <='0'; + Z_error <= '0'; + ELSE + IF set_Z_error='1' THEN + Z_error <= '1'; + END IF; + IF set_exec(opcMOVE)='1' AND state="11" THEN + use_direct_data <= '1'; + END IF; + + IF state="10" THEN + store_in_tmp <= '1'; + END IF; + IF direct_data='1' AND state="00" THEN + store_in_tmp <= '1'; + END IF; + END IF; + IF state="10" THEN + ea_data <= data_read; + ELSIF exec(get_2ndOPC)='1' THEN + ea_data <= addr; + ELSIF exec(store_ea_data)='1' OR (direct_data='1' AND state="00") THEN + ea_data <= last_data_read; + END IF; + + IF writePC='1' THEN + data_write_tmp <= TG68_PC; + ELSIF exec(writePC_add)='1' THEN + data_write_tmp <= TG68_PC_add; + ELSIF micro_state=trap0 THEN + data_write_tmp(15 downto 0) <= trap_vector(15 downto 0); + ELSIF exec(hold_dwr)='1' THEN + data_write_tmp <= data_write_tmp; + ELSIF exec(exg)='1' THEN + data_write_tmp <= OP1out; + ELSIF exec(get_ea_now)='1' AND ea_only='1' THEN -- ist for pea + data_write_tmp <= addr; + ELSIF execOPC='1' THEN + data_write_tmp <= ALUout; + ELSIF (exec_DIRECT='1' AND state="10") THEN + data_write_tmp <= data_read; + IF exec(movepl)='1' THEN + data_write_tmp(31 downto 8) <= data_write_tmp(23 downto 0); + END IF; + ELSIF exec(movepl)='1' THEN + data_write_tmp(15 downto 0) <= reg_QB(31 downto 16); + ELSIF direct_data='1' THEN + data_write_tmp <= last_data_read; + ELSIF writeSR='1'THEN + data_write_tmp(15 downto 0) <= trap_SR(7 downto 0)& Flags(7 downto 0); + ELSE + data_write_tmp <= OP2out; + END IF; + END IF; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- brief +----------------------------------------------------------------------------- +PROCESS (brief, OP1out, OP1outbrief, cpu) + BEGIN + IF brief(11)='1' THEN + OP1outbrief <= OP1out(31 downto 16); + ELSE + OP1outbrief <= (OTHERS=>OP1out(15)); + END IF; + briefdata <= OP1outbrief&OP1out(15 downto 0); + IF extAddr_Mode=1 OR (cpu(1)='1' AND extAddr_Mode=2) THEN + CASE brief(10 downto 9) IS + WHEN "00" => briefdata <= OP1outbrief&OP1out(15 downto 0); + WHEN "01" => briefdata <= OP1outbrief(14 downto 0)&OP1out(15 downto 0)&'0'; + WHEN "10" => briefdata <= OP1outbrief(13 downto 0)&OP1out(15 downto 0)&"00"; + WHEN "11" => briefdata <= OP1outbrief(12 downto 0)&OP1out(15 downto 0)&"000"; + WHEN OTHERS => NULL; + END CASE; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- MEM_IO +----------------------------------------------------------------------------- +PROCESS (clk, setdisp, memaddr_a, briefdata, memaddr_delta, setdispbyte, datatype, interrupt, rIPL_nr, IPL_vec, + memaddr_reg, reg_QA, use_base, VBR, last_data_read, trap_vector, exec, set, cpu) + BEGIN + + IF rising_edge(clk) THEN + IF clkena_lw='1' THEN +-- trap_vector(31 downto 8) <= (others => '0'); + trap_vector(31 downto 10) <= (others => '0'); +-- IF trap_addr_fault='1' THEN + IF trap_berr='1' THEN + trap_vector(9 downto 0) <= "00" & X"08"; + END IF; + IF trap_addr_error='1' THEN + trap_vector(9 downto 0) <= "00" & X"0C"; + END IF; + IF trap_illegal='1' THEN + trap_vector(9 downto 0) <= "00" & X"10"; + END IF; + IF z_error='1' THEN + trap_vector(9 downto 0) <= "00" & X"14"; + END IF; + IF exec(trap_chk)='1' THEN + trap_vector(9 downto 0) <= "00" & X"18"; + END IF; + IF trap_trapv='1' THEN + trap_vector(9 downto 0) <= "00" & X"1C"; + END IF; + IF trap_priv='1' THEN + trap_vector(9 downto 0) <= "00" & X"20"; + END IF; + IF trap_trace='1' THEN + trap_vector(9 downto 0) <= "00" & X"24"; + END IF; + IF trap_1010='1' THEN + trap_vector(9 downto 0) <= "00" & X"28"; + END IF; + IF trap_1111='1' THEN + trap_vector(9 downto 0) <= "00" & X"2C"; + END IF; + IF trap_trap='1' THEN + trap_vector(9 downto 0) <= "0010" & opcode(3 downto 0) & "00"; + END IF; + IF trap_interrupt='1' or set_vectoraddr = '1' THEN + trap_vector(9 downto 0) <= IPL_vec & "00"; --TH + END IF; + -- TH TODO: non-autovector IRQs + END IF; + END IF; + IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN + trap_vector_vbr <= trap_vector; + ELSE + trap_vector_vbr <= std_logic_vector(unsigned(trap_vector) + unsigned(VBR)); + END IF; + + memaddr_a(4 downto 0) <= "00000"; + memaddr_a(7 downto 5) <= (OTHERS=>memaddr_a(4)); + memaddr_a(15 downto 8) <= (OTHERS=>memaddr_a(7)); + memaddr_a(31 downto 16) <= (OTHERS=>memaddr_a(15)); + IF setdisp='1' THEN + IF exec(briefext)='1' THEN + memaddr_a <= std_logic_vector(unsigned(briefdata) + unsigned(memaddr_delta)); + ELSIF setdispbyte='1' THEN + memaddr_a(7 downto 0) <= last_data_read(7 downto 0); + ELSE + memaddr_a <= last_data_read; + END IF; + ELSIF set(presub)='1' THEN + IF set(longaktion)='1' THEN + memaddr_a(4 downto 0) <= "11100"; + ELSIF datatype="00" AND set(use_SP)='0' THEN + memaddr_a(4 downto 0) <= "11111"; + ELSE + memaddr_a(4 downto 0) <= "11110"; + END IF; + ELSIF interrupt='1' THEN + memaddr_a(4 downto 0) <= '1'&rIPL_nr&'0'; + END IF; + + IF rising_edge(clk) THEN + IF clkena_in='1' THEN + IF exec(get_2ndOPC)='1' OR (state="10" AND memread(0)='1') THEN + tmp_TG68_PC <= addr; + END IF; + use_base <= '0'; + IF memmaskmux(3)='0' OR exec(mem_addsub)='1' THEN + memaddr_delta <= addsub_q; + ELSIF state="01" AND exec_write_back='1' THEN + memaddr_delta <= tmp_TG68_PC; + ELSIF exec(direct_delta)='1' THEN + memaddr_delta <= data_read; + ELSIF exec(ea_to_pc)='1' AND setstate="00" THEN + memaddr_delta <= addr; + ELSIF set(addrlong)='1' THEN + memaddr_delta <= last_data_read; + ELSIF setstate="00" THEN + memaddr_delta <= TG68_PC_add; + ELSIF exec(dispouter)='1' THEN + memaddr_delta <= std_logic_vector(unsigned(ea_data)+unsigned(memaddr_a)); + ELSIF set_vectoraddr='1' THEN + memaddr_delta <= trap_vector_vbr; + ELSE + memaddr_delta <= memaddr_a; + IF interrupt='0' AND Suppress_Base='0' THEN +-- IF interrupt='0' AND Suppress_Base='0' AND setstate(1)='1' THEN + use_base <= '1'; + END IF; + END IF; + +-- IF clkena_in THEN + IF (long_done='0' AND state(1)='1') OR movem_presub='0' THEN + memaddr <= addr; + END IF; +-- END IF; + END IF; + END IF; + + addr <= std_logic_vector(unsigned(memaddr_reg)+unsigned(memaddr_delta)); + IF use_base='0' THEN + memaddr_reg <= (others=>'0'); + ELSE + memaddr_reg <= reg_QA; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- PC Calc + fetch opcode +----------------------------------------------------------------------------- +PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro_state, stop, make_trace, make_berr, IPL_nr, FlagsSR, set_rot_cnt, opcode, writePCbig, set_exec, exec, + PC_dataa, PC_datab, setnextpass, last_data_read, TG68_PC_brw, TG68_PC_word, Z_error, trap_trap, trap_trapv, interrupt, tmp_TG68_PC, TG68_PC) + BEGIN + + PC_dataa <= TG68_PC; + IF TG68_PC_brw = '1' THEN + PC_dataa <= tmp_TG68_PC; + END IF; + + PC_datab(2 downto 0) <= (others => '0'); + PC_datab(3) <= PC_datab(2); + PC_datab(7 downto 4) <= (others => PC_datab(3)); + PC_datab(15 downto 8) <= (others => PC_datab(7)); + PC_datab(31 downto 16) <= (others => PC_datab(15)); + IF interrupt='1' THEN + PC_datab(2 downto 1) <= "11"; + END IF; + IF exec(writePC_add) ='1' THEN + IF writePCbig='1' THEN + PC_datab(3) <= '1'; + PC_datab(1) <= '1'; + ELSE + PC_datab(2) <= '1'; + END IF; + IF trap_trap='1' OR trap_trapv='1' OR exec(trap_chk)='1' OR Z_error='1' THEN + PC_datab(1) <= '1'; + END IF; + ELSIF state="00" THEN + PC_datab(1) <= '1'; + END IF; + IF TG68_PC_brw = '1' THEN + IF TG68_PC_word='1' THEN + PC_datab <= last_data_read; + ELSE + PC_datab(7 downto 0) <= opcode(7 downto 0); + END IF; + END IF; + + TG68_PC_add <= std_logic_vector(unsigned(PC_dataa)+unsigned(PC_datab)); + + setopcode <= '0'; + setendOPC <= '0'; + setinterrupt <= '0'; + IF setstate="00" AND next_micro_state=idle AND setnextpass='0' AND (exec_write_back='0' OR state="11") AND set_rot_cnt="000001" AND set_exec(opcCHK)='0'THEN + setendOPC <= '1'; + IF FlagsSR(2 downto 0) + set_memmask <= "101111"; + WHEN "001" => + set_memmask <= "100111"; + WHEN "010" => + set_memmask <= "100011"; + WHEN "011" => + set_memmask <= "100001"; + WHEN OTHERS => + set_memmask <= "100000"; + END CASE; + IF setstate="00" THEN + set_memmask <= "100111"; + END IF; + END PROCESS; + +------------------------------------------------------------------------------ +--SR op +------------------------------------------------------------------------------ +PROCESS (clk, Reset, FlagsSR, last_data_read, OP2out, exec) + BEGIN + IF exec(andiSR)='1' THEN + SRin <= FlagsSR AND last_data_read(15 downto 8); + ELSIF exec(eoriSR)='1' THEN + SRin <= FlagsSR XOR last_data_read(15 downto 8); + ELSIF exec(oriSR)='1' THEN + SRin <= FlagsSR OR last_data_read(15 downto 8); + ELSE + SRin <= OP2out(15 downto 8); + END IF; + + IF rising_edge(clk) THEN + IF Reset='1' THEN + FlagsSR(5) <= '1'; + FC(2) <= '1'; + SVmode <= '1'; + preSVmode <= '1'; + FlagsSR(2 downto 0) <= "111"; + make_trace <= '0'; + ELSIF clkena_lw = '1' THEN + IF setopcode='1' THEN + make_trace <= FlagsSR(7); + IF set(changeMode)='1' THEN + SVmode <= NOT SVmode; + ELSE + SVmode <= preSVmode; + END IF; + END IF; + IF set(changeMode)='1' THEN + preSVmode <= NOT preSVmode; + FlagsSR(5) <= NOT preSVmode; + FC(2) <= NOT preSVmode; + END IF; + IF micro_state=trap3 THEN + FlagsSR(7) <= '0'; + END IF; + IF trap_trace='1' AND state="10" THEN + make_trace <= '0'; + END IF; + IF exec(directSR)='1' OR set_stop='1' THEN + FlagsSR <= data_read(15 downto 8); + END IF; + IF interrupt='1' AND trap_interrupt='1' THEN + FlagsSR(2 downto 0) <=rIPL_nr; + END IF; +-- IF exec(to_CCR)='1' AND exec(to_SR)='1' THEN + IF exec(to_SR)='1' THEN + FlagsSR(7 downto 0) <= SRin; --SR + FC(2) <= SRin(5); +-- END IF; + ELSIF exec(update_FC)='1' THEN + FC(2) <= FlagsSR(5); + END IF; + IF interrupt='1' THEN + FC(2) <= '1'; + END IF; + END IF; + END IF; + END PROCESS; + +----------------------------------------------------------------------------- +-- decode opcode +----------------------------------------------------------------------------- +PROCESS (clk, cpu, OP1out, OP2out, opcode, exe_condition, nextpass, micro_state, decodeOPC, state, setexecOPC, Flags, FlagsSR, direct_data, build_logical, + build_bcd, set_Z_error, trapd, movem_run, last_data_read, set, set_V_Flag, z_error, trap_trace, trap_interrupt, + SVmode, preSVmode, stop, long_done, ea_only, setstate, execOPC, exec_write_back, exe_datatype, + datatype, interrupt, c_out, trapmake, rot_cnt, brief, addr, + long_start, set_datatype, sndOPC, set_exec, exec, ea_build_now, reg_QA, reg_QB, make_berr, trap_berr) + BEGIN + TG68_PC_brw <= '0'; + setstate <= "00"; + Regwrena_now <= '0'; + movem_presub <= '0'; + setnextpass <= '0'; + regdirectsource <= '0'; + setdisp <= '0'; + setdispbyte <= '0'; + getbrief <= '0'; + dest_areg <= '0'; + source_areg <= '0'; + data_is_source <= '0'; + write_back <= '0'; + setstackaddr <= '0'; + writePC <= '0'; + ea_build_now <= '0'; + set_rot_bits <= "XX"; + set_rot_cnt <= "000001"; + dest_hbits <= '0'; + source_lowbits <= '0'; + source_2ndHbits <= '0'; + source_2ndLbits <= '0'; + dest_2ndHbits <= '0'; + ea_only <= '0'; + set_direct_data <= '0'; + set_exec_tas <= '0'; + trap_illegal <='0'; + trap_addr_error <= '0'; + trap_priv <='0'; + trap_1010 <='0'; + trap_1111 <='0'; + trap_trap <='0'; + trap_trapv <= '0'; + trapmake <='0'; + set_vectoraddr <='0'; + writeSR <= '0'; + set_stop <= '0'; + illegal_write_mode <= '0'; + illegal_read_mode <= '0'; + illegal_byteaddr <= '0'; + set_Z_error <= '0'; + + next_micro_state <= idle; + build_logical <= '0'; + build_bcd <= '0'; + skipFetch <= make_berr; + set_writePCbig <= '0'; +-- set_recall_last <= '0'; + set_Suppress_Base <= '0'; + set_PCbase <= '0'; + + IF rot_cnt/="000001" THEN + set_rot_cnt <= std_logic_vector(unsigned(rot_cnt)-1); + END IF; + set_datatype <= datatype; + + set <= (OTHERS=>'0'); + set_exec <= (OTHERS=>'0'); + set(update_ld) <= '0'; +-- odd_start <= '0'; +------------------------------------------------------------------------------ +--Sourcepass +------------------------------------------------------------------------------ + CASE opcode(7 downto 6) IS + WHEN "00" => datatype <= "00"; --Byte + WHEN "01" => datatype <= "01"; --Word + WHEN OTHERS => datatype <= "10"; --Long + END CASE; + + IF trapmake='1' AND trapd='0' THEN + next_micro_state <= trap0; + IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN + set(writePC_add) <= '1'; +-- set_datatype <= "10"; + END IF; + IF preSVmode='0' THEN + set(changeMode) <= '1'; + END IF; + setstate <= "01"; + END IF; + IF interrupt='1' AND trap_berr='1' THEN + next_micro_state <= trap0; + IF preSVmode='0' THEN + set(changeMode) <= '1'; + END IF; + setstate <= "01"; + END IF; + IF micro_state=int1 OR (interrupt='1' AND trap_trace='1') THEN + next_micro_state <= trap0; +-- IF cpu(0)='0' THEN +-- set_datatype <= "10"; +-- END IF; + IF preSVmode='0' THEN + set(changeMode) <= '1'; + END IF; + setstate <= "01"; + END IF; + + IF setexecOPC='1' AND FlagsSR(5)/=preSVmode THEN + set(changeMode) <= '1'; +-- setstate <= "01"; +-- next_micro_state <= nop; + END IF; + + IF interrupt='1' AND trap_interrupt='1'THEN +-- skipFetch <= '1'; + next_micro_state <= int1; + set(update_ld) <= '1'; + setstate <= "10"; + END IF; + + IF set(changeMode)='1' THEN + set(to_USP) <= '1'; + set(from_USP) <= '1'; + setstackaddr <='1'; + END IF; + + IF ea_only='0' AND set(get_ea_now)='1' THEN + setstate <= "10"; +-- set_recall_last <= '1'; +-- set(update_ld) <= '0'; + END IF; + + IF setstate(1)='1' AND set_datatype(1)='1' THEN + set(longaktion) <= '1'; + END IF; + + IF (ea_build_now='1' AND decodeOPC='1') OR exec(ea_build)='1' THEN + CASE opcode(5 downto 3) IS --source + WHEN "010"|"011"|"100" => -- -(An)+ + set(get_ea_now) <='1'; + setnextpass <= '1'; + IF opcode(3)='1' THEN --(An)+ + set(postadd) <= '1'; + IF opcode(2 downto 0)="111" THEN + set(use_SP) <= '1'; + END IF; + END IF; + IF opcode(5)='1' THEN -- -(An) + set(presub) <= '1'; + IF opcode(2 downto 0)="111" THEN + set(use_SP) <= '1'; + END IF; + END IF; + WHEN "101" => --(d16,An) + next_micro_state <= ld_dAn1; + WHEN "110" => --(d8,An,Xn) + next_micro_state <= ld_AnXn1; + getbrief <='1'; + WHEN "111" => + CASE opcode(2 downto 0) IS + WHEN "000" => --(xxxx).w + next_micro_state <= ld_nn; + WHEN "001" => --(xxxx).l + set(longaktion) <= '1'; + next_micro_state <= ld_nn; + WHEN "010" => --(d16,PC) + next_micro_state <= ld_dAn1; + set(dispouter) <= '1'; + set_Suppress_Base <= '1'; + set_PCbase <= '1'; + WHEN "011" => --(d8,PC,Xn) + next_micro_state <= ld_AnXn1; + getbrief <= '1'; + set(dispouter) <= '1'; + set_Suppress_Base <= '1'; + set_PCbase <= '1'; + WHEN "100" => --#data + setnextpass <= '1'; + set_direct_data <= '1'; + IF datatype="10" THEN + set(longaktion) <= '1'; + END IF; + WHEN OTHERS => NULL; + END CASE; + WHEN OTHERS => NULL; + END CASE; + END IF; +------------------------------------------------------------------------------ +--prepere opcode +------------------------------------------------------------------------------ + CASE opcode(15 downto 12) IS +-- 0000 ---------------------------------------------------------------------------- + WHEN "0000" => + IF opcode(8)='1' AND opcode(5 downto 3)="001" THEN --movep + datatype <= "00"; --Byte + set(use_SP) <= '1'; --addr+2 + set(no_Flags) <='1'; + IF opcode(7)='0' THEN --to register + set_exec(Regwrena) <= '1'; + set_exec(opcMOVE) <= '1'; + set(movepl) <= '1'; + END IF; + IF decodeOPC='1' THEN + IF opcode(6)='1' THEN + set(movepl) <= '1'; + END IF; + IF opcode(7)='0' THEN + set_direct_data <= '1'; -- to register + END IF; + next_micro_state <= movep1; + END IF; + IF setexecOPC='1' THEN + dest_hbits <='1'; + END IF; + ELSE + IF opcode(8)='1' OR opcode(11 downto 9)="100" THEN --Bits + set_exec(opcBITS) <= '1'; + set_exec(ea_data_OP1) <= '1'; + IF opcode(7 downto 6)/="00" THEN + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + write_back <= '1'; + END IF; + IF opcode(5 downto 4)="00" THEN + datatype <= "10"; --Long + ELSE + datatype <= "00"; --Byte + END IF; + IF opcode(8)='0' THEN + IF decodeOPC='1' THEN + next_micro_state <= nop; + set(get_2ndOPC) <= '1'; + set(ea_build) <= '1'; + END IF; + ELSE + ea_build_now <= '1'; + END IF; + ELSIF opcode(11 downto 9)="111" THEN --MOVES not in 68000 + trap_illegal <= '1'; +-- trap_addr_error <= '1'; + trapmake <= '1'; + ELSE --andi, ...xxxi + IF opcode(11 downto 9)="000" THEN --ORI + set_exec(opcOR) <= '1'; + END IF; + IF opcode(11 downto 9)="001" THEN --ANDI + set_exec(opcAND) <= '1'; + END IF; + IF opcode(11 downto 9)="010" OR opcode(11 downto 9)="011" THEN --SUBI, ADDI + set_exec(opcADD) <= '1'; + END IF; + IF opcode(11 downto 9)="101" THEN --EORI + set_exec(opcEOR) <= '1'; + END IF; + IF opcode(11 downto 9)="110" THEN --CMPI + set_exec(opcCMP) <= '1'; + END IF; + IF opcode(7)='0' AND opcode(5 downto 0)="111100" AND (set_exec(opcAND) OR set_exec(opcOR) OR set_exec(opcEOR))='1' THEN --SR + IF decodeOPC='1' AND SVmode='0' AND opcode(6)='1' THEN --SR + trap_priv <= '1'; + trapmake <= '1'; + ELSE + set(no_Flags) <= '1'; + IF decodeOPC='1' THEN + IF opcode(6)='1' THEN + set(to_SR) <= '1'; + END IF; + set(to_CCR) <= '1'; + set(andiSR) <= set_exec(opcAND); + set(eoriSR) <= set_exec(opcEOR); + set(oriSR) <= set_exec(opcOR); + setstate <= "01"; + next_micro_state <= nopnop; + END IF; + END IF; + ELSE + IF decodeOPC='1' THEN + next_micro_state <= andi; + set(ea_build) <= '1'; + set_direct_data <= '1'; + IF datatype="10" THEN + set(longaktion) <= '1'; + END IF; + END IF; + IF opcode(5 downto 4)/="00" THEN + set_exec(ea_data_OP1) <= '1'; + END IF; + IF opcode(11 downto 9)/="110" THEN --CMPI + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + write_back <= '1'; + END IF; + IF opcode(10 downto 9)="10" THEN --CMPI, SUBI + set(addsub) <= '1'; + END IF; + END IF; + END IF; + END IF; + +-- 0001, 0010, 0011 ----------------------------------------------------------------- + WHEN "0001"|"0010"|"0011" => --move.b, move.l, move.w + set_exec(opcMOVE) <= '1'; + ea_build_now <= '1'; + IF opcode(8 downto 6)="001" THEN + set(no_Flags) <= '1'; + END IF; + IF opcode(5 downto 4)="00" THEN --Dn, An + IF opcode(8 downto 7)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + END IF; + CASE opcode(13 downto 12) IS + WHEN "01" => datatype <= "00"; --Byte + WHEN "10" => datatype <= "10"; --Long + WHEN OTHERS => datatype <= "01"; --Word + END CASE; + source_lowbits <= '1'; -- Dn=> An=> + IF opcode(3)='1' THEN + source_areg <= '1'; + END IF; + + IF nextpass='1' OR opcode(5 downto 4)="00" THEN + dest_hbits <= '1'; + IF opcode(8 downto 6)/="000" THEN + dest_areg <= '1'; + END IF; + END IF; +-- IF setstate="10" THEN +-- set(update_ld) <= '0'; +-- END IF; +-- + IF micro_state=idle AND (nextpass='1' OR (opcode(5 downto 4)="00" AND decodeOPC='1')) THEN + CASE opcode(8 downto 6) IS --destination + WHEN "000"|"001" => --Dn,An + set_exec(Regwrena) <= '1'; + WHEN "010"|"011"|"100" => --destination -(an)+ + IF opcode(6)='1' THEN --(An)+ + set(postadd) <= '1'; + IF opcode(11 downto 9)="111" THEN + set(use_SP) <= '1'; + END IF; + END IF; + IF opcode(8)='1' THEN -- -(An) + set(presub) <= '1'; + IF opcode(11 downto 9)="111" THEN + set(use_SP) <= '1'; + END IF; + END IF; + setstate <= "11"; + next_micro_state <= nop; + IF nextpass='0' THEN + set(write_reg) <= '1'; + END IF; + WHEN "101" => --(d16,An) + next_micro_state <= st_dAn1; +-- getbrief <= '1'; + WHEN "110" => --(d8,An,Xn) + next_micro_state <= st_AnXn1; + getbrief <= '1'; + WHEN "111" => + CASE opcode(11 downto 9) IS + WHEN "000" => --(xxxx).w + next_micro_state <= st_nn; + WHEN "001" => --(xxxx).l + set(longaktion) <= '1'; + next_micro_state <= st_nn; + WHEN OTHERS => NULL; + END CASE; + WHEN OTHERS => NULL; + END CASE; + END IF; +---- 0100 ---------------------------------------------------------------------------- + WHEN "0100" => --rts_group + IF opcode(8)='1' THEN --lea + IF opcode(6)='1' THEN --lea + IF opcode(7)='1' THEN + source_lowbits <= '1'; +-- IF opcode(5 downto 3)="000" AND opcode(10)='0' THEN --ext + IF opcode(5 downto 4)="00" THEN --extb.l + set_exec(opcEXT) <= '1'; + set_exec(opcMOVE) <= '1'; + set_exec(Regwrena) <= '1'; +-- IF opcode(6)='0' THEN +-- datatype <= "01"; --WORD +-- END IF; + ELSE + source_areg <= '1'; + ea_only <= '1'; + set_exec(Regwrena) <= '1'; + set_exec(opcMOVE) <='1'; + set(no_Flags) <='1'; + IF opcode(5 downto 3)="010" THEN --lea (Am),An + dest_areg <= '1'; + dest_hbits <= '1'; + ELSE + ea_build_now <= '1'; + END IF; + IF set(get_ea_now)='1' THEN + setstate <= "01"; + set_direct_data <= '1'; + END IF; + IF setexecOPC='1' THEN + dest_areg <= '1'; + dest_hbits <= '1'; + END IF; + END IF; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + ELSE --chk + IF opcode(7)='1' THEN + datatype <= "01"; --Word + set(trap_chk) <= '1'; + IF (c_out(1)='0' OR OP1out(15)='1' OR OP2out(15)='1') AND exec(opcCHK)='1' THEN + trapmake <= '1'; + END IF; + ELSIF cpu(1)='1' THEN --chk long for 68020 + datatype <= "10"; --Long + set(trap_chk) <= '1'; + IF (c_out(2)='1' OR OP1out(31)='1' OR OP2out(31)='1') AND exec(opcCHK)='1' THEN + trapmake <= '1'; + END IF; + ELSE + trap_illegal <= '1'; -- chk long for 68020 + trapmake <= '1'; + END IF; + IF opcode(7)='1' OR cpu(1)='1' THEN + IF (nextpass='1' OR opcode(5 downto 4)="00") AND exec(opcCHK)='0' AND micro_state=idle THEN + set_exec(opcCHK) <= '1'; + END IF; + ea_build_now <= '1'; + set(addsub) <= '1'; + IF setexecOPC='1' THEN + dest_hbits <= '1'; + source_lowbits <='1'; + END IF; + END IF; + END IF; + ELSE + CASE opcode(11 downto 9) IS + WHEN "000"=> + IF opcode(7 downto 6)="11" THEN --move from SR + IF SR_Read=0 OR (cpu(0)='0' AND SR_Read=2) OR SVmode='1' THEN +-- IF SVmode='1' THEN + ea_build_now <= '1'; + set_exec(opcMOVESR) <= '1'; + datatype <= "01"; + write_back <='1'; -- im 68000 wird auch erst gelesen + IF cpu(0)='1' AND state="10" THEN + skipFetch <= '1'; + END IF; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + ELSE + trap_priv <= '1'; + trapmake <= '1'; + END IF; + ELSE --negx + ea_build_now <= '1'; + set_exec(use_XZFlag) <= '1'; + write_back <='1'; + set_exec(opcADD) <= '1'; + set(addsub) <= '1'; + source_lowbits <= '1'; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + IF setexecOPC='1' THEN + set(OP1out_zero) <= '1'; + END IF; + END IF; + WHEN "001"=> + IF opcode(7 downto 6)="11" THEN --move from CCR 68010 + IF SR_Read=1 OR (cpu(0)='1' AND SR_Read=2) THEN + ea_build_now <= '1'; + set_exec(opcMOVESR) <= '1'; + datatype <= "00"; + write_back <='1'; -- im 68000 wird auch erst gelesen + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + ELSE --clr + ea_build_now <= '1'; + write_back <='1'; + set_exec(opcAND) <= '1'; + IF cpu(0)='1' AND state="10" THEN + skipFetch <= '1'; + END IF; + IF setexecOPC='1' THEN + set(OP1out_zero) <= '1'; + END IF; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + END IF; + WHEN "010"=> + ea_build_now <= '1'; + IF opcode(7 downto 6)="11" THEN --move to CCR + datatype <= "01"; + source_lowbits <= '1'; + IF (decodeOPC='1' AND opcode(5 downto 4)="00") OR state="10" OR direct_data='1' THEN + set(to_CCR) <= '1'; + END IF; + ELSE --neg + write_back <='1'; + set_exec(opcADD) <= '1'; + set(addsub) <= '1'; + source_lowbits <= '1'; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + IF setexecOPC='1' THEN + set(OP1out_zero) <= '1'; + END IF; + END IF; + WHEN "011"=> --not, move toSR + IF opcode(7 downto 6)="11" THEN --move to SR + IF SVmode='1' THEN + ea_build_now <= '1'; + datatype <= "01"; + source_lowbits <= '1'; + IF (decodeOPC='1' AND opcode(5 downto 4)="00") OR state="10" OR direct_data='1' THEN + set(to_SR) <= '1'; + set(to_CCR) <= '1'; + END IF; + IF exec(to_SR)='1' OR (decodeOPC='1' AND opcode(5 downto 4)="00") OR state="10" OR direct_data='1' THEN + setstate <="01"; + END IF; + ELSE + trap_priv <= '1'; + trapmake <= '1'; + END IF; + ELSE --not + ea_build_now <= '1'; + write_back <='1'; + set_exec(opcEOR) <= '1'; + set_exec(ea_data_OP1) <= '1'; + IF opcode(5 downto 3)="000" THEN + set_exec(Regwrena) <= '1'; + END IF; + IF setexecOPC='1' THEN + set(OP2out_one) <= '1'; + END IF; + END IF; + WHEN "100"|"110"=> + IF opcode(7)='1' THEN --movem, ext + IF opcode(5 downto 3)="000" AND opcode(10)='0' THEN --ext + source_lowbits <= '1'; + set_exec(opcEXT) <= '1'; + set_exec(opcMOVE) <= '1'; + set_exec(Regwrena) <= '1'; + IF opcode(6)='0' THEN + datatype <= "01"; --WORD + END IF; + ELSE --movem +-- IF opcode(11 downto 7)="10001" OR opcode(11 downto 7)="11001" THEN --MOVEM + ea_only <= '1'; + set(no_Flags) <= '1'; + IF opcode(6)='0' THEN + datatype <= "01"; --Word transfer + END IF; + IF (opcode(5 downto 3)="100" OR opcode(5 downto 3)="011") AND state="01" THEN -- -(An), (An)+ + set_exec(save_memaddr) <= '1'; + set_exec(Regwrena) <= '1'; + END IF; + IF opcode(5 downto 3)="100" THEN -- -(An) + movem_presub <= '1'; + set(subidx) <= '1'; + END IF; + IF state="10" THEN + set(Regwrena) <= '1'; + set(opcMOVE) <= '1'; + END IF; + IF decodeOPC='1' THEN + set(get_2ndOPC) <='1'; + IF opcode(5 downto 3)="010" OR opcode(5 downto 3)="011" OR opcode(5 downto 3)="100" THEN + next_micro_state <= movem1; + ELSE + next_micro_state <= nop; + set(ea_build) <= '1'; + END IF; + END IF; + IF set(get_ea_now)='1' THEN + IF movem_run='1' THEN + set(movem_action) <= '1'; + IF opcode(10)='0' THEN + setstate <="11"; + set(write_reg) <= '1'; + ELSE + setstate <="10"; + END IF; + next_micro_state <= movem2; + set(mem_addsub) <= '1'; + ELSE + setstate <="01"; + END IF; + END IF; + END IF; + ELSE + IF opcode(10)='1' THEN --MUL.L, DIV.L 68020 +-- IF cpu(1)='1' THEN + IF (opcode(6)='1' AND (DIV_Mode=1 OR (cpu(1)='1' AND DIV_Mode=2))) OR + (opcode(6)='0' AND (MUL_Mode=1 OR (cpu(1)='1' AND MUL_Mode=2))) THEN + IF decodeOPC='1' THEN + next_micro_state <= nop; + set(get_2ndOPC) <= '1'; + set(ea_build) <= '1'; + END IF; + IF (micro_state=idle AND nextpass='1') OR (opcode(5 downto 4)="00" AND exec(ea_build)='1')THEN + setstate <="01"; + dest_2ndHbits <= '1'; + source_2ndLbits <= '1'; + IF opcode(6)='1' THEN + next_micro_state <= div1; + ELSE + next_micro_state <= mul1; + set(ld_rot_cnt) <= '1'; + END IF; + END IF; + IF z_error='0' AND set_V_Flag='0' AND set(opcDIVU)='1' THEN + set(Regwrena) <= '1'; + END IF; + source_lowbits <='1'; + IF nextpass='1' OR (opcode(5 downto 4)="00" AND decodeOPC='1') THEN + dest_hbits <= '1'; + END IF; + datatype <= "10"; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + + ELSE --pea, swap + IF opcode(6)='1' THEN + datatype <= "10"; + IF opcode(5 downto 3)="000" THEN --swap + set_exec(opcSWAP) <= '1'; + set_exec(Regwrena) <= '1'; + ELSIF opcode(5 downto 3)="001" THEN --bkpt + + ELSE --pea + ea_only <= '1'; + ea_build_now <= '1'; + IF nextpass='1' AND micro_state=idle THEN + set(presub) <= '1'; + setstackaddr <='1'; + setstate <="11"; + next_micro_state <= nop; + END IF; + IF set(get_ea_now)='1' THEN + setstate <="01"; + END IF; + END IF; + ELSE + IF opcode(5 downto 3)="001" THEN --link.l + datatype <= "10"; + set_exec(opcADD) <= '1'; --for displacement + set_exec(Regwrena) <= '1'; + set(no_Flags) <= '1'; + IF decodeOPC='1' THEN + set(linksp) <= '1'; + set(longaktion) <= '1'; + next_micro_state <= link1; + set(presub) <= '1'; + setstackaddr <='1'; + set(mem_addsub) <= '1'; + source_lowbits <= '1'; + source_areg <= '1'; + set(store_ea_data) <= '1'; + END IF; + ELSE --nbcd + ea_build_now <= '1'; + set_exec(use_XZFlag) <= '1'; + write_back <='1'; + set_exec(opcADD) <= '1'; + set_exec(opcSBCD) <= '1'; + source_lowbits <= '1'; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + IF setexecOPC='1' THEN + set(OP1out_zero) <= '1'; + END IF; + END IF; + END IF; + END IF; + END IF; +-- + WHEN "101"=> --tst, tas 4aFC - illegal + IF opcode(7 downto 2)="111111" THEN --illegal + trap_illegal <= '1'; + trapmake <= '1'; + ELSE + ea_build_now <= '1'; + IF setexecOPC='1' THEN + source_lowbits <= '1'; + IF opcode(3)='1' THEN --MC68020... + source_areg <= '1'; + END IF; + END IF; + set_exec(opcMOVE) <= '1'; + IF opcode(7 downto 6)="11" THEN --tas + set_exec_tas <= '1'; + write_back <= '1'; + datatype <= "00"; --Byte + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + END IF; + END IF; +---- WHEN "110"=> + WHEN "111"=> --4EXX +-- +-- ea_only <= '1'; +-- ea_build_now <= '1'; +-- IF nextpass='1' AND micro_state=idle THEN +-- set(presub) <= '1'; +-- setstackaddr <='1'; +-- set(mem_addsub) <= '1'; +-- setstate <="11"; +-- next_micro_state <= nop; +-- END IF; +-- IF set(get_ea_now)='1' THEN +-- setstate <="01"; +-- END IF; +-- + + + + IF opcode(7)='1' THEN --jsr, jmp + datatype <= "10"; + ea_only <= '1'; + ea_build_now <= '1'; + IF exec(ea_to_pc)='1' THEN + next_micro_state <= nop; + END IF; + IF nextpass='1' AND micro_state=idle AND opcode(6)='0' THEN + set(presub) <= '1'; + setstackaddr <='1'; + setstate <="11"; + next_micro_state <= nopnop; + END IF; +-- achtung buggefahr + IF micro_state=ld_AnXn1 AND brief(8)='0'THEN --JMP/JSR n(Ax,Dn) + skipFetch <= '1'; + END IF; + IF state="00" THEN + writePC <= '1'; + END IF; + set(hold_dwr) <= '1'; + IF set(get_ea_now)='1' THEN --jsr + IF exec(longaktion)='0' OR long_done='1' THEN + skipFetch <= '1'; + END IF; + setstate <="01"; + set(ea_to_pc) <= '1'; + END IF; + ELSE -- + CASE opcode(6 downto 0) IS + WHEN "1000000"|"1000001"|"1000010"|"1000011"|"1000100"|"1000101"|"1000110"|"1000111"| --trap + "1001000"|"1001001"|"1001010"|"1001011"|"1001100"|"1001101"|"1001110"|"1001111" => --trap + trap_trap <='1'; + trapmake <= '1'; + WHEN "1010000"|"1010001"|"1010010"|"1010011"|"1010100"|"1010101"|"1010110"|"1010111"=> --link + datatype <= "10"; + set_exec(opcADD) <= '1'; --for displacement + set_exec(Regwrena) <= '1'; + set(no_Flags) <= '1'; + IF decodeOPC='1' THEN + next_micro_state <= link1; + set(presub) <= '1'; + setstackaddr <='1'; + set(mem_addsub) <= '1'; + source_lowbits <= '1'; + source_areg <= '1'; + set(store_ea_data) <= '1'; + END IF; + + WHEN "1011000"|"1011001"|"1011010"|"1011011"|"1011100"|"1011101"|"1011110"|"1011111" => --unlink + datatype <= "10"; + set_exec(Regwrena) <= '1'; + set_exec(opcMOVE) <= '1'; + set(no_Flags) <= '1'; + IF decodeOPC='1' THEN + setstate <= "01"; + next_micro_state <= unlink1; + set(opcMOVE) <= '1'; + set(Regwrena) <= '1'; + setstackaddr <='1'; + source_lowbits <= '1'; + source_areg <= '1'; + END IF; + + WHEN "1100000"|"1100001"|"1100010"|"1100011"|"1100100"|"1100101"|"1100110"|"1100111" => --move An,USP + IF SVmode='1' THEN +-- set(no_Flags) <= '1'; + set(to_USP) <= '1'; + source_lowbits <= '1'; + source_areg <= '1'; + datatype <= "10"; + ELSE + trap_priv <= '1'; + trapmake <= '1'; + END IF; + WHEN "1101000"|"1101001"|"1101010"|"1101011"|"1101100"|"1101101"|"1101110"|"1101111" => --move USP,An + IF SVmode='1' THEN +-- set(no_Flags) <= '1'; + set(from_USP) <= '1'; + datatype <= "10"; + set_exec(Regwrena) <= '1'; + ELSE + trap_priv <= '1'; + trapmake <= '1'; + END IF; + + WHEN "1110000" => --reset + IF SVmode='0' THEN + trap_priv <= '1'; + trapmake <= '1'; + ELSE + set(opcRESET) <= '1'; + IF decodeOPC='1' THEN + set(ld_rot_cnt) <= '1'; + set_rot_cnt <= "000000"; + END IF; + END IF; + + WHEN "1110001" => --nop + + WHEN "1110010" => --stop + IF SVmode='0' THEN + trap_priv <= '1'; + trapmake <= '1'; + ELSE + IF decodeOPC='1' THEN + setnextpass <= '1'; + set_stop <= '1'; + END IF; + IF stop='1' THEN + skipFetch <= '1'; + END IF; + + END IF; + + WHEN "1110011"|"1110111" => --rte/rtr + IF SVmode='1' OR opcode(2)='1' THEN + IF decodeOPC='1' THEN + setstate <= "10"; + set(postadd) <= '1'; + setstackaddr <= '1'; + IF opcode(2)='1' THEN + set(directCCR) <= '1'; + ELSE + set(directSR) <= '1'; + END IF; + next_micro_state <= rte1; + END IF; + ELSE + trap_priv <= '1'; + trapmake <= '1'; + END IF; + + WHEN "1110101" => --rts + datatype <= "10"; + IF decodeOPC='1' THEN + setstate <= "10"; + set(postadd) <= '1'; + setstackaddr <= '1'; + set(direct_delta) <= '1'; + set(directPC) <= '1'; + next_micro_state <= nopnop; + END IF; + + WHEN "1110110" => --trapv + IF decodeOPC='1' THEN + setstate <= "01"; + END IF; + IF Flags(1)='1' AND state="01" THEN + trap_trapv <= '1'; + trapmake <= '1'; + END IF; + + WHEN "1111010"|"1111011" => --movec + IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN + trap_illegal <= '1'; + trapmake <= '1'; + ELSIF SVmode='0' THEN + trap_priv <= '1'; + trapmake <= '1'; + ELSE + datatype <= "10"; --Long + IF last_data_read(11 downto 0)=X"800" THEN + set(from_USP) <= '1'; + IF opcode(0)='1' THEN + set(to_USP) <= '1'; + END IF; + END IF; + IF opcode(0)='0' THEN + set_exec(movec_rd) <= '1'; + ELSE + set_exec(movec_wr) <= '1'; + END IF; + IF decodeOPC='1' THEN + next_micro_state <= movec1; + getbrief <='1'; + END IF; + END IF; + + WHEN OTHERS => + trap_illegal <= '1'; + trapmake <= '1'; + END CASE; + END IF; + WHEN OTHERS => NULL; + END CASE; + END IF; +-- +---- 0101 ---------------------------------------------------------------------------- + WHEN "0101" => --subq, addq + + IF opcode(7 downto 6)="11" THEN --dbcc + IF opcode(5 downto 3)="001" THEN --dbcc + IF decodeOPC='1' THEN + next_micro_state <= dbcc1; + set(OP2out_one) <= '1'; + data_is_source <= '1'; + END IF; + ELSE --Scc + datatype <= "00"; --Byte + ea_build_now <= '1'; + write_back <= '1'; + set_exec(opcScc) <= '1'; + IF cpu(0)='1' AND state="10" THEN + skipFetch <= '1'; + END IF; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + END IF; + ELSE --addq, subq + ea_build_now <= '1'; + IF opcode(5 downto 3)="001" THEN + set(no_Flags) <= '1'; + END IF; + IF opcode(8)='1' THEN + set(addsub) <= '1'; + END IF; + write_back <= '1'; + set_exec(opcADDQ) <= '1'; + set_exec(opcADD) <= '1'; + set_exec(ea_data_OP1) <= '1'; + IF opcode(5 downto 4)="00" THEN + set_exec(Regwrena) <= '1'; + END IF; + END IF; +-- +---- 0110 ---------------------------------------------------------------------------- + WHEN "0110" => --bra,bsr,bcc + datatype <= "10"; + + IF micro_state=idle THEN + IF opcode(11 downto 8)="0001" THEN --bsr + set(presub) <= '1'; + setstackaddr <='1'; + IF opcode(7 downto 0)="11111111" THEN + next_micro_state <= bsr2; + set(longaktion) <= '1'; + ELSIF opcode(7 downto 0)="00000000" THEN + next_micro_state <= bsr2; + ELSE + next_micro_state <= bsr1; + setstate <= "11"; + writePC <= '1'; + END IF; + ELSE --bra + IF opcode(7 downto 0)="11111111" THEN + next_micro_state <= bra1; + set(longaktion) <= '1'; + ELSIF opcode(7 downto 0)="00000000" THEN + next_micro_state <= bra1; + ELSE + setstate <= "01"; + next_micro_state <= bra1; + END IF; + END IF; + END IF; + +-- 0111 ---------------------------------------------------------------------------- + WHEN "0111" => --moveq +-- IF opcode(8)='0' THEN -- Cloanto's Amiga Forver ROMs have mangled moveq instructions with a 1 here... + datatype <= "10"; --Long + set_exec(Regwrena) <= '1'; + set_exec(opcMOVEQ) <= '1'; + set_exec(opcMOVE) <= '1'; + dest_hbits <= '1'; +-- ELSE +-- trap_illegal <= '1'; +-- trapmake <= '1'; +-- END IF; + +---- 1000 ---------------------------------------------------------------------------- + WHEN "1000" => --or + IF opcode(7 downto 6)="11" THEN --divu, divs + IF DIV_Mode/=3 THEN + IF opcode(5 downto 4)="00" THEN --Dn, An + regdirectsource <= '1'; + END IF; + IF (micro_state=idle AND nextpass='1') OR (opcode(5 downto 4)="00" AND decodeOPC='1') THEN + setstate <="01"; + next_micro_state <= div1; + END IF; + ea_build_now <= '1'; + IF z_error='0' AND set_V_Flag='0' THEN + set_exec(Regwrena) <= '1'; + END IF; + source_lowbits <='1'; + IF nextpass='1' OR (opcode(5 downto 4)="00" AND decodeOPC='1') THEN + dest_hbits <= '1'; + END IF; + datatype <= "01"; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + + ELSIF opcode(8)='1' AND opcode(5 downto 4)="00" THEN --sbcd, pack , unpack + IF opcode(7 downto 6)="00" THEN --sbcd + build_bcd <= '1'; + set_exec(opcADD) <= '1'; + set_exec(opcSBCD) <= '1'; + ELSE --pack, unpack + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + ELSE --or + set_exec(opcOR) <= '1'; + build_logical <= '1'; + END IF; + +---- 1001, 1101 ----------------------------------------------------------------------- + WHEN "1001"|"1101" => --sub, add + set_exec(opcADD) <= '1'; + ea_build_now <= '1'; + IF opcode(14)='0' THEN + set(addsub) <= '1'; + END IF; + IF opcode(7 downto 6)="11" THEN -- --adda, suba + IF opcode(8)='0' THEN --adda.w, suba.w + datatype <= "01"; --Word + END IF; + set_exec(Regwrena) <= '1'; + source_lowbits <='1'; + IF opcode(3)='1' THEN + source_areg <= '1'; + END IF; + set(no_Flags) <= '1'; + IF setexecOPC='1' THEN + dest_areg <='1'; + dest_hbits <= '1'; + END IF; + ELSE + IF opcode(8)='1' AND opcode(5 downto 4)="00" THEN --addx, subx + build_bcd <= '1'; + ELSE --sub, add + build_logical <= '1'; + END IF; + END IF; + +-- +---- 1010 ---------------------------------------------------------------------------- + WHEN "1010" => --Trap 1010 + trap_1010 <= '1'; + trapmake <= '1'; +---- 1011 ---------------------------------------------------------------------------- + WHEN "1011" => --eor, cmp + ea_build_now <= '1'; + IF opcode(7 downto 6)="11" THEN --CMPA + IF opcode(8)='0' THEN --cmpa.w + datatype <= "01"; --Word + set_exec(opcCPMAW) <= '1'; + END IF; + set_exec(opcCMP) <= '1'; + IF setexecOPC='1' THEN + source_lowbits <='1'; + IF opcode(3)='1' THEN + source_areg <= '1'; + END IF; + dest_areg <='1'; + dest_hbits <= '1'; + END IF; + set(addsub) <= '1'; + ELSE + IF opcode(8)='1' THEN + IF opcode(5 downto 3)="001" THEN --cmpm + set_exec(opcCMP) <= '1'; + IF decodeOPC='1' THEN + setstate <= "10"; + set(update_ld) <= '1'; + set(postadd) <= '1'; + next_micro_state <= cmpm; + END IF; + set_exec(ea_data_OP1) <= '1'; + set(addsub) <= '1'; + ELSE --EOR + build_logical <= '1'; + set_exec(opcEOR) <= '1'; + END IF; + ELSE --CMP + build_logical <= '1'; + set_exec(opcCMP) <= '1'; + set(addsub) <= '1'; + END IF; + END IF; +-- +---- 1100 ---------------------------------------------------------------------------- + WHEN "1100" => --and, exg + IF opcode(7 downto 6)="11" THEN --mulu, muls + IF MUL_Mode/=3 THEN + IF opcode(5 downto 4)="00" THEN --Dn, An + regdirectsource <= '1'; + END IF; + IF (micro_state=idle AND nextpass='1') OR (opcode(5 downto 4)="00" AND decodeOPC='1') THEN + setstate <="01"; + set(ld_rot_cnt) <= '1'; + next_micro_state <= mul1; + END IF; + ea_build_now <= '1'; + set_exec(Regwrena) <= '1'; + source_lowbits <='1'; + IF (nextpass='1') OR (opcode(5 downto 4)="00" AND decodeOPC='1') THEN + dest_hbits <= '1'; + END IF; + datatype <= "01"; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + + ELSIF opcode(8)='1' AND opcode(5 downto 4)="00" THEN --exg, abcd + IF opcode(7 downto 6)="00" THEN --abcd + build_bcd <= '1'; + set_exec(opcADD) <= '1'; + set_exec(opcABCD) <= '1'; + ELSE --exg + datatype <= "10"; + set(Regwrena) <= '1'; + set(exg) <= '1'; + IF opcode(6)='1' AND opcode(3)='1' THEN + dest_areg <= '1'; + source_areg <= '1'; + END IF; + IF decodeOPC='1' THEN + setstate <= "01"; + ELSE + dest_hbits <= '1'; + END IF; + END IF; + ELSE --and + set_exec(opcAND) <= '1'; + build_logical <= '1'; + END IF; +-- +---- 1110 ---------------------------------------------------------------------------- + WHEN "1110" => --rotation / bitfield + IF opcode(7 downto 6)="11" THEN + IF opcode(11)='0' THEN + set_exec(opcROT) <= '1'; + ea_build_now <= '1'; + datatype <= "01"; + set_rot_bits <= opcode(10 downto 9); + set_exec(ea_data_OP1) <= '1'; + write_back <= '1'; + ELSE --bitfield + IF BitField=0 OR (cpu(1)='0' AND BitField=2) THEN + trap_illegal <= '1'; + trapmake <= '1'; + ELSE + IF decodeOPC='1' THEN + next_micro_state <= nop; + set(get_2ndOPC) <= '1'; + set(ea_build) <= '1'; + END IF; + set_exec(opcBF) <= '1'; + IF opcode(10)='1' OR opcode(8)='0' THEN + set_exec(opcBFwb) <= '1'; +-- END IF; +-- IF opcode(10 downto 8)="111" THEN + set_exec(ea_data_OP1) <= '1'; + END IF; + IF opcode(10 downto 8)="010" OR opcode(10 downto 8)="100" OR opcode(10 downto 8)="110" OR opcode(10 downto 8)="111" THEN + write_back <= '1'; + END IF; + ea_only <= '1'; + IF opcode(10 downto 8)="001" OR opcode(10 downto 8)="011" OR opcode(10 downto 8)="101" THEN + set_exec(Regwrena) <= '1'; + END IF; + IF opcode(4 downto 3)="00" THEN + set_exec(Regwrena) <= '1'; + IF exec(ea_build)='1' THEN + dest_2ndHbits <= '1'; + source_2ndLbits <= '1'; + set(get_bfoffset) <='1'; + setstate <= "01"; + END IF; + END IF; + IF set(get_ea_now)='1' THEN + setstate <= "01"; + END IF; + IF exec(get_ea_now)='1' THEN + dest_2ndHbits <= '1'; + source_2ndLbits <= '1'; + set(get_bfoffset) <='1'; + setstate <= "01"; + set(mem_addsub) <='1'; + next_micro_state <= bf1; + END IF; + +-- BFINS D1,D0 s2ndHbits < D0 +-- BFEXT D0,D1 sLbits >>D0 -> D1 d2ndHbits +-- BFINS D1,(A0) s2ndHbits < (A0) +-- BFEXT (A0),D1 >>(A0) -> D1 d2ndHbits + IF setexecOPC='1' THEN + IF opcode(10 downto 8)="111" THEN --BFINS + source_2ndHbits <= '1'; + ELSE + source_lowbits <= '1'; + dest_2ndHbits <= '1'; + END IF; + END IF; + END IF; + END IF; + ELSE + set_exec(opcROT) <= '1'; + set_rot_bits <= opcode(4 downto 3); + data_is_source <= '1'; + set_exec(Regwrena) <= '1'; + IF decodeOPC='1' THEN + IF opcode(5)='1' THEN + next_micro_state <= rota1; + set(ld_rot_cnt) <= '1'; + setstate <= "01"; + ELSE + set_rot_cnt(2 downto 0) <= opcode(11 downto 9); + IF opcode(11 downto 9)="000" THEN + set_rot_cnt(3) <='1'; + ELSE + set_rot_cnt(3) <='0'; + END IF; + END IF; + END IF; + END IF; +-- +---- ---------------------------------------------------------------------------- + WHEN OTHERS => + trap_1111 <= '1'; + trapmake <= '1'; + + END CASE; + +-- use for AND, OR, EOR, CMP + IF build_logical='1' THEN + ea_build_now <= '1'; + IF set_exec(opcCMP)='0' AND (opcode(8)='0' OR opcode(5 downto 4)="00" ) THEN + set_exec(Regwrena) <= '1'; + END IF; + IF opcode(8)='1' THEN + write_back <= '1'; + set_exec(ea_data_OP1) <= '1'; + ELSE + source_lowbits <='1'; + IF opcode(3)='1' THEN --use for cmp + source_areg <= '1'; + END IF; + IF setexecOPC='1' THEN + dest_hbits <= '1'; + END IF; + END IF; + END IF; + +-- use for ABCD, SBCD + IF build_bcd='1' THEN + set_exec(use_XZFlag) <= '1'; + set_exec(ea_data_OP1) <= '1'; + write_back <= '1'; + source_lowbits <='1'; + IF opcode(3)='1' THEN + IF decodeOPC='1' THEN + setstate <= "10"; + set(update_ld) <= '1'; + set(presub) <= '1'; + next_micro_state <= op_AxAy; + dest_areg <= '1'; --??? + END IF; + ELSE + dest_hbits <= '1'; + set_exec(Regwrena) <= '1'; + END IF; + END IF; + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ + IF set_Z_error='1' THEN -- divu by zero + trapmake <= '1'; --wichtig for USP + IF trapd='0' THEN + writePC <= '1'; + END IF; + END IF; + +----------------------------------------------------------------------------- +-- execute microcode +----------------------------------------------------------------------------- + IF rising_edge(clk) THEN + IF Reset='1' THEN + micro_state <= ld_nn; + ELSIF clkena_lw='1' THEN + trapd <= trapmake; + micro_state <= next_micro_state; + END IF; + END IF; + + CASE micro_state IS + WHEN ld_nn => -- (nnnn).w/l=> + set(get_ea_now) <='1'; + setnextpass <= '1'; + set(addrlong) <= '1'; + + WHEN st_nn => -- =>(nnnn).w/l + setstate <= "11"; + set(addrlong) <= '1'; + next_micro_state <= nop; + + WHEN ld_dAn1 => -- d(An)=>, --d(PC)=> + set(get_ea_now) <='1'; + setdisp <= '1'; --word + setnextpass <= '1'; + + WHEN ld_AnXn1 => -- d(An,Xn)=>, --d(PC,Xn)=> + IF brief(8)='0' OR extAddr_Mode=0 OR (cpu(1)='0' AND extAddr_Mode=2) THEN + setdisp <= '1'; --byte + setdispbyte <= '1'; + setstate <= "01"; + set(briefext) <= '1'; + next_micro_state <= ld_AnXn2; + ELSE + IF brief(7)='1'THEN --suppress Base + set_suppress_base <= '1'; + ELSIF exec(dispouter)='1' THEN + set(dispouter) <= '1'; + END IF; + IF brief(5)='0' THEN --NULL Base Displacement + setstate <= "01"; + ELSE --WORD Base Displacement + IF brief(4)='1' THEN + set(longaktion) <= '1'; --LONG Base Displacement + END IF; + END IF; + next_micro_state <= ld_229_1; + END IF; + + WHEN ld_AnXn2 => + set(get_ea_now) <='1'; + setdisp <= '1'; --brief + setnextpass <= '1'; + +------------------------------------------------------------------------------------- + + WHEN ld_229_1 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + IF brief(5)='1' THEN --Base Displacement + setdisp <= '1'; --add last_data_read + END IF; + IF brief(6)='0' AND brief(2)='0' THEN --Preindex or Index + set(briefext) <= '1'; + setstate <= "01"; + IF brief(1 downto 0)="00" THEN + next_micro_state <= ld_AnXn2; + ELSE + next_micro_state <= ld_229_2; + END IF; + ELSE + IF brief(1 downto 0)="00" THEN + set(get_ea_now) <='1'; + setnextpass <= '1'; + ELSE + setstate <= "10"; + set(longaktion) <= '1'; + next_micro_state <= ld_229_3; + END IF; + END IF; + + WHEN ld_229_2 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + setdisp <= '1'; -- add Index + setstate <= "10"; + set(longaktion) <= '1'; + next_micro_state <= ld_229_3; + + WHEN ld_229_3 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + set_suppress_base <= '1'; + set(dispouter) <= '1'; + IF brief(1)='0' THEN --NULL Outer Displacement + setstate <= "01"; + ELSE --WORD Outer Displacement + IF brief(0)='1' THEN + set(longaktion) <= '1'; --LONG Outer Displacement + END IF; + END IF; + next_micro_state <= ld_229_4; + + WHEN ld_229_4 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + IF brief(1)='1' THEN -- Outer Displacement + setdisp <= '1'; --add last_data_read + END IF; + IF brief(6)='0' AND brief(2)='1' THEN --Postindex + set(briefext) <= '1'; + setstate <= "01"; + next_micro_state <= ld_AnXn2; + ELSE + set(get_ea_now) <='1'; + setnextpass <= '1'; + END IF; + +---------------------------------------------------------------------------------------- + WHEN st_dAn1 => -- =>d(An) + setstate <= "11"; + setdisp <= '1'; --word + next_micro_state <= nop; + + WHEN st_AnXn1 => -- =>d(An,Xn) + IF brief(8)='0' OR extAddr_Mode=0 OR (cpu(1)='0' AND extAddr_Mode=2) THEN + setdisp <= '1'; --byte + setdispbyte <= '1'; + setstate <= "01"; + set(briefext) <= '1'; + next_micro_state <= st_AnXn2; + ELSE + IF brief(7)='1'THEN --suppress Base + set_suppress_base <= '1'; +-- ELSIF exec(dispouter)='1' THEN +-- set(dispouter) <= '1'; + END IF; + IF brief(5)='0' THEN --NULL Base Displacement + setstate <= "01"; + ELSE --WORD Base Displacement + IF brief(4)='1' THEN + set(longaktion) <= '1'; --LONG Base Displacement + END IF; + END IF; + next_micro_state <= st_229_1; + END IF; + + WHEN st_AnXn2 => + setstate <= "11"; + setdisp <= '1'; --brief + next_micro_state <= nop; + +------------------------------------------------------------------------------------- + + WHEN st_229_1 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + IF brief(5)='1' THEN --Base Displacement + setdisp <= '1'; --add last_data_read + END IF; + IF brief(6)='0' AND brief(2)='0' THEN --Preindex or Index + set(briefext) <= '1'; + setstate <= "01"; + IF brief(1 downto 0)="00" THEN + next_micro_state <= st_AnXn2; + ELSE + next_micro_state <= st_229_2; + END IF; + ELSE + IF brief(1 downto 0)="00" THEN + setstate <= "11"; + next_micro_state <= nop; + ELSE + set(hold_dwr) <= '1'; + setstate <= "10"; + set(longaktion) <= '1'; + next_micro_state <= st_229_3; + END IF; + END IF; + + WHEN st_229_2 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + setdisp <= '1'; -- add Index + set(hold_dwr) <= '1'; + setstate <= "10"; + set(longaktion) <= '1'; + next_micro_state <= st_229_3; + + WHEN st_229_3 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + set(hold_dwr) <= '1'; + set_suppress_base <= '1'; + set(dispouter) <= '1'; + IF brief(1)='0' THEN --NULL Outer Displacement + setstate <= "01"; + ELSE --WORD Outer Displacement + IF brief(0)='1' THEN + set(longaktion) <= '1'; --LONG Outer Displacement + END IF; + END IF; + next_micro_state <= st_229_4; + + WHEN st_229_4 => -- (bd,An,Xn)=>, --(bd,PC,Xn)=> + set(hold_dwr) <= '1'; + IF brief(1)='1' THEN -- Outer Displacement + setdisp <= '1'; --add last_data_read + END IF; + IF brief(6)='0' AND brief(2)='1' THEN --Postindex + set(briefext) <= '1'; + setstate <= "01"; + next_micro_state <= st_AnXn2; + ELSE + setstate <= "11"; + next_micro_state <= nop; + END IF; + +---------------------------------------------------------------------------------------- + WHEN bra1 => --bra + IF exe_condition='1' THEN + TG68_PC_brw <= '1'; --pc+0000 + next_micro_state <= nop; + skipFetch <= '1'; + END IF; + + WHEN bsr1 => --bsr short + TG68_PC_brw <= '1'; + next_micro_state <= nop; + + WHEN bsr2 => --bsr + IF long_start='0' THEN + TG68_PC_brw <= '1'; + END IF; + skipFetch <= '1'; + set(longaktion) <= '1'; + writePC <= '1'; + setstate <= "11"; + next_micro_state <= nopnop; + setstackaddr <='1'; + WHEN nopnop => --bsr + next_micro_state <= nop; + + WHEN dbcc1 => --dbcc + IF exe_condition='0' THEN + Regwrena_now <= '1'; + IF c_out(1)='1' THEN + skipFetch <= '1'; + next_micro_state <= nop; + TG68_PC_brw <= '1'; + END IF; + END IF; + + WHEN movem1 => --movem + IF last_data_read(15 downto 0)/=X"0000" THEN + setstate <="01"; + IF opcode(5 downto 3)="100" THEN + set(mem_addsub) <= '1'; + END IF; + next_micro_state <= movem2; + END IF; + WHEN movem2 => --movem + IF movem_run='0' THEN + setstate <="01"; + ELSE + set(movem_action) <= '1'; + set(mem_addsub) <= '1'; + next_micro_state <= movem2; + IF opcode(10)='0' THEN + setstate <="11"; + set(write_reg) <= '1'; + ELSE + setstate <="10"; + END IF; + END IF; + + WHEN andi => --andi + IF opcode(5 downto 4)/="00" THEN + setnextpass <= '1'; + END IF; + + WHEN op_AxAy => -- op -(Ax),-(Ay) + set_direct_data <= '1'; + set(presub) <= '1'; + dest_hbits <= '1'; + dest_areg <= '1'; + setstate <= "10"; + + WHEN cmpm => -- cmpm (Ay)+,(Ax)+ + set_direct_data <= '1'; + set(postadd) <= '1'; + dest_hbits <= '1'; + dest_areg <= '1'; + setstate <= "10"; + + WHEN link1 => -- link + setstate <="11"; + source_areg <= '1'; + set(opcMOVE) <= '1'; + set(Regwrena) <= '1'; + next_micro_state <= link2; + WHEN link2 => -- link + setstackaddr <='1'; + set(ea_data_OP2) <= '1'; + + WHEN unlink1 => -- unlink + setstate <="10"; + setstackaddr <='1'; + set(postadd) <= '1'; + next_micro_state <= unlink2; + WHEN unlink2 => -- unlink + set(ea_data_OP2) <= '1'; + + WHEN trap0 => -- TRAP + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + IF VBR_Stackframe=1 OR (cpu(0)='1' AND VBR_Stackframe=2) THEN --68010 + set(writePC_add) <= '1'; + datatype <= "01"; +-- set_datatype <= "10"; + next_micro_state <= trap1; + ELSE + IF trap_interrupt='1' OR trap_trace='1' OR trap_berr='1' THEN + writePC <= '1'; + END IF; + datatype <= "10"; + next_micro_state <= trap2; + END IF; + WHEN trap1 => -- TRAP + IF trap_interrupt='1' OR trap_trace='1' THEN + writePC <= '1'; + END IF; + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + datatype <= "10"; + next_micro_state <= trap2; + WHEN trap2 => -- TRAP + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + datatype <= "01"; + writeSR <= '1'; + IF trap_berr='1' THEN + next_micro_state <= trap4; + ELSE + next_micro_state <= trap3; + END IF; + WHEN trap3 => -- TRAP + set_vectoraddr <= '1'; + datatype <= "10"; + set(direct_delta) <= '1'; + set(directPC) <= '1'; + setstate <= "10"; + next_micro_state <= nopnop; + + WHEN trap4 => -- TRAP + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + datatype <= "01"; + writeSR <= '1'; + next_micro_state <= trap5; + WHEN trap5 => -- TRAP + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + datatype <= "10"; + writeSR <= '1'; + next_micro_state <= trap6; + WHEN trap6 => -- TRAP + set(presub) <= '1'; + setstackaddr <='1'; + setstate <= "11"; + datatype <= "01"; + writeSR <= '1'; + next_micro_state <= trap3; + + WHEN rte1 => -- RTE + datatype <= "10"; + setstate <= "10"; + set(postadd) <= '1'; + setstackaddr <= '1'; + IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN + set(direct_delta) <= '1'; + END IF; + set(directPC) <= '1'; + next_micro_state <= rte2; + WHEN rte2 => -- RTE + datatype <= "01"; + set(update_FC) <= '1'; + IF VBR_Stackframe=1 OR (cpu(0)='1' AND VBR_Stackframe=2) THEN + setstate <= "10"; + set(postadd) <= '1'; + setstackaddr <= '1'; + next_micro_state <= rte3; + ELSE + next_micro_state <= nop; + END IF; + WHEN rte3 => -- RTE + next_micro_state <= nop; +-- set(update_FC) <= '1'; + + WHEN movec1 => -- MOVEC + set(briefext) <= '1'; + set_writePCbig <='1'; + IF (brief(11 downto 0)=X"000" OR brief(11 downto 0)=X"001" OR brief(11 downto 0)=X"800" OR brief(11 downto 0)=X"801") OR + (cpu(1)='1' AND (brief(11 downto 0)=X"002" OR brief(11 downto 0)=X"802" OR brief(11 downto 0)=X"803" OR brief(11 downto 0)=X"804")) THEN + IF opcode(0)='0' THEN + set(Regwrena) <= '1'; + END IF; +-- ELSIF brief(11 downto 0)=X"800"OR brief(11 downto 0)=X"001" OR brief(11 downto 0)=X"000" THEN +-- trap_addr_error <= '1'; +-- trapmake <= '1'; + ELSE + trap_illegal <= '1'; + trapmake <= '1'; + END IF; + + WHEN movep1 => -- MOVEP d(An) + setdisp <= '1'; + set(mem_addsub) <= '1'; + set(mem_byte) <= '1'; + set(OP1addr) <= '1'; + IF opcode(6)='1' THEN + set(movepl) <= '1'; + END IF; + IF opcode(7)='0' THEN + setstate <= "10"; + ELSE + setstate <= "11"; + END IF; + next_micro_state <= movep2; + WHEN movep2 => + IF opcode(6)='1' THEN + set(mem_addsub) <= '1'; + set(OP1addr) <= '1'; + END IF; + IF opcode(7)='0' THEN + setstate <= "10"; + ELSE + setstate <= "11"; + END IF; + next_micro_state <= movep3; + WHEN movep3 => + IF opcode(6)='1' THEN + set(mem_addsub) <= '1'; + set(OP1addr) <= '1'; + set(mem_byte) <= '1'; + IF opcode(7)='0' THEN + setstate <= "10"; + ELSE + setstate <= "11"; + END IF; + next_micro_state <= movep4; + ELSE + datatype <= "01"; --Word + END IF; + WHEN movep4 => + IF opcode(7)='0' THEN + setstate <= "10"; + ELSE + setstate <= "11"; + END IF; + next_micro_state <= movep5; + WHEN movep5 => + datatype <= "10"; --Long + + WHEN mul1 => -- mulu + IF opcode(15)='1' OR MUL_Mode=0 THEN + set_rot_cnt <= "001110"; + ELSE + set_rot_cnt <= "011110"; + END IF; + setstate <="01"; + next_micro_state <= mul2; + WHEN mul2 => -- mulu + setstate <="01"; + IF rot_cnt="00001" THEN + next_micro_state <= mul_end1; + ELSE + next_micro_state <= mul2; + END IF; + WHEN mul_end1 => -- mulu + datatype <= "10"; + set(opcMULU) <= '1'; + IF opcode(15)='0' AND (MUL_Mode=1 OR MUL_Mode=2) THEN + dest_2ndHbits <= '1'; + source_2ndLbits <= '1';--??? + set(write_lowlong) <= '1'; + IF sndOPC(10)='1' THEN + setstate <="01"; + next_micro_state <= mul_end2; + END IF; + set(Regwrena) <= '1'; + END IF; + datatype <= "10"; + WHEN mul_end2 => -- divu + set(write_reminder) <= '1'; + set(Regwrena) <= '1'; + set(opcMULU) <= '1'; + + WHEN div1 => -- divu + setstate <="01"; + next_micro_state <= div2; + WHEN div2 => -- divu + IF (OP2out(31 downto 16)=x"0000" OR opcode(15)='1' OR DIV_Mode=0) AND OP2out(15 downto 0)=x"0000" THEN --div zero + set_Z_error <= '1'; + ELSE + next_micro_state <= div3; + END IF; + set(ld_rot_cnt) <= '1'; + setstate <="01"; + WHEN div3 => -- divu + IF opcode(15)='1' OR DIV_Mode=0 THEN + set_rot_cnt <= "001101"; + ELSE + set_rot_cnt <= "011101"; + END IF; + setstate <="01"; + next_micro_state <= div4; + WHEN div4 => -- divu + setstate <="01"; + IF rot_cnt="00001" THEN + next_micro_state <= div_end1; + ELSE + next_micro_state <= div4; + END IF; + WHEN div_end1 => -- divu + IF opcode(15)='0' AND (DIV_Mode=1 OR DIV_Mode=2) THEN + set(write_reminder) <= '1'; + next_micro_state <= div_end2; + setstate <="01"; + END IF; + set(opcDIVU) <= '1'; + datatype <= "10"; + WHEN div_end2 => -- divu + dest_2ndHbits <= '1'; + source_2ndLbits <= '1';--??? + set(opcDIVU) <= '1'; + + WHEN rota1 => + IF OP2out(5 downto 0)/="000000" THEN + set_rot_cnt <= OP2out(5 downto 0); + ELSE + set_exec(rot_nop) <= '1'; + END IF; + + WHEN bf1 => + setstate <="10"; + + WHEN OTHERS => NULL; + END CASE; + END PROCESS; + +----------------------------------------------------------------------------- +-- MOVEC +----------------------------------------------------------------------------- +PROCESS (clk, VBR, CACR, brief) + BEGIN + IF rising_edge(clk) THEN + IF Reset = '1' THEN + VBR <= (OTHERS => '0'); + CACR <= (OTHERS => '0'); + ELSIF clkena_lw='1' AND exec(movec_wr)='1' THEN + CASE brief(11 downto 0) IS + WHEN X"002" => CACR <= reg_QA(3 downto 0); + WHEN X"801" => VBR <= reg_QA; + WHEN OTHERS => NULL; + END CASE; + END IF; + END IF; + movec_data <= (OTHERS=>'0'); + CASE brief(11 downto 0) IS + WHEN X"002" => movec_data(3 downto 0) <= CACR; + WHEN X"801" => --IF VBR_Stackframe=1 OR (cpu(0)='1' AND VBR_Stackframe=2) THEN + movec_data <= VBR; + --END IF; + WHEN OTHERS => NULL; + END CASE; + END PROCESS; + +----------------------------------------------------------------------------- +-- Conditions +----------------------------------------------------------------------------- +PROCESS (exe_opcode, Flags) + BEGIN + CASE exe_opcode(11 downto 8) IS + WHEN X"0" => exe_condition <= '1'; + WHEN X"1" => exe_condition <= '0'; + WHEN X"2" => exe_condition <= NOT Flags(0) AND NOT Flags(2); + WHEN X"3" => exe_condition <= Flags(0) OR Flags(2); + WHEN X"4" => exe_condition <= NOT Flags(0); + WHEN X"5" => exe_condition <= Flags(0); + WHEN X"6" => exe_condition <= NOT Flags(2); + WHEN X"7" => exe_condition <= Flags(2); + WHEN X"8" => exe_condition <= NOT Flags(1); + WHEN X"9" => exe_condition <= Flags(1); + WHEN X"a" => exe_condition <= NOT Flags(3); + WHEN X"b" => exe_condition <= Flags(3); + WHEN X"c" => exe_condition <= (Flags(3) AND Flags(1)) OR (NOT Flags(3) AND NOT Flags(1)); + WHEN X"d" => exe_condition <= (Flags(3) AND NOT Flags(1)) OR (NOT Flags(3) AND Flags(1)); + WHEN X"e" => exe_condition <= (Flags(3) AND Flags(1) AND NOT Flags(2)) OR (NOT Flags(3) AND NOT Flags(1) AND NOT Flags(2)); + WHEN X"f" => exe_condition <= (Flags(3) AND NOT Flags(1)) OR (NOT Flags(3) AND Flags(1)) OR Flags(2); + WHEN OTHERS => NULL; + END CASE; + END PROCESS; + +----------------------------------------------------------------------------- +-- Movem +----------------------------------------------------------------------------- +PROCESS (clk) + BEGIN + IF rising_edge(clk) THEN + IF clkena_lw='1' THEN + movem_actiond <= exec(movem_action); + IF decodeOPC='1' THEN + sndOPC <= data_read(15 downto 0); + ELSIF exec(movem_action)='1' OR set(movem_action) ='1' THEN + CASE movem_regaddr IS + WHEN "0000" => sndOPC(0) <= '0'; + WHEN "0001" => sndOPC(1) <= '0'; + WHEN "0010" => sndOPC(2) <= '0'; + WHEN "0011" => sndOPC(3) <= '0'; + WHEN "0100" => sndOPC(4) <= '0'; + WHEN "0101" => sndOPC(5) <= '0'; + WHEN "0110" => sndOPC(6) <= '0'; + WHEN "0111" => sndOPC(7) <= '0'; + WHEN "1000" => sndOPC(8) <= '0'; + WHEN "1001" => sndOPC(9) <= '0'; + WHEN "1010" => sndOPC(10) <= '0'; + WHEN "1011" => sndOPC(11) <= '0'; + WHEN "1100" => sndOPC(12) <= '0'; + WHEN "1101" => sndOPC(13) <= '0'; + WHEN "1110" => sndOPC(14) <= '0'; + WHEN "1111" => sndOPC(15) <= '0'; + WHEN OTHERS => NULL; + END CASE; + END IF; + END IF; + END IF; + END PROCESS; + +PROCESS (sndOPC, movem_mux) + BEGIN + movem_regaddr <="0000"; + movem_run <= '1'; + IF sndOPC(3 downto 0)="0000" THEN + IF sndOPC(7 downto 4)="0000" THEN + movem_regaddr(3) <= '1'; + IF sndOPC(11 downto 8)="0000" THEN + IF sndOPC(15 downto 12)="0000" THEN + movem_run <= '0'; + END IF; + movem_regaddr(2) <= '1'; + movem_mux <= sndOPC(15 downto 12); + ELSE + movem_mux <= sndOPC(11 downto 8); + END IF; + ELSE + movem_mux <= sndOPC(7 downto 4); + movem_regaddr(2) <= '1'; + END IF; + ELSE + movem_mux <= sndOPC(3 downto 0); + END IF; + IF movem_mux(1 downto 0)="00" THEN + movem_regaddr(1) <= '1'; + IF movem_mux(2)='0' THEN + movem_regaddr(0) <= '1'; + END IF; + ELSE + IF movem_mux(0)='0' THEN + movem_regaddr(0) <= '1'; + END IF; + END IF; + END PROCESS; +END; diff --git a/tests/tg68k/testcode.s b/tests/tg68k/testcode.s new file mode 100644 index 0000000..0b213fa --- /dev/null +++ b/tests/tg68k/testcode.s @@ -0,0 +1,35 @@ + org $fc0000 ; + +start: +; jsr sub + move #$a700,sr ; Enter trace mode +; nop ; + lsr #5,d0 + +; move.l #$3237,d0 +; pack d0,d5,#$0123 ; d5 = $3a +; unpk d5,d6,#$4040 ; d6 = $434a +; move.l #testdata1,a0 +; move.l #testdata2,a1 +; pack -(a0),-(a1),#$1122 +; pack -(a0),-(a1),#$f0f0 +; unpk -(a0),-(a1),#$1122 +; unpk -(a0),-(a1),#$f0f0 +loop: move d0,d0 + bra.s loop + +sub: rts + + dc.l 0,0,0,0 + + dc.l $12345678 +testdata1: + dc.l $aaaaaaaa + + dc.l $c0ffee12 +testdata2: + dc.l $55555555 + + org $fc0100 ; +trace: rte + diff --git a/tests/tg68k/testcode_defs_pack.vhd b/tests/tg68k/testcode_defs_pack.vhd new file mode 100644 index 0000000..b2f05ef --- /dev/null +++ b/tests/tg68k/testcode_defs_pack.vhd @@ -0,0 +1,44 @@ +-- +-- Example ROM definitions pack for type-independent srecord output +-- Copyright (C) 2000 Hendrik De Vloed - hendrik.devloed@rug.ac.be +-- Copyright (C) 2007 Peter Miller +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see +-- . +-- + +library IEEE; +use IEEE.std_logic_1164.all; +package testcode_defs_pack is + -- The basic type of the data word stored in the ROM. Define + -- your ROM's width here. + subtype testcode_rom_entry is std_logic_vector(15 downto 0); + -- The type used to represent the ROM. Define your range + -- here. + type testcode_rom_array is array(0 to 511) of testcode_rom_entry; + -- The "Don't Care" value used to fill unused parts of the ROM. + constant testcode_dont_care : testcode_rom_entry := (others=>'-'); + -- The conversion function used to make srecord's output + -- independent of the actual rom_entry type and # of bits. + function testcode_entry(data:natural) return testcode_rom_entry; +end package; + +library IEEE; +use IEEE.numeric_std.all; +package body testcode_defs_pack is + function testcode_entry(data:natural) return testcode_rom_entry is + begin + return std_logic_vector(to_unsigned(data,testcode_rom_entry'length)); + end testcode_entry; +end package body; diff --git a/tests/tg68k/tg68k_tb.sav b/tests/tg68k/tg68k_tb.sav new file mode 100644 index 0000000..d6dbc86 --- /dev/null +++ b/tests/tg68k/tg68k_tb.sav @@ -0,0 +1,86 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Wed Jun 3 09:28:41 2015 +[*] +[dumpfile] "/home/tharbaum/tmp/mist/hdl/tests/tg68k/tg68k_tb.ghw" +[dumpfile_mtime] "Wed Jun 3 09:27:59 2015" +[dumpfile_size] 199850 +[savefile] "/home/tharbaum/tmp/mist/hdl/tests/tg68k/tg68k_tb.sav" +[timestart] 1181500000 +[size] 1240 816 +[pos] 11 123 +*-27.000000 2190000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] top. +[treeopen] top.tg68k_tb. +[treeopen] top.tg68k_tb.tg68k. +[sst_width] 202 +[signals_width] 257 +[sst_expanded] 1 +[sst_vpaned_height] 434 +@28 +top.tg68k_tb.clk +@22 +#{top.tg68k_tb.addr[31:0]} top.tg68k_tb.addr[31] top.tg68k_tb.addr[30] top.tg68k_tb.addr[29] top.tg68k_tb.addr[28] top.tg68k_tb.addr[27] top.tg68k_tb.addr[26] top.tg68k_tb.addr[25] top.tg68k_tb.addr[24] top.tg68k_tb.addr[23] top.tg68k_tb.addr[22] top.tg68k_tb.addr[21] top.tg68k_tb.addr[20] top.tg68k_tb.addr[19] top.tg68k_tb.addr[18] top.tg68k_tb.addr[17] top.tg68k_tb.addr[16] top.tg68k_tb.addr[15] top.tg68k_tb.addr[14] top.tg68k_tb.addr[13] top.tg68k_tb.addr[12] top.tg68k_tb.addr[11] top.tg68k_tb.addr[10] top.tg68k_tb.addr[9] top.tg68k_tb.addr[8] top.tg68k_tb.addr[7] top.tg68k_tb.addr[6] top.tg68k_tb.addr[5] top.tg68k_tb.addr[4] top.tg68k_tb.addr[3] top.tg68k_tb.addr[2] top.tg68k_tb.addr[1] top.tg68k_tb.addr[0] +@28 +#{top.tg68k_tb.tg68k.busstate[1:0]} top.tg68k_tb.tg68k.busstate[1] top.tg68k_tb.tg68k.busstate[0] +@22 +#{top.tg68k_tb.din[15:0]} top.tg68k_tb.din[15] top.tg68k_tb.din[14] top.tg68k_tb.din[13] top.tg68k_tb.din[12] top.tg68k_tb.din[11] top.tg68k_tb.din[10] top.tg68k_tb.din[9] top.tg68k_tb.din[8] top.tg68k_tb.din[7] top.tg68k_tb.din[6] top.tg68k_tb.din[5] top.tg68k_tb.din[4] top.tg68k_tb.din[3] top.tg68k_tb.din[2] top.tg68k_tb.din[1] top.tg68k_tb.din[0] +#{top.tg68k_tb.tg68k.data_write[15:0]} top.tg68k_tb.tg68k.data_write[15] top.tg68k_tb.tg68k.data_write[14] top.tg68k_tb.tg68k.data_write[13] top.tg68k_tb.tg68k.data_write[12] top.tg68k_tb.tg68k.data_write[11] top.tg68k_tb.tg68k.data_write[10] top.tg68k_tb.tg68k.data_write[9] top.tg68k_tb.tg68k.data_write[8] top.tg68k_tb.tg68k.data_write[7] top.tg68k_tb.tg68k.data_write[6] top.tg68k_tb.tg68k.data_write[5] top.tg68k_tb.tg68k.data_write[4] top.tg68k_tb.tg68k.data_write[3] top.tg68k_tb.tg68k.data_write[2] top.tg68k_tb.tg68k.data_write[1] top.tg68k_tb.tg68k.data_write[0] +#{top.tg68k_tb.tg68k.exe_opcode[15:0]} top.tg68k_tb.tg68k.exe_opcode[15] top.tg68k_tb.tg68k.exe_opcode[14] top.tg68k_tb.tg68k.exe_opcode[13] top.tg68k_tb.tg68k.exe_opcode[12] top.tg68k_tb.tg68k.exe_opcode[11] top.tg68k_tb.tg68k.exe_opcode[10] top.tg68k_tb.tg68k.exe_opcode[9] top.tg68k_tb.tg68k.exe_opcode[8] top.tg68k_tb.tg68k.exe_opcode[7] top.tg68k_tb.tg68k.exe_opcode[6] top.tg68k_tb.tg68k.exe_opcode[5] top.tg68k_tb.tg68k.exe_opcode[4] top.tg68k_tb.tg68k.exe_opcode[3] top.tg68k_tb.tg68k.exe_opcode[2] top.tg68k_tb.tg68k.exe_opcode[1] top.tg68k_tb.tg68k.exe_opcode[0] +@28 +top.tg68k_tb.tg68k.rdindex_a +@22 +#{top.tg68k_tb.tg68k.reg_qa[31:0]} top.tg68k_tb.tg68k.reg_qa[31] top.tg68k_tb.tg68k.reg_qa[30] top.tg68k_tb.tg68k.reg_qa[29] top.tg68k_tb.tg68k.reg_qa[28] top.tg68k_tb.tg68k.reg_qa[27] top.tg68k_tb.tg68k.reg_qa[26] top.tg68k_tb.tg68k.reg_qa[25] top.tg68k_tb.tg68k.reg_qa[24] top.tg68k_tb.tg68k.reg_qa[23] top.tg68k_tb.tg68k.reg_qa[22] top.tg68k_tb.tg68k.reg_qa[21] top.tg68k_tb.tg68k.reg_qa[20] top.tg68k_tb.tg68k.reg_qa[19] top.tg68k_tb.tg68k.reg_qa[18] top.tg68k_tb.tg68k.reg_qa[17] top.tg68k_tb.tg68k.reg_qa[16] top.tg68k_tb.tg68k.reg_qa[15] top.tg68k_tb.tg68k.reg_qa[14] top.tg68k_tb.tg68k.reg_qa[13] top.tg68k_tb.tg68k.reg_qa[12] top.tg68k_tb.tg68k.reg_qa[11] top.tg68k_tb.tg68k.reg_qa[10] top.tg68k_tb.tg68k.reg_qa[9] top.tg68k_tb.tg68k.reg_qa[8] top.tg68k_tb.tg68k.reg_qa[7] top.tg68k_tb.tg68k.reg_qa[6] top.tg68k_tb.tg68k.reg_qa[5] top.tg68k_tb.tg68k.reg_qa[4] top.tg68k_tb.tg68k.reg_qa[3] top.tg68k_tb.tg68k.reg_qa[2] top.tg68k_tb.tg68k.reg_qa[1] top.tg68k_tb.tg68k.reg_qa[0] +@28 +top.tg68k_tb.tg68k.rdindex_b +@22 +#{top.tg68k_tb.tg68k.reg_qb[31:0]} top.tg68k_tb.tg68k.reg_qb[31] top.tg68k_tb.tg68k.reg_qb[30] top.tg68k_tb.tg68k.reg_qb[29] top.tg68k_tb.tg68k.reg_qb[28] top.tg68k_tb.tg68k.reg_qb[27] top.tg68k_tb.tg68k.reg_qb[26] top.tg68k_tb.tg68k.reg_qb[25] top.tg68k_tb.tg68k.reg_qb[24] top.tg68k_tb.tg68k.reg_qb[23] top.tg68k_tb.tg68k.reg_qb[22] top.tg68k_tb.tg68k.reg_qb[21] top.tg68k_tb.tg68k.reg_qb[20] top.tg68k_tb.tg68k.reg_qb[19] top.tg68k_tb.tg68k.reg_qb[18] top.tg68k_tb.tg68k.reg_qb[17] top.tg68k_tb.tg68k.reg_qb[16] top.tg68k_tb.tg68k.reg_qb[15] top.tg68k_tb.tg68k.reg_qb[14] top.tg68k_tb.tg68k.reg_qb[13] top.tg68k_tb.tg68k.reg_qb[12] top.tg68k_tb.tg68k.reg_qb[11] top.tg68k_tb.tg68k.reg_qb[10] top.tg68k_tb.tg68k.reg_qb[9] top.tg68k_tb.tg68k.reg_qb[8] top.tg68k_tb.tg68k.reg_qb[7] top.tg68k_tb.tg68k.reg_qb[6] top.tg68k_tb.tg68k.reg_qb[5] top.tg68k_tb.tg68k.reg_qb[4] top.tg68k_tb.tg68k.reg_qb[3] top.tg68k_tb.tg68k.reg_qb[2] top.tg68k_tb.tg68k.reg_qb[1] top.tg68k_tb.tg68k.reg_qb[0] +@28 +top.tg68k_tb.tg68k.bwrena +@22 +#{top.tg68k_tb.tg68k.regfile[0][31:0]} top.tg68k_tb.tg68k.regfile[0][31] top.tg68k_tb.tg68k.regfile[0][30] top.tg68k_tb.tg68k.regfile[0][29] top.tg68k_tb.tg68k.regfile[0][28] top.tg68k_tb.tg68k.regfile[0][27] top.tg68k_tb.tg68k.regfile[0][26] top.tg68k_tb.tg68k.regfile[0][25] top.tg68k_tb.tg68k.regfile[0][24] top.tg68k_tb.tg68k.regfile[0][23] top.tg68k_tb.tg68k.regfile[0][22] top.tg68k_tb.tg68k.regfile[0][21] top.tg68k_tb.tg68k.regfile[0][20] top.tg68k_tb.tg68k.regfile[0][19] top.tg68k_tb.tg68k.regfile[0][18] top.tg68k_tb.tg68k.regfile[0][17] top.tg68k_tb.tg68k.regfile[0][16] top.tg68k_tb.tg68k.regfile[0][15] top.tg68k_tb.tg68k.regfile[0][14] top.tg68k_tb.tg68k.regfile[0][13] top.tg68k_tb.tg68k.regfile[0][12] top.tg68k_tb.tg68k.regfile[0][11] top.tg68k_tb.tg68k.regfile[0][10] top.tg68k_tb.tg68k.regfile[0][9] top.tg68k_tb.tg68k.regfile[0][8] top.tg68k_tb.tg68k.regfile[0][7] top.tg68k_tb.tg68k.regfile[0][6] top.tg68k_tb.tg68k.regfile[0][5] top.tg68k_tb.tg68k.regfile[0][4] top.tg68k_tb.tg68k.regfile[0][3] top.tg68k_tb.tg68k.regfile[0][2] top.tg68k_tb.tg68k.regfile[0][1] top.tg68k_tb.tg68k.regfile[0][0] +#{top.tg68k_tb.tg68k.regfile[5][31:0]} top.tg68k_tb.tg68k.regfile[5][31] top.tg68k_tb.tg68k.regfile[5][30] top.tg68k_tb.tg68k.regfile[5][29] top.tg68k_tb.tg68k.regfile[5][28] top.tg68k_tb.tg68k.regfile[5][27] top.tg68k_tb.tg68k.regfile[5][26] top.tg68k_tb.tg68k.regfile[5][25] top.tg68k_tb.tg68k.regfile[5][24] top.tg68k_tb.tg68k.regfile[5][23] top.tg68k_tb.tg68k.regfile[5][22] top.tg68k_tb.tg68k.regfile[5][21] top.tg68k_tb.tg68k.regfile[5][20] top.tg68k_tb.tg68k.regfile[5][19] top.tg68k_tb.tg68k.regfile[5][18] top.tg68k_tb.tg68k.regfile[5][17] top.tg68k_tb.tg68k.regfile[5][16] top.tg68k_tb.tg68k.regfile[5][15] top.tg68k_tb.tg68k.regfile[5][14] top.tg68k_tb.tg68k.regfile[5][13] top.tg68k_tb.tg68k.regfile[5][12] top.tg68k_tb.tg68k.regfile[5][11] top.tg68k_tb.tg68k.regfile[5][10] top.tg68k_tb.tg68k.regfile[5][9] top.tg68k_tb.tg68k.regfile[5][8] top.tg68k_tb.tg68k.regfile[5][7] top.tg68k_tb.tg68k.regfile[5][6] top.tg68k_tb.tg68k.regfile[5][5] top.tg68k_tb.tg68k.regfile[5][4] top.tg68k_tb.tg68k.regfile[5][3] top.tg68k_tb.tg68k.regfile[5][2] top.tg68k_tb.tg68k.regfile[5][1] top.tg68k_tb.tg68k.regfile[5][0] +#{top.tg68k_tb.tg68k.regfile[6][31:0]} top.tg68k_tb.tg68k.regfile[6][31] top.tg68k_tb.tg68k.regfile[6][30] top.tg68k_tb.tg68k.regfile[6][29] top.tg68k_tb.tg68k.regfile[6][28] top.tg68k_tb.tg68k.regfile[6][27] top.tg68k_tb.tg68k.regfile[6][26] top.tg68k_tb.tg68k.regfile[6][25] top.tg68k_tb.tg68k.regfile[6][24] top.tg68k_tb.tg68k.regfile[6][23] top.tg68k_tb.tg68k.regfile[6][22] top.tg68k_tb.tg68k.regfile[6][21] top.tg68k_tb.tg68k.regfile[6][20] top.tg68k_tb.tg68k.regfile[6][19] top.tg68k_tb.tg68k.regfile[6][18] top.tg68k_tb.tg68k.regfile[6][17] top.tg68k_tb.tg68k.regfile[6][16] top.tg68k_tb.tg68k.regfile[6][15] top.tg68k_tb.tg68k.regfile[6][14] top.tg68k_tb.tg68k.regfile[6][13] top.tg68k_tb.tg68k.regfile[6][12] top.tg68k_tb.tg68k.regfile[6][11] top.tg68k_tb.tg68k.regfile[6][10] top.tg68k_tb.tg68k.regfile[6][9] top.tg68k_tb.tg68k.regfile[6][8] top.tg68k_tb.tg68k.regfile[6][7] top.tg68k_tb.tg68k.regfile[6][6] top.tg68k_tb.tg68k.regfile[6][5] top.tg68k_tb.tg68k.regfile[6][4] top.tg68k_tb.tg68k.regfile[6][3] top.tg68k_tb.tg68k.regfile[6][2] top.tg68k_tb.tg68k.regfile[6][1] top.tg68k_tb.tg68k.regfile[6][0] +#{top.tg68k_tb.tg68k.alu.aluout[31:0]} top.tg68k_tb.tg68k.alu.aluout[31] top.tg68k_tb.tg68k.alu.aluout[30] top.tg68k_tb.tg68k.alu.aluout[29] top.tg68k_tb.tg68k.alu.aluout[28] top.tg68k_tb.tg68k.alu.aluout[27] top.tg68k_tb.tg68k.alu.aluout[26] top.tg68k_tb.tg68k.alu.aluout[25] top.tg68k_tb.tg68k.alu.aluout[24] top.tg68k_tb.tg68k.alu.aluout[23] top.tg68k_tb.tg68k.alu.aluout[22] top.tg68k_tb.tg68k.alu.aluout[21] top.tg68k_tb.tg68k.alu.aluout[20] top.tg68k_tb.tg68k.alu.aluout[19] top.tg68k_tb.tg68k.alu.aluout[18] top.tg68k_tb.tg68k.alu.aluout[17] top.tg68k_tb.tg68k.alu.aluout[16] top.tg68k_tb.tg68k.alu.aluout[15] top.tg68k_tb.tg68k.alu.aluout[14] top.tg68k_tb.tg68k.alu.aluout[13] top.tg68k_tb.tg68k.alu.aluout[12] top.tg68k_tb.tg68k.alu.aluout[11] top.tg68k_tb.tg68k.alu.aluout[10] top.tg68k_tb.tg68k.alu.aluout[9] top.tg68k_tb.tg68k.alu.aluout[8] top.tg68k_tb.tg68k.alu.aluout[7] top.tg68k_tb.tg68k.alu.aluout[6] top.tg68k_tb.tg68k.alu.aluout[5] top.tg68k_tb.tg68k.alu.aluout[4] top.tg68k_tb.tg68k.alu.aluout[3] top.tg68k_tb.tg68k.alu.aluout[2] top.tg68k_tb.tg68k.alu.aluout[1] top.tg68k_tb.tg68k.alu.aluout[0] +#{top.tg68k_tb.tg68k.alu.op1out[31:0]} top.tg68k_tb.tg68k.alu.op1out[31] top.tg68k_tb.tg68k.alu.op1out[30] top.tg68k_tb.tg68k.alu.op1out[29] top.tg68k_tb.tg68k.alu.op1out[28] top.tg68k_tb.tg68k.alu.op1out[27] top.tg68k_tb.tg68k.alu.op1out[26] top.tg68k_tb.tg68k.alu.op1out[25] top.tg68k_tb.tg68k.alu.op1out[24] top.tg68k_tb.tg68k.alu.op1out[23] top.tg68k_tb.tg68k.alu.op1out[22] top.tg68k_tb.tg68k.alu.op1out[21] top.tg68k_tb.tg68k.alu.op1out[20] top.tg68k_tb.tg68k.alu.op1out[19] top.tg68k_tb.tg68k.alu.op1out[18] top.tg68k_tb.tg68k.alu.op1out[17] top.tg68k_tb.tg68k.alu.op1out[16] top.tg68k_tb.tg68k.alu.op1out[15] top.tg68k_tb.tg68k.alu.op1out[14] top.tg68k_tb.tg68k.alu.op1out[13] top.tg68k_tb.tg68k.alu.op1out[12] top.tg68k_tb.tg68k.alu.op1out[11] top.tg68k_tb.tg68k.alu.op1out[10] top.tg68k_tb.tg68k.alu.op1out[9] top.tg68k_tb.tg68k.alu.op1out[8] top.tg68k_tb.tg68k.alu.op1out[7] top.tg68k_tb.tg68k.alu.op1out[6] top.tg68k_tb.tg68k.alu.op1out[5] top.tg68k_tb.tg68k.alu.op1out[4] top.tg68k_tb.tg68k.alu.op1out[3] top.tg68k_tb.tg68k.alu.op1out[2] top.tg68k_tb.tg68k.alu.op1out[1] top.tg68k_tb.tg68k.alu.op1out[0] +#{top.tg68k_tb.tg68k.alu.op2out[31:0]} top.tg68k_tb.tg68k.alu.op2out[31] top.tg68k_tb.tg68k.alu.op2out[30] top.tg68k_tb.tg68k.alu.op2out[29] top.tg68k_tb.tg68k.alu.op2out[28] top.tg68k_tb.tg68k.alu.op2out[27] top.tg68k_tb.tg68k.alu.op2out[26] top.tg68k_tb.tg68k.alu.op2out[25] top.tg68k_tb.tg68k.alu.op2out[24] top.tg68k_tb.tg68k.alu.op2out[23] top.tg68k_tb.tg68k.alu.op2out[22] top.tg68k_tb.tg68k.alu.op2out[21] top.tg68k_tb.tg68k.alu.op2out[20] top.tg68k_tb.tg68k.alu.op2out[19] top.tg68k_tb.tg68k.alu.op2out[18] top.tg68k_tb.tg68k.alu.op2out[17] top.tg68k_tb.tg68k.alu.op2out[16] top.tg68k_tb.tg68k.alu.op2out[15] top.tg68k_tb.tg68k.alu.op2out[14] top.tg68k_tb.tg68k.alu.op2out[13] top.tg68k_tb.tg68k.alu.op2out[12] top.tg68k_tb.tg68k.alu.op2out[11] top.tg68k_tb.tg68k.alu.op2out[10] top.tg68k_tb.tg68k.alu.op2out[9] top.tg68k_tb.tg68k.alu.op2out[8] top.tg68k_tb.tg68k.alu.op2out[7] top.tg68k_tb.tg68k.alu.op2out[6] top.tg68k_tb.tg68k.alu.op2out[5] top.tg68k_tb.tg68k.alu.op2out[4] top.tg68k_tb.tg68k.alu.op2out[3] top.tg68k_tb.tg68k.alu.op2out[2] top.tg68k_tb.tg68k.alu.op2out[1] top.tg68k_tb.tg68k.alu.op2out[0] +#{top.tg68k_tb.tg68k.regfile[8][31:0]} top.tg68k_tb.tg68k.regfile[8][31] top.tg68k_tb.tg68k.regfile[8][30] top.tg68k_tb.tg68k.regfile[8][29] top.tg68k_tb.tg68k.regfile[8][28] top.tg68k_tb.tg68k.regfile[8][27] top.tg68k_tb.tg68k.regfile[8][26] top.tg68k_tb.tg68k.regfile[8][25] top.tg68k_tb.tg68k.regfile[8][24] top.tg68k_tb.tg68k.regfile[8][23] top.tg68k_tb.tg68k.regfile[8][22] top.tg68k_tb.tg68k.regfile[8][21] top.tg68k_tb.tg68k.regfile[8][20] top.tg68k_tb.tg68k.regfile[8][19] top.tg68k_tb.tg68k.regfile[8][18] top.tg68k_tb.tg68k.regfile[8][17] top.tg68k_tb.tg68k.regfile[8][16] top.tg68k_tb.tg68k.regfile[8][15] top.tg68k_tb.tg68k.regfile[8][14] top.tg68k_tb.tg68k.regfile[8][13] top.tg68k_tb.tg68k.regfile[8][12] top.tg68k_tb.tg68k.regfile[8][11] top.tg68k_tb.tg68k.regfile[8][10] top.tg68k_tb.tg68k.regfile[8][9] top.tg68k_tb.tg68k.regfile[8][8] top.tg68k_tb.tg68k.regfile[8][7] top.tg68k_tb.tg68k.regfile[8][6] top.tg68k_tb.tg68k.regfile[8][5] top.tg68k_tb.tg68k.regfile[8][4] top.tg68k_tb.tg68k.regfile[8][3] top.tg68k_tb.tg68k.regfile[8][2] top.tg68k_tb.tg68k.regfile[8][1] top.tg68k_tb.tg68k.regfile[8][0] +#{top.tg68k_tb.tg68k.regfile[9][31:0]} top.tg68k_tb.tg68k.regfile[9][31] top.tg68k_tb.tg68k.regfile[9][30] top.tg68k_tb.tg68k.regfile[9][29] top.tg68k_tb.tg68k.regfile[9][28] top.tg68k_tb.tg68k.regfile[9][27] top.tg68k_tb.tg68k.regfile[9][26] top.tg68k_tb.tg68k.regfile[9][25] top.tg68k_tb.tg68k.regfile[9][24] top.tg68k_tb.tg68k.regfile[9][23] top.tg68k_tb.tg68k.regfile[9][22] top.tg68k_tb.tg68k.regfile[9][21] top.tg68k_tb.tg68k.regfile[9][20] top.tg68k_tb.tg68k.regfile[9][19] top.tg68k_tb.tg68k.regfile[9][18] top.tg68k_tb.tg68k.regfile[9][17] top.tg68k_tb.tg68k.regfile[9][16] top.tg68k_tb.tg68k.regfile[9][15] top.tg68k_tb.tg68k.regfile[9][14] top.tg68k_tb.tg68k.regfile[9][13] top.tg68k_tb.tg68k.regfile[9][12] top.tg68k_tb.tg68k.regfile[9][11] top.tg68k_tb.tg68k.regfile[9][10] top.tg68k_tb.tg68k.regfile[9][9] top.tg68k_tb.tg68k.regfile[9][8] top.tg68k_tb.tg68k.regfile[9][7] top.tg68k_tb.tg68k.regfile[9][6] top.tg68k_tb.tg68k.regfile[9][5] top.tg68k_tb.tg68k.regfile[9][4] top.tg68k_tb.tg68k.regfile[9][3] top.tg68k_tb.tg68k.regfile[9][2] top.tg68k_tb.tg68k.regfile[9][1] top.tg68k_tb.tg68k.regfile[9][0] +@28 +top.tg68k_tb.tg68k.decodeopc +top.tg68k_tb.tg68k.next_micro_state +top.tg68k_tb.tg68k.micro_state +@22 +#{top.tg68k_tb.tg68k.data_write_tmp[31:0]} top.tg68k_tb.tg68k.data_write_tmp[31] top.tg68k_tb.tg68k.data_write_tmp[30] top.tg68k_tb.tg68k.data_write_tmp[29] top.tg68k_tb.tg68k.data_write_tmp[28] top.tg68k_tb.tg68k.data_write_tmp[27] top.tg68k_tb.tg68k.data_write_tmp[26] top.tg68k_tb.tg68k.data_write_tmp[25] top.tg68k_tb.tg68k.data_write_tmp[24] top.tg68k_tb.tg68k.data_write_tmp[23] top.tg68k_tb.tg68k.data_write_tmp[22] top.tg68k_tb.tg68k.data_write_tmp[21] top.tg68k_tb.tg68k.data_write_tmp[20] top.tg68k_tb.tg68k.data_write_tmp[19] top.tg68k_tb.tg68k.data_write_tmp[18] top.tg68k_tb.tg68k.data_write_tmp[17] top.tg68k_tb.tg68k.data_write_tmp[16] top.tg68k_tb.tg68k.data_write_tmp[15] top.tg68k_tb.tg68k.data_write_tmp[14] top.tg68k_tb.tg68k.data_write_tmp[13] top.tg68k_tb.tg68k.data_write_tmp[12] top.tg68k_tb.tg68k.data_write_tmp[11] top.tg68k_tb.tg68k.data_write_tmp[10] top.tg68k_tb.tg68k.data_write_tmp[9] top.tg68k_tb.tg68k.data_write_tmp[8] top.tg68k_tb.tg68k.data_write_tmp[7] top.tg68k_tb.tg68k.data_write_tmp[6] top.tg68k_tb.tg68k.data_write_tmp[5] top.tg68k_tb.tg68k.data_write_tmp[4] top.tg68k_tb.tg68k.data_write_tmp[3] top.tg68k_tb.tg68k.data_write_tmp[2] top.tg68k_tb.tg68k.data_write_tmp[1] top.tg68k_tb.tg68k.data_write_tmp[0] +#{top.tg68k_tb.tg68k.data_read[31:0]} top.tg68k_tb.tg68k.data_read[31] top.tg68k_tb.tg68k.data_read[30] top.tg68k_tb.tg68k.data_read[29] top.tg68k_tb.tg68k.data_read[28] top.tg68k_tb.tg68k.data_read[27] top.tg68k_tb.tg68k.data_read[26] top.tg68k_tb.tg68k.data_read[25] top.tg68k_tb.tg68k.data_read[24] top.tg68k_tb.tg68k.data_read[23] top.tg68k_tb.tg68k.data_read[22] top.tg68k_tb.tg68k.data_read[21] top.tg68k_tb.tg68k.data_read[20] top.tg68k_tb.tg68k.data_read[19] top.tg68k_tb.tg68k.data_read[18] top.tg68k_tb.tg68k.data_read[17] top.tg68k_tb.tg68k.data_read[16] top.tg68k_tb.tg68k.data_read[15] top.tg68k_tb.tg68k.data_read[14] top.tg68k_tb.tg68k.data_read[13] top.tg68k_tb.tg68k.data_read[12] top.tg68k_tb.tg68k.data_read[11] top.tg68k_tb.tg68k.data_read[10] top.tg68k_tb.tg68k.data_read[9] top.tg68k_tb.tg68k.data_read[8] top.tg68k_tb.tg68k.data_read[7] top.tg68k_tb.tg68k.data_read[6] top.tg68k_tb.tg68k.data_read[5] top.tg68k_tb.tg68k.data_read[4] top.tg68k_tb.tg68k.data_read[3] top.tg68k_tb.tg68k.data_read[2] top.tg68k_tb.tg68k.data_read[1] top.tg68k_tb.tg68k.data_read[0] +#{top.tg68k_tb.tg68k.last_data_read[31:0]} top.tg68k_tb.tg68k.last_data_read[31] top.tg68k_tb.tg68k.last_data_read[30] top.tg68k_tb.tg68k.last_data_read[29] top.tg68k_tb.tg68k.last_data_read[28] top.tg68k_tb.tg68k.last_data_read[27] top.tg68k_tb.tg68k.last_data_read[26] top.tg68k_tb.tg68k.last_data_read[25] top.tg68k_tb.tg68k.last_data_read[24] top.tg68k_tb.tg68k.last_data_read[23] top.tg68k_tb.tg68k.last_data_read[22] top.tg68k_tb.tg68k.last_data_read[21] top.tg68k_tb.tg68k.last_data_read[20] top.tg68k_tb.tg68k.last_data_read[19] top.tg68k_tb.tg68k.last_data_read[18] top.tg68k_tb.tg68k.last_data_read[17] top.tg68k_tb.tg68k.last_data_read[16] top.tg68k_tb.tg68k.last_data_read[15] top.tg68k_tb.tg68k.last_data_read[14] top.tg68k_tb.tg68k.last_data_read[13] top.tg68k_tb.tg68k.last_data_read[12] top.tg68k_tb.tg68k.last_data_read[11] top.tg68k_tb.tg68k.last_data_read[10] top.tg68k_tb.tg68k.last_data_read[9] top.tg68k_tb.tg68k.last_data_read[8] top.tg68k_tb.tg68k.last_data_read[7] top.tg68k_tb.tg68k.last_data_read[6] top.tg68k_tb.tg68k.last_data_read[5] top.tg68k_tb.tg68k.last_data_read[4] top.tg68k_tb.tg68k.last_data_read[3] top.tg68k_tb.tg68k.last_data_read[2] top.tg68k_tb.tg68k.last_data_read[1] top.tg68k_tb.tg68k.last_data_read[0] +@28 +#{top.tg68k_tb.tg68k.datatype[1:0]} top.tg68k_tb.tg68k.datatype[1] top.tg68k_tb.tg68k.datatype[0] +@c00022 +#{top.tg68k_tb.tg68k.flagssr[7:0]} top.tg68k_tb.tg68k.flagssr[7] top.tg68k_tb.tg68k.flagssr[6] top.tg68k_tb.tg68k.flagssr[5] top.tg68k_tb.tg68k.flagssr[4] top.tg68k_tb.tg68k.flagssr[3] top.tg68k_tb.tg68k.flagssr[2] top.tg68k_tb.tg68k.flagssr[1] top.tg68k_tb.tg68k.flagssr[0] +@28 +top.tg68k_tb.tg68k.flagssr[7] +top.tg68k_tb.tg68k.flagssr[6] +top.tg68k_tb.tg68k.flagssr[5] +top.tg68k_tb.tg68k.flagssr[4] +top.tg68k_tb.tg68k.flagssr[3] +top.tg68k_tb.tg68k.flagssr[2] +top.tg68k_tb.tg68k.flagssr[1] +top.tg68k_tb.tg68k.flagssr[0] +@1401200 +-group_end +@c00023 +#{top.tg68k_tb.tg68k.flags[7:0]} top.tg68k_tb.tg68k.flags[7] top.tg68k_tb.tg68k.flags[6] top.tg68k_tb.tg68k.flags[5] top.tg68k_tb.tg68k.flags[4] top.tg68k_tb.tg68k.flags[3] top.tg68k_tb.tg68k.flags[2] top.tg68k_tb.tg68k.flags[1] top.tg68k_tb.tg68k.flags[0] +@29 +top.tg68k_tb.tg68k.flags[7] +top.tg68k_tb.tg68k.flags[6] +top.tg68k_tb.tg68k.flags[5] +top.tg68k_tb.tg68k.flags[4] +top.tg68k_tb.tg68k.flags[3] +top.tg68k_tb.tg68k.flags[2] +top.tg68k_tb.tg68k.flags[1] +top.tg68k_tb.tg68k.flags[0] +@1401201 +-group_end +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/tests/tg68k/tg68k_tb.vhd b/tests/tg68k/tg68k_tb.vhd new file mode 100644 index 0000000..997ba3d --- /dev/null +++ b/tests/tg68k/tg68k_tb.vhd @@ -0,0 +1,129 @@ +-- https://raw.githubusercontent.com/rkrajnc/minimig-de1/master/bench/cpu_cache_sdram/cpu_cache_sdram_tb.v +-- http://www.asic-world.com/vhdl/first1.html + +library ieee; +use ieee.std_logic_1164.all; +use IEEE.numeric_std.all; +use std.textio.all; +use work.testcode_pack.all; + +-- `timescale 1us/1ns + +entity tg68k_tb is +end; + +architecture tg68k_tb of tg68k_tb is + + -- include tg68k +component TG68KdotC_Kernel +generic( + SR_Read : integer:= 2; --0=>user, 1=>privileged, 2=>switchable with CPU(0) + VBR_Stackframe : integer:= 2; --0=>no, 1=>yes/extended, 2=>switchable with CPU(0) + extAddr_Mode : integer:= 2; --0=>no, 1=>yes, 2=>switchable with CPU(1) + MUL_Mode : integer := 2; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL, + DIV_Mode : integer := 2; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV, + BitField : integer := 2 --0=>no, 1=>yes, 2=>switchable with CPU(1) + ); + port (clk : in std_logic; + nReset : in std_logic; --low active + clkena_in : in std_logic; + data_in : in std_logic_vector(15 downto 0); + IPL : in std_logic_vector(2 downto 0):="111"; + IPL_autovector : in std_logic; + berr : in std_logic; -- only 68000 sp dummy + CPU : in std_logic_vector(1 downto 0); + addr : buffer std_logic_vector(31 downto 0); + data_write : out std_logic_vector(15 downto 0); + nWr : out std_logic; + nUDS, nLDS : out std_logic; + busstate : out std_logic_vector(1 downto 0); + nResetOut : out std_logic; + FC : out std_logic_vector(2 downto 0); + clr_berr : out std_logic; + -- for debug + db_OP1out : out std_logic_vector(31 downto 0); + db_OP2out : out std_logic_vector(31 downto 0); + skipFetch : out std_logic; + regin : buffer std_logic_vector(31 downto 0) + ); +end component ; + +signal clk : std_logic := '0'; +signal reset_n : std_logic := '1'; +signal din : std_logic_vector(15 downto 0); +signal dout : std_logic_vector(15 downto 0); +signal addr : std_logic_vector(31 downto 0); +signal busstate : std_logic_vector(1 downto 0); + +type ram_t is array(0 to 255) of std_logic_vector(15 downto 0); +signal ram : ram_t; + +begin + + -- wire up cpu + tg68k : TG68KdotC_Kernel + port map ( + clk => clk, + nReset => reset_n, + clkena_in => '1', + data_in => din, + data_write => dout, + IPL => "111", + IPL_autovector => '0', + berr => '0', + CPU => "11", -- 00=68000, 11=68020 + addr => addr, + busstate => busstate + ); + +-- generate a 32mhz clock + clock : process + begin + wait for 30 ns; clk <= not clk; + end process clock; + + stimulus : process + begin + report "start"; + + reset_n <= '0'; + wait for 125 ns; reset_n <= '1'; + + assert false report "tg68k out of reset" + severity note; + + wait; + end process stimulus; + + memory : process (clk) + variable c_str : line; + begin + if (clk = '0' and clk'event) then + if(busstate = "11") then + if(unsigned(addr) >= x"55aa0000" and unsigned(addr) < (x"55aa0000"+512)) then + ram(to_integer((unsigned(addr) - x"55aa0000"))/2) <= dout; + end if; + elsif(busstate = "00" or busstate = "10") then + if (unsigned(addr) < 256) then + case addr is + when x"00000000" => din <= x"55aa"; -- stack at 55aa0100 + when x"00000002" => din <= x"0100"; + when x"00000004" => din <= x"00fc"; -- tos rom base -> fc0000 + when x"00000006" => din <= x"0000"; + when x"00000024" => din <= x"00fc"; -- trace vector -> fc0100 + when x"00000026" => din <= x"0100"; + when others => din <= x"0000"; + end case; + elsif(unsigned(addr) >= x"00fc0000" and unsigned(addr) < (x"00fc0000"+512)) then + din <= testcode_rom(to_integer((unsigned(addr) - x"00fc0000"))/2); + elsif(unsigned(addr) >= x"55aa0000" and unsigned(addr) < (x"55aa0000"+512)) then + din <= ram(to_integer((unsigned(addr) - x"55aa0000"))/2); + else + din <= (others=>'-'); + end if; + end if; + end if; + end process memory; + +end tg68k_tb; + diff --git a/tests/tg68k/todo.txt b/tests/tg68k/todo.txt new file mode 100644 index 0000000..5ad4339 --- /dev/null +++ b/tests/tg68k/todo.txt @@ -0,0 +1,19 @@ +PACK Dx,Dy,# + +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +1 0 0 0 1 0 1 0 0 RM + +RM=0->Dx/y RM=1->-(Ax/y) + +UNPK Dx,Dy,# + +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +1 0 0 0 1 1 0 0 0 RM + +trace + +t0 (bit14): trace on change of flow. + +all trace happens after the instruction! + +nop is also a change of flow