OpenCores
URL https://opencores.org/ocsvn/core_arm/core_arm/trunk

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [arm/] [libs/] [armdecode.vhd] - Rev 4

Compare with Previous | Blame | View Log

library ieee;
use ieee.std_logic_1164.all;
use work.config.all;
use work.memdef.all;
use work.armpmodel.all;
use work.armshiefter.all;
 
-- PREFIX: ade_xxx
package armdecode is
 
-------------------------------------------------------------------------------
 
-- Addressing modes:
-- DAta PRocessing Addressing Modes      : DAPRAM
-- LoaD/STore Addressing Modes           : LDSTAM
-- Load/Store misc (V4) Addressing Modes : LSV4AM
 
-- DAta PRocessing Addressing Modes (DAPRAM):
--
-- o ade_DAPRAM_simm:
--   - DP op2: Register                     : <rm>
--   - DP op2: Register <SDIR> by Immediate : <rm>, <SDIR> #<imm>
--   - DP op2: Register RRX                 : <rm>, RRX
--   - <SDIR>: {LSL}|{LSR}|{ASR}|{ROR}
-- o ade_DAPRAM_sreg:
--   - DP op2: Register <SDIR> by Register  : <rm>, <SDIR> <rs>
--   - <SDIR>: {LSL}|{LSR}|{ASR}|{ROR}
-- o ade_DAPRAM_immrot:
--   - DP op2: Immediate #<imm>
 
type ade_DAPRAM is (
  ade_DAPRAM_simm,       -- OP2 shieft with imm 
  ade_DAPRAM_sreg,       -- OP2 shieft with reg 
  ade_DAPRAM_immrot      -- OP2 immidiate rotated
);
 
-- Load/Store  Addressing Modes (LDSTAM) and Load/Store misc (V4) Addressing Modes (LSV4AM) :
-- 
-- o adm_LDSTAMxLSV4AM_reg:
--   * <LSV4AM>
--     - L/S W/UB: Register Offset                     : [<rn>, +/-<rm>]
--     - L/S W/UB: Register Offset pre-indexed         : [<rn>, +/-<rm>]!
--     - L/S W/UB: Register Offset post-indexed        : [<rn>], +/-<rm>
--     - L/S W/UB: Scaled Register Offset              : [<rn>, +/-<rm>, <LSAMscale>]
--     - L/S W/UB: Scaled Register Offset pre-indexed  : [<rn>, +/-<rm>, <LSAMscale>]!
--     - L/S W/UB: Scaled Register Offset post-indexed : [<rn>], +/-<rm>, <LSAMscale>
--     - <LSAMscale>: {LSL #<imm>}|{LSR #<imm>}|{ASR #<imm>}|{ROR #<imm>}|{RRX}
--   * <LDSTAM>
--     - L/S MISC: Register offset            : [<rn>, #+/-<rm>]
--     - L/S MISC: Register offset pre-index  : [<rn>, #+/-<rm>] !
--     - L/S MISC: Register offset post-index : [<rn>], #+/-<rm>
-- o adm_LDSTAMxLSV4AM_imm:
--   * <LSV4AM>
--     - L/S W/UB: Immediate Offset              : [<rn>, #+/-<offset12>]
--     - L/S W/UB: Immediate Offset pre-indexed  : [<rn>, #+/-<offset12>]!
--     - L/S W/UB: Immediate Offset post-indexed : [<rn>], #+/-<offset12>
--   * <LDSTAM>
--     - L/S MISC: Immediate offset            : [<rn>, #+/-<off>]
--     - L/S MISC: Immediate offset pre-index  : [<rn>, #+/-<off>] !
--     - L/S MISC: Immediate offset post-index : [<rn>], #+/-<off>
 
type ade_LDSTAMxLSV4AM is (
  ade_LDSTAMxLSV4AM_imm,  -- addr v1 imm
                          -- addr v4 imm
  ade_LDSTAMxLSV4AM_reg   -- addr v1 reg (shieft with imm)
                          -- addr v4 reg
);
 
-- Prefix/Postfix
type ade_pos is (
  ade_pre,      -- pre indexed
  ade_post      -- post indexed
); 
 
-- Decoded addressing mode
type ade_amode is record
  DAPRAM_typ           : ade_DAPRAM;
  LDSTAM_typ           : ade_LDSTAMxLSV4AM;
  LSV4AM_typ           : ade_LDSTAMxLSV4AM;
  LDSTAMxLSV4AM_pos    : ade_pos;
  DAPRAMxLDSTAM_sdir   : ash_sdir;
  LDSTAMxLSV4AM_uacc   : std_logic;
  LDSTAMxLSV4AM_wb     : std_logic;
end record;
 
-- Decode addressing mode
procedure ade_decode_amode (
  insn : in std_logic_vector(31 downto 0);
  am   : out ade_amode
);
 
-------------------------------------------------------------------------------
 
-- Implemented instructions:
type ade_decinsn is (
  type_arm_invalid,type_arm_nop,    type_arm_mrs,    type_arm_bx,    type_arm_mul,   type_arm_mla,
  type_arm_swp,    type_arm_sumull, type_arm_sumlal, type_arm_strhb, type_arm_ldrhb, type_arm_and,
  type_arm_sub,    type_arm_eor,    type_arm_rsb,    type_arm_add,   type_arm_sbc,   type_arm_adc, 
  type_arm_msr,    type_arm_teq,    type_arm_cmn,    type_arm_tst,   type_arm_cmp,   type_arm_orr, 
  type_arm_mov,    type_arm_mvn,    type_arm_str1,   type_arm_str2,  type_arm_str3,  type_arm_ldr1,
  type_arm_stm,    type_arm_ldm,    type_arm_b,      type_arm_swi,   type_arm_cdp,   type_arm_mrc,
  type_arm_mcr,    type_arm_stc,    type_arm_ldc,    type_arm_rsc,   type_arm_bic,   type_arm_undefined
);
 
-- Instruction groups
type ade_insntyp is (
  ade_typmem,
  ade_typalu,
  ade_typmisc,
  ade_typcp
);
 
-- this decoder is automatically generated by "decgen"
function ade_decode_v4(
  insn_in : in std_logic_vector(31 downto 0)
) return ade_decinsn;
 
-------------------------------------------------------------------------------
-- Condition code
 
constant ADE_COND_U  : integer := 31;
constant ADE_COND_D  : integer := 28;
constant ADE_COND_EQ : std_logic_vector(3 downto 0) := "0000";
constant ADE_COND_NE : std_logic_vector(3 downto 0) := "0001";
constant ADE_COND_CS : std_logic_vector(3 downto 0) := "0010";
constant ADE_COND_CC : std_logic_vector(3 downto 0) := "0011";
constant ADE_COND_MI : std_logic_vector(3 downto 0) := "0100";
constant ADE_COND_PL : std_logic_vector(3 downto 0) := "0101";
constant ADE_COND_VS : std_logic_vector(3 downto 0) := "0110";
constant ADE_COND_VC : std_logic_vector(3 downto 0) := "0111";
constant ADE_COND_HI : std_logic_vector(3 downto 0) := "1000";
constant ADE_COND_LS : std_logic_vector(3 downto 0) := "1001";
constant ADE_COND_GE : std_logic_vector(3 downto 0) := "1010";
constant ADE_COND_LT : std_logic_vector(3 downto 0) := "1011";
constant ADE_COND_GT : std_logic_vector(3 downto 0) := "1100";
constant ADE_COND_LE : std_logic_vector(3 downto 0) := "1101";
constant ADE_COND_AL : std_logic_vector(3 downto 0) := "1110";
constant ADE_COND_NV : std_logic_vector(3 downto 0) := "1111";
 
-------------------------------------------------------------------------------
-- Alu codes
 
constant ADE_OP_U : integer := 24;
constant ADE_OP_D : integer := 21;
constant ADE_OP_AND : std_logic_vector(3 downto 0) := "0000";
constant ADE_OP_EOR : std_logic_vector(3 downto 0) := "0001";
constant ADE_OP_SUB : std_logic_vector(3 downto 0) := "0010";
constant ADE_OP_RSB : std_logic_vector(3 downto 0) := "0011";
constant ADE_OP_ADD : std_logic_vector(3 downto 0) := "0100";
constant ADE_OP_ADC : std_logic_vector(3 downto 0) := "0101";
constant ADE_OP_SBC : std_logic_vector(3 downto 0) := "0110";
constant ADE_OP_RSC : std_logic_vector(3 downto 0) := "0111";
constant ADE_OP_TST : std_logic_vector(3 downto 0) := "1000";
constant ADE_OP_TEQ : std_logic_vector(3 downto 0) := "1001";
constant ADE_OP_CMP : std_logic_vector(3 downto 0) := "1010";
constant ADE_OP_CMN : std_logic_vector(3 downto 0) := "1011";
constant ADE_OP_ORR : std_logic_vector(3 downto 0) := "1100";
constant ADE_OP_MOV : std_logic_vector(3 downto 0) := "1101";
constant ADE_OP_BIC : std_logic_vector(3 downto 0) := "1110";
constant ADE_OP_MVN : std_logic_vector(3 downto 0) := "1111";
 
constant ADE_SETCPSR_C : integer := 20;  -- set cpsr
 
-------------------------------------------------------------------------------
-- swp, msr, mrs codes
 
constant ADE_MSR_R : integer := 22;  -- '1' = spsr: '0' = cpsr
constant ADE_MRS_R : integer := 22;  -- '1' = spsr: '0' = cpsr
constant ADE_MSR_IMM : integer := 16;   -- '1' = imm; '0' = reg
 
constant ADE_WB_C : integer := 21;      -- same as ADE_LDSTAMxLSV4AM_WB
constant ADE_SWPB_C : integer := 22;    -- 1=SWPB,0=SWP
 
constant ADE_BROFF_U : integer := 23;     -- branch offset
constant ADE_BROFF_D : integer := 0;
constant ADE_BRLINK_C : integer := 22;
 
-------------------------------------------------------------------------------
-- ld, st codes
 
constant ADE_LDSTAM_OFF_U : integer := 11;  -- <offset12> of armcmd_l1.vhd LDSSTAM
constant ADE_LDSTAM_OFF_D : integer := 0;
 
constant ADE_LSV4AM_OFF8_HU : integer := 11;  -- <offset8> of armcmd_l4.vhd LSV4AM
constant ADE_LSV4AM_OFF8_HD : integer := 8;
constant ADE_LSV4AM_OFF8_LU : integer := 3;
constant ADE_LSV4AM_OFF8_LD : integer := 0;
 
constant ADE_LDSTAM_UBYTE  : integer := 22;  -- '1': unsigned byte, '0': word
constant ADE_LSV4AM_SIGNED  : integer := 6;  -- '1': unsigned byte, '0': word
constant ADE_LSV4AM_HALF    : integer := 5;  -- '1': unsigned byte, '0': word
constant ADE_LDSTAMxLSV4AM_ADD    : integer := 23;  -- '1': add, '0': sub
 
constant ADE_PAB_U : integer := 24;     -- '0': after / '1': before
constant ADE_UID_U : integer := 23;     -- '1':increment / '0':decrement
 
constant ADE_REGLIST_U  : integer := 15;
constant ADE_REGLIST_D  : integer := 0;
 
-------------------------------------------------------------------------------
-- coprocessor
 
constant ADE_MRC_MCR_C : integer := 20;  -- '1':MRC '0':MCR
constant ADE_LDC_STC_WB_C : integer := 21;  -- '1': writeback '0': nowriteback (ADE_LDSTAMxLSV4AM_WB)
constant ADE_LDC_STC_P_C : integer := 24;  -- '1': Post; '0': Pre (negate ADE_LDSTAMxLSV4AM_POS)
 
-------------------------------------------------------------------------------
-- registers
 
constant ADE_RN_U : integer := 19;
constant ADE_RN_D : integer := 16;
constant ADE_RD_U : integer := 15;
constant ADE_RD_D : integer := 12;
constant ADE_RM_U : integer := 3;
constant ADE_RM_D : integer := 0;
constant ADE_SREG_U : integer := 11;  -- shieft register
constant ADE_SREG_D : integer := 8;
 
-------------------------------------------------------------------------------
 
-- festg out insn
type ade_feinsn is record
  insn    : std_logic_vector(31 downto 0);
  pc      : std_logic_vector(31 downto 0);
  pc_vir  : std_logic_vector(31 downto 0);
  valid   : std_logic;
  trap    : std_logic;
end record;
 
-- Decoded insn
type ade_insn is record
  pc_8    : std_logic_vector(31 downto 0);
  insn    : std_logic_vector(31 downto 0);
  insntyp : ade_insntyp;
  decinsn : ade_decinsn;
  am      : ade_amode;
  valid   : std_logic;
  id      : std_logic_vector(2 downto 0);
end record;
 
-- destg out insn
type ade_deinsn is record
  insn   : ade_insn;
  trap   : std_logic;
end record;
 
-------------------------------------------------------------------------------
 
end armdecode;
 
package body armdecode is
 
-- Addressing mode decode constants
-- DAPRAM: am.DAPRAM_typ 
constant ADE_DAPRAM_TYP   : integer := 25; -- '1': imm rot, '0': sreg/simm (shiefted)
constant ADE_DAPRAM_TYP_P : integer := 4;  -- shiefted: ('0': imm , '1': reg)
-- LDSTAM: am.LDSTAM_typ
constant ADE_LDSTAM_TYP   : integer := 25; -- '0': adm_LDSTAM_imm, '1': adm_LDSTAM_reg (shiefted)
-- LSV4AM: am.LSV4AM_typ
constant ADE_LSV4AM_TYP   : integer := 22; -- '1': adm_LSV4AM_imm , '0': adm_LSV4AM_reg
-- DAPRAM, LDSTAM: am.DAPRAMxLDSTAM_sdir
constant ADE_DAPRAMxLDSTAM_SDIR_U     : integer := 6;  -- shieft type 
constant ADE_DAPRAMxLDSTAM_SDIR_D     : integer := 5;
constant ADE_DAPRAMxLDSTAM_SDIRNONE_U : integer := 11; -- no shieft
constant ADE_DAPRAMxLDSTAM_SDIRNONE_D : integer := 4;
constant ADE_DAPRAMxLDSTAM_SDIRROR_U  : integer := 11; -- ror 
constant ADE_DAPRAMxLDSTAM_SDIRROR_D  : integer := 7;   
-- LDSTAM, LSV4AM: am.LDSTAMxLSV4AM_pos
-- LDSTAM, LSV4AM: am.LDSTAMxLSV4AM_wb
-- LDSTAM, LSV4AM: am.LDSTAMxLSV4AM_uacc
constant ADE_LDSTAMxLSV4AM_POS : integer := 24; -- '0': postindexed, '1': preindexed
constant ADE_LDSTAMxLSV4AM_WB  : integer := 21; -- postindexed: 0 = normal, 1 = usermode
 
procedure ade_decode_amode (
  insn : in std_logic_vector(31 downto 0);
  am   : out ade_amode
) is
  variable tmp : std_logic_vector(4 downto 0);
begin
 
  -- DAPRAM: typ
  am.DAPRAM_typ := ade_DAPRAM_simm;
  if insn(ADE_DAPRAM_TYP_P) = '1' then
    am.DAPRAM_typ := ade_DAPRAM_sreg;
  end if;
 
  -- DPAM and LSAM: shieft direction
  am.DAPRAMxLDSTAM_sdir := ash_sdir_srrx;
  case insn(ADE_DAPRAMxLDSTAM_SDIR_U downto ADE_DAPRAMxLDSTAM_SDIR_D) is
    when "00" =>
      am.DAPRAMxLDSTAM_sdir := ash_sdir_slsl;
      if insn(ADE_DAPRAMxLDSTAM_SDIRNONE_U downto ADE_DAPRAMxLDSTAM_SDIRNONE_D) = "00000000" then
        am.DAPRAMxLDSTAM_sdir := ash_sdir_snone;
      end if;
    when "01" => am.DAPRAMxLDSTAM_sdir := ash_sdir_slsr;
    when "10" => am.DAPRAMxLDSTAM_sdir := ash_sdir_sasr;
    when "11" =>
      if not (insn(ADE_DAPRAMxLDSTAM_SDIRROR_U downto ADE_DAPRAMxLDSTAM_SDIRROR_D) = "00000") then
        am.DAPRAMxLDSTAM_sdir := ash_sdir_sror;
      end if;
    when others => null;
  end case;
 
  -- DAPRAM: typ
  if insn(ADE_DAPRAM_TYP) = '1' then
    am.DAPRAM_typ := ade_DAPRAM_immrot;
  end if;
 
  -- LDSTAM: typ
  am.LDSTAM_typ := ade_LDSTAMxLSV4AM_imm;
  if insn(ADE_LDSTAM_TYP) = '1' then
    am.LDSTAM_typ := ade_LDSTAMxLSV4AM_reg;
    -- am.DAPRAMxLDSTAM_sdir := ade_snone;
  end if;
 
  -- LDSTAM and LSV4AM: preindexed / postindexed
  am.LDSTAMxLSV4AM_uacc := '0';
  am.LDSTAMxLSV4AM_wb := '1';
  if insn(ADE_LDSTAMxLSV4AM_POS) = '1' then
    am.LDSTAMxLSV4AM_pos := ade_pre; 
    if insn(ADE_LDSTAMxLSV4AM_WB) = '0' then
      am.LDSTAMxLSV4AM_wb := '0';
    end if;
  else
    am.LDSTAMxLSV4AM_pos := ade_post;
    if insn(ADE_LDSTAMxLSV4AM_WB) = '1' then
      am.LDSTAMxLSV4AM_uacc := '1';
    end if;
  end if;
 
  -- LSV4AM: offset, register (not shiefted)
  am.LSV4AM_typ := ade_LDSTAMxLSV4AM_imm;
  if insn(ADE_LSV4AM_TYP) = '0' then
    am.LSV4AM_typ := ade_LDSTAMxLSV4AM_reg;
  end if;
 
end;
 
 
-- todo: remember fixing recursion bug in decgen
function ade_decode_v4(
  insn_in : in std_logic_vector(31 downto 0)
) return ade_decinsn is
  variable arm_nop	 : std_logic;
  variable arm_mrs	 : std_logic;
  variable arm_bx	 : std_logic;
  variable arm_mul	 : std_logic;
  variable arm_mla	 : std_logic;
  variable arm_swp	 : std_logic;
  variable arm_sumull	 : std_logic;
  variable arm_sumlal	 : std_logic;
  variable arm_strhb	 : std_logic;
  variable arm_ldrhb	 : std_logic;
  variable arm_and	 : std_logic;
  variable arm_sub	 : std_logic;
  variable arm_eor	 : std_logic;
  variable arm_rsb	 : std_logic;
  variable arm_add	 : std_logic;
  variable arm_sbc	 : std_logic;
  variable arm_adc	 : std_logic;
  variable arm_rsc	 : std_logic;
  variable arm_msr	 : std_logic;
  variable arm_teq	 : std_logic;
  variable arm_cmn	 : std_logic;
  variable arm_tst	 : std_logic;
  variable arm_cmp	 : std_logic;
  variable arm_orr	 : std_logic;
  variable arm_bic	 : std_logic;
  variable arm_mov	 : std_logic;
  variable arm_mvn	 : std_logic;
  variable arm_str1	 : std_logic;
  variable arm_str2	 : std_logic;
  variable arm_str3	 : std_logic;
  variable arm_ldr1	 : std_logic;
  variable arm_undefined	 : std_logic;
  variable arm_stm	 : std_logic;
  variable arm_ldm	 : std_logic;
  variable arm_b	 : std_logic;
  variable arm_swi	 : std_logic;
  variable arm_cdp	 : std_logic;
  variable arm_mrc	 : std_logic;
  variable arm_mcr	 : std_logic;
  variable arm_stc	 : std_logic;
  variable arm_ldc	 : std_logic;
  variable vec_1	: std_logic_vector(1 downto 0);
  variable vec_2	: std_logic_vector(2 downto 0);
  variable vec_3	: std_logic_vector(4 downto 0);
  variable vec_4	: std_logic_vector(21 downto 0);
  variable vec_5	: std_logic_vector(12 downto 0);
  variable vec_6	: std_logic_vector(18 downto 0);
  variable vec_7	: std_logic_vector(4 downto 0);
  variable vec_8	: std_logic_vector(0 downto 0);
  variable vec_9	: std_logic_vector(0 downto 0);
  variable vec_10	: std_logic_vector(4 downto 0);
  variable vec_11	: std_logic_vector(0 downto 0);
  variable vec_12	: std_logic_vector(2 downto 0);
  variable vec_13	: std_logic_vector(0 downto 0);
  variable vec_14	: std_logic_vector(0 downto 0);
  variable vec_15	: std_logic_vector(0 downto 0);
  variable vec_16	: std_logic_vector(0 downto 0);
  variable vec_17	: std_logic_vector(6 downto 0);
  variable vec_18	: std_logic_vector(0 downto 0);
  variable vec_19	: std_logic_vector(0 downto 0);
  variable vec_20	: std_logic_vector(0 downto 0);
  variable vec_21	: std_logic_vector(0 downto 0);
  variable vec_22	: std_logic_vector(0 downto 0);
  variable vec_23	: std_logic_vector(0 downto 0);
  variable vec_24	: std_logic_vector(7 downto 0);
  variable vec_25	: std_logic_vector(0 downto 0);
  variable vec_26	: std_logic_vector(1 downto 0);
  variable vec_27	: std_logic_vector(0 downto 0);
  variable vec_28	: std_logic_vector(0 downto 0);
  variable vec_29	: std_logic_vector(0 downto 0);
  variable vec_30	: std_logic_vector(0 downto 0);
  variable vec_31	: std_logic_vector(0 downto 0);
  variable vec_32	: std_logic_vector(0 downto 0);
  variable vec_33	: std_logic_vector(0 downto 0);
  variable insn_return : ade_decinsn;
  variable insn : std_logic_vector(31 downto 0);
begin
  insn := insn_in;
  -- decoder assumes littleendian: word[3 2 1 0]
  insn := insn_in;
  if CFG_BO_PROC = lmd_big then
    insn := insn(7 downto 0) & insn(15 downto 8) & insn(23 downto 16) & insn(31 downto 24);
  end if;
  insn_return := type_arm_invalid;
  vec_1	 := insn(3 downto 2);
  vec_2	 := insn(31 downto 31)&insn(28 downto 28)&insn(1 downto 1);
  vec_3	 := insn(30 downto 29)&insn(15 downto 15)&insn(13 downto 13)&insn(0 downto 0);
  vec_4	 := insn(27 downto 16)&insn(14 downto 14)&insn(12 downto 4);
  arm_nop	 := '0';
  vec_5	 := insn(27 downto 24)&insn(19 downto 16)&insn(12 downto 8);
  arm_mrs	 := '0';
  vec_6	 := insn(30 downto 29)&insn(23 downto 8)&insn(0 downto 0);
  arm_bx	 := '0';
  vec_7	 := insn(30 downto 29)&insn(15 downto 15)&insn(13 downto 13)&insn(0 downto 0);
  vec_8	 := insn(14 downto 14);
  arm_mul	 := '0';
  vec_9	 := insn(14 downto 14);
  arm_mla	 := '0';
  vec_10	 := insn(19 downto 16)&insn(12 downto 12);
  arm_swp	 := '0';
  arm_sumull	 := '0';
  arm_sumlal	 := '0';
  vec_11	 := insn(12 downto 12);
  arm_strhb	 := '0';
  arm_ldrhb	 := '0';
  vec_12	 := insn(15 downto 15)&insn(13 downto 13)&insn(0 downto 0);
  vec_13	 := insn(14 downto 14);
  arm_and	 := '0';
  arm_sub	 := '0';
  vec_14	 := insn(14 downto 14);
  arm_eor	 := '0';
  arm_rsb	 := '0';
  vec_15	 := insn(14 downto 14);
  arm_add	 := '0';
  arm_sbc	 := '0';
  vec_16	 := insn(14 downto 14);
  arm_adc	 := '0';
  arm_rsc	 := '0';
  vec_17	 := insn(23 downto 20)&insn(12 downto 12)&insn(10 downto 9);
  arm_msr	 := '0';
  vec_18	 := insn(14 downto 14);
  arm_teq	 := '0';
  arm_cmn	 := '0';
  vec_19	 := insn(14 downto 14);
  arm_tst	 := '0';
  arm_cmp	 := '0';
  vec_20	 := insn(14 downto 14);
  arm_orr	 := '0';
  arm_bic	 := '0';
  vec_21	 := insn(14 downto 14);
  arm_mov	 := '0';
  arm_mvn	 := '0';
  vec_22	 := insn(12 downto 12);
  vec_23	 := insn(1 downto 1);
  arm_str1	 := '0';
  vec_24	 := insn(31 downto 28)&insn(19 downto 16);
  arm_str2	 := '0';
  vec_25	 := insn(28 downto 28);
  arm_str3	 := '0';
  arm_ldr1	 := '0';
  vec_26	 := insn(28 downto 28)&insn(1 downto 1);
  arm_undefined	 := '0';
  vec_27	 := insn(1 downto 1);
  vec_28	 := insn(12 downto 12);
  arm_stm	 := '0';
  arm_ldm	 := '0';
  arm_b	 := '0';
  vec_29	 := insn(1 downto 1);
  vec_30	 := insn(0 downto 0);
  arm_swi	 := '0';
  vec_31	 := insn(28 downto 28);
  arm_cdp	 := '0';
  vec_32	 := insn(12 downto 12);
  arm_mrc	 := '0';
  arm_mcr	 := '0';
  vec_33	 := insn(12 downto 12);
  arm_stc	 := '0';
  arm_ldc	 := '0';
case vec_1 is
  when "00" =>
    case vec_2 is
      when "000" =>
        case vec_3 is
          when "00111" =>
            case vec_4 is
              when "0000000000000000001110" =>
                arm_nop := '1';
                if arm_nop = '1' then
                insn_return := type_arm_nop;
                end if;
              when others => null;
            end case;
          when "00001" =>
            case vec_5 is
              when "0000000001111" =>
                arm_mrs := '1';
                if arm_mrs = '1' then
                insn_return := type_arm_mrs;
                end if;
              when others => null;
            end case;
          when others => null;
        end case;
      when "010" =>
        case vec_6 is
          when "0011111111001011111" =>
            arm_bx := '1';
            if arm_bx = '1' then
            insn_return := type_arm_bx;
            end if;
          when others => null;
        end case;
      when "110" =>
        case vec_7 is
          when "00000" =>
            case vec_8 is
              when "0" =>
                arm_mul := '1';
                if arm_mul = '1' then
                insn_return := type_arm_mul;
                end if;
              when others => null;
            end case;
          when "00010" =>
            case vec_9 is
              when "0" =>
                arm_mla := '1';
                if arm_mla = '1' then
                insn_return := type_arm_mla;
                end if;
              when others => null;
            end case;
          when "00001" =>
            case vec_10 is
              when "00000" =>
                arm_swp := '1';
                if arm_swp = '1' then
                insn_return := type_arm_swp;
                end if;
              when others => null;
            end case;
          when "00100" =>
            arm_sumull := '1';
            if arm_sumull = '1' then
            insn_return := type_arm_sumull;
            end if;
          when "00110" =>
            arm_sumlal := '1';
            if arm_sumlal = '1' then
            insn_return := type_arm_sumlal;
            end if;
          when others => null;
        end case;
        case vec_11 is
          when "0" =>
            arm_strhb := '1' and not (arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal);
            if arm_strhb = '1' then
            insn_return := type_arm_strhb;
            end if;
          when "1" =>
            arm_ldrhb := '1' and not (arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal);
            if arm_ldrhb = '1' then
            insn_return := type_arm_ldrhb;
            end if;
          when others => null;
        end case;
      when others => null;
    end case;
    case vec_12 is
      when "000" =>
        case vec_13 is
          when "0" =>
            arm_and := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_and = '1' then
            insn_return := type_arm_and;
            end if;
          when "1" =>
            arm_sub := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_sub = '1' then
            insn_return := type_arm_sub;
            end if;
          when others => null;
        end case;
      when "010" =>
        case vec_14 is
          when "0" =>
            arm_eor := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_eor = '1' then
            insn_return := type_arm_eor;
            end if;
          when "1" =>
            arm_rsb := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_rsb = '1' then
            insn_return := type_arm_rsb;
            end if;
          when others => null;
        end case;
      when "100" =>
        case vec_15 is
          when "0" =>
            arm_add := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_add = '1' then
            insn_return := type_arm_add;
            end if;
          when "1" =>
            arm_sbc := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_sbc = '1' then
            insn_return := type_arm_sbc;
            end if;
          when others => null;
        end case;
      when "110" =>
        case vec_16 is
          when "0" =>
            arm_adc := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_adc = '1' then
            insn_return := type_arm_adc;
            end if;
          when "1" =>
            arm_rsc := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_rsc = '1' then
            insn_return := type_arm_rsc;
            end if;
          when others => null;
        end case;
      when "011" =>
        case vec_17 is
          when "1111000" =>
            arm_msr := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_msr = '1' then
            insn_return := type_arm_msr;
            end if;
          when others => null;
        end case;
        case vec_18 is
          when "0" =>
            arm_teq := '1' and not (arm_msr or arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_teq = '1' then
            insn_return := type_arm_teq;
            end if;
          when "1" =>
            arm_cmn := '1' and not (arm_msr or arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_cmn = '1' then
            insn_return := type_arm_cmn;
            end if;
          when others => null;
        end case;
      when "001" =>
        case vec_19 is
          when "0" =>
            arm_tst := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_tst = '1' then
            insn_return := type_arm_tst;
            end if;
          when "1" =>
            arm_cmp := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_cmp = '1' then
            insn_return := type_arm_cmp;
            end if;
          when others => null;
        end case;
      when "101" =>
        case vec_20 is
          when "0" =>
            arm_orr := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_orr = '1' then
            insn_return := type_arm_orr;
            end if;
          when "1" =>
            arm_bic := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_bic = '1' then
            insn_return := type_arm_bic;
            end if;
          when others => null;
        end case;
      when "111" =>
        case vec_21 is
          when "0" =>
            arm_mov := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_mov = '1' then
            insn_return := type_arm_mov;
            end if;
          when "1" =>
            arm_mvn := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb);
            if arm_mvn = '1' then
            insn_return := type_arm_mvn;
            end if;
          when others => null;
        end case;
      when others => null;
    end case;
  when "01" =>
    case vec_22 is
      when "0" =>
        case vec_23 is
          when "0" =>
            arm_str1 := '1';
            if arm_str1 = '1' then
            insn_return := type_arm_str1;
            end if;
          when "1" =>
            case vec_24 is
              when "00000000" =>
                arm_str2 := '1';
                if arm_str2 = '1' then
                insn_return := type_arm_str2;
                end if;
              when others => null;
            end case;
          when others => null;
        end case;
        case vec_25 is
          when "0" =>
            arm_str3 := '1' and not (arm_str1 or arm_str2);
            if arm_str3 = '1' then
            insn_return := type_arm_str3;
            end if;
          when others => null;
        end case;
      when "1" =>
        arm_ldr1 := '1';
        if arm_ldr1 = '1' then
        insn_return := type_arm_ldr1;
        end if;
      when others => null;
    end case;
    case vec_26 is
      when "11" =>
        arm_undefined := '1' and not (arm_str1 or arm_str2 or arm_str3 or arm_ldr1);
        if arm_undefined = '1' then
        insn_return := type_arm_undefined;
        end if;
      when others => null;
    end case;
  when "10" =>
    case vec_27 is
      when "0" =>
        case vec_28 is
          when "0" =>
            arm_stm := '1';
            if arm_stm = '1' then
            insn_return := type_arm_stm;
            end if;
          when "1" =>
            arm_ldm := '1';
            if arm_ldm = '1' then
            insn_return := type_arm_ldm;
            end if;
          when others => null;
        end case;
      when "1" =>
        arm_b := '1';
        if arm_b = '1' then
        insn_return := type_arm_b;
        end if;
      when others => null;
    end case;
  when "11" =>
    case vec_29 is
      when "1" =>
        case vec_30 is
          when "1" =>
            arm_swi := '1';
            if arm_swi = '1' then
            insn_return := type_arm_swi;
            end if;
          when "0" =>
            case vec_31 is
              when "0" =>
                arm_cdp := '1';
                if arm_cdp = '1' then
                insn_return := type_arm_cdp;
                end if;
              when "1" =>
                case vec_32 is
                  when "1" =>
                    arm_mrc := '1';
                    if arm_mrc = '1' then
                    insn_return := type_arm_mrc;
                    end if;
                  when "0" =>
                    arm_mcr := '1';
                    if arm_mcr = '1' then
                    insn_return := type_arm_mcr;
                    end if;
                  when others => null;
                end case;
              when others => null;
            end case;
          when others => null;
        end case;
      when "0" =>
        case vec_33 is
          when "0" =>
            arm_stc := '1';
            if arm_stc = '1' then
            insn_return := type_arm_stc;
            end if;
          when "1" =>
            arm_ldc := '1';
            if arm_ldc = '1' then
            insn_return := type_arm_ldc;
            end if;
          when others => null;
        end case;
      when others => null;
    end case;
  when others => null;
end case;
return insn_return;
end;
 
end armdecode;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.