You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
microwatt/decode_types.vhdl

441 lines
11 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
package decode_types is
type insn_type_t is (OP_ILLEGAL, OP_NOP, OP_ADD,
OP_AND, OP_ATTN, OP_B, OP_BC, OP_BCREG,
OP_BCD, OP_BPERM, OP_CMP, OP_CMPB, OP_CMPEQB, OP_CMPRB,
OP_CNTZ, OP_CROP,
OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST,
OP_DCBZ, OP_ICBI, OP_ICBT,
OP_FP_CMP, OP_FP_ARITH, OP_FP_MOVE, OP_FP_MISC,
OP_DIV, OP_DIVE, OP_MOD,
OP_EXTS, OP_EXTSWSLI,
OP_ISEL, OP_ISYNC,
OP_LOAD, OP_STORE,
OP_MCRXRX, OP_MFCR, OP_MFMSR, OP_MFSPR,
OP_MTCRF, OP_MTMSRD, OP_MTSPR, OP_MUL_L64,
OP_MUL_H64, OP_MUL_H32, OP_OR,
OP_POPCNT, OP_PRTY, OP_RFID,
OP_RLC, OP_RLCL, OP_RLCR, OP_SC, OP_SETB,
OP_SHL, OP_SHR,
OP_SYNC, OP_TLBIE, OP_TRAP,
OP_XOR,
OP_ADDG6S,
OP_FETCH_FAILED
);
-- The following list is ordered in such a way that we can know some
-- things about which registers are accessed by an instruction by its place
-- in the list. In other words we can decide whether an instruction
-- accesses FPRs and whether it has an RB operand by doing simple
-- comparisons of the insn_code for the instruction with a few constants.
type insn_code is (
-- The following instructions don't have an RB operand or access FPRs
INSN_illegal, -- 0
INSN_fetch_fail,
INSN_addi,
INSN_addic,
INSN_addic_dot,
INSN_addis,
INSN_addme,
INSN_addpcis,
INSN_addze,
INSN_andi_dot,
INSN_andis_dot, -- 10
INSN_attn,
INSN_b,
INSN_bc,
INSN_bcctr,
INSN_bclr,
INSN_bctar,
INSN_cbcdtd,
INSN_cdtbcd,
INSN_cmpi,
INSN_cmpli, -- 20
INSN_cntlzw,
INSN_cntlzd,
INSN_cnttzw,
INSN_cnttzd,
INSN_crand,
INSN_crandc,
INSN_creqv,
INSN_crnand,
INSN_crnor,
INSN_cror, -- 30
INSN_crorc,
INSN_crxor,
INSN_darn,
INSN_eieio,
INSN_extsb,
INSN_extsh,
INSN_extsw,
INSN_extswsli,
INSN_isync,
INSN_lbz, -- 40
INSN_lbzu,
INSN_ld,
INSN_ldu,
INSN_lha,
INSN_lhau,
INSN_lhz,
INSN_lhzu,
INSN_lwa,
INSN_lwz,
INSN_lwzu, -- 50
INSN_mcrf,
INSN_mcrfs,
INSN_mcrxrx,
INSN_mfcr,
INSN_mfmsr,
INSN_mfspr,
INSN_mtcrf,
INSN_mtfsb,
INSN_mtfsfi,
INSN_mtmsr, -- 60
INSN_mtmsrd,
INSN_mtspr,
INSN_mulli,
INSN_neg,
INSN_nop,
INSN_ori,
INSN_oris,
INSN_popcntb,
INSN_popcntw,
INSN_popcntd, -- 70
INSN_prtyw,
INSN_prtyd,
INSN_rfid,
INSN_rldic,
INSN_rldicl,
INSN_rldicr,
INSN_rldimi,
INSN_rlwimi,
INSN_rlwinm,
INSN_sc, -- 80
INSN_setb,
INSN_slbia,
INSN_sradi,
INSN_srawi,
INSN_stb,
INSN_stbu,
INSN_std,
INSN_stdu,
INSN_sth,
INSN_sthu, -- 90
INSN_stw,
INSN_stwu,
INSN_subfic,
INSN_subfme,
INSN_subfze,
INSN_sync,
INSN_tdi,
INSN_tlbsync,
INSN_twi,
INSN_wait, -- 100
INSN_xori,
INSN_xoris,
-- pad to 112 to simplify comparison logic
INSN_103,
INSN_104, INSN_105, INSN_106, INSN_107,
INSN_108, INSN_109, INSN_110, INSN_111,
-- The following instructions have an RB operand but don't access FPRs
INSN_add,
INSN_addc,
INSN_adde,
INSN_addex,
INSN_addg6s,
INSN_and,
INSN_andc,
INSN_bperm,
INSN_cmp, -- 120
INSN_cmpb,
INSN_cmpeqb,
INSN_cmpl,
INSN_cmprb,
INSN_dcbf,
INSN_dcbst,
INSN_dcbt,
INSN_dcbtst,
INSN_dcbz,
INSN_divd, -- 130
INSN_divdu,
INSN_divde,
INSN_divdeu,
INSN_divw,
INSN_divwu,
INSN_divwe,
INSN_divweu,
INSN_eqv,
INSN_icbi,
INSN_icbt, -- 140
INSN_isel,
INSN_lbarx,
INSN_lbzcix,
INSN_lbzux,
INSN_lbzx,
INSN_ldarx,
INSN_ldbrx,
INSN_ldcix,
INSN_ldx,
INSN_ldux, -- 150
INSN_lharx,
INSN_lhax,
INSN_lhaux,
INSN_lhbrx,
INSN_lhzcix,
INSN_lhzx,
INSN_lhzux,
INSN_lwarx,
INSN_lwax,
INSN_lwaux, -- 160
INSN_lwbrx,
INSN_lwzcix,
INSN_lwzx,
INSN_lwzux,
INSN_modsd,
INSN_modsw,
INSN_moduw,
INSN_modud,
INSN_mulhw,
INSN_mulhwu, -- 170
INSN_mulhd,
INSN_mulhdu,
INSN_mullw,
INSN_mulld,
INSN_nand,
INSN_nor,
INSN_or,
INSN_orc,
INSN_rldcl,
INSN_rldcr, -- 180
INSN_rlwnm,
INSN_slw,
INSN_sld,
INSN_sraw,
INSN_srad,
INSN_srw,
INSN_srd,
INSN_stbcix,
INSN_stbcx,
INSN_stbx, -- 190
INSN_stbux,
INSN_stdbrx,
INSN_stdcix,
INSN_stdcx,
INSN_stdx,
INSN_stdux,
INSN_sthbrx,
INSN_sthcix,
INSN_sthcx,
INSN_sthx, -- 200
INSN_sthux,
INSN_stwbrx,
INSN_stwcix,
INSN_stwcx,
INSN_stwx,
INSN_stwux,
INSN_subf,
INSN_subfc,
INSN_subfe,
INSN_td, -- 210
INSN_tlbie,
INSN_tlbiel,
INSN_tw,
INSN_xor,
-- pad to 224 to simplify comparison logic
INSN_215,
INSN_216, INSN_217, INSN_218, INSN_219,
INSN_220, INSN_221, INSN_222, INSN_223,
-- The following instructions have a third input addressed by RC
INSN_maddld,
INSN_maddhd,
INSN_maddhdu,
-- pad to 256 to simplify comparison logic
INSN_227,
INSN_228, INSN_229, INSN_230, INSN_231,
INSN_232, INSN_233, INSN_234, INSN_235,
INSN_236, INSN_237, INSN_238, INSN_239,
INSN_240, INSN_241, INSN_242, INSN_243,
INSN_244, INSN_245, INSN_246, INSN_247,
INSN_248, INSN_249, INSN_250, INSN_251,
INSN_252, INSN_253, INSN_254, INSN_255,
-- The following instructions access floating-point registers
-- These ones have an FRS operand, but RA/RB are GPRs
INSN_stfd,
INSN_stfdu,
INSN_stfs,
INSN_stfsu,
INSN_stfdux, -- 260
INSN_stfdx,
INSN_stfiwx,
INSN_stfsux,
INSN_stfsx,
-- These ones don't actually have an FRS operand (rather an FRT destination)
-- but are here so that all FP instructions are >= INST_first_frs.
INSN_lfd,
INSN_lfdu,
INSN_lfs,
INSN_lfsu,
INSN_lfdx,
INSN_lfdux, -- 270
INSN_lfiwax,
INSN_lfiwzx,
INSN_lfsx,
INSN_lfsux,
INSN_275, -- padding
-- The following instructions access FRA and/or FRB operands
INSN_fabs,
INSN_fadd,
INSN_fadds,
INSN_fcfid,
INSN_fcfids, -- 280
INSN_fcfidu,
INSN_fcfidus,
INSN_fcmpo,
INSN_fcmpu,
INSN_fcpsgn,
INSN_fctid,
INSN_fctidz,
INSN_fctidu,
INSN_fctiduz,
INSN_fctiw, -- 290
INSN_fctiwz,
INSN_fctiwu,
INSN_fctiwuz,
INSN_fdiv,
INSN_fdivs,
INSN_fmr,
INSN_fmrgew,
INSN_fmrgow,
INSN_fnabs,
INSN_fneg, -- 300
INSN_fre,
INSN_fres,
INSN_frim,
INSN_frin,
INSN_frip,
INSN_friz,
INSN_frsp,
INSN_frsqrte,
INSN_frsqrtes,
INSN_fsqrt, -- 310
INSN_fsqrts,
INSN_fsub,
INSN_fsubs,
INSN_ftdiv,
INSN_ftsqrt,
INSN_mffs,
INSN_mtfsf,
-- pad to 320
INSN_318, INSN_319,
-- The following instructions access FRA, FRB (possibly) and FRC operands
INSN_fmul, -- 320
INSN_fmuls,
INSN_fmadd,
INSN_fmadds,
INSN_fmsub,
INSN_fmsubs,
INSN_fnmadd,
INSN_fnmadds,
INSN_fnmsub,
INSN_fnmsubs,
INSN_fsel -- 330
);
constant INSN_first_rb : insn_code := INSN_add;
constant INSN_first_rc : insn_code := INSN_maddld;
constant INSN_first_frs : insn_code := INSN_stfd;
constant INSN_first_frab : insn_code := INSN_fabs;
constant INSN_first_frabc : insn_code := INSN_fmul;
type input_reg_a_t is (NONE, RA, RA_OR_ZERO, CIA, FRA);
type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD,
CONST_DXHI4, CONST_DS, CONST_DQ, CONST_M1, CONST_SH, CONST_SH32, FRB);
type input_reg_c_t is (NONE, RS, RCR, FRC, FRS);
type output_reg_a_t is (NONE, RT, RA, FRT);
type rc_t is (NONE, ONE, RC, RCOE);
type carry_in_t is (ZERO, CA, OV, ONE);
constant SH_OFFSET : integer := 0;
constant MB_OFFSET : integer := 1;
constant ME_OFFSET : integer := 1;
constant SH32_OFFSET : integer := 0;
constant MB32_OFFSET : integer := 1;
constant ME32_OFFSET : integer := 2;
constant FXM_OFFSET : integer := 0;
constant BO_OFFSET : integer := 0;
constant BI_OFFSET : integer := 1;
constant BH_OFFSET : integer := 2;
constant BF_OFFSET : integer := 0;
constant L_OFFSET : integer := 1;
constant TOO_OFFSET : integer := 0;
type unit_t is (NONE, ALU, LDST, FPU);
type facility_t is (NONE, FPU);
type length_t is (NONE, is1B, is2B, is4B, is8B);
type repeat_t is (NONE, -- instruction is not repeated
DUPD); -- update-form load
type decode_rom_t is record
unit : unit_t;
facility : facility_t;
insn_type : insn_type_t;
input_reg_a : input_reg_a_t;
input_reg_b : input_reg_b_t;
input_reg_c : input_reg_c_t;
output_reg_a : output_reg_a_t;
input_cr : std_ulogic;
output_cr : std_ulogic;
invert_a : std_ulogic;
invert_out : std_ulogic;
input_carry : carry_in_t;
output_carry : std_ulogic;
-- load/store signals
length : length_t;
byte_reverse : std_ulogic;
sign_extend : std_ulogic;
update : std_ulogic;
reserve : std_ulogic;
-- multiplier and ALU signals
is_32bit : std_ulogic;
is_signed : std_ulogic;
rc : rc_t;
lr : std_ulogic;
sgl_pipe : std_ulogic;
repeat : repeat_t;
end record;
constant decode_rom_init : decode_rom_t := (unit => NONE, facility => NONE,
insn_type => OP_ILLEGAL, input_reg_a => NONE,
input_reg_b => NONE, input_reg_c => NONE,
output_reg_a => NONE, input_cr => '0', output_cr => '0',
invert_a => '0', invert_out => '0', input_carry => ZERO, output_carry => '0',
length => NONE, byte_reverse => '0', sign_extend => '0',
update => '0', reserve => '0', is_32bit => '0',
is_signed => '0', rc => NONE, lr => '0', sgl_pipe => '0', repeat => NONE);
end decode_types;
package body decode_types is
end decode_types;