diff --git a/tests/tg68k/TG68K_ALU.vhd b/tests/tg68k/TG68K_ALU.vhd
index e4a4e6d..0d35652 100644
--- a/tests/tg68k/TG68K_ALU.vhd
+++ b/tests/tg68k/TG68K_ALU.vhd
@@ -1,1196 +1,991 @@
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--- --
--- 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,
- BarrelShifter : integer := 0 --0=>no, 1=>yes, 2=>switchable with CPU(1)
- );
- port (
- clk : in std_logic;
- Reset : in std_logic;
- cpu : in std_logic_vector(1 downto 0);
- clkena_lw : in std_logic := '1';
- execOPC : in bit;
- exe_condition : in std_logic;
- exec_tas : in std_logic;
- long_start : in bit;
- non_aligned : in std_logic;
- movem_presub : in bit;
- set_stop : in bit;
- Z_error : in bit;
- rot_bits : in std_logic_vector(1 downto 0);
- rot_cnt : in std_logic_vector(5 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_width : in std_logic_vector(4 downto 0);
- bf_loffset : in std_logic_vector(4 downto 0);
- bf_offset : in std_logic_vector(31 downto 0);
- set_V_Flag_out : out bit;
- Flags_out : out std_logic_vector(7 downto 0);
- c_out_out : out std_logic_vector(2 downto 0);
- addsub_q_out : out 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 datareg : std_logic_vector(31 downto 0);
- signal insert : std_logic_vector(31 downto 0);
- signal bf_datareg : 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_loff_dir : std_logic_vector(4 downto 0);
- signal bf_set2 : std_logic_vector(39 downto 0);
- signal copy : std_logic_vector(39 downto 0);
-
- signal bf_firstbit : std_logic_vector(5 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_extu : std_logic;
- signal bf_fffo : std_logic;
- signal bf_d32 : std_logic;
- signal index : std_logic_vector(4 downto 0);
- signal bf_flag_z : std_logic;
- signal bf_flag_n : std_logic;
- signal set_V_Flag : BIT;
-
- -- barrel shifter
- signal bs_rox : std_logic_vector(32 downto 0);
- signal bs_mask : std_logic_vector(31 downto 0);
- signal bs_data : std_logic_vector(31 downto 0);
- signal bs_msb : std_logic_vector(4 downto 0);
- signal bs_V : std_logic;
-
- signal Flags : std_logic_vector(7 downto 0);
- signal c_out : std_logic_vector(2 downto 0);
- signal addsub_q : std_logic_vector(31 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_offset, bf_width,
- 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 <= bf_offset + bf_width + 1 - bf_firstbit;
- 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(opcMOVECCR) = '1' then
- OP1in(15 downto 8) <= "00000000";
- OP1in( 7 downto 0) <= Flags;
- elsif exec(opcMOVESR) = '1' then
- OP1in(15 downto 8) <= FlagsSR;
- OP1in( 7 downto 0) <= Flags;
- elsif exec(opcPACK) = '1' then
- OP1in(15 downto 0) <= pack_out;
- end if;
- end process;
-
- -----------------------------------------------------------------------------
- -- addsub
- -----------------------------------------------------------------------------
- process (OP1out, OP2out, execOPC, datatype, Flags, long_start, non_aligned, 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 -- used for initial offset / aligned case
- 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;
-
- -- patch for un-aligned movem
- if (exec(movem_action) = '1') then
- if (movem_presub = '0') then -- up
- if (non_aligned = '1') and (long_start = '0') then -- hold
- addsub_b <= (others => '0');
- end if;
- else
- if (non_aligned = '1') and (long_start = '0') then
- if (exe_datatype = "10") then
- addsub_b <= "00000000000000000000000000001000";
- else
- addsub_b <= "00000000000000000000000000000100";
- end if;
- end if;
- end if;
- 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 <= (('0' & addsub_a & notaddsub_b(0)) + 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 & (niba_h(4 downto 1) + ('0', niba_hc, niba_hc, '0')) & (niba_l(4 downto 1) + ('0', niba_lc, niba_lc, '0'));
- niba_l <= ('0' & OP1out(3 downto 0) & '1') + ('0' & OP2out(3 downto 0) & Flags(4));
- niba_lc <= niba_l(5) OR (niba_l(4) and niba_l(3)) OR (niba_l(4) and niba_l(2));
-
- niba_h <= ('0' & OP1out(7 downto 4) & '1') + ('0' & OP2out(7 downto 4) & niba_lc);
- niba_hc <= niba_h(5) OR (niba_h(4) and niba_h(3)) OR (niba_h(4) and niba_h(2));
- --SBC
- bcd_s <= nibs_hc & (nibs_h(4 downto 1) - ('0', nibs_hc, nibs_hc, '0')) & (nibs_l(4 downto 1) - ('0', nibs_lc, nibs_lc, '0'));
- nibs_l <= ('0' & OP1out(3 downto 0) & '0') - ('0' & OP2out(3 downto 0) & Flags(4));
- nibs_lc <= nibs_l(5);
-
- nibs_h <= ('0' & OP1out(7 downto 4) & '0') - ('0' & OP2out(7 downto 4) & nibs_lc);
- nibs_hc <= nibs_h(5);
- end process;
-
- -----------------------------------------------------------------------------
- -- Bits
- -----------------------------------------------------------------------------
- process (clk, exe_opcode, OP1out, OP2out, one_bit_in, bchg, bset, bit_Number, sndOPC, reg_QB)
- 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" & reg_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
- -----------------------------------------------------------------------------
-
- -- Bitfields can have up to four (register) operands, e.g. bfins d0,d1{d2,d3}
- -- the width an offset operands are evaluated while the second opcode word is
- -- evaluated. These values are latched, so the two other registers can be read
- -- in the next cycle while the ALU is working since the tg68k can only read
- -- from two registers at once.
- --
- -- All bitfield operations can operate on registers or memory. There are
- -- two fundamental differences which make the shifters quite complex:
- -- 1. Memory content is delivered byte aligned to the ALU. Thus all shifting
- -- is 7 bits far at most. Registers are 32 bit in size and may require
- -- shifting of up to 31 bit positions
- -- 2. Memory operations can affect 5 bytes. Thus all shifting is 40 bit in that
- -- case. Registers are 32 bit in size and bitfield operations wrap. Shifts
- -- are actually rotations for that reason
- --
- -- The destination operand is transfered via op1out and bf_ext into the ALU.
- --
- -- bftst, bfset, bfclr and bfchg
- --------------------------------
- -- bftst, bfset, bfclr and bfchg work very similar. A "sign" vector is generated
- -- having "width" right aligned 0-bits and the rest ones.
- -- A "copy" vector is generated from this by shifting through copymux so
- -- this contains a 1 for all bits in bf_ext_in & op1out that will not be
- -- affected by the operation.
- -- The result vector is either all 1's (bfset), all 0's(bfclr) or the inverse
- -- of bf_ext_in & op1out. Those bits in result that have a 1 in the copy
- -- vector are overwritten with the original value from bf_ext_in & op1out
- -- The result is returned through bf_ext_out and ALUout
- --
- -- These instructions only calculate the Z and N flags. Both are derived
- -- directly from bf_ext_in & op1out with the help of the copy vector and
- -- the offset/width fields. Thus Z and N are set from the previous contents
- -- of the bitfield.
- --
- -- bfins
- --------
- -- bfins reuses most of the functionality of bfset, bfclr and bfchg. But it
- -- has another 32 bit parameter that's being used for the source. This is passed
- -- to the ALU via op2out. This is moved to the shift register and shifted
- -- bf_shift bits to the right.
- -- The input valus is also store in datareg and the lowest "width" bits
- -- are masked. This is then forwarded to op1in which in turn uses the normal
- -- mechanisms to generate the flags. A special bf_NFlag is also generated
- -- from this. Z and N are set from these and not from the previous bitfield
- -- contents as with bfset, bfclr or bfchg
- --
- -- bfextu/bfexts
- ----------------
- -- bfexts and bfextu use the same shifter that is used by bfins to shift the
- -- data to be inserted. It's using that same shifter to shift data in the
- -- opposite direction. Flags are set from the extraced data
- --
- -- bfffo
- --------
- -- bfffo uses the same data path as bfext. But instead of directly returning
- -- the extracted data it determines the highest bit setin the result
-
- process (clk, bf_ins, bf_bchg, bf_bset, bf_exts, bf_extu, bf_set2, OP1out, OP2out, result_tmp, bf_ext_in,
- datareg, bf_NFlag, result, reg_QB, sign, bf_d32, copy, bf_loffset, bf_width, bf_loff_dir, exe_opcode)
- begin
- if rising_edge(clk) then
- if clkena_lw = '1' then
- bf_bset <= '0';
- bf_bchg <= '0';
- bf_ins <= '0';
- bf_exts <= '0';
- bf_extu <= '0';
- bf_fffo <= '0';
- bf_d32 <= '0';
- case opcode(10 downto 8) IS
- when "010" => bf_bchg <= '1'; --BFCHG
- when "011" => bf_exts <= '1'; --BFEXTS
- when "001" => bf_extu <= '1'; --BFEXTU
- -- when "100" => insert <= (others =>'0'); --BFCLR
- when "101" => bf_fffo <= '1'; --BFFFO
- when "110" => bf_bset <= '1'; --BFSET
- when "111" => bf_ins <= '1'; --BFinS
- when others => NULL;
- end case;
-
- -- ea is a register
- if opcode(4 downto 3) = "00" then
- bf_d32 <= '1';
- end if;
-
- bf_ext_out <= result(39 downto 32);
- end if;
- end if;
-
- ------------- BF_SET2 --------------
- if bf_ins = '1' then
- bf_loff_dir <= 32 - bf_loffset;
- else
- bf_loff_dir <= bf_loffset;
- end if;
-
- if bf_d32 = '1' then
- -- 32bit: rotate 0..31 bits left or right, don't care for upper 8 bits
- bf_set2 <= "--------" & std_logic_vector(unsigned(OP2out) ror to_integer(unsigned(bf_loff_dir)));
- else
- if bf_ins = '1' then
- -- 40 bit: shift 0..7 bits left
- bf_set2 <= std_logic_vector(unsigned(bf_ext_in & OP2out) sll to_integer(unsigned(bf_loffset(2 downto 0))));
- else
- -- 40 bit: shift 0..7 bits right
- bf_set2 <= std_logic_vector(unsigned(bf_ext_in & OP2out) srl to_integer(unsigned(bf_loffset(2 downto 0))));
- end if;
- end if;
-
- ------------- COPY --------------
- if bf_d32 = '1' then
- -- 32bit: rotate 32 bits 0..31 bits left, don't care for upper 8 bits
- copy <= "--------" & std_logic_vector(unsigned(sign) rol to_integer(unsigned(bf_loffset)));
- else
- -- 40 bit: shift 40 bits 0..7 bits left, fill with '1's (hence the two not's)
- copy <= not std_logic_vector(unsigned(x"00" & (not sign)) sll to_integer(unsigned(bf_loffset(2 downto 0))));
- end if;
-
- if bf_ins = '1' then
- datareg <= reg_QB;
- else
- datareg <= bf_set2(31 downto 0);
- end if;
-
- -- do the bitfield operation itself
- if bf_ins = '1' then
- result <= bf_set2;
- elsif bf_bchg = '1' then
- result <= not (bf_ext_in & OP1out);
- elsif bf_bset = '1' then
- result <= (others => '1');
- else
- result <= (others => '0');
- end if;
-
- sign <= (others => '0');
- bf_NFlag <= datareg(to_integer(unsigned(bf_width)));
- for i in 0 TO 31 loop
- if i > bf_width then
- datareg(i) <= '0';
- sign(i) <= '1';
- end if;
- end loop;
-
- -- Set bits 32..39 to 0 if operating on register to make sure
- -- zero flag calculation over all 40 bits works correctly
- result_tmp(31 downto 0) <= OP1out;
- if bf_d32 = '1' then
- result_tmp(39 downto 32) <= "00000000";
- else
- result_tmp(39 downto 32) <= bf_ext_in;
- end if;
-
- bf_flag_z <= '1';
- if bf_d32 = '0' then
- -- The test for this overflow shouldn't be needed. But GHDL complains
- -- otherwise.
- if(to_integer(unsigned('0' & bf_loffset)+unsigned(bf_width)) > 39) then
- bf_flag_n <= result_tmp(39);
- else
- bf_flag_n <= result_tmp(to_integer(unsigned('0' & bf_loffset)+unsigned(bf_width)));
- end if;
- else
- --TH: TODO: check if this really does what it's supposed to
- bf_flag_n <= result_tmp(to_integer(unsigned(bf_loffset)+unsigned(bf_width)));
- end if;
- for i in 0 TO 39 loop
- if copy(i) = '1' then
- result(i) <= result_tmp(i);
- elsif result_tmp(i) = '1' then
- bf_flag_z <= '0';
- end if;
- end loop;
-
- if bf_exts = '1' and bf_NFlag = '1' then
- bf_datareg <= datareg OR sign;
- else
- bf_datareg <= datareg;
- end if;
-
- --BFFFO
- if datareg(31) = '1' then bf_firstbit <= "100000";
- elsif datareg(30) = '1' then bf_firstbit <= "011111";
- elsif datareg(29) = '1' then bf_firstbit <= "011110";
- elsif datareg(28) = '1' then bf_firstbit <= "011101";
- elsif datareg(27) = '1' then bf_firstbit <= "011100";
- elsif datareg(26) = '1' then bf_firstbit <= "011011";
- elsif datareg(25) = '1' then bf_firstbit <= "011010";
- elsif datareg(24) = '1' then bf_firstbit <= "011001";
- elsif datareg(23) = '1' then bf_firstbit <= "011000";
- elsif datareg(22) = '1' then bf_firstbit <= "010111";
- elsif datareg(21) = '1' then bf_firstbit <= "010110";
- elsif datareg(20) = '1' then bf_firstbit <= "010101";
- elsif datareg(19) = '1' then bf_firstbit <= "010100";
- elsif datareg(18) = '1' then bf_firstbit <= "010011";
- elsif datareg(17) = '1' then bf_firstbit <= "010010";
- elsif datareg(16) = '1' then bf_firstbit <= "010001";
- elsif datareg(15) = '1' then bf_firstbit <= "010000";
- elsif datareg(14) = '1' then bf_firstbit <= "001111";
- elsif datareg(13) = '1' then bf_firstbit <= "001110";
- elsif datareg(12) = '1' then bf_firstbit <= "001101";
- elsif datareg(11) = '1' then bf_firstbit <= "001100";
- elsif datareg(10) = '1' then bf_firstbit <= "001011";
- elsif datareg(9) = '1' then bf_firstbit <= "001010";
- elsif datareg(8) = '1' then bf_firstbit <= "001001";
- elsif datareg(7) = '1' then bf_firstbit <= "001000";
- elsif datareg(6) = '1' then bf_firstbit <= "000111";
- elsif datareg(5) = '1' then bf_firstbit <= "000110";
- elsif datareg(4) = '1' then bf_firstbit <= "000101";
- elsif datareg(3) = '1' then bf_firstbit <= "000100";
- elsif datareg(2) = '1' then bf_firstbit <= "000011";
- elsif datareg(1) = '1' then bf_firstbit <= "000010";
- elsif datareg(0) = '1' then bf_firstbit <= "000001";
- else bf_firstbit <= "000000";
- end if;
-
- end process;
-
- -----------------------------------------------------------------------------
- -- Rotation
- -----------------------------------------------------------------------------
- process (exe_opcode, OP1out, Flags, rot_bits, rot_msb, rot_lsb, rot_cnt, rot_out, rot_rot, bs_data, bs_mask, bs_msb, bs_rox, 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;
-
- ---------------------------------------------------------------------------
- --------------------------- 68020 barrel shifter --------------------------
- ---------------------------------------------------------------------------
-
- bs_mask <= (others => '-');
- bs_rox <= (others => '-');
- -- default: long word size
- bs_data <= OP1out;
- bs_msb <= "11111"; -- 31
- bs_V <= '0'; -- overflow flag for asr/asl
-
- -- the version doesn't use the barrel shifter as it can only shift 1 bit anyway
- if (BarrelShifter = 1 or (cpu(1) = '1' and BarrelShifter = 2)) then
- if exe_opcode(7 downto 6) /= "11" then
- -- create a mask of rot_cnt left aligned 1 bits according to operation size
- -- this is required for the arithmetic shifts to handle the V bit and the sign
- bs_mask <= (others => '0');
- for i in 0 TO 31 loop
- if rot_cnt > bs_msb-i and i <= bs_msb then
- bs_mask(i) <= '1';
- end if;
- end loop;
-
- -- check if msb would change during shifts
- -- in left shift either msb is 1 and remaining mask bits are not 11111...
- if OP1out(to_integer(unsigned(bs_msb))) = '1' and exe_opcode(8) = '1' then
- if (OP1out and ('0' & bs_mask(31 downto 1))) /= ('0' & bs_mask(31 downto 1)) then
- bs_V <= '1';
- end if;
-
- -- when shifting left more than 31/15/7 times a '0' will sure appear in the msb
- if(rot_cnt > bs_msb) then
- bs_V <= '1';
- end if;
- end if;
-
- -- ... or msb is 0 and remaining mask bits are not 00000...
- if OP1out(to_integer(unsigned(bs_msb))) = '0' and exe_opcode(8) = '1' then
- if (OP1out and ('0' & bs_mask(31 downto 1))) /= x"00000000" then
- bs_V <= '1';
- end if;
- end if;
-
- -- TODO: move to asr/asl only
- -- word or byte size
- if exe_opcode(7) = '0' then
- bs_msb(4) <= '0'; -- 15
- bs_data(31 downto 16) <= "0000000000000000";
-
- -- byte size
- if exe_opcode(6) = '0' then
- bs_msb(3) <= '0'; -- 7
- bs_data(15 downto 8) <= "00000000";
- end if;
- end if;
-
- if exe_opcode(8) = '1' then
- -- left
- if rot_bits = "10" then
- --====================== ROXL =====================
- if exe_opcode(7 downto 6) = "00" then
- -- roxl.b
- bs_rox <= "------------------------" &
- std_logic_vector(unsigned(Flags(4) & bs_data(7 downto 0)) rol
- to_integer(unsigned(rot_cnt)));
- rot_X <= bs_rox(8);
- rot_C <= bs_rox(8);
- elsif exe_opcode(7 downto 6) = "01" then
- -- roxl.w
- bs_rox <= "----------------" &
- std_logic_vector(unsigned(Flags(4) & bs_data(15 downto 0)) rol
- to_integer(unsigned(rot_cnt)));
- rot_X <= bs_rox(16);
- rot_C <= bs_rox(16);
- else
- -- roxl.l
- bs_rox <= std_logic_vector(unsigned(Flags(4) & bs_data) rol
- to_integer(unsigned(rot_cnt)));
- rot_X <= bs_rox(32);
- rot_C <= bs_rox(32);
- end if;
- rot_out <= bs_rox(31 downto 0);
- elsif rot_bits = "11" then
- --====================== ROL =====================
- if exe_opcode(7 downto 6) = "00" then
- -- rol.b
- rot_out <= "------------------------" &
- std_logic_vector(unsigned(bs_data(7 downto 0)) rol
- to_integer(unsigned(rot_cnt(2 downto 0))));
- rot_C <= OP1out(to_integer(unsigned("001" - rot_cnt(2 downto 0) + bs_msb(2 downto 0))));
- elsif exe_opcode(7 downto 6) = "01" then
- -- rol.w
- rot_out <= "----------------" &
- std_logic_vector(unsigned(bs_data(15 downto 0)) rol
- to_integer(unsigned(rot_cnt(3 downto 0))));
- rot_C <= OP1out(to_integer(unsigned("0001" - rot_cnt(3 downto 0) + bs_msb(3 downto 0))));
- else
- -- rol.l
- rot_out <= std_logic_vector(unsigned(bs_data) rol
- to_integer(unsigned(rot_cnt(4 downto 0))));
- rot_C <= OP1out(to_integer(unsigned("00001" - rot_cnt(4 downto 0) + bs_msb)));
- end if;
- rot_X <= Flags(4); -- keep X flag
- else
- --====================== LSL/ASL =====================
- -- shifting left is the same for arithmetic and logic
- rot_out <= std_logic_vector(unsigned(bs_data) sll to_integer(unsigned(rot_cnt)));
- rot_X <= OP1out(to_integer(unsigned("00001" - rot_cnt(4 downto 0) + bs_msb)));
- rot_C <= OP1out(to_integer(unsigned("00001" - rot_cnt(4 downto 0) + bs_msb)));
- end if;
-
- else
- -- right
- if rot_bits = "10" then
- --====================== ROXR =====================
- if exe_opcode(7 downto 6) = "00" then
- -- roxr.b
- bs_rox <= "------------------------" &
- std_logic_vector(unsigned(bs_data(7 downto 0) & Flags(4)) ror
- to_integer(unsigned(rot_cnt)));
- elsif exe_opcode(7 downto 6) = "01" then
- -- roxr.w
- bs_rox <= "----------------" &
- std_logic_vector(unsigned(bs_data(15 downto 0) & Flags(4)) ror
- to_integer(unsigned(rot_cnt)));
- else
- -- roxr.l
- bs_rox <= std_logic_vector(unsigned(bs_data & Flags(4)) ror
- to_integer(unsigned(rot_cnt)));
- end if;
-
- rot_out <= bs_rox(32 downto 1);
- rot_C <= bs_rox(0);
- rot_X <= bs_rox(0);
- elsif rot_bits = "11" then
- --====================== ROR =====================
- if exe_opcode(7 downto 6) = "00" then
- -- ror.b
- rot_out <= "------------------------" &
- std_logic_vector(unsigned(bs_data(7 downto 0)) ror
- to_integer(unsigned(rot_cnt(2 downto 0))));
- rot_C <= OP1out(to_integer(unsigned(rot_cnt(2 downto 0) - "001")));
- elsif exe_opcode(7 downto 6) = "01" then
- -- ror.w
- rot_out <= "----------------" &
- std_logic_vector(unsigned(bs_data(15 downto 0)) ror
- to_integer(unsigned(rot_cnt(3 downto 0))));
- rot_C <= OP1out(to_integer(unsigned(rot_cnt(3 downto 0) - "0001")));
- else
- -- ror.l
- rot_out <= std_logic_vector(unsigned(bs_data) ror
- to_integer(unsigned(rot_cnt(4 downto 0))));
- rot_C <= OP1out(to_integer(unsigned(rot_cnt(4 downto 0) - "00001")));
- end if;
- rot_X <= Flags(4); -- keep X flag
- else
- --====================== LSR/ASR =====================
- rot_out <= std_logic_vector(unsigned(bs_data) srl to_integer(unsigned(rot_cnt)));
- rot_X <= OP1out(to_integer(unsigned(rot_cnt(4 downto 0) - "00001")));
- rot_C <= OP1out(to_integer(unsigned(rot_cnt(4 downto 0) - "00001")));
-
- -- arithmetic shift right with msb being 1? then make sure all
- -- newly shifted in bits are set to 1
- if rot_bits = "00" and OP1out(to_integer(unsigned(bs_msb))) = '1' then
- rot_out <= bs_mask or std_logic_vector(unsigned(bs_data) srl
- to_integer(unsigned(rot_cnt)));
- end if;
- end if;
- end if;
-
- -- not shifting at all or shifting more than the whole byte/word/long
- if(rot_cnt = 0) then
- -- rox returns X in C bit with rotate of zero. all other clear it
- if rot_bits = "10" then
- rot_C <= Flags(4);
- else
- rot_C <= '0';
- end if;
- rot_X <= Flags(4);
- else
- -- asX/lsX shifting more than the total operand width
- if rot_bits(1) = '0' and rot_cnt - 1 > bs_msb then
- rot_X <= '0';
- rot_C <= '0';
-
- -- arithmetic shift right with msb set? Then the sign '1's will
- -- be shifted out
- if rot_bits = "00" and exe_opcode(8) = '0' and
- OP1out(to_integer(unsigned(bs_msb))) = '1' then
- rot_X <= '1';
- rot_C <= '1';
- end if;
- end if;
- end if;
-
- 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(2) has correctly been set from set_flags
- Flags(3) <= bf_NFlag;
-
- --TH TODO: check flag handling of fffo
-
- -- "normal" flags are taken from op2in
- if bf_fffo = '0' and bf_extu='0' and bf_exts='0' and bf_ins='0' then
- Flags(2) <= bf_flag_z;
- Flags(3) <= bf_flag_n;
- end if;
- 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;
- if BarrelShifter = 1 or (cpu(1) = '1' and BarrelShifter = 2) then
- -- v flag from barrel shifter when doing asl/asr
- if rot_bits = "00" and exe_opcode(7 downto 6) /= "11" then
- Flags(1) <= bs_V;
- end if;
- 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) <= (muls_msb & mulu_reg(63 downto 48) - (mulu_sign & faktorB(31 downto 16)));
- else
- result_mulu(63 downto 47) <= (muls_msb & mulu_reg(63 downto 48) + (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) <= (muls_msb & mulu_reg(63 downto 32) - (mulu_sign & faktorB));
- else
- result_mulu(63 downto 31) <= (muls_msb & mulu_reg(63 downto 32) + (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) <= 0 - 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 <= (div_reg(63 downto 31)) + ('1' & OP2out(31 downto 0));
- else
- div_sub <= (div_reg(63 downto 31)) - ('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 <= 0 - 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) <= ('0' & div_reg(47 downto 32)) - ('0' & OP2out(15 downto 0));
- else
- div_over <= ('0' & div_reg(63 downto 32)) - ('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) <= 0 - 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) <= 0 - 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;
-
- set_V_Flag_out <= set_V_Flag;
- Flags_out <= Flags;
- c_out_out <= c_out;
- addsub_q_out <= addsub_q;
-
-end;
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- --
+-- 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;
+ non_aligned : in std_logic;
+ 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_width : in std_logic_vector(4 downto 0);
+ bf_loffset : in std_logic_vector(4 downto 0);
+ bf_offset : in std_logic_vector(31 downto 0);
+ set_V_Flag_out : out bit;
+ Flags_out : out std_logic_vector(7 downto 0);
+ c_out_out : out std_logic_vector(2 downto 0);
+ addsub_q_out : out 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_lca : std_logic;
+ signal niba_lpt : 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_lca : std_logic_vector(4 downto 0);
+ 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 datareg : std_logic_vector(31 downto 0);
+ signal insert : std_logic_vector(31 downto 0);
+ signal bf_datareg : 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_loff_dir : std_logic_vector(4 downto 0);
+ signal bf_set2 : std_logic_vector(39 downto 0);
+ signal copy : std_logic_vector(39 downto 0);
+
+ signal bf_firstbit : std_logic_vector(5 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_extu : std_logic;
+ signal bf_fffo : std_logic;
+ signal bf_d32 : std_logic;
+ signal index : std_logic_vector(4 downto 0);
+ signal bf_flag_z : std_logic;
+ signal bf_flag_n : std_logic;
+
+ signal set_V_Flag : BIT;
+ signal Flags : std_logic_vector(7 downto 0);
+ signal c_out : std_logic_vector(2 downto 0);
+ signal addsub_q : std_logic_vector(31 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_offset, bf_width,
+ 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 <= bf_offset + bf_width + 1 - bf_firstbit;
+ 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(opcMOVECCR) = '1' then
+ OP1in(15 downto 8) <= "00000000";
+ OP1in( 7 downto 0) <= Flags;
+ elsif exec(opcMOVESR) = '1' then
+ OP1in(15 downto 8) <= FlagsSR;
+ OP1in( 7 downto 0) <= Flags;
+ elsif exec(opcPACK) = '1' then
+ OP1in(15 downto 0) <= pack_out;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- addsub
+ -----------------------------------------------------------------------------
+ process (OP1out, OP2out, execOPC, datatype, Flags, long_start, non_aligned, 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 -- used for initial offset / aligned case
+ 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;
+
+ -- patch for un-aligned movem
+ if (exec(movem_action) = '1') then
+ if (movem_presub = '0') then -- up
+ if (non_aligned = '1') and (long_start = '0') then -- hold
+ addsub_b <= (others => '0');
+ end if;
+ else
+ if (non_aligned = '1') and (long_start = '0') then
+ if (exe_datatype = "10") then
+ addsub_b <= "00000000000000000000000000001000";
+ else
+ addsub_b <= "00000000000000000000000000000100";
+ end if;
+ end if;
+ end if;
+ 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 <= (('0' & addsub_a & notaddsub_b(0)) + 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_lpt, niba_lc, niba_lca, nibs_hc, nibs_h, nibs_l, nibs_lc, nibs_lca, Flags, exe_opcode)
+ 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-------------------------------------------------------------------
+ --ABCD
+ bcd_a <= niba_hc & (niba_h(4 downto 1) + ('0', niba_hc, niba_hc, niba_lca)) & (niba_l(4 downto 1) + ('0', niba_lc, niba_lc, '0'));
+
+ niba_l <= ('0' & OP1out(3 downto 0) & '1') + ('0' & OP2out(3 downto 0) & Flags(4));
+ niba_lpt <= (niba_l(4) and niba_l(3)) OR (niba_l(4) and niba_l(2));
+ niba_lc <= niba_l(5) OR niba_lpt;
+ niba_lca <= niba_l(5) and niba_lpt;
+
+ niba_h <= ('0' & OP1out(7 downto 4) & '1') + ('0' & OP2out(7 downto 4) & niba_lc);
+ niba_hc <= niba_h(5) OR (niba_h(4) and niba_h(3)) OR (niba_h(4) and niba_h(2));
+ --SBCD
+ bcd_s <= nibs_hc & (nibs_h(4 downto 1) - ('0', nibs_hc, nibs_hc, nibs_lca(4))) & nibs_lca(3 downto 0);
+
+ nibs_l <= ('0' & OP1out(3 downto 0) & '0') - ('0' & OP2out(3 downto 0) & Flags(4));
+ nibs_lc <= nibs_l(5);
+ nibs_lca <= '0' & nibs_l(4 downto 1) - ('0', '0', nibs_lc, nibs_lc, '0');
+
+ nibs_h <= ('0' & OP1out(7 downto 4) & '0') - ('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, reg_QB)
+ 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" & reg_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
+ -----------------------------------------------------------------------------
+
+ -- Bitfields can have up to four (register) operands, e.g. bfins d0,d1{d2,d3}
+ -- the width an offset operands are evaluated while the second opcode word is
+ -- evaluated. These values are latched, so the two other registers can be read
+ -- in the next cycle while the ALU is working since the tg68k can only read
+ -- from two registers at once.
+ --
+ -- All bitfield operations can operate on registers or memory. There are
+ -- two fundamental differences which make the shifters quite complex:
+ -- 1. Memory content is delivered byte aligned to the ALU. Thus all shifting
+ -- is 7 bits far at most. Registers are 32 bit in size and may require
+ -- shifting of up to 31 bit positions
+ -- 2. Memory operations can affect 5 bytes. Thus all shifting is 40 bit in that
+ -- case. Registers are 32 bit in size and bitfield operations wrap. Shifts
+ -- are actually rotations for that reason
+ --
+ -- The destination operand is transfered via op1out and bf_ext into the ALU.
+ --
+ -- bftst, bfset, bfclr and bfchg
+ --------------------------------
+ -- bftst, bfset, bfclr and bfchg work very similar. A "sign" vector is generated
+ -- having "width" right aligned 0-bits and the rest ones.
+ -- A "copy" vector is generated from this by shifting through copymux so
+ -- this contains a 1 for all bits in bf_ext_in & op1out that will not be
+ -- affected by the operation.
+ -- The result vector is either all 1's (bfset), all 0's(bfclr) or the inverse
+ -- of bf_ext_in & op1out. Those bits in result that have a 1 in the copy
+ -- vector are overwritten with the original value from bf_ext_in & op1out
+ -- The result is returned through bf_ext_out and ALUout
+ --
+ -- These instructions only calculate the Z and N flags. Both are derived
+ -- directly from bf_ext_in & op1out with the help of the copy vector and
+ -- the offset/width fields. Thus Z and N are set from the previous contents
+ -- of the bitfield.
+ --
+ -- bfins
+ --------
+ -- bfins reuses most of the functionality of bfset, bfclr and bfchg. But it
+ -- has another 32 bit parameter that's being used for the source. This is passed
+ -- to the ALU via op2out. This is moved to the shift register and shifted
+ -- bf_shift bits to the right.
+ -- The input valus is also store in datareg and the lowest "width" bits
+ -- are masked. This is then forwarded to op1in which in turn uses the normal
+ -- mechanisms to generate the flags. A special bf_NFlag is also generated
+ -- from this. Z and N are set from these and not from the previous bitfield
+ -- contents as with bfset, bfclr or bfchg
+ --
+ -- bfextu/bfexts
+ ----------------
+ -- bfexts and bfextu use the same shifter that is used by bfins to shift the
+ -- data to be inserted. It's using that same shifter to shift data in the
+ -- opposite direction. Flags are set from the extraced data
+ --
+ -- bfffo
+ --------
+ -- bfffo uses the same data path as bfext. But instead of directly returning
+ -- the extracted data it determines the highest bit setin the result
+
+ process (clk, bf_ins, bf_bchg, bf_bset, bf_exts, bf_extu, bf_set2, OP1out, OP2out, result_tmp, bf_ext_in,
+ datareg, bf_NFlag, result, reg_QB, sign, bf_d32, copy, bf_loffset, bf_width, bf_loff_dir)
+ begin
+ if rising_edge(clk) then
+ if clkena_lw = '1' then
+ bf_bset <= '0';
+ bf_bchg <= '0';
+ bf_ins <= '0';
+ bf_exts <= '0';
+ bf_extu <= '0';
+ bf_fffo <= '0';
+ bf_d32 <= '0';
+ case opcode(10 downto 8) IS
+ when "010" => bf_bchg <= '1'; --BFCHG
+ when "011" => bf_exts <= '1'; --BFEXTS
+ when "001" => bf_extu <= '1'; --BFEXTU
+ -- when "100" => insert <= (others =>'0'); --BFCLR
+ when "101" => bf_fffo <= '1'; --BFFFO
+ when "110" => bf_bset <= '1'; --BFSET
+ when "111" => bf_ins <= '1'; --BFinS
+ when others => NULL;
+ end case;
+
+ -- ea is a register
+ if opcode(4 downto 3) = "00" then
+ bf_d32 <= '1';
+ end if;
+
+ bf_ext_out <= result(39 downto 32);
+ end if;
+ end if;
+
+ ------------- BF_SET2 --------------
+ if bf_ins = '1' then
+ bf_loff_dir <= 32 - bf_loffset;
+ else
+ bf_loff_dir <= bf_loffset;
+ end if;
+
+ if bf_d32 = '1' then
+ -- 32bit: rotate 0..31 bits left or right, don't care for upper 8 bits
+ bf_set2 <= "--------" & std_logic_vector(unsigned(OP2out) ror to_integer(unsigned(bf_loff_dir)));
+ else
+ if bf_ins = '1' then
+ -- 40 bit: shift 0..7 bits left
+ bf_set2 <= std_logic_vector(unsigned(bf_ext_in & OP2out) sll to_integer(unsigned(bf_loffset(2 downto 0))));
+ else
+ -- 40 bit: shift 0..7 bits right
+ bf_set2 <= std_logic_vector(unsigned(bf_ext_in & OP2out) srl to_integer(unsigned(bf_loffset(2 downto 0))));
+ end if;
+ end if;
+
+ ------------- COPY --------------
+ if bf_d32 = '1' then
+ -- 32bit: rotate 32 bits 0..31 bits left, don't care for upper 8 bits
+ copy <= "--------" & std_logic_vector(unsigned(sign) rol to_integer(unsigned(bf_loffset)));
+ else
+ -- 40 bit: shift 40 bits 0..7 bits left, fill with '1's (hence the two not's)
+ copy <= not std_logic_vector(unsigned(x"00" & (not sign)) sll to_integer(unsigned(bf_loffset(2 downto 0))));
+ end if;
+
+ if bf_ins = '1' then
+ datareg <= reg_QB;
+ else
+ datareg <= bf_set2(31 downto 0);
+ end if;
+
+ -- do the bitfield operation itself
+ if bf_ins = '1' then
+ result <= bf_set2;
+ elsif bf_bchg = '1' then
+ result <= not (bf_ext_in & OP1out);
+ elsif bf_bset = '1' then
+ result <= (others => '1');
+ else
+ result <= (others => '0');
+ end if;
+
+ sign <= (others => '0');
+ bf_NFlag <= datareg(to_integer(unsigned(bf_width)));
+ for i in 0 TO 31 loop
+ if i > bf_width then
+ datareg(i) <= '0';
+ sign(i) <= '1';
+ end if;
+ end loop;
+
+ -- Set bits 32..39 to 0 if operating on register to make sure
+ -- zero flag calculation over all 40 bits works correctly
+ result_tmp(31 downto 0) <= OP1out;
+ if bf_d32 = '1' then
+ result_tmp(39 downto 32) <= "00000000";
+ else
+ result_tmp(39 downto 32) <= bf_ext_in;
+ end if;
+
+ bf_flag_z <= '1';
+ if bf_d32 = '0' then
+ -- The test for this overflow shouldn't be needed. But GHDL complains
+ -- otherwise.
+ if(to_integer(unsigned('0' & bf_loffset)+unsigned(bf_width)) > 39) then
+ bf_flag_n <= result_tmp(39);
+ else
+ bf_flag_n <= result_tmp(to_integer(unsigned('0' & bf_loffset)+unsigned(bf_width)));
+ end if;
+ else
+ --TH: TODO: check if this really does what it's supposed to
+ bf_flag_n <= result_tmp(to_integer(unsigned(bf_loffset)+unsigned(bf_width)));
+ end if;
+ for i in 0 TO 39 loop
+ if copy(i) = '1' then
+ result(i) <= result_tmp(i);
+ elsif result_tmp(i) = '1' then
+ bf_flag_z <= '0';
+ end if;
+ end loop;
+
+ if bf_exts = '1' and bf_NFlag = '1' then
+ bf_datareg <= datareg OR sign;
+ else
+ bf_datareg <= datareg;
+ end if;
+
+ --BFFFO
+ if datareg(31) = '1' then bf_firstbit <= "100000";
+ elsif datareg(30) = '1' then bf_firstbit <= "011111";
+ elsif datareg(29) = '1' then bf_firstbit <= "011110";
+ elsif datareg(28) = '1' then bf_firstbit <= "011101";
+ elsif datareg(27) = '1' then bf_firstbit <= "011100";
+ elsif datareg(26) = '1' then bf_firstbit <= "011011";
+ elsif datareg(25) = '1' then bf_firstbit <= "011010";
+ elsif datareg(24) = '1' then bf_firstbit <= "011001";
+ elsif datareg(23) = '1' then bf_firstbit <= "011000";
+ elsif datareg(22) = '1' then bf_firstbit <= "010111";
+ elsif datareg(21) = '1' then bf_firstbit <= "010110";
+ elsif datareg(20) = '1' then bf_firstbit <= "010101";
+ elsif datareg(19) = '1' then bf_firstbit <= "010100";
+ elsif datareg(18) = '1' then bf_firstbit <= "010011";
+ elsif datareg(17) = '1' then bf_firstbit <= "010010";
+ elsif datareg(16) = '1' then bf_firstbit <= "010001";
+ elsif datareg(15) = '1' then bf_firstbit <= "010000";
+ elsif datareg(14) = '1' then bf_firstbit <= "001111";
+ elsif datareg(13) = '1' then bf_firstbit <= "001110";
+ elsif datareg(12) = '1' then bf_firstbit <= "001101";
+ elsif datareg(11) = '1' then bf_firstbit <= "001100";
+ elsif datareg(10) = '1' then bf_firstbit <= "001011";
+ elsif datareg(9) = '1' then bf_firstbit <= "001010";
+ elsif datareg(8) = '1' then bf_firstbit <= "001001";
+ elsif datareg(7) = '1' then bf_firstbit <= "001000";
+ elsif datareg(6) = '1' then bf_firstbit <= "000111";
+ elsif datareg(5) = '1' then bf_firstbit <= "000110";
+ elsif datareg(4) = '1' then bf_firstbit <= "000101";
+ elsif datareg(3) = '1' then bf_firstbit <= "000100";
+ elsif datareg(2) = '1' then bf_firstbit <= "000011";
+ elsif datareg(1) = '1' then bf_firstbit <= "000010";
+ elsif datareg(0) = '1' then bf_firstbit <= "000001";
+ else bf_firstbit <= "000000";
+ 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);
+ set_flags(1) <= '0';
+ elsif exec(opcSBCD) = '1' then
+ set_flags(0) <= bcd_s(8);
+ set_flags(1) <= '0';
+ 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(2) has correctly been set from set_flags
+ Flags(3) <= bf_NFlag;
+
+ --TH TODO: check flag handling of fffo
+
+ -- "normal" flags are taken from op2in
+ if bf_fffo = '0' and bf_extu='0' and bf_exts='0' and bf_ins='0' then
+ Flags(2) <= bf_flag_z;
+ Flags(3) <= bf_flag_n;
+ end if;
+ 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) <= (muls_msb & mulu_reg(63 downto 48) - (mulu_sign & faktorB(31 downto 16)));
+ else
+ result_mulu(63 downto 47) <= (muls_msb & mulu_reg(63 downto 48) + (mulu_sign & faktorB(31 downto 16)));
+ end if;
+ end if;
+ else -- 32 Bit xyz
+ result_mulu <= muls_msb & mulu_reg(63 downto 1);
+ if mulu_reg(0) = '1' then
+ if FAsign = '1' then
+ result_mulu(63 downto 31) <= (muls_msb & mulu_reg(63 downto 32) - (mulu_sign & faktorB));
+ else
+ result_mulu(63 downto 31) <= (muls_msb & mulu_reg(63 downto 32) + (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 0) <= (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) <= 0 - 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 <= (div_reg(63 downto 31)) + ('1' & OP2out(31 downto 0));
+ else
+ div_sub <= (div_reg(63 downto 31)) - ('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 <= 0 - 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) <= ('0' & div_reg(47 downto 32)) - ('0' & OP2out(15 downto 0));
+ else
+ div_over <= ('0' & div_reg(63 downto 32)) - ('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) <= 0 - 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) <= 0 - 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;
+
+ set_V_Flag_out <= set_V_Flag;
+ Flags_out <= Flags;
+ c_out_out <= c_out;
+ addsub_q_out <= addsub_q;
+
+end;
diff --git a/tests/tg68k/TG68K_Pack.vhd b/tests/tg68k/TG68K_Pack.vhd
index ceb9c69..5640fbf 100644
--- a/tests/tg68k/TG68K_Pack.vhd
+++ b/tests/tg68k/TG68K_Pack.vhd
@@ -1,247 +1,246 @@
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--- --
--- 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, rte4, rte5, trap00, 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 opcMOVECCR : integer := 3; --
- constant opcADD : integer := 4; --
- constant opcADDQ : integer := 5; --
- constant opcOR : integer := 6; --
- constant opcAND : integer := 7; --
- constant opcEOR : integer := 8; --
- constant opcCMP : integer := 9; --
- constant opcROT : integer := 10; --
- constant opcCPMAW : integer := 11;
- constant opcEXT : integer := 12; --
- constant opcABCD : integer := 13; --
- constant opcSBCD : integer := 14; --
- constant opcBITS : integer := 15; --
- constant opcSWAP : integer := 16; --
- constant opcScc : integer := 17; --
- constant andiSR : integer := 18; --
- constant eoriSR : integer := 19; --
- constant oriSR : integer := 20; --
- constant opcMULU : integer := 21; --
- constant opcDIVU : integer := 22; --
- constant dispouter : integer := 23; --
- constant rot_nop : integer := 24; --
- constant ld_rot_cnt : integer := 25; --
- constant writePC_add : integer := 26; --
- constant ea_data_OP1 : integer := 27; --
- constant ea_data_OP2 : integer := 28; --
- constant use_XZFlag : integer := 29; --
- constant get_bfoffset : integer := 30; --
- constant save_memaddr : integer := 31; --
- constant opcCHK : integer := 32; --
- constant movec_rd : integer := 33; --
- constant movec_wr : integer := 34; --
- constant Regwrena : integer := 35; --
- constant update_FC : integer := 36; --
- constant linksp : integer := 37; --
- constant movepl : integer := 38; --
- constant update_ld : integer := 39; --
- constant OP1addr : integer := 40; --
- constant write_reg : integer := 41; --
- constant changeMode : integer := 42; --
- constant ea_build : integer := 43; --
- constant trap_chk : integer := 44; --
- constant store_ea_data : integer := 45; --
- constant addrlong : integer := 46; --
- constant postadd : integer := 47; --
- constant presub : integer := 48; --
- constant subidx : integer := 49; --
- constant no_Flags : integer := 50; --
- constant use_SP : integer := 51; --
- constant to_CCR : integer := 52; --
- constant to_SR : integer := 53; --
- constant OP2out_one : integer := 54; --
- constant OP1out_zero : integer := 55; --
- constant mem_addsub : integer := 56; --
- constant addsub : integer := 57; --
- constant directPC : integer := 58; --
- constant direct_delta : integer := 59; --
- constant directSR : integer := 60; --
- constant directCCR : integer := 61; --
- constant exg : integer := 62; --
- constant get_ea_now : integer := 63; --
- constant ea_to_pc : integer := 64; --
- constant hold_dwr : integer := 65; --
- constant to_USP : integer := 66; --
- constant from_USP : integer := 67; --
- constant write_lowlong : integer := 68; --
- constant write_reminder : integer := 69; --
- constant movem_action : integer := 70; --
- constant briefext : integer := 71; --
- constant get_2ndOPC : integer := 72; --
- constant mem_byte : integer := 73; --
- constant longaktion : integer := 74; --
- constant opcRESET : integer := 75; --
- constant opcBF : integer := 76; --
- constant opcBFwb : integer := 77; --
- constant opcPACK : integer := 78; --
-
- constant lastOpcBit : integer := 78;
-
- type rTG68K_opc is record
- opcMOVE : bit;
- opcMOVEQ : bit;
- opcMOVESR : bit;
- opcMOVECCR : bit;
- opcADD : bit;
- opcADDQ : bit;
- opcOR : bit;
- opcAND : bit;
- opcEOR : bit;
- opcCMP : bit;
- opcROT : bit;
- opcCPMAW : bit;
- opcEXT : bit;
- opcABCD : bit;
- opcSBCD : bit;
- opcBITS : bit;
- opcSWAP : bit;
- opcScc : bit;
- andiSR : bit;
- eoriSR : bit;
- oriSR : bit;
- opcMULU : bit;
- opcDIVU : bit;
- dispouter : bit;
- rot_nop : bit;
- ld_rot_cnt : bit;
- writePC_add : bit;
- ea_data_OP1 : bit;
- ea_data_OP2 : bit;
- use_XZFlag : bit;
- get_bfoffset : bit;
- save_memaddr : bit;
- opcCHK : bit;
- movec_rd : bit;
- movec_wr : bit;
- Regwrena : bit;
- update_FC : bit;
- linksp : bit;
- movepl : bit;
- update_ld : bit;
- OP1addr : bit;
- write_reg : bit;
- changeMode : bit;
- ea_build : bit;
- trap_chk : bit;
- store_ea_data : bit;
- addrlong : bit;
- postadd : bit;
- presub : bit;
- subidx : bit;
- no_Flags : bit;
- use_SP : bit;
- to_CCR : bit;
- to_SR : bit;
- OP2out_one : bit;
- OP1out_zero : bit;
- mem_addsub : bit;
- addsub : bit;
- directPC : bit;
- direct_delta : bit;
- directSR : bit;
- directCCR : bit;
- exg : bit;
- get_ea_now : bit;
- ea_to_pc : bit;
- hold_dwr : bit;
- to_USP : bit;
- from_USP : bit;
- write_lowlong : bit;
- write_reminder : bit;
- movem_action : bit;
- briefext : bit;
- get_2ndOPC : bit;
- mem_byte : bit;
- longaktion : bit;
- opcRESET : bit;
- opcBF : bit;
- opcBFwb : bit;
- opcPACK : bit;
- end record;
-
- 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,
- BarrelShifter : integer := 0 --0=>no, 1=>yes, 2=>switchable with CPU(1)
- );
- port(
- clk : in std_logic;
- Reset : in std_logic;
- cpu : in std_logic_vector(1 downto 0);
- clkena_lw : in std_logic:='1';
- execOPC : in bit;
- exe_condition : in std_logic;
- exec_tas : in std_logic;
- long_start : in bit;
- non_aligned : in std_logic;
- movem_presub : in bit;
- set_stop : in bit;
- Z_error : in bit;
- rot_bits : in std_logic_vector(1 downto 0);
- rot_cnt : in std_logic_vector(5 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_width : in std_logic_vector(4 downto 0);
- bf_loffset : in std_logic_vector(4 downto 0);
- bf_offset : in std_logic_vector(31 downto 0);
- set_V_Flag_out : out bit;
- Flags_out : out std_logic_vector(7 downto 0);
- c_out_out : out std_logic_vector(2 downto 0);
- addsub_q_out : out std_logic_vector(31 downto 0);
- ALUout : out std_logic_vector(31 downto 0)
- );
- end component;
-
-end;
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- --
+-- 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, rtr1, rte1,
+ rte2, rte3, rte4, rte5, rtd1, rtd2, trap00, 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 opcMOVECCR : integer := 3; --
+ constant opcADD : integer := 4; --
+ constant opcADDQ : integer := 5; --
+ constant opcOR : integer := 6; --
+ constant opcAND : integer := 7; --
+ constant opcEOR : integer := 8; --
+ constant opcCMP : integer := 9; --
+ constant opcROT : integer := 10; --
+ constant opcCPMAW : integer := 11;
+ constant opcEXT : integer := 12; --
+ constant opcABCD : integer := 13; --
+ constant opcSBCD : integer := 14; --
+ constant opcBITS : integer := 15; --
+ constant opcSWAP : integer := 16; --
+ constant opcScc : integer := 17; --
+ constant andiSR : integer := 18; --
+ constant eoriSR : integer := 19; --
+ constant oriSR : integer := 20; --
+ constant opcMULU : integer := 21; --
+ constant opcDIVU : integer := 22; --
+ constant dispouter : integer := 23; --
+ constant rot_nop : integer := 24; --
+ constant ld_rot_cnt : integer := 25; --
+ constant writePC_add : integer := 26; --
+ constant ea_data_OP1 : integer := 27; --
+ constant ea_data_OP2 : integer := 28; --
+ constant use_XZFlag : integer := 29; --
+ constant get_bfoffset : integer := 30; --
+ constant save_memaddr : integer := 31; --
+ constant opcCHK : integer := 32; --
+ constant movec_rd : integer := 33; --
+ constant movec_wr : integer := 34; --
+ constant Regwrena : integer := 35; --
+ constant update_FC : integer := 36; --
+ constant linksp : integer := 37; --
+ constant movepl : integer := 38; --
+ constant update_ld : integer := 39; --
+ constant OP1addr : integer := 40; --
+ constant write_reg : integer := 41; --
+ constant changeMode : integer := 42; --
+ constant ea_build : integer := 43; --
+ constant trap_chk : integer := 44; --
+ constant store_ea_data : integer := 45; --
+ constant addrlong : integer := 46; --
+ constant postadd : integer := 47; --
+ constant presub : integer := 48; --
+ constant subidx : integer := 49; --
+ constant no_Flags : integer := 50; --
+ constant use_SP : integer := 51; --
+ constant to_CCR : integer := 52; --
+ constant to_SR : integer := 53; --
+ constant OP2out_one : integer := 54; --
+ constant OP1out_zero : integer := 55; --
+ constant mem_addsub : integer := 56; --
+ constant addsub : integer := 57; --
+ constant directPC : integer := 58; --
+ constant direct_delta : integer := 59; --
+ constant directSR : integer := 60; --
+ constant directCCR : integer := 61; --
+ constant exg : integer := 62; --
+ constant get_ea_now : integer := 63; --
+ constant ea_to_pc : integer := 64; --
+ constant hold_dwr : integer := 65; --
+ constant to_USP : integer := 66; --
+ constant from_USP : integer := 67; --
+ constant write_lowlong : integer := 68; --
+ constant write_reminder : integer := 69; --
+ constant movem_action : integer := 70; --
+ constant briefext : integer := 71; --
+ constant get_2ndOPC : integer := 72; --
+ constant mem_byte : integer := 73; --
+ constant longaktion : integer := 74; --
+ constant opcRESET : integer := 75; --
+ constant opcBF : integer := 76; --
+ constant opcBFwb : integer := 77; --
+ constant opcPACK : integer := 78; --
+ constant opcTRAPV : integer := 79; --
+
+ constant lastOpcBit : integer := 79;
+
+ type rTG68K_opc is record
+ opcMOVE : bit;
+ opcMOVEQ : bit;
+ opcMOVESR : bit;
+ opcMOVECCR : bit;
+ opcADD : bit;
+ opcADDQ : bit;
+ opcOR : bit;
+ opcAND : bit;
+ opcEOR : bit;
+ opcCMP : bit;
+ opcROT : bit;
+ opcCPMAW : bit;
+ opcEXT : bit;
+ opcABCD : bit;
+ opcSBCD : bit;
+ opcBITS : bit;
+ opcSWAP : bit;
+ opcScc : bit;
+ andiSR : bit;
+ eoriSR : bit;
+ oriSR : bit;
+ opcMULU : bit;
+ opcDIVU : bit;
+ dispouter : bit;
+ rot_nop : bit;
+ ld_rot_cnt : bit;
+ writePC_add : bit;
+ ea_data_OP1 : bit;
+ ea_data_OP2 : bit;
+ use_XZFlag : bit;
+ get_bfoffset : bit;
+ save_memaddr : bit;
+ opcCHK : bit;
+ movec_rd : bit;
+ movec_wr : bit;
+ Regwrena : bit;
+ update_FC : bit;
+ linksp : bit;
+ movepl : bit;
+ update_ld : bit;
+ OP1addr : bit;
+ write_reg : bit;
+ changeMode : bit;
+ ea_build : bit;
+ trap_chk : bit;
+ store_ea_data : bit;
+ addrlong : bit;
+ postadd : bit;
+ presub : bit;
+ subidx : bit;
+ no_Flags : bit;
+ use_SP : bit;
+ to_CCR : bit;
+ to_SR : bit;
+ OP2out_one : bit;
+ OP1out_zero : bit;
+ mem_addsub : bit;
+ addsub : bit;
+ directPC : bit;
+ direct_delta : bit;
+ directSR : bit;
+ directCCR : bit;
+ exg : bit;
+ get_ea_now : bit;
+ ea_to_pc : bit;
+ hold_dwr : bit;
+ to_USP : bit;
+ from_USP : bit;
+ write_lowlong : bit;
+ write_reminder : bit;
+ movem_action : bit;
+ briefext : bit;
+ get_2ndOPC : bit;
+ mem_byte : bit;
+ longaktion : bit;
+ opcRESET : bit;
+ opcBF : bit;
+ opcBFwb : bit;
+ opcPACK : bit;
+ opcTRAPV : bit;
+ end record;
+
+ 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;
+ non_aligned : in std_logic;
+ 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_width : in std_logic_vector(4 downto 0);
+ bf_loffset : in std_logic_vector(4 downto 0);
+ bf_offset : in std_logic_vector(31 downto 0);
+ set_V_Flag_out : out bit;
+ Flags_out : out std_logic_vector(7 downto 0);
+ c_out_out : out std_logic_vector(2 downto 0);
+ addsub_q_out : out 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
index 876376a..b9e656a 100644
--- a/tests/tg68k/TG68KdotC_Kernel.vhd
+++ b/tests/tg68k/TG68KdotC_Kernel.vhd
@@ -1,3456 +1,3575 @@
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--- --
--- Copyright (c) 2009-2013 Tobias Gubener --
--- Patches by MikeJ, Till Harbaum, Rok Krajnk, ... --
--- 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 . --
--- --
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-
--- optimize Register file
-
--- to do 68010:
--- (MOVEC)
--- BKPT
--- RTD
--- MOVES
---
--- to do 68020:
--- (CALLM)
--- (RETM)
-
--- CAS, CAS2
--- CHK2
--- CMP2
--- cpXXX coprocessor stuff
--- TRAPcc
-
--- done 020:
--- barrel shifter
--- PACK, UNPK
--- 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;
-
-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)
- BarrelShifter : 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 := '1'; -- ACTIVE LOW
- 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_out : out std_logic_vector(31 downto 0);
- data_write : out std_logic_vector(15 downto 0);
- nWr : out std_logic;
- nUDS : out std_logic;
- 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
- skipFetch : out std_logic;
- regin_out : out std_logic_vector(31 downto 0);
- CACR_out : out std_logic_vector( 3 downto 0);
- VBR_out : out std_logic_vector(31 downto 0)
- );
-end TG68KdotC_Kernel;
-
---nBS : std_logic_vector(3 downto 0); -- nBS0 is 31..24 3 is 7..0, active LOW
---SIZ : std_logic_vector(1 downto 0);
---ACK for 16/32 bit transfer?
-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 exe_pc : std_logic_vector(31 downto 0);
- signal last_opc_pc : std_logic_vector(31 downto 0);
- signal sndOPC : std_logic_vector(15 downto 0);
-
- signal last_opc_read : std_logic_vector(15 downto 0);
- signal reg_QA : std_logic_vector(31 downto 0);
- signal reg_QB : std_logic_vector(31 downto 0);
- signal Wwrena : bit;
- signal 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 := (OTHERS => (OTHERS => '0')); -- mikej stops sim X issues;
- signal RDindex_A : integer range 0 TO 15;
- signal RDindex_B : integer range 0 TO 15;
-
- signal WR_AReg : std_logic;
- signal addr : std_logic_vector(31 downto 0);
- 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 : std_logic_vector(31 downto 0);
- signal 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_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) := (others => '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 alu_rot_cnt : std_logic_vector(5 downto 0);
- signal set_alu_rot_cnt : std_logic_vector(5 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 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 non_aligned : std_logic;
- 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(31 downto 0);
- signal bf_offset_l : std_logic_vector(4 downto 0);
- signal bf_loffset : std_logic_vector(4 downto 0);
- signal bf_width : std_logic_vector(4 downto 0);
- signal bf_bhits : std_logic_vector(5 downto 0);
- signal alu_bf_width : std_logic_vector(4 downto 0);
- signal alu_bf_offset : std_logic_vector(31 downto 0);
- signal alu_bf_loffset : std_logic_vector(4 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;
-
- signal regin : std_logic_vector(31 downto 0);
-
-begin
-
- 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,
- BarrelShifter => BarrelShifter --0=>no, 1=>yes, 2=>switchable with CPU(1)
- )
- port map(
- clk => clk, --: in std_logic;
- Reset => Reset, --: in std_logic;
- cpu => cpu, --: in std_logic_vector(1 downto 0);
- 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;
- non_aligned => non_aligned,
- 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);
- rot_cnt => alu_rot_cnt, --: in std_logic_vector(5 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_width => alu_bf_width,
- bf_offset => alu_bf_offset,
- bf_loffset => alu_bf_loffset,
- set_V_Flag_out => set_V_Flag, --: buffer bit;
- Flags_out => Flags, --: buffer std_logic_vector(8 downto 0);
- c_out_out => c_out, --: buffer std_logic_vector(2 downto 0);
- addsub_q_out => 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));
-
- process (memmaskmux)
- begin
- non_aligned <= '0';
- if (memmaskmux(5 downto 4) = "01") or (memmaskmux(5 downto 4) = "10") then
- non_aligned <= '1';
- end if;
- end process;
- -----------------------------------------------------------------------------
- -- Bus control
- -----------------------------------------------------------------------------
- nWr <= '0' when state = "11" else '1';
- busstate <= state;
- nResetOut <= '0' when exec(opcRESET) = '1' else '1';
-
- -- does shift for byte access. note active low me
- -- should produce address error on 68000
- 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'; -- step
- 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; -- 32 bits
- 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 <= conv_integer(rf_dest_addr(3 downto 0));
- RDindex_B <= conv_integer(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 -- only used for movem
- 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, data_write_tmp)
- 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' and exec(opcPACK) = '0') 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' or set_PCbase='1' THEN --TH cmpi (d16,PC) fix
- 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=trap00 THEN
- data_write_tmp <= exe_pc; --TH
- elsif micro_state = trap0 then
- -- this is only active for 010+ since in 000 writePC is
- -- true in state trap0
- if trap_trace='1' then
- -- stack frame format #2
- data_write_tmp(15 downto 0) <= "0010" & trap_vector(11 downto 0); --TH
- else
- data_write_tmp(15 downto 0) <= "0000" & trap_vector(11 downto 0);
- end if;
- 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 -- mikej SCALE factor
- 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 12) <= (others => '0');
-
- if trap_berr='1' then
- trap_vector(11 downto 0) <= X"008";
- end IF;
-
- if trap_addr_error = '1' then
- trap_vector(11 downto 0) <= X"00C";
- end if;
-
- if trap_illegal = '1' then
- trap_vector(11 downto 0) <= X"010";
- end if;
-
- if z_error = '1' then
- trap_vector(11 downto 0) <= X"014";
- end if;
-
- if exec(trap_chk) = '1' then
- trap_vector(11 downto 0) <= X"018";
- end if;
-
- if trap_trapv = '1' then
- trap_vector(11 downto 0) <= X"01C";
- end if;
-
- if trap_priv = '1' then
- trap_vector(11 downto 0) <= X"020";
- end if;
-
- if trap_trace = '1' then
- trap_vector(11 downto 0) <= X"024";
- end if;
-
- if trap_1010 = '1' then
- trap_vector(11 downto 0) <= X"028";
- end if;
-
- if trap_1111 = '1' then
- trap_vector(11 downto 0) <= X"02C";
- end if;
-
- if trap_trap = '1' then
- trap_vector(11 downto 0) <= x"0" & "10" & opcode(3 downto 0) & "00";
- end if;
-
- if trap_interrupt = '1' then
- trap_vector(11 downto 0) <= "00" & 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 <= trap_vector + 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 <= briefdata + 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' then
- memaddr_delta <= addsub_q;
- elsif 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 <= ea_data + 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;
-
- -- only used for movem address update
- --if (long_done = '0' and state(1) = '1') or movem_presub = '0' then
- if ((memread(0) = '1') and state(1) = '1') or movem_presub = '0' then -- fix for unaligned movem mikej
- memaddr <= addr;
- end if;
- end if;
- end if;
- -- if access done, and not aligned, don't increment
- addr <= memaddr_reg + memaddr_delta;
- addr_out <= memaddr_reg + 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, set_alu_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 <= PC_dataa + 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) '0');
- bf_offset(4 downto 0) <= sndOPC(10 downto 6);
- end if;
- -- offset within long word
- bf_offset_l <= bf_offset(4 downto 0);
-
- if sndOPC(5) = '1' then
- bf_width <= reg_QB(4 downto 0) - 1;
- else
- bf_width <= sndOPC(4 downto 0) - 1;
- end if;
-
- bf_bhits <= ('0' & bf_width) + ('0' & bf_offset_l);
- set_oddout <= not bf_bhits(3);
-
- bf_loffset <= 31 - bf_bhits(4 downto 0);
- if opcode(4 downto 3) /= "00" then
- -- memory is being read with byte precision, thus offset
- -- bit 2:0 are only used in the alu
- bf_loffset(4 downto 3) <= "00";
- bf_offset_l(4 downto 3) <= "00";
- end if;
-
- case bf_bhits(5 downto 3) is
- when "000" =>
- 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';
- FlagsSR(2 downto 0) <= "111";
- FC(2) <= '1';
- SVmode <= '1';
- preSVmode <= '1';
- 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, last_data_in,
- 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";
- set_alu_rot_cnt <= "XXXXXX";
- 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';
- 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';
-
- -- decrement xyz
- if rot_cnt /= "000001" then
- set_rot_cnt <= 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
- if trap_trace='1' AND (VBR_Stackframe=1 or (cpu(0)='1' AND VBR_Stackframe=2)) then
- next_micro_state <= trap00; --TH
- else
- next_micro_state <= trap0;
- end if;
- -- 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' AND opcode(5 downto 0) /= "111111" 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'; -- 68000 also reads first
- 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(opcMOVECCR) <= '1';
- --datatype <= "00"; -- WRONG, should be WORD zero extended.
- datatype <= "01"; -- WRONG, should be WORD zero extended.
- write_back <= '1'; -- 68000 also reads first
- 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 movq instructions with a 1 here...
- if trap_interrupt = '0' and trap_trace = '0' then
- datatype <= "10"; --Long
- set_exec(Regwrena) <= '1';
- set_exec(opcMOVEQ) <= '1';
- set_exec(opcMOVE) <= '1';
- dest_hbits <= '1';
- end if;
- -- 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
-
- 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';
-
- -- BFCLR, BFSET, BFINS, BFCHG, BFFFO, BFTST
- if opcode(10) = '1' or opcode(8) = '0' then
- set_exec(opcBFwb) <= '1';
- -- BFFFO operating on memory
- if opcode(10 downto 8) = "101" and opcode(4 downto 3) /= "00" then
- set_exec(ea_data_OP2) <= '1';
- end if;
- set_exec(ea_data_OP1) <= '1';
- end if;
-
- -- BFCHG, BFCLR, BFSET, BFINS
- 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';
- -- BFEXTU, BFEXTS, BFFFO
- 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;
-
- -- register destination
- if opcode(4 downto 3) = "00" then
- -- bftst doesn't write
- if opcode(10 downto 8) /= "000" then
- set_exec(Regwrena) <= '1';
- end if;
-
- 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;
-
- if setexecOPC = '1' then
- if opcode(10 downto 8) = "111" then --BFINS
- source_2ndHbits <= '1';
- elsif opcode(10 downto 8)="001" or opcode(10 downto 8)="011" or
- opcode(10 downto 8)="101" THEN
- --BFEXTU, BFEXTS, BFFFO
- source_lowbits <= '1';
- dest_2ndHbits <= '1';
- end if;
- end if;
- end if;
- end if;
- else
- -- register rotation/shift
- 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
- -- load rotation count from register
- next_micro_state <= rota1;
- set(ld_rot_cnt) <= '1';
- setstate <= "01";
- else -- xyz
- set_alu_rot_cnt <= (others => '0');
- set_alu_rot_cnt(2 downto 0) <= opcode(11 downto 9);
- if opcode(11 downto 9) = "000" then set_alu_rot_cnt(3) <= '1';
- else set_alu_rot_cnt(3) <= '0';
- end if;
-
- -- take rotation count from opcode
- 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;
-
- -- use barrel shifter
- if BarrelShifter = 1 or (cpu(1) = '1' and BarrelShifter = 2) then
- set_rot_cnt <= "000001";
- 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
- -- mikej brief extension word only
- 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 trap00 => -- TRAP format #2
- next_micro_state <= trap0;
- set(presub) <= '1';
- setstackaddr <='1';
- setstate <= "11";
- datatype <= "10";
-
- 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
- -- additional word for 68020
- 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;
-
- -- return from exception - RTE
- -- fetch PC and status register from stack
- -- 010+ fetches another word containing
- -- the 12 bit vector offset and the
- -- frame format. If the frame format is
- -- 2 another two words have to be taken
- -- from the stack
- 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
- -- 010+ reads another word
- setstate <= "10";
- set(postadd) <= '1';
- setstackaddr <= '1';
- next_micro_state <= rte3;
- else
- next_micro_state <= nop;
- end if;
- when rte3 => -- RTE
- setstate <= "01"; -- idle state to wait
- -- for input data to
- -- arrive
- next_micro_state <= rte4;
- WHEN rte4 => -- RTE
- -- check for stack frame format #2
- if last_data_in(15 downto 12)="0010" then
- -- read another 32 bits in this case
- setstate <= "10"; -- read
- datatype <= "10"; -- long word
- set(postadd) <= '1';
- setstackaddr <= '1';
- next_micro_state <= rte5;
- else
- datatype <= "01";
- next_micro_state <= nop;
- end if;
- WHEN rte5 => -- RTE
- next_micro_state <= nop;
- 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 =>
- -- load rot_cnt from register, use barrel shifter
- if BarrelShifter = 1 or (cpu(1) = '1' and BarrelShifter = 2) then
- set_alu_rot_cnt <= OP2out(5 downto 0);
- else
- if OP2out(5 downto 0) /= "000000" then
- set_rot_cnt <= OP2out(5 downto 0);
- else
- set_exec(rot_nop) <= '1';
- end if;
- 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
- -- all other hexa codes should give illegal isntruction exception
- 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"000" => NULL; -- SFC -- 68010+
- when X"001" => NULL; -- DFC -- 68010+
- when X"002" => CACR <= reg_QA(3 downto 0); -- 68020+
- when X"800" => NULL; -- USP -- 68010+
- when X"801" => VBR <= reg_QA; -- 68010+
- when X"802" => NULL; -- CAAR -- 68020+
- when X"803" => NULL; -- MSP -- 68020+
- when X"804" => NULL; -- isP -- 68020+
- when others => NULL;
- end case;
- end if;
- end if;
-
- movec_data <= (others => '0');
- case brief(11 downto 0) is
- when X"002" => movec_data <= "0000000000000000000000000000" & (CACR AND "0011");
-
- 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;
-
- CACR_out <= CACR;
- VBR_out <= VBR;
-
- -----------------------------------------------------------------------------
- -- 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;
-
- --when the instruction has completed, the decremented address
- --register contains the address of the last operand stored. For
- --the MC68020, MC68030, and MC68040, if the addressing
- --register is also moved to memory, the value written is the
- --initial register value decremented by the size of the oper-
- --ation. The MC68000 writes the initial register value
- --(not decremented).
-
- regin_out <= regin;
- end;
-
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- --
+-- Copyright (c) 2009-2013 Tobias Gubener --
+-- Patches by MikeJ, Till Harbaum, Rok Krajnk, ... --
+-- 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 . --
+-- --
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+-- optimize Register file
+
+-- to do 68010:
+-- (MOVEC)
+-- BKPT (with debug hardware attached)
+-- MOVES
+--
+-- to do 68020:
+-- (CALLM)
+-- (RETM)
+
+-- CAS, CAS2
+-- CHK2
+-- CMP2
+-- cpXXX Coprozessor stuff
+-- TRAPcc
+
+-- done 020:
+-- PACK, UNPK
+-- Bitfields
+-- address modes
+-- long bra
+-- DIVS.L, DIVU.L
+-- LINK long
+-- MULS.L, MULU.L
+-- extb.l
+-- RTD
+
+library ieee;
+use ieee.std_logic_1164.ALL;
+use ieee.std_logic_unsigned.ALL;
+use work.TG68K_Pack.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 := '1'; -- ACTIVE LOW
+ 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_out : out std_logic_vector(31 downto 0);
+ data_write : out std_logic_vector(15 downto 0);
+ nWr : out std_logic;
+ nUDS : out std_logic;
+ 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
+ skipFetch : out std_logic;
+ regin_out : out std_logic_vector(31 downto 0);
+ CACR_out : out std_logic_vector( 3 downto 0);
+ VBR_out : out std_logic_vector(31 downto 0)
+ );
+end TG68KdotC_Kernel;
+
+--nBS : std_logic_vector(3 downto 0); -- nBS0 is 31..24 3 is 7..0, active LOW
+--SIZ : std_logic_vector(1 downto 0);
+--ACK for 16/32 bit transfer?
+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 exe_pc : std_logic_vector(31 downto 0);
+ signal last_opc_pc : std_logic_vector(31 downto 0);
+ signal sndOPC : std_logic_vector(15 downto 0);
+
+ signal last_opc_read : std_logic_vector(15 downto 0);
+ signal reg_QA : std_logic_vector(31 downto 0);
+ signal reg_QB : std_logic_vector(31 downto 0);
+ signal Wwrena : bit;
+ signal 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 := (OTHERS => (OTHERS => '0')); -- mikej stops sim X issues;
+ signal RDindex_A : integer range 0 TO 15;
+ signal RDindex_B : integer range 0 TO 15;
+
+ signal WR_AReg : std_logic;
+ signal addr : std_logic_vector(31 downto 0);
+ 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 : std_logic_vector(31 downto 0);
+ signal 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_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) := (others => '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 non_aligned : std_logic;
+ 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(31 downto 0);
+ signal bf_offset_l : std_logic_vector(4 downto 0);
+ signal bf_loffset : std_logic_vector(4 downto 0);
+ signal bf_width : std_logic_vector(4 downto 0);
+ signal bf_bhits : std_logic_vector(5 downto 0);
+ signal alu_bf_width : std_logic_vector(4 downto 0);
+ signal alu_bf_offset : std_logic_vector(31 downto 0);
+ signal alu_bf_loffset : std_logic_vector(4 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 exec_d : rTG68K_opc;
+
+ signal micro_state : micro_states;
+ signal next_micro_state : micro_states;
+
+ signal regin : std_logic_vector(31 downto 0);
+
+begin
+
+ 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;
+ non_aligned => non_aligned,
+ 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_width => alu_bf_width,
+ bf_offset => alu_bf_offset,
+ bf_loffset => alu_bf_loffset,
+ set_V_Flag_out => set_V_Flag, --: buffer bit;
+ Flags_out => Flags, --: buffer std_logic_vector(8 downto 0);
+ c_out_out => c_out, --: buffer std_logic_vector(2 downto 0);
+ addsub_q_out => 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));
+
+ process (memmaskmux)
+ begin
+ non_aligned <= '0';
+ if (memmaskmux(5 downto 4) = "01") or (memmaskmux(5 downto 4) = "10") then
+ non_aligned <= '1';
+ end if;
+ end process;
+ -----------------------------------------------------------------------------
+ -- Bus control
+ -----------------------------------------------------------------------------
+ nWr <= '0' when state = "11" else '1';
+ busstate <= state;
+ nResetOut <= '0' when exec(opcRESET) = '1' else '1';
+
+ -- does shift for byte access. note active low me
+ -- should produce address error on 68000
+ 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'; -- step
+ 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; -- 32 bits
+ 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 <= conv_integer(rf_dest_addr(3 downto 0));
+ RDindex_B <= conv_integer(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 -- only used for movem
+ 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
+ if opcode(15 downto 12) = "1110" then
+ rf_dest_addr <= '0' & sndOPC(8 downto 6);
+ else
+ rf_dest_addr <= sndOPC(9 downto 6);
+ end if;
+ elsif dest_2ndHbits = '1' then
+ rf_dest_addr <= '0' & sndOPC(14 downto 12);
+ elsif set(write_reminder) = '1' then
+ rf_dest_addr <= '0' & sndOPC(2 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 <= '0' & sndOPC(2 downto 0);
+ elsif source_2ndHbits = '1' then
+ rf_source_addr <= '0' & sndOPC(14 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, data_write_tmp)
+ 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' and exec(opcPACK) = '0') 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' and next_micro_state = idle 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' or set_PCbase='1' THEN --TH cmpi (d16,PC) fix
+ 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=trap00 THEN
+ data_write_tmp <= exe_pc; --TH
+ elsif micro_state = trap0 then
+ -- this is only active for 010+ since in 000 writePC is
+ -- true in state trap0
+ if trap_trace='1' or set_exec(opcTRAPV) = '1' then
+ -- stack frame format #2
+ data_write_tmp(15 downto 0) <= "0010" & trap_vector(11 downto 0); --TH
+ else
+ data_write_tmp(15 downto 0) <= "0000" & trap_vector(11 downto 0);
+ end if;
+ 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 -- mikej SCALE factor
+ 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 12) <= (others => '0');
+
+ if trap_berr='1' then
+ trap_vector(11 downto 0) <= X"008";
+ end IF;
+
+ if trap_addr_error = '1' then
+ trap_vector(11 downto 0) <= X"00C";
+ end if;
+
+ if trap_illegal = '1' then
+ trap_vector(11 downto 0) <= X"010";
+ end if;
+
+ if z_error = '1' then
+ trap_vector(11 downto 0) <= X"014";
+ end if;
+
+ if exec(trap_chk) = '1' then
+ trap_vector(11 downto 0) <= X"018";
+ end if;
+
+ if trap_trapv = '1' then
+ trap_vector(11 downto 0) <= X"01C";
+ end if;
+
+ if trap_priv = '1' then
+ trap_vector(11 downto 0) <= X"020";
+ end if;
+
+ if trap_trace = '1' then
+ trap_vector(11 downto 0) <= X"024";
+ end if;
+
+ if trap_1010 = '1' then
+ trap_vector(11 downto 0) <= X"028";
+ end if;
+
+ if trap_1111 = '1' then
+ trap_vector(11 downto 0) <= X"02C";
+ end if;
+
+ if trap_trap = '1' then
+ trap_vector(11 downto 0) <= x"0" & "10" & opcode(3 downto 0) & "00";
+ end if;
+
+ if trap_interrupt = '1' then
+ trap_vector(11 downto 0) <= "00" & 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 <= trap_vector + 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 <= briefdata + 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' then
+ memaddr_delta <= addsub_q;
+ elsif 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 <= ea_data + 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;
+
+ -- only used for movem address update
+ --if (long_done = '0' and state(1) = '1') or movem_presub = '0' then
+ if ((memread(0) = '1') and state(1) = '1') or movem_presub = '0' then -- fix for unaligned movem mikej
+ memaddr <= addr;
+ end if;
+ end if;
+ end if;
+ -- if access done, and not aligned, don't increment
+ addr <= memaddr_reg + memaddr_delta;
+ addr_out <= memaddr_reg + 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 <= PC_dataa + 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) '0');
+ bf_offset(4 downto 0) <= sndOPC(10 downto 6);
+ end if;
+ -- offset within long word
+ bf_offset_l <= bf_offset(4 downto 0);
+
+ if sndOPC(5) = '1' then
+ bf_width <= reg_QB(4 downto 0) - 1;
+ else
+ bf_width <= sndOPC(4 downto 0) - 1;
+ end if;
+
+ bf_bhits <= ('0' & bf_width) + ('0' & bf_offset_l);
+ set_oddout <= not bf_bhits(3);
+
+ bf_loffset <= 31 - bf_bhits(4 downto 0);
+ if opcode(4 downto 3) /= "00" then
+ -- memory is being read with byte precision, thus offset
+ -- bit 2:0 are only used in the alu
+ bf_loffset(4 downto 3) <= "00";
+ bf_offset_l(4 downto 3) <= "00";
+ end if;
+
+ case bf_bhits(5 downto 3) is
+ when "000" =>
+ 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) and x"f7");
+ elsif exec(orisR) = '1' then
+ SRin <= FlagsSR or (last_data_read(15 downto 8) and x"f7");
+ else
+ SRin <= OP2out(15 downto 8);
+ end if;
+
+ if rising_edge(clk) then
+ if Reset = '1' then
+ FlagsSR(5) <= '1';
+ FlagsSR(2 downto 0) <= "111";
+ FC(2) <= '1';
+ SVmode <= '1';
+ preSVmode <= '1';
+ 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_in, 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, trap_trapv)
+ 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 <= 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
+ if trap_trapv = '1' and (VBR_Stackframe = 1 or (cpu(0) = '1' and VBR_Stackframe = 2)) then
+ next_micro_state <= trap00;
+ else
+ next_micro_state <= trap0;
+ end if;
+ 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
+ if trap_trace='1' AND (VBR_Stackframe=1 or (cpu(0)='1' AND VBR_Stackframe=2)) then
+ next_micro_state <= trap00; --TH
+ else
+ next_micro_state <= trap0;
+ end if;
+ -- 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' AND opcode(5 downto 0) /= "111111" 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'; -- 68000 also reads first
+ 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(opcMOVECCR) <= '1';
+ --datatype <= "00"; -- WRONG, should be WORD zero extended.
+ datatype <= "01"; -- WRONG, should be WORD zero extended.
+ write_back <= '1'; -- 68000 also reads first
+ 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 (TODO: behavior with debug HW attached)
+ trap_illegal <= '1';
+ trapmake <= '1';
+ 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';
+ next_micro_state <= rtr1;
+ else
+ set(directSR) <= '1';
+ next_micro_state <= rte1;
+ end if;
+ end if;
+ else
+ trap_priv <= '1';
+ trapmake <= '1';
+ end if;
+
+ when "1110100" => --rtd
+ if VBR_Stackframe = 0 or (cpu(0) = '0' and VBR_Stackframe = 2) then
+ trap_illegal <= '1';
+ trapmake <= '1';
+ else
+ datatype <= "10";
+ set_exec(opcADD) <= '1'; --for displacement
+ set_exec(Regwrena) <= '1';
+ set(no_Flags) <= '1';
+ if decodeOPC = '1' then
+ setstate <= "10";
+ set(postadd) <= '1';
+ setstackaddr <= '1';
+ set(direct_delta) <= '1';
+ set(directPC) <= '1';
+ next_micro_state <= rtd1;
+ end if;
+ 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
+ set_exec(opcTRAPV) <= '1';
+ 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 movq instructions with a 1 here...
+ if trap_interrupt = '0' and trap_trace = '0' then
+ datatype <= "10"; --Long
+ set_exec(Regwrena) <= '1';
+ set_exec(opcMOVEQ) <= '1';
+ set_exec(opcMOVE) <= '1';
+ dest_hbits <= '1';
+ end if;
+ -- 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
+
+ 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';
+ if opcode(2 downto 0) = "111" then
+ set(use_SP) <= '1';
+ end if;
+ 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';
+ if opcode(2 downto 0) = "111" then
+ set(use_SP) <= '1';
+ end if;
+ 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';
+
+ -- BFCLR, BFSET, BFINS, BFCHG, BFFFO, BFTST
+ if opcode(10) = '1' or opcode(8) = '0' then
+ set_exec(opcBFwb) <= '1';
+ -- BFFFO operating on memory
+ if opcode(10 downto 8) = "101" and opcode(4 downto 3) /= "00" then
+ set_exec(ea_data_OP2) <= '1';
+ end if;
+ set_exec(ea_data_OP1) <= '1';
+ end if;
+
+ -- BFCHG, BFCLR, BFSET, BFINS
+ 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';
+ -- BFEXTU, BFEXTS, BFFFO
+ 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;
+
+ -- register destination
+ if opcode(4 downto 3) = "00" then
+ -- bftst doesn't write
+ if opcode(10 downto 8) /= "000" then
+ set_exec(Regwrena) <= '1';
+ end if;
+
+ 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;
+
+ if setexecOPC = '1' then
+ if opcode(10 downto 8) = "111" then --BFINS
+ source_2ndHbits <= '1';
+ elsif opcode(10 downto 8)="001" or opcode(10 downto 8)="011" or
+ opcode(10 downto 8)="101" THEN
+ --BFEXTU, BFEXTS, BFFFO
+ 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, ADDX, SUBX
+ 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';
+ if opcode(2 downto 0) = "111" then
+ set(use_SP) <= '1';
+ end if;
+ 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
+ -- mikej brief extension word only
+ 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';
+ if opcode(11 downto 9) = "111" then
+ set(use_SP) <= '1';
+ end if;
+ dest_hbits <= '1';
+ dest_areg <= '1';
+ setstate <= "10";
+
+ when cmpm => -- cmpm (Ay)+,(Ax)+
+ set_direct_data <= '1';
+ set(postadd) <= '1';
+ if opcode(11 downto 9) = "111" then
+ set(use_SP) <= '1';
+ end if;
+ 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 trap00 => -- TRAP format #2
+ next_micro_state <= trap0;
+ set(presub) <= '1';
+ setstackaddr <='1';
+ setstate <= "11";
+ datatype <= "10";
+
+ 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
+ -- additional word for 68020
+ 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 rtr1 => -- RTR
+ datatype <= "10";
+ setstate <= "10";
+ set(postadd) <= '1';
+ setstackaddr <= '1';
+ set(direct_delta) <= '1';
+ set(directPC) <= '1';
+ next_micro_state <= nopnop;
+
+ -- return from exception - RTE
+ -- fetch PC and status register from stack
+ -- 010+ fetches another word containing
+ -- the 12 bit vector offset and the
+ -- frame format. If the frame format is
+ -- 2 another two words have to be taken
+ -- from the stack
+ 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
+ -- 010+ reads another word
+ setstate <= "10";
+ set(postadd) <= '1';
+ setstackaddr <= '1';
+ next_micro_state <= rte3;
+ else
+ next_micro_state <= nop;
+ end if;
+ when rte3 => -- RTE
+ setstate <= "01"; -- idle state to wait
+ -- for input data to
+ -- arrive
+ next_micro_state <= rte4;
+ WHEN rte4 => -- RTE
+ -- check for stack frame format #2
+ if last_data_in(15 downto 12)="0010" then
+ -- read another 32 bits in this case
+ setstate <= "10"; -- read
+ datatype <= "10"; -- long word
+ set(postadd) <= '1';
+ setstackaddr <= '1';
+ next_micro_state <= rte5;
+ else
+ datatype <= "01";
+ next_micro_state <= nop;
+ end if;
+ WHEN rte5 => -- RTE
+ next_micro_state <= nop;
+
+ when rtd1 => -- RTD
+ set(store_ea_data) <= '1';
+ next_micro_state <= rtd2;
+
+ when rtd2 => -- RTD
+ setstackaddr <= '1';
+ set(ea_data_OP2) <= '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';
+ if opcode(11 downto 9) = "111" then
+ set(use_SP) <= '1';
+ end if;
+ 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
+ -- all other hexa codes should give illegal isntruction exception
+ 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"000" => NULL; -- SFC -- 68010+
+ when X"001" => NULL; -- DFC -- 68010+
+ when X"002" => CACR <= reg_QA(3 downto 0); -- 68020+
+ when X"800" => NULL; -- USP -- 68010+
+ when X"801" => VBR <= reg_QA; -- 68010+
+ when X"802" => NULL; -- CAAR -- 68020+
+ when X"803" => NULL; -- MSP -- 68020+
+ when X"804" => NULL; -- isP -- 68020+
+ when others => NULL;
+ end case;
+ end if;
+ end if;
+
+ movec_data <= (others => '0');
+ case brief(11 downto 0) is
+ when X"002" => movec_data <= "0000000000000000000000000000" & (CACR AND "0011");
+
+ 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;
+
+ CACR_out <= CACR;
+ VBR_out <= VBR;
+
+ -----------------------------------------------------------------------------
+ -- 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;
+
+ exec_d.opcMOVE <= exec(opcMOVE);
+ exec_d.opcMOVEQ <= exec(opcMOVEQ);
+ exec_d.opcMOVESR <= exec(opcMOVESR);
+ exec_d.opcMOVECCR <= exec(opcMOVECCR);
+ exec_d.opcADD <= exec(opcADD);
+ exec_d.opcADDQ <= exec(opcADDQ);
+ exec_d.opcor <= exec(opcor);
+ exec_d.opcand <= exec(opcand);
+ exec_d.opcEor <= exec(opcEor);
+ exec_d.opcCMP <= exec(opcCMP);
+ exec_d.opcROT <= exec(opcROT);
+ exec_d.opcCPMAW <= exec(opcCPMAW);
+ exec_d.opcEXT <= exec(opcEXT);
+ exec_d.opcABCD <= exec(opcABCD);
+ exec_d.opcSBCD <= exec(opcSBCD);
+ exec_d.opcBITS <= exec(opcBITS);
+ exec_d.opcSWAP <= exec(opcSWAP);
+ exec_d.opcScc <= exec(opcScc);
+ exec_d.andisR <= exec(andisR);
+ exec_d.eorisR <= exec(eorisR);
+ exec_d.orisR <= exec(orisR);
+ exec_d.opcMULU <= exec(opcMULU);
+ exec_d.opcDIVU <= exec(opcDIVU);
+ exec_d.dispouter <= exec(dispouter);
+ exec_d.rot_nop <= exec(rot_nop);
+ exec_d.ld_rot_cnt <= exec(ld_rot_cnt);
+ exec_d.writePC_add <= exec(writePC_add);
+ exec_d.ea_data_OP1 <= exec(ea_data_OP1);
+ exec_d.ea_data_OP2 <= exec(ea_data_OP2);
+ exec_d.use_XZFlag <= exec(use_XZFlag);
+ exec_d.get_bfoffset <= exec(get_bfoffset);
+ exec_d.save_memaddr <= exec(save_memaddr);
+ exec_d.opcCHK <= exec(opcCHK);
+ exec_d.movec_rd <= exec(movec_rd);
+ exec_d.movec_wr <= exec(movec_wr);
+ exec_d.Regwrena <= exec(Regwrena);
+ exec_d.update_FC <= exec(update_FC);
+ exec_d.linksp <= exec(linksp);
+ exec_d.movepl <= exec(movepl);
+ exec_d.update_ld <= exec(update_ld);
+ exec_d.OP1addr <= exec(OP1addr);
+ exec_d.write_reg <= exec(write_reg);
+ exec_d.changeMode <= exec(changeMode);
+ exec_d.ea_build <= exec(ea_build);
+ exec_d.trap_chk <= exec(trap_chk);
+ exec_d.store_ea_data <= exec(store_ea_data);
+ exec_d.addrlong <= exec(addrlong);
+ exec_d.postadd <= exec(postadd);
+ exec_d.presub <= exec(presub);
+ exec_d.subidx <= exec(subidx);
+ exec_d.no_Flags <= exec(no_Flags);
+ exec_d.use_SP <= exec(use_SP);
+ exec_d.to_CCR <= exec(to_CCR);
+ exec_d.to_SR <= exec(to_SR);
+ exec_d.OP2out_one <= exec(OP2out_one);
+ exec_d.OP1out_zero <= exec(OP1out_zero);
+ exec_d.mem_addsub <= exec(mem_addsub);
+ exec_d.addsub <= exec(addsub);
+ exec_d.directPC <= exec(directPC);
+ exec_d.direct_delta <= exec(direct_delta);
+ exec_d.directSR <= exec(directSR);
+ exec_d.directCCR <= exec(directCCR);
+ exec_d.exg <= exec(exg);
+ exec_d.get_ea_now <= exec(get_ea_now);
+ exec_d.ea_to_pc <= exec(ea_to_pc);
+ exec_d.hold_dwr <= exec(hold_dwr);
+ exec_d.to_USP <= exec(to_USP);
+ exec_d.from_USP <= exec(from_USP);
+ exec_d.write_lowlong <= exec(write_lowlong);
+ exec_d.write_reminder <= exec(write_reminder);
+ exec_d.movem_action <= exec(movem_action);
+ exec_d.briefext <= exec(briefext);
+ exec_d.get_2ndOPC <= exec(get_2ndOPC);
+ exec_d.mem_byte <= exec(mem_byte);
+ exec_d.longaktion <= exec(longaktion);
+ exec_d.opcRESET <= exec(opcRESET);
+ exec_d.opcBF <= exec(opcBF);
+ exec_d.opcBFwb <= exec(opcBFwb);
+ exec_d.opcPACK <= exec(opcPACK);
+ exec_d.opcTRAPV <= exec(opcTRAPV);
+ --when the instruction has completed, the decremented address
+ --register contains the address of the last operand stored. For
+ --the MC68020, MC68030, and MC68040, if the addressing
+ --register is also moved to memory, the value written is the
+ --initial register value decremented by the size of the oper-
+ --ation. The MC68000 writes the initial register value
+ --(not decremented).
+
+ regin_out <= regin;
+ end;
+
diff --git a/tests/tg68k/tests/mulu.s b/tests/tg68k/tests/mulu.s
new file mode 100644
index 0000000..50fd6e4
--- /dev/null
+++ b/tests/tg68k/tests/mulu.s
@@ -0,0 +1,23 @@
+ ;; 68020 mulu.l
+ ;; http://atari-forum.com/viewtopic.php?f=117&t=32761&start=925#p383381
+
+; move.l #$a26b,d0
+; move.l #$7667,d1
+; mulu.w d1,d0 ; 4B1EAB0D
+; move.l d0,testword1 ; to see value being written
+
+ move.l #$a26bd7e0,d0
+ move.l #$7667c08f,d1
+; mulu.l d0,d1
+ mulu.l d0,d1:d2
+ move.l d1,testword1 ; to see value being written
+ move.l d2,testword1 ; to see value being written
+ cmp.l #$b7459620,d1 ; 4B1F8910 B7459620
+ bne fail
+
+ move.l #$a26bd7e0,d0
+ move.l #$7667c08f,d1
+ mulu.l d1,d0
+ move.l d0,testword1 ; to see value being written
+ cmp.l #$b7459620,d0 ; 4B1F8910 B7459620
+ bne fail
diff --git a/tests/tg68k/tests/testsuite.s b/tests/tg68k/tests/testsuite.s
index 8999729..2306272 100644
--- a/tests/tg68k/tests/testsuite.s
+++ b/tests/tg68k/tests/testsuite.s
@@ -11,12 +11,14 @@ testword4 equ $10104
org $100
start:
; include "tests/cmpi_d16_pc.s"
- include "tests/bfxxx.s"
+; include "tests/longword.s"
+ include "tests/mulu.s"
+; include "tests/bfxxx.s"
; include "tests/bcd.s"
; include "tests/pack.s"
; include "tests/trace.s"
; include "tests/magic.s"
-
+
;; if all tests pass the code will arrive here
move.b #0,$beefed ; exit with result 0
loop: bra loop
diff --git a/tests/tg68k/tg68k_run.sav b/tests/tg68k/tg68k_run.sav
index 0a14efa..fc00c85 100644
--- a/tests/tg68k/tg68k_run.sav
+++ b/tests/tg68k/tg68k_run.sav
@@ -1,24 +1,24 @@
[*]
-[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
-[*] Mon Sep 21 14:01:15 2015
+[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI
+[*] Mon Oct 28 12:13:49 2019
[*]
-[dumpfile] "/home/tharbaum/tmp/mist/hdl/tests/tg68k_run/tg68k_run.ghw"
-[dumpfile_mtime] "Mon Sep 21 13:51:56 2015"
-[dumpfile_size] 375936
-[savefile] "/home/tharbaum/tmp/mist/hdl/tests/tg68k_run/tg68k_run.sav"
-[timestart] 16632300000
-[size] 1186 682
-[pos] 71 187
-*-27.000000 16860000000 -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
+[dumpfile] "/home/tharbaum/tmp/github/mist/hdl/tests/tg68k/tg68k_run.ghw"
+[dumpfile_mtime] "Mon Oct 28 12:12:48 2019"
+[dumpfile_size] 83278
+[savefile] "/home/tharbaum/tmp/github/mist/hdl/tests/tg68k/tg68k_run.sav"
+[timestart] 7420000000
+[size] 1618 979
+[pos] 262 107
+*-28.000000 7890000000 -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_run.
[treeopen] top.tg68k_run.tg68k.
[treeopen] top.tg68k_run.tg68k.alu.
[treeopen] top.tg68k_run.tg68k.regfile.
-[sst_width] 202
-[signals_width] 190
+[sst_width] 312
+[signals_width] 191
[sst_expanded] 1
-[sst_vpaned_height] 214
+[sst_vpaned_height] 337
@28
top.tg68k_run.clk
top.tg68k_run.reset_n
@@ -34,35 +34,77 @@ top.tg68k_run.reset_n
#{top.tg68k_run.tg68k.tg68_pc[31:0]} top.tg68k_run.tg68k.tg68_pc[31] top.tg68k_run.tg68k.tg68_pc[30] top.tg68k_run.tg68k.tg68_pc[29] top.tg68k_run.tg68k.tg68_pc[28] top.tg68k_run.tg68k.tg68_pc[27] top.tg68k_run.tg68k.tg68_pc[26] top.tg68k_run.tg68k.tg68_pc[25] top.tg68k_run.tg68k.tg68_pc[24] top.tg68k_run.tg68k.tg68_pc[23] top.tg68k_run.tg68k.tg68_pc[22] top.tg68k_run.tg68k.tg68_pc[21] top.tg68k_run.tg68k.tg68_pc[20] top.tg68k_run.tg68k.tg68_pc[19] top.tg68k_run.tg68k.tg68_pc[18] top.tg68k_run.tg68k.tg68_pc[17] top.tg68k_run.tg68k.tg68_pc[16] top.tg68k_run.tg68k.tg68_pc[15] top.tg68k_run.tg68k.tg68_pc[14] top.tg68k_run.tg68k.tg68_pc[13] top.tg68k_run.tg68k.tg68_pc[12] top.tg68k_run.tg68k.tg68_pc[11] top.tg68k_run.tg68k.tg68_pc[10] top.tg68k_run.tg68k.tg68_pc[9] top.tg68k_run.tg68k.tg68_pc[8] top.tg68k_run.tg68k.tg68_pc[7] top.tg68k_run.tg68k.tg68_pc[6] top.tg68k_run.tg68k.tg68_pc[5] top.tg68k_run.tg68k.tg68_pc[4] top.tg68k_run.tg68k.tg68_pc[3] top.tg68k_run.tg68k.tg68_pc[2] top.tg68k_run.tg68k.tg68_pc[1] top.tg68k_run.tg68k.tg68_pc[0]
@28
top.tg68k_run.tg68k.next_micro_state
+top.tg68k_run.tg68k.micro_state
top.tg68k_run.tg68k.setdisp
-@c00022
-#{top.tg68k_run.tg68k.flags[7:0]} top.tg68k_run.tg68k.flags[7] top.tg68k_run.tg68k.flags[6] top.tg68k_run.tg68k.flags[5] top.tg68k_run.tg68k.flags[4] top.tg68k_run.tg68k.flags[3] top.tg68k_run.tg68k.flags[2] top.tg68k_run.tg68k.flags[1] top.tg68k_run.tg68k.flags[0]
+@22
+#{top.tg68k_run.tg68k.tg68_pc[31:0]} top.tg68k_run.tg68k.tg68_pc[31] top.tg68k_run.tg68k.tg68_pc[30] top.tg68k_run.tg68k.tg68_pc[29] top.tg68k_run.tg68k.tg68_pc[28] top.tg68k_run.tg68k.tg68_pc[27] top.tg68k_run.tg68k.tg68_pc[26] top.tg68k_run.tg68k.tg68_pc[25] top.tg68k_run.tg68k.tg68_pc[24] top.tg68k_run.tg68k.tg68_pc[23] top.tg68k_run.tg68k.tg68_pc[22] top.tg68k_run.tg68k.tg68_pc[21] top.tg68k_run.tg68k.tg68_pc[20] top.tg68k_run.tg68k.tg68_pc[19] top.tg68k_run.tg68k.tg68_pc[18] top.tg68k_run.tg68k.tg68_pc[17] top.tg68k_run.tg68k.tg68_pc[16] top.tg68k_run.tg68k.tg68_pc[15] top.tg68k_run.tg68k.tg68_pc[14] top.tg68k_run.tg68k.tg68_pc[13] top.tg68k_run.tg68k.tg68_pc[12] top.tg68k_run.tg68k.tg68_pc[11] top.tg68k_run.tg68k.tg68_pc[10] top.tg68k_run.tg68k.tg68_pc[9] top.tg68k_run.tg68k.tg68_pc[8] top.tg68k_run.tg68k.tg68_pc[7] top.tg68k_run.tg68k.tg68_pc[6] top.tg68k_run.tg68k.tg68_pc[5] top.tg68k_run.tg68k.tg68_pc[4] top.tg68k_run.tg68k.tg68_pc[3] top.tg68k_run.tg68k.tg68_pc[2] top.tg68k_run.tg68k.tg68_pc[1] top.tg68k_run.tg68k.tg68_pc[0]
+[color] 2
+#{top.tg68k_run.tg68k.alu.datareg[31:0]} top.tg68k_run.tg68k.alu.datareg[31] top.tg68k_run.tg68k.alu.datareg[30] top.tg68k_run.tg68k.alu.datareg[29] top.tg68k_run.tg68k.alu.datareg[28] top.tg68k_run.tg68k.alu.datareg[27] top.tg68k_run.tg68k.alu.datareg[26] top.tg68k_run.tg68k.alu.datareg[25] top.tg68k_run.tg68k.alu.datareg[24] top.tg68k_run.tg68k.alu.datareg[23] top.tg68k_run.tg68k.alu.datareg[22] top.tg68k_run.tg68k.alu.datareg[21] top.tg68k_run.tg68k.alu.datareg[20] top.tg68k_run.tg68k.alu.datareg[19] top.tg68k_run.tg68k.alu.datareg[18] top.tg68k_run.tg68k.alu.datareg[17] top.tg68k_run.tg68k.alu.datareg[16] top.tg68k_run.tg68k.alu.datareg[15] top.tg68k_run.tg68k.alu.datareg[14] top.tg68k_run.tg68k.alu.datareg[13] top.tg68k_run.tg68k.alu.datareg[12] top.tg68k_run.tg68k.alu.datareg[11] top.tg68k_run.tg68k.alu.datareg[10] top.tg68k_run.tg68k.alu.datareg[9] top.tg68k_run.tg68k.alu.datareg[8] top.tg68k_run.tg68k.alu.datareg[7] top.tg68k_run.tg68k.alu.datareg[6] top.tg68k_run.tg68k.alu.datareg[5] top.tg68k_run.tg68k.alu.datareg[4] top.tg68k_run.tg68k.alu.datareg[3] top.tg68k_run.tg68k.alu.datareg[2] top.tg68k_run.tg68k.alu.datareg[1] top.tg68k_run.tg68k.alu.datareg[0]
+@24
+#{top.tg68k_run.tg68k.set_rot_cnt[5:0]} top.tg68k_run.tg68k.set_rot_cnt[5] top.tg68k_run.tg68k.set_rot_cnt[4] top.tg68k_run.tg68k.set_rot_cnt[3] top.tg68k_run.tg68k.set_rot_cnt[2] top.tg68k_run.tg68k.set_rot_cnt[1] top.tg68k_run.tg68k.set_rot_cnt[0]
+#{top.tg68k_run.tg68k.rot_cnt[5:0]} top.tg68k_run.tg68k.rot_cnt[5] top.tg68k_run.tg68k.rot_cnt[4] top.tg68k_run.tg68k.rot_cnt[3] top.tg68k_run.tg68k.rot_cnt[2] top.tg68k_run.tg68k.rot_cnt[1] top.tg68k_run.tg68k.rot_cnt[0]
@28
-top.tg68k_run.tg68k.flags[7]
-top.tg68k_run.tg68k.flags[6]
-top.tg68k_run.tg68k.flags[5]
-top.tg68k_run.tg68k.flags[4]
-top.tg68k_run.tg68k.flags[3]
-top.tg68k_run.tg68k.flags[2]
-top.tg68k_run.tg68k.flags[1]
-top.tg68k_run.tg68k.flags[0]
+#{top.tg68k_run.tg68k.rot_bits[1:0]} top.tg68k_run.tg68k.rot_bits[1] top.tg68k_run.tg68k.rot_bits[0]
+@22
+[color] 5
+#{top.tg68k_run.tg68k.alu.op1out[31:0]} top.tg68k_run.tg68k.alu.op1out[31] top.tg68k_run.tg68k.alu.op1out[30] top.tg68k_run.tg68k.alu.op1out[29] top.tg68k_run.tg68k.alu.op1out[28] top.tg68k_run.tg68k.alu.op1out[27] top.tg68k_run.tg68k.alu.op1out[26] top.tg68k_run.tg68k.alu.op1out[25] top.tg68k_run.tg68k.alu.op1out[24] top.tg68k_run.tg68k.alu.op1out[23] top.tg68k_run.tg68k.alu.op1out[22] top.tg68k_run.tg68k.alu.op1out[21] top.tg68k_run.tg68k.alu.op1out[20] top.tg68k_run.tg68k.alu.op1out[19] top.tg68k_run.tg68k.alu.op1out[18] top.tg68k_run.tg68k.alu.op1out[17] top.tg68k_run.tg68k.alu.op1out[16] top.tg68k_run.tg68k.alu.op1out[15] top.tg68k_run.tg68k.alu.op1out[14] top.tg68k_run.tg68k.alu.op1out[13] top.tg68k_run.tg68k.alu.op1out[12] top.tg68k_run.tg68k.alu.op1out[11] top.tg68k_run.tg68k.alu.op1out[10] top.tg68k_run.tg68k.alu.op1out[9] top.tg68k_run.tg68k.alu.op1out[8] top.tg68k_run.tg68k.alu.op1out[7] top.tg68k_run.tg68k.alu.op1out[6] top.tg68k_run.tg68k.alu.op1out[5] top.tg68k_run.tg68k.alu.op1out[4] top.tg68k_run.tg68k.alu.op1out[3] top.tg68k_run.tg68k.alu.op1out[2] top.tg68k_run.tg68k.alu.op1out[1] top.tg68k_run.tg68k.alu.op1out[0]
+#{top.tg68k_run.tg68k.alu.op1in[31:0]} top.tg68k_run.tg68k.alu.op1in[31] top.tg68k_run.tg68k.alu.op1in[30] top.tg68k_run.tg68k.alu.op1in[29] top.tg68k_run.tg68k.alu.op1in[28] top.tg68k_run.tg68k.alu.op1in[27] top.tg68k_run.tg68k.alu.op1in[26] top.tg68k_run.tg68k.alu.op1in[25] top.tg68k_run.tg68k.alu.op1in[24] top.tg68k_run.tg68k.alu.op1in[23] top.tg68k_run.tg68k.alu.op1in[22] top.tg68k_run.tg68k.alu.op1in[21] top.tg68k_run.tg68k.alu.op1in[20] top.tg68k_run.tg68k.alu.op1in[19] top.tg68k_run.tg68k.alu.op1in[18] top.tg68k_run.tg68k.alu.op1in[17] top.tg68k_run.tg68k.alu.op1in[16] top.tg68k_run.tg68k.alu.op1in[15] top.tg68k_run.tg68k.alu.op1in[14] top.tg68k_run.tg68k.alu.op1in[13] top.tg68k_run.tg68k.alu.op1in[12] top.tg68k_run.tg68k.alu.op1in[11] top.tg68k_run.tg68k.alu.op1in[10] top.tg68k_run.tg68k.alu.op1in[9] top.tg68k_run.tg68k.alu.op1in[8] top.tg68k_run.tg68k.alu.op1in[7] top.tg68k_run.tg68k.alu.op1in[6] top.tg68k_run.tg68k.alu.op1in[5] top.tg68k_run.tg68k.alu.op1in[4] top.tg68k_run.tg68k.alu.op1in[3] top.tg68k_run.tg68k.alu.op1in[2] top.tg68k_run.tg68k.alu.op1in[1] top.tg68k_run.tg68k.alu.op1in[0]
+#{top.tg68k_run.tg68k.aluout[31:0]} top.tg68k_run.tg68k.aluout[31] top.tg68k_run.tg68k.aluout[30] top.tg68k_run.tg68k.aluout[29] top.tg68k_run.tg68k.aluout[28] top.tg68k_run.tg68k.aluout[27] top.tg68k_run.tg68k.aluout[26] top.tg68k_run.tg68k.aluout[25] top.tg68k_run.tg68k.aluout[24] top.tg68k_run.tg68k.aluout[23] top.tg68k_run.tg68k.aluout[22] top.tg68k_run.tg68k.aluout[21] top.tg68k_run.tg68k.aluout[20] top.tg68k_run.tg68k.aluout[19] top.tg68k_run.tg68k.aluout[18] top.tg68k_run.tg68k.aluout[17] top.tg68k_run.tg68k.aluout[16] top.tg68k_run.tg68k.aluout[15] top.tg68k_run.tg68k.aluout[14] top.tg68k_run.tg68k.aluout[13] top.tg68k_run.tg68k.aluout[12] top.tg68k_run.tg68k.aluout[11] top.tg68k_run.tg68k.aluout[10] top.tg68k_run.tg68k.aluout[9] top.tg68k_run.tg68k.aluout[8] top.tg68k_run.tg68k.aluout[7] top.tg68k_run.tg68k.aluout[6] top.tg68k_run.tg68k.aluout[5] top.tg68k_run.tg68k.aluout[4] top.tg68k_run.tg68k.aluout[3] top.tg68k_run.tg68k.aluout[2] top.tg68k_run.tg68k.aluout[1] top.tg68k_run.tg68k.aluout[0]
+#{top.tg68k_run.tg68k.alu.rot_out[31:0]} top.tg68k_run.tg68k.alu.rot_out[31] top.tg68k_run.tg68k.alu.rot_out[30] top.tg68k_run.tg68k.alu.rot_out[29] top.tg68k_run.tg68k.alu.rot_out[28] top.tg68k_run.tg68k.alu.rot_out[27] top.tg68k_run.tg68k.alu.rot_out[26] top.tg68k_run.tg68k.alu.rot_out[25] top.tg68k_run.tg68k.alu.rot_out[24] top.tg68k_run.tg68k.alu.rot_out[23] top.tg68k_run.tg68k.alu.rot_out[22] top.tg68k_run.tg68k.alu.rot_out[21] top.tg68k_run.tg68k.alu.rot_out[20] top.tg68k_run.tg68k.alu.rot_out[19] top.tg68k_run.tg68k.alu.rot_out[18] top.tg68k_run.tg68k.alu.rot_out[17] top.tg68k_run.tg68k.alu.rot_out[16] top.tg68k_run.tg68k.alu.rot_out[15] top.tg68k_run.tg68k.alu.rot_out[14] top.tg68k_run.tg68k.alu.rot_out[13] top.tg68k_run.tg68k.alu.rot_out[12] top.tg68k_run.tg68k.alu.rot_out[11] top.tg68k_run.tg68k.alu.rot_out[10] top.tg68k_run.tg68k.alu.rot_out[9] top.tg68k_run.tg68k.alu.rot_out[8] top.tg68k_run.tg68k.alu.rot_out[7] top.tg68k_run.tg68k.alu.rot_out[6] top.tg68k_run.tg68k.alu.rot_out[5] top.tg68k_run.tg68k.alu.rot_out[4] top.tg68k_run.tg68k.alu.rot_out[3] top.tg68k_run.tg68k.alu.rot_out[2] top.tg68k_run.tg68k.alu.rot_out[1] top.tg68k_run.tg68k.alu.rot_out[0]
+#{top.tg68k_run.tg68k.alu.op2out[31:0]} top.tg68k_run.tg68k.alu.op2out[31] top.tg68k_run.tg68k.alu.op2out[30] top.tg68k_run.tg68k.alu.op2out[29] top.tg68k_run.tg68k.alu.op2out[28] top.tg68k_run.tg68k.alu.op2out[27] top.tg68k_run.tg68k.alu.op2out[26] top.tg68k_run.tg68k.alu.op2out[25] top.tg68k_run.tg68k.alu.op2out[24] top.tg68k_run.tg68k.alu.op2out[23] top.tg68k_run.tg68k.alu.op2out[22] top.tg68k_run.tg68k.alu.op2out[21] top.tg68k_run.tg68k.alu.op2out[20] top.tg68k_run.tg68k.alu.op2out[19] top.tg68k_run.tg68k.alu.op2out[18] top.tg68k_run.tg68k.alu.op2out[17] top.tg68k_run.tg68k.alu.op2out[16] top.tg68k_run.tg68k.alu.op2out[15] top.tg68k_run.tg68k.alu.op2out[14] top.tg68k_run.tg68k.alu.op2out[13] top.tg68k_run.tg68k.alu.op2out[12] top.tg68k_run.tg68k.alu.op2out[11] top.tg68k_run.tg68k.alu.op2out[10] top.tg68k_run.tg68k.alu.op2out[9] top.tg68k_run.tg68k.alu.op2out[8] top.tg68k_run.tg68k.alu.op2out[7] top.tg68k_run.tg68k.alu.op2out[6] top.tg68k_run.tg68k.alu.op2out[5] top.tg68k_run.tg68k.alu.op2out[4] top.tg68k_run.tg68k.alu.op2out[3] top.tg68k_run.tg68k.alu.op2out[2] top.tg68k_run.tg68k.alu.op2out[1] top.tg68k_run.tg68k.alu.op2out[0]
+#{top.tg68k_run.tg68k.alu.sndopc[15:0]} top.tg68k_run.tg68k.alu.sndopc[15] top.tg68k_run.tg68k.alu.sndopc[14] top.tg68k_run.tg68k.alu.sndopc[13] top.tg68k_run.tg68k.alu.sndopc[12] top.tg68k_run.tg68k.alu.sndopc[11] top.tg68k_run.tg68k.alu.sndopc[10] top.tg68k_run.tg68k.alu.sndopc[9] top.tg68k_run.tg68k.alu.sndopc[8] top.tg68k_run.tg68k.alu.sndopc[7] top.tg68k_run.tg68k.alu.sndopc[6] top.tg68k_run.tg68k.alu.sndopc[5] top.tg68k_run.tg68k.alu.sndopc[4] top.tg68k_run.tg68k.alu.sndopc[3] top.tg68k_run.tg68k.alu.sndopc[2] top.tg68k_run.tg68k.alu.sndopc[1] top.tg68k_run.tg68k.alu.sndopc[0]
+#{top.tg68k_run.tg68k.regfile[2][31:0]} top.tg68k_run.tg68k.regfile[2][31] top.tg68k_run.tg68k.regfile[2][30] top.tg68k_run.tg68k.regfile[2][29] top.tg68k_run.tg68k.regfile[2][28] top.tg68k_run.tg68k.regfile[2][27] top.tg68k_run.tg68k.regfile[2][26] top.tg68k_run.tg68k.regfile[2][25] top.tg68k_run.tg68k.regfile[2][24] top.tg68k_run.tg68k.regfile[2][23] top.tg68k_run.tg68k.regfile[2][22] top.tg68k_run.tg68k.regfile[2][21] top.tg68k_run.tg68k.regfile[2][20] top.tg68k_run.tg68k.regfile[2][19] top.tg68k_run.tg68k.regfile[2][18] top.tg68k_run.tg68k.regfile[2][17] top.tg68k_run.tg68k.regfile[2][16] top.tg68k_run.tg68k.regfile[2][15] top.tg68k_run.tg68k.regfile[2][14] top.tg68k_run.tg68k.regfile[2][13] top.tg68k_run.tg68k.regfile[2][12] top.tg68k_run.tg68k.regfile[2][11] top.tg68k_run.tg68k.regfile[2][10] top.tg68k_run.tg68k.regfile[2][9] top.tg68k_run.tg68k.regfile[2][8] top.tg68k_run.tg68k.regfile[2][7] top.tg68k_run.tg68k.regfile[2][6] top.tg68k_run.tg68k.regfile[2][5] top.tg68k_run.tg68k.regfile[2][4] top.tg68k_run.tg68k.regfile[2][3] top.tg68k_run.tg68k.regfile[2][2] top.tg68k_run.tg68k.regfile[2][1] top.tg68k_run.tg68k.regfile[2][0]
+@c00022
+#{top.tg68k_run.tg68k.regfile[1][31:0]} top.tg68k_run.tg68k.regfile[1][31] top.tg68k_run.tg68k.regfile[1][30] top.tg68k_run.tg68k.regfile[1][29] top.tg68k_run.tg68k.regfile[1][28] top.tg68k_run.tg68k.regfile[1][27] top.tg68k_run.tg68k.regfile[1][26] top.tg68k_run.tg68k.regfile[1][25] top.tg68k_run.tg68k.regfile[1][24] top.tg68k_run.tg68k.regfile[1][23] top.tg68k_run.tg68k.regfile[1][22] top.tg68k_run.tg68k.regfile[1][21] top.tg68k_run.tg68k.regfile[1][20] top.tg68k_run.tg68k.regfile[1][19] top.tg68k_run.tg68k.regfile[1][18] top.tg68k_run.tg68k.regfile[1][17] top.tg68k_run.tg68k.regfile[1][16] top.tg68k_run.tg68k.regfile[1][15] top.tg68k_run.tg68k.regfile[1][14] top.tg68k_run.tg68k.regfile[1][13] top.tg68k_run.tg68k.regfile[1][12] top.tg68k_run.tg68k.regfile[1][11] top.tg68k_run.tg68k.regfile[1][10] top.tg68k_run.tg68k.regfile[1][9] top.tg68k_run.tg68k.regfile[1][8] top.tg68k_run.tg68k.regfile[1][7] top.tg68k_run.tg68k.regfile[1][6] top.tg68k_run.tg68k.regfile[1][5] top.tg68k_run.tg68k.regfile[1][4] top.tg68k_run.tg68k.regfile[1][3] top.tg68k_run.tg68k.regfile[1][2] top.tg68k_run.tg68k.regfile[1][1] top.tg68k_run.tg68k.regfile[1][0]
+@28
+top.tg68k_run.tg68k.regfile[1][31]
+top.tg68k_run.tg68k.regfile[1][30]
+top.tg68k_run.tg68k.regfile[1][29]
+top.tg68k_run.tg68k.regfile[1][28]
+top.tg68k_run.tg68k.regfile[1][27]
+top.tg68k_run.tg68k.regfile[1][26]
+top.tg68k_run.tg68k.regfile[1][25]
+top.tg68k_run.tg68k.regfile[1][24]
+top.tg68k_run.tg68k.regfile[1][23]
+top.tg68k_run.tg68k.regfile[1][22]
+top.tg68k_run.tg68k.regfile[1][21]
+top.tg68k_run.tg68k.regfile[1][20]
+top.tg68k_run.tg68k.regfile[1][19]
+top.tg68k_run.tg68k.regfile[1][18]
+top.tg68k_run.tg68k.regfile[1][17]
+top.tg68k_run.tg68k.regfile[1][16]
+top.tg68k_run.tg68k.regfile[1][15]
+top.tg68k_run.tg68k.regfile[1][14]
+top.tg68k_run.tg68k.regfile[1][13]
+top.tg68k_run.tg68k.regfile[1][12]
+top.tg68k_run.tg68k.regfile[1][11]
+top.tg68k_run.tg68k.regfile[1][10]
+top.tg68k_run.tg68k.regfile[1][9]
+top.tg68k_run.tg68k.regfile[1][8]
+top.tg68k_run.tg68k.regfile[1][7]
+top.tg68k_run.tg68k.regfile[1][6]
+top.tg68k_run.tg68k.regfile[1][5]
+top.tg68k_run.tg68k.regfile[1][4]
+top.tg68k_run.tg68k.regfile[1][3]
+top.tg68k_run.tg68k.regfile[1][2]
+top.tg68k_run.tg68k.regfile[1][1]
+top.tg68k_run.tg68k.regfile[1][0]
@1401200
-group_end
@22
-#{top.tg68k_run.tg68k.alu.set_flags[3:0]} top.tg68k_run.tg68k.alu.set_flags[3] top.tg68k_run.tg68k.alu.set_flags[2] top.tg68k_run.tg68k.alu.set_flags[1] top.tg68k_run.tg68k.alu.set_flags[0]
-#{top.tg68k_run.tg68k.ea_data[31:0]} top.tg68k_run.tg68k.ea_data[31] top.tg68k_run.tg68k.ea_data[30] top.tg68k_run.tg68k.ea_data[29] top.tg68k_run.tg68k.ea_data[28] top.tg68k_run.tg68k.ea_data[27] top.tg68k_run.tg68k.ea_data[26] top.tg68k_run.tg68k.ea_data[25] top.tg68k_run.tg68k.ea_data[24] top.tg68k_run.tg68k.ea_data[23] top.tg68k_run.tg68k.ea_data[22] top.tg68k_run.tg68k.ea_data[21] top.tg68k_run.tg68k.ea_data[20] top.tg68k_run.tg68k.ea_data[19] top.tg68k_run.tg68k.ea_data[18] top.tg68k_run.tg68k.ea_data[17] top.tg68k_run.tg68k.ea_data[16] top.tg68k_run.tg68k.ea_data[15] top.tg68k_run.tg68k.ea_data[14] top.tg68k_run.tg68k.ea_data[13] top.tg68k_run.tg68k.ea_data[12] top.tg68k_run.tg68k.ea_data[11] top.tg68k_run.tg68k.ea_data[10] top.tg68k_run.tg68k.ea_data[9] top.tg68k_run.tg68k.ea_data[8] top.tg68k_run.tg68k.ea_data[7] top.tg68k_run.tg68k.ea_data[6] top.tg68k_run.tg68k.ea_data[5] top.tg68k_run.tg68k.ea_data[4] top.tg68k_run.tg68k.ea_data[3] top.tg68k_run.tg68k.ea_data[2] top.tg68k_run.tg68k.ea_data[1] top.tg68k_run.tg68k.ea_data[0]
-#{top.tg68k_run.tg68k.op2out[31:0]} top.tg68k_run.tg68k.op2out[31] top.tg68k_run.tg68k.op2out[30] top.tg68k_run.tg68k.op2out[29] top.tg68k_run.tg68k.op2out[28] top.tg68k_run.tg68k.op2out[27] top.tg68k_run.tg68k.op2out[26] top.tg68k_run.tg68k.op2out[25] top.tg68k_run.tg68k.op2out[24] top.tg68k_run.tg68k.op2out[23] top.tg68k_run.tg68k.op2out[22] top.tg68k_run.tg68k.op2out[21] top.tg68k_run.tg68k.op2out[20] top.tg68k_run.tg68k.op2out[19] top.tg68k_run.tg68k.op2out[18] top.tg68k_run.tg68k.op2out[17] top.tg68k_run.tg68k.op2out[16] top.tg68k_run.tg68k.op2out[15] top.tg68k_run.tg68k.op2out[14] top.tg68k_run.tg68k.op2out[13] top.tg68k_run.tg68k.op2out[12] top.tg68k_run.tg68k.op2out[11] top.tg68k_run.tg68k.op2out[10] top.tg68k_run.tg68k.op2out[9] top.tg68k_run.tg68k.op2out[8] top.tg68k_run.tg68k.op2out[7] top.tg68k_run.tg68k.op2out[6] top.tg68k_run.tg68k.op2out[5] top.tg68k_run.tg68k.op2out[4] top.tg68k_run.tg68k.op2out[3] top.tg68k_run.tg68k.op2out[2] top.tg68k_run.tg68k.op2out[1] top.tg68k_run.tg68k.op2out[0]
-@24
-#{top.tg68k_run.tg68k.alu.bf_shift[5:0]} top.tg68k_run.tg68k.alu.bf_shift[5] top.tg68k_run.tg68k.alu.bf_shift[4] top.tg68k_run.tg68k.alu.bf_shift[3] top.tg68k_run.tg68k.alu.bf_shift[2] top.tg68k_run.tg68k.alu.bf_shift[1] top.tg68k_run.tg68k.alu.bf_shift[0]
-@23
-#{top.tg68k_run.tg68k.alu.bf_loffset[4:0]} top.tg68k_run.tg68k.alu.bf_loffset[4] top.tg68k_run.tg68k.alu.bf_loffset[3] top.tg68k_run.tg68k.alu.bf_loffset[2] top.tg68k_run.tg68k.alu.bf_loffset[1] top.tg68k_run.tg68k.alu.bf_loffset[0]
+#{top.tg68k_run.tg68k.regfile[0][31:0]} top.tg68k_run.tg68k.regfile[0][31] top.tg68k_run.tg68k.regfile[0][30] top.tg68k_run.tg68k.regfile[0][29] top.tg68k_run.tg68k.regfile[0][28] top.tg68k_run.tg68k.regfile[0][27] top.tg68k_run.tg68k.regfile[0][26] top.tg68k_run.tg68k.regfile[0][25] top.tg68k_run.tg68k.regfile[0][24] top.tg68k_run.tg68k.regfile[0][23] top.tg68k_run.tg68k.regfile[0][22] top.tg68k_run.tg68k.regfile[0][21] top.tg68k_run.tg68k.regfile[0][20] top.tg68k_run.tg68k.regfile[0][19] top.tg68k_run.tg68k.regfile[0][18] top.tg68k_run.tg68k.regfile[0][17] top.tg68k_run.tg68k.regfile[0][16] top.tg68k_run.tg68k.regfile[0][15] top.tg68k_run.tg68k.regfile[0][14] top.tg68k_run.tg68k.regfile[0][13] top.tg68k_run.tg68k.regfile[0][12] top.tg68k_run.tg68k.regfile[0][11] top.tg68k_run.tg68k.regfile[0][10] top.tg68k_run.tg68k.regfile[0][9] top.tg68k_run.tg68k.regfile[0][8] top.tg68k_run.tg68k.regfile[0][7] top.tg68k_run.tg68k.regfile[0][6] top.tg68k_run.tg68k.regfile[0][5] top.tg68k_run.tg68k.regfile[0][4] top.tg68k_run.tg68k.regfile[0][3] top.tg68k_run.tg68k.regfile[0][2] top.tg68k_run.tg68k.regfile[0][1] top.tg68k_run.tg68k.regfile[0][0]
+#{top.tg68k_run.tg68k.alu.result_mulu[63:0]} top.tg68k_run.tg68k.alu.result_mulu[63] top.tg68k_run.tg68k.alu.result_mulu[62] top.tg68k_run.tg68k.alu.result_mulu[61] top.tg68k_run.tg68k.alu.result_mulu[60] top.tg68k_run.tg68k.alu.result_mulu[59] top.tg68k_run.tg68k.alu.result_mulu[58] top.tg68k_run.tg68k.alu.result_mulu[57] top.tg68k_run.tg68k.alu.result_mulu[56] top.tg68k_run.tg68k.alu.result_mulu[55] top.tg68k_run.tg68k.alu.result_mulu[54] top.tg68k_run.tg68k.alu.result_mulu[53] top.tg68k_run.tg68k.alu.result_mulu[52] top.tg68k_run.tg68k.alu.result_mulu[51] top.tg68k_run.tg68k.alu.result_mulu[50] top.tg68k_run.tg68k.alu.result_mulu[49] top.tg68k_run.tg68k.alu.result_mulu[48] top.tg68k_run.tg68k.alu.result_mulu[47] top.tg68k_run.tg68k.alu.result_mulu[46] top.tg68k_run.tg68k.alu.result_mulu[45] top.tg68k_run.tg68k.alu.result_mulu[44] top.tg68k_run.tg68k.alu.result_mulu[43] top.tg68k_run.tg68k.alu.result_mulu[42] top.tg68k_run.tg68k.alu.result_mulu[41] top.tg68k_run.tg68k.alu.result_mulu[40] top.tg68k_run.tg68k.alu.result_mulu[39] top.tg68k_run.tg68k.alu.result_mulu[38] top.tg68k_run.tg68k.alu.result_mulu[37] top.tg68k_run.tg68k.alu.result_mulu[36] top.tg68k_run.tg68k.alu.result_mulu[35] top.tg68k_run.tg68k.alu.result_mulu[34] top.tg68k_run.tg68k.alu.result_mulu[33] top.tg68k_run.tg68k.alu.result_mulu[32] top.tg68k_run.tg68k.alu.result_mulu[31] top.tg68k_run.tg68k.alu.result_mulu[30] top.tg68k_run.tg68k.alu.result_mulu[29] top.tg68k_run.tg68k.alu.result_mulu[28] top.tg68k_run.tg68k.alu.result_mulu[27] top.tg68k_run.tg68k.alu.result_mulu[26] top.tg68k_run.tg68k.alu.result_mulu[25] top.tg68k_run.tg68k.alu.result_mulu[24] top.tg68k_run.tg68k.alu.result_mulu[23] top.tg68k_run.tg68k.alu.result_mulu[22] top.tg68k_run.tg68k.alu.result_mulu[21] top.tg68k_run.tg68k.alu.result_mulu[20] top.tg68k_run.tg68k.alu.result_mulu[19] top.tg68k_run.tg68k.alu.result_mulu[18] top.tg68k_run.tg68k.alu.result_mulu[17] top.tg68k_run.tg68k.alu.result_mulu[16] top.tg68k_run.tg68k.alu.result_mulu[15] top.tg68k_run.tg68k.alu.result_mulu[14] top.tg68k_run.tg68k.alu.result_mulu[13] top.tg68k_run.tg68k.alu.result_mulu[12] top.tg68k_run.tg68k.alu.result_mulu[11] top.tg68k_run.tg68k.alu.result_mulu[10] top.tg68k_run.tg68k.alu.result_mulu[9] top.tg68k_run.tg68k.alu.result_mulu[8] top.tg68k_run.tg68k.alu.result_mulu[7] top.tg68k_run.tg68k.alu.result_mulu[6] top.tg68k_run.tg68k.alu.result_mulu[5] top.tg68k_run.tg68k.alu.result_mulu[4] top.tg68k_run.tg68k.alu.result_mulu[3] top.tg68k_run.tg68k.alu.result_mulu[2] top.tg68k_run.tg68k.alu.result_mulu[1] top.tg68k_run.tg68k.alu.result_mulu[0]
+#{top.tg68k_run.tg68k.alu.mulu_reg[63:0]} top.tg68k_run.tg68k.alu.mulu_reg[63] top.tg68k_run.tg68k.alu.mulu_reg[62] top.tg68k_run.tg68k.alu.mulu_reg[61] top.tg68k_run.tg68k.alu.mulu_reg[60] top.tg68k_run.tg68k.alu.mulu_reg[59] top.tg68k_run.tg68k.alu.mulu_reg[58] top.tg68k_run.tg68k.alu.mulu_reg[57] top.tg68k_run.tg68k.alu.mulu_reg[56] top.tg68k_run.tg68k.alu.mulu_reg[55] top.tg68k_run.tg68k.alu.mulu_reg[54] top.tg68k_run.tg68k.alu.mulu_reg[53] top.tg68k_run.tg68k.alu.mulu_reg[52] top.tg68k_run.tg68k.alu.mulu_reg[51] top.tg68k_run.tg68k.alu.mulu_reg[50] top.tg68k_run.tg68k.alu.mulu_reg[49] top.tg68k_run.tg68k.alu.mulu_reg[48] top.tg68k_run.tg68k.alu.mulu_reg[47] top.tg68k_run.tg68k.alu.mulu_reg[46] top.tg68k_run.tg68k.alu.mulu_reg[45] top.tg68k_run.tg68k.alu.mulu_reg[44] top.tg68k_run.tg68k.alu.mulu_reg[43] top.tg68k_run.tg68k.alu.mulu_reg[42] top.tg68k_run.tg68k.alu.mulu_reg[41] top.tg68k_run.tg68k.alu.mulu_reg[40] top.tg68k_run.tg68k.alu.mulu_reg[39] top.tg68k_run.tg68k.alu.mulu_reg[38] top.tg68k_run.tg68k.alu.mulu_reg[37] top.tg68k_run.tg68k.alu.mulu_reg[36] top.tg68k_run.tg68k.alu.mulu_reg[35] top.tg68k_run.tg68k.alu.mulu_reg[34] top.tg68k_run.tg68k.alu.mulu_reg[33] top.tg68k_run.tg68k.alu.mulu_reg[32] top.tg68k_run.tg68k.alu.mulu_reg[31] top.tg68k_run.tg68k.alu.mulu_reg[30] top.tg68k_run.tg68k.alu.mulu_reg[29] top.tg68k_run.tg68k.alu.mulu_reg[28] top.tg68k_run.tg68k.alu.mulu_reg[27] top.tg68k_run.tg68k.alu.mulu_reg[26] top.tg68k_run.tg68k.alu.mulu_reg[25] top.tg68k_run.tg68k.alu.mulu_reg[24] top.tg68k_run.tg68k.alu.mulu_reg[23] top.tg68k_run.tg68k.alu.mulu_reg[22] top.tg68k_run.tg68k.alu.mulu_reg[21] top.tg68k_run.tg68k.alu.mulu_reg[20] top.tg68k_run.tg68k.alu.mulu_reg[19] top.tg68k_run.tg68k.alu.mulu_reg[18] top.tg68k_run.tg68k.alu.mulu_reg[17] top.tg68k_run.tg68k.alu.mulu_reg[16] top.tg68k_run.tg68k.alu.mulu_reg[15] top.tg68k_run.tg68k.alu.mulu_reg[14] top.tg68k_run.tg68k.alu.mulu_reg[13] top.tg68k_run.tg68k.alu.mulu_reg[12] top.tg68k_run.tg68k.alu.mulu_reg[11] top.tg68k_run.tg68k.alu.mulu_reg[10] top.tg68k_run.tg68k.alu.mulu_reg[9] top.tg68k_run.tg68k.alu.mulu_reg[8] top.tg68k_run.tg68k.alu.mulu_reg[7] top.tg68k_run.tg68k.alu.mulu_reg[6] top.tg68k_run.tg68k.alu.mulu_reg[5] top.tg68k_run.tg68k.alu.mulu_reg[4] top.tg68k_run.tg68k.alu.mulu_reg[3] top.tg68k_run.tg68k.alu.mulu_reg[2] top.tg68k_run.tg68k.alu.mulu_reg[1] top.tg68k_run.tg68k.alu.mulu_reg[0]
+#{top.tg68k_run.tg68k.alu.mulu_signext[16:0]} top.tg68k_run.tg68k.alu.mulu_signext[16] top.tg68k_run.tg68k.alu.mulu_signext[15] top.tg68k_run.tg68k.alu.mulu_signext[14] top.tg68k_run.tg68k.alu.mulu_signext[13] top.tg68k_run.tg68k.alu.mulu_signext[12] top.tg68k_run.tg68k.alu.mulu_signext[11] top.tg68k_run.tg68k.alu.mulu_signext[10] top.tg68k_run.tg68k.alu.mulu_signext[9] top.tg68k_run.tg68k.alu.mulu_signext[8] top.tg68k_run.tg68k.alu.mulu_signext[7] top.tg68k_run.tg68k.alu.mulu_signext[6] top.tg68k_run.tg68k.alu.mulu_signext[5] top.tg68k_run.tg68k.alu.mulu_signext[4] top.tg68k_run.tg68k.alu.mulu_signext[3] top.tg68k_run.tg68k.alu.mulu_signext[2] top.tg68k_run.tg68k.alu.mulu_signext[1] top.tg68k_run.tg68k.alu.mulu_signext[0]
+@28
+top.tg68k_run.tg68k.alu.fasign
+top.tg68k_run.tg68k.alu.mulu_sign
@22
-#{top.tg68k_run.tg68k.alu.bf_set2[31:0]} top.tg68k_run.tg68k.alu.bf_set2[31] top.tg68k_run.tg68k.alu.bf_set2[30] top.tg68k_run.tg68k.alu.bf_set2[29] top.tg68k_run.tg68k.alu.bf_set2[28] top.tg68k_run.tg68k.alu.bf_set2[27] top.tg68k_run.tg68k.alu.bf_set2[26] top.tg68k_run.tg68k.alu.bf_set2[25] top.tg68k_run.tg68k.alu.bf_set2[24] top.tg68k_run.tg68k.alu.bf_set2[23] top.tg68k_run.tg68k.alu.bf_set2[22] top.tg68k_run.tg68k.alu.bf_set2[21] top.tg68k_run.tg68k.alu.bf_set2[20] top.tg68k_run.tg68k.alu.bf_set2[19] top.tg68k_run.tg68k.alu.bf_set2[18] top.tg68k_run.tg68k.alu.bf_set2[17] top.tg68k_run.tg68k.alu.bf_set2[16] top.tg68k_run.tg68k.alu.bf_set2[15] top.tg68k_run.tg68k.alu.bf_set2[14] top.tg68k_run.tg68k.alu.bf_set2[13] top.tg68k_run.tg68k.alu.bf_set2[12] top.tg68k_run.tg68k.alu.bf_set2[11] top.tg68k_run.tg68k.alu.bf_set2[10] top.tg68k_run.tg68k.alu.bf_set2[9] top.tg68k_run.tg68k.alu.bf_set2[8] top.tg68k_run.tg68k.alu.bf_set2[7] top.tg68k_run.tg68k.alu.bf_set2[6] top.tg68k_run.tg68k.alu.bf_set2[5] top.tg68k_run.tg68k.alu.bf_set2[4] top.tg68k_run.tg68k.alu.bf_set2[3] top.tg68k_run.tg68k.alu.bf_set2[2] top.tg68k_run.tg68k.alu.bf_set2[1] top.tg68k_run.tg68k.alu.bf_set2[0]
-#{top.tg68k_run.tg68k.alu.bf_datareg[31:0]} top.tg68k_run.tg68k.alu.bf_datareg[31] top.tg68k_run.tg68k.alu.bf_datareg[30] top.tg68k_run.tg68k.alu.bf_datareg[29] top.tg68k_run.tg68k.alu.bf_datareg[28] top.tg68k_run.tg68k.alu.bf_datareg[27] top.tg68k_run.tg68k.alu.bf_datareg[26] top.tg68k_run.tg68k.alu.bf_datareg[25] top.tg68k_run.tg68k.alu.bf_datareg[24] top.tg68k_run.tg68k.alu.bf_datareg[23] top.tg68k_run.tg68k.alu.bf_datareg[22] top.tg68k_run.tg68k.alu.bf_datareg[21] top.tg68k_run.tg68k.alu.bf_datareg[20] top.tg68k_run.tg68k.alu.bf_datareg[19] top.tg68k_run.tg68k.alu.bf_datareg[18] top.tg68k_run.tg68k.alu.bf_datareg[17] top.tg68k_run.tg68k.alu.bf_datareg[16] top.tg68k_run.tg68k.alu.bf_datareg[15] top.tg68k_run.tg68k.alu.bf_datareg[14] top.tg68k_run.tg68k.alu.bf_datareg[13] top.tg68k_run.tg68k.alu.bf_datareg[12] top.tg68k_run.tg68k.alu.bf_datareg[11] top.tg68k_run.tg68k.alu.bf_datareg[10] top.tg68k_run.tg68k.alu.bf_datareg[9] top.tg68k_run.tg68k.alu.bf_datareg[8] top.tg68k_run.tg68k.alu.bf_datareg[7] top.tg68k_run.tg68k.alu.bf_datareg[6] top.tg68k_run.tg68k.alu.bf_datareg[5] top.tg68k_run.tg68k.alu.bf_datareg[4] top.tg68k_run.tg68k.alu.bf_datareg[3] top.tg68k_run.tg68k.alu.bf_datareg[2] top.tg68k_run.tg68k.alu.bf_datareg[1] top.tg68k_run.tg68k.alu.bf_datareg[0]
-#{top.tg68k_run.tg68k.alu.datareg[31:0]} top.tg68k_run.tg68k.alu.datareg[31] top.tg68k_run.tg68k.alu.datareg[30] top.tg68k_run.tg68k.alu.datareg[29] top.tg68k_run.tg68k.alu.datareg[28] top.tg68k_run.tg68k.alu.datareg[27] top.tg68k_run.tg68k.alu.datareg[26] top.tg68k_run.tg68k.alu.datareg[25] top.tg68k_run.tg68k.alu.datareg[24] top.tg68k_run.tg68k.alu.datareg[23] top.tg68k_run.tg68k.alu.datareg[22] top.tg68k_run.tg68k.alu.datareg[21] top.tg68k_run.tg68k.alu.datareg[20] top.tg68k_run.tg68k.alu.datareg[19] top.tg68k_run.tg68k.alu.datareg[18] top.tg68k_run.tg68k.alu.datareg[17] top.tg68k_run.tg68k.alu.datareg[16] top.tg68k_run.tg68k.alu.datareg[15] top.tg68k_run.tg68k.alu.datareg[14] top.tg68k_run.tg68k.alu.datareg[13] top.tg68k_run.tg68k.alu.datareg[12] top.tg68k_run.tg68k.alu.datareg[11] top.tg68k_run.tg68k.alu.datareg[10] top.tg68k_run.tg68k.alu.datareg[9] top.tg68k_run.tg68k.alu.datareg[8] top.tg68k_run.tg68k.alu.datareg[7] top.tg68k_run.tg68k.alu.datareg[6] top.tg68k_run.tg68k.alu.datareg[5] top.tg68k_run.tg68k.alu.datareg[4] top.tg68k_run.tg68k.alu.datareg[3] top.tg68k_run.tg68k.alu.datareg[2] top.tg68k_run.tg68k.alu.datareg[1] top.tg68k_run.tg68k.alu.datareg[0]
-#{top.tg68k_run.tg68k.alu.op1in[31:0]} top.tg68k_run.tg68k.alu.op1in[31] top.tg68k_run.tg68k.alu.op1in[30] top.tg68k_run.tg68k.alu.op1in[29] top.tg68k_run.tg68k.alu.op1in[28] top.tg68k_run.tg68k.alu.op1in[27] top.tg68k_run.tg68k.alu.op1in[26] top.tg68k_run.tg68k.alu.op1in[25] top.tg68k_run.tg68k.alu.op1in[24] top.tg68k_run.tg68k.alu.op1in[23] top.tg68k_run.tg68k.alu.op1in[22] top.tg68k_run.tg68k.alu.op1in[21] top.tg68k_run.tg68k.alu.op1in[20] top.tg68k_run.tg68k.alu.op1in[19] top.tg68k_run.tg68k.alu.op1in[18] top.tg68k_run.tg68k.alu.op1in[17] top.tg68k_run.tg68k.alu.op1in[16] top.tg68k_run.tg68k.alu.op1in[15] top.tg68k_run.tg68k.alu.op1in[14] top.tg68k_run.tg68k.alu.op1in[13] top.tg68k_run.tg68k.alu.op1in[12] top.tg68k_run.tg68k.alu.op1in[11] top.tg68k_run.tg68k.alu.op1in[10] top.tg68k_run.tg68k.alu.op1in[9] top.tg68k_run.tg68k.alu.op1in[8] top.tg68k_run.tg68k.alu.op1in[7] top.tg68k_run.tg68k.alu.op1in[6] top.tg68k_run.tg68k.alu.op1in[5] top.tg68k_run.tg68k.alu.op1in[4] top.tg68k_run.tg68k.alu.op1in[3] top.tg68k_run.tg68k.alu.op1in[2] top.tg68k_run.tg68k.alu.op1in[1] top.tg68k_run.tg68k.alu.op1in[0]
-#{top.tg68k_run.tg68k.alu.bf_ext_in[7:0]} top.tg68k_run.tg68k.alu.bf_ext_in[7] top.tg68k_run.tg68k.alu.bf_ext_in[6] top.tg68k_run.tg68k.alu.bf_ext_in[5] top.tg68k_run.tg68k.alu.bf_ext_in[4] top.tg68k_run.tg68k.alu.bf_ext_in[3] top.tg68k_run.tg68k.alu.bf_ext_in[2] top.tg68k_run.tg68k.alu.bf_ext_in[1] top.tg68k_run.tg68k.alu.bf_ext_in[0]
-#{top.tg68k_run.tg68k.alu.reg_qb[31:0]} top.tg68k_run.tg68k.alu.reg_qb[31] top.tg68k_run.tg68k.alu.reg_qb[30] top.tg68k_run.tg68k.alu.reg_qb[29] top.tg68k_run.tg68k.alu.reg_qb[28] top.tg68k_run.tg68k.alu.reg_qb[27] top.tg68k_run.tg68k.alu.reg_qb[26] top.tg68k_run.tg68k.alu.reg_qb[25] top.tg68k_run.tg68k.alu.reg_qb[24] top.tg68k_run.tg68k.alu.reg_qb[23] top.tg68k_run.tg68k.alu.reg_qb[22] top.tg68k_run.tg68k.alu.reg_qb[21] top.tg68k_run.tg68k.alu.reg_qb[20] top.tg68k_run.tg68k.alu.reg_qb[19] top.tg68k_run.tg68k.alu.reg_qb[18] top.tg68k_run.tg68k.alu.reg_qb[17] top.tg68k_run.tg68k.alu.reg_qb[16] top.tg68k_run.tg68k.alu.reg_qb[15] top.tg68k_run.tg68k.alu.reg_qb[14] top.tg68k_run.tg68k.alu.reg_qb[13] top.tg68k_run.tg68k.alu.reg_qb[12] top.tg68k_run.tg68k.alu.reg_qb[11] top.tg68k_run.tg68k.alu.reg_qb[10] top.tg68k_run.tg68k.alu.reg_qb[9] top.tg68k_run.tg68k.alu.reg_qb[8] top.tg68k_run.tg68k.alu.reg_qb[7] top.tg68k_run.tg68k.alu.reg_qb[6] top.tg68k_run.tg68k.alu.reg_qb[5] top.tg68k_run.tg68k.alu.reg_qb[4] top.tg68k_run.tg68k.alu.reg_qb[3] top.tg68k_run.tg68k.alu.reg_qb[2] top.tg68k_run.tg68k.alu.reg_qb[1] top.tg68k_run.tg68k.alu.reg_qb[0]
-#{top.tg68k_run.tg68k.alu.result[39:0]} top.tg68k_run.tg68k.alu.result[39] top.tg68k_run.tg68k.alu.result[38] top.tg68k_run.tg68k.alu.result[37] top.tg68k_run.tg68k.alu.result[36] top.tg68k_run.tg68k.alu.result[35] top.tg68k_run.tg68k.alu.result[34] top.tg68k_run.tg68k.alu.result[33] top.tg68k_run.tg68k.alu.result[32] top.tg68k_run.tg68k.alu.result[31] top.tg68k_run.tg68k.alu.result[30] top.tg68k_run.tg68k.alu.result[29] top.tg68k_run.tg68k.alu.result[28] top.tg68k_run.tg68k.alu.result[27] top.tg68k_run.tg68k.alu.result[26] top.tg68k_run.tg68k.alu.result[25] top.tg68k_run.tg68k.alu.result[24] top.tg68k_run.tg68k.alu.result[23] top.tg68k_run.tg68k.alu.result[22] top.tg68k_run.tg68k.alu.result[21] top.tg68k_run.tg68k.alu.result[20] top.tg68k_run.tg68k.alu.result[19] top.tg68k_run.tg68k.alu.result[18] top.tg68k_run.tg68k.alu.result[17] top.tg68k_run.tg68k.alu.result[16] top.tg68k_run.tg68k.alu.result[15] top.tg68k_run.tg68k.alu.result[14] top.tg68k_run.tg68k.alu.result[13] top.tg68k_run.tg68k.alu.result[12] top.tg68k_run.tg68k.alu.result[11] top.tg68k_run.tg68k.alu.result[10] top.tg68k_run.tg68k.alu.result[9] top.tg68k_run.tg68k.alu.result[8] top.tg68k_run.tg68k.alu.result[7] top.tg68k_run.tg68k.alu.result[6] top.tg68k_run.tg68k.alu.result[5] top.tg68k_run.tg68k.alu.result[4] top.tg68k_run.tg68k.alu.result[3] top.tg68k_run.tg68k.alu.result[2] top.tg68k_run.tg68k.alu.result[1] top.tg68k_run.tg68k.alu.result[0]
+#{top.tg68k_run.tg68k.alu.faktora[31:0]} top.tg68k_run.tg68k.alu.faktora[31] top.tg68k_run.tg68k.alu.faktora[30] top.tg68k_run.tg68k.alu.faktora[29] top.tg68k_run.tg68k.alu.faktora[28] top.tg68k_run.tg68k.alu.faktora[27] top.tg68k_run.tg68k.alu.faktora[26] top.tg68k_run.tg68k.alu.faktora[25] top.tg68k_run.tg68k.alu.faktora[24] top.tg68k_run.tg68k.alu.faktora[23] top.tg68k_run.tg68k.alu.faktora[22] top.tg68k_run.tg68k.alu.faktora[21] top.tg68k_run.tg68k.alu.faktora[20] top.tg68k_run.tg68k.alu.faktora[19] top.tg68k_run.tg68k.alu.faktora[18] top.tg68k_run.tg68k.alu.faktora[17] top.tg68k_run.tg68k.alu.faktora[16] top.tg68k_run.tg68k.alu.faktora[15] top.tg68k_run.tg68k.alu.faktora[14] top.tg68k_run.tg68k.alu.faktora[13] top.tg68k_run.tg68k.alu.faktora[12] top.tg68k_run.tg68k.alu.faktora[11] top.tg68k_run.tg68k.alu.faktora[10] top.tg68k_run.tg68k.alu.faktora[9] top.tg68k_run.tg68k.alu.faktora[8] top.tg68k_run.tg68k.alu.faktora[7] top.tg68k_run.tg68k.alu.faktora[6] top.tg68k_run.tg68k.alu.faktora[5] top.tg68k_run.tg68k.alu.faktora[4] top.tg68k_run.tg68k.alu.faktora[3] top.tg68k_run.tg68k.alu.faktora[2] top.tg68k_run.tg68k.alu.faktora[1] top.tg68k_run.tg68k.alu.faktora[0]
+#{top.tg68k_run.tg68k.alu.faktorb[31:0]} top.tg68k_run.tg68k.alu.faktorb[31] top.tg68k_run.tg68k.alu.faktorb[30] top.tg68k_run.tg68k.alu.faktorb[29] top.tg68k_run.tg68k.alu.faktorb[28] top.tg68k_run.tg68k.alu.faktorb[27] top.tg68k_run.tg68k.alu.faktorb[26] top.tg68k_run.tg68k.alu.faktorb[25] top.tg68k_run.tg68k.alu.faktorb[24] top.tg68k_run.tg68k.alu.faktorb[23] top.tg68k_run.tg68k.alu.faktorb[22] top.tg68k_run.tg68k.alu.faktorb[21] top.tg68k_run.tg68k.alu.faktorb[20] top.tg68k_run.tg68k.alu.faktorb[19] top.tg68k_run.tg68k.alu.faktorb[18] top.tg68k_run.tg68k.alu.faktorb[17] top.tg68k_run.tg68k.alu.faktorb[16] top.tg68k_run.tg68k.alu.faktorb[15] top.tg68k_run.tg68k.alu.faktorb[14] top.tg68k_run.tg68k.alu.faktorb[13] top.tg68k_run.tg68k.alu.faktorb[12] top.tg68k_run.tg68k.alu.faktorb[11] top.tg68k_run.tg68k.alu.faktorb[10] top.tg68k_run.tg68k.alu.faktorb[9] top.tg68k_run.tg68k.alu.faktorb[8] top.tg68k_run.tg68k.alu.faktorb[7] top.tg68k_run.tg68k.alu.faktorb[6] top.tg68k_run.tg68k.alu.faktorb[5] top.tg68k_run.tg68k.alu.faktorb[4] top.tg68k_run.tg68k.alu.faktorb[3] top.tg68k_run.tg68k.alu.faktorb[2] top.tg68k_run.tg68k.alu.faktorb[1] top.tg68k_run.tg68k.alu.faktorb[0]
+@420
+top.tg68k_run.tg68k.rdindex_b
+@29
+top.tg68k_run.tg68k.source_2ndlbits
[pattern_trace] 1
[pattern_trace] 0
diff --git a/tests/tg68k/tg68k_run.vhd b/tests/tg68k/tg68k_run.vhd
index 94c7bd4..957ed3d 100644
--- a/tests/tg68k/tg68k_run.vhd
+++ b/tests/tg68k/tg68k_run.vhd
@@ -22,8 +22,7 @@ generic(
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)
- BarrelShifter : integer := 2 --0=>no, 1=>yes, 2=>switchable with CPU(1)
+ BitField : integer := 2 --0=>no, 1=>yes, 2=>switchable with CPU(1)
);
port (clk : in std_logic;
nReset : in std_logic; --low active