📄 armshiefter.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
-- PREFIX: ash_xxx
package armshiefter is
-- Addressing modes:
-- DAta PRocessing Addressing Modes : DAPRAM
-- LoaD/STore Addressing Modes : LDSTAM
-- Load/Store misc (V4) Addressing Modes : LSV4AM
-- Share shiefter for DAPRAM and LDSTAM addressing modes
-- operands:
-- data1 data2 value shieftval
-- ade_styp_immrot(DAPRAM): - - imm imm
-- ade_styp_simm(DAPRAM+LDSTAM): - use data2 imm
-- ade_styp_sreg(DAPRAM): use use data1 data2
-- ade_styp_none: - use data2 0
type ash_styp is (
ash_styp_none, -- no shieft
ash_styp_immrot,-- DAPRAM: OP2 immidiate rotated
ash_styp_simm, -- DAPRAM: OP2 shieft with imm, LDSTAM: addr v1 reg (adm_LDSTAM_reg)
ash_styp_sreg -- DAPRAM: OP2 shieft with reg
);
type ash_sdir is (
ash_sdir_snone, -- no shieft
ash_sdir_slsl, -- LSL #: logical shieft left
ash_sdir_slsr, -- LSR #: logical shieft righ
ash_sdir_sasr, -- ASR #: arithmetic shieft left
ash_sdir_sror, -- ROR #: rotate
ash_sdir_srrx -- RRX #: rotate 1 with carry
);
-- Shiefter of rsstg
procedure aas_shieft(
insn : in std_logic_vector(31 downto 0);
dir : in ash_sdir;
typ : in ash_styp;
data1 : in std_logic_vector(31 downto 0);
data2 : in std_logic_vector(31 downto 0);
carry : in std_logic;
shieftout : out std_logic_vector(31 downto 0);
shieftcarryout : out std_logic
);
end armshiefter;
package body armshiefter is
constant ASH_DAPRAMxLDSTAM_IMMROT_U : integer := 11; -- imm rot amount
constant ASH_DAPRAMxLDSTAM_IMMROT_D : integer := 8;
constant ASH_DAPRAMxLDSTAM_IMM_U : integer := 7; -- imm const
constant ASH_DAPRAMxLDSTAM_IMM_D : integer := 0;
constant ASH_DAPRAMxLDSTAM_SIMM_U : integer := 11; -- shieft immidiate amount
constant ASH_DAPRAMxLDSTAM_SIMM_D : integer := 7;
type shift_src is (shiftin_00,shiftin_32,shiftin_33,shiftin_prev);
procedure aas_shieft(
insn : in std_logic_vector(31 downto 0);
dir : in ash_sdir;
typ : in ash_styp;
data1 : in std_logic_vector(31 downto 0);
data2 : in std_logic_vector(31 downto 0);
carry : in std_logic;
shieftout : out std_logic_vector(31 downto 0);
shieftcarryout : out std_logic
) is
variable op1 : std_logic_vector(31 downto 0);
variable op2 : std_logic_vector(4 downto 0);
variable shiftin : std_logic_vector(64 downto 0);
variable carryout : std_logic;
variable carryoutsrc : shift_src;
begin
carryoutsrc := shiftin_prev;
carryout := carry;
op1 := data1;
op2 := (others => '0');
shiftin := (others => '0');
shiftin(32 downto 1) := data1;
-- data1 data2 value shieftval
-- adm_DAPRAMxLDSTAM_DAPRAM_immrot: - - imm imm
-- adm_DAPRAMxLDSTAM_DAPRAMxLDSTAM_simm: - use data2 imm
-- adm_DAPRAMxLDSTAM_DAPRAM_sreg: use use data1 data2
-- adm_DAPRAMxLDSTAM_DAPRAM_none: - use data2 0
case typ is
when ash_styp_immrot => -- (special msr case also)
-- 64 63 33 32 31 1 0
-- +---+---+---------------+===+=============+---+
-- | op1 | op1 | 0 |
-- +---+---+---------------+ccc+=============+---+
-- | op1 | << 1 (>>1)
-- | op1 | << 31 (>>31)
op1 := (others => '0');
op1(7 downto 0) := insn(ASH_DAPRAMxLDSTAM_IMM_U downto ASH_DAPRAMxLDSTAM_IMM_D);
shiftin := (others => '0');
shiftin(32 downto 1) := op1;
shiftin(64 downto 33) := op1;
op2 := insn(ASH_DAPRAMxLDSTAM_IMMROT_U downto ASH_DAPRAMxLDSTAM_IMMROT_D) & "0";
carryoutsrc := shiftin_32;
if op2 = "00000" then -- == 0
carryoutsrc := shiftin_prev;
carryout := carry;
end if;
when ash_styp_simm =>
shiftin := (others => '0');
shiftin(32 downto 1) := data2;
case dir is
when ash_sdir_slsl =>
--$(del)
--if shift_imm == 0 then /* Register Operand */
-- shifter_operand = Rm
-- shifter_carry_out = C Flag
--else /* shift_imm > 0 */
-- shifter_operand = Rm Logical_Shift_Left shift_imm
-- shifter_carry_out = Rm[32 - shift_imm]
--$(/del)
-- 64 63 33 32 31 1 0
-- +---+---+---------------+===+=============+---+
-- | c | op1 | 000 | 0 |
-- +---+---+------------ccc+===+=============+---+
-- c | op1 | << 31 (>>0)
-- c | op1 | << 0 (>>31)
shiftin := (others => '0');
shiftin(64) := carry;
shiftin(63 downto 32) := data2;
op2 := not insn(ASH_DAPRAMxLDSTAM_SIMM_U downto ASH_DAPRAMxLDSTAM_SIMM_D);
carryoutsrc := shiftin_33;
when ash_sdir_slsr =>
--$(del)
--if shift_imm == 0 then
-- shifter_operand = 0
-- shifter_carry_out = Rm[31]
--else /* shift_imm > 0 */
-- shifter_operand = Rm Logical_Shift_Right shift_imm
-- shifter_carry_out = Rm[shift_imm - 1]
--$(/del)
-- 64 63 33 32 31 1 0
-- +---+---+---------------+===+=============+---+
-- | 0 | 0 | 000 | op1 | c |
-- +---+---+---------------+===+=============+ccc+
-- | op1 | >> 0
-- |op1| >> 31
shiftin := (others => '0');
shiftin(0) := carry;
shiftin(32 downto 1) := data2;
op2 := insn(ASH_DAPRAMxLDSTAM_SIMM_U downto ASH_DAPRAMxLDSTAM_SIMM_D);
carryoutsrc := shiftin_00;
when ash_sdir_sasr =>
--$(del)
--if shift_imm == 0 then
-- if Rm[31] == 0 then
-- shifter_operand = 0
-- shifter_carry_out = Rm[31]
-- else /* Rm[31] == 1 */
-- shifter_operand = 0xFFFFFFFF
-- shifter_carry_out = Rm[31]
--else /* shift_imm > 0 */
-- shifter_operand = Rm Arithmetic_Shift_Right <shift_imm>
-- shifter_carry_out = Rm[shift_imm - 1]
--$(/del)
-- 64 63 33 32 31 1 0
-- +---+---+---------------+===+=============+---+
-- | s | s | sss | op1 | c |
-- +---+---+---------------+===+=============+ccc+
-- s | op1 | >> 1
-- sss |op1| >> 31
-- 000 | 0 >> 0 (s=0)
-- 111 | 1 >> 0 (s=1)
if data2(31) = '1' then
shiftin(64 downto 33) := (others => '1');
else
shiftin(64 downto 33) := (others => '0');
end if;
shiftin(0) := carry;
shiftin(32 downto 1) := data2;
op2 := insn(ASH_DAPRAMxLDSTAM_SIMM_U downto ASH_DAPRAMxLDSTAM_SIMM_D);
if op2 = "00000" then
if data2(31) = '1' then
shiftin(32 downto 0) := (others => '1');
else
shiftin(32 downto 0) := (others => '0');
end if;
end if;
carryoutsrc := shiftin_00;
when ash_sdir_sror =>
--$(del)
--if shift_imm == 0 then
-- ash_sdir_srrx case
--else /* shift_imm > 0 */
-- shifter_operand = Rm Rotate_Right shift_imm
-- shifter_carry_out = Rm[shift_imm - 1]
--$(/del)
-- 64 63 33 32 31 1 0
-- +---+---+---------------+===+=============+---+
-- | op1 | op1 | 0 |
-- +---+---+---------------+ccc+=============+---+
-- | op1 | << 1 (>>1)
-- | op1 | << 31 (>>31)
shiftin := (others => '0');
shiftin(64 downto 33) := data2;
shiftin(32 downto 1) := data2;
op2 := insn(ASH_DAPRAMxLDSTAM_SIMM_U downto ASH_DAPRAMxLDSTAM_SIMM_D);
carryoutsrc := shiftin_32;
when ash_sdir_srrx =>
--$(del)
--shifter_operand = (C Flag Logical_Shift_Left 31) OR (Rm Logical_Shift_Right 1)
--shifter_carry_out = Rm[0]
--$(/del)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -