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