1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-01-27 04:11:51 +00:00

[TG68K] Tests with lsr/lsl barrel shifter

This commit is contained in:
Till Harbaum
2016-01-27 11:22:35 +01:00
parent 11e93b2879
commit 926af02ee0
7 changed files with 4578 additions and 4271 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -27,104 +27,98 @@ package TG68K_Pack is
type micro_states is (idle, nop, ld_nn, st_nn, ld_dAn1, ld_AnXn1, ld_AnXn2, st_dAn1, ld_AnXnbd1, ld_AnXnbd2, ld_AnXnbd3,
ld_229_1, ld_229_2, ld_229_3, ld_229_4, st_229_1, st_229_2, st_229_3, st_229_4,
st_AnXn1, st_AnXn2, bra1, bsr1, bsr2, nopnop, dbcc1, movem1, movem2, movem3,
andi, op_AxAy, cmpm, link1, link2, unlink1, unlink2, int1, int2, int3, int4, rte1, rte2, rte3, trap0, trap1, trap2, trap3,
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 opcADD : integer := 3; --
constant opcADDQ : integer := 4; --
constant opcOR : integer := 5; --
constant opcAND : integer := 6; --
constant opcEOR : integer := 7; --
constant opcCMP : integer := 8; --
constant opcROT : integer := 9; --
constant opcCPMAW : integer := 10;
constant opcEXT : integer := 11; --
constant opcABCD : integer := 12; --
constant opcSBCD : integer := 13; --
constant opcBITS : integer := 14; --
constant opcSWAP : integer := 15; --
constant opcScc : integer := 16; --
constant andiSR : integer := 17; --
constant eoriSR : integer := 18; --
constant oriSR : integer := 19; --
constant opcMULU : integer := 20; --
constant opcDIVU : integer := 21; --
constant dispouter : integer := 22; --
constant rot_nop : integer := 23; --
constant ld_rot_cnt : integer := 24; --
constant writePC_add : integer := 25; --
constant ea_data_OP1 : integer := 26; --
constant ea_data_OP2 : integer := 27; --
constant use_XZFlag : integer := 28; --
constant get_bfoffset : integer := 29; --
constant save_memaddr : integer := 30; --
constant opcCHK : integer := 31; --
constant movec_rd : integer := 32; --
constant movec_wr : integer := 33; --
constant Regwrena : integer := 34; --
constant update_FC : integer := 35; --
constant linksp : integer := 36; --
constant movepl : integer := 37; --
constant update_ld : integer := 38; --
constant OP1addr : integer := 39; --
constant write_reg : integer := 40; --
constant changeMode : integer := 41; --
constant ea_build : integer := 42; --
constant trap_chk : integer := 43; --
constant store_ea_data : integer := 44; --
constant addrlong : integer := 45; --
constant postadd : integer := 46; --
constant presub : integer := 47; --
constant subidx : integer := 48; --
constant no_Flags : integer := 49; --
constant use_SP : integer := 50; --
constant to_CCR : integer := 51; --
constant to_SR : integer := 52; --
constant OP2out_one : integer := 53; --
constant OP1out_zero : integer := 54; --
constant mem_addsub : integer := 55; --
constant addsub : integer := 56; --
constant directPC : integer := 57; --
constant direct_delta : integer := 58; --
constant directSR : integer := 59; --
constant directCCR : integer := 60; --
constant exg : integer := 61; --
constant get_ea_now : integer := 62; --
constant ea_to_pc : integer := 63; --
constant hold_dwr : integer := 64; --
constant to_USP : integer := 65; --
constant from_USP : integer := 66; --
constant write_lowlong : integer := 67; --
constant write_reminder : integer := 68; --
constant movem_action : integer := 69; --
constant briefext : integer := 70; --
constant get_2ndOPC : integer := 71; --
constant mem_byte : integer := 72; --
constant longaktion : integer := 73; --
constant opcRESET : integer := 74; --
constant opcBF : integer := 75; --
constant opcBFwb : integer := 76; --
constant s2nd_hbits : integer := 77; --
constant opcPACK : integer := 77; --
-- constant s2nd_hbits : integer := 77; --
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 : integer := 75; --
-- constant : integer := 76; --
-- constant : integer := 7; --
-- constant : integer := 7; --
-- constant : integer := 7; --
constant lastOpcBit : integer := 77;
constant lastOpcBit : integer := 78;
type rTG68K_opc is record
opcMOVE : bit;
opcMOVEQ : bit;
opcMOVESR : bit;
opcMOVECCR : bit;
opcADD : bit;
opcADDQ : bit;
opcOR : bit;
@@ -199,7 +193,7 @@ package TG68K_Pack is
opcRESET : bit;
opcBF : bit;
opcBFwb : bit;
s2nd_hbits : bit;
opcPACK : bit;
end record;
component TG68K_ALU
@@ -208,41 +202,42 @@ package TG68K_Pack is
DIV_Mode : integer := 0 --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV,
);
port(
clk : in std_logic;
Reset : in std_logic;
clkena_lw : in std_logic:='1';
execOPC : in bit;
exe_condition : in std_logic;
exec_tas : in std_logic;
long_start : in bit;
movem_presub : in bit;
set_stop : in bit;
Z_error : in bit;
rot_bits : in std_logic_vector(1 downto 0);
exec : in bit_vector(lastOpcBit downto 0);
OP1out : in std_logic_vector(31 downto 0);
OP2out : in std_logic_vector(31 downto 0);
reg_QA : in std_logic_vector(31 downto 0);
reg_QB : in std_logic_vector(31 downto 0);
opcode : in std_logic_vector(15 downto 0);
datatype : in std_logic_vector(1 downto 0);
exe_opcode : in std_logic_vector(15 downto 0);
exe_datatype : in std_logic_vector(1 downto 0);
sndOPC : in std_logic_vector(15 downto 0);
last_data_read : in std_logic_vector(15 downto 0);
data_read : in std_logic_vector(15 downto 0);
FlagsSR : in std_logic_vector(7 downto 0);
micro_state : in micro_states;
bf_ext_in : in std_logic_vector(7 downto 0);
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);
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_shift : in std_logic_vector(5 downto 0);
bf_width : in std_logic_vector(5 downto 0);
bf_loffset : in std_logic_vector(4 downto 0);
set_V_Flag : buffer bit;
Flags : buffer std_logic_vector(7 downto 0);
c_out : buffer std_logic_vector(2 downto 0);
addsub_q : buffer std_logic_vector(31 downto 0);
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;

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/********************************************/
/* */
/********************************************/
module mist_top (
// clock inputs
input wire [ 2-1:0] CLOCK_27, // 27 MHz
@@ -856,7 +856,7 @@ TG68KdotC_Kernel #(2,2,2,2,2,2) tg68k (
.berr (tg68_berr ),
.clr_berr (tg68_clr_berr ),
.CPU (system_ctrl[5:4] ), // 00=68000
.addr (tg68_adr_S ),
.addr_out (tg68_adr_S ),
.data_write (tg68_dat_out_S),
.nUDS (tg68_uds_S ),
.nLDS (tg68_lds_S ),

View File

@@ -44,6 +44,7 @@ entity TG68K_ALU is
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);
@@ -171,6 +172,10 @@ architecture logic of TG68K_ALU IS
signal bf_flag_z : std_logic;
signal bf_flag_n : std_logic;
-- barrel shifter
signal bs_data : std_logic_vector(31 downto 0);
signal bs_msb : std_logic_vector(4 downto 0);
signal set_V_Flag : BIT;
signal Flags : std_logic_vector(7 downto 0);
signal c_out : std_logic_vector(2 downto 0);
@@ -616,7 +621,7 @@ begin
-----------------------------------------------------------------------------
-- Rotation
-----------------------------------------------------------------------------
process (exe_opcode, OP1out, Flags, rot_bits, rot_msb, rot_lsb, rot_rot, exec)
process (exe_opcode, OP1out, Flags, rot_bits, rot_msb, rot_lsb, rot_cnt, rot_out, rot_rot, bs_data, bs_msb, exec)
begin
case exe_opcode(7 downto 6) IS
when "00" => --Byte
@@ -670,6 +675,51 @@ begin
end case;
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
bs_data <= OP1out;
bs_msb <= "11111";
-- word size
if exe_opcode(7 downto 6)="01" then
bs_msb <= "01111";
bs_data(31 downto 16) <= "0000000000000000";
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)));
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")));
end if;
-- not shifting at all or shifting more than the whole byte/word/long
if(rot_cnt = 0) then
rot_X <= Flags(4);
rot_C <= '0';
else
if(rot_cnt - 1 > bs_msb) then
rot_X <= '0';
rot_C <= '0';
end if;
end if;
end if;
end process;
------------------------------------------------------------------------------

