mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-04-30 13:52:33 +00:00
[TG68K] Barrel shifter in 68020 mode
This commit is contained in:
@@ -29,11 +29,13 @@ 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,
|
||||
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;
|
||||
@@ -171,12 +173,15 @@ architecture logic of TG68K_ALU IS
|
||||
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 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);
|
||||
@@ -458,7 +463,7 @@ begin
|
||||
-- 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)
|
||||
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
|
||||
@@ -621,7 +626,7 @@ begin
|
||||
-----------------------------------------------------------------------------
|
||||
-- Rotation
|
||||
-----------------------------------------------------------------------------
|
||||
process (exe_opcode, OP1out, Flags, rot_bits, rot_msb, rot_lsb, rot_cnt, rot_out, rot_rot, bs_data, bs_msb, exec)
|
||||
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
|
||||
@@ -676,49 +681,203 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- -------- barrel shifter ------------
|
||||
if rot_bits = "01" and exe_opcode(7 downto 6) /= "11" then
|
||||
-- currently only and LSL/LSR use the barrel shifter
|
||||
---------------------------------------------------------------------------
|
||||
--------------------------- 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 <ea> 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;
|
||||
|
||||
bs_data <= OP1out;
|
||||
bs_msb <= "11111";
|
||||
-- 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;
|
||||
|
||||
-- word size
|
||||
if exe_opcode(7 downto 6)="01" then
|
||||
bs_msb <= "01111";
|
||||
bs_data(31 downto 16) <= "0000000000000000";
|
||||
-- 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;
|
||||
|
||||
-- byte size
|
||||
if exe_opcode(7 downto 6)="00" then
|
||||
bs_msb <= "00111";
|
||||
bs_data(31 downto 8) <= "000000000000000000000000";
|
||||
end if;
|
||||
|
||||
if exe_opcode(8) = '1' then
|
||||
-- left
|
||||
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)));
|
||||
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
|
||||
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")));
|
||||
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);
|
||||
rot_C <= '0';
|
||||
else
|
||||
if(rot_cnt - 1 > bs_msb) then
|
||||
-- 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;
|
||||
|
||||
@@ -838,6 +997,12 @@ process (clk, Reset, exe_opcode, exe_datatype, Flags, last_data_read, OP2out, fl
|
||||
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
|
||||
|
||||
@@ -199,11 +199,13 @@ package TG68K_Pack is
|
||||
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,
|
||||
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;
|
||||
|
||||
@@ -36,10 +36,11 @@
|
||||
-- CAS, CAS2
|
||||
-- CHK2
|
||||
-- CMP2
|
||||
-- cpXXX Coprozessor stuff
|
||||
-- cpXXX coprocessor stuff
|
||||
-- TRAPcc
|
||||
|
||||
-- done 020:
|
||||
-- barrel shifter
|
||||
-- PACK, UNPK
|
||||
-- Bitfields
|
||||
-- address modes
|
||||
@@ -61,7 +62,8 @@ entity TG68KdotC_Kernel is
|
||||
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)
|
||||
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;
|
||||
@@ -227,9 +229,6 @@ architecture logic of TG68KdotC_Kernel is
|
||||
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);
|
||||
@@ -284,7 +283,6 @@ architecture logic of TG68KdotC_Kernel is
|
||||
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;
|
||||
@@ -296,11 +294,13 @@ 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,
|
||||
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;
|
||||
@@ -577,7 +577,7 @@ begin
|
||||
-----------------------------------------------------------------------------
|
||||
-- set OP1out
|
||||
-----------------------------------------------------------------------------
|
||||
process (reg_QA, store_in_tmp, ea_data, long_start, addr, exec, memmaskmux)
|
||||
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
|
||||
@@ -1295,7 +1295,7 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
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,
|
||||
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';
|
||||
@@ -1316,6 +1316,7 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
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';
|
||||
@@ -1335,9 +1336,6 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
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;
|
||||
@@ -2616,9 +2614,9 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
else
|
||||
set_rot_cnt(3) <= '0';
|
||||
end if;
|
||||
|
||||
-- lsr or lsl use a barrel shifter and are done immediately
|
||||
if opcode(4 downto 3) = "01" then
|
||||
|
||||
-- use barrel shifter
|
||||
if BarrelShifter = 1 or (cpu(1) = '1' and BarrelShifter = 2) then
|
||||
set_rot_cnt <= "000001";
|
||||
end if;
|
||||
|
||||
@@ -3264,8 +3262,8 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
set(opcDIVU) <= '1';
|
||||
|
||||
when rota1 =>
|
||||
-- load rot_cnt from register
|
||||
if opcode(4 downto 3) = "01" then -- lsl/lsr uses barrel shifter
|
||||
-- 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
|
||||
@@ -3445,85 +3443,6 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
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);
|
||||
--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
|
||||
|
||||
@@ -846,7 +846,7 @@ wire [15:0] cache_data_out = data_cache_hit?data_cache_data_out:inst_cache_data_
|
||||
wire [15:0] cpu_data_in = cacheRead?cache_data_out:system_data_out;
|
||||
|
||||
|
||||
TG68KdotC_Kernel #(2,2,2,2,2,2) tg68k (
|
||||
TG68KdotC_Kernel #(2,2,2,2,2,2,2) tg68k (
|
||||
.clk (clk_32 ),
|
||||
.nReset (~reset ),
|
||||
.clkena_in (clkena ),
|
||||
|
||||
@@ -29,11 +29,13 @@ 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,
|
||||
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;
|
||||
@@ -171,12 +173,15 @@ architecture logic of TG68K_ALU IS
|
||||
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 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);
|
||||
@@ -458,7 +463,7 @@ begin
|
||||
-- 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)
|
||||
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
|
||||
@@ -621,7 +626,7 @@ begin
|
||||
-----------------------------------------------------------------------------
|
||||
-- Rotation
|
||||
-----------------------------------------------------------------------------
|
||||
process (exe_opcode, OP1out, Flags, rot_bits, rot_msb, rot_lsb, rot_cnt, rot_out, rot_rot, bs_data, bs_msb, exec)
|
||||
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
|
||||
@@ -676,49 +681,203 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- -------- barrel shifter ------------
|
||||
if rot_bits = "01" and exe_opcode(7 downto 6) /= "11" then
|
||||
-- currently only and LSL/LSR use the barrel shifter
|
||||
---------------------------------------------------------------------------
|
||||
--------------------------- 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 <ea> 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;
|
||||
|
||||
bs_data <= OP1out;
|
||||
bs_msb <= "11111";
|
||||
-- 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;
|
||||
|
||||
-- word size
|
||||
if exe_opcode(7 downto 6)="01" then
|
||||
bs_msb <= "01111";
|
||||
bs_data(31 downto 16) <= "0000000000000000";
|
||||
-- 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;
|
||||
|
||||
-- byte size
|
||||
if exe_opcode(7 downto 6)="00" then
|
||||
bs_msb <= "00111";
|
||||
bs_data(31 downto 8) <= "000000000000000000000000";
|
||||
end if;
|
||||
|
||||
if exe_opcode(8) = '1' then
|
||||
-- left
|
||||
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)));
|
||||
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
|
||||
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")));
|
||||
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);
|
||||
rot_C <= '0';
|
||||
else
|
||||
if(rot_cnt - 1 > bs_msb) then
|
||||
-- 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;
|
||||
|
||||
@@ -838,6 +997,12 @@ process (clk, Reset, exe_opcode, exe_datatype, Flags, last_data_read, OP2out, fl
|
||||
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
|
||||
|
||||
@@ -199,11 +199,13 @@ package TG68K_Pack is
|
||||
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,
|
||||
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;
|
||||
|
||||
@@ -36,10 +36,11 @@
|
||||
-- CAS, CAS2
|
||||
-- CHK2
|
||||
-- CMP2
|
||||
-- cpXXX Coprozessor stuff
|
||||
-- cpXXX coprocessor stuff
|
||||
-- TRAPcc
|
||||
|
||||
-- done 020:
|
||||
-- barrel shifter
|
||||
-- PACK, UNPK
|
||||
-- Bitfields
|
||||
-- address modes
|
||||
@@ -61,7 +62,8 @@ entity TG68KdotC_Kernel is
|
||||
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)
|
||||
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;
|
||||
@@ -227,9 +229,6 @@ architecture logic of TG68KdotC_Kernel is
|
||||
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);
|
||||
@@ -284,7 +283,6 @@ architecture logic of TG68KdotC_Kernel is
|
||||
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;
|
||||
@@ -296,11 +294,13 @@ 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,
|
||||
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;
|
||||
@@ -577,7 +577,7 @@ begin
|
||||
-----------------------------------------------------------------------------
|
||||
-- set OP1out
|
||||
-----------------------------------------------------------------------------
|
||||
process (reg_QA, store_in_tmp, ea_data, long_start, addr, exec, memmaskmux)
|
||||
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
|
||||
@@ -1295,7 +1295,7 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
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,
|
||||
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';
|
||||
@@ -1316,6 +1316,7 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
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';
|
||||
@@ -1335,9 +1336,6 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
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;
|
||||
@@ -2616,9 +2614,9 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
else
|
||||
set_rot_cnt(3) <= '0';
|
||||
end if;
|
||||
|
||||
-- lsr or lsl use a barrel shifter and are done immediately
|
||||
if opcode(4 downto 3) = "01" then
|
||||
|
||||
-- use barrel shifter
|
||||
if BarrelShifter = 1 or (cpu(1) = '1' and BarrelShifter = 2) then
|
||||
set_rot_cnt <= "000001";
|
||||
end if;
|
||||
|
||||
@@ -3264,8 +3262,8 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
set(opcDIVU) <= '1';
|
||||
|
||||
when rota1 =>
|
||||
-- load rot_cnt from register
|
||||
if opcode(4 downto 3) = "01" then -- lsl/lsr uses barrel shifter
|
||||
-- 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
|
||||
@@ -3445,85 +3443,6 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
|
||||
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);
|
||||
--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
|
||||
|
||||
@@ -22,7 +22,8 @@ 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)
|
||||
BitField : integer := 2; --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
||||
BarrelShifter : integer := 2 --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
||||
);
|
||||
port (clk : in std_logic;
|
||||
nReset : in std_logic; --low active
|
||||
|
||||
Reference in New Issue
Block a user