View File

@@ -214,6 +214,7 @@ package TG68K_Pack is
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);

View File

@@ -189,6 +189,8 @@ architecture logic of TG68KdotC_Kernel is
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;
@@ -309,6 +311,7 @@ begin
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);
@@ -896,7 +899,7 @@ begin
-----------------------------------------------------------------------------
-- 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,
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;
@@ -1099,7 +1102,11 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
if decodeOPC = '1' or exec(ld_rot_cnt) = '1' or rot_cnt /= "000001" then
rot_cnt <= set_rot_cnt;
end if;
if setstate(1) = '1' and set_datatype = "00" then
if decodeOPC = '1' or exec(ld_rot_cnt) = '1' then
alu_rot_cnt <= set_alu_rot_cnt;
end if;
if setstate(1) = '1' and set_datatype = "00" then
byte <= '1';
end if;
@@ -1342,6 +1349,7 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
set_Suppress_Base <= '0';
set_PCbase <= '0';
-- decrement xyz
if rot_cnt /= "000001" then
set_rot_cnt <= rot_cnt - 1;
end if;
@@ -2583,22 +2591,37 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
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
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;
-- lsr or lsl use a barrel shifter and are done immediately
if opcode(4 downto 3) = "01" then
set_rot_cnt <= "000001";
end if;
end if;
end if;
end if;
@@ -3241,10 +3264,15 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro
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';
-- load rot_cnt from register
if opcode(4 downto 3) = "01" then -- lsl/lsr uses barrel shifter
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 =